summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorattilio <attilio@FreeBSD.org>2013-03-08 00:03:07 +0000
committerattilio <attilio@FreeBSD.org>2013-03-08 00:03:07 +0000
commitbf1dc904466a6994f1b4cd94d2187edfeca7b187 (patch)
tree7d66370442268ff1c2639db0446b7970c995c657
parente98f58faf63a90d85e0e2ad78353915f9615a4eb (diff)
parent281d1157a14218414e773086b47c81754114b42a (diff)
downloadFreeBSD-src-bf1dc904466a6994f1b4cd94d2187edfeca7b187.zip
FreeBSD-src-bf1dc904466a6994f1b4cd94d2187edfeca7b187.tar.gz
MFC
-rw-r--r--MAINTAINERS3
-rw-r--r--ObsoleteFiles.inc31
-rw-r--r--UPDATING13
-rw-r--r--bin/sh/trap.c5
-rw-r--r--cddl/contrib/opensolaris/cmd/zdb/zdb.c70
-rw-r--r--cddl/contrib/opensolaris/tools/ctf/cvt/output.c4
-rw-r--r--contrib/libyaml/LICENSE19
-rw-r--r--contrib/libyaml/Makefile.am18
-rw-r--r--contrib/libyaml/Makefile.in782
-rw-r--r--contrib/libyaml/README27
-rw-r--r--contrib/libyaml/aclocal.m48917
-rw-r--r--contrib/libyaml/config.h.in80
-rwxr-xr-xcontrib/libyaml/config/config.guess1502
-rwxr-xr-xcontrib/libyaml/config/config.sub1714
-rwxr-xr-xcontrib/libyaml/config/depcomp630
-rwxr-xr-xcontrib/libyaml/config/install-sh520
-rwxr-xr-xcontrib/libyaml/config/ltmain.sh8413
-rwxr-xr-xcontrib/libyaml/config/missing376
-rwxr-xr-xcontrib/libyaml/configure13149
-rw-r--r--contrib/libyaml/configure.ac73
-rw-r--r--contrib/libyaml/doc/doxygen.cfg222
-rw-r--r--contrib/libyaml/doc/html/annotated.html51
-rw-r--r--contrib/libyaml/doc/html/bc_s.pngbin0 -> 677 bytes
-rw-r--r--contrib/libyaml/doc/html/classes.html41
-rw-r--r--contrib/libyaml/doc/html/closed.pngbin0 -> 126 bytes
-rw-r--r--contrib/libyaml/doc/html/doxygen.css656
-rw-r--r--contrib/libyaml/doc/html/doxygen.pngbin0 -> 3942 bytes
-rw-r--r--contrib/libyaml/doc/html/files.html40
-rw-r--r--contrib/libyaml/doc/html/functions.html91
-rw-r--r--contrib/libyaml/doc/html/functions_0x62.html84
-rw-r--r--contrib/libyaml/doc/html/functions_0x63.html87
-rw-r--r--contrib/libyaml/doc/html/functions_0x64.html83
-rw-r--r--contrib/libyaml/doc/html/functions_0x65.html110
-rw-r--r--contrib/libyaml/doc/html/functions_0x66.html79
-rw-r--r--contrib/libyaml/doc/html/functions_0x68.html80
-rw-r--r--contrib/libyaml/doc/html/functions_0x69.html92
-rw-r--r--contrib/libyaml/doc/html/functions_0x6b.html71
-rw-r--r--contrib/libyaml/doc/html/functions_0x6c.html88
-rw-r--r--contrib/libyaml/doc/html/functions_0x6d.html96
-rw-r--r--contrib/libyaml/doc/html/functions_0x6e.html71
-rw-r--r--contrib/libyaml/doc/html/functions_0x6f.html80
-rw-r--r--contrib/libyaml/doc/html/functions_0x70.html100
-rw-r--r--contrib/libyaml/doc/html/functions_0x71.html71
-rw-r--r--contrib/libyaml/doc/html/functions_0x72.html87
-rw-r--r--contrib/libyaml/doc/html/functions_0x73.html163
-rw-r--r--contrib/libyaml/doc/html/functions_0x74.html115
-rw-r--r--contrib/libyaml/doc/html/functions_0x75.html71
-rw-r--r--contrib/libyaml/doc/html/functions_0x76.html80
-rw-r--r--contrib/libyaml/doc/html/functions_0x77.html77
-rw-r--r--contrib/libyaml/doc/html/functions_vars.html91
-rw-r--r--contrib/libyaml/doc/html/functions_vars_0x62.html84
-rw-r--r--contrib/libyaml/doc/html/functions_vars_0x63.html87
-rw-r--r--contrib/libyaml/doc/html/functions_vars_0x64.html83
-rw-r--r--contrib/libyaml/doc/html/functions_vars_0x65.html110
-rw-r--r--contrib/libyaml/doc/html/functions_vars_0x66.html79
-rw-r--r--contrib/libyaml/doc/html/functions_vars_0x68.html80
-rw-r--r--contrib/libyaml/doc/html/functions_vars_0x69.html92
-rw-r--r--contrib/libyaml/doc/html/functions_vars_0x6b.html71
-rw-r--r--contrib/libyaml/doc/html/functions_vars_0x6c.html88
-rw-r--r--contrib/libyaml/doc/html/functions_vars_0x6d.html96
-rw-r--r--contrib/libyaml/doc/html/functions_vars_0x6e.html71
-rw-r--r--contrib/libyaml/doc/html/functions_vars_0x6f.html80
-rw-r--r--contrib/libyaml/doc/html/functions_vars_0x70.html100
-rw-r--r--contrib/libyaml/doc/html/functions_vars_0x71.html71
-rw-r--r--contrib/libyaml/doc/html/functions_vars_0x72.html87
-rw-r--r--contrib/libyaml/doc/html/functions_vars_0x73.html163
-rw-r--r--contrib/libyaml/doc/html/functions_vars_0x74.html115
-rw-r--r--contrib/libyaml/doc/html/functions_vars_0x75.html71
-rw-r--r--contrib/libyaml/doc/html/functions_vars_0x76.html80
-rw-r--r--contrib/libyaml/doc/html/functions_vars_0x77.html77
-rw-r--r--contrib/libyaml/doc/html/globals.html667
-rw-r--r--contrib/libyaml/doc/html/globals_defs.html81
-rw-r--r--contrib/libyaml/doc/html/globals_enum.html78
-rw-r--r--contrib/libyaml/doc/html/globals_eval.html373
-rw-r--r--contrib/libyaml/doc/html/globals_func.html196
-rw-r--r--contrib/libyaml/doc/html/globals_type.html126
-rw-r--r--contrib/libyaml/doc/html/group__basic.html320
-rw-r--r--contrib/libyaml/doc/html/group__emitter.html819
-rw-r--r--contrib/libyaml/doc/html/group__events.html664
-rw-r--r--contrib/libyaml/doc/html/group__export.html60
-rw-r--r--contrib/libyaml/doc/html/group__nodes.html795
-rw-r--r--contrib/libyaml/doc/html/group__parser.html606
-rw-r--r--contrib/libyaml/doc/html/group__styles.html222
-rw-r--r--contrib/libyaml/doc/html/group__tokens.html246
-rw-r--r--contrib/libyaml/doc/html/group__version.html106
-rw-r--r--contrib/libyaml/doc/html/index.html31
-rw-r--r--contrib/libyaml/doc/html/modules.html42
-rw-r--r--contrib/libyaml/doc/html/nav_f.pngbin0 -> 159 bytes
-rw-r--r--contrib/libyaml/doc/html/nav_h.pngbin0 -> 97 bytes
-rw-r--r--contrib/libyaml/doc/html/open.pngbin0 -> 118 bytes
-rw-r--r--contrib/libyaml/doc/html/structyaml__alias__data__s.html108
-rw-r--r--contrib/libyaml/doc/html/structyaml__document__s.html235
-rw-r--r--contrib/libyaml/doc/html/structyaml__emitter__s.html1300
-rw-r--r--contrib/libyaml/doc/html/structyaml__event__s.html496
-rw-r--r--contrib/libyaml/doc/html/structyaml__mark__s.html108
-rw-r--r--contrib/libyaml/doc/html/structyaml__node__pair__s.html91
-rw-r--r--contrib/libyaml/doc/html/structyaml__node__s.html420
-rw-r--r--contrib/libyaml/doc/html/structyaml__parser__s.html1229
-rw-r--r--contrib/libyaml/doc/html/structyaml__simple__key__s.html97
-rw-r--r--contrib/libyaml/doc/html/structyaml__tag__directive__s.html91
-rw-r--r--contrib/libyaml/doc/html/structyaml__token__s.html413
-rw-r--r--contrib/libyaml/doc/html/structyaml__version__directive__s.html91
-rw-r--r--contrib/libyaml/doc/html/tab_a.pngbin0 -> 140 bytes
-rw-r--r--contrib/libyaml/doc/html/tab_b.pngbin0 -> 178 bytes
-rw-r--r--contrib/libyaml/doc/html/tab_h.pngbin0 -> 192 bytes
-rw-r--r--contrib/libyaml/doc/html/tab_s.pngbin0 -> 189 bytes
-rw-r--r--contrib/libyaml/doc/html/tabs.css59
-rw-r--r--contrib/libyaml/doc/html/yaml_8h.html525
-rw-r--r--contrib/libyaml/include/Makefile.am17
-rw-r--r--contrib/libyaml/include/Makefile.in470
-rw-r--r--contrib/libyaml/include/yaml.h1971
-rw-r--r--contrib/libyaml/src/Makefile.am4
-rw-r--r--contrib/libyaml/src/Makefile.in529
-rw-r--r--contrib/libyaml/src/api.c1392
-rw-r--r--contrib/libyaml/src/dumper.c394
-rw-r--r--contrib/libyaml/src/emitter.c2329
-rw-r--r--contrib/libyaml/src/loader.c432
-rw-r--r--contrib/libyaml/src/parser.c1374
-rw-r--r--contrib/libyaml/src/reader.c465
-rw-r--r--contrib/libyaml/src/scanner.c3570
-rw-r--r--contrib/libyaml/src/writer.c141
-rw-r--r--contrib/libyaml/src/yaml_private.h640
-rw-r--r--contrib/libyaml/tests/Makefile.am8
-rw-r--r--contrib/libyaml/tests/Makefile.in672
-rw-r--r--contrib/libyaml/tests/example-deconstructor-alt.c800
-rw-r--r--contrib/libyaml/tests/example-deconstructor.c1130
-rw-r--r--contrib/libyaml/tests/example-reformatter-alt.c217
-rw-r--r--contrib/libyaml/tests/example-reformatter.c202
-rw-r--r--contrib/libyaml/tests/run-dumper.c311
-rw-r--r--contrib/libyaml/tests/run-emitter.c327
-rw-r--r--contrib/libyaml/tests/run-loader.c63
-rw-r--r--contrib/libyaml/tests/run-parser.c63
-rw-r--r--contrib/libyaml/tests/run-scanner.c63
-rw-r--r--contrib/libyaml/tests/test-reader.c354
-rw-r--r--contrib/libyaml/tests/test-version.c29
-rw-r--r--contrib/libyaml/win32/Makefile.am24
-rw-r--r--contrib/libyaml/win32/Makefile.in374
-rw-r--r--contrib/libyaml/win32/config.h4
-rw-r--r--contrib/libyaml/win32/vc6/example_deconstructor.dsp102
-rw-r--r--contrib/libyaml/win32/vc6/example_deconstructor_alt.dsp102
-rw-r--r--contrib/libyaml/win32/vc6/example_reformatter.dsp102
-rw-r--r--contrib/libyaml/win32/vc6/example_reformatter_alt.dsp102
-rw-r--r--contrib/libyaml/win32/vc6/libyaml.dsw206
-rw-r--r--contrib/libyaml/win32/vc6/run_dumper.dsp102
-rw-r--r--contrib/libyaml/win32/vc6/run_emitter.dsp102
-rw-r--r--contrib/libyaml/win32/vc6/run_loader.dsp102
-rw-r--r--contrib/libyaml/win32/vc6/run_parser.dsp102
-rw-r--r--contrib/libyaml/win32/vc6/run_scanner.dsp102
-rw-r--r--contrib/libyaml/win32/vc6/test_reader.dsp102
-rw-r--r--contrib/libyaml/win32/vc6/test_version.dsp102
-rw-r--r--contrib/libyaml/win32/vc6/yaml.dsp136
-rw-r--r--contrib/libyaml/win32/vc6/yamldll.dsp147
-rw-r--r--contrib/libyaml/win32/vs2003/example_deconstructor.vcproj134
-rw-r--r--contrib/libyaml/win32/vs2003/example_deconstructor_alt.vcproj134
-rw-r--r--contrib/libyaml/win32/vs2003/example_reformatter.vcproj134
-rw-r--r--contrib/libyaml/win32/vs2003/example_reformatter_alt.vcproj134
-rw-r--r--contrib/libyaml/win32/vs2003/libyaml.sln128
-rw-r--r--contrib/libyaml/win32/vs2003/run_dumper.vcproj134
-rw-r--r--contrib/libyaml/win32/vs2003/run_emitter.vcproj134
-rw-r--r--contrib/libyaml/win32/vs2003/run_loader.vcproj134
-rw-r--r--contrib/libyaml/win32/vs2003/run_parser.vcproj134
-rw-r--r--contrib/libyaml/win32/vs2003/run_scanner.vcproj134
-rw-r--r--contrib/libyaml/win32/vs2003/test_reader.vcproj134
-rw-r--r--contrib/libyaml/win32/vs2003/test_version.vcproj134
-rw-r--r--contrib/libyaml/win32/vs2003/yaml.vcproj149
-rw-r--r--contrib/libyaml/win32/vs2003/yamldll.vcproj166
-rw-r--r--contrib/libyaml/win32/vs2008/example_deconstructor.vcproj201
-rw-r--r--contrib/libyaml/win32/vs2008/example_deconstructor_alt.vcproj201
-rw-r--r--contrib/libyaml/win32/vs2008/example_reformatter.vcproj201
-rw-r--r--contrib/libyaml/win32/vs2008/example_reformatter_alt.vcproj201
-rw-r--r--contrib/libyaml/win32/vs2008/libyaml.sln124
-rw-r--r--contrib/libyaml/win32/vs2008/run_dumper.vcproj201
-rw-r--r--contrib/libyaml/win32/vs2008/run_emitter.vcproj201
-rw-r--r--contrib/libyaml/win32/vs2008/run_loader.vcproj201
-rw-r--r--contrib/libyaml/win32/vs2008/run_parser.vcproj201
-rw-r--r--contrib/libyaml/win32/vs2008/run_scanner.vcproj201
-rw-r--r--contrib/libyaml/win32/vs2008/test_reader.vcproj201
-rw-r--r--contrib/libyaml/win32/vs2008/test_version.vcproj201
-rw-r--r--contrib/libyaml/win32/vs2008/yaml.vcproj215
-rw-r--r--contrib/libyaml/win32/vs2008/yamldll.vcproj243
-rw-r--r--contrib/libyaml/yaml-0.1.pc.in10
-rw-r--r--contrib/openbsm/etc/audit_event2
-rw-r--r--contrib/openpam/doc/man/openpam_straddch.321
-rw-r--r--contrib/openpam/lib/openpam_readline.c6
-rw-r--r--contrib/openpam/lib/openpam_readword.c7
-rw-r--r--crypto/openssh/FREEBSD-upgrade1
-rw-r--r--crypto/openssh/config.h51
-rw-r--r--etc/devd.conf16
-rw-r--r--etc/portsnap.conf1
-rw-r--r--lib/Makefile1
-rw-r--r--lib/libc/string/Makefile.inc3
-rw-r--r--lib/libc/sys/Makefile.inc2
-rw-r--r--lib/libc/sys/Symbol.map2
-rw-r--r--lib/libc/sys/bindat.2109
-rw-r--r--lib/libc/sys/cap_rights_limit.210
-rw-r--r--lib/libc/sys/connectat.2109
-rw-r--r--lib/libprocstat/ntfs.c71
-rw-r--r--lib/libstand/Makefile3
-rw-r--r--lib/libutil/gr_util.c137
-rw-r--r--lib/libutil/libutil.h2
-rw-r--r--lib/libyaml/Makefile24
-rw-r--r--lib/libyaml/config.h83
-rw-r--r--lib/libyaml/libbsdyml.3 (renamed from sbin/mount_ext2fs/mount_ext2fs.8)71
-rw-r--r--sbin/devd/devd.cc33
-rw-r--r--sbin/devd/devd.hh7
-rw-r--r--sbin/ipfw/ipfw2.c317
-rw-r--r--sbin/ipfw/ipfw2.h8
-rw-r--r--sbin/ipfw/ipv6.c25
-rw-r--r--sbin/mount_cd9660/mount_cd9660.86
-rw-r--r--sbin/mount_cd9660/mount_cd9660.c6
-rw-r--r--sbin/mount_ext2fs/Makefile14
-rw-r--r--sbin/mount_ext2fs/mount_ext2fs.c125
-rw-r--r--sbin/mount_hpfs/Makefile14
-rw-r--r--sbin/mount_hpfs/mount_hpfs.8100
-rw-r--r--sbin/mount_hpfs/mount_hpfs.c244
-rw-r--r--sbin/mount_msdosfs/mount_msdosfs.c7
-rw-r--r--sbin/mount_nfs/mount_nfs.c13
-rw-r--r--sbin/mount_ntfs/Makefile20
-rw-r--r--sbin/mount_ntfs/mount_ntfs.8173
-rw-r--r--sbin/mount_ntfs/mount_ntfs.c280
-rw-r--r--sbin/mount_nullfs/mount_nullfs.c5
-rw-r--r--sbin/mount_reiserfs/Makefile13
-rw-r--r--sbin/mount_reiserfs/mount_reiserfs.890
-rw-r--r--sbin/mount_reiserfs/mount_reiserfs.c108
-rw-r--r--sbin/mount_std/Makefile23
-rw-r--r--sbin/mount_std/mount_std.8167
-rw-r--r--sbin/mount_std/mount_std.c160
-rw-r--r--sbin/mount_udf/Makefile1
-rw-r--r--sbin/mount_udf/mount_udf.c46
-rw-r--r--sbin/mount_unionfs/mount_unionfs.c5
-rw-r--r--share/examples/portal/README65
-rw-r--r--share/examples/portal/portal.conf3
-rw-r--r--share/man/man4/coda.482
-rw-r--r--share/man/man4/eventtimers.48
-rw-r--r--share/man/man4/mvs.46
-rw-r--r--share/man/man4/zyd.43
-rw-r--r--share/man/man5/xfs.5108
-rw-r--r--share/man/man7/development.78
-rw-r--r--share/man/man7/ports.714
-rw-r--r--share/man/man9/Makefile8
-rw-r--r--share/man/man9/condvar.932
-rw-r--r--share/man/man9/sleep.942
-rw-r--r--share/man/man9/sleepqueue.926
-rw-r--r--share/man/man9/timeout.935
-rw-r--r--share/mk/bsd.libnames.mk1
-rw-r--r--sys/amd64/conf/GENERIC5
-rw-r--r--sys/amd64/conf/NOTES7
-rw-r--r--sys/arm/arm/busdma_machdep-v6.c3
-rw-r--r--sys/arm/arm/swtch.S5
-rw-r--r--sys/arm/arm/vm_machdep.c16
-rw-r--r--sys/arm/broadcom/bcm2835/bcm2835_dma.c2
-rw-r--r--sys/arm/include/frame.h6
-rw-r--r--sys/bsm/audit_kevents.h2
-rw-r--r--sys/cam/ctl/ctl.c6
-rw-r--r--sys/cddl/compat/opensolaris/sys/kcondvar.h2
-rw-r--r--sys/cddl/contrib/opensolaris/uts/common/fs/zfs/bpobj.c8
-rw-r--r--sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dmu.c2
-rw-r--r--sys/cddl/contrib/opensolaris/uts/intel/dtrace/fasttrap_isa.c9
-rw-r--r--sys/compat/freebsd32/freebsd32_proto.h2
-rw-r--r--sys/compat/freebsd32/freebsd32_syscall.h6
-rw-r--r--sys/compat/freebsd32/freebsd32_syscalls.c4
-rw-r--r--sys/compat/freebsd32/freebsd32_sysent.c4
-rw-r--r--sys/compat/freebsd32/freebsd32_systrace_args.c68
-rw-r--r--sys/compat/freebsd32/syscalls.master4
-rw-r--r--sys/compat/linprocfs/linprocfs.c6
-rw-r--r--sys/compat/linux/linux_file.c3
-rw-r--r--sys/compat/linux/linux_socket.c6
-rw-r--r--sys/conf/NOTES5
-rw-r--r--sys/conf/files.amd6410
-rw-r--r--sys/conf/files.i38610
-rw-r--r--sys/conf/options4
-rw-r--r--sys/contrib/altq/altq/altq_hfsc.c99
-rw-r--r--sys/contrib/altq/altq/altq_hfsc.h18
-rw-r--r--sys/dev/ath/ath_hal/ah.h4
-rw-r--r--sys/dev/ath/ath_hal/ar5416/ar5416.h3
-rw-r--r--sys/dev/ath/ath_hal/ar5416/ar5416_attach.c1
-rw-r--r--sys/dev/ath/ath_hal/ar5416/ar5416_xmit.c11
-rw-r--r--sys/dev/ath/if_athvar.h2
-rw-r--r--sys/dev/drm2/drmP.h10
-rw-r--r--sys/dev/drm2/drm_drv.c21
-rw-r--r--sys/dev/drm2/drm_gem.c6
-rw-r--r--sys/dev/drm2/drm_global.c110
-rw-r--r--sys/dev/drm2/drm_global.h56
-rw-r--r--sys/dev/drm2/drm_mm.c37
-rw-r--r--sys/dev/drm2/drm_mm.h2
-rw-r--r--sys/dev/drm2/ttm/ttm_agp_backend.c145
-rw-r--r--sys/dev/drm2/ttm/ttm_bo.c1820
-rw-r--r--sys/dev/drm2/ttm/ttm_bo_api.h740
-rw-r--r--sys/dev/drm2/ttm/ttm_bo_driver.h1018
-rw-r--r--sys/dev/drm2/ttm/ttm_bo_manager.c157
-rw-r--r--sys/dev/drm2/ttm/ttm_bo_util.c658
-rw-r--r--sys/dev/drm2/ttm/ttm_bo_vm.c492
-rw-r--r--sys/dev/drm2/ttm/ttm_execbuf_util.c230
-rw-r--r--sys/dev/drm2/ttm/ttm_execbuf_util.h109
-rw-r--r--sys/dev/drm2/ttm/ttm_lock.c340
-rw-r--r--sys/dev/drm2/ttm/ttm_lock.h228
-rw-r--r--sys/dev/drm2/ttm/ttm_memory.c471
-rw-r--r--sys/dev/drm2/ttm/ttm_memory.h149
-rw-r--r--sys/dev/drm2/ttm/ttm_module.h37
-rw-r--r--sys/dev/drm2/ttm/ttm_object.c455
-rw-r--r--sys/dev/drm2/ttm/ttm_object.h271
-rw-r--r--sys/dev/drm2/ttm/ttm_page_alloc.c900
-rw-r--r--sys/dev/drm2/ttm/ttm_page_alloc.h103
-rw-r--r--sys/dev/drm2/ttm/ttm_page_alloc_dma.c1134
-rw-r--r--sys/dev/drm2/ttm/ttm_placement.h93
-rw-r--r--sys/dev/drm2/ttm/ttm_tt.c370
-rw-r--r--sys/dev/hwpmc/hwpmc_soft.c21
-rw-r--r--sys/dev/ixgbe/LICENSE2
-rw-r--r--sys/dev/ixgbe/ixgbe.c134
-rw-r--r--sys/dev/ixgbe/ixgbe_82598.c60
-rw-r--r--sys/dev/ixgbe/ixgbe_82599.c382
-rw-r--r--sys/dev/ixgbe/ixgbe_82599.h9
-rw-r--r--sys/dev/ixgbe/ixgbe_api.c102
-rw-r--r--sys/dev/ixgbe/ixgbe_api.h6
-rw-r--r--sys/dev/ixgbe/ixgbe_common.c276
-rw-r--r--sys/dev/ixgbe/ixgbe_common.h23
-rw-r--r--sys/dev/ixgbe/ixgbe_mbx.h14
-rw-r--r--sys/dev/ixgbe/ixgbe_osdep.h5
-rw-r--r--sys/dev/ixgbe/ixgbe_phy.c55
-rw-r--r--sys/dev/ixgbe/ixgbe_phy.h22
-rw-r--r--sys/dev/ixgbe/ixgbe_type.h51
-rw-r--r--sys/dev/ixgbe/ixgbe_vf.c125
-rw-r--r--sys/dev/ixgbe/ixgbe_vf.h11
-rw-r--r--sys/dev/ixgbe/ixgbe_x540.c10
-rw-r--r--sys/dev/ixgbe/ixgbe_x540.h4
-rw-r--r--sys/dev/ixgbe/ixv.c8
-rw-r--r--sys/dev/nvme/nvme.c8
-rw-r--r--sys/dev/nvme/nvme_ctrlr.c4
-rw-r--r--sys/dev/oce/oce_hw.c8
-rw-r--r--sys/dev/oce/oce_hw.h152
-rw-r--r--sys/dev/oce/oce_if.c240
-rw-r--r--sys/dev/oce/oce_if.h47
-rw-r--r--sys/dev/oce/oce_mbox.c429
-rw-r--r--sys/dev/oce/oce_queue.c61
-rw-r--r--sys/dev/oce/oce_sysctl.c52
-rw-r--r--sys/dev/oce/oce_util.c5
-rw-r--r--sys/dev/pci/pci.c21
-rw-r--r--sys/dev/random/randomdev_soft.c7
-rw-r--r--sys/dev/sound/pci/hda/hdaa_patches.c17
-rw-r--r--sys/dev/sound/pci/hda/hdac.h5
-rw-r--r--sys/dev/sound/pci/hda/hdacc.c6
-rw-r--r--sys/dev/syscons/syscons.c58
-rw-r--r--sys/dev/syscons/syscons.h2
-rw-r--r--sys/dev/virtio/block/virtio_blk.c49
-rw-r--r--sys/fs/coda/README62
-rw-r--r--sys/fs/coda/TODO16
-rw-r--r--sys/fs/coda/cnode.h206
-rw-r--r--sys/fs/coda/coda.h838
-rw-r--r--sys/fs/coda/coda_fbsd.c148
-rw-r--r--sys/fs/coda/coda_io.h73
-rw-r--r--sys/fs/coda/coda_opstats.h130
-rw-r--r--sys/fs/coda/coda_pioctl.h69
-rw-r--r--sys/fs/coda/coda_psdev.c675
-rw-r--r--sys/fs/coda/coda_psdev.h46
-rw-r--r--sys/fs/coda/coda_subr.c628
-rw-r--r--sys/fs/coda/coda_subr.h49
-rw-r--r--sys/fs/coda/coda_venus.c705
-rw-r--r--sys/fs/coda/coda_venus.h83
-rw-r--r--sys/fs/coda/coda_vfsops.c446
-rw-r--r--sys/fs/coda/coda_vfsops.h60
-rw-r--r--sys/fs/coda/coda_vnops.c1738
-rw-r--r--sys/fs/coda/coda_vnops.h84
-rw-r--r--sys/fs/hpfs/hpfs.h387
-rw-r--r--sys/fs/hpfs/hpfs_alsubr.c907
-rw-r--r--sys/fs/hpfs/hpfs_lookup.c213
-rw-r--r--sys/fs/hpfs/hpfs_subr.c869
-rw-r--r--sys/fs/hpfs/hpfs_subr.h89
-rw-r--r--sys/fs/hpfs/hpfs_vfsops.c545
-rw-r--r--sys/fs/hpfs/hpfs_vnops.c1264
-rw-r--r--sys/fs/hpfs/hpfsmount.h39
-rw-r--r--sys/fs/ntfs/ntfs.h308
-rw-r--r--sys/fs/ntfs/ntfs_compr.c111
-rw-r--r--sys/fs/ntfs/ntfs_compr.h35
-rw-r--r--sys/fs/ntfs/ntfs_iconv.c36
-rw-r--r--sys/fs/ntfs/ntfs_ihash.c130
-rw-r--r--sys/fs/ntfs/ntfs_ihash.h37
-rw-r--r--sys/fs/ntfs/ntfs_inode.h101
-rw-r--r--sys/fs/ntfs/ntfs_subr.c2029
-rw-r--r--sys/fs/ntfs/ntfs_subr.h120
-rw-r--r--sys/fs/ntfs/ntfs_vfsops.c780
-rw-r--r--sys/fs/ntfs/ntfs_vfsops.h43
-rw-r--r--sys/fs/ntfs/ntfs_vnops.c687
-rw-r--r--sys/fs/ntfs/ntfsmount.h44
-rw-r--r--sys/fs/portalfs/portal.h67
-rw-r--r--sys/fs/portalfs/portal_vfsops.c263
-rw-r--r--sys/fs/portalfs/portal_vnops.c586
-rw-r--r--sys/geom/label/g_label_ntfs.c79
-rw-r--r--sys/geom/part/g_part.c1
-rw-r--r--sys/geom/part/g_part.h1
-rw-r--r--sys/geom/part/g_part_mbr.c1
-rw-r--r--sys/geom/raid/md_ddf.c5
-rw-r--r--sys/gnu/fs/xfs/FreeBSD/support/atomic.h36
-rw-r--r--sys/gnu/fs/xfs/FreeBSD/support/debug.c97
-rw-r--r--sys/gnu/fs/xfs/FreeBSD/support/debug.h79
-rw-r--r--sys/gnu/fs/xfs/FreeBSD/support/kdb.c62
-rw-r--r--sys/gnu/fs/xfs/FreeBSD/support/kdb.h44
-rw-r--r--sys/gnu/fs/xfs/FreeBSD/support/kmem.c3
-rw-r--r--sys/gnu/fs/xfs/FreeBSD/support/kmem.h86
-rw-r--r--sys/gnu/fs/xfs/FreeBSD/support/ktrace.c334
-rw-r--r--sys/gnu/fs/xfs/FreeBSD/support/ktrace.h101
-rw-r--r--sys/gnu/fs/xfs/FreeBSD/support/move.h48
-rw-r--r--sys/gnu/fs/xfs/FreeBSD/support/mrlock.c14
-rw-r--r--sys/gnu/fs/xfs/FreeBSD/support/mrlock.h41
-rw-r--r--sys/gnu/fs/xfs/FreeBSD/support/mutex.h29
-rw-r--r--sys/gnu/fs/xfs/FreeBSD/support/rwlock.h23
-rw-r--r--sys/gnu/fs/xfs/FreeBSD/support/rwsem.h21
-rw-r--r--sys/gnu/fs/xfs/FreeBSD/support/sema.h53
-rw-r--r--sys/gnu/fs/xfs/FreeBSD/support/spin.h42
-rw-r--r--sys/gnu/fs/xfs/FreeBSD/support/support.h49
-rw-r--r--sys/gnu/fs/xfs/FreeBSD/support/sv.h30
-rw-r--r--sys/gnu/fs/xfs/FreeBSD/support/time.h37
-rw-r--r--sys/gnu/fs/xfs/FreeBSD/support/uuid.c165
-rw-r--r--sys/gnu/fs/xfs/FreeBSD/support/uuid.h45
-rw-r--r--sys/gnu/fs/xfs/FreeBSD/xfs_buf.c334
-rw-r--r--sys/gnu/fs/xfs/FreeBSD/xfs_buf.h348
-rw-r--r--sys/gnu/fs/xfs/FreeBSD/xfs_compat.h173
-rw-r--r--sys/gnu/fs/xfs/FreeBSD/xfs_config.h38
-rw-r--r--sys/gnu/fs/xfs/FreeBSD/xfs_cred.h46
-rw-r--r--sys/gnu/fs/xfs/FreeBSD/xfs_dmistubs.c144
-rw-r--r--sys/gnu/fs/xfs/FreeBSD/xfs_freebsd.h350
-rw-r--r--sys/gnu/fs/xfs/FreeBSD/xfs_freebsd_iget.c419
-rw-r--r--sys/gnu/fs/xfs/FreeBSD/xfs_frw.c891
-rw-r--r--sys/gnu/fs/xfs/FreeBSD/xfs_frw.h106
-rw-r--r--sys/gnu/fs/xfs/FreeBSD/xfs_fs_subr.c131
-rw-r--r--sys/gnu/fs/xfs/FreeBSD/xfs_fs_subr.h49
-rw-r--r--sys/gnu/fs/xfs/FreeBSD/xfs_globals.c77
-rw-r--r--sys/gnu/fs/xfs/FreeBSD/xfs_ioctl.c1460
-rw-r--r--sys/gnu/fs/xfs/FreeBSD/xfs_iops.h61
-rw-r--r--sys/gnu/fs/xfs/FreeBSD/xfs_mountops.c500
-rw-r--r--sys/gnu/fs/xfs/FreeBSD/xfs_mountops.h59
-rw-r--r--sys/gnu/fs/xfs/FreeBSD/xfs_node.h16
-rw-r--r--sys/gnu/fs/xfs/FreeBSD/xfs_stats.c105
-rw-r--r--sys/gnu/fs/xfs/FreeBSD/xfs_stats.h161
-rw-r--r--sys/gnu/fs/xfs/FreeBSD/xfs_super.c279
-rw-r--r--sys/gnu/fs/xfs/FreeBSD/xfs_super.h113
-rw-r--r--sys/gnu/fs/xfs/FreeBSD/xfs_sysctl.c43
-rw-r--r--sys/gnu/fs/xfs/FreeBSD/xfs_sysctl.h102
-rw-r--r--sys/gnu/fs/xfs/FreeBSD/xfs_version.h44
-rw-r--r--sys/gnu/fs/xfs/FreeBSD/xfs_vfs.c356
-rw-r--r--sys/gnu/fs/xfs/FreeBSD/xfs_vfs.h232
-rw-r--r--sys/gnu/fs/xfs/FreeBSD/xfs_vnode.c272
-rw-r--r--sys/gnu/fs/xfs/FreeBSD/xfs_vnode.h673
-rw-r--r--sys/gnu/fs/xfs/FreeBSD/xfs_vnops.c1680
-rw-r--r--sys/gnu/fs/xfs/xfs.h23
-rw-r--r--sys/gnu/fs/xfs/xfs_acl.c928
-rw-r--r--sys/gnu/fs/xfs/xfs_acl.h102
-rw-r--r--sys/gnu/fs/xfs/xfs_ag.h231
-rw-r--r--sys/gnu/fs/xfs/xfs_alloc.c2603
-rw-r--r--sys/gnu/fs/xfs/xfs_alloc.h189
-rw-r--r--sys/gnu/fs/xfs/xfs_alloc_btree.c2203
-rw-r--r--sys/gnu/fs/xfs/xfs_alloc_btree.h159
-rw-r--r--sys/gnu/fs/xfs/xfs_arch.h239
-rw-r--r--sys/gnu/fs/xfs/xfs_attr.c2646
-rw-r--r--sys/gnu/fs/xfs/xfs_attr.h172
-rw-r--r--sys/gnu/fs/xfs/xfs_attr_leaf.c3083
-rw-r--r--sys/gnu/fs/xfs/xfs_attr_leaf.h282
-rw-r--r--sys/gnu/fs/xfs/xfs_attr_sf.h114
-rw-r--r--sys/gnu/fs/xfs/xfs_behavior.c203
-rw-r--r--sys/gnu/fs/xfs/xfs_behavior.h190
-rw-r--r--sys/gnu/fs/xfs/xfs_bit.c296
-rw-r--r--sys/gnu/fs/xfs/xfs_bit.h67
-rw-r--r--sys/gnu/fs/xfs/xfs_bmap.c6547
-rw-r--r--sys/gnu/fs/xfs/xfs_bmap.h386
-rw-r--r--sys/gnu/fs/xfs/xfs_bmap_btree.c2782
-rw-r--r--sys/gnu/fs/xfs/xfs_bmap_btree.h377
-rw-r--r--sys/gnu/fs/xfs/xfs_btree.c943
-rw-r--r--sys/gnu/fs/xfs/xfs_btree.h473
-rw-r--r--sys/gnu/fs/xfs/xfs_buf_item.c1203
-rw-r--r--sys/gnu/fs/xfs/xfs_buf_item.h157
-rw-r--r--sys/gnu/fs/xfs/xfs_cap.c207
-rw-r--r--sys/gnu/fs/xfs/xfs_cap.h70
-rw-r--r--sys/gnu/fs/xfs/xfs_clnt.h103
-rw-r--r--sys/gnu/fs/xfs/xfs_da_btree.c2590
-rw-r--r--sys/gnu/fs/xfs/xfs_da_btree.h270
-rw-r--r--sys/gnu/fs/xfs/xfs_dfrag.c413
-rw-r--r--sys/gnu/fs/xfs/xfs_dfrag.h56
-rw-r--r--sys/gnu/fs/xfs/xfs_dinode.h281
-rw-r--r--sys/gnu/fs/xfs/xfs_dir.c1218
-rw-r--r--sys/gnu/fs/xfs/xfs_dir.h142
-rw-r--r--sys/gnu/fs/xfs/xfs_dir2.c851
-rw-r--r--sys/gnu/fs/xfs/xfs_dir2.h87
-rw-r--r--sys/gnu/fs/xfs/xfs_dir2_block.c1229
-rw-r--r--sys/gnu/fs/xfs/xfs_dir2_block.h95
-rw-r--r--sys/gnu/fs/xfs/xfs_dir2_data.c837
-rw-r--r--sys/gnu/fs/xfs/xfs_dir2_data.h188
-rw-r--r--sys/gnu/fs/xfs/xfs_dir2_leaf.c1877
-rw-r--r--sys/gnu/fs/xfs/xfs_dir2_leaf.h270
-rw-r--r--sys/gnu/fs/xfs/xfs_dir2_node.c1999
-rw-r--r--sys/gnu/fs/xfs/xfs_dir2_node.h104
-rw-r--r--sys/gnu/fs/xfs/xfs_dir2_sf.c1296
-rw-r--r--sys/gnu/fs/xfs/xfs_dir2_sf.h195
-rw-r--r--sys/gnu/fs/xfs/xfs_dir2_trace.c216
-rw-r--r--sys/gnu/fs/xfs/xfs_dir2_trace.h72
-rw-r--r--sys/gnu/fs/xfs/xfs_dir_leaf.c2215
-rw-r--r--sys/gnu/fs/xfs/xfs_dir_leaf.h231
-rw-r--r--sys/gnu/fs/xfs/xfs_dir_sf.h155
-rw-r--r--sys/gnu/fs/xfs/xfs_dmapi.h198
-rw-r--r--sys/gnu/fs/xfs/xfs_dmops.c37
-rw-r--r--sys/gnu/fs/xfs/xfs_error.c311
-rw-r--r--sys/gnu/fs/xfs/xfs_error.h193
-rw-r--r--sys/gnu/fs/xfs/xfs_extfree_item.c587
-rw-r--r--sys/gnu/fs/xfs/xfs_extfree_item.h111
-rw-r--r--sys/gnu/fs/xfs/xfs_fs.h527
-rw-r--r--sys/gnu/fs/xfs/xfs_fsops.c599
-rw-r--r--sys/gnu/fs/xfs/xfs_fsops.h30
-rw-r--r--sys/gnu/fs/xfs/xfs_ialloc.c1411
-rw-r--r--sys/gnu/fs/xfs/xfs_ialloc.h154
-rw-r--r--sys/gnu/fs/xfs/xfs_ialloc_btree.c2080
-rw-r--r--sys/gnu/fs/xfs/xfs_ialloc_btree.h177
-rw-r--r--sys/gnu/fs/xfs/xfs_iget.c1052
-rw-r--r--sys/gnu/fs/xfs/xfs_imap.h40
-rw-r--r--sys/gnu/fs/xfs/xfs_inode.c4796
-rw-r--r--sys/gnu/fs/xfs/xfs_inode.h516
-rw-r--r--sys/gnu/fs/xfs/xfs_inode_item.c1086
-rw-r--r--sys/gnu/fs/xfs/xfs_inode_item.h178
-rw-r--r--sys/gnu/fs/xfs/xfs_inum.h81
-rw-r--r--sys/gnu/fs/xfs/xfs_iocore.c123
-rw-r--r--sys/gnu/fs/xfs/xfs_iomap.c1006
-rw-r--r--sys/gnu/fs/xfs/xfs_iomap.h90
-rw-r--r--sys/gnu/fs/xfs/xfs_itable.c848
-rw-r--r--sys/gnu/fs/xfs/xfs_itable.h91
-rw-r--r--sys/gnu/fs/xfs/xfs_log.c3708
-rw-r--r--sys/gnu/fs/xfs/xfs_log.h192
-rw-r--r--sys/gnu/fs/xfs/xfs_log_priv.h511
-rw-r--r--sys/gnu/fs/xfs/xfs_log_recover.c4078
-rw-r--r--sys/gnu/fs/xfs/xfs_log_recover.h67
-rw-r--r--sys/gnu/fs/xfs/xfs_mac.c72
-rw-r--r--sys/gnu/fs/xfs/xfs_mac.h106
-rw-r--r--sys/gnu/fs/xfs/xfs_mount.c2207
-rw-r--r--sys/gnu/fs/xfs/xfs_mount.h626
-rw-r--r--sys/gnu/fs/xfs/xfs_qmops.c128
-rw-r--r--sys/gnu/fs/xfs/xfs_quota.h372
-rw-r--r--sys/gnu/fs/xfs/xfs_refcache.c431
-rw-r--r--sys/gnu/fs/xfs/xfs_refcache.h54
-rw-r--r--sys/gnu/fs/xfs/xfs_rename.c636
-rw-r--r--sys/gnu/fs/xfs/xfs_rtalloc.c2449
-rw-r--r--sys/gnu/fs/xfs/xfs_rtalloc.h173
-rw-r--r--sys/gnu/fs/xfs/xfs_rw.c341
-rw-r--r--sys/gnu/fs/xfs/xfs_rw.h98
-rw-r--r--sys/gnu/fs/xfs/xfs_sb.h492
-rw-r--r--sys/gnu/fs/xfs/xfs_trans.c1382
-rw-r--r--sys/gnu/fs/xfs/xfs_trans.h1016
-rw-r--r--sys/gnu/fs/xfs/xfs_trans_ail.c581
-rw-r--r--sys/gnu/fs/xfs/xfs_trans_buf.c1113
-rw-r--r--sys/gnu/fs/xfs/xfs_trans_extfree.c141
-rw-r--r--sys/gnu/fs/xfs/xfs_trans_inode.c310
-rw-r--r--sys/gnu/fs/xfs/xfs_trans_item.c539
-rw-r--r--sys/gnu/fs/xfs/xfs_trans_priv.h61
-rw-r--r--sys/gnu/fs/xfs/xfs_trans_space.h91
-rw-r--r--sys/gnu/fs/xfs/xfs_types.h179
-rw-r--r--sys/gnu/fs/xfs/xfs_utils.c472
-rw-r--r--sys/gnu/fs/xfs/xfs_utils.h38
-rw-r--r--sys/gnu/fs/xfs/xfs_vfsops.c2030
-rw-r--r--sys/gnu/fs/xfs/xfs_vnodeops.c4719
-rw-r--r--sys/gnu/fs/xfs/xfsidbg.c7769
-rw-r--r--sys/i386/conf/GENERIC5
-rw-r--r--sys/i386/conf/NOTES7
-rw-r--r--sys/i386/xen/pmap.c36
-rw-r--r--sys/kern/capabilities.conf12
-rw-r--r--sys/kern/init_sysent.c4
-rw-r--r--sys/kern/kern_clock.c6
-rw-r--r--sys/kern/kern_clocksource.c468
-rw-r--r--sys/kern/kern_condvar.c25
-rw-r--r--sys/kern/kern_descrip.c7
-rw-r--r--sys/kern/kern_event.c87
-rw-r--r--sys/kern/kern_intr.c11
-rw-r--r--sys/kern/kern_resource.c17
-rw-r--r--sys/kern/kern_synch.c60
-rw-r--r--sys/kern/kern_tc.c59
-rw-r--r--sys/kern/kern_time.c99
-rw-r--r--sys/kern/kern_timeout.c771
-rw-r--r--sys/kern/subr_log.c23
-rw-r--r--sys/kern/subr_param.c8
-rw-r--r--sys/kern/subr_sleepqueue.c6
-rw-r--r--sys/kern/sys_generic.c94
-rw-r--r--sys/kern/syscalls.c4
-rw-r--r--sys/kern/syscalls.master4
-rw-r--r--sys/kern/systrace_args.c68
-rw-r--r--sys/kern/uipc_domain.c2
-rw-r--r--sys/kern/uipc_socket.c46
-rw-r--r--sys/kern/uipc_syscalls.c117
-rw-r--r--sys/kern/uipc_usrreq.c94
-rw-r--r--sys/modules/coda/Makefile10
-rw-r--r--sys/modules/coda5/Makefile13
-rw-r--r--sys/modules/drm2/drm2/Makefile17
-rw-r--r--sys/modules/hpfs/Makefile10
-rw-r--r--sys/modules/mqueue/Makefile2
-rw-r--r--sys/modules/ntfs/Makefile11
-rw-r--r--sys/modules/ntfs_iconv/Makefile7
-rw-r--r--sys/modules/portalfs/Makefile10
-rw-r--r--sys/modules/uart/Makefile1
-rw-r--r--sys/modules/xfs/Makefile89
-rw-r--r--sys/net/route.c4
-rw-r--r--sys/netinet/siftr.c2
-rw-r--r--sys/netinet/tcp_timer.c18
-rw-r--r--sys/netpfil/ipfw/ip_fw_dynamic.c6
-rw-r--r--sys/ofed/include/linux/timer.h16
-rw-r--r--sys/security/audit/audit.h8
-rw-r--r--sys/security/audit/audit_arg.c6
-rw-r--r--sys/security/audit/audit_bsm.c15
-rw-r--r--sys/sparc64/pci/psycho.c2
-rw-r--r--sys/sys/_callout.h7
-rw-r--r--sys/sys/callout.h24
-rw-r--r--sys/sys/capability.h11
-rw-r--r--sys/sys/condvar.h16
-rw-r--r--sys/sys/diskmbr.h1
-rw-r--r--sys/sys/filedesc.h1
-rw-r--r--sys/sys/mutex.h3
-rw-r--r--sys/sys/param.h2
-rw-r--r--sys/sys/pmckern.h9
-rw-r--r--sys/sys/protosw.h8
-rw-r--r--sys/sys/rwlock.h3
-rw-r--r--sys/sys/sleepqueue.h5
-rw-r--r--sys/sys/socket.h2
-rw-r--r--sys/sys/socketvar.h4
-rw-r--r--sys/sys/sx.h3
-rw-r--r--sys/sys/syscall.h6
-rw-r--r--sys/sys/syscall.mk6
-rw-r--r--sys/sys/sysproto.h18
-rw-r--r--sys/sys/systm.h27
-rw-r--r--sys/sys/time.h48
-rw-r--r--sys/vm/vm_object.c10
-rw-r--r--tools/make_libdeps.sh1
-rw-r--r--tools/regression/bin/sh/builtins/trap12.010
-rw-r--r--tools/regression/capsicum/syscalls/cap_ioctls_limit.c4
-rw-r--r--tools/regression/pjdfstest/Makefile2
-rw-r--r--tools/regression/pjdfstest/pjdfstest.c44
-rw-r--r--tools/tools/cxgbetool/cxgbetool.c1
-rw-r--r--usr.bin/Makefile.arm1
-rw-r--r--usr.bin/c89/c89.c2
-rw-r--r--usr.bin/c99/c99.c2
-rw-r--r--usr.bin/calendar/calendars/calendar.birthday1
-rw-r--r--usr.bin/find/extern.h2
-rw-r--r--usr.bin/find/find.16
-rw-r--r--usr.bin/find/function.c23
-rw-r--r--usr.bin/find/option.c1
-rw-r--r--usr.bin/hexdump/conv.c2
-rw-r--r--usr.bin/procstat/procstat_files.c7
-rw-r--r--usr.bin/truss/arm-fbsd.c369
-rw-r--r--usr.bin/truss/extern.h4
-rw-r--r--usr.bin/truss/main.c3
-rw-r--r--usr.sbin/bhyve/acpi.c16
-rw-r--r--usr.sbin/bhyve/pci_virtio_block.c17
-rw-r--r--usr.sbin/bhyve/pci_virtio_net.c15
-rw-r--r--usr.sbin/mount_portalfs/Makefile15
-rw-r--r--usr.sbin/mount_portalfs/activate.c195
-rw-r--r--usr.sbin/mount_portalfs/conf.c318
-rw-r--r--usr.sbin/mount_portalfs/cred.c75
-rw-r--r--usr.sbin/mount_portalfs/mount_portalfs.8216
-rw-r--r--usr.sbin/mount_portalfs/mount_portalfs.c281
-rw-r--r--usr.sbin/mount_portalfs/pathnames.h40
-rw-r--r--usr.sbin/mount_portalfs/portal.conf7
-rw-r--r--usr.sbin/mount_portalfs/portald.h86
-rw-r--r--usr.sbin/mount_portalfs/pt_conf.c50
-rw-r--r--usr.sbin/mount_portalfs/pt_exec.c50
-rw-r--r--usr.sbin/mount_portalfs/pt_file.c91
-rw-r--r--usr.sbin/mount_portalfs/pt_pipe.c229
-rw-r--r--usr.sbin/mount_portalfs/pt_tcp.c157
-rw-r--r--usr.sbin/mount_portalfs/pt_tcplisten.c201
-rwxr-xr-xusr.sbin/pc-sysinstall/backend/functions-bsdlabel.sh13
-rwxr-xr-xusr.sbin/pc-sysinstall/backend/functions-disk.sh1
-rwxr-xr-xusr.sbin/pc-sysinstall/backend/functions-extractimage.sh143
-rwxr-xr-xusr.sbin/pc-sysinstall/backend/functions-installpackages.sh131
-rwxr-xr-xusr.sbin/pc-sysinstall/backend/functions-mountdisk.sh8
-rwxr-xr-xusr.sbin/pc-sysinstall/backend/functions-newfs.sh44
-rwxr-xr-xusr.sbin/pc-sysinstall/backend/functions-packages.sh137
-rwxr-xr-xusr.sbin/pc-sysinstall/backend/functions-parse.sh2
-rwxr-xr-xusr.sbin/pc-sysinstall/backend/functions.sh6
-rwxr-xr-xusr.sbin/pc-sysinstall/backend/parseconfig.sh2
-rw-r--r--usr.sbin/pc-sysinstall/conf/pc-sysinstall.conf8
-rw-r--r--usr.sbin/pc-sysinstall/examples/README11
-rw-r--r--usr.sbin/pkg/Makefile6
-rw-r--r--usr.sbin/pkg/config.c428
-rw-r--r--usr.sbin/pkg/config.h (renamed from sys/fs/hpfs/hpfs_ioctl.h)35
-rw-r--r--usr.sbin/pkg/pkg.c186
-rw-r--r--usr.sbin/rtadvd/rtadvd.c2
-rw-r--r--usr.sbin/tzsetup/tzsetup.c5
677 files changed, 92793 insertions, 130105 deletions
diff --git a/MAINTAINERS b/MAINTAINERS
index 7df973a..41142d2 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -124,3 +124,6 @@ isci(4) jimharris Pre-commit review requested.
cmx daniel@roe.ch Pre-commit review preferred.
filemon obrien Pre-commit review preferred.
sysdoc trhodes Pre-commit review preferred.
+sh(1) jilles Pre-commit review requested. This also applies
+ to kill(1), printf(1) and test(1) which are
+ compiled in as builtins.
diff --git a/ObsoleteFiles.inc b/ObsoleteFiles.inc
index 33bb90b..cfa085f 100644
--- a/ObsoleteFiles.inc
+++ b/ObsoleteFiles.inc
@@ -38,6 +38,30 @@
# xargs -n1 | sort | uniq -d;
# done
+# 20130302: NTFS support removed
+OLD_FILES+=rescue/mount_ntfs
+OLD_FILES+=sbin/mount_ntfs
+OLD_FILES+=usr/include/fs/ntfs/ntfs.h
+OLD_FILES+=usr/include/fs/ntfs/ntfs_compr.h
+OLD_FILES+=usr/include/fs/ntfs/ntfs_ihash.h
+OLD_FILES+=usr/include/fs/ntfs/ntfs_inode.h
+OLD_FILES+=usr/include/fs/ntfs/ntfs_subr.h
+OLD_FILES+=usr/include/fs/ntfs/ntfs_vfsops.h
+OLD_FILES+=usr/include/fs/ntfs/ntfsmount.h
+OLD_DIRS+=usr/include/fs/ntfs
+OLD_FILES+=usr/share/man/man8/mount_ntfs.8.gz
+# 20130302: PORTALFS support removed
+OLD_FILES+=usr/include/fs/portalfs/portal.h
+OLD_DIRS+=usr/include/fs/portalfs
+OLD_FILES+=usr/sbin/mount_portalfs
+OLD_FILES+=usr/share/examples/portal/README
+OLD_FILES+=usr/share/examples/portal/portal.conf
+OLD_DIRS+=usr/share/examples/portal
+OLD_FILES+=usr/share/man/man8/mount_portalfs.8.gz
+# 20130302: CODAFS support removed
+OLD_FILES+=usr/share/man/man4/coda.4.gz
+# 20130302: XFS support removed
+OLD_FILES+=usr/share/man/man5/xfs.5.gz
# 20130116: removed long unused directories for .1aout section manpages
OLD_FILES+=usr/share/man/en.ISO8859-1/man1aout
OLD_FILES+=usr/share/man/en.UTF-8/man1aout
@@ -58,9 +82,10 @@ OLD_DIRS+=var/remote
# 20121114: zpool-features manual page moved from section 5 to 7
OLD_FILES+=usr/share/man/man5/zpool-features.5.gz
# 20121022: remove harp, hfa and idt man page
-OLD_FILES+=share/man/man4/harp.4
-OLD_FILES+=share/man/man4/hfa.4
-OLD_FILES+=share/man/man4/idt.4
+OLD_FILES+=usr/share/man/man4/harp.4.gz
+OLD_FILES+=usr/share/man/man4/hfa.4.gz
+OLD_FILES+=usr/share/man/man4/idt.4.gz
+OLD_FILES+=usr/share/man/man4/if_idt.4.gz
# 20121022: VFS_LOCK_GIANT elimination
OLD_FILES+=usr/share/man/man9/VFS_LOCK_GIANT.9.gz
OLD_FILES+=usr/share/man/man9/VFS_UNLOCK_GIANT.9.gz
diff --git a/UPDATING b/UPDATING
index 50e6452..99af0ed 100644
--- a/UPDATING
+++ b/UPDATING
@@ -26,6 +26,19 @@ NOTE TO PEOPLE WHO THINK THAT FreeBSD 10.x IS SLOW:
disable the most expensive debugging functionality run
"ln -s 'abort:false,junk:false' /etc/malloc.conf".)
+20130304:
+ Recent commits to callout(9) changed the size of struct callout,
+ so the KBI is probably heavily disturbed. Also, some functions
+ in callout(9)/sleep(9)/sleepqueue(9)/condvar(9) KPIs were replaced
+ by macros. Every kernel module using it won't load, so rebuild
+ is requested.
+
+ The ctl device has been re-enabled in GENERIC for i386 and amd64,
+ but does not initialize by default (because of the new CTL_DISABLE
+ option) to save memory. To re-enable it, remove the CTL_DISABLE
+ option from the kernel config file or set kern.cam.ctl.disable=0
+ in /boot/loader.conf.
+
20130301:
The ctl device has been disabled in GENERIC for i386 and amd64.
This was done due to the extra memory being allocated at system
diff --git a/bin/sh/trap.c b/bin/sh/trap.c
index 0a9eb60..6c4cbbe 100644
--- a/bin/sh/trap.c
+++ b/bin/sh/trap.c
@@ -455,7 +455,6 @@ dotrap(void)
last_trapsig = i;
savestatus = exitstatus;
evalstring(trap[i], 0);
- exitstatus = savestatus;
/*
* If such a command was not
@@ -464,9 +463,11 @@ dotrap(void)
* trap action to have an effect
* outside of it.
*/
- if (prev_evalskip != 0) {
+ if (evalskip == 0 ||
+ prev_evalskip != 0) {
evalskip = prev_evalskip;
skipcount = prev_skipcount;
+ exitstatus = savestatus;
}
if (i == SIGCHLD)
diff --git a/cddl/contrib/opensolaris/cmd/zdb/zdb.c b/cddl/contrib/opensolaris/cmd/zdb/zdb.c
index 0238c65..2f0e658 100644
--- a/cddl/contrib/opensolaris/cmd/zdb/zdb.c
+++ b/cddl/contrib/opensolaris/cmd/zdb/zdb.c
@@ -1189,7 +1189,7 @@ dump_bpobj_cb(void *arg, const blkptr_t *bp, dmu_tx_t *tx)
}
static void
-dump_bpobj(bpobj_t *bpo, char *name)
+dump_bpobj(bpobj_t *bpo, char *name, int indent)
{
char bytes[32];
char comp[32];
@@ -1199,31 +1199,56 @@ dump_bpobj(bpobj_t *bpo, char *name)
return;
zdb_nicenum(bpo->bpo_phys->bpo_bytes, bytes);
- if (bpo->bpo_havesubobj) {
+ if (bpo->bpo_havesubobj && bpo->bpo_phys->bpo_subobjs != 0) {
zdb_nicenum(bpo->bpo_phys->bpo_comp, comp);
zdb_nicenum(bpo->bpo_phys->bpo_uncomp, uncomp);
- (void) printf("\n %s: %llu local blkptrs, %llu subobjs, "
- "%s (%s/%s comp)\n",
- name, (u_longlong_t)bpo->bpo_phys->bpo_num_blkptrs,
+ (void) printf(" %*s: object %llu, %llu local blkptrs, "
+ "%llu subobjs, %s (%s/%s comp)\n",
+ indent * 8, name,
+ (u_longlong_t)bpo->bpo_object,
+ (u_longlong_t)bpo->bpo_phys->bpo_num_blkptrs,
(u_longlong_t)bpo->bpo_phys->bpo_num_subobjs,
bytes, comp, uncomp);
+
+ for (uint64_t i = 0; i < bpo->bpo_phys->bpo_num_subobjs; i++) {
+ uint64_t subobj;
+ bpobj_t subbpo;
+ int error;
+ VERIFY0(dmu_read(bpo->bpo_os,
+ bpo->bpo_phys->bpo_subobjs,
+ i * sizeof (subobj), sizeof (subobj), &subobj, 0));
+ error = bpobj_open(&subbpo, bpo->bpo_os, subobj);
+ if (error != 0) {
+ (void) printf("ERROR %u while trying to open "
+ "subobj id %llu\n",
+ error, (u_longlong_t)subobj);
+ continue;
+ }
+ dump_bpobj(&subbpo, "subobj", indent + 1);
+ }
} else {
- (void) printf("\n %s: %llu blkptrs, %s\n",
- name, (u_longlong_t)bpo->bpo_phys->bpo_num_blkptrs, bytes);
+ (void) printf(" %*s: object %llu, %llu blkptrs, %s\n",
+ indent * 8, name,
+ (u_longlong_t)bpo->bpo_object,
+ (u_longlong_t)bpo->bpo_phys->bpo_num_blkptrs,
+ bytes);
}
if (dump_opt['d'] < 5)
return;
- (void) printf("\n");
- (void) bpobj_iterate_nofree(bpo, dump_bpobj_cb, NULL, NULL);
+ if (indent == 0) {
+ (void) bpobj_iterate_nofree(bpo, dump_bpobj_cb, NULL, NULL);
+ (void) printf("\n");
+ }
}
static void
dump_deadlist(dsl_deadlist_t *dl)
{
dsl_deadlist_entry_t *dle;
+ uint64_t unused;
char bytes[32];
char comp[32];
char uncomp[32];
@@ -1242,14 +1267,24 @@ dump_deadlist(dsl_deadlist_t *dl)
(void) printf("\n");
+ /* force the tree to be loaded */
+ dsl_deadlist_space_range(dl, 0, UINT64_MAX, &unused, &unused, &unused);
+
for (dle = avl_first(&dl->dl_tree); dle;
dle = AVL_NEXT(&dl->dl_tree, dle)) {
- (void) printf(" mintxg %llu -> obj %llu\n",
- (longlong_t)dle->dle_mintxg,
- (longlong_t)dle->dle_bpobj.bpo_object);
+ if (dump_opt['d'] >= 5) {
+ char buf[128];
+ (void) snprintf(buf, sizeof (buf), "mintxg %llu -> ",
+ (longlong_t)dle->dle_mintxg,
+ (longlong_t)dle->dle_bpobj.bpo_object);
- if (dump_opt['d'] >= 5)
- dump_bpobj(&dle->dle_bpobj, "");
+ dump_bpobj(&dle->dle_bpobj, buf, 0);
+ } else {
+ (void) printf("mintxg %llu -> obj %llu\n",
+ (longlong_t)dle->dle_mintxg,
+ (longlong_t)dle->dle_bpobj.bpo_object);
+
+ }
}
}
@@ -1272,7 +1307,7 @@ fuid_table_destroy()
* print uid or gid information.
* For normal POSIX id just the id is printed in decimal format.
* For CIFS files with FUID the fuid is printed in hex followed by
- * the doman-rid string.
+ * the domain-rid string.
*/
static void
print_idstr(uint64_t id, const char *id_type)
@@ -2529,10 +2564,11 @@ dump_zpool(spa_t *spa)
if (dump_opt['d'] || dump_opt['i']) {
dump_dir(dp->dp_meta_objset);
if (dump_opt['d'] >= 3) {
- dump_bpobj(&spa->spa_deferred_bpobj, "Deferred frees");
+ dump_bpobj(&spa->spa_deferred_bpobj,
+ "Deferred frees", 0);
if (spa_version(spa) >= SPA_VERSION_DEADLISTS) {
dump_bpobj(&spa->spa_dsl_pool->dp_free_bpobj,
- "Pool snapshot frees");
+ "Pool snapshot frees", 0);
}
if (spa_feature_is_active(spa,
diff --git a/cddl/contrib/opensolaris/tools/ctf/cvt/output.c b/cddl/contrib/opensolaris/tools/ctf/cvt/output.c
index bfe5b7e..af79769 100644
--- a/cddl/contrib/opensolaris/tools/ctf/cvt/output.c
+++ b/cddl/contrib/opensolaris/tools/ctf/cvt/output.c
@@ -363,6 +363,7 @@ sort_iidescs(Elf *elf, const char *file, tdata_t *td, int fuzzymatch,
for (i = 0; i < nent; i++) {
GElf_Sym sym;
+ char *bname;
iidesc_t **tolist;
GElf_Sym ssym;
iidesc_match_t smatch;
@@ -377,7 +378,8 @@ sort_iidescs(Elf *elf, const char *file, tdata_t *td, int fuzzymatch,
switch (GELF_ST_TYPE(sym.st_info)) {
case STT_FILE:
- match.iim_file = match.iim_name;
+ bname = strrchr(match.iim_name, '/');
+ match.iim_file = bname == NULL ? match.iim_name : bname + 1;
continue;
case STT_OBJECT:
tolist = iiburst->iib_objts;
diff --git a/contrib/libyaml/LICENSE b/contrib/libyaml/LICENSE
new file mode 100644
index 0000000..050ced2
--- /dev/null
+++ b/contrib/libyaml/LICENSE
@@ -0,0 +1,19 @@
+Copyright (c) 2006 Kirill Simonov
+
+Permission is hereby granted, free of charge, to any person obtaining a copy of
+this software and associated documentation files (the "Software"), to deal in
+the Software without restriction, including without limitation the rights to
+use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
+of the Software, and to permit persons to whom the Software is furnished to do
+so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.
diff --git a/contrib/libyaml/Makefile.am b/contrib/libyaml/Makefile.am
new file mode 100644
index 0000000..4111fdb
--- /dev/null
+++ b/contrib/libyaml/Makefile.am
@@ -0,0 +1,18 @@
+## Run `./bootstrap` to generate the "Makefile.in" files in this directory and
+## the "$SUBDIRS" subdirectories.
+
+SUBDIRS = include src . tests win32
+
+EXTRA_DIST = README LICENSE doc/doxygen.cfg
+
+pkgconfigdir = $(libdir)/pkgconfig
+pkgconfig_DATA = yaml-0.1.pc
+
+maintainer-clean-local:
+ -rm -f aclocal.m4 config.h.in configure config/*
+ -find ${builddir} -name Makefile.in -exec rm -f '{}' ';'
+
+.PHONY: bootstrap
+bootstrap: maintainer-clean
+ ./bootstrap
+
diff --git a/contrib/libyaml/Makefile.in b/contrib/libyaml/Makefile.in
new file mode 100644
index 0000000..eec3474
--- /dev/null
+++ b/contrib/libyaml/Makefile.in
@@ -0,0 +1,782 @@
+# Makefile.in generated by automake 1.11.1 from Makefile.am.
+# @configure_input@
+
+# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
+# 2003, 2004, 2005, 2006, 2007, 2008, 2009 Free Software Foundation,
+# Inc.
+# This Makefile.in is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
+# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+# PARTICULAR PURPOSE.
+
+@SET_MAKE@
+
+VPATH = @srcdir@
+pkgdatadir = $(datadir)/@PACKAGE@
+pkgincludedir = $(includedir)/@PACKAGE@
+pkglibdir = $(libdir)/@PACKAGE@
+pkglibexecdir = $(libexecdir)/@PACKAGE@
+am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
+install_sh_DATA = $(install_sh) -c -m 644
+install_sh_PROGRAM = $(install_sh) -c
+install_sh_SCRIPT = $(install_sh) -c
+INSTALL_HEADER = $(INSTALL_DATA)
+transform = $(program_transform_name)
+NORMAL_INSTALL = :
+PRE_INSTALL = :
+POST_INSTALL = :
+NORMAL_UNINSTALL = :
+PRE_UNINSTALL = :
+POST_UNINSTALL = :
+build_triplet = @build@
+host_triplet = @host@
+subdir = .
+DIST_COMMON = README $(am__configure_deps) $(srcdir)/Makefile.am \
+ $(srcdir)/Makefile.in $(srcdir)/config.h.in \
+ $(srcdir)/yaml-0.1.pc.in $(top_srcdir)/configure \
+ config/config.guess config/config.sub config/depcomp \
+ config/install-sh config/ltmain.sh config/missing
+ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
+am__aclocal_m4_deps = $(top_srcdir)/configure.ac
+am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
+ $(ACLOCAL_M4)
+am__CONFIG_DISTCLEAN_FILES = config.status config.cache config.log \
+ configure.lineno config.status.lineno
+mkinstalldirs = $(install_sh) -d
+CONFIG_HEADER = config.h
+CONFIG_CLEAN_FILES = yaml-0.1.pc
+CONFIG_CLEAN_VPATH_FILES =
+SOURCES =
+DIST_SOURCES =
+RECURSIVE_TARGETS = all-recursive check-recursive dvi-recursive \
+ html-recursive info-recursive install-data-recursive \
+ install-dvi-recursive install-exec-recursive \
+ install-html-recursive install-info-recursive \
+ install-pdf-recursive install-ps-recursive install-recursive \
+ installcheck-recursive installdirs-recursive pdf-recursive \
+ ps-recursive uninstall-recursive
+am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`;
+am__vpath_adj = case $$p in \
+ $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \
+ *) f=$$p;; \
+ esac;
+am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`;
+am__install_max = 40
+am__nobase_strip_setup = \
+ srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'`
+am__nobase_strip = \
+ for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||"
+am__nobase_list = $(am__nobase_strip_setup); \
+ for p in $$list; do echo "$$p $$p"; done | \
+ sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \
+ $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \
+ if (++n[$$2] == $(am__install_max)) \
+ { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \
+ END { for (dir in files) print dir, files[dir] }'
+am__base_list = \
+ sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \
+ sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g'
+am__installdirs = "$(DESTDIR)$(pkgconfigdir)"
+DATA = $(pkgconfig_DATA)
+RECURSIVE_CLEAN_TARGETS = mostlyclean-recursive clean-recursive \
+ distclean-recursive maintainer-clean-recursive
+AM_RECURSIVE_TARGETS = $(RECURSIVE_TARGETS:-recursive=) \
+ $(RECURSIVE_CLEAN_TARGETS:-recursive=) tags TAGS ctags CTAGS \
+ distdir dist dist-all distcheck
+ETAGS = etags
+CTAGS = ctags
+DIST_SUBDIRS = $(SUBDIRS)
+DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
+distdir = $(PACKAGE)-$(VERSION)
+top_distdir = $(distdir)
+am__remove_distdir = \
+ { test ! -d "$(distdir)" \
+ || { find "$(distdir)" -type d ! -perm -200 -exec chmod u+w {} ';' \
+ && rm -fr "$(distdir)"; }; }
+am__relativize = \
+ dir0=`pwd`; \
+ sed_first='s,^\([^/]*\)/.*$$,\1,'; \
+ sed_rest='s,^[^/]*/*,,'; \
+ sed_last='s,^.*/\([^/]*\)$$,\1,'; \
+ sed_butlast='s,/*[^/]*$$,,'; \
+ while test -n "$$dir1"; do \
+ first=`echo "$$dir1" | sed -e "$$sed_first"`; \
+ if test "$$first" != "."; then \
+ if test "$$first" = ".."; then \
+ dir2=`echo "$$dir0" | sed -e "$$sed_last"`/"$$dir2"; \
+ dir0=`echo "$$dir0" | sed -e "$$sed_butlast"`; \
+ else \
+ first2=`echo "$$dir2" | sed -e "$$sed_first"`; \
+ if test "$$first2" = "$$first"; then \
+ dir2=`echo "$$dir2" | sed -e "$$sed_rest"`; \
+ else \
+ dir2="../$$dir2"; \
+ fi; \
+ dir0="$$dir0"/"$$first"; \
+ fi; \
+ fi; \
+ dir1=`echo "$$dir1" | sed -e "$$sed_rest"`; \
+ done; \
+ reldir="$$dir2"
+DIST_ARCHIVES = $(distdir).tar.gz
+GZIP_ENV = --best
+distuninstallcheck_listfiles = find . -type f -print
+distcleancheck_listfiles = find . -type f -print
+ACLOCAL = @ACLOCAL@
+AMTAR = @AMTAR@
+AR = @AR@
+AUTOCONF = @AUTOCONF@
+AUTOHEADER = @AUTOHEADER@
+AUTOMAKE = @AUTOMAKE@
+AWK = @AWK@
+CC = @CC@
+CCDEPMODE = @CCDEPMODE@
+CFLAGS = @CFLAGS@
+CPP = @CPP@
+CPPFLAGS = @CPPFLAGS@
+CYGPATH_W = @CYGPATH_W@
+DEFS = @DEFS@
+DEPDIR = @DEPDIR@
+DOXYGEN = @DOXYGEN@
+DSYMUTIL = @DSYMUTIL@
+DUMPBIN = @DUMPBIN@
+ECHO_C = @ECHO_C@
+ECHO_N = @ECHO_N@
+ECHO_T = @ECHO_T@
+EGREP = @EGREP@
+EXEEXT = @EXEEXT@
+FGREP = @FGREP@
+GREP = @GREP@
+INSTALL = @INSTALL@
+INSTALL_DATA = @INSTALL_DATA@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@
+INSTALL_SCRIPT = @INSTALL_SCRIPT@
+INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
+LD = @LD@
+LDFLAGS = @LDFLAGS@
+LIBOBJS = @LIBOBJS@
+LIBS = @LIBS@
+LIBTOOL = @LIBTOOL@
+LIPO = @LIPO@
+LN_S = @LN_S@
+LTLIBOBJS = @LTLIBOBJS@
+MAKEINFO = @MAKEINFO@
+MKDIR_P = @MKDIR_P@
+NM = @NM@
+NMEDIT = @NMEDIT@
+OBJDUMP = @OBJDUMP@
+OBJEXT = @OBJEXT@
+OTOOL = @OTOOL@
+OTOOL64 = @OTOOL64@
+PACKAGE = @PACKAGE@
+PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
+PACKAGE_NAME = @PACKAGE_NAME@
+PACKAGE_STRING = @PACKAGE_STRING@
+PACKAGE_TARNAME = @PACKAGE_TARNAME@
+PACKAGE_URL = @PACKAGE_URL@
+PACKAGE_VERSION = @PACKAGE_VERSION@
+PATH_SEPARATOR = @PATH_SEPARATOR@
+RANLIB = @RANLIB@
+SED = @SED@
+SET_MAKE = @SET_MAKE@
+SHELL = @SHELL@
+STRIP = @STRIP@
+VERSION = @VERSION@
+YAML_LT_AGE = @YAML_LT_AGE@
+YAML_LT_CURRENT = @YAML_LT_CURRENT@
+YAML_LT_RELEASE = @YAML_LT_RELEASE@
+YAML_LT_REVISION = @YAML_LT_REVISION@
+abs_builddir = @abs_builddir@
+abs_srcdir = @abs_srcdir@
+abs_top_builddir = @abs_top_builddir@
+abs_top_srcdir = @abs_top_srcdir@
+ac_ct_CC = @ac_ct_CC@
+ac_ct_DUMPBIN = @ac_ct_DUMPBIN@
+am__include = @am__include@
+am__leading_dot = @am__leading_dot@
+am__quote = @am__quote@
+am__tar = @am__tar@
+am__untar = @am__untar@
+bindir = @bindir@
+build = @build@
+build_alias = @build_alias@
+build_cpu = @build_cpu@
+build_os = @build_os@
+build_vendor = @build_vendor@
+builddir = @builddir@
+datadir = @datadir@
+datarootdir = @datarootdir@
+docdir = @docdir@
+dvidir = @dvidir@
+exec_prefix = @exec_prefix@
+host = @host@
+host_alias = @host_alias@
+host_cpu = @host_cpu@
+host_os = @host_os@
+host_vendor = @host_vendor@
+htmldir = @htmldir@
+includedir = @includedir@
+infodir = @infodir@
+install_sh = @install_sh@
+libdir = @libdir@
+libexecdir = @libexecdir@
+localedir = @localedir@
+localstatedir = @localstatedir@
+lt_ECHO = @lt_ECHO@
+mandir = @mandir@
+mkdir_p = @mkdir_p@
+oldincludedir = @oldincludedir@
+pdfdir = @pdfdir@
+prefix = @prefix@
+program_transform_name = @program_transform_name@
+psdir = @psdir@
+sbindir = @sbindir@
+sharedstatedir = @sharedstatedir@
+srcdir = @srcdir@
+sysconfdir = @sysconfdir@
+target_alias = @target_alias@
+top_build_prefix = @top_build_prefix@
+top_builddir = @top_builddir@
+top_srcdir = @top_srcdir@
+SUBDIRS = include src . tests win32
+EXTRA_DIST = README LICENSE doc/doxygen.cfg
+pkgconfigdir = $(libdir)/pkgconfig
+pkgconfig_DATA = yaml-0.1.pc
+all: config.h
+ $(MAKE) $(AM_MAKEFLAGS) all-recursive
+
+.SUFFIXES:
+am--refresh:
+ @:
+$(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps)
+ @for dep in $?; do \
+ case '$(am__configure_deps)' in \
+ *$$dep*) \
+ echo ' cd $(srcdir) && $(AUTOMAKE) --foreign'; \
+ $(am__cd) $(srcdir) && $(AUTOMAKE) --foreign \
+ && exit 0; \
+ exit 1;; \
+ esac; \
+ done; \
+ echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign Makefile'; \
+ $(am__cd) $(top_srcdir) && \
+ $(AUTOMAKE) --foreign Makefile
+.PRECIOUS: Makefile
+Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
+ @case '$?' in \
+ *config.status*) \
+ echo ' $(SHELL) ./config.status'; \
+ $(SHELL) ./config.status;; \
+ *) \
+ echo ' cd $(top_builddir) && $(SHELL) ./config.status $@ $(am__depfiles_maybe)'; \
+ cd $(top_builddir) && $(SHELL) ./config.status $@ $(am__depfiles_maybe);; \
+ esac;
+
+$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
+ $(SHELL) ./config.status --recheck
+
+$(top_srcdir)/configure: $(am__configure_deps)
+ $(am__cd) $(srcdir) && $(AUTOCONF)
+$(ACLOCAL_M4): $(am__aclocal_m4_deps)
+ $(am__cd) $(srcdir) && $(ACLOCAL) $(ACLOCAL_AMFLAGS)
+$(am__aclocal_m4_deps):
+
+config.h: stamp-h1
+ @if test ! -f $@; then \
+ rm -f stamp-h1; \
+ $(MAKE) $(AM_MAKEFLAGS) stamp-h1; \
+ else :; fi
+
+stamp-h1: $(srcdir)/config.h.in $(top_builddir)/config.status
+ @rm -f stamp-h1
+ cd $(top_builddir) && $(SHELL) ./config.status config.h
+$(srcdir)/config.h.in: $(am__configure_deps)
+ ($(am__cd) $(top_srcdir) && $(AUTOHEADER))
+ rm -f stamp-h1
+ touch $@
+
+distclean-hdr:
+ -rm -f config.h stamp-h1
+yaml-0.1.pc: $(top_builddir)/config.status $(srcdir)/yaml-0.1.pc.in
+ cd $(top_builddir) && $(SHELL) ./config.status $@
+
+mostlyclean-libtool:
+ -rm -f *.lo
+
+clean-libtool:
+ -rm -rf .libs _libs
+
+distclean-libtool:
+ -rm -f libtool config.lt
+install-pkgconfigDATA: $(pkgconfig_DATA)
+ @$(NORMAL_INSTALL)
+ test -z "$(pkgconfigdir)" || $(MKDIR_P) "$(DESTDIR)$(pkgconfigdir)"
+ @list='$(pkgconfig_DATA)'; test -n "$(pkgconfigdir)" || list=; \
+ for p in $$list; do \
+ if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \
+ echo "$$d$$p"; \
+ done | $(am__base_list) | \
+ while read files; do \
+ echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(pkgconfigdir)'"; \
+ $(INSTALL_DATA) $$files "$(DESTDIR)$(pkgconfigdir)" || exit $$?; \
+ done
+
+uninstall-pkgconfigDATA:
+ @$(NORMAL_UNINSTALL)
+ @list='$(pkgconfig_DATA)'; test -n "$(pkgconfigdir)" || list=; \
+ files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \
+ test -n "$$files" || exit 0; \
+ echo " ( cd '$(DESTDIR)$(pkgconfigdir)' && rm -f" $$files ")"; \
+ cd "$(DESTDIR)$(pkgconfigdir)" && rm -f $$files
+
+# This directory's subdirectories are mostly independent; you can cd
+# into them and run `make' without going through this Makefile.
+# To change the values of `make' variables: instead of editing Makefiles,
+# (1) if the variable is set in `config.status', edit `config.status'
+# (which will cause the Makefiles to be regenerated when you run `make');
+# (2) otherwise, pass the desired values on the `make' command line.
+$(RECURSIVE_TARGETS):
+ @fail= failcom='exit 1'; \
+ for f in x $$MAKEFLAGS; do \
+ case $$f in \
+ *=* | --[!k]*);; \
+ *k*) failcom='fail=yes';; \
+ esac; \
+ done; \
+ dot_seen=no; \
+ target=`echo $@ | sed s/-recursive//`; \
+ list='$(SUBDIRS)'; for subdir in $$list; do \
+ echo "Making $$target in $$subdir"; \
+ if test "$$subdir" = "."; then \
+ dot_seen=yes; \
+ local_target="$$target-am"; \
+ else \
+ local_target="$$target"; \
+ fi; \
+ ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \
+ || eval $$failcom; \
+ done; \
+ if test "$$dot_seen" = "no"; then \
+ $(MAKE) $(AM_MAKEFLAGS) "$$target-am" || exit 1; \
+ fi; test -z "$$fail"
+
+$(RECURSIVE_CLEAN_TARGETS):
+ @fail= failcom='exit 1'; \
+ for f in x $$MAKEFLAGS; do \
+ case $$f in \
+ *=* | --[!k]*);; \
+ *k*) failcom='fail=yes';; \
+ esac; \
+ done; \
+ dot_seen=no; \
+ case "$@" in \
+ distclean-* | maintainer-clean-*) list='$(DIST_SUBDIRS)' ;; \
+ *) list='$(SUBDIRS)' ;; \
+ esac; \
+ rev=''; for subdir in $$list; do \
+ if test "$$subdir" = "."; then :; else \
+ rev="$$subdir $$rev"; \
+ fi; \
+ done; \
+ rev="$$rev ."; \
+ target=`echo $@ | sed s/-recursive//`; \
+ for subdir in $$rev; do \
+ echo "Making $$target in $$subdir"; \
+ if test "$$subdir" = "."; then \
+ local_target="$$target-am"; \
+ else \
+ local_target="$$target"; \
+ fi; \
+ ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \
+ || eval $$failcom; \
+ done && test -z "$$fail"
+tags-recursive:
+ list='$(SUBDIRS)'; for subdir in $$list; do \
+ test "$$subdir" = . || ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) tags); \
+ done
+ctags-recursive:
+ list='$(SUBDIRS)'; for subdir in $$list; do \
+ test "$$subdir" = . || ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) ctags); \
+ done
+
+ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES)
+ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
+ unique=`for i in $$list; do \
+ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+ done | \
+ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \
+ END { if (nonempty) { for (i in files) print i; }; }'`; \
+ mkid -fID $$unique
+tags: TAGS
+
+TAGS: tags-recursive $(HEADERS) $(SOURCES) config.h.in $(TAGS_DEPENDENCIES) \
+ $(TAGS_FILES) $(LISP)
+ set x; \
+ here=`pwd`; \
+ if ($(ETAGS) --etags-include --version) >/dev/null 2>&1; then \
+ include_option=--etags-include; \
+ empty_fix=.; \
+ else \
+ include_option=--include; \
+ empty_fix=; \
+ fi; \
+ list='$(SUBDIRS)'; for subdir in $$list; do \
+ if test "$$subdir" = .; then :; else \
+ test ! -f $$subdir/TAGS || \
+ set "$$@" "$$include_option=$$here/$$subdir/TAGS"; \
+ fi; \
+ done; \
+ list='$(SOURCES) $(HEADERS) config.h.in $(LISP) $(TAGS_FILES)'; \
+ unique=`for i in $$list; do \
+ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+ done | \
+ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \
+ END { if (nonempty) { for (i in files) print i; }; }'`; \
+ shift; \
+ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \
+ test -n "$$unique" || unique=$$empty_fix; \
+ if test $$# -gt 0; then \
+ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
+ "$$@" $$unique; \
+ else \
+ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
+ $$unique; \
+ fi; \
+ fi
+ctags: CTAGS
+CTAGS: ctags-recursive $(HEADERS) $(SOURCES) config.h.in $(TAGS_DEPENDENCIES) \
+ $(TAGS_FILES) $(LISP)
+ list='$(SOURCES) $(HEADERS) config.h.in $(LISP) $(TAGS_FILES)'; \
+ unique=`for i in $$list; do \
+ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+ done | \
+ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \
+ END { if (nonempty) { for (i in files) print i; }; }'`; \
+ test -z "$(CTAGS_ARGS)$$unique" \
+ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \
+ $$unique
+
+GTAGS:
+ here=`$(am__cd) $(top_builddir) && pwd` \
+ && $(am__cd) $(top_srcdir) \
+ && gtags -i $(GTAGS_ARGS) "$$here"
+
+distclean-tags:
+ -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
+
+distdir: $(DISTFILES)
+ $(am__remove_distdir)
+ test -d "$(distdir)" || mkdir "$(distdir)"
+ @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+ list='$(DISTFILES)'; \
+ dist_files=`for file in $$list; do echo $$file; done | \
+ sed -e "s|^$$srcdirstrip/||;t" \
+ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \
+ case $$dist_files in \
+ */*) $(MKDIR_P) `echo "$$dist_files" | \
+ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \
+ sort -u` ;; \
+ esac; \
+ for file in $$dist_files; do \
+ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
+ if test -d $$d/$$file; then \
+ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \
+ if test -d "$(distdir)/$$file"; then \
+ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
+ fi; \
+ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
+ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \
+ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
+ fi; \
+ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \
+ else \
+ test -f "$(distdir)/$$file" \
+ || cp -p $$d/$$file "$(distdir)/$$file" \
+ || exit 1; \
+ fi; \
+ done
+ @list='$(DIST_SUBDIRS)'; for subdir in $$list; do \
+ if test "$$subdir" = .; then :; else \
+ test -d "$(distdir)/$$subdir" \
+ || $(MKDIR_P) "$(distdir)/$$subdir" \
+ || exit 1; \
+ fi; \
+ done
+ @list='$(DIST_SUBDIRS)'; for subdir in $$list; do \
+ if test "$$subdir" = .; then :; else \
+ dir1=$$subdir; dir2="$(distdir)/$$subdir"; \
+ $(am__relativize); \
+ new_distdir=$$reldir; \
+ dir1=$$subdir; dir2="$(top_distdir)"; \
+ $(am__relativize); \
+ new_top_distdir=$$reldir; \
+ echo " (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) top_distdir="$$new_top_distdir" distdir="$$new_distdir" \\"; \
+ echo " am__remove_distdir=: am__skip_length_check=: am__skip_mode_fix=: distdir)"; \
+ ($(am__cd) $$subdir && \
+ $(MAKE) $(AM_MAKEFLAGS) \
+ top_distdir="$$new_top_distdir" \
+ distdir="$$new_distdir" \
+ am__remove_distdir=: \
+ am__skip_length_check=: \
+ am__skip_mode_fix=: \
+ distdir) \
+ || exit 1; \
+ fi; \
+ done
+ -test -n "$(am__skip_mode_fix)" \
+ || find "$(distdir)" -type d ! -perm -755 \
+ -exec chmod u+rwx,go+rx {} \; -o \
+ ! -type d ! -perm -444 -links 1 -exec chmod a+r {} \; -o \
+ ! -type d ! -perm -400 -exec chmod a+r {} \; -o \
+ ! -type d ! -perm -444 -exec $(install_sh) -c -m a+r {} {} \; \
+ || chmod -R a+r "$(distdir)"
+dist-gzip: distdir
+ tardir=$(distdir) && $(am__tar) | GZIP=$(GZIP_ENV) gzip -c >$(distdir).tar.gz
+ $(am__remove_distdir)
+
+dist-bzip2: distdir
+ tardir=$(distdir) && $(am__tar) | bzip2 -9 -c >$(distdir).tar.bz2
+ $(am__remove_distdir)
+
+dist-lzma: distdir
+ tardir=$(distdir) && $(am__tar) | lzma -9 -c >$(distdir).tar.lzma
+ $(am__remove_distdir)
+
+dist-xz: distdir
+ tardir=$(distdir) && $(am__tar) | xz -c >$(distdir).tar.xz
+ $(am__remove_distdir)
+
+dist-tarZ: distdir
+ tardir=$(distdir) && $(am__tar) | compress -c >$(distdir).tar.Z
+ $(am__remove_distdir)
+
+dist-shar: distdir
+ shar $(distdir) | GZIP=$(GZIP_ENV) gzip -c >$(distdir).shar.gz
+ $(am__remove_distdir)
+
+dist-zip: distdir
+ -rm -f $(distdir).zip
+ zip -rq $(distdir).zip $(distdir)
+ $(am__remove_distdir)
+
+dist dist-all: distdir
+ tardir=$(distdir) && $(am__tar) | GZIP=$(GZIP_ENV) gzip -c >$(distdir).tar.gz
+ $(am__remove_distdir)
+
+# This target untars the dist file and tries a VPATH configuration. Then
+# it guarantees that the distribution is self-contained by making another
+# tarfile.
+distcheck: dist
+ case '$(DIST_ARCHIVES)' in \
+ *.tar.gz*) \
+ GZIP=$(GZIP_ENV) gzip -dc $(distdir).tar.gz | $(am__untar) ;;\
+ *.tar.bz2*) \
+ bzip2 -dc $(distdir).tar.bz2 | $(am__untar) ;;\
+ *.tar.lzma*) \
+ lzma -dc $(distdir).tar.lzma | $(am__untar) ;;\
+ *.tar.xz*) \
+ xz -dc $(distdir).tar.xz | $(am__untar) ;;\
+ *.tar.Z*) \
+ uncompress -c $(distdir).tar.Z | $(am__untar) ;;\
+ *.shar.gz*) \
+ GZIP=$(GZIP_ENV) gzip -dc $(distdir).shar.gz | unshar ;;\
+ *.zip*) \
+ unzip $(distdir).zip ;;\
+ esac
+ chmod -R a-w $(distdir); chmod a+w $(distdir)
+ mkdir $(distdir)/_build
+ mkdir $(distdir)/_inst
+ chmod a-w $(distdir)
+ test -d $(distdir)/_build || exit 0; \
+ dc_install_base=`$(am__cd) $(distdir)/_inst && pwd | sed -e 's,^[^:\\/]:[\\/],/,'` \
+ && dc_destdir="$${TMPDIR-/tmp}/am-dc-$$$$/" \
+ && am__cwd=`pwd` \
+ && $(am__cd) $(distdir)/_build \
+ && ../configure --srcdir=.. --prefix="$$dc_install_base" \
+ $(DISTCHECK_CONFIGURE_FLAGS) \
+ && $(MAKE) $(AM_MAKEFLAGS) \
+ && $(MAKE) $(AM_MAKEFLAGS) dvi \
+ && $(MAKE) $(AM_MAKEFLAGS) check \
+ && $(MAKE) $(AM_MAKEFLAGS) install \
+ && $(MAKE) $(AM_MAKEFLAGS) installcheck \
+ && $(MAKE) $(AM_MAKEFLAGS) uninstall \
+ && $(MAKE) $(AM_MAKEFLAGS) distuninstallcheck_dir="$$dc_install_base" \
+ distuninstallcheck \
+ && chmod -R a-w "$$dc_install_base" \
+ && ({ \
+ (cd ../.. && umask 077 && mkdir "$$dc_destdir") \
+ && $(MAKE) $(AM_MAKEFLAGS) DESTDIR="$$dc_destdir" install \
+ && $(MAKE) $(AM_MAKEFLAGS) DESTDIR="$$dc_destdir" uninstall \
+ && $(MAKE) $(AM_MAKEFLAGS) DESTDIR="$$dc_destdir" \
+ distuninstallcheck_dir="$$dc_destdir" distuninstallcheck; \
+ } || { rm -rf "$$dc_destdir"; exit 1; }) \
+ && rm -rf "$$dc_destdir" \
+ && $(MAKE) $(AM_MAKEFLAGS) dist \
+ && rm -rf $(DIST_ARCHIVES) \
+ && $(MAKE) $(AM_MAKEFLAGS) distcleancheck \
+ && cd "$$am__cwd" \
+ || exit 1
+ $(am__remove_distdir)
+ @(echo "$(distdir) archives ready for distribution: "; \
+ list='$(DIST_ARCHIVES)'; for i in $$list; do echo $$i; done) | \
+ sed -e 1h -e 1s/./=/g -e 1p -e 1x -e '$$p' -e '$$x'
+distuninstallcheck:
+ @$(am__cd) '$(distuninstallcheck_dir)' \
+ && test `$(distuninstallcheck_listfiles) | wc -l` -le 1 \
+ || { echo "ERROR: files left after uninstall:" ; \
+ if test -n "$(DESTDIR)"; then \
+ echo " (check DESTDIR support)"; \
+ fi ; \
+ $(distuninstallcheck_listfiles) ; \
+ exit 1; } >&2
+distcleancheck: distclean
+ @if test '$(srcdir)' = . ; then \
+ echo "ERROR: distcleancheck can only run from a VPATH build" ; \
+ exit 1 ; \
+ fi
+ @test `$(distcleancheck_listfiles) | wc -l` -eq 0 \
+ || { echo "ERROR: files left in build directory after distclean:" ; \
+ $(distcleancheck_listfiles) ; \
+ exit 1; } >&2
+check-am: all-am
+check: check-recursive
+all-am: Makefile $(DATA) config.h
+installdirs: installdirs-recursive
+installdirs-am:
+ for dir in "$(DESTDIR)$(pkgconfigdir)"; do \
+ test -z "$$dir" || $(MKDIR_P) "$$dir"; \
+ done
+install: install-recursive
+install-exec: install-exec-recursive
+install-data: install-data-recursive
+uninstall: uninstall-recursive
+
+install-am: all-am
+ @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
+
+installcheck: installcheck-recursive
+install-strip:
+ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+ `test -z '$(STRIP)' || \
+ echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install
+mostlyclean-generic:
+
+clean-generic:
+
+distclean-generic:
+ -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
+ -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES)
+
+maintainer-clean-generic:
+ @echo "This command is intended for maintainers to use"
+ @echo "it deletes files that may require special tools to rebuild."
+clean: clean-recursive
+
+clean-am: clean-generic clean-libtool mostlyclean-am
+
+distclean: distclean-recursive
+ -rm -f $(am__CONFIG_DISTCLEAN_FILES)
+ -rm -f Makefile
+distclean-am: clean-am distclean-generic distclean-hdr \
+ distclean-libtool distclean-tags
+
+dvi: dvi-recursive
+
+dvi-am:
+
+html: html-recursive
+
+html-am:
+
+info: info-recursive
+
+info-am:
+
+install-data-am: install-pkgconfigDATA
+
+install-dvi: install-dvi-recursive
+
+install-dvi-am:
+
+install-exec-am:
+
+install-html: install-html-recursive
+
+install-html-am:
+
+install-info: install-info-recursive
+
+install-info-am:
+
+install-man:
+
+install-pdf: install-pdf-recursive
+
+install-pdf-am:
+
+install-ps: install-ps-recursive
+
+install-ps-am:
+
+installcheck-am:
+
+maintainer-clean: maintainer-clean-recursive
+ -rm -f $(am__CONFIG_DISTCLEAN_FILES)
+ -rm -rf $(top_srcdir)/autom4te.cache
+ -rm -f Makefile
+maintainer-clean-am: distclean-am maintainer-clean-generic \
+ maintainer-clean-local
+
+mostlyclean: mostlyclean-recursive
+
+mostlyclean-am: mostlyclean-generic mostlyclean-libtool
+
+pdf: pdf-recursive
+
+pdf-am:
+
+ps: ps-recursive
+
+ps-am:
+
+uninstall-am: uninstall-pkgconfigDATA
+
+.MAKE: $(RECURSIVE_CLEAN_TARGETS) $(RECURSIVE_TARGETS) all \
+ ctags-recursive install-am install-strip tags-recursive
+
+.PHONY: $(RECURSIVE_CLEAN_TARGETS) $(RECURSIVE_TARGETS) CTAGS GTAGS \
+ all all-am am--refresh check check-am clean clean-generic \
+ clean-libtool ctags ctags-recursive dist dist-all dist-bzip2 \
+ dist-gzip dist-lzma dist-shar dist-tarZ dist-xz dist-zip \
+ distcheck distclean distclean-generic distclean-hdr \
+ distclean-libtool distclean-tags distcleancheck distdir \
+ distuninstallcheck dvi dvi-am html html-am info info-am \
+ install install-am install-data install-data-am install-dvi \
+ install-dvi-am install-exec install-exec-am install-html \
+ install-html-am install-info install-info-am install-man \
+ install-pdf install-pdf-am install-pkgconfigDATA install-ps \
+ install-ps-am install-strip installcheck installcheck-am \
+ installdirs installdirs-am maintainer-clean \
+ maintainer-clean-generic maintainer-clean-local mostlyclean \
+ mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \
+ tags tags-recursive uninstall uninstall-am \
+ uninstall-pkgconfigDATA
+
+
+maintainer-clean-local:
+ -rm -f aclocal.m4 config.h.in configure config/*
+ -find ${builddir} -name Makefile.in -exec rm -f '{}' ';'
+
+.PHONY: bootstrap
+bootstrap: maintainer-clean
+ ./bootstrap
+
+# Tell versions [3.59,3.63) of GNU make to not export all variables.
+# Otherwise a system limit (for SysV at least) may be exceeded.
+.NOEXPORT:
diff --git a/contrib/libyaml/README b/contrib/libyaml/README
new file mode 100644
index 0000000..d35ebcc
--- /dev/null
+++ b/contrib/libyaml/README
@@ -0,0 +1,27 @@
+LibYAML - A C library for parsing and emitting YAML.
+
+To build and install the library, run:
+$ ./configure
+$ make
+# make install
+
+If you checked the source code from the Subversion repository, run
+$ ./bootstrap
+$ ./configure
+$ make
+# make install
+
+For more information, check the LibYAML homepage:
+'http://pyyaml.org/wiki/LibYAML'.
+
+Post your questions and opinions to the YAML-Core mailing list:
+'http://lists.sourceforge.net/lists/listinfo/yaml-core'.
+
+Submit bug reports and feature requests to the LibYAML bug tracker:
+'http://pyyaml.org/newticket?component=libyaml'.
+
+LibYAML is written by Kirill Simonov <xi@resolvent.net>. It is released
+under the MIT license. See the file LICENSE for more details.
+
+This project is developed for Python Software Foundation as a part of
+Google Summer of Code under the mentorship of Clark Evans.
diff --git a/contrib/libyaml/aclocal.m4 b/contrib/libyaml/aclocal.m4
new file mode 100644
index 0000000..c5edfb1
--- /dev/null
+++ b/contrib/libyaml/aclocal.m4
@@ -0,0 +1,8917 @@
+# generated automatically by aclocal 1.11.1 -*- Autoconf -*-
+
+# Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004,
+# 2005, 2006, 2007, 2008, 2009 Free Software Foundation, Inc.
+# This file is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
+# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+# PARTICULAR PURPOSE.
+
+m4_ifndef([AC_AUTOCONF_VERSION],
+ [m4_copy([m4_PACKAGE_VERSION], [AC_AUTOCONF_VERSION])])dnl
+m4_if(m4_defn([AC_AUTOCONF_VERSION]), [2.67],,
+[m4_warning([this file was generated for autoconf 2.67.
+You have another version of autoconf. It may work, but is not guaranteed to.
+If you have problems, you may need to regenerate the build system entirely.
+To do so, use the procedure documented by the package, typically `autoreconf'.])])
+
+# libtool.m4 - Configure libtool for the host system. -*-Autoconf-*-
+#
+# Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2003, 2004, 2005,
+# 2006, 2007, 2008 Free Software Foundation, Inc.
+# Written by Gordon Matzigkeit, 1996
+#
+# This file is free software; the Free Software Foundation gives
+# unlimited permission to copy and/or distribute it, with or without
+# modifications, as long as this notice is preserved.
+
+m4_define([_LT_COPYING], [dnl
+# Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2003, 2004, 2005,
+# 2006, 2007, 2008 Free Software Foundation, Inc.
+# Written by Gordon Matzigkeit, 1996
+#
+# This file is part of GNU Libtool.
+#
+# GNU Libtool 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.
+#
+# As a special exception to the GNU General Public License,
+# if you distribute this file as part of a program or library that
+# is built using GNU Libtool, you may include this file under the
+# same distribution terms that you use for the rest of that program.
+#
+# GNU Libtool 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 GNU Libtool; see the file COPYING. If not, a copy
+# can be downloaded from http://www.gnu.org/licenses/gpl.html, or
+# obtained by writing to the Free Software Foundation, Inc.,
+# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+])
+
+# serial 56 LT_INIT
+
+
+# LT_PREREQ(VERSION)
+# ------------------
+# Complain and exit if this libtool version is less that VERSION.
+m4_defun([LT_PREREQ],
+[m4_if(m4_version_compare(m4_defn([LT_PACKAGE_VERSION]), [$1]), -1,
+ [m4_default([$3],
+ [m4_fatal([Libtool version $1 or higher is required],
+ 63)])],
+ [$2])])
+
+
+# _LT_CHECK_BUILDDIR
+# ------------------
+# Complain if the absolute build directory name contains unusual characters
+m4_defun([_LT_CHECK_BUILDDIR],
+[case `pwd` in
+ *\ * | *\ *)
+ AC_MSG_WARN([Libtool does not cope well with whitespace in `pwd`]) ;;
+esac
+])
+
+
+# LT_INIT([OPTIONS])
+# ------------------
+AC_DEFUN([LT_INIT],
+[AC_PREREQ([2.58])dnl We use AC_INCLUDES_DEFAULT
+AC_BEFORE([$0], [LT_LANG])dnl
+AC_BEFORE([$0], [LT_OUTPUT])dnl
+AC_BEFORE([$0], [LTDL_INIT])dnl
+m4_require([_LT_CHECK_BUILDDIR])dnl
+
+dnl Autoconf doesn't catch unexpanded LT_ macros by default:
+m4_pattern_forbid([^_?LT_[A-Z_]+$])dnl
+m4_pattern_allow([^(_LT_EOF|LT_DLGLOBAL|LT_DLLAZY_OR_NOW|LT_MULTI_MODULE)$])dnl
+dnl aclocal doesn't pull ltoptions.m4, ltsugar.m4, or ltversion.m4
+dnl unless we require an AC_DEFUNed macro:
+AC_REQUIRE([LTOPTIONS_VERSION])dnl
+AC_REQUIRE([LTSUGAR_VERSION])dnl
+AC_REQUIRE([LTVERSION_VERSION])dnl
+AC_REQUIRE([LTOBSOLETE_VERSION])dnl
+m4_require([_LT_PROG_LTMAIN])dnl
+
+dnl Parse OPTIONS
+_LT_SET_OPTIONS([$0], [$1])
+
+# This can be used to rebuild libtool when needed
+LIBTOOL_DEPS="$ltmain"
+
+# Always use our own libtool.
+LIBTOOL='$(SHELL) $(top_builddir)/libtool'
+AC_SUBST(LIBTOOL)dnl
+
+_LT_SETUP
+
+# Only expand once:
+m4_define([LT_INIT])
+])# LT_INIT
+
+# Old names:
+AU_ALIAS([AC_PROG_LIBTOOL], [LT_INIT])
+AU_ALIAS([AM_PROG_LIBTOOL], [LT_INIT])
+dnl aclocal-1.4 backwards compatibility:
+dnl AC_DEFUN([AC_PROG_LIBTOOL], [])
+dnl AC_DEFUN([AM_PROG_LIBTOOL], [])
+
+
+# _LT_CC_BASENAME(CC)
+# -------------------
+# Calculate cc_basename. Skip known compiler wrappers and cross-prefix.
+m4_defun([_LT_CC_BASENAME],
+[for cc_temp in $1""; do
+ case $cc_temp in
+ compile | *[[\\/]]compile | ccache | *[[\\/]]ccache ) ;;
+ distcc | *[[\\/]]distcc | purify | *[[\\/]]purify ) ;;
+ \-*) ;;
+ *) break;;
+ esac
+done
+cc_basename=`$ECHO "X$cc_temp" | $Xsed -e 's%.*/%%' -e "s%^$host_alias-%%"`
+])
+
+
+# _LT_FILEUTILS_DEFAULTS
+# ----------------------
+# It is okay to use these file commands and assume they have been set
+# sensibly after `m4_require([_LT_FILEUTILS_DEFAULTS])'.
+m4_defun([_LT_FILEUTILS_DEFAULTS],
+[: ${CP="cp -f"}
+: ${MV="mv -f"}
+: ${RM="rm -f"}
+])# _LT_FILEUTILS_DEFAULTS
+
+
+# _LT_SETUP
+# ---------
+m4_defun([_LT_SETUP],
+[AC_REQUIRE([AC_CANONICAL_HOST])dnl
+AC_REQUIRE([AC_CANONICAL_BUILD])dnl
+_LT_DECL([], [host_alias], [0], [The host system])dnl
+_LT_DECL([], [host], [0])dnl
+_LT_DECL([], [host_os], [0])dnl
+dnl
+_LT_DECL([], [build_alias], [0], [The build system])dnl
+_LT_DECL([], [build], [0])dnl
+_LT_DECL([], [build_os], [0])dnl
+dnl
+AC_REQUIRE([AC_PROG_CC])dnl
+AC_REQUIRE([LT_PATH_LD])dnl
+AC_REQUIRE([LT_PATH_NM])dnl
+dnl
+AC_REQUIRE([AC_PROG_LN_S])dnl
+test -z "$LN_S" && LN_S="ln -s"
+_LT_DECL([], [LN_S], [1], [Whether we need soft or hard links])dnl
+dnl
+AC_REQUIRE([LT_CMD_MAX_LEN])dnl
+_LT_DECL([objext], [ac_objext], [0], [Object file suffix (normally "o")])dnl
+_LT_DECL([], [exeext], [0], [Executable file suffix (normally "")])dnl
+dnl
+m4_require([_LT_FILEUTILS_DEFAULTS])dnl
+m4_require([_LT_CHECK_SHELL_FEATURES])dnl
+m4_require([_LT_CMD_RELOAD])dnl
+m4_require([_LT_CHECK_MAGIC_METHOD])dnl
+m4_require([_LT_CMD_OLD_ARCHIVE])dnl
+m4_require([_LT_CMD_GLOBAL_SYMBOLS])dnl
+
+_LT_CONFIG_LIBTOOL_INIT([
+# See if we are running on zsh, and set the options which allow our
+# commands through without removal of \ escapes INIT.
+if test -n "\${ZSH_VERSION+set}" ; then
+ setopt NO_GLOB_SUBST
+fi
+])
+if test -n "${ZSH_VERSION+set}" ; then
+ setopt NO_GLOB_SUBST
+fi
+
+_LT_CHECK_OBJDIR
+
+m4_require([_LT_TAG_COMPILER])dnl
+_LT_PROG_ECHO_BACKSLASH
+
+case $host_os in
+aix3*)
+ # AIX sometimes has problems with the GCC collect2 program. For some
+ # reason, if we set the COLLECT_NAMES environment variable, the problems
+ # vanish in a puff of smoke.
+ if test "X${COLLECT_NAMES+set}" != Xset; then
+ COLLECT_NAMES=
+ export COLLECT_NAMES
+ fi
+ ;;
+esac
+
+# Sed substitution that helps us do robust quoting. It backslashifies
+# metacharacters that are still active within double-quoted strings.
+sed_quote_subst='s/\([["`$\\]]\)/\\\1/g'
+
+# Same as above, but do not quote variable references.
+double_quote_subst='s/\([["`\\]]\)/\\\1/g'
+
+# Sed substitution to delay expansion of an escaped shell variable in a
+# double_quote_subst'ed string.
+delay_variable_subst='s/\\\\\\\\\\\$/\\\\\\$/g'
+
+# Sed substitution to delay expansion of an escaped single quote.
+delay_single_quote_subst='s/'\''/'\'\\\\\\\'\''/g'
+
+# Sed substitution to avoid accidental globbing in evaled expressions
+no_glob_subst='s/\*/\\\*/g'
+
+# Global variables:
+ofile=libtool
+can_build_shared=yes
+
+# All known linkers require a `.a' archive for static linking (except MSVC,
+# which needs '.lib').
+libext=a
+
+with_gnu_ld="$lt_cv_prog_gnu_ld"
+
+old_CC="$CC"
+old_CFLAGS="$CFLAGS"
+
+# Set sane defaults for various variables
+test -z "$CC" && CC=cc
+test -z "$LTCC" && LTCC=$CC
+test -z "$LTCFLAGS" && LTCFLAGS=$CFLAGS
+test -z "$LD" && LD=ld
+test -z "$ac_objext" && ac_objext=o
+
+_LT_CC_BASENAME([$compiler])
+
+# Only perform the check for file, if the check method requires it
+test -z "$MAGIC_CMD" && MAGIC_CMD=file
+case $deplibs_check_method in
+file_magic*)
+ if test "$file_magic_cmd" = '$MAGIC_CMD'; then
+ _LT_PATH_MAGIC
+ fi
+ ;;
+esac
+
+# Use C for the default configuration in the libtool script
+LT_SUPPORTED_TAG([CC])
+_LT_LANG_C_CONFIG
+_LT_LANG_DEFAULT_CONFIG
+_LT_CONFIG_COMMANDS
+])# _LT_SETUP
+
+
+# _LT_PROG_LTMAIN
+# ---------------
+# Note that this code is called both from `configure', and `config.status'
+# now that we use AC_CONFIG_COMMANDS to generate libtool. Notably,
+# `config.status' has no value for ac_aux_dir unless we are using Automake,
+# so we pass a copy along to make sure it has a sensible value anyway.
+m4_defun([_LT_PROG_LTMAIN],
+[m4_ifdef([AC_REQUIRE_AUX_FILE], [AC_REQUIRE_AUX_FILE([ltmain.sh])])dnl
+_LT_CONFIG_LIBTOOL_INIT([ac_aux_dir='$ac_aux_dir'])
+ltmain="$ac_aux_dir/ltmain.sh"
+])# _LT_PROG_LTMAIN
+
+
+
+# So that we can recreate a full libtool script including additional
+# tags, we accumulate the chunks of code to send to AC_CONFIG_COMMANDS
+# in macros and then make a single call at the end using the `libtool'
+# label.
+
+
+# _LT_CONFIG_LIBTOOL_INIT([INIT-COMMANDS])
+# ----------------------------------------
+# Register INIT-COMMANDS to be passed to AC_CONFIG_COMMANDS later.
+m4_define([_LT_CONFIG_LIBTOOL_INIT],
+[m4_ifval([$1],
+ [m4_append([_LT_OUTPUT_LIBTOOL_INIT],
+ [$1
+])])])
+
+# Initialize.
+m4_define([_LT_OUTPUT_LIBTOOL_INIT])
+
+
+# _LT_CONFIG_LIBTOOL([COMMANDS])
+# ------------------------------
+# Register COMMANDS to be passed to AC_CONFIG_COMMANDS later.
+m4_define([_LT_CONFIG_LIBTOOL],
+[m4_ifval([$1],
+ [m4_append([_LT_OUTPUT_LIBTOOL_COMMANDS],
+ [$1
+])])])
+
+# Initialize.
+m4_define([_LT_OUTPUT_LIBTOOL_COMMANDS])
+
+
+# _LT_CONFIG_SAVE_COMMANDS([COMMANDS], [INIT_COMMANDS])
+# -----------------------------------------------------
+m4_defun([_LT_CONFIG_SAVE_COMMANDS],
+[_LT_CONFIG_LIBTOOL([$1])
+_LT_CONFIG_LIBTOOL_INIT([$2])
+])
+
+
+# _LT_FORMAT_COMMENT([COMMENT])
+# -----------------------------
+# Add leading comment marks to the start of each line, and a trailing
+# full-stop to the whole comment if one is not present already.
+m4_define([_LT_FORMAT_COMMENT],
+[m4_ifval([$1], [
+m4_bpatsubst([m4_bpatsubst([$1], [^ *], [# ])],
+ [['`$\]], [\\\&])]m4_bmatch([$1], [[!?.]$], [], [.])
+)])
+
+
+
+
+
+# _LT_DECL([CONFIGNAME], VARNAME, VALUE, [DESCRIPTION], [IS-TAGGED?])
+# -------------------------------------------------------------------
+# CONFIGNAME is the name given to the value in the libtool script.
+# VARNAME is the (base) name used in the configure script.
+# VALUE may be 0, 1 or 2 for a computed quote escaped value based on
+# VARNAME. Any other value will be used directly.
+m4_define([_LT_DECL],
+[lt_if_append_uniq([lt_decl_varnames], [$2], [, ],
+ [lt_dict_add_subkey([lt_decl_dict], [$2], [libtool_name],
+ [m4_ifval([$1], [$1], [$2])])
+ lt_dict_add_subkey([lt_decl_dict], [$2], [value], [$3])
+ m4_ifval([$4],
+ [lt_dict_add_subkey([lt_decl_dict], [$2], [description], [$4])])
+ lt_dict_add_subkey([lt_decl_dict], [$2],
+ [tagged?], [m4_ifval([$5], [yes], [no])])])
+])
+
+
+# _LT_TAGDECL([CONFIGNAME], VARNAME, VALUE, [DESCRIPTION])
+# --------------------------------------------------------
+m4_define([_LT_TAGDECL], [_LT_DECL([$1], [$2], [$3], [$4], [yes])])
+
+
+# lt_decl_tag_varnames([SEPARATOR], [VARNAME1...])
+# ------------------------------------------------
+m4_define([lt_decl_tag_varnames],
+[_lt_decl_filter([tagged?], [yes], $@)])
+
+
+# _lt_decl_filter(SUBKEY, VALUE, [SEPARATOR], [VARNAME1..])
+# ---------------------------------------------------------
+m4_define([_lt_decl_filter],
+[m4_case([$#],
+ [0], [m4_fatal([$0: too few arguments: $#])],
+ [1], [m4_fatal([$0: too few arguments: $#: $1])],
+ [2], [lt_dict_filter([lt_decl_dict], [$1], [$2], [], lt_decl_varnames)],
+ [3], [lt_dict_filter([lt_decl_dict], [$1], [$2], [$3], lt_decl_varnames)],
+ [lt_dict_filter([lt_decl_dict], $@)])[]dnl
+])
+
+
+# lt_decl_quote_varnames([SEPARATOR], [VARNAME1...])
+# --------------------------------------------------
+m4_define([lt_decl_quote_varnames],
+[_lt_decl_filter([value], [1], $@)])
+
+
+# lt_decl_dquote_varnames([SEPARATOR], [VARNAME1...])
+# ---------------------------------------------------
+m4_define([lt_decl_dquote_varnames],
+[_lt_decl_filter([value], [2], $@)])
+
+
+# lt_decl_varnames_tagged([SEPARATOR], [VARNAME1...])
+# ---------------------------------------------------
+m4_define([lt_decl_varnames_tagged],
+[m4_assert([$# <= 2])dnl
+_$0(m4_quote(m4_default([$1], [[, ]])),
+ m4_ifval([$2], [[$2]], [m4_dquote(lt_decl_tag_varnames)]),
+ m4_split(m4_normalize(m4_quote(_LT_TAGS)), [ ]))])
+m4_define([_lt_decl_varnames_tagged],
+[m4_ifval([$3], [lt_combine([$1], [$2], [_], $3)])])
+
+
+# lt_decl_all_varnames([SEPARATOR], [VARNAME1...])
+# ------------------------------------------------
+m4_define([lt_decl_all_varnames],
+[_$0(m4_quote(m4_default([$1], [[, ]])),
+ m4_if([$2], [],
+ m4_quote(lt_decl_varnames),
+ m4_quote(m4_shift($@))))[]dnl
+])
+m4_define([_lt_decl_all_varnames],
+[lt_join($@, lt_decl_varnames_tagged([$1],
+ lt_decl_tag_varnames([[, ]], m4_shift($@))))dnl
+])
+
+
+# _LT_CONFIG_STATUS_DECLARE([VARNAME])
+# ------------------------------------
+# Quote a variable value, and forward it to `config.status' so that its
+# declaration there will have the same value as in `configure'. VARNAME
+# must have a single quote delimited value for this to work.
+m4_define([_LT_CONFIG_STATUS_DECLARE],
+[$1='`$ECHO "X$][$1" | $Xsed -e "$delay_single_quote_subst"`'])
+
+
+# _LT_CONFIG_STATUS_DECLARATIONS
+# ------------------------------
+# We delimit libtool config variables with single quotes, so when
+# we write them to config.status, we have to be sure to quote all
+# embedded single quotes properly. In configure, this macro expands
+# each variable declared with _LT_DECL (and _LT_TAGDECL) into:
+#
+# <var>='`$ECHO "X$<var>" | $Xsed -e "$delay_single_quote_subst"`'
+m4_defun([_LT_CONFIG_STATUS_DECLARATIONS],
+[m4_foreach([_lt_var], m4_quote(lt_decl_all_varnames),
+ [m4_n([_LT_CONFIG_STATUS_DECLARE(_lt_var)])])])
+
+
+# _LT_LIBTOOL_TAGS
+# ----------------
+# Output comment and list of tags supported by the script
+m4_defun([_LT_LIBTOOL_TAGS],
+[_LT_FORMAT_COMMENT([The names of the tagged configurations supported by this script])dnl
+available_tags="_LT_TAGS"dnl
+])
+
+
+# _LT_LIBTOOL_DECLARE(VARNAME, [TAG])
+# -----------------------------------
+# Extract the dictionary values for VARNAME (optionally with TAG) and
+# expand to a commented shell variable setting:
+#
+# # Some comment about what VAR is for.
+# visible_name=$lt_internal_name
+m4_define([_LT_LIBTOOL_DECLARE],
+[_LT_FORMAT_COMMENT(m4_quote(lt_dict_fetch([lt_decl_dict], [$1],
+ [description])))[]dnl
+m4_pushdef([_libtool_name],
+ m4_quote(lt_dict_fetch([lt_decl_dict], [$1], [libtool_name])))[]dnl
+m4_case(m4_quote(lt_dict_fetch([lt_decl_dict], [$1], [value])),
+ [0], [_libtool_name=[$]$1],
+ [1], [_libtool_name=$lt_[]$1],
+ [2], [_libtool_name=$lt_[]$1],
+ [_libtool_name=lt_dict_fetch([lt_decl_dict], [$1], [value])])[]dnl
+m4_ifval([$2], [_$2])[]m4_popdef([_libtool_name])[]dnl
+])
+
+
+# _LT_LIBTOOL_CONFIG_VARS
+# -----------------------
+# Produce commented declarations of non-tagged libtool config variables
+# suitable for insertion in the LIBTOOL CONFIG section of the `libtool'
+# script. Tagged libtool config variables (even for the LIBTOOL CONFIG
+# section) are produced by _LT_LIBTOOL_TAG_VARS.
+m4_defun([_LT_LIBTOOL_CONFIG_VARS],
+[m4_foreach([_lt_var],
+ m4_quote(_lt_decl_filter([tagged?], [no], [], lt_decl_varnames)),
+ [m4_n([_LT_LIBTOOL_DECLARE(_lt_var)])])])
+
+
+# _LT_LIBTOOL_TAG_VARS(TAG)
+# -------------------------
+m4_define([_LT_LIBTOOL_TAG_VARS],
+[m4_foreach([_lt_var], m4_quote(lt_decl_tag_varnames),
+ [m4_n([_LT_LIBTOOL_DECLARE(_lt_var, [$1])])])])
+
+
+# _LT_TAGVAR(VARNAME, [TAGNAME])
+# ------------------------------
+m4_define([_LT_TAGVAR], [m4_ifval([$2], [$1_$2], [$1])])
+
+
+# _LT_CONFIG_COMMANDS
+# -------------------
+# Send accumulated output to $CONFIG_STATUS. Thanks to the lists of
+# variables for single and double quote escaping we saved from calls
+# to _LT_DECL, we can put quote escaped variables declarations
+# into `config.status', and then the shell code to quote escape them in
+# for loops in `config.status'. Finally, any additional code accumulated
+# from calls to _LT_CONFIG_LIBTOOL_INIT is expanded.
+m4_defun([_LT_CONFIG_COMMANDS],
+[AC_PROVIDE_IFELSE([LT_OUTPUT],
+ dnl If the libtool generation code has been placed in $CONFIG_LT,
+ dnl instead of duplicating it all over again into config.status,
+ dnl then we will have config.status run $CONFIG_LT later, so it
+ dnl needs to know what name is stored there:
+ [AC_CONFIG_COMMANDS([libtool],
+ [$SHELL $CONFIG_LT || AS_EXIT(1)], [CONFIG_LT='$CONFIG_LT'])],
+ dnl If the libtool generation code is destined for config.status,
+ dnl expand the accumulated commands and init code now:
+ [AC_CONFIG_COMMANDS([libtool],
+ [_LT_OUTPUT_LIBTOOL_COMMANDS], [_LT_OUTPUT_LIBTOOL_COMMANDS_INIT])])
+])#_LT_CONFIG_COMMANDS
+
+
+# Initialize.
+m4_define([_LT_OUTPUT_LIBTOOL_COMMANDS_INIT],
+[
+
+# The HP-UX ksh and POSIX shell print the target directory to stdout
+# if CDPATH is set.
+(unset CDPATH) >/dev/null 2>&1 && unset CDPATH
+
+sed_quote_subst='$sed_quote_subst'
+double_quote_subst='$double_quote_subst'
+delay_variable_subst='$delay_variable_subst'
+_LT_CONFIG_STATUS_DECLARATIONS
+LTCC='$LTCC'
+LTCFLAGS='$LTCFLAGS'
+compiler='$compiler_DEFAULT'
+
+# Quote evaled strings.
+for var in lt_decl_all_varnames([[ \
+]], lt_decl_quote_varnames); do
+ case \`eval \\\\\$ECHO "X\\\\\$\$var"\` in
+ *[[\\\\\\\`\\"\\\$]]*)
+ eval "lt_\$var=\\\\\\"\\\`\\\$ECHO \\"X\\\$\$var\\" | \\\$Xsed -e \\"\\\$sed_quote_subst\\"\\\`\\\\\\""
+ ;;
+ *)
+ eval "lt_\$var=\\\\\\"\\\$\$var\\\\\\""
+ ;;
+ esac
+done
+
+# Double-quote double-evaled strings.
+for var in lt_decl_all_varnames([[ \
+]], lt_decl_dquote_varnames); do
+ case \`eval \\\\\$ECHO "X\\\\\$\$var"\` in
+ *[[\\\\\\\`\\"\\\$]]*)
+ eval "lt_\$var=\\\\\\"\\\`\\\$ECHO \\"X\\\$\$var\\" | \\\$Xsed -e \\"\\\$double_quote_subst\\" -e \\"\\\$sed_quote_subst\\" -e \\"\\\$delay_variable_subst\\"\\\`\\\\\\""
+ ;;
+ *)
+ eval "lt_\$var=\\\\\\"\\\$\$var\\\\\\""
+ ;;
+ esac
+done
+
+# Fix-up fallback echo if it was mangled by the above quoting rules.
+case \$lt_ECHO in
+*'\\\[$]0 --fallback-echo"')dnl "
+ lt_ECHO=\`\$ECHO "X\$lt_ECHO" | \$Xsed -e 's/\\\\\\\\\\\\\\\[$]0 --fallback-echo"\[$]/\[$]0 --fallback-echo"/'\`
+ ;;
+esac
+
+_LT_OUTPUT_LIBTOOL_INIT
+])
+
+
+# LT_OUTPUT
+# ---------
+# This macro allows early generation of the libtool script (before
+# AC_OUTPUT is called), incase it is used in configure for compilation
+# tests.
+AC_DEFUN([LT_OUTPUT],
+[: ${CONFIG_LT=./config.lt}
+AC_MSG_NOTICE([creating $CONFIG_LT])
+cat >"$CONFIG_LT" <<_LTEOF
+#! $SHELL
+# Generated by $as_me.
+# Run this file to recreate a libtool stub with the current configuration.
+
+lt_cl_silent=false
+SHELL=\${CONFIG_SHELL-$SHELL}
+_LTEOF
+
+cat >>"$CONFIG_LT" <<\_LTEOF
+AS_SHELL_SANITIZE
+_AS_PREPARE
+
+exec AS_MESSAGE_FD>&1
+exec AS_MESSAGE_LOG_FD>>config.log
+{
+ echo
+ AS_BOX([Running $as_me.])
+} >&AS_MESSAGE_LOG_FD
+
+lt_cl_help="\
+\`$as_me' creates a local libtool stub from the current configuration,
+for use in further configure time tests before the real libtool is
+generated.
+
+Usage: $[0] [[OPTIONS]]
+
+ -h, --help print this help, then exit
+ -V, --version print version number, then exit
+ -q, --quiet do not print progress messages
+ -d, --debug don't remove temporary files
+
+Report bugs to <bug-libtool@gnu.org>."
+
+lt_cl_version="\
+m4_ifset([AC_PACKAGE_NAME], [AC_PACKAGE_NAME ])config.lt[]dnl
+m4_ifset([AC_PACKAGE_VERSION], [ AC_PACKAGE_VERSION])
+configured by $[0], generated by m4_PACKAGE_STRING.
+
+Copyright (C) 2008 Free Software Foundation, Inc.
+This config.lt script is free software; the Free Software Foundation
+gives unlimited permision to copy, distribute and modify it."
+
+while test $[#] != 0
+do
+ case $[1] in
+ --version | --v* | -V )
+ echo "$lt_cl_version"; exit 0 ;;
+ --help | --h* | -h )
+ echo "$lt_cl_help"; exit 0 ;;
+ --debug | --d* | -d )
+ debug=: ;;
+ --quiet | --q* | --silent | --s* | -q )
+ lt_cl_silent=: ;;
+
+ -*) AC_MSG_ERROR([unrecognized option: $[1]
+Try \`$[0] --help' for more information.]) ;;
+
+ *) AC_MSG_ERROR([unrecognized argument: $[1]
+Try \`$[0] --help' for more information.]) ;;
+ esac
+ shift
+done
+
+if $lt_cl_silent; then
+ exec AS_MESSAGE_FD>/dev/null
+fi
+_LTEOF
+
+cat >>"$CONFIG_LT" <<_LTEOF
+_LT_OUTPUT_LIBTOOL_COMMANDS_INIT
+_LTEOF
+
+cat >>"$CONFIG_LT" <<\_LTEOF
+AC_MSG_NOTICE([creating $ofile])
+_LT_OUTPUT_LIBTOOL_COMMANDS
+AS_EXIT(0)
+_LTEOF
+chmod +x "$CONFIG_LT"
+
+# configure is writing to config.log, but config.lt does its own redirection,
+# appending to config.log, which fails on DOS, as config.log is still kept
+# open by configure. Here we exec the FD to /dev/null, effectively closing
+# config.log, so it can be properly (re)opened and appended to by config.lt.
+if test "$no_create" != yes; then
+ lt_cl_success=:
+ test "$silent" = yes &&
+ lt_config_lt_args="$lt_config_lt_args --quiet"
+ exec AS_MESSAGE_LOG_FD>/dev/null
+ $SHELL "$CONFIG_LT" $lt_config_lt_args || lt_cl_success=false
+ exec AS_MESSAGE_LOG_FD>>config.log
+ $lt_cl_success || AS_EXIT(1)
+fi
+])# LT_OUTPUT
+
+
+# _LT_CONFIG(TAG)
+# ---------------
+# If TAG is the built-in tag, create an initial libtool script with a
+# default configuration from the untagged config vars. Otherwise add code
+# to config.status for appending the configuration named by TAG from the
+# matching tagged config vars.
+m4_defun([_LT_CONFIG],
+[m4_require([_LT_FILEUTILS_DEFAULTS])dnl
+_LT_CONFIG_SAVE_COMMANDS([
+ m4_define([_LT_TAG], m4_if([$1], [], [C], [$1]))dnl
+ m4_if(_LT_TAG, [C], [
+ # See if we are running on zsh, and set the options which allow our
+ # commands through without removal of \ escapes.
+ if test -n "${ZSH_VERSION+set}" ; then
+ setopt NO_GLOB_SUBST
+ fi
+
+ cfgfile="${ofile}T"
+ trap "$RM \"$cfgfile\"; exit 1" 1 2 15
+ $RM "$cfgfile"
+
+ cat <<_LT_EOF >> "$cfgfile"
+#! $SHELL
+
+# `$ECHO "$ofile" | sed 's%^.*/%%'` - Provide generalized library-building support services.
+# Generated automatically by $as_me ($PACKAGE$TIMESTAMP) $VERSION
+# Libtool was configured on host `(hostname || uname -n) 2>/dev/null | sed 1q`:
+# NOTE: Changes made to this file will be lost: look at ltmain.sh.
+#
+_LT_COPYING
+_LT_LIBTOOL_TAGS
+
+# ### BEGIN LIBTOOL CONFIG
+_LT_LIBTOOL_CONFIG_VARS
+_LT_LIBTOOL_TAG_VARS
+# ### END LIBTOOL CONFIG
+
+_LT_EOF
+
+ case $host_os in
+ aix3*)
+ cat <<\_LT_EOF >> "$cfgfile"
+# AIX sometimes has problems with the GCC collect2 program. For some
+# reason, if we set the COLLECT_NAMES environment variable, the problems
+# vanish in a puff of smoke.
+if test "X${COLLECT_NAMES+set}" != Xset; then
+ COLLECT_NAMES=
+ export COLLECT_NAMES
+fi
+_LT_EOF
+ ;;
+ esac
+
+ _LT_PROG_LTMAIN
+
+ # We use sed instead of cat because bash on DJGPP gets confused if
+ # if finds mixed CR/LF and LF-only lines. Since sed operates in
+ # text mode, it properly converts lines to CR/LF. This bash problem
+ # is reportedly fixed, but why not run on old versions too?
+ sed '/^# Generated shell functions inserted here/q' "$ltmain" >> "$cfgfile" \
+ || (rm -f "$cfgfile"; exit 1)
+
+ _LT_PROG_XSI_SHELLFNS
+
+ sed -n '/^# Generated shell functions inserted here/,$p' "$ltmain" >> "$cfgfile" \
+ || (rm -f "$cfgfile"; exit 1)
+
+ mv -f "$cfgfile" "$ofile" ||
+ (rm -f "$ofile" && cp "$cfgfile" "$ofile" && rm -f "$cfgfile")
+ chmod +x "$ofile"
+],
+[cat <<_LT_EOF >> "$ofile"
+
+dnl Unfortunately we have to use $1 here, since _LT_TAG is not expanded
+dnl in a comment (ie after a #).
+# ### BEGIN LIBTOOL TAG CONFIG: $1
+_LT_LIBTOOL_TAG_VARS(_LT_TAG)
+# ### END LIBTOOL TAG CONFIG: $1
+_LT_EOF
+])dnl /m4_if
+],
+[m4_if([$1], [], [
+ PACKAGE='$PACKAGE'
+ VERSION='$VERSION'
+ TIMESTAMP='$TIMESTAMP'
+ RM='$RM'
+ ofile='$ofile'], [])
+])dnl /_LT_CONFIG_SAVE_COMMANDS
+])# _LT_CONFIG
+
+
+# LT_SUPPORTED_TAG(TAG)
+# ---------------------
+# Trace this macro to discover what tags are supported by the libtool
+# --tag option, using:
+# autoconf --trace 'LT_SUPPORTED_TAG:$1'
+AC_DEFUN([LT_SUPPORTED_TAG], [])
+
+
+# C support is built-in for now
+m4_define([_LT_LANG_C_enabled], [])
+m4_define([_LT_TAGS], [])
+
+
+# LT_LANG(LANG)
+# -------------
+# Enable libtool support for the given language if not already enabled.
+AC_DEFUN([LT_LANG],
+[AC_BEFORE([$0], [LT_OUTPUT])dnl
+m4_case([$1],
+ [C], [_LT_LANG(C)],
+ [C++], [_LT_LANG(CXX)],
+ [Java], [_LT_LANG(GCJ)],
+ [Fortran 77], [_LT_LANG(F77)],
+ [Fortran], [_LT_LANG(FC)],
+ [Windows Resource], [_LT_LANG(RC)],
+ [m4_ifdef([_LT_LANG_]$1[_CONFIG],
+ [_LT_LANG($1)],
+ [m4_fatal([$0: unsupported language: "$1"])])])dnl
+])# LT_LANG
+
+
+# _LT_LANG(LANGNAME)
+# ------------------
+m4_defun([_LT_LANG],
+[m4_ifdef([_LT_LANG_]$1[_enabled], [],
+ [LT_SUPPORTED_TAG([$1])dnl
+ m4_append([_LT_TAGS], [$1 ])dnl
+ m4_define([_LT_LANG_]$1[_enabled], [])dnl
+ _LT_LANG_$1_CONFIG($1)])dnl
+])# _LT_LANG
+
+
+# _LT_LANG_DEFAULT_CONFIG
+# -----------------------
+m4_defun([_LT_LANG_DEFAULT_CONFIG],
+[AC_PROVIDE_IFELSE([AC_PROG_CXX],
+ [LT_LANG(CXX)],
+ [m4_define([AC_PROG_CXX], defn([AC_PROG_CXX])[LT_LANG(CXX)])])
+
+AC_PROVIDE_IFELSE([AC_PROG_F77],
+ [LT_LANG(F77)],
+ [m4_define([AC_PROG_F77], defn([AC_PROG_F77])[LT_LANG(F77)])])
+
+AC_PROVIDE_IFELSE([AC_PROG_FC],
+ [LT_LANG(FC)],
+ [m4_define([AC_PROG_FC], defn([AC_PROG_FC])[LT_LANG(FC)])])
+
+dnl The call to [A][M_PROG_GCJ] is quoted like that to stop aclocal
+dnl pulling things in needlessly.
+AC_PROVIDE_IFELSE([AC_PROG_GCJ],
+ [LT_LANG(GCJ)],
+ [AC_PROVIDE_IFELSE([A][M_PROG_GCJ],
+ [LT_LANG(GCJ)],
+ [AC_PROVIDE_IFELSE([LT_PROG_GCJ],
+ [LT_LANG(GCJ)],
+ [m4_ifdef([AC_PROG_GCJ],
+ [m4_define([AC_PROG_GCJ], defn([AC_PROG_GCJ])[LT_LANG(GCJ)])])
+ m4_ifdef([A][M_PROG_GCJ],
+ [m4_define([A][M_PROG_GCJ], defn([A][M_PROG_GCJ])[LT_LANG(GCJ)])])
+ m4_ifdef([LT_PROG_GCJ],
+ [m4_define([LT_PROG_GCJ], defn([LT_PROG_GCJ])[LT_LANG(GCJ)])])])])])
+
+AC_PROVIDE_IFELSE([LT_PROG_RC],
+ [LT_LANG(RC)],
+ [m4_define([LT_PROG_RC], defn([LT_PROG_RC])[LT_LANG(RC)])])
+])# _LT_LANG_DEFAULT_CONFIG
+
+# Obsolete macros:
+AU_DEFUN([AC_LIBTOOL_CXX], [LT_LANG(C++)])
+AU_DEFUN([AC_LIBTOOL_F77], [LT_LANG(Fortran 77)])
+AU_DEFUN([AC_LIBTOOL_FC], [LT_LANG(Fortran)])
+AU_DEFUN([AC_LIBTOOL_GCJ], [LT_LANG(Java)])
+dnl aclocal-1.4 backwards compatibility:
+dnl AC_DEFUN([AC_LIBTOOL_CXX], [])
+dnl AC_DEFUN([AC_LIBTOOL_F77], [])
+dnl AC_DEFUN([AC_LIBTOOL_FC], [])
+dnl AC_DEFUN([AC_LIBTOOL_GCJ], [])
+
+
+# _LT_TAG_COMPILER
+# ----------------
+m4_defun([_LT_TAG_COMPILER],
+[AC_REQUIRE([AC_PROG_CC])dnl
+
+_LT_DECL([LTCC], [CC], [1], [A C compiler])dnl
+_LT_DECL([LTCFLAGS], [CFLAGS], [1], [LTCC compiler flags])dnl
+_LT_TAGDECL([CC], [compiler], [1], [A language specific compiler])dnl
+_LT_TAGDECL([with_gcc], [GCC], [0], [Is the compiler the GNU compiler?])dnl
+
+# If no C compiler was specified, use CC.
+LTCC=${LTCC-"$CC"}
+
+# If no C compiler flags were specified, use CFLAGS.
+LTCFLAGS=${LTCFLAGS-"$CFLAGS"}
+
+# Allow CC to be a program name with arguments.
+compiler=$CC
+])# _LT_TAG_COMPILER
+
+
+# _LT_COMPILER_BOILERPLATE
+# ------------------------
+# Check for compiler boilerplate output or warnings with
+# the simple compiler test code.
+m4_defun([_LT_COMPILER_BOILERPLATE],
+[m4_require([_LT_DECL_SED])dnl
+ac_outfile=conftest.$ac_objext
+echo "$lt_simple_compile_test_code" >conftest.$ac_ext
+eval "$ac_compile" 2>&1 >/dev/null | $SED '/^$/d; /^ *+/d' >conftest.err
+_lt_compiler_boilerplate=`cat conftest.err`
+$RM conftest*
+])# _LT_COMPILER_BOILERPLATE
+
+
+# _LT_LINKER_BOILERPLATE
+# ----------------------
+# Check for linker boilerplate output or warnings with
+# the simple link test code.
+m4_defun([_LT_LINKER_BOILERPLATE],
+[m4_require([_LT_DECL_SED])dnl
+ac_outfile=conftest.$ac_objext
+echo "$lt_simple_link_test_code" >conftest.$ac_ext
+eval "$ac_link" 2>&1 >/dev/null | $SED '/^$/d; /^ *+/d' >conftest.err
+_lt_linker_boilerplate=`cat conftest.err`
+$RM -r conftest*
+])# _LT_LINKER_BOILERPLATE
+
+# _LT_REQUIRED_DARWIN_CHECKS
+# -------------------------
+m4_defun_once([_LT_REQUIRED_DARWIN_CHECKS],[
+ case $host_os in
+ rhapsody* | darwin*)
+ AC_CHECK_TOOL([DSYMUTIL], [dsymutil], [:])
+ AC_CHECK_TOOL([NMEDIT], [nmedit], [:])
+ AC_CHECK_TOOL([LIPO], [lipo], [:])
+ AC_CHECK_TOOL([OTOOL], [otool], [:])
+ AC_CHECK_TOOL([OTOOL64], [otool64], [:])
+ _LT_DECL([], [DSYMUTIL], [1],
+ [Tool to manipulate archived DWARF debug symbol files on Mac OS X])
+ _LT_DECL([], [NMEDIT], [1],
+ [Tool to change global to local symbols on Mac OS X])
+ _LT_DECL([], [LIPO], [1],
+ [Tool to manipulate fat objects and archives on Mac OS X])
+ _LT_DECL([], [OTOOL], [1],
+ [ldd/readelf like tool for Mach-O binaries on Mac OS X])
+ _LT_DECL([], [OTOOL64], [1],
+ [ldd/readelf like tool for 64 bit Mach-O binaries on Mac OS X 10.4])
+
+ AC_CACHE_CHECK([for -single_module linker flag],[lt_cv_apple_cc_single_mod],
+ [lt_cv_apple_cc_single_mod=no
+ if test -z "${LT_MULTI_MODULE}"; then
+ # By default we will add the -single_module flag. You can override
+ # by either setting the environment variable LT_MULTI_MODULE
+ # non-empty at configure time, or by adding -multi_module to the
+ # link flags.
+ rm -rf libconftest.dylib*
+ echo "int foo(void){return 1;}" > conftest.c
+ echo "$LTCC $LTCFLAGS $LDFLAGS -o libconftest.dylib \
+-dynamiclib -Wl,-single_module conftest.c" >&AS_MESSAGE_LOG_FD
+ $LTCC $LTCFLAGS $LDFLAGS -o libconftest.dylib \
+ -dynamiclib -Wl,-single_module conftest.c 2>conftest.err
+ _lt_result=$?
+ if test -f libconftest.dylib && test ! -s conftest.err && test $_lt_result = 0; then
+ lt_cv_apple_cc_single_mod=yes
+ else
+ cat conftest.err >&AS_MESSAGE_LOG_FD
+ fi
+ rm -rf libconftest.dylib*
+ rm -f conftest.*
+ fi])
+ AC_CACHE_CHECK([for -exported_symbols_list linker flag],
+ [lt_cv_ld_exported_symbols_list],
+ [lt_cv_ld_exported_symbols_list=no
+ save_LDFLAGS=$LDFLAGS
+ echo "_main" > conftest.sym
+ LDFLAGS="$LDFLAGS -Wl,-exported_symbols_list,conftest.sym"
+ AC_LINK_IFELSE([AC_LANG_PROGRAM([],[])],
+ [lt_cv_ld_exported_symbols_list=yes],
+ [lt_cv_ld_exported_symbols_list=no])
+ LDFLAGS="$save_LDFLAGS"
+ ])
+ case $host_os in
+ rhapsody* | darwin1.[[012]])
+ _lt_dar_allow_undefined='${wl}-undefined ${wl}suppress' ;;
+ darwin1.*)
+ _lt_dar_allow_undefined='${wl}-flat_namespace ${wl}-undefined ${wl}suppress' ;;
+ darwin*) # darwin 5.x on
+ # if running on 10.5 or later, the deployment target defaults
+ # to the OS version, if on x86, and 10.4, the deployment
+ # target defaults to 10.4. Don't you love it?
+ case ${MACOSX_DEPLOYMENT_TARGET-10.0},$host in
+ 10.0,*86*-darwin8*|10.0,*-darwin[[91]]*)
+ _lt_dar_allow_undefined='${wl}-undefined ${wl}dynamic_lookup' ;;
+ 10.[[012]]*)
+ _lt_dar_allow_undefined='${wl}-flat_namespace ${wl}-undefined ${wl}suppress' ;;
+ 10.*)
+ _lt_dar_allow_undefined='${wl}-undefined ${wl}dynamic_lookup' ;;
+ esac
+ ;;
+ esac
+ if test "$lt_cv_apple_cc_single_mod" = "yes"; then
+ _lt_dar_single_mod='$single_module'
+ fi
+ if test "$lt_cv_ld_exported_symbols_list" = "yes"; then
+ _lt_dar_export_syms=' ${wl}-exported_symbols_list,$output_objdir/${libname}-symbols.expsym'
+ else
+ _lt_dar_export_syms='~$NMEDIT -s $output_objdir/${libname}-symbols.expsym ${lib}'
+ fi
+ if test "$DSYMUTIL" != ":"; then
+ _lt_dsymutil='~$DSYMUTIL $lib || :'
+ else
+ _lt_dsymutil=
+ fi
+ ;;
+ esac
+])
+
+
+# _LT_DARWIN_LINKER_FEATURES
+# --------------------------
+# Checks for linker and compiler features on darwin
+m4_defun([_LT_DARWIN_LINKER_FEATURES],
+[
+ m4_require([_LT_REQUIRED_DARWIN_CHECKS])
+ _LT_TAGVAR(archive_cmds_need_lc, $1)=no
+ _LT_TAGVAR(hardcode_direct, $1)=no
+ _LT_TAGVAR(hardcode_automatic, $1)=yes
+ _LT_TAGVAR(hardcode_shlibpath_var, $1)=unsupported
+ _LT_TAGVAR(whole_archive_flag_spec, $1)=''
+ _LT_TAGVAR(link_all_deplibs, $1)=yes
+ _LT_TAGVAR(allow_undefined_flag, $1)="$_lt_dar_allow_undefined"
+ case $cc_basename in
+ ifort*) _lt_dar_can_shared=yes ;;
+ *) _lt_dar_can_shared=$GCC ;;
+ esac
+ if test "$_lt_dar_can_shared" = "yes"; then
+ output_verbose_link_cmd=echo
+ _LT_TAGVAR(archive_cmds, $1)="\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring $_lt_dar_single_mod${_lt_dsymutil}"
+ _LT_TAGVAR(module_cmds, $1)="\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags${_lt_dsymutil}"
+ _LT_TAGVAR(archive_expsym_cmds, $1)="sed 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring ${_lt_dar_single_mod}${_lt_dar_export_syms}${_lt_dsymutil}"
+ _LT_TAGVAR(module_expsym_cmds, $1)="sed -e 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags${_lt_dar_export_syms}${_lt_dsymutil}"
+ m4_if([$1], [CXX],
+[ if test "$lt_cv_apple_cc_single_mod" != "yes"; then
+ _LT_TAGVAR(archive_cmds, $1)="\$CC -r -keep_private_externs -nostdlib -o \${lib}-master.o \$libobjs~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \${lib}-master.o \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring${_lt_dsymutil}"
+ _LT_TAGVAR(archive_expsym_cmds, $1)="sed 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC -r -keep_private_externs -nostdlib -o \${lib}-master.o \$libobjs~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \${lib}-master.o \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring${_lt_dar_export_syms}${_lt_dsymutil}"
+ fi
+],[])
+ else
+ _LT_TAGVAR(ld_shlibs, $1)=no
+ fi
+])
+
+# _LT_SYS_MODULE_PATH_AIX
+# -----------------------
+# Links a minimal program and checks the executable
+# for the system default hardcoded library path. In most cases,
+# this is /usr/lib:/lib, but when the MPI compilers are used
+# the location of the communication and MPI libs are included too.
+# If we don't find anything, use the default library path according
+# to the aix ld manual.
+m4_defun([_LT_SYS_MODULE_PATH_AIX],
+[m4_require([_LT_DECL_SED])dnl
+AC_LINK_IFELSE(AC_LANG_PROGRAM,[
+lt_aix_libpath_sed='
+ /Import File Strings/,/^$/ {
+ /^0/ {
+ s/^0 *\(.*\)$/\1/
+ p
+ }
+ }'
+aix_libpath=`dump -H conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"`
+# Check for a 64-bit object if we didn't find anything.
+if test -z "$aix_libpath"; then
+ aix_libpath=`dump -HX64 conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"`
+fi],[])
+if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi
+])# _LT_SYS_MODULE_PATH_AIX
+
+
+# _LT_SHELL_INIT(ARG)
+# -------------------
+m4_define([_LT_SHELL_INIT],
+[ifdef([AC_DIVERSION_NOTICE],
+ [AC_DIVERT_PUSH(AC_DIVERSION_NOTICE)],
+ [AC_DIVERT_PUSH(NOTICE)])
+$1
+AC_DIVERT_POP
+])# _LT_SHELL_INIT
+
+
+# _LT_PROG_ECHO_BACKSLASH
+# -----------------------
+# Add some code to the start of the generated configure script which
+# will find an echo command which doesn't interpret backslashes.
+m4_defun([_LT_PROG_ECHO_BACKSLASH],
+[_LT_SHELL_INIT([
+# Check that we are running under the correct shell.
+SHELL=${CONFIG_SHELL-/bin/sh}
+
+case X$lt_ECHO in
+X*--fallback-echo)
+ # Remove one level of quotation (which was required for Make).
+ ECHO=`echo "$lt_ECHO" | sed 's,\\\\\[$]\\[$]0,'[$]0','`
+ ;;
+esac
+
+ECHO=${lt_ECHO-echo}
+if test "X[$]1" = X--no-reexec; then
+ # Discard the --no-reexec flag, and continue.
+ shift
+elif test "X[$]1" = X--fallback-echo; then
+ # Avoid inline document here, it may be left over
+ :
+elif test "X`{ $ECHO '\t'; } 2>/dev/null`" = 'X\t' ; then
+ # Yippee, $ECHO works!
+ :
+else
+ # Restart under the correct shell.
+ exec $SHELL "[$]0" --no-reexec ${1+"[$]@"}
+fi
+
+if test "X[$]1" = X--fallback-echo; then
+ # used as fallback echo
+ shift
+ cat <<_LT_EOF
+[$]*
+_LT_EOF
+ exit 0
+fi
+
+# The HP-UX ksh and POSIX shell print the target directory to stdout
+# if CDPATH is set.
+(unset CDPATH) >/dev/null 2>&1 && unset CDPATH
+
+if test -z "$lt_ECHO"; then
+ if test "X${echo_test_string+set}" != Xset; then
+ # find a string as large as possible, as long as the shell can cope with it
+ for cmd in 'sed 50q "[$]0"' 'sed 20q "[$]0"' 'sed 10q "[$]0"' 'sed 2q "[$]0"' 'echo test'; do
+ # expected sizes: less than 2Kb, 1Kb, 512 bytes, 16 bytes, ...
+ if { echo_test_string=`eval $cmd`; } 2>/dev/null &&
+ { test "X$echo_test_string" = "X$echo_test_string"; } 2>/dev/null
+ then
+ break
+ fi
+ done
+ fi
+
+ if test "X`{ $ECHO '\t'; } 2>/dev/null`" = 'X\t' &&
+ echo_testing_string=`{ $ECHO "$echo_test_string"; } 2>/dev/null` &&
+ test "X$echo_testing_string" = "X$echo_test_string"; then
+ :
+ else
+ # The Solaris, AIX, and Digital Unix default echo programs unquote
+ # backslashes. This makes it impossible to quote backslashes using
+ # echo "$something" | sed 's/\\/\\\\/g'
+ #
+ # So, first we look for a working echo in the user's PATH.
+
+ lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR
+ for dir in $PATH /usr/ucb; do
+ IFS="$lt_save_ifs"
+ if (test -f $dir/echo || test -f $dir/echo$ac_exeext) &&
+ test "X`($dir/echo '\t') 2>/dev/null`" = 'X\t' &&
+ echo_testing_string=`($dir/echo "$echo_test_string") 2>/dev/null` &&
+ test "X$echo_testing_string" = "X$echo_test_string"; then
+ ECHO="$dir/echo"
+ break
+ fi
+ done
+ IFS="$lt_save_ifs"
+
+ if test "X$ECHO" = Xecho; then
+ # We didn't find a better echo, so look for alternatives.
+ if test "X`{ print -r '\t'; } 2>/dev/null`" = 'X\t' &&
+ echo_testing_string=`{ print -r "$echo_test_string"; } 2>/dev/null` &&
+ test "X$echo_testing_string" = "X$echo_test_string"; then
+ # This shell has a builtin print -r that does the trick.
+ ECHO='print -r'
+ elif { test -f /bin/ksh || test -f /bin/ksh$ac_exeext; } &&
+ test "X$CONFIG_SHELL" != X/bin/ksh; then
+ # If we have ksh, try running configure again with it.
+ ORIGINAL_CONFIG_SHELL=${CONFIG_SHELL-/bin/sh}
+ export ORIGINAL_CONFIG_SHELL
+ CONFIG_SHELL=/bin/ksh
+ export CONFIG_SHELL
+ exec $CONFIG_SHELL "[$]0" --no-reexec ${1+"[$]@"}
+ else
+ # Try using printf.
+ ECHO='printf %s\n'
+ if test "X`{ $ECHO '\t'; } 2>/dev/null`" = 'X\t' &&
+ echo_testing_string=`{ $ECHO "$echo_test_string"; } 2>/dev/null` &&
+ test "X$echo_testing_string" = "X$echo_test_string"; then
+ # Cool, printf works
+ :
+ elif echo_testing_string=`($ORIGINAL_CONFIG_SHELL "[$]0" --fallback-echo '\t') 2>/dev/null` &&
+ test "X$echo_testing_string" = 'X\t' &&
+ echo_testing_string=`($ORIGINAL_CONFIG_SHELL "[$]0" --fallback-echo "$echo_test_string") 2>/dev/null` &&
+ test "X$echo_testing_string" = "X$echo_test_string"; then
+ CONFIG_SHELL=$ORIGINAL_CONFIG_SHELL
+ export CONFIG_SHELL
+ SHELL="$CONFIG_SHELL"
+ export SHELL
+ ECHO="$CONFIG_SHELL [$]0 --fallback-echo"
+ elif echo_testing_string=`($CONFIG_SHELL "[$]0" --fallback-echo '\t') 2>/dev/null` &&
+ test "X$echo_testing_string" = 'X\t' &&
+ echo_testing_string=`($CONFIG_SHELL "[$]0" --fallback-echo "$echo_test_string") 2>/dev/null` &&
+ test "X$echo_testing_string" = "X$echo_test_string"; then
+ ECHO="$CONFIG_SHELL [$]0 --fallback-echo"
+ else
+ # maybe with a smaller string...
+ prev=:
+
+ for cmd in 'echo test' 'sed 2q "[$]0"' 'sed 10q "[$]0"' 'sed 20q "[$]0"' 'sed 50q "[$]0"'; do
+ if { test "X$echo_test_string" = "X`eval $cmd`"; } 2>/dev/null
+ then
+ break
+ fi
+ prev="$cmd"
+ done
+
+ if test "$prev" != 'sed 50q "[$]0"'; then
+ echo_test_string=`eval $prev`
+ export echo_test_string
+ exec ${ORIGINAL_CONFIG_SHELL-${CONFIG_SHELL-/bin/sh}} "[$]0" ${1+"[$]@"}
+ else
+ # Oops. We lost completely, so just stick with echo.
+ ECHO=echo
+ fi
+ fi
+ fi
+ fi
+ fi
+fi
+
+# Copy echo and quote the copy suitably for passing to libtool from
+# the Makefile, instead of quoting the original, which is used later.
+lt_ECHO=$ECHO
+if test "X$lt_ECHO" = "X$CONFIG_SHELL [$]0 --fallback-echo"; then
+ lt_ECHO="$CONFIG_SHELL \\\$\[$]0 --fallback-echo"
+fi
+
+AC_SUBST(lt_ECHO)
+])
+_LT_DECL([], [SHELL], [1], [Shell to use when invoking shell scripts])
+_LT_DECL([], [ECHO], [1],
+ [An echo program that does not interpret backslashes])
+])# _LT_PROG_ECHO_BACKSLASH
+
+
+# _LT_ENABLE_LOCK
+# ---------------
+m4_defun([_LT_ENABLE_LOCK],
+[AC_ARG_ENABLE([libtool-lock],
+ [AS_HELP_STRING([--disable-libtool-lock],
+ [avoid locking (might break parallel builds)])])
+test "x$enable_libtool_lock" != xno && enable_libtool_lock=yes
+
+# Some flags need to be propagated to the compiler or linker for good
+# libtool support.
+case $host in
+ia64-*-hpux*)
+ # Find out which ABI we are using.
+ echo 'int i;' > conftest.$ac_ext
+ if AC_TRY_EVAL(ac_compile); then
+ case `/usr/bin/file conftest.$ac_objext` in
+ *ELF-32*)
+ HPUX_IA64_MODE="32"
+ ;;
+ *ELF-64*)
+ HPUX_IA64_MODE="64"
+ ;;
+ esac
+ fi
+ rm -rf conftest*
+ ;;
+*-*-irix6*)
+ # Find out which ABI we are using.
+ echo '[#]line __oline__ "configure"' > conftest.$ac_ext
+ if AC_TRY_EVAL(ac_compile); then
+ if test "$lt_cv_prog_gnu_ld" = yes; then
+ case `/usr/bin/file conftest.$ac_objext` in
+ *32-bit*)
+ LD="${LD-ld} -melf32bsmip"
+ ;;
+ *N32*)
+ LD="${LD-ld} -melf32bmipn32"
+ ;;
+ *64-bit*)
+ LD="${LD-ld} -melf64bmip"
+ ;;
+ esac
+ else
+ case `/usr/bin/file conftest.$ac_objext` in
+ *32-bit*)
+ LD="${LD-ld} -32"
+ ;;
+ *N32*)
+ LD="${LD-ld} -n32"
+ ;;
+ *64-bit*)
+ LD="${LD-ld} -64"
+ ;;
+ esac
+ fi
+ fi
+ rm -rf conftest*
+ ;;
+
+x86_64-*kfreebsd*-gnu|x86_64-*linux*|ppc*-*linux*|powerpc*-*linux*| \
+s390*-*linux*|s390*-*tpf*|sparc*-*linux*)
+ # Find out which ABI we are using.
+ echo 'int i;' > conftest.$ac_ext
+ if AC_TRY_EVAL(ac_compile); then
+ case `/usr/bin/file conftest.o` in
+ *32-bit*)
+ case $host in
+ x86_64-*kfreebsd*-gnu)
+ LD="${LD-ld} -m elf_i386_fbsd"
+ ;;
+ x86_64-*linux*)
+ LD="${LD-ld} -m elf_i386"
+ ;;
+ ppc64-*linux*|powerpc64-*linux*)
+ LD="${LD-ld} -m elf32ppclinux"
+ ;;
+ s390x-*linux*)
+ LD="${LD-ld} -m elf_s390"
+ ;;
+ sparc64-*linux*)
+ LD="${LD-ld} -m elf32_sparc"
+ ;;
+ esac
+ ;;
+ *64-bit*)
+ case $host in
+ x86_64-*kfreebsd*-gnu)
+ LD="${LD-ld} -m elf_x86_64_fbsd"
+ ;;
+ x86_64-*linux*)
+ LD="${LD-ld} -m elf_x86_64"
+ ;;
+ ppc*-*linux*|powerpc*-*linux*)
+ LD="${LD-ld} -m elf64ppc"
+ ;;
+ s390*-*linux*|s390*-*tpf*)
+ LD="${LD-ld} -m elf64_s390"
+ ;;
+ sparc*-*linux*)
+ LD="${LD-ld} -m elf64_sparc"
+ ;;
+ esac
+ ;;
+ esac
+ fi
+ rm -rf conftest*
+ ;;
+
+*-*-sco3.2v5*)
+ # On SCO OpenServer 5, we need -belf to get full-featured binaries.
+ SAVE_CFLAGS="$CFLAGS"
+ CFLAGS="$CFLAGS -belf"
+ AC_CACHE_CHECK([whether the C compiler needs -belf], lt_cv_cc_needs_belf,
+ [AC_LANG_PUSH(C)
+ AC_LINK_IFELSE([AC_LANG_PROGRAM([[]],[[]])],[lt_cv_cc_needs_belf=yes],[lt_cv_cc_needs_belf=no])
+ AC_LANG_POP])
+ if test x"$lt_cv_cc_needs_belf" != x"yes"; then
+ # this is probably gcc 2.8.0, egcs 1.0 or newer; no need for -belf
+ CFLAGS="$SAVE_CFLAGS"
+ fi
+ ;;
+sparc*-*solaris*)
+ # Find out which ABI we are using.
+ echo 'int i;' > conftest.$ac_ext
+ if AC_TRY_EVAL(ac_compile); then
+ case `/usr/bin/file conftest.o` in
+ *64-bit*)
+ case $lt_cv_prog_gnu_ld in
+ yes*) LD="${LD-ld} -m elf64_sparc" ;;
+ *)
+ if ${LD-ld} -64 -r -o conftest2.o conftest.o >/dev/null 2>&1; then
+ LD="${LD-ld} -64"
+ fi
+ ;;
+ esac
+ ;;
+ esac
+ fi
+ rm -rf conftest*
+ ;;
+esac
+
+need_locks="$enable_libtool_lock"
+])# _LT_ENABLE_LOCK
+
+
+# _LT_CMD_OLD_ARCHIVE
+# -------------------
+m4_defun([_LT_CMD_OLD_ARCHIVE],
+[AC_CHECK_TOOL(AR, ar, false)
+test -z "$AR" && AR=ar
+test -z "$AR_FLAGS" && AR_FLAGS=cru
+_LT_DECL([], [AR], [1], [The archiver])
+_LT_DECL([], [AR_FLAGS], [1])
+
+AC_CHECK_TOOL(STRIP, strip, :)
+test -z "$STRIP" && STRIP=:
+_LT_DECL([], [STRIP], [1], [A symbol stripping program])
+
+AC_CHECK_TOOL(RANLIB, ranlib, :)
+test -z "$RANLIB" && RANLIB=:
+_LT_DECL([], [RANLIB], [1],
+ [Commands used to install an old-style archive])
+
+# Determine commands to create old-style static archives.
+old_archive_cmds='$AR $AR_FLAGS $oldlib$oldobjs'
+old_postinstall_cmds='chmod 644 $oldlib'
+old_postuninstall_cmds=
+
+if test -n "$RANLIB"; then
+ case $host_os in
+ openbsd*)
+ old_postinstall_cmds="$old_postinstall_cmds~\$RANLIB -t \$oldlib"
+ ;;
+ *)
+ old_postinstall_cmds="$old_postinstall_cmds~\$RANLIB \$oldlib"
+ ;;
+ esac
+ old_archive_cmds="$old_archive_cmds~\$RANLIB \$oldlib"
+fi
+_LT_DECL([], [old_postinstall_cmds], [2])
+_LT_DECL([], [old_postuninstall_cmds], [2])
+_LT_TAGDECL([], [old_archive_cmds], [2],
+ [Commands used to build an old-style archive])
+])# _LT_CMD_OLD_ARCHIVE
+
+
+# _LT_COMPILER_OPTION(MESSAGE, VARIABLE-NAME, FLAGS,
+# [OUTPUT-FILE], [ACTION-SUCCESS], [ACTION-FAILURE])
+# ----------------------------------------------------------------
+# Check whether the given compiler option works
+AC_DEFUN([_LT_COMPILER_OPTION],
+[m4_require([_LT_FILEUTILS_DEFAULTS])dnl
+m4_require([_LT_DECL_SED])dnl
+AC_CACHE_CHECK([$1], [$2],
+ [$2=no
+ m4_if([$4], , [ac_outfile=conftest.$ac_objext], [ac_outfile=$4])
+ echo "$lt_simple_compile_test_code" > conftest.$ac_ext
+ lt_compiler_flag="$3"
+ # Insert the option either (1) after the last *FLAGS variable, or
+ # (2) before a word containing "conftest.", or (3) at the end.
+ # Note that $ac_compile itself does not contain backslashes and begins
+ # with a dollar sign (not a hyphen), so the echo should work correctly.
+ # The option is referenced via a variable to avoid confusing sed.
+ lt_compile=`echo "$ac_compile" | $SED \
+ -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
+ -e 's: [[^ ]]*conftest\.: $lt_compiler_flag&:; t' \
+ -e 's:$: $lt_compiler_flag:'`
+ (eval echo "\"\$as_me:__oline__: $lt_compile\"" >&AS_MESSAGE_LOG_FD)
+ (eval "$lt_compile" 2>conftest.err)
+ ac_status=$?
+ cat conftest.err >&AS_MESSAGE_LOG_FD
+ echo "$as_me:__oline__: \$? = $ac_status" >&AS_MESSAGE_LOG_FD
+ if (exit $ac_status) && test -s "$ac_outfile"; then
+ # The compiler can only warn and ignore the option if not recognized
+ # So say no if there are warnings other than the usual output.
+ $ECHO "X$_lt_compiler_boilerplate" | $Xsed -e '/^$/d' >conftest.exp
+ $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2
+ if test ! -s conftest.er2 || diff conftest.exp conftest.er2 >/dev/null; then
+ $2=yes
+ fi
+ fi
+ $RM conftest*
+])
+
+if test x"[$]$2" = xyes; then
+ m4_if([$5], , :, [$5])
+else
+ m4_if([$6], , :, [$6])
+fi
+])# _LT_COMPILER_OPTION
+
+# Old name:
+AU_ALIAS([AC_LIBTOOL_COMPILER_OPTION], [_LT_COMPILER_OPTION])
+dnl aclocal-1.4 backwards compatibility:
+dnl AC_DEFUN([AC_LIBTOOL_COMPILER_OPTION], [])
+
+
+# _LT_LINKER_OPTION(MESSAGE, VARIABLE-NAME, FLAGS,
+# [ACTION-SUCCESS], [ACTION-FAILURE])
+# ----------------------------------------------------
+# Check whether the given linker option works
+AC_DEFUN([_LT_LINKER_OPTION],
+[m4_require([_LT_FILEUTILS_DEFAULTS])dnl
+m4_require([_LT_DECL_SED])dnl
+AC_CACHE_CHECK([$1], [$2],
+ [$2=no
+ save_LDFLAGS="$LDFLAGS"
+ LDFLAGS="$LDFLAGS $3"
+ echo "$lt_simple_link_test_code" > conftest.$ac_ext
+ if (eval $ac_link 2>conftest.err) && test -s conftest$ac_exeext; then
+ # The linker can only warn and ignore the option if not recognized
+ # So say no if there are warnings
+ if test -s conftest.err; then
+ # Append any errors to the config.log.
+ cat conftest.err 1>&AS_MESSAGE_LOG_FD
+ $ECHO "X$_lt_linker_boilerplate" | $Xsed -e '/^$/d' > conftest.exp
+ $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2
+ if diff conftest.exp conftest.er2 >/dev/null; then
+ $2=yes
+ fi
+ else
+ $2=yes
+ fi
+ fi
+ $RM -r conftest*
+ LDFLAGS="$save_LDFLAGS"
+])
+
+if test x"[$]$2" = xyes; then
+ m4_if([$4], , :, [$4])
+else
+ m4_if([$5], , :, [$5])
+fi
+])# _LT_LINKER_OPTION
+
+# Old name:
+AU_ALIAS([AC_LIBTOOL_LINKER_OPTION], [_LT_LINKER_OPTION])
+dnl aclocal-1.4 backwards compatibility:
+dnl AC_DEFUN([AC_LIBTOOL_LINKER_OPTION], [])
+
+
+# LT_CMD_MAX_LEN
+#---------------
+AC_DEFUN([LT_CMD_MAX_LEN],
+[AC_REQUIRE([AC_CANONICAL_HOST])dnl
+# find the maximum length of command line arguments
+AC_MSG_CHECKING([the maximum length of command line arguments])
+AC_CACHE_VAL([lt_cv_sys_max_cmd_len], [dnl
+ i=0
+ teststring="ABCD"
+
+ case $build_os in
+ msdosdjgpp*)
+ # On DJGPP, this test can blow up pretty badly due to problems in libc
+ # (any single argument exceeding 2000 bytes causes a buffer overrun
+ # during glob expansion). Even if it were fixed, the result of this
+ # check would be larger than it should be.
+ lt_cv_sys_max_cmd_len=12288; # 12K is about right
+ ;;
+
+ gnu*)
+ # Under GNU Hurd, this test is not required because there is
+ # no limit to the length of command line arguments.
+ # Libtool will interpret -1 as no limit whatsoever
+ lt_cv_sys_max_cmd_len=-1;
+ ;;
+
+ cygwin* | mingw* | cegcc*)
+ # On Win9x/ME, this test blows up -- it succeeds, but takes
+ # about 5 minutes as the teststring grows exponentially.
+ # Worse, since 9x/ME are not pre-emptively multitasking,
+ # you end up with a "frozen" computer, even though with patience
+ # the test eventually succeeds (with a max line length of 256k).
+ # Instead, let's just punt: use the minimum linelength reported by
+ # all of the supported platforms: 8192 (on NT/2K/XP).
+ lt_cv_sys_max_cmd_len=8192;
+ ;;
+
+ amigaos*)
+ # On AmigaOS with pdksh, this test takes hours, literally.
+ # So we just punt and use a minimum line length of 8192.
+ lt_cv_sys_max_cmd_len=8192;
+ ;;
+
+ netbsd* | freebsd* | openbsd* | darwin* | dragonfly*)
+ # This has been around since 386BSD, at least. Likely further.
+ if test -x /sbin/sysctl; then
+ lt_cv_sys_max_cmd_len=`/sbin/sysctl -n kern.argmax`
+ elif test -x /usr/sbin/sysctl; then
+ lt_cv_sys_max_cmd_len=`/usr/sbin/sysctl -n kern.argmax`
+ else
+ lt_cv_sys_max_cmd_len=65536 # usable default for all BSDs
+ fi
+ # And add a safety zone
+ lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 4`
+ lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \* 3`
+ ;;
+
+ interix*)
+ # We know the value 262144 and hardcode it with a safety zone (like BSD)
+ lt_cv_sys_max_cmd_len=196608
+ ;;
+
+ osf*)
+ # Dr. Hans Ekkehard Plesser reports seeing a kernel panic running configure
+ # due to this test when exec_disable_arg_limit is 1 on Tru64. It is not
+ # nice to cause kernel panics so lets avoid the loop below.
+ # First set a reasonable default.
+ lt_cv_sys_max_cmd_len=16384
+ #
+ if test -x /sbin/sysconfig; then
+ case `/sbin/sysconfig -q proc exec_disable_arg_limit` in
+ *1*) lt_cv_sys_max_cmd_len=-1 ;;
+ esac
+ fi
+ ;;
+ sco3.2v5*)
+ lt_cv_sys_max_cmd_len=102400
+ ;;
+ sysv5* | sco5v6* | sysv4.2uw2*)
+ kargmax=`grep ARG_MAX /etc/conf/cf.d/stune 2>/dev/null`
+ if test -n "$kargmax"; then
+ lt_cv_sys_max_cmd_len=`echo $kargmax | sed 's/.*[[ ]]//'`
+ else
+ lt_cv_sys_max_cmd_len=32768
+ fi
+ ;;
+ *)
+ lt_cv_sys_max_cmd_len=`(getconf ARG_MAX) 2> /dev/null`
+ if test -n "$lt_cv_sys_max_cmd_len"; then
+ lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 4`
+ lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \* 3`
+ else
+ # Make teststring a little bigger before we do anything with it.
+ # a 1K string should be a reasonable start.
+ for i in 1 2 3 4 5 6 7 8 ; do
+ teststring=$teststring$teststring
+ done
+ SHELL=${SHELL-${CONFIG_SHELL-/bin/sh}}
+ # If test is not a shell built-in, we'll probably end up computing a
+ # maximum length that is only half of the actual maximum length, but
+ # we can't tell.
+ while { test "X"`$SHELL [$]0 --fallback-echo "X$teststring$teststring" 2>/dev/null` \
+ = "XX$teststring$teststring"; } >/dev/null 2>&1 &&
+ test $i != 17 # 1/2 MB should be enough
+ do
+ i=`expr $i + 1`
+ teststring=$teststring$teststring
+ done
+ # Only check the string length outside the loop.
+ lt_cv_sys_max_cmd_len=`expr "X$teststring" : ".*" 2>&1`
+ teststring=
+ # Add a significant safety factor because C++ compilers can tack on
+ # massive amounts of additional arguments before passing them to the
+ # linker. It appears as though 1/2 is a usable value.
+ lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 2`
+ fi
+ ;;
+ esac
+])
+if test -n $lt_cv_sys_max_cmd_len ; then
+ AC_MSG_RESULT($lt_cv_sys_max_cmd_len)
+else
+ AC_MSG_RESULT(none)
+fi
+max_cmd_len=$lt_cv_sys_max_cmd_len
+_LT_DECL([], [max_cmd_len], [0],
+ [What is the maximum length of a command?])
+])# LT_CMD_MAX_LEN
+
+# Old name:
+AU_ALIAS([AC_LIBTOOL_SYS_MAX_CMD_LEN], [LT_CMD_MAX_LEN])
+dnl aclocal-1.4 backwards compatibility:
+dnl AC_DEFUN([AC_LIBTOOL_SYS_MAX_CMD_LEN], [])
+
+
+# _LT_HEADER_DLFCN
+# ----------------
+m4_defun([_LT_HEADER_DLFCN],
+[AC_CHECK_HEADERS([dlfcn.h], [], [], [AC_INCLUDES_DEFAULT])dnl
+])# _LT_HEADER_DLFCN
+
+
+# _LT_TRY_DLOPEN_SELF (ACTION-IF-TRUE, ACTION-IF-TRUE-W-USCORE,
+# ACTION-IF-FALSE, ACTION-IF-CROSS-COMPILING)
+# ----------------------------------------------------------------
+m4_defun([_LT_TRY_DLOPEN_SELF],
+[m4_require([_LT_HEADER_DLFCN])dnl
+if test "$cross_compiling" = yes; then :
+ [$4]
+else
+ lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
+ lt_status=$lt_dlunknown
+ cat > conftest.$ac_ext <<_LT_EOF
+[#line __oline__ "configure"
+#include "confdefs.h"
+
+#if HAVE_DLFCN_H
+#include <dlfcn.h>
+#endif
+
+#include <stdio.h>
+
+#ifdef RTLD_GLOBAL
+# define LT_DLGLOBAL RTLD_GLOBAL
+#else
+# ifdef DL_GLOBAL
+# define LT_DLGLOBAL DL_GLOBAL
+# else
+# define LT_DLGLOBAL 0
+# endif
+#endif
+
+/* We may have to define LT_DLLAZY_OR_NOW in the command line if we
+ find out it does not work in some platform. */
+#ifndef LT_DLLAZY_OR_NOW
+# ifdef RTLD_LAZY
+# define LT_DLLAZY_OR_NOW RTLD_LAZY
+# else
+# ifdef DL_LAZY
+# define LT_DLLAZY_OR_NOW DL_LAZY
+# else
+# ifdef RTLD_NOW
+# define LT_DLLAZY_OR_NOW RTLD_NOW
+# else
+# ifdef DL_NOW
+# define LT_DLLAZY_OR_NOW DL_NOW
+# else
+# define LT_DLLAZY_OR_NOW 0
+# endif
+# endif
+# endif
+# endif
+#endif
+
+void fnord() { int i=42;}
+int main ()
+{
+ void *self = dlopen (0, LT_DLGLOBAL|LT_DLLAZY_OR_NOW);
+ int status = $lt_dlunknown;
+
+ if (self)
+ {
+ if (dlsym (self,"fnord")) status = $lt_dlno_uscore;
+ else if (dlsym( self,"_fnord")) status = $lt_dlneed_uscore;
+ /* dlclose (self); */
+ }
+ else
+ puts (dlerror ());
+
+ return status;
+}]
+_LT_EOF
+ if AC_TRY_EVAL(ac_link) && test -s conftest${ac_exeext} 2>/dev/null; then
+ (./conftest; exit; ) >&AS_MESSAGE_LOG_FD 2>/dev/null
+ lt_status=$?
+ case x$lt_status in
+ x$lt_dlno_uscore) $1 ;;
+ x$lt_dlneed_uscore) $2 ;;
+ x$lt_dlunknown|x*) $3 ;;
+ esac
+ else :
+ # compilation failed
+ $3
+ fi
+fi
+rm -fr conftest*
+])# _LT_TRY_DLOPEN_SELF
+
+
+# LT_SYS_DLOPEN_SELF
+# ------------------
+AC_DEFUN([LT_SYS_DLOPEN_SELF],
+[m4_require([_LT_HEADER_DLFCN])dnl
+if test "x$enable_dlopen" != xyes; then
+ enable_dlopen=unknown
+ enable_dlopen_self=unknown
+ enable_dlopen_self_static=unknown
+else
+ lt_cv_dlopen=no
+ lt_cv_dlopen_libs=
+
+ case $host_os in
+ beos*)
+ lt_cv_dlopen="load_add_on"
+ lt_cv_dlopen_libs=
+ lt_cv_dlopen_self=yes
+ ;;
+
+ mingw* | pw32* | cegcc*)
+ lt_cv_dlopen="LoadLibrary"
+ lt_cv_dlopen_libs=
+ ;;
+
+ cygwin*)
+ lt_cv_dlopen="dlopen"
+ lt_cv_dlopen_libs=
+ ;;
+
+ darwin*)
+ # if libdl is installed we need to link against it
+ AC_CHECK_LIB([dl], [dlopen],
+ [lt_cv_dlopen="dlopen" lt_cv_dlopen_libs="-ldl"],[
+ lt_cv_dlopen="dyld"
+ lt_cv_dlopen_libs=
+ lt_cv_dlopen_self=yes
+ ])
+ ;;
+
+ *)
+ AC_CHECK_FUNC([shl_load],
+ [lt_cv_dlopen="shl_load"],
+ [AC_CHECK_LIB([dld], [shl_load],
+ [lt_cv_dlopen="shl_load" lt_cv_dlopen_libs="-ldld"],
+ [AC_CHECK_FUNC([dlopen],
+ [lt_cv_dlopen="dlopen"],
+ [AC_CHECK_LIB([dl], [dlopen],
+ [lt_cv_dlopen="dlopen" lt_cv_dlopen_libs="-ldl"],
+ [AC_CHECK_LIB([svld], [dlopen],
+ [lt_cv_dlopen="dlopen" lt_cv_dlopen_libs="-lsvld"],
+ [AC_CHECK_LIB([dld], [dld_link],
+ [lt_cv_dlopen="dld_link" lt_cv_dlopen_libs="-ldld"])
+ ])
+ ])
+ ])
+ ])
+ ])
+ ;;
+ esac
+
+ if test "x$lt_cv_dlopen" != xno; then
+ enable_dlopen=yes
+ else
+ enable_dlopen=no
+ fi
+
+ case $lt_cv_dlopen in
+ dlopen)
+ save_CPPFLAGS="$CPPFLAGS"
+ test "x$ac_cv_header_dlfcn_h" = xyes && CPPFLAGS="$CPPFLAGS -DHAVE_DLFCN_H"
+
+ save_LDFLAGS="$LDFLAGS"
+ wl=$lt_prog_compiler_wl eval LDFLAGS=\"\$LDFLAGS $export_dynamic_flag_spec\"
+
+ save_LIBS="$LIBS"
+ LIBS="$lt_cv_dlopen_libs $LIBS"
+
+ AC_CACHE_CHECK([whether a program can dlopen itself],
+ lt_cv_dlopen_self, [dnl
+ _LT_TRY_DLOPEN_SELF(
+ lt_cv_dlopen_self=yes, lt_cv_dlopen_self=yes,
+ lt_cv_dlopen_self=no, lt_cv_dlopen_self=cross)
+ ])
+
+ if test "x$lt_cv_dlopen_self" = xyes; then
+ wl=$lt_prog_compiler_wl eval LDFLAGS=\"\$LDFLAGS $lt_prog_compiler_static\"
+ AC_CACHE_CHECK([whether a statically linked program can dlopen itself],
+ lt_cv_dlopen_self_static, [dnl
+ _LT_TRY_DLOPEN_SELF(
+ lt_cv_dlopen_self_static=yes, lt_cv_dlopen_self_static=yes,
+ lt_cv_dlopen_self_static=no, lt_cv_dlopen_self_static=cross)
+ ])
+ fi
+
+ CPPFLAGS="$save_CPPFLAGS"
+ LDFLAGS="$save_LDFLAGS"
+ LIBS="$save_LIBS"
+ ;;
+ esac
+
+ case $lt_cv_dlopen_self in
+ yes|no) enable_dlopen_self=$lt_cv_dlopen_self ;;
+ *) enable_dlopen_self=unknown ;;
+ esac
+
+ case $lt_cv_dlopen_self_static in
+ yes|no) enable_dlopen_self_static=$lt_cv_dlopen_self_static ;;
+ *) enable_dlopen_self_static=unknown ;;
+ esac
+fi
+_LT_DECL([dlopen_support], [enable_dlopen], [0],
+ [Whether dlopen is supported])
+_LT_DECL([dlopen_self], [enable_dlopen_self], [0],
+ [Whether dlopen of programs is supported])
+_LT_DECL([dlopen_self_static], [enable_dlopen_self_static], [0],
+ [Whether dlopen of statically linked programs is supported])
+])# LT_SYS_DLOPEN_SELF
+
+# Old name:
+AU_ALIAS([AC_LIBTOOL_DLOPEN_SELF], [LT_SYS_DLOPEN_SELF])
+dnl aclocal-1.4 backwards compatibility:
+dnl AC_DEFUN([AC_LIBTOOL_DLOPEN_SELF], [])
+
+
+# _LT_COMPILER_C_O([TAGNAME])
+# ---------------------------
+# Check to see if options -c and -o are simultaneously supported by compiler.
+# This macro does not hard code the compiler like AC_PROG_CC_C_O.
+m4_defun([_LT_COMPILER_C_O],
+[m4_require([_LT_DECL_SED])dnl
+m4_require([_LT_FILEUTILS_DEFAULTS])dnl
+m4_require([_LT_TAG_COMPILER])dnl
+AC_CACHE_CHECK([if $compiler supports -c -o file.$ac_objext],
+ [_LT_TAGVAR(lt_cv_prog_compiler_c_o, $1)],
+ [_LT_TAGVAR(lt_cv_prog_compiler_c_o, $1)=no
+ $RM -r conftest 2>/dev/null
+ mkdir conftest
+ cd conftest
+ mkdir out
+ echo "$lt_simple_compile_test_code" > conftest.$ac_ext
+
+ lt_compiler_flag="-o out/conftest2.$ac_objext"
+ # Insert the option either (1) after the last *FLAGS variable, or
+ # (2) before a word containing "conftest.", or (3) at the end.
+ # Note that $ac_compile itself does not contain backslashes and begins
+ # with a dollar sign (not a hyphen), so the echo should work correctly.
+ lt_compile=`echo "$ac_compile" | $SED \
+ -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
+ -e 's: [[^ ]]*conftest\.: $lt_compiler_flag&:; t' \
+ -e 's:$: $lt_compiler_flag:'`
+ (eval echo "\"\$as_me:__oline__: $lt_compile\"" >&AS_MESSAGE_LOG_FD)
+ (eval "$lt_compile" 2>out/conftest.err)
+ ac_status=$?
+ cat out/conftest.err >&AS_MESSAGE_LOG_FD
+ echo "$as_me:__oline__: \$? = $ac_status" >&AS_MESSAGE_LOG_FD
+ if (exit $ac_status) && test -s out/conftest2.$ac_objext
+ then
+ # The compiler can only warn and ignore the option if not recognized
+ # So say no if there are warnings
+ $ECHO "X$_lt_compiler_boilerplate" | $Xsed -e '/^$/d' > out/conftest.exp
+ $SED '/^$/d; /^ *+/d' out/conftest.err >out/conftest.er2
+ if test ! -s out/conftest.er2 || diff out/conftest.exp out/conftest.er2 >/dev/null; then
+ _LT_TAGVAR(lt_cv_prog_compiler_c_o, $1)=yes
+ fi
+ fi
+ chmod u+w . 2>&AS_MESSAGE_LOG_FD
+ $RM conftest*
+ # SGI C++ compiler will create directory out/ii_files/ for
+ # template instantiation
+ test -d out/ii_files && $RM out/ii_files/* && rmdir out/ii_files
+ $RM out/* && rmdir out
+ cd ..
+ $RM -r conftest
+ $RM conftest*
+])
+_LT_TAGDECL([compiler_c_o], [lt_cv_prog_compiler_c_o], [1],
+ [Does compiler simultaneously support -c and -o options?])
+])# _LT_COMPILER_C_O
+
+
+# _LT_COMPILER_FILE_LOCKS([TAGNAME])
+# ----------------------------------
+# Check to see if we can do hard links to lock some files if needed
+m4_defun([_LT_COMPILER_FILE_LOCKS],
+[m4_require([_LT_ENABLE_LOCK])dnl
+m4_require([_LT_FILEUTILS_DEFAULTS])dnl
+_LT_COMPILER_C_O([$1])
+
+hard_links="nottested"
+if test "$_LT_TAGVAR(lt_cv_prog_compiler_c_o, $1)" = no && test "$need_locks" != no; then
+ # do not overwrite the value of need_locks provided by the user
+ AC_MSG_CHECKING([if we can lock with hard links])
+ hard_links=yes
+ $RM conftest*
+ ln conftest.a conftest.b 2>/dev/null && hard_links=no
+ touch conftest.a
+ ln conftest.a conftest.b 2>&5 || hard_links=no
+ ln conftest.a conftest.b 2>/dev/null && hard_links=no
+ AC_MSG_RESULT([$hard_links])
+ if test "$hard_links" = no; then
+ AC_MSG_WARN([`$CC' does not support `-c -o', so `make -j' may be unsafe])
+ need_locks=warn
+ fi
+else
+ need_locks=no
+fi
+_LT_DECL([], [need_locks], [1], [Must we lock files when doing compilation?])
+])# _LT_COMPILER_FILE_LOCKS
+
+
+# _LT_CHECK_OBJDIR
+# ----------------
+m4_defun([_LT_CHECK_OBJDIR],
+[AC_CACHE_CHECK([for objdir], [lt_cv_objdir],
+[rm -f .libs 2>/dev/null
+mkdir .libs 2>/dev/null
+if test -d .libs; then
+ lt_cv_objdir=.libs
+else
+ # MS-DOS does not allow filenames that begin with a dot.
+ lt_cv_objdir=_libs
+fi
+rmdir .libs 2>/dev/null])
+objdir=$lt_cv_objdir
+_LT_DECL([], [objdir], [0],
+ [The name of the directory that contains temporary libtool files])dnl
+m4_pattern_allow([LT_OBJDIR])dnl
+AC_DEFINE_UNQUOTED(LT_OBJDIR, "$lt_cv_objdir/",
+ [Define to the sub-directory in which libtool stores uninstalled libraries.])
+])# _LT_CHECK_OBJDIR
+
+
+# _LT_LINKER_HARDCODE_LIBPATH([TAGNAME])
+# --------------------------------------
+# Check hardcoding attributes.
+m4_defun([_LT_LINKER_HARDCODE_LIBPATH],
+[AC_MSG_CHECKING([how to hardcode library paths into programs])
+_LT_TAGVAR(hardcode_action, $1)=
+if test -n "$_LT_TAGVAR(hardcode_libdir_flag_spec, $1)" ||
+ test -n "$_LT_TAGVAR(runpath_var, $1)" ||
+ test "X$_LT_TAGVAR(hardcode_automatic, $1)" = "Xyes" ; then
+
+ # We can hardcode non-existent directories.
+ if test "$_LT_TAGVAR(hardcode_direct, $1)" != no &&
+ # If the only mechanism to avoid hardcoding is shlibpath_var, we
+ # have to relink, otherwise we might link with an installed library
+ # when we should be linking with a yet-to-be-installed one
+ ## test "$_LT_TAGVAR(hardcode_shlibpath_var, $1)" != no &&
+ test "$_LT_TAGVAR(hardcode_minus_L, $1)" != no; then
+ # Linking always hardcodes the temporary library directory.
+ _LT_TAGVAR(hardcode_action, $1)=relink
+ else
+ # We can link without hardcoding, and we can hardcode nonexisting dirs.
+ _LT_TAGVAR(hardcode_action, $1)=immediate
+ fi
+else
+ # We cannot hardcode anything, or else we can only hardcode existing
+ # directories.
+ _LT_TAGVAR(hardcode_action, $1)=unsupported
+fi
+AC_MSG_RESULT([$_LT_TAGVAR(hardcode_action, $1)])
+
+if test "$_LT_TAGVAR(hardcode_action, $1)" = relink ||
+ test "$_LT_TAGVAR(inherit_rpath, $1)" = yes; then
+ # Fast installation is not supported
+ enable_fast_install=no
+elif test "$shlibpath_overrides_runpath" = yes ||
+ test "$enable_shared" = no; then
+ # Fast installation is not necessary
+ enable_fast_install=needless
+fi
+_LT_TAGDECL([], [hardcode_action], [0],
+ [How to hardcode a shared library path into an executable])
+])# _LT_LINKER_HARDCODE_LIBPATH
+
+
+# _LT_CMD_STRIPLIB
+# ----------------
+m4_defun([_LT_CMD_STRIPLIB],
+[m4_require([_LT_DECL_EGREP])
+striplib=
+old_striplib=
+AC_MSG_CHECKING([whether stripping libraries is possible])
+if test -n "$STRIP" && $STRIP -V 2>&1 | $GREP "GNU strip" >/dev/null; then
+ test -z "$old_striplib" && old_striplib="$STRIP --strip-debug"
+ test -z "$striplib" && striplib="$STRIP --strip-unneeded"
+ AC_MSG_RESULT([yes])
+else
+# FIXME - insert some real tests, host_os isn't really good enough
+ case $host_os in
+ darwin*)
+ if test -n "$STRIP" ; then
+ striplib="$STRIP -x"
+ old_striplib="$STRIP -S"
+ AC_MSG_RESULT([yes])
+ else
+ AC_MSG_RESULT([no])
+ fi
+ ;;
+ *)
+ AC_MSG_RESULT([no])
+ ;;
+ esac
+fi
+_LT_DECL([], [old_striplib], [1], [Commands to strip libraries])
+_LT_DECL([], [striplib], [1])
+])# _LT_CMD_STRIPLIB
+
+
+# _LT_SYS_DYNAMIC_LINKER([TAG])
+# -----------------------------
+# PORTME Fill in your ld.so characteristics
+m4_defun([_LT_SYS_DYNAMIC_LINKER],
+[AC_REQUIRE([AC_CANONICAL_HOST])dnl
+m4_require([_LT_DECL_EGREP])dnl
+m4_require([_LT_FILEUTILS_DEFAULTS])dnl
+m4_require([_LT_DECL_OBJDUMP])dnl
+m4_require([_LT_DECL_SED])dnl
+AC_MSG_CHECKING([dynamic linker characteristics])
+m4_if([$1],
+ [], [
+if test "$GCC" = yes; then
+ case $host_os in
+ darwin*) lt_awk_arg="/^libraries:/,/LR/" ;;
+ *) lt_awk_arg="/^libraries:/" ;;
+ esac
+ lt_search_path_spec=`$CC -print-search-dirs | awk $lt_awk_arg | $SED -e "s/^libraries://" -e "s,=/,/,g"`
+ if $ECHO "$lt_search_path_spec" | $GREP ';' >/dev/null ; then
+ # if the path contains ";" then we assume it to be the separator
+ # otherwise default to the standard path separator (i.e. ":") - it is
+ # assumed that no part of a normal pathname contains ";" but that should
+ # okay in the real world where ";" in dirpaths is itself problematic.
+ lt_search_path_spec=`$ECHO "$lt_search_path_spec" | $SED -e 's/;/ /g'`
+ else
+ lt_search_path_spec=`$ECHO "$lt_search_path_spec" | $SED -e "s/$PATH_SEPARATOR/ /g"`
+ fi
+ # Ok, now we have the path, separated by spaces, we can step through it
+ # and add multilib dir if necessary.
+ lt_tmp_lt_search_path_spec=
+ lt_multi_os_dir=`$CC $CPPFLAGS $CFLAGS $LDFLAGS -print-multi-os-directory 2>/dev/null`
+ for lt_sys_path in $lt_search_path_spec; do
+ if test -d "$lt_sys_path/$lt_multi_os_dir"; then
+ lt_tmp_lt_search_path_spec="$lt_tmp_lt_search_path_spec $lt_sys_path/$lt_multi_os_dir"
+ else
+ test -d "$lt_sys_path" && \
+ lt_tmp_lt_search_path_spec="$lt_tmp_lt_search_path_spec $lt_sys_path"
+ fi
+ done
+ lt_search_path_spec=`$ECHO $lt_tmp_lt_search_path_spec | awk '
+BEGIN {RS=" "; FS="/|\n";} {
+ lt_foo="";
+ lt_count=0;
+ for (lt_i = NF; lt_i > 0; lt_i--) {
+ if ($lt_i != "" && $lt_i != ".") {
+ if ($lt_i == "..") {
+ lt_count++;
+ } else {
+ if (lt_count == 0) {
+ lt_foo="/" $lt_i lt_foo;
+ } else {
+ lt_count--;
+ }
+ }
+ }
+ }
+ if (lt_foo != "") { lt_freq[[lt_foo]]++; }
+ if (lt_freq[[lt_foo]] == 1) { print lt_foo; }
+}'`
+ sys_lib_search_path_spec=`$ECHO $lt_search_path_spec`
+else
+ sys_lib_search_path_spec="/lib /usr/lib /usr/local/lib"
+fi])
+library_names_spec=
+libname_spec='lib$name'
+soname_spec=
+shrext_cmds=".so"
+postinstall_cmds=
+postuninstall_cmds=
+finish_cmds=
+finish_eval=
+shlibpath_var=
+shlibpath_overrides_runpath=unknown
+version_type=none
+dynamic_linker="$host_os ld.so"
+sys_lib_dlsearch_path_spec="/lib /usr/lib"
+need_lib_prefix=unknown
+hardcode_into_libs=no
+
+# when you set need_version to no, make sure it does not cause -set_version
+# flags to be left without arguments
+need_version=unknown
+
+case $host_os in
+aix3*)
+ version_type=linux
+ library_names_spec='${libname}${release}${shared_ext}$versuffix $libname.a'
+ shlibpath_var=LIBPATH
+
+ # AIX 3 has no versioning support, so we append a major version to the name.
+ soname_spec='${libname}${release}${shared_ext}$major'
+ ;;
+
+aix[[4-9]]*)
+ version_type=linux
+ need_lib_prefix=no
+ need_version=no
+ hardcode_into_libs=yes
+ if test "$host_cpu" = ia64; then
+ # AIX 5 supports IA64
+ library_names_spec='${libname}${release}${shared_ext}$major ${libname}${release}${shared_ext}$versuffix $libname${shared_ext}'
+ shlibpath_var=LD_LIBRARY_PATH
+ else
+ # With GCC up to 2.95.x, collect2 would create an import file
+ # for dependence libraries. The import file would start with
+ # the line `#! .'. This would cause the generated library to
+ # depend on `.', always an invalid library. This was fixed in
+ # development snapshots of GCC prior to 3.0.
+ case $host_os in
+ aix4 | aix4.[[01]] | aix4.[[01]].*)
+ if { echo '#if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 97)'
+ echo ' yes '
+ echo '#endif'; } | ${CC} -E - | $GREP yes > /dev/null; then
+ :
+ else
+ can_build_shared=no
+ fi
+ ;;
+ esac
+ # AIX (on Power*) has no versioning support, so currently we can not hardcode correct
+ # soname into executable. Probably we can add versioning support to
+ # collect2, so additional links can be useful in future.
+ if test "$aix_use_runtimelinking" = yes; then
+ # If using run time linking (on AIX 4.2 or later) use lib<name>.so
+ # instead of lib<name>.a to let people know that these are not
+ # typical AIX shared libraries.
+ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+ else
+ # We preserve .a as extension for shared libraries through AIX4.2
+ # and later when we are not doing run time linking.
+ library_names_spec='${libname}${release}.a $libname.a'
+ soname_spec='${libname}${release}${shared_ext}$major'
+ fi
+ shlibpath_var=LIBPATH
+ fi
+ ;;
+
+amigaos*)
+ case $host_cpu in
+ powerpc)
+ # Since July 2007 AmigaOS4 officially supports .so libraries.
+ # When compiling the executable, add -use-dynld -Lsobjs: to the compileline.
+ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+ ;;
+ m68k)
+ library_names_spec='$libname.ixlibrary $libname.a'
+ # Create ${libname}_ixlibrary.a entries in /sys/libs.
+ finish_eval='for lib in `ls $libdir/*.ixlibrary 2>/dev/null`; do libname=`$ECHO "X$lib" | $Xsed -e '\''s%^.*/\([[^/]]*\)\.ixlibrary$%\1%'\''`; test $RM /sys/libs/${libname}_ixlibrary.a; $show "cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a"; cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a || exit 1; done'
+ ;;
+ esac
+ ;;
+
+beos*)
+ library_names_spec='${libname}${shared_ext}'
+ dynamic_linker="$host_os ld.so"
+ shlibpath_var=LIBRARY_PATH
+ ;;
+
+bsdi[[45]]*)
+ version_type=linux
+ need_version=no
+ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+ soname_spec='${libname}${release}${shared_ext}$major'
+ finish_cmds='PATH="\$PATH:/sbin" ldconfig $libdir'
+ shlibpath_var=LD_LIBRARY_PATH
+ sys_lib_search_path_spec="/shlib /usr/lib /usr/X11/lib /usr/contrib/lib /lib /usr/local/lib"
+ sys_lib_dlsearch_path_spec="/shlib /usr/lib /usr/local/lib"
+ # the default ld.so.conf also contains /usr/contrib/lib and
+ # /usr/X11R6/lib (/usr/X11 is a link to /usr/X11R6), but let us allow
+ # libtool to hard-code these into programs
+ ;;
+
+cygwin* | mingw* | pw32* | cegcc*)
+ version_type=windows
+ shrext_cmds=".dll"
+ need_version=no
+ need_lib_prefix=no
+
+ case $GCC,$host_os in
+ yes,cygwin* | yes,mingw* | yes,pw32* | yes,cegcc*)
+ library_names_spec='$libname.dll.a'
+ # DLL is installed to $(libdir)/../bin by postinstall_cmds
+ postinstall_cmds='base_file=`basename \${file}`~
+ dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\${base_file}'\''i; echo \$dlname'\''`~
+ dldir=$destdir/`dirname \$dlpath`~
+ test -d \$dldir || mkdir -p \$dldir~
+ $install_prog $dir/$dlname \$dldir/$dlname~
+ chmod a+x \$dldir/$dlname~
+ if test -n '\''$stripme'\'' && test -n '\''$striplib'\''; then
+ eval '\''$striplib \$dldir/$dlname'\'' || exit \$?;
+ fi'
+ postuninstall_cmds='dldll=`$SHELL 2>&1 -c '\''. $file; echo \$dlname'\''`~
+ dlpath=$dir/\$dldll~
+ $RM \$dlpath'
+ shlibpath_overrides_runpath=yes
+
+ case $host_os in
+ cygwin*)
+ # Cygwin DLLs use 'cyg' prefix rather than 'lib'
+ soname_spec='`echo ${libname} | sed -e 's/^lib/cyg/'``echo ${release} | $SED -e 's/[[.]]/-/g'`${versuffix}${shared_ext}'
+ sys_lib_search_path_spec="/usr/lib /lib/w32api /lib /usr/local/lib"
+ ;;
+ mingw* | cegcc*)
+ # MinGW DLLs use traditional 'lib' prefix
+ soname_spec='${libname}`echo ${release} | $SED -e 's/[[.]]/-/g'`${versuffix}${shared_ext}'
+ sys_lib_search_path_spec=`$CC -print-search-dirs | $GREP "^libraries:" | $SED -e "s/^libraries://" -e "s,=/,/,g"`
+ if $ECHO "$sys_lib_search_path_spec" | [$GREP ';[c-zC-Z]:/' >/dev/null]; then
+ # It is most probably a Windows format PATH printed by
+ # mingw gcc, but we are running on Cygwin. Gcc prints its search
+ # path with ; separators, and with drive letters. We can handle the
+ # drive letters (cygwin fileutils understands them), so leave them,
+ # especially as we might pass files found there to a mingw objdump,
+ # which wouldn't understand a cygwinified path. Ahh.
+ sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | $SED -e 's/;/ /g'`
+ else
+ sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | $SED -e "s/$PATH_SEPARATOR/ /g"`
+ fi
+ ;;
+ pw32*)
+ # pw32 DLLs use 'pw' prefix rather than 'lib'
+ library_names_spec='`echo ${libname} | sed -e 's/^lib/pw/'``echo ${release} | $SED -e 's/[[.]]/-/g'`${versuffix}${shared_ext}'
+ ;;
+ esac
+ ;;
+
+ *)
+ library_names_spec='${libname}`echo ${release} | $SED -e 's/[[.]]/-/g'`${versuffix}${shared_ext} $libname.lib'
+ ;;
+ esac
+ dynamic_linker='Win32 ld.exe'
+ # FIXME: first we should search . and the directory the executable is in
+ shlibpath_var=PATH
+ ;;
+
+darwin* | rhapsody*)
+ dynamic_linker="$host_os dyld"
+ version_type=darwin
+ need_lib_prefix=no
+ need_version=no
+ library_names_spec='${libname}${release}${major}$shared_ext ${libname}$shared_ext'
+ soname_spec='${libname}${release}${major}$shared_ext'
+ shlibpath_overrides_runpath=yes
+ shlibpath_var=DYLD_LIBRARY_PATH
+ shrext_cmds='`test .$module = .yes && echo .so || echo .dylib`'
+m4_if([$1], [],[
+ sys_lib_search_path_spec="$sys_lib_search_path_spec /usr/local/lib"])
+ sys_lib_dlsearch_path_spec='/usr/local/lib /lib /usr/lib'
+ ;;
+
+dgux*)
+ version_type=linux
+ need_lib_prefix=no
+ need_version=no
+ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname$shared_ext'
+ soname_spec='${libname}${release}${shared_ext}$major'
+ shlibpath_var=LD_LIBRARY_PATH
+ ;;
+
+freebsd1*)
+ dynamic_linker=no
+ ;;
+
+freebsd* | dragonfly*)
+ # DragonFly does not have aout. When/if they implement a new
+ # versioning mechanism, adjust this.
+ if test -x /usr/bin/objformat; then
+ objformat=`/usr/bin/objformat`
+ else
+ case $host_os in
+ freebsd[[123]]*) objformat=aout ;;
+ *) objformat=elf ;;
+ esac
+ fi
+ version_type=freebsd-$objformat
+ case $version_type in
+ freebsd-elf*)
+ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext} $libname${shared_ext}'
+ need_version=no
+ need_lib_prefix=no
+ ;;
+ freebsd-*)
+ library_names_spec='${libname}${release}${shared_ext}$versuffix $libname${shared_ext}$versuffix'
+ need_version=yes
+ ;;
+ esac
+ shlibpath_var=LD_LIBRARY_PATH
+ case $host_os in
+ freebsd2*)
+ shlibpath_overrides_runpath=yes
+ ;;
+ freebsd3.[[01]]* | freebsdelf3.[[01]]*)
+ shlibpath_overrides_runpath=yes
+ hardcode_into_libs=yes
+ ;;
+ freebsd3.[[2-9]]* | freebsdelf3.[[2-9]]* | \
+ freebsd4.[[0-5]] | freebsdelf4.[[0-5]] | freebsd4.1.1 | freebsdelf4.1.1)
+ shlibpath_overrides_runpath=no
+ hardcode_into_libs=yes
+ ;;
+ *) # from 4.6 on, and DragonFly
+ shlibpath_overrides_runpath=yes
+ hardcode_into_libs=yes
+ ;;
+ esac
+ ;;
+
+gnu*)
+ version_type=linux
+ need_lib_prefix=no
+ need_version=no
+ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}${major} ${libname}${shared_ext}'
+ soname_spec='${libname}${release}${shared_ext}$major'
+ shlibpath_var=LD_LIBRARY_PATH
+ hardcode_into_libs=yes
+ ;;
+
+hpux9* | hpux10* | hpux11*)
+ # Give a soname corresponding to the major version so that dld.sl refuses to
+ # link against other versions.
+ version_type=sunos
+ need_lib_prefix=no
+ need_version=no
+ case $host_cpu in
+ ia64*)
+ shrext_cmds='.so'
+ hardcode_into_libs=yes
+ dynamic_linker="$host_os dld.so"
+ shlibpath_var=LD_LIBRARY_PATH
+ shlibpath_overrides_runpath=yes # Unless +noenvvar is specified.
+ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+ soname_spec='${libname}${release}${shared_ext}$major'
+ if test "X$HPUX_IA64_MODE" = X32; then
+ sys_lib_search_path_spec="/usr/lib/hpux32 /usr/local/lib/hpux32 /usr/local/lib"
+ else
+ sys_lib_search_path_spec="/usr/lib/hpux64 /usr/local/lib/hpux64"
+ fi
+ sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec
+ ;;
+ hppa*64*)
+ shrext_cmds='.sl'
+ hardcode_into_libs=yes
+ dynamic_linker="$host_os dld.sl"
+ shlibpath_var=LD_LIBRARY_PATH # How should we handle SHLIB_PATH
+ shlibpath_overrides_runpath=yes # Unless +noenvvar is specified.
+ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+ soname_spec='${libname}${release}${shared_ext}$major'
+ sys_lib_search_path_spec="/usr/lib/pa20_64 /usr/ccs/lib/pa20_64"
+ sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec
+ ;;
+ *)
+ shrext_cmds='.sl'
+ dynamic_linker="$host_os dld.sl"
+ shlibpath_var=SHLIB_PATH
+ shlibpath_overrides_runpath=no # +s is required to enable SHLIB_PATH
+ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+ soname_spec='${libname}${release}${shared_ext}$major'
+ ;;
+ esac
+ # HP-UX runs *really* slowly unless shared libraries are mode 555.
+ postinstall_cmds='chmod 555 $lib'
+ ;;
+
+interix[[3-9]]*)
+ version_type=linux
+ need_lib_prefix=no
+ need_version=no
+ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}'
+ soname_spec='${libname}${release}${shared_ext}$major'
+ dynamic_linker='Interix 3.x ld.so.1 (PE, like ELF)'
+ shlibpath_var=LD_LIBRARY_PATH
+ shlibpath_overrides_runpath=no
+ hardcode_into_libs=yes
+ ;;
+
+irix5* | irix6* | nonstopux*)
+ case $host_os in
+ nonstopux*) version_type=nonstopux ;;
+ *)
+ if test "$lt_cv_prog_gnu_ld" = yes; then
+ version_type=linux
+ else
+ version_type=irix
+ fi ;;
+ esac
+ need_lib_prefix=no
+ need_version=no
+ soname_spec='${libname}${release}${shared_ext}$major'
+ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${release}${shared_ext} $libname${shared_ext}'
+ case $host_os in
+ irix5* | nonstopux*)
+ libsuff= shlibsuff=
+ ;;
+ *)
+ case $LD in # libtool.m4 will add one of these switches to LD
+ *-32|*"-32 "|*-melf32bsmip|*"-melf32bsmip ")
+ libsuff= shlibsuff= libmagic=32-bit;;
+ *-n32|*"-n32 "|*-melf32bmipn32|*"-melf32bmipn32 ")
+ libsuff=32 shlibsuff=N32 libmagic=N32;;
+ *-64|*"-64 "|*-melf64bmip|*"-melf64bmip ")
+ libsuff=64 shlibsuff=64 libmagic=64-bit;;
+ *) libsuff= shlibsuff= libmagic=never-match;;
+ esac
+ ;;
+ esac
+ shlibpath_var=LD_LIBRARY${shlibsuff}_PATH
+ shlibpath_overrides_runpath=no
+ sys_lib_search_path_spec="/usr/lib${libsuff} /lib${libsuff} /usr/local/lib${libsuff}"
+ sys_lib_dlsearch_path_spec="/usr/lib${libsuff} /lib${libsuff}"
+ hardcode_into_libs=yes
+ ;;
+
+# No shared lib support for Linux oldld, aout, or coff.
+linux*oldld* | linux*aout* | linux*coff*)
+ dynamic_linker=no
+ ;;
+
+# This must be Linux ELF.
+linux* | k*bsd*-gnu | kopensolaris*-gnu)
+ version_type=linux
+ need_lib_prefix=no
+ need_version=no
+ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+ soname_spec='${libname}${release}${shared_ext}$major'
+ finish_cmds='PATH="\$PATH:/sbin" ldconfig -n $libdir'
+ shlibpath_var=LD_LIBRARY_PATH
+ shlibpath_overrides_runpath=no
+ # Some binutils ld are patched to set DT_RUNPATH
+ save_LDFLAGS=$LDFLAGS
+ save_libdir=$libdir
+ eval "libdir=/foo; wl=\"$_LT_TAGVAR(lt_prog_compiler_wl, $1)\"; \
+ LDFLAGS=\"\$LDFLAGS $_LT_TAGVAR(hardcode_libdir_flag_spec, $1)\""
+ AC_LINK_IFELSE([AC_LANG_PROGRAM([],[])],
+ [AS_IF([ ($OBJDUMP -p conftest$ac_exeext) 2>/dev/null | grep "RUNPATH.*$libdir" >/dev/null],
+ [shlibpath_overrides_runpath=yes])])
+ LDFLAGS=$save_LDFLAGS
+ libdir=$save_libdir
+
+ # This implies no fast_install, which is unacceptable.
+ # Some rework will be needed to allow for fast_install
+ # before this can be enabled.
+ hardcode_into_libs=yes
+
+ # Append ld.so.conf contents to the search path
+ if test -f /etc/ld.so.conf; then
+ lt_ld_extra=`awk '/^include / { system(sprintf("cd /etc; cat %s 2>/dev/null", \[$]2)); skip = 1; } { if (!skip) print \[$]0; skip = 0; }' < /etc/ld.so.conf | $SED -e 's/#.*//;/^[ ]*hwcap[ ]/d;s/[:, ]/ /g;s/=[^=]*$//;s/=[^= ]* / /g;/^$/d' | tr '\n' ' '`
+ sys_lib_dlsearch_path_spec="/lib /usr/lib $lt_ld_extra"
+ fi
+
+ # We used to test for /lib/ld.so.1 and disable shared libraries on
+ # powerpc, because MkLinux only supported shared libraries with the
+ # GNU dynamic linker. Since this was broken with cross compilers,
+ # most powerpc-linux boxes support dynamic linking these days and
+ # people can always --disable-shared, the test was removed, and we
+ # assume the GNU/Linux dynamic linker is in use.
+ dynamic_linker='GNU/Linux ld.so'
+ ;;
+
+netbsdelf*-gnu)
+ version_type=linux
+ need_lib_prefix=no
+ need_version=no
+ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}'
+ soname_spec='${libname}${release}${shared_ext}$major'
+ shlibpath_var=LD_LIBRARY_PATH
+ shlibpath_overrides_runpath=no
+ hardcode_into_libs=yes
+ dynamic_linker='NetBSD ld.elf_so'
+ ;;
+
+netbsd*)
+ version_type=sunos
+ need_lib_prefix=no
+ need_version=no
+ if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then
+ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix'
+ finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir'
+ dynamic_linker='NetBSD (a.out) ld.so'
+ else
+ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}'
+ soname_spec='${libname}${release}${shared_ext}$major'
+ dynamic_linker='NetBSD ld.elf_so'
+ fi
+ shlibpath_var=LD_LIBRARY_PATH
+ shlibpath_overrides_runpath=yes
+ hardcode_into_libs=yes
+ ;;
+
+newsos6)
+ version_type=linux
+ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+ shlibpath_var=LD_LIBRARY_PATH
+ shlibpath_overrides_runpath=yes
+ ;;
+
+*nto* | *qnx*)
+ version_type=qnx
+ need_lib_prefix=no
+ need_version=no
+ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+ soname_spec='${libname}${release}${shared_ext}$major'
+ shlibpath_var=LD_LIBRARY_PATH
+ shlibpath_overrides_runpath=no
+ hardcode_into_libs=yes
+ dynamic_linker='ldqnx.so'
+ ;;
+
+openbsd*)
+ version_type=sunos
+ sys_lib_dlsearch_path_spec="/usr/lib"
+ need_lib_prefix=no
+ # Some older versions of OpenBSD (3.3 at least) *do* need versioned libs.
+ case $host_os in
+ openbsd3.3 | openbsd3.3.*) need_version=yes ;;
+ *) need_version=no ;;
+ esac
+ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix'
+ finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir'
+ shlibpath_var=LD_LIBRARY_PATH
+ if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then
+ case $host_os in
+ openbsd2.[[89]] | openbsd2.[[89]].*)
+ shlibpath_overrides_runpath=no
+ ;;
+ *)
+ shlibpath_overrides_runpath=yes
+ ;;
+ esac
+ else
+ shlibpath_overrides_runpath=yes
+ fi
+ ;;
+
+os2*)
+ libname_spec='$name'
+ shrext_cmds=".dll"
+ need_lib_prefix=no
+ library_names_spec='$libname${shared_ext} $libname.a'
+ dynamic_linker='OS/2 ld.exe'
+ shlibpath_var=LIBPATH
+ ;;
+
+osf3* | osf4* | osf5*)
+ version_type=osf
+ need_lib_prefix=no
+ need_version=no
+ soname_spec='${libname}${release}${shared_ext}$major'
+ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+ shlibpath_var=LD_LIBRARY_PATH
+ sys_lib_search_path_spec="/usr/shlib /usr/ccs/lib /usr/lib/cmplrs/cc /usr/lib /usr/local/lib /var/shlib"
+ sys_lib_dlsearch_path_spec="$sys_lib_search_path_spec"
+ ;;
+
+rdos*)
+ dynamic_linker=no
+ ;;
+
+solaris*)
+ version_type=linux
+ need_lib_prefix=no
+ need_version=no
+ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+ soname_spec='${libname}${release}${shared_ext}$major'
+ shlibpath_var=LD_LIBRARY_PATH
+ shlibpath_overrides_runpath=yes
+ hardcode_into_libs=yes
+ # ldd complains unless libraries are executable
+ postinstall_cmds='chmod +x $lib'
+ ;;
+
+sunos4*)
+ version_type=sunos
+ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix'
+ finish_cmds='PATH="\$PATH:/usr/etc" ldconfig $libdir'
+ shlibpath_var=LD_LIBRARY_PATH
+ shlibpath_overrides_runpath=yes
+ if test "$with_gnu_ld" = yes; then
+ need_lib_prefix=no
+ fi
+ need_version=yes
+ ;;
+
+sysv4 | sysv4.3*)
+ version_type=linux
+ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+ soname_spec='${libname}${release}${shared_ext}$major'
+ shlibpath_var=LD_LIBRARY_PATH
+ case $host_vendor in
+ sni)
+ shlibpath_overrides_runpath=no
+ need_lib_prefix=no
+ runpath_var=LD_RUN_PATH
+ ;;
+ siemens)
+ need_lib_prefix=no
+ ;;
+ motorola)
+ need_lib_prefix=no
+ need_version=no
+ shlibpath_overrides_runpath=no
+ sys_lib_search_path_spec='/lib /usr/lib /usr/ccs/lib'
+ ;;
+ esac
+ ;;
+
+sysv4*MP*)
+ if test -d /usr/nec ;then
+ version_type=linux
+ library_names_spec='$libname${shared_ext}.$versuffix $libname${shared_ext}.$major $libname${shared_ext}'
+ soname_spec='$libname${shared_ext}.$major'
+ shlibpath_var=LD_LIBRARY_PATH
+ fi
+ ;;
+
+sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX* | sysv4*uw2*)
+ version_type=freebsd-elf
+ need_lib_prefix=no
+ need_version=no
+ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext} $libname${shared_ext}'
+ soname_spec='${libname}${release}${shared_ext}$major'
+ shlibpath_var=LD_LIBRARY_PATH
+ shlibpath_overrides_runpath=yes
+ hardcode_into_libs=yes
+ if test "$with_gnu_ld" = yes; then
+ sys_lib_search_path_spec='/usr/local/lib /usr/gnu/lib /usr/ccs/lib /usr/lib /lib'
+ else
+ sys_lib_search_path_spec='/usr/ccs/lib /usr/lib'
+ case $host_os in
+ sco3.2v5*)
+ sys_lib_search_path_spec="$sys_lib_search_path_spec /lib"
+ ;;
+ esac
+ fi
+ sys_lib_dlsearch_path_spec='/usr/lib'
+ ;;
+
+tpf*)
+ # TPF is a cross-target only. Preferred cross-host = GNU/Linux.
+ version_type=linux
+ need_lib_prefix=no
+ need_version=no
+ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+ shlibpath_var=LD_LIBRARY_PATH
+ shlibpath_overrides_runpath=no
+ hardcode_into_libs=yes
+ ;;
+
+uts4*)
+ version_type=linux
+ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+ soname_spec='${libname}${release}${shared_ext}$major'
+ shlibpath_var=LD_LIBRARY_PATH
+ ;;
+
+*)
+ dynamic_linker=no
+ ;;
+esac
+AC_MSG_RESULT([$dynamic_linker])
+test "$dynamic_linker" = no && can_build_shared=no
+
+variables_saved_for_relink="PATH $shlibpath_var $runpath_var"
+if test "$GCC" = yes; then
+ variables_saved_for_relink="$variables_saved_for_relink GCC_EXEC_PREFIX COMPILER_PATH LIBRARY_PATH"
+fi
+
+if test "${lt_cv_sys_lib_search_path_spec+set}" = set; then
+ sys_lib_search_path_spec="$lt_cv_sys_lib_search_path_spec"
+fi
+if test "${lt_cv_sys_lib_dlsearch_path_spec+set}" = set; then
+ sys_lib_dlsearch_path_spec="$lt_cv_sys_lib_dlsearch_path_spec"
+fi
+
+_LT_DECL([], [variables_saved_for_relink], [1],
+ [Variables whose values should be saved in libtool wrapper scripts and
+ restored at link time])
+_LT_DECL([], [need_lib_prefix], [0],
+ [Do we need the "lib" prefix for modules?])
+_LT_DECL([], [need_version], [0], [Do we need a version for libraries?])
+_LT_DECL([], [version_type], [0], [Library versioning type])
+_LT_DECL([], [runpath_var], [0], [Shared library runtime path variable])
+_LT_DECL([], [shlibpath_var], [0],[Shared library path variable])
+_LT_DECL([], [shlibpath_overrides_runpath], [0],
+ [Is shlibpath searched before the hard-coded library search path?])
+_LT_DECL([], [libname_spec], [1], [Format of library name prefix])
+_LT_DECL([], [library_names_spec], [1],
+ [[List of archive names. First name is the real one, the rest are links.
+ The last name is the one that the linker finds with -lNAME]])
+_LT_DECL([], [soname_spec], [1],
+ [[The coded name of the library, if different from the real name]])
+_LT_DECL([], [postinstall_cmds], [2],
+ [Command to use after installation of a shared archive])
+_LT_DECL([], [postuninstall_cmds], [2],
+ [Command to use after uninstallation of a shared archive])
+_LT_DECL([], [finish_cmds], [2],
+ [Commands used to finish a libtool library installation in a directory])
+_LT_DECL([], [finish_eval], [1],
+ [[As "finish_cmds", except a single script fragment to be evaled but
+ not shown]])
+_LT_DECL([], [hardcode_into_libs], [0],
+ [Whether we should hardcode library paths into libraries])
+_LT_DECL([], [sys_lib_search_path_spec], [2],
+ [Compile-time system search path for libraries])
+_LT_DECL([], [sys_lib_dlsearch_path_spec], [2],
+ [Run-time system search path for libraries])
+])# _LT_SYS_DYNAMIC_LINKER
+
+
+# _LT_PATH_TOOL_PREFIX(TOOL)
+# --------------------------
+# find a file program which can recognize shared library
+AC_DEFUN([_LT_PATH_TOOL_PREFIX],
+[m4_require([_LT_DECL_EGREP])dnl
+AC_MSG_CHECKING([for $1])
+AC_CACHE_VAL(lt_cv_path_MAGIC_CMD,
+[case $MAGIC_CMD in
+[[\\/*] | ?:[\\/]*])
+ lt_cv_path_MAGIC_CMD="$MAGIC_CMD" # Let the user override the test with a path.
+ ;;
+*)
+ lt_save_MAGIC_CMD="$MAGIC_CMD"
+ lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR
+dnl $ac_dummy forces splitting on constant user-supplied paths.
+dnl POSIX.2 word splitting is done only on the output of word expansions,
+dnl not every word. This closes a longstanding sh security hole.
+ ac_dummy="m4_if([$2], , $PATH, [$2])"
+ for ac_dir in $ac_dummy; do
+ IFS="$lt_save_ifs"
+ test -z "$ac_dir" && ac_dir=.
+ if test -f $ac_dir/$1; then
+ lt_cv_path_MAGIC_CMD="$ac_dir/$1"
+ if test -n "$file_magic_test_file"; then
+ case $deplibs_check_method in
+ "file_magic "*)
+ file_magic_regex=`expr "$deplibs_check_method" : "file_magic \(.*\)"`
+ MAGIC_CMD="$lt_cv_path_MAGIC_CMD"
+ if eval $file_magic_cmd \$file_magic_test_file 2> /dev/null |
+ $EGREP "$file_magic_regex" > /dev/null; then
+ :
+ else
+ cat <<_LT_EOF 1>&2
+
+*** Warning: the command libtool uses to detect shared libraries,
+*** $file_magic_cmd, produces output that libtool cannot recognize.
+*** The result is that libtool may fail to recognize shared libraries
+*** as such. This will affect the creation of libtool libraries that
+*** depend on shared libraries, but programs linked with such libtool
+*** libraries will work regardless of this problem. Nevertheless, you
+*** may want to report the problem to your system manager and/or to
+*** bug-libtool@gnu.org
+
+_LT_EOF
+ fi ;;
+ esac
+ fi
+ break
+ fi
+ done
+ IFS="$lt_save_ifs"
+ MAGIC_CMD="$lt_save_MAGIC_CMD"
+ ;;
+esac])
+MAGIC_CMD="$lt_cv_path_MAGIC_CMD"
+if test -n "$MAGIC_CMD"; then
+ AC_MSG_RESULT($MAGIC_CMD)
+else
+ AC_MSG_RESULT(no)
+fi
+_LT_DECL([], [MAGIC_CMD], [0],
+ [Used to examine libraries when file_magic_cmd begins with "file"])dnl
+])# _LT_PATH_TOOL_PREFIX
+
+# Old name:
+AU_ALIAS([AC_PATH_TOOL_PREFIX], [_LT_PATH_TOOL_PREFIX])
+dnl aclocal-1.4 backwards compatibility:
+dnl AC_DEFUN([AC_PATH_TOOL_PREFIX], [])
+
+
+# _LT_PATH_MAGIC
+# --------------
+# find a file program which can recognize a shared library
+m4_defun([_LT_PATH_MAGIC],
+[_LT_PATH_TOOL_PREFIX(${ac_tool_prefix}file, /usr/bin$PATH_SEPARATOR$PATH)
+if test -z "$lt_cv_path_MAGIC_CMD"; then
+ if test -n "$ac_tool_prefix"; then
+ _LT_PATH_TOOL_PREFIX(file, /usr/bin$PATH_SEPARATOR$PATH)
+ else
+ MAGIC_CMD=:
+ fi
+fi
+])# _LT_PATH_MAGIC
+
+
+# LT_PATH_LD
+# ----------
+# find the pathname to the GNU or non-GNU linker
+AC_DEFUN([LT_PATH_LD],
+[AC_REQUIRE([AC_PROG_CC])dnl
+AC_REQUIRE([AC_CANONICAL_HOST])dnl
+AC_REQUIRE([AC_CANONICAL_BUILD])dnl
+m4_require([_LT_DECL_SED])dnl
+m4_require([_LT_DECL_EGREP])dnl
+
+AC_ARG_WITH([gnu-ld],
+ [AS_HELP_STRING([--with-gnu-ld],
+ [assume the C compiler uses GNU ld @<:@default=no@:>@])],
+ [test "$withval" = no || with_gnu_ld=yes],
+ [with_gnu_ld=no])dnl
+
+ac_prog=ld
+if test "$GCC" = yes; then
+ # Check if gcc -print-prog-name=ld gives a path.
+ AC_MSG_CHECKING([for ld used by $CC])
+ case $host in
+ *-*-mingw*)
+ # gcc leaves a trailing carriage return which upsets mingw
+ ac_prog=`($CC -print-prog-name=ld) 2>&5 | tr -d '\015'` ;;
+ *)
+ ac_prog=`($CC -print-prog-name=ld) 2>&5` ;;
+ esac
+ case $ac_prog in
+ # Accept absolute paths.
+ [[\\/]]* | ?:[[\\/]]*)
+ re_direlt='/[[^/]][[^/]]*/\.\./'
+ # Canonicalize the pathname of ld
+ ac_prog=`$ECHO "$ac_prog"| $SED 's%\\\\%/%g'`
+ while $ECHO "$ac_prog" | $GREP "$re_direlt" > /dev/null 2>&1; do
+ ac_prog=`$ECHO $ac_prog| $SED "s%$re_direlt%/%"`
+ done
+ test -z "$LD" && LD="$ac_prog"
+ ;;
+ "")
+ # If it fails, then pretend we aren't using GCC.
+ ac_prog=ld
+ ;;
+ *)
+ # If it is relative, then search for the first ld in PATH.
+ with_gnu_ld=unknown
+ ;;
+ esac
+elif test "$with_gnu_ld" = yes; then
+ AC_MSG_CHECKING([for GNU ld])
+else
+ AC_MSG_CHECKING([for non-GNU ld])
+fi
+AC_CACHE_VAL(lt_cv_path_LD,
+[if test -z "$LD"; then
+ lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR
+ for ac_dir in $PATH; do
+ IFS="$lt_save_ifs"
+ test -z "$ac_dir" && ac_dir=.
+ if test -f "$ac_dir/$ac_prog" || test -f "$ac_dir/$ac_prog$ac_exeext"; then
+ lt_cv_path_LD="$ac_dir/$ac_prog"
+ # Check to see if the program is GNU ld. I'd rather use --version,
+ # but apparently some variants of GNU ld only accept -v.
+ # Break only if it was the GNU/non-GNU ld that we prefer.
+ case `"$lt_cv_path_LD" -v 2>&1 </dev/null` in
+ *GNU* | *'with BFD'*)
+ test "$with_gnu_ld" != no && break
+ ;;
+ *)
+ test "$with_gnu_ld" != yes && break
+ ;;
+ esac
+ fi
+ done
+ IFS="$lt_save_ifs"
+else
+ lt_cv_path_LD="$LD" # Let the user override the test with a path.
+fi])
+LD="$lt_cv_path_LD"
+if test -n "$LD"; then
+ AC_MSG_RESULT($LD)
+else
+ AC_MSG_RESULT(no)
+fi
+test -z "$LD" && AC_MSG_ERROR([no acceptable ld found in \$PATH])
+_LT_PATH_LD_GNU
+AC_SUBST([LD])
+
+_LT_TAGDECL([], [LD], [1], [The linker used to build libraries])
+])# LT_PATH_LD
+
+# Old names:
+AU_ALIAS([AM_PROG_LD], [LT_PATH_LD])
+AU_ALIAS([AC_PROG_LD], [LT_PATH_LD])
+dnl aclocal-1.4 backwards compatibility:
+dnl AC_DEFUN([AM_PROG_LD], [])
+dnl AC_DEFUN([AC_PROG_LD], [])
+
+
+# _LT_PATH_LD_GNU
+#- --------------
+m4_defun([_LT_PATH_LD_GNU],
+[AC_CACHE_CHECK([if the linker ($LD) is GNU ld], lt_cv_prog_gnu_ld,
+[# I'd rather use --version here, but apparently some GNU lds only accept -v.
+case `$LD -v 2>&1 </dev/null` in
+*GNU* | *'with BFD'*)
+ lt_cv_prog_gnu_ld=yes
+ ;;
+*)
+ lt_cv_prog_gnu_ld=no
+ ;;
+esac])
+with_gnu_ld=$lt_cv_prog_gnu_ld
+])# _LT_PATH_LD_GNU
+
+
+# _LT_CMD_RELOAD
+# --------------
+# find reload flag for linker
+# -- PORTME Some linkers may need a different reload flag.
+m4_defun([_LT_CMD_RELOAD],
+[AC_CACHE_CHECK([for $LD option to reload object files],
+ lt_cv_ld_reload_flag,
+ [lt_cv_ld_reload_flag='-r'])
+reload_flag=$lt_cv_ld_reload_flag
+case $reload_flag in
+"" | " "*) ;;
+*) reload_flag=" $reload_flag" ;;
+esac
+reload_cmds='$LD$reload_flag -o $output$reload_objs'
+case $host_os in
+ darwin*)
+ if test "$GCC" = yes; then
+ reload_cmds='$LTCC $LTCFLAGS -nostdlib ${wl}-r -o $output$reload_objs'
+ else
+ reload_cmds='$LD$reload_flag -o $output$reload_objs'
+ fi
+ ;;
+esac
+_LT_DECL([], [reload_flag], [1], [How to create reloadable object files])dnl
+_LT_DECL([], [reload_cmds], [2])dnl
+])# _LT_CMD_RELOAD
+
+
+# _LT_CHECK_MAGIC_METHOD
+# ----------------------
+# how to check for library dependencies
+# -- PORTME fill in with the dynamic library characteristics
+m4_defun([_LT_CHECK_MAGIC_METHOD],
+[m4_require([_LT_DECL_EGREP])
+m4_require([_LT_DECL_OBJDUMP])
+AC_CACHE_CHECK([how to recognize dependent libraries],
+lt_cv_deplibs_check_method,
+[lt_cv_file_magic_cmd='$MAGIC_CMD'
+lt_cv_file_magic_test_file=
+lt_cv_deplibs_check_method='unknown'
+# Need to set the preceding variable on all platforms that support
+# interlibrary dependencies.
+# 'none' -- dependencies not supported.
+# `unknown' -- same as none, but documents that we really don't know.
+# 'pass_all' -- all dependencies passed with no checks.
+# 'test_compile' -- check by making test program.
+# 'file_magic [[regex]]' -- check by looking for files in library path
+# which responds to the $file_magic_cmd with a given extended regex.
+# If you have `file' or equivalent on your system and you're not sure
+# whether `pass_all' will *always* work, you probably want this one.
+
+case $host_os in
+aix[[4-9]]*)
+ lt_cv_deplibs_check_method=pass_all
+ ;;
+
+beos*)
+ lt_cv_deplibs_check_method=pass_all
+ ;;
+
+bsdi[[45]]*)
+ lt_cv_deplibs_check_method='file_magic ELF [[0-9]][[0-9]]*-bit [[ML]]SB (shared object|dynamic lib)'
+ lt_cv_file_magic_cmd='/usr/bin/file -L'
+ lt_cv_file_magic_test_file=/shlib/libc.so
+ ;;
+
+cygwin*)
+ # func_win32_libid is a shell function defined in ltmain.sh
+ lt_cv_deplibs_check_method='file_magic ^x86 archive import|^x86 DLL'
+ lt_cv_file_magic_cmd='func_win32_libid'
+ ;;
+
+mingw* | pw32*)
+ # Base MSYS/MinGW do not provide the 'file' command needed by
+ # func_win32_libid shell function, so use a weaker test based on 'objdump',
+ # unless we find 'file', for example because we are cross-compiling.
+ if ( file / ) >/dev/null 2>&1; then
+ lt_cv_deplibs_check_method='file_magic ^x86 archive import|^x86 DLL'
+ lt_cv_file_magic_cmd='func_win32_libid'
+ else
+ lt_cv_deplibs_check_method='file_magic file format pei*-i386(.*architecture: i386)?'
+ lt_cv_file_magic_cmd='$OBJDUMP -f'
+ fi
+ ;;
+
+cegcc)
+ # use the weaker test based on 'objdump'. See mingw*.
+ lt_cv_deplibs_check_method='file_magic file format pe-arm-.*little(.*architecture: arm)?'
+ lt_cv_file_magic_cmd='$OBJDUMP -f'
+ ;;
+
+darwin* | rhapsody*)
+ lt_cv_deplibs_check_method=pass_all
+ ;;
+
+freebsd* | dragonfly*)
+ if echo __ELF__ | $CC -E - | $GREP __ELF__ > /dev/null; then
+ case $host_cpu in
+ i*86 )
+ # Not sure whether the presence of OpenBSD here was a mistake.
+ # Let's accept both of them until this is cleared up.
+ lt_cv_deplibs_check_method='file_magic (FreeBSD|OpenBSD|DragonFly)/i[[3-9]]86 (compact )?demand paged shared library'
+ lt_cv_file_magic_cmd=/usr/bin/file
+ lt_cv_file_magic_test_file=`echo /usr/lib/libc.so.*`
+ ;;
+ esac
+ else
+ lt_cv_deplibs_check_method=pass_all
+ fi
+ ;;
+
+gnu*)
+ lt_cv_deplibs_check_method=pass_all
+ ;;
+
+hpux10.20* | hpux11*)
+ lt_cv_file_magic_cmd=/usr/bin/file
+ case $host_cpu in
+ ia64*)
+ lt_cv_deplibs_check_method='file_magic (s[[0-9]][[0-9]][[0-9]]|ELF-[[0-9]][[0-9]]) shared object file - IA64'
+ lt_cv_file_magic_test_file=/usr/lib/hpux32/libc.so
+ ;;
+ hppa*64*)
+ [lt_cv_deplibs_check_method='file_magic (s[0-9][0-9][0-9]|ELF-[0-9][0-9]) shared object file - PA-RISC [0-9].[0-9]']
+ lt_cv_file_magic_test_file=/usr/lib/pa20_64/libc.sl
+ ;;
+ *)
+ lt_cv_deplibs_check_method='file_magic (s[[0-9]][[0-9]][[0-9]]|PA-RISC[[0-9]].[[0-9]]) shared library'
+ lt_cv_file_magic_test_file=/usr/lib/libc.sl
+ ;;
+ esac
+ ;;
+
+interix[[3-9]]*)
+ # PIC code is broken on Interix 3.x, that's why |\.a not |_pic\.a here
+ lt_cv_deplibs_check_method='match_pattern /lib[[^/]]+(\.so|\.a)$'
+ ;;
+
+irix5* | irix6* | nonstopux*)
+ case $LD in
+ *-32|*"-32 ") libmagic=32-bit;;
+ *-n32|*"-n32 ") libmagic=N32;;
+ *-64|*"-64 ") libmagic=64-bit;;
+ *) libmagic=never-match;;
+ esac
+ lt_cv_deplibs_check_method=pass_all
+ ;;
+
+# This must be Linux ELF.
+linux* | k*bsd*-gnu | kopensolaris*-gnu)
+ lt_cv_deplibs_check_method=pass_all
+ ;;
+
+netbsd* | netbsdelf*-gnu)
+ if echo __ELF__ | $CC -E - | $GREP __ELF__ > /dev/null; then
+ lt_cv_deplibs_check_method='match_pattern /lib[[^/]]+(\.so\.[[0-9]]+\.[[0-9]]+|_pic\.a)$'
+ else
+ lt_cv_deplibs_check_method='match_pattern /lib[[^/]]+(\.so|_pic\.a)$'
+ fi
+ ;;
+
+newos6*)
+ lt_cv_deplibs_check_method='file_magic ELF [[0-9]][[0-9]]*-bit [[ML]]SB (executable|dynamic lib)'
+ lt_cv_file_magic_cmd=/usr/bin/file
+ lt_cv_file_magic_test_file=/usr/lib/libnls.so
+ ;;
+
+*nto* | *qnx*)
+ lt_cv_deplibs_check_method=pass_all
+ ;;
+
+openbsd*)
+ if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then
+ lt_cv_deplibs_check_method='match_pattern /lib[[^/]]+(\.so\.[[0-9]]+\.[[0-9]]+|\.so|_pic\.a)$'
+ else
+ lt_cv_deplibs_check_method='match_pattern /lib[[^/]]+(\.so\.[[0-9]]+\.[[0-9]]+|_pic\.a)$'
+ fi
+ ;;
+
+osf3* | osf4* | osf5*)
+ lt_cv_deplibs_check_method=pass_all
+ ;;
+
+rdos*)
+ lt_cv_deplibs_check_method=pass_all
+ ;;
+
+solaris*)
+ lt_cv_deplibs_check_method=pass_all
+ ;;
+
+sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX* | sysv4*uw2*)
+ lt_cv_deplibs_check_method=pass_all
+ ;;
+
+sysv4 | sysv4.3*)
+ case $host_vendor in
+ motorola)
+ lt_cv_deplibs_check_method='file_magic ELF [[0-9]][[0-9]]*-bit [[ML]]SB (shared object|dynamic lib) M[[0-9]][[0-9]]* Version [[0-9]]'
+ lt_cv_file_magic_test_file=`echo /usr/lib/libc.so*`
+ ;;
+ ncr)
+ lt_cv_deplibs_check_method=pass_all
+ ;;
+ sequent)
+ lt_cv_file_magic_cmd='/bin/file'
+ lt_cv_deplibs_check_method='file_magic ELF [[0-9]][[0-9]]*-bit [[LM]]SB (shared object|dynamic lib )'
+ ;;
+ sni)
+ lt_cv_file_magic_cmd='/bin/file'
+ lt_cv_deplibs_check_method="file_magic ELF [[0-9]][[0-9]]*-bit [[LM]]SB dynamic lib"
+ lt_cv_file_magic_test_file=/lib/libc.so
+ ;;
+ siemens)
+ lt_cv_deplibs_check_method=pass_all
+ ;;
+ pc)
+ lt_cv_deplibs_check_method=pass_all
+ ;;
+ esac
+ ;;
+
+tpf*)
+ lt_cv_deplibs_check_method=pass_all
+ ;;
+esac
+])
+file_magic_cmd=$lt_cv_file_magic_cmd
+deplibs_check_method=$lt_cv_deplibs_check_method
+test -z "$deplibs_check_method" && deplibs_check_method=unknown
+
+_LT_DECL([], [deplibs_check_method], [1],
+ [Method to check whether dependent libraries are shared objects])
+_LT_DECL([], [file_magic_cmd], [1],
+ [Command to use when deplibs_check_method == "file_magic"])
+])# _LT_CHECK_MAGIC_METHOD
+
+
+# LT_PATH_NM
+# ----------
+# find the pathname to a BSD- or MS-compatible name lister
+AC_DEFUN([LT_PATH_NM],
+[AC_REQUIRE([AC_PROG_CC])dnl
+AC_CACHE_CHECK([for BSD- or MS-compatible name lister (nm)], lt_cv_path_NM,
+[if test -n "$NM"; then
+ # Let the user override the test.
+ lt_cv_path_NM="$NM"
+else
+ lt_nm_to_check="${ac_tool_prefix}nm"
+ if test -n "$ac_tool_prefix" && test "$build" = "$host"; then
+ lt_nm_to_check="$lt_nm_to_check nm"
+ fi
+ for lt_tmp_nm in $lt_nm_to_check; do
+ lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR
+ for ac_dir in $PATH /usr/ccs/bin/elf /usr/ccs/bin /usr/ucb /bin; do
+ IFS="$lt_save_ifs"
+ test -z "$ac_dir" && ac_dir=.
+ tmp_nm="$ac_dir/$lt_tmp_nm"
+ if test -f "$tmp_nm" || test -f "$tmp_nm$ac_exeext" ; then
+ # Check to see if the nm accepts a BSD-compat flag.
+ # Adding the `sed 1q' prevents false positives on HP-UX, which says:
+ # nm: unknown option "B" ignored
+ # Tru64's nm complains that /dev/null is an invalid object file
+ case `"$tmp_nm" -B /dev/null 2>&1 | sed '1q'` in
+ */dev/null* | *'Invalid file or object type'*)
+ lt_cv_path_NM="$tmp_nm -B"
+ break
+ ;;
+ *)
+ case `"$tmp_nm" -p /dev/null 2>&1 | sed '1q'` in
+ */dev/null*)
+ lt_cv_path_NM="$tmp_nm -p"
+ break
+ ;;
+ *)
+ lt_cv_path_NM=${lt_cv_path_NM="$tmp_nm"} # keep the first match, but
+ continue # so that we can try to find one that supports BSD flags
+ ;;
+ esac
+ ;;
+ esac
+ fi
+ done
+ IFS="$lt_save_ifs"
+ done
+ : ${lt_cv_path_NM=no}
+fi])
+if test "$lt_cv_path_NM" != "no"; then
+ NM="$lt_cv_path_NM"
+else
+ # Didn't find any BSD compatible name lister, look for dumpbin.
+ AC_CHECK_TOOLS(DUMPBIN, ["dumpbin -symbols" "link -dump -symbols"], :)
+ AC_SUBST([DUMPBIN])
+ if test "$DUMPBIN" != ":"; then
+ NM="$DUMPBIN"
+ fi
+fi
+test -z "$NM" && NM=nm
+AC_SUBST([NM])
+_LT_DECL([], [NM], [1], [A BSD- or MS-compatible name lister])dnl
+
+AC_CACHE_CHECK([the name lister ($NM) interface], [lt_cv_nm_interface],
+ [lt_cv_nm_interface="BSD nm"
+ echo "int some_variable = 0;" > conftest.$ac_ext
+ (eval echo "\"\$as_me:__oline__: $ac_compile\"" >&AS_MESSAGE_LOG_FD)
+ (eval "$ac_compile" 2>conftest.err)
+ cat conftest.err >&AS_MESSAGE_LOG_FD
+ (eval echo "\"\$as_me:__oline__: $NM \\\"conftest.$ac_objext\\\"\"" >&AS_MESSAGE_LOG_FD)
+ (eval "$NM \"conftest.$ac_objext\"" 2>conftest.err > conftest.out)
+ cat conftest.err >&AS_MESSAGE_LOG_FD
+ (eval echo "\"\$as_me:__oline__: output\"" >&AS_MESSAGE_LOG_FD)
+ cat conftest.out >&AS_MESSAGE_LOG_FD
+ if $GREP 'External.*some_variable' conftest.out > /dev/null; then
+ lt_cv_nm_interface="MS dumpbin"
+ fi
+ rm -f conftest*])
+])# LT_PATH_NM
+
+# Old names:
+AU_ALIAS([AM_PROG_NM], [LT_PATH_NM])
+AU_ALIAS([AC_PROG_NM], [LT_PATH_NM])
+dnl aclocal-1.4 backwards compatibility:
+dnl AC_DEFUN([AM_PROG_NM], [])
+dnl AC_DEFUN([AC_PROG_NM], [])
+
+
+# LT_LIB_M
+# --------
+# check for math library
+AC_DEFUN([LT_LIB_M],
+[AC_REQUIRE([AC_CANONICAL_HOST])dnl
+LIBM=
+case $host in
+*-*-beos* | *-*-cygwin* | *-*-pw32* | *-*-darwin*)
+ # These system don't have libm, or don't need it
+ ;;
+*-ncr-sysv4.3*)
+ AC_CHECK_LIB(mw, _mwvalidcheckl, LIBM="-lmw")
+ AC_CHECK_LIB(m, cos, LIBM="$LIBM -lm")
+ ;;
+*)
+ AC_CHECK_LIB(m, cos, LIBM="-lm")
+ ;;
+esac
+AC_SUBST([LIBM])
+])# LT_LIB_M
+
+# Old name:
+AU_ALIAS([AC_CHECK_LIBM], [LT_LIB_M])
+dnl aclocal-1.4 backwards compatibility:
+dnl AC_DEFUN([AC_CHECK_LIBM], [])
+
+
+# _LT_COMPILER_NO_RTTI([TAGNAME])
+# -------------------------------
+m4_defun([_LT_COMPILER_NO_RTTI],
+[m4_require([_LT_TAG_COMPILER])dnl
+
+_LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)=
+
+if test "$GCC" = yes; then
+ _LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)=' -fno-builtin'
+
+ _LT_COMPILER_OPTION([if $compiler supports -fno-rtti -fno-exceptions],
+ lt_cv_prog_compiler_rtti_exceptions,
+ [-fno-rtti -fno-exceptions], [],
+ [_LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)="$_LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1) -fno-rtti -fno-exceptions"])
+fi
+_LT_TAGDECL([no_builtin_flag], [lt_prog_compiler_no_builtin_flag], [1],
+ [Compiler flag to turn off builtin functions])
+])# _LT_COMPILER_NO_RTTI
+
+
+# _LT_CMD_GLOBAL_SYMBOLS
+# ----------------------
+m4_defun([_LT_CMD_GLOBAL_SYMBOLS],
+[AC_REQUIRE([AC_CANONICAL_HOST])dnl
+AC_REQUIRE([AC_PROG_CC])dnl
+AC_REQUIRE([LT_PATH_NM])dnl
+AC_REQUIRE([LT_PATH_LD])dnl
+m4_require([_LT_DECL_SED])dnl
+m4_require([_LT_DECL_EGREP])dnl
+m4_require([_LT_TAG_COMPILER])dnl
+
+# Check for command to grab the raw symbol name followed by C symbol from nm.
+AC_MSG_CHECKING([command to parse $NM output from $compiler object])
+AC_CACHE_VAL([lt_cv_sys_global_symbol_pipe],
+[
+# These are sane defaults that work on at least a few old systems.
+# [They come from Ultrix. What could be older than Ultrix?!! ;)]
+
+# Character class describing NM global symbol codes.
+symcode='[[BCDEGRST]]'
+
+# Regexp to match symbols that can be accessed directly from C.
+sympat='\([[_A-Za-z]][[_A-Za-z0-9]]*\)'
+
+# Define system-specific variables.
+case $host_os in
+aix*)
+ symcode='[[BCDT]]'
+ ;;
+cygwin* | mingw* | pw32* | cegcc*)
+ symcode='[[ABCDGISTW]]'
+ ;;
+hpux*)
+ if test "$host_cpu" = ia64; then
+ symcode='[[ABCDEGRST]]'
+ fi
+ ;;
+irix* | nonstopux*)
+ symcode='[[BCDEGRST]]'
+ ;;
+osf*)
+ symcode='[[BCDEGQRST]]'
+ ;;
+solaris*)
+ symcode='[[BDRT]]'
+ ;;
+sco3.2v5*)
+ symcode='[[DT]]'
+ ;;
+sysv4.2uw2*)
+ symcode='[[DT]]'
+ ;;
+sysv5* | sco5v6* | unixware* | OpenUNIX*)
+ symcode='[[ABDT]]'
+ ;;
+sysv4)
+ symcode='[[DFNSTU]]'
+ ;;
+esac
+
+# If we're using GNU nm, then use its standard symbol codes.
+case `$NM -V 2>&1` in
+*GNU* | *'with BFD'*)
+ symcode='[[ABCDGIRSTW]]' ;;
+esac
+
+# Transform an extracted symbol line into a proper C declaration.
+# Some systems (esp. on ia64) link data and code symbols differently,
+# so use this general approach.
+lt_cv_sys_global_symbol_to_cdecl="sed -n -e 's/^T .* \(.*\)$/extern int \1();/p' -e 's/^$symcode* .* \(.*\)$/extern char \1;/p'"
+
+# Transform an extracted symbol line into symbol name and symbol address
+lt_cv_sys_global_symbol_to_c_name_address="sed -n -e 's/^: \([[^ ]]*\) $/ {\\\"\1\\\", (void *) 0},/p' -e 's/^$symcode* \([[^ ]]*\) \([[^ ]]*\)$/ {\"\2\", (void *) \&\2},/p'"
+lt_cv_sys_global_symbol_to_c_name_address_lib_prefix="sed -n -e 's/^: \([[^ ]]*\) $/ {\\\"\1\\\", (void *) 0},/p' -e 's/^$symcode* \([[^ ]]*\) \(lib[[^ ]]*\)$/ {\"\2\", (void *) \&\2},/p' -e 's/^$symcode* \([[^ ]]*\) \([[^ ]]*\)$/ {\"lib\2\", (void *) \&\2},/p'"
+
+# Handle CRLF in mingw tool chain
+opt_cr=
+case $build_os in
+mingw*)
+ opt_cr=`$ECHO 'x\{0,1\}' | tr x '\015'` # option cr in regexp
+ ;;
+esac
+
+# Try without a prefix underscore, then with it.
+for ac_symprfx in "" "_"; do
+
+ # Transform symcode, sympat, and symprfx into a raw symbol and a C symbol.
+ symxfrm="\\1 $ac_symprfx\\2 \\2"
+
+ # Write the raw and C identifiers.
+ if test "$lt_cv_nm_interface" = "MS dumpbin"; then
+ # Fake it for dumpbin and say T for any non-static function
+ # and D for any global variable.
+ # Also find C++ and __fastcall symbols from MSVC++,
+ # which start with @ or ?.
+ lt_cv_sys_global_symbol_pipe="$AWK ['"\
+" {last_section=section; section=\$ 3};"\
+" /Section length .*#relocs.*(pick any)/{hide[last_section]=1};"\
+" \$ 0!~/External *\|/{next};"\
+" / 0+ UNDEF /{next}; / UNDEF \([^|]\)*()/{next};"\
+" {if(hide[section]) next};"\
+" {f=0}; \$ 0~/\(\).*\|/{f=1}; {printf f ? \"T \" : \"D \"};"\
+" {split(\$ 0, a, /\||\r/); split(a[2], s)};"\
+" s[1]~/^[@?]/{print s[1], s[1]; next};"\
+" s[1]~prfx {split(s[1],t,\"@\"); print t[1], substr(t[1],length(prfx))}"\
+" ' prfx=^$ac_symprfx]"
+ else
+ lt_cv_sys_global_symbol_pipe="sed -n -e 's/^.*[[ ]]\($symcode$symcode*\)[[ ]][[ ]]*$ac_symprfx$sympat$opt_cr$/$symxfrm/p'"
+ fi
+
+ # Check to see that the pipe works correctly.
+ pipe_works=no
+
+ rm -f conftest*
+ cat > conftest.$ac_ext <<_LT_EOF
+#ifdef __cplusplus
+extern "C" {
+#endif
+char nm_test_var;
+void nm_test_func(void);
+void nm_test_func(void){}
+#ifdef __cplusplus
+}
+#endif
+int main(){nm_test_var='a';nm_test_func();return(0);}
+_LT_EOF
+
+ if AC_TRY_EVAL(ac_compile); then
+ # Now try to grab the symbols.
+ nlist=conftest.nm
+ if AC_TRY_EVAL(NM conftest.$ac_objext \| $lt_cv_sys_global_symbol_pipe \> $nlist) && test -s "$nlist"; then
+ # Try sorting and uniquifying the output.
+ if sort "$nlist" | uniq > "$nlist"T; then
+ mv -f "$nlist"T "$nlist"
+ else
+ rm -f "$nlist"T
+ fi
+
+ # Make sure that we snagged all the symbols we need.
+ if $GREP ' nm_test_var$' "$nlist" >/dev/null; then
+ if $GREP ' nm_test_func$' "$nlist" >/dev/null; then
+ cat <<_LT_EOF > conftest.$ac_ext
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+_LT_EOF
+ # Now generate the symbol file.
+ eval "$lt_cv_sys_global_symbol_to_cdecl"' < "$nlist" | $GREP -v main >> conftest.$ac_ext'
+
+ cat <<_LT_EOF >> conftest.$ac_ext
+
+/* The mapping between symbol names and symbols. */
+const struct {
+ const char *name;
+ void *address;
+}
+lt__PROGRAM__LTX_preloaded_symbols[[]] =
+{
+ { "@PROGRAM@", (void *) 0 },
+_LT_EOF
+ $SED "s/^$symcode$symcode* \(.*\) \(.*\)$/ {\"\2\", (void *) \&\2},/" < "$nlist" | $GREP -v main >> conftest.$ac_ext
+ cat <<\_LT_EOF >> conftest.$ac_ext
+ {0, (void *) 0}
+};
+
+/* This works around a problem in FreeBSD linker */
+#ifdef FREEBSD_WORKAROUND
+static const void *lt_preloaded_setup() {
+ return lt__PROGRAM__LTX_preloaded_symbols;
+}
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+_LT_EOF
+ # Now try linking the two files.
+ mv conftest.$ac_objext conftstm.$ac_objext
+ lt_save_LIBS="$LIBS"
+ lt_save_CFLAGS="$CFLAGS"
+ LIBS="conftstm.$ac_objext"
+ CFLAGS="$CFLAGS$_LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)"
+ if AC_TRY_EVAL(ac_link) && test -s conftest${ac_exeext}; then
+ pipe_works=yes
+ fi
+ LIBS="$lt_save_LIBS"
+ CFLAGS="$lt_save_CFLAGS"
+ else
+ echo "cannot find nm_test_func in $nlist" >&AS_MESSAGE_LOG_FD
+ fi
+ else
+ echo "cannot find nm_test_var in $nlist" >&AS_MESSAGE_LOG_FD
+ fi
+ else
+ echo "cannot run $lt_cv_sys_global_symbol_pipe" >&AS_MESSAGE_LOG_FD
+ fi
+ else
+ echo "$progname: failed program was:" >&AS_MESSAGE_LOG_FD
+ cat conftest.$ac_ext >&5
+ fi
+ rm -rf conftest* conftst*
+
+ # Do not use the global_symbol_pipe unless it works.
+ if test "$pipe_works" = yes; then
+ break
+ else
+ lt_cv_sys_global_symbol_pipe=
+ fi
+done
+])
+if test -z "$lt_cv_sys_global_symbol_pipe"; then
+ lt_cv_sys_global_symbol_to_cdecl=
+fi
+if test -z "$lt_cv_sys_global_symbol_pipe$lt_cv_sys_global_symbol_to_cdecl"; then
+ AC_MSG_RESULT(failed)
+else
+ AC_MSG_RESULT(ok)
+fi
+
+_LT_DECL([global_symbol_pipe], [lt_cv_sys_global_symbol_pipe], [1],
+ [Take the output of nm and produce a listing of raw symbols and C names])
+_LT_DECL([global_symbol_to_cdecl], [lt_cv_sys_global_symbol_to_cdecl], [1],
+ [Transform the output of nm in a proper C declaration])
+_LT_DECL([global_symbol_to_c_name_address],
+ [lt_cv_sys_global_symbol_to_c_name_address], [1],
+ [Transform the output of nm in a C name address pair])
+_LT_DECL([global_symbol_to_c_name_address_lib_prefix],
+ [lt_cv_sys_global_symbol_to_c_name_address_lib_prefix], [1],
+ [Transform the output of nm in a C name address pair when lib prefix is needed])
+]) # _LT_CMD_GLOBAL_SYMBOLS
+
+
+# _LT_COMPILER_PIC([TAGNAME])
+# ---------------------------
+m4_defun([_LT_COMPILER_PIC],
+[m4_require([_LT_TAG_COMPILER])dnl
+_LT_TAGVAR(lt_prog_compiler_wl, $1)=
+_LT_TAGVAR(lt_prog_compiler_pic, $1)=
+_LT_TAGVAR(lt_prog_compiler_static, $1)=
+
+AC_MSG_CHECKING([for $compiler option to produce PIC])
+m4_if([$1], [CXX], [
+ # C++ specific cases for pic, static, wl, etc.
+ if test "$GXX" = yes; then
+ _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+ _LT_TAGVAR(lt_prog_compiler_static, $1)='-static'
+
+ case $host_os in
+ aix*)
+ # All AIX code is PIC.
+ if test "$host_cpu" = ia64; then
+ # AIX 5 now supports IA64 processor
+ _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
+ fi
+ ;;
+
+ amigaos*)
+ case $host_cpu in
+ powerpc)
+ # see comment about AmigaOS4 .so support
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC'
+ ;;
+ m68k)
+ # FIXME: we need at least 68020 code to build shared libraries, but
+ # adding the `-m68020' flag to GCC prevents building anything better,
+ # like `-m68040'.
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-m68020 -resident32 -malways-restore-a4'
+ ;;
+ esac
+ ;;
+
+ beos* | irix5* | irix6* | nonstopux* | osf3* | osf4* | osf5*)
+ # PIC is the default for these OSes.
+ ;;
+ mingw* | cygwin* | os2* | pw32* | cegcc*)
+ # This hack is so that the source file can tell whether it is being
+ # built for inclusion in a dll (and should export symbols for example).
+ # Although the cygwin gcc ignores -fPIC, still need this for old-style
+ # (--disable-auto-import) libraries
+ m4_if([$1], [GCJ], [],
+ [_LT_TAGVAR(lt_prog_compiler_pic, $1)='-DDLL_EXPORT'])
+ ;;
+ darwin* | rhapsody*)
+ # PIC is the default on this platform
+ # Common symbols not allowed in MH_DYLIB files
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fno-common'
+ ;;
+ *djgpp*)
+ # DJGPP does not support shared libraries at all
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)=
+ ;;
+ interix[[3-9]]*)
+ # Interix 3.x gcc -fpic/-fPIC options generate broken code.
+ # Instead, we relocate shared libraries at runtime.
+ ;;
+ sysv4*MP*)
+ if test -d /usr/nec; then
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)=-Kconform_pic
+ fi
+ ;;
+ hpux*)
+ # PIC is the default for 64-bit PA HP-UX, but not for 32-bit
+ # PA HP-UX. On IA64 HP-UX, PIC is the default but the pic flag
+ # sets the default TLS model and affects inlining.
+ case $host_cpu in
+ hppa*64*)
+ ;;
+ *)
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC'
+ ;;
+ esac
+ ;;
+ *qnx* | *nto*)
+ # QNX uses GNU C++, but need to define -shared option too, otherwise
+ # it will coredump.
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC -shared'
+ ;;
+ *)
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC'
+ ;;
+ esac
+ else
+ case $host_os in
+ aix[[4-9]]*)
+ # All AIX code is PIC.
+ if test "$host_cpu" = ia64; then
+ # AIX 5 now supports IA64 processor
+ _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
+ else
+ _LT_TAGVAR(lt_prog_compiler_static, $1)='-bnso -bI:/lib/syscalls.exp'
+ fi
+ ;;
+ chorus*)
+ case $cc_basename in
+ cxch68*)
+ # Green Hills C++ Compiler
+ # _LT_TAGVAR(lt_prog_compiler_static, $1)="--no_auto_instantiation -u __main -u __premain -u _abort -r $COOL_DIR/lib/libOrb.a $MVME_DIR/lib/CC/libC.a $MVME_DIR/lib/classix/libcx.s.a"
+ ;;
+ esac
+ ;;
+ dgux*)
+ case $cc_basename in
+ ec++*)
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC'
+ ;;
+ ghcx*)
+ # Green Hills C++ Compiler
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-pic'
+ ;;
+ *)
+ ;;
+ esac
+ ;;
+ freebsd* | dragonfly*)
+ # FreeBSD uses GNU C++
+ ;;
+ hpux9* | hpux10* | hpux11*)
+ case $cc_basename in
+ CC*)
+ _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+ _LT_TAGVAR(lt_prog_compiler_static, $1)='${wl}-a ${wl}archive'
+ if test "$host_cpu" != ia64; then
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='+Z'
+ fi
+ ;;
+ aCC*)
+ _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+ _LT_TAGVAR(lt_prog_compiler_static, $1)='${wl}-a ${wl}archive'
+ case $host_cpu in
+ hppa*64*|ia64*)
+ # +Z the default
+ ;;
+ *)
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='+Z'
+ ;;
+ esac
+ ;;
+ *)
+ ;;
+ esac
+ ;;
+ interix*)
+ # This is c89, which is MS Visual C++ (no shared libs)
+ # Anyone wants to do a port?
+ ;;
+ irix5* | irix6* | nonstopux*)
+ case $cc_basename in
+ CC*)
+ _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+ _LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared'
+ # CC pic flag -KPIC is the default.
+ ;;
+ *)
+ ;;
+ esac
+ ;;
+ linux* | k*bsd*-gnu | kopensolaris*-gnu)
+ case $cc_basename in
+ KCC*)
+ # KAI C++ Compiler
+ _LT_TAGVAR(lt_prog_compiler_wl, $1)='--backend -Wl,'
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC'
+ ;;
+ ecpc* )
+ # old Intel C++ for x86_64 which still supported -KPIC.
+ _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC'
+ _LT_TAGVAR(lt_prog_compiler_static, $1)='-static'
+ ;;
+ icpc* )
+ # Intel C++, used to be incompatible with GCC.
+ # ICC 10 doesn't accept -KPIC any more.
+ _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC'
+ _LT_TAGVAR(lt_prog_compiler_static, $1)='-static'
+ ;;
+ pgCC* | pgcpp*)
+ # Portland Group C++ compiler
+ _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fpic'
+ _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
+ ;;
+ cxx*)
+ # Compaq C++
+ # Make sure the PIC flag is empty. It appears that all Alpha
+ # Linux and Compaq Tru64 Unix objects are PIC.
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)=
+ _LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared'
+ ;;
+ xlc* | xlC*)
+ # IBM XL 8.0 on PPC
+ _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-qpic'
+ _LT_TAGVAR(lt_prog_compiler_static, $1)='-qstaticlink'
+ ;;
+ *)
+ case `$CC -V 2>&1 | sed 5q` in
+ *Sun\ C*)
+ # Sun C++ 5.9
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC'
+ _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
+ _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Qoption ld '
+ ;;
+ esac
+ ;;
+ esac
+ ;;
+ lynxos*)
+ ;;
+ m88k*)
+ ;;
+ mvs*)
+ case $cc_basename in
+ cxx*)
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-W c,exportall'
+ ;;
+ *)
+ ;;
+ esac
+ ;;
+ netbsd* | netbsdelf*-gnu)
+ ;;
+ *qnx* | *nto*)
+ # QNX uses GNU C++, but need to define -shared option too, otherwise
+ # it will coredump.
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC -shared'
+ ;;
+ osf3* | osf4* | osf5*)
+ case $cc_basename in
+ KCC*)
+ _LT_TAGVAR(lt_prog_compiler_wl, $1)='--backend -Wl,'
+ ;;
+ RCC*)
+ # Rational C++ 2.4.1
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-pic'
+ ;;
+ cxx*)
+ # Digital/Compaq C++
+ _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+ # Make sure the PIC flag is empty. It appears that all Alpha
+ # Linux and Compaq Tru64 Unix objects are PIC.
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)=
+ _LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared'
+ ;;
+ *)
+ ;;
+ esac
+ ;;
+ psos*)
+ ;;
+ solaris*)
+ case $cc_basename in
+ CC*)
+ # Sun C++ 4.2, 5.x and Centerline C++
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC'
+ _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
+ _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Qoption ld '
+ ;;
+ gcx*)
+ # Green Hills C++ Compiler
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-PIC'
+ ;;
+ *)
+ ;;
+ esac
+ ;;
+ sunos4*)
+ case $cc_basename in
+ CC*)
+ # Sun C++ 4.x
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-pic'
+ _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
+ ;;
+ lcc*)
+ # Lucid
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-pic'
+ ;;
+ *)
+ ;;
+ esac
+ ;;
+ sysv5* | unixware* | sco3.2v5* | sco5v6* | OpenUNIX*)
+ case $cc_basename in
+ CC*)
+ _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC'
+ _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
+ ;;
+ esac
+ ;;
+ tandem*)
+ case $cc_basename in
+ NCC*)
+ # NonStop-UX NCC 3.20
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC'
+ ;;
+ *)
+ ;;
+ esac
+ ;;
+ vxworks*)
+ ;;
+ *)
+ _LT_TAGVAR(lt_prog_compiler_can_build_shared, $1)=no
+ ;;
+ esac
+ fi
+],
+[
+ if test "$GCC" = yes; then
+ _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+ _LT_TAGVAR(lt_prog_compiler_static, $1)='-static'
+
+ case $host_os in
+ aix*)
+ # All AIX code is PIC.
+ if test "$host_cpu" = ia64; then
+ # AIX 5 now supports IA64 processor
+ _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
+ fi
+ ;;
+
+ amigaos*)
+ case $host_cpu in
+ powerpc)
+ # see comment about AmigaOS4 .so support
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC'
+ ;;
+ m68k)
+ # FIXME: we need at least 68020 code to build shared libraries, but
+ # adding the `-m68020' flag to GCC prevents building anything better,
+ # like `-m68040'.
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-m68020 -resident32 -malways-restore-a4'
+ ;;
+ esac
+ ;;
+
+ beos* | irix5* | irix6* | nonstopux* | osf3* | osf4* | osf5*)
+ # PIC is the default for these OSes.
+ ;;
+
+ mingw* | cygwin* | pw32* | os2* | cegcc*)
+ # This hack is so that the source file can tell whether it is being
+ # built for inclusion in a dll (and should export symbols for example).
+ # Although the cygwin gcc ignores -fPIC, still need this for old-style
+ # (--disable-auto-import) libraries
+ m4_if([$1], [GCJ], [],
+ [_LT_TAGVAR(lt_prog_compiler_pic, $1)='-DDLL_EXPORT'])
+ ;;
+
+ darwin* | rhapsody*)
+ # PIC is the default on this platform
+ # Common symbols not allowed in MH_DYLIB files
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fno-common'
+ ;;
+
+ hpux*)
+ # PIC is the default for 64-bit PA HP-UX, but not for 32-bit
+ # PA HP-UX. On IA64 HP-UX, PIC is the default but the pic flag
+ # sets the default TLS model and affects inlining.
+ case $host_cpu in
+ hppa*64*)
+ # +Z the default
+ ;;
+ *)
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC'
+ ;;
+ esac
+ ;;
+
+ interix[[3-9]]*)
+ # Interix 3.x gcc -fpic/-fPIC options generate broken code.
+ # Instead, we relocate shared libraries at runtime.
+ ;;
+
+ msdosdjgpp*)
+ # Just because we use GCC doesn't mean we suddenly get shared libraries
+ # on systems that don't support them.
+ _LT_TAGVAR(lt_prog_compiler_can_build_shared, $1)=no
+ enable_shared=no
+ ;;
+
+ *nto* | *qnx*)
+ # QNX uses GNU C++, but need to define -shared option too, otherwise
+ # it will coredump.
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC -shared'
+ ;;
+
+ sysv4*MP*)
+ if test -d /usr/nec; then
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)=-Kconform_pic
+ fi
+ ;;
+
+ *)
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC'
+ ;;
+ esac
+ else
+ # PORTME Check for flag to pass linker flags through the system compiler.
+ case $host_os in
+ aix*)
+ _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+ if test "$host_cpu" = ia64; then
+ # AIX 5 now supports IA64 processor
+ _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
+ else
+ _LT_TAGVAR(lt_prog_compiler_static, $1)='-bnso -bI:/lib/syscalls.exp'
+ fi
+ ;;
+
+ mingw* | cygwin* | pw32* | os2* | cegcc*)
+ # This hack is so that the source file can tell whether it is being
+ # built for inclusion in a dll (and should export symbols for example).
+ m4_if([$1], [GCJ], [],
+ [_LT_TAGVAR(lt_prog_compiler_pic, $1)='-DDLL_EXPORT'])
+ ;;
+
+ hpux9* | hpux10* | hpux11*)
+ _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+ # PIC is the default for IA64 HP-UX and 64-bit HP-UX, but
+ # not for PA HP-UX.
+ case $host_cpu in
+ hppa*64*|ia64*)
+ # +Z the default
+ ;;
+ *)
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='+Z'
+ ;;
+ esac
+ # Is there a better lt_prog_compiler_static that works with the bundled CC?
+ _LT_TAGVAR(lt_prog_compiler_static, $1)='${wl}-a ${wl}archive'
+ ;;
+
+ irix5* | irix6* | nonstopux*)
+ _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+ # PIC (with -KPIC) is the default.
+ _LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared'
+ ;;
+
+ linux* | k*bsd*-gnu | kopensolaris*-gnu)
+ case $cc_basename in
+ # old Intel for x86_64 which still supported -KPIC.
+ ecc*)
+ _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC'
+ _LT_TAGVAR(lt_prog_compiler_static, $1)='-static'
+ ;;
+ # icc used to be incompatible with GCC.
+ # ICC 10 doesn't accept -KPIC any more.
+ icc* | ifort*)
+ _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC'
+ _LT_TAGVAR(lt_prog_compiler_static, $1)='-static'
+ ;;
+ # Lahey Fortran 8.1.
+ lf95*)
+ _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='--shared'
+ _LT_TAGVAR(lt_prog_compiler_static, $1)='--static'
+ ;;
+ pgcc* | pgf77* | pgf90* | pgf95*)
+ # Portland Group compilers (*not* the Pentium gcc compiler,
+ # which looks to be a dead project)
+ _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fpic'
+ _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
+ ;;
+ ccc*)
+ _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+ # All Alpha code is PIC.
+ _LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared'
+ ;;
+ xl*)
+ # IBM XL C 8.0/Fortran 10.1 on PPC
+ _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-qpic'
+ _LT_TAGVAR(lt_prog_compiler_static, $1)='-qstaticlink'
+ ;;
+ *)
+ case `$CC -V 2>&1 | sed 5q` in
+ *Sun\ C*)
+ # Sun C 5.9
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC'
+ _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
+ _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+ ;;
+ *Sun\ F*)
+ # Sun Fortran 8.3 passes all unrecognized flags to the linker
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC'
+ _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
+ _LT_TAGVAR(lt_prog_compiler_wl, $1)=''
+ ;;
+ esac
+ ;;
+ esac
+ ;;
+
+ newsos6)
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC'
+ _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
+ ;;
+
+ *nto* | *qnx*)
+ # QNX uses GNU C++, but need to define -shared option too, otherwise
+ # it will coredump.
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC -shared'
+ ;;
+
+ osf3* | osf4* | osf5*)
+ _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+ # All OSF/1 code is PIC.
+ _LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared'
+ ;;
+
+ rdos*)
+ _LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared'
+ ;;
+
+ solaris*)
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC'
+ _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
+ case $cc_basename in
+ f77* | f90* | f95*)
+ _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Qoption ld ';;
+ *)
+ _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,';;
+ esac
+ ;;
+
+ sunos4*)
+ _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Qoption ld '
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-PIC'
+ _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
+ ;;
+
+ sysv4 | sysv4.2uw2* | sysv4.3*)
+ _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC'
+ _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
+ ;;
+
+ sysv4*MP*)
+ if test -d /usr/nec ;then
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-Kconform_pic'
+ _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
+ fi
+ ;;
+
+ sysv5* | unixware* | sco3.2v5* | sco5v6* | OpenUNIX*)
+ _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC'
+ _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
+ ;;
+
+ unicos*)
+ _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+ _LT_TAGVAR(lt_prog_compiler_can_build_shared, $1)=no
+ ;;
+
+ uts4*)
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-pic'
+ _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
+ ;;
+
+ *)
+ _LT_TAGVAR(lt_prog_compiler_can_build_shared, $1)=no
+ ;;
+ esac
+ fi
+])
+case $host_os in
+ # For platforms which do not support PIC, -DPIC is meaningless:
+ *djgpp*)
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)=
+ ;;
+ *)
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)="$_LT_TAGVAR(lt_prog_compiler_pic, $1)@&t@m4_if([$1],[],[ -DPIC],[m4_if([$1],[CXX],[ -DPIC],[])])"
+ ;;
+esac
+AC_MSG_RESULT([$_LT_TAGVAR(lt_prog_compiler_pic, $1)])
+_LT_TAGDECL([wl], [lt_prog_compiler_wl], [1],
+ [How to pass a linker flag through the compiler])
+
+#
+# Check to make sure the PIC flag actually works.
+#
+if test -n "$_LT_TAGVAR(lt_prog_compiler_pic, $1)"; then
+ _LT_COMPILER_OPTION([if $compiler PIC flag $_LT_TAGVAR(lt_prog_compiler_pic, $1) works],
+ [_LT_TAGVAR(lt_cv_prog_compiler_pic_works, $1)],
+ [$_LT_TAGVAR(lt_prog_compiler_pic, $1)@&t@m4_if([$1],[],[ -DPIC],[m4_if([$1],[CXX],[ -DPIC],[])])], [],
+ [case $_LT_TAGVAR(lt_prog_compiler_pic, $1) in
+ "" | " "*) ;;
+ *) _LT_TAGVAR(lt_prog_compiler_pic, $1)=" $_LT_TAGVAR(lt_prog_compiler_pic, $1)" ;;
+ esac],
+ [_LT_TAGVAR(lt_prog_compiler_pic, $1)=
+ _LT_TAGVAR(lt_prog_compiler_can_build_shared, $1)=no])
+fi
+_LT_TAGDECL([pic_flag], [lt_prog_compiler_pic], [1],
+ [Additional compiler flags for building library objects])
+
+#
+# Check to make sure the static flag actually works.
+#
+wl=$_LT_TAGVAR(lt_prog_compiler_wl, $1) eval lt_tmp_static_flag=\"$_LT_TAGVAR(lt_prog_compiler_static, $1)\"
+_LT_LINKER_OPTION([if $compiler static flag $lt_tmp_static_flag works],
+ _LT_TAGVAR(lt_cv_prog_compiler_static_works, $1),
+ $lt_tmp_static_flag,
+ [],
+ [_LT_TAGVAR(lt_prog_compiler_static, $1)=])
+_LT_TAGDECL([link_static_flag], [lt_prog_compiler_static], [1],
+ [Compiler flag to prevent dynamic linking])
+])# _LT_COMPILER_PIC
+
+
+# _LT_LINKER_SHLIBS([TAGNAME])
+# ----------------------------
+# See if the linker supports building shared libraries.
+m4_defun([_LT_LINKER_SHLIBS],
+[AC_REQUIRE([LT_PATH_LD])dnl
+AC_REQUIRE([LT_PATH_NM])dnl
+m4_require([_LT_FILEUTILS_DEFAULTS])dnl
+m4_require([_LT_DECL_EGREP])dnl
+m4_require([_LT_DECL_SED])dnl
+m4_require([_LT_CMD_GLOBAL_SYMBOLS])dnl
+m4_require([_LT_TAG_COMPILER])dnl
+AC_MSG_CHECKING([whether the $compiler linker ($LD) supports shared libraries])
+m4_if([$1], [CXX], [
+ _LT_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\''s/.* //'\'' | sort | uniq > $export_symbols'
+ case $host_os in
+ aix[[4-9]]*)
+ # If we're using GNU nm, then we don't want the "-C" option.
+ # -C means demangle to AIX nm, but means don't demangle with GNU nm
+ if $NM -V 2>&1 | $GREP 'GNU' > /dev/null; then
+ _LT_TAGVAR(export_symbols_cmds, $1)='$NM -Bpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B")) && ([substr](\$ 3,1,1) != ".")) { print \$ 3 } }'\'' | sort -u > $export_symbols'
+ else
+ _LT_TAGVAR(export_symbols_cmds, $1)='$NM -BCpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B")) && ([substr](\$ 3,1,1) != ".")) { print \$ 3 } }'\'' | sort -u > $export_symbols'
+ fi
+ ;;
+ pw32*)
+ _LT_TAGVAR(export_symbols_cmds, $1)="$ltdll_cmds"
+ ;;
+ cygwin* | mingw* | cegcc*)
+ _LT_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[[BCDGRS]][[ ]]/s/.*[[ ]]\([[^ ]]*\)/\1 DATA/;/^.*[[ ]]__nm__/s/^.*[[ ]]__nm__\([[^ ]]*\)[[ ]][[^ ]]*/\1 DATA/;/^I[[ ]]/d;/^[[AITW]][[ ]]/s/.* //'\'' | sort | uniq > $export_symbols'
+ ;;
+ linux* | k*bsd*-gnu)
+ _LT_TAGVAR(link_all_deplibs, $1)=no
+ ;;
+ *)
+ _LT_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\''s/.* //'\'' | sort | uniq > $export_symbols'
+ ;;
+ esac
+ _LT_TAGVAR(exclude_expsyms, $1)=['_GLOBAL_OFFSET_TABLE_|_GLOBAL__F[ID]_.*']
+], [
+ runpath_var=
+ _LT_TAGVAR(allow_undefined_flag, $1)=
+ _LT_TAGVAR(always_export_symbols, $1)=no
+ _LT_TAGVAR(archive_cmds, $1)=
+ _LT_TAGVAR(archive_expsym_cmds, $1)=
+ _LT_TAGVAR(compiler_needs_object, $1)=no
+ _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=no
+ _LT_TAGVAR(export_dynamic_flag_spec, $1)=
+ _LT_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\''s/.* //'\'' | sort | uniq > $export_symbols'
+ _LT_TAGVAR(hardcode_automatic, $1)=no
+ _LT_TAGVAR(hardcode_direct, $1)=no
+ _LT_TAGVAR(hardcode_direct_absolute, $1)=no
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)=
+ _LT_TAGVAR(hardcode_libdir_flag_spec_ld, $1)=
+ _LT_TAGVAR(hardcode_libdir_separator, $1)=
+ _LT_TAGVAR(hardcode_minus_L, $1)=no
+ _LT_TAGVAR(hardcode_shlibpath_var, $1)=unsupported
+ _LT_TAGVAR(inherit_rpath, $1)=no
+ _LT_TAGVAR(link_all_deplibs, $1)=unknown
+ _LT_TAGVAR(module_cmds, $1)=
+ _LT_TAGVAR(module_expsym_cmds, $1)=
+ _LT_TAGVAR(old_archive_from_new_cmds, $1)=
+ _LT_TAGVAR(old_archive_from_expsyms_cmds, $1)=
+ _LT_TAGVAR(thread_safe_flag_spec, $1)=
+ _LT_TAGVAR(whole_archive_flag_spec, $1)=
+ # include_expsyms should be a list of space-separated symbols to be *always*
+ # included in the symbol list
+ _LT_TAGVAR(include_expsyms, $1)=
+ # exclude_expsyms can be an extended regexp of symbols to exclude
+ # it will be wrapped by ` (' and `)$', so one must not match beginning or
+ # end of line. Example: `a|bc|.*d.*' will exclude the symbols `a' and `bc',
+ # as well as any symbol that contains `d'.
+ _LT_TAGVAR(exclude_expsyms, $1)=['_GLOBAL_OFFSET_TABLE_|_GLOBAL__F[ID]_.*']
+ # Although _GLOBAL_OFFSET_TABLE_ is a valid symbol C name, most a.out
+ # platforms (ab)use it in PIC code, but their linkers get confused if
+ # the symbol is explicitly referenced. Since portable code cannot
+ # rely on this symbol name, it's probably fine to never include it in
+ # preloaded symbol tables.
+ # Exclude shared library initialization/finalization symbols.
+dnl Note also adjust exclude_expsyms for C++ above.
+ extract_expsyms_cmds=
+
+ case $host_os in
+ cygwin* | mingw* | pw32* | cegcc*)
+ # FIXME: the MSVC++ port hasn't been tested in a loooong time
+ # When not using gcc, we currently assume that we are using
+ # Microsoft Visual C++.
+ if test "$GCC" != yes; then
+ with_gnu_ld=no
+ fi
+ ;;
+ interix*)
+ # we just hope/assume this is gcc and not c89 (= MSVC++)
+ with_gnu_ld=yes
+ ;;
+ openbsd*)
+ with_gnu_ld=no
+ ;;
+ linux* | k*bsd*-gnu)
+ _LT_TAGVAR(link_all_deplibs, $1)=no
+ ;;
+ esac
+
+ _LT_TAGVAR(ld_shlibs, $1)=yes
+ if test "$with_gnu_ld" = yes; then
+ # If archive_cmds runs LD, not CC, wlarc should be empty
+ wlarc='${wl}'
+
+ # Set some defaults for GNU ld with shared library support. These
+ # are reset later if shared libraries are not supported. Putting them
+ # here allows them to be overridden if necessary.
+ runpath_var=LD_RUN_PATH
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir'
+ _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}--export-dynamic'
+ # ancient GNU ld didn't support --whole-archive et. al.
+ if $LD --help 2>&1 | $GREP 'no-whole-archive' > /dev/null; then
+ _LT_TAGVAR(whole_archive_flag_spec, $1)="$wlarc"'--whole-archive$convenience '"$wlarc"'--no-whole-archive'
+ else
+ _LT_TAGVAR(whole_archive_flag_spec, $1)=
+ fi
+ supports_anon_versioning=no
+ case `$LD -v 2>&1` in
+ *GNU\ gold*) supports_anon_versioning=yes ;;
+ *\ [[01]].* | *\ 2.[[0-9]].* | *\ 2.10.*) ;; # catch versions < 2.11
+ *\ 2.11.93.0.2\ *) supports_anon_versioning=yes ;; # RH7.3 ...
+ *\ 2.11.92.0.12\ *) supports_anon_versioning=yes ;; # Mandrake 8.2 ...
+ *\ 2.11.*) ;; # other 2.11 versions
+ *) supports_anon_versioning=yes ;;
+ esac
+
+ # See if GNU ld supports shared libraries.
+ case $host_os in
+ aix[[3-9]]*)
+ # On AIX/PPC, the GNU linker is very broken
+ if test "$host_cpu" != ia64; then
+ _LT_TAGVAR(ld_shlibs, $1)=no
+ cat <<_LT_EOF 1>&2
+
+*** Warning: the GNU linker, at least up to release 2.9.1, is reported
+*** to be unable to reliably create shared libraries on AIX.
+*** Therefore, libtool is disabling shared libraries support. If you
+*** really care for shared libraries, you may want to modify your PATH
+*** so that a non-GNU linker is found, and then restart.
+
+_LT_EOF
+ fi
+ ;;
+
+ amigaos*)
+ case $host_cpu in
+ powerpc)
+ # see comment about AmigaOS4 .so support
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
+ _LT_TAGVAR(archive_expsym_cmds, $1)=''
+ ;;
+ m68k)
+ _LT_TAGVAR(archive_cmds, $1)='$RM $output_objdir/a2ixlibrary.data~$ECHO "#define NAME $libname" > $output_objdir/a2ixlibrary.data~$ECHO "#define LIBRARY_ID 1" >> $output_objdir/a2ixlibrary.data~$ECHO "#define VERSION $major" >> $output_objdir/a2ixlibrary.data~$ECHO "#define REVISION $revision" >> $output_objdir/a2ixlibrary.data~$AR $AR_FLAGS $lib $libobjs~$RANLIB $lib~(cd $output_objdir && a2ixlibrary -32)'
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir'
+ _LT_TAGVAR(hardcode_minus_L, $1)=yes
+ ;;
+ esac
+ ;;
+
+ beos*)
+ if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then
+ _LT_TAGVAR(allow_undefined_flag, $1)=unsupported
+ # Joseph Beckenbach <jrb3@best.com> says some releases of gcc
+ # support --undefined. This deserves some investigation. FIXME
+ _LT_TAGVAR(archive_cmds, $1)='$CC -nostart $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
+ else
+ _LT_TAGVAR(ld_shlibs, $1)=no
+ fi
+ ;;
+
+ cygwin* | mingw* | pw32* | cegcc*)
+ # _LT_TAGVAR(hardcode_libdir_flag_spec, $1) is actually meaningless,
+ # as there is no search path for DLLs.
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir'
+ _LT_TAGVAR(allow_undefined_flag, $1)=unsupported
+ _LT_TAGVAR(always_export_symbols, $1)=no
+ _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=yes
+ _LT_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[[BCDGRS]][[ ]]/s/.*[[ ]]\([[^ ]]*\)/\1 DATA/'\'' | $SED -e '\''/^[[AITW]][[ ]]/s/.*[[ ]]//'\'' | sort | uniq > $export_symbols'
+
+ if $LD --help 2>&1 | $GREP 'auto-import' > /dev/null; then
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib'
+ # If the export-symbols file already is a .def file (1st line
+ # is EXPORTS), use it as is; otherwise, prepend...
+ _LT_TAGVAR(archive_expsym_cmds, $1)='if test "x`$SED 1q $export_symbols`" = xEXPORTS; then
+ cp $export_symbols $output_objdir/$soname.def;
+ else
+ echo EXPORTS > $output_objdir/$soname.def;
+ cat $export_symbols >> $output_objdir/$soname.def;
+ fi~
+ $CC -shared $output_objdir/$soname.def $libobjs $deplibs $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib'
+ else
+ _LT_TAGVAR(ld_shlibs, $1)=no
+ fi
+ ;;
+
+ interix[[3-9]]*)
+ _LT_TAGVAR(hardcode_direct, $1)=no
+ _LT_TAGVAR(hardcode_shlibpath_var, $1)=no
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir'
+ _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E'
+ # Hack: On Interix 3.x, we cannot compile PIC because of a broken gcc.
+ # Instead, shared libraries are loaded at an image base (0x10000000 by
+ # default) and relocated if they conflict, which is a slow very memory
+ # consuming and fragmenting process. To avoid this, we pick a random,
+ # 256 KiB-aligned image base between 0x50000000 and 0x6FFC0000 at link
+ # time. Moving up from 0x10000000 also allows more sbrk(2) space.
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-h,$soname ${wl}--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib'
+ _LT_TAGVAR(archive_expsym_cmds, $1)='sed "s,^,_," $export_symbols >$output_objdir/$soname.expsym~$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-h,$soname ${wl}--retain-symbols-file,$output_objdir/$soname.expsym ${wl}--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib'
+ ;;
+
+ gnu* | linux* | tpf* | k*bsd*-gnu | kopensolaris*-gnu)
+ tmp_diet=no
+ if test "$host_os" = linux-dietlibc; then
+ case $cc_basename in
+ diet\ *) tmp_diet=yes;; # linux-dietlibc with static linking (!diet-dyn)
+ esac
+ fi
+ if $LD --help 2>&1 | $EGREP ': supported targets:.* elf' > /dev/null \
+ && test "$tmp_diet" = no
+ then
+ tmp_addflag=
+ tmp_sharedflag='-shared'
+ case $cc_basename,$host_cpu in
+ pgcc*) # Portland Group C compiler
+ _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; $ECHO \"$new_convenience\"` ${wl}--no-whole-archive'
+ tmp_addflag=' $pic_flag'
+ ;;
+ pgf77* | pgf90* | pgf95*) # Portland Group f77 and f90 compilers
+ _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; $ECHO \"$new_convenience\"` ${wl}--no-whole-archive'
+ tmp_addflag=' $pic_flag -Mnomain' ;;
+ ecc*,ia64* | icc*,ia64*) # Intel C compiler on ia64
+ tmp_addflag=' -i_dynamic' ;;
+ efc*,ia64* | ifort*,ia64*) # Intel Fortran compiler on ia64
+ tmp_addflag=' -i_dynamic -nofor_main' ;;
+ ifc* | ifort*) # Intel Fortran compiler
+ tmp_addflag=' -nofor_main' ;;
+ lf95*) # Lahey Fortran 8.1
+ _LT_TAGVAR(whole_archive_flag_spec, $1)=
+ tmp_sharedflag='--shared' ;;
+ xl[[cC]]*) # IBM XL C 8.0 on PPC (deal with xlf below)
+ tmp_sharedflag='-qmkshrobj'
+ tmp_addflag= ;;
+ esac
+ case `$CC -V 2>&1 | sed 5q` in
+ *Sun\ C*) # Sun C 5.9
+ _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive`new_convenience=; for conv in $convenience\"\"; do test -z \"$conv\" || new_convenience=\"$new_convenience,$conv\"; done; $ECHO \"$new_convenience\"` ${wl}--no-whole-archive'
+ _LT_TAGVAR(compiler_needs_object, $1)=yes
+ tmp_sharedflag='-G' ;;
+ *Sun\ F*) # Sun Fortran 8.3
+ tmp_sharedflag='-G' ;;
+ esac
+ _LT_TAGVAR(archive_cmds, $1)='$CC '"$tmp_sharedflag""$tmp_addflag"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
+
+ if test "x$supports_anon_versioning" = xyes; then
+ _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $output_objdir/$libname.ver~
+ cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~
+ echo "local: *; };" >> $output_objdir/$libname.ver~
+ $CC '"$tmp_sharedflag""$tmp_addflag"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-version-script ${wl}$output_objdir/$libname.ver -o $lib'
+ fi
+
+ case $cc_basename in
+ xlf*)
+ # IBM XL Fortran 10.1 on PPC cannot create shared libs itself
+ _LT_TAGVAR(whole_archive_flag_spec, $1)='--whole-archive$convenience --no-whole-archive'
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)=
+ _LT_TAGVAR(hardcode_libdir_flag_spec_ld, $1)='-rpath $libdir'
+ _LT_TAGVAR(archive_cmds, $1)='$LD -shared $libobjs $deplibs $compiler_flags -soname $soname -o $lib'
+ if test "x$supports_anon_versioning" = xyes; then
+ _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $output_objdir/$libname.ver~
+ cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~
+ echo "local: *; };" >> $output_objdir/$libname.ver~
+ $LD -shared $libobjs $deplibs $compiler_flags -soname $soname -version-script $output_objdir/$libname.ver -o $lib'
+ fi
+ ;;
+ esac
+ else
+ _LT_TAGVAR(ld_shlibs, $1)=no
+ fi
+ ;;
+
+ netbsd* | netbsdelf*-gnu)
+ if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then
+ _LT_TAGVAR(archive_cmds, $1)='$LD -Bshareable $libobjs $deplibs $linker_flags -o $lib'
+ wlarc=
+ else
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
+ _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib'
+ fi
+ ;;
+
+ solaris*)
+ if $LD -v 2>&1 | $GREP 'BFD 2\.8' > /dev/null; then
+ _LT_TAGVAR(ld_shlibs, $1)=no
+ cat <<_LT_EOF 1>&2
+
+*** Warning: The releases 2.8.* of the GNU linker cannot reliably
+*** create shared libraries on Solaris systems. Therefore, libtool
+*** is disabling shared libraries support. We urge you to upgrade GNU
+*** binutils to release 2.9.1 or newer. Another option is to modify
+*** your PATH or compiler configuration so that the native linker is
+*** used, and then restart.
+
+_LT_EOF
+ elif $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
+ _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib'
+ else
+ _LT_TAGVAR(ld_shlibs, $1)=no
+ fi
+ ;;
+
+ sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX*)
+ case `$LD -v 2>&1` in
+ *\ [[01]].* | *\ 2.[[0-9]].* | *\ 2.1[[0-5]].*)
+ _LT_TAGVAR(ld_shlibs, $1)=no
+ cat <<_LT_EOF 1>&2
+
+*** Warning: Releases of the GNU linker prior to 2.16.91.0.3 can not
+*** reliably create shared libraries on SCO systems. Therefore, libtool
+*** is disabling shared libraries support. We urge you to upgrade GNU
+*** binutils to release 2.16.91.0.3 or newer. Another option is to modify
+*** your PATH or compiler configuration so that the native linker is
+*** used, and then restart.
+
+_LT_EOF
+ ;;
+ *)
+ # For security reasons, it is highly recommended that you always
+ # use absolute paths for naming shared libraries, and exclude the
+ # DT_RUNPATH tag from executables and libraries. But doing so
+ # requires that you compile everything twice, which is a pain.
+ if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir'
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
+ _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib'
+ else
+ _LT_TAGVAR(ld_shlibs, $1)=no
+ fi
+ ;;
+ esac
+ ;;
+
+ sunos4*)
+ _LT_TAGVAR(archive_cmds, $1)='$LD -assert pure-text -Bshareable -o $lib $libobjs $deplibs $linker_flags'
+ wlarc=
+ _LT_TAGVAR(hardcode_direct, $1)=yes
+ _LT_TAGVAR(hardcode_shlibpath_var, $1)=no
+ ;;
+
+ *)
+ if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
+ _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib'
+ else
+ _LT_TAGVAR(ld_shlibs, $1)=no
+ fi
+ ;;
+ esac
+
+ if test "$_LT_TAGVAR(ld_shlibs, $1)" = no; then
+ runpath_var=
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)=
+ _LT_TAGVAR(export_dynamic_flag_spec, $1)=
+ _LT_TAGVAR(whole_archive_flag_spec, $1)=
+ fi
+ else
+ # PORTME fill in a description of your system's linker (not GNU ld)
+ case $host_os in
+ aix3*)
+ _LT_TAGVAR(allow_undefined_flag, $1)=unsupported
+ _LT_TAGVAR(always_export_symbols, $1)=yes
+ _LT_TAGVAR(archive_expsym_cmds, $1)='$LD -o $output_objdir/$soname $libobjs $deplibs $linker_flags -bE:$export_symbols -T512 -H512 -bM:SRE~$AR $AR_FLAGS $lib $output_objdir/$soname'
+ # Note: this linker hardcodes the directories in LIBPATH if there
+ # are no directories specified by -L.
+ _LT_TAGVAR(hardcode_minus_L, $1)=yes
+ if test "$GCC" = yes && test -z "$lt_prog_compiler_static"; then
+ # Neither direct hardcoding nor static linking is supported with a
+ # broken collect2.
+ _LT_TAGVAR(hardcode_direct, $1)=unsupported
+ fi
+ ;;
+
+ aix[[4-9]]*)
+ if test "$host_cpu" = ia64; then
+ # On IA64, the linker does run time linking by default, so we don't
+ # have to do anything special.
+ aix_use_runtimelinking=no
+ exp_sym_flag='-Bexport'
+ no_entry_flag=""
+ else
+ # If we're using GNU nm, then we don't want the "-C" option.
+ # -C means demangle to AIX nm, but means don't demangle with GNU nm
+ if $NM -V 2>&1 | $GREP 'GNU' > /dev/null; then
+ _LT_TAGVAR(export_symbols_cmds, $1)='$NM -Bpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B")) && ([substr](\$ 3,1,1) != ".")) { print \$ 3 } }'\'' | sort -u > $export_symbols'
+ else
+ _LT_TAGVAR(export_symbols_cmds, $1)='$NM -BCpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B")) && ([substr](\$ 3,1,1) != ".")) { print \$ 3 } }'\'' | sort -u > $export_symbols'
+ fi
+ aix_use_runtimelinking=no
+
+ # Test if we are trying to use run time linking or normal
+ # AIX style linking. If -brtl is somewhere in LDFLAGS, we
+ # need to do runtime linking.
+ case $host_os in aix4.[[23]]|aix4.[[23]].*|aix[[5-9]]*)
+ for ld_flag in $LDFLAGS; do
+ if (test $ld_flag = "-brtl" || test $ld_flag = "-Wl,-brtl"); then
+ aix_use_runtimelinking=yes
+ break
+ fi
+ done
+ ;;
+ esac
+
+ exp_sym_flag='-bexport'
+ no_entry_flag='-bnoentry'
+ fi
+
+ # When large executables or shared objects are built, AIX ld can
+ # have problems creating the table of contents. If linking a library
+ # or program results in "error TOC overflow" add -mminimal-toc to
+ # CXXFLAGS/CFLAGS for g++/gcc. In the cases where that is not
+ # enough to fix the problem, add -Wl,-bbigtoc to LDFLAGS.
+
+ _LT_TAGVAR(archive_cmds, $1)=''
+ _LT_TAGVAR(hardcode_direct, $1)=yes
+ _LT_TAGVAR(hardcode_direct_absolute, $1)=yes
+ _LT_TAGVAR(hardcode_libdir_separator, $1)=':'
+ _LT_TAGVAR(link_all_deplibs, $1)=yes
+ _LT_TAGVAR(file_list_spec, $1)='${wl}-f,'
+
+ if test "$GCC" = yes; then
+ case $host_os in aix4.[[012]]|aix4.[[012]].*)
+ # We only want to do this on AIX 4.2 and lower, the check
+ # below for broken collect2 doesn't work under 4.3+
+ collect2name=`${CC} -print-prog-name=collect2`
+ if test -f "$collect2name" &&
+ strings "$collect2name" | $GREP resolve_lib_name >/dev/null
+ then
+ # We have reworked collect2
+ :
+ else
+ # We have old collect2
+ _LT_TAGVAR(hardcode_direct, $1)=unsupported
+ # It fails to find uninstalled libraries when the uninstalled
+ # path is not listed in the libpath. Setting hardcode_minus_L
+ # to unsupported forces relinking
+ _LT_TAGVAR(hardcode_minus_L, $1)=yes
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir'
+ _LT_TAGVAR(hardcode_libdir_separator, $1)=
+ fi
+ ;;
+ esac
+ shared_flag='-shared'
+ if test "$aix_use_runtimelinking" = yes; then
+ shared_flag="$shared_flag "'${wl}-G'
+ fi
+ _LT_TAGVAR(link_all_deplibs, $1)=no
+ else
+ # not using gcc
+ if test "$host_cpu" = ia64; then
+ # VisualAge C++, Version 5.5 for AIX 5L for IA-64, Beta 3 Release
+ # chokes on -Wl,-G. The following line is correct:
+ shared_flag='-G'
+ else
+ if test "$aix_use_runtimelinking" = yes; then
+ shared_flag='${wl}-G'
+ else
+ shared_flag='${wl}-bM:SRE'
+ fi
+ fi
+ fi
+
+ _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-bexpall'
+ # It seems that -bexpall does not export symbols beginning with
+ # underscore (_), so it is better to generate a list of symbols to export.
+ _LT_TAGVAR(always_export_symbols, $1)=yes
+ if test "$aix_use_runtimelinking" = yes; then
+ # Warning - without using the other runtime loading flags (-brtl),
+ # -berok will link without error, but may produce a broken library.
+ _LT_TAGVAR(allow_undefined_flag, $1)='-berok'
+ # Determine the default libpath from the value encoded in an
+ # empty executable.
+ _LT_SYS_MODULE_PATH_AIX
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-blibpath:$libdir:'"$aix_libpath"
+ _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -o $output_objdir/$soname $libobjs $deplibs '"\${wl}$no_entry_flag"' $compiler_flags `if test "x${allow_undefined_flag}" != "x"; then $ECHO "X${wl}${allow_undefined_flag}" | $Xsed; else :; fi` '"\${wl}$exp_sym_flag:\$export_symbols $shared_flag"
+ else
+ if test "$host_cpu" = ia64; then
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-R $libdir:/usr/lib:/lib'
+ _LT_TAGVAR(allow_undefined_flag, $1)="-z nodefs"
+ _LT_TAGVAR(archive_expsym_cmds, $1)="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs '"\${wl}$no_entry_flag"' $compiler_flags ${wl}${allow_undefined_flag} '"\${wl}$exp_sym_flag:\$export_symbols"
+ else
+ # Determine the default libpath from the value encoded in an
+ # empty executable.
+ _LT_SYS_MODULE_PATH_AIX
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-blibpath:$libdir:'"$aix_libpath"
+ # Warning - without using the other run time loading flags,
+ # -berok will link without error, but may produce a broken library.
+ _LT_TAGVAR(no_undefined_flag, $1)=' ${wl}-bernotok'
+ _LT_TAGVAR(allow_undefined_flag, $1)=' ${wl}-berok'
+ # Exported symbols can be pulled into shared objects from archives
+ _LT_TAGVAR(whole_archive_flag_spec, $1)='$convenience'
+ _LT_TAGVAR(archive_cmds_need_lc, $1)=yes
+ # This is similar to how AIX traditionally builds its shared libraries.
+ _LT_TAGVAR(archive_expsym_cmds, $1)="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs ${wl}-bnoentry $compiler_flags ${wl}-bE:$export_symbols${allow_undefined_flag}~$AR $AR_FLAGS $output_objdir/$libname$release.a $output_objdir/$soname'
+ fi
+ fi
+ ;;
+
+ amigaos*)
+ case $host_cpu in
+ powerpc)
+ # see comment about AmigaOS4 .so support
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
+ _LT_TAGVAR(archive_expsym_cmds, $1)=''
+ ;;
+ m68k)
+ _LT_TAGVAR(archive_cmds, $1)='$RM $output_objdir/a2ixlibrary.data~$ECHO "#define NAME $libname" > $output_objdir/a2ixlibrary.data~$ECHO "#define LIBRARY_ID 1" >> $output_objdir/a2ixlibrary.data~$ECHO "#define VERSION $major" >> $output_objdir/a2ixlibrary.data~$ECHO "#define REVISION $revision" >> $output_objdir/a2ixlibrary.data~$AR $AR_FLAGS $lib $libobjs~$RANLIB $lib~(cd $output_objdir && a2ixlibrary -32)'
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir'
+ _LT_TAGVAR(hardcode_minus_L, $1)=yes
+ ;;
+ esac
+ ;;
+
+ bsdi[[45]]*)
+ _LT_TAGVAR(export_dynamic_flag_spec, $1)=-rdynamic
+ ;;
+
+ cygwin* | mingw* | pw32* | cegcc*)
+ # When not using gcc, we currently assume that we are using
+ # Microsoft Visual C++.
+ # hardcode_libdir_flag_spec is actually meaningless, as there is
+ # no search path for DLLs.
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)=' '
+ _LT_TAGVAR(allow_undefined_flag, $1)=unsupported
+ # Tell ltmain to make .lib files, not .a files.
+ libext=lib
+ # Tell ltmain to make .dll files, not .so files.
+ shrext_cmds=".dll"
+ # FIXME: Setting linknames here is a bad hack.
+ _LT_TAGVAR(archive_cmds, $1)='$CC -o $lib $libobjs $compiler_flags `$ECHO "X$deplibs" | $Xsed -e '\''s/ -lc$//'\''` -link -dll~linknames='
+ # The linker will automatically build a .lib file if we build a DLL.
+ _LT_TAGVAR(old_archive_from_new_cmds, $1)='true'
+ # FIXME: Should let the user specify the lib program.
+ _LT_TAGVAR(old_archive_cmds, $1)='lib -OUT:$oldlib$oldobjs$old_deplibs'
+ _LT_TAGVAR(fix_srcfile_path, $1)='`cygpath -w "$srcfile"`'
+ _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=yes
+ ;;
+
+ darwin* | rhapsody*)
+ _LT_DARWIN_LINKER_FEATURES($1)
+ ;;
+
+ dgux*)
+ _LT_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir'
+ _LT_TAGVAR(hardcode_shlibpath_var, $1)=no
+ ;;
+
+ freebsd1*)
+ _LT_TAGVAR(ld_shlibs, $1)=no
+ ;;
+
+ # FreeBSD 2.2.[012] allows us to include c++rt0.o to get C++ constructor
+ # support. Future versions do this automatically, but an explicit c++rt0.o
+ # does not break anything, and helps significantly (at the cost of a little
+ # extra space).
+ freebsd2.2*)
+ _LT_TAGVAR(archive_cmds, $1)='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags /usr/lib/c++rt0.o'
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir'
+ _LT_TAGVAR(hardcode_direct, $1)=yes
+ _LT_TAGVAR(hardcode_shlibpath_var, $1)=no
+ ;;
+
+ # Unfortunately, older versions of FreeBSD 2 do not have this feature.
+ freebsd2*)
+ _LT_TAGVAR(archive_cmds, $1)='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags'
+ _LT_TAGVAR(hardcode_direct, $1)=yes
+ _LT_TAGVAR(hardcode_minus_L, $1)=yes
+ _LT_TAGVAR(hardcode_shlibpath_var, $1)=no
+ ;;
+
+ # FreeBSD 3 and greater uses gcc -shared to do shared libraries.
+ freebsd* | dragonfly*)
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared -o $lib $libobjs $deplibs $compiler_flags'
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir'
+ _LT_TAGVAR(hardcode_direct, $1)=yes
+ _LT_TAGVAR(hardcode_shlibpath_var, $1)=no
+ ;;
+
+ hpux9*)
+ if test "$GCC" = yes; then
+ _LT_TAGVAR(archive_cmds, $1)='$RM $output_objdir/$soname~$CC -shared -fPIC ${wl}+b ${wl}$install_libdir -o $output_objdir/$soname $libobjs $deplibs $compiler_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib'
+ else
+ _LT_TAGVAR(archive_cmds, $1)='$RM $output_objdir/$soname~$LD -b +b $install_libdir -o $output_objdir/$soname $libobjs $deplibs $linker_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib'
+ fi
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}+b ${wl}$libdir'
+ _LT_TAGVAR(hardcode_libdir_separator, $1)=:
+ _LT_TAGVAR(hardcode_direct, $1)=yes
+
+ # hardcode_minus_L: Not really in the search PATH,
+ # but as the default location of the library.
+ _LT_TAGVAR(hardcode_minus_L, $1)=yes
+ _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E'
+ ;;
+
+ hpux10*)
+ if test "$GCC" = yes -a "$with_gnu_ld" = no; then
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared -fPIC ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags'
+ else
+ _LT_TAGVAR(archive_cmds, $1)='$LD -b +h $soname +b $install_libdir -o $lib $libobjs $deplibs $linker_flags'
+ fi
+ if test "$with_gnu_ld" = no; then
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}+b ${wl}$libdir'
+ _LT_TAGVAR(hardcode_libdir_flag_spec_ld, $1)='+b $libdir'
+ _LT_TAGVAR(hardcode_libdir_separator, $1)=:
+ _LT_TAGVAR(hardcode_direct, $1)=yes
+ _LT_TAGVAR(hardcode_direct_absolute, $1)=yes
+ _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E'
+ # hardcode_minus_L: Not really in the search PATH,
+ # but as the default location of the library.
+ _LT_TAGVAR(hardcode_minus_L, $1)=yes
+ fi
+ ;;
+
+ hpux11*)
+ if test "$GCC" = yes -a "$with_gnu_ld" = no; then
+ case $host_cpu in
+ hppa*64*)
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared ${wl}+h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags'
+ ;;
+ ia64*)
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared -fPIC ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags'
+ ;;
+ *)
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared -fPIC ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags'
+ ;;
+ esac
+ else
+ case $host_cpu in
+ hppa*64*)
+ _LT_TAGVAR(archive_cmds, $1)='$CC -b ${wl}+h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags'
+ ;;
+ ia64*)
+ _LT_TAGVAR(archive_cmds, $1)='$CC -b ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags'
+ ;;
+ *)
+ _LT_TAGVAR(archive_cmds, $1)='$CC -b ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags'
+ ;;
+ esac
+ fi
+ if test "$with_gnu_ld" = no; then
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}+b ${wl}$libdir'
+ _LT_TAGVAR(hardcode_libdir_separator, $1)=:
+
+ case $host_cpu in
+ hppa*64*|ia64*)
+ _LT_TAGVAR(hardcode_direct, $1)=no
+ _LT_TAGVAR(hardcode_shlibpath_var, $1)=no
+ ;;
+ *)
+ _LT_TAGVAR(hardcode_direct, $1)=yes
+ _LT_TAGVAR(hardcode_direct_absolute, $1)=yes
+ _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E'
+
+ # hardcode_minus_L: Not really in the search PATH,
+ # but as the default location of the library.
+ _LT_TAGVAR(hardcode_minus_L, $1)=yes
+ ;;
+ esac
+ fi
+ ;;
+
+ irix5* | irix6* | nonstopux*)
+ if test "$GCC" = yes; then
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && $ECHO "X${wl}-set_version ${wl}$verstring" | $Xsed` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib'
+ # Try to use the -exported_symbol ld option, if it does not
+ # work, assume that -exports_file does not work either and
+ # implicitly export all symbols.
+ save_LDFLAGS="$LDFLAGS"
+ LDFLAGS="$LDFLAGS -shared ${wl}-exported_symbol ${wl}foo ${wl}-update_registry ${wl}/dev/null"
+ AC_LINK_IFELSE(int foo(void) {},
+ _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && $ECHO "X${wl}-set_version ${wl}$verstring" | $Xsed` ${wl}-update_registry ${wl}${output_objdir}/so_locations ${wl}-exports_file ${wl}$export_symbols -o $lib'
+ )
+ LDFLAGS="$save_LDFLAGS"
+ else
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && $ECHO "X-set_version $verstring" | $Xsed` -update_registry ${output_objdir}/so_locations -o $lib'
+ _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && $ECHO "X-set_version $verstring" | $Xsed` -update_registry ${output_objdir}/so_locations -exports_file $export_symbols -o $lib'
+ fi
+ _LT_TAGVAR(archive_cmds_need_lc, $1)='no'
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir'
+ _LT_TAGVAR(hardcode_libdir_separator, $1)=:
+ _LT_TAGVAR(inherit_rpath, $1)=yes
+ _LT_TAGVAR(link_all_deplibs, $1)=yes
+ ;;
+
+ netbsd* | netbsdelf*-gnu)
+ if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then
+ _LT_TAGVAR(archive_cmds, $1)='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags' # a.out
+ else
+ _LT_TAGVAR(archive_cmds, $1)='$LD -shared -o $lib $libobjs $deplibs $linker_flags' # ELF
+ fi
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir'
+ _LT_TAGVAR(hardcode_direct, $1)=yes
+ _LT_TAGVAR(hardcode_shlibpath_var, $1)=no
+ ;;
+
+ newsos6)
+ _LT_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'
+ _LT_TAGVAR(hardcode_direct, $1)=yes
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir'
+ _LT_TAGVAR(hardcode_libdir_separator, $1)=:
+ _LT_TAGVAR(hardcode_shlibpath_var, $1)=no
+ ;;
+
+ *nto* | *qnx*)
+ ;;
+
+ openbsd*)
+ if test -f /usr/libexec/ld.so; then
+ _LT_TAGVAR(hardcode_direct, $1)=yes
+ _LT_TAGVAR(hardcode_shlibpath_var, $1)=no
+ _LT_TAGVAR(hardcode_direct_absolute, $1)=yes
+ if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags'
+ _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags ${wl}-retain-symbols-file,$export_symbols'
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir'
+ _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E'
+ else
+ case $host_os in
+ openbsd[[01]].* | openbsd2.[[0-7]] | openbsd2.[[0-7]].*)
+ _LT_TAGVAR(archive_cmds, $1)='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags'
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir'
+ ;;
+ *)
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags'
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir'
+ ;;
+ esac
+ fi
+ else
+ _LT_TAGVAR(ld_shlibs, $1)=no
+ fi
+ ;;
+
+ os2*)
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir'
+ _LT_TAGVAR(hardcode_minus_L, $1)=yes
+ _LT_TAGVAR(allow_undefined_flag, $1)=unsupported
+ _LT_TAGVAR(archive_cmds, $1)='$ECHO "LIBRARY $libname INITINSTANCE" > $output_objdir/$libname.def~$ECHO "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~$ECHO DATA >> $output_objdir/$libname.def~$ECHO " SINGLE NONSHARED" >> $output_objdir/$libname.def~$ECHO EXPORTS >> $output_objdir/$libname.def~emxexp $libobjs >> $output_objdir/$libname.def~$CC -Zdll -Zcrtdll -o $lib $libobjs $deplibs $compiler_flags $output_objdir/$libname.def'
+ _LT_TAGVAR(old_archive_from_new_cmds, $1)='emximp -o $output_objdir/$libname.a $output_objdir/$libname.def'
+ ;;
+
+ osf3*)
+ if test "$GCC" = yes; then
+ _LT_TAGVAR(allow_undefined_flag, $1)=' ${wl}-expect_unresolved ${wl}\*'
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && $ECHO "X${wl}-set_version ${wl}$verstring" | $Xsed` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib'
+ else
+ _LT_TAGVAR(allow_undefined_flag, $1)=' -expect_unresolved \*'
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && $ECHO "X-set_version $verstring" | $Xsed` -update_registry ${output_objdir}/so_locations -o $lib'
+ fi
+ _LT_TAGVAR(archive_cmds_need_lc, $1)='no'
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir'
+ _LT_TAGVAR(hardcode_libdir_separator, $1)=:
+ ;;
+
+ osf4* | osf5*) # as osf3* with the addition of -msym flag
+ if test "$GCC" = yes; then
+ _LT_TAGVAR(allow_undefined_flag, $1)=' ${wl}-expect_unresolved ${wl}\*'
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags ${wl}-msym ${wl}-soname ${wl}$soname `test -n "$verstring" && $ECHO "X${wl}-set_version ${wl}$verstring" | $Xsed` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib'
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir'
+ else
+ _LT_TAGVAR(allow_undefined_flag, $1)=' -expect_unresolved \*'
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags -msym -soname $soname `test -n "$verstring" && $ECHO "X-set_version $verstring" | $Xsed` -update_registry ${output_objdir}/so_locations -o $lib'
+ _LT_TAGVAR(archive_expsym_cmds, $1)='for i in `cat $export_symbols`; do printf "%s %s\\n" -exported_symbol "\$i" >> $lib.exp; done; printf "%s\\n" "-hidden">> $lib.exp~
+ $CC -shared${allow_undefined_flag} ${wl}-input ${wl}$lib.exp $compiler_flags $libobjs $deplibs -soname $soname `test -n "$verstring" && $ECHO "X-set_version $verstring" | $Xsed` -update_registry ${output_objdir}/so_locations -o $lib~$RM $lib.exp'
+
+ # Both c and cxx compiler support -rpath directly
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-rpath $libdir'
+ fi
+ _LT_TAGVAR(archive_cmds_need_lc, $1)='no'
+ _LT_TAGVAR(hardcode_libdir_separator, $1)=:
+ ;;
+
+ solaris*)
+ _LT_TAGVAR(no_undefined_flag, $1)=' -z defs'
+ if test "$GCC" = yes; then
+ wlarc='${wl}'
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared ${wl}-z ${wl}text ${wl}-h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags'
+ _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~
+ $CC -shared ${wl}-z ${wl}text ${wl}-M ${wl}$lib.exp ${wl}-h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags~$RM $lib.exp'
+ else
+ case `$CC -V 2>&1` in
+ *"Compilers 5.0"*)
+ wlarc=''
+ _LT_TAGVAR(archive_cmds, $1)='$LD -G${allow_undefined_flag} -h $soname -o $lib $libobjs $deplibs $linker_flags'
+ _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~
+ $LD -G${allow_undefined_flag} -M $lib.exp -h $soname -o $lib $libobjs $deplibs $linker_flags~$RM $lib.exp'
+ ;;
+ *)
+ wlarc='${wl}'
+ _LT_TAGVAR(archive_cmds, $1)='$CC -G${allow_undefined_flag} -h $soname -o $lib $libobjs $deplibs $compiler_flags'
+ _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~
+ $CC -G${allow_undefined_flag} -M $lib.exp -h $soname -o $lib $libobjs $deplibs $compiler_flags~$RM $lib.exp'
+ ;;
+ esac
+ fi
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir'
+ _LT_TAGVAR(hardcode_shlibpath_var, $1)=no
+ case $host_os in
+ solaris2.[[0-5]] | solaris2.[[0-5]].*) ;;
+ *)
+ # The compiler driver will combine and reorder linker options,
+ # but understands `-z linker_flag'. GCC discards it without `$wl',
+ # but is careful enough not to reorder.
+ # Supported since Solaris 2.6 (maybe 2.5.1?)
+ if test "$GCC" = yes; then
+ _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}-z ${wl}allextract$convenience ${wl}-z ${wl}defaultextract'
+ else
+ _LT_TAGVAR(whole_archive_flag_spec, $1)='-z allextract$convenience -z defaultextract'
+ fi
+ ;;
+ esac
+ _LT_TAGVAR(link_all_deplibs, $1)=yes
+ ;;
+
+ sunos4*)
+ if test "x$host_vendor" = xsequent; then
+ # Use $CC to link under sequent, because it throws in some extra .o
+ # files that make .init and .fini sections work.
+ _LT_TAGVAR(archive_cmds, $1)='$CC -G ${wl}-h $soname -o $lib $libobjs $deplibs $compiler_flags'
+ else
+ _LT_TAGVAR(archive_cmds, $1)='$LD -assert pure-text -Bstatic -o $lib $libobjs $deplibs $linker_flags'
+ fi
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir'
+ _LT_TAGVAR(hardcode_direct, $1)=yes
+ _LT_TAGVAR(hardcode_minus_L, $1)=yes
+ _LT_TAGVAR(hardcode_shlibpath_var, $1)=no
+ ;;
+
+ sysv4)
+ case $host_vendor in
+ sni)
+ _LT_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'
+ _LT_TAGVAR(hardcode_direct, $1)=yes # is this really true???
+ ;;
+ siemens)
+ ## LD is ld it makes a PLAMLIB
+ ## CC just makes a GrossModule.
+ _LT_TAGVAR(archive_cmds, $1)='$LD -G -o $lib $libobjs $deplibs $linker_flags'
+ _LT_TAGVAR(reload_cmds, $1)='$CC -r -o $output$reload_objs'
+ _LT_TAGVAR(hardcode_direct, $1)=no
+ ;;
+ motorola)
+ _LT_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'
+ _LT_TAGVAR(hardcode_direct, $1)=no #Motorola manual says yes, but my tests say they lie
+ ;;
+ esac
+ runpath_var='LD_RUN_PATH'
+ _LT_TAGVAR(hardcode_shlibpath_var, $1)=no
+ ;;
+
+ sysv4.3*)
+ _LT_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'
+ _LT_TAGVAR(hardcode_shlibpath_var, $1)=no
+ _LT_TAGVAR(export_dynamic_flag_spec, $1)='-Bexport'
+ ;;
+
+ sysv4*MP*)
+ if test -d /usr/nec; then
+ _LT_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'
+ _LT_TAGVAR(hardcode_shlibpath_var, $1)=no
+ runpath_var=LD_RUN_PATH
+ hardcode_runpath_var=yes
+ _LT_TAGVAR(ld_shlibs, $1)=yes
+ fi
+ ;;
+
+ sysv4*uw2* | sysv5OpenUNIX* | sysv5UnixWare7.[[01]].[[10]]* | unixware7* | sco3.2v5.0.[[024]]*)
+ _LT_TAGVAR(no_undefined_flag, $1)='${wl}-z,text'
+ _LT_TAGVAR(archive_cmds_need_lc, $1)=no
+ _LT_TAGVAR(hardcode_shlibpath_var, $1)=no
+ runpath_var='LD_RUN_PATH'
+
+ if test "$GCC" = yes; then
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+ _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+ else
+ _LT_TAGVAR(archive_cmds, $1)='$CC -G ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+ _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -G ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+ fi
+ ;;
+
+ sysv5* | sco3.2v5* | sco5v6*)
+ # Note: We can NOT use -z defs as we might desire, because we do not
+ # link with -lc, and that would cause any symbols used from libc to
+ # always be unresolved, which means just about no library would
+ # ever link correctly. If we're not using GNU ld we use -z text
+ # though, which does catch some bad symbols but isn't as heavy-handed
+ # as -z defs.
+ _LT_TAGVAR(no_undefined_flag, $1)='${wl}-z,text'
+ _LT_TAGVAR(allow_undefined_flag, $1)='${wl}-z,nodefs'
+ _LT_TAGVAR(archive_cmds_need_lc, $1)=no
+ _LT_TAGVAR(hardcode_shlibpath_var, $1)=no
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-R,$libdir'
+ _LT_TAGVAR(hardcode_libdir_separator, $1)=':'
+ _LT_TAGVAR(link_all_deplibs, $1)=yes
+ _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-Bexport'
+ runpath_var='LD_RUN_PATH'
+
+ if test "$GCC" = yes; then
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+ _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+ else
+ _LT_TAGVAR(archive_cmds, $1)='$CC -G ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+ _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -G ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+ fi
+ ;;
+
+ uts4*)
+ _LT_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir'
+ _LT_TAGVAR(hardcode_shlibpath_var, $1)=no
+ ;;
+
+ *)
+ _LT_TAGVAR(ld_shlibs, $1)=no
+ ;;
+ esac
+
+ if test x$host_vendor = xsni; then
+ case $host in
+ sysv4 | sysv4.2uw2* | sysv4.3* | sysv5*)
+ _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-Blargedynsym'
+ ;;
+ esac
+ fi
+ fi
+])
+AC_MSG_RESULT([$_LT_TAGVAR(ld_shlibs, $1)])
+test "$_LT_TAGVAR(ld_shlibs, $1)" = no && can_build_shared=no
+
+_LT_TAGVAR(with_gnu_ld, $1)=$with_gnu_ld
+
+_LT_DECL([], [libext], [0], [Old archive suffix (normally "a")])dnl
+_LT_DECL([], [shrext_cmds], [1], [Shared library suffix (normally ".so")])dnl
+_LT_DECL([], [extract_expsyms_cmds], [2],
+ [The commands to extract the exported symbol list from a shared archive])
+
+#
+# Do we need to explicitly link libc?
+#
+case "x$_LT_TAGVAR(archive_cmds_need_lc, $1)" in
+x|xyes)
+ # Assume -lc should be added
+ _LT_TAGVAR(archive_cmds_need_lc, $1)=yes
+
+ if test "$enable_shared" = yes && test "$GCC" = yes; then
+ case $_LT_TAGVAR(archive_cmds, $1) in
+ *'~'*)
+ # FIXME: we may have to deal with multi-command sequences.
+ ;;
+ '$CC '*)
+ # Test whether the compiler implicitly links with -lc since on some
+ # systems, -lgcc has to come before -lc. If gcc already passes -lc
+ # to ld, don't add -lc before -lgcc.
+ AC_MSG_CHECKING([whether -lc should be explicitly linked in])
+ $RM conftest*
+ echo "$lt_simple_compile_test_code" > conftest.$ac_ext
+
+ if AC_TRY_EVAL(ac_compile) 2>conftest.err; then
+ soname=conftest
+ lib=conftest
+ libobjs=conftest.$ac_objext
+ deplibs=
+ wl=$_LT_TAGVAR(lt_prog_compiler_wl, $1)
+ pic_flag=$_LT_TAGVAR(lt_prog_compiler_pic, $1)
+ compiler_flags=-v
+ linker_flags=-v
+ verstring=
+ output_objdir=.
+ libname=conftest
+ lt_save_allow_undefined_flag=$_LT_TAGVAR(allow_undefined_flag, $1)
+ _LT_TAGVAR(allow_undefined_flag, $1)=
+ if AC_TRY_EVAL(_LT_TAGVAR(archive_cmds, $1) 2\>\&1 \| $GREP \" -lc \" \>/dev/null 2\>\&1)
+ then
+ _LT_TAGVAR(archive_cmds_need_lc, $1)=no
+ else
+ _LT_TAGVAR(archive_cmds_need_lc, $1)=yes
+ fi
+ _LT_TAGVAR(allow_undefined_flag, $1)=$lt_save_allow_undefined_flag
+ else
+ cat conftest.err 1>&5
+ fi
+ $RM conftest*
+ AC_MSG_RESULT([$_LT_TAGVAR(archive_cmds_need_lc, $1)])
+ ;;
+ esac
+ fi
+ ;;
+esac
+
+_LT_TAGDECL([build_libtool_need_lc], [archive_cmds_need_lc], [0],
+ [Whether or not to add -lc for building shared libraries])
+_LT_TAGDECL([allow_libtool_libs_with_static_runtimes],
+ [enable_shared_with_static_runtimes], [0],
+ [Whether or not to disallow shared libs when runtime libs are static])
+_LT_TAGDECL([], [export_dynamic_flag_spec], [1],
+ [Compiler flag to allow reflexive dlopens])
+_LT_TAGDECL([], [whole_archive_flag_spec], [1],
+ [Compiler flag to generate shared objects directly from archives])
+_LT_TAGDECL([], [compiler_needs_object], [1],
+ [Whether the compiler copes with passing no objects directly])
+_LT_TAGDECL([], [old_archive_from_new_cmds], [2],
+ [Create an old-style archive from a shared archive])
+_LT_TAGDECL([], [old_archive_from_expsyms_cmds], [2],
+ [Create a temporary old-style archive to link instead of a shared archive])
+_LT_TAGDECL([], [archive_cmds], [2], [Commands used to build a shared archive])
+_LT_TAGDECL([], [archive_expsym_cmds], [2])
+_LT_TAGDECL([], [module_cmds], [2],
+ [Commands used to build a loadable module if different from building
+ a shared archive.])
+_LT_TAGDECL([], [module_expsym_cmds], [2])
+_LT_TAGDECL([], [with_gnu_ld], [1],
+ [Whether we are building with GNU ld or not])
+_LT_TAGDECL([], [allow_undefined_flag], [1],
+ [Flag that allows shared libraries with undefined symbols to be built])
+_LT_TAGDECL([], [no_undefined_flag], [1],
+ [Flag that enforces no undefined symbols])
+_LT_TAGDECL([], [hardcode_libdir_flag_spec], [1],
+ [Flag to hardcode $libdir into a binary during linking.
+ This must work even if $libdir does not exist])
+_LT_TAGDECL([], [hardcode_libdir_flag_spec_ld], [1],
+ [[If ld is used when linking, flag to hardcode $libdir into a binary
+ during linking. This must work even if $libdir does not exist]])
+_LT_TAGDECL([], [hardcode_libdir_separator], [1],
+ [Whether we need a single "-rpath" flag with a separated argument])
+_LT_TAGDECL([], [hardcode_direct], [0],
+ [Set to "yes" if using DIR/libNAME${shared_ext} during linking hardcodes
+ DIR into the resulting binary])
+_LT_TAGDECL([], [hardcode_direct_absolute], [0],
+ [Set to "yes" if using DIR/libNAME${shared_ext} during linking hardcodes
+ DIR into the resulting binary and the resulting library dependency is
+ "absolute", i.e impossible to change by setting ${shlibpath_var} if the
+ library is relocated])
+_LT_TAGDECL([], [hardcode_minus_L], [0],
+ [Set to "yes" if using the -LDIR flag during linking hardcodes DIR
+ into the resulting binary])
+_LT_TAGDECL([], [hardcode_shlibpath_var], [0],
+ [Set to "yes" if using SHLIBPATH_VAR=DIR during linking hardcodes DIR
+ into the resulting binary])
+_LT_TAGDECL([], [hardcode_automatic], [0],
+ [Set to "yes" if building a shared library automatically hardcodes DIR
+ into the library and all subsequent libraries and executables linked
+ against it])
+_LT_TAGDECL([], [inherit_rpath], [0],
+ [Set to yes if linker adds runtime paths of dependent libraries
+ to runtime path list])
+_LT_TAGDECL([], [link_all_deplibs], [0],
+ [Whether libtool must link a program against all its dependency libraries])
+_LT_TAGDECL([], [fix_srcfile_path], [1],
+ [Fix the shell variable $srcfile for the compiler])
+_LT_TAGDECL([], [always_export_symbols], [0],
+ [Set to "yes" if exported symbols are required])
+_LT_TAGDECL([], [export_symbols_cmds], [2],
+ [The commands to list exported symbols])
+_LT_TAGDECL([], [exclude_expsyms], [1],
+ [Symbols that should not be listed in the preloaded symbols])
+_LT_TAGDECL([], [include_expsyms], [1],
+ [Symbols that must always be exported])
+_LT_TAGDECL([], [prelink_cmds], [2],
+ [Commands necessary for linking programs (against libraries) with templates])
+_LT_TAGDECL([], [file_list_spec], [1],
+ [Specify filename containing input files])
+dnl FIXME: Not yet implemented
+dnl _LT_TAGDECL([], [thread_safe_flag_spec], [1],
+dnl [Compiler flag to generate thread safe objects])
+])# _LT_LINKER_SHLIBS
+
+
+# _LT_LANG_C_CONFIG([TAG])
+# ------------------------
+# Ensure that the configuration variables for a C compiler are suitably
+# defined. These variables are subsequently used by _LT_CONFIG to write
+# the compiler configuration to `libtool'.
+m4_defun([_LT_LANG_C_CONFIG],
+[m4_require([_LT_DECL_EGREP])dnl
+lt_save_CC="$CC"
+AC_LANG_PUSH(C)
+
+# Source file extension for C test sources.
+ac_ext=c
+
+# Object file extension for compiled C test sources.
+objext=o
+_LT_TAGVAR(objext, $1)=$objext
+
+# Code to be used in simple compile tests
+lt_simple_compile_test_code="int some_variable = 0;"
+
+# Code to be used in simple link tests
+lt_simple_link_test_code='int main(){return(0);}'
+
+_LT_TAG_COMPILER
+# Save the default compiler, since it gets overwritten when the other
+# tags are being tested, and _LT_TAGVAR(compiler, []) is a NOP.
+compiler_DEFAULT=$CC
+
+# save warnings/boilerplate of simple test code
+_LT_COMPILER_BOILERPLATE
+_LT_LINKER_BOILERPLATE
+
+if test -n "$compiler"; then
+ _LT_COMPILER_NO_RTTI($1)
+ _LT_COMPILER_PIC($1)
+ _LT_COMPILER_C_O($1)
+ _LT_COMPILER_FILE_LOCKS($1)
+ _LT_LINKER_SHLIBS($1)
+ _LT_SYS_DYNAMIC_LINKER($1)
+ _LT_LINKER_HARDCODE_LIBPATH($1)
+ LT_SYS_DLOPEN_SELF
+ _LT_CMD_STRIPLIB
+
+ # Report which library types will actually be built
+ AC_MSG_CHECKING([if libtool supports shared libraries])
+ AC_MSG_RESULT([$can_build_shared])
+
+ AC_MSG_CHECKING([whether to build shared libraries])
+ test "$can_build_shared" = "no" && enable_shared=no
+
+ # On AIX, shared libraries and static libraries use the same namespace, and
+ # are all built from PIC.
+ case $host_os in
+ aix3*)
+ test "$enable_shared" = yes && enable_static=no
+ if test -n "$RANLIB"; then
+ archive_cmds="$archive_cmds~\$RANLIB \$lib"
+ postinstall_cmds='$RANLIB $lib'
+ fi
+ ;;
+
+ aix[[4-9]]*)
+ if test "$host_cpu" != ia64 && test "$aix_use_runtimelinking" = no ; then
+ test "$enable_shared" = yes && enable_static=no
+ fi
+ ;;
+ esac
+ AC_MSG_RESULT([$enable_shared])
+
+ AC_MSG_CHECKING([whether to build static libraries])
+ # Make sure either enable_shared or enable_static is yes.
+ test "$enable_shared" = yes || enable_static=yes
+ AC_MSG_RESULT([$enable_static])
+
+ _LT_CONFIG($1)
+fi
+AC_LANG_POP
+CC="$lt_save_CC"
+])# _LT_LANG_C_CONFIG
+
+
+# _LT_PROG_CXX
+# ------------
+# Since AC_PROG_CXX is broken, in that it returns g++ if there is no c++
+# compiler, we have our own version here.
+m4_defun([_LT_PROG_CXX],
+[
+pushdef([AC_MSG_ERROR], [_lt_caught_CXX_error=yes])
+AC_PROG_CXX
+if test -n "$CXX" && ( test "X$CXX" != "Xno" &&
+ ( (test "X$CXX" = "Xg++" && `g++ -v >/dev/null 2>&1` ) ||
+ (test "X$CXX" != "Xg++"))) ; then
+ AC_PROG_CXXCPP
+else
+ _lt_caught_CXX_error=yes
+fi
+popdef([AC_MSG_ERROR])
+])# _LT_PROG_CXX
+
+dnl aclocal-1.4 backwards compatibility:
+dnl AC_DEFUN([_LT_PROG_CXX], [])
+
+
+# _LT_LANG_CXX_CONFIG([TAG])
+# --------------------------
+# Ensure that the configuration variables for a C++ compiler are suitably
+# defined. These variables are subsequently used by _LT_CONFIG to write
+# the compiler configuration to `libtool'.
+m4_defun([_LT_LANG_CXX_CONFIG],
+[AC_REQUIRE([_LT_PROG_CXX])dnl
+m4_require([_LT_FILEUTILS_DEFAULTS])dnl
+m4_require([_LT_DECL_EGREP])dnl
+
+AC_LANG_PUSH(C++)
+_LT_TAGVAR(archive_cmds_need_lc, $1)=no
+_LT_TAGVAR(allow_undefined_flag, $1)=
+_LT_TAGVAR(always_export_symbols, $1)=no
+_LT_TAGVAR(archive_expsym_cmds, $1)=
+_LT_TAGVAR(compiler_needs_object, $1)=no
+_LT_TAGVAR(export_dynamic_flag_spec, $1)=
+_LT_TAGVAR(hardcode_direct, $1)=no
+_LT_TAGVAR(hardcode_direct_absolute, $1)=no
+_LT_TAGVAR(hardcode_libdir_flag_spec, $1)=
+_LT_TAGVAR(hardcode_libdir_flag_spec_ld, $1)=
+_LT_TAGVAR(hardcode_libdir_separator, $1)=
+_LT_TAGVAR(hardcode_minus_L, $1)=no
+_LT_TAGVAR(hardcode_shlibpath_var, $1)=unsupported
+_LT_TAGVAR(hardcode_automatic, $1)=no
+_LT_TAGVAR(inherit_rpath, $1)=no
+_LT_TAGVAR(module_cmds, $1)=
+_LT_TAGVAR(module_expsym_cmds, $1)=
+_LT_TAGVAR(link_all_deplibs, $1)=unknown
+_LT_TAGVAR(old_archive_cmds, $1)=$old_archive_cmds
+_LT_TAGVAR(no_undefined_flag, $1)=
+_LT_TAGVAR(whole_archive_flag_spec, $1)=
+_LT_TAGVAR(enable_shared_with_static_runtimes, $1)=no
+
+# Source file extension for C++ test sources.
+ac_ext=cpp
+
+# Object file extension for compiled C++ test sources.
+objext=o
+_LT_TAGVAR(objext, $1)=$objext
+
+# No sense in running all these tests if we already determined that
+# the CXX compiler isn't working. Some variables (like enable_shared)
+# are currently assumed to apply to all compilers on this platform,
+# and will be corrupted by setting them based on a non-working compiler.
+if test "$_lt_caught_CXX_error" != yes; then
+ # Code to be used in simple compile tests
+ lt_simple_compile_test_code="int some_variable = 0;"
+
+ # Code to be used in simple link tests
+ lt_simple_link_test_code='int main(int, char *[[]]) { return(0); }'
+
+ # ltmain only uses $CC for tagged configurations so make sure $CC is set.
+ _LT_TAG_COMPILER
+
+ # save warnings/boilerplate of simple test code
+ _LT_COMPILER_BOILERPLATE
+ _LT_LINKER_BOILERPLATE
+
+ # Allow CC to be a program name with arguments.
+ lt_save_CC=$CC
+ lt_save_LD=$LD
+ lt_save_GCC=$GCC
+ GCC=$GXX
+ lt_save_with_gnu_ld=$with_gnu_ld
+ lt_save_path_LD=$lt_cv_path_LD
+ if test -n "${lt_cv_prog_gnu_ldcxx+set}"; then
+ lt_cv_prog_gnu_ld=$lt_cv_prog_gnu_ldcxx
+ else
+ $as_unset lt_cv_prog_gnu_ld
+ fi
+ if test -n "${lt_cv_path_LDCXX+set}"; then
+ lt_cv_path_LD=$lt_cv_path_LDCXX
+ else
+ $as_unset lt_cv_path_LD
+ fi
+ test -z "${LDCXX+set}" || LD=$LDCXX
+ CC=${CXX-"c++"}
+ compiler=$CC
+ _LT_TAGVAR(compiler, $1)=$CC
+ _LT_CC_BASENAME([$compiler])
+
+ if test -n "$compiler"; then
+ # We don't want -fno-exception when compiling C++ code, so set the
+ # no_builtin_flag separately
+ if test "$GXX" = yes; then
+ _LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)=' -fno-builtin'
+ else
+ _LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)=
+ fi
+
+ if test "$GXX" = yes; then
+ # Set up default GNU C++ configuration
+
+ LT_PATH_LD
+
+ # Check if GNU C++ uses GNU ld as the underlying linker, since the
+ # archiving commands below assume that GNU ld is being used.
+ if test "$with_gnu_ld" = yes; then
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname -o $lib'
+ _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib'
+
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir'
+ _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}--export-dynamic'
+
+ # If archive_cmds runs LD, not CC, wlarc should be empty
+ # XXX I think wlarc can be eliminated in ltcf-cxx, but I need to
+ # investigate it a little bit more. (MM)
+ wlarc='${wl}'
+
+ # ancient GNU ld didn't support --whole-archive et. al.
+ if eval "`$CC -print-prog-name=ld` --help 2>&1" |
+ $GREP 'no-whole-archive' > /dev/null; then
+ _LT_TAGVAR(whole_archive_flag_spec, $1)="$wlarc"'--whole-archive$convenience '"$wlarc"'--no-whole-archive'
+ else
+ _LT_TAGVAR(whole_archive_flag_spec, $1)=
+ fi
+ else
+ with_gnu_ld=no
+ wlarc=
+
+ # A generic and very simple default shared library creation
+ # command for GNU C++ for the case where it uses the native
+ # linker, instead of GNU ld. If possible, this setting should
+ # overridden to take advantage of the native linker features on
+ # the platform it is being used on.
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $lib'
+ fi
+
+ # Commands to make compiler produce verbose output that lists
+ # what "hidden" libraries, object files and flags are used when
+ # linking a shared library.
+ output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP "\-L"'
+
+ else
+ GXX=no
+ with_gnu_ld=no
+ wlarc=
+ fi
+
+ # PORTME: fill in a description of your system's C++ link characteristics
+ AC_MSG_CHECKING([whether the $compiler linker ($LD) supports shared libraries])
+ _LT_TAGVAR(ld_shlibs, $1)=yes
+ case $host_os in
+ aix3*)
+ # FIXME: insert proper C++ library support
+ _LT_TAGVAR(ld_shlibs, $1)=no
+ ;;
+ aix[[4-9]]*)
+ if test "$host_cpu" = ia64; then
+ # On IA64, the linker does run time linking by default, so we don't
+ # have to do anything special.
+ aix_use_runtimelinking=no
+ exp_sym_flag='-Bexport'
+ no_entry_flag=""
+ else
+ aix_use_runtimelinking=no
+
+ # Test if we are trying to use run time linking or normal
+ # AIX style linking. If -brtl is somewhere in LDFLAGS, we
+ # need to do runtime linking.
+ case $host_os in aix4.[[23]]|aix4.[[23]].*|aix[[5-9]]*)
+ for ld_flag in $LDFLAGS; do
+ case $ld_flag in
+ *-brtl*)
+ aix_use_runtimelinking=yes
+ break
+ ;;
+ esac
+ done
+ ;;
+ esac
+
+ exp_sym_flag='-bexport'
+ no_entry_flag='-bnoentry'
+ fi
+
+ # When large executables or shared objects are built, AIX ld can
+ # have problems creating the table of contents. If linking a library
+ # or program results in "error TOC overflow" add -mminimal-toc to
+ # CXXFLAGS/CFLAGS for g++/gcc. In the cases where that is not
+ # enough to fix the problem, add -Wl,-bbigtoc to LDFLAGS.
+
+ _LT_TAGVAR(archive_cmds, $1)=''
+ _LT_TAGVAR(hardcode_direct, $1)=yes
+ _LT_TAGVAR(hardcode_direct_absolute, $1)=yes
+ _LT_TAGVAR(hardcode_libdir_separator, $1)=':'
+ _LT_TAGVAR(link_all_deplibs, $1)=yes
+ _LT_TAGVAR(file_list_spec, $1)='${wl}-f,'
+
+ if test "$GXX" = yes; then
+ case $host_os in aix4.[[012]]|aix4.[[012]].*)
+ # We only want to do this on AIX 4.2 and lower, the check
+ # below for broken collect2 doesn't work under 4.3+
+ collect2name=`${CC} -print-prog-name=collect2`
+ if test -f "$collect2name" &&
+ strings "$collect2name" | $GREP resolve_lib_name >/dev/null
+ then
+ # We have reworked collect2
+ :
+ else
+ # We have old collect2
+ _LT_TAGVAR(hardcode_direct, $1)=unsupported
+ # It fails to find uninstalled libraries when the uninstalled
+ # path is not listed in the libpath. Setting hardcode_minus_L
+ # to unsupported forces relinking
+ _LT_TAGVAR(hardcode_minus_L, $1)=yes
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir'
+ _LT_TAGVAR(hardcode_libdir_separator, $1)=
+ fi
+ esac
+ shared_flag='-shared'
+ if test "$aix_use_runtimelinking" = yes; then
+ shared_flag="$shared_flag "'${wl}-G'
+ fi
+ else
+ # not using gcc
+ if test "$host_cpu" = ia64; then
+ # VisualAge C++, Version 5.5 for AIX 5L for IA-64, Beta 3 Release
+ # chokes on -Wl,-G. The following line is correct:
+ shared_flag='-G'
+ else
+ if test "$aix_use_runtimelinking" = yes; then
+ shared_flag='${wl}-G'
+ else
+ shared_flag='${wl}-bM:SRE'
+ fi
+ fi
+ fi
+
+ _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-bexpall'
+ # It seems that -bexpall does not export symbols beginning with
+ # underscore (_), so it is better to generate a list of symbols to
+ # export.
+ _LT_TAGVAR(always_export_symbols, $1)=yes
+ if test "$aix_use_runtimelinking" = yes; then
+ # Warning - without using the other runtime loading flags (-brtl),
+ # -berok will link without error, but may produce a broken library.
+ _LT_TAGVAR(allow_undefined_flag, $1)='-berok'
+ # Determine the default libpath from the value encoded in an empty
+ # executable.
+ _LT_SYS_MODULE_PATH_AIX
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-blibpath:$libdir:'"$aix_libpath"
+
+ _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -o $output_objdir/$soname $libobjs $deplibs '"\${wl}$no_entry_flag"' $compiler_flags `if test "x${allow_undefined_flag}" != "x"; then $ECHO "X${wl}${allow_undefined_flag}" | $Xsed; else :; fi` '"\${wl}$exp_sym_flag:\$export_symbols $shared_flag"
+ else
+ if test "$host_cpu" = ia64; then
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-R $libdir:/usr/lib:/lib'
+ _LT_TAGVAR(allow_undefined_flag, $1)="-z nodefs"
+ _LT_TAGVAR(archive_expsym_cmds, $1)="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs '"\${wl}$no_entry_flag"' $compiler_flags ${wl}${allow_undefined_flag} '"\${wl}$exp_sym_flag:\$export_symbols"
+ else
+ # Determine the default libpath from the value encoded in an
+ # empty executable.
+ _LT_SYS_MODULE_PATH_AIX
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-blibpath:$libdir:'"$aix_libpath"
+ # Warning - without using the other run time loading flags,
+ # -berok will link without error, but may produce a broken library.
+ _LT_TAGVAR(no_undefined_flag, $1)=' ${wl}-bernotok'
+ _LT_TAGVAR(allow_undefined_flag, $1)=' ${wl}-berok'
+ # Exported symbols can be pulled into shared objects from archives
+ _LT_TAGVAR(whole_archive_flag_spec, $1)='$convenience'
+ _LT_TAGVAR(archive_cmds_need_lc, $1)=yes
+ # This is similar to how AIX traditionally builds its shared
+ # libraries.
+ _LT_TAGVAR(archive_expsym_cmds, $1)="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs ${wl}-bnoentry $compiler_flags ${wl}-bE:$export_symbols${allow_undefined_flag}~$AR $AR_FLAGS $output_objdir/$libname$release.a $output_objdir/$soname'
+ fi
+ fi
+ ;;
+
+ beos*)
+ if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then
+ _LT_TAGVAR(allow_undefined_flag, $1)=unsupported
+ # Joseph Beckenbach <jrb3@best.com> says some releases of gcc
+ # support --undefined. This deserves some investigation. FIXME
+ _LT_TAGVAR(archive_cmds, $1)='$CC -nostart $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
+ else
+ _LT_TAGVAR(ld_shlibs, $1)=no
+ fi
+ ;;
+
+ chorus*)
+ case $cc_basename in
+ *)
+ # FIXME: insert proper C++ library support
+ _LT_TAGVAR(ld_shlibs, $1)=no
+ ;;
+ esac
+ ;;
+
+ cygwin* | mingw* | pw32* | cegcc*)
+ # _LT_TAGVAR(hardcode_libdir_flag_spec, $1) is actually meaningless,
+ # as there is no search path for DLLs.
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir'
+ _LT_TAGVAR(allow_undefined_flag, $1)=unsupported
+ _LT_TAGVAR(always_export_symbols, $1)=no
+ _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=yes
+
+ if $LD --help 2>&1 | $GREP 'auto-import' > /dev/null; then
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib'
+ # If the export-symbols file already is a .def file (1st line
+ # is EXPORTS), use it as is; otherwise, prepend...
+ _LT_TAGVAR(archive_expsym_cmds, $1)='if test "x`$SED 1q $export_symbols`" = xEXPORTS; then
+ cp $export_symbols $output_objdir/$soname.def;
+ else
+ echo EXPORTS > $output_objdir/$soname.def;
+ cat $export_symbols >> $output_objdir/$soname.def;
+ fi~
+ $CC -shared -nostdlib $output_objdir/$soname.def $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib'
+ else
+ _LT_TAGVAR(ld_shlibs, $1)=no
+ fi
+ ;;
+ darwin* | rhapsody*)
+ _LT_DARWIN_LINKER_FEATURES($1)
+ ;;
+
+ dgux*)
+ case $cc_basename in
+ ec++*)
+ # FIXME: insert proper C++ library support
+ _LT_TAGVAR(ld_shlibs, $1)=no
+ ;;
+ ghcx*)
+ # Green Hills C++ Compiler
+ # FIXME: insert proper C++ library support
+ _LT_TAGVAR(ld_shlibs, $1)=no
+ ;;
+ *)
+ # FIXME: insert proper C++ library support
+ _LT_TAGVAR(ld_shlibs, $1)=no
+ ;;
+ esac
+ ;;
+
+ freebsd[[12]]*)
+ # C++ shared libraries reported to be fairly broken before
+ # switch to ELF
+ _LT_TAGVAR(ld_shlibs, $1)=no
+ ;;
+
+ freebsd-elf*)
+ _LT_TAGVAR(archive_cmds_need_lc, $1)=no
+ ;;
+
+ freebsd* | dragonfly*)
+ # FreeBSD 3 and later use GNU C++ and GNU ld with standard ELF
+ # conventions
+ _LT_TAGVAR(ld_shlibs, $1)=yes
+ ;;
+
+ gnu*)
+ ;;
+
+ hpux9*)
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}+b ${wl}$libdir'
+ _LT_TAGVAR(hardcode_libdir_separator, $1)=:
+ _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E'
+ _LT_TAGVAR(hardcode_direct, $1)=yes
+ _LT_TAGVAR(hardcode_minus_L, $1)=yes # Not in the search PATH,
+ # but as the default
+ # location of the library.
+
+ case $cc_basename in
+ CC*)
+ # FIXME: insert proper C++ library support
+ _LT_TAGVAR(ld_shlibs, $1)=no
+ ;;
+ aCC*)
+ _LT_TAGVAR(archive_cmds, $1)='$RM $output_objdir/$soname~$CC -b ${wl}+b ${wl}$install_libdir -o $output_objdir/$soname $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib'
+ # Commands to make compiler produce verbose output that lists
+ # what "hidden" libraries, object files and flags are used when
+ # linking a shared library.
+ #
+ # There doesn't appear to be a way to prevent this compiler from
+ # explicitly linking system object files so we need to strip them
+ # from the output so that they don't get included in the library
+ # dependencies.
+ output_verbose_link_cmd='templist=`($CC -b $CFLAGS -v conftest.$objext 2>&1) | $EGREP "\-L"`; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; $ECHO "X$list" | $Xsed'
+ ;;
+ *)
+ if test "$GXX" = yes; then
+ _LT_TAGVAR(archive_cmds, $1)='$RM $output_objdir/$soname~$CC -shared -nostdlib -fPIC ${wl}+b ${wl}$install_libdir -o $output_objdir/$soname $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib'
+ else
+ # FIXME: insert proper C++ library support
+ _LT_TAGVAR(ld_shlibs, $1)=no
+ fi
+ ;;
+ esac
+ ;;
+
+ hpux10*|hpux11*)
+ if test $with_gnu_ld = no; then
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}+b ${wl}$libdir'
+ _LT_TAGVAR(hardcode_libdir_separator, $1)=:
+
+ case $host_cpu in
+ hppa*64*|ia64*)
+ ;;
+ *)
+ _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E'
+ ;;
+ esac
+ fi
+ case $host_cpu in
+ hppa*64*|ia64*)
+ _LT_TAGVAR(hardcode_direct, $1)=no
+ _LT_TAGVAR(hardcode_shlibpath_var, $1)=no
+ ;;
+ *)
+ _LT_TAGVAR(hardcode_direct, $1)=yes
+ _LT_TAGVAR(hardcode_direct_absolute, $1)=yes
+ _LT_TAGVAR(hardcode_minus_L, $1)=yes # Not in the search PATH,
+ # but as the default
+ # location of the library.
+ ;;
+ esac
+
+ case $cc_basename in
+ CC*)
+ # FIXME: insert proper C++ library support
+ _LT_TAGVAR(ld_shlibs, $1)=no
+ ;;
+ aCC*)
+ case $host_cpu in
+ hppa*64*)
+ _LT_TAGVAR(archive_cmds, $1)='$CC -b ${wl}+h ${wl}$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags'
+ ;;
+ ia64*)
+ _LT_TAGVAR(archive_cmds, $1)='$CC -b ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags'
+ ;;
+ *)
+ _LT_TAGVAR(archive_cmds, $1)='$CC -b ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags'
+ ;;
+ esac
+ # Commands to make compiler produce verbose output that lists
+ # what "hidden" libraries, object files and flags are used when
+ # linking a shared library.
+ #
+ # There doesn't appear to be a way to prevent this compiler from
+ # explicitly linking system object files so we need to strip them
+ # from the output so that they don't get included in the library
+ # dependencies.
+ output_verbose_link_cmd='templist=`($CC -b $CFLAGS -v conftest.$objext 2>&1) | $GREP "\-L"`; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; $ECHO "X$list" | $Xsed'
+ ;;
+ *)
+ if test "$GXX" = yes; then
+ if test $with_gnu_ld = no; then
+ case $host_cpu in
+ hppa*64*)
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib -fPIC ${wl}+h ${wl}$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags'
+ ;;
+ ia64*)
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib -fPIC ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags'
+ ;;
+ *)
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib -fPIC ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags'
+ ;;
+ esac
+ fi
+ else
+ # FIXME: insert proper C++ library support
+ _LT_TAGVAR(ld_shlibs, $1)=no
+ fi
+ ;;
+ esac
+ ;;
+
+ interix[[3-9]]*)
+ _LT_TAGVAR(hardcode_direct, $1)=no
+ _LT_TAGVAR(hardcode_shlibpath_var, $1)=no
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir'
+ _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E'
+ # Hack: On Interix 3.x, we cannot compile PIC because of a broken gcc.
+ # Instead, shared libraries are loaded at an image base (0x10000000 by
+ # default) and relocated if they conflict, which is a slow very memory
+ # consuming and fragmenting process. To avoid this, we pick a random,
+ # 256 KiB-aligned image base between 0x50000000 and 0x6FFC0000 at link
+ # time. Moving up from 0x10000000 also allows more sbrk(2) space.
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-h,$soname ${wl}--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib'
+ _LT_TAGVAR(archive_expsym_cmds, $1)='sed "s,^,_," $export_symbols >$output_objdir/$soname.expsym~$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-h,$soname ${wl}--retain-symbols-file,$output_objdir/$soname.expsym ${wl}--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib'
+ ;;
+ irix5* | irix6*)
+ case $cc_basename in
+ CC*)
+ # SGI C++
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared -all -multigot $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -soname $soname `test -n "$verstring" && $ECHO "X-set_version $verstring" | $Xsed` -update_registry ${output_objdir}/so_locations -o $lib'
+
+ # Archives containing C++ object files must be created using
+ # "CC -ar", where "CC" is the IRIX C++ compiler. This is
+ # necessary to make sure instantiated templates are included
+ # in the archive.
+ _LT_TAGVAR(old_archive_cmds, $1)='$CC -ar -WR,-u -o $oldlib $oldobjs'
+ ;;
+ *)
+ if test "$GXX" = yes; then
+ if test "$with_gnu_ld" = no; then
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && $ECHO "X${wl}-set_version ${wl}$verstring" | $Xsed` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib'
+ else
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && $ECHO "X${wl}-set_version ${wl}$verstring" | $Xsed` -o $lib'
+ fi
+ fi
+ _LT_TAGVAR(link_all_deplibs, $1)=yes
+ ;;
+ esac
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir'
+ _LT_TAGVAR(hardcode_libdir_separator, $1)=:
+ _LT_TAGVAR(inherit_rpath, $1)=yes
+ ;;
+
+ linux* | k*bsd*-gnu | kopensolaris*-gnu)
+ case $cc_basename in
+ KCC*)
+ # Kuck and Associates, Inc. (KAI) C++ Compiler
+
+ # KCC will only create a shared library if the output file
+ # ends with ".so" (or ".sl" for HP-UX), so rename the library
+ # to its proper name (with version) after linking.
+ _LT_TAGVAR(archive_cmds, $1)='tempext=`echo $shared_ext | $SED -e '\''s/\([[^()0-9A-Za-z{}]]\)/\\\\\1/g'\''`; templib=`echo $lib | $SED -e "s/\${tempext}\..*/.so/"`; $CC $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags --soname $soname -o \$templib; mv \$templib $lib'
+ _LT_TAGVAR(archive_expsym_cmds, $1)='tempext=`echo $shared_ext | $SED -e '\''s/\([[^()0-9A-Za-z{}]]\)/\\\\\1/g'\''`; templib=`echo $lib | $SED -e "s/\${tempext}\..*/.so/"`; $CC $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags --soname $soname -o \$templib ${wl}-retain-symbols-file,$export_symbols; mv \$templib $lib'
+ # Commands to make compiler produce verbose output that lists
+ # what "hidden" libraries, object files and flags are used when
+ # linking a shared library.
+ #
+ # There doesn't appear to be a way to prevent this compiler from
+ # explicitly linking system object files so we need to strip them
+ # from the output so that they don't get included in the library
+ # dependencies.
+ output_verbose_link_cmd='templist=`$CC $CFLAGS -v conftest.$objext -o libconftest$shared_ext 2>&1 | $GREP "ld"`; rm -f libconftest$shared_ext; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; $ECHO "X$list" | $Xsed'
+
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir'
+ _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}--export-dynamic'
+
+ # Archives containing C++ object files must be created using
+ # "CC -Bstatic", where "CC" is the KAI C++ compiler.
+ _LT_TAGVAR(old_archive_cmds, $1)='$CC -Bstatic -o $oldlib $oldobjs'
+ ;;
+ icpc* | ecpc* )
+ # Intel C++
+ with_gnu_ld=yes
+ # version 8.0 and above of icpc choke on multiply defined symbols
+ # if we add $predep_objects and $postdep_objects, however 7.1 and
+ # earlier do not add the objects themselves.
+ case `$CC -V 2>&1` in
+ *"Version 7."*)
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname -o $lib'
+ _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib'
+ ;;
+ *) # Version 8.0 or newer
+ tmp_idyn=
+ case $host_cpu in
+ ia64*) tmp_idyn=' -i_dynamic';;
+ esac
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared'"$tmp_idyn"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
+ _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared'"$tmp_idyn"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib'
+ ;;
+ esac
+ _LT_TAGVAR(archive_cmds_need_lc, $1)=no
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir'
+ _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}--export-dynamic'
+ _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive$convenience ${wl}--no-whole-archive'
+ ;;
+ pgCC* | pgcpp*)
+ # Portland Group C++ compiler
+ case `$CC -V` in
+ *pgCC\ [[1-5]]* | *pgcpp\ [[1-5]]*)
+ _LT_TAGVAR(prelink_cmds, $1)='tpldir=Template.dir~
+ rm -rf $tpldir~
+ $CC --prelink_objects --instantiation_dir $tpldir $objs $libobjs $compile_deplibs~
+ compile_command="$compile_command `find $tpldir -name \*.o | $NL2SP`"'
+ _LT_TAGVAR(old_archive_cmds, $1)='tpldir=Template.dir~
+ rm -rf $tpldir~
+ $CC --prelink_objects --instantiation_dir $tpldir $oldobjs$old_deplibs~
+ $AR $AR_FLAGS $oldlib$oldobjs$old_deplibs `find $tpldir -name \*.o | $NL2SP`~
+ $RANLIB $oldlib'
+ _LT_TAGVAR(archive_cmds, $1)='tpldir=Template.dir~
+ rm -rf $tpldir~
+ $CC --prelink_objects --instantiation_dir $tpldir $predep_objects $libobjs $deplibs $convenience $postdep_objects~
+ $CC -shared $pic_flag $predep_objects $libobjs $deplibs `find $tpldir -name \*.o | $NL2SP` $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname -o $lib'
+ _LT_TAGVAR(archive_expsym_cmds, $1)='tpldir=Template.dir~
+ rm -rf $tpldir~
+ $CC --prelink_objects --instantiation_dir $tpldir $predep_objects $libobjs $deplibs $convenience $postdep_objects~
+ $CC -shared $pic_flag $predep_objects $libobjs $deplibs `find $tpldir -name \*.o | $NL2SP` $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname ${wl}-retain-symbols-file ${wl}$export_symbols -o $lib'
+ ;;
+ *) # Version 6 will use weak symbols
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname -o $lib'
+ _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname ${wl}-retain-symbols-file ${wl}$export_symbols -o $lib'
+ ;;
+ esac
+
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}--rpath ${wl}$libdir'
+ _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}--export-dynamic'
+ _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; $ECHO \"$new_convenience\"` ${wl}--no-whole-archive'
+ ;;
+ cxx*)
+ # Compaq C++
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname -o $lib'
+ _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname -o $lib ${wl}-retain-symbols-file $wl$export_symbols'
+
+ runpath_var=LD_RUN_PATH
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-rpath $libdir'
+ _LT_TAGVAR(hardcode_libdir_separator, $1)=:
+
+ # Commands to make compiler produce verbose output that lists
+ # what "hidden" libraries, object files and flags are used when
+ # linking a shared library.
+ #
+ # There doesn't appear to be a way to prevent this compiler from
+ # explicitly linking system object files so we need to strip them
+ # from the output so that they don't get included in the library
+ # dependencies.
+ output_verbose_link_cmd='templist=`$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP "ld"`; templist=`$ECHO "X$templist" | $Xsed -e "s/\(^.*ld.*\)\( .*ld .*$\)/\1/"`; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; $ECHO "X$list" | $Xsed'
+ ;;
+ xl*)
+ # IBM XL 8.0 on PPC, with GNU ld
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir'
+ _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}--export-dynamic'
+ _LT_TAGVAR(archive_cmds, $1)='$CC -qmkshrobj $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
+ if test "x$supports_anon_versioning" = xyes; then
+ _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $output_objdir/$libname.ver~
+ cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~
+ echo "local: *; };" >> $output_objdir/$libname.ver~
+ $CC -qmkshrobj $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-version-script ${wl}$output_objdir/$libname.ver -o $lib'
+ fi
+ ;;
+ *)
+ case `$CC -V 2>&1 | sed 5q` in
+ *Sun\ C*)
+ # Sun C++ 5.9
+ _LT_TAGVAR(no_undefined_flag, $1)=' -zdefs'
+ _LT_TAGVAR(archive_cmds, $1)='$CC -G${allow_undefined_flag} -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags'
+ _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -G${allow_undefined_flag} -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-retain-symbols-file ${wl}$export_symbols'
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir'
+ _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive`new_convenience=; for conv in $convenience\"\"; do test -z \"$conv\" || new_convenience=\"$new_convenience,$conv\"; done; $ECHO \"$new_convenience\"` ${wl}--no-whole-archive'
+ _LT_TAGVAR(compiler_needs_object, $1)=yes
+
+ # Not sure whether something based on
+ # $CC $CFLAGS -v conftest.$objext -o libconftest$shared_ext 2>&1
+ # would be better.
+ output_verbose_link_cmd='echo'
+
+ # Archives containing C++ object files must be created using
+ # "CC -xar", where "CC" is the Sun C++ compiler. This is
+ # necessary to make sure instantiated templates are included
+ # in the archive.
+ _LT_TAGVAR(old_archive_cmds, $1)='$CC -xar -o $oldlib $oldobjs'
+ ;;
+ esac
+ ;;
+ esac
+ ;;
+
+ lynxos*)
+ # FIXME: insert proper C++ library support
+ _LT_TAGVAR(ld_shlibs, $1)=no
+ ;;
+
+ m88k*)
+ # FIXME: insert proper C++ library support
+ _LT_TAGVAR(ld_shlibs, $1)=no
+ ;;
+
+ mvs*)
+ case $cc_basename in
+ cxx*)
+ # FIXME: insert proper C++ library support
+ _LT_TAGVAR(ld_shlibs, $1)=no
+ ;;
+ *)
+ # FIXME: insert proper C++ library support
+ _LT_TAGVAR(ld_shlibs, $1)=no
+ ;;
+ esac
+ ;;
+
+ netbsd*)
+ if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then
+ _LT_TAGVAR(archive_cmds, $1)='$LD -Bshareable -o $lib $predep_objects $libobjs $deplibs $postdep_objects $linker_flags'
+ wlarc=
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir'
+ _LT_TAGVAR(hardcode_direct, $1)=yes
+ _LT_TAGVAR(hardcode_shlibpath_var, $1)=no
+ fi
+ # Workaround some broken pre-1.5 toolchains
+ output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP conftest.$objext | $SED -e "s:-lgcc -lc -lgcc::"'
+ ;;
+
+ *nto* | *qnx*)
+ _LT_TAGVAR(ld_shlibs, $1)=yes
+ ;;
+
+ openbsd2*)
+ # C++ shared libraries are fairly broken
+ _LT_TAGVAR(ld_shlibs, $1)=no
+ ;;
+
+ openbsd*)
+ if test -f /usr/libexec/ld.so; then
+ _LT_TAGVAR(hardcode_direct, $1)=yes
+ _LT_TAGVAR(hardcode_shlibpath_var, $1)=no
+ _LT_TAGVAR(hardcode_direct_absolute, $1)=yes
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $lib'
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir'
+ if test -z "`echo __ELF__ | $CC -E - | grep __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then
+ _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-retain-symbols-file,$export_symbols -o $lib'
+ _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E'
+ _LT_TAGVAR(whole_archive_flag_spec, $1)="$wlarc"'--whole-archive$convenience '"$wlarc"'--no-whole-archive'
+ fi
+ output_verbose_link_cmd=echo
+ else
+ _LT_TAGVAR(ld_shlibs, $1)=no
+ fi
+ ;;
+
+ osf3* | osf4* | osf5*)
+ case $cc_basename in
+ KCC*)
+ # Kuck and Associates, Inc. (KAI) C++ Compiler
+
+ # KCC will only create a shared library if the output file
+ # ends with ".so" (or ".sl" for HP-UX), so rename the library
+ # to its proper name (with version) after linking.
+ _LT_TAGVAR(archive_cmds, $1)='tempext=`echo $shared_ext | $SED -e '\''s/\([[^()0-9A-Za-z{}]]\)/\\\\\1/g'\''`; templib=`echo "$lib" | $SED -e "s/\${tempext}\..*/.so/"`; $CC $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags --soname $soname -o \$templib; mv \$templib $lib'
+
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir'
+ _LT_TAGVAR(hardcode_libdir_separator, $1)=:
+
+ # Archives containing C++ object files must be created using
+ # the KAI C++ compiler.
+ case $host in
+ osf3*) _LT_TAGVAR(old_archive_cmds, $1)='$CC -Bstatic -o $oldlib $oldobjs' ;;
+ *) _LT_TAGVAR(old_archive_cmds, $1)='$CC -o $oldlib $oldobjs' ;;
+ esac
+ ;;
+ RCC*)
+ # Rational C++ 2.4.1
+ # FIXME: insert proper C++ library support
+ _LT_TAGVAR(ld_shlibs, $1)=no
+ ;;
+ cxx*)
+ case $host in
+ osf3*)
+ _LT_TAGVAR(allow_undefined_flag, $1)=' ${wl}-expect_unresolved ${wl}\*'
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared${allow_undefined_flag} $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $soname `test -n "$verstring" && $ECHO "X${wl}-set_version $verstring" | $Xsed` -update_registry ${output_objdir}/so_locations -o $lib'
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir'
+ ;;
+ *)
+ _LT_TAGVAR(allow_undefined_flag, $1)=' -expect_unresolved \*'
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared${allow_undefined_flag} $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -msym -soname $soname `test -n "$verstring" && $ECHO "X-set_version $verstring" | $Xsed` -update_registry ${output_objdir}/so_locations -o $lib'
+ _LT_TAGVAR(archive_expsym_cmds, $1)='for i in `cat $export_symbols`; do printf "%s %s\\n" -exported_symbol "\$i" >> $lib.exp; done~
+ echo "-hidden">> $lib.exp~
+ $CC -shared$allow_undefined_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -msym -soname $soname ${wl}-input ${wl}$lib.exp `test -n "$verstring" && $ECHO "X-set_version $verstring" | $Xsed` -update_registry ${output_objdir}/so_locations -o $lib~
+ $RM $lib.exp'
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-rpath $libdir'
+ ;;
+ esac
+
+ _LT_TAGVAR(hardcode_libdir_separator, $1)=:
+
+ # Commands to make compiler produce verbose output that lists
+ # what "hidden" libraries, object files and flags are used when
+ # linking a shared library.
+ #
+ # There doesn't appear to be a way to prevent this compiler from
+ # explicitly linking system object files so we need to strip them
+ # from the output so that they don't get included in the library
+ # dependencies.
+ output_verbose_link_cmd='templist=`$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP "ld" | $GREP -v "ld:"`; templist=`$ECHO "X$templist" | $Xsed -e "s/\(^.*ld.*\)\( .*ld.*$\)/\1/"`; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; $ECHO "X$list" | $Xsed'
+ ;;
+ *)
+ if test "$GXX" = yes && test "$with_gnu_ld" = no; then
+ _LT_TAGVAR(allow_undefined_flag, $1)=' ${wl}-expect_unresolved ${wl}\*'
+ case $host in
+ osf3*)
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib ${allow_undefined_flag} $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && $ECHO "X${wl}-set_version ${wl}$verstring" | $Xsed` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib'
+ ;;
+ *)
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib ${allow_undefined_flag} $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-msym ${wl}-soname ${wl}$soname `test -n "$verstring" && $ECHO "${wl}-set_version ${wl}$verstring" | $Xsed` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib'
+ ;;
+ esac
+
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir'
+ _LT_TAGVAR(hardcode_libdir_separator, $1)=:
+
+ # Commands to make compiler produce verbose output that lists
+ # what "hidden" libraries, object files and flags are used when
+ # linking a shared library.
+ output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP "\-L"'
+
+ else
+ # FIXME: insert proper C++ library support
+ _LT_TAGVAR(ld_shlibs, $1)=no
+ fi
+ ;;
+ esac
+ ;;
+
+ psos*)
+ # FIXME: insert proper C++ library support
+ _LT_TAGVAR(ld_shlibs, $1)=no
+ ;;
+
+ sunos4*)
+ case $cc_basename in
+ CC*)
+ # Sun C++ 4.x
+ # FIXME: insert proper C++ library support
+ _LT_TAGVAR(ld_shlibs, $1)=no
+ ;;
+ lcc*)
+ # Lucid
+ # FIXME: insert proper C++ library support
+ _LT_TAGVAR(ld_shlibs, $1)=no
+ ;;
+ *)
+ # FIXME: insert proper C++ library support
+ _LT_TAGVAR(ld_shlibs, $1)=no
+ ;;
+ esac
+ ;;
+
+ solaris*)
+ case $cc_basename in
+ CC*)
+ # Sun C++ 4.2, 5.x and Centerline C++
+ _LT_TAGVAR(archive_cmds_need_lc,$1)=yes
+ _LT_TAGVAR(no_undefined_flag, $1)=' -zdefs'
+ _LT_TAGVAR(archive_cmds, $1)='$CC -G${allow_undefined_flag} -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags'
+ _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~
+ $CC -G${allow_undefined_flag} ${wl}-M ${wl}$lib.exp -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~$RM $lib.exp'
+
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir'
+ _LT_TAGVAR(hardcode_shlibpath_var, $1)=no
+ case $host_os in
+ solaris2.[[0-5]] | solaris2.[[0-5]].*) ;;
+ *)
+ # The compiler driver will combine and reorder linker options,
+ # but understands `-z linker_flag'.
+ # Supported since Solaris 2.6 (maybe 2.5.1?)
+ _LT_TAGVAR(whole_archive_flag_spec, $1)='-z allextract$convenience -z defaultextract'
+ ;;
+ esac
+ _LT_TAGVAR(link_all_deplibs, $1)=yes
+
+ output_verbose_link_cmd='echo'
+
+ # Archives containing C++ object files must be created using
+ # "CC -xar", where "CC" is the Sun C++ compiler. This is
+ # necessary to make sure instantiated templates are included
+ # in the archive.
+ _LT_TAGVAR(old_archive_cmds, $1)='$CC -xar -o $oldlib $oldobjs'
+ ;;
+ gcx*)
+ # Green Hills C++ Compiler
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-h $wl$soname -o $lib'
+
+ # The C++ compiler must be used to create the archive.
+ _LT_TAGVAR(old_archive_cmds, $1)='$CC $LDFLAGS -archive -o $oldlib $oldobjs'
+ ;;
+ *)
+ # GNU C++ compiler with Solaris linker
+ if test "$GXX" = yes && test "$with_gnu_ld" = no; then
+ _LT_TAGVAR(no_undefined_flag, $1)=' ${wl}-z ${wl}defs'
+ if $CC --version | $GREP -v '^2\.7' > /dev/null; then
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $LDFLAGS $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-h $wl$soname -o $lib'
+ _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~
+ $CC -shared -nostdlib ${wl}-M $wl$lib.exp -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~$RM $lib.exp'
+
+ # Commands to make compiler produce verbose output that lists
+ # what "hidden" libraries, object files and flags are used when
+ # linking a shared library.
+ output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP "\-L"'
+ else
+ # g++ 2.7 appears to require `-G' NOT `-shared' on this
+ # platform.
+ _LT_TAGVAR(archive_cmds, $1)='$CC -G -nostdlib $LDFLAGS $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-h $wl$soname -o $lib'
+ _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~
+ $CC -G -nostdlib ${wl}-M $wl$lib.exp -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~$RM $lib.exp'
+
+ # Commands to make compiler produce verbose output that lists
+ # what "hidden" libraries, object files and flags are used when
+ # linking a shared library.
+ output_verbose_link_cmd='$CC -G $CFLAGS -v conftest.$objext 2>&1 | $GREP "\-L"'
+ fi
+
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-R $wl$libdir'
+ case $host_os in
+ solaris2.[[0-5]] | solaris2.[[0-5]].*) ;;
+ *)
+ _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}-z ${wl}allextract$convenience ${wl}-z ${wl}defaultextract'
+ ;;
+ esac
+ fi
+ ;;
+ esac
+ ;;
+
+ sysv4*uw2* | sysv5OpenUNIX* | sysv5UnixWare7.[[01]].[[10]]* | unixware7* | sco3.2v5.0.[[024]]*)
+ _LT_TAGVAR(no_undefined_flag, $1)='${wl}-z,text'
+ _LT_TAGVAR(archive_cmds_need_lc, $1)=no
+ _LT_TAGVAR(hardcode_shlibpath_var, $1)=no
+ runpath_var='LD_RUN_PATH'
+
+ case $cc_basename in
+ CC*)
+ _LT_TAGVAR(archive_cmds, $1)='$CC -G ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+ _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -G ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+ ;;
+ *)
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+ _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+ ;;
+ esac
+ ;;
+
+ sysv5* | sco3.2v5* | sco5v6*)
+ # Note: We can NOT use -z defs as we might desire, because we do not
+ # link with -lc, and that would cause any symbols used from libc to
+ # always be unresolved, which means just about no library would
+ # ever link correctly. If we're not using GNU ld we use -z text
+ # though, which does catch some bad symbols but isn't as heavy-handed
+ # as -z defs.
+ _LT_TAGVAR(no_undefined_flag, $1)='${wl}-z,text'
+ _LT_TAGVAR(allow_undefined_flag, $1)='${wl}-z,nodefs'
+ _LT_TAGVAR(archive_cmds_need_lc, $1)=no
+ _LT_TAGVAR(hardcode_shlibpath_var, $1)=no
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-R,$libdir'
+ _LT_TAGVAR(hardcode_libdir_separator, $1)=':'
+ _LT_TAGVAR(link_all_deplibs, $1)=yes
+ _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-Bexport'
+ runpath_var='LD_RUN_PATH'
+
+ case $cc_basename in
+ CC*)
+ _LT_TAGVAR(archive_cmds, $1)='$CC -G ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+ _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -G ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+ ;;
+ *)
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+ _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+ ;;
+ esac
+ ;;
+
+ tandem*)
+ case $cc_basename in
+ NCC*)
+ # NonStop-UX NCC 3.20
+ # FIXME: insert proper C++ library support
+ _LT_TAGVAR(ld_shlibs, $1)=no
+ ;;
+ *)
+ # FIXME: insert proper C++ library support
+ _LT_TAGVAR(ld_shlibs, $1)=no
+ ;;
+ esac
+ ;;
+
+ vxworks*)
+ # FIXME: insert proper C++ library support
+ _LT_TAGVAR(ld_shlibs, $1)=no
+ ;;
+
+ *)
+ # FIXME: insert proper C++ library support
+ _LT_TAGVAR(ld_shlibs, $1)=no
+ ;;
+ esac
+
+ AC_MSG_RESULT([$_LT_TAGVAR(ld_shlibs, $1)])
+ test "$_LT_TAGVAR(ld_shlibs, $1)" = no && can_build_shared=no
+
+ _LT_TAGVAR(GCC, $1)="$GXX"
+ _LT_TAGVAR(LD, $1)="$LD"
+
+ ## CAVEAT EMPTOR:
+ ## There is no encapsulation within the following macros, do not change
+ ## the running order or otherwise move them around unless you know exactly
+ ## what you are doing...
+ _LT_SYS_HIDDEN_LIBDEPS($1)
+ _LT_COMPILER_PIC($1)
+ _LT_COMPILER_C_O($1)
+ _LT_COMPILER_FILE_LOCKS($1)
+ _LT_LINKER_SHLIBS($1)
+ _LT_SYS_DYNAMIC_LINKER($1)
+ _LT_LINKER_HARDCODE_LIBPATH($1)
+
+ _LT_CONFIG($1)
+ fi # test -n "$compiler"
+
+ CC=$lt_save_CC
+ LDCXX=$LD
+ LD=$lt_save_LD
+ GCC=$lt_save_GCC
+ with_gnu_ld=$lt_save_with_gnu_ld
+ lt_cv_path_LDCXX=$lt_cv_path_LD
+ lt_cv_path_LD=$lt_save_path_LD
+ lt_cv_prog_gnu_ldcxx=$lt_cv_prog_gnu_ld
+ lt_cv_prog_gnu_ld=$lt_save_with_gnu_ld
+fi # test "$_lt_caught_CXX_error" != yes
+
+AC_LANG_POP
+])# _LT_LANG_CXX_CONFIG
+
+
+# _LT_SYS_HIDDEN_LIBDEPS([TAGNAME])
+# ---------------------------------
+# Figure out "hidden" library dependencies from verbose
+# compiler output when linking a shared library.
+# Parse the compiler output and extract the necessary
+# objects, libraries and library flags.
+m4_defun([_LT_SYS_HIDDEN_LIBDEPS],
+[m4_require([_LT_FILEUTILS_DEFAULTS])dnl
+# Dependencies to place before and after the object being linked:
+_LT_TAGVAR(predep_objects, $1)=
+_LT_TAGVAR(postdep_objects, $1)=
+_LT_TAGVAR(predeps, $1)=
+_LT_TAGVAR(postdeps, $1)=
+_LT_TAGVAR(compiler_lib_search_path, $1)=
+
+dnl we can't use the lt_simple_compile_test_code here,
+dnl because it contains code intended for an executable,
+dnl not a library. It's possible we should let each
+dnl tag define a new lt_????_link_test_code variable,
+dnl but it's only used here...
+m4_if([$1], [], [cat > conftest.$ac_ext <<_LT_EOF
+int a;
+void foo (void) { a = 0; }
+_LT_EOF
+], [$1], [CXX], [cat > conftest.$ac_ext <<_LT_EOF
+class Foo
+{
+public:
+ Foo (void) { a = 0; }
+private:
+ int a;
+};
+_LT_EOF
+], [$1], [F77], [cat > conftest.$ac_ext <<_LT_EOF
+ subroutine foo
+ implicit none
+ integer*4 a
+ a=0
+ return
+ end
+_LT_EOF
+], [$1], [FC], [cat > conftest.$ac_ext <<_LT_EOF
+ subroutine foo
+ implicit none
+ integer a
+ a=0
+ return
+ end
+_LT_EOF
+], [$1], [GCJ], [cat > conftest.$ac_ext <<_LT_EOF
+public class foo {
+ private int a;
+ public void bar (void) {
+ a = 0;
+ }
+};
+_LT_EOF
+])
+dnl Parse the compiler output and extract the necessary
+dnl objects, libraries and library flags.
+if AC_TRY_EVAL(ac_compile); then
+ # Parse the compiler output and extract the necessary
+ # objects, libraries and library flags.
+
+ # Sentinel used to keep track of whether or not we are before
+ # the conftest object file.
+ pre_test_object_deps_done=no
+
+ for p in `eval "$output_verbose_link_cmd"`; do
+ case $p in
+
+ -L* | -R* | -l*)
+ # Some compilers place space between "-{L,R}" and the path.
+ # Remove the space.
+ if test $p = "-L" ||
+ test $p = "-R"; then
+ prev=$p
+ continue
+ else
+ prev=
+ fi
+
+ if test "$pre_test_object_deps_done" = no; then
+ case $p in
+ -L* | -R*)
+ # Internal compiler library paths should come after those
+ # provided the user. The postdeps already come after the
+ # user supplied libs so there is no need to process them.
+ if test -z "$_LT_TAGVAR(compiler_lib_search_path, $1)"; then
+ _LT_TAGVAR(compiler_lib_search_path, $1)="${prev}${p}"
+ else
+ _LT_TAGVAR(compiler_lib_search_path, $1)="${_LT_TAGVAR(compiler_lib_search_path, $1)} ${prev}${p}"
+ fi
+ ;;
+ # The "-l" case would never come before the object being
+ # linked, so don't bother handling this case.
+ esac
+ else
+ if test -z "$_LT_TAGVAR(postdeps, $1)"; then
+ _LT_TAGVAR(postdeps, $1)="${prev}${p}"
+ else
+ _LT_TAGVAR(postdeps, $1)="${_LT_TAGVAR(postdeps, $1)} ${prev}${p}"
+ fi
+ fi
+ ;;
+
+ *.$objext)
+ # This assumes that the test object file only shows up
+ # once in the compiler output.
+ if test "$p" = "conftest.$objext"; then
+ pre_test_object_deps_done=yes
+ continue
+ fi
+
+ if test "$pre_test_object_deps_done" = no; then
+ if test -z "$_LT_TAGVAR(predep_objects, $1)"; then
+ _LT_TAGVAR(predep_objects, $1)="$p"
+ else
+ _LT_TAGVAR(predep_objects, $1)="$_LT_TAGVAR(predep_objects, $1) $p"
+ fi
+ else
+ if test -z "$_LT_TAGVAR(postdep_objects, $1)"; then
+ _LT_TAGVAR(postdep_objects, $1)="$p"
+ else
+ _LT_TAGVAR(postdep_objects, $1)="$_LT_TAGVAR(postdep_objects, $1) $p"
+ fi
+ fi
+ ;;
+
+ *) ;; # Ignore the rest.
+
+ esac
+ done
+
+ # Clean up.
+ rm -f a.out a.exe
+else
+ echo "libtool.m4: error: problem compiling $1 test program"
+fi
+
+$RM -f confest.$objext
+
+# PORTME: override above test on systems where it is broken
+m4_if([$1], [CXX],
+[case $host_os in
+interix[[3-9]]*)
+ # Interix 3.5 installs completely hosed .la files for C++, so rather than
+ # hack all around it, let's just trust "g++" to DTRT.
+ _LT_TAGVAR(predep_objects,$1)=
+ _LT_TAGVAR(postdep_objects,$1)=
+ _LT_TAGVAR(postdeps,$1)=
+ ;;
+
+linux*)
+ case `$CC -V 2>&1 | sed 5q` in
+ *Sun\ C*)
+ # Sun C++ 5.9
+
+ # The more standards-conforming stlport4 library is
+ # incompatible with the Cstd library. Avoid specifying
+ # it if it's in CXXFLAGS. Ignore libCrun as
+ # -library=stlport4 depends on it.
+ case " $CXX $CXXFLAGS " in
+ *" -library=stlport4 "*)
+ solaris_use_stlport4=yes
+ ;;
+ esac
+
+ if test "$solaris_use_stlport4" != yes; then
+ _LT_TAGVAR(postdeps,$1)='-library=Cstd -library=Crun'
+ fi
+ ;;
+ esac
+ ;;
+
+solaris*)
+ case $cc_basename in
+ CC*)
+ # The more standards-conforming stlport4 library is
+ # incompatible with the Cstd library. Avoid specifying
+ # it if it's in CXXFLAGS. Ignore libCrun as
+ # -library=stlport4 depends on it.
+ case " $CXX $CXXFLAGS " in
+ *" -library=stlport4 "*)
+ solaris_use_stlport4=yes
+ ;;
+ esac
+
+ # Adding this requires a known-good setup of shared libraries for
+ # Sun compiler versions before 5.6, else PIC objects from an old
+ # archive will be linked into the output, leading to subtle bugs.
+ if test "$solaris_use_stlport4" != yes; then
+ _LT_TAGVAR(postdeps,$1)='-library=Cstd -library=Crun'
+ fi
+ ;;
+ esac
+ ;;
+esac
+])
+
+case " $_LT_TAGVAR(postdeps, $1) " in
+*" -lc "*) _LT_TAGVAR(archive_cmds_need_lc, $1)=no ;;
+esac
+ _LT_TAGVAR(compiler_lib_search_dirs, $1)=
+if test -n "${_LT_TAGVAR(compiler_lib_search_path, $1)}"; then
+ _LT_TAGVAR(compiler_lib_search_dirs, $1)=`echo " ${_LT_TAGVAR(compiler_lib_search_path, $1)}" | ${SED} -e 's! -L! !g' -e 's!^ !!'`
+fi
+_LT_TAGDECL([], [compiler_lib_search_dirs], [1],
+ [The directories searched by this compiler when creating a shared library])
+_LT_TAGDECL([], [predep_objects], [1],
+ [Dependencies to place before and after the objects being linked to
+ create a shared library])
+_LT_TAGDECL([], [postdep_objects], [1])
+_LT_TAGDECL([], [predeps], [1])
+_LT_TAGDECL([], [postdeps], [1])
+_LT_TAGDECL([], [compiler_lib_search_path], [1],
+ [The library search path used internally by the compiler when linking
+ a shared library])
+])# _LT_SYS_HIDDEN_LIBDEPS
+
+
+# _LT_PROG_F77
+# ------------
+# Since AC_PROG_F77 is broken, in that it returns the empty string
+# if there is no fortran compiler, we have our own version here.
+m4_defun([_LT_PROG_F77],
+[
+pushdef([AC_MSG_ERROR], [_lt_disable_F77=yes])
+AC_PROG_F77
+if test -z "$F77" || test "X$F77" = "Xno"; then
+ _lt_disable_F77=yes
+fi
+popdef([AC_MSG_ERROR])
+])# _LT_PROG_F77
+
+dnl aclocal-1.4 backwards compatibility:
+dnl AC_DEFUN([_LT_PROG_F77], [])
+
+
+# _LT_LANG_F77_CONFIG([TAG])
+# --------------------------
+# Ensure that the configuration variables for a Fortran 77 compiler are
+# suitably defined. These variables are subsequently used by _LT_CONFIG
+# to write the compiler configuration to `libtool'.
+m4_defun([_LT_LANG_F77_CONFIG],
+[AC_REQUIRE([_LT_PROG_F77])dnl
+AC_LANG_PUSH(Fortran 77)
+
+_LT_TAGVAR(archive_cmds_need_lc, $1)=no
+_LT_TAGVAR(allow_undefined_flag, $1)=
+_LT_TAGVAR(always_export_symbols, $1)=no
+_LT_TAGVAR(archive_expsym_cmds, $1)=
+_LT_TAGVAR(export_dynamic_flag_spec, $1)=
+_LT_TAGVAR(hardcode_direct, $1)=no
+_LT_TAGVAR(hardcode_direct_absolute, $1)=no
+_LT_TAGVAR(hardcode_libdir_flag_spec, $1)=
+_LT_TAGVAR(hardcode_libdir_flag_spec_ld, $1)=
+_LT_TAGVAR(hardcode_libdir_separator, $1)=
+_LT_TAGVAR(hardcode_minus_L, $1)=no
+_LT_TAGVAR(hardcode_automatic, $1)=no
+_LT_TAGVAR(inherit_rpath, $1)=no
+_LT_TAGVAR(module_cmds, $1)=
+_LT_TAGVAR(module_expsym_cmds, $1)=
+_LT_TAGVAR(link_all_deplibs, $1)=unknown
+_LT_TAGVAR(old_archive_cmds, $1)=$old_archive_cmds
+_LT_TAGVAR(no_undefined_flag, $1)=
+_LT_TAGVAR(whole_archive_flag_spec, $1)=
+_LT_TAGVAR(enable_shared_with_static_runtimes, $1)=no
+
+# Source file extension for f77 test sources.
+ac_ext=f
+
+# Object file extension for compiled f77 test sources.
+objext=o
+_LT_TAGVAR(objext, $1)=$objext
+
+# No sense in running all these tests if we already determined that
+# the F77 compiler isn't working. Some variables (like enable_shared)
+# are currently assumed to apply to all compilers on this platform,
+# and will be corrupted by setting them based on a non-working compiler.
+if test "$_lt_disable_F77" != yes; then
+ # Code to be used in simple compile tests
+ lt_simple_compile_test_code="\
+ subroutine t
+ return
+ end
+"
+
+ # Code to be used in simple link tests
+ lt_simple_link_test_code="\
+ program t
+ end
+"
+
+ # ltmain only uses $CC for tagged configurations so make sure $CC is set.
+ _LT_TAG_COMPILER
+
+ # save warnings/boilerplate of simple test code
+ _LT_COMPILER_BOILERPLATE
+ _LT_LINKER_BOILERPLATE
+
+ # Allow CC to be a program name with arguments.
+ lt_save_CC="$CC"
+ lt_save_GCC=$GCC
+ CC=${F77-"f77"}
+ compiler=$CC
+ _LT_TAGVAR(compiler, $1)=$CC
+ _LT_CC_BASENAME([$compiler])
+ GCC=$G77
+ if test -n "$compiler"; then
+ AC_MSG_CHECKING([if libtool supports shared libraries])
+ AC_MSG_RESULT([$can_build_shared])
+
+ AC_MSG_CHECKING([whether to build shared libraries])
+ test "$can_build_shared" = "no" && enable_shared=no
+
+ # On AIX, shared libraries and static libraries use the same namespace, and
+ # are all built from PIC.
+ case $host_os in
+ aix3*)
+ test "$enable_shared" = yes && enable_static=no
+ if test -n "$RANLIB"; then
+ archive_cmds="$archive_cmds~\$RANLIB \$lib"
+ postinstall_cmds='$RANLIB $lib'
+ fi
+ ;;
+ aix[[4-9]]*)
+ if test "$host_cpu" != ia64 && test "$aix_use_runtimelinking" = no ; then
+ test "$enable_shared" = yes && enable_static=no
+ fi
+ ;;
+ esac
+ AC_MSG_RESULT([$enable_shared])
+
+ AC_MSG_CHECKING([whether to build static libraries])
+ # Make sure either enable_shared or enable_static is yes.
+ test "$enable_shared" = yes || enable_static=yes
+ AC_MSG_RESULT([$enable_static])
+
+ _LT_TAGVAR(GCC, $1)="$G77"
+ _LT_TAGVAR(LD, $1)="$LD"
+
+ ## CAVEAT EMPTOR:
+ ## There is no encapsulation within the following macros, do not change
+ ## the running order or otherwise move them around unless you know exactly
+ ## what you are doing...
+ _LT_COMPILER_PIC($1)
+ _LT_COMPILER_C_O($1)
+ _LT_COMPILER_FILE_LOCKS($1)
+ _LT_LINKER_SHLIBS($1)
+ _LT_SYS_DYNAMIC_LINKER($1)
+ _LT_LINKER_HARDCODE_LIBPATH($1)
+
+ _LT_CONFIG($1)
+ fi # test -n "$compiler"
+
+ GCC=$lt_save_GCC
+ CC="$lt_save_CC"
+fi # test "$_lt_disable_F77" != yes
+
+AC_LANG_POP
+])# _LT_LANG_F77_CONFIG
+
+
+# _LT_PROG_FC
+# -----------
+# Since AC_PROG_FC is broken, in that it returns the empty string
+# if there is no fortran compiler, we have our own version here.
+m4_defun([_LT_PROG_FC],
+[
+pushdef([AC_MSG_ERROR], [_lt_disable_FC=yes])
+AC_PROG_FC
+if test -z "$FC" || test "X$FC" = "Xno"; then
+ _lt_disable_FC=yes
+fi
+popdef([AC_MSG_ERROR])
+])# _LT_PROG_FC
+
+dnl aclocal-1.4 backwards compatibility:
+dnl AC_DEFUN([_LT_PROG_FC], [])
+
+
+# _LT_LANG_FC_CONFIG([TAG])
+# -------------------------
+# Ensure that the configuration variables for a Fortran compiler are
+# suitably defined. These variables are subsequently used by _LT_CONFIG
+# to write the compiler configuration to `libtool'.
+m4_defun([_LT_LANG_FC_CONFIG],
+[AC_REQUIRE([_LT_PROG_FC])dnl
+AC_LANG_PUSH(Fortran)
+
+_LT_TAGVAR(archive_cmds_need_lc, $1)=no
+_LT_TAGVAR(allow_undefined_flag, $1)=
+_LT_TAGVAR(always_export_symbols, $1)=no
+_LT_TAGVAR(archive_expsym_cmds, $1)=
+_LT_TAGVAR(export_dynamic_flag_spec, $1)=
+_LT_TAGVAR(hardcode_direct, $1)=no
+_LT_TAGVAR(hardcode_direct_absolute, $1)=no
+_LT_TAGVAR(hardcode_libdir_flag_spec, $1)=
+_LT_TAGVAR(hardcode_libdir_flag_spec_ld, $1)=
+_LT_TAGVAR(hardcode_libdir_separator, $1)=
+_LT_TAGVAR(hardcode_minus_L, $1)=no
+_LT_TAGVAR(hardcode_automatic, $1)=no
+_LT_TAGVAR(inherit_rpath, $1)=no
+_LT_TAGVAR(module_cmds, $1)=
+_LT_TAGVAR(module_expsym_cmds, $1)=
+_LT_TAGVAR(link_all_deplibs, $1)=unknown
+_LT_TAGVAR(old_archive_cmds, $1)=$old_archive_cmds
+_LT_TAGVAR(no_undefined_flag, $1)=
+_LT_TAGVAR(whole_archive_flag_spec, $1)=
+_LT_TAGVAR(enable_shared_with_static_runtimes, $1)=no
+
+# Source file extension for fc test sources.
+ac_ext=${ac_fc_srcext-f}
+
+# Object file extension for compiled fc test sources.
+objext=o
+_LT_TAGVAR(objext, $1)=$objext
+
+# No sense in running all these tests if we already determined that
+# the FC compiler isn't working. Some variables (like enable_shared)
+# are currently assumed to apply to all compilers on this platform,
+# and will be corrupted by setting them based on a non-working compiler.
+if test "$_lt_disable_FC" != yes; then
+ # Code to be used in simple compile tests
+ lt_simple_compile_test_code="\
+ subroutine t
+ return
+ end
+"
+
+ # Code to be used in simple link tests
+ lt_simple_link_test_code="\
+ program t
+ end
+"
+
+ # ltmain only uses $CC for tagged configurations so make sure $CC is set.
+ _LT_TAG_COMPILER
+
+ # save warnings/boilerplate of simple test code
+ _LT_COMPILER_BOILERPLATE
+ _LT_LINKER_BOILERPLATE
+
+ # Allow CC to be a program name with arguments.
+ lt_save_CC="$CC"
+ lt_save_GCC=$GCC
+ CC=${FC-"f95"}
+ compiler=$CC
+ GCC=$ac_cv_fc_compiler_gnu
+
+ _LT_TAGVAR(compiler, $1)=$CC
+ _LT_CC_BASENAME([$compiler])
+
+ if test -n "$compiler"; then
+ AC_MSG_CHECKING([if libtool supports shared libraries])
+ AC_MSG_RESULT([$can_build_shared])
+
+ AC_MSG_CHECKING([whether to build shared libraries])
+ test "$can_build_shared" = "no" && enable_shared=no
+
+ # On AIX, shared libraries and static libraries use the same namespace, and
+ # are all built from PIC.
+ case $host_os in
+ aix3*)
+ test "$enable_shared" = yes && enable_static=no
+ if test -n "$RANLIB"; then
+ archive_cmds="$archive_cmds~\$RANLIB \$lib"
+ postinstall_cmds='$RANLIB $lib'
+ fi
+ ;;
+ aix[[4-9]]*)
+ if test "$host_cpu" != ia64 && test "$aix_use_runtimelinking" = no ; then
+ test "$enable_shared" = yes && enable_static=no
+ fi
+ ;;
+ esac
+ AC_MSG_RESULT([$enable_shared])
+
+ AC_MSG_CHECKING([whether to build static libraries])
+ # Make sure either enable_shared or enable_static is yes.
+ test "$enable_shared" = yes || enable_static=yes
+ AC_MSG_RESULT([$enable_static])
+
+ _LT_TAGVAR(GCC, $1)="$ac_cv_fc_compiler_gnu"
+ _LT_TAGVAR(LD, $1)="$LD"
+
+ ## CAVEAT EMPTOR:
+ ## There is no encapsulation within the following macros, do not change
+ ## the running order or otherwise move them around unless you know exactly
+ ## what you are doing...
+ _LT_SYS_HIDDEN_LIBDEPS($1)
+ _LT_COMPILER_PIC($1)
+ _LT_COMPILER_C_O($1)
+ _LT_COMPILER_FILE_LOCKS($1)
+ _LT_LINKER_SHLIBS($1)
+ _LT_SYS_DYNAMIC_LINKER($1)
+ _LT_LINKER_HARDCODE_LIBPATH($1)
+
+ _LT_CONFIG($1)
+ fi # test -n "$compiler"
+
+ GCC=$lt_save_GCC
+ CC="$lt_save_CC"
+fi # test "$_lt_disable_FC" != yes
+
+AC_LANG_POP
+])# _LT_LANG_FC_CONFIG
+
+
+# _LT_LANG_GCJ_CONFIG([TAG])
+# --------------------------
+# Ensure that the configuration variables for the GNU Java Compiler compiler
+# are suitably defined. These variables are subsequently used by _LT_CONFIG
+# to write the compiler configuration to `libtool'.
+m4_defun([_LT_LANG_GCJ_CONFIG],
+[AC_REQUIRE([LT_PROG_GCJ])dnl
+AC_LANG_SAVE
+
+# Source file extension for Java test sources.
+ac_ext=java
+
+# Object file extension for compiled Java test sources.
+objext=o
+_LT_TAGVAR(objext, $1)=$objext
+
+# Code to be used in simple compile tests
+lt_simple_compile_test_code="class foo {}"
+
+# Code to be used in simple link tests
+lt_simple_link_test_code='public class conftest { public static void main(String[[]] argv) {}; }'
+
+# ltmain only uses $CC for tagged configurations so make sure $CC is set.
+_LT_TAG_COMPILER
+
+# save warnings/boilerplate of simple test code
+_LT_COMPILER_BOILERPLATE
+_LT_LINKER_BOILERPLATE
+
+# Allow CC to be a program name with arguments.
+lt_save_CC="$CC"
+lt_save_GCC=$GCC
+GCC=yes
+CC=${GCJ-"gcj"}
+compiler=$CC
+_LT_TAGVAR(compiler, $1)=$CC
+_LT_TAGVAR(LD, $1)="$LD"
+_LT_CC_BASENAME([$compiler])
+
+# GCJ did not exist at the time GCC didn't implicitly link libc in.
+_LT_TAGVAR(archive_cmds_need_lc, $1)=no
+
+_LT_TAGVAR(old_archive_cmds, $1)=$old_archive_cmds
+
+if test -n "$compiler"; then
+ _LT_COMPILER_NO_RTTI($1)
+ _LT_COMPILER_PIC($1)
+ _LT_COMPILER_C_O($1)
+ _LT_COMPILER_FILE_LOCKS($1)
+ _LT_LINKER_SHLIBS($1)
+ _LT_LINKER_HARDCODE_LIBPATH($1)
+
+ _LT_CONFIG($1)
+fi
+
+AC_LANG_RESTORE
+
+GCC=$lt_save_GCC
+CC="$lt_save_CC"
+])# _LT_LANG_GCJ_CONFIG
+
+
+# _LT_LANG_RC_CONFIG([TAG])
+# -------------------------
+# Ensure that the configuration variables for the Windows resource compiler
+# are suitably defined. These variables are subsequently used by _LT_CONFIG
+# to write the compiler configuration to `libtool'.
+m4_defun([_LT_LANG_RC_CONFIG],
+[AC_REQUIRE([LT_PROG_RC])dnl
+AC_LANG_SAVE
+
+# Source file extension for RC test sources.
+ac_ext=rc
+
+# Object file extension for compiled RC test sources.
+objext=o
+_LT_TAGVAR(objext, $1)=$objext
+
+# Code to be used in simple compile tests
+lt_simple_compile_test_code='sample MENU { MENUITEM "&Soup", 100, CHECKED }'
+
+# Code to be used in simple link tests
+lt_simple_link_test_code="$lt_simple_compile_test_code"
+
+# ltmain only uses $CC for tagged configurations so make sure $CC is set.
+_LT_TAG_COMPILER
+
+# save warnings/boilerplate of simple test code
+_LT_COMPILER_BOILERPLATE
+_LT_LINKER_BOILERPLATE
+
+# Allow CC to be a program name with arguments.
+lt_save_CC="$CC"
+lt_save_GCC=$GCC
+GCC=
+CC=${RC-"windres"}
+compiler=$CC
+_LT_TAGVAR(compiler, $1)=$CC
+_LT_CC_BASENAME([$compiler])
+_LT_TAGVAR(lt_cv_prog_compiler_c_o, $1)=yes
+
+if test -n "$compiler"; then
+ :
+ _LT_CONFIG($1)
+fi
+
+GCC=$lt_save_GCC
+AC_LANG_RESTORE
+CC="$lt_save_CC"
+])# _LT_LANG_RC_CONFIG
+
+
+# LT_PROG_GCJ
+# -----------
+AC_DEFUN([LT_PROG_GCJ],
+[m4_ifdef([AC_PROG_GCJ], [AC_PROG_GCJ],
+ [m4_ifdef([A][M_PROG_GCJ], [A][M_PROG_GCJ],
+ [AC_CHECK_TOOL(GCJ, gcj,)
+ test "x${GCJFLAGS+set}" = xset || GCJFLAGS="-g -O2"
+ AC_SUBST(GCJFLAGS)])])[]dnl
+])
+
+# Old name:
+AU_ALIAS([LT_AC_PROG_GCJ], [LT_PROG_GCJ])
+dnl aclocal-1.4 backwards compatibility:
+dnl AC_DEFUN([LT_AC_PROG_GCJ], [])
+
+
+# LT_PROG_RC
+# ----------
+AC_DEFUN([LT_PROG_RC],
+[AC_CHECK_TOOL(RC, windres,)
+])
+
+# Old name:
+AU_ALIAS([LT_AC_PROG_RC], [LT_PROG_RC])
+dnl aclocal-1.4 backwards compatibility:
+dnl AC_DEFUN([LT_AC_PROG_RC], [])
+
+
+# _LT_DECL_EGREP
+# --------------
+# If we don't have a new enough Autoconf to choose the best grep
+# available, choose the one first in the user's PATH.
+m4_defun([_LT_DECL_EGREP],
+[AC_REQUIRE([AC_PROG_EGREP])dnl
+AC_REQUIRE([AC_PROG_FGREP])dnl
+test -z "$GREP" && GREP=grep
+_LT_DECL([], [GREP], [1], [A grep program that handles long lines])
+_LT_DECL([], [EGREP], [1], [An ERE matcher])
+_LT_DECL([], [FGREP], [1], [A literal string matcher])
+dnl Non-bleeding-edge autoconf doesn't subst GREP, so do it here too
+AC_SUBST([GREP])
+])
+
+
+# _LT_DECL_OBJDUMP
+# --------------
+# If we don't have a new enough Autoconf to choose the best objdump
+# available, choose the one first in the user's PATH.
+m4_defun([_LT_DECL_OBJDUMP],
+[AC_CHECK_TOOL(OBJDUMP, objdump, false)
+test -z "$OBJDUMP" && OBJDUMP=objdump
+_LT_DECL([], [OBJDUMP], [1], [An object symbol dumper])
+AC_SUBST([OBJDUMP])
+])
+
+
+# _LT_DECL_SED
+# ------------
+# Check for a fully-functional sed program, that truncates
+# as few characters as possible. Prefer GNU sed if found.
+m4_defun([_LT_DECL_SED],
+[AC_PROG_SED
+test -z "$SED" && SED=sed
+Xsed="$SED -e 1s/^X//"
+_LT_DECL([], [SED], [1], [A sed program that does not truncate output])
+_LT_DECL([], [Xsed], ["\$SED -e 1s/^X//"],
+ [Sed that helps us avoid accidentally triggering echo(1) options like -n])
+])# _LT_DECL_SED
+
+m4_ifndef([AC_PROG_SED], [
+# NOTE: This macro has been submitted for inclusion into #
+# GNU Autoconf as AC_PROG_SED. When it is available in #
+# a released version of Autoconf we should remove this #
+# macro and use it instead. #
+
+m4_defun([AC_PROG_SED],
+[AC_MSG_CHECKING([for a sed that does not truncate output])
+AC_CACHE_VAL(lt_cv_path_SED,
+[# Loop through the user's path and test for sed and gsed.
+# Then use that list of sed's as ones to test for truncation.
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for lt_ac_prog in sed gsed; do
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if $as_executable_p "$as_dir/$lt_ac_prog$ac_exec_ext"; then
+ lt_ac_sed_list="$lt_ac_sed_list $as_dir/$lt_ac_prog$ac_exec_ext"
+ fi
+ done
+ done
+done
+IFS=$as_save_IFS
+lt_ac_max=0
+lt_ac_count=0
+# Add /usr/xpg4/bin/sed as it is typically found on Solaris
+# along with /bin/sed that truncates output.
+for lt_ac_sed in $lt_ac_sed_list /usr/xpg4/bin/sed; do
+ test ! -f $lt_ac_sed && continue
+ cat /dev/null > conftest.in
+ lt_ac_count=0
+ echo $ECHO_N "0123456789$ECHO_C" >conftest.in
+ # Check for GNU sed and select it if it is found.
+ if "$lt_ac_sed" --version 2>&1 < /dev/null | grep 'GNU' > /dev/null; then
+ lt_cv_path_SED=$lt_ac_sed
+ break
+ fi
+ while true; do
+ cat conftest.in conftest.in >conftest.tmp
+ mv conftest.tmp conftest.in
+ cp conftest.in conftest.nl
+ echo >>conftest.nl
+ $lt_ac_sed -e 's/a$//' < conftest.nl >conftest.out || break
+ cmp -s conftest.out conftest.nl || break
+ # 10000 chars as input seems more than enough
+ test $lt_ac_count -gt 10 && break
+ lt_ac_count=`expr $lt_ac_count + 1`
+ if test $lt_ac_count -gt $lt_ac_max; then
+ lt_ac_max=$lt_ac_count
+ lt_cv_path_SED=$lt_ac_sed
+ fi
+ done
+done
+])
+SED=$lt_cv_path_SED
+AC_SUBST([SED])
+AC_MSG_RESULT([$SED])
+])#AC_PROG_SED
+])#m4_ifndef
+
+# Old name:
+AU_ALIAS([LT_AC_PROG_SED], [AC_PROG_SED])
+dnl aclocal-1.4 backwards compatibility:
+dnl AC_DEFUN([LT_AC_PROG_SED], [])
+
+
+# _LT_CHECK_SHELL_FEATURES
+# ------------------------
+# Find out whether the shell is Bourne or XSI compatible,
+# or has some other useful features.
+m4_defun([_LT_CHECK_SHELL_FEATURES],
+[AC_MSG_CHECKING([whether the shell understands some XSI constructs])
+# Try some XSI features
+xsi_shell=no
+( _lt_dummy="a/b/c"
+ test "${_lt_dummy##*/},${_lt_dummy%/*},"${_lt_dummy%"$_lt_dummy"}, \
+ = c,a/b,, \
+ && eval 'test $(( 1 + 1 )) -eq 2 \
+ && test "${#_lt_dummy}" -eq 5' ) >/dev/null 2>&1 \
+ && xsi_shell=yes
+AC_MSG_RESULT([$xsi_shell])
+_LT_CONFIG_LIBTOOL_INIT([xsi_shell='$xsi_shell'])
+
+AC_MSG_CHECKING([whether the shell understands "+="])
+lt_shell_append=no
+( foo=bar; set foo baz; eval "$[1]+=\$[2]" && test "$foo" = barbaz ) \
+ >/dev/null 2>&1 \
+ && lt_shell_append=yes
+AC_MSG_RESULT([$lt_shell_append])
+_LT_CONFIG_LIBTOOL_INIT([lt_shell_append='$lt_shell_append'])
+
+if ( (MAIL=60; unset MAIL) || exit) >/dev/null 2>&1; then
+ lt_unset=unset
+else
+ lt_unset=false
+fi
+_LT_DECL([], [lt_unset], [0], [whether the shell understands "unset"])dnl
+
+# test EBCDIC or ASCII
+case `echo X|tr X '\101'` in
+ A) # ASCII based system
+ # \n is not interpreted correctly by Solaris 8 /usr/ucb/tr
+ lt_SP2NL='tr \040 \012'
+ lt_NL2SP='tr \015\012 \040\040'
+ ;;
+ *) # EBCDIC based system
+ lt_SP2NL='tr \100 \n'
+ lt_NL2SP='tr \r\n \100\100'
+ ;;
+esac
+_LT_DECL([SP2NL], [lt_SP2NL], [1], [turn spaces into newlines])dnl
+_LT_DECL([NL2SP], [lt_NL2SP], [1], [turn newlines into spaces])dnl
+])# _LT_CHECK_SHELL_FEATURES
+
+
+# _LT_PROG_XSI_SHELLFNS
+# ---------------------
+# Bourne and XSI compatible variants of some useful shell functions.
+m4_defun([_LT_PROG_XSI_SHELLFNS],
+[case $xsi_shell in
+ yes)
+ cat << \_LT_EOF >> "$cfgfile"
+
+# func_dirname file append nondir_replacement
+# Compute the dirname of FILE. If nonempty, add APPEND to the result,
+# otherwise set result to NONDIR_REPLACEMENT.
+func_dirname ()
+{
+ case ${1} in
+ */*) func_dirname_result="${1%/*}${2}" ;;
+ * ) func_dirname_result="${3}" ;;
+ esac
+}
+
+# func_basename file
+func_basename ()
+{
+ func_basename_result="${1##*/}"
+}
+
+# func_dirname_and_basename file append nondir_replacement
+# perform func_basename and func_dirname in a single function
+# call:
+# dirname: Compute the dirname of FILE. If nonempty,
+# add APPEND to the result, otherwise set result
+# to NONDIR_REPLACEMENT.
+# value returned in "$func_dirname_result"
+# basename: Compute filename of FILE.
+# value retuned in "$func_basename_result"
+# Implementation must be kept synchronized with func_dirname
+# and func_basename. For efficiency, we do not delegate to
+# those functions but instead duplicate the functionality here.
+func_dirname_and_basename ()
+{
+ case ${1} in
+ */*) func_dirname_result="${1%/*}${2}" ;;
+ * ) func_dirname_result="${3}" ;;
+ esac
+ func_basename_result="${1##*/}"
+}
+
+# func_stripname prefix suffix name
+# strip PREFIX and SUFFIX off of NAME.
+# PREFIX and SUFFIX must not contain globbing or regex special
+# characters, hashes, percent signs, but SUFFIX may contain a leading
+# dot (in which case that matches only a dot).
+func_stripname ()
+{
+ # pdksh 5.2.14 does not do ${X%$Y} correctly if both X and Y are
+ # positional parameters, so assign one to ordinary parameter first.
+ func_stripname_result=${3}
+ func_stripname_result=${func_stripname_result#"${1}"}
+ func_stripname_result=${func_stripname_result%"${2}"}
+}
+
+# func_opt_split
+func_opt_split ()
+{
+ func_opt_split_opt=${1%%=*}
+ func_opt_split_arg=${1#*=}
+}
+
+# func_lo2o object
+func_lo2o ()
+{
+ case ${1} in
+ *.lo) func_lo2o_result=${1%.lo}.${objext} ;;
+ *) func_lo2o_result=${1} ;;
+ esac
+}
+
+# func_xform libobj-or-source
+func_xform ()
+{
+ func_xform_result=${1%.*}.lo
+}
+
+# func_arith arithmetic-term...
+func_arith ()
+{
+ func_arith_result=$(( $[*] ))
+}
+
+# func_len string
+# STRING may not start with a hyphen.
+func_len ()
+{
+ func_len_result=${#1}
+}
+
+_LT_EOF
+ ;;
+ *) # Bourne compatible functions.
+ cat << \_LT_EOF >> "$cfgfile"
+
+# func_dirname file append nondir_replacement
+# Compute the dirname of FILE. If nonempty, add APPEND to the result,
+# otherwise set result to NONDIR_REPLACEMENT.
+func_dirname ()
+{
+ # Extract subdirectory from the argument.
+ func_dirname_result=`$ECHO "X${1}" | $Xsed -e "$dirname"`
+ if test "X$func_dirname_result" = "X${1}"; then
+ func_dirname_result="${3}"
+ else
+ func_dirname_result="$func_dirname_result${2}"
+ fi
+}
+
+# func_basename file
+func_basename ()
+{
+ func_basename_result=`$ECHO "X${1}" | $Xsed -e "$basename"`
+}
+
+dnl func_dirname_and_basename
+dnl A portable version of this function is already defined in general.m4sh
+dnl so there is no need for it here.
+
+# func_stripname prefix suffix name
+# strip PREFIX and SUFFIX off of NAME.
+# PREFIX and SUFFIX must not contain globbing or regex special
+# characters, hashes, percent signs, but SUFFIX may contain a leading
+# dot (in which case that matches only a dot).
+# func_strip_suffix prefix name
+func_stripname ()
+{
+ case ${2} in
+ .*) func_stripname_result=`$ECHO "X${3}" \
+ | $Xsed -e "s%^${1}%%" -e "s%\\\\${2}\$%%"`;;
+ *) func_stripname_result=`$ECHO "X${3}" \
+ | $Xsed -e "s%^${1}%%" -e "s%${2}\$%%"`;;
+ esac
+}
+
+# sed scripts:
+my_sed_long_opt='1s/^\(-[[^=]]*\)=.*/\1/;q'
+my_sed_long_arg='1s/^-[[^=]]*=//'
+
+# func_opt_split
+func_opt_split ()
+{
+ func_opt_split_opt=`$ECHO "X${1}" | $Xsed -e "$my_sed_long_opt"`
+ func_opt_split_arg=`$ECHO "X${1}" | $Xsed -e "$my_sed_long_arg"`
+}
+
+# func_lo2o object
+func_lo2o ()
+{
+ func_lo2o_result=`$ECHO "X${1}" | $Xsed -e "$lo2o"`
+}
+
+# func_xform libobj-or-source
+func_xform ()
+{
+ func_xform_result=`$ECHO "X${1}" | $Xsed -e 's/\.[[^.]]*$/.lo/'`
+}
+
+# func_arith arithmetic-term...
+func_arith ()
+{
+ func_arith_result=`expr "$[@]"`
+}
+
+# func_len string
+# STRING may not start with a hyphen.
+func_len ()
+{
+ func_len_result=`expr "$[1]" : ".*" 2>/dev/null || echo $max_cmd_len`
+}
+
+_LT_EOF
+esac
+
+case $lt_shell_append in
+ yes)
+ cat << \_LT_EOF >> "$cfgfile"
+
+# func_append var value
+# Append VALUE to the end of shell variable VAR.
+func_append ()
+{
+ eval "$[1]+=\$[2]"
+}
+_LT_EOF
+ ;;
+ *)
+ cat << \_LT_EOF >> "$cfgfile"
+
+# func_append var value
+# Append VALUE to the end of shell variable VAR.
+func_append ()
+{
+ eval "$[1]=\$$[1]\$[2]"
+}
+
+_LT_EOF
+ ;;
+ esac
+])
+
+# Helper functions for option handling. -*- Autoconf -*-
+#
+# Copyright (C) 2004, 2005, 2007, 2008 Free Software Foundation, Inc.
+# Written by Gary V. Vaughan, 2004
+#
+# This file is free software; the Free Software Foundation gives
+# unlimited permission to copy and/or distribute it, with or without
+# modifications, as long as this notice is preserved.
+
+# serial 6 ltoptions.m4
+
+# This is to help aclocal find these macros, as it can't see m4_define.
+AC_DEFUN([LTOPTIONS_VERSION], [m4_if([1])])
+
+
+# _LT_MANGLE_OPTION(MACRO-NAME, OPTION-NAME)
+# ------------------------------------------
+m4_define([_LT_MANGLE_OPTION],
+[[_LT_OPTION_]m4_bpatsubst($1__$2, [[^a-zA-Z0-9_]], [_])])
+
+
+# _LT_SET_OPTION(MACRO-NAME, OPTION-NAME)
+# ---------------------------------------
+# Set option OPTION-NAME for macro MACRO-NAME, and if there is a
+# matching handler defined, dispatch to it. Other OPTION-NAMEs are
+# saved as a flag.
+m4_define([_LT_SET_OPTION],
+[m4_define(_LT_MANGLE_OPTION([$1], [$2]))dnl
+m4_ifdef(_LT_MANGLE_DEFUN([$1], [$2]),
+ _LT_MANGLE_DEFUN([$1], [$2]),
+ [m4_warning([Unknown $1 option `$2'])])[]dnl
+])
+
+
+# _LT_IF_OPTION(MACRO-NAME, OPTION-NAME, IF-SET, [IF-NOT-SET])
+# ------------------------------------------------------------
+# Execute IF-SET if OPTION is set, IF-NOT-SET otherwise.
+m4_define([_LT_IF_OPTION],
+[m4_ifdef(_LT_MANGLE_OPTION([$1], [$2]), [$3], [$4])])
+
+
+# _LT_UNLESS_OPTIONS(MACRO-NAME, OPTION-LIST, IF-NOT-SET)
+# -------------------------------------------------------
+# Execute IF-NOT-SET unless all options in OPTION-LIST for MACRO-NAME
+# are set.
+m4_define([_LT_UNLESS_OPTIONS],
+[m4_foreach([_LT_Option], m4_split(m4_normalize([$2])),
+ [m4_ifdef(_LT_MANGLE_OPTION([$1], _LT_Option),
+ [m4_define([$0_found])])])[]dnl
+m4_ifdef([$0_found], [m4_undefine([$0_found])], [$3
+])[]dnl
+])
+
+
+# _LT_SET_OPTIONS(MACRO-NAME, OPTION-LIST)
+# ----------------------------------------
+# OPTION-LIST is a space-separated list of Libtool options associated
+# with MACRO-NAME. If any OPTION has a matching handler declared with
+# LT_OPTION_DEFINE, dispatch to that macro; otherwise complain about
+# the unknown option and exit.
+m4_defun([_LT_SET_OPTIONS],
+[# Set options
+m4_foreach([_LT_Option], m4_split(m4_normalize([$2])),
+ [_LT_SET_OPTION([$1], _LT_Option)])
+
+m4_if([$1],[LT_INIT],[
+ dnl
+ dnl Simply set some default values (i.e off) if boolean options were not
+ dnl specified:
+ _LT_UNLESS_OPTIONS([LT_INIT], [dlopen], [enable_dlopen=no
+ ])
+ _LT_UNLESS_OPTIONS([LT_INIT], [win32-dll], [enable_win32_dll=no
+ ])
+ dnl
+ dnl If no reference was made to various pairs of opposing options, then
+ dnl we run the default mode handler for the pair. For example, if neither
+ dnl `shared' nor `disable-shared' was passed, we enable building of shared
+ dnl archives by default:
+ _LT_UNLESS_OPTIONS([LT_INIT], [shared disable-shared], [_LT_ENABLE_SHARED])
+ _LT_UNLESS_OPTIONS([LT_INIT], [static disable-static], [_LT_ENABLE_STATIC])
+ _LT_UNLESS_OPTIONS([LT_INIT], [pic-only no-pic], [_LT_WITH_PIC])
+ _LT_UNLESS_OPTIONS([LT_INIT], [fast-install disable-fast-install],
+ [_LT_ENABLE_FAST_INSTALL])
+ ])
+])# _LT_SET_OPTIONS
+
+
+
+# _LT_MANGLE_DEFUN(MACRO-NAME, OPTION-NAME)
+# -----------------------------------------
+m4_define([_LT_MANGLE_DEFUN],
+[[_LT_OPTION_DEFUN_]m4_bpatsubst(m4_toupper([$1__$2]), [[^A-Z0-9_]], [_])])
+
+
+# LT_OPTION_DEFINE(MACRO-NAME, OPTION-NAME, CODE)
+# -----------------------------------------------
+m4_define([LT_OPTION_DEFINE],
+[m4_define(_LT_MANGLE_DEFUN([$1], [$2]), [$3])[]dnl
+])# LT_OPTION_DEFINE
+
+
+# dlopen
+# ------
+LT_OPTION_DEFINE([LT_INIT], [dlopen], [enable_dlopen=yes
+])
+
+AU_DEFUN([AC_LIBTOOL_DLOPEN],
+[_LT_SET_OPTION([LT_INIT], [dlopen])
+AC_DIAGNOSE([obsolete],
+[$0: Remove this warning and the call to _LT_SET_OPTION when you
+put the `dlopen' option into LT_INIT's first parameter.])
+])
+
+dnl aclocal-1.4 backwards compatibility:
+dnl AC_DEFUN([AC_LIBTOOL_DLOPEN], [])
+
+
+# win32-dll
+# ---------
+# Declare package support for building win32 dll's.
+LT_OPTION_DEFINE([LT_INIT], [win32-dll],
+[enable_win32_dll=yes
+
+case $host in
+*-*-cygwin* | *-*-mingw* | *-*-pw32* | *-cegcc*)
+ AC_CHECK_TOOL(AS, as, false)
+ AC_CHECK_TOOL(DLLTOOL, dlltool, false)
+ AC_CHECK_TOOL(OBJDUMP, objdump, false)
+ ;;
+esac
+
+test -z "$AS" && AS=as
+_LT_DECL([], [AS], [0], [Assembler program])dnl
+
+test -z "$DLLTOOL" && DLLTOOL=dlltool
+_LT_DECL([], [DLLTOOL], [0], [DLL creation program])dnl
+
+test -z "$OBJDUMP" && OBJDUMP=objdump
+_LT_DECL([], [OBJDUMP], [0], [Object dumper program])dnl
+])# win32-dll
+
+AU_DEFUN([AC_LIBTOOL_WIN32_DLL],
+[AC_REQUIRE([AC_CANONICAL_HOST])dnl
+_LT_SET_OPTION([LT_INIT], [win32-dll])
+AC_DIAGNOSE([obsolete],
+[$0: Remove this warning and the call to _LT_SET_OPTION when you
+put the `win32-dll' option into LT_INIT's first parameter.])
+])
+
+dnl aclocal-1.4 backwards compatibility:
+dnl AC_DEFUN([AC_LIBTOOL_WIN32_DLL], [])
+
+
+# _LT_ENABLE_SHARED([DEFAULT])
+# ----------------------------
+# implement the --enable-shared flag, and supports the `shared' and
+# `disable-shared' LT_INIT options.
+# DEFAULT is either `yes' or `no'. If omitted, it defaults to `yes'.
+m4_define([_LT_ENABLE_SHARED],
+[m4_define([_LT_ENABLE_SHARED_DEFAULT], [m4_if($1, no, no, yes)])dnl
+AC_ARG_ENABLE([shared],
+ [AS_HELP_STRING([--enable-shared@<:@=PKGS@:>@],
+ [build shared libraries @<:@default=]_LT_ENABLE_SHARED_DEFAULT[@:>@])],
+ [p=${PACKAGE-default}
+ case $enableval in
+ yes) enable_shared=yes ;;
+ no) enable_shared=no ;;
+ *)
+ enable_shared=no
+ # Look at the argument we got. We use all the common list separators.
+ lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR,"
+ for pkg in $enableval; do
+ IFS="$lt_save_ifs"
+ if test "X$pkg" = "X$p"; then
+ enable_shared=yes
+ fi
+ done
+ IFS="$lt_save_ifs"
+ ;;
+ esac],
+ [enable_shared=]_LT_ENABLE_SHARED_DEFAULT)
+
+ _LT_DECL([build_libtool_libs], [enable_shared], [0],
+ [Whether or not to build shared libraries])
+])# _LT_ENABLE_SHARED
+
+LT_OPTION_DEFINE([LT_INIT], [shared], [_LT_ENABLE_SHARED([yes])])
+LT_OPTION_DEFINE([LT_INIT], [disable-shared], [_LT_ENABLE_SHARED([no])])
+
+# Old names:
+AC_DEFUN([AC_ENABLE_SHARED],
+[_LT_SET_OPTION([LT_INIT], m4_if([$1], [no], [disable-])[shared])
+])
+
+AC_DEFUN([AC_DISABLE_SHARED],
+[_LT_SET_OPTION([LT_INIT], [disable-shared])
+])
+
+AU_DEFUN([AM_ENABLE_SHARED], [AC_ENABLE_SHARED($@)])
+AU_DEFUN([AM_DISABLE_SHARED], [AC_DISABLE_SHARED($@)])
+
+dnl aclocal-1.4 backwards compatibility:
+dnl AC_DEFUN([AM_ENABLE_SHARED], [])
+dnl AC_DEFUN([AM_DISABLE_SHARED], [])
+
+
+
+# _LT_ENABLE_STATIC([DEFAULT])
+# ----------------------------
+# implement the --enable-static flag, and support the `static' and
+# `disable-static' LT_INIT options.
+# DEFAULT is either `yes' or `no'. If omitted, it defaults to `yes'.
+m4_define([_LT_ENABLE_STATIC],
+[m4_define([_LT_ENABLE_STATIC_DEFAULT], [m4_if($1, no, no, yes)])dnl
+AC_ARG_ENABLE([static],
+ [AS_HELP_STRING([--enable-static@<:@=PKGS@:>@],
+ [build static libraries @<:@default=]_LT_ENABLE_STATIC_DEFAULT[@:>@])],
+ [p=${PACKAGE-default}
+ case $enableval in
+ yes) enable_static=yes ;;
+ no) enable_static=no ;;
+ *)
+ enable_static=no
+ # Look at the argument we got. We use all the common list separators.
+ lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR,"
+ for pkg in $enableval; do
+ IFS="$lt_save_ifs"
+ if test "X$pkg" = "X$p"; then
+ enable_static=yes
+ fi
+ done
+ IFS="$lt_save_ifs"
+ ;;
+ esac],
+ [enable_static=]_LT_ENABLE_STATIC_DEFAULT)
+
+ _LT_DECL([build_old_libs], [enable_static], [0],
+ [Whether or not to build static libraries])
+])# _LT_ENABLE_STATIC
+
+LT_OPTION_DEFINE([LT_INIT], [static], [_LT_ENABLE_STATIC([yes])])
+LT_OPTION_DEFINE([LT_INIT], [disable-static], [_LT_ENABLE_STATIC([no])])
+
+# Old names:
+AC_DEFUN([AC_ENABLE_STATIC],
+[_LT_SET_OPTION([LT_INIT], m4_if([$1], [no], [disable-])[static])
+])
+
+AC_DEFUN([AC_DISABLE_STATIC],
+[_LT_SET_OPTION([LT_INIT], [disable-static])
+])
+
+AU_DEFUN([AM_ENABLE_STATIC], [AC_ENABLE_STATIC($@)])
+AU_DEFUN([AM_DISABLE_STATIC], [AC_DISABLE_STATIC($@)])
+
+dnl aclocal-1.4 backwards compatibility:
+dnl AC_DEFUN([AM_ENABLE_STATIC], [])
+dnl AC_DEFUN([AM_DISABLE_STATIC], [])
+
+
+
+# _LT_ENABLE_FAST_INSTALL([DEFAULT])
+# ----------------------------------
+# implement the --enable-fast-install flag, and support the `fast-install'
+# and `disable-fast-install' LT_INIT options.
+# DEFAULT is either `yes' or `no'. If omitted, it defaults to `yes'.
+m4_define([_LT_ENABLE_FAST_INSTALL],
+[m4_define([_LT_ENABLE_FAST_INSTALL_DEFAULT], [m4_if($1, no, no, yes)])dnl
+AC_ARG_ENABLE([fast-install],
+ [AS_HELP_STRING([--enable-fast-install@<:@=PKGS@:>@],
+ [optimize for fast installation @<:@default=]_LT_ENABLE_FAST_INSTALL_DEFAULT[@:>@])],
+ [p=${PACKAGE-default}
+ case $enableval in
+ yes) enable_fast_install=yes ;;
+ no) enable_fast_install=no ;;
+ *)
+ enable_fast_install=no
+ # Look at the argument we got. We use all the common list separators.
+ lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR,"
+ for pkg in $enableval; do
+ IFS="$lt_save_ifs"
+ if test "X$pkg" = "X$p"; then
+ enable_fast_install=yes
+ fi
+ done
+ IFS="$lt_save_ifs"
+ ;;
+ esac],
+ [enable_fast_install=]_LT_ENABLE_FAST_INSTALL_DEFAULT)
+
+_LT_DECL([fast_install], [enable_fast_install], [0],
+ [Whether or not to optimize for fast installation])dnl
+])# _LT_ENABLE_FAST_INSTALL
+
+LT_OPTION_DEFINE([LT_INIT], [fast-install], [_LT_ENABLE_FAST_INSTALL([yes])])
+LT_OPTION_DEFINE([LT_INIT], [disable-fast-install], [_LT_ENABLE_FAST_INSTALL([no])])
+
+# Old names:
+AU_DEFUN([AC_ENABLE_FAST_INSTALL],
+[_LT_SET_OPTION([LT_INIT], m4_if([$1], [no], [disable-])[fast-install])
+AC_DIAGNOSE([obsolete],
+[$0: Remove this warning and the call to _LT_SET_OPTION when you put
+the `fast-install' option into LT_INIT's first parameter.])
+])
+
+AU_DEFUN([AC_DISABLE_FAST_INSTALL],
+[_LT_SET_OPTION([LT_INIT], [disable-fast-install])
+AC_DIAGNOSE([obsolete],
+[$0: Remove this warning and the call to _LT_SET_OPTION when you put
+the `disable-fast-install' option into LT_INIT's first parameter.])
+])
+
+dnl aclocal-1.4 backwards compatibility:
+dnl AC_DEFUN([AC_ENABLE_FAST_INSTALL], [])
+dnl AC_DEFUN([AM_DISABLE_FAST_INSTALL], [])
+
+
+# _LT_WITH_PIC([MODE])
+# --------------------
+# implement the --with-pic flag, and support the `pic-only' and `no-pic'
+# LT_INIT options.
+# MODE is either `yes' or `no'. If omitted, it defaults to `both'.
+m4_define([_LT_WITH_PIC],
+[AC_ARG_WITH([pic],
+ [AS_HELP_STRING([--with-pic],
+ [try to use only PIC/non-PIC objects @<:@default=use both@:>@])],
+ [pic_mode="$withval"],
+ [pic_mode=default])
+
+test -z "$pic_mode" && pic_mode=m4_default([$1], [default])
+
+_LT_DECL([], [pic_mode], [0], [What type of objects to build])dnl
+])# _LT_WITH_PIC
+
+LT_OPTION_DEFINE([LT_INIT], [pic-only], [_LT_WITH_PIC([yes])])
+LT_OPTION_DEFINE([LT_INIT], [no-pic], [_LT_WITH_PIC([no])])
+
+# Old name:
+AU_DEFUN([AC_LIBTOOL_PICMODE],
+[_LT_SET_OPTION([LT_INIT], [pic-only])
+AC_DIAGNOSE([obsolete],
+[$0: Remove this warning and the call to _LT_SET_OPTION when you
+put the `pic-only' option into LT_INIT's first parameter.])
+])
+
+dnl aclocal-1.4 backwards compatibility:
+dnl AC_DEFUN([AC_LIBTOOL_PICMODE], [])
+
+
+m4_define([_LTDL_MODE], [])
+LT_OPTION_DEFINE([LTDL_INIT], [nonrecursive],
+ [m4_define([_LTDL_MODE], [nonrecursive])])
+LT_OPTION_DEFINE([LTDL_INIT], [recursive],
+ [m4_define([_LTDL_MODE], [recursive])])
+LT_OPTION_DEFINE([LTDL_INIT], [subproject],
+ [m4_define([_LTDL_MODE], [subproject])])
+
+m4_define([_LTDL_TYPE], [])
+LT_OPTION_DEFINE([LTDL_INIT], [installable],
+ [m4_define([_LTDL_TYPE], [installable])])
+LT_OPTION_DEFINE([LTDL_INIT], [convenience],
+ [m4_define([_LTDL_TYPE], [convenience])])
+
+# ltsugar.m4 -- libtool m4 base layer. -*-Autoconf-*-
+#
+# Copyright (C) 2004, 2005, 2007, 2008 Free Software Foundation, Inc.
+# Written by Gary V. Vaughan, 2004
+#
+# This file is free software; the Free Software Foundation gives
+# unlimited permission to copy and/or distribute it, with or without
+# modifications, as long as this notice is preserved.
+
+# serial 6 ltsugar.m4
+
+# This is to help aclocal find these macros, as it can't see m4_define.
+AC_DEFUN([LTSUGAR_VERSION], [m4_if([0.1])])
+
+
+# lt_join(SEP, ARG1, [ARG2...])
+# -----------------------------
+# Produce ARG1SEPARG2...SEPARGn, omitting [] arguments and their
+# associated separator.
+# Needed until we can rely on m4_join from Autoconf 2.62, since all earlier
+# versions in m4sugar had bugs.
+m4_define([lt_join],
+[m4_if([$#], [1], [],
+ [$#], [2], [[$2]],
+ [m4_if([$2], [], [], [[$2]_])$0([$1], m4_shift(m4_shift($@)))])])
+m4_define([_lt_join],
+[m4_if([$#$2], [2], [],
+ [m4_if([$2], [], [], [[$1$2]])$0([$1], m4_shift(m4_shift($@)))])])
+
+
+# lt_car(LIST)
+# lt_cdr(LIST)
+# ------------
+# Manipulate m4 lists.
+# These macros are necessary as long as will still need to support
+# Autoconf-2.59 which quotes differently.
+m4_define([lt_car], [[$1]])
+m4_define([lt_cdr],
+[m4_if([$#], 0, [m4_fatal([$0: cannot be called without arguments])],
+ [$#], 1, [],
+ [m4_dquote(m4_shift($@))])])
+m4_define([lt_unquote], $1)
+
+
+# lt_append(MACRO-NAME, STRING, [SEPARATOR])
+# ------------------------------------------
+# Redefine MACRO-NAME to hold its former content plus `SEPARATOR'`STRING'.
+# Note that neither SEPARATOR nor STRING are expanded; they are appended
+# to MACRO-NAME as is (leaving the expansion for when MACRO-NAME is invoked).
+# No SEPARATOR is output if MACRO-NAME was previously undefined (different
+# than defined and empty).
+#
+# This macro is needed until we can rely on Autoconf 2.62, since earlier
+# versions of m4sugar mistakenly expanded SEPARATOR but not STRING.
+m4_define([lt_append],
+[m4_define([$1],
+ m4_ifdef([$1], [m4_defn([$1])[$3]])[$2])])
+
+
+
+# lt_combine(SEP, PREFIX-LIST, INFIX, SUFFIX1, [SUFFIX2...])
+# ----------------------------------------------------------
+# Produce a SEP delimited list of all paired combinations of elements of
+# PREFIX-LIST with SUFFIX1 through SUFFIXn. Each element of the list
+# has the form PREFIXmINFIXSUFFIXn.
+# Needed until we can rely on m4_combine added in Autoconf 2.62.
+m4_define([lt_combine],
+[m4_if(m4_eval([$# > 3]), [1],
+ [m4_pushdef([_Lt_sep], [m4_define([_Lt_sep], m4_defn([lt_car]))])]]dnl
+[[m4_foreach([_Lt_prefix], [$2],
+ [m4_foreach([_Lt_suffix],
+ ]m4_dquote(m4_dquote(m4_shift(m4_shift(m4_shift($@)))))[,
+ [_Lt_sep([$1])[]m4_defn([_Lt_prefix])[$3]m4_defn([_Lt_suffix])])])])])
+
+
+# lt_if_append_uniq(MACRO-NAME, VARNAME, [SEPARATOR], [UNIQ], [NOT-UNIQ])
+# -----------------------------------------------------------------------
+# Iff MACRO-NAME does not yet contain VARNAME, then append it (delimited
+# by SEPARATOR if supplied) and expand UNIQ, else NOT-UNIQ.
+m4_define([lt_if_append_uniq],
+[m4_ifdef([$1],
+ [m4_if(m4_index([$3]m4_defn([$1])[$3], [$3$2$3]), [-1],
+ [lt_append([$1], [$2], [$3])$4],
+ [$5])],
+ [lt_append([$1], [$2], [$3])$4])])
+
+
+# lt_dict_add(DICT, KEY, VALUE)
+# -----------------------------
+m4_define([lt_dict_add],
+[m4_define([$1($2)], [$3])])
+
+
+# lt_dict_add_subkey(DICT, KEY, SUBKEY, VALUE)
+# --------------------------------------------
+m4_define([lt_dict_add_subkey],
+[m4_define([$1($2:$3)], [$4])])
+
+
+# lt_dict_fetch(DICT, KEY, [SUBKEY])
+# ----------------------------------
+m4_define([lt_dict_fetch],
+[m4_ifval([$3],
+ m4_ifdef([$1($2:$3)], [m4_defn([$1($2:$3)])]),
+ m4_ifdef([$1($2)], [m4_defn([$1($2)])]))])
+
+
+# lt_if_dict_fetch(DICT, KEY, [SUBKEY], VALUE, IF-TRUE, [IF-FALSE])
+# -----------------------------------------------------------------
+m4_define([lt_if_dict_fetch],
+[m4_if(lt_dict_fetch([$1], [$2], [$3]), [$4],
+ [$5],
+ [$6])])
+
+
+# lt_dict_filter(DICT, [SUBKEY], VALUE, [SEPARATOR], KEY, [...])
+# --------------------------------------------------------------
+m4_define([lt_dict_filter],
+[m4_if([$5], [], [],
+ [lt_join(m4_quote(m4_default([$4], [[, ]])),
+ lt_unquote(m4_split(m4_normalize(m4_foreach(_Lt_key, lt_car([m4_shiftn(4, $@)]),
+ [lt_if_dict_fetch([$1], _Lt_key, [$2], [$3], [_Lt_key ])])))))])[]dnl
+])
+
+# ltversion.m4 -- version numbers -*- Autoconf -*-
+#
+# Copyright (C) 2004 Free Software Foundation, Inc.
+# Written by Scott James Remnant, 2004
+#
+# This file is free software; the Free Software Foundation gives
+# unlimited permission to copy and/or distribute it, with or without
+# modifications, as long as this notice is preserved.
+
+# Generated from ltversion.in.
+
+# serial 3017 ltversion.m4
+# This file is part of GNU Libtool
+
+m4_define([LT_PACKAGE_VERSION], [2.2.6b])
+m4_define([LT_PACKAGE_REVISION], [1.3017])
+
+AC_DEFUN([LTVERSION_VERSION],
+[macro_version='2.2.6b'
+macro_revision='1.3017'
+_LT_DECL(, macro_version, 0, [Which release of libtool.m4 was used?])
+_LT_DECL(, macro_revision, 0)
+])
+
+# lt~obsolete.m4 -- aclocal satisfying obsolete definitions. -*-Autoconf-*-
+#
+# Copyright (C) 2004, 2005, 2007 Free Software Foundation, Inc.
+# Written by Scott James Remnant, 2004.
+#
+# This file is free software; the Free Software Foundation gives
+# unlimited permission to copy and/or distribute it, with or without
+# modifications, as long as this notice is preserved.
+
+# serial 4 lt~obsolete.m4
+
+# These exist entirely to fool aclocal when bootstrapping libtool.
+#
+# In the past libtool.m4 has provided macros via AC_DEFUN (or AU_DEFUN)
+# which have later been changed to m4_define as they aren't part of the
+# exported API, or moved to Autoconf or Automake where they belong.
+#
+# The trouble is, aclocal is a bit thick. It'll see the old AC_DEFUN
+# in /usr/share/aclocal/libtool.m4 and remember it, then when it sees us
+# using a macro with the same name in our local m4/libtool.m4 it'll
+# pull the old libtool.m4 in (it doesn't see our shiny new m4_define
+# and doesn't know about Autoconf macros at all.)
+#
+# So we provide this file, which has a silly filename so it's always
+# included after everything else. This provides aclocal with the
+# AC_DEFUNs it wants, but when m4 processes it, it doesn't do anything
+# because those macros already exist, or will be overwritten later.
+# We use AC_DEFUN over AU_DEFUN for compatibility with aclocal-1.6.
+#
+# Anytime we withdraw an AC_DEFUN or AU_DEFUN, remember to add it here.
+# Yes, that means every name once taken will need to remain here until
+# we give up compatibility with versions before 1.7, at which point
+# we need to keep only those names which we still refer to.
+
+# This is to help aclocal find these macros, as it can't see m4_define.
+AC_DEFUN([LTOBSOLETE_VERSION], [m4_if([1])])
+
+m4_ifndef([AC_LIBTOOL_LINKER_OPTION], [AC_DEFUN([AC_LIBTOOL_LINKER_OPTION])])
+m4_ifndef([AC_PROG_EGREP], [AC_DEFUN([AC_PROG_EGREP])])
+m4_ifndef([_LT_AC_PROG_ECHO_BACKSLASH], [AC_DEFUN([_LT_AC_PROG_ECHO_BACKSLASH])])
+m4_ifndef([_LT_AC_SHELL_INIT], [AC_DEFUN([_LT_AC_SHELL_INIT])])
+m4_ifndef([_LT_AC_SYS_LIBPATH_AIX], [AC_DEFUN([_LT_AC_SYS_LIBPATH_AIX])])
+m4_ifndef([_LT_PROG_LTMAIN], [AC_DEFUN([_LT_PROG_LTMAIN])])
+m4_ifndef([_LT_AC_TAGVAR], [AC_DEFUN([_LT_AC_TAGVAR])])
+m4_ifndef([AC_LTDL_ENABLE_INSTALL], [AC_DEFUN([AC_LTDL_ENABLE_INSTALL])])
+m4_ifndef([AC_LTDL_PREOPEN], [AC_DEFUN([AC_LTDL_PREOPEN])])
+m4_ifndef([_LT_AC_SYS_COMPILER], [AC_DEFUN([_LT_AC_SYS_COMPILER])])
+m4_ifndef([_LT_AC_LOCK], [AC_DEFUN([_LT_AC_LOCK])])
+m4_ifndef([AC_LIBTOOL_SYS_OLD_ARCHIVE], [AC_DEFUN([AC_LIBTOOL_SYS_OLD_ARCHIVE])])
+m4_ifndef([_LT_AC_TRY_DLOPEN_SELF], [AC_DEFUN([_LT_AC_TRY_DLOPEN_SELF])])
+m4_ifndef([AC_LIBTOOL_PROG_CC_C_O], [AC_DEFUN([AC_LIBTOOL_PROG_CC_C_O])])
+m4_ifndef([AC_LIBTOOL_SYS_HARD_LINK_LOCKS], [AC_DEFUN([AC_LIBTOOL_SYS_HARD_LINK_LOCKS])])
+m4_ifndef([AC_LIBTOOL_OBJDIR], [AC_DEFUN([AC_LIBTOOL_OBJDIR])])
+m4_ifndef([AC_LTDL_OBJDIR], [AC_DEFUN([AC_LTDL_OBJDIR])])
+m4_ifndef([AC_LIBTOOL_PROG_LD_HARDCODE_LIBPATH], [AC_DEFUN([AC_LIBTOOL_PROG_LD_HARDCODE_LIBPATH])])
+m4_ifndef([AC_LIBTOOL_SYS_LIB_STRIP], [AC_DEFUN([AC_LIBTOOL_SYS_LIB_STRIP])])
+m4_ifndef([AC_PATH_MAGIC], [AC_DEFUN([AC_PATH_MAGIC])])
+m4_ifndef([AC_PROG_LD_GNU], [AC_DEFUN([AC_PROG_LD_GNU])])
+m4_ifndef([AC_PROG_LD_RELOAD_FLAG], [AC_DEFUN([AC_PROG_LD_RELOAD_FLAG])])
+m4_ifndef([AC_DEPLIBS_CHECK_METHOD], [AC_DEFUN([AC_DEPLIBS_CHECK_METHOD])])
+m4_ifndef([AC_LIBTOOL_PROG_COMPILER_NO_RTTI], [AC_DEFUN([AC_LIBTOOL_PROG_COMPILER_NO_RTTI])])
+m4_ifndef([AC_LIBTOOL_SYS_GLOBAL_SYMBOL_PIPE], [AC_DEFUN([AC_LIBTOOL_SYS_GLOBAL_SYMBOL_PIPE])])
+m4_ifndef([AC_LIBTOOL_PROG_COMPILER_PIC], [AC_DEFUN([AC_LIBTOOL_PROG_COMPILER_PIC])])
+m4_ifndef([AC_LIBTOOL_PROG_LD_SHLIBS], [AC_DEFUN([AC_LIBTOOL_PROG_LD_SHLIBS])])
+m4_ifndef([AC_LIBTOOL_POSTDEP_PREDEP], [AC_DEFUN([AC_LIBTOOL_POSTDEP_PREDEP])])
+m4_ifndef([LT_AC_PROG_EGREP], [AC_DEFUN([LT_AC_PROG_EGREP])])
+m4_ifndef([LT_AC_PROG_SED], [AC_DEFUN([LT_AC_PROG_SED])])
+m4_ifndef([_LT_CC_BASENAME], [AC_DEFUN([_LT_CC_BASENAME])])
+m4_ifndef([_LT_COMPILER_BOILERPLATE], [AC_DEFUN([_LT_COMPILER_BOILERPLATE])])
+m4_ifndef([_LT_LINKER_BOILERPLATE], [AC_DEFUN([_LT_LINKER_BOILERPLATE])])
+m4_ifndef([_AC_PROG_LIBTOOL], [AC_DEFUN([_AC_PROG_LIBTOOL])])
+m4_ifndef([AC_LIBTOOL_SETUP], [AC_DEFUN([AC_LIBTOOL_SETUP])])
+m4_ifndef([_LT_AC_CHECK_DLFCN], [AC_DEFUN([_LT_AC_CHECK_DLFCN])])
+m4_ifndef([AC_LIBTOOL_SYS_DYNAMIC_LINKER], [AC_DEFUN([AC_LIBTOOL_SYS_DYNAMIC_LINKER])])
+m4_ifndef([_LT_AC_TAGCONFIG], [AC_DEFUN([_LT_AC_TAGCONFIG])])
+m4_ifndef([AC_DISABLE_FAST_INSTALL], [AC_DEFUN([AC_DISABLE_FAST_INSTALL])])
+m4_ifndef([_LT_AC_LANG_CXX], [AC_DEFUN([_LT_AC_LANG_CXX])])
+m4_ifndef([_LT_AC_LANG_F77], [AC_DEFUN([_LT_AC_LANG_F77])])
+m4_ifndef([_LT_AC_LANG_GCJ], [AC_DEFUN([_LT_AC_LANG_GCJ])])
+m4_ifndef([AC_LIBTOOL_RC], [AC_DEFUN([AC_LIBTOOL_RC])])
+m4_ifndef([AC_LIBTOOL_LANG_C_CONFIG], [AC_DEFUN([AC_LIBTOOL_LANG_C_CONFIG])])
+m4_ifndef([_LT_AC_LANG_C_CONFIG], [AC_DEFUN([_LT_AC_LANG_C_CONFIG])])
+m4_ifndef([AC_LIBTOOL_LANG_CXX_CONFIG], [AC_DEFUN([AC_LIBTOOL_LANG_CXX_CONFIG])])
+m4_ifndef([_LT_AC_LANG_CXX_CONFIG], [AC_DEFUN([_LT_AC_LANG_CXX_CONFIG])])
+m4_ifndef([AC_LIBTOOL_LANG_F77_CONFIG], [AC_DEFUN([AC_LIBTOOL_LANG_F77_CONFIG])])
+m4_ifndef([_LT_AC_LANG_F77_CONFIG], [AC_DEFUN([_LT_AC_LANG_F77_CONFIG])])
+m4_ifndef([AC_LIBTOOL_LANG_GCJ_CONFIG], [AC_DEFUN([AC_LIBTOOL_LANG_GCJ_CONFIG])])
+m4_ifndef([_LT_AC_LANG_GCJ_CONFIG], [AC_DEFUN([_LT_AC_LANG_GCJ_CONFIG])])
+m4_ifndef([AC_LIBTOOL_LANG_RC_CONFIG], [AC_DEFUN([AC_LIBTOOL_LANG_RC_CONFIG])])
+m4_ifndef([_LT_AC_LANG_RC_CONFIG], [AC_DEFUN([_LT_AC_LANG_RC_CONFIG])])
+m4_ifndef([AC_LIBTOOL_CONFIG], [AC_DEFUN([AC_LIBTOOL_CONFIG])])
+m4_ifndef([_LT_AC_FILE_LTDLL_C], [AC_DEFUN([_LT_AC_FILE_LTDLL_C])])
+
+# Copyright (C) 2002, 2003, 2005, 2006, 2007, 2008 Free Software Foundation, Inc.
+#
+# This file is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# AM_AUTOMAKE_VERSION(VERSION)
+# ----------------------------
+# Automake X.Y traces this macro to ensure aclocal.m4 has been
+# generated from the m4 files accompanying Automake X.Y.
+# (This private macro should not be called outside this file.)
+AC_DEFUN([AM_AUTOMAKE_VERSION],
+[am__api_version='1.11'
+dnl Some users find AM_AUTOMAKE_VERSION and mistake it for a way to
+dnl require some minimum version. Point them to the right macro.
+m4_if([$1], [1.11.1], [],
+ [AC_FATAL([Do not call $0, use AM_INIT_AUTOMAKE([$1]).])])dnl
+])
+
+# _AM_AUTOCONF_VERSION(VERSION)
+# -----------------------------
+# aclocal traces this macro to find the Autoconf version.
+# This is a private macro too. Using m4_define simplifies
+# the logic in aclocal, which can simply ignore this definition.
+m4_define([_AM_AUTOCONF_VERSION], [])
+
+# AM_SET_CURRENT_AUTOMAKE_VERSION
+# -------------------------------
+# Call AM_AUTOMAKE_VERSION and AM_AUTOMAKE_VERSION so they can be traced.
+# This function is AC_REQUIREd by AM_INIT_AUTOMAKE.
+AC_DEFUN([AM_SET_CURRENT_AUTOMAKE_VERSION],
+[AM_AUTOMAKE_VERSION([1.11.1])dnl
+m4_ifndef([AC_AUTOCONF_VERSION],
+ [m4_copy([m4_PACKAGE_VERSION], [AC_AUTOCONF_VERSION])])dnl
+_AM_AUTOCONF_VERSION(m4_defn([AC_AUTOCONF_VERSION]))])
+
+# AM_AUX_DIR_EXPAND -*- Autoconf -*-
+
+# Copyright (C) 2001, 2003, 2005 Free Software Foundation, Inc.
+#
+# This file is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# For projects using AC_CONFIG_AUX_DIR([foo]), Autoconf sets
+# $ac_aux_dir to `$srcdir/foo'. In other projects, it is set to
+# `$srcdir', `$srcdir/..', or `$srcdir/../..'.
+#
+# Of course, Automake must honor this variable whenever it calls a
+# tool from the auxiliary directory. The problem is that $srcdir (and
+# therefore $ac_aux_dir as well) can be either absolute or relative,
+# depending on how configure is run. This is pretty annoying, since
+# it makes $ac_aux_dir quite unusable in subdirectories: in the top
+# source directory, any form will work fine, but in subdirectories a
+# relative path needs to be adjusted first.
+#
+# $ac_aux_dir/missing
+# fails when called from a subdirectory if $ac_aux_dir is relative
+# $top_srcdir/$ac_aux_dir/missing
+# fails if $ac_aux_dir is absolute,
+# fails when called from a subdirectory in a VPATH build with
+# a relative $ac_aux_dir
+#
+# The reason of the latter failure is that $top_srcdir and $ac_aux_dir
+# are both prefixed by $srcdir. In an in-source build this is usually
+# harmless because $srcdir is `.', but things will broke when you
+# start a VPATH build or use an absolute $srcdir.
+#
+# So we could use something similar to $top_srcdir/$ac_aux_dir/missing,
+# iff we strip the leading $srcdir from $ac_aux_dir. That would be:
+# am_aux_dir='\$(top_srcdir)/'`expr "$ac_aux_dir" : "$srcdir//*\(.*\)"`
+# and then we would define $MISSING as
+# MISSING="\${SHELL} $am_aux_dir/missing"
+# This will work as long as MISSING is not called from configure, because
+# unfortunately $(top_srcdir) has no meaning in configure.
+# However there are other variables, like CC, which are often used in
+# configure, and could therefore not use this "fixed" $ac_aux_dir.
+#
+# Another solution, used here, is to always expand $ac_aux_dir to an
+# absolute PATH. The drawback is that using absolute paths prevent a
+# configured tree to be moved without reconfiguration.
+
+AC_DEFUN([AM_AUX_DIR_EXPAND],
+[dnl Rely on autoconf to set up CDPATH properly.
+AC_PREREQ([2.50])dnl
+# expand $ac_aux_dir to an absolute path
+am_aux_dir=`cd $ac_aux_dir && pwd`
+])
+
+# AM_CONDITIONAL -*- Autoconf -*-
+
+# Copyright (C) 1997, 2000, 2001, 2003, 2004, 2005, 2006, 2008
+# Free Software Foundation, Inc.
+#
+# This file is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# serial 9
+
+# AM_CONDITIONAL(NAME, SHELL-CONDITION)
+# -------------------------------------
+# Define a conditional.
+AC_DEFUN([AM_CONDITIONAL],
+[AC_PREREQ(2.52)dnl
+ ifelse([$1], [TRUE], [AC_FATAL([$0: invalid condition: $1])],
+ [$1], [FALSE], [AC_FATAL([$0: invalid condition: $1])])dnl
+AC_SUBST([$1_TRUE])dnl
+AC_SUBST([$1_FALSE])dnl
+_AM_SUBST_NOTMAKE([$1_TRUE])dnl
+_AM_SUBST_NOTMAKE([$1_FALSE])dnl
+m4_define([_AM_COND_VALUE_$1], [$2])dnl
+if $2; then
+ $1_TRUE=
+ $1_FALSE='#'
+else
+ $1_TRUE='#'
+ $1_FALSE=
+fi
+AC_CONFIG_COMMANDS_PRE(
+[if test -z "${$1_TRUE}" && test -z "${$1_FALSE}"; then
+ AC_MSG_ERROR([[conditional "$1" was never defined.
+Usually this means the macro was only invoked conditionally.]])
+fi])])
+
+# Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2009
+# Free Software Foundation, Inc.
+#
+# This file is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# serial 10
+
+# There are a few dirty hacks below to avoid letting `AC_PROG_CC' be
+# written in clear, in which case automake, when reading aclocal.m4,
+# will think it sees a *use*, and therefore will trigger all it's
+# C support machinery. Also note that it means that autoscan, seeing
+# CC etc. in the Makefile, will ask for an AC_PROG_CC use...
+
+
+# _AM_DEPENDENCIES(NAME)
+# ----------------------
+# See how the compiler implements dependency checking.
+# NAME is "CC", "CXX", "GCJ", or "OBJC".
+# We try a few techniques and use that to set a single cache variable.
+#
+# We don't AC_REQUIRE the corresponding AC_PROG_CC since the latter was
+# modified to invoke _AM_DEPENDENCIES(CC); we would have a circular
+# dependency, and given that the user is not expected to run this macro,
+# just rely on AC_PROG_CC.
+AC_DEFUN([_AM_DEPENDENCIES],
+[AC_REQUIRE([AM_SET_DEPDIR])dnl
+AC_REQUIRE([AM_OUTPUT_DEPENDENCY_COMMANDS])dnl
+AC_REQUIRE([AM_MAKE_INCLUDE])dnl
+AC_REQUIRE([AM_DEP_TRACK])dnl
+
+ifelse([$1], CC, [depcc="$CC" am_compiler_list=],
+ [$1], CXX, [depcc="$CXX" am_compiler_list=],
+ [$1], OBJC, [depcc="$OBJC" am_compiler_list='gcc3 gcc'],
+ [$1], UPC, [depcc="$UPC" am_compiler_list=],
+ [$1], GCJ, [depcc="$GCJ" am_compiler_list='gcc3 gcc'],
+ [depcc="$$1" am_compiler_list=])
+
+AC_CACHE_CHECK([dependency style of $depcc],
+ [am_cv_$1_dependencies_compiler_type],
+[if test -z "$AMDEP_TRUE" && test -f "$am_depcomp"; then
+ # We make a subdir and do the tests there. Otherwise we can end up
+ # making bogus files that we don't know about and never remove. For
+ # instance it was reported that on HP-UX the gcc test will end up
+ # making a dummy file named `D' -- because `-MD' means `put the output
+ # in D'.
+ mkdir conftest.dir
+ # Copy depcomp to subdir because otherwise we won't find it if we're
+ # using a relative directory.
+ cp "$am_depcomp" conftest.dir
+ cd conftest.dir
+ # We will build objects and dependencies in a subdirectory because
+ # it helps to detect inapplicable dependency modes. For instance
+ # both Tru64's cc and ICC support -MD to output dependencies as a
+ # side effect of compilation, but ICC will put the dependencies in
+ # the current directory while Tru64 will put them in the object
+ # directory.
+ mkdir sub
+
+ am_cv_$1_dependencies_compiler_type=none
+ if test "$am_compiler_list" = ""; then
+ am_compiler_list=`sed -n ['s/^#*\([a-zA-Z0-9]*\))$/\1/p'] < ./depcomp`
+ fi
+ am__universal=false
+ m4_case([$1], [CC],
+ [case " $depcc " in #(
+ *\ -arch\ *\ -arch\ *) am__universal=true ;;
+ esac],
+ [CXX],
+ [case " $depcc " in #(
+ *\ -arch\ *\ -arch\ *) am__universal=true ;;
+ esac])
+
+ for depmode in $am_compiler_list; do
+ # Setup a source with many dependencies, because some compilers
+ # like to wrap large dependency lists on column 80 (with \), and
+ # we should not choose a depcomp mode which is confused by this.
+ #
+ # We need to recreate these files for each test, as the compiler may
+ # overwrite some of them when testing with obscure command lines.
+ # This happens at least with the AIX C compiler.
+ : > sub/conftest.c
+ for i in 1 2 3 4 5 6; do
+ echo '#include "conftst'$i'.h"' >> sub/conftest.c
+ # Using `: > sub/conftst$i.h' creates only sub/conftst1.h with
+ # Solaris 8's {/usr,}/bin/sh.
+ touch sub/conftst$i.h
+ done
+ echo "${am__include} ${am__quote}sub/conftest.Po${am__quote}" > confmf
+
+ # We check with `-c' and `-o' for the sake of the "dashmstdout"
+ # mode. It turns out that the SunPro C++ compiler does not properly
+ # handle `-M -o', and we need to detect this. Also, some Intel
+ # versions had trouble with output in subdirs
+ am__obj=sub/conftest.${OBJEXT-o}
+ am__minus_obj="-o $am__obj"
+ case $depmode in
+ gcc)
+ # This depmode causes a compiler race in universal mode.
+ test "$am__universal" = false || continue
+ ;;
+ nosideeffect)
+ # after this tag, mechanisms are not by side-effect, so they'll
+ # only be used when explicitly requested
+ if test "x$enable_dependency_tracking" = xyes; then
+ continue
+ else
+ break
+ fi
+ ;;
+ msvisualcpp | msvcmsys)
+ # This compiler won't grok `-c -o', but also, the minuso test has
+ # not run yet. These depmodes are late enough in the game, and
+ # so weak that their functioning should not be impacted.
+ am__obj=conftest.${OBJEXT-o}
+ am__minus_obj=
+ ;;
+ none) break ;;
+ esac
+ if depmode=$depmode \
+ source=sub/conftest.c object=$am__obj \
+ depfile=sub/conftest.Po tmpdepfile=sub/conftest.TPo \
+ $SHELL ./depcomp $depcc -c $am__minus_obj sub/conftest.c \
+ >/dev/null 2>conftest.err &&
+ grep sub/conftst1.h sub/conftest.Po > /dev/null 2>&1 &&
+ grep sub/conftst6.h sub/conftest.Po > /dev/null 2>&1 &&
+ grep $am__obj sub/conftest.Po > /dev/null 2>&1 &&
+ ${MAKE-make} -s -f confmf > /dev/null 2>&1; then
+ # icc doesn't choke on unknown options, it will just issue warnings
+ # or remarks (even with -Werror). So we grep stderr for any message
+ # that says an option was ignored or not supported.
+ # When given -MP, icc 7.0 and 7.1 complain thusly:
+ # icc: Command line warning: ignoring option '-M'; no argument required
+ # The diagnosis changed in icc 8.0:
+ # icc: Command line remark: option '-MP' not supported
+ if (grep 'ignoring option' conftest.err ||
+ grep 'not supported' conftest.err) >/dev/null 2>&1; then :; else
+ am_cv_$1_dependencies_compiler_type=$depmode
+ break
+ fi
+ fi
+ done
+
+ cd ..
+ rm -rf conftest.dir
+else
+ am_cv_$1_dependencies_compiler_type=none
+fi
+])
+AC_SUBST([$1DEPMODE], [depmode=$am_cv_$1_dependencies_compiler_type])
+AM_CONDITIONAL([am__fastdep$1], [
+ test "x$enable_dependency_tracking" != xno \
+ && test "$am_cv_$1_dependencies_compiler_type" = gcc3])
+])
+
+
+# AM_SET_DEPDIR
+# -------------
+# Choose a directory name for dependency files.
+# This macro is AC_REQUIREd in _AM_DEPENDENCIES
+AC_DEFUN([AM_SET_DEPDIR],
+[AC_REQUIRE([AM_SET_LEADING_DOT])dnl
+AC_SUBST([DEPDIR], ["${am__leading_dot}deps"])dnl
+])
+
+
+# AM_DEP_TRACK
+# ------------
+AC_DEFUN([AM_DEP_TRACK],
+[AC_ARG_ENABLE(dependency-tracking,
+[ --disable-dependency-tracking speeds up one-time build
+ --enable-dependency-tracking do not reject slow dependency extractors])
+if test "x$enable_dependency_tracking" != xno; then
+ am_depcomp="$ac_aux_dir/depcomp"
+ AMDEPBACKSLASH='\'
+fi
+AM_CONDITIONAL([AMDEP], [test "x$enable_dependency_tracking" != xno])
+AC_SUBST([AMDEPBACKSLASH])dnl
+_AM_SUBST_NOTMAKE([AMDEPBACKSLASH])dnl
+])
+
+# Generate code to set up dependency tracking. -*- Autoconf -*-
+
+# Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2008
+# Free Software Foundation, Inc.
+#
+# This file is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+#serial 5
+
+# _AM_OUTPUT_DEPENDENCY_COMMANDS
+# ------------------------------
+AC_DEFUN([_AM_OUTPUT_DEPENDENCY_COMMANDS],
+[{
+ # Autoconf 2.62 quotes --file arguments for eval, but not when files
+ # are listed without --file. Let's play safe and only enable the eval
+ # if we detect the quoting.
+ case $CONFIG_FILES in
+ *\'*) eval set x "$CONFIG_FILES" ;;
+ *) set x $CONFIG_FILES ;;
+ esac
+ shift
+ for mf
+ do
+ # Strip MF so we end up with the name of the file.
+ mf=`echo "$mf" | sed -e 's/:.*$//'`
+ # Check whether this is an Automake generated Makefile or not.
+ # We used to match only the files named `Makefile.in', but
+ # some people rename them; so instead we look at the file content.
+ # Grep'ing the first line is not enough: some people post-process
+ # each Makefile.in and add a new line on top of each file to say so.
+ # Grep'ing the whole file is not good either: AIX grep has a line
+ # limit of 2048, but all sed's we know have understand at least 4000.
+ if sed -n 's,^#.*generated by automake.*,X,p' "$mf" | grep X >/dev/null 2>&1; then
+ dirpart=`AS_DIRNAME("$mf")`
+ else
+ continue
+ fi
+ # Extract the definition of DEPDIR, am__include, and am__quote
+ # from the Makefile without running `make'.
+ DEPDIR=`sed -n 's/^DEPDIR = //p' < "$mf"`
+ test -z "$DEPDIR" && continue
+ am__include=`sed -n 's/^am__include = //p' < "$mf"`
+ test -z "am__include" && continue
+ am__quote=`sed -n 's/^am__quote = //p' < "$mf"`
+ # When using ansi2knr, U may be empty or an underscore; expand it
+ U=`sed -n 's/^U = //p' < "$mf"`
+ # Find all dependency output files, they are included files with
+ # $(DEPDIR) in their names. We invoke sed twice because it is the
+ # simplest approach to changing $(DEPDIR) to its actual value in the
+ # expansion.
+ for file in `sed -n "
+ s/^$am__include $am__quote\(.*(DEPDIR).*\)$am__quote"'$/\1/p' <"$mf" | \
+ sed -e 's/\$(DEPDIR)/'"$DEPDIR"'/g' -e 's/\$U/'"$U"'/g'`; do
+ # Make sure the directory exists.
+ test -f "$dirpart/$file" && continue
+ fdir=`AS_DIRNAME(["$file"])`
+ AS_MKDIR_P([$dirpart/$fdir])
+ # echo "creating $dirpart/$file"
+ echo '# dummy' > "$dirpart/$file"
+ done
+ done
+}
+])# _AM_OUTPUT_DEPENDENCY_COMMANDS
+
+
+# AM_OUTPUT_DEPENDENCY_COMMANDS
+# -----------------------------
+# This macro should only be invoked once -- use via AC_REQUIRE.
+#
+# This code is only required when automatic dependency tracking
+# is enabled. FIXME. This creates each `.P' file that we will
+# need in order to bootstrap the dependency handling code.
+AC_DEFUN([AM_OUTPUT_DEPENDENCY_COMMANDS],
+[AC_CONFIG_COMMANDS([depfiles],
+ [test x"$AMDEP_TRUE" != x"" || _AM_OUTPUT_DEPENDENCY_COMMANDS],
+ [AMDEP_TRUE="$AMDEP_TRUE" ac_aux_dir="$ac_aux_dir"])
+])
+
+# Do all the work for Automake. -*- Autoconf -*-
+
+# Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004,
+# 2005, 2006, 2008, 2009 Free Software Foundation, Inc.
+#
+# This file is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# serial 16
+
+# This macro actually does too much. Some checks are only needed if
+# your package does certain things. But this isn't really a big deal.
+
+# AM_INIT_AUTOMAKE(PACKAGE, VERSION, [NO-DEFINE])
+# AM_INIT_AUTOMAKE([OPTIONS])
+# -----------------------------------------------
+# The call with PACKAGE and VERSION arguments is the old style
+# call (pre autoconf-2.50), which is being phased out. PACKAGE
+# and VERSION should now be passed to AC_INIT and removed from
+# the call to AM_INIT_AUTOMAKE.
+# We support both call styles for the transition. After
+# the next Automake release, Autoconf can make the AC_INIT
+# arguments mandatory, and then we can depend on a new Autoconf
+# release and drop the old call support.
+AC_DEFUN([AM_INIT_AUTOMAKE],
+[AC_PREREQ([2.62])dnl
+dnl Autoconf wants to disallow AM_ names. We explicitly allow
+dnl the ones we care about.
+m4_pattern_allow([^AM_[A-Z]+FLAGS$])dnl
+AC_REQUIRE([AM_SET_CURRENT_AUTOMAKE_VERSION])dnl
+AC_REQUIRE([AC_PROG_INSTALL])dnl
+if test "`cd $srcdir && pwd`" != "`pwd`"; then
+ # Use -I$(srcdir) only when $(srcdir) != ., so that make's output
+ # is not polluted with repeated "-I."
+ AC_SUBST([am__isrc], [' -I$(srcdir)'])_AM_SUBST_NOTMAKE([am__isrc])dnl
+ # test to see if srcdir already configured
+ if test -f $srcdir/config.status; then
+ AC_MSG_ERROR([source directory already configured; run "make distclean" there first])
+ fi
+fi
+
+# test whether we have cygpath
+if test -z "$CYGPATH_W"; then
+ if (cygpath --version) >/dev/null 2>/dev/null; then
+ CYGPATH_W='cygpath -w'
+ else
+ CYGPATH_W=echo
+ fi
+fi
+AC_SUBST([CYGPATH_W])
+
+# Define the identity of the package.
+dnl Distinguish between old-style and new-style calls.
+m4_ifval([$2],
+[m4_ifval([$3], [_AM_SET_OPTION([no-define])])dnl
+ AC_SUBST([PACKAGE], [$1])dnl
+ AC_SUBST([VERSION], [$2])],
+[_AM_SET_OPTIONS([$1])dnl
+dnl Diagnose old-style AC_INIT with new-style AM_AUTOMAKE_INIT.
+m4_if(m4_ifdef([AC_PACKAGE_NAME], 1)m4_ifdef([AC_PACKAGE_VERSION], 1), 11,,
+ [m4_fatal([AC_INIT should be called with package and version arguments])])dnl
+ AC_SUBST([PACKAGE], ['AC_PACKAGE_TARNAME'])dnl
+ AC_SUBST([VERSION], ['AC_PACKAGE_VERSION'])])dnl
+
+_AM_IF_OPTION([no-define],,
+[AC_DEFINE_UNQUOTED(PACKAGE, "$PACKAGE", [Name of package])
+ AC_DEFINE_UNQUOTED(VERSION, "$VERSION", [Version number of package])])dnl
+
+# Some tools Automake needs.
+AC_REQUIRE([AM_SANITY_CHECK])dnl
+AC_REQUIRE([AC_ARG_PROGRAM])dnl
+AM_MISSING_PROG(ACLOCAL, aclocal-${am__api_version})
+AM_MISSING_PROG(AUTOCONF, autoconf)
+AM_MISSING_PROG(AUTOMAKE, automake-${am__api_version})
+AM_MISSING_PROG(AUTOHEADER, autoheader)
+AM_MISSING_PROG(MAKEINFO, makeinfo)
+AC_REQUIRE([AM_PROG_INSTALL_SH])dnl
+AC_REQUIRE([AM_PROG_INSTALL_STRIP])dnl
+AC_REQUIRE([AM_PROG_MKDIR_P])dnl
+# We need awk for the "check" target. The system "awk" is bad on
+# some platforms.
+AC_REQUIRE([AC_PROG_AWK])dnl
+AC_REQUIRE([AC_PROG_MAKE_SET])dnl
+AC_REQUIRE([AM_SET_LEADING_DOT])dnl
+_AM_IF_OPTION([tar-ustar], [_AM_PROG_TAR([ustar])],
+ [_AM_IF_OPTION([tar-pax], [_AM_PROG_TAR([pax])],
+ [_AM_PROG_TAR([v7])])])
+_AM_IF_OPTION([no-dependencies],,
+[AC_PROVIDE_IFELSE([AC_PROG_CC],
+ [_AM_DEPENDENCIES(CC)],
+ [define([AC_PROG_CC],
+ defn([AC_PROG_CC])[_AM_DEPENDENCIES(CC)])])dnl
+AC_PROVIDE_IFELSE([AC_PROG_CXX],
+ [_AM_DEPENDENCIES(CXX)],
+ [define([AC_PROG_CXX],
+ defn([AC_PROG_CXX])[_AM_DEPENDENCIES(CXX)])])dnl
+AC_PROVIDE_IFELSE([AC_PROG_OBJC],
+ [_AM_DEPENDENCIES(OBJC)],
+ [define([AC_PROG_OBJC],
+ defn([AC_PROG_OBJC])[_AM_DEPENDENCIES(OBJC)])])dnl
+])
+_AM_IF_OPTION([silent-rules], [AC_REQUIRE([AM_SILENT_RULES])])dnl
+dnl The `parallel-tests' driver may need to know about EXEEXT, so add the
+dnl `am__EXEEXT' conditional if _AM_COMPILER_EXEEXT was seen. This macro
+dnl is hooked onto _AC_COMPILER_EXEEXT early, see below.
+AC_CONFIG_COMMANDS_PRE(dnl
+[m4_provide_if([_AM_COMPILER_EXEEXT],
+ [AM_CONDITIONAL([am__EXEEXT], [test -n "$EXEEXT"])])])dnl
+])
+
+dnl Hook into `_AC_COMPILER_EXEEXT' early to learn its expansion. Do not
+dnl add the conditional right here, as _AC_COMPILER_EXEEXT may be further
+dnl mangled by Autoconf and run in a shell conditional statement.
+m4_define([_AC_COMPILER_EXEEXT],
+m4_defn([_AC_COMPILER_EXEEXT])[m4_provide([_AM_COMPILER_EXEEXT])])
+
+
+# When config.status generates a header, we must update the stamp-h file.
+# This file resides in the same directory as the config header
+# that is generated. The stamp files are numbered to have different names.
+
+# Autoconf calls _AC_AM_CONFIG_HEADER_HOOK (when defined) in the
+# loop where config.status creates the headers, so we can generate
+# our stamp files there.
+AC_DEFUN([_AC_AM_CONFIG_HEADER_HOOK],
+[# Compute $1's index in $config_headers.
+_am_arg=$1
+_am_stamp_count=1
+for _am_header in $config_headers :; do
+ case $_am_header in
+ $_am_arg | $_am_arg:* )
+ break ;;
+ * )
+ _am_stamp_count=`expr $_am_stamp_count + 1` ;;
+ esac
+done
+echo "timestamp for $_am_arg" >`AS_DIRNAME(["$_am_arg"])`/stamp-h[]$_am_stamp_count])
+
+# Copyright (C) 2001, 2003, 2005, 2008 Free Software Foundation, Inc.
+#
+# This file is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# AM_PROG_INSTALL_SH
+# ------------------
+# Define $install_sh.
+AC_DEFUN([AM_PROG_INSTALL_SH],
+[AC_REQUIRE([AM_AUX_DIR_EXPAND])dnl
+if test x"${install_sh}" != xset; then
+ case $am_aux_dir in
+ *\ * | *\ *)
+ install_sh="\${SHELL} '$am_aux_dir/install-sh'" ;;
+ *)
+ install_sh="\${SHELL} $am_aux_dir/install-sh"
+ esac
+fi
+AC_SUBST(install_sh)])
+
+# Copyright (C) 2003, 2005 Free Software Foundation, Inc.
+#
+# This file is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# serial 2
+
+# Check whether the underlying file-system supports filenames
+# with a leading dot. For instance MS-DOS doesn't.
+AC_DEFUN([AM_SET_LEADING_DOT],
+[rm -rf .tst 2>/dev/null
+mkdir .tst 2>/dev/null
+if test -d .tst; then
+ am__leading_dot=.
+else
+ am__leading_dot=_
+fi
+rmdir .tst 2>/dev/null
+AC_SUBST([am__leading_dot])])
+
+# Check to see how 'make' treats includes. -*- Autoconf -*-
+
+# Copyright (C) 2001, 2002, 2003, 2005, 2009 Free Software Foundation, Inc.
+#
+# This file is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# serial 4
+
+# AM_MAKE_INCLUDE()
+# -----------------
+# Check to see how make treats includes.
+AC_DEFUN([AM_MAKE_INCLUDE],
+[am_make=${MAKE-make}
+cat > confinc << 'END'
+am__doit:
+ @echo this is the am__doit target
+.PHONY: am__doit
+END
+# If we don't find an include directive, just comment out the code.
+AC_MSG_CHECKING([for style of include used by $am_make])
+am__include="#"
+am__quote=
+_am_result=none
+# First try GNU make style include.
+echo "include confinc" > confmf
+# Ignore all kinds of additional output from `make'.
+case `$am_make -s -f confmf 2> /dev/null` in #(
+*the\ am__doit\ target*)
+ am__include=include
+ am__quote=
+ _am_result=GNU
+ ;;
+esac
+# Now try BSD make style include.
+if test "$am__include" = "#"; then
+ echo '.include "confinc"' > confmf
+ case `$am_make -s -f confmf 2> /dev/null` in #(
+ *the\ am__doit\ target*)
+ am__include=.include
+ am__quote="\""
+ _am_result=BSD
+ ;;
+ esac
+fi
+AC_SUBST([am__include])
+AC_SUBST([am__quote])
+AC_MSG_RESULT([$_am_result])
+rm -f confinc confmf
+])
+
+# Fake the existence of programs that GNU maintainers use. -*- Autoconf -*-
+
+# Copyright (C) 1997, 1999, 2000, 2001, 2003, 2004, 2005, 2008
+# Free Software Foundation, Inc.
+#
+# This file is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# serial 6
+
+# AM_MISSING_PROG(NAME, PROGRAM)
+# ------------------------------
+AC_DEFUN([AM_MISSING_PROG],
+[AC_REQUIRE([AM_MISSING_HAS_RUN])
+$1=${$1-"${am_missing_run}$2"}
+AC_SUBST($1)])
+
+
+# AM_MISSING_HAS_RUN
+# ------------------
+# Define MISSING if not defined so far and test if it supports --run.
+# If it does, set am_missing_run to use it, otherwise, to nothing.
+AC_DEFUN([AM_MISSING_HAS_RUN],
+[AC_REQUIRE([AM_AUX_DIR_EXPAND])dnl
+AC_REQUIRE_AUX_FILE([missing])dnl
+if test x"${MISSING+set}" != xset; then
+ case $am_aux_dir in
+ *\ * | *\ *)
+ MISSING="\${SHELL} \"$am_aux_dir/missing\"" ;;
+ *)
+ MISSING="\${SHELL} $am_aux_dir/missing" ;;
+ esac
+fi
+# Use eval to expand $SHELL
+if eval "$MISSING --run true"; then
+ am_missing_run="$MISSING --run "
+else
+ am_missing_run=
+ AC_MSG_WARN([`missing' script is too old or missing])
+fi
+])
+
+# Copyright (C) 2003, 2004, 2005, 2006 Free Software Foundation, Inc.
+#
+# This file is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# AM_PROG_MKDIR_P
+# ---------------
+# Check for `mkdir -p'.
+AC_DEFUN([AM_PROG_MKDIR_P],
+[AC_PREREQ([2.60])dnl
+AC_REQUIRE([AC_PROG_MKDIR_P])dnl
+dnl Automake 1.8 to 1.9.6 used to define mkdir_p. We now use MKDIR_P,
+dnl while keeping a definition of mkdir_p for backward compatibility.
+dnl @MKDIR_P@ is magic: AC_OUTPUT adjusts its value for each Makefile.
+dnl However we cannot define mkdir_p as $(MKDIR_P) for the sake of
+dnl Makefile.ins that do not define MKDIR_P, so we do our own
+dnl adjustment using top_builddir (which is defined more often than
+dnl MKDIR_P).
+AC_SUBST([mkdir_p], ["$MKDIR_P"])dnl
+case $mkdir_p in
+ [[\\/$]]* | ?:[[\\/]]*) ;;
+ */*) mkdir_p="\$(top_builddir)/$mkdir_p" ;;
+esac
+])
+
+# Helper functions for option handling. -*- Autoconf -*-
+
+# Copyright (C) 2001, 2002, 2003, 2005, 2008 Free Software Foundation, Inc.
+#
+# This file is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# serial 4
+
+# _AM_MANGLE_OPTION(NAME)
+# -----------------------
+AC_DEFUN([_AM_MANGLE_OPTION],
+[[_AM_OPTION_]m4_bpatsubst($1, [[^a-zA-Z0-9_]], [_])])
+
+# _AM_SET_OPTION(NAME)
+# ------------------------------
+# Set option NAME. Presently that only means defining a flag for this option.
+AC_DEFUN([_AM_SET_OPTION],
+[m4_define(_AM_MANGLE_OPTION([$1]), 1)])
+
+# _AM_SET_OPTIONS(OPTIONS)
+# ----------------------------------
+# OPTIONS is a space-separated list of Automake options.
+AC_DEFUN([_AM_SET_OPTIONS],
+[m4_foreach_w([_AM_Option], [$1], [_AM_SET_OPTION(_AM_Option)])])
+
+# _AM_IF_OPTION(OPTION, IF-SET, [IF-NOT-SET])
+# -------------------------------------------
+# Execute IF-SET if OPTION is set, IF-NOT-SET otherwise.
+AC_DEFUN([_AM_IF_OPTION],
+[m4_ifset(_AM_MANGLE_OPTION([$1]), [$2], [$3])])
+
+# Check to make sure that the build environment is sane. -*- Autoconf -*-
+
+# Copyright (C) 1996, 1997, 2000, 2001, 2003, 2005, 2008
+# Free Software Foundation, Inc.
+#
+# This file is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# serial 5
+
+# AM_SANITY_CHECK
+# ---------------
+AC_DEFUN([AM_SANITY_CHECK],
+[AC_MSG_CHECKING([whether build environment is sane])
+# Just in case
+sleep 1
+echo timestamp > conftest.file
+# Reject unsafe characters in $srcdir or the absolute working directory
+# name. Accept space and tab only in the latter.
+am_lf='
+'
+case `pwd` in
+ *[[\\\"\#\$\&\'\`$am_lf]]*)
+ AC_MSG_ERROR([unsafe absolute working directory name]);;
+esac
+case $srcdir in
+ *[[\\\"\#\$\&\'\`$am_lf\ \ ]]*)
+ AC_MSG_ERROR([unsafe srcdir value: `$srcdir']);;
+esac
+
+# Do `set' in a subshell so we don't clobber the current shell's
+# arguments. Must try -L first in case configure is actually a
+# symlink; some systems play weird games with the mod time of symlinks
+# (eg FreeBSD returns the mod time of the symlink's containing
+# directory).
+if (
+ set X `ls -Lt "$srcdir/configure" conftest.file 2> /dev/null`
+ if test "$[*]" = "X"; then
+ # -L didn't work.
+ set X `ls -t "$srcdir/configure" conftest.file`
+ fi
+ rm -f conftest.file
+ if test "$[*]" != "X $srcdir/configure conftest.file" \
+ && test "$[*]" != "X conftest.file $srcdir/configure"; then
+
+ # If neither matched, then we have a broken ls. This can happen
+ # if, for instance, CONFIG_SHELL is bash and it inherits a
+ # broken ls alias from the environment. This has actually
+ # happened. Such a system could not be considered "sane".
+ AC_MSG_ERROR([ls -t appears to fail. Make sure there is not a broken
+alias in your environment])
+ fi
+
+ test "$[2]" = conftest.file
+ )
+then
+ # Ok.
+ :
+else
+ AC_MSG_ERROR([newly created file is older than distributed files!
+Check your system clock])
+fi
+AC_MSG_RESULT(yes)])
+
+# Copyright (C) 2001, 2003, 2005 Free Software Foundation, Inc.
+#
+# This file is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# AM_PROG_INSTALL_STRIP
+# ---------------------
+# One issue with vendor `install' (even GNU) is that you can't
+# specify the program used to strip binaries. This is especially
+# annoying in cross-compiling environments, where the build's strip
+# is unlikely to handle the host's binaries.
+# Fortunately install-sh will honor a STRIPPROG variable, so we
+# always use install-sh in `make install-strip', and initialize
+# STRIPPROG with the value of the STRIP variable (set by the user).
+AC_DEFUN([AM_PROG_INSTALL_STRIP],
+[AC_REQUIRE([AM_PROG_INSTALL_SH])dnl
+# Installed binaries are usually stripped using `strip' when the user
+# run `make install-strip'. However `strip' might not be the right
+# tool to use in cross-compilation environments, therefore Automake
+# will honor the `STRIP' environment variable to overrule this program.
+dnl Don't test for $cross_compiling = yes, because it might be `maybe'.
+if test "$cross_compiling" != no; then
+ AC_CHECK_TOOL([STRIP], [strip], :)
+fi
+INSTALL_STRIP_PROGRAM="\$(install_sh) -c -s"
+AC_SUBST([INSTALL_STRIP_PROGRAM])])
+
+# Copyright (C) 2006, 2008 Free Software Foundation, Inc.
+#
+# This file is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# serial 2
+
+# _AM_SUBST_NOTMAKE(VARIABLE)
+# ---------------------------
+# Prevent Automake from outputting VARIABLE = @VARIABLE@ in Makefile.in.
+# This macro is traced by Automake.
+AC_DEFUN([_AM_SUBST_NOTMAKE])
+
+# AM_SUBST_NOTMAKE(VARIABLE)
+# ---------------------------
+# Public sister of _AM_SUBST_NOTMAKE.
+AC_DEFUN([AM_SUBST_NOTMAKE], [_AM_SUBST_NOTMAKE($@)])
+
+# Check how to create a tarball. -*- Autoconf -*-
+
+# Copyright (C) 2004, 2005 Free Software Foundation, Inc.
+#
+# This file is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# serial 2
+
+# _AM_PROG_TAR(FORMAT)
+# --------------------
+# Check how to create a tarball in format FORMAT.
+# FORMAT should be one of `v7', `ustar', or `pax'.
+#
+# Substitute a variable $(am__tar) that is a command
+# writing to stdout a FORMAT-tarball containing the directory
+# $tardir.
+# tardir=directory && $(am__tar) > result.tar
+#
+# Substitute a variable $(am__untar) that extract such
+# a tarball read from stdin.
+# $(am__untar) < result.tar
+AC_DEFUN([_AM_PROG_TAR],
+[# Always define AMTAR for backward compatibility.
+AM_MISSING_PROG([AMTAR], [tar])
+m4_if([$1], [v7],
+ [am__tar='${AMTAR} chof - "$$tardir"'; am__untar='${AMTAR} xf -'],
+ [m4_case([$1], [ustar],, [pax],,
+ [m4_fatal([Unknown tar format])])
+AC_MSG_CHECKING([how to create a $1 tar archive])
+# Loop over all known methods to create a tar archive until one works.
+_am_tools='gnutar m4_if([$1], [ustar], [plaintar]) pax cpio none'
+_am_tools=${am_cv_prog_tar_$1-$_am_tools}
+# Do not fold the above two line into one, because Tru64 sh and
+# Solaris sh will not grok spaces in the rhs of `-'.
+for _am_tool in $_am_tools
+do
+ case $_am_tool in
+ gnutar)
+ for _am_tar in tar gnutar gtar;
+ do
+ AM_RUN_LOG([$_am_tar --version]) && break
+ done
+ am__tar="$_am_tar --format=m4_if([$1], [pax], [posix], [$1]) -chf - "'"$$tardir"'
+ am__tar_="$_am_tar --format=m4_if([$1], [pax], [posix], [$1]) -chf - "'"$tardir"'
+ am__untar="$_am_tar -xf -"
+ ;;
+ plaintar)
+ # Must skip GNU tar: if it does not support --format= it doesn't create
+ # ustar tarball either.
+ (tar --version) >/dev/null 2>&1 && continue
+ am__tar='tar chf - "$$tardir"'
+ am__tar_='tar chf - "$tardir"'
+ am__untar='tar xf -'
+ ;;
+ pax)
+ am__tar='pax -L -x $1 -w "$$tardir"'
+ am__tar_='pax -L -x $1 -w "$tardir"'
+ am__untar='pax -r'
+ ;;
+ cpio)
+ am__tar='find "$$tardir" -print | cpio -o -H $1 -L'
+ am__tar_='find "$tardir" -print | cpio -o -H $1 -L'
+ am__untar='cpio -i -H $1 -d'
+ ;;
+ none)
+ am__tar=false
+ am__tar_=false
+ am__untar=false
+ ;;
+ esac
+
+ # If the value was cached, stop now. We just wanted to have am__tar
+ # and am__untar set.
+ test -n "${am_cv_prog_tar_$1}" && break
+
+ # tar/untar a dummy directory, and stop if the command works
+ rm -rf conftest.dir
+ mkdir conftest.dir
+ echo GrepMe > conftest.dir/file
+ AM_RUN_LOG([tardir=conftest.dir && eval $am__tar_ >conftest.tar])
+ rm -rf conftest.dir
+ if test -s conftest.tar; then
+ AM_RUN_LOG([$am__untar <conftest.tar])
+ grep GrepMe conftest.dir/file >/dev/null 2>&1 && break
+ fi
+done
+rm -rf conftest.dir
+
+AC_CACHE_VAL([am_cv_prog_tar_$1], [am_cv_prog_tar_$1=$_am_tool])
+AC_MSG_RESULT([$am_cv_prog_tar_$1])])
+AC_SUBST([am__tar])
+AC_SUBST([am__untar])
+]) # _AM_PROG_TAR
+
diff --git a/contrib/libyaml/config.h.in b/contrib/libyaml/config.h.in
new file mode 100644
index 0000000..1836546
--- /dev/null
+++ b/contrib/libyaml/config.h.in
@@ -0,0 +1,80 @@
+/* config.h.in. Generated from configure.ac by autoheader. */
+
+/* Define to 1 if you have the <dlfcn.h> header file. */
+#undef HAVE_DLFCN_H
+
+/* Define to 1 if you have the <inttypes.h> header file. */
+#undef HAVE_INTTYPES_H
+
+/* Define to 1 if you have the <memory.h> header file. */
+#undef HAVE_MEMORY_H
+
+/* Define to 1 if you have the <stdint.h> header file. */
+#undef HAVE_STDINT_H
+
+/* Define to 1 if you have the <stdlib.h> header file. */
+#undef HAVE_STDLIB_H
+
+/* Define to 1 if you have the <strings.h> header file. */
+#undef HAVE_STRINGS_H
+
+/* Define to 1 if you have the <string.h> header file. */
+#undef HAVE_STRING_H
+
+/* Define to 1 if you have the <sys/stat.h> header file. */
+#undef HAVE_SYS_STAT_H
+
+/* Define to 1 if you have the <sys/types.h> header file. */
+#undef HAVE_SYS_TYPES_H
+
+/* Define to 1 if you have the <unistd.h> header file. */
+#undef HAVE_UNISTD_H
+
+/* Define to the sub-directory in which libtool stores uninstalled libraries.
+ */
+#undef LT_OBJDIR
+
+/* Name of package */
+#undef PACKAGE
+
+/* Define to the address where bug reports for this package should be sent. */
+#undef PACKAGE_BUGREPORT
+
+/* Define to the full name of this package. */
+#undef PACKAGE_NAME
+
+/* Define to the full name and version of this package. */
+#undef PACKAGE_STRING
+
+/* Define to the one symbol short name of this package. */
+#undef PACKAGE_TARNAME
+
+/* Define to the home page for this package. */
+#undef PACKAGE_URL
+
+/* Define to the version of this package. */
+#undef PACKAGE_VERSION
+
+/* Define to 1 if you have the ANSI C header files. */
+#undef STDC_HEADERS
+
+/* Version number of package */
+#undef VERSION
+
+/* Define the major version number. */
+#undef YAML_VERSION_MAJOR
+
+/* Define the minor version number. */
+#undef YAML_VERSION_MINOR
+
+/* Define the patch version number. */
+#undef YAML_VERSION_PATCH
+
+/* Define the version string. */
+#undef YAML_VERSION_STRING
+
+/* Define to empty if `const' does not conform to ANSI C. */
+#undef const
+
+/* Define to `unsigned int' if <sys/types.h> does not define. */
+#undef size_t
diff --git a/contrib/libyaml/config/config.guess b/contrib/libyaml/config/config.guess
new file mode 100755
index 0000000..c2246a4
--- /dev/null
+++ b/contrib/libyaml/config/config.guess
@@ -0,0 +1,1502 @@
+#! /bin/sh
+# Attempt to guess a canonical system name.
+# Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
+# 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010
+# Free Software Foundation, Inc.
+
+timestamp='2009-12-30'
+
+# This file 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., 51 Franklin Street - Fifth Floor, Boston, MA
+# 02110-1301, 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.
+
+
+# Originally written by Per Bothner. Please send patches (context
+# diff format) to <config-patches@gnu.org> and include a ChangeLog
+# entry.
+#
+# This script attempts to guess a canonical system name similar to
+# config.sub. If it succeeds, it prints the system name on stdout, and
+# exits with 0. Otherwise, it exits with 1.
+#
+# You can get the latest version of this script from:
+# http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.guess;hb=HEAD
+
+me=`echo "$0" | sed -e 's,.*/,,'`
+
+usage="\
+Usage: $0 [OPTION]
+
+Output the configuration name of the system \`$me' is run on.
+
+Operation modes:
+ -h, --help print this help, then exit
+ -t, --time-stamp print date of last modification, then exit
+ -v, --version print version number, then exit
+
+Report bugs and patches to <config-patches@gnu.org>."
+
+version="\
+GNU config.guess ($timestamp)
+
+Originally written by Per Bothner.
+Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000,
+2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010 Free
+Software Foundation, Inc.
+
+This is free software; see the source for copying conditions. There is NO
+warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE."
+
+help="
+Try \`$me --help' for more information."
+
+# Parse command line
+while test $# -gt 0 ; do
+ case $1 in
+ --time-stamp | --time* | -t )
+ echo "$timestamp" ; exit ;;
+ --version | -v )
+ echo "$version" ; exit ;;
+ --help | --h* | -h )
+ echo "$usage"; exit ;;
+ -- ) # Stop option processing
+ shift; break ;;
+ - ) # Use stdin as input.
+ break ;;
+ -* )
+ echo "$me: invalid option $1$help" >&2
+ exit 1 ;;
+ * )
+ break ;;
+ esac
+done
+
+if test $# != 0; then
+ echo "$me: too many arguments$help" >&2
+ exit 1
+fi
+
+trap 'exit 1' 1 2 15
+
+# CC_FOR_BUILD -- compiler used by this script. Note that the use of a
+# compiler to aid in system detection is discouraged as it requires
+# temporary files to be created and, as you can see below, it is a
+# headache to deal with in a portable fashion.
+
+# Historically, `CC_FOR_BUILD' used to be named `HOST_CC'. We still
+# use `HOST_CC' if defined, but it is deprecated.
+
+# Portable tmp directory creation inspired by the Autoconf team.
+
+set_cc_for_build='
+trap "exitcode=\$?; (rm -f \$tmpfiles 2>/dev/null; rmdir \$tmp 2>/dev/null) && exit \$exitcode" 0 ;
+trap "rm -f \$tmpfiles 2>/dev/null; rmdir \$tmp 2>/dev/null; exit 1" 1 2 13 15 ;
+: ${TMPDIR=/tmp} ;
+ { tmp=`(umask 077 && mktemp -d "$TMPDIR/cgXXXXXX") 2>/dev/null` && test -n "$tmp" && test -d "$tmp" ; } ||
+ { test -n "$RANDOM" && tmp=$TMPDIR/cg$$-$RANDOM && (umask 077 && mkdir $tmp) ; } ||
+ { tmp=$TMPDIR/cg-$$ && (umask 077 && mkdir $tmp) && echo "Warning: creating insecure temp directory" >&2 ; } ||
+ { echo "$me: cannot create a temporary directory in $TMPDIR" >&2 ; exit 1 ; } ;
+dummy=$tmp/dummy ;
+tmpfiles="$dummy.c $dummy.o $dummy.rel $dummy" ;
+case $CC_FOR_BUILD,$HOST_CC,$CC in
+ ,,) echo "int x;" > $dummy.c ;
+ for c in cc gcc c89 c99 ; do
+ if ($c -c -o $dummy.o $dummy.c) >/dev/null 2>&1 ; then
+ CC_FOR_BUILD="$c"; break ;
+ fi ;
+ done ;
+ if test x"$CC_FOR_BUILD" = x ; then
+ CC_FOR_BUILD=no_compiler_found ;
+ fi
+ ;;
+ ,,*) CC_FOR_BUILD=$CC ;;
+ ,*,*) CC_FOR_BUILD=$HOST_CC ;;
+esac ; set_cc_for_build= ;'
+
+# This is needed to find uname on a Pyramid OSx when run in the BSD universe.
+# (ghazi@noc.rutgers.edu 1994-08-24)
+if (test -f /.attbin/uname) >/dev/null 2>&1 ; then
+ PATH=$PATH:/.attbin ; export PATH
+fi
+
+UNAME_MACHINE=`(uname -m) 2>/dev/null` || UNAME_MACHINE=unknown
+UNAME_RELEASE=`(uname -r) 2>/dev/null` || UNAME_RELEASE=unknown
+UNAME_SYSTEM=`(uname -s) 2>/dev/null` || UNAME_SYSTEM=unknown
+UNAME_VERSION=`(uname -v) 2>/dev/null` || UNAME_VERSION=unknown
+
+# Note: order is significant - the case branches are not exclusive.
+
+case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in
+ *:NetBSD:*:*)
+ # NetBSD (nbsd) targets should (where applicable) match one or
+ # more of the tupples: *-*-netbsdelf*, *-*-netbsdaout*,
+ # *-*-netbsdecoff* and *-*-netbsd*. For targets that recently
+ # switched to ELF, *-*-netbsd* would select the old
+ # object file format. This provides both forward
+ # compatibility and a consistent mechanism for selecting the
+ # object file format.
+ #
+ # Note: NetBSD doesn't particularly care about the vendor
+ # portion of the name. We always set it to "unknown".
+ sysctl="sysctl -n hw.machine_arch"
+ UNAME_MACHINE_ARCH=`(/sbin/$sysctl 2>/dev/null || \
+ /usr/sbin/$sysctl 2>/dev/null || echo unknown)`
+ case "${UNAME_MACHINE_ARCH}" in
+ armeb) machine=armeb-unknown ;;
+ arm*) machine=arm-unknown ;;
+ sh3el) machine=shl-unknown ;;
+ sh3eb) machine=sh-unknown ;;
+ sh5el) machine=sh5le-unknown ;;
+ *) machine=${UNAME_MACHINE_ARCH}-unknown ;;
+ esac
+ # The Operating System including object format, if it has switched
+ # to ELF recently, or will in the future.
+ case "${UNAME_MACHINE_ARCH}" in
+ arm*|i386|m68k|ns32k|sh3*|sparc|vax)
+ eval $set_cc_for_build
+ if echo __ELF__ | $CC_FOR_BUILD -E - 2>/dev/null \
+ | grep -q __ELF__
+ then
+ # Once all utilities can be ECOFF (netbsdecoff) or a.out (netbsdaout).
+ # Return netbsd for either. FIX?
+ os=netbsd
+ else
+ os=netbsdelf
+ fi
+ ;;
+ *)
+ os=netbsd
+ ;;
+ esac
+ # The OS release
+ # Debian GNU/NetBSD machines have a different userland, and
+ # thus, need a distinct triplet. However, they do not need
+ # kernel version information, so it can be replaced with a
+ # suitable tag, in the style of linux-gnu.
+ case "${UNAME_VERSION}" in
+ Debian*)
+ release='-gnu'
+ ;;
+ *)
+ release=`echo ${UNAME_RELEASE}|sed -e 's/[-_].*/\./'`
+ ;;
+ esac
+ # Since CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM:
+ # contains redundant information, the shorter form:
+ # CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM is used.
+ echo "${machine}-${os}${release}"
+ exit ;;
+ *:OpenBSD:*:*)
+ UNAME_MACHINE_ARCH=`arch | sed 's/OpenBSD.//'`
+ echo ${UNAME_MACHINE_ARCH}-unknown-openbsd${UNAME_RELEASE}
+ exit ;;
+ *:ekkoBSD:*:*)
+ echo ${UNAME_MACHINE}-unknown-ekkobsd${UNAME_RELEASE}
+ exit ;;
+ *:SolidBSD:*:*)
+ echo ${UNAME_MACHINE}-unknown-solidbsd${UNAME_RELEASE}
+ exit ;;
+ macppc:MirBSD:*:*)
+ echo powerpc-unknown-mirbsd${UNAME_RELEASE}
+ exit ;;
+ *:MirBSD:*:*)
+ echo ${UNAME_MACHINE}-unknown-mirbsd${UNAME_RELEASE}
+ exit ;;
+ alpha:OSF1:*:*)
+ case $UNAME_RELEASE in
+ *4.0)
+ UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $3}'`
+ ;;
+ *5.*)
+ UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $4}'`
+ ;;
+ esac
+ # According to Compaq, /usr/sbin/psrinfo has been available on
+ # OSF/1 and Tru64 systems produced since 1995. I hope that
+ # covers most systems running today. This code pipes the CPU
+ # types through head -n 1, so we only detect the type of CPU 0.
+ ALPHA_CPU_TYPE=`/usr/sbin/psrinfo -v | sed -n -e 's/^ The alpha \(.*\) processor.*$/\1/p' | head -n 1`
+ case "$ALPHA_CPU_TYPE" in
+ "EV4 (21064)")
+ UNAME_MACHINE="alpha" ;;
+ "EV4.5 (21064)")
+ UNAME_MACHINE="alpha" ;;
+ "LCA4 (21066/21068)")
+ UNAME_MACHINE="alpha" ;;
+ "EV5 (21164)")
+ UNAME_MACHINE="alphaev5" ;;
+ "EV5.6 (21164A)")
+ UNAME_MACHINE="alphaev56" ;;
+ "EV5.6 (21164PC)")
+ UNAME_MACHINE="alphapca56" ;;
+ "EV5.7 (21164PC)")
+ UNAME_MACHINE="alphapca57" ;;
+ "EV6 (21264)")
+ UNAME_MACHINE="alphaev6" ;;
+ "EV6.7 (21264A)")
+ UNAME_MACHINE="alphaev67" ;;
+ "EV6.8CB (21264C)")
+ UNAME_MACHINE="alphaev68" ;;
+ "EV6.8AL (21264B)")
+ UNAME_MACHINE="alphaev68" ;;
+ "EV6.8CX (21264D)")
+ UNAME_MACHINE="alphaev68" ;;
+ "EV6.9A (21264/EV69A)")
+ UNAME_MACHINE="alphaev69" ;;
+ "EV7 (21364)")
+ UNAME_MACHINE="alphaev7" ;;
+ "EV7.9 (21364A)")
+ UNAME_MACHINE="alphaev79" ;;
+ esac
+ # A Pn.n version is a patched version.
+ # A Vn.n version is a released version.
+ # A Tn.n version is a released field test version.
+ # A Xn.n version is an unreleased experimental baselevel.
+ # 1.2 uses "1.2" for uname -r.
+ echo ${UNAME_MACHINE}-dec-osf`echo ${UNAME_RELEASE} | sed -e 's/^[PVTX]//' | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'`
+ exit ;;
+ Alpha\ *:Windows_NT*:*)
+ # How do we know it's Interix rather than the generic POSIX subsystem?
+ # Should we change UNAME_MACHINE based on the output of uname instead
+ # of the specific Alpha model?
+ echo alpha-pc-interix
+ exit ;;
+ 21064:Windows_NT:50:3)
+ echo alpha-dec-winnt3.5
+ exit ;;
+ Amiga*:UNIX_System_V:4.0:*)
+ echo m68k-unknown-sysv4
+ exit ;;
+ *:[Aa]miga[Oo][Ss]:*:*)
+ echo ${UNAME_MACHINE}-unknown-amigaos
+ exit ;;
+ *:[Mm]orph[Oo][Ss]:*:*)
+ echo ${UNAME_MACHINE}-unknown-morphos
+ exit ;;
+ *:OS/390:*:*)
+ echo i370-ibm-openedition
+ exit ;;
+ *:z/VM:*:*)
+ echo s390-ibm-zvmoe
+ exit ;;
+ *:OS400:*:*)
+ echo powerpc-ibm-os400
+ exit ;;
+ arm:RISC*:1.[012]*:*|arm:riscix:1.[012]*:*)
+ echo arm-acorn-riscix${UNAME_RELEASE}
+ exit ;;
+ arm:riscos:*:*|arm:RISCOS:*:*)
+ echo arm-unknown-riscos
+ exit ;;
+ SR2?01:HI-UX/MPP:*:* | SR8000:HI-UX/MPP:*:*)
+ echo hppa1.1-hitachi-hiuxmpp
+ exit ;;
+ Pyramid*:OSx*:*:* | MIS*:OSx*:*:* | MIS*:SMP_DC-OSx*:*:*)
+ # akee@wpdis03.wpafb.af.mil (Earle F. Ake) contributed MIS and NILE.
+ if test "`(/bin/universe) 2>/dev/null`" = att ; then
+ echo pyramid-pyramid-sysv3
+ else
+ echo pyramid-pyramid-bsd
+ fi
+ exit ;;
+ NILE*:*:*:dcosx)
+ echo pyramid-pyramid-svr4
+ exit ;;
+ DRS?6000:unix:4.0:6*)
+ echo sparc-icl-nx6
+ exit ;;
+ DRS?6000:UNIX_SV:4.2*:7* | DRS?6000:isis:4.2*:7*)
+ case `/usr/bin/uname -p` in
+ sparc) echo sparc-icl-nx7; exit ;;
+ esac ;;
+ s390x:SunOS:*:*)
+ echo ${UNAME_MACHINE}-ibm-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
+ exit ;;
+ sun4H:SunOS:5.*:*)
+ echo sparc-hal-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
+ exit ;;
+ sun4*:SunOS:5.*:* | tadpole*:SunOS:5.*:*)
+ echo sparc-sun-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
+ exit ;;
+ i86pc:AuroraUX:5.*:* | i86xen:AuroraUX:5.*:*)
+ echo i386-pc-auroraux${UNAME_RELEASE}
+ exit ;;
+ i86pc:SunOS:5.*:* | i86xen:SunOS:5.*:*)
+ eval $set_cc_for_build
+ SUN_ARCH="i386"
+ # If there is a compiler, see if it is configured for 64-bit objects.
+ # Note that the Sun cc does not turn __LP64__ into 1 like gcc does.
+ # This test works for both compilers.
+ if [ "$CC_FOR_BUILD" != 'no_compiler_found' ]; then
+ if (echo '#ifdef __amd64'; echo IS_64BIT_ARCH; echo '#endif') | \
+ (CCOPTS= $CC_FOR_BUILD -E - 2>/dev/null) | \
+ grep IS_64BIT_ARCH >/dev/null
+ then
+ SUN_ARCH="x86_64"
+ fi
+ fi
+ echo ${SUN_ARCH}-pc-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
+ exit ;;
+ sun4*:SunOS:6*:*)
+ # According to config.sub, this is the proper way to canonicalize
+ # SunOS6. Hard to guess exactly what SunOS6 will be like, but
+ # it's likely to be more like Solaris than SunOS4.
+ echo sparc-sun-solaris3`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
+ exit ;;
+ sun4*:SunOS:*:*)
+ case "`/usr/bin/arch -k`" in
+ Series*|S4*)
+ UNAME_RELEASE=`uname -v`
+ ;;
+ esac
+ # Japanese Language versions have a version number like `4.1.3-JL'.
+ echo sparc-sun-sunos`echo ${UNAME_RELEASE}|sed -e 's/-/_/'`
+ exit ;;
+ sun3*:SunOS:*:*)
+ echo m68k-sun-sunos${UNAME_RELEASE}
+ exit ;;
+ sun*:*:4.2BSD:*)
+ UNAME_RELEASE=`(sed 1q /etc/motd | awk '{print substr($5,1,3)}') 2>/dev/null`
+ test "x${UNAME_RELEASE}" = "x" && UNAME_RELEASE=3
+ case "`/bin/arch`" in
+ sun3)
+ echo m68k-sun-sunos${UNAME_RELEASE}
+ ;;
+ sun4)
+ echo sparc-sun-sunos${UNAME_RELEASE}
+ ;;
+ esac
+ exit ;;
+ aushp:SunOS:*:*)
+ echo sparc-auspex-sunos${UNAME_RELEASE}
+ exit ;;
+ # The situation for MiNT is a little confusing. The machine name
+ # can be virtually everything (everything which is not
+ # "atarist" or "atariste" at least should have a processor
+ # > m68000). The system name ranges from "MiNT" over "FreeMiNT"
+ # to the lowercase version "mint" (or "freemint"). Finally
+ # the system name "TOS" denotes a system which is actually not
+ # MiNT. But MiNT is downward compatible to TOS, so this should
+ # be no problem.
+ atarist[e]:*MiNT:*:* | atarist[e]:*mint:*:* | atarist[e]:*TOS:*:*)
+ echo m68k-atari-mint${UNAME_RELEASE}
+ exit ;;
+ atari*:*MiNT:*:* | atari*:*mint:*:* | atarist[e]:*TOS:*:*)
+ echo m68k-atari-mint${UNAME_RELEASE}
+ exit ;;
+ *falcon*:*MiNT:*:* | *falcon*:*mint:*:* | *falcon*:*TOS:*:*)
+ echo m68k-atari-mint${UNAME_RELEASE}
+ exit ;;
+ milan*:*MiNT:*:* | milan*:*mint:*:* | *milan*:*TOS:*:*)
+ echo m68k-milan-mint${UNAME_RELEASE}
+ exit ;;
+ hades*:*MiNT:*:* | hades*:*mint:*:* | *hades*:*TOS:*:*)
+ echo m68k-hades-mint${UNAME_RELEASE}
+ exit ;;
+ *:*MiNT:*:* | *:*mint:*:* | *:*TOS:*:*)
+ echo m68k-unknown-mint${UNAME_RELEASE}
+ exit ;;
+ m68k:machten:*:*)
+ echo m68k-apple-machten${UNAME_RELEASE}
+ exit ;;
+ powerpc:machten:*:*)
+ echo powerpc-apple-machten${UNAME_RELEASE}
+ exit ;;
+ RISC*:Mach:*:*)
+ echo mips-dec-mach_bsd4.3
+ exit ;;
+ RISC*:ULTRIX:*:*)
+ echo mips-dec-ultrix${UNAME_RELEASE}
+ exit ;;
+ VAX*:ULTRIX*:*:*)
+ echo vax-dec-ultrix${UNAME_RELEASE}
+ exit ;;
+ 2020:CLIX:*:* | 2430:CLIX:*:*)
+ echo clipper-intergraph-clix${UNAME_RELEASE}
+ exit ;;
+ mips:*:*:UMIPS | mips:*:*:RISCos)
+ eval $set_cc_for_build
+ sed 's/^ //' << EOF >$dummy.c
+#ifdef __cplusplus
+#include <stdio.h> /* for printf() prototype */
+ int main (int argc, char *argv[]) {
+#else
+ int main (argc, argv) int argc; char *argv[]; {
+#endif
+ #if defined (host_mips) && defined (MIPSEB)
+ #if defined (SYSTYPE_SYSV)
+ printf ("mips-mips-riscos%ssysv\n", argv[1]); exit (0);
+ #endif
+ #if defined (SYSTYPE_SVR4)
+ printf ("mips-mips-riscos%ssvr4\n", argv[1]); exit (0);
+ #endif
+ #if defined (SYSTYPE_BSD43) || defined(SYSTYPE_BSD)
+ printf ("mips-mips-riscos%sbsd\n", argv[1]); exit (0);
+ #endif
+ #endif
+ exit (-1);
+ }
+EOF
+ $CC_FOR_BUILD -o $dummy $dummy.c &&
+ dummyarg=`echo "${UNAME_RELEASE}" | sed -n 's/\([0-9]*\).*/\1/p'` &&
+ SYSTEM_NAME=`$dummy $dummyarg` &&
+ { echo "$SYSTEM_NAME"; exit; }
+ echo mips-mips-riscos${UNAME_RELEASE}
+ exit ;;
+ Motorola:PowerMAX_OS:*:*)
+ echo powerpc-motorola-powermax
+ exit ;;
+ Motorola:*:4.3:PL8-*)
+ echo powerpc-harris-powermax
+ exit ;;
+ Night_Hawk:*:*:PowerMAX_OS | Synergy:PowerMAX_OS:*:*)
+ echo powerpc-harris-powermax
+ exit ;;
+ Night_Hawk:Power_UNIX:*:*)
+ echo powerpc-harris-powerunix
+ exit ;;
+ m88k:CX/UX:7*:*)
+ echo m88k-harris-cxux7
+ exit ;;
+ m88k:*:4*:R4*)
+ echo m88k-motorola-sysv4
+ exit ;;
+ m88k:*:3*:R3*)
+ echo m88k-motorola-sysv3
+ exit ;;
+ AViiON:dgux:*:*)
+ # DG/UX returns AViiON for all architectures
+ UNAME_PROCESSOR=`/usr/bin/uname -p`
+ if [ $UNAME_PROCESSOR = mc88100 ] || [ $UNAME_PROCESSOR = mc88110 ]
+ then
+ if [ ${TARGET_BINARY_INTERFACE}x = m88kdguxelfx ] || \
+ [ ${TARGET_BINARY_INTERFACE}x = x ]
+ then
+ echo m88k-dg-dgux${UNAME_RELEASE}
+ else
+ echo m88k-dg-dguxbcs${UNAME_RELEASE}
+ fi
+ else
+ echo i586-dg-dgux${UNAME_RELEASE}
+ fi
+ exit ;;
+ M88*:DolphinOS:*:*) # DolphinOS (SVR3)
+ echo m88k-dolphin-sysv3
+ exit ;;
+ M88*:*:R3*:*)
+ # Delta 88k system running SVR3
+ echo m88k-motorola-sysv3
+ exit ;;
+ XD88*:*:*:*) # Tektronix XD88 system running UTekV (SVR3)
+ echo m88k-tektronix-sysv3
+ exit ;;
+ Tek43[0-9][0-9]:UTek:*:*) # Tektronix 4300 system running UTek (BSD)
+ echo m68k-tektronix-bsd
+ exit ;;
+ *:IRIX*:*:*)
+ echo mips-sgi-irix`echo ${UNAME_RELEASE}|sed -e 's/-/_/g'`
+ exit ;;
+ ????????:AIX?:[12].1:2) # AIX 2.2.1 or AIX 2.1.1 is RT/PC AIX.
+ echo romp-ibm-aix # uname -m gives an 8 hex-code CPU id
+ exit ;; # Note that: echo "'`uname -s`'" gives 'AIX '
+ i*86:AIX:*:*)
+ echo i386-ibm-aix
+ exit ;;
+ ia64:AIX:*:*)
+ if [ -x /usr/bin/oslevel ] ; then
+ IBM_REV=`/usr/bin/oslevel`
+ else
+ IBM_REV=${UNAME_VERSION}.${UNAME_RELEASE}
+ fi
+ echo ${UNAME_MACHINE}-ibm-aix${IBM_REV}
+ exit ;;
+ *:AIX:2:3)
+ if grep bos325 /usr/include/stdio.h >/dev/null 2>&1; then
+ eval $set_cc_for_build
+ sed 's/^ //' << EOF >$dummy.c
+ #include <sys/systemcfg.h>
+
+ main()
+ {
+ if (!__power_pc())
+ exit(1);
+ puts("powerpc-ibm-aix3.2.5");
+ exit(0);
+ }
+EOF
+ if $CC_FOR_BUILD -o $dummy $dummy.c && SYSTEM_NAME=`$dummy`
+ then
+ echo "$SYSTEM_NAME"
+ else
+ echo rs6000-ibm-aix3.2.5
+ fi
+ elif grep bos324 /usr/include/stdio.h >/dev/null 2>&1; then
+ echo rs6000-ibm-aix3.2.4
+ else
+ echo rs6000-ibm-aix3.2
+ fi
+ exit ;;
+ *:AIX:*:[456])
+ IBM_CPU_ID=`/usr/sbin/lsdev -C -c processor -S available | sed 1q | awk '{ print $1 }'`
+ if /usr/sbin/lsattr -El ${IBM_CPU_ID} | grep ' POWER' >/dev/null 2>&1; then
+ IBM_ARCH=rs6000
+ else
+ IBM_ARCH=powerpc
+ fi
+ if [ -x /usr/bin/oslevel ] ; then
+ IBM_REV=`/usr/bin/oslevel`
+ else
+ IBM_REV=${UNAME_VERSION}.${UNAME_RELEASE}
+ fi
+ echo ${IBM_ARCH}-ibm-aix${IBM_REV}
+ exit ;;
+ *:AIX:*:*)
+ echo rs6000-ibm-aix
+ exit ;;
+ ibmrt:4.4BSD:*|romp-ibm:BSD:*)
+ echo romp-ibm-bsd4.4
+ exit ;;
+ ibmrt:*BSD:*|romp-ibm:BSD:*) # covers RT/PC BSD and
+ echo romp-ibm-bsd${UNAME_RELEASE} # 4.3 with uname added to
+ exit ;; # report: romp-ibm BSD 4.3
+ *:BOSX:*:*)
+ echo rs6000-bull-bosx
+ exit ;;
+ DPX/2?00:B.O.S.:*:*)
+ echo m68k-bull-sysv3
+ exit ;;
+ 9000/[34]??:4.3bsd:1.*:*)
+ echo m68k-hp-bsd
+ exit ;;
+ hp300:4.4BSD:*:* | 9000/[34]??:4.3bsd:2.*:*)
+ echo m68k-hp-bsd4.4
+ exit ;;
+ 9000/[34678]??:HP-UX:*:*)
+ HPUX_REV=`echo ${UNAME_RELEASE}|sed -e 's/[^.]*.[0B]*//'`
+ case "${UNAME_MACHINE}" in
+ 9000/31? ) HP_ARCH=m68000 ;;
+ 9000/[34]?? ) HP_ARCH=m68k ;;
+ 9000/[678][0-9][0-9])
+ if [ -x /usr/bin/getconf ]; then
+ sc_cpu_version=`/usr/bin/getconf SC_CPU_VERSION 2>/dev/null`
+ sc_kernel_bits=`/usr/bin/getconf SC_KERNEL_BITS 2>/dev/null`
+ case "${sc_cpu_version}" in
+ 523) HP_ARCH="hppa1.0" ;; # CPU_PA_RISC1_0
+ 528) HP_ARCH="hppa1.1" ;; # CPU_PA_RISC1_1
+ 532) # CPU_PA_RISC2_0
+ case "${sc_kernel_bits}" in
+ 32) HP_ARCH="hppa2.0n" ;;
+ 64) HP_ARCH="hppa2.0w" ;;
+ '') HP_ARCH="hppa2.0" ;; # HP-UX 10.20
+ esac ;;
+ esac
+ fi
+ if [ "${HP_ARCH}" = "" ]; then
+ eval $set_cc_for_build
+ sed 's/^ //' << EOF >$dummy.c
+
+ #define _HPUX_SOURCE
+ #include <stdlib.h>
+ #include <unistd.h>
+
+ int main ()
+ {
+ #if defined(_SC_KERNEL_BITS)
+ long bits = sysconf(_SC_KERNEL_BITS);
+ #endif
+ long cpu = sysconf (_SC_CPU_VERSION);
+
+ switch (cpu)
+ {
+ case CPU_PA_RISC1_0: puts ("hppa1.0"); break;
+ case CPU_PA_RISC1_1: puts ("hppa1.1"); break;
+ case CPU_PA_RISC2_0:
+ #if defined(_SC_KERNEL_BITS)
+ switch (bits)
+ {
+ case 64: puts ("hppa2.0w"); break;
+ case 32: puts ("hppa2.0n"); break;
+ default: puts ("hppa2.0"); break;
+ } break;
+ #else /* !defined(_SC_KERNEL_BITS) */
+ puts ("hppa2.0"); break;
+ #endif
+ default: puts ("hppa1.0"); break;
+ }
+ exit (0);
+ }
+EOF
+ (CCOPTS= $CC_FOR_BUILD -o $dummy $dummy.c 2>/dev/null) && HP_ARCH=`$dummy`
+ test -z "$HP_ARCH" && HP_ARCH=hppa
+ fi ;;
+ esac
+ if [ ${HP_ARCH} = "hppa2.0w" ]
+ then
+ eval $set_cc_for_build
+
+ # hppa2.0w-hp-hpux* has a 64-bit kernel and a compiler generating
+ # 32-bit code. hppa64-hp-hpux* has the same kernel and a compiler
+ # generating 64-bit code. GNU and HP use different nomenclature:
+ #
+ # $ CC_FOR_BUILD=cc ./config.guess
+ # => hppa2.0w-hp-hpux11.23
+ # $ CC_FOR_BUILD="cc +DA2.0w" ./config.guess
+ # => hppa64-hp-hpux11.23
+
+ if echo __LP64__ | (CCOPTS= $CC_FOR_BUILD -E - 2>/dev/null) |
+ grep -q __LP64__
+ then
+ HP_ARCH="hppa2.0w"
+ else
+ HP_ARCH="hppa64"
+ fi
+ fi
+ echo ${HP_ARCH}-hp-hpux${HPUX_REV}
+ exit ;;
+ ia64:HP-UX:*:*)
+ HPUX_REV=`echo ${UNAME_RELEASE}|sed -e 's/[^.]*.[0B]*//'`
+ echo ia64-hp-hpux${HPUX_REV}
+ exit ;;
+ 3050*:HI-UX:*:*)
+ eval $set_cc_for_build
+ sed 's/^ //' << EOF >$dummy.c
+ #include <unistd.h>
+ int
+ main ()
+ {
+ long cpu = sysconf (_SC_CPU_VERSION);
+ /* The order matters, because CPU_IS_HP_MC68K erroneously returns
+ true for CPU_PA_RISC1_0. CPU_IS_PA_RISC returns correct
+ results, however. */
+ if (CPU_IS_PA_RISC (cpu))
+ {
+ switch (cpu)
+ {
+ case CPU_PA_RISC1_0: puts ("hppa1.0-hitachi-hiuxwe2"); break;
+ case CPU_PA_RISC1_1: puts ("hppa1.1-hitachi-hiuxwe2"); break;
+ case CPU_PA_RISC2_0: puts ("hppa2.0-hitachi-hiuxwe2"); break;
+ default: puts ("hppa-hitachi-hiuxwe2"); break;
+ }
+ }
+ else if (CPU_IS_HP_MC68K (cpu))
+ puts ("m68k-hitachi-hiuxwe2");
+ else puts ("unknown-hitachi-hiuxwe2");
+ exit (0);
+ }
+EOF
+ $CC_FOR_BUILD -o $dummy $dummy.c && SYSTEM_NAME=`$dummy` &&
+ { echo "$SYSTEM_NAME"; exit; }
+ echo unknown-hitachi-hiuxwe2
+ exit ;;
+ 9000/7??:4.3bsd:*:* | 9000/8?[79]:4.3bsd:*:* )
+ echo hppa1.1-hp-bsd
+ exit ;;
+ 9000/8??:4.3bsd:*:*)
+ echo hppa1.0-hp-bsd
+ exit ;;
+ *9??*:MPE/iX:*:* | *3000*:MPE/iX:*:*)
+ echo hppa1.0-hp-mpeix
+ exit ;;
+ hp7??:OSF1:*:* | hp8?[79]:OSF1:*:* )
+ echo hppa1.1-hp-osf
+ exit ;;
+ hp8??:OSF1:*:*)
+ echo hppa1.0-hp-osf
+ exit ;;
+ i*86:OSF1:*:*)
+ if [ -x /usr/sbin/sysversion ] ; then
+ echo ${UNAME_MACHINE}-unknown-osf1mk
+ else
+ echo ${UNAME_MACHINE}-unknown-osf1
+ fi
+ exit ;;
+ parisc*:Lites*:*:*)
+ echo hppa1.1-hp-lites
+ exit ;;
+ C1*:ConvexOS:*:* | convex:ConvexOS:C1*:*)
+ echo c1-convex-bsd
+ exit ;;
+ C2*:ConvexOS:*:* | convex:ConvexOS:C2*:*)
+ if getsysinfo -f scalar_acc
+ then echo c32-convex-bsd
+ else echo c2-convex-bsd
+ fi
+ exit ;;
+ C34*:ConvexOS:*:* | convex:ConvexOS:C34*:*)
+ echo c34-convex-bsd
+ exit ;;
+ C38*:ConvexOS:*:* | convex:ConvexOS:C38*:*)
+ echo c38-convex-bsd
+ exit ;;
+ C4*:ConvexOS:*:* | convex:ConvexOS:C4*:*)
+ echo c4-convex-bsd
+ exit ;;
+ CRAY*Y-MP:*:*:*)
+ echo ymp-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/'
+ exit ;;
+ CRAY*[A-Z]90:*:*:*)
+ echo ${UNAME_MACHINE}-cray-unicos${UNAME_RELEASE} \
+ | sed -e 's/CRAY.*\([A-Z]90\)/\1/' \
+ -e y/ABCDEFGHIJKLMNOPQRSTUVWXYZ/abcdefghijklmnopqrstuvwxyz/ \
+ -e 's/\.[^.]*$/.X/'
+ exit ;;
+ CRAY*TS:*:*:*)
+ echo t90-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/'
+ exit ;;
+ CRAY*T3E:*:*:*)
+ echo alphaev5-cray-unicosmk${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/'
+ exit ;;
+ CRAY*SV1:*:*:*)
+ echo sv1-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/'
+ exit ;;
+ *:UNICOS/mp:*:*)
+ echo craynv-cray-unicosmp${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/'
+ exit ;;
+ F30[01]:UNIX_System_V:*:* | F700:UNIX_System_V:*:*)
+ FUJITSU_PROC=`uname -m | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'`
+ FUJITSU_SYS=`uname -p | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/\///'`
+ FUJITSU_REL=`echo ${UNAME_RELEASE} | sed -e 's/ /_/'`
+ echo "${FUJITSU_PROC}-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}"
+ exit ;;
+ 5000:UNIX_System_V:4.*:*)
+ FUJITSU_SYS=`uname -p | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/\///'`
+ FUJITSU_REL=`echo ${UNAME_RELEASE} | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/ /_/'`
+ echo "sparc-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}"
+ exit ;;
+ i*86:BSD/386:*:* | i*86:BSD/OS:*:* | *:Ascend\ Embedded/OS:*:*)
+ echo ${UNAME_MACHINE}-pc-bsdi${UNAME_RELEASE}
+ exit ;;
+ sparc*:BSD/OS:*:*)
+ echo sparc-unknown-bsdi${UNAME_RELEASE}
+ exit ;;
+ *:BSD/OS:*:*)
+ echo ${UNAME_MACHINE}-unknown-bsdi${UNAME_RELEASE}
+ exit ;;
+ *:FreeBSD:*:*)
+ case ${UNAME_MACHINE} in
+ pc98)
+ echo i386-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` ;;
+ amd64)
+ echo x86_64-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` ;;
+ *)
+ echo ${UNAME_MACHINE}-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` ;;
+ esac
+ exit ;;
+ i*:CYGWIN*:*)
+ echo ${UNAME_MACHINE}-pc-cygwin
+ exit ;;
+ *:MINGW*:*)
+ echo ${UNAME_MACHINE}-pc-mingw32
+ exit ;;
+ i*:windows32*:*)
+ # uname -m includes "-pc" on this system.
+ echo ${UNAME_MACHINE}-mingw32
+ exit ;;
+ i*:PW*:*)
+ echo ${UNAME_MACHINE}-pc-pw32
+ exit ;;
+ *:Interix*:*)
+ case ${UNAME_MACHINE} in
+ x86)
+ echo i586-pc-interix${UNAME_RELEASE}
+ exit ;;
+ authenticamd | genuineintel | EM64T)
+ echo x86_64-unknown-interix${UNAME_RELEASE}
+ exit ;;
+ IA64)
+ echo ia64-unknown-interix${UNAME_RELEASE}
+ exit ;;
+ esac ;;
+ [345]86:Windows_95:* | [345]86:Windows_98:* | [345]86:Windows_NT:*)
+ echo i${UNAME_MACHINE}-pc-mks
+ exit ;;
+ 8664:Windows_NT:*)
+ echo x86_64-pc-mks
+ exit ;;
+ i*:Windows_NT*:* | Pentium*:Windows_NT*:*)
+ # How do we know it's Interix rather than the generic POSIX subsystem?
+ # It also conflicts with pre-2.0 versions of AT&T UWIN. Should we
+ # UNAME_MACHINE based on the output of uname instead of i386?
+ echo i586-pc-interix
+ exit ;;
+ i*:UWIN*:*)
+ echo ${UNAME_MACHINE}-pc-uwin
+ exit ;;
+ amd64:CYGWIN*:*:* | x86_64:CYGWIN*:*:*)
+ echo x86_64-unknown-cygwin
+ exit ;;
+ p*:CYGWIN*:*)
+ echo powerpcle-unknown-cygwin
+ exit ;;
+ prep*:SunOS:5.*:*)
+ echo powerpcle-unknown-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
+ exit ;;
+ *:GNU:*:*)
+ # the GNU system
+ echo `echo ${UNAME_MACHINE}|sed -e 's,[-/].*$,,'`-unknown-gnu`echo ${UNAME_RELEASE}|sed -e 's,/.*$,,'`
+ exit ;;
+ *:GNU/*:*:*)
+ # other systems with GNU libc and userland
+ echo ${UNAME_MACHINE}-unknown-`echo ${UNAME_SYSTEM} | sed 's,^[^/]*/,,' | tr '[A-Z]' '[a-z]'``echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'`-gnu
+ exit ;;
+ i*86:Minix:*:*)
+ echo ${UNAME_MACHINE}-pc-minix
+ exit ;;
+ alpha:Linux:*:*)
+ case `sed -n '/^cpu model/s/^.*: \(.*\)/\1/p' < /proc/cpuinfo` in
+ EV5) UNAME_MACHINE=alphaev5 ;;
+ EV56) UNAME_MACHINE=alphaev56 ;;
+ PCA56) UNAME_MACHINE=alphapca56 ;;
+ PCA57) UNAME_MACHINE=alphapca56 ;;
+ EV6) UNAME_MACHINE=alphaev6 ;;
+ EV67) UNAME_MACHINE=alphaev67 ;;
+ EV68*) UNAME_MACHINE=alphaev68 ;;
+ esac
+ objdump --private-headers /bin/sh | grep -q ld.so.1
+ if test "$?" = 0 ; then LIBC="libc1" ; else LIBC="" ; fi
+ echo ${UNAME_MACHINE}-unknown-linux-gnu${LIBC}
+ exit ;;
+ arm*:Linux:*:*)
+ eval $set_cc_for_build
+ if echo __ARM_EABI__ | $CC_FOR_BUILD -E - 2>/dev/null \
+ | grep -q __ARM_EABI__
+ then
+ echo ${UNAME_MACHINE}-unknown-linux-gnu
+ else
+ echo ${UNAME_MACHINE}-unknown-linux-gnueabi
+ fi
+ exit ;;
+ avr32*:Linux:*:*)
+ echo ${UNAME_MACHINE}-unknown-linux-gnu
+ exit ;;
+ cris:Linux:*:*)
+ echo cris-axis-linux-gnu
+ exit ;;
+ crisv32:Linux:*:*)
+ echo crisv32-axis-linux-gnu
+ exit ;;
+ frv:Linux:*:*)
+ echo frv-unknown-linux-gnu
+ exit ;;
+ i*86:Linux:*:*)
+ LIBC=gnu
+ eval $set_cc_for_build
+ sed 's/^ //' << EOF >$dummy.c
+ #ifdef __dietlibc__
+ LIBC=dietlibc
+ #endif
+EOF
+ eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep '^LIBC'`
+ echo "${UNAME_MACHINE}-pc-linux-${LIBC}"
+ exit ;;
+ ia64:Linux:*:*)
+ echo ${UNAME_MACHINE}-unknown-linux-gnu
+ exit ;;
+ m32r*:Linux:*:*)
+ echo ${UNAME_MACHINE}-unknown-linux-gnu
+ exit ;;
+ m68*:Linux:*:*)
+ echo ${UNAME_MACHINE}-unknown-linux-gnu
+ exit ;;
+ mips:Linux:*:* | mips64:Linux:*:*)
+ eval $set_cc_for_build
+ sed 's/^ //' << EOF >$dummy.c
+ #undef CPU
+ #undef ${UNAME_MACHINE}
+ #undef ${UNAME_MACHINE}el
+ #if defined(__MIPSEL__) || defined(__MIPSEL) || defined(_MIPSEL) || defined(MIPSEL)
+ CPU=${UNAME_MACHINE}el
+ #else
+ #if defined(__MIPSEB__) || defined(__MIPSEB) || defined(_MIPSEB) || defined(MIPSEB)
+ CPU=${UNAME_MACHINE}
+ #else
+ CPU=
+ #endif
+ #endif
+EOF
+ eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep '^CPU'`
+ test x"${CPU}" != x && { echo "${CPU}-unknown-linux-gnu"; exit; }
+ ;;
+ or32:Linux:*:*)
+ echo or32-unknown-linux-gnu
+ exit ;;
+ padre:Linux:*:*)
+ echo sparc-unknown-linux-gnu
+ exit ;;
+ parisc64:Linux:*:* | hppa64:Linux:*:*)
+ echo hppa64-unknown-linux-gnu
+ exit ;;
+ parisc:Linux:*:* | hppa:Linux:*:*)
+ # Look for CPU level
+ case `grep '^cpu[^a-z]*:' /proc/cpuinfo 2>/dev/null | cut -d' ' -f2` in
+ PA7*) echo hppa1.1-unknown-linux-gnu ;;
+ PA8*) echo hppa2.0-unknown-linux-gnu ;;
+ *) echo hppa-unknown-linux-gnu ;;
+ esac
+ exit ;;
+ ppc64:Linux:*:*)
+ echo powerpc64-unknown-linux-gnu
+ exit ;;
+ ppc:Linux:*:*)
+ echo powerpc-unknown-linux-gnu
+ exit ;;
+ s390:Linux:*:* | s390x:Linux:*:*)
+ echo ${UNAME_MACHINE}-ibm-linux
+ exit ;;
+ sh64*:Linux:*:*)
+ echo ${UNAME_MACHINE}-unknown-linux-gnu
+ exit ;;
+ sh*:Linux:*:*)
+ echo ${UNAME_MACHINE}-unknown-linux-gnu
+ exit ;;
+ sparc:Linux:*:* | sparc64:Linux:*:*)
+ echo ${UNAME_MACHINE}-unknown-linux-gnu
+ exit ;;
+ vax:Linux:*:*)
+ echo ${UNAME_MACHINE}-dec-linux-gnu
+ exit ;;
+ x86_64:Linux:*:*)
+ echo x86_64-unknown-linux-gnu
+ exit ;;
+ xtensa*:Linux:*:*)
+ echo ${UNAME_MACHINE}-unknown-linux-gnu
+ exit ;;
+ i*86:DYNIX/ptx:4*:*)
+ # ptx 4.0 does uname -s correctly, with DYNIX/ptx in there.
+ # earlier versions are messed up and put the nodename in both
+ # sysname and nodename.
+ echo i386-sequent-sysv4
+ exit ;;
+ i*86:UNIX_SV:4.2MP:2.*)
+ # Unixware is an offshoot of SVR4, but it has its own version
+ # number series starting with 2...
+ # I am not positive that other SVR4 systems won't match this,
+ # I just have to hope. -- rms.
+ # Use sysv4.2uw... so that sysv4* matches it.
+ echo ${UNAME_MACHINE}-pc-sysv4.2uw${UNAME_VERSION}
+ exit ;;
+ i*86:OS/2:*:*)
+ # If we were able to find `uname', then EMX Unix compatibility
+ # is probably installed.
+ echo ${UNAME_MACHINE}-pc-os2-emx
+ exit ;;
+ i*86:XTS-300:*:STOP)
+ echo ${UNAME_MACHINE}-unknown-stop
+ exit ;;
+ i*86:atheos:*:*)
+ echo ${UNAME_MACHINE}-unknown-atheos
+ exit ;;
+ i*86:syllable:*:*)
+ echo ${UNAME_MACHINE}-pc-syllable
+ exit ;;
+ i*86:LynxOS:2.*:* | i*86:LynxOS:3.[01]*:* | i*86:LynxOS:4.[02]*:*)
+ echo i386-unknown-lynxos${UNAME_RELEASE}
+ exit ;;
+ i*86:*DOS:*:*)
+ echo ${UNAME_MACHINE}-pc-msdosdjgpp
+ exit ;;
+ i*86:*:4.*:* | i*86:SYSTEM_V:4.*:*)
+ UNAME_REL=`echo ${UNAME_RELEASE} | sed 's/\/MP$//'`
+ if grep Novell /usr/include/link.h >/dev/null 2>/dev/null; then
+ echo ${UNAME_MACHINE}-univel-sysv${UNAME_REL}
+ else
+ echo ${UNAME_MACHINE}-pc-sysv${UNAME_REL}
+ fi
+ exit ;;
+ i*86:*:5:[678]*)
+ # UnixWare 7.x, OpenUNIX and OpenServer 6.
+ case `/bin/uname -X | grep "^Machine"` in
+ *486*) UNAME_MACHINE=i486 ;;
+ *Pentium) UNAME_MACHINE=i586 ;;
+ *Pent*|*Celeron) UNAME_MACHINE=i686 ;;
+ esac
+ echo ${UNAME_MACHINE}-unknown-sysv${UNAME_RELEASE}${UNAME_SYSTEM}${UNAME_VERSION}
+ exit ;;
+ i*86:*:3.2:*)
+ if test -f /usr/options/cb.name; then
+ UNAME_REL=`sed -n 's/.*Version //p' </usr/options/cb.name`
+ echo ${UNAME_MACHINE}-pc-isc$UNAME_REL
+ elif /bin/uname -X 2>/dev/null >/dev/null ; then
+ UNAME_REL=`(/bin/uname -X|grep Release|sed -e 's/.*= //')`
+ (/bin/uname -X|grep i80486 >/dev/null) && UNAME_MACHINE=i486
+ (/bin/uname -X|grep '^Machine.*Pentium' >/dev/null) \
+ && UNAME_MACHINE=i586
+ (/bin/uname -X|grep '^Machine.*Pent *II' >/dev/null) \
+ && UNAME_MACHINE=i686
+ (/bin/uname -X|grep '^Machine.*Pentium Pro' >/dev/null) \
+ && UNAME_MACHINE=i686
+ echo ${UNAME_MACHINE}-pc-sco$UNAME_REL
+ else
+ echo ${UNAME_MACHINE}-pc-sysv32
+ fi
+ exit ;;
+ pc:*:*:*)
+ # Left here for compatibility:
+ # uname -m prints for DJGPP always 'pc', but it prints nothing about
+ # the processor, so we play safe by assuming i586.
+ # Note: whatever this is, it MUST be the same as what config.sub
+ # prints for the "djgpp" host, or else GDB configury will decide that
+ # this is a cross-build.
+ echo i586-pc-msdosdjgpp
+ exit ;;
+ Intel:Mach:3*:*)
+ echo i386-pc-mach3
+ exit ;;
+ paragon:*:*:*)
+ echo i860-intel-osf1
+ exit ;;
+ i860:*:4.*:*) # i860-SVR4
+ if grep Stardent /usr/include/sys/uadmin.h >/dev/null 2>&1 ; then
+ echo i860-stardent-sysv${UNAME_RELEASE} # Stardent Vistra i860-SVR4
+ else # Add other i860-SVR4 vendors below as they are discovered.
+ echo i860-unknown-sysv${UNAME_RELEASE} # Unknown i860-SVR4
+ fi
+ exit ;;
+ mini*:CTIX:SYS*5:*)
+ # "miniframe"
+ echo m68010-convergent-sysv
+ exit ;;
+ mc68k:UNIX:SYSTEM5:3.51m)
+ echo m68k-convergent-sysv
+ exit ;;
+ M680?0:D-NIX:5.3:*)
+ echo m68k-diab-dnix
+ exit ;;
+ M68*:*:R3V[5678]*:*)
+ test -r /sysV68 && { echo 'm68k-motorola-sysv'; exit; } ;;
+ 3[345]??:*:4.0:3.0 | 3[34]??A:*:4.0:3.0 | 3[34]??,*:*:4.0:3.0 | 3[34]??/*:*:4.0:3.0 | 4400:*:4.0:3.0 | 4850:*:4.0:3.0 | SKA40:*:4.0:3.0 | SDS2:*:4.0:3.0 | SHG2:*:4.0:3.0 | S7501*:*:4.0:3.0)
+ OS_REL=''
+ test -r /etc/.relid \
+ && OS_REL=.`sed -n 's/[^ ]* [^ ]* \([0-9][0-9]\).*/\1/p' < /etc/.relid`
+ /bin/uname -p 2>/dev/null | grep 86 >/dev/null \
+ && { echo i486-ncr-sysv4.3${OS_REL}; exit; }
+ /bin/uname -p 2>/dev/null | /bin/grep entium >/dev/null \
+ && { echo i586-ncr-sysv4.3${OS_REL}; exit; } ;;
+ 3[34]??:*:4.0:* | 3[34]??,*:*:4.0:*)
+ /bin/uname -p 2>/dev/null | grep 86 >/dev/null \
+ && { echo i486-ncr-sysv4; exit; } ;;
+ NCR*:*:4.2:* | MPRAS*:*:4.2:*)
+ OS_REL='.3'
+ test -r /etc/.relid \
+ && OS_REL=.`sed -n 's/[^ ]* [^ ]* \([0-9][0-9]\).*/\1/p' < /etc/.relid`
+ /bin/uname -p 2>/dev/null | grep 86 >/dev/null \
+ && { echo i486-ncr-sysv4.3${OS_REL}; exit; }
+ /bin/uname -p 2>/dev/null | /bin/grep entium >/dev/null \
+ && { echo i586-ncr-sysv4.3${OS_REL}; exit; }
+ /bin/uname -p 2>/dev/null | /bin/grep pteron >/dev/null \
+ && { echo i586-ncr-sysv4.3${OS_REL}; exit; } ;;
+ m68*:LynxOS:2.*:* | m68*:LynxOS:3.0*:*)
+ echo m68k-unknown-lynxos${UNAME_RELEASE}
+ exit ;;
+ mc68030:UNIX_System_V:4.*:*)
+ echo m68k-atari-sysv4
+ exit ;;
+ TSUNAMI:LynxOS:2.*:*)
+ echo sparc-unknown-lynxos${UNAME_RELEASE}
+ exit ;;
+ rs6000:LynxOS:2.*:*)
+ echo rs6000-unknown-lynxos${UNAME_RELEASE}
+ exit ;;
+ PowerPC:LynxOS:2.*:* | PowerPC:LynxOS:3.[01]*:* | PowerPC:LynxOS:4.[02]*:*)
+ echo powerpc-unknown-lynxos${UNAME_RELEASE}
+ exit ;;
+ SM[BE]S:UNIX_SV:*:*)
+ echo mips-dde-sysv${UNAME_RELEASE}
+ exit ;;
+ RM*:ReliantUNIX-*:*:*)
+ echo mips-sni-sysv4
+ exit ;;
+ RM*:SINIX-*:*:*)
+ echo mips-sni-sysv4
+ exit ;;
+ *:SINIX-*:*:*)
+ if uname -p 2>/dev/null >/dev/null ; then
+ UNAME_MACHINE=`(uname -p) 2>/dev/null`
+ echo ${UNAME_MACHINE}-sni-sysv4
+ else
+ echo ns32k-sni-sysv
+ fi
+ exit ;;
+ PENTIUM:*:4.0*:*) # Unisys `ClearPath HMP IX 4000' SVR4/MP effort
+ # says <Richard.M.Bartel@ccMail.Census.GOV>
+ echo i586-unisys-sysv4
+ exit ;;
+ *:UNIX_System_V:4*:FTX*)
+ # From Gerald Hewes <hewes@openmarket.com>.
+ # How about differentiating between stratus architectures? -djm
+ echo hppa1.1-stratus-sysv4
+ exit ;;
+ *:*:*:FTX*)
+ # From seanf@swdc.stratus.com.
+ echo i860-stratus-sysv4
+ exit ;;
+ i*86:VOS:*:*)
+ # From Paul.Green@stratus.com.
+ echo ${UNAME_MACHINE}-stratus-vos
+ exit ;;
+ *:VOS:*:*)
+ # From Paul.Green@stratus.com.
+ echo hppa1.1-stratus-vos
+ exit ;;
+ mc68*:A/UX:*:*)
+ echo m68k-apple-aux${UNAME_RELEASE}
+ exit ;;
+ news*:NEWS-OS:6*:*)
+ echo mips-sony-newsos6
+ exit ;;
+ R[34]000:*System_V*:*:* | R4000:UNIX_SYSV:*:* | R*000:UNIX_SV:*:*)
+ if [ -d /usr/nec ]; then
+ echo mips-nec-sysv${UNAME_RELEASE}
+ else
+ echo mips-unknown-sysv${UNAME_RELEASE}
+ fi
+ exit ;;
+ BeBox:BeOS:*:*) # BeOS running on hardware made by Be, PPC only.
+ echo powerpc-be-beos
+ exit ;;
+ BeMac:BeOS:*:*) # BeOS running on Mac or Mac clone, PPC only.
+ echo powerpc-apple-beos
+ exit ;;
+ BePC:BeOS:*:*) # BeOS running on Intel PC compatible.
+ echo i586-pc-beos
+ exit ;;
+ BePC:Haiku:*:*) # Haiku running on Intel PC compatible.
+ echo i586-pc-haiku
+ exit ;;
+ SX-4:SUPER-UX:*:*)
+ echo sx4-nec-superux${UNAME_RELEASE}
+ exit ;;
+ SX-5:SUPER-UX:*:*)
+ echo sx5-nec-superux${UNAME_RELEASE}
+ exit ;;
+ SX-6:SUPER-UX:*:*)
+ echo sx6-nec-superux${UNAME_RELEASE}
+ exit ;;
+ SX-7:SUPER-UX:*:*)
+ echo sx7-nec-superux${UNAME_RELEASE}
+ exit ;;
+ SX-8:SUPER-UX:*:*)
+ echo sx8-nec-superux${UNAME_RELEASE}
+ exit ;;
+ SX-8R:SUPER-UX:*:*)
+ echo sx8r-nec-superux${UNAME_RELEASE}
+ exit ;;
+ Power*:Rhapsody:*:*)
+ echo powerpc-apple-rhapsody${UNAME_RELEASE}
+ exit ;;
+ *:Rhapsody:*:*)
+ echo ${UNAME_MACHINE}-apple-rhapsody${UNAME_RELEASE}
+ exit ;;
+ *:Darwin:*:*)
+ UNAME_PROCESSOR=`uname -p` || UNAME_PROCESSOR=unknown
+ case $UNAME_PROCESSOR in
+ i386)
+ eval $set_cc_for_build
+ if [ "$CC_FOR_BUILD" != 'no_compiler_found' ]; then
+ if (echo '#ifdef __LP64__'; echo IS_64BIT_ARCH; echo '#endif') | \
+ (CCOPTS= $CC_FOR_BUILD -E - 2>/dev/null) | \
+ grep IS_64BIT_ARCH >/dev/null
+ then
+ UNAME_PROCESSOR="x86_64"
+ fi
+ fi ;;
+ unknown) UNAME_PROCESSOR=powerpc ;;
+ esac
+ echo ${UNAME_PROCESSOR}-apple-darwin${UNAME_RELEASE}
+ exit ;;
+ *:procnto*:*:* | *:QNX:[0123456789]*:*)
+ UNAME_PROCESSOR=`uname -p`
+ if test "$UNAME_PROCESSOR" = "x86"; then
+ UNAME_PROCESSOR=i386
+ UNAME_MACHINE=pc
+ fi
+ echo ${UNAME_PROCESSOR}-${UNAME_MACHINE}-nto-qnx${UNAME_RELEASE}
+ exit ;;
+ *:QNX:*:4*)
+ echo i386-pc-qnx
+ exit ;;
+ NSE-?:NONSTOP_KERNEL:*:*)
+ echo nse-tandem-nsk${UNAME_RELEASE}
+ exit ;;
+ NSR-?:NONSTOP_KERNEL:*:*)
+ echo nsr-tandem-nsk${UNAME_RELEASE}
+ exit ;;
+ *:NonStop-UX:*:*)
+ echo mips-compaq-nonstopux
+ exit ;;
+ BS2000:POSIX*:*:*)
+ echo bs2000-siemens-sysv
+ exit ;;
+ DS/*:UNIX_System_V:*:*)
+ echo ${UNAME_MACHINE}-${UNAME_SYSTEM}-${UNAME_RELEASE}
+ exit ;;
+ *:Plan9:*:*)
+ # "uname -m" is not consistent, so use $cputype instead. 386
+ # is converted to i386 for consistency with other x86
+ # operating systems.
+ if test "$cputype" = "386"; then
+ UNAME_MACHINE=i386
+ else
+ UNAME_MACHINE="$cputype"
+ fi
+ echo ${UNAME_MACHINE}-unknown-plan9
+ exit ;;
+ *:TOPS-10:*:*)
+ echo pdp10-unknown-tops10
+ exit ;;
+ *:TENEX:*:*)
+ echo pdp10-unknown-tenex
+ exit ;;
+ KS10:TOPS-20:*:* | KL10:TOPS-20:*:* | TYPE4:TOPS-20:*:*)
+ echo pdp10-dec-tops20
+ exit ;;
+ XKL-1:TOPS-20:*:* | TYPE5:TOPS-20:*:*)
+ echo pdp10-xkl-tops20
+ exit ;;
+ *:TOPS-20:*:*)
+ echo pdp10-unknown-tops20
+ exit ;;
+ *:ITS:*:*)
+ echo pdp10-unknown-its
+ exit ;;
+ SEI:*:*:SEIUX)
+ echo mips-sei-seiux${UNAME_RELEASE}
+ exit ;;
+ *:DragonFly:*:*)
+ echo ${UNAME_MACHINE}-unknown-dragonfly`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'`
+ exit ;;
+ *:*VMS:*:*)
+ UNAME_MACHINE=`(uname -p) 2>/dev/null`
+ case "${UNAME_MACHINE}" in
+ A*) echo alpha-dec-vms ; exit ;;
+ I*) echo ia64-dec-vms ; exit ;;
+ V*) echo vax-dec-vms ; exit ;;
+ esac ;;
+ *:XENIX:*:SysV)
+ echo i386-pc-xenix
+ exit ;;
+ i*86:skyos:*:*)
+ echo ${UNAME_MACHINE}-pc-skyos`echo ${UNAME_RELEASE}` | sed -e 's/ .*$//'
+ exit ;;
+ i*86:rdos:*:*)
+ echo ${UNAME_MACHINE}-pc-rdos
+ exit ;;
+ i*86:AROS:*:*)
+ echo ${UNAME_MACHINE}-pc-aros
+ exit ;;
+esac
+
+#echo '(No uname command or uname output not recognized.)' 1>&2
+#echo "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" 1>&2
+
+eval $set_cc_for_build
+cat >$dummy.c <<EOF
+#ifdef _SEQUENT_
+# include <sys/types.h>
+# include <sys/utsname.h>
+#endif
+main ()
+{
+#if defined (sony)
+#if defined (MIPSEB)
+ /* BFD wants "bsd" instead of "newsos". Perhaps BFD should be changed,
+ I don't know.... */
+ printf ("mips-sony-bsd\n"); exit (0);
+#else
+#include <sys/param.h>
+ printf ("m68k-sony-newsos%s\n",
+#ifdef NEWSOS4
+ "4"
+#else
+ ""
+#endif
+ ); exit (0);
+#endif
+#endif
+
+#if defined (__arm) && defined (__acorn) && defined (__unix)
+ printf ("arm-acorn-riscix\n"); exit (0);
+#endif
+
+#if defined (hp300) && !defined (hpux)
+ printf ("m68k-hp-bsd\n"); exit (0);
+#endif
+
+#if defined (NeXT)
+#if !defined (__ARCHITECTURE__)
+#define __ARCHITECTURE__ "m68k"
+#endif
+ int version;
+ version=`(hostinfo | sed -n 's/.*NeXT Mach \([0-9]*\).*/\1/p') 2>/dev/null`;
+ if (version < 4)
+ printf ("%s-next-nextstep%d\n", __ARCHITECTURE__, version);
+ else
+ printf ("%s-next-openstep%d\n", __ARCHITECTURE__, version);
+ exit (0);
+#endif
+
+#if defined (MULTIMAX) || defined (n16)
+#if defined (UMAXV)
+ printf ("ns32k-encore-sysv\n"); exit (0);
+#else
+#if defined (CMU)
+ printf ("ns32k-encore-mach\n"); exit (0);
+#else
+ printf ("ns32k-encore-bsd\n"); exit (0);
+#endif
+#endif
+#endif
+
+#if defined (__386BSD__)
+ printf ("i386-pc-bsd\n"); exit (0);
+#endif
+
+#if defined (sequent)
+#if defined (i386)
+ printf ("i386-sequent-dynix\n"); exit (0);
+#endif
+#if defined (ns32000)
+ printf ("ns32k-sequent-dynix\n"); exit (0);
+#endif
+#endif
+
+#if defined (_SEQUENT_)
+ struct utsname un;
+
+ uname(&un);
+
+ if (strncmp(un.version, "V2", 2) == 0) {
+ printf ("i386-sequent-ptx2\n"); exit (0);
+ }
+ if (strncmp(un.version, "V1", 2) == 0) { /* XXX is V1 correct? */
+ printf ("i386-sequent-ptx1\n"); exit (0);
+ }
+ printf ("i386-sequent-ptx\n"); exit (0);
+
+#endif
+
+#if defined (vax)
+# if !defined (ultrix)
+# include <sys/param.h>
+# if defined (BSD)
+# if BSD == 43
+ printf ("vax-dec-bsd4.3\n"); exit (0);
+# else
+# if BSD == 199006
+ printf ("vax-dec-bsd4.3reno\n"); exit (0);
+# else
+ printf ("vax-dec-bsd\n"); exit (0);
+# endif
+# endif
+# else
+ printf ("vax-dec-bsd\n"); exit (0);
+# endif
+# else
+ printf ("vax-dec-ultrix\n"); exit (0);
+# endif
+#endif
+
+#if defined (alliant) && defined (i860)
+ printf ("i860-alliant-bsd\n"); exit (0);
+#endif
+
+ exit (1);
+}
+EOF
+
+$CC_FOR_BUILD -o $dummy $dummy.c 2>/dev/null && SYSTEM_NAME=`$dummy` &&
+ { echo "$SYSTEM_NAME"; exit; }
+
+# Apollos put the system type in the environment.
+
+test -d /usr/apollo && { echo ${ISP}-apollo-${SYSTYPE}; exit; }
+
+# Convex versions that predate uname can use getsysinfo(1)
+
+if [ -x /usr/convex/getsysinfo ]
+then
+ case `getsysinfo -f cpu_type` in
+ c1*)
+ echo c1-convex-bsd
+ exit ;;
+ c2*)
+ if getsysinfo -f scalar_acc
+ then echo c32-convex-bsd
+ else echo c2-convex-bsd
+ fi
+ exit ;;
+ c34*)
+ echo c34-convex-bsd
+ exit ;;
+ c38*)
+ echo c38-convex-bsd
+ exit ;;
+ c4*)
+ echo c4-convex-bsd
+ exit ;;
+ esac
+fi
+
+cat >&2 <<EOF
+$0: unable to guess system type
+
+This script, last modified $timestamp, has failed to recognize
+the operating system you are using. It is advised that you
+download the most up to date version of the config scripts from
+
+ http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.guess;hb=HEAD
+and
+ http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.sub;hb=HEAD
+
+If the version you run ($0) is already up to date, please
+send the following data and any information you think might be
+pertinent to <config-patches@gnu.org> in order to provide the needed
+information to handle your system.
+
+config.guess timestamp = $timestamp
+
+uname -m = `(uname -m) 2>/dev/null || echo unknown`
+uname -r = `(uname -r) 2>/dev/null || echo unknown`
+uname -s = `(uname -s) 2>/dev/null || echo unknown`
+uname -v = `(uname -v) 2>/dev/null || echo unknown`
+
+/usr/bin/uname -p = `(/usr/bin/uname -p) 2>/dev/null`
+/bin/uname -X = `(/bin/uname -X) 2>/dev/null`
+
+hostinfo = `(hostinfo) 2>/dev/null`
+/bin/universe = `(/bin/universe) 2>/dev/null`
+/usr/bin/arch -k = `(/usr/bin/arch -k) 2>/dev/null`
+/bin/arch = `(/bin/arch) 2>/dev/null`
+/usr/bin/oslevel = `(/usr/bin/oslevel) 2>/dev/null`
+/usr/convex/getsysinfo = `(/usr/convex/getsysinfo) 2>/dev/null`
+
+UNAME_MACHINE = ${UNAME_MACHINE}
+UNAME_RELEASE = ${UNAME_RELEASE}
+UNAME_SYSTEM = ${UNAME_SYSTEM}
+UNAME_VERSION = ${UNAME_VERSION}
+EOF
+
+exit 1
+
+# Local variables:
+# eval: (add-hook 'write-file-hooks 'time-stamp)
+# time-stamp-start: "timestamp='"
+# time-stamp-format: "%:y-%02m-%02d"
+# time-stamp-end: "'"
+# End:
diff --git a/contrib/libyaml/config/config.sub b/contrib/libyaml/config/config.sub
new file mode 100755
index 0000000..c2d1257
--- /dev/null
+++ b/contrib/libyaml/config/config.sub
@@ -0,0 +1,1714 @@
+#! /bin/sh
+# Configuration validation subroutine script.
+# Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
+# 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010
+# Free Software Foundation, Inc.
+
+timestamp='2010-01-22'
+
+# This file is (in principle) common to ALL GNU software.
+# The presence of a machine in this file suggests that SOME GNU software
+# can handle that machine. It does not imply ALL GNU software can.
+#
+# This file 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., 51 Franklin Street - Fifth Floor, Boston, MA
+# 02110-1301, 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.
+
+
+# Please send patches to <config-patches@gnu.org>. Submit a context
+# diff and a properly formatted GNU ChangeLog entry.
+#
+# Configuration subroutine to validate and canonicalize a configuration type.
+# Supply the specified configuration type as an argument.
+# If it is invalid, we print an error message on stderr and exit with code 1.
+# Otherwise, we print the canonical config type on stdout and succeed.
+
+# You can get the latest version of this script from:
+# http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.sub;hb=HEAD
+
+# This file is supposed to be the same for all GNU packages
+# and recognize all the CPU types, system types and aliases
+# that are meaningful with *any* GNU software.
+# Each package is responsible for reporting which valid configurations
+# it does not support. The user should be able to distinguish
+# a failure to support a valid configuration from a meaningless
+# configuration.
+
+# The goal of this file is to map all the various variations of a given
+# machine specification into a single specification in the form:
+# CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM
+# or in some cases, the newer four-part form:
+# CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM
+# It is wrong to echo any other type of specification.
+
+me=`echo "$0" | sed -e 's,.*/,,'`
+
+usage="\
+Usage: $0 [OPTION] CPU-MFR-OPSYS
+ $0 [OPTION] ALIAS
+
+Canonicalize a configuration name.
+
+Operation modes:
+ -h, --help print this help, then exit
+ -t, --time-stamp print date of last modification, then exit
+ -v, --version print version number, then exit
+
+Report bugs and patches to <config-patches@gnu.org>."
+
+version="\
+GNU config.sub ($timestamp)
+
+Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000,
+2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010 Free
+Software Foundation, Inc.
+
+This is free software; see the source for copying conditions. There is NO
+warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE."
+
+help="
+Try \`$me --help' for more information."
+
+# Parse command line
+while test $# -gt 0 ; do
+ case $1 in
+ --time-stamp | --time* | -t )
+ echo "$timestamp" ; exit ;;
+ --version | -v )
+ echo "$version" ; exit ;;
+ --help | --h* | -h )
+ echo "$usage"; exit ;;
+ -- ) # Stop option processing
+ shift; break ;;
+ - ) # Use stdin as input.
+ break ;;
+ -* )
+ echo "$me: invalid option $1$help"
+ exit 1 ;;
+
+ *local*)
+ # First pass through any local machine types.
+ echo $1
+ exit ;;
+
+ * )
+ break ;;
+ esac
+done
+
+case $# in
+ 0) echo "$me: missing argument$help" >&2
+ exit 1;;
+ 1) ;;
+ *) echo "$me: too many arguments$help" >&2
+ exit 1;;
+esac
+
+# Separate what the user gave into CPU-COMPANY and OS or KERNEL-OS (if any).
+# Here we must recognize all the valid KERNEL-OS combinations.
+maybe_os=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\2/'`
+case $maybe_os in
+ nto-qnx* | linux-gnu* | linux-dietlibc | linux-newlib* | linux-uclibc* | \
+ uclinux-uclibc* | uclinux-gnu* | kfreebsd*-gnu* | knetbsd*-gnu* | netbsd*-gnu* | \
+ kopensolaris*-gnu* | \
+ storm-chaos* | os2-emx* | rtmk-nova*)
+ os=-$maybe_os
+ basic_machine=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\1/'`
+ ;;
+ *)
+ basic_machine=`echo $1 | sed 's/-[^-]*$//'`
+ if [ $basic_machine != $1 ]
+ then os=`echo $1 | sed 's/.*-/-/'`
+ else os=; fi
+ ;;
+esac
+
+### Let's recognize common machines as not being operating systems so
+### that things like config.sub decstation-3100 work. We also
+### recognize some manufacturers as not being operating systems, so we
+### can provide default operating systems below.
+case $os in
+ -sun*os*)
+ # Prevent following clause from handling this invalid input.
+ ;;
+ -dec* | -mips* | -sequent* | -encore* | -pc532* | -sgi* | -sony* | \
+ -att* | -7300* | -3300* | -delta* | -motorola* | -sun[234]* | \
+ -unicom* | -ibm* | -next | -hp | -isi* | -apollo | -altos* | \
+ -convergent* | -ncr* | -news | -32* | -3600* | -3100* | -hitachi* |\
+ -c[123]* | -convex* | -sun | -crds | -omron* | -dg | -ultra | -tti* | \
+ -harris | -dolphin | -highlevel | -gould | -cbm | -ns | -masscomp | \
+ -apple | -axis | -knuth | -cray | -microblaze)
+ os=
+ basic_machine=$1
+ ;;
+ -bluegene*)
+ os=-cnk
+ ;;
+ -sim | -cisco | -oki | -wec | -winbond)
+ os=
+ basic_machine=$1
+ ;;
+ -scout)
+ ;;
+ -wrs)
+ os=-vxworks
+ basic_machine=$1
+ ;;
+ -chorusos*)
+ os=-chorusos
+ basic_machine=$1
+ ;;
+ -chorusrdb)
+ os=-chorusrdb
+ basic_machine=$1
+ ;;
+ -hiux*)
+ os=-hiuxwe2
+ ;;
+ -sco6)
+ os=-sco5v6
+ basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+ ;;
+ -sco5)
+ os=-sco3.2v5
+ basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+ ;;
+ -sco4)
+ os=-sco3.2v4
+ basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+ ;;
+ -sco3.2.[4-9]*)
+ os=`echo $os | sed -e 's/sco3.2./sco3.2v/'`
+ basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+ ;;
+ -sco3.2v[4-9]*)
+ # Don't forget version if it is 3.2v4 or newer.
+ basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+ ;;
+ -sco5v6*)
+ # Don't forget version if it is 3.2v4 or newer.
+ basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+ ;;
+ -sco*)
+ os=-sco3.2v2
+ basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+ ;;
+ -udk*)
+ basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+ ;;
+ -isc)
+ os=-isc2.2
+ basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+ ;;
+ -clix*)
+ basic_machine=clipper-intergraph
+ ;;
+ -isc*)
+ basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+ ;;
+ -lynx*)
+ os=-lynxos
+ ;;
+ -ptx*)
+ basic_machine=`echo $1 | sed -e 's/86-.*/86-sequent/'`
+ ;;
+ -windowsnt*)
+ os=`echo $os | sed -e 's/windowsnt/winnt/'`
+ ;;
+ -psos*)
+ os=-psos
+ ;;
+ -mint | -mint[0-9]*)
+ basic_machine=m68k-atari
+ os=-mint
+ ;;
+esac
+
+# Decode aliases for certain CPU-COMPANY combinations.
+case $basic_machine in
+ # Recognize the basic CPU types without company name.
+ # Some are omitted here because they have special meanings below.
+ 1750a | 580 \
+ | a29k \
+ | alpha | alphaev[4-8] | alphaev56 | alphaev6[78] | alphapca5[67] \
+ | alpha64 | alpha64ev[4-8] | alpha64ev56 | alpha64ev6[78] | alpha64pca5[67] \
+ | am33_2.0 \
+ | arc | arm | arm[bl]e | arme[lb] | armv[2345] | armv[345][lb] | avr | avr32 \
+ | bfin \
+ | c4x | clipper \
+ | d10v | d30v | dlx | dsp16xx \
+ | fido | fr30 | frv \
+ | h8300 | h8500 | hppa | hppa1.[01] | hppa2.0 | hppa2.0[nw] | hppa64 \
+ | i370 | i860 | i960 | ia64 \
+ | ip2k | iq2000 \
+ | lm32 \
+ | m32c | m32r | m32rle | m68000 | m68k | m88k \
+ | maxq | mb | microblaze | mcore | mep | metag \
+ | mips | mipsbe | mipseb | mipsel | mipsle \
+ | mips16 \
+ | mips64 | mips64el \
+ | mips64octeon | mips64octeonel \
+ | mips64orion | mips64orionel \
+ | mips64r5900 | mips64r5900el \
+ | mips64vr | mips64vrel \
+ | mips64vr4100 | mips64vr4100el \
+ | mips64vr4300 | mips64vr4300el \
+ | mips64vr5000 | mips64vr5000el \
+ | mips64vr5900 | mips64vr5900el \
+ | mipsisa32 | mipsisa32el \
+ | mipsisa32r2 | mipsisa32r2el \
+ | mipsisa64 | mipsisa64el \
+ | mipsisa64r2 | mipsisa64r2el \
+ | mipsisa64sb1 | mipsisa64sb1el \
+ | mipsisa64sr71k | mipsisa64sr71kel \
+ | mipstx39 | mipstx39el \
+ | mn10200 | mn10300 \
+ | moxie \
+ | mt \
+ | msp430 \
+ | nios | nios2 \
+ | ns16k | ns32k \
+ | or32 \
+ | pdp10 | pdp11 | pj | pjl \
+ | powerpc | powerpc64 | powerpc64le | powerpcle | ppcbe \
+ | pyramid \
+ | rx \
+ | score \
+ | sh | sh[1234] | sh[24]a | sh[24]aeb | sh[23]e | sh[34]eb | sheb | shbe | shle | sh[1234]le | sh3ele \
+ | sh64 | sh64le \
+ | sparc | sparc64 | sparc64b | sparc64v | sparc86x | sparclet | sparclite \
+ | sparcv8 | sparcv9 | sparcv9b | sparcv9v \
+ | spu | strongarm \
+ | tahoe | thumb | tic4x | tic80 | tron \
+ | ubicom32 \
+ | v850 | v850e \
+ | we32k \
+ | x86 | xc16x | xscale | xscalee[bl] | xstormy16 | xtensa \
+ | z8k | z80)
+ basic_machine=$basic_machine-unknown
+ ;;
+ m6811 | m68hc11 | m6812 | m68hc12 | picochip)
+ # Motorola 68HC11/12.
+ basic_machine=$basic_machine-unknown
+ os=-none
+ ;;
+ m88110 | m680[12346]0 | m683?2 | m68360 | m5200 | v70 | w65 | z8k)
+ ;;
+ ms1)
+ basic_machine=mt-unknown
+ ;;
+
+ # We use `pc' rather than `unknown'
+ # because (1) that's what they normally are, and
+ # (2) the word "unknown" tends to confuse beginning users.
+ i*86 | x86_64)
+ basic_machine=$basic_machine-pc
+ ;;
+ # Object if more than one company name word.
+ *-*-*)
+ echo Invalid configuration \`$1\': machine \`$basic_machine\' not recognized 1>&2
+ exit 1
+ ;;
+ # Recognize the basic CPU types with company name.
+ 580-* \
+ | a29k-* \
+ | alpha-* | alphaev[4-8]-* | alphaev56-* | alphaev6[78]-* \
+ | alpha64-* | alpha64ev[4-8]-* | alpha64ev56-* | alpha64ev6[78]-* \
+ | alphapca5[67]-* | alpha64pca5[67]-* | arc-* \
+ | arm-* | armbe-* | armle-* | armeb-* | armv*-* \
+ | avr-* | avr32-* \
+ | bfin-* | bs2000-* \
+ | c[123]* | c30-* | [cjt]90-* | c4x-* | c54x-* | c55x-* | c6x-* \
+ | clipper-* | craynv-* | cydra-* \
+ | d10v-* | d30v-* | dlx-* \
+ | elxsi-* \
+ | f30[01]-* | f700-* | fido-* | fr30-* | frv-* | fx80-* \
+ | h8300-* | h8500-* \
+ | hppa-* | hppa1.[01]-* | hppa2.0-* | hppa2.0[nw]-* | hppa64-* \
+ | i*86-* | i860-* | i960-* | ia64-* \
+ | ip2k-* | iq2000-* \
+ | lm32-* \
+ | m32c-* | m32r-* | m32rle-* \
+ | m68000-* | m680[012346]0-* | m68360-* | m683?2-* | m68k-* \
+ | m88110-* | m88k-* | maxq-* | mcore-* | metag-* | microblaze-* \
+ | mips-* | mipsbe-* | mipseb-* | mipsel-* | mipsle-* \
+ | mips16-* \
+ | mips64-* | mips64el-* \
+ | mips64octeon-* | mips64octeonel-* \
+ | mips64orion-* | mips64orionel-* \
+ | mips64r5900-* | mips64r5900el-* \
+ | mips64vr-* | mips64vrel-* \
+ | mips64vr4100-* | mips64vr4100el-* \
+ | mips64vr4300-* | mips64vr4300el-* \
+ | mips64vr5000-* | mips64vr5000el-* \
+ | mips64vr5900-* | mips64vr5900el-* \
+ | mipsisa32-* | mipsisa32el-* \
+ | mipsisa32r2-* | mipsisa32r2el-* \
+ | mipsisa64-* | mipsisa64el-* \
+ | mipsisa64r2-* | mipsisa64r2el-* \
+ | mipsisa64sb1-* | mipsisa64sb1el-* \
+ | mipsisa64sr71k-* | mipsisa64sr71kel-* \
+ | mipstx39-* | mipstx39el-* \
+ | mmix-* \
+ | mt-* \
+ | msp430-* \
+ | nios-* | nios2-* \
+ | none-* | np1-* | ns16k-* | ns32k-* \
+ | orion-* \
+ | pdp10-* | pdp11-* | pj-* | pjl-* | pn-* | power-* \
+ | powerpc-* | powerpc64-* | powerpc64le-* | powerpcle-* | ppcbe-* \
+ | pyramid-* \
+ | romp-* | rs6000-* | rx-* \
+ | sh-* | sh[1234]-* | sh[24]a-* | sh[24]aeb-* | sh[23]e-* | sh[34]eb-* | sheb-* | shbe-* \
+ | shle-* | sh[1234]le-* | sh3ele-* | sh64-* | sh64le-* \
+ | sparc-* | sparc64-* | sparc64b-* | sparc64v-* | sparc86x-* | sparclet-* \
+ | sparclite-* \
+ | sparcv8-* | sparcv9-* | sparcv9b-* | sparcv9v-* | strongarm-* | sv1-* | sx?-* \
+ | tahoe-* | thumb-* \
+ | tic30-* | tic4x-* | tic54x-* | tic55x-* | tic6x-* | tic80-* \
+ | tile-* | tilegx-* \
+ | tron-* \
+ | ubicom32-* \
+ | v850-* | v850e-* | vax-* \
+ | we32k-* \
+ | x86-* | x86_64-* | xc16x-* | xps100-* | xscale-* | xscalee[bl]-* \
+ | xstormy16-* | xtensa*-* \
+ | ymp-* \
+ | z8k-* | z80-*)
+ ;;
+ # Recognize the basic CPU types without company name, with glob match.
+ xtensa*)
+ basic_machine=$basic_machine-unknown
+ ;;
+ # Recognize the various machine names and aliases which stand
+ # for a CPU type and a company and sometimes even an OS.
+ 386bsd)
+ basic_machine=i386-unknown
+ os=-bsd
+ ;;
+ 3b1 | 7300 | 7300-att | att-7300 | pc7300 | safari | unixpc)
+ basic_machine=m68000-att
+ ;;
+ 3b*)
+ basic_machine=we32k-att
+ ;;
+ a29khif)
+ basic_machine=a29k-amd
+ os=-udi
+ ;;
+ abacus)
+ basic_machine=abacus-unknown
+ ;;
+ adobe68k)
+ basic_machine=m68010-adobe
+ os=-scout
+ ;;
+ alliant | fx80)
+ basic_machine=fx80-alliant
+ ;;
+ altos | altos3068)
+ basic_machine=m68k-altos
+ ;;
+ am29k)
+ basic_machine=a29k-none
+ os=-bsd
+ ;;
+ amd64)
+ basic_machine=x86_64-pc
+ ;;
+ amd64-*)
+ basic_machine=x86_64-`echo $basic_machine | sed 's/^[^-]*-//'`
+ ;;
+ amdahl)
+ basic_machine=580-amdahl
+ os=-sysv
+ ;;
+ amiga | amiga-*)
+ basic_machine=m68k-unknown
+ ;;
+ amigaos | amigados)
+ basic_machine=m68k-unknown
+ os=-amigaos
+ ;;
+ amigaunix | amix)
+ basic_machine=m68k-unknown
+ os=-sysv4
+ ;;
+ apollo68)
+ basic_machine=m68k-apollo
+ os=-sysv
+ ;;
+ apollo68bsd)
+ basic_machine=m68k-apollo
+ os=-bsd
+ ;;
+ aros)
+ basic_machine=i386-pc
+ os=-aros
+ ;;
+ aux)
+ basic_machine=m68k-apple
+ os=-aux
+ ;;
+ balance)
+ basic_machine=ns32k-sequent
+ os=-dynix
+ ;;
+ blackfin)
+ basic_machine=bfin-unknown
+ os=-linux
+ ;;
+ blackfin-*)
+ basic_machine=bfin-`echo $basic_machine | sed 's/^[^-]*-//'`
+ os=-linux
+ ;;
+ bluegene*)
+ basic_machine=powerpc-ibm
+ os=-cnk
+ ;;
+ c90)
+ basic_machine=c90-cray
+ os=-unicos
+ ;;
+ cegcc)
+ basic_machine=arm-unknown
+ os=-cegcc
+ ;;
+ convex-c1)
+ basic_machine=c1-convex
+ os=-bsd
+ ;;
+ convex-c2)
+ basic_machine=c2-convex
+ os=-bsd
+ ;;
+ convex-c32)
+ basic_machine=c32-convex
+ os=-bsd
+ ;;
+ convex-c34)
+ basic_machine=c34-convex
+ os=-bsd
+ ;;
+ convex-c38)
+ basic_machine=c38-convex
+ os=-bsd
+ ;;
+ cray | j90)
+ basic_machine=j90-cray
+ os=-unicos
+ ;;
+ craynv)
+ basic_machine=craynv-cray
+ os=-unicosmp
+ ;;
+ cr16)
+ basic_machine=cr16-unknown
+ os=-elf
+ ;;
+ crds | unos)
+ basic_machine=m68k-crds
+ ;;
+ crisv32 | crisv32-* | etraxfs*)
+ basic_machine=crisv32-axis
+ ;;
+ cris | cris-* | etrax*)
+ basic_machine=cris-axis
+ ;;
+ crx)
+ basic_machine=crx-unknown
+ os=-elf
+ ;;
+ da30 | da30-*)
+ basic_machine=m68k-da30
+ ;;
+ decstation | decstation-3100 | pmax | pmax-* | pmin | dec3100 | decstatn)
+ basic_machine=mips-dec
+ ;;
+ decsystem10* | dec10*)
+ basic_machine=pdp10-dec
+ os=-tops10
+ ;;
+ decsystem20* | dec20*)
+ basic_machine=pdp10-dec
+ os=-tops20
+ ;;
+ delta | 3300 | motorola-3300 | motorola-delta \
+ | 3300-motorola | delta-motorola)
+ basic_machine=m68k-motorola
+ ;;
+ delta88)
+ basic_machine=m88k-motorola
+ os=-sysv3
+ ;;
+ dicos)
+ basic_machine=i686-pc
+ os=-dicos
+ ;;
+ djgpp)
+ basic_machine=i586-pc
+ os=-msdosdjgpp
+ ;;
+ dpx20 | dpx20-*)
+ basic_machine=rs6000-bull
+ os=-bosx
+ ;;
+ dpx2* | dpx2*-bull)
+ basic_machine=m68k-bull
+ os=-sysv3
+ ;;
+ ebmon29k)
+ basic_machine=a29k-amd
+ os=-ebmon
+ ;;
+ elxsi)
+ basic_machine=elxsi-elxsi
+ os=-bsd
+ ;;
+ encore | umax | mmax)
+ basic_machine=ns32k-encore
+ ;;
+ es1800 | OSE68k | ose68k | ose | OSE)
+ basic_machine=m68k-ericsson
+ os=-ose
+ ;;
+ fx2800)
+ basic_machine=i860-alliant
+ ;;
+ genix)
+ basic_machine=ns32k-ns
+ ;;
+ gmicro)
+ basic_machine=tron-gmicro
+ os=-sysv
+ ;;
+ go32)
+ basic_machine=i386-pc
+ os=-go32
+ ;;
+ h3050r* | hiux*)
+ basic_machine=hppa1.1-hitachi
+ os=-hiuxwe2
+ ;;
+ h8300hms)
+ basic_machine=h8300-hitachi
+ os=-hms
+ ;;
+ h8300xray)
+ basic_machine=h8300-hitachi
+ os=-xray
+ ;;
+ h8500hms)
+ basic_machine=h8500-hitachi
+ os=-hms
+ ;;
+ harris)
+ basic_machine=m88k-harris
+ os=-sysv3
+ ;;
+ hp300-*)
+ basic_machine=m68k-hp
+ ;;
+ hp300bsd)
+ basic_machine=m68k-hp
+ os=-bsd
+ ;;
+ hp300hpux)
+ basic_machine=m68k-hp
+ os=-hpux
+ ;;
+ hp3k9[0-9][0-9] | hp9[0-9][0-9])
+ basic_machine=hppa1.0-hp
+ ;;
+ hp9k2[0-9][0-9] | hp9k31[0-9])
+ basic_machine=m68000-hp
+ ;;
+ hp9k3[2-9][0-9])
+ basic_machine=m68k-hp
+ ;;
+ hp9k6[0-9][0-9] | hp6[0-9][0-9])
+ basic_machine=hppa1.0-hp
+ ;;
+ hp9k7[0-79][0-9] | hp7[0-79][0-9])
+ basic_machine=hppa1.1-hp
+ ;;
+ hp9k78[0-9] | hp78[0-9])
+ # FIXME: really hppa2.0-hp
+ basic_machine=hppa1.1-hp
+ ;;
+ hp9k8[67]1 | hp8[67]1 | hp9k80[24] | hp80[24] | hp9k8[78]9 | hp8[78]9 | hp9k893 | hp893)
+ # FIXME: really hppa2.0-hp
+ basic_machine=hppa1.1-hp
+ ;;
+ hp9k8[0-9][13679] | hp8[0-9][13679])
+ basic_machine=hppa1.1-hp
+ ;;
+ hp9k8[0-9][0-9] | hp8[0-9][0-9])
+ basic_machine=hppa1.0-hp
+ ;;
+ hppa-next)
+ os=-nextstep3
+ ;;
+ hppaosf)
+ basic_machine=hppa1.1-hp
+ os=-osf
+ ;;
+ hppro)
+ basic_machine=hppa1.1-hp
+ os=-proelf
+ ;;
+ i370-ibm* | ibm*)
+ basic_machine=i370-ibm
+ ;;
+# I'm not sure what "Sysv32" means. Should this be sysv3.2?
+ i*86v32)
+ basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'`
+ os=-sysv32
+ ;;
+ i*86v4*)
+ basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'`
+ os=-sysv4
+ ;;
+ i*86v)
+ basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'`
+ os=-sysv
+ ;;
+ i*86sol2)
+ basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'`
+ os=-solaris2
+ ;;
+ i386mach)
+ basic_machine=i386-mach
+ os=-mach
+ ;;
+ i386-vsta | vsta)
+ basic_machine=i386-unknown
+ os=-vsta
+ ;;
+ iris | iris4d)
+ basic_machine=mips-sgi
+ case $os in
+ -irix*)
+ ;;
+ *)
+ os=-irix4
+ ;;
+ esac
+ ;;
+ isi68 | isi)
+ basic_machine=m68k-isi
+ os=-sysv
+ ;;
+ m68knommu)
+ basic_machine=m68k-unknown
+ os=-linux
+ ;;
+ m68knommu-*)
+ basic_machine=m68k-`echo $basic_machine | sed 's/^[^-]*-//'`
+ os=-linux
+ ;;
+ m88k-omron*)
+ basic_machine=m88k-omron
+ ;;
+ magnum | m3230)
+ basic_machine=mips-mips
+ os=-sysv
+ ;;
+ merlin)
+ basic_machine=ns32k-utek
+ os=-sysv
+ ;;
+ microblaze)
+ basic_machine=microblaze-xilinx
+ ;;
+ mingw32)
+ basic_machine=i386-pc
+ os=-mingw32
+ ;;
+ mingw32ce)
+ basic_machine=arm-unknown
+ os=-mingw32ce
+ ;;
+ miniframe)
+ basic_machine=m68000-convergent
+ ;;
+ *mint | -mint[0-9]* | *MiNT | *MiNT[0-9]*)
+ basic_machine=m68k-atari
+ os=-mint
+ ;;
+ mips3*-*)
+ basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'`
+ ;;
+ mips3*)
+ basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'`-unknown
+ ;;
+ monitor)
+ basic_machine=m68k-rom68k
+ os=-coff
+ ;;
+ morphos)
+ basic_machine=powerpc-unknown
+ os=-morphos
+ ;;
+ msdos)
+ basic_machine=i386-pc
+ os=-msdos
+ ;;
+ ms1-*)
+ basic_machine=`echo $basic_machine | sed -e 's/ms1-/mt-/'`
+ ;;
+ mvs)
+ basic_machine=i370-ibm
+ os=-mvs
+ ;;
+ ncr3000)
+ basic_machine=i486-ncr
+ os=-sysv4
+ ;;
+ netbsd386)
+ basic_machine=i386-unknown
+ os=-netbsd
+ ;;
+ netwinder)
+ basic_machine=armv4l-rebel
+ os=-linux
+ ;;
+ news | news700 | news800 | news900)
+ basic_machine=m68k-sony
+ os=-newsos
+ ;;
+ news1000)
+ basic_machine=m68030-sony
+ os=-newsos
+ ;;
+ news-3600 | risc-news)
+ basic_machine=mips-sony
+ os=-newsos
+ ;;
+ necv70)
+ basic_machine=v70-nec
+ os=-sysv
+ ;;
+ next | m*-next )
+ basic_machine=m68k-next
+ case $os in
+ -nextstep* )
+ ;;
+ -ns2*)
+ os=-nextstep2
+ ;;
+ *)
+ os=-nextstep3
+ ;;
+ esac
+ ;;
+ nh3000)
+ basic_machine=m68k-harris
+ os=-cxux
+ ;;
+ nh[45]000)
+ basic_machine=m88k-harris
+ os=-cxux
+ ;;
+ nindy960)
+ basic_machine=i960-intel
+ os=-nindy
+ ;;
+ mon960)
+ basic_machine=i960-intel
+ os=-mon960
+ ;;
+ nonstopux)
+ basic_machine=mips-compaq
+ os=-nonstopux
+ ;;
+ np1)
+ basic_machine=np1-gould
+ ;;
+ nsr-tandem)
+ basic_machine=nsr-tandem
+ ;;
+ op50n-* | op60c-*)
+ basic_machine=hppa1.1-oki
+ os=-proelf
+ ;;
+ openrisc | openrisc-*)
+ basic_machine=or32-unknown
+ ;;
+ os400)
+ basic_machine=powerpc-ibm
+ os=-os400
+ ;;
+ OSE68000 | ose68000)
+ basic_machine=m68000-ericsson
+ os=-ose
+ ;;
+ os68k)
+ basic_machine=m68k-none
+ os=-os68k
+ ;;
+ pa-hitachi)
+ basic_machine=hppa1.1-hitachi
+ os=-hiuxwe2
+ ;;
+ paragon)
+ basic_machine=i860-intel
+ os=-osf
+ ;;
+ parisc)
+ basic_machine=hppa-unknown
+ os=-linux
+ ;;
+ parisc-*)
+ basic_machine=hppa-`echo $basic_machine | sed 's/^[^-]*-//'`
+ os=-linux
+ ;;
+ pbd)
+ basic_machine=sparc-tti
+ ;;
+ pbb)
+ basic_machine=m68k-tti
+ ;;
+ pc532 | pc532-*)
+ basic_machine=ns32k-pc532
+ ;;
+ pc98)
+ basic_machine=i386-pc
+ ;;
+ pc98-*)
+ basic_machine=i386-`echo $basic_machine | sed 's/^[^-]*-//'`
+ ;;
+ pentium | p5 | k5 | k6 | nexgen | viac3)
+ basic_machine=i586-pc
+ ;;
+ pentiumpro | p6 | 6x86 | athlon | athlon_*)
+ basic_machine=i686-pc
+ ;;
+ pentiumii | pentium2 | pentiumiii | pentium3)
+ basic_machine=i686-pc
+ ;;
+ pentium4)
+ basic_machine=i786-pc
+ ;;
+ pentium-* | p5-* | k5-* | k6-* | nexgen-* | viac3-*)
+ basic_machine=i586-`echo $basic_machine | sed 's/^[^-]*-//'`
+ ;;
+ pentiumpro-* | p6-* | 6x86-* | athlon-*)
+ basic_machine=i686-`echo $basic_machine | sed 's/^[^-]*-//'`
+ ;;
+ pentiumii-* | pentium2-* | pentiumiii-* | pentium3-*)
+ basic_machine=i686-`echo $basic_machine | sed 's/^[^-]*-//'`
+ ;;
+ pentium4-*)
+ basic_machine=i786-`echo $basic_machine | sed 's/^[^-]*-//'`
+ ;;
+ pn)
+ basic_machine=pn-gould
+ ;;
+ power) basic_machine=power-ibm
+ ;;
+ ppc) basic_machine=powerpc-unknown
+ ;;
+ ppc-*) basic_machine=powerpc-`echo $basic_machine | sed 's/^[^-]*-//'`
+ ;;
+ ppcle | powerpclittle | ppc-le | powerpc-little)
+ basic_machine=powerpcle-unknown
+ ;;
+ ppcle-* | powerpclittle-*)
+ basic_machine=powerpcle-`echo $basic_machine | sed 's/^[^-]*-//'`
+ ;;
+ ppc64) basic_machine=powerpc64-unknown
+ ;;
+ ppc64-*) basic_machine=powerpc64-`echo $basic_machine | sed 's/^[^-]*-//'`
+ ;;
+ ppc64le | powerpc64little | ppc64-le | powerpc64-little)
+ basic_machine=powerpc64le-unknown
+ ;;
+ ppc64le-* | powerpc64little-*)
+ basic_machine=powerpc64le-`echo $basic_machine | sed 's/^[^-]*-//'`
+ ;;
+ ps2)
+ basic_machine=i386-ibm
+ ;;
+ pw32)
+ basic_machine=i586-unknown
+ os=-pw32
+ ;;
+ rdos)
+ basic_machine=i386-pc
+ os=-rdos
+ ;;
+ rom68k)
+ basic_machine=m68k-rom68k
+ os=-coff
+ ;;
+ rm[46]00)
+ basic_machine=mips-siemens
+ ;;
+ rtpc | rtpc-*)
+ basic_machine=romp-ibm
+ ;;
+ s390 | s390-*)
+ basic_machine=s390-ibm
+ ;;
+ s390x | s390x-*)
+ basic_machine=s390x-ibm
+ ;;
+ sa29200)
+ basic_machine=a29k-amd
+ os=-udi
+ ;;
+ sb1)
+ basic_machine=mipsisa64sb1-unknown
+ ;;
+ sb1el)
+ basic_machine=mipsisa64sb1el-unknown
+ ;;
+ sde)
+ basic_machine=mipsisa32-sde
+ os=-elf
+ ;;
+ sei)
+ basic_machine=mips-sei
+ os=-seiux
+ ;;
+ sequent)
+ basic_machine=i386-sequent
+ ;;
+ sh)
+ basic_machine=sh-hitachi
+ os=-hms
+ ;;
+ sh5el)
+ basic_machine=sh5le-unknown
+ ;;
+ sh64)
+ basic_machine=sh64-unknown
+ ;;
+ sparclite-wrs | simso-wrs)
+ basic_machine=sparclite-wrs
+ os=-vxworks
+ ;;
+ sps7)
+ basic_machine=m68k-bull
+ os=-sysv2
+ ;;
+ spur)
+ basic_machine=spur-unknown
+ ;;
+ st2000)
+ basic_machine=m68k-tandem
+ ;;
+ stratus)
+ basic_machine=i860-stratus
+ os=-sysv4
+ ;;
+ sun2)
+ basic_machine=m68000-sun
+ ;;
+ sun2os3)
+ basic_machine=m68000-sun
+ os=-sunos3
+ ;;
+ sun2os4)
+ basic_machine=m68000-sun
+ os=-sunos4
+ ;;
+ sun3os3)
+ basic_machine=m68k-sun
+ os=-sunos3
+ ;;
+ sun3os4)
+ basic_machine=m68k-sun
+ os=-sunos4
+ ;;
+ sun4os3)
+ basic_machine=sparc-sun
+ os=-sunos3
+ ;;
+ sun4os4)
+ basic_machine=sparc-sun
+ os=-sunos4
+ ;;
+ sun4sol2)
+ basic_machine=sparc-sun
+ os=-solaris2
+ ;;
+ sun3 | sun3-*)
+ basic_machine=m68k-sun
+ ;;
+ sun4)
+ basic_machine=sparc-sun
+ ;;
+ sun386 | sun386i | roadrunner)
+ basic_machine=i386-sun
+ ;;
+ sv1)
+ basic_machine=sv1-cray
+ os=-unicos
+ ;;
+ symmetry)
+ basic_machine=i386-sequent
+ os=-dynix
+ ;;
+ t3e)
+ basic_machine=alphaev5-cray
+ os=-unicos
+ ;;
+ t90)
+ basic_machine=t90-cray
+ os=-unicos
+ ;;
+ tic54x | c54x*)
+ basic_machine=tic54x-unknown
+ os=-coff
+ ;;
+ tic55x | c55x*)
+ basic_machine=tic55x-unknown
+ os=-coff
+ ;;
+ tic6x | c6x*)
+ basic_machine=tic6x-unknown
+ os=-coff
+ ;;
+ # This must be matched before tile*.
+ tilegx*)
+ basic_machine=tilegx-unknown
+ os=-linux-gnu
+ ;;
+ tile*)
+ basic_machine=tile-unknown
+ os=-linux-gnu
+ ;;
+ tx39)
+ basic_machine=mipstx39-unknown
+ ;;
+ tx39el)
+ basic_machine=mipstx39el-unknown
+ ;;
+ toad1)
+ basic_machine=pdp10-xkl
+ os=-tops20
+ ;;
+ tower | tower-32)
+ basic_machine=m68k-ncr
+ ;;
+ tpf)
+ basic_machine=s390x-ibm
+ os=-tpf
+ ;;
+ udi29k)
+ basic_machine=a29k-amd
+ os=-udi
+ ;;
+ ultra3)
+ basic_machine=a29k-nyu
+ os=-sym1
+ ;;
+ v810 | necv810)
+ basic_machine=v810-nec
+ os=-none
+ ;;
+ vaxv)
+ basic_machine=vax-dec
+ os=-sysv
+ ;;
+ vms)
+ basic_machine=vax-dec
+ os=-vms
+ ;;
+ vpp*|vx|vx-*)
+ basic_machine=f301-fujitsu
+ ;;
+ vxworks960)
+ basic_machine=i960-wrs
+ os=-vxworks
+ ;;
+ vxworks68)
+ basic_machine=m68k-wrs
+ os=-vxworks
+ ;;
+ vxworks29k)
+ basic_machine=a29k-wrs
+ os=-vxworks
+ ;;
+ w65*)
+ basic_machine=w65-wdc
+ os=-none
+ ;;
+ w89k-*)
+ basic_machine=hppa1.1-winbond
+ os=-proelf
+ ;;
+ xbox)
+ basic_machine=i686-pc
+ os=-mingw32
+ ;;
+ xps | xps100)
+ basic_machine=xps100-honeywell
+ ;;
+ ymp)
+ basic_machine=ymp-cray
+ os=-unicos
+ ;;
+ z8k-*-coff)
+ basic_machine=z8k-unknown
+ os=-sim
+ ;;
+ z80-*-coff)
+ basic_machine=z80-unknown
+ os=-sim
+ ;;
+ none)
+ basic_machine=none-none
+ os=-none
+ ;;
+
+# Here we handle the default manufacturer of certain CPU types. It is in
+# some cases the only manufacturer, in others, it is the most popular.
+ w89k)
+ basic_machine=hppa1.1-winbond
+ ;;
+ op50n)
+ basic_machine=hppa1.1-oki
+ ;;
+ op60c)
+ basic_machine=hppa1.1-oki
+ ;;
+ romp)
+ basic_machine=romp-ibm
+ ;;
+ mmix)
+ basic_machine=mmix-knuth
+ ;;
+ rs6000)
+ basic_machine=rs6000-ibm
+ ;;
+ vax)
+ basic_machine=vax-dec
+ ;;
+ pdp10)
+ # there are many clones, so DEC is not a safe bet
+ basic_machine=pdp10-unknown
+ ;;
+ pdp11)
+ basic_machine=pdp11-dec
+ ;;
+ we32k)
+ basic_machine=we32k-att
+ ;;
+ sh[1234] | sh[24]a | sh[24]aeb | sh[34]eb | sh[1234]le | sh[23]ele)
+ basic_machine=sh-unknown
+ ;;
+ sparc | sparcv8 | sparcv9 | sparcv9b | sparcv9v)
+ basic_machine=sparc-sun
+ ;;
+ cydra)
+ basic_machine=cydra-cydrome
+ ;;
+ orion)
+ basic_machine=orion-highlevel
+ ;;
+ orion105)
+ basic_machine=clipper-highlevel
+ ;;
+ mac | mpw | mac-mpw)
+ basic_machine=m68k-apple
+ ;;
+ pmac | pmac-mpw)
+ basic_machine=powerpc-apple
+ ;;
+ *-unknown)
+ # Make sure to match an already-canonicalized machine name.
+ ;;
+ *)
+ echo Invalid configuration \`$1\': machine \`$basic_machine\' not recognized 1>&2
+ exit 1
+ ;;
+esac
+
+# Here we canonicalize certain aliases for manufacturers.
+case $basic_machine in
+ *-digital*)
+ basic_machine=`echo $basic_machine | sed 's/digital.*/dec/'`
+ ;;
+ *-commodore*)
+ basic_machine=`echo $basic_machine | sed 's/commodore.*/cbm/'`
+ ;;
+ *)
+ ;;
+esac
+
+# Decode manufacturer-specific aliases for certain operating systems.
+
+if [ x"$os" != x"" ]
+then
+case $os in
+ # First match some system type aliases
+ # that might get confused with valid system types.
+ # -solaris* is a basic system type, with this one exception.
+ -auroraux)
+ os=-auroraux
+ ;;
+ -solaris1 | -solaris1.*)
+ os=`echo $os | sed -e 's|solaris1|sunos4|'`
+ ;;
+ -solaris)
+ os=-solaris2
+ ;;
+ -svr4*)
+ os=-sysv4
+ ;;
+ -unixware*)
+ os=-sysv4.2uw
+ ;;
+ -gnu/linux*)
+ os=`echo $os | sed -e 's|gnu/linux|linux-gnu|'`
+ ;;
+ # First accept the basic system types.
+ # The portable systems comes first.
+ # Each alternative MUST END IN A *, to match a version number.
+ # -sysv* is not here because it comes later, after sysvr4.
+ -gnu* | -bsd* | -mach* | -minix* | -genix* | -ultrix* | -irix* \
+ | -*vms* | -sco* | -esix* | -isc* | -aix* | -cnk* | -sunos | -sunos[34]*\
+ | -hpux* | -unos* | -osf* | -luna* | -dgux* | -auroraux* | -solaris* \
+ | -sym* | -kopensolaris* \
+ | -amigaos* | -amigados* | -msdos* | -newsos* | -unicos* | -aof* \
+ | -aos* | -aros* \
+ | -nindy* | -vxsim* | -vxworks* | -ebmon* | -hms* | -mvs* \
+ | -clix* | -riscos* | -uniplus* | -iris* | -rtu* | -xenix* \
+ | -hiux* | -386bsd* | -knetbsd* | -mirbsd* | -netbsd* \
+ | -openbsd* | -solidbsd* \
+ | -ekkobsd* | -kfreebsd* | -freebsd* | -riscix* | -lynxos* \
+ | -bosx* | -nextstep* | -cxux* | -aout* | -elf* | -oabi* \
+ | -ptx* | -coff* | -ecoff* | -winnt* | -domain* | -vsta* \
+ | -udi* | -eabi* | -lites* | -ieee* | -go32* | -aux* \
+ | -chorusos* | -chorusrdb* | -cegcc* \
+ | -cygwin* | -pe* | -psos* | -moss* | -proelf* | -rtems* \
+ | -mingw32* | -linux-gnu* | -linux-newlib* | -linux-uclibc* \
+ | -uxpv* | -beos* | -mpeix* | -udk* \
+ | -interix* | -uwin* | -mks* | -rhapsody* | -darwin* | -opened* \
+ | -openstep* | -oskit* | -conix* | -pw32* | -nonstopux* \
+ | -storm-chaos* | -tops10* | -tenex* | -tops20* | -its* \
+ | -os2* | -vos* | -palmos* | -uclinux* | -nucleus* \
+ | -morphos* | -superux* | -rtmk* | -rtmk-nova* | -windiss* \
+ | -powermax* | -dnix* | -nx6 | -nx7 | -sei* | -dragonfly* \
+ | -skyos* | -haiku* | -rdos* | -toppers* | -drops* | -es*)
+ # Remember, each alternative MUST END IN *, to match a version number.
+ ;;
+ -qnx*)
+ case $basic_machine in
+ x86-* | i*86-*)
+ ;;
+ *)
+ os=-nto$os
+ ;;
+ esac
+ ;;
+ -nto-qnx*)
+ ;;
+ -nto*)
+ os=`echo $os | sed -e 's|nto|nto-qnx|'`
+ ;;
+ -sim | -es1800* | -hms* | -xray | -os68k* | -none* | -v88r* \
+ | -windows* | -osx | -abug | -netware* | -os9* | -beos* | -haiku* \
+ | -macos* | -mpw* | -magic* | -mmixware* | -mon960* | -lnews*)
+ ;;
+ -mac*)
+ os=`echo $os | sed -e 's|mac|macos|'`
+ ;;
+ -linux-dietlibc)
+ os=-linux-dietlibc
+ ;;
+ -linux*)
+ os=`echo $os | sed -e 's|linux|linux-gnu|'`
+ ;;
+ -sunos5*)
+ os=`echo $os | sed -e 's|sunos5|solaris2|'`
+ ;;
+ -sunos6*)
+ os=`echo $os | sed -e 's|sunos6|solaris3|'`
+ ;;
+ -opened*)
+ os=-openedition
+ ;;
+ -os400*)
+ os=-os400
+ ;;
+ -wince*)
+ os=-wince
+ ;;
+ -osfrose*)
+ os=-osfrose
+ ;;
+ -osf*)
+ os=-osf
+ ;;
+ -utek*)
+ os=-bsd
+ ;;
+ -dynix*)
+ os=-bsd
+ ;;
+ -acis*)
+ os=-aos
+ ;;
+ -atheos*)
+ os=-atheos
+ ;;
+ -syllable*)
+ os=-syllable
+ ;;
+ -386bsd)
+ os=-bsd
+ ;;
+ -ctix* | -uts*)
+ os=-sysv
+ ;;
+ -nova*)
+ os=-rtmk-nova
+ ;;
+ -ns2 )
+ os=-nextstep2
+ ;;
+ -nsk*)
+ os=-nsk
+ ;;
+ # Preserve the version number of sinix5.
+ -sinix5.*)
+ os=`echo $os | sed -e 's|sinix|sysv|'`
+ ;;
+ -sinix*)
+ os=-sysv4
+ ;;
+ -tpf*)
+ os=-tpf
+ ;;
+ -triton*)
+ os=-sysv3
+ ;;
+ -oss*)
+ os=-sysv3
+ ;;
+ -svr4)
+ os=-sysv4
+ ;;
+ -svr3)
+ os=-sysv3
+ ;;
+ -sysvr4)
+ os=-sysv4
+ ;;
+ # This must come after -sysvr4.
+ -sysv*)
+ ;;
+ -ose*)
+ os=-ose
+ ;;
+ -es1800*)
+ os=-ose
+ ;;
+ -xenix)
+ os=-xenix
+ ;;
+ -*mint | -mint[0-9]* | -*MiNT | -MiNT[0-9]*)
+ os=-mint
+ ;;
+ -aros*)
+ os=-aros
+ ;;
+ -kaos*)
+ os=-kaos
+ ;;
+ -zvmoe)
+ os=-zvmoe
+ ;;
+ -dicos*)
+ os=-dicos
+ ;;
+ -nacl*)
+ ;;
+ -none)
+ ;;
+ *)
+ # Get rid of the `-' at the beginning of $os.
+ os=`echo $os | sed 's/[^-]*-//'`
+ echo Invalid configuration \`$1\': system \`$os\' not recognized 1>&2
+ exit 1
+ ;;
+esac
+else
+
+# Here we handle the default operating systems that come with various machines.
+# The value should be what the vendor currently ships out the door with their
+# machine or put another way, the most popular os provided with the machine.
+
+# Note that if you're going to try to match "-MANUFACTURER" here (say,
+# "-sun"), then you have to tell the case statement up towards the top
+# that MANUFACTURER isn't an operating system. Otherwise, code above
+# will signal an error saying that MANUFACTURER isn't an operating
+# system, and we'll never get to this point.
+
+case $basic_machine in
+ score-*)
+ os=-elf
+ ;;
+ spu-*)
+ os=-elf
+ ;;
+ *-acorn)
+ os=-riscix1.2
+ ;;
+ arm*-rebel)
+ os=-linux
+ ;;
+ arm*-semi)
+ os=-aout
+ ;;
+ c4x-* | tic4x-*)
+ os=-coff
+ ;;
+ # This must come before the *-dec entry.
+ pdp10-*)
+ os=-tops20
+ ;;
+ pdp11-*)
+ os=-none
+ ;;
+ *-dec | vax-*)
+ os=-ultrix4.2
+ ;;
+ m68*-apollo)
+ os=-domain
+ ;;
+ i386-sun)
+ os=-sunos4.0.2
+ ;;
+ m68000-sun)
+ os=-sunos3
+ # This also exists in the configure program, but was not the
+ # default.
+ # os=-sunos4
+ ;;
+ m68*-cisco)
+ os=-aout
+ ;;
+ mep-*)
+ os=-elf
+ ;;
+ mips*-cisco)
+ os=-elf
+ ;;
+ mips*-*)
+ os=-elf
+ ;;
+ or32-*)
+ os=-coff
+ ;;
+ *-tti) # must be before sparc entry or we get the wrong os.
+ os=-sysv3
+ ;;
+ sparc-* | *-sun)
+ os=-sunos4.1.1
+ ;;
+ *-be)
+ os=-beos
+ ;;
+ *-haiku)
+ os=-haiku
+ ;;
+ *-ibm)
+ os=-aix
+ ;;
+ *-knuth)
+ os=-mmixware
+ ;;
+ *-wec)
+ os=-proelf
+ ;;
+ *-winbond)
+ os=-proelf
+ ;;
+ *-oki)
+ os=-proelf
+ ;;
+ *-hp)
+ os=-hpux
+ ;;
+ *-hitachi)
+ os=-hiux
+ ;;
+ i860-* | *-att | *-ncr | *-altos | *-motorola | *-convergent)
+ os=-sysv
+ ;;
+ *-cbm)
+ os=-amigaos
+ ;;
+ *-dg)
+ os=-dgux
+ ;;
+ *-dolphin)
+ os=-sysv3
+ ;;
+ m68k-ccur)
+ os=-rtu
+ ;;
+ m88k-omron*)
+ os=-luna
+ ;;
+ *-next )
+ os=-nextstep
+ ;;
+ *-sequent)
+ os=-ptx
+ ;;
+ *-crds)
+ os=-unos
+ ;;
+ *-ns)
+ os=-genix
+ ;;
+ i370-*)
+ os=-mvs
+ ;;
+ *-next)
+ os=-nextstep3
+ ;;
+ *-gould)
+ os=-sysv
+ ;;
+ *-highlevel)
+ os=-bsd
+ ;;
+ *-encore)
+ os=-bsd
+ ;;
+ *-sgi)
+ os=-irix
+ ;;
+ *-siemens)
+ os=-sysv4
+ ;;
+ *-masscomp)
+ os=-rtu
+ ;;
+ f30[01]-fujitsu | f700-fujitsu)
+ os=-uxpv
+ ;;
+ *-rom68k)
+ os=-coff
+ ;;
+ *-*bug)
+ os=-coff
+ ;;
+ *-apple)
+ os=-macos
+ ;;
+ *-atari*)
+ os=-mint
+ ;;
+ *)
+ os=-none
+ ;;
+esac
+fi
+
+# Here we handle the case where we know the os, and the CPU type, but not the
+# manufacturer. We pick the logical manufacturer.
+vendor=unknown
+case $basic_machine in
+ *-unknown)
+ case $os in
+ -riscix*)
+ vendor=acorn
+ ;;
+ -sunos*)
+ vendor=sun
+ ;;
+ -cnk*|-aix*)
+ vendor=ibm
+ ;;
+ -beos*)
+ vendor=be
+ ;;
+ -hpux*)
+ vendor=hp
+ ;;
+ -mpeix*)
+ vendor=hp
+ ;;
+ -hiux*)
+ vendor=hitachi
+ ;;
+ -unos*)
+ vendor=crds
+ ;;
+ -dgux*)
+ vendor=dg
+ ;;
+ -luna*)
+ vendor=omron
+ ;;
+ -genix*)
+ vendor=ns
+ ;;
+ -mvs* | -opened*)
+ vendor=ibm
+ ;;
+ -os400*)
+ vendor=ibm
+ ;;
+ -ptx*)
+ vendor=sequent
+ ;;
+ -tpf*)
+ vendor=ibm
+ ;;
+ -vxsim* | -vxworks* | -windiss*)
+ vendor=wrs
+ ;;
+ -aux*)
+ vendor=apple
+ ;;
+ -hms*)
+ vendor=hitachi
+ ;;
+ -mpw* | -macos*)
+ vendor=apple
+ ;;
+ -*mint | -mint[0-9]* | -*MiNT | -MiNT[0-9]*)
+ vendor=atari
+ ;;
+ -vos*)
+ vendor=stratus
+ ;;
+ esac
+ basic_machine=`echo $basic_machine | sed "s/unknown/$vendor/"`
+ ;;
+esac
+
+echo $basic_machine$os
+exit
+
+# Local variables:
+# eval: (add-hook 'write-file-hooks 'time-stamp)
+# time-stamp-start: "timestamp='"
+# time-stamp-format: "%:y-%02m-%02d"
+# time-stamp-end: "'"
+# End:
diff --git a/contrib/libyaml/config/depcomp b/contrib/libyaml/config/depcomp
new file mode 100755
index 0000000..df8eea7
--- /dev/null
+++ b/contrib/libyaml/config/depcomp
@@ -0,0 +1,630 @@
+#! /bin/sh
+# depcomp - compile a program generating dependencies as side-effects
+
+scriptversion=2009-04-28.21; # UTC
+
+# Copyright (C) 1999, 2000, 2003, 2004, 2005, 2006, 2007, 2009 Free
+# Software Foundation, Inc.
+
+# 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, see <http://www.gnu.org/licenses/>.
+
+# 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.
+
+# Originally written by Alexandre Oliva <oliva@dcc.unicamp.br>.
+
+case $1 in
+ '')
+ echo "$0: No command. Try \`$0 --help' for more information." 1>&2
+ exit 1;
+ ;;
+ -h | --h*)
+ cat <<\EOF
+Usage: depcomp [--help] [--version] PROGRAM [ARGS]
+
+Run PROGRAMS ARGS to compile a file, generating dependencies
+as side-effects.
+
+Environment variables:
+ depmode Dependency tracking mode.
+ source Source file read by `PROGRAMS ARGS'.
+ object Object file output by `PROGRAMS ARGS'.
+ DEPDIR directory where to store dependencies.
+ depfile Dependency file to output.
+ tmpdepfile Temporary file to use when outputing dependencies.
+ libtool Whether libtool is used (yes/no).
+
+Report bugs to <bug-automake@gnu.org>.
+EOF
+ exit $?
+ ;;
+ -v | --v*)
+ echo "depcomp $scriptversion"
+ exit $?
+ ;;
+esac
+
+if test -z "$depmode" || test -z "$source" || test -z "$object"; then
+ echo "depcomp: Variables source, object and depmode must be set" 1>&2
+ exit 1
+fi
+
+# Dependencies for sub/bar.o or sub/bar.obj go into sub/.deps/bar.Po.
+depfile=${depfile-`echo "$object" |
+ sed 's|[^\\/]*$|'${DEPDIR-.deps}'/&|;s|\.\([^.]*\)$|.P\1|;s|Pobj$|Po|'`}
+tmpdepfile=${tmpdepfile-`echo "$depfile" | sed 's/\.\([^.]*\)$/.T\1/'`}
+
+rm -f "$tmpdepfile"
+
+# Some modes work just like other modes, but use different flags. We
+# parameterize here, but still list the modes in the big case below,
+# to make depend.m4 easier to write. Note that we *cannot* use a case
+# here, because this file can only contain one case statement.
+if test "$depmode" = hp; then
+ # HP compiler uses -M and no extra arg.
+ gccflag=-M
+ depmode=gcc
+fi
+
+if test "$depmode" = dashXmstdout; then
+ # This is just like dashmstdout with a different argument.
+ dashmflag=-xM
+ depmode=dashmstdout
+fi
+
+cygpath_u="cygpath -u -f -"
+if test "$depmode" = msvcmsys; then
+ # This is just like msvisualcpp but w/o cygpath translation.
+ # Just convert the backslash-escaped backslashes to single forward
+ # slashes to satisfy depend.m4
+ cygpath_u="sed s,\\\\\\\\,/,g"
+ depmode=msvisualcpp
+fi
+
+case "$depmode" in
+gcc3)
+## gcc 3 implements dependency tracking that does exactly what
+## we want. Yay! Note: for some reason libtool 1.4 doesn't like
+## it if -MD -MP comes after the -MF stuff. Hmm.
+## Unfortunately, FreeBSD c89 acceptance of flags depends upon
+## the command line argument order; so add the flags where they
+## appear in depend2.am. Note that the slowdown incurred here
+## affects only configure: in makefiles, %FASTDEP% shortcuts this.
+ for arg
+ do
+ case $arg in
+ -c) set fnord "$@" -MT "$object" -MD -MP -MF "$tmpdepfile" "$arg" ;;
+ *) set fnord "$@" "$arg" ;;
+ esac
+ shift # fnord
+ shift # $arg
+ done
+ "$@"
+ stat=$?
+ if test $stat -eq 0; then :
+ else
+ rm -f "$tmpdepfile"
+ exit $stat
+ fi
+ mv "$tmpdepfile" "$depfile"
+ ;;
+
+gcc)
+## There are various ways to get dependency output from gcc. Here's
+## why we pick this rather obscure method:
+## - Don't want to use -MD because we'd like the dependencies to end
+## up in a subdir. Having to rename by hand is ugly.
+## (We might end up doing this anyway to support other compilers.)
+## - The DEPENDENCIES_OUTPUT environment variable makes gcc act like
+## -MM, not -M (despite what the docs say).
+## - Using -M directly means running the compiler twice (even worse
+## than renaming).
+ if test -z "$gccflag"; then
+ gccflag=-MD,
+ fi
+ "$@" -Wp,"$gccflag$tmpdepfile"
+ stat=$?
+ if test $stat -eq 0; then :
+ else
+ rm -f "$tmpdepfile"
+ exit $stat
+ fi
+ rm -f "$depfile"
+ echo "$object : \\" > "$depfile"
+ alpha=ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz
+## The second -e expression handles DOS-style file names with drive letters.
+ sed -e 's/^[^:]*: / /' \
+ -e 's/^['$alpha']:\/[^:]*: / /' < "$tmpdepfile" >> "$depfile"
+## This next piece of magic avoids the `deleted header file' problem.
+## The problem is that when a header file which appears in a .P file
+## is deleted, the dependency causes make to die (because there is
+## typically no way to rebuild the header). We avoid this by adding
+## dummy dependencies for each header file. Too bad gcc doesn't do
+## this for us directly.
+ tr ' ' '
+' < "$tmpdepfile" |
+## Some versions of gcc put a space before the `:'. On the theory
+## that the space means something, we add a space to the output as
+## well.
+## Some versions of the HPUX 10.20 sed can't process this invocation
+## correctly. Breaking it into two sed invocations is a workaround.
+ sed -e 's/^\\$//' -e '/^$/d' -e '/:$/d' | sed -e 's/$/ :/' >> "$depfile"
+ rm -f "$tmpdepfile"
+ ;;
+
+hp)
+ # This case exists only to let depend.m4 do its work. It works by
+ # looking at the text of this script. This case will never be run,
+ # since it is checked for above.
+ exit 1
+ ;;
+
+sgi)
+ if test "$libtool" = yes; then
+ "$@" "-Wp,-MDupdate,$tmpdepfile"
+ else
+ "$@" -MDupdate "$tmpdepfile"
+ fi
+ stat=$?
+ if test $stat -eq 0; then :
+ else
+ rm -f "$tmpdepfile"
+ exit $stat
+ fi
+ rm -f "$depfile"
+
+ if test -f "$tmpdepfile"; then # yes, the sourcefile depend on other files
+ echo "$object : \\" > "$depfile"
+
+ # Clip off the initial element (the dependent). Don't try to be
+ # clever and replace this with sed code, as IRIX sed won't handle
+ # lines with more than a fixed number of characters (4096 in
+ # IRIX 6.2 sed, 8192 in IRIX 6.5). We also remove comment lines;
+ # the IRIX cc adds comments like `#:fec' to the end of the
+ # dependency line.
+ tr ' ' '
+' < "$tmpdepfile" \
+ | sed -e 's/^.*\.o://' -e 's/#.*$//' -e '/^$/ d' | \
+ tr '
+' ' ' >> "$depfile"
+ echo >> "$depfile"
+
+ # The second pass generates a dummy entry for each header file.
+ tr ' ' '
+' < "$tmpdepfile" \
+ | sed -e 's/^.*\.o://' -e 's/#.*$//' -e '/^$/ d' -e 's/$/:/' \
+ >> "$depfile"
+ else
+ # The sourcefile does not contain any dependencies, so just
+ # store a dummy comment line, to avoid errors with the Makefile
+ # "include basename.Plo" scheme.
+ echo "#dummy" > "$depfile"
+ fi
+ rm -f "$tmpdepfile"
+ ;;
+
+aix)
+ # The C for AIX Compiler uses -M and outputs the dependencies
+ # in a .u file. In older versions, this file always lives in the
+ # current directory. Also, the AIX compiler puts `$object:' at the
+ # start of each line; $object doesn't have directory information.
+ # Version 6 uses the directory in both cases.
+ dir=`echo "$object" | sed -e 's|/[^/]*$|/|'`
+ test "x$dir" = "x$object" && dir=
+ base=`echo "$object" | sed -e 's|^.*/||' -e 's/\.o$//' -e 's/\.lo$//'`
+ if test "$libtool" = yes; then
+ tmpdepfile1=$dir$base.u
+ tmpdepfile2=$base.u
+ tmpdepfile3=$dir.libs/$base.u
+ "$@" -Wc,-M
+ else
+ tmpdepfile1=$dir$base.u
+ tmpdepfile2=$dir$base.u
+ tmpdepfile3=$dir$base.u
+ "$@" -M
+ fi
+ stat=$?
+
+ if test $stat -eq 0; then :
+ else
+ rm -f "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3"
+ exit $stat
+ fi
+
+ for tmpdepfile in "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3"
+ do
+ test -f "$tmpdepfile" && break
+ done
+ if test -f "$tmpdepfile"; then
+ # Each line is of the form `foo.o: dependent.h'.
+ # Do two passes, one to just change these to
+ # `$object: dependent.h' and one to simply `dependent.h:'.
+ sed -e "s,^.*\.[a-z]*:,$object:," < "$tmpdepfile" > "$depfile"
+ # That's a tab and a space in the [].
+ sed -e 's,^.*\.[a-z]*:[ ]*,,' -e 's,$,:,' < "$tmpdepfile" >> "$depfile"
+ else
+ # The sourcefile does not contain any dependencies, so just
+ # store a dummy comment line, to avoid errors with the Makefile
+ # "include basename.Plo" scheme.
+ echo "#dummy" > "$depfile"
+ fi
+ rm -f "$tmpdepfile"
+ ;;
+
+icc)
+ # Intel's C compiler understands `-MD -MF file'. However on
+ # icc -MD -MF foo.d -c -o sub/foo.o sub/foo.c
+ # ICC 7.0 will fill foo.d with something like
+ # foo.o: sub/foo.c
+ # foo.o: sub/foo.h
+ # which is wrong. We want:
+ # sub/foo.o: sub/foo.c
+ # sub/foo.o: sub/foo.h
+ # sub/foo.c:
+ # sub/foo.h:
+ # ICC 7.1 will output
+ # foo.o: sub/foo.c sub/foo.h
+ # and will wrap long lines using \ :
+ # foo.o: sub/foo.c ... \
+ # sub/foo.h ... \
+ # ...
+
+ "$@" -MD -MF "$tmpdepfile"
+ stat=$?
+ if test $stat -eq 0; then :
+ else
+ rm -f "$tmpdepfile"
+ exit $stat
+ fi
+ rm -f "$depfile"
+ # Each line is of the form `foo.o: dependent.h',
+ # or `foo.o: dep1.h dep2.h \', or ` dep3.h dep4.h \'.
+ # Do two passes, one to just change these to
+ # `$object: dependent.h' and one to simply `dependent.h:'.
+ sed "s,^[^:]*:,$object :," < "$tmpdepfile" > "$depfile"
+ # Some versions of the HPUX 10.20 sed can't process this invocation
+ # correctly. Breaking it into two sed invocations is a workaround.
+ sed 's,^[^:]*: \(.*\)$,\1,;s/^\\$//;/^$/d;/:$/d' < "$tmpdepfile" |
+ sed -e 's/$/ :/' >> "$depfile"
+ rm -f "$tmpdepfile"
+ ;;
+
+hp2)
+ # The "hp" stanza above does not work with aCC (C++) and HP's ia64
+ # compilers, which have integrated preprocessors. The correct option
+ # to use with these is +Maked; it writes dependencies to a file named
+ # 'foo.d', which lands next to the object file, wherever that
+ # happens to be.
+ # Much of this is similar to the tru64 case; see comments there.
+ dir=`echo "$object" | sed -e 's|/[^/]*$|/|'`
+ test "x$dir" = "x$object" && dir=
+ base=`echo "$object" | sed -e 's|^.*/||' -e 's/\.o$//' -e 's/\.lo$//'`
+ if test "$libtool" = yes; then
+ tmpdepfile1=$dir$base.d
+ tmpdepfile2=$dir.libs/$base.d
+ "$@" -Wc,+Maked
+ else
+ tmpdepfile1=$dir$base.d
+ tmpdepfile2=$dir$base.d
+ "$@" +Maked
+ fi
+ stat=$?
+ if test $stat -eq 0; then :
+ else
+ rm -f "$tmpdepfile1" "$tmpdepfile2"
+ exit $stat
+ fi
+
+ for tmpdepfile in "$tmpdepfile1" "$tmpdepfile2"
+ do
+ test -f "$tmpdepfile" && break
+ done
+ if test -f "$tmpdepfile"; then
+ sed -e "s,^.*\.[a-z]*:,$object:," "$tmpdepfile" > "$depfile"
+ # Add `dependent.h:' lines.
+ sed -ne '2,${
+ s/^ *//
+ s/ \\*$//
+ s/$/:/
+ p
+ }' "$tmpdepfile" >> "$depfile"
+ else
+ echo "#dummy" > "$depfile"
+ fi
+ rm -f "$tmpdepfile" "$tmpdepfile2"
+ ;;
+
+tru64)
+ # The Tru64 compiler uses -MD to generate dependencies as a side
+ # effect. `cc -MD -o foo.o ...' puts the dependencies into `foo.o.d'.
+ # At least on Alpha/Redhat 6.1, Compaq CCC V6.2-504 seems to put
+ # dependencies in `foo.d' instead, so we check for that too.
+ # Subdirectories are respected.
+ dir=`echo "$object" | sed -e 's|/[^/]*$|/|'`
+ test "x$dir" = "x$object" && dir=
+ base=`echo "$object" | sed -e 's|^.*/||' -e 's/\.o$//' -e 's/\.lo$//'`
+
+ if test "$libtool" = yes; then
+ # With Tru64 cc, shared objects can also be used to make a
+ # static library. This mechanism is used in libtool 1.4 series to
+ # handle both shared and static libraries in a single compilation.
+ # With libtool 1.4, dependencies were output in $dir.libs/$base.lo.d.
+ #
+ # With libtool 1.5 this exception was removed, and libtool now
+ # generates 2 separate objects for the 2 libraries. These two
+ # compilations output dependencies in $dir.libs/$base.o.d and
+ # in $dir$base.o.d. We have to check for both files, because
+ # one of the two compilations can be disabled. We should prefer
+ # $dir$base.o.d over $dir.libs/$base.o.d because the latter is
+ # automatically cleaned when .libs/ is deleted, while ignoring
+ # the former would cause a distcleancheck panic.
+ tmpdepfile1=$dir.libs/$base.lo.d # libtool 1.4
+ tmpdepfile2=$dir$base.o.d # libtool 1.5
+ tmpdepfile3=$dir.libs/$base.o.d # libtool 1.5
+ tmpdepfile4=$dir.libs/$base.d # Compaq CCC V6.2-504
+ "$@" -Wc,-MD
+ else
+ tmpdepfile1=$dir$base.o.d
+ tmpdepfile2=$dir$base.d
+ tmpdepfile3=$dir$base.d
+ tmpdepfile4=$dir$base.d
+ "$@" -MD
+ fi
+
+ stat=$?
+ if test $stat -eq 0; then :
+ else
+ rm -f "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3" "$tmpdepfile4"
+ exit $stat
+ fi
+
+ for tmpdepfile in "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3" "$tmpdepfile4"
+ do
+ test -f "$tmpdepfile" && break
+ done
+ if test -f "$tmpdepfile"; then
+ sed -e "s,^.*\.[a-z]*:,$object:," < "$tmpdepfile" > "$depfile"
+ # That's a tab and a space in the [].
+ sed -e 's,^.*\.[a-z]*:[ ]*,,' -e 's,$,:,' < "$tmpdepfile" >> "$depfile"
+ else
+ echo "#dummy" > "$depfile"
+ fi
+ rm -f "$tmpdepfile"
+ ;;
+
+#nosideeffect)
+ # This comment above is used by automake to tell side-effect
+ # dependency tracking mechanisms from slower ones.
+
+dashmstdout)
+ # Important note: in order to support this mode, a compiler *must*
+ # always write the preprocessed file to stdout, regardless of -o.
+ "$@" || exit $?
+
+ # Remove the call to Libtool.
+ if test "$libtool" = yes; then
+ while test "X$1" != 'X--mode=compile'; do
+ shift
+ done
+ shift
+ fi
+
+ # Remove `-o $object'.
+ IFS=" "
+ for arg
+ do
+ case $arg in
+ -o)
+ shift
+ ;;
+ $object)
+ shift
+ ;;
+ *)
+ set fnord "$@" "$arg"
+ shift # fnord
+ shift # $arg
+ ;;
+ esac
+ done
+
+ test -z "$dashmflag" && dashmflag=-M
+ # Require at least two characters before searching for `:'
+ # in the target name. This is to cope with DOS-style filenames:
+ # a dependency such as `c:/foo/bar' could be seen as target `c' otherwise.
+ "$@" $dashmflag |
+ sed 's:^[ ]*[^: ][^:][^:]*\:[ ]*:'"$object"'\: :' > "$tmpdepfile"
+ rm -f "$depfile"
+ cat < "$tmpdepfile" > "$depfile"
+ tr ' ' '
+' < "$tmpdepfile" | \
+## Some versions of the HPUX 10.20 sed can't process this invocation
+## correctly. Breaking it into two sed invocations is a workaround.
+ sed -e 's/^\\$//' -e '/^$/d' -e '/:$/d' | sed -e 's/$/ :/' >> "$depfile"
+ rm -f "$tmpdepfile"
+ ;;
+
+dashXmstdout)
+ # This case only exists to satisfy depend.m4. It is never actually
+ # run, as this mode is specially recognized in the preamble.
+ exit 1
+ ;;
+
+makedepend)
+ "$@" || exit $?
+ # Remove any Libtool call
+ if test "$libtool" = yes; then
+ while test "X$1" != 'X--mode=compile'; do
+ shift
+ done
+ shift
+ fi
+ # X makedepend
+ shift
+ cleared=no eat=no
+ for arg
+ do
+ case $cleared in
+ no)
+ set ""; shift
+ cleared=yes ;;
+ esac
+ if test $eat = yes; then
+ eat=no
+ continue
+ fi
+ case "$arg" in
+ -D*|-I*)
+ set fnord "$@" "$arg"; shift ;;
+ # Strip any option that makedepend may not understand. Remove
+ # the object too, otherwise makedepend will parse it as a source file.
+ -arch)
+ eat=yes ;;
+ -*|$object)
+ ;;
+ *)
+ set fnord "$@" "$arg"; shift ;;
+ esac
+ done
+ obj_suffix=`echo "$object" | sed 's/^.*\././'`
+ touch "$tmpdepfile"
+ ${MAKEDEPEND-makedepend} -o"$obj_suffix" -f"$tmpdepfile" "$@"
+ rm -f "$depfile"
+ cat < "$tmpdepfile" > "$depfile"
+ sed '1,2d' "$tmpdepfile" | tr ' ' '
+' | \
+## Some versions of the HPUX 10.20 sed can't process this invocation
+## correctly. Breaking it into two sed invocations is a workaround.
+ sed -e 's/^\\$//' -e '/^$/d' -e '/:$/d' | sed -e 's/$/ :/' >> "$depfile"
+ rm -f "$tmpdepfile" "$tmpdepfile".bak
+ ;;
+
+cpp)
+ # Important note: in order to support this mode, a compiler *must*
+ # always write the preprocessed file to stdout.
+ "$@" || exit $?
+
+ # Remove the call to Libtool.
+ if test "$libtool" = yes; then
+ while test "X$1" != 'X--mode=compile'; do
+ shift
+ done
+ shift
+ fi
+
+ # Remove `-o $object'.
+ IFS=" "
+ for arg
+ do
+ case $arg in
+ -o)
+ shift
+ ;;
+ $object)
+ shift
+ ;;
+ *)
+ set fnord "$@" "$arg"
+ shift # fnord
+ shift # $arg
+ ;;
+ esac
+ done
+
+ "$@" -E |
+ sed -n -e '/^# [0-9][0-9]* "\([^"]*\)".*/ s:: \1 \\:p' \
+ -e '/^#line [0-9][0-9]* "\([^"]*\)".*/ s:: \1 \\:p' |
+ sed '$ s: \\$::' > "$tmpdepfile"
+ rm -f "$depfile"
+ echo "$object : \\" > "$depfile"
+ cat < "$tmpdepfile" >> "$depfile"
+ sed < "$tmpdepfile" '/^$/d;s/^ //;s/ \\$//;s/$/ :/' >> "$depfile"
+ rm -f "$tmpdepfile"
+ ;;
+
+msvisualcpp)
+ # Important note: in order to support this mode, a compiler *must*
+ # always write the preprocessed file to stdout.
+ "$@" || exit $?
+
+ # Remove the call to Libtool.
+ if test "$libtool" = yes; then
+ while test "X$1" != 'X--mode=compile'; do
+ shift
+ done
+ shift
+ fi
+
+ IFS=" "
+ for arg
+ do
+ case "$arg" in
+ -o)
+ shift
+ ;;
+ $object)
+ shift
+ ;;
+ "-Gm"|"/Gm"|"-Gi"|"/Gi"|"-ZI"|"/ZI")
+ set fnord "$@"
+ shift
+ shift
+ ;;
+ *)
+ set fnord "$@" "$arg"
+ shift
+ shift
+ ;;
+ esac
+ done
+ "$@" -E 2>/dev/null |
+ sed -n '/^#line [0-9][0-9]* "\([^"]*\)"/ s::\1:p' | $cygpath_u | sort -u > "$tmpdepfile"
+ rm -f "$depfile"
+ echo "$object : \\" > "$depfile"
+ sed < "$tmpdepfile" -n -e 's% %\\ %g' -e '/^\(.*\)$/ s:: \1 \\:p' >> "$depfile"
+ echo " " >> "$depfile"
+ sed < "$tmpdepfile" -n -e 's% %\\ %g' -e '/^\(.*\)$/ s::\1\::p' >> "$depfile"
+ rm -f "$tmpdepfile"
+ ;;
+
+msvcmsys)
+ # This case exists only to let depend.m4 do its work. It works by
+ # looking at the text of this script. This case will never be run,
+ # since it is checked for above.
+ exit 1
+ ;;
+
+none)
+ exec "$@"
+ ;;
+
+*)
+ echo "Unknown depmode $depmode" 1>&2
+ exit 1
+ ;;
+esac
+
+exit 0
+
+# Local Variables:
+# mode: shell-script
+# sh-indentation: 2
+# eval: (add-hook 'write-file-hooks 'time-stamp)
+# time-stamp-start: "scriptversion="
+# time-stamp-format: "%:y-%02m-%02d.%02H"
+# time-stamp-time-zone: "UTC"
+# time-stamp-end: "; # UTC"
+# End:
diff --git a/contrib/libyaml/config/install-sh b/contrib/libyaml/config/install-sh
new file mode 100755
index 0000000..6781b98
--- /dev/null
+++ b/contrib/libyaml/config/install-sh
@@ -0,0 +1,520 @@
+#!/bin/sh
+# install - install a program, script, or datafile
+
+scriptversion=2009-04-28.21; # UTC
+
+# This originates from X11R5 (mit/util/scripts/install.sh), which was
+# later released in X11R6 (xc/config/util/install.sh) with the
+# following copyright and license.
+#
+# Copyright (C) 1994 X Consortium
+#
+# Permission is hereby granted, free of charge, to any person obtaining a copy
+# of this software and associated documentation files (the "Software"), to
+# deal in the Software without restriction, including without limitation the
+# rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+# sell copies of the Software, and to permit persons to whom the Software is
+# furnished to do so, subject to the following conditions:
+#
+# The above copyright notice and this permission notice shall be included in
+# all copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+# X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+# AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNEC-
+# TION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+#
+# Except as contained in this notice, the name of the X Consortium shall not
+# be used in advertising or otherwise to promote the sale, use or other deal-
+# ings in this Software without prior written authorization from the X Consor-
+# tium.
+#
+#
+# FSF changes to this file are in the public domain.
+#
+# 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.
+
+nl='
+'
+IFS=" "" $nl"
+
+# set DOITPROG to echo to test this script
+
+# Don't use :- since 4.3BSD and earlier shells don't like it.
+doit=${DOITPROG-}
+if test -z "$doit"; then
+ doit_exec=exec
+else
+ doit_exec=$doit
+fi
+
+# Put in absolute file names if you don't have them in your path;
+# or use environment vars.
+
+chgrpprog=${CHGRPPROG-chgrp}
+chmodprog=${CHMODPROG-chmod}
+chownprog=${CHOWNPROG-chown}
+cmpprog=${CMPPROG-cmp}
+cpprog=${CPPROG-cp}
+mkdirprog=${MKDIRPROG-mkdir}
+mvprog=${MVPROG-mv}
+rmprog=${RMPROG-rm}
+stripprog=${STRIPPROG-strip}
+
+posix_glob='?'
+initialize_posix_glob='
+ test "$posix_glob" != "?" || {
+ if (set -f) 2>/dev/null; then
+ posix_glob=
+ else
+ posix_glob=:
+ fi
+ }
+'
+
+posix_mkdir=
+
+# Desired mode of installed file.
+mode=0755
+
+chgrpcmd=
+chmodcmd=$chmodprog
+chowncmd=
+mvcmd=$mvprog
+rmcmd="$rmprog -f"
+stripcmd=
+
+src=
+dst=
+dir_arg=
+dst_arg=
+
+copy_on_change=false
+no_target_directory=
+
+usage="\
+Usage: $0 [OPTION]... [-T] SRCFILE DSTFILE
+ or: $0 [OPTION]... SRCFILES... DIRECTORY
+ or: $0 [OPTION]... -t DIRECTORY SRCFILES...
+ or: $0 [OPTION]... -d DIRECTORIES...
+
+In the 1st form, copy SRCFILE to DSTFILE.
+In the 2nd and 3rd, copy all SRCFILES to DIRECTORY.
+In the 4th, create DIRECTORIES.
+
+Options:
+ --help display this help and exit.
+ --version display version info and exit.
+
+ -c (ignored)
+ -C install only if different (preserve the last data modification time)
+ -d create directories instead of installing files.
+ -g GROUP $chgrpprog installed files to GROUP.
+ -m MODE $chmodprog installed files to MODE.
+ -o USER $chownprog installed files to USER.
+ -s $stripprog installed files.
+ -t DIRECTORY install into DIRECTORY.
+ -T report an error if DSTFILE is a directory.
+
+Environment variables override the default commands:
+ CHGRPPROG CHMODPROG CHOWNPROG CMPPROG CPPROG MKDIRPROG MVPROG
+ RMPROG STRIPPROG
+"
+
+while test $# -ne 0; do
+ case $1 in
+ -c) ;;
+
+ -C) copy_on_change=true;;
+
+ -d) dir_arg=true;;
+
+ -g) chgrpcmd="$chgrpprog $2"
+ shift;;
+
+ --help) echo "$usage"; exit $?;;
+
+ -m) mode=$2
+ case $mode in
+ *' '* | *' '* | *'
+'* | *'*'* | *'?'* | *'['*)
+ echo "$0: invalid mode: $mode" >&2
+ exit 1;;
+ esac
+ shift;;
+
+ -o) chowncmd="$chownprog $2"
+ shift;;
+
+ -s) stripcmd=$stripprog;;
+
+ -t) dst_arg=$2
+ shift;;
+
+ -T) no_target_directory=true;;
+
+ --version) echo "$0 $scriptversion"; exit $?;;
+
+ --) shift
+ break;;
+
+ -*) echo "$0: invalid option: $1" >&2
+ exit 1;;
+
+ *) break;;
+ esac
+ shift
+done
+
+if test $# -ne 0 && test -z "$dir_arg$dst_arg"; then
+ # When -d is used, all remaining arguments are directories to create.
+ # When -t is used, the destination is already specified.
+ # Otherwise, the last argument is the destination. Remove it from $@.
+ for arg
+ do
+ if test -n "$dst_arg"; then
+ # $@ is not empty: it contains at least $arg.
+ set fnord "$@" "$dst_arg"
+ shift # fnord
+ fi
+ shift # arg
+ dst_arg=$arg
+ done
+fi
+
+if test $# -eq 0; then
+ if test -z "$dir_arg"; then
+ echo "$0: no input file specified." >&2
+ exit 1
+ fi
+ # It's OK to call `install-sh -d' without argument.
+ # This can happen when creating conditional directories.
+ exit 0
+fi
+
+if test -z "$dir_arg"; then
+ trap '(exit $?); exit' 1 2 13 15
+
+ # Set umask so as not to create temps with too-generous modes.
+ # However, 'strip' requires both read and write access to temps.
+ case $mode in
+ # Optimize common cases.
+ *644) cp_umask=133;;
+ *755) cp_umask=22;;
+
+ *[0-7])
+ if test -z "$stripcmd"; then
+ u_plus_rw=
+ else
+ u_plus_rw='% 200'
+ fi
+ cp_umask=`expr '(' 777 - $mode % 1000 ')' $u_plus_rw`;;
+ *)
+ if test -z "$stripcmd"; then
+ u_plus_rw=
+ else
+ u_plus_rw=,u+rw
+ fi
+ cp_umask=$mode$u_plus_rw;;
+ esac
+fi
+
+for src
+do
+ # Protect names starting with `-'.
+ case $src in
+ -*) src=./$src;;
+ esac
+
+ if test -n "$dir_arg"; then
+ dst=$src
+ dstdir=$dst
+ test -d "$dstdir"
+ dstdir_status=$?
+ else
+
+ # Waiting for this to be detected by the "$cpprog $src $dsttmp" command
+ # might cause directories to be created, which would be especially bad
+ # if $src (and thus $dsttmp) contains '*'.
+ if test ! -f "$src" && test ! -d "$src"; then
+ echo "$0: $src does not exist." >&2
+ exit 1
+ fi
+
+ if test -z "$dst_arg"; then
+ echo "$0: no destination specified." >&2
+ exit 1
+ fi
+
+ dst=$dst_arg
+ # Protect names starting with `-'.
+ case $dst in
+ -*) dst=./$dst;;
+ esac
+
+ # If destination is a directory, append the input filename; won't work
+ # if double slashes aren't ignored.
+ if test -d "$dst"; then
+ if test -n "$no_target_directory"; then
+ echo "$0: $dst_arg: Is a directory" >&2
+ exit 1
+ fi
+ dstdir=$dst
+ dst=$dstdir/`basename "$src"`
+ dstdir_status=0
+ else
+ # Prefer dirname, but fall back on a substitute if dirname fails.
+ dstdir=`
+ (dirname "$dst") 2>/dev/null ||
+ expr X"$dst" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
+ X"$dst" : 'X\(//\)[^/]' \| \
+ X"$dst" : 'X\(//\)$' \| \
+ X"$dst" : 'X\(/\)' \| . 2>/dev/null ||
+ echo X"$dst" |
+ sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{
+ s//\1/
+ q
+ }
+ /^X\(\/\/\)[^/].*/{
+ s//\1/
+ q
+ }
+ /^X\(\/\/\)$/{
+ s//\1/
+ q
+ }
+ /^X\(\/\).*/{
+ s//\1/
+ q
+ }
+ s/.*/./; q'
+ `
+
+ test -d "$dstdir"
+ dstdir_status=$?
+ fi
+ fi
+
+ obsolete_mkdir_used=false
+
+ if test $dstdir_status != 0; then
+ case $posix_mkdir in
+ '')
+ # Create intermediate dirs using mode 755 as modified by the umask.
+ # This is like FreeBSD 'install' as of 1997-10-28.
+ umask=`umask`
+ case $stripcmd.$umask in
+ # Optimize common cases.
+ *[2367][2367]) mkdir_umask=$umask;;
+ .*0[02][02] | .[02][02] | .[02]) mkdir_umask=22;;
+
+ *[0-7])
+ mkdir_umask=`expr $umask + 22 \
+ - $umask % 100 % 40 + $umask % 20 \
+ - $umask % 10 % 4 + $umask % 2
+ `;;
+ *) mkdir_umask=$umask,go-w;;
+ esac
+
+ # With -d, create the new directory with the user-specified mode.
+ # Otherwise, rely on $mkdir_umask.
+ if test -n "$dir_arg"; then
+ mkdir_mode=-m$mode
+ else
+ mkdir_mode=
+ fi
+
+ posix_mkdir=false
+ case $umask in
+ *[123567][0-7][0-7])
+ # POSIX mkdir -p sets u+wx bits regardless of umask, which
+ # is incompatible with FreeBSD 'install' when (umask & 300) != 0.
+ ;;
+ *)
+ tmpdir=${TMPDIR-/tmp}/ins$RANDOM-$$
+ trap 'ret=$?; rmdir "$tmpdir/d" "$tmpdir" 2>/dev/null; exit $ret' 0
+
+ if (umask $mkdir_umask &&
+ exec $mkdirprog $mkdir_mode -p -- "$tmpdir/d") >/dev/null 2>&1
+ then
+ if test -z "$dir_arg" || {
+ # Check for POSIX incompatibilities with -m.
+ # HP-UX 11.23 and IRIX 6.5 mkdir -m -p sets group- or
+ # other-writeable bit of parent directory when it shouldn't.
+ # FreeBSD 6.1 mkdir -m -p sets mode of existing directory.
+ ls_ld_tmpdir=`ls -ld "$tmpdir"`
+ case $ls_ld_tmpdir in
+ d????-?r-*) different_mode=700;;
+ d????-?--*) different_mode=755;;
+ *) false;;
+ esac &&
+ $mkdirprog -m$different_mode -p -- "$tmpdir" && {
+ ls_ld_tmpdir_1=`ls -ld "$tmpdir"`
+ test "$ls_ld_tmpdir" = "$ls_ld_tmpdir_1"
+ }
+ }
+ then posix_mkdir=:
+ fi
+ rmdir "$tmpdir/d" "$tmpdir"
+ else
+ # Remove any dirs left behind by ancient mkdir implementations.
+ rmdir ./$mkdir_mode ./-p ./-- 2>/dev/null
+ fi
+ trap '' 0;;
+ esac;;
+ esac
+
+ if
+ $posix_mkdir && (
+ umask $mkdir_umask &&
+ $doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir"
+ )
+ then :
+ else
+
+ # The umask is ridiculous, or mkdir does not conform to POSIX,
+ # or it failed possibly due to a race condition. Create the
+ # directory the slow way, step by step, checking for races as we go.
+
+ case $dstdir in
+ /*) prefix='/';;
+ -*) prefix='./';;
+ *) prefix='';;
+ esac
+
+ eval "$initialize_posix_glob"
+
+ oIFS=$IFS
+ IFS=/
+ $posix_glob set -f
+ set fnord $dstdir
+ shift
+ $posix_glob set +f
+ IFS=$oIFS
+
+ prefixes=
+
+ for d
+ do
+ test -z "$d" && continue
+
+ prefix=$prefix$d
+ if test -d "$prefix"; then
+ prefixes=
+ else
+ if $posix_mkdir; then
+ (umask=$mkdir_umask &&
+ $doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir") && break
+ # Don't fail if two instances are running concurrently.
+ test -d "$prefix" || exit 1
+ else
+ case $prefix in
+ *\'*) qprefix=`echo "$prefix" | sed "s/'/'\\\\\\\\''/g"`;;
+ *) qprefix=$prefix;;
+ esac
+ prefixes="$prefixes '$qprefix'"
+ fi
+ fi
+ prefix=$prefix/
+ done
+
+ if test -n "$prefixes"; then
+ # Don't fail if two instances are running concurrently.
+ (umask $mkdir_umask &&
+ eval "\$doit_exec \$mkdirprog $prefixes") ||
+ test -d "$dstdir" || exit 1
+ obsolete_mkdir_used=true
+ fi
+ fi
+ fi
+
+ if test -n "$dir_arg"; then
+ { test -z "$chowncmd" || $doit $chowncmd "$dst"; } &&
+ { test -z "$chgrpcmd" || $doit $chgrpcmd "$dst"; } &&
+ { test "$obsolete_mkdir_used$chowncmd$chgrpcmd" = false ||
+ test -z "$chmodcmd" || $doit $chmodcmd $mode "$dst"; } || exit 1
+ else
+
+ # Make a couple of temp file names in the proper directory.
+ dsttmp=$dstdir/_inst.$$_
+ rmtmp=$dstdir/_rm.$$_
+
+ # Trap to clean up those temp files at exit.
+ trap 'ret=$?; rm -f "$dsttmp" "$rmtmp" && exit $ret' 0
+
+ # Copy the file name to the temp name.
+ (umask $cp_umask && $doit_exec $cpprog "$src" "$dsttmp") &&
+
+ # 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 $cpprog $src $dsttmp" command.
+ #
+ { test -z "$chowncmd" || $doit $chowncmd "$dsttmp"; } &&
+ { test -z "$chgrpcmd" || $doit $chgrpcmd "$dsttmp"; } &&
+ { test -z "$stripcmd" || $doit $stripcmd "$dsttmp"; } &&
+ { test -z "$chmodcmd" || $doit $chmodcmd $mode "$dsttmp"; } &&
+
+ # If -C, don't bother to copy if it wouldn't change the file.
+ if $copy_on_change &&
+ old=`LC_ALL=C ls -dlL "$dst" 2>/dev/null` &&
+ new=`LC_ALL=C ls -dlL "$dsttmp" 2>/dev/null` &&
+
+ eval "$initialize_posix_glob" &&
+ $posix_glob set -f &&
+ set X $old && old=:$2:$4:$5:$6 &&
+ set X $new && new=:$2:$4:$5:$6 &&
+ $posix_glob set +f &&
+
+ test "$old" = "$new" &&
+ $cmpprog "$dst" "$dsttmp" >/dev/null 2>&1
+ then
+ rm -f "$dsttmp"
+ else
+ # Rename the file to the real destination.
+ $doit $mvcmd -f "$dsttmp" "$dst" 2>/dev/null ||
+
+ # The rename failed, perhaps because mv can't rename something else
+ # to itself, or perhaps because mv is so ancient that it does not
+ # support -f.
+ {
+ # Now remove or move aside any old file at destination location.
+ # We try this two ways since rm can't unlink itself on some
+ # systems and the destination file might be busy for other
+ # reasons. In this case, the final cleanup might fail but the new
+ # file should still install successfully.
+ {
+ test ! -f "$dst" ||
+ $doit $rmcmd -f "$dst" 2>/dev/null ||
+ { $doit $mvcmd -f "$dst" "$rmtmp" 2>/dev/null &&
+ { $doit $rmcmd -f "$rmtmp" 2>/dev/null; :; }
+ } ||
+ { echo "$0: cannot unlink or rename $dst" >&2
+ (exit 1); exit 1
+ }
+ } &&
+
+ # Now rename the file to the real destination.
+ $doit $mvcmd "$dsttmp" "$dst"
+ }
+ fi || exit 1
+
+ trap '' 0
+ fi
+done
+
+# Local variables:
+# eval: (add-hook 'write-file-hooks 'time-stamp)
+# time-stamp-start: "scriptversion="
+# time-stamp-format: "%:y-%02m-%02d.%02H"
+# time-stamp-time-zone: "UTC"
+# time-stamp-end: "; # UTC"
+# End:
diff --git a/contrib/libyaml/config/ltmain.sh b/contrib/libyaml/config/ltmain.sh
new file mode 100755
index 0000000..7ed280b
--- /dev/null
+++ b/contrib/libyaml/config/ltmain.sh
@@ -0,0 +1,8413 @@
+# Generated from ltmain.m4sh.
+
+# ltmain.sh (GNU libtool) 2.2.6b
+# Written by Gordon Matzigkeit <gord@gnu.ai.mit.edu>, 1996
+
+# Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2003, 2004, 2005, 2006, 2007 2008 Free Software Foundation, Inc.
+# This is free software; see the source for copying conditions. There is NO
+# warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+
+# GNU Libtool 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.
+#
+# As a special exception to the GNU General Public License,
+# if you distribute this file as part of a program or library that
+# is built using GNU Libtool, you may include this file under the
+# same distribution terms that you use for the rest of that program.
+#
+# GNU Libtool 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 GNU Libtool; see the file COPYING. If not, a copy
+# can be downloaded from http://www.gnu.org/licenses/gpl.html,
+# or obtained by writing to the Free Software Foundation, Inc.,
+# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+
+# Usage: $progname [OPTION]... [MODE-ARG]...
+#
+# Provide generalized library-building support services.
+#
+# --config show all configuration variables
+# --debug enable verbose shell tracing
+# -n, --dry-run display commands without modifying any files
+# --features display basic configuration information and exit
+# --mode=MODE use operation mode MODE
+# --preserve-dup-deps don't remove duplicate dependency libraries
+# --quiet, --silent don't print informational messages
+# --tag=TAG use configuration variables from tag TAG
+# -v, --verbose print informational messages (default)
+# --version print version information
+# -h, --help print short or long help message
+#
+# MODE must be one of the following:
+#
+# clean remove files from the build directory
+# compile compile a source file into a libtool object
+# execute automatically set library path, then run a program
+# finish complete the installation of libtool libraries
+# install install libraries or executables
+# link create a library or an executable
+# uninstall remove libraries from an installed directory
+#
+# MODE-ARGS vary depending on the MODE.
+# Try `$progname --help --mode=MODE' for a more detailed description of MODE.
+#
+# When reporting a bug, please describe a test case to reproduce it and
+# include the following information:
+#
+# host-triplet: $host
+# shell: $SHELL
+# compiler: $LTCC
+# compiler flags: $LTCFLAGS
+# linker: $LD (gnu? $with_gnu_ld)
+# $progname: (GNU libtool) 2.2.6b Debian-2.2.6b-2ubuntu1
+# automake: $automake_version
+# autoconf: $autoconf_version
+#
+# Report bugs to <bug-libtool@gnu.org>.
+
+PROGRAM=ltmain.sh
+PACKAGE=libtool
+VERSION="2.2.6b Debian-2.2.6b-2ubuntu1"
+TIMESTAMP=""
+package_revision=1.3017
+
+# Be Bourne compatible
+if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then
+ emulate sh
+ NULLCMD=:
+ # Zsh 3.x and 4.x performs word splitting on ${1+"$@"}, which
+ # is contrary to our usage. Disable this feature.
+ alias -g '${1+"$@"}'='"$@"'
+ setopt NO_GLOB_SUBST
+else
+ case `(set -o) 2>/dev/null` in *posix*) set -o posix;; esac
+fi
+BIN_SH=xpg4; export BIN_SH # for Tru64
+DUALCASE=1; export DUALCASE # for MKS sh
+
+# NLS nuisances: We save the old values to restore during execute mode.
+# Only set LANG and LC_ALL to C if already set.
+# These must not be set unconditionally because not all systems understand
+# e.g. LANG=C (notably SCO).
+lt_user_locale=
+lt_safe_locale=
+for lt_var in LANG LANGUAGE LC_ALL LC_CTYPE LC_COLLATE LC_MESSAGES
+do
+ eval "if test \"\${$lt_var+set}\" = set; then
+ save_$lt_var=\$$lt_var
+ $lt_var=C
+ export $lt_var
+ lt_user_locale=\"$lt_var=\\\$save_\$lt_var; \$lt_user_locale\"
+ lt_safe_locale=\"$lt_var=C; \$lt_safe_locale\"
+ fi"
+done
+
+$lt_unset CDPATH
+
+
+
+
+
+: ${CP="cp -f"}
+: ${ECHO="echo"}
+: ${EGREP="/bin/grep -E"}
+: ${FGREP="/bin/grep -F"}
+: ${GREP="/bin/grep"}
+: ${LN_S="ln -s"}
+: ${MAKE="make"}
+: ${MKDIR="mkdir"}
+: ${MV="mv -f"}
+: ${RM="rm -f"}
+: ${SED="/bin/sed"}
+: ${SHELL="${CONFIG_SHELL-/bin/sh}"}
+: ${Xsed="$SED -e 1s/^X//"}
+
+# Global variables:
+EXIT_SUCCESS=0
+EXIT_FAILURE=1
+EXIT_MISMATCH=63 # $? = 63 is used to indicate version mismatch to missing.
+EXIT_SKIP=77 # $? = 77 is used to indicate a skipped test to automake.
+
+exit_status=$EXIT_SUCCESS
+
+# Make sure IFS has a sensible default
+lt_nl='
+'
+IFS=" $lt_nl"
+
+dirname="s,/[^/]*$,,"
+basename="s,^.*/,,"
+
+# func_dirname_and_basename file append nondir_replacement
+# perform func_basename and func_dirname in a single function
+# call:
+# dirname: Compute the dirname of FILE. If nonempty,
+# add APPEND to the result, otherwise set result
+# to NONDIR_REPLACEMENT.
+# value returned in "$func_dirname_result"
+# basename: Compute filename of FILE.
+# value retuned in "$func_basename_result"
+# Implementation must be kept synchronized with func_dirname
+# and func_basename. For efficiency, we do not delegate to
+# those functions but instead duplicate the functionality here.
+func_dirname_and_basename ()
+{
+ # Extract subdirectory from the argument.
+ func_dirname_result=`$ECHO "X${1}" | $Xsed -e "$dirname"`
+ if test "X$func_dirname_result" = "X${1}"; then
+ func_dirname_result="${3}"
+ else
+ func_dirname_result="$func_dirname_result${2}"
+ fi
+ func_basename_result=`$ECHO "X${1}" | $Xsed -e "$basename"`
+}
+
+# Generated shell functions inserted here.
+
+# Work around backward compatibility issue on IRIX 6.5. On IRIX 6.4+, sh
+# is ksh but when the shell is invoked as "sh" and the current value of
+# the _XPG environment variable is not equal to 1 (one), the special
+# positional parameter $0, within a function call, is the name of the
+# function.
+progpath="$0"
+
+# The name of this program:
+# In the unlikely event $progname began with a '-', it would play havoc with
+# func_echo (imagine progname=-n), so we prepend ./ in that case:
+func_dirname_and_basename "$progpath"
+progname=$func_basename_result
+case $progname in
+ -*) progname=./$progname ;;
+esac
+
+# Make sure we have an absolute path for reexecution:
+case $progpath in
+ [\\/]*|[A-Za-z]:\\*) ;;
+ *[\\/]*)
+ progdir=$func_dirname_result
+ progdir=`cd "$progdir" && pwd`
+ progpath="$progdir/$progname"
+ ;;
+ *)
+ save_IFS="$IFS"
+ IFS=:
+ for progdir in $PATH; do
+ IFS="$save_IFS"
+ test -x "$progdir/$progname" && break
+ done
+ IFS="$save_IFS"
+ test -n "$progdir" || progdir=`pwd`
+ progpath="$progdir/$progname"
+ ;;
+esac
+
+# Sed substitution that helps us do robust quoting. It backslashifies
+# metacharacters that are still active within double-quoted strings.
+Xsed="${SED}"' -e 1s/^X//'
+sed_quote_subst='s/\([`"$\\]\)/\\\1/g'
+
+# Same as above, but do not quote variable references.
+double_quote_subst='s/\(["`\\]\)/\\\1/g'
+
+# Re-`\' parameter expansions in output of double_quote_subst that were
+# `\'-ed in input to the same. If an odd number of `\' preceded a '$'
+# in input to double_quote_subst, that '$' was protected from expansion.
+# Since each input `\' is now two `\'s, look for any number of runs of
+# four `\'s followed by two `\'s and then a '$'. `\' that '$'.
+bs='\\'
+bs2='\\\\'
+bs4='\\\\\\\\'
+dollar='\$'
+sed_double_backslash="\
+ s/$bs4/&\\
+/g
+ s/^$bs2$dollar/$bs&/
+ s/\\([^$bs]\\)$bs2$dollar/\\1$bs2$bs$dollar/g
+ s/\n//g"
+
+# Standard options:
+opt_dry_run=false
+opt_help=false
+opt_quiet=false
+opt_verbose=false
+opt_warning=:
+
+# func_echo arg...
+# Echo program name prefixed message, along with the current mode
+# name if it has been set yet.
+func_echo ()
+{
+ $ECHO "$progname${mode+: }$mode: $*"
+}
+
+# func_verbose arg...
+# Echo program name prefixed message in verbose mode only.
+func_verbose ()
+{
+ $opt_verbose && func_echo ${1+"$@"}
+
+ # A bug in bash halts the script if the last line of a function
+ # fails when set -e is in force, so we need another command to
+ # work around that:
+ :
+}
+
+# func_error arg...
+# Echo program name prefixed message to standard error.
+func_error ()
+{
+ $ECHO "$progname${mode+: }$mode: "${1+"$@"} 1>&2
+}
+
+# func_warning arg...
+# Echo program name prefixed warning message to standard error.
+func_warning ()
+{
+ $opt_warning && $ECHO "$progname${mode+: }$mode: warning: "${1+"$@"} 1>&2
+
+ # bash bug again:
+ :
+}
+
+# func_fatal_error arg...
+# Echo program name prefixed message to standard error, and exit.
+func_fatal_error ()
+{
+ func_error ${1+"$@"}
+ exit $EXIT_FAILURE
+}
+
+# func_fatal_help arg...
+# Echo program name prefixed message to standard error, followed by
+# a help hint, and exit.
+func_fatal_help ()
+{
+ func_error ${1+"$@"}
+ func_fatal_error "$help"
+}
+help="Try \`$progname --help' for more information." ## default
+
+
+# func_grep expression filename
+# Check whether EXPRESSION matches any line of FILENAME, without output.
+func_grep ()
+{
+ $GREP "$1" "$2" >/dev/null 2>&1
+}
+
+
+# func_mkdir_p directory-path
+# Make sure the entire path to DIRECTORY-PATH is available.
+func_mkdir_p ()
+{
+ my_directory_path="$1"
+ my_dir_list=
+
+ if test -n "$my_directory_path" && test "$opt_dry_run" != ":"; then
+
+ # Protect directory names starting with `-'
+ case $my_directory_path in
+ -*) my_directory_path="./$my_directory_path" ;;
+ esac
+
+ # While some portion of DIR does not yet exist...
+ while test ! -d "$my_directory_path"; do
+ # ...make a list in topmost first order. Use a colon delimited
+ # list incase some portion of path contains whitespace.
+ my_dir_list="$my_directory_path:$my_dir_list"
+
+ # If the last portion added has no slash in it, the list is done
+ case $my_directory_path in */*) ;; *) break ;; esac
+
+ # ...otherwise throw away the child directory and loop
+ my_directory_path=`$ECHO "X$my_directory_path" | $Xsed -e "$dirname"`
+ done
+ my_dir_list=`$ECHO "X$my_dir_list" | $Xsed -e 's,:*$,,'`
+
+ save_mkdir_p_IFS="$IFS"; IFS=':'
+ for my_dir in $my_dir_list; do
+ IFS="$save_mkdir_p_IFS"
+ # mkdir can fail with a `File exist' error if two processes
+ # try to create one of the directories concurrently. Don't
+ # stop in that case!
+ $MKDIR "$my_dir" 2>/dev/null || :
+ done
+ IFS="$save_mkdir_p_IFS"
+
+ # Bail out if we (or some other process) failed to create a directory.
+ test -d "$my_directory_path" || \
+ func_fatal_error "Failed to create \`$1'"
+ fi
+}
+
+
+# func_mktempdir [string]
+# Make a temporary directory that won't clash with other running
+# libtool processes, and avoids race conditions if possible. If
+# given, STRING is the basename for that directory.
+func_mktempdir ()
+{
+ my_template="${TMPDIR-/tmp}/${1-$progname}"
+
+ if test "$opt_dry_run" = ":"; then
+ # Return a directory name, but don't create it in dry-run mode
+ my_tmpdir="${my_template}-$$"
+ else
+
+ # If mktemp works, use that first and foremost
+ my_tmpdir=`mktemp -d "${my_template}-XXXXXXXX" 2>/dev/null`
+
+ if test ! -d "$my_tmpdir"; then
+ # Failing that, at least try and use $RANDOM to avoid a race
+ my_tmpdir="${my_template}-${RANDOM-0}$$"
+
+ save_mktempdir_umask=`umask`
+ umask 0077
+ $MKDIR "$my_tmpdir"
+ umask $save_mktempdir_umask
+ fi
+
+ # If we're not in dry-run mode, bomb out on failure
+ test -d "$my_tmpdir" || \
+ func_fatal_error "cannot create temporary directory \`$my_tmpdir'"
+ fi
+
+ $ECHO "X$my_tmpdir" | $Xsed
+}
+
+
+# func_quote_for_eval arg
+# Aesthetically quote ARG to be evaled later.
+# This function returns two values: FUNC_QUOTE_FOR_EVAL_RESULT
+# is double-quoted, suitable for a subsequent eval, whereas
+# FUNC_QUOTE_FOR_EVAL_UNQUOTED_RESULT has merely all characters
+# which are still active within double quotes backslashified.
+func_quote_for_eval ()
+{
+ case $1 in
+ *[\\\`\"\$]*)
+ func_quote_for_eval_unquoted_result=`$ECHO "X$1" | $Xsed -e "$sed_quote_subst"` ;;
+ *)
+ func_quote_for_eval_unquoted_result="$1" ;;
+ esac
+
+ case $func_quote_for_eval_unquoted_result in
+ # Double-quote args containing shell metacharacters to delay
+ # word splitting, command substitution and and variable
+ # expansion for a subsequent eval.
+ # Many Bourne shells cannot handle close brackets correctly
+ # in scan sets, so we specify it separately.
+ *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \ ]*|*]*|"")
+ func_quote_for_eval_result="\"$func_quote_for_eval_unquoted_result\""
+ ;;
+ *)
+ func_quote_for_eval_result="$func_quote_for_eval_unquoted_result"
+ esac
+}
+
+
+# func_quote_for_expand arg
+# Aesthetically quote ARG to be evaled later; same as above,
+# but do not quote variable references.
+func_quote_for_expand ()
+{
+ case $1 in
+ *[\\\`\"]*)
+ my_arg=`$ECHO "X$1" | $Xsed \
+ -e "$double_quote_subst" -e "$sed_double_backslash"` ;;
+ *)
+ my_arg="$1" ;;
+ esac
+
+ case $my_arg in
+ # Double-quote args containing shell metacharacters to delay
+ # word splitting and command substitution for a subsequent eval.
+ # Many Bourne shells cannot handle close brackets correctly
+ # in scan sets, so we specify it separately.
+ *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \ ]*|*]*|"")
+ my_arg="\"$my_arg\""
+ ;;
+ esac
+
+ func_quote_for_expand_result="$my_arg"
+}
+
+
+# func_show_eval cmd [fail_exp]
+# Unless opt_silent is true, then output CMD. Then, if opt_dryrun is
+# not true, evaluate CMD. If the evaluation of CMD fails, and FAIL_EXP
+# is given, then evaluate it.
+func_show_eval ()
+{
+ my_cmd="$1"
+ my_fail_exp="${2-:}"
+
+ ${opt_silent-false} || {
+ func_quote_for_expand "$my_cmd"
+ eval "func_echo $func_quote_for_expand_result"
+ }
+
+ if ${opt_dry_run-false}; then :; else
+ eval "$my_cmd"
+ my_status=$?
+ if test "$my_status" -eq 0; then :; else
+ eval "(exit $my_status); $my_fail_exp"
+ fi
+ fi
+}
+
+
+# func_show_eval_locale cmd [fail_exp]
+# Unless opt_silent is true, then output CMD. Then, if opt_dryrun is
+# not true, evaluate CMD. If the evaluation of CMD fails, and FAIL_EXP
+# is given, then evaluate it. Use the saved locale for evaluation.
+func_show_eval_locale ()
+{
+ my_cmd="$1"
+ my_fail_exp="${2-:}"
+
+ ${opt_silent-false} || {
+ func_quote_for_expand "$my_cmd"
+ eval "func_echo $func_quote_for_expand_result"
+ }
+
+ if ${opt_dry_run-false}; then :; else
+ eval "$lt_user_locale
+ $my_cmd"
+ my_status=$?
+ eval "$lt_safe_locale"
+ if test "$my_status" -eq 0; then :; else
+ eval "(exit $my_status); $my_fail_exp"
+ fi
+ fi
+}
+
+
+
+
+
+# func_version
+# Echo version message to standard output and exit.
+func_version ()
+{
+ $SED -n '/^# '$PROGRAM' (GNU /,/# warranty; / {
+ s/^# //
+ s/^# *$//
+ s/\((C)\)[ 0-9,-]*\( [1-9][0-9]*\)/\1\2/
+ p
+ }' < "$progpath"
+ exit $?
+}
+
+# func_usage
+# Echo short help message to standard output and exit.
+func_usage ()
+{
+ $SED -n '/^# Usage:/,/# -h/ {
+ s/^# //
+ s/^# *$//
+ s/\$progname/'$progname'/
+ p
+ }' < "$progpath"
+ $ECHO
+ $ECHO "run \`$progname --help | more' for full usage"
+ exit $?
+}
+
+# func_help
+# Echo long help message to standard output and exit.
+func_help ()
+{
+ $SED -n '/^# Usage:/,/# Report bugs to/ {
+ s/^# //
+ s/^# *$//
+ s*\$progname*'$progname'*
+ s*\$host*'"$host"'*
+ s*\$SHELL*'"$SHELL"'*
+ s*\$LTCC*'"$LTCC"'*
+ s*\$LTCFLAGS*'"$LTCFLAGS"'*
+ s*\$LD*'"$LD"'*
+ s/\$with_gnu_ld/'"$with_gnu_ld"'/
+ s/\$automake_version/'"`(automake --version) 2>/dev/null |$SED 1q`"'/
+ s/\$autoconf_version/'"`(autoconf --version) 2>/dev/null |$SED 1q`"'/
+ p
+ }' < "$progpath"
+ exit $?
+}
+
+# func_missing_arg argname
+# Echo program name prefixed message to standard error and set global
+# exit_cmd.
+func_missing_arg ()
+{
+ func_error "missing argument for $1"
+ exit_cmd=exit
+}
+
+exit_cmd=:
+
+
+
+
+
+# Check that we have a working $ECHO.
+if test "X$1" = X--no-reexec; then
+ # Discard the --no-reexec flag, and continue.
+ shift
+elif test "X$1" = X--fallback-echo; then
+ # Avoid inline document here, it may be left over
+ :
+elif test "X`{ $ECHO '\t'; } 2>/dev/null`" = 'X\t'; then
+ # Yippee, $ECHO works!
+ :
+else
+ # Restart under the correct shell, and then maybe $ECHO will work.
+ exec $SHELL "$progpath" --no-reexec ${1+"$@"}
+fi
+
+if test "X$1" = X--fallback-echo; then
+ # used as fallback echo
+ shift
+ cat <<EOF
+$*
+EOF
+ exit $EXIT_SUCCESS
+fi
+
+magic="%%%MAGIC variable%%%"
+magic_exe="%%%MAGIC EXE variable%%%"
+
+# Global variables.
+# $mode is unset
+nonopt=
+execute_dlfiles=
+preserve_args=
+lo2o="s/\\.lo\$/.${objext}/"
+o2lo="s/\\.${objext}\$/.lo/"
+extracted_archives=
+extracted_serial=0
+
+opt_dry_run=false
+opt_duplicate_deps=false
+opt_silent=false
+opt_debug=:
+
+# If this variable is set in any of the actions, the command in it
+# will be execed at the end. This prevents here-documents from being
+# left over by shells.
+exec_cmd=
+
+# func_fatal_configuration arg...
+# Echo program name prefixed message to standard error, followed by
+# a configuration failure hint, and exit.
+func_fatal_configuration ()
+{
+ func_error ${1+"$@"}
+ func_error "See the $PACKAGE documentation for more information."
+ func_fatal_error "Fatal configuration error."
+}
+
+
+# func_config
+# Display the configuration for all the tags in this script.
+func_config ()
+{
+ re_begincf='^# ### BEGIN LIBTOOL'
+ re_endcf='^# ### END LIBTOOL'
+
+ # Default configuration.
+ $SED "1,/$re_begincf CONFIG/d;/$re_endcf CONFIG/,\$d" < "$progpath"
+
+ # Now print the configurations for the tags.
+ for tagname in $taglist; do
+ $SED -n "/$re_begincf TAG CONFIG: $tagname\$/,/$re_endcf TAG CONFIG: $tagname\$/p" < "$progpath"
+ done
+
+ exit $?
+}
+
+# func_features
+# Display the features supported by this script.
+func_features ()
+{
+ $ECHO "host: $host"
+ if test "$build_libtool_libs" = yes; then
+ $ECHO "enable shared libraries"
+ else
+ $ECHO "disable shared libraries"
+ fi
+ if test "$build_old_libs" = yes; then
+ $ECHO "enable static libraries"
+ else
+ $ECHO "disable static libraries"
+ fi
+
+ exit $?
+}
+
+# func_enable_tag tagname
+# Verify that TAGNAME is valid, and either flag an error and exit, or
+# enable the TAGNAME tag. We also add TAGNAME to the global $taglist
+# variable here.
+func_enable_tag ()
+{
+ # Global variable:
+ tagname="$1"
+
+ re_begincf="^# ### BEGIN LIBTOOL TAG CONFIG: $tagname\$"
+ re_endcf="^# ### END LIBTOOL TAG CONFIG: $tagname\$"
+ sed_extractcf="/$re_begincf/,/$re_endcf/p"
+
+ # Validate tagname.
+ case $tagname in
+ *[!-_A-Za-z0-9,/]*)
+ func_fatal_error "invalid tag name: $tagname"
+ ;;
+ esac
+
+ # Don't test for the "default" C tag, as we know it's
+ # there but not specially marked.
+ case $tagname in
+ CC) ;;
+ *)
+ if $GREP "$re_begincf" "$progpath" >/dev/null 2>&1; then
+ taglist="$taglist $tagname"
+
+ # Evaluate the configuration. Be careful to quote the path
+ # and the sed script, to avoid splitting on whitespace, but
+ # also don't use non-portable quotes within backquotes within
+ # quotes we have to do it in 2 steps:
+ extractedcf=`$SED -n -e "$sed_extractcf" < "$progpath"`
+ eval "$extractedcf"
+ else
+ func_error "ignoring unknown tag $tagname"
+ fi
+ ;;
+ esac
+}
+
+# Parse options once, thoroughly. This comes as soon as possible in
+# the script to make things like `libtool --version' happen quickly.
+{
+
+ # Shorthand for --mode=foo, only valid as the first argument
+ case $1 in
+ clean|clea|cle|cl)
+ shift; set dummy --mode clean ${1+"$@"}; shift
+ ;;
+ compile|compil|compi|comp|com|co|c)
+ shift; set dummy --mode compile ${1+"$@"}; shift
+ ;;
+ execute|execut|execu|exec|exe|ex|e)
+ shift; set dummy --mode execute ${1+"$@"}; shift
+ ;;
+ finish|finis|fini|fin|fi|f)
+ shift; set dummy --mode finish ${1+"$@"}; shift
+ ;;
+ install|instal|insta|inst|ins|in|i)
+ shift; set dummy --mode install ${1+"$@"}; shift
+ ;;
+ link|lin|li|l)
+ shift; set dummy --mode link ${1+"$@"}; shift
+ ;;
+ uninstall|uninstal|uninsta|uninst|unins|unin|uni|un|u)
+ shift; set dummy --mode uninstall ${1+"$@"}; shift
+ ;;
+ esac
+
+ # Parse non-mode specific arguments:
+ while test "$#" -gt 0; do
+ opt="$1"
+ shift
+
+ case $opt in
+ --config) func_config ;;
+
+ --debug) preserve_args="$preserve_args $opt"
+ func_echo "enabling shell trace mode"
+ opt_debug='set -x'
+ $opt_debug
+ ;;
+
+ -dlopen) test "$#" -eq 0 && func_missing_arg "$opt" && break
+ execute_dlfiles="$execute_dlfiles $1"
+ shift
+ ;;
+
+ --dry-run | -n) opt_dry_run=: ;;
+ --features) func_features ;;
+ --finish) mode="finish" ;;
+
+ --mode) test "$#" -eq 0 && func_missing_arg "$opt" && break
+ case $1 in
+ # Valid mode arguments:
+ clean) ;;
+ compile) ;;
+ execute) ;;
+ finish) ;;
+ install) ;;
+ link) ;;
+ relink) ;;
+ uninstall) ;;
+
+ # Catch anything else as an error
+ *) func_error "invalid argument for $opt"
+ exit_cmd=exit
+ break
+ ;;
+ esac
+
+ mode="$1"
+ shift
+ ;;
+
+ --preserve-dup-deps)
+ opt_duplicate_deps=: ;;
+
+ --quiet|--silent) preserve_args="$preserve_args $opt"
+ opt_silent=:
+ ;;
+
+ --verbose| -v) preserve_args="$preserve_args $opt"
+ opt_silent=false
+ ;;
+
+ --tag) test "$#" -eq 0 && func_missing_arg "$opt" && break
+ preserve_args="$preserve_args $opt $1"
+ func_enable_tag "$1" # tagname is set here
+ shift
+ ;;
+
+ # Separate optargs to long options:
+ -dlopen=*|--mode=*|--tag=*)
+ func_opt_split "$opt"
+ set dummy "$func_opt_split_opt" "$func_opt_split_arg" ${1+"$@"}
+ shift
+ ;;
+
+ -\?|-h) func_usage ;;
+ --help) opt_help=: ;;
+ --version) func_version ;;
+
+ -*) func_fatal_help "unrecognized option \`$opt'" ;;
+
+ *) nonopt="$opt"
+ break
+ ;;
+ esac
+ done
+
+
+ case $host in
+ *cygwin* | *mingw* | *pw32* | *cegcc*)
+ # don't eliminate duplications in $postdeps and $predeps
+ opt_duplicate_compiler_generated_deps=:
+ ;;
+ *)
+ opt_duplicate_compiler_generated_deps=$opt_duplicate_deps
+ ;;
+ esac
+
+ # Having warned about all mis-specified options, bail out if
+ # anything was wrong.
+ $exit_cmd $EXIT_FAILURE
+}
+
+# func_check_version_match
+# Ensure that we are using m4 macros, and libtool script from the same
+# release of libtool.
+func_check_version_match ()
+{
+ if test "$package_revision" != "$macro_revision"; then
+ if test "$VERSION" != "$macro_version"; then
+ if test -z "$macro_version"; then
+ cat >&2 <<_LT_EOF
+$progname: Version mismatch error. This is $PACKAGE $VERSION, but the
+$progname: definition of this LT_INIT comes from an older release.
+$progname: You should recreate aclocal.m4 with macros from $PACKAGE $VERSION
+$progname: and run autoconf again.
+_LT_EOF
+ else
+ cat >&2 <<_LT_EOF
+$progname: Version mismatch error. This is $PACKAGE $VERSION, but the
+$progname: definition of this LT_INIT comes from $PACKAGE $macro_version.
+$progname: You should recreate aclocal.m4 with macros from $PACKAGE $VERSION
+$progname: and run autoconf again.
+_LT_EOF
+ fi
+ else
+ cat >&2 <<_LT_EOF
+$progname: Version mismatch error. This is $PACKAGE $VERSION, revision $package_revision,
+$progname: but the definition of this LT_INIT comes from revision $macro_revision.
+$progname: You should recreate aclocal.m4 with macros from revision $package_revision
+$progname: of $PACKAGE $VERSION and run autoconf again.
+_LT_EOF
+ fi
+
+ exit $EXIT_MISMATCH
+ fi
+}
+
+
+## ----------- ##
+## Main. ##
+## ----------- ##
+
+$opt_help || {
+ # Sanity checks first:
+ func_check_version_match
+
+ if test "$build_libtool_libs" != yes && test "$build_old_libs" != yes; then
+ func_fatal_configuration "not configured to build any kind of library"
+ fi
+
+ test -z "$mode" && func_fatal_error "error: you must specify a MODE."
+
+
+ # Darwin sucks
+ eval std_shrext=\"$shrext_cmds\"
+
+
+ # Only execute mode is allowed to have -dlopen flags.
+ if test -n "$execute_dlfiles" && test "$mode" != execute; then
+ func_error "unrecognized option \`-dlopen'"
+ $ECHO "$help" 1>&2
+ exit $EXIT_FAILURE
+ fi
+
+ # Change the help message to a mode-specific one.
+ generic_help="$help"
+ help="Try \`$progname --help --mode=$mode' for more information."
+}
+
+
+# func_lalib_p file
+# True iff FILE is a libtool `.la' library or `.lo' object file.
+# This function is only a basic sanity check; it will hardly flush out
+# determined imposters.
+func_lalib_p ()
+{
+ test -f "$1" &&
+ $SED -e 4q "$1" 2>/dev/null \
+ | $GREP "^# Generated by .*$PACKAGE" > /dev/null 2>&1
+}
+
+# func_lalib_unsafe_p file
+# True iff FILE is a libtool `.la' library or `.lo' object file.
+# This function implements the same check as func_lalib_p without
+# resorting to external programs. To this end, it redirects stdin and
+# closes it afterwards, without saving the original file descriptor.
+# As a safety measure, use it only where a negative result would be
+# fatal anyway. Works if `file' does not exist.
+func_lalib_unsafe_p ()
+{
+ lalib_p=no
+ if test -f "$1" && test -r "$1" && exec 5<&0 <"$1"; then
+ for lalib_p_l in 1 2 3 4
+ do
+ read lalib_p_line
+ case "$lalib_p_line" in
+ \#\ Generated\ by\ *$PACKAGE* ) lalib_p=yes; break;;
+ esac
+ done
+ exec 0<&5 5<&-
+ fi
+ test "$lalib_p" = yes
+}
+
+# func_ltwrapper_script_p file
+# True iff FILE is a libtool wrapper script
+# This function is only a basic sanity check; it will hardly flush out
+# determined imposters.
+func_ltwrapper_script_p ()
+{
+ func_lalib_p "$1"
+}
+
+# func_ltwrapper_executable_p file
+# True iff FILE is a libtool wrapper executable
+# This function is only a basic sanity check; it will hardly flush out
+# determined imposters.
+func_ltwrapper_executable_p ()
+{
+ func_ltwrapper_exec_suffix=
+ case $1 in
+ *.exe) ;;
+ *) func_ltwrapper_exec_suffix=.exe ;;
+ esac
+ $GREP "$magic_exe" "$1$func_ltwrapper_exec_suffix" >/dev/null 2>&1
+}
+
+# func_ltwrapper_scriptname file
+# Assumes file is an ltwrapper_executable
+# uses $file to determine the appropriate filename for a
+# temporary ltwrapper_script.
+func_ltwrapper_scriptname ()
+{
+ func_ltwrapper_scriptname_result=""
+ if func_ltwrapper_executable_p "$1"; then
+ func_dirname_and_basename "$1" "" "."
+ func_stripname '' '.exe' "$func_basename_result"
+ func_ltwrapper_scriptname_result="$func_dirname_result/$objdir/${func_stripname_result}_ltshwrapper"
+ fi
+}
+
+# func_ltwrapper_p file
+# True iff FILE is a libtool wrapper script or wrapper executable
+# This function is only a basic sanity check; it will hardly flush out
+# determined imposters.
+func_ltwrapper_p ()
+{
+ func_ltwrapper_script_p "$1" || func_ltwrapper_executable_p "$1"
+}
+
+
+# func_execute_cmds commands fail_cmd
+# Execute tilde-delimited COMMANDS.
+# If FAIL_CMD is given, eval that upon failure.
+# FAIL_CMD may read-access the current command in variable CMD!
+func_execute_cmds ()
+{
+ $opt_debug
+ save_ifs=$IFS; IFS='~'
+ for cmd in $1; do
+ IFS=$save_ifs
+ eval cmd=\"$cmd\"
+ func_show_eval "$cmd" "${2-:}"
+ done
+ IFS=$save_ifs
+}
+
+
+# func_source file
+# Source FILE, adding directory component if necessary.
+# Note that it is not necessary on cygwin/mingw to append a dot to
+# FILE even if both FILE and FILE.exe exist: automatic-append-.exe
+# behavior happens only for exec(3), not for open(2)! Also, sourcing
+# `FILE.' does not work on cygwin managed mounts.
+func_source ()
+{
+ $opt_debug
+ case $1 in
+ */* | *\\*) . "$1" ;;
+ *) . "./$1" ;;
+ esac
+}
+
+
+# func_infer_tag arg
+# Infer tagged configuration to use if any are available and
+# if one wasn't chosen via the "--tag" command line option.
+# Only attempt this if the compiler in the base compile
+# command doesn't match the default compiler.
+# arg is usually of the form 'gcc ...'
+func_infer_tag ()
+{
+ $opt_debug
+ if test -n "$available_tags" && test -z "$tagname"; then
+ CC_quoted=
+ for arg in $CC; do
+ func_quote_for_eval "$arg"
+ CC_quoted="$CC_quoted $func_quote_for_eval_result"
+ done
+ case $@ in
+ # Blanks in the command may have been stripped by the calling shell,
+ # but not from the CC environment variable when configure was run.
+ " $CC "* | "$CC "* | " `$ECHO $CC` "* | "`$ECHO $CC` "* | " $CC_quoted"* | "$CC_quoted "* | " `$ECHO $CC_quoted` "* | "`$ECHO $CC_quoted` "*) ;;
+ # Blanks at the start of $base_compile will cause this to fail
+ # if we don't check for them as well.
+ *)
+ for z in $available_tags; do
+ if $GREP "^# ### BEGIN LIBTOOL TAG CONFIG: $z$" < "$progpath" > /dev/null; then
+ # Evaluate the configuration.
+ eval "`${SED} -n -e '/^# ### BEGIN LIBTOOL TAG CONFIG: '$z'$/,/^# ### END LIBTOOL TAG CONFIG: '$z'$/p' < $progpath`"
+ CC_quoted=
+ for arg in $CC; do
+ # Double-quote args containing other shell metacharacters.
+ func_quote_for_eval "$arg"
+ CC_quoted="$CC_quoted $func_quote_for_eval_result"
+ done
+ case "$@ " in
+ " $CC "* | "$CC "* | " `$ECHO $CC` "* | "`$ECHO $CC` "* | " $CC_quoted"* | "$CC_quoted "* | " `$ECHO $CC_quoted` "* | "`$ECHO $CC_quoted` "*)
+ # The compiler in the base compile command matches
+ # the one in the tagged configuration.
+ # Assume this is the tagged configuration we want.
+ tagname=$z
+ break
+ ;;
+ esac
+ fi
+ done
+ # If $tagname still isn't set, then no tagged configuration
+ # was found and let the user know that the "--tag" command
+ # line option must be used.
+ if test -z "$tagname"; then
+ func_echo "unable to infer tagged configuration"
+ func_fatal_error "specify a tag with \`--tag'"
+# else
+# func_verbose "using $tagname tagged configuration"
+ fi
+ ;;
+ esac
+ fi
+}
+
+
+
+# func_write_libtool_object output_name pic_name nonpic_name
+# Create a libtool object file (analogous to a ".la" file),
+# but don't create it if we're doing a dry run.
+func_write_libtool_object ()
+{
+ write_libobj=${1}
+ if test "$build_libtool_libs" = yes; then
+ write_lobj=\'${2}\'
+ else
+ write_lobj=none
+ fi
+
+ if test "$build_old_libs" = yes; then
+ write_oldobj=\'${3}\'
+ else
+ write_oldobj=none
+ fi
+
+ $opt_dry_run || {
+ cat >${write_libobj}T <<EOF
+# $write_libobj - a libtool object file
+# Generated by $PROGRAM (GNU $PACKAGE$TIMESTAMP) $VERSION
+#
+# Please DO NOT delete this file!
+# It is necessary for linking the library.
+
+# Name of the PIC object.
+pic_object=$write_lobj
+
+# Name of the non-PIC object
+non_pic_object=$write_oldobj
+
+EOF
+ $MV "${write_libobj}T" "${write_libobj}"
+ }
+}
+
+# func_mode_compile arg...
+func_mode_compile ()
+{
+ $opt_debug
+ # Get the compilation command and the source file.
+ base_compile=
+ srcfile="$nonopt" # always keep a non-empty value in "srcfile"
+ suppress_opt=yes
+ suppress_output=
+ arg_mode=normal
+ libobj=
+ later=
+ pie_flag=
+
+ for arg
+ do
+ case $arg_mode in
+ arg )
+ # do not "continue". Instead, add this to base_compile
+ lastarg="$arg"
+ arg_mode=normal
+ ;;
+
+ target )
+ libobj="$arg"
+ arg_mode=normal
+ continue
+ ;;
+
+ normal )
+ # Accept any command-line options.
+ case $arg in
+ -o)
+ test -n "$libobj" && \
+ func_fatal_error "you cannot specify \`-o' more than once"
+ arg_mode=target
+ continue
+ ;;
+
+ -pie | -fpie | -fPIE)
+ pie_flag="$pie_flag $arg"
+ continue
+ ;;
+
+ -shared | -static | -prefer-pic | -prefer-non-pic)
+ later="$later $arg"
+ continue
+ ;;
+
+ -no-suppress)
+ suppress_opt=no
+ continue
+ ;;
+
+ -Xcompiler)
+ arg_mode=arg # the next one goes into the "base_compile" arg list
+ continue # The current "srcfile" will either be retained or
+ ;; # replaced later. I would guess that would be a bug.
+
+ -Wc,*)
+ func_stripname '-Wc,' '' "$arg"
+ args=$func_stripname_result
+ lastarg=
+ save_ifs="$IFS"; IFS=','
+ for arg in $args; do
+ IFS="$save_ifs"
+ func_quote_for_eval "$arg"
+ lastarg="$lastarg $func_quote_for_eval_result"
+ done
+ IFS="$save_ifs"
+ func_stripname ' ' '' "$lastarg"
+ lastarg=$func_stripname_result
+
+ # Add the arguments to base_compile.
+ base_compile="$base_compile $lastarg"
+ continue
+ ;;
+
+ *)
+ # Accept the current argument as the source file.
+ # The previous "srcfile" becomes the current argument.
+ #
+ lastarg="$srcfile"
+ srcfile="$arg"
+ ;;
+ esac # case $arg
+ ;;
+ esac # case $arg_mode
+
+ # Aesthetically quote the previous argument.
+ func_quote_for_eval "$lastarg"
+ base_compile="$base_compile $func_quote_for_eval_result"
+ done # for arg
+
+ case $arg_mode in
+ arg)
+ func_fatal_error "you must specify an argument for -Xcompile"
+ ;;
+ target)
+ func_fatal_error "you must specify a target with \`-o'"
+ ;;
+ *)
+ # Get the name of the library object.
+ test -z "$libobj" && {
+ func_basename "$srcfile"
+ libobj="$func_basename_result"
+ }
+ ;;
+ esac
+
+ # Recognize several different file suffixes.
+ # If the user specifies -o file.o, it is replaced with file.lo
+ case $libobj in
+ *.[cCFSifmso] | \
+ *.ada | *.adb | *.ads | *.asm | \
+ *.c++ | *.cc | *.ii | *.class | *.cpp | *.cxx | \
+ *.[fF][09]? | *.for | *.java | *.obj | *.sx)
+ func_xform "$libobj"
+ libobj=$func_xform_result
+ ;;
+ esac
+
+ case $libobj in
+ *.lo) func_lo2o "$libobj"; obj=$func_lo2o_result ;;
+ *)
+ func_fatal_error "cannot determine name of library object from \`$libobj'"
+ ;;
+ esac
+
+ func_infer_tag $base_compile
+
+ for arg in $later; do
+ case $arg in
+ -shared)
+ test "$build_libtool_libs" != yes && \
+ func_fatal_configuration "can not build a shared library"
+ build_old_libs=no
+ continue
+ ;;
+
+ -static)
+ build_libtool_libs=no
+ build_old_libs=yes
+ continue
+ ;;
+
+ -prefer-pic)
+ pic_mode=yes
+ continue
+ ;;
+
+ -prefer-non-pic)
+ pic_mode=no
+ continue
+ ;;
+ esac
+ done
+
+ func_quote_for_eval "$libobj"
+ test "X$libobj" != "X$func_quote_for_eval_result" \
+ && $ECHO "X$libobj" | $GREP '[]~#^*{};<>?"'"'"' &()|`$[]' \
+ && func_warning "libobj name \`$libobj' may not contain shell special characters."
+ func_dirname_and_basename "$obj" "/" ""
+ objname="$func_basename_result"
+ xdir="$func_dirname_result"
+ lobj=${xdir}$objdir/$objname
+
+ test -z "$base_compile" && \
+ func_fatal_help "you must specify a compilation command"
+
+ # Delete any leftover library objects.
+ if test "$build_old_libs" = yes; then
+ removelist="$obj $lobj $libobj ${libobj}T"
+ else
+ removelist="$lobj $libobj ${libobj}T"
+ fi
+
+ # On Cygwin there's no "real" PIC flag so we must build both object types
+ case $host_os in
+ cygwin* | mingw* | pw32* | os2* | cegcc*)
+ pic_mode=default
+ ;;
+ esac
+ if test "$pic_mode" = no && test "$deplibs_check_method" != pass_all; then
+ # non-PIC code in shared libraries is not supported
+ pic_mode=default
+ fi
+
+ # Calculate the filename of the output object if compiler does
+ # not support -o with -c
+ if test "$compiler_c_o" = no; then
+ output_obj=`$ECHO "X$srcfile" | $Xsed -e 's%^.*/%%' -e 's%\.[^.]*$%%'`.${objext}
+ lockfile="$output_obj.lock"
+ else
+ output_obj=
+ need_locks=no
+ lockfile=
+ fi
+
+ # Lock this critical section if it is needed
+ # We use this script file to make the link, it avoids creating a new file
+ if test "$need_locks" = yes; then
+ until $opt_dry_run || ln "$progpath" "$lockfile" 2>/dev/null; do
+ func_echo "Waiting for $lockfile to be removed"
+ sleep 2
+ done
+ elif test "$need_locks" = warn; then
+ if test -f "$lockfile"; then
+ $ECHO "\
+*** ERROR, $lockfile exists and contains:
+`cat $lockfile 2>/dev/null`
+
+This indicates that another process is trying to use the same
+temporary object file, and libtool could not work around it because
+your compiler does not support \`-c' and \`-o' together. If you
+repeat this compilation, it may succeed, by chance, but you had better
+avoid parallel builds (make -j) in this platform, or get a better
+compiler."
+
+ $opt_dry_run || $RM $removelist
+ exit $EXIT_FAILURE
+ fi
+ removelist="$removelist $output_obj"
+ $ECHO "$srcfile" > "$lockfile"
+ fi
+
+ $opt_dry_run || $RM $removelist
+ removelist="$removelist $lockfile"
+ trap '$opt_dry_run || $RM $removelist; exit $EXIT_FAILURE' 1 2 15
+
+ if test -n "$fix_srcfile_path"; then
+ eval srcfile=\"$fix_srcfile_path\"
+ fi
+ func_quote_for_eval "$srcfile"
+ qsrcfile=$func_quote_for_eval_result
+
+ # Only build a PIC object if we are building libtool libraries.
+ if test "$build_libtool_libs" = yes; then
+ # Without this assignment, base_compile gets emptied.
+ fbsd_hideous_sh_bug=$base_compile
+
+ if test "$pic_mode" != no; then
+ command="$base_compile $qsrcfile $pic_flag"
+ else
+ # Don't build PIC code
+ command="$base_compile $qsrcfile"
+ fi
+
+ func_mkdir_p "$xdir$objdir"
+
+ if test -z "$output_obj"; then
+ # Place PIC objects in $objdir
+ command="$command -o $lobj"
+ fi
+
+ func_show_eval_locale "$command" \
+ 'test -n "$output_obj" && $RM $removelist; exit $EXIT_FAILURE'
+
+ if test "$need_locks" = warn &&
+ test "X`cat $lockfile 2>/dev/null`" != "X$srcfile"; then
+ $ECHO "\
+*** ERROR, $lockfile contains:
+`cat $lockfile 2>/dev/null`
+
+but it should contain:
+$srcfile
+
+This indicates that another process is trying to use the same
+temporary object file, and libtool could not work around it because
+your compiler does not support \`-c' and \`-o' together. If you
+repeat this compilation, it may succeed, by chance, but you had better
+avoid parallel builds (make -j) in this platform, or get a better
+compiler."
+
+ $opt_dry_run || $RM $removelist
+ exit $EXIT_FAILURE
+ fi
+
+ # Just move the object if needed, then go on to compile the next one
+ if test -n "$output_obj" && test "X$output_obj" != "X$lobj"; then
+ func_show_eval '$MV "$output_obj" "$lobj"' \
+ 'error=$?; $opt_dry_run || $RM $removelist; exit $error'
+ fi
+
+ # Allow error messages only from the first compilation.
+ if test "$suppress_opt" = yes; then
+ suppress_output=' >/dev/null 2>&1'
+ fi
+ fi
+
+ # Only build a position-dependent object if we build old libraries.
+ if test "$build_old_libs" = yes; then
+ if test "$pic_mode" != yes; then
+ # Don't build PIC code
+ command="$base_compile $qsrcfile$pie_flag"
+ else
+ command="$base_compile $qsrcfile $pic_flag"
+ fi
+ if test "$compiler_c_o" = yes; then
+ command="$command -o $obj"
+ fi
+
+ # Suppress compiler output if we already did a PIC compilation.
+ command="$command$suppress_output"
+ func_show_eval_locale "$command" \
+ '$opt_dry_run || $RM $removelist; exit $EXIT_FAILURE'
+
+ if test "$need_locks" = warn &&
+ test "X`cat $lockfile 2>/dev/null`" != "X$srcfile"; then
+ $ECHO "\
+*** ERROR, $lockfile contains:
+`cat $lockfile 2>/dev/null`
+
+but it should contain:
+$srcfile
+
+This indicates that another process is trying to use the same
+temporary object file, and libtool could not work around it because
+your compiler does not support \`-c' and \`-o' together. If you
+repeat this compilation, it may succeed, by chance, but you had better
+avoid parallel builds (make -j) in this platform, or get a better
+compiler."
+
+ $opt_dry_run || $RM $removelist
+ exit $EXIT_FAILURE
+ fi
+
+ # Just move the object if needed
+ if test -n "$output_obj" && test "X$output_obj" != "X$obj"; then
+ func_show_eval '$MV "$output_obj" "$obj"' \
+ 'error=$?; $opt_dry_run || $RM $removelist; exit $error'
+ fi
+ fi
+
+ $opt_dry_run || {
+ func_write_libtool_object "$libobj" "$objdir/$objname" "$objname"
+
+ # Unlock the critical section if it was locked
+ if test "$need_locks" != no; then
+ removelist=$lockfile
+ $RM "$lockfile"
+ fi
+ }
+
+ exit $EXIT_SUCCESS
+}
+
+$opt_help || {
+test "$mode" = compile && func_mode_compile ${1+"$@"}
+}
+
+func_mode_help ()
+{
+ # We need to display help for each of the modes.
+ case $mode in
+ "")
+ # Generic help is extracted from the usage comments
+ # at the start of this file.
+ func_help
+ ;;
+
+ clean)
+ $ECHO \
+"Usage: $progname [OPTION]... --mode=clean RM [RM-OPTION]... FILE...
+
+Remove files from the build directory.
+
+RM is the name of the program to use to delete files associated with each FILE
+(typically \`/bin/rm'). RM-OPTIONS are options (such as \`-f') to be passed
+to RM.
+
+If FILE is a libtool library, object or program, all the files associated
+with it are deleted. Otherwise, only FILE itself is deleted using RM."
+ ;;
+
+ compile)
+ $ECHO \
+"Usage: $progname [OPTION]... --mode=compile COMPILE-COMMAND... SOURCEFILE
+
+Compile a source file into a libtool library object.
+
+This mode accepts the following additional options:
+
+ -o OUTPUT-FILE set the output file name to OUTPUT-FILE
+ -no-suppress do not suppress compiler output for multiple passes
+ -prefer-pic try to building PIC objects only
+ -prefer-non-pic try to building non-PIC objects only
+ -shared do not build a \`.o' file suitable for static linking
+ -static only build a \`.o' file suitable for static linking
+
+COMPILE-COMMAND is a command to be used in creating a \`standard' object file
+from the given SOURCEFILE.
+
+The output file name is determined by removing the directory component from
+SOURCEFILE, then substituting the C source code suffix \`.c' with the
+library object suffix, \`.lo'."
+ ;;
+
+ execute)
+ $ECHO \
+"Usage: $progname [OPTION]... --mode=execute COMMAND [ARGS]...
+
+Automatically set library path, then run a program.
+
+This mode accepts the following additional options:
+
+ -dlopen FILE add the directory containing FILE to the library path
+
+This mode sets the library path environment variable according to \`-dlopen'
+flags.
+
+If any of the ARGS are libtool executable wrappers, then they are translated
+into their corresponding uninstalled binary, and any of their required library
+directories are added to the library path.
+
+Then, COMMAND is executed, with ARGS as arguments."
+ ;;
+
+ finish)
+ $ECHO \
+"Usage: $progname [OPTION]... --mode=finish [LIBDIR]...
+
+Complete the installation of libtool libraries.
+
+Each LIBDIR is a directory that contains libtool libraries.
+
+The commands that this mode executes may require superuser privileges. Use
+the \`--dry-run' option if you just want to see what would be executed."
+ ;;
+
+ install)
+ $ECHO \
+"Usage: $progname [OPTION]... --mode=install INSTALL-COMMAND...
+
+Install executables or libraries.
+
+INSTALL-COMMAND is the installation command. The first component should be
+either the \`install' or \`cp' program.
+
+The following components of INSTALL-COMMAND are treated specially:
+
+ -inst-prefix PREFIX-DIR Use PREFIX-DIR as a staging area for installation
+
+The rest of the components are interpreted as arguments to that command (only
+BSD-compatible install options are recognized)."
+ ;;
+
+ link)
+ $ECHO \
+"Usage: $progname [OPTION]... --mode=link LINK-COMMAND...
+
+Link object files or libraries together to form another library, or to
+create an executable program.
+
+LINK-COMMAND is a command using the C compiler that you would use to create
+a program from several object files.
+
+The following components of LINK-COMMAND are treated specially:
+
+ -all-static do not do any dynamic linking at all
+ -avoid-version do not add a version suffix if possible
+ -dlopen FILE \`-dlpreopen' FILE if it cannot be dlopened at runtime
+ -dlpreopen FILE link in FILE and add its symbols to lt_preloaded_symbols
+ -export-dynamic allow symbols from OUTPUT-FILE to be resolved with dlsym(3)
+ -export-symbols SYMFILE
+ try to export only the symbols listed in SYMFILE
+ -export-symbols-regex REGEX
+ try to export only the symbols matching REGEX
+ -LLIBDIR search LIBDIR for required installed libraries
+ -lNAME OUTPUT-FILE requires the installed library libNAME
+ -module build a library that can dlopened
+ -no-fast-install disable the fast-install mode
+ -no-install link a not-installable executable
+ -no-undefined declare that a library does not refer to external symbols
+ -o OUTPUT-FILE create OUTPUT-FILE from the specified objects
+ -objectlist FILE Use a list of object files found in FILE to specify objects
+ -precious-files-regex REGEX
+ don't remove output files matching REGEX
+ -release RELEASE specify package release information
+ -rpath LIBDIR the created library will eventually be installed in LIBDIR
+ -R[ ]LIBDIR add LIBDIR to the runtime path of programs and libraries
+ -shared only do dynamic linking of libtool libraries
+ -shrext SUFFIX override the standard shared library file extension
+ -static do not do any dynamic linking of uninstalled libtool libraries
+ -static-libtool-libs
+ do not do any dynamic linking of libtool libraries
+ -version-info CURRENT[:REVISION[:AGE]]
+ specify library version info [each variable defaults to 0]
+ -weak LIBNAME declare that the target provides the LIBNAME interface
+
+All other options (arguments beginning with \`-') are ignored.
+
+Every other argument is treated as a filename. Files ending in \`.la' are
+treated as uninstalled libtool libraries, other files are standard or library
+object files.
+
+If the OUTPUT-FILE ends in \`.la', then a libtool library is created,
+only library objects (\`.lo' files) may be specified, and \`-rpath' is
+required, except when creating a convenience library.
+
+If OUTPUT-FILE ends in \`.a' or \`.lib', then a standard library is created
+using \`ar' and \`ranlib', or on Windows using \`lib'.
+
+If OUTPUT-FILE ends in \`.lo' or \`.${objext}', then a reloadable object file
+is created, otherwise an executable program is created."
+ ;;
+
+ uninstall)
+ $ECHO \
+"Usage: $progname [OPTION]... --mode=uninstall RM [RM-OPTION]... FILE...
+
+Remove libraries from an installation directory.
+
+RM is the name of the program to use to delete files associated with each FILE
+(typically \`/bin/rm'). RM-OPTIONS are options (such as \`-f') to be passed
+to RM.
+
+If FILE is a libtool library, all the files associated with it are deleted.
+Otherwise, only FILE itself is deleted using RM."
+ ;;
+
+ *)
+ func_fatal_help "invalid operation mode \`$mode'"
+ ;;
+ esac
+
+ $ECHO
+ $ECHO "Try \`$progname --help' for more information about other modes."
+
+ exit $?
+}
+
+ # Now that we've collected a possible --mode arg, show help if necessary
+ $opt_help && func_mode_help
+
+
+# func_mode_execute arg...
+func_mode_execute ()
+{
+ $opt_debug
+ # The first argument is the command name.
+ cmd="$nonopt"
+ test -z "$cmd" && \
+ func_fatal_help "you must specify a COMMAND"
+
+ # Handle -dlopen flags immediately.
+ for file in $execute_dlfiles; do
+ test -f "$file" \
+ || func_fatal_help "\`$file' is not a file"
+
+ dir=
+ case $file in
+ *.la)
+ # Check to see that this really is a libtool archive.
+ func_lalib_unsafe_p "$file" \
+ || func_fatal_help "\`$lib' is not a valid libtool archive"
+
+ # Read the libtool library.
+ dlname=
+ library_names=
+ func_source "$file"
+
+ # Skip this library if it cannot be dlopened.
+ if test -z "$dlname"; then
+ # Warn if it was a shared library.
+ test -n "$library_names" && \
+ func_warning "\`$file' was not linked with \`-export-dynamic'"
+ continue
+ fi
+
+ func_dirname "$file" "" "."
+ dir="$func_dirname_result"
+
+ if test -f "$dir/$objdir/$dlname"; then
+ dir="$dir/$objdir"
+ else
+ if test ! -f "$dir/$dlname"; then
+ func_fatal_error "cannot find \`$dlname' in \`$dir' or \`$dir/$objdir'"
+ fi
+ fi
+ ;;
+
+ *.lo)
+ # Just add the directory containing the .lo file.
+ func_dirname "$file" "" "."
+ dir="$func_dirname_result"
+ ;;
+
+ *)
+ func_warning "\`-dlopen' is ignored for non-libtool libraries and objects"
+ continue
+ ;;
+ esac
+
+ # Get the absolute pathname.
+ absdir=`cd "$dir" && pwd`
+ test -n "$absdir" && dir="$absdir"
+
+ # Now add the directory to shlibpath_var.
+ if eval "test -z \"\$$shlibpath_var\""; then
+ eval "$shlibpath_var=\"\$dir\""
+ else
+ eval "$shlibpath_var=\"\$dir:\$$shlibpath_var\""
+ fi
+ done
+
+ # This variable tells wrapper scripts just to set shlibpath_var
+ # rather than running their programs.
+ libtool_execute_magic="$magic"
+
+ # Check if any of the arguments is a wrapper script.
+ args=
+ for file
+ do
+ case $file in
+ -*) ;;
+ *)
+ # Do a test to see if this is really a libtool program.
+ if func_ltwrapper_script_p "$file"; then
+ func_source "$file"
+ # Transform arg to wrapped name.
+ file="$progdir/$program"
+ elif func_ltwrapper_executable_p "$file"; then
+ func_ltwrapper_scriptname "$file"
+ func_source "$func_ltwrapper_scriptname_result"
+ # Transform arg to wrapped name.
+ file="$progdir/$program"
+ fi
+ ;;
+ esac
+ # Quote arguments (to preserve shell metacharacters).
+ func_quote_for_eval "$file"
+ args="$args $func_quote_for_eval_result"
+ done
+
+ if test "X$opt_dry_run" = Xfalse; then
+ if test -n "$shlibpath_var"; then
+ # Export the shlibpath_var.
+ eval "export $shlibpath_var"
+ fi
+
+ # Restore saved environment variables
+ for lt_var in LANG LANGUAGE LC_ALL LC_CTYPE LC_COLLATE LC_MESSAGES
+ do
+ eval "if test \"\${save_$lt_var+set}\" = set; then
+ $lt_var=\$save_$lt_var; export $lt_var
+ else
+ $lt_unset $lt_var
+ fi"
+ done
+
+ # Now prepare to actually exec the command.
+ exec_cmd="\$cmd$args"
+ else
+ # Display what would be done.
+ if test -n "$shlibpath_var"; then
+ eval "\$ECHO \"\$shlibpath_var=\$$shlibpath_var\""
+ $ECHO "export $shlibpath_var"
+ fi
+ $ECHO "$cmd$args"
+ exit $EXIT_SUCCESS
+ fi
+}
+
+test "$mode" = execute && func_mode_execute ${1+"$@"}
+
+
+# func_mode_finish arg...
+func_mode_finish ()
+{
+ $opt_debug
+ libdirs="$nonopt"
+ admincmds=
+
+ if test -n "$finish_cmds$finish_eval" && test -n "$libdirs"; then
+ for dir
+ do
+ libdirs="$libdirs $dir"
+ done
+
+ for libdir in $libdirs; do
+ if test -n "$finish_cmds"; then
+ # Do each command in the finish commands.
+ func_execute_cmds "$finish_cmds" 'admincmds="$admincmds
+'"$cmd"'"'
+ fi
+ if test -n "$finish_eval"; then
+ # Do the single finish_eval.
+ eval cmds=\"$finish_eval\"
+ $opt_dry_run || eval "$cmds" || admincmds="$admincmds
+ $cmds"
+ fi
+ done
+ fi
+
+ # Exit here if they wanted silent mode.
+ $opt_silent && exit $EXIT_SUCCESS
+
+ $ECHO "X----------------------------------------------------------------------" | $Xsed
+ $ECHO "Libraries have been installed in:"
+ for libdir in $libdirs; do
+ $ECHO " $libdir"
+ done
+ $ECHO
+ $ECHO "If you ever happen to want to link against installed libraries"
+ $ECHO "in a given directory, LIBDIR, you must either use libtool, and"
+ $ECHO "specify the full pathname of the library, or use the \`-LLIBDIR'"
+ $ECHO "flag during linking and do at least one of the following:"
+ if test -n "$shlibpath_var"; then
+ $ECHO " - add LIBDIR to the \`$shlibpath_var' environment variable"
+ $ECHO " during execution"
+ fi
+ if test -n "$runpath_var"; then
+ $ECHO " - add LIBDIR to the \`$runpath_var' environment variable"
+ $ECHO " during linking"
+ fi
+ if test -n "$hardcode_libdir_flag_spec"; then
+ libdir=LIBDIR
+ eval flag=\"$hardcode_libdir_flag_spec\"
+
+ $ECHO " - use the \`$flag' linker flag"
+ fi
+ if test -n "$admincmds"; then
+ $ECHO " - have your system administrator run these commands:$admincmds"
+ fi
+ if test -f /etc/ld.so.conf; then
+ $ECHO " - have your system administrator add LIBDIR to \`/etc/ld.so.conf'"
+ fi
+ $ECHO
+
+ $ECHO "See any operating system documentation about shared libraries for"
+ case $host in
+ solaris2.[6789]|solaris2.1[0-9])
+ $ECHO "more information, such as the ld(1), crle(1) and ld.so(8) manual"
+ $ECHO "pages."
+ ;;
+ *)
+ $ECHO "more information, such as the ld(1) and ld.so(8) manual pages."
+ ;;
+ esac
+ $ECHO "X----------------------------------------------------------------------" | $Xsed
+ exit $EXIT_SUCCESS
+}
+
+test "$mode" = finish && func_mode_finish ${1+"$@"}
+
+
+# func_mode_install arg...
+func_mode_install ()
+{
+ $opt_debug
+ # There may be an optional sh(1) argument at the beginning of
+ # install_prog (especially on Windows NT).
+ if test "$nonopt" = "$SHELL" || test "$nonopt" = /bin/sh ||
+ # Allow the use of GNU shtool's install command.
+ $ECHO "X$nonopt" | $GREP shtool >/dev/null; then
+ # Aesthetically quote it.
+ func_quote_for_eval "$nonopt"
+ install_prog="$func_quote_for_eval_result "
+ arg=$1
+ shift
+ else
+ install_prog=
+ arg=$nonopt
+ fi
+
+ # The real first argument should be the name of the installation program.
+ # Aesthetically quote it.
+ func_quote_for_eval "$arg"
+ install_prog="$install_prog$func_quote_for_eval_result"
+
+ # We need to accept at least all the BSD install flags.
+ dest=
+ files=
+ opts=
+ prev=
+ install_type=
+ isdir=no
+ stripme=
+ for arg
+ do
+ if test -n "$dest"; then
+ files="$files $dest"
+ dest=$arg
+ continue
+ fi
+
+ case $arg in
+ -d) isdir=yes ;;
+ -f)
+ case " $install_prog " in
+ *[\\\ /]cp\ *) ;;
+ *) prev=$arg ;;
+ esac
+ ;;
+ -g | -m | -o)
+ prev=$arg
+ ;;
+ -s)
+ stripme=" -s"
+ continue
+ ;;
+ -*)
+ ;;
+ *)
+ # If the previous option needed an argument, then skip it.
+ if test -n "$prev"; then
+ prev=
+ else
+ dest=$arg
+ continue
+ fi
+ ;;
+ esac
+
+ # Aesthetically quote the argument.
+ func_quote_for_eval "$arg"
+ install_prog="$install_prog $func_quote_for_eval_result"
+ done
+
+ test -z "$install_prog" && \
+ func_fatal_help "you must specify an install program"
+
+ test -n "$prev" && \
+ func_fatal_help "the \`$prev' option requires an argument"
+
+ if test -z "$files"; then
+ if test -z "$dest"; then
+ func_fatal_help "no file or destination specified"
+ else
+ func_fatal_help "you must specify a destination"
+ fi
+ fi
+
+ # Strip any trailing slash from the destination.
+ func_stripname '' '/' "$dest"
+ dest=$func_stripname_result
+
+ # Check to see that the destination is a directory.
+ test -d "$dest" && isdir=yes
+ if test "$isdir" = yes; then
+ destdir="$dest"
+ destname=
+ else
+ func_dirname_and_basename "$dest" "" "."
+ destdir="$func_dirname_result"
+ destname="$func_basename_result"
+
+ # Not a directory, so check to see that there is only one file specified.
+ set dummy $files; shift
+ test "$#" -gt 1 && \
+ func_fatal_help "\`$dest' is not a directory"
+ fi
+ case $destdir in
+ [\\/]* | [A-Za-z]:[\\/]*) ;;
+ *)
+ for file in $files; do
+ case $file in
+ *.lo) ;;
+ *)
+ func_fatal_help "\`$destdir' must be an absolute directory name"
+ ;;
+ esac
+ done
+ ;;
+ esac
+
+ # This variable tells wrapper scripts just to set variables rather
+ # than running their programs.
+ libtool_install_magic="$magic"
+
+ staticlibs=
+ future_libdirs=
+ current_libdirs=
+ for file in $files; do
+
+ # Do each installation.
+ case $file in
+ *.$libext)
+ # Do the static libraries later.
+ staticlibs="$staticlibs $file"
+ ;;
+
+ *.la)
+ # Check to see that this really is a libtool archive.
+ func_lalib_unsafe_p "$file" \
+ || func_fatal_help "\`$file' is not a valid libtool archive"
+
+ library_names=
+ old_library=
+ relink_command=
+ func_source "$file"
+
+ # Add the libdir to current_libdirs if it is the destination.
+ if test "X$destdir" = "X$libdir"; then
+ case "$current_libdirs " in
+ *" $libdir "*) ;;
+ *) current_libdirs="$current_libdirs $libdir" ;;
+ esac
+ else
+ # Note the libdir as a future libdir.
+ case "$future_libdirs " in
+ *" $libdir "*) ;;
+ *) future_libdirs="$future_libdirs $libdir" ;;
+ esac
+ fi
+
+ func_dirname "$file" "/" ""
+ dir="$func_dirname_result"
+ dir="$dir$objdir"
+
+ if test -n "$relink_command"; then
+ # Determine the prefix the user has applied to our future dir.
+ inst_prefix_dir=`$ECHO "X$destdir" | $Xsed -e "s%$libdir\$%%"`
+
+ # Don't allow the user to place us outside of our expected
+ # location b/c this prevents finding dependent libraries that
+ # are installed to the same prefix.
+ # At present, this check doesn't affect windows .dll's that
+ # are installed into $libdir/../bin (currently, that works fine)
+ # but it's something to keep an eye on.
+ test "$inst_prefix_dir" = "$destdir" && \
+ func_fatal_error "error: cannot install \`$file' to a directory not ending in $libdir"
+
+ if test -n "$inst_prefix_dir"; then
+ # Stick the inst_prefix_dir data into the link command.
+ relink_command=`$ECHO "X$relink_command" | $Xsed -e "s%@inst_prefix_dir@%-inst-prefix-dir $inst_prefix_dir%"`
+ else
+ relink_command=`$ECHO "X$relink_command" | $Xsed -e "s%@inst_prefix_dir@%%"`
+ fi
+
+ func_warning "relinking \`$file'"
+ func_show_eval "$relink_command" \
+ 'func_fatal_error "error: relink \`$file'\'' with the above command before installing it"'
+ fi
+
+ # See the names of the shared library.
+ set dummy $library_names; shift
+ if test -n "$1"; then
+ realname="$1"
+ shift
+
+ srcname="$realname"
+ test -n "$relink_command" && srcname="$realname"T
+
+ # Install the shared library and build the symlinks.
+ func_show_eval "$install_prog $dir/$srcname $destdir/$realname" \
+ 'exit $?'
+ tstripme="$stripme"
+ case $host_os in
+ cygwin* | mingw* | pw32* | cegcc*)
+ case $realname in
+ *.dll.a)
+ tstripme=""
+ ;;
+ esac
+ ;;
+ esac
+ if test -n "$tstripme" && test -n "$striplib"; then
+ func_show_eval "$striplib $destdir/$realname" 'exit $?'
+ fi
+
+ if test "$#" -gt 0; then
+ # Delete the old symlinks, and create new ones.
+ # Try `ln -sf' first, because the `ln' binary might depend on
+ # the symlink we replace! Solaris /bin/ln does not understand -f,
+ # so we also need to try rm && ln -s.
+ for linkname
+ do
+ test "$linkname" != "$realname" \
+ && func_show_eval "(cd $destdir && { $LN_S -f $realname $linkname || { $RM $linkname && $LN_S $realname $linkname; }; })"
+ done
+ fi
+
+ # Do each command in the postinstall commands.
+ lib="$destdir/$realname"
+ func_execute_cmds "$postinstall_cmds" 'exit $?'
+ fi
+
+ # Install the pseudo-library for information purposes.
+ func_basename "$file"
+ name="$func_basename_result"
+ instname="$dir/$name"i
+ func_show_eval "$install_prog $instname $destdir/$name" 'exit $?'
+
+ # Maybe install the static library, too.
+ test -n "$old_library" && staticlibs="$staticlibs $dir/$old_library"
+ ;;
+
+ *.lo)
+ # Install (i.e. copy) a libtool object.
+
+ # Figure out destination file name, if it wasn't already specified.
+ if test -n "$destname"; then
+ destfile="$destdir/$destname"
+ else
+ func_basename "$file"
+ destfile="$func_basename_result"
+ destfile="$destdir/$destfile"
+ fi
+
+ # Deduce the name of the destination old-style object file.
+ case $destfile in
+ *.lo)
+ func_lo2o "$destfile"
+ staticdest=$func_lo2o_result
+ ;;
+ *.$objext)
+ staticdest="$destfile"
+ destfile=
+ ;;
+ *)
+ func_fatal_help "cannot copy a libtool object to \`$destfile'"
+ ;;
+ esac
+
+ # Install the libtool object if requested.
+ test -n "$destfile" && \
+ func_show_eval "$install_prog $file $destfile" 'exit $?'
+
+ # Install the old object if enabled.
+ if test "$build_old_libs" = yes; then
+ # Deduce the name of the old-style object file.
+ func_lo2o "$file"
+ staticobj=$func_lo2o_result
+ func_show_eval "$install_prog \$staticobj \$staticdest" 'exit $?'
+ fi
+ exit $EXIT_SUCCESS
+ ;;
+
+ *)
+ # Figure out destination file name, if it wasn't already specified.
+ if test -n "$destname"; then
+ destfile="$destdir/$destname"
+ else
+ func_basename "$file"
+ destfile="$func_basename_result"
+ destfile="$destdir/$destfile"
+ fi
+
+ # If the file is missing, and there is a .exe on the end, strip it
+ # because it is most likely a libtool script we actually want to
+ # install
+ stripped_ext=""
+ case $file in
+ *.exe)
+ if test ! -f "$file"; then
+ func_stripname '' '.exe' "$file"
+ file=$func_stripname_result
+ stripped_ext=".exe"
+ fi
+ ;;
+ esac
+
+ # Do a test to see if this is really a libtool program.
+ case $host in
+ *cygwin* | *mingw*)
+ if func_ltwrapper_executable_p "$file"; then
+ func_ltwrapper_scriptname "$file"
+ wrapper=$func_ltwrapper_scriptname_result
+ else
+ func_stripname '' '.exe' "$file"
+ wrapper=$func_stripname_result
+ fi
+ ;;
+ *)
+ wrapper=$file
+ ;;
+ esac
+ if func_ltwrapper_script_p "$wrapper"; then
+ notinst_deplibs=
+ relink_command=
+
+ func_source "$wrapper"
+
+ # Check the variables that should have been set.
+ test -z "$generated_by_libtool_version" && \
+ func_fatal_error "invalid libtool wrapper script \`$wrapper'"
+
+ finalize=yes
+ for lib in $notinst_deplibs; do
+ # Check to see that each library is installed.
+ libdir=
+ if test -f "$lib"; then
+ func_source "$lib"
+ fi
+ libfile="$libdir/"`$ECHO "X$lib" | $Xsed -e 's%^.*/%%g'` ### testsuite: skip nested quoting test
+ if test -n "$libdir" && test ! -f "$libfile"; then
+ func_warning "\`$lib' has not been installed in \`$libdir'"
+ finalize=no
+ fi
+ done
+
+ relink_command=
+ func_source "$wrapper"
+
+ outputname=
+ if test "$fast_install" = no && test -n "$relink_command"; then
+ $opt_dry_run || {
+ if test "$finalize" = yes; then
+ tmpdir=`func_mktempdir`
+ func_basename "$file$stripped_ext"
+ file="$func_basename_result"
+ outputname="$tmpdir/$file"
+ # Replace the output file specification.
+ relink_command=`$ECHO "X$relink_command" | $Xsed -e 's%@OUTPUT@%'"$outputname"'%g'`
+
+ $opt_silent || {
+ func_quote_for_expand "$relink_command"
+ eval "func_echo $func_quote_for_expand_result"
+ }
+ if eval "$relink_command"; then :
+ else
+ func_error "error: relink \`$file' with the above command before installing it"
+ $opt_dry_run || ${RM}r "$tmpdir"
+ continue
+ fi
+ file="$outputname"
+ else
+ func_warning "cannot relink \`$file'"
+ fi
+ }
+ else
+ # Install the binary that we compiled earlier.
+ file=`$ECHO "X$file$stripped_ext" | $Xsed -e "s%\([^/]*\)$%$objdir/\1%"`
+ fi
+ fi
+
+ # remove .exe since cygwin /usr/bin/install will append another
+ # one anyway
+ case $install_prog,$host in
+ */usr/bin/install*,*cygwin*)
+ case $file:$destfile in
+ *.exe:*.exe)
+ # this is ok
+ ;;
+ *.exe:*)
+ destfile=$destfile.exe
+ ;;
+ *:*.exe)
+ func_stripname '' '.exe' "$destfile"
+ destfile=$func_stripname_result
+ ;;
+ esac
+ ;;
+ esac
+ func_show_eval "$install_prog\$stripme \$file \$destfile" 'exit $?'
+ $opt_dry_run || if test -n "$outputname"; then
+ ${RM}r "$tmpdir"
+ fi
+ ;;
+ esac
+ done
+
+ for file in $staticlibs; do
+ func_basename "$file"
+ name="$func_basename_result"
+
+ # Set up the ranlib parameters.
+ oldlib="$destdir/$name"
+
+ func_show_eval "$install_prog \$file \$oldlib" 'exit $?'
+
+ if test -n "$stripme" && test -n "$old_striplib"; then
+ func_show_eval "$old_striplib $oldlib" 'exit $?'
+ fi
+
+ # Do each command in the postinstall commands.
+ func_execute_cmds "$old_postinstall_cmds" 'exit $?'
+ done
+
+ test -n "$future_libdirs" && \
+ func_warning "remember to run \`$progname --finish$future_libdirs'"
+
+ if test -n "$current_libdirs"; then
+ # Maybe just do a dry run.
+ $opt_dry_run && current_libdirs=" -n$current_libdirs"
+ exec_cmd='$SHELL $progpath $preserve_args --finish$current_libdirs'
+ else
+ exit $EXIT_SUCCESS
+ fi
+}
+
+test "$mode" = install && func_mode_install ${1+"$@"}
+
+
+# func_generate_dlsyms outputname originator pic_p
+# Extract symbols from dlprefiles and create ${outputname}S.o with
+# a dlpreopen symbol table.
+func_generate_dlsyms ()
+{
+ $opt_debug
+ my_outputname="$1"
+ my_originator="$2"
+ my_pic_p="${3-no}"
+ my_prefix=`$ECHO "$my_originator" | sed 's%[^a-zA-Z0-9]%_%g'`
+ my_dlsyms=
+
+ if test -n "$dlfiles$dlprefiles" || test "$dlself" != no; then
+ if test -n "$NM" && test -n "$global_symbol_pipe"; then
+ my_dlsyms="${my_outputname}S.c"
+ else
+ func_error "not configured to extract global symbols from dlpreopened files"
+ fi
+ fi
+
+ if test -n "$my_dlsyms"; then
+ case $my_dlsyms in
+ "") ;;
+ *.c)
+ # Discover the nlist of each of the dlfiles.
+ nlist="$output_objdir/${my_outputname}.nm"
+
+ func_show_eval "$RM $nlist ${nlist}S ${nlist}T"
+
+ # Parse the name list into a source file.
+ func_verbose "creating $output_objdir/$my_dlsyms"
+
+ $opt_dry_run || $ECHO > "$output_objdir/$my_dlsyms" "\
+/* $my_dlsyms - symbol resolution table for \`$my_outputname' dlsym emulation. */
+/* Generated by $PROGRAM (GNU $PACKAGE$TIMESTAMP) $VERSION */
+
+#ifdef __cplusplus
+extern \"C\" {
+#endif
+
+/* External symbol declarations for the compiler. */\
+"
+
+ if test "$dlself" = yes; then
+ func_verbose "generating symbol list for \`$output'"
+
+ $opt_dry_run || echo ': @PROGRAM@ ' > "$nlist"
+
+ # Add our own program objects to the symbol list.
+ progfiles=`$ECHO "X$objs$old_deplibs" | $SP2NL | $Xsed -e "$lo2o" | $NL2SP`
+ for progfile in $progfiles; do
+ func_verbose "extracting global C symbols from \`$progfile'"
+ $opt_dry_run || eval "$NM $progfile | $global_symbol_pipe >> '$nlist'"
+ done
+
+ if test -n "$exclude_expsyms"; then
+ $opt_dry_run || {
+ eval '$EGREP -v " ($exclude_expsyms)$" "$nlist" > "$nlist"T'
+ eval '$MV "$nlist"T "$nlist"'
+ }
+ fi
+
+ if test -n "$export_symbols_regex"; then
+ $opt_dry_run || {
+ eval '$EGREP -e "$export_symbols_regex" "$nlist" > "$nlist"T'
+ eval '$MV "$nlist"T "$nlist"'
+ }
+ fi
+
+ # Prepare the list of exported symbols
+ if test -z "$export_symbols"; then
+ export_symbols="$output_objdir/$outputname.exp"
+ $opt_dry_run || {
+ $RM $export_symbols
+ eval "${SED} -n -e '/^: @PROGRAM@ $/d' -e 's/^.* \(.*\)$/\1/p' "'< "$nlist" > "$export_symbols"'
+ case $host in
+ *cygwin* | *mingw* | *cegcc* )
+ eval "echo EXPORTS "'> "$output_objdir/$outputname.def"'
+ eval 'cat "$export_symbols" >> "$output_objdir/$outputname.def"'
+ ;;
+ esac
+ }
+ else
+ $opt_dry_run || {
+ eval "${SED} -e 's/\([].[*^$]\)/\\\\\1/g' -e 's/^/ /' -e 's/$/$/'"' < "$export_symbols" > "$output_objdir/$outputname.exp"'
+ eval '$GREP -f "$output_objdir/$outputname.exp" < "$nlist" > "$nlist"T'
+ eval '$MV "$nlist"T "$nlist"'
+ case $host in
+ *cygwin | *mingw* | *cegcc* )
+ eval "echo EXPORTS "'> "$output_objdir/$outputname.def"'
+ eval 'cat "$nlist" >> "$output_objdir/$outputname.def"'
+ ;;
+ esac
+ }
+ fi
+ fi
+
+ for dlprefile in $dlprefiles; do
+ func_verbose "extracting global C symbols from \`$dlprefile'"
+ func_basename "$dlprefile"
+ name="$func_basename_result"
+ $opt_dry_run || {
+ eval '$ECHO ": $name " >> "$nlist"'
+ eval "$NM $dlprefile 2>/dev/null | $global_symbol_pipe >> '$nlist'"
+ }
+ done
+
+ $opt_dry_run || {
+ # Make sure we have at least an empty file.
+ test -f "$nlist" || : > "$nlist"
+
+ if test -n "$exclude_expsyms"; then
+ $EGREP -v " ($exclude_expsyms)$" "$nlist" > "$nlist"T
+ $MV "$nlist"T "$nlist"
+ fi
+
+ # Try sorting and uniquifying the output.
+ if $GREP -v "^: " < "$nlist" |
+ if sort -k 3 </dev/null >/dev/null 2>&1; then
+ sort -k 3
+ else
+ sort +2
+ fi |
+ uniq > "$nlist"S; then
+ :
+ else
+ $GREP -v "^: " < "$nlist" > "$nlist"S
+ fi
+
+ if test -f "$nlist"S; then
+ eval "$global_symbol_to_cdecl"' < "$nlist"S >> "$output_objdir/$my_dlsyms"'
+ else
+ $ECHO '/* NONE */' >> "$output_objdir/$my_dlsyms"
+ fi
+
+ $ECHO >> "$output_objdir/$my_dlsyms" "\
+
+/* The mapping between symbol names and symbols. */
+typedef struct {
+ const char *name;
+ void *address;
+} lt_dlsymlist;
+"
+ case $host in
+ *cygwin* | *mingw* | *cegcc* )
+ $ECHO >> "$output_objdir/$my_dlsyms" "\
+/* DATA imports from DLLs on WIN32 con't be const, because
+ runtime relocations are performed -- see ld's documentation
+ on pseudo-relocs. */"
+ lt_dlsym_const= ;;
+ *osf5*)
+ echo >> "$output_objdir/$my_dlsyms" "\
+/* This system does not cope well with relocations in const data */"
+ lt_dlsym_const= ;;
+ *)
+ lt_dlsym_const=const ;;
+ esac
+
+ $ECHO >> "$output_objdir/$my_dlsyms" "\
+extern $lt_dlsym_const lt_dlsymlist
+lt_${my_prefix}_LTX_preloaded_symbols[];
+$lt_dlsym_const lt_dlsymlist
+lt_${my_prefix}_LTX_preloaded_symbols[] =
+{\
+ { \"$my_originator\", (void *) 0 },"
+
+ case $need_lib_prefix in
+ no)
+ eval "$global_symbol_to_c_name_address" < "$nlist" >> "$output_objdir/$my_dlsyms"
+ ;;
+ *)
+ eval "$global_symbol_to_c_name_address_lib_prefix" < "$nlist" >> "$output_objdir/$my_dlsyms"
+ ;;
+ esac
+ $ECHO >> "$output_objdir/$my_dlsyms" "\
+ {0, (void *) 0}
+};
+
+/* This works around a problem in FreeBSD linker */
+#ifdef FREEBSD_WORKAROUND
+static const void *lt_preloaded_setup() {
+ return lt_${my_prefix}_LTX_preloaded_symbols;
+}
+#endif
+
+#ifdef __cplusplus
+}
+#endif\
+"
+ } # !$opt_dry_run
+
+ pic_flag_for_symtable=
+ case "$compile_command " in
+ *" -static "*) ;;
+ *)
+ case $host in
+ # compiling the symbol table file with pic_flag works around
+ # a FreeBSD bug that causes programs to crash when -lm is
+ # linked before any other PIC object. But we must not use
+ # pic_flag when linking with -static. The problem exists in
+ # FreeBSD 2.2.6 and is fixed in FreeBSD 3.1.
+ *-*-freebsd2*|*-*-freebsd3.0*|*-*-freebsdelf3.0*)
+ pic_flag_for_symtable=" $pic_flag -DFREEBSD_WORKAROUND" ;;
+ *-*-hpux*)
+ pic_flag_for_symtable=" $pic_flag" ;;
+ *)
+ if test "X$my_pic_p" != Xno; then
+ pic_flag_for_symtable=" $pic_flag"
+ fi
+ ;;
+ esac
+ ;;
+ esac
+ symtab_cflags=
+ for arg in $LTCFLAGS; do
+ case $arg in
+ -pie | -fpie | -fPIE) ;;
+ *) symtab_cflags="$symtab_cflags $arg" ;;
+ esac
+ done
+
+ # Now compile the dynamic symbol file.
+ func_show_eval '(cd $output_objdir && $LTCC$symtab_cflags -c$no_builtin_flag$pic_flag_for_symtable "$my_dlsyms")' 'exit $?'
+
+ # Clean up the generated files.
+ func_show_eval '$RM "$output_objdir/$my_dlsyms" "$nlist" "${nlist}S" "${nlist}T"'
+
+ # Transform the symbol file into the correct name.
+ symfileobj="$output_objdir/${my_outputname}S.$objext"
+ case $host in
+ *cygwin* | *mingw* | *cegcc* )
+ if test -f "$output_objdir/$my_outputname.def"; then
+ compile_command=`$ECHO "X$compile_command" | $Xsed -e "s%@SYMFILE@%$output_objdir/$my_outputname.def $symfileobj%"`
+ finalize_command=`$ECHO "X$finalize_command" | $Xsed -e "s%@SYMFILE@%$output_objdir/$my_outputname.def $symfileobj%"`
+ else
+ compile_command=`$ECHO "X$compile_command" | $Xsed -e "s%@SYMFILE@%$symfileobj%"`
+ finalize_command=`$ECHO "X$finalize_command" | $Xsed -e "s%@SYMFILE@%$symfileobj%"`
+ fi
+ ;;
+ *)
+ compile_command=`$ECHO "X$compile_command" | $Xsed -e "s%@SYMFILE@%$symfileobj%"`
+ finalize_command=`$ECHO "X$finalize_command" | $Xsed -e "s%@SYMFILE@%$symfileobj%"`
+ ;;
+ esac
+ ;;
+ *)
+ func_fatal_error "unknown suffix for \`$my_dlsyms'"
+ ;;
+ esac
+ else
+ # We keep going just in case the user didn't refer to
+ # lt_preloaded_symbols. The linker will fail if global_symbol_pipe
+ # really was required.
+
+ # Nullify the symbol file.
+ compile_command=`$ECHO "X$compile_command" | $Xsed -e "s% @SYMFILE@%%"`
+ finalize_command=`$ECHO "X$finalize_command" | $Xsed -e "s% @SYMFILE@%%"`
+ fi
+}
+
+# func_win32_libid arg
+# return the library type of file 'arg'
+#
+# Need a lot of goo to handle *both* DLLs and import libs
+# Has to be a shell function in order to 'eat' the argument
+# that is supplied when $file_magic_command is called.
+func_win32_libid ()
+{
+ $opt_debug
+ win32_libid_type="unknown"
+ win32_fileres=`file -L $1 2>/dev/null`
+ case $win32_fileres in
+ *ar\ archive\ import\ library*) # definitely import
+ win32_libid_type="x86 archive import"
+ ;;
+ *ar\ archive*) # could be an import, or static
+ if eval $OBJDUMP -f $1 | $SED -e '10q' 2>/dev/null |
+ $EGREP 'file format pe-i386(.*architecture: i386)?' >/dev/null ; then
+ win32_nmres=`eval $NM -f posix -A $1 |
+ $SED -n -e '
+ 1,100{
+ / I /{
+ s,.*,import,
+ p
+ q
+ }
+ }'`
+ case $win32_nmres in
+ import*) win32_libid_type="x86 archive import";;
+ *) win32_libid_type="x86 archive static";;
+ esac
+ fi
+ ;;
+ *DLL*)
+ win32_libid_type="x86 DLL"
+ ;;
+ *executable*) # but shell scripts are "executable" too...
+ case $win32_fileres in
+ *MS\ Windows\ PE\ Intel*)
+ win32_libid_type="x86 DLL"
+ ;;
+ esac
+ ;;
+ esac
+ $ECHO "$win32_libid_type"
+}
+
+
+
+# func_extract_an_archive dir oldlib
+func_extract_an_archive ()
+{
+ $opt_debug
+ f_ex_an_ar_dir="$1"; shift
+ f_ex_an_ar_oldlib="$1"
+ func_show_eval "(cd \$f_ex_an_ar_dir && $AR x \"\$f_ex_an_ar_oldlib\")" 'exit $?'
+ if ($AR t "$f_ex_an_ar_oldlib" | sort | sort -uc >/dev/null 2>&1); then
+ :
+ else
+ func_fatal_error "object name conflicts in archive: $f_ex_an_ar_dir/$f_ex_an_ar_oldlib"
+ fi
+}
+
+
+# func_extract_archives gentop oldlib ...
+func_extract_archives ()
+{
+ $opt_debug
+ my_gentop="$1"; shift
+ my_oldlibs=${1+"$@"}
+ my_oldobjs=""
+ my_xlib=""
+ my_xabs=""
+ my_xdir=""
+
+ for my_xlib in $my_oldlibs; do
+ # Extract the objects.
+ case $my_xlib in
+ [\\/]* | [A-Za-z]:[\\/]*) my_xabs="$my_xlib" ;;
+ *) my_xabs=`pwd`"/$my_xlib" ;;
+ esac
+ func_basename "$my_xlib"
+ my_xlib="$func_basename_result"
+ my_xlib_u=$my_xlib
+ while :; do
+ case " $extracted_archives " in
+ *" $my_xlib_u "*)
+ func_arith $extracted_serial + 1
+ extracted_serial=$func_arith_result
+ my_xlib_u=lt$extracted_serial-$my_xlib ;;
+ *) break ;;
+ esac
+ done
+ extracted_archives="$extracted_archives $my_xlib_u"
+ my_xdir="$my_gentop/$my_xlib_u"
+
+ func_mkdir_p "$my_xdir"
+
+ case $host in
+ *-darwin*)
+ func_verbose "Extracting $my_xabs"
+ # Do not bother doing anything if just a dry run
+ $opt_dry_run || {
+ darwin_orig_dir=`pwd`
+ cd $my_xdir || exit $?
+ darwin_archive=$my_xabs
+ darwin_curdir=`pwd`
+ darwin_base_archive=`basename "$darwin_archive"`
+ darwin_arches=`$LIPO -info "$darwin_archive" 2>/dev/null | $GREP Architectures 2>/dev/null || true`
+ if test -n "$darwin_arches"; then
+ darwin_arches=`$ECHO "$darwin_arches" | $SED -e 's/.*are://'`
+ darwin_arch=
+ func_verbose "$darwin_base_archive has multiple architectures $darwin_arches"
+ for darwin_arch in $darwin_arches ; do
+ func_mkdir_p "unfat-$$/${darwin_base_archive}-${darwin_arch}"
+ $LIPO -thin $darwin_arch -output "unfat-$$/${darwin_base_archive}-${darwin_arch}/${darwin_base_archive}" "${darwin_archive}"
+ cd "unfat-$$/${darwin_base_archive}-${darwin_arch}"
+ func_extract_an_archive "`pwd`" "${darwin_base_archive}"
+ cd "$darwin_curdir"
+ $RM "unfat-$$/${darwin_base_archive}-${darwin_arch}/${darwin_base_archive}"
+ done # $darwin_arches
+ ## Okay now we've a bunch of thin objects, gotta fatten them up :)
+ darwin_filelist=`find unfat-$$ -type f -name \*.o -print -o -name \*.lo -print | $SED -e "$basename" | sort -u`
+ darwin_file=
+ darwin_files=
+ for darwin_file in $darwin_filelist; do
+ darwin_files=`find unfat-$$ -name $darwin_file -print | $NL2SP`
+ $LIPO -create -output "$darwin_file" $darwin_files
+ done # $darwin_filelist
+ $RM -rf unfat-$$
+ cd "$darwin_orig_dir"
+ else
+ cd $darwin_orig_dir
+ func_extract_an_archive "$my_xdir" "$my_xabs"
+ fi # $darwin_arches
+ } # !$opt_dry_run
+ ;;
+ *)
+ func_extract_an_archive "$my_xdir" "$my_xabs"
+ ;;
+ esac
+ my_oldobjs="$my_oldobjs "`find $my_xdir -name \*.$objext -print -o -name \*.lo -print | $NL2SP`
+ done
+
+ func_extract_archives_result="$my_oldobjs"
+}
+
+
+
+# func_emit_wrapper_part1 [arg=no]
+#
+# Emit the first part of a libtool wrapper script on stdout.
+# For more information, see the description associated with
+# func_emit_wrapper(), below.
+func_emit_wrapper_part1 ()
+{
+ func_emit_wrapper_part1_arg1=no
+ if test -n "$1" ; then
+ func_emit_wrapper_part1_arg1=$1
+ fi
+
+ $ECHO "\
+#! $SHELL
+
+# $output - temporary wrapper script for $objdir/$outputname
+# Generated by $PROGRAM (GNU $PACKAGE$TIMESTAMP) $VERSION
+#
+# The $output program cannot be directly executed until all the libtool
+# libraries that it depends on are installed.
+#
+# This wrapper script should never be moved out of the build directory.
+# If it is, it will not operate correctly.
+
+# Sed substitution that helps us do robust quoting. It backslashifies
+# metacharacters that are still active within double-quoted strings.
+Xsed='${SED} -e 1s/^X//'
+sed_quote_subst='$sed_quote_subst'
+
+# Be Bourne compatible
+if test -n \"\${ZSH_VERSION+set}\" && (emulate sh) >/dev/null 2>&1; then
+ emulate sh
+ NULLCMD=:
+ # Zsh 3.x and 4.x performs word splitting on \${1+\"\$@\"}, which
+ # is contrary to our usage. Disable this feature.
+ alias -g '\${1+\"\$@\"}'='\"\$@\"'
+ setopt NO_GLOB_SUBST
+else
+ case \`(set -o) 2>/dev/null\` in *posix*) set -o posix;; esac
+fi
+BIN_SH=xpg4; export BIN_SH # for Tru64
+DUALCASE=1; export DUALCASE # for MKS sh
+
+# The HP-UX ksh and POSIX shell print the target directory to stdout
+# if CDPATH is set.
+(unset CDPATH) >/dev/null 2>&1 && unset CDPATH
+
+relink_command=\"$relink_command\"
+
+# This environment variable determines our operation mode.
+if test \"\$libtool_install_magic\" = \"$magic\"; then
+ # install mode needs the following variables:
+ generated_by_libtool_version='$macro_version'
+ notinst_deplibs='$notinst_deplibs'
+else
+ # When we are sourced in execute mode, \$file and \$ECHO are already set.
+ if test \"\$libtool_execute_magic\" != \"$magic\"; then
+ ECHO=\"$qecho\"
+ file=\"\$0\"
+ # Make sure echo works.
+ if test \"X\$1\" = X--no-reexec; then
+ # Discard the --no-reexec flag, and continue.
+ shift
+ elif test \"X\`{ \$ECHO '\t'; } 2>/dev/null\`\" = 'X\t'; then
+ # Yippee, \$ECHO works!
+ :
+ else
+ # Restart under the correct shell, and then maybe \$ECHO will work.
+ exec $SHELL \"\$0\" --no-reexec \${1+\"\$@\"}
+ fi
+ fi\
+"
+ $ECHO "\
+
+ # Find the directory that this script lives in.
+ thisdir=\`\$ECHO \"X\$file\" | \$Xsed -e 's%/[^/]*$%%'\`
+ test \"x\$thisdir\" = \"x\$file\" && thisdir=.
+
+ # Follow symbolic links until we get to the real thisdir.
+ file=\`ls -ld \"\$file\" | ${SED} -n 's/.*-> //p'\`
+ while test -n \"\$file\"; do
+ destdir=\`\$ECHO \"X\$file\" | \$Xsed -e 's%/[^/]*\$%%'\`
+
+ # If there was a directory component, then change thisdir.
+ if test \"x\$destdir\" != \"x\$file\"; then
+ case \"\$destdir\" in
+ [\\\\/]* | [A-Za-z]:[\\\\/]*) thisdir=\"\$destdir\" ;;
+ *) thisdir=\"\$thisdir/\$destdir\" ;;
+ esac
+ fi
+
+ file=\`\$ECHO \"X\$file\" | \$Xsed -e 's%^.*/%%'\`
+ file=\`ls -ld \"\$thisdir/\$file\" | ${SED} -n 's/.*-> //p'\`
+ done
+"
+}
+# end: func_emit_wrapper_part1
+
+# func_emit_wrapper_part2 [arg=no]
+#
+# Emit the second part of a libtool wrapper script on stdout.
+# For more information, see the description associated with
+# func_emit_wrapper(), below.
+func_emit_wrapper_part2 ()
+{
+ func_emit_wrapper_part2_arg1=no
+ if test -n "$1" ; then
+ func_emit_wrapper_part2_arg1=$1
+ fi
+
+ $ECHO "\
+
+ # Usually 'no', except on cygwin/mingw when embedded into
+ # the cwrapper.
+ WRAPPER_SCRIPT_BELONGS_IN_OBJDIR=$func_emit_wrapper_part2_arg1
+ if test \"\$WRAPPER_SCRIPT_BELONGS_IN_OBJDIR\" = \"yes\"; then
+ # special case for '.'
+ if test \"\$thisdir\" = \".\"; then
+ thisdir=\`pwd\`
+ fi
+ # remove .libs from thisdir
+ case \"\$thisdir\" in
+ *[\\\\/]$objdir ) thisdir=\`\$ECHO \"X\$thisdir\" | \$Xsed -e 's%[\\\\/][^\\\\/]*$%%'\` ;;
+ $objdir ) thisdir=. ;;
+ esac
+ fi
+
+ # Try to get the absolute directory name.
+ absdir=\`cd \"\$thisdir\" && pwd\`
+ test -n \"\$absdir\" && thisdir=\"\$absdir\"
+"
+
+ if test "$fast_install" = yes; then
+ $ECHO "\
+ program=lt-'$outputname'$exeext
+ progdir=\"\$thisdir/$objdir\"
+
+ if test ! -f \"\$progdir/\$program\" ||
+ { file=\`ls -1dt \"\$progdir/\$program\" \"\$progdir/../\$program\" 2>/dev/null | ${SED} 1q\`; \\
+ test \"X\$file\" != \"X\$progdir/\$program\"; }; then
+
+ file=\"\$\$-\$program\"
+
+ if test ! -d \"\$progdir\"; then
+ $MKDIR \"\$progdir\"
+ else
+ $RM \"\$progdir/\$file\"
+ fi"
+
+ $ECHO "\
+
+ # relink executable if necessary
+ if test -n \"\$relink_command\"; then
+ if relink_command_output=\`eval \$relink_command 2>&1\`; then :
+ else
+ $ECHO \"\$relink_command_output\" >&2
+ $RM \"\$progdir/\$file\"
+ exit 1
+ fi
+ fi
+
+ $MV \"\$progdir/\$file\" \"\$progdir/\$program\" 2>/dev/null ||
+ { $RM \"\$progdir/\$program\";
+ $MV \"\$progdir/\$file\" \"\$progdir/\$program\"; }
+ $RM \"\$progdir/\$file\"
+ fi"
+ else
+ $ECHO "\
+ program='$outputname'
+ progdir=\"\$thisdir/$objdir\"
+"
+ fi
+
+ $ECHO "\
+
+ if test -f \"\$progdir/\$program\"; then"
+
+ # Export our shlibpath_var if we have one.
+ if test "$shlibpath_overrides_runpath" = yes && test -n "$shlibpath_var" && test -n "$temp_rpath"; then
+ $ECHO "\
+ # Add our own library path to $shlibpath_var
+ $shlibpath_var=\"$temp_rpath\$$shlibpath_var\"
+
+ # Some systems cannot cope with colon-terminated $shlibpath_var
+ # The second colon is a workaround for a bug in BeOS R4 sed
+ $shlibpath_var=\`\$ECHO \"X\$$shlibpath_var\" | \$Xsed -e 's/::*\$//'\`
+
+ export $shlibpath_var
+"
+ fi
+
+ # fixup the dll searchpath if we need to.
+ if test -n "$dllsearchpath"; then
+ $ECHO "\
+ # Add the dll search path components to the executable PATH
+ PATH=$dllsearchpath:\$PATH
+"
+ fi
+
+ $ECHO "\
+ if test \"\$libtool_execute_magic\" != \"$magic\"; then
+ # Run the actual program with our arguments.
+"
+ case $host in
+ # Backslashes separate directories on plain windows
+ *-*-mingw | *-*-os2* | *-cegcc*)
+ $ECHO "\
+ exec \"\$progdir\\\\\$program\" \${1+\"\$@\"}
+"
+ ;;
+
+ *)
+ $ECHO "\
+ exec \"\$progdir/\$program\" \${1+\"\$@\"}
+"
+ ;;
+ esac
+ $ECHO "\
+ \$ECHO \"\$0: cannot exec \$program \$*\" 1>&2
+ exit 1
+ fi
+ else
+ # The program doesn't exist.
+ \$ECHO \"\$0: error: \\\`\$progdir/\$program' does not exist\" 1>&2
+ \$ECHO \"This script is just a wrapper for \$program.\" 1>&2
+ $ECHO \"See the $PACKAGE documentation for more information.\" 1>&2
+ exit 1
+ fi
+fi\
+"
+}
+# end: func_emit_wrapper_part2
+
+
+# func_emit_wrapper [arg=no]
+#
+# Emit a libtool wrapper script on stdout.
+# Don't directly open a file because we may want to
+# incorporate the script contents within a cygwin/mingw
+# wrapper executable. Must ONLY be called from within
+# func_mode_link because it depends on a number of variables
+# set therein.
+#
+# ARG is the value that the WRAPPER_SCRIPT_BELONGS_IN_OBJDIR
+# variable will take. If 'yes', then the emitted script
+# will assume that the directory in which it is stored is
+# the $objdir directory. This is a cygwin/mingw-specific
+# behavior.
+func_emit_wrapper ()
+{
+ func_emit_wrapper_arg1=no
+ if test -n "$1" ; then
+ func_emit_wrapper_arg1=$1
+ fi
+
+ # split this up so that func_emit_cwrapperexe_src
+ # can call each part independently.
+ func_emit_wrapper_part1 "${func_emit_wrapper_arg1}"
+ func_emit_wrapper_part2 "${func_emit_wrapper_arg1}"
+}
+
+
+# func_to_host_path arg
+#
+# Convert paths to host format when used with build tools.
+# Intended for use with "native" mingw (where libtool itself
+# is running under the msys shell), or in the following cross-
+# build environments:
+# $build $host
+# mingw (msys) mingw [e.g. native]
+# cygwin mingw
+# *nix + wine mingw
+# where wine is equipped with the `winepath' executable.
+# In the native mingw case, the (msys) shell automatically
+# converts paths for any non-msys applications it launches,
+# but that facility isn't available from inside the cwrapper.
+# Similar accommodations are necessary for $host mingw and
+# $build cygwin. Calling this function does no harm for other
+# $host/$build combinations not listed above.
+#
+# ARG is the path (on $build) that should be converted to
+# the proper representation for $host. The result is stored
+# in $func_to_host_path_result.
+func_to_host_path ()
+{
+ func_to_host_path_result="$1"
+ if test -n "$1" ; then
+ case $host in
+ *mingw* )
+ lt_sed_naive_backslashify='s|\\\\*|\\|g;s|/|\\|g;s|\\|\\\\|g'
+ case $build in
+ *mingw* ) # actually, msys
+ # awkward: cmd appends spaces to result
+ lt_sed_strip_trailing_spaces="s/[ ]*\$//"
+ func_to_host_path_tmp1=`( cmd //c echo "$1" |\
+ $SED -e "$lt_sed_strip_trailing_spaces" ) 2>/dev/null || echo ""`
+ func_to_host_path_result=`echo "$func_to_host_path_tmp1" |\
+ $SED -e "$lt_sed_naive_backslashify"`
+ ;;
+ *cygwin* )
+ func_to_host_path_tmp1=`cygpath -w "$1"`
+ func_to_host_path_result=`echo "$func_to_host_path_tmp1" |\
+ $SED -e "$lt_sed_naive_backslashify"`
+ ;;
+ * )
+ # Unfortunately, winepath does not exit with a non-zero
+ # error code, so we are forced to check the contents of
+ # stdout. On the other hand, if the command is not
+ # found, the shell will set an exit code of 127 and print
+ # *an error message* to stdout. So we must check for both
+ # error code of zero AND non-empty stdout, which explains
+ # the odd construction:
+ func_to_host_path_tmp1=`winepath -w "$1" 2>/dev/null`
+ if test "$?" -eq 0 && test -n "${func_to_host_path_tmp1}"; then
+ func_to_host_path_result=`echo "$func_to_host_path_tmp1" |\
+ $SED -e "$lt_sed_naive_backslashify"`
+ else
+ # Allow warning below.
+ func_to_host_path_result=""
+ fi
+ ;;
+ esac
+ if test -z "$func_to_host_path_result" ; then
+ func_error "Could not determine host path corresponding to"
+ func_error " '$1'"
+ func_error "Continuing, but uninstalled executables may not work."
+ # Fallback:
+ func_to_host_path_result="$1"
+ fi
+ ;;
+ esac
+ fi
+}
+# end: func_to_host_path
+
+# func_to_host_pathlist arg
+#
+# Convert pathlists to host format when used with build tools.
+# See func_to_host_path(), above. This function supports the
+# following $build/$host combinations (but does no harm for
+# combinations not listed here):
+# $build $host
+# mingw (msys) mingw [e.g. native]
+# cygwin mingw
+# *nix + wine mingw
+#
+# Path separators are also converted from $build format to
+# $host format. If ARG begins or ends with a path separator
+# character, it is preserved (but converted to $host format)
+# on output.
+#
+# ARG is a pathlist (on $build) that should be converted to
+# the proper representation on $host. The result is stored
+# in $func_to_host_pathlist_result.
+func_to_host_pathlist ()
+{
+ func_to_host_pathlist_result="$1"
+ if test -n "$1" ; then
+ case $host in
+ *mingw* )
+ lt_sed_naive_backslashify='s|\\\\*|\\|g;s|/|\\|g;s|\\|\\\\|g'
+ # Remove leading and trailing path separator characters from
+ # ARG. msys behavior is inconsistent here, cygpath turns them
+ # into '.;' and ';.', and winepath ignores them completely.
+ func_to_host_pathlist_tmp2="$1"
+ # Once set for this call, this variable should not be
+ # reassigned. It is used in tha fallback case.
+ func_to_host_pathlist_tmp1=`echo "$func_to_host_pathlist_tmp2" |\
+ $SED -e 's|^:*||' -e 's|:*$||'`
+ case $build in
+ *mingw* ) # Actually, msys.
+ # Awkward: cmd appends spaces to result.
+ lt_sed_strip_trailing_spaces="s/[ ]*\$//"
+ func_to_host_pathlist_tmp2=`( cmd //c echo "$func_to_host_pathlist_tmp1" |\
+ $SED -e "$lt_sed_strip_trailing_spaces" ) 2>/dev/null || echo ""`
+ func_to_host_pathlist_result=`echo "$func_to_host_pathlist_tmp2" |\
+ $SED -e "$lt_sed_naive_backslashify"`
+ ;;
+ *cygwin* )
+ func_to_host_pathlist_tmp2=`cygpath -w -p "$func_to_host_pathlist_tmp1"`
+ func_to_host_pathlist_result=`echo "$func_to_host_pathlist_tmp2" |\
+ $SED -e "$lt_sed_naive_backslashify"`
+ ;;
+ * )
+ # unfortunately, winepath doesn't convert pathlists
+ func_to_host_pathlist_result=""
+ func_to_host_pathlist_oldIFS=$IFS
+ IFS=:
+ for func_to_host_pathlist_f in $func_to_host_pathlist_tmp1 ; do
+ IFS=$func_to_host_pathlist_oldIFS
+ if test -n "$func_to_host_pathlist_f" ; then
+ func_to_host_path "$func_to_host_pathlist_f"
+ if test -n "$func_to_host_path_result" ; then
+ if test -z "$func_to_host_pathlist_result" ; then
+ func_to_host_pathlist_result="$func_to_host_path_result"
+ else
+ func_to_host_pathlist_result="$func_to_host_pathlist_result;$func_to_host_path_result"
+ fi
+ fi
+ fi
+ IFS=:
+ done
+ IFS=$func_to_host_pathlist_oldIFS
+ ;;
+ esac
+ if test -z "$func_to_host_pathlist_result" ; then
+ func_error "Could not determine the host path(s) corresponding to"
+ func_error " '$1'"
+ func_error "Continuing, but uninstalled executables may not work."
+ # Fallback. This may break if $1 contains DOS-style drive
+ # specifications. The fix is not to complicate the expression
+ # below, but for the user to provide a working wine installation
+ # with winepath so that path translation in the cross-to-mingw
+ # case works properly.
+ lt_replace_pathsep_nix_to_dos="s|:|;|g"
+ func_to_host_pathlist_result=`echo "$func_to_host_pathlist_tmp1" |\
+ $SED -e "$lt_replace_pathsep_nix_to_dos"`
+ fi
+ # Now, add the leading and trailing path separators back
+ case "$1" in
+ :* ) func_to_host_pathlist_result=";$func_to_host_pathlist_result"
+ ;;
+ esac
+ case "$1" in
+ *: ) func_to_host_pathlist_result="$func_to_host_pathlist_result;"
+ ;;
+ esac
+ ;;
+ esac
+ fi
+}
+# end: func_to_host_pathlist
+
+# func_emit_cwrapperexe_src
+# emit the source code for a wrapper executable on stdout
+# Must ONLY be called from within func_mode_link because
+# it depends on a number of variable set therein.
+func_emit_cwrapperexe_src ()
+{
+ cat <<EOF
+
+/* $cwrappersource - temporary wrapper executable for $objdir/$outputname
+ Generated by $PROGRAM (GNU $PACKAGE$TIMESTAMP) $VERSION
+
+ The $output program cannot be directly executed until all the libtool
+ libraries that it depends on are installed.
+
+ This wrapper executable should never be moved out of the build directory.
+ If it is, it will not operate correctly.
+
+ Currently, it simply execs the wrapper *script* "$SHELL $output",
+ but could eventually absorb all of the scripts functionality and
+ exec $objdir/$outputname directly.
+*/
+EOF
+ cat <<"EOF"
+#include <stdio.h>
+#include <stdlib.h>
+#ifdef _MSC_VER
+# include <direct.h>
+# include <process.h>
+# include <io.h>
+# define setmode _setmode
+#else
+# include <unistd.h>
+# include <stdint.h>
+# ifdef __CYGWIN__
+# include <io.h>
+# define HAVE_SETENV
+# ifdef __STRICT_ANSI__
+char *realpath (const char *, char *);
+int putenv (char *);
+int setenv (const char *, const char *, int);
+# endif
+# endif
+#endif
+#include <malloc.h>
+#include <stdarg.h>
+#include <assert.h>
+#include <string.h>
+#include <ctype.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <sys/stat.h>
+
+#if defined(PATH_MAX)
+# define LT_PATHMAX PATH_MAX
+#elif defined(MAXPATHLEN)
+# define LT_PATHMAX MAXPATHLEN
+#else
+# define LT_PATHMAX 1024
+#endif
+
+#ifndef S_IXOTH
+# define S_IXOTH 0
+#endif
+#ifndef S_IXGRP
+# define S_IXGRP 0
+#endif
+
+#ifdef _MSC_VER
+# define S_IXUSR _S_IEXEC
+# define stat _stat
+# ifndef _INTPTR_T_DEFINED
+# define intptr_t int
+# endif
+#endif
+
+#ifndef DIR_SEPARATOR
+# define DIR_SEPARATOR '/'
+# define PATH_SEPARATOR ':'
+#endif
+
+#if defined (_WIN32) || defined (__MSDOS__) || defined (__DJGPP__) || \
+ defined (__OS2__)
+# define HAVE_DOS_BASED_FILE_SYSTEM
+# define FOPEN_WB "wb"
+# ifndef DIR_SEPARATOR_2
+# define DIR_SEPARATOR_2 '\\'
+# endif
+# ifndef PATH_SEPARATOR_2
+# define PATH_SEPARATOR_2 ';'
+# endif
+#endif
+
+#ifndef DIR_SEPARATOR_2
+# define IS_DIR_SEPARATOR(ch) ((ch) == DIR_SEPARATOR)
+#else /* DIR_SEPARATOR_2 */
+# define IS_DIR_SEPARATOR(ch) \
+ (((ch) == DIR_SEPARATOR) || ((ch) == DIR_SEPARATOR_2))
+#endif /* DIR_SEPARATOR_2 */
+
+#ifndef PATH_SEPARATOR_2
+# define IS_PATH_SEPARATOR(ch) ((ch) == PATH_SEPARATOR)
+#else /* PATH_SEPARATOR_2 */
+# define IS_PATH_SEPARATOR(ch) ((ch) == PATH_SEPARATOR_2)
+#endif /* PATH_SEPARATOR_2 */
+
+#ifdef __CYGWIN__
+# define FOPEN_WB "wb"
+#endif
+
+#ifndef FOPEN_WB
+# define FOPEN_WB "w"
+#endif
+#ifndef _O_BINARY
+# define _O_BINARY 0
+#endif
+
+#define XMALLOC(type, num) ((type *) xmalloc ((num) * sizeof(type)))
+#define XFREE(stale) do { \
+ if (stale) { free ((void *) stale); stale = 0; } \
+} while (0)
+
+#undef LTWRAPPER_DEBUGPRINTF
+#if defined DEBUGWRAPPER
+# define LTWRAPPER_DEBUGPRINTF(args) ltwrapper_debugprintf args
+static void
+ltwrapper_debugprintf (const char *fmt, ...)
+{
+ va_list args;
+ va_start (args, fmt);
+ (void) vfprintf (stderr, fmt, args);
+ va_end (args);
+}
+#else
+# define LTWRAPPER_DEBUGPRINTF(args)
+#endif
+
+const char *program_name = NULL;
+
+void *xmalloc (size_t num);
+char *xstrdup (const char *string);
+const char *base_name (const char *name);
+char *find_executable (const char *wrapper);
+char *chase_symlinks (const char *pathspec);
+int make_executable (const char *path);
+int check_executable (const char *path);
+char *strendzap (char *str, const char *pat);
+void lt_fatal (const char *message, ...);
+void lt_setenv (const char *name, const char *value);
+char *lt_extend_str (const char *orig_value, const char *add, int to_end);
+void lt_opt_process_env_set (const char *arg);
+void lt_opt_process_env_prepend (const char *arg);
+void lt_opt_process_env_append (const char *arg);
+int lt_split_name_value (const char *arg, char** name, char** value);
+void lt_update_exe_path (const char *name, const char *value);
+void lt_update_lib_path (const char *name, const char *value);
+
+static const char *script_text_part1 =
+EOF
+
+ func_emit_wrapper_part1 yes |
+ $SED -e 's/\([\\"]\)/\\\1/g' \
+ -e 's/^/ "/' -e 's/$/\\n"/'
+ echo ";"
+ cat <<EOF
+
+static const char *script_text_part2 =
+EOF
+ func_emit_wrapper_part2 yes |
+ $SED -e 's/\([\\"]\)/\\\1/g' \
+ -e 's/^/ "/' -e 's/$/\\n"/'
+ echo ";"
+
+ cat <<EOF
+const char * MAGIC_EXE = "$magic_exe";
+const char * LIB_PATH_VARNAME = "$shlibpath_var";
+EOF
+
+ if test "$shlibpath_overrides_runpath" = yes && test -n "$shlibpath_var" && test -n "$temp_rpath"; then
+ func_to_host_pathlist "$temp_rpath"
+ cat <<EOF
+const char * LIB_PATH_VALUE = "$func_to_host_pathlist_result";
+EOF
+ else
+ cat <<"EOF"
+const char * LIB_PATH_VALUE = "";
+EOF
+ fi
+
+ if test -n "$dllsearchpath"; then
+ func_to_host_pathlist "$dllsearchpath:"
+ cat <<EOF
+const char * EXE_PATH_VARNAME = "PATH";
+const char * EXE_PATH_VALUE = "$func_to_host_pathlist_result";
+EOF
+ else
+ cat <<"EOF"
+const char * EXE_PATH_VARNAME = "";
+const char * EXE_PATH_VALUE = "";
+EOF
+ fi
+
+ if test "$fast_install" = yes; then
+ cat <<EOF
+const char * TARGET_PROGRAM_NAME = "lt-$outputname"; /* hopefully, no .exe */
+EOF
+ else
+ cat <<EOF
+const char * TARGET_PROGRAM_NAME = "$outputname"; /* hopefully, no .exe */
+EOF
+ fi
+
+
+ cat <<"EOF"
+
+#define LTWRAPPER_OPTION_PREFIX "--lt-"
+#define LTWRAPPER_OPTION_PREFIX_LENGTH 5
+
+static const size_t opt_prefix_len = LTWRAPPER_OPTION_PREFIX_LENGTH;
+static const char *ltwrapper_option_prefix = LTWRAPPER_OPTION_PREFIX;
+
+static const char *dumpscript_opt = LTWRAPPER_OPTION_PREFIX "dump-script";
+
+static const size_t env_set_opt_len = LTWRAPPER_OPTION_PREFIX_LENGTH + 7;
+static const char *env_set_opt = LTWRAPPER_OPTION_PREFIX "env-set";
+ /* argument is putenv-style "foo=bar", value of foo is set to bar */
+
+static const size_t env_prepend_opt_len = LTWRAPPER_OPTION_PREFIX_LENGTH + 11;
+static const char *env_prepend_opt = LTWRAPPER_OPTION_PREFIX "env-prepend";
+ /* argument is putenv-style "foo=bar", new value of foo is bar${foo} */
+
+static const size_t env_append_opt_len = LTWRAPPER_OPTION_PREFIX_LENGTH + 10;
+static const char *env_append_opt = LTWRAPPER_OPTION_PREFIX "env-append";
+ /* argument is putenv-style "foo=bar", new value of foo is ${foo}bar */
+
+int
+main (int argc, char *argv[])
+{
+ char **newargz;
+ int newargc;
+ char *tmp_pathspec;
+ char *actual_cwrapper_path;
+ char *actual_cwrapper_name;
+ char *target_name;
+ char *lt_argv_zero;
+ intptr_t rval = 127;
+
+ int i;
+
+ program_name = (char *) xstrdup (base_name (argv[0]));
+ LTWRAPPER_DEBUGPRINTF (("(main) argv[0] : %s\n", argv[0]));
+ LTWRAPPER_DEBUGPRINTF (("(main) program_name : %s\n", program_name));
+
+ /* very simple arg parsing; don't want to rely on getopt */
+ for (i = 1; i < argc; i++)
+ {
+ if (strcmp (argv[i], dumpscript_opt) == 0)
+ {
+EOF
+ case "$host" in
+ *mingw* | *cygwin* )
+ # make stdout use "unix" line endings
+ echo " setmode(1,_O_BINARY);"
+ ;;
+ esac
+
+ cat <<"EOF"
+ printf ("%s", script_text_part1);
+ printf ("%s", script_text_part2);
+ return 0;
+ }
+ }
+
+ newargz = XMALLOC (char *, argc + 1);
+ tmp_pathspec = find_executable (argv[0]);
+ if (tmp_pathspec == NULL)
+ lt_fatal ("Couldn't find %s", argv[0]);
+ LTWRAPPER_DEBUGPRINTF (("(main) found exe (before symlink chase) at : %s\n",
+ tmp_pathspec));
+
+ actual_cwrapper_path = chase_symlinks (tmp_pathspec);
+ LTWRAPPER_DEBUGPRINTF (("(main) found exe (after symlink chase) at : %s\n",
+ actual_cwrapper_path));
+ XFREE (tmp_pathspec);
+
+ actual_cwrapper_name = xstrdup( base_name (actual_cwrapper_path));
+ strendzap (actual_cwrapper_path, actual_cwrapper_name);
+
+ /* wrapper name transforms */
+ strendzap (actual_cwrapper_name, ".exe");
+ tmp_pathspec = lt_extend_str (actual_cwrapper_name, ".exe", 1);
+ XFREE (actual_cwrapper_name);
+ actual_cwrapper_name = tmp_pathspec;
+ tmp_pathspec = 0;
+
+ /* target_name transforms -- use actual target program name; might have lt- prefix */
+ target_name = xstrdup (base_name (TARGET_PROGRAM_NAME));
+ strendzap (target_name, ".exe");
+ tmp_pathspec = lt_extend_str (target_name, ".exe", 1);
+ XFREE (target_name);
+ target_name = tmp_pathspec;
+ tmp_pathspec = 0;
+
+ LTWRAPPER_DEBUGPRINTF (("(main) libtool target name: %s\n",
+ target_name));
+EOF
+
+ cat <<EOF
+ newargz[0] =
+ XMALLOC (char, (strlen (actual_cwrapper_path) +
+ strlen ("$objdir") + 1 + strlen (actual_cwrapper_name) + 1));
+ strcpy (newargz[0], actual_cwrapper_path);
+ strcat (newargz[0], "$objdir");
+ strcat (newargz[0], "/");
+EOF
+
+ cat <<"EOF"
+ /* stop here, and copy so we don't have to do this twice */
+ tmp_pathspec = xstrdup (newargz[0]);
+
+ /* do NOT want the lt- prefix here, so use actual_cwrapper_name */
+ strcat (newargz[0], actual_cwrapper_name);
+
+ /* DO want the lt- prefix here if it exists, so use target_name */
+ lt_argv_zero = lt_extend_str (tmp_pathspec, target_name, 1);
+ XFREE (tmp_pathspec);
+ tmp_pathspec = NULL;
+EOF
+
+ case $host_os in
+ mingw*)
+ cat <<"EOF"
+ {
+ char* p;
+ while ((p = strchr (newargz[0], '\\')) != NULL)
+ {
+ *p = '/';
+ }
+ while ((p = strchr (lt_argv_zero, '\\')) != NULL)
+ {
+ *p = '/';
+ }
+ }
+EOF
+ ;;
+ esac
+
+ cat <<"EOF"
+ XFREE (target_name);
+ XFREE (actual_cwrapper_path);
+ XFREE (actual_cwrapper_name);
+
+ lt_setenv ("BIN_SH", "xpg4"); /* for Tru64 */
+ lt_setenv ("DUALCASE", "1"); /* for MSK sh */
+ lt_update_lib_path (LIB_PATH_VARNAME, LIB_PATH_VALUE);
+ lt_update_exe_path (EXE_PATH_VARNAME, EXE_PATH_VALUE);
+
+ newargc=0;
+ for (i = 1; i < argc; i++)
+ {
+ if (strncmp (argv[i], env_set_opt, env_set_opt_len) == 0)
+ {
+ if (argv[i][env_set_opt_len] == '=')
+ {
+ const char *p = argv[i] + env_set_opt_len + 1;
+ lt_opt_process_env_set (p);
+ }
+ else if (argv[i][env_set_opt_len] == '\0' && i + 1 < argc)
+ {
+ lt_opt_process_env_set (argv[++i]); /* don't copy */
+ }
+ else
+ lt_fatal ("%s missing required argument", env_set_opt);
+ continue;
+ }
+ if (strncmp (argv[i], env_prepend_opt, env_prepend_opt_len) == 0)
+ {
+ if (argv[i][env_prepend_opt_len] == '=')
+ {
+ const char *p = argv[i] + env_prepend_opt_len + 1;
+ lt_opt_process_env_prepend (p);
+ }
+ else if (argv[i][env_prepend_opt_len] == '\0' && i + 1 < argc)
+ {
+ lt_opt_process_env_prepend (argv[++i]); /* don't copy */
+ }
+ else
+ lt_fatal ("%s missing required argument", env_prepend_opt);
+ continue;
+ }
+ if (strncmp (argv[i], env_append_opt, env_append_opt_len) == 0)
+ {
+ if (argv[i][env_append_opt_len] == '=')
+ {
+ const char *p = argv[i] + env_append_opt_len + 1;
+ lt_opt_process_env_append (p);
+ }
+ else if (argv[i][env_append_opt_len] == '\0' && i + 1 < argc)
+ {
+ lt_opt_process_env_append (argv[++i]); /* don't copy */
+ }
+ else
+ lt_fatal ("%s missing required argument", env_append_opt);
+ continue;
+ }
+ if (strncmp (argv[i], ltwrapper_option_prefix, opt_prefix_len) == 0)
+ {
+ /* however, if there is an option in the LTWRAPPER_OPTION_PREFIX
+ namespace, but it is not one of the ones we know about and
+ have already dealt with, above (inluding dump-script), then
+ report an error. Otherwise, targets might begin to believe
+ they are allowed to use options in the LTWRAPPER_OPTION_PREFIX
+ namespace. The first time any user complains about this, we'll
+ need to make LTWRAPPER_OPTION_PREFIX a configure-time option
+ or a configure.ac-settable value.
+ */
+ lt_fatal ("Unrecognized option in %s namespace: '%s'",
+ ltwrapper_option_prefix, argv[i]);
+ }
+ /* otherwise ... */
+ newargz[++newargc] = xstrdup (argv[i]);
+ }
+ newargz[++newargc] = NULL;
+
+ LTWRAPPER_DEBUGPRINTF (("(main) lt_argv_zero : %s\n", (lt_argv_zero ? lt_argv_zero : "<NULL>")));
+ for (i = 0; i < newargc; i++)
+ {
+ LTWRAPPER_DEBUGPRINTF (("(main) newargz[%d] : %s\n", i, (newargz[i] ? newargz[i] : "<NULL>")));
+ }
+
+EOF
+
+ case $host_os in
+ mingw*)
+ cat <<"EOF"
+ /* execv doesn't actually work on mingw as expected on unix */
+ rval = _spawnv (_P_WAIT, lt_argv_zero, (const char * const *) newargz);
+ if (rval == -1)
+ {
+ /* failed to start process */
+ LTWRAPPER_DEBUGPRINTF (("(main) failed to launch target \"%s\": errno = %d\n", lt_argv_zero, errno));
+ return 127;
+ }
+ return rval;
+EOF
+ ;;
+ *)
+ cat <<"EOF"
+ execv (lt_argv_zero, newargz);
+ return rval; /* =127, but avoids unused variable warning */
+EOF
+ ;;
+ esac
+
+ cat <<"EOF"
+}
+
+void *
+xmalloc (size_t num)
+{
+ void *p = (void *) malloc (num);
+ if (!p)
+ lt_fatal ("Memory exhausted");
+
+ return p;
+}
+
+char *
+xstrdup (const char *string)
+{
+ return string ? strcpy ((char *) xmalloc (strlen (string) + 1),
+ string) : NULL;
+}
+
+const char *
+base_name (const char *name)
+{
+ const char *base;
+
+#if defined (HAVE_DOS_BASED_FILE_SYSTEM)
+ /* Skip over the disk name in MSDOS pathnames. */
+ if (isalpha ((unsigned char) name[0]) && name[1] == ':')
+ name += 2;
+#endif
+
+ for (base = name; *name; name++)
+ if (IS_DIR_SEPARATOR (*name))
+ base = name + 1;
+ return base;
+}
+
+int
+check_executable (const char *path)
+{
+ struct stat st;
+
+ LTWRAPPER_DEBUGPRINTF (("(check_executable) : %s\n",
+ path ? (*path ? path : "EMPTY!") : "NULL!"));
+ if ((!path) || (!*path))
+ return 0;
+
+ if ((stat (path, &st) >= 0)
+ && (st.st_mode & (S_IXUSR | S_IXGRP | S_IXOTH)))
+ return 1;
+ else
+ return 0;
+}
+
+int
+make_executable (const char *path)
+{
+ int rval = 0;
+ struct stat st;
+
+ LTWRAPPER_DEBUGPRINTF (("(make_executable) : %s\n",
+ path ? (*path ? path : "EMPTY!") : "NULL!"));
+ if ((!path) || (!*path))
+ return 0;
+
+ if (stat (path, &st) >= 0)
+ {
+ rval = chmod (path, st.st_mode | S_IXOTH | S_IXGRP | S_IXUSR);
+ }
+ return rval;
+}
+
+/* Searches for the full path of the wrapper. Returns
+ newly allocated full path name if found, NULL otherwise
+ Does not chase symlinks, even on platforms that support them.
+*/
+char *
+find_executable (const char *wrapper)
+{
+ int has_slash = 0;
+ const char *p;
+ const char *p_next;
+ /* static buffer for getcwd */
+ char tmp[LT_PATHMAX + 1];
+ int tmp_len;
+ char *concat_name;
+
+ LTWRAPPER_DEBUGPRINTF (("(find_executable) : %s\n",
+ wrapper ? (*wrapper ? wrapper : "EMPTY!") : "NULL!"));
+
+ if ((wrapper == NULL) || (*wrapper == '\0'))
+ return NULL;
+
+ /* Absolute path? */
+#if defined (HAVE_DOS_BASED_FILE_SYSTEM)
+ if (isalpha ((unsigned char) wrapper[0]) && wrapper[1] == ':')
+ {
+ concat_name = xstrdup (wrapper);
+ if (check_executable (concat_name))
+ return concat_name;
+ XFREE (concat_name);
+ }
+ else
+ {
+#endif
+ if (IS_DIR_SEPARATOR (wrapper[0]))
+ {
+ concat_name = xstrdup (wrapper);
+ if (check_executable (concat_name))
+ return concat_name;
+ XFREE (concat_name);
+ }
+#if defined (HAVE_DOS_BASED_FILE_SYSTEM)
+ }
+#endif
+
+ for (p = wrapper; *p; p++)
+ if (*p == '/')
+ {
+ has_slash = 1;
+ break;
+ }
+ if (!has_slash)
+ {
+ /* no slashes; search PATH */
+ const char *path = getenv ("PATH");
+ if (path != NULL)
+ {
+ for (p = path; *p; p = p_next)
+ {
+ const char *q;
+ size_t p_len;
+ for (q = p; *q; q++)
+ if (IS_PATH_SEPARATOR (*q))
+ break;
+ p_len = q - p;
+ p_next = (*q == '\0' ? q : q + 1);
+ if (p_len == 0)
+ {
+ /* empty path: current directory */
+ if (getcwd (tmp, LT_PATHMAX) == NULL)
+ lt_fatal ("getcwd failed");
+ tmp_len = strlen (tmp);
+ concat_name =
+ XMALLOC (char, tmp_len + 1 + strlen (wrapper) + 1);
+ memcpy (concat_name, tmp, tmp_len);
+ concat_name[tmp_len] = '/';
+ strcpy (concat_name + tmp_len + 1, wrapper);
+ }
+ else
+ {
+ concat_name =
+ XMALLOC (char, p_len + 1 + strlen (wrapper) + 1);
+ memcpy (concat_name, p, p_len);
+ concat_name[p_len] = '/';
+ strcpy (concat_name + p_len + 1, wrapper);
+ }
+ if (check_executable (concat_name))
+ return concat_name;
+ XFREE (concat_name);
+ }
+ }
+ /* not found in PATH; assume curdir */
+ }
+ /* Relative path | not found in path: prepend cwd */
+ if (getcwd (tmp, LT_PATHMAX) == NULL)
+ lt_fatal ("getcwd failed");
+ tmp_len = strlen (tmp);
+ concat_name = XMALLOC (char, tmp_len + 1 + strlen (wrapper) + 1);
+ memcpy (concat_name, tmp, tmp_len);
+ concat_name[tmp_len] = '/';
+ strcpy (concat_name + tmp_len + 1, wrapper);
+
+ if (check_executable (concat_name))
+ return concat_name;
+ XFREE (concat_name);
+ return NULL;
+}
+
+char *
+chase_symlinks (const char *pathspec)
+{
+#ifndef S_ISLNK
+ return xstrdup (pathspec);
+#else
+ char buf[LT_PATHMAX];
+ struct stat s;
+ char *tmp_pathspec = xstrdup (pathspec);
+ char *p;
+ int has_symlinks = 0;
+ while (strlen (tmp_pathspec) && !has_symlinks)
+ {
+ LTWRAPPER_DEBUGPRINTF (("checking path component for symlinks: %s\n",
+ tmp_pathspec));
+ if (lstat (tmp_pathspec, &s) == 0)
+ {
+ if (S_ISLNK (s.st_mode) != 0)
+ {
+ has_symlinks = 1;
+ break;
+ }
+
+ /* search backwards for last DIR_SEPARATOR */
+ p = tmp_pathspec + strlen (tmp_pathspec) - 1;
+ while ((p > tmp_pathspec) && (!IS_DIR_SEPARATOR (*p)))
+ p--;
+ if ((p == tmp_pathspec) && (!IS_DIR_SEPARATOR (*p)))
+ {
+ /* no more DIR_SEPARATORS left */
+ break;
+ }
+ *p = '\0';
+ }
+ else
+ {
+ char *errstr = strerror (errno);
+ lt_fatal ("Error accessing file %s (%s)", tmp_pathspec, errstr);
+ }
+ }
+ XFREE (tmp_pathspec);
+
+ if (!has_symlinks)
+ {
+ return xstrdup (pathspec);
+ }
+
+ tmp_pathspec = realpath (pathspec, buf);
+ if (tmp_pathspec == 0)
+ {
+ lt_fatal ("Could not follow symlinks for %s", pathspec);
+ }
+ return xstrdup (tmp_pathspec);
+#endif
+}
+
+char *
+strendzap (char *str, const char *pat)
+{
+ size_t len, patlen;
+
+ assert (str != NULL);
+ assert (pat != NULL);
+
+ len = strlen (str);
+ patlen = strlen (pat);
+
+ if (patlen <= len)
+ {
+ str += len - patlen;
+ if (strcmp (str, pat) == 0)
+ *str = '\0';
+ }
+ return str;
+}
+
+static void
+lt_error_core (int exit_status, const char *mode,
+ const char *message, va_list ap)
+{
+ fprintf (stderr, "%s: %s: ", program_name, mode);
+ vfprintf (stderr, message, ap);
+ fprintf (stderr, ".\n");
+
+ if (exit_status >= 0)
+ exit (exit_status);
+}
+
+void
+lt_fatal (const char *message, ...)
+{
+ va_list ap;
+ va_start (ap, message);
+ lt_error_core (EXIT_FAILURE, "FATAL", message, ap);
+ va_end (ap);
+}
+
+void
+lt_setenv (const char *name, const char *value)
+{
+ LTWRAPPER_DEBUGPRINTF (("(lt_setenv) setting '%s' to '%s'\n",
+ (name ? name : "<NULL>"),
+ (value ? value : "<NULL>")));
+ {
+#ifdef HAVE_SETENV
+ /* always make a copy, for consistency with !HAVE_SETENV */
+ char *str = xstrdup (value);
+ setenv (name, str, 1);
+#else
+ int len = strlen (name) + 1 + strlen (value) + 1;
+ char *str = XMALLOC (char, len);
+ sprintf (str, "%s=%s", name, value);
+ if (putenv (str) != EXIT_SUCCESS)
+ {
+ XFREE (str);
+ }
+#endif
+ }
+}
+
+char *
+lt_extend_str (const char *orig_value, const char *add, int to_end)
+{
+ char *new_value;
+ if (orig_value && *orig_value)
+ {
+ int orig_value_len = strlen (orig_value);
+ int add_len = strlen (add);
+ new_value = XMALLOC (char, add_len + orig_value_len + 1);
+ if (to_end)
+ {
+ strcpy (new_value, orig_value);
+ strcpy (new_value + orig_value_len, add);
+ }
+ else
+ {
+ strcpy (new_value, add);
+ strcpy (new_value + add_len, orig_value);
+ }
+ }
+ else
+ {
+ new_value = xstrdup (add);
+ }
+ return new_value;
+}
+
+int
+lt_split_name_value (const char *arg, char** name, char** value)
+{
+ const char *p;
+ int len;
+ if (!arg || !*arg)
+ return 1;
+
+ p = strchr (arg, (int)'=');
+
+ if (!p)
+ return 1;
+
+ *value = xstrdup (++p);
+
+ len = strlen (arg) - strlen (*value);
+ *name = XMALLOC (char, len);
+ strncpy (*name, arg, len-1);
+ (*name)[len - 1] = '\0';
+
+ return 0;
+}
+
+void
+lt_opt_process_env_set (const char *arg)
+{
+ char *name = NULL;
+ char *value = NULL;
+
+ if (lt_split_name_value (arg, &name, &value) != 0)
+ {
+ XFREE (name);
+ XFREE (value);
+ lt_fatal ("bad argument for %s: '%s'", env_set_opt, arg);
+ }
+
+ lt_setenv (name, value);
+ XFREE (name);
+ XFREE (value);
+}
+
+void
+lt_opt_process_env_prepend (const char *arg)
+{
+ char *name = NULL;
+ char *value = NULL;
+ char *new_value = NULL;
+
+ if (lt_split_name_value (arg, &name, &value) != 0)
+ {
+ XFREE (name);
+ XFREE (value);
+ lt_fatal ("bad argument for %s: '%s'", env_prepend_opt, arg);
+ }
+
+ new_value = lt_extend_str (getenv (name), value, 0);
+ lt_setenv (name, new_value);
+ XFREE (new_value);
+ XFREE (name);
+ XFREE (value);
+}
+
+void
+lt_opt_process_env_append (const char *arg)
+{
+ char *name = NULL;
+ char *value = NULL;
+ char *new_value = NULL;
+
+ if (lt_split_name_value (arg, &name, &value) != 0)
+ {
+ XFREE (name);
+ XFREE (value);
+ lt_fatal ("bad argument for %s: '%s'", env_append_opt, arg);
+ }
+
+ new_value = lt_extend_str (getenv (name), value, 1);
+ lt_setenv (name, new_value);
+ XFREE (new_value);
+ XFREE (name);
+ XFREE (value);
+}
+
+void
+lt_update_exe_path (const char *name, const char *value)
+{
+ LTWRAPPER_DEBUGPRINTF (("(lt_update_exe_path) modifying '%s' by prepending '%s'\n",
+ (name ? name : "<NULL>"),
+ (value ? value : "<NULL>")));
+
+ if (name && *name && value && *value)
+ {
+ char *new_value = lt_extend_str (getenv (name), value, 0);
+ /* some systems can't cope with a ':'-terminated path #' */
+ int len = strlen (new_value);
+ while (((len = strlen (new_value)) > 0) && IS_PATH_SEPARATOR (new_value[len-1]))
+ {
+ new_value[len-1] = '\0';
+ }
+ lt_setenv (name, new_value);
+ XFREE (new_value);
+ }
+}
+
+void
+lt_update_lib_path (const char *name, const char *value)
+{
+ LTWRAPPER_DEBUGPRINTF (("(lt_update_lib_path) modifying '%s' by prepending '%s'\n",
+ (name ? name : "<NULL>"),
+ (value ? value : "<NULL>")));
+
+ if (name && *name && value && *value)
+ {
+ char *new_value = lt_extend_str (getenv (name), value, 0);
+ lt_setenv (name, new_value);
+ XFREE (new_value);
+ }
+}
+
+
+EOF
+}
+# end: func_emit_cwrapperexe_src
+
+# func_mode_link arg...
+func_mode_link ()
+{
+ $opt_debug
+ case $host in
+ *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2* | *-cegcc*)
+ # It is impossible to link a dll without this setting, and
+ # we shouldn't force the makefile maintainer to figure out
+ # which system we are compiling for in order to pass an extra
+ # flag for every libtool invocation.
+ # allow_undefined=no
+
+ # FIXME: Unfortunately, there are problems with the above when trying
+ # to make a dll which has undefined symbols, in which case not
+ # even a static library is built. For now, we need to specify
+ # -no-undefined on the libtool link line when we can be certain
+ # that all symbols are satisfied, otherwise we get a static library.
+ allow_undefined=yes
+ ;;
+ *)
+ allow_undefined=yes
+ ;;
+ esac
+ libtool_args=$nonopt
+ base_compile="$nonopt $@"
+ compile_command=$nonopt
+ finalize_command=$nonopt
+
+ compile_rpath=
+ finalize_rpath=
+ compile_shlibpath=
+ finalize_shlibpath=
+ convenience=
+ old_convenience=
+ deplibs=
+ old_deplibs=
+ compiler_flags=
+ linker_flags=
+ dllsearchpath=
+ lib_search_path=`pwd`
+ inst_prefix_dir=
+ new_inherited_linker_flags=
+
+ avoid_version=no
+ dlfiles=
+ dlprefiles=
+ dlself=no
+ export_dynamic=no
+ export_symbols=
+ export_symbols_regex=
+ generated=
+ libobjs=
+ ltlibs=
+ module=no
+ no_install=no
+ objs=
+ non_pic_objects=
+ precious_files_regex=
+ prefer_static_libs=no
+ preload=no
+ prev=
+ prevarg=
+ release=
+ rpath=
+ xrpath=
+ perm_rpath=
+ temp_rpath=
+ thread_safe=no
+ vinfo=
+ vinfo_number=no
+ weak_libs=
+ single_module="${wl}-single_module"
+ func_infer_tag $base_compile
+
+ # We need to know -static, to get the right output filenames.
+ for arg
+ do
+ case $arg in
+ -shared)
+ test "$build_libtool_libs" != yes && \
+ func_fatal_configuration "can not build a shared library"
+ build_old_libs=no
+ break
+ ;;
+ -all-static | -static | -static-libtool-libs)
+ case $arg in
+ -all-static)
+ if test "$build_libtool_libs" = yes && test -z "$link_static_flag"; then
+ func_warning "complete static linking is impossible in this configuration"
+ fi
+ if test -n "$link_static_flag"; then
+ dlopen_self=$dlopen_self_static
+ fi
+ prefer_static_libs=yes
+ ;;
+ -static)
+ if test -z "$pic_flag" && test -n "$link_static_flag"; then
+ dlopen_self=$dlopen_self_static
+ fi
+ prefer_static_libs=built
+ ;;
+ -static-libtool-libs)
+ if test -z "$pic_flag" && test -n "$link_static_flag"; then
+ dlopen_self=$dlopen_self_static
+ fi
+ prefer_static_libs=yes
+ ;;
+ esac
+ build_libtool_libs=no
+ build_old_libs=yes
+ break
+ ;;
+ esac
+ done
+
+ # See if our shared archives depend on static archives.
+ test -n "$old_archive_from_new_cmds" && build_old_libs=yes
+
+ # Go through the arguments, transforming them on the way.
+ while test "$#" -gt 0; do
+ arg="$1"
+ shift
+ func_quote_for_eval "$arg"
+ qarg=$func_quote_for_eval_unquoted_result
+ func_append libtool_args " $func_quote_for_eval_result"
+
+ # If the previous option needs an argument, assign it.
+ if test -n "$prev"; then
+ case $prev in
+ output)
+ func_append compile_command " @OUTPUT@"
+ func_append finalize_command " @OUTPUT@"
+ ;;
+ esac
+
+ case $prev in
+ dlfiles|dlprefiles)
+ if test "$preload" = no; then
+ # Add the symbol object into the linking commands.
+ func_append compile_command " @SYMFILE@"
+ func_append finalize_command " @SYMFILE@"
+ preload=yes
+ fi
+ case $arg in
+ *.la | *.lo) ;; # We handle these cases below.
+ force)
+ if test "$dlself" = no; then
+ dlself=needless
+ export_dynamic=yes
+ fi
+ prev=
+ continue
+ ;;
+ self)
+ if test "$prev" = dlprefiles; then
+ dlself=yes
+ elif test "$prev" = dlfiles && test "$dlopen_self" != yes; then
+ dlself=yes
+ else
+ dlself=needless
+ export_dynamic=yes
+ fi
+ prev=
+ continue
+ ;;
+ *)
+ if test "$prev" = dlfiles; then
+ dlfiles="$dlfiles $arg"
+ else
+ dlprefiles="$dlprefiles $arg"
+ fi
+ prev=
+ continue
+ ;;
+ esac
+ ;;
+ expsyms)
+ export_symbols="$arg"
+ test -f "$arg" \
+ || func_fatal_error "symbol file \`$arg' does not exist"
+ prev=
+ continue
+ ;;
+ expsyms_regex)
+ export_symbols_regex="$arg"
+ prev=
+ continue
+ ;;
+ framework)
+ case $host in
+ *-*-darwin*)
+ case "$deplibs " in
+ *" $qarg.ltframework "*) ;;
+ *) deplibs="$deplibs $qarg.ltframework" # this is fixed later
+ ;;
+ esac
+ ;;
+ esac
+ prev=
+ continue
+ ;;
+ inst_prefix)
+ inst_prefix_dir="$arg"
+ prev=
+ continue
+ ;;
+ objectlist)
+ if test -f "$arg"; then
+ save_arg=$arg
+ moreargs=
+ for fil in `cat "$save_arg"`
+ do
+# moreargs="$moreargs $fil"
+ arg=$fil
+ # A libtool-controlled object.
+
+ # Check to see that this really is a libtool object.
+ if func_lalib_unsafe_p "$arg"; then
+ pic_object=
+ non_pic_object=
+
+ # Read the .lo file
+ func_source "$arg"
+
+ if test -z "$pic_object" ||
+ test -z "$non_pic_object" ||
+ test "$pic_object" = none &&
+ test "$non_pic_object" = none; then
+ func_fatal_error "cannot find name of object for \`$arg'"
+ fi
+
+ # Extract subdirectory from the argument.
+ func_dirname "$arg" "/" ""
+ xdir="$func_dirname_result"
+
+ if test "$pic_object" != none; then
+ # Prepend the subdirectory the object is found in.
+ pic_object="$xdir$pic_object"
+
+ if test "$prev" = dlfiles; then
+ if test "$build_libtool_libs" = yes && test "$dlopen_support" = yes; then
+ dlfiles="$dlfiles $pic_object"
+ prev=
+ continue
+ else
+ # If libtool objects are unsupported, then we need to preload.
+ prev=dlprefiles
+ fi
+ fi
+
+ # CHECK ME: I think I busted this. -Ossama
+ if test "$prev" = dlprefiles; then
+ # Preload the old-style object.
+ dlprefiles="$dlprefiles $pic_object"
+ prev=
+ fi
+
+ # A PIC object.
+ func_append libobjs " $pic_object"
+ arg="$pic_object"
+ fi
+
+ # Non-PIC object.
+ if test "$non_pic_object" != none; then
+ # Prepend the subdirectory the object is found in.
+ non_pic_object="$xdir$non_pic_object"
+
+ # A standard non-PIC object
+ func_append non_pic_objects " $non_pic_object"
+ if test -z "$pic_object" || test "$pic_object" = none ; then
+ arg="$non_pic_object"
+ fi
+ else
+ # If the PIC object exists, use it instead.
+ # $xdir was prepended to $pic_object above.
+ non_pic_object="$pic_object"
+ func_append non_pic_objects " $non_pic_object"
+ fi
+ else
+ # Only an error if not doing a dry-run.
+ if $opt_dry_run; then
+ # Extract subdirectory from the argument.
+ func_dirname "$arg" "/" ""
+ xdir="$func_dirname_result"
+
+ func_lo2o "$arg"
+ pic_object=$xdir$objdir/$func_lo2o_result
+ non_pic_object=$xdir$func_lo2o_result
+ func_append libobjs " $pic_object"
+ func_append non_pic_objects " $non_pic_object"
+ else
+ func_fatal_error "\`$arg' is not a valid libtool object"
+ fi
+ fi
+ done
+ else
+ func_fatal_error "link input file \`$arg' does not exist"
+ fi
+ arg=$save_arg
+ prev=
+ continue
+ ;;
+ precious_regex)
+ precious_files_regex="$arg"
+ prev=
+ continue
+ ;;
+ release)
+ release="-$arg"
+ prev=
+ continue
+ ;;
+ rpath | xrpath)
+ # We need an absolute path.
+ case $arg in
+ [\\/]* | [A-Za-z]:[\\/]*) ;;
+ *)
+ func_fatal_error "only absolute run-paths are allowed"
+ ;;
+ esac
+ if test "$prev" = rpath; then
+ case "$rpath " in
+ *" $arg "*) ;;
+ *) rpath="$rpath $arg" ;;
+ esac
+ else
+ case "$xrpath " in
+ *" $arg "*) ;;
+ *) xrpath="$xrpath $arg" ;;
+ esac
+ fi
+ prev=
+ continue
+ ;;
+ shrext)
+ shrext_cmds="$arg"
+ prev=
+ continue
+ ;;
+ weak)
+ weak_libs="$weak_libs $arg"
+ prev=
+ continue
+ ;;
+ xcclinker)
+ linker_flags="$linker_flags $qarg"
+ compiler_flags="$compiler_flags $qarg"
+ prev=
+ func_append compile_command " $qarg"
+ func_append finalize_command " $qarg"
+ continue
+ ;;
+ xcompiler)
+ compiler_flags="$compiler_flags $qarg"
+ prev=
+ func_append compile_command " $qarg"
+ func_append finalize_command " $qarg"
+ continue
+ ;;
+ xlinker)
+ linker_flags="$linker_flags $qarg"
+ compiler_flags="$compiler_flags $wl$qarg"
+ prev=
+ func_append compile_command " $wl$qarg"
+ func_append finalize_command " $wl$qarg"
+ continue
+ ;;
+ *)
+ eval "$prev=\"\$arg\""
+ prev=
+ continue
+ ;;
+ esac
+ fi # test -n "$prev"
+
+ prevarg="$arg"
+
+ case $arg in
+ -all-static)
+ if test -n "$link_static_flag"; then
+ # See comment for -static flag below, for more details.
+ func_append compile_command " $link_static_flag"
+ func_append finalize_command " $link_static_flag"
+ fi
+ continue
+ ;;
+
+ -allow-undefined)
+ # FIXME: remove this flag sometime in the future.
+ func_fatal_error "\`-allow-undefined' must not be used because it is the default"
+ ;;
+
+ -avoid-version)
+ avoid_version=yes
+ continue
+ ;;
+
+ -dlopen)
+ prev=dlfiles
+ continue
+ ;;
+
+ -dlpreopen)
+ prev=dlprefiles
+ continue
+ ;;
+
+ -export-dynamic)
+ export_dynamic=yes
+ continue
+ ;;
+
+ -export-symbols | -export-symbols-regex)
+ if test -n "$export_symbols" || test -n "$export_symbols_regex"; then
+ func_fatal_error "more than one -exported-symbols argument is not allowed"
+ fi
+ if test "X$arg" = "X-export-symbols"; then
+ prev=expsyms
+ else
+ prev=expsyms_regex
+ fi
+ continue
+ ;;
+
+ -framework)
+ prev=framework
+ continue
+ ;;
+
+ -inst-prefix-dir)
+ prev=inst_prefix
+ continue
+ ;;
+
+ # The native IRIX linker understands -LANG:*, -LIST:* and -LNO:*
+ # so, if we see these flags be careful not to treat them like -L
+ -L[A-Z][A-Z]*:*)
+ case $with_gcc/$host in
+ no/*-*-irix* | /*-*-irix*)
+ func_append compile_command " $arg"
+ func_append finalize_command " $arg"
+ ;;
+ esac
+ continue
+ ;;
+
+ -L*)
+ func_stripname '-L' '' "$arg"
+ dir=$func_stripname_result
+ if test -z "$dir"; then
+ if test "$#" -gt 0; then
+ func_fatal_error "require no space between \`-L' and \`$1'"
+ else
+ func_fatal_error "need path for \`-L' option"
+ fi
+ fi
+ # We need an absolute path.
+ case $dir in
+ [\\/]* | [A-Za-z]:[\\/]*) ;;
+ *)
+ absdir=`cd "$dir" && pwd`
+ test -z "$absdir" && \
+ func_fatal_error "cannot determine absolute directory name of \`$dir'"
+ dir="$absdir"
+ ;;
+ esac
+ case "$deplibs " in
+ *" -L$dir "*) ;;
+ *)
+ deplibs="$deplibs -L$dir"
+ lib_search_path="$lib_search_path $dir"
+ ;;
+ esac
+ case $host in
+ *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2* | *-cegcc*)
+ testbindir=`$ECHO "X$dir" | $Xsed -e 's*/lib$*/bin*'`
+ case :$dllsearchpath: in
+ *":$dir:"*) ;;
+ ::) dllsearchpath=$dir;;
+ *) dllsearchpath="$dllsearchpath:$dir";;
+ esac
+ case :$dllsearchpath: in
+ *":$testbindir:"*) ;;
+ ::) dllsearchpath=$testbindir;;
+ *) dllsearchpath="$dllsearchpath:$testbindir";;
+ esac
+ ;;
+ esac
+ continue
+ ;;
+
+ -l*)
+ if test "X$arg" = "X-lc" || test "X$arg" = "X-lm"; then
+ case $host in
+ *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-beos* | *-cegcc*)
+ # These systems don't actually have a C or math library (as such)
+ continue
+ ;;
+ *-*-os2*)
+ # These systems don't actually have a C library (as such)
+ test "X$arg" = "X-lc" && continue
+ ;;
+ *-*-openbsd* | *-*-freebsd* | *-*-dragonfly*)
+ # Do not include libc due to us having libc/libc_r.
+ test "X$arg" = "X-lc" && continue
+ ;;
+ *-*-rhapsody* | *-*-darwin1.[012])
+ # Rhapsody C and math libraries are in the System framework
+ deplibs="$deplibs System.ltframework"
+ continue
+ ;;
+ *-*-sco3.2v5* | *-*-sco5v6*)
+ # Causes problems with __ctype
+ test "X$arg" = "X-lc" && continue
+ ;;
+ *-*-sysv4.2uw2* | *-*-sysv5* | *-*-unixware* | *-*-OpenUNIX*)
+ # Compiler inserts libc in the correct place for threads to work
+ test "X$arg" = "X-lc" && continue
+ ;;
+ esac
+ elif test "X$arg" = "X-lc_r"; then
+ case $host in
+ *-*-openbsd* | *-*-freebsd* | *-*-dragonfly*)
+ # Do not include libc_r directly, use -pthread flag.
+ continue
+ ;;
+ esac
+ fi
+ deplibs="$deplibs $arg"
+ continue
+ ;;
+
+ -module)
+ module=yes
+ continue
+ ;;
+
+ # Tru64 UNIX uses -model [arg] to determine the layout of C++
+ # classes, name mangling, and exception handling.
+ # Darwin uses the -arch flag to determine output architecture.
+ -model|-arch|-isysroot)
+ compiler_flags="$compiler_flags $arg"
+ func_append compile_command " $arg"
+ func_append finalize_command " $arg"
+ prev=xcompiler
+ continue
+ ;;
+
+ -mt|-mthreads|-kthread|-Kthread|-pthread|-pthreads|--thread-safe|-threads)
+ compiler_flags="$compiler_flags $arg"
+ func_append compile_command " $arg"
+ func_append finalize_command " $arg"
+ case "$new_inherited_linker_flags " in
+ *" $arg "*) ;;
+ * ) new_inherited_linker_flags="$new_inherited_linker_flags $arg" ;;
+ esac
+ continue
+ ;;
+
+ -multi_module)
+ single_module="${wl}-multi_module"
+ continue
+ ;;
+
+ -no-fast-install)
+ fast_install=no
+ continue
+ ;;
+
+ -no-install)
+ case $host in
+ *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2* | *-*-darwin* | *-cegcc*)
+ # The PATH hackery in wrapper scripts is required on Windows
+ # and Darwin in order for the loader to find any dlls it needs.
+ func_warning "\`-no-install' is ignored for $host"
+ func_warning "assuming \`-no-fast-install' instead"
+ fast_install=no
+ ;;
+ *) no_install=yes ;;
+ esac
+ continue
+ ;;
+
+ -no-undefined)
+ allow_undefined=no
+ continue
+ ;;
+
+ -objectlist)
+ prev=objectlist
+ continue
+ ;;
+
+ -o) prev=output ;;
+
+ -precious-files-regex)
+ prev=precious_regex
+ continue
+ ;;
+
+ -release)
+ prev=release
+ continue
+ ;;
+
+ -rpath)
+ prev=rpath
+ continue
+ ;;
+
+ -R)
+ prev=xrpath
+ continue
+ ;;
+
+ -R*)
+ func_stripname '-R' '' "$arg"
+ dir=$func_stripname_result
+ # We need an absolute path.
+ case $dir in
+ [\\/]* | [A-Za-z]:[\\/]*) ;;
+ *)
+ func_fatal_error "only absolute run-paths are allowed"
+ ;;
+ esac
+ case "$xrpath " in
+ *" $dir "*) ;;
+ *) xrpath="$xrpath $dir" ;;
+ esac
+ continue
+ ;;
+
+ -shared)
+ # The effects of -shared are defined in a previous loop.
+ continue
+ ;;
+
+ -shrext)
+ prev=shrext
+ continue
+ ;;
+
+ -static | -static-libtool-libs)
+ # The effects of -static are defined in a previous loop.
+ # We used to do the same as -all-static on platforms that
+ # didn't have a PIC flag, but the assumption that the effects
+ # would be equivalent was wrong. It would break on at least
+ # Digital Unix and AIX.
+ continue
+ ;;
+
+ -thread-safe)
+ thread_safe=yes
+ continue
+ ;;
+
+ -version-info)
+ prev=vinfo
+ continue
+ ;;
+
+ -version-number)
+ prev=vinfo
+ vinfo_number=yes
+ continue
+ ;;
+
+ -weak)
+ prev=weak
+ continue
+ ;;
+
+ -Wc,*)
+ func_stripname '-Wc,' '' "$arg"
+ args=$func_stripname_result
+ arg=
+ save_ifs="$IFS"; IFS=','
+ for flag in $args; do
+ IFS="$save_ifs"
+ func_quote_for_eval "$flag"
+ arg="$arg $wl$func_quote_for_eval_result"
+ compiler_flags="$compiler_flags $func_quote_for_eval_result"
+ done
+ IFS="$save_ifs"
+ func_stripname ' ' '' "$arg"
+ arg=$func_stripname_result
+ ;;
+
+ -Wl,*)
+ func_stripname '-Wl,' '' "$arg"
+ args=$func_stripname_result
+ arg=
+ save_ifs="$IFS"; IFS=','
+ for flag in $args; do
+ IFS="$save_ifs"
+ func_quote_for_eval "$flag"
+ arg="$arg $wl$func_quote_for_eval_result"
+ compiler_flags="$compiler_flags $wl$func_quote_for_eval_result"
+ linker_flags="$linker_flags $func_quote_for_eval_result"
+ done
+ IFS="$save_ifs"
+ func_stripname ' ' '' "$arg"
+ arg=$func_stripname_result
+ ;;
+
+ -Xcompiler)
+ prev=xcompiler
+ continue
+ ;;
+
+ -Xlinker)
+ prev=xlinker
+ continue
+ ;;
+
+ -XCClinker)
+ prev=xcclinker
+ continue
+ ;;
+
+ # -msg_* for osf cc
+ -msg_*)
+ func_quote_for_eval "$arg"
+ arg="$func_quote_for_eval_result"
+ ;;
+
+ # -64, -mips[0-9] enable 64-bit mode on the SGI compiler
+ # -r[0-9][0-9]* specifies the processor on the SGI compiler
+ # -xarch=*, -xtarget=* enable 64-bit mode on the Sun compiler
+ # +DA*, +DD* enable 64-bit mode on the HP compiler
+ # -q* pass through compiler args for the IBM compiler
+ # -m*, -t[45]*, -txscale* pass through architecture-specific
+ # compiler args for GCC
+ # -F/path gives path to uninstalled frameworks, gcc on darwin
+ # -p, -pg, --coverage, -fprofile-* pass through profiling flag for GCC
+ # @file GCC response files
+ -64|-mips[0-9]|-r[0-9][0-9]*|-xarch=*|-xtarget=*|+DA*|+DD*|-q*|-m*| \
+ -t[45]*|-txscale*|-p|-pg|--coverage|-fprofile-*|-F*|@*)
+ func_quote_for_eval "$arg"
+ arg="$func_quote_for_eval_result"
+ func_append compile_command " $arg"
+ func_append finalize_command " $arg"
+ compiler_flags="$compiler_flags $arg"
+ continue
+ ;;
+
+ # Some other compiler flag.
+ -* | +*)
+ func_quote_for_eval "$arg"
+ arg="$func_quote_for_eval_result"
+ ;;
+
+ *.$objext)
+ # A standard object.
+ objs="$objs $arg"
+ ;;
+
+ *.lo)
+ # A libtool-controlled object.
+
+ # Check to see that this really is a libtool object.
+ if func_lalib_unsafe_p "$arg"; then
+ pic_object=
+ non_pic_object=
+
+ # Read the .lo file
+ func_source "$arg"
+
+ if test -z "$pic_object" ||
+ test -z "$non_pic_object" ||
+ test "$pic_object" = none &&
+ test "$non_pic_object" = none; then
+ func_fatal_error "cannot find name of object for \`$arg'"
+ fi
+
+ # Extract subdirectory from the argument.
+ func_dirname "$arg" "/" ""
+ xdir="$func_dirname_result"
+
+ if test "$pic_object" != none; then
+ # Prepend the subdirectory the object is found in.
+ pic_object="$xdir$pic_object"
+
+ if test "$prev" = dlfiles; then
+ if test "$build_libtool_libs" = yes && test "$dlopen_support" = yes; then
+ dlfiles="$dlfiles $pic_object"
+ prev=
+ continue
+ else
+ # If libtool objects are unsupported, then we need to preload.
+ prev=dlprefiles
+ fi
+ fi
+
+ # CHECK ME: I think I busted this. -Ossama
+ if test "$prev" = dlprefiles; then
+ # Preload the old-style object.
+ dlprefiles="$dlprefiles $pic_object"
+ prev=
+ fi
+
+ # A PIC object.
+ func_append libobjs " $pic_object"
+ arg="$pic_object"
+ fi
+
+ # Non-PIC object.
+ if test "$non_pic_object" != none; then
+ # Prepend the subdirectory the object is found in.
+ non_pic_object="$xdir$non_pic_object"
+
+ # A standard non-PIC object
+ func_append non_pic_objects " $non_pic_object"
+ if test -z "$pic_object" || test "$pic_object" = none ; then
+ arg="$non_pic_object"
+ fi
+ else
+ # If the PIC object exists, use it instead.
+ # $xdir was prepended to $pic_object above.
+ non_pic_object="$pic_object"
+ func_append non_pic_objects " $non_pic_object"
+ fi
+ else
+ # Only an error if not doing a dry-run.
+ if $opt_dry_run; then
+ # Extract subdirectory from the argument.
+ func_dirname "$arg" "/" ""
+ xdir="$func_dirname_result"
+
+ func_lo2o "$arg"
+ pic_object=$xdir$objdir/$func_lo2o_result
+ non_pic_object=$xdir$func_lo2o_result
+ func_append libobjs " $pic_object"
+ func_append non_pic_objects " $non_pic_object"
+ else
+ func_fatal_error "\`$arg' is not a valid libtool object"
+ fi
+ fi
+ ;;
+
+ *.$libext)
+ # An archive.
+ deplibs="$deplibs $arg"
+ old_deplibs="$old_deplibs $arg"
+ continue
+ ;;
+
+ *.la)
+ # A libtool-controlled library.
+
+ if test "$prev" = dlfiles; then
+ # This library was specified with -dlopen.
+ dlfiles="$dlfiles $arg"
+ prev=
+ elif test "$prev" = dlprefiles; then
+ # The library was specified with -dlpreopen.
+ dlprefiles="$dlprefiles $arg"
+ prev=
+ else
+ deplibs="$deplibs $arg"
+ fi
+ continue
+ ;;
+
+ # Some other compiler argument.
+ *)
+ # Unknown arguments in both finalize_command and compile_command need
+ # to be aesthetically quoted because they are evaled later.
+ func_quote_for_eval "$arg"
+ arg="$func_quote_for_eval_result"
+ ;;
+ esac # arg
+
+ # Now actually substitute the argument into the commands.
+ if test -n "$arg"; then
+ func_append compile_command " $arg"
+ func_append finalize_command " $arg"
+ fi
+ done # argument parsing loop
+
+ test -n "$prev" && \
+ func_fatal_help "the \`$prevarg' option requires an argument"
+
+ if test "$export_dynamic" = yes && test -n "$export_dynamic_flag_spec"; then
+ eval arg=\"$export_dynamic_flag_spec\"
+ func_append compile_command " $arg"
+ func_append finalize_command " $arg"
+ fi
+
+ oldlibs=
+ # calculate the name of the file, without its directory
+ func_basename "$output"
+ outputname="$func_basename_result"
+ libobjs_save="$libobjs"
+
+ if test -n "$shlibpath_var"; then
+ # get the directories listed in $shlibpath_var
+ eval shlib_search_path=\`\$ECHO \"X\${$shlibpath_var}\" \| \$Xsed -e \'s/:/ /g\'\`
+ else
+ shlib_search_path=
+ fi
+ eval sys_lib_search_path=\"$sys_lib_search_path_spec\"
+ eval sys_lib_dlsearch_path=\"$sys_lib_dlsearch_path_spec\"
+
+ func_dirname "$output" "/" ""
+ output_objdir="$func_dirname_result$objdir"
+ # Create the object directory.
+ func_mkdir_p "$output_objdir"
+
+ # Determine the type of output
+ case $output in
+ "")
+ func_fatal_help "you must specify an output file"
+ ;;
+ *.$libext) linkmode=oldlib ;;
+ *.lo | *.$objext) linkmode=obj ;;
+ *.la) linkmode=lib ;;
+ *) linkmode=prog ;; # Anything else should be a program.
+ esac
+
+ specialdeplibs=
+
+ libs=
+ # Find all interdependent deplibs by searching for libraries
+ # that are linked more than once (e.g. -la -lb -la)
+ for deplib in $deplibs; do
+ if $opt_duplicate_deps ; then
+ case "$libs " in
+ *" $deplib "*) specialdeplibs="$specialdeplibs $deplib" ;;
+ esac
+ fi
+ libs="$libs $deplib"
+ done
+
+ if test "$linkmode" = lib; then
+ libs="$predeps $libs $compiler_lib_search_path $postdeps"
+
+ # Compute libraries that are listed more than once in $predeps
+ # $postdeps and mark them as special (i.e., whose duplicates are
+ # not to be eliminated).
+ pre_post_deps=
+ if $opt_duplicate_compiler_generated_deps; then
+ for pre_post_dep in $predeps $postdeps; do
+ case "$pre_post_deps " in
+ *" $pre_post_dep "*) specialdeplibs="$specialdeplibs $pre_post_deps" ;;
+ esac
+ pre_post_deps="$pre_post_deps $pre_post_dep"
+ done
+ fi
+ pre_post_deps=
+ fi
+
+ deplibs=
+ newdependency_libs=
+ newlib_search_path=
+ need_relink=no # whether we're linking any uninstalled libtool libraries
+ notinst_deplibs= # not-installed libtool libraries
+ notinst_path= # paths that contain not-installed libtool libraries
+
+ case $linkmode in
+ lib)
+ passes="conv dlpreopen link"
+ for file in $dlfiles $dlprefiles; do
+ case $file in
+ *.la) ;;
+ *)
+ func_fatal_help "libraries can \`-dlopen' only libtool libraries: $file"
+ ;;
+ esac
+ done
+ ;;
+ prog)
+ compile_deplibs=
+ finalize_deplibs=
+ alldeplibs=no
+ newdlfiles=
+ newdlprefiles=
+ passes="conv scan dlopen dlpreopen link"
+ ;;
+ *) passes="conv"
+ ;;
+ esac
+
+ for pass in $passes; do
+ # The preopen pass in lib mode reverses $deplibs; put it back here
+ # so that -L comes before libs that need it for instance...
+ if test "$linkmode,$pass" = "lib,link"; then
+ ## FIXME: Find the place where the list is rebuilt in the wrong
+ ## order, and fix it there properly
+ tmp_deplibs=
+ for deplib in $deplibs; do
+ tmp_deplibs="$deplib $tmp_deplibs"
+ done
+ deplibs="$tmp_deplibs"
+ fi
+
+ if test "$linkmode,$pass" = "lib,link" ||
+ test "$linkmode,$pass" = "prog,scan"; then
+ libs="$deplibs"
+ deplibs=
+ fi
+ if test "$linkmode" = prog; then
+ case $pass in
+ dlopen) libs="$dlfiles" ;;
+ dlpreopen) libs="$dlprefiles" ;;
+ link)
+ libs="$deplibs %DEPLIBS%"
+ test "X$link_all_deplibs" != Xno && libs="$libs $dependency_libs"
+ ;;
+ esac
+ fi
+ if test "$linkmode,$pass" = "lib,dlpreopen"; then
+ # Collect and forward deplibs of preopened libtool libs
+ for lib in $dlprefiles; do
+ # Ignore non-libtool-libs
+ dependency_libs=
+ case $lib in
+ *.la) func_source "$lib" ;;
+ esac
+
+ # Collect preopened libtool deplibs, except any this library
+ # has declared as weak libs
+ for deplib in $dependency_libs; do
+ deplib_base=`$ECHO "X$deplib" | $Xsed -e "$basename"`
+ case " $weak_libs " in
+ *" $deplib_base "*) ;;
+ *) deplibs="$deplibs $deplib" ;;
+ esac
+ done
+ done
+ libs="$dlprefiles"
+ fi
+ if test "$pass" = dlopen; then
+ # Collect dlpreopened libraries
+ save_deplibs="$deplibs"
+ deplibs=
+ fi
+
+ for deplib in $libs; do
+ lib=
+ found=no
+ case $deplib in
+ -mt|-mthreads|-kthread|-Kthread|-pthread|-pthreads|--thread-safe|-threads)
+ if test "$linkmode,$pass" = "prog,link"; then
+ compile_deplibs="$deplib $compile_deplibs"
+ finalize_deplibs="$deplib $finalize_deplibs"
+ else
+ compiler_flags="$compiler_flags $deplib"
+ if test "$linkmode" = lib ; then
+ case "$new_inherited_linker_flags " in
+ *" $deplib "*) ;;
+ * ) new_inherited_linker_flags="$new_inherited_linker_flags $deplib" ;;
+ esac
+ fi
+ fi
+ continue
+ ;;
+ -l*)
+ if test "$linkmode" != lib && test "$linkmode" != prog; then
+ func_warning "\`-l' is ignored for archives/objects"
+ continue
+ fi
+ func_stripname '-l' '' "$deplib"
+ name=$func_stripname_result
+ if test "$linkmode" = lib; then
+ searchdirs="$newlib_search_path $lib_search_path $compiler_lib_search_dirs $sys_lib_search_path $shlib_search_path"
+ else
+ searchdirs="$newlib_search_path $lib_search_path $sys_lib_search_path $shlib_search_path"
+ fi
+ for searchdir in $searchdirs; do
+ for search_ext in .la $std_shrext .so .a; do
+ # Search the libtool library
+ lib="$searchdir/lib${name}${search_ext}"
+ if test -f "$lib"; then
+ if test "$search_ext" = ".la"; then
+ found=yes
+ else
+ found=no
+ fi
+ break 2
+ fi
+ done
+ done
+ if test "$found" != yes; then
+ # deplib doesn't seem to be a libtool library
+ if test "$linkmode,$pass" = "prog,link"; then
+ compile_deplibs="$deplib $compile_deplibs"
+ finalize_deplibs="$deplib $finalize_deplibs"
+ else
+ deplibs="$deplib $deplibs"
+ test "$linkmode" = lib && newdependency_libs="$deplib $newdependency_libs"
+ fi
+ continue
+ else # deplib is a libtool library
+ # If $allow_libtool_libs_with_static_runtimes && $deplib is a stdlib,
+ # We need to do some special things here, and not later.
+ if test "X$allow_libtool_libs_with_static_runtimes" = "Xyes" ; then
+ case " $predeps $postdeps " in
+ *" $deplib "*)
+ if func_lalib_p "$lib"; then
+ library_names=
+ old_library=
+ func_source "$lib"
+ for l in $old_library $library_names; do
+ ll="$l"
+ done
+ if test "X$ll" = "X$old_library" ; then # only static version available
+ found=no
+ func_dirname "$lib" "" "."
+ ladir="$func_dirname_result"
+ lib=$ladir/$old_library
+ if test "$linkmode,$pass" = "prog,link"; then
+ compile_deplibs="$deplib $compile_deplibs"
+ finalize_deplibs="$deplib $finalize_deplibs"
+ else
+ deplibs="$deplib $deplibs"
+ test "$linkmode" = lib && newdependency_libs="$deplib $newdependency_libs"
+ fi
+ continue
+ fi
+ fi
+ ;;
+ *) ;;
+ esac
+ fi
+ fi
+ ;; # -l
+ *.ltframework)
+ if test "$linkmode,$pass" = "prog,link"; then
+ compile_deplibs="$deplib $compile_deplibs"
+ finalize_deplibs="$deplib $finalize_deplibs"
+ else
+ deplibs="$deplib $deplibs"
+ if test "$linkmode" = lib ; then
+ case "$new_inherited_linker_flags " in
+ *" $deplib "*) ;;
+ * ) new_inherited_linker_flags="$new_inherited_linker_flags $deplib" ;;
+ esac
+ fi
+ fi
+ continue
+ ;;
+ -L*)
+ case $linkmode in
+ lib)
+ deplibs="$deplib $deplibs"
+ test "$pass" = conv && continue
+ newdependency_libs="$deplib $newdependency_libs"
+ func_stripname '-L' '' "$deplib"
+ newlib_search_path="$newlib_search_path $func_stripname_result"
+ ;;
+ prog)
+ if test "$pass" = conv; then
+ deplibs="$deplib $deplibs"
+ continue
+ fi
+ if test "$pass" = scan; then
+ deplibs="$deplib $deplibs"
+ else
+ compile_deplibs="$deplib $compile_deplibs"
+ finalize_deplibs="$deplib $finalize_deplibs"
+ fi
+ func_stripname '-L' '' "$deplib"
+ newlib_search_path="$newlib_search_path $func_stripname_result"
+ ;;
+ *)
+ func_warning "\`-L' is ignored for archives/objects"
+ ;;
+ esac # linkmode
+ continue
+ ;; # -L
+ -R*)
+ if test "$pass" = link; then
+ func_stripname '-R' '' "$deplib"
+ dir=$func_stripname_result
+ # Make sure the xrpath contains only unique directories.
+ case "$xrpath " in
+ *" $dir "*) ;;
+ *) xrpath="$xrpath $dir" ;;
+ esac
+ fi
+ deplibs="$deplib $deplibs"
+ continue
+ ;;
+ *.la) lib="$deplib" ;;
+ *.$libext)
+ if test "$pass" = conv; then
+ deplibs="$deplib $deplibs"
+ continue
+ fi
+ case $linkmode in
+ lib)
+ # Linking convenience modules into shared libraries is allowed,
+ # but linking other static libraries is non-portable.
+ case " $dlpreconveniencelibs " in
+ *" $deplib "*) ;;
+ *)
+ valid_a_lib=no
+ case $deplibs_check_method in
+ match_pattern*)
+ set dummy $deplibs_check_method; shift
+ match_pattern_regex=`expr "$deplibs_check_method" : "$1 \(.*\)"`
+ if eval "\$ECHO \"X$deplib\"" 2>/dev/null | $Xsed -e 10q \
+ | $EGREP "$match_pattern_regex" > /dev/null; then
+ valid_a_lib=yes
+ fi
+ ;;
+ pass_all)
+ valid_a_lib=yes
+ ;;
+ esac
+ if test "$valid_a_lib" != yes; then
+ $ECHO
+ $ECHO "*** Warning: Trying to link with static lib archive $deplib."
+ $ECHO "*** I have the capability to make that library automatically link in when"
+ $ECHO "*** you link to this library. But I can only do this if you have a"
+ $ECHO "*** shared version of the library, which you do not appear to have"
+ $ECHO "*** because the file extensions .$libext of this argument makes me believe"
+ $ECHO "*** that it is just a static archive that I should not use here."
+ else
+ $ECHO
+ $ECHO "*** Warning: Linking the shared library $output against the"
+ $ECHO "*** static library $deplib is not portable!"
+ deplibs="$deplib $deplibs"
+ fi
+ ;;
+ esac
+ continue
+ ;;
+ prog)
+ if test "$pass" != link; then
+ deplibs="$deplib $deplibs"
+ else
+ compile_deplibs="$deplib $compile_deplibs"
+ finalize_deplibs="$deplib $finalize_deplibs"
+ fi
+ continue
+ ;;
+ esac # linkmode
+ ;; # *.$libext
+ *.lo | *.$objext)
+ if test "$pass" = conv; then
+ deplibs="$deplib $deplibs"
+ elif test "$linkmode" = prog; then
+ if test "$pass" = dlpreopen || test "$dlopen_support" != yes || test "$build_libtool_libs" = no; then
+ # If there is no dlopen support or we're linking statically,
+ # we need to preload.
+ newdlprefiles="$newdlprefiles $deplib"
+ compile_deplibs="$deplib $compile_deplibs"
+ finalize_deplibs="$deplib $finalize_deplibs"
+ else
+ newdlfiles="$newdlfiles $deplib"
+ fi
+ fi
+ continue
+ ;;
+ %DEPLIBS%)
+ alldeplibs=yes
+ continue
+ ;;
+ esac # case $deplib
+
+ if test "$found" = yes || test -f "$lib"; then :
+ else
+ func_fatal_error "cannot find the library \`$lib' or unhandled argument \`$deplib'"
+ fi
+
+ # Check to see that this really is a libtool archive.
+ func_lalib_unsafe_p "$lib" \
+ || func_fatal_error "\`$lib' is not a valid libtool archive"
+
+ func_dirname "$lib" "" "."
+ ladir="$func_dirname_result"
+
+ dlname=
+ dlopen=
+ dlpreopen=
+ libdir=
+ library_names=
+ old_library=
+ inherited_linker_flags=
+ # If the library was installed with an old release of libtool,
+ # it will not redefine variables installed, or shouldnotlink
+ installed=yes
+ shouldnotlink=no
+ avoidtemprpath=
+
+
+ # Read the .la file
+ func_source "$lib"
+
+ # Convert "-framework foo" to "foo.ltframework"
+ if test -n "$inherited_linker_flags"; then
+ tmp_inherited_linker_flags=`$ECHO "X$inherited_linker_flags" | $Xsed -e 's/-framework \([^ $]*\)/\1.ltframework/g'`
+ for tmp_inherited_linker_flag in $tmp_inherited_linker_flags; do
+ case " $new_inherited_linker_flags " in
+ *" $tmp_inherited_linker_flag "*) ;;
+ *) new_inherited_linker_flags="$new_inherited_linker_flags $tmp_inherited_linker_flag";;
+ esac
+ done
+ fi
+ dependency_libs=`$ECHO "X $dependency_libs" | $Xsed -e 's% \([^ $]*\).ltframework% -framework \1%g'`
+ if test "$linkmode,$pass" = "lib,link" ||
+ test "$linkmode,$pass" = "prog,scan" ||
+ { test "$linkmode" != prog && test "$linkmode" != lib; }; then
+ test -n "$dlopen" && dlfiles="$dlfiles $dlopen"
+ test -n "$dlpreopen" && dlprefiles="$dlprefiles $dlpreopen"
+ fi
+
+ if test "$pass" = conv; then
+ # Only check for convenience libraries
+ deplibs="$lib $deplibs"
+ if test -z "$libdir"; then
+ if test -z "$old_library"; then
+ func_fatal_error "cannot find name of link library for \`$lib'"
+ fi
+ # It is a libtool convenience library, so add in its objects.
+ convenience="$convenience $ladir/$objdir/$old_library"
+ old_convenience="$old_convenience $ladir/$objdir/$old_library"
+ tmp_libs=
+ for deplib in $dependency_libs; do
+ deplibs="$deplib $deplibs"
+ if $opt_duplicate_deps ; then
+ case "$tmp_libs " in
+ *" $deplib "*) specialdeplibs="$specialdeplibs $deplib" ;;
+ esac
+ fi
+ tmp_libs="$tmp_libs $deplib"
+ done
+ elif test "$linkmode" != prog && test "$linkmode" != lib; then
+ func_fatal_error "\`$lib' is not a convenience library"
+ fi
+ continue
+ fi # $pass = conv
+
+
+ # Get the name of the library we link against.
+ linklib=
+ for l in $old_library $library_names; do
+ linklib="$l"
+ done
+ if test -z "$linklib"; then
+ func_fatal_error "cannot find name of link library for \`$lib'"
+ fi
+
+ # This library was specified with -dlopen.
+ if test "$pass" = dlopen; then
+ if test -z "$libdir"; then
+ func_fatal_error "cannot -dlopen a convenience library: \`$lib'"
+ fi
+ if test -z "$dlname" ||
+ test "$dlopen_support" != yes ||
+ test "$build_libtool_libs" = no; then
+ # If there is no dlname, no dlopen support or we're linking
+ # statically, we need to preload. We also need to preload any
+ # dependent libraries so libltdl's deplib preloader doesn't
+ # bomb out in the load deplibs phase.
+ dlprefiles="$dlprefiles $lib $dependency_libs"
+ else
+ newdlfiles="$newdlfiles $lib"
+ fi
+ continue
+ fi # $pass = dlopen
+
+ # We need an absolute path.
+ case $ladir in
+ [\\/]* | [A-Za-z]:[\\/]*) abs_ladir="$ladir" ;;
+ *)
+ abs_ladir=`cd "$ladir" && pwd`
+ if test -z "$abs_ladir"; then
+ func_warning "cannot determine absolute directory name of \`$ladir'"
+ func_warning "passing it literally to the linker, although it might fail"
+ abs_ladir="$ladir"
+ fi
+ ;;
+ esac
+ func_basename "$lib"
+ laname="$func_basename_result"
+
+ # Find the relevant object directory and library name.
+ if test "X$installed" = Xyes; then
+ if test ! -f "$libdir/$linklib" && test -f "$abs_ladir/$linklib"; then
+ func_warning "library \`$lib' was moved."
+ dir="$ladir"
+ absdir="$abs_ladir"
+ libdir="$abs_ladir"
+ else
+ dir="$libdir"
+ absdir="$libdir"
+ fi
+ test "X$hardcode_automatic" = Xyes && avoidtemprpath=yes
+ else
+ if test ! -f "$ladir/$objdir/$linklib" && test -f "$abs_ladir/$linklib"; then
+ dir="$ladir"
+ absdir="$abs_ladir"
+ # Remove this search path later
+ notinst_path="$notinst_path $abs_ladir"
+ else
+ dir="$ladir/$objdir"
+ absdir="$abs_ladir/$objdir"
+ # Remove this search path later
+ notinst_path="$notinst_path $abs_ladir"
+ fi
+ fi # $installed = yes
+ func_stripname 'lib' '.la' "$laname"
+ name=$func_stripname_result
+
+ # This library was specified with -dlpreopen.
+ if test "$pass" = dlpreopen; then
+ if test -z "$libdir" && test "$linkmode" = prog; then
+ func_fatal_error "only libraries may -dlpreopen a convenience library: \`$lib'"
+ fi
+ # Prefer using a static library (so that no silly _DYNAMIC symbols
+ # are required to link).
+ if test -n "$old_library"; then
+ newdlprefiles="$newdlprefiles $dir/$old_library"
+ # Keep a list of preopened convenience libraries to check
+ # that they are being used correctly in the link pass.
+ test -z "$libdir" && \
+ dlpreconveniencelibs="$dlpreconveniencelibs $dir/$old_library"
+ # Otherwise, use the dlname, so that lt_dlopen finds it.
+ elif test -n "$dlname"; then
+ newdlprefiles="$newdlprefiles $dir/$dlname"
+ else
+ newdlprefiles="$newdlprefiles $dir/$linklib"
+ fi
+ fi # $pass = dlpreopen
+
+ if test -z "$libdir"; then
+ # Link the convenience library
+ if test "$linkmode" = lib; then
+ deplibs="$dir/$old_library $deplibs"
+ elif test "$linkmode,$pass" = "prog,link"; then
+ compile_deplibs="$dir/$old_library $compile_deplibs"
+ finalize_deplibs="$dir/$old_library $finalize_deplibs"
+ else
+ deplibs="$lib $deplibs" # used for prog,scan pass
+ fi
+ continue
+ fi
+
+
+ if test "$linkmode" = prog && test "$pass" != link; then
+ newlib_search_path="$newlib_search_path $ladir"
+ deplibs="$lib $deplibs"
+
+ linkalldeplibs=no
+ if test "$link_all_deplibs" != no || test -z "$library_names" ||
+ test "$build_libtool_libs" = no; then
+ linkalldeplibs=yes
+ fi
+
+ tmp_libs=
+ for deplib in $dependency_libs; do
+ case $deplib in
+ -L*) func_stripname '-L' '' "$deplib"
+ newlib_search_path="$newlib_search_path $func_stripname_result"
+ ;;
+ esac
+ # Need to link against all dependency_libs?
+ if test "$linkalldeplibs" = yes; then
+ deplibs="$deplib $deplibs"
+ else
+ # Need to hardcode shared library paths
+ # or/and link against static libraries
+ newdependency_libs="$deplib $newdependency_libs"
+ fi
+ if $opt_duplicate_deps ; then
+ case "$tmp_libs " in
+ *" $deplib "*) specialdeplibs="$specialdeplibs $deplib" ;;
+ esac
+ fi
+ tmp_libs="$tmp_libs $deplib"
+ done # for deplib
+ continue
+ fi # $linkmode = prog...
+
+ if test "$linkmode,$pass" = "prog,link"; then
+ if test -n "$library_names" &&
+ { { test "$prefer_static_libs" = no ||
+ test "$prefer_static_libs,$installed" = "built,yes"; } ||
+ test -z "$old_library"; }; then
+ # We need to hardcode the library path
+ if test -n "$shlibpath_var" && test -z "$avoidtemprpath" ; then
+ # Make sure the rpath contains only unique directories.
+ case "$temp_rpath:" in
+ *"$absdir:"*) ;;
+ *) temp_rpath="$temp_rpath$absdir:" ;;
+ esac
+ fi
+
+ # Hardcode the library path.
+ # Skip directories that are in the system default run-time
+ # search path.
+ case " $sys_lib_dlsearch_path " in
+ *" $absdir "*) ;;
+ *)
+ case "$compile_rpath " in
+ *" $absdir "*) ;;
+ *) compile_rpath="$compile_rpath $absdir"
+ esac
+ ;;
+ esac
+ case " $sys_lib_dlsearch_path " in
+ *" $libdir "*) ;;
+ *)
+ case "$finalize_rpath " in
+ *" $libdir "*) ;;
+ *) finalize_rpath="$finalize_rpath $libdir"
+ esac
+ ;;
+ esac
+ fi # $linkmode,$pass = prog,link...
+
+ if test "$alldeplibs" = yes &&
+ { test "$deplibs_check_method" = pass_all ||
+ { test "$build_libtool_libs" = yes &&
+ test -n "$library_names"; }; }; then
+ # We only need to search for static libraries
+ continue
+ fi
+ fi
+
+ link_static=no # Whether the deplib will be linked statically
+ use_static_libs=$prefer_static_libs
+ if test "$use_static_libs" = built && test "$installed" = yes; then
+ use_static_libs=no
+ fi
+ if test -n "$library_names" &&
+ { test "$use_static_libs" = no || test -z "$old_library"; }; then
+ case $host in
+ *cygwin* | *mingw* | *cegcc*)
+ # No point in relinking DLLs because paths are not encoded
+ notinst_deplibs="$notinst_deplibs $lib"
+ need_relink=no
+ ;;
+ *)
+ if test "$installed" = no; then
+ notinst_deplibs="$notinst_deplibs $lib"
+ need_relink=yes
+ fi
+ ;;
+ esac
+ # This is a shared library
+
+ # Warn about portability, can't link against -module's on some
+ # systems (darwin). Don't bleat about dlopened modules though!
+ dlopenmodule=""
+ for dlpremoduletest in $dlprefiles; do
+ if test "X$dlpremoduletest" = "X$lib"; then
+ dlopenmodule="$dlpremoduletest"
+ break
+ fi
+ done
+ if test -z "$dlopenmodule" && test "$shouldnotlink" = yes && test "$pass" = link; then
+ $ECHO
+ if test "$linkmode" = prog; then
+ $ECHO "*** Warning: Linking the executable $output against the loadable module"
+ else
+ $ECHO "*** Warning: Linking the shared library $output against the loadable module"
+ fi
+ $ECHO "*** $linklib is not portable!"
+ fi
+ if test "$linkmode" = lib &&
+ test "$hardcode_into_libs" = yes; then
+ # Hardcode the library path.
+ # Skip directories that are in the system default run-time
+ # search path.
+ case " $sys_lib_dlsearch_path " in
+ *" $absdir "*) ;;
+ *)
+ case "$compile_rpath " in
+ *" $absdir "*) ;;
+ *) compile_rpath="$compile_rpath $absdir"
+ esac
+ ;;
+ esac
+ case " $sys_lib_dlsearch_path " in
+ *" $libdir "*) ;;
+ *)
+ case "$finalize_rpath " in
+ *" $libdir "*) ;;
+ *) finalize_rpath="$finalize_rpath $libdir"
+ esac
+ ;;
+ esac
+ fi
+
+ if test -n "$old_archive_from_expsyms_cmds"; then
+ # figure out the soname
+ set dummy $library_names
+ shift
+ realname="$1"
+ shift
+ libname=`eval "\\$ECHO \"$libname_spec\""`
+ # use dlname if we got it. it's perfectly good, no?
+ if test -n "$dlname"; then
+ soname="$dlname"
+ elif test -n "$soname_spec"; then
+ # bleh windows
+ case $host in
+ *cygwin* | mingw* | *cegcc*)
+ func_arith $current - $age
+ major=$func_arith_result
+ versuffix="-$major"
+ ;;
+ esac
+ eval soname=\"$soname_spec\"
+ else
+ soname="$realname"
+ fi
+
+ # Make a new name for the extract_expsyms_cmds to use
+ soroot="$soname"
+ func_basename "$soroot"
+ soname="$func_basename_result"
+ func_stripname 'lib' '.dll' "$soname"
+ newlib=libimp-$func_stripname_result.a
+
+ # If the library has no export list, then create one now
+ if test -f "$output_objdir/$soname-def"; then :
+ else
+ func_verbose "extracting exported symbol list from \`$soname'"
+ func_execute_cmds "$extract_expsyms_cmds" 'exit $?'
+ fi
+
+ # Create $newlib
+ if test -f "$output_objdir/$newlib"; then :; else
+ func_verbose "generating import library for \`$soname'"
+ func_execute_cmds "$old_archive_from_expsyms_cmds" 'exit $?'
+ fi
+ # make sure the library variables are pointing to the new library
+ dir=$output_objdir
+ linklib=$newlib
+ fi # test -n "$old_archive_from_expsyms_cmds"
+
+ if test "$linkmode" = prog || test "$mode" != relink; then
+ add_shlibpath=
+ add_dir=
+ add=
+ lib_linked=yes
+ case $hardcode_action in
+ immediate | unsupported)
+ if test "$hardcode_direct" = no; then
+ add="$dir/$linklib"
+ case $host in
+ *-*-sco3.2v5.0.[024]*) add_dir="-L$dir" ;;
+ *-*-sysv4*uw2*) add_dir="-L$dir" ;;
+ *-*-sysv5OpenUNIX* | *-*-sysv5UnixWare7.[01].[10]* | \
+ *-*-unixware7*) add_dir="-L$dir" ;;
+ *-*-darwin* )
+ # if the lib is a (non-dlopened) module then we can not
+ # link against it, someone is ignoring the earlier warnings
+ if /usr/bin/file -L $add 2> /dev/null |
+ $GREP ": [^:]* bundle" >/dev/null ; then
+ if test "X$dlopenmodule" != "X$lib"; then
+ $ECHO "*** Warning: lib $linklib is a module, not a shared library"
+ if test -z "$old_library" ; then
+ $ECHO
+ $ECHO "*** And there doesn't seem to be a static archive available"
+ $ECHO "*** The link will probably fail, sorry"
+ else
+ add="$dir/$old_library"
+ fi
+ elif test -n "$old_library"; then
+ add="$dir/$old_library"
+ fi
+ fi
+ esac
+ elif test "$hardcode_minus_L" = no; then
+ case $host in
+ *-*-sunos*) add_shlibpath="$dir" ;;
+ esac
+ add_dir="-L$dir"
+ add="-l$name"
+ elif test "$hardcode_shlibpath_var" = no; then
+ add_shlibpath="$dir"
+ add="-l$name"
+ else
+ lib_linked=no
+ fi
+ ;;
+ relink)
+ if test "$hardcode_direct" = yes &&
+ test "$hardcode_direct_absolute" = no; then
+ add="$dir/$linklib"
+ elif test "$hardcode_minus_L" = yes; then
+ add_dir="-L$dir"
+ # Try looking first in the location we're being installed to.
+ if test -n "$inst_prefix_dir"; then
+ case $libdir in
+ [\\/]*)
+ add_dir="$add_dir -L$inst_prefix_dir$libdir"
+ ;;
+ esac
+ fi
+ add="-l$name"
+ elif test "$hardcode_shlibpath_var" = yes; then
+ add_shlibpath="$dir"
+ add="-l$name"
+ else
+ lib_linked=no
+ fi
+ ;;
+ *) lib_linked=no ;;
+ esac
+
+ if test "$lib_linked" != yes; then
+ func_fatal_configuration "unsupported hardcode properties"
+ fi
+
+ if test -n "$add_shlibpath"; then
+ case :$compile_shlibpath: in
+ *":$add_shlibpath:"*) ;;
+ *) compile_shlibpath="$compile_shlibpath$add_shlibpath:" ;;
+ esac
+ fi
+ if test "$linkmode" = prog; then
+ test -n "$add_dir" && compile_deplibs="$add_dir $compile_deplibs"
+ test -n "$add" && compile_deplibs="$add $compile_deplibs"
+ else
+ test -n "$add_dir" && deplibs="$add_dir $deplibs"
+ test -n "$add" && deplibs="$add $deplibs"
+ if test "$hardcode_direct" != yes &&
+ test "$hardcode_minus_L" != yes &&
+ test "$hardcode_shlibpath_var" = yes; then
+ case :$finalize_shlibpath: in
+ *":$libdir:"*) ;;
+ *) finalize_shlibpath="$finalize_shlibpath$libdir:" ;;
+ esac
+ fi
+ fi
+ fi
+
+ if test "$linkmode" = prog || test "$mode" = relink; then
+ add_shlibpath=
+ add_dir=
+ add=
+ # Finalize command for both is simple: just hardcode it.
+ if test "$hardcode_direct" = yes &&
+ test "$hardcode_direct_absolute" = no; then
+ add="$libdir/$linklib"
+ elif test "$hardcode_minus_L" = yes; then
+ add_dir="-L$libdir"
+ add="-l$name"
+ elif test "$hardcode_shlibpath_var" = yes; then
+ case :$finalize_shlibpath: in
+ *":$libdir:"*) ;;
+ *) finalize_shlibpath="$finalize_shlibpath$libdir:" ;;
+ esac
+ add="-l$name"
+ elif test "$hardcode_automatic" = yes; then
+ if test -n "$inst_prefix_dir" &&
+ test -f "$inst_prefix_dir$libdir/$linklib" ; then
+ add="$inst_prefix_dir$libdir/$linklib"
+ else
+ add="$libdir/$linklib"
+ fi
+ else
+ # We cannot seem to hardcode it, guess we'll fake it.
+ add_dir="-L$libdir"
+ # Try looking first in the location we're being installed to.
+ if test -n "$inst_prefix_dir"; then
+ case $libdir in
+ [\\/]*)
+ add_dir="$add_dir -L$inst_prefix_dir$libdir"
+ ;;
+ esac
+ fi
+ add="-l$name"
+ fi
+
+ if test "$linkmode" = prog; then
+ test -n "$add_dir" && finalize_deplibs="$add_dir $finalize_deplibs"
+ test -n "$add" && finalize_deplibs="$add $finalize_deplibs"
+ else
+ test -n "$add_dir" && deplibs="$add_dir $deplibs"
+ test -n "$add" && deplibs="$add $deplibs"
+ fi
+ fi
+ elif test "$linkmode" = prog; then
+ # Here we assume that one of hardcode_direct or hardcode_minus_L
+ # is not unsupported. This is valid on all known static and
+ # shared platforms.
+ if test "$hardcode_direct" != unsupported; then
+ test -n "$old_library" && linklib="$old_library"
+ compile_deplibs="$dir/$linklib $compile_deplibs"
+ finalize_deplibs="$dir/$linklib $finalize_deplibs"
+ else
+ compile_deplibs="-l$name -L$dir $compile_deplibs"
+ finalize_deplibs="-l$name -L$dir $finalize_deplibs"
+ fi
+ elif test "$build_libtool_libs" = yes; then
+ # Not a shared library
+ if test "$deplibs_check_method" != pass_all; then
+ # We're trying link a shared library against a static one
+ # but the system doesn't support it.
+
+ # Just print a warning and add the library to dependency_libs so
+ # that the program can be linked against the static library.
+ $ECHO
+ $ECHO "*** Warning: This system can not link to static lib archive $lib."
+ $ECHO "*** I have the capability to make that library automatically link in when"
+ $ECHO "*** you link to this library. But I can only do this if you have a"
+ $ECHO "*** shared version of the library, which you do not appear to have."
+ if test "$module" = yes; then
+ $ECHO "*** But as you try to build a module library, libtool will still create "
+ $ECHO "*** a static module, that should work as long as the dlopening application"
+ $ECHO "*** is linked with the -dlopen flag to resolve symbols at runtime."
+ if test -z "$global_symbol_pipe"; then
+ $ECHO
+ $ECHO "*** However, this would only work if libtool was able to extract symbol"
+ $ECHO "*** lists from a program, using \`nm' or equivalent, but libtool could"
+ $ECHO "*** not find such a program. So, this module is probably useless."
+ $ECHO "*** \`nm' from GNU binutils and a full rebuild may help."
+ fi
+ if test "$build_old_libs" = no; then
+ build_libtool_libs=module
+ build_old_libs=yes
+ else
+ build_libtool_libs=no
+ fi
+ fi
+ else
+ deplibs="$dir/$old_library $deplibs"
+ link_static=yes
+ fi
+ fi # link shared/static library?
+
+ if test "$linkmode" = lib; then
+ if test -n "$dependency_libs" &&
+ { test "$hardcode_into_libs" != yes ||
+ test "$build_old_libs" = yes ||
+ test "$link_static" = yes; }; then
+ # Extract -R from dependency_libs
+ temp_deplibs=
+ for libdir in $dependency_libs; do
+ case $libdir in
+ -R*) func_stripname '-R' '' "$libdir"
+ temp_xrpath=$func_stripname_result
+ case " $xrpath " in
+ *" $temp_xrpath "*) ;;
+ *) xrpath="$xrpath $temp_xrpath";;
+ esac;;
+ *) temp_deplibs="$temp_deplibs $libdir";;
+ esac
+ done
+ dependency_libs="$temp_deplibs"
+ fi
+
+ newlib_search_path="$newlib_search_path $absdir"
+ # Link against this library
+ test "$link_static" = no && newdependency_libs="$abs_ladir/$laname $newdependency_libs"
+ # ... and its dependency_libs
+ tmp_libs=
+ for deplib in $dependency_libs; do
+ newdependency_libs="$deplib $newdependency_libs"
+ if $opt_duplicate_deps ; then
+ case "$tmp_libs " in
+ *" $deplib "*) specialdeplibs="$specialdeplibs $deplib" ;;
+ esac
+ fi
+ tmp_libs="$tmp_libs $deplib"
+ done
+
+ if test "$link_all_deplibs" != no; then
+ # Add the search paths of all dependency libraries
+ for deplib in $dependency_libs; do
+ path=
+ case $deplib in
+ -L*) path="$deplib" ;;
+ *.la)
+ func_dirname "$deplib" "" "."
+ dir="$func_dirname_result"
+ # We need an absolute path.
+ case $dir in
+ [\\/]* | [A-Za-z]:[\\/]*) absdir="$dir" ;;
+ *)
+ absdir=`cd "$dir" && pwd`
+ if test -z "$absdir"; then
+ func_warning "cannot determine absolute directory name of \`$dir'"
+ absdir="$dir"
+ fi
+ ;;
+ esac
+ if $GREP "^installed=no" $deplib > /dev/null; then
+ case $host in
+ *-*-darwin*)
+ depdepl=
+ eval deplibrary_names=`${SED} -n -e 's/^library_names=\(.*\)$/\1/p' $deplib`
+ if test -n "$deplibrary_names" ; then
+ for tmp in $deplibrary_names ; do
+ depdepl=$tmp
+ done
+ if test -f "$absdir/$objdir/$depdepl" ; then
+ depdepl="$absdir/$objdir/$depdepl"
+ darwin_install_name=`${OTOOL} -L $depdepl | awk '{if (NR == 2) {print $1;exit}}'`
+ if test -z "$darwin_install_name"; then
+ darwin_install_name=`${OTOOL64} -L $depdepl | awk '{if (NR == 2) {print $1;exit}}'`
+ fi
+ compiler_flags="$compiler_flags ${wl}-dylib_file ${wl}${darwin_install_name}:${depdepl}"
+ linker_flags="$linker_flags -dylib_file ${darwin_install_name}:${depdepl}"
+ path=
+ fi
+ fi
+ ;;
+ *)
+ path="-L$absdir/$objdir"
+ ;;
+ esac
+ else
+ eval libdir=`${SED} -n -e 's/^libdir=\(.*\)$/\1/p' $deplib`
+ test -z "$libdir" && \
+ func_fatal_error "\`$deplib' is not a valid libtool archive"
+ test "$absdir" != "$libdir" && \
+ func_warning "\`$deplib' seems to be moved"
+
+ path="-L$absdir"
+ fi
+ ;;
+ esac
+ case " $deplibs " in
+ *" $path "*) ;;
+ *) deplibs="$path $deplibs" ;;
+ esac
+ done
+ fi # link_all_deplibs != no
+ fi # linkmode = lib
+ done # for deplib in $libs
+ if test "$pass" = link; then
+ if test "$linkmode" = "prog"; then
+ compile_deplibs="$new_inherited_linker_flags $compile_deplibs"
+ finalize_deplibs="$new_inherited_linker_flags $finalize_deplibs"
+ else
+ compiler_flags="$compiler_flags "`$ECHO "X $new_inherited_linker_flags" | $Xsed -e 's% \([^ $]*\).ltframework% -framework \1%g'`
+ fi
+ fi
+ dependency_libs="$newdependency_libs"
+ if test "$pass" = dlpreopen; then
+ # Link the dlpreopened libraries before other libraries
+ for deplib in $save_deplibs; do
+ deplibs="$deplib $deplibs"
+ done
+ fi
+ if test "$pass" != dlopen; then
+ if test "$pass" != conv; then
+ # Make sure lib_search_path contains only unique directories.
+ lib_search_path=
+ for dir in $newlib_search_path; do
+ case "$lib_search_path " in
+ *" $dir "*) ;;
+ *) lib_search_path="$lib_search_path $dir" ;;
+ esac
+ done
+ newlib_search_path=
+ fi
+
+ if test "$linkmode,$pass" != "prog,link"; then
+ vars="deplibs"
+ else
+ vars="compile_deplibs finalize_deplibs"
+ fi
+ for var in $vars dependency_libs; do
+ # Add libraries to $var in reverse order
+ eval tmp_libs=\"\$$var\"
+ new_libs=
+ for deplib in $tmp_libs; do
+ # FIXME: Pedantically, this is the right thing to do, so
+ # that some nasty dependency loop isn't accidentally
+ # broken:
+ #new_libs="$deplib $new_libs"
+ # Pragmatically, this seems to cause very few problems in
+ # practice:
+ case $deplib in
+ -L*) new_libs="$deplib $new_libs" ;;
+ -R*) ;;
+ *)
+ # And here is the reason: when a library appears more
+ # than once as an explicit dependence of a library, or
+ # is implicitly linked in more than once by the
+ # compiler, it is considered special, and multiple
+ # occurrences thereof are not removed. Compare this
+ # with having the same library being listed as a
+ # dependency of multiple other libraries: in this case,
+ # we know (pedantically, we assume) the library does not
+ # need to be listed more than once, so we keep only the
+ # last copy. This is not always right, but it is rare
+ # enough that we require users that really mean to play
+ # such unportable linking tricks to link the library
+ # using -Wl,-lname, so that libtool does not consider it
+ # for duplicate removal.
+ case " $specialdeplibs " in
+ *" $deplib "*) new_libs="$deplib $new_libs" ;;
+ *)
+ case " $new_libs " in
+ *" $deplib "*) ;;
+ *) new_libs="$deplib $new_libs" ;;
+ esac
+ ;;
+ esac
+ ;;
+ esac
+ done
+ tmp_libs=
+ for deplib in $new_libs; do
+ case $deplib in
+ -L*)
+ case " $tmp_libs " in
+ *" $deplib "*) ;;
+ *) tmp_libs="$tmp_libs $deplib" ;;
+ esac
+ ;;
+ *) tmp_libs="$tmp_libs $deplib" ;;
+ esac
+ done
+ eval $var=\"$tmp_libs\"
+ done # for var
+ fi
+ # Last step: remove runtime libs from dependency_libs
+ # (they stay in deplibs)
+ tmp_libs=
+ for i in $dependency_libs ; do
+ case " $predeps $postdeps $compiler_lib_search_path " in
+ *" $i "*)
+ i=""
+ ;;
+ esac
+ if test -n "$i" ; then
+ tmp_libs="$tmp_libs $i"
+ fi
+ done
+ dependency_libs=$tmp_libs
+ done # for pass
+ if test "$linkmode" = prog; then
+ dlfiles="$newdlfiles"
+ fi
+ if test "$linkmode" = prog || test "$linkmode" = lib; then
+ dlprefiles="$newdlprefiles"
+ fi
+
+ case $linkmode in
+ oldlib)
+ if test -n "$dlfiles$dlprefiles" || test "$dlself" != no; then
+ func_warning "\`-dlopen' is ignored for archives"
+ fi
+
+ case " $deplibs" in
+ *\ -l* | *\ -L*)
+ func_warning "\`-l' and \`-L' are ignored for archives" ;;
+ esac
+
+ test -n "$rpath" && \
+ func_warning "\`-rpath' is ignored for archives"
+
+ test -n "$xrpath" && \
+ func_warning "\`-R' is ignored for archives"
+
+ test -n "$vinfo" && \
+ func_warning "\`-version-info/-version-number' is ignored for archives"
+
+ test -n "$release" && \
+ func_warning "\`-release' is ignored for archives"
+
+ test -n "$export_symbols$export_symbols_regex" && \
+ func_warning "\`-export-symbols' is ignored for archives"
+
+ # Now set the variables for building old libraries.
+ build_libtool_libs=no
+ oldlibs="$output"
+ objs="$objs$old_deplibs"
+ ;;
+
+ lib)
+ # Make sure we only generate libraries of the form `libNAME.la'.
+ case $outputname in
+ lib*)
+ func_stripname 'lib' '.la' "$outputname"
+ name=$func_stripname_result
+ eval shared_ext=\"$shrext_cmds\"
+ eval libname=\"$libname_spec\"
+ ;;
+ *)
+ test "$module" = no && \
+ func_fatal_help "libtool library \`$output' must begin with \`lib'"
+
+ if test "$need_lib_prefix" != no; then
+ # Add the "lib" prefix for modules if required
+ func_stripname '' '.la' "$outputname"
+ name=$func_stripname_result
+ eval shared_ext=\"$shrext_cmds\"
+ eval libname=\"$libname_spec\"
+ else
+ func_stripname '' '.la' "$outputname"
+ libname=$func_stripname_result
+ fi
+ ;;
+ esac
+
+ if test -n "$objs"; then
+ if test "$deplibs_check_method" != pass_all; then
+ func_fatal_error "cannot build libtool library \`$output' from non-libtool objects on this host:$objs"
+ else
+ $ECHO
+ $ECHO "*** Warning: Linking the shared library $output against the non-libtool"
+ $ECHO "*** objects $objs is not portable!"
+ libobjs="$libobjs $objs"
+ fi
+ fi
+
+ test "$dlself" != no && \
+ func_warning "\`-dlopen self' is ignored for libtool libraries"
+
+ set dummy $rpath
+ shift
+ test "$#" -gt 1 && \
+ func_warning "ignoring multiple \`-rpath's for a libtool library"
+
+ install_libdir="$1"
+
+ oldlibs=
+ if test -z "$rpath"; then
+ if test "$build_libtool_libs" = yes; then
+ # Building a libtool convenience library.
+ # Some compilers have problems with a `.al' extension so
+ # convenience libraries should have the same extension an
+ # archive normally would.
+ oldlibs="$output_objdir/$libname.$libext $oldlibs"
+ build_libtool_libs=convenience
+ build_old_libs=yes
+ fi
+
+ test -n "$vinfo" && \
+ func_warning "\`-version-info/-version-number' is ignored for convenience libraries"
+
+ test -n "$release" && \
+ func_warning "\`-release' is ignored for convenience libraries"
+ else
+
+ # Parse the version information argument.
+ save_ifs="$IFS"; IFS=':'
+ set dummy $vinfo 0 0 0
+ shift
+ IFS="$save_ifs"
+
+ test -n "$7" && \
+ func_fatal_help "too many parameters to \`-version-info'"
+
+ # convert absolute version numbers to libtool ages
+ # this retains compatibility with .la files and attempts
+ # to make the code below a bit more comprehensible
+
+ case $vinfo_number in
+ yes)
+ number_major="$1"
+ number_minor="$2"
+ number_revision="$3"
+ #
+ # There are really only two kinds -- those that
+ # use the current revision as the major version
+ # and those that subtract age and use age as
+ # a minor version. But, then there is irix
+ # which has an extra 1 added just for fun
+ #
+ case $version_type in
+ darwin|linux|osf|windows|none)
+ func_arith $number_major + $number_minor
+ current=$func_arith_result
+ age="$number_minor"
+ revision="$number_revision"
+ ;;
+ freebsd-aout|freebsd-elf|sunos)
+ current="$number_major"
+ revision="$number_minor"
+ age="0"
+ ;;
+ irix|nonstopux)
+ func_arith $number_major + $number_minor
+ current=$func_arith_result
+ age="$number_minor"
+ revision="$number_minor"
+ lt_irix_increment=no
+ ;;
+ *)
+ func_fatal_configuration "$modename: unknown library version type \`$version_type'"
+ ;;
+ esac
+ ;;
+ no)
+ current="$1"
+ revision="$2"
+ age="$3"
+ ;;
+ esac
+
+ # Check that each of the things are valid numbers.
+ case $current in
+ 0|[1-9]|[1-9][0-9]|[1-9][0-9][0-9]|[1-9][0-9][0-9][0-9]|[1-9][0-9][0-9][0-9][0-9]) ;;
+ *)
+ func_error "CURRENT \`$current' must be a nonnegative integer"
+ func_fatal_error "\`$vinfo' is not valid version information"
+ ;;
+ esac
+
+ case $revision in
+ 0|[1-9]|[1-9][0-9]|[1-9][0-9][0-9]|[1-9][0-9][0-9][0-9]|[1-9][0-9][0-9][0-9][0-9]) ;;
+ *)
+ func_error "REVISION \`$revision' must be a nonnegative integer"
+ func_fatal_error "\`$vinfo' is not valid version information"
+ ;;
+ esac
+
+ case $age in
+ 0|[1-9]|[1-9][0-9]|[1-9][0-9][0-9]|[1-9][0-9][0-9][0-9]|[1-9][0-9][0-9][0-9][0-9]) ;;
+ *)
+ func_error "AGE \`$age' must be a nonnegative integer"
+ func_fatal_error "\`$vinfo' is not valid version information"
+ ;;
+ esac
+
+ if test "$age" -gt "$current"; then
+ func_error "AGE \`$age' is greater than the current interface number \`$current'"
+ func_fatal_error "\`$vinfo' is not valid version information"
+ fi
+
+ # Calculate the version variables.
+ major=
+ versuffix=
+ verstring=
+ case $version_type in
+ none) ;;
+
+ darwin)
+ # Like Linux, but with the current version available in
+ # verstring for coding it into the library header
+ func_arith $current - $age
+ major=.$func_arith_result
+ versuffix="$major.$age.$revision"
+ # Darwin ld doesn't like 0 for these options...
+ func_arith $current + 1
+ minor_current=$func_arith_result
+ xlcverstring="${wl}-compatibility_version ${wl}$minor_current ${wl}-current_version ${wl}$minor_current.$revision"
+ verstring="-compatibility_version $minor_current -current_version $minor_current.$revision"
+ ;;
+
+ freebsd-aout)
+ major=".$current"
+ versuffix=".$current.$revision";
+ ;;
+
+ freebsd-elf)
+ major=".$current"
+ versuffix=".$current"
+ ;;
+
+ irix | nonstopux)
+ if test "X$lt_irix_increment" = "Xno"; then
+ func_arith $current - $age
+ else
+ func_arith $current - $age + 1
+ fi
+ major=$func_arith_result
+
+ case $version_type in
+ nonstopux) verstring_prefix=nonstopux ;;
+ *) verstring_prefix=sgi ;;
+ esac
+ verstring="$verstring_prefix$major.$revision"
+
+ # Add in all the interfaces that we are compatible with.
+ loop=$revision
+ while test "$loop" -ne 0; do
+ func_arith $revision - $loop
+ iface=$func_arith_result
+ func_arith $loop - 1
+ loop=$func_arith_result
+ verstring="$verstring_prefix$major.$iface:$verstring"
+ done
+
+ # Before this point, $major must not contain `.'.
+ major=.$major
+ versuffix="$major.$revision"
+ ;;
+
+ linux)
+ func_arith $current - $age
+ major=.$func_arith_result
+ versuffix="$major.$age.$revision"
+ ;;
+
+ osf)
+ func_arith $current - $age
+ major=.$func_arith_result
+ versuffix=".$current.$age.$revision"
+ verstring="$current.$age.$revision"
+
+ # Add in all the interfaces that we are compatible with.
+ loop=$age
+ while test "$loop" -ne 0; do
+ func_arith $current - $loop
+ iface=$func_arith_result
+ func_arith $loop - 1
+ loop=$func_arith_result
+ verstring="$verstring:${iface}.0"
+ done
+
+ # Make executables depend on our current version.
+ verstring="$verstring:${current}.0"
+ ;;
+
+ qnx)
+ major=".$current"
+ versuffix=".$current"
+ ;;
+
+ sunos)
+ major=".$current"
+ versuffix=".$current.$revision"
+ ;;
+
+ windows)
+ # Use '-' rather than '.', since we only want one
+ # extension on DOS 8.3 filesystems.
+ func_arith $current - $age
+ major=$func_arith_result
+ versuffix="-$major"
+ ;;
+
+ *)
+ func_fatal_configuration "unknown library version type \`$version_type'"
+ ;;
+ esac
+
+ # Clear the version info if we defaulted, and they specified a release.
+ if test -z "$vinfo" && test -n "$release"; then
+ major=
+ case $version_type in
+ darwin)
+ # we can't check for "0.0" in archive_cmds due to quoting
+ # problems, so we reset it completely
+ verstring=
+ ;;
+ *)
+ verstring="0.0"
+ ;;
+ esac
+ if test "$need_version" = no; then
+ versuffix=
+ else
+ versuffix=".0.0"
+ fi
+ fi
+
+ # Remove version info from name if versioning should be avoided
+ if test "$avoid_version" = yes && test "$need_version" = no; then
+ major=
+ versuffix=
+ verstring=""
+ fi
+
+ # Check to see if the archive will have undefined symbols.
+ if test "$allow_undefined" = yes; then
+ if test "$allow_undefined_flag" = unsupported; then
+ func_warning "undefined symbols not allowed in $host shared libraries"
+ build_libtool_libs=no
+ build_old_libs=yes
+ fi
+ else
+ # Don't allow undefined symbols.
+ allow_undefined_flag="$no_undefined_flag"
+ fi
+
+ fi
+
+ func_generate_dlsyms "$libname" "$libname" "yes"
+ libobjs="$libobjs $symfileobj"
+ test "X$libobjs" = "X " && libobjs=
+
+ if test "$mode" != relink; then
+ # Remove our outputs, but don't remove object files since they
+ # may have been created when compiling PIC objects.
+ removelist=
+ tempremovelist=`$ECHO "$output_objdir/*"`
+ for p in $tempremovelist; do
+ case $p in
+ *.$objext | *.gcno)
+ ;;
+ $output_objdir/$outputname | $output_objdir/$libname.* | $output_objdir/${libname}${release}.*)
+ if test "X$precious_files_regex" != "X"; then
+ if $ECHO "$p" | $EGREP -e "$precious_files_regex" >/dev/null 2>&1
+ then
+ continue
+ fi
+ fi
+ removelist="$removelist $p"
+ ;;
+ *) ;;
+ esac
+ done
+ test -n "$removelist" && \
+ func_show_eval "${RM}r \$removelist"
+ fi
+
+ # Now set the variables for building old libraries.
+ if test "$build_old_libs" = yes && test "$build_libtool_libs" != convenience ; then
+ oldlibs="$oldlibs $output_objdir/$libname.$libext"
+
+ # Transform .lo files to .o files.
+ oldobjs="$objs "`$ECHO "X$libobjs" | $SP2NL | $Xsed -e '/\.'${libext}'$/d' -e "$lo2o" | $NL2SP`
+ fi
+
+ # Eliminate all temporary directories.
+ #for path in $notinst_path; do
+ # lib_search_path=`$ECHO "X$lib_search_path " | $Xsed -e "s% $path % %g"`
+ # deplibs=`$ECHO "X$deplibs " | $Xsed -e "s% -L$path % %g"`
+ # dependency_libs=`$ECHO "X$dependency_libs " | $Xsed -e "s% -L$path % %g"`
+ #done
+
+ if test -n "$xrpath"; then
+ # If the user specified any rpath flags, then add them.
+ temp_xrpath=
+ for libdir in $xrpath; do
+ temp_xrpath="$temp_xrpath -R$libdir"
+ case "$finalize_rpath " in
+ *" $libdir "*) ;;
+ *) finalize_rpath="$finalize_rpath $libdir" ;;
+ esac
+ done
+ if test "$hardcode_into_libs" != yes || test "$build_old_libs" = yes; then
+ dependency_libs="$temp_xrpath $dependency_libs"
+ fi
+ fi
+
+ # Make sure dlfiles contains only unique files that won't be dlpreopened
+ old_dlfiles="$dlfiles"
+ dlfiles=
+ for lib in $old_dlfiles; do
+ case " $dlprefiles $dlfiles " in
+ *" $lib "*) ;;
+ *) dlfiles="$dlfiles $lib" ;;
+ esac
+ done
+
+ # Make sure dlprefiles contains only unique files
+ old_dlprefiles="$dlprefiles"
+ dlprefiles=
+ for lib in $old_dlprefiles; do
+ case "$dlprefiles " in
+ *" $lib "*) ;;
+ *) dlprefiles="$dlprefiles $lib" ;;
+ esac
+ done
+
+ if test "$build_libtool_libs" = yes; then
+ if test -n "$rpath"; then
+ case $host in
+ *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2* | *-*-beos* | *-cegcc*)
+ # these systems don't actually have a c library (as such)!
+ ;;
+ *-*-rhapsody* | *-*-darwin1.[012])
+ # Rhapsody C library is in the System framework
+ deplibs="$deplibs System.ltframework"
+ ;;
+ *-*-netbsd*)
+ # Don't link with libc until the a.out ld.so is fixed.
+ ;;
+ *-*-openbsd* | *-*-freebsd* | *-*-dragonfly*)
+ # Do not include libc due to us having libc/libc_r.
+ ;;
+ *-*-sco3.2v5* | *-*-sco5v6*)
+ # Causes problems with __ctype
+ ;;
+ *-*-sysv4.2uw2* | *-*-sysv5* | *-*-unixware* | *-*-OpenUNIX*)
+ # Compiler inserts libc in the correct place for threads to work
+ ;;
+ *)
+ # Add libc to deplibs on all other systems if necessary.
+ if test "$build_libtool_need_lc" = "yes"; then
+ deplibs="$deplibs -lc"
+ fi
+ ;;
+ esac
+ fi
+
+ # Transform deplibs into only deplibs that can be linked in shared.
+ name_save=$name
+ libname_save=$libname
+ release_save=$release
+ versuffix_save=$versuffix
+ major_save=$major
+ # I'm not sure if I'm treating the release correctly. I think
+ # release should show up in the -l (ie -lgmp5) so we don't want to
+ # add it in twice. Is that correct?
+ release=""
+ versuffix=""
+ major=""
+ newdeplibs=
+ droppeddeps=no
+ case $deplibs_check_method in
+ pass_all)
+ # Don't check for shared/static. Everything works.
+ # This might be a little naive. We might want to check
+ # whether the library exists or not. But this is on
+ # osf3 & osf4 and I'm not really sure... Just
+ # implementing what was already the behavior.
+ newdeplibs=$deplibs
+ ;;
+ test_compile)
+ # This code stresses the "libraries are programs" paradigm to its
+ # limits. Maybe even breaks it. We compile a program, linking it
+ # against the deplibs as a proxy for the library. Then we can check
+ # whether they linked in statically or dynamically with ldd.
+ $opt_dry_run || $RM conftest.c
+ cat > conftest.c <<EOF
+ int main() { return 0; }
+EOF
+ $opt_dry_run || $RM conftest
+ if $LTCC $LTCFLAGS -o conftest conftest.c $deplibs; then
+ ldd_output=`ldd conftest`
+ for i in $deplibs; do
+ case $i in
+ -l*)
+ func_stripname -l '' "$i"
+ name=$func_stripname_result
+ if test "X$allow_libtool_libs_with_static_runtimes" = "Xyes" ; then
+ case " $predeps $postdeps " in
+ *" $i "*)
+ newdeplibs="$newdeplibs $i"
+ i=""
+ ;;
+ esac
+ fi
+ if test -n "$i" ; then
+ libname=`eval "\\$ECHO \"$libname_spec\""`
+ deplib_matches=`eval "\\$ECHO \"$library_names_spec\""`
+ set dummy $deplib_matches; shift
+ deplib_match=$1
+ if test `expr "$ldd_output" : ".*$deplib_match"` -ne 0 ; then
+ newdeplibs="$newdeplibs $i"
+ else
+ droppeddeps=yes
+ $ECHO
+ $ECHO "*** Warning: dynamic linker does not accept needed library $i."
+ $ECHO "*** I have the capability to make that library automatically link in when"
+ $ECHO "*** you link to this library. But I can only do this if you have a"
+ $ECHO "*** shared version of the library, which I believe you do not have"
+ $ECHO "*** because a test_compile did reveal that the linker did not use it for"
+ $ECHO "*** its dynamic dependency list that programs get resolved with at runtime."
+ fi
+ fi
+ ;;
+ *)
+ newdeplibs="$newdeplibs $i"
+ ;;
+ esac
+ done
+ else
+ # Error occurred in the first compile. Let's try to salvage
+ # the situation: Compile a separate program for each library.
+ for i in $deplibs; do
+ case $i in
+ -l*)
+ func_stripname -l '' "$i"
+ name=$func_stripname_result
+ $opt_dry_run || $RM conftest
+ if $LTCC $LTCFLAGS -o conftest conftest.c $i; then
+ ldd_output=`ldd conftest`
+ if test "X$allow_libtool_libs_with_static_runtimes" = "Xyes" ; then
+ case " $predeps $postdeps " in
+ *" $i "*)
+ newdeplibs="$newdeplibs $i"
+ i=""
+ ;;
+ esac
+ fi
+ if test -n "$i" ; then
+ libname=`eval "\\$ECHO \"$libname_spec\""`
+ deplib_matches=`eval "\\$ECHO \"$library_names_spec\""`
+ set dummy $deplib_matches; shift
+ deplib_match=$1
+ if test `expr "$ldd_output" : ".*$deplib_match"` -ne 0 ; then
+ newdeplibs="$newdeplibs $i"
+ else
+ droppeddeps=yes
+ $ECHO
+ $ECHO "*** Warning: dynamic linker does not accept needed library $i."
+ $ECHO "*** I have the capability to make that library automatically link in when"
+ $ECHO "*** you link to this library. But I can only do this if you have a"
+ $ECHO "*** shared version of the library, which you do not appear to have"
+ $ECHO "*** because a test_compile did reveal that the linker did not use this one"
+ $ECHO "*** as a dynamic dependency that programs can get resolved with at runtime."
+ fi
+ fi
+ else
+ droppeddeps=yes
+ $ECHO
+ $ECHO "*** Warning! Library $i is needed by this library but I was not able to"
+ $ECHO "*** make it link in! You will probably need to install it or some"
+ $ECHO "*** library that it depends on before this library will be fully"
+ $ECHO "*** functional. Installing it before continuing would be even better."
+ fi
+ ;;
+ *)
+ newdeplibs="$newdeplibs $i"
+ ;;
+ esac
+ done
+ fi
+ ;;
+ file_magic*)
+ set dummy $deplibs_check_method; shift
+ file_magic_regex=`expr "$deplibs_check_method" : "$1 \(.*\)"`
+ for a_deplib in $deplibs; do
+ case $a_deplib in
+ -l*)
+ func_stripname -l '' "$a_deplib"
+ name=$func_stripname_result
+ if test "X$allow_libtool_libs_with_static_runtimes" = "Xyes" ; then
+ case " $predeps $postdeps " in
+ *" $a_deplib "*)
+ newdeplibs="$newdeplibs $a_deplib"
+ a_deplib=""
+ ;;
+ esac
+ fi
+ if test -n "$a_deplib" ; then
+ libname=`eval "\\$ECHO \"$libname_spec\""`
+ for i in $lib_search_path $sys_lib_search_path $shlib_search_path; do
+ potential_libs=`ls $i/$libname[.-]* 2>/dev/null`
+ for potent_lib in $potential_libs; do
+ # Follow soft links.
+ if ls -lLd "$potent_lib" 2>/dev/null |
+ $GREP " -> " >/dev/null; then
+ continue
+ fi
+ # The statement above tries to avoid entering an
+ # endless loop below, in case of cyclic links.
+ # We might still enter an endless loop, since a link
+ # loop can be closed while we follow links,
+ # but so what?
+ potlib="$potent_lib"
+ while test -h "$potlib" 2>/dev/null; do
+ potliblink=`ls -ld $potlib | ${SED} 's/.* -> //'`
+ case $potliblink in
+ [\\/]* | [A-Za-z]:[\\/]*) potlib="$potliblink";;
+ *) potlib=`$ECHO "X$potlib" | $Xsed -e 's,[^/]*$,,'`"$potliblink";;
+ esac
+ done
+ if eval $file_magic_cmd \"\$potlib\" 2>/dev/null |
+ $SED -e 10q |
+ $EGREP "$file_magic_regex" > /dev/null; then
+ newdeplibs="$newdeplibs $a_deplib"
+ a_deplib=""
+ break 2
+ fi
+ done
+ done
+ fi
+ if test -n "$a_deplib" ; then
+ droppeddeps=yes
+ $ECHO
+ $ECHO "*** Warning: linker path does not have real file for library $a_deplib."
+ $ECHO "*** I have the capability to make that library automatically link in when"
+ $ECHO "*** you link to this library. But I can only do this if you have a"
+ $ECHO "*** shared version of the library, which you do not appear to have"
+ $ECHO "*** because I did check the linker path looking for a file starting"
+ if test -z "$potlib" ; then
+ $ECHO "*** with $libname but no candidates were found. (...for file magic test)"
+ else
+ $ECHO "*** with $libname and none of the candidates passed a file format test"
+ $ECHO "*** using a file magic. Last file checked: $potlib"
+ fi
+ fi
+ ;;
+ *)
+ # Add a -L argument.
+ newdeplibs="$newdeplibs $a_deplib"
+ ;;
+ esac
+ done # Gone through all deplibs.
+ ;;
+ match_pattern*)
+ set dummy $deplibs_check_method; shift
+ match_pattern_regex=`expr "$deplibs_check_method" : "$1 \(.*\)"`
+ for a_deplib in $deplibs; do
+ case $a_deplib in
+ -l*)
+ func_stripname -l '' "$a_deplib"
+ name=$func_stripname_result
+ if test "X$allow_libtool_libs_with_static_runtimes" = "Xyes" ; then
+ case " $predeps $postdeps " in
+ *" $a_deplib "*)
+ newdeplibs="$newdeplibs $a_deplib"
+ a_deplib=""
+ ;;
+ esac
+ fi
+ if test -n "$a_deplib" ; then
+ libname=`eval "\\$ECHO \"$libname_spec\""`
+ for i in $lib_search_path $sys_lib_search_path $shlib_search_path; do
+ potential_libs=`ls $i/$libname[.-]* 2>/dev/null`
+ for potent_lib in $potential_libs; do
+ potlib="$potent_lib" # see symlink-check above in file_magic test
+ if eval "\$ECHO \"X$potent_lib\"" 2>/dev/null | $Xsed -e 10q | \
+ $EGREP "$match_pattern_regex" > /dev/null; then
+ newdeplibs="$newdeplibs $a_deplib"
+ a_deplib=""
+ break 2
+ fi
+ done
+ done
+ fi
+ if test -n "$a_deplib" ; then
+ droppeddeps=yes
+ $ECHO
+ $ECHO "*** Warning: linker path does not have real file for library $a_deplib."
+ $ECHO "*** I have the capability to make that library automatically link in when"
+ $ECHO "*** you link to this library. But I can only do this if you have a"
+ $ECHO "*** shared version of the library, which you do not appear to have"
+ $ECHO "*** because I did check the linker path looking for a file starting"
+ if test -z "$potlib" ; then
+ $ECHO "*** with $libname but no candidates were found. (...for regex pattern test)"
+ else
+ $ECHO "*** with $libname and none of the candidates passed a file format test"
+ $ECHO "*** using a regex pattern. Last file checked: $potlib"
+ fi
+ fi
+ ;;
+ *)
+ # Add a -L argument.
+ newdeplibs="$newdeplibs $a_deplib"
+ ;;
+ esac
+ done # Gone through all deplibs.
+ ;;
+ none | unknown | *)
+ newdeplibs=""
+ tmp_deplibs=`$ECHO "X $deplibs" | $Xsed \
+ -e 's/ -lc$//' -e 's/ -[LR][^ ]*//g'`
+ if test "X$allow_libtool_libs_with_static_runtimes" = "Xyes" ; then
+ for i in $predeps $postdeps ; do
+ # can't use Xsed below, because $i might contain '/'
+ tmp_deplibs=`$ECHO "X $tmp_deplibs" | $Xsed -e "s,$i,,"`
+ done
+ fi
+ if $ECHO "X $tmp_deplibs" | $Xsed -e 's/[ ]//g' |
+ $GREP . >/dev/null; then
+ $ECHO
+ if test "X$deplibs_check_method" = "Xnone"; then
+ $ECHO "*** Warning: inter-library dependencies are not supported in this platform."
+ else
+ $ECHO "*** Warning: inter-library dependencies are not known to be supported."
+ fi
+ $ECHO "*** All declared inter-library dependencies are being dropped."
+ droppeddeps=yes
+ fi
+ ;;
+ esac
+ versuffix=$versuffix_save
+ major=$major_save
+ release=$release_save
+ libname=$libname_save
+ name=$name_save
+
+ case $host in
+ *-*-rhapsody* | *-*-darwin1.[012])
+ # On Rhapsody replace the C library with the System framework
+ newdeplibs=`$ECHO "X $newdeplibs" | $Xsed -e 's/ -lc / System.ltframework /'`
+ ;;
+ esac
+
+ if test "$droppeddeps" = yes; then
+ if test "$module" = yes; then
+ $ECHO
+ $ECHO "*** Warning: libtool could not satisfy all declared inter-library"
+ $ECHO "*** dependencies of module $libname. Therefore, libtool will create"
+ $ECHO "*** a static module, that should work as long as the dlopening"
+ $ECHO "*** application is linked with the -dlopen flag."
+ if test -z "$global_symbol_pipe"; then
+ $ECHO
+ $ECHO "*** However, this would only work if libtool was able to extract symbol"
+ $ECHO "*** lists from a program, using \`nm' or equivalent, but libtool could"
+ $ECHO "*** not find such a program. So, this module is probably useless."
+ $ECHO "*** \`nm' from GNU binutils and a full rebuild may help."
+ fi
+ if test "$build_old_libs" = no; then
+ oldlibs="$output_objdir/$libname.$libext"
+ build_libtool_libs=module
+ build_old_libs=yes
+ else
+ build_libtool_libs=no
+ fi
+ else
+ $ECHO "*** The inter-library dependencies that have been dropped here will be"
+ $ECHO "*** automatically added whenever a program is linked with this library"
+ $ECHO "*** or is declared to -dlopen it."
+
+ if test "$allow_undefined" = no; then
+ $ECHO
+ $ECHO "*** Since this library must not contain undefined symbols,"
+ $ECHO "*** because either the platform does not support them or"
+ $ECHO "*** it was explicitly requested with -no-undefined,"
+ $ECHO "*** libtool will only create a static version of it."
+ if test "$build_old_libs" = no; then
+ oldlibs="$output_objdir/$libname.$libext"
+ build_libtool_libs=module
+ build_old_libs=yes
+ else
+ build_libtool_libs=no
+ fi
+ fi
+ fi
+ fi
+ # Done checking deplibs!
+ deplibs=$newdeplibs
+ fi
+ # Time to change all our "foo.ltframework" stuff back to "-framework foo"
+ case $host in
+ *-*-darwin*)
+ newdeplibs=`$ECHO "X $newdeplibs" | $Xsed -e 's% \([^ $]*\).ltframework% -framework \1%g'`
+ new_inherited_linker_flags=`$ECHO "X $new_inherited_linker_flags" | $Xsed -e 's% \([^ $]*\).ltframework% -framework \1%g'`
+ deplibs=`$ECHO "X $deplibs" | $Xsed -e 's% \([^ $]*\).ltframework% -framework \1%g'`
+ ;;
+ esac
+
+ # move library search paths that coincide with paths to not yet
+ # installed libraries to the beginning of the library search list
+ new_libs=
+ for path in $notinst_path; do
+ case " $new_libs " in
+ *" -L$path/$objdir "*) ;;
+ *)
+ case " $deplibs " in
+ *" -L$path/$objdir "*)
+ new_libs="$new_libs -L$path/$objdir" ;;
+ esac
+ ;;
+ esac
+ done
+ for deplib in $deplibs; do
+ case $deplib in
+ -L*)
+ case " $new_libs " in
+ *" $deplib "*) ;;
+ *) new_libs="$new_libs $deplib" ;;
+ esac
+ ;;
+ *) new_libs="$new_libs $deplib" ;;
+ esac
+ done
+ deplibs="$new_libs"
+
+ # All the library-specific variables (install_libdir is set above).
+ library_names=
+ old_library=
+ dlname=
+
+ # Test again, we may have decided not to build it any more
+ if test "$build_libtool_libs" = yes; then
+ if test "$hardcode_into_libs" = yes; then
+ # Hardcode the library paths
+ hardcode_libdirs=
+ dep_rpath=
+ rpath="$finalize_rpath"
+ test "$mode" != relink && rpath="$compile_rpath$rpath"
+ for libdir in $rpath; do
+ if test -n "$hardcode_libdir_flag_spec"; then
+ if test -n "$hardcode_libdir_separator"; then
+ if test -z "$hardcode_libdirs"; then
+ hardcode_libdirs="$libdir"
+ else
+ # Just accumulate the unique libdirs.
+ case $hardcode_libdir_separator$hardcode_libdirs$hardcode_libdir_separator in
+ *"$hardcode_libdir_separator$libdir$hardcode_libdir_separator"*)
+ ;;
+ *)
+ hardcode_libdirs="$hardcode_libdirs$hardcode_libdir_separator$libdir"
+ ;;
+ esac
+ fi
+ else
+ eval flag=\"$hardcode_libdir_flag_spec\"
+ dep_rpath="$dep_rpath $flag"
+ fi
+ elif test -n "$runpath_var"; then
+ case "$perm_rpath " in
+ *" $libdir "*) ;;
+ *) perm_rpath="$perm_rpath $libdir" ;;
+ esac
+ fi
+ done
+ # Substitute the hardcoded libdirs into the rpath.
+ if test -n "$hardcode_libdir_separator" &&
+ test -n "$hardcode_libdirs"; then
+ libdir="$hardcode_libdirs"
+ if test -n "$hardcode_libdir_flag_spec_ld"; then
+ eval dep_rpath=\"$hardcode_libdir_flag_spec_ld\"
+ else
+ eval dep_rpath=\"$hardcode_libdir_flag_spec\"
+ fi
+ fi
+ if test -n "$runpath_var" && test -n "$perm_rpath"; then
+ # We should set the runpath_var.
+ rpath=
+ for dir in $perm_rpath; do
+ rpath="$rpath$dir:"
+ done
+ eval "$runpath_var='$rpath\$$runpath_var'; export $runpath_var"
+ fi
+ test -n "$dep_rpath" && deplibs="$dep_rpath $deplibs"
+ fi
+
+ shlibpath="$finalize_shlibpath"
+ test "$mode" != relink && shlibpath="$compile_shlibpath$shlibpath"
+ if test -n "$shlibpath"; then
+ eval "$shlibpath_var='$shlibpath\$$shlibpath_var'; export $shlibpath_var"
+ fi
+
+ # Get the real and link names of the library.
+ eval shared_ext=\"$shrext_cmds\"
+ eval library_names=\"$library_names_spec\"
+ set dummy $library_names
+ shift
+ realname="$1"
+ shift
+
+ if test -n "$soname_spec"; then
+ eval soname=\"$soname_spec\"
+ else
+ soname="$realname"
+ fi
+ if test -z "$dlname"; then
+ dlname=$soname
+ fi
+
+ lib="$output_objdir/$realname"
+ linknames=
+ for link
+ do
+ linknames="$linknames $link"
+ done
+
+ # Use standard objects if they are pic
+ test -z "$pic_flag" && libobjs=`$ECHO "X$libobjs" | $SP2NL | $Xsed -e "$lo2o" | $NL2SP`
+ test "X$libobjs" = "X " && libobjs=
+
+ delfiles=
+ if test -n "$export_symbols" && test -n "$include_expsyms"; then
+ $opt_dry_run || cp "$export_symbols" "$output_objdir/$libname.uexp"
+ export_symbols="$output_objdir/$libname.uexp"
+ delfiles="$delfiles $export_symbols"
+ fi
+
+ orig_export_symbols=
+ case $host_os in
+ cygwin* | mingw* | cegcc*)
+ if test -n "$export_symbols" && test -z "$export_symbols_regex"; then
+ # exporting using user supplied symfile
+ if test "x`$SED 1q $export_symbols`" != xEXPORTS; then
+ # and it's NOT already a .def file. Must figure out
+ # which of the given symbols are data symbols and tag
+ # them as such. So, trigger use of export_symbols_cmds.
+ # export_symbols gets reassigned inside the "prepare
+ # the list of exported symbols" if statement, so the
+ # include_expsyms logic still works.
+ orig_export_symbols="$export_symbols"
+ export_symbols=
+ always_export_symbols=yes
+ fi
+ fi
+ ;;
+ esac
+
+ # Prepare the list of exported symbols
+ if test -z "$export_symbols"; then
+ if test "$always_export_symbols" = yes || test -n "$export_symbols_regex"; then
+ func_verbose "generating symbol list for \`$libname.la'"
+ export_symbols="$output_objdir/$libname.exp"
+ $opt_dry_run || $RM $export_symbols
+ cmds=$export_symbols_cmds
+ save_ifs="$IFS"; IFS='~'
+ for cmd in $cmds; do
+ IFS="$save_ifs"
+ eval cmd=\"$cmd\"
+ func_len " $cmd"
+ len=$func_len_result
+ if test "$len" -lt "$max_cmd_len" || test "$max_cmd_len" -le -1; then
+ func_show_eval "$cmd" 'exit $?'
+ skipped_export=false
+ else
+ # The command line is too long to execute in one step.
+ func_verbose "using reloadable object file for export list..."
+ skipped_export=:
+ # Break out early, otherwise skipped_export may be
+ # set to false by a later but shorter cmd.
+ break
+ fi
+ done
+ IFS="$save_ifs"
+ if test -n "$export_symbols_regex" && test "X$skipped_export" != "X:"; then
+ func_show_eval '$EGREP -e "$export_symbols_regex" "$export_symbols" > "${export_symbols}T"'
+ func_show_eval '$MV "${export_symbols}T" "$export_symbols"'
+ fi
+ fi
+ fi
+
+ if test -n "$export_symbols" && test -n "$include_expsyms"; then
+ tmp_export_symbols="$export_symbols"
+ test -n "$orig_export_symbols" && tmp_export_symbols="$orig_export_symbols"
+ $opt_dry_run || eval '$ECHO "X$include_expsyms" | $Xsed | $SP2NL >> "$tmp_export_symbols"'
+ fi
+
+ if test "X$skipped_export" != "X:" && test -n "$orig_export_symbols"; then
+ # The given exports_symbols file has to be filtered, so filter it.
+ func_verbose "filter symbol list for \`$libname.la' to tag DATA exports"
+ # FIXME: $output_objdir/$libname.filter potentially contains lots of
+ # 's' commands which not all seds can handle. GNU sed should be fine
+ # though. Also, the filter scales superlinearly with the number of
+ # global variables. join(1) would be nice here, but unfortunately
+ # isn't a blessed tool.
+ $opt_dry_run || $SED -e '/[ ,]DATA/!d;s,\(.*\)\([ \,].*\),s|^\1$|\1\2|,' < $export_symbols > $output_objdir/$libname.filter
+ delfiles="$delfiles $export_symbols $output_objdir/$libname.filter"
+ export_symbols=$output_objdir/$libname.def
+ $opt_dry_run || $SED -f $output_objdir/$libname.filter < $orig_export_symbols > $export_symbols
+ fi
+
+ tmp_deplibs=
+ for test_deplib in $deplibs; do
+ case " $convenience " in
+ *" $test_deplib "*) ;;
+ *)
+ tmp_deplibs="$tmp_deplibs $test_deplib"
+ ;;
+ esac
+ done
+ deplibs="$tmp_deplibs"
+
+ if test -n "$convenience"; then
+ if test -n "$whole_archive_flag_spec" &&
+ test "$compiler_needs_object" = yes &&
+ test -z "$libobjs"; then
+ # extract the archives, so we have objects to list.
+ # TODO: could optimize this to just extract one archive.
+ whole_archive_flag_spec=
+ fi
+ if test -n "$whole_archive_flag_spec"; then
+ save_libobjs=$libobjs
+ eval libobjs=\"\$libobjs $whole_archive_flag_spec\"
+ test "X$libobjs" = "X " && libobjs=
+ else
+ gentop="$output_objdir/${outputname}x"
+ generated="$generated $gentop"
+
+ func_extract_archives $gentop $convenience
+ libobjs="$libobjs $func_extract_archives_result"
+ test "X$libobjs" = "X " && libobjs=
+ fi
+ fi
+
+ if test "$thread_safe" = yes && test -n "$thread_safe_flag_spec"; then
+ eval flag=\"$thread_safe_flag_spec\"
+ linker_flags="$linker_flags $flag"
+ fi
+
+ # Make a backup of the uninstalled library when relinking
+ if test "$mode" = relink; then
+ $opt_dry_run || eval '(cd $output_objdir && $RM ${realname}U && $MV $realname ${realname}U)' || exit $?
+ fi
+
+ # Do each of the archive commands.
+ if test "$module" = yes && test -n "$module_cmds" ; then
+ if test -n "$export_symbols" && test -n "$module_expsym_cmds"; then
+ eval test_cmds=\"$module_expsym_cmds\"
+ cmds=$module_expsym_cmds
+ else
+ eval test_cmds=\"$module_cmds\"
+ cmds=$module_cmds
+ fi
+ else
+ if test -n "$export_symbols" && test -n "$archive_expsym_cmds"; then
+ eval test_cmds=\"$archive_expsym_cmds\"
+ cmds=$archive_expsym_cmds
+ else
+ eval test_cmds=\"$archive_cmds\"
+ cmds=$archive_cmds
+ fi
+ fi
+
+ if test "X$skipped_export" != "X:" &&
+ func_len " $test_cmds" &&
+ len=$func_len_result &&
+ test "$len" -lt "$max_cmd_len" || test "$max_cmd_len" -le -1; then
+ :
+ else
+ # The command line is too long to link in one step, link piecewise
+ # or, if using GNU ld and skipped_export is not :, use a linker
+ # script.
+
+ # Save the value of $output and $libobjs because we want to
+ # use them later. If we have whole_archive_flag_spec, we
+ # want to use save_libobjs as it was before
+ # whole_archive_flag_spec was expanded, because we can't
+ # assume the linker understands whole_archive_flag_spec.
+ # This may have to be revisited, in case too many
+ # convenience libraries get linked in and end up exceeding
+ # the spec.
+ if test -z "$convenience" || test -z "$whole_archive_flag_spec"; then
+ save_libobjs=$libobjs
+ fi
+ save_output=$output
+ output_la=`$ECHO "X$output" | $Xsed -e "$basename"`
+
+ # Clear the reloadable object creation command queue and
+ # initialize k to one.
+ test_cmds=
+ concat_cmds=
+ objlist=
+ last_robj=
+ k=1
+
+ if test -n "$save_libobjs" && test "X$skipped_export" != "X:" && test "$with_gnu_ld" = yes; then
+ output=${output_objdir}/${output_la}.lnkscript
+ func_verbose "creating GNU ld script: $output"
+ $ECHO 'INPUT (' > $output
+ for obj in $save_libobjs
+ do
+ $ECHO "$obj" >> $output
+ done
+ $ECHO ')' >> $output
+ delfiles="$delfiles $output"
+ elif test -n "$save_libobjs" && test "X$skipped_export" != "X:" && test "X$file_list_spec" != X; then
+ output=${output_objdir}/${output_la}.lnk
+ func_verbose "creating linker input file list: $output"
+ : > $output
+ set x $save_libobjs
+ shift
+ firstobj=
+ if test "$compiler_needs_object" = yes; then
+ firstobj="$1 "
+ shift
+ fi
+ for obj
+ do
+ $ECHO "$obj" >> $output
+ done
+ delfiles="$delfiles $output"
+ output=$firstobj\"$file_list_spec$output\"
+ else
+ if test -n "$save_libobjs"; then
+ func_verbose "creating reloadable object files..."
+ output=$output_objdir/$output_la-${k}.$objext
+ eval test_cmds=\"$reload_cmds\"
+ func_len " $test_cmds"
+ len0=$func_len_result
+ len=$len0
+
+ # Loop over the list of objects to be linked.
+ for obj in $save_libobjs
+ do
+ func_len " $obj"
+ func_arith $len + $func_len_result
+ len=$func_arith_result
+ if test "X$objlist" = X ||
+ test "$len" -lt "$max_cmd_len"; then
+ func_append objlist " $obj"
+ else
+ # The command $test_cmds is almost too long, add a
+ # command to the queue.
+ if test "$k" -eq 1 ; then
+ # The first file doesn't have a previous command to add.
+ eval concat_cmds=\"$reload_cmds $objlist $last_robj\"
+ else
+ # All subsequent reloadable object files will link in
+ # the last one created.
+ eval concat_cmds=\"\$concat_cmds~$reload_cmds $objlist $last_robj~\$RM $last_robj\"
+ fi
+ last_robj=$output_objdir/$output_la-${k}.$objext
+ func_arith $k + 1
+ k=$func_arith_result
+ output=$output_objdir/$output_la-${k}.$objext
+ objlist=$obj
+ func_len " $last_robj"
+ func_arith $len0 + $func_len_result
+ len=$func_arith_result
+ fi
+ done
+ # Handle the remaining objects by creating one last
+ # reloadable object file. All subsequent reloadable object
+ # files will link in the last one created.
+ test -z "$concat_cmds" || concat_cmds=$concat_cmds~
+ eval concat_cmds=\"\${concat_cmds}$reload_cmds $objlist $last_robj\"
+ if test -n "$last_robj"; then
+ eval concat_cmds=\"\${concat_cmds}~\$RM $last_robj\"
+ fi
+ delfiles="$delfiles $output"
+
+ else
+ output=
+ fi
+
+ if ${skipped_export-false}; then
+ func_verbose "generating symbol list for \`$libname.la'"
+ export_symbols="$output_objdir/$libname.exp"
+ $opt_dry_run || $RM $export_symbols
+ libobjs=$output
+ # Append the command to create the export file.
+ test -z "$concat_cmds" || concat_cmds=$concat_cmds~
+ eval concat_cmds=\"\$concat_cmds$export_symbols_cmds\"
+ if test -n "$last_robj"; then
+ eval concat_cmds=\"\$concat_cmds~\$RM $last_robj\"
+ fi
+ fi
+
+ test -n "$save_libobjs" &&
+ func_verbose "creating a temporary reloadable object file: $output"
+
+ # Loop through the commands generated above and execute them.
+ save_ifs="$IFS"; IFS='~'
+ for cmd in $concat_cmds; do
+ IFS="$save_ifs"
+ $opt_silent || {
+ func_quote_for_expand "$cmd"
+ eval "func_echo $func_quote_for_expand_result"
+ }
+ $opt_dry_run || eval "$cmd" || {
+ lt_exit=$?
+
+ # Restore the uninstalled library and exit
+ if test "$mode" = relink; then
+ ( cd "$output_objdir" && \
+ $RM "${realname}T" && \
+ $MV "${realname}U" "$realname" )
+ fi
+
+ exit $lt_exit
+ }
+ done
+ IFS="$save_ifs"
+
+ if test -n "$export_symbols_regex" && ${skipped_export-false}; then
+ func_show_eval '$EGREP -e "$export_symbols_regex" "$export_symbols" > "${export_symbols}T"'
+ func_show_eval '$MV "${export_symbols}T" "$export_symbols"'
+ fi
+ fi
+
+ if ${skipped_export-false}; then
+ if test -n "$export_symbols" && test -n "$include_expsyms"; then
+ tmp_export_symbols="$export_symbols"
+ test -n "$orig_export_symbols" && tmp_export_symbols="$orig_export_symbols"
+ $opt_dry_run || eval '$ECHO "X$include_expsyms" | $Xsed | $SP2NL >> "$tmp_export_symbols"'
+ fi
+
+ if test -n "$orig_export_symbols"; then
+ # The given exports_symbols file has to be filtered, so filter it.
+ func_verbose "filter symbol list for \`$libname.la' to tag DATA exports"
+ # FIXME: $output_objdir/$libname.filter potentially contains lots of
+ # 's' commands which not all seds can handle. GNU sed should be fine
+ # though. Also, the filter scales superlinearly with the number of
+ # global variables. join(1) would be nice here, but unfortunately
+ # isn't a blessed tool.
+ $opt_dry_run || $SED -e '/[ ,]DATA/!d;s,\(.*\)\([ \,].*\),s|^\1$|\1\2|,' < $export_symbols > $output_objdir/$libname.filter
+ delfiles="$delfiles $export_symbols $output_objdir/$libname.filter"
+ export_symbols=$output_objdir/$libname.def
+ $opt_dry_run || $SED -f $output_objdir/$libname.filter < $orig_export_symbols > $export_symbols
+ fi
+ fi
+
+ libobjs=$output
+ # Restore the value of output.
+ output=$save_output
+
+ if test -n "$convenience" && test -n "$whole_archive_flag_spec"; then
+ eval libobjs=\"\$libobjs $whole_archive_flag_spec\"
+ test "X$libobjs" = "X " && libobjs=
+ fi
+ # Expand the library linking commands again to reset the
+ # value of $libobjs for piecewise linking.
+
+ # Do each of the archive commands.
+ if test "$module" = yes && test -n "$module_cmds" ; then
+ if test -n "$export_symbols" && test -n "$module_expsym_cmds"; then
+ cmds=$module_expsym_cmds
+ else
+ cmds=$module_cmds
+ fi
+ else
+ if test -n "$export_symbols" && test -n "$archive_expsym_cmds"; then
+ cmds=$archive_expsym_cmds
+ else
+ cmds=$archive_cmds
+ fi
+ fi
+ fi
+
+ if test -n "$delfiles"; then
+ # Append the command to remove temporary files to $cmds.
+ eval cmds=\"\$cmds~\$RM $delfiles\"
+ fi
+
+ # Add any objects from preloaded convenience libraries
+ if test -n "$dlprefiles"; then
+ gentop="$output_objdir/${outputname}x"
+ generated="$generated $gentop"
+
+ func_extract_archives $gentop $dlprefiles
+ libobjs="$libobjs $func_extract_archives_result"
+ test "X$libobjs" = "X " && libobjs=
+ fi
+
+ save_ifs="$IFS"; IFS='~'
+ for cmd in $cmds; do
+ IFS="$save_ifs"
+ eval cmd=\"$cmd\"
+ $opt_silent || {
+ func_quote_for_expand "$cmd"
+ eval "func_echo $func_quote_for_expand_result"
+ }
+ $opt_dry_run || eval "$cmd" || {
+ lt_exit=$?
+
+ # Restore the uninstalled library and exit
+ if test "$mode" = relink; then
+ ( cd "$output_objdir" && \
+ $RM "${realname}T" && \
+ $MV "${realname}U" "$realname" )
+ fi
+
+ exit $lt_exit
+ }
+ done
+ IFS="$save_ifs"
+
+ # Restore the uninstalled library and exit
+ if test "$mode" = relink; then
+ $opt_dry_run || eval '(cd $output_objdir && $RM ${realname}T && $MV $realname ${realname}T && $MV ${realname}U $realname)' || exit $?
+
+ if test -n "$convenience"; then
+ if test -z "$whole_archive_flag_spec"; then
+ func_show_eval '${RM}r "$gentop"'
+ fi
+ fi
+
+ exit $EXIT_SUCCESS
+ fi
+
+ # Create links to the real library.
+ for linkname in $linknames; do
+ if test "$realname" != "$linkname"; then
+ func_show_eval '(cd "$output_objdir" && $RM "$linkname" && $LN_S "$realname" "$linkname")' 'exit $?'
+ fi
+ done
+
+ # If -module or -export-dynamic was specified, set the dlname.
+ if test "$module" = yes || test "$export_dynamic" = yes; then
+ # On all known operating systems, these are identical.
+ dlname="$soname"
+ fi
+ fi
+ ;;
+
+ obj)
+ if test -n "$dlfiles$dlprefiles" || test "$dlself" != no; then
+ func_warning "\`-dlopen' is ignored for objects"
+ fi
+
+ case " $deplibs" in
+ *\ -l* | *\ -L*)
+ func_warning "\`-l' and \`-L' are ignored for objects" ;;
+ esac
+
+ test -n "$rpath" && \
+ func_warning "\`-rpath' is ignored for objects"
+
+ test -n "$xrpath" && \
+ func_warning "\`-R' is ignored for objects"
+
+ test -n "$vinfo" && \
+ func_warning "\`-version-info' is ignored for objects"
+
+ test -n "$release" && \
+ func_warning "\`-release' is ignored for objects"
+
+ case $output in
+ *.lo)
+ test -n "$objs$old_deplibs" && \
+ func_fatal_error "cannot build library object \`$output' from non-libtool objects"
+
+ libobj=$output
+ func_lo2o "$libobj"
+ obj=$func_lo2o_result
+ ;;
+ *)
+ libobj=
+ obj="$output"
+ ;;
+ esac
+
+ # Delete the old objects.
+ $opt_dry_run || $RM $obj $libobj
+
+ # Objects from convenience libraries. This assumes
+ # single-version convenience libraries. Whenever we create
+ # different ones for PIC/non-PIC, this we'll have to duplicate
+ # the extraction.
+ reload_conv_objs=
+ gentop=
+ # reload_cmds runs $LD directly, so let us get rid of
+ # -Wl from whole_archive_flag_spec and hope we can get by with
+ # turning comma into space..
+ wl=
+
+ if test -n "$convenience"; then
+ if test -n "$whole_archive_flag_spec"; then
+ eval tmp_whole_archive_flags=\"$whole_archive_flag_spec\"
+ reload_conv_objs=$reload_objs\ `$ECHO "X$tmp_whole_archive_flags" | $Xsed -e 's|,| |g'`
+ else
+ gentop="$output_objdir/${obj}x"
+ generated="$generated $gentop"
+
+ func_extract_archives $gentop $convenience
+ reload_conv_objs="$reload_objs $func_extract_archives_result"
+ fi
+ fi
+
+ # Create the old-style object.
+ reload_objs="$objs$old_deplibs "`$ECHO "X$libobjs" | $SP2NL | $Xsed -e '/\.'${libext}$'/d' -e '/\.lib$/d' -e "$lo2o" | $NL2SP`" $reload_conv_objs" ### testsuite: skip nested quoting test
+
+ output="$obj"
+ func_execute_cmds "$reload_cmds" 'exit $?'
+
+ # Exit if we aren't doing a library object file.
+ if test -z "$libobj"; then
+ if test -n "$gentop"; then
+ func_show_eval '${RM}r "$gentop"'
+ fi
+
+ exit $EXIT_SUCCESS
+ fi
+
+ if test "$build_libtool_libs" != yes; then
+ if test -n "$gentop"; then
+ func_show_eval '${RM}r "$gentop"'
+ fi
+
+ # Create an invalid libtool object if no PIC, so that we don't
+ # accidentally link it into a program.
+ # $show "echo timestamp > $libobj"
+ # $opt_dry_run || eval "echo timestamp > $libobj" || exit $?
+ exit $EXIT_SUCCESS
+ fi
+
+ if test -n "$pic_flag" || test "$pic_mode" != default; then
+ # Only do commands if we really have different PIC objects.
+ reload_objs="$libobjs $reload_conv_objs"
+ output="$libobj"
+ func_execute_cmds "$reload_cmds" 'exit $?'
+ fi
+
+ if test -n "$gentop"; then
+ func_show_eval '${RM}r "$gentop"'
+ fi
+
+ exit $EXIT_SUCCESS
+ ;;
+
+ prog)
+ case $host in
+ *cygwin*) func_stripname '' '.exe' "$output"
+ output=$func_stripname_result.exe;;
+ esac
+ test -n "$vinfo" && \
+ func_warning "\`-version-info' is ignored for programs"
+
+ test -n "$release" && \
+ func_warning "\`-release' is ignored for programs"
+
+ test "$preload" = yes \
+ && test "$dlopen_support" = unknown \
+ && test "$dlopen_self" = unknown \
+ && test "$dlopen_self_static" = unknown && \
+ func_warning "\`LT_INIT([dlopen])' not used. Assuming no dlopen support."
+
+ case $host in
+ *-*-rhapsody* | *-*-darwin1.[012])
+ # On Rhapsody replace the C library is the System framework
+ compile_deplibs=`$ECHO "X $compile_deplibs" | $Xsed -e 's/ -lc / System.ltframework /'`
+ finalize_deplibs=`$ECHO "X $finalize_deplibs" | $Xsed -e 's/ -lc / System.ltframework /'`
+ ;;
+ esac
+
+ case $host in
+ *-*-darwin*)
+ # Don't allow lazy linking, it breaks C++ global constructors
+ # But is supposedly fixed on 10.4 or later (yay!).
+ if test "$tagname" = CXX ; then
+ case ${MACOSX_DEPLOYMENT_TARGET-10.0} in
+ 10.[0123])
+ compile_command="$compile_command ${wl}-bind_at_load"
+ finalize_command="$finalize_command ${wl}-bind_at_load"
+ ;;
+ esac
+ fi
+ # Time to change all our "foo.ltframework" stuff back to "-framework foo"
+ compile_deplibs=`$ECHO "X $compile_deplibs" | $Xsed -e 's% \([^ $]*\).ltframework% -framework \1%g'`
+ finalize_deplibs=`$ECHO "X $finalize_deplibs" | $Xsed -e 's% \([^ $]*\).ltframework% -framework \1%g'`
+ ;;
+ esac
+
+
+ # move library search paths that coincide with paths to not yet
+ # installed libraries to the beginning of the library search list
+ new_libs=
+ for path in $notinst_path; do
+ case " $new_libs " in
+ *" -L$path/$objdir "*) ;;
+ *)
+ case " $compile_deplibs " in
+ *" -L$path/$objdir "*)
+ new_libs="$new_libs -L$path/$objdir" ;;
+ esac
+ ;;
+ esac
+ done
+ for deplib in $compile_deplibs; do
+ case $deplib in
+ -L*)
+ case " $new_libs " in
+ *" $deplib "*) ;;
+ *) new_libs="$new_libs $deplib" ;;
+ esac
+ ;;
+ *) new_libs="$new_libs $deplib" ;;
+ esac
+ done
+ compile_deplibs="$new_libs"
+
+
+ compile_command="$compile_command $compile_deplibs"
+ finalize_command="$finalize_command $finalize_deplibs"
+
+ if test -n "$rpath$xrpath"; then
+ # If the user specified any rpath flags, then add them.
+ for libdir in $rpath $xrpath; do
+ # This is the magic to use -rpath.
+ case "$finalize_rpath " in
+ *" $libdir "*) ;;
+ *) finalize_rpath="$finalize_rpath $libdir" ;;
+ esac
+ done
+ fi
+
+ # Now hardcode the library paths
+ rpath=
+ hardcode_libdirs=
+ for libdir in $compile_rpath $finalize_rpath; do
+ if test -n "$hardcode_libdir_flag_spec"; then
+ if test -n "$hardcode_libdir_separator"; then
+ if test -z "$hardcode_libdirs"; then
+ hardcode_libdirs="$libdir"
+ else
+ # Just accumulate the unique libdirs.
+ case $hardcode_libdir_separator$hardcode_libdirs$hardcode_libdir_separator in
+ *"$hardcode_libdir_separator$libdir$hardcode_libdir_separator"*)
+ ;;
+ *)
+ hardcode_libdirs="$hardcode_libdirs$hardcode_libdir_separator$libdir"
+ ;;
+ esac
+ fi
+ else
+ eval flag=\"$hardcode_libdir_flag_spec\"
+ rpath="$rpath $flag"
+ fi
+ elif test -n "$runpath_var"; then
+ case "$perm_rpath " in
+ *" $libdir "*) ;;
+ *) perm_rpath="$perm_rpath $libdir" ;;
+ esac
+ fi
+ case $host in
+ *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2* | *-cegcc*)
+ testbindir=`${ECHO} "$libdir" | ${SED} -e 's*/lib$*/bin*'`
+ case :$dllsearchpath: in
+ *":$libdir:"*) ;;
+ ::) dllsearchpath=$libdir;;
+ *) dllsearchpath="$dllsearchpath:$libdir";;
+ esac
+ case :$dllsearchpath: in
+ *":$testbindir:"*) ;;
+ ::) dllsearchpath=$testbindir;;
+ *) dllsearchpath="$dllsearchpath:$testbindir";;
+ esac
+ ;;
+ esac
+ done
+ # Substitute the hardcoded libdirs into the rpath.
+ if test -n "$hardcode_libdir_separator" &&
+ test -n "$hardcode_libdirs"; then
+ libdir="$hardcode_libdirs"
+ eval rpath=\" $hardcode_libdir_flag_spec\"
+ fi
+ compile_rpath="$rpath"
+
+ rpath=
+ hardcode_libdirs=
+ for libdir in $finalize_rpath; do
+ if test -n "$hardcode_libdir_flag_spec"; then
+ if test -n "$hardcode_libdir_separator"; then
+ if test -z "$hardcode_libdirs"; then
+ hardcode_libdirs="$libdir"
+ else
+ # Just accumulate the unique libdirs.
+ case $hardcode_libdir_separator$hardcode_libdirs$hardcode_libdir_separator in
+ *"$hardcode_libdir_separator$libdir$hardcode_libdir_separator"*)
+ ;;
+ *)
+ hardcode_libdirs="$hardcode_libdirs$hardcode_libdir_separator$libdir"
+ ;;
+ esac
+ fi
+ else
+ eval flag=\"$hardcode_libdir_flag_spec\"
+ rpath="$rpath $flag"
+ fi
+ elif test -n "$runpath_var"; then
+ case "$finalize_perm_rpath " in
+ *" $libdir "*) ;;
+ *) finalize_perm_rpath="$finalize_perm_rpath $libdir" ;;
+ esac
+ fi
+ done
+ # Substitute the hardcoded libdirs into the rpath.
+ if test -n "$hardcode_libdir_separator" &&
+ test -n "$hardcode_libdirs"; then
+ libdir="$hardcode_libdirs"
+ eval rpath=\" $hardcode_libdir_flag_spec\"
+ fi
+ finalize_rpath="$rpath"
+
+ if test -n "$libobjs" && test "$build_old_libs" = yes; then
+ # Transform all the library objects into standard objects.
+ compile_command=`$ECHO "X$compile_command" | $SP2NL | $Xsed -e "$lo2o" | $NL2SP`
+ finalize_command=`$ECHO "X$finalize_command" | $SP2NL | $Xsed -e "$lo2o" | $NL2SP`
+ fi
+
+ func_generate_dlsyms "$outputname" "@PROGRAM@" "no"
+
+ # template prelinking step
+ if test -n "$prelink_cmds"; then
+ func_execute_cmds "$prelink_cmds" 'exit $?'
+ fi
+
+ wrappers_required=yes
+ case $host in
+ *cygwin* | *mingw* )
+ if test "$build_libtool_libs" != yes; then
+ wrappers_required=no
+ fi
+ ;;
+ *cegcc)
+ # Disable wrappers for cegcc, we are cross compiling anyway.
+ wrappers_required=no
+ ;;
+ *)
+ if test "$need_relink" = no || test "$build_libtool_libs" != yes; then
+ wrappers_required=no
+ fi
+ ;;
+ esac
+ if test "$wrappers_required" = no; then
+ # Replace the output file specification.
+ compile_command=`$ECHO "X$compile_command" | $Xsed -e 's%@OUTPUT@%'"$output"'%g'`
+ link_command="$compile_command$compile_rpath"
+
+ # We have no uninstalled library dependencies, so finalize right now.
+ exit_status=0
+ func_show_eval "$link_command" 'exit_status=$?'
+
+ # Delete the generated files.
+ if test -f "$output_objdir/${outputname}S.${objext}"; then
+ func_show_eval '$RM "$output_objdir/${outputname}S.${objext}"'
+ fi
+
+ exit $exit_status
+ fi
+
+ if test -n "$compile_shlibpath$finalize_shlibpath"; then
+ compile_command="$shlibpath_var=\"$compile_shlibpath$finalize_shlibpath\$$shlibpath_var\" $compile_command"
+ fi
+ if test -n "$finalize_shlibpath"; then
+ finalize_command="$shlibpath_var=\"$finalize_shlibpath\$$shlibpath_var\" $finalize_command"
+ fi
+
+ compile_var=
+ finalize_var=
+ if test -n "$runpath_var"; then
+ if test -n "$perm_rpath"; then
+ # We should set the runpath_var.
+ rpath=
+ for dir in $perm_rpath; do
+ rpath="$rpath$dir:"
+ done
+ compile_var="$runpath_var=\"$rpath\$$runpath_var\" "
+ fi
+ if test -n "$finalize_perm_rpath"; then
+ # We should set the runpath_var.
+ rpath=
+ for dir in $finalize_perm_rpath; do
+ rpath="$rpath$dir:"
+ done
+ finalize_var="$runpath_var=\"$rpath\$$runpath_var\" "
+ fi
+ fi
+
+ if test "$no_install" = yes; then
+ # We don't need to create a wrapper script.
+ link_command="$compile_var$compile_command$compile_rpath"
+ # Replace the output file specification.
+ link_command=`$ECHO "X$link_command" | $Xsed -e 's%@OUTPUT@%'"$output"'%g'`
+ # Delete the old output file.
+ $opt_dry_run || $RM $output
+ # Link the executable and exit
+ func_show_eval "$link_command" 'exit $?'
+ exit $EXIT_SUCCESS
+ fi
+
+ if test "$hardcode_action" = relink; then
+ # Fast installation is not supported
+ link_command="$compile_var$compile_command$compile_rpath"
+ relink_command="$finalize_var$finalize_command$finalize_rpath"
+
+ func_warning "this platform does not like uninstalled shared libraries"
+ func_warning "\`$output' will be relinked during installation"
+ else
+ if test "$fast_install" != no; then
+ link_command="$finalize_var$compile_command$finalize_rpath"
+ if test "$fast_install" = yes; then
+ relink_command=`$ECHO "X$compile_var$compile_command$compile_rpath" | $Xsed -e 's%@OUTPUT@%\$progdir/\$file%g'`
+ else
+ # fast_install is set to needless
+ relink_command=
+ fi
+ else
+ link_command="$compile_var$compile_command$compile_rpath"
+ relink_command="$finalize_var$finalize_command$finalize_rpath"
+ fi
+ fi
+
+ # Replace the output file specification.
+ link_command=`$ECHO "X$link_command" | $Xsed -e 's%@OUTPUT@%'"$output_objdir/$outputname"'%g'`
+
+ # Delete the old output files.
+ $opt_dry_run || $RM $output $output_objdir/$outputname $output_objdir/lt-$outputname
+
+ func_show_eval "$link_command" 'exit $?'
+
+ # Now create the wrapper script.
+ func_verbose "creating $output"
+
+ # Quote the relink command for shipping.
+ if test -n "$relink_command"; then
+ # Preserve any variables that may affect compiler behavior
+ for var in $variables_saved_for_relink; do
+ if eval test -z \"\${$var+set}\"; then
+ relink_command="{ test -z \"\${$var+set}\" || $lt_unset $var || { $var=; export $var; }; }; $relink_command"
+ elif eval var_value=\$$var; test -z "$var_value"; then
+ relink_command="$var=; export $var; $relink_command"
+ else
+ func_quote_for_eval "$var_value"
+ relink_command="$var=$func_quote_for_eval_result; export $var; $relink_command"
+ fi
+ done
+ relink_command="(cd `pwd`; $relink_command)"
+ relink_command=`$ECHO "X$relink_command" | $Xsed -e "$sed_quote_subst"`
+ fi
+
+ # Quote $ECHO for shipping.
+ if test "X$ECHO" = "X$SHELL $progpath --fallback-echo"; then
+ case $progpath in
+ [\\/]* | [A-Za-z]:[\\/]*) qecho="$SHELL $progpath --fallback-echo";;
+ *) qecho="$SHELL `pwd`/$progpath --fallback-echo";;
+ esac
+ qecho=`$ECHO "X$qecho" | $Xsed -e "$sed_quote_subst"`
+ else
+ qecho=`$ECHO "X$ECHO" | $Xsed -e "$sed_quote_subst"`
+ fi
+
+ # Only actually do things if not in dry run mode.
+ $opt_dry_run || {
+ # win32 will think the script is a binary if it has
+ # a .exe suffix, so we strip it off here.
+ case $output in
+ *.exe) func_stripname '' '.exe' "$output"
+ output=$func_stripname_result ;;
+ esac
+ # test for cygwin because mv fails w/o .exe extensions
+ case $host in
+ *cygwin*)
+ exeext=.exe
+ func_stripname '' '.exe' "$outputname"
+ outputname=$func_stripname_result ;;
+ *) exeext= ;;
+ esac
+ case $host in
+ *cygwin* | *mingw* )
+ func_dirname_and_basename "$output" "" "."
+ output_name=$func_basename_result
+ output_path=$func_dirname_result
+ cwrappersource="$output_path/$objdir/lt-$output_name.c"
+ cwrapper="$output_path/$output_name.exe"
+ $RM $cwrappersource $cwrapper
+ trap "$RM $cwrappersource $cwrapper; exit $EXIT_FAILURE" 1 2 15
+
+ func_emit_cwrapperexe_src > $cwrappersource
+
+ # The wrapper executable is built using the $host compiler,
+ # because it contains $host paths and files. If cross-
+ # compiling, it, like the target executable, must be
+ # executed on the $host or under an emulation environment.
+ $opt_dry_run || {
+ $LTCC $LTCFLAGS -o $cwrapper $cwrappersource
+ $STRIP $cwrapper
+ }
+
+ # Now, create the wrapper script for func_source use:
+ func_ltwrapper_scriptname $cwrapper
+ $RM $func_ltwrapper_scriptname_result
+ trap "$RM $func_ltwrapper_scriptname_result; exit $EXIT_FAILURE" 1 2 15
+ $opt_dry_run || {
+ # note: this script will not be executed, so do not chmod.
+ if test "x$build" = "x$host" ; then
+ $cwrapper --lt-dump-script > $func_ltwrapper_scriptname_result
+ else
+ func_emit_wrapper no > $func_ltwrapper_scriptname_result
+ fi
+ }
+ ;;
+ * )
+ $RM $output
+ trap "$RM $output; exit $EXIT_FAILURE" 1 2 15
+
+ func_emit_wrapper no > $output
+ chmod +x $output
+ ;;
+ esac
+ }
+ exit $EXIT_SUCCESS
+ ;;
+ esac
+
+ # See if we need to build an old-fashioned archive.
+ for oldlib in $oldlibs; do
+
+ if test "$build_libtool_libs" = convenience; then
+ oldobjs="$libobjs_save $symfileobj"
+ addlibs="$convenience"
+ build_libtool_libs=no
+ else
+ if test "$build_libtool_libs" = module; then
+ oldobjs="$libobjs_save"
+ build_libtool_libs=no
+ else
+ oldobjs="$old_deplibs $non_pic_objects"
+ if test "$preload" = yes && test -f "$symfileobj"; then
+ oldobjs="$oldobjs $symfileobj"
+ fi
+ fi
+ addlibs="$old_convenience"
+ fi
+
+ if test -n "$addlibs"; then
+ gentop="$output_objdir/${outputname}x"
+ generated="$generated $gentop"
+
+ func_extract_archives $gentop $addlibs
+ oldobjs="$oldobjs $func_extract_archives_result"
+ fi
+
+ # Do each command in the archive commands.
+ if test -n "$old_archive_from_new_cmds" && test "$build_libtool_libs" = yes; then
+ cmds=$old_archive_from_new_cmds
+ else
+
+ # Add any objects from preloaded convenience libraries
+ if test -n "$dlprefiles"; then
+ gentop="$output_objdir/${outputname}x"
+ generated="$generated $gentop"
+
+ func_extract_archives $gentop $dlprefiles
+ oldobjs="$oldobjs $func_extract_archives_result"
+ fi
+
+ # POSIX demands no paths to be encoded in archives. We have
+ # to avoid creating archives with duplicate basenames if we
+ # might have to extract them afterwards, e.g., when creating a
+ # static archive out of a convenience library, or when linking
+ # the entirety of a libtool archive into another (currently
+ # not supported by libtool).
+ if (for obj in $oldobjs
+ do
+ func_basename "$obj"
+ $ECHO "$func_basename_result"
+ done | sort | sort -uc >/dev/null 2>&1); then
+ :
+ else
+ $ECHO "copying selected object files to avoid basename conflicts..."
+ gentop="$output_objdir/${outputname}x"
+ generated="$generated $gentop"
+ func_mkdir_p "$gentop"
+ save_oldobjs=$oldobjs
+ oldobjs=
+ counter=1
+ for obj in $save_oldobjs
+ do
+ func_basename "$obj"
+ objbase="$func_basename_result"
+ case " $oldobjs " in
+ " ") oldobjs=$obj ;;
+ *[\ /]"$objbase "*)
+ while :; do
+ # Make sure we don't pick an alternate name that also
+ # overlaps.
+ newobj=lt$counter-$objbase
+ func_arith $counter + 1
+ counter=$func_arith_result
+ case " $oldobjs " in
+ *[\ /]"$newobj "*) ;;
+ *) if test ! -f "$gentop/$newobj"; then break; fi ;;
+ esac
+ done
+ func_show_eval "ln $obj $gentop/$newobj || cp $obj $gentop/$newobj"
+ oldobjs="$oldobjs $gentop/$newobj"
+ ;;
+ *) oldobjs="$oldobjs $obj" ;;
+ esac
+ done
+ fi
+ eval cmds=\"$old_archive_cmds\"
+
+ func_len " $cmds"
+ len=$func_len_result
+ if test "$len" -lt "$max_cmd_len" || test "$max_cmd_len" -le -1; then
+ cmds=$old_archive_cmds
+ else
+ # the command line is too long to link in one step, link in parts
+ func_verbose "using piecewise archive linking..."
+ save_RANLIB=$RANLIB
+ RANLIB=:
+ objlist=
+ concat_cmds=
+ save_oldobjs=$oldobjs
+ oldobjs=
+ # Is there a better way of finding the last object in the list?
+ for obj in $save_oldobjs
+ do
+ last_oldobj=$obj
+ done
+ eval test_cmds=\"$old_archive_cmds\"
+ func_len " $test_cmds"
+ len0=$func_len_result
+ len=$len0
+ for obj in $save_oldobjs
+ do
+ func_len " $obj"
+ func_arith $len + $func_len_result
+ len=$func_arith_result
+ func_append objlist " $obj"
+ if test "$len" -lt "$max_cmd_len"; then
+ :
+ else
+ # the above command should be used before it gets too long
+ oldobjs=$objlist
+ if test "$obj" = "$last_oldobj" ; then
+ RANLIB=$save_RANLIB
+ fi
+ test -z "$concat_cmds" || concat_cmds=$concat_cmds~
+ eval concat_cmds=\"\${concat_cmds}$old_archive_cmds\"
+ objlist=
+ len=$len0
+ fi
+ done
+ RANLIB=$save_RANLIB
+ oldobjs=$objlist
+ if test "X$oldobjs" = "X" ; then
+ eval cmds=\"\$concat_cmds\"
+ else
+ eval cmds=\"\$concat_cmds~\$old_archive_cmds\"
+ fi
+ fi
+ fi
+ func_execute_cmds "$cmds" 'exit $?'
+ done
+
+ test -n "$generated" && \
+ func_show_eval "${RM}r$generated"
+
+ # Now create the libtool archive.
+ case $output in
+ *.la)
+ old_library=
+ test "$build_old_libs" = yes && old_library="$libname.$libext"
+ func_verbose "creating $output"
+
+ # Preserve any variables that may affect compiler behavior
+ for var in $variables_saved_for_relink; do
+ if eval test -z \"\${$var+set}\"; then
+ relink_command="{ test -z \"\${$var+set}\" || $lt_unset $var || { $var=; export $var; }; }; $relink_command"
+ elif eval var_value=\$$var; test -z "$var_value"; then
+ relink_command="$var=; export $var; $relink_command"
+ else
+ func_quote_for_eval "$var_value"
+ relink_command="$var=$func_quote_for_eval_result; export $var; $relink_command"
+ fi
+ done
+ # Quote the link command for shipping.
+ relink_command="(cd `pwd`; $SHELL $progpath $preserve_args --mode=relink $libtool_args @inst_prefix_dir@)"
+ relink_command=`$ECHO "X$relink_command" | $Xsed -e "$sed_quote_subst"`
+ if test "$hardcode_automatic" = yes ; then
+ relink_command=
+ fi
+
+ # Only create the output if not a dry run.
+ $opt_dry_run || {
+ for installed in no yes; do
+ if test "$installed" = yes; then
+ if test -z "$install_libdir"; then
+ break
+ fi
+ output="$output_objdir/$outputname"i
+ # Replace all uninstalled libtool libraries with the installed ones
+ newdependency_libs=
+ for deplib in $dependency_libs; do
+ case $deplib in
+ *.la)
+ func_basename "$deplib"
+ name="$func_basename_result"
+ eval libdir=`${SED} -n -e 's/^libdir=\(.*\)$/\1/p' $deplib`
+ test -z "$libdir" && \
+ func_fatal_error "\`$deplib' is not a valid libtool archive"
+ newdependency_libs="$newdependency_libs $libdir/$name"
+ ;;
+ *) newdependency_libs="$newdependency_libs $deplib" ;;
+ esac
+ done
+ dependency_libs="$newdependency_libs"
+ newdlfiles=
+
+ for lib in $dlfiles; do
+ case $lib in
+ *.la)
+ func_basename "$lib"
+ name="$func_basename_result"
+ eval libdir=`${SED} -n -e 's/^libdir=\(.*\)$/\1/p' $lib`
+ test -z "$libdir" && \
+ func_fatal_error "\`$lib' is not a valid libtool archive"
+ newdlfiles="$newdlfiles $libdir/$name"
+ ;;
+ *) newdlfiles="$newdlfiles $lib" ;;
+ esac
+ done
+ dlfiles="$newdlfiles"
+ newdlprefiles=
+ for lib in $dlprefiles; do
+ case $lib in
+ *.la)
+ # Only pass preopened files to the pseudo-archive (for
+ # eventual linking with the app. that links it) if we
+ # didn't already link the preopened objects directly into
+ # the library:
+ func_basename "$lib"
+ name="$func_basename_result"
+ eval libdir=`${SED} -n -e 's/^libdir=\(.*\)$/\1/p' $lib`
+ test -z "$libdir" && \
+ func_fatal_error "\`$lib' is not a valid libtool archive"
+ newdlprefiles="$newdlprefiles $libdir/$name"
+ ;;
+ esac
+ done
+ dlprefiles="$newdlprefiles"
+ else
+ newdlfiles=
+ for lib in $dlfiles; do
+ case $lib in
+ [\\/]* | [A-Za-z]:[\\/]*) abs="$lib" ;;
+ *) abs=`pwd`"/$lib" ;;
+ esac
+ newdlfiles="$newdlfiles $abs"
+ done
+ dlfiles="$newdlfiles"
+ newdlprefiles=
+ for lib in $dlprefiles; do
+ case $lib in
+ [\\/]* | [A-Za-z]:[\\/]*) abs="$lib" ;;
+ *) abs=`pwd`"/$lib" ;;
+ esac
+ newdlprefiles="$newdlprefiles $abs"
+ done
+ dlprefiles="$newdlprefiles"
+ fi
+ $RM $output
+ # place dlname in correct position for cygwin
+ tdlname=$dlname
+ case $host,$output,$installed,$module,$dlname in
+ *cygwin*,*lai,yes,no,*.dll | *mingw*,*lai,yes,no,*.dll | *cegcc*,*lai,yes,no,*.dll) tdlname=../bin/$dlname ;;
+ esac
+ $ECHO > $output "\
+# $outputname - a libtool library file
+# Generated by $PROGRAM (GNU $PACKAGE$TIMESTAMP) $VERSION
+#
+# Please DO NOT delete this file!
+# It is necessary for linking the library.
+
+# The name that we can dlopen(3).
+dlname='$tdlname'
+
+# Names of this library.
+library_names='$library_names'
+
+# The name of the static archive.
+old_library='$old_library'
+
+# Linker flags that can not go in dependency_libs.
+inherited_linker_flags='$new_inherited_linker_flags'
+
+# Libraries that this one depends upon.
+dependency_libs='$dependency_libs'
+
+# Names of additional weak libraries provided by this library
+weak_library_names='$weak_libs'
+
+# Version information for $libname.
+current=$current
+age=$age
+revision=$revision
+
+# Is this an already installed library?
+installed=$installed
+
+# Should we warn about portability when linking against -modules?
+shouldnotlink=$module
+
+# Files to dlopen/dlpreopen
+dlopen='$dlfiles'
+dlpreopen='$dlprefiles'
+
+# Directory that this library needs to be installed in:
+libdir='$install_libdir'"
+ if test "$installed" = no && test "$need_relink" = yes; then
+ $ECHO >> $output "\
+relink_command=\"$relink_command\""
+ fi
+ done
+ }
+
+ # Do a symbolic link so that the libtool archive can be found in
+ # LD_LIBRARY_PATH before the program is installed.
+ func_show_eval '( cd "$output_objdir" && $RM "$outputname" && $LN_S "../$outputname" "$outputname" )' 'exit $?'
+ ;;
+ esac
+ exit $EXIT_SUCCESS
+}
+
+{ test "$mode" = link || test "$mode" = relink; } &&
+ func_mode_link ${1+"$@"}
+
+
+# func_mode_uninstall arg...
+func_mode_uninstall ()
+{
+ $opt_debug
+ RM="$nonopt"
+ files=
+ rmforce=
+ exit_status=0
+
+ # This variable tells wrapper scripts just to set variables rather
+ # than running their programs.
+ libtool_install_magic="$magic"
+
+ for arg
+ do
+ case $arg in
+ -f) RM="$RM $arg"; rmforce=yes ;;
+ -*) RM="$RM $arg" ;;
+ *) files="$files $arg" ;;
+ esac
+ done
+
+ test -z "$RM" && \
+ func_fatal_help "you must specify an RM program"
+
+ rmdirs=
+
+ origobjdir="$objdir"
+ for file in $files; do
+ func_dirname "$file" "" "."
+ dir="$func_dirname_result"
+ if test "X$dir" = X.; then
+ objdir="$origobjdir"
+ else
+ objdir="$dir/$origobjdir"
+ fi
+ func_basename "$file"
+ name="$func_basename_result"
+ test "$mode" = uninstall && objdir="$dir"
+
+ # Remember objdir for removal later, being careful to avoid duplicates
+ if test "$mode" = clean; then
+ case " $rmdirs " in
+ *" $objdir "*) ;;
+ *) rmdirs="$rmdirs $objdir" ;;
+ esac
+ fi
+
+ # Don't error if the file doesn't exist and rm -f was used.
+ if { test -L "$file"; } >/dev/null 2>&1 ||
+ { test -h "$file"; } >/dev/null 2>&1 ||
+ test -f "$file"; then
+ :
+ elif test -d "$file"; then
+ exit_status=1
+ continue
+ elif test "$rmforce" = yes; then
+ continue
+ fi
+
+ rmfiles="$file"
+
+ case $name in
+ *.la)
+ # Possibly a libtool archive, so verify it.
+ if func_lalib_p "$file"; then
+ func_source $dir/$name
+
+ # Delete the libtool libraries and symlinks.
+ for n in $library_names; do
+ rmfiles="$rmfiles $objdir/$n"
+ done
+ test -n "$old_library" && rmfiles="$rmfiles $objdir/$old_library"
+
+ case "$mode" in
+ clean)
+ case " $library_names " in
+ # " " in the beginning catches empty $dlname
+ *" $dlname "*) ;;
+ *) rmfiles="$rmfiles $objdir/$dlname" ;;
+ esac
+ test -n "$libdir" && rmfiles="$rmfiles $objdir/$name $objdir/${name}i"
+ ;;
+ uninstall)
+ if test -n "$library_names"; then
+ # Do each command in the postuninstall commands.
+ func_execute_cmds "$postuninstall_cmds" 'test "$rmforce" = yes || exit_status=1'
+ fi
+
+ if test -n "$old_library"; then
+ # Do each command in the old_postuninstall commands.
+ func_execute_cmds "$old_postuninstall_cmds" 'test "$rmforce" = yes || exit_status=1'
+ fi
+ # FIXME: should reinstall the best remaining shared library.
+ ;;
+ esac
+ fi
+ ;;
+
+ *.lo)
+ # Possibly a libtool object, so verify it.
+ if func_lalib_p "$file"; then
+
+ # Read the .lo file
+ func_source $dir/$name
+
+ # Add PIC object to the list of files to remove.
+ if test -n "$pic_object" &&
+ test "$pic_object" != none; then
+ rmfiles="$rmfiles $dir/$pic_object"
+ fi
+
+ # Add non-PIC object to the list of files to remove.
+ if test -n "$non_pic_object" &&
+ test "$non_pic_object" != none; then
+ rmfiles="$rmfiles $dir/$non_pic_object"
+ fi
+ fi
+ ;;
+
+ *)
+ if test "$mode" = clean ; then
+ noexename=$name
+ case $file in
+ *.exe)
+ func_stripname '' '.exe' "$file"
+ file=$func_stripname_result
+ func_stripname '' '.exe' "$name"
+ noexename=$func_stripname_result
+ # $file with .exe has already been added to rmfiles,
+ # add $file without .exe
+ rmfiles="$rmfiles $file"
+ ;;
+ esac
+ # Do a test to see if this is a libtool program.
+ if func_ltwrapper_p "$file"; then
+ if func_ltwrapper_executable_p "$file"; then
+ func_ltwrapper_scriptname "$file"
+ relink_command=
+ func_source $func_ltwrapper_scriptname_result
+ rmfiles="$rmfiles $func_ltwrapper_scriptname_result"
+ else
+ relink_command=
+ func_source $dir/$noexename
+ fi
+
+ # note $name still contains .exe if it was in $file originally
+ # as does the version of $file that was added into $rmfiles
+ rmfiles="$rmfiles $objdir/$name $objdir/${name}S.${objext}"
+ if test "$fast_install" = yes && test -n "$relink_command"; then
+ rmfiles="$rmfiles $objdir/lt-$name"
+ fi
+ if test "X$noexename" != "X$name" ; then
+ rmfiles="$rmfiles $objdir/lt-${noexename}.c"
+ fi
+ fi
+ fi
+ ;;
+ esac
+ func_show_eval "$RM $rmfiles" 'exit_status=1'
+ done
+ objdir="$origobjdir"
+
+ # Try to remove the ${objdir}s in the directories where we deleted files
+ for dir in $rmdirs; do
+ if test -d "$dir"; then
+ func_show_eval "rmdir $dir >/dev/null 2>&1"
+ fi
+ done
+
+ exit $exit_status
+}
+
+{ test "$mode" = uninstall || test "$mode" = clean; } &&
+ func_mode_uninstall ${1+"$@"}
+
+test -z "$mode" && {
+ help="$generic_help"
+ func_fatal_help "you must specify a MODE"
+}
+
+test -z "$exec_cmd" && \
+ func_fatal_help "invalid operation mode \`$mode'"
+
+if test -n "$exec_cmd"; then
+ eval exec "$exec_cmd"
+ exit $EXIT_FAILURE
+fi
+
+exit $exit_status
+
+
+# The TAGs below are defined such that we never get into a situation
+# in which we disable both kinds of libraries. Given conflicting
+# choices, we go for a static library, that is the most portable,
+# since we can't tell whether shared libraries were disabled because
+# the user asked for that or because the platform doesn't support
+# them. This is particularly important on AIX, because we don't
+# support having both static and shared libraries enabled at the same
+# time on that platform, so we default to a shared-only configuration.
+# If a disable-shared tag is given, we'll fallback to a static-only
+# configuration. But we'll never go from static-only to shared-only.
+
+# ### BEGIN LIBTOOL TAG CONFIG: disable-shared
+build_libtool_libs=no
+build_old_libs=yes
+# ### END LIBTOOL TAG CONFIG: disable-shared
+
+# ### BEGIN LIBTOOL TAG CONFIG: disable-static
+build_old_libs=`case $build_libtool_libs in yes) echo no;; *) echo yes;; esac`
+# ### END LIBTOOL TAG CONFIG: disable-static
+
+# Local Variables:
+# mode:shell-script
+# sh-indentation:2
+# End:
+# vi:sw=2
+
diff --git a/contrib/libyaml/config/missing b/contrib/libyaml/config/missing
new file mode 100755
index 0000000..28055d2
--- /dev/null
+++ b/contrib/libyaml/config/missing
@@ -0,0 +1,376 @@
+#! /bin/sh
+# Common stub for a few missing GNU programs while installing.
+
+scriptversion=2009-04-28.21; # UTC
+
+# Copyright (C) 1996, 1997, 1999, 2000, 2002, 2003, 2004, 2005, 2006,
+# 2008, 2009 Free Software Foundation, Inc.
+# Originally by Fran,cois Pinard <pinard@iro.umontreal.ca>, 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, see <http://www.gnu.org/licenses/>.
+
+# 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=:
+sed_output='s/.* --output[ =]\([^ ]*\).*/\1/p'
+sed_minuso='s/.* -o \([^ ]*\).*/\1/p'
+
+# 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
+
+msg="missing on your system"
+
+case $1 in
+--run)
+ # Try to run requested program, and just exit if it succeeds.
+ run=
+ shift
+ "$@" && exit 0
+ # Exit code 63 means version mismatch. This often happens
+ # when the user try to use an ancient version of a tool on
+ # a file that requires a minimum version. In this case we
+ # we should proceed has if the program had been absent, or
+ # if --run hadn't been passed.
+ if test $? = 63; then
+ run=:
+ msg="probably too old"
+ fi
+ ;;
+
+ -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'
+ autom4te touch the output file, or create a stub one
+ 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]
+
+Version suffixes to PROGRAM as well as the prefixes \`gnu-', \`gnu', and
+\`g' are ignored when checking the name.
+
+Send bug reports to <bug-automake@gnu.org>."
+ exit $?
+ ;;
+
+ -v|--v|--ve|--ver|--vers|--versi|--versio|--version)
+ echo "missing $scriptversion (GNU Automake)"
+ exit $?
+ ;;
+
+ -*)
+ echo 1>&2 "$0: Unknown \`$1' option"
+ echo 1>&2 "Try \`$0 --help' for more information"
+ exit 1
+ ;;
+
+esac
+
+# normalize program name to check for.
+program=`echo "$1" | sed '
+ s/^gnu-//; t
+ s/^gnu//; t
+ s/^g//; t'`
+
+# Now exit if we have it, but it failed. Also exit now if we
+# don't have it and --version was passed (most likely to detect
+# the program). This is about non-GNU programs, so use $1 not
+# $program.
+case $1 in
+ lex*|yacc*)
+ # Not GNU programs, they don't have --version.
+ ;;
+
+ tar*)
+ if test -n "$run"; then
+ echo 1>&2 "ERROR: \`tar' requires --run"
+ exit 1
+ elif test "x$2" = "x--version" || test "x$2" = "x--help"; then
+ exit 1
+ fi
+ ;;
+
+ *)
+ if test -z "$run" && ($1 --version) > /dev/null 2>&1; then
+ # We have it, but it failed.
+ exit 1
+ elif test "x$2" = "x--version" || test "x$2" = "x--help"; then
+ # Could not run --version or --help. This is probably someone
+ # running `$TOOL --version' or `$TOOL --help' to check whether
+ # $TOOL exists and not knowing $TOOL uses missing.
+ exit 1
+ fi
+ ;;
+esac
+
+# If it does not exist, or fails to run (possibly an outdated version),
+# try to emulate it.
+case $program in
+ aclocal*)
+ echo 1>&2 "\
+WARNING: \`$1' is $msg. 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*)
+ echo 1>&2 "\
+WARNING: \`$1' is $msg. 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*)
+ echo 1>&2 "\
+WARNING: \`$1' is $msg. 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*)
+ echo 1>&2 "\
+WARNING: \`$1' is $msg. 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*)
+ echo 1>&2 "\
+WARNING: \`$1' is needed, but is $msg.
+ You might have modified some files without having the
+ proper tools for further handling them.
+ You can get \`$1' as part of \`Autoconf' from any GNU
+ archive site."
+
+ file=`echo "$*" | sed -n "$sed_output"`
+ test -z "$file" && file=`echo "$*" | sed -n "$sed_minuso"`
+ 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' $msg. 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 test $# -ne 1; then
+ eval LASTARG="\${$#}"
+ case $LASTARG in
+ *.y)
+ SRCFILE=`echo "$LASTARG" | sed 's/y$/c/'`
+ if test -f "$SRCFILE"; then
+ cp "$SRCFILE" y.tab.c
+ fi
+ SRCFILE=`echo "$LASTARG" | sed 's/y$/h/'`
+ if test -f "$SRCFILE"; then
+ cp "$SRCFILE" y.tab.h
+ fi
+ ;;
+ esac
+ fi
+ if test ! -f y.tab.h; then
+ echo >y.tab.h
+ fi
+ if test ! -f y.tab.c; then
+ echo 'main() { return 0; }' >y.tab.c
+ fi
+ ;;
+
+ lex*|flex*)
+ echo 1>&2 "\
+WARNING: \`$1' is $msg. 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 test $# -ne 1; then
+ eval LASTARG="\${$#}"
+ case $LASTARG in
+ *.l)
+ SRCFILE=`echo "$LASTARG" | sed 's/l$/c/'`
+ if test -f "$SRCFILE"; then
+ cp "$SRCFILE" lex.yy.c
+ fi
+ ;;
+ esac
+ fi
+ if test ! -f lex.yy.c; then
+ echo 'main() { return 0; }' >lex.yy.c
+ fi
+ ;;
+
+ help2man*)
+ echo 1>&2 "\
+WARNING: \`$1' is $msg. 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 "$sed_output"`
+ test -z "$file" && file=`echo "$*" | sed -n "$sed_minuso"`
+ if test -f "$file"; then
+ touch $file
+ else
+ test -z "$file" || exec >$file
+ echo ".ab help2man is required to generate this page"
+ exit $?
+ fi
+ ;;
+
+ makeinfo*)
+ echo 1>&2 "\
+WARNING: \`$1' is $msg. 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."
+ # The file to touch is that specified with -o ...
+ file=`echo "$*" | sed -n "$sed_output"`
+ test -z "$file" && file=`echo "$*" | sed -n "$sed_minuso"`
+ if test -z "$file"; then
+ # ... or it is the one specified with @setfilename ...
+ infile=`echo "$*" | sed 's/.* \([^ ]*\) *$/\1/'`
+ file=`sed -n '
+ /^@setfilename/{
+ s/.* \([^ ]*\) *$/\1/
+ p
+ q
+ }' $infile`
+ # ... or it is derived from the source name (dir/f.texi becomes f.info)
+ test -z "$file" && file=`echo "$infile" | sed 's,.*/,,;s,.[^.]*$,,'`.info
+ fi
+ # If the file does not exist, the user really needs makeinfo;
+ # let's fail without touching anything.
+ test -f $file || exit 1
+ touch $file
+ ;;
+
+ tar*)
+ shift
+
+ # 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 is $msg.
+ 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 prerequisites 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
+
+# Local variables:
+# eval: (add-hook 'write-file-hooks 'time-stamp)
+# time-stamp-start: "scriptversion="
+# time-stamp-format: "%:y-%02m-%02d.%02H"
+# time-stamp-time-zone: "UTC"
+# time-stamp-end: "; # UTC"
+# End:
diff --git a/contrib/libyaml/configure b/contrib/libyaml/configure
new file mode 100755
index 0000000..194fa3d
--- /dev/null
+++ b/contrib/libyaml/configure
@@ -0,0 +1,13149 @@
+#! /bin/sh
+# Guess values for system-dependent variables and create Makefiles.
+# Generated by GNU Autoconf 2.67 for yaml 0.1.4.
+#
+# Report bugs to <http://pyyaml.org/newticket?component=libyaml>.
+#
+#
+# Copyright (C) 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001,
+# 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010 Free Software
+# Foundation, Inc.
+#
+#
+# This configure script is free software; the Free Software Foundation
+# gives unlimited permission to copy, distribute and modify it.
+## -------------------- ##
+## M4sh Initialization. ##
+## -------------------- ##
+
+# Be more Bourne compatible
+DUALCASE=1; export DUALCASE # for MKS sh
+if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then :
+ emulate sh
+ NULLCMD=:
+ # Pre-4.2 versions of Zsh do word splitting on ${1+"$@"}, which
+ # is contrary to our usage. Disable this feature.
+ alias -g '${1+"$@"}'='"$@"'
+ setopt NO_GLOB_SUBST
+else
+ case `(set -o) 2>/dev/null` in #(
+ *posix*) :
+ set -o posix ;; #(
+ *) :
+ ;;
+esac
+fi
+
+
+as_nl='
+'
+export as_nl
+# Printing a long string crashes Solaris 7 /usr/bin/printf.
+as_echo='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\'
+as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo
+as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo$as_echo
+# Prefer a ksh shell builtin over an external printf program on Solaris,
+# but without wasting forks for bash or zsh.
+if test -z "$BASH_VERSION$ZSH_VERSION" \
+ && (test "X`print -r -- $as_echo`" = "X$as_echo") 2>/dev/null; then
+ as_echo='print -r --'
+ as_echo_n='print -rn --'
+elif (test "X`printf %s $as_echo`" = "X$as_echo") 2>/dev/null; then
+ as_echo='printf %s\n'
+ as_echo_n='printf %s'
+else
+ if test "X`(/usr/ucb/echo -n -n $as_echo) 2>/dev/null`" = "X-n $as_echo"; then
+ as_echo_body='eval /usr/ucb/echo -n "$1$as_nl"'
+ as_echo_n='/usr/ucb/echo -n'
+ else
+ as_echo_body='eval expr "X$1" : "X\\(.*\\)"'
+ as_echo_n_body='eval
+ arg=$1;
+ case $arg in #(
+ *"$as_nl"*)
+ expr "X$arg" : "X\\(.*\\)$as_nl";
+ arg=`expr "X$arg" : ".*$as_nl\\(.*\\)"`;;
+ esac;
+ expr "X$arg" : "X\\(.*\\)" | tr -d "$as_nl"
+ '
+ export as_echo_n_body
+ as_echo_n='sh -c $as_echo_n_body as_echo'
+ fi
+ export as_echo_body
+ as_echo='sh -c $as_echo_body as_echo'
+fi
+
+# The user is always right.
+if test "${PATH_SEPARATOR+set}" != set; then
+ PATH_SEPARATOR=:
+ (PATH='/bin;/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 && {
+ (PATH='/bin:/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 ||
+ PATH_SEPARATOR=';'
+ }
+fi
+
+
+# IFS
+# We need space, tab and new line, in precisely that order. Quoting is
+# there to prevent editors from complaining about space-tab.
+# (If _AS_PATH_WALK were called with IFS unset, it would disable word
+# splitting by setting IFS to empty value.)
+IFS=" "" $as_nl"
+
+# Find who we are. Look in the path if we contain no directory separator.
+case $0 in #((
+ *[\\/]* ) as_myself=$0 ;;
+ *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break
+ done
+IFS=$as_save_IFS
+
+ ;;
+esac
+# We did not find ourselves, most probably we were run as `sh COMMAND'
+# in which case we are not to be found in the path.
+if test "x$as_myself" = x; then
+ as_myself=$0
+fi
+if test ! -f "$as_myself"; then
+ $as_echo "$as_myself: error: cannot find myself; rerun with an absolute file name" >&2
+ exit 1
+fi
+
+# Unset variables that we do not need and which cause bugs (e.g. in
+# pre-3.0 UWIN ksh). But do not cause bugs in bash 2.01; the "|| exit 1"
+# suppresses any "Segmentation fault" message there. '((' could
+# trigger a bug in pdksh 5.2.14.
+for as_var in BASH_ENV ENV MAIL MAILPATH
+do eval test x\${$as_var+set} = xset \
+ && ( (unset $as_var) || exit 1) >/dev/null 2>&1 && unset $as_var || :
+done
+PS1='$ '
+PS2='> '
+PS4='+ '
+
+# NLS nuisances.
+LC_ALL=C
+export LC_ALL
+LANGUAGE=C
+export LANGUAGE
+
+# CDPATH.
+(unset CDPATH) >/dev/null 2>&1 && unset CDPATH
+
+if test "x$CONFIG_SHELL" = x; then
+ as_bourne_compatible="if test -n \"\${ZSH_VERSION+set}\" && (emulate sh) >/dev/null 2>&1; then :
+ emulate sh
+ NULLCMD=:
+ # Pre-4.2 versions of Zsh do word splitting on \${1+\"\$@\"}, which
+ # is contrary to our usage. Disable this feature.
+ alias -g '\${1+\"\$@\"}'='\"\$@\"'
+ setopt NO_GLOB_SUBST
+else
+ case \`(set -o) 2>/dev/null\` in #(
+ *posix*) :
+ set -o posix ;; #(
+ *) :
+ ;;
+esac
+fi
+"
+ as_required="as_fn_return () { (exit \$1); }
+as_fn_success () { as_fn_return 0; }
+as_fn_failure () { as_fn_return 1; }
+as_fn_ret_success () { return 0; }
+as_fn_ret_failure () { return 1; }
+
+exitcode=0
+as_fn_success || { exitcode=1; echo as_fn_success failed.; }
+as_fn_failure && { exitcode=1; echo as_fn_failure succeeded.; }
+as_fn_ret_success || { exitcode=1; echo as_fn_ret_success failed.; }
+as_fn_ret_failure && { exitcode=1; echo as_fn_ret_failure succeeded.; }
+if ( set x; as_fn_ret_success y && test x = \"\$1\" ); then :
+
+else
+ exitcode=1; echo positional parameters were not saved.
+fi
+test x\$exitcode = x0 || exit 1"
+ as_suggested=" as_lineno_1=";as_suggested=$as_suggested$LINENO;as_suggested=$as_suggested" as_lineno_1a=\$LINENO
+ as_lineno_2=";as_suggested=$as_suggested$LINENO;as_suggested=$as_suggested" as_lineno_2a=\$LINENO
+ eval 'test \"x\$as_lineno_1'\$as_run'\" != \"x\$as_lineno_2'\$as_run'\" &&
+ test \"x\`expr \$as_lineno_1'\$as_run' + 1\`\" = \"x\$as_lineno_2'\$as_run'\"' || exit 1
+test \$(( 1 + 1 )) = 2 || exit 1"
+ if (eval "$as_required") 2>/dev/null; then :
+ as_have_required=yes
+else
+ as_have_required=no
+fi
+ if test x$as_have_required = xyes && (eval "$as_suggested") 2>/dev/null; then :
+
+else
+ as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+as_found=false
+for as_dir in /bin$PATH_SEPARATOR/usr/bin$PATH_SEPARATOR$PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ as_found=:
+ case $as_dir in #(
+ /*)
+ for as_base in sh bash ksh sh5; do
+ # Try only shells that exist, to save several forks.
+ as_shell=$as_dir/$as_base
+ if { test -f "$as_shell" || test -f "$as_shell.exe"; } &&
+ { $as_echo "$as_bourne_compatible""$as_required" | as_run=a "$as_shell"; } 2>/dev/null; then :
+ CONFIG_SHELL=$as_shell as_have_required=yes
+ if { $as_echo "$as_bourne_compatible""$as_suggested" | as_run=a "$as_shell"; } 2>/dev/null; then :
+ break 2
+fi
+fi
+ done;;
+ esac
+ as_found=false
+done
+$as_found || { if { test -f "$SHELL" || test -f "$SHELL.exe"; } &&
+ { $as_echo "$as_bourne_compatible""$as_required" | as_run=a "$SHELL"; } 2>/dev/null; then :
+ CONFIG_SHELL=$SHELL as_have_required=yes
+fi; }
+IFS=$as_save_IFS
+
+
+ if test "x$CONFIG_SHELL" != x; then :
+ # We cannot yet assume a decent shell, so we have to provide a
+ # neutralization value for shells without unset; and this also
+ # works around shells that cannot unset nonexistent variables.
+ BASH_ENV=/dev/null
+ ENV=/dev/null
+ (unset BASH_ENV) >/dev/null 2>&1 && unset BASH_ENV ENV
+ export CONFIG_SHELL
+ exec "$CONFIG_SHELL" "$as_myself" ${1+"$@"}
+fi
+
+ if test x$as_have_required = xno; then :
+ $as_echo "$0: This script requires a shell more modern than all"
+ $as_echo "$0: the shells that I found on your system."
+ if test x${ZSH_VERSION+set} = xset ; then
+ $as_echo "$0: In particular, zsh $ZSH_VERSION has bugs and should"
+ $as_echo "$0: be upgraded to zsh 4.3.4 or later."
+ else
+ $as_echo "$0: Please tell bug-autoconf@gnu.org and http://pyyaml.org/newticket?component=libyaml about
+$0: your system, including any error possibly output before
+$0: this message. Then install a modern shell, or manually
+$0: run the script under such a shell if you do have one."
+ fi
+ exit 1
+fi
+fi
+fi
+SHELL=${CONFIG_SHELL-/bin/sh}
+export SHELL
+# Unset more variables known to interfere with behavior of common tools.
+CLICOLOR_FORCE= GREP_OPTIONS=
+unset CLICOLOR_FORCE GREP_OPTIONS
+
+## --------------------- ##
+## M4sh Shell Functions. ##
+## --------------------- ##
+# as_fn_unset VAR
+# ---------------
+# Portably unset VAR.
+as_fn_unset ()
+{
+ { eval $1=; unset $1;}
+}
+as_unset=as_fn_unset
+
+# as_fn_set_status STATUS
+# -----------------------
+# Set $? to STATUS, without forking.
+as_fn_set_status ()
+{
+ return $1
+} # as_fn_set_status
+
+# as_fn_exit STATUS
+# -----------------
+# Exit the shell with STATUS, even in a "trap 0" or "set -e" context.
+as_fn_exit ()
+{
+ set +e
+ as_fn_set_status $1
+ exit $1
+} # as_fn_exit
+
+# as_fn_mkdir_p
+# -------------
+# Create "$as_dir" as a directory, including parents if necessary.
+as_fn_mkdir_p ()
+{
+
+ case $as_dir in #(
+ -*) as_dir=./$as_dir;;
+ esac
+ test -d "$as_dir" || eval $as_mkdir_p || {
+ as_dirs=
+ while :; do
+ case $as_dir in #(
+ *\'*) as_qdir=`$as_echo "$as_dir" | sed "s/'/'\\\\\\\\''/g"`;; #'(
+ *) as_qdir=$as_dir;;
+ esac
+ as_dirs="'$as_qdir' $as_dirs"
+ as_dir=`$as_dirname -- "$as_dir" ||
+$as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
+ X"$as_dir" : 'X\(//\)[^/]' \| \
+ X"$as_dir" : 'X\(//\)$' \| \
+ X"$as_dir" : 'X\(/\)' \| . 2>/dev/null ||
+$as_echo X"$as_dir" |
+ sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{
+ s//\1/
+ q
+ }
+ /^X\(\/\/\)[^/].*/{
+ s//\1/
+ q
+ }
+ /^X\(\/\/\)$/{
+ s//\1/
+ q
+ }
+ /^X\(\/\).*/{
+ s//\1/
+ q
+ }
+ s/.*/./; q'`
+ test -d "$as_dir" && break
+ done
+ test -z "$as_dirs" || eval "mkdir $as_dirs"
+ } || test -d "$as_dir" || as_fn_error $? "cannot create directory $as_dir"
+
+
+} # as_fn_mkdir_p
+# as_fn_append VAR VALUE
+# ----------------------
+# Append the text in VALUE to the end of the definition contained in VAR. Take
+# advantage of any shell optimizations that allow amortized linear growth over
+# repeated appends, instead of the typical quadratic growth present in naive
+# implementations.
+if (eval "as_var=1; as_var+=2; test x\$as_var = x12") 2>/dev/null; then :
+ eval 'as_fn_append ()
+ {
+ eval $1+=\$2
+ }'
+else
+ as_fn_append ()
+ {
+ eval $1=\$$1\$2
+ }
+fi # as_fn_append
+
+# as_fn_arith ARG...
+# ------------------
+# Perform arithmetic evaluation on the ARGs, and store the result in the
+# global $as_val. Take advantage of shells that can avoid forks. The arguments
+# must be portable across $(()) and expr.
+if (eval "test \$(( 1 + 1 )) = 2") 2>/dev/null; then :
+ eval 'as_fn_arith ()
+ {
+ as_val=$(( $* ))
+ }'
+else
+ as_fn_arith ()
+ {
+ as_val=`expr "$@" || test $? -eq 1`
+ }
+fi # as_fn_arith
+
+
+# as_fn_error STATUS ERROR [LINENO LOG_FD]
+# ----------------------------------------
+# Output "`basename $0`: error: ERROR" to stderr. If LINENO and LOG_FD are
+# provided, also output the error to LOG_FD, referencing LINENO. Then exit the
+# script with STATUS, using 1 if that was 0.
+as_fn_error ()
+{
+ as_status=$1; test $as_status -eq 0 && as_status=1
+ if test "$4"; then
+ as_lineno=${as_lineno-"$3"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
+ $as_echo "$as_me:${as_lineno-$LINENO}: error: $2" >&$4
+ fi
+ $as_echo "$as_me: error: $2" >&2
+ as_fn_exit $as_status
+} # as_fn_error
+
+if expr a : '\(a\)' >/dev/null 2>&1 &&
+ test "X`expr 00001 : '.*\(...\)'`" = X001; then
+ as_expr=expr
+else
+ as_expr=false
+fi
+
+if (basename -- /) >/dev/null 2>&1 && test "X`basename -- / 2>&1`" = "X/"; then
+ as_basename=basename
+else
+ as_basename=false
+fi
+
+if (as_dir=`dirname -- /` && test "X$as_dir" = X/) >/dev/null 2>&1; then
+ as_dirname=dirname
+else
+ as_dirname=false
+fi
+
+as_me=`$as_basename -- "$0" ||
+$as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \
+ X"$0" : 'X\(//\)$' \| \
+ X"$0" : 'X\(/\)' \| . 2>/dev/null ||
+$as_echo X/"$0" |
+ sed '/^.*\/\([^/][^/]*\)\/*$/{
+ s//\1/
+ q
+ }
+ /^X\/\(\/\/\)$/{
+ s//\1/
+ q
+ }
+ /^X\/\(\/\).*/{
+ s//\1/
+ q
+ }
+ s/.*/./; q'`
+
+# Avoid depending upon Character Ranges.
+as_cr_letters='abcdefghijklmnopqrstuvwxyz'
+as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ'
+as_cr_Letters=$as_cr_letters$as_cr_LETTERS
+as_cr_digits='0123456789'
+as_cr_alnum=$as_cr_Letters$as_cr_digits
+
+
+ as_lineno_1=$LINENO as_lineno_1a=$LINENO
+ as_lineno_2=$LINENO as_lineno_2a=$LINENO
+ eval 'test "x$as_lineno_1'$as_run'" != "x$as_lineno_2'$as_run'" &&
+ test "x`expr $as_lineno_1'$as_run' + 1`" = "x$as_lineno_2'$as_run'"' || {
+ # Blame Lee E. McMahon (1931-1989) for sed's syntax. :-)
+ sed -n '
+ p
+ /[$]LINENO/=
+ ' <$as_myself |
+ sed '
+ s/[$]LINENO.*/&-/
+ t lineno
+ b
+ :lineno
+ N
+ :loop
+ s/[$]LINENO\([^'$as_cr_alnum'_].*\n\)\(.*\)/\2\1\2/
+ t loop
+ s/-\n.*//
+ ' >$as_me.lineno &&
+ chmod +x "$as_me.lineno" ||
+ { $as_echo "$as_me: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&2; as_fn_exit 1; }
+
+ # Don't try to exec as it changes $[0], causing all sort of problems
+ # (the dirname of $[0] is not the place where we might find the
+ # original and so on. Autoconf is especially sensitive to this).
+ . "./$as_me.lineno"
+ # Exit status is that of the last command.
+ exit
+}
+
+ECHO_C= ECHO_N= ECHO_T=
+case `echo -n x` in #(((((
+-n*)
+ case `echo 'xy\c'` in
+ *c*) ECHO_T=' ';; # ECHO_T is single tab character.
+ xy) ECHO_C='\c';;
+ *) echo `echo ksh88 bug on AIX 6.1` > /dev/null
+ ECHO_T=' ';;
+ esac;;
+*)
+ ECHO_N='-n';;
+esac
+
+rm -f conf$$ conf$$.exe conf$$.file
+if test -d conf$$.dir; then
+ rm -f conf$$.dir/conf$$.file
+else
+ rm -f conf$$.dir
+ mkdir conf$$.dir 2>/dev/null
+fi
+if (echo >conf$$.file) 2>/dev/null; then
+ if ln -s conf$$.file conf$$ 2>/dev/null; then
+ as_ln_s='ln -s'
+ # ... but there are two gotchas:
+ # 1) On MSYS, both `ln -s file dir' and `ln file dir' fail.
+ # 2) DJGPP < 2.04 has no symlinks; `ln -s' creates a wrapper executable.
+ # In both cases, we have to default to `cp -p'.
+ ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe ||
+ as_ln_s='cp -p'
+ elif ln conf$$.file conf$$ 2>/dev/null; then
+ as_ln_s=ln
+ else
+ as_ln_s='cp -p'
+ fi
+else
+ as_ln_s='cp -p'
+fi
+rm -f conf$$ conf$$.exe conf$$.dir/conf$$.file conf$$.file
+rmdir conf$$.dir 2>/dev/null
+
+if mkdir -p . 2>/dev/null; then
+ as_mkdir_p='mkdir -p "$as_dir"'
+else
+ test -d ./-p && rmdir ./-p
+ as_mkdir_p=false
+fi
+
+if test -x / >/dev/null 2>&1; then
+ as_test_x='test -x'
+else
+ if ls -dL / >/dev/null 2>&1; then
+ as_ls_L_option=L
+ else
+ as_ls_L_option=
+ fi
+ as_test_x='
+ eval sh -c '\''
+ if test -d "$1"; then
+ test -d "$1/.";
+ else
+ case $1 in #(
+ -*)set "./$1";;
+ esac;
+ case `ls -ld'$as_ls_L_option' "$1" 2>/dev/null` in #((
+ ???[sx]*):;;*)false;;esac;fi
+ '\'' sh
+ '
+fi
+as_executable_p=$as_test_x
+
+# Sed expression to map a string onto a valid CPP name.
+as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'"
+
+# Sed expression to map a string onto a valid variable name.
+as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'"
+
+
+
+# Check that we are running under the correct shell.
+SHELL=${CONFIG_SHELL-/bin/sh}
+
+case X$lt_ECHO in
+X*--fallback-echo)
+ # Remove one level of quotation (which was required for Make).
+ ECHO=`echo "$lt_ECHO" | sed 's,\\\\\$\\$0,'$0','`
+ ;;
+esac
+
+ECHO=${lt_ECHO-echo}
+if test "X$1" = X--no-reexec; then
+ # Discard the --no-reexec flag, and continue.
+ shift
+elif test "X$1" = X--fallback-echo; then
+ # Avoid inline document here, it may be left over
+ :
+elif test "X`{ $ECHO '\t'; } 2>/dev/null`" = 'X\t' ; then
+ # Yippee, $ECHO works!
+ :
+else
+ # Restart under the correct shell.
+ exec $SHELL "$0" --no-reexec ${1+"$@"}
+fi
+
+if test "X$1" = X--fallback-echo; then
+ # used as fallback echo
+ shift
+ cat <<_LT_EOF
+$*
+_LT_EOF
+ exit 0
+fi
+
+# The HP-UX ksh and POSIX shell print the target directory to stdout
+# if CDPATH is set.
+(unset CDPATH) >/dev/null 2>&1 && unset CDPATH
+
+if test -z "$lt_ECHO"; then
+ if test "X${echo_test_string+set}" != Xset; then
+ # find a string as large as possible, as long as the shell can cope with it
+ for cmd in 'sed 50q "$0"' 'sed 20q "$0"' 'sed 10q "$0"' 'sed 2q "$0"' 'echo test'; do
+ # expected sizes: less than 2Kb, 1Kb, 512 bytes, 16 bytes, ...
+ if { echo_test_string=`eval $cmd`; } 2>/dev/null &&
+ { test "X$echo_test_string" = "X$echo_test_string"; } 2>/dev/null
+ then
+ break
+ fi
+ done
+ fi
+
+ if test "X`{ $ECHO '\t'; } 2>/dev/null`" = 'X\t' &&
+ echo_testing_string=`{ $ECHO "$echo_test_string"; } 2>/dev/null` &&
+ test "X$echo_testing_string" = "X$echo_test_string"; then
+ :
+ else
+ # The Solaris, AIX, and Digital Unix default echo programs unquote
+ # backslashes. This makes it impossible to quote backslashes using
+ # echo "$something" | sed 's/\\/\\\\/g'
+ #
+ # So, first we look for a working echo in the user's PATH.
+
+ lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR
+ for dir in $PATH /usr/ucb; do
+ IFS="$lt_save_ifs"
+ if (test -f $dir/echo || test -f $dir/echo$ac_exeext) &&
+ test "X`($dir/echo '\t') 2>/dev/null`" = 'X\t' &&
+ echo_testing_string=`($dir/echo "$echo_test_string") 2>/dev/null` &&
+ test "X$echo_testing_string" = "X$echo_test_string"; then
+ ECHO="$dir/echo"
+ break
+ fi
+ done
+ IFS="$lt_save_ifs"
+
+ if test "X$ECHO" = Xecho; then
+ # We didn't find a better echo, so look for alternatives.
+ if test "X`{ print -r '\t'; } 2>/dev/null`" = 'X\t' &&
+ echo_testing_string=`{ print -r "$echo_test_string"; } 2>/dev/null` &&
+ test "X$echo_testing_string" = "X$echo_test_string"; then
+ # This shell has a builtin print -r that does the trick.
+ ECHO='print -r'
+ elif { test -f /bin/ksh || test -f /bin/ksh$ac_exeext; } &&
+ test "X$CONFIG_SHELL" != X/bin/ksh; then
+ # If we have ksh, try running configure again with it.
+ ORIGINAL_CONFIG_SHELL=${CONFIG_SHELL-/bin/sh}
+ export ORIGINAL_CONFIG_SHELL
+ CONFIG_SHELL=/bin/ksh
+ export CONFIG_SHELL
+ exec $CONFIG_SHELL "$0" --no-reexec ${1+"$@"}
+ else
+ # Try using printf.
+ ECHO='printf %s\n'
+ if test "X`{ $ECHO '\t'; } 2>/dev/null`" = 'X\t' &&
+ echo_testing_string=`{ $ECHO "$echo_test_string"; } 2>/dev/null` &&
+ test "X$echo_testing_string" = "X$echo_test_string"; then
+ # Cool, printf works
+ :
+ elif echo_testing_string=`($ORIGINAL_CONFIG_SHELL "$0" --fallback-echo '\t') 2>/dev/null` &&
+ test "X$echo_testing_string" = 'X\t' &&
+ echo_testing_string=`($ORIGINAL_CONFIG_SHELL "$0" --fallback-echo "$echo_test_string") 2>/dev/null` &&
+ test "X$echo_testing_string" = "X$echo_test_string"; then
+ CONFIG_SHELL=$ORIGINAL_CONFIG_SHELL
+ export CONFIG_SHELL
+ SHELL="$CONFIG_SHELL"
+ export SHELL
+ ECHO="$CONFIG_SHELL $0 --fallback-echo"
+ elif echo_testing_string=`($CONFIG_SHELL "$0" --fallback-echo '\t') 2>/dev/null` &&
+ test "X$echo_testing_string" = 'X\t' &&
+ echo_testing_string=`($CONFIG_SHELL "$0" --fallback-echo "$echo_test_string") 2>/dev/null` &&
+ test "X$echo_testing_string" = "X$echo_test_string"; then
+ ECHO="$CONFIG_SHELL $0 --fallback-echo"
+ else
+ # maybe with a smaller string...
+ prev=:
+
+ for cmd in 'echo test' 'sed 2q "$0"' 'sed 10q "$0"' 'sed 20q "$0"' 'sed 50q "$0"'; do
+ if { test "X$echo_test_string" = "X`eval $cmd`"; } 2>/dev/null
+ then
+ break
+ fi
+ prev="$cmd"
+ done
+
+ if test "$prev" != 'sed 50q "$0"'; then
+ echo_test_string=`eval $prev`
+ export echo_test_string
+ exec ${ORIGINAL_CONFIG_SHELL-${CONFIG_SHELL-/bin/sh}} "$0" ${1+"$@"}
+ else
+ # Oops. We lost completely, so just stick with echo.
+ ECHO=echo
+ fi
+ fi
+ fi
+ fi
+ fi
+fi
+
+# Copy echo and quote the copy suitably for passing to libtool from
+# the Makefile, instead of quoting the original, which is used later.
+lt_ECHO=$ECHO
+if test "X$lt_ECHO" = "X$CONFIG_SHELL $0 --fallback-echo"; then
+ lt_ECHO="$CONFIG_SHELL \\\$\$0 --fallback-echo"
+fi
+
+
+
+
+test -n "$DJDIR" || exec 7<&0 </dev/null
+exec 6>&1
+
+# Name of the host.
+# hostname on some systems (SVR3.2, old GNU/Linux) returns a bogus exit status,
+# so uname gets run too.
+ac_hostname=`(hostname || uname -n) 2>/dev/null | sed 1q`
+
+#
+# Initializations.
+#
+ac_default_prefix=/usr/local
+ac_clean_files=
+ac_config_libobj_dir=.
+LIBOBJS=
+cross_compiling=no
+subdirs=
+MFLAGS=
+MAKEFLAGS=
+
+# Identity of this package.
+PACKAGE_NAME='yaml'
+PACKAGE_TARNAME='yaml'
+PACKAGE_VERSION='0.1.4'
+PACKAGE_STRING='yaml 0.1.4'
+PACKAGE_BUGREPORT='http://pyyaml.org/newticket?component=libyaml'
+PACKAGE_URL=''
+
+# Factoring default headers for most tests.
+ac_includes_default="\
+#include <stdio.h>
+#ifdef HAVE_SYS_TYPES_H
+# include <sys/types.h>
+#endif
+#ifdef HAVE_SYS_STAT_H
+# include <sys/stat.h>
+#endif
+#ifdef STDC_HEADERS
+# include <stdlib.h>
+# include <stddef.h>
+#else
+# ifdef HAVE_STDLIB_H
+# include <stdlib.h>
+# endif
+#endif
+#ifdef HAVE_STRING_H
+# if !defined STDC_HEADERS && defined HAVE_MEMORY_H
+# include <memory.h>
+# endif
+# include <string.h>
+#endif
+#ifdef HAVE_STRINGS_H
+# include <strings.h>
+#endif
+#ifdef HAVE_INTTYPES_H
+# include <inttypes.h>
+#endif
+#ifdef HAVE_STDINT_H
+# include <stdint.h>
+#endif
+#ifdef HAVE_UNISTD_H
+# include <unistd.h>
+#endif"
+
+ac_subst_vars='am__EXEEXT_FALSE
+am__EXEEXT_TRUE
+LTLIBOBJS
+LIBOBJS
+DOXYGEN_FALSE
+DOXYGEN_TRUE
+DOXYGEN
+OTOOL64
+OTOOL
+LIPO
+NMEDIT
+DSYMUTIL
+lt_ECHO
+RANLIB
+AR
+OBJDUMP
+NM
+ac_ct_DUMPBIN
+DUMPBIN
+LD
+FGREP
+EGREP
+GREP
+SED
+host_os
+host_vendor
+host_cpu
+host
+build_os
+build_vendor
+build_cpu
+build
+LIBTOOL
+LN_S
+CPP
+am__fastdepCC_FALSE
+am__fastdepCC_TRUE
+CCDEPMODE
+AMDEPBACKSLASH
+AMDEP_FALSE
+AMDEP_TRUE
+am__quote
+am__include
+DEPDIR
+OBJEXT
+EXEEXT
+ac_ct_CC
+CPPFLAGS
+LDFLAGS
+CFLAGS
+CC
+YAML_LT_AGE
+YAML_LT_REVISION
+YAML_LT_CURRENT
+YAML_LT_RELEASE
+am__untar
+am__tar
+AMTAR
+am__leading_dot
+SET_MAKE
+AWK
+mkdir_p
+MKDIR_P
+INSTALL_STRIP_PROGRAM
+STRIP
+install_sh
+MAKEINFO
+AUTOHEADER
+AUTOMAKE
+AUTOCONF
+ACLOCAL
+VERSION
+PACKAGE
+CYGPATH_W
+am__isrc
+INSTALL_DATA
+INSTALL_SCRIPT
+INSTALL_PROGRAM
+target_alias
+host_alias
+build_alias
+LIBS
+ECHO_T
+ECHO_N
+ECHO_C
+DEFS
+mandir
+localedir
+libdir
+psdir
+pdfdir
+dvidir
+htmldir
+infodir
+docdir
+oldincludedir
+includedir
+localstatedir
+sharedstatedir
+sysconfdir
+datadir
+datarootdir
+libexecdir
+sbindir
+bindir
+program_transform_name
+prefix
+exec_prefix
+PACKAGE_URL
+PACKAGE_BUGREPORT
+PACKAGE_STRING
+PACKAGE_VERSION
+PACKAGE_TARNAME
+PACKAGE_NAME
+PATH_SEPARATOR
+SHELL'
+ac_subst_files=''
+ac_user_opts='
+enable_option_checking
+enable_dependency_tracking
+enable_shared
+enable_static
+with_pic
+enable_fast_install
+with_gnu_ld
+enable_libtool_lock
+'
+ ac_precious_vars='build_alias
+host_alias
+target_alias
+CC
+CFLAGS
+LDFLAGS
+LIBS
+CPPFLAGS
+CPP'
+
+
+# Initialize some variables set by options.
+ac_init_help=
+ac_init_version=false
+ac_unrecognized_opts=
+ac_unrecognized_sep=
+# The variables have the same names as the options, with
+# dashes changed to underlines.
+cache_file=/dev/null
+exec_prefix=NONE
+no_create=
+no_recursion=
+prefix=NONE
+program_prefix=NONE
+program_suffix=NONE
+program_transform_name=s,x,x,
+silent=
+site=
+srcdir=
+verbose=
+x_includes=NONE
+x_libraries=NONE
+
+# Installation directory options.
+# These are left unexpanded so users can "make install exec_prefix=/foo"
+# and all the variables that are supposed to be based on exec_prefix
+# by default will actually change.
+# Use braces instead of parens because sh, perl, etc. also accept them.
+# (The list follows the same order as the GNU Coding Standards.)
+bindir='${exec_prefix}/bin'
+sbindir='${exec_prefix}/sbin'
+libexecdir='${exec_prefix}/libexec'
+datarootdir='${prefix}/share'
+datadir='${datarootdir}'
+sysconfdir='${prefix}/etc'
+sharedstatedir='${prefix}/com'
+localstatedir='${prefix}/var'
+includedir='${prefix}/include'
+oldincludedir='/usr/include'
+docdir='${datarootdir}/doc/${PACKAGE_TARNAME}'
+infodir='${datarootdir}/info'
+htmldir='${docdir}'
+dvidir='${docdir}'
+pdfdir='${docdir}'
+psdir='${docdir}'
+libdir='${exec_prefix}/lib'
+localedir='${datarootdir}/locale'
+mandir='${datarootdir}/man'
+
+ac_prev=
+ac_dashdash=
+for ac_option
+do
+ # If the previous option needs an argument, assign it.
+ if test -n "$ac_prev"; then
+ eval $ac_prev=\$ac_option
+ ac_prev=
+ continue
+ fi
+
+ case $ac_option in
+ *=?*) ac_optarg=`expr "X$ac_option" : '[^=]*=\(.*\)'` ;;
+ *=) ac_optarg= ;;
+ *) ac_optarg=yes ;;
+ esac
+
+ # Accept the important Cygnus configure options, so we can diagnose typos.
+
+ case $ac_dashdash$ac_option in
+ --)
+ ac_dashdash=yes ;;
+
+ -bindir | --bindir | --bindi | --bind | --bin | --bi)
+ ac_prev=bindir ;;
+ -bindir=* | --bindir=* | --bindi=* | --bind=* | --bin=* | --bi=*)
+ bindir=$ac_optarg ;;
+
+ -build | --build | --buil | --bui | --bu)
+ ac_prev=build_alias ;;
+ -build=* | --build=* | --buil=* | --bui=* | --bu=*)
+ build_alias=$ac_optarg ;;
+
+ -cache-file | --cache-file | --cache-fil | --cache-fi \
+ | --cache-f | --cache- | --cache | --cach | --cac | --ca | --c)
+ ac_prev=cache_file ;;
+ -cache-file=* | --cache-file=* | --cache-fil=* | --cache-fi=* \
+ | --cache-f=* | --cache-=* | --cache=* | --cach=* | --cac=* | --ca=* | --c=*)
+ cache_file=$ac_optarg ;;
+
+ --config-cache | -C)
+ cache_file=config.cache ;;
+
+ -datadir | --datadir | --datadi | --datad)
+ ac_prev=datadir ;;
+ -datadir=* | --datadir=* | --datadi=* | --datad=*)
+ datadir=$ac_optarg ;;
+
+ -datarootdir | --datarootdir | --datarootdi | --datarootd | --dataroot \
+ | --dataroo | --dataro | --datar)
+ ac_prev=datarootdir ;;
+ -datarootdir=* | --datarootdir=* | --datarootdi=* | --datarootd=* \
+ | --dataroot=* | --dataroo=* | --dataro=* | --datar=*)
+ datarootdir=$ac_optarg ;;
+
+ -disable-* | --disable-*)
+ ac_useropt=`expr "x$ac_option" : 'x-*disable-\(.*\)'`
+ # Reject names that are not valid shell variable names.
+ expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null &&
+ as_fn_error $? "invalid feature name: $ac_useropt"
+ ac_useropt_orig=$ac_useropt
+ ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'`
+ case $ac_user_opts in
+ *"
+"enable_$ac_useropt"
+"*) ;;
+ *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--disable-$ac_useropt_orig"
+ ac_unrecognized_sep=', ';;
+ esac
+ eval enable_$ac_useropt=no ;;
+
+ -docdir | --docdir | --docdi | --doc | --do)
+ ac_prev=docdir ;;
+ -docdir=* | --docdir=* | --docdi=* | --doc=* | --do=*)
+ docdir=$ac_optarg ;;
+
+ -dvidir | --dvidir | --dvidi | --dvid | --dvi | --dv)
+ ac_prev=dvidir ;;
+ -dvidir=* | --dvidir=* | --dvidi=* | --dvid=* | --dvi=* | --dv=*)
+ dvidir=$ac_optarg ;;
+
+ -enable-* | --enable-*)
+ ac_useropt=`expr "x$ac_option" : 'x-*enable-\([^=]*\)'`
+ # Reject names that are not valid shell variable names.
+ expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null &&
+ as_fn_error $? "invalid feature name: $ac_useropt"
+ ac_useropt_orig=$ac_useropt
+ ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'`
+ case $ac_user_opts in
+ *"
+"enable_$ac_useropt"
+"*) ;;
+ *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--enable-$ac_useropt_orig"
+ ac_unrecognized_sep=', ';;
+ esac
+ eval enable_$ac_useropt=\$ac_optarg ;;
+
+ -exec-prefix | --exec_prefix | --exec-prefix | --exec-prefi \
+ | --exec-pref | --exec-pre | --exec-pr | --exec-p | --exec- \
+ | --exec | --exe | --ex)
+ ac_prev=exec_prefix ;;
+ -exec-prefix=* | --exec_prefix=* | --exec-prefix=* | --exec-prefi=* \
+ | --exec-pref=* | --exec-pre=* | --exec-pr=* | --exec-p=* | --exec-=* \
+ | --exec=* | --exe=* | --ex=*)
+ exec_prefix=$ac_optarg ;;
+
+ -gas | --gas | --ga | --g)
+ # Obsolete; use --with-gas.
+ with_gas=yes ;;
+
+ -help | --help | --hel | --he | -h)
+ ac_init_help=long ;;
+ -help=r* | --help=r* | --hel=r* | --he=r* | -hr*)
+ ac_init_help=recursive ;;
+ -help=s* | --help=s* | --hel=s* | --he=s* | -hs*)
+ ac_init_help=short ;;
+
+ -host | --host | --hos | --ho)
+ ac_prev=host_alias ;;
+ -host=* | --host=* | --hos=* | --ho=*)
+ host_alias=$ac_optarg ;;
+
+ -htmldir | --htmldir | --htmldi | --htmld | --html | --htm | --ht)
+ ac_prev=htmldir ;;
+ -htmldir=* | --htmldir=* | --htmldi=* | --htmld=* | --html=* | --htm=* \
+ | --ht=*)
+ htmldir=$ac_optarg ;;
+
+ -includedir | --includedir | --includedi | --included | --include \
+ | --includ | --inclu | --incl | --inc)
+ ac_prev=includedir ;;
+ -includedir=* | --includedir=* | --includedi=* | --included=* | --include=* \
+ | --includ=* | --inclu=* | --incl=* | --inc=*)
+ includedir=$ac_optarg ;;
+
+ -infodir | --infodir | --infodi | --infod | --info | --inf)
+ ac_prev=infodir ;;
+ -infodir=* | --infodir=* | --infodi=* | --infod=* | --info=* | --inf=*)
+ infodir=$ac_optarg ;;
+
+ -libdir | --libdir | --libdi | --libd)
+ ac_prev=libdir ;;
+ -libdir=* | --libdir=* | --libdi=* | --libd=*)
+ libdir=$ac_optarg ;;
+
+ -libexecdir | --libexecdir | --libexecdi | --libexecd | --libexec \
+ | --libexe | --libex | --libe)
+ ac_prev=libexecdir ;;
+ -libexecdir=* | --libexecdir=* | --libexecdi=* | --libexecd=* | --libexec=* \
+ | --libexe=* | --libex=* | --libe=*)
+ libexecdir=$ac_optarg ;;
+
+ -localedir | --localedir | --localedi | --localed | --locale)
+ ac_prev=localedir ;;
+ -localedir=* | --localedir=* | --localedi=* | --localed=* | --locale=*)
+ localedir=$ac_optarg ;;
+
+ -localstatedir | --localstatedir | --localstatedi | --localstated \
+ | --localstate | --localstat | --localsta | --localst | --locals)
+ ac_prev=localstatedir ;;
+ -localstatedir=* | --localstatedir=* | --localstatedi=* | --localstated=* \
+ | --localstate=* | --localstat=* | --localsta=* | --localst=* | --locals=*)
+ localstatedir=$ac_optarg ;;
+
+ -mandir | --mandir | --mandi | --mand | --man | --ma | --m)
+ ac_prev=mandir ;;
+ -mandir=* | --mandir=* | --mandi=* | --mand=* | --man=* | --ma=* | --m=*)
+ mandir=$ac_optarg ;;
+
+ -nfp | --nfp | --nf)
+ # Obsolete; use --without-fp.
+ with_fp=no ;;
+
+ -no-create | --no-create | --no-creat | --no-crea | --no-cre \
+ | --no-cr | --no-c | -n)
+ no_create=yes ;;
+
+ -no-recursion | --no-recursion | --no-recursio | --no-recursi \
+ | --no-recurs | --no-recur | --no-recu | --no-rec | --no-re | --no-r)
+ no_recursion=yes ;;
+
+ -oldincludedir | --oldincludedir | --oldincludedi | --oldincluded \
+ | --oldinclude | --oldinclud | --oldinclu | --oldincl | --oldinc \
+ | --oldin | --oldi | --old | --ol | --o)
+ ac_prev=oldincludedir ;;
+ -oldincludedir=* | --oldincludedir=* | --oldincludedi=* | --oldincluded=* \
+ | --oldinclude=* | --oldinclud=* | --oldinclu=* | --oldincl=* | --oldinc=* \
+ | --oldin=* | --oldi=* | --old=* | --ol=* | --o=*)
+ oldincludedir=$ac_optarg ;;
+
+ -prefix | --prefix | --prefi | --pref | --pre | --pr | --p)
+ ac_prev=prefix ;;
+ -prefix=* | --prefix=* | --prefi=* | --pref=* | --pre=* | --pr=* | --p=*)
+ prefix=$ac_optarg ;;
+
+ -program-prefix | --program-prefix | --program-prefi | --program-pref \
+ | --program-pre | --program-pr | --program-p)
+ ac_prev=program_prefix ;;
+ -program-prefix=* | --program-prefix=* | --program-prefi=* \
+ | --program-pref=* | --program-pre=* | --program-pr=* | --program-p=*)
+ program_prefix=$ac_optarg ;;
+
+ -program-suffix | --program-suffix | --program-suffi | --program-suff \
+ | --program-suf | --program-su | --program-s)
+ ac_prev=program_suffix ;;
+ -program-suffix=* | --program-suffix=* | --program-suffi=* \
+ | --program-suff=* | --program-suf=* | --program-su=* | --program-s=*)
+ program_suffix=$ac_optarg ;;
+
+ -program-transform-name | --program-transform-name \
+ | --program-transform-nam | --program-transform-na \
+ | --program-transform-n | --program-transform- \
+ | --program-transform | --program-transfor \
+ | --program-transfo | --program-transf \
+ | --program-trans | --program-tran \
+ | --progr-tra | --program-tr | --program-t)
+ ac_prev=program_transform_name ;;
+ -program-transform-name=* | --program-transform-name=* \
+ | --program-transform-nam=* | --program-transform-na=* \
+ | --program-transform-n=* | --program-transform-=* \
+ | --program-transform=* | --program-transfor=* \
+ | --program-transfo=* | --program-transf=* \
+ | --program-trans=* | --program-tran=* \
+ | --progr-tra=* | --program-tr=* | --program-t=*)
+ program_transform_name=$ac_optarg ;;
+
+ -pdfdir | --pdfdir | --pdfdi | --pdfd | --pdf | --pd)
+ ac_prev=pdfdir ;;
+ -pdfdir=* | --pdfdir=* | --pdfdi=* | --pdfd=* | --pdf=* | --pd=*)
+ pdfdir=$ac_optarg ;;
+
+ -psdir | --psdir | --psdi | --psd | --ps)
+ ac_prev=psdir ;;
+ -psdir=* | --psdir=* | --psdi=* | --psd=* | --ps=*)
+ psdir=$ac_optarg ;;
+
+ -q | -quiet | --quiet | --quie | --qui | --qu | --q \
+ | -silent | --silent | --silen | --sile | --sil)
+ silent=yes ;;
+
+ -sbindir | --sbindir | --sbindi | --sbind | --sbin | --sbi | --sb)
+ ac_prev=sbindir ;;
+ -sbindir=* | --sbindir=* | --sbindi=* | --sbind=* | --sbin=* \
+ | --sbi=* | --sb=*)
+ sbindir=$ac_optarg ;;
+
+ -sharedstatedir | --sharedstatedir | --sharedstatedi \
+ | --sharedstated | --sharedstate | --sharedstat | --sharedsta \
+ | --sharedst | --shareds | --shared | --share | --shar \
+ | --sha | --sh)
+ ac_prev=sharedstatedir ;;
+ -sharedstatedir=* | --sharedstatedir=* | --sharedstatedi=* \
+ | --sharedstated=* | --sharedstate=* | --sharedstat=* | --sharedsta=* \
+ | --sharedst=* | --shareds=* | --shared=* | --share=* | --shar=* \
+ | --sha=* | --sh=*)
+ sharedstatedir=$ac_optarg ;;
+
+ -site | --site | --sit)
+ ac_prev=site ;;
+ -site=* | --site=* | --sit=*)
+ site=$ac_optarg ;;
+
+ -srcdir | --srcdir | --srcdi | --srcd | --src | --sr)
+ ac_prev=srcdir ;;
+ -srcdir=* | --srcdir=* | --srcdi=* | --srcd=* | --src=* | --sr=*)
+ srcdir=$ac_optarg ;;
+
+ -sysconfdir | --sysconfdir | --sysconfdi | --sysconfd | --sysconf \
+ | --syscon | --sysco | --sysc | --sys | --sy)
+ ac_prev=sysconfdir ;;
+ -sysconfdir=* | --sysconfdir=* | --sysconfdi=* | --sysconfd=* | --sysconf=* \
+ | --syscon=* | --sysco=* | --sysc=* | --sys=* | --sy=*)
+ sysconfdir=$ac_optarg ;;
+
+ -target | --target | --targe | --targ | --tar | --ta | --t)
+ ac_prev=target_alias ;;
+ -target=* | --target=* | --targe=* | --targ=* | --tar=* | --ta=* | --t=*)
+ target_alias=$ac_optarg ;;
+
+ -v | -verbose | --verbose | --verbos | --verbo | --verb)
+ verbose=yes ;;
+
+ -version | --version | --versio | --versi | --vers | -V)
+ ac_init_version=: ;;
+
+ -with-* | --with-*)
+ ac_useropt=`expr "x$ac_option" : 'x-*with-\([^=]*\)'`
+ # Reject names that are not valid shell variable names.
+ expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null &&
+ as_fn_error $? "invalid package name: $ac_useropt"
+ ac_useropt_orig=$ac_useropt
+ ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'`
+ case $ac_user_opts in
+ *"
+"with_$ac_useropt"
+"*) ;;
+ *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--with-$ac_useropt_orig"
+ ac_unrecognized_sep=', ';;
+ esac
+ eval with_$ac_useropt=\$ac_optarg ;;
+
+ -without-* | --without-*)
+ ac_useropt=`expr "x$ac_option" : 'x-*without-\(.*\)'`
+ # Reject names that are not valid shell variable names.
+ expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null &&
+ as_fn_error $? "invalid package name: $ac_useropt"
+ ac_useropt_orig=$ac_useropt
+ ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'`
+ case $ac_user_opts in
+ *"
+"with_$ac_useropt"
+"*) ;;
+ *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--without-$ac_useropt_orig"
+ ac_unrecognized_sep=', ';;
+ esac
+ eval with_$ac_useropt=no ;;
+
+ --x)
+ # Obsolete; use --with-x.
+ with_x=yes ;;
+
+ -x-includes | --x-includes | --x-include | --x-includ | --x-inclu \
+ | --x-incl | --x-inc | --x-in | --x-i)
+ ac_prev=x_includes ;;
+ -x-includes=* | --x-includes=* | --x-include=* | --x-includ=* | --x-inclu=* \
+ | --x-incl=* | --x-inc=* | --x-in=* | --x-i=*)
+ x_includes=$ac_optarg ;;
+
+ -x-libraries | --x-libraries | --x-librarie | --x-librari \
+ | --x-librar | --x-libra | --x-libr | --x-lib | --x-li | --x-l)
+ ac_prev=x_libraries ;;
+ -x-libraries=* | --x-libraries=* | --x-librarie=* | --x-librari=* \
+ | --x-librar=* | --x-libra=* | --x-libr=* | --x-lib=* | --x-li=* | --x-l=*)
+ x_libraries=$ac_optarg ;;
+
+ -*) as_fn_error $? "unrecognized option: \`$ac_option'
+Try \`$0 --help' for more information"
+ ;;
+
+ *=*)
+ ac_envvar=`expr "x$ac_option" : 'x\([^=]*\)='`
+ # Reject names that are not valid shell variable names.
+ case $ac_envvar in #(
+ '' | [0-9]* | *[!_$as_cr_alnum]* )
+ as_fn_error $? "invalid variable name: \`$ac_envvar'" ;;
+ esac
+ eval $ac_envvar=\$ac_optarg
+ export $ac_envvar ;;
+
+ *)
+ # FIXME: should be removed in autoconf 3.0.
+ $as_echo "$as_me: WARNING: you should use --build, --host, --target" >&2
+ expr "x$ac_option" : ".*[^-._$as_cr_alnum]" >/dev/null &&
+ $as_echo "$as_me: WARNING: invalid host type: $ac_option" >&2
+ : ${build_alias=$ac_option} ${host_alias=$ac_option} ${target_alias=$ac_option}
+ ;;
+
+ esac
+done
+
+if test -n "$ac_prev"; then
+ ac_option=--`echo $ac_prev | sed 's/_/-/g'`
+ as_fn_error $? "missing argument to $ac_option"
+fi
+
+if test -n "$ac_unrecognized_opts"; then
+ case $enable_option_checking in
+ no) ;;
+ fatal) as_fn_error $? "unrecognized options: $ac_unrecognized_opts" ;;
+ *) $as_echo "$as_me: WARNING: unrecognized options: $ac_unrecognized_opts" >&2 ;;
+ esac
+fi
+
+# Check all directory arguments for consistency.
+for ac_var in exec_prefix prefix bindir sbindir libexecdir datarootdir \
+ datadir sysconfdir sharedstatedir localstatedir includedir \
+ oldincludedir docdir infodir htmldir dvidir pdfdir psdir \
+ libdir localedir mandir
+do
+ eval ac_val=\$$ac_var
+ # Remove trailing slashes.
+ case $ac_val in
+ */ )
+ ac_val=`expr "X$ac_val" : 'X\(.*[^/]\)' \| "X$ac_val" : 'X\(.*\)'`
+ eval $ac_var=\$ac_val;;
+ esac
+ # Be sure to have absolute directory names.
+ case $ac_val in
+ [\\/$]* | ?:[\\/]* ) continue;;
+ NONE | '' ) case $ac_var in *prefix ) continue;; esac;;
+ esac
+ as_fn_error $? "expected an absolute directory name for --$ac_var: $ac_val"
+done
+
+# There might be people who depend on the old broken behavior: `$host'
+# used to hold the argument of --host etc.
+# FIXME: To remove some day.
+build=$build_alias
+host=$host_alias
+target=$target_alias
+
+# FIXME: To remove some day.
+if test "x$host_alias" != x; then
+ if test "x$build_alias" = x; then
+ cross_compiling=maybe
+ $as_echo "$as_me: WARNING: if you wanted to set the --build type, don't use --host.
+ If a cross compiler is detected then cross compile mode will be used" >&2
+ elif test "x$build_alias" != "x$host_alias"; then
+ cross_compiling=yes
+ fi
+fi
+
+ac_tool_prefix=
+test -n "$host_alias" && ac_tool_prefix=$host_alias-
+
+test "$silent" = yes && exec 6>/dev/null
+
+
+ac_pwd=`pwd` && test -n "$ac_pwd" &&
+ac_ls_di=`ls -di .` &&
+ac_pwd_ls_di=`cd "$ac_pwd" && ls -di .` ||
+ as_fn_error $? "working directory cannot be determined"
+test "X$ac_ls_di" = "X$ac_pwd_ls_di" ||
+ as_fn_error $? "pwd does not report name of working directory"
+
+
+# Find the source files, if location was not specified.
+if test -z "$srcdir"; then
+ ac_srcdir_defaulted=yes
+ # Try the directory containing this script, then the parent directory.
+ ac_confdir=`$as_dirname -- "$as_myself" ||
+$as_expr X"$as_myself" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
+ X"$as_myself" : 'X\(//\)[^/]' \| \
+ X"$as_myself" : 'X\(//\)$' \| \
+ X"$as_myself" : 'X\(/\)' \| . 2>/dev/null ||
+$as_echo X"$as_myself" |
+ sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{
+ s//\1/
+ q
+ }
+ /^X\(\/\/\)[^/].*/{
+ s//\1/
+ q
+ }
+ /^X\(\/\/\)$/{
+ s//\1/
+ q
+ }
+ /^X\(\/\).*/{
+ s//\1/
+ q
+ }
+ s/.*/./; q'`
+ srcdir=$ac_confdir
+ if test ! -r "$srcdir/$ac_unique_file"; then
+ srcdir=..
+ fi
+else
+ ac_srcdir_defaulted=no
+fi
+if test ! -r "$srcdir/$ac_unique_file"; then
+ test "$ac_srcdir_defaulted" = yes && srcdir="$ac_confdir or .."
+ as_fn_error $? "cannot find sources ($ac_unique_file) in $srcdir"
+fi
+ac_msg="sources are in $srcdir, but \`cd $srcdir' does not work"
+ac_abs_confdir=`(
+ cd "$srcdir" && test -r "./$ac_unique_file" || as_fn_error $? "$ac_msg"
+ pwd)`
+# When building in place, set srcdir=.
+if test "$ac_abs_confdir" = "$ac_pwd"; then
+ srcdir=.
+fi
+# Remove unnecessary trailing slashes from srcdir.
+# Double slashes in file names in object file debugging info
+# mess up M-x gdb in Emacs.
+case $srcdir in
+*/) srcdir=`expr "X$srcdir" : 'X\(.*[^/]\)' \| "X$srcdir" : 'X\(.*\)'`;;
+esac
+for ac_var in $ac_precious_vars; do
+ eval ac_env_${ac_var}_set=\${${ac_var}+set}
+ eval ac_env_${ac_var}_value=\$${ac_var}
+ eval ac_cv_env_${ac_var}_set=\${${ac_var}+set}
+ eval ac_cv_env_${ac_var}_value=\$${ac_var}
+done
+
+#
+# Report the --help message.
+#
+if test "$ac_init_help" = "long"; then
+ # Omit some internal or obsolete options to make the list less imposing.
+ # This message is too long to be a string in the A/UX 3.1 sh.
+ cat <<_ACEOF
+\`configure' configures yaml 0.1.4 to adapt to many kinds of systems.
+
+Usage: $0 [OPTION]... [VAR=VALUE]...
+
+To assign environment variables (e.g., CC, CFLAGS...), specify them as
+VAR=VALUE. See below for descriptions of some of the useful variables.
+
+Defaults for the options are specified in brackets.
+
+Configuration:
+ -h, --help display this help and exit
+ --help=short display options specific to this package
+ --help=recursive display the short help of all the included packages
+ -V, --version display version information and exit
+ -q, --quiet, --silent do not print \`checking ...' messages
+ --cache-file=FILE cache test results in FILE [disabled]
+ -C, --config-cache alias for \`--cache-file=config.cache'
+ -n, --no-create do not create output files
+ --srcdir=DIR find the sources in DIR [configure dir or \`..']
+
+Installation directories:
+ --prefix=PREFIX install architecture-independent files in PREFIX
+ [$ac_default_prefix]
+ --exec-prefix=EPREFIX install architecture-dependent files in EPREFIX
+ [PREFIX]
+
+By default, \`make install' will install all the files in
+\`$ac_default_prefix/bin', \`$ac_default_prefix/lib' etc. You can specify
+an installation prefix other than \`$ac_default_prefix' using \`--prefix',
+for instance \`--prefix=\$HOME'.
+
+For better control, use the options below.
+
+Fine tuning of the installation directories:
+ --bindir=DIR user executables [EPREFIX/bin]
+ --sbindir=DIR system admin executables [EPREFIX/sbin]
+ --libexecdir=DIR program executables [EPREFIX/libexec]
+ --sysconfdir=DIR read-only single-machine data [PREFIX/etc]
+ --sharedstatedir=DIR modifiable architecture-independent data [PREFIX/com]
+ --localstatedir=DIR modifiable single-machine data [PREFIX/var]
+ --libdir=DIR object code libraries [EPREFIX/lib]
+ --includedir=DIR C header files [PREFIX/include]
+ --oldincludedir=DIR C header files for non-gcc [/usr/include]
+ --datarootdir=DIR read-only arch.-independent data root [PREFIX/share]
+ --datadir=DIR read-only architecture-independent data [DATAROOTDIR]
+ --infodir=DIR info documentation [DATAROOTDIR/info]
+ --localedir=DIR locale-dependent data [DATAROOTDIR/locale]
+ --mandir=DIR man documentation [DATAROOTDIR/man]
+ --docdir=DIR documentation root [DATAROOTDIR/doc/yaml]
+ --htmldir=DIR html documentation [DOCDIR]
+ --dvidir=DIR dvi documentation [DOCDIR]
+ --pdfdir=DIR pdf documentation [DOCDIR]
+ --psdir=DIR ps documentation [DOCDIR]
+_ACEOF
+
+ cat <<\_ACEOF
+
+Program names:
+ --program-prefix=PREFIX prepend PREFIX to installed program names
+ --program-suffix=SUFFIX append SUFFIX to installed program names
+ --program-transform-name=PROGRAM run sed PROGRAM on installed program names
+
+System types:
+ --build=BUILD configure for building on BUILD [guessed]
+ --host=HOST cross-compile to build programs to run on HOST [BUILD]
+_ACEOF
+fi
+
+if test -n "$ac_init_help"; then
+ case $ac_init_help in
+ short | recursive ) echo "Configuration of yaml 0.1.4:";;
+ esac
+ cat <<\_ACEOF
+
+Optional Features:
+ --disable-option-checking ignore unrecognized --enable/--with options
+ --disable-FEATURE do not include FEATURE (same as --enable-FEATURE=no)
+ --enable-FEATURE[=ARG] include FEATURE [ARG=yes]
+ --disable-dependency-tracking speeds up one-time build
+ --enable-dependency-tracking do not reject slow dependency extractors
+ --enable-shared[=PKGS] build shared libraries [default=yes]
+ --enable-static[=PKGS] build static libraries [default=yes]
+ --enable-fast-install[=PKGS]
+ optimize for fast installation [default=yes]
+ --disable-libtool-lock avoid locking (might break parallel builds)
+
+Optional Packages:
+ --with-PACKAGE[=ARG] use PACKAGE [ARG=yes]
+ --without-PACKAGE do not use PACKAGE (same as --with-PACKAGE=no)
+ --with-pic try to use only PIC/non-PIC objects [default=use
+ both]
+ --with-gnu-ld assume the C compiler uses GNU ld [default=no]
+
+Some influential environment variables:
+ CC C compiler command
+ CFLAGS C compiler flags
+ LDFLAGS linker flags, e.g. -L<lib dir> if you have libraries in a
+ nonstandard directory <lib dir>
+ LIBS libraries to pass to the linker, e.g. -l<library>
+ CPPFLAGS (Objective) C/C++ preprocessor flags, e.g. -I<include dir> if
+ you have headers in a nonstandard directory <include dir>
+ CPP C preprocessor
+
+Use these variables to override the choices made by `configure' or to help
+it to find libraries and programs with nonstandard names/locations.
+
+Report bugs to <http://pyyaml.org/newticket?component=libyaml>.
+_ACEOF
+ac_status=$?
+fi
+
+if test "$ac_init_help" = "recursive"; then
+ # If there are subdirs, report their specific --help.
+ for ac_dir in : $ac_subdirs_all; do test "x$ac_dir" = x: && continue
+ test -d "$ac_dir" ||
+ { cd "$srcdir" && ac_pwd=`pwd` && srcdir=. && test -d "$ac_dir"; } ||
+ continue
+ ac_builddir=.
+
+case "$ac_dir" in
+.) ac_dir_suffix= ac_top_builddir_sub=. ac_top_build_prefix= ;;
+*)
+ ac_dir_suffix=/`$as_echo "$ac_dir" | sed 's|^\.[\\/]||'`
+ # A ".." for each directory in $ac_dir_suffix.
+ ac_top_builddir_sub=`$as_echo "$ac_dir_suffix" | sed 's|/[^\\/]*|/..|g;s|/||'`
+ case $ac_top_builddir_sub in
+ "") ac_top_builddir_sub=. ac_top_build_prefix= ;;
+ *) ac_top_build_prefix=$ac_top_builddir_sub/ ;;
+ esac ;;
+esac
+ac_abs_top_builddir=$ac_pwd
+ac_abs_builddir=$ac_pwd$ac_dir_suffix
+# for backward compatibility:
+ac_top_builddir=$ac_top_build_prefix
+
+case $srcdir in
+ .) # We are building in place.
+ ac_srcdir=.
+ ac_top_srcdir=$ac_top_builddir_sub
+ ac_abs_top_srcdir=$ac_pwd ;;
+ [\\/]* | ?:[\\/]* ) # Absolute name.
+ ac_srcdir=$srcdir$ac_dir_suffix;
+ ac_top_srcdir=$srcdir
+ ac_abs_top_srcdir=$srcdir ;;
+ *) # Relative name.
+ ac_srcdir=$ac_top_build_prefix$srcdir$ac_dir_suffix
+ ac_top_srcdir=$ac_top_build_prefix$srcdir
+ ac_abs_top_srcdir=$ac_pwd/$srcdir ;;
+esac
+ac_abs_srcdir=$ac_abs_top_srcdir$ac_dir_suffix
+
+ cd "$ac_dir" || { ac_status=$?; continue; }
+ # Check for guested configure.
+ if test -f "$ac_srcdir/configure.gnu"; then
+ echo &&
+ $SHELL "$ac_srcdir/configure.gnu" --help=recursive
+ elif test -f "$ac_srcdir/configure"; then
+ echo &&
+ $SHELL "$ac_srcdir/configure" --help=recursive
+ else
+ $as_echo "$as_me: WARNING: no configuration information is in $ac_dir" >&2
+ fi || ac_status=$?
+ cd "$ac_pwd" || { ac_status=$?; break; }
+ done
+fi
+
+test -n "$ac_init_help" && exit $ac_status
+if $ac_init_version; then
+ cat <<\_ACEOF
+yaml configure 0.1.4
+generated by GNU Autoconf 2.67
+
+Copyright (C) 2010 Free Software Foundation, Inc.
+This configure script is free software; the Free Software Foundation
+gives unlimited permission to copy, distribute and modify it.
+_ACEOF
+ exit
+fi
+
+## ------------------------ ##
+## Autoconf initialization. ##
+## ------------------------ ##
+
+# ac_fn_c_try_compile LINENO
+# --------------------------
+# Try to compile conftest.$ac_ext, and return whether this succeeded.
+ac_fn_c_try_compile ()
+{
+ as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
+ rm -f conftest.$ac_objext
+ if { { ac_try="$ac_compile"
+case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
+$as_echo "$ac_try_echo"; } >&5
+ (eval "$ac_compile") 2>conftest.err
+ ac_status=$?
+ if test -s conftest.err; then
+ grep -v '^ *+' conftest.err >conftest.er1
+ cat conftest.er1 >&5
+ mv -f conftest.er1 conftest.err
+ fi
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; } && {
+ test -z "$ac_c_werror_flag" ||
+ test ! -s conftest.err
+ } && test -s conftest.$ac_objext; then :
+ ac_retval=0
+else
+ $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ ac_retval=1
+fi
+ eval $as_lineno_stack; test "x$as_lineno_stack" = x && { as_lineno=; unset as_lineno;}
+ as_fn_set_status $ac_retval
+
+} # ac_fn_c_try_compile
+
+# ac_fn_c_try_cpp LINENO
+# ----------------------
+# Try to preprocess conftest.$ac_ext, and return whether this succeeded.
+ac_fn_c_try_cpp ()
+{
+ as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
+ if { { ac_try="$ac_cpp conftest.$ac_ext"
+case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
+$as_echo "$ac_try_echo"; } >&5
+ (eval "$ac_cpp conftest.$ac_ext") 2>conftest.err
+ ac_status=$?
+ if test -s conftest.err; then
+ grep -v '^ *+' conftest.err >conftest.er1
+ cat conftest.er1 >&5
+ mv -f conftest.er1 conftest.err
+ fi
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; } > conftest.i && {
+ test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" ||
+ test ! -s conftest.err
+ }; then :
+ ac_retval=0
+else
+ $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ ac_retval=1
+fi
+ eval $as_lineno_stack; test "x$as_lineno_stack" = x && { as_lineno=; unset as_lineno;}
+ as_fn_set_status $ac_retval
+
+} # ac_fn_c_try_cpp
+
+# ac_fn_c_try_link LINENO
+# -----------------------
+# Try to link conftest.$ac_ext, and return whether this succeeded.
+ac_fn_c_try_link ()
+{
+ as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
+ rm -f conftest.$ac_objext conftest$ac_exeext
+ if { { ac_try="$ac_link"
+case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
+$as_echo "$ac_try_echo"; } >&5
+ (eval "$ac_link") 2>conftest.err
+ ac_status=$?
+ if test -s conftest.err; then
+ grep -v '^ *+' conftest.err >conftest.er1
+ cat conftest.er1 >&5
+ mv -f conftest.er1 conftest.err
+ fi
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; } && {
+ test -z "$ac_c_werror_flag" ||
+ test ! -s conftest.err
+ } && test -s conftest$ac_exeext && {
+ test "$cross_compiling" = yes ||
+ $as_test_x conftest$ac_exeext
+ }; then :
+ ac_retval=0
+else
+ $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ ac_retval=1
+fi
+ # Delete the IPA/IPO (Inter Procedural Analysis/Optimization) information
+ # created by the PGI compiler (conftest_ipa8_conftest.oo), as it would
+ # interfere with the next link command; also delete a directory that is
+ # left behind by Apple's compiler. We do this before executing the actions.
+ rm -rf conftest.dSYM conftest_ipa8_conftest.oo
+ eval $as_lineno_stack; test "x$as_lineno_stack" = x && { as_lineno=; unset as_lineno;}
+ as_fn_set_status $ac_retval
+
+} # ac_fn_c_try_link
+
+# ac_fn_c_check_header_compile LINENO HEADER VAR INCLUDES
+# -------------------------------------------------------
+# Tests whether HEADER exists and can be compiled using the include files in
+# INCLUDES, setting the cache variable VAR accordingly.
+ac_fn_c_check_header_compile ()
+{
+ as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5
+$as_echo_n "checking for $2... " >&6; }
+if eval "test \"\${$3+set}\"" = set; then :
+ $as_echo_n "(cached) " >&6
+else
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+$4
+#include <$2>
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+ eval "$3=yes"
+else
+ eval "$3=no"
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+eval ac_res=\$$3
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
+$as_echo "$ac_res" >&6; }
+ eval $as_lineno_stack; test "x$as_lineno_stack" = x && { as_lineno=; unset as_lineno;}
+
+} # ac_fn_c_check_header_compile
+
+# ac_fn_c_try_run LINENO
+# ----------------------
+# Try to link conftest.$ac_ext, and return whether this succeeded. Assumes
+# that executables *can* be run.
+ac_fn_c_try_run ()
+{
+ as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
+ if { { ac_try="$ac_link"
+case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
+$as_echo "$ac_try_echo"; } >&5
+ (eval "$ac_link") 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; } && { ac_try='./conftest$ac_exeext'
+ { { case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
+$as_echo "$ac_try_echo"; } >&5
+ (eval "$ac_try") 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }; }; then :
+ ac_retval=0
+else
+ $as_echo "$as_me: program exited with status $ac_status" >&5
+ $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ ac_retval=$ac_status
+fi
+ rm -rf conftest.dSYM conftest_ipa8_conftest.oo
+ eval $as_lineno_stack; test "x$as_lineno_stack" = x && { as_lineno=; unset as_lineno;}
+ as_fn_set_status $ac_retval
+
+} # ac_fn_c_try_run
+
+# ac_fn_c_check_func LINENO FUNC VAR
+# ----------------------------------
+# Tests whether FUNC exists, setting the cache variable VAR accordingly
+ac_fn_c_check_func ()
+{
+ as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5
+$as_echo_n "checking for $2... " >&6; }
+if eval "test \"\${$3+set}\"" = set; then :
+ $as_echo_n "(cached) " >&6
+else
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+/* Define $2 to an innocuous variant, in case <limits.h> declares $2.
+ For example, HP-UX 11i <limits.h> declares gettimeofday. */
+#define $2 innocuous_$2
+
+/* System header to define __stub macros and hopefully few prototypes,
+ which can conflict with char $2 (); below.
+ Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
+ <limits.h> exists even on freestanding compilers. */
+
+#ifdef __STDC__
+# include <limits.h>
+#else
+# include <assert.h>
+#endif
+
+#undef $2
+
+/* Override any GCC internal prototype to avoid an error.
+ Use char because int might match the return type of a GCC
+ builtin and then its argument prototype would still apply. */
+#ifdef __cplusplus
+extern "C"
+#endif
+char $2 ();
+/* The GNU C library defines this for functions which it implements
+ to always fail with ENOSYS. Some functions are actually named
+ something starting with __ and the normal name is an alias. */
+#if defined __stub_$2 || defined __stub___$2
+choke me
+#endif
+
+int
+main ()
+{
+return $2 ();
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+ eval "$3=yes"
+else
+ eval "$3=no"
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+fi
+eval ac_res=\$$3
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
+$as_echo "$ac_res" >&6; }
+ eval $as_lineno_stack; test "x$as_lineno_stack" = x && { as_lineno=; unset as_lineno;}
+
+} # ac_fn_c_check_func
+
+# ac_fn_c_check_header_mongrel LINENO HEADER VAR INCLUDES
+# -------------------------------------------------------
+# Tests whether HEADER exists, giving a warning if it cannot be compiled using
+# the include files in INCLUDES and setting the cache variable VAR
+# accordingly.
+ac_fn_c_check_header_mongrel ()
+{
+ as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
+ if eval "test \"\${$3+set}\"" = set; then :
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5
+$as_echo_n "checking for $2... " >&6; }
+if eval "test \"\${$3+set}\"" = set; then :
+ $as_echo_n "(cached) " >&6
+fi
+eval ac_res=\$$3
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
+$as_echo "$ac_res" >&6; }
+else
+ # Is the header compilable?
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking $2 usability" >&5
+$as_echo_n "checking $2 usability... " >&6; }
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+$4
+#include <$2>
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+ ac_header_compiler=yes
+else
+ ac_header_compiler=no
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_header_compiler" >&5
+$as_echo "$ac_header_compiler" >&6; }
+
+# Is the header present?
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking $2 presence" >&5
+$as_echo_n "checking $2 presence... " >&6; }
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#include <$2>
+_ACEOF
+if ac_fn_c_try_cpp "$LINENO"; then :
+ ac_header_preproc=yes
+else
+ ac_header_preproc=no
+fi
+rm -f conftest.err conftest.i conftest.$ac_ext
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_header_preproc" >&5
+$as_echo "$ac_header_preproc" >&6; }
+
+# So? What about this header?
+case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in #((
+ yes:no: )
+ { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: accepted by the compiler, rejected by the preprocessor!" >&5
+$as_echo "$as_me: WARNING: $2: accepted by the compiler, rejected by the preprocessor!" >&2;}
+ { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: proceeding with the compiler's result" >&5
+$as_echo "$as_me: WARNING: $2: proceeding with the compiler's result" >&2;}
+ ;;
+ no:yes:* )
+ { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: present but cannot be compiled" >&5
+$as_echo "$as_me: WARNING: $2: present but cannot be compiled" >&2;}
+ { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: check for missing prerequisite headers?" >&5
+$as_echo "$as_me: WARNING: $2: check for missing prerequisite headers?" >&2;}
+ { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: see the Autoconf documentation" >&5
+$as_echo "$as_me: WARNING: $2: see the Autoconf documentation" >&2;}
+ { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: section \"Present But Cannot Be Compiled\"" >&5
+$as_echo "$as_me: WARNING: $2: section \"Present But Cannot Be Compiled\"" >&2;}
+ { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: proceeding with the compiler's result" >&5
+$as_echo "$as_me: WARNING: $2: proceeding with the compiler's result" >&2;}
+( $as_echo "## ------------------------------------------------------------ ##
+## Report this to http://pyyaml.org/newticket?component=libyaml ##
+## ------------------------------------------------------------ ##"
+ ) | sed "s/^/$as_me: WARNING: /" >&2
+ ;;
+esac
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5
+$as_echo_n "checking for $2... " >&6; }
+if eval "test \"\${$3+set}\"" = set; then :
+ $as_echo_n "(cached) " >&6
+else
+ eval "$3=\$ac_header_compiler"
+fi
+eval ac_res=\$$3
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
+$as_echo "$ac_res" >&6; }
+fi
+ eval $as_lineno_stack; test "x$as_lineno_stack" = x && { as_lineno=; unset as_lineno;}
+
+} # ac_fn_c_check_header_mongrel
+
+# ac_fn_c_check_type LINENO TYPE VAR INCLUDES
+# -------------------------------------------
+# Tests whether TYPE exists after having included INCLUDES, setting cache
+# variable VAR accordingly.
+ac_fn_c_check_type ()
+{
+ as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5
+$as_echo_n "checking for $2... " >&6; }
+if eval "test \"\${$3+set}\"" = set; then :
+ $as_echo_n "(cached) " >&6
+else
+ eval "$3=no"
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+$4
+int
+main ()
+{
+if (sizeof ($2))
+ return 0;
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+$4
+int
+main ()
+{
+if (sizeof (($2)))
+ return 0;
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+
+else
+ eval "$3=yes"
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+eval ac_res=\$$3
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
+$as_echo "$ac_res" >&6; }
+ eval $as_lineno_stack; test "x$as_lineno_stack" = x && { as_lineno=; unset as_lineno;}
+
+} # ac_fn_c_check_type
+cat >config.log <<_ACEOF
+This file contains any messages produced by compilers while
+running configure, to aid debugging if configure makes a mistake.
+
+It was created by yaml $as_me 0.1.4, which was
+generated by GNU Autoconf 2.67. Invocation command line was
+
+ $ $0 $@
+
+_ACEOF
+exec 5>>config.log
+{
+cat <<_ASUNAME
+## --------- ##
+## Platform. ##
+## --------- ##
+
+hostname = `(hostname || uname -n) 2>/dev/null | sed 1q`
+uname -m = `(uname -m) 2>/dev/null || echo unknown`
+uname -r = `(uname -r) 2>/dev/null || echo unknown`
+uname -s = `(uname -s) 2>/dev/null || echo unknown`
+uname -v = `(uname -v) 2>/dev/null || echo unknown`
+
+/usr/bin/uname -p = `(/usr/bin/uname -p) 2>/dev/null || echo unknown`
+/bin/uname -X = `(/bin/uname -X) 2>/dev/null || echo unknown`
+
+/bin/arch = `(/bin/arch) 2>/dev/null || echo unknown`
+/usr/bin/arch -k = `(/usr/bin/arch -k) 2>/dev/null || echo unknown`
+/usr/convex/getsysinfo = `(/usr/convex/getsysinfo) 2>/dev/null || echo unknown`
+/usr/bin/hostinfo = `(/usr/bin/hostinfo) 2>/dev/null || echo unknown`
+/bin/machine = `(/bin/machine) 2>/dev/null || echo unknown`
+/usr/bin/oslevel = `(/usr/bin/oslevel) 2>/dev/null || echo unknown`
+/bin/universe = `(/bin/universe) 2>/dev/null || echo unknown`
+
+_ASUNAME
+
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ $as_echo "PATH: $as_dir"
+ done
+IFS=$as_save_IFS
+
+} >&5
+
+cat >&5 <<_ACEOF
+
+
+## ----------- ##
+## Core tests. ##
+## ----------- ##
+
+_ACEOF
+
+
+# Keep a trace of the command line.
+# Strip out --no-create and --no-recursion so they do not pile up.
+# Strip out --silent because we don't want to record it for future runs.
+# Also quote any args containing shell meta-characters.
+# Make two passes to allow for proper duplicate-argument suppression.
+ac_configure_args=
+ac_configure_args0=
+ac_configure_args1=
+ac_must_keep_next=false
+for ac_pass in 1 2
+do
+ for ac_arg
+ do
+ case $ac_arg in
+ -no-create | --no-c* | -n | -no-recursion | --no-r*) continue ;;
+ -q | -quiet | --quiet | --quie | --qui | --qu | --q \
+ | -silent | --silent | --silen | --sile | --sil)
+ continue ;;
+ *\'*)
+ ac_arg=`$as_echo "$ac_arg" | sed "s/'/'\\\\\\\\''/g"` ;;
+ esac
+ case $ac_pass in
+ 1) as_fn_append ac_configure_args0 " '$ac_arg'" ;;
+ 2)
+ as_fn_append ac_configure_args1 " '$ac_arg'"
+ if test $ac_must_keep_next = true; then
+ ac_must_keep_next=false # Got value, back to normal.
+ else
+ case $ac_arg in
+ *=* | --config-cache | -C | -disable-* | --disable-* \
+ | -enable-* | --enable-* | -gas | --g* | -nfp | --nf* \
+ | -q | -quiet | --q* | -silent | --sil* | -v | -verb* \
+ | -with-* | --with-* | -without-* | --without-* | --x)
+ case "$ac_configure_args0 " in
+ "$ac_configure_args1"*" '$ac_arg' "* ) continue ;;
+ esac
+ ;;
+ -* ) ac_must_keep_next=true ;;
+ esac
+ fi
+ as_fn_append ac_configure_args " '$ac_arg'"
+ ;;
+ esac
+ done
+done
+{ ac_configure_args0=; unset ac_configure_args0;}
+{ ac_configure_args1=; unset ac_configure_args1;}
+
+# When interrupted or exit'd, cleanup temporary files, and complete
+# config.log. We remove comments because anyway the quotes in there
+# would cause problems or look ugly.
+# WARNING: Use '\'' to represent an apostrophe within the trap.
+# WARNING: Do not start the trap code with a newline, due to a FreeBSD 4.0 bug.
+trap 'exit_status=$?
+ # Save into config.log some information that might help in debugging.
+ {
+ echo
+
+ $as_echo "## ---------------- ##
+## Cache variables. ##
+## ---------------- ##"
+ echo
+ # The following way of writing the cache mishandles newlines in values,
+(
+ for ac_var in `(set) 2>&1 | sed -n '\''s/^\([a-zA-Z_][a-zA-Z0-9_]*\)=.*/\1/p'\''`; do
+ eval ac_val=\$$ac_var
+ case $ac_val in #(
+ *${as_nl}*)
+ case $ac_var in #(
+ *_cv_*) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: cache variable $ac_var contains a newline" >&5
+$as_echo "$as_me: WARNING: cache variable $ac_var contains a newline" >&2;} ;;
+ esac
+ case $ac_var in #(
+ _ | IFS | as_nl) ;; #(
+ BASH_ARGV | BASH_SOURCE) eval $ac_var= ;; #(
+ *) { eval $ac_var=; unset $ac_var;} ;;
+ esac ;;
+ esac
+ done
+ (set) 2>&1 |
+ case $as_nl`(ac_space='\'' '\''; set) 2>&1` in #(
+ *${as_nl}ac_space=\ *)
+ sed -n \
+ "s/'\''/'\''\\\\'\'''\''/g;
+ s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='\''\\2'\''/p"
+ ;; #(
+ *)
+ sed -n "/^[_$as_cr_alnum]*_cv_[_$as_cr_alnum]*=/p"
+ ;;
+ esac |
+ sort
+)
+ echo
+
+ $as_echo "## ----------------- ##
+## Output variables. ##
+## ----------------- ##"
+ echo
+ for ac_var in $ac_subst_vars
+ do
+ eval ac_val=\$$ac_var
+ case $ac_val in
+ *\'\''*) ac_val=`$as_echo "$ac_val" | sed "s/'\''/'\''\\\\\\\\'\'''\''/g"`;;
+ esac
+ $as_echo "$ac_var='\''$ac_val'\''"
+ done | sort
+ echo
+
+ if test -n "$ac_subst_files"; then
+ $as_echo "## ------------------- ##
+## File substitutions. ##
+## ------------------- ##"
+ echo
+ for ac_var in $ac_subst_files
+ do
+ eval ac_val=\$$ac_var
+ case $ac_val in
+ *\'\''*) ac_val=`$as_echo "$ac_val" | sed "s/'\''/'\''\\\\\\\\'\'''\''/g"`;;
+ esac
+ $as_echo "$ac_var='\''$ac_val'\''"
+ done | sort
+ echo
+ fi
+
+ if test -s confdefs.h; then
+ $as_echo "## ----------- ##
+## confdefs.h. ##
+## ----------- ##"
+ echo
+ cat confdefs.h
+ echo
+ fi
+ test "$ac_signal" != 0 &&
+ $as_echo "$as_me: caught signal $ac_signal"
+ $as_echo "$as_me: exit $exit_status"
+ } >&5
+ rm -f core *.core core.conftest.* &&
+ rm -f -r conftest* confdefs* conf$$* $ac_clean_files &&
+ exit $exit_status
+' 0
+for ac_signal in 1 2 13 15; do
+ trap 'ac_signal='$ac_signal'; as_fn_exit 1' $ac_signal
+done
+ac_signal=0
+
+# confdefs.h avoids OS command line length limits that DEFS can exceed.
+rm -f -r conftest* confdefs.h
+
+$as_echo "/* confdefs.h */" > confdefs.h
+
+# Predefined preprocessor variables.
+
+cat >>confdefs.h <<_ACEOF
+#define PACKAGE_NAME "$PACKAGE_NAME"
+_ACEOF
+
+cat >>confdefs.h <<_ACEOF
+#define PACKAGE_TARNAME "$PACKAGE_TARNAME"
+_ACEOF
+
+cat >>confdefs.h <<_ACEOF
+#define PACKAGE_VERSION "$PACKAGE_VERSION"
+_ACEOF
+
+cat >>confdefs.h <<_ACEOF
+#define PACKAGE_STRING "$PACKAGE_STRING"
+_ACEOF
+
+cat >>confdefs.h <<_ACEOF
+#define PACKAGE_BUGREPORT "$PACKAGE_BUGREPORT"
+_ACEOF
+
+cat >>confdefs.h <<_ACEOF
+#define PACKAGE_URL "$PACKAGE_URL"
+_ACEOF
+
+
+# Let the site file select an alternate cache file if it wants to.
+# Prefer an explicitly selected file to automatically selected ones.
+ac_site_file1=NONE
+ac_site_file2=NONE
+if test -n "$CONFIG_SITE"; then
+ # We do not want a PATH search for config.site.
+ case $CONFIG_SITE in #((
+ -*) ac_site_file1=./$CONFIG_SITE;;
+ */*) ac_site_file1=$CONFIG_SITE;;
+ *) ac_site_file1=./$CONFIG_SITE;;
+ esac
+elif test "x$prefix" != xNONE; then
+ ac_site_file1=$prefix/share/config.site
+ ac_site_file2=$prefix/etc/config.site
+else
+ ac_site_file1=$ac_default_prefix/share/config.site
+ ac_site_file2=$ac_default_prefix/etc/config.site
+fi
+for ac_site_file in "$ac_site_file1" "$ac_site_file2"
+do
+ test "x$ac_site_file" = xNONE && continue
+ if test /dev/null != "$ac_site_file" && test -r "$ac_site_file"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: loading site script $ac_site_file" >&5
+$as_echo "$as_me: loading site script $ac_site_file" >&6;}
+ sed 's/^/| /' "$ac_site_file" >&5
+ . "$ac_site_file" \
+ || { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+as_fn_error $? "failed to load site script $ac_site_file
+See \`config.log' for more details" "$LINENO" 5 ; }
+ fi
+done
+
+if test -r "$cache_file"; then
+ # Some versions of bash will fail to source /dev/null (special files
+ # actually), so we avoid doing that. DJGPP emulates it as a regular file.
+ if test /dev/null != "$cache_file" && test -f "$cache_file"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: loading cache $cache_file" >&5
+$as_echo "$as_me: loading cache $cache_file" >&6;}
+ case $cache_file in
+ [\\/]* | ?:[\\/]* ) . "$cache_file";;
+ *) . "./$cache_file";;
+ esac
+ fi
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: creating cache $cache_file" >&5
+$as_echo "$as_me: creating cache $cache_file" >&6;}
+ >$cache_file
+fi
+
+# Check that the precious variables saved in the cache have kept the same
+# value.
+ac_cache_corrupted=false
+for ac_var in $ac_precious_vars; do
+ eval ac_old_set=\$ac_cv_env_${ac_var}_set
+ eval ac_new_set=\$ac_env_${ac_var}_set
+ eval ac_old_val=\$ac_cv_env_${ac_var}_value
+ eval ac_new_val=\$ac_env_${ac_var}_value
+ case $ac_old_set,$ac_new_set in
+ set,)
+ { $as_echo "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&5
+$as_echo "$as_me: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&2;}
+ ac_cache_corrupted=: ;;
+ ,set)
+ { $as_echo "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' was not set in the previous run" >&5
+$as_echo "$as_me: error: \`$ac_var' was not set in the previous run" >&2;}
+ ac_cache_corrupted=: ;;
+ ,);;
+ *)
+ if test "x$ac_old_val" != "x$ac_new_val"; then
+ # differences in whitespace do not lead to failure.
+ ac_old_val_w=`echo x $ac_old_val`
+ ac_new_val_w=`echo x $ac_new_val`
+ if test "$ac_old_val_w" != "$ac_new_val_w"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' has changed since the previous run:" >&5
+$as_echo "$as_me: error: \`$ac_var' has changed since the previous run:" >&2;}
+ ac_cache_corrupted=:
+ else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: warning: ignoring whitespace changes in \`$ac_var' since the previous run:" >&5
+$as_echo "$as_me: warning: ignoring whitespace changes in \`$ac_var' since the previous run:" >&2;}
+ eval $ac_var=\$ac_old_val
+ fi
+ { $as_echo "$as_me:${as_lineno-$LINENO}: former value: \`$ac_old_val'" >&5
+$as_echo "$as_me: former value: \`$ac_old_val'" >&2;}
+ { $as_echo "$as_me:${as_lineno-$LINENO}: current value: \`$ac_new_val'" >&5
+$as_echo "$as_me: current value: \`$ac_new_val'" >&2;}
+ fi;;
+ esac
+ # Pass precious variables to config.status.
+ if test "$ac_new_set" = set; then
+ case $ac_new_val in
+ *\'*) ac_arg=$ac_var=`$as_echo "$ac_new_val" | sed "s/'/'\\\\\\\\''/g"` ;;
+ *) ac_arg=$ac_var=$ac_new_val ;;
+ esac
+ case " $ac_configure_args " in
+ *" '$ac_arg' "*) ;; # Avoid dups. Use of quotes ensures accuracy.
+ *) as_fn_append ac_configure_args " '$ac_arg'" ;;
+ esac
+ fi
+done
+if $ac_cache_corrupted; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+ { $as_echo "$as_me:${as_lineno-$LINENO}: error: changes in the environment can compromise the build" >&5
+$as_echo "$as_me: error: changes in the environment can compromise the build" >&2;}
+ as_fn_error $? "run \`make distclean' and/or \`rm $cache_file' and start over" "$LINENO" 5
+fi
+## -------------------- ##
+## Main body of script. ##
+## -------------------- ##
+
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+
+ac_aux_dir=
+for ac_dir in config "$srcdir"/config; do
+ if test -f "$ac_dir/install-sh"; then
+ ac_aux_dir=$ac_dir
+ ac_install_sh="$ac_aux_dir/install-sh -c"
+ break
+ elif test -f "$ac_dir/install.sh"; then
+ ac_aux_dir=$ac_dir
+ ac_install_sh="$ac_aux_dir/install.sh -c"
+ break
+ elif test -f "$ac_dir/shtool"; then
+ ac_aux_dir=$ac_dir
+ ac_install_sh="$ac_aux_dir/shtool install -c"
+ break
+ fi
+done
+if test -z "$ac_aux_dir"; then
+ as_fn_error $? "cannot find install-sh, install.sh, or shtool in config \"$srcdir\"/config" "$LINENO" 5
+fi
+
+# These three variables are undocumented and unsupported,
+# and are intended to be withdrawn in a future Autoconf release.
+# They can cause serious problems if a builder's source tree is in a directory
+# whose full name contains unusual characters.
+ac_config_guess="$SHELL $ac_aux_dir/config.guess" # Please don't use this var.
+ac_config_sub="$SHELL $ac_aux_dir/config.sub" # Please don't use this var.
+ac_configure="$SHELL $ac_aux_dir/configure" # Please don't use this var.
+
+
+ac_config_headers="$ac_config_headers config.h"
+
+am__api_version='1.11'
+
+# Find a good install program. We prefer a C program (faster),
+# so one script is as good as another. But avoid the broken or
+# incompatible versions:
+# SysV /etc/install, /usr/sbin/install
+# SunOS /usr/etc/install
+# IRIX /sbin/install
+# AIX /bin/install
+# AmigaOS /C/install, which installs bootblocks on floppy discs
+# AIX 4 /usr/bin/installbsd, which doesn't work without a -g flag
+# AFS /usr/afsws/bin/install, which mishandles nonexistent args
+# SVR4 /usr/ucb/install, which tries to use the nonexistent group "staff"
+# OS/2's system install, which has a completely different semantic
+# ./install, which can be erroneously created by make from ./install.sh.
+# Reject install programs that cannot install multiple files.
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for a BSD-compatible install" >&5
+$as_echo_n "checking for a BSD-compatible install... " >&6; }
+if test -z "$INSTALL"; then
+if test "${ac_cv_path_install+set}" = set; then :
+ $as_echo_n "(cached) " >&6
+else
+ as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ # Account for people who put trailing slashes in PATH elements.
+case $as_dir/ in #((
+ ./ | .// | /[cC]/* | \
+ /etc/* | /usr/sbin/* | /usr/etc/* | /sbin/* | /usr/afsws/bin/* | \
+ ?:[\\/]os2[\\/]install[\\/]* | ?:[\\/]OS2[\\/]INSTALL[\\/]* | \
+ /usr/ucb/* ) ;;
+ *)
+ # OSF1 and SCO ODT 3.0 have their own names for install.
+ # Don't use installbsd from OSF since it installs stuff as root
+ # by default.
+ for ac_prog in ginstall scoinst install; do
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if { test -f "$as_dir/$ac_prog$ac_exec_ext" && $as_test_x "$as_dir/$ac_prog$ac_exec_ext"; }; then
+ if test $ac_prog = install &&
+ grep dspmsg "$as_dir/$ac_prog$ac_exec_ext" >/dev/null 2>&1; then
+ # AIX install. It has an incompatible calling convention.
+ :
+ elif test $ac_prog = install &&
+ grep pwplus "$as_dir/$ac_prog$ac_exec_ext" >/dev/null 2>&1; then
+ # program-specific install script used by HP pwplus--don't use.
+ :
+ else
+ rm -rf conftest.one conftest.two conftest.dir
+ echo one > conftest.one
+ echo two > conftest.two
+ mkdir conftest.dir
+ if "$as_dir/$ac_prog$ac_exec_ext" -c conftest.one conftest.two "`pwd`/conftest.dir" &&
+ test -s conftest.one && test -s conftest.two &&
+ test -s conftest.dir/conftest.one &&
+ test -s conftest.dir/conftest.two
+ then
+ ac_cv_path_install="$as_dir/$ac_prog$ac_exec_ext -c"
+ break 3
+ fi
+ fi
+ fi
+ done
+ done
+ ;;
+esac
+
+ done
+IFS=$as_save_IFS
+
+rm -rf conftest.one conftest.two conftest.dir
+
+fi
+ if test "${ac_cv_path_install+set}" = set; then
+ INSTALL=$ac_cv_path_install
+ else
+ # As a last resort, use the slow shell script. Don't cache a
+ # value for INSTALL within a source directory, because that will
+ # break other packages using the cache if that directory is
+ # removed, or if the value is a relative name.
+ INSTALL=$ac_install_sh
+ fi
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $INSTALL" >&5
+$as_echo "$INSTALL" >&6; }
+
+# Use test -z because SunOS4 sh mishandles braces in ${var-val}.
+# It thinks the first close brace ends the variable substitution.
+test -z "$INSTALL_PROGRAM" && INSTALL_PROGRAM='${INSTALL}'
+
+test -z "$INSTALL_SCRIPT" && INSTALL_SCRIPT='${INSTALL}'
+
+test -z "$INSTALL_DATA" && INSTALL_DATA='${INSTALL} -m 644'
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether build environment is sane" >&5
+$as_echo_n "checking whether build environment is sane... " >&6; }
+# Just in case
+sleep 1
+echo timestamp > conftest.file
+# Reject unsafe characters in $srcdir or the absolute working directory
+# name. Accept space and tab only in the latter.
+am_lf='
+'
+case `pwd` in
+ *[\\\"\#\$\&\'\`$am_lf]*)
+ as_fn_error $? "unsafe absolute working directory name" "$LINENO" 5 ;;
+esac
+case $srcdir in
+ *[\\\"\#\$\&\'\`$am_lf\ \ ]*)
+ as_fn_error $? "unsafe srcdir value: \`$srcdir'" "$LINENO" 5 ;;
+esac
+
+# Do `set' in a subshell so we don't clobber the current shell's
+# arguments. Must try -L first in case configure is actually a
+# symlink; some systems play weird games with the mod time of symlinks
+# (eg FreeBSD returns the mod time of the symlink's containing
+# directory).
+if (
+ set X `ls -Lt "$srcdir/configure" conftest.file 2> /dev/null`
+ if test "$*" = "X"; then
+ # -L didn't work.
+ set X `ls -t "$srcdir/configure" conftest.file`
+ fi
+ rm -f conftest.file
+ if test "$*" != "X $srcdir/configure conftest.file" \
+ && test "$*" != "X conftest.file $srcdir/configure"; then
+
+ # If neither matched, then we have a broken ls. This can happen
+ # if, for instance, CONFIG_SHELL is bash and it inherits a
+ # broken ls alias from the environment. This has actually
+ # happened. Such a system could not be considered "sane".
+ as_fn_error $? "ls -t appears to fail. Make sure there is not a broken
+alias in your environment" "$LINENO" 5
+ fi
+
+ test "$2" = conftest.file
+ )
+then
+ # Ok.
+ :
+else
+ as_fn_error $? "newly created file is older than distributed files!
+Check your system clock" "$LINENO" 5
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+test "$program_prefix" != NONE &&
+ program_transform_name="s&^&$program_prefix&;$program_transform_name"
+# Use a double $ so make ignores it.
+test "$program_suffix" != NONE &&
+ program_transform_name="s&\$&$program_suffix&;$program_transform_name"
+# Double any \ or $.
+# By default was `s,x,x', remove it if useless.
+ac_script='s/[\\$]/&&/g;s/;s,x,x,$//'
+program_transform_name=`$as_echo "$program_transform_name" | sed "$ac_script"`
+
+# expand $ac_aux_dir to an absolute path
+am_aux_dir=`cd $ac_aux_dir && pwd`
+
+if test x"${MISSING+set}" != xset; then
+ case $am_aux_dir in
+ *\ * | *\ *)
+ MISSING="\${SHELL} \"$am_aux_dir/missing\"" ;;
+ *)
+ MISSING="\${SHELL} $am_aux_dir/missing" ;;
+ esac
+fi
+# Use eval to expand $SHELL
+if eval "$MISSING --run true"; then
+ am_missing_run="$MISSING --run "
+else
+ am_missing_run=
+ { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: \`missing' script is too old or missing" >&5
+$as_echo "$as_me: WARNING: \`missing' script is too old or missing" >&2;}
+fi
+
+if test x"${install_sh}" != xset; then
+ case $am_aux_dir in
+ *\ * | *\ *)
+ install_sh="\${SHELL} '$am_aux_dir/install-sh'" ;;
+ *)
+ install_sh="\${SHELL} $am_aux_dir/install-sh"
+ esac
+fi
+
+# Installed binaries are usually stripped using `strip' when the user
+# run `make install-strip'. However `strip' might not be the right
+# tool to use in cross-compilation environments, therefore Automake
+# will honor the `STRIP' environment variable to overrule this program.
+if test "$cross_compiling" != no; then
+ if test -n "$ac_tool_prefix"; then
+ # Extract the first word of "${ac_tool_prefix}strip", so it can be a program name with args.
+set dummy ${ac_tool_prefix}strip; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if test "${ac_cv_prog_STRIP+set}" = set; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$STRIP"; then
+ ac_cv_prog_STRIP="$STRIP" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+ ac_cv_prog_STRIP="${ac_tool_prefix}strip"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+fi
+fi
+STRIP=$ac_cv_prog_STRIP
+if test -n "$STRIP"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $STRIP" >&5
+$as_echo "$STRIP" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+fi
+if test -z "$ac_cv_prog_STRIP"; then
+ ac_ct_STRIP=$STRIP
+ # Extract the first word of "strip", so it can be a program name with args.
+set dummy strip; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if test "${ac_cv_prog_ac_ct_STRIP+set}" = set; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$ac_ct_STRIP"; then
+ ac_cv_prog_ac_ct_STRIP="$ac_ct_STRIP" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+ ac_cv_prog_ac_ct_STRIP="strip"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+fi
+fi
+ac_ct_STRIP=$ac_cv_prog_ac_ct_STRIP
+if test -n "$ac_ct_STRIP"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_STRIP" >&5
+$as_echo "$ac_ct_STRIP" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+ if test "x$ac_ct_STRIP" = x; then
+ STRIP=":"
+ else
+ case $cross_compiling:$ac_tool_warned in
+yes:)
+{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
+$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
+ac_tool_warned=yes ;;
+esac
+ STRIP=$ac_ct_STRIP
+ fi
+else
+ STRIP="$ac_cv_prog_STRIP"
+fi
+
+fi
+INSTALL_STRIP_PROGRAM="\$(install_sh) -c -s"
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for a thread-safe mkdir -p" >&5
+$as_echo_n "checking for a thread-safe mkdir -p... " >&6; }
+if test -z "$MKDIR_P"; then
+ if test "${ac_cv_path_mkdir+set}" = set; then :
+ $as_echo_n "(cached) " >&6
+else
+ as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH$PATH_SEPARATOR/opt/sfw/bin
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_prog in mkdir gmkdir; do
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ { test -f "$as_dir/$ac_prog$ac_exec_ext" && $as_test_x "$as_dir/$ac_prog$ac_exec_ext"; } || continue
+ case `"$as_dir/$ac_prog$ac_exec_ext" --version 2>&1` in #(
+ 'mkdir (GNU coreutils) '* | \
+ 'mkdir (coreutils) '* | \
+ 'mkdir (fileutils) '4.1*)
+ ac_cv_path_mkdir=$as_dir/$ac_prog$ac_exec_ext
+ break 3;;
+ esac
+ done
+ done
+ done
+IFS=$as_save_IFS
+
+fi
+
+ test -d ./--version && rmdir ./--version
+ if test "${ac_cv_path_mkdir+set}" = set; then
+ MKDIR_P="$ac_cv_path_mkdir -p"
+ else
+ # As a last resort, use the slow shell script. Don't cache a
+ # value for MKDIR_P within a source directory, because that will
+ # break other packages using the cache if that directory is
+ # removed, or if the value is a relative name.
+ MKDIR_P="$ac_install_sh -d"
+ fi
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $MKDIR_P" >&5
+$as_echo "$MKDIR_P" >&6; }
+
+mkdir_p="$MKDIR_P"
+case $mkdir_p in
+ [\\/$]* | ?:[\\/]*) ;;
+ */*) mkdir_p="\$(top_builddir)/$mkdir_p" ;;
+esac
+
+for ac_prog in gawk mawk nawk awk
+do
+ # Extract the first word of "$ac_prog", so it can be a program name with args.
+set dummy $ac_prog; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if test "${ac_cv_prog_AWK+set}" = set; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$AWK"; then
+ ac_cv_prog_AWK="$AWK" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+ ac_cv_prog_AWK="$ac_prog"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+fi
+fi
+AWK=$ac_cv_prog_AWK
+if test -n "$AWK"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $AWK" >&5
+$as_echo "$AWK" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+ test -n "$AWK" && break
+done
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether ${MAKE-make} sets \$(MAKE)" >&5
+$as_echo_n "checking whether ${MAKE-make} sets \$(MAKE)... " >&6; }
+set x ${MAKE-make}
+ac_make=`$as_echo "$2" | sed 's/+/p/g; s/[^a-zA-Z0-9_]/_/g'`
+if eval "test \"\${ac_cv_prog_make_${ac_make}_set+set}\"" = set; then :
+ $as_echo_n "(cached) " >&6
+else
+ cat >conftest.make <<\_ACEOF
+SHELL = /bin/sh
+all:
+ @echo '@@@%%%=$(MAKE)=@@@%%%'
+_ACEOF
+# GNU make sometimes prints "make[1]: Entering ...", which would confuse us.
+case `${MAKE-make} -f conftest.make 2>/dev/null` in
+ *@@@%%%=?*=@@@%%%*)
+ eval ac_cv_prog_make_${ac_make}_set=yes;;
+ *)
+ eval ac_cv_prog_make_${ac_make}_set=no;;
+esac
+rm -f conftest.make
+fi
+if eval test \$ac_cv_prog_make_${ac_make}_set = yes; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+ SET_MAKE=
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+ SET_MAKE="MAKE=${MAKE-make}"
+fi
+
+rm -rf .tst 2>/dev/null
+mkdir .tst 2>/dev/null
+if test -d .tst; then
+ am__leading_dot=.
+else
+ am__leading_dot=_
+fi
+rmdir .tst 2>/dev/null
+
+if test "`cd $srcdir && pwd`" != "`pwd`"; then
+ # Use -I$(srcdir) only when $(srcdir) != ., so that make's output
+ # is not polluted with repeated "-I."
+ am__isrc=' -I$(srcdir)'
+ # test to see if srcdir already configured
+ if test -f $srcdir/config.status; then
+ as_fn_error $? "source directory already configured; run \"make distclean\" there first" "$LINENO" 5
+ fi
+fi
+
+# test whether we have cygpath
+if test -z "$CYGPATH_W"; then
+ if (cygpath --version) >/dev/null 2>/dev/null; then
+ CYGPATH_W='cygpath -w'
+ else
+ CYGPATH_W=echo
+ fi
+fi
+
+
+# Define the identity of the package.
+ PACKAGE='yaml'
+ VERSION='0.1.4'
+
+
+cat >>confdefs.h <<_ACEOF
+#define PACKAGE "$PACKAGE"
+_ACEOF
+
+
+cat >>confdefs.h <<_ACEOF
+#define VERSION "$VERSION"
+_ACEOF
+
+# Some tools Automake needs.
+
+ACLOCAL=${ACLOCAL-"${am_missing_run}aclocal-${am__api_version}"}
+
+
+AUTOCONF=${AUTOCONF-"${am_missing_run}autoconf"}
+
+
+AUTOMAKE=${AUTOMAKE-"${am_missing_run}automake-${am__api_version}"}
+
+
+AUTOHEADER=${AUTOHEADER-"${am_missing_run}autoheader"}
+
+
+MAKEINFO=${MAKEINFO-"${am_missing_run}makeinfo"}
+
+# We need awk for the "check" target. The system "awk" is bad on
+# some platforms.
+# Always define AMTAR for backward compatibility.
+
+AMTAR=${AMTAR-"${am_missing_run}tar"}
+
+am__tar='${AMTAR} chof - "$$tardir"'; am__untar='${AMTAR} xf -'
+
+
+
+
+
+
+# Define macro variables for the package version numbers.
+
+$as_echo "#define YAML_VERSION_MAJOR 0" >>confdefs.h
+
+
+$as_echo "#define YAML_VERSION_MINOR 1" >>confdefs.h
+
+
+$as_echo "#define YAML_VERSION_PATCH 4" >>confdefs.h
+
+
+$as_echo "#define YAML_VERSION_STRING \"0.1.4\"" >>confdefs.h
+
+
+# Define substitutions for the libtool version numbers.
+YAML_LT_RELEASE=0
+YAML_LT_CURRENT=2
+YAML_LT_REVISION=2
+YAML_LT_AGE=0
+
+
+
+
+
+# Note: in order to update checks, run `autoscan` and look through "configure.scan".
+
+# Checks for programs.
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+if test -n "$ac_tool_prefix"; then
+ # Extract the first word of "${ac_tool_prefix}gcc", so it can be a program name with args.
+set dummy ${ac_tool_prefix}gcc; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if test "${ac_cv_prog_CC+set}" = set; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$CC"; then
+ ac_cv_prog_CC="$CC" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+ ac_cv_prog_CC="${ac_tool_prefix}gcc"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+fi
+fi
+CC=$ac_cv_prog_CC
+if test -n "$CC"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5
+$as_echo "$CC" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+fi
+if test -z "$ac_cv_prog_CC"; then
+ ac_ct_CC=$CC
+ # Extract the first word of "gcc", so it can be a program name with args.
+set dummy gcc; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if test "${ac_cv_prog_ac_ct_CC+set}" = set; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$ac_ct_CC"; then
+ ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+ ac_cv_prog_ac_ct_CC="gcc"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+fi
+fi
+ac_ct_CC=$ac_cv_prog_ac_ct_CC
+if test -n "$ac_ct_CC"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CC" >&5
+$as_echo "$ac_ct_CC" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+ if test "x$ac_ct_CC" = x; then
+ CC=""
+ else
+ case $cross_compiling:$ac_tool_warned in
+yes:)
+{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
+$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
+ac_tool_warned=yes ;;
+esac
+ CC=$ac_ct_CC
+ fi
+else
+ CC="$ac_cv_prog_CC"
+fi
+
+if test -z "$CC"; then
+ if test -n "$ac_tool_prefix"; then
+ # Extract the first word of "${ac_tool_prefix}cc", so it can be a program name with args.
+set dummy ${ac_tool_prefix}cc; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if test "${ac_cv_prog_CC+set}" = set; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$CC"; then
+ ac_cv_prog_CC="$CC" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+ ac_cv_prog_CC="${ac_tool_prefix}cc"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+fi
+fi
+CC=$ac_cv_prog_CC
+if test -n "$CC"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5
+$as_echo "$CC" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+ fi
+fi
+if test -z "$CC"; then
+ # Extract the first word of "cc", so it can be a program name with args.
+set dummy cc; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if test "${ac_cv_prog_CC+set}" = set; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$CC"; then
+ ac_cv_prog_CC="$CC" # Let the user override the test.
+else
+ ac_prog_rejected=no
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+ if test "$as_dir/$ac_word$ac_exec_ext" = "/usr/ucb/cc"; then
+ ac_prog_rejected=yes
+ continue
+ fi
+ ac_cv_prog_CC="cc"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+if test $ac_prog_rejected = yes; then
+ # We found a bogon in the path, so make sure we never use it.
+ set dummy $ac_cv_prog_CC
+ shift
+ if test $# != 0; then
+ # We chose a different compiler from the bogus one.
+ # However, it has the same basename, so the bogon will be chosen
+ # first if we set CC to just the basename; use the full file name.
+ shift
+ ac_cv_prog_CC="$as_dir/$ac_word${1+' '}$@"
+ fi
+fi
+fi
+fi
+CC=$ac_cv_prog_CC
+if test -n "$CC"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5
+$as_echo "$CC" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+fi
+if test -z "$CC"; then
+ if test -n "$ac_tool_prefix"; then
+ for ac_prog in cl.exe
+ do
+ # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args.
+set dummy $ac_tool_prefix$ac_prog; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if test "${ac_cv_prog_CC+set}" = set; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$CC"; then
+ ac_cv_prog_CC="$CC" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+ ac_cv_prog_CC="$ac_tool_prefix$ac_prog"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+fi
+fi
+CC=$ac_cv_prog_CC
+if test -n "$CC"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5
+$as_echo "$CC" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+ test -n "$CC" && break
+ done
+fi
+if test -z "$CC"; then
+ ac_ct_CC=$CC
+ for ac_prog in cl.exe
+do
+ # Extract the first word of "$ac_prog", so it can be a program name with args.
+set dummy $ac_prog; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if test "${ac_cv_prog_ac_ct_CC+set}" = set; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$ac_ct_CC"; then
+ ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+ ac_cv_prog_ac_ct_CC="$ac_prog"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+fi
+fi
+ac_ct_CC=$ac_cv_prog_ac_ct_CC
+if test -n "$ac_ct_CC"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CC" >&5
+$as_echo "$ac_ct_CC" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+ test -n "$ac_ct_CC" && break
+done
+
+ if test "x$ac_ct_CC" = x; then
+ CC=""
+ else
+ case $cross_compiling:$ac_tool_warned in
+yes:)
+{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
+$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
+ac_tool_warned=yes ;;
+esac
+ CC=$ac_ct_CC
+ fi
+fi
+
+fi
+
+
+test -z "$CC" && { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+as_fn_error $? "no acceptable C compiler found in \$PATH
+See \`config.log' for more details" "$LINENO" 5 ; }
+
+# Provide some information about the compiler.
+$as_echo "$as_me:${as_lineno-$LINENO}: checking for C compiler version" >&5
+set X $ac_compile
+ac_compiler=$2
+for ac_option in --version -v -V -qversion; do
+ { { ac_try="$ac_compiler $ac_option >&5"
+case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
+$as_echo "$ac_try_echo"; } >&5
+ (eval "$ac_compiler $ac_option >&5") 2>conftest.err
+ ac_status=$?
+ if test -s conftest.err; then
+ sed '10a\
+... rest of stderr output deleted ...
+ 10q' conftest.err >conftest.er1
+ cat conftest.er1 >&5
+ fi
+ rm -f conftest.er1 conftest.err
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }
+done
+
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+int
+main ()
+{
+
+ ;
+ return 0;
+}
+_ACEOF
+ac_clean_files_save=$ac_clean_files
+ac_clean_files="$ac_clean_files a.out a.out.dSYM a.exe b.out"
+# Try to create an executable without -o first, disregard a.out.
+# It will help us diagnose broken compilers, and finding out an intuition
+# of exeext.
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the C compiler works" >&5
+$as_echo_n "checking whether the C compiler works... " >&6; }
+ac_link_default=`$as_echo "$ac_link" | sed 's/ -o *conftest[^ ]*//'`
+
+# The possible output files:
+ac_files="a.out conftest.exe conftest a.exe a_out.exe b.out conftest.*"
+
+ac_rmfiles=
+for ac_file in $ac_files
+do
+ case $ac_file in
+ *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.o | *.obj ) ;;
+ * ) ac_rmfiles="$ac_rmfiles $ac_file";;
+ esac
+done
+rm -f $ac_rmfiles
+
+if { { ac_try="$ac_link_default"
+case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
+$as_echo "$ac_try_echo"; } >&5
+ (eval "$ac_link_default") 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }; then :
+ # Autoconf-2.13 could set the ac_cv_exeext variable to `no'.
+# So ignore a value of `no', otherwise this would lead to `EXEEXT = no'
+# in a Makefile. We should not override ac_cv_exeext if it was cached,
+# so that the user can short-circuit this test for compilers unknown to
+# Autoconf.
+for ac_file in $ac_files ''
+do
+ test -f "$ac_file" || continue
+ case $ac_file in
+ *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.o | *.obj )
+ ;;
+ [ab].out )
+ # We found the default executable, but exeext='' is most
+ # certainly right.
+ break;;
+ *.* )
+ if test "${ac_cv_exeext+set}" = set && test "$ac_cv_exeext" != no;
+ then :; else
+ ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'`
+ fi
+ # We set ac_cv_exeext here because the later test for it is not
+ # safe: cross compilers may not add the suffix if given an `-o'
+ # argument, so we may need to know it at that point already.
+ # Even if this section looks crufty: it has the advantage of
+ # actually working.
+ break;;
+ * )
+ break;;
+ esac
+done
+test "$ac_cv_exeext" = no && ac_cv_exeext=
+
+else
+ ac_file=''
+fi
+if test -z "$ac_file"; then :
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+$as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+{ { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+as_fn_error 77 "C compiler cannot create executables
+See \`config.log' for more details" "$LINENO" 5 ; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for C compiler default output file name" >&5
+$as_echo_n "checking for C compiler default output file name... " >&6; }
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_file" >&5
+$as_echo "$ac_file" >&6; }
+ac_exeext=$ac_cv_exeext
+
+rm -f -r a.out a.out.dSYM a.exe conftest$ac_cv_exeext b.out
+ac_clean_files=$ac_clean_files_save
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for suffix of executables" >&5
+$as_echo_n "checking for suffix of executables... " >&6; }
+if { { ac_try="$ac_link"
+case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
+$as_echo "$ac_try_echo"; } >&5
+ (eval "$ac_link") 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }; then :
+ # If both `conftest.exe' and `conftest' are `present' (well, observable)
+# catch `conftest.exe'. For instance with Cygwin, `ls conftest' will
+# work properly (i.e., refer to `conftest.exe'), while it won't with
+# `rm'.
+for ac_file in conftest.exe conftest conftest.*; do
+ test -f "$ac_file" || continue
+ case $ac_file in
+ *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.o | *.obj ) ;;
+ *.* ) ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'`
+ break;;
+ * ) break;;
+ esac
+done
+else
+ { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+as_fn_error $? "cannot compute suffix of executables: cannot compile and link
+See \`config.log' for more details" "$LINENO" 5 ; }
+fi
+rm -f conftest conftest$ac_cv_exeext
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_exeext" >&5
+$as_echo "$ac_cv_exeext" >&6; }
+
+rm -f conftest.$ac_ext
+EXEEXT=$ac_cv_exeext
+ac_exeext=$EXEEXT
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#include <stdio.h>
+int
+main ()
+{
+FILE *f = fopen ("conftest.out", "w");
+ return ferror (f) || fclose (f) != 0;
+
+ ;
+ return 0;
+}
+_ACEOF
+ac_clean_files="$ac_clean_files conftest.out"
+# Check that the compiler produces executables we can run. If not, either
+# the compiler is broken, or we cross compile.
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether we are cross compiling" >&5
+$as_echo_n "checking whether we are cross compiling... " >&6; }
+if test "$cross_compiling" != yes; then
+ { { ac_try="$ac_link"
+case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
+$as_echo "$ac_try_echo"; } >&5
+ (eval "$ac_link") 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }
+ if { ac_try='./conftest$ac_cv_exeext'
+ { { case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
+$as_echo "$ac_try_echo"; } >&5
+ (eval "$ac_try") 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }; }; then
+ cross_compiling=no
+ else
+ if test "$cross_compiling" = maybe; then
+ cross_compiling=yes
+ else
+ { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+as_fn_error $? "cannot run C compiled programs.
+If you meant to cross compile, use \`--host'.
+See \`config.log' for more details" "$LINENO" 5 ; }
+ fi
+ fi
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $cross_compiling" >&5
+$as_echo "$cross_compiling" >&6; }
+
+rm -f conftest.$ac_ext conftest$ac_cv_exeext conftest.out
+ac_clean_files=$ac_clean_files_save
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for suffix of object files" >&5
+$as_echo_n "checking for suffix of object files... " >&6; }
+if test "${ac_cv_objext+set}" = set; then :
+ $as_echo_n "(cached) " >&6
+else
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+int
+main ()
+{
+
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.o conftest.obj
+if { { ac_try="$ac_compile"
+case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
+$as_echo "$ac_try_echo"; } >&5
+ (eval "$ac_compile") 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }; then :
+ for ac_file in conftest.o conftest.obj conftest.*; do
+ test -f "$ac_file" || continue;
+ case $ac_file in
+ *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM ) ;;
+ *) ac_cv_objext=`expr "$ac_file" : '.*\.\(.*\)'`
+ break;;
+ esac
+done
+else
+ $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+{ { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+as_fn_error $? "cannot compute suffix of object files: cannot compile
+See \`config.log' for more details" "$LINENO" 5 ; }
+fi
+rm -f conftest.$ac_cv_objext conftest.$ac_ext
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_objext" >&5
+$as_echo "$ac_cv_objext" >&6; }
+OBJEXT=$ac_cv_objext
+ac_objext=$OBJEXT
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether we are using the GNU C compiler" >&5
+$as_echo_n "checking whether we are using the GNU C compiler... " >&6; }
+if test "${ac_cv_c_compiler_gnu+set}" = set; then :
+ $as_echo_n "(cached) " >&6
+else
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+int
+main ()
+{
+#ifndef __GNUC__
+ choke me
+#endif
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+ ac_compiler_gnu=yes
+else
+ ac_compiler_gnu=no
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+ac_cv_c_compiler_gnu=$ac_compiler_gnu
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_c_compiler_gnu" >&5
+$as_echo "$ac_cv_c_compiler_gnu" >&6; }
+if test $ac_compiler_gnu = yes; then
+ GCC=yes
+else
+ GCC=
+fi
+ac_test_CFLAGS=${CFLAGS+set}
+ac_save_CFLAGS=$CFLAGS
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CC accepts -g" >&5
+$as_echo_n "checking whether $CC accepts -g... " >&6; }
+if test "${ac_cv_prog_cc_g+set}" = set; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_save_c_werror_flag=$ac_c_werror_flag
+ ac_c_werror_flag=yes
+ ac_cv_prog_cc_g=no
+ CFLAGS="-g"
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+int
+main ()
+{
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+ ac_cv_prog_cc_g=yes
+else
+ CFLAGS=""
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+int
+main ()
+{
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+
+else
+ ac_c_werror_flag=$ac_save_c_werror_flag
+ CFLAGS="-g"
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+int
+main ()
+{
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+ ac_cv_prog_cc_g=yes
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+ ac_c_werror_flag=$ac_save_c_werror_flag
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_g" >&5
+$as_echo "$ac_cv_prog_cc_g" >&6; }
+if test "$ac_test_CFLAGS" = set; then
+ CFLAGS=$ac_save_CFLAGS
+elif test $ac_cv_prog_cc_g = yes; then
+ if test "$GCC" = yes; then
+ CFLAGS="-g -O2"
+ else
+ CFLAGS="-g"
+ fi
+else
+ if test "$GCC" = yes; then
+ CFLAGS="-O2"
+ else
+ CFLAGS=
+ fi
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $CC option to accept ISO C89" >&5
+$as_echo_n "checking for $CC option to accept ISO C89... " >&6; }
+if test "${ac_cv_prog_cc_c89+set}" = set; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_cv_prog_cc_c89=no
+ac_save_CC=$CC
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#include <stdarg.h>
+#include <stdio.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+/* Most of the following tests are stolen from RCS 5.7's src/conf.sh. */
+struct buf { int x; };
+FILE * (*rcsopen) (struct buf *, struct stat *, int);
+static char *e (p, i)
+ char **p;
+ int i;
+{
+ return p[i];
+}
+static char *f (char * (*g) (char **, int), char **p, ...)
+{
+ char *s;
+ va_list v;
+ va_start (v,p);
+ s = g (p, va_arg (v,int));
+ va_end (v);
+ return s;
+}
+
+/* OSF 4.0 Compaq cc is some sort of almost-ANSI by default. It has
+ function prototypes and stuff, but not '\xHH' hex character constants.
+ These don't provoke an error unfortunately, instead are silently treated
+ as 'x'. The following induces an error, until -std is added to get
+ proper ANSI mode. Curiously '\x00'!='x' always comes out true, for an
+ array size at least. It's necessary to write '\x00'==0 to get something
+ that's true only with -std. */
+int osf4_cc_array ['\x00' == 0 ? 1 : -1];
+
+/* IBM C 6 for AIX is almost-ANSI by default, but it replaces macro parameters
+ inside strings and character constants. */
+#define FOO(x) 'x'
+int xlc6_cc_array[FOO(a) == 'x' ? 1 : -1];
+
+int test (int i, double x);
+struct s1 {int (*f) (int a);};
+struct s2 {int (*f) (double a);};
+int pairnames (int, char **, FILE *(*)(struct buf *, struct stat *, int), int, int);
+int argc;
+char **argv;
+int
+main ()
+{
+return f (e, argv, 0) != argv[0] || f (e, argv, 1) != argv[1];
+ ;
+ return 0;
+}
+_ACEOF
+for ac_arg in '' -qlanglvl=extc89 -qlanglvl=ansi -std \
+ -Ae "-Aa -D_HPUX_SOURCE" "-Xc -D__EXTENSIONS__"
+do
+ CC="$ac_save_CC $ac_arg"
+ if ac_fn_c_try_compile "$LINENO"; then :
+ ac_cv_prog_cc_c89=$ac_arg
+fi
+rm -f core conftest.err conftest.$ac_objext
+ test "x$ac_cv_prog_cc_c89" != "xno" && break
+done
+rm -f conftest.$ac_ext
+CC=$ac_save_CC
+
+fi
+# AC_CACHE_VAL
+case "x$ac_cv_prog_cc_c89" in
+ x)
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: none needed" >&5
+$as_echo "none needed" >&6; } ;;
+ xno)
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: unsupported" >&5
+$as_echo "unsupported" >&6; } ;;
+ *)
+ CC="$CC $ac_cv_prog_cc_c89"
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_c89" >&5
+$as_echo "$ac_cv_prog_cc_c89" >&6; } ;;
+esac
+if test "x$ac_cv_prog_cc_c89" != xno; then :
+
+fi
+
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+DEPDIR="${am__leading_dot}deps"
+
+ac_config_commands="$ac_config_commands depfiles"
+
+
+am_make=${MAKE-make}
+cat > confinc << 'END'
+am__doit:
+ @echo this is the am__doit target
+.PHONY: am__doit
+END
+# If we don't find an include directive, just comment out the code.
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for style of include used by $am_make" >&5
+$as_echo_n "checking for style of include used by $am_make... " >&6; }
+am__include="#"
+am__quote=
+_am_result=none
+# First try GNU make style include.
+echo "include confinc" > confmf
+# Ignore all kinds of additional output from `make'.
+case `$am_make -s -f confmf 2> /dev/null` in #(
+*the\ am__doit\ target*)
+ am__include=include
+ am__quote=
+ _am_result=GNU
+ ;;
+esac
+# Now try BSD make style include.
+if test "$am__include" = "#"; then
+ echo '.include "confinc"' > confmf
+ case `$am_make -s -f confmf 2> /dev/null` in #(
+ *the\ am__doit\ target*)
+ am__include=.include
+ am__quote="\""
+ _am_result=BSD
+ ;;
+ esac
+fi
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $_am_result" >&5
+$as_echo "$_am_result" >&6; }
+rm -f confinc confmf
+
+# Check whether --enable-dependency-tracking was given.
+if test "${enable_dependency_tracking+set}" = set; then :
+ enableval=$enable_dependency_tracking;
+fi
+
+if test "x$enable_dependency_tracking" != xno; then
+ am_depcomp="$ac_aux_dir/depcomp"
+ AMDEPBACKSLASH='\'
+fi
+ if test "x$enable_dependency_tracking" != xno; then
+ AMDEP_TRUE=
+ AMDEP_FALSE='#'
+else
+ AMDEP_TRUE='#'
+ AMDEP_FALSE=
+fi
+
+
+
+depcc="$CC" am_compiler_list=
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking dependency style of $depcc" >&5
+$as_echo_n "checking dependency style of $depcc... " >&6; }
+if test "${am_cv_CC_dependencies_compiler_type+set}" = set; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -z "$AMDEP_TRUE" && test -f "$am_depcomp"; then
+ # We make a subdir and do the tests there. Otherwise we can end up
+ # making bogus files that we don't know about and never remove. For
+ # instance it was reported that on HP-UX the gcc test will end up
+ # making a dummy file named `D' -- because `-MD' means `put the output
+ # in D'.
+ mkdir conftest.dir
+ # Copy depcomp to subdir because otherwise we won't find it if we're
+ # using a relative directory.
+ cp "$am_depcomp" conftest.dir
+ cd conftest.dir
+ # We will build objects and dependencies in a subdirectory because
+ # it helps to detect inapplicable dependency modes. For instance
+ # both Tru64's cc and ICC support -MD to output dependencies as a
+ # side effect of compilation, but ICC will put the dependencies in
+ # the current directory while Tru64 will put them in the object
+ # directory.
+ mkdir sub
+
+ am_cv_CC_dependencies_compiler_type=none
+ if test "$am_compiler_list" = ""; then
+ am_compiler_list=`sed -n 's/^#*\([a-zA-Z0-9]*\))$/\1/p' < ./depcomp`
+ fi
+ am__universal=false
+ case " $depcc " in #(
+ *\ -arch\ *\ -arch\ *) am__universal=true ;;
+ esac
+
+ for depmode in $am_compiler_list; do
+ # Setup a source with many dependencies, because some compilers
+ # like to wrap large dependency lists on column 80 (with \), and
+ # we should not choose a depcomp mode which is confused by this.
+ #
+ # We need to recreate these files for each test, as the compiler may
+ # overwrite some of them when testing with obscure command lines.
+ # This happens at least with the AIX C compiler.
+ : > sub/conftest.c
+ for i in 1 2 3 4 5 6; do
+ echo '#include "conftst'$i'.h"' >> sub/conftest.c
+ # Using `: > sub/conftst$i.h' creates only sub/conftst1.h with
+ # Solaris 8's {/usr,}/bin/sh.
+ touch sub/conftst$i.h
+ done
+ echo "${am__include} ${am__quote}sub/conftest.Po${am__quote}" > confmf
+
+ # We check with `-c' and `-o' for the sake of the "dashmstdout"
+ # mode. It turns out that the SunPro C++ compiler does not properly
+ # handle `-M -o', and we need to detect this. Also, some Intel
+ # versions had trouble with output in subdirs
+ am__obj=sub/conftest.${OBJEXT-o}
+ am__minus_obj="-o $am__obj"
+ case $depmode in
+ gcc)
+ # This depmode causes a compiler race in universal mode.
+ test "$am__universal" = false || continue
+ ;;
+ nosideeffect)
+ # after this tag, mechanisms are not by side-effect, so they'll
+ # only be used when explicitly requested
+ if test "x$enable_dependency_tracking" = xyes; then
+ continue
+ else
+ break
+ fi
+ ;;
+ msvisualcpp | msvcmsys)
+ # This compiler won't grok `-c -o', but also, the minuso test has
+ # not run yet. These depmodes are late enough in the game, and
+ # so weak that their functioning should not be impacted.
+ am__obj=conftest.${OBJEXT-o}
+ am__minus_obj=
+ ;;
+ none) break ;;
+ esac
+ if depmode=$depmode \
+ source=sub/conftest.c object=$am__obj \
+ depfile=sub/conftest.Po tmpdepfile=sub/conftest.TPo \
+ $SHELL ./depcomp $depcc -c $am__minus_obj sub/conftest.c \
+ >/dev/null 2>conftest.err &&
+ grep sub/conftst1.h sub/conftest.Po > /dev/null 2>&1 &&
+ grep sub/conftst6.h sub/conftest.Po > /dev/null 2>&1 &&
+ grep $am__obj sub/conftest.Po > /dev/null 2>&1 &&
+ ${MAKE-make} -s -f confmf > /dev/null 2>&1; then
+ # icc doesn't choke on unknown options, it will just issue warnings
+ # or remarks (even with -Werror). So we grep stderr for any message
+ # that says an option was ignored or not supported.
+ # When given -MP, icc 7.0 and 7.1 complain thusly:
+ # icc: Command line warning: ignoring option '-M'; no argument required
+ # The diagnosis changed in icc 8.0:
+ # icc: Command line remark: option '-MP' not supported
+ if (grep 'ignoring option' conftest.err ||
+ grep 'not supported' conftest.err) >/dev/null 2>&1; then :; else
+ am_cv_CC_dependencies_compiler_type=$depmode
+ break
+ fi
+ fi
+ done
+
+ cd ..
+ rm -rf conftest.dir
+else
+ am_cv_CC_dependencies_compiler_type=none
+fi
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $am_cv_CC_dependencies_compiler_type" >&5
+$as_echo "$am_cv_CC_dependencies_compiler_type" >&6; }
+CCDEPMODE=depmode=$am_cv_CC_dependencies_compiler_type
+
+ if
+ test "x$enable_dependency_tracking" != xno \
+ && test "$am_cv_CC_dependencies_compiler_type" = gcc3; then
+ am__fastdepCC_TRUE=
+ am__fastdepCC_FALSE='#'
+else
+ am__fastdepCC_TRUE='#'
+ am__fastdepCC_FALSE=
+fi
+
+
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking how to run the C preprocessor" >&5
+$as_echo_n "checking how to run the C preprocessor... " >&6; }
+# On Suns, sometimes $CPP names a directory.
+if test -n "$CPP" && test -d "$CPP"; then
+ CPP=
+fi
+if test -z "$CPP"; then
+ if test "${ac_cv_prog_CPP+set}" = set; then :
+ $as_echo_n "(cached) " >&6
+else
+ # Double quotes because CPP needs to be expanded
+ for CPP in "$CC -E" "$CC -E -traditional-cpp" "/lib/cpp"
+ do
+ ac_preproc_ok=false
+for ac_c_preproc_warn_flag in '' yes
+do
+ # Use a header file that comes with gcc, so configuring glibc
+ # with a fresh cross-compiler works.
+ # Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
+ # <limits.h> exists even on freestanding compilers.
+ # On the NeXT, cc -E runs the code through the compiler's parser,
+ # not just through cpp. "Syntax error" is here to catch this case.
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#ifdef __STDC__
+# include <limits.h>
+#else
+# include <assert.h>
+#endif
+ Syntax error
+_ACEOF
+if ac_fn_c_try_cpp "$LINENO"; then :
+
+else
+ # Broken: fails on valid input.
+continue
+fi
+rm -f conftest.err conftest.i conftest.$ac_ext
+
+ # OK, works on sane cases. Now check whether nonexistent headers
+ # can be detected and how.
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#include <ac_nonexistent.h>
+_ACEOF
+if ac_fn_c_try_cpp "$LINENO"; then :
+ # Broken: success on invalid input.
+continue
+else
+ # Passes both tests.
+ac_preproc_ok=:
+break
+fi
+rm -f conftest.err conftest.i conftest.$ac_ext
+
+done
+# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped.
+rm -f conftest.i conftest.err conftest.$ac_ext
+if $ac_preproc_ok; then :
+ break
+fi
+
+ done
+ ac_cv_prog_CPP=$CPP
+
+fi
+ CPP=$ac_cv_prog_CPP
+else
+ ac_cv_prog_CPP=$CPP
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $CPP" >&5
+$as_echo "$CPP" >&6; }
+ac_preproc_ok=false
+for ac_c_preproc_warn_flag in '' yes
+do
+ # Use a header file that comes with gcc, so configuring glibc
+ # with a fresh cross-compiler works.
+ # Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
+ # <limits.h> exists even on freestanding compilers.
+ # On the NeXT, cc -E runs the code through the compiler's parser,
+ # not just through cpp. "Syntax error" is here to catch this case.
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#ifdef __STDC__
+# include <limits.h>
+#else
+# include <assert.h>
+#endif
+ Syntax error
+_ACEOF
+if ac_fn_c_try_cpp "$LINENO"; then :
+
+else
+ # Broken: fails on valid input.
+continue
+fi
+rm -f conftest.err conftest.i conftest.$ac_ext
+
+ # OK, works on sane cases. Now check whether nonexistent headers
+ # can be detected and how.
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#include <ac_nonexistent.h>
+_ACEOF
+if ac_fn_c_try_cpp "$LINENO"; then :
+ # Broken: success on invalid input.
+continue
+else
+ # Passes both tests.
+ac_preproc_ok=:
+break
+fi
+rm -f conftest.err conftest.i conftest.$ac_ext
+
+done
+# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped.
+rm -f conftest.i conftest.err conftest.$ac_ext
+if $ac_preproc_ok; then :
+
+else
+ { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+as_fn_error $? "C preprocessor \"$CPP\" fails sanity check
+See \`config.log' for more details" "$LINENO" 5 ; }
+fi
+
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether ln -s works" >&5
+$as_echo_n "checking whether ln -s works... " >&6; }
+LN_S=$as_ln_s
+if test "$LN_S" = "ln -s"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no, using $LN_S" >&5
+$as_echo "no, using $LN_S" >&6; }
+fi
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether ${MAKE-make} sets \$(MAKE)" >&5
+$as_echo_n "checking whether ${MAKE-make} sets \$(MAKE)... " >&6; }
+set x ${MAKE-make}
+ac_make=`$as_echo "$2" | sed 's/+/p/g; s/[^a-zA-Z0-9_]/_/g'`
+if eval "test \"\${ac_cv_prog_make_${ac_make}_set+set}\"" = set; then :
+ $as_echo_n "(cached) " >&6
+else
+ cat >conftest.make <<\_ACEOF
+SHELL = /bin/sh
+all:
+ @echo '@@@%%%=$(MAKE)=@@@%%%'
+_ACEOF
+# GNU make sometimes prints "make[1]: Entering ...", which would confuse us.
+case `${MAKE-make} -f conftest.make 2>/dev/null` in
+ *@@@%%%=?*=@@@%%%*)
+ eval ac_cv_prog_make_${ac_make}_set=yes;;
+ *)
+ eval ac_cv_prog_make_${ac_make}_set=no;;
+esac
+rm -f conftest.make
+fi
+if eval test \$ac_cv_prog_make_${ac_make}_set = yes; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+ SET_MAKE=
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+ SET_MAKE="MAKE=${MAKE-make}"
+fi
+
+case `pwd` in
+ *\ * | *\ *)
+ { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: Libtool does not cope well with whitespace in \`pwd\`" >&5
+$as_echo "$as_me: WARNING: Libtool does not cope well with whitespace in \`pwd\`" >&2;} ;;
+esac
+
+
+
+macro_version='2.2.6b'
+macro_revision='1.3017'
+
+
+
+
+
+
+
+
+
+
+
+
+
+ltmain="$ac_aux_dir/ltmain.sh"
+
+# Make sure we can run config.sub.
+$SHELL "$ac_aux_dir/config.sub" sun4 >/dev/null 2>&1 ||
+ as_fn_error $? "cannot run $SHELL $ac_aux_dir/config.sub" "$LINENO" 5
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking build system type" >&5
+$as_echo_n "checking build system type... " >&6; }
+if test "${ac_cv_build+set}" = set; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_build_alias=$build_alias
+test "x$ac_build_alias" = x &&
+ ac_build_alias=`$SHELL "$ac_aux_dir/config.guess"`
+test "x$ac_build_alias" = x &&
+ as_fn_error $? "cannot guess build type; you must specify one" "$LINENO" 5
+ac_cv_build=`$SHELL "$ac_aux_dir/config.sub" $ac_build_alias` ||
+ as_fn_error $? "$SHELL $ac_aux_dir/config.sub $ac_build_alias failed" "$LINENO" 5
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_build" >&5
+$as_echo "$ac_cv_build" >&6; }
+case $ac_cv_build in
+*-*-*) ;;
+*) as_fn_error $? "invalid value of canonical build" "$LINENO" 5 ;;
+esac
+build=$ac_cv_build
+ac_save_IFS=$IFS; IFS='-'
+set x $ac_cv_build
+shift
+build_cpu=$1
+build_vendor=$2
+shift; shift
+# Remember, the first character of IFS is used to create $*,
+# except with old shells:
+build_os=$*
+IFS=$ac_save_IFS
+case $build_os in *\ *) build_os=`echo "$build_os" | sed 's/ /-/g'`;; esac
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking host system type" >&5
+$as_echo_n "checking host system type... " >&6; }
+if test "${ac_cv_host+set}" = set; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test "x$host_alias" = x; then
+ ac_cv_host=$ac_cv_build
+else
+ ac_cv_host=`$SHELL "$ac_aux_dir/config.sub" $host_alias` ||
+ as_fn_error $? "$SHELL $ac_aux_dir/config.sub $host_alias failed" "$LINENO" 5
+fi
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_host" >&5
+$as_echo "$ac_cv_host" >&6; }
+case $ac_cv_host in
+*-*-*) ;;
+*) as_fn_error $? "invalid value of canonical host" "$LINENO" 5 ;;
+esac
+host=$ac_cv_host
+ac_save_IFS=$IFS; IFS='-'
+set x $ac_cv_host
+shift
+host_cpu=$1
+host_vendor=$2
+shift; shift
+# Remember, the first character of IFS is used to create $*,
+# except with old shells:
+host_os=$*
+IFS=$ac_save_IFS
+case $host_os in *\ *) host_os=`echo "$host_os" | sed 's/ /-/g'`;; esac
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for a sed that does not truncate output" >&5
+$as_echo_n "checking for a sed that does not truncate output... " >&6; }
+if test "${ac_cv_path_SED+set}" = set; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_script=s/aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa/bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb/
+ for ac_i in 1 2 3 4 5 6 7; do
+ ac_script="$ac_script$as_nl$ac_script"
+ done
+ echo "$ac_script" 2>/dev/null | sed 99q >conftest.sed
+ { ac_script=; unset ac_script;}
+ if test -z "$SED"; then
+ ac_path_SED_found=false
+ # Loop through the user's path and test for each of PROGNAME-LIST
+ as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_prog in sed gsed; do
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ ac_path_SED="$as_dir/$ac_prog$ac_exec_ext"
+ { test -f "$ac_path_SED" && $as_test_x "$ac_path_SED"; } || continue
+# Check for GNU ac_path_SED and select it if it is found.
+ # Check for GNU $ac_path_SED
+case `"$ac_path_SED" --version 2>&1` in
+*GNU*)
+ ac_cv_path_SED="$ac_path_SED" ac_path_SED_found=:;;
+*)
+ ac_count=0
+ $as_echo_n 0123456789 >"conftest.in"
+ while :
+ do
+ cat "conftest.in" "conftest.in" >"conftest.tmp"
+ mv "conftest.tmp" "conftest.in"
+ cp "conftest.in" "conftest.nl"
+ $as_echo '' >> "conftest.nl"
+ "$ac_path_SED" -f conftest.sed < "conftest.nl" >"conftest.out" 2>/dev/null || break
+ diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break
+ as_fn_arith $ac_count + 1 && ac_count=$as_val
+ if test $ac_count -gt ${ac_path_SED_max-0}; then
+ # Best one so far, save it but keep looking for a better one
+ ac_cv_path_SED="$ac_path_SED"
+ ac_path_SED_max=$ac_count
+ fi
+ # 10*(2^10) chars as input seems more than enough
+ test $ac_count -gt 10 && break
+ done
+ rm -f conftest.in conftest.tmp conftest.nl conftest.out;;
+esac
+
+ $ac_path_SED_found && break 3
+ done
+ done
+ done
+IFS=$as_save_IFS
+ if test -z "$ac_cv_path_SED"; then
+ as_fn_error $? "no acceptable sed could be found in \$PATH" "$LINENO" 5
+ fi
+else
+ ac_cv_path_SED=$SED
+fi
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_SED" >&5
+$as_echo "$ac_cv_path_SED" >&6; }
+ SED="$ac_cv_path_SED"
+ rm -f conftest.sed
+
+test -z "$SED" && SED=sed
+Xsed="$SED -e 1s/^X//"
+
+
+
+
+
+
+
+
+
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for grep that handles long lines and -e" >&5
+$as_echo_n "checking for grep that handles long lines and -e... " >&6; }
+if test "${ac_cv_path_GREP+set}" = set; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -z "$GREP"; then
+ ac_path_GREP_found=false
+ # Loop through the user's path and test for each of PROGNAME-LIST
+ as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH$PATH_SEPARATOR/usr/xpg4/bin
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_prog in grep ggrep; do
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ ac_path_GREP="$as_dir/$ac_prog$ac_exec_ext"
+ { test -f "$ac_path_GREP" && $as_test_x "$ac_path_GREP"; } || continue
+# Check for GNU ac_path_GREP and select it if it is found.
+ # Check for GNU $ac_path_GREP
+case `"$ac_path_GREP" --version 2>&1` in
+*GNU*)
+ ac_cv_path_GREP="$ac_path_GREP" ac_path_GREP_found=:;;
+*)
+ ac_count=0
+ $as_echo_n 0123456789 >"conftest.in"
+ while :
+ do
+ cat "conftest.in" "conftest.in" >"conftest.tmp"
+ mv "conftest.tmp" "conftest.in"
+ cp "conftest.in" "conftest.nl"
+ $as_echo 'GREP' >> "conftest.nl"
+ "$ac_path_GREP" -e 'GREP$' -e '-(cannot match)-' < "conftest.nl" >"conftest.out" 2>/dev/null || break
+ diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break
+ as_fn_arith $ac_count + 1 && ac_count=$as_val
+ if test $ac_count -gt ${ac_path_GREP_max-0}; then
+ # Best one so far, save it but keep looking for a better one
+ ac_cv_path_GREP="$ac_path_GREP"
+ ac_path_GREP_max=$ac_count
+ fi
+ # 10*(2^10) chars as input seems more than enough
+ test $ac_count -gt 10 && break
+ done
+ rm -f conftest.in conftest.tmp conftest.nl conftest.out;;
+esac
+
+ $ac_path_GREP_found && break 3
+ done
+ done
+ done
+IFS=$as_save_IFS
+ if test -z "$ac_cv_path_GREP"; then
+ as_fn_error $? "no acceptable grep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" "$LINENO" 5
+ fi
+else
+ ac_cv_path_GREP=$GREP
+fi
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_GREP" >&5
+$as_echo "$ac_cv_path_GREP" >&6; }
+ GREP="$ac_cv_path_GREP"
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for egrep" >&5
+$as_echo_n "checking for egrep... " >&6; }
+if test "${ac_cv_path_EGREP+set}" = set; then :
+ $as_echo_n "(cached) " >&6
+else
+ if echo a | $GREP -E '(a|b)' >/dev/null 2>&1
+ then ac_cv_path_EGREP="$GREP -E"
+ else
+ if test -z "$EGREP"; then
+ ac_path_EGREP_found=false
+ # Loop through the user's path and test for each of PROGNAME-LIST
+ as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH$PATH_SEPARATOR/usr/xpg4/bin
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_prog in egrep; do
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ ac_path_EGREP="$as_dir/$ac_prog$ac_exec_ext"
+ { test -f "$ac_path_EGREP" && $as_test_x "$ac_path_EGREP"; } || continue
+# Check for GNU ac_path_EGREP and select it if it is found.
+ # Check for GNU $ac_path_EGREP
+case `"$ac_path_EGREP" --version 2>&1` in
+*GNU*)
+ ac_cv_path_EGREP="$ac_path_EGREP" ac_path_EGREP_found=:;;
+*)
+ ac_count=0
+ $as_echo_n 0123456789 >"conftest.in"
+ while :
+ do
+ cat "conftest.in" "conftest.in" >"conftest.tmp"
+ mv "conftest.tmp" "conftest.in"
+ cp "conftest.in" "conftest.nl"
+ $as_echo 'EGREP' >> "conftest.nl"
+ "$ac_path_EGREP" 'EGREP$' < "conftest.nl" >"conftest.out" 2>/dev/null || break
+ diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break
+ as_fn_arith $ac_count + 1 && ac_count=$as_val
+ if test $ac_count -gt ${ac_path_EGREP_max-0}; then
+ # Best one so far, save it but keep looking for a better one
+ ac_cv_path_EGREP="$ac_path_EGREP"
+ ac_path_EGREP_max=$ac_count
+ fi
+ # 10*(2^10) chars as input seems more than enough
+ test $ac_count -gt 10 && break
+ done
+ rm -f conftest.in conftest.tmp conftest.nl conftest.out;;
+esac
+
+ $ac_path_EGREP_found && break 3
+ done
+ done
+ done
+IFS=$as_save_IFS
+ if test -z "$ac_cv_path_EGREP"; then
+ as_fn_error $? "no acceptable egrep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" "$LINENO" 5
+ fi
+else
+ ac_cv_path_EGREP=$EGREP
+fi
+
+ fi
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_EGREP" >&5
+$as_echo "$ac_cv_path_EGREP" >&6; }
+ EGREP="$ac_cv_path_EGREP"
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for fgrep" >&5
+$as_echo_n "checking for fgrep... " >&6; }
+if test "${ac_cv_path_FGREP+set}" = set; then :
+ $as_echo_n "(cached) " >&6
+else
+ if echo 'ab*c' | $GREP -F 'ab*c' >/dev/null 2>&1
+ then ac_cv_path_FGREP="$GREP -F"
+ else
+ if test -z "$FGREP"; then
+ ac_path_FGREP_found=false
+ # Loop through the user's path and test for each of PROGNAME-LIST
+ as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH$PATH_SEPARATOR/usr/xpg4/bin
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_prog in fgrep; do
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ ac_path_FGREP="$as_dir/$ac_prog$ac_exec_ext"
+ { test -f "$ac_path_FGREP" && $as_test_x "$ac_path_FGREP"; } || continue
+# Check for GNU ac_path_FGREP and select it if it is found.
+ # Check for GNU $ac_path_FGREP
+case `"$ac_path_FGREP" --version 2>&1` in
+*GNU*)
+ ac_cv_path_FGREP="$ac_path_FGREP" ac_path_FGREP_found=:;;
+*)
+ ac_count=0
+ $as_echo_n 0123456789 >"conftest.in"
+ while :
+ do
+ cat "conftest.in" "conftest.in" >"conftest.tmp"
+ mv "conftest.tmp" "conftest.in"
+ cp "conftest.in" "conftest.nl"
+ $as_echo 'FGREP' >> "conftest.nl"
+ "$ac_path_FGREP" FGREP < "conftest.nl" >"conftest.out" 2>/dev/null || break
+ diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break
+ as_fn_arith $ac_count + 1 && ac_count=$as_val
+ if test $ac_count -gt ${ac_path_FGREP_max-0}; then
+ # Best one so far, save it but keep looking for a better one
+ ac_cv_path_FGREP="$ac_path_FGREP"
+ ac_path_FGREP_max=$ac_count
+ fi
+ # 10*(2^10) chars as input seems more than enough
+ test $ac_count -gt 10 && break
+ done
+ rm -f conftest.in conftest.tmp conftest.nl conftest.out;;
+esac
+
+ $ac_path_FGREP_found && break 3
+ done
+ done
+ done
+IFS=$as_save_IFS
+ if test -z "$ac_cv_path_FGREP"; then
+ as_fn_error $? "no acceptable fgrep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" "$LINENO" 5
+ fi
+else
+ ac_cv_path_FGREP=$FGREP
+fi
+
+ fi
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_FGREP" >&5
+$as_echo "$ac_cv_path_FGREP" >&6; }
+ FGREP="$ac_cv_path_FGREP"
+
+
+test -z "$GREP" && GREP=grep
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+# Check whether --with-gnu-ld was given.
+if test "${with_gnu_ld+set}" = set; then :
+ withval=$with_gnu_ld; test "$withval" = no || with_gnu_ld=yes
+else
+ with_gnu_ld=no
+fi
+
+ac_prog=ld
+if test "$GCC" = yes; then
+ # Check if gcc -print-prog-name=ld gives a path.
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for ld used by $CC" >&5
+$as_echo_n "checking for ld used by $CC... " >&6; }
+ case $host in
+ *-*-mingw*)
+ # gcc leaves a trailing carriage return which upsets mingw
+ ac_prog=`($CC -print-prog-name=ld) 2>&5 | tr -d '\015'` ;;
+ *)
+ ac_prog=`($CC -print-prog-name=ld) 2>&5` ;;
+ esac
+ case $ac_prog in
+ # Accept absolute paths.
+ [\\/]* | ?:[\\/]*)
+ re_direlt='/[^/][^/]*/\.\./'
+ # Canonicalize the pathname of ld
+ ac_prog=`$ECHO "$ac_prog"| $SED 's%\\\\%/%g'`
+ while $ECHO "$ac_prog" | $GREP "$re_direlt" > /dev/null 2>&1; do
+ ac_prog=`$ECHO $ac_prog| $SED "s%$re_direlt%/%"`
+ done
+ test -z "$LD" && LD="$ac_prog"
+ ;;
+ "")
+ # If it fails, then pretend we aren't using GCC.
+ ac_prog=ld
+ ;;
+ *)
+ # If it is relative, then search for the first ld in PATH.
+ with_gnu_ld=unknown
+ ;;
+ esac
+elif test "$with_gnu_ld" = yes; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for GNU ld" >&5
+$as_echo_n "checking for GNU ld... " >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for non-GNU ld" >&5
+$as_echo_n "checking for non-GNU ld... " >&6; }
+fi
+if test "${lt_cv_path_LD+set}" = set; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -z "$LD"; then
+ lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR
+ for ac_dir in $PATH; do
+ IFS="$lt_save_ifs"
+ test -z "$ac_dir" && ac_dir=.
+ if test -f "$ac_dir/$ac_prog" || test -f "$ac_dir/$ac_prog$ac_exeext"; then
+ lt_cv_path_LD="$ac_dir/$ac_prog"
+ # Check to see if the program is GNU ld. I'd rather use --version,
+ # but apparently some variants of GNU ld only accept -v.
+ # Break only if it was the GNU/non-GNU ld that we prefer.
+ case `"$lt_cv_path_LD" -v 2>&1 </dev/null` in
+ *GNU* | *'with BFD'*)
+ test "$with_gnu_ld" != no && break
+ ;;
+ *)
+ test "$with_gnu_ld" != yes && break
+ ;;
+ esac
+ fi
+ done
+ IFS="$lt_save_ifs"
+else
+ lt_cv_path_LD="$LD" # Let the user override the test with a path.
+fi
+fi
+
+LD="$lt_cv_path_LD"
+if test -n "$LD"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $LD" >&5
+$as_echo "$LD" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+test -z "$LD" && as_fn_error $? "no acceptable ld found in \$PATH" "$LINENO" 5
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking if the linker ($LD) is GNU ld" >&5
+$as_echo_n "checking if the linker ($LD) is GNU ld... " >&6; }
+if test "${lt_cv_prog_gnu_ld+set}" = set; then :
+ $as_echo_n "(cached) " >&6
+else
+ # I'd rather use --version here, but apparently some GNU lds only accept -v.
+case `$LD -v 2>&1 </dev/null` in
+*GNU* | *'with BFD'*)
+ lt_cv_prog_gnu_ld=yes
+ ;;
+*)
+ lt_cv_prog_gnu_ld=no
+ ;;
+esac
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_gnu_ld" >&5
+$as_echo "$lt_cv_prog_gnu_ld" >&6; }
+with_gnu_ld=$lt_cv_prog_gnu_ld
+
+
+
+
+
+
+
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for BSD- or MS-compatible name lister (nm)" >&5
+$as_echo_n "checking for BSD- or MS-compatible name lister (nm)... " >&6; }
+if test "${lt_cv_path_NM+set}" = set; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$NM"; then
+ # Let the user override the test.
+ lt_cv_path_NM="$NM"
+else
+ lt_nm_to_check="${ac_tool_prefix}nm"
+ if test -n "$ac_tool_prefix" && test "$build" = "$host"; then
+ lt_nm_to_check="$lt_nm_to_check nm"
+ fi
+ for lt_tmp_nm in $lt_nm_to_check; do
+ lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR
+ for ac_dir in $PATH /usr/ccs/bin/elf /usr/ccs/bin /usr/ucb /bin; do
+ IFS="$lt_save_ifs"
+ test -z "$ac_dir" && ac_dir=.
+ tmp_nm="$ac_dir/$lt_tmp_nm"
+ if test -f "$tmp_nm" || test -f "$tmp_nm$ac_exeext" ; then
+ # Check to see if the nm accepts a BSD-compat flag.
+ # Adding the `sed 1q' prevents false positives on HP-UX, which says:
+ # nm: unknown option "B" ignored
+ # Tru64's nm complains that /dev/null is an invalid object file
+ case `"$tmp_nm" -B /dev/null 2>&1 | sed '1q'` in
+ */dev/null* | *'Invalid file or object type'*)
+ lt_cv_path_NM="$tmp_nm -B"
+ break
+ ;;
+ *)
+ case `"$tmp_nm" -p /dev/null 2>&1 | sed '1q'` in
+ */dev/null*)
+ lt_cv_path_NM="$tmp_nm -p"
+ break
+ ;;
+ *)
+ lt_cv_path_NM=${lt_cv_path_NM="$tmp_nm"} # keep the first match, but
+ continue # so that we can try to find one that supports BSD flags
+ ;;
+ esac
+ ;;
+ esac
+ fi
+ done
+ IFS="$lt_save_ifs"
+ done
+ : ${lt_cv_path_NM=no}
+fi
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_path_NM" >&5
+$as_echo "$lt_cv_path_NM" >&6; }
+if test "$lt_cv_path_NM" != "no"; then
+ NM="$lt_cv_path_NM"
+else
+ # Didn't find any BSD compatible name lister, look for dumpbin.
+ if test -n "$ac_tool_prefix"; then
+ for ac_prog in "dumpbin -symbols" "link -dump -symbols"
+ do
+ # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args.
+set dummy $ac_tool_prefix$ac_prog; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if test "${ac_cv_prog_DUMPBIN+set}" = set; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$DUMPBIN"; then
+ ac_cv_prog_DUMPBIN="$DUMPBIN" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+ ac_cv_prog_DUMPBIN="$ac_tool_prefix$ac_prog"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+fi
+fi
+DUMPBIN=$ac_cv_prog_DUMPBIN
+if test -n "$DUMPBIN"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $DUMPBIN" >&5
+$as_echo "$DUMPBIN" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+ test -n "$DUMPBIN" && break
+ done
+fi
+if test -z "$DUMPBIN"; then
+ ac_ct_DUMPBIN=$DUMPBIN
+ for ac_prog in "dumpbin -symbols" "link -dump -symbols"
+do
+ # Extract the first word of "$ac_prog", so it can be a program name with args.
+set dummy $ac_prog; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if test "${ac_cv_prog_ac_ct_DUMPBIN+set}" = set; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$ac_ct_DUMPBIN"; then
+ ac_cv_prog_ac_ct_DUMPBIN="$ac_ct_DUMPBIN" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+ ac_cv_prog_ac_ct_DUMPBIN="$ac_prog"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+fi
+fi
+ac_ct_DUMPBIN=$ac_cv_prog_ac_ct_DUMPBIN
+if test -n "$ac_ct_DUMPBIN"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_DUMPBIN" >&5
+$as_echo "$ac_ct_DUMPBIN" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+ test -n "$ac_ct_DUMPBIN" && break
+done
+
+ if test "x$ac_ct_DUMPBIN" = x; then
+ DUMPBIN=":"
+ else
+ case $cross_compiling:$ac_tool_warned in
+yes:)
+{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
+$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
+ac_tool_warned=yes ;;
+esac
+ DUMPBIN=$ac_ct_DUMPBIN
+ fi
+fi
+
+
+ if test "$DUMPBIN" != ":"; then
+ NM="$DUMPBIN"
+ fi
+fi
+test -z "$NM" && NM=nm
+
+
+
+
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking the name lister ($NM) interface" >&5
+$as_echo_n "checking the name lister ($NM) interface... " >&6; }
+if test "${lt_cv_nm_interface+set}" = set; then :
+ $as_echo_n "(cached) " >&6
+else
+ lt_cv_nm_interface="BSD nm"
+ echo "int some_variable = 0;" > conftest.$ac_ext
+ (eval echo "\"\$as_me:4738: $ac_compile\"" >&5)
+ (eval "$ac_compile" 2>conftest.err)
+ cat conftest.err >&5
+ (eval echo "\"\$as_me:4741: $NM \\\"conftest.$ac_objext\\\"\"" >&5)
+ (eval "$NM \"conftest.$ac_objext\"" 2>conftest.err > conftest.out)
+ cat conftest.err >&5
+ (eval echo "\"\$as_me:4744: output\"" >&5)
+ cat conftest.out >&5
+ if $GREP 'External.*some_variable' conftest.out > /dev/null; then
+ lt_cv_nm_interface="MS dumpbin"
+ fi
+ rm -f conftest*
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_nm_interface" >&5
+$as_echo "$lt_cv_nm_interface" >&6; }
+
+# find the maximum length of command line arguments
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking the maximum length of command line arguments" >&5
+$as_echo_n "checking the maximum length of command line arguments... " >&6; }
+if test "${lt_cv_sys_max_cmd_len+set}" = set; then :
+ $as_echo_n "(cached) " >&6
+else
+ i=0
+ teststring="ABCD"
+
+ case $build_os in
+ msdosdjgpp*)
+ # On DJGPP, this test can blow up pretty badly due to problems in libc
+ # (any single argument exceeding 2000 bytes causes a buffer overrun
+ # during glob expansion). Even if it were fixed, the result of this
+ # check would be larger than it should be.
+ lt_cv_sys_max_cmd_len=12288; # 12K is about right
+ ;;
+
+ gnu*)
+ # Under GNU Hurd, this test is not required because there is
+ # no limit to the length of command line arguments.
+ # Libtool will interpret -1 as no limit whatsoever
+ lt_cv_sys_max_cmd_len=-1;
+ ;;
+
+ cygwin* | mingw* | cegcc*)
+ # On Win9x/ME, this test blows up -- it succeeds, but takes
+ # about 5 minutes as the teststring grows exponentially.
+ # Worse, since 9x/ME are not pre-emptively multitasking,
+ # you end up with a "frozen" computer, even though with patience
+ # the test eventually succeeds (with a max line length of 256k).
+ # Instead, let's just punt: use the minimum linelength reported by
+ # all of the supported platforms: 8192 (on NT/2K/XP).
+ lt_cv_sys_max_cmd_len=8192;
+ ;;
+
+ amigaos*)
+ # On AmigaOS with pdksh, this test takes hours, literally.
+ # So we just punt and use a minimum line length of 8192.
+ lt_cv_sys_max_cmd_len=8192;
+ ;;
+
+ netbsd* | freebsd* | openbsd* | darwin* | dragonfly*)
+ # This has been around since 386BSD, at least. Likely further.
+ if test -x /sbin/sysctl; then
+ lt_cv_sys_max_cmd_len=`/sbin/sysctl -n kern.argmax`
+ elif test -x /usr/sbin/sysctl; then
+ lt_cv_sys_max_cmd_len=`/usr/sbin/sysctl -n kern.argmax`
+ else
+ lt_cv_sys_max_cmd_len=65536 # usable default for all BSDs
+ fi
+ # And add a safety zone
+ lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 4`
+ lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \* 3`
+ ;;
+
+ interix*)
+ # We know the value 262144 and hardcode it with a safety zone (like BSD)
+ lt_cv_sys_max_cmd_len=196608
+ ;;
+
+ osf*)
+ # Dr. Hans Ekkehard Plesser reports seeing a kernel panic running configure
+ # due to this test when exec_disable_arg_limit is 1 on Tru64. It is not
+ # nice to cause kernel panics so lets avoid the loop below.
+ # First set a reasonable default.
+ lt_cv_sys_max_cmd_len=16384
+ #
+ if test -x /sbin/sysconfig; then
+ case `/sbin/sysconfig -q proc exec_disable_arg_limit` in
+ *1*) lt_cv_sys_max_cmd_len=-1 ;;
+ esac
+ fi
+ ;;
+ sco3.2v5*)
+ lt_cv_sys_max_cmd_len=102400
+ ;;
+ sysv5* | sco5v6* | sysv4.2uw2*)
+ kargmax=`grep ARG_MAX /etc/conf/cf.d/stune 2>/dev/null`
+ if test -n "$kargmax"; then
+ lt_cv_sys_max_cmd_len=`echo $kargmax | sed 's/.*[ ]//'`
+ else
+ lt_cv_sys_max_cmd_len=32768
+ fi
+ ;;
+ *)
+ lt_cv_sys_max_cmd_len=`(getconf ARG_MAX) 2> /dev/null`
+ if test -n "$lt_cv_sys_max_cmd_len"; then
+ lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 4`
+ lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \* 3`
+ else
+ # Make teststring a little bigger before we do anything with it.
+ # a 1K string should be a reasonable start.
+ for i in 1 2 3 4 5 6 7 8 ; do
+ teststring=$teststring$teststring
+ done
+ SHELL=${SHELL-${CONFIG_SHELL-/bin/sh}}
+ # If test is not a shell built-in, we'll probably end up computing a
+ # maximum length that is only half of the actual maximum length, but
+ # we can't tell.
+ while { test "X"`$SHELL $0 --fallback-echo "X$teststring$teststring" 2>/dev/null` \
+ = "XX$teststring$teststring"; } >/dev/null 2>&1 &&
+ test $i != 17 # 1/2 MB should be enough
+ do
+ i=`expr $i + 1`
+ teststring=$teststring$teststring
+ done
+ # Only check the string length outside the loop.
+ lt_cv_sys_max_cmd_len=`expr "X$teststring" : ".*" 2>&1`
+ teststring=
+ # Add a significant safety factor because C++ compilers can tack on
+ # massive amounts of additional arguments before passing them to the
+ # linker. It appears as though 1/2 is a usable value.
+ lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 2`
+ fi
+ ;;
+ esac
+
+fi
+
+if test -n $lt_cv_sys_max_cmd_len ; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_sys_max_cmd_len" >&5
+$as_echo "$lt_cv_sys_max_cmd_len" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: none" >&5
+$as_echo "none" >&6; }
+fi
+max_cmd_len=$lt_cv_sys_max_cmd_len
+
+
+
+
+
+
+: ${CP="cp -f"}
+: ${MV="mv -f"}
+: ${RM="rm -f"}
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the shell understands some XSI constructs" >&5
+$as_echo_n "checking whether the shell understands some XSI constructs... " >&6; }
+# Try some XSI features
+xsi_shell=no
+( _lt_dummy="a/b/c"
+ test "${_lt_dummy##*/},${_lt_dummy%/*},"${_lt_dummy%"$_lt_dummy"}, \
+ = c,a/b,, \
+ && eval 'test $(( 1 + 1 )) -eq 2 \
+ && test "${#_lt_dummy}" -eq 5' ) >/dev/null 2>&1 \
+ && xsi_shell=yes
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $xsi_shell" >&5
+$as_echo "$xsi_shell" >&6; }
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the shell understands \"+=\"" >&5
+$as_echo_n "checking whether the shell understands \"+=\"... " >&6; }
+lt_shell_append=no
+( foo=bar; set foo baz; eval "$1+=\$2" && test "$foo" = barbaz ) \
+ >/dev/null 2>&1 \
+ && lt_shell_append=yes
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_shell_append" >&5
+$as_echo "$lt_shell_append" >&6; }
+
+
+if ( (MAIL=60; unset MAIL) || exit) >/dev/null 2>&1; then
+ lt_unset=unset
+else
+ lt_unset=false
+fi
+
+
+
+
+
+# test EBCDIC or ASCII
+case `echo X|tr X '\101'` in
+ A) # ASCII based system
+ # \n is not interpreted correctly by Solaris 8 /usr/ucb/tr
+ lt_SP2NL='tr \040 \012'
+ lt_NL2SP='tr \015\012 \040\040'
+ ;;
+ *) # EBCDIC based system
+ lt_SP2NL='tr \100 \n'
+ lt_NL2SP='tr \r\n \100\100'
+ ;;
+esac
+
+
+
+
+
+
+
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $LD option to reload object files" >&5
+$as_echo_n "checking for $LD option to reload object files... " >&6; }
+if test "${lt_cv_ld_reload_flag+set}" = set; then :
+ $as_echo_n "(cached) " >&6
+else
+ lt_cv_ld_reload_flag='-r'
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_ld_reload_flag" >&5
+$as_echo "$lt_cv_ld_reload_flag" >&6; }
+reload_flag=$lt_cv_ld_reload_flag
+case $reload_flag in
+"" | " "*) ;;
+*) reload_flag=" $reload_flag" ;;
+esac
+reload_cmds='$LD$reload_flag -o $output$reload_objs'
+case $host_os in
+ darwin*)
+ if test "$GCC" = yes; then
+ reload_cmds='$LTCC $LTCFLAGS -nostdlib ${wl}-r -o $output$reload_objs'
+ else
+ reload_cmds='$LD$reload_flag -o $output$reload_objs'
+ fi
+ ;;
+esac
+
+
+
+
+
+
+
+
+
+if test -n "$ac_tool_prefix"; then
+ # Extract the first word of "${ac_tool_prefix}objdump", so it can be a program name with args.
+set dummy ${ac_tool_prefix}objdump; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if test "${ac_cv_prog_OBJDUMP+set}" = set; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$OBJDUMP"; then
+ ac_cv_prog_OBJDUMP="$OBJDUMP" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+ ac_cv_prog_OBJDUMP="${ac_tool_prefix}objdump"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+fi
+fi
+OBJDUMP=$ac_cv_prog_OBJDUMP
+if test -n "$OBJDUMP"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $OBJDUMP" >&5
+$as_echo "$OBJDUMP" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+fi
+if test -z "$ac_cv_prog_OBJDUMP"; then
+ ac_ct_OBJDUMP=$OBJDUMP
+ # Extract the first word of "objdump", so it can be a program name with args.
+set dummy objdump; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if test "${ac_cv_prog_ac_ct_OBJDUMP+set}" = set; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$ac_ct_OBJDUMP"; then
+ ac_cv_prog_ac_ct_OBJDUMP="$ac_ct_OBJDUMP" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+ ac_cv_prog_ac_ct_OBJDUMP="objdump"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+fi
+fi
+ac_ct_OBJDUMP=$ac_cv_prog_ac_ct_OBJDUMP
+if test -n "$ac_ct_OBJDUMP"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_OBJDUMP" >&5
+$as_echo "$ac_ct_OBJDUMP" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+ if test "x$ac_ct_OBJDUMP" = x; then
+ OBJDUMP="false"
+ else
+ case $cross_compiling:$ac_tool_warned in
+yes:)
+{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
+$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
+ac_tool_warned=yes ;;
+esac
+ OBJDUMP=$ac_ct_OBJDUMP
+ fi
+else
+ OBJDUMP="$ac_cv_prog_OBJDUMP"
+fi
+
+test -z "$OBJDUMP" && OBJDUMP=objdump
+
+
+
+
+
+
+
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking how to recognize dependent libraries" >&5
+$as_echo_n "checking how to recognize dependent libraries... " >&6; }
+if test "${lt_cv_deplibs_check_method+set}" = set; then :
+ $as_echo_n "(cached) " >&6
+else
+ lt_cv_file_magic_cmd='$MAGIC_CMD'
+lt_cv_file_magic_test_file=
+lt_cv_deplibs_check_method='unknown'
+# Need to set the preceding variable on all platforms that support
+# interlibrary dependencies.
+# 'none' -- dependencies not supported.
+# `unknown' -- same as none, but documents that we really don't know.
+# 'pass_all' -- all dependencies passed with no checks.
+# 'test_compile' -- check by making test program.
+# 'file_magic [[regex]]' -- check by looking for files in library path
+# which responds to the $file_magic_cmd with a given extended regex.
+# If you have `file' or equivalent on your system and you're not sure
+# whether `pass_all' will *always* work, you probably want this one.
+
+case $host_os in
+aix[4-9]*)
+ lt_cv_deplibs_check_method=pass_all
+ ;;
+
+beos*)
+ lt_cv_deplibs_check_method=pass_all
+ ;;
+
+bsdi[45]*)
+ lt_cv_deplibs_check_method='file_magic ELF [0-9][0-9]*-bit [ML]SB (shared object|dynamic lib)'
+ lt_cv_file_magic_cmd='/usr/bin/file -L'
+ lt_cv_file_magic_test_file=/shlib/libc.so
+ ;;
+
+cygwin*)
+ # func_win32_libid is a shell function defined in ltmain.sh
+ lt_cv_deplibs_check_method='file_magic ^x86 archive import|^x86 DLL'
+ lt_cv_file_magic_cmd='func_win32_libid'
+ ;;
+
+mingw* | pw32*)
+ # Base MSYS/MinGW do not provide the 'file' command needed by
+ # func_win32_libid shell function, so use a weaker test based on 'objdump',
+ # unless we find 'file', for example because we are cross-compiling.
+ if ( file / ) >/dev/null 2>&1; then
+ lt_cv_deplibs_check_method='file_magic ^x86 archive import|^x86 DLL'
+ lt_cv_file_magic_cmd='func_win32_libid'
+ else
+ lt_cv_deplibs_check_method='file_magic file format pei*-i386(.*architecture: i386)?'
+ lt_cv_file_magic_cmd='$OBJDUMP -f'
+ fi
+ ;;
+
+cegcc)
+ # use the weaker test based on 'objdump'. See mingw*.
+ lt_cv_deplibs_check_method='file_magic file format pe-arm-.*little(.*architecture: arm)?'
+ lt_cv_file_magic_cmd='$OBJDUMP -f'
+ ;;
+
+darwin* | rhapsody*)
+ lt_cv_deplibs_check_method=pass_all
+ ;;
+
+freebsd* | dragonfly*)
+ if echo __ELF__ | $CC -E - | $GREP __ELF__ > /dev/null; then
+ case $host_cpu in
+ i*86 )
+ # Not sure whether the presence of OpenBSD here was a mistake.
+ # Let's accept both of them until this is cleared up.
+ lt_cv_deplibs_check_method='file_magic (FreeBSD|OpenBSD|DragonFly)/i[3-9]86 (compact )?demand paged shared library'
+ lt_cv_file_magic_cmd=/usr/bin/file
+ lt_cv_file_magic_test_file=`echo /usr/lib/libc.so.*`
+ ;;
+ esac
+ else
+ lt_cv_deplibs_check_method=pass_all
+ fi
+ ;;
+
+gnu*)
+ lt_cv_deplibs_check_method=pass_all
+ ;;
+
+hpux10.20* | hpux11*)
+ lt_cv_file_magic_cmd=/usr/bin/file
+ case $host_cpu in
+ ia64*)
+ lt_cv_deplibs_check_method='file_magic (s[0-9][0-9][0-9]|ELF-[0-9][0-9]) shared object file - IA64'
+ lt_cv_file_magic_test_file=/usr/lib/hpux32/libc.so
+ ;;
+ hppa*64*)
+ lt_cv_deplibs_check_method='file_magic (s[0-9][0-9][0-9]|ELF-[0-9][0-9]) shared object file - PA-RISC [0-9].[0-9]'
+ lt_cv_file_magic_test_file=/usr/lib/pa20_64/libc.sl
+ ;;
+ *)
+ lt_cv_deplibs_check_method='file_magic (s[0-9][0-9][0-9]|PA-RISC[0-9].[0-9]) shared library'
+ lt_cv_file_magic_test_file=/usr/lib/libc.sl
+ ;;
+ esac
+ ;;
+
+interix[3-9]*)
+ # PIC code is broken on Interix 3.x, that's why |\.a not |_pic\.a here
+ lt_cv_deplibs_check_method='match_pattern /lib[^/]+(\.so|\.a)$'
+ ;;
+
+irix5* | irix6* | nonstopux*)
+ case $LD in
+ *-32|*"-32 ") libmagic=32-bit;;
+ *-n32|*"-n32 ") libmagic=N32;;
+ *-64|*"-64 ") libmagic=64-bit;;
+ *) libmagic=never-match;;
+ esac
+ lt_cv_deplibs_check_method=pass_all
+ ;;
+
+# This must be Linux ELF.
+linux* | k*bsd*-gnu | kopensolaris*-gnu)
+ lt_cv_deplibs_check_method=pass_all
+ ;;
+
+netbsd* | netbsdelf*-gnu)
+ if echo __ELF__ | $CC -E - | $GREP __ELF__ > /dev/null; then
+ lt_cv_deplibs_check_method='match_pattern /lib[^/]+(\.so\.[0-9]+\.[0-9]+|_pic\.a)$'
+ else
+ lt_cv_deplibs_check_method='match_pattern /lib[^/]+(\.so|_pic\.a)$'
+ fi
+ ;;
+
+newos6*)
+ lt_cv_deplibs_check_method='file_magic ELF [0-9][0-9]*-bit [ML]SB (executable|dynamic lib)'
+ lt_cv_file_magic_cmd=/usr/bin/file
+ lt_cv_file_magic_test_file=/usr/lib/libnls.so
+ ;;
+
+*nto* | *qnx*)
+ lt_cv_deplibs_check_method=pass_all
+ ;;
+
+openbsd*)
+ if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then
+ lt_cv_deplibs_check_method='match_pattern /lib[^/]+(\.so\.[0-9]+\.[0-9]+|\.so|_pic\.a)$'
+ else
+ lt_cv_deplibs_check_method='match_pattern /lib[^/]+(\.so\.[0-9]+\.[0-9]+|_pic\.a)$'
+ fi
+ ;;
+
+osf3* | osf4* | osf5*)
+ lt_cv_deplibs_check_method=pass_all
+ ;;
+
+rdos*)
+ lt_cv_deplibs_check_method=pass_all
+ ;;
+
+solaris*)
+ lt_cv_deplibs_check_method=pass_all
+ ;;
+
+sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX* | sysv4*uw2*)
+ lt_cv_deplibs_check_method=pass_all
+ ;;
+
+sysv4 | sysv4.3*)
+ case $host_vendor in
+ motorola)
+ lt_cv_deplibs_check_method='file_magic ELF [0-9][0-9]*-bit [ML]SB (shared object|dynamic lib) M[0-9][0-9]* Version [0-9]'
+ lt_cv_file_magic_test_file=`echo /usr/lib/libc.so*`
+ ;;
+ ncr)
+ lt_cv_deplibs_check_method=pass_all
+ ;;
+ sequent)
+ lt_cv_file_magic_cmd='/bin/file'
+ lt_cv_deplibs_check_method='file_magic ELF [0-9][0-9]*-bit [LM]SB (shared object|dynamic lib )'
+ ;;
+ sni)
+ lt_cv_file_magic_cmd='/bin/file'
+ lt_cv_deplibs_check_method="file_magic ELF [0-9][0-9]*-bit [LM]SB dynamic lib"
+ lt_cv_file_magic_test_file=/lib/libc.so
+ ;;
+ siemens)
+ lt_cv_deplibs_check_method=pass_all
+ ;;
+ pc)
+ lt_cv_deplibs_check_method=pass_all
+ ;;
+ esac
+ ;;
+
+tpf*)
+ lt_cv_deplibs_check_method=pass_all
+ ;;
+esac
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_deplibs_check_method" >&5
+$as_echo "$lt_cv_deplibs_check_method" >&6; }
+file_magic_cmd=$lt_cv_file_magic_cmd
+deplibs_check_method=$lt_cv_deplibs_check_method
+test -z "$deplibs_check_method" && deplibs_check_method=unknown
+
+
+
+
+
+
+
+
+
+
+
+
+if test -n "$ac_tool_prefix"; then
+ # Extract the first word of "${ac_tool_prefix}ar", so it can be a program name with args.
+set dummy ${ac_tool_prefix}ar; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if test "${ac_cv_prog_AR+set}" = set; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$AR"; then
+ ac_cv_prog_AR="$AR" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+ ac_cv_prog_AR="${ac_tool_prefix}ar"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+fi
+fi
+AR=$ac_cv_prog_AR
+if test -n "$AR"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $AR" >&5
+$as_echo "$AR" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+fi
+if test -z "$ac_cv_prog_AR"; then
+ ac_ct_AR=$AR
+ # Extract the first word of "ar", so it can be a program name with args.
+set dummy ar; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if test "${ac_cv_prog_ac_ct_AR+set}" = set; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$ac_ct_AR"; then
+ ac_cv_prog_ac_ct_AR="$ac_ct_AR" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+ ac_cv_prog_ac_ct_AR="ar"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+fi
+fi
+ac_ct_AR=$ac_cv_prog_ac_ct_AR
+if test -n "$ac_ct_AR"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_AR" >&5
+$as_echo "$ac_ct_AR" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+ if test "x$ac_ct_AR" = x; then
+ AR="false"
+ else
+ case $cross_compiling:$ac_tool_warned in
+yes:)
+{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
+$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
+ac_tool_warned=yes ;;
+esac
+ AR=$ac_ct_AR
+ fi
+else
+ AR="$ac_cv_prog_AR"
+fi
+
+test -z "$AR" && AR=ar
+test -z "$AR_FLAGS" && AR_FLAGS=cru
+
+
+
+
+
+
+
+
+
+
+
+if test -n "$ac_tool_prefix"; then
+ # Extract the first word of "${ac_tool_prefix}strip", so it can be a program name with args.
+set dummy ${ac_tool_prefix}strip; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if test "${ac_cv_prog_STRIP+set}" = set; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$STRIP"; then
+ ac_cv_prog_STRIP="$STRIP" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+ ac_cv_prog_STRIP="${ac_tool_prefix}strip"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+fi
+fi
+STRIP=$ac_cv_prog_STRIP
+if test -n "$STRIP"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $STRIP" >&5
+$as_echo "$STRIP" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+fi
+if test -z "$ac_cv_prog_STRIP"; then
+ ac_ct_STRIP=$STRIP
+ # Extract the first word of "strip", so it can be a program name with args.
+set dummy strip; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if test "${ac_cv_prog_ac_ct_STRIP+set}" = set; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$ac_ct_STRIP"; then
+ ac_cv_prog_ac_ct_STRIP="$ac_ct_STRIP" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+ ac_cv_prog_ac_ct_STRIP="strip"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+fi
+fi
+ac_ct_STRIP=$ac_cv_prog_ac_ct_STRIP
+if test -n "$ac_ct_STRIP"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_STRIP" >&5
+$as_echo "$ac_ct_STRIP" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+ if test "x$ac_ct_STRIP" = x; then
+ STRIP=":"
+ else
+ case $cross_compiling:$ac_tool_warned in
+yes:)
+{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
+$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
+ac_tool_warned=yes ;;
+esac
+ STRIP=$ac_ct_STRIP
+ fi
+else
+ STRIP="$ac_cv_prog_STRIP"
+fi
+
+test -z "$STRIP" && STRIP=:
+
+
+
+
+
+
+if test -n "$ac_tool_prefix"; then
+ # Extract the first word of "${ac_tool_prefix}ranlib", so it can be a program name with args.
+set dummy ${ac_tool_prefix}ranlib; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if test "${ac_cv_prog_RANLIB+set}" = set; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$RANLIB"; then
+ ac_cv_prog_RANLIB="$RANLIB" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+ ac_cv_prog_RANLIB="${ac_tool_prefix}ranlib"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+fi
+fi
+RANLIB=$ac_cv_prog_RANLIB
+if test -n "$RANLIB"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $RANLIB" >&5
+$as_echo "$RANLIB" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+fi
+if test -z "$ac_cv_prog_RANLIB"; then
+ ac_ct_RANLIB=$RANLIB
+ # Extract the first word of "ranlib", so it can be a program name with args.
+set dummy ranlib; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if test "${ac_cv_prog_ac_ct_RANLIB+set}" = set; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$ac_ct_RANLIB"; then
+ ac_cv_prog_ac_ct_RANLIB="$ac_ct_RANLIB" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+ ac_cv_prog_ac_ct_RANLIB="ranlib"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+fi
+fi
+ac_ct_RANLIB=$ac_cv_prog_ac_ct_RANLIB
+if test -n "$ac_ct_RANLIB"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_RANLIB" >&5
+$as_echo "$ac_ct_RANLIB" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+ if test "x$ac_ct_RANLIB" = x; then
+ RANLIB=":"
+ else
+ case $cross_compiling:$ac_tool_warned in
+yes:)
+{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
+$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
+ac_tool_warned=yes ;;
+esac
+ RANLIB=$ac_ct_RANLIB
+ fi
+else
+ RANLIB="$ac_cv_prog_RANLIB"
+fi
+
+test -z "$RANLIB" && RANLIB=:
+
+
+
+
+
+
+# Determine commands to create old-style static archives.
+old_archive_cmds='$AR $AR_FLAGS $oldlib$oldobjs'
+old_postinstall_cmds='chmod 644 $oldlib'
+old_postuninstall_cmds=
+
+if test -n "$RANLIB"; then
+ case $host_os in
+ openbsd*)
+ old_postinstall_cmds="$old_postinstall_cmds~\$RANLIB -t \$oldlib"
+ ;;
+ *)
+ old_postinstall_cmds="$old_postinstall_cmds~\$RANLIB \$oldlib"
+ ;;
+ esac
+ old_archive_cmds="$old_archive_cmds~\$RANLIB \$oldlib"
+fi
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+# If no C compiler was specified, use CC.
+LTCC=${LTCC-"$CC"}
+
+# If no C compiler flags were specified, use CFLAGS.
+LTCFLAGS=${LTCFLAGS-"$CFLAGS"}
+
+# Allow CC to be a program name with arguments.
+compiler=$CC
+
+
+# Check for command to grab the raw symbol name followed by C symbol from nm.
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking command to parse $NM output from $compiler object" >&5
+$as_echo_n "checking command to parse $NM output from $compiler object... " >&6; }
+if test "${lt_cv_sys_global_symbol_pipe+set}" = set; then :
+ $as_echo_n "(cached) " >&6
+else
+
+# These are sane defaults that work on at least a few old systems.
+# [They come from Ultrix. What could be older than Ultrix?!! ;)]
+
+# Character class describing NM global symbol codes.
+symcode='[BCDEGRST]'
+
+# Regexp to match symbols that can be accessed directly from C.
+sympat='\([_A-Za-z][_A-Za-z0-9]*\)'
+
+# Define system-specific variables.
+case $host_os in
+aix*)
+ symcode='[BCDT]'
+ ;;
+cygwin* | mingw* | pw32* | cegcc*)
+ symcode='[ABCDGISTW]'
+ ;;
+hpux*)
+ if test "$host_cpu" = ia64; then
+ symcode='[ABCDEGRST]'
+ fi
+ ;;
+irix* | nonstopux*)
+ symcode='[BCDEGRST]'
+ ;;
+osf*)
+ symcode='[BCDEGQRST]'
+ ;;
+solaris*)
+ symcode='[BDRT]'
+ ;;
+sco3.2v5*)
+ symcode='[DT]'
+ ;;
+sysv4.2uw2*)
+ symcode='[DT]'
+ ;;
+sysv5* | sco5v6* | unixware* | OpenUNIX*)
+ symcode='[ABDT]'
+ ;;
+sysv4)
+ symcode='[DFNSTU]'
+ ;;
+esac
+
+# If we're using GNU nm, then use its standard symbol codes.
+case `$NM -V 2>&1` in
+*GNU* | *'with BFD'*)
+ symcode='[ABCDGIRSTW]' ;;
+esac
+
+# Transform an extracted symbol line into a proper C declaration.
+# Some systems (esp. on ia64) link data and code symbols differently,
+# so use this general approach.
+lt_cv_sys_global_symbol_to_cdecl="sed -n -e 's/^T .* \(.*\)$/extern int \1();/p' -e 's/^$symcode* .* \(.*\)$/extern char \1;/p'"
+
+# Transform an extracted symbol line into symbol name and symbol address
+lt_cv_sys_global_symbol_to_c_name_address="sed -n -e 's/^: \([^ ]*\) $/ {\\\"\1\\\", (void *) 0},/p' -e 's/^$symcode* \([^ ]*\) \([^ ]*\)$/ {\"\2\", (void *) \&\2},/p'"
+lt_cv_sys_global_symbol_to_c_name_address_lib_prefix="sed -n -e 's/^: \([^ ]*\) $/ {\\\"\1\\\", (void *) 0},/p' -e 's/^$symcode* \([^ ]*\) \(lib[^ ]*\)$/ {\"\2\", (void *) \&\2},/p' -e 's/^$symcode* \([^ ]*\) \([^ ]*\)$/ {\"lib\2\", (void *) \&\2},/p'"
+
+# Handle CRLF in mingw tool chain
+opt_cr=
+case $build_os in
+mingw*)
+ opt_cr=`$ECHO 'x\{0,1\}' | tr x '\015'` # option cr in regexp
+ ;;
+esac
+
+# Try without a prefix underscore, then with it.
+for ac_symprfx in "" "_"; do
+
+ # Transform symcode, sympat, and symprfx into a raw symbol and a C symbol.
+ symxfrm="\\1 $ac_symprfx\\2 \\2"
+
+ # Write the raw and C identifiers.
+ if test "$lt_cv_nm_interface" = "MS dumpbin"; then
+ # Fake it for dumpbin and say T for any non-static function
+ # and D for any global variable.
+ # Also find C++ and __fastcall symbols from MSVC++,
+ # which start with @ or ?.
+ lt_cv_sys_global_symbol_pipe="$AWK '"\
+" {last_section=section; section=\$ 3};"\
+" /Section length .*#relocs.*(pick any)/{hide[last_section]=1};"\
+" \$ 0!~/External *\|/{next};"\
+" / 0+ UNDEF /{next}; / UNDEF \([^|]\)*()/{next};"\
+" {if(hide[section]) next};"\
+" {f=0}; \$ 0~/\(\).*\|/{f=1}; {printf f ? \"T \" : \"D \"};"\
+" {split(\$ 0, a, /\||\r/); split(a[2], s)};"\
+" s[1]~/^[@?]/{print s[1], s[1]; next};"\
+" s[1]~prfx {split(s[1],t,\"@\"); print t[1], substr(t[1],length(prfx))}"\
+" ' prfx=^$ac_symprfx"
+ else
+ lt_cv_sys_global_symbol_pipe="sed -n -e 's/^.*[ ]\($symcode$symcode*\)[ ][ ]*$ac_symprfx$sympat$opt_cr$/$symxfrm/p'"
+ fi
+
+ # Check to see that the pipe works correctly.
+ pipe_works=no
+
+ rm -f conftest*
+ cat > conftest.$ac_ext <<_LT_EOF
+#ifdef __cplusplus
+extern "C" {
+#endif
+char nm_test_var;
+void nm_test_func(void);
+void nm_test_func(void){}
+#ifdef __cplusplus
+}
+#endif
+int main(){nm_test_var='a';nm_test_func();return(0);}
+_LT_EOF
+
+ if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5
+ (eval $ac_compile) 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }; then
+ # Now try to grab the symbols.
+ nlist=conftest.nm
+ if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$NM conftest.$ac_objext \| $lt_cv_sys_global_symbol_pipe \> $nlist\""; } >&5
+ (eval $NM conftest.$ac_objext \| $lt_cv_sys_global_symbol_pipe \> $nlist) 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; } && test -s "$nlist"; then
+ # Try sorting and uniquifying the output.
+ if sort "$nlist" | uniq > "$nlist"T; then
+ mv -f "$nlist"T "$nlist"
+ else
+ rm -f "$nlist"T
+ fi
+
+ # Make sure that we snagged all the symbols we need.
+ if $GREP ' nm_test_var$' "$nlist" >/dev/null; then
+ if $GREP ' nm_test_func$' "$nlist" >/dev/null; then
+ cat <<_LT_EOF > conftest.$ac_ext
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+_LT_EOF
+ # Now generate the symbol file.
+ eval "$lt_cv_sys_global_symbol_to_cdecl"' < "$nlist" | $GREP -v main >> conftest.$ac_ext'
+
+ cat <<_LT_EOF >> conftest.$ac_ext
+
+/* The mapping between symbol names and symbols. */
+const struct {
+ const char *name;
+ void *address;
+}
+lt__PROGRAM__LTX_preloaded_symbols[] =
+{
+ { "@PROGRAM@", (void *) 0 },
+_LT_EOF
+ $SED "s/^$symcode$symcode* \(.*\) \(.*\)$/ {\"\2\", (void *) \&\2},/" < "$nlist" | $GREP -v main >> conftest.$ac_ext
+ cat <<\_LT_EOF >> conftest.$ac_ext
+ {0, (void *) 0}
+};
+
+/* This works around a problem in FreeBSD linker */
+#ifdef FREEBSD_WORKAROUND
+static const void *lt_preloaded_setup() {
+ return lt__PROGRAM__LTX_preloaded_symbols;
+}
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+_LT_EOF
+ # Now try linking the two files.
+ mv conftest.$ac_objext conftstm.$ac_objext
+ lt_save_LIBS="$LIBS"
+ lt_save_CFLAGS="$CFLAGS"
+ LIBS="conftstm.$ac_objext"
+ CFLAGS="$CFLAGS$lt_prog_compiler_no_builtin_flag"
+ if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_link\""; } >&5
+ (eval $ac_link) 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; } && test -s conftest${ac_exeext}; then
+ pipe_works=yes
+ fi
+ LIBS="$lt_save_LIBS"
+ CFLAGS="$lt_save_CFLAGS"
+ else
+ echo "cannot find nm_test_func in $nlist" >&5
+ fi
+ else
+ echo "cannot find nm_test_var in $nlist" >&5
+ fi
+ else
+ echo "cannot run $lt_cv_sys_global_symbol_pipe" >&5
+ fi
+ else
+ echo "$progname: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ fi
+ rm -rf conftest* conftst*
+
+ # Do not use the global_symbol_pipe unless it works.
+ if test "$pipe_works" = yes; then
+ break
+ else
+ lt_cv_sys_global_symbol_pipe=
+ fi
+done
+
+fi
+
+if test -z "$lt_cv_sys_global_symbol_pipe"; then
+ lt_cv_sys_global_symbol_to_cdecl=
+fi
+if test -z "$lt_cv_sys_global_symbol_pipe$lt_cv_sys_global_symbol_to_cdecl"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: failed" >&5
+$as_echo "failed" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: ok" >&5
+$as_echo "ok" >&6; }
+fi
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+# Check whether --enable-libtool-lock was given.
+if test "${enable_libtool_lock+set}" = set; then :
+ enableval=$enable_libtool_lock;
+fi
+
+test "x$enable_libtool_lock" != xno && enable_libtool_lock=yes
+
+# Some flags need to be propagated to the compiler or linker for good
+# libtool support.
+case $host in
+ia64-*-hpux*)
+ # Find out which ABI we are using.
+ echo 'int i;' > conftest.$ac_ext
+ if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5
+ (eval $ac_compile) 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }; then
+ case `/usr/bin/file conftest.$ac_objext` in
+ *ELF-32*)
+ HPUX_IA64_MODE="32"
+ ;;
+ *ELF-64*)
+ HPUX_IA64_MODE="64"
+ ;;
+ esac
+ fi
+ rm -rf conftest*
+ ;;
+*-*-irix6*)
+ # Find out which ABI we are using.
+ echo '#line 5939 "configure"' > conftest.$ac_ext
+ if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5
+ (eval $ac_compile) 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }; then
+ if test "$lt_cv_prog_gnu_ld" = yes; then
+ case `/usr/bin/file conftest.$ac_objext` in
+ *32-bit*)
+ LD="${LD-ld} -melf32bsmip"
+ ;;
+ *N32*)
+ LD="${LD-ld} -melf32bmipn32"
+ ;;
+ *64-bit*)
+ LD="${LD-ld} -melf64bmip"
+ ;;
+ esac
+ else
+ case `/usr/bin/file conftest.$ac_objext` in
+ *32-bit*)
+ LD="${LD-ld} -32"
+ ;;
+ *N32*)
+ LD="${LD-ld} -n32"
+ ;;
+ *64-bit*)
+ LD="${LD-ld} -64"
+ ;;
+ esac
+ fi
+ fi
+ rm -rf conftest*
+ ;;
+
+x86_64-*kfreebsd*-gnu|x86_64-*linux*|ppc*-*linux*|powerpc*-*linux*| \
+s390*-*linux*|s390*-*tpf*|sparc*-*linux*)
+ # Find out which ABI we are using.
+ echo 'int i;' > conftest.$ac_ext
+ if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5
+ (eval $ac_compile) 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }; then
+ case `/usr/bin/file conftest.o` in
+ *32-bit*)
+ case $host in
+ x86_64-*kfreebsd*-gnu)
+ LD="${LD-ld} -m elf_i386_fbsd"
+ ;;
+ x86_64-*linux*)
+ LD="${LD-ld} -m elf_i386"
+ ;;
+ ppc64-*linux*|powerpc64-*linux*)
+ LD="${LD-ld} -m elf32ppclinux"
+ ;;
+ s390x-*linux*)
+ LD="${LD-ld} -m elf_s390"
+ ;;
+ sparc64-*linux*)
+ LD="${LD-ld} -m elf32_sparc"
+ ;;
+ esac
+ ;;
+ *64-bit*)
+ case $host in
+ x86_64-*kfreebsd*-gnu)
+ LD="${LD-ld} -m elf_x86_64_fbsd"
+ ;;
+ x86_64-*linux*)
+ LD="${LD-ld} -m elf_x86_64"
+ ;;
+ ppc*-*linux*|powerpc*-*linux*)
+ LD="${LD-ld} -m elf64ppc"
+ ;;
+ s390*-*linux*|s390*-*tpf*)
+ LD="${LD-ld} -m elf64_s390"
+ ;;
+ sparc*-*linux*)
+ LD="${LD-ld} -m elf64_sparc"
+ ;;
+ esac
+ ;;
+ esac
+ fi
+ rm -rf conftest*
+ ;;
+
+*-*-sco3.2v5*)
+ # On SCO OpenServer 5, we need -belf to get full-featured binaries.
+ SAVE_CFLAGS="$CFLAGS"
+ CFLAGS="$CFLAGS -belf"
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the C compiler needs -belf" >&5
+$as_echo_n "checking whether the C compiler needs -belf... " >&6; }
+if test "${lt_cv_cc_needs_belf+set}" = set; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+int
+main ()
+{
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+ lt_cv_cc_needs_belf=yes
+else
+ lt_cv_cc_needs_belf=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+ ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_cc_needs_belf" >&5
+$as_echo "$lt_cv_cc_needs_belf" >&6; }
+ if test x"$lt_cv_cc_needs_belf" != x"yes"; then
+ # this is probably gcc 2.8.0, egcs 1.0 or newer; no need for -belf
+ CFLAGS="$SAVE_CFLAGS"
+ fi
+ ;;
+sparc*-*solaris*)
+ # Find out which ABI we are using.
+ echo 'int i;' > conftest.$ac_ext
+ if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5
+ (eval $ac_compile) 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }; then
+ case `/usr/bin/file conftest.o` in
+ *64-bit*)
+ case $lt_cv_prog_gnu_ld in
+ yes*) LD="${LD-ld} -m elf64_sparc" ;;
+ *)
+ if ${LD-ld} -64 -r -o conftest2.o conftest.o >/dev/null 2>&1; then
+ LD="${LD-ld} -64"
+ fi
+ ;;
+ esac
+ ;;
+ esac
+ fi
+ rm -rf conftest*
+ ;;
+esac
+
+need_locks="$enable_libtool_lock"
+
+
+ case $host_os in
+ rhapsody* | darwin*)
+ if test -n "$ac_tool_prefix"; then
+ # Extract the first word of "${ac_tool_prefix}dsymutil", so it can be a program name with args.
+set dummy ${ac_tool_prefix}dsymutil; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if test "${ac_cv_prog_DSYMUTIL+set}" = set; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$DSYMUTIL"; then
+ ac_cv_prog_DSYMUTIL="$DSYMUTIL" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+ ac_cv_prog_DSYMUTIL="${ac_tool_prefix}dsymutil"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+fi
+fi
+DSYMUTIL=$ac_cv_prog_DSYMUTIL
+if test -n "$DSYMUTIL"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $DSYMUTIL" >&5
+$as_echo "$DSYMUTIL" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+fi
+if test -z "$ac_cv_prog_DSYMUTIL"; then
+ ac_ct_DSYMUTIL=$DSYMUTIL
+ # Extract the first word of "dsymutil", so it can be a program name with args.
+set dummy dsymutil; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if test "${ac_cv_prog_ac_ct_DSYMUTIL+set}" = set; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$ac_ct_DSYMUTIL"; then
+ ac_cv_prog_ac_ct_DSYMUTIL="$ac_ct_DSYMUTIL" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+ ac_cv_prog_ac_ct_DSYMUTIL="dsymutil"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+fi
+fi
+ac_ct_DSYMUTIL=$ac_cv_prog_ac_ct_DSYMUTIL
+if test -n "$ac_ct_DSYMUTIL"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_DSYMUTIL" >&5
+$as_echo "$ac_ct_DSYMUTIL" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+ if test "x$ac_ct_DSYMUTIL" = x; then
+ DSYMUTIL=":"
+ else
+ case $cross_compiling:$ac_tool_warned in
+yes:)
+{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
+$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
+ac_tool_warned=yes ;;
+esac
+ DSYMUTIL=$ac_ct_DSYMUTIL
+ fi
+else
+ DSYMUTIL="$ac_cv_prog_DSYMUTIL"
+fi
+
+ if test -n "$ac_tool_prefix"; then
+ # Extract the first word of "${ac_tool_prefix}nmedit", so it can be a program name with args.
+set dummy ${ac_tool_prefix}nmedit; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if test "${ac_cv_prog_NMEDIT+set}" = set; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$NMEDIT"; then
+ ac_cv_prog_NMEDIT="$NMEDIT" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+ ac_cv_prog_NMEDIT="${ac_tool_prefix}nmedit"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+fi
+fi
+NMEDIT=$ac_cv_prog_NMEDIT
+if test -n "$NMEDIT"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $NMEDIT" >&5
+$as_echo "$NMEDIT" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+fi
+if test -z "$ac_cv_prog_NMEDIT"; then
+ ac_ct_NMEDIT=$NMEDIT
+ # Extract the first word of "nmedit", so it can be a program name with args.
+set dummy nmedit; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if test "${ac_cv_prog_ac_ct_NMEDIT+set}" = set; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$ac_ct_NMEDIT"; then
+ ac_cv_prog_ac_ct_NMEDIT="$ac_ct_NMEDIT" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+ ac_cv_prog_ac_ct_NMEDIT="nmedit"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+fi
+fi
+ac_ct_NMEDIT=$ac_cv_prog_ac_ct_NMEDIT
+if test -n "$ac_ct_NMEDIT"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_NMEDIT" >&5
+$as_echo "$ac_ct_NMEDIT" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+ if test "x$ac_ct_NMEDIT" = x; then
+ NMEDIT=":"
+ else
+ case $cross_compiling:$ac_tool_warned in
+yes:)
+{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
+$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
+ac_tool_warned=yes ;;
+esac
+ NMEDIT=$ac_ct_NMEDIT
+ fi
+else
+ NMEDIT="$ac_cv_prog_NMEDIT"
+fi
+
+ if test -n "$ac_tool_prefix"; then
+ # Extract the first word of "${ac_tool_prefix}lipo", so it can be a program name with args.
+set dummy ${ac_tool_prefix}lipo; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if test "${ac_cv_prog_LIPO+set}" = set; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$LIPO"; then
+ ac_cv_prog_LIPO="$LIPO" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+ ac_cv_prog_LIPO="${ac_tool_prefix}lipo"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+fi
+fi
+LIPO=$ac_cv_prog_LIPO
+if test -n "$LIPO"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $LIPO" >&5
+$as_echo "$LIPO" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+fi
+if test -z "$ac_cv_prog_LIPO"; then
+ ac_ct_LIPO=$LIPO
+ # Extract the first word of "lipo", so it can be a program name with args.
+set dummy lipo; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if test "${ac_cv_prog_ac_ct_LIPO+set}" = set; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$ac_ct_LIPO"; then
+ ac_cv_prog_ac_ct_LIPO="$ac_ct_LIPO" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+ ac_cv_prog_ac_ct_LIPO="lipo"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+fi
+fi
+ac_ct_LIPO=$ac_cv_prog_ac_ct_LIPO
+if test -n "$ac_ct_LIPO"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_LIPO" >&5
+$as_echo "$ac_ct_LIPO" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+ if test "x$ac_ct_LIPO" = x; then
+ LIPO=":"
+ else
+ case $cross_compiling:$ac_tool_warned in
+yes:)
+{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
+$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
+ac_tool_warned=yes ;;
+esac
+ LIPO=$ac_ct_LIPO
+ fi
+else
+ LIPO="$ac_cv_prog_LIPO"
+fi
+
+ if test -n "$ac_tool_prefix"; then
+ # Extract the first word of "${ac_tool_prefix}otool", so it can be a program name with args.
+set dummy ${ac_tool_prefix}otool; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if test "${ac_cv_prog_OTOOL+set}" = set; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$OTOOL"; then
+ ac_cv_prog_OTOOL="$OTOOL" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+ ac_cv_prog_OTOOL="${ac_tool_prefix}otool"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+fi
+fi
+OTOOL=$ac_cv_prog_OTOOL
+if test -n "$OTOOL"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $OTOOL" >&5
+$as_echo "$OTOOL" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+fi
+if test -z "$ac_cv_prog_OTOOL"; then
+ ac_ct_OTOOL=$OTOOL
+ # Extract the first word of "otool", so it can be a program name with args.
+set dummy otool; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if test "${ac_cv_prog_ac_ct_OTOOL+set}" = set; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$ac_ct_OTOOL"; then
+ ac_cv_prog_ac_ct_OTOOL="$ac_ct_OTOOL" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+ ac_cv_prog_ac_ct_OTOOL="otool"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+fi
+fi
+ac_ct_OTOOL=$ac_cv_prog_ac_ct_OTOOL
+if test -n "$ac_ct_OTOOL"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_OTOOL" >&5
+$as_echo "$ac_ct_OTOOL" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+ if test "x$ac_ct_OTOOL" = x; then
+ OTOOL=":"
+ else
+ case $cross_compiling:$ac_tool_warned in
+yes:)
+{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
+$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
+ac_tool_warned=yes ;;
+esac
+ OTOOL=$ac_ct_OTOOL
+ fi
+else
+ OTOOL="$ac_cv_prog_OTOOL"
+fi
+
+ if test -n "$ac_tool_prefix"; then
+ # Extract the first word of "${ac_tool_prefix}otool64", so it can be a program name with args.
+set dummy ${ac_tool_prefix}otool64; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if test "${ac_cv_prog_OTOOL64+set}" = set; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$OTOOL64"; then
+ ac_cv_prog_OTOOL64="$OTOOL64" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+ ac_cv_prog_OTOOL64="${ac_tool_prefix}otool64"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+fi
+fi
+OTOOL64=$ac_cv_prog_OTOOL64
+if test -n "$OTOOL64"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $OTOOL64" >&5
+$as_echo "$OTOOL64" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+fi
+if test -z "$ac_cv_prog_OTOOL64"; then
+ ac_ct_OTOOL64=$OTOOL64
+ # Extract the first word of "otool64", so it can be a program name with args.
+set dummy otool64; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if test "${ac_cv_prog_ac_ct_OTOOL64+set}" = set; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$ac_ct_OTOOL64"; then
+ ac_cv_prog_ac_ct_OTOOL64="$ac_ct_OTOOL64" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+ ac_cv_prog_ac_ct_OTOOL64="otool64"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+fi
+fi
+ac_ct_OTOOL64=$ac_cv_prog_ac_ct_OTOOL64
+if test -n "$ac_ct_OTOOL64"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_OTOOL64" >&5
+$as_echo "$ac_ct_OTOOL64" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+ if test "x$ac_ct_OTOOL64" = x; then
+ OTOOL64=":"
+ else
+ case $cross_compiling:$ac_tool_warned in
+yes:)
+{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
+$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
+ac_tool_warned=yes ;;
+esac
+ OTOOL64=$ac_ct_OTOOL64
+ fi
+else
+ OTOOL64="$ac_cv_prog_OTOOL64"
+fi
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for -single_module linker flag" >&5
+$as_echo_n "checking for -single_module linker flag... " >&6; }
+if test "${lt_cv_apple_cc_single_mod+set}" = set; then :
+ $as_echo_n "(cached) " >&6
+else
+ lt_cv_apple_cc_single_mod=no
+ if test -z "${LT_MULTI_MODULE}"; then
+ # By default we will add the -single_module flag. You can override
+ # by either setting the environment variable LT_MULTI_MODULE
+ # non-empty at configure time, or by adding -multi_module to the
+ # link flags.
+ rm -rf libconftest.dylib*
+ echo "int foo(void){return 1;}" > conftest.c
+ echo "$LTCC $LTCFLAGS $LDFLAGS -o libconftest.dylib \
+-dynamiclib -Wl,-single_module conftest.c" >&5
+ $LTCC $LTCFLAGS $LDFLAGS -o libconftest.dylib \
+ -dynamiclib -Wl,-single_module conftest.c 2>conftest.err
+ _lt_result=$?
+ if test -f libconftest.dylib && test ! -s conftest.err && test $_lt_result = 0; then
+ lt_cv_apple_cc_single_mod=yes
+ else
+ cat conftest.err >&5
+ fi
+ rm -rf libconftest.dylib*
+ rm -f conftest.*
+ fi
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_apple_cc_single_mod" >&5
+$as_echo "$lt_cv_apple_cc_single_mod" >&6; }
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for -exported_symbols_list linker flag" >&5
+$as_echo_n "checking for -exported_symbols_list linker flag... " >&6; }
+if test "${lt_cv_ld_exported_symbols_list+set}" = set; then :
+ $as_echo_n "(cached) " >&6
+else
+ lt_cv_ld_exported_symbols_list=no
+ save_LDFLAGS=$LDFLAGS
+ echo "_main" > conftest.sym
+ LDFLAGS="$LDFLAGS -Wl,-exported_symbols_list,conftest.sym"
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+int
+main ()
+{
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+ lt_cv_ld_exported_symbols_list=yes
+else
+ lt_cv_ld_exported_symbols_list=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+ LDFLAGS="$save_LDFLAGS"
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_ld_exported_symbols_list" >&5
+$as_echo "$lt_cv_ld_exported_symbols_list" >&6; }
+ case $host_os in
+ rhapsody* | darwin1.[012])
+ _lt_dar_allow_undefined='${wl}-undefined ${wl}suppress' ;;
+ darwin1.*)
+ _lt_dar_allow_undefined='${wl}-flat_namespace ${wl}-undefined ${wl}suppress' ;;
+ darwin*) # darwin 5.x on
+ # if running on 10.5 or later, the deployment target defaults
+ # to the OS version, if on x86, and 10.4, the deployment
+ # target defaults to 10.4. Don't you love it?
+ case ${MACOSX_DEPLOYMENT_TARGET-10.0},$host in
+ 10.0,*86*-darwin8*|10.0,*-darwin[91]*)
+ _lt_dar_allow_undefined='${wl}-undefined ${wl}dynamic_lookup' ;;
+ 10.[012]*)
+ _lt_dar_allow_undefined='${wl}-flat_namespace ${wl}-undefined ${wl}suppress' ;;
+ 10.*)
+ _lt_dar_allow_undefined='${wl}-undefined ${wl}dynamic_lookup' ;;
+ esac
+ ;;
+ esac
+ if test "$lt_cv_apple_cc_single_mod" = "yes"; then
+ _lt_dar_single_mod='$single_module'
+ fi
+ if test "$lt_cv_ld_exported_symbols_list" = "yes"; then
+ _lt_dar_export_syms=' ${wl}-exported_symbols_list,$output_objdir/${libname}-symbols.expsym'
+ else
+ _lt_dar_export_syms='~$NMEDIT -s $output_objdir/${libname}-symbols.expsym ${lib}'
+ fi
+ if test "$DSYMUTIL" != ":"; then
+ _lt_dsymutil='~$DSYMUTIL $lib || :'
+ else
+ _lt_dsymutil=
+ fi
+ ;;
+ esac
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for ANSI C header files" >&5
+$as_echo_n "checking for ANSI C header files... " >&6; }
+if test "${ac_cv_header_stdc+set}" = set; then :
+ $as_echo_n "(cached) " >&6
+else
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#include <stdlib.h>
+#include <stdarg.h>
+#include <string.h>
+#include <float.h>
+
+int
+main ()
+{
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+ ac_cv_header_stdc=yes
+else
+ ac_cv_header_stdc=no
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+
+if test $ac_cv_header_stdc = yes; then
+ # SunOS 4.x string.h does not declare mem*, contrary to ANSI.
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#include <string.h>
+
+_ACEOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+ $EGREP "memchr" >/dev/null 2>&1; then :
+
+else
+ ac_cv_header_stdc=no
+fi
+rm -f conftest*
+
+fi
+
+if test $ac_cv_header_stdc = yes; then
+ # ISC 2.0.2 stdlib.h does not declare free, contrary to ANSI.
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#include <stdlib.h>
+
+_ACEOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+ $EGREP "free" >/dev/null 2>&1; then :
+
+else
+ ac_cv_header_stdc=no
+fi
+rm -f conftest*
+
+fi
+
+if test $ac_cv_header_stdc = yes; then
+ # /bin/cc in Irix-4.0.5 gets non-ANSI ctype macros unless using -ansi.
+ if test "$cross_compiling" = yes; then :
+ :
+else
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#include <ctype.h>
+#include <stdlib.h>
+#if ((' ' & 0x0FF) == 0x020)
+# define ISLOWER(c) ('a' <= (c) && (c) <= 'z')
+# define TOUPPER(c) (ISLOWER(c) ? 'A' + ((c) - 'a') : (c))
+#else
+# define ISLOWER(c) \
+ (('a' <= (c) && (c) <= 'i') \
+ || ('j' <= (c) && (c) <= 'r') \
+ || ('s' <= (c) && (c) <= 'z'))
+# define TOUPPER(c) (ISLOWER(c) ? ((c) | 0x40) : (c))
+#endif
+
+#define XOR(e, f) (((e) && !(f)) || (!(e) && (f)))
+int
+main ()
+{
+ int i;
+ for (i = 0; i < 256; i++)
+ if (XOR (islower (i), ISLOWER (i))
+ || toupper (i) != TOUPPER (i))
+ return 2;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_run "$LINENO"; then :
+
+else
+ ac_cv_header_stdc=no
+fi
+rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \
+ conftest.$ac_objext conftest.beam conftest.$ac_ext
+fi
+
+fi
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_header_stdc" >&5
+$as_echo "$ac_cv_header_stdc" >&6; }
+if test $ac_cv_header_stdc = yes; then
+
+$as_echo "#define STDC_HEADERS 1" >>confdefs.h
+
+fi
+
+# On IRIX 5.3, sys/types and inttypes.h are conflicting.
+for ac_header in sys/types.h sys/stat.h stdlib.h string.h memory.h strings.h \
+ inttypes.h stdint.h unistd.h
+do :
+ as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh`
+ac_fn_c_check_header_compile "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default
+"
+if eval test \"x\$"$as_ac_Header"\" = x"yes"; then :
+ cat >>confdefs.h <<_ACEOF
+#define `$as_echo "HAVE_$ac_header" | $as_tr_cpp` 1
+_ACEOF
+
+fi
+
+done
+
+
+for ac_header in dlfcn.h
+do :
+ ac_fn_c_check_header_compile "$LINENO" "dlfcn.h" "ac_cv_header_dlfcn_h" "$ac_includes_default
+"
+if test "x$ac_cv_header_dlfcn_h" = x""yes; then :
+ cat >>confdefs.h <<_ACEOF
+#define HAVE_DLFCN_H 1
+_ACEOF
+
+fi
+
+done
+
+
+
+# Set options
+
+
+
+ enable_dlopen=no
+
+
+ enable_win32_dll=no
+
+
+ # Check whether --enable-shared was given.
+if test "${enable_shared+set}" = set; then :
+ enableval=$enable_shared; p=${PACKAGE-default}
+ case $enableval in
+ yes) enable_shared=yes ;;
+ no) enable_shared=no ;;
+ *)
+ enable_shared=no
+ # Look at the argument we got. We use all the common list separators.
+ lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR,"
+ for pkg in $enableval; do
+ IFS="$lt_save_ifs"
+ if test "X$pkg" = "X$p"; then
+ enable_shared=yes
+ fi
+ done
+ IFS="$lt_save_ifs"
+ ;;
+ esac
+else
+ enable_shared=yes
+fi
+
+
+
+
+
+
+
+
+
+ # Check whether --enable-static was given.
+if test "${enable_static+set}" = set; then :
+ enableval=$enable_static; p=${PACKAGE-default}
+ case $enableval in
+ yes) enable_static=yes ;;
+ no) enable_static=no ;;
+ *)
+ enable_static=no
+ # Look at the argument we got. We use all the common list separators.
+ lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR,"
+ for pkg in $enableval; do
+ IFS="$lt_save_ifs"
+ if test "X$pkg" = "X$p"; then
+ enable_static=yes
+ fi
+ done
+ IFS="$lt_save_ifs"
+ ;;
+ esac
+else
+ enable_static=yes
+fi
+
+
+
+
+
+
+
+
+
+
+# Check whether --with-pic was given.
+if test "${with_pic+set}" = set; then :
+ withval=$with_pic; pic_mode="$withval"
+else
+ pic_mode=default
+fi
+
+
+test -z "$pic_mode" && pic_mode=default
+
+
+
+
+
+
+
+ # Check whether --enable-fast-install was given.
+if test "${enable_fast_install+set}" = set; then :
+ enableval=$enable_fast_install; p=${PACKAGE-default}
+ case $enableval in
+ yes) enable_fast_install=yes ;;
+ no) enable_fast_install=no ;;
+ *)
+ enable_fast_install=no
+ # Look at the argument we got. We use all the common list separators.
+ lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR,"
+ for pkg in $enableval; do
+ IFS="$lt_save_ifs"
+ if test "X$pkg" = "X$p"; then
+ enable_fast_install=yes
+ fi
+ done
+ IFS="$lt_save_ifs"
+ ;;
+ esac
+else
+ enable_fast_install=yes
+fi
+
+
+
+
+
+
+
+
+
+
+
+# This can be used to rebuild libtool when needed
+LIBTOOL_DEPS="$ltmain"
+
+# Always use our own libtool.
+LIBTOOL='$(SHELL) $(top_builddir)/libtool'
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+test -z "$LN_S" && LN_S="ln -s"
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+if test -n "${ZSH_VERSION+set}" ; then
+ setopt NO_GLOB_SUBST
+fi
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for objdir" >&5
+$as_echo_n "checking for objdir... " >&6; }
+if test "${lt_cv_objdir+set}" = set; then :
+ $as_echo_n "(cached) " >&6
+else
+ rm -f .libs 2>/dev/null
+mkdir .libs 2>/dev/null
+if test -d .libs; then
+ lt_cv_objdir=.libs
+else
+ # MS-DOS does not allow filenames that begin with a dot.
+ lt_cv_objdir=_libs
+fi
+rmdir .libs 2>/dev/null
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_objdir" >&5
+$as_echo "$lt_cv_objdir" >&6; }
+objdir=$lt_cv_objdir
+
+
+
+
+
+cat >>confdefs.h <<_ACEOF
+#define LT_OBJDIR "$lt_cv_objdir/"
+_ACEOF
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+case $host_os in
+aix3*)
+ # AIX sometimes has problems with the GCC collect2 program. For some
+ # reason, if we set the COLLECT_NAMES environment variable, the problems
+ # vanish in a puff of smoke.
+ if test "X${COLLECT_NAMES+set}" != Xset; then
+ COLLECT_NAMES=
+ export COLLECT_NAMES
+ fi
+ ;;
+esac
+
+# Sed substitution that helps us do robust quoting. It backslashifies
+# metacharacters that are still active within double-quoted strings.
+sed_quote_subst='s/\(["`$\\]\)/\\\1/g'
+
+# Same as above, but do not quote variable references.
+double_quote_subst='s/\(["`\\]\)/\\\1/g'
+
+# Sed substitution to delay expansion of an escaped shell variable in a
+# double_quote_subst'ed string.
+delay_variable_subst='s/\\\\\\\\\\\$/\\\\\\$/g'
+
+# Sed substitution to delay expansion of an escaped single quote.
+delay_single_quote_subst='s/'\''/'\'\\\\\\\'\''/g'
+
+# Sed substitution to avoid accidental globbing in evaled expressions
+no_glob_subst='s/\*/\\\*/g'
+
+# Global variables:
+ofile=libtool
+can_build_shared=yes
+
+# All known linkers require a `.a' archive for static linking (except MSVC,
+# which needs '.lib').
+libext=a
+
+with_gnu_ld="$lt_cv_prog_gnu_ld"
+
+old_CC="$CC"
+old_CFLAGS="$CFLAGS"
+
+# Set sane defaults for various variables
+test -z "$CC" && CC=cc
+test -z "$LTCC" && LTCC=$CC
+test -z "$LTCFLAGS" && LTCFLAGS=$CFLAGS
+test -z "$LD" && LD=ld
+test -z "$ac_objext" && ac_objext=o
+
+for cc_temp in $compiler""; do
+ case $cc_temp in
+ compile | *[\\/]compile | ccache | *[\\/]ccache ) ;;
+ distcc | *[\\/]distcc | purify | *[\\/]purify ) ;;
+ \-*) ;;
+ *) break;;
+ esac
+done
+cc_basename=`$ECHO "X$cc_temp" | $Xsed -e 's%.*/%%' -e "s%^$host_alias-%%"`
+
+
+# Only perform the check for file, if the check method requires it
+test -z "$MAGIC_CMD" && MAGIC_CMD=file
+case $deplibs_check_method in
+file_magic*)
+ if test "$file_magic_cmd" = '$MAGIC_CMD'; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for ${ac_tool_prefix}file" >&5
+$as_echo_n "checking for ${ac_tool_prefix}file... " >&6; }
+if test "${lt_cv_path_MAGIC_CMD+set}" = set; then :
+ $as_echo_n "(cached) " >&6
+else
+ case $MAGIC_CMD in
+[\\/*] | ?:[\\/]*)
+ lt_cv_path_MAGIC_CMD="$MAGIC_CMD" # Let the user override the test with a path.
+ ;;
+*)
+ lt_save_MAGIC_CMD="$MAGIC_CMD"
+ lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR
+ ac_dummy="/usr/bin$PATH_SEPARATOR$PATH"
+ for ac_dir in $ac_dummy; do
+ IFS="$lt_save_ifs"
+ test -z "$ac_dir" && ac_dir=.
+ if test -f $ac_dir/${ac_tool_prefix}file; then
+ lt_cv_path_MAGIC_CMD="$ac_dir/${ac_tool_prefix}file"
+ if test -n "$file_magic_test_file"; then
+ case $deplibs_check_method in
+ "file_magic "*)
+ file_magic_regex=`expr "$deplibs_check_method" : "file_magic \(.*\)"`
+ MAGIC_CMD="$lt_cv_path_MAGIC_CMD"
+ if eval $file_magic_cmd \$file_magic_test_file 2> /dev/null |
+ $EGREP "$file_magic_regex" > /dev/null; then
+ :
+ else
+ cat <<_LT_EOF 1>&2
+
+*** Warning: the command libtool uses to detect shared libraries,
+*** $file_magic_cmd, produces output that libtool cannot recognize.
+*** The result is that libtool may fail to recognize shared libraries
+*** as such. This will affect the creation of libtool libraries that
+*** depend on shared libraries, but programs linked with such libtool
+*** libraries will work regardless of this problem. Nevertheless, you
+*** may want to report the problem to your system manager and/or to
+*** bug-libtool@gnu.org
+
+_LT_EOF
+ fi ;;
+ esac
+ fi
+ break
+ fi
+ done
+ IFS="$lt_save_ifs"
+ MAGIC_CMD="$lt_save_MAGIC_CMD"
+ ;;
+esac
+fi
+
+MAGIC_CMD="$lt_cv_path_MAGIC_CMD"
+if test -n "$MAGIC_CMD"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $MAGIC_CMD" >&5
+$as_echo "$MAGIC_CMD" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+
+
+
+if test -z "$lt_cv_path_MAGIC_CMD"; then
+ if test -n "$ac_tool_prefix"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for file" >&5
+$as_echo_n "checking for file... " >&6; }
+if test "${lt_cv_path_MAGIC_CMD+set}" = set; then :
+ $as_echo_n "(cached) " >&6
+else
+ case $MAGIC_CMD in
+[\\/*] | ?:[\\/]*)
+ lt_cv_path_MAGIC_CMD="$MAGIC_CMD" # Let the user override the test with a path.
+ ;;
+*)
+ lt_save_MAGIC_CMD="$MAGIC_CMD"
+ lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR
+ ac_dummy="/usr/bin$PATH_SEPARATOR$PATH"
+ for ac_dir in $ac_dummy; do
+ IFS="$lt_save_ifs"
+ test -z "$ac_dir" && ac_dir=.
+ if test -f $ac_dir/file; then
+ lt_cv_path_MAGIC_CMD="$ac_dir/file"
+ if test -n "$file_magic_test_file"; then
+ case $deplibs_check_method in
+ "file_magic "*)
+ file_magic_regex=`expr "$deplibs_check_method" : "file_magic \(.*\)"`
+ MAGIC_CMD="$lt_cv_path_MAGIC_CMD"
+ if eval $file_magic_cmd \$file_magic_test_file 2> /dev/null |
+ $EGREP "$file_magic_regex" > /dev/null; then
+ :
+ else
+ cat <<_LT_EOF 1>&2
+
+*** Warning: the command libtool uses to detect shared libraries,
+*** $file_magic_cmd, produces output that libtool cannot recognize.
+*** The result is that libtool may fail to recognize shared libraries
+*** as such. This will affect the creation of libtool libraries that
+*** depend on shared libraries, but programs linked with such libtool
+*** libraries will work regardless of this problem. Nevertheless, you
+*** may want to report the problem to your system manager and/or to
+*** bug-libtool@gnu.org
+
+_LT_EOF
+ fi ;;
+ esac
+ fi
+ break
+ fi
+ done
+ IFS="$lt_save_ifs"
+ MAGIC_CMD="$lt_save_MAGIC_CMD"
+ ;;
+esac
+fi
+
+MAGIC_CMD="$lt_cv_path_MAGIC_CMD"
+if test -n "$MAGIC_CMD"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $MAGIC_CMD" >&5
+$as_echo "$MAGIC_CMD" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+ else
+ MAGIC_CMD=:
+ fi
+fi
+
+ fi
+ ;;
+esac
+
+# Use C for the default configuration in the libtool script
+
+lt_save_CC="$CC"
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+
+# Source file extension for C test sources.
+ac_ext=c
+
+# Object file extension for compiled C test sources.
+objext=o
+objext=$objext
+
+# Code to be used in simple compile tests
+lt_simple_compile_test_code="int some_variable = 0;"
+
+# Code to be used in simple link tests
+lt_simple_link_test_code='int main(){return(0);}'
+
+
+
+
+
+
+
+# If no C compiler was specified, use CC.
+LTCC=${LTCC-"$CC"}
+
+# If no C compiler flags were specified, use CFLAGS.
+LTCFLAGS=${LTCFLAGS-"$CFLAGS"}
+
+# Allow CC to be a program name with arguments.
+compiler=$CC
+
+# Save the default compiler, since it gets overwritten when the other
+# tags are being tested, and _LT_TAGVAR(compiler, []) is a NOP.
+compiler_DEFAULT=$CC
+
+# save warnings/boilerplate of simple test code
+ac_outfile=conftest.$ac_objext
+echo "$lt_simple_compile_test_code" >conftest.$ac_ext
+eval "$ac_compile" 2>&1 >/dev/null | $SED '/^$/d; /^ *+/d' >conftest.err
+_lt_compiler_boilerplate=`cat conftest.err`
+$RM conftest*
+
+ac_outfile=conftest.$ac_objext
+echo "$lt_simple_link_test_code" >conftest.$ac_ext
+eval "$ac_link" 2>&1 >/dev/null | $SED '/^$/d; /^ *+/d' >conftest.err
+_lt_linker_boilerplate=`cat conftest.err`
+$RM -r conftest*
+
+
+if test -n "$compiler"; then
+
+lt_prog_compiler_no_builtin_flag=
+
+if test "$GCC" = yes; then
+ lt_prog_compiler_no_builtin_flag=' -fno-builtin'
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $compiler supports -fno-rtti -fno-exceptions" >&5
+$as_echo_n "checking if $compiler supports -fno-rtti -fno-exceptions... " >&6; }
+if test "${lt_cv_prog_compiler_rtti_exceptions+set}" = set; then :
+ $as_echo_n "(cached) " >&6
+else
+ lt_cv_prog_compiler_rtti_exceptions=no
+ ac_outfile=conftest.$ac_objext
+ echo "$lt_simple_compile_test_code" > conftest.$ac_ext
+ lt_compiler_flag="-fno-rtti -fno-exceptions"
+ # Insert the option either (1) after the last *FLAGS variable, or
+ # (2) before a word containing "conftest.", or (3) at the end.
+ # Note that $ac_compile itself does not contain backslashes and begins
+ # with a dollar sign (not a hyphen), so the echo should work correctly.
+ # The option is referenced via a variable to avoid confusing sed.
+ lt_compile=`echo "$ac_compile" | $SED \
+ -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
+ -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
+ -e 's:$: $lt_compiler_flag:'`
+ (eval echo "\"\$as_me:7327: $lt_compile\"" >&5)
+ (eval "$lt_compile" 2>conftest.err)
+ ac_status=$?
+ cat conftest.err >&5
+ echo "$as_me:7331: \$? = $ac_status" >&5
+ if (exit $ac_status) && test -s "$ac_outfile"; then
+ # The compiler can only warn and ignore the option if not recognized
+ # So say no if there are warnings other than the usual output.
+ $ECHO "X$_lt_compiler_boilerplate" | $Xsed -e '/^$/d' >conftest.exp
+ $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2
+ if test ! -s conftest.er2 || diff conftest.exp conftest.er2 >/dev/null; then
+ lt_cv_prog_compiler_rtti_exceptions=yes
+ fi
+ fi
+ $RM conftest*
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_rtti_exceptions" >&5
+$as_echo "$lt_cv_prog_compiler_rtti_exceptions" >&6; }
+
+if test x"$lt_cv_prog_compiler_rtti_exceptions" = xyes; then
+ lt_prog_compiler_no_builtin_flag="$lt_prog_compiler_no_builtin_flag -fno-rtti -fno-exceptions"
+else
+ :
+fi
+
+fi
+
+
+
+
+
+
+ lt_prog_compiler_wl=
+lt_prog_compiler_pic=
+lt_prog_compiler_static=
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $compiler option to produce PIC" >&5
+$as_echo_n "checking for $compiler option to produce PIC... " >&6; }
+
+ if test "$GCC" = yes; then
+ lt_prog_compiler_wl='-Wl,'
+ lt_prog_compiler_static='-static'
+
+ case $host_os in
+ aix*)
+ # All AIX code is PIC.
+ if test "$host_cpu" = ia64; then
+ # AIX 5 now supports IA64 processor
+ lt_prog_compiler_static='-Bstatic'
+ fi
+ ;;
+
+ amigaos*)
+ case $host_cpu in
+ powerpc)
+ # see comment about AmigaOS4 .so support
+ lt_prog_compiler_pic='-fPIC'
+ ;;
+ m68k)
+ # FIXME: we need at least 68020 code to build shared libraries, but
+ # adding the `-m68020' flag to GCC prevents building anything better,
+ # like `-m68040'.
+ lt_prog_compiler_pic='-m68020 -resident32 -malways-restore-a4'
+ ;;
+ esac
+ ;;
+
+ beos* | irix5* | irix6* | nonstopux* | osf3* | osf4* | osf5*)
+ # PIC is the default for these OSes.
+ ;;
+
+ mingw* | cygwin* | pw32* | os2* | cegcc*)
+ # This hack is so that the source file can tell whether it is being
+ # built for inclusion in a dll (and should export symbols for example).
+ # Although the cygwin gcc ignores -fPIC, still need this for old-style
+ # (--disable-auto-import) libraries
+ lt_prog_compiler_pic='-DDLL_EXPORT'
+ ;;
+
+ darwin* | rhapsody*)
+ # PIC is the default on this platform
+ # Common symbols not allowed in MH_DYLIB files
+ lt_prog_compiler_pic='-fno-common'
+ ;;
+
+ hpux*)
+ # PIC is the default for 64-bit PA HP-UX, but not for 32-bit
+ # PA HP-UX. On IA64 HP-UX, PIC is the default but the pic flag
+ # sets the default TLS model and affects inlining.
+ case $host_cpu in
+ hppa*64*)
+ # +Z the default
+ ;;
+ *)
+ lt_prog_compiler_pic='-fPIC'
+ ;;
+ esac
+ ;;
+
+ interix[3-9]*)
+ # Interix 3.x gcc -fpic/-fPIC options generate broken code.
+ # Instead, we relocate shared libraries at runtime.
+ ;;
+
+ msdosdjgpp*)
+ # Just because we use GCC doesn't mean we suddenly get shared libraries
+ # on systems that don't support them.
+ lt_prog_compiler_can_build_shared=no
+ enable_shared=no
+ ;;
+
+ *nto* | *qnx*)
+ # QNX uses GNU C++, but need to define -shared option too, otherwise
+ # it will coredump.
+ lt_prog_compiler_pic='-fPIC -shared'
+ ;;
+
+ sysv4*MP*)
+ if test -d /usr/nec; then
+ lt_prog_compiler_pic=-Kconform_pic
+ fi
+ ;;
+
+ *)
+ lt_prog_compiler_pic='-fPIC'
+ ;;
+ esac
+ else
+ # PORTME Check for flag to pass linker flags through the system compiler.
+ case $host_os in
+ aix*)
+ lt_prog_compiler_wl='-Wl,'
+ if test "$host_cpu" = ia64; then
+ # AIX 5 now supports IA64 processor
+ lt_prog_compiler_static='-Bstatic'
+ else
+ lt_prog_compiler_static='-bnso -bI:/lib/syscalls.exp'
+ fi
+ ;;
+
+ mingw* | cygwin* | pw32* | os2* | cegcc*)
+ # This hack is so that the source file can tell whether it is being
+ # built for inclusion in a dll (and should export symbols for example).
+ lt_prog_compiler_pic='-DDLL_EXPORT'
+ ;;
+
+ hpux9* | hpux10* | hpux11*)
+ lt_prog_compiler_wl='-Wl,'
+ # PIC is the default for IA64 HP-UX and 64-bit HP-UX, but
+ # not for PA HP-UX.
+ case $host_cpu in
+ hppa*64*|ia64*)
+ # +Z the default
+ ;;
+ *)
+ lt_prog_compiler_pic='+Z'
+ ;;
+ esac
+ # Is there a better lt_prog_compiler_static that works with the bundled CC?
+ lt_prog_compiler_static='${wl}-a ${wl}archive'
+ ;;
+
+ irix5* | irix6* | nonstopux*)
+ lt_prog_compiler_wl='-Wl,'
+ # PIC (with -KPIC) is the default.
+ lt_prog_compiler_static='-non_shared'
+ ;;
+
+ linux* | k*bsd*-gnu | kopensolaris*-gnu)
+ case $cc_basename in
+ # old Intel for x86_64 which still supported -KPIC.
+ ecc*)
+ lt_prog_compiler_wl='-Wl,'
+ lt_prog_compiler_pic='-KPIC'
+ lt_prog_compiler_static='-static'
+ ;;
+ # icc used to be incompatible with GCC.
+ # ICC 10 doesn't accept -KPIC any more.
+ icc* | ifort*)
+ lt_prog_compiler_wl='-Wl,'
+ lt_prog_compiler_pic='-fPIC'
+ lt_prog_compiler_static='-static'
+ ;;
+ # Lahey Fortran 8.1.
+ lf95*)
+ lt_prog_compiler_wl='-Wl,'
+ lt_prog_compiler_pic='--shared'
+ lt_prog_compiler_static='--static'
+ ;;
+ pgcc* | pgf77* | pgf90* | pgf95*)
+ # Portland Group compilers (*not* the Pentium gcc compiler,
+ # which looks to be a dead project)
+ lt_prog_compiler_wl='-Wl,'
+ lt_prog_compiler_pic='-fpic'
+ lt_prog_compiler_static='-Bstatic'
+ ;;
+ ccc*)
+ lt_prog_compiler_wl='-Wl,'
+ # All Alpha code is PIC.
+ lt_prog_compiler_static='-non_shared'
+ ;;
+ xl*)
+ # IBM XL C 8.0/Fortran 10.1 on PPC
+ lt_prog_compiler_wl='-Wl,'
+ lt_prog_compiler_pic='-qpic'
+ lt_prog_compiler_static='-qstaticlink'
+ ;;
+ *)
+ case `$CC -V 2>&1 | sed 5q` in
+ *Sun\ C*)
+ # Sun C 5.9
+ lt_prog_compiler_pic='-KPIC'
+ lt_prog_compiler_static='-Bstatic'
+ lt_prog_compiler_wl='-Wl,'
+ ;;
+ *Sun\ F*)
+ # Sun Fortran 8.3 passes all unrecognized flags to the linker
+ lt_prog_compiler_pic='-KPIC'
+ lt_prog_compiler_static='-Bstatic'
+ lt_prog_compiler_wl=''
+ ;;
+ esac
+ ;;
+ esac
+ ;;
+
+ newsos6)
+ lt_prog_compiler_pic='-KPIC'
+ lt_prog_compiler_static='-Bstatic'
+ ;;
+
+ *nto* | *qnx*)
+ # QNX uses GNU C++, but need to define -shared option too, otherwise
+ # it will coredump.
+ lt_prog_compiler_pic='-fPIC -shared'
+ ;;
+
+ osf3* | osf4* | osf5*)
+ lt_prog_compiler_wl='-Wl,'
+ # All OSF/1 code is PIC.
+ lt_prog_compiler_static='-non_shared'
+ ;;
+
+ rdos*)
+ lt_prog_compiler_static='-non_shared'
+ ;;
+
+ solaris*)
+ lt_prog_compiler_pic='-KPIC'
+ lt_prog_compiler_static='-Bstatic'
+ case $cc_basename in
+ f77* | f90* | f95*)
+ lt_prog_compiler_wl='-Qoption ld ';;
+ *)
+ lt_prog_compiler_wl='-Wl,';;
+ esac
+ ;;
+
+ sunos4*)
+ lt_prog_compiler_wl='-Qoption ld '
+ lt_prog_compiler_pic='-PIC'
+ lt_prog_compiler_static='-Bstatic'
+ ;;
+
+ sysv4 | sysv4.2uw2* | sysv4.3*)
+ lt_prog_compiler_wl='-Wl,'
+ lt_prog_compiler_pic='-KPIC'
+ lt_prog_compiler_static='-Bstatic'
+ ;;
+
+ sysv4*MP*)
+ if test -d /usr/nec ;then
+ lt_prog_compiler_pic='-Kconform_pic'
+ lt_prog_compiler_static='-Bstatic'
+ fi
+ ;;
+
+ sysv5* | unixware* | sco3.2v5* | sco5v6* | OpenUNIX*)
+ lt_prog_compiler_wl='-Wl,'
+ lt_prog_compiler_pic='-KPIC'
+ lt_prog_compiler_static='-Bstatic'
+ ;;
+
+ unicos*)
+ lt_prog_compiler_wl='-Wl,'
+ lt_prog_compiler_can_build_shared=no
+ ;;
+
+ uts4*)
+ lt_prog_compiler_pic='-pic'
+ lt_prog_compiler_static='-Bstatic'
+ ;;
+
+ *)
+ lt_prog_compiler_can_build_shared=no
+ ;;
+ esac
+ fi
+
+case $host_os in
+ # For platforms which do not support PIC, -DPIC is meaningless:
+ *djgpp*)
+ lt_prog_compiler_pic=
+ ;;
+ *)
+ lt_prog_compiler_pic="$lt_prog_compiler_pic -DPIC"
+ ;;
+esac
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_prog_compiler_pic" >&5
+$as_echo "$lt_prog_compiler_pic" >&6; }
+
+
+
+
+
+
+#
+# Check to make sure the PIC flag actually works.
+#
+if test -n "$lt_prog_compiler_pic"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $compiler PIC flag $lt_prog_compiler_pic works" >&5
+$as_echo_n "checking if $compiler PIC flag $lt_prog_compiler_pic works... " >&6; }
+if test "${lt_cv_prog_compiler_pic_works+set}" = set; then :
+ $as_echo_n "(cached) " >&6
+else
+ lt_cv_prog_compiler_pic_works=no
+ ac_outfile=conftest.$ac_objext
+ echo "$lt_simple_compile_test_code" > conftest.$ac_ext
+ lt_compiler_flag="$lt_prog_compiler_pic -DPIC"
+ # Insert the option either (1) after the last *FLAGS variable, or
+ # (2) before a word containing "conftest.", or (3) at the end.
+ # Note that $ac_compile itself does not contain backslashes and begins
+ # with a dollar sign (not a hyphen), so the echo should work correctly.
+ # The option is referenced via a variable to avoid confusing sed.
+ lt_compile=`echo "$ac_compile" | $SED \
+ -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
+ -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
+ -e 's:$: $lt_compiler_flag:'`
+ (eval echo "\"\$as_me:7666: $lt_compile\"" >&5)
+ (eval "$lt_compile" 2>conftest.err)
+ ac_status=$?
+ cat conftest.err >&5
+ echo "$as_me:7670: \$? = $ac_status" >&5
+ if (exit $ac_status) && test -s "$ac_outfile"; then
+ # The compiler can only warn and ignore the option if not recognized
+ # So say no if there are warnings other than the usual output.
+ $ECHO "X$_lt_compiler_boilerplate" | $Xsed -e '/^$/d' >conftest.exp
+ $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2
+ if test ! -s conftest.er2 || diff conftest.exp conftest.er2 >/dev/null; then
+ lt_cv_prog_compiler_pic_works=yes
+ fi
+ fi
+ $RM conftest*
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_pic_works" >&5
+$as_echo "$lt_cv_prog_compiler_pic_works" >&6; }
+
+if test x"$lt_cv_prog_compiler_pic_works" = xyes; then
+ case $lt_prog_compiler_pic in
+ "" | " "*) ;;
+ *) lt_prog_compiler_pic=" $lt_prog_compiler_pic" ;;
+ esac
+else
+ lt_prog_compiler_pic=
+ lt_prog_compiler_can_build_shared=no
+fi
+
+fi
+
+
+
+
+
+
+#
+# Check to make sure the static flag actually works.
+#
+wl=$lt_prog_compiler_wl eval lt_tmp_static_flag=\"$lt_prog_compiler_static\"
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking if $compiler static flag $lt_tmp_static_flag works" >&5
+$as_echo_n "checking if $compiler static flag $lt_tmp_static_flag works... " >&6; }
+if test "${lt_cv_prog_compiler_static_works+set}" = set; then :
+ $as_echo_n "(cached) " >&6
+else
+ lt_cv_prog_compiler_static_works=no
+ save_LDFLAGS="$LDFLAGS"
+ LDFLAGS="$LDFLAGS $lt_tmp_static_flag"
+ echo "$lt_simple_link_test_code" > conftest.$ac_ext
+ if (eval $ac_link 2>conftest.err) && test -s conftest$ac_exeext; then
+ # The linker can only warn and ignore the option if not recognized
+ # So say no if there are warnings
+ if test -s conftest.err; then
+ # Append any errors to the config.log.
+ cat conftest.err 1>&5
+ $ECHO "X$_lt_linker_boilerplate" | $Xsed -e '/^$/d' > conftest.exp
+ $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2
+ if diff conftest.exp conftest.er2 >/dev/null; then
+ lt_cv_prog_compiler_static_works=yes
+ fi
+ else
+ lt_cv_prog_compiler_static_works=yes
+ fi
+ fi
+ $RM -r conftest*
+ LDFLAGS="$save_LDFLAGS"
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_static_works" >&5
+$as_echo "$lt_cv_prog_compiler_static_works" >&6; }
+
+if test x"$lt_cv_prog_compiler_static_works" = xyes; then
+ :
+else
+ lt_prog_compiler_static=
+fi
+
+
+
+
+
+
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $compiler supports -c -o file.$ac_objext" >&5
+$as_echo_n "checking if $compiler supports -c -o file.$ac_objext... " >&6; }
+if test "${lt_cv_prog_compiler_c_o+set}" = set; then :
+ $as_echo_n "(cached) " >&6
+else
+ lt_cv_prog_compiler_c_o=no
+ $RM -r conftest 2>/dev/null
+ mkdir conftest
+ cd conftest
+ mkdir out
+ echo "$lt_simple_compile_test_code" > conftest.$ac_ext
+
+ lt_compiler_flag="-o out/conftest2.$ac_objext"
+ # Insert the option either (1) after the last *FLAGS variable, or
+ # (2) before a word containing "conftest.", or (3) at the end.
+ # Note that $ac_compile itself does not contain backslashes and begins
+ # with a dollar sign (not a hyphen), so the echo should work correctly.
+ lt_compile=`echo "$ac_compile" | $SED \
+ -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
+ -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
+ -e 's:$: $lt_compiler_flag:'`
+ (eval echo "\"\$as_me:7771: $lt_compile\"" >&5)
+ (eval "$lt_compile" 2>out/conftest.err)
+ ac_status=$?
+ cat out/conftest.err >&5
+ echo "$as_me:7775: \$? = $ac_status" >&5
+ if (exit $ac_status) && test -s out/conftest2.$ac_objext
+ then
+ # The compiler can only warn and ignore the option if not recognized
+ # So say no if there are warnings
+ $ECHO "X$_lt_compiler_boilerplate" | $Xsed -e '/^$/d' > out/conftest.exp
+ $SED '/^$/d; /^ *+/d' out/conftest.err >out/conftest.er2
+ if test ! -s out/conftest.er2 || diff out/conftest.exp out/conftest.er2 >/dev/null; then
+ lt_cv_prog_compiler_c_o=yes
+ fi
+ fi
+ chmod u+w . 2>&5
+ $RM conftest*
+ # SGI C++ compiler will create directory out/ii_files/ for
+ # template instantiation
+ test -d out/ii_files && $RM out/ii_files/* && rmdir out/ii_files
+ $RM out/* && rmdir out
+ cd ..
+ $RM -r conftest
+ $RM conftest*
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_c_o" >&5
+$as_echo "$lt_cv_prog_compiler_c_o" >&6; }
+
+
+
+
+
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $compiler supports -c -o file.$ac_objext" >&5
+$as_echo_n "checking if $compiler supports -c -o file.$ac_objext... " >&6; }
+if test "${lt_cv_prog_compiler_c_o+set}" = set; then :
+ $as_echo_n "(cached) " >&6
+else
+ lt_cv_prog_compiler_c_o=no
+ $RM -r conftest 2>/dev/null
+ mkdir conftest
+ cd conftest
+ mkdir out
+ echo "$lt_simple_compile_test_code" > conftest.$ac_ext
+
+ lt_compiler_flag="-o out/conftest2.$ac_objext"
+ # Insert the option either (1) after the last *FLAGS variable, or
+ # (2) before a word containing "conftest.", or (3) at the end.
+ # Note that $ac_compile itself does not contain backslashes and begins
+ # with a dollar sign (not a hyphen), so the echo should work correctly.
+ lt_compile=`echo "$ac_compile" | $SED \
+ -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
+ -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
+ -e 's:$: $lt_compiler_flag:'`
+ (eval echo "\"\$as_me:7826: $lt_compile\"" >&5)
+ (eval "$lt_compile" 2>out/conftest.err)
+ ac_status=$?
+ cat out/conftest.err >&5
+ echo "$as_me:7830: \$? = $ac_status" >&5
+ if (exit $ac_status) && test -s out/conftest2.$ac_objext
+ then
+ # The compiler can only warn and ignore the option if not recognized
+ # So say no if there are warnings
+ $ECHO "X$_lt_compiler_boilerplate" | $Xsed -e '/^$/d' > out/conftest.exp
+ $SED '/^$/d; /^ *+/d' out/conftest.err >out/conftest.er2
+ if test ! -s out/conftest.er2 || diff out/conftest.exp out/conftest.er2 >/dev/null; then
+ lt_cv_prog_compiler_c_o=yes
+ fi
+ fi
+ chmod u+w . 2>&5
+ $RM conftest*
+ # SGI C++ compiler will create directory out/ii_files/ for
+ # template instantiation
+ test -d out/ii_files && $RM out/ii_files/* && rmdir out/ii_files
+ $RM out/* && rmdir out
+ cd ..
+ $RM -r conftest
+ $RM conftest*
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_c_o" >&5
+$as_echo "$lt_cv_prog_compiler_c_o" >&6; }
+
+
+
+
+hard_links="nottested"
+if test "$lt_cv_prog_compiler_c_o" = no && test "$need_locks" != no; then
+ # do not overwrite the value of need_locks provided by the user
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking if we can lock with hard links" >&5
+$as_echo_n "checking if we can lock with hard links... " >&6; }
+ hard_links=yes
+ $RM conftest*
+ ln conftest.a conftest.b 2>/dev/null && hard_links=no
+ touch conftest.a
+ ln conftest.a conftest.b 2>&5 || hard_links=no
+ ln conftest.a conftest.b 2>/dev/null && hard_links=no
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $hard_links" >&5
+$as_echo "$hard_links" >&6; }
+ if test "$hard_links" = no; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: \`$CC' does not support \`-c -o', so \`make -j' may be unsafe" >&5
+$as_echo "$as_me: WARNING: \`$CC' does not support \`-c -o', so \`make -j' may be unsafe" >&2;}
+ need_locks=warn
+ fi
+else
+ need_locks=no
+fi
+
+
+
+
+
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the $compiler linker ($LD) supports shared libraries" >&5
+$as_echo_n "checking whether the $compiler linker ($LD) supports shared libraries... " >&6; }
+
+ runpath_var=
+ allow_undefined_flag=
+ always_export_symbols=no
+ archive_cmds=
+ archive_expsym_cmds=
+ compiler_needs_object=no
+ enable_shared_with_static_runtimes=no
+ export_dynamic_flag_spec=
+ export_symbols_cmds='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\''s/.* //'\'' | sort | uniq > $export_symbols'
+ hardcode_automatic=no
+ hardcode_direct=no
+ hardcode_direct_absolute=no
+ hardcode_libdir_flag_spec=
+ hardcode_libdir_flag_spec_ld=
+ hardcode_libdir_separator=
+ hardcode_minus_L=no
+ hardcode_shlibpath_var=unsupported
+ inherit_rpath=no
+ link_all_deplibs=unknown
+ module_cmds=
+ module_expsym_cmds=
+ old_archive_from_new_cmds=
+ old_archive_from_expsyms_cmds=
+ thread_safe_flag_spec=
+ whole_archive_flag_spec=
+ # include_expsyms should be a list of space-separated symbols to be *always*
+ # included in the symbol list
+ include_expsyms=
+ # exclude_expsyms can be an extended regexp of symbols to exclude
+ # it will be wrapped by ` (' and `)$', so one must not match beginning or
+ # end of line. Example: `a|bc|.*d.*' will exclude the symbols `a' and `bc',
+ # as well as any symbol that contains `d'.
+ exclude_expsyms='_GLOBAL_OFFSET_TABLE_|_GLOBAL__F[ID]_.*'
+ # Although _GLOBAL_OFFSET_TABLE_ is a valid symbol C name, most a.out
+ # platforms (ab)use it in PIC code, but their linkers get confused if
+ # the symbol is explicitly referenced. Since portable code cannot
+ # rely on this symbol name, it's probably fine to never include it in
+ # preloaded symbol tables.
+ # Exclude shared library initialization/finalization symbols.
+ extract_expsyms_cmds=
+
+ case $host_os in
+ cygwin* | mingw* | pw32* | cegcc*)
+ # FIXME: the MSVC++ port hasn't been tested in a loooong time
+ # When not using gcc, we currently assume that we are using
+ # Microsoft Visual C++.
+ if test "$GCC" != yes; then
+ with_gnu_ld=no
+ fi
+ ;;
+ interix*)
+ # we just hope/assume this is gcc and not c89 (= MSVC++)
+ with_gnu_ld=yes
+ ;;
+ openbsd*)
+ with_gnu_ld=no
+ ;;
+ linux* | k*bsd*-gnu)
+ link_all_deplibs=no
+ ;;
+ esac
+
+ ld_shlibs=yes
+ if test "$with_gnu_ld" = yes; then
+ # If archive_cmds runs LD, not CC, wlarc should be empty
+ wlarc='${wl}'
+
+ # Set some defaults for GNU ld with shared library support. These
+ # are reset later if shared libraries are not supported. Putting them
+ # here allows them to be overridden if necessary.
+ runpath_var=LD_RUN_PATH
+ hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir'
+ export_dynamic_flag_spec='${wl}--export-dynamic'
+ # ancient GNU ld didn't support --whole-archive et. al.
+ if $LD --help 2>&1 | $GREP 'no-whole-archive' > /dev/null; then
+ whole_archive_flag_spec="$wlarc"'--whole-archive$convenience '"$wlarc"'--no-whole-archive'
+ else
+ whole_archive_flag_spec=
+ fi
+ supports_anon_versioning=no
+ case `$LD -v 2>&1` in
+ *GNU\ gold*) supports_anon_versioning=yes ;;
+ *\ [01].* | *\ 2.[0-9].* | *\ 2.10.*) ;; # catch versions < 2.11
+ *\ 2.11.93.0.2\ *) supports_anon_versioning=yes ;; # RH7.3 ...
+ *\ 2.11.92.0.12\ *) supports_anon_versioning=yes ;; # Mandrake 8.2 ...
+ *\ 2.11.*) ;; # other 2.11 versions
+ *) supports_anon_versioning=yes ;;
+ esac
+
+ # See if GNU ld supports shared libraries.
+ case $host_os in
+ aix[3-9]*)
+ # On AIX/PPC, the GNU linker is very broken
+ if test "$host_cpu" != ia64; then
+ ld_shlibs=no
+ cat <<_LT_EOF 1>&2
+
+*** Warning: the GNU linker, at least up to release 2.9.1, is reported
+*** to be unable to reliably create shared libraries on AIX.
+*** Therefore, libtool is disabling shared libraries support. If you
+*** really care for shared libraries, you may want to modify your PATH
+*** so that a non-GNU linker is found, and then restart.
+
+_LT_EOF
+ fi
+ ;;
+
+ amigaos*)
+ case $host_cpu in
+ powerpc)
+ # see comment about AmigaOS4 .so support
+ archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
+ archive_expsym_cmds=''
+ ;;
+ m68k)
+ archive_cmds='$RM $output_objdir/a2ixlibrary.data~$ECHO "#define NAME $libname" > $output_objdir/a2ixlibrary.data~$ECHO "#define LIBRARY_ID 1" >> $output_objdir/a2ixlibrary.data~$ECHO "#define VERSION $major" >> $output_objdir/a2ixlibrary.data~$ECHO "#define REVISION $revision" >> $output_objdir/a2ixlibrary.data~$AR $AR_FLAGS $lib $libobjs~$RANLIB $lib~(cd $output_objdir && a2ixlibrary -32)'
+ hardcode_libdir_flag_spec='-L$libdir'
+ hardcode_minus_L=yes
+ ;;
+ esac
+ ;;
+
+ beos*)
+ if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then
+ allow_undefined_flag=unsupported
+ # Joseph Beckenbach <jrb3@best.com> says some releases of gcc
+ # support --undefined. This deserves some investigation. FIXME
+ archive_cmds='$CC -nostart $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
+ else
+ ld_shlibs=no
+ fi
+ ;;
+
+ cygwin* | mingw* | pw32* | cegcc*)
+ # _LT_TAGVAR(hardcode_libdir_flag_spec, ) is actually meaningless,
+ # as there is no search path for DLLs.
+ hardcode_libdir_flag_spec='-L$libdir'
+ allow_undefined_flag=unsupported
+ always_export_symbols=no
+ enable_shared_with_static_runtimes=yes
+ export_symbols_cmds='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[BCDGRS][ ]/s/.*[ ]\([^ ]*\)/\1 DATA/'\'' | $SED -e '\''/^[AITW][ ]/s/.*[ ]//'\'' | sort | uniq > $export_symbols'
+
+ if $LD --help 2>&1 | $GREP 'auto-import' > /dev/null; then
+ archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib'
+ # If the export-symbols file already is a .def file (1st line
+ # is EXPORTS), use it as is; otherwise, prepend...
+ archive_expsym_cmds='if test "x`$SED 1q $export_symbols`" = xEXPORTS; then
+ cp $export_symbols $output_objdir/$soname.def;
+ else
+ echo EXPORTS > $output_objdir/$soname.def;
+ cat $export_symbols >> $output_objdir/$soname.def;
+ fi~
+ $CC -shared $output_objdir/$soname.def $libobjs $deplibs $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib'
+ else
+ ld_shlibs=no
+ fi
+ ;;
+
+ interix[3-9]*)
+ hardcode_direct=no
+ hardcode_shlibpath_var=no
+ hardcode_libdir_flag_spec='${wl}-rpath,$libdir'
+ export_dynamic_flag_spec='${wl}-E'
+ # Hack: On Interix 3.x, we cannot compile PIC because of a broken gcc.
+ # Instead, shared libraries are loaded at an image base (0x10000000 by
+ # default) and relocated if they conflict, which is a slow very memory
+ # consuming and fragmenting process. To avoid this, we pick a random,
+ # 256 KiB-aligned image base between 0x50000000 and 0x6FFC0000 at link
+ # time. Moving up from 0x10000000 also allows more sbrk(2) space.
+ archive_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-h,$soname ${wl}--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib'
+ archive_expsym_cmds='sed "s,^,_," $export_symbols >$output_objdir/$soname.expsym~$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-h,$soname ${wl}--retain-symbols-file,$output_objdir/$soname.expsym ${wl}--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib'
+ ;;
+
+ gnu* | linux* | tpf* | k*bsd*-gnu | kopensolaris*-gnu)
+ tmp_diet=no
+ if test "$host_os" = linux-dietlibc; then
+ case $cc_basename in
+ diet\ *) tmp_diet=yes;; # linux-dietlibc with static linking (!diet-dyn)
+ esac
+ fi
+ if $LD --help 2>&1 | $EGREP ': supported targets:.* elf' > /dev/null \
+ && test "$tmp_diet" = no
+ then
+ tmp_addflag=
+ tmp_sharedflag='-shared'
+ case $cc_basename,$host_cpu in
+ pgcc*) # Portland Group C compiler
+ whole_archive_flag_spec='${wl}--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; $ECHO \"$new_convenience\"` ${wl}--no-whole-archive'
+ tmp_addflag=' $pic_flag'
+ ;;
+ pgf77* | pgf90* | pgf95*) # Portland Group f77 and f90 compilers
+ whole_archive_flag_spec='${wl}--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; $ECHO \"$new_convenience\"` ${wl}--no-whole-archive'
+ tmp_addflag=' $pic_flag -Mnomain' ;;
+ ecc*,ia64* | icc*,ia64*) # Intel C compiler on ia64
+ tmp_addflag=' -i_dynamic' ;;
+ efc*,ia64* | ifort*,ia64*) # Intel Fortran compiler on ia64
+ tmp_addflag=' -i_dynamic -nofor_main' ;;
+ ifc* | ifort*) # Intel Fortran compiler
+ tmp_addflag=' -nofor_main' ;;
+ lf95*) # Lahey Fortran 8.1
+ whole_archive_flag_spec=
+ tmp_sharedflag='--shared' ;;
+ xl[cC]*) # IBM XL C 8.0 on PPC (deal with xlf below)
+ tmp_sharedflag='-qmkshrobj'
+ tmp_addflag= ;;
+ esac
+ case `$CC -V 2>&1 | sed 5q` in
+ *Sun\ C*) # Sun C 5.9
+ whole_archive_flag_spec='${wl}--whole-archive`new_convenience=; for conv in $convenience\"\"; do test -z \"$conv\" || new_convenience=\"$new_convenience,$conv\"; done; $ECHO \"$new_convenience\"` ${wl}--no-whole-archive'
+ compiler_needs_object=yes
+ tmp_sharedflag='-G' ;;
+ *Sun\ F*) # Sun Fortran 8.3
+ tmp_sharedflag='-G' ;;
+ esac
+ archive_cmds='$CC '"$tmp_sharedflag""$tmp_addflag"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
+
+ if test "x$supports_anon_versioning" = xyes; then
+ archive_expsym_cmds='echo "{ global:" > $output_objdir/$libname.ver~
+ cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~
+ echo "local: *; };" >> $output_objdir/$libname.ver~
+ $CC '"$tmp_sharedflag""$tmp_addflag"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-version-script ${wl}$output_objdir/$libname.ver -o $lib'
+ fi
+
+ case $cc_basename in
+ xlf*)
+ # IBM XL Fortran 10.1 on PPC cannot create shared libs itself
+ whole_archive_flag_spec='--whole-archive$convenience --no-whole-archive'
+ hardcode_libdir_flag_spec=
+ hardcode_libdir_flag_spec_ld='-rpath $libdir'
+ archive_cmds='$LD -shared $libobjs $deplibs $compiler_flags -soname $soname -o $lib'
+ if test "x$supports_anon_versioning" = xyes; then
+ archive_expsym_cmds='echo "{ global:" > $output_objdir/$libname.ver~
+ cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~
+ echo "local: *; };" >> $output_objdir/$libname.ver~
+ $LD -shared $libobjs $deplibs $compiler_flags -soname $soname -version-script $output_objdir/$libname.ver -o $lib'
+ fi
+ ;;
+ esac
+ else
+ ld_shlibs=no
+ fi
+ ;;
+
+ netbsd* | netbsdelf*-gnu)
+ if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then
+ archive_cmds='$LD -Bshareable $libobjs $deplibs $linker_flags -o $lib'
+ wlarc=
+ else
+ archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
+ archive_expsym_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib'
+ fi
+ ;;
+
+ solaris*)
+ if $LD -v 2>&1 | $GREP 'BFD 2\.8' > /dev/null; then
+ ld_shlibs=no
+ cat <<_LT_EOF 1>&2
+
+*** Warning: The releases 2.8.* of the GNU linker cannot reliably
+*** create shared libraries on Solaris systems. Therefore, libtool
+*** is disabling shared libraries support. We urge you to upgrade GNU
+*** binutils to release 2.9.1 or newer. Another option is to modify
+*** your PATH or compiler configuration so that the native linker is
+*** used, and then restart.
+
+_LT_EOF
+ elif $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then
+ archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
+ archive_expsym_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib'
+ else
+ ld_shlibs=no
+ fi
+ ;;
+
+ sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX*)
+ case `$LD -v 2>&1` in
+ *\ [01].* | *\ 2.[0-9].* | *\ 2.1[0-5].*)
+ ld_shlibs=no
+ cat <<_LT_EOF 1>&2
+
+*** Warning: Releases of the GNU linker prior to 2.16.91.0.3 can not
+*** reliably create shared libraries on SCO systems. Therefore, libtool
+*** is disabling shared libraries support. We urge you to upgrade GNU
+*** binutils to release 2.16.91.0.3 or newer. Another option is to modify
+*** your PATH or compiler configuration so that the native linker is
+*** used, and then restart.
+
+_LT_EOF
+ ;;
+ *)
+ # For security reasons, it is highly recommended that you always
+ # use absolute paths for naming shared libraries, and exclude the
+ # DT_RUNPATH tag from executables and libraries. But doing so
+ # requires that you compile everything twice, which is a pain.
+ if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then
+ hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir'
+ archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
+ archive_expsym_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib'
+ else
+ ld_shlibs=no
+ fi
+ ;;
+ esac
+ ;;
+
+ sunos4*)
+ archive_cmds='$LD -assert pure-text -Bshareable -o $lib $libobjs $deplibs $linker_flags'
+ wlarc=
+ hardcode_direct=yes
+ hardcode_shlibpath_var=no
+ ;;
+
+ *)
+ if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then
+ archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
+ archive_expsym_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib'
+ else
+ ld_shlibs=no
+ fi
+ ;;
+ esac
+
+ if test "$ld_shlibs" = no; then
+ runpath_var=
+ hardcode_libdir_flag_spec=
+ export_dynamic_flag_spec=
+ whole_archive_flag_spec=
+ fi
+ else
+ # PORTME fill in a description of your system's linker (not GNU ld)
+ case $host_os in
+ aix3*)
+ allow_undefined_flag=unsupported
+ always_export_symbols=yes
+ archive_expsym_cmds='$LD -o $output_objdir/$soname $libobjs $deplibs $linker_flags -bE:$export_symbols -T512 -H512 -bM:SRE~$AR $AR_FLAGS $lib $output_objdir/$soname'
+ # Note: this linker hardcodes the directories in LIBPATH if there
+ # are no directories specified by -L.
+ hardcode_minus_L=yes
+ if test "$GCC" = yes && test -z "$lt_prog_compiler_static"; then
+ # Neither direct hardcoding nor static linking is supported with a
+ # broken collect2.
+ hardcode_direct=unsupported
+ fi
+ ;;
+
+ aix[4-9]*)
+ if test "$host_cpu" = ia64; then
+ # On IA64, the linker does run time linking by default, so we don't
+ # have to do anything special.
+ aix_use_runtimelinking=no
+ exp_sym_flag='-Bexport'
+ no_entry_flag=""
+ else
+ # If we're using GNU nm, then we don't want the "-C" option.
+ # -C means demangle to AIX nm, but means don't demangle with GNU nm
+ if $NM -V 2>&1 | $GREP 'GNU' > /dev/null; then
+ export_symbols_cmds='$NM -Bpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B")) && (substr(\$ 3,1,1) != ".")) { print \$ 3 } }'\'' | sort -u > $export_symbols'
+ else
+ export_symbols_cmds='$NM -BCpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B")) && (substr(\$ 3,1,1) != ".")) { print \$ 3 } }'\'' | sort -u > $export_symbols'
+ fi
+ aix_use_runtimelinking=no
+
+ # Test if we are trying to use run time linking or normal
+ # AIX style linking. If -brtl is somewhere in LDFLAGS, we
+ # need to do runtime linking.
+ case $host_os in aix4.[23]|aix4.[23].*|aix[5-9]*)
+ for ld_flag in $LDFLAGS; do
+ if (test $ld_flag = "-brtl" || test $ld_flag = "-Wl,-brtl"); then
+ aix_use_runtimelinking=yes
+ break
+ fi
+ done
+ ;;
+ esac
+
+ exp_sym_flag='-bexport'
+ no_entry_flag='-bnoentry'
+ fi
+
+ # When large executables or shared objects are built, AIX ld can
+ # have problems creating the table of contents. If linking a library
+ # or program results in "error TOC overflow" add -mminimal-toc to
+ # CXXFLAGS/CFLAGS for g++/gcc. In the cases where that is not
+ # enough to fix the problem, add -Wl,-bbigtoc to LDFLAGS.
+
+ archive_cmds=''
+ hardcode_direct=yes
+ hardcode_direct_absolute=yes
+ hardcode_libdir_separator=':'
+ link_all_deplibs=yes
+ file_list_spec='${wl}-f,'
+
+ if test "$GCC" = yes; then
+ case $host_os in aix4.[012]|aix4.[012].*)
+ # We only want to do this on AIX 4.2 and lower, the check
+ # below for broken collect2 doesn't work under 4.3+
+ collect2name=`${CC} -print-prog-name=collect2`
+ if test -f "$collect2name" &&
+ strings "$collect2name" | $GREP resolve_lib_name >/dev/null
+ then
+ # We have reworked collect2
+ :
+ else
+ # We have old collect2
+ hardcode_direct=unsupported
+ # It fails to find uninstalled libraries when the uninstalled
+ # path is not listed in the libpath. Setting hardcode_minus_L
+ # to unsupported forces relinking
+ hardcode_minus_L=yes
+ hardcode_libdir_flag_spec='-L$libdir'
+ hardcode_libdir_separator=
+ fi
+ ;;
+ esac
+ shared_flag='-shared'
+ if test "$aix_use_runtimelinking" = yes; then
+ shared_flag="$shared_flag "'${wl}-G'
+ fi
+ link_all_deplibs=no
+ else
+ # not using gcc
+ if test "$host_cpu" = ia64; then
+ # VisualAge C++, Version 5.5 for AIX 5L for IA-64, Beta 3 Release
+ # chokes on -Wl,-G. The following line is correct:
+ shared_flag='-G'
+ else
+ if test "$aix_use_runtimelinking" = yes; then
+ shared_flag='${wl}-G'
+ else
+ shared_flag='${wl}-bM:SRE'
+ fi
+ fi
+ fi
+
+ export_dynamic_flag_spec='${wl}-bexpall'
+ # It seems that -bexpall does not export symbols beginning with
+ # underscore (_), so it is better to generate a list of symbols to export.
+ always_export_symbols=yes
+ if test "$aix_use_runtimelinking" = yes; then
+ # Warning - without using the other runtime loading flags (-brtl),
+ # -berok will link without error, but may produce a broken library.
+ allow_undefined_flag='-berok'
+ # Determine the default libpath from the value encoded in an
+ # empty executable.
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+int
+main ()
+{
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+
+lt_aix_libpath_sed='
+ /Import File Strings/,/^$/ {
+ /^0/ {
+ s/^0 *\(.*\)$/\1/
+ p
+ }
+ }'
+aix_libpath=`dump -H conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"`
+# Check for a 64-bit object if we didn't find anything.
+if test -z "$aix_libpath"; then
+ aix_libpath=`dump -HX64 conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"`
+fi
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi
+
+ hardcode_libdir_flag_spec='${wl}-blibpath:$libdir:'"$aix_libpath"
+ archive_expsym_cmds='$CC -o $output_objdir/$soname $libobjs $deplibs '"\${wl}$no_entry_flag"' $compiler_flags `if test "x${allow_undefined_flag}" != "x"; then $ECHO "X${wl}${allow_undefined_flag}" | $Xsed; else :; fi` '"\${wl}$exp_sym_flag:\$export_symbols $shared_flag"
+ else
+ if test "$host_cpu" = ia64; then
+ hardcode_libdir_flag_spec='${wl}-R $libdir:/usr/lib:/lib'
+ allow_undefined_flag="-z nodefs"
+ archive_expsym_cmds="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs '"\${wl}$no_entry_flag"' $compiler_flags ${wl}${allow_undefined_flag} '"\${wl}$exp_sym_flag:\$export_symbols"
+ else
+ # Determine the default libpath from the value encoded in an
+ # empty executable.
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+int
+main ()
+{
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+
+lt_aix_libpath_sed='
+ /Import File Strings/,/^$/ {
+ /^0/ {
+ s/^0 *\(.*\)$/\1/
+ p
+ }
+ }'
+aix_libpath=`dump -H conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"`
+# Check for a 64-bit object if we didn't find anything.
+if test -z "$aix_libpath"; then
+ aix_libpath=`dump -HX64 conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"`
+fi
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi
+
+ hardcode_libdir_flag_spec='${wl}-blibpath:$libdir:'"$aix_libpath"
+ # Warning - without using the other run time loading flags,
+ # -berok will link without error, but may produce a broken library.
+ no_undefined_flag=' ${wl}-bernotok'
+ allow_undefined_flag=' ${wl}-berok'
+ # Exported symbols can be pulled into shared objects from archives
+ whole_archive_flag_spec='$convenience'
+ archive_cmds_need_lc=yes
+ # This is similar to how AIX traditionally builds its shared libraries.
+ archive_expsym_cmds="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs ${wl}-bnoentry $compiler_flags ${wl}-bE:$export_symbols${allow_undefined_flag}~$AR $AR_FLAGS $output_objdir/$libname$release.a $output_objdir/$soname'
+ fi
+ fi
+ ;;
+
+ amigaos*)
+ case $host_cpu in
+ powerpc)
+ # see comment about AmigaOS4 .so support
+ archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
+ archive_expsym_cmds=''
+ ;;
+ m68k)
+ archive_cmds='$RM $output_objdir/a2ixlibrary.data~$ECHO "#define NAME $libname" > $output_objdir/a2ixlibrary.data~$ECHO "#define LIBRARY_ID 1" >> $output_objdir/a2ixlibrary.data~$ECHO "#define VERSION $major" >> $output_objdir/a2ixlibrary.data~$ECHO "#define REVISION $revision" >> $output_objdir/a2ixlibrary.data~$AR $AR_FLAGS $lib $libobjs~$RANLIB $lib~(cd $output_objdir && a2ixlibrary -32)'
+ hardcode_libdir_flag_spec='-L$libdir'
+ hardcode_minus_L=yes
+ ;;
+ esac
+ ;;
+
+ bsdi[45]*)
+ export_dynamic_flag_spec=-rdynamic
+ ;;
+
+ cygwin* | mingw* | pw32* | cegcc*)
+ # When not using gcc, we currently assume that we are using
+ # Microsoft Visual C++.
+ # hardcode_libdir_flag_spec is actually meaningless, as there is
+ # no search path for DLLs.
+ hardcode_libdir_flag_spec=' '
+ allow_undefined_flag=unsupported
+ # Tell ltmain to make .lib files, not .a files.
+ libext=lib
+ # Tell ltmain to make .dll files, not .so files.
+ shrext_cmds=".dll"
+ # FIXME: Setting linknames here is a bad hack.
+ archive_cmds='$CC -o $lib $libobjs $compiler_flags `$ECHO "X$deplibs" | $Xsed -e '\''s/ -lc$//'\''` -link -dll~linknames='
+ # The linker will automatically build a .lib file if we build a DLL.
+ old_archive_from_new_cmds='true'
+ # FIXME: Should let the user specify the lib program.
+ old_archive_cmds='lib -OUT:$oldlib$oldobjs$old_deplibs'
+ fix_srcfile_path='`cygpath -w "$srcfile"`'
+ enable_shared_with_static_runtimes=yes
+ ;;
+
+ darwin* | rhapsody*)
+
+
+ archive_cmds_need_lc=no
+ hardcode_direct=no
+ hardcode_automatic=yes
+ hardcode_shlibpath_var=unsupported
+ whole_archive_flag_spec=''
+ link_all_deplibs=yes
+ allow_undefined_flag="$_lt_dar_allow_undefined"
+ case $cc_basename in
+ ifort*) _lt_dar_can_shared=yes ;;
+ *) _lt_dar_can_shared=$GCC ;;
+ esac
+ if test "$_lt_dar_can_shared" = "yes"; then
+ output_verbose_link_cmd=echo
+ archive_cmds="\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring $_lt_dar_single_mod${_lt_dsymutil}"
+ module_cmds="\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags${_lt_dsymutil}"
+ archive_expsym_cmds="sed 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring ${_lt_dar_single_mod}${_lt_dar_export_syms}${_lt_dsymutil}"
+ module_expsym_cmds="sed -e 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags${_lt_dar_export_syms}${_lt_dsymutil}"
+
+ else
+ ld_shlibs=no
+ fi
+
+ ;;
+
+ dgux*)
+ archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'
+ hardcode_libdir_flag_spec='-L$libdir'
+ hardcode_shlibpath_var=no
+ ;;
+
+ freebsd1*)
+ ld_shlibs=no
+ ;;
+
+ # FreeBSD 2.2.[012] allows us to include c++rt0.o to get C++ constructor
+ # support. Future versions do this automatically, but an explicit c++rt0.o
+ # does not break anything, and helps significantly (at the cost of a little
+ # extra space).
+ freebsd2.2*)
+ archive_cmds='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags /usr/lib/c++rt0.o'
+ hardcode_libdir_flag_spec='-R$libdir'
+ hardcode_direct=yes
+ hardcode_shlibpath_var=no
+ ;;
+
+ # Unfortunately, older versions of FreeBSD 2 do not have this feature.
+ freebsd2*)
+ archive_cmds='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags'
+ hardcode_direct=yes
+ hardcode_minus_L=yes
+ hardcode_shlibpath_var=no
+ ;;
+
+ # FreeBSD 3 and greater uses gcc -shared to do shared libraries.
+ freebsd* | dragonfly*)
+ archive_cmds='$CC -shared -o $lib $libobjs $deplibs $compiler_flags'
+ hardcode_libdir_flag_spec='-R$libdir'
+ hardcode_direct=yes
+ hardcode_shlibpath_var=no
+ ;;
+
+ hpux9*)
+ if test "$GCC" = yes; then
+ archive_cmds='$RM $output_objdir/$soname~$CC -shared -fPIC ${wl}+b ${wl}$install_libdir -o $output_objdir/$soname $libobjs $deplibs $compiler_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib'
+ else
+ archive_cmds='$RM $output_objdir/$soname~$LD -b +b $install_libdir -o $output_objdir/$soname $libobjs $deplibs $linker_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib'
+ fi
+ hardcode_libdir_flag_spec='${wl}+b ${wl}$libdir'
+ hardcode_libdir_separator=:
+ hardcode_direct=yes
+
+ # hardcode_minus_L: Not really in the search PATH,
+ # but as the default location of the library.
+ hardcode_minus_L=yes
+ export_dynamic_flag_spec='${wl}-E'
+ ;;
+
+ hpux10*)
+ if test "$GCC" = yes -a "$with_gnu_ld" = no; then
+ archive_cmds='$CC -shared -fPIC ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags'
+ else
+ archive_cmds='$LD -b +h $soname +b $install_libdir -o $lib $libobjs $deplibs $linker_flags'
+ fi
+ if test "$with_gnu_ld" = no; then
+ hardcode_libdir_flag_spec='${wl}+b ${wl}$libdir'
+ hardcode_libdir_flag_spec_ld='+b $libdir'
+ hardcode_libdir_separator=:
+ hardcode_direct=yes
+ hardcode_direct_absolute=yes
+ export_dynamic_flag_spec='${wl}-E'
+ # hardcode_minus_L: Not really in the search PATH,
+ # but as the default location of the library.
+ hardcode_minus_L=yes
+ fi
+ ;;
+
+ hpux11*)
+ if test "$GCC" = yes -a "$with_gnu_ld" = no; then
+ case $host_cpu in
+ hppa*64*)
+ archive_cmds='$CC -shared ${wl}+h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags'
+ ;;
+ ia64*)
+ archive_cmds='$CC -shared -fPIC ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags'
+ ;;
+ *)
+ archive_cmds='$CC -shared -fPIC ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags'
+ ;;
+ esac
+ else
+ case $host_cpu in
+ hppa*64*)
+ archive_cmds='$CC -b ${wl}+h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags'
+ ;;
+ ia64*)
+ archive_cmds='$CC -b ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags'
+ ;;
+ *)
+ archive_cmds='$CC -b ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags'
+ ;;
+ esac
+ fi
+ if test "$with_gnu_ld" = no; then
+ hardcode_libdir_flag_spec='${wl}+b ${wl}$libdir'
+ hardcode_libdir_separator=:
+
+ case $host_cpu in
+ hppa*64*|ia64*)
+ hardcode_direct=no
+ hardcode_shlibpath_var=no
+ ;;
+ *)
+ hardcode_direct=yes
+ hardcode_direct_absolute=yes
+ export_dynamic_flag_spec='${wl}-E'
+
+ # hardcode_minus_L: Not really in the search PATH,
+ # but as the default location of the library.
+ hardcode_minus_L=yes
+ ;;
+ esac
+ fi
+ ;;
+
+ irix5* | irix6* | nonstopux*)
+ if test "$GCC" = yes; then
+ archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && $ECHO "X${wl}-set_version ${wl}$verstring" | $Xsed` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib'
+ # Try to use the -exported_symbol ld option, if it does not
+ # work, assume that -exports_file does not work either and
+ # implicitly export all symbols.
+ save_LDFLAGS="$LDFLAGS"
+ LDFLAGS="$LDFLAGS -shared ${wl}-exported_symbol ${wl}foo ${wl}-update_registry ${wl}/dev/null"
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+int foo(void) {}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+ archive_expsym_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && $ECHO "X${wl}-set_version ${wl}$verstring" | $Xsed` ${wl}-update_registry ${wl}${output_objdir}/so_locations ${wl}-exports_file ${wl}$export_symbols -o $lib'
+
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+ LDFLAGS="$save_LDFLAGS"
+ else
+ archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && $ECHO "X-set_version $verstring" | $Xsed` -update_registry ${output_objdir}/so_locations -o $lib'
+ archive_expsym_cmds='$CC -shared $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && $ECHO "X-set_version $verstring" | $Xsed` -update_registry ${output_objdir}/so_locations -exports_file $export_symbols -o $lib'
+ fi
+ archive_cmds_need_lc='no'
+ hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir'
+ hardcode_libdir_separator=:
+ inherit_rpath=yes
+ link_all_deplibs=yes
+ ;;
+
+ netbsd* | netbsdelf*-gnu)
+ if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then
+ archive_cmds='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags' # a.out
+ else
+ archive_cmds='$LD -shared -o $lib $libobjs $deplibs $linker_flags' # ELF
+ fi
+ hardcode_libdir_flag_spec='-R$libdir'
+ hardcode_direct=yes
+ hardcode_shlibpath_var=no
+ ;;
+
+ newsos6)
+ archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'
+ hardcode_direct=yes
+ hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir'
+ hardcode_libdir_separator=:
+ hardcode_shlibpath_var=no
+ ;;
+
+ *nto* | *qnx*)
+ ;;
+
+ openbsd*)
+ if test -f /usr/libexec/ld.so; then
+ hardcode_direct=yes
+ hardcode_shlibpath_var=no
+ hardcode_direct_absolute=yes
+ if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then
+ archive_cmds='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags'
+ archive_expsym_cmds='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags ${wl}-retain-symbols-file,$export_symbols'
+ hardcode_libdir_flag_spec='${wl}-rpath,$libdir'
+ export_dynamic_flag_spec='${wl}-E'
+ else
+ case $host_os in
+ openbsd[01].* | openbsd2.[0-7] | openbsd2.[0-7].*)
+ archive_cmds='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags'
+ hardcode_libdir_flag_spec='-R$libdir'
+ ;;
+ *)
+ archive_cmds='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags'
+ hardcode_libdir_flag_spec='${wl}-rpath,$libdir'
+ ;;
+ esac
+ fi
+ else
+ ld_shlibs=no
+ fi
+ ;;
+
+ os2*)
+ hardcode_libdir_flag_spec='-L$libdir'
+ hardcode_minus_L=yes
+ allow_undefined_flag=unsupported
+ archive_cmds='$ECHO "LIBRARY $libname INITINSTANCE" > $output_objdir/$libname.def~$ECHO "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~$ECHO DATA >> $output_objdir/$libname.def~$ECHO " SINGLE NONSHARED" >> $output_objdir/$libname.def~$ECHO EXPORTS >> $output_objdir/$libname.def~emxexp $libobjs >> $output_objdir/$libname.def~$CC -Zdll -Zcrtdll -o $lib $libobjs $deplibs $compiler_flags $output_objdir/$libname.def'
+ old_archive_from_new_cmds='emximp -o $output_objdir/$libname.a $output_objdir/$libname.def'
+ ;;
+
+ osf3*)
+ if test "$GCC" = yes; then
+ allow_undefined_flag=' ${wl}-expect_unresolved ${wl}\*'
+ archive_cmds='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && $ECHO "X${wl}-set_version ${wl}$verstring" | $Xsed` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib'
+ else
+ allow_undefined_flag=' -expect_unresolved \*'
+ archive_cmds='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && $ECHO "X-set_version $verstring" | $Xsed` -update_registry ${output_objdir}/so_locations -o $lib'
+ fi
+ archive_cmds_need_lc='no'
+ hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir'
+ hardcode_libdir_separator=:
+ ;;
+
+ osf4* | osf5*) # as osf3* with the addition of -msym flag
+ if test "$GCC" = yes; then
+ allow_undefined_flag=' ${wl}-expect_unresolved ${wl}\*'
+ archive_cmds='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags ${wl}-msym ${wl}-soname ${wl}$soname `test -n "$verstring" && $ECHO "X${wl}-set_version ${wl}$verstring" | $Xsed` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib'
+ hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir'
+ else
+ allow_undefined_flag=' -expect_unresolved \*'
+ archive_cmds='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags -msym -soname $soname `test -n "$verstring" && $ECHO "X-set_version $verstring" | $Xsed` -update_registry ${output_objdir}/so_locations -o $lib'
+ archive_expsym_cmds='for i in `cat $export_symbols`; do printf "%s %s\\n" -exported_symbol "\$i" >> $lib.exp; done; printf "%s\\n" "-hidden">> $lib.exp~
+ $CC -shared${allow_undefined_flag} ${wl}-input ${wl}$lib.exp $compiler_flags $libobjs $deplibs -soname $soname `test -n "$verstring" && $ECHO "X-set_version $verstring" | $Xsed` -update_registry ${output_objdir}/so_locations -o $lib~$RM $lib.exp'
+
+ # Both c and cxx compiler support -rpath directly
+ hardcode_libdir_flag_spec='-rpath $libdir'
+ fi
+ archive_cmds_need_lc='no'
+ hardcode_libdir_separator=:
+ ;;
+
+ solaris*)
+ no_undefined_flag=' -z defs'
+ if test "$GCC" = yes; then
+ wlarc='${wl}'
+ archive_cmds='$CC -shared ${wl}-z ${wl}text ${wl}-h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags'
+ archive_expsym_cmds='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~
+ $CC -shared ${wl}-z ${wl}text ${wl}-M ${wl}$lib.exp ${wl}-h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags~$RM $lib.exp'
+ else
+ case `$CC -V 2>&1` in
+ *"Compilers 5.0"*)
+ wlarc=''
+ archive_cmds='$LD -G${allow_undefined_flag} -h $soname -o $lib $libobjs $deplibs $linker_flags'
+ archive_expsym_cmds='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~
+ $LD -G${allow_undefined_flag} -M $lib.exp -h $soname -o $lib $libobjs $deplibs $linker_flags~$RM $lib.exp'
+ ;;
+ *)
+ wlarc='${wl}'
+ archive_cmds='$CC -G${allow_undefined_flag} -h $soname -o $lib $libobjs $deplibs $compiler_flags'
+ archive_expsym_cmds='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~
+ $CC -G${allow_undefined_flag} -M $lib.exp -h $soname -o $lib $libobjs $deplibs $compiler_flags~$RM $lib.exp'
+ ;;
+ esac
+ fi
+ hardcode_libdir_flag_spec='-R$libdir'
+ hardcode_shlibpath_var=no
+ case $host_os in
+ solaris2.[0-5] | solaris2.[0-5].*) ;;
+ *)
+ # The compiler driver will combine and reorder linker options,
+ # but understands `-z linker_flag'. GCC discards it without `$wl',
+ # but is careful enough not to reorder.
+ # Supported since Solaris 2.6 (maybe 2.5.1?)
+ if test "$GCC" = yes; then
+ whole_archive_flag_spec='${wl}-z ${wl}allextract$convenience ${wl}-z ${wl}defaultextract'
+ else
+ whole_archive_flag_spec='-z allextract$convenience -z defaultextract'
+ fi
+ ;;
+ esac
+ link_all_deplibs=yes
+ ;;
+
+ sunos4*)
+ if test "x$host_vendor" = xsequent; then
+ # Use $CC to link under sequent, because it throws in some extra .o
+ # files that make .init and .fini sections work.
+ archive_cmds='$CC -G ${wl}-h $soname -o $lib $libobjs $deplibs $compiler_flags'
+ else
+ archive_cmds='$LD -assert pure-text -Bstatic -o $lib $libobjs $deplibs $linker_flags'
+ fi
+ hardcode_libdir_flag_spec='-L$libdir'
+ hardcode_direct=yes
+ hardcode_minus_L=yes
+ hardcode_shlibpath_var=no
+ ;;
+
+ sysv4)
+ case $host_vendor in
+ sni)
+ archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'
+ hardcode_direct=yes # is this really true???
+ ;;
+ siemens)
+ ## LD is ld it makes a PLAMLIB
+ ## CC just makes a GrossModule.
+ archive_cmds='$LD -G -o $lib $libobjs $deplibs $linker_flags'
+ reload_cmds='$CC -r -o $output$reload_objs'
+ hardcode_direct=no
+ ;;
+ motorola)
+ archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'
+ hardcode_direct=no #Motorola manual says yes, but my tests say they lie
+ ;;
+ esac
+ runpath_var='LD_RUN_PATH'
+ hardcode_shlibpath_var=no
+ ;;
+
+ sysv4.3*)
+ archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'
+ hardcode_shlibpath_var=no
+ export_dynamic_flag_spec='-Bexport'
+ ;;
+
+ sysv4*MP*)
+ if test -d /usr/nec; then
+ archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'
+ hardcode_shlibpath_var=no
+ runpath_var=LD_RUN_PATH
+ hardcode_runpath_var=yes
+ ld_shlibs=yes
+ fi
+ ;;
+
+ sysv4*uw2* | sysv5OpenUNIX* | sysv5UnixWare7.[01].[10]* | unixware7* | sco3.2v5.0.[024]*)
+ no_undefined_flag='${wl}-z,text'
+ archive_cmds_need_lc=no
+ hardcode_shlibpath_var=no
+ runpath_var='LD_RUN_PATH'
+
+ if test "$GCC" = yes; then
+ archive_cmds='$CC -shared ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+ archive_expsym_cmds='$CC -shared ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+ else
+ archive_cmds='$CC -G ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+ archive_expsym_cmds='$CC -G ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+ fi
+ ;;
+
+ sysv5* | sco3.2v5* | sco5v6*)
+ # Note: We can NOT use -z defs as we might desire, because we do not
+ # link with -lc, and that would cause any symbols used from libc to
+ # always be unresolved, which means just about no library would
+ # ever link correctly. If we're not using GNU ld we use -z text
+ # though, which does catch some bad symbols but isn't as heavy-handed
+ # as -z defs.
+ no_undefined_flag='${wl}-z,text'
+ allow_undefined_flag='${wl}-z,nodefs'
+ archive_cmds_need_lc=no
+ hardcode_shlibpath_var=no
+ hardcode_libdir_flag_spec='${wl}-R,$libdir'
+ hardcode_libdir_separator=':'
+ link_all_deplibs=yes
+ export_dynamic_flag_spec='${wl}-Bexport'
+ runpath_var='LD_RUN_PATH'
+
+ if test "$GCC" = yes; then
+ archive_cmds='$CC -shared ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+ archive_expsym_cmds='$CC -shared ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+ else
+ archive_cmds='$CC -G ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+ archive_expsym_cmds='$CC -G ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+ fi
+ ;;
+
+ uts4*)
+ archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'
+ hardcode_libdir_flag_spec='-L$libdir'
+ hardcode_shlibpath_var=no
+ ;;
+
+ *)
+ ld_shlibs=no
+ ;;
+ esac
+
+ if test x$host_vendor = xsni; then
+ case $host in
+ sysv4 | sysv4.2uw2* | sysv4.3* | sysv5*)
+ export_dynamic_flag_spec='${wl}-Blargedynsym'
+ ;;
+ esac
+ fi
+ fi
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ld_shlibs" >&5
+$as_echo "$ld_shlibs" >&6; }
+test "$ld_shlibs" = no && can_build_shared=no
+
+with_gnu_ld=$with_gnu_ld
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+#
+# Do we need to explicitly link libc?
+#
+case "x$archive_cmds_need_lc" in
+x|xyes)
+ # Assume -lc should be added
+ archive_cmds_need_lc=yes
+
+ if test "$enable_shared" = yes && test "$GCC" = yes; then
+ case $archive_cmds in
+ *'~'*)
+ # FIXME: we may have to deal with multi-command sequences.
+ ;;
+ '$CC '*)
+ # Test whether the compiler implicitly links with -lc since on some
+ # systems, -lgcc has to come before -lc. If gcc already passes -lc
+ # to ld, don't add -lc before -lgcc.
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether -lc should be explicitly linked in" >&5
+$as_echo_n "checking whether -lc should be explicitly linked in... " >&6; }
+ $RM conftest*
+ echo "$lt_simple_compile_test_code" > conftest.$ac_ext
+
+ if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5
+ (eval $ac_compile) 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; } 2>conftest.err; then
+ soname=conftest
+ lib=conftest
+ libobjs=conftest.$ac_objext
+ deplibs=
+ wl=$lt_prog_compiler_wl
+ pic_flag=$lt_prog_compiler_pic
+ compiler_flags=-v
+ linker_flags=-v
+ verstring=
+ output_objdir=.
+ libname=conftest
+ lt_save_allow_undefined_flag=$allow_undefined_flag
+ allow_undefined_flag=
+ if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$archive_cmds 2\>\&1 \| $GREP \" -lc \" \>/dev/null 2\>\&1\""; } >&5
+ (eval $archive_cmds 2\>\&1 \| $GREP \" -lc \" \>/dev/null 2\>\&1) 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }
+ then
+ archive_cmds_need_lc=no
+ else
+ archive_cmds_need_lc=yes
+ fi
+ allow_undefined_flag=$lt_save_allow_undefined_flag
+ else
+ cat conftest.err 1>&5
+ fi
+ $RM conftest*
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $archive_cmds_need_lc" >&5
+$as_echo "$archive_cmds_need_lc" >&6; }
+ ;;
+ esac
+ fi
+ ;;
+esac
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking dynamic linker characteristics" >&5
+$as_echo_n "checking dynamic linker characteristics... " >&6; }
+
+if test "$GCC" = yes; then
+ case $host_os in
+ darwin*) lt_awk_arg="/^libraries:/,/LR/" ;;
+ *) lt_awk_arg="/^libraries:/" ;;
+ esac
+ lt_search_path_spec=`$CC -print-search-dirs | awk $lt_awk_arg | $SED -e "s/^libraries://" -e "s,=/,/,g"`
+ if $ECHO "$lt_search_path_spec" | $GREP ';' >/dev/null ; then
+ # if the path contains ";" then we assume it to be the separator
+ # otherwise default to the standard path separator (i.e. ":") - it is
+ # assumed that no part of a normal pathname contains ";" but that should
+ # okay in the real world where ";" in dirpaths is itself problematic.
+ lt_search_path_spec=`$ECHO "$lt_search_path_spec" | $SED -e 's/;/ /g'`
+ else
+ lt_search_path_spec=`$ECHO "$lt_search_path_spec" | $SED -e "s/$PATH_SEPARATOR/ /g"`
+ fi
+ # Ok, now we have the path, separated by spaces, we can step through it
+ # and add multilib dir if necessary.
+ lt_tmp_lt_search_path_spec=
+ lt_multi_os_dir=`$CC $CPPFLAGS $CFLAGS $LDFLAGS -print-multi-os-directory 2>/dev/null`
+ for lt_sys_path in $lt_search_path_spec; do
+ if test -d "$lt_sys_path/$lt_multi_os_dir"; then
+ lt_tmp_lt_search_path_spec="$lt_tmp_lt_search_path_spec $lt_sys_path/$lt_multi_os_dir"
+ else
+ test -d "$lt_sys_path" && \
+ lt_tmp_lt_search_path_spec="$lt_tmp_lt_search_path_spec $lt_sys_path"
+ fi
+ done
+ lt_search_path_spec=`$ECHO $lt_tmp_lt_search_path_spec | awk '
+BEGIN {RS=" "; FS="/|\n";} {
+ lt_foo="";
+ lt_count=0;
+ for (lt_i = NF; lt_i > 0; lt_i--) {
+ if ($lt_i != "" && $lt_i != ".") {
+ if ($lt_i == "..") {
+ lt_count++;
+ } else {
+ if (lt_count == 0) {
+ lt_foo="/" $lt_i lt_foo;
+ } else {
+ lt_count--;
+ }
+ }
+ }
+ }
+ if (lt_foo != "") { lt_freq[lt_foo]++; }
+ if (lt_freq[lt_foo] == 1) { print lt_foo; }
+}'`
+ sys_lib_search_path_spec=`$ECHO $lt_search_path_spec`
+else
+ sys_lib_search_path_spec="/lib /usr/lib /usr/local/lib"
+fi
+library_names_spec=
+libname_spec='lib$name'
+soname_spec=
+shrext_cmds=".so"
+postinstall_cmds=
+postuninstall_cmds=
+finish_cmds=
+finish_eval=
+shlibpath_var=
+shlibpath_overrides_runpath=unknown
+version_type=none
+dynamic_linker="$host_os ld.so"
+sys_lib_dlsearch_path_spec="/lib /usr/lib"
+need_lib_prefix=unknown
+hardcode_into_libs=no
+
+# when you set need_version to no, make sure it does not cause -set_version
+# flags to be left without arguments
+need_version=unknown
+
+case $host_os in
+aix3*)
+ version_type=linux
+ library_names_spec='${libname}${release}${shared_ext}$versuffix $libname.a'
+ shlibpath_var=LIBPATH
+
+ # AIX 3 has no versioning support, so we append a major version to the name.
+ soname_spec='${libname}${release}${shared_ext}$major'
+ ;;
+
+aix[4-9]*)
+ version_type=linux
+ need_lib_prefix=no
+ need_version=no
+ hardcode_into_libs=yes
+ if test "$host_cpu" = ia64; then
+ # AIX 5 supports IA64
+ library_names_spec='${libname}${release}${shared_ext}$major ${libname}${release}${shared_ext}$versuffix $libname${shared_ext}'
+ shlibpath_var=LD_LIBRARY_PATH
+ else
+ # With GCC up to 2.95.x, collect2 would create an import file
+ # for dependence libraries. The import file would start with
+ # the line `#! .'. This would cause the generated library to
+ # depend on `.', always an invalid library. This was fixed in
+ # development snapshots of GCC prior to 3.0.
+ case $host_os in
+ aix4 | aix4.[01] | aix4.[01].*)
+ if { echo '#if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 97)'
+ echo ' yes '
+ echo '#endif'; } | ${CC} -E - | $GREP yes > /dev/null; then
+ :
+ else
+ can_build_shared=no
+ fi
+ ;;
+ esac
+ # AIX (on Power*) has no versioning support, so currently we can not hardcode correct
+ # soname into executable. Probably we can add versioning support to
+ # collect2, so additional links can be useful in future.
+ if test "$aix_use_runtimelinking" = yes; then
+ # If using run time linking (on AIX 4.2 or later) use lib<name>.so
+ # instead of lib<name>.a to let people know that these are not
+ # typical AIX shared libraries.
+ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+ else
+ # We preserve .a as extension for shared libraries through AIX4.2
+ # and later when we are not doing run time linking.
+ library_names_spec='${libname}${release}.a $libname.a'
+ soname_spec='${libname}${release}${shared_ext}$major'
+ fi
+ shlibpath_var=LIBPATH
+ fi
+ ;;
+
+amigaos*)
+ case $host_cpu in
+ powerpc)
+ # Since July 2007 AmigaOS4 officially supports .so libraries.
+ # When compiling the executable, add -use-dynld -Lsobjs: to the compileline.
+ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+ ;;
+ m68k)
+ library_names_spec='$libname.ixlibrary $libname.a'
+ # Create ${libname}_ixlibrary.a entries in /sys/libs.
+ finish_eval='for lib in `ls $libdir/*.ixlibrary 2>/dev/null`; do libname=`$ECHO "X$lib" | $Xsed -e '\''s%^.*/\([^/]*\)\.ixlibrary$%\1%'\''`; test $RM /sys/libs/${libname}_ixlibrary.a; $show "cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a"; cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a || exit 1; done'
+ ;;
+ esac
+ ;;
+
+beos*)
+ library_names_spec='${libname}${shared_ext}'
+ dynamic_linker="$host_os ld.so"
+ shlibpath_var=LIBRARY_PATH
+ ;;
+
+bsdi[45]*)
+ version_type=linux
+ need_version=no
+ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+ soname_spec='${libname}${release}${shared_ext}$major'
+ finish_cmds='PATH="\$PATH:/sbin" ldconfig $libdir'
+ shlibpath_var=LD_LIBRARY_PATH
+ sys_lib_search_path_spec="/shlib /usr/lib /usr/X11/lib /usr/contrib/lib /lib /usr/local/lib"
+ sys_lib_dlsearch_path_spec="/shlib /usr/lib /usr/local/lib"
+ # the default ld.so.conf also contains /usr/contrib/lib and
+ # /usr/X11R6/lib (/usr/X11 is a link to /usr/X11R6), but let us allow
+ # libtool to hard-code these into programs
+ ;;
+
+cygwin* | mingw* | pw32* | cegcc*)
+ version_type=windows
+ shrext_cmds=".dll"
+ need_version=no
+ need_lib_prefix=no
+
+ case $GCC,$host_os in
+ yes,cygwin* | yes,mingw* | yes,pw32* | yes,cegcc*)
+ library_names_spec='$libname.dll.a'
+ # DLL is installed to $(libdir)/../bin by postinstall_cmds
+ postinstall_cmds='base_file=`basename \${file}`~
+ dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\${base_file}'\''i; echo \$dlname'\''`~
+ dldir=$destdir/`dirname \$dlpath`~
+ test -d \$dldir || mkdir -p \$dldir~
+ $install_prog $dir/$dlname \$dldir/$dlname~
+ chmod a+x \$dldir/$dlname~
+ if test -n '\''$stripme'\'' && test -n '\''$striplib'\''; then
+ eval '\''$striplib \$dldir/$dlname'\'' || exit \$?;
+ fi'
+ postuninstall_cmds='dldll=`$SHELL 2>&1 -c '\''. $file; echo \$dlname'\''`~
+ dlpath=$dir/\$dldll~
+ $RM \$dlpath'
+ shlibpath_overrides_runpath=yes
+
+ case $host_os in
+ cygwin*)
+ # Cygwin DLLs use 'cyg' prefix rather than 'lib'
+ soname_spec='`echo ${libname} | sed -e 's/^lib/cyg/'``echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext}'
+ sys_lib_search_path_spec="/usr/lib /lib/w32api /lib /usr/local/lib"
+ ;;
+ mingw* | cegcc*)
+ # MinGW DLLs use traditional 'lib' prefix
+ soname_spec='${libname}`echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext}'
+ sys_lib_search_path_spec=`$CC -print-search-dirs | $GREP "^libraries:" | $SED -e "s/^libraries://" -e "s,=/,/,g"`
+ if $ECHO "$sys_lib_search_path_spec" | $GREP ';[c-zC-Z]:/' >/dev/null; then
+ # It is most probably a Windows format PATH printed by
+ # mingw gcc, but we are running on Cygwin. Gcc prints its search
+ # path with ; separators, and with drive letters. We can handle the
+ # drive letters (cygwin fileutils understands them), so leave them,
+ # especially as we might pass files found there to a mingw objdump,
+ # which wouldn't understand a cygwinified path. Ahh.
+ sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | $SED -e 's/;/ /g'`
+ else
+ sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | $SED -e "s/$PATH_SEPARATOR/ /g"`
+ fi
+ ;;
+ pw32*)
+ # pw32 DLLs use 'pw' prefix rather than 'lib'
+ library_names_spec='`echo ${libname} | sed -e 's/^lib/pw/'``echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext}'
+ ;;
+ esac
+ ;;
+
+ *)
+ library_names_spec='${libname}`echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext} $libname.lib'
+ ;;
+ esac
+ dynamic_linker='Win32 ld.exe'
+ # FIXME: first we should search . and the directory the executable is in
+ shlibpath_var=PATH
+ ;;
+
+darwin* | rhapsody*)
+ dynamic_linker="$host_os dyld"
+ version_type=darwin
+ need_lib_prefix=no
+ need_version=no
+ library_names_spec='${libname}${release}${major}$shared_ext ${libname}$shared_ext'
+ soname_spec='${libname}${release}${major}$shared_ext'
+ shlibpath_overrides_runpath=yes
+ shlibpath_var=DYLD_LIBRARY_PATH
+ shrext_cmds='`test .$module = .yes && echo .so || echo .dylib`'
+
+ sys_lib_search_path_spec="$sys_lib_search_path_spec /usr/local/lib"
+ sys_lib_dlsearch_path_spec='/usr/local/lib /lib /usr/lib'
+ ;;
+
+dgux*)
+ version_type=linux
+ need_lib_prefix=no
+ need_version=no
+ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname$shared_ext'
+ soname_spec='${libname}${release}${shared_ext}$major'
+ shlibpath_var=LD_LIBRARY_PATH
+ ;;
+
+freebsd1*)
+ dynamic_linker=no
+ ;;
+
+freebsd* | dragonfly*)
+ # DragonFly does not have aout. When/if they implement a new
+ # versioning mechanism, adjust this.
+ if test -x /usr/bin/objformat; then
+ objformat=`/usr/bin/objformat`
+ else
+ case $host_os in
+ freebsd[123]*) objformat=aout ;;
+ *) objformat=elf ;;
+ esac
+ fi
+ version_type=freebsd-$objformat
+ case $version_type in
+ freebsd-elf*)
+ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext} $libname${shared_ext}'
+ need_version=no
+ need_lib_prefix=no
+ ;;
+ freebsd-*)
+ library_names_spec='${libname}${release}${shared_ext}$versuffix $libname${shared_ext}$versuffix'
+ need_version=yes
+ ;;
+ esac
+ shlibpath_var=LD_LIBRARY_PATH
+ case $host_os in
+ freebsd2*)
+ shlibpath_overrides_runpath=yes
+ ;;
+ freebsd3.[01]* | freebsdelf3.[01]*)
+ shlibpath_overrides_runpath=yes
+ hardcode_into_libs=yes
+ ;;
+ freebsd3.[2-9]* | freebsdelf3.[2-9]* | \
+ freebsd4.[0-5] | freebsdelf4.[0-5] | freebsd4.1.1 | freebsdelf4.1.1)
+ shlibpath_overrides_runpath=no
+ hardcode_into_libs=yes
+ ;;
+ *) # from 4.6 on, and DragonFly
+ shlibpath_overrides_runpath=yes
+ hardcode_into_libs=yes
+ ;;
+ esac
+ ;;
+
+gnu*)
+ version_type=linux
+ need_lib_prefix=no
+ need_version=no
+ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}${major} ${libname}${shared_ext}'
+ soname_spec='${libname}${release}${shared_ext}$major'
+ shlibpath_var=LD_LIBRARY_PATH
+ hardcode_into_libs=yes
+ ;;
+
+hpux9* | hpux10* | hpux11*)
+ # Give a soname corresponding to the major version so that dld.sl refuses to
+ # link against other versions.
+ version_type=sunos
+ need_lib_prefix=no
+ need_version=no
+ case $host_cpu in
+ ia64*)
+ shrext_cmds='.so'
+ hardcode_into_libs=yes
+ dynamic_linker="$host_os dld.so"
+ shlibpath_var=LD_LIBRARY_PATH
+ shlibpath_overrides_runpath=yes # Unless +noenvvar is specified.
+ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+ soname_spec='${libname}${release}${shared_ext}$major'
+ if test "X$HPUX_IA64_MODE" = X32; then
+ sys_lib_search_path_spec="/usr/lib/hpux32 /usr/local/lib/hpux32 /usr/local/lib"
+ else
+ sys_lib_search_path_spec="/usr/lib/hpux64 /usr/local/lib/hpux64"
+ fi
+ sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec
+ ;;
+ hppa*64*)
+ shrext_cmds='.sl'
+ hardcode_into_libs=yes
+ dynamic_linker="$host_os dld.sl"
+ shlibpath_var=LD_LIBRARY_PATH # How should we handle SHLIB_PATH
+ shlibpath_overrides_runpath=yes # Unless +noenvvar is specified.
+ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+ soname_spec='${libname}${release}${shared_ext}$major'
+ sys_lib_search_path_spec="/usr/lib/pa20_64 /usr/ccs/lib/pa20_64"
+ sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec
+ ;;
+ *)
+ shrext_cmds='.sl'
+ dynamic_linker="$host_os dld.sl"
+ shlibpath_var=SHLIB_PATH
+ shlibpath_overrides_runpath=no # +s is required to enable SHLIB_PATH
+ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+ soname_spec='${libname}${release}${shared_ext}$major'
+ ;;
+ esac
+ # HP-UX runs *really* slowly unless shared libraries are mode 555.
+ postinstall_cmds='chmod 555 $lib'
+ ;;
+
+interix[3-9]*)
+ version_type=linux
+ need_lib_prefix=no
+ need_version=no
+ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}'
+ soname_spec='${libname}${release}${shared_ext}$major'
+ dynamic_linker='Interix 3.x ld.so.1 (PE, like ELF)'
+ shlibpath_var=LD_LIBRARY_PATH
+ shlibpath_overrides_runpath=no
+ hardcode_into_libs=yes
+ ;;
+
+irix5* | irix6* | nonstopux*)
+ case $host_os in
+ nonstopux*) version_type=nonstopux ;;
+ *)
+ if test "$lt_cv_prog_gnu_ld" = yes; then
+ version_type=linux
+ else
+ version_type=irix
+ fi ;;
+ esac
+ need_lib_prefix=no
+ need_version=no
+ soname_spec='${libname}${release}${shared_ext}$major'
+ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${release}${shared_ext} $libname${shared_ext}'
+ case $host_os in
+ irix5* | nonstopux*)
+ libsuff= shlibsuff=
+ ;;
+ *)
+ case $LD in # libtool.m4 will add one of these switches to LD
+ *-32|*"-32 "|*-melf32bsmip|*"-melf32bsmip ")
+ libsuff= shlibsuff= libmagic=32-bit;;
+ *-n32|*"-n32 "|*-melf32bmipn32|*"-melf32bmipn32 ")
+ libsuff=32 shlibsuff=N32 libmagic=N32;;
+ *-64|*"-64 "|*-melf64bmip|*"-melf64bmip ")
+ libsuff=64 shlibsuff=64 libmagic=64-bit;;
+ *) libsuff= shlibsuff= libmagic=never-match;;
+ esac
+ ;;
+ esac
+ shlibpath_var=LD_LIBRARY${shlibsuff}_PATH
+ shlibpath_overrides_runpath=no
+ sys_lib_search_path_spec="/usr/lib${libsuff} /lib${libsuff} /usr/local/lib${libsuff}"
+ sys_lib_dlsearch_path_spec="/usr/lib${libsuff} /lib${libsuff}"
+ hardcode_into_libs=yes
+ ;;
+
+# No shared lib support for Linux oldld, aout, or coff.
+linux*oldld* | linux*aout* | linux*coff*)
+ dynamic_linker=no
+ ;;
+
+# This must be Linux ELF.
+linux* | k*bsd*-gnu | kopensolaris*-gnu)
+ version_type=linux
+ need_lib_prefix=no
+ need_version=no
+ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+ soname_spec='${libname}${release}${shared_ext}$major'
+ finish_cmds='PATH="\$PATH:/sbin" ldconfig -n $libdir'
+ shlibpath_var=LD_LIBRARY_PATH
+ shlibpath_overrides_runpath=no
+ # Some binutils ld are patched to set DT_RUNPATH
+ save_LDFLAGS=$LDFLAGS
+ save_libdir=$libdir
+ eval "libdir=/foo; wl=\"$lt_prog_compiler_wl\"; \
+ LDFLAGS=\"\$LDFLAGS $hardcode_libdir_flag_spec\""
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+int
+main ()
+{
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+ if ($OBJDUMP -p conftest$ac_exeext) 2>/dev/null | grep "RUNPATH.*$libdir" >/dev/null; then :
+ shlibpath_overrides_runpath=yes
+fi
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+ LDFLAGS=$save_LDFLAGS
+ libdir=$save_libdir
+
+ # This implies no fast_install, which is unacceptable.
+ # Some rework will be needed to allow for fast_install
+ # before this can be enabled.
+ hardcode_into_libs=yes
+
+ # Append ld.so.conf contents to the search path
+ if test -f /etc/ld.so.conf; then
+ lt_ld_extra=`awk '/^include / { system(sprintf("cd /etc; cat %s 2>/dev/null", \$2)); skip = 1; } { if (!skip) print \$0; skip = 0; }' < /etc/ld.so.conf | $SED -e 's/#.*//;/^[ ]*hwcap[ ]/d;s/[:, ]/ /g;s/=[^=]*$//;s/=[^= ]* / /g;/^$/d' | tr '\n' ' '`
+ sys_lib_dlsearch_path_spec="/lib /usr/lib $lt_ld_extra"
+ fi
+
+ # We used to test for /lib/ld.so.1 and disable shared libraries on
+ # powerpc, because MkLinux only supported shared libraries with the
+ # GNU dynamic linker. Since this was broken with cross compilers,
+ # most powerpc-linux boxes support dynamic linking these days and
+ # people can always --disable-shared, the test was removed, and we
+ # assume the GNU/Linux dynamic linker is in use.
+ dynamic_linker='GNU/Linux ld.so'
+ ;;
+
+netbsdelf*-gnu)
+ version_type=linux
+ need_lib_prefix=no
+ need_version=no
+ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}'
+ soname_spec='${libname}${release}${shared_ext}$major'
+ shlibpath_var=LD_LIBRARY_PATH
+ shlibpath_overrides_runpath=no
+ hardcode_into_libs=yes
+ dynamic_linker='NetBSD ld.elf_so'
+ ;;
+
+netbsd*)
+ version_type=sunos
+ need_lib_prefix=no
+ need_version=no
+ if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then
+ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix'
+ finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir'
+ dynamic_linker='NetBSD (a.out) ld.so'
+ else
+ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}'
+ soname_spec='${libname}${release}${shared_ext}$major'
+ dynamic_linker='NetBSD ld.elf_so'
+ fi
+ shlibpath_var=LD_LIBRARY_PATH
+ shlibpath_overrides_runpath=yes
+ hardcode_into_libs=yes
+ ;;
+
+newsos6)
+ version_type=linux
+ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+ shlibpath_var=LD_LIBRARY_PATH
+ shlibpath_overrides_runpath=yes
+ ;;
+
+*nto* | *qnx*)
+ version_type=qnx
+ need_lib_prefix=no
+ need_version=no
+ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+ soname_spec='${libname}${release}${shared_ext}$major'
+ shlibpath_var=LD_LIBRARY_PATH
+ shlibpath_overrides_runpath=no
+ hardcode_into_libs=yes
+ dynamic_linker='ldqnx.so'
+ ;;
+
+openbsd*)
+ version_type=sunos
+ sys_lib_dlsearch_path_spec="/usr/lib"
+ need_lib_prefix=no
+ # Some older versions of OpenBSD (3.3 at least) *do* need versioned libs.
+ case $host_os in
+ openbsd3.3 | openbsd3.3.*) need_version=yes ;;
+ *) need_version=no ;;
+ esac
+ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix'
+ finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir'
+ shlibpath_var=LD_LIBRARY_PATH
+ if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then
+ case $host_os in
+ openbsd2.[89] | openbsd2.[89].*)
+ shlibpath_overrides_runpath=no
+ ;;
+ *)
+ shlibpath_overrides_runpath=yes
+ ;;
+ esac
+ else
+ shlibpath_overrides_runpath=yes
+ fi
+ ;;
+
+os2*)
+ libname_spec='$name'
+ shrext_cmds=".dll"
+ need_lib_prefix=no
+ library_names_spec='$libname${shared_ext} $libname.a'
+ dynamic_linker='OS/2 ld.exe'
+ shlibpath_var=LIBPATH
+ ;;
+
+osf3* | osf4* | osf5*)
+ version_type=osf
+ need_lib_prefix=no
+ need_version=no
+ soname_spec='${libname}${release}${shared_ext}$major'
+ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+ shlibpath_var=LD_LIBRARY_PATH
+ sys_lib_search_path_spec="/usr/shlib /usr/ccs/lib /usr/lib/cmplrs/cc /usr/lib /usr/local/lib /var/shlib"
+ sys_lib_dlsearch_path_spec="$sys_lib_search_path_spec"
+ ;;
+
+rdos*)
+ dynamic_linker=no
+ ;;
+
+solaris*)
+ version_type=linux
+ need_lib_prefix=no
+ need_version=no
+ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+ soname_spec='${libname}${release}${shared_ext}$major'
+ shlibpath_var=LD_LIBRARY_PATH
+ shlibpath_overrides_runpath=yes
+ hardcode_into_libs=yes
+ # ldd complains unless libraries are executable
+ postinstall_cmds='chmod +x $lib'
+ ;;
+
+sunos4*)
+ version_type=sunos
+ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix'
+ finish_cmds='PATH="\$PATH:/usr/etc" ldconfig $libdir'
+ shlibpath_var=LD_LIBRARY_PATH
+ shlibpath_overrides_runpath=yes
+ if test "$with_gnu_ld" = yes; then
+ need_lib_prefix=no
+ fi
+ need_version=yes
+ ;;
+
+sysv4 | sysv4.3*)
+ version_type=linux
+ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+ soname_spec='${libname}${release}${shared_ext}$major'
+ shlibpath_var=LD_LIBRARY_PATH
+ case $host_vendor in
+ sni)
+ shlibpath_overrides_runpath=no
+ need_lib_prefix=no
+ runpath_var=LD_RUN_PATH
+ ;;
+ siemens)
+ need_lib_prefix=no
+ ;;
+ motorola)
+ need_lib_prefix=no
+ need_version=no
+ shlibpath_overrides_runpath=no
+ sys_lib_search_path_spec='/lib /usr/lib /usr/ccs/lib'
+ ;;
+ esac
+ ;;
+
+sysv4*MP*)
+ if test -d /usr/nec ;then
+ version_type=linux
+ library_names_spec='$libname${shared_ext}.$versuffix $libname${shared_ext}.$major $libname${shared_ext}'
+ soname_spec='$libname${shared_ext}.$major'
+ shlibpath_var=LD_LIBRARY_PATH
+ fi
+ ;;
+
+sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX* | sysv4*uw2*)
+ version_type=freebsd-elf
+ need_lib_prefix=no
+ need_version=no
+ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext} $libname${shared_ext}'
+ soname_spec='${libname}${release}${shared_ext}$major'
+ shlibpath_var=LD_LIBRARY_PATH
+ shlibpath_overrides_runpath=yes
+ hardcode_into_libs=yes
+ if test "$with_gnu_ld" = yes; then
+ sys_lib_search_path_spec='/usr/local/lib /usr/gnu/lib /usr/ccs/lib /usr/lib /lib'
+ else
+ sys_lib_search_path_spec='/usr/ccs/lib /usr/lib'
+ case $host_os in
+ sco3.2v5*)
+ sys_lib_search_path_spec="$sys_lib_search_path_spec /lib"
+ ;;
+ esac
+ fi
+ sys_lib_dlsearch_path_spec='/usr/lib'
+ ;;
+
+tpf*)
+ # TPF is a cross-target only. Preferred cross-host = GNU/Linux.
+ version_type=linux
+ need_lib_prefix=no
+ need_version=no
+ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+ shlibpath_var=LD_LIBRARY_PATH
+ shlibpath_overrides_runpath=no
+ hardcode_into_libs=yes
+ ;;
+
+uts4*)
+ version_type=linux
+ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+ soname_spec='${libname}${release}${shared_ext}$major'
+ shlibpath_var=LD_LIBRARY_PATH
+ ;;
+
+*)
+ dynamic_linker=no
+ ;;
+esac
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $dynamic_linker" >&5
+$as_echo "$dynamic_linker" >&6; }
+test "$dynamic_linker" = no && can_build_shared=no
+
+variables_saved_for_relink="PATH $shlibpath_var $runpath_var"
+if test "$GCC" = yes; then
+ variables_saved_for_relink="$variables_saved_for_relink GCC_EXEC_PREFIX COMPILER_PATH LIBRARY_PATH"
+fi
+
+if test "${lt_cv_sys_lib_search_path_spec+set}" = set; then
+ sys_lib_search_path_spec="$lt_cv_sys_lib_search_path_spec"
+fi
+if test "${lt_cv_sys_lib_dlsearch_path_spec+set}" = set; then
+ sys_lib_dlsearch_path_spec="$lt_cv_sys_lib_dlsearch_path_spec"
+fi
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking how to hardcode library paths into programs" >&5
+$as_echo_n "checking how to hardcode library paths into programs... " >&6; }
+hardcode_action=
+if test -n "$hardcode_libdir_flag_spec" ||
+ test -n "$runpath_var" ||
+ test "X$hardcode_automatic" = "Xyes" ; then
+
+ # We can hardcode non-existent directories.
+ if test "$hardcode_direct" != no &&
+ # If the only mechanism to avoid hardcoding is shlibpath_var, we
+ # have to relink, otherwise we might link with an installed library
+ # when we should be linking with a yet-to-be-installed one
+ ## test "$_LT_TAGVAR(hardcode_shlibpath_var, )" != no &&
+ test "$hardcode_minus_L" != no; then
+ # Linking always hardcodes the temporary library directory.
+ hardcode_action=relink
+ else
+ # We can link without hardcoding, and we can hardcode nonexisting dirs.
+ hardcode_action=immediate
+ fi
+else
+ # We cannot hardcode anything, or else we can only hardcode existing
+ # directories.
+ hardcode_action=unsupported
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $hardcode_action" >&5
+$as_echo "$hardcode_action" >&6; }
+
+if test "$hardcode_action" = relink ||
+ test "$inherit_rpath" = yes; then
+ # Fast installation is not supported
+ enable_fast_install=no
+elif test "$shlibpath_overrides_runpath" = yes ||
+ test "$enable_shared" = no; then
+ # Fast installation is not necessary
+ enable_fast_install=needless
+fi
+
+
+
+
+
+
+ if test "x$enable_dlopen" != xyes; then
+ enable_dlopen=unknown
+ enable_dlopen_self=unknown
+ enable_dlopen_self_static=unknown
+else
+ lt_cv_dlopen=no
+ lt_cv_dlopen_libs=
+
+ case $host_os in
+ beos*)
+ lt_cv_dlopen="load_add_on"
+ lt_cv_dlopen_libs=
+ lt_cv_dlopen_self=yes
+ ;;
+
+ mingw* | pw32* | cegcc*)
+ lt_cv_dlopen="LoadLibrary"
+ lt_cv_dlopen_libs=
+ ;;
+
+ cygwin*)
+ lt_cv_dlopen="dlopen"
+ lt_cv_dlopen_libs=
+ ;;
+
+ darwin*)
+ # if libdl is installed we need to link against it
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for dlopen in -ldl" >&5
+$as_echo_n "checking for dlopen in -ldl... " >&6; }
+if test "${ac_cv_lib_dl_dlopen+set}" = set; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_check_lib_save_LIBS=$LIBS
+LIBS="-ldl $LIBS"
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+/* Override any GCC internal prototype to avoid an error.
+ Use char because int might match the return type of a GCC
+ builtin and then its argument prototype would still apply. */
+#ifdef __cplusplus
+extern "C"
+#endif
+char dlopen ();
+int
+main ()
+{
+return dlopen ();
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+ ac_cv_lib_dl_dlopen=yes
+else
+ ac_cv_lib_dl_dlopen=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_dl_dlopen" >&5
+$as_echo "$ac_cv_lib_dl_dlopen" >&6; }
+if test "x$ac_cv_lib_dl_dlopen" = x""yes; then :
+ lt_cv_dlopen="dlopen" lt_cv_dlopen_libs="-ldl"
+else
+
+ lt_cv_dlopen="dyld"
+ lt_cv_dlopen_libs=
+ lt_cv_dlopen_self=yes
+
+fi
+
+ ;;
+
+ *)
+ ac_fn_c_check_func "$LINENO" "shl_load" "ac_cv_func_shl_load"
+if test "x$ac_cv_func_shl_load" = x""yes; then :
+ lt_cv_dlopen="shl_load"
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for shl_load in -ldld" >&5
+$as_echo_n "checking for shl_load in -ldld... " >&6; }
+if test "${ac_cv_lib_dld_shl_load+set}" = set; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_check_lib_save_LIBS=$LIBS
+LIBS="-ldld $LIBS"
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+/* Override any GCC internal prototype to avoid an error.
+ Use char because int might match the return type of a GCC
+ builtin and then its argument prototype would still apply. */
+#ifdef __cplusplus
+extern "C"
+#endif
+char shl_load ();
+int
+main ()
+{
+return shl_load ();
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+ ac_cv_lib_dld_shl_load=yes
+else
+ ac_cv_lib_dld_shl_load=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_dld_shl_load" >&5
+$as_echo "$ac_cv_lib_dld_shl_load" >&6; }
+if test "x$ac_cv_lib_dld_shl_load" = x""yes; then :
+ lt_cv_dlopen="shl_load" lt_cv_dlopen_libs="-ldld"
+else
+ ac_fn_c_check_func "$LINENO" "dlopen" "ac_cv_func_dlopen"
+if test "x$ac_cv_func_dlopen" = x""yes; then :
+ lt_cv_dlopen="dlopen"
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for dlopen in -ldl" >&5
+$as_echo_n "checking for dlopen in -ldl... " >&6; }
+if test "${ac_cv_lib_dl_dlopen+set}" = set; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_check_lib_save_LIBS=$LIBS
+LIBS="-ldl $LIBS"
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+/* Override any GCC internal prototype to avoid an error.
+ Use char because int might match the return type of a GCC
+ builtin and then its argument prototype would still apply. */
+#ifdef __cplusplus
+extern "C"
+#endif
+char dlopen ();
+int
+main ()
+{
+return dlopen ();
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+ ac_cv_lib_dl_dlopen=yes
+else
+ ac_cv_lib_dl_dlopen=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_dl_dlopen" >&5
+$as_echo "$ac_cv_lib_dl_dlopen" >&6; }
+if test "x$ac_cv_lib_dl_dlopen" = x""yes; then :
+ lt_cv_dlopen="dlopen" lt_cv_dlopen_libs="-ldl"
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for dlopen in -lsvld" >&5
+$as_echo_n "checking for dlopen in -lsvld... " >&6; }
+if test "${ac_cv_lib_svld_dlopen+set}" = set; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_check_lib_save_LIBS=$LIBS
+LIBS="-lsvld $LIBS"
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+/* Override any GCC internal prototype to avoid an error.
+ Use char because int might match the return type of a GCC
+ builtin and then its argument prototype would still apply. */
+#ifdef __cplusplus
+extern "C"
+#endif
+char dlopen ();
+int
+main ()
+{
+return dlopen ();
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+ ac_cv_lib_svld_dlopen=yes
+else
+ ac_cv_lib_svld_dlopen=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_svld_dlopen" >&5
+$as_echo "$ac_cv_lib_svld_dlopen" >&6; }
+if test "x$ac_cv_lib_svld_dlopen" = x""yes; then :
+ lt_cv_dlopen="dlopen" lt_cv_dlopen_libs="-lsvld"
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for dld_link in -ldld" >&5
+$as_echo_n "checking for dld_link in -ldld... " >&6; }
+if test "${ac_cv_lib_dld_dld_link+set}" = set; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_check_lib_save_LIBS=$LIBS
+LIBS="-ldld $LIBS"
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+/* Override any GCC internal prototype to avoid an error.
+ Use char because int might match the return type of a GCC
+ builtin and then its argument prototype would still apply. */
+#ifdef __cplusplus
+extern "C"
+#endif
+char dld_link ();
+int
+main ()
+{
+return dld_link ();
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+ ac_cv_lib_dld_dld_link=yes
+else
+ ac_cv_lib_dld_dld_link=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_dld_dld_link" >&5
+$as_echo "$ac_cv_lib_dld_dld_link" >&6; }
+if test "x$ac_cv_lib_dld_dld_link" = x""yes; then :
+ lt_cv_dlopen="dld_link" lt_cv_dlopen_libs="-ldld"
+fi
+
+
+fi
+
+
+fi
+
+
+fi
+
+
+fi
+
+
+fi
+
+ ;;
+ esac
+
+ if test "x$lt_cv_dlopen" != xno; then
+ enable_dlopen=yes
+ else
+ enable_dlopen=no
+ fi
+
+ case $lt_cv_dlopen in
+ dlopen)
+ save_CPPFLAGS="$CPPFLAGS"
+ test "x$ac_cv_header_dlfcn_h" = xyes && CPPFLAGS="$CPPFLAGS -DHAVE_DLFCN_H"
+
+ save_LDFLAGS="$LDFLAGS"
+ wl=$lt_prog_compiler_wl eval LDFLAGS=\"\$LDFLAGS $export_dynamic_flag_spec\"
+
+ save_LIBS="$LIBS"
+ LIBS="$lt_cv_dlopen_libs $LIBS"
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether a program can dlopen itself" >&5
+$as_echo_n "checking whether a program can dlopen itself... " >&6; }
+if test "${lt_cv_dlopen_self+set}" = set; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test "$cross_compiling" = yes; then :
+ lt_cv_dlopen_self=cross
+else
+ lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
+ lt_status=$lt_dlunknown
+ cat > conftest.$ac_ext <<_LT_EOF
+#line 10210 "configure"
+#include "confdefs.h"
+
+#if HAVE_DLFCN_H
+#include <dlfcn.h>
+#endif
+
+#include <stdio.h>
+
+#ifdef RTLD_GLOBAL
+# define LT_DLGLOBAL RTLD_GLOBAL
+#else
+# ifdef DL_GLOBAL
+# define LT_DLGLOBAL DL_GLOBAL
+# else
+# define LT_DLGLOBAL 0
+# endif
+#endif
+
+/* We may have to define LT_DLLAZY_OR_NOW in the command line if we
+ find out it does not work in some platform. */
+#ifndef LT_DLLAZY_OR_NOW
+# ifdef RTLD_LAZY
+# define LT_DLLAZY_OR_NOW RTLD_LAZY
+# else
+# ifdef DL_LAZY
+# define LT_DLLAZY_OR_NOW DL_LAZY
+# else
+# ifdef RTLD_NOW
+# define LT_DLLAZY_OR_NOW RTLD_NOW
+# else
+# ifdef DL_NOW
+# define LT_DLLAZY_OR_NOW DL_NOW
+# else
+# define LT_DLLAZY_OR_NOW 0
+# endif
+# endif
+# endif
+# endif
+#endif
+
+void fnord() { int i=42;}
+int main ()
+{
+ void *self = dlopen (0, LT_DLGLOBAL|LT_DLLAZY_OR_NOW);
+ int status = $lt_dlunknown;
+
+ if (self)
+ {
+ if (dlsym (self,"fnord")) status = $lt_dlno_uscore;
+ else if (dlsym( self,"_fnord")) status = $lt_dlneed_uscore;
+ /* dlclose (self); */
+ }
+ else
+ puts (dlerror ());
+
+ return status;
+}
+_LT_EOF
+ if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_link\""; } >&5
+ (eval $ac_link) 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; } && test -s conftest${ac_exeext} 2>/dev/null; then
+ (./conftest; exit; ) >&5 2>/dev/null
+ lt_status=$?
+ case x$lt_status in
+ x$lt_dlno_uscore) lt_cv_dlopen_self=yes ;;
+ x$lt_dlneed_uscore) lt_cv_dlopen_self=yes ;;
+ x$lt_dlunknown|x*) lt_cv_dlopen_self=no ;;
+ esac
+ else :
+ # compilation failed
+ lt_cv_dlopen_self=no
+ fi
+fi
+rm -fr conftest*
+
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_dlopen_self" >&5
+$as_echo "$lt_cv_dlopen_self" >&6; }
+
+ if test "x$lt_cv_dlopen_self" = xyes; then
+ wl=$lt_prog_compiler_wl eval LDFLAGS=\"\$LDFLAGS $lt_prog_compiler_static\"
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether a statically linked program can dlopen itself" >&5
+$as_echo_n "checking whether a statically linked program can dlopen itself... " >&6; }
+if test "${lt_cv_dlopen_self_static+set}" = set; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test "$cross_compiling" = yes; then :
+ lt_cv_dlopen_self_static=cross
+else
+ lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
+ lt_status=$lt_dlunknown
+ cat > conftest.$ac_ext <<_LT_EOF
+#line 10306 "configure"
+#include "confdefs.h"
+
+#if HAVE_DLFCN_H
+#include <dlfcn.h>
+#endif
+
+#include <stdio.h>
+
+#ifdef RTLD_GLOBAL
+# define LT_DLGLOBAL RTLD_GLOBAL
+#else
+# ifdef DL_GLOBAL
+# define LT_DLGLOBAL DL_GLOBAL
+# else
+# define LT_DLGLOBAL 0
+# endif
+#endif
+
+/* We may have to define LT_DLLAZY_OR_NOW in the command line if we
+ find out it does not work in some platform. */
+#ifndef LT_DLLAZY_OR_NOW
+# ifdef RTLD_LAZY
+# define LT_DLLAZY_OR_NOW RTLD_LAZY
+# else
+# ifdef DL_LAZY
+# define LT_DLLAZY_OR_NOW DL_LAZY
+# else
+# ifdef RTLD_NOW
+# define LT_DLLAZY_OR_NOW RTLD_NOW
+# else
+# ifdef DL_NOW
+# define LT_DLLAZY_OR_NOW DL_NOW
+# else
+# define LT_DLLAZY_OR_NOW 0
+# endif
+# endif
+# endif
+# endif
+#endif
+
+void fnord() { int i=42;}
+int main ()
+{
+ void *self = dlopen (0, LT_DLGLOBAL|LT_DLLAZY_OR_NOW);
+ int status = $lt_dlunknown;
+
+ if (self)
+ {
+ if (dlsym (self,"fnord")) status = $lt_dlno_uscore;
+ else if (dlsym( self,"_fnord")) status = $lt_dlneed_uscore;
+ /* dlclose (self); */
+ }
+ else
+ puts (dlerror ());
+
+ return status;
+}
+_LT_EOF
+ if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_link\""; } >&5
+ (eval $ac_link) 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; } && test -s conftest${ac_exeext} 2>/dev/null; then
+ (./conftest; exit; ) >&5 2>/dev/null
+ lt_status=$?
+ case x$lt_status in
+ x$lt_dlno_uscore) lt_cv_dlopen_self_static=yes ;;
+ x$lt_dlneed_uscore) lt_cv_dlopen_self_static=yes ;;
+ x$lt_dlunknown|x*) lt_cv_dlopen_self_static=no ;;
+ esac
+ else :
+ # compilation failed
+ lt_cv_dlopen_self_static=no
+ fi
+fi
+rm -fr conftest*
+
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_dlopen_self_static" >&5
+$as_echo "$lt_cv_dlopen_self_static" >&6; }
+ fi
+
+ CPPFLAGS="$save_CPPFLAGS"
+ LDFLAGS="$save_LDFLAGS"
+ LIBS="$save_LIBS"
+ ;;
+ esac
+
+ case $lt_cv_dlopen_self in
+ yes|no) enable_dlopen_self=$lt_cv_dlopen_self ;;
+ *) enable_dlopen_self=unknown ;;
+ esac
+
+ case $lt_cv_dlopen_self_static in
+ yes|no) enable_dlopen_self_static=$lt_cv_dlopen_self_static ;;
+ *) enable_dlopen_self_static=unknown ;;
+ esac
+fi
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+striplib=
+old_striplib=
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether stripping libraries is possible" >&5
+$as_echo_n "checking whether stripping libraries is possible... " >&6; }
+if test -n "$STRIP" && $STRIP -V 2>&1 | $GREP "GNU strip" >/dev/null; then
+ test -z "$old_striplib" && old_striplib="$STRIP --strip-debug"
+ test -z "$striplib" && striplib="$STRIP --strip-unneeded"
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+else
+# FIXME - insert some real tests, host_os isn't really good enough
+ case $host_os in
+ darwin*)
+ if test -n "$STRIP" ; then
+ striplib="$STRIP -x"
+ old_striplib="$STRIP -S"
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+ else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+ fi
+ ;;
+ *)
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+ ;;
+ esac
+fi
+
+
+
+
+
+
+
+
+
+
+
+
+ # Report which library types will actually be built
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking if libtool supports shared libraries" >&5
+$as_echo_n "checking if libtool supports shared libraries... " >&6; }
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $can_build_shared" >&5
+$as_echo "$can_build_shared" >&6; }
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to build shared libraries" >&5
+$as_echo_n "checking whether to build shared libraries... " >&6; }
+ test "$can_build_shared" = "no" && enable_shared=no
+
+ # On AIX, shared libraries and static libraries use the same namespace, and
+ # are all built from PIC.
+ case $host_os in
+ aix3*)
+ test "$enable_shared" = yes && enable_static=no
+ if test -n "$RANLIB"; then
+ archive_cmds="$archive_cmds~\$RANLIB \$lib"
+ postinstall_cmds='$RANLIB $lib'
+ fi
+ ;;
+
+ aix[4-9]*)
+ if test "$host_cpu" != ia64 && test "$aix_use_runtimelinking" = no ; then
+ test "$enable_shared" = yes && enable_static=no
+ fi
+ ;;
+ esac
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $enable_shared" >&5
+$as_echo "$enable_shared" >&6; }
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to build static libraries" >&5
+$as_echo_n "checking whether to build static libraries... " >&6; }
+ # Make sure either enable_shared or enable_static is yes.
+ test "$enable_shared" = yes || enable_static=yes
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $enable_static" >&5
+$as_echo "$enable_static" >&6; }
+
+
+
+
+fi
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+CC="$lt_save_CC"
+
+
+
+
+
+
+
+
+
+
+
+
+
+ ac_config_commands="$ac_config_commands libtool"
+
+
+
+
+# Only expand once:
+
+
+
+# Extract the first word of "doxygen", so it can be a program name with args.
+set dummy doxygen; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if test "${ac_cv_prog_DOXYGEN+set}" = set; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$DOXYGEN"; then
+ ac_cv_prog_DOXYGEN="$DOXYGEN" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+ ac_cv_prog_DOXYGEN="true"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+ test -z "$ac_cv_prog_DOXYGEN" && ac_cv_prog_DOXYGEN="false"
+fi
+fi
+DOXYGEN=$ac_cv_prog_DOXYGEN
+if test -n "$DOXYGEN"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $DOXYGEN" >&5
+$as_echo "$DOXYGEN" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+ if test "$DOXYGEN" = true; then
+ DOXYGEN_TRUE=
+ DOXYGEN_FALSE='#'
+else
+ DOXYGEN_TRUE='#'
+ DOXYGEN_FALSE=
+fi
+
+
+# Checks for header files.
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for ANSI C header files" >&5
+$as_echo_n "checking for ANSI C header files... " >&6; }
+if test "${ac_cv_header_stdc+set}" = set; then :
+ $as_echo_n "(cached) " >&6
+else
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#include <stdlib.h>
+#include <stdarg.h>
+#include <string.h>
+#include <float.h>
+
+int
+main ()
+{
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+ ac_cv_header_stdc=yes
+else
+ ac_cv_header_stdc=no
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+
+if test $ac_cv_header_stdc = yes; then
+ # SunOS 4.x string.h does not declare mem*, contrary to ANSI.
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#include <string.h>
+
+_ACEOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+ $EGREP "memchr" >/dev/null 2>&1; then :
+
+else
+ ac_cv_header_stdc=no
+fi
+rm -f conftest*
+
+fi
+
+if test $ac_cv_header_stdc = yes; then
+ # ISC 2.0.2 stdlib.h does not declare free, contrary to ANSI.
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#include <stdlib.h>
+
+_ACEOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+ $EGREP "free" >/dev/null 2>&1; then :
+
+else
+ ac_cv_header_stdc=no
+fi
+rm -f conftest*
+
+fi
+
+if test $ac_cv_header_stdc = yes; then
+ # /bin/cc in Irix-4.0.5 gets non-ANSI ctype macros unless using -ansi.
+ if test "$cross_compiling" = yes; then :
+ :
+else
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#include <ctype.h>
+#include <stdlib.h>
+#if ((' ' & 0x0FF) == 0x020)
+# define ISLOWER(c) ('a' <= (c) && (c) <= 'z')
+# define TOUPPER(c) (ISLOWER(c) ? 'A' + ((c) - 'a') : (c))
+#else
+# define ISLOWER(c) \
+ (('a' <= (c) && (c) <= 'i') \
+ || ('j' <= (c) && (c) <= 'r') \
+ || ('s' <= (c) && (c) <= 'z'))
+# define TOUPPER(c) (ISLOWER(c) ? ((c) | 0x40) : (c))
+#endif
+
+#define XOR(e, f) (((e) && !(f)) || (!(e) && (f)))
+int
+main ()
+{
+ int i;
+ for (i = 0; i < 256; i++)
+ if (XOR (islower (i), ISLOWER (i))
+ || toupper (i) != TOUPPER (i))
+ return 2;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_run "$LINENO"; then :
+
+else
+ ac_cv_header_stdc=no
+fi
+rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \
+ conftest.$ac_objext conftest.beam conftest.$ac_ext
+fi
+
+fi
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_header_stdc" >&5
+$as_echo "$ac_cv_header_stdc" >&6; }
+if test $ac_cv_header_stdc = yes; then
+
+$as_echo "#define STDC_HEADERS 1" >>confdefs.h
+
+fi
+
+for ac_header in stdlib.h
+do :
+ ac_fn_c_check_header_mongrel "$LINENO" "stdlib.h" "ac_cv_header_stdlib_h" "$ac_includes_default"
+if test "x$ac_cv_header_stdlib_h" = x""yes; then :
+ cat >>confdefs.h <<_ACEOF
+#define HAVE_STDLIB_H 1
+_ACEOF
+
+fi
+
+done
+
+
+# Checks for typedefs, structures, and compiler characteristics.
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for an ANSI C-conforming const" >&5
+$as_echo_n "checking for an ANSI C-conforming const... " >&6; }
+if test "${ac_cv_c_const+set}" = set; then :
+ $as_echo_n "(cached) " >&6
+else
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+int
+main ()
+{
+/* FIXME: Include the comments suggested by Paul. */
+#ifndef __cplusplus
+ /* Ultrix mips cc rejects this. */
+ typedef int charset[2];
+ const charset cs;
+ /* SunOS 4.1.1 cc rejects this. */
+ char const *const *pcpcc;
+ char **ppc;
+ /* NEC SVR4.0.2 mips cc rejects this. */
+ struct point {int x, y;};
+ static struct point const zero = {0,0};
+ /* AIX XL C 1.02.0.0 rejects this.
+ It does not let you subtract one const X* pointer from another in
+ an arm of an if-expression whose if-part is not a constant
+ expression */
+ const char *g = "string";
+ pcpcc = &g + (g ? g-g : 0);
+ /* HPUX 7.0 cc rejects these. */
+ ++pcpcc;
+ ppc = (char**) pcpcc;
+ pcpcc = (char const *const *) ppc;
+ { /* SCO 3.2v4 cc rejects this. */
+ char *t;
+ char const *s = 0 ? (char *) 0 : (char const *) 0;
+
+ *t++ = 0;
+ if (s) return 0;
+ }
+ { /* Someone thinks the Sun supposedly-ANSI compiler will reject this. */
+ int x[] = {25, 17};
+ const int *foo = &x[0];
+ ++foo;
+ }
+ { /* Sun SC1.0 ANSI compiler rejects this -- but not the above. */
+ typedef const int *iptr;
+ iptr p = 0;
+ ++p;
+ }
+ { /* AIX XL C 1.02.0.0 rejects this saying
+ "k.c", line 2.27: 1506-025 (S) Operand must be a modifiable lvalue. */
+ struct s { int j; const int *ap[3]; };
+ struct s *b; b->j = 5;
+ }
+ { /* ULTRIX-32 V3.1 (Rev 9) vcc rejects this */
+ const int foo = 10;
+ if (!foo) return 0;
+ }
+ return !cs[0] && !zero.x;
+#endif
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+ ac_cv_c_const=yes
+else
+ ac_cv_c_const=no
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_c_const" >&5
+$as_echo "$ac_cv_c_const" >&6; }
+if test $ac_cv_c_const = no; then
+
+$as_echo "#define const /**/" >>confdefs.h
+
+fi
+
+ac_fn_c_check_type "$LINENO" "size_t" "ac_cv_type_size_t" "$ac_includes_default"
+if test "x$ac_cv_type_size_t" = x""yes; then :
+
+else
+
+cat >>confdefs.h <<_ACEOF
+#define size_t unsigned int
+_ACEOF
+
+fi
+
+
+# Define Makefiles.
+ac_config_files="$ac_config_files yaml-0.1.pc include/Makefile src/Makefile Makefile tests/Makefile win32/Makefile"
+
+
+# Generate the "configure" script.
+cat >confcache <<\_ACEOF
+# This file is a shell script that caches the results of configure
+# tests run on this system so they can be shared between configure
+# scripts and configure runs, see configure's option --config-cache.
+# It is not useful on other systems. If it contains results you don't
+# want to keep, you may remove or edit it.
+#
+# config.status only pays attention to the cache file if you give it
+# the --recheck option to rerun configure.
+#
+# `ac_cv_env_foo' variables (set or unset) will be overridden when
+# loading this file, other *unset* `ac_cv_foo' will be assigned the
+# following values.
+
+_ACEOF
+
+# The following way of writing the cache mishandles newlines in values,
+# but we know of no workaround that is simple, portable, and efficient.
+# So, we kill variables containing newlines.
+# Ultrix sh set writes to stderr and can't be redirected directly,
+# and sets the high bit in the cache file unless we assign to the vars.
+(
+ for ac_var in `(set) 2>&1 | sed -n 's/^\([a-zA-Z_][a-zA-Z0-9_]*\)=.*/\1/p'`; do
+ eval ac_val=\$$ac_var
+ case $ac_val in #(
+ *${as_nl}*)
+ case $ac_var in #(
+ *_cv_*) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: cache variable $ac_var contains a newline" >&5
+$as_echo "$as_me: WARNING: cache variable $ac_var contains a newline" >&2;} ;;
+ esac
+ case $ac_var in #(
+ _ | IFS | as_nl) ;; #(
+ BASH_ARGV | BASH_SOURCE) eval $ac_var= ;; #(
+ *) { eval $ac_var=; unset $ac_var;} ;;
+ esac ;;
+ esac
+ done
+
+ (set) 2>&1 |
+ case $as_nl`(ac_space=' '; set) 2>&1` in #(
+ *${as_nl}ac_space=\ *)
+ # `set' does not quote correctly, so add quotes: double-quote
+ # substitution turns \\\\ into \\, and sed turns \\ into \.
+ sed -n \
+ "s/'/'\\\\''/g;
+ s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='\\2'/p"
+ ;; #(
+ *)
+ # `set' quotes correctly as required by POSIX, so do not add quotes.
+ sed -n "/^[_$as_cr_alnum]*_cv_[_$as_cr_alnum]*=/p"
+ ;;
+ esac |
+ sort
+) |
+ sed '
+ /^ac_cv_env_/b end
+ t clear
+ :clear
+ s/^\([^=]*\)=\(.*[{}].*\)$/test "${\1+set}" = set || &/
+ t end
+ s/^\([^=]*\)=\(.*\)$/\1=${\1=\2}/
+ :end' >>confcache
+if diff "$cache_file" confcache >/dev/null 2>&1; then :; else
+ if test -w "$cache_file"; then
+ test "x$cache_file" != "x/dev/null" &&
+ { $as_echo "$as_me:${as_lineno-$LINENO}: updating cache $cache_file" >&5
+$as_echo "$as_me: updating cache $cache_file" >&6;}
+ cat confcache >$cache_file
+ else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: not updating unwritable cache $cache_file" >&5
+$as_echo "$as_me: not updating unwritable cache $cache_file" >&6;}
+ fi
+fi
+rm -f confcache
+
+test "x$prefix" = xNONE && prefix=$ac_default_prefix
+# Let make expand exec_prefix.
+test "x$exec_prefix" = xNONE && exec_prefix='${prefix}'
+
+DEFS=-DHAVE_CONFIG_H
+
+ac_libobjs=
+ac_ltlibobjs=
+U=
+for ac_i in : $LIBOBJS; do test "x$ac_i" = x: && continue
+ # 1. Remove the extension, and $U if already installed.
+ ac_script='s/\$U\././;s/\.o$//;s/\.obj$//'
+ ac_i=`$as_echo "$ac_i" | sed "$ac_script"`
+ # 2. Prepend LIBOBJDIR. When used with automake>=1.10 LIBOBJDIR
+ # will be set to the directory where LIBOBJS objects are built.
+ as_fn_append ac_libobjs " \${LIBOBJDIR}$ac_i\$U.$ac_objext"
+ as_fn_append ac_ltlibobjs " \${LIBOBJDIR}$ac_i"'$U.lo'
+done
+LIBOBJS=$ac_libobjs
+
+LTLIBOBJS=$ac_ltlibobjs
+
+
+ if test -n "$EXEEXT"; then
+ am__EXEEXT_TRUE=
+ am__EXEEXT_FALSE='#'
+else
+ am__EXEEXT_TRUE='#'
+ am__EXEEXT_FALSE=
+fi
+
+if test -z "${AMDEP_TRUE}" && test -z "${AMDEP_FALSE}"; then
+ as_fn_error $? "conditional \"AMDEP\" was never defined.
+Usually this means the macro was only invoked conditionally." "$LINENO" 5
+fi
+if test -z "${am__fastdepCC_TRUE}" && test -z "${am__fastdepCC_FALSE}"; then
+ as_fn_error $? "conditional \"am__fastdepCC\" was never defined.
+Usually this means the macro was only invoked conditionally." "$LINENO" 5
+fi
+if test -z "${DOXYGEN_TRUE}" && test -z "${DOXYGEN_FALSE}"; then
+ as_fn_error $? "conditional \"DOXYGEN\" was never defined.
+Usually this means the macro was only invoked conditionally." "$LINENO" 5
+fi
+
+: ${CONFIG_STATUS=./config.status}
+ac_write_fail=0
+ac_clean_files_save=$ac_clean_files
+ac_clean_files="$ac_clean_files $CONFIG_STATUS"
+{ $as_echo "$as_me:${as_lineno-$LINENO}: creating $CONFIG_STATUS" >&5
+$as_echo "$as_me: creating $CONFIG_STATUS" >&6;}
+as_write_fail=0
+cat >$CONFIG_STATUS <<_ASEOF || as_write_fail=1
+#! $SHELL
+# Generated by $as_me.
+# Run this file to recreate the current configuration.
+# Compiler output produced by configure, useful for debugging
+# configure, is in config.log if it exists.
+
+debug=false
+ac_cs_recheck=false
+ac_cs_silent=false
+
+SHELL=\${CONFIG_SHELL-$SHELL}
+export SHELL
+_ASEOF
+cat >>$CONFIG_STATUS <<\_ASEOF || as_write_fail=1
+## -------------------- ##
+## M4sh Initialization. ##
+## -------------------- ##
+
+# Be more Bourne compatible
+DUALCASE=1; export DUALCASE # for MKS sh
+if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then :
+ emulate sh
+ NULLCMD=:
+ # Pre-4.2 versions of Zsh do word splitting on ${1+"$@"}, which
+ # is contrary to our usage. Disable this feature.
+ alias -g '${1+"$@"}'='"$@"'
+ setopt NO_GLOB_SUBST
+else
+ case `(set -o) 2>/dev/null` in #(
+ *posix*) :
+ set -o posix ;; #(
+ *) :
+ ;;
+esac
+fi
+
+
+as_nl='
+'
+export as_nl
+# Printing a long string crashes Solaris 7 /usr/bin/printf.
+as_echo='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\'
+as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo
+as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo$as_echo
+# Prefer a ksh shell builtin over an external printf program on Solaris,
+# but without wasting forks for bash or zsh.
+if test -z "$BASH_VERSION$ZSH_VERSION" \
+ && (test "X`print -r -- $as_echo`" = "X$as_echo") 2>/dev/null; then
+ as_echo='print -r --'
+ as_echo_n='print -rn --'
+elif (test "X`printf %s $as_echo`" = "X$as_echo") 2>/dev/null; then
+ as_echo='printf %s\n'
+ as_echo_n='printf %s'
+else
+ if test "X`(/usr/ucb/echo -n -n $as_echo) 2>/dev/null`" = "X-n $as_echo"; then
+ as_echo_body='eval /usr/ucb/echo -n "$1$as_nl"'
+ as_echo_n='/usr/ucb/echo -n'
+ else
+ as_echo_body='eval expr "X$1" : "X\\(.*\\)"'
+ as_echo_n_body='eval
+ arg=$1;
+ case $arg in #(
+ *"$as_nl"*)
+ expr "X$arg" : "X\\(.*\\)$as_nl";
+ arg=`expr "X$arg" : ".*$as_nl\\(.*\\)"`;;
+ esac;
+ expr "X$arg" : "X\\(.*\\)" | tr -d "$as_nl"
+ '
+ export as_echo_n_body
+ as_echo_n='sh -c $as_echo_n_body as_echo'
+ fi
+ export as_echo_body
+ as_echo='sh -c $as_echo_body as_echo'
+fi
+
+# The user is always right.
+if test "${PATH_SEPARATOR+set}" != set; then
+ PATH_SEPARATOR=:
+ (PATH='/bin;/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 && {
+ (PATH='/bin:/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 ||
+ PATH_SEPARATOR=';'
+ }
+fi
+
+
+# IFS
+# We need space, tab and new line, in precisely that order. Quoting is
+# there to prevent editors from complaining about space-tab.
+# (If _AS_PATH_WALK were called with IFS unset, it would disable word
+# splitting by setting IFS to empty value.)
+IFS=" "" $as_nl"
+
+# Find who we are. Look in the path if we contain no directory separator.
+case $0 in #((
+ *[\\/]* ) as_myself=$0 ;;
+ *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break
+ done
+IFS=$as_save_IFS
+
+ ;;
+esac
+# We did not find ourselves, most probably we were run as `sh COMMAND'
+# in which case we are not to be found in the path.
+if test "x$as_myself" = x; then
+ as_myself=$0
+fi
+if test ! -f "$as_myself"; then
+ $as_echo "$as_myself: error: cannot find myself; rerun with an absolute file name" >&2
+ exit 1
+fi
+
+# Unset variables that we do not need and which cause bugs (e.g. in
+# pre-3.0 UWIN ksh). But do not cause bugs in bash 2.01; the "|| exit 1"
+# suppresses any "Segmentation fault" message there. '((' could
+# trigger a bug in pdksh 5.2.14.
+for as_var in BASH_ENV ENV MAIL MAILPATH
+do eval test x\${$as_var+set} = xset \
+ && ( (unset $as_var) || exit 1) >/dev/null 2>&1 && unset $as_var || :
+done
+PS1='$ '
+PS2='> '
+PS4='+ '
+
+# NLS nuisances.
+LC_ALL=C
+export LC_ALL
+LANGUAGE=C
+export LANGUAGE
+
+# CDPATH.
+(unset CDPATH) >/dev/null 2>&1 && unset CDPATH
+
+
+# as_fn_error STATUS ERROR [LINENO LOG_FD]
+# ----------------------------------------
+# Output "`basename $0`: error: ERROR" to stderr. If LINENO and LOG_FD are
+# provided, also output the error to LOG_FD, referencing LINENO. Then exit the
+# script with STATUS, using 1 if that was 0.
+as_fn_error ()
+{
+ as_status=$1; test $as_status -eq 0 && as_status=1
+ if test "$4"; then
+ as_lineno=${as_lineno-"$3"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
+ $as_echo "$as_me:${as_lineno-$LINENO}: error: $2" >&$4
+ fi
+ $as_echo "$as_me: error: $2" >&2
+ as_fn_exit $as_status
+} # as_fn_error
+
+
+# as_fn_set_status STATUS
+# -----------------------
+# Set $? to STATUS, without forking.
+as_fn_set_status ()
+{
+ return $1
+} # as_fn_set_status
+
+# as_fn_exit STATUS
+# -----------------
+# Exit the shell with STATUS, even in a "trap 0" or "set -e" context.
+as_fn_exit ()
+{
+ set +e
+ as_fn_set_status $1
+ exit $1
+} # as_fn_exit
+
+# as_fn_unset VAR
+# ---------------
+# Portably unset VAR.
+as_fn_unset ()
+{
+ { eval $1=; unset $1;}
+}
+as_unset=as_fn_unset
+# as_fn_append VAR VALUE
+# ----------------------
+# Append the text in VALUE to the end of the definition contained in VAR. Take
+# advantage of any shell optimizations that allow amortized linear growth over
+# repeated appends, instead of the typical quadratic growth present in naive
+# implementations.
+if (eval "as_var=1; as_var+=2; test x\$as_var = x12") 2>/dev/null; then :
+ eval 'as_fn_append ()
+ {
+ eval $1+=\$2
+ }'
+else
+ as_fn_append ()
+ {
+ eval $1=\$$1\$2
+ }
+fi # as_fn_append
+
+# as_fn_arith ARG...
+# ------------------
+# Perform arithmetic evaluation on the ARGs, and store the result in the
+# global $as_val. Take advantage of shells that can avoid forks. The arguments
+# must be portable across $(()) and expr.
+if (eval "test \$(( 1 + 1 )) = 2") 2>/dev/null; then :
+ eval 'as_fn_arith ()
+ {
+ as_val=$(( $* ))
+ }'
+else
+ as_fn_arith ()
+ {
+ as_val=`expr "$@" || test $? -eq 1`
+ }
+fi # as_fn_arith
+
+
+if expr a : '\(a\)' >/dev/null 2>&1 &&
+ test "X`expr 00001 : '.*\(...\)'`" = X001; then
+ as_expr=expr
+else
+ as_expr=false
+fi
+
+if (basename -- /) >/dev/null 2>&1 && test "X`basename -- / 2>&1`" = "X/"; then
+ as_basename=basename
+else
+ as_basename=false
+fi
+
+if (as_dir=`dirname -- /` && test "X$as_dir" = X/) >/dev/null 2>&1; then
+ as_dirname=dirname
+else
+ as_dirname=false
+fi
+
+as_me=`$as_basename -- "$0" ||
+$as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \
+ X"$0" : 'X\(//\)$' \| \
+ X"$0" : 'X\(/\)' \| . 2>/dev/null ||
+$as_echo X/"$0" |
+ sed '/^.*\/\([^/][^/]*\)\/*$/{
+ s//\1/
+ q
+ }
+ /^X\/\(\/\/\)$/{
+ s//\1/
+ q
+ }
+ /^X\/\(\/\).*/{
+ s//\1/
+ q
+ }
+ s/.*/./; q'`
+
+# Avoid depending upon Character Ranges.
+as_cr_letters='abcdefghijklmnopqrstuvwxyz'
+as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ'
+as_cr_Letters=$as_cr_letters$as_cr_LETTERS
+as_cr_digits='0123456789'
+as_cr_alnum=$as_cr_Letters$as_cr_digits
+
+ECHO_C= ECHO_N= ECHO_T=
+case `echo -n x` in #(((((
+-n*)
+ case `echo 'xy\c'` in
+ *c*) ECHO_T=' ';; # ECHO_T is single tab character.
+ xy) ECHO_C='\c';;
+ *) echo `echo ksh88 bug on AIX 6.1` > /dev/null
+ ECHO_T=' ';;
+ esac;;
+*)
+ ECHO_N='-n';;
+esac
+
+rm -f conf$$ conf$$.exe conf$$.file
+if test -d conf$$.dir; then
+ rm -f conf$$.dir/conf$$.file
+else
+ rm -f conf$$.dir
+ mkdir conf$$.dir 2>/dev/null
+fi
+if (echo >conf$$.file) 2>/dev/null; then
+ if ln -s conf$$.file conf$$ 2>/dev/null; then
+ as_ln_s='ln -s'
+ # ... but there are two gotchas:
+ # 1) On MSYS, both `ln -s file dir' and `ln file dir' fail.
+ # 2) DJGPP < 2.04 has no symlinks; `ln -s' creates a wrapper executable.
+ # In both cases, we have to default to `cp -p'.
+ ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe ||
+ as_ln_s='cp -p'
+ elif ln conf$$.file conf$$ 2>/dev/null; then
+ as_ln_s=ln
+ else
+ as_ln_s='cp -p'
+ fi
+else
+ as_ln_s='cp -p'
+fi
+rm -f conf$$ conf$$.exe conf$$.dir/conf$$.file conf$$.file
+rmdir conf$$.dir 2>/dev/null
+
+
+# as_fn_mkdir_p
+# -------------
+# Create "$as_dir" as a directory, including parents if necessary.
+as_fn_mkdir_p ()
+{
+
+ case $as_dir in #(
+ -*) as_dir=./$as_dir;;
+ esac
+ test -d "$as_dir" || eval $as_mkdir_p || {
+ as_dirs=
+ while :; do
+ case $as_dir in #(
+ *\'*) as_qdir=`$as_echo "$as_dir" | sed "s/'/'\\\\\\\\''/g"`;; #'(
+ *) as_qdir=$as_dir;;
+ esac
+ as_dirs="'$as_qdir' $as_dirs"
+ as_dir=`$as_dirname -- "$as_dir" ||
+$as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
+ X"$as_dir" : 'X\(//\)[^/]' \| \
+ X"$as_dir" : 'X\(//\)$' \| \
+ X"$as_dir" : 'X\(/\)' \| . 2>/dev/null ||
+$as_echo X"$as_dir" |
+ sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{
+ s//\1/
+ q
+ }
+ /^X\(\/\/\)[^/].*/{
+ s//\1/
+ q
+ }
+ /^X\(\/\/\)$/{
+ s//\1/
+ q
+ }
+ /^X\(\/\).*/{
+ s//\1/
+ q
+ }
+ s/.*/./; q'`
+ test -d "$as_dir" && break
+ done
+ test -z "$as_dirs" || eval "mkdir $as_dirs"
+ } || test -d "$as_dir" || as_fn_error $? "cannot create directory $as_dir"
+
+
+} # as_fn_mkdir_p
+if mkdir -p . 2>/dev/null; then
+ as_mkdir_p='mkdir -p "$as_dir"'
+else
+ test -d ./-p && rmdir ./-p
+ as_mkdir_p=false
+fi
+
+if test -x / >/dev/null 2>&1; then
+ as_test_x='test -x'
+else
+ if ls -dL / >/dev/null 2>&1; then
+ as_ls_L_option=L
+ else
+ as_ls_L_option=
+ fi
+ as_test_x='
+ eval sh -c '\''
+ if test -d "$1"; then
+ test -d "$1/.";
+ else
+ case $1 in #(
+ -*)set "./$1";;
+ esac;
+ case `ls -ld'$as_ls_L_option' "$1" 2>/dev/null` in #((
+ ???[sx]*):;;*)false;;esac;fi
+ '\'' sh
+ '
+fi
+as_executable_p=$as_test_x
+
+# Sed expression to map a string onto a valid CPP name.
+as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'"
+
+# Sed expression to map a string onto a valid variable name.
+as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'"
+
+
+exec 6>&1
+## ----------------------------------- ##
+## Main body of $CONFIG_STATUS script. ##
+## ----------------------------------- ##
+_ASEOF
+test $as_write_fail = 0 && chmod +x $CONFIG_STATUS || ac_write_fail=1
+
+cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
+# Save the log message, to keep $0 and so on meaningful, and to
+# report actual input values of CONFIG_FILES etc. instead of their
+# values after options handling.
+ac_log="
+This file was extended by yaml $as_me 0.1.4, which was
+generated by GNU Autoconf 2.67. Invocation command line was
+
+ CONFIG_FILES = $CONFIG_FILES
+ CONFIG_HEADERS = $CONFIG_HEADERS
+ CONFIG_LINKS = $CONFIG_LINKS
+ CONFIG_COMMANDS = $CONFIG_COMMANDS
+ $ $0 $@
+
+on `(hostname || uname -n) 2>/dev/null | sed 1q`
+"
+
+_ACEOF
+
+case $ac_config_files in *"
+"*) set x $ac_config_files; shift; ac_config_files=$*;;
+esac
+
+case $ac_config_headers in *"
+"*) set x $ac_config_headers; shift; ac_config_headers=$*;;
+esac
+
+
+cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
+# Files that config.status was made for.
+config_files="$ac_config_files"
+config_headers="$ac_config_headers"
+config_commands="$ac_config_commands"
+
+_ACEOF
+
+cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
+ac_cs_usage="\
+\`$as_me' instantiates files and other configuration actions
+from templates according to the current configuration. Unless the files
+and actions are specified as TAGs, all are instantiated by default.
+
+Usage: $0 [OPTION]... [TAG]...
+
+ -h, --help print this help, then exit
+ -V, --version print version number and configuration settings, then exit
+ --config print configuration, then exit
+ -q, --quiet, --silent
+ do not print progress messages
+ -d, --debug don't remove temporary files
+ --recheck update $as_me by reconfiguring in the same conditions
+ --file=FILE[:TEMPLATE]
+ instantiate the configuration file FILE
+ --header=FILE[:TEMPLATE]
+ instantiate the configuration header FILE
+
+Configuration files:
+$config_files
+
+Configuration headers:
+$config_headers
+
+Configuration commands:
+$config_commands
+
+Report bugs to <http://pyyaml.org/newticket?component=libyaml>."
+
+_ACEOF
+cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
+ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`"
+ac_cs_version="\\
+yaml config.status 0.1.4
+configured by $0, generated by GNU Autoconf 2.67,
+ with options \\"\$ac_cs_config\\"
+
+Copyright (C) 2010 Free Software Foundation, Inc.
+This config.status script is free software; the Free Software Foundation
+gives unlimited permission to copy, distribute and modify it."
+
+ac_pwd='$ac_pwd'
+srcdir='$srcdir'
+INSTALL='$INSTALL'
+MKDIR_P='$MKDIR_P'
+AWK='$AWK'
+test -n "\$AWK" || AWK=awk
+_ACEOF
+
+cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
+# The default lists apply if the user does not specify any file.
+ac_need_defaults=:
+while test $# != 0
+do
+ case $1 in
+ --*=?*)
+ ac_option=`expr "X$1" : 'X\([^=]*\)='`
+ ac_optarg=`expr "X$1" : 'X[^=]*=\(.*\)'`
+ ac_shift=:
+ ;;
+ --*=)
+ ac_option=`expr "X$1" : 'X\([^=]*\)='`
+ ac_optarg=
+ ac_shift=:
+ ;;
+ *)
+ ac_option=$1
+ ac_optarg=$2
+ ac_shift=shift
+ ;;
+ esac
+
+ case $ac_option in
+ # Handling of the options.
+ -recheck | --recheck | --rechec | --reche | --rech | --rec | --re | --r)
+ ac_cs_recheck=: ;;
+ --version | --versio | --versi | --vers | --ver | --ve | --v | -V )
+ $as_echo "$ac_cs_version"; exit ;;
+ --config | --confi | --conf | --con | --co | --c )
+ $as_echo "$ac_cs_config"; exit ;;
+ --debug | --debu | --deb | --de | --d | -d )
+ debug=: ;;
+ --file | --fil | --fi | --f )
+ $ac_shift
+ case $ac_optarg in
+ *\'*) ac_optarg=`$as_echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"` ;;
+ '') as_fn_error $? "missing file argument" ;;
+ esac
+ as_fn_append CONFIG_FILES " '$ac_optarg'"
+ ac_need_defaults=false;;
+ --header | --heade | --head | --hea )
+ $ac_shift
+ case $ac_optarg in
+ *\'*) ac_optarg=`$as_echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"` ;;
+ esac
+ as_fn_append CONFIG_HEADERS " '$ac_optarg'"
+ ac_need_defaults=false;;
+ --he | --h)
+ # Conflict between --help and --header
+ as_fn_error $? "ambiguous option: \`$1'
+Try \`$0 --help' for more information.";;
+ --help | --hel | -h )
+ $as_echo "$ac_cs_usage"; exit ;;
+ -q | -quiet | --quiet | --quie | --qui | --qu | --q \
+ | -silent | --silent | --silen | --sile | --sil | --si | --s)
+ ac_cs_silent=: ;;
+
+ # This is an error.
+ -*) as_fn_error $? "unrecognized option: \`$1'
+Try \`$0 --help' for more information." ;;
+
+ *) as_fn_append ac_config_targets " $1"
+ ac_need_defaults=false ;;
+
+ esac
+ shift
+done
+
+ac_configure_extra_args=
+
+if $ac_cs_silent; then
+ exec 6>/dev/null
+ ac_configure_extra_args="$ac_configure_extra_args --silent"
+fi
+
+_ACEOF
+cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
+if \$ac_cs_recheck; then
+ set X '$SHELL' '$0' $ac_configure_args \$ac_configure_extra_args --no-create --no-recursion
+ shift
+ \$as_echo "running CONFIG_SHELL=$SHELL \$*" >&6
+ CONFIG_SHELL='$SHELL'
+ export CONFIG_SHELL
+ exec "\$@"
+fi
+
+_ACEOF
+cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
+exec 5>>config.log
+{
+ echo
+ sed 'h;s/./-/g;s/^.../## /;s/...$/ ##/;p;x;p;x' <<_ASBOX
+## Running $as_me. ##
+_ASBOX
+ $as_echo "$ac_log"
+} >&5
+
+_ACEOF
+cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
+#
+# INIT-COMMANDS
+#
+AMDEP_TRUE="$AMDEP_TRUE" ac_aux_dir="$ac_aux_dir"
+
+
+# The HP-UX ksh and POSIX shell print the target directory to stdout
+# if CDPATH is set.
+(unset CDPATH) >/dev/null 2>&1 && unset CDPATH
+
+sed_quote_subst='$sed_quote_subst'
+double_quote_subst='$double_quote_subst'
+delay_variable_subst='$delay_variable_subst'
+macro_version='`$ECHO "X$macro_version" | $Xsed -e "$delay_single_quote_subst"`'
+macro_revision='`$ECHO "X$macro_revision" | $Xsed -e "$delay_single_quote_subst"`'
+enable_shared='`$ECHO "X$enable_shared" | $Xsed -e "$delay_single_quote_subst"`'
+enable_static='`$ECHO "X$enable_static" | $Xsed -e "$delay_single_quote_subst"`'
+pic_mode='`$ECHO "X$pic_mode" | $Xsed -e "$delay_single_quote_subst"`'
+enable_fast_install='`$ECHO "X$enable_fast_install" | $Xsed -e "$delay_single_quote_subst"`'
+host_alias='`$ECHO "X$host_alias" | $Xsed -e "$delay_single_quote_subst"`'
+host='`$ECHO "X$host" | $Xsed -e "$delay_single_quote_subst"`'
+host_os='`$ECHO "X$host_os" | $Xsed -e "$delay_single_quote_subst"`'
+build_alias='`$ECHO "X$build_alias" | $Xsed -e "$delay_single_quote_subst"`'
+build='`$ECHO "X$build" | $Xsed -e "$delay_single_quote_subst"`'
+build_os='`$ECHO "X$build_os" | $Xsed -e "$delay_single_quote_subst"`'
+SED='`$ECHO "X$SED" | $Xsed -e "$delay_single_quote_subst"`'
+Xsed='`$ECHO "X$Xsed" | $Xsed -e "$delay_single_quote_subst"`'
+GREP='`$ECHO "X$GREP" | $Xsed -e "$delay_single_quote_subst"`'
+EGREP='`$ECHO "X$EGREP" | $Xsed -e "$delay_single_quote_subst"`'
+FGREP='`$ECHO "X$FGREP" | $Xsed -e "$delay_single_quote_subst"`'
+LD='`$ECHO "X$LD" | $Xsed -e "$delay_single_quote_subst"`'
+NM='`$ECHO "X$NM" | $Xsed -e "$delay_single_quote_subst"`'
+LN_S='`$ECHO "X$LN_S" | $Xsed -e "$delay_single_quote_subst"`'
+max_cmd_len='`$ECHO "X$max_cmd_len" | $Xsed -e "$delay_single_quote_subst"`'
+ac_objext='`$ECHO "X$ac_objext" | $Xsed -e "$delay_single_quote_subst"`'
+exeext='`$ECHO "X$exeext" | $Xsed -e "$delay_single_quote_subst"`'
+lt_unset='`$ECHO "X$lt_unset" | $Xsed -e "$delay_single_quote_subst"`'
+lt_SP2NL='`$ECHO "X$lt_SP2NL" | $Xsed -e "$delay_single_quote_subst"`'
+lt_NL2SP='`$ECHO "X$lt_NL2SP" | $Xsed -e "$delay_single_quote_subst"`'
+reload_flag='`$ECHO "X$reload_flag" | $Xsed -e "$delay_single_quote_subst"`'
+reload_cmds='`$ECHO "X$reload_cmds" | $Xsed -e "$delay_single_quote_subst"`'
+OBJDUMP='`$ECHO "X$OBJDUMP" | $Xsed -e "$delay_single_quote_subst"`'
+deplibs_check_method='`$ECHO "X$deplibs_check_method" | $Xsed -e "$delay_single_quote_subst"`'
+file_magic_cmd='`$ECHO "X$file_magic_cmd" | $Xsed -e "$delay_single_quote_subst"`'
+AR='`$ECHO "X$AR" | $Xsed -e "$delay_single_quote_subst"`'
+AR_FLAGS='`$ECHO "X$AR_FLAGS" | $Xsed -e "$delay_single_quote_subst"`'
+STRIP='`$ECHO "X$STRIP" | $Xsed -e "$delay_single_quote_subst"`'
+RANLIB='`$ECHO "X$RANLIB" | $Xsed -e "$delay_single_quote_subst"`'
+old_postinstall_cmds='`$ECHO "X$old_postinstall_cmds" | $Xsed -e "$delay_single_quote_subst"`'
+old_postuninstall_cmds='`$ECHO "X$old_postuninstall_cmds" | $Xsed -e "$delay_single_quote_subst"`'
+old_archive_cmds='`$ECHO "X$old_archive_cmds" | $Xsed -e "$delay_single_quote_subst"`'
+CC='`$ECHO "X$CC" | $Xsed -e "$delay_single_quote_subst"`'
+CFLAGS='`$ECHO "X$CFLAGS" | $Xsed -e "$delay_single_quote_subst"`'
+compiler='`$ECHO "X$compiler" | $Xsed -e "$delay_single_quote_subst"`'
+GCC='`$ECHO "X$GCC" | $Xsed -e "$delay_single_quote_subst"`'
+lt_cv_sys_global_symbol_pipe='`$ECHO "X$lt_cv_sys_global_symbol_pipe" | $Xsed -e "$delay_single_quote_subst"`'
+lt_cv_sys_global_symbol_to_cdecl='`$ECHO "X$lt_cv_sys_global_symbol_to_cdecl" | $Xsed -e "$delay_single_quote_subst"`'
+lt_cv_sys_global_symbol_to_c_name_address='`$ECHO "X$lt_cv_sys_global_symbol_to_c_name_address" | $Xsed -e "$delay_single_quote_subst"`'
+lt_cv_sys_global_symbol_to_c_name_address_lib_prefix='`$ECHO "X$lt_cv_sys_global_symbol_to_c_name_address_lib_prefix" | $Xsed -e "$delay_single_quote_subst"`'
+objdir='`$ECHO "X$objdir" | $Xsed -e "$delay_single_quote_subst"`'
+SHELL='`$ECHO "X$SHELL" | $Xsed -e "$delay_single_quote_subst"`'
+ECHO='`$ECHO "X$ECHO" | $Xsed -e "$delay_single_quote_subst"`'
+MAGIC_CMD='`$ECHO "X$MAGIC_CMD" | $Xsed -e "$delay_single_quote_subst"`'
+lt_prog_compiler_no_builtin_flag='`$ECHO "X$lt_prog_compiler_no_builtin_flag" | $Xsed -e "$delay_single_quote_subst"`'
+lt_prog_compiler_wl='`$ECHO "X$lt_prog_compiler_wl" | $Xsed -e "$delay_single_quote_subst"`'
+lt_prog_compiler_pic='`$ECHO "X$lt_prog_compiler_pic" | $Xsed -e "$delay_single_quote_subst"`'
+lt_prog_compiler_static='`$ECHO "X$lt_prog_compiler_static" | $Xsed -e "$delay_single_quote_subst"`'
+lt_cv_prog_compiler_c_o='`$ECHO "X$lt_cv_prog_compiler_c_o" | $Xsed -e "$delay_single_quote_subst"`'
+need_locks='`$ECHO "X$need_locks" | $Xsed -e "$delay_single_quote_subst"`'
+DSYMUTIL='`$ECHO "X$DSYMUTIL" | $Xsed -e "$delay_single_quote_subst"`'
+NMEDIT='`$ECHO "X$NMEDIT" | $Xsed -e "$delay_single_quote_subst"`'
+LIPO='`$ECHO "X$LIPO" | $Xsed -e "$delay_single_quote_subst"`'
+OTOOL='`$ECHO "X$OTOOL" | $Xsed -e "$delay_single_quote_subst"`'
+OTOOL64='`$ECHO "X$OTOOL64" | $Xsed -e "$delay_single_quote_subst"`'
+libext='`$ECHO "X$libext" | $Xsed -e "$delay_single_quote_subst"`'
+shrext_cmds='`$ECHO "X$shrext_cmds" | $Xsed -e "$delay_single_quote_subst"`'
+extract_expsyms_cmds='`$ECHO "X$extract_expsyms_cmds" | $Xsed -e "$delay_single_quote_subst"`'
+archive_cmds_need_lc='`$ECHO "X$archive_cmds_need_lc" | $Xsed -e "$delay_single_quote_subst"`'
+enable_shared_with_static_runtimes='`$ECHO "X$enable_shared_with_static_runtimes" | $Xsed -e "$delay_single_quote_subst"`'
+export_dynamic_flag_spec='`$ECHO "X$export_dynamic_flag_spec" | $Xsed -e "$delay_single_quote_subst"`'
+whole_archive_flag_spec='`$ECHO "X$whole_archive_flag_spec" | $Xsed -e "$delay_single_quote_subst"`'
+compiler_needs_object='`$ECHO "X$compiler_needs_object" | $Xsed -e "$delay_single_quote_subst"`'
+old_archive_from_new_cmds='`$ECHO "X$old_archive_from_new_cmds" | $Xsed -e "$delay_single_quote_subst"`'
+old_archive_from_expsyms_cmds='`$ECHO "X$old_archive_from_expsyms_cmds" | $Xsed -e "$delay_single_quote_subst"`'
+archive_cmds='`$ECHO "X$archive_cmds" | $Xsed -e "$delay_single_quote_subst"`'
+archive_expsym_cmds='`$ECHO "X$archive_expsym_cmds" | $Xsed -e "$delay_single_quote_subst"`'
+module_cmds='`$ECHO "X$module_cmds" | $Xsed -e "$delay_single_quote_subst"`'
+module_expsym_cmds='`$ECHO "X$module_expsym_cmds" | $Xsed -e "$delay_single_quote_subst"`'
+with_gnu_ld='`$ECHO "X$with_gnu_ld" | $Xsed -e "$delay_single_quote_subst"`'
+allow_undefined_flag='`$ECHO "X$allow_undefined_flag" | $Xsed -e "$delay_single_quote_subst"`'
+no_undefined_flag='`$ECHO "X$no_undefined_flag" | $Xsed -e "$delay_single_quote_subst"`'
+hardcode_libdir_flag_spec='`$ECHO "X$hardcode_libdir_flag_spec" | $Xsed -e "$delay_single_quote_subst"`'
+hardcode_libdir_flag_spec_ld='`$ECHO "X$hardcode_libdir_flag_spec_ld" | $Xsed -e "$delay_single_quote_subst"`'
+hardcode_libdir_separator='`$ECHO "X$hardcode_libdir_separator" | $Xsed -e "$delay_single_quote_subst"`'
+hardcode_direct='`$ECHO "X$hardcode_direct" | $Xsed -e "$delay_single_quote_subst"`'
+hardcode_direct_absolute='`$ECHO "X$hardcode_direct_absolute" | $Xsed -e "$delay_single_quote_subst"`'
+hardcode_minus_L='`$ECHO "X$hardcode_minus_L" | $Xsed -e "$delay_single_quote_subst"`'
+hardcode_shlibpath_var='`$ECHO "X$hardcode_shlibpath_var" | $Xsed -e "$delay_single_quote_subst"`'
+hardcode_automatic='`$ECHO "X$hardcode_automatic" | $Xsed -e "$delay_single_quote_subst"`'
+inherit_rpath='`$ECHO "X$inherit_rpath" | $Xsed -e "$delay_single_quote_subst"`'
+link_all_deplibs='`$ECHO "X$link_all_deplibs" | $Xsed -e "$delay_single_quote_subst"`'
+fix_srcfile_path='`$ECHO "X$fix_srcfile_path" | $Xsed -e "$delay_single_quote_subst"`'
+always_export_symbols='`$ECHO "X$always_export_symbols" | $Xsed -e "$delay_single_quote_subst"`'
+export_symbols_cmds='`$ECHO "X$export_symbols_cmds" | $Xsed -e "$delay_single_quote_subst"`'
+exclude_expsyms='`$ECHO "X$exclude_expsyms" | $Xsed -e "$delay_single_quote_subst"`'
+include_expsyms='`$ECHO "X$include_expsyms" | $Xsed -e "$delay_single_quote_subst"`'
+prelink_cmds='`$ECHO "X$prelink_cmds" | $Xsed -e "$delay_single_quote_subst"`'
+file_list_spec='`$ECHO "X$file_list_spec" | $Xsed -e "$delay_single_quote_subst"`'
+variables_saved_for_relink='`$ECHO "X$variables_saved_for_relink" | $Xsed -e "$delay_single_quote_subst"`'
+need_lib_prefix='`$ECHO "X$need_lib_prefix" | $Xsed -e "$delay_single_quote_subst"`'
+need_version='`$ECHO "X$need_version" | $Xsed -e "$delay_single_quote_subst"`'
+version_type='`$ECHO "X$version_type" | $Xsed -e "$delay_single_quote_subst"`'
+runpath_var='`$ECHO "X$runpath_var" | $Xsed -e "$delay_single_quote_subst"`'
+shlibpath_var='`$ECHO "X$shlibpath_var" | $Xsed -e "$delay_single_quote_subst"`'
+shlibpath_overrides_runpath='`$ECHO "X$shlibpath_overrides_runpath" | $Xsed -e "$delay_single_quote_subst"`'
+libname_spec='`$ECHO "X$libname_spec" | $Xsed -e "$delay_single_quote_subst"`'
+library_names_spec='`$ECHO "X$library_names_spec" | $Xsed -e "$delay_single_quote_subst"`'
+soname_spec='`$ECHO "X$soname_spec" | $Xsed -e "$delay_single_quote_subst"`'
+postinstall_cmds='`$ECHO "X$postinstall_cmds" | $Xsed -e "$delay_single_quote_subst"`'
+postuninstall_cmds='`$ECHO "X$postuninstall_cmds" | $Xsed -e "$delay_single_quote_subst"`'
+finish_cmds='`$ECHO "X$finish_cmds" | $Xsed -e "$delay_single_quote_subst"`'
+finish_eval='`$ECHO "X$finish_eval" | $Xsed -e "$delay_single_quote_subst"`'
+hardcode_into_libs='`$ECHO "X$hardcode_into_libs" | $Xsed -e "$delay_single_quote_subst"`'
+sys_lib_search_path_spec='`$ECHO "X$sys_lib_search_path_spec" | $Xsed -e "$delay_single_quote_subst"`'
+sys_lib_dlsearch_path_spec='`$ECHO "X$sys_lib_dlsearch_path_spec" | $Xsed -e "$delay_single_quote_subst"`'
+hardcode_action='`$ECHO "X$hardcode_action" | $Xsed -e "$delay_single_quote_subst"`'
+enable_dlopen='`$ECHO "X$enable_dlopen" | $Xsed -e "$delay_single_quote_subst"`'
+enable_dlopen_self='`$ECHO "X$enable_dlopen_self" | $Xsed -e "$delay_single_quote_subst"`'
+enable_dlopen_self_static='`$ECHO "X$enable_dlopen_self_static" | $Xsed -e "$delay_single_quote_subst"`'
+old_striplib='`$ECHO "X$old_striplib" | $Xsed -e "$delay_single_quote_subst"`'
+striplib='`$ECHO "X$striplib" | $Xsed -e "$delay_single_quote_subst"`'
+
+LTCC='$LTCC'
+LTCFLAGS='$LTCFLAGS'
+compiler='$compiler_DEFAULT'
+
+# Quote evaled strings.
+for var in SED \
+GREP \
+EGREP \
+FGREP \
+LD \
+NM \
+LN_S \
+lt_SP2NL \
+lt_NL2SP \
+reload_flag \
+OBJDUMP \
+deplibs_check_method \
+file_magic_cmd \
+AR \
+AR_FLAGS \
+STRIP \
+RANLIB \
+CC \
+CFLAGS \
+compiler \
+lt_cv_sys_global_symbol_pipe \
+lt_cv_sys_global_symbol_to_cdecl \
+lt_cv_sys_global_symbol_to_c_name_address \
+lt_cv_sys_global_symbol_to_c_name_address_lib_prefix \
+SHELL \
+ECHO \
+lt_prog_compiler_no_builtin_flag \
+lt_prog_compiler_wl \
+lt_prog_compiler_pic \
+lt_prog_compiler_static \
+lt_cv_prog_compiler_c_o \
+need_locks \
+DSYMUTIL \
+NMEDIT \
+LIPO \
+OTOOL \
+OTOOL64 \
+shrext_cmds \
+export_dynamic_flag_spec \
+whole_archive_flag_spec \
+compiler_needs_object \
+with_gnu_ld \
+allow_undefined_flag \
+no_undefined_flag \
+hardcode_libdir_flag_spec \
+hardcode_libdir_flag_spec_ld \
+hardcode_libdir_separator \
+fix_srcfile_path \
+exclude_expsyms \
+include_expsyms \
+file_list_spec \
+variables_saved_for_relink \
+libname_spec \
+library_names_spec \
+soname_spec \
+finish_eval \
+old_striplib \
+striplib; do
+ case \`eval \\\\\$ECHO "X\\\\\$\$var"\` in
+ *[\\\\\\\`\\"\\\$]*)
+ eval "lt_\$var=\\\\\\"\\\`\\\$ECHO \\"X\\\$\$var\\" | \\\$Xsed -e \\"\\\$sed_quote_subst\\"\\\`\\\\\\""
+ ;;
+ *)
+ eval "lt_\$var=\\\\\\"\\\$\$var\\\\\\""
+ ;;
+ esac
+done
+
+# Double-quote double-evaled strings.
+for var in reload_cmds \
+old_postinstall_cmds \
+old_postuninstall_cmds \
+old_archive_cmds \
+extract_expsyms_cmds \
+old_archive_from_new_cmds \
+old_archive_from_expsyms_cmds \
+archive_cmds \
+archive_expsym_cmds \
+module_cmds \
+module_expsym_cmds \
+export_symbols_cmds \
+prelink_cmds \
+postinstall_cmds \
+postuninstall_cmds \
+finish_cmds \
+sys_lib_search_path_spec \
+sys_lib_dlsearch_path_spec; do
+ case \`eval \\\\\$ECHO "X\\\\\$\$var"\` in
+ *[\\\\\\\`\\"\\\$]*)
+ eval "lt_\$var=\\\\\\"\\\`\\\$ECHO \\"X\\\$\$var\\" | \\\$Xsed -e \\"\\\$double_quote_subst\\" -e \\"\\\$sed_quote_subst\\" -e \\"\\\$delay_variable_subst\\"\\\`\\\\\\""
+ ;;
+ *)
+ eval "lt_\$var=\\\\\\"\\\$\$var\\\\\\""
+ ;;
+ esac
+done
+
+# Fix-up fallback echo if it was mangled by the above quoting rules.
+case \$lt_ECHO in
+*'\\\$0 --fallback-echo"') lt_ECHO=\`\$ECHO "X\$lt_ECHO" | \$Xsed -e 's/\\\\\\\\\\\\\\\$0 --fallback-echo"\$/\$0 --fallback-echo"/'\`
+ ;;
+esac
+
+ac_aux_dir='$ac_aux_dir'
+xsi_shell='$xsi_shell'
+lt_shell_append='$lt_shell_append'
+
+# See if we are running on zsh, and set the options which allow our
+# commands through without removal of \ escapes INIT.
+if test -n "\${ZSH_VERSION+set}" ; then
+ setopt NO_GLOB_SUBST
+fi
+
+
+ PACKAGE='$PACKAGE'
+ VERSION='$VERSION'
+ TIMESTAMP='$TIMESTAMP'
+ RM='$RM'
+ ofile='$ofile'
+
+
+
+
+_ACEOF
+
+cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
+
+# Handling of arguments.
+for ac_config_target in $ac_config_targets
+do
+ case $ac_config_target in
+ "config.h") CONFIG_HEADERS="$CONFIG_HEADERS config.h" ;;
+ "depfiles") CONFIG_COMMANDS="$CONFIG_COMMANDS depfiles" ;;
+ "libtool") CONFIG_COMMANDS="$CONFIG_COMMANDS libtool" ;;
+ "yaml-0.1.pc") CONFIG_FILES="$CONFIG_FILES yaml-0.1.pc" ;;
+ "include/Makefile") CONFIG_FILES="$CONFIG_FILES include/Makefile" ;;
+ "src/Makefile") CONFIG_FILES="$CONFIG_FILES src/Makefile" ;;
+ "Makefile") CONFIG_FILES="$CONFIG_FILES Makefile" ;;
+ "tests/Makefile") CONFIG_FILES="$CONFIG_FILES tests/Makefile" ;;
+ "win32/Makefile") CONFIG_FILES="$CONFIG_FILES win32/Makefile" ;;
+
+ *) as_fn_error $? "invalid argument: \`$ac_config_target'" "$LINENO" 5 ;;
+ esac
+done
+
+
+# If the user did not use the arguments to specify the items to instantiate,
+# then the envvar interface is used. Set only those that are not.
+# We use the long form for the default assignment because of an extremely
+# bizarre bug on SunOS 4.1.3.
+if $ac_need_defaults; then
+ test "${CONFIG_FILES+set}" = set || CONFIG_FILES=$config_files
+ test "${CONFIG_HEADERS+set}" = set || CONFIG_HEADERS=$config_headers
+ test "${CONFIG_COMMANDS+set}" = set || CONFIG_COMMANDS=$config_commands
+fi
+
+# Have a temporary directory for convenience. Make it in the build tree
+# simply because there is no reason against having it here, and in addition,
+# creating and moving files from /tmp can sometimes cause problems.
+# Hook for its removal unless debugging.
+# Note that there is a small window in which the directory will not be cleaned:
+# after its creation but before its name has been assigned to `$tmp'.
+$debug ||
+{
+ tmp=
+ trap 'exit_status=$?
+ { test -z "$tmp" || test ! -d "$tmp" || rm -fr "$tmp"; } && exit $exit_status
+' 0
+ trap 'as_fn_exit 1' 1 2 13 15
+}
+# Create a (secure) tmp directory for tmp files.
+
+{
+ tmp=`(umask 077 && mktemp -d "./confXXXXXX") 2>/dev/null` &&
+ test -n "$tmp" && test -d "$tmp"
+} ||
+{
+ tmp=./conf$$-$RANDOM
+ (umask 077 && mkdir "$tmp")
+} || as_fn_error $? "cannot create a temporary directory in ." "$LINENO" 5
+
+# Set up the scripts for CONFIG_FILES section.
+# No need to generate them if there are no CONFIG_FILES.
+# This happens for instance with `./config.status config.h'.
+if test -n "$CONFIG_FILES"; then
+
+
+ac_cr=`echo X | tr X '\015'`
+# On cygwin, bash can eat \r inside `` if the user requested igncr.
+# But we know of no other shell where ac_cr would be empty at this
+# point, so we can use a bashism as a fallback.
+if test "x$ac_cr" = x; then
+ eval ac_cr=\$\'\\r\'
+fi
+ac_cs_awk_cr=`$AWK 'BEGIN { print "a\rb" }' </dev/null 2>/dev/null`
+if test "$ac_cs_awk_cr" = "a${ac_cr}b"; then
+ ac_cs_awk_cr='\\r'
+else
+ ac_cs_awk_cr=$ac_cr
+fi
+
+echo 'BEGIN {' >"$tmp/subs1.awk" &&
+_ACEOF
+
+
+{
+ echo "cat >conf$$subs.awk <<_ACEOF" &&
+ echo "$ac_subst_vars" | sed 's/.*/&!$&$ac_delim/' &&
+ echo "_ACEOF"
+} >conf$$subs.sh ||
+ as_fn_error $? "could not make $CONFIG_STATUS" "$LINENO" 5
+ac_delim_num=`echo "$ac_subst_vars" | grep -c '^'`
+ac_delim='%!_!# '
+for ac_last_try in false false false false false :; do
+ . ./conf$$subs.sh ||
+ as_fn_error $? "could not make $CONFIG_STATUS" "$LINENO" 5
+
+ ac_delim_n=`sed -n "s/.*$ac_delim\$/X/p" conf$$subs.awk | grep -c X`
+ if test $ac_delim_n = $ac_delim_num; then
+ break
+ elif $ac_last_try; then
+ as_fn_error $? "could not make $CONFIG_STATUS" "$LINENO" 5
+ else
+ ac_delim="$ac_delim!$ac_delim _$ac_delim!! "
+ fi
+done
+rm -f conf$$subs.sh
+
+cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
+cat >>"\$tmp/subs1.awk" <<\\_ACAWK &&
+_ACEOF
+sed -n '
+h
+s/^/S["/; s/!.*/"]=/
+p
+g
+s/^[^!]*!//
+:repl
+t repl
+s/'"$ac_delim"'$//
+t delim
+:nl
+h
+s/\(.\{148\}\)..*/\1/
+t more1
+s/["\\]/\\&/g; s/^/"/; s/$/\\n"\\/
+p
+n
+b repl
+:more1
+s/["\\]/\\&/g; s/^/"/; s/$/"\\/
+p
+g
+s/.\{148\}//
+t nl
+:delim
+h
+s/\(.\{148\}\)..*/\1/
+t more2
+s/["\\]/\\&/g; s/^/"/; s/$/"/
+p
+b
+:more2
+s/["\\]/\\&/g; s/^/"/; s/$/"\\/
+p
+g
+s/.\{148\}//
+t delim
+' <conf$$subs.awk | sed '
+/^[^""]/{
+ N
+ s/\n//
+}
+' >>$CONFIG_STATUS || ac_write_fail=1
+rm -f conf$$subs.awk
+cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
+_ACAWK
+cat >>"\$tmp/subs1.awk" <<_ACAWK &&
+ for (key in S) S_is_set[key] = 1
+ FS = ""
+
+}
+{
+ line = $ 0
+ nfields = split(line, field, "@")
+ substed = 0
+ len = length(field[1])
+ for (i = 2; i < nfields; i++) {
+ key = field[i]
+ keylen = length(key)
+ if (S_is_set[key]) {
+ value = S[key]
+ line = substr(line, 1, len) "" value "" substr(line, len + keylen + 3)
+ len += length(value) + length(field[++i])
+ substed = 1
+ } else
+ len += 1 + keylen
+ }
+
+ print line
+}
+
+_ACAWK
+_ACEOF
+cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
+if sed "s/$ac_cr//" < /dev/null > /dev/null 2>&1; then
+ sed "s/$ac_cr\$//; s/$ac_cr/$ac_cs_awk_cr/g"
+else
+ cat
+fi < "$tmp/subs1.awk" > "$tmp/subs.awk" \
+ || as_fn_error $? "could not setup config files machinery" "$LINENO" 5
+_ACEOF
+
+# VPATH may cause trouble with some makes, so we remove sole $(srcdir),
+# ${srcdir} and @srcdir@ entries from VPATH if srcdir is ".", strip leading and
+# trailing colons and then remove the whole line if VPATH becomes empty
+# (actually we leave an empty line to preserve line numbers).
+if test "x$srcdir" = x.; then
+ ac_vpsub='/^[ ]*VPATH[ ]*=[ ]*/{
+h
+s///
+s/^/:/
+s/[ ]*$/:/
+s/:\$(srcdir):/:/g
+s/:\${srcdir}:/:/g
+s/:@srcdir@:/:/g
+s/^:*//
+s/:*$//
+x
+s/\(=[ ]*\).*/\1/
+G
+s/\n//
+s/^[^=]*=[ ]*$//
+}'
+fi
+
+cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
+fi # test -n "$CONFIG_FILES"
+
+# Set up the scripts for CONFIG_HEADERS section.
+# No need to generate them if there are no CONFIG_HEADERS.
+# This happens for instance with `./config.status Makefile'.
+if test -n "$CONFIG_HEADERS"; then
+cat >"$tmp/defines.awk" <<\_ACAWK ||
+BEGIN {
+_ACEOF
+
+# Transform confdefs.h into an awk script `defines.awk', embedded as
+# here-document in config.status, that substitutes the proper values into
+# config.h.in to produce config.h.
+
+# Create a delimiter string that does not exist in confdefs.h, to ease
+# handling of long lines.
+ac_delim='%!_!# '
+for ac_last_try in false false :; do
+ ac_t=`sed -n "/$ac_delim/p" confdefs.h`
+ if test -z "$ac_t"; then
+ break
+ elif $ac_last_try; then
+ as_fn_error $? "could not make $CONFIG_HEADERS" "$LINENO" 5
+ else
+ ac_delim="$ac_delim!$ac_delim _$ac_delim!! "
+ fi
+done
+
+# For the awk script, D is an array of macro values keyed by name,
+# likewise P contains macro parameters if any. Preserve backslash
+# newline sequences.
+
+ac_word_re=[_$as_cr_Letters][_$as_cr_alnum]*
+sed -n '
+s/.\{148\}/&'"$ac_delim"'/g
+t rset
+:rset
+s/^[ ]*#[ ]*define[ ][ ]*/ /
+t def
+d
+:def
+s/\\$//
+t bsnl
+s/["\\]/\\&/g
+s/^ \('"$ac_word_re"'\)\(([^()]*)\)[ ]*\(.*\)/P["\1"]="\2"\
+D["\1"]=" \3"/p
+s/^ \('"$ac_word_re"'\)[ ]*\(.*\)/D["\1"]=" \2"/p
+d
+:bsnl
+s/["\\]/\\&/g
+s/^ \('"$ac_word_re"'\)\(([^()]*)\)[ ]*\(.*\)/P["\1"]="\2"\
+D["\1"]=" \3\\\\\\n"\\/p
+t cont
+s/^ \('"$ac_word_re"'\)[ ]*\(.*\)/D["\1"]=" \2\\\\\\n"\\/p
+t cont
+d
+:cont
+n
+s/.\{148\}/&'"$ac_delim"'/g
+t clear
+:clear
+s/\\$//
+t bsnlc
+s/["\\]/\\&/g; s/^/"/; s/$/"/p
+d
+:bsnlc
+s/["\\]/\\&/g; s/^/"/; s/$/\\\\\\n"\\/p
+b cont
+' <confdefs.h | sed '
+s/'"$ac_delim"'/"\\\
+"/g' >>$CONFIG_STATUS || ac_write_fail=1
+
+cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
+ for (key in D) D_is_set[key] = 1
+ FS = ""
+}
+/^[\t ]*#[\t ]*(define|undef)[\t ]+$ac_word_re([\t (]|\$)/ {
+ line = \$ 0
+ split(line, arg, " ")
+ if (arg[1] == "#") {
+ defundef = arg[2]
+ mac1 = arg[3]
+ } else {
+ defundef = substr(arg[1], 2)
+ mac1 = arg[2]
+ }
+ split(mac1, mac2, "(") #)
+ macro = mac2[1]
+ prefix = substr(line, 1, index(line, defundef) - 1)
+ if (D_is_set[macro]) {
+ # Preserve the white space surrounding the "#".
+ print prefix "define", macro P[macro] D[macro]
+ next
+ } else {
+ # Replace #undef with comments. This is necessary, for example,
+ # in the case of _POSIX_SOURCE, which is predefined and required
+ # on some systems where configure will not decide to define it.
+ if (defundef == "undef") {
+ print "/*", prefix defundef, macro, "*/"
+ next
+ }
+ }
+}
+{ print }
+_ACAWK
+_ACEOF
+cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
+ as_fn_error $? "could not setup config headers machinery" "$LINENO" 5
+fi # test -n "$CONFIG_HEADERS"
+
+
+eval set X " :F $CONFIG_FILES :H $CONFIG_HEADERS :C $CONFIG_COMMANDS"
+shift
+for ac_tag
+do
+ case $ac_tag in
+ :[FHLC]) ac_mode=$ac_tag; continue;;
+ esac
+ case $ac_mode$ac_tag in
+ :[FHL]*:*);;
+ :L* | :C*:*) as_fn_error $? "invalid tag \`$ac_tag'" "$LINENO" 5 ;;
+ :[FH]-) ac_tag=-:-;;
+ :[FH]*) ac_tag=$ac_tag:$ac_tag.in;;
+ esac
+ ac_save_IFS=$IFS
+ IFS=:
+ set x $ac_tag
+ IFS=$ac_save_IFS
+ shift
+ ac_file=$1
+ shift
+
+ case $ac_mode in
+ :L) ac_source=$1;;
+ :[FH])
+ ac_file_inputs=
+ for ac_f
+ do
+ case $ac_f in
+ -) ac_f="$tmp/stdin";;
+ *) # Look for the file first in the build tree, then in the source tree
+ # (if the path is not absolute). The absolute path cannot be DOS-style,
+ # because $ac_f cannot contain `:'.
+ test -f "$ac_f" ||
+ case $ac_f in
+ [\\/$]*) false;;
+ *) test -f "$srcdir/$ac_f" && ac_f="$srcdir/$ac_f";;
+ esac ||
+ as_fn_error 1 "cannot find input file: \`$ac_f'" "$LINENO" 5 ;;
+ esac
+ case $ac_f in *\'*) ac_f=`$as_echo "$ac_f" | sed "s/'/'\\\\\\\\''/g"`;; esac
+ as_fn_append ac_file_inputs " '$ac_f'"
+ done
+
+ # Let's still pretend it is `configure' which instantiates (i.e., don't
+ # use $as_me), people would be surprised to read:
+ # /* config.h. Generated by config.status. */
+ configure_input='Generated from '`
+ $as_echo "$*" | sed 's|^[^:]*/||;s|:[^:]*/|, |g'
+ `' by configure.'
+ if test x"$ac_file" != x-; then
+ configure_input="$ac_file. $configure_input"
+ { $as_echo "$as_me:${as_lineno-$LINENO}: creating $ac_file" >&5
+$as_echo "$as_me: creating $ac_file" >&6;}
+ fi
+ # Neutralize special characters interpreted by sed in replacement strings.
+ case $configure_input in #(
+ *\&* | *\|* | *\\* )
+ ac_sed_conf_input=`$as_echo "$configure_input" |
+ sed 's/[\\\\&|]/\\\\&/g'`;; #(
+ *) ac_sed_conf_input=$configure_input;;
+ esac
+
+ case $ac_tag in
+ *:-:* | *:-) cat >"$tmp/stdin" \
+ || as_fn_error $? "could not create $ac_file" "$LINENO" 5 ;;
+ esac
+ ;;
+ esac
+
+ ac_dir=`$as_dirname -- "$ac_file" ||
+$as_expr X"$ac_file" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
+ X"$ac_file" : 'X\(//\)[^/]' \| \
+ X"$ac_file" : 'X\(//\)$' \| \
+ X"$ac_file" : 'X\(/\)' \| . 2>/dev/null ||
+$as_echo X"$ac_file" |
+ sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{
+ s//\1/
+ q
+ }
+ /^X\(\/\/\)[^/].*/{
+ s//\1/
+ q
+ }
+ /^X\(\/\/\)$/{
+ s//\1/
+ q
+ }
+ /^X\(\/\).*/{
+ s//\1/
+ q
+ }
+ s/.*/./; q'`
+ as_dir="$ac_dir"; as_fn_mkdir_p
+ ac_builddir=.
+
+case "$ac_dir" in
+.) ac_dir_suffix= ac_top_builddir_sub=. ac_top_build_prefix= ;;
+*)
+ ac_dir_suffix=/`$as_echo "$ac_dir" | sed 's|^\.[\\/]||'`
+ # A ".." for each directory in $ac_dir_suffix.
+ ac_top_builddir_sub=`$as_echo "$ac_dir_suffix" | sed 's|/[^\\/]*|/..|g;s|/||'`
+ case $ac_top_builddir_sub in
+ "") ac_top_builddir_sub=. ac_top_build_prefix= ;;
+ *) ac_top_build_prefix=$ac_top_builddir_sub/ ;;
+ esac ;;
+esac
+ac_abs_top_builddir=$ac_pwd
+ac_abs_builddir=$ac_pwd$ac_dir_suffix
+# for backward compatibility:
+ac_top_builddir=$ac_top_build_prefix
+
+case $srcdir in
+ .) # We are building in place.
+ ac_srcdir=.
+ ac_top_srcdir=$ac_top_builddir_sub
+ ac_abs_top_srcdir=$ac_pwd ;;
+ [\\/]* | ?:[\\/]* ) # Absolute name.
+ ac_srcdir=$srcdir$ac_dir_suffix;
+ ac_top_srcdir=$srcdir
+ ac_abs_top_srcdir=$srcdir ;;
+ *) # Relative name.
+ ac_srcdir=$ac_top_build_prefix$srcdir$ac_dir_suffix
+ ac_top_srcdir=$ac_top_build_prefix$srcdir
+ ac_abs_top_srcdir=$ac_pwd/$srcdir ;;
+esac
+ac_abs_srcdir=$ac_abs_top_srcdir$ac_dir_suffix
+
+
+ case $ac_mode in
+ :F)
+ #
+ # CONFIG_FILE
+ #
+
+ case $INSTALL in
+ [\\/$]* | ?:[\\/]* ) ac_INSTALL=$INSTALL ;;
+ *) ac_INSTALL=$ac_top_build_prefix$INSTALL ;;
+ esac
+ ac_MKDIR_P=$MKDIR_P
+ case $MKDIR_P in
+ [\\/$]* | ?:[\\/]* ) ;;
+ */*) ac_MKDIR_P=$ac_top_build_prefix$MKDIR_P ;;
+ esac
+_ACEOF
+
+cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
+# If the template does not know about datarootdir, expand it.
+# FIXME: This hack should be removed a few years after 2.60.
+ac_datarootdir_hack=; ac_datarootdir_seen=
+ac_sed_dataroot='
+/datarootdir/ {
+ p
+ q
+}
+/@datadir@/p
+/@docdir@/p
+/@infodir@/p
+/@localedir@/p
+/@mandir@/p'
+case `eval "sed -n \"\$ac_sed_dataroot\" $ac_file_inputs"` in
+*datarootdir*) ac_datarootdir_seen=yes;;
+*@datadir@*|*@docdir@*|*@infodir@*|*@localedir@*|*@mandir@*)
+ { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $ac_file_inputs seems to ignore the --datarootdir setting" >&5
+$as_echo "$as_me: WARNING: $ac_file_inputs seems to ignore the --datarootdir setting" >&2;}
+_ACEOF
+cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
+ ac_datarootdir_hack='
+ s&@datadir@&$datadir&g
+ s&@docdir@&$docdir&g
+ s&@infodir@&$infodir&g
+ s&@localedir@&$localedir&g
+ s&@mandir@&$mandir&g
+ s&\\\${datarootdir}&$datarootdir&g' ;;
+esac
+_ACEOF
+
+# Neutralize VPATH when `$srcdir' = `.'.
+# Shell code in configure.ac might set extrasub.
+# FIXME: do we really want to maintain this feature?
+cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
+ac_sed_extra="$ac_vpsub
+$extrasub
+_ACEOF
+cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
+:t
+/@[a-zA-Z_][a-zA-Z_0-9]*@/!b
+s|@configure_input@|$ac_sed_conf_input|;t t
+s&@top_builddir@&$ac_top_builddir_sub&;t t
+s&@top_build_prefix@&$ac_top_build_prefix&;t t
+s&@srcdir@&$ac_srcdir&;t t
+s&@abs_srcdir@&$ac_abs_srcdir&;t t
+s&@top_srcdir@&$ac_top_srcdir&;t t
+s&@abs_top_srcdir@&$ac_abs_top_srcdir&;t t
+s&@builddir@&$ac_builddir&;t t
+s&@abs_builddir@&$ac_abs_builddir&;t t
+s&@abs_top_builddir@&$ac_abs_top_builddir&;t t
+s&@INSTALL@&$ac_INSTALL&;t t
+s&@MKDIR_P@&$ac_MKDIR_P&;t t
+$ac_datarootdir_hack
+"
+eval sed \"\$ac_sed_extra\" "$ac_file_inputs" | $AWK -f "$tmp/subs.awk" >$tmp/out \
+ || as_fn_error $? "could not create $ac_file" "$LINENO" 5
+
+test -z "$ac_datarootdir_hack$ac_datarootdir_seen" &&
+ { ac_out=`sed -n '/\${datarootdir}/p' "$tmp/out"`; test -n "$ac_out"; } &&
+ { ac_out=`sed -n '/^[ ]*datarootdir[ ]*:*=/p' "$tmp/out"`; test -z "$ac_out"; } &&
+ { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $ac_file contains a reference to the variable \`datarootdir'
+which seems to be undefined. Please make sure it is defined" >&5
+$as_echo "$as_me: WARNING: $ac_file contains a reference to the variable \`datarootdir'
+which seems to be undefined. Please make sure it is defined" >&2;}
+
+ rm -f "$tmp/stdin"
+ case $ac_file in
+ -) cat "$tmp/out" && rm -f "$tmp/out";;
+ *) rm -f "$ac_file" && mv "$tmp/out" "$ac_file";;
+ esac \
+ || as_fn_error $? "could not create $ac_file" "$LINENO" 5
+ ;;
+ :H)
+ #
+ # CONFIG_HEADER
+ #
+ if test x"$ac_file" != x-; then
+ {
+ $as_echo "/* $configure_input */" \
+ && eval '$AWK -f "$tmp/defines.awk"' "$ac_file_inputs"
+ } >"$tmp/config.h" \
+ || as_fn_error $? "could not create $ac_file" "$LINENO" 5
+ if diff "$ac_file" "$tmp/config.h" >/dev/null 2>&1; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: $ac_file is unchanged" >&5
+$as_echo "$as_me: $ac_file is unchanged" >&6;}
+ else
+ rm -f "$ac_file"
+ mv "$tmp/config.h" "$ac_file" \
+ || as_fn_error $? "could not create $ac_file" "$LINENO" 5
+ fi
+ else
+ $as_echo "/* $configure_input */" \
+ && eval '$AWK -f "$tmp/defines.awk"' "$ac_file_inputs" \
+ || as_fn_error $? "could not create -" "$LINENO" 5
+ fi
+# Compute "$ac_file"'s index in $config_headers.
+_am_arg="$ac_file"
+_am_stamp_count=1
+for _am_header in $config_headers :; do
+ case $_am_header in
+ $_am_arg | $_am_arg:* )
+ break ;;
+ * )
+ _am_stamp_count=`expr $_am_stamp_count + 1` ;;
+ esac
+done
+echo "timestamp for $_am_arg" >`$as_dirname -- "$_am_arg" ||
+$as_expr X"$_am_arg" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
+ X"$_am_arg" : 'X\(//\)[^/]' \| \
+ X"$_am_arg" : 'X\(//\)$' \| \
+ X"$_am_arg" : 'X\(/\)' \| . 2>/dev/null ||
+$as_echo X"$_am_arg" |
+ sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{
+ s//\1/
+ q
+ }
+ /^X\(\/\/\)[^/].*/{
+ s//\1/
+ q
+ }
+ /^X\(\/\/\)$/{
+ s//\1/
+ q
+ }
+ /^X\(\/\).*/{
+ s//\1/
+ q
+ }
+ s/.*/./; q'`/stamp-h$_am_stamp_count
+ ;;
+
+ :C) { $as_echo "$as_me:${as_lineno-$LINENO}: executing $ac_file commands" >&5
+$as_echo "$as_me: executing $ac_file commands" >&6;}
+ ;;
+ esac
+
+
+ case $ac_file$ac_mode in
+ "depfiles":C) test x"$AMDEP_TRUE" != x"" || {
+ # Autoconf 2.62 quotes --file arguments for eval, but not when files
+ # are listed without --file. Let's play safe and only enable the eval
+ # if we detect the quoting.
+ case $CONFIG_FILES in
+ *\'*) eval set x "$CONFIG_FILES" ;;
+ *) set x $CONFIG_FILES ;;
+ esac
+ shift
+ for mf
+ do
+ # Strip MF so we end up with the name of the file.
+ mf=`echo "$mf" | sed -e 's/:.*$//'`
+ # Check whether this is an Automake generated Makefile or not.
+ # We used to match only the files named `Makefile.in', but
+ # some people rename them; so instead we look at the file content.
+ # Grep'ing the first line is not enough: some people post-process
+ # each Makefile.in and add a new line on top of each file to say so.
+ # Grep'ing the whole file is not good either: AIX grep has a line
+ # limit of 2048, but all sed's we know have understand at least 4000.
+ if sed -n 's,^#.*generated by automake.*,X,p' "$mf" | grep X >/dev/null 2>&1; then
+ dirpart=`$as_dirname -- "$mf" ||
+$as_expr X"$mf" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
+ X"$mf" : 'X\(//\)[^/]' \| \
+ X"$mf" : 'X\(//\)$' \| \
+ X"$mf" : 'X\(/\)' \| . 2>/dev/null ||
+$as_echo X"$mf" |
+ sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{
+ s//\1/
+ q
+ }
+ /^X\(\/\/\)[^/].*/{
+ s//\1/
+ q
+ }
+ /^X\(\/\/\)$/{
+ s//\1/
+ q
+ }
+ /^X\(\/\).*/{
+ s//\1/
+ q
+ }
+ s/.*/./; q'`
+ else
+ continue
+ fi
+ # Extract the definition of DEPDIR, am__include, and am__quote
+ # from the Makefile without running `make'.
+ DEPDIR=`sed -n 's/^DEPDIR = //p' < "$mf"`
+ test -z "$DEPDIR" && continue
+ am__include=`sed -n 's/^am__include = //p' < "$mf"`
+ test -z "am__include" && continue
+ am__quote=`sed -n 's/^am__quote = //p' < "$mf"`
+ # When using ansi2knr, U may be empty or an underscore; expand it
+ U=`sed -n 's/^U = //p' < "$mf"`
+ # Find all dependency output files, they are included files with
+ # $(DEPDIR) in their names. We invoke sed twice because it is the
+ # simplest approach to changing $(DEPDIR) to its actual value in the
+ # expansion.
+ for file in `sed -n "
+ s/^$am__include $am__quote\(.*(DEPDIR).*\)$am__quote"'$/\1/p' <"$mf" | \
+ sed -e 's/\$(DEPDIR)/'"$DEPDIR"'/g' -e 's/\$U/'"$U"'/g'`; do
+ # Make sure the directory exists.
+ test -f "$dirpart/$file" && continue
+ fdir=`$as_dirname -- "$file" ||
+$as_expr X"$file" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
+ X"$file" : 'X\(//\)[^/]' \| \
+ X"$file" : 'X\(//\)$' \| \
+ X"$file" : 'X\(/\)' \| . 2>/dev/null ||
+$as_echo X"$file" |
+ sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{
+ s//\1/
+ q
+ }
+ /^X\(\/\/\)[^/].*/{
+ s//\1/
+ q
+ }
+ /^X\(\/\/\)$/{
+ s//\1/
+ q
+ }
+ /^X\(\/\).*/{
+ s//\1/
+ q
+ }
+ s/.*/./; q'`
+ as_dir=$dirpart/$fdir; as_fn_mkdir_p
+ # echo "creating $dirpart/$file"
+ echo '# dummy' > "$dirpart/$file"
+ done
+ done
+}
+ ;;
+ "libtool":C)
+
+ # See if we are running on zsh, and set the options which allow our
+ # commands through without removal of \ escapes.
+ if test -n "${ZSH_VERSION+set}" ; then
+ setopt NO_GLOB_SUBST
+ fi
+
+ cfgfile="${ofile}T"
+ trap "$RM \"$cfgfile\"; exit 1" 1 2 15
+ $RM "$cfgfile"
+
+ cat <<_LT_EOF >> "$cfgfile"
+#! $SHELL
+
+# `$ECHO "$ofile" | sed 's%^.*/%%'` - Provide generalized library-building support services.
+# Generated automatically by $as_me ($PACKAGE$TIMESTAMP) $VERSION
+# Libtool was configured on host `(hostname || uname -n) 2>/dev/null | sed 1q`:
+# NOTE: Changes made to this file will be lost: look at ltmain.sh.
+#
+# Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2003, 2004, 2005,
+# 2006, 2007, 2008 Free Software Foundation, Inc.
+# Written by Gordon Matzigkeit, 1996
+#
+# This file is part of GNU Libtool.
+#
+# GNU Libtool 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.
+#
+# As a special exception to the GNU General Public License,
+# if you distribute this file as part of a program or library that
+# is built using GNU Libtool, you may include this file under the
+# same distribution terms that you use for the rest of that program.
+#
+# GNU Libtool 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 GNU Libtool; see the file COPYING. If not, a copy
+# can be downloaded from http://www.gnu.org/licenses/gpl.html, or
+# obtained by writing to the Free Software Foundation, Inc.,
+# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+
+
+# The names of the tagged configurations supported by this script.
+available_tags=""
+
+# ### BEGIN LIBTOOL CONFIG
+
+# Which release of libtool.m4 was used?
+macro_version=$macro_version
+macro_revision=$macro_revision
+
+# Whether or not to build shared libraries.
+build_libtool_libs=$enable_shared
+
+# Whether or not to build static libraries.
+build_old_libs=$enable_static
+
+# What type of objects to build.
+pic_mode=$pic_mode
+
+# Whether or not to optimize for fast installation.
+fast_install=$enable_fast_install
+
+# The host system.
+host_alias=$host_alias
+host=$host
+host_os=$host_os
+
+# The build system.
+build_alias=$build_alias
+build=$build
+build_os=$build_os
+
+# A sed program that does not truncate output.
+SED=$lt_SED
+
+# Sed that helps us avoid accidentally triggering echo(1) options like -n.
+Xsed="\$SED -e 1s/^X//"
+
+# A grep program that handles long lines.
+GREP=$lt_GREP
+
+# An ERE matcher.
+EGREP=$lt_EGREP
+
+# A literal string matcher.
+FGREP=$lt_FGREP
+
+# A BSD- or MS-compatible name lister.
+NM=$lt_NM
+
+# Whether we need soft or hard links.
+LN_S=$lt_LN_S
+
+# What is the maximum length of a command?
+max_cmd_len=$max_cmd_len
+
+# Object file suffix (normally "o").
+objext=$ac_objext
+
+# Executable file suffix (normally "").
+exeext=$exeext
+
+# whether the shell understands "unset".
+lt_unset=$lt_unset
+
+# turn spaces into newlines.
+SP2NL=$lt_lt_SP2NL
+
+# turn newlines into spaces.
+NL2SP=$lt_lt_NL2SP
+
+# How to create reloadable object files.
+reload_flag=$lt_reload_flag
+reload_cmds=$lt_reload_cmds
+
+# An object symbol dumper.
+OBJDUMP=$lt_OBJDUMP
+
+# Method to check whether dependent libraries are shared objects.
+deplibs_check_method=$lt_deplibs_check_method
+
+# Command to use when deplibs_check_method == "file_magic".
+file_magic_cmd=$lt_file_magic_cmd
+
+# The archiver.
+AR=$lt_AR
+AR_FLAGS=$lt_AR_FLAGS
+
+# A symbol stripping program.
+STRIP=$lt_STRIP
+
+# Commands used to install an old-style archive.
+RANLIB=$lt_RANLIB
+old_postinstall_cmds=$lt_old_postinstall_cmds
+old_postuninstall_cmds=$lt_old_postuninstall_cmds
+
+# A C compiler.
+LTCC=$lt_CC
+
+# LTCC compiler flags.
+LTCFLAGS=$lt_CFLAGS
+
+# Take the output of nm and produce a listing of raw symbols and C names.
+global_symbol_pipe=$lt_lt_cv_sys_global_symbol_pipe
+
+# Transform the output of nm in a proper C declaration.
+global_symbol_to_cdecl=$lt_lt_cv_sys_global_symbol_to_cdecl
+
+# Transform the output of nm in a C name address pair.
+global_symbol_to_c_name_address=$lt_lt_cv_sys_global_symbol_to_c_name_address
+
+# Transform the output of nm in a C name address pair when lib prefix is needed.
+global_symbol_to_c_name_address_lib_prefix=$lt_lt_cv_sys_global_symbol_to_c_name_address_lib_prefix
+
+# The name of the directory that contains temporary libtool files.
+objdir=$objdir
+
+# Shell to use when invoking shell scripts.
+SHELL=$lt_SHELL
+
+# An echo program that does not interpret backslashes.
+ECHO=$lt_ECHO
+
+# Used to examine libraries when file_magic_cmd begins with "file".
+MAGIC_CMD=$MAGIC_CMD
+
+# Must we lock files when doing compilation?
+need_locks=$lt_need_locks
+
+# Tool to manipulate archived DWARF debug symbol files on Mac OS X.
+DSYMUTIL=$lt_DSYMUTIL
+
+# Tool to change global to local symbols on Mac OS X.
+NMEDIT=$lt_NMEDIT
+
+# Tool to manipulate fat objects and archives on Mac OS X.
+LIPO=$lt_LIPO
+
+# ldd/readelf like tool for Mach-O binaries on Mac OS X.
+OTOOL=$lt_OTOOL
+
+# ldd/readelf like tool for 64 bit Mach-O binaries on Mac OS X 10.4.
+OTOOL64=$lt_OTOOL64
+
+# Old archive suffix (normally "a").
+libext=$libext
+
+# Shared library suffix (normally ".so").
+shrext_cmds=$lt_shrext_cmds
+
+# The commands to extract the exported symbol list from a shared archive.
+extract_expsyms_cmds=$lt_extract_expsyms_cmds
+
+# Variables whose values should be saved in libtool wrapper scripts and
+# restored at link time.
+variables_saved_for_relink=$lt_variables_saved_for_relink
+
+# Do we need the "lib" prefix for modules?
+need_lib_prefix=$need_lib_prefix
+
+# Do we need a version for libraries?
+need_version=$need_version
+
+# Library versioning type.
+version_type=$version_type
+
+# Shared library runtime path variable.
+runpath_var=$runpath_var
+
+# Shared library path variable.
+shlibpath_var=$shlibpath_var
+
+# Is shlibpath searched before the hard-coded library search path?
+shlibpath_overrides_runpath=$shlibpath_overrides_runpath
+
+# Format of library name prefix.
+libname_spec=$lt_libname_spec
+
+# List of archive names. First name is the real one, the rest are links.
+# The last name is the one that the linker finds with -lNAME
+library_names_spec=$lt_library_names_spec
+
+# The coded name of the library, if different from the real name.
+soname_spec=$lt_soname_spec
+
+# Command to use after installation of a shared archive.
+postinstall_cmds=$lt_postinstall_cmds
+
+# Command to use after uninstallation of a shared archive.
+postuninstall_cmds=$lt_postuninstall_cmds
+
+# Commands used to finish a libtool library installation in a directory.
+finish_cmds=$lt_finish_cmds
+
+# As "finish_cmds", except a single script fragment to be evaled but
+# not shown.
+finish_eval=$lt_finish_eval
+
+# Whether we should hardcode library paths into libraries.
+hardcode_into_libs=$hardcode_into_libs
+
+# Compile-time system search path for libraries.
+sys_lib_search_path_spec=$lt_sys_lib_search_path_spec
+
+# Run-time system search path for libraries.
+sys_lib_dlsearch_path_spec=$lt_sys_lib_dlsearch_path_spec
+
+# Whether dlopen is supported.
+dlopen_support=$enable_dlopen
+
+# Whether dlopen of programs is supported.
+dlopen_self=$enable_dlopen_self
+
+# Whether dlopen of statically linked programs is supported.
+dlopen_self_static=$enable_dlopen_self_static
+
+# Commands to strip libraries.
+old_striplib=$lt_old_striplib
+striplib=$lt_striplib
+
+
+# The linker used to build libraries.
+LD=$lt_LD
+
+# Commands used to build an old-style archive.
+old_archive_cmds=$lt_old_archive_cmds
+
+# A language specific compiler.
+CC=$lt_compiler
+
+# Is the compiler the GNU compiler?
+with_gcc=$GCC
+
+# Compiler flag to turn off builtin functions.
+no_builtin_flag=$lt_lt_prog_compiler_no_builtin_flag
+
+# How to pass a linker flag through the compiler.
+wl=$lt_lt_prog_compiler_wl
+
+# Additional compiler flags for building library objects.
+pic_flag=$lt_lt_prog_compiler_pic
+
+# Compiler flag to prevent dynamic linking.
+link_static_flag=$lt_lt_prog_compiler_static
+
+# Does compiler simultaneously support -c and -o options?
+compiler_c_o=$lt_lt_cv_prog_compiler_c_o
+
+# Whether or not to add -lc for building shared libraries.
+build_libtool_need_lc=$archive_cmds_need_lc
+
+# Whether or not to disallow shared libs when runtime libs are static.
+allow_libtool_libs_with_static_runtimes=$enable_shared_with_static_runtimes
+
+# Compiler flag to allow reflexive dlopens.
+export_dynamic_flag_spec=$lt_export_dynamic_flag_spec
+
+# Compiler flag to generate shared objects directly from archives.
+whole_archive_flag_spec=$lt_whole_archive_flag_spec
+
+# Whether the compiler copes with passing no objects directly.
+compiler_needs_object=$lt_compiler_needs_object
+
+# Create an old-style archive from a shared archive.
+old_archive_from_new_cmds=$lt_old_archive_from_new_cmds
+
+# Create a temporary old-style archive to link instead of a shared archive.
+old_archive_from_expsyms_cmds=$lt_old_archive_from_expsyms_cmds
+
+# Commands used to build a shared archive.
+archive_cmds=$lt_archive_cmds
+archive_expsym_cmds=$lt_archive_expsym_cmds
+
+# Commands used to build a loadable module if different from building
+# a shared archive.
+module_cmds=$lt_module_cmds
+module_expsym_cmds=$lt_module_expsym_cmds
+
+# Whether we are building with GNU ld or not.
+with_gnu_ld=$lt_with_gnu_ld
+
+# Flag that allows shared libraries with undefined symbols to be built.
+allow_undefined_flag=$lt_allow_undefined_flag
+
+# Flag that enforces no undefined symbols.
+no_undefined_flag=$lt_no_undefined_flag
+
+# Flag to hardcode \$libdir into a binary during linking.
+# This must work even if \$libdir does not exist
+hardcode_libdir_flag_spec=$lt_hardcode_libdir_flag_spec
+
+# If ld is used when linking, flag to hardcode \$libdir into a binary
+# during linking. This must work even if \$libdir does not exist.
+hardcode_libdir_flag_spec_ld=$lt_hardcode_libdir_flag_spec_ld
+
+# Whether we need a single "-rpath" flag with a separated argument.
+hardcode_libdir_separator=$lt_hardcode_libdir_separator
+
+# Set to "yes" if using DIR/libNAME\${shared_ext} during linking hardcodes
+# DIR into the resulting binary.
+hardcode_direct=$hardcode_direct
+
+# Set to "yes" if using DIR/libNAME\${shared_ext} during linking hardcodes
+# DIR into the resulting binary and the resulting library dependency is
+# "absolute",i.e impossible to change by setting \${shlibpath_var} if the
+# library is relocated.
+hardcode_direct_absolute=$hardcode_direct_absolute
+
+# Set to "yes" if using the -LDIR flag during linking hardcodes DIR
+# into the resulting binary.
+hardcode_minus_L=$hardcode_minus_L
+
+# Set to "yes" if using SHLIBPATH_VAR=DIR during linking hardcodes DIR
+# into the resulting binary.
+hardcode_shlibpath_var=$hardcode_shlibpath_var
+
+# Set to "yes" if building a shared library automatically hardcodes DIR
+# into the library and all subsequent libraries and executables linked
+# against it.
+hardcode_automatic=$hardcode_automatic
+
+# Set to yes if linker adds runtime paths of dependent libraries
+# to runtime path list.
+inherit_rpath=$inherit_rpath
+
+# Whether libtool must link a program against all its dependency libraries.
+link_all_deplibs=$link_all_deplibs
+
+# Fix the shell variable \$srcfile for the compiler.
+fix_srcfile_path=$lt_fix_srcfile_path
+
+# Set to "yes" if exported symbols are required.
+always_export_symbols=$always_export_symbols
+
+# The commands to list exported symbols.
+export_symbols_cmds=$lt_export_symbols_cmds
+
+# Symbols that should not be listed in the preloaded symbols.
+exclude_expsyms=$lt_exclude_expsyms
+
+# Symbols that must always be exported.
+include_expsyms=$lt_include_expsyms
+
+# Commands necessary for linking programs (against libraries) with templates.
+prelink_cmds=$lt_prelink_cmds
+
+# Specify filename containing input files.
+file_list_spec=$lt_file_list_spec
+
+# How to hardcode a shared library path into an executable.
+hardcode_action=$hardcode_action
+
+# ### END LIBTOOL CONFIG
+
+_LT_EOF
+
+ case $host_os in
+ aix3*)
+ cat <<\_LT_EOF >> "$cfgfile"
+# AIX sometimes has problems with the GCC collect2 program. For some
+# reason, if we set the COLLECT_NAMES environment variable, the problems
+# vanish in a puff of smoke.
+if test "X${COLLECT_NAMES+set}" != Xset; then
+ COLLECT_NAMES=
+ export COLLECT_NAMES
+fi
+_LT_EOF
+ ;;
+ esac
+
+
+ltmain="$ac_aux_dir/ltmain.sh"
+
+
+ # We use sed instead of cat because bash on DJGPP gets confused if
+ # if finds mixed CR/LF and LF-only lines. Since sed operates in
+ # text mode, it properly converts lines to CR/LF. This bash problem
+ # is reportedly fixed, but why not run on old versions too?
+ sed '/^# Generated shell functions inserted here/q' "$ltmain" >> "$cfgfile" \
+ || (rm -f "$cfgfile"; exit 1)
+
+ case $xsi_shell in
+ yes)
+ cat << \_LT_EOF >> "$cfgfile"
+
+# func_dirname file append nondir_replacement
+# Compute the dirname of FILE. If nonempty, add APPEND to the result,
+# otherwise set result to NONDIR_REPLACEMENT.
+func_dirname ()
+{
+ case ${1} in
+ */*) func_dirname_result="${1%/*}${2}" ;;
+ * ) func_dirname_result="${3}" ;;
+ esac
+}
+
+# func_basename file
+func_basename ()
+{
+ func_basename_result="${1##*/}"
+}
+
+# func_dirname_and_basename file append nondir_replacement
+# perform func_basename and func_dirname in a single function
+# call:
+# dirname: Compute the dirname of FILE. If nonempty,
+# add APPEND to the result, otherwise set result
+# to NONDIR_REPLACEMENT.
+# value returned in "$func_dirname_result"
+# basename: Compute filename of FILE.
+# value retuned in "$func_basename_result"
+# Implementation must be kept synchronized with func_dirname
+# and func_basename. For efficiency, we do not delegate to
+# those functions but instead duplicate the functionality here.
+func_dirname_and_basename ()
+{
+ case ${1} in
+ */*) func_dirname_result="${1%/*}${2}" ;;
+ * ) func_dirname_result="${3}" ;;
+ esac
+ func_basename_result="${1##*/}"
+}
+
+# func_stripname prefix suffix name
+# strip PREFIX and SUFFIX off of NAME.
+# PREFIX and SUFFIX must not contain globbing or regex special
+# characters, hashes, percent signs, but SUFFIX may contain a leading
+# dot (in which case that matches only a dot).
+func_stripname ()
+{
+ # pdksh 5.2.14 does not do ${X%$Y} correctly if both X and Y are
+ # positional parameters, so assign one to ordinary parameter first.
+ func_stripname_result=${3}
+ func_stripname_result=${func_stripname_result#"${1}"}
+ func_stripname_result=${func_stripname_result%"${2}"}
+}
+
+# func_opt_split
+func_opt_split ()
+{
+ func_opt_split_opt=${1%%=*}
+ func_opt_split_arg=${1#*=}
+}
+
+# func_lo2o object
+func_lo2o ()
+{
+ case ${1} in
+ *.lo) func_lo2o_result=${1%.lo}.${objext} ;;
+ *) func_lo2o_result=${1} ;;
+ esac
+}
+
+# func_xform libobj-or-source
+func_xform ()
+{
+ func_xform_result=${1%.*}.lo
+}
+
+# func_arith arithmetic-term...
+func_arith ()
+{
+ func_arith_result=$(( $* ))
+}
+
+# func_len string
+# STRING may not start with a hyphen.
+func_len ()
+{
+ func_len_result=${#1}
+}
+
+_LT_EOF
+ ;;
+ *) # Bourne compatible functions.
+ cat << \_LT_EOF >> "$cfgfile"
+
+# func_dirname file append nondir_replacement
+# Compute the dirname of FILE. If nonempty, add APPEND to the result,
+# otherwise set result to NONDIR_REPLACEMENT.
+func_dirname ()
+{
+ # Extract subdirectory from the argument.
+ func_dirname_result=`$ECHO "X${1}" | $Xsed -e "$dirname"`
+ if test "X$func_dirname_result" = "X${1}"; then
+ func_dirname_result="${3}"
+ else
+ func_dirname_result="$func_dirname_result${2}"
+ fi
+}
+
+# func_basename file
+func_basename ()
+{
+ func_basename_result=`$ECHO "X${1}" | $Xsed -e "$basename"`
+}
+
+
+# func_stripname prefix suffix name
+# strip PREFIX and SUFFIX off of NAME.
+# PREFIX and SUFFIX must not contain globbing or regex special
+# characters, hashes, percent signs, but SUFFIX may contain a leading
+# dot (in which case that matches only a dot).
+# func_strip_suffix prefix name
+func_stripname ()
+{
+ case ${2} in
+ .*) func_stripname_result=`$ECHO "X${3}" \
+ | $Xsed -e "s%^${1}%%" -e "s%\\\\${2}\$%%"`;;
+ *) func_stripname_result=`$ECHO "X${3}" \
+ | $Xsed -e "s%^${1}%%" -e "s%${2}\$%%"`;;
+ esac
+}
+
+# sed scripts:
+my_sed_long_opt='1s/^\(-[^=]*\)=.*/\1/;q'
+my_sed_long_arg='1s/^-[^=]*=//'
+
+# func_opt_split
+func_opt_split ()
+{
+ func_opt_split_opt=`$ECHO "X${1}" | $Xsed -e "$my_sed_long_opt"`
+ func_opt_split_arg=`$ECHO "X${1}" | $Xsed -e "$my_sed_long_arg"`
+}
+
+# func_lo2o object
+func_lo2o ()
+{
+ func_lo2o_result=`$ECHO "X${1}" | $Xsed -e "$lo2o"`
+}
+
+# func_xform libobj-or-source
+func_xform ()
+{
+ func_xform_result=`$ECHO "X${1}" | $Xsed -e 's/\.[^.]*$/.lo/'`
+}
+
+# func_arith arithmetic-term...
+func_arith ()
+{
+ func_arith_result=`expr "$@"`
+}
+
+# func_len string
+# STRING may not start with a hyphen.
+func_len ()
+{
+ func_len_result=`expr "$1" : ".*" 2>/dev/null || echo $max_cmd_len`
+}
+
+_LT_EOF
+esac
+
+case $lt_shell_append in
+ yes)
+ cat << \_LT_EOF >> "$cfgfile"
+
+# func_append var value
+# Append VALUE to the end of shell variable VAR.
+func_append ()
+{
+ eval "$1+=\$2"
+}
+_LT_EOF
+ ;;
+ *)
+ cat << \_LT_EOF >> "$cfgfile"
+
+# func_append var value
+# Append VALUE to the end of shell variable VAR.
+func_append ()
+{
+ eval "$1=\$$1\$2"
+}
+
+_LT_EOF
+ ;;
+ esac
+
+
+ sed -n '/^# Generated shell functions inserted here/,$p' "$ltmain" >> "$cfgfile" \
+ || (rm -f "$cfgfile"; exit 1)
+
+ mv -f "$cfgfile" "$ofile" ||
+ (rm -f "$ofile" && cp "$cfgfile" "$ofile" && rm -f "$cfgfile")
+ chmod +x "$ofile"
+
+ ;;
+
+ esac
+done # for ac_tag
+
+
+as_fn_exit 0
+_ACEOF
+ac_clean_files=$ac_clean_files_save
+
+test $ac_write_fail = 0 ||
+ as_fn_error $? "write failure creating $CONFIG_STATUS" "$LINENO" 5
+
+
+# configure is writing to config.log, and then calls config.status.
+# config.status does its own redirection, appending to config.log.
+# Unfortunately, on DOS this fails, as config.log is still kept open
+# by configure, so config.status won't be able to write to it; its
+# output is simply discarded. So we exec the FD to /dev/null,
+# effectively closing config.log, so it can be properly (re)opened and
+# appended to by config.status. When coming back to configure, we
+# need to make the FD available again.
+if test "$no_create" != yes; then
+ ac_cs_success=:
+ ac_config_status_args=
+ test "$silent" = yes &&
+ ac_config_status_args="$ac_config_status_args --quiet"
+ exec 5>/dev/null
+ $SHELL $CONFIG_STATUS $ac_config_status_args || ac_cs_success=false
+ exec 5>>config.log
+ # Use ||, not &&, to avoid exiting from the if with $? = 1, which
+ # would make configure fail if this is the last instruction.
+ $ac_cs_success || as_fn_exit 1
+fi
+if test -n "$ac_unrecognized_opts" && test "$enable_option_checking" != no; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: unrecognized options: $ac_unrecognized_opts" >&5
+$as_echo "$as_me: WARNING: unrecognized options: $ac_unrecognized_opts" >&2;}
+fi
+
diff --git a/contrib/libyaml/configure.ac b/contrib/libyaml/configure.ac
new file mode 100644
index 0000000..f0fa397
--- /dev/null
+++ b/contrib/libyaml/configure.ac
@@ -0,0 +1,73 @@
+# Run `./bootstrap` to generate the "configure" script.
+
+# Define the package version numbers and the bug reporting link.
+m4_define([YAML_MAJOR], 0)
+m4_define([YAML_MINOR], 1)
+m4_define([YAML_PATCH], 4)
+m4_define([YAML_BUGS], [http://pyyaml.org/newticket?component=libyaml])
+
+# Define the libtool version numbers; check the Autobook, Section 11.4.
+# Bump the libtool version numbers using the following algorithm:
+# if (the current interface has not been changed):
+# YAML_REVISION += 1
+# else:
+# YAML_REVISION = 0
+# YAML_CURRENT += 1
+# if (this release is backward compatible with the previous release):
+# YAML_AGE += 1
+# else:
+# YAML_AGE = 0
+m4_define([YAML_RELEASE], 0)
+m4_define([YAML_CURRENT], 2)
+m4_define([YAML_REVISION], 2)
+m4_define([YAML_AGE], 0)
+
+# Initialize autoconf & automake.
+AC_PREREQ(2.59)
+AC_INIT([yaml], [YAML_MAJOR.YAML_MINOR.YAML_PATCH], [YAML_BUGS])
+AC_CONFIG_AUX_DIR([config])
+AC_CONFIG_HEADERS([config.h])
+AM_INIT_AUTOMAKE([1.9 foreign])
+
+# Define macro variables for the package version numbers.
+AC_DEFINE(YAML_VERSION_MAJOR, YAML_MAJOR, [Define the major version number.])
+AC_DEFINE(YAML_VERSION_MINOR, YAML_MINOR, [Define the minor version number.])
+AC_DEFINE(YAML_VERSION_PATCH, YAML_PATCH, [Define the patch version number.])
+AC_DEFINE(YAML_VERSION_STRING, "YAML_MAJOR.YAML_MINOR.YAML_PATCH", [Define the version string.])
+
+# Define substitutions for the libtool version numbers.
+YAML_LT_RELEASE=YAML_RELEASE
+YAML_LT_CURRENT=YAML_CURRENT
+YAML_LT_REVISION=YAML_REVISION
+YAML_LT_AGE=YAML_AGE
+AC_SUBST(YAML_LT_RELEASE)
+AC_SUBST(YAML_LT_CURRENT)
+AC_SUBST(YAML_LT_REVISION)
+AC_SUBST(YAML_LT_AGE)
+
+# Note: in order to update checks, run `autoscan` and look through "configure.scan".
+
+# Checks for programs.
+AC_PROG_CC
+AC_PROG_CPP
+AC_PROG_INSTALL
+AC_PROG_LN_S
+AC_PROG_MAKE_SET
+AC_PROG_LIBTOOL
+
+AC_CHECK_PROG(DOXYGEN, [doxygen], [true], [false])
+AM_CONDITIONAL(DOXYGEN, [test "$DOXYGEN" = true])
+
+# Checks for header files.
+AC_HEADER_STDC
+AC_CHECK_HEADERS([stdlib.h])
+
+# Checks for typedefs, structures, and compiler characteristics.
+AC_C_CONST
+AC_TYPE_SIZE_T
+
+# Define Makefiles.
+AC_CONFIG_FILES([yaml-0.1.pc include/Makefile src/Makefile Makefile tests/Makefile win32/Makefile])
+
+# Generate the "configure" script.
+AC_OUTPUT
diff --git a/contrib/libyaml/doc/doxygen.cfg b/contrib/libyaml/doc/doxygen.cfg
new file mode 100644
index 0000000..a58bb17
--- /dev/null
+++ b/contrib/libyaml/doc/doxygen.cfg
@@ -0,0 +1,222 @@
+# Doxyfile 1.4.4
+
+#---------------------------------------------------------------------------
+# Project related configuration options
+#---------------------------------------------------------------------------
+PROJECT_NAME = $(PACKAGE)
+PROJECT_NUMBER = $(VERSION)
+OUTPUT_DIRECTORY = $(top_builddir)/doc/
+CREATE_SUBDIRS = NO
+OUTPUT_LANGUAGE = English
+USE_WINDOWS_ENCODING = NO
+BRIEF_MEMBER_DESC = YES
+REPEAT_BRIEF = YES
+ABBREVIATE_BRIEF =
+ALWAYS_DETAILED_SEC = NO
+INLINE_INHERITED_MEMB = NO
+FULL_PATH_NAMES = YES
+STRIP_FROM_PATH =
+STRIP_FROM_INC_PATH =
+SHORT_NAMES = NO
+JAVADOC_AUTOBRIEF = YES
+MULTILINE_CPP_IS_BRIEF = NO
+DETAILS_AT_TOP = NO
+INHERIT_DOCS = YES
+DISTRIBUTE_GROUP_DOC = NO
+SEPARATE_MEMBER_PAGES = NO
+TAB_SIZE = 8
+ALIASES =
+OPTIMIZE_OUTPUT_FOR_C = YES
+OPTIMIZE_OUTPUT_JAVA = NO
+SUBGROUPING = YES
+#---------------------------------------------------------------------------
+# Build related configuration options
+#---------------------------------------------------------------------------
+EXTRACT_ALL = NO
+EXTRACT_PRIVATE = NO
+EXTRACT_STATIC = NO
+EXTRACT_LOCAL_CLASSES = NO
+EXTRACT_LOCAL_METHODS = NO
+HIDE_UNDOC_MEMBERS = NO
+HIDE_UNDOC_CLASSES = NO
+HIDE_FRIEND_COMPOUNDS = NO
+HIDE_IN_BODY_DOCS = NO
+INTERNAL_DOCS = NO
+CASE_SENSE_NAMES = YES
+HIDE_SCOPE_NAMES = NO
+SHOW_INCLUDE_FILES = YES
+INLINE_INFO = YES
+SORT_MEMBER_DOCS = NO
+SORT_BRIEF_DOCS = NO
+SORT_BY_SCOPE_NAME = NO
+GENERATE_TODOLIST = YES
+GENERATE_TESTLIST = YES
+GENERATE_BUGLIST = YES
+GENERATE_DEPRECATEDLIST= YES
+ENABLED_SECTIONS =
+MAX_INITIALIZER_LINES = 30
+SHOW_USED_FILES = YES
+SHOW_DIRECTORIES = YES
+FILE_VERSION_FILTER =
+#---------------------------------------------------------------------------
+# configuration options related to warning and progress messages
+#---------------------------------------------------------------------------
+QUIET = NO
+WARNINGS = YES
+WARN_IF_UNDOCUMENTED = YES
+WARN_IF_DOC_ERROR = YES
+WARN_NO_PARAMDOC = NO
+WARN_FORMAT = "$file:$line: $text"
+WARN_LOGFILE =
+#---------------------------------------------------------------------------
+# configuration options related to the input files
+#---------------------------------------------------------------------------
+INPUT = $(top_srcdir)/include/
+FILE_PATTERNS = *.h
+RECURSIVE = YES
+EXCLUDE =
+EXCLUDE_SYMLINKS = NO
+EXCLUDE_PATTERNS =
+EXAMPLE_PATH =
+EXAMPLE_PATTERNS =
+EXAMPLE_RECURSIVE = NO
+IMAGE_PATH =
+INPUT_FILTER =
+FILTER_PATTERNS =
+FILTER_SOURCE_FILES = NO
+#---------------------------------------------------------------------------
+# configuration options related to source browsing
+#---------------------------------------------------------------------------
+SOURCE_BROWSER = NO
+INLINE_SOURCES = NO
+STRIP_CODE_COMMENTS = YES
+REFERENCED_BY_RELATION = NO
+REFERENCES_RELATION = NO
+USE_HTAGS = NO
+VERBATIM_HEADERS = NO
+#---------------------------------------------------------------------------
+# configuration options related to the alphabetical class index
+#---------------------------------------------------------------------------
+ALPHABETICAL_INDEX = NO
+COLS_IN_ALPHA_INDEX = 5
+IGNORE_PREFIX =
+#---------------------------------------------------------------------------
+# configuration options related to the HTML output
+#---------------------------------------------------------------------------
+GENERATE_HTML = YES
+HTML_OUTPUT = html
+HTML_FILE_EXTENSION = .html
+HTML_HEADER =
+HTML_FOOTER =
+HTML_STYLESHEET =
+HTML_ALIGN_MEMBERS = YES
+GENERATE_HTMLHELP = NO
+CHM_FILE =
+HHC_LOCATION =
+GENERATE_CHI = NO
+BINARY_TOC = NO
+TOC_EXPAND = NO
+DISABLE_INDEX = NO
+ENUM_VALUES_PER_LINE = 1
+GENERATE_TREEVIEW = NO
+TREEVIEW_WIDTH = 250
+#---------------------------------------------------------------------------
+# configuration options related to the LaTeX output
+#---------------------------------------------------------------------------
+GENERATE_LATEX = NO
+LATEX_OUTPUT = latex
+LATEX_CMD_NAME = latex
+MAKEINDEX_CMD_NAME = makeindex
+COMPACT_LATEX = NO
+PAPER_TYPE = a4wide
+EXTRA_PACKAGES =
+LATEX_HEADER =
+PDF_HYPERLINKS = NO
+USE_PDFLATEX = NO
+LATEX_BATCHMODE = NO
+LATEX_HIDE_INDICES = NO
+#---------------------------------------------------------------------------
+# configuration options related to the RTF output
+#---------------------------------------------------------------------------
+GENERATE_RTF = NO
+RTF_OUTPUT = rtf
+COMPACT_RTF = NO
+RTF_HYPERLINKS = NO
+RTF_STYLESHEET_FILE =
+RTF_EXTENSIONS_FILE =
+#---------------------------------------------------------------------------
+# configuration options related to the man page output
+#---------------------------------------------------------------------------
+GENERATE_MAN = NO
+MAN_OUTPUT = man
+MAN_EXTENSION = .3
+MAN_LINKS = NO
+#---------------------------------------------------------------------------
+# configuration options related to the XML output
+#---------------------------------------------------------------------------
+GENERATE_XML = NO
+XML_OUTPUT = xml
+XML_SCHEMA =
+XML_DTD =
+XML_PROGRAMLISTING = YES
+#---------------------------------------------------------------------------
+# configuration options for the AutoGen Definitions output
+#---------------------------------------------------------------------------
+GENERATE_AUTOGEN_DEF = NO
+#---------------------------------------------------------------------------
+# configuration options related to the Perl module output
+#---------------------------------------------------------------------------
+GENERATE_PERLMOD = NO
+PERLMOD_LATEX = NO
+PERLMOD_PRETTY = YES
+PERLMOD_MAKEVAR_PREFIX =
+#---------------------------------------------------------------------------
+# Configuration options related to the preprocessor
+#---------------------------------------------------------------------------
+ENABLE_PREPROCESSING = YES
+MACRO_EXPANSION = YES
+EXPAND_ONLY_PREDEF = YES
+SEARCH_INCLUDES = YES
+INCLUDE_PATH =
+INCLUDE_FILE_PATTERNS =
+PREDEFINED = "YAML_DECLARE(type)=type"
+EXPAND_AS_DEFINED =
+SKIP_FUNCTION_MACROS = YES
+#---------------------------------------------------------------------------
+# Configuration::additions related to external references
+#---------------------------------------------------------------------------
+TAGFILES =
+GENERATE_TAGFILE =
+ALLEXTERNALS = NO
+EXTERNAL_GROUPS = YES
+PERL_PATH = /usr/bin/perl
+#---------------------------------------------------------------------------
+# Configuration options related to the dot tool
+#---------------------------------------------------------------------------
+CLASS_DIAGRAMS = NO
+HIDE_UNDOC_RELATIONS = YES
+HAVE_DOT = NO
+CLASS_GRAPH = YES
+COLLABORATION_GRAPH = YES
+GROUP_GRAPHS = YES
+UML_LOOK = NO
+TEMPLATE_RELATIONS = NO
+INCLUDE_GRAPH = YES
+INCLUDED_BY_GRAPH = YES
+CALL_GRAPH = NO
+GRAPHICAL_HIERARCHY = YES
+DIRECTORY_GRAPH = YES
+DOT_IMAGE_FORMAT = png
+DOT_PATH =
+DOTFILE_DIRS =
+MAX_DOT_GRAPH_WIDTH = 1024
+MAX_DOT_GRAPH_HEIGHT = 1024
+MAX_DOT_GRAPH_DEPTH = 0
+DOT_TRANSPARENT = NO
+DOT_MULTI_TARGETS = NO
+GENERATE_LEGEND = YES
+DOT_CLEANUP = YES
+#---------------------------------------------------------------------------
+# Configuration::additions related to the search engine
+#---------------------------------------------------------------------------
+SEARCHENGINE = NO
diff --git a/contrib/libyaml/doc/html/annotated.html b/contrib/libyaml/doc/html/annotated.html
new file mode 100644
index 0000000..7cce097
--- /dev/null
+++ b/contrib/libyaml/doc/html/annotated.html
@@ -0,0 +1,51 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head>
+<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/>
+<title>yaml: Data Structures</title>
+<link href="tabs.css" rel="stylesheet" type="text/css"/>
+<link href="doxygen.css" rel="stylesheet" type="text/css"/>
+</head>
+<body>
+<!-- Generated by Doxygen 1.7.1 -->
+<div class="navigation" id="top">
+ <div class="tabs">
+ <ul class="tablist">
+ <li><a href="index.html"><span>Main&nbsp;Page</span></a></li>
+ <li><a href="modules.html"><span>Modules</span></a></li>
+ <li class="current"><a href="annotated.html"><span>Data&nbsp;Structures</span></a></li>
+ <li><a href="files.html"><span>Files</span></a></li>
+ </ul>
+ </div>
+ <div class="tabs2">
+ <ul class="tablist">
+ <li class="current"><a href="annotated.html"><span>Data&nbsp;Structures</span></a></li>
+ <li><a href="functions.html"><span>Data&nbsp;Fields</span></a></li>
+ </ul>
+ </div>
+</div>
+<div class="header">
+ <div class="headertitle">
+<h1>Data Structures</h1> </div>
+</div>
+<div class="contents">
+Here are the data structures with brief descriptions:<table>
+ <tr><td class="indexkey"><a class="el" href="structyaml__alias__data__s.html">yaml_alias_data_s</a></td><td class="indexvalue">This structure holds aliases data </td></tr>
+ <tr><td class="indexkey"><a class="el" href="structyaml__document__s.html">yaml_document_s</a></td><td class="indexvalue">The document structure </td></tr>
+ <tr><td class="indexkey"><a class="el" href="structyaml__emitter__s.html">yaml_emitter_s</a></td><td class="indexvalue">The emitter structure </td></tr>
+ <tr><td class="indexkey"><a class="el" href="structyaml__event__s.html">yaml_event_s</a></td><td class="indexvalue">The event structure </td></tr>
+ <tr><td class="indexkey"><a class="el" href="structyaml__mark__s.html">yaml_mark_s</a></td><td class="indexvalue">The pointer position </td></tr>
+ <tr><td class="indexkey"><a class="el" href="structyaml__node__pair__s.html">yaml_node_pair_s</a></td><td class="indexvalue">An element of a mapping node </td></tr>
+ <tr><td class="indexkey"><a class="el" href="structyaml__node__s.html">yaml_node_s</a></td><td class="indexvalue">The node structure </td></tr>
+ <tr><td class="indexkey"><a class="el" href="structyaml__parser__s.html">yaml_parser_s</a></td><td class="indexvalue">The parser structure </td></tr>
+ <tr><td class="indexkey"><a class="el" href="structyaml__simple__key__s.html">yaml_simple_key_s</a></td><td class="indexvalue">This structure holds information about a potential simple key </td></tr>
+ <tr><td class="indexkey"><a class="el" href="structyaml__tag__directive__s.html">yaml_tag_directive_s</a></td><td class="indexvalue">The tag directive data </td></tr>
+ <tr><td class="indexkey"><a class="el" href="structyaml__token__s.html">yaml_token_s</a></td><td class="indexvalue">The token structure </td></tr>
+ <tr><td class="indexkey"><a class="el" href="structyaml__version__directive__s.html">yaml_version_directive_s</a></td><td class="indexvalue">The version directive data </td></tr>
+</table>
+</div>
+<hr class="footer"/><address class="footer"><small>Generated on Mon May 30 2011 22:00:00 for yaml by&nbsp;
+<a href="http://www.doxygen.org/index.html">
+<img class="footer" src="doxygen.png" alt="doxygen"/></a> 1.7.1 </small></address>
+</body>
+</html>
diff --git a/contrib/libyaml/doc/html/bc_s.png b/contrib/libyaml/doc/html/bc_s.png
new file mode 100644
index 0000000..e401862
--- /dev/null
+++ b/contrib/libyaml/doc/html/bc_s.png
Binary files differ
diff --git a/contrib/libyaml/doc/html/classes.html b/contrib/libyaml/doc/html/classes.html
new file mode 100644
index 0000000..8bcca58
--- /dev/null
+++ b/contrib/libyaml/doc/html/classes.html
@@ -0,0 +1,41 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head>
+<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/>
+<title>yaml: Alphabetical List</title>
+<link href="tabs.css" rel="stylesheet" type="text/css"/>
+<link href="doxygen.css" rel="stylesheet" type="text/css"/>
+</head>
+<body>
+<!-- Generated by Doxygen 1.7.1 -->
+<div class="navigation" id="top">
+ <div class="tabs">
+ <ul class="tablist">
+ <li><a href="index.html"><span>Main&nbsp;Page</span></a></li>
+ <li><a href="modules.html"><span>Modules</span></a></li>
+ <li class="current"><a href="annotated.html"><span>Data&nbsp;Structures</span></a></li>
+ <li><a href="files.html"><span>Files</span></a></li>
+ </ul>
+ </div>
+ <div class="tabs2">
+ <ul class="tablist">
+ <li><a href="annotated.html"><span>Data&nbsp;Structures</span></a></li>
+ <li><a href="functions.html"><span>Data&nbsp;Fields</span></a></li>
+ </ul>
+ </div>
+</div>
+<div class="header">
+ <div class="headertitle">
+<h1>Data Structure Index</h1> </div>
+</div>
+<div class="contents">
+<div class="qindex"><a class="qindex" href="#letter_Y">Y</a></div>
+<table align="center" width="95%" border="0" cellspacing="0" cellpadding="0">
+<tr><td><a name="letter_Y"></a><table border="0" cellspacing="0" cellpadding="0"><tr><td><div class="ah">&nbsp;&nbsp;Y&nbsp;&nbsp;</div></td></tr></table>
+</td><td><a class="el" href="structyaml__emitter__s.html">yaml_emitter_s</a>&nbsp;&nbsp;&nbsp;</td><td><a class="el" href="structyaml__node__pair__s.html">yaml_node_pair_s</a>&nbsp;&nbsp;&nbsp;</td><td><a class="el" href="structyaml__simple__key__s.html">yaml_simple_key_s</a>&nbsp;&nbsp;&nbsp;</td><td><a class="el" href="structyaml__token__s.html">yaml_token_s</a>&nbsp;&nbsp;&nbsp;</td></tr><tr><td><a class="el" href="structyaml__alias__data__s.html">yaml_alias_data_s</a>&nbsp;&nbsp;&nbsp;</td><td><a class="el" href="structyaml__event__s.html">yaml_event_s</a>&nbsp;&nbsp;&nbsp;</td><td><a class="el" href="structyaml__node__s.html">yaml_node_s</a>&nbsp;&nbsp;&nbsp;</td><td><a class="el" href="structyaml__tag__directive__s.html">yaml_tag_directive_s</a>&nbsp;&nbsp;&nbsp;</td><td><a class="el" href="structyaml__version__directive__s.html">yaml_version_directive_s</a>&nbsp;&nbsp;&nbsp;</td></tr><tr><td><a class="el" href="structyaml__document__s.html">yaml_document_s</a>&nbsp;&nbsp;&nbsp;</td><td><a class="el" href="structyaml__mark__s.html">yaml_mark_s</a>&nbsp;&nbsp;&nbsp;</td><td><a class="el" href="structyaml__parser__s.html">yaml_parser_s</a>&nbsp;&nbsp;&nbsp;</td></tr></table><div class="qindex"><a class="qindex" href="#letter_Y">Y</a></div>
+</div>
+<hr class="footer"/><address class="footer"><small>Generated on Mon May 30 2011 22:00:00 for yaml by&nbsp;
+<a href="http://www.doxygen.org/index.html">
+<img class="footer" src="doxygen.png" alt="doxygen"/></a> 1.7.1 </small></address>
+</body>
+</html>
diff --git a/contrib/libyaml/doc/html/closed.png b/contrib/libyaml/doc/html/closed.png
new file mode 100644
index 0000000..b7d4bd9
--- /dev/null
+++ b/contrib/libyaml/doc/html/closed.png
Binary files differ
diff --git a/contrib/libyaml/doc/html/doxygen.css b/contrib/libyaml/doc/html/doxygen.css
new file mode 100644
index 0000000..658686f
--- /dev/null
+++ b/contrib/libyaml/doc/html/doxygen.css
@@ -0,0 +1,656 @@
+/* The standard CSS for doxygen */
+
+body, table, div, p, dl {
+ font-family: Lucida Grande, Verdana, Geneva, Arial, sans-serif;
+ font-size: 12px;
+}
+
+/* @group Heading Levels */
+
+h1 {
+ font-size: 150%;
+}
+
+h2 {
+ font-size: 120%;
+}
+
+h3 {
+ font-size: 100%;
+}
+
+dt {
+ font-weight: bold;
+}
+
+div.multicol {
+ -moz-column-gap: 1em;
+ -webkit-column-gap: 1em;
+ -moz-column-count: 3;
+ -webkit-column-count: 3;
+}
+
+p.startli, p.startdd, p.starttd {
+ margin-top: 2px;
+}
+
+p.endli {
+ margin-bottom: 0px;
+}
+
+p.enddd {
+ margin-bottom: 4px;
+}
+
+p.endtd {
+ margin-bottom: 2px;
+}
+
+/* @end */
+
+caption {
+ font-weight: bold;
+}
+
+span.legend {
+ font-size: 70%;
+ text-align: center;
+}
+
+h3.version {
+ font-size: 90%;
+ text-align: center;
+}
+
+div.qindex, div.navtab{
+ background-color: #EBEFF6;
+ border: 1px solid #A3B4D7;
+ text-align: center;
+ margin: 2px;
+ padding: 2px;
+}
+
+div.qindex, div.navpath {
+ width: 100%;
+ line-height: 140%;
+}
+
+div.navtab {
+ margin-right: 15px;
+}
+
+/* @group Link Styling */
+
+a {
+ color: #3D578C;
+ font-weight: normal;
+ text-decoration: none;
+}
+
+.contents a:visited {
+ color: #4665A2;
+}
+
+a:hover {
+ text-decoration: underline;
+}
+
+a.qindex {
+ font-weight: bold;
+}
+
+a.qindexHL {
+ font-weight: bold;
+ background-color: #9CAFD4;
+ color: #ffffff;
+ border: 1px double #869DCA;
+}
+
+.contents a.qindexHL:visited {
+ color: #ffffff;
+}
+
+a.el {
+ font-weight: bold;
+}
+
+a.elRef {
+}
+
+a.code {
+ color: #4665A2;
+}
+
+a.codeRef {
+ color: #4665A2;
+}
+
+/* @end */
+
+dl.el {
+ margin-left: -1cm;
+}
+
+.fragment {
+ font-family: monospace, fixed;
+ font-size: 105%;
+}
+
+pre.fragment {
+ border: 1px solid #C4CFE5;
+ background-color: #FBFCFD;
+ padding: 4px 6px;
+ margin: 4px 8px 4px 2px;
+ overflow: auto;
+ word-wrap: break-word;
+ font-size: 9pt;
+ line-height: 125%;
+}
+
+div.ah {
+ background-color: black;
+ font-weight: bold;
+ color: #ffffff;
+ margin-bottom: 3px;
+ margin-top: 3px;
+ padding: 0.2em;
+ border: solid thin #333;
+ border-radius: 0.5em;
+ -webkit-border-radius: .5em;
+ -moz-border-radius: .5em;
+ -webkit-box-shadow: 2px 2px 3px #999;
+ -moz-box-shadow: rgba(0, 0, 0, 0.15) 2px 2px 2px;
+ background-image: -webkit-gradient(linear, left top, left bottom, from(#eee), to(#000),color-stop(0.3, #444));
+ background-image: -moz-linear-gradient(center top, #eee 0%, #444 40%, #000);
+}
+
+div.groupHeader {
+ margin-left: 16px;
+ margin-top: 12px;
+ margin-bottom: 6px;
+ font-weight: bold;
+}
+
+div.groupText {
+ margin-left: 16px;
+ font-style: italic;
+}
+
+body {
+ background: white;
+ color: black;
+ margin: 0;
+}
+
+div.contents {
+ margin-top: 10px;
+ margin-left: 10px;
+ margin-right: 10px;
+}
+
+td.indexkey {
+ background-color: #EBEFF6;
+ font-weight: bold;
+ border: 1px solid #C4CFE5;
+ margin: 2px 0px 2px 0;
+ padding: 2px 10px;
+}
+
+td.indexvalue {
+ background-color: #EBEFF6;
+ border: 1px solid #C4CFE5;
+ padding: 2px 10px;
+ margin: 2px 0px;
+}
+
+tr.memlist {
+ background-color: #EEF1F7;
+}
+
+p.formulaDsp {
+ text-align: center;
+}
+
+img.formulaDsp {
+
+}
+
+img.formulaInl {
+ vertical-align: middle;
+}
+
+div.center {
+ text-align: center;
+ margin-top: 0px;
+ margin-bottom: 0px;
+ padding: 0px;
+}
+
+div.center img {
+ border: 0px;
+}
+
+address.footer {
+ text-align: right;
+ padding-right: 12px;
+}
+
+img.footer {
+ border: 0px;
+ vertical-align: middle;
+}
+
+/* @group Code Colorization */
+
+span.keyword {
+ color: #008000
+}
+
+span.keywordtype {
+ color: #604020
+}
+
+span.keywordflow {
+ color: #e08000
+}
+
+span.comment {
+ color: #800000
+}
+
+span.preprocessor {
+ color: #806020
+}
+
+span.stringliteral {
+ color: #002080
+}
+
+span.charliteral {
+ color: #008080
+}
+
+span.vhdldigit {
+ color: #ff00ff
+}
+
+span.vhdlchar {
+ color: #000000
+}
+
+span.vhdlkeyword {
+ color: #700070
+}
+
+span.vhdllogic {
+ color: #ff0000
+}
+
+/* @end */
+
+/*
+.search {
+ color: #003399;
+ font-weight: bold;
+}
+
+form.search {
+ margin-bottom: 0px;
+ margin-top: 0px;
+}
+
+input.search {
+ font-size: 75%;
+ color: #000080;
+ font-weight: normal;
+ background-color: #e8eef2;
+}
+*/
+
+td.tiny {
+ font-size: 75%;
+}
+
+.dirtab {
+ padding: 4px;
+ border-collapse: collapse;
+ border: 1px solid #A3B4D7;
+}
+
+th.dirtab {
+ background: #EBEFF6;
+ font-weight: bold;
+}
+
+hr {
+ height: 0px;
+ border: none;
+ border-top: 1px solid #4A6AAA;
+}
+
+hr.footer {
+ height: 1px;
+}
+
+/* @group Member Descriptions */
+
+table.memberdecls {
+ border-spacing: 0px;
+ padding: 0px;
+}
+
+.mdescLeft, .mdescRight,
+.memItemLeft, .memItemRight,
+.memTemplItemLeft, .memTemplItemRight, .memTemplParams {
+ background-color: #F9FAFC;
+ border: none;
+ margin: 4px;
+ padding: 1px 0 0 8px;
+}
+
+.mdescLeft, .mdescRight {
+ padding: 0px 8px 4px 8px;
+ color: #555;
+}
+
+.memItemLeft, .memItemRight, .memTemplParams {
+ border-top: 1px solid #C4CFE5;
+}
+
+.memItemLeft, .memTemplItemLeft {
+ white-space: nowrap;
+}
+
+.memTemplParams {
+ color: #4665A2;
+ white-space: nowrap;
+}
+
+/* @end */
+
+/* @group Member Details */
+
+/* Styles for detailed member documentation */
+
+.memtemplate {
+ font-size: 80%;
+ color: #4665A2;
+ font-weight: normal;
+ margin-left: 3px;
+}
+
+.memnav {
+ background-color: #EBEFF6;
+ border: 1px solid #A3B4D7;
+ text-align: center;
+ margin: 2px;
+ margin-right: 15px;
+ padding: 2px;
+}
+
+.memitem {
+ padding: 0;
+ margin-bottom: 10px;
+}
+
+.memname {
+ white-space: nowrap;
+ font-weight: bold;
+ margin-left: 6px;
+}
+
+.memproto {
+ border-top: 1px solid #A8B8D9;
+ border-left: 1px solid #A8B8D9;
+ border-right: 1px solid #A8B8D9;
+ padding: 6px 0px 6px 0px;
+ color: #253555;
+ font-weight: bold;
+ text-shadow: 0px 1px 1px rgba(255, 255, 255, 0.9);
+ /* firefox specific markup */
+ -moz-box-shadow: rgba(0, 0, 0, 0.15) 5px 5px 5px;
+ -moz-border-radius-topright: 8px;
+ -moz-border-radius-topleft: 8px;
+ /* webkit specific markup */
+ -webkit-box-shadow: 5px 5px 5px rgba(0, 0, 0, 0.15);
+ -webkit-border-top-right-radius: 8px;
+ -webkit-border-top-left-radius: 8px;
+ background-image:url('nav_f.png');
+ background-repeat:repeat-x;
+ background-color: #E2E8F2;
+
+}
+
+.memdoc {
+ border-bottom: 1px solid #A8B8D9;
+ border-left: 1px solid #A8B8D9;
+ border-right: 1px solid #A8B8D9;
+ padding: 2px 5px;
+ background-color: #FBFCFD;
+ border-top-width: 0;
+ /* firefox specific markup */
+ -moz-border-radius-bottomleft: 8px;
+ -moz-border-radius-bottomright: 8px;
+ -moz-box-shadow: rgba(0, 0, 0, 0.15) 5px 5px 5px;
+ background-image: -moz-linear-gradient(center top, #FFFFFF 0%, #FFFFFF 60%, #F7F8FB 95%, #EEF1F7);
+ /* webkit specific markup */
+ -webkit-border-bottom-left-radius: 8px;
+ -webkit-border-bottom-right-radius: 8px;
+ -webkit-box-shadow: 5px 5px 5px rgba(0, 0, 0, 0.15);
+ background-image: -webkit-gradient(linear,center top,center bottom,from(#FFFFFF), color-stop(0.6,#FFFFFF), color-stop(0.60,#FFFFFF), color-stop(0.95,#F7F8FB), to(#EEF1F7));
+}
+
+.paramkey {
+ text-align: right;
+}
+
+.paramtype {
+ white-space: nowrap;
+}
+
+.paramname {
+ color: #602020;
+ white-space: nowrap;
+}
+.paramname em {
+ font-style: normal;
+}
+
+/* @end */
+
+/* @group Directory (tree) */
+
+/* for the tree view */
+
+.ftvtree {
+ font-family: sans-serif;
+ margin: 0px;
+}
+
+/* these are for tree view when used as main index */
+
+.directory {
+ font-size: 9pt;
+ font-weight: bold;
+ margin: 5px;
+}
+
+.directory h3 {
+ margin: 0px;
+ margin-top: 1em;
+ font-size: 11pt;
+}
+
+/*
+The following two styles can be used to replace the root node title
+with an image of your choice. Simply uncomment the next two styles,
+specify the name of your image and be sure to set 'height' to the
+proper pixel height of your image.
+*/
+
+/*
+.directory h3.swap {
+ height: 61px;
+ background-repeat: no-repeat;
+ background-image: url("yourimage.gif");
+}
+.directory h3.swap span {
+ display: none;
+}
+*/
+
+.directory > h3 {
+ margin-top: 0;
+}
+
+.directory p {
+ margin: 0px;
+ white-space: nowrap;
+}
+
+.directory div {
+ display: none;
+ margin: 0px;
+}
+
+.directory img {
+ vertical-align: -30%;
+}
+
+/* these are for tree view when not used as main index */
+
+.directory-alt {
+ font-size: 100%;
+ font-weight: bold;
+}
+
+.directory-alt h3 {
+ margin: 0px;
+ margin-top: 1em;
+ font-size: 11pt;
+}
+
+.directory-alt > h3 {
+ margin-top: 0;
+}
+
+.directory-alt p {
+ margin: 0px;
+ white-space: nowrap;
+}
+
+.directory-alt div {
+ display: none;
+ margin: 0px;
+}
+
+.directory-alt img {
+ vertical-align: -30%;
+}
+
+/* @end */
+
+div.dynheader {
+ margin-top: 8px;
+}
+
+address {
+ font-style: normal;
+ color: #2A3D61;
+}
+
+table.doxtable {
+ border-collapse:collapse;
+}
+
+table.doxtable td, table.doxtable th {
+ border: 1px solid #2D4068;
+ padding: 3px 7px 2px;
+}
+
+table.doxtable th {
+ background-color: #374F7F;
+ color: #FFFFFF;
+ font-size: 110%;
+ padding-bottom: 4px;
+ padding-top: 5px;
+ text-align:left;
+}
+
+.tabsearch {
+ top: 0px;
+ left: 10px;
+ height: 36px;
+ background-image: url('tab_b.png');
+ z-index: 101;
+ overflow: hidden;
+ font-size: 13px;
+}
+
+.navpath ul
+{
+ font-size: 11px;
+ background-image:url('tab_b.png');
+ background-repeat:repeat-x;
+ height:30px;
+ line-height:30px;
+ color:#8AA0CC;
+ border:solid 1px #C2CDE4;
+ overflow:hidden;
+ margin:0px;
+ padding:0px;
+}
+
+.navpath li
+{
+ list-style-type:none;
+ float:left;
+ padding-left:10px;
+ padding-right: 15px;
+ background-image:url('bc_s.png');
+ background-repeat:no-repeat;
+ background-position:right;
+ color:#364D7C;
+}
+
+.navpath a
+{
+ height:32px;
+ display:block;
+ text-decoration: none;
+ outline: none;
+}
+
+.navpath a:hover
+{
+ color:#6884BD;
+}
+
+div.summary
+{
+ float: right;
+ font-size: 8pt;
+ padding-right: 5px;
+ width: 50%;
+ text-align: right;
+}
+
+div.summary a
+{
+ white-space: nowrap;
+}
+
+div.header
+{
+ background-image:url('nav_h.png');
+ background-repeat:repeat-x;
+ background-color: #F9FAFC;
+ margin: 0px;
+ border-bottom: 1px solid #C4CFE5;
+}
+
+div.headertitle
+{
+ padding: 5px 5px 5px 10px;
+}
+
diff --git a/contrib/libyaml/doc/html/doxygen.png b/contrib/libyaml/doc/html/doxygen.png
new file mode 100644
index 0000000..635ed52
--- /dev/null
+++ b/contrib/libyaml/doc/html/doxygen.png
Binary files differ
diff --git a/contrib/libyaml/doc/html/files.html b/contrib/libyaml/doc/html/files.html
new file mode 100644
index 0000000..7bd75ee
--- /dev/null
+++ b/contrib/libyaml/doc/html/files.html
@@ -0,0 +1,40 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head>
+<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/>
+<title>yaml: File Index</title>
+<link href="tabs.css" rel="stylesheet" type="text/css"/>
+<link href="doxygen.css" rel="stylesheet" type="text/css"/>
+</head>
+<body>
+<!-- Generated by Doxygen 1.7.1 -->
+<div class="navigation" id="top">
+ <div class="tabs">
+ <ul class="tablist">
+ <li><a href="index.html"><span>Main&nbsp;Page</span></a></li>
+ <li><a href="modules.html"><span>Modules</span></a></li>
+ <li><a href="annotated.html"><span>Data&nbsp;Structures</span></a></li>
+ <li class="current"><a href="files.html"><span>Files</span></a></li>
+ </ul>
+ </div>
+ <div class="tabs2">
+ <ul class="tablist">
+ <li class="current"><a href="files.html"><span>File&nbsp;List</span></a></li>
+ <li><a href="globals.html"><span>Globals</span></a></li>
+ </ul>
+ </div>
+</div>
+<div class="header">
+ <div class="headertitle">
+<h1>File List</h1> </div>
+</div>
+<div class="contents">
+Here is a list of all documented files with brief descriptions:<table>
+ <tr><td class="indexkey"><a class="el" href="yaml_8h.html">yaml.h</a></td><td class="indexvalue">Public interface for libyaml </td></tr>
+</table>
+</div>
+<hr class="footer"/><address class="footer"><small>Generated on Mon May 30 2011 22:00:01 for yaml by&nbsp;
+<a href="http://www.doxygen.org/index.html">
+<img class="footer" src="doxygen.png" alt="doxygen"/></a> 1.7.1 </small></address>
+</body>
+</html>
diff --git a/contrib/libyaml/doc/html/functions.html b/contrib/libyaml/doc/html/functions.html
new file mode 100644
index 0000000..16e9eda
--- /dev/null
+++ b/contrib/libyaml/doc/html/functions.html
@@ -0,0 +1,91 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head>
+<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/>
+<title>yaml: Data Fields</title>
+<link href="tabs.css" rel="stylesheet" type="text/css"/>
+<link href="doxygen.css" rel="stylesheet" type="text/css"/>
+</head>
+<body>
+<!-- Generated by Doxygen 1.7.1 -->
+<div class="navigation" id="top">
+ <div class="tabs">
+ <ul class="tablist">
+ <li><a href="index.html"><span>Main&nbsp;Page</span></a></li>
+ <li><a href="modules.html"><span>Modules</span></a></li>
+ <li class="current"><a href="annotated.html"><span>Data&nbsp;Structures</span></a></li>
+ <li><a href="files.html"><span>Files</span></a></li>
+ </ul>
+ </div>
+ <div class="tabs2">
+ <ul class="tablist">
+ <li><a href="annotated.html"><span>Data&nbsp;Structures</span></a></li>
+ <li class="current"><a href="functions.html"><span>Data&nbsp;Fields</span></a></li>
+ </ul>
+ </div>
+ <div class="tabs2">
+ <ul class="tablist">
+ <li class="current"><a href="functions.html"><span>All</span></a></li>
+ <li><a href="functions_vars.html"><span>Variables</span></a></li>
+ </ul>
+ </div>
+ <div class="tabs3">
+ <ul class="tablist">
+ <li class="current"><a href="functions.html#index_a"><span>a</span></a></li>
+ <li><a href="functions_0x62.html#index_b"><span>b</span></a></li>
+ <li><a href="functions_0x63.html#index_c"><span>c</span></a></li>
+ <li><a href="functions_0x64.html#index_d"><span>d</span></a></li>
+ <li><a href="functions_0x65.html#index_e"><span>e</span></a></li>
+ <li><a href="functions_0x66.html#index_f"><span>f</span></a></li>
+ <li><a href="functions_0x68.html#index_h"><span>h</span></a></li>
+ <li><a href="functions_0x69.html#index_i"><span>i</span></a></li>
+ <li><a href="functions_0x6b.html#index_k"><span>k</span></a></li>
+ <li><a href="functions_0x6c.html#index_l"><span>l</span></a></li>
+ <li><a href="functions_0x6d.html#index_m"><span>m</span></a></li>
+ <li><a href="functions_0x6e.html#index_n"><span>n</span></a></li>
+ <li><a href="functions_0x6f.html#index_o"><span>o</span></a></li>
+ <li><a href="functions_0x70.html#index_p"><span>p</span></a></li>
+ <li><a href="functions_0x71.html#index_q"><span>q</span></a></li>
+ <li><a href="functions_0x72.html#index_r"><span>r</span></a></li>
+ <li><a href="functions_0x73.html#index_s"><span>s</span></a></li>
+ <li><a href="functions_0x74.html#index_t"><span>t</span></a></li>
+ <li><a href="functions_0x75.html#index_u"><span>u</span></a></li>
+ <li><a href="functions_0x76.html#index_v"><span>v</span></a></li>
+ <li><a href="functions_0x77.html#index_w"><span>w</span></a></li>
+ </ul>
+ </div>
+</div>
+<div class="contents">
+Here is a list of all documented struct and union fields with links to the struct/union documentation for each field:
+
+<h3><a class="anchor" id="index_a"></a>- a -</h3><ul>
+<li>alias
+: <a class="el" href="structyaml__token__s.html#a1f942353efa1972a38a0763afefabe0c">yaml_token_s</a>
+, <a class="el" href="structyaml__event__s.html#ac21f0f1e12207b8fd4f02496259f6c0b">yaml_event_s</a>
+, <a class="el" href="structyaml__emitter__s.html#a1129c6f9ae5cd3b437b8ab8767324f03">yaml_emitter_s</a>
+</li>
+<li>aliases
+: <a class="el" href="structyaml__parser__s.html#a0c10698207d727f9e5d9ced627d130ef">yaml_parser_s</a>
+</li>
+<li>anchor
+: <a class="el" href="structyaml__emitter__s.html#a6f2882bde71e478e29dc5b293def8739">yaml_emitter_s</a>
+, <a class="el" href="structyaml__alias__data__s.html#ac4b9a352dd8ff747bfa63a54832d7962">yaml_alias_data_s</a>
+, <a class="el" href="structyaml__token__s.html#acc0f6636995f5fe332604b74571e6cfa">yaml_token_s</a>
+, <a class="el" href="structyaml__event__s.html#aaa97ab683d28e5f611042d0fbd929125">yaml_event_s</a>
+</li>
+<li>anchor_data
+: <a class="el" href="structyaml__emitter__s.html#ad8883d967ee02e3e15e58bc2533188cc">yaml_emitter_s</a>
+</li>
+<li>anchor_length
+: <a class="el" href="structyaml__emitter__s.html#aece73cc234475630032b1c75a735eeb5">yaml_emitter_s</a>
+</li>
+<li>anchors
+: <a class="el" href="structyaml__emitter__s.html#ad4e7a72cb8b1b67373ba6d76a5229e6b">yaml_emitter_s</a>
+</li>
+</ul>
+</div>
+<hr class="footer"/><address class="footer"><small>Generated on Mon May 30 2011 22:00:00 for yaml by&nbsp;
+<a href="http://www.doxygen.org/index.html">
+<img class="footer" src="doxygen.png" alt="doxygen"/></a> 1.7.1 </small></address>
+</body>
+</html>
diff --git a/contrib/libyaml/doc/html/functions_0x62.html b/contrib/libyaml/doc/html/functions_0x62.html
new file mode 100644
index 0000000..902caf2
--- /dev/null
+++ b/contrib/libyaml/doc/html/functions_0x62.html
@@ -0,0 +1,84 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head>
+<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/>
+<title>yaml: Data Fields</title>
+<link href="tabs.css" rel="stylesheet" type="text/css"/>
+<link href="doxygen.css" rel="stylesheet" type="text/css"/>
+</head>
+<body>
+<!-- Generated by Doxygen 1.7.1 -->
+<div class="navigation" id="top">
+ <div class="tabs">
+ <ul class="tablist">
+ <li><a href="index.html"><span>Main&nbsp;Page</span></a></li>
+ <li><a href="modules.html"><span>Modules</span></a></li>
+ <li class="current"><a href="annotated.html"><span>Data&nbsp;Structures</span></a></li>
+ <li><a href="files.html"><span>Files</span></a></li>
+ </ul>
+ </div>
+ <div class="tabs2">
+ <ul class="tablist">
+ <li><a href="annotated.html"><span>Data&nbsp;Structures</span></a></li>
+ <li class="current"><a href="functions.html"><span>Data&nbsp;Fields</span></a></li>
+ </ul>
+ </div>
+ <div class="tabs2">
+ <ul class="tablist">
+ <li class="current"><a href="functions.html"><span>All</span></a></li>
+ <li><a href="functions_vars.html"><span>Variables</span></a></li>
+ </ul>
+ </div>
+ <div class="tabs3">
+ <ul class="tablist">
+ <li><a href="functions.html#index_a"><span>a</span></a></li>
+ <li class="current"><a href="functions_0x62.html#index_b"><span>b</span></a></li>
+ <li><a href="functions_0x63.html#index_c"><span>c</span></a></li>
+ <li><a href="functions_0x64.html#index_d"><span>d</span></a></li>
+ <li><a href="functions_0x65.html#index_e"><span>e</span></a></li>
+ <li><a href="functions_0x66.html#index_f"><span>f</span></a></li>
+ <li><a href="functions_0x68.html#index_h"><span>h</span></a></li>
+ <li><a href="functions_0x69.html#index_i"><span>i</span></a></li>
+ <li><a href="functions_0x6b.html#index_k"><span>k</span></a></li>
+ <li><a href="functions_0x6c.html#index_l"><span>l</span></a></li>
+ <li><a href="functions_0x6d.html#index_m"><span>m</span></a></li>
+ <li><a href="functions_0x6e.html#index_n"><span>n</span></a></li>
+ <li><a href="functions_0x6f.html#index_o"><span>o</span></a></li>
+ <li><a href="functions_0x70.html#index_p"><span>p</span></a></li>
+ <li><a href="functions_0x71.html#index_q"><span>q</span></a></li>
+ <li><a href="functions_0x72.html#index_r"><span>r</span></a></li>
+ <li><a href="functions_0x73.html#index_s"><span>s</span></a></li>
+ <li><a href="functions_0x74.html#index_t"><span>t</span></a></li>
+ <li><a href="functions_0x75.html#index_u"><span>u</span></a></li>
+ <li><a href="functions_0x76.html#index_v"><span>v</span></a></li>
+ <li><a href="functions_0x77.html#index_w"><span>w</span></a></li>
+ </ul>
+ </div>
+</div>
+<div class="contents">
+Here is a list of all documented struct and union fields with links to the struct/union documentation for each field:
+
+<h3><a class="anchor" id="index_b"></a>- b -</h3><ul>
+<li>best_indent
+: <a class="el" href="structyaml__emitter__s.html#a33545f8924be89daf8b81dc905d558c0">yaml_emitter_s</a>
+</li>
+<li>best_width
+: <a class="el" href="structyaml__emitter__s.html#a56dde6b352bdf7d4031f89d2b5d704f6">yaml_emitter_s</a>
+</li>
+<li>block_allowed
+: <a class="el" href="structyaml__emitter__s.html#a64e05972897d02f606627ef0cf3c7420">yaml_emitter_s</a>
+</li>
+<li>block_plain_allowed
+: <a class="el" href="structyaml__emitter__s.html#a5b5f6c9d687d788c8dac86d213ef4c16">yaml_emitter_s</a>
+</li>
+<li>buffer
+: <a class="el" href="structyaml__emitter__s.html#afb2700e9b866b5be0ff6c7549c719f81">yaml_emitter_s</a>
+, <a class="el" href="structyaml__parser__s.html#afc56b6252bd75ec87edec5c80a5c733e">yaml_parser_s</a>
+</li>
+</ul>
+</div>
+<hr class="footer"/><address class="footer"><small>Generated on Mon May 30 2011 22:00:00 for yaml by&nbsp;
+<a href="http://www.doxygen.org/index.html">
+<img class="footer" src="doxygen.png" alt="doxygen"/></a> 1.7.1 </small></address>
+</body>
+</html>
diff --git a/contrib/libyaml/doc/html/functions_0x63.html b/contrib/libyaml/doc/html/functions_0x63.html
new file mode 100644
index 0000000..fff0416
--- /dev/null
+++ b/contrib/libyaml/doc/html/functions_0x63.html
@@ -0,0 +1,87 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head>
+<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/>
+<title>yaml: Data Fields</title>
+<link href="tabs.css" rel="stylesheet" type="text/css"/>
+<link href="doxygen.css" rel="stylesheet" type="text/css"/>
+</head>
+<body>
+<!-- Generated by Doxygen 1.7.1 -->
+<div class="navigation" id="top">
+ <div class="tabs">
+ <ul class="tablist">
+ <li><a href="index.html"><span>Main&nbsp;Page</span></a></li>
+ <li><a href="modules.html"><span>Modules</span></a></li>
+ <li class="current"><a href="annotated.html"><span>Data&nbsp;Structures</span></a></li>
+ <li><a href="files.html"><span>Files</span></a></li>
+ </ul>
+ </div>
+ <div class="tabs2">
+ <ul class="tablist">
+ <li><a href="annotated.html"><span>Data&nbsp;Structures</span></a></li>
+ <li class="current"><a href="functions.html"><span>Data&nbsp;Fields</span></a></li>
+ </ul>
+ </div>
+ <div class="tabs2">
+ <ul class="tablist">
+ <li class="current"><a href="functions.html"><span>All</span></a></li>
+ <li><a href="functions_vars.html"><span>Variables</span></a></li>
+ </ul>
+ </div>
+ <div class="tabs3">
+ <ul class="tablist">
+ <li><a href="functions.html#index_a"><span>a</span></a></li>
+ <li><a href="functions_0x62.html#index_b"><span>b</span></a></li>
+ <li class="current"><a href="functions_0x63.html#index_c"><span>c</span></a></li>
+ <li><a href="functions_0x64.html#index_d"><span>d</span></a></li>
+ <li><a href="functions_0x65.html#index_e"><span>e</span></a></li>
+ <li><a href="functions_0x66.html#index_f"><span>f</span></a></li>
+ <li><a href="functions_0x68.html#index_h"><span>h</span></a></li>
+ <li><a href="functions_0x69.html#index_i"><span>i</span></a></li>
+ <li><a href="functions_0x6b.html#index_k"><span>k</span></a></li>
+ <li><a href="functions_0x6c.html#index_l"><span>l</span></a></li>
+ <li><a href="functions_0x6d.html#index_m"><span>m</span></a></li>
+ <li><a href="functions_0x6e.html#index_n"><span>n</span></a></li>
+ <li><a href="functions_0x6f.html#index_o"><span>o</span></a></li>
+ <li><a href="functions_0x70.html#index_p"><span>p</span></a></li>
+ <li><a href="functions_0x71.html#index_q"><span>q</span></a></li>
+ <li><a href="functions_0x72.html#index_r"><span>r</span></a></li>
+ <li><a href="functions_0x73.html#index_s"><span>s</span></a></li>
+ <li><a href="functions_0x74.html#index_t"><span>t</span></a></li>
+ <li><a href="functions_0x75.html#index_u"><span>u</span></a></li>
+ <li><a href="functions_0x76.html#index_v"><span>v</span></a></li>
+ <li><a href="functions_0x77.html#index_w"><span>w</span></a></li>
+ </ul>
+ </div>
+</div>
+<div class="contents">
+Here is a list of all documented struct and union fields with links to the struct/union documentation for each field:
+
+<h3><a class="anchor" id="index_c"></a>- c -</h3><ul>
+<li>canonical
+: <a class="el" href="structyaml__emitter__s.html#acb0259cdc5e2bb23faaf7266496df827">yaml_emitter_s</a>
+</li>
+<li>closed
+: <a class="el" href="structyaml__emitter__s.html#a978d894a219686d31d971899e31910cd">yaml_emitter_s</a>
+</li>
+<li>column
+: <a class="el" href="structyaml__emitter__s.html#a678fbbacad5d1f3f9bb7516282888b8a">yaml_emitter_s</a>
+, <a class="el" href="structyaml__mark__s.html#aaa18357a6fb2bb377b969ce9ff589797">yaml_mark_s</a>
+</li>
+<li>context
+: <a class="el" href="structyaml__parser__s.html#a6779b67a23bbf7c401e4257d5875ae6b">yaml_parser_s</a>
+</li>
+<li>context_mark
+: <a class="el" href="structyaml__parser__s.html#ace259eec6e570f94b98b252e1a632e88">yaml_parser_s</a>
+</li>
+<li>current
+: <a class="el" href="structyaml__parser__s.html#a3406d2ba7e969c09344d4ced8c855007">yaml_parser_s</a>
+</li>
+</ul>
+</div>
+<hr class="footer"/><address class="footer"><small>Generated on Mon May 30 2011 22:00:00 for yaml by&nbsp;
+<a href="http://www.doxygen.org/index.html">
+<img class="footer" src="doxygen.png" alt="doxygen"/></a> 1.7.1 </small></address>
+</body>
+</html>
diff --git a/contrib/libyaml/doc/html/functions_0x64.html b/contrib/libyaml/doc/html/functions_0x64.html
new file mode 100644
index 0000000..921b4c1
--- /dev/null
+++ b/contrib/libyaml/doc/html/functions_0x64.html
@@ -0,0 +1,83 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head>
+<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/>
+<title>yaml: Data Fields</title>
+<link href="tabs.css" rel="stylesheet" type="text/css"/>
+<link href="doxygen.css" rel="stylesheet" type="text/css"/>
+</head>
+<body>
+<!-- Generated by Doxygen 1.7.1 -->
+<div class="navigation" id="top">
+ <div class="tabs">
+ <ul class="tablist">
+ <li><a href="index.html"><span>Main&nbsp;Page</span></a></li>
+ <li><a href="modules.html"><span>Modules</span></a></li>
+ <li class="current"><a href="annotated.html"><span>Data&nbsp;Structures</span></a></li>
+ <li><a href="files.html"><span>Files</span></a></li>
+ </ul>
+ </div>
+ <div class="tabs2">
+ <ul class="tablist">
+ <li><a href="annotated.html"><span>Data&nbsp;Structures</span></a></li>
+ <li class="current"><a href="functions.html"><span>Data&nbsp;Fields</span></a></li>
+ </ul>
+ </div>
+ <div class="tabs2">
+ <ul class="tablist">
+ <li class="current"><a href="functions.html"><span>All</span></a></li>
+ <li><a href="functions_vars.html"><span>Variables</span></a></li>
+ </ul>
+ </div>
+ <div class="tabs3">
+ <ul class="tablist">
+ <li><a href="functions.html#index_a"><span>a</span></a></li>
+ <li><a href="functions_0x62.html#index_b"><span>b</span></a></li>
+ <li><a href="functions_0x63.html#index_c"><span>c</span></a></li>
+ <li class="current"><a href="functions_0x64.html#index_d"><span>d</span></a></li>
+ <li><a href="functions_0x65.html#index_e"><span>e</span></a></li>
+ <li><a href="functions_0x66.html#index_f"><span>f</span></a></li>
+ <li><a href="functions_0x68.html#index_h"><span>h</span></a></li>
+ <li><a href="functions_0x69.html#index_i"><span>i</span></a></li>
+ <li><a href="functions_0x6b.html#index_k"><span>k</span></a></li>
+ <li><a href="functions_0x6c.html#index_l"><span>l</span></a></li>
+ <li><a href="functions_0x6d.html#index_m"><span>m</span></a></li>
+ <li><a href="functions_0x6e.html#index_n"><span>n</span></a></li>
+ <li><a href="functions_0x6f.html#index_o"><span>o</span></a></li>
+ <li><a href="functions_0x70.html#index_p"><span>p</span></a></li>
+ <li><a href="functions_0x71.html#index_q"><span>q</span></a></li>
+ <li><a href="functions_0x72.html#index_r"><span>r</span></a></li>
+ <li><a href="functions_0x73.html#index_s"><span>s</span></a></li>
+ <li><a href="functions_0x74.html#index_t"><span>t</span></a></li>
+ <li><a href="functions_0x75.html#index_u"><span>u</span></a></li>
+ <li><a href="functions_0x76.html#index_v"><span>v</span></a></li>
+ <li><a href="functions_0x77.html#index_w"><span>w</span></a></li>
+ </ul>
+ </div>
+</div>
+<div class="contents">
+Here is a list of all documented struct and union fields with links to the struct/union documentation for each field:
+
+<h3><a class="anchor" id="index_d"></a>- d -</h3><ul>
+<li>data
+: <a class="el" href="structyaml__token__s.html#aedb5be9b6b8f5ef6c129575e84f63605">yaml_token_s</a>
+, <a class="el" href="structyaml__event__s.html#a0b8f9cce08e49459e4bab89035dbf6c6">yaml_event_s</a>
+, <a class="el" href="structyaml__node__s.html#a7e1be921e921f2d0911e450a063b1344">yaml_node_s</a>
+</li>
+<li>document
+: <a class="el" href="structyaml__emitter__s.html#af9cc8801cc9b46a4f45255c67a1574a7">yaml_emitter_s</a>
+, <a class="el" href="structyaml__parser__s.html#ac3dad5822f49d86cfddc2e5e415a158c">yaml_parser_s</a>
+</li>
+<li>document_end
+: <a class="el" href="structyaml__event__s.html#acffec5f24c01bb6bfb0c93a9bf1a803e">yaml_event_s</a>
+</li>
+<li>document_start
+: <a class="el" href="structyaml__event__s.html#aed593fadbeb898d6d90b0c62522a82cc">yaml_event_s</a>
+</li>
+</ul>
+</div>
+<hr class="footer"/><address class="footer"><small>Generated on Mon May 30 2011 22:00:00 for yaml by&nbsp;
+<a href="http://www.doxygen.org/index.html">
+<img class="footer" src="doxygen.png" alt="doxygen"/></a> 1.7.1 </small></address>
+</body>
+</html>
diff --git a/contrib/libyaml/doc/html/functions_0x65.html b/contrib/libyaml/doc/html/functions_0x65.html
new file mode 100644
index 0000000..d0d3e30
--- /dev/null
+++ b/contrib/libyaml/doc/html/functions_0x65.html
@@ -0,0 +1,110 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head>
+<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/>
+<title>yaml: Data Fields</title>
+<link href="tabs.css" rel="stylesheet" type="text/css"/>
+<link href="doxygen.css" rel="stylesheet" type="text/css"/>
+</head>
+<body>
+<!-- Generated by Doxygen 1.7.1 -->
+<div class="navigation" id="top">
+ <div class="tabs">
+ <ul class="tablist">
+ <li><a href="index.html"><span>Main&nbsp;Page</span></a></li>
+ <li><a href="modules.html"><span>Modules</span></a></li>
+ <li class="current"><a href="annotated.html"><span>Data&nbsp;Structures</span></a></li>
+ <li><a href="files.html"><span>Files</span></a></li>
+ </ul>
+ </div>
+ <div class="tabs2">
+ <ul class="tablist">
+ <li><a href="annotated.html"><span>Data&nbsp;Structures</span></a></li>
+ <li class="current"><a href="functions.html"><span>Data&nbsp;Fields</span></a></li>
+ </ul>
+ </div>
+ <div class="tabs2">
+ <ul class="tablist">
+ <li class="current"><a href="functions.html"><span>All</span></a></li>
+ <li><a href="functions_vars.html"><span>Variables</span></a></li>
+ </ul>
+ </div>
+ <div class="tabs3">
+ <ul class="tablist">
+ <li><a href="functions.html#index_a"><span>a</span></a></li>
+ <li><a href="functions_0x62.html#index_b"><span>b</span></a></li>
+ <li><a href="functions_0x63.html#index_c"><span>c</span></a></li>
+ <li><a href="functions_0x64.html#index_d"><span>d</span></a></li>
+ <li class="current"><a href="functions_0x65.html#index_e"><span>e</span></a></li>
+ <li><a href="functions_0x66.html#index_f"><span>f</span></a></li>
+ <li><a href="functions_0x68.html#index_h"><span>h</span></a></li>
+ <li><a href="functions_0x69.html#index_i"><span>i</span></a></li>
+ <li><a href="functions_0x6b.html#index_k"><span>k</span></a></li>
+ <li><a href="functions_0x6c.html#index_l"><span>l</span></a></li>
+ <li><a href="functions_0x6d.html#index_m"><span>m</span></a></li>
+ <li><a href="functions_0x6e.html#index_n"><span>n</span></a></li>
+ <li><a href="functions_0x6f.html#index_o"><span>o</span></a></li>
+ <li><a href="functions_0x70.html#index_p"><span>p</span></a></li>
+ <li><a href="functions_0x71.html#index_q"><span>q</span></a></li>
+ <li><a href="functions_0x72.html#index_r"><span>r</span></a></li>
+ <li><a href="functions_0x73.html#index_s"><span>s</span></a></li>
+ <li><a href="functions_0x74.html#index_t"><span>t</span></a></li>
+ <li><a href="functions_0x75.html#index_u"><span>u</span></a></li>
+ <li><a href="functions_0x76.html#index_v"><span>v</span></a></li>
+ <li><a href="functions_0x77.html#index_w"><span>w</span></a></li>
+ </ul>
+ </div>
+</div>
+<div class="contents">
+Here is a list of all documented struct and union fields with links to the struct/union documentation for each field:
+
+<h3><a class="anchor" id="index_e"></a>- e -</h3><ul>
+<li>encoding
+: <a class="el" href="structyaml__token__s.html#aab75b9cb91438e0e1efe2522652cf478">yaml_token_s</a>
+, <a class="el" href="structyaml__event__s.html#a92139ba6ae79089fd9a2f5f4aeaf733f">yaml_event_s</a>
+, <a class="el" href="structyaml__emitter__s.html#ada17f19fa6248d6ee493684b03700857">yaml_emitter_s</a>
+, <a class="el" href="structyaml__parser__s.html#a4f062e9d1fb1082bbf3996e46214905a">yaml_parser_s</a>
+</li>
+<li>end
+: <a class="el" href="structyaml__document__s.html#adc9ffcca86a2684362428da69ffd3dea">yaml_document_s</a>
+, <a class="el" href="structyaml__parser__s.html#a211a0aedc964ba8cd07cb7875faa464b">yaml_parser_s</a>
+, <a class="el" href="structyaml__document__s.html#af14fd1a6c1fd10088391f07349ba55e8">yaml_document_s</a>
+, <a class="el" href="structyaml__parser__s.html#aa7fdc1ff8342636119934ac824a2ecc8">yaml_parser_s</a>
+, <a class="el" href="structyaml__emitter__s.html#a3b28127063323de1d88fc18cdb6adf8a">yaml_emitter_s</a>
+, <a class="el" href="structyaml__event__s.html#a115b4a9797f3a72cd78d42c85100317c">yaml_event_s</a>
+, <a class="el" href="structyaml__emitter__s.html#a55703a15e71c6b9551a2f4feb888bdcb">yaml_emitter_s</a>
+, <a class="el" href="structyaml__parser__s.html#aad74ffeb7f2eef0a12e34b0aac263ff3">yaml_parser_s</a>
+, <a class="el" href="structyaml__emitter__s.html#a42285849529f1b0eb9f4aac2eaef5204">yaml_emitter_s</a>
+, <a class="el" href="structyaml__parser__s.html#a6ff1f802eb95bc45f13e8e73ec009828">yaml_parser_s</a>
+, <a class="el" href="structyaml__node__s.html#ac9b3d891f9fcd5462289823716deca0e">yaml_node_s</a>
+, <a class="el" href="structyaml__parser__s.html#aa768a9c29ae2c3015fdb84ea313844e2">yaml_parser_s</a>
+, <a class="el" href="structyaml__emitter__s.html#a6669a94bc18247491e59c709852be0d1">yaml_emitter_s</a>
+, <a class="el" href="structyaml__parser__s.html#a41594b6495f4d31edb977cafb8cbaf78">yaml_parser_s</a>
+, <a class="el" href="structyaml__node__s.html#a1827ba7f3e7f7e94171fa20ade25345d">yaml_node_s</a>
+</li>
+<li>end_implicit
+: <a class="el" href="structyaml__document__s.html#a59de90b4078659fd0f49377929afcac1">yaml_document_s</a>
+</li>
+<li>end_mark
+: <a class="el" href="structyaml__event__s.html#a9307f91473094c229738b03d223bc4ba">yaml_event_s</a>
+, <a class="el" href="structyaml__node__s.html#a63144671fd16f94f72c6d537360f7328">yaml_node_s</a>
+, <a class="el" href="structyaml__token__s.html#a97f08b38dfb0a5be26ef8831864a5311">yaml_token_s</a>
+, <a class="el" href="structyaml__document__s.html#a9299efdaadf764f4d03641a3ee51e0d0">yaml_document_s</a>
+</li>
+<li>eof
+: <a class="el" href="structyaml__parser__s.html#a6129a99d45aee14ec705aa54dbb493b7">yaml_parser_s</a>
+</li>
+<li>error
+: <a class="el" href="structyaml__emitter__s.html#afa2d6367a86ae6d43df14e24479bb0a7">yaml_emitter_s</a>
+, <a class="el" href="structyaml__parser__s.html#a6c5c3488ff22c8a4d234ca8587fa1472">yaml_parser_s</a>
+</li>
+<li>events
+: <a class="el" href="structyaml__emitter__s.html#a3516b49eb7579e422750a94a9d7c1700">yaml_emitter_s</a>
+</li>
+</ul>
+</div>
+<hr class="footer"/><address class="footer"><small>Generated on Mon May 30 2011 22:00:00 for yaml by&nbsp;
+<a href="http://www.doxygen.org/index.html">
+<img class="footer" src="doxygen.png" alt="doxygen"/></a> 1.7.1 </small></address>
+</body>
+</html>
diff --git a/contrib/libyaml/doc/html/functions_0x66.html b/contrib/libyaml/doc/html/functions_0x66.html
new file mode 100644
index 0000000..e95a19d
--- /dev/null
+++ b/contrib/libyaml/doc/html/functions_0x66.html
@@ -0,0 +1,79 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head>
+<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/>
+<title>yaml: Data Fields</title>
+<link href="tabs.css" rel="stylesheet" type="text/css"/>
+<link href="doxygen.css" rel="stylesheet" type="text/css"/>
+</head>
+<body>
+<!-- Generated by Doxygen 1.7.1 -->
+<div class="navigation" id="top">
+ <div class="tabs">
+ <ul class="tablist">
+ <li><a href="index.html"><span>Main&nbsp;Page</span></a></li>
+ <li><a href="modules.html"><span>Modules</span></a></li>
+ <li class="current"><a href="annotated.html"><span>Data&nbsp;Structures</span></a></li>
+ <li><a href="files.html"><span>Files</span></a></li>
+ </ul>
+ </div>
+ <div class="tabs2">
+ <ul class="tablist">
+ <li><a href="annotated.html"><span>Data&nbsp;Structures</span></a></li>
+ <li class="current"><a href="functions.html"><span>Data&nbsp;Fields</span></a></li>
+ </ul>
+ </div>
+ <div class="tabs2">
+ <ul class="tablist">
+ <li class="current"><a href="functions.html"><span>All</span></a></li>
+ <li><a href="functions_vars.html"><span>Variables</span></a></li>
+ </ul>
+ </div>
+ <div class="tabs3">
+ <ul class="tablist">
+ <li><a href="functions.html#index_a"><span>a</span></a></li>
+ <li><a href="functions_0x62.html#index_b"><span>b</span></a></li>
+ <li><a href="functions_0x63.html#index_c"><span>c</span></a></li>
+ <li><a href="functions_0x64.html#index_d"><span>d</span></a></li>
+ <li><a href="functions_0x65.html#index_e"><span>e</span></a></li>
+ <li class="current"><a href="functions_0x66.html#index_f"><span>f</span></a></li>
+ <li><a href="functions_0x68.html#index_h"><span>h</span></a></li>
+ <li><a href="functions_0x69.html#index_i"><span>i</span></a></li>
+ <li><a href="functions_0x6b.html#index_k"><span>k</span></a></li>
+ <li><a href="functions_0x6c.html#index_l"><span>l</span></a></li>
+ <li><a href="functions_0x6d.html#index_m"><span>m</span></a></li>
+ <li><a href="functions_0x6e.html#index_n"><span>n</span></a></li>
+ <li><a href="functions_0x6f.html#index_o"><span>o</span></a></li>
+ <li><a href="functions_0x70.html#index_p"><span>p</span></a></li>
+ <li><a href="functions_0x71.html#index_q"><span>q</span></a></li>
+ <li><a href="functions_0x72.html#index_r"><span>r</span></a></li>
+ <li><a href="functions_0x73.html#index_s"><span>s</span></a></li>
+ <li><a href="functions_0x74.html#index_t"><span>t</span></a></li>
+ <li><a href="functions_0x75.html#index_u"><span>u</span></a></li>
+ <li><a href="functions_0x76.html#index_v"><span>v</span></a></li>
+ <li><a href="functions_0x77.html#index_w"><span>w</span></a></li>
+ </ul>
+ </div>
+</div>
+<div class="contents">
+Here is a list of all documented struct and union fields with links to the struct/union documentation for each field:
+
+<h3><a class="anchor" id="index_f"></a>- f -</h3><ul>
+<li>file
+: <a class="el" href="structyaml__parser__s.html#ae69c2974e3c4c37e941a0e1971be15a9">yaml_parser_s</a>
+, <a class="el" href="structyaml__emitter__s.html#abfe1e82cd5c4a180b1468e65ccfd1c61">yaml_emitter_s</a>
+</li>
+<li>flow_level
+: <a class="el" href="structyaml__emitter__s.html#a50f8e97c4290b83ebd646b4c4f5c5de9">yaml_emitter_s</a>
+, <a class="el" href="structyaml__parser__s.html#a6a4bbbd3f58533e0969b7218c1e73fd4">yaml_parser_s</a>
+</li>
+<li>flow_plain_allowed
+: <a class="el" href="structyaml__emitter__s.html#afd8496f5bb995bb5aacc349fd6b45bf5">yaml_emitter_s</a>
+</li>
+</ul>
+</div>
+<hr class="footer"/><address class="footer"><small>Generated on Mon May 30 2011 22:00:00 for yaml by&nbsp;
+<a href="http://www.doxygen.org/index.html">
+<img class="footer" src="doxygen.png" alt="doxygen"/></a> 1.7.1 </small></address>
+</body>
+</html>
diff --git a/contrib/libyaml/doc/html/functions_0x68.html b/contrib/libyaml/doc/html/functions_0x68.html
new file mode 100644
index 0000000..5283c33
--- /dev/null
+++ b/contrib/libyaml/doc/html/functions_0x68.html
@@ -0,0 +1,80 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head>
+<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/>
+<title>yaml: Data Fields</title>
+<link href="tabs.css" rel="stylesheet" type="text/css"/>
+<link href="doxygen.css" rel="stylesheet" type="text/css"/>
+</head>
+<body>
+<!-- Generated by Doxygen 1.7.1 -->
+<div class="navigation" id="top">
+ <div class="tabs">
+ <ul class="tablist">
+ <li><a href="index.html"><span>Main&nbsp;Page</span></a></li>
+ <li><a href="modules.html"><span>Modules</span></a></li>
+ <li class="current"><a href="annotated.html"><span>Data&nbsp;Structures</span></a></li>
+ <li><a href="files.html"><span>Files</span></a></li>
+ </ul>
+ </div>
+ <div class="tabs2">
+ <ul class="tablist">
+ <li><a href="annotated.html"><span>Data&nbsp;Structures</span></a></li>
+ <li class="current"><a href="functions.html"><span>Data&nbsp;Fields</span></a></li>
+ </ul>
+ </div>
+ <div class="tabs2">
+ <ul class="tablist">
+ <li class="current"><a href="functions.html"><span>All</span></a></li>
+ <li><a href="functions_vars.html"><span>Variables</span></a></li>
+ </ul>
+ </div>
+ <div class="tabs3">
+ <ul class="tablist">
+ <li><a href="functions.html#index_a"><span>a</span></a></li>
+ <li><a href="functions_0x62.html#index_b"><span>b</span></a></li>
+ <li><a href="functions_0x63.html#index_c"><span>c</span></a></li>
+ <li><a href="functions_0x64.html#index_d"><span>d</span></a></li>
+ <li><a href="functions_0x65.html#index_e"><span>e</span></a></li>
+ <li><a href="functions_0x66.html#index_f"><span>f</span></a></li>
+ <li class="current"><a href="functions_0x68.html#index_h"><span>h</span></a></li>
+ <li><a href="functions_0x69.html#index_i"><span>i</span></a></li>
+ <li><a href="functions_0x6b.html#index_k"><span>k</span></a></li>
+ <li><a href="functions_0x6c.html#index_l"><span>l</span></a></li>
+ <li><a href="functions_0x6d.html#index_m"><span>m</span></a></li>
+ <li><a href="functions_0x6e.html#index_n"><span>n</span></a></li>
+ <li><a href="functions_0x6f.html#index_o"><span>o</span></a></li>
+ <li><a href="functions_0x70.html#index_p"><span>p</span></a></li>
+ <li><a href="functions_0x71.html#index_q"><span>q</span></a></li>
+ <li><a href="functions_0x72.html#index_r"><span>r</span></a></li>
+ <li><a href="functions_0x73.html#index_s"><span>s</span></a></li>
+ <li><a href="functions_0x74.html#index_t"><span>t</span></a></li>
+ <li><a href="functions_0x75.html#index_u"><span>u</span></a></li>
+ <li><a href="functions_0x76.html#index_v"><span>v</span></a></li>
+ <li><a href="functions_0x77.html#index_w"><span>w</span></a></li>
+ </ul>
+ </div>
+</div>
+<div class="contents">
+Here is a list of all documented struct and union fields with links to the struct/union documentation for each field:
+
+<h3><a class="anchor" id="index_h"></a>- h -</h3><ul>
+<li>handle
+: <a class="el" href="structyaml__tag__directive__s.html#a9934c62f2b18fd087a95af25c7739490">yaml_tag_directive_s</a>
+, <a class="el" href="structyaml__token__s.html#a01665687653c945a6666dd9debaecd65">yaml_token_s</a>
+, <a class="el" href="structyaml__emitter__s.html#a7f043a9092eef2d644cc8f1180386239">yaml_emitter_s</a>
+</li>
+<li>handle_length
+: <a class="el" href="structyaml__emitter__s.html#a3552cece6908f99518205e8cbe2c793a">yaml_emitter_s</a>
+</li>
+<li>head
+: <a class="el" href="structyaml__parser__s.html#aa1c7a1248ca22159a3e60ba45b386507">yaml_parser_s</a>
+, <a class="el" href="structyaml__emitter__s.html#a547dfd20576006e606ffb0d8042b4234">yaml_emitter_s</a>
+</li>
+</ul>
+</div>
+<hr class="footer"/><address class="footer"><small>Generated on Mon May 30 2011 22:00:00 for yaml by&nbsp;
+<a href="http://www.doxygen.org/index.html">
+<img class="footer" src="doxygen.png" alt="doxygen"/></a> 1.7.1 </small></address>
+</body>
+</html>
diff --git a/contrib/libyaml/doc/html/functions_0x69.html b/contrib/libyaml/doc/html/functions_0x69.html
new file mode 100644
index 0000000..1900c9c
--- /dev/null
+++ b/contrib/libyaml/doc/html/functions_0x69.html
@@ -0,0 +1,92 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head>
+<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/>
+<title>yaml: Data Fields</title>
+<link href="tabs.css" rel="stylesheet" type="text/css"/>
+<link href="doxygen.css" rel="stylesheet" type="text/css"/>
+</head>
+<body>
+<!-- Generated by Doxygen 1.7.1 -->
+<div class="navigation" id="top">
+ <div class="tabs">
+ <ul class="tablist">
+ <li><a href="index.html"><span>Main&nbsp;Page</span></a></li>
+ <li><a href="modules.html"><span>Modules</span></a></li>
+ <li class="current"><a href="annotated.html"><span>Data&nbsp;Structures</span></a></li>
+ <li><a href="files.html"><span>Files</span></a></li>
+ </ul>
+ </div>
+ <div class="tabs2">
+ <ul class="tablist">
+ <li><a href="annotated.html"><span>Data&nbsp;Structures</span></a></li>
+ <li class="current"><a href="functions.html"><span>Data&nbsp;Fields</span></a></li>
+ </ul>
+ </div>
+ <div class="tabs2">
+ <ul class="tablist">
+ <li class="current"><a href="functions.html"><span>All</span></a></li>
+ <li><a href="functions_vars.html"><span>Variables</span></a></li>
+ </ul>
+ </div>
+ <div class="tabs3">
+ <ul class="tablist">
+ <li><a href="functions.html#index_a"><span>a</span></a></li>
+ <li><a href="functions_0x62.html#index_b"><span>b</span></a></li>
+ <li><a href="functions_0x63.html#index_c"><span>c</span></a></li>
+ <li><a href="functions_0x64.html#index_d"><span>d</span></a></li>
+ <li><a href="functions_0x65.html#index_e"><span>e</span></a></li>
+ <li><a href="functions_0x66.html#index_f"><span>f</span></a></li>
+ <li><a href="functions_0x68.html#index_h"><span>h</span></a></li>
+ <li class="current"><a href="functions_0x69.html#index_i"><span>i</span></a></li>
+ <li><a href="functions_0x6b.html#index_k"><span>k</span></a></li>
+ <li><a href="functions_0x6c.html#index_l"><span>l</span></a></li>
+ <li><a href="functions_0x6d.html#index_m"><span>m</span></a></li>
+ <li><a href="functions_0x6e.html#index_n"><span>n</span></a></li>
+ <li><a href="functions_0x6f.html#index_o"><span>o</span></a></li>
+ <li><a href="functions_0x70.html#index_p"><span>p</span></a></li>
+ <li><a href="functions_0x71.html#index_q"><span>q</span></a></li>
+ <li><a href="functions_0x72.html#index_r"><span>r</span></a></li>
+ <li><a href="functions_0x73.html#index_s"><span>s</span></a></li>
+ <li><a href="functions_0x74.html#index_t"><span>t</span></a></li>
+ <li><a href="functions_0x75.html#index_u"><span>u</span></a></li>
+ <li><a href="functions_0x76.html#index_v"><span>v</span></a></li>
+ <li><a href="functions_0x77.html#index_w"><span>w</span></a></li>
+ </ul>
+ </div>
+</div>
+<div class="contents">
+Here is a list of all documented struct and union fields with links to the struct/union documentation for each field:
+
+<h3><a class="anchor" id="index_i"></a>- i -</h3><ul>
+<li>implicit
+: <a class="el" href="structyaml__event__s.html#a3cbb10e276d55890ee2fa802dd6290e1">yaml_event_s</a>
+</li>
+<li>indent
+: <a class="el" href="structyaml__parser__s.html#abad00703b649df32ee0d7b00b2f10403">yaml_parser_s</a>
+, <a class="el" href="structyaml__emitter__s.html#a93a73494a5d62464a67cc71f86ad9728">yaml_emitter_s</a>
+</li>
+<li>indention
+: <a class="el" href="structyaml__emitter__s.html#a407de8ff950b16b4254a381d4e5cea42">yaml_emitter_s</a>
+</li>
+<li>indents
+: <a class="el" href="structyaml__parser__s.html#a2e29feac36a89f644d9640d44df62b74">yaml_parser_s</a>
+, <a class="el" href="structyaml__emitter__s.html#ad31c591593ccb78e6b04887bf4f162c8">yaml_emitter_s</a>
+</li>
+<li>index
+: <a class="el" href="structyaml__mark__s.html#a525306fb424a79f0b0d5a7d3990aa596">yaml_mark_s</a>
+, <a class="el" href="structyaml__alias__data__s.html#ac45e17508386dec9163b4aa5cfb5312e">yaml_alias_data_s</a>
+</li>
+<li>input
+: <a class="el" href="structyaml__parser__s.html#ae800ef7fd42ad8bcbb69b116da3a7f53">yaml_parser_s</a>
+</li>
+<li>items
+: <a class="el" href="structyaml__node__s.html#a6b340541cc012ac5aacdcaa46ced097a">yaml_node_s</a>
+</li>
+</ul>
+</div>
+<hr class="footer"/><address class="footer"><small>Generated on Mon May 30 2011 22:00:00 for yaml by&nbsp;
+<a href="http://www.doxygen.org/index.html">
+<img class="footer" src="doxygen.png" alt="doxygen"/></a> 1.7.1 </small></address>
+</body>
+</html>
diff --git a/contrib/libyaml/doc/html/functions_0x6b.html b/contrib/libyaml/doc/html/functions_0x6b.html
new file mode 100644
index 0000000..c9aaa19
--- /dev/null
+++ b/contrib/libyaml/doc/html/functions_0x6b.html
@@ -0,0 +1,71 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head>
+<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/>
+<title>yaml: Data Fields</title>
+<link href="tabs.css" rel="stylesheet" type="text/css"/>
+<link href="doxygen.css" rel="stylesheet" type="text/css"/>
+</head>
+<body>
+<!-- Generated by Doxygen 1.7.1 -->
+<div class="navigation" id="top">
+ <div class="tabs">
+ <ul class="tablist">
+ <li><a href="index.html"><span>Main&nbsp;Page</span></a></li>
+ <li><a href="modules.html"><span>Modules</span></a></li>
+ <li class="current"><a href="annotated.html"><span>Data&nbsp;Structures</span></a></li>
+ <li><a href="files.html"><span>Files</span></a></li>
+ </ul>
+ </div>
+ <div class="tabs2">
+ <ul class="tablist">
+ <li><a href="annotated.html"><span>Data&nbsp;Structures</span></a></li>
+ <li class="current"><a href="functions.html"><span>Data&nbsp;Fields</span></a></li>
+ </ul>
+ </div>
+ <div class="tabs2">
+ <ul class="tablist">
+ <li class="current"><a href="functions.html"><span>All</span></a></li>
+ <li><a href="functions_vars.html"><span>Variables</span></a></li>
+ </ul>
+ </div>
+ <div class="tabs3">
+ <ul class="tablist">
+ <li><a href="functions.html#index_a"><span>a</span></a></li>
+ <li><a href="functions_0x62.html#index_b"><span>b</span></a></li>
+ <li><a href="functions_0x63.html#index_c"><span>c</span></a></li>
+ <li><a href="functions_0x64.html#index_d"><span>d</span></a></li>
+ <li><a href="functions_0x65.html#index_e"><span>e</span></a></li>
+ <li><a href="functions_0x66.html#index_f"><span>f</span></a></li>
+ <li><a href="functions_0x68.html#index_h"><span>h</span></a></li>
+ <li><a href="functions_0x69.html#index_i"><span>i</span></a></li>
+ <li class="current"><a href="functions_0x6b.html#index_k"><span>k</span></a></li>
+ <li><a href="functions_0x6c.html#index_l"><span>l</span></a></li>
+ <li><a href="functions_0x6d.html#index_m"><span>m</span></a></li>
+ <li><a href="functions_0x6e.html#index_n"><span>n</span></a></li>
+ <li><a href="functions_0x6f.html#index_o"><span>o</span></a></li>
+ <li><a href="functions_0x70.html#index_p"><span>p</span></a></li>
+ <li><a href="functions_0x71.html#index_q"><span>q</span></a></li>
+ <li><a href="functions_0x72.html#index_r"><span>r</span></a></li>
+ <li><a href="functions_0x73.html#index_s"><span>s</span></a></li>
+ <li><a href="functions_0x74.html#index_t"><span>t</span></a></li>
+ <li><a href="functions_0x75.html#index_u"><span>u</span></a></li>
+ <li><a href="functions_0x76.html#index_v"><span>v</span></a></li>
+ <li><a href="functions_0x77.html#index_w"><span>w</span></a></li>
+ </ul>
+ </div>
+</div>
+<div class="contents">
+Here is a list of all documented struct and union fields with links to the struct/union documentation for each field:
+
+<h3><a class="anchor" id="index_k"></a>- k -</h3><ul>
+<li>key
+: <a class="el" href="structyaml__node__pair__s.html#ac83746eb40b6b3a84f6da3143658ed4e">yaml_node_pair_s</a>
+</li>
+</ul>
+</div>
+<hr class="footer"/><address class="footer"><small>Generated on Mon May 30 2011 22:00:00 for yaml by&nbsp;
+<a href="http://www.doxygen.org/index.html">
+<img class="footer" src="doxygen.png" alt="doxygen"/></a> 1.7.1 </small></address>
+</body>
+</html>
diff --git a/contrib/libyaml/doc/html/functions_0x6c.html b/contrib/libyaml/doc/html/functions_0x6c.html
new file mode 100644
index 0000000..539a4d2
--- /dev/null
+++ b/contrib/libyaml/doc/html/functions_0x6c.html
@@ -0,0 +1,88 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head>
+<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/>
+<title>yaml: Data Fields</title>
+<link href="tabs.css" rel="stylesheet" type="text/css"/>
+<link href="doxygen.css" rel="stylesheet" type="text/css"/>
+</head>
+<body>
+<!-- Generated by Doxygen 1.7.1 -->
+<div class="navigation" id="top">
+ <div class="tabs">
+ <ul class="tablist">
+ <li><a href="index.html"><span>Main&nbsp;Page</span></a></li>
+ <li><a href="modules.html"><span>Modules</span></a></li>
+ <li class="current"><a href="annotated.html"><span>Data&nbsp;Structures</span></a></li>
+ <li><a href="files.html"><span>Files</span></a></li>
+ </ul>
+ </div>
+ <div class="tabs2">
+ <ul class="tablist">
+ <li><a href="annotated.html"><span>Data&nbsp;Structures</span></a></li>
+ <li class="current"><a href="functions.html"><span>Data&nbsp;Fields</span></a></li>
+ </ul>
+ </div>
+ <div class="tabs2">
+ <ul class="tablist">
+ <li class="current"><a href="functions.html"><span>All</span></a></li>
+ <li><a href="functions_vars.html"><span>Variables</span></a></li>
+ </ul>
+ </div>
+ <div class="tabs3">
+ <ul class="tablist">
+ <li><a href="functions.html#index_a"><span>a</span></a></li>
+ <li><a href="functions_0x62.html#index_b"><span>b</span></a></li>
+ <li><a href="functions_0x63.html#index_c"><span>c</span></a></li>
+ <li><a href="functions_0x64.html#index_d"><span>d</span></a></li>
+ <li><a href="functions_0x65.html#index_e"><span>e</span></a></li>
+ <li><a href="functions_0x66.html#index_f"><span>f</span></a></li>
+ <li><a href="functions_0x68.html#index_h"><span>h</span></a></li>
+ <li><a href="functions_0x69.html#index_i"><span>i</span></a></li>
+ <li><a href="functions_0x6b.html#index_k"><span>k</span></a></li>
+ <li class="current"><a href="functions_0x6c.html#index_l"><span>l</span></a></li>
+ <li><a href="functions_0x6d.html#index_m"><span>m</span></a></li>
+ <li><a href="functions_0x6e.html#index_n"><span>n</span></a></li>
+ <li><a href="functions_0x6f.html#index_o"><span>o</span></a></li>
+ <li><a href="functions_0x70.html#index_p"><span>p</span></a></li>
+ <li><a href="functions_0x71.html#index_q"><span>q</span></a></li>
+ <li><a href="functions_0x72.html#index_r"><span>r</span></a></li>
+ <li><a href="functions_0x73.html#index_s"><span>s</span></a></li>
+ <li><a href="functions_0x74.html#index_t"><span>t</span></a></li>
+ <li><a href="functions_0x75.html#index_u"><span>u</span></a></li>
+ <li><a href="functions_0x76.html#index_v"><span>v</span></a></li>
+ <li><a href="functions_0x77.html#index_w"><span>w</span></a></li>
+ </ul>
+ </div>
+</div>
+<div class="contents">
+Here is a list of all documented struct and union fields with links to the struct/union documentation for each field:
+
+<h3><a class="anchor" id="index_l"></a>- l -</h3><ul>
+<li>last
+: <a class="el" href="structyaml__parser__s.html#aea4d8da24939825b2fadd368a71ec7de">yaml_parser_s</a>
+, <a class="el" href="structyaml__emitter__s.html#ad0c5410fff4602266a0c6e0af730dd70">yaml_emitter_s</a>
+</li>
+<li>last_anchor_id
+: <a class="el" href="structyaml__emitter__s.html#a0cede830c77a15df7f1b73b9023d2d11">yaml_emitter_s</a>
+</li>
+<li>length
+: <a class="el" href="structyaml__emitter__s.html#a4f72d57ad020803803e78922ecdec580">yaml_emitter_s</a>
+, <a class="el" href="structyaml__event__s.html#a15618ee917746d28d97ad8eb9639e141">yaml_event_s</a>
+, <a class="el" href="structyaml__node__s.html#ad90dd9926d9debbaa48eb5339bd9fc36">yaml_node_s</a>
+, <a class="el" href="structyaml__token__s.html#a06e51daf74cf78103e00608c3c9132e2">yaml_token_s</a>
+</li>
+<li>line
+: <a class="el" href="structyaml__mark__s.html#a55952e426fc8a5f180a5e9c907ca926c">yaml_mark_s</a>
+, <a class="el" href="structyaml__emitter__s.html#a4fe9295608f19a687e41ec3661383e88">yaml_emitter_s</a>
+</li>
+<li>line_break
+: <a class="el" href="structyaml__emitter__s.html#a84c1b884d805588495067ee98a8e7c50">yaml_emitter_s</a>
+</li>
+</ul>
+</div>
+<hr class="footer"/><address class="footer"><small>Generated on Mon May 30 2011 22:00:00 for yaml by&nbsp;
+<a href="http://www.doxygen.org/index.html">
+<img class="footer" src="doxygen.png" alt="doxygen"/></a> 1.7.1 </small></address>
+</body>
+</html>
diff --git a/contrib/libyaml/doc/html/functions_0x6d.html b/contrib/libyaml/doc/html/functions_0x6d.html
new file mode 100644
index 0000000..858ec44
--- /dev/null
+++ b/contrib/libyaml/doc/html/functions_0x6d.html
@@ -0,0 +1,96 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head>
+<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/>
+<title>yaml: Data Fields</title>
+<link href="tabs.css" rel="stylesheet" type="text/css"/>
+<link href="doxygen.css" rel="stylesheet" type="text/css"/>
+</head>
+<body>
+<!-- Generated by Doxygen 1.7.1 -->
+<div class="navigation" id="top">
+ <div class="tabs">
+ <ul class="tablist">
+ <li><a href="index.html"><span>Main&nbsp;Page</span></a></li>
+ <li><a href="modules.html"><span>Modules</span></a></li>
+ <li class="current"><a href="annotated.html"><span>Data&nbsp;Structures</span></a></li>
+ <li><a href="files.html"><span>Files</span></a></li>
+ </ul>
+ </div>
+ <div class="tabs2">
+ <ul class="tablist">
+ <li><a href="annotated.html"><span>Data&nbsp;Structures</span></a></li>
+ <li class="current"><a href="functions.html"><span>Data&nbsp;Fields</span></a></li>
+ </ul>
+ </div>
+ <div class="tabs2">
+ <ul class="tablist">
+ <li class="current"><a href="functions.html"><span>All</span></a></li>
+ <li><a href="functions_vars.html"><span>Variables</span></a></li>
+ </ul>
+ </div>
+ <div class="tabs3">
+ <ul class="tablist">
+ <li><a href="functions.html#index_a"><span>a</span></a></li>
+ <li><a href="functions_0x62.html#index_b"><span>b</span></a></li>
+ <li><a href="functions_0x63.html#index_c"><span>c</span></a></li>
+ <li><a href="functions_0x64.html#index_d"><span>d</span></a></li>
+ <li><a href="functions_0x65.html#index_e"><span>e</span></a></li>
+ <li><a href="functions_0x66.html#index_f"><span>f</span></a></li>
+ <li><a href="functions_0x68.html#index_h"><span>h</span></a></li>
+ <li><a href="functions_0x69.html#index_i"><span>i</span></a></li>
+ <li><a href="functions_0x6b.html#index_k"><span>k</span></a></li>
+ <li><a href="functions_0x6c.html#index_l"><span>l</span></a></li>
+ <li class="current"><a href="functions_0x6d.html#index_m"><span>m</span></a></li>
+ <li><a href="functions_0x6e.html#index_n"><span>n</span></a></li>
+ <li><a href="functions_0x6f.html#index_o"><span>o</span></a></li>
+ <li><a href="functions_0x70.html#index_p"><span>p</span></a></li>
+ <li><a href="functions_0x71.html#index_q"><span>q</span></a></li>
+ <li><a href="functions_0x72.html#index_r"><span>r</span></a></li>
+ <li><a href="functions_0x73.html#index_s"><span>s</span></a></li>
+ <li><a href="functions_0x74.html#index_t"><span>t</span></a></li>
+ <li><a href="functions_0x75.html#index_u"><span>u</span></a></li>
+ <li><a href="functions_0x76.html#index_v"><span>v</span></a></li>
+ <li><a href="functions_0x77.html#index_w"><span>w</span></a></li>
+ </ul>
+ </div>
+</div>
+<div class="contents">
+Here is a list of all documented struct and union fields with links to the struct/union documentation for each field:
+
+<h3><a class="anchor" id="index_m"></a>- m -</h3><ul>
+<li>major
+: <a class="el" href="structyaml__version__directive__s.html#ad27326ff94b7772027c3009d1dd5e52b">yaml_version_directive_s</a>
+, <a class="el" href="structyaml__token__s.html#aac2ed466afd0390872774238dfcd152c">yaml_token_s</a>
+</li>
+<li>mapping
+: <a class="el" href="structyaml__node__s.html#ab18dc5c573885a08a92e113dcb7fb361">yaml_node_s</a>
+</li>
+<li>mapping_context
+: <a class="el" href="structyaml__emitter__s.html#a5a7527d8da86b28d95ff18b29f9d82f0">yaml_emitter_s</a>
+</li>
+<li>mapping_start
+: <a class="el" href="structyaml__event__s.html#a361b28413783f92797e6bfe03e9abaa1">yaml_event_s</a>
+</li>
+<li>mark
+: <a class="el" href="structyaml__parser__s.html#aaeeb58dc348e6e6f89d6a7c8fea8f734">yaml_parser_s</a>
+, <a class="el" href="structyaml__alias__data__s.html#a9f8d87255bfc39df69068ed87b602e9f">yaml_alias_data_s</a>
+, <a class="el" href="structyaml__simple__key__s.html#ad0f5dd11cbf2e4d6d81376511e2b6dfb">yaml_simple_key_s</a>
+</li>
+<li>marks
+: <a class="el" href="structyaml__parser__s.html#ad78837ae36e35d523e02c43d1ae3f30e">yaml_parser_s</a>
+</li>
+<li>minor
+: <a class="el" href="structyaml__version__directive__s.html#a89f074113501e6e150503f34b046dbd1">yaml_version_directive_s</a>
+, <a class="el" href="structyaml__token__s.html#a97b9f537b24e8413e9fddc6a4b183d30">yaml_token_s</a>
+</li>
+<li>multiline
+: <a class="el" href="structyaml__emitter__s.html#a363a1aaaf512433ee7eab3083428cc70">yaml_emitter_s</a>
+</li>
+</ul>
+</div>
+<hr class="footer"/><address class="footer"><small>Generated on Mon May 30 2011 22:00:00 for yaml by&nbsp;
+<a href="http://www.doxygen.org/index.html">
+<img class="footer" src="doxygen.png" alt="doxygen"/></a> 1.7.1 </small></address>
+</body>
+</html>
diff --git a/contrib/libyaml/doc/html/functions_0x6e.html b/contrib/libyaml/doc/html/functions_0x6e.html
new file mode 100644
index 0000000..3c30d53
--- /dev/null
+++ b/contrib/libyaml/doc/html/functions_0x6e.html
@@ -0,0 +1,71 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head>
+<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/>
+<title>yaml: Data Fields</title>
+<link href="tabs.css" rel="stylesheet" type="text/css"/>
+<link href="doxygen.css" rel="stylesheet" type="text/css"/>
+</head>
+<body>
+<!-- Generated by Doxygen 1.7.1 -->
+<div class="navigation" id="top">
+ <div class="tabs">
+ <ul class="tablist">
+ <li><a href="index.html"><span>Main&nbsp;Page</span></a></li>
+ <li><a href="modules.html"><span>Modules</span></a></li>
+ <li class="current"><a href="annotated.html"><span>Data&nbsp;Structures</span></a></li>
+ <li><a href="files.html"><span>Files</span></a></li>
+ </ul>
+ </div>
+ <div class="tabs2">
+ <ul class="tablist">
+ <li><a href="annotated.html"><span>Data&nbsp;Structures</span></a></li>
+ <li class="current"><a href="functions.html"><span>Data&nbsp;Fields</span></a></li>
+ </ul>
+ </div>
+ <div class="tabs2">
+ <ul class="tablist">
+ <li class="current"><a href="functions.html"><span>All</span></a></li>
+ <li><a href="functions_vars.html"><span>Variables</span></a></li>
+ </ul>
+ </div>
+ <div class="tabs3">
+ <ul class="tablist">
+ <li><a href="functions.html#index_a"><span>a</span></a></li>
+ <li><a href="functions_0x62.html#index_b"><span>b</span></a></li>
+ <li><a href="functions_0x63.html#index_c"><span>c</span></a></li>
+ <li><a href="functions_0x64.html#index_d"><span>d</span></a></li>
+ <li><a href="functions_0x65.html#index_e"><span>e</span></a></li>
+ <li><a href="functions_0x66.html#index_f"><span>f</span></a></li>
+ <li><a href="functions_0x68.html#index_h"><span>h</span></a></li>
+ <li><a href="functions_0x69.html#index_i"><span>i</span></a></li>
+ <li><a href="functions_0x6b.html#index_k"><span>k</span></a></li>
+ <li><a href="functions_0x6c.html#index_l"><span>l</span></a></li>
+ <li><a href="functions_0x6d.html#index_m"><span>m</span></a></li>
+ <li class="current"><a href="functions_0x6e.html#index_n"><span>n</span></a></li>
+ <li><a href="functions_0x6f.html#index_o"><span>o</span></a></li>
+ <li><a href="functions_0x70.html#index_p"><span>p</span></a></li>
+ <li><a href="functions_0x71.html#index_q"><span>q</span></a></li>
+ <li><a href="functions_0x72.html#index_r"><span>r</span></a></li>
+ <li><a href="functions_0x73.html#index_s"><span>s</span></a></li>
+ <li><a href="functions_0x74.html#index_t"><span>t</span></a></li>
+ <li><a href="functions_0x75.html#index_u"><span>u</span></a></li>
+ <li><a href="functions_0x76.html#index_v"><span>v</span></a></li>
+ <li><a href="functions_0x77.html#index_w"><span>w</span></a></li>
+ </ul>
+ </div>
+</div>
+<div class="contents">
+Here is a list of all documented struct and union fields with links to the struct/union documentation for each field:
+
+<h3><a class="anchor" id="index_n"></a>- n -</h3><ul>
+<li>nodes
+: <a class="el" href="structyaml__document__s.html#aa9eeab76b69cc84a6ab1b02c14cfd594">yaml_document_s</a>
+</li>
+</ul>
+</div>
+<hr class="footer"/><address class="footer"><small>Generated on Mon May 30 2011 22:00:00 for yaml by&nbsp;
+<a href="http://www.doxygen.org/index.html">
+<img class="footer" src="doxygen.png" alt="doxygen"/></a> 1.7.1 </small></address>
+</body>
+</html>
diff --git a/contrib/libyaml/doc/html/functions_0x6f.html b/contrib/libyaml/doc/html/functions_0x6f.html
new file mode 100644
index 0000000..da9d901
--- /dev/null
+++ b/contrib/libyaml/doc/html/functions_0x6f.html
@@ -0,0 +1,80 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head>
+<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/>
+<title>yaml: Data Fields</title>
+<link href="tabs.css" rel="stylesheet" type="text/css"/>
+<link href="doxygen.css" rel="stylesheet" type="text/css"/>
+</head>
+<body>
+<!-- Generated by Doxygen 1.7.1 -->
+<div class="navigation" id="top">
+ <div class="tabs">
+ <ul class="tablist">
+ <li><a href="index.html"><span>Main&nbsp;Page</span></a></li>
+ <li><a href="modules.html"><span>Modules</span></a></li>
+ <li class="current"><a href="annotated.html"><span>Data&nbsp;Structures</span></a></li>
+ <li><a href="files.html"><span>Files</span></a></li>
+ </ul>
+ </div>
+ <div class="tabs2">
+ <ul class="tablist">
+ <li><a href="annotated.html"><span>Data&nbsp;Structures</span></a></li>
+ <li class="current"><a href="functions.html"><span>Data&nbsp;Fields</span></a></li>
+ </ul>
+ </div>
+ <div class="tabs2">
+ <ul class="tablist">
+ <li class="current"><a href="functions.html"><span>All</span></a></li>
+ <li><a href="functions_vars.html"><span>Variables</span></a></li>
+ </ul>
+ </div>
+ <div class="tabs3">
+ <ul class="tablist">
+ <li><a href="functions.html#index_a"><span>a</span></a></li>
+ <li><a href="functions_0x62.html#index_b"><span>b</span></a></li>
+ <li><a href="functions_0x63.html#index_c"><span>c</span></a></li>
+ <li><a href="functions_0x64.html#index_d"><span>d</span></a></li>
+ <li><a href="functions_0x65.html#index_e"><span>e</span></a></li>
+ <li><a href="functions_0x66.html#index_f"><span>f</span></a></li>
+ <li><a href="functions_0x68.html#index_h"><span>h</span></a></li>
+ <li><a href="functions_0x69.html#index_i"><span>i</span></a></li>
+ <li><a href="functions_0x6b.html#index_k"><span>k</span></a></li>
+ <li><a href="functions_0x6c.html#index_l"><span>l</span></a></li>
+ <li><a href="functions_0x6d.html#index_m"><span>m</span></a></li>
+ <li><a href="functions_0x6e.html#index_n"><span>n</span></a></li>
+ <li class="current"><a href="functions_0x6f.html#index_o"><span>o</span></a></li>
+ <li><a href="functions_0x70.html#index_p"><span>p</span></a></li>
+ <li><a href="functions_0x71.html#index_q"><span>q</span></a></li>
+ <li><a href="functions_0x72.html#index_r"><span>r</span></a></li>
+ <li><a href="functions_0x73.html#index_s"><span>s</span></a></li>
+ <li><a href="functions_0x74.html#index_t"><span>t</span></a></li>
+ <li><a href="functions_0x75.html#index_u"><span>u</span></a></li>
+ <li><a href="functions_0x76.html#index_v"><span>v</span></a></li>
+ <li><a href="functions_0x77.html#index_w"><span>w</span></a></li>
+ </ul>
+ </div>
+</div>
+<div class="contents">
+Here is a list of all documented struct and union fields with links to the struct/union documentation for each field:
+
+<h3><a class="anchor" id="index_o"></a>- o -</h3><ul>
+<li>offset
+: <a class="el" href="structyaml__parser__s.html#a04a7ba684ce49b2300c236c561439b13">yaml_parser_s</a>
+</li>
+<li>open_ended
+: <a class="el" href="structyaml__emitter__s.html#a65e84454b702622c41a068768c144c51">yaml_emitter_s</a>
+</li>
+<li>opened
+: <a class="el" href="structyaml__emitter__s.html#a0234d7e9bfbe7cc6e12b60f90f5ec552">yaml_emitter_s</a>
+</li>
+<li>output
+: <a class="el" href="structyaml__emitter__s.html#aa975acf559cc87d79abdb732c994f56f">yaml_emitter_s</a>
+</li>
+</ul>
+</div>
+<hr class="footer"/><address class="footer"><small>Generated on Mon May 30 2011 22:00:00 for yaml by&nbsp;
+<a href="http://www.doxygen.org/index.html">
+<img class="footer" src="doxygen.png" alt="doxygen"/></a> 1.7.1 </small></address>
+</body>
+</html>
diff --git a/contrib/libyaml/doc/html/functions_0x70.html b/contrib/libyaml/doc/html/functions_0x70.html
new file mode 100644
index 0000000..531cfe6
--- /dev/null
+++ b/contrib/libyaml/doc/html/functions_0x70.html
@@ -0,0 +1,100 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head>
+<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/>
+<title>yaml: Data Fields</title>
+<link href="tabs.css" rel="stylesheet" type="text/css"/>
+<link href="doxygen.css" rel="stylesheet" type="text/css"/>
+</head>
+<body>
+<!-- Generated by Doxygen 1.7.1 -->
+<div class="navigation" id="top">
+ <div class="tabs">
+ <ul class="tablist">
+ <li><a href="index.html"><span>Main&nbsp;Page</span></a></li>
+ <li><a href="modules.html"><span>Modules</span></a></li>
+ <li class="current"><a href="annotated.html"><span>Data&nbsp;Structures</span></a></li>
+ <li><a href="files.html"><span>Files</span></a></li>
+ </ul>
+ </div>
+ <div class="tabs2">
+ <ul class="tablist">
+ <li><a href="annotated.html"><span>Data&nbsp;Structures</span></a></li>
+ <li class="current"><a href="functions.html"><span>Data&nbsp;Fields</span></a></li>
+ </ul>
+ </div>
+ <div class="tabs2">
+ <ul class="tablist">
+ <li class="current"><a href="functions.html"><span>All</span></a></li>
+ <li><a href="functions_vars.html"><span>Variables</span></a></li>
+ </ul>
+ </div>
+ <div class="tabs3">
+ <ul class="tablist">
+ <li><a href="functions.html#index_a"><span>a</span></a></li>
+ <li><a href="functions_0x62.html#index_b"><span>b</span></a></li>
+ <li><a href="functions_0x63.html#index_c"><span>c</span></a></li>
+ <li><a href="functions_0x64.html#index_d"><span>d</span></a></li>
+ <li><a href="functions_0x65.html#index_e"><span>e</span></a></li>
+ <li><a href="functions_0x66.html#index_f"><span>f</span></a></li>
+ <li><a href="functions_0x68.html#index_h"><span>h</span></a></li>
+ <li><a href="functions_0x69.html#index_i"><span>i</span></a></li>
+ <li><a href="functions_0x6b.html#index_k"><span>k</span></a></li>
+ <li><a href="functions_0x6c.html#index_l"><span>l</span></a></li>
+ <li><a href="functions_0x6d.html#index_m"><span>m</span></a></li>
+ <li><a href="functions_0x6e.html#index_n"><span>n</span></a></li>
+ <li><a href="functions_0x6f.html#index_o"><span>o</span></a></li>
+ <li class="current"><a href="functions_0x70.html#index_p"><span>p</span></a></li>
+ <li><a href="functions_0x71.html#index_q"><span>q</span></a></li>
+ <li><a href="functions_0x72.html#index_r"><span>r</span></a></li>
+ <li><a href="functions_0x73.html#index_s"><span>s</span></a></li>
+ <li><a href="functions_0x74.html#index_t"><span>t</span></a></li>
+ <li><a href="functions_0x75.html#index_u"><span>u</span></a></li>
+ <li><a href="functions_0x76.html#index_v"><span>v</span></a></li>
+ <li><a href="functions_0x77.html#index_w"><span>w</span></a></li>
+ </ul>
+ </div>
+</div>
+<div class="contents">
+Here is a list of all documented struct and union fields with links to the struct/union documentation for each field:
+
+<h3><a class="anchor" id="index_p"></a>- p -</h3><ul>
+<li>pairs
+: <a class="el" href="structyaml__node__s.html#a830a080bbed021eb230ef644e4680909">yaml_node_s</a>
+</li>
+<li>plain_implicit
+: <a class="el" href="structyaml__event__s.html#ac3600acbcc6b4787f1ec3511976a3151">yaml_event_s</a>
+</li>
+<li>pointer
+: <a class="el" href="structyaml__parser__s.html#abea626790abfbcaeeb72a3772dc69e43">yaml_parser_s</a>
+, <a class="el" href="structyaml__emitter__s.html#a7615ab51145234f467984f3091558852">yaml_emitter_s</a>
+, <a class="el" href="structyaml__parser__s.html#a8199466e3578374b3f984b6c0c4e2ae4">yaml_parser_s</a>
+, <a class="el" href="structyaml__emitter__s.html#aed9370f42cea4dff82f96839ce760b5a">yaml_emitter_s</a>
+</li>
+<li>possible
+: <a class="el" href="structyaml__simple__key__s.html#aad311b0fa599db04657a5177ec331f07">yaml_simple_key_s</a>
+</li>
+<li>prefix
+: <a class="el" href="structyaml__tag__directive__s.html#a514850fefaafbe65b2322da8c193a896">yaml_tag_directive_s</a>
+, <a class="el" href="structyaml__token__s.html#a561b3730b9999cfe1010e77aca49c5b8">yaml_token_s</a>
+</li>
+<li>problem
+: <a class="el" href="structyaml__parser__s.html#a3dd8a43294cd420a433595a7a7d6e73d">yaml_parser_s</a>
+, <a class="el" href="structyaml__emitter__s.html#ae076ef7c85ae107a2233dd4206577800">yaml_emitter_s</a>
+</li>
+<li>problem_mark
+: <a class="el" href="structyaml__parser__s.html#a595b5412d39a4a9e441e5ad34fb059d9">yaml_parser_s</a>
+</li>
+<li>problem_offset
+: <a class="el" href="structyaml__parser__s.html#ae2d62a2ad45671c6dd89e18fb7c1c5bd">yaml_parser_s</a>
+</li>
+<li>problem_value
+: <a class="el" href="structyaml__parser__s.html#a8694691b20824f6595873b728cb3bc0f">yaml_parser_s</a>
+</li>
+</ul>
+</div>
+<hr class="footer"/><address class="footer"><small>Generated on Mon May 30 2011 22:00:00 for yaml by&nbsp;
+<a href="http://www.doxygen.org/index.html">
+<img class="footer" src="doxygen.png" alt="doxygen"/></a> 1.7.1 </small></address>
+</body>
+</html>
diff --git a/contrib/libyaml/doc/html/functions_0x71.html b/contrib/libyaml/doc/html/functions_0x71.html
new file mode 100644
index 0000000..6cd72b7
--- /dev/null
+++ b/contrib/libyaml/doc/html/functions_0x71.html
@@ -0,0 +1,71 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head>
+<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/>
+<title>yaml: Data Fields</title>
+<link href="tabs.css" rel="stylesheet" type="text/css"/>
+<link href="doxygen.css" rel="stylesheet" type="text/css"/>
+</head>
+<body>
+<!-- Generated by Doxygen 1.7.1 -->
+<div class="navigation" id="top">
+ <div class="tabs">
+ <ul class="tablist">
+ <li><a href="index.html"><span>Main&nbsp;Page</span></a></li>
+ <li><a href="modules.html"><span>Modules</span></a></li>
+ <li class="current"><a href="annotated.html"><span>Data&nbsp;Structures</span></a></li>
+ <li><a href="files.html"><span>Files</span></a></li>
+ </ul>
+ </div>
+ <div class="tabs2">
+ <ul class="tablist">
+ <li><a href="annotated.html"><span>Data&nbsp;Structures</span></a></li>
+ <li class="current"><a href="functions.html"><span>Data&nbsp;Fields</span></a></li>
+ </ul>
+ </div>
+ <div class="tabs2">
+ <ul class="tablist">
+ <li class="current"><a href="functions.html"><span>All</span></a></li>
+ <li><a href="functions_vars.html"><span>Variables</span></a></li>
+ </ul>
+ </div>
+ <div class="tabs3">
+ <ul class="tablist">
+ <li><a href="functions.html#index_a"><span>a</span></a></li>
+ <li><a href="functions_0x62.html#index_b"><span>b</span></a></li>
+ <li><a href="functions_0x63.html#index_c"><span>c</span></a></li>
+ <li><a href="functions_0x64.html#index_d"><span>d</span></a></li>
+ <li><a href="functions_0x65.html#index_e"><span>e</span></a></li>
+ <li><a href="functions_0x66.html#index_f"><span>f</span></a></li>
+ <li><a href="functions_0x68.html#index_h"><span>h</span></a></li>
+ <li><a href="functions_0x69.html#index_i"><span>i</span></a></li>
+ <li><a href="functions_0x6b.html#index_k"><span>k</span></a></li>
+ <li><a href="functions_0x6c.html#index_l"><span>l</span></a></li>
+ <li><a href="functions_0x6d.html#index_m"><span>m</span></a></li>
+ <li><a href="functions_0x6e.html#index_n"><span>n</span></a></li>
+ <li><a href="functions_0x6f.html#index_o"><span>o</span></a></li>
+ <li><a href="functions_0x70.html#index_p"><span>p</span></a></li>
+ <li class="current"><a href="functions_0x71.html#index_q"><span>q</span></a></li>
+ <li><a href="functions_0x72.html#index_r"><span>r</span></a></li>
+ <li><a href="functions_0x73.html#index_s"><span>s</span></a></li>
+ <li><a href="functions_0x74.html#index_t"><span>t</span></a></li>
+ <li><a href="functions_0x75.html#index_u"><span>u</span></a></li>
+ <li><a href="functions_0x76.html#index_v"><span>v</span></a></li>
+ <li><a href="functions_0x77.html#index_w"><span>w</span></a></li>
+ </ul>
+ </div>
+</div>
+<div class="contents">
+Here is a list of all documented struct and union fields with links to the struct/union documentation for each field:
+
+<h3><a class="anchor" id="index_q"></a>- q -</h3><ul>
+<li>quoted_implicit
+: <a class="el" href="structyaml__event__s.html#a9ce2441d08d9cf6a1bf9f28f5ee17f68">yaml_event_s</a>
+</li>
+</ul>
+</div>
+<hr class="footer"/><address class="footer"><small>Generated on Mon May 30 2011 22:00:00 for yaml by&nbsp;
+<a href="http://www.doxygen.org/index.html">
+<img class="footer" src="doxygen.png" alt="doxygen"/></a> 1.7.1 </small></address>
+</body>
+</html>
diff --git a/contrib/libyaml/doc/html/functions_0x72.html b/contrib/libyaml/doc/html/functions_0x72.html
new file mode 100644
index 0000000..5409ee6
--- /dev/null
+++ b/contrib/libyaml/doc/html/functions_0x72.html
@@ -0,0 +1,87 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head>
+<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/>
+<title>yaml: Data Fields</title>
+<link href="tabs.css" rel="stylesheet" type="text/css"/>
+<link href="doxygen.css" rel="stylesheet" type="text/css"/>
+</head>
+<body>
+<!-- Generated by Doxygen 1.7.1 -->
+<div class="navigation" id="top">
+ <div class="tabs">
+ <ul class="tablist">
+ <li><a href="index.html"><span>Main&nbsp;Page</span></a></li>
+ <li><a href="modules.html"><span>Modules</span></a></li>
+ <li class="current"><a href="annotated.html"><span>Data&nbsp;Structures</span></a></li>
+ <li><a href="files.html"><span>Files</span></a></li>
+ </ul>
+ </div>
+ <div class="tabs2">
+ <ul class="tablist">
+ <li><a href="annotated.html"><span>Data&nbsp;Structures</span></a></li>
+ <li class="current"><a href="functions.html"><span>Data&nbsp;Fields</span></a></li>
+ </ul>
+ </div>
+ <div class="tabs2">
+ <ul class="tablist">
+ <li class="current"><a href="functions.html"><span>All</span></a></li>
+ <li><a href="functions_vars.html"><span>Variables</span></a></li>
+ </ul>
+ </div>
+ <div class="tabs3">
+ <ul class="tablist">
+ <li><a href="functions.html#index_a"><span>a</span></a></li>
+ <li><a href="functions_0x62.html#index_b"><span>b</span></a></li>
+ <li><a href="functions_0x63.html#index_c"><span>c</span></a></li>
+ <li><a href="functions_0x64.html#index_d"><span>d</span></a></li>
+ <li><a href="functions_0x65.html#index_e"><span>e</span></a></li>
+ <li><a href="functions_0x66.html#index_f"><span>f</span></a></li>
+ <li><a href="functions_0x68.html#index_h"><span>h</span></a></li>
+ <li><a href="functions_0x69.html#index_i"><span>i</span></a></li>
+ <li><a href="functions_0x6b.html#index_k"><span>k</span></a></li>
+ <li><a href="functions_0x6c.html#index_l"><span>l</span></a></li>
+ <li><a href="functions_0x6d.html#index_m"><span>m</span></a></li>
+ <li><a href="functions_0x6e.html#index_n"><span>n</span></a></li>
+ <li><a href="functions_0x6f.html#index_o"><span>o</span></a></li>
+ <li><a href="functions_0x70.html#index_p"><span>p</span></a></li>
+ <li><a href="functions_0x71.html#index_q"><span>q</span></a></li>
+ <li class="current"><a href="functions_0x72.html#index_r"><span>r</span></a></li>
+ <li><a href="functions_0x73.html#index_s"><span>s</span></a></li>
+ <li><a href="functions_0x74.html#index_t"><span>t</span></a></li>
+ <li><a href="functions_0x75.html#index_u"><span>u</span></a></li>
+ <li><a href="functions_0x76.html#index_v"><span>v</span></a></li>
+ <li><a href="functions_0x77.html#index_w"><span>w</span></a></li>
+ </ul>
+ </div>
+</div>
+<div class="contents">
+Here is a list of all documented struct and union fields with links to the struct/union documentation for each field:
+
+<h3><a class="anchor" id="index_r"></a>- r -</h3><ul>
+<li>raw_buffer
+: <a class="el" href="structyaml__parser__s.html#ae3e8481ceabdbf6796a7dc6265f740ac">yaml_parser_s</a>
+, <a class="el" href="structyaml__emitter__s.html#a6eeffbc9cd5beb89b679740b7f1d6d09">yaml_emitter_s</a>
+</li>
+<li>read_handler
+: <a class="el" href="structyaml__parser__s.html#a8c3af47a7a0750d437cba34699fcad30">yaml_parser_s</a>
+</li>
+<li>read_handler_data
+: <a class="el" href="structyaml__parser__s.html#a11f265cd495e814c8ee7d3dd78ff2ca9">yaml_parser_s</a>
+</li>
+<li>references
+: <a class="el" href="structyaml__emitter__s.html#a8f00c3c08e0d87bab11e91a4464a50bc">yaml_emitter_s</a>
+</li>
+<li>required
+: <a class="el" href="structyaml__simple__key__s.html#acacccea26520e74c4c61f170fdcbb4c3">yaml_simple_key_s</a>
+</li>
+<li>root_context
+: <a class="el" href="structyaml__emitter__s.html#a70fb5f09cc60de989fbec2868f4db19e">yaml_emitter_s</a>
+</li>
+</ul>
+</div>
+<hr class="footer"/><address class="footer"><small>Generated on Mon May 30 2011 22:00:00 for yaml by&nbsp;
+<a href="http://www.doxygen.org/index.html">
+<img class="footer" src="doxygen.png" alt="doxygen"/></a> 1.7.1 </small></address>
+</body>
+</html>
diff --git a/contrib/libyaml/doc/html/functions_0x73.html b/contrib/libyaml/doc/html/functions_0x73.html
new file mode 100644
index 0000000..8caa39d
--- /dev/null
+++ b/contrib/libyaml/doc/html/functions_0x73.html
@@ -0,0 +1,163 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head>
+<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/>
+<title>yaml: Data Fields</title>
+<link href="tabs.css" rel="stylesheet" type="text/css"/>
+<link href="doxygen.css" rel="stylesheet" type="text/css"/>
+</head>
+<body>
+<!-- Generated by Doxygen 1.7.1 -->
+<div class="navigation" id="top">
+ <div class="tabs">
+ <ul class="tablist">
+ <li><a href="index.html"><span>Main&nbsp;Page</span></a></li>
+ <li><a href="modules.html"><span>Modules</span></a></li>
+ <li class="current"><a href="annotated.html"><span>Data&nbsp;Structures</span></a></li>
+ <li><a href="files.html"><span>Files</span></a></li>
+ </ul>
+ </div>
+ <div class="tabs2">
+ <ul class="tablist">
+ <li><a href="annotated.html"><span>Data&nbsp;Structures</span></a></li>
+ <li class="current"><a href="functions.html"><span>Data&nbsp;Fields</span></a></li>
+ </ul>
+ </div>
+ <div class="tabs2">
+ <ul class="tablist">
+ <li class="current"><a href="functions.html"><span>All</span></a></li>
+ <li><a href="functions_vars.html"><span>Variables</span></a></li>
+ </ul>
+ </div>
+ <div class="tabs3">
+ <ul class="tablist">
+ <li><a href="functions.html#index_a"><span>a</span></a></li>
+ <li><a href="functions_0x62.html#index_b"><span>b</span></a></li>
+ <li><a href="functions_0x63.html#index_c"><span>c</span></a></li>
+ <li><a href="functions_0x64.html#index_d"><span>d</span></a></li>
+ <li><a href="functions_0x65.html#index_e"><span>e</span></a></li>
+ <li><a href="functions_0x66.html#index_f"><span>f</span></a></li>
+ <li><a href="functions_0x68.html#index_h"><span>h</span></a></li>
+ <li><a href="functions_0x69.html#index_i"><span>i</span></a></li>
+ <li><a href="functions_0x6b.html#index_k"><span>k</span></a></li>
+ <li><a href="functions_0x6c.html#index_l"><span>l</span></a></li>
+ <li><a href="functions_0x6d.html#index_m"><span>m</span></a></li>
+ <li><a href="functions_0x6e.html#index_n"><span>n</span></a></li>
+ <li><a href="functions_0x6f.html#index_o"><span>o</span></a></li>
+ <li><a href="functions_0x70.html#index_p"><span>p</span></a></li>
+ <li><a href="functions_0x71.html#index_q"><span>q</span></a></li>
+ <li><a href="functions_0x72.html#index_r"><span>r</span></a></li>
+ <li class="current"><a href="functions_0x73.html#index_s"><span>s</span></a></li>
+ <li><a href="functions_0x74.html#index_t"><span>t</span></a></li>
+ <li><a href="functions_0x75.html#index_u"><span>u</span></a></li>
+ <li><a href="functions_0x76.html#index_v"><span>v</span></a></li>
+ <li><a href="functions_0x77.html#index_w"><span>w</span></a></li>
+ </ul>
+ </div>
+</div>
+<div class="contents">
+Here is a list of all documented struct and union fields with links to the struct/union documentation for each field:
+
+<h3><a class="anchor" id="index_s"></a>- s -</h3><ul>
+<li>scalar
+: <a class="el" href="structyaml__token__s.html#a35e3629351176dd91b38cbfc827a8b00">yaml_token_s</a>
+, <a class="el" href="structyaml__event__s.html#a3753b4c5d10040d75f7c7f4b56c42549">yaml_event_s</a>
+, <a class="el" href="structyaml__node__s.html#a688583a2649848aed700d7e07d9efac9">yaml_node_s</a>
+</li>
+<li>scalar_data
+: <a class="el" href="structyaml__emitter__s.html#ac3f80f4cb9c361b5fa4fa8f5cc04dbac">yaml_emitter_s</a>
+</li>
+<li>sequence
+: <a class="el" href="structyaml__node__s.html#afe215962139fac93b965cc2acd71452b">yaml_node_s</a>
+</li>
+<li>sequence_context
+: <a class="el" href="structyaml__emitter__s.html#a9d20d55b0914ff81bf0f56e57ca7416e">yaml_emitter_s</a>
+</li>
+<li>sequence_start
+: <a class="el" href="structyaml__event__s.html#a632895e022fbf29ab24a816893a8580f">yaml_event_s</a>
+</li>
+<li>serialized
+: <a class="el" href="structyaml__emitter__s.html#a6c3e98c02ffae879717b3d09f9458936">yaml_emitter_s</a>
+</li>
+<li>simple_key_allowed
+: <a class="el" href="structyaml__parser__s.html#acc85a7bfddc7ae9114cf115e43c89126">yaml_parser_s</a>
+</li>
+<li>simple_key_context
+: <a class="el" href="structyaml__emitter__s.html#acc0db69cdae44c1385bbb2b6c207371b">yaml_emitter_s</a>
+</li>
+<li>simple_keys
+: <a class="el" href="structyaml__parser__s.html#ad5ce7de476c58fb6e1fdabbcc1c51659">yaml_parser_s</a>
+</li>
+<li>single_quoted_allowed
+: <a class="el" href="structyaml__emitter__s.html#a3729ff7e7add06a1a1d9067a557a59fc">yaml_emitter_s</a>
+</li>
+<li>size
+: <a class="el" href="structyaml__emitter__s.html#a53bdc6a00632b48c81098aad91a9fd8d">yaml_emitter_s</a>
+</li>
+<li>size_written
+: <a class="el" href="structyaml__emitter__s.html#a1851639b8f0e53b8e272c806d9fb648b">yaml_emitter_s</a>
+</li>
+<li>start
+: <a class="el" href="structyaml__node__s.html#a2e1001a0a7b068d4b2543a93d4cf60d4">yaml_node_s</a>
+, <a class="el" href="structyaml__emitter__s.html#ad68af21e510adcfc2db43b31e791efe1">yaml_emitter_s</a>
+, <a class="el" href="structyaml__node__s.html#a82afddfe1cf7f1a346d931ad4896d3de">yaml_node_s</a>
+, <a class="el" href="structyaml__emitter__s.html#a28ec8053132a8e7cf29df983835754b7">yaml_emitter_s</a>
+, <a class="el" href="structyaml__document__s.html#aa3f9a11d8fbe4ac2eada1786176bab89">yaml_document_s</a>
+, <a class="el" href="structyaml__parser__s.html#a8cdb2fed4bb17b1d62d29fa06c53fef6">yaml_parser_s</a>
+, <a class="el" href="structyaml__emitter__s.html#ae8913d3c0bf4c987dc452efee2c802e3">yaml_emitter_s</a>
+, <a class="el" href="structyaml__parser__s.html#ab9eddd3a112c3a4547bf87f6936aba94">yaml_parser_s</a>
+, <a class="el" href="structyaml__event__s.html#a74d7f521a559305585009ab503bee16b">yaml_event_s</a>
+, <a class="el" href="structyaml__emitter__s.html#a1c8f40a58f0a3061449b3fed02be145e">yaml_emitter_s</a>
+</li>
+<li>start_implicit
+: <a class="el" href="structyaml__document__s.html#a65c49e4f61ca5c2f6ecf410e1cc65787">yaml_document_s</a>
+</li>
+<li>start_mark
+: <a class="el" href="structyaml__token__s.html#abdc5f4f2059c5a7bfe8e810b49a53980">yaml_token_s</a>
+, <a class="el" href="structyaml__event__s.html#aeaf86eb588e75232e1b73e8213eb3e31">yaml_event_s</a>
+, <a class="el" href="structyaml__document__s.html#a0a37311ebf8f6637e4bc1d280a879997">yaml_document_s</a>
+, <a class="el" href="structyaml__node__s.html#ac17afa3b3a9ff4703bb4983163bfae5c">yaml_node_s</a>
+</li>
+<li>state
+: <a class="el" href="structyaml__parser__s.html#a069d39cdf587ac2188e69d8fb018be64">yaml_parser_s</a>
+, <a class="el" href="structyaml__emitter__s.html#a29f1d4f27ff9b9616c154f0730dd24ee">yaml_emitter_s</a>
+</li>
+<li>states
+: <a class="el" href="structyaml__parser__s.html#a57aa3c5fbfcaed8c17e046f0778c92bf">yaml_parser_s</a>
+, <a class="el" href="structyaml__emitter__s.html#a6dc87fbd5b074507e102b967492b135d">yaml_emitter_s</a>
+</li>
+<li>stream_end_produced
+: <a class="el" href="structyaml__parser__s.html#a63ccf04d623f36c04b62cfd1fc6fccb5">yaml_parser_s</a>
+</li>
+<li>stream_start
+: <a class="el" href="structyaml__token__s.html#aab66b62f4507f4fd0e9d2b7548f588e6">yaml_token_s</a>
+, <a class="el" href="structyaml__event__s.html#a18946df9b7c815dd7fb30103c02a9e24">yaml_event_s</a>
+</li>
+<li>stream_start_produced
+: <a class="el" href="structyaml__parser__s.html#a7fecde5abcce11406c271f7db08f7a05">yaml_parser_s</a>
+</li>
+<li>string
+: <a class="el" href="structyaml__emitter__s.html#a8803fe1047e8bcea9bdfcad0743fa0dd">yaml_emitter_s</a>
+, <a class="el" href="structyaml__parser__s.html#a44fa7ca68030680244f3743ce5e35702">yaml_parser_s</a>
+</li>
+<li>style
+: <a class="el" href="structyaml__node__s.html#a362960375516e77a130c412ef10ef55d">yaml_node_s</a>
+, <a class="el" href="structyaml__event__s.html#a2ac1305583a8e7e2247738116bca6b3b">yaml_event_s</a>
+, <a class="el" href="structyaml__emitter__s.html#acd1e83d220103aa24577038cfb1c2d21">yaml_emitter_s</a>
+, <a class="el" href="structyaml__token__s.html#a530a8c4d78feaf5496fb9f461674382b">yaml_token_s</a>
+, <a class="el" href="structyaml__node__s.html#a5b80d97f64e2867927404fedb65949c6">yaml_node_s</a>
+</li>
+<li>suffix
+: <a class="el" href="structyaml__token__s.html#a61344c49b73da5821cb06cab4cbab505">yaml_token_s</a>
+, <a class="el" href="structyaml__emitter__s.html#ad9b61d5e9e05a47b2f873342ab226188">yaml_emitter_s</a>
+</li>
+<li>suffix_length
+: <a class="el" href="structyaml__emitter__s.html#ad83936bbd4b6b77c79555c71cccc8fb5">yaml_emitter_s</a>
+</li>
+</ul>
+</div>
+<hr class="footer"/><address class="footer"><small>Generated on Mon May 30 2011 22:00:00 for yaml by&nbsp;
+<a href="http://www.doxygen.org/index.html">
+<img class="footer" src="doxygen.png" alt="doxygen"/></a> 1.7.1 </small></address>
+</body>
+</html>
diff --git a/contrib/libyaml/doc/html/functions_0x74.html b/contrib/libyaml/doc/html/functions_0x74.html
new file mode 100644
index 0000000..6adf45e
--- /dev/null
+++ b/contrib/libyaml/doc/html/functions_0x74.html
@@ -0,0 +1,115 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head>
+<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/>
+<title>yaml: Data Fields</title>
+<link href="tabs.css" rel="stylesheet" type="text/css"/>
+<link href="doxygen.css" rel="stylesheet" type="text/css"/>
+</head>
+<body>
+<!-- Generated by Doxygen 1.7.1 -->
+<div class="navigation" id="top">
+ <div class="tabs">
+ <ul class="tablist">
+ <li><a href="index.html"><span>Main&nbsp;Page</span></a></li>
+ <li><a href="modules.html"><span>Modules</span></a></li>
+ <li class="current"><a href="annotated.html"><span>Data&nbsp;Structures</span></a></li>
+ <li><a href="files.html"><span>Files</span></a></li>
+ </ul>
+ </div>
+ <div class="tabs2">
+ <ul class="tablist">
+ <li><a href="annotated.html"><span>Data&nbsp;Structures</span></a></li>
+ <li class="current"><a href="functions.html"><span>Data&nbsp;Fields</span></a></li>
+ </ul>
+ </div>
+ <div class="tabs2">
+ <ul class="tablist">
+ <li class="current"><a href="functions.html"><span>All</span></a></li>
+ <li><a href="functions_vars.html"><span>Variables</span></a></li>
+ </ul>
+ </div>
+ <div class="tabs3">
+ <ul class="tablist">
+ <li><a href="functions.html#index_a"><span>a</span></a></li>
+ <li><a href="functions_0x62.html#index_b"><span>b</span></a></li>
+ <li><a href="functions_0x63.html#index_c"><span>c</span></a></li>
+ <li><a href="functions_0x64.html#index_d"><span>d</span></a></li>
+ <li><a href="functions_0x65.html#index_e"><span>e</span></a></li>
+ <li><a href="functions_0x66.html#index_f"><span>f</span></a></li>
+ <li><a href="functions_0x68.html#index_h"><span>h</span></a></li>
+ <li><a href="functions_0x69.html#index_i"><span>i</span></a></li>
+ <li><a href="functions_0x6b.html#index_k"><span>k</span></a></li>
+ <li><a href="functions_0x6c.html#index_l"><span>l</span></a></li>
+ <li><a href="functions_0x6d.html#index_m"><span>m</span></a></li>
+ <li><a href="functions_0x6e.html#index_n"><span>n</span></a></li>
+ <li><a href="functions_0x6f.html#index_o"><span>o</span></a></li>
+ <li><a href="functions_0x70.html#index_p"><span>p</span></a></li>
+ <li><a href="functions_0x71.html#index_q"><span>q</span></a></li>
+ <li><a href="functions_0x72.html#index_r"><span>r</span></a></li>
+ <li><a href="functions_0x73.html#index_s"><span>s</span></a></li>
+ <li class="current"><a href="functions_0x74.html#index_t"><span>t</span></a></li>
+ <li><a href="functions_0x75.html#index_u"><span>u</span></a></li>
+ <li><a href="functions_0x76.html#index_v"><span>v</span></a></li>
+ <li><a href="functions_0x77.html#index_w"><span>w</span></a></li>
+ </ul>
+ </div>
+</div>
+<div class="contents">
+Here is a list of all documented struct and union fields with links to the struct/union documentation for each field:
+
+<h3><a class="anchor" id="index_t"></a>- t -</h3><ul>
+<li>tag
+: <a class="el" href="structyaml__token__s.html#ab281db5b7563c5489726768fe0fbaac7">yaml_token_s</a>
+, <a class="el" href="structyaml__event__s.html#a4daf9ed2683d79f2be7e89ca7d06801c">yaml_event_s</a>
+, <a class="el" href="structyaml__node__s.html#aa753358ea6d9d221b7b188832d47fefa">yaml_node_s</a>
+</li>
+<li>tag_data
+: <a class="el" href="structyaml__emitter__s.html#a3b947fbbc337d123af10c58abf1353a4">yaml_emitter_s</a>
+</li>
+<li>tag_directive
+: <a class="el" href="structyaml__token__s.html#aa8a1b9eeee539233e8461773894f4ea0">yaml_token_s</a>
+</li>
+<li>tag_directives
+: <a class="el" href="structyaml__parser__s.html#a9bdfc1888d4e30ffb43146377d44fba0">yaml_parser_s</a>
+, <a class="el" href="structyaml__emitter__s.html#a9dc51f2ccb8a517e2dc029e1af960258">yaml_emitter_s</a>
+, <a class="el" href="structyaml__event__s.html#a162ce89a77e706d68649d40e1a520e1f">yaml_event_s</a>
+, <a class="el" href="structyaml__document__s.html#af1e09d0469fc24106f3790b1e3de09e1">yaml_document_s</a>
+</li>
+<li>tail
+: <a class="el" href="structyaml__parser__s.html#a22ad26583d8d1264e982188358aa79b6">yaml_parser_s</a>
+, <a class="el" href="structyaml__emitter__s.html#acafa1e3cb872fa7917217469659fb273">yaml_emitter_s</a>
+</li>
+<li>token_number
+: <a class="el" href="structyaml__simple__key__s.html#ae098916893ad7415c5c041dd45d24a86">yaml_simple_key_s</a>
+</li>
+<li>tokens
+: <a class="el" href="structyaml__parser__s.html#a96d39b8333411d741ee1c13aa4141682">yaml_parser_s</a>
+</li>
+<li>tokens_parsed
+: <a class="el" href="structyaml__parser__s.html#a7358e72ad071fec3185a833a3a245690">yaml_parser_s</a>
+</li>
+<li>top
+: <a class="el" href="structyaml__emitter__s.html#a5779bcbfd04df64e42434b7599332d11">yaml_emitter_s</a>
+, <a class="el" href="structyaml__node__s.html#a510326726569a06a11119f12649787cf">yaml_node_s</a>
+, <a class="el" href="structyaml__parser__s.html#a24a3f3138b44de1914a3e54dbe0aeff7">yaml_parser_s</a>
+, <a class="el" href="structyaml__node__s.html#aa420f88720907fe02b1d1595c9351d59">yaml_node_s</a>
+, <a class="el" href="structyaml__document__s.html#a5ac36f59c4a0f28124c2e1630ca4f227">yaml_document_s</a>
+, <a class="el" href="structyaml__parser__s.html#a490eddbfcc27787e47de631a3d2e09a8">yaml_parser_s</a>
+, <a class="el" href="structyaml__emitter__s.html#a8e3f468d814d2aa5e074f7da1648d34a">yaml_emitter_s</a>
+, <a class="el" href="structyaml__parser__s.html#ab2678112fd2eaa8f588f2d6217aabc9d">yaml_parser_s</a>
+, <a class="el" href="structyaml__emitter__s.html#aafa8b6f21022ce2f4cb9b44ad15a535e">yaml_emitter_s</a>
+, <a class="el" href="structyaml__parser__s.html#ae610673669f06d46146198a346796276">yaml_parser_s</a>
+</li>
+<li>type
+: <a class="el" href="structyaml__token__s.html#aa8aeb89e2e74f5e2f199484177d0ea14">yaml_token_s</a>
+, <a class="el" href="structyaml__event__s.html#aff08bc3df4859d5b3a804e8c011cac51">yaml_event_s</a>
+, <a class="el" href="structyaml__node__s.html#a1db4ea72e13be65ec42339ce47d19669">yaml_node_s</a>
+</li>
+</ul>
+</div>
+<hr class="footer"/><address class="footer"><small>Generated on Mon May 30 2011 22:00:00 for yaml by&nbsp;
+<a href="http://www.doxygen.org/index.html">
+<img class="footer" src="doxygen.png" alt="doxygen"/></a> 1.7.1 </small></address>
+</body>
+</html>
diff --git a/contrib/libyaml/doc/html/functions_0x75.html b/contrib/libyaml/doc/html/functions_0x75.html
new file mode 100644
index 0000000..6d48a8f
--- /dev/null
+++ b/contrib/libyaml/doc/html/functions_0x75.html
@@ -0,0 +1,71 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head>
+<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/>
+<title>yaml: Data Fields</title>
+<link href="tabs.css" rel="stylesheet" type="text/css"/>
+<link href="doxygen.css" rel="stylesheet" type="text/css"/>
+</head>
+<body>
+<!-- Generated by Doxygen 1.7.1 -->
+<div class="navigation" id="top">
+ <div class="tabs">
+ <ul class="tablist">
+ <li><a href="index.html"><span>Main&nbsp;Page</span></a></li>
+ <li><a href="modules.html"><span>Modules</span></a></li>
+ <li class="current"><a href="annotated.html"><span>Data&nbsp;Structures</span></a></li>
+ <li><a href="files.html"><span>Files</span></a></li>
+ </ul>
+ </div>
+ <div class="tabs2">
+ <ul class="tablist">
+ <li><a href="annotated.html"><span>Data&nbsp;Structures</span></a></li>
+ <li class="current"><a href="functions.html"><span>Data&nbsp;Fields</span></a></li>
+ </ul>
+ </div>
+ <div class="tabs2">
+ <ul class="tablist">
+ <li class="current"><a href="functions.html"><span>All</span></a></li>
+ <li><a href="functions_vars.html"><span>Variables</span></a></li>
+ </ul>
+ </div>
+ <div class="tabs3">
+ <ul class="tablist">
+ <li><a href="functions.html#index_a"><span>a</span></a></li>
+ <li><a href="functions_0x62.html#index_b"><span>b</span></a></li>
+ <li><a href="functions_0x63.html#index_c"><span>c</span></a></li>
+ <li><a href="functions_0x64.html#index_d"><span>d</span></a></li>
+ <li><a href="functions_0x65.html#index_e"><span>e</span></a></li>
+ <li><a href="functions_0x66.html#index_f"><span>f</span></a></li>
+ <li><a href="functions_0x68.html#index_h"><span>h</span></a></li>
+ <li><a href="functions_0x69.html#index_i"><span>i</span></a></li>
+ <li><a href="functions_0x6b.html#index_k"><span>k</span></a></li>
+ <li><a href="functions_0x6c.html#index_l"><span>l</span></a></li>
+ <li><a href="functions_0x6d.html#index_m"><span>m</span></a></li>
+ <li><a href="functions_0x6e.html#index_n"><span>n</span></a></li>
+ <li><a href="functions_0x6f.html#index_o"><span>o</span></a></li>
+ <li><a href="functions_0x70.html#index_p"><span>p</span></a></li>
+ <li><a href="functions_0x71.html#index_q"><span>q</span></a></li>
+ <li><a href="functions_0x72.html#index_r"><span>r</span></a></li>
+ <li><a href="functions_0x73.html#index_s"><span>s</span></a></li>
+ <li><a href="functions_0x74.html#index_t"><span>t</span></a></li>
+ <li class="current"><a href="functions_0x75.html#index_u"><span>u</span></a></li>
+ <li><a href="functions_0x76.html#index_v"><span>v</span></a></li>
+ <li><a href="functions_0x77.html#index_w"><span>w</span></a></li>
+ </ul>
+ </div>
+</div>
+<div class="contents">
+Here is a list of all documented struct and union fields with links to the struct/union documentation for each field:
+
+<h3><a class="anchor" id="index_u"></a>- u -</h3><ul>
+<li>unicode
+: <a class="el" href="structyaml__emitter__s.html#a76372a2413f71a5b36bf77a58d8f5d40">yaml_emitter_s</a>
+</li>
+</ul>
+</div>
+<hr class="footer"/><address class="footer"><small>Generated on Mon May 30 2011 22:00:00 for yaml by&nbsp;
+<a href="http://www.doxygen.org/index.html">
+<img class="footer" src="doxygen.png" alt="doxygen"/></a> 1.7.1 </small></address>
+</body>
+</html>
diff --git a/contrib/libyaml/doc/html/functions_0x76.html b/contrib/libyaml/doc/html/functions_0x76.html
new file mode 100644
index 0000000..d510ab80
--- /dev/null
+++ b/contrib/libyaml/doc/html/functions_0x76.html
@@ -0,0 +1,80 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head>
+<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/>
+<title>yaml: Data Fields</title>
+<link href="tabs.css" rel="stylesheet" type="text/css"/>
+<link href="doxygen.css" rel="stylesheet" type="text/css"/>
+</head>
+<body>
+<!-- Generated by Doxygen 1.7.1 -->
+<div class="navigation" id="top">
+ <div class="tabs">
+ <ul class="tablist">
+ <li><a href="index.html"><span>Main&nbsp;Page</span></a></li>
+ <li><a href="modules.html"><span>Modules</span></a></li>
+ <li class="current"><a href="annotated.html"><span>Data&nbsp;Structures</span></a></li>
+ <li><a href="files.html"><span>Files</span></a></li>
+ </ul>
+ </div>
+ <div class="tabs2">
+ <ul class="tablist">
+ <li><a href="annotated.html"><span>Data&nbsp;Structures</span></a></li>
+ <li class="current"><a href="functions.html"><span>Data&nbsp;Fields</span></a></li>
+ </ul>
+ </div>
+ <div class="tabs2">
+ <ul class="tablist">
+ <li class="current"><a href="functions.html"><span>All</span></a></li>
+ <li><a href="functions_vars.html"><span>Variables</span></a></li>
+ </ul>
+ </div>
+ <div class="tabs3">
+ <ul class="tablist">
+ <li><a href="functions.html#index_a"><span>a</span></a></li>
+ <li><a href="functions_0x62.html#index_b"><span>b</span></a></li>
+ <li><a href="functions_0x63.html#index_c"><span>c</span></a></li>
+ <li><a href="functions_0x64.html#index_d"><span>d</span></a></li>
+ <li><a href="functions_0x65.html#index_e"><span>e</span></a></li>
+ <li><a href="functions_0x66.html#index_f"><span>f</span></a></li>
+ <li><a href="functions_0x68.html#index_h"><span>h</span></a></li>
+ <li><a href="functions_0x69.html#index_i"><span>i</span></a></li>
+ <li><a href="functions_0x6b.html#index_k"><span>k</span></a></li>
+ <li><a href="functions_0x6c.html#index_l"><span>l</span></a></li>
+ <li><a href="functions_0x6d.html#index_m"><span>m</span></a></li>
+ <li><a href="functions_0x6e.html#index_n"><span>n</span></a></li>
+ <li><a href="functions_0x6f.html#index_o"><span>o</span></a></li>
+ <li><a href="functions_0x70.html#index_p"><span>p</span></a></li>
+ <li><a href="functions_0x71.html#index_q"><span>q</span></a></li>
+ <li><a href="functions_0x72.html#index_r"><span>r</span></a></li>
+ <li><a href="functions_0x73.html#index_s"><span>s</span></a></li>
+ <li><a href="functions_0x74.html#index_t"><span>t</span></a></li>
+ <li><a href="functions_0x75.html#index_u"><span>u</span></a></li>
+ <li class="current"><a href="functions_0x76.html#index_v"><span>v</span></a></li>
+ <li><a href="functions_0x77.html#index_w"><span>w</span></a></li>
+ </ul>
+ </div>
+</div>
+<div class="contents">
+Here is a list of all documented struct and union fields with links to the struct/union documentation for each field:
+
+<h3><a class="anchor" id="index_v"></a>- v -</h3><ul>
+<li>value
+: <a class="el" href="structyaml__token__s.html#a97ce52329d6093b63fba36817f8bd549">yaml_token_s</a>
+, <a class="el" href="structyaml__event__s.html#a23436bdddb447d0fc217bab5c5b04a36">yaml_event_s</a>
+, <a class="el" href="structyaml__node__s.html#a0d444412a29609d62699267ae72f971d">yaml_node_s</a>
+, <a class="el" href="structyaml__emitter__s.html#a20246ec76d64854ff93629cf1b424d86">yaml_emitter_s</a>
+, <a class="el" href="structyaml__node__pair__s.html#a56c1de2c11d509462d1bf03803bb8ab1">yaml_node_pair_s</a>
+</li>
+<li>version_directive
+: <a class="el" href="structyaml__document__s.html#a7d36862d070804b8bedb53866487ac6d">yaml_document_s</a>
+, <a class="el" href="structyaml__event__s.html#a5cef7981358ecefdf9d4780b3eacd39b">yaml_event_s</a>
+, <a class="el" href="structyaml__token__s.html#a41b30a59ca22d1020d6af4cc7cc0da47">yaml_token_s</a>
+</li>
+</ul>
+</div>
+<hr class="footer"/><address class="footer"><small>Generated on Mon May 30 2011 22:00:00 for yaml by&nbsp;
+<a href="http://www.doxygen.org/index.html">
+<img class="footer" src="doxygen.png" alt="doxygen"/></a> 1.7.1 </small></address>
+</body>
+</html>
diff --git a/contrib/libyaml/doc/html/functions_0x77.html b/contrib/libyaml/doc/html/functions_0x77.html
new file mode 100644
index 0000000..44b8d29
--- /dev/null
+++ b/contrib/libyaml/doc/html/functions_0x77.html
@@ -0,0 +1,77 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head>
+<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/>
+<title>yaml: Data Fields</title>
+<link href="tabs.css" rel="stylesheet" type="text/css"/>
+<link href="doxygen.css" rel="stylesheet" type="text/css"/>
+</head>
+<body>
+<!-- Generated by Doxygen 1.7.1 -->
+<div class="navigation" id="top">
+ <div class="tabs">
+ <ul class="tablist">
+ <li><a href="index.html"><span>Main&nbsp;Page</span></a></li>
+ <li><a href="modules.html"><span>Modules</span></a></li>
+ <li class="current"><a href="annotated.html"><span>Data&nbsp;Structures</span></a></li>
+ <li><a href="files.html"><span>Files</span></a></li>
+ </ul>
+ </div>
+ <div class="tabs2">
+ <ul class="tablist">
+ <li><a href="annotated.html"><span>Data&nbsp;Structures</span></a></li>
+ <li class="current"><a href="functions.html"><span>Data&nbsp;Fields</span></a></li>
+ </ul>
+ </div>
+ <div class="tabs2">
+ <ul class="tablist">
+ <li class="current"><a href="functions.html"><span>All</span></a></li>
+ <li><a href="functions_vars.html"><span>Variables</span></a></li>
+ </ul>
+ </div>
+ <div class="tabs3">
+ <ul class="tablist">
+ <li><a href="functions.html#index_a"><span>a</span></a></li>
+ <li><a href="functions_0x62.html#index_b"><span>b</span></a></li>
+ <li><a href="functions_0x63.html#index_c"><span>c</span></a></li>
+ <li><a href="functions_0x64.html#index_d"><span>d</span></a></li>
+ <li><a href="functions_0x65.html#index_e"><span>e</span></a></li>
+ <li><a href="functions_0x66.html#index_f"><span>f</span></a></li>
+ <li><a href="functions_0x68.html#index_h"><span>h</span></a></li>
+ <li><a href="functions_0x69.html#index_i"><span>i</span></a></li>
+ <li><a href="functions_0x6b.html#index_k"><span>k</span></a></li>
+ <li><a href="functions_0x6c.html#index_l"><span>l</span></a></li>
+ <li><a href="functions_0x6d.html#index_m"><span>m</span></a></li>
+ <li><a href="functions_0x6e.html#index_n"><span>n</span></a></li>
+ <li><a href="functions_0x6f.html#index_o"><span>o</span></a></li>
+ <li><a href="functions_0x70.html#index_p"><span>p</span></a></li>
+ <li><a href="functions_0x71.html#index_q"><span>q</span></a></li>
+ <li><a href="functions_0x72.html#index_r"><span>r</span></a></li>
+ <li><a href="functions_0x73.html#index_s"><span>s</span></a></li>
+ <li><a href="functions_0x74.html#index_t"><span>t</span></a></li>
+ <li><a href="functions_0x75.html#index_u"><span>u</span></a></li>
+ <li><a href="functions_0x76.html#index_v"><span>v</span></a></li>
+ <li class="current"><a href="functions_0x77.html#index_w"><span>w</span></a></li>
+ </ul>
+ </div>
+</div>
+<div class="contents">
+Here is a list of all documented struct and union fields with links to the struct/union documentation for each field:
+
+<h3><a class="anchor" id="index_w"></a>- w -</h3><ul>
+<li>whitespace
+: <a class="el" href="structyaml__emitter__s.html#a160ed0cf1cc6116b65772d14ced2d867">yaml_emitter_s</a>
+</li>
+<li>write_handler
+: <a class="el" href="structyaml__emitter__s.html#aefa7e29ba8042ed1d133a02bb368ea3e">yaml_emitter_s</a>
+</li>
+<li>write_handler_data
+: <a class="el" href="structyaml__emitter__s.html#a6c4fe0176b69da64ac1ddc7e091967e5">yaml_emitter_s</a>
+</li>
+</ul>
+</div>
+<hr class="footer"/><address class="footer"><small>Generated on Mon May 30 2011 22:00:00 for yaml by&nbsp;
+<a href="http://www.doxygen.org/index.html">
+<img class="footer" src="doxygen.png" alt="doxygen"/></a> 1.7.1 </small></address>
+</body>
+</html>
diff --git a/contrib/libyaml/doc/html/functions_vars.html b/contrib/libyaml/doc/html/functions_vars.html
new file mode 100644
index 0000000..c8b5032
--- /dev/null
+++ b/contrib/libyaml/doc/html/functions_vars.html
@@ -0,0 +1,91 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head>
+<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/>
+<title>yaml: Data Fields - Variables</title>
+<link href="tabs.css" rel="stylesheet" type="text/css"/>
+<link href="doxygen.css" rel="stylesheet" type="text/css"/>
+</head>
+<body>
+<!-- Generated by Doxygen 1.7.1 -->
+<div class="navigation" id="top">
+ <div class="tabs">
+ <ul class="tablist">
+ <li><a href="index.html"><span>Main&nbsp;Page</span></a></li>
+ <li><a href="modules.html"><span>Modules</span></a></li>
+ <li class="current"><a href="annotated.html"><span>Data&nbsp;Structures</span></a></li>
+ <li><a href="files.html"><span>Files</span></a></li>
+ </ul>
+ </div>
+ <div class="tabs2">
+ <ul class="tablist">
+ <li><a href="annotated.html"><span>Data&nbsp;Structures</span></a></li>
+ <li class="current"><a href="functions.html"><span>Data&nbsp;Fields</span></a></li>
+ </ul>
+ </div>
+ <div class="tabs2">
+ <ul class="tablist">
+ <li><a href="functions.html"><span>All</span></a></li>
+ <li class="current"><a href="functions_vars.html"><span>Variables</span></a></li>
+ </ul>
+ </div>
+ <div class="tabs3">
+ <ul class="tablist">
+ <li class="current"><a href="functions_vars.html#index_a"><span>a</span></a></li>
+ <li><a href="functions_vars_0x62.html#index_b"><span>b</span></a></li>
+ <li><a href="functions_vars_0x63.html#index_c"><span>c</span></a></li>
+ <li><a href="functions_vars_0x64.html#index_d"><span>d</span></a></li>
+ <li><a href="functions_vars_0x65.html#index_e"><span>e</span></a></li>
+ <li><a href="functions_vars_0x66.html#index_f"><span>f</span></a></li>
+ <li><a href="functions_vars_0x68.html#index_h"><span>h</span></a></li>
+ <li><a href="functions_vars_0x69.html#index_i"><span>i</span></a></li>
+ <li><a href="functions_vars_0x6b.html#index_k"><span>k</span></a></li>
+ <li><a href="functions_vars_0x6c.html#index_l"><span>l</span></a></li>
+ <li><a href="functions_vars_0x6d.html#index_m"><span>m</span></a></li>
+ <li><a href="functions_vars_0x6e.html#index_n"><span>n</span></a></li>
+ <li><a href="functions_vars_0x6f.html#index_o"><span>o</span></a></li>
+ <li><a href="functions_vars_0x70.html#index_p"><span>p</span></a></li>
+ <li><a href="functions_vars_0x71.html#index_q"><span>q</span></a></li>
+ <li><a href="functions_vars_0x72.html#index_r"><span>r</span></a></li>
+ <li><a href="functions_vars_0x73.html#index_s"><span>s</span></a></li>
+ <li><a href="functions_vars_0x74.html#index_t"><span>t</span></a></li>
+ <li><a href="functions_vars_0x75.html#index_u"><span>u</span></a></li>
+ <li><a href="functions_vars_0x76.html#index_v"><span>v</span></a></li>
+ <li><a href="functions_vars_0x77.html#index_w"><span>w</span></a></li>
+ </ul>
+ </div>
+</div>
+<div class="contents">
+&nbsp;
+
+<h3><a class="anchor" id="index_a"></a>- a -</h3><ul>
+<li>alias
+: <a class="el" href="structyaml__token__s.html#a1f942353efa1972a38a0763afefabe0c">yaml_token_s</a>
+, <a class="el" href="structyaml__event__s.html#ac21f0f1e12207b8fd4f02496259f6c0b">yaml_event_s</a>
+, <a class="el" href="structyaml__emitter__s.html#a1129c6f9ae5cd3b437b8ab8767324f03">yaml_emitter_s</a>
+</li>
+<li>aliases
+: <a class="el" href="structyaml__parser__s.html#a0c10698207d727f9e5d9ced627d130ef">yaml_parser_s</a>
+</li>
+<li>anchor
+: <a class="el" href="structyaml__emitter__s.html#a6f2882bde71e478e29dc5b293def8739">yaml_emitter_s</a>
+, <a class="el" href="structyaml__alias__data__s.html#ac4b9a352dd8ff747bfa63a54832d7962">yaml_alias_data_s</a>
+, <a class="el" href="structyaml__token__s.html#acc0f6636995f5fe332604b74571e6cfa">yaml_token_s</a>
+, <a class="el" href="structyaml__event__s.html#aaa97ab683d28e5f611042d0fbd929125">yaml_event_s</a>
+</li>
+<li>anchor_data
+: <a class="el" href="structyaml__emitter__s.html#ad8883d967ee02e3e15e58bc2533188cc">yaml_emitter_s</a>
+</li>
+<li>anchor_length
+: <a class="el" href="structyaml__emitter__s.html#aece73cc234475630032b1c75a735eeb5">yaml_emitter_s</a>
+</li>
+<li>anchors
+: <a class="el" href="structyaml__emitter__s.html#ad4e7a72cb8b1b67373ba6d76a5229e6b">yaml_emitter_s</a>
+</li>
+</ul>
+</div>
+<hr class="footer"/><address class="footer"><small>Generated on Mon May 30 2011 22:00:00 for yaml by&nbsp;
+<a href="http://www.doxygen.org/index.html">
+<img class="footer" src="doxygen.png" alt="doxygen"/></a> 1.7.1 </small></address>
+</body>
+</html>
diff --git a/contrib/libyaml/doc/html/functions_vars_0x62.html b/contrib/libyaml/doc/html/functions_vars_0x62.html
new file mode 100644
index 0000000..0d04a42
--- /dev/null
+++ b/contrib/libyaml/doc/html/functions_vars_0x62.html
@@ -0,0 +1,84 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head>
+<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/>
+<title>yaml: Data Fields - Variables</title>
+<link href="tabs.css" rel="stylesheet" type="text/css"/>
+<link href="doxygen.css" rel="stylesheet" type="text/css"/>
+</head>
+<body>
+<!-- Generated by Doxygen 1.7.1 -->
+<div class="navigation" id="top">
+ <div class="tabs">
+ <ul class="tablist">
+ <li><a href="index.html"><span>Main&nbsp;Page</span></a></li>
+ <li><a href="modules.html"><span>Modules</span></a></li>
+ <li class="current"><a href="annotated.html"><span>Data&nbsp;Structures</span></a></li>
+ <li><a href="files.html"><span>Files</span></a></li>
+ </ul>
+ </div>
+ <div class="tabs2">
+ <ul class="tablist">
+ <li><a href="annotated.html"><span>Data&nbsp;Structures</span></a></li>
+ <li class="current"><a href="functions.html"><span>Data&nbsp;Fields</span></a></li>
+ </ul>
+ </div>
+ <div class="tabs2">
+ <ul class="tablist">
+ <li><a href="functions.html"><span>All</span></a></li>
+ <li class="current"><a href="functions_vars.html"><span>Variables</span></a></li>
+ </ul>
+ </div>
+ <div class="tabs3">
+ <ul class="tablist">
+ <li><a href="functions_vars.html#index_a"><span>a</span></a></li>
+ <li class="current"><a href="functions_vars_0x62.html#index_b"><span>b</span></a></li>
+ <li><a href="functions_vars_0x63.html#index_c"><span>c</span></a></li>
+ <li><a href="functions_vars_0x64.html#index_d"><span>d</span></a></li>
+ <li><a href="functions_vars_0x65.html#index_e"><span>e</span></a></li>
+ <li><a href="functions_vars_0x66.html#index_f"><span>f</span></a></li>
+ <li><a href="functions_vars_0x68.html#index_h"><span>h</span></a></li>
+ <li><a href="functions_vars_0x69.html#index_i"><span>i</span></a></li>
+ <li><a href="functions_vars_0x6b.html#index_k"><span>k</span></a></li>
+ <li><a href="functions_vars_0x6c.html#index_l"><span>l</span></a></li>
+ <li><a href="functions_vars_0x6d.html#index_m"><span>m</span></a></li>
+ <li><a href="functions_vars_0x6e.html#index_n"><span>n</span></a></li>
+ <li><a href="functions_vars_0x6f.html#index_o"><span>o</span></a></li>
+ <li><a href="functions_vars_0x70.html#index_p"><span>p</span></a></li>
+ <li><a href="functions_vars_0x71.html#index_q"><span>q</span></a></li>
+ <li><a href="functions_vars_0x72.html#index_r"><span>r</span></a></li>
+ <li><a href="functions_vars_0x73.html#index_s"><span>s</span></a></li>
+ <li><a href="functions_vars_0x74.html#index_t"><span>t</span></a></li>
+ <li><a href="functions_vars_0x75.html#index_u"><span>u</span></a></li>
+ <li><a href="functions_vars_0x76.html#index_v"><span>v</span></a></li>
+ <li><a href="functions_vars_0x77.html#index_w"><span>w</span></a></li>
+ </ul>
+ </div>
+</div>
+<div class="contents">
+&nbsp;
+
+<h3><a class="anchor" id="index_b"></a>- b -</h3><ul>
+<li>best_indent
+: <a class="el" href="structyaml__emitter__s.html#a33545f8924be89daf8b81dc905d558c0">yaml_emitter_s</a>
+</li>
+<li>best_width
+: <a class="el" href="structyaml__emitter__s.html#a56dde6b352bdf7d4031f89d2b5d704f6">yaml_emitter_s</a>
+</li>
+<li>block_allowed
+: <a class="el" href="structyaml__emitter__s.html#a64e05972897d02f606627ef0cf3c7420">yaml_emitter_s</a>
+</li>
+<li>block_plain_allowed
+: <a class="el" href="structyaml__emitter__s.html#a5b5f6c9d687d788c8dac86d213ef4c16">yaml_emitter_s</a>
+</li>
+<li>buffer
+: <a class="el" href="structyaml__emitter__s.html#afb2700e9b866b5be0ff6c7549c719f81">yaml_emitter_s</a>
+, <a class="el" href="structyaml__parser__s.html#afc56b6252bd75ec87edec5c80a5c733e">yaml_parser_s</a>
+</li>
+</ul>
+</div>
+<hr class="footer"/><address class="footer"><small>Generated on Mon May 30 2011 22:00:00 for yaml by&nbsp;
+<a href="http://www.doxygen.org/index.html">
+<img class="footer" src="doxygen.png" alt="doxygen"/></a> 1.7.1 </small></address>
+</body>
+</html>
diff --git a/contrib/libyaml/doc/html/functions_vars_0x63.html b/contrib/libyaml/doc/html/functions_vars_0x63.html
new file mode 100644
index 0000000..0edc901
--- /dev/null
+++ b/contrib/libyaml/doc/html/functions_vars_0x63.html
@@ -0,0 +1,87 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head>
+<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/>
+<title>yaml: Data Fields - Variables</title>
+<link href="tabs.css" rel="stylesheet" type="text/css"/>
+<link href="doxygen.css" rel="stylesheet" type="text/css"/>
+</head>
+<body>
+<!-- Generated by Doxygen 1.7.1 -->
+<div class="navigation" id="top">
+ <div class="tabs">
+ <ul class="tablist">
+ <li><a href="index.html"><span>Main&nbsp;Page</span></a></li>
+ <li><a href="modules.html"><span>Modules</span></a></li>
+ <li class="current"><a href="annotated.html"><span>Data&nbsp;Structures</span></a></li>
+ <li><a href="files.html"><span>Files</span></a></li>
+ </ul>
+ </div>
+ <div class="tabs2">
+ <ul class="tablist">
+ <li><a href="annotated.html"><span>Data&nbsp;Structures</span></a></li>
+ <li class="current"><a href="functions.html"><span>Data&nbsp;Fields</span></a></li>
+ </ul>
+ </div>
+ <div class="tabs2">
+ <ul class="tablist">
+ <li><a href="functions.html"><span>All</span></a></li>
+ <li class="current"><a href="functions_vars.html"><span>Variables</span></a></li>
+ </ul>
+ </div>
+ <div class="tabs3">
+ <ul class="tablist">
+ <li><a href="functions_vars.html#index_a"><span>a</span></a></li>
+ <li><a href="functions_vars_0x62.html#index_b"><span>b</span></a></li>
+ <li class="current"><a href="functions_vars_0x63.html#index_c"><span>c</span></a></li>
+ <li><a href="functions_vars_0x64.html#index_d"><span>d</span></a></li>
+ <li><a href="functions_vars_0x65.html#index_e"><span>e</span></a></li>
+ <li><a href="functions_vars_0x66.html#index_f"><span>f</span></a></li>
+ <li><a href="functions_vars_0x68.html#index_h"><span>h</span></a></li>
+ <li><a href="functions_vars_0x69.html#index_i"><span>i</span></a></li>
+ <li><a href="functions_vars_0x6b.html#index_k"><span>k</span></a></li>
+ <li><a href="functions_vars_0x6c.html#index_l"><span>l</span></a></li>
+ <li><a href="functions_vars_0x6d.html#index_m"><span>m</span></a></li>
+ <li><a href="functions_vars_0x6e.html#index_n"><span>n</span></a></li>
+ <li><a href="functions_vars_0x6f.html#index_o"><span>o</span></a></li>
+ <li><a href="functions_vars_0x70.html#index_p"><span>p</span></a></li>
+ <li><a href="functions_vars_0x71.html#index_q"><span>q</span></a></li>
+ <li><a href="functions_vars_0x72.html#index_r"><span>r</span></a></li>
+ <li><a href="functions_vars_0x73.html#index_s"><span>s</span></a></li>
+ <li><a href="functions_vars_0x74.html#index_t"><span>t</span></a></li>
+ <li><a href="functions_vars_0x75.html#index_u"><span>u</span></a></li>
+ <li><a href="functions_vars_0x76.html#index_v"><span>v</span></a></li>
+ <li><a href="functions_vars_0x77.html#index_w"><span>w</span></a></li>
+ </ul>
+ </div>
+</div>
+<div class="contents">
+&nbsp;
+
+<h3><a class="anchor" id="index_c"></a>- c -</h3><ul>
+<li>canonical
+: <a class="el" href="structyaml__emitter__s.html#acb0259cdc5e2bb23faaf7266496df827">yaml_emitter_s</a>
+</li>
+<li>closed
+: <a class="el" href="structyaml__emitter__s.html#a978d894a219686d31d971899e31910cd">yaml_emitter_s</a>
+</li>
+<li>column
+: <a class="el" href="structyaml__emitter__s.html#a678fbbacad5d1f3f9bb7516282888b8a">yaml_emitter_s</a>
+, <a class="el" href="structyaml__mark__s.html#aaa18357a6fb2bb377b969ce9ff589797">yaml_mark_s</a>
+</li>
+<li>context
+: <a class="el" href="structyaml__parser__s.html#a6779b67a23bbf7c401e4257d5875ae6b">yaml_parser_s</a>
+</li>
+<li>context_mark
+: <a class="el" href="structyaml__parser__s.html#ace259eec6e570f94b98b252e1a632e88">yaml_parser_s</a>
+</li>
+<li>current
+: <a class="el" href="structyaml__parser__s.html#a3406d2ba7e969c09344d4ced8c855007">yaml_parser_s</a>
+</li>
+</ul>
+</div>
+<hr class="footer"/><address class="footer"><small>Generated on Mon May 30 2011 22:00:00 for yaml by&nbsp;
+<a href="http://www.doxygen.org/index.html">
+<img class="footer" src="doxygen.png" alt="doxygen"/></a> 1.7.1 </small></address>
+</body>
+</html>
diff --git a/contrib/libyaml/doc/html/functions_vars_0x64.html b/contrib/libyaml/doc/html/functions_vars_0x64.html
new file mode 100644
index 0000000..8d476e9
--- /dev/null
+++ b/contrib/libyaml/doc/html/functions_vars_0x64.html
@@ -0,0 +1,83 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head>
+<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/>
+<title>yaml: Data Fields - Variables</title>
+<link href="tabs.css" rel="stylesheet" type="text/css"/>
+<link href="doxygen.css" rel="stylesheet" type="text/css"/>
+</head>
+<body>
+<!-- Generated by Doxygen 1.7.1 -->
+<div class="navigation" id="top">
+ <div class="tabs">
+ <ul class="tablist">
+ <li><a href="index.html"><span>Main&nbsp;Page</span></a></li>
+ <li><a href="modules.html"><span>Modules</span></a></li>
+ <li class="current"><a href="annotated.html"><span>Data&nbsp;Structures</span></a></li>
+ <li><a href="files.html"><span>Files</span></a></li>
+ </ul>
+ </div>
+ <div class="tabs2">
+ <ul class="tablist">
+ <li><a href="annotated.html"><span>Data&nbsp;Structures</span></a></li>
+ <li class="current"><a href="functions.html"><span>Data&nbsp;Fields</span></a></li>
+ </ul>
+ </div>
+ <div class="tabs2">
+ <ul class="tablist">
+ <li><a href="functions.html"><span>All</span></a></li>
+ <li class="current"><a href="functions_vars.html"><span>Variables</span></a></li>
+ </ul>
+ </div>
+ <div class="tabs3">
+ <ul class="tablist">
+ <li><a href="functions_vars.html#index_a"><span>a</span></a></li>
+ <li><a href="functions_vars_0x62.html#index_b"><span>b</span></a></li>
+ <li><a href="functions_vars_0x63.html#index_c"><span>c</span></a></li>
+ <li class="current"><a href="functions_vars_0x64.html#index_d"><span>d</span></a></li>
+ <li><a href="functions_vars_0x65.html#index_e"><span>e</span></a></li>
+ <li><a href="functions_vars_0x66.html#index_f"><span>f</span></a></li>
+ <li><a href="functions_vars_0x68.html#index_h"><span>h</span></a></li>
+ <li><a href="functions_vars_0x69.html#index_i"><span>i</span></a></li>
+ <li><a href="functions_vars_0x6b.html#index_k"><span>k</span></a></li>
+ <li><a href="functions_vars_0x6c.html#index_l"><span>l</span></a></li>
+ <li><a href="functions_vars_0x6d.html#index_m"><span>m</span></a></li>
+ <li><a href="functions_vars_0x6e.html#index_n"><span>n</span></a></li>
+ <li><a href="functions_vars_0x6f.html#index_o"><span>o</span></a></li>
+ <li><a href="functions_vars_0x70.html#index_p"><span>p</span></a></li>
+ <li><a href="functions_vars_0x71.html#index_q"><span>q</span></a></li>
+ <li><a href="functions_vars_0x72.html#index_r"><span>r</span></a></li>
+ <li><a href="functions_vars_0x73.html#index_s"><span>s</span></a></li>
+ <li><a href="functions_vars_0x74.html#index_t"><span>t</span></a></li>
+ <li><a href="functions_vars_0x75.html#index_u"><span>u</span></a></li>
+ <li><a href="functions_vars_0x76.html#index_v"><span>v</span></a></li>
+ <li><a href="functions_vars_0x77.html#index_w"><span>w</span></a></li>
+ </ul>
+ </div>
+</div>
+<div class="contents">
+&nbsp;
+
+<h3><a class="anchor" id="index_d"></a>- d -</h3><ul>
+<li>data
+: <a class="el" href="structyaml__token__s.html#aedb5be9b6b8f5ef6c129575e84f63605">yaml_token_s</a>
+, <a class="el" href="structyaml__event__s.html#a0b8f9cce08e49459e4bab89035dbf6c6">yaml_event_s</a>
+, <a class="el" href="structyaml__node__s.html#a7e1be921e921f2d0911e450a063b1344">yaml_node_s</a>
+</li>
+<li>document
+: <a class="el" href="structyaml__emitter__s.html#af9cc8801cc9b46a4f45255c67a1574a7">yaml_emitter_s</a>
+, <a class="el" href="structyaml__parser__s.html#ac3dad5822f49d86cfddc2e5e415a158c">yaml_parser_s</a>
+</li>
+<li>document_end
+: <a class="el" href="structyaml__event__s.html#acffec5f24c01bb6bfb0c93a9bf1a803e">yaml_event_s</a>
+</li>
+<li>document_start
+: <a class="el" href="structyaml__event__s.html#aed593fadbeb898d6d90b0c62522a82cc">yaml_event_s</a>
+</li>
+</ul>
+</div>
+<hr class="footer"/><address class="footer"><small>Generated on Mon May 30 2011 22:00:00 for yaml by&nbsp;
+<a href="http://www.doxygen.org/index.html">
+<img class="footer" src="doxygen.png" alt="doxygen"/></a> 1.7.1 </small></address>
+</body>
+</html>
diff --git a/contrib/libyaml/doc/html/functions_vars_0x65.html b/contrib/libyaml/doc/html/functions_vars_0x65.html
new file mode 100644
index 0000000..97f2269
--- /dev/null
+++ b/contrib/libyaml/doc/html/functions_vars_0x65.html
@@ -0,0 +1,110 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head>
+<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/>
+<title>yaml: Data Fields - Variables</title>
+<link href="tabs.css" rel="stylesheet" type="text/css"/>
+<link href="doxygen.css" rel="stylesheet" type="text/css"/>
+</head>
+<body>
+<!-- Generated by Doxygen 1.7.1 -->
+<div class="navigation" id="top">
+ <div class="tabs">
+ <ul class="tablist">
+ <li><a href="index.html"><span>Main&nbsp;Page</span></a></li>
+ <li><a href="modules.html"><span>Modules</span></a></li>
+ <li class="current"><a href="annotated.html"><span>Data&nbsp;Structures</span></a></li>
+ <li><a href="files.html"><span>Files</span></a></li>
+ </ul>
+ </div>
+ <div class="tabs2">
+ <ul class="tablist">
+ <li><a href="annotated.html"><span>Data&nbsp;Structures</span></a></li>
+ <li class="current"><a href="functions.html"><span>Data&nbsp;Fields</span></a></li>
+ </ul>
+ </div>
+ <div class="tabs2">
+ <ul class="tablist">
+ <li><a href="functions.html"><span>All</span></a></li>
+ <li class="current"><a href="functions_vars.html"><span>Variables</span></a></li>
+ </ul>
+ </div>
+ <div class="tabs3">
+ <ul class="tablist">
+ <li><a href="functions_vars.html#index_a"><span>a</span></a></li>
+ <li><a href="functions_vars_0x62.html#index_b"><span>b</span></a></li>
+ <li><a href="functions_vars_0x63.html#index_c"><span>c</span></a></li>
+ <li><a href="functions_vars_0x64.html#index_d"><span>d</span></a></li>
+ <li class="current"><a href="functions_vars_0x65.html#index_e"><span>e</span></a></li>
+ <li><a href="functions_vars_0x66.html#index_f"><span>f</span></a></li>
+ <li><a href="functions_vars_0x68.html#index_h"><span>h</span></a></li>
+ <li><a href="functions_vars_0x69.html#index_i"><span>i</span></a></li>
+ <li><a href="functions_vars_0x6b.html#index_k"><span>k</span></a></li>
+ <li><a href="functions_vars_0x6c.html#index_l"><span>l</span></a></li>
+ <li><a href="functions_vars_0x6d.html#index_m"><span>m</span></a></li>
+ <li><a href="functions_vars_0x6e.html#index_n"><span>n</span></a></li>
+ <li><a href="functions_vars_0x6f.html#index_o"><span>o</span></a></li>
+ <li><a href="functions_vars_0x70.html#index_p"><span>p</span></a></li>
+ <li><a href="functions_vars_0x71.html#index_q"><span>q</span></a></li>
+ <li><a href="functions_vars_0x72.html#index_r"><span>r</span></a></li>
+ <li><a href="functions_vars_0x73.html#index_s"><span>s</span></a></li>
+ <li><a href="functions_vars_0x74.html#index_t"><span>t</span></a></li>
+ <li><a href="functions_vars_0x75.html#index_u"><span>u</span></a></li>
+ <li><a href="functions_vars_0x76.html#index_v"><span>v</span></a></li>
+ <li><a href="functions_vars_0x77.html#index_w"><span>w</span></a></li>
+ </ul>
+ </div>
+</div>
+<div class="contents">
+&nbsp;
+
+<h3><a class="anchor" id="index_e"></a>- e -</h3><ul>
+<li>encoding
+: <a class="el" href="structyaml__token__s.html#aab75b9cb91438e0e1efe2522652cf478">yaml_token_s</a>
+, <a class="el" href="structyaml__event__s.html#a92139ba6ae79089fd9a2f5f4aeaf733f">yaml_event_s</a>
+, <a class="el" href="structyaml__emitter__s.html#ada17f19fa6248d6ee493684b03700857">yaml_emitter_s</a>
+, <a class="el" href="structyaml__parser__s.html#a4f062e9d1fb1082bbf3996e46214905a">yaml_parser_s</a>
+</li>
+<li>end
+: <a class="el" href="structyaml__document__s.html#adc9ffcca86a2684362428da69ffd3dea">yaml_document_s</a>
+, <a class="el" href="structyaml__parser__s.html#a211a0aedc964ba8cd07cb7875faa464b">yaml_parser_s</a>
+, <a class="el" href="structyaml__document__s.html#af14fd1a6c1fd10088391f07349ba55e8">yaml_document_s</a>
+, <a class="el" href="structyaml__parser__s.html#aa7fdc1ff8342636119934ac824a2ecc8">yaml_parser_s</a>
+, <a class="el" href="structyaml__emitter__s.html#a3b28127063323de1d88fc18cdb6adf8a">yaml_emitter_s</a>
+, <a class="el" href="structyaml__event__s.html#a115b4a9797f3a72cd78d42c85100317c">yaml_event_s</a>
+, <a class="el" href="structyaml__emitter__s.html#a55703a15e71c6b9551a2f4feb888bdcb">yaml_emitter_s</a>
+, <a class="el" href="structyaml__parser__s.html#aad74ffeb7f2eef0a12e34b0aac263ff3">yaml_parser_s</a>
+, <a class="el" href="structyaml__emitter__s.html#a42285849529f1b0eb9f4aac2eaef5204">yaml_emitter_s</a>
+, <a class="el" href="structyaml__parser__s.html#a6ff1f802eb95bc45f13e8e73ec009828">yaml_parser_s</a>
+, <a class="el" href="structyaml__node__s.html#ac9b3d891f9fcd5462289823716deca0e">yaml_node_s</a>
+, <a class="el" href="structyaml__parser__s.html#aa768a9c29ae2c3015fdb84ea313844e2">yaml_parser_s</a>
+, <a class="el" href="structyaml__emitter__s.html#a6669a94bc18247491e59c709852be0d1">yaml_emitter_s</a>
+, <a class="el" href="structyaml__parser__s.html#a41594b6495f4d31edb977cafb8cbaf78">yaml_parser_s</a>
+, <a class="el" href="structyaml__node__s.html#a1827ba7f3e7f7e94171fa20ade25345d">yaml_node_s</a>
+</li>
+<li>end_implicit
+: <a class="el" href="structyaml__document__s.html#a59de90b4078659fd0f49377929afcac1">yaml_document_s</a>
+</li>
+<li>end_mark
+: <a class="el" href="structyaml__event__s.html#a9307f91473094c229738b03d223bc4ba">yaml_event_s</a>
+, <a class="el" href="structyaml__node__s.html#a63144671fd16f94f72c6d537360f7328">yaml_node_s</a>
+, <a class="el" href="structyaml__token__s.html#a97f08b38dfb0a5be26ef8831864a5311">yaml_token_s</a>
+, <a class="el" href="structyaml__document__s.html#a9299efdaadf764f4d03641a3ee51e0d0">yaml_document_s</a>
+</li>
+<li>eof
+: <a class="el" href="structyaml__parser__s.html#a6129a99d45aee14ec705aa54dbb493b7">yaml_parser_s</a>
+</li>
+<li>error
+: <a class="el" href="structyaml__emitter__s.html#afa2d6367a86ae6d43df14e24479bb0a7">yaml_emitter_s</a>
+, <a class="el" href="structyaml__parser__s.html#a6c5c3488ff22c8a4d234ca8587fa1472">yaml_parser_s</a>
+</li>
+<li>events
+: <a class="el" href="structyaml__emitter__s.html#a3516b49eb7579e422750a94a9d7c1700">yaml_emitter_s</a>
+</li>
+</ul>
+</div>
+<hr class="footer"/><address class="footer"><small>Generated on Mon May 30 2011 22:00:00 for yaml by&nbsp;
+<a href="http://www.doxygen.org/index.html">
+<img class="footer" src="doxygen.png" alt="doxygen"/></a> 1.7.1 </small></address>
+</body>
+</html>
diff --git a/contrib/libyaml/doc/html/functions_vars_0x66.html b/contrib/libyaml/doc/html/functions_vars_0x66.html
new file mode 100644
index 0000000..bee0ee0
--- /dev/null
+++ b/contrib/libyaml/doc/html/functions_vars_0x66.html
@@ -0,0 +1,79 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head>
+<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/>
+<title>yaml: Data Fields - Variables</title>
+<link href="tabs.css" rel="stylesheet" type="text/css"/>
+<link href="doxygen.css" rel="stylesheet" type="text/css"/>
+</head>
+<body>
+<!-- Generated by Doxygen 1.7.1 -->
+<div class="navigation" id="top">
+ <div class="tabs">
+ <ul class="tablist">
+ <li><a href="index.html"><span>Main&nbsp;Page</span></a></li>
+ <li><a href="modules.html"><span>Modules</span></a></li>
+ <li class="current"><a href="annotated.html"><span>Data&nbsp;Structures</span></a></li>
+ <li><a href="files.html"><span>Files</span></a></li>
+ </ul>
+ </div>
+ <div class="tabs2">
+ <ul class="tablist">
+ <li><a href="annotated.html"><span>Data&nbsp;Structures</span></a></li>
+ <li class="current"><a href="functions.html"><span>Data&nbsp;Fields</span></a></li>
+ </ul>
+ </div>
+ <div class="tabs2">
+ <ul class="tablist">
+ <li><a href="functions.html"><span>All</span></a></li>
+ <li class="current"><a href="functions_vars.html"><span>Variables</span></a></li>
+ </ul>
+ </div>
+ <div class="tabs3">
+ <ul class="tablist">
+ <li><a href="functions_vars.html#index_a"><span>a</span></a></li>
+ <li><a href="functions_vars_0x62.html#index_b"><span>b</span></a></li>
+ <li><a href="functions_vars_0x63.html#index_c"><span>c</span></a></li>
+ <li><a href="functions_vars_0x64.html#index_d"><span>d</span></a></li>
+ <li><a href="functions_vars_0x65.html#index_e"><span>e</span></a></li>
+ <li class="current"><a href="functions_vars_0x66.html#index_f"><span>f</span></a></li>
+ <li><a href="functions_vars_0x68.html#index_h"><span>h</span></a></li>
+ <li><a href="functions_vars_0x69.html#index_i"><span>i</span></a></li>
+ <li><a href="functions_vars_0x6b.html#index_k"><span>k</span></a></li>
+ <li><a href="functions_vars_0x6c.html#index_l"><span>l</span></a></li>
+ <li><a href="functions_vars_0x6d.html#index_m"><span>m</span></a></li>
+ <li><a href="functions_vars_0x6e.html#index_n"><span>n</span></a></li>
+ <li><a href="functions_vars_0x6f.html#index_o"><span>o</span></a></li>
+ <li><a href="functions_vars_0x70.html#index_p"><span>p</span></a></li>
+ <li><a href="functions_vars_0x71.html#index_q"><span>q</span></a></li>
+ <li><a href="functions_vars_0x72.html#index_r"><span>r</span></a></li>
+ <li><a href="functions_vars_0x73.html#index_s"><span>s</span></a></li>
+ <li><a href="functions_vars_0x74.html#index_t"><span>t</span></a></li>
+ <li><a href="functions_vars_0x75.html#index_u"><span>u</span></a></li>
+ <li><a href="functions_vars_0x76.html#index_v"><span>v</span></a></li>
+ <li><a href="functions_vars_0x77.html#index_w"><span>w</span></a></li>
+ </ul>
+ </div>
+</div>
+<div class="contents">
+&nbsp;
+
+<h3><a class="anchor" id="index_f"></a>- f -</h3><ul>
+<li>file
+: <a class="el" href="structyaml__parser__s.html#ae69c2974e3c4c37e941a0e1971be15a9">yaml_parser_s</a>
+, <a class="el" href="structyaml__emitter__s.html#abfe1e82cd5c4a180b1468e65ccfd1c61">yaml_emitter_s</a>
+</li>
+<li>flow_level
+: <a class="el" href="structyaml__emitter__s.html#a50f8e97c4290b83ebd646b4c4f5c5de9">yaml_emitter_s</a>
+, <a class="el" href="structyaml__parser__s.html#a6a4bbbd3f58533e0969b7218c1e73fd4">yaml_parser_s</a>
+</li>
+<li>flow_plain_allowed
+: <a class="el" href="structyaml__emitter__s.html#afd8496f5bb995bb5aacc349fd6b45bf5">yaml_emitter_s</a>
+</li>
+</ul>
+</div>
+<hr class="footer"/><address class="footer"><small>Generated on Mon May 30 2011 22:00:00 for yaml by&nbsp;
+<a href="http://www.doxygen.org/index.html">
+<img class="footer" src="doxygen.png" alt="doxygen"/></a> 1.7.1 </small></address>
+</body>
+</html>
diff --git a/contrib/libyaml/doc/html/functions_vars_0x68.html b/contrib/libyaml/doc/html/functions_vars_0x68.html
new file mode 100644
index 0000000..bda8dc8
--- /dev/null
+++ b/contrib/libyaml/doc/html/functions_vars_0x68.html
@@ -0,0 +1,80 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head>
+<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/>
+<title>yaml: Data Fields - Variables</title>
+<link href="tabs.css" rel="stylesheet" type="text/css"/>
+<link href="doxygen.css" rel="stylesheet" type="text/css"/>
+</head>
+<body>
+<!-- Generated by Doxygen 1.7.1 -->
+<div class="navigation" id="top">
+ <div class="tabs">
+ <ul class="tablist">
+ <li><a href="index.html"><span>Main&nbsp;Page</span></a></li>
+ <li><a href="modules.html"><span>Modules</span></a></li>
+ <li class="current"><a href="annotated.html"><span>Data&nbsp;Structures</span></a></li>
+ <li><a href="files.html"><span>Files</span></a></li>
+ </ul>
+ </div>
+ <div class="tabs2">
+ <ul class="tablist">
+ <li><a href="annotated.html"><span>Data&nbsp;Structures</span></a></li>
+ <li class="current"><a href="functions.html"><span>Data&nbsp;Fields</span></a></li>
+ </ul>
+ </div>
+ <div class="tabs2">
+ <ul class="tablist">
+ <li><a href="functions.html"><span>All</span></a></li>
+ <li class="current"><a href="functions_vars.html"><span>Variables</span></a></li>
+ </ul>
+ </div>
+ <div class="tabs3">
+ <ul class="tablist">
+ <li><a href="functions_vars.html#index_a"><span>a</span></a></li>
+ <li><a href="functions_vars_0x62.html#index_b"><span>b</span></a></li>
+ <li><a href="functions_vars_0x63.html#index_c"><span>c</span></a></li>
+ <li><a href="functions_vars_0x64.html#index_d"><span>d</span></a></li>
+ <li><a href="functions_vars_0x65.html#index_e"><span>e</span></a></li>
+ <li><a href="functions_vars_0x66.html#index_f"><span>f</span></a></li>
+ <li class="current"><a href="functions_vars_0x68.html#index_h"><span>h</span></a></li>
+ <li><a href="functions_vars_0x69.html#index_i"><span>i</span></a></li>
+ <li><a href="functions_vars_0x6b.html#index_k"><span>k</span></a></li>
+ <li><a href="functions_vars_0x6c.html#index_l"><span>l</span></a></li>
+ <li><a href="functions_vars_0x6d.html#index_m"><span>m</span></a></li>
+ <li><a href="functions_vars_0x6e.html#index_n"><span>n</span></a></li>
+ <li><a href="functions_vars_0x6f.html#index_o"><span>o</span></a></li>
+ <li><a href="functions_vars_0x70.html#index_p"><span>p</span></a></li>
+ <li><a href="functions_vars_0x71.html#index_q"><span>q</span></a></li>
+ <li><a href="functions_vars_0x72.html#index_r"><span>r</span></a></li>
+ <li><a href="functions_vars_0x73.html#index_s"><span>s</span></a></li>
+ <li><a href="functions_vars_0x74.html#index_t"><span>t</span></a></li>
+ <li><a href="functions_vars_0x75.html#index_u"><span>u</span></a></li>
+ <li><a href="functions_vars_0x76.html#index_v"><span>v</span></a></li>
+ <li><a href="functions_vars_0x77.html#index_w"><span>w</span></a></li>
+ </ul>
+ </div>
+</div>
+<div class="contents">
+&nbsp;
+
+<h3><a class="anchor" id="index_h"></a>- h -</h3><ul>
+<li>handle
+: <a class="el" href="structyaml__tag__directive__s.html#a9934c62f2b18fd087a95af25c7739490">yaml_tag_directive_s</a>
+, <a class="el" href="structyaml__token__s.html#a01665687653c945a6666dd9debaecd65">yaml_token_s</a>
+, <a class="el" href="structyaml__emitter__s.html#a7f043a9092eef2d644cc8f1180386239">yaml_emitter_s</a>
+</li>
+<li>handle_length
+: <a class="el" href="structyaml__emitter__s.html#a3552cece6908f99518205e8cbe2c793a">yaml_emitter_s</a>
+</li>
+<li>head
+: <a class="el" href="structyaml__parser__s.html#aa1c7a1248ca22159a3e60ba45b386507">yaml_parser_s</a>
+, <a class="el" href="structyaml__emitter__s.html#a547dfd20576006e606ffb0d8042b4234">yaml_emitter_s</a>
+</li>
+</ul>
+</div>
+<hr class="footer"/><address class="footer"><small>Generated on Mon May 30 2011 22:00:00 for yaml by&nbsp;
+<a href="http://www.doxygen.org/index.html">
+<img class="footer" src="doxygen.png" alt="doxygen"/></a> 1.7.1 </small></address>
+</body>
+</html>
diff --git a/contrib/libyaml/doc/html/functions_vars_0x69.html b/contrib/libyaml/doc/html/functions_vars_0x69.html
new file mode 100644
index 0000000..92e1376
--- /dev/null
+++ b/contrib/libyaml/doc/html/functions_vars_0x69.html
@@ -0,0 +1,92 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head>
+<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/>
+<title>yaml: Data Fields - Variables</title>
+<link href="tabs.css" rel="stylesheet" type="text/css"/>
+<link href="doxygen.css" rel="stylesheet" type="text/css"/>
+</head>
+<body>
+<!-- Generated by Doxygen 1.7.1 -->
+<div class="navigation" id="top">
+ <div class="tabs">
+ <ul class="tablist">
+ <li><a href="index.html"><span>Main&nbsp;Page</span></a></li>
+ <li><a href="modules.html"><span>Modules</span></a></li>
+ <li class="current"><a href="annotated.html"><span>Data&nbsp;Structures</span></a></li>
+ <li><a href="files.html"><span>Files</span></a></li>
+ </ul>
+ </div>
+ <div class="tabs2">
+ <ul class="tablist">
+ <li><a href="annotated.html"><span>Data&nbsp;Structures</span></a></li>
+ <li class="current"><a href="functions.html"><span>Data&nbsp;Fields</span></a></li>
+ </ul>
+ </div>
+ <div class="tabs2">
+ <ul class="tablist">
+ <li><a href="functions.html"><span>All</span></a></li>
+ <li class="current"><a href="functions_vars.html"><span>Variables</span></a></li>
+ </ul>
+ </div>
+ <div class="tabs3">
+ <ul class="tablist">
+ <li><a href="functions_vars.html#index_a"><span>a</span></a></li>
+ <li><a href="functions_vars_0x62.html#index_b"><span>b</span></a></li>
+ <li><a href="functions_vars_0x63.html#index_c"><span>c</span></a></li>
+ <li><a href="functions_vars_0x64.html#index_d"><span>d</span></a></li>
+ <li><a href="functions_vars_0x65.html#index_e"><span>e</span></a></li>
+ <li><a href="functions_vars_0x66.html#index_f"><span>f</span></a></li>
+ <li><a href="functions_vars_0x68.html#index_h"><span>h</span></a></li>
+ <li class="current"><a href="functions_vars_0x69.html#index_i"><span>i</span></a></li>
+ <li><a href="functions_vars_0x6b.html#index_k"><span>k</span></a></li>
+ <li><a href="functions_vars_0x6c.html#index_l"><span>l</span></a></li>
+ <li><a href="functions_vars_0x6d.html#index_m"><span>m</span></a></li>
+ <li><a href="functions_vars_0x6e.html#index_n"><span>n</span></a></li>
+ <li><a href="functions_vars_0x6f.html#index_o"><span>o</span></a></li>
+ <li><a href="functions_vars_0x70.html#index_p"><span>p</span></a></li>
+ <li><a href="functions_vars_0x71.html#index_q"><span>q</span></a></li>
+ <li><a href="functions_vars_0x72.html#index_r"><span>r</span></a></li>
+ <li><a href="functions_vars_0x73.html#index_s"><span>s</span></a></li>
+ <li><a href="functions_vars_0x74.html#index_t"><span>t</span></a></li>
+ <li><a href="functions_vars_0x75.html#index_u"><span>u</span></a></li>
+ <li><a href="functions_vars_0x76.html#index_v"><span>v</span></a></li>
+ <li><a href="functions_vars_0x77.html#index_w"><span>w</span></a></li>
+ </ul>
+ </div>
+</div>
+<div class="contents">
+&nbsp;
+
+<h3><a class="anchor" id="index_i"></a>- i -</h3><ul>
+<li>implicit
+: <a class="el" href="structyaml__event__s.html#a3cbb10e276d55890ee2fa802dd6290e1">yaml_event_s</a>
+</li>
+<li>indent
+: <a class="el" href="structyaml__parser__s.html#abad00703b649df32ee0d7b00b2f10403">yaml_parser_s</a>
+, <a class="el" href="structyaml__emitter__s.html#a93a73494a5d62464a67cc71f86ad9728">yaml_emitter_s</a>
+</li>
+<li>indention
+: <a class="el" href="structyaml__emitter__s.html#a407de8ff950b16b4254a381d4e5cea42">yaml_emitter_s</a>
+</li>
+<li>indents
+: <a class="el" href="structyaml__parser__s.html#a2e29feac36a89f644d9640d44df62b74">yaml_parser_s</a>
+, <a class="el" href="structyaml__emitter__s.html#ad31c591593ccb78e6b04887bf4f162c8">yaml_emitter_s</a>
+</li>
+<li>index
+: <a class="el" href="structyaml__mark__s.html#a525306fb424a79f0b0d5a7d3990aa596">yaml_mark_s</a>
+, <a class="el" href="structyaml__alias__data__s.html#ac45e17508386dec9163b4aa5cfb5312e">yaml_alias_data_s</a>
+</li>
+<li>input
+: <a class="el" href="structyaml__parser__s.html#ae800ef7fd42ad8bcbb69b116da3a7f53">yaml_parser_s</a>
+</li>
+<li>items
+: <a class="el" href="structyaml__node__s.html#a6b340541cc012ac5aacdcaa46ced097a">yaml_node_s</a>
+</li>
+</ul>
+</div>
+<hr class="footer"/><address class="footer"><small>Generated on Mon May 30 2011 22:00:00 for yaml by&nbsp;
+<a href="http://www.doxygen.org/index.html">
+<img class="footer" src="doxygen.png" alt="doxygen"/></a> 1.7.1 </small></address>
+</body>
+</html>
diff --git a/contrib/libyaml/doc/html/functions_vars_0x6b.html b/contrib/libyaml/doc/html/functions_vars_0x6b.html
new file mode 100644
index 0000000..14231ce
--- /dev/null
+++ b/contrib/libyaml/doc/html/functions_vars_0x6b.html
@@ -0,0 +1,71 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head>
+<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/>
+<title>yaml: Data Fields - Variables</title>
+<link href="tabs.css" rel="stylesheet" type="text/css"/>
+<link href="doxygen.css" rel="stylesheet" type="text/css"/>
+</head>
+<body>
+<!-- Generated by Doxygen 1.7.1 -->
+<div class="navigation" id="top">
+ <div class="tabs">
+ <ul class="tablist">
+ <li><a href="index.html"><span>Main&nbsp;Page</span></a></li>
+ <li><a href="modules.html"><span>Modules</span></a></li>
+ <li class="current"><a href="annotated.html"><span>Data&nbsp;Structures</span></a></li>
+ <li><a href="files.html"><span>Files</span></a></li>
+ </ul>
+ </div>
+ <div class="tabs2">
+ <ul class="tablist">
+ <li><a href="annotated.html"><span>Data&nbsp;Structures</span></a></li>
+ <li class="current"><a href="functions.html"><span>Data&nbsp;Fields</span></a></li>
+ </ul>
+ </div>
+ <div class="tabs2">
+ <ul class="tablist">
+ <li><a href="functions.html"><span>All</span></a></li>
+ <li class="current"><a href="functions_vars.html"><span>Variables</span></a></li>
+ </ul>
+ </div>
+ <div class="tabs3">
+ <ul class="tablist">
+ <li><a href="functions_vars.html#index_a"><span>a</span></a></li>
+ <li><a href="functions_vars_0x62.html#index_b"><span>b</span></a></li>
+ <li><a href="functions_vars_0x63.html#index_c"><span>c</span></a></li>
+ <li><a href="functions_vars_0x64.html#index_d"><span>d</span></a></li>
+ <li><a href="functions_vars_0x65.html#index_e"><span>e</span></a></li>
+ <li><a href="functions_vars_0x66.html#index_f"><span>f</span></a></li>
+ <li><a href="functions_vars_0x68.html#index_h"><span>h</span></a></li>
+ <li><a href="functions_vars_0x69.html#index_i"><span>i</span></a></li>
+ <li class="current"><a href="functions_vars_0x6b.html#index_k"><span>k</span></a></li>
+ <li><a href="functions_vars_0x6c.html#index_l"><span>l</span></a></li>
+ <li><a href="functions_vars_0x6d.html#index_m"><span>m</span></a></li>
+ <li><a href="functions_vars_0x6e.html#index_n"><span>n</span></a></li>
+ <li><a href="functions_vars_0x6f.html#index_o"><span>o</span></a></li>
+ <li><a href="functions_vars_0x70.html#index_p"><span>p</span></a></li>
+ <li><a href="functions_vars_0x71.html#index_q"><span>q</span></a></li>
+ <li><a href="functions_vars_0x72.html#index_r"><span>r</span></a></li>
+ <li><a href="functions_vars_0x73.html#index_s"><span>s</span></a></li>
+ <li><a href="functions_vars_0x74.html#index_t"><span>t</span></a></li>
+ <li><a href="functions_vars_0x75.html#index_u"><span>u</span></a></li>
+ <li><a href="functions_vars_0x76.html#index_v"><span>v</span></a></li>
+ <li><a href="functions_vars_0x77.html#index_w"><span>w</span></a></li>
+ </ul>
+ </div>
+</div>
+<div class="contents">
+&nbsp;
+
+<h3><a class="anchor" id="index_k"></a>- k -</h3><ul>
+<li>key
+: <a class="el" href="structyaml__node__pair__s.html#ac83746eb40b6b3a84f6da3143658ed4e">yaml_node_pair_s</a>
+</li>
+</ul>
+</div>
+<hr class="footer"/><address class="footer"><small>Generated on Mon May 30 2011 22:00:00 for yaml by&nbsp;
+<a href="http://www.doxygen.org/index.html">
+<img class="footer" src="doxygen.png" alt="doxygen"/></a> 1.7.1 </small></address>
+</body>
+</html>
diff --git a/contrib/libyaml/doc/html/functions_vars_0x6c.html b/contrib/libyaml/doc/html/functions_vars_0x6c.html
new file mode 100644
index 0000000..ae53df5
--- /dev/null
+++ b/contrib/libyaml/doc/html/functions_vars_0x6c.html
@@ -0,0 +1,88 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head>
+<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/>
+<title>yaml: Data Fields - Variables</title>
+<link href="tabs.css" rel="stylesheet" type="text/css"/>
+<link href="doxygen.css" rel="stylesheet" type="text/css"/>
+</head>
+<body>
+<!-- Generated by Doxygen 1.7.1 -->
+<div class="navigation" id="top">
+ <div class="tabs">
+ <ul class="tablist">
+ <li><a href="index.html"><span>Main&nbsp;Page</span></a></li>
+ <li><a href="modules.html"><span>Modules</span></a></li>
+ <li class="current"><a href="annotated.html"><span>Data&nbsp;Structures</span></a></li>
+ <li><a href="files.html"><span>Files</span></a></li>
+ </ul>
+ </div>
+ <div class="tabs2">
+ <ul class="tablist">
+ <li><a href="annotated.html"><span>Data&nbsp;Structures</span></a></li>
+ <li class="current"><a href="functions.html"><span>Data&nbsp;Fields</span></a></li>
+ </ul>
+ </div>
+ <div class="tabs2">
+ <ul class="tablist">
+ <li><a href="functions.html"><span>All</span></a></li>
+ <li class="current"><a href="functions_vars.html"><span>Variables</span></a></li>
+ </ul>
+ </div>
+ <div class="tabs3">
+ <ul class="tablist">
+ <li><a href="functions_vars.html#index_a"><span>a</span></a></li>
+ <li><a href="functions_vars_0x62.html#index_b"><span>b</span></a></li>
+ <li><a href="functions_vars_0x63.html#index_c"><span>c</span></a></li>
+ <li><a href="functions_vars_0x64.html#index_d"><span>d</span></a></li>
+ <li><a href="functions_vars_0x65.html#index_e"><span>e</span></a></li>
+ <li><a href="functions_vars_0x66.html#index_f"><span>f</span></a></li>
+ <li><a href="functions_vars_0x68.html#index_h"><span>h</span></a></li>
+ <li><a href="functions_vars_0x69.html#index_i"><span>i</span></a></li>
+ <li><a href="functions_vars_0x6b.html#index_k"><span>k</span></a></li>
+ <li class="current"><a href="functions_vars_0x6c.html#index_l"><span>l</span></a></li>
+ <li><a href="functions_vars_0x6d.html#index_m"><span>m</span></a></li>
+ <li><a href="functions_vars_0x6e.html#index_n"><span>n</span></a></li>
+ <li><a href="functions_vars_0x6f.html#index_o"><span>o</span></a></li>
+ <li><a href="functions_vars_0x70.html#index_p"><span>p</span></a></li>
+ <li><a href="functions_vars_0x71.html#index_q"><span>q</span></a></li>
+ <li><a href="functions_vars_0x72.html#index_r"><span>r</span></a></li>
+ <li><a href="functions_vars_0x73.html#index_s"><span>s</span></a></li>
+ <li><a href="functions_vars_0x74.html#index_t"><span>t</span></a></li>
+ <li><a href="functions_vars_0x75.html#index_u"><span>u</span></a></li>
+ <li><a href="functions_vars_0x76.html#index_v"><span>v</span></a></li>
+ <li><a href="functions_vars_0x77.html#index_w"><span>w</span></a></li>
+ </ul>
+ </div>
+</div>
+<div class="contents">
+&nbsp;
+
+<h3><a class="anchor" id="index_l"></a>- l -</h3><ul>
+<li>last
+: <a class="el" href="structyaml__parser__s.html#aea4d8da24939825b2fadd368a71ec7de">yaml_parser_s</a>
+, <a class="el" href="structyaml__emitter__s.html#ad0c5410fff4602266a0c6e0af730dd70">yaml_emitter_s</a>
+</li>
+<li>last_anchor_id
+: <a class="el" href="structyaml__emitter__s.html#a0cede830c77a15df7f1b73b9023d2d11">yaml_emitter_s</a>
+</li>
+<li>length
+: <a class="el" href="structyaml__emitter__s.html#a4f72d57ad020803803e78922ecdec580">yaml_emitter_s</a>
+, <a class="el" href="structyaml__event__s.html#a15618ee917746d28d97ad8eb9639e141">yaml_event_s</a>
+, <a class="el" href="structyaml__node__s.html#ad90dd9926d9debbaa48eb5339bd9fc36">yaml_node_s</a>
+, <a class="el" href="structyaml__token__s.html#a06e51daf74cf78103e00608c3c9132e2">yaml_token_s</a>
+</li>
+<li>line
+: <a class="el" href="structyaml__mark__s.html#a55952e426fc8a5f180a5e9c907ca926c">yaml_mark_s</a>
+, <a class="el" href="structyaml__emitter__s.html#a4fe9295608f19a687e41ec3661383e88">yaml_emitter_s</a>
+</li>
+<li>line_break
+: <a class="el" href="structyaml__emitter__s.html#a84c1b884d805588495067ee98a8e7c50">yaml_emitter_s</a>
+</li>
+</ul>
+</div>
+<hr class="footer"/><address class="footer"><small>Generated on Mon May 30 2011 22:00:00 for yaml by&nbsp;
+<a href="http://www.doxygen.org/index.html">
+<img class="footer" src="doxygen.png" alt="doxygen"/></a> 1.7.1 </small></address>
+</body>
+</html>
diff --git a/contrib/libyaml/doc/html/functions_vars_0x6d.html b/contrib/libyaml/doc/html/functions_vars_0x6d.html
new file mode 100644
index 0000000..63919e1
--- /dev/null
+++ b/contrib/libyaml/doc/html/functions_vars_0x6d.html
@@ -0,0 +1,96 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head>
+<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/>
+<title>yaml: Data Fields - Variables</title>
+<link href="tabs.css" rel="stylesheet" type="text/css"/>
+<link href="doxygen.css" rel="stylesheet" type="text/css"/>
+</head>
+<body>
+<!-- Generated by Doxygen 1.7.1 -->
+<div class="navigation" id="top">
+ <div class="tabs">
+ <ul class="tablist">
+ <li><a href="index.html"><span>Main&nbsp;Page</span></a></li>
+ <li><a href="modules.html"><span>Modules</span></a></li>
+ <li class="current"><a href="annotated.html"><span>Data&nbsp;Structures</span></a></li>
+ <li><a href="files.html"><span>Files</span></a></li>
+ </ul>
+ </div>
+ <div class="tabs2">
+ <ul class="tablist">
+ <li><a href="annotated.html"><span>Data&nbsp;Structures</span></a></li>
+ <li class="current"><a href="functions.html"><span>Data&nbsp;Fields</span></a></li>
+ </ul>
+ </div>
+ <div class="tabs2">
+ <ul class="tablist">
+ <li><a href="functions.html"><span>All</span></a></li>
+ <li class="current"><a href="functions_vars.html"><span>Variables</span></a></li>
+ </ul>
+ </div>
+ <div class="tabs3">
+ <ul class="tablist">
+ <li><a href="functions_vars.html#index_a"><span>a</span></a></li>
+ <li><a href="functions_vars_0x62.html#index_b"><span>b</span></a></li>
+ <li><a href="functions_vars_0x63.html#index_c"><span>c</span></a></li>
+ <li><a href="functions_vars_0x64.html#index_d"><span>d</span></a></li>
+ <li><a href="functions_vars_0x65.html#index_e"><span>e</span></a></li>
+ <li><a href="functions_vars_0x66.html#index_f"><span>f</span></a></li>
+ <li><a href="functions_vars_0x68.html#index_h"><span>h</span></a></li>
+ <li><a href="functions_vars_0x69.html#index_i"><span>i</span></a></li>
+ <li><a href="functions_vars_0x6b.html#index_k"><span>k</span></a></li>
+ <li><a href="functions_vars_0x6c.html#index_l"><span>l</span></a></li>
+ <li class="current"><a href="functions_vars_0x6d.html#index_m"><span>m</span></a></li>
+ <li><a href="functions_vars_0x6e.html#index_n"><span>n</span></a></li>
+ <li><a href="functions_vars_0x6f.html#index_o"><span>o</span></a></li>
+ <li><a href="functions_vars_0x70.html#index_p"><span>p</span></a></li>
+ <li><a href="functions_vars_0x71.html#index_q"><span>q</span></a></li>
+ <li><a href="functions_vars_0x72.html#index_r"><span>r</span></a></li>
+ <li><a href="functions_vars_0x73.html#index_s"><span>s</span></a></li>
+ <li><a href="functions_vars_0x74.html#index_t"><span>t</span></a></li>
+ <li><a href="functions_vars_0x75.html#index_u"><span>u</span></a></li>
+ <li><a href="functions_vars_0x76.html#index_v"><span>v</span></a></li>
+ <li><a href="functions_vars_0x77.html#index_w"><span>w</span></a></li>
+ </ul>
+ </div>
+</div>
+<div class="contents">
+&nbsp;
+
+<h3><a class="anchor" id="index_m"></a>- m -</h3><ul>
+<li>major
+: <a class="el" href="structyaml__version__directive__s.html#ad27326ff94b7772027c3009d1dd5e52b">yaml_version_directive_s</a>
+, <a class="el" href="structyaml__token__s.html#aac2ed466afd0390872774238dfcd152c">yaml_token_s</a>
+</li>
+<li>mapping
+: <a class="el" href="structyaml__node__s.html#ab18dc5c573885a08a92e113dcb7fb361">yaml_node_s</a>
+</li>
+<li>mapping_context
+: <a class="el" href="structyaml__emitter__s.html#a5a7527d8da86b28d95ff18b29f9d82f0">yaml_emitter_s</a>
+</li>
+<li>mapping_start
+: <a class="el" href="structyaml__event__s.html#a361b28413783f92797e6bfe03e9abaa1">yaml_event_s</a>
+</li>
+<li>mark
+: <a class="el" href="structyaml__parser__s.html#aaeeb58dc348e6e6f89d6a7c8fea8f734">yaml_parser_s</a>
+, <a class="el" href="structyaml__alias__data__s.html#a9f8d87255bfc39df69068ed87b602e9f">yaml_alias_data_s</a>
+, <a class="el" href="structyaml__simple__key__s.html#ad0f5dd11cbf2e4d6d81376511e2b6dfb">yaml_simple_key_s</a>
+</li>
+<li>marks
+: <a class="el" href="structyaml__parser__s.html#ad78837ae36e35d523e02c43d1ae3f30e">yaml_parser_s</a>
+</li>
+<li>minor
+: <a class="el" href="structyaml__version__directive__s.html#a89f074113501e6e150503f34b046dbd1">yaml_version_directive_s</a>
+, <a class="el" href="structyaml__token__s.html#a97b9f537b24e8413e9fddc6a4b183d30">yaml_token_s</a>
+</li>
+<li>multiline
+: <a class="el" href="structyaml__emitter__s.html#a363a1aaaf512433ee7eab3083428cc70">yaml_emitter_s</a>
+</li>
+</ul>
+</div>
+<hr class="footer"/><address class="footer"><small>Generated on Mon May 30 2011 22:00:00 for yaml by&nbsp;
+<a href="http://www.doxygen.org/index.html">
+<img class="footer" src="doxygen.png" alt="doxygen"/></a> 1.7.1 </small></address>
+</body>
+</html>
diff --git a/contrib/libyaml/doc/html/functions_vars_0x6e.html b/contrib/libyaml/doc/html/functions_vars_0x6e.html
new file mode 100644
index 0000000..c959180
--- /dev/null
+++ b/contrib/libyaml/doc/html/functions_vars_0x6e.html
@@ -0,0 +1,71 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head>
+<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/>
+<title>yaml: Data Fields - Variables</title>
+<link href="tabs.css" rel="stylesheet" type="text/css"/>
+<link href="doxygen.css" rel="stylesheet" type="text/css"/>
+</head>
+<body>
+<!-- Generated by Doxygen 1.7.1 -->
+<div class="navigation" id="top">
+ <div class="tabs">
+ <ul class="tablist">
+ <li><a href="index.html"><span>Main&nbsp;Page</span></a></li>
+ <li><a href="modules.html"><span>Modules</span></a></li>
+ <li class="current"><a href="annotated.html"><span>Data&nbsp;Structures</span></a></li>
+ <li><a href="files.html"><span>Files</span></a></li>
+ </ul>
+ </div>
+ <div class="tabs2">
+ <ul class="tablist">
+ <li><a href="annotated.html"><span>Data&nbsp;Structures</span></a></li>
+ <li class="current"><a href="functions.html"><span>Data&nbsp;Fields</span></a></li>
+ </ul>
+ </div>
+ <div class="tabs2">
+ <ul class="tablist">
+ <li><a href="functions.html"><span>All</span></a></li>
+ <li class="current"><a href="functions_vars.html"><span>Variables</span></a></li>
+ </ul>
+ </div>
+ <div class="tabs3">
+ <ul class="tablist">
+ <li><a href="functions_vars.html#index_a"><span>a</span></a></li>
+ <li><a href="functions_vars_0x62.html#index_b"><span>b</span></a></li>
+ <li><a href="functions_vars_0x63.html#index_c"><span>c</span></a></li>
+ <li><a href="functions_vars_0x64.html#index_d"><span>d</span></a></li>
+ <li><a href="functions_vars_0x65.html#index_e"><span>e</span></a></li>
+ <li><a href="functions_vars_0x66.html#index_f"><span>f</span></a></li>
+ <li><a href="functions_vars_0x68.html#index_h"><span>h</span></a></li>
+ <li><a href="functions_vars_0x69.html#index_i"><span>i</span></a></li>
+ <li><a href="functions_vars_0x6b.html#index_k"><span>k</span></a></li>
+ <li><a href="functions_vars_0x6c.html#index_l"><span>l</span></a></li>
+ <li><a href="functions_vars_0x6d.html#index_m"><span>m</span></a></li>
+ <li class="current"><a href="functions_vars_0x6e.html#index_n"><span>n</span></a></li>
+ <li><a href="functions_vars_0x6f.html#index_o"><span>o</span></a></li>
+ <li><a href="functions_vars_0x70.html#index_p"><span>p</span></a></li>
+ <li><a href="functions_vars_0x71.html#index_q"><span>q</span></a></li>
+ <li><a href="functions_vars_0x72.html#index_r"><span>r</span></a></li>
+ <li><a href="functions_vars_0x73.html#index_s"><span>s</span></a></li>
+ <li><a href="functions_vars_0x74.html#index_t"><span>t</span></a></li>
+ <li><a href="functions_vars_0x75.html#index_u"><span>u</span></a></li>
+ <li><a href="functions_vars_0x76.html#index_v"><span>v</span></a></li>
+ <li><a href="functions_vars_0x77.html#index_w"><span>w</span></a></li>
+ </ul>
+ </div>
+</div>
+<div class="contents">
+&nbsp;
+
+<h3><a class="anchor" id="index_n"></a>- n -</h3><ul>
+<li>nodes
+: <a class="el" href="structyaml__document__s.html#aa9eeab76b69cc84a6ab1b02c14cfd594">yaml_document_s</a>
+</li>
+</ul>
+</div>
+<hr class="footer"/><address class="footer"><small>Generated on Mon May 30 2011 22:00:00 for yaml by&nbsp;
+<a href="http://www.doxygen.org/index.html">
+<img class="footer" src="doxygen.png" alt="doxygen"/></a> 1.7.1 </small></address>
+</body>
+</html>
diff --git a/contrib/libyaml/doc/html/functions_vars_0x6f.html b/contrib/libyaml/doc/html/functions_vars_0x6f.html
new file mode 100644
index 0000000..8a91fce
--- /dev/null
+++ b/contrib/libyaml/doc/html/functions_vars_0x6f.html
@@ -0,0 +1,80 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head>
+<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/>
+<title>yaml: Data Fields - Variables</title>
+<link href="tabs.css" rel="stylesheet" type="text/css"/>
+<link href="doxygen.css" rel="stylesheet" type="text/css"/>
+</head>
+<body>
+<!-- Generated by Doxygen 1.7.1 -->
+<div class="navigation" id="top">
+ <div class="tabs">
+ <ul class="tablist">
+ <li><a href="index.html"><span>Main&nbsp;Page</span></a></li>
+ <li><a href="modules.html"><span>Modules</span></a></li>
+ <li class="current"><a href="annotated.html"><span>Data&nbsp;Structures</span></a></li>
+ <li><a href="files.html"><span>Files</span></a></li>
+ </ul>
+ </div>
+ <div class="tabs2">
+ <ul class="tablist">
+ <li><a href="annotated.html"><span>Data&nbsp;Structures</span></a></li>
+ <li class="current"><a href="functions.html"><span>Data&nbsp;Fields</span></a></li>
+ </ul>
+ </div>
+ <div class="tabs2">
+ <ul class="tablist">
+ <li><a href="functions.html"><span>All</span></a></li>
+ <li class="current"><a href="functions_vars.html"><span>Variables</span></a></li>
+ </ul>
+ </div>
+ <div class="tabs3">
+ <ul class="tablist">
+ <li><a href="functions_vars.html#index_a"><span>a</span></a></li>
+ <li><a href="functions_vars_0x62.html#index_b"><span>b</span></a></li>
+ <li><a href="functions_vars_0x63.html#index_c"><span>c</span></a></li>
+ <li><a href="functions_vars_0x64.html#index_d"><span>d</span></a></li>
+ <li><a href="functions_vars_0x65.html#index_e"><span>e</span></a></li>
+ <li><a href="functions_vars_0x66.html#index_f"><span>f</span></a></li>
+ <li><a href="functions_vars_0x68.html#index_h"><span>h</span></a></li>
+ <li><a href="functions_vars_0x69.html#index_i"><span>i</span></a></li>
+ <li><a href="functions_vars_0x6b.html#index_k"><span>k</span></a></li>
+ <li><a href="functions_vars_0x6c.html#index_l"><span>l</span></a></li>
+ <li><a href="functions_vars_0x6d.html#index_m"><span>m</span></a></li>
+ <li><a href="functions_vars_0x6e.html#index_n"><span>n</span></a></li>
+ <li class="current"><a href="functions_vars_0x6f.html#index_o"><span>o</span></a></li>
+ <li><a href="functions_vars_0x70.html#index_p"><span>p</span></a></li>
+ <li><a href="functions_vars_0x71.html#index_q"><span>q</span></a></li>
+ <li><a href="functions_vars_0x72.html#index_r"><span>r</span></a></li>
+ <li><a href="functions_vars_0x73.html#index_s"><span>s</span></a></li>
+ <li><a href="functions_vars_0x74.html#index_t"><span>t</span></a></li>
+ <li><a href="functions_vars_0x75.html#index_u"><span>u</span></a></li>
+ <li><a href="functions_vars_0x76.html#index_v"><span>v</span></a></li>
+ <li><a href="functions_vars_0x77.html#index_w"><span>w</span></a></li>
+ </ul>
+ </div>
+</div>
+<div class="contents">
+&nbsp;
+
+<h3><a class="anchor" id="index_o"></a>- o -</h3><ul>
+<li>offset
+: <a class="el" href="structyaml__parser__s.html#a04a7ba684ce49b2300c236c561439b13">yaml_parser_s</a>
+</li>
+<li>open_ended
+: <a class="el" href="structyaml__emitter__s.html#a65e84454b702622c41a068768c144c51">yaml_emitter_s</a>
+</li>
+<li>opened
+: <a class="el" href="structyaml__emitter__s.html#a0234d7e9bfbe7cc6e12b60f90f5ec552">yaml_emitter_s</a>
+</li>
+<li>output
+: <a class="el" href="structyaml__emitter__s.html#aa975acf559cc87d79abdb732c994f56f">yaml_emitter_s</a>
+</li>
+</ul>
+</div>
+<hr class="footer"/><address class="footer"><small>Generated on Mon May 30 2011 22:00:00 for yaml by&nbsp;
+<a href="http://www.doxygen.org/index.html">
+<img class="footer" src="doxygen.png" alt="doxygen"/></a> 1.7.1 </small></address>
+</body>
+</html>
diff --git a/contrib/libyaml/doc/html/functions_vars_0x70.html b/contrib/libyaml/doc/html/functions_vars_0x70.html
new file mode 100644
index 0000000..abe744c
--- /dev/null
+++ b/contrib/libyaml/doc/html/functions_vars_0x70.html
@@ -0,0 +1,100 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head>
+<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/>
+<title>yaml: Data Fields - Variables</title>
+<link href="tabs.css" rel="stylesheet" type="text/css"/>
+<link href="doxygen.css" rel="stylesheet" type="text/css"/>
+</head>
+<body>
+<!-- Generated by Doxygen 1.7.1 -->
+<div class="navigation" id="top">
+ <div class="tabs">
+ <ul class="tablist">
+ <li><a href="index.html"><span>Main&nbsp;Page</span></a></li>
+ <li><a href="modules.html"><span>Modules</span></a></li>
+ <li class="current"><a href="annotated.html"><span>Data&nbsp;Structures</span></a></li>
+ <li><a href="files.html"><span>Files</span></a></li>
+ </ul>
+ </div>
+ <div class="tabs2">
+ <ul class="tablist">
+ <li><a href="annotated.html"><span>Data&nbsp;Structures</span></a></li>
+ <li class="current"><a href="functions.html"><span>Data&nbsp;Fields</span></a></li>
+ </ul>
+ </div>
+ <div class="tabs2">
+ <ul class="tablist">
+ <li><a href="functions.html"><span>All</span></a></li>
+ <li class="current"><a href="functions_vars.html"><span>Variables</span></a></li>
+ </ul>
+ </div>
+ <div class="tabs3">
+ <ul class="tablist">
+ <li><a href="functions_vars.html#index_a"><span>a</span></a></li>
+ <li><a href="functions_vars_0x62.html#index_b"><span>b</span></a></li>
+ <li><a href="functions_vars_0x63.html#index_c"><span>c</span></a></li>
+ <li><a href="functions_vars_0x64.html#index_d"><span>d</span></a></li>
+ <li><a href="functions_vars_0x65.html#index_e"><span>e</span></a></li>
+ <li><a href="functions_vars_0x66.html#index_f"><span>f</span></a></li>
+ <li><a href="functions_vars_0x68.html#index_h"><span>h</span></a></li>
+ <li><a href="functions_vars_0x69.html#index_i"><span>i</span></a></li>
+ <li><a href="functions_vars_0x6b.html#index_k"><span>k</span></a></li>
+ <li><a href="functions_vars_0x6c.html#index_l"><span>l</span></a></li>
+ <li><a href="functions_vars_0x6d.html#index_m"><span>m</span></a></li>
+ <li><a href="functions_vars_0x6e.html#index_n"><span>n</span></a></li>
+ <li><a href="functions_vars_0x6f.html#index_o"><span>o</span></a></li>
+ <li class="current"><a href="functions_vars_0x70.html#index_p"><span>p</span></a></li>
+ <li><a href="functions_vars_0x71.html#index_q"><span>q</span></a></li>
+ <li><a href="functions_vars_0x72.html#index_r"><span>r</span></a></li>
+ <li><a href="functions_vars_0x73.html#index_s"><span>s</span></a></li>
+ <li><a href="functions_vars_0x74.html#index_t"><span>t</span></a></li>
+ <li><a href="functions_vars_0x75.html#index_u"><span>u</span></a></li>
+ <li><a href="functions_vars_0x76.html#index_v"><span>v</span></a></li>
+ <li><a href="functions_vars_0x77.html#index_w"><span>w</span></a></li>
+ </ul>
+ </div>
+</div>
+<div class="contents">
+&nbsp;
+
+<h3><a class="anchor" id="index_p"></a>- p -</h3><ul>
+<li>pairs
+: <a class="el" href="structyaml__node__s.html#a830a080bbed021eb230ef644e4680909">yaml_node_s</a>
+</li>
+<li>plain_implicit
+: <a class="el" href="structyaml__event__s.html#ac3600acbcc6b4787f1ec3511976a3151">yaml_event_s</a>
+</li>
+<li>pointer
+: <a class="el" href="structyaml__parser__s.html#abea626790abfbcaeeb72a3772dc69e43">yaml_parser_s</a>
+, <a class="el" href="structyaml__emitter__s.html#a7615ab51145234f467984f3091558852">yaml_emitter_s</a>
+, <a class="el" href="structyaml__parser__s.html#a8199466e3578374b3f984b6c0c4e2ae4">yaml_parser_s</a>
+, <a class="el" href="structyaml__emitter__s.html#aed9370f42cea4dff82f96839ce760b5a">yaml_emitter_s</a>
+</li>
+<li>possible
+: <a class="el" href="structyaml__simple__key__s.html#aad311b0fa599db04657a5177ec331f07">yaml_simple_key_s</a>
+</li>
+<li>prefix
+: <a class="el" href="structyaml__tag__directive__s.html#a514850fefaafbe65b2322da8c193a896">yaml_tag_directive_s</a>
+, <a class="el" href="structyaml__token__s.html#a561b3730b9999cfe1010e77aca49c5b8">yaml_token_s</a>
+</li>
+<li>problem
+: <a class="el" href="structyaml__parser__s.html#a3dd8a43294cd420a433595a7a7d6e73d">yaml_parser_s</a>
+, <a class="el" href="structyaml__emitter__s.html#ae076ef7c85ae107a2233dd4206577800">yaml_emitter_s</a>
+</li>
+<li>problem_mark
+: <a class="el" href="structyaml__parser__s.html#a595b5412d39a4a9e441e5ad34fb059d9">yaml_parser_s</a>
+</li>
+<li>problem_offset
+: <a class="el" href="structyaml__parser__s.html#ae2d62a2ad45671c6dd89e18fb7c1c5bd">yaml_parser_s</a>
+</li>
+<li>problem_value
+: <a class="el" href="structyaml__parser__s.html#a8694691b20824f6595873b728cb3bc0f">yaml_parser_s</a>
+</li>
+</ul>
+</div>
+<hr class="footer"/><address class="footer"><small>Generated on Mon May 30 2011 22:00:00 for yaml by&nbsp;
+<a href="http://www.doxygen.org/index.html">
+<img class="footer" src="doxygen.png" alt="doxygen"/></a> 1.7.1 </small></address>
+</body>
+</html>
diff --git a/contrib/libyaml/doc/html/functions_vars_0x71.html b/contrib/libyaml/doc/html/functions_vars_0x71.html
new file mode 100644
index 0000000..002c8f0
--- /dev/null
+++ b/contrib/libyaml/doc/html/functions_vars_0x71.html
@@ -0,0 +1,71 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head>
+<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/>
+<title>yaml: Data Fields - Variables</title>
+<link href="tabs.css" rel="stylesheet" type="text/css"/>
+<link href="doxygen.css" rel="stylesheet" type="text/css"/>
+</head>
+<body>
+<!-- Generated by Doxygen 1.7.1 -->
+<div class="navigation" id="top">
+ <div class="tabs">
+ <ul class="tablist">
+ <li><a href="index.html"><span>Main&nbsp;Page</span></a></li>
+ <li><a href="modules.html"><span>Modules</span></a></li>
+ <li class="current"><a href="annotated.html"><span>Data&nbsp;Structures</span></a></li>
+ <li><a href="files.html"><span>Files</span></a></li>
+ </ul>
+ </div>
+ <div class="tabs2">
+ <ul class="tablist">
+ <li><a href="annotated.html"><span>Data&nbsp;Structures</span></a></li>
+ <li class="current"><a href="functions.html"><span>Data&nbsp;Fields</span></a></li>
+ </ul>
+ </div>
+ <div class="tabs2">
+ <ul class="tablist">
+ <li><a href="functions.html"><span>All</span></a></li>
+ <li class="current"><a href="functions_vars.html"><span>Variables</span></a></li>
+ </ul>
+ </div>
+ <div class="tabs3">
+ <ul class="tablist">
+ <li><a href="functions_vars.html#index_a"><span>a</span></a></li>
+ <li><a href="functions_vars_0x62.html#index_b"><span>b</span></a></li>
+ <li><a href="functions_vars_0x63.html#index_c"><span>c</span></a></li>
+ <li><a href="functions_vars_0x64.html#index_d"><span>d</span></a></li>
+ <li><a href="functions_vars_0x65.html#index_e"><span>e</span></a></li>
+ <li><a href="functions_vars_0x66.html#index_f"><span>f</span></a></li>
+ <li><a href="functions_vars_0x68.html#index_h"><span>h</span></a></li>
+ <li><a href="functions_vars_0x69.html#index_i"><span>i</span></a></li>
+ <li><a href="functions_vars_0x6b.html#index_k"><span>k</span></a></li>
+ <li><a href="functions_vars_0x6c.html#index_l"><span>l</span></a></li>
+ <li><a href="functions_vars_0x6d.html#index_m"><span>m</span></a></li>
+ <li><a href="functions_vars_0x6e.html#index_n"><span>n</span></a></li>
+ <li><a href="functions_vars_0x6f.html#index_o"><span>o</span></a></li>
+ <li><a href="functions_vars_0x70.html#index_p"><span>p</span></a></li>
+ <li class="current"><a href="functions_vars_0x71.html#index_q"><span>q</span></a></li>
+ <li><a href="functions_vars_0x72.html#index_r"><span>r</span></a></li>
+ <li><a href="functions_vars_0x73.html#index_s"><span>s</span></a></li>
+ <li><a href="functions_vars_0x74.html#index_t"><span>t</span></a></li>
+ <li><a href="functions_vars_0x75.html#index_u"><span>u</span></a></li>
+ <li><a href="functions_vars_0x76.html#index_v"><span>v</span></a></li>
+ <li><a href="functions_vars_0x77.html#index_w"><span>w</span></a></li>
+ </ul>
+ </div>
+</div>
+<div class="contents">
+&nbsp;
+
+<h3><a class="anchor" id="index_q"></a>- q -</h3><ul>
+<li>quoted_implicit
+: <a class="el" href="structyaml__event__s.html#a9ce2441d08d9cf6a1bf9f28f5ee17f68">yaml_event_s</a>
+</li>
+</ul>
+</div>
+<hr class="footer"/><address class="footer"><small>Generated on Mon May 30 2011 22:00:00 for yaml by&nbsp;
+<a href="http://www.doxygen.org/index.html">
+<img class="footer" src="doxygen.png" alt="doxygen"/></a> 1.7.1 </small></address>
+</body>
+</html>
diff --git a/contrib/libyaml/doc/html/functions_vars_0x72.html b/contrib/libyaml/doc/html/functions_vars_0x72.html
new file mode 100644
index 0000000..cc9aff5
--- /dev/null
+++ b/contrib/libyaml/doc/html/functions_vars_0x72.html
@@ -0,0 +1,87 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head>
+<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/>
+<title>yaml: Data Fields - Variables</title>
+<link href="tabs.css" rel="stylesheet" type="text/css"/>
+<link href="doxygen.css" rel="stylesheet" type="text/css"/>
+</head>
+<body>
+<!-- Generated by Doxygen 1.7.1 -->
+<div class="navigation" id="top">
+ <div class="tabs">
+ <ul class="tablist">
+ <li><a href="index.html"><span>Main&nbsp;Page</span></a></li>
+ <li><a href="modules.html"><span>Modules</span></a></li>
+ <li class="current"><a href="annotated.html"><span>Data&nbsp;Structures</span></a></li>
+ <li><a href="files.html"><span>Files</span></a></li>
+ </ul>
+ </div>
+ <div class="tabs2">
+ <ul class="tablist">
+ <li><a href="annotated.html"><span>Data&nbsp;Structures</span></a></li>
+ <li class="current"><a href="functions.html"><span>Data&nbsp;Fields</span></a></li>
+ </ul>
+ </div>
+ <div class="tabs2">
+ <ul class="tablist">
+ <li><a href="functions.html"><span>All</span></a></li>
+ <li class="current"><a href="functions_vars.html"><span>Variables</span></a></li>
+ </ul>
+ </div>
+ <div class="tabs3">
+ <ul class="tablist">
+ <li><a href="functions_vars.html#index_a"><span>a</span></a></li>
+ <li><a href="functions_vars_0x62.html#index_b"><span>b</span></a></li>
+ <li><a href="functions_vars_0x63.html#index_c"><span>c</span></a></li>
+ <li><a href="functions_vars_0x64.html#index_d"><span>d</span></a></li>
+ <li><a href="functions_vars_0x65.html#index_e"><span>e</span></a></li>
+ <li><a href="functions_vars_0x66.html#index_f"><span>f</span></a></li>
+ <li><a href="functions_vars_0x68.html#index_h"><span>h</span></a></li>
+ <li><a href="functions_vars_0x69.html#index_i"><span>i</span></a></li>
+ <li><a href="functions_vars_0x6b.html#index_k"><span>k</span></a></li>
+ <li><a href="functions_vars_0x6c.html#index_l"><span>l</span></a></li>
+ <li><a href="functions_vars_0x6d.html#index_m"><span>m</span></a></li>
+ <li><a href="functions_vars_0x6e.html#index_n"><span>n</span></a></li>
+ <li><a href="functions_vars_0x6f.html#index_o"><span>o</span></a></li>
+ <li><a href="functions_vars_0x70.html#index_p"><span>p</span></a></li>
+ <li><a href="functions_vars_0x71.html#index_q"><span>q</span></a></li>
+ <li class="current"><a href="functions_vars_0x72.html#index_r"><span>r</span></a></li>
+ <li><a href="functions_vars_0x73.html#index_s"><span>s</span></a></li>
+ <li><a href="functions_vars_0x74.html#index_t"><span>t</span></a></li>
+ <li><a href="functions_vars_0x75.html#index_u"><span>u</span></a></li>
+ <li><a href="functions_vars_0x76.html#index_v"><span>v</span></a></li>
+ <li><a href="functions_vars_0x77.html#index_w"><span>w</span></a></li>
+ </ul>
+ </div>
+</div>
+<div class="contents">
+&nbsp;
+
+<h3><a class="anchor" id="index_r"></a>- r -</h3><ul>
+<li>raw_buffer
+: <a class="el" href="structyaml__parser__s.html#ae3e8481ceabdbf6796a7dc6265f740ac">yaml_parser_s</a>
+, <a class="el" href="structyaml__emitter__s.html#a6eeffbc9cd5beb89b679740b7f1d6d09">yaml_emitter_s</a>
+</li>
+<li>read_handler
+: <a class="el" href="structyaml__parser__s.html#a8c3af47a7a0750d437cba34699fcad30">yaml_parser_s</a>
+</li>
+<li>read_handler_data
+: <a class="el" href="structyaml__parser__s.html#a11f265cd495e814c8ee7d3dd78ff2ca9">yaml_parser_s</a>
+</li>
+<li>references
+: <a class="el" href="structyaml__emitter__s.html#a8f00c3c08e0d87bab11e91a4464a50bc">yaml_emitter_s</a>
+</li>
+<li>required
+: <a class="el" href="structyaml__simple__key__s.html#acacccea26520e74c4c61f170fdcbb4c3">yaml_simple_key_s</a>
+</li>
+<li>root_context
+: <a class="el" href="structyaml__emitter__s.html#a70fb5f09cc60de989fbec2868f4db19e">yaml_emitter_s</a>
+</li>
+</ul>
+</div>
+<hr class="footer"/><address class="footer"><small>Generated on Mon May 30 2011 22:00:00 for yaml by&nbsp;
+<a href="http://www.doxygen.org/index.html">
+<img class="footer" src="doxygen.png" alt="doxygen"/></a> 1.7.1 </small></address>
+</body>
+</html>
diff --git a/contrib/libyaml/doc/html/functions_vars_0x73.html b/contrib/libyaml/doc/html/functions_vars_0x73.html
new file mode 100644
index 0000000..2aedfe1
--- /dev/null
+++ b/contrib/libyaml/doc/html/functions_vars_0x73.html
@@ -0,0 +1,163 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head>
+<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/>
+<title>yaml: Data Fields - Variables</title>
+<link href="tabs.css" rel="stylesheet" type="text/css"/>
+<link href="doxygen.css" rel="stylesheet" type="text/css"/>
+</head>
+<body>
+<!-- Generated by Doxygen 1.7.1 -->
+<div class="navigation" id="top">
+ <div class="tabs">
+ <ul class="tablist">
+ <li><a href="index.html"><span>Main&nbsp;Page</span></a></li>
+ <li><a href="modules.html"><span>Modules</span></a></li>
+ <li class="current"><a href="annotated.html"><span>Data&nbsp;Structures</span></a></li>
+ <li><a href="files.html"><span>Files</span></a></li>
+ </ul>
+ </div>
+ <div class="tabs2">
+ <ul class="tablist">
+ <li><a href="annotated.html"><span>Data&nbsp;Structures</span></a></li>
+ <li class="current"><a href="functions.html"><span>Data&nbsp;Fields</span></a></li>
+ </ul>
+ </div>
+ <div class="tabs2">
+ <ul class="tablist">
+ <li><a href="functions.html"><span>All</span></a></li>
+ <li class="current"><a href="functions_vars.html"><span>Variables</span></a></li>
+ </ul>
+ </div>
+ <div class="tabs3">
+ <ul class="tablist">
+ <li><a href="functions_vars.html#index_a"><span>a</span></a></li>
+ <li><a href="functions_vars_0x62.html#index_b"><span>b</span></a></li>
+ <li><a href="functions_vars_0x63.html#index_c"><span>c</span></a></li>
+ <li><a href="functions_vars_0x64.html#index_d"><span>d</span></a></li>
+ <li><a href="functions_vars_0x65.html#index_e"><span>e</span></a></li>
+ <li><a href="functions_vars_0x66.html#index_f"><span>f</span></a></li>
+ <li><a href="functions_vars_0x68.html#index_h"><span>h</span></a></li>
+ <li><a href="functions_vars_0x69.html#index_i"><span>i</span></a></li>
+ <li><a href="functions_vars_0x6b.html#index_k"><span>k</span></a></li>
+ <li><a href="functions_vars_0x6c.html#index_l"><span>l</span></a></li>
+ <li><a href="functions_vars_0x6d.html#index_m"><span>m</span></a></li>
+ <li><a href="functions_vars_0x6e.html#index_n"><span>n</span></a></li>
+ <li><a href="functions_vars_0x6f.html#index_o"><span>o</span></a></li>
+ <li><a href="functions_vars_0x70.html#index_p"><span>p</span></a></li>
+ <li><a href="functions_vars_0x71.html#index_q"><span>q</span></a></li>
+ <li><a href="functions_vars_0x72.html#index_r"><span>r</span></a></li>
+ <li class="current"><a href="functions_vars_0x73.html#index_s"><span>s</span></a></li>
+ <li><a href="functions_vars_0x74.html#index_t"><span>t</span></a></li>
+ <li><a href="functions_vars_0x75.html#index_u"><span>u</span></a></li>
+ <li><a href="functions_vars_0x76.html#index_v"><span>v</span></a></li>
+ <li><a href="functions_vars_0x77.html#index_w"><span>w</span></a></li>
+ </ul>
+ </div>
+</div>
+<div class="contents">
+&nbsp;
+
+<h3><a class="anchor" id="index_s"></a>- s -</h3><ul>
+<li>scalar
+: <a class="el" href="structyaml__token__s.html#a35e3629351176dd91b38cbfc827a8b00">yaml_token_s</a>
+, <a class="el" href="structyaml__event__s.html#a3753b4c5d10040d75f7c7f4b56c42549">yaml_event_s</a>
+, <a class="el" href="structyaml__node__s.html#a688583a2649848aed700d7e07d9efac9">yaml_node_s</a>
+</li>
+<li>scalar_data
+: <a class="el" href="structyaml__emitter__s.html#ac3f80f4cb9c361b5fa4fa8f5cc04dbac">yaml_emitter_s</a>
+</li>
+<li>sequence
+: <a class="el" href="structyaml__node__s.html#afe215962139fac93b965cc2acd71452b">yaml_node_s</a>
+</li>
+<li>sequence_context
+: <a class="el" href="structyaml__emitter__s.html#a9d20d55b0914ff81bf0f56e57ca7416e">yaml_emitter_s</a>
+</li>
+<li>sequence_start
+: <a class="el" href="structyaml__event__s.html#a632895e022fbf29ab24a816893a8580f">yaml_event_s</a>
+</li>
+<li>serialized
+: <a class="el" href="structyaml__emitter__s.html#a6c3e98c02ffae879717b3d09f9458936">yaml_emitter_s</a>
+</li>
+<li>simple_key_allowed
+: <a class="el" href="structyaml__parser__s.html#acc85a7bfddc7ae9114cf115e43c89126">yaml_parser_s</a>
+</li>
+<li>simple_key_context
+: <a class="el" href="structyaml__emitter__s.html#acc0db69cdae44c1385bbb2b6c207371b">yaml_emitter_s</a>
+</li>
+<li>simple_keys
+: <a class="el" href="structyaml__parser__s.html#ad5ce7de476c58fb6e1fdabbcc1c51659">yaml_parser_s</a>
+</li>
+<li>single_quoted_allowed
+: <a class="el" href="structyaml__emitter__s.html#a3729ff7e7add06a1a1d9067a557a59fc">yaml_emitter_s</a>
+</li>
+<li>size
+: <a class="el" href="structyaml__emitter__s.html#a53bdc6a00632b48c81098aad91a9fd8d">yaml_emitter_s</a>
+</li>
+<li>size_written
+: <a class="el" href="structyaml__emitter__s.html#a1851639b8f0e53b8e272c806d9fb648b">yaml_emitter_s</a>
+</li>
+<li>start
+: <a class="el" href="structyaml__node__s.html#a2e1001a0a7b068d4b2543a93d4cf60d4">yaml_node_s</a>
+, <a class="el" href="structyaml__emitter__s.html#ad68af21e510adcfc2db43b31e791efe1">yaml_emitter_s</a>
+, <a class="el" href="structyaml__node__s.html#a82afddfe1cf7f1a346d931ad4896d3de">yaml_node_s</a>
+, <a class="el" href="structyaml__emitter__s.html#a28ec8053132a8e7cf29df983835754b7">yaml_emitter_s</a>
+, <a class="el" href="structyaml__document__s.html#aa3f9a11d8fbe4ac2eada1786176bab89">yaml_document_s</a>
+, <a class="el" href="structyaml__parser__s.html#a8cdb2fed4bb17b1d62d29fa06c53fef6">yaml_parser_s</a>
+, <a class="el" href="structyaml__emitter__s.html#ae8913d3c0bf4c987dc452efee2c802e3">yaml_emitter_s</a>
+, <a class="el" href="structyaml__parser__s.html#ab9eddd3a112c3a4547bf87f6936aba94">yaml_parser_s</a>
+, <a class="el" href="structyaml__event__s.html#a74d7f521a559305585009ab503bee16b">yaml_event_s</a>
+, <a class="el" href="structyaml__emitter__s.html#a1c8f40a58f0a3061449b3fed02be145e">yaml_emitter_s</a>
+</li>
+<li>start_implicit
+: <a class="el" href="structyaml__document__s.html#a65c49e4f61ca5c2f6ecf410e1cc65787">yaml_document_s</a>
+</li>
+<li>start_mark
+: <a class="el" href="structyaml__token__s.html#abdc5f4f2059c5a7bfe8e810b49a53980">yaml_token_s</a>
+, <a class="el" href="structyaml__event__s.html#aeaf86eb588e75232e1b73e8213eb3e31">yaml_event_s</a>
+, <a class="el" href="structyaml__document__s.html#a0a37311ebf8f6637e4bc1d280a879997">yaml_document_s</a>
+, <a class="el" href="structyaml__node__s.html#ac17afa3b3a9ff4703bb4983163bfae5c">yaml_node_s</a>
+</li>
+<li>state
+: <a class="el" href="structyaml__parser__s.html#a069d39cdf587ac2188e69d8fb018be64">yaml_parser_s</a>
+, <a class="el" href="structyaml__emitter__s.html#a29f1d4f27ff9b9616c154f0730dd24ee">yaml_emitter_s</a>
+</li>
+<li>states
+: <a class="el" href="structyaml__parser__s.html#a57aa3c5fbfcaed8c17e046f0778c92bf">yaml_parser_s</a>
+, <a class="el" href="structyaml__emitter__s.html#a6dc87fbd5b074507e102b967492b135d">yaml_emitter_s</a>
+</li>
+<li>stream_end_produced
+: <a class="el" href="structyaml__parser__s.html#a63ccf04d623f36c04b62cfd1fc6fccb5">yaml_parser_s</a>
+</li>
+<li>stream_start
+: <a class="el" href="structyaml__token__s.html#aab66b62f4507f4fd0e9d2b7548f588e6">yaml_token_s</a>
+, <a class="el" href="structyaml__event__s.html#a18946df9b7c815dd7fb30103c02a9e24">yaml_event_s</a>
+</li>
+<li>stream_start_produced
+: <a class="el" href="structyaml__parser__s.html#a7fecde5abcce11406c271f7db08f7a05">yaml_parser_s</a>
+</li>
+<li>string
+: <a class="el" href="structyaml__emitter__s.html#a8803fe1047e8bcea9bdfcad0743fa0dd">yaml_emitter_s</a>
+, <a class="el" href="structyaml__parser__s.html#a44fa7ca68030680244f3743ce5e35702">yaml_parser_s</a>
+</li>
+<li>style
+: <a class="el" href="structyaml__node__s.html#a362960375516e77a130c412ef10ef55d">yaml_node_s</a>
+, <a class="el" href="structyaml__event__s.html#a2ac1305583a8e7e2247738116bca6b3b">yaml_event_s</a>
+, <a class="el" href="structyaml__emitter__s.html#acd1e83d220103aa24577038cfb1c2d21">yaml_emitter_s</a>
+, <a class="el" href="structyaml__token__s.html#a530a8c4d78feaf5496fb9f461674382b">yaml_token_s</a>
+, <a class="el" href="structyaml__node__s.html#a5b80d97f64e2867927404fedb65949c6">yaml_node_s</a>
+</li>
+<li>suffix
+: <a class="el" href="structyaml__token__s.html#a61344c49b73da5821cb06cab4cbab505">yaml_token_s</a>
+, <a class="el" href="structyaml__emitter__s.html#ad9b61d5e9e05a47b2f873342ab226188">yaml_emitter_s</a>
+</li>
+<li>suffix_length
+: <a class="el" href="structyaml__emitter__s.html#ad83936bbd4b6b77c79555c71cccc8fb5">yaml_emitter_s</a>
+</li>
+</ul>
+</div>
+<hr class="footer"/><address class="footer"><small>Generated on Mon May 30 2011 22:00:00 for yaml by&nbsp;
+<a href="http://www.doxygen.org/index.html">
+<img class="footer" src="doxygen.png" alt="doxygen"/></a> 1.7.1 </small></address>
+</body>
+</html>
diff --git a/contrib/libyaml/doc/html/functions_vars_0x74.html b/contrib/libyaml/doc/html/functions_vars_0x74.html
new file mode 100644
index 0000000..2eb7278
--- /dev/null
+++ b/contrib/libyaml/doc/html/functions_vars_0x74.html
@@ -0,0 +1,115 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head>
+<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/>
+<title>yaml: Data Fields - Variables</title>
+<link href="tabs.css" rel="stylesheet" type="text/css"/>
+<link href="doxygen.css" rel="stylesheet" type="text/css"/>
+</head>
+<body>
+<!-- Generated by Doxygen 1.7.1 -->
+<div class="navigation" id="top">
+ <div class="tabs">
+ <ul class="tablist">
+ <li><a href="index.html"><span>Main&nbsp;Page</span></a></li>
+ <li><a href="modules.html"><span>Modules</span></a></li>
+ <li class="current"><a href="annotated.html"><span>Data&nbsp;Structures</span></a></li>
+ <li><a href="files.html"><span>Files</span></a></li>
+ </ul>
+ </div>
+ <div class="tabs2">
+ <ul class="tablist">
+ <li><a href="annotated.html"><span>Data&nbsp;Structures</span></a></li>
+ <li class="current"><a href="functions.html"><span>Data&nbsp;Fields</span></a></li>
+ </ul>
+ </div>
+ <div class="tabs2">
+ <ul class="tablist">
+ <li><a href="functions.html"><span>All</span></a></li>
+ <li class="current"><a href="functions_vars.html"><span>Variables</span></a></li>
+ </ul>
+ </div>
+ <div class="tabs3">
+ <ul class="tablist">
+ <li><a href="functions_vars.html#index_a"><span>a</span></a></li>
+ <li><a href="functions_vars_0x62.html#index_b"><span>b</span></a></li>
+ <li><a href="functions_vars_0x63.html#index_c"><span>c</span></a></li>
+ <li><a href="functions_vars_0x64.html#index_d"><span>d</span></a></li>
+ <li><a href="functions_vars_0x65.html#index_e"><span>e</span></a></li>
+ <li><a href="functions_vars_0x66.html#index_f"><span>f</span></a></li>
+ <li><a href="functions_vars_0x68.html#index_h"><span>h</span></a></li>
+ <li><a href="functions_vars_0x69.html#index_i"><span>i</span></a></li>
+ <li><a href="functions_vars_0x6b.html#index_k"><span>k</span></a></li>
+ <li><a href="functions_vars_0x6c.html#index_l"><span>l</span></a></li>
+ <li><a href="functions_vars_0x6d.html#index_m"><span>m</span></a></li>
+ <li><a href="functions_vars_0x6e.html#index_n"><span>n</span></a></li>
+ <li><a href="functions_vars_0x6f.html#index_o"><span>o</span></a></li>
+ <li><a href="functions_vars_0x70.html#index_p"><span>p</span></a></li>
+ <li><a href="functions_vars_0x71.html#index_q"><span>q</span></a></li>
+ <li><a href="functions_vars_0x72.html#index_r"><span>r</span></a></li>
+ <li><a href="functions_vars_0x73.html#index_s"><span>s</span></a></li>
+ <li class="current"><a href="functions_vars_0x74.html#index_t"><span>t</span></a></li>
+ <li><a href="functions_vars_0x75.html#index_u"><span>u</span></a></li>
+ <li><a href="functions_vars_0x76.html#index_v"><span>v</span></a></li>
+ <li><a href="functions_vars_0x77.html#index_w"><span>w</span></a></li>
+ </ul>
+ </div>
+</div>
+<div class="contents">
+&nbsp;
+
+<h3><a class="anchor" id="index_t"></a>- t -</h3><ul>
+<li>tag
+: <a class="el" href="structyaml__token__s.html#ab281db5b7563c5489726768fe0fbaac7">yaml_token_s</a>
+, <a class="el" href="structyaml__event__s.html#a4daf9ed2683d79f2be7e89ca7d06801c">yaml_event_s</a>
+, <a class="el" href="structyaml__node__s.html#aa753358ea6d9d221b7b188832d47fefa">yaml_node_s</a>
+</li>
+<li>tag_data
+: <a class="el" href="structyaml__emitter__s.html#a3b947fbbc337d123af10c58abf1353a4">yaml_emitter_s</a>
+</li>
+<li>tag_directive
+: <a class="el" href="structyaml__token__s.html#aa8a1b9eeee539233e8461773894f4ea0">yaml_token_s</a>
+</li>
+<li>tag_directives
+: <a class="el" href="structyaml__parser__s.html#a9bdfc1888d4e30ffb43146377d44fba0">yaml_parser_s</a>
+, <a class="el" href="structyaml__emitter__s.html#a9dc51f2ccb8a517e2dc029e1af960258">yaml_emitter_s</a>
+, <a class="el" href="structyaml__event__s.html#a162ce89a77e706d68649d40e1a520e1f">yaml_event_s</a>
+, <a class="el" href="structyaml__document__s.html#af1e09d0469fc24106f3790b1e3de09e1">yaml_document_s</a>
+</li>
+<li>tail
+: <a class="el" href="structyaml__parser__s.html#a22ad26583d8d1264e982188358aa79b6">yaml_parser_s</a>
+, <a class="el" href="structyaml__emitter__s.html#acafa1e3cb872fa7917217469659fb273">yaml_emitter_s</a>
+</li>
+<li>token_number
+: <a class="el" href="structyaml__simple__key__s.html#ae098916893ad7415c5c041dd45d24a86">yaml_simple_key_s</a>
+</li>
+<li>tokens
+: <a class="el" href="structyaml__parser__s.html#a96d39b8333411d741ee1c13aa4141682">yaml_parser_s</a>
+</li>
+<li>tokens_parsed
+: <a class="el" href="structyaml__parser__s.html#a7358e72ad071fec3185a833a3a245690">yaml_parser_s</a>
+</li>
+<li>top
+: <a class="el" href="structyaml__emitter__s.html#a5779bcbfd04df64e42434b7599332d11">yaml_emitter_s</a>
+, <a class="el" href="structyaml__node__s.html#a510326726569a06a11119f12649787cf">yaml_node_s</a>
+, <a class="el" href="structyaml__parser__s.html#a24a3f3138b44de1914a3e54dbe0aeff7">yaml_parser_s</a>
+, <a class="el" href="structyaml__node__s.html#aa420f88720907fe02b1d1595c9351d59">yaml_node_s</a>
+, <a class="el" href="structyaml__document__s.html#a5ac36f59c4a0f28124c2e1630ca4f227">yaml_document_s</a>
+, <a class="el" href="structyaml__parser__s.html#a490eddbfcc27787e47de631a3d2e09a8">yaml_parser_s</a>
+, <a class="el" href="structyaml__emitter__s.html#a8e3f468d814d2aa5e074f7da1648d34a">yaml_emitter_s</a>
+, <a class="el" href="structyaml__parser__s.html#ab2678112fd2eaa8f588f2d6217aabc9d">yaml_parser_s</a>
+, <a class="el" href="structyaml__emitter__s.html#aafa8b6f21022ce2f4cb9b44ad15a535e">yaml_emitter_s</a>
+, <a class="el" href="structyaml__parser__s.html#ae610673669f06d46146198a346796276">yaml_parser_s</a>
+</li>
+<li>type
+: <a class="el" href="structyaml__token__s.html#aa8aeb89e2e74f5e2f199484177d0ea14">yaml_token_s</a>
+, <a class="el" href="structyaml__event__s.html#aff08bc3df4859d5b3a804e8c011cac51">yaml_event_s</a>
+, <a class="el" href="structyaml__node__s.html#a1db4ea72e13be65ec42339ce47d19669">yaml_node_s</a>
+</li>
+</ul>
+</div>
+<hr class="footer"/><address class="footer"><small>Generated on Mon May 30 2011 22:00:00 for yaml by&nbsp;
+<a href="http://www.doxygen.org/index.html">
+<img class="footer" src="doxygen.png" alt="doxygen"/></a> 1.7.1 </small></address>
+</body>
+</html>
diff --git a/contrib/libyaml/doc/html/functions_vars_0x75.html b/contrib/libyaml/doc/html/functions_vars_0x75.html
new file mode 100644
index 0000000..c445f6f
--- /dev/null
+++ b/contrib/libyaml/doc/html/functions_vars_0x75.html
@@ -0,0 +1,71 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head>
+<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/>
+<title>yaml: Data Fields - Variables</title>
+<link href="tabs.css" rel="stylesheet" type="text/css"/>
+<link href="doxygen.css" rel="stylesheet" type="text/css"/>
+</head>
+<body>
+<!-- Generated by Doxygen 1.7.1 -->
+<div class="navigation" id="top">
+ <div class="tabs">
+ <ul class="tablist">
+ <li><a href="index.html"><span>Main&nbsp;Page</span></a></li>
+ <li><a href="modules.html"><span>Modules</span></a></li>
+ <li class="current"><a href="annotated.html"><span>Data&nbsp;Structures</span></a></li>
+ <li><a href="files.html"><span>Files</span></a></li>
+ </ul>
+ </div>
+ <div class="tabs2">
+ <ul class="tablist">
+ <li><a href="annotated.html"><span>Data&nbsp;Structures</span></a></li>
+ <li class="current"><a href="functions.html"><span>Data&nbsp;Fields</span></a></li>
+ </ul>
+ </div>
+ <div class="tabs2">
+ <ul class="tablist">
+ <li><a href="functions.html"><span>All</span></a></li>
+ <li class="current"><a href="functions_vars.html"><span>Variables</span></a></li>
+ </ul>
+ </div>
+ <div class="tabs3">
+ <ul class="tablist">
+ <li><a href="functions_vars.html#index_a"><span>a</span></a></li>
+ <li><a href="functions_vars_0x62.html#index_b"><span>b</span></a></li>
+ <li><a href="functions_vars_0x63.html#index_c"><span>c</span></a></li>
+ <li><a href="functions_vars_0x64.html#index_d"><span>d</span></a></li>
+ <li><a href="functions_vars_0x65.html#index_e"><span>e</span></a></li>
+ <li><a href="functions_vars_0x66.html#index_f"><span>f</span></a></li>
+ <li><a href="functions_vars_0x68.html#index_h"><span>h</span></a></li>
+ <li><a href="functions_vars_0x69.html#index_i"><span>i</span></a></li>
+ <li><a href="functions_vars_0x6b.html#index_k"><span>k</span></a></li>
+ <li><a href="functions_vars_0x6c.html#index_l"><span>l</span></a></li>
+ <li><a href="functions_vars_0x6d.html#index_m"><span>m</span></a></li>
+ <li><a href="functions_vars_0x6e.html#index_n"><span>n</span></a></li>
+ <li><a href="functions_vars_0x6f.html#index_o"><span>o</span></a></li>
+ <li><a href="functions_vars_0x70.html#index_p"><span>p</span></a></li>
+ <li><a href="functions_vars_0x71.html#index_q"><span>q</span></a></li>
+ <li><a href="functions_vars_0x72.html#index_r"><span>r</span></a></li>
+ <li><a href="functions_vars_0x73.html#index_s"><span>s</span></a></li>
+ <li><a href="functions_vars_0x74.html#index_t"><span>t</span></a></li>
+ <li class="current"><a href="functions_vars_0x75.html#index_u"><span>u</span></a></li>
+ <li><a href="functions_vars_0x76.html#index_v"><span>v</span></a></li>
+ <li><a href="functions_vars_0x77.html#index_w"><span>w</span></a></li>
+ </ul>
+ </div>
+</div>
+<div class="contents">
+&nbsp;
+
+<h3><a class="anchor" id="index_u"></a>- u -</h3><ul>
+<li>unicode
+: <a class="el" href="structyaml__emitter__s.html#a76372a2413f71a5b36bf77a58d8f5d40">yaml_emitter_s</a>
+</li>
+</ul>
+</div>
+<hr class="footer"/><address class="footer"><small>Generated on Mon May 30 2011 22:00:00 for yaml by&nbsp;
+<a href="http://www.doxygen.org/index.html">
+<img class="footer" src="doxygen.png" alt="doxygen"/></a> 1.7.1 </small></address>
+</body>
+</html>
diff --git a/contrib/libyaml/doc/html/functions_vars_0x76.html b/contrib/libyaml/doc/html/functions_vars_0x76.html
new file mode 100644
index 0000000..4e0d3ae
--- /dev/null
+++ b/contrib/libyaml/doc/html/functions_vars_0x76.html
@@ -0,0 +1,80 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head>
+<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/>
+<title>yaml: Data Fields - Variables</title>
+<link href="tabs.css" rel="stylesheet" type="text/css"/>
+<link href="doxygen.css" rel="stylesheet" type="text/css"/>
+</head>
+<body>
+<!-- Generated by Doxygen 1.7.1 -->
+<div class="navigation" id="top">
+ <div class="tabs">
+ <ul class="tablist">
+ <li><a href="index.html"><span>Main&nbsp;Page</span></a></li>
+ <li><a href="modules.html"><span>Modules</span></a></li>
+ <li class="current"><a href="annotated.html"><span>Data&nbsp;Structures</span></a></li>
+ <li><a href="files.html"><span>Files</span></a></li>
+ </ul>
+ </div>
+ <div class="tabs2">
+ <ul class="tablist">
+ <li><a href="annotated.html"><span>Data&nbsp;Structures</span></a></li>
+ <li class="current"><a href="functions.html"><span>Data&nbsp;Fields</span></a></li>
+ </ul>
+ </div>
+ <div class="tabs2">
+ <ul class="tablist">
+ <li><a href="functions.html"><span>All</span></a></li>
+ <li class="current"><a href="functions_vars.html"><span>Variables</span></a></li>
+ </ul>
+ </div>
+ <div class="tabs3">
+ <ul class="tablist">
+ <li><a href="functions_vars.html#index_a"><span>a</span></a></li>
+ <li><a href="functions_vars_0x62.html#index_b"><span>b</span></a></li>
+ <li><a href="functions_vars_0x63.html#index_c"><span>c</span></a></li>
+ <li><a href="functions_vars_0x64.html#index_d"><span>d</span></a></li>
+ <li><a href="functions_vars_0x65.html#index_e"><span>e</span></a></li>
+ <li><a href="functions_vars_0x66.html#index_f"><span>f</span></a></li>
+ <li><a href="functions_vars_0x68.html#index_h"><span>h</span></a></li>
+ <li><a href="functions_vars_0x69.html#index_i"><span>i</span></a></li>
+ <li><a href="functions_vars_0x6b.html#index_k"><span>k</span></a></li>
+ <li><a href="functions_vars_0x6c.html#index_l"><span>l</span></a></li>
+ <li><a href="functions_vars_0x6d.html#index_m"><span>m</span></a></li>
+ <li><a href="functions_vars_0x6e.html#index_n"><span>n</span></a></li>
+ <li><a href="functions_vars_0x6f.html#index_o"><span>o</span></a></li>
+ <li><a href="functions_vars_0x70.html#index_p"><span>p</span></a></li>
+ <li><a href="functions_vars_0x71.html#index_q"><span>q</span></a></li>
+ <li><a href="functions_vars_0x72.html#index_r"><span>r</span></a></li>
+ <li><a href="functions_vars_0x73.html#index_s"><span>s</span></a></li>
+ <li><a href="functions_vars_0x74.html#index_t"><span>t</span></a></li>
+ <li><a href="functions_vars_0x75.html#index_u"><span>u</span></a></li>
+ <li class="current"><a href="functions_vars_0x76.html#index_v"><span>v</span></a></li>
+ <li><a href="functions_vars_0x77.html#index_w"><span>w</span></a></li>
+ </ul>
+ </div>
+</div>
+<div class="contents">
+&nbsp;
+
+<h3><a class="anchor" id="index_v"></a>- v -</h3><ul>
+<li>value
+: <a class="el" href="structyaml__token__s.html#a97ce52329d6093b63fba36817f8bd549">yaml_token_s</a>
+, <a class="el" href="structyaml__event__s.html#a23436bdddb447d0fc217bab5c5b04a36">yaml_event_s</a>
+, <a class="el" href="structyaml__node__s.html#a0d444412a29609d62699267ae72f971d">yaml_node_s</a>
+, <a class="el" href="structyaml__emitter__s.html#a20246ec76d64854ff93629cf1b424d86">yaml_emitter_s</a>
+, <a class="el" href="structyaml__node__pair__s.html#a56c1de2c11d509462d1bf03803bb8ab1">yaml_node_pair_s</a>
+</li>
+<li>version_directive
+: <a class="el" href="structyaml__document__s.html#a7d36862d070804b8bedb53866487ac6d">yaml_document_s</a>
+, <a class="el" href="structyaml__event__s.html#a5cef7981358ecefdf9d4780b3eacd39b">yaml_event_s</a>
+, <a class="el" href="structyaml__token__s.html#a41b30a59ca22d1020d6af4cc7cc0da47">yaml_token_s</a>
+</li>
+</ul>
+</div>
+<hr class="footer"/><address class="footer"><small>Generated on Mon May 30 2011 22:00:00 for yaml by&nbsp;
+<a href="http://www.doxygen.org/index.html">
+<img class="footer" src="doxygen.png" alt="doxygen"/></a> 1.7.1 </small></address>
+</body>
+</html>
diff --git a/contrib/libyaml/doc/html/functions_vars_0x77.html b/contrib/libyaml/doc/html/functions_vars_0x77.html
new file mode 100644
index 0000000..946db42
--- /dev/null
+++ b/contrib/libyaml/doc/html/functions_vars_0x77.html
@@ -0,0 +1,77 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head>
+<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/>
+<title>yaml: Data Fields - Variables</title>
+<link href="tabs.css" rel="stylesheet" type="text/css"/>
+<link href="doxygen.css" rel="stylesheet" type="text/css"/>
+</head>
+<body>
+<!-- Generated by Doxygen 1.7.1 -->
+<div class="navigation" id="top">
+ <div class="tabs">
+ <ul class="tablist">
+ <li><a href="index.html"><span>Main&nbsp;Page</span></a></li>
+ <li><a href="modules.html"><span>Modules</span></a></li>
+ <li class="current"><a href="annotated.html"><span>Data&nbsp;Structures</span></a></li>
+ <li><a href="files.html"><span>Files</span></a></li>
+ </ul>
+ </div>
+ <div class="tabs2">
+ <ul class="tablist">
+ <li><a href="annotated.html"><span>Data&nbsp;Structures</span></a></li>
+ <li class="current"><a href="functions.html"><span>Data&nbsp;Fields</span></a></li>
+ </ul>
+ </div>
+ <div class="tabs2">
+ <ul class="tablist">
+ <li><a href="functions.html"><span>All</span></a></li>
+ <li class="current"><a href="functions_vars.html"><span>Variables</span></a></li>
+ </ul>
+ </div>
+ <div class="tabs3">
+ <ul class="tablist">
+ <li><a href="functions_vars.html#index_a"><span>a</span></a></li>
+ <li><a href="functions_vars_0x62.html#index_b"><span>b</span></a></li>
+ <li><a href="functions_vars_0x63.html#index_c"><span>c</span></a></li>
+ <li><a href="functions_vars_0x64.html#index_d"><span>d</span></a></li>
+ <li><a href="functions_vars_0x65.html#index_e"><span>e</span></a></li>
+ <li><a href="functions_vars_0x66.html#index_f"><span>f</span></a></li>
+ <li><a href="functions_vars_0x68.html#index_h"><span>h</span></a></li>
+ <li><a href="functions_vars_0x69.html#index_i"><span>i</span></a></li>
+ <li><a href="functions_vars_0x6b.html#index_k"><span>k</span></a></li>
+ <li><a href="functions_vars_0x6c.html#index_l"><span>l</span></a></li>
+ <li><a href="functions_vars_0x6d.html#index_m"><span>m</span></a></li>
+ <li><a href="functions_vars_0x6e.html#index_n"><span>n</span></a></li>
+ <li><a href="functions_vars_0x6f.html#index_o"><span>o</span></a></li>
+ <li><a href="functions_vars_0x70.html#index_p"><span>p</span></a></li>
+ <li><a href="functions_vars_0x71.html#index_q"><span>q</span></a></li>
+ <li><a href="functions_vars_0x72.html#index_r"><span>r</span></a></li>
+ <li><a href="functions_vars_0x73.html#index_s"><span>s</span></a></li>
+ <li><a href="functions_vars_0x74.html#index_t"><span>t</span></a></li>
+ <li><a href="functions_vars_0x75.html#index_u"><span>u</span></a></li>
+ <li><a href="functions_vars_0x76.html#index_v"><span>v</span></a></li>
+ <li class="current"><a href="functions_vars_0x77.html#index_w"><span>w</span></a></li>
+ </ul>
+ </div>
+</div>
+<div class="contents">
+&nbsp;
+
+<h3><a class="anchor" id="index_w"></a>- w -</h3><ul>
+<li>whitespace
+: <a class="el" href="structyaml__emitter__s.html#a160ed0cf1cc6116b65772d14ced2d867">yaml_emitter_s</a>
+</li>
+<li>write_handler
+: <a class="el" href="structyaml__emitter__s.html#aefa7e29ba8042ed1d133a02bb368ea3e">yaml_emitter_s</a>
+</li>
+<li>write_handler_data
+: <a class="el" href="structyaml__emitter__s.html#a6c4fe0176b69da64ac1ddc7e091967e5">yaml_emitter_s</a>
+</li>
+</ul>
+</div>
+<hr class="footer"/><address class="footer"><small>Generated on Mon May 30 2011 22:00:00 for yaml by&nbsp;
+<a href="http://www.doxygen.org/index.html">
+<img class="footer" src="doxygen.png" alt="doxygen"/></a> 1.7.1 </small></address>
+</body>
+</html>
diff --git a/contrib/libyaml/doc/html/globals.html b/contrib/libyaml/doc/html/globals.html
new file mode 100644
index 0000000..eb4fc4e
--- /dev/null
+++ b/contrib/libyaml/doc/html/globals.html
@@ -0,0 +1,667 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head>
+<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/>
+<title>yaml: Data Fields</title>
+<link href="tabs.css" rel="stylesheet" type="text/css"/>
+<link href="doxygen.css" rel="stylesheet" type="text/css"/>
+</head>
+<body>
+<!-- Generated by Doxygen 1.7.1 -->
+<div class="navigation" id="top">
+ <div class="tabs">
+ <ul class="tablist">
+ <li><a href="index.html"><span>Main&nbsp;Page</span></a></li>
+ <li><a href="modules.html"><span>Modules</span></a></li>
+ <li><a href="annotated.html"><span>Data&nbsp;Structures</span></a></li>
+ <li class="current"><a href="files.html"><span>Files</span></a></li>
+ </ul>
+ </div>
+ <div class="tabs2">
+ <ul class="tablist">
+ <li><a href="files.html"><span>File&nbsp;List</span></a></li>
+ <li class="current"><a href="globals.html"><span>Globals</span></a></li>
+ </ul>
+ </div>
+ <div class="tabs2">
+ <ul class="tablist">
+ <li class="current"><a href="globals.html"><span>All</span></a></li>
+ <li><a href="globals_func.html"><span>Functions</span></a></li>
+ <li><a href="globals_type.html"><span>Typedefs</span></a></li>
+ <li><a href="globals_enum.html"><span>Enumerations</span></a></li>
+ <li><a href="globals_eval.html"><span>Enumerator</span></a></li>
+ <li><a href="globals_defs.html"><span>Defines</span></a></li>
+ </ul>
+ </div>
+ <div class="tabs3">
+ <ul class="tablist">
+ <li class="current"><a href="globals.html#index_y"><span>y</span></a></li>
+ </ul>
+ </div>
+</div>
+<div class="contents">
+Here is a list of all documented functions, variables, defines, enums, and typedefs with links to the documentation:
+
+<h3><a class="anchor" id="index_y"></a>- y -</h3><ul>
+<li>yaml_alias_data_t
+: <a class="el" href="group__parser.html#ga1434228b82f5f90d3c8ccda816e9ca9d">yaml.h</a>
+</li>
+<li>YAML_ALIAS_EVENT
+: <a class="el" href="group__events.html#gga454fccebae859c188fe3e7fa3299577ca8c3ce47705cfbd49a87a32bdbe544eb7">yaml.h</a>
+</li>
+<li>yaml_alias_event_initialize()
+: <a class="el" href="group__events.html#gade4c15b75eb9a8035e04d4f0dd23f005">yaml.h</a>
+</li>
+<li>YAML_ALIAS_TOKEN
+: <a class="el" href="group__tokens.html#ggaae955b10aa6b5f922de64873bf4ccdbda080c398f6fc31f9ab35c7cf94cf948c2">yaml.h</a>
+</li>
+<li>YAML_ANCHOR_TOKEN
+: <a class="el" href="group__tokens.html#ggaae955b10aa6b5f922de64873bf4ccdbda7f0855938c5ccc4820b68ddd7985a5d0">yaml.h</a>
+</li>
+<li>YAML_ANY_BREAK
+: <a class="el" href="group__basic.html#gga912ad8c893126133fab5e4231db3017ea052bd56adef565c33a86fcc05b49513f">yaml.h</a>
+</li>
+<li>YAML_ANY_ENCODING
+: <a class="el" href="group__basic.html#ggab88ee52b5d722e644c1cb4d1afcccdd9ab61d2a81b8e698e642ce6ad69612fa7f">yaml.h</a>
+</li>
+<li>YAML_ANY_MAPPING_STYLE
+: <a class="el" href="group__styles.html#gga1efef592e2e3df6f00432c04ef77d98fac580a83312204ea142c3d08a4954a74a">yaml.h</a>
+</li>
+<li>YAML_ANY_SCALAR_STYLE
+: <a class="el" href="group__styles.html#gga435ae8886b70c16830d853b6c566e2e0aead38b3e6846302ee032927267c34ae0">yaml.h</a>
+</li>
+<li>YAML_ANY_SEQUENCE_STYLE
+: <a class="el" href="group__styles.html#gga5079a4ab96e398371c60423abd88ccc0a5a10d6f70339876b76e5a002dd16212f">yaml.h</a>
+</li>
+<li>YAML_BLOCK_END_TOKEN
+: <a class="el" href="group__tokens.html#ggaae955b10aa6b5f922de64873bf4ccdbda439948425097b4fc853f39f0de14a5ff">yaml.h</a>
+</li>
+<li>YAML_BLOCK_ENTRY_TOKEN
+: <a class="el" href="group__tokens.html#ggaae955b10aa6b5f922de64873bf4ccdbdaa9bdf1d6da41fcd4d356c7bcfa0227b4">yaml.h</a>
+</li>
+<li>YAML_BLOCK_MAPPING_START_TOKEN
+: <a class="el" href="group__tokens.html#ggaae955b10aa6b5f922de64873bf4ccdbda9a95db99bd99f7f9b4e1e879106297dc">yaml.h</a>
+</li>
+<li>YAML_BLOCK_MAPPING_STYLE
+: <a class="el" href="group__styles.html#gga1efef592e2e3df6f00432c04ef77d98fad5e70fe97009c8247a45f4620f071874">yaml.h</a>
+</li>
+<li>YAML_BLOCK_SEQUENCE_START_TOKEN
+: <a class="el" href="group__tokens.html#ggaae955b10aa6b5f922de64873bf4ccdbda4bfddc427da159168ee47267cbeea94f">yaml.h</a>
+</li>
+<li>YAML_BLOCK_SEQUENCE_STYLE
+: <a class="el" href="group__styles.html#gga5079a4ab96e398371c60423abd88ccc0a65f99099ef4ecdcf99bbdd798b5dcbb5">yaml.h</a>
+</li>
+<li>YAML_BOOL_TAG
+: <a class="el" href="group__nodes.html#ga312629a1f51e91b136352db988d4d771">yaml.h</a>
+</li>
+<li>yaml_break_e
+: <a class="el" href="group__basic.html#ga912ad8c893126133fab5e4231db3017e">yaml.h</a>
+</li>
+<li>yaml_break_t
+: <a class="el" href="group__basic.html#ga64d1365e1acd4deeab50d6b48e39cb6d">yaml.h</a>
+</li>
+<li>yaml_char_t
+: <a class="el" href="group__basic.html#gaf8657e81f0b8b05d1a081001fc6cb8bd">yaml.h</a>
+</li>
+<li>YAML_COMPOSER_ERROR
+: <a class="el" href="group__basic.html#gga2efbcde2e82238117982b789c5a8ea01a43d6eb640e50a1b1ec843cc54ab15f2b">yaml.h</a>
+</li>
+<li>YAML_CR_BREAK
+: <a class="el" href="group__basic.html#gga912ad8c893126133fab5e4231db3017ea116a98ba4ed0bacfdf098a7d5beeb9d4">yaml.h</a>
+</li>
+<li>YAML_CRLN_BREAK
+: <a class="el" href="group__basic.html#gga912ad8c893126133fab5e4231db3017ea15f8daa406870ebfe82b85781c2468f3">yaml.h</a>
+</li>
+<li>YAML_DECLARE
+: <a class="el" href="group__export.html#ga0791fd3e1d85ed53711b1feaae131f93">yaml.h</a>
+</li>
+<li>YAML_DEFAULT_MAPPING_TAG
+: <a class="el" href="group__nodes.html#gaf7b1f8f0ce5665794510cd3841802a5f">yaml.h</a>
+</li>
+<li>YAML_DEFAULT_SCALAR_TAG
+: <a class="el" href="group__nodes.html#gaf6b0c4e819b8f6915515a4f70065aaaa">yaml.h</a>
+</li>
+<li>YAML_DEFAULT_SEQUENCE_TAG
+: <a class="el" href="group__nodes.html#gaf195b67002518702e27746d6b4da6124">yaml.h</a>
+</li>
+<li>yaml_document_add_mapping()
+: <a class="el" href="group__nodes.html#ga45a9f8288704f99cd81dc5cb31329d34">yaml.h</a>
+</li>
+<li>yaml_document_add_scalar()
+: <a class="el" href="group__nodes.html#ga45dab8b983b58a005557d4b01f5057b0">yaml.h</a>
+</li>
+<li>yaml_document_add_sequence()
+: <a class="el" href="group__nodes.html#ga83b2f7fdd9a439397a42016bddad7786">yaml.h</a>
+</li>
+<li>yaml_document_append_mapping_pair()
+: <a class="el" href="group__nodes.html#ga2db27002d8a9ae06b1729d0ee06553d2">yaml.h</a>
+</li>
+<li>yaml_document_append_sequence_item()
+: <a class="el" href="group__nodes.html#ga16435917cd6c0261cd390fa8cf173b1b">yaml.h</a>
+</li>
+<li>yaml_document_delete()
+: <a class="el" href="group__nodes.html#ga2754b1544fb4e110e83fafbc708b0672">yaml.h</a>
+</li>
+<li>YAML_DOCUMENT_END_EVENT
+: <a class="el" href="group__events.html#gga454fccebae859c188fe3e7fa3299577ca355ec471f963827c96512e529676276f">yaml.h</a>
+</li>
+<li>yaml_document_end_event_initialize()
+: <a class="el" href="group__events.html#ga8bae16548ee88f8a5ca15204f8c30344">yaml.h</a>
+</li>
+<li>YAML_DOCUMENT_END_TOKEN
+: <a class="el" href="group__tokens.html#ggaae955b10aa6b5f922de64873bf4ccdbda8d0908a82229f44d5ea92a2c380f4579">yaml.h</a>
+</li>
+<li>yaml_document_get_node()
+: <a class="el" href="group__nodes.html#gafa1feabc9747dbded4dca24e27d3c21a">yaml.h</a>
+</li>
+<li>yaml_document_get_root_node()
+: <a class="el" href="group__nodes.html#ga40eeaa68fb2f3be34c4fe34e7597d324">yaml.h</a>
+</li>
+<li>yaml_document_initialize()
+: <a class="el" href="group__nodes.html#ga62a485c96f3b7962436a0da5e6f3cc89">yaml.h</a>
+</li>
+<li>YAML_DOCUMENT_START_EVENT
+: <a class="el" href="group__events.html#gga454fccebae859c188fe3e7fa3299577caf4ca2b0f538029cf054cdebd09d3d6d3">yaml.h</a>
+</li>
+<li>yaml_document_start_event_initialize()
+: <a class="el" href="group__events.html#ga527e89302e1c969fbea5aa45664bf51c">yaml.h</a>
+</li>
+<li>YAML_DOCUMENT_START_TOKEN
+: <a class="el" href="group__tokens.html#ggaae955b10aa6b5f922de64873bf4ccdbdabcafcdb506886387f93cca734ddfd670">yaml.h</a>
+</li>
+<li>yaml_document_t
+: <a class="el" href="group__nodes.html#gad94e064e95baeb22e4f7acc7804e8479">yaml.h</a>
+</li>
+<li>YAML_DOUBLE_QUOTED_SCALAR_STYLE
+: <a class="el" href="group__styles.html#gga435ae8886b70c16830d853b6c566e2e0af6fdfd14690361f4937d67d1f0f011d3">yaml.h</a>
+</li>
+<li>YAML_EMIT_BLOCK_MAPPING_FIRST_KEY_STATE
+: <a class="el" href="group__emitter.html#gga387b79da11c3941e43a56947263aa721aee36d46c1facecfd73fab73e3343226e">yaml.h</a>
+</li>
+<li>YAML_EMIT_BLOCK_MAPPING_KEY_STATE
+: <a class="el" href="group__emitter.html#gga387b79da11c3941e43a56947263aa721a58495cae63b8c3d7c389b1281baeec05">yaml.h</a>
+</li>
+<li>YAML_EMIT_BLOCK_MAPPING_SIMPLE_VALUE_STATE
+: <a class="el" href="group__emitter.html#gga387b79da11c3941e43a56947263aa721a4aa3c6bf2f2d976c47289c741d7a8704">yaml.h</a>
+</li>
+<li>YAML_EMIT_BLOCK_MAPPING_VALUE_STATE
+: <a class="el" href="group__emitter.html#gga387b79da11c3941e43a56947263aa721a7e0f7fac64fc64bb2bc9fe2ec93ca564">yaml.h</a>
+</li>
+<li>YAML_EMIT_BLOCK_SEQUENCE_FIRST_ITEM_STATE
+: <a class="el" href="group__emitter.html#gga387b79da11c3941e43a56947263aa721a68af7c090c6d0187788e390341f0cc4d">yaml.h</a>
+</li>
+<li>YAML_EMIT_BLOCK_SEQUENCE_ITEM_STATE
+: <a class="el" href="group__emitter.html#gga387b79da11c3941e43a56947263aa721a8197c180c3cefee7b67304e17b52c5ff">yaml.h</a>
+</li>
+<li>YAML_EMIT_DOCUMENT_CONTENT_STATE
+: <a class="el" href="group__emitter.html#gga387b79da11c3941e43a56947263aa721a5ce3ed6155496a6fbd7384e310c58bec">yaml.h</a>
+</li>
+<li>YAML_EMIT_DOCUMENT_END_STATE
+: <a class="el" href="group__emitter.html#gga387b79da11c3941e43a56947263aa721a100cad4538be033202da4bb85f8443d3">yaml.h</a>
+</li>
+<li>YAML_EMIT_DOCUMENT_START_STATE
+: <a class="el" href="group__emitter.html#gga387b79da11c3941e43a56947263aa721a678d8c3146f0b2c84e0fc537a9b1109f">yaml.h</a>
+</li>
+<li>YAML_EMIT_END_STATE
+: <a class="el" href="group__emitter.html#gga387b79da11c3941e43a56947263aa721a2a0232912eaf4eeb06594ee6157dfbc0">yaml.h</a>
+</li>
+<li>YAML_EMIT_FIRST_DOCUMENT_START_STATE
+: <a class="el" href="group__emitter.html#gga387b79da11c3941e43a56947263aa721ab1ae25188f02581a137f66c4b6e084ae">yaml.h</a>
+</li>
+<li>YAML_EMIT_FLOW_MAPPING_FIRST_KEY_STATE
+: <a class="el" href="group__emitter.html#gga387b79da11c3941e43a56947263aa721ab811f3d642dacc7c413af2c32356f894">yaml.h</a>
+</li>
+<li>YAML_EMIT_FLOW_MAPPING_KEY_STATE
+: <a class="el" href="group__emitter.html#gga387b79da11c3941e43a56947263aa721ababf835ee5cd4c6de2231e2a49e40626">yaml.h</a>
+</li>
+<li>YAML_EMIT_FLOW_MAPPING_SIMPLE_VALUE_STATE
+: <a class="el" href="group__emitter.html#gga387b79da11c3941e43a56947263aa721aa6f687a6b57e727f0e7b7a2687ad7383">yaml.h</a>
+</li>
+<li>YAML_EMIT_FLOW_MAPPING_VALUE_STATE
+: <a class="el" href="group__emitter.html#gga387b79da11c3941e43a56947263aa721acb6dbcb535248b8fde779aeedc957b2e">yaml.h</a>
+</li>
+<li>YAML_EMIT_FLOW_SEQUENCE_FIRST_ITEM_STATE
+: <a class="el" href="group__emitter.html#gga387b79da11c3941e43a56947263aa721a5a36fc535f3a5720fbb86712959e5654">yaml.h</a>
+</li>
+<li>YAML_EMIT_FLOW_SEQUENCE_ITEM_STATE
+: <a class="el" href="group__emitter.html#gga387b79da11c3941e43a56947263aa721aded45f1dee80027d7b9c6ce061c08767">yaml.h</a>
+</li>
+<li>YAML_EMIT_STREAM_START_STATE
+: <a class="el" href="group__emitter.html#gga387b79da11c3941e43a56947263aa721aa013a33dab710fe9a30ba014af27b81d">yaml.h</a>
+</li>
+<li>yaml_emitter_close()
+: <a class="el" href="group__emitter.html#gaa91442864679280985df14b2d96b8c42">yaml.h</a>
+</li>
+<li>yaml_emitter_delete()
+: <a class="el" href="group__emitter.html#gad705212f3a5150e3f00075fd90bc8c3d">yaml.h</a>
+</li>
+<li>yaml_emitter_dump()
+: <a class="el" href="group__emitter.html#ga5f0306abe9bff373b5bc339913b3769c">yaml.h</a>
+</li>
+<li>yaml_emitter_emit()
+: <a class="el" href="group__emitter.html#ga4d6c0f8e712797e2660e69479fdae433">yaml.h</a>
+</li>
+<li>YAML_EMITTER_ERROR
+: <a class="el" href="group__basic.html#gga2efbcde2e82238117982b789c5a8ea01a8ec99a26382dd2853a5550027f6e9db1">yaml.h</a>
+</li>
+<li>yaml_emitter_flush()
+: <a class="el" href="group__emitter.html#gacaf24456e2bf85bc5654cbd7d828055f">yaml.h</a>
+</li>
+<li>yaml_emitter_initialize()
+: <a class="el" href="group__emitter.html#ga83649205374285802fc27aa293ecd111">yaml.h</a>
+</li>
+<li>yaml_emitter_open()
+: <a class="el" href="group__emitter.html#gae323c34e378040106f24c7b5ab834b16">yaml.h</a>
+</li>
+<li>yaml_emitter_set_break()
+: <a class="el" href="group__emitter.html#ga04b5494f0b8244eec359579c31d5e20c">yaml.h</a>
+</li>
+<li>yaml_emitter_set_canonical()
+: <a class="el" href="group__emitter.html#ga62713a8130e11d95cbefa95a2eb3ac4b">yaml.h</a>
+</li>
+<li>yaml_emitter_set_encoding()
+: <a class="el" href="group__emitter.html#gabc22888ec8bf942199acbf38f7a0b9bb">yaml.h</a>
+</li>
+<li>yaml_emitter_set_indent()
+: <a class="el" href="group__emitter.html#ga07eca3c344053a9028b4a84291cdf4d7">yaml.h</a>
+</li>
+<li>yaml_emitter_set_output()
+: <a class="el" href="group__emitter.html#gac85a6a212ed7b469fb426a3451d15922">yaml.h</a>
+</li>
+<li>yaml_emitter_set_output_file()
+: <a class="el" href="group__emitter.html#gaf7610c61b303bde9c701024c10ece024">yaml.h</a>
+</li>
+<li>yaml_emitter_set_output_string()
+: <a class="el" href="group__emitter.html#ga62725c0f616f634588374d1a4c0ed35a">yaml.h</a>
+</li>
+<li>yaml_emitter_set_unicode()
+: <a class="el" href="group__emitter.html#gaa59e7dcf24cb9b614c32af6c3e949fc3">yaml.h</a>
+</li>
+<li>yaml_emitter_set_width()
+: <a class="el" href="group__emitter.html#gaa91ae0fa8af5ab67e64567e08f4458c2">yaml.h</a>
+</li>
+<li>yaml_emitter_state_e
+: <a class="el" href="group__emitter.html#ga387b79da11c3941e43a56947263aa721">yaml.h</a>
+</li>
+<li>yaml_emitter_state_t
+: <a class="el" href="group__emitter.html#ga0889461fa3efe8eee881aef48a4ba6b2">yaml.h</a>
+</li>
+<li>yaml_emitter_t
+: <a class="el" href="group__emitter.html#ga4ce3e054f0016c49d9e8c36d359e710b">yaml.h</a>
+</li>
+<li>yaml_encoding_e
+: <a class="el" href="group__basic.html#gab88ee52b5d722e644c1cb4d1afcccdd9">yaml.h</a>
+</li>
+<li>yaml_encoding_t
+: <a class="el" href="group__basic.html#ga2170996d7e636397b5e6bc0c1b7df7c6">yaml.h</a>
+</li>
+<li>yaml_error_type_e
+: <a class="el" href="group__basic.html#ga2efbcde2e82238117982b789c5a8ea01">yaml.h</a>
+</li>
+<li>yaml_error_type_t
+: <a class="el" href="group__basic.html#ga1a449f0c1b023e2ef1a596093c018e73">yaml.h</a>
+</li>
+<li>yaml_event_delete()
+: <a class="el" href="group__events.html#ga5330d62ef52856aa53188137cb93a6a1">yaml.h</a>
+</li>
+<li>yaml_event_t
+: <a class="el" href="group__events.html#ga3b392d9716c4920cabefdd29e78dd542">yaml.h</a>
+</li>
+<li>yaml_event_type_e
+: <a class="el" href="group__events.html#ga454fccebae859c188fe3e7fa3299577c">yaml.h</a>
+</li>
+<li>yaml_event_type_t
+: <a class="el" href="group__events.html#ga8934661be36bd7c9d17a8af69eff89a1">yaml.h</a>
+</li>
+<li>YAML_FLOAT_TAG
+: <a class="el" href="group__nodes.html#ga6ab2ec71fc47cb24f1003b9acdb92843">yaml.h</a>
+</li>
+<li>YAML_FLOW_ENTRY_TOKEN
+: <a class="el" href="group__tokens.html#ggaae955b10aa6b5f922de64873bf4ccdbdaf11ab5655350e4cf0559f78382daa93f">yaml.h</a>
+</li>
+<li>YAML_FLOW_MAPPING_END_TOKEN
+: <a class="el" href="group__tokens.html#ggaae955b10aa6b5f922de64873bf4ccdbdaad99bf47234572d9d0eeea7669d1e769">yaml.h</a>
+</li>
+<li>YAML_FLOW_MAPPING_START_TOKEN
+: <a class="el" href="group__tokens.html#ggaae955b10aa6b5f922de64873bf4ccdbdaff68a3f7c000c5294211eef8f4156100">yaml.h</a>
+</li>
+<li>YAML_FLOW_MAPPING_STYLE
+: <a class="el" href="group__styles.html#gga1efef592e2e3df6f00432c04ef77d98fa4c5425077b0310cbf84e1d73e20b42d3">yaml.h</a>
+</li>
+<li>YAML_FLOW_SEQUENCE_END_TOKEN
+: <a class="el" href="group__tokens.html#ggaae955b10aa6b5f922de64873bf4ccdbdab3496580bee30936f756e0102e98f331">yaml.h</a>
+</li>
+<li>YAML_FLOW_SEQUENCE_START_TOKEN
+: <a class="el" href="group__tokens.html#ggaae955b10aa6b5f922de64873bf4ccdbda862a2390be4abd59bb7bf55b18d9260c">yaml.h</a>
+</li>
+<li>YAML_FLOW_SEQUENCE_STYLE
+: <a class="el" href="group__styles.html#gga5079a4ab96e398371c60423abd88ccc0ae511554b654ebca464d1feec12501d80">yaml.h</a>
+</li>
+<li>YAML_FOLDED_SCALAR_STYLE
+: <a class="el" href="group__styles.html#gga435ae8886b70c16830d853b6c566e2e0aa67c3de37dc127986b08bdbe07cee607">yaml.h</a>
+</li>
+<li>yaml_get_version()
+: <a class="el" href="group__version.html#gaec764c91f3e181ae63d3d59b7980fe78">yaml.h</a>
+</li>
+<li>yaml_get_version_string()
+: <a class="el" href="group__version.html#gaf1ba5c1c34e809db5047d79a9fa85a73">yaml.h</a>
+</li>
+<li>YAML_INT_TAG
+: <a class="el" href="group__nodes.html#ga83263cdb4ffa6ad2f7d9a87281979ff5">yaml.h</a>
+</li>
+<li>YAML_KEY_TOKEN
+: <a class="el" href="group__tokens.html#ggaae955b10aa6b5f922de64873bf4ccdbda94d701c1f5bb8a392bb45b7cbf4bc2a5">yaml.h</a>
+</li>
+<li>YAML_LITERAL_SCALAR_STYLE
+: <a class="el" href="group__styles.html#gga435ae8886b70c16830d853b6c566e2e0a542d1ac1bf5c3434df3d2a757d0a8ca0">yaml.h</a>
+</li>
+<li>YAML_LN_BREAK
+: <a class="el" href="group__basic.html#gga912ad8c893126133fab5e4231db3017ea23bf395462dcd045e22303be6f3f7781">yaml.h</a>
+</li>
+<li>YAML_MAP_TAG
+: <a class="el" href="group__nodes.html#ga22ae99cf3ac014dd76873268fd068c12">yaml.h</a>
+</li>
+<li>YAML_MAPPING_END_EVENT
+: <a class="el" href="group__events.html#gga454fccebae859c188fe3e7fa3299577cadc3dc55f17056a657005fecfb80fbd30">yaml.h</a>
+</li>
+<li>yaml_mapping_end_event_initialize()
+: <a class="el" href="group__events.html#ga3afaf8b3aca2ec902a4e268f12adb0c2">yaml.h</a>
+</li>
+<li>YAML_MAPPING_NODE
+: <a class="el" href="group__nodes.html#gga0897d4b6bdd1b56c7a5fa0ff17b4f798ac1a08580e3a70973583fc85e3e097ee6">yaml.h</a>
+</li>
+<li>YAML_MAPPING_START_EVENT
+: <a class="el" href="group__events.html#gga454fccebae859c188fe3e7fa3299577ca0f6982f6d1c325ee71af518c2c66dae8">yaml.h</a>
+</li>
+<li>yaml_mapping_start_event_initialize()
+: <a class="el" href="group__events.html#ga0603cf8d20f0b6dfc3be04b6360134aa">yaml.h</a>
+</li>
+<li>yaml_mapping_style_e
+: <a class="el" href="group__styles.html#ga1efef592e2e3df6f00432c04ef77d98f">yaml.h</a>
+</li>
+<li>yaml_mapping_style_t
+: <a class="el" href="group__styles.html#gab47523846a5c5960e07367a28ea9750a">yaml.h</a>
+</li>
+<li>yaml_mark_t
+: <a class="el" href="group__basic.html#ga232eacba89691b841ba941338a302bfd">yaml.h</a>
+</li>
+<li>YAML_MEMORY_ERROR
+: <a class="el" href="group__basic.html#gga2efbcde2e82238117982b789c5a8ea01a57be0407d1f344206d9673c9571bde53">yaml.h</a>
+</li>
+<li>YAML_NO_ERROR
+: <a class="el" href="group__basic.html#gga2efbcde2e82238117982b789c5a8ea01a24cadfb5364769959ad8647649d1e86f">yaml.h</a>
+</li>
+<li>YAML_NO_EVENT
+: <a class="el" href="group__events.html#gga454fccebae859c188fe3e7fa3299577caefda9f31823fe534f094f4241d5e5eac">yaml.h</a>
+</li>
+<li>YAML_NO_NODE
+: <a class="el" href="group__nodes.html#gga0897d4b6bdd1b56c7a5fa0ff17b4f798a0fa87c0e89c4d4136cb47165e6917739">yaml.h</a>
+</li>
+<li>YAML_NO_TOKEN
+: <a class="el" href="group__tokens.html#ggaae955b10aa6b5f922de64873bf4ccdbda66c1b8eec0cc6402c0fb4b2d1b017f92">yaml.h</a>
+</li>
+<li>yaml_node_item_t
+: <a class="el" href="group__nodes.html#ga7cc3581582e778b00c04e99cd3656860">yaml.h</a>
+</li>
+<li>yaml_node_pair_t
+: <a class="el" href="group__nodes.html#ga90f1c8b83c5c38dc4016afc1cc2050c4">yaml.h</a>
+</li>
+<li>yaml_node_t
+: <a class="el" href="group__nodes.html#ga9eaaa233b120b9d9db47de93c294c40f">yaml.h</a>
+</li>
+<li>yaml_node_type_e
+: <a class="el" href="group__nodes.html#ga0897d4b6bdd1b56c7a5fa0ff17b4f798">yaml.h</a>
+</li>
+<li>yaml_node_type_t
+: <a class="el" href="group__nodes.html#gabe020d2fc42d3e896549e9f97da622d2">yaml.h</a>
+</li>
+<li>YAML_NULL_TAG
+: <a class="el" href="group__nodes.html#gadfa882b6e42a3a993d12392d55260b00">yaml.h</a>
+</li>
+<li>YAML_PARSE_BLOCK_MAPPING_FIRST_KEY_STATE
+: <a class="el" href="group__parser.html#ggad39c19e7b0df6f542ca97806535b57c5afebcb5bbd67d112d9ecfa633155f0644">yaml.h</a>
+</li>
+<li>YAML_PARSE_BLOCK_MAPPING_KEY_STATE
+: <a class="el" href="group__parser.html#ggad39c19e7b0df6f542ca97806535b57c5a2df81c86e90b874b415ecb19e72efe45">yaml.h</a>
+</li>
+<li>YAML_PARSE_BLOCK_MAPPING_VALUE_STATE
+: <a class="el" href="group__parser.html#ggad39c19e7b0df6f542ca97806535b57c5ae94acf5685fa1538b225413f154465c2">yaml.h</a>
+</li>
+<li>YAML_PARSE_BLOCK_NODE_OR_INDENTLESS_SEQUENCE_STATE
+: <a class="el" href="group__parser.html#ggad39c19e7b0df6f542ca97806535b57c5acbd390af0d3919fe0382d03c284ff3b5">yaml.h</a>
+</li>
+<li>YAML_PARSE_BLOCK_NODE_STATE
+: <a class="el" href="group__parser.html#ggad39c19e7b0df6f542ca97806535b57c5ae1893c0835bacf05cdc21ed181fb75f1">yaml.h</a>
+</li>
+<li>YAML_PARSE_BLOCK_SEQUENCE_ENTRY_STATE
+: <a class="el" href="group__parser.html#ggad39c19e7b0df6f542ca97806535b57c5a8a6cb1f12fe08eee7fc2fa854dbd5b1a">yaml.h</a>
+</li>
+<li>YAML_PARSE_BLOCK_SEQUENCE_FIRST_ENTRY_STATE
+: <a class="el" href="group__parser.html#ggad39c19e7b0df6f542ca97806535b57c5a5bb5f95fc5f1a258ee8e9db0ed25b2d9">yaml.h</a>
+</li>
+<li>YAML_PARSE_DOCUMENT_CONTENT_STATE
+: <a class="el" href="group__parser.html#ggad39c19e7b0df6f542ca97806535b57c5ae444c7652c8029b0ef80068eaaaa3d4d">yaml.h</a>
+</li>
+<li>YAML_PARSE_DOCUMENT_END_STATE
+: <a class="el" href="group__parser.html#ggad39c19e7b0df6f542ca97806535b57c5aeef06d7f13fa4501146a5b9876c98239">yaml.h</a>
+</li>
+<li>YAML_PARSE_DOCUMENT_START_STATE
+: <a class="el" href="group__parser.html#ggad39c19e7b0df6f542ca97806535b57c5aa06d10f700d245caecfc6074a6c52fde">yaml.h</a>
+</li>
+<li>YAML_PARSE_END_STATE
+: <a class="el" href="group__parser.html#ggad39c19e7b0df6f542ca97806535b57c5a51fd3d45693e2240251996def375a2a2">yaml.h</a>
+</li>
+<li>YAML_PARSE_FLOW_MAPPING_EMPTY_VALUE_STATE
+: <a class="el" href="group__parser.html#ggad39c19e7b0df6f542ca97806535b57c5a5a8ec0af5c3314c1ad5e0569b6a5d6d2">yaml.h</a>
+</li>
+<li>YAML_PARSE_FLOW_MAPPING_FIRST_KEY_STATE
+: <a class="el" href="group__parser.html#ggad39c19e7b0df6f542ca97806535b57c5a91ac4bbb6629e2b768a3305fb707b7cd">yaml.h</a>
+</li>
+<li>YAML_PARSE_FLOW_MAPPING_KEY_STATE
+: <a class="el" href="group__parser.html#ggad39c19e7b0df6f542ca97806535b57c5a924f8eb891dc7527bf4db594a0b1bff8">yaml.h</a>
+</li>
+<li>YAML_PARSE_FLOW_MAPPING_VALUE_STATE
+: <a class="el" href="group__parser.html#ggad39c19e7b0df6f542ca97806535b57c5a3ba351f6cfba029248ada2c0720246d4">yaml.h</a>
+</li>
+<li>YAML_PARSE_FLOW_NODE_STATE
+: <a class="el" href="group__parser.html#ggad39c19e7b0df6f542ca97806535b57c5a5bb321f9d18c5b208a71c04bbcbd1d01">yaml.h</a>
+</li>
+<li>YAML_PARSE_FLOW_SEQUENCE_ENTRY_MAPPING_END_STATE
+: <a class="el" href="group__parser.html#ggad39c19e7b0df6f542ca97806535b57c5a397fd87de9227c64e5308481930b5eeb">yaml.h</a>
+</li>
+<li>YAML_PARSE_FLOW_SEQUENCE_ENTRY_MAPPING_KEY_STATE
+: <a class="el" href="group__parser.html#ggad39c19e7b0df6f542ca97806535b57c5a563e11601cf3a1d2a3efc1feb1b696a3">yaml.h</a>
+</li>
+<li>YAML_PARSE_FLOW_SEQUENCE_ENTRY_MAPPING_VALUE_STATE
+: <a class="el" href="group__parser.html#ggad39c19e7b0df6f542ca97806535b57c5a9e5ebb4bee4541e7a7025689c7fc66eb">yaml.h</a>
+</li>
+<li>YAML_PARSE_FLOW_SEQUENCE_ENTRY_STATE
+: <a class="el" href="group__parser.html#ggad39c19e7b0df6f542ca97806535b57c5a0e50f3841eb0d37ad159e64c4a9a1171">yaml.h</a>
+</li>
+<li>YAML_PARSE_FLOW_SEQUENCE_FIRST_ENTRY_STATE
+: <a class="el" href="group__parser.html#ggad39c19e7b0df6f542ca97806535b57c5a3f54830989c12cc4a63494df792eeb08">yaml.h</a>
+</li>
+<li>YAML_PARSE_IMPLICIT_DOCUMENT_START_STATE
+: <a class="el" href="group__parser.html#ggad39c19e7b0df6f542ca97806535b57c5a8255725d67d5bd3574fc7df4db1c6c84">yaml.h</a>
+</li>
+<li>YAML_PARSE_INDENTLESS_SEQUENCE_ENTRY_STATE
+: <a class="el" href="group__parser.html#ggad39c19e7b0df6f542ca97806535b57c5af7095f2141cf9887489e832f0ec61fbd">yaml.h</a>
+</li>
+<li>YAML_PARSE_STREAM_START_STATE
+: <a class="el" href="group__parser.html#ggad39c19e7b0df6f542ca97806535b57c5ae7b52e16bf002db5cf2944596d8c880e">yaml.h</a>
+</li>
+<li>yaml_parser_delete()
+: <a class="el" href="group__parser.html#gaa27150107c4667c1024ec0651e2ac26b">yaml.h</a>
+</li>
+<li>YAML_PARSER_ERROR
+: <a class="el" href="group__basic.html#gga2efbcde2e82238117982b789c5a8ea01a0e12c79d8586bc61470e3088b666078b">yaml.h</a>
+</li>
+<li>yaml_parser_initialize()
+: <a class="el" href="group__parser.html#gacc37ceeb5847e38a3fe24eb0c9b53965">yaml.h</a>
+</li>
+<li>yaml_parser_load()
+: <a class="el" href="group__parser.html#ga9ef7d6e9494766b5880c389bc431d138">yaml.h</a>
+</li>
+<li>yaml_parser_parse()
+: <a class="el" href="group__parser.html#ga559312fb137533d8b7e07f224fe0ec8f">yaml.h</a>
+</li>
+<li>yaml_parser_scan()
+: <a class="el" href="group__parser.html#ga6c2144f131ebd600a075d4ba654540f7">yaml.h</a>
+</li>
+<li>yaml_parser_set_encoding()
+: <a class="el" href="group__parser.html#ga9565b64975570ed34612a19adf02ae6a">yaml.h</a>
+</li>
+<li>yaml_parser_set_input()
+: <a class="el" href="group__parser.html#gabc67581bfa771a3e787d907d6914b8d9">yaml.h</a>
+</li>
+<li>yaml_parser_set_input_file()
+: <a class="el" href="group__parser.html#gac3f00f8beb2365b1e4569692d64696b6">yaml.h</a>
+</li>
+<li>yaml_parser_set_input_string()
+: <a class="el" href="group__parser.html#ga08a94762bf5f4c61f72c1da0a407df0d">yaml.h</a>
+</li>
+<li>yaml_parser_state_e
+: <a class="el" href="group__parser.html#gad39c19e7b0df6f542ca97806535b57c5">yaml.h</a>
+</li>
+<li>yaml_parser_state_t
+: <a class="el" href="group__parser.html#ga52b56d3e3cee0f9ba460978802a8c83b">yaml.h</a>
+</li>
+<li>yaml_parser_t
+: <a class="el" href="group__parser.html#gafdc6319cb28a8b8034542b29be85b0c4">yaml.h</a>
+</li>
+<li>YAML_PLAIN_SCALAR_STYLE
+: <a class="el" href="group__styles.html#gga435ae8886b70c16830d853b6c566e2e0afd62a761a36cf56e1f0414fb391db0e6">yaml.h</a>
+</li>
+<li>yaml_read_handler_t
+: <a class="el" href="group__parser.html#ga4982f7e4e001ddb47d2819f38f0cd9d6">yaml.h</a>
+</li>
+<li>YAML_READER_ERROR
+: <a class="el" href="group__basic.html#gga2efbcde2e82238117982b789c5a8ea01a9216f41a453dc36b090cdc1ca9f89637">yaml.h</a>
+</li>
+<li>YAML_SCALAR_EVENT
+: <a class="el" href="group__events.html#gga454fccebae859c188fe3e7fa3299577ca8b16dc795bb228e33d647d1bdf683713">yaml.h</a>
+</li>
+<li>yaml_scalar_event_initialize()
+: <a class="el" href="group__events.html#gafc60a1a437385e19e6fb3be075958c8c">yaml.h</a>
+</li>
+<li>YAML_SCALAR_NODE
+: <a class="el" href="group__nodes.html#gga0897d4b6bdd1b56c7a5fa0ff17b4f798a413ec8ce6b728c9ace703d194b370a45">yaml.h</a>
+</li>
+<li>yaml_scalar_style_e
+: <a class="el" href="group__styles.html#ga435ae8886b70c16830d853b6c566e2e0">yaml.h</a>
+</li>
+<li>yaml_scalar_style_t
+: <a class="el" href="group__styles.html#ga3fa6405631e1afe5bd5c488a6c5e8065">yaml.h</a>
+</li>
+<li>YAML_SCALAR_TOKEN
+: <a class="el" href="group__tokens.html#ggaae955b10aa6b5f922de64873bf4ccdbda107a78f31dd9857d06e9ead7936ea51e">yaml.h</a>
+</li>
+<li>YAML_SCANNER_ERROR
+: <a class="el" href="group__basic.html#gga2efbcde2e82238117982b789c5a8ea01a6f8d865d9a25b385146660d8260d3d6f">yaml.h</a>
+</li>
+<li>YAML_SEQ_TAG
+: <a class="el" href="group__nodes.html#gaa8284b30f9c9e3f10f6a69c9b882f417">yaml.h</a>
+</li>
+<li>YAML_SEQUENCE_END_EVENT
+: <a class="el" href="group__events.html#gga454fccebae859c188fe3e7fa3299577ca2a8af98529275987d73eb307b6a92898">yaml.h</a>
+</li>
+<li>yaml_sequence_end_event_initialize()
+: <a class="el" href="group__events.html#ga99fdfa4b9d42b64d8171c9b22f334b1c">yaml.h</a>
+</li>
+<li>YAML_SEQUENCE_NODE
+: <a class="el" href="group__nodes.html#gga0897d4b6bdd1b56c7a5fa0ff17b4f798a6c03b52f7ee737982eac5e4001faac15">yaml.h</a>
+</li>
+<li>YAML_SEQUENCE_START_EVENT
+: <a class="el" href="group__events.html#gga454fccebae859c188fe3e7fa3299577cad90ccd43e238221f542defa3c8eaf093">yaml.h</a>
+</li>
+<li>yaml_sequence_start_event_initialize()
+: <a class="el" href="group__events.html#ga53aea428c768d7b131923d08c904b4eb">yaml.h</a>
+</li>
+<li>yaml_sequence_style_e
+: <a class="el" href="group__styles.html#ga5079a4ab96e398371c60423abd88ccc0">yaml.h</a>
+</li>
+<li>yaml_sequence_style_t
+: <a class="el" href="group__styles.html#ga58a1123d271e56c72de6abf852ac4dc2">yaml.h</a>
+</li>
+<li>yaml_simple_key_t
+: <a class="el" href="group__parser.html#gae5570fbb7ab7c8332cd666f3a9c26591">yaml.h</a>
+</li>
+<li>YAML_SINGLE_QUOTED_SCALAR_STYLE
+: <a class="el" href="group__styles.html#gga435ae8886b70c16830d853b6c566e2e0a68a2af452008e3af3f6de14318dfb2c6">yaml.h</a>
+</li>
+<li>YAML_STR_TAG
+: <a class="el" href="group__nodes.html#gac5dbc6d1f556663edf8db88d6113e931">yaml.h</a>
+</li>
+<li>YAML_STREAM_END_EVENT
+: <a class="el" href="group__events.html#gga454fccebae859c188fe3e7fa3299577ca4a5e76ed540645102a13352af2503d3b">yaml.h</a>
+</li>
+<li>yaml_stream_end_event_initialize()
+: <a class="el" href="group__events.html#ga84cf0c3ff01251c852c71624e64df9fe">yaml.h</a>
+</li>
+<li>YAML_STREAM_END_TOKEN
+: <a class="el" href="group__tokens.html#ggaae955b10aa6b5f922de64873bf4ccdbda020a0a266ed7fc4902dd02750512dc19">yaml.h</a>
+</li>
+<li>YAML_STREAM_START_EVENT
+: <a class="el" href="group__events.html#gga454fccebae859c188fe3e7fa3299577caa742e9970f14d1fe7ce4d178d79e8465">yaml.h</a>
+</li>
+<li>yaml_stream_start_event_initialize()
+: <a class="el" href="group__events.html#ga0650d255b23d9aae13c839f4ab3ec2ab">yaml.h</a>
+</li>
+<li>YAML_STREAM_START_TOKEN
+: <a class="el" href="group__tokens.html#ggaae955b10aa6b5f922de64873bf4ccdbdaf5f42f2d5025e5629034848d2e1db6c9">yaml.h</a>
+</li>
+<li>yaml_tag_directive_t
+: <a class="el" href="group__basic.html#ga0b4bc4871b0c9104e32d40d5f3803674">yaml.h</a>
+</li>
+<li>YAML_TAG_DIRECTIVE_TOKEN
+: <a class="el" href="group__tokens.html#ggaae955b10aa6b5f922de64873bf4ccdbdaed517a61b868769e2bfced40678be414">yaml.h</a>
+</li>
+<li>YAML_TAG_TOKEN
+: <a class="el" href="group__tokens.html#ggaae955b10aa6b5f922de64873bf4ccdbda8f02c514b72f29bd3c26b7c832d8152d">yaml.h</a>
+</li>
+<li>YAML_TIMESTAMP_TAG
+: <a class="el" href="group__nodes.html#ga3e27cca7191234f2e8c95eaf3bc99a73">yaml.h</a>
+</li>
+<li>yaml_token_delete()
+: <a class="el" href="group__tokens.html#ga3140131870e38e27f92a8fd286e5c004">yaml.h</a>
+</li>
+<li>yaml_token_t
+: <a class="el" href="group__tokens.html#ga1ed3dc460e62aee8270c5d63d5734bbb">yaml.h</a>
+</li>
+<li>yaml_token_type_e
+: <a class="el" href="group__tokens.html#gaae955b10aa6b5f922de64873bf4ccdbd">yaml.h</a>
+</li>
+<li>yaml_token_type_t
+: <a class="el" href="group__tokens.html#gaba51dda022dced02f8df2224ab7993f7">yaml.h</a>
+</li>
+<li>YAML_UTF16BE_ENCODING
+: <a class="el" href="group__basic.html#ggab88ee52b5d722e644c1cb4d1afcccdd9a9f4fcb99a71d3416239f343f1334780b">yaml.h</a>
+</li>
+<li>YAML_UTF16LE_ENCODING
+: <a class="el" href="group__basic.html#ggab88ee52b5d722e644c1cb4d1afcccdd9ac68c68725ec1f6492e59fd388fd123c9">yaml.h</a>
+</li>
+<li>YAML_UTF8_ENCODING
+: <a class="el" href="group__basic.html#ggab88ee52b5d722e644c1cb4d1afcccdd9a5bacbc5e68fc0c25baedf87e3be25a28">yaml.h</a>
+</li>
+<li>YAML_VALUE_TOKEN
+: <a class="el" href="group__tokens.html#ggaae955b10aa6b5f922de64873bf4ccdbdaac46e8a6a6e0614de322c7b53d785b4e">yaml.h</a>
+</li>
+<li>yaml_version_directive_t
+: <a class="el" href="group__basic.html#ga2fc55608333fbe6df17cf891be709b72">yaml.h</a>
+</li>
+<li>YAML_VERSION_DIRECTIVE_TOKEN
+: <a class="el" href="group__tokens.html#ggaae955b10aa6b5f922de64873bf4ccdbdaa15a96ec81c00c7db8f83628a89542e4">yaml.h</a>
+</li>
+<li>yaml_write_handler_t
+: <a class="el" href="group__emitter.html#ga1669659aacbe631ad406c78fce1f5379">yaml.h</a>
+</li>
+<li>YAML_WRITER_ERROR
+: <a class="el" href="group__basic.html#gga2efbcde2e82238117982b789c5a8ea01ae80fef003be3d7e72ed7acae7984004c">yaml.h</a>
+</li>
+</ul>
+</div>
+<hr class="footer"/><address class="footer"><small>Generated on Mon May 30 2011 22:00:01 for yaml by&nbsp;
+<a href="http://www.doxygen.org/index.html">
+<img class="footer" src="doxygen.png" alt="doxygen"/></a> 1.7.1 </small></address>
+</body>
+</html>
diff --git a/contrib/libyaml/doc/html/globals_defs.html b/contrib/libyaml/doc/html/globals_defs.html
new file mode 100644
index 0000000..be3b627
--- /dev/null
+++ b/contrib/libyaml/doc/html/globals_defs.html
@@ -0,0 +1,81 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head>
+<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/>
+<title>yaml: Data Fields</title>
+<link href="tabs.css" rel="stylesheet" type="text/css"/>
+<link href="doxygen.css" rel="stylesheet" type="text/css"/>
+</head>
+<body>
+<!-- Generated by Doxygen 1.7.1 -->
+<div class="navigation" id="top">
+ <div class="tabs">
+ <ul class="tablist">
+ <li><a href="index.html"><span>Main&nbsp;Page</span></a></li>
+ <li><a href="modules.html"><span>Modules</span></a></li>
+ <li><a href="annotated.html"><span>Data&nbsp;Structures</span></a></li>
+ <li class="current"><a href="files.html"><span>Files</span></a></li>
+ </ul>
+ </div>
+ <div class="tabs2">
+ <ul class="tablist">
+ <li><a href="files.html"><span>File&nbsp;List</span></a></li>
+ <li class="current"><a href="globals.html"><span>Globals</span></a></li>
+ </ul>
+ </div>
+ <div class="tabs2">
+ <ul class="tablist">
+ <li><a href="globals.html"><span>All</span></a></li>
+ <li><a href="globals_func.html"><span>Functions</span></a></li>
+ <li><a href="globals_type.html"><span>Typedefs</span></a></li>
+ <li><a href="globals_enum.html"><span>Enumerations</span></a></li>
+ <li><a href="globals_eval.html"><span>Enumerator</span></a></li>
+ <li class="current"><a href="globals_defs.html"><span>Defines</span></a></li>
+ </ul>
+ </div>
+</div>
+<div class="contents">
+&nbsp;<ul>
+<li>YAML_BOOL_TAG
+: <a class="el" href="group__nodes.html#ga312629a1f51e91b136352db988d4d771">yaml.h</a>
+</li>
+<li>YAML_DECLARE
+: <a class="el" href="group__export.html#ga0791fd3e1d85ed53711b1feaae131f93">yaml.h</a>
+</li>
+<li>YAML_DEFAULT_MAPPING_TAG
+: <a class="el" href="group__nodes.html#gaf7b1f8f0ce5665794510cd3841802a5f">yaml.h</a>
+</li>
+<li>YAML_DEFAULT_SCALAR_TAG
+: <a class="el" href="group__nodes.html#gaf6b0c4e819b8f6915515a4f70065aaaa">yaml.h</a>
+</li>
+<li>YAML_DEFAULT_SEQUENCE_TAG
+: <a class="el" href="group__nodes.html#gaf195b67002518702e27746d6b4da6124">yaml.h</a>
+</li>
+<li>YAML_FLOAT_TAG
+: <a class="el" href="group__nodes.html#ga6ab2ec71fc47cb24f1003b9acdb92843">yaml.h</a>
+</li>
+<li>YAML_INT_TAG
+: <a class="el" href="group__nodes.html#ga83263cdb4ffa6ad2f7d9a87281979ff5">yaml.h</a>
+</li>
+<li>YAML_MAP_TAG
+: <a class="el" href="group__nodes.html#ga22ae99cf3ac014dd76873268fd068c12">yaml.h</a>
+</li>
+<li>YAML_NULL_TAG
+: <a class="el" href="group__nodes.html#gadfa882b6e42a3a993d12392d55260b00">yaml.h</a>
+</li>
+<li>YAML_SEQ_TAG
+: <a class="el" href="group__nodes.html#gaa8284b30f9c9e3f10f6a69c9b882f417">yaml.h</a>
+</li>
+<li>YAML_STR_TAG
+: <a class="el" href="group__nodes.html#gac5dbc6d1f556663edf8db88d6113e931">yaml.h</a>
+</li>
+<li>YAML_TIMESTAMP_TAG
+: <a class="el" href="group__nodes.html#ga3e27cca7191234f2e8c95eaf3bc99a73">yaml.h</a>
+</li>
+</ul>
+</div>
+<hr class="footer"/><address class="footer"><small>Generated on Mon May 30 2011 22:00:01 for yaml by&nbsp;
+<a href="http://www.doxygen.org/index.html">
+<img class="footer" src="doxygen.png" alt="doxygen"/></a> 1.7.1 </small></address>
+</body>
+</html>
diff --git a/contrib/libyaml/doc/html/globals_enum.html b/contrib/libyaml/doc/html/globals_enum.html
new file mode 100644
index 0000000..675ee0b
--- /dev/null
+++ b/contrib/libyaml/doc/html/globals_enum.html
@@ -0,0 +1,78 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head>
+<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/>
+<title>yaml: Data Fields</title>
+<link href="tabs.css" rel="stylesheet" type="text/css"/>
+<link href="doxygen.css" rel="stylesheet" type="text/css"/>
+</head>
+<body>
+<!-- Generated by Doxygen 1.7.1 -->
+<div class="navigation" id="top">
+ <div class="tabs">
+ <ul class="tablist">
+ <li><a href="index.html"><span>Main&nbsp;Page</span></a></li>
+ <li><a href="modules.html"><span>Modules</span></a></li>
+ <li><a href="annotated.html"><span>Data&nbsp;Structures</span></a></li>
+ <li class="current"><a href="files.html"><span>Files</span></a></li>
+ </ul>
+ </div>
+ <div class="tabs2">
+ <ul class="tablist">
+ <li><a href="files.html"><span>File&nbsp;List</span></a></li>
+ <li class="current"><a href="globals.html"><span>Globals</span></a></li>
+ </ul>
+ </div>
+ <div class="tabs2">
+ <ul class="tablist">
+ <li><a href="globals.html"><span>All</span></a></li>
+ <li><a href="globals_func.html"><span>Functions</span></a></li>
+ <li><a href="globals_type.html"><span>Typedefs</span></a></li>
+ <li class="current"><a href="globals_enum.html"><span>Enumerations</span></a></li>
+ <li><a href="globals_eval.html"><span>Enumerator</span></a></li>
+ <li><a href="globals_defs.html"><span>Defines</span></a></li>
+ </ul>
+ </div>
+</div>
+<div class="contents">
+&nbsp;<ul>
+<li>yaml_break_e
+: <a class="el" href="group__basic.html#ga912ad8c893126133fab5e4231db3017e">yaml.h</a>
+</li>
+<li>yaml_emitter_state_e
+: <a class="el" href="group__emitter.html#ga387b79da11c3941e43a56947263aa721">yaml.h</a>
+</li>
+<li>yaml_encoding_e
+: <a class="el" href="group__basic.html#gab88ee52b5d722e644c1cb4d1afcccdd9">yaml.h</a>
+</li>
+<li>yaml_error_type_e
+: <a class="el" href="group__basic.html#ga2efbcde2e82238117982b789c5a8ea01">yaml.h</a>
+</li>
+<li>yaml_event_type_e
+: <a class="el" href="group__events.html#ga454fccebae859c188fe3e7fa3299577c">yaml.h</a>
+</li>
+<li>yaml_mapping_style_e
+: <a class="el" href="group__styles.html#ga1efef592e2e3df6f00432c04ef77d98f">yaml.h</a>
+</li>
+<li>yaml_node_type_e
+: <a class="el" href="group__nodes.html#ga0897d4b6bdd1b56c7a5fa0ff17b4f798">yaml.h</a>
+</li>
+<li>yaml_parser_state_e
+: <a class="el" href="group__parser.html#gad39c19e7b0df6f542ca97806535b57c5">yaml.h</a>
+</li>
+<li>yaml_scalar_style_e
+: <a class="el" href="group__styles.html#ga435ae8886b70c16830d853b6c566e2e0">yaml.h</a>
+</li>
+<li>yaml_sequence_style_e
+: <a class="el" href="group__styles.html#ga5079a4ab96e398371c60423abd88ccc0">yaml.h</a>
+</li>
+<li>yaml_token_type_e
+: <a class="el" href="group__tokens.html#gaae955b10aa6b5f922de64873bf4ccdbd">yaml.h</a>
+</li>
+</ul>
+</div>
+<hr class="footer"/><address class="footer"><small>Generated on Mon May 30 2011 22:00:01 for yaml by&nbsp;
+<a href="http://www.doxygen.org/index.html">
+<img class="footer" src="doxygen.png" alt="doxygen"/></a> 1.7.1 </small></address>
+</body>
+</html>
diff --git a/contrib/libyaml/doc/html/globals_eval.html b/contrib/libyaml/doc/html/globals_eval.html
new file mode 100644
index 0000000..e7c103c
--- /dev/null
+++ b/contrib/libyaml/doc/html/globals_eval.html
@@ -0,0 +1,373 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head>
+<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/>
+<title>yaml: Data Fields</title>
+<link href="tabs.css" rel="stylesheet" type="text/css"/>
+<link href="doxygen.css" rel="stylesheet" type="text/css"/>
+</head>
+<body>
+<!-- Generated by Doxygen 1.7.1 -->
+<div class="navigation" id="top">
+ <div class="tabs">
+ <ul class="tablist">
+ <li><a href="index.html"><span>Main&nbsp;Page</span></a></li>
+ <li><a href="modules.html"><span>Modules</span></a></li>
+ <li><a href="annotated.html"><span>Data&nbsp;Structures</span></a></li>
+ <li class="current"><a href="files.html"><span>Files</span></a></li>
+ </ul>
+ </div>
+ <div class="tabs2">
+ <ul class="tablist">
+ <li><a href="files.html"><span>File&nbsp;List</span></a></li>
+ <li class="current"><a href="globals.html"><span>Globals</span></a></li>
+ </ul>
+ </div>
+ <div class="tabs2">
+ <ul class="tablist">
+ <li><a href="globals.html"><span>All</span></a></li>
+ <li><a href="globals_func.html"><span>Functions</span></a></li>
+ <li><a href="globals_type.html"><span>Typedefs</span></a></li>
+ <li><a href="globals_enum.html"><span>Enumerations</span></a></li>
+ <li class="current"><a href="globals_eval.html"><span>Enumerator</span></a></li>
+ <li><a href="globals_defs.html"><span>Defines</span></a></li>
+ </ul>
+ </div>
+ <div class="tabs3">
+ <ul class="tablist">
+ <li><a href="#index_y"><span>y</span></a></li>
+ </ul>
+ </div>
+</div>
+<div class="contents">
+&nbsp;
+
+<h3><a class="anchor" id="index_y"></a>- y -</h3><ul>
+<li>YAML_ALIAS_EVENT
+: <a class="el" href="group__events.html#gga454fccebae859c188fe3e7fa3299577ca8c3ce47705cfbd49a87a32bdbe544eb7">yaml.h</a>
+</li>
+<li>YAML_ALIAS_TOKEN
+: <a class="el" href="group__tokens.html#ggaae955b10aa6b5f922de64873bf4ccdbda080c398f6fc31f9ab35c7cf94cf948c2">yaml.h</a>
+</li>
+<li>YAML_ANCHOR_TOKEN
+: <a class="el" href="group__tokens.html#ggaae955b10aa6b5f922de64873bf4ccdbda7f0855938c5ccc4820b68ddd7985a5d0">yaml.h</a>
+</li>
+<li>YAML_ANY_BREAK
+: <a class="el" href="group__basic.html#gga912ad8c893126133fab5e4231db3017ea052bd56adef565c33a86fcc05b49513f">yaml.h</a>
+</li>
+<li>YAML_ANY_ENCODING
+: <a class="el" href="group__basic.html#ggab88ee52b5d722e644c1cb4d1afcccdd9ab61d2a81b8e698e642ce6ad69612fa7f">yaml.h</a>
+</li>
+<li>YAML_ANY_MAPPING_STYLE
+: <a class="el" href="group__styles.html#gga1efef592e2e3df6f00432c04ef77d98fac580a83312204ea142c3d08a4954a74a">yaml.h</a>
+</li>
+<li>YAML_ANY_SCALAR_STYLE
+: <a class="el" href="group__styles.html#gga435ae8886b70c16830d853b6c566e2e0aead38b3e6846302ee032927267c34ae0">yaml.h</a>
+</li>
+<li>YAML_ANY_SEQUENCE_STYLE
+: <a class="el" href="group__styles.html#gga5079a4ab96e398371c60423abd88ccc0a5a10d6f70339876b76e5a002dd16212f">yaml.h</a>
+</li>
+<li>YAML_BLOCK_END_TOKEN
+: <a class="el" href="group__tokens.html#ggaae955b10aa6b5f922de64873bf4ccdbda439948425097b4fc853f39f0de14a5ff">yaml.h</a>
+</li>
+<li>YAML_BLOCK_ENTRY_TOKEN
+: <a class="el" href="group__tokens.html#ggaae955b10aa6b5f922de64873bf4ccdbdaa9bdf1d6da41fcd4d356c7bcfa0227b4">yaml.h</a>
+</li>
+<li>YAML_BLOCK_MAPPING_START_TOKEN
+: <a class="el" href="group__tokens.html#ggaae955b10aa6b5f922de64873bf4ccdbda9a95db99bd99f7f9b4e1e879106297dc">yaml.h</a>
+</li>
+<li>YAML_BLOCK_MAPPING_STYLE
+: <a class="el" href="group__styles.html#gga1efef592e2e3df6f00432c04ef77d98fad5e70fe97009c8247a45f4620f071874">yaml.h</a>
+</li>
+<li>YAML_BLOCK_SEQUENCE_START_TOKEN
+: <a class="el" href="group__tokens.html#ggaae955b10aa6b5f922de64873bf4ccdbda4bfddc427da159168ee47267cbeea94f">yaml.h</a>
+</li>
+<li>YAML_BLOCK_SEQUENCE_STYLE
+: <a class="el" href="group__styles.html#gga5079a4ab96e398371c60423abd88ccc0a65f99099ef4ecdcf99bbdd798b5dcbb5">yaml.h</a>
+</li>
+<li>YAML_COMPOSER_ERROR
+: <a class="el" href="group__basic.html#gga2efbcde2e82238117982b789c5a8ea01a43d6eb640e50a1b1ec843cc54ab15f2b">yaml.h</a>
+</li>
+<li>YAML_CR_BREAK
+: <a class="el" href="group__basic.html#gga912ad8c893126133fab5e4231db3017ea116a98ba4ed0bacfdf098a7d5beeb9d4">yaml.h</a>
+</li>
+<li>YAML_CRLN_BREAK
+: <a class="el" href="group__basic.html#gga912ad8c893126133fab5e4231db3017ea15f8daa406870ebfe82b85781c2468f3">yaml.h</a>
+</li>
+<li>YAML_DOCUMENT_END_EVENT
+: <a class="el" href="group__events.html#gga454fccebae859c188fe3e7fa3299577ca355ec471f963827c96512e529676276f">yaml.h</a>
+</li>
+<li>YAML_DOCUMENT_END_TOKEN
+: <a class="el" href="group__tokens.html#ggaae955b10aa6b5f922de64873bf4ccdbda8d0908a82229f44d5ea92a2c380f4579">yaml.h</a>
+</li>
+<li>YAML_DOCUMENT_START_EVENT
+: <a class="el" href="group__events.html#gga454fccebae859c188fe3e7fa3299577caf4ca2b0f538029cf054cdebd09d3d6d3">yaml.h</a>
+</li>
+<li>YAML_DOCUMENT_START_TOKEN
+: <a class="el" href="group__tokens.html#ggaae955b10aa6b5f922de64873bf4ccdbdabcafcdb506886387f93cca734ddfd670">yaml.h</a>
+</li>
+<li>YAML_DOUBLE_QUOTED_SCALAR_STYLE
+: <a class="el" href="group__styles.html#gga435ae8886b70c16830d853b6c566e2e0af6fdfd14690361f4937d67d1f0f011d3">yaml.h</a>
+</li>
+<li>YAML_EMIT_BLOCK_MAPPING_FIRST_KEY_STATE
+: <a class="el" href="group__emitter.html#gga387b79da11c3941e43a56947263aa721aee36d46c1facecfd73fab73e3343226e">yaml.h</a>
+</li>
+<li>YAML_EMIT_BLOCK_MAPPING_KEY_STATE
+: <a class="el" href="group__emitter.html#gga387b79da11c3941e43a56947263aa721a58495cae63b8c3d7c389b1281baeec05">yaml.h</a>
+</li>
+<li>YAML_EMIT_BLOCK_MAPPING_SIMPLE_VALUE_STATE
+: <a class="el" href="group__emitter.html#gga387b79da11c3941e43a56947263aa721a4aa3c6bf2f2d976c47289c741d7a8704">yaml.h</a>
+</li>
+<li>YAML_EMIT_BLOCK_MAPPING_VALUE_STATE
+: <a class="el" href="group__emitter.html#gga387b79da11c3941e43a56947263aa721a7e0f7fac64fc64bb2bc9fe2ec93ca564">yaml.h</a>
+</li>
+<li>YAML_EMIT_BLOCK_SEQUENCE_FIRST_ITEM_STATE
+: <a class="el" href="group__emitter.html#gga387b79da11c3941e43a56947263aa721a68af7c090c6d0187788e390341f0cc4d">yaml.h</a>
+</li>
+<li>YAML_EMIT_BLOCK_SEQUENCE_ITEM_STATE
+: <a class="el" href="group__emitter.html#gga387b79da11c3941e43a56947263aa721a8197c180c3cefee7b67304e17b52c5ff">yaml.h</a>
+</li>
+<li>YAML_EMIT_DOCUMENT_CONTENT_STATE
+: <a class="el" href="group__emitter.html#gga387b79da11c3941e43a56947263aa721a5ce3ed6155496a6fbd7384e310c58bec">yaml.h</a>
+</li>
+<li>YAML_EMIT_DOCUMENT_END_STATE
+: <a class="el" href="group__emitter.html#gga387b79da11c3941e43a56947263aa721a100cad4538be033202da4bb85f8443d3">yaml.h</a>
+</li>
+<li>YAML_EMIT_DOCUMENT_START_STATE
+: <a class="el" href="group__emitter.html#gga387b79da11c3941e43a56947263aa721a678d8c3146f0b2c84e0fc537a9b1109f">yaml.h</a>
+</li>
+<li>YAML_EMIT_END_STATE
+: <a class="el" href="group__emitter.html#gga387b79da11c3941e43a56947263aa721a2a0232912eaf4eeb06594ee6157dfbc0">yaml.h</a>
+</li>
+<li>YAML_EMIT_FIRST_DOCUMENT_START_STATE
+: <a class="el" href="group__emitter.html#gga387b79da11c3941e43a56947263aa721ab1ae25188f02581a137f66c4b6e084ae">yaml.h</a>
+</li>
+<li>YAML_EMIT_FLOW_MAPPING_FIRST_KEY_STATE
+: <a class="el" href="group__emitter.html#gga387b79da11c3941e43a56947263aa721ab811f3d642dacc7c413af2c32356f894">yaml.h</a>
+</li>
+<li>YAML_EMIT_FLOW_MAPPING_KEY_STATE
+: <a class="el" href="group__emitter.html#gga387b79da11c3941e43a56947263aa721ababf835ee5cd4c6de2231e2a49e40626">yaml.h</a>
+</li>
+<li>YAML_EMIT_FLOW_MAPPING_SIMPLE_VALUE_STATE
+: <a class="el" href="group__emitter.html#gga387b79da11c3941e43a56947263aa721aa6f687a6b57e727f0e7b7a2687ad7383">yaml.h</a>
+</li>
+<li>YAML_EMIT_FLOW_MAPPING_VALUE_STATE
+: <a class="el" href="group__emitter.html#gga387b79da11c3941e43a56947263aa721acb6dbcb535248b8fde779aeedc957b2e">yaml.h</a>
+</li>
+<li>YAML_EMIT_FLOW_SEQUENCE_FIRST_ITEM_STATE
+: <a class="el" href="group__emitter.html#gga387b79da11c3941e43a56947263aa721a5a36fc535f3a5720fbb86712959e5654">yaml.h</a>
+</li>
+<li>YAML_EMIT_FLOW_SEQUENCE_ITEM_STATE
+: <a class="el" href="group__emitter.html#gga387b79da11c3941e43a56947263aa721aded45f1dee80027d7b9c6ce061c08767">yaml.h</a>
+</li>
+<li>YAML_EMIT_STREAM_START_STATE
+: <a class="el" href="group__emitter.html#gga387b79da11c3941e43a56947263aa721aa013a33dab710fe9a30ba014af27b81d">yaml.h</a>
+</li>
+<li>YAML_EMITTER_ERROR
+: <a class="el" href="group__basic.html#gga2efbcde2e82238117982b789c5a8ea01a8ec99a26382dd2853a5550027f6e9db1">yaml.h</a>
+</li>
+<li>YAML_FLOW_ENTRY_TOKEN
+: <a class="el" href="group__tokens.html#ggaae955b10aa6b5f922de64873bf4ccdbdaf11ab5655350e4cf0559f78382daa93f">yaml.h</a>
+</li>
+<li>YAML_FLOW_MAPPING_END_TOKEN
+: <a class="el" href="group__tokens.html#ggaae955b10aa6b5f922de64873bf4ccdbdaad99bf47234572d9d0eeea7669d1e769">yaml.h</a>
+</li>
+<li>YAML_FLOW_MAPPING_START_TOKEN
+: <a class="el" href="group__tokens.html#ggaae955b10aa6b5f922de64873bf4ccdbdaff68a3f7c000c5294211eef8f4156100">yaml.h</a>
+</li>
+<li>YAML_FLOW_MAPPING_STYLE
+: <a class="el" href="group__styles.html#gga1efef592e2e3df6f00432c04ef77d98fa4c5425077b0310cbf84e1d73e20b42d3">yaml.h</a>
+</li>
+<li>YAML_FLOW_SEQUENCE_END_TOKEN
+: <a class="el" href="group__tokens.html#ggaae955b10aa6b5f922de64873bf4ccdbdab3496580bee30936f756e0102e98f331">yaml.h</a>
+</li>
+<li>YAML_FLOW_SEQUENCE_START_TOKEN
+: <a class="el" href="group__tokens.html#ggaae955b10aa6b5f922de64873bf4ccdbda862a2390be4abd59bb7bf55b18d9260c">yaml.h</a>
+</li>
+<li>YAML_FLOW_SEQUENCE_STYLE
+: <a class="el" href="group__styles.html#gga5079a4ab96e398371c60423abd88ccc0ae511554b654ebca464d1feec12501d80">yaml.h</a>
+</li>
+<li>YAML_FOLDED_SCALAR_STYLE
+: <a class="el" href="group__styles.html#gga435ae8886b70c16830d853b6c566e2e0aa67c3de37dc127986b08bdbe07cee607">yaml.h</a>
+</li>
+<li>YAML_KEY_TOKEN
+: <a class="el" href="group__tokens.html#ggaae955b10aa6b5f922de64873bf4ccdbda94d701c1f5bb8a392bb45b7cbf4bc2a5">yaml.h</a>
+</li>
+<li>YAML_LITERAL_SCALAR_STYLE
+: <a class="el" href="group__styles.html#gga435ae8886b70c16830d853b6c566e2e0a542d1ac1bf5c3434df3d2a757d0a8ca0">yaml.h</a>
+</li>
+<li>YAML_LN_BREAK
+: <a class="el" href="group__basic.html#gga912ad8c893126133fab5e4231db3017ea23bf395462dcd045e22303be6f3f7781">yaml.h</a>
+</li>
+<li>YAML_MAPPING_END_EVENT
+: <a class="el" href="group__events.html#gga454fccebae859c188fe3e7fa3299577cadc3dc55f17056a657005fecfb80fbd30">yaml.h</a>
+</li>
+<li>YAML_MAPPING_NODE
+: <a class="el" href="group__nodes.html#gga0897d4b6bdd1b56c7a5fa0ff17b4f798ac1a08580e3a70973583fc85e3e097ee6">yaml.h</a>
+</li>
+<li>YAML_MAPPING_START_EVENT
+: <a class="el" href="group__events.html#gga454fccebae859c188fe3e7fa3299577ca0f6982f6d1c325ee71af518c2c66dae8">yaml.h</a>
+</li>
+<li>YAML_MEMORY_ERROR
+: <a class="el" href="group__basic.html#gga2efbcde2e82238117982b789c5a8ea01a57be0407d1f344206d9673c9571bde53">yaml.h</a>
+</li>
+<li>YAML_NO_ERROR
+: <a class="el" href="group__basic.html#gga2efbcde2e82238117982b789c5a8ea01a24cadfb5364769959ad8647649d1e86f">yaml.h</a>
+</li>
+<li>YAML_NO_EVENT
+: <a class="el" href="group__events.html#gga454fccebae859c188fe3e7fa3299577caefda9f31823fe534f094f4241d5e5eac">yaml.h</a>
+</li>
+<li>YAML_NO_NODE
+: <a class="el" href="group__nodes.html#gga0897d4b6bdd1b56c7a5fa0ff17b4f798a0fa87c0e89c4d4136cb47165e6917739">yaml.h</a>
+</li>
+<li>YAML_NO_TOKEN
+: <a class="el" href="group__tokens.html#ggaae955b10aa6b5f922de64873bf4ccdbda66c1b8eec0cc6402c0fb4b2d1b017f92">yaml.h</a>
+</li>
+<li>YAML_PARSE_BLOCK_MAPPING_FIRST_KEY_STATE
+: <a class="el" href="group__parser.html#ggad39c19e7b0df6f542ca97806535b57c5afebcb5bbd67d112d9ecfa633155f0644">yaml.h</a>
+</li>
+<li>YAML_PARSE_BLOCK_MAPPING_KEY_STATE
+: <a class="el" href="group__parser.html#ggad39c19e7b0df6f542ca97806535b57c5a2df81c86e90b874b415ecb19e72efe45">yaml.h</a>
+</li>
+<li>YAML_PARSE_BLOCK_MAPPING_VALUE_STATE
+: <a class="el" href="group__parser.html#ggad39c19e7b0df6f542ca97806535b57c5ae94acf5685fa1538b225413f154465c2">yaml.h</a>
+</li>
+<li>YAML_PARSE_BLOCK_NODE_OR_INDENTLESS_SEQUENCE_STATE
+: <a class="el" href="group__parser.html#ggad39c19e7b0df6f542ca97806535b57c5acbd390af0d3919fe0382d03c284ff3b5">yaml.h</a>
+</li>
+<li>YAML_PARSE_BLOCK_NODE_STATE
+: <a class="el" href="group__parser.html#ggad39c19e7b0df6f542ca97806535b57c5ae1893c0835bacf05cdc21ed181fb75f1">yaml.h</a>
+</li>
+<li>YAML_PARSE_BLOCK_SEQUENCE_ENTRY_STATE
+: <a class="el" href="group__parser.html#ggad39c19e7b0df6f542ca97806535b57c5a8a6cb1f12fe08eee7fc2fa854dbd5b1a">yaml.h</a>
+</li>
+<li>YAML_PARSE_BLOCK_SEQUENCE_FIRST_ENTRY_STATE
+: <a class="el" href="group__parser.html#ggad39c19e7b0df6f542ca97806535b57c5a5bb5f95fc5f1a258ee8e9db0ed25b2d9">yaml.h</a>
+</li>
+<li>YAML_PARSE_DOCUMENT_CONTENT_STATE
+: <a class="el" href="group__parser.html#ggad39c19e7b0df6f542ca97806535b57c5ae444c7652c8029b0ef80068eaaaa3d4d">yaml.h</a>
+</li>
+<li>YAML_PARSE_DOCUMENT_END_STATE
+: <a class="el" href="group__parser.html#ggad39c19e7b0df6f542ca97806535b57c5aeef06d7f13fa4501146a5b9876c98239">yaml.h</a>
+</li>
+<li>YAML_PARSE_DOCUMENT_START_STATE
+: <a class="el" href="group__parser.html#ggad39c19e7b0df6f542ca97806535b57c5aa06d10f700d245caecfc6074a6c52fde">yaml.h</a>
+</li>
+<li>YAML_PARSE_END_STATE
+: <a class="el" href="group__parser.html#ggad39c19e7b0df6f542ca97806535b57c5a51fd3d45693e2240251996def375a2a2">yaml.h</a>
+</li>
+<li>YAML_PARSE_FLOW_MAPPING_EMPTY_VALUE_STATE
+: <a class="el" href="group__parser.html#ggad39c19e7b0df6f542ca97806535b57c5a5a8ec0af5c3314c1ad5e0569b6a5d6d2">yaml.h</a>
+</li>
+<li>YAML_PARSE_FLOW_MAPPING_FIRST_KEY_STATE
+: <a class="el" href="group__parser.html#ggad39c19e7b0df6f542ca97806535b57c5a91ac4bbb6629e2b768a3305fb707b7cd">yaml.h</a>
+</li>
+<li>YAML_PARSE_FLOW_MAPPING_KEY_STATE
+: <a class="el" href="group__parser.html#ggad39c19e7b0df6f542ca97806535b57c5a924f8eb891dc7527bf4db594a0b1bff8">yaml.h</a>
+</li>
+<li>YAML_PARSE_FLOW_MAPPING_VALUE_STATE
+: <a class="el" href="group__parser.html#ggad39c19e7b0df6f542ca97806535b57c5a3ba351f6cfba029248ada2c0720246d4">yaml.h</a>
+</li>
+<li>YAML_PARSE_FLOW_NODE_STATE
+: <a class="el" href="group__parser.html#ggad39c19e7b0df6f542ca97806535b57c5a5bb321f9d18c5b208a71c04bbcbd1d01">yaml.h</a>
+</li>
+<li>YAML_PARSE_FLOW_SEQUENCE_ENTRY_MAPPING_END_STATE
+: <a class="el" href="group__parser.html#ggad39c19e7b0df6f542ca97806535b57c5a397fd87de9227c64e5308481930b5eeb">yaml.h</a>
+</li>
+<li>YAML_PARSE_FLOW_SEQUENCE_ENTRY_MAPPING_KEY_STATE
+: <a class="el" href="group__parser.html#ggad39c19e7b0df6f542ca97806535b57c5a563e11601cf3a1d2a3efc1feb1b696a3">yaml.h</a>
+</li>
+<li>YAML_PARSE_FLOW_SEQUENCE_ENTRY_MAPPING_VALUE_STATE
+: <a class="el" href="group__parser.html#ggad39c19e7b0df6f542ca97806535b57c5a9e5ebb4bee4541e7a7025689c7fc66eb">yaml.h</a>
+</li>
+<li>YAML_PARSE_FLOW_SEQUENCE_ENTRY_STATE
+: <a class="el" href="group__parser.html#ggad39c19e7b0df6f542ca97806535b57c5a0e50f3841eb0d37ad159e64c4a9a1171">yaml.h</a>
+</li>
+<li>YAML_PARSE_FLOW_SEQUENCE_FIRST_ENTRY_STATE
+: <a class="el" href="group__parser.html#ggad39c19e7b0df6f542ca97806535b57c5a3f54830989c12cc4a63494df792eeb08">yaml.h</a>
+</li>
+<li>YAML_PARSE_IMPLICIT_DOCUMENT_START_STATE
+: <a class="el" href="group__parser.html#ggad39c19e7b0df6f542ca97806535b57c5a8255725d67d5bd3574fc7df4db1c6c84">yaml.h</a>
+</li>
+<li>YAML_PARSE_INDENTLESS_SEQUENCE_ENTRY_STATE
+: <a class="el" href="group__parser.html#ggad39c19e7b0df6f542ca97806535b57c5af7095f2141cf9887489e832f0ec61fbd">yaml.h</a>
+</li>
+<li>YAML_PARSE_STREAM_START_STATE
+: <a class="el" href="group__parser.html#ggad39c19e7b0df6f542ca97806535b57c5ae7b52e16bf002db5cf2944596d8c880e">yaml.h</a>
+</li>
+<li>YAML_PARSER_ERROR
+: <a class="el" href="group__basic.html#gga2efbcde2e82238117982b789c5a8ea01a0e12c79d8586bc61470e3088b666078b">yaml.h</a>
+</li>
+<li>YAML_PLAIN_SCALAR_STYLE
+: <a class="el" href="group__styles.html#gga435ae8886b70c16830d853b6c566e2e0afd62a761a36cf56e1f0414fb391db0e6">yaml.h</a>
+</li>
+<li>YAML_READER_ERROR
+: <a class="el" href="group__basic.html#gga2efbcde2e82238117982b789c5a8ea01a9216f41a453dc36b090cdc1ca9f89637">yaml.h</a>
+</li>
+<li>YAML_SCALAR_EVENT
+: <a class="el" href="group__events.html#gga454fccebae859c188fe3e7fa3299577ca8b16dc795bb228e33d647d1bdf683713">yaml.h</a>
+</li>
+<li>YAML_SCALAR_NODE
+: <a class="el" href="group__nodes.html#gga0897d4b6bdd1b56c7a5fa0ff17b4f798a413ec8ce6b728c9ace703d194b370a45">yaml.h</a>
+</li>
+<li>YAML_SCALAR_TOKEN
+: <a class="el" href="group__tokens.html#ggaae955b10aa6b5f922de64873bf4ccdbda107a78f31dd9857d06e9ead7936ea51e">yaml.h</a>
+</li>
+<li>YAML_SCANNER_ERROR
+: <a class="el" href="group__basic.html#gga2efbcde2e82238117982b789c5a8ea01a6f8d865d9a25b385146660d8260d3d6f">yaml.h</a>
+</li>
+<li>YAML_SEQUENCE_END_EVENT
+: <a class="el" href="group__events.html#gga454fccebae859c188fe3e7fa3299577ca2a8af98529275987d73eb307b6a92898">yaml.h</a>
+</li>
+<li>YAML_SEQUENCE_NODE
+: <a class="el" href="group__nodes.html#gga0897d4b6bdd1b56c7a5fa0ff17b4f798a6c03b52f7ee737982eac5e4001faac15">yaml.h</a>
+</li>
+<li>YAML_SEQUENCE_START_EVENT
+: <a class="el" href="group__events.html#gga454fccebae859c188fe3e7fa3299577cad90ccd43e238221f542defa3c8eaf093">yaml.h</a>
+</li>
+<li>YAML_SINGLE_QUOTED_SCALAR_STYLE
+: <a class="el" href="group__styles.html#gga435ae8886b70c16830d853b6c566e2e0a68a2af452008e3af3f6de14318dfb2c6">yaml.h</a>
+</li>
+<li>YAML_STREAM_END_EVENT
+: <a class="el" href="group__events.html#gga454fccebae859c188fe3e7fa3299577ca4a5e76ed540645102a13352af2503d3b">yaml.h</a>
+</li>
+<li>YAML_STREAM_END_TOKEN
+: <a class="el" href="group__tokens.html#ggaae955b10aa6b5f922de64873bf4ccdbda020a0a266ed7fc4902dd02750512dc19">yaml.h</a>
+</li>
+<li>YAML_STREAM_START_EVENT
+: <a class="el" href="group__events.html#gga454fccebae859c188fe3e7fa3299577caa742e9970f14d1fe7ce4d178d79e8465">yaml.h</a>
+</li>
+<li>YAML_STREAM_START_TOKEN
+: <a class="el" href="group__tokens.html#ggaae955b10aa6b5f922de64873bf4ccdbdaf5f42f2d5025e5629034848d2e1db6c9">yaml.h</a>
+</li>
+<li>YAML_TAG_DIRECTIVE_TOKEN
+: <a class="el" href="group__tokens.html#ggaae955b10aa6b5f922de64873bf4ccdbdaed517a61b868769e2bfced40678be414">yaml.h</a>
+</li>
+<li>YAML_TAG_TOKEN
+: <a class="el" href="group__tokens.html#ggaae955b10aa6b5f922de64873bf4ccdbda8f02c514b72f29bd3c26b7c832d8152d">yaml.h</a>
+</li>
+<li>YAML_UTF16BE_ENCODING
+: <a class="el" href="group__basic.html#ggab88ee52b5d722e644c1cb4d1afcccdd9a9f4fcb99a71d3416239f343f1334780b">yaml.h</a>
+</li>
+<li>YAML_UTF16LE_ENCODING
+: <a class="el" href="group__basic.html#ggab88ee52b5d722e644c1cb4d1afcccdd9ac68c68725ec1f6492e59fd388fd123c9">yaml.h</a>
+</li>
+<li>YAML_UTF8_ENCODING
+: <a class="el" href="group__basic.html#ggab88ee52b5d722e644c1cb4d1afcccdd9a5bacbc5e68fc0c25baedf87e3be25a28">yaml.h</a>
+</li>
+<li>YAML_VALUE_TOKEN
+: <a class="el" href="group__tokens.html#ggaae955b10aa6b5f922de64873bf4ccdbdaac46e8a6a6e0614de322c7b53d785b4e">yaml.h</a>
+</li>
+<li>YAML_VERSION_DIRECTIVE_TOKEN
+: <a class="el" href="group__tokens.html#ggaae955b10aa6b5f922de64873bf4ccdbdaa15a96ec81c00c7db8f83628a89542e4">yaml.h</a>
+</li>
+<li>YAML_WRITER_ERROR
+: <a class="el" href="group__basic.html#gga2efbcde2e82238117982b789c5a8ea01ae80fef003be3d7e72ed7acae7984004c">yaml.h</a>
+</li>
+</ul>
+</div>
+<hr class="footer"/><address class="footer"><small>Generated on Mon May 30 2011 22:00:01 for yaml by&nbsp;
+<a href="http://www.doxygen.org/index.html">
+<img class="footer" src="doxygen.png" alt="doxygen"/></a> 1.7.1 </small></address>
+</body>
+</html>
diff --git a/contrib/libyaml/doc/html/globals_func.html b/contrib/libyaml/doc/html/globals_func.html
new file mode 100644
index 0000000..5e55c16
--- /dev/null
+++ b/contrib/libyaml/doc/html/globals_func.html
@@ -0,0 +1,196 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head>
+<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/>
+<title>yaml: Data Fields</title>
+<link href="tabs.css" rel="stylesheet" type="text/css"/>
+<link href="doxygen.css" rel="stylesheet" type="text/css"/>
+</head>
+<body>
+<!-- Generated by Doxygen 1.7.1 -->
+<div class="navigation" id="top">
+ <div class="tabs">
+ <ul class="tablist">
+ <li><a href="index.html"><span>Main&nbsp;Page</span></a></li>
+ <li><a href="modules.html"><span>Modules</span></a></li>
+ <li><a href="annotated.html"><span>Data&nbsp;Structures</span></a></li>
+ <li class="current"><a href="files.html"><span>Files</span></a></li>
+ </ul>
+ </div>
+ <div class="tabs2">
+ <ul class="tablist">
+ <li><a href="files.html"><span>File&nbsp;List</span></a></li>
+ <li class="current"><a href="globals.html"><span>Globals</span></a></li>
+ </ul>
+ </div>
+ <div class="tabs2">
+ <ul class="tablist">
+ <li><a href="globals.html"><span>All</span></a></li>
+ <li class="current"><a href="globals_func.html"><span>Functions</span></a></li>
+ <li><a href="globals_type.html"><span>Typedefs</span></a></li>
+ <li><a href="globals_enum.html"><span>Enumerations</span></a></li>
+ <li><a href="globals_eval.html"><span>Enumerator</span></a></li>
+ <li><a href="globals_defs.html"><span>Defines</span></a></li>
+ </ul>
+ </div>
+ <div class="tabs3">
+ <ul class="tablist">
+ <li><a href="#index_y"><span>y</span></a></li>
+ </ul>
+ </div>
+</div>
+<div class="contents">
+&nbsp;
+
+<h3><a class="anchor" id="index_y"></a>- y -</h3><ul>
+<li>yaml_alias_event_initialize()
+: <a class="el" href="group__events.html#gade4c15b75eb9a8035e04d4f0dd23f005">yaml.h</a>
+</li>
+<li>yaml_document_add_mapping()
+: <a class="el" href="group__nodes.html#ga45a9f8288704f99cd81dc5cb31329d34">yaml.h</a>
+</li>
+<li>yaml_document_add_scalar()
+: <a class="el" href="group__nodes.html#ga45dab8b983b58a005557d4b01f5057b0">yaml.h</a>
+</li>
+<li>yaml_document_add_sequence()
+: <a class="el" href="group__nodes.html#ga83b2f7fdd9a439397a42016bddad7786">yaml.h</a>
+</li>
+<li>yaml_document_append_mapping_pair()
+: <a class="el" href="group__nodes.html#ga2db27002d8a9ae06b1729d0ee06553d2">yaml.h</a>
+</li>
+<li>yaml_document_append_sequence_item()
+: <a class="el" href="group__nodes.html#ga16435917cd6c0261cd390fa8cf173b1b">yaml.h</a>
+</li>
+<li>yaml_document_delete()
+: <a class="el" href="group__nodes.html#ga2754b1544fb4e110e83fafbc708b0672">yaml.h</a>
+</li>
+<li>yaml_document_end_event_initialize()
+: <a class="el" href="group__events.html#ga8bae16548ee88f8a5ca15204f8c30344">yaml.h</a>
+</li>
+<li>yaml_document_get_node()
+: <a class="el" href="group__nodes.html#gafa1feabc9747dbded4dca24e27d3c21a">yaml.h</a>
+</li>
+<li>yaml_document_get_root_node()
+: <a class="el" href="group__nodes.html#ga40eeaa68fb2f3be34c4fe34e7597d324">yaml.h</a>
+</li>
+<li>yaml_document_initialize()
+: <a class="el" href="group__nodes.html#ga62a485c96f3b7962436a0da5e6f3cc89">yaml.h</a>
+</li>
+<li>yaml_document_start_event_initialize()
+: <a class="el" href="group__events.html#ga527e89302e1c969fbea5aa45664bf51c">yaml.h</a>
+</li>
+<li>yaml_emitter_close()
+: <a class="el" href="group__emitter.html#gaa91442864679280985df14b2d96b8c42">yaml.h</a>
+</li>
+<li>yaml_emitter_delete()
+: <a class="el" href="group__emitter.html#gad705212f3a5150e3f00075fd90bc8c3d">yaml.h</a>
+</li>
+<li>yaml_emitter_dump()
+: <a class="el" href="group__emitter.html#ga5f0306abe9bff373b5bc339913b3769c">yaml.h</a>
+</li>
+<li>yaml_emitter_emit()
+: <a class="el" href="group__emitter.html#ga4d6c0f8e712797e2660e69479fdae433">yaml.h</a>
+</li>
+<li>yaml_emitter_flush()
+: <a class="el" href="group__emitter.html#gacaf24456e2bf85bc5654cbd7d828055f">yaml.h</a>
+</li>
+<li>yaml_emitter_initialize()
+: <a class="el" href="group__emitter.html#ga83649205374285802fc27aa293ecd111">yaml.h</a>
+</li>
+<li>yaml_emitter_open()
+: <a class="el" href="group__emitter.html#gae323c34e378040106f24c7b5ab834b16">yaml.h</a>
+</li>
+<li>yaml_emitter_set_break()
+: <a class="el" href="group__emitter.html#ga04b5494f0b8244eec359579c31d5e20c">yaml.h</a>
+</li>
+<li>yaml_emitter_set_canonical()
+: <a class="el" href="group__emitter.html#ga62713a8130e11d95cbefa95a2eb3ac4b">yaml.h</a>
+</li>
+<li>yaml_emitter_set_encoding()
+: <a class="el" href="group__emitter.html#gabc22888ec8bf942199acbf38f7a0b9bb">yaml.h</a>
+</li>
+<li>yaml_emitter_set_indent()
+: <a class="el" href="group__emitter.html#ga07eca3c344053a9028b4a84291cdf4d7">yaml.h</a>
+</li>
+<li>yaml_emitter_set_output()
+: <a class="el" href="group__emitter.html#gac85a6a212ed7b469fb426a3451d15922">yaml.h</a>
+</li>
+<li>yaml_emitter_set_output_file()
+: <a class="el" href="group__emitter.html#gaf7610c61b303bde9c701024c10ece024">yaml.h</a>
+</li>
+<li>yaml_emitter_set_output_string()
+: <a class="el" href="group__emitter.html#ga62725c0f616f634588374d1a4c0ed35a">yaml.h</a>
+</li>
+<li>yaml_emitter_set_unicode()
+: <a class="el" href="group__emitter.html#gaa59e7dcf24cb9b614c32af6c3e949fc3">yaml.h</a>
+</li>
+<li>yaml_emitter_set_width()
+: <a class="el" href="group__emitter.html#gaa91ae0fa8af5ab67e64567e08f4458c2">yaml.h</a>
+</li>
+<li>yaml_event_delete()
+: <a class="el" href="group__events.html#ga5330d62ef52856aa53188137cb93a6a1">yaml.h</a>
+</li>
+<li>yaml_get_version()
+: <a class="el" href="group__version.html#gaec764c91f3e181ae63d3d59b7980fe78">yaml.h</a>
+</li>
+<li>yaml_get_version_string()
+: <a class="el" href="group__version.html#gaf1ba5c1c34e809db5047d79a9fa85a73">yaml.h</a>
+</li>
+<li>yaml_mapping_end_event_initialize()
+: <a class="el" href="group__events.html#ga3afaf8b3aca2ec902a4e268f12adb0c2">yaml.h</a>
+</li>
+<li>yaml_mapping_start_event_initialize()
+: <a class="el" href="group__events.html#ga0603cf8d20f0b6dfc3be04b6360134aa">yaml.h</a>
+</li>
+<li>yaml_parser_delete()
+: <a class="el" href="group__parser.html#gaa27150107c4667c1024ec0651e2ac26b">yaml.h</a>
+</li>
+<li>yaml_parser_initialize()
+: <a class="el" href="group__parser.html#gacc37ceeb5847e38a3fe24eb0c9b53965">yaml.h</a>
+</li>
+<li>yaml_parser_load()
+: <a class="el" href="group__parser.html#ga9ef7d6e9494766b5880c389bc431d138">yaml.h</a>
+</li>
+<li>yaml_parser_parse()
+: <a class="el" href="group__parser.html#ga559312fb137533d8b7e07f224fe0ec8f">yaml.h</a>
+</li>
+<li>yaml_parser_scan()
+: <a class="el" href="group__parser.html#ga6c2144f131ebd600a075d4ba654540f7">yaml.h</a>
+</li>
+<li>yaml_parser_set_encoding()
+: <a class="el" href="group__parser.html#ga9565b64975570ed34612a19adf02ae6a">yaml.h</a>
+</li>
+<li>yaml_parser_set_input()
+: <a class="el" href="group__parser.html#gabc67581bfa771a3e787d907d6914b8d9">yaml.h</a>
+</li>
+<li>yaml_parser_set_input_file()
+: <a class="el" href="group__parser.html#gac3f00f8beb2365b1e4569692d64696b6">yaml.h</a>
+</li>
+<li>yaml_parser_set_input_string()
+: <a class="el" href="group__parser.html#ga08a94762bf5f4c61f72c1da0a407df0d">yaml.h</a>
+</li>
+<li>yaml_scalar_event_initialize()
+: <a class="el" href="group__events.html#gafc60a1a437385e19e6fb3be075958c8c">yaml.h</a>
+</li>
+<li>yaml_sequence_end_event_initialize()
+: <a class="el" href="group__events.html#ga99fdfa4b9d42b64d8171c9b22f334b1c">yaml.h</a>
+</li>
+<li>yaml_sequence_start_event_initialize()
+: <a class="el" href="group__events.html#ga53aea428c768d7b131923d08c904b4eb">yaml.h</a>
+</li>
+<li>yaml_stream_end_event_initialize()
+: <a class="el" href="group__events.html#ga84cf0c3ff01251c852c71624e64df9fe">yaml.h</a>
+</li>
+<li>yaml_stream_start_event_initialize()
+: <a class="el" href="group__events.html#ga0650d255b23d9aae13c839f4ab3ec2ab">yaml.h</a>
+</li>
+<li>yaml_token_delete()
+: <a class="el" href="group__tokens.html#ga3140131870e38e27f92a8fd286e5c004">yaml.h</a>
+</li>
+</ul>
+</div>
+<hr class="footer"/><address class="footer"><small>Generated on Mon May 30 2011 22:00:01 for yaml by&nbsp;
+<a href="http://www.doxygen.org/index.html">
+<img class="footer" src="doxygen.png" alt="doxygen"/></a> 1.7.1 </small></address>
+</body>
+</html>
diff --git a/contrib/libyaml/doc/html/globals_type.html b/contrib/libyaml/doc/html/globals_type.html
new file mode 100644
index 0000000..854125b
--- /dev/null
+++ b/contrib/libyaml/doc/html/globals_type.html
@@ -0,0 +1,126 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head>
+<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/>
+<title>yaml: Data Fields</title>
+<link href="tabs.css" rel="stylesheet" type="text/css"/>
+<link href="doxygen.css" rel="stylesheet" type="text/css"/>
+</head>
+<body>
+<!-- Generated by Doxygen 1.7.1 -->
+<div class="navigation" id="top">
+ <div class="tabs">
+ <ul class="tablist">
+ <li><a href="index.html"><span>Main&nbsp;Page</span></a></li>
+ <li><a href="modules.html"><span>Modules</span></a></li>
+ <li><a href="annotated.html"><span>Data&nbsp;Structures</span></a></li>
+ <li class="current"><a href="files.html"><span>Files</span></a></li>
+ </ul>
+ </div>
+ <div class="tabs2">
+ <ul class="tablist">
+ <li><a href="files.html"><span>File&nbsp;List</span></a></li>
+ <li class="current"><a href="globals.html"><span>Globals</span></a></li>
+ </ul>
+ </div>
+ <div class="tabs2">
+ <ul class="tablist">
+ <li><a href="globals.html"><span>All</span></a></li>
+ <li><a href="globals_func.html"><span>Functions</span></a></li>
+ <li class="current"><a href="globals_type.html"><span>Typedefs</span></a></li>
+ <li><a href="globals_enum.html"><span>Enumerations</span></a></li>
+ <li><a href="globals_eval.html"><span>Enumerator</span></a></li>
+ <li><a href="globals_defs.html"><span>Defines</span></a></li>
+ </ul>
+ </div>
+</div>
+<div class="contents">
+&nbsp;<ul>
+<li>yaml_alias_data_t
+: <a class="el" href="group__parser.html#ga1434228b82f5f90d3c8ccda816e9ca9d">yaml.h</a>
+</li>
+<li>yaml_break_t
+: <a class="el" href="group__basic.html#ga64d1365e1acd4deeab50d6b48e39cb6d">yaml.h</a>
+</li>
+<li>yaml_char_t
+: <a class="el" href="group__basic.html#gaf8657e81f0b8b05d1a081001fc6cb8bd">yaml.h</a>
+</li>
+<li>yaml_document_t
+: <a class="el" href="group__nodes.html#gad94e064e95baeb22e4f7acc7804e8479">yaml.h</a>
+</li>
+<li>yaml_emitter_state_t
+: <a class="el" href="group__emitter.html#ga0889461fa3efe8eee881aef48a4ba6b2">yaml.h</a>
+</li>
+<li>yaml_emitter_t
+: <a class="el" href="group__emitter.html#ga4ce3e054f0016c49d9e8c36d359e710b">yaml.h</a>
+</li>
+<li>yaml_encoding_t
+: <a class="el" href="group__basic.html#ga2170996d7e636397b5e6bc0c1b7df7c6">yaml.h</a>
+</li>
+<li>yaml_error_type_t
+: <a class="el" href="group__basic.html#ga1a449f0c1b023e2ef1a596093c018e73">yaml.h</a>
+</li>
+<li>yaml_event_t
+: <a class="el" href="group__events.html#ga3b392d9716c4920cabefdd29e78dd542">yaml.h</a>
+</li>
+<li>yaml_event_type_t
+: <a class="el" href="group__events.html#ga8934661be36bd7c9d17a8af69eff89a1">yaml.h</a>
+</li>
+<li>yaml_mapping_style_t
+: <a class="el" href="group__styles.html#gab47523846a5c5960e07367a28ea9750a">yaml.h</a>
+</li>
+<li>yaml_mark_t
+: <a class="el" href="group__basic.html#ga232eacba89691b841ba941338a302bfd">yaml.h</a>
+</li>
+<li>yaml_node_item_t
+: <a class="el" href="group__nodes.html#ga7cc3581582e778b00c04e99cd3656860">yaml.h</a>
+</li>
+<li>yaml_node_pair_t
+: <a class="el" href="group__nodes.html#ga90f1c8b83c5c38dc4016afc1cc2050c4">yaml.h</a>
+</li>
+<li>yaml_node_t
+: <a class="el" href="group__nodes.html#ga9eaaa233b120b9d9db47de93c294c40f">yaml.h</a>
+</li>
+<li>yaml_node_type_t
+: <a class="el" href="group__nodes.html#gabe020d2fc42d3e896549e9f97da622d2">yaml.h</a>
+</li>
+<li>yaml_parser_state_t
+: <a class="el" href="group__parser.html#ga52b56d3e3cee0f9ba460978802a8c83b">yaml.h</a>
+</li>
+<li>yaml_parser_t
+: <a class="el" href="group__parser.html#gafdc6319cb28a8b8034542b29be85b0c4">yaml.h</a>
+</li>
+<li>yaml_read_handler_t
+: <a class="el" href="group__parser.html#ga4982f7e4e001ddb47d2819f38f0cd9d6">yaml.h</a>
+</li>
+<li>yaml_scalar_style_t
+: <a class="el" href="group__styles.html#ga3fa6405631e1afe5bd5c488a6c5e8065">yaml.h</a>
+</li>
+<li>yaml_sequence_style_t
+: <a class="el" href="group__styles.html#ga58a1123d271e56c72de6abf852ac4dc2">yaml.h</a>
+</li>
+<li>yaml_simple_key_t
+: <a class="el" href="group__parser.html#gae5570fbb7ab7c8332cd666f3a9c26591">yaml.h</a>
+</li>
+<li>yaml_tag_directive_t
+: <a class="el" href="group__basic.html#ga0b4bc4871b0c9104e32d40d5f3803674">yaml.h</a>
+</li>
+<li>yaml_token_t
+: <a class="el" href="group__tokens.html#ga1ed3dc460e62aee8270c5d63d5734bbb">yaml.h</a>
+</li>
+<li>yaml_token_type_t
+: <a class="el" href="group__tokens.html#gaba51dda022dced02f8df2224ab7993f7">yaml.h</a>
+</li>
+<li>yaml_version_directive_t
+: <a class="el" href="group__basic.html#ga2fc55608333fbe6df17cf891be709b72">yaml.h</a>
+</li>
+<li>yaml_write_handler_t
+: <a class="el" href="group__emitter.html#ga1669659aacbe631ad406c78fce1f5379">yaml.h</a>
+</li>
+</ul>
+</div>
+<hr class="footer"/><address class="footer"><small>Generated on Mon May 30 2011 22:00:01 for yaml by&nbsp;
+<a href="http://www.doxygen.org/index.html">
+<img class="footer" src="doxygen.png" alt="doxygen"/></a> 1.7.1 </small></address>
+</body>
+</html>
diff --git a/contrib/libyaml/doc/html/group__basic.html b/contrib/libyaml/doc/html/group__basic.html
new file mode 100644
index 0000000..636b7db
--- /dev/null
+++ b/contrib/libyaml/doc/html/group__basic.html
@@ -0,0 +1,320 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head>
+<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/>
+<title>yaml: Basic Types</title>
+<link href="tabs.css" rel="stylesheet" type="text/css"/>
+<link href="doxygen.css" rel="stylesheet" type="text/css"/>
+</head>
+<body>
+<!-- Generated by Doxygen 1.7.1 -->
+<div class="navigation" id="top">
+ <div class="tabs">
+ <ul class="tablist">
+ <li><a href="index.html"><span>Main&nbsp;Page</span></a></li>
+ <li><a href="modules.html"><span>Modules</span></a></li>
+ <li><a href="annotated.html"><span>Data&nbsp;Structures</span></a></li>
+ <li><a href="files.html"><span>Files</span></a></li>
+ </ul>
+ </div>
+</div>
+<div class="header">
+ <div class="summary">
+<a href="#nested-classes">Data Structures</a> &#124;
+<a href="#typedef-members">Typedefs</a> &#124;
+<a href="#enum-members">Enumerations</a> </div>
+ <div class="headertitle">
+<h1>Basic Types</h1> </div>
+</div>
+<div class="contents">
+<table class="memberdecls">
+<tr><td colspan="2"><h2><a name="nested-classes"></a>
+Data Structures</h2></td></tr>
+<tr><td class="memItemLeft" align="right" valign="top">struct &nbsp;</td><td class="memItemRight" valign="bottom"><a class="el" href="structyaml__version__directive__s.html">yaml_version_directive_s</a></td></tr>
+<tr><td class="mdescLeft">&nbsp;</td><td class="mdescRight">The version directive data. <a href="structyaml__version__directive__s.html#_details">More...</a><br/></td></tr>
+<tr><td class="memItemLeft" align="right" valign="top">struct &nbsp;</td><td class="memItemRight" valign="bottom"><a class="el" href="structyaml__tag__directive__s.html">yaml_tag_directive_s</a></td></tr>
+<tr><td class="mdescLeft">&nbsp;</td><td class="mdescRight">The tag directive data. <a href="structyaml__tag__directive__s.html#_details">More...</a><br/></td></tr>
+<tr><td class="memItemLeft" align="right" valign="top">struct &nbsp;</td><td class="memItemRight" valign="bottom"><a class="el" href="structyaml__mark__s.html">yaml_mark_s</a></td></tr>
+<tr><td class="mdescLeft">&nbsp;</td><td class="mdescRight">The pointer position. <a href="structyaml__mark__s.html#_details">More...</a><br/></td></tr>
+<tr><td colspan="2"><h2><a name="typedef-members"></a>
+Typedefs</h2></td></tr>
+<tr><td class="memItemLeft" align="right" valign="top">typedef unsigned char&nbsp;</td><td class="memItemRight" valign="bottom"><a class="el" href="group__basic.html#gaf8657e81f0b8b05d1a081001fc6cb8bd">yaml_char_t</a></td></tr>
+<tr><td class="mdescLeft">&nbsp;</td><td class="mdescRight">The character type (UTF-8 octet). <a href="#gaf8657e81f0b8b05d1a081001fc6cb8bd"></a><br/></td></tr>
+<tr><td class="memItemLeft" align="right" valign="top">typedef struct <br class="typebreak"/>
+<a class="el" href="structyaml__version__directive__s.html">yaml_version_directive_s</a>&nbsp;</td><td class="memItemRight" valign="bottom"><a class="el" href="group__basic.html#ga2fc55608333fbe6df17cf891be709b72">yaml_version_directive_t</a></td></tr>
+<tr><td class="mdescLeft">&nbsp;</td><td class="mdescRight">The version directive data. <a href="#ga2fc55608333fbe6df17cf891be709b72"></a><br/></td></tr>
+<tr><td class="memItemLeft" align="right" valign="top">typedef struct <a class="el" href="structyaml__tag__directive__s.html">yaml_tag_directive_s</a>&nbsp;</td><td class="memItemRight" valign="bottom"><a class="el" href="group__basic.html#ga0b4bc4871b0c9104e32d40d5f3803674">yaml_tag_directive_t</a></td></tr>
+<tr><td class="mdescLeft">&nbsp;</td><td class="mdescRight">The tag directive data. <a href="#ga0b4bc4871b0c9104e32d40d5f3803674"></a><br/></td></tr>
+<tr><td class="memItemLeft" align="right" valign="top">typedef enum <a class="el" href="group__basic.html#gab88ee52b5d722e644c1cb4d1afcccdd9">yaml_encoding_e</a>&nbsp;</td><td class="memItemRight" valign="bottom"><a class="el" href="group__basic.html#ga2170996d7e636397b5e6bc0c1b7df7c6">yaml_encoding_t</a></td></tr>
+<tr><td class="mdescLeft">&nbsp;</td><td class="mdescRight">The stream encoding. <a href="#ga2170996d7e636397b5e6bc0c1b7df7c6"></a><br/></td></tr>
+<tr><td class="memItemLeft" align="right" valign="top">typedef enum <a class="el" href="group__basic.html#ga912ad8c893126133fab5e4231db3017e">yaml_break_e</a>&nbsp;</td><td class="memItemRight" valign="bottom"><a class="el" href="group__basic.html#ga64d1365e1acd4deeab50d6b48e39cb6d">yaml_break_t</a></td></tr>
+<tr><td class="mdescLeft">&nbsp;</td><td class="mdescRight">Line break types. <a href="#ga64d1365e1acd4deeab50d6b48e39cb6d"></a><br/></td></tr>
+<tr><td class="memItemLeft" align="right" valign="top">typedef enum <a class="el" href="group__basic.html#ga2efbcde2e82238117982b789c5a8ea01">yaml_error_type_e</a>&nbsp;</td><td class="memItemRight" valign="bottom"><a class="el" href="group__basic.html#ga1a449f0c1b023e2ef1a596093c018e73">yaml_error_type_t</a></td></tr>
+<tr><td class="mdescLeft">&nbsp;</td><td class="mdescRight">Many bad things could happen with the parser and emitter. <a href="#ga1a449f0c1b023e2ef1a596093c018e73"></a><br/></td></tr>
+<tr><td class="memItemLeft" align="right" valign="top">typedef struct <a class="el" href="structyaml__mark__s.html">yaml_mark_s</a>&nbsp;</td><td class="memItemRight" valign="bottom"><a class="el" href="group__basic.html#ga232eacba89691b841ba941338a302bfd">yaml_mark_t</a></td></tr>
+<tr><td class="mdescLeft">&nbsp;</td><td class="mdescRight">The pointer position. <a href="#ga232eacba89691b841ba941338a302bfd"></a><br/></td></tr>
+<tr><td colspan="2"><h2><a name="enum-members"></a>
+Enumerations</h2></td></tr>
+<tr><td class="memItemLeft" align="right" valign="top">enum &nbsp;</td><td class="memItemRight" valign="bottom"><a class="el" href="group__basic.html#gab88ee52b5d722e644c1cb4d1afcccdd9">yaml_encoding_e</a> { <br/>
+&nbsp;&nbsp;<a class="el" href="group__basic.html#ggab88ee52b5d722e644c1cb4d1afcccdd9ab61d2a81b8e698e642ce6ad69612fa7f">YAML_ANY_ENCODING</a>,
+<br/>
+&nbsp;&nbsp;<a class="el" href="group__basic.html#ggab88ee52b5d722e644c1cb4d1afcccdd9a5bacbc5e68fc0c25baedf87e3be25a28">YAML_UTF8_ENCODING</a>,
+<br/>
+&nbsp;&nbsp;<a class="el" href="group__basic.html#ggab88ee52b5d722e644c1cb4d1afcccdd9ac68c68725ec1f6492e59fd388fd123c9">YAML_UTF16LE_ENCODING</a>,
+<br/>
+&nbsp;&nbsp;<a class="el" href="group__basic.html#ggab88ee52b5d722e644c1cb4d1afcccdd9a9f4fcb99a71d3416239f343f1334780b">YAML_UTF16BE_ENCODING</a>
+<br/>
+ }</td></tr>
+<tr><td class="mdescLeft">&nbsp;</td><td class="mdescRight"><p>The stream encoding. </p>
+ <a href="group__basic.html#gab88ee52b5d722e644c1cb4d1afcccdd9">More...</a><br/></td></tr>
+<tr><td class="memItemLeft" align="right" valign="top">enum &nbsp;</td><td class="memItemRight" valign="bottom"><a class="el" href="group__basic.html#ga912ad8c893126133fab5e4231db3017e">yaml_break_e</a> { <br/>
+&nbsp;&nbsp;<a class="el" href="group__basic.html#gga912ad8c893126133fab5e4231db3017ea052bd56adef565c33a86fcc05b49513f">YAML_ANY_BREAK</a>,
+<br/>
+&nbsp;&nbsp;<a class="el" href="group__basic.html#gga912ad8c893126133fab5e4231db3017ea116a98ba4ed0bacfdf098a7d5beeb9d4">YAML_CR_BREAK</a>,
+<br/>
+&nbsp;&nbsp;<a class="el" href="group__basic.html#gga912ad8c893126133fab5e4231db3017ea23bf395462dcd045e22303be6f3f7781">YAML_LN_BREAK</a>,
+<br/>
+&nbsp;&nbsp;<a class="el" href="group__basic.html#gga912ad8c893126133fab5e4231db3017ea15f8daa406870ebfe82b85781c2468f3">YAML_CRLN_BREAK</a>
+<br/>
+ }</td></tr>
+<tr><td class="mdescLeft">&nbsp;</td><td class="mdescRight"><p>Line break types. </p>
+ <a href="group__basic.html#ga912ad8c893126133fab5e4231db3017e">More...</a><br/></td></tr>
+<tr><td class="memItemLeft" align="right" valign="top">enum &nbsp;</td><td class="memItemRight" valign="bottom"><a class="el" href="group__basic.html#ga2efbcde2e82238117982b789c5a8ea01">yaml_error_type_e</a> { <br/>
+&nbsp;&nbsp;<a class="el" href="group__basic.html#gga2efbcde2e82238117982b789c5a8ea01a24cadfb5364769959ad8647649d1e86f">YAML_NO_ERROR</a>,
+<br/>
+&nbsp;&nbsp;<a class="el" href="group__basic.html#gga2efbcde2e82238117982b789c5a8ea01a57be0407d1f344206d9673c9571bde53">YAML_MEMORY_ERROR</a>,
+<br/>
+&nbsp;&nbsp;<a class="el" href="group__basic.html#gga2efbcde2e82238117982b789c5a8ea01a9216f41a453dc36b090cdc1ca9f89637">YAML_READER_ERROR</a>,
+<br/>
+&nbsp;&nbsp;<a class="el" href="group__basic.html#gga2efbcde2e82238117982b789c5a8ea01a6f8d865d9a25b385146660d8260d3d6f">YAML_SCANNER_ERROR</a>,
+<br/>
+&nbsp;&nbsp;<a class="el" href="group__basic.html#gga2efbcde2e82238117982b789c5a8ea01a0e12c79d8586bc61470e3088b666078b">YAML_PARSER_ERROR</a>,
+<br/>
+&nbsp;&nbsp;<a class="el" href="group__basic.html#gga2efbcde2e82238117982b789c5a8ea01a43d6eb640e50a1b1ec843cc54ab15f2b">YAML_COMPOSER_ERROR</a>,
+<br/>
+&nbsp;&nbsp;<a class="el" href="group__basic.html#gga2efbcde2e82238117982b789c5a8ea01ae80fef003be3d7e72ed7acae7984004c">YAML_WRITER_ERROR</a>,
+<br/>
+&nbsp;&nbsp;<a class="el" href="group__basic.html#gga2efbcde2e82238117982b789c5a8ea01a8ec99a26382dd2853a5550027f6e9db1">YAML_EMITTER_ERROR</a>
+<br/>
+ }</td></tr>
+<tr><td class="mdescLeft">&nbsp;</td><td class="mdescRight"><p>Many bad things could happen with the parser and emitter. </p>
+ <a href="group__basic.html#ga2efbcde2e82238117982b789c5a8ea01">More...</a><br/></td></tr>
+</table>
+<hr/><h2>Typedef Documentation</h2>
+<a class="anchor" id="gaf8657e81f0b8b05d1a081001fc6cb8bd"></a><!-- doxytag: member="yaml.h::yaml_char_t" ref="gaf8657e81f0b8b05d1a081001fc6cb8bd" args="" -->
+<div class="memitem">
+<div class="memproto">
+ <table class="memname">
+ <tr>
+ <td class="memname">typedef unsigned char <a class="el" href="group__basic.html#gaf8657e81f0b8b05d1a081001fc6cb8bd">yaml_char_t</a></td>
+ </tr>
+ </table>
+</div>
+<div class="memdoc">
+
+<p>The character type (UTF-8 octet). </p>
+
+</div>
+</div>
+<a class="anchor" id="ga2fc55608333fbe6df17cf891be709b72"></a><!-- doxytag: member="yaml.h::yaml_version_directive_t" ref="ga2fc55608333fbe6df17cf891be709b72" args="" -->
+<div class="memitem">
+<div class="memproto">
+ <table class="memname">
+ <tr>
+ <td class="memname">typedef struct <a class="el" href="structyaml__version__directive__s.html">yaml_version_directive_s</a> <a class="el" href="structyaml__version__directive__s.html">yaml_version_directive_t</a></td>
+ </tr>
+ </table>
+</div>
+<div class="memdoc">
+
+<p>The version directive data. </p>
+
+</div>
+</div>
+<a class="anchor" id="ga0b4bc4871b0c9104e32d40d5f3803674"></a><!-- doxytag: member="yaml.h::yaml_tag_directive_t" ref="ga0b4bc4871b0c9104e32d40d5f3803674" args="" -->
+<div class="memitem">
+<div class="memproto">
+ <table class="memname">
+ <tr>
+ <td class="memname">typedef struct <a class="el" href="structyaml__tag__directive__s.html">yaml_tag_directive_s</a> <a class="el" href="structyaml__tag__directive__s.html">yaml_tag_directive_t</a></td>
+ </tr>
+ </table>
+</div>
+<div class="memdoc">
+
+<p>The tag directive data. </p>
+
+</div>
+</div>
+<a class="anchor" id="ga2170996d7e636397b5e6bc0c1b7df7c6"></a><!-- doxytag: member="yaml.h::yaml_encoding_t" ref="ga2170996d7e636397b5e6bc0c1b7df7c6" args="" -->
+<div class="memitem">
+<div class="memproto">
+ <table class="memname">
+ <tr>
+ <td class="memname">typedef enum <a class="el" href="group__basic.html#gab88ee52b5d722e644c1cb4d1afcccdd9">yaml_encoding_e</a> <a class="el" href="group__basic.html#ga2170996d7e636397b5e6bc0c1b7df7c6">yaml_encoding_t</a></td>
+ </tr>
+ </table>
+</div>
+<div class="memdoc">
+
+<p>The stream encoding. </p>
+
+</div>
+</div>
+<a class="anchor" id="ga64d1365e1acd4deeab50d6b48e39cb6d"></a><!-- doxytag: member="yaml.h::yaml_break_t" ref="ga64d1365e1acd4deeab50d6b48e39cb6d" args="" -->
+<div class="memitem">
+<div class="memproto">
+ <table class="memname">
+ <tr>
+ <td class="memname">typedef enum <a class="el" href="group__basic.html#ga912ad8c893126133fab5e4231db3017e">yaml_break_e</a> <a class="el" href="group__basic.html#ga64d1365e1acd4deeab50d6b48e39cb6d">yaml_break_t</a></td>
+ </tr>
+ </table>
+</div>
+<div class="memdoc">
+
+<p>Line break types. </p>
+
+</div>
+</div>
+<a class="anchor" id="ga1a449f0c1b023e2ef1a596093c018e73"></a><!-- doxytag: member="yaml.h::yaml_error_type_t" ref="ga1a449f0c1b023e2ef1a596093c018e73" args="" -->
+<div class="memitem">
+<div class="memproto">
+ <table class="memname">
+ <tr>
+ <td class="memname">typedef enum <a class="el" href="group__basic.html#ga2efbcde2e82238117982b789c5a8ea01">yaml_error_type_e</a> <a class="el" href="group__basic.html#ga1a449f0c1b023e2ef1a596093c018e73">yaml_error_type_t</a></td>
+ </tr>
+ </table>
+</div>
+<div class="memdoc">
+
+<p>Many bad things could happen with the parser and emitter. </p>
+
+</div>
+</div>
+<a class="anchor" id="ga232eacba89691b841ba941338a302bfd"></a><!-- doxytag: member="yaml.h::yaml_mark_t" ref="ga232eacba89691b841ba941338a302bfd" args="" -->
+<div class="memitem">
+<div class="memproto">
+ <table class="memname">
+ <tr>
+ <td class="memname">typedef struct <a class="el" href="structyaml__mark__s.html">yaml_mark_s</a> <a class="el" href="structyaml__mark__s.html">yaml_mark_t</a></td>
+ </tr>
+ </table>
+</div>
+<div class="memdoc">
+
+<p>The pointer position. </p>
+
+</div>
+</div>
+<hr/><h2>Enumeration Type Documentation</h2>
+<a class="anchor" id="gab88ee52b5d722e644c1cb4d1afcccdd9"></a><!-- doxytag: member="yaml.h::yaml_encoding_e" ref="gab88ee52b5d722e644c1cb4d1afcccdd9" args="" -->
+<div class="memitem">
+<div class="memproto">
+ <table class="memname">
+ <tr>
+ <td class="memname">enum <a class="el" href="group__basic.html#gab88ee52b5d722e644c1cb4d1afcccdd9">yaml_encoding_e</a></td>
+ </tr>
+ </table>
+</div>
+<div class="memdoc">
+
+<p>The stream encoding. </p>
+<dl><dt><b>Enumerator: </b></dt><dd><table border="0" cellspacing="2" cellpadding="0">
+<tr><td valign="top"><em><a class="anchor" id="ggab88ee52b5d722e644c1cb4d1afcccdd9ab61d2a81b8e698e642ce6ad69612fa7f"></a><!-- doxytag: member="YAML_ANY_ENCODING" ref="ggab88ee52b5d722e644c1cb4d1afcccdd9ab61d2a81b8e698e642ce6ad69612fa7f" args="" -->YAML_ANY_ENCODING</em>&nbsp;</td><td>
+<p>Let the parser choose the encoding. </p>
+</td></tr>
+<tr><td valign="top"><em><a class="anchor" id="ggab88ee52b5d722e644c1cb4d1afcccdd9a5bacbc5e68fc0c25baedf87e3be25a28"></a><!-- doxytag: member="YAML_UTF8_ENCODING" ref="ggab88ee52b5d722e644c1cb4d1afcccdd9a5bacbc5e68fc0c25baedf87e3be25a28" args="" -->YAML_UTF8_ENCODING</em>&nbsp;</td><td>
+<p>The default UTF-8 encoding. </p>
+</td></tr>
+<tr><td valign="top"><em><a class="anchor" id="ggab88ee52b5d722e644c1cb4d1afcccdd9ac68c68725ec1f6492e59fd388fd123c9"></a><!-- doxytag: member="YAML_UTF16LE_ENCODING" ref="ggab88ee52b5d722e644c1cb4d1afcccdd9ac68c68725ec1f6492e59fd388fd123c9" args="" -->YAML_UTF16LE_ENCODING</em>&nbsp;</td><td>
+<p>The UTF-16-LE encoding with BOM. </p>
+</td></tr>
+<tr><td valign="top"><em><a class="anchor" id="ggab88ee52b5d722e644c1cb4d1afcccdd9a9f4fcb99a71d3416239f343f1334780b"></a><!-- doxytag: member="YAML_UTF16BE_ENCODING" ref="ggab88ee52b5d722e644c1cb4d1afcccdd9a9f4fcb99a71d3416239f343f1334780b" args="" -->YAML_UTF16BE_ENCODING</em>&nbsp;</td><td>
+<p>The UTF-16-BE encoding with BOM. </p>
+</td></tr>
+</table>
+</dd>
+</dl>
+
+</div>
+</div>
+<a class="anchor" id="ga912ad8c893126133fab5e4231db3017e"></a><!-- doxytag: member="yaml.h::yaml_break_e" ref="ga912ad8c893126133fab5e4231db3017e" args="" -->
+<div class="memitem">
+<div class="memproto">
+ <table class="memname">
+ <tr>
+ <td class="memname">enum <a class="el" href="group__basic.html#ga912ad8c893126133fab5e4231db3017e">yaml_break_e</a></td>
+ </tr>
+ </table>
+</div>
+<div class="memdoc">
+
+<p>Line break types. </p>
+<dl><dt><b>Enumerator: </b></dt><dd><table border="0" cellspacing="2" cellpadding="0">
+<tr><td valign="top"><em><a class="anchor" id="gga912ad8c893126133fab5e4231db3017ea052bd56adef565c33a86fcc05b49513f"></a><!-- doxytag: member="YAML_ANY_BREAK" ref="gga912ad8c893126133fab5e4231db3017ea052bd56adef565c33a86fcc05b49513f" args="" -->YAML_ANY_BREAK</em>&nbsp;</td><td>
+<p>Let the parser choose the break type. </p>
+</td></tr>
+<tr><td valign="top"><em><a class="anchor" id="gga912ad8c893126133fab5e4231db3017ea116a98ba4ed0bacfdf098a7d5beeb9d4"></a><!-- doxytag: member="YAML_CR_BREAK" ref="gga912ad8c893126133fab5e4231db3017ea116a98ba4ed0bacfdf098a7d5beeb9d4" args="" -->YAML_CR_BREAK</em>&nbsp;</td><td>
+<p>Use CR for line breaks (Mac style). </p>
+</td></tr>
+<tr><td valign="top"><em><a class="anchor" id="gga912ad8c893126133fab5e4231db3017ea23bf395462dcd045e22303be6f3f7781"></a><!-- doxytag: member="YAML_LN_BREAK" ref="gga912ad8c893126133fab5e4231db3017ea23bf395462dcd045e22303be6f3f7781" args="" -->YAML_LN_BREAK</em>&nbsp;</td><td>
+<p>Use LN for line breaks (Unix style). </p>
+</td></tr>
+<tr><td valign="top"><em><a class="anchor" id="gga912ad8c893126133fab5e4231db3017ea15f8daa406870ebfe82b85781c2468f3"></a><!-- doxytag: member="YAML_CRLN_BREAK" ref="gga912ad8c893126133fab5e4231db3017ea15f8daa406870ebfe82b85781c2468f3" args="" -->YAML_CRLN_BREAK</em>&nbsp;</td><td>
+<p>Use CR LN for line breaks (DOS style). </p>
+</td></tr>
+</table>
+</dd>
+</dl>
+
+</div>
+</div>
+<a class="anchor" id="ga2efbcde2e82238117982b789c5a8ea01"></a><!-- doxytag: member="yaml.h::yaml_error_type_e" ref="ga2efbcde2e82238117982b789c5a8ea01" args="" -->
+<div class="memitem">
+<div class="memproto">
+ <table class="memname">
+ <tr>
+ <td class="memname">enum <a class="el" href="group__basic.html#ga2efbcde2e82238117982b789c5a8ea01">yaml_error_type_e</a></td>
+ </tr>
+ </table>
+</div>
+<div class="memdoc">
+
+<p>Many bad things could happen with the parser and emitter. </p>
+<dl><dt><b>Enumerator: </b></dt><dd><table border="0" cellspacing="2" cellpadding="0">
+<tr><td valign="top"><em><a class="anchor" id="gga2efbcde2e82238117982b789c5a8ea01a24cadfb5364769959ad8647649d1e86f"></a><!-- doxytag: member="YAML_NO_ERROR" ref="gga2efbcde2e82238117982b789c5a8ea01a24cadfb5364769959ad8647649d1e86f" args="" -->YAML_NO_ERROR</em>&nbsp;</td><td>
+<p>No error is produced. </p>
+</td></tr>
+<tr><td valign="top"><em><a class="anchor" id="gga2efbcde2e82238117982b789c5a8ea01a57be0407d1f344206d9673c9571bde53"></a><!-- doxytag: member="YAML_MEMORY_ERROR" ref="gga2efbcde2e82238117982b789c5a8ea01a57be0407d1f344206d9673c9571bde53" args="" -->YAML_MEMORY_ERROR</em>&nbsp;</td><td>
+<p>Cannot allocate or reallocate a block of memory. </p>
+</td></tr>
+<tr><td valign="top"><em><a class="anchor" id="gga2efbcde2e82238117982b789c5a8ea01a9216f41a453dc36b090cdc1ca9f89637"></a><!-- doxytag: member="YAML_READER_ERROR" ref="gga2efbcde2e82238117982b789c5a8ea01a9216f41a453dc36b090cdc1ca9f89637" args="" -->YAML_READER_ERROR</em>&nbsp;</td><td>
+<p>Cannot read or decode the input stream. </p>
+</td></tr>
+<tr><td valign="top"><em><a class="anchor" id="gga2efbcde2e82238117982b789c5a8ea01a6f8d865d9a25b385146660d8260d3d6f"></a><!-- doxytag: member="YAML_SCANNER_ERROR" ref="gga2efbcde2e82238117982b789c5a8ea01a6f8d865d9a25b385146660d8260d3d6f" args="" -->YAML_SCANNER_ERROR</em>&nbsp;</td><td>
+<p>Cannot scan the input stream. </p>
+</td></tr>
+<tr><td valign="top"><em><a class="anchor" id="gga2efbcde2e82238117982b789c5a8ea01a0e12c79d8586bc61470e3088b666078b"></a><!-- doxytag: member="YAML_PARSER_ERROR" ref="gga2efbcde2e82238117982b789c5a8ea01a0e12c79d8586bc61470e3088b666078b" args="" -->YAML_PARSER_ERROR</em>&nbsp;</td><td>
+<p>Cannot parse the input stream. </p>
+</td></tr>
+<tr><td valign="top"><em><a class="anchor" id="gga2efbcde2e82238117982b789c5a8ea01a43d6eb640e50a1b1ec843cc54ab15f2b"></a><!-- doxytag: member="YAML_COMPOSER_ERROR" ref="gga2efbcde2e82238117982b789c5a8ea01a43d6eb640e50a1b1ec843cc54ab15f2b" args="" -->YAML_COMPOSER_ERROR</em>&nbsp;</td><td>
+<p>Cannot compose a YAML document. </p>
+</td></tr>
+<tr><td valign="top"><em><a class="anchor" id="gga2efbcde2e82238117982b789c5a8ea01ae80fef003be3d7e72ed7acae7984004c"></a><!-- doxytag: member="YAML_WRITER_ERROR" ref="gga2efbcde2e82238117982b789c5a8ea01ae80fef003be3d7e72ed7acae7984004c" args="" -->YAML_WRITER_ERROR</em>&nbsp;</td><td>
+<p>Cannot write to the output stream. </p>
+</td></tr>
+<tr><td valign="top"><em><a class="anchor" id="gga2efbcde2e82238117982b789c5a8ea01a8ec99a26382dd2853a5550027f6e9db1"></a><!-- doxytag: member="YAML_EMITTER_ERROR" ref="gga2efbcde2e82238117982b789c5a8ea01a8ec99a26382dd2853a5550027f6e9db1" args="" -->YAML_EMITTER_ERROR</em>&nbsp;</td><td>
+<p>Cannot emit a YAML stream. </p>
+</td></tr>
+</table>
+</dd>
+</dl>
+
+</div>
+</div>
+</div>
+<hr class="footer"/><address class="footer"><small>Generated on Mon May 30 2011 22:00:00 for yaml by&nbsp;
+<a href="http://www.doxygen.org/index.html">
+<img class="footer" src="doxygen.png" alt="doxygen"/></a> 1.7.1 </small></address>
+</body>
+</html>
diff --git a/contrib/libyaml/doc/html/group__emitter.html b/contrib/libyaml/doc/html/group__emitter.html
new file mode 100644
index 0000000..b0f9256
--- /dev/null
+++ b/contrib/libyaml/doc/html/group__emitter.html
@@ -0,0 +1,819 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head>
+<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/>
+<title>yaml: Emitter Definitions</title>
+<link href="tabs.css" rel="stylesheet" type="text/css"/>
+<link href="doxygen.css" rel="stylesheet" type="text/css"/>
+</head>
+<body>
+<!-- Generated by Doxygen 1.7.1 -->
+<div class="navigation" id="top">
+ <div class="tabs">
+ <ul class="tablist">
+ <li><a href="index.html"><span>Main&nbsp;Page</span></a></li>
+ <li><a href="modules.html"><span>Modules</span></a></li>
+ <li><a href="annotated.html"><span>Data&nbsp;Structures</span></a></li>
+ <li><a href="files.html"><span>Files</span></a></li>
+ </ul>
+ </div>
+</div>
+<div class="header">
+ <div class="summary">
+<a href="#nested-classes">Data Structures</a> &#124;
+<a href="#typedef-members">Typedefs</a> &#124;
+<a href="#enum-members">Enumerations</a> &#124;
+<a href="#func-members">Functions</a> </div>
+ <div class="headertitle">
+<h1>Emitter Definitions</h1> </div>
+</div>
+<div class="contents">
+<table class="memberdecls">
+<tr><td colspan="2"><h2><a name="nested-classes"></a>
+Data Structures</h2></td></tr>
+<tr><td class="memItemLeft" align="right" valign="top">struct &nbsp;</td><td class="memItemRight" valign="bottom"><a class="el" href="structyaml__emitter__s.html">yaml_emitter_s</a></td></tr>
+<tr><td class="mdescLeft">&nbsp;</td><td class="mdescRight">The emitter structure. <a href="structyaml__emitter__s.html#_details">More...</a><br/></td></tr>
+<tr><td colspan="2"><h2><a name="typedef-members"></a>
+Typedefs</h2></td></tr>
+<tr><td class="memItemLeft" align="right" valign="top">typedef int&nbsp;</td><td class="memItemRight" valign="bottom"><a class="el" href="group__emitter.html#ga1669659aacbe631ad406c78fce1f5379">yaml_write_handler_t</a> (void *data, unsigned char *buffer, size_t size)</td></tr>
+<tr><td class="mdescLeft">&nbsp;</td><td class="mdescRight">The prototype of a write handler. <a href="#ga1669659aacbe631ad406c78fce1f5379"></a><br/></td></tr>
+<tr><td class="memItemLeft" align="right" valign="top">typedef enum <a class="el" href="group__emitter.html#ga387b79da11c3941e43a56947263aa721">yaml_emitter_state_e</a>&nbsp;</td><td class="memItemRight" valign="bottom"><a class="el" href="group__emitter.html#ga0889461fa3efe8eee881aef48a4ba6b2">yaml_emitter_state_t</a></td></tr>
+<tr><td class="mdescLeft">&nbsp;</td><td class="mdescRight">The emitter states. <a href="#ga0889461fa3efe8eee881aef48a4ba6b2"></a><br/></td></tr>
+<tr><td class="memItemLeft" align="right" valign="top">typedef struct <a class="el" href="structyaml__emitter__s.html">yaml_emitter_s</a>&nbsp;</td><td class="memItemRight" valign="bottom"><a class="el" href="group__emitter.html#ga4ce3e054f0016c49d9e8c36d359e710b">yaml_emitter_t</a></td></tr>
+<tr><td class="mdescLeft">&nbsp;</td><td class="mdescRight">The emitter structure. <a href="#ga4ce3e054f0016c49d9e8c36d359e710b"></a><br/></td></tr>
+<tr><td colspan="2"><h2><a name="enum-members"></a>
+Enumerations</h2></td></tr>
+<tr><td class="memItemLeft" align="right" valign="top">enum &nbsp;</td><td class="memItemRight" valign="bottom"><a class="el" href="group__emitter.html#ga387b79da11c3941e43a56947263aa721">yaml_emitter_state_e</a> { <br/>
+&nbsp;&nbsp;<a class="el" href="group__emitter.html#gga387b79da11c3941e43a56947263aa721aa013a33dab710fe9a30ba014af27b81d">YAML_EMIT_STREAM_START_STATE</a>,
+<br/>
+&nbsp;&nbsp;<a class="el" href="group__emitter.html#gga387b79da11c3941e43a56947263aa721ab1ae25188f02581a137f66c4b6e084ae">YAML_EMIT_FIRST_DOCUMENT_START_STATE</a>,
+<br/>
+&nbsp;&nbsp;<a class="el" href="group__emitter.html#gga387b79da11c3941e43a56947263aa721a678d8c3146f0b2c84e0fc537a9b1109f">YAML_EMIT_DOCUMENT_START_STATE</a>,
+<br/>
+&nbsp;&nbsp;<a class="el" href="group__emitter.html#gga387b79da11c3941e43a56947263aa721a5ce3ed6155496a6fbd7384e310c58bec">YAML_EMIT_DOCUMENT_CONTENT_STATE</a>,
+<br/>
+&nbsp;&nbsp;<a class="el" href="group__emitter.html#gga387b79da11c3941e43a56947263aa721a100cad4538be033202da4bb85f8443d3">YAML_EMIT_DOCUMENT_END_STATE</a>,
+<br/>
+&nbsp;&nbsp;<a class="el" href="group__emitter.html#gga387b79da11c3941e43a56947263aa721a5a36fc535f3a5720fbb86712959e5654">YAML_EMIT_FLOW_SEQUENCE_FIRST_ITEM_STATE</a>,
+<br/>
+&nbsp;&nbsp;<a class="el" href="group__emitter.html#gga387b79da11c3941e43a56947263aa721aded45f1dee80027d7b9c6ce061c08767">YAML_EMIT_FLOW_SEQUENCE_ITEM_STATE</a>,
+<br/>
+&nbsp;&nbsp;<a class="el" href="group__emitter.html#gga387b79da11c3941e43a56947263aa721ab811f3d642dacc7c413af2c32356f894">YAML_EMIT_FLOW_MAPPING_FIRST_KEY_STATE</a>,
+<br/>
+&nbsp;&nbsp;<a class="el" href="group__emitter.html#gga387b79da11c3941e43a56947263aa721ababf835ee5cd4c6de2231e2a49e40626">YAML_EMIT_FLOW_MAPPING_KEY_STATE</a>,
+<br/>
+&nbsp;&nbsp;<a class="el" href="group__emitter.html#gga387b79da11c3941e43a56947263aa721aa6f687a6b57e727f0e7b7a2687ad7383">YAML_EMIT_FLOW_MAPPING_SIMPLE_VALUE_STATE</a>,
+<br/>
+&nbsp;&nbsp;<a class="el" href="group__emitter.html#gga387b79da11c3941e43a56947263aa721acb6dbcb535248b8fde779aeedc957b2e">YAML_EMIT_FLOW_MAPPING_VALUE_STATE</a>,
+<br/>
+&nbsp;&nbsp;<a class="el" href="group__emitter.html#gga387b79da11c3941e43a56947263aa721a68af7c090c6d0187788e390341f0cc4d">YAML_EMIT_BLOCK_SEQUENCE_FIRST_ITEM_STATE</a>,
+<br/>
+&nbsp;&nbsp;<a class="el" href="group__emitter.html#gga387b79da11c3941e43a56947263aa721a8197c180c3cefee7b67304e17b52c5ff">YAML_EMIT_BLOCK_SEQUENCE_ITEM_STATE</a>,
+<br/>
+&nbsp;&nbsp;<a class="el" href="group__emitter.html#gga387b79da11c3941e43a56947263aa721aee36d46c1facecfd73fab73e3343226e">YAML_EMIT_BLOCK_MAPPING_FIRST_KEY_STATE</a>,
+<br/>
+&nbsp;&nbsp;<a class="el" href="group__emitter.html#gga387b79da11c3941e43a56947263aa721a58495cae63b8c3d7c389b1281baeec05">YAML_EMIT_BLOCK_MAPPING_KEY_STATE</a>,
+<br/>
+&nbsp;&nbsp;<a class="el" href="group__emitter.html#gga387b79da11c3941e43a56947263aa721a4aa3c6bf2f2d976c47289c741d7a8704">YAML_EMIT_BLOCK_MAPPING_SIMPLE_VALUE_STATE</a>,
+<br/>
+&nbsp;&nbsp;<a class="el" href="group__emitter.html#gga387b79da11c3941e43a56947263aa721a7e0f7fac64fc64bb2bc9fe2ec93ca564">YAML_EMIT_BLOCK_MAPPING_VALUE_STATE</a>,
+<br/>
+&nbsp;&nbsp;<a class="el" href="group__emitter.html#gga387b79da11c3941e43a56947263aa721a2a0232912eaf4eeb06594ee6157dfbc0">YAML_EMIT_END_STATE</a>
+<br/>
+ }</td></tr>
+<tr><td class="mdescLeft">&nbsp;</td><td class="mdescRight"><p>The emitter states. </p>
+ <a href="group__emitter.html#ga387b79da11c3941e43a56947263aa721">More...</a><br/></td></tr>
+<tr><td colspan="2"><h2><a name="func-members"></a>
+Functions</h2></td></tr>
+<tr><td class="memItemLeft" align="right" valign="top">int&nbsp;</td><td class="memItemRight" valign="bottom"><a class="el" href="group__emitter.html#ga83649205374285802fc27aa293ecd111">yaml_emitter_initialize</a> (<a class="el" href="structyaml__emitter__s.html">yaml_emitter_t</a> *emitter)</td></tr>
+<tr><td class="mdescLeft">&nbsp;</td><td class="mdescRight">Initialize an emitter. <a href="#ga83649205374285802fc27aa293ecd111"></a><br/></td></tr>
+<tr><td class="memItemLeft" align="right" valign="top">void&nbsp;</td><td class="memItemRight" valign="bottom"><a class="el" href="group__emitter.html#gad705212f3a5150e3f00075fd90bc8c3d">yaml_emitter_delete</a> (<a class="el" href="structyaml__emitter__s.html">yaml_emitter_t</a> *emitter)</td></tr>
+<tr><td class="mdescLeft">&nbsp;</td><td class="mdescRight">Destroy an emitter. <a href="#gad705212f3a5150e3f00075fd90bc8c3d"></a><br/></td></tr>
+<tr><td class="memItemLeft" align="right" valign="top">void&nbsp;</td><td class="memItemRight" valign="bottom"><a class="el" href="group__emitter.html#ga62725c0f616f634588374d1a4c0ed35a">yaml_emitter_set_output_string</a> (<a class="el" href="structyaml__emitter__s.html">yaml_emitter_t</a> *emitter, unsigned char *output, size_t size, size_t *size_written)</td></tr>
+<tr><td class="mdescLeft">&nbsp;</td><td class="mdescRight">Set a string output. <a href="#ga62725c0f616f634588374d1a4c0ed35a"></a><br/></td></tr>
+<tr><td class="memItemLeft" align="right" valign="top">void&nbsp;</td><td class="memItemRight" valign="bottom"><a class="el" href="group__emitter.html#gaf7610c61b303bde9c701024c10ece024">yaml_emitter_set_output_file</a> (<a class="el" href="structyaml__emitter__s.html">yaml_emitter_t</a> *emitter, FILE *file)</td></tr>
+<tr><td class="mdescLeft">&nbsp;</td><td class="mdescRight">Set a file output. <a href="#gaf7610c61b303bde9c701024c10ece024"></a><br/></td></tr>
+<tr><td class="memItemLeft" align="right" valign="top">void&nbsp;</td><td class="memItemRight" valign="bottom"><a class="el" href="group__emitter.html#gac85a6a212ed7b469fb426a3451d15922">yaml_emitter_set_output</a> (<a class="el" href="structyaml__emitter__s.html">yaml_emitter_t</a> *emitter, <a class="el" href="group__emitter.html#ga1669659aacbe631ad406c78fce1f5379">yaml_write_handler_t</a> *handler, void *data)</td></tr>
+<tr><td class="mdescLeft">&nbsp;</td><td class="mdescRight">Set a generic output handler. <a href="#gac85a6a212ed7b469fb426a3451d15922"></a><br/></td></tr>
+<tr><td class="memItemLeft" align="right" valign="top">void&nbsp;</td><td class="memItemRight" valign="bottom"><a class="el" href="group__emitter.html#gabc22888ec8bf942199acbf38f7a0b9bb">yaml_emitter_set_encoding</a> (<a class="el" href="structyaml__emitter__s.html">yaml_emitter_t</a> *emitter, <a class="el" href="group__basic.html#ga2170996d7e636397b5e6bc0c1b7df7c6">yaml_encoding_t</a> encoding)</td></tr>
+<tr><td class="mdescLeft">&nbsp;</td><td class="mdescRight">Set the output encoding. <a href="#gabc22888ec8bf942199acbf38f7a0b9bb"></a><br/></td></tr>
+<tr><td class="memItemLeft" align="right" valign="top">void&nbsp;</td><td class="memItemRight" valign="bottom"><a class="el" href="group__emitter.html#ga62713a8130e11d95cbefa95a2eb3ac4b">yaml_emitter_set_canonical</a> (<a class="el" href="structyaml__emitter__s.html">yaml_emitter_t</a> *emitter, int canonical)</td></tr>
+<tr><td class="mdescLeft">&nbsp;</td><td class="mdescRight">Set if the output should be in the "canonical" format as in the YAML specification. <a href="#ga62713a8130e11d95cbefa95a2eb3ac4b"></a><br/></td></tr>
+<tr><td class="memItemLeft" align="right" valign="top">void&nbsp;</td><td class="memItemRight" valign="bottom"><a class="el" href="group__emitter.html#ga07eca3c344053a9028b4a84291cdf4d7">yaml_emitter_set_indent</a> (<a class="el" href="structyaml__emitter__s.html">yaml_emitter_t</a> *emitter, int indent)</td></tr>
+<tr><td class="mdescLeft">&nbsp;</td><td class="mdescRight">Set the intendation increment. <a href="#ga07eca3c344053a9028b4a84291cdf4d7"></a><br/></td></tr>
+<tr><td class="memItemLeft" align="right" valign="top">void&nbsp;</td><td class="memItemRight" valign="bottom"><a class="el" href="group__emitter.html#gaa91ae0fa8af5ab67e64567e08f4458c2">yaml_emitter_set_width</a> (<a class="el" href="structyaml__emitter__s.html">yaml_emitter_t</a> *emitter, int width)</td></tr>
+<tr><td class="mdescLeft">&nbsp;</td><td class="mdescRight">Set the preferred line width. <a href="#gaa91ae0fa8af5ab67e64567e08f4458c2"></a><br/></td></tr>
+<tr><td class="memItemLeft" align="right" valign="top">void&nbsp;</td><td class="memItemRight" valign="bottom"><a class="el" href="group__emitter.html#gaa59e7dcf24cb9b614c32af6c3e949fc3">yaml_emitter_set_unicode</a> (<a class="el" href="structyaml__emitter__s.html">yaml_emitter_t</a> *emitter, int unicode)</td></tr>
+<tr><td class="mdescLeft">&nbsp;</td><td class="mdescRight">Set if unescaped non-ASCII characters are allowed. <a href="#gaa59e7dcf24cb9b614c32af6c3e949fc3"></a><br/></td></tr>
+<tr><td class="memItemLeft" align="right" valign="top">void&nbsp;</td><td class="memItemRight" valign="bottom"><a class="el" href="group__emitter.html#ga04b5494f0b8244eec359579c31d5e20c">yaml_emitter_set_break</a> (<a class="el" href="structyaml__emitter__s.html">yaml_emitter_t</a> *emitter, <a class="el" href="group__basic.html#ga64d1365e1acd4deeab50d6b48e39cb6d">yaml_break_t</a> line_break)</td></tr>
+<tr><td class="mdescLeft">&nbsp;</td><td class="mdescRight">Set the preferred line break. <a href="#ga04b5494f0b8244eec359579c31d5e20c"></a><br/></td></tr>
+<tr><td class="memItemLeft" align="right" valign="top">int&nbsp;</td><td class="memItemRight" valign="bottom"><a class="el" href="group__emitter.html#ga4d6c0f8e712797e2660e69479fdae433">yaml_emitter_emit</a> (<a class="el" href="structyaml__emitter__s.html">yaml_emitter_t</a> *emitter, <a class="el" href="structyaml__event__s.html">yaml_event_t</a> *event)</td></tr>
+<tr><td class="mdescLeft">&nbsp;</td><td class="mdescRight">Emit an event. <a href="#ga4d6c0f8e712797e2660e69479fdae433"></a><br/></td></tr>
+<tr><td class="memItemLeft" align="right" valign="top">int&nbsp;</td><td class="memItemRight" valign="bottom"><a class="el" href="group__emitter.html#gae323c34e378040106f24c7b5ab834b16">yaml_emitter_open</a> (<a class="el" href="structyaml__emitter__s.html">yaml_emitter_t</a> *emitter)</td></tr>
+<tr><td class="mdescLeft">&nbsp;</td><td class="mdescRight">Start a YAML stream. <a href="#gae323c34e378040106f24c7b5ab834b16"></a><br/></td></tr>
+<tr><td class="memItemLeft" align="right" valign="top">int&nbsp;</td><td class="memItemRight" valign="bottom"><a class="el" href="group__emitter.html#gaa91442864679280985df14b2d96b8c42">yaml_emitter_close</a> (<a class="el" href="structyaml__emitter__s.html">yaml_emitter_t</a> *emitter)</td></tr>
+<tr><td class="mdescLeft">&nbsp;</td><td class="mdescRight">Finish a YAML stream. <a href="#gaa91442864679280985df14b2d96b8c42"></a><br/></td></tr>
+<tr><td class="memItemLeft" align="right" valign="top">int&nbsp;</td><td class="memItemRight" valign="bottom"><a class="el" href="group__emitter.html#ga5f0306abe9bff373b5bc339913b3769c">yaml_emitter_dump</a> (<a class="el" href="structyaml__emitter__s.html">yaml_emitter_t</a> *emitter, <a class="el" href="structyaml__document__s.html">yaml_document_t</a> *document)</td></tr>
+<tr><td class="mdescLeft">&nbsp;</td><td class="mdescRight">Emit a YAML document. <a href="#ga5f0306abe9bff373b5bc339913b3769c"></a><br/></td></tr>
+<tr><td class="memItemLeft" align="right" valign="top">int&nbsp;</td><td class="memItemRight" valign="bottom"><a class="el" href="group__emitter.html#gacaf24456e2bf85bc5654cbd7d828055f">yaml_emitter_flush</a> (<a class="el" href="structyaml__emitter__s.html">yaml_emitter_t</a> *emitter)</td></tr>
+<tr><td class="mdescLeft">&nbsp;</td><td class="mdescRight">Flush the accumulated characters to the output. <a href="#gacaf24456e2bf85bc5654cbd7d828055f"></a><br/></td></tr>
+</table>
+<hr/><h2>Typedef Documentation</h2>
+<a class="anchor" id="ga1669659aacbe631ad406c78fce1f5379"></a><!-- doxytag: member="yaml.h::yaml_write_handler_t" ref="ga1669659aacbe631ad406c78fce1f5379" args="(void *data, unsigned char *buffer, size_t size)" -->
+<div class="memitem">
+<div class="memproto">
+ <table class="memname">
+ <tr>
+ <td class="memname">typedef int <a class="el" href="group__emitter.html#ga1669659aacbe631ad406c78fce1f5379">yaml_write_handler_t</a>(void *data, unsigned char *buffer, size_t size)</td>
+ </tr>
+ </table>
+</div>
+<div class="memdoc">
+
+<p>The prototype of a write handler. </p>
+<p>The write handler is called when the emitter needs to flush the accumulated characters to the output. The handler should write <em>size</em> bytes of the <em>buffer</em> to the output.</p>
+<dl><dt><b>Parameters:</b></dt><dd>
+ <table border="0" cellspacing="2" cellpadding="0">
+ <tr><td valign="top"><tt>[in,out]</tt>&nbsp;</td><td valign="top"><em>data</em>&nbsp;</td><td>A pointer to an application data specified by <a class="el" href="group__emitter.html#gac85a6a212ed7b469fb426a3451d15922" title="Set a generic output handler.">yaml_emitter_set_output()</a>. </td></tr>
+ <tr><td valign="top"><tt>[in]</tt>&nbsp;</td><td valign="top"><em>buffer</em>&nbsp;</td><td>The buffer with bytes to be written. </td></tr>
+ <tr><td valign="top"><tt>[in]</tt>&nbsp;</td><td valign="top"><em>size</em>&nbsp;</td><td>The size of the buffer.</td></tr>
+ </table>
+ </dd>
+</dl>
+<dl class="return"><dt><b>Returns:</b></dt><dd>On success, the handler should return <code>1</code>. If the handler failed, the returned value should be <code>0</code>. </dd></dl>
+
+</div>
+</div>
+<a class="anchor" id="ga0889461fa3efe8eee881aef48a4ba6b2"></a><!-- doxytag: member="yaml.h::yaml_emitter_state_t" ref="ga0889461fa3efe8eee881aef48a4ba6b2" args="" -->
+<div class="memitem">
+<div class="memproto">
+ <table class="memname">
+ <tr>
+ <td class="memname">typedef enum <a class="el" href="group__emitter.html#ga387b79da11c3941e43a56947263aa721">yaml_emitter_state_e</a> <a class="el" href="group__emitter.html#ga0889461fa3efe8eee881aef48a4ba6b2">yaml_emitter_state_t</a></td>
+ </tr>
+ </table>
+</div>
+<div class="memdoc">
+
+<p>The emitter states. </p>
+
+</div>
+</div>
+<a class="anchor" id="ga4ce3e054f0016c49d9e8c36d359e710b"></a><!-- doxytag: member="yaml.h::yaml_emitter_t" ref="ga4ce3e054f0016c49d9e8c36d359e710b" args="" -->
+<div class="memitem">
+<div class="memproto">
+ <table class="memname">
+ <tr>
+ <td class="memname">typedef struct <a class="el" href="structyaml__emitter__s.html">yaml_emitter_s</a> <a class="el" href="structyaml__emitter__s.html">yaml_emitter_t</a></td>
+ </tr>
+ </table>
+</div>
+<div class="memdoc">
+
+<p>The emitter structure. </p>
+<p>All members are internal. Manage the structure using the <code>yaml_emitter_</code> family of functions. </p>
+
+</div>
+</div>
+<hr/><h2>Enumeration Type Documentation</h2>
+<a class="anchor" id="ga387b79da11c3941e43a56947263aa721"></a><!-- doxytag: member="yaml.h::yaml_emitter_state_e" ref="ga387b79da11c3941e43a56947263aa721" args="" -->
+<div class="memitem">
+<div class="memproto">
+ <table class="memname">
+ <tr>
+ <td class="memname">enum <a class="el" href="group__emitter.html#ga387b79da11c3941e43a56947263aa721">yaml_emitter_state_e</a></td>
+ </tr>
+ </table>
+</div>
+<div class="memdoc">
+
+<p>The emitter states. </p>
+<dl><dt><b>Enumerator: </b></dt><dd><table border="0" cellspacing="2" cellpadding="0">
+<tr><td valign="top"><em><a class="anchor" id="gga387b79da11c3941e43a56947263aa721aa013a33dab710fe9a30ba014af27b81d"></a><!-- doxytag: member="YAML_EMIT_STREAM_START_STATE" ref="gga387b79da11c3941e43a56947263aa721aa013a33dab710fe9a30ba014af27b81d" args="" -->YAML_EMIT_STREAM_START_STATE</em>&nbsp;</td><td>
+<p>Expect STREAM-START. </p>
+</td></tr>
+<tr><td valign="top"><em><a class="anchor" id="gga387b79da11c3941e43a56947263aa721ab1ae25188f02581a137f66c4b6e084ae"></a><!-- doxytag: member="YAML_EMIT_FIRST_DOCUMENT_START_STATE" ref="gga387b79da11c3941e43a56947263aa721ab1ae25188f02581a137f66c4b6e084ae" args="" -->YAML_EMIT_FIRST_DOCUMENT_START_STATE</em>&nbsp;</td><td>
+<p>Expect the first DOCUMENT-START or STREAM-END. </p>
+</td></tr>
+<tr><td valign="top"><em><a class="anchor" id="gga387b79da11c3941e43a56947263aa721a678d8c3146f0b2c84e0fc537a9b1109f"></a><!-- doxytag: member="YAML_EMIT_DOCUMENT_START_STATE" ref="gga387b79da11c3941e43a56947263aa721a678d8c3146f0b2c84e0fc537a9b1109f" args="" -->YAML_EMIT_DOCUMENT_START_STATE</em>&nbsp;</td><td>
+<p>Expect DOCUMENT-START or STREAM-END. </p>
+</td></tr>
+<tr><td valign="top"><em><a class="anchor" id="gga387b79da11c3941e43a56947263aa721a5ce3ed6155496a6fbd7384e310c58bec"></a><!-- doxytag: member="YAML_EMIT_DOCUMENT_CONTENT_STATE" ref="gga387b79da11c3941e43a56947263aa721a5ce3ed6155496a6fbd7384e310c58bec" args="" -->YAML_EMIT_DOCUMENT_CONTENT_STATE</em>&nbsp;</td><td>
+<p>Expect the content of a document. </p>
+</td></tr>
+<tr><td valign="top"><em><a class="anchor" id="gga387b79da11c3941e43a56947263aa721a100cad4538be033202da4bb85f8443d3"></a><!-- doxytag: member="YAML_EMIT_DOCUMENT_END_STATE" ref="gga387b79da11c3941e43a56947263aa721a100cad4538be033202da4bb85f8443d3" args="" -->YAML_EMIT_DOCUMENT_END_STATE</em>&nbsp;</td><td>
+<p>Expect DOCUMENT-END. </p>
+</td></tr>
+<tr><td valign="top"><em><a class="anchor" id="gga387b79da11c3941e43a56947263aa721a5a36fc535f3a5720fbb86712959e5654"></a><!-- doxytag: member="YAML_EMIT_FLOW_SEQUENCE_FIRST_ITEM_STATE" ref="gga387b79da11c3941e43a56947263aa721a5a36fc535f3a5720fbb86712959e5654" args="" -->YAML_EMIT_FLOW_SEQUENCE_FIRST_ITEM_STATE</em>&nbsp;</td><td>
+<p>Expect the first item of a flow sequence. </p>
+</td></tr>
+<tr><td valign="top"><em><a class="anchor" id="gga387b79da11c3941e43a56947263aa721aded45f1dee80027d7b9c6ce061c08767"></a><!-- doxytag: member="YAML_EMIT_FLOW_SEQUENCE_ITEM_STATE" ref="gga387b79da11c3941e43a56947263aa721aded45f1dee80027d7b9c6ce061c08767" args="" -->YAML_EMIT_FLOW_SEQUENCE_ITEM_STATE</em>&nbsp;</td><td>
+<p>Expect an item of a flow sequence. </p>
+</td></tr>
+<tr><td valign="top"><em><a class="anchor" id="gga387b79da11c3941e43a56947263aa721ab811f3d642dacc7c413af2c32356f894"></a><!-- doxytag: member="YAML_EMIT_FLOW_MAPPING_FIRST_KEY_STATE" ref="gga387b79da11c3941e43a56947263aa721ab811f3d642dacc7c413af2c32356f894" args="" -->YAML_EMIT_FLOW_MAPPING_FIRST_KEY_STATE</em>&nbsp;</td><td>
+<p>Expect the first key of a flow mapping. </p>
+</td></tr>
+<tr><td valign="top"><em><a class="anchor" id="gga387b79da11c3941e43a56947263aa721ababf835ee5cd4c6de2231e2a49e40626"></a><!-- doxytag: member="YAML_EMIT_FLOW_MAPPING_KEY_STATE" ref="gga387b79da11c3941e43a56947263aa721ababf835ee5cd4c6de2231e2a49e40626" args="" -->YAML_EMIT_FLOW_MAPPING_KEY_STATE</em>&nbsp;</td><td>
+<p>Expect a key of a flow mapping. </p>
+</td></tr>
+<tr><td valign="top"><em><a class="anchor" id="gga387b79da11c3941e43a56947263aa721aa6f687a6b57e727f0e7b7a2687ad7383"></a><!-- doxytag: member="YAML_EMIT_FLOW_MAPPING_SIMPLE_VALUE_STATE" ref="gga387b79da11c3941e43a56947263aa721aa6f687a6b57e727f0e7b7a2687ad7383" args="" -->YAML_EMIT_FLOW_MAPPING_SIMPLE_VALUE_STATE</em>&nbsp;</td><td>
+<p>Expect a value for a simple key of a flow mapping. </p>
+</td></tr>
+<tr><td valign="top"><em><a class="anchor" id="gga387b79da11c3941e43a56947263aa721acb6dbcb535248b8fde779aeedc957b2e"></a><!-- doxytag: member="YAML_EMIT_FLOW_MAPPING_VALUE_STATE" ref="gga387b79da11c3941e43a56947263aa721acb6dbcb535248b8fde779aeedc957b2e" args="" -->YAML_EMIT_FLOW_MAPPING_VALUE_STATE</em>&nbsp;</td><td>
+<p>Expect a value of a flow mapping. </p>
+</td></tr>
+<tr><td valign="top"><em><a class="anchor" id="gga387b79da11c3941e43a56947263aa721a68af7c090c6d0187788e390341f0cc4d"></a><!-- doxytag: member="YAML_EMIT_BLOCK_SEQUENCE_FIRST_ITEM_STATE" ref="gga387b79da11c3941e43a56947263aa721a68af7c090c6d0187788e390341f0cc4d" args="" -->YAML_EMIT_BLOCK_SEQUENCE_FIRST_ITEM_STATE</em>&nbsp;</td><td>
+<p>Expect the first item of a block sequence. </p>
+</td></tr>
+<tr><td valign="top"><em><a class="anchor" id="gga387b79da11c3941e43a56947263aa721a8197c180c3cefee7b67304e17b52c5ff"></a><!-- doxytag: member="YAML_EMIT_BLOCK_SEQUENCE_ITEM_STATE" ref="gga387b79da11c3941e43a56947263aa721a8197c180c3cefee7b67304e17b52c5ff" args="" -->YAML_EMIT_BLOCK_SEQUENCE_ITEM_STATE</em>&nbsp;</td><td>
+<p>Expect an item of a block sequence. </p>
+</td></tr>
+<tr><td valign="top"><em><a class="anchor" id="gga387b79da11c3941e43a56947263aa721aee36d46c1facecfd73fab73e3343226e"></a><!-- doxytag: member="YAML_EMIT_BLOCK_MAPPING_FIRST_KEY_STATE" ref="gga387b79da11c3941e43a56947263aa721aee36d46c1facecfd73fab73e3343226e" args="" -->YAML_EMIT_BLOCK_MAPPING_FIRST_KEY_STATE</em>&nbsp;</td><td>
+<p>Expect the first key of a block mapping. </p>
+</td></tr>
+<tr><td valign="top"><em><a class="anchor" id="gga387b79da11c3941e43a56947263aa721a58495cae63b8c3d7c389b1281baeec05"></a><!-- doxytag: member="YAML_EMIT_BLOCK_MAPPING_KEY_STATE" ref="gga387b79da11c3941e43a56947263aa721a58495cae63b8c3d7c389b1281baeec05" args="" -->YAML_EMIT_BLOCK_MAPPING_KEY_STATE</em>&nbsp;</td><td>
+<p>Expect the key of a block mapping. </p>
+</td></tr>
+<tr><td valign="top"><em><a class="anchor" id="gga387b79da11c3941e43a56947263aa721a4aa3c6bf2f2d976c47289c741d7a8704"></a><!-- doxytag: member="YAML_EMIT_BLOCK_MAPPING_SIMPLE_VALUE_STATE" ref="gga387b79da11c3941e43a56947263aa721a4aa3c6bf2f2d976c47289c741d7a8704" args="" -->YAML_EMIT_BLOCK_MAPPING_SIMPLE_VALUE_STATE</em>&nbsp;</td><td>
+<p>Expect a value for a simple key of a block mapping. </p>
+</td></tr>
+<tr><td valign="top"><em><a class="anchor" id="gga387b79da11c3941e43a56947263aa721a7e0f7fac64fc64bb2bc9fe2ec93ca564"></a><!-- doxytag: member="YAML_EMIT_BLOCK_MAPPING_VALUE_STATE" ref="gga387b79da11c3941e43a56947263aa721a7e0f7fac64fc64bb2bc9fe2ec93ca564" args="" -->YAML_EMIT_BLOCK_MAPPING_VALUE_STATE</em>&nbsp;</td><td>
+<p>Expect a value of a block mapping. </p>
+</td></tr>
+<tr><td valign="top"><em><a class="anchor" id="gga387b79da11c3941e43a56947263aa721a2a0232912eaf4eeb06594ee6157dfbc0"></a><!-- doxytag: member="YAML_EMIT_END_STATE" ref="gga387b79da11c3941e43a56947263aa721a2a0232912eaf4eeb06594ee6157dfbc0" args="" -->YAML_EMIT_END_STATE</em>&nbsp;</td><td>
+<p>Expect nothing. </p>
+</td></tr>
+</table>
+</dd>
+</dl>
+
+</div>
+</div>
+<hr/><h2>Function Documentation</h2>
+<a class="anchor" id="ga83649205374285802fc27aa293ecd111"></a><!-- doxytag: member="yaml.h::yaml_emitter_initialize" ref="ga83649205374285802fc27aa293ecd111" args="(yaml_emitter_t *emitter)" -->
+<div class="memitem">
+<div class="memproto">
+ <table class="memname">
+ <tr>
+ <td class="memname">int yaml_emitter_initialize </td>
+ <td>(</td>
+ <td class="paramtype"><a class="el" href="structyaml__emitter__s.html">yaml_emitter_t</a> *&nbsp;</td>
+ <td class="paramname"> <em>emitter</em></td>
+ <td>&nbsp;)&nbsp;</td>
+ <td></td>
+ </tr>
+ </table>
+</div>
+<div class="memdoc">
+
+<p>Initialize an emitter. </p>
+<p>This function creates a new emitter object. An application is responsible for destroying the object using the <a class="el" href="group__emitter.html#gad705212f3a5150e3f00075fd90bc8c3d" title="Destroy an emitter.">yaml_emitter_delete()</a> function.</p>
+<dl><dt><b>Parameters:</b></dt><dd>
+ <table border="0" cellspacing="2" cellpadding="0">
+ <tr><td valign="top"><tt>[out]</tt>&nbsp;</td><td valign="top"><em>emitter</em>&nbsp;</td><td>An empty parser object.</td></tr>
+ </table>
+ </dd>
+</dl>
+<dl class="return"><dt><b>Returns:</b></dt><dd><code>1</code> if the function succeeded, <code>0</code> on error. </dd></dl>
+
+</div>
+</div>
+<a class="anchor" id="gad705212f3a5150e3f00075fd90bc8c3d"></a><!-- doxytag: member="yaml.h::yaml_emitter_delete" ref="gad705212f3a5150e3f00075fd90bc8c3d" args="(yaml_emitter_t *emitter)" -->
+<div class="memitem">
+<div class="memproto">
+ <table class="memname">
+ <tr>
+ <td class="memname">void yaml_emitter_delete </td>
+ <td>(</td>
+ <td class="paramtype"><a class="el" href="structyaml__emitter__s.html">yaml_emitter_t</a> *&nbsp;</td>
+ <td class="paramname"> <em>emitter</em></td>
+ <td>&nbsp;)&nbsp;</td>
+ <td></td>
+ </tr>
+ </table>
+</div>
+<div class="memdoc">
+
+<p>Destroy an emitter. </p>
+<dl><dt><b>Parameters:</b></dt><dd>
+ <table border="0" cellspacing="2" cellpadding="0">
+ <tr><td valign="top"><tt>[in,out]</tt>&nbsp;</td><td valign="top"><em>emitter</em>&nbsp;</td><td>An emitter object. </td></tr>
+ </table>
+ </dd>
+</dl>
+
+</div>
+</div>
+<a class="anchor" id="ga62725c0f616f634588374d1a4c0ed35a"></a><!-- doxytag: member="yaml.h::yaml_emitter_set_output_string" ref="ga62725c0f616f634588374d1a4c0ed35a" args="(yaml_emitter_t *emitter, unsigned char *output, size_t size, size_t *size_written)" -->
+<div class="memitem">
+<div class="memproto">
+ <table class="memname">
+ <tr>
+ <td class="memname">void yaml_emitter_set_output_string </td>
+ <td>(</td>
+ <td class="paramtype"><a class="el" href="structyaml__emitter__s.html">yaml_emitter_t</a> *&nbsp;</td>
+ <td class="paramname"> <em>emitter</em>, </td>
+ </tr>
+ <tr>
+ <td class="paramkey"></td>
+ <td></td>
+ <td class="paramtype">unsigned char *&nbsp;</td>
+ <td class="paramname"> <em>output</em>, </td>
+ </tr>
+ <tr>
+ <td class="paramkey"></td>
+ <td></td>
+ <td class="paramtype">size_t&nbsp;</td>
+ <td class="paramname"> <em>size</em>, </td>
+ </tr>
+ <tr>
+ <td class="paramkey"></td>
+ <td></td>
+ <td class="paramtype">size_t *&nbsp;</td>
+ <td class="paramname"> <em>size_written</em></td><td>&nbsp;</td>
+ </tr>
+ <tr>
+ <td></td>
+ <td>)</td>
+ <td></td><td></td><td></td>
+ </tr>
+ </table>
+</div>
+<div class="memdoc">
+
+<p>Set a string output. </p>
+<p>The emitter will write the output characters to the <em>output</em> buffer of the size <em>size</em>. The emitter will set <em>size_written</em> to the number of written bytes. If the buffer is smaller than required, the emitter produces the YAML_WRITE_ERROR error.</p>
+<dl><dt><b>Parameters:</b></dt><dd>
+ <table border="0" cellspacing="2" cellpadding="0">
+ <tr><td valign="top"><tt>[in,out]</tt>&nbsp;</td><td valign="top"><em>emitter</em>&nbsp;</td><td>An emitter object. </td></tr>
+ <tr><td valign="top"><tt>[in]</tt>&nbsp;</td><td valign="top"><em>output</em>&nbsp;</td><td>An output buffer. </td></tr>
+ <tr><td valign="top"><tt>[in]</tt>&nbsp;</td><td valign="top"><em>size</em>&nbsp;</td><td>The buffer size. </td></tr>
+ <tr><td valign="top"><tt>[in]</tt>&nbsp;</td><td valign="top"><em>size_written</em>&nbsp;</td><td>The pointer to save the number of written bytes. </td></tr>
+ </table>
+ </dd>
+</dl>
+
+</div>
+</div>
+<a class="anchor" id="gaf7610c61b303bde9c701024c10ece024"></a><!-- doxytag: member="yaml.h::yaml_emitter_set_output_file" ref="gaf7610c61b303bde9c701024c10ece024" args="(yaml_emitter_t *emitter, FILE *file)" -->
+<div class="memitem">
+<div class="memproto">
+ <table class="memname">
+ <tr>
+ <td class="memname">void yaml_emitter_set_output_file </td>
+ <td>(</td>
+ <td class="paramtype"><a class="el" href="structyaml__emitter__s.html">yaml_emitter_t</a> *&nbsp;</td>
+ <td class="paramname"> <em>emitter</em>, </td>
+ </tr>
+ <tr>
+ <td class="paramkey"></td>
+ <td></td>
+ <td class="paramtype">FILE *&nbsp;</td>
+ <td class="paramname"> <em>file</em></td><td>&nbsp;</td>
+ </tr>
+ <tr>
+ <td></td>
+ <td>)</td>
+ <td></td><td></td><td></td>
+ </tr>
+ </table>
+</div>
+<div class="memdoc">
+
+<p>Set a file output. </p>
+<p><em>file</em> should be a file object open for writing. The application is responsible for closing the <em>file</em>.</p>
+<dl><dt><b>Parameters:</b></dt><dd>
+ <table border="0" cellspacing="2" cellpadding="0">
+ <tr><td valign="top"><tt>[in,out]</tt>&nbsp;</td><td valign="top"><em>emitter</em>&nbsp;</td><td>An emitter object. </td></tr>
+ <tr><td valign="top"><tt>[in]</tt>&nbsp;</td><td valign="top"><em>file</em>&nbsp;</td><td>An open file. </td></tr>
+ </table>
+ </dd>
+</dl>
+
+</div>
+</div>
+<a class="anchor" id="gac85a6a212ed7b469fb426a3451d15922"></a><!-- doxytag: member="yaml.h::yaml_emitter_set_output" ref="gac85a6a212ed7b469fb426a3451d15922" args="(yaml_emitter_t *emitter, yaml_write_handler_t *handler, void *data)" -->
+<div class="memitem">
+<div class="memproto">
+ <table class="memname">
+ <tr>
+ <td class="memname">void yaml_emitter_set_output </td>
+ <td>(</td>
+ <td class="paramtype"><a class="el" href="structyaml__emitter__s.html">yaml_emitter_t</a> *&nbsp;</td>
+ <td class="paramname"> <em>emitter</em>, </td>
+ </tr>
+ <tr>
+ <td class="paramkey"></td>
+ <td></td>
+ <td class="paramtype"><a class="el" href="group__emitter.html#ga1669659aacbe631ad406c78fce1f5379">yaml_write_handler_t</a> *&nbsp;</td>
+ <td class="paramname"> <em>handler</em>, </td>
+ </tr>
+ <tr>
+ <td class="paramkey"></td>
+ <td></td>
+ <td class="paramtype">void *&nbsp;</td>
+ <td class="paramname"> <em>data</em></td><td>&nbsp;</td>
+ </tr>
+ <tr>
+ <td></td>
+ <td>)</td>
+ <td></td><td></td><td></td>
+ </tr>
+ </table>
+</div>
+<div class="memdoc">
+
+<p>Set a generic output handler. </p>
+<dl><dt><b>Parameters:</b></dt><dd>
+ <table border="0" cellspacing="2" cellpadding="0">
+ <tr><td valign="top"><tt>[in,out]</tt>&nbsp;</td><td valign="top"><em>emitter</em>&nbsp;</td><td>An emitter object. </td></tr>
+ <tr><td valign="top"><tt>[in]</tt>&nbsp;</td><td valign="top"><em>handler</em>&nbsp;</td><td>A write handler. </td></tr>
+ <tr><td valign="top"><tt>[in]</tt>&nbsp;</td><td valign="top"><em>data</em>&nbsp;</td><td>Any application data for passing to the write handler. </td></tr>
+ </table>
+ </dd>
+</dl>
+
+</div>
+</div>
+<a class="anchor" id="gabc22888ec8bf942199acbf38f7a0b9bb"></a><!-- doxytag: member="yaml.h::yaml_emitter_set_encoding" ref="gabc22888ec8bf942199acbf38f7a0b9bb" args="(yaml_emitter_t *emitter, yaml_encoding_t encoding)" -->
+<div class="memitem">
+<div class="memproto">
+ <table class="memname">
+ <tr>
+ <td class="memname">void yaml_emitter_set_encoding </td>
+ <td>(</td>
+ <td class="paramtype"><a class="el" href="structyaml__emitter__s.html">yaml_emitter_t</a> *&nbsp;</td>
+ <td class="paramname"> <em>emitter</em>, </td>
+ </tr>
+ <tr>
+ <td class="paramkey"></td>
+ <td></td>
+ <td class="paramtype"><a class="el" href="group__basic.html#ga2170996d7e636397b5e6bc0c1b7df7c6">yaml_encoding_t</a>&nbsp;</td>
+ <td class="paramname"> <em>encoding</em></td><td>&nbsp;</td>
+ </tr>
+ <tr>
+ <td></td>
+ <td>)</td>
+ <td></td><td></td><td></td>
+ </tr>
+ </table>
+</div>
+<div class="memdoc">
+
+<p>Set the output encoding. </p>
+<dl><dt><b>Parameters:</b></dt><dd>
+ <table border="0" cellspacing="2" cellpadding="0">
+ <tr><td valign="top"><tt>[in,out]</tt>&nbsp;</td><td valign="top"><em>emitter</em>&nbsp;</td><td>An emitter object. </td></tr>
+ <tr><td valign="top"><tt>[in]</tt>&nbsp;</td><td valign="top"><em>encoding</em>&nbsp;</td><td>The output encoding. </td></tr>
+ </table>
+ </dd>
+</dl>
+
+</div>
+</div>
+<a class="anchor" id="ga62713a8130e11d95cbefa95a2eb3ac4b"></a><!-- doxytag: member="yaml.h::yaml_emitter_set_canonical" ref="ga62713a8130e11d95cbefa95a2eb3ac4b" args="(yaml_emitter_t *emitter, int canonical)" -->
+<div class="memitem">
+<div class="memproto">
+ <table class="memname">
+ <tr>
+ <td class="memname">void yaml_emitter_set_canonical </td>
+ <td>(</td>
+ <td class="paramtype"><a class="el" href="structyaml__emitter__s.html">yaml_emitter_t</a> *&nbsp;</td>
+ <td class="paramname"> <em>emitter</em>, </td>
+ </tr>
+ <tr>
+ <td class="paramkey"></td>
+ <td></td>
+ <td class="paramtype">int&nbsp;</td>
+ <td class="paramname"> <em>canonical</em></td><td>&nbsp;</td>
+ </tr>
+ <tr>
+ <td></td>
+ <td>)</td>
+ <td></td><td></td><td></td>
+ </tr>
+ </table>
+</div>
+<div class="memdoc">
+
+<p>Set if the output should be in the "canonical" format as in the YAML specification. </p>
+<dl><dt><b>Parameters:</b></dt><dd>
+ <table border="0" cellspacing="2" cellpadding="0">
+ <tr><td valign="top"><tt>[in,out]</tt>&nbsp;</td><td valign="top"><em>emitter</em>&nbsp;</td><td>An emitter object. </td></tr>
+ <tr><td valign="top"><tt>[in]</tt>&nbsp;</td><td valign="top"><em>canonical</em>&nbsp;</td><td>If the output is canonical. </td></tr>
+ </table>
+ </dd>
+</dl>
+
+</div>
+</div>
+<a class="anchor" id="ga07eca3c344053a9028b4a84291cdf4d7"></a><!-- doxytag: member="yaml.h::yaml_emitter_set_indent" ref="ga07eca3c344053a9028b4a84291cdf4d7" args="(yaml_emitter_t *emitter, int indent)" -->
+<div class="memitem">
+<div class="memproto">
+ <table class="memname">
+ <tr>
+ <td class="memname">void yaml_emitter_set_indent </td>
+ <td>(</td>
+ <td class="paramtype"><a class="el" href="structyaml__emitter__s.html">yaml_emitter_t</a> *&nbsp;</td>
+ <td class="paramname"> <em>emitter</em>, </td>
+ </tr>
+ <tr>
+ <td class="paramkey"></td>
+ <td></td>
+ <td class="paramtype">int&nbsp;</td>
+ <td class="paramname"> <em>indent</em></td><td>&nbsp;</td>
+ </tr>
+ <tr>
+ <td></td>
+ <td>)</td>
+ <td></td><td></td><td></td>
+ </tr>
+ </table>
+</div>
+<div class="memdoc">
+
+<p>Set the intendation increment. </p>
+<dl><dt><b>Parameters:</b></dt><dd>
+ <table border="0" cellspacing="2" cellpadding="0">
+ <tr><td valign="top"><tt>[in,out]</tt>&nbsp;</td><td valign="top"><em>emitter</em>&nbsp;</td><td>An emitter object. </td></tr>
+ <tr><td valign="top"><tt>[in]</tt>&nbsp;</td><td valign="top"><em>indent</em>&nbsp;</td><td>The indentation increment (1 &lt; . &lt; 10). </td></tr>
+ </table>
+ </dd>
+</dl>
+
+</div>
+</div>
+<a class="anchor" id="gaa91ae0fa8af5ab67e64567e08f4458c2"></a><!-- doxytag: member="yaml.h::yaml_emitter_set_width" ref="gaa91ae0fa8af5ab67e64567e08f4458c2" args="(yaml_emitter_t *emitter, int width)" -->
+<div class="memitem">
+<div class="memproto">
+ <table class="memname">
+ <tr>
+ <td class="memname">void yaml_emitter_set_width </td>
+ <td>(</td>
+ <td class="paramtype"><a class="el" href="structyaml__emitter__s.html">yaml_emitter_t</a> *&nbsp;</td>
+ <td class="paramname"> <em>emitter</em>, </td>
+ </tr>
+ <tr>
+ <td class="paramkey"></td>
+ <td></td>
+ <td class="paramtype">int&nbsp;</td>
+ <td class="paramname"> <em>width</em></td><td>&nbsp;</td>
+ </tr>
+ <tr>
+ <td></td>
+ <td>)</td>
+ <td></td><td></td><td></td>
+ </tr>
+ </table>
+</div>
+<div class="memdoc">
+
+<p>Set the preferred line width. </p>
+<p><code>-1</code> means unlimited.</p>
+<dl><dt><b>Parameters:</b></dt><dd>
+ <table border="0" cellspacing="2" cellpadding="0">
+ <tr><td valign="top"><tt>[in,out]</tt>&nbsp;</td><td valign="top"><em>emitter</em>&nbsp;</td><td>An emitter object. </td></tr>
+ <tr><td valign="top"><tt>[in]</tt>&nbsp;</td><td valign="top"><em>width</em>&nbsp;</td><td>The preferred line width. </td></tr>
+ </table>
+ </dd>
+</dl>
+
+</div>
+</div>
+<a class="anchor" id="gaa59e7dcf24cb9b614c32af6c3e949fc3"></a><!-- doxytag: member="yaml.h::yaml_emitter_set_unicode" ref="gaa59e7dcf24cb9b614c32af6c3e949fc3" args="(yaml_emitter_t *emitter, int unicode)" -->
+<div class="memitem">
+<div class="memproto">
+ <table class="memname">
+ <tr>
+ <td class="memname">void yaml_emitter_set_unicode </td>
+ <td>(</td>
+ <td class="paramtype"><a class="el" href="structyaml__emitter__s.html">yaml_emitter_t</a> *&nbsp;</td>
+ <td class="paramname"> <em>emitter</em>, </td>
+ </tr>
+ <tr>
+ <td class="paramkey"></td>
+ <td></td>
+ <td class="paramtype">int&nbsp;</td>
+ <td class="paramname"> <em>unicode</em></td><td>&nbsp;</td>
+ </tr>
+ <tr>
+ <td></td>
+ <td>)</td>
+ <td></td><td></td><td></td>
+ </tr>
+ </table>
+</div>
+<div class="memdoc">
+
+<p>Set if unescaped non-ASCII characters are allowed. </p>
+<dl><dt><b>Parameters:</b></dt><dd>
+ <table border="0" cellspacing="2" cellpadding="0">
+ <tr><td valign="top"><tt>[in,out]</tt>&nbsp;</td><td valign="top"><em>emitter</em>&nbsp;</td><td>An emitter object. </td></tr>
+ <tr><td valign="top"><tt>[in]</tt>&nbsp;</td><td valign="top"><em>unicode</em>&nbsp;</td><td>If unescaped Unicode characters are allowed. </td></tr>
+ </table>
+ </dd>
+</dl>
+
+</div>
+</div>
+<a class="anchor" id="ga04b5494f0b8244eec359579c31d5e20c"></a><!-- doxytag: member="yaml.h::yaml_emitter_set_break" ref="ga04b5494f0b8244eec359579c31d5e20c" args="(yaml_emitter_t *emitter, yaml_break_t line_break)" -->
+<div class="memitem">
+<div class="memproto">
+ <table class="memname">
+ <tr>
+ <td class="memname">void yaml_emitter_set_break </td>
+ <td>(</td>
+ <td class="paramtype"><a class="el" href="structyaml__emitter__s.html">yaml_emitter_t</a> *&nbsp;</td>
+ <td class="paramname"> <em>emitter</em>, </td>
+ </tr>
+ <tr>
+ <td class="paramkey"></td>
+ <td></td>
+ <td class="paramtype"><a class="el" href="group__basic.html#ga64d1365e1acd4deeab50d6b48e39cb6d">yaml_break_t</a>&nbsp;</td>
+ <td class="paramname"> <em>line_break</em></td><td>&nbsp;</td>
+ </tr>
+ <tr>
+ <td></td>
+ <td>)</td>
+ <td></td><td></td><td></td>
+ </tr>
+ </table>
+</div>
+<div class="memdoc">
+
+<p>Set the preferred line break. </p>
+<dl><dt><b>Parameters:</b></dt><dd>
+ <table border="0" cellspacing="2" cellpadding="0">
+ <tr><td valign="top"><tt>[in,out]</tt>&nbsp;</td><td valign="top"><em>emitter</em>&nbsp;</td><td>An emitter object. </td></tr>
+ <tr><td valign="top"><tt>[in]</tt>&nbsp;</td><td valign="top"><em>line_break</em>&nbsp;</td><td>The preferred line break. </td></tr>
+ </table>
+ </dd>
+</dl>
+
+</div>
+</div>
+<a class="anchor" id="ga4d6c0f8e712797e2660e69479fdae433"></a><!-- doxytag: member="yaml.h::yaml_emitter_emit" ref="ga4d6c0f8e712797e2660e69479fdae433" args="(yaml_emitter_t *emitter, yaml_event_t *event)" -->
+<div class="memitem">
+<div class="memproto">
+ <table class="memname">
+ <tr>
+ <td class="memname">int yaml_emitter_emit </td>
+ <td>(</td>
+ <td class="paramtype"><a class="el" href="structyaml__emitter__s.html">yaml_emitter_t</a> *&nbsp;</td>
+ <td class="paramname"> <em>emitter</em>, </td>
+ </tr>
+ <tr>
+ <td class="paramkey"></td>
+ <td></td>
+ <td class="paramtype"><a class="el" href="structyaml__event__s.html">yaml_event_t</a> *&nbsp;</td>
+ <td class="paramname"> <em>event</em></td><td>&nbsp;</td>
+ </tr>
+ <tr>
+ <td></td>
+ <td>)</td>
+ <td></td><td></td><td></td>
+ </tr>
+ </table>
+</div>
+<div class="memdoc">
+
+<p>Emit an event. </p>
+<p>The event object may be generated using the <a class="el" href="group__parser.html#ga559312fb137533d8b7e07f224fe0ec8f" title="Parse the input stream and produce the next parsing event.">yaml_parser_parse()</a> function. The emitter takes the responsibility for the event object and destroys its content after it is emitted. The event object is destroyed even if the function fails.</p>
+<dl><dt><b>Parameters:</b></dt><dd>
+ <table border="0" cellspacing="2" cellpadding="0">
+ <tr><td valign="top"><tt>[in,out]</tt>&nbsp;</td><td valign="top"><em>emitter</em>&nbsp;</td><td>An emitter object. </td></tr>
+ <tr><td valign="top"><tt>[in,out]</tt>&nbsp;</td><td valign="top"><em>event</em>&nbsp;</td><td>An event object.</td></tr>
+ </table>
+ </dd>
+</dl>
+<dl class="return"><dt><b>Returns:</b></dt><dd><code>1</code> if the function succeeded, <code>0</code> on error. </dd></dl>
+
+</div>
+</div>
+<a class="anchor" id="gae323c34e378040106f24c7b5ab834b16"></a><!-- doxytag: member="yaml.h::yaml_emitter_open" ref="gae323c34e378040106f24c7b5ab834b16" args="(yaml_emitter_t *emitter)" -->
+<div class="memitem">
+<div class="memproto">
+ <table class="memname">
+ <tr>
+ <td class="memname">int yaml_emitter_open </td>
+ <td>(</td>
+ <td class="paramtype"><a class="el" href="structyaml__emitter__s.html">yaml_emitter_t</a> *&nbsp;</td>
+ <td class="paramname"> <em>emitter</em></td>
+ <td>&nbsp;)&nbsp;</td>
+ <td></td>
+ </tr>
+ </table>
+</div>
+<div class="memdoc">
+
+<p>Start a YAML stream. </p>
+<p>This function should be used before <a class="el" href="group__emitter.html#ga5f0306abe9bff373b5bc339913b3769c" title="Emit a YAML document.">yaml_emitter_dump()</a> is called.</p>
+<dl><dt><b>Parameters:</b></dt><dd>
+ <table border="0" cellspacing="2" cellpadding="0">
+ <tr><td valign="top"><tt>[in,out]</tt>&nbsp;</td><td valign="top"><em>emitter</em>&nbsp;</td><td>An emitter object.</td></tr>
+ </table>
+ </dd>
+</dl>
+<dl class="return"><dt><b>Returns:</b></dt><dd><code>1</code> if the function succeeded, <code>0</code> on error. </dd></dl>
+
+</div>
+</div>
+<a class="anchor" id="gaa91442864679280985df14b2d96b8c42"></a><!-- doxytag: member="yaml.h::yaml_emitter_close" ref="gaa91442864679280985df14b2d96b8c42" args="(yaml_emitter_t *emitter)" -->
+<div class="memitem">
+<div class="memproto">
+ <table class="memname">
+ <tr>
+ <td class="memname">int yaml_emitter_close </td>
+ <td>(</td>
+ <td class="paramtype"><a class="el" href="structyaml__emitter__s.html">yaml_emitter_t</a> *&nbsp;</td>
+ <td class="paramname"> <em>emitter</em></td>
+ <td>&nbsp;)&nbsp;</td>
+ <td></td>
+ </tr>
+ </table>
+</div>
+<div class="memdoc">
+
+<p>Finish a YAML stream. </p>
+<p>This function should be used after <a class="el" href="group__emitter.html#ga5f0306abe9bff373b5bc339913b3769c" title="Emit a YAML document.">yaml_emitter_dump()</a> is called.</p>
+<dl><dt><b>Parameters:</b></dt><dd>
+ <table border="0" cellspacing="2" cellpadding="0">
+ <tr><td valign="top"><tt>[in,out]</tt>&nbsp;</td><td valign="top"><em>emitter</em>&nbsp;</td><td>An emitter object.</td></tr>
+ </table>
+ </dd>
+</dl>
+<dl class="return"><dt><b>Returns:</b></dt><dd><code>1</code> if the function succeeded, <code>0</code> on error. </dd></dl>
+
+</div>
+</div>
+<a class="anchor" id="ga5f0306abe9bff373b5bc339913b3769c"></a><!-- doxytag: member="yaml.h::yaml_emitter_dump" ref="ga5f0306abe9bff373b5bc339913b3769c" args="(yaml_emitter_t *emitter, yaml_document_t *document)" -->
+<div class="memitem">
+<div class="memproto">
+ <table class="memname">
+ <tr>
+ <td class="memname">int yaml_emitter_dump </td>
+ <td>(</td>
+ <td class="paramtype"><a class="el" href="structyaml__emitter__s.html">yaml_emitter_t</a> *&nbsp;</td>
+ <td class="paramname"> <em>emitter</em>, </td>
+ </tr>
+ <tr>
+ <td class="paramkey"></td>
+ <td></td>
+ <td class="paramtype"><a class="el" href="structyaml__document__s.html">yaml_document_t</a> *&nbsp;</td>
+ <td class="paramname"> <em>document</em></td><td>&nbsp;</td>
+ </tr>
+ <tr>
+ <td></td>
+ <td>)</td>
+ <td></td><td></td><td></td>
+ </tr>
+ </table>
+</div>
+<div class="memdoc">
+
+<p>Emit a YAML document. </p>
+<p>The documen object may be generated using the <a class="el" href="group__parser.html#ga9ef7d6e9494766b5880c389bc431d138" title="Parse the input stream and produce the next YAML document.">yaml_parser_load()</a> function or the <a class="el" href="group__nodes.html#ga62a485c96f3b7962436a0da5e6f3cc89" title="Create a YAML document.">yaml_document_initialize()</a> function. The emitter takes the responsibility for the document object and destoys its content after it is emitted. The document object is destroyedeven if the function fails.</p>
+<dl><dt><b>Parameters:</b></dt><dd>
+ <table border="0" cellspacing="2" cellpadding="0">
+ <tr><td valign="top"><tt>[in,out]</tt>&nbsp;</td><td valign="top"><em>emitter</em>&nbsp;</td><td>An emitter object. </td></tr>
+ <tr><td valign="top"><tt>[in,out]</tt>&nbsp;</td><td valign="top"><em>document</em>&nbsp;</td><td>A document object.</td></tr>
+ </table>
+ </dd>
+</dl>
+<dl class="return"><dt><b>Returns:</b></dt><dd><code>1</code> if the function succeeded, <code>0</code> on error. </dd></dl>
+
+</div>
+</div>
+<a class="anchor" id="gacaf24456e2bf85bc5654cbd7d828055f"></a><!-- doxytag: member="yaml.h::yaml_emitter_flush" ref="gacaf24456e2bf85bc5654cbd7d828055f" args="(yaml_emitter_t *emitter)" -->
+<div class="memitem">
+<div class="memproto">
+ <table class="memname">
+ <tr>
+ <td class="memname">int yaml_emitter_flush </td>
+ <td>(</td>
+ <td class="paramtype"><a class="el" href="structyaml__emitter__s.html">yaml_emitter_t</a> *&nbsp;</td>
+ <td class="paramname"> <em>emitter</em></td>
+ <td>&nbsp;)&nbsp;</td>
+ <td></td>
+ </tr>
+ </table>
+</div>
+<div class="memdoc">
+
+<p>Flush the accumulated characters to the output. </p>
+<dl><dt><b>Parameters:</b></dt><dd>
+ <table border="0" cellspacing="2" cellpadding="0">
+ <tr><td valign="top"><tt>[in,out]</tt>&nbsp;</td><td valign="top"><em>emitter</em>&nbsp;</td><td>An emitter object.</td></tr>
+ </table>
+ </dd>
+</dl>
+<dl class="return"><dt><b>Returns:</b></dt><dd><code>1</code> if the function succeeded, <code>0</code> on error. </dd></dl>
+
+</div>
+</div>
+</div>
+<hr class="footer"/><address class="footer"><small>Generated on Mon May 30 2011 22:00:00 for yaml by&nbsp;
+<a href="http://www.doxygen.org/index.html">
+<img class="footer" src="doxygen.png" alt="doxygen"/></a> 1.7.1 </small></address>
+</body>
+</html>
diff --git a/contrib/libyaml/doc/html/group__events.html b/contrib/libyaml/doc/html/group__events.html
new file mode 100644
index 0000000..43e81b3
--- /dev/null
+++ b/contrib/libyaml/doc/html/group__events.html
@@ -0,0 +1,664 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head>
+<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/>
+<title>yaml: Events</title>
+<link href="tabs.css" rel="stylesheet" type="text/css"/>
+<link href="doxygen.css" rel="stylesheet" type="text/css"/>
+</head>
+<body>
+<!-- Generated by Doxygen 1.7.1 -->
+<div class="navigation" id="top">
+ <div class="tabs">
+ <ul class="tablist">
+ <li><a href="index.html"><span>Main&nbsp;Page</span></a></li>
+ <li><a href="modules.html"><span>Modules</span></a></li>
+ <li><a href="annotated.html"><span>Data&nbsp;Structures</span></a></li>
+ <li><a href="files.html"><span>Files</span></a></li>
+ </ul>
+ </div>
+</div>
+<div class="header">
+ <div class="summary">
+<a href="#nested-classes">Data Structures</a> &#124;
+<a href="#typedef-members">Typedefs</a> &#124;
+<a href="#enum-members">Enumerations</a> &#124;
+<a href="#func-members">Functions</a> </div>
+ <div class="headertitle">
+<h1>Events</h1> </div>
+</div>
+<div class="contents">
+<table class="memberdecls">
+<tr><td colspan="2"><h2><a name="nested-classes"></a>
+Data Structures</h2></td></tr>
+<tr><td class="memItemLeft" align="right" valign="top">struct &nbsp;</td><td class="memItemRight" valign="bottom"><a class="el" href="structyaml__event__s.html">yaml_event_s</a></td></tr>
+<tr><td class="mdescLeft">&nbsp;</td><td class="mdescRight">The event structure. <a href="structyaml__event__s.html#_details">More...</a><br/></td></tr>
+<tr><td colspan="2"><h2><a name="typedef-members"></a>
+Typedefs</h2></td></tr>
+<tr><td class="memItemLeft" align="right" valign="top">typedef enum <a class="el" href="group__events.html#ga454fccebae859c188fe3e7fa3299577c">yaml_event_type_e</a>&nbsp;</td><td class="memItemRight" valign="bottom"><a class="el" href="group__events.html#ga8934661be36bd7c9d17a8af69eff89a1">yaml_event_type_t</a></td></tr>
+<tr><td class="mdescLeft">&nbsp;</td><td class="mdescRight">Event types. <a href="#ga8934661be36bd7c9d17a8af69eff89a1"></a><br/></td></tr>
+<tr><td class="memItemLeft" align="right" valign="top">typedef struct <a class="el" href="structyaml__event__s.html">yaml_event_s</a>&nbsp;</td><td class="memItemRight" valign="bottom"><a class="el" href="group__events.html#ga3b392d9716c4920cabefdd29e78dd542">yaml_event_t</a></td></tr>
+<tr><td class="mdescLeft">&nbsp;</td><td class="mdescRight">The event structure. <a href="#ga3b392d9716c4920cabefdd29e78dd542"></a><br/></td></tr>
+<tr><td colspan="2"><h2><a name="enum-members"></a>
+Enumerations</h2></td></tr>
+<tr><td class="memItemLeft" align="right" valign="top">enum &nbsp;</td><td class="memItemRight" valign="bottom"><a class="el" href="group__events.html#ga454fccebae859c188fe3e7fa3299577c">yaml_event_type_e</a> { <br/>
+&nbsp;&nbsp;<a class="el" href="group__events.html#gga454fccebae859c188fe3e7fa3299577caefda9f31823fe534f094f4241d5e5eac">YAML_NO_EVENT</a>,
+<br/>
+&nbsp;&nbsp;<a class="el" href="group__events.html#gga454fccebae859c188fe3e7fa3299577caa742e9970f14d1fe7ce4d178d79e8465">YAML_STREAM_START_EVENT</a>,
+<br/>
+&nbsp;&nbsp;<a class="el" href="group__events.html#gga454fccebae859c188fe3e7fa3299577ca4a5e76ed540645102a13352af2503d3b">YAML_STREAM_END_EVENT</a>,
+<br/>
+&nbsp;&nbsp;<a class="el" href="group__events.html#gga454fccebae859c188fe3e7fa3299577caf4ca2b0f538029cf054cdebd09d3d6d3">YAML_DOCUMENT_START_EVENT</a>,
+<br/>
+&nbsp;&nbsp;<a class="el" href="group__events.html#gga454fccebae859c188fe3e7fa3299577ca355ec471f963827c96512e529676276f">YAML_DOCUMENT_END_EVENT</a>,
+<br/>
+&nbsp;&nbsp;<a class="el" href="group__events.html#gga454fccebae859c188fe3e7fa3299577ca8c3ce47705cfbd49a87a32bdbe544eb7">YAML_ALIAS_EVENT</a>,
+<br/>
+&nbsp;&nbsp;<a class="el" href="group__events.html#gga454fccebae859c188fe3e7fa3299577ca8b16dc795bb228e33d647d1bdf683713">YAML_SCALAR_EVENT</a>,
+<br/>
+&nbsp;&nbsp;<a class="el" href="group__events.html#gga454fccebae859c188fe3e7fa3299577cad90ccd43e238221f542defa3c8eaf093">YAML_SEQUENCE_START_EVENT</a>,
+<br/>
+&nbsp;&nbsp;<a class="el" href="group__events.html#gga454fccebae859c188fe3e7fa3299577ca2a8af98529275987d73eb307b6a92898">YAML_SEQUENCE_END_EVENT</a>,
+<br/>
+&nbsp;&nbsp;<a class="el" href="group__events.html#gga454fccebae859c188fe3e7fa3299577ca0f6982f6d1c325ee71af518c2c66dae8">YAML_MAPPING_START_EVENT</a>,
+<br/>
+&nbsp;&nbsp;<a class="el" href="group__events.html#gga454fccebae859c188fe3e7fa3299577cadc3dc55f17056a657005fecfb80fbd30">YAML_MAPPING_END_EVENT</a>
+<br/>
+ }</td></tr>
+<tr><td class="mdescLeft">&nbsp;</td><td class="mdescRight"><p>Event types. </p>
+ <a href="group__events.html#ga454fccebae859c188fe3e7fa3299577c">More...</a><br/></td></tr>
+<tr><td colspan="2"><h2><a name="func-members"></a>
+Functions</h2></td></tr>
+<tr><td class="memItemLeft" align="right" valign="top">int&nbsp;</td><td class="memItemRight" valign="bottom"><a class="el" href="group__events.html#ga0650d255b23d9aae13c839f4ab3ec2ab">yaml_stream_start_event_initialize</a> (<a class="el" href="structyaml__event__s.html">yaml_event_t</a> *event, <a class="el" href="group__basic.html#ga2170996d7e636397b5e6bc0c1b7df7c6">yaml_encoding_t</a> encoding)</td></tr>
+<tr><td class="mdescLeft">&nbsp;</td><td class="mdescRight">Create the STREAM-START event. <a href="#ga0650d255b23d9aae13c839f4ab3ec2ab"></a><br/></td></tr>
+<tr><td class="memItemLeft" align="right" valign="top">int&nbsp;</td><td class="memItemRight" valign="bottom"><a class="el" href="group__events.html#ga84cf0c3ff01251c852c71624e64df9fe">yaml_stream_end_event_initialize</a> (<a class="el" href="structyaml__event__s.html">yaml_event_t</a> *event)</td></tr>
+<tr><td class="mdescLeft">&nbsp;</td><td class="mdescRight">Create the STREAM-END event. <a href="#ga84cf0c3ff01251c852c71624e64df9fe"></a><br/></td></tr>
+<tr><td class="memItemLeft" align="right" valign="top">int&nbsp;</td><td class="memItemRight" valign="bottom"><a class="el" href="group__events.html#ga527e89302e1c969fbea5aa45664bf51c">yaml_document_start_event_initialize</a> (<a class="el" href="structyaml__event__s.html">yaml_event_t</a> *event, <a class="el" href="structyaml__version__directive__s.html">yaml_version_directive_t</a> *version_directive, <a class="el" href="structyaml__tag__directive__s.html">yaml_tag_directive_t</a> *tag_directives_start, <a class="el" href="structyaml__tag__directive__s.html">yaml_tag_directive_t</a> *tag_directives_end, int implicit)</td></tr>
+<tr><td class="mdescLeft">&nbsp;</td><td class="mdescRight">Create the DOCUMENT-START event. <a href="#ga527e89302e1c969fbea5aa45664bf51c"></a><br/></td></tr>
+<tr><td class="memItemLeft" align="right" valign="top">int&nbsp;</td><td class="memItemRight" valign="bottom"><a class="el" href="group__events.html#ga8bae16548ee88f8a5ca15204f8c30344">yaml_document_end_event_initialize</a> (<a class="el" href="structyaml__event__s.html">yaml_event_t</a> *event, int implicit)</td></tr>
+<tr><td class="mdescLeft">&nbsp;</td><td class="mdescRight">Create the DOCUMENT-END event. <a href="#ga8bae16548ee88f8a5ca15204f8c30344"></a><br/></td></tr>
+<tr><td class="memItemLeft" align="right" valign="top">int&nbsp;</td><td class="memItemRight" valign="bottom"><a class="el" href="group__events.html#gade4c15b75eb9a8035e04d4f0dd23f005">yaml_alias_event_initialize</a> (<a class="el" href="structyaml__event__s.html">yaml_event_t</a> *event, <a class="el" href="group__basic.html#gaf8657e81f0b8b05d1a081001fc6cb8bd">yaml_char_t</a> *anchor)</td></tr>
+<tr><td class="mdescLeft">&nbsp;</td><td class="mdescRight">Create an ALIAS event. <a href="#gade4c15b75eb9a8035e04d4f0dd23f005"></a><br/></td></tr>
+<tr><td class="memItemLeft" align="right" valign="top">int&nbsp;</td><td class="memItemRight" valign="bottom"><a class="el" href="group__events.html#gafc60a1a437385e19e6fb3be075958c8c">yaml_scalar_event_initialize</a> (<a class="el" href="structyaml__event__s.html">yaml_event_t</a> *event, <a class="el" href="group__basic.html#gaf8657e81f0b8b05d1a081001fc6cb8bd">yaml_char_t</a> *anchor, <a class="el" href="group__basic.html#gaf8657e81f0b8b05d1a081001fc6cb8bd">yaml_char_t</a> *tag, <a class="el" href="group__basic.html#gaf8657e81f0b8b05d1a081001fc6cb8bd">yaml_char_t</a> *value, int length, int plain_implicit, int quoted_implicit, <a class="el" href="group__styles.html#ga3fa6405631e1afe5bd5c488a6c5e8065">yaml_scalar_style_t</a> style)</td></tr>
+<tr><td class="mdescLeft">&nbsp;</td><td class="mdescRight">Create a SCALAR event. <a href="#gafc60a1a437385e19e6fb3be075958c8c"></a><br/></td></tr>
+<tr><td class="memItemLeft" align="right" valign="top">int&nbsp;</td><td class="memItemRight" valign="bottom"><a class="el" href="group__events.html#ga53aea428c768d7b131923d08c904b4eb">yaml_sequence_start_event_initialize</a> (<a class="el" href="structyaml__event__s.html">yaml_event_t</a> *event, <a class="el" href="group__basic.html#gaf8657e81f0b8b05d1a081001fc6cb8bd">yaml_char_t</a> *anchor, <a class="el" href="group__basic.html#gaf8657e81f0b8b05d1a081001fc6cb8bd">yaml_char_t</a> *tag, int implicit, <a class="el" href="group__styles.html#ga58a1123d271e56c72de6abf852ac4dc2">yaml_sequence_style_t</a> style)</td></tr>
+<tr><td class="mdescLeft">&nbsp;</td><td class="mdescRight">Create a SEQUENCE-START event. <a href="#ga53aea428c768d7b131923d08c904b4eb"></a><br/></td></tr>
+<tr><td class="memItemLeft" align="right" valign="top">int&nbsp;</td><td class="memItemRight" valign="bottom"><a class="el" href="group__events.html#ga99fdfa4b9d42b64d8171c9b22f334b1c">yaml_sequence_end_event_initialize</a> (<a class="el" href="structyaml__event__s.html">yaml_event_t</a> *event)</td></tr>
+<tr><td class="mdescLeft">&nbsp;</td><td class="mdescRight">Create a SEQUENCE-END event. <a href="#ga99fdfa4b9d42b64d8171c9b22f334b1c"></a><br/></td></tr>
+<tr><td class="memItemLeft" align="right" valign="top">int&nbsp;</td><td class="memItemRight" valign="bottom"><a class="el" href="group__events.html#ga0603cf8d20f0b6dfc3be04b6360134aa">yaml_mapping_start_event_initialize</a> (<a class="el" href="structyaml__event__s.html">yaml_event_t</a> *event, <a class="el" href="group__basic.html#gaf8657e81f0b8b05d1a081001fc6cb8bd">yaml_char_t</a> *anchor, <a class="el" href="group__basic.html#gaf8657e81f0b8b05d1a081001fc6cb8bd">yaml_char_t</a> *tag, int implicit, <a class="el" href="group__styles.html#gab47523846a5c5960e07367a28ea9750a">yaml_mapping_style_t</a> style)</td></tr>
+<tr><td class="mdescLeft">&nbsp;</td><td class="mdescRight">Create a MAPPING-START event. <a href="#ga0603cf8d20f0b6dfc3be04b6360134aa"></a><br/></td></tr>
+<tr><td class="memItemLeft" align="right" valign="top">int&nbsp;</td><td class="memItemRight" valign="bottom"><a class="el" href="group__events.html#ga3afaf8b3aca2ec902a4e268f12adb0c2">yaml_mapping_end_event_initialize</a> (<a class="el" href="structyaml__event__s.html">yaml_event_t</a> *event)</td></tr>
+<tr><td class="mdescLeft">&nbsp;</td><td class="mdescRight">Create a MAPPING-END event. <a href="#ga3afaf8b3aca2ec902a4e268f12adb0c2"></a><br/></td></tr>
+<tr><td class="memItemLeft" align="right" valign="top">void&nbsp;</td><td class="memItemRight" valign="bottom"><a class="el" href="group__events.html#ga5330d62ef52856aa53188137cb93a6a1">yaml_event_delete</a> (<a class="el" href="structyaml__event__s.html">yaml_event_t</a> *event)</td></tr>
+<tr><td class="mdescLeft">&nbsp;</td><td class="mdescRight">Free any memory allocated for an event object. <a href="#ga5330d62ef52856aa53188137cb93a6a1"></a><br/></td></tr>
+</table>
+<hr/><h2>Typedef Documentation</h2>
+<a class="anchor" id="ga8934661be36bd7c9d17a8af69eff89a1"></a><!-- doxytag: member="yaml.h::yaml_event_type_t" ref="ga8934661be36bd7c9d17a8af69eff89a1" args="" -->
+<div class="memitem">
+<div class="memproto">
+ <table class="memname">
+ <tr>
+ <td class="memname">typedef enum <a class="el" href="group__events.html#ga454fccebae859c188fe3e7fa3299577c">yaml_event_type_e</a> <a class="el" href="group__events.html#ga8934661be36bd7c9d17a8af69eff89a1">yaml_event_type_t</a></td>
+ </tr>
+ </table>
+</div>
+<div class="memdoc">
+
+<p>Event types. </p>
+
+</div>
+</div>
+<a class="anchor" id="ga3b392d9716c4920cabefdd29e78dd542"></a><!-- doxytag: member="yaml.h::yaml_event_t" ref="ga3b392d9716c4920cabefdd29e78dd542" args="" -->
+<div class="memitem">
+<div class="memproto">
+ <table class="memname">
+ <tr>
+ <td class="memname">typedef struct <a class="el" href="structyaml__event__s.html">yaml_event_s</a> <a class="el" href="structyaml__event__s.html">yaml_event_t</a></td>
+ </tr>
+ </table>
+</div>
+<div class="memdoc">
+
+<p>The event structure. </p>
+
+</div>
+</div>
+<hr/><h2>Enumeration Type Documentation</h2>
+<a class="anchor" id="ga454fccebae859c188fe3e7fa3299577c"></a><!-- doxytag: member="yaml.h::yaml_event_type_e" ref="ga454fccebae859c188fe3e7fa3299577c" args="" -->
+<div class="memitem">
+<div class="memproto">
+ <table class="memname">
+ <tr>
+ <td class="memname">enum <a class="el" href="group__events.html#ga454fccebae859c188fe3e7fa3299577c">yaml_event_type_e</a></td>
+ </tr>
+ </table>
+</div>
+<div class="memdoc">
+
+<p>Event types. </p>
+<dl><dt><b>Enumerator: </b></dt><dd><table border="0" cellspacing="2" cellpadding="0">
+<tr><td valign="top"><em><a class="anchor" id="gga454fccebae859c188fe3e7fa3299577caefda9f31823fe534f094f4241d5e5eac"></a><!-- doxytag: member="YAML_NO_EVENT" ref="gga454fccebae859c188fe3e7fa3299577caefda9f31823fe534f094f4241d5e5eac" args="" -->YAML_NO_EVENT</em>&nbsp;</td><td>
+<p>An empty event. </p>
+</td></tr>
+<tr><td valign="top"><em><a class="anchor" id="gga454fccebae859c188fe3e7fa3299577caa742e9970f14d1fe7ce4d178d79e8465"></a><!-- doxytag: member="YAML_STREAM_START_EVENT" ref="gga454fccebae859c188fe3e7fa3299577caa742e9970f14d1fe7ce4d178d79e8465" args="" -->YAML_STREAM_START_EVENT</em>&nbsp;</td><td>
+<p>A STREAM-START event. </p>
+</td></tr>
+<tr><td valign="top"><em><a class="anchor" id="gga454fccebae859c188fe3e7fa3299577ca4a5e76ed540645102a13352af2503d3b"></a><!-- doxytag: member="YAML_STREAM_END_EVENT" ref="gga454fccebae859c188fe3e7fa3299577ca4a5e76ed540645102a13352af2503d3b" args="" -->YAML_STREAM_END_EVENT</em>&nbsp;</td><td>
+<p>A STREAM-END event. </p>
+</td></tr>
+<tr><td valign="top"><em><a class="anchor" id="gga454fccebae859c188fe3e7fa3299577caf4ca2b0f538029cf054cdebd09d3d6d3"></a><!-- doxytag: member="YAML_DOCUMENT_START_EVENT" ref="gga454fccebae859c188fe3e7fa3299577caf4ca2b0f538029cf054cdebd09d3d6d3" args="" -->YAML_DOCUMENT_START_EVENT</em>&nbsp;</td><td>
+<p>A DOCUMENT-START event. </p>
+</td></tr>
+<tr><td valign="top"><em><a class="anchor" id="gga454fccebae859c188fe3e7fa3299577ca355ec471f963827c96512e529676276f"></a><!-- doxytag: member="YAML_DOCUMENT_END_EVENT" ref="gga454fccebae859c188fe3e7fa3299577ca355ec471f963827c96512e529676276f" args="" -->YAML_DOCUMENT_END_EVENT</em>&nbsp;</td><td>
+<p>A DOCUMENT-END event. </p>
+</td></tr>
+<tr><td valign="top"><em><a class="anchor" id="gga454fccebae859c188fe3e7fa3299577ca8c3ce47705cfbd49a87a32bdbe544eb7"></a><!-- doxytag: member="YAML_ALIAS_EVENT" ref="gga454fccebae859c188fe3e7fa3299577ca8c3ce47705cfbd49a87a32bdbe544eb7" args="" -->YAML_ALIAS_EVENT</em>&nbsp;</td><td>
+<p>An ALIAS event. </p>
+</td></tr>
+<tr><td valign="top"><em><a class="anchor" id="gga454fccebae859c188fe3e7fa3299577ca8b16dc795bb228e33d647d1bdf683713"></a><!-- doxytag: member="YAML_SCALAR_EVENT" ref="gga454fccebae859c188fe3e7fa3299577ca8b16dc795bb228e33d647d1bdf683713" args="" -->YAML_SCALAR_EVENT</em>&nbsp;</td><td>
+<p>A SCALAR event. </p>
+</td></tr>
+<tr><td valign="top"><em><a class="anchor" id="gga454fccebae859c188fe3e7fa3299577cad90ccd43e238221f542defa3c8eaf093"></a><!-- doxytag: member="YAML_SEQUENCE_START_EVENT" ref="gga454fccebae859c188fe3e7fa3299577cad90ccd43e238221f542defa3c8eaf093" args="" -->YAML_SEQUENCE_START_EVENT</em>&nbsp;</td><td>
+<p>A SEQUENCE-START event. </p>
+</td></tr>
+<tr><td valign="top"><em><a class="anchor" id="gga454fccebae859c188fe3e7fa3299577ca2a8af98529275987d73eb307b6a92898"></a><!-- doxytag: member="YAML_SEQUENCE_END_EVENT" ref="gga454fccebae859c188fe3e7fa3299577ca2a8af98529275987d73eb307b6a92898" args="" -->YAML_SEQUENCE_END_EVENT</em>&nbsp;</td><td>
+<p>A SEQUENCE-END event. </p>
+</td></tr>
+<tr><td valign="top"><em><a class="anchor" id="gga454fccebae859c188fe3e7fa3299577ca0f6982f6d1c325ee71af518c2c66dae8"></a><!-- doxytag: member="YAML_MAPPING_START_EVENT" ref="gga454fccebae859c188fe3e7fa3299577ca0f6982f6d1c325ee71af518c2c66dae8" args="" -->YAML_MAPPING_START_EVENT</em>&nbsp;</td><td>
+<p>A MAPPING-START event. </p>
+</td></tr>
+<tr><td valign="top"><em><a class="anchor" id="gga454fccebae859c188fe3e7fa3299577cadc3dc55f17056a657005fecfb80fbd30"></a><!-- doxytag: member="YAML_MAPPING_END_EVENT" ref="gga454fccebae859c188fe3e7fa3299577cadc3dc55f17056a657005fecfb80fbd30" args="" -->YAML_MAPPING_END_EVENT</em>&nbsp;</td><td>
+<p>A MAPPING-END event. </p>
+</td></tr>
+</table>
+</dd>
+</dl>
+
+</div>
+</div>
+<hr/><h2>Function Documentation</h2>
+<a class="anchor" id="ga0650d255b23d9aae13c839f4ab3ec2ab"></a><!-- doxytag: member="yaml.h::yaml_stream_start_event_initialize" ref="ga0650d255b23d9aae13c839f4ab3ec2ab" args="(yaml_event_t *event, yaml_encoding_t encoding)" -->
+<div class="memitem">
+<div class="memproto">
+ <table class="memname">
+ <tr>
+ <td class="memname">int yaml_stream_start_event_initialize </td>
+ <td>(</td>
+ <td class="paramtype"><a class="el" href="structyaml__event__s.html">yaml_event_t</a> *&nbsp;</td>
+ <td class="paramname"> <em>event</em>, </td>
+ </tr>
+ <tr>
+ <td class="paramkey"></td>
+ <td></td>
+ <td class="paramtype"><a class="el" href="group__basic.html#ga2170996d7e636397b5e6bc0c1b7df7c6">yaml_encoding_t</a>&nbsp;</td>
+ <td class="paramname"> <em>encoding</em></td><td>&nbsp;</td>
+ </tr>
+ <tr>
+ <td></td>
+ <td>)</td>
+ <td></td><td></td><td></td>
+ </tr>
+ </table>
+</div>
+<div class="memdoc">
+
+<p>Create the STREAM-START event. </p>
+<dl><dt><b>Parameters:</b></dt><dd>
+ <table border="0" cellspacing="2" cellpadding="0">
+ <tr><td valign="top"><tt>[out]</tt>&nbsp;</td><td valign="top"><em>event</em>&nbsp;</td><td>An empty event object. </td></tr>
+ <tr><td valign="top"><tt>[in]</tt>&nbsp;</td><td valign="top"><em>encoding</em>&nbsp;</td><td>The stream encoding.</td></tr>
+ </table>
+ </dd>
+</dl>
+<dl class="return"><dt><b>Returns:</b></dt><dd><code>1</code> if the function succeeded, <code>0</code> on error. </dd></dl>
+
+</div>
+</div>
+<a class="anchor" id="ga84cf0c3ff01251c852c71624e64df9fe"></a><!-- doxytag: member="yaml.h::yaml_stream_end_event_initialize" ref="ga84cf0c3ff01251c852c71624e64df9fe" args="(yaml_event_t *event)" -->
+<div class="memitem">
+<div class="memproto">
+ <table class="memname">
+ <tr>
+ <td class="memname">int yaml_stream_end_event_initialize </td>
+ <td>(</td>
+ <td class="paramtype"><a class="el" href="structyaml__event__s.html">yaml_event_t</a> *&nbsp;</td>
+ <td class="paramname"> <em>event</em></td>
+ <td>&nbsp;)&nbsp;</td>
+ <td></td>
+ </tr>
+ </table>
+</div>
+<div class="memdoc">
+
+<p>Create the STREAM-END event. </p>
+<dl><dt><b>Parameters:</b></dt><dd>
+ <table border="0" cellspacing="2" cellpadding="0">
+ <tr><td valign="top"><tt>[out]</tt>&nbsp;</td><td valign="top"><em>event</em>&nbsp;</td><td>An empty event object.</td></tr>
+ </table>
+ </dd>
+</dl>
+<dl class="return"><dt><b>Returns:</b></dt><dd><code>1</code> if the function succeeded, <code>0</code> on error. </dd></dl>
+
+</div>
+</div>
+<a class="anchor" id="ga527e89302e1c969fbea5aa45664bf51c"></a><!-- doxytag: member="yaml.h::yaml_document_start_event_initialize" ref="ga527e89302e1c969fbea5aa45664bf51c" args="(yaml_event_t *event, yaml_version_directive_t *version_directive, yaml_tag_directive_t *tag_directives_start, yaml_tag_directive_t *tag_directives_end, int implicit)" -->
+<div class="memitem">
+<div class="memproto">
+ <table class="memname">
+ <tr>
+ <td class="memname">int yaml_document_start_event_initialize </td>
+ <td>(</td>
+ <td class="paramtype"><a class="el" href="structyaml__event__s.html">yaml_event_t</a> *&nbsp;</td>
+ <td class="paramname"> <em>event</em>, </td>
+ </tr>
+ <tr>
+ <td class="paramkey"></td>
+ <td></td>
+ <td class="paramtype"><a class="el" href="structyaml__version__directive__s.html">yaml_version_directive_t</a> *&nbsp;</td>
+ <td class="paramname"> <em>version_directive</em>, </td>
+ </tr>
+ <tr>
+ <td class="paramkey"></td>
+ <td></td>
+ <td class="paramtype"><a class="el" href="structyaml__tag__directive__s.html">yaml_tag_directive_t</a> *&nbsp;</td>
+ <td class="paramname"> <em>tag_directives_start</em>, </td>
+ </tr>
+ <tr>
+ <td class="paramkey"></td>
+ <td></td>
+ <td class="paramtype"><a class="el" href="structyaml__tag__directive__s.html">yaml_tag_directive_t</a> *&nbsp;</td>
+ <td class="paramname"> <em>tag_directives_end</em>, </td>
+ </tr>
+ <tr>
+ <td class="paramkey"></td>
+ <td></td>
+ <td class="paramtype">int&nbsp;</td>
+ <td class="paramname"> <em>implicit</em></td><td>&nbsp;</td>
+ </tr>
+ <tr>
+ <td></td>
+ <td>)</td>
+ <td></td><td></td><td></td>
+ </tr>
+ </table>
+</div>
+<div class="memdoc">
+
+<p>Create the DOCUMENT-START event. </p>
+<p>The <em>implicit</em> argument is considered as a stylistic parameter and may be ignored by the emitter.</p>
+<dl><dt><b>Parameters:</b></dt><dd>
+ <table border="0" cellspacing="2" cellpadding="0">
+ <tr><td valign="top"><tt>[out]</tt>&nbsp;</td><td valign="top"><em>event</em>&nbsp;</td><td>An empty event object. </td></tr>
+ <tr><td valign="top"><tt>[in]</tt>&nbsp;</td><td valign="top"><em>version_directive</em>&nbsp;</td><td>The YAML directive value or <code>NULL</code>. </td></tr>
+ <tr><td valign="top"><tt>[in]</tt>&nbsp;</td><td valign="top"><em>tag_directives_start</em>&nbsp;</td><td>The beginning of the TAG directives list. </td></tr>
+ <tr><td valign="top"><tt>[in]</tt>&nbsp;</td><td valign="top"><em>tag_directives_end</em>&nbsp;</td><td>The end of the TAG directives list. </td></tr>
+ <tr><td valign="top"><tt>[in]</tt>&nbsp;</td><td valign="top"><em>implicit</em>&nbsp;</td><td>If the document start indicator is implicit.</td></tr>
+ </table>
+ </dd>
+</dl>
+<dl class="return"><dt><b>Returns:</b></dt><dd><code>1</code> if the function succeeded, <code>0</code> on error. </dd></dl>
+
+</div>
+</div>
+<a class="anchor" id="ga8bae16548ee88f8a5ca15204f8c30344"></a><!-- doxytag: member="yaml.h::yaml_document_end_event_initialize" ref="ga8bae16548ee88f8a5ca15204f8c30344" args="(yaml_event_t *event, int implicit)" -->
+<div class="memitem">
+<div class="memproto">
+ <table class="memname">
+ <tr>
+ <td class="memname">int yaml_document_end_event_initialize </td>
+ <td>(</td>
+ <td class="paramtype"><a class="el" href="structyaml__event__s.html">yaml_event_t</a> *&nbsp;</td>
+ <td class="paramname"> <em>event</em>, </td>
+ </tr>
+ <tr>
+ <td class="paramkey"></td>
+ <td></td>
+ <td class="paramtype">int&nbsp;</td>
+ <td class="paramname"> <em>implicit</em></td><td>&nbsp;</td>
+ </tr>
+ <tr>
+ <td></td>
+ <td>)</td>
+ <td></td><td></td><td></td>
+ </tr>
+ </table>
+</div>
+<div class="memdoc">
+
+<p>Create the DOCUMENT-END event. </p>
+<p>The <em>implicit</em> argument is considered as a stylistic parameter and may be ignored by the emitter.</p>
+<dl><dt><b>Parameters:</b></dt><dd>
+ <table border="0" cellspacing="2" cellpadding="0">
+ <tr><td valign="top"><tt>[out]</tt>&nbsp;</td><td valign="top"><em>event</em>&nbsp;</td><td>An empty event object. </td></tr>
+ <tr><td valign="top"><tt>[in]</tt>&nbsp;</td><td valign="top"><em>implicit</em>&nbsp;</td><td>If the document end indicator is implicit.</td></tr>
+ </table>
+ </dd>
+</dl>
+<dl class="return"><dt><b>Returns:</b></dt><dd><code>1</code> if the function succeeded, <code>0</code> on error. </dd></dl>
+
+</div>
+</div>
+<a class="anchor" id="gade4c15b75eb9a8035e04d4f0dd23f005"></a><!-- doxytag: member="yaml.h::yaml_alias_event_initialize" ref="gade4c15b75eb9a8035e04d4f0dd23f005" args="(yaml_event_t *event, yaml_char_t *anchor)" -->
+<div class="memitem">
+<div class="memproto">
+ <table class="memname">
+ <tr>
+ <td class="memname">int yaml_alias_event_initialize </td>
+ <td>(</td>
+ <td class="paramtype"><a class="el" href="structyaml__event__s.html">yaml_event_t</a> *&nbsp;</td>
+ <td class="paramname"> <em>event</em>, </td>
+ </tr>
+ <tr>
+ <td class="paramkey"></td>
+ <td></td>
+ <td class="paramtype"><a class="el" href="group__basic.html#gaf8657e81f0b8b05d1a081001fc6cb8bd">yaml_char_t</a> *&nbsp;</td>
+ <td class="paramname"> <em>anchor</em></td><td>&nbsp;</td>
+ </tr>
+ <tr>
+ <td></td>
+ <td>)</td>
+ <td></td><td></td><td></td>
+ </tr>
+ </table>
+</div>
+<div class="memdoc">
+
+<p>Create an ALIAS event. </p>
+<dl><dt><b>Parameters:</b></dt><dd>
+ <table border="0" cellspacing="2" cellpadding="0">
+ <tr><td valign="top"><tt>[out]</tt>&nbsp;</td><td valign="top"><em>event</em>&nbsp;</td><td>An empty event object. </td></tr>
+ <tr><td valign="top"><tt>[in]</tt>&nbsp;</td><td valign="top"><em>anchor</em>&nbsp;</td><td>The anchor value.</td></tr>
+ </table>
+ </dd>
+</dl>
+<dl class="return"><dt><b>Returns:</b></dt><dd><code>1</code> if the function succeeded, <code>0</code> on error. </dd></dl>
+
+</div>
+</div>
+<a class="anchor" id="gafc60a1a437385e19e6fb3be075958c8c"></a><!-- doxytag: member="yaml.h::yaml_scalar_event_initialize" ref="gafc60a1a437385e19e6fb3be075958c8c" args="(yaml_event_t *event, yaml_char_t *anchor, yaml_char_t *tag, yaml_char_t *value, int length, int plain_implicit, int quoted_implicit, yaml_scalar_style_t style)" -->
+<div class="memitem">
+<div class="memproto">
+ <table class="memname">
+ <tr>
+ <td class="memname">int yaml_scalar_event_initialize </td>
+ <td>(</td>
+ <td class="paramtype"><a class="el" href="structyaml__event__s.html">yaml_event_t</a> *&nbsp;</td>
+ <td class="paramname"> <em>event</em>, </td>
+ </tr>
+ <tr>
+ <td class="paramkey"></td>
+ <td></td>
+ <td class="paramtype"><a class="el" href="group__basic.html#gaf8657e81f0b8b05d1a081001fc6cb8bd">yaml_char_t</a> *&nbsp;</td>
+ <td class="paramname"> <em>anchor</em>, </td>
+ </tr>
+ <tr>
+ <td class="paramkey"></td>
+ <td></td>
+ <td class="paramtype"><a class="el" href="group__basic.html#gaf8657e81f0b8b05d1a081001fc6cb8bd">yaml_char_t</a> *&nbsp;</td>
+ <td class="paramname"> <em>tag</em>, </td>
+ </tr>
+ <tr>
+ <td class="paramkey"></td>
+ <td></td>
+ <td class="paramtype"><a class="el" href="group__basic.html#gaf8657e81f0b8b05d1a081001fc6cb8bd">yaml_char_t</a> *&nbsp;</td>
+ <td class="paramname"> <em>value</em>, </td>
+ </tr>
+ <tr>
+ <td class="paramkey"></td>
+ <td></td>
+ <td class="paramtype">int&nbsp;</td>
+ <td class="paramname"> <em>length</em>, </td>
+ </tr>
+ <tr>
+ <td class="paramkey"></td>
+ <td></td>
+ <td class="paramtype">int&nbsp;</td>
+ <td class="paramname"> <em>plain_implicit</em>, </td>
+ </tr>
+ <tr>
+ <td class="paramkey"></td>
+ <td></td>
+ <td class="paramtype">int&nbsp;</td>
+ <td class="paramname"> <em>quoted_implicit</em>, </td>
+ </tr>
+ <tr>
+ <td class="paramkey"></td>
+ <td></td>
+ <td class="paramtype"><a class="el" href="group__styles.html#ga3fa6405631e1afe5bd5c488a6c5e8065">yaml_scalar_style_t</a>&nbsp;</td>
+ <td class="paramname"> <em>style</em></td><td>&nbsp;</td>
+ </tr>
+ <tr>
+ <td></td>
+ <td>)</td>
+ <td></td><td></td><td></td>
+ </tr>
+ </table>
+</div>
+<div class="memdoc">
+
+<p>Create a SCALAR event. </p>
+<p>The <em>style</em> argument may be ignored by the emitter.</p>
+<p>Either the <em>tag</em> attribute or one of the <em>plain_implicit</em> and <em>quoted_implicit</em> flags must be set.</p>
+<dl><dt><b>Parameters:</b></dt><dd>
+ <table border="0" cellspacing="2" cellpadding="0">
+ <tr><td valign="top"><tt>[out]</tt>&nbsp;</td><td valign="top"><em>event</em>&nbsp;</td><td>An empty event object. </td></tr>
+ <tr><td valign="top"><tt>[in]</tt>&nbsp;</td><td valign="top"><em>anchor</em>&nbsp;</td><td>The scalar anchor or <code>NULL</code>. </td></tr>
+ <tr><td valign="top"><tt>[in]</tt>&nbsp;</td><td valign="top"><em>tag</em>&nbsp;</td><td>The scalar tag or <code>NULL</code>. </td></tr>
+ <tr><td valign="top"><tt>[in]</tt>&nbsp;</td><td valign="top"><em>value</em>&nbsp;</td><td>The scalar value. </td></tr>
+ <tr><td valign="top"><tt>[in]</tt>&nbsp;</td><td valign="top"><em>length</em>&nbsp;</td><td>The length of the scalar value. </td></tr>
+ <tr><td valign="top"><tt>[in]</tt>&nbsp;</td><td valign="top"><em>plain_implicit</em>&nbsp;</td><td>If the tag may be omitted for the plain style. </td></tr>
+ <tr><td valign="top"><tt>[in]</tt>&nbsp;</td><td valign="top"><em>quoted_implicit</em>&nbsp;</td><td>If the tag may be omitted for any non-plain style. </td></tr>
+ <tr><td valign="top"><tt>[in]</tt>&nbsp;</td><td valign="top"><em>style</em>&nbsp;</td><td>The scalar style.</td></tr>
+ </table>
+ </dd>
+</dl>
+<dl class="return"><dt><b>Returns:</b></dt><dd><code>1</code> if the function succeeded, <code>0</code> on error. </dd></dl>
+
+</div>
+</div>
+<a class="anchor" id="ga53aea428c768d7b131923d08c904b4eb"></a><!-- doxytag: member="yaml.h::yaml_sequence_start_event_initialize" ref="ga53aea428c768d7b131923d08c904b4eb" args="(yaml_event_t *event, yaml_char_t *anchor, yaml_char_t *tag, int implicit, yaml_sequence_style_t style)" -->
+<div class="memitem">
+<div class="memproto">
+ <table class="memname">
+ <tr>
+ <td class="memname">int yaml_sequence_start_event_initialize </td>
+ <td>(</td>
+ <td class="paramtype"><a class="el" href="structyaml__event__s.html">yaml_event_t</a> *&nbsp;</td>
+ <td class="paramname"> <em>event</em>, </td>
+ </tr>
+ <tr>
+ <td class="paramkey"></td>
+ <td></td>
+ <td class="paramtype"><a class="el" href="group__basic.html#gaf8657e81f0b8b05d1a081001fc6cb8bd">yaml_char_t</a> *&nbsp;</td>
+ <td class="paramname"> <em>anchor</em>, </td>
+ </tr>
+ <tr>
+ <td class="paramkey"></td>
+ <td></td>
+ <td class="paramtype"><a class="el" href="group__basic.html#gaf8657e81f0b8b05d1a081001fc6cb8bd">yaml_char_t</a> *&nbsp;</td>
+ <td class="paramname"> <em>tag</em>, </td>
+ </tr>
+ <tr>
+ <td class="paramkey"></td>
+ <td></td>
+ <td class="paramtype">int&nbsp;</td>
+ <td class="paramname"> <em>implicit</em>, </td>
+ </tr>
+ <tr>
+ <td class="paramkey"></td>
+ <td></td>
+ <td class="paramtype"><a class="el" href="group__styles.html#ga58a1123d271e56c72de6abf852ac4dc2">yaml_sequence_style_t</a>&nbsp;</td>
+ <td class="paramname"> <em>style</em></td><td>&nbsp;</td>
+ </tr>
+ <tr>
+ <td></td>
+ <td>)</td>
+ <td></td><td></td><td></td>
+ </tr>
+ </table>
+</div>
+<div class="memdoc">
+
+<p>Create a SEQUENCE-START event. </p>
+<p>The <em>style</em> argument may be ignored by the emitter.</p>
+<p>Either the <em>tag</em> attribute or the <em>implicit</em> flag must be set.</p>
+<dl><dt><b>Parameters:</b></dt><dd>
+ <table border="0" cellspacing="2" cellpadding="0">
+ <tr><td valign="top"><tt>[out]</tt>&nbsp;</td><td valign="top"><em>event</em>&nbsp;</td><td>An empty event object. </td></tr>
+ <tr><td valign="top"><tt>[in]</tt>&nbsp;</td><td valign="top"><em>anchor</em>&nbsp;</td><td>The sequence anchor or <code>NULL</code>. </td></tr>
+ <tr><td valign="top"><tt>[in]</tt>&nbsp;</td><td valign="top"><em>tag</em>&nbsp;</td><td>The sequence tag or <code>NULL</code>. </td></tr>
+ <tr><td valign="top"><tt>[in]</tt>&nbsp;</td><td valign="top"><em>implicit</em>&nbsp;</td><td>If the tag may be omitted. </td></tr>
+ <tr><td valign="top"><tt>[in]</tt>&nbsp;</td><td valign="top"><em>style</em>&nbsp;</td><td>The sequence style.</td></tr>
+ </table>
+ </dd>
+</dl>
+<dl class="return"><dt><b>Returns:</b></dt><dd><code>1</code> if the function succeeded, <code>0</code> on error. </dd></dl>
+
+</div>
+</div>
+<a class="anchor" id="ga99fdfa4b9d42b64d8171c9b22f334b1c"></a><!-- doxytag: member="yaml.h::yaml_sequence_end_event_initialize" ref="ga99fdfa4b9d42b64d8171c9b22f334b1c" args="(yaml_event_t *event)" -->
+<div class="memitem">
+<div class="memproto">
+ <table class="memname">
+ <tr>
+ <td class="memname">int yaml_sequence_end_event_initialize </td>
+ <td>(</td>
+ <td class="paramtype"><a class="el" href="structyaml__event__s.html">yaml_event_t</a> *&nbsp;</td>
+ <td class="paramname"> <em>event</em></td>
+ <td>&nbsp;)&nbsp;</td>
+ <td></td>
+ </tr>
+ </table>
+</div>
+<div class="memdoc">
+
+<p>Create a SEQUENCE-END event. </p>
+<dl><dt><b>Parameters:</b></dt><dd>
+ <table border="0" cellspacing="2" cellpadding="0">
+ <tr><td valign="top"><tt>[out]</tt>&nbsp;</td><td valign="top"><em>event</em>&nbsp;</td><td>An empty event object.</td></tr>
+ </table>
+ </dd>
+</dl>
+<dl class="return"><dt><b>Returns:</b></dt><dd><code>1</code> if the function succeeded, <code>0</code> on error. </dd></dl>
+
+</div>
+</div>
+<a class="anchor" id="ga0603cf8d20f0b6dfc3be04b6360134aa"></a><!-- doxytag: member="yaml.h::yaml_mapping_start_event_initialize" ref="ga0603cf8d20f0b6dfc3be04b6360134aa" args="(yaml_event_t *event, yaml_char_t *anchor, yaml_char_t *tag, int implicit, yaml_mapping_style_t style)" -->
+<div class="memitem">
+<div class="memproto">
+ <table class="memname">
+ <tr>
+ <td class="memname">int yaml_mapping_start_event_initialize </td>
+ <td>(</td>
+ <td class="paramtype"><a class="el" href="structyaml__event__s.html">yaml_event_t</a> *&nbsp;</td>
+ <td class="paramname"> <em>event</em>, </td>
+ </tr>
+ <tr>
+ <td class="paramkey"></td>
+ <td></td>
+ <td class="paramtype"><a class="el" href="group__basic.html#gaf8657e81f0b8b05d1a081001fc6cb8bd">yaml_char_t</a> *&nbsp;</td>
+ <td class="paramname"> <em>anchor</em>, </td>
+ </tr>
+ <tr>
+ <td class="paramkey"></td>
+ <td></td>
+ <td class="paramtype"><a class="el" href="group__basic.html#gaf8657e81f0b8b05d1a081001fc6cb8bd">yaml_char_t</a> *&nbsp;</td>
+ <td class="paramname"> <em>tag</em>, </td>
+ </tr>
+ <tr>
+ <td class="paramkey"></td>
+ <td></td>
+ <td class="paramtype">int&nbsp;</td>
+ <td class="paramname"> <em>implicit</em>, </td>
+ </tr>
+ <tr>
+ <td class="paramkey"></td>
+ <td></td>
+ <td class="paramtype"><a class="el" href="group__styles.html#gab47523846a5c5960e07367a28ea9750a">yaml_mapping_style_t</a>&nbsp;</td>
+ <td class="paramname"> <em>style</em></td><td>&nbsp;</td>
+ </tr>
+ <tr>
+ <td></td>
+ <td>)</td>
+ <td></td><td></td><td></td>
+ </tr>
+ </table>
+</div>
+<div class="memdoc">
+
+<p>Create a MAPPING-START event. </p>
+<p>The <em>style</em> argument may be ignored by the emitter.</p>
+<p>Either the <em>tag</em> attribute or the <em>implicit</em> flag must be set.</p>
+<dl><dt><b>Parameters:</b></dt><dd>
+ <table border="0" cellspacing="2" cellpadding="0">
+ <tr><td valign="top"><tt>[out]</tt>&nbsp;</td><td valign="top"><em>event</em>&nbsp;</td><td>An empty event object. </td></tr>
+ <tr><td valign="top"><tt>[in]</tt>&nbsp;</td><td valign="top"><em>anchor</em>&nbsp;</td><td>The mapping anchor or <code>NULL</code>. </td></tr>
+ <tr><td valign="top"><tt>[in]</tt>&nbsp;</td><td valign="top"><em>tag</em>&nbsp;</td><td>The mapping tag or <code>NULL</code>. </td></tr>
+ <tr><td valign="top"><tt>[in]</tt>&nbsp;</td><td valign="top"><em>implicit</em>&nbsp;</td><td>If the tag may be omitted. </td></tr>
+ <tr><td valign="top"><tt>[in]</tt>&nbsp;</td><td valign="top"><em>style</em>&nbsp;</td><td>The mapping style.</td></tr>
+ </table>
+ </dd>
+</dl>
+<dl class="return"><dt><b>Returns:</b></dt><dd><code>1</code> if the function succeeded, <code>0</code> on error. </dd></dl>
+
+</div>
+</div>
+<a class="anchor" id="ga3afaf8b3aca2ec902a4e268f12adb0c2"></a><!-- doxytag: member="yaml.h::yaml_mapping_end_event_initialize" ref="ga3afaf8b3aca2ec902a4e268f12adb0c2" args="(yaml_event_t *event)" -->
+<div class="memitem">
+<div class="memproto">
+ <table class="memname">
+ <tr>
+ <td class="memname">int yaml_mapping_end_event_initialize </td>
+ <td>(</td>
+ <td class="paramtype"><a class="el" href="structyaml__event__s.html">yaml_event_t</a> *&nbsp;</td>
+ <td class="paramname"> <em>event</em></td>
+ <td>&nbsp;)&nbsp;</td>
+ <td></td>
+ </tr>
+ </table>
+</div>
+<div class="memdoc">
+
+<p>Create a MAPPING-END event. </p>
+<dl><dt><b>Parameters:</b></dt><dd>
+ <table border="0" cellspacing="2" cellpadding="0">
+ <tr><td valign="top"><tt>[out]</tt>&nbsp;</td><td valign="top"><em>event</em>&nbsp;</td><td>An empty event object.</td></tr>
+ </table>
+ </dd>
+</dl>
+<dl class="return"><dt><b>Returns:</b></dt><dd><code>1</code> if the function succeeded, <code>0</code> on error. </dd></dl>
+
+</div>
+</div>
+<a class="anchor" id="ga5330d62ef52856aa53188137cb93a6a1"></a><!-- doxytag: member="yaml.h::yaml_event_delete" ref="ga5330d62ef52856aa53188137cb93a6a1" args="(yaml_event_t *event)" -->
+<div class="memitem">
+<div class="memproto">
+ <table class="memname">
+ <tr>
+ <td class="memname">void yaml_event_delete </td>
+ <td>(</td>
+ <td class="paramtype"><a class="el" href="structyaml__event__s.html">yaml_event_t</a> *&nbsp;</td>
+ <td class="paramname"> <em>event</em></td>
+ <td>&nbsp;)&nbsp;</td>
+ <td></td>
+ </tr>
+ </table>
+</div>
+<div class="memdoc">
+
+<p>Free any memory allocated for an event object. </p>
+<dl><dt><b>Parameters:</b></dt><dd>
+ <table border="0" cellspacing="2" cellpadding="0">
+ <tr><td valign="top"><tt>[in,out]</tt>&nbsp;</td><td valign="top"><em>event</em>&nbsp;</td><td>An event object. </td></tr>
+ </table>
+ </dd>
+</dl>
+
+</div>
+</div>
+</div>
+<hr class="footer"/><address class="footer"><small>Generated on Mon May 30 2011 22:00:00 for yaml by&nbsp;
+<a href="http://www.doxygen.org/index.html">
+<img class="footer" src="doxygen.png" alt="doxygen"/></a> 1.7.1 </small></address>
+</body>
+</html>
diff --git a/contrib/libyaml/doc/html/group__export.html b/contrib/libyaml/doc/html/group__export.html
new file mode 100644
index 0000000..2a57b6f
--- /dev/null
+++ b/contrib/libyaml/doc/html/group__export.html
@@ -0,0 +1,60 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head>
+<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/>
+<title>yaml: Export Definitions</title>
+<link href="tabs.css" rel="stylesheet" type="text/css"/>
+<link href="doxygen.css" rel="stylesheet" type="text/css"/>
+</head>
+<body>
+<!-- Generated by Doxygen 1.7.1 -->
+<div class="navigation" id="top">
+ <div class="tabs">
+ <ul class="tablist">
+ <li><a href="index.html"><span>Main&nbsp;Page</span></a></li>
+ <li><a href="modules.html"><span>Modules</span></a></li>
+ <li><a href="annotated.html"><span>Data&nbsp;Structures</span></a></li>
+ <li><a href="files.html"><span>Files</span></a></li>
+ </ul>
+ </div>
+</div>
+<div class="header">
+ <div class="summary">
+<a href="#define-members">Defines</a> </div>
+ <div class="headertitle">
+<h1>Export Definitions</h1> </div>
+</div>
+<div class="contents">
+<table class="memberdecls">
+<tr><td colspan="2"><h2><a name="define-members"></a>
+Defines</h2></td></tr>
+<tr><td class="memItemLeft" align="right" valign="top">#define&nbsp;</td><td class="memItemRight" valign="bottom"><a class="el" href="group__export.html#ga0791fd3e1d85ed53711b1feaae131f93">YAML_DECLARE</a>(type)&nbsp;&nbsp;&nbsp;type</td></tr>
+<tr><td class="mdescLeft">&nbsp;</td><td class="mdescRight">The public API declaration. <a href="#ga0791fd3e1d85ed53711b1feaae131f93"></a><br/></td></tr>
+</table>
+<hr/><h2>Define Documentation</h2>
+<a class="anchor" id="ga0791fd3e1d85ed53711b1feaae131f93"></a><!-- doxytag: member="yaml.h::YAML_DECLARE" ref="ga0791fd3e1d85ed53711b1feaae131f93" args="(type)" -->
+<div class="memitem">
+<div class="memproto">
+ <table class="memname">
+ <tr>
+ <td class="memname">#define YAML_DECLARE</td>
+ <td>(</td>
+ <td class="paramtype">&nbsp;</td>
+ <td class="paramname">type</td>
+ <td>&nbsp;)&nbsp;</td>
+ <td>&nbsp;&nbsp;&nbsp;type</td>
+ </tr>
+ </table>
+</div>
+<div class="memdoc">
+
+<p>The public API declaration. </p>
+
+</div>
+</div>
+</div>
+<hr class="footer"/><address class="footer"><small>Generated on Mon May 30 2011 22:00:00 for yaml by&nbsp;
+<a href="http://www.doxygen.org/index.html">
+<img class="footer" src="doxygen.png" alt="doxygen"/></a> 1.7.1 </small></address>
+</body>
+</html>
diff --git a/contrib/libyaml/doc/html/group__nodes.html b/contrib/libyaml/doc/html/group__nodes.html
new file mode 100644
index 0000000..e0713cc
--- /dev/null
+++ b/contrib/libyaml/doc/html/group__nodes.html
@@ -0,0 +1,795 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head>
+<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/>
+<title>yaml: Nodes</title>
+<link href="tabs.css" rel="stylesheet" type="text/css"/>
+<link href="doxygen.css" rel="stylesheet" type="text/css"/>
+</head>
+<body>
+<!-- Generated by Doxygen 1.7.1 -->
+<div class="navigation" id="top">
+ <div class="tabs">
+ <ul class="tablist">
+ <li><a href="index.html"><span>Main&nbsp;Page</span></a></li>
+ <li><a href="modules.html"><span>Modules</span></a></li>
+ <li><a href="annotated.html"><span>Data&nbsp;Structures</span></a></li>
+ <li><a href="files.html"><span>Files</span></a></li>
+ </ul>
+ </div>
+</div>
+<div class="header">
+ <div class="summary">
+<a href="#nested-classes">Data Structures</a> &#124;
+<a href="#define-members">Defines</a> &#124;
+<a href="#typedef-members">Typedefs</a> &#124;
+<a href="#enum-members">Enumerations</a> &#124;
+<a href="#func-members">Functions</a> </div>
+ <div class="headertitle">
+<h1>Nodes</h1> </div>
+</div>
+<div class="contents">
+<table class="memberdecls">
+<tr><td colspan="2"><h2><a name="nested-classes"></a>
+Data Structures</h2></td></tr>
+<tr><td class="memItemLeft" align="right" valign="top">struct &nbsp;</td><td class="memItemRight" valign="bottom"><a class="el" href="structyaml__node__pair__s.html">yaml_node_pair_s</a></td></tr>
+<tr><td class="mdescLeft">&nbsp;</td><td class="mdescRight">An element of a mapping node. <a href="structyaml__node__pair__s.html#_details">More...</a><br/></td></tr>
+<tr><td class="memItemLeft" align="right" valign="top">struct &nbsp;</td><td class="memItemRight" valign="bottom"><a class="el" href="structyaml__node__s.html">yaml_node_s</a></td></tr>
+<tr><td class="mdescLeft">&nbsp;</td><td class="mdescRight">The node structure. <a href="structyaml__node__s.html#_details">More...</a><br/></td></tr>
+<tr><td class="memItemLeft" align="right" valign="top">struct &nbsp;</td><td class="memItemRight" valign="bottom"><a class="el" href="structyaml__document__s.html">yaml_document_s</a></td></tr>
+<tr><td class="mdescLeft">&nbsp;</td><td class="mdescRight">The document structure. <a href="structyaml__document__s.html#_details">More...</a><br/></td></tr>
+<tr><td colspan="2"><h2><a name="define-members"></a>
+Defines</h2></td></tr>
+<tr><td class="memItemLeft" align="right" valign="top">#define&nbsp;</td><td class="memItemRight" valign="bottom"><a class="el" href="group__nodes.html#gadfa882b6e42a3a993d12392d55260b00">YAML_NULL_TAG</a>&nbsp;&nbsp;&nbsp;&quot;tag:yaml.org,2002:null&quot;</td></tr>
+<tr><td class="mdescLeft">&nbsp;</td><td class="mdescRight">The tag <code>!!null</code> with the only possible value: <code>null</code>. <a href="#gadfa882b6e42a3a993d12392d55260b00"></a><br/></td></tr>
+<tr><td class="memItemLeft" align="right" valign="top">#define&nbsp;</td><td class="memItemRight" valign="bottom"><a class="el" href="group__nodes.html#ga312629a1f51e91b136352db988d4d771">YAML_BOOL_TAG</a>&nbsp;&nbsp;&nbsp;&quot;tag:yaml.org,2002:bool&quot;</td></tr>
+<tr><td class="mdescLeft">&nbsp;</td><td class="mdescRight">The tag <code>!!bool</code> with the values: <code>true</code> and <code>falce</code>. <a href="#ga312629a1f51e91b136352db988d4d771"></a><br/></td></tr>
+<tr><td class="memItemLeft" align="right" valign="top">#define&nbsp;</td><td class="memItemRight" valign="bottom"><a class="el" href="group__nodes.html#gac5dbc6d1f556663edf8db88d6113e931">YAML_STR_TAG</a>&nbsp;&nbsp;&nbsp;&quot;tag:yaml.org,2002:str&quot;</td></tr>
+<tr><td class="mdescLeft">&nbsp;</td><td class="mdescRight">The tag <code>!!str</code> for string values. <a href="#gac5dbc6d1f556663edf8db88d6113e931"></a><br/></td></tr>
+<tr><td class="memItemLeft" align="right" valign="top">#define&nbsp;</td><td class="memItemRight" valign="bottom"><a class="el" href="group__nodes.html#ga83263cdb4ffa6ad2f7d9a87281979ff5">YAML_INT_TAG</a>&nbsp;&nbsp;&nbsp;&quot;tag:yaml.org,2002:int&quot;</td></tr>
+<tr><td class="mdescLeft">&nbsp;</td><td class="mdescRight">The tag <code>!!int</code> for integer values. <a href="#ga83263cdb4ffa6ad2f7d9a87281979ff5"></a><br/></td></tr>
+<tr><td class="memItemLeft" align="right" valign="top">#define&nbsp;</td><td class="memItemRight" valign="bottom"><a class="el" href="group__nodes.html#ga6ab2ec71fc47cb24f1003b9acdb92843">YAML_FLOAT_TAG</a>&nbsp;&nbsp;&nbsp;&quot;tag:yaml.org,2002:float&quot;</td></tr>
+<tr><td class="mdescLeft">&nbsp;</td><td class="mdescRight">The tag <code>!!float</code> for float values. <a href="#ga6ab2ec71fc47cb24f1003b9acdb92843"></a><br/></td></tr>
+<tr><td class="memItemLeft" align="right" valign="top">#define&nbsp;</td><td class="memItemRight" valign="bottom"><a class="el" href="group__nodes.html#ga3e27cca7191234f2e8c95eaf3bc99a73">YAML_TIMESTAMP_TAG</a>&nbsp;&nbsp;&nbsp;&quot;tag:yaml.org,2002:timestamp&quot;</td></tr>
+<tr><td class="mdescLeft">&nbsp;</td><td class="mdescRight">The tag <code>!!timestamp</code> for date and time values. <a href="#ga3e27cca7191234f2e8c95eaf3bc99a73"></a><br/></td></tr>
+<tr><td class="memItemLeft" align="right" valign="top">#define&nbsp;</td><td class="memItemRight" valign="bottom"><a class="el" href="group__nodes.html#gaa8284b30f9c9e3f10f6a69c9b882f417">YAML_SEQ_TAG</a>&nbsp;&nbsp;&nbsp;&quot;tag:yaml.org,2002:seq&quot;</td></tr>
+<tr><td class="mdescLeft">&nbsp;</td><td class="mdescRight">The tag <code>!!seq</code> is used to denote sequences. <a href="#gaa8284b30f9c9e3f10f6a69c9b882f417"></a><br/></td></tr>
+<tr><td class="memItemLeft" align="right" valign="top">#define&nbsp;</td><td class="memItemRight" valign="bottom"><a class="el" href="group__nodes.html#ga22ae99cf3ac014dd76873268fd068c12">YAML_MAP_TAG</a>&nbsp;&nbsp;&nbsp;&quot;tag:yaml.org,2002:map&quot;</td></tr>
+<tr><td class="mdescLeft">&nbsp;</td><td class="mdescRight">The tag <code>!!map</code> is used to denote mapping. <a href="#ga22ae99cf3ac014dd76873268fd068c12"></a><br/></td></tr>
+<tr><td class="memItemLeft" align="right" valign="top">#define&nbsp;</td><td class="memItemRight" valign="bottom"><a class="el" href="group__nodes.html#gaf6b0c4e819b8f6915515a4f70065aaaa">YAML_DEFAULT_SCALAR_TAG</a>&nbsp;&nbsp;&nbsp;YAML_STR_TAG</td></tr>
+<tr><td class="mdescLeft">&nbsp;</td><td class="mdescRight">The default scalar tag is <code>!!str</code>. <a href="#gaf6b0c4e819b8f6915515a4f70065aaaa"></a><br/></td></tr>
+<tr><td class="memItemLeft" align="right" valign="top">#define&nbsp;</td><td class="memItemRight" valign="bottom"><a class="el" href="group__nodes.html#gaf195b67002518702e27746d6b4da6124">YAML_DEFAULT_SEQUENCE_TAG</a>&nbsp;&nbsp;&nbsp;YAML_SEQ_TAG</td></tr>
+<tr><td class="mdescLeft">&nbsp;</td><td class="mdescRight">The default sequence tag is <code>!!seq</code>. <a href="#gaf195b67002518702e27746d6b4da6124"></a><br/></td></tr>
+<tr><td class="memItemLeft" align="right" valign="top">#define&nbsp;</td><td class="memItemRight" valign="bottom"><a class="el" href="group__nodes.html#gaf7b1f8f0ce5665794510cd3841802a5f">YAML_DEFAULT_MAPPING_TAG</a>&nbsp;&nbsp;&nbsp;YAML_MAP_TAG</td></tr>
+<tr><td class="mdescLeft">&nbsp;</td><td class="mdescRight">The default mapping tag is <code>!!map</code>. <a href="#gaf7b1f8f0ce5665794510cd3841802a5f"></a><br/></td></tr>
+<tr><td colspan="2"><h2><a name="typedef-members"></a>
+Typedefs</h2></td></tr>
+<tr><td class="memItemLeft" align="right" valign="top">typedef enum <a class="el" href="group__nodes.html#ga0897d4b6bdd1b56c7a5fa0ff17b4f798">yaml_node_type_e</a>&nbsp;</td><td class="memItemRight" valign="bottom"><a class="el" href="group__nodes.html#gabe020d2fc42d3e896549e9f97da622d2">yaml_node_type_t</a></td></tr>
+<tr><td class="mdescLeft">&nbsp;</td><td class="mdescRight">Node types. <a href="#gabe020d2fc42d3e896549e9f97da622d2"></a><br/></td></tr>
+<tr><td class="memItemLeft" align="right" valign="top">typedef struct <a class="el" href="structyaml__node__s.html">yaml_node_s</a>&nbsp;</td><td class="memItemRight" valign="bottom"><a class="el" href="group__nodes.html#ga9eaaa233b120b9d9db47de93c294c40f">yaml_node_t</a></td></tr>
+<tr><td class="mdescLeft">&nbsp;</td><td class="mdescRight">The forward definition of a document node structure. <a href="#ga9eaaa233b120b9d9db47de93c294c40f"></a><br/></td></tr>
+<tr><td class="memItemLeft" align="right" valign="top">typedef int&nbsp;</td><td class="memItemRight" valign="bottom"><a class="el" href="group__nodes.html#ga7cc3581582e778b00c04e99cd3656860">yaml_node_item_t</a></td></tr>
+<tr><td class="mdescLeft">&nbsp;</td><td class="mdescRight">An element of a sequence node. <a href="#ga7cc3581582e778b00c04e99cd3656860"></a><br/></td></tr>
+<tr><td class="memItemLeft" align="right" valign="top">typedef struct <a class="el" href="structyaml__node__pair__s.html">yaml_node_pair_s</a>&nbsp;</td><td class="memItemRight" valign="bottom"><a class="el" href="group__nodes.html#ga90f1c8b83c5c38dc4016afc1cc2050c4">yaml_node_pair_t</a></td></tr>
+<tr><td class="mdescLeft">&nbsp;</td><td class="mdescRight">An element of a mapping node. <a href="#ga90f1c8b83c5c38dc4016afc1cc2050c4"></a><br/></td></tr>
+<tr><td class="memItemLeft" align="right" valign="top">typedef struct <a class="el" href="structyaml__document__s.html">yaml_document_s</a>&nbsp;</td><td class="memItemRight" valign="bottom"><a class="el" href="group__nodes.html#gad94e064e95baeb22e4f7acc7804e8479">yaml_document_t</a></td></tr>
+<tr><td class="mdescLeft">&nbsp;</td><td class="mdescRight">The document structure. <a href="#gad94e064e95baeb22e4f7acc7804e8479"></a><br/></td></tr>
+<tr><td colspan="2"><h2><a name="enum-members"></a>
+Enumerations</h2></td></tr>
+<tr><td class="memItemLeft" align="right" valign="top">enum &nbsp;</td><td class="memItemRight" valign="bottom"><a class="el" href="group__nodes.html#ga0897d4b6bdd1b56c7a5fa0ff17b4f798">yaml_node_type_e</a> { <br/>
+&nbsp;&nbsp;<a class="el" href="group__nodes.html#gga0897d4b6bdd1b56c7a5fa0ff17b4f798a0fa87c0e89c4d4136cb47165e6917739">YAML_NO_NODE</a>,
+<br/>
+&nbsp;&nbsp;<a class="el" href="group__nodes.html#gga0897d4b6bdd1b56c7a5fa0ff17b4f798a413ec8ce6b728c9ace703d194b370a45">YAML_SCALAR_NODE</a>,
+<br/>
+&nbsp;&nbsp;<a class="el" href="group__nodes.html#gga0897d4b6bdd1b56c7a5fa0ff17b4f798a6c03b52f7ee737982eac5e4001faac15">YAML_SEQUENCE_NODE</a>,
+<br/>
+&nbsp;&nbsp;<a class="el" href="group__nodes.html#gga0897d4b6bdd1b56c7a5fa0ff17b4f798ac1a08580e3a70973583fc85e3e097ee6">YAML_MAPPING_NODE</a>
+<br/>
+ }</td></tr>
+<tr><td class="mdescLeft">&nbsp;</td><td class="mdescRight"><p>Node types. </p>
+ <a href="group__nodes.html#ga0897d4b6bdd1b56c7a5fa0ff17b4f798">More...</a><br/></td></tr>
+<tr><td colspan="2"><h2><a name="func-members"></a>
+Functions</h2></td></tr>
+<tr><td class="memItemLeft" align="right" valign="top">int&nbsp;</td><td class="memItemRight" valign="bottom"><a class="el" href="group__nodes.html#ga62a485c96f3b7962436a0da5e6f3cc89">yaml_document_initialize</a> (<a class="el" href="structyaml__document__s.html">yaml_document_t</a> *document, <a class="el" href="structyaml__version__directive__s.html">yaml_version_directive_t</a> *version_directive, <a class="el" href="structyaml__tag__directive__s.html">yaml_tag_directive_t</a> *tag_directives_start, <a class="el" href="structyaml__tag__directive__s.html">yaml_tag_directive_t</a> *tag_directives_end, int start_implicit, int end_implicit)</td></tr>
+<tr><td class="mdescLeft">&nbsp;</td><td class="mdescRight">Create a YAML document. <a href="#ga62a485c96f3b7962436a0da5e6f3cc89"></a><br/></td></tr>
+<tr><td class="memItemLeft" align="right" valign="top">void&nbsp;</td><td class="memItemRight" valign="bottom"><a class="el" href="group__nodes.html#ga2754b1544fb4e110e83fafbc708b0672">yaml_document_delete</a> (<a class="el" href="structyaml__document__s.html">yaml_document_t</a> *document)</td></tr>
+<tr><td class="mdescLeft">&nbsp;</td><td class="mdescRight">Delete a YAML document and all its nodes. <a href="#ga2754b1544fb4e110e83fafbc708b0672"></a><br/></td></tr>
+<tr><td class="memItemLeft" align="right" valign="top"><a class="el" href="structyaml__node__s.html">yaml_node_t</a> *&nbsp;</td><td class="memItemRight" valign="bottom"><a class="el" href="group__nodes.html#gafa1feabc9747dbded4dca24e27d3c21a">yaml_document_get_node</a> (<a class="el" href="structyaml__document__s.html">yaml_document_t</a> *document, int index)</td></tr>
+<tr><td class="mdescLeft">&nbsp;</td><td class="mdescRight">Get a node of a YAML document. <a href="#gafa1feabc9747dbded4dca24e27d3c21a"></a><br/></td></tr>
+<tr><td class="memItemLeft" align="right" valign="top"><a class="el" href="structyaml__node__s.html">yaml_node_t</a> *&nbsp;</td><td class="memItemRight" valign="bottom"><a class="el" href="group__nodes.html#ga40eeaa68fb2f3be34c4fe34e7597d324">yaml_document_get_root_node</a> (<a class="el" href="structyaml__document__s.html">yaml_document_t</a> *document)</td></tr>
+<tr><td class="mdescLeft">&nbsp;</td><td class="mdescRight">Get the root of a YAML document node. <a href="#ga40eeaa68fb2f3be34c4fe34e7597d324"></a><br/></td></tr>
+<tr><td class="memItemLeft" align="right" valign="top">int&nbsp;</td><td class="memItemRight" valign="bottom"><a class="el" href="group__nodes.html#ga45dab8b983b58a005557d4b01f5057b0">yaml_document_add_scalar</a> (<a class="el" href="structyaml__document__s.html">yaml_document_t</a> *document, <a class="el" href="group__basic.html#gaf8657e81f0b8b05d1a081001fc6cb8bd">yaml_char_t</a> *tag, <a class="el" href="group__basic.html#gaf8657e81f0b8b05d1a081001fc6cb8bd">yaml_char_t</a> *value, int length, <a class="el" href="group__styles.html#ga3fa6405631e1afe5bd5c488a6c5e8065">yaml_scalar_style_t</a> style)</td></tr>
+<tr><td class="mdescLeft">&nbsp;</td><td class="mdescRight">Create a SCALAR node and attach it to the document. <a href="#ga45dab8b983b58a005557d4b01f5057b0"></a><br/></td></tr>
+<tr><td class="memItemLeft" align="right" valign="top">int&nbsp;</td><td class="memItemRight" valign="bottom"><a class="el" href="group__nodes.html#ga83b2f7fdd9a439397a42016bddad7786">yaml_document_add_sequence</a> (<a class="el" href="structyaml__document__s.html">yaml_document_t</a> *document, <a class="el" href="group__basic.html#gaf8657e81f0b8b05d1a081001fc6cb8bd">yaml_char_t</a> *tag, <a class="el" href="group__styles.html#ga58a1123d271e56c72de6abf852ac4dc2">yaml_sequence_style_t</a> style)</td></tr>
+<tr><td class="mdescLeft">&nbsp;</td><td class="mdescRight">Create a SEQUENCE node and attach it to the document. <a href="#ga83b2f7fdd9a439397a42016bddad7786"></a><br/></td></tr>
+<tr><td class="memItemLeft" align="right" valign="top">int&nbsp;</td><td class="memItemRight" valign="bottom"><a class="el" href="group__nodes.html#ga45a9f8288704f99cd81dc5cb31329d34">yaml_document_add_mapping</a> (<a class="el" href="structyaml__document__s.html">yaml_document_t</a> *document, <a class="el" href="group__basic.html#gaf8657e81f0b8b05d1a081001fc6cb8bd">yaml_char_t</a> *tag, <a class="el" href="group__styles.html#gab47523846a5c5960e07367a28ea9750a">yaml_mapping_style_t</a> style)</td></tr>
+<tr><td class="mdescLeft">&nbsp;</td><td class="mdescRight">Create a MAPPING node and attach it to the document. <a href="#ga45a9f8288704f99cd81dc5cb31329d34"></a><br/></td></tr>
+<tr><td class="memItemLeft" align="right" valign="top">int&nbsp;</td><td class="memItemRight" valign="bottom"><a class="el" href="group__nodes.html#ga16435917cd6c0261cd390fa8cf173b1b">yaml_document_append_sequence_item</a> (<a class="el" href="structyaml__document__s.html">yaml_document_t</a> *document, int sequence, int item)</td></tr>
+<tr><td class="mdescLeft">&nbsp;</td><td class="mdescRight">Add an item to a SEQUENCE node. <a href="#ga16435917cd6c0261cd390fa8cf173b1b"></a><br/></td></tr>
+<tr><td class="memItemLeft" align="right" valign="top">int&nbsp;</td><td class="memItemRight" valign="bottom"><a class="el" href="group__nodes.html#ga2db27002d8a9ae06b1729d0ee06553d2">yaml_document_append_mapping_pair</a> (<a class="el" href="structyaml__document__s.html">yaml_document_t</a> *document, int mapping, int key, int value)</td></tr>
+<tr><td class="mdescLeft">&nbsp;</td><td class="mdescRight">Add a pair of a key and a value to a MAPPING node. <a href="#ga2db27002d8a9ae06b1729d0ee06553d2"></a><br/></td></tr>
+</table>
+<hr/><h2>Define Documentation</h2>
+<a class="anchor" id="gadfa882b6e42a3a993d12392d55260b00"></a><!-- doxytag: member="yaml.h::YAML_NULL_TAG" ref="gadfa882b6e42a3a993d12392d55260b00" args="" -->
+<div class="memitem">
+<div class="memproto">
+ <table class="memname">
+ <tr>
+ <td class="memname">#define YAML_NULL_TAG&nbsp;&nbsp;&nbsp;&quot;tag:yaml.org,2002:null&quot;</td>
+ </tr>
+ </table>
+</div>
+<div class="memdoc">
+
+<p>The tag <code>!!null</code> with the only possible value: <code>null</code>. </p>
+
+</div>
+</div>
+<a class="anchor" id="ga312629a1f51e91b136352db988d4d771"></a><!-- doxytag: member="yaml.h::YAML_BOOL_TAG" ref="ga312629a1f51e91b136352db988d4d771" args="" -->
+<div class="memitem">
+<div class="memproto">
+ <table class="memname">
+ <tr>
+ <td class="memname">#define YAML_BOOL_TAG&nbsp;&nbsp;&nbsp;&quot;tag:yaml.org,2002:bool&quot;</td>
+ </tr>
+ </table>
+</div>
+<div class="memdoc">
+
+<p>The tag <code>!!bool</code> with the values: <code>true</code> and <code>falce</code>. </p>
+
+</div>
+</div>
+<a class="anchor" id="gac5dbc6d1f556663edf8db88d6113e931"></a><!-- doxytag: member="yaml.h::YAML_STR_TAG" ref="gac5dbc6d1f556663edf8db88d6113e931" args="" -->
+<div class="memitem">
+<div class="memproto">
+ <table class="memname">
+ <tr>
+ <td class="memname">#define YAML_STR_TAG&nbsp;&nbsp;&nbsp;&quot;tag:yaml.org,2002:str&quot;</td>
+ </tr>
+ </table>
+</div>
+<div class="memdoc">
+
+<p>The tag <code>!!str</code> for string values. </p>
+
+</div>
+</div>
+<a class="anchor" id="ga83263cdb4ffa6ad2f7d9a87281979ff5"></a><!-- doxytag: member="yaml.h::YAML_INT_TAG" ref="ga83263cdb4ffa6ad2f7d9a87281979ff5" args="" -->
+<div class="memitem">
+<div class="memproto">
+ <table class="memname">
+ <tr>
+ <td class="memname">#define YAML_INT_TAG&nbsp;&nbsp;&nbsp;&quot;tag:yaml.org,2002:int&quot;</td>
+ </tr>
+ </table>
+</div>
+<div class="memdoc">
+
+<p>The tag <code>!!int</code> for integer values. </p>
+
+</div>
+</div>
+<a class="anchor" id="ga6ab2ec71fc47cb24f1003b9acdb92843"></a><!-- doxytag: member="yaml.h::YAML_FLOAT_TAG" ref="ga6ab2ec71fc47cb24f1003b9acdb92843" args="" -->
+<div class="memitem">
+<div class="memproto">
+ <table class="memname">
+ <tr>
+ <td class="memname">#define YAML_FLOAT_TAG&nbsp;&nbsp;&nbsp;&quot;tag:yaml.org,2002:float&quot;</td>
+ </tr>
+ </table>
+</div>
+<div class="memdoc">
+
+<p>The tag <code>!!float</code> for float values. </p>
+
+</div>
+</div>
+<a class="anchor" id="ga3e27cca7191234f2e8c95eaf3bc99a73"></a><!-- doxytag: member="yaml.h::YAML_TIMESTAMP_TAG" ref="ga3e27cca7191234f2e8c95eaf3bc99a73" args="" -->
+<div class="memitem">
+<div class="memproto">
+ <table class="memname">
+ <tr>
+ <td class="memname">#define YAML_TIMESTAMP_TAG&nbsp;&nbsp;&nbsp;&quot;tag:yaml.org,2002:timestamp&quot;</td>
+ </tr>
+ </table>
+</div>
+<div class="memdoc">
+
+<p>The tag <code>!!timestamp</code> for date and time values. </p>
+
+</div>
+</div>
+<a class="anchor" id="gaa8284b30f9c9e3f10f6a69c9b882f417"></a><!-- doxytag: member="yaml.h::YAML_SEQ_TAG" ref="gaa8284b30f9c9e3f10f6a69c9b882f417" args="" -->
+<div class="memitem">
+<div class="memproto">
+ <table class="memname">
+ <tr>
+ <td class="memname">#define YAML_SEQ_TAG&nbsp;&nbsp;&nbsp;&quot;tag:yaml.org,2002:seq&quot;</td>
+ </tr>
+ </table>
+</div>
+<div class="memdoc">
+
+<p>The tag <code>!!seq</code> is used to denote sequences. </p>
+
+</div>
+</div>
+<a class="anchor" id="ga22ae99cf3ac014dd76873268fd068c12"></a><!-- doxytag: member="yaml.h::YAML_MAP_TAG" ref="ga22ae99cf3ac014dd76873268fd068c12" args="" -->
+<div class="memitem">
+<div class="memproto">
+ <table class="memname">
+ <tr>
+ <td class="memname">#define YAML_MAP_TAG&nbsp;&nbsp;&nbsp;&quot;tag:yaml.org,2002:map&quot;</td>
+ </tr>
+ </table>
+</div>
+<div class="memdoc">
+
+<p>The tag <code>!!map</code> is used to denote mapping. </p>
+
+</div>
+</div>
+<a class="anchor" id="gaf6b0c4e819b8f6915515a4f70065aaaa"></a><!-- doxytag: member="yaml.h::YAML_DEFAULT_SCALAR_TAG" ref="gaf6b0c4e819b8f6915515a4f70065aaaa" args="" -->
+<div class="memitem">
+<div class="memproto">
+ <table class="memname">
+ <tr>
+ <td class="memname">#define YAML_DEFAULT_SCALAR_TAG&nbsp;&nbsp;&nbsp;YAML_STR_TAG</td>
+ </tr>
+ </table>
+</div>
+<div class="memdoc">
+
+<p>The default scalar tag is <code>!!str</code>. </p>
+
+</div>
+</div>
+<a class="anchor" id="gaf195b67002518702e27746d6b4da6124"></a><!-- doxytag: member="yaml.h::YAML_DEFAULT_SEQUENCE_TAG" ref="gaf195b67002518702e27746d6b4da6124" args="" -->
+<div class="memitem">
+<div class="memproto">
+ <table class="memname">
+ <tr>
+ <td class="memname">#define YAML_DEFAULT_SEQUENCE_TAG&nbsp;&nbsp;&nbsp;YAML_SEQ_TAG</td>
+ </tr>
+ </table>
+</div>
+<div class="memdoc">
+
+<p>The default sequence tag is <code>!!seq</code>. </p>
+
+</div>
+</div>
+<a class="anchor" id="gaf7b1f8f0ce5665794510cd3841802a5f"></a><!-- doxytag: member="yaml.h::YAML_DEFAULT_MAPPING_TAG" ref="gaf7b1f8f0ce5665794510cd3841802a5f" args="" -->
+<div class="memitem">
+<div class="memproto">
+ <table class="memname">
+ <tr>
+ <td class="memname">#define YAML_DEFAULT_MAPPING_TAG&nbsp;&nbsp;&nbsp;YAML_MAP_TAG</td>
+ </tr>
+ </table>
+</div>
+<div class="memdoc">
+
+<p>The default mapping tag is <code>!!map</code>. </p>
+
+</div>
+</div>
+<hr/><h2>Typedef Documentation</h2>
+<a class="anchor" id="gabe020d2fc42d3e896549e9f97da622d2"></a><!-- doxytag: member="yaml.h::yaml_node_type_t" ref="gabe020d2fc42d3e896549e9f97da622d2" args="" -->
+<div class="memitem">
+<div class="memproto">
+ <table class="memname">
+ <tr>
+ <td class="memname">typedef enum <a class="el" href="group__nodes.html#ga0897d4b6bdd1b56c7a5fa0ff17b4f798">yaml_node_type_e</a> <a class="el" href="group__nodes.html#gabe020d2fc42d3e896549e9f97da622d2">yaml_node_type_t</a></td>
+ </tr>
+ </table>
+</div>
+<div class="memdoc">
+
+<p>Node types. </p>
+
+</div>
+</div>
+<a class="anchor" id="ga9eaaa233b120b9d9db47de93c294c40f"></a><!-- doxytag: member="yaml.h::yaml_node_t" ref="ga9eaaa233b120b9d9db47de93c294c40f" args="" -->
+<div class="memitem">
+<div class="memproto">
+ <table class="memname">
+ <tr>
+ <td class="memname">typedef struct <a class="el" href="structyaml__node__s.html">yaml_node_s</a> <a class="el" href="structyaml__node__s.html">yaml_node_t</a></td>
+ </tr>
+ </table>
+</div>
+<div class="memdoc">
+
+<p>The forward definition of a document node structure. </p>
+
+</div>
+</div>
+<a class="anchor" id="ga7cc3581582e778b00c04e99cd3656860"></a><!-- doxytag: member="yaml.h::yaml_node_item_t" ref="ga7cc3581582e778b00c04e99cd3656860" args="" -->
+<div class="memitem">
+<div class="memproto">
+ <table class="memname">
+ <tr>
+ <td class="memname">typedef int <a class="el" href="group__nodes.html#ga7cc3581582e778b00c04e99cd3656860">yaml_node_item_t</a></td>
+ </tr>
+ </table>
+</div>
+<div class="memdoc">
+
+<p>An element of a sequence node. </p>
+
+</div>
+</div>
+<a class="anchor" id="ga90f1c8b83c5c38dc4016afc1cc2050c4"></a><!-- doxytag: member="yaml.h::yaml_node_pair_t" ref="ga90f1c8b83c5c38dc4016afc1cc2050c4" args="" -->
+<div class="memitem">
+<div class="memproto">
+ <table class="memname">
+ <tr>
+ <td class="memname">typedef struct <a class="el" href="structyaml__node__pair__s.html">yaml_node_pair_s</a> <a class="el" href="structyaml__node__pair__s.html">yaml_node_pair_t</a></td>
+ </tr>
+ </table>
+</div>
+<div class="memdoc">
+
+<p>An element of a mapping node. </p>
+
+</div>
+</div>
+<a class="anchor" id="gad94e064e95baeb22e4f7acc7804e8479"></a><!-- doxytag: member="yaml.h::yaml_document_t" ref="gad94e064e95baeb22e4f7acc7804e8479" args="" -->
+<div class="memitem">
+<div class="memproto">
+ <table class="memname">
+ <tr>
+ <td class="memname">typedef struct <a class="el" href="structyaml__document__s.html">yaml_document_s</a> <a class="el" href="structyaml__document__s.html">yaml_document_t</a></td>
+ </tr>
+ </table>
+</div>
+<div class="memdoc">
+
+<p>The document structure. </p>
+
+</div>
+</div>
+<hr/><h2>Enumeration Type Documentation</h2>
+<a class="anchor" id="ga0897d4b6bdd1b56c7a5fa0ff17b4f798"></a><!-- doxytag: member="yaml.h::yaml_node_type_e" ref="ga0897d4b6bdd1b56c7a5fa0ff17b4f798" args="" -->
+<div class="memitem">
+<div class="memproto">
+ <table class="memname">
+ <tr>
+ <td class="memname">enum <a class="el" href="group__nodes.html#ga0897d4b6bdd1b56c7a5fa0ff17b4f798">yaml_node_type_e</a></td>
+ </tr>
+ </table>
+</div>
+<div class="memdoc">
+
+<p>Node types. </p>
+<dl><dt><b>Enumerator: </b></dt><dd><table border="0" cellspacing="2" cellpadding="0">
+<tr><td valign="top"><em><a class="anchor" id="gga0897d4b6bdd1b56c7a5fa0ff17b4f798a0fa87c0e89c4d4136cb47165e6917739"></a><!-- doxytag: member="YAML_NO_NODE" ref="gga0897d4b6bdd1b56c7a5fa0ff17b4f798a0fa87c0e89c4d4136cb47165e6917739" args="" -->YAML_NO_NODE</em>&nbsp;</td><td>
+<p>An empty node. </p>
+</td></tr>
+<tr><td valign="top"><em><a class="anchor" id="gga0897d4b6bdd1b56c7a5fa0ff17b4f798a413ec8ce6b728c9ace703d194b370a45"></a><!-- doxytag: member="YAML_SCALAR_NODE" ref="gga0897d4b6bdd1b56c7a5fa0ff17b4f798a413ec8ce6b728c9ace703d194b370a45" args="" -->YAML_SCALAR_NODE</em>&nbsp;</td><td>
+<p>A scalar node. </p>
+</td></tr>
+<tr><td valign="top"><em><a class="anchor" id="gga0897d4b6bdd1b56c7a5fa0ff17b4f798a6c03b52f7ee737982eac5e4001faac15"></a><!-- doxytag: member="YAML_SEQUENCE_NODE" ref="gga0897d4b6bdd1b56c7a5fa0ff17b4f798a6c03b52f7ee737982eac5e4001faac15" args="" -->YAML_SEQUENCE_NODE</em>&nbsp;</td><td>
+<p>A sequence node. </p>
+</td></tr>
+<tr><td valign="top"><em><a class="anchor" id="gga0897d4b6bdd1b56c7a5fa0ff17b4f798ac1a08580e3a70973583fc85e3e097ee6"></a><!-- doxytag: member="YAML_MAPPING_NODE" ref="gga0897d4b6bdd1b56c7a5fa0ff17b4f798ac1a08580e3a70973583fc85e3e097ee6" args="" -->YAML_MAPPING_NODE</em>&nbsp;</td><td>
+<p>A mapping node. </p>
+</td></tr>
+</table>
+</dd>
+</dl>
+
+</div>
+</div>
+<hr/><h2>Function Documentation</h2>
+<a class="anchor" id="ga62a485c96f3b7962436a0da5e6f3cc89"></a><!-- doxytag: member="yaml.h::yaml_document_initialize" ref="ga62a485c96f3b7962436a0da5e6f3cc89" args="(yaml_document_t *document, yaml_version_directive_t *version_directive, yaml_tag_directive_t *tag_directives_start, yaml_tag_directive_t *tag_directives_end, int start_implicit, int end_implicit)" -->
+<div class="memitem">
+<div class="memproto">
+ <table class="memname">
+ <tr>
+ <td class="memname">int yaml_document_initialize </td>
+ <td>(</td>
+ <td class="paramtype"><a class="el" href="structyaml__document__s.html">yaml_document_t</a> *&nbsp;</td>
+ <td class="paramname"> <em>document</em>, </td>
+ </tr>
+ <tr>
+ <td class="paramkey"></td>
+ <td></td>
+ <td class="paramtype"><a class="el" href="structyaml__version__directive__s.html">yaml_version_directive_t</a> *&nbsp;</td>
+ <td class="paramname"> <em>version_directive</em>, </td>
+ </tr>
+ <tr>
+ <td class="paramkey"></td>
+ <td></td>
+ <td class="paramtype"><a class="el" href="structyaml__tag__directive__s.html">yaml_tag_directive_t</a> *&nbsp;</td>
+ <td class="paramname"> <em>tag_directives_start</em>, </td>
+ </tr>
+ <tr>
+ <td class="paramkey"></td>
+ <td></td>
+ <td class="paramtype"><a class="el" href="structyaml__tag__directive__s.html">yaml_tag_directive_t</a> *&nbsp;</td>
+ <td class="paramname"> <em>tag_directives_end</em>, </td>
+ </tr>
+ <tr>
+ <td class="paramkey"></td>
+ <td></td>
+ <td class="paramtype">int&nbsp;</td>
+ <td class="paramname"> <em>start_implicit</em>, </td>
+ </tr>
+ <tr>
+ <td class="paramkey"></td>
+ <td></td>
+ <td class="paramtype">int&nbsp;</td>
+ <td class="paramname"> <em>end_implicit</em></td><td>&nbsp;</td>
+ </tr>
+ <tr>
+ <td></td>
+ <td>)</td>
+ <td></td><td></td><td></td>
+ </tr>
+ </table>
+</div>
+<div class="memdoc">
+
+<p>Create a YAML document. </p>
+<dl><dt><b>Parameters:</b></dt><dd>
+ <table border="0" cellspacing="2" cellpadding="0">
+ <tr><td valign="top"><tt>[out]</tt>&nbsp;</td><td valign="top"><em>document</em>&nbsp;</td><td>An empty document object. </td></tr>
+ <tr><td valign="top"><tt>[in]</tt>&nbsp;</td><td valign="top"><em>version_directive</em>&nbsp;</td><td>The YAML directive value or <code>NULL</code>. </td></tr>
+ <tr><td valign="top"><tt>[in]</tt>&nbsp;</td><td valign="top"><em>tag_directives_start</em>&nbsp;</td><td>The beginning of the TAG directives list. </td></tr>
+ <tr><td valign="top"><tt>[in]</tt>&nbsp;</td><td valign="top"><em>tag_directives_end</em>&nbsp;</td><td>The end of the TAG directives list. </td></tr>
+ <tr><td valign="top"><tt>[in]</tt>&nbsp;</td><td valign="top"><em>start_implicit</em>&nbsp;</td><td>If the document start indicator is implicit. </td></tr>
+ <tr><td valign="top"><tt>[in]</tt>&nbsp;</td><td valign="top"><em>end_implicit</em>&nbsp;</td><td>If the document end indicator is implicit.</td></tr>
+ </table>
+ </dd>
+</dl>
+<dl class="return"><dt><b>Returns:</b></dt><dd><code>1</code> if the function succeeded, <code>0</code> on error. </dd></dl>
+
+</div>
+</div>
+<a class="anchor" id="ga2754b1544fb4e110e83fafbc708b0672"></a><!-- doxytag: member="yaml.h::yaml_document_delete" ref="ga2754b1544fb4e110e83fafbc708b0672" args="(yaml_document_t *document)" -->
+<div class="memitem">
+<div class="memproto">
+ <table class="memname">
+ <tr>
+ <td class="memname">void yaml_document_delete </td>
+ <td>(</td>
+ <td class="paramtype"><a class="el" href="structyaml__document__s.html">yaml_document_t</a> *&nbsp;</td>
+ <td class="paramname"> <em>document</em></td>
+ <td>&nbsp;)&nbsp;</td>
+ <td></td>
+ </tr>
+ </table>
+</div>
+<div class="memdoc">
+
+<p>Delete a YAML document and all its nodes. </p>
+<dl><dt><b>Parameters:</b></dt><dd>
+ <table border="0" cellspacing="2" cellpadding="0">
+ <tr><td valign="top"><tt>[in,out]</tt>&nbsp;</td><td valign="top"><em>document</em>&nbsp;</td><td>A document object. </td></tr>
+ </table>
+ </dd>
+</dl>
+
+</div>
+</div>
+<a class="anchor" id="gafa1feabc9747dbded4dca24e27d3c21a"></a><!-- doxytag: member="yaml.h::yaml_document_get_node" ref="gafa1feabc9747dbded4dca24e27d3c21a" args="(yaml_document_t *document, int index)" -->
+<div class="memitem">
+<div class="memproto">
+ <table class="memname">
+ <tr>
+ <td class="memname"><a class="el" href="structyaml__node__s.html">yaml_node_t</a>* yaml_document_get_node </td>
+ <td>(</td>
+ <td class="paramtype"><a class="el" href="structyaml__document__s.html">yaml_document_t</a> *&nbsp;</td>
+ <td class="paramname"> <em>document</em>, </td>
+ </tr>
+ <tr>
+ <td class="paramkey"></td>
+ <td></td>
+ <td class="paramtype">int&nbsp;</td>
+ <td class="paramname"> <em>index</em></td><td>&nbsp;</td>
+ </tr>
+ <tr>
+ <td></td>
+ <td>)</td>
+ <td></td><td></td><td></td>
+ </tr>
+ </table>
+</div>
+<div class="memdoc">
+
+<p>Get a node of a YAML document. </p>
+<p>The pointer returned by this function is valid until any of the functions modifying the documents are called.</p>
+<dl><dt><b>Parameters:</b></dt><dd>
+ <table border="0" cellspacing="2" cellpadding="0">
+ <tr><td valign="top"><tt>[in]</tt>&nbsp;</td><td valign="top"><em>document</em>&nbsp;</td><td>A document object. </td></tr>
+ <tr><td valign="top"><tt>[in]</tt>&nbsp;</td><td valign="top"><em>index</em>&nbsp;</td><td>The node id.</td></tr>
+ </table>
+ </dd>
+</dl>
+<dl class="return"><dt><b>Returns:</b></dt><dd>the node objct or <code>NULL</code> if <code>node_id</code> is out of range. </dd></dl>
+
+</div>
+</div>
+<a class="anchor" id="ga40eeaa68fb2f3be34c4fe34e7597d324"></a><!-- doxytag: member="yaml.h::yaml_document_get_root_node" ref="ga40eeaa68fb2f3be34c4fe34e7597d324" args="(yaml_document_t *document)" -->
+<div class="memitem">
+<div class="memproto">
+ <table class="memname">
+ <tr>
+ <td class="memname"><a class="el" href="structyaml__node__s.html">yaml_node_t</a>* yaml_document_get_root_node </td>
+ <td>(</td>
+ <td class="paramtype"><a class="el" href="structyaml__document__s.html">yaml_document_t</a> *&nbsp;</td>
+ <td class="paramname"> <em>document</em></td>
+ <td>&nbsp;)&nbsp;</td>
+ <td></td>
+ </tr>
+ </table>
+</div>
+<div class="memdoc">
+
+<p>Get the root of a YAML document node. </p>
+<p>The root object is the first object added to the document.</p>
+<p>The pointer returned by this function is valid until any of the functions modifying the documents are called.</p>
+<p>An empty document produced by the parser signifies the end of a YAML stream.</p>
+<dl><dt><b>Parameters:</b></dt><dd>
+ <table border="0" cellspacing="2" cellpadding="0">
+ <tr><td valign="top"><tt>[in]</tt>&nbsp;</td><td valign="top"><em>document</em>&nbsp;</td><td>A document object.</td></tr>
+ </table>
+ </dd>
+</dl>
+<dl class="return"><dt><b>Returns:</b></dt><dd>the node object or <code>NULL</code> if the document is empty. </dd></dl>
+
+</div>
+</div>
+<a class="anchor" id="ga45dab8b983b58a005557d4b01f5057b0"></a><!-- doxytag: member="yaml.h::yaml_document_add_scalar" ref="ga45dab8b983b58a005557d4b01f5057b0" args="(yaml_document_t *document, yaml_char_t *tag, yaml_char_t *value, int length, yaml_scalar_style_t style)" -->
+<div class="memitem">
+<div class="memproto">
+ <table class="memname">
+ <tr>
+ <td class="memname">int yaml_document_add_scalar </td>
+ <td>(</td>
+ <td class="paramtype"><a class="el" href="structyaml__document__s.html">yaml_document_t</a> *&nbsp;</td>
+ <td class="paramname"> <em>document</em>, </td>
+ </tr>
+ <tr>
+ <td class="paramkey"></td>
+ <td></td>
+ <td class="paramtype"><a class="el" href="group__basic.html#gaf8657e81f0b8b05d1a081001fc6cb8bd">yaml_char_t</a> *&nbsp;</td>
+ <td class="paramname"> <em>tag</em>, </td>
+ </tr>
+ <tr>
+ <td class="paramkey"></td>
+ <td></td>
+ <td class="paramtype"><a class="el" href="group__basic.html#gaf8657e81f0b8b05d1a081001fc6cb8bd">yaml_char_t</a> *&nbsp;</td>
+ <td class="paramname"> <em>value</em>, </td>
+ </tr>
+ <tr>
+ <td class="paramkey"></td>
+ <td></td>
+ <td class="paramtype">int&nbsp;</td>
+ <td class="paramname"> <em>length</em>, </td>
+ </tr>
+ <tr>
+ <td class="paramkey"></td>
+ <td></td>
+ <td class="paramtype"><a class="el" href="group__styles.html#ga3fa6405631e1afe5bd5c488a6c5e8065">yaml_scalar_style_t</a>&nbsp;</td>
+ <td class="paramname"> <em>style</em></td><td>&nbsp;</td>
+ </tr>
+ <tr>
+ <td></td>
+ <td>)</td>
+ <td></td><td></td><td></td>
+ </tr>
+ </table>
+</div>
+<div class="memdoc">
+
+<p>Create a SCALAR node and attach it to the document. </p>
+<p>The <em>style</em> argument may be ignored by the emitter.</p>
+<dl><dt><b>Parameters:</b></dt><dd>
+ <table border="0" cellspacing="2" cellpadding="0">
+ <tr><td valign="top"><tt>[in,out]</tt>&nbsp;</td><td valign="top"><em>document</em>&nbsp;</td><td>A document object. </td></tr>
+ <tr><td valign="top"><tt>[in]</tt>&nbsp;</td><td valign="top"><em>tag</em>&nbsp;</td><td>The scalar tag. </td></tr>
+ <tr><td valign="top"><tt>[in]</tt>&nbsp;</td><td valign="top"><em>value</em>&nbsp;</td><td>The scalar value. </td></tr>
+ <tr><td valign="top"><tt>[in]</tt>&nbsp;</td><td valign="top"><em>length</em>&nbsp;</td><td>The length of the scalar value. </td></tr>
+ <tr><td valign="top"><tt>[in]</tt>&nbsp;</td><td valign="top"><em>style</em>&nbsp;</td><td>The scalar style.</td></tr>
+ </table>
+ </dd>
+</dl>
+<dl class="return"><dt><b>Returns:</b></dt><dd>the node id or <code>0</code> on error. </dd></dl>
+
+</div>
+</div>
+<a class="anchor" id="ga83b2f7fdd9a439397a42016bddad7786"></a><!-- doxytag: member="yaml.h::yaml_document_add_sequence" ref="ga83b2f7fdd9a439397a42016bddad7786" args="(yaml_document_t *document, yaml_char_t *tag, yaml_sequence_style_t style)" -->
+<div class="memitem">
+<div class="memproto">
+ <table class="memname">
+ <tr>
+ <td class="memname">int yaml_document_add_sequence </td>
+ <td>(</td>
+ <td class="paramtype"><a class="el" href="structyaml__document__s.html">yaml_document_t</a> *&nbsp;</td>
+ <td class="paramname"> <em>document</em>, </td>
+ </tr>
+ <tr>
+ <td class="paramkey"></td>
+ <td></td>
+ <td class="paramtype"><a class="el" href="group__basic.html#gaf8657e81f0b8b05d1a081001fc6cb8bd">yaml_char_t</a> *&nbsp;</td>
+ <td class="paramname"> <em>tag</em>, </td>
+ </tr>
+ <tr>
+ <td class="paramkey"></td>
+ <td></td>
+ <td class="paramtype"><a class="el" href="group__styles.html#ga58a1123d271e56c72de6abf852ac4dc2">yaml_sequence_style_t</a>&nbsp;</td>
+ <td class="paramname"> <em>style</em></td><td>&nbsp;</td>
+ </tr>
+ <tr>
+ <td></td>
+ <td>)</td>
+ <td></td><td></td><td></td>
+ </tr>
+ </table>
+</div>
+<div class="memdoc">
+
+<p>Create a SEQUENCE node and attach it to the document. </p>
+<p>The <em>style</em> argument may be ignored by the emitter.</p>
+<dl><dt><b>Parameters:</b></dt><dd>
+ <table border="0" cellspacing="2" cellpadding="0">
+ <tr><td valign="top"><tt>[in,out]</tt>&nbsp;</td><td valign="top"><em>document</em>&nbsp;</td><td>A document object. </td></tr>
+ <tr><td valign="top"><tt>[in]</tt>&nbsp;</td><td valign="top"><em>tag</em>&nbsp;</td><td>The sequence tag. </td></tr>
+ <tr><td valign="top"><tt>[in]</tt>&nbsp;</td><td valign="top"><em>style</em>&nbsp;</td><td>The sequence style.</td></tr>
+ </table>
+ </dd>
+</dl>
+<dl class="return"><dt><b>Returns:</b></dt><dd>the node id or <code>0</code> on error. </dd></dl>
+
+</div>
+</div>
+<a class="anchor" id="ga45a9f8288704f99cd81dc5cb31329d34"></a><!-- doxytag: member="yaml.h::yaml_document_add_mapping" ref="ga45a9f8288704f99cd81dc5cb31329d34" args="(yaml_document_t *document, yaml_char_t *tag, yaml_mapping_style_t style)" -->
+<div class="memitem">
+<div class="memproto">
+ <table class="memname">
+ <tr>
+ <td class="memname">int yaml_document_add_mapping </td>
+ <td>(</td>
+ <td class="paramtype"><a class="el" href="structyaml__document__s.html">yaml_document_t</a> *&nbsp;</td>
+ <td class="paramname"> <em>document</em>, </td>
+ </tr>
+ <tr>
+ <td class="paramkey"></td>
+ <td></td>
+ <td class="paramtype"><a class="el" href="group__basic.html#gaf8657e81f0b8b05d1a081001fc6cb8bd">yaml_char_t</a> *&nbsp;</td>
+ <td class="paramname"> <em>tag</em>, </td>
+ </tr>
+ <tr>
+ <td class="paramkey"></td>
+ <td></td>
+ <td class="paramtype"><a class="el" href="group__styles.html#gab47523846a5c5960e07367a28ea9750a">yaml_mapping_style_t</a>&nbsp;</td>
+ <td class="paramname"> <em>style</em></td><td>&nbsp;</td>
+ </tr>
+ <tr>
+ <td></td>
+ <td>)</td>
+ <td></td><td></td><td></td>
+ </tr>
+ </table>
+</div>
+<div class="memdoc">
+
+<p>Create a MAPPING node and attach it to the document. </p>
+<p>The <em>style</em> argument may be ignored by the emitter.</p>
+<dl><dt><b>Parameters:</b></dt><dd>
+ <table border="0" cellspacing="2" cellpadding="0">
+ <tr><td valign="top"><tt>[in,out]</tt>&nbsp;</td><td valign="top"><em>document</em>&nbsp;</td><td>A document object. </td></tr>
+ <tr><td valign="top"><tt>[in]</tt>&nbsp;</td><td valign="top"><em>tag</em>&nbsp;</td><td>The sequence tag. </td></tr>
+ <tr><td valign="top"><tt>[in]</tt>&nbsp;</td><td valign="top"><em>style</em>&nbsp;</td><td>The sequence style.</td></tr>
+ </table>
+ </dd>
+</dl>
+<dl class="return"><dt><b>Returns:</b></dt><dd>the node id or <code>0</code> on error. </dd></dl>
+
+</div>
+</div>
+<a class="anchor" id="ga16435917cd6c0261cd390fa8cf173b1b"></a><!-- doxytag: member="yaml.h::yaml_document_append_sequence_item" ref="ga16435917cd6c0261cd390fa8cf173b1b" args="(yaml_document_t *document, int sequence, int item)" -->
+<div class="memitem">
+<div class="memproto">
+ <table class="memname">
+ <tr>
+ <td class="memname">int yaml_document_append_sequence_item </td>
+ <td>(</td>
+ <td class="paramtype"><a class="el" href="structyaml__document__s.html">yaml_document_t</a> *&nbsp;</td>
+ <td class="paramname"> <em>document</em>, </td>
+ </tr>
+ <tr>
+ <td class="paramkey"></td>
+ <td></td>
+ <td class="paramtype">int&nbsp;</td>
+ <td class="paramname"> <em>sequence</em>, </td>
+ </tr>
+ <tr>
+ <td class="paramkey"></td>
+ <td></td>
+ <td class="paramtype">int&nbsp;</td>
+ <td class="paramname"> <em>item</em></td><td>&nbsp;</td>
+ </tr>
+ <tr>
+ <td></td>
+ <td>)</td>
+ <td></td><td></td><td></td>
+ </tr>
+ </table>
+</div>
+<div class="memdoc">
+
+<p>Add an item to a SEQUENCE node. </p>
+<dl><dt><b>Parameters:</b></dt><dd>
+ <table border="0" cellspacing="2" cellpadding="0">
+ <tr><td valign="top"><tt>[in,out]</tt>&nbsp;</td><td valign="top"><em>document</em>&nbsp;</td><td>A document object. </td></tr>
+ <tr><td valign="top"><tt>[in]</tt>&nbsp;</td><td valign="top"><em>sequence</em>&nbsp;</td><td>The sequence node id. </td></tr>
+ <tr><td valign="top"><tt>[in]</tt>&nbsp;</td><td valign="top"><em>item</em>&nbsp;</td><td>The item node id.</td></tr>
+ </table>
+ </dd>
+</dl>
+<dl class="return"><dt><b>Returns:</b></dt><dd><code>1</code> if the function succeeded, <code>0</code> on error. </dd></dl>
+
+</div>
+</div>
+<a class="anchor" id="ga2db27002d8a9ae06b1729d0ee06553d2"></a><!-- doxytag: member="yaml.h::yaml_document_append_mapping_pair" ref="ga2db27002d8a9ae06b1729d0ee06553d2" args="(yaml_document_t *document, int mapping, int key, int value)" -->
+<div class="memitem">
+<div class="memproto">
+ <table class="memname">
+ <tr>
+ <td class="memname">int yaml_document_append_mapping_pair </td>
+ <td>(</td>
+ <td class="paramtype"><a class="el" href="structyaml__document__s.html">yaml_document_t</a> *&nbsp;</td>
+ <td class="paramname"> <em>document</em>, </td>
+ </tr>
+ <tr>
+ <td class="paramkey"></td>
+ <td></td>
+ <td class="paramtype">int&nbsp;</td>
+ <td class="paramname"> <em>mapping</em>, </td>
+ </tr>
+ <tr>
+ <td class="paramkey"></td>
+ <td></td>
+ <td class="paramtype">int&nbsp;</td>
+ <td class="paramname"> <em>key</em>, </td>
+ </tr>
+ <tr>
+ <td class="paramkey"></td>
+ <td></td>
+ <td class="paramtype">int&nbsp;</td>
+ <td class="paramname"> <em>value</em></td><td>&nbsp;</td>
+ </tr>
+ <tr>
+ <td></td>
+ <td>)</td>
+ <td></td><td></td><td></td>
+ </tr>
+ </table>
+</div>
+<div class="memdoc">
+
+<p>Add a pair of a key and a value to a MAPPING node. </p>
+<dl><dt><b>Parameters:</b></dt><dd>
+ <table border="0" cellspacing="2" cellpadding="0">
+ <tr><td valign="top"><tt>[in,out]</tt>&nbsp;</td><td valign="top"><em>document</em>&nbsp;</td><td>A document object. </td></tr>
+ <tr><td valign="top"><tt>[in]</tt>&nbsp;</td><td valign="top"><em>mapping</em>&nbsp;</td><td>The mapping node id. </td></tr>
+ <tr><td valign="top"><tt>[in]</tt>&nbsp;</td><td valign="top"><em>key</em>&nbsp;</td><td>The key node id. </td></tr>
+ <tr><td valign="top"><tt>[in]</tt>&nbsp;</td><td valign="top"><em>value</em>&nbsp;</td><td>The value node id.</td></tr>
+ </table>
+ </dd>
+</dl>
+<dl class="return"><dt><b>Returns:</b></dt><dd><code>1</code> if the function succeeded, <code>0</code> on error. </dd></dl>
+
+</div>
+</div>
+</div>
+<hr class="footer"/><address class="footer"><small>Generated on Mon May 30 2011 22:00:00 for yaml by&nbsp;
+<a href="http://www.doxygen.org/index.html">
+<img class="footer" src="doxygen.png" alt="doxygen"/></a> 1.7.1 </small></address>
+</body>
+</html>
diff --git a/contrib/libyaml/doc/html/group__parser.html b/contrib/libyaml/doc/html/group__parser.html
new file mode 100644
index 0000000..dfcfa64
--- /dev/null
+++ b/contrib/libyaml/doc/html/group__parser.html
@@ -0,0 +1,606 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head>
+<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/>
+<title>yaml: Parser Definitions</title>
+<link href="tabs.css" rel="stylesheet" type="text/css"/>
+<link href="doxygen.css" rel="stylesheet" type="text/css"/>
+</head>
+<body>
+<!-- Generated by Doxygen 1.7.1 -->
+<div class="navigation" id="top">
+ <div class="tabs">
+ <ul class="tablist">
+ <li><a href="index.html"><span>Main&nbsp;Page</span></a></li>
+ <li><a href="modules.html"><span>Modules</span></a></li>
+ <li><a href="annotated.html"><span>Data&nbsp;Structures</span></a></li>
+ <li><a href="files.html"><span>Files</span></a></li>
+ </ul>
+ </div>
+</div>
+<div class="header">
+ <div class="summary">
+<a href="#nested-classes">Data Structures</a> &#124;
+<a href="#typedef-members">Typedefs</a> &#124;
+<a href="#enum-members">Enumerations</a> &#124;
+<a href="#func-members">Functions</a> </div>
+ <div class="headertitle">
+<h1>Parser Definitions</h1> </div>
+</div>
+<div class="contents">
+<table class="memberdecls">
+<tr><td colspan="2"><h2><a name="nested-classes"></a>
+Data Structures</h2></td></tr>
+<tr><td class="memItemLeft" align="right" valign="top">struct &nbsp;</td><td class="memItemRight" valign="bottom"><a class="el" href="structyaml__simple__key__s.html">yaml_simple_key_s</a></td></tr>
+<tr><td class="mdescLeft">&nbsp;</td><td class="mdescRight">This structure holds information about a potential simple key. <a href="structyaml__simple__key__s.html#_details">More...</a><br/></td></tr>
+<tr><td class="memItemLeft" align="right" valign="top">struct &nbsp;</td><td class="memItemRight" valign="bottom"><a class="el" href="structyaml__alias__data__s.html">yaml_alias_data_s</a></td></tr>
+<tr><td class="mdescLeft">&nbsp;</td><td class="mdescRight">This structure holds aliases data. <a href="structyaml__alias__data__s.html#_details">More...</a><br/></td></tr>
+<tr><td class="memItemLeft" align="right" valign="top">struct &nbsp;</td><td class="memItemRight" valign="bottom"><a class="el" href="structyaml__parser__s.html">yaml_parser_s</a></td></tr>
+<tr><td class="mdescLeft">&nbsp;</td><td class="mdescRight">The parser structure. <a href="structyaml__parser__s.html#_details">More...</a><br/></td></tr>
+<tr><td colspan="2"><h2><a name="typedef-members"></a>
+Typedefs</h2></td></tr>
+<tr><td class="memItemLeft" align="right" valign="top">typedef int&nbsp;</td><td class="memItemRight" valign="bottom"><a class="el" href="group__parser.html#ga4982f7e4e001ddb47d2819f38f0cd9d6">yaml_read_handler_t</a> (void *data, unsigned char *buffer, size_t size, size_t *size_read)</td></tr>
+<tr><td class="mdescLeft">&nbsp;</td><td class="mdescRight">The prototype of a read handler. <a href="#ga4982f7e4e001ddb47d2819f38f0cd9d6"></a><br/></td></tr>
+<tr><td class="memItemLeft" align="right" valign="top"><a class="anchor" id="gae5570fbb7ab7c8332cd666f3a9c26591"></a><!-- doxytag: member="parser::yaml_simple_key_t" ref="gae5570fbb7ab7c8332cd666f3a9c26591" args="" -->
+typedef struct <a class="el" href="structyaml__simple__key__s.html">yaml_simple_key_s</a>&nbsp;</td><td class="memItemRight" valign="bottom"><a class="el" href="group__parser.html#gae5570fbb7ab7c8332cd666f3a9c26591">yaml_simple_key_t</a></td></tr>
+<tr><td class="mdescLeft">&nbsp;</td><td class="mdescRight">This structure holds information about a potential simple key. <br/></td></tr>
+<tr><td class="memItemLeft" align="right" valign="top"><a class="anchor" id="ga52b56d3e3cee0f9ba460978802a8c83b"></a><!-- doxytag: member="parser::yaml_parser_state_t" ref="ga52b56d3e3cee0f9ba460978802a8c83b" args="" -->
+typedef enum <a class="el" href="group__parser.html#gad39c19e7b0df6f542ca97806535b57c5">yaml_parser_state_e</a>&nbsp;</td><td class="memItemRight" valign="bottom"><a class="el" href="group__parser.html#ga52b56d3e3cee0f9ba460978802a8c83b">yaml_parser_state_t</a></td></tr>
+<tr><td class="mdescLeft">&nbsp;</td><td class="mdescRight">The states of the parser. <br/></td></tr>
+<tr><td class="memItemLeft" align="right" valign="top"><a class="anchor" id="ga1434228b82f5f90d3c8ccda816e9ca9d"></a><!-- doxytag: member="parser::yaml_alias_data_t" ref="ga1434228b82f5f90d3c8ccda816e9ca9d" args="" -->
+typedef struct <a class="el" href="structyaml__alias__data__s.html">yaml_alias_data_s</a>&nbsp;</td><td class="memItemRight" valign="bottom"><a class="el" href="group__parser.html#ga1434228b82f5f90d3c8ccda816e9ca9d">yaml_alias_data_t</a></td></tr>
+<tr><td class="mdescLeft">&nbsp;</td><td class="mdescRight">This structure holds aliases data. <br/></td></tr>
+<tr><td class="memItemLeft" align="right" valign="top">typedef struct <a class="el" href="structyaml__parser__s.html">yaml_parser_s</a>&nbsp;</td><td class="memItemRight" valign="bottom"><a class="el" href="group__parser.html#gafdc6319cb28a8b8034542b29be85b0c4">yaml_parser_t</a></td></tr>
+<tr><td class="mdescLeft">&nbsp;</td><td class="mdescRight">The parser structure. <a href="#gafdc6319cb28a8b8034542b29be85b0c4"></a><br/></td></tr>
+<tr><td colspan="2"><h2><a name="enum-members"></a>
+Enumerations</h2></td></tr>
+<tr><td class="memItemLeft" align="right" valign="top">enum &nbsp;</td><td class="memItemRight" valign="bottom"><a class="el" href="group__parser.html#gad39c19e7b0df6f542ca97806535b57c5">yaml_parser_state_e</a> { <br/>
+&nbsp;&nbsp;<a class="el" href="group__parser.html#ggad39c19e7b0df6f542ca97806535b57c5ae7b52e16bf002db5cf2944596d8c880e">YAML_PARSE_STREAM_START_STATE</a>,
+<br/>
+&nbsp;&nbsp;<a class="el" href="group__parser.html#ggad39c19e7b0df6f542ca97806535b57c5a8255725d67d5bd3574fc7df4db1c6c84">YAML_PARSE_IMPLICIT_DOCUMENT_START_STATE</a>,
+<br/>
+&nbsp;&nbsp;<a class="el" href="group__parser.html#ggad39c19e7b0df6f542ca97806535b57c5aa06d10f700d245caecfc6074a6c52fde">YAML_PARSE_DOCUMENT_START_STATE</a>,
+<br/>
+&nbsp;&nbsp;<a class="el" href="group__parser.html#ggad39c19e7b0df6f542ca97806535b57c5ae444c7652c8029b0ef80068eaaaa3d4d">YAML_PARSE_DOCUMENT_CONTENT_STATE</a>,
+<br/>
+&nbsp;&nbsp;<a class="el" href="group__parser.html#ggad39c19e7b0df6f542ca97806535b57c5aeef06d7f13fa4501146a5b9876c98239">YAML_PARSE_DOCUMENT_END_STATE</a>,
+<br/>
+&nbsp;&nbsp;<a class="el" href="group__parser.html#ggad39c19e7b0df6f542ca97806535b57c5ae1893c0835bacf05cdc21ed181fb75f1">YAML_PARSE_BLOCK_NODE_STATE</a>,
+<br/>
+&nbsp;&nbsp;<a class="el" href="group__parser.html#ggad39c19e7b0df6f542ca97806535b57c5acbd390af0d3919fe0382d03c284ff3b5">YAML_PARSE_BLOCK_NODE_OR_INDENTLESS_SEQUENCE_STATE</a>,
+<br/>
+&nbsp;&nbsp;<a class="el" href="group__parser.html#ggad39c19e7b0df6f542ca97806535b57c5a5bb321f9d18c5b208a71c04bbcbd1d01">YAML_PARSE_FLOW_NODE_STATE</a>,
+<br/>
+&nbsp;&nbsp;<a class="el" href="group__parser.html#ggad39c19e7b0df6f542ca97806535b57c5a5bb5f95fc5f1a258ee8e9db0ed25b2d9">YAML_PARSE_BLOCK_SEQUENCE_FIRST_ENTRY_STATE</a>,
+<br/>
+&nbsp;&nbsp;<a class="el" href="group__parser.html#ggad39c19e7b0df6f542ca97806535b57c5a8a6cb1f12fe08eee7fc2fa854dbd5b1a">YAML_PARSE_BLOCK_SEQUENCE_ENTRY_STATE</a>,
+<br/>
+&nbsp;&nbsp;<a class="el" href="group__parser.html#ggad39c19e7b0df6f542ca97806535b57c5af7095f2141cf9887489e832f0ec61fbd">YAML_PARSE_INDENTLESS_SEQUENCE_ENTRY_STATE</a>,
+<br/>
+&nbsp;&nbsp;<a class="el" href="group__parser.html#ggad39c19e7b0df6f542ca97806535b57c5afebcb5bbd67d112d9ecfa633155f0644">YAML_PARSE_BLOCK_MAPPING_FIRST_KEY_STATE</a>,
+<br/>
+&nbsp;&nbsp;<a class="el" href="group__parser.html#ggad39c19e7b0df6f542ca97806535b57c5a2df81c86e90b874b415ecb19e72efe45">YAML_PARSE_BLOCK_MAPPING_KEY_STATE</a>,
+<br/>
+&nbsp;&nbsp;<a class="el" href="group__parser.html#ggad39c19e7b0df6f542ca97806535b57c5ae94acf5685fa1538b225413f154465c2">YAML_PARSE_BLOCK_MAPPING_VALUE_STATE</a>,
+<br/>
+&nbsp;&nbsp;<a class="el" href="group__parser.html#ggad39c19e7b0df6f542ca97806535b57c5a3f54830989c12cc4a63494df792eeb08">YAML_PARSE_FLOW_SEQUENCE_FIRST_ENTRY_STATE</a>,
+<br/>
+&nbsp;&nbsp;<a class="el" href="group__parser.html#ggad39c19e7b0df6f542ca97806535b57c5a0e50f3841eb0d37ad159e64c4a9a1171">YAML_PARSE_FLOW_SEQUENCE_ENTRY_STATE</a>,
+<br/>
+&nbsp;&nbsp;<a class="el" href="group__parser.html#ggad39c19e7b0df6f542ca97806535b57c5a563e11601cf3a1d2a3efc1feb1b696a3">YAML_PARSE_FLOW_SEQUENCE_ENTRY_MAPPING_KEY_STATE</a>,
+<br/>
+&nbsp;&nbsp;<a class="el" href="group__parser.html#ggad39c19e7b0df6f542ca97806535b57c5a9e5ebb4bee4541e7a7025689c7fc66eb">YAML_PARSE_FLOW_SEQUENCE_ENTRY_MAPPING_VALUE_STATE</a>,
+<br/>
+&nbsp;&nbsp;<a class="el" href="group__parser.html#ggad39c19e7b0df6f542ca97806535b57c5a397fd87de9227c64e5308481930b5eeb">YAML_PARSE_FLOW_SEQUENCE_ENTRY_MAPPING_END_STATE</a>,
+<br/>
+&nbsp;&nbsp;<a class="el" href="group__parser.html#ggad39c19e7b0df6f542ca97806535b57c5a91ac4bbb6629e2b768a3305fb707b7cd">YAML_PARSE_FLOW_MAPPING_FIRST_KEY_STATE</a>,
+<br/>
+&nbsp;&nbsp;<a class="el" href="group__parser.html#ggad39c19e7b0df6f542ca97806535b57c5a924f8eb891dc7527bf4db594a0b1bff8">YAML_PARSE_FLOW_MAPPING_KEY_STATE</a>,
+<br/>
+&nbsp;&nbsp;<a class="el" href="group__parser.html#ggad39c19e7b0df6f542ca97806535b57c5a3ba351f6cfba029248ada2c0720246d4">YAML_PARSE_FLOW_MAPPING_VALUE_STATE</a>,
+<br/>
+&nbsp;&nbsp;<a class="el" href="group__parser.html#ggad39c19e7b0df6f542ca97806535b57c5a5a8ec0af5c3314c1ad5e0569b6a5d6d2">YAML_PARSE_FLOW_MAPPING_EMPTY_VALUE_STATE</a>,
+<br/>
+&nbsp;&nbsp;<a class="el" href="group__parser.html#ggad39c19e7b0df6f542ca97806535b57c5a51fd3d45693e2240251996def375a2a2">YAML_PARSE_END_STATE</a>
+<br/>
+ }</td></tr>
+<tr><td class="mdescLeft">&nbsp;</td><td class="mdescRight"><p>The states of the parser. </p>
+ <a href="group__parser.html#gad39c19e7b0df6f542ca97806535b57c5">More...</a><br/></td></tr>
+<tr><td colspan="2"><h2><a name="func-members"></a>
+Functions</h2></td></tr>
+<tr><td class="memItemLeft" align="right" valign="top">int&nbsp;</td><td class="memItemRight" valign="bottom"><a class="el" href="group__parser.html#gacc37ceeb5847e38a3fe24eb0c9b53965">yaml_parser_initialize</a> (<a class="el" href="structyaml__parser__s.html">yaml_parser_t</a> *parser)</td></tr>
+<tr><td class="mdescLeft">&nbsp;</td><td class="mdescRight">Initialize a parser. <a href="#gacc37ceeb5847e38a3fe24eb0c9b53965"></a><br/></td></tr>
+<tr><td class="memItemLeft" align="right" valign="top">void&nbsp;</td><td class="memItemRight" valign="bottom"><a class="el" href="group__parser.html#gaa27150107c4667c1024ec0651e2ac26b">yaml_parser_delete</a> (<a class="el" href="structyaml__parser__s.html">yaml_parser_t</a> *parser)</td></tr>
+<tr><td class="mdescLeft">&nbsp;</td><td class="mdescRight">Destroy a parser. <a href="#gaa27150107c4667c1024ec0651e2ac26b"></a><br/></td></tr>
+<tr><td class="memItemLeft" align="right" valign="top">void&nbsp;</td><td class="memItemRight" valign="bottom"><a class="el" href="group__parser.html#ga08a94762bf5f4c61f72c1da0a407df0d">yaml_parser_set_input_string</a> (<a class="el" href="structyaml__parser__s.html">yaml_parser_t</a> *parser, const unsigned char *input, size_t size)</td></tr>
+<tr><td class="mdescLeft">&nbsp;</td><td class="mdescRight">Set a string input. <a href="#ga08a94762bf5f4c61f72c1da0a407df0d"></a><br/></td></tr>
+<tr><td class="memItemLeft" align="right" valign="top">void&nbsp;</td><td class="memItemRight" valign="bottom"><a class="el" href="group__parser.html#gac3f00f8beb2365b1e4569692d64696b6">yaml_parser_set_input_file</a> (<a class="el" href="structyaml__parser__s.html">yaml_parser_t</a> *parser, FILE *file)</td></tr>
+<tr><td class="mdescLeft">&nbsp;</td><td class="mdescRight">Set a file input. <a href="#gac3f00f8beb2365b1e4569692d64696b6"></a><br/></td></tr>
+<tr><td class="memItemLeft" align="right" valign="top">void&nbsp;</td><td class="memItemRight" valign="bottom"><a class="el" href="group__parser.html#gabc67581bfa771a3e787d907d6914b8d9">yaml_parser_set_input</a> (<a class="el" href="structyaml__parser__s.html">yaml_parser_t</a> *parser, <a class="el" href="group__parser.html#ga4982f7e4e001ddb47d2819f38f0cd9d6">yaml_read_handler_t</a> *handler, void *data)</td></tr>
+<tr><td class="mdescLeft">&nbsp;</td><td class="mdescRight">Set a generic input handler. <a href="#gabc67581bfa771a3e787d907d6914b8d9"></a><br/></td></tr>
+<tr><td class="memItemLeft" align="right" valign="top">void&nbsp;</td><td class="memItemRight" valign="bottom"><a class="el" href="group__parser.html#ga9565b64975570ed34612a19adf02ae6a">yaml_parser_set_encoding</a> (<a class="el" href="structyaml__parser__s.html">yaml_parser_t</a> *parser, <a class="el" href="group__basic.html#ga2170996d7e636397b5e6bc0c1b7df7c6">yaml_encoding_t</a> encoding)</td></tr>
+<tr><td class="mdescLeft">&nbsp;</td><td class="mdescRight">Set the source encoding. <a href="#ga9565b64975570ed34612a19adf02ae6a"></a><br/></td></tr>
+<tr><td class="memItemLeft" align="right" valign="top">int&nbsp;</td><td class="memItemRight" valign="bottom"><a class="el" href="group__parser.html#ga6c2144f131ebd600a075d4ba654540f7">yaml_parser_scan</a> (<a class="el" href="structyaml__parser__s.html">yaml_parser_t</a> *parser, <a class="el" href="structyaml__token__s.html">yaml_token_t</a> *token)</td></tr>
+<tr><td class="mdescLeft">&nbsp;</td><td class="mdescRight">Scan the input stream and produce the next token. <a href="#ga6c2144f131ebd600a075d4ba654540f7"></a><br/></td></tr>
+<tr><td class="memItemLeft" align="right" valign="top">int&nbsp;</td><td class="memItemRight" valign="bottom"><a class="el" href="group__parser.html#ga559312fb137533d8b7e07f224fe0ec8f">yaml_parser_parse</a> (<a class="el" href="structyaml__parser__s.html">yaml_parser_t</a> *parser, <a class="el" href="structyaml__event__s.html">yaml_event_t</a> *event)</td></tr>
+<tr><td class="mdescLeft">&nbsp;</td><td class="mdescRight">Parse the input stream and produce the next parsing event. <a href="#ga559312fb137533d8b7e07f224fe0ec8f"></a><br/></td></tr>
+<tr><td class="memItemLeft" align="right" valign="top">int&nbsp;</td><td class="memItemRight" valign="bottom"><a class="el" href="group__parser.html#ga9ef7d6e9494766b5880c389bc431d138">yaml_parser_load</a> (<a class="el" href="structyaml__parser__s.html">yaml_parser_t</a> *parser, <a class="el" href="structyaml__document__s.html">yaml_document_t</a> *document)</td></tr>
+<tr><td class="mdescLeft">&nbsp;</td><td class="mdescRight">Parse the input stream and produce the next YAML document. <a href="#ga9ef7d6e9494766b5880c389bc431d138"></a><br/></td></tr>
+</table>
+<hr/><h2>Typedef Documentation</h2>
+<a class="anchor" id="ga4982f7e4e001ddb47d2819f38f0cd9d6"></a><!-- doxytag: member="yaml.h::yaml_read_handler_t" ref="ga4982f7e4e001ddb47d2819f38f0cd9d6" args="(void *data, unsigned char *buffer, size_t size, size_t *size_read)" -->
+<div class="memitem">
+<div class="memproto">
+ <table class="memname">
+ <tr>
+ <td class="memname">typedef int <a class="el" href="group__parser.html#ga4982f7e4e001ddb47d2819f38f0cd9d6">yaml_read_handler_t</a>(void *data, unsigned char *buffer, size_t size, size_t *size_read)</td>
+ </tr>
+ </table>
+</div>
+<div class="memdoc">
+
+<p>The prototype of a read handler. </p>
+<p>The read handler is called when the parser needs to read more bytes from the source. The handler should write not more than <em>size</em> bytes to the <em>buffer</em>. The number of written bytes should be set to the <em>length</em> variable.</p>
+<dl><dt><b>Parameters:</b></dt><dd>
+ <table border="0" cellspacing="2" cellpadding="0">
+ <tr><td valign="top"><tt>[in,out]</tt>&nbsp;</td><td valign="top"><em>data</em>&nbsp;</td><td>A pointer to an application data specified by <a class="el" href="group__parser.html#gabc67581bfa771a3e787d907d6914b8d9" title="Set a generic input handler.">yaml_parser_set_input()</a>. </td></tr>
+ <tr><td valign="top"><tt>[out]</tt>&nbsp;</td><td valign="top"><em>buffer</em>&nbsp;</td><td>The buffer to write the data from the source. </td></tr>
+ <tr><td valign="top"><tt>[in]</tt>&nbsp;</td><td valign="top"><em>size</em>&nbsp;</td><td>The size of the buffer. </td></tr>
+ <tr><td valign="top"><tt>[out]</tt>&nbsp;</td><td valign="top"><em>size_read</em>&nbsp;</td><td>The actual number of bytes read from the source.</td></tr>
+ </table>
+ </dd>
+</dl>
+<dl class="return"><dt><b>Returns:</b></dt><dd>On success, the handler should return <code>1</code>. If the handler failed, the returned value should be <code>0</code>. On EOF, the handler should set the <em>size_read</em> to <code>0</code> and return <code>1</code>. </dd></dl>
+
+</div>
+</div>
+<a class="anchor" id="gafdc6319cb28a8b8034542b29be85b0c4"></a><!-- doxytag: member="yaml.h::yaml_parser_t" ref="gafdc6319cb28a8b8034542b29be85b0c4" args="" -->
+<div class="memitem">
+<div class="memproto">
+ <table class="memname">
+ <tr>
+ <td class="memname">typedef struct <a class="el" href="structyaml__parser__s.html">yaml_parser_s</a> <a class="el" href="structyaml__parser__s.html">yaml_parser_t</a></td>
+ </tr>
+ </table>
+</div>
+<div class="memdoc">
+
+<p>The parser structure. </p>
+<p>All members are internal. Manage the structure using the <code>yaml_parser_</code> family of functions. </p>
+
+</div>
+</div>
+<hr/><h2>Enumeration Type Documentation</h2>
+<a class="anchor" id="gad39c19e7b0df6f542ca97806535b57c5"></a><!-- doxytag: member="yaml.h::yaml_parser_state_e" ref="gad39c19e7b0df6f542ca97806535b57c5" args="" -->
+<div class="memitem">
+<div class="memproto">
+ <table class="memname">
+ <tr>
+ <td class="memname">enum <a class="el" href="group__parser.html#gad39c19e7b0df6f542ca97806535b57c5">yaml_parser_state_e</a></td>
+ </tr>
+ </table>
+</div>
+<div class="memdoc">
+
+<p>The states of the parser. </p>
+<dl><dt><b>Enumerator: </b></dt><dd><table border="0" cellspacing="2" cellpadding="0">
+<tr><td valign="top"><em><a class="anchor" id="ggad39c19e7b0df6f542ca97806535b57c5ae7b52e16bf002db5cf2944596d8c880e"></a><!-- doxytag: member="YAML_PARSE_STREAM_START_STATE" ref="ggad39c19e7b0df6f542ca97806535b57c5ae7b52e16bf002db5cf2944596d8c880e" args="" -->YAML_PARSE_STREAM_START_STATE</em>&nbsp;</td><td>
+<p>Expect STREAM-START. </p>
+</td></tr>
+<tr><td valign="top"><em><a class="anchor" id="ggad39c19e7b0df6f542ca97806535b57c5a8255725d67d5bd3574fc7df4db1c6c84"></a><!-- doxytag: member="YAML_PARSE_IMPLICIT_DOCUMENT_START_STATE" ref="ggad39c19e7b0df6f542ca97806535b57c5a8255725d67d5bd3574fc7df4db1c6c84" args="" -->YAML_PARSE_IMPLICIT_DOCUMENT_START_STATE</em>&nbsp;</td><td>
+<p>Expect the beginning of an implicit document. </p>
+</td></tr>
+<tr><td valign="top"><em><a class="anchor" id="ggad39c19e7b0df6f542ca97806535b57c5aa06d10f700d245caecfc6074a6c52fde"></a><!-- doxytag: member="YAML_PARSE_DOCUMENT_START_STATE" ref="ggad39c19e7b0df6f542ca97806535b57c5aa06d10f700d245caecfc6074a6c52fde" args="" -->YAML_PARSE_DOCUMENT_START_STATE</em>&nbsp;</td><td>
+<p>Expect DOCUMENT-START. </p>
+</td></tr>
+<tr><td valign="top"><em><a class="anchor" id="ggad39c19e7b0df6f542ca97806535b57c5ae444c7652c8029b0ef80068eaaaa3d4d"></a><!-- doxytag: member="YAML_PARSE_DOCUMENT_CONTENT_STATE" ref="ggad39c19e7b0df6f542ca97806535b57c5ae444c7652c8029b0ef80068eaaaa3d4d" args="" -->YAML_PARSE_DOCUMENT_CONTENT_STATE</em>&nbsp;</td><td>
+<p>Expect the content of a document. </p>
+</td></tr>
+<tr><td valign="top"><em><a class="anchor" id="ggad39c19e7b0df6f542ca97806535b57c5aeef06d7f13fa4501146a5b9876c98239"></a><!-- doxytag: member="YAML_PARSE_DOCUMENT_END_STATE" ref="ggad39c19e7b0df6f542ca97806535b57c5aeef06d7f13fa4501146a5b9876c98239" args="" -->YAML_PARSE_DOCUMENT_END_STATE</em>&nbsp;</td><td>
+<p>Expect DOCUMENT-END. </p>
+</td></tr>
+<tr><td valign="top"><em><a class="anchor" id="ggad39c19e7b0df6f542ca97806535b57c5ae1893c0835bacf05cdc21ed181fb75f1"></a><!-- doxytag: member="YAML_PARSE_BLOCK_NODE_STATE" ref="ggad39c19e7b0df6f542ca97806535b57c5ae1893c0835bacf05cdc21ed181fb75f1" args="" -->YAML_PARSE_BLOCK_NODE_STATE</em>&nbsp;</td><td>
+<p>Expect a block node. </p>
+</td></tr>
+<tr><td valign="top"><em><a class="anchor" id="ggad39c19e7b0df6f542ca97806535b57c5acbd390af0d3919fe0382d03c284ff3b5"></a><!-- doxytag: member="YAML_PARSE_BLOCK_NODE_OR_INDENTLESS_SEQUENCE_STATE" ref="ggad39c19e7b0df6f542ca97806535b57c5acbd390af0d3919fe0382d03c284ff3b5" args="" -->YAML_PARSE_BLOCK_NODE_OR_INDENTLESS_SEQUENCE_STATE</em>&nbsp;</td><td>
+<p>Expect a block node or indentless sequence. </p>
+</td></tr>
+<tr><td valign="top"><em><a class="anchor" id="ggad39c19e7b0df6f542ca97806535b57c5a5bb321f9d18c5b208a71c04bbcbd1d01"></a><!-- doxytag: member="YAML_PARSE_FLOW_NODE_STATE" ref="ggad39c19e7b0df6f542ca97806535b57c5a5bb321f9d18c5b208a71c04bbcbd1d01" args="" -->YAML_PARSE_FLOW_NODE_STATE</em>&nbsp;</td><td>
+<p>Expect a flow node. </p>
+</td></tr>
+<tr><td valign="top"><em><a class="anchor" id="ggad39c19e7b0df6f542ca97806535b57c5a5bb5f95fc5f1a258ee8e9db0ed25b2d9"></a><!-- doxytag: member="YAML_PARSE_BLOCK_SEQUENCE_FIRST_ENTRY_STATE" ref="ggad39c19e7b0df6f542ca97806535b57c5a5bb5f95fc5f1a258ee8e9db0ed25b2d9" args="" -->YAML_PARSE_BLOCK_SEQUENCE_FIRST_ENTRY_STATE</em>&nbsp;</td><td>
+<p>Expect the first entry of a block sequence. </p>
+</td></tr>
+<tr><td valign="top"><em><a class="anchor" id="ggad39c19e7b0df6f542ca97806535b57c5a8a6cb1f12fe08eee7fc2fa854dbd5b1a"></a><!-- doxytag: member="YAML_PARSE_BLOCK_SEQUENCE_ENTRY_STATE" ref="ggad39c19e7b0df6f542ca97806535b57c5a8a6cb1f12fe08eee7fc2fa854dbd5b1a" args="" -->YAML_PARSE_BLOCK_SEQUENCE_ENTRY_STATE</em>&nbsp;</td><td>
+<p>Expect an entry of a block sequence. </p>
+</td></tr>
+<tr><td valign="top"><em><a class="anchor" id="ggad39c19e7b0df6f542ca97806535b57c5af7095f2141cf9887489e832f0ec61fbd"></a><!-- doxytag: member="YAML_PARSE_INDENTLESS_SEQUENCE_ENTRY_STATE" ref="ggad39c19e7b0df6f542ca97806535b57c5af7095f2141cf9887489e832f0ec61fbd" args="" -->YAML_PARSE_INDENTLESS_SEQUENCE_ENTRY_STATE</em>&nbsp;</td><td>
+<p>Expect an entry of an indentless sequence. </p>
+</td></tr>
+<tr><td valign="top"><em><a class="anchor" id="ggad39c19e7b0df6f542ca97806535b57c5afebcb5bbd67d112d9ecfa633155f0644"></a><!-- doxytag: member="YAML_PARSE_BLOCK_MAPPING_FIRST_KEY_STATE" ref="ggad39c19e7b0df6f542ca97806535b57c5afebcb5bbd67d112d9ecfa633155f0644" args="" -->YAML_PARSE_BLOCK_MAPPING_FIRST_KEY_STATE</em>&nbsp;</td><td>
+<p>Expect the first key of a block mapping. </p>
+</td></tr>
+<tr><td valign="top"><em><a class="anchor" id="ggad39c19e7b0df6f542ca97806535b57c5a2df81c86e90b874b415ecb19e72efe45"></a><!-- doxytag: member="YAML_PARSE_BLOCK_MAPPING_KEY_STATE" ref="ggad39c19e7b0df6f542ca97806535b57c5a2df81c86e90b874b415ecb19e72efe45" args="" -->YAML_PARSE_BLOCK_MAPPING_KEY_STATE</em>&nbsp;</td><td>
+<p>Expect a block mapping key. </p>
+</td></tr>
+<tr><td valign="top"><em><a class="anchor" id="ggad39c19e7b0df6f542ca97806535b57c5ae94acf5685fa1538b225413f154465c2"></a><!-- doxytag: member="YAML_PARSE_BLOCK_MAPPING_VALUE_STATE" ref="ggad39c19e7b0df6f542ca97806535b57c5ae94acf5685fa1538b225413f154465c2" args="" -->YAML_PARSE_BLOCK_MAPPING_VALUE_STATE</em>&nbsp;</td><td>
+<p>Expect a block mapping value. </p>
+</td></tr>
+<tr><td valign="top"><em><a class="anchor" id="ggad39c19e7b0df6f542ca97806535b57c5a3f54830989c12cc4a63494df792eeb08"></a><!-- doxytag: member="YAML_PARSE_FLOW_SEQUENCE_FIRST_ENTRY_STATE" ref="ggad39c19e7b0df6f542ca97806535b57c5a3f54830989c12cc4a63494df792eeb08" args="" -->YAML_PARSE_FLOW_SEQUENCE_FIRST_ENTRY_STATE</em>&nbsp;</td><td>
+<p>Expect the first entry of a flow sequence. </p>
+</td></tr>
+<tr><td valign="top"><em><a class="anchor" id="ggad39c19e7b0df6f542ca97806535b57c5a0e50f3841eb0d37ad159e64c4a9a1171"></a><!-- doxytag: member="YAML_PARSE_FLOW_SEQUENCE_ENTRY_STATE" ref="ggad39c19e7b0df6f542ca97806535b57c5a0e50f3841eb0d37ad159e64c4a9a1171" args="" -->YAML_PARSE_FLOW_SEQUENCE_ENTRY_STATE</em>&nbsp;</td><td>
+<p>Expect an entry of a flow sequence. </p>
+</td></tr>
+<tr><td valign="top"><em><a class="anchor" id="ggad39c19e7b0df6f542ca97806535b57c5a563e11601cf3a1d2a3efc1feb1b696a3"></a><!-- doxytag: member="YAML_PARSE_FLOW_SEQUENCE_ENTRY_MAPPING_KEY_STATE" ref="ggad39c19e7b0df6f542ca97806535b57c5a563e11601cf3a1d2a3efc1feb1b696a3" args="" -->YAML_PARSE_FLOW_SEQUENCE_ENTRY_MAPPING_KEY_STATE</em>&nbsp;</td><td>
+<p>Expect a key of an ordered mapping. </p>
+</td></tr>
+<tr><td valign="top"><em><a class="anchor" id="ggad39c19e7b0df6f542ca97806535b57c5a9e5ebb4bee4541e7a7025689c7fc66eb"></a><!-- doxytag: member="YAML_PARSE_FLOW_SEQUENCE_ENTRY_MAPPING_VALUE_STATE" ref="ggad39c19e7b0df6f542ca97806535b57c5a9e5ebb4bee4541e7a7025689c7fc66eb" args="" -->YAML_PARSE_FLOW_SEQUENCE_ENTRY_MAPPING_VALUE_STATE</em>&nbsp;</td><td>
+<p>Expect a value of an ordered mapping. </p>
+</td></tr>
+<tr><td valign="top"><em><a class="anchor" id="ggad39c19e7b0df6f542ca97806535b57c5a397fd87de9227c64e5308481930b5eeb"></a><!-- doxytag: member="YAML_PARSE_FLOW_SEQUENCE_ENTRY_MAPPING_END_STATE" ref="ggad39c19e7b0df6f542ca97806535b57c5a397fd87de9227c64e5308481930b5eeb" args="" -->YAML_PARSE_FLOW_SEQUENCE_ENTRY_MAPPING_END_STATE</em>&nbsp;</td><td>
+<p>Expect the and of an ordered mapping entry. </p>
+</td></tr>
+<tr><td valign="top"><em><a class="anchor" id="ggad39c19e7b0df6f542ca97806535b57c5a91ac4bbb6629e2b768a3305fb707b7cd"></a><!-- doxytag: member="YAML_PARSE_FLOW_MAPPING_FIRST_KEY_STATE" ref="ggad39c19e7b0df6f542ca97806535b57c5a91ac4bbb6629e2b768a3305fb707b7cd" args="" -->YAML_PARSE_FLOW_MAPPING_FIRST_KEY_STATE</em>&nbsp;</td><td>
+<p>Expect the first key of a flow mapping. </p>
+</td></tr>
+<tr><td valign="top"><em><a class="anchor" id="ggad39c19e7b0df6f542ca97806535b57c5a924f8eb891dc7527bf4db594a0b1bff8"></a><!-- doxytag: member="YAML_PARSE_FLOW_MAPPING_KEY_STATE" ref="ggad39c19e7b0df6f542ca97806535b57c5a924f8eb891dc7527bf4db594a0b1bff8" args="" -->YAML_PARSE_FLOW_MAPPING_KEY_STATE</em>&nbsp;</td><td>
+<p>Expect a key of a flow mapping. </p>
+</td></tr>
+<tr><td valign="top"><em><a class="anchor" id="ggad39c19e7b0df6f542ca97806535b57c5a3ba351f6cfba029248ada2c0720246d4"></a><!-- doxytag: member="YAML_PARSE_FLOW_MAPPING_VALUE_STATE" ref="ggad39c19e7b0df6f542ca97806535b57c5a3ba351f6cfba029248ada2c0720246d4" args="" -->YAML_PARSE_FLOW_MAPPING_VALUE_STATE</em>&nbsp;</td><td>
+<p>Expect a value of a flow mapping. </p>
+</td></tr>
+<tr><td valign="top"><em><a class="anchor" id="ggad39c19e7b0df6f542ca97806535b57c5a5a8ec0af5c3314c1ad5e0569b6a5d6d2"></a><!-- doxytag: member="YAML_PARSE_FLOW_MAPPING_EMPTY_VALUE_STATE" ref="ggad39c19e7b0df6f542ca97806535b57c5a5a8ec0af5c3314c1ad5e0569b6a5d6d2" args="" -->YAML_PARSE_FLOW_MAPPING_EMPTY_VALUE_STATE</em>&nbsp;</td><td>
+<p>Expect an empty value of a flow mapping. </p>
+</td></tr>
+<tr><td valign="top"><em><a class="anchor" id="ggad39c19e7b0df6f542ca97806535b57c5a51fd3d45693e2240251996def375a2a2"></a><!-- doxytag: member="YAML_PARSE_END_STATE" ref="ggad39c19e7b0df6f542ca97806535b57c5a51fd3d45693e2240251996def375a2a2" args="" -->YAML_PARSE_END_STATE</em>&nbsp;</td><td>
+<p>Expect nothing. </p>
+</td></tr>
+</table>
+</dd>
+</dl>
+
+</div>
+</div>
+<hr/><h2>Function Documentation</h2>
+<a class="anchor" id="gacc37ceeb5847e38a3fe24eb0c9b53965"></a><!-- doxytag: member="yaml.h::yaml_parser_initialize" ref="gacc37ceeb5847e38a3fe24eb0c9b53965" args="(yaml_parser_t *parser)" -->
+<div class="memitem">
+<div class="memproto">
+ <table class="memname">
+ <tr>
+ <td class="memname">int yaml_parser_initialize </td>
+ <td>(</td>
+ <td class="paramtype"><a class="el" href="structyaml__parser__s.html">yaml_parser_t</a> *&nbsp;</td>
+ <td class="paramname"> <em>parser</em></td>
+ <td>&nbsp;)&nbsp;</td>
+ <td></td>
+ </tr>
+ </table>
+</div>
+<div class="memdoc">
+
+<p>Initialize a parser. </p>
+<p>This function creates a new parser object. An application is responsible for destroying the object using the <a class="el" href="group__parser.html#gaa27150107c4667c1024ec0651e2ac26b" title="Destroy a parser.">yaml_parser_delete()</a> function.</p>
+<dl><dt><b>Parameters:</b></dt><dd>
+ <table border="0" cellspacing="2" cellpadding="0">
+ <tr><td valign="top"><tt>[out]</tt>&nbsp;</td><td valign="top"><em>parser</em>&nbsp;</td><td>An empty parser object.</td></tr>
+ </table>
+ </dd>
+</dl>
+<dl class="return"><dt><b>Returns:</b></dt><dd><code>1</code> if the function succeeded, <code>0</code> on error. </dd></dl>
+
+</div>
+</div>
+<a class="anchor" id="gaa27150107c4667c1024ec0651e2ac26b"></a><!-- doxytag: member="yaml.h::yaml_parser_delete" ref="gaa27150107c4667c1024ec0651e2ac26b" args="(yaml_parser_t *parser)" -->
+<div class="memitem">
+<div class="memproto">
+ <table class="memname">
+ <tr>
+ <td class="memname">void yaml_parser_delete </td>
+ <td>(</td>
+ <td class="paramtype"><a class="el" href="structyaml__parser__s.html">yaml_parser_t</a> *&nbsp;</td>
+ <td class="paramname"> <em>parser</em></td>
+ <td>&nbsp;)&nbsp;</td>
+ <td></td>
+ </tr>
+ </table>
+</div>
+<div class="memdoc">
+
+<p>Destroy a parser. </p>
+<dl><dt><b>Parameters:</b></dt><dd>
+ <table border="0" cellspacing="2" cellpadding="0">
+ <tr><td valign="top"><tt>[in,out]</tt>&nbsp;</td><td valign="top"><em>parser</em>&nbsp;</td><td>A parser object. </td></tr>
+ </table>
+ </dd>
+</dl>
+
+</div>
+</div>
+<a class="anchor" id="ga08a94762bf5f4c61f72c1da0a407df0d"></a><!-- doxytag: member="yaml.h::yaml_parser_set_input_string" ref="ga08a94762bf5f4c61f72c1da0a407df0d" args="(yaml_parser_t *parser, const unsigned char *input, size_t size)" -->
+<div class="memitem">
+<div class="memproto">
+ <table class="memname">
+ <tr>
+ <td class="memname">void yaml_parser_set_input_string </td>
+ <td>(</td>
+ <td class="paramtype"><a class="el" href="structyaml__parser__s.html">yaml_parser_t</a> *&nbsp;</td>
+ <td class="paramname"> <em>parser</em>, </td>
+ </tr>
+ <tr>
+ <td class="paramkey"></td>
+ <td></td>
+ <td class="paramtype">const unsigned char *&nbsp;</td>
+ <td class="paramname"> <em>input</em>, </td>
+ </tr>
+ <tr>
+ <td class="paramkey"></td>
+ <td></td>
+ <td class="paramtype">size_t&nbsp;</td>
+ <td class="paramname"> <em>size</em></td><td>&nbsp;</td>
+ </tr>
+ <tr>
+ <td></td>
+ <td>)</td>
+ <td></td><td></td><td></td>
+ </tr>
+ </table>
+</div>
+<div class="memdoc">
+
+<p>Set a string input. </p>
+<p>Note that the <em>input</em> pointer must be valid while the <em>parser</em> object exists. The application is responsible for destroing <em>input</em> after destroying the <em>parser</em>.</p>
+<dl><dt><b>Parameters:</b></dt><dd>
+ <table border="0" cellspacing="2" cellpadding="0">
+ <tr><td valign="top"><tt>[in,out]</tt>&nbsp;</td><td valign="top"><em>parser</em>&nbsp;</td><td>A parser object. </td></tr>
+ <tr><td valign="top"><tt>[in]</tt>&nbsp;</td><td valign="top"><em>input</em>&nbsp;</td><td>A source data. </td></tr>
+ <tr><td valign="top"><tt>[in]</tt>&nbsp;</td><td valign="top"><em>size</em>&nbsp;</td><td>The length of the source data in bytes. </td></tr>
+ </table>
+ </dd>
+</dl>
+
+</div>
+</div>
+<a class="anchor" id="gac3f00f8beb2365b1e4569692d64696b6"></a><!-- doxytag: member="yaml.h::yaml_parser_set_input_file" ref="gac3f00f8beb2365b1e4569692d64696b6" args="(yaml_parser_t *parser, FILE *file)" -->
+<div class="memitem">
+<div class="memproto">
+ <table class="memname">
+ <tr>
+ <td class="memname">void yaml_parser_set_input_file </td>
+ <td>(</td>
+ <td class="paramtype"><a class="el" href="structyaml__parser__s.html">yaml_parser_t</a> *&nbsp;</td>
+ <td class="paramname"> <em>parser</em>, </td>
+ </tr>
+ <tr>
+ <td class="paramkey"></td>
+ <td></td>
+ <td class="paramtype">FILE *&nbsp;</td>
+ <td class="paramname"> <em>file</em></td><td>&nbsp;</td>
+ </tr>
+ <tr>
+ <td></td>
+ <td>)</td>
+ <td></td><td></td><td></td>
+ </tr>
+ </table>
+</div>
+<div class="memdoc">
+
+<p>Set a file input. </p>
+<p><em>file</em> should be a file object open for reading. The application is responsible for closing the <em>file</em>.</p>
+<dl><dt><b>Parameters:</b></dt><dd>
+ <table border="0" cellspacing="2" cellpadding="0">
+ <tr><td valign="top"><tt>[in,out]</tt>&nbsp;</td><td valign="top"><em>parser</em>&nbsp;</td><td>A parser object. </td></tr>
+ <tr><td valign="top"><tt>[in]</tt>&nbsp;</td><td valign="top"><em>file</em>&nbsp;</td><td>An open file. </td></tr>
+ </table>
+ </dd>
+</dl>
+
+</div>
+</div>
+<a class="anchor" id="gabc67581bfa771a3e787d907d6914b8d9"></a><!-- doxytag: member="yaml.h::yaml_parser_set_input" ref="gabc67581bfa771a3e787d907d6914b8d9" args="(yaml_parser_t *parser, yaml_read_handler_t *handler, void *data)" -->
+<div class="memitem">
+<div class="memproto">
+ <table class="memname">
+ <tr>
+ <td class="memname">void yaml_parser_set_input </td>
+ <td>(</td>
+ <td class="paramtype"><a class="el" href="structyaml__parser__s.html">yaml_parser_t</a> *&nbsp;</td>
+ <td class="paramname"> <em>parser</em>, </td>
+ </tr>
+ <tr>
+ <td class="paramkey"></td>
+ <td></td>
+ <td class="paramtype"><a class="el" href="group__parser.html#ga4982f7e4e001ddb47d2819f38f0cd9d6">yaml_read_handler_t</a> *&nbsp;</td>
+ <td class="paramname"> <em>handler</em>, </td>
+ </tr>
+ <tr>
+ <td class="paramkey"></td>
+ <td></td>
+ <td class="paramtype">void *&nbsp;</td>
+ <td class="paramname"> <em>data</em></td><td>&nbsp;</td>
+ </tr>
+ <tr>
+ <td></td>
+ <td>)</td>
+ <td></td><td></td><td></td>
+ </tr>
+ </table>
+</div>
+<div class="memdoc">
+
+<p>Set a generic input handler. </p>
+<dl><dt><b>Parameters:</b></dt><dd>
+ <table border="0" cellspacing="2" cellpadding="0">
+ <tr><td valign="top"><tt>[in,out]</tt>&nbsp;</td><td valign="top"><em>parser</em>&nbsp;</td><td>A parser object. </td></tr>
+ <tr><td valign="top"><tt>[in]</tt>&nbsp;</td><td valign="top"><em>handler</em>&nbsp;</td><td>A read handler. </td></tr>
+ <tr><td valign="top"><tt>[in]</tt>&nbsp;</td><td valign="top"><em>data</em>&nbsp;</td><td>Any application data for passing to the read handler. </td></tr>
+ </table>
+ </dd>
+</dl>
+
+</div>
+</div>
+<a class="anchor" id="ga9565b64975570ed34612a19adf02ae6a"></a><!-- doxytag: member="yaml.h::yaml_parser_set_encoding" ref="ga9565b64975570ed34612a19adf02ae6a" args="(yaml_parser_t *parser, yaml_encoding_t encoding)" -->
+<div class="memitem">
+<div class="memproto">
+ <table class="memname">
+ <tr>
+ <td class="memname">void yaml_parser_set_encoding </td>
+ <td>(</td>
+ <td class="paramtype"><a class="el" href="structyaml__parser__s.html">yaml_parser_t</a> *&nbsp;</td>
+ <td class="paramname"> <em>parser</em>, </td>
+ </tr>
+ <tr>
+ <td class="paramkey"></td>
+ <td></td>
+ <td class="paramtype"><a class="el" href="group__basic.html#ga2170996d7e636397b5e6bc0c1b7df7c6">yaml_encoding_t</a>&nbsp;</td>
+ <td class="paramname"> <em>encoding</em></td><td>&nbsp;</td>
+ </tr>
+ <tr>
+ <td></td>
+ <td>)</td>
+ <td></td><td></td><td></td>
+ </tr>
+ </table>
+</div>
+<div class="memdoc">
+
+<p>Set the source encoding. </p>
+<dl><dt><b>Parameters:</b></dt><dd>
+ <table border="0" cellspacing="2" cellpadding="0">
+ <tr><td valign="top"><tt>[in,out]</tt>&nbsp;</td><td valign="top"><em>parser</em>&nbsp;</td><td>A parser object. </td></tr>
+ <tr><td valign="top"><tt>[in]</tt>&nbsp;</td><td valign="top"><em>encoding</em>&nbsp;</td><td>The source encoding. </td></tr>
+ </table>
+ </dd>
+</dl>
+
+</div>
+</div>
+<a class="anchor" id="ga6c2144f131ebd600a075d4ba654540f7"></a><!-- doxytag: member="yaml.h::yaml_parser_scan" ref="ga6c2144f131ebd600a075d4ba654540f7" args="(yaml_parser_t *parser, yaml_token_t *token)" -->
+<div class="memitem">
+<div class="memproto">
+ <table class="memname">
+ <tr>
+ <td class="memname">int yaml_parser_scan </td>
+ <td>(</td>
+ <td class="paramtype"><a class="el" href="structyaml__parser__s.html">yaml_parser_t</a> *&nbsp;</td>
+ <td class="paramname"> <em>parser</em>, </td>
+ </tr>
+ <tr>
+ <td class="paramkey"></td>
+ <td></td>
+ <td class="paramtype"><a class="el" href="structyaml__token__s.html">yaml_token_t</a> *&nbsp;</td>
+ <td class="paramname"> <em>token</em></td><td>&nbsp;</td>
+ </tr>
+ <tr>
+ <td></td>
+ <td>)</td>
+ <td></td><td></td><td></td>
+ </tr>
+ </table>
+</div>
+<div class="memdoc">
+
+<p>Scan the input stream and produce the next token. </p>
+<p>Call the function subsequently to produce a sequence of tokens corresponding to the input stream. The initial token has the type <code>YAML_STREAM_START_TOKEN</code> while the ending token has the type <code>YAML_STREAM_END_TOKEN</code>.</p>
+<p>An application is responsible for freeing any buffers associated with the produced token object using the <code>yaml_token_delete</code> function.</p>
+<p>An application must not alternate the calls of <a class="el" href="group__parser.html#ga6c2144f131ebd600a075d4ba654540f7" title="Scan the input stream and produce the next token.">yaml_parser_scan()</a> with the calls of <a class="el" href="group__parser.html#ga559312fb137533d8b7e07f224fe0ec8f" title="Parse the input stream and produce the next parsing event.">yaml_parser_parse()</a> or <a class="el" href="group__parser.html#ga9ef7d6e9494766b5880c389bc431d138" title="Parse the input stream and produce the next YAML document.">yaml_parser_load()</a>. Doing this will break the parser.</p>
+<dl><dt><b>Parameters:</b></dt><dd>
+ <table border="0" cellspacing="2" cellpadding="0">
+ <tr><td valign="top"><tt>[in,out]</tt>&nbsp;</td><td valign="top"><em>parser</em>&nbsp;</td><td>A parser object. </td></tr>
+ <tr><td valign="top"><tt>[out]</tt>&nbsp;</td><td valign="top"><em>token</em>&nbsp;</td><td>An empty token object.</td></tr>
+ </table>
+ </dd>
+</dl>
+<dl class="return"><dt><b>Returns:</b></dt><dd><code>1</code> if the function succeeded, <code>0</code> on error. </dd></dl>
+
+</div>
+</div>
+<a class="anchor" id="ga559312fb137533d8b7e07f224fe0ec8f"></a><!-- doxytag: member="yaml.h::yaml_parser_parse" ref="ga559312fb137533d8b7e07f224fe0ec8f" args="(yaml_parser_t *parser, yaml_event_t *event)" -->
+<div class="memitem">
+<div class="memproto">
+ <table class="memname">
+ <tr>
+ <td class="memname">int yaml_parser_parse </td>
+ <td>(</td>
+ <td class="paramtype"><a class="el" href="structyaml__parser__s.html">yaml_parser_t</a> *&nbsp;</td>
+ <td class="paramname"> <em>parser</em>, </td>
+ </tr>
+ <tr>
+ <td class="paramkey"></td>
+ <td></td>
+ <td class="paramtype"><a class="el" href="structyaml__event__s.html">yaml_event_t</a> *&nbsp;</td>
+ <td class="paramname"> <em>event</em></td><td>&nbsp;</td>
+ </tr>
+ <tr>
+ <td></td>
+ <td>)</td>
+ <td></td><td></td><td></td>
+ </tr>
+ </table>
+</div>
+<div class="memdoc">
+
+<p>Parse the input stream and produce the next parsing event. </p>
+<p>Call the function subsequently to produce a sequence of events corresponding to the input stream. The initial event has the type <code>YAML_STREAM_START_EVENT</code> while the ending event has the type <code>YAML_STREAM_END_EVENT</code>.</p>
+<p>An application is responsible for freeing any buffers associated with the produced event object using the <a class="el" href="group__events.html#ga5330d62ef52856aa53188137cb93a6a1" title="Free any memory allocated for an event object.">yaml_event_delete()</a> function.</p>
+<p>An application must not alternate the calls of <a class="el" href="group__parser.html#ga559312fb137533d8b7e07f224fe0ec8f" title="Parse the input stream and produce the next parsing event.">yaml_parser_parse()</a> with the calls of <a class="el" href="group__parser.html#ga6c2144f131ebd600a075d4ba654540f7" title="Scan the input stream and produce the next token.">yaml_parser_scan()</a> or <a class="el" href="group__parser.html#ga9ef7d6e9494766b5880c389bc431d138" title="Parse the input stream and produce the next YAML document.">yaml_parser_load()</a>. Doing this will break the parser.</p>
+<dl><dt><b>Parameters:</b></dt><dd>
+ <table border="0" cellspacing="2" cellpadding="0">
+ <tr><td valign="top"><tt>[in,out]</tt>&nbsp;</td><td valign="top"><em>parser</em>&nbsp;</td><td>A parser object. </td></tr>
+ <tr><td valign="top"><tt>[out]</tt>&nbsp;</td><td valign="top"><em>event</em>&nbsp;</td><td>An empty event object.</td></tr>
+ </table>
+ </dd>
+</dl>
+<dl class="return"><dt><b>Returns:</b></dt><dd><code>1</code> if the function succeeded, <code>0</code> on error. </dd></dl>
+
+</div>
+</div>
+<a class="anchor" id="ga9ef7d6e9494766b5880c389bc431d138"></a><!-- doxytag: member="yaml.h::yaml_parser_load" ref="ga9ef7d6e9494766b5880c389bc431d138" args="(yaml_parser_t *parser, yaml_document_t *document)" -->
+<div class="memitem">
+<div class="memproto">
+ <table class="memname">
+ <tr>
+ <td class="memname">int yaml_parser_load </td>
+ <td>(</td>
+ <td class="paramtype"><a class="el" href="structyaml__parser__s.html">yaml_parser_t</a> *&nbsp;</td>
+ <td class="paramname"> <em>parser</em>, </td>
+ </tr>
+ <tr>
+ <td class="paramkey"></td>
+ <td></td>
+ <td class="paramtype"><a class="el" href="structyaml__document__s.html">yaml_document_t</a> *&nbsp;</td>
+ <td class="paramname"> <em>document</em></td><td>&nbsp;</td>
+ </tr>
+ <tr>
+ <td></td>
+ <td>)</td>
+ <td></td><td></td><td></td>
+ </tr>
+ </table>
+</div>
+<div class="memdoc">
+
+<p>Parse the input stream and produce the next YAML document. </p>
+<p>Call this function subsequently to produce a sequence of documents constituting the input stream.</p>
+<p>If the produced document has no root node, it means that the document end has been reached.</p>
+<p>An application is responsible for freeing any data associated with the produced document object using the <a class="el" href="group__nodes.html#ga2754b1544fb4e110e83fafbc708b0672" title="Delete a YAML document and all its nodes.">yaml_document_delete()</a> function.</p>
+<p>An application must not alternate the calls of <a class="el" href="group__parser.html#ga9ef7d6e9494766b5880c389bc431d138" title="Parse the input stream and produce the next YAML document.">yaml_parser_load()</a> with the calls of <a class="el" href="group__parser.html#ga6c2144f131ebd600a075d4ba654540f7" title="Scan the input stream and produce the next token.">yaml_parser_scan()</a> or <a class="el" href="group__parser.html#ga559312fb137533d8b7e07f224fe0ec8f" title="Parse the input stream and produce the next parsing event.">yaml_parser_parse()</a>. Doing this will break the parser.</p>
+<dl><dt><b>Parameters:</b></dt><dd>
+ <table border="0" cellspacing="2" cellpadding="0">
+ <tr><td valign="top"><tt>[in,out]</tt>&nbsp;</td><td valign="top"><em>parser</em>&nbsp;</td><td>A parser object. </td></tr>
+ <tr><td valign="top"><tt>[out]</tt>&nbsp;</td><td valign="top"><em>document</em>&nbsp;</td><td>An empty document object.</td></tr>
+ </table>
+ </dd>
+</dl>
+<dl class="return"><dt><b>Returns:</b></dt><dd><code>1</code> if the function succeeded, <code>0</code> on error. </dd></dl>
+
+</div>
+</div>
+</div>
+<hr class="footer"/><address class="footer"><small>Generated on Mon May 30 2011 22:00:00 for yaml by&nbsp;
+<a href="http://www.doxygen.org/index.html">
+<img class="footer" src="doxygen.png" alt="doxygen"/></a> 1.7.1 </small></address>
+</body>
+</html>
diff --git a/contrib/libyaml/doc/html/group__styles.html b/contrib/libyaml/doc/html/group__styles.html
new file mode 100644
index 0000000..147f85e
--- /dev/null
+++ b/contrib/libyaml/doc/html/group__styles.html
@@ -0,0 +1,222 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head>
+<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/>
+<title>yaml: Node Styles</title>
+<link href="tabs.css" rel="stylesheet" type="text/css"/>
+<link href="doxygen.css" rel="stylesheet" type="text/css"/>
+</head>
+<body>
+<!-- Generated by Doxygen 1.7.1 -->
+<div class="navigation" id="top">
+ <div class="tabs">
+ <ul class="tablist">
+ <li><a href="index.html"><span>Main&nbsp;Page</span></a></li>
+ <li><a href="modules.html"><span>Modules</span></a></li>
+ <li><a href="annotated.html"><span>Data&nbsp;Structures</span></a></li>
+ <li><a href="files.html"><span>Files</span></a></li>
+ </ul>
+ </div>
+</div>
+<div class="header">
+ <div class="summary">
+<a href="#typedef-members">Typedefs</a> &#124;
+<a href="#enum-members">Enumerations</a> </div>
+ <div class="headertitle">
+<h1>Node Styles</h1> </div>
+</div>
+<div class="contents">
+<table class="memberdecls">
+<tr><td colspan="2"><h2><a name="typedef-members"></a>
+Typedefs</h2></td></tr>
+<tr><td class="memItemLeft" align="right" valign="top">typedef enum <a class="el" href="group__styles.html#ga435ae8886b70c16830d853b6c566e2e0">yaml_scalar_style_e</a>&nbsp;</td><td class="memItemRight" valign="bottom"><a class="el" href="group__styles.html#ga3fa6405631e1afe5bd5c488a6c5e8065">yaml_scalar_style_t</a></td></tr>
+<tr><td class="mdescLeft">&nbsp;</td><td class="mdescRight">Scalar styles. <a href="#ga3fa6405631e1afe5bd5c488a6c5e8065"></a><br/></td></tr>
+<tr><td class="memItemLeft" align="right" valign="top">typedef enum <a class="el" href="group__styles.html#ga5079a4ab96e398371c60423abd88ccc0">yaml_sequence_style_e</a>&nbsp;</td><td class="memItemRight" valign="bottom"><a class="el" href="group__styles.html#ga58a1123d271e56c72de6abf852ac4dc2">yaml_sequence_style_t</a></td></tr>
+<tr><td class="mdescLeft">&nbsp;</td><td class="mdescRight">Sequence styles. <a href="#ga58a1123d271e56c72de6abf852ac4dc2"></a><br/></td></tr>
+<tr><td class="memItemLeft" align="right" valign="top">typedef enum <a class="el" href="group__styles.html#ga1efef592e2e3df6f00432c04ef77d98f">yaml_mapping_style_e</a>&nbsp;</td><td class="memItemRight" valign="bottom"><a class="el" href="group__styles.html#gab47523846a5c5960e07367a28ea9750a">yaml_mapping_style_t</a></td></tr>
+<tr><td class="mdescLeft">&nbsp;</td><td class="mdescRight">Mapping styles. <a href="#gab47523846a5c5960e07367a28ea9750a"></a><br/></td></tr>
+<tr><td colspan="2"><h2><a name="enum-members"></a>
+Enumerations</h2></td></tr>
+<tr><td class="memItemLeft" align="right" valign="top">enum &nbsp;</td><td class="memItemRight" valign="bottom"><a class="el" href="group__styles.html#ga435ae8886b70c16830d853b6c566e2e0">yaml_scalar_style_e</a> { <br/>
+&nbsp;&nbsp;<a class="el" href="group__styles.html#gga435ae8886b70c16830d853b6c566e2e0aead38b3e6846302ee032927267c34ae0">YAML_ANY_SCALAR_STYLE</a>,
+<br/>
+&nbsp;&nbsp;<a class="el" href="group__styles.html#gga435ae8886b70c16830d853b6c566e2e0afd62a761a36cf56e1f0414fb391db0e6">YAML_PLAIN_SCALAR_STYLE</a>,
+<br/>
+&nbsp;&nbsp;<a class="el" href="group__styles.html#gga435ae8886b70c16830d853b6c566e2e0a68a2af452008e3af3f6de14318dfb2c6">YAML_SINGLE_QUOTED_SCALAR_STYLE</a>,
+<br/>
+&nbsp;&nbsp;<a class="el" href="group__styles.html#gga435ae8886b70c16830d853b6c566e2e0af6fdfd14690361f4937d67d1f0f011d3">YAML_DOUBLE_QUOTED_SCALAR_STYLE</a>,
+<br/>
+&nbsp;&nbsp;<a class="el" href="group__styles.html#gga435ae8886b70c16830d853b6c566e2e0a542d1ac1bf5c3434df3d2a757d0a8ca0">YAML_LITERAL_SCALAR_STYLE</a>,
+<br/>
+&nbsp;&nbsp;<a class="el" href="group__styles.html#gga435ae8886b70c16830d853b6c566e2e0aa67c3de37dc127986b08bdbe07cee607">YAML_FOLDED_SCALAR_STYLE</a>
+<br/>
+ }</td></tr>
+<tr><td class="mdescLeft">&nbsp;</td><td class="mdescRight"><p>Scalar styles. </p>
+ <a href="group__styles.html#ga435ae8886b70c16830d853b6c566e2e0">More...</a><br/></td></tr>
+<tr><td class="memItemLeft" align="right" valign="top">enum &nbsp;</td><td class="memItemRight" valign="bottom"><a class="el" href="group__styles.html#ga5079a4ab96e398371c60423abd88ccc0">yaml_sequence_style_e</a> { <br/>
+&nbsp;&nbsp;<a class="el" href="group__styles.html#gga5079a4ab96e398371c60423abd88ccc0a5a10d6f70339876b76e5a002dd16212f">YAML_ANY_SEQUENCE_STYLE</a>,
+<br/>
+&nbsp;&nbsp;<a class="el" href="group__styles.html#gga5079a4ab96e398371c60423abd88ccc0a65f99099ef4ecdcf99bbdd798b5dcbb5">YAML_BLOCK_SEQUENCE_STYLE</a>,
+<br/>
+&nbsp;&nbsp;<a class="el" href="group__styles.html#gga5079a4ab96e398371c60423abd88ccc0ae511554b654ebca464d1feec12501d80">YAML_FLOW_SEQUENCE_STYLE</a>
+<br/>
+ }</td></tr>
+<tr><td class="mdescLeft">&nbsp;</td><td class="mdescRight"><p>Sequence styles. </p>
+ <a href="group__styles.html#ga5079a4ab96e398371c60423abd88ccc0">More...</a><br/></td></tr>
+<tr><td class="memItemLeft" align="right" valign="top">enum &nbsp;</td><td class="memItemRight" valign="bottom"><a class="el" href="group__styles.html#ga1efef592e2e3df6f00432c04ef77d98f">yaml_mapping_style_e</a> { <br/>
+&nbsp;&nbsp;<a class="el" href="group__styles.html#gga1efef592e2e3df6f00432c04ef77d98fac580a83312204ea142c3d08a4954a74a">YAML_ANY_MAPPING_STYLE</a>,
+<br/>
+&nbsp;&nbsp;<a class="el" href="group__styles.html#gga1efef592e2e3df6f00432c04ef77d98fad5e70fe97009c8247a45f4620f071874">YAML_BLOCK_MAPPING_STYLE</a>,
+<br/>
+&nbsp;&nbsp;<a class="el" href="group__styles.html#gga1efef592e2e3df6f00432c04ef77d98fa4c5425077b0310cbf84e1d73e20b42d3">YAML_FLOW_MAPPING_STYLE</a>
+<br/>
+ }</td></tr>
+<tr><td class="mdescLeft">&nbsp;</td><td class="mdescRight"><p>Mapping styles. </p>
+ <a href="group__styles.html#ga1efef592e2e3df6f00432c04ef77d98f">More...</a><br/></td></tr>
+</table>
+<hr/><h2>Typedef Documentation</h2>
+<a class="anchor" id="ga3fa6405631e1afe5bd5c488a6c5e8065"></a><!-- doxytag: member="yaml.h::yaml_scalar_style_t" ref="ga3fa6405631e1afe5bd5c488a6c5e8065" args="" -->
+<div class="memitem">
+<div class="memproto">
+ <table class="memname">
+ <tr>
+ <td class="memname">typedef enum <a class="el" href="group__styles.html#ga435ae8886b70c16830d853b6c566e2e0">yaml_scalar_style_e</a> <a class="el" href="group__styles.html#ga3fa6405631e1afe5bd5c488a6c5e8065">yaml_scalar_style_t</a></td>
+ </tr>
+ </table>
+</div>
+<div class="memdoc">
+
+<p>Scalar styles. </p>
+
+</div>
+</div>
+<a class="anchor" id="ga58a1123d271e56c72de6abf852ac4dc2"></a><!-- doxytag: member="yaml.h::yaml_sequence_style_t" ref="ga58a1123d271e56c72de6abf852ac4dc2" args="" -->
+<div class="memitem">
+<div class="memproto">
+ <table class="memname">
+ <tr>
+ <td class="memname">typedef enum <a class="el" href="group__styles.html#ga5079a4ab96e398371c60423abd88ccc0">yaml_sequence_style_e</a> <a class="el" href="group__styles.html#ga58a1123d271e56c72de6abf852ac4dc2">yaml_sequence_style_t</a></td>
+ </tr>
+ </table>
+</div>
+<div class="memdoc">
+
+<p>Sequence styles. </p>
+
+</div>
+</div>
+<a class="anchor" id="gab47523846a5c5960e07367a28ea9750a"></a><!-- doxytag: member="yaml.h::yaml_mapping_style_t" ref="gab47523846a5c5960e07367a28ea9750a" args="" -->
+<div class="memitem">
+<div class="memproto">
+ <table class="memname">
+ <tr>
+ <td class="memname">typedef enum <a class="el" href="group__styles.html#ga1efef592e2e3df6f00432c04ef77d98f">yaml_mapping_style_e</a> <a class="el" href="group__styles.html#gab47523846a5c5960e07367a28ea9750a">yaml_mapping_style_t</a></td>
+ </tr>
+ </table>
+</div>
+<div class="memdoc">
+
+<p>Mapping styles. </p>
+
+</div>
+</div>
+<hr/><h2>Enumeration Type Documentation</h2>
+<a class="anchor" id="ga435ae8886b70c16830d853b6c566e2e0"></a><!-- doxytag: member="yaml.h::yaml_scalar_style_e" ref="ga435ae8886b70c16830d853b6c566e2e0" args="" -->
+<div class="memitem">
+<div class="memproto">
+ <table class="memname">
+ <tr>
+ <td class="memname">enum <a class="el" href="group__styles.html#ga435ae8886b70c16830d853b6c566e2e0">yaml_scalar_style_e</a></td>
+ </tr>
+ </table>
+</div>
+<div class="memdoc">
+
+<p>Scalar styles. </p>
+<dl><dt><b>Enumerator: </b></dt><dd><table border="0" cellspacing="2" cellpadding="0">
+<tr><td valign="top"><em><a class="anchor" id="gga435ae8886b70c16830d853b6c566e2e0aead38b3e6846302ee032927267c34ae0"></a><!-- doxytag: member="YAML_ANY_SCALAR_STYLE" ref="gga435ae8886b70c16830d853b6c566e2e0aead38b3e6846302ee032927267c34ae0" args="" -->YAML_ANY_SCALAR_STYLE</em>&nbsp;</td><td>
+<p>Let the emitter choose the style. </p>
+</td></tr>
+<tr><td valign="top"><em><a class="anchor" id="gga435ae8886b70c16830d853b6c566e2e0afd62a761a36cf56e1f0414fb391db0e6"></a><!-- doxytag: member="YAML_PLAIN_SCALAR_STYLE" ref="gga435ae8886b70c16830d853b6c566e2e0afd62a761a36cf56e1f0414fb391db0e6" args="" -->YAML_PLAIN_SCALAR_STYLE</em>&nbsp;</td><td>
+<p>The plain scalar style. </p>
+</td></tr>
+<tr><td valign="top"><em><a class="anchor" id="gga435ae8886b70c16830d853b6c566e2e0a68a2af452008e3af3f6de14318dfb2c6"></a><!-- doxytag: member="YAML_SINGLE_QUOTED_SCALAR_STYLE" ref="gga435ae8886b70c16830d853b6c566e2e0a68a2af452008e3af3f6de14318dfb2c6" args="" -->YAML_SINGLE_QUOTED_SCALAR_STYLE</em>&nbsp;</td><td>
+<p>The single-quoted scalar style. </p>
+</td></tr>
+<tr><td valign="top"><em><a class="anchor" id="gga435ae8886b70c16830d853b6c566e2e0af6fdfd14690361f4937d67d1f0f011d3"></a><!-- doxytag: member="YAML_DOUBLE_QUOTED_SCALAR_STYLE" ref="gga435ae8886b70c16830d853b6c566e2e0af6fdfd14690361f4937d67d1f0f011d3" args="" -->YAML_DOUBLE_QUOTED_SCALAR_STYLE</em>&nbsp;</td><td>
+<p>The double-quoted scalar style. </p>
+</td></tr>
+<tr><td valign="top"><em><a class="anchor" id="gga435ae8886b70c16830d853b6c566e2e0a542d1ac1bf5c3434df3d2a757d0a8ca0"></a><!-- doxytag: member="YAML_LITERAL_SCALAR_STYLE" ref="gga435ae8886b70c16830d853b6c566e2e0a542d1ac1bf5c3434df3d2a757d0a8ca0" args="" -->YAML_LITERAL_SCALAR_STYLE</em>&nbsp;</td><td>
+<p>The literal scalar style. </p>
+</td></tr>
+<tr><td valign="top"><em><a class="anchor" id="gga435ae8886b70c16830d853b6c566e2e0aa67c3de37dc127986b08bdbe07cee607"></a><!-- doxytag: member="YAML_FOLDED_SCALAR_STYLE" ref="gga435ae8886b70c16830d853b6c566e2e0aa67c3de37dc127986b08bdbe07cee607" args="" -->YAML_FOLDED_SCALAR_STYLE</em>&nbsp;</td><td>
+<p>The folded scalar style. </p>
+</td></tr>
+</table>
+</dd>
+</dl>
+
+</div>
+</div>
+<a class="anchor" id="ga5079a4ab96e398371c60423abd88ccc0"></a><!-- doxytag: member="yaml.h::yaml_sequence_style_e" ref="ga5079a4ab96e398371c60423abd88ccc0" args="" -->
+<div class="memitem">
+<div class="memproto">
+ <table class="memname">
+ <tr>
+ <td class="memname">enum <a class="el" href="group__styles.html#ga5079a4ab96e398371c60423abd88ccc0">yaml_sequence_style_e</a></td>
+ </tr>
+ </table>
+</div>
+<div class="memdoc">
+
+<p>Sequence styles. </p>
+<dl><dt><b>Enumerator: </b></dt><dd><table border="0" cellspacing="2" cellpadding="0">
+<tr><td valign="top"><em><a class="anchor" id="gga5079a4ab96e398371c60423abd88ccc0a5a10d6f70339876b76e5a002dd16212f"></a><!-- doxytag: member="YAML_ANY_SEQUENCE_STYLE" ref="gga5079a4ab96e398371c60423abd88ccc0a5a10d6f70339876b76e5a002dd16212f" args="" -->YAML_ANY_SEQUENCE_STYLE</em>&nbsp;</td><td>
+<p>Let the emitter choose the style. </p>
+</td></tr>
+<tr><td valign="top"><em><a class="anchor" id="gga5079a4ab96e398371c60423abd88ccc0a65f99099ef4ecdcf99bbdd798b5dcbb5"></a><!-- doxytag: member="YAML_BLOCK_SEQUENCE_STYLE" ref="gga5079a4ab96e398371c60423abd88ccc0a65f99099ef4ecdcf99bbdd798b5dcbb5" args="" -->YAML_BLOCK_SEQUENCE_STYLE</em>&nbsp;</td><td>
+<p>The block sequence style. </p>
+</td></tr>
+<tr><td valign="top"><em><a class="anchor" id="gga5079a4ab96e398371c60423abd88ccc0ae511554b654ebca464d1feec12501d80"></a><!-- doxytag: member="YAML_FLOW_SEQUENCE_STYLE" ref="gga5079a4ab96e398371c60423abd88ccc0ae511554b654ebca464d1feec12501d80" args="" -->YAML_FLOW_SEQUENCE_STYLE</em>&nbsp;</td><td>
+<p>The flow sequence style. </p>
+</td></tr>
+</table>
+</dd>
+</dl>
+
+</div>
+</div>
+<a class="anchor" id="ga1efef592e2e3df6f00432c04ef77d98f"></a><!-- doxytag: member="yaml.h::yaml_mapping_style_e" ref="ga1efef592e2e3df6f00432c04ef77d98f" args="" -->
+<div class="memitem">
+<div class="memproto">
+ <table class="memname">
+ <tr>
+ <td class="memname">enum <a class="el" href="group__styles.html#ga1efef592e2e3df6f00432c04ef77d98f">yaml_mapping_style_e</a></td>
+ </tr>
+ </table>
+</div>
+<div class="memdoc">
+
+<p>Mapping styles. </p>
+<dl><dt><b>Enumerator: </b></dt><dd><table border="0" cellspacing="2" cellpadding="0">
+<tr><td valign="top"><em><a class="anchor" id="gga1efef592e2e3df6f00432c04ef77d98fac580a83312204ea142c3d08a4954a74a"></a><!-- doxytag: member="YAML_ANY_MAPPING_STYLE" ref="gga1efef592e2e3df6f00432c04ef77d98fac580a83312204ea142c3d08a4954a74a" args="" -->YAML_ANY_MAPPING_STYLE</em>&nbsp;</td><td>
+<p>Let the emitter choose the style. </p>
+</td></tr>
+<tr><td valign="top"><em><a class="anchor" id="gga1efef592e2e3df6f00432c04ef77d98fad5e70fe97009c8247a45f4620f071874"></a><!-- doxytag: member="YAML_BLOCK_MAPPING_STYLE" ref="gga1efef592e2e3df6f00432c04ef77d98fad5e70fe97009c8247a45f4620f071874" args="" -->YAML_BLOCK_MAPPING_STYLE</em>&nbsp;</td><td>
+<p>The block mapping style. </p>
+</td></tr>
+<tr><td valign="top"><em><a class="anchor" id="gga1efef592e2e3df6f00432c04ef77d98fa4c5425077b0310cbf84e1d73e20b42d3"></a><!-- doxytag: member="YAML_FLOW_MAPPING_STYLE" ref="gga1efef592e2e3df6f00432c04ef77d98fa4c5425077b0310cbf84e1d73e20b42d3" args="" -->YAML_FLOW_MAPPING_STYLE</em>&nbsp;</td><td>
+<p>The flow mapping style. </p>
+</td></tr>
+</table>
+</dd>
+</dl>
+
+</div>
+</div>
+</div>
+<hr class="footer"/><address class="footer"><small>Generated on Mon May 30 2011 22:00:00 for yaml by&nbsp;
+<a href="http://www.doxygen.org/index.html">
+<img class="footer" src="doxygen.png" alt="doxygen"/></a> 1.7.1 </small></address>
+</body>
+</html>
diff --git a/contrib/libyaml/doc/html/group__tokens.html b/contrib/libyaml/doc/html/group__tokens.html
new file mode 100644
index 0000000..5f2b167
--- /dev/null
+++ b/contrib/libyaml/doc/html/group__tokens.html
@@ -0,0 +1,246 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head>
+<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/>
+<title>yaml: Tokens</title>
+<link href="tabs.css" rel="stylesheet" type="text/css"/>
+<link href="doxygen.css" rel="stylesheet" type="text/css"/>
+</head>
+<body>
+<!-- Generated by Doxygen 1.7.1 -->
+<div class="navigation" id="top">
+ <div class="tabs">
+ <ul class="tablist">
+ <li><a href="index.html"><span>Main&nbsp;Page</span></a></li>
+ <li><a href="modules.html"><span>Modules</span></a></li>
+ <li><a href="annotated.html"><span>Data&nbsp;Structures</span></a></li>
+ <li><a href="files.html"><span>Files</span></a></li>
+ </ul>
+ </div>
+</div>
+<div class="header">
+ <div class="summary">
+<a href="#nested-classes">Data Structures</a> &#124;
+<a href="#typedef-members">Typedefs</a> &#124;
+<a href="#enum-members">Enumerations</a> &#124;
+<a href="#func-members">Functions</a> </div>
+ <div class="headertitle">
+<h1>Tokens</h1> </div>
+</div>
+<div class="contents">
+<table class="memberdecls">
+<tr><td colspan="2"><h2><a name="nested-classes"></a>
+Data Structures</h2></td></tr>
+<tr><td class="memItemLeft" align="right" valign="top">struct &nbsp;</td><td class="memItemRight" valign="bottom"><a class="el" href="structyaml__token__s.html">yaml_token_s</a></td></tr>
+<tr><td class="mdescLeft">&nbsp;</td><td class="mdescRight">The token structure. <a href="structyaml__token__s.html#_details">More...</a><br/></td></tr>
+<tr><td colspan="2"><h2><a name="typedef-members"></a>
+Typedefs</h2></td></tr>
+<tr><td class="memItemLeft" align="right" valign="top">typedef enum <a class="el" href="group__tokens.html#gaae955b10aa6b5f922de64873bf4ccdbd">yaml_token_type_e</a>&nbsp;</td><td class="memItemRight" valign="bottom"><a class="el" href="group__tokens.html#gaba51dda022dced02f8df2224ab7993f7">yaml_token_type_t</a></td></tr>
+<tr><td class="mdescLeft">&nbsp;</td><td class="mdescRight">Token types. <a href="#gaba51dda022dced02f8df2224ab7993f7"></a><br/></td></tr>
+<tr><td class="memItemLeft" align="right" valign="top">typedef struct <a class="el" href="structyaml__token__s.html">yaml_token_s</a>&nbsp;</td><td class="memItemRight" valign="bottom"><a class="el" href="group__tokens.html#ga1ed3dc460e62aee8270c5d63d5734bbb">yaml_token_t</a></td></tr>
+<tr><td class="mdescLeft">&nbsp;</td><td class="mdescRight">The token structure. <a href="#ga1ed3dc460e62aee8270c5d63d5734bbb"></a><br/></td></tr>
+<tr><td colspan="2"><h2><a name="enum-members"></a>
+Enumerations</h2></td></tr>
+<tr><td class="memItemLeft" align="right" valign="top">enum &nbsp;</td><td class="memItemRight" valign="bottom"><a class="el" href="group__tokens.html#gaae955b10aa6b5f922de64873bf4ccdbd">yaml_token_type_e</a> { <br/>
+&nbsp;&nbsp;<a class="el" href="group__tokens.html#ggaae955b10aa6b5f922de64873bf4ccdbda66c1b8eec0cc6402c0fb4b2d1b017f92">YAML_NO_TOKEN</a>,
+<br/>
+&nbsp;&nbsp;<a class="el" href="group__tokens.html#ggaae955b10aa6b5f922de64873bf4ccdbdaf5f42f2d5025e5629034848d2e1db6c9">YAML_STREAM_START_TOKEN</a>,
+<br/>
+&nbsp;&nbsp;<a class="el" href="group__tokens.html#ggaae955b10aa6b5f922de64873bf4ccdbda020a0a266ed7fc4902dd02750512dc19">YAML_STREAM_END_TOKEN</a>,
+<br/>
+&nbsp;&nbsp;<a class="el" href="group__tokens.html#ggaae955b10aa6b5f922de64873bf4ccdbdaa15a96ec81c00c7db8f83628a89542e4">YAML_VERSION_DIRECTIVE_TOKEN</a>,
+<br/>
+&nbsp;&nbsp;<a class="el" href="group__tokens.html#ggaae955b10aa6b5f922de64873bf4ccdbdaed517a61b868769e2bfced40678be414">YAML_TAG_DIRECTIVE_TOKEN</a>,
+<br/>
+&nbsp;&nbsp;<a class="el" href="group__tokens.html#ggaae955b10aa6b5f922de64873bf4ccdbdabcafcdb506886387f93cca734ddfd670">YAML_DOCUMENT_START_TOKEN</a>,
+<br/>
+&nbsp;&nbsp;<a class="el" href="group__tokens.html#ggaae955b10aa6b5f922de64873bf4ccdbda8d0908a82229f44d5ea92a2c380f4579">YAML_DOCUMENT_END_TOKEN</a>,
+<br/>
+&nbsp;&nbsp;<a class="el" href="group__tokens.html#ggaae955b10aa6b5f922de64873bf4ccdbda4bfddc427da159168ee47267cbeea94f">YAML_BLOCK_SEQUENCE_START_TOKEN</a>,
+<br/>
+&nbsp;&nbsp;<a class="el" href="group__tokens.html#ggaae955b10aa6b5f922de64873bf4ccdbda9a95db99bd99f7f9b4e1e879106297dc">YAML_BLOCK_MAPPING_START_TOKEN</a>,
+<br/>
+&nbsp;&nbsp;<a class="el" href="group__tokens.html#ggaae955b10aa6b5f922de64873bf4ccdbda439948425097b4fc853f39f0de14a5ff">YAML_BLOCK_END_TOKEN</a>,
+<br/>
+&nbsp;&nbsp;<a class="el" href="group__tokens.html#ggaae955b10aa6b5f922de64873bf4ccdbda862a2390be4abd59bb7bf55b18d9260c">YAML_FLOW_SEQUENCE_START_TOKEN</a>,
+<br/>
+&nbsp;&nbsp;<a class="el" href="group__tokens.html#ggaae955b10aa6b5f922de64873bf4ccdbdab3496580bee30936f756e0102e98f331">YAML_FLOW_SEQUENCE_END_TOKEN</a>,
+<br/>
+&nbsp;&nbsp;<a class="el" href="group__tokens.html#ggaae955b10aa6b5f922de64873bf4ccdbdaff68a3f7c000c5294211eef8f4156100">YAML_FLOW_MAPPING_START_TOKEN</a>,
+<br/>
+&nbsp;&nbsp;<a class="el" href="group__tokens.html#ggaae955b10aa6b5f922de64873bf4ccdbdaad99bf47234572d9d0eeea7669d1e769">YAML_FLOW_MAPPING_END_TOKEN</a>,
+<br/>
+&nbsp;&nbsp;<a class="el" href="group__tokens.html#ggaae955b10aa6b5f922de64873bf4ccdbdaa9bdf1d6da41fcd4d356c7bcfa0227b4">YAML_BLOCK_ENTRY_TOKEN</a>,
+<br/>
+&nbsp;&nbsp;<a class="el" href="group__tokens.html#ggaae955b10aa6b5f922de64873bf4ccdbdaf11ab5655350e4cf0559f78382daa93f">YAML_FLOW_ENTRY_TOKEN</a>,
+<br/>
+&nbsp;&nbsp;<a class="el" href="group__tokens.html#ggaae955b10aa6b5f922de64873bf4ccdbda94d701c1f5bb8a392bb45b7cbf4bc2a5">YAML_KEY_TOKEN</a>,
+<br/>
+&nbsp;&nbsp;<a class="el" href="group__tokens.html#ggaae955b10aa6b5f922de64873bf4ccdbdaac46e8a6a6e0614de322c7b53d785b4e">YAML_VALUE_TOKEN</a>,
+<br/>
+&nbsp;&nbsp;<a class="el" href="group__tokens.html#ggaae955b10aa6b5f922de64873bf4ccdbda080c398f6fc31f9ab35c7cf94cf948c2">YAML_ALIAS_TOKEN</a>,
+<br/>
+&nbsp;&nbsp;<a class="el" href="group__tokens.html#ggaae955b10aa6b5f922de64873bf4ccdbda7f0855938c5ccc4820b68ddd7985a5d0">YAML_ANCHOR_TOKEN</a>,
+<br/>
+&nbsp;&nbsp;<a class="el" href="group__tokens.html#ggaae955b10aa6b5f922de64873bf4ccdbda8f02c514b72f29bd3c26b7c832d8152d">YAML_TAG_TOKEN</a>,
+<br/>
+&nbsp;&nbsp;<a class="el" href="group__tokens.html#ggaae955b10aa6b5f922de64873bf4ccdbda107a78f31dd9857d06e9ead7936ea51e">YAML_SCALAR_TOKEN</a>
+<br/>
+ }</td></tr>
+<tr><td class="mdescLeft">&nbsp;</td><td class="mdescRight"><p>Token types. </p>
+ <a href="group__tokens.html#gaae955b10aa6b5f922de64873bf4ccdbd">More...</a><br/></td></tr>
+<tr><td colspan="2"><h2><a name="func-members"></a>
+Functions</h2></td></tr>
+<tr><td class="memItemLeft" align="right" valign="top">void&nbsp;</td><td class="memItemRight" valign="bottom"><a class="el" href="group__tokens.html#ga3140131870e38e27f92a8fd286e5c004">yaml_token_delete</a> (<a class="el" href="structyaml__token__s.html">yaml_token_t</a> *token)</td></tr>
+<tr><td class="mdescLeft">&nbsp;</td><td class="mdescRight">Free any memory allocated for a token object. <a href="#ga3140131870e38e27f92a8fd286e5c004"></a><br/></td></tr>
+</table>
+<hr/><h2>Typedef Documentation</h2>
+<a class="anchor" id="gaba51dda022dced02f8df2224ab7993f7"></a><!-- doxytag: member="yaml.h::yaml_token_type_t" ref="gaba51dda022dced02f8df2224ab7993f7" args="" -->
+<div class="memitem">
+<div class="memproto">
+ <table class="memname">
+ <tr>
+ <td class="memname">typedef enum <a class="el" href="group__tokens.html#gaae955b10aa6b5f922de64873bf4ccdbd">yaml_token_type_e</a> <a class="el" href="group__tokens.html#gaba51dda022dced02f8df2224ab7993f7">yaml_token_type_t</a></td>
+ </tr>
+ </table>
+</div>
+<div class="memdoc">
+
+<p>Token types. </p>
+
+</div>
+</div>
+<a class="anchor" id="ga1ed3dc460e62aee8270c5d63d5734bbb"></a><!-- doxytag: member="yaml.h::yaml_token_t" ref="ga1ed3dc460e62aee8270c5d63d5734bbb" args="" -->
+<div class="memitem">
+<div class="memproto">
+ <table class="memname">
+ <tr>
+ <td class="memname">typedef struct <a class="el" href="structyaml__token__s.html">yaml_token_s</a> <a class="el" href="structyaml__token__s.html">yaml_token_t</a></td>
+ </tr>
+ </table>
+</div>
+<div class="memdoc">
+
+<p>The token structure. </p>
+
+</div>
+</div>
+<hr/><h2>Enumeration Type Documentation</h2>
+<a class="anchor" id="gaae955b10aa6b5f922de64873bf4ccdbd"></a><!-- doxytag: member="yaml.h::yaml_token_type_e" ref="gaae955b10aa6b5f922de64873bf4ccdbd" args="" -->
+<div class="memitem">
+<div class="memproto">
+ <table class="memname">
+ <tr>
+ <td class="memname">enum <a class="el" href="group__tokens.html#gaae955b10aa6b5f922de64873bf4ccdbd">yaml_token_type_e</a></td>
+ </tr>
+ </table>
+</div>
+<div class="memdoc">
+
+<p>Token types. </p>
+<dl><dt><b>Enumerator: </b></dt><dd><table border="0" cellspacing="2" cellpadding="0">
+<tr><td valign="top"><em><a class="anchor" id="ggaae955b10aa6b5f922de64873bf4ccdbda66c1b8eec0cc6402c0fb4b2d1b017f92"></a><!-- doxytag: member="YAML_NO_TOKEN" ref="ggaae955b10aa6b5f922de64873bf4ccdbda66c1b8eec0cc6402c0fb4b2d1b017f92" args="" -->YAML_NO_TOKEN</em>&nbsp;</td><td>
+<p>An empty token. </p>
+</td></tr>
+<tr><td valign="top"><em><a class="anchor" id="ggaae955b10aa6b5f922de64873bf4ccdbdaf5f42f2d5025e5629034848d2e1db6c9"></a><!-- doxytag: member="YAML_STREAM_START_TOKEN" ref="ggaae955b10aa6b5f922de64873bf4ccdbdaf5f42f2d5025e5629034848d2e1db6c9" args="" -->YAML_STREAM_START_TOKEN</em>&nbsp;</td><td>
+<p>A STREAM-START token. </p>
+</td></tr>
+<tr><td valign="top"><em><a class="anchor" id="ggaae955b10aa6b5f922de64873bf4ccdbda020a0a266ed7fc4902dd02750512dc19"></a><!-- doxytag: member="YAML_STREAM_END_TOKEN" ref="ggaae955b10aa6b5f922de64873bf4ccdbda020a0a266ed7fc4902dd02750512dc19" args="" -->YAML_STREAM_END_TOKEN</em>&nbsp;</td><td>
+<p>A STREAM-END token. </p>
+</td></tr>
+<tr><td valign="top"><em><a class="anchor" id="ggaae955b10aa6b5f922de64873bf4ccdbdaa15a96ec81c00c7db8f83628a89542e4"></a><!-- doxytag: member="YAML_VERSION_DIRECTIVE_TOKEN" ref="ggaae955b10aa6b5f922de64873bf4ccdbdaa15a96ec81c00c7db8f83628a89542e4" args="" -->YAML_VERSION_DIRECTIVE_TOKEN</em>&nbsp;</td><td>
+<p>A VERSION-DIRECTIVE token. </p>
+</td></tr>
+<tr><td valign="top"><em><a class="anchor" id="ggaae955b10aa6b5f922de64873bf4ccdbdaed517a61b868769e2bfced40678be414"></a><!-- doxytag: member="YAML_TAG_DIRECTIVE_TOKEN" ref="ggaae955b10aa6b5f922de64873bf4ccdbdaed517a61b868769e2bfced40678be414" args="" -->YAML_TAG_DIRECTIVE_TOKEN</em>&nbsp;</td><td>
+<p>A TAG-DIRECTIVE token. </p>
+</td></tr>
+<tr><td valign="top"><em><a class="anchor" id="ggaae955b10aa6b5f922de64873bf4ccdbdabcafcdb506886387f93cca734ddfd670"></a><!-- doxytag: member="YAML_DOCUMENT_START_TOKEN" ref="ggaae955b10aa6b5f922de64873bf4ccdbdabcafcdb506886387f93cca734ddfd670" args="" -->YAML_DOCUMENT_START_TOKEN</em>&nbsp;</td><td>
+<p>A DOCUMENT-START token. </p>
+</td></tr>
+<tr><td valign="top"><em><a class="anchor" id="ggaae955b10aa6b5f922de64873bf4ccdbda8d0908a82229f44d5ea92a2c380f4579"></a><!-- doxytag: member="YAML_DOCUMENT_END_TOKEN" ref="ggaae955b10aa6b5f922de64873bf4ccdbda8d0908a82229f44d5ea92a2c380f4579" args="" -->YAML_DOCUMENT_END_TOKEN</em>&nbsp;</td><td>
+<p>A DOCUMENT-END token. </p>
+</td></tr>
+<tr><td valign="top"><em><a class="anchor" id="ggaae955b10aa6b5f922de64873bf4ccdbda4bfddc427da159168ee47267cbeea94f"></a><!-- doxytag: member="YAML_BLOCK_SEQUENCE_START_TOKEN" ref="ggaae955b10aa6b5f922de64873bf4ccdbda4bfddc427da159168ee47267cbeea94f" args="" -->YAML_BLOCK_SEQUENCE_START_TOKEN</em>&nbsp;</td><td>
+<p>A BLOCK-SEQUENCE-START token. </p>
+</td></tr>
+<tr><td valign="top"><em><a class="anchor" id="ggaae955b10aa6b5f922de64873bf4ccdbda9a95db99bd99f7f9b4e1e879106297dc"></a><!-- doxytag: member="YAML_BLOCK_MAPPING_START_TOKEN" ref="ggaae955b10aa6b5f922de64873bf4ccdbda9a95db99bd99f7f9b4e1e879106297dc" args="" -->YAML_BLOCK_MAPPING_START_TOKEN</em>&nbsp;</td><td>
+<p>A BLOCK-SEQUENCE-END token. </p>
+</td></tr>
+<tr><td valign="top"><em><a class="anchor" id="ggaae955b10aa6b5f922de64873bf4ccdbda439948425097b4fc853f39f0de14a5ff"></a><!-- doxytag: member="YAML_BLOCK_END_TOKEN" ref="ggaae955b10aa6b5f922de64873bf4ccdbda439948425097b4fc853f39f0de14a5ff" args="" -->YAML_BLOCK_END_TOKEN</em>&nbsp;</td><td>
+<p>A BLOCK-END token. </p>
+</td></tr>
+<tr><td valign="top"><em><a class="anchor" id="ggaae955b10aa6b5f922de64873bf4ccdbda862a2390be4abd59bb7bf55b18d9260c"></a><!-- doxytag: member="YAML_FLOW_SEQUENCE_START_TOKEN" ref="ggaae955b10aa6b5f922de64873bf4ccdbda862a2390be4abd59bb7bf55b18d9260c" args="" -->YAML_FLOW_SEQUENCE_START_TOKEN</em>&nbsp;</td><td>
+<p>A FLOW-SEQUENCE-START token. </p>
+</td></tr>
+<tr><td valign="top"><em><a class="anchor" id="ggaae955b10aa6b5f922de64873bf4ccdbdab3496580bee30936f756e0102e98f331"></a><!-- doxytag: member="YAML_FLOW_SEQUENCE_END_TOKEN" ref="ggaae955b10aa6b5f922de64873bf4ccdbdab3496580bee30936f756e0102e98f331" args="" -->YAML_FLOW_SEQUENCE_END_TOKEN</em>&nbsp;</td><td>
+<p>A FLOW-SEQUENCE-END token. </p>
+</td></tr>
+<tr><td valign="top"><em><a class="anchor" id="ggaae955b10aa6b5f922de64873bf4ccdbdaff68a3f7c000c5294211eef8f4156100"></a><!-- doxytag: member="YAML_FLOW_MAPPING_START_TOKEN" ref="ggaae955b10aa6b5f922de64873bf4ccdbdaff68a3f7c000c5294211eef8f4156100" args="" -->YAML_FLOW_MAPPING_START_TOKEN</em>&nbsp;</td><td>
+<p>A FLOW-MAPPING-START token. </p>
+</td></tr>
+<tr><td valign="top"><em><a class="anchor" id="ggaae955b10aa6b5f922de64873bf4ccdbdaad99bf47234572d9d0eeea7669d1e769"></a><!-- doxytag: member="YAML_FLOW_MAPPING_END_TOKEN" ref="ggaae955b10aa6b5f922de64873bf4ccdbdaad99bf47234572d9d0eeea7669d1e769" args="" -->YAML_FLOW_MAPPING_END_TOKEN</em>&nbsp;</td><td>
+<p>A FLOW-MAPPING-END token. </p>
+</td></tr>
+<tr><td valign="top"><em><a class="anchor" id="ggaae955b10aa6b5f922de64873bf4ccdbdaa9bdf1d6da41fcd4d356c7bcfa0227b4"></a><!-- doxytag: member="YAML_BLOCK_ENTRY_TOKEN" ref="ggaae955b10aa6b5f922de64873bf4ccdbdaa9bdf1d6da41fcd4d356c7bcfa0227b4" args="" -->YAML_BLOCK_ENTRY_TOKEN</em>&nbsp;</td><td>
+<p>A BLOCK-ENTRY token. </p>
+</td></tr>
+<tr><td valign="top"><em><a class="anchor" id="ggaae955b10aa6b5f922de64873bf4ccdbdaf11ab5655350e4cf0559f78382daa93f"></a><!-- doxytag: member="YAML_FLOW_ENTRY_TOKEN" ref="ggaae955b10aa6b5f922de64873bf4ccdbdaf11ab5655350e4cf0559f78382daa93f" args="" -->YAML_FLOW_ENTRY_TOKEN</em>&nbsp;</td><td>
+<p>A FLOW-ENTRY token. </p>
+</td></tr>
+<tr><td valign="top"><em><a class="anchor" id="ggaae955b10aa6b5f922de64873bf4ccdbda94d701c1f5bb8a392bb45b7cbf4bc2a5"></a><!-- doxytag: member="YAML_KEY_TOKEN" ref="ggaae955b10aa6b5f922de64873bf4ccdbda94d701c1f5bb8a392bb45b7cbf4bc2a5" args="" -->YAML_KEY_TOKEN</em>&nbsp;</td><td>
+<p>A KEY token. </p>
+</td></tr>
+<tr><td valign="top"><em><a class="anchor" id="ggaae955b10aa6b5f922de64873bf4ccdbdaac46e8a6a6e0614de322c7b53d785b4e"></a><!-- doxytag: member="YAML_VALUE_TOKEN" ref="ggaae955b10aa6b5f922de64873bf4ccdbdaac46e8a6a6e0614de322c7b53d785b4e" args="" -->YAML_VALUE_TOKEN</em>&nbsp;</td><td>
+<p>A VALUE token. </p>
+</td></tr>
+<tr><td valign="top"><em><a class="anchor" id="ggaae955b10aa6b5f922de64873bf4ccdbda080c398f6fc31f9ab35c7cf94cf948c2"></a><!-- doxytag: member="YAML_ALIAS_TOKEN" ref="ggaae955b10aa6b5f922de64873bf4ccdbda080c398f6fc31f9ab35c7cf94cf948c2" args="" -->YAML_ALIAS_TOKEN</em>&nbsp;</td><td>
+<p>An ALIAS token. </p>
+</td></tr>
+<tr><td valign="top"><em><a class="anchor" id="ggaae955b10aa6b5f922de64873bf4ccdbda7f0855938c5ccc4820b68ddd7985a5d0"></a><!-- doxytag: member="YAML_ANCHOR_TOKEN" ref="ggaae955b10aa6b5f922de64873bf4ccdbda7f0855938c5ccc4820b68ddd7985a5d0" args="" -->YAML_ANCHOR_TOKEN</em>&nbsp;</td><td>
+<p>An ANCHOR token. </p>
+</td></tr>
+<tr><td valign="top"><em><a class="anchor" id="ggaae955b10aa6b5f922de64873bf4ccdbda8f02c514b72f29bd3c26b7c832d8152d"></a><!-- doxytag: member="YAML_TAG_TOKEN" ref="ggaae955b10aa6b5f922de64873bf4ccdbda8f02c514b72f29bd3c26b7c832d8152d" args="" -->YAML_TAG_TOKEN</em>&nbsp;</td><td>
+<p>A TAG token. </p>
+</td></tr>
+<tr><td valign="top"><em><a class="anchor" id="ggaae955b10aa6b5f922de64873bf4ccdbda107a78f31dd9857d06e9ead7936ea51e"></a><!-- doxytag: member="YAML_SCALAR_TOKEN" ref="ggaae955b10aa6b5f922de64873bf4ccdbda107a78f31dd9857d06e9ead7936ea51e" args="" -->YAML_SCALAR_TOKEN</em>&nbsp;</td><td>
+<p>A SCALAR token. </p>
+</td></tr>
+</table>
+</dd>
+</dl>
+
+</div>
+</div>
+<hr/><h2>Function Documentation</h2>
+<a class="anchor" id="ga3140131870e38e27f92a8fd286e5c004"></a><!-- doxytag: member="yaml.h::yaml_token_delete" ref="ga3140131870e38e27f92a8fd286e5c004" args="(yaml_token_t *token)" -->
+<div class="memitem">
+<div class="memproto">
+ <table class="memname">
+ <tr>
+ <td class="memname">void yaml_token_delete </td>
+ <td>(</td>
+ <td class="paramtype"><a class="el" href="structyaml__token__s.html">yaml_token_t</a> *&nbsp;</td>
+ <td class="paramname"> <em>token</em></td>
+ <td>&nbsp;)&nbsp;</td>
+ <td></td>
+ </tr>
+ </table>
+</div>
+<div class="memdoc">
+
+<p>Free any memory allocated for a token object. </p>
+<dl><dt><b>Parameters:</b></dt><dd>
+ <table border="0" cellspacing="2" cellpadding="0">
+ <tr><td valign="top"><tt>[in,out]</tt>&nbsp;</td><td valign="top"><em>token</em>&nbsp;</td><td>A token object. </td></tr>
+ </table>
+ </dd>
+</dl>
+
+</div>
+</div>
+</div>
+<hr class="footer"/><address class="footer"><small>Generated on Mon May 30 2011 22:00:00 for yaml by&nbsp;
+<a href="http://www.doxygen.org/index.html">
+<img class="footer" src="doxygen.png" alt="doxygen"/></a> 1.7.1 </small></address>
+</body>
+</html>
diff --git a/contrib/libyaml/doc/html/group__version.html b/contrib/libyaml/doc/html/group__version.html
new file mode 100644
index 0000000..9949f30
--- /dev/null
+++ b/contrib/libyaml/doc/html/group__version.html
@@ -0,0 +1,106 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head>
+<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/>
+<title>yaml: Version Information</title>
+<link href="tabs.css" rel="stylesheet" type="text/css"/>
+<link href="doxygen.css" rel="stylesheet" type="text/css"/>
+</head>
+<body>
+<!-- Generated by Doxygen 1.7.1 -->
+<div class="navigation" id="top">
+ <div class="tabs">
+ <ul class="tablist">
+ <li><a href="index.html"><span>Main&nbsp;Page</span></a></li>
+ <li><a href="modules.html"><span>Modules</span></a></li>
+ <li><a href="annotated.html"><span>Data&nbsp;Structures</span></a></li>
+ <li><a href="files.html"><span>Files</span></a></li>
+ </ul>
+ </div>
+</div>
+<div class="header">
+ <div class="summary">
+<a href="#func-members">Functions</a> </div>
+ <div class="headertitle">
+<h1>Version Information</h1> </div>
+</div>
+<div class="contents">
+<table class="memberdecls">
+<tr><td colspan="2"><h2><a name="func-members"></a>
+Functions</h2></td></tr>
+<tr><td class="memItemLeft" align="right" valign="top">const char *&nbsp;</td><td class="memItemRight" valign="bottom"><a class="el" href="group__version.html#gaf1ba5c1c34e809db5047d79a9fa85a73">yaml_get_version_string</a> (void)</td></tr>
+<tr><td class="mdescLeft">&nbsp;</td><td class="mdescRight">Get the library version as a string. <a href="#gaf1ba5c1c34e809db5047d79a9fa85a73"></a><br/></td></tr>
+<tr><td class="memItemLeft" align="right" valign="top">void&nbsp;</td><td class="memItemRight" valign="bottom"><a class="el" href="group__version.html#gaec764c91f3e181ae63d3d59b7980fe78">yaml_get_version</a> (int *major, int *minor, int *patch)</td></tr>
+<tr><td class="mdescLeft">&nbsp;</td><td class="mdescRight">Get the library version numbers. <a href="#gaec764c91f3e181ae63d3d59b7980fe78"></a><br/></td></tr>
+</table>
+<hr/><h2>Function Documentation</h2>
+<a class="anchor" id="gaf1ba5c1c34e809db5047d79a9fa85a73"></a><!-- doxytag: member="yaml.h::yaml_get_version_string" ref="gaf1ba5c1c34e809db5047d79a9fa85a73" args="(void)" -->
+<div class="memitem">
+<div class="memproto">
+ <table class="memname">
+ <tr>
+ <td class="memname">const char* yaml_get_version_string </td>
+ <td>(</td>
+ <td class="paramtype">void&nbsp;</td>
+ <td class="paramname"></td>
+ <td>&nbsp;)&nbsp;</td>
+ <td></td>
+ </tr>
+ </table>
+</div>
+<div class="memdoc">
+
+<p>Get the library version as a string. </p>
+<dl class="return"><dt><b>Returns:</b></dt><dd>The function returns the pointer to a static string of the form <code>"X.Y.Z"</code>, where <code>X</code> is the major version number, <code>Y</code> is a minor version number, and <code>Z</code> is the patch version number. </dd></dl>
+
+</div>
+</div>
+<a class="anchor" id="gaec764c91f3e181ae63d3d59b7980fe78"></a><!-- doxytag: member="yaml.h::yaml_get_version" ref="gaec764c91f3e181ae63d3d59b7980fe78" args="(int *major, int *minor, int *patch)" -->
+<div class="memitem">
+<div class="memproto">
+ <table class="memname">
+ <tr>
+ <td class="memname">void yaml_get_version </td>
+ <td>(</td>
+ <td class="paramtype">int *&nbsp;</td>
+ <td class="paramname"> <em>major</em>, </td>
+ </tr>
+ <tr>
+ <td class="paramkey"></td>
+ <td></td>
+ <td class="paramtype">int *&nbsp;</td>
+ <td class="paramname"> <em>minor</em>, </td>
+ </tr>
+ <tr>
+ <td class="paramkey"></td>
+ <td></td>
+ <td class="paramtype">int *&nbsp;</td>
+ <td class="paramname"> <em>patch</em></td><td>&nbsp;</td>
+ </tr>
+ <tr>
+ <td></td>
+ <td>)</td>
+ <td></td><td></td><td></td>
+ </tr>
+ </table>
+</div>
+<div class="memdoc">
+
+<p>Get the library version numbers. </p>
+<dl><dt><b>Parameters:</b></dt><dd>
+ <table border="0" cellspacing="2" cellpadding="0">
+ <tr><td valign="top"><tt>[out]</tt>&nbsp;</td><td valign="top"><em>major</em>&nbsp;</td><td>Major version number. </td></tr>
+ <tr><td valign="top"><tt>[out]</tt>&nbsp;</td><td valign="top"><em>minor</em>&nbsp;</td><td>Minor version number. </td></tr>
+ <tr><td valign="top"><tt>[out]</tt>&nbsp;</td><td valign="top"><em>patch</em>&nbsp;</td><td>Patch version number. </td></tr>
+ </table>
+ </dd>
+</dl>
+
+</div>
+</div>
+</div>
+<hr class="footer"/><address class="footer"><small>Generated on Mon May 30 2011 22:00:00 for yaml by&nbsp;
+<a href="http://www.doxygen.org/index.html">
+<img class="footer" src="doxygen.png" alt="doxygen"/></a> 1.7.1 </small></address>
+</body>
+</html>
diff --git a/contrib/libyaml/doc/html/index.html b/contrib/libyaml/doc/html/index.html
new file mode 100644
index 0000000..b909ab2
--- /dev/null
+++ b/contrib/libyaml/doc/html/index.html
@@ -0,0 +1,31 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head>
+<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/>
+<title>yaml: Main Page</title>
+<link href="tabs.css" rel="stylesheet" type="text/css"/>
+<link href="doxygen.css" rel="stylesheet" type="text/css"/>
+</head>
+<body>
+<!-- Generated by Doxygen 1.7.1 -->
+<div class="navigation" id="top">
+ <div class="tabs">
+ <ul class="tablist">
+ <li class="current"><a href="index.html"><span>Main&nbsp;Page</span></a></li>
+ <li><a href="modules.html"><span>Modules</span></a></li>
+ <li><a href="annotated.html"><span>Data&nbsp;Structures</span></a></li>
+ <li><a href="files.html"><span>Files</span></a></li>
+ </ul>
+ </div>
+</div>
+<div class="header">
+ <div class="headertitle">
+<h1>yaml Documentation</h1> </div>
+</div>
+<div class="contents">
+<h3 class="version">0.1.4 </h3></div>
+<hr class="footer"/><address class="footer"><small>Generated on Mon May 30 2011 22:00:00 for yaml by&nbsp;
+<a href="http://www.doxygen.org/index.html">
+<img class="footer" src="doxygen.png" alt="doxygen"/></a> 1.7.1 </small></address>
+</body>
+</html>
diff --git a/contrib/libyaml/doc/html/modules.html b/contrib/libyaml/doc/html/modules.html
new file mode 100644
index 0000000..6b48536
--- /dev/null
+++ b/contrib/libyaml/doc/html/modules.html
@@ -0,0 +1,42 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head>
+<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/>
+<title>yaml: Module Index</title>
+<link href="tabs.css" rel="stylesheet" type="text/css"/>
+<link href="doxygen.css" rel="stylesheet" type="text/css"/>
+</head>
+<body>
+<!-- Generated by Doxygen 1.7.1 -->
+<div class="navigation" id="top">
+ <div class="tabs">
+ <ul class="tablist">
+ <li><a href="index.html"><span>Main&nbsp;Page</span></a></li>
+ <li class="current"><a href="modules.html"><span>Modules</span></a></li>
+ <li><a href="annotated.html"><span>Data&nbsp;Structures</span></a></li>
+ <li><a href="files.html"><span>Files</span></a></li>
+ </ul>
+ </div>
+</div>
+<div class="header">
+ <div class="headertitle">
+<h1>Modules</h1> </div>
+</div>
+<div class="contents">
+Here is a list of all modules:<ul>
+<li><a class="el" href="group__export.html">Export Definitions</a></li>
+<li><a class="el" href="group__version.html">Version Information</a></li>
+<li><a class="el" href="group__basic.html">Basic Types</a></li>
+<li><a class="el" href="group__styles.html">Node Styles</a></li>
+<li><a class="el" href="group__tokens.html">Tokens</a></li>
+<li><a class="el" href="group__events.html">Events</a></li>
+<li><a class="el" href="group__nodes.html">Nodes</a></li>
+<li><a class="el" href="group__parser.html">Parser Definitions</a></li>
+<li><a class="el" href="group__emitter.html">Emitter Definitions</a></li>
+</ul>
+</div>
+<hr class="footer"/><address class="footer"><small>Generated on Mon May 30 2011 22:00:00 for yaml by&nbsp;
+<a href="http://www.doxygen.org/index.html">
+<img class="footer" src="doxygen.png" alt="doxygen"/></a> 1.7.1 </small></address>
+</body>
+</html>
diff --git a/contrib/libyaml/doc/html/nav_f.png b/contrib/libyaml/doc/html/nav_f.png
new file mode 100644
index 0000000..1b07a16
--- /dev/null
+++ b/contrib/libyaml/doc/html/nav_f.png
Binary files differ
diff --git a/contrib/libyaml/doc/html/nav_h.png b/contrib/libyaml/doc/html/nav_h.png
new file mode 100644
index 0000000..01f5fa6
--- /dev/null
+++ b/contrib/libyaml/doc/html/nav_h.png
Binary files differ
diff --git a/contrib/libyaml/doc/html/open.png b/contrib/libyaml/doc/html/open.png
new file mode 100644
index 0000000..7b35d2c
--- /dev/null
+++ b/contrib/libyaml/doc/html/open.png
Binary files differ
diff --git a/contrib/libyaml/doc/html/structyaml__alias__data__s.html b/contrib/libyaml/doc/html/structyaml__alias__data__s.html
new file mode 100644
index 0000000..daff45c
--- /dev/null
+++ b/contrib/libyaml/doc/html/structyaml__alias__data__s.html
@@ -0,0 +1,108 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head>
+<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/>
+<title>yaml: yaml_alias_data_s Struct Reference</title>
+<link href="tabs.css" rel="stylesheet" type="text/css"/>
+<link href="doxygen.css" rel="stylesheet" type="text/css"/>
+</head>
+<body>
+<!-- Generated by Doxygen 1.7.1 -->
+<div class="navigation" id="top">
+ <div class="tabs">
+ <ul class="tablist">
+ <li><a href="index.html"><span>Main&nbsp;Page</span></a></li>
+ <li><a href="modules.html"><span>Modules</span></a></li>
+ <li class="current"><a href="annotated.html"><span>Data&nbsp;Structures</span></a></li>
+ <li><a href="files.html"><span>Files</span></a></li>
+ </ul>
+ </div>
+ <div class="tabs2">
+ <ul class="tablist">
+ <li><a href="annotated.html"><span>Data&nbsp;Structures</span></a></li>
+ <li><a href="functions.html"><span>Data&nbsp;Fields</span></a></li>
+ </ul>
+ </div>
+</div>
+<div class="header">
+ <div class="summary">
+<a href="#pub-attribs">Data Fields</a> </div>
+ <div class="headertitle">
+<h1>yaml_alias_data_s Struct Reference<br/>
+<small>
+[<a class="el" href="group__parser.html">Parser Definitions</a>]</small>
+</h1> </div>
+</div>
+<div class="contents">
+<!-- doxytag: class="yaml_alias_data_s" -->
+<p>This structure holds aliases data.
+<a href="#_details">More...</a></p>
+
+<p><code>#include &lt;yaml.h&gt;</code></p>
+<table class="memberdecls">
+<tr><td colspan="2"><h2><a name="pub-attribs"></a>
+Data Fields</h2></td></tr>
+<tr><td class="memItemLeft" align="right" valign="top"><a class="el" href="group__basic.html#gaf8657e81f0b8b05d1a081001fc6cb8bd">yaml_char_t</a> *&nbsp;</td><td class="memItemRight" valign="bottom"><a class="el" href="structyaml__alias__data__s.html#ac4b9a352dd8ff747bfa63a54832d7962">anchor</a></td></tr>
+<tr><td class="mdescLeft">&nbsp;</td><td class="mdescRight">The anchor. <a href="#ac4b9a352dd8ff747bfa63a54832d7962"></a><br/></td></tr>
+<tr><td class="memItemLeft" align="right" valign="top">int&nbsp;</td><td class="memItemRight" valign="bottom"><a class="el" href="structyaml__alias__data__s.html#ac45e17508386dec9163b4aa5cfb5312e">index</a></td></tr>
+<tr><td class="mdescLeft">&nbsp;</td><td class="mdescRight">The node id. <a href="#ac45e17508386dec9163b4aa5cfb5312e"></a><br/></td></tr>
+<tr><td class="memItemLeft" align="right" valign="top"><a class="el" href="structyaml__mark__s.html">yaml_mark_t</a>&nbsp;</td><td class="memItemRight" valign="bottom"><a class="el" href="structyaml__alias__data__s.html#a9f8d87255bfc39df69068ed87b602e9f">mark</a></td></tr>
+<tr><td class="mdescLeft">&nbsp;</td><td class="mdescRight">The anchor mark. <a href="#a9f8d87255bfc39df69068ed87b602e9f"></a><br/></td></tr>
+</table>
+<hr/><a name="_details"></a><h2>Detailed Description</h2>
+<p>This structure holds aliases data. </p>
+<hr/><h2>Field Documentation</h2>
+<a class="anchor" id="ac4b9a352dd8ff747bfa63a54832d7962"></a><!-- doxytag: member="yaml_alias_data_s::anchor" ref="ac4b9a352dd8ff747bfa63a54832d7962" args="" -->
+<div class="memitem">
+<div class="memproto">
+ <table class="memname">
+ <tr>
+ <td class="memname"><a class="el" href="group__basic.html#gaf8657e81f0b8b05d1a081001fc6cb8bd">yaml_char_t</a>* <a class="el" href="structyaml__alias__data__s.html#ac4b9a352dd8ff747bfa63a54832d7962">yaml_alias_data_s::anchor</a></td>
+ </tr>
+ </table>
+</div>
+<div class="memdoc">
+
+<p>The anchor. </p>
+
+</div>
+</div>
+<a class="anchor" id="ac45e17508386dec9163b4aa5cfb5312e"></a><!-- doxytag: member="yaml_alias_data_s::index" ref="ac45e17508386dec9163b4aa5cfb5312e" args="" -->
+<div class="memitem">
+<div class="memproto">
+ <table class="memname">
+ <tr>
+ <td class="memname">int <a class="el" href="structyaml__alias__data__s.html#ac45e17508386dec9163b4aa5cfb5312e">yaml_alias_data_s::index</a></td>
+ </tr>
+ </table>
+</div>
+<div class="memdoc">
+
+<p>The node id. </p>
+
+</div>
+</div>
+<a class="anchor" id="a9f8d87255bfc39df69068ed87b602e9f"></a><!-- doxytag: member="yaml_alias_data_s::mark" ref="a9f8d87255bfc39df69068ed87b602e9f" args="" -->
+<div class="memitem">
+<div class="memproto">
+ <table class="memname">
+ <tr>
+ <td class="memname"><a class="el" href="structyaml__mark__s.html">yaml_mark_t</a> <a class="el" href="structyaml__alias__data__s.html#a9f8d87255bfc39df69068ed87b602e9f">yaml_alias_data_s::mark</a></td>
+ </tr>
+ </table>
+</div>
+<div class="memdoc">
+
+<p>The anchor mark. </p>
+
+</div>
+</div>
+<hr/>The documentation for this struct was generated from the following file:<ul>
+<li><a class="el" href="yaml_8h.html">yaml.h</a></li>
+</ul>
+</div>
+<hr class="footer"/><address class="footer"><small>Generated on Mon May 30 2011 22:00:00 for yaml by&nbsp;
+<a href="http://www.doxygen.org/index.html">
+<img class="footer" src="doxygen.png" alt="doxygen"/></a> 1.7.1 </small></address>
+</body>
+</html>
diff --git a/contrib/libyaml/doc/html/structyaml__document__s.html b/contrib/libyaml/doc/html/structyaml__document__s.html
new file mode 100644
index 0000000..fe2a65f
--- /dev/null
+++ b/contrib/libyaml/doc/html/structyaml__document__s.html
@@ -0,0 +1,235 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head>
+<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/>
+<title>yaml: yaml_document_s Struct Reference</title>
+<link href="tabs.css" rel="stylesheet" type="text/css"/>
+<link href="doxygen.css" rel="stylesheet" type="text/css"/>
+</head>
+<body>
+<!-- Generated by Doxygen 1.7.1 -->
+<div class="navigation" id="top">
+ <div class="tabs">
+ <ul class="tablist">
+ <li><a href="index.html"><span>Main&nbsp;Page</span></a></li>
+ <li><a href="modules.html"><span>Modules</span></a></li>
+ <li class="current"><a href="annotated.html"><span>Data&nbsp;Structures</span></a></li>
+ <li><a href="files.html"><span>Files</span></a></li>
+ </ul>
+ </div>
+ <div class="tabs2">
+ <ul class="tablist">
+ <li><a href="annotated.html"><span>Data&nbsp;Structures</span></a></li>
+ <li><a href="functions.html"><span>Data&nbsp;Fields</span></a></li>
+ </ul>
+ </div>
+</div>
+<div class="header">
+ <div class="summary">
+<a href="#pub-attribs">Data Fields</a> </div>
+ <div class="headertitle">
+<h1>yaml_document_s Struct Reference<br/>
+<small>
+[<a class="el" href="group__nodes.html">Nodes</a>]</small>
+</h1> </div>
+</div>
+<div class="contents">
+<!-- doxytag: class="yaml_document_s" -->
+<p>The document structure.
+<a href="#_details">More...</a></p>
+
+<p><code>#include &lt;yaml.h&gt;</code></p>
+<table class="memberdecls">
+<tr><td colspan="2"><h2><a name="pub-attribs"></a>
+Data Fields</h2></td></tr>
+<tr><td class="memItemLeft" >struct {</td></tr>
+<tr><td class="memItemLeft" >&nbsp;&nbsp;&nbsp;<a class="el" href="structyaml__node__s.html">yaml_node_t</a> *&nbsp;&nbsp;&nbsp;<a class="el" href="structyaml__document__s.html#aa3f9a11d8fbe4ac2eada1786176bab89">start</a></td></tr>
+<tr><td class="mdescLeft">&nbsp;</td><td class="mdescRight">The beginning of the stack. <a href="#a47c65aa6e05b1bbdd23ca6bf861057b7"></a><br/></td></tr>
+<tr><td class="memItemLeft" >&nbsp;&nbsp;&nbsp;<a class="el" href="structyaml__node__s.html">yaml_node_t</a> *&nbsp;&nbsp;&nbsp;<a class="el" href="structyaml__document__s.html#adc9ffcca86a2684362428da69ffd3dea">end</a></td></tr>
+<tr><td class="mdescLeft">&nbsp;</td><td class="mdescRight">The end of the stack. <a href="#afbbfd5d4dcbe1f0ce088afa7266518bf"></a><br/></td></tr>
+<tr><td class="memItemLeft" >&nbsp;&nbsp;&nbsp;<a class="el" href="structyaml__node__s.html">yaml_node_t</a> *&nbsp;&nbsp;&nbsp;<a class="el" href="structyaml__document__s.html#a5ac36f59c4a0f28124c2e1630ca4f227">top</a></td></tr>
+<tr><td class="mdescLeft">&nbsp;</td><td class="mdescRight">The top of the stack. <a href="#a39d2f17a1edca2641a6b93646e9931b6"></a><br/></td></tr>
+<tr><td class="memItemLeft" valign="top">}&nbsp;</td><td class="memItemRight" valign="bottom"><a class="el" href="structyaml__document__s.html#aa9eeab76b69cc84a6ab1b02c14cfd594">nodes</a></td></tr>
+<tr><td class="mdescLeft">&nbsp;</td><td class="mdescRight">The document nodes. <a href="#aa9eeab76b69cc84a6ab1b02c14cfd594"></a><br/></td></tr>
+<tr><td class="memItemLeft" align="right" valign="top"><a class="el" href="structyaml__version__directive__s.html">yaml_version_directive_t</a> *&nbsp;</td><td class="memItemRight" valign="bottom"><a class="el" href="structyaml__document__s.html#a7d36862d070804b8bedb53866487ac6d">version_directive</a></td></tr>
+<tr><td class="mdescLeft">&nbsp;</td><td class="mdescRight">The version directive. <a href="#a7d36862d070804b8bedb53866487ac6d"></a><br/></td></tr>
+<tr><td class="memItemLeft" >struct {</td></tr>
+<tr><td class="memItemLeft" >&nbsp;&nbsp;&nbsp;<a class="el" href="structyaml__tag__directive__s.html">yaml_tag_directive_t</a> *&nbsp;&nbsp;&nbsp;<a class="el" href="structyaml__document__s.html#afb9b6cb56a29f880ad6b76c532133c40">start</a></td></tr>
+<tr><td class="mdescLeft">&nbsp;</td><td class="mdescRight">The beginning of the tag directives list. <a href="#a3f9c1d3d7466cc035179e64af2b983d5"></a><br/></td></tr>
+<tr><td class="memItemLeft" >&nbsp;&nbsp;&nbsp;<a class="el" href="structyaml__tag__directive__s.html">yaml_tag_directive_t</a> *&nbsp;&nbsp;&nbsp;<a class="el" href="structyaml__document__s.html#af14fd1a6c1fd10088391f07349ba55e8">end</a></td></tr>
+<tr><td class="mdescLeft">&nbsp;</td><td class="mdescRight">The end of the tag directives list. <a href="#aacdf541ee0945d7b3901a71538a7639f"></a><br/></td></tr>
+<tr><td class="memItemLeft" valign="top">}&nbsp;</td><td class="memItemRight" valign="bottom"><a class="el" href="structyaml__document__s.html#af1e09d0469fc24106f3790b1e3de09e1">tag_directives</a></td></tr>
+<tr><td class="mdescLeft">&nbsp;</td><td class="mdescRight">The list of tag directives. <a href="#af1e09d0469fc24106f3790b1e3de09e1"></a><br/></td></tr>
+<tr><td class="memItemLeft" align="right" valign="top"><a class="anchor" id="a65c49e4f61ca5c2f6ecf410e1cc65787"></a><!-- doxytag: member="yaml_document_s::start_implicit" ref="a65c49e4f61ca5c2f6ecf410e1cc65787" args="" -->
+int&nbsp;</td><td class="memItemRight" valign="bottom"><a class="el" href="structyaml__document__s.html#a65c49e4f61ca5c2f6ecf410e1cc65787">start_implicit</a></td></tr>
+<tr><td class="mdescLeft">&nbsp;</td><td class="mdescRight">Is the document start indicator implicit? <br/></td></tr>
+<tr><td class="memItemLeft" align="right" valign="top"><a class="anchor" id="a59de90b4078659fd0f49377929afcac1"></a><!-- doxytag: member="yaml_document_s::end_implicit" ref="a59de90b4078659fd0f49377929afcac1" args="" -->
+int&nbsp;</td><td class="memItemRight" valign="bottom"><a class="el" href="structyaml__document__s.html#a59de90b4078659fd0f49377929afcac1">end_implicit</a></td></tr>
+<tr><td class="mdescLeft">&nbsp;</td><td class="mdescRight">Is the document end indicator implicit? <br/></td></tr>
+<tr><td class="memItemLeft" align="right" valign="top"><a class="el" href="structyaml__mark__s.html">yaml_mark_t</a>&nbsp;</td><td class="memItemRight" valign="bottom"><a class="el" href="structyaml__document__s.html#a0a37311ebf8f6637e4bc1d280a879997">start_mark</a></td></tr>
+<tr><td class="mdescLeft">&nbsp;</td><td class="mdescRight">The beginning of the document. <a href="#a0a37311ebf8f6637e4bc1d280a879997"></a><br/></td></tr>
+<tr><td class="memItemLeft" align="right" valign="top"><a class="el" href="structyaml__mark__s.html">yaml_mark_t</a>&nbsp;</td><td class="memItemRight" valign="bottom"><a class="el" href="structyaml__document__s.html#a9299efdaadf764f4d03641a3ee51e0d0">end_mark</a></td></tr>
+<tr><td class="mdescLeft">&nbsp;</td><td class="mdescRight">The end of the document. <a href="#a9299efdaadf764f4d03641a3ee51e0d0"></a><br/></td></tr>
+</table>
+<hr/><a name="_details"></a><h2>Detailed Description</h2>
+<p>The document structure. </p>
+<hr/><h2>Field Documentation</h2>
+<a class="anchor" id="aa3f9a11d8fbe4ac2eada1786176bab89"></a><!-- doxytag: member="yaml_document_s::start" ref="aa3f9a11d8fbe4ac2eada1786176bab89" args="" -->
+<div class="memitem">
+<div class="memproto">
+ <table class="memname">
+ <tr>
+ <td class="memname"><a class="el" href="structyaml__node__s.html">yaml_node_t</a>* <a class="el" href="structyaml__document__s.html#aa3f9a11d8fbe4ac2eada1786176bab89">yaml_document_s::start</a></td>
+ </tr>
+ </table>
+</div>
+<div class="memdoc">
+
+<p>The beginning of the stack. </p>
+
+</div>
+</div>
+<a class="anchor" id="adc9ffcca86a2684362428da69ffd3dea"></a><!-- doxytag: member="yaml_document_s::end" ref="adc9ffcca86a2684362428da69ffd3dea" args="" -->
+<div class="memitem">
+<div class="memproto">
+ <table class="memname">
+ <tr>
+ <td class="memname"><a class="el" href="structyaml__node__s.html">yaml_node_t</a>* <a class="el" href="structyaml__document__s.html#adc9ffcca86a2684362428da69ffd3dea">yaml_document_s::end</a></td>
+ </tr>
+ </table>
+</div>
+<div class="memdoc">
+
+<p>The end of the stack. </p>
+
+</div>
+</div>
+<a class="anchor" id="a5ac36f59c4a0f28124c2e1630ca4f227"></a><!-- doxytag: member="yaml_document_s::top" ref="a5ac36f59c4a0f28124c2e1630ca4f227" args="" -->
+<div class="memitem">
+<div class="memproto">
+ <table class="memname">
+ <tr>
+ <td class="memname"><a class="el" href="structyaml__node__s.html">yaml_node_t</a>* <a class="el" href="structyaml__document__s.html#a5ac36f59c4a0f28124c2e1630ca4f227">yaml_document_s::top</a></td>
+ </tr>
+ </table>
+</div>
+<div class="memdoc">
+
+<p>The top of the stack. </p>
+
+</div>
+</div>
+<a class="anchor" id="aa9eeab76b69cc84a6ab1b02c14cfd594"></a><!-- doxytag: member="yaml_document_s::nodes" ref="aa9eeab76b69cc84a6ab1b02c14cfd594" args="" -->
+<div class="memitem">
+<div class="memproto">
+ <table class="memname">
+ <tr>
+ <td class="memname">struct { ... } <a class="el" href="structyaml__document__s.html#aa9eeab76b69cc84a6ab1b02c14cfd594">yaml_document_s::nodes</a></td>
+ </tr>
+ </table>
+</div>
+<div class="memdoc">
+
+<p>The document nodes. </p>
+
+</div>
+</div>
+<a class="anchor" id="a7d36862d070804b8bedb53866487ac6d"></a><!-- doxytag: member="yaml_document_s::version_directive" ref="a7d36862d070804b8bedb53866487ac6d" args="" -->
+<div class="memitem">
+<div class="memproto">
+ <table class="memname">
+ <tr>
+ <td class="memname"><a class="el" href="structyaml__version__directive__s.html">yaml_version_directive_t</a>* <a class="el" href="structyaml__document__s.html#a7d36862d070804b8bedb53866487ac6d">yaml_document_s::version_directive</a></td>
+ </tr>
+ </table>
+</div>
+<div class="memdoc">
+
+<p>The version directive. </p>
+
+</div>
+</div>
+<a class="anchor" id="afb9b6cb56a29f880ad6b76c532133c40"></a><!-- doxytag: member="yaml_document_s::start" ref="afb9b6cb56a29f880ad6b76c532133c40" args="" -->
+<div class="memitem">
+<div class="memproto">
+ <table class="memname">
+ <tr>
+ <td class="memname"><a class="el" href="structyaml__tag__directive__s.html">yaml_tag_directive_t</a>* <a class="el" href="structyaml__document__s.html#aa3f9a11d8fbe4ac2eada1786176bab89">yaml_document_s::start</a></td>
+ </tr>
+ </table>
+</div>
+<div class="memdoc">
+
+<p>The beginning of the tag directives list. </p>
+
+</div>
+</div>
+<a class="anchor" id="af14fd1a6c1fd10088391f07349ba55e8"></a><!-- doxytag: member="yaml_document_s::end" ref="af14fd1a6c1fd10088391f07349ba55e8" args="" -->
+<div class="memitem">
+<div class="memproto">
+ <table class="memname">
+ <tr>
+ <td class="memname"><a class="el" href="structyaml__tag__directive__s.html">yaml_tag_directive_t</a>* <a class="el" href="structyaml__document__s.html#adc9ffcca86a2684362428da69ffd3dea">yaml_document_s::end</a></td>
+ </tr>
+ </table>
+</div>
+<div class="memdoc">
+
+<p>The end of the tag directives list. </p>
+
+</div>
+</div>
+<a class="anchor" id="af1e09d0469fc24106f3790b1e3de09e1"></a><!-- doxytag: member="yaml_document_s::tag_directives" ref="af1e09d0469fc24106f3790b1e3de09e1" args="" -->
+<div class="memitem">
+<div class="memproto">
+ <table class="memname">
+ <tr>
+ <td class="memname">struct { ... } <a class="el" href="structyaml__document__s.html#af1e09d0469fc24106f3790b1e3de09e1">yaml_document_s::tag_directives</a></td>
+ </tr>
+ </table>
+</div>
+<div class="memdoc">
+
+<p>The list of tag directives. </p>
+
+</div>
+</div>
+<a class="anchor" id="a0a37311ebf8f6637e4bc1d280a879997"></a><!-- doxytag: member="yaml_document_s::start_mark" ref="a0a37311ebf8f6637e4bc1d280a879997" args="" -->
+<div class="memitem">
+<div class="memproto">
+ <table class="memname">
+ <tr>
+ <td class="memname"><a class="el" href="structyaml__mark__s.html">yaml_mark_t</a> <a class="el" href="structyaml__document__s.html#a0a37311ebf8f6637e4bc1d280a879997">yaml_document_s::start_mark</a></td>
+ </tr>
+ </table>
+</div>
+<div class="memdoc">
+
+<p>The beginning of the document. </p>
+
+</div>
+</div>
+<a class="anchor" id="a9299efdaadf764f4d03641a3ee51e0d0"></a><!-- doxytag: member="yaml_document_s::end_mark" ref="a9299efdaadf764f4d03641a3ee51e0d0" args="" -->
+<div class="memitem">
+<div class="memproto">
+ <table class="memname">
+ <tr>
+ <td class="memname"><a class="el" href="structyaml__mark__s.html">yaml_mark_t</a> <a class="el" href="structyaml__document__s.html#a9299efdaadf764f4d03641a3ee51e0d0">yaml_document_s::end_mark</a></td>
+ </tr>
+ </table>
+</div>
+<div class="memdoc">
+
+<p>The end of the document. </p>
+
+</div>
+</div>
+<hr/>The documentation for this struct was generated from the following file:<ul>
+<li><a class="el" href="yaml_8h.html">yaml.h</a></li>
+</ul>
+</div>
+<hr class="footer"/><address class="footer"><small>Generated on Mon May 30 2011 22:00:00 for yaml by&nbsp;
+<a href="http://www.doxygen.org/index.html">
+<img class="footer" src="doxygen.png" alt="doxygen"/></a> 1.7.1 </small></address>
+</body>
+</html>
diff --git a/contrib/libyaml/doc/html/structyaml__emitter__s.html b/contrib/libyaml/doc/html/structyaml__emitter__s.html
new file mode 100644
index 0000000..2e8a084
--- /dev/null
+++ b/contrib/libyaml/doc/html/structyaml__emitter__s.html
@@ -0,0 +1,1300 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head>
+<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/>
+<title>yaml: yaml_emitter_s Struct Reference</title>
+<link href="tabs.css" rel="stylesheet" type="text/css"/>
+<link href="doxygen.css" rel="stylesheet" type="text/css"/>
+</head>
+<body>
+<!-- Generated by Doxygen 1.7.1 -->
+<div class="navigation" id="top">
+ <div class="tabs">
+ <ul class="tablist">
+ <li><a href="index.html"><span>Main&nbsp;Page</span></a></li>
+ <li><a href="modules.html"><span>Modules</span></a></li>
+ <li class="current"><a href="annotated.html"><span>Data&nbsp;Structures</span></a></li>
+ <li><a href="files.html"><span>Files</span></a></li>
+ </ul>
+ </div>
+ <div class="tabs2">
+ <ul class="tablist">
+ <li><a href="annotated.html"><span>Data&nbsp;Structures</span></a></li>
+ <li><a href="functions.html"><span>Data&nbsp;Fields</span></a></li>
+ </ul>
+ </div>
+</div>
+<div class="header">
+ <div class="headertitle">
+<h1>yaml_emitter_s Struct Reference<br/>
+<small>
+[<a class="el" href="group__emitter.html">Emitter Definitions</a>]</small>
+</h1> </div>
+</div>
+<div class="contents">
+<!-- doxytag: class="yaml_emitter_s" -->
+<p>The emitter structure.
+<a href="#_details">More...</a></p>
+
+<p><code>#include &lt;yaml.h&gt;</code></p>
+<table class="memberdecls">
+<tr><td colspan="2"><h2><a name="pub-attribs"></a>
+Data Fields</h2></td></tr>
+<tr><td class="memItemLeft" align="right" valign="top">unsigned char *&nbsp;</td><td class="memItemRight" valign="bottom"><a class="el" href="structyaml__emitter__s.html#adb154d3d10b34077792b8e4a0f0596f7">buffer</a></td></tr>
+<tr><td class="mdescLeft">&nbsp;</td><td class="mdescRight">The buffer pointer. <a href="#adb154d3d10b34077792b8e4a0f0596f7"></a><br/></td></tr>
+<tr><td class="memItemLeft" align="right" valign="top">size_t&nbsp;</td><td class="memItemRight" valign="bottom"><a class="el" href="structyaml__emitter__s.html#a53bdc6a00632b48c81098aad91a9fd8d">size</a></td></tr>
+<tr><td class="mdescLeft">&nbsp;</td><td class="mdescRight">The buffer size. <a href="#a53bdc6a00632b48c81098aad91a9fd8d"></a><br/></td></tr>
+<tr><td class="memItemLeft" align="right" valign="top">size_t *&nbsp;</td><td class="memItemRight" valign="bottom"><a class="el" href="structyaml__emitter__s.html#a1851639b8f0e53b8e272c806d9fb648b">size_written</a></td></tr>
+<tr><td class="mdescLeft">&nbsp;</td><td class="mdescRight">The number of written bytes. <a href="#a1851639b8f0e53b8e272c806d9fb648b"></a><br/></td></tr>
+<tr><td class="memItemLeft" >struct {</td></tr>
+<tr><td class="memItemLeft" >&nbsp;&nbsp;&nbsp;unsigned char *&nbsp;&nbsp;&nbsp;<a class="el" href="structyaml__emitter__s.html#adb154d3d10b34077792b8e4a0f0596f7">buffer</a></td></tr>
+<tr><td class="mdescLeft">&nbsp;</td><td class="mdescRight">The buffer pointer. <a href="#a5ce72aa2067fe7f22bd75a95eb076053"></a><br/></td></tr>
+<tr><td class="memItemLeft" >&nbsp;&nbsp;&nbsp;size_t&nbsp;&nbsp;&nbsp;<a class="el" href="structyaml__emitter__s.html#a53bdc6a00632b48c81098aad91a9fd8d">size</a></td></tr>
+<tr><td class="mdescLeft">&nbsp;</td><td class="mdescRight">The buffer size. <a href="#ad24c67d483fff16060e1134b19962d2b"></a><br/></td></tr>
+<tr><td class="memItemLeft" >&nbsp;&nbsp;&nbsp;size_t *&nbsp;&nbsp;&nbsp;<a class="el" href="structyaml__emitter__s.html#a1851639b8f0e53b8e272c806d9fb648b">size_written</a></td></tr>
+<tr><td class="mdescLeft">&nbsp;</td><td class="mdescRight">The number of written bytes. <a href="#a1d428c6dcc5082c6cbf1e2aede852c9a"></a><br/></td></tr>
+<tr><td class="memItemLeft" valign="top">}&nbsp;</td><td class="memItemRight" valign="bottom"><a class="el" href="structyaml__emitter__s.html#a8803fe1047e8bcea9bdfcad0743fa0dd">string</a></td></tr>
+<tr><td class="mdescLeft">&nbsp;</td><td class="mdescRight">String output data. <a href="#a8803fe1047e8bcea9bdfcad0743fa0dd"></a><br/></td></tr>
+<tr><td class="memItemLeft" align="right" valign="top">FILE *&nbsp;</td><td class="memItemRight" valign="bottom"><a class="el" href="structyaml__emitter__s.html#abfe1e82cd5c4a180b1468e65ccfd1c61">file</a></td></tr>
+<tr><td class="mdescLeft">&nbsp;</td><td class="mdescRight">File output data. <a href="#abfe1e82cd5c4a180b1468e65ccfd1c61"></a><br/></td></tr>
+<tr><td class="memItemLeft" align="right" valign="top"><a class="el" href="group__basic.html#gaf8657e81f0b8b05d1a081001fc6cb8bd">yaml_char_t</a> *&nbsp;</td><td class="memItemRight" valign="bottom"><a class="el" href="structyaml__emitter__s.html#a1c8f40a58f0a3061449b3fed02be145e">start</a></td></tr>
+<tr><td class="mdescLeft">&nbsp;</td><td class="mdescRight">The beginning of the buffer. <a href="#a1c8f40a58f0a3061449b3fed02be145e"></a><br/></td></tr>
+<tr><td class="memItemLeft" align="right" valign="top"><a class="el" href="group__basic.html#gaf8657e81f0b8b05d1a081001fc6cb8bd">yaml_char_t</a> *&nbsp;</td><td class="memItemRight" valign="bottom"><a class="el" href="structyaml__emitter__s.html#a42285849529f1b0eb9f4aac2eaef5204">end</a></td></tr>
+<tr><td class="mdescLeft">&nbsp;</td><td class="mdescRight">The end of the buffer. <a href="#a42285849529f1b0eb9f4aac2eaef5204"></a><br/></td></tr>
+<tr><td class="memItemLeft" align="right" valign="top"><a class="el" href="group__basic.html#gaf8657e81f0b8b05d1a081001fc6cb8bd">yaml_char_t</a> *&nbsp;</td><td class="memItemRight" valign="bottom"><a class="el" href="structyaml__emitter__s.html#a7615ab51145234f467984f3091558852">pointer</a></td></tr>
+<tr><td class="mdescLeft">&nbsp;</td><td class="mdescRight">The current position of the buffer. <a href="#a7615ab51145234f467984f3091558852"></a><br/></td></tr>
+<tr><td class="memItemLeft" align="right" valign="top"><a class="el" href="group__basic.html#gaf8657e81f0b8b05d1a081001fc6cb8bd">yaml_char_t</a> *&nbsp;</td><td class="memItemRight" valign="bottom"><a class="el" href="structyaml__emitter__s.html#adf20e81d4690b86732932aff06a6d2e6">last</a></td></tr>
+<tr><td class="mdescLeft">&nbsp;</td><td class="mdescRight">The last filled position of the buffer. <a href="#adf20e81d4690b86732932aff06a6d2e6"></a><br/></td></tr>
+<tr><td class="memItemLeft" align="right" valign="top">unsigned char *&nbsp;</td><td class="memItemRight" valign="bottom"><a class="el" href="structyaml__emitter__s.html#ae8913d3c0bf4c987dc452efee2c802e3">start</a></td></tr>
+<tr><td class="mdescLeft">&nbsp;</td><td class="mdescRight">The beginning of the buffer. <a href="#ae8913d3c0bf4c987dc452efee2c802e3"></a><br/></td></tr>
+<tr><td class="memItemLeft" align="right" valign="top">unsigned char *&nbsp;</td><td class="memItemRight" valign="bottom"><a class="el" href="structyaml__emitter__s.html#abb03bd7a5b832de48f9fbc9512ed7936">end</a></td></tr>
+<tr><td class="mdescLeft">&nbsp;</td><td class="mdescRight">The end of the buffer. <a href="#abb03bd7a5b832de48f9fbc9512ed7936"></a><br/></td></tr>
+<tr><td class="memItemLeft" align="right" valign="top">unsigned char *&nbsp;</td><td class="memItemRight" valign="bottom"><a class="el" href="structyaml__emitter__s.html#aed9370f42cea4dff82f96839ce760b5a">pointer</a></td></tr>
+<tr><td class="mdescLeft">&nbsp;</td><td class="mdescRight">The current position of the buffer. <a href="#aed9370f42cea4dff82f96839ce760b5a"></a><br/></td></tr>
+<tr><td class="memItemLeft" align="right" valign="top">unsigned char *&nbsp;</td><td class="memItemRight" valign="bottom"><a class="el" href="structyaml__emitter__s.html#ad0c5410fff4602266a0c6e0af730dd70">last</a></td></tr>
+<tr><td class="mdescLeft">&nbsp;</td><td class="mdescRight">The last filled position of the buffer. <a href="#ad0c5410fff4602266a0c6e0af730dd70"></a><br/></td></tr>
+<tr><td class="memItemLeft" align="right" valign="top"><a class="el" href="group__emitter.html#ga0889461fa3efe8eee881aef48a4ba6b2">yaml_emitter_state_t</a> *&nbsp;</td><td class="memItemRight" valign="bottom"><a class="el" href="structyaml__emitter__s.html#ad68af21e510adcfc2db43b31e791efe1">start</a></td></tr>
+<tr><td class="mdescLeft">&nbsp;</td><td class="mdescRight">The beginning of the stack. <a href="#ad68af21e510adcfc2db43b31e791efe1"></a><br/></td></tr>
+<tr><td class="memItemLeft" align="right" valign="top"><a class="el" href="group__emitter.html#ga0889461fa3efe8eee881aef48a4ba6b2">yaml_emitter_state_t</a> *&nbsp;</td><td class="memItemRight" valign="bottom"><a class="el" href="structyaml__emitter__s.html#a126a19ae360206437647892a344a30f0">end</a></td></tr>
+<tr><td class="mdescLeft">&nbsp;</td><td class="mdescRight">The end of the stack. <a href="#a126a19ae360206437647892a344a30f0"></a><br/></td></tr>
+<tr><td class="memItemLeft" align="right" valign="top"><a class="el" href="group__emitter.html#ga0889461fa3efe8eee881aef48a4ba6b2">yaml_emitter_state_t</a> *&nbsp;</td><td class="memItemRight" valign="bottom"><a class="el" href="structyaml__emitter__s.html#aafa8b6f21022ce2f4cb9b44ad15a535e">top</a></td></tr>
+<tr><td class="mdescLeft">&nbsp;</td><td class="mdescRight">The top of the stack. <a href="#aafa8b6f21022ce2f4cb9b44ad15a535e"></a><br/></td></tr>
+<tr><td class="memItemLeft" align="right" valign="top"><a class="el" href="structyaml__event__s.html">yaml_event_t</a> *&nbsp;</td><td class="memItemRight" valign="bottom"><a class="el" href="structyaml__emitter__s.html#a2c31edecd7f6dfd87fe3f8e12b705884">start</a></td></tr>
+<tr><td class="mdescLeft">&nbsp;</td><td class="mdescRight">The beginning of the event queue. <a href="#a2c31edecd7f6dfd87fe3f8e12b705884"></a><br/></td></tr>
+<tr><td class="memItemLeft" align="right" valign="top"><a class="el" href="structyaml__event__s.html">yaml_event_t</a> *&nbsp;</td><td class="memItemRight" valign="bottom"><a class="el" href="structyaml__emitter__s.html#a55703a15e71c6b9551a2f4feb888bdcb">end</a></td></tr>
+<tr><td class="mdescLeft">&nbsp;</td><td class="mdescRight">The end of the event queue. <a href="#a55703a15e71c6b9551a2f4feb888bdcb"></a><br/></td></tr>
+<tr><td class="memItemLeft" align="right" valign="top"><a class="el" href="structyaml__event__s.html">yaml_event_t</a> *&nbsp;</td><td class="memItemRight" valign="bottom"><a class="el" href="structyaml__emitter__s.html#a547dfd20576006e606ffb0d8042b4234">head</a></td></tr>
+<tr><td class="mdescLeft">&nbsp;</td><td class="mdescRight">The head of the event queue. <a href="#a547dfd20576006e606ffb0d8042b4234"></a><br/></td></tr>
+<tr><td class="memItemLeft" align="right" valign="top"><a class="el" href="structyaml__event__s.html">yaml_event_t</a> *&nbsp;</td><td class="memItemRight" valign="bottom"><a class="el" href="structyaml__emitter__s.html#acafa1e3cb872fa7917217469659fb273">tail</a></td></tr>
+<tr><td class="mdescLeft">&nbsp;</td><td class="mdescRight">The tail of the event queue. <a href="#acafa1e3cb872fa7917217469659fb273"></a><br/></td></tr>
+<tr><td class="memItemLeft" align="right" valign="top">int *&nbsp;</td><td class="memItemRight" valign="bottom"><a class="el" href="structyaml__emitter__s.html#a28ec8053132a8e7cf29df983835754b7">start</a></td></tr>
+<tr><td class="mdescLeft">&nbsp;</td><td class="mdescRight">The beginning of the stack. <a href="#a28ec8053132a8e7cf29df983835754b7"></a><br/></td></tr>
+<tr><td class="memItemLeft" align="right" valign="top">int *&nbsp;</td><td class="memItemRight" valign="bottom"><a class="el" href="structyaml__emitter__s.html#a6669a94bc18247491e59c709852be0d1">end</a></td></tr>
+<tr><td class="mdescLeft">&nbsp;</td><td class="mdescRight">The end of the stack. <a href="#a6669a94bc18247491e59c709852be0d1"></a><br/></td></tr>
+<tr><td class="memItemLeft" align="right" valign="top">int *&nbsp;</td><td class="memItemRight" valign="bottom"><a class="el" href="structyaml__emitter__s.html#a5779bcbfd04df64e42434b7599332d11">top</a></td></tr>
+<tr><td class="mdescLeft">&nbsp;</td><td class="mdescRight">The top of the stack. <a href="#a5779bcbfd04df64e42434b7599332d11"></a><br/></td></tr>
+<tr><td class="memItemLeft" align="right" valign="top"><a class="el" href="structyaml__tag__directive__s.html">yaml_tag_directive_t</a> *&nbsp;</td><td class="memItemRight" valign="bottom"><a class="el" href="structyaml__emitter__s.html#a94afdd9750b95529bbbbd09456a4391d">start</a></td></tr>
+<tr><td class="mdescLeft">&nbsp;</td><td class="mdescRight">The beginning of the list. <a href="#a94afdd9750b95529bbbbd09456a4391d"></a><br/></td></tr>
+<tr><td class="memItemLeft" align="right" valign="top"><a class="el" href="structyaml__tag__directive__s.html">yaml_tag_directive_t</a> *&nbsp;</td><td class="memItemRight" valign="bottom"><a class="el" href="structyaml__emitter__s.html#a3b28127063323de1d88fc18cdb6adf8a">end</a></td></tr>
+<tr><td class="mdescLeft">&nbsp;</td><td class="mdescRight">The end of the list. <a href="#a3b28127063323de1d88fc18cdb6adf8a"></a><br/></td></tr>
+<tr><td class="memItemLeft" align="right" valign="top"><a class="el" href="structyaml__tag__directive__s.html">yaml_tag_directive_t</a> *&nbsp;</td><td class="memItemRight" valign="bottom"><a class="el" href="structyaml__emitter__s.html#a8e3f468d814d2aa5e074f7da1648d34a">top</a></td></tr>
+<tr><td class="mdescLeft">&nbsp;</td><td class="mdescRight">The top of the list. <a href="#a8e3f468d814d2aa5e074f7da1648d34a"></a><br/></td></tr>
+<tr><td class="memItemLeft" align="right" valign="top"><a class="el" href="group__basic.html#gaf8657e81f0b8b05d1a081001fc6cb8bd">yaml_char_t</a> *&nbsp;</td><td class="memItemRight" valign="bottom"><a class="el" href="structyaml__emitter__s.html#a6f2882bde71e478e29dc5b293def8739">anchor</a></td></tr>
+<tr><td class="mdescLeft">&nbsp;</td><td class="mdescRight">The anchor value. <a href="#a6f2882bde71e478e29dc5b293def8739"></a><br/></td></tr>
+<tr><td class="memItemLeft" align="right" valign="top">size_t&nbsp;</td><td class="memItemRight" valign="bottom"><a class="el" href="structyaml__emitter__s.html#aece73cc234475630032b1c75a735eeb5">anchor_length</a></td></tr>
+<tr><td class="mdescLeft">&nbsp;</td><td class="mdescRight">The anchor length. <a href="#aece73cc234475630032b1c75a735eeb5"></a><br/></td></tr>
+<tr><td class="memItemLeft" align="right" valign="top"><a class="anchor" id="a1129c6f9ae5cd3b437b8ab8767324f03"></a><!-- doxytag: member="yaml_emitter_s::alias" ref="a1129c6f9ae5cd3b437b8ab8767324f03" args="" -->
+int&nbsp;</td><td class="memItemRight" valign="bottom"><a class="el" href="structyaml__emitter__s.html#a1129c6f9ae5cd3b437b8ab8767324f03">alias</a></td></tr>
+<tr><td class="mdescLeft">&nbsp;</td><td class="mdescRight">Is it an alias? <br/></td></tr>
+<tr><td class="memItemLeft" align="right" valign="top"><a class="el" href="group__basic.html#gaf8657e81f0b8b05d1a081001fc6cb8bd">yaml_char_t</a> *&nbsp;</td><td class="memItemRight" valign="bottom"><a class="el" href="structyaml__emitter__s.html#a7f043a9092eef2d644cc8f1180386239">handle</a></td></tr>
+<tr><td class="mdescLeft">&nbsp;</td><td class="mdescRight">The tag handle. <a href="#a7f043a9092eef2d644cc8f1180386239"></a><br/></td></tr>
+<tr><td class="memItemLeft" align="right" valign="top">size_t&nbsp;</td><td class="memItemRight" valign="bottom"><a class="el" href="structyaml__emitter__s.html#a3552cece6908f99518205e8cbe2c793a">handle_length</a></td></tr>
+<tr><td class="mdescLeft">&nbsp;</td><td class="mdescRight">The tag handle length. <a href="#a3552cece6908f99518205e8cbe2c793a"></a><br/></td></tr>
+<tr><td class="memItemLeft" align="right" valign="top"><a class="el" href="group__basic.html#gaf8657e81f0b8b05d1a081001fc6cb8bd">yaml_char_t</a> *&nbsp;</td><td class="memItemRight" valign="bottom"><a class="el" href="structyaml__emitter__s.html#ad9b61d5e9e05a47b2f873342ab226188">suffix</a></td></tr>
+<tr><td class="mdescLeft">&nbsp;</td><td class="mdescRight">The tag suffix. <a href="#ad9b61d5e9e05a47b2f873342ab226188"></a><br/></td></tr>
+<tr><td class="memItemLeft" align="right" valign="top">size_t&nbsp;</td><td class="memItemRight" valign="bottom"><a class="el" href="structyaml__emitter__s.html#ad83936bbd4b6b77c79555c71cccc8fb5">suffix_length</a></td></tr>
+<tr><td class="mdescLeft">&nbsp;</td><td class="mdescRight">The tag suffix length. <a href="#ad83936bbd4b6b77c79555c71cccc8fb5"></a><br/></td></tr>
+<tr><td class="memItemLeft" align="right" valign="top"><a class="el" href="group__basic.html#gaf8657e81f0b8b05d1a081001fc6cb8bd">yaml_char_t</a> *&nbsp;</td><td class="memItemRight" valign="bottom"><a class="el" href="structyaml__emitter__s.html#a20246ec76d64854ff93629cf1b424d86">value</a></td></tr>
+<tr><td class="mdescLeft">&nbsp;</td><td class="mdescRight">The scalar value. <a href="#a20246ec76d64854ff93629cf1b424d86"></a><br/></td></tr>
+<tr><td class="memItemLeft" align="right" valign="top">size_t&nbsp;</td><td class="memItemRight" valign="bottom"><a class="el" href="structyaml__emitter__s.html#a4f72d57ad020803803e78922ecdec580">length</a></td></tr>
+<tr><td class="mdescLeft">&nbsp;</td><td class="mdescRight">The scalar length. <a href="#a4f72d57ad020803803e78922ecdec580"></a><br/></td></tr>
+<tr><td class="memItemLeft" align="right" valign="top"><a class="anchor" id="a363a1aaaf512433ee7eab3083428cc70"></a><!-- doxytag: member="yaml_emitter_s::multiline" ref="a363a1aaaf512433ee7eab3083428cc70" args="" -->
+int&nbsp;</td><td class="memItemRight" valign="bottom"><a class="el" href="structyaml__emitter__s.html#a363a1aaaf512433ee7eab3083428cc70">multiline</a></td></tr>
+<tr><td class="mdescLeft">&nbsp;</td><td class="mdescRight">Does the scalar contain line breaks? <br/></td></tr>
+<tr><td class="memItemLeft" align="right" valign="top"><a class="anchor" id="afd8496f5bb995bb5aacc349fd6b45bf5"></a><!-- doxytag: member="yaml_emitter_s::flow_plain_allowed" ref="afd8496f5bb995bb5aacc349fd6b45bf5" args="" -->
+int&nbsp;</td><td class="memItemRight" valign="bottom"><a class="el" href="structyaml__emitter__s.html#afd8496f5bb995bb5aacc349fd6b45bf5">flow_plain_allowed</a></td></tr>
+<tr><td class="mdescLeft">&nbsp;</td><td class="mdescRight">Can the scalar be expessed in the flow plain style? <br/></td></tr>
+<tr><td class="memItemLeft" align="right" valign="top"><a class="anchor" id="a5b5f6c9d687d788c8dac86d213ef4c16"></a><!-- doxytag: member="yaml_emitter_s::block_plain_allowed" ref="a5b5f6c9d687d788c8dac86d213ef4c16" args="" -->
+int&nbsp;</td><td class="memItemRight" valign="bottom"><a class="el" href="structyaml__emitter__s.html#a5b5f6c9d687d788c8dac86d213ef4c16">block_plain_allowed</a></td></tr>
+<tr><td class="mdescLeft">&nbsp;</td><td class="mdescRight">Can the scalar be expressed in the block plain style? <br/></td></tr>
+<tr><td class="memItemLeft" align="right" valign="top"><a class="anchor" id="a3729ff7e7add06a1a1d9067a557a59fc"></a><!-- doxytag: member="yaml_emitter_s::single_quoted_allowed" ref="a3729ff7e7add06a1a1d9067a557a59fc" args="" -->
+int&nbsp;</td><td class="memItemRight" valign="bottom"><a class="el" href="structyaml__emitter__s.html#a3729ff7e7add06a1a1d9067a557a59fc">single_quoted_allowed</a></td></tr>
+<tr><td class="mdescLeft">&nbsp;</td><td class="mdescRight">Can the scalar be expressed in the single quoted style? <br/></td></tr>
+<tr><td class="memItemLeft" align="right" valign="top"><a class="anchor" id="a64e05972897d02f606627ef0cf3c7420"></a><!-- doxytag: member="yaml_emitter_s::block_allowed" ref="a64e05972897d02f606627ef0cf3c7420" args="" -->
+int&nbsp;</td><td class="memItemRight" valign="bottom"><a class="el" href="structyaml__emitter__s.html#a64e05972897d02f606627ef0cf3c7420">block_allowed</a></td></tr>
+<tr><td class="mdescLeft">&nbsp;</td><td class="mdescRight">Can the scalar be expressed in the literal or folded styles? <br/></td></tr>
+<tr><td class="memItemLeft" align="right" valign="top"><a class="el" href="group__styles.html#ga3fa6405631e1afe5bd5c488a6c5e8065">yaml_scalar_style_t</a>&nbsp;</td><td class="memItemRight" valign="bottom"><a class="el" href="structyaml__emitter__s.html#acd1e83d220103aa24577038cfb1c2d21">style</a></td></tr>
+<tr><td class="mdescLeft">&nbsp;</td><td class="mdescRight">The output style. <a href="#acd1e83d220103aa24577038cfb1c2d21"></a><br/></td></tr>
+<tr><td class="memItemLeft" align="right" valign="top">int&nbsp;</td><td class="memItemRight" valign="bottom"><a class="el" href="structyaml__emitter__s.html#a8f00c3c08e0d87bab11e91a4464a50bc">references</a></td></tr>
+<tr><td class="mdescLeft">&nbsp;</td><td class="mdescRight">The number of references. <a href="#a8f00c3c08e0d87bab11e91a4464a50bc"></a><br/></td></tr>
+<tr><td class="memItemLeft" align="right" valign="top">int&nbsp;</td><td class="memItemRight" valign="bottom"><a class="el" href="structyaml__emitter__s.html#a88154c89db7ec99fb322b1970371c350">anchor</a></td></tr>
+<tr><td class="mdescLeft">&nbsp;</td><td class="mdescRight">The anchor id. <a href="#a88154c89db7ec99fb322b1970371c350"></a><br/></td></tr>
+<tr><td class="memItemLeft" align="right" valign="top"><a class="anchor" id="a6c3e98c02ffae879717b3d09f9458936"></a><!-- doxytag: member="yaml_emitter_s::serialized" ref="a6c3e98c02ffae879717b3d09f9458936" args="" -->
+int&nbsp;</td><td class="memItemRight" valign="bottom"><a class="el" href="structyaml__emitter__s.html#a6c3e98c02ffae879717b3d09f9458936">serialized</a></td></tr>
+<tr><td class="mdescLeft">&nbsp;</td><td class="mdescRight">If the node has been emitted? <br/></td></tr>
+<tr><td colspan="2"><div class="groupHeader">Error handling</div></td></tr>
+<tr><td colspan="2"><div class="groupText"><p><a class="anchor" id="amgrpaf042bafd560f7bd09b37efa40772311"></a> </p>
+</div></td></tr>
+<tr><td class="memItemLeft" align="right" valign="top"><a class="el" href="group__basic.html#ga1a449f0c1b023e2ef1a596093c018e73">yaml_error_type_t</a>&nbsp;</td><td class="memItemRight" valign="bottom"><a class="el" href="structyaml__emitter__s.html#afa2d6367a86ae6d43df14e24479bb0a7">error</a></td></tr>
+<tr><td class="mdescLeft">&nbsp;</td><td class="mdescRight">Error type. <a href="#afa2d6367a86ae6d43df14e24479bb0a7"></a><br/></td></tr>
+<tr><td class="memItemLeft" align="right" valign="top">const char *&nbsp;</td><td class="memItemRight" valign="bottom"><a class="el" href="structyaml__emitter__s.html#ae076ef7c85ae107a2233dd4206577800">problem</a></td></tr>
+<tr><td class="mdescLeft">&nbsp;</td><td class="mdescRight">Error description. <a href="#ae076ef7c85ae107a2233dd4206577800"></a><br/></td></tr>
+<tr><td colspan="2"><div class="groupHeader">Writer stuff</div></td></tr>
+<tr><td colspan="2"><div class="groupText"><p><a class="anchor" id="amgrpee82c26a762d9eda665a45fdcdae7f67"></a> </p>
+</div></td></tr>
+<tr><td class="memItemLeft" align="right" valign="top"><a class="el" href="group__emitter.html#ga1669659aacbe631ad406c78fce1f5379">yaml_write_handler_t</a> *&nbsp;</td><td class="memItemRight" valign="bottom"><a class="el" href="structyaml__emitter__s.html#aefa7e29ba8042ed1d133a02bb368ea3e">write_handler</a></td></tr>
+<tr><td class="mdescLeft">&nbsp;</td><td class="mdescRight">Write handler. <a href="#aefa7e29ba8042ed1d133a02bb368ea3e"></a><br/></td></tr>
+<tr><td class="memItemLeft" align="right" valign="top">void *&nbsp;</td><td class="memItemRight" valign="bottom"><a class="el" href="structyaml__emitter__s.html#a6c4fe0176b69da64ac1ddc7e091967e5">write_handler_data</a></td></tr>
+<tr><td class="mdescLeft">&nbsp;</td><td class="mdescRight">A pointer for passing to the white handler. <a href="#a6c4fe0176b69da64ac1ddc7e091967e5"></a><br/></td></tr>
+<tr><td class="memItemLeft" >union {</td></tr>
+<tr><td class="memItemLeft" >&nbsp;&nbsp;&nbsp;struct {</td></tr>
+<tr><td class="memItemLeft" >&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;unsigned char *&nbsp;&nbsp;&nbsp;<a class="el" href="structyaml__emitter__s.html#adb154d3d10b34077792b8e4a0f0596f7">buffer</a></td></tr>
+<tr><td class="mdescLeft">&nbsp;</td><td class="mdescRight">The buffer pointer. <a href="#a5ce72aa2067fe7f22bd75a95eb076053"></a><br/></td></tr>
+<tr><td class="memItemLeft" >&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;size_t&nbsp;&nbsp;&nbsp;<a class="el" href="structyaml__emitter__s.html#a53bdc6a00632b48c81098aad91a9fd8d">size</a></td></tr>
+<tr><td class="mdescLeft">&nbsp;</td><td class="mdescRight">The buffer size. <a href="#ad24c67d483fff16060e1134b19962d2b"></a><br/></td></tr>
+<tr><td class="memItemLeft" >&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;size_t *&nbsp;&nbsp;&nbsp;<a class="el" href="structyaml__emitter__s.html#a1851639b8f0e53b8e272c806d9fb648b">size_written</a></td></tr>
+<tr><td class="mdescLeft">&nbsp;</td><td class="mdescRight">The number of written bytes. <a href="#a1d428c6dcc5082c6cbf1e2aede852c9a"></a><br/></td></tr>
+<tr><td class="memItemLeft" valign="top">&nbsp;&nbsp;&nbsp;}&nbsp;&nbsp;&nbsp;<a class="el" href="structyaml__emitter__s.html#a8803fe1047e8bcea9bdfcad0743fa0dd">string</a></td></tr>
+<tr><td class="mdescLeft">&nbsp;</td><td class="mdescRight">String output data. <a href="#a43d34f4667ee7c0da8d6b9406a1dce96"></a><br/></td></tr>
+<tr><td class="memItemLeft" >&nbsp;&nbsp;&nbsp;FILE *&nbsp;&nbsp;&nbsp;<a class="el" href="structyaml__emitter__s.html#abfe1e82cd5c4a180b1468e65ccfd1c61">file</a></td></tr>
+<tr><td class="mdescLeft">&nbsp;</td><td class="mdescRight">File output data. <a href="#afb86cb14f60416cc07eedb20585f3764"></a><br/></td></tr>
+<tr><td class="memItemLeft" valign="top">}&nbsp;</td><td class="memItemRight" valign="bottom"><a class="el" href="structyaml__emitter__s.html#aa975acf559cc87d79abdb732c994f56f">output</a></td></tr>
+<tr><td class="mdescLeft">&nbsp;</td><td class="mdescRight">Standard (string or file) output data. <a href="#aa975acf559cc87d79abdb732c994f56f"></a><br/></td></tr>
+<tr><td class="memItemLeft" >struct {</td></tr>
+<tr><td class="memItemLeft" >&nbsp;&nbsp;&nbsp;<a class="el" href="group__basic.html#gaf8657e81f0b8b05d1a081001fc6cb8bd">yaml_char_t</a> *&nbsp;&nbsp;&nbsp;<a class="el" href="structyaml__emitter__s.html#a1c8f40a58f0a3061449b3fed02be145e">start</a></td></tr>
+<tr><td class="mdescLeft">&nbsp;</td><td class="mdescRight">The beginning of the buffer. <a href="#adbc4316b40afdcc9ef49d3929d97eb1c"></a><br/></td></tr>
+<tr><td class="memItemLeft" >&nbsp;&nbsp;&nbsp;<a class="el" href="group__basic.html#gaf8657e81f0b8b05d1a081001fc6cb8bd">yaml_char_t</a> *&nbsp;&nbsp;&nbsp;<a class="el" href="structyaml__emitter__s.html#a42285849529f1b0eb9f4aac2eaef5204">end</a></td></tr>
+<tr><td class="mdescLeft">&nbsp;</td><td class="mdescRight">The end of the buffer. <a href="#ab1a7ec35fcc61cc3affe62bc5ee9e0b2"></a><br/></td></tr>
+<tr><td class="memItemLeft" >&nbsp;&nbsp;&nbsp;<a class="el" href="group__basic.html#gaf8657e81f0b8b05d1a081001fc6cb8bd">yaml_char_t</a> *&nbsp;&nbsp;&nbsp;<a class="el" href="structyaml__emitter__s.html#a7615ab51145234f467984f3091558852">pointer</a></td></tr>
+<tr><td class="mdescLeft">&nbsp;</td><td class="mdescRight">The current position of the buffer. <a href="#a84fcdc6e2cd91ff2e38594a1d8f435a6"></a><br/></td></tr>
+<tr><td class="memItemLeft" >&nbsp;&nbsp;&nbsp;<a class="el" href="group__basic.html#gaf8657e81f0b8b05d1a081001fc6cb8bd">yaml_char_t</a> *&nbsp;&nbsp;&nbsp;<a class="el" href="structyaml__emitter__s.html#adf20e81d4690b86732932aff06a6d2e6">last</a></td></tr>
+<tr><td class="mdescLeft">&nbsp;</td><td class="mdescRight">The last filled position of the buffer. <a href="#ab86889ad01535a8c288408df3f7455c2"></a><br/></td></tr>
+<tr><td class="memItemLeft" valign="top">}&nbsp;</td><td class="memItemRight" valign="bottom"><a class="el" href="structyaml__emitter__s.html#afb2700e9b866b5be0ff6c7549c719f81">buffer</a></td></tr>
+<tr><td class="mdescLeft">&nbsp;</td><td class="mdescRight">The working buffer. <a href="#afb2700e9b866b5be0ff6c7549c719f81"></a><br/></td></tr>
+<tr><td class="memItemLeft" >struct {</td></tr>
+<tr><td class="memItemLeft" >&nbsp;&nbsp;&nbsp;unsigned char *&nbsp;&nbsp;&nbsp;<a class="el" href="structyaml__emitter__s.html#ae8913d3c0bf4c987dc452efee2c802e3">start</a></td></tr>
+<tr><td class="mdescLeft">&nbsp;</td><td class="mdescRight">The beginning of the buffer. <a href="#a9096d152a3292fca324044907326804a"></a><br/></td></tr>
+<tr><td class="memItemLeft" >&nbsp;&nbsp;&nbsp;unsigned char *&nbsp;&nbsp;&nbsp;<a class="el" href="structyaml__emitter__s.html#abb03bd7a5b832de48f9fbc9512ed7936">end</a></td></tr>
+<tr><td class="mdescLeft">&nbsp;</td><td class="mdescRight">The end of the buffer. <a href="#a64a25c335013ec4497a5f14796111828"></a><br/></td></tr>
+<tr><td class="memItemLeft" >&nbsp;&nbsp;&nbsp;unsigned char *&nbsp;&nbsp;&nbsp;<a class="el" href="structyaml__emitter__s.html#aed9370f42cea4dff82f96839ce760b5a">pointer</a></td></tr>
+<tr><td class="mdescLeft">&nbsp;</td><td class="mdescRight">The current position of the buffer. <a href="#a523f757260794400ffdae6d051090710"></a><br/></td></tr>
+<tr><td class="memItemLeft" >&nbsp;&nbsp;&nbsp;unsigned char *&nbsp;&nbsp;&nbsp;<a class="el" href="structyaml__emitter__s.html#ad0c5410fff4602266a0c6e0af730dd70">last</a></td></tr>
+<tr><td class="mdescLeft">&nbsp;</td><td class="mdescRight">The last filled position of the buffer. <a href="#aaff93992cd5c0be1386b3f8090207ea6"></a><br/></td></tr>
+<tr><td class="memItemLeft" valign="top">}&nbsp;</td><td class="memItemRight" valign="bottom"><a class="el" href="structyaml__emitter__s.html#a6eeffbc9cd5beb89b679740b7f1d6d09">raw_buffer</a></td></tr>
+<tr><td class="mdescLeft">&nbsp;</td><td class="mdescRight">The raw buffer. <a href="#a6eeffbc9cd5beb89b679740b7f1d6d09"></a><br/></td></tr>
+<tr><td class="memItemLeft" align="right" valign="top"><a class="el" href="group__basic.html#ga2170996d7e636397b5e6bc0c1b7df7c6">yaml_encoding_t</a>&nbsp;</td><td class="memItemRight" valign="bottom"><a class="el" href="structyaml__emitter__s.html#ada17f19fa6248d6ee493684b03700857">encoding</a></td></tr>
+<tr><td class="mdescLeft">&nbsp;</td><td class="mdescRight">The stream encoding. <a href="#ada17f19fa6248d6ee493684b03700857"></a><br/></td></tr>
+<tr><td colspan="2"><div class="groupHeader">Emitter stuff</div></td></tr>
+<tr><td colspan="2"><div class="groupText"><p><a class="anchor" id="amgrp57228565532f46f6090d0fe7426f7ac0"></a> </p>
+</div></td></tr>
+<tr><td class="memItemLeft" align="right" valign="top"><a class="anchor" id="acb0259cdc5e2bb23faaf7266496df827"></a><!-- doxytag: member="yaml_emitter_s::canonical" ref="acb0259cdc5e2bb23faaf7266496df827" args="" -->
+int&nbsp;</td><td class="memItemRight" valign="bottom"><a class="el" href="structyaml__emitter__s.html#acb0259cdc5e2bb23faaf7266496df827">canonical</a></td></tr>
+<tr><td class="mdescLeft">&nbsp;</td><td class="mdescRight">If the output is in the canonical style? <br/></td></tr>
+<tr><td class="memItemLeft" align="right" valign="top">int&nbsp;</td><td class="memItemRight" valign="bottom"><a class="el" href="structyaml__emitter__s.html#a33545f8924be89daf8b81dc905d558c0">best_indent</a></td></tr>
+<tr><td class="mdescLeft">&nbsp;</td><td class="mdescRight">The number of indentation spaces. <a href="#a33545f8924be89daf8b81dc905d558c0"></a><br/></td></tr>
+<tr><td class="memItemLeft" align="right" valign="top">int&nbsp;</td><td class="memItemRight" valign="bottom"><a class="el" href="structyaml__emitter__s.html#a56dde6b352bdf7d4031f89d2b5d704f6">best_width</a></td></tr>
+<tr><td class="mdescLeft">&nbsp;</td><td class="mdescRight">The preferred width of the output lines. <a href="#a56dde6b352bdf7d4031f89d2b5d704f6"></a><br/></td></tr>
+<tr><td class="memItemLeft" align="right" valign="top"><a class="anchor" id="a76372a2413f71a5b36bf77a58d8f5d40"></a><!-- doxytag: member="yaml_emitter_s::unicode" ref="a76372a2413f71a5b36bf77a58d8f5d40" args="" -->
+int&nbsp;</td><td class="memItemRight" valign="bottom"><a class="el" href="structyaml__emitter__s.html#a76372a2413f71a5b36bf77a58d8f5d40">unicode</a></td></tr>
+<tr><td class="mdescLeft">&nbsp;</td><td class="mdescRight">Allow unescaped non-ASCII characters? <br/></td></tr>
+<tr><td class="memItemLeft" align="right" valign="top"><a class="el" href="group__basic.html#ga64d1365e1acd4deeab50d6b48e39cb6d">yaml_break_t</a>&nbsp;</td><td class="memItemRight" valign="bottom"><a class="el" href="structyaml__emitter__s.html#a84c1b884d805588495067ee98a8e7c50">line_break</a></td></tr>
+<tr><td class="mdescLeft">&nbsp;</td><td class="mdescRight">The preferred line break. <a href="#a84c1b884d805588495067ee98a8e7c50"></a><br/></td></tr>
+<tr><td class="memItemLeft" >struct {</td></tr>
+<tr><td class="memItemLeft" >&nbsp;&nbsp;&nbsp;<a class="el" href="group__emitter.html#ga0889461fa3efe8eee881aef48a4ba6b2">yaml_emitter_state_t</a> *&nbsp;&nbsp;&nbsp;<a class="el" href="structyaml__emitter__s.html#ad68af21e510adcfc2db43b31e791efe1">start</a></td></tr>
+<tr><td class="mdescLeft">&nbsp;</td><td class="mdescRight">The beginning of the stack. <a href="#a4f917a8c795813420ecfc1f30bcb5ea9"></a><br/></td></tr>
+<tr><td class="memItemLeft" >&nbsp;&nbsp;&nbsp;<a class="el" href="group__emitter.html#ga0889461fa3efe8eee881aef48a4ba6b2">yaml_emitter_state_t</a> *&nbsp;&nbsp;&nbsp;<a class="el" href="structyaml__emitter__s.html#a126a19ae360206437647892a344a30f0">end</a></td></tr>
+<tr><td class="mdescLeft">&nbsp;</td><td class="mdescRight">The end of the stack. <a href="#a4a5f2a6fc80a080b58a80d6f29f374b6"></a><br/></td></tr>
+<tr><td class="memItemLeft" >&nbsp;&nbsp;&nbsp;<a class="el" href="group__emitter.html#ga0889461fa3efe8eee881aef48a4ba6b2">yaml_emitter_state_t</a> *&nbsp;&nbsp;&nbsp;<a class="el" href="structyaml__emitter__s.html#aafa8b6f21022ce2f4cb9b44ad15a535e">top</a></td></tr>
+<tr><td class="mdescLeft">&nbsp;</td><td class="mdescRight">The top of the stack. <a href="#ada10f335135a1ce5d90bbff5542dfe68"></a><br/></td></tr>
+<tr><td class="memItemLeft" valign="top">}&nbsp;</td><td class="memItemRight" valign="bottom"><a class="el" href="structyaml__emitter__s.html#a6dc87fbd5b074507e102b967492b135d">states</a></td></tr>
+<tr><td class="mdescLeft">&nbsp;</td><td class="mdescRight">The stack of states. <a href="#a6dc87fbd5b074507e102b967492b135d"></a><br/></td></tr>
+<tr><td class="memItemLeft" align="right" valign="top"><a class="el" href="group__emitter.html#ga0889461fa3efe8eee881aef48a4ba6b2">yaml_emitter_state_t</a>&nbsp;</td><td class="memItemRight" valign="bottom"><a class="el" href="structyaml__emitter__s.html#a29f1d4f27ff9b9616c154f0730dd24ee">state</a></td></tr>
+<tr><td class="mdescLeft">&nbsp;</td><td class="mdescRight">The current emitter state. <a href="#a29f1d4f27ff9b9616c154f0730dd24ee"></a><br/></td></tr>
+<tr><td class="memItemLeft" >struct {</td></tr>
+<tr><td class="memItemLeft" >&nbsp;&nbsp;&nbsp;<a class="el" href="structyaml__event__s.html">yaml_event_t</a> *&nbsp;&nbsp;&nbsp;<a class="el" href="structyaml__emitter__s.html#a2c31edecd7f6dfd87fe3f8e12b705884">start</a></td></tr>
+<tr><td class="mdescLeft">&nbsp;</td><td class="mdescRight">The beginning of the event queue. <a href="#a7ba41d2e39753745641acfa882814b0f"></a><br/></td></tr>
+<tr><td class="memItemLeft" >&nbsp;&nbsp;&nbsp;<a class="el" href="structyaml__event__s.html">yaml_event_t</a> *&nbsp;&nbsp;&nbsp;<a class="el" href="structyaml__emitter__s.html#a55703a15e71c6b9551a2f4feb888bdcb">end</a></td></tr>
+<tr><td class="mdescLeft">&nbsp;</td><td class="mdescRight">The end of the event queue. <a href="#ac6a1a353e78f8e8c1fd161e9b43b74bd"></a><br/></td></tr>
+<tr><td class="memItemLeft" >&nbsp;&nbsp;&nbsp;<a class="el" href="structyaml__event__s.html">yaml_event_t</a> *&nbsp;&nbsp;&nbsp;<a class="el" href="structyaml__emitter__s.html#a547dfd20576006e606ffb0d8042b4234">head</a></td></tr>
+<tr><td class="mdescLeft">&nbsp;</td><td class="mdescRight">The head of the event queue. <a href="#aa7be3f3ad25c98710ab3a922b939da18"></a><br/></td></tr>
+<tr><td class="memItemLeft" >&nbsp;&nbsp;&nbsp;<a class="el" href="structyaml__event__s.html">yaml_event_t</a> *&nbsp;&nbsp;&nbsp;<a class="el" href="structyaml__emitter__s.html#acafa1e3cb872fa7917217469659fb273">tail</a></td></tr>
+<tr><td class="mdescLeft">&nbsp;</td><td class="mdescRight">The tail of the event queue. <a href="#a338d5b9b3263b2f96b051007fbb30a84"></a><br/></td></tr>
+<tr><td class="memItemLeft" valign="top">}&nbsp;</td><td class="memItemRight" valign="bottom"><a class="el" href="structyaml__emitter__s.html#a3516b49eb7579e422750a94a9d7c1700">events</a></td></tr>
+<tr><td class="mdescLeft">&nbsp;</td><td class="mdescRight">The event queue. <a href="#a3516b49eb7579e422750a94a9d7c1700"></a><br/></td></tr>
+<tr><td class="memItemLeft" >struct {</td></tr>
+<tr><td class="memItemLeft" >&nbsp;&nbsp;&nbsp;int *&nbsp;&nbsp;&nbsp;<a class="el" href="structyaml__emitter__s.html#a28ec8053132a8e7cf29df983835754b7">start</a></td></tr>
+<tr><td class="mdescLeft">&nbsp;</td><td class="mdescRight">The beginning of the stack. <a href="#af9833ef02c6e7a58b7f0bbce9d547f22"></a><br/></td></tr>
+<tr><td class="memItemLeft" >&nbsp;&nbsp;&nbsp;int *&nbsp;&nbsp;&nbsp;<a class="el" href="structyaml__emitter__s.html#a6669a94bc18247491e59c709852be0d1">end</a></td></tr>
+<tr><td class="mdescLeft">&nbsp;</td><td class="mdescRight">The end of the stack. <a href="#a105801b34622359a06dfa1650c74556b"></a><br/></td></tr>
+<tr><td class="memItemLeft" >&nbsp;&nbsp;&nbsp;int *&nbsp;&nbsp;&nbsp;<a class="el" href="structyaml__emitter__s.html#a5779bcbfd04df64e42434b7599332d11">top</a></td></tr>
+<tr><td class="mdescLeft">&nbsp;</td><td class="mdescRight">The top of the stack. <a href="#a684090c9803fd7423539179e6016e742"></a><br/></td></tr>
+<tr><td class="memItemLeft" valign="top">}&nbsp;</td><td class="memItemRight" valign="bottom"><a class="el" href="structyaml__emitter__s.html#ad31c591593ccb78e6b04887bf4f162c8">indents</a></td></tr>
+<tr><td class="mdescLeft">&nbsp;</td><td class="mdescRight">The stack of indentation levels. <a href="#ad31c591593ccb78e6b04887bf4f162c8"></a><br/></td></tr>
+<tr><td class="memItemLeft" >struct {</td></tr>
+<tr><td class="memItemLeft" >&nbsp;&nbsp;&nbsp;<a class="el" href="structyaml__tag__directive__s.html">yaml_tag_directive_t</a> *&nbsp;&nbsp;&nbsp;<a class="el" href="structyaml__emitter__s.html#a94afdd9750b95529bbbbd09456a4391d">start</a></td></tr>
+<tr><td class="mdescLeft">&nbsp;</td><td class="mdescRight">The beginning of the list. <a href="#af1647603f56c5038dd239947f4268a71"></a><br/></td></tr>
+<tr><td class="memItemLeft" >&nbsp;&nbsp;&nbsp;<a class="el" href="structyaml__tag__directive__s.html">yaml_tag_directive_t</a> *&nbsp;&nbsp;&nbsp;<a class="el" href="structyaml__emitter__s.html#a3b28127063323de1d88fc18cdb6adf8a">end</a></td></tr>
+<tr><td class="mdescLeft">&nbsp;</td><td class="mdescRight">The end of the list. <a href="#a4597d8531037b8b6f15487929e4a671b"></a><br/></td></tr>
+<tr><td class="memItemLeft" >&nbsp;&nbsp;&nbsp;<a class="el" href="structyaml__tag__directive__s.html">yaml_tag_directive_t</a> *&nbsp;&nbsp;&nbsp;<a class="el" href="structyaml__emitter__s.html#a8e3f468d814d2aa5e074f7da1648d34a">top</a></td></tr>
+<tr><td class="mdescLeft">&nbsp;</td><td class="mdescRight">The top of the list. <a href="#a2a5da3f15fc79f62dd14a7187b48471d"></a><br/></td></tr>
+<tr><td class="memItemLeft" valign="top">}&nbsp;</td><td class="memItemRight" valign="bottom"><a class="el" href="structyaml__emitter__s.html#a9dc51f2ccb8a517e2dc029e1af960258">tag_directives</a></td></tr>
+<tr><td class="mdescLeft">&nbsp;</td><td class="mdescRight">The list of tag directives. <a href="#a9dc51f2ccb8a517e2dc029e1af960258"></a><br/></td></tr>
+<tr><td class="memItemLeft" align="right" valign="top">int&nbsp;</td><td class="memItemRight" valign="bottom"><a class="el" href="structyaml__emitter__s.html#a93a73494a5d62464a67cc71f86ad9728">indent</a></td></tr>
+<tr><td class="mdescLeft">&nbsp;</td><td class="mdescRight">The current indentation level. <a href="#a93a73494a5d62464a67cc71f86ad9728"></a><br/></td></tr>
+<tr><td class="memItemLeft" align="right" valign="top">int&nbsp;</td><td class="memItemRight" valign="bottom"><a class="el" href="structyaml__emitter__s.html#a50f8e97c4290b83ebd646b4c4f5c5de9">flow_level</a></td></tr>
+<tr><td class="mdescLeft">&nbsp;</td><td class="mdescRight">The current flow level. <a href="#a50f8e97c4290b83ebd646b4c4f5c5de9"></a><br/></td></tr>
+<tr><td class="memItemLeft" align="right" valign="top"><a class="anchor" id="a70fb5f09cc60de989fbec2868f4db19e"></a><!-- doxytag: member="yaml_emitter_s::root_context" ref="a70fb5f09cc60de989fbec2868f4db19e" args="" -->
+int&nbsp;</td><td class="memItemRight" valign="bottom"><a class="el" href="structyaml__emitter__s.html#a70fb5f09cc60de989fbec2868f4db19e">root_context</a></td></tr>
+<tr><td class="mdescLeft">&nbsp;</td><td class="mdescRight">Is it the document root context? <br/></td></tr>
+<tr><td class="memItemLeft" align="right" valign="top"><a class="anchor" id="a9d20d55b0914ff81bf0f56e57ca7416e"></a><!-- doxytag: member="yaml_emitter_s::sequence_context" ref="a9d20d55b0914ff81bf0f56e57ca7416e" args="" -->
+int&nbsp;</td><td class="memItemRight" valign="bottom"><a class="el" href="structyaml__emitter__s.html#a9d20d55b0914ff81bf0f56e57ca7416e">sequence_context</a></td></tr>
+<tr><td class="mdescLeft">&nbsp;</td><td class="mdescRight">Is it a sequence context? <br/></td></tr>
+<tr><td class="memItemLeft" align="right" valign="top"><a class="anchor" id="a5a7527d8da86b28d95ff18b29f9d82f0"></a><!-- doxytag: member="yaml_emitter_s::mapping_context" ref="a5a7527d8da86b28d95ff18b29f9d82f0" args="" -->
+int&nbsp;</td><td class="memItemRight" valign="bottom"><a class="el" href="structyaml__emitter__s.html#a5a7527d8da86b28d95ff18b29f9d82f0">mapping_context</a></td></tr>
+<tr><td class="mdescLeft">&nbsp;</td><td class="mdescRight">Is it a mapping context? <br/></td></tr>
+<tr><td class="memItemLeft" align="right" valign="top"><a class="anchor" id="acc0db69cdae44c1385bbb2b6c207371b"></a><!-- doxytag: member="yaml_emitter_s::simple_key_context" ref="acc0db69cdae44c1385bbb2b6c207371b" args="" -->
+int&nbsp;</td><td class="memItemRight" valign="bottom"><a class="el" href="structyaml__emitter__s.html#acc0db69cdae44c1385bbb2b6c207371b">simple_key_context</a></td></tr>
+<tr><td class="mdescLeft">&nbsp;</td><td class="mdescRight">Is it a simple mapping key context? <br/></td></tr>
+<tr><td class="memItemLeft" align="right" valign="top">int&nbsp;</td><td class="memItemRight" valign="bottom"><a class="el" href="structyaml__emitter__s.html#a4fe9295608f19a687e41ec3661383e88">line</a></td></tr>
+<tr><td class="mdescLeft">&nbsp;</td><td class="mdescRight">The current line. <a href="#a4fe9295608f19a687e41ec3661383e88"></a><br/></td></tr>
+<tr><td class="memItemLeft" align="right" valign="top">int&nbsp;</td><td class="memItemRight" valign="bottom"><a class="el" href="structyaml__emitter__s.html#a678fbbacad5d1f3f9bb7516282888b8a">column</a></td></tr>
+<tr><td class="mdescLeft">&nbsp;</td><td class="mdescRight">The current column. <a href="#a678fbbacad5d1f3f9bb7516282888b8a"></a><br/></td></tr>
+<tr><td class="memItemLeft" align="right" valign="top"><a class="anchor" id="a160ed0cf1cc6116b65772d14ced2d867"></a><!-- doxytag: member="yaml_emitter_s::whitespace" ref="a160ed0cf1cc6116b65772d14ced2d867" args="" -->
+int&nbsp;</td><td class="memItemRight" valign="bottom"><a class="el" href="structyaml__emitter__s.html#a160ed0cf1cc6116b65772d14ced2d867">whitespace</a></td></tr>
+<tr><td class="mdescLeft">&nbsp;</td><td class="mdescRight">If the last character was a whitespace? <br/></td></tr>
+<tr><td class="memItemLeft" align="right" valign="top"><a class="anchor" id="a407de8ff950b16b4254a381d4e5cea42"></a><!-- doxytag: member="yaml_emitter_s::indention" ref="a407de8ff950b16b4254a381d4e5cea42" args="" -->
+int&nbsp;</td><td class="memItemRight" valign="bottom"><a class="el" href="structyaml__emitter__s.html#a407de8ff950b16b4254a381d4e5cea42">indention</a></td></tr>
+<tr><td class="mdescLeft">&nbsp;</td><td class="mdescRight">If the last character was an indentation character (' ', '-', '?', ':')? <br/></td></tr>
+<tr><td class="memItemLeft" align="right" valign="top"><a class="anchor" id="a65e84454b702622c41a068768c144c51"></a><!-- doxytag: member="yaml_emitter_s::open_ended" ref="a65e84454b702622c41a068768c144c51" args="" -->
+int&nbsp;</td><td class="memItemRight" valign="bottom"><a class="el" href="structyaml__emitter__s.html#a65e84454b702622c41a068768c144c51">open_ended</a></td></tr>
+<tr><td class="mdescLeft">&nbsp;</td><td class="mdescRight">If an explicit document end is required? <br/></td></tr>
+<tr><td class="memItemLeft" >struct {</td></tr>
+<tr><td class="memItemLeft" >&nbsp;&nbsp;&nbsp;<a class="el" href="group__basic.html#gaf8657e81f0b8b05d1a081001fc6cb8bd">yaml_char_t</a> *&nbsp;&nbsp;&nbsp;<a class="el" href="structyaml__emitter__s.html#a6f2882bde71e478e29dc5b293def8739">anchor</a></td></tr>
+<tr><td class="mdescLeft">&nbsp;</td><td class="mdescRight">The anchor value. <a href="#ad3e6ace8839e0b08f63246bfbf90b2ef"></a><br/></td></tr>
+<tr><td class="memItemLeft" >&nbsp;&nbsp;&nbsp;size_t&nbsp;&nbsp;&nbsp;<a class="el" href="structyaml__emitter__s.html#aece73cc234475630032b1c75a735eeb5">anchor_length</a></td></tr>
+<tr><td class="mdescLeft">&nbsp;</td><td class="mdescRight">The anchor length. <a href="#a842cf7da8db1cd9dc7307f1399b91f27"></a><br/></td></tr>
+<tr><td class="memItemLeft" >&nbsp;&nbsp;&nbsp;int&nbsp;&nbsp;&nbsp;<a class="el" href="structyaml__emitter__s.html#a1129c6f9ae5cd3b437b8ab8767324f03">alias</a></td></tr>
+<tr><td class="mdescLeft">&nbsp;</td><td class="mdescRight">Is it an alias? <br/></td></tr>
+<tr><td class="memItemLeft" valign="top">}&nbsp;</td><td class="memItemRight" valign="bottom"><a class="el" href="structyaml__emitter__s.html#ad8883d967ee02e3e15e58bc2533188cc">anchor_data</a></td></tr>
+<tr><td class="mdescLeft">&nbsp;</td><td class="mdescRight">Anchor analysis. <a href="#ad8883d967ee02e3e15e58bc2533188cc"></a><br/></td></tr>
+<tr><td class="memItemLeft" >struct {</td></tr>
+<tr><td class="memItemLeft" >&nbsp;&nbsp;&nbsp;<a class="el" href="group__basic.html#gaf8657e81f0b8b05d1a081001fc6cb8bd">yaml_char_t</a> *&nbsp;&nbsp;&nbsp;<a class="el" href="structyaml__emitter__s.html#a7f043a9092eef2d644cc8f1180386239">handle</a></td></tr>
+<tr><td class="mdescLeft">&nbsp;</td><td class="mdescRight">The tag handle. <a href="#a125a07a57bdea9ce74b227e5110846b3"></a><br/></td></tr>
+<tr><td class="memItemLeft" >&nbsp;&nbsp;&nbsp;size_t&nbsp;&nbsp;&nbsp;<a class="el" href="structyaml__emitter__s.html#a3552cece6908f99518205e8cbe2c793a">handle_length</a></td></tr>
+<tr><td class="mdescLeft">&nbsp;</td><td class="mdescRight">The tag handle length. <a href="#a48ed2d41edbc13c4b6d9544a650c7df3"></a><br/></td></tr>
+<tr><td class="memItemLeft" >&nbsp;&nbsp;&nbsp;<a class="el" href="group__basic.html#gaf8657e81f0b8b05d1a081001fc6cb8bd">yaml_char_t</a> *&nbsp;&nbsp;&nbsp;<a class="el" href="structyaml__emitter__s.html#ad9b61d5e9e05a47b2f873342ab226188">suffix</a></td></tr>
+<tr><td class="mdescLeft">&nbsp;</td><td class="mdescRight">The tag suffix. <a href="#a4b489e1dd4ea43b8ecf54879ded7dd0c"></a><br/></td></tr>
+<tr><td class="memItemLeft" >&nbsp;&nbsp;&nbsp;size_t&nbsp;&nbsp;&nbsp;<a class="el" href="structyaml__emitter__s.html#ad83936bbd4b6b77c79555c71cccc8fb5">suffix_length</a></td></tr>
+<tr><td class="mdescLeft">&nbsp;</td><td class="mdescRight">The tag suffix length. <a href="#a604f3279204adb47bbd1d6337338cb4b"></a><br/></td></tr>
+<tr><td class="memItemLeft" valign="top">}&nbsp;</td><td class="memItemRight" valign="bottom"><a class="el" href="structyaml__emitter__s.html#a3b947fbbc337d123af10c58abf1353a4">tag_data</a></td></tr>
+<tr><td class="mdescLeft">&nbsp;</td><td class="mdescRight">Tag analysis. <a href="#a3b947fbbc337d123af10c58abf1353a4"></a><br/></td></tr>
+<tr><td class="memItemLeft" >struct {</td></tr>
+<tr><td class="memItemLeft" >&nbsp;&nbsp;&nbsp;<a class="el" href="group__basic.html#gaf8657e81f0b8b05d1a081001fc6cb8bd">yaml_char_t</a> *&nbsp;&nbsp;&nbsp;<a class="el" href="structyaml__emitter__s.html#a20246ec76d64854ff93629cf1b424d86">value</a></td></tr>
+<tr><td class="mdescLeft">&nbsp;</td><td class="mdescRight">The scalar value. <a href="#a6164e21146b779344687765d2a725c6a"></a><br/></td></tr>
+<tr><td class="memItemLeft" >&nbsp;&nbsp;&nbsp;size_t&nbsp;&nbsp;&nbsp;<a class="el" href="structyaml__emitter__s.html#a4f72d57ad020803803e78922ecdec580">length</a></td></tr>
+<tr><td class="mdescLeft">&nbsp;</td><td class="mdescRight">The scalar length. <a href="#a0f4fb6e181eaf2233b2bb8dc78492f61"></a><br/></td></tr>
+<tr><td class="memItemLeft" >&nbsp;&nbsp;&nbsp;int&nbsp;&nbsp;&nbsp;<a class="el" href="structyaml__emitter__s.html#a363a1aaaf512433ee7eab3083428cc70">multiline</a></td></tr>
+<tr><td class="mdescLeft">&nbsp;</td><td class="mdescRight">Does the scalar contain line breaks? <br/></td></tr>
+<tr><td class="memItemLeft" >&nbsp;&nbsp;&nbsp;int&nbsp;&nbsp;&nbsp;<a class="el" href="structyaml__emitter__s.html#afd8496f5bb995bb5aacc349fd6b45bf5">flow_plain_allowed</a></td></tr>
+<tr><td class="mdescLeft">&nbsp;</td><td class="mdescRight">Can the scalar be expessed in the flow plain style? <br/></td></tr>
+<tr><td class="memItemLeft" >&nbsp;&nbsp;&nbsp;int&nbsp;&nbsp;&nbsp;<a class="el" href="structyaml__emitter__s.html#a5b5f6c9d687d788c8dac86d213ef4c16">block_plain_allowed</a></td></tr>
+<tr><td class="mdescLeft">&nbsp;</td><td class="mdescRight">Can the scalar be expressed in the block plain style? <br/></td></tr>
+<tr><td class="memItemLeft" >&nbsp;&nbsp;&nbsp;int&nbsp;&nbsp;&nbsp;<a class="el" href="structyaml__emitter__s.html#a3729ff7e7add06a1a1d9067a557a59fc">single_quoted_allowed</a></td></tr>
+<tr><td class="mdescLeft">&nbsp;</td><td class="mdescRight">Can the scalar be expressed in the single quoted style? <br/></td></tr>
+<tr><td class="memItemLeft" >&nbsp;&nbsp;&nbsp;int&nbsp;&nbsp;&nbsp;<a class="el" href="structyaml__emitter__s.html#a64e05972897d02f606627ef0cf3c7420">block_allowed</a></td></tr>
+<tr><td class="mdescLeft">&nbsp;</td><td class="mdescRight">Can the scalar be expressed in the literal or folded styles? <br/></td></tr>
+<tr><td class="memItemLeft" >&nbsp;&nbsp;&nbsp;<a class="el" href="group__styles.html#ga3fa6405631e1afe5bd5c488a6c5e8065">yaml_scalar_style_t</a>&nbsp;&nbsp;&nbsp;<a class="el" href="structyaml__emitter__s.html#acd1e83d220103aa24577038cfb1c2d21">style</a></td></tr>
+<tr><td class="mdescLeft">&nbsp;</td><td class="mdescRight">The output style. <a href="#ae941b4d9252e3748f27227bbfa7a35ae"></a><br/></td></tr>
+<tr><td class="memItemLeft" valign="top">}&nbsp;</td><td class="memItemRight" valign="bottom"><a class="el" href="structyaml__emitter__s.html#ac3f80f4cb9c361b5fa4fa8f5cc04dbac">scalar_data</a></td></tr>
+<tr><td class="mdescLeft">&nbsp;</td><td class="mdescRight">Scalar analysis. <a href="#ac3f80f4cb9c361b5fa4fa8f5cc04dbac"></a><br/></td></tr>
+<tr><td colspan="2"><div class="groupHeader">Dumper stuff</div></td></tr>
+<tr><td colspan="2"><div class="groupText"><p><a class="anchor" id="amgrp07d3f44098630ad2efbb005f4d3493a8"></a> </p>
+</div></td></tr>
+<tr><td class="memItemLeft" align="right" valign="top"><a class="anchor" id="a0234d7e9bfbe7cc6e12b60f90f5ec552"></a><!-- doxytag: member="yaml_emitter_s::opened" ref="a0234d7e9bfbe7cc6e12b60f90f5ec552" args="" -->
+int&nbsp;</td><td class="memItemRight" valign="bottom"><a class="el" href="structyaml__emitter__s.html#a0234d7e9bfbe7cc6e12b60f90f5ec552">opened</a></td></tr>
+<tr><td class="mdescLeft">&nbsp;</td><td class="mdescRight">If the stream was already opened? <br/></td></tr>
+<tr><td class="memItemLeft" align="right" valign="top"><a class="anchor" id="a978d894a219686d31d971899e31910cd"></a><!-- doxytag: member="yaml_emitter_s::closed" ref="a978d894a219686d31d971899e31910cd" args="" -->
+int&nbsp;</td><td class="memItemRight" valign="bottom"><a class="el" href="structyaml__emitter__s.html#a978d894a219686d31d971899e31910cd">closed</a></td></tr>
+<tr><td class="mdescLeft">&nbsp;</td><td class="mdescRight">If the stream was already closed? <br/></td></tr>
+<tr><td class="memItemLeft" >struct {</td></tr>
+<tr><td class="memItemLeft" >&nbsp;&nbsp;&nbsp;int&nbsp;&nbsp;&nbsp;<a class="el" href="structyaml__emitter__s.html#a8f00c3c08e0d87bab11e91a4464a50bc">references</a></td></tr>
+<tr><td class="mdescLeft">&nbsp;</td><td class="mdescRight">The number of references. <a href="#a16a14d92decbdcedfca4b1feb7fb72cf"></a><br/></td></tr>
+<tr><td class="memItemLeft" >&nbsp;&nbsp;&nbsp;int&nbsp;&nbsp;&nbsp;<a class="el" href="structyaml__emitter__s.html#a88154c89db7ec99fb322b1970371c350">anchor</a></td></tr>
+<tr><td class="mdescLeft">&nbsp;</td><td class="mdescRight">The anchor id. <a href="#adaa633eac5b067224ff2136502d01c6f"></a><br/></td></tr>
+<tr><td class="memItemLeft" >&nbsp;&nbsp;&nbsp;int&nbsp;&nbsp;&nbsp;<a class="el" href="structyaml__emitter__s.html#a6c3e98c02ffae879717b3d09f9458936">serialized</a></td></tr>
+<tr><td class="mdescLeft">&nbsp;</td><td class="mdescRight">If the node has been emitted? <br/></td></tr>
+<tr><td class="memItemLeft" valign="top">}&nbsp;</td><td class="memItemRight" valign="bottom"><a class="el" href="structyaml__emitter__s.html#ad4e7a72cb8b1b67373ba6d76a5229e6b">anchors</a></td></tr>
+<tr><td class="mdescLeft">&nbsp;</td><td class="mdescRight">The information associated with the document nodes. <a href="#ad4e7a72cb8b1b67373ba6d76a5229e6b"></a><br/></td></tr>
+<tr><td class="memItemLeft" align="right" valign="top">int&nbsp;</td><td class="memItemRight" valign="bottom"><a class="el" href="structyaml__emitter__s.html#a0cede830c77a15df7f1b73b9023d2d11">last_anchor_id</a></td></tr>
+<tr><td class="mdescLeft">&nbsp;</td><td class="mdescRight">The last assigned anchor id. <a href="#a0cede830c77a15df7f1b73b9023d2d11"></a><br/></td></tr>
+<tr><td class="memItemLeft" align="right" valign="top"><a class="el" href="structyaml__document__s.html">yaml_document_t</a> *&nbsp;</td><td class="memItemRight" valign="bottom"><a class="el" href="structyaml__emitter__s.html#af9cc8801cc9b46a4f45255c67a1574a7">document</a></td></tr>
+<tr><td class="mdescLeft">&nbsp;</td><td class="mdescRight">The currently emitted document. <a href="#af9cc8801cc9b46a4f45255c67a1574a7"></a><br/></td></tr>
+</table>
+<hr/><a name="_details"></a><h2>Detailed Description</h2>
+<p>The emitter structure. </p>
+<p>All members are internal. Manage the structure using the <code>yaml_emitter_</code> family of functions. </p>
+<hr/><h2>Field Documentation</h2>
+<a class="anchor" id="afa2d6367a86ae6d43df14e24479bb0a7"></a><!-- doxytag: member="yaml_emitter_s::error" ref="afa2d6367a86ae6d43df14e24479bb0a7" args="" -->
+<div class="memitem">
+<div class="memproto">
+ <table class="memname">
+ <tr>
+ <td class="memname"><a class="el" href="group__basic.html#ga1a449f0c1b023e2ef1a596093c018e73">yaml_error_type_t</a> <a class="el" href="structyaml__emitter__s.html#afa2d6367a86ae6d43df14e24479bb0a7">yaml_emitter_s::error</a></td>
+ </tr>
+ </table>
+</div>
+<div class="memdoc">
+
+<p>Error type. </p>
+
+</div>
+</div>
+<a class="anchor" id="ae076ef7c85ae107a2233dd4206577800"></a><!-- doxytag: member="yaml_emitter_s::problem" ref="ae076ef7c85ae107a2233dd4206577800" args="" -->
+<div class="memitem">
+<div class="memproto">
+ <table class="memname">
+ <tr>
+ <td class="memname">const char* <a class="el" href="structyaml__emitter__s.html#ae076ef7c85ae107a2233dd4206577800">yaml_emitter_s::problem</a></td>
+ </tr>
+ </table>
+</div>
+<div class="memdoc">
+
+<p>Error description. </p>
+
+</div>
+</div>
+<a class="anchor" id="aefa7e29ba8042ed1d133a02bb368ea3e"></a><!-- doxytag: member="yaml_emitter_s::write_handler" ref="aefa7e29ba8042ed1d133a02bb368ea3e" args="" -->
+<div class="memitem">
+<div class="memproto">
+ <table class="memname">
+ <tr>
+ <td class="memname"><a class="el" href="group__emitter.html#ga1669659aacbe631ad406c78fce1f5379">yaml_write_handler_t</a>* <a class="el" href="structyaml__emitter__s.html#aefa7e29ba8042ed1d133a02bb368ea3e">yaml_emitter_s::write_handler</a></td>
+ </tr>
+ </table>
+</div>
+<div class="memdoc">
+
+<p>Write handler. </p>
+
+</div>
+</div>
+<a class="anchor" id="a6c4fe0176b69da64ac1ddc7e091967e5"></a><!-- doxytag: member="yaml_emitter_s::write_handler_data" ref="a6c4fe0176b69da64ac1ddc7e091967e5" args="" -->
+<div class="memitem">
+<div class="memproto">
+ <table class="memname">
+ <tr>
+ <td class="memname">void* <a class="el" href="structyaml__emitter__s.html#a6c4fe0176b69da64ac1ddc7e091967e5">yaml_emitter_s::write_handler_data</a></td>
+ </tr>
+ </table>
+</div>
+<div class="memdoc">
+
+<p>A pointer for passing to the white handler. </p>
+
+</div>
+</div>
+<a class="anchor" id="adb154d3d10b34077792b8e4a0f0596f7"></a><!-- doxytag: member="yaml_emitter_s::buffer" ref="adb154d3d10b34077792b8e4a0f0596f7" args="" -->
+<div class="memitem">
+<div class="memproto">
+ <table class="memname">
+ <tr>
+ <td class="memname">unsigned char* <a class="el" href="structyaml__emitter__s.html#adb154d3d10b34077792b8e4a0f0596f7">yaml_emitter_s::buffer</a></td>
+ </tr>
+ </table>
+</div>
+<div class="memdoc">
+
+<p>The buffer pointer. </p>
+
+</div>
+</div>
+<a class="anchor" id="a53bdc6a00632b48c81098aad91a9fd8d"></a><!-- doxytag: member="yaml_emitter_s::size" ref="a53bdc6a00632b48c81098aad91a9fd8d" args="" -->
+<div class="memitem">
+<div class="memproto">
+ <table class="memname">
+ <tr>
+ <td class="memname">size_t <a class="el" href="structyaml__emitter__s.html#a53bdc6a00632b48c81098aad91a9fd8d">yaml_emitter_s::size</a></td>
+ </tr>
+ </table>
+</div>
+<div class="memdoc">
+
+<p>The buffer size. </p>
+
+</div>
+</div>
+<a class="anchor" id="a1851639b8f0e53b8e272c806d9fb648b"></a><!-- doxytag: member="yaml_emitter_s::size_written" ref="a1851639b8f0e53b8e272c806d9fb648b" args="" -->
+<div class="memitem">
+<div class="memproto">
+ <table class="memname">
+ <tr>
+ <td class="memname">size_t* <a class="el" href="structyaml__emitter__s.html#a1851639b8f0e53b8e272c806d9fb648b">yaml_emitter_s::size_written</a></td>
+ </tr>
+ </table>
+</div>
+<div class="memdoc">
+
+<p>The number of written bytes. </p>
+
+</div>
+</div>
+<a class="anchor" id="a8803fe1047e8bcea9bdfcad0743fa0dd"></a><!-- doxytag: member="yaml_emitter_s::string" ref="a8803fe1047e8bcea9bdfcad0743fa0dd" args="" -->
+<div class="memitem">
+<div class="memproto">
+ <table class="memname">
+ <tr>
+ <td class="memname">struct { ... } <a class="el" href="structyaml__emitter__s.html#a8803fe1047e8bcea9bdfcad0743fa0dd">yaml_emitter_s::string</a></td>
+ </tr>
+ </table>
+</div>
+<div class="memdoc">
+
+<p>String output data. </p>
+
+</div>
+</div>
+<a class="anchor" id="abfe1e82cd5c4a180b1468e65ccfd1c61"></a><!-- doxytag: member="yaml_emitter_s::file" ref="abfe1e82cd5c4a180b1468e65ccfd1c61" args="" -->
+<div class="memitem">
+<div class="memproto">
+ <table class="memname">
+ <tr>
+ <td class="memname">FILE* <a class="el" href="structyaml__emitter__s.html#abfe1e82cd5c4a180b1468e65ccfd1c61">yaml_emitter_s::file</a></td>
+ </tr>
+ </table>
+</div>
+<div class="memdoc">
+
+<p>File output data. </p>
+
+</div>
+</div>
+<a class="anchor" id="aa975acf559cc87d79abdb732c994f56f"></a><!-- doxytag: member="yaml_emitter_s::output" ref="aa975acf559cc87d79abdb732c994f56f" args="" -->
+<div class="memitem">
+<div class="memproto">
+ <table class="memname">
+ <tr>
+ <td class="memname">union { ... } <a class="el" href="structyaml__emitter__s.html#aa975acf559cc87d79abdb732c994f56f">yaml_emitter_s::output</a></td>
+ </tr>
+ </table>
+</div>
+<div class="memdoc">
+
+<p>Standard (string or file) output data. </p>
+
+</div>
+</div>
+<a class="anchor" id="a1c8f40a58f0a3061449b3fed02be145e"></a><!-- doxytag: member="yaml_emitter_s::start" ref="a1c8f40a58f0a3061449b3fed02be145e" args="" -->
+<div class="memitem">
+<div class="memproto">
+ <table class="memname">
+ <tr>
+ <td class="memname"><a class="el" href="group__basic.html#gaf8657e81f0b8b05d1a081001fc6cb8bd">yaml_char_t</a>* <a class="el" href="structyaml__emitter__s.html#a1c8f40a58f0a3061449b3fed02be145e">yaml_emitter_s::start</a></td>
+ </tr>
+ </table>
+</div>
+<div class="memdoc">
+
+<p>The beginning of the buffer. </p>
+
+</div>
+</div>
+<a class="anchor" id="a42285849529f1b0eb9f4aac2eaef5204"></a><!-- doxytag: member="yaml_emitter_s::end" ref="a42285849529f1b0eb9f4aac2eaef5204" args="" -->
+<div class="memitem">
+<div class="memproto">
+ <table class="memname">
+ <tr>
+ <td class="memname"><a class="el" href="group__basic.html#gaf8657e81f0b8b05d1a081001fc6cb8bd">yaml_char_t</a>* <a class="el" href="structyaml__emitter__s.html#a42285849529f1b0eb9f4aac2eaef5204">yaml_emitter_s::end</a></td>
+ </tr>
+ </table>
+</div>
+<div class="memdoc">
+
+<p>The end of the buffer. </p>
+
+</div>
+</div>
+<a class="anchor" id="a7615ab51145234f467984f3091558852"></a><!-- doxytag: member="yaml_emitter_s::pointer" ref="a7615ab51145234f467984f3091558852" args="" -->
+<div class="memitem">
+<div class="memproto">
+ <table class="memname">
+ <tr>
+ <td class="memname"><a class="el" href="group__basic.html#gaf8657e81f0b8b05d1a081001fc6cb8bd">yaml_char_t</a>* <a class="el" href="structyaml__emitter__s.html#a7615ab51145234f467984f3091558852">yaml_emitter_s::pointer</a></td>
+ </tr>
+ </table>
+</div>
+<div class="memdoc">
+
+<p>The current position of the buffer. </p>
+
+</div>
+</div>
+<a class="anchor" id="adf20e81d4690b86732932aff06a6d2e6"></a><!-- doxytag: member="yaml_emitter_s::last" ref="adf20e81d4690b86732932aff06a6d2e6" args="" -->
+<div class="memitem">
+<div class="memproto">
+ <table class="memname">
+ <tr>
+ <td class="memname"><a class="el" href="group__basic.html#gaf8657e81f0b8b05d1a081001fc6cb8bd">yaml_char_t</a>* <a class="el" href="structyaml__emitter__s.html#adf20e81d4690b86732932aff06a6d2e6">yaml_emitter_s::last</a></td>
+ </tr>
+ </table>
+</div>
+<div class="memdoc">
+
+<p>The last filled position of the buffer. </p>
+
+</div>
+</div>
+<a class="anchor" id="afb2700e9b866b5be0ff6c7549c719f81"></a><!-- doxytag: member="yaml_emitter_s::buffer" ref="afb2700e9b866b5be0ff6c7549c719f81" args="" -->
+<div class="memitem">
+<div class="memproto">
+ <table class="memname">
+ <tr>
+ <td class="memname">struct { ... } <a class="el" href="structyaml__emitter__s.html#adb154d3d10b34077792b8e4a0f0596f7">yaml_emitter_s::buffer</a></td>
+ </tr>
+ </table>
+</div>
+<div class="memdoc">
+
+<p>The working buffer. </p>
+
+</div>
+</div>
+<a class="anchor" id="ae8913d3c0bf4c987dc452efee2c802e3"></a><!-- doxytag: member="yaml_emitter_s::start" ref="ae8913d3c0bf4c987dc452efee2c802e3" args="" -->
+<div class="memitem">
+<div class="memproto">
+ <table class="memname">
+ <tr>
+ <td class="memname">unsigned char* <a class="el" href="structyaml__emitter__s.html#a1c8f40a58f0a3061449b3fed02be145e">yaml_emitter_s::start</a></td>
+ </tr>
+ </table>
+</div>
+<div class="memdoc">
+
+<p>The beginning of the buffer. </p>
+
+</div>
+</div>
+<a class="anchor" id="abb03bd7a5b832de48f9fbc9512ed7936"></a><!-- doxytag: member="yaml_emitter_s::end" ref="abb03bd7a5b832de48f9fbc9512ed7936" args="" -->
+<div class="memitem">
+<div class="memproto">
+ <table class="memname">
+ <tr>
+ <td class="memname">unsigned char* <a class="el" href="structyaml__emitter__s.html#a42285849529f1b0eb9f4aac2eaef5204">yaml_emitter_s::end</a></td>
+ </tr>
+ </table>
+</div>
+<div class="memdoc">
+
+<p>The end of the buffer. </p>
+
+</div>
+</div>
+<a class="anchor" id="aed9370f42cea4dff82f96839ce760b5a"></a><!-- doxytag: member="yaml_emitter_s::pointer" ref="aed9370f42cea4dff82f96839ce760b5a" args="" -->
+<div class="memitem">
+<div class="memproto">
+ <table class="memname">
+ <tr>
+ <td class="memname">unsigned char* <a class="el" href="structyaml__emitter__s.html#a7615ab51145234f467984f3091558852">yaml_emitter_s::pointer</a></td>
+ </tr>
+ </table>
+</div>
+<div class="memdoc">
+
+<p>The current position of the buffer. </p>
+
+</div>
+</div>
+<a class="anchor" id="ad0c5410fff4602266a0c6e0af730dd70"></a><!-- doxytag: member="yaml_emitter_s::last" ref="ad0c5410fff4602266a0c6e0af730dd70" args="" -->
+<div class="memitem">
+<div class="memproto">
+ <table class="memname">
+ <tr>
+ <td class="memname">unsigned char* <a class="el" href="structyaml__emitter__s.html#adf20e81d4690b86732932aff06a6d2e6">yaml_emitter_s::last</a></td>
+ </tr>
+ </table>
+</div>
+<div class="memdoc">
+
+<p>The last filled position of the buffer. </p>
+
+</div>
+</div>
+<a class="anchor" id="a6eeffbc9cd5beb89b679740b7f1d6d09"></a><!-- doxytag: member="yaml_emitter_s::raw_buffer" ref="a6eeffbc9cd5beb89b679740b7f1d6d09" args="" -->
+<div class="memitem">
+<div class="memproto">
+ <table class="memname">
+ <tr>
+ <td class="memname">struct { ... } <a class="el" href="structyaml__emitter__s.html#a6eeffbc9cd5beb89b679740b7f1d6d09">yaml_emitter_s::raw_buffer</a></td>
+ </tr>
+ </table>
+</div>
+<div class="memdoc">
+
+<p>The raw buffer. </p>
+
+</div>
+</div>
+<a class="anchor" id="ada17f19fa6248d6ee493684b03700857"></a><!-- doxytag: member="yaml_emitter_s::encoding" ref="ada17f19fa6248d6ee493684b03700857" args="" -->
+<div class="memitem">
+<div class="memproto">
+ <table class="memname">
+ <tr>
+ <td class="memname"><a class="el" href="group__basic.html#ga2170996d7e636397b5e6bc0c1b7df7c6">yaml_encoding_t</a> <a class="el" href="structyaml__emitter__s.html#ada17f19fa6248d6ee493684b03700857">yaml_emitter_s::encoding</a></td>
+ </tr>
+ </table>
+</div>
+<div class="memdoc">
+
+<p>The stream encoding. </p>
+
+</div>
+</div>
+<a class="anchor" id="a33545f8924be89daf8b81dc905d558c0"></a><!-- doxytag: member="yaml_emitter_s::best_indent" ref="a33545f8924be89daf8b81dc905d558c0" args="" -->
+<div class="memitem">
+<div class="memproto">
+ <table class="memname">
+ <tr>
+ <td class="memname">int <a class="el" href="structyaml__emitter__s.html#a33545f8924be89daf8b81dc905d558c0">yaml_emitter_s::best_indent</a></td>
+ </tr>
+ </table>
+</div>
+<div class="memdoc">
+
+<p>The number of indentation spaces. </p>
+
+</div>
+</div>
+<a class="anchor" id="a56dde6b352bdf7d4031f89d2b5d704f6"></a><!-- doxytag: member="yaml_emitter_s::best_width" ref="a56dde6b352bdf7d4031f89d2b5d704f6" args="" -->
+<div class="memitem">
+<div class="memproto">
+ <table class="memname">
+ <tr>
+ <td class="memname">int <a class="el" href="structyaml__emitter__s.html#a56dde6b352bdf7d4031f89d2b5d704f6">yaml_emitter_s::best_width</a></td>
+ </tr>
+ </table>
+</div>
+<div class="memdoc">
+
+<p>The preferred width of the output lines. </p>
+
+</div>
+</div>
+<a class="anchor" id="a84c1b884d805588495067ee98a8e7c50"></a><!-- doxytag: member="yaml_emitter_s::line_break" ref="a84c1b884d805588495067ee98a8e7c50" args="" -->
+<div class="memitem">
+<div class="memproto">
+ <table class="memname">
+ <tr>
+ <td class="memname"><a class="el" href="group__basic.html#ga64d1365e1acd4deeab50d6b48e39cb6d">yaml_break_t</a> <a class="el" href="structyaml__emitter__s.html#a84c1b884d805588495067ee98a8e7c50">yaml_emitter_s::line_break</a></td>
+ </tr>
+ </table>
+</div>
+<div class="memdoc">
+
+<p>The preferred line break. </p>
+
+</div>
+</div>
+<a class="anchor" id="ad68af21e510adcfc2db43b31e791efe1"></a><!-- doxytag: member="yaml_emitter_s::start" ref="ad68af21e510adcfc2db43b31e791efe1" args="" -->
+<div class="memitem">
+<div class="memproto">
+ <table class="memname">
+ <tr>
+ <td class="memname"><a class="el" href="group__emitter.html#ga0889461fa3efe8eee881aef48a4ba6b2">yaml_emitter_state_t</a>* <a class="el" href="structyaml__emitter__s.html#a1c8f40a58f0a3061449b3fed02be145e">yaml_emitter_s::start</a></td>
+ </tr>
+ </table>
+</div>
+<div class="memdoc">
+
+<p>The beginning of the stack. </p>
+
+</div>
+</div>
+<a class="anchor" id="a126a19ae360206437647892a344a30f0"></a><!-- doxytag: member="yaml_emitter_s::end" ref="a126a19ae360206437647892a344a30f0" args="" -->
+<div class="memitem">
+<div class="memproto">
+ <table class="memname">
+ <tr>
+ <td class="memname"><a class="el" href="group__emitter.html#ga0889461fa3efe8eee881aef48a4ba6b2">yaml_emitter_state_t</a>* <a class="el" href="structyaml__emitter__s.html#a42285849529f1b0eb9f4aac2eaef5204">yaml_emitter_s::end</a></td>
+ </tr>
+ </table>
+</div>
+<div class="memdoc">
+
+<p>The end of the stack. </p>
+
+</div>
+</div>
+<a class="anchor" id="aafa8b6f21022ce2f4cb9b44ad15a535e"></a><!-- doxytag: member="yaml_emitter_s::top" ref="aafa8b6f21022ce2f4cb9b44ad15a535e" args="" -->
+<div class="memitem">
+<div class="memproto">
+ <table class="memname">
+ <tr>
+ <td class="memname"><a class="el" href="group__emitter.html#ga0889461fa3efe8eee881aef48a4ba6b2">yaml_emitter_state_t</a>* <a class="el" href="structyaml__emitter__s.html#aafa8b6f21022ce2f4cb9b44ad15a535e">yaml_emitter_s::top</a></td>
+ </tr>
+ </table>
+</div>
+<div class="memdoc">
+
+<p>The top of the stack. </p>
+
+</div>
+</div>
+<a class="anchor" id="a6dc87fbd5b074507e102b967492b135d"></a><!-- doxytag: member="yaml_emitter_s::states" ref="a6dc87fbd5b074507e102b967492b135d" args="" -->
+<div class="memitem">
+<div class="memproto">
+ <table class="memname">
+ <tr>
+ <td class="memname">struct { ... } <a class="el" href="structyaml__emitter__s.html#a6dc87fbd5b074507e102b967492b135d">yaml_emitter_s::states</a></td>
+ </tr>
+ </table>
+</div>
+<div class="memdoc">
+
+<p>The stack of states. </p>
+
+</div>
+</div>
+<a class="anchor" id="a29f1d4f27ff9b9616c154f0730dd24ee"></a><!-- doxytag: member="yaml_emitter_s::state" ref="a29f1d4f27ff9b9616c154f0730dd24ee" args="" -->
+<div class="memitem">
+<div class="memproto">
+ <table class="memname">
+ <tr>
+ <td class="memname"><a class="el" href="group__emitter.html#ga0889461fa3efe8eee881aef48a4ba6b2">yaml_emitter_state_t</a> <a class="el" href="structyaml__emitter__s.html#a29f1d4f27ff9b9616c154f0730dd24ee">yaml_emitter_s::state</a></td>
+ </tr>
+ </table>
+</div>
+<div class="memdoc">
+
+<p>The current emitter state. </p>
+
+</div>
+</div>
+<a class="anchor" id="a2c31edecd7f6dfd87fe3f8e12b705884"></a><!-- doxytag: member="yaml_emitter_s::start" ref="a2c31edecd7f6dfd87fe3f8e12b705884" args="" -->
+<div class="memitem">
+<div class="memproto">
+ <table class="memname">
+ <tr>
+ <td class="memname"><a class="el" href="structyaml__event__s.html">yaml_event_t</a>* <a class="el" href="structyaml__emitter__s.html#a1c8f40a58f0a3061449b3fed02be145e">yaml_emitter_s::start</a></td>
+ </tr>
+ </table>
+</div>
+<div class="memdoc">
+
+<p>The beginning of the event queue. </p>
+
+</div>
+</div>
+<a class="anchor" id="a55703a15e71c6b9551a2f4feb888bdcb"></a><!-- doxytag: member="yaml_emitter_s::end" ref="a55703a15e71c6b9551a2f4feb888bdcb" args="" -->
+<div class="memitem">
+<div class="memproto">
+ <table class="memname">
+ <tr>
+ <td class="memname"><a class="el" href="structyaml__event__s.html">yaml_event_t</a>* <a class="el" href="structyaml__emitter__s.html#a42285849529f1b0eb9f4aac2eaef5204">yaml_emitter_s::end</a></td>
+ </tr>
+ </table>
+</div>
+<div class="memdoc">
+
+<p>The end of the event queue. </p>
+
+</div>
+</div>
+<a class="anchor" id="a547dfd20576006e606ffb0d8042b4234"></a><!-- doxytag: member="yaml_emitter_s::head" ref="a547dfd20576006e606ffb0d8042b4234" args="" -->
+<div class="memitem">
+<div class="memproto">
+ <table class="memname">
+ <tr>
+ <td class="memname"><a class="el" href="structyaml__event__s.html">yaml_event_t</a>* <a class="el" href="structyaml__emitter__s.html#a547dfd20576006e606ffb0d8042b4234">yaml_emitter_s::head</a></td>
+ </tr>
+ </table>
+</div>
+<div class="memdoc">
+
+<p>The head of the event queue. </p>
+
+</div>
+</div>
+<a class="anchor" id="acafa1e3cb872fa7917217469659fb273"></a><!-- doxytag: member="yaml_emitter_s::tail" ref="acafa1e3cb872fa7917217469659fb273" args="" -->
+<div class="memitem">
+<div class="memproto">
+ <table class="memname">
+ <tr>
+ <td class="memname"><a class="el" href="structyaml__event__s.html">yaml_event_t</a>* <a class="el" href="structyaml__emitter__s.html#acafa1e3cb872fa7917217469659fb273">yaml_emitter_s::tail</a></td>
+ </tr>
+ </table>
+</div>
+<div class="memdoc">
+
+<p>The tail of the event queue. </p>
+
+</div>
+</div>
+<a class="anchor" id="a3516b49eb7579e422750a94a9d7c1700"></a><!-- doxytag: member="yaml_emitter_s::events" ref="a3516b49eb7579e422750a94a9d7c1700" args="" -->
+<div class="memitem">
+<div class="memproto">
+ <table class="memname">
+ <tr>
+ <td class="memname">struct { ... } <a class="el" href="structyaml__emitter__s.html#a3516b49eb7579e422750a94a9d7c1700">yaml_emitter_s::events</a></td>
+ </tr>
+ </table>
+</div>
+<div class="memdoc">
+
+<p>The event queue. </p>
+
+</div>
+</div>
+<a class="anchor" id="a28ec8053132a8e7cf29df983835754b7"></a><!-- doxytag: member="yaml_emitter_s::start" ref="a28ec8053132a8e7cf29df983835754b7" args="" -->
+<div class="memitem">
+<div class="memproto">
+ <table class="memname">
+ <tr>
+ <td class="memname">int* <a class="el" href="structyaml__emitter__s.html#a1c8f40a58f0a3061449b3fed02be145e">yaml_emitter_s::start</a></td>
+ </tr>
+ </table>
+</div>
+<div class="memdoc">
+
+<p>The beginning of the stack. </p>
+
+</div>
+</div>
+<a class="anchor" id="a6669a94bc18247491e59c709852be0d1"></a><!-- doxytag: member="yaml_emitter_s::end" ref="a6669a94bc18247491e59c709852be0d1" args="" -->
+<div class="memitem">
+<div class="memproto">
+ <table class="memname">
+ <tr>
+ <td class="memname">int* <a class="el" href="structyaml__emitter__s.html#a42285849529f1b0eb9f4aac2eaef5204">yaml_emitter_s::end</a></td>
+ </tr>
+ </table>
+</div>
+<div class="memdoc">
+
+<p>The end of the stack. </p>
+
+</div>
+</div>
+<a class="anchor" id="a5779bcbfd04df64e42434b7599332d11"></a><!-- doxytag: member="yaml_emitter_s::top" ref="a5779bcbfd04df64e42434b7599332d11" args="" -->
+<div class="memitem">
+<div class="memproto">
+ <table class="memname">
+ <tr>
+ <td class="memname">int* <a class="el" href="structyaml__emitter__s.html#aafa8b6f21022ce2f4cb9b44ad15a535e">yaml_emitter_s::top</a></td>
+ </tr>
+ </table>
+</div>
+<div class="memdoc">
+
+<p>The top of the stack. </p>
+
+</div>
+</div>
+<a class="anchor" id="ad31c591593ccb78e6b04887bf4f162c8"></a><!-- doxytag: member="yaml_emitter_s::indents" ref="ad31c591593ccb78e6b04887bf4f162c8" args="" -->
+<div class="memitem">
+<div class="memproto">
+ <table class="memname">
+ <tr>
+ <td class="memname">struct { ... } <a class="el" href="structyaml__emitter__s.html#ad31c591593ccb78e6b04887bf4f162c8">yaml_emitter_s::indents</a></td>
+ </tr>
+ </table>
+</div>
+<div class="memdoc">
+
+<p>The stack of indentation levels. </p>
+
+</div>
+</div>
+<a class="anchor" id="a94afdd9750b95529bbbbd09456a4391d"></a><!-- doxytag: member="yaml_emitter_s::start" ref="a94afdd9750b95529bbbbd09456a4391d" args="" -->
+<div class="memitem">
+<div class="memproto">
+ <table class="memname">
+ <tr>
+ <td class="memname"><a class="el" href="structyaml__tag__directive__s.html">yaml_tag_directive_t</a>* <a class="el" href="structyaml__emitter__s.html#a1c8f40a58f0a3061449b3fed02be145e">yaml_emitter_s::start</a></td>
+ </tr>
+ </table>
+</div>
+<div class="memdoc">
+
+<p>The beginning of the list. </p>
+
+</div>
+</div>
+<a class="anchor" id="a3b28127063323de1d88fc18cdb6adf8a"></a><!-- doxytag: member="yaml_emitter_s::end" ref="a3b28127063323de1d88fc18cdb6adf8a" args="" -->
+<div class="memitem">
+<div class="memproto">
+ <table class="memname">
+ <tr>
+ <td class="memname"><a class="el" href="structyaml__tag__directive__s.html">yaml_tag_directive_t</a>* <a class="el" href="structyaml__emitter__s.html#a42285849529f1b0eb9f4aac2eaef5204">yaml_emitter_s::end</a></td>
+ </tr>
+ </table>
+</div>
+<div class="memdoc">
+
+<p>The end of the list. </p>
+
+</div>
+</div>
+<a class="anchor" id="a8e3f468d814d2aa5e074f7da1648d34a"></a><!-- doxytag: member="yaml_emitter_s::top" ref="a8e3f468d814d2aa5e074f7da1648d34a" args="" -->
+<div class="memitem">
+<div class="memproto">
+ <table class="memname">
+ <tr>
+ <td class="memname"><a class="el" href="structyaml__tag__directive__s.html">yaml_tag_directive_t</a>* <a class="el" href="structyaml__emitter__s.html#aafa8b6f21022ce2f4cb9b44ad15a535e">yaml_emitter_s::top</a></td>
+ </tr>
+ </table>
+</div>
+<div class="memdoc">
+
+<p>The top of the list. </p>
+
+</div>
+</div>
+<a class="anchor" id="a9dc51f2ccb8a517e2dc029e1af960258"></a><!-- doxytag: member="yaml_emitter_s::tag_directives" ref="a9dc51f2ccb8a517e2dc029e1af960258" args="" -->
+<div class="memitem">
+<div class="memproto">
+ <table class="memname">
+ <tr>
+ <td class="memname">struct { ... } <a class="el" href="structyaml__emitter__s.html#a9dc51f2ccb8a517e2dc029e1af960258">yaml_emitter_s::tag_directives</a></td>
+ </tr>
+ </table>
+</div>
+<div class="memdoc">
+
+<p>The list of tag directives. </p>
+
+</div>
+</div>
+<a class="anchor" id="a93a73494a5d62464a67cc71f86ad9728"></a><!-- doxytag: member="yaml_emitter_s::indent" ref="a93a73494a5d62464a67cc71f86ad9728" args="" -->
+<div class="memitem">
+<div class="memproto">
+ <table class="memname">
+ <tr>
+ <td class="memname">int <a class="el" href="structyaml__emitter__s.html#a93a73494a5d62464a67cc71f86ad9728">yaml_emitter_s::indent</a></td>
+ </tr>
+ </table>
+</div>
+<div class="memdoc">
+
+<p>The current indentation level. </p>
+
+</div>
+</div>
+<a class="anchor" id="a50f8e97c4290b83ebd646b4c4f5c5de9"></a><!-- doxytag: member="yaml_emitter_s::flow_level" ref="a50f8e97c4290b83ebd646b4c4f5c5de9" args="" -->
+<div class="memitem">
+<div class="memproto">
+ <table class="memname">
+ <tr>
+ <td class="memname">int <a class="el" href="structyaml__emitter__s.html#a50f8e97c4290b83ebd646b4c4f5c5de9">yaml_emitter_s::flow_level</a></td>
+ </tr>
+ </table>
+</div>
+<div class="memdoc">
+
+<p>The current flow level. </p>
+
+</div>
+</div>
+<a class="anchor" id="a4fe9295608f19a687e41ec3661383e88"></a><!-- doxytag: member="yaml_emitter_s::line" ref="a4fe9295608f19a687e41ec3661383e88" args="" -->
+<div class="memitem">
+<div class="memproto">
+ <table class="memname">
+ <tr>
+ <td class="memname">int <a class="el" href="structyaml__emitter__s.html#a4fe9295608f19a687e41ec3661383e88">yaml_emitter_s::line</a></td>
+ </tr>
+ </table>
+</div>
+<div class="memdoc">
+
+<p>The current line. </p>
+
+</div>
+</div>
+<a class="anchor" id="a678fbbacad5d1f3f9bb7516282888b8a"></a><!-- doxytag: member="yaml_emitter_s::column" ref="a678fbbacad5d1f3f9bb7516282888b8a" args="" -->
+<div class="memitem">
+<div class="memproto">
+ <table class="memname">
+ <tr>
+ <td class="memname">int <a class="el" href="structyaml__emitter__s.html#a678fbbacad5d1f3f9bb7516282888b8a">yaml_emitter_s::column</a></td>
+ </tr>
+ </table>
+</div>
+<div class="memdoc">
+
+<p>The current column. </p>
+
+</div>
+</div>
+<a class="anchor" id="a6f2882bde71e478e29dc5b293def8739"></a><!-- doxytag: member="yaml_emitter_s::anchor" ref="a6f2882bde71e478e29dc5b293def8739" args="" -->
+<div class="memitem">
+<div class="memproto">
+ <table class="memname">
+ <tr>
+ <td class="memname"><a class="el" href="group__basic.html#gaf8657e81f0b8b05d1a081001fc6cb8bd">yaml_char_t</a>* <a class="el" href="structyaml__emitter__s.html#a6f2882bde71e478e29dc5b293def8739">yaml_emitter_s::anchor</a></td>
+ </tr>
+ </table>
+</div>
+<div class="memdoc">
+
+<p>The anchor value. </p>
+
+</div>
+</div>
+<a class="anchor" id="aece73cc234475630032b1c75a735eeb5"></a><!-- doxytag: member="yaml_emitter_s::anchor_length" ref="aece73cc234475630032b1c75a735eeb5" args="" -->
+<div class="memitem">
+<div class="memproto">
+ <table class="memname">
+ <tr>
+ <td class="memname">size_t <a class="el" href="structyaml__emitter__s.html#aece73cc234475630032b1c75a735eeb5">yaml_emitter_s::anchor_length</a></td>
+ </tr>
+ </table>
+</div>
+<div class="memdoc">
+
+<p>The anchor length. </p>
+
+</div>
+</div>
+<a class="anchor" id="ad8883d967ee02e3e15e58bc2533188cc"></a><!-- doxytag: member="yaml_emitter_s::anchor_data" ref="ad8883d967ee02e3e15e58bc2533188cc" args="" -->
+<div class="memitem">
+<div class="memproto">
+ <table class="memname">
+ <tr>
+ <td class="memname">struct { ... } <a class="el" href="structyaml__emitter__s.html#ad8883d967ee02e3e15e58bc2533188cc">yaml_emitter_s::anchor_data</a></td>
+ </tr>
+ </table>
+</div>
+<div class="memdoc">
+
+<p>Anchor analysis. </p>
+
+</div>
+</div>
+<a class="anchor" id="a7f043a9092eef2d644cc8f1180386239"></a><!-- doxytag: member="yaml_emitter_s::handle" ref="a7f043a9092eef2d644cc8f1180386239" args="" -->
+<div class="memitem">
+<div class="memproto">
+ <table class="memname">
+ <tr>
+ <td class="memname"><a class="el" href="group__basic.html#gaf8657e81f0b8b05d1a081001fc6cb8bd">yaml_char_t</a>* <a class="el" href="structyaml__emitter__s.html#a7f043a9092eef2d644cc8f1180386239">yaml_emitter_s::handle</a></td>
+ </tr>
+ </table>
+</div>
+<div class="memdoc">
+
+<p>The tag handle. </p>
+
+</div>
+</div>
+<a class="anchor" id="a3552cece6908f99518205e8cbe2c793a"></a><!-- doxytag: member="yaml_emitter_s::handle_length" ref="a3552cece6908f99518205e8cbe2c793a" args="" -->
+<div class="memitem">
+<div class="memproto">
+ <table class="memname">
+ <tr>
+ <td class="memname">size_t <a class="el" href="structyaml__emitter__s.html#a3552cece6908f99518205e8cbe2c793a">yaml_emitter_s::handle_length</a></td>
+ </tr>
+ </table>
+</div>
+<div class="memdoc">
+
+<p>The tag handle length. </p>
+
+</div>
+</div>
+<a class="anchor" id="ad9b61d5e9e05a47b2f873342ab226188"></a><!-- doxytag: member="yaml_emitter_s::suffix" ref="ad9b61d5e9e05a47b2f873342ab226188" args="" -->
+<div class="memitem">
+<div class="memproto">
+ <table class="memname">
+ <tr>
+ <td class="memname"><a class="el" href="group__basic.html#gaf8657e81f0b8b05d1a081001fc6cb8bd">yaml_char_t</a>* <a class="el" href="structyaml__emitter__s.html#ad9b61d5e9e05a47b2f873342ab226188">yaml_emitter_s::suffix</a></td>
+ </tr>
+ </table>
+</div>
+<div class="memdoc">
+
+<p>The tag suffix. </p>
+
+</div>
+</div>
+<a class="anchor" id="ad83936bbd4b6b77c79555c71cccc8fb5"></a><!-- doxytag: member="yaml_emitter_s::suffix_length" ref="ad83936bbd4b6b77c79555c71cccc8fb5" args="" -->
+<div class="memitem">
+<div class="memproto">
+ <table class="memname">
+ <tr>
+ <td class="memname">size_t <a class="el" href="structyaml__emitter__s.html#ad83936bbd4b6b77c79555c71cccc8fb5">yaml_emitter_s::suffix_length</a></td>
+ </tr>
+ </table>
+</div>
+<div class="memdoc">
+
+<p>The tag suffix length. </p>
+
+</div>
+</div>
+<a class="anchor" id="a3b947fbbc337d123af10c58abf1353a4"></a><!-- doxytag: member="yaml_emitter_s::tag_data" ref="a3b947fbbc337d123af10c58abf1353a4" args="" -->
+<div class="memitem">
+<div class="memproto">
+ <table class="memname">
+ <tr>
+ <td class="memname">struct { ... } <a class="el" href="structyaml__emitter__s.html#a3b947fbbc337d123af10c58abf1353a4">yaml_emitter_s::tag_data</a></td>
+ </tr>
+ </table>
+</div>
+<div class="memdoc">
+
+<p>Tag analysis. </p>
+
+</div>
+</div>
+<a class="anchor" id="a20246ec76d64854ff93629cf1b424d86"></a><!-- doxytag: member="yaml_emitter_s::value" ref="a20246ec76d64854ff93629cf1b424d86" args="" -->
+<div class="memitem">
+<div class="memproto">
+ <table class="memname">
+ <tr>
+ <td class="memname"><a class="el" href="group__basic.html#gaf8657e81f0b8b05d1a081001fc6cb8bd">yaml_char_t</a>* <a class="el" href="structyaml__emitter__s.html#a20246ec76d64854ff93629cf1b424d86">yaml_emitter_s::value</a></td>
+ </tr>
+ </table>
+</div>
+<div class="memdoc">
+
+<p>The scalar value. </p>
+
+</div>
+</div>
+<a class="anchor" id="a4f72d57ad020803803e78922ecdec580"></a><!-- doxytag: member="yaml_emitter_s::length" ref="a4f72d57ad020803803e78922ecdec580" args="" -->
+<div class="memitem">
+<div class="memproto">
+ <table class="memname">
+ <tr>
+ <td class="memname">size_t <a class="el" href="structyaml__emitter__s.html#a4f72d57ad020803803e78922ecdec580">yaml_emitter_s::length</a></td>
+ </tr>
+ </table>
+</div>
+<div class="memdoc">
+
+<p>The scalar length. </p>
+
+</div>
+</div>
+<a class="anchor" id="acd1e83d220103aa24577038cfb1c2d21"></a><!-- doxytag: member="yaml_emitter_s::style" ref="acd1e83d220103aa24577038cfb1c2d21" args="" -->
+<div class="memitem">
+<div class="memproto">
+ <table class="memname">
+ <tr>
+ <td class="memname"><a class="el" href="group__styles.html#ga3fa6405631e1afe5bd5c488a6c5e8065">yaml_scalar_style_t</a> <a class="el" href="structyaml__emitter__s.html#acd1e83d220103aa24577038cfb1c2d21">yaml_emitter_s::style</a></td>
+ </tr>
+ </table>
+</div>
+<div class="memdoc">
+
+<p>The output style. </p>
+
+</div>
+</div>
+<a class="anchor" id="ac3f80f4cb9c361b5fa4fa8f5cc04dbac"></a><!-- doxytag: member="yaml_emitter_s::scalar_data" ref="ac3f80f4cb9c361b5fa4fa8f5cc04dbac" args="" -->
+<div class="memitem">
+<div class="memproto">
+ <table class="memname">
+ <tr>
+ <td class="memname">struct { ... } <a class="el" href="structyaml__emitter__s.html#ac3f80f4cb9c361b5fa4fa8f5cc04dbac">yaml_emitter_s::scalar_data</a></td>
+ </tr>
+ </table>
+</div>
+<div class="memdoc">
+
+<p>Scalar analysis. </p>
+
+</div>
+</div>
+<a class="anchor" id="a8f00c3c08e0d87bab11e91a4464a50bc"></a><!-- doxytag: member="yaml_emitter_s::references" ref="a8f00c3c08e0d87bab11e91a4464a50bc" args="" -->
+<div class="memitem">
+<div class="memproto">
+ <table class="memname">
+ <tr>
+ <td class="memname">int <a class="el" href="structyaml__emitter__s.html#a8f00c3c08e0d87bab11e91a4464a50bc">yaml_emitter_s::references</a></td>
+ </tr>
+ </table>
+</div>
+<div class="memdoc">
+
+<p>The number of references. </p>
+
+</div>
+</div>
+<a class="anchor" id="a88154c89db7ec99fb322b1970371c350"></a><!-- doxytag: member="yaml_emitter_s::anchor" ref="a88154c89db7ec99fb322b1970371c350" args="" -->
+<div class="memitem">
+<div class="memproto">
+ <table class="memname">
+ <tr>
+ <td class="memname">int <a class="el" href="structyaml__emitter__s.html#a6f2882bde71e478e29dc5b293def8739">yaml_emitter_s::anchor</a></td>
+ </tr>
+ </table>
+</div>
+<div class="memdoc">
+
+<p>The anchor id. </p>
+
+</div>
+</div>
+<a class="anchor" id="ad4e7a72cb8b1b67373ba6d76a5229e6b"></a><!-- doxytag: member="yaml_emitter_s::anchors" ref="ad4e7a72cb8b1b67373ba6d76a5229e6b" args="" -->
+<div class="memitem">
+<div class="memproto">
+ <table class="memname">
+ <tr>
+ <td class="memname">struct { ... } * <a class="el" href="structyaml__emitter__s.html#ad4e7a72cb8b1b67373ba6d76a5229e6b">yaml_emitter_s::anchors</a></td>
+ </tr>
+ </table>
+</div>
+<div class="memdoc">
+
+<p>The information associated with the document nodes. </p>
+
+</div>
+</div>
+<a class="anchor" id="a0cede830c77a15df7f1b73b9023d2d11"></a><!-- doxytag: member="yaml_emitter_s::last_anchor_id" ref="a0cede830c77a15df7f1b73b9023d2d11" args="" -->
+<div class="memitem">
+<div class="memproto">
+ <table class="memname">
+ <tr>
+ <td class="memname">int <a class="el" href="structyaml__emitter__s.html#a0cede830c77a15df7f1b73b9023d2d11">yaml_emitter_s::last_anchor_id</a></td>
+ </tr>
+ </table>
+</div>
+<div class="memdoc">
+
+<p>The last assigned anchor id. </p>
+
+</div>
+</div>
+<a class="anchor" id="af9cc8801cc9b46a4f45255c67a1574a7"></a><!-- doxytag: member="yaml_emitter_s::document" ref="af9cc8801cc9b46a4f45255c67a1574a7" args="" -->
+<div class="memitem">
+<div class="memproto">
+ <table class="memname">
+ <tr>
+ <td class="memname"><a class="el" href="structyaml__document__s.html">yaml_document_t</a>* <a class="el" href="structyaml__emitter__s.html#af9cc8801cc9b46a4f45255c67a1574a7">yaml_emitter_s::document</a></td>
+ </tr>
+ </table>
+</div>
+<div class="memdoc">
+
+<p>The currently emitted document. </p>
+
+</div>
+</div>
+<hr/>The documentation for this struct was generated from the following file:<ul>
+<li><a class="el" href="yaml_8h.html">yaml.h</a></li>
+</ul>
+</div>
+<hr class="footer"/><address class="footer"><small>Generated on Mon May 30 2011 22:00:00 for yaml by&nbsp;
+<a href="http://www.doxygen.org/index.html">
+<img class="footer" src="doxygen.png" alt="doxygen"/></a> 1.7.1 </small></address>
+</body>
+</html>
diff --git a/contrib/libyaml/doc/html/structyaml__event__s.html b/contrib/libyaml/doc/html/structyaml__event__s.html
new file mode 100644
index 0000000..5c21fd4
--- /dev/null
+++ b/contrib/libyaml/doc/html/structyaml__event__s.html
@@ -0,0 +1,496 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head>
+<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/>
+<title>yaml: yaml_event_s Struct Reference</title>
+<link href="tabs.css" rel="stylesheet" type="text/css"/>
+<link href="doxygen.css" rel="stylesheet" type="text/css"/>
+</head>
+<body>
+<!-- Generated by Doxygen 1.7.1 -->
+<div class="navigation" id="top">
+ <div class="tabs">
+ <ul class="tablist">
+ <li><a href="index.html"><span>Main&nbsp;Page</span></a></li>
+ <li><a href="modules.html"><span>Modules</span></a></li>
+ <li class="current"><a href="annotated.html"><span>Data&nbsp;Structures</span></a></li>
+ <li><a href="files.html"><span>Files</span></a></li>
+ </ul>
+ </div>
+ <div class="tabs2">
+ <ul class="tablist">
+ <li><a href="annotated.html"><span>Data&nbsp;Structures</span></a></li>
+ <li><a href="functions.html"><span>Data&nbsp;Fields</span></a></li>
+ </ul>
+ </div>
+</div>
+<div class="header">
+ <div class="summary">
+<a href="#pub-attribs">Data Fields</a> </div>
+ <div class="headertitle">
+<h1>yaml_event_s Struct Reference<br/>
+<small>
+[<a class="el" href="group__events.html">Events</a>]</small>
+</h1> </div>
+</div>
+<div class="contents">
+<!-- doxytag: class="yaml_event_s" -->
+<p>The event structure.
+<a href="#_details">More...</a></p>
+
+<p><code>#include &lt;yaml.h&gt;</code></p>
+<table class="memberdecls">
+<tr><td colspan="2"><h2><a name="pub-attribs"></a>
+Data Fields</h2></td></tr>
+<tr><td class="memItemLeft" align="right" valign="top"><a class="el" href="group__events.html#ga8934661be36bd7c9d17a8af69eff89a1">yaml_event_type_t</a>&nbsp;</td><td class="memItemRight" valign="bottom"><a class="el" href="structyaml__event__s.html#aff08bc3df4859d5b3a804e8c011cac51">type</a></td></tr>
+<tr><td class="mdescLeft">&nbsp;</td><td class="mdescRight">The event type. <a href="#aff08bc3df4859d5b3a804e8c011cac51"></a><br/></td></tr>
+<tr><td class="memItemLeft" >union {</td></tr>
+<tr><td class="memItemLeft" >&nbsp;&nbsp;&nbsp;struct {</td></tr>
+<tr><td class="memItemLeft" >&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<a class="el" href="group__basic.html#ga2170996d7e636397b5e6bc0c1b7df7c6">yaml_encoding_t</a>&nbsp;&nbsp;&nbsp;<a class="el" href="structyaml__event__s.html#a92139ba6ae79089fd9a2f5f4aeaf733f">encoding</a></td></tr>
+<tr><td class="mdescLeft">&nbsp;</td><td class="mdescRight">The document encoding. <a href="#abec210d9c046bfcd96980f6687f64aab"></a><br/></td></tr>
+<tr><td class="memItemLeft" valign="top">&nbsp;&nbsp;&nbsp;}&nbsp;&nbsp;&nbsp;<a class="el" href="structyaml__event__s.html#a18946df9b7c815dd7fb30103c02a9e24">stream_start</a></td></tr>
+<tr><td class="mdescLeft">&nbsp;</td><td class="mdescRight">The stream parameters (for <code>YAML_STREAM_START_EVENT</code>). <a href="#a8e65a6205bf09dad3155a12fccf0e022"></a><br/></td></tr>
+<tr><td class="memItemLeft" >&nbsp;&nbsp;&nbsp;struct {</td></tr>
+<tr><td class="memItemLeft" >&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<a class="el" href="structyaml__version__directive__s.html">yaml_version_directive_t</a> *&nbsp;&nbsp;&nbsp;<a class="el" href="structyaml__event__s.html#a5cef7981358ecefdf9d4780b3eacd39b">version_directive</a></td></tr>
+<tr><td class="mdescLeft">&nbsp;</td><td class="mdescRight">The version directive. <a href="#a9eb5bf4c9c577231fe7a882ed6339ef5"></a><br/></td></tr>
+<tr><td class="memItemLeft" >&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;struct {</td></tr>
+<tr><td class="memItemLeft" >&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<a class="el" href="structyaml__tag__directive__s.html">yaml_tag_directive_t</a> *&nbsp;&nbsp;&nbsp;<a class="el" href="structyaml__event__s.html#a74d7f521a559305585009ab503bee16b">start</a></td></tr>
+<tr><td class="mdescLeft">&nbsp;</td><td class="mdescRight">The beginning of the tag directives list. <a href="#ac82187258ad2d770c657daa327f85d9b"></a><br/></td></tr>
+<tr><td class="memItemLeft" >&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<a class="el" href="structyaml__tag__directive__s.html">yaml_tag_directive_t</a> *&nbsp;&nbsp;&nbsp;<a class="el" href="structyaml__event__s.html#a115b4a9797f3a72cd78d42c85100317c">end</a></td></tr>
+<tr><td class="mdescLeft">&nbsp;</td><td class="mdescRight">The end of the tag directives list. <a href="#a15345ef7fb8509c0cd062ed5d2be44e7"></a><br/></td></tr>
+<tr><td class="memItemLeft" valign="top">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;&nbsp;&nbsp;<a class="el" href="structyaml__event__s.html#a162ce89a77e706d68649d40e1a520e1f">tag_directives</a></td></tr>
+<tr><td class="mdescLeft">&nbsp;</td><td class="mdescRight">The list of tag directives. <a href="#a2c17df45272556145a2252bf82759d3d"></a><br/></td></tr>
+<tr><td class="memItemLeft" >&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;int&nbsp;&nbsp;&nbsp;<a class="el" href="structyaml__event__s.html#a3cbb10e276d55890ee2fa802dd6290e1">implicit</a></td></tr>
+<tr><td class="mdescLeft">&nbsp;</td><td class="mdescRight">Is the document indicator implicit? <br/></td></tr>
+<tr><td class="memItemLeft" valign="top">&nbsp;&nbsp;&nbsp;}&nbsp;&nbsp;&nbsp;<a class="el" href="structyaml__event__s.html#aed593fadbeb898d6d90b0c62522a82cc">document_start</a></td></tr>
+<tr><td class="mdescLeft">&nbsp;</td><td class="mdescRight">The document parameters (for <code>YAML_DOCUMENT_START_EVENT</code>). <a href="#a407fd0a986a3180bc0e0d302a775e1ea"></a><br/></td></tr>
+<tr><td class="memItemLeft" >&nbsp;&nbsp;&nbsp;struct {</td></tr>
+<tr><td class="memItemLeft" >&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;int&nbsp;&nbsp;&nbsp;<a class="el" href="structyaml__event__s.html#a3cbb10e276d55890ee2fa802dd6290e1">implicit</a></td></tr>
+<tr><td class="mdescLeft">&nbsp;</td><td class="mdescRight">Is the document end indicator implicit? <br/></td></tr>
+<tr><td class="memItemLeft" valign="top">&nbsp;&nbsp;&nbsp;}&nbsp;&nbsp;&nbsp;<a class="el" href="structyaml__event__s.html#acffec5f24c01bb6bfb0c93a9bf1a803e">document_end</a></td></tr>
+<tr><td class="mdescLeft">&nbsp;</td><td class="mdescRight">The document end parameters (for <code>YAML_DOCUMENT_END_EVENT</code>). <a href="#a2b7b07388ae344569ec05cf241d181ec"></a><br/></td></tr>
+<tr><td class="memItemLeft" >&nbsp;&nbsp;&nbsp;struct {</td></tr>
+<tr><td class="memItemLeft" >&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<a class="el" href="group__basic.html#gaf8657e81f0b8b05d1a081001fc6cb8bd">yaml_char_t</a> *&nbsp;&nbsp;&nbsp;<a class="el" href="structyaml__event__s.html#aaa97ab683d28e5f611042d0fbd929125">anchor</a></td></tr>
+<tr><td class="mdescLeft">&nbsp;</td><td class="mdescRight">The anchor. <a href="#a3c02ccdc16b200d0fd43fbb3780450b2"></a><br/></td></tr>
+<tr><td class="memItemLeft" valign="top">&nbsp;&nbsp;&nbsp;}&nbsp;&nbsp;&nbsp;<a class="el" href="structyaml__event__s.html#ac21f0f1e12207b8fd4f02496259f6c0b">alias</a></td></tr>
+<tr><td class="mdescLeft">&nbsp;</td><td class="mdescRight">The alias parameters (for <code>YAML_ALIAS_EVENT</code>). <a href="#abb691f82be4ecbdd7b9dd9f6835042ae"></a><br/></td></tr>
+<tr><td class="memItemLeft" >&nbsp;&nbsp;&nbsp;struct {</td></tr>
+<tr><td class="memItemLeft" >&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<a class="el" href="group__basic.html#gaf8657e81f0b8b05d1a081001fc6cb8bd">yaml_char_t</a> *&nbsp;&nbsp;&nbsp;<a class="el" href="structyaml__event__s.html#aaa97ab683d28e5f611042d0fbd929125">anchor</a></td></tr>
+<tr><td class="mdescLeft">&nbsp;</td><td class="mdescRight">The anchor. <a href="#ab34bebc8eee036545d0c1823c4acf9ec"></a><br/></td></tr>
+<tr><td class="memItemLeft" >&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<a class="el" href="group__basic.html#gaf8657e81f0b8b05d1a081001fc6cb8bd">yaml_char_t</a> *&nbsp;&nbsp;&nbsp;<a class="el" href="structyaml__event__s.html#a4daf9ed2683d79f2be7e89ca7d06801c">tag</a></td></tr>
+<tr><td class="mdescLeft">&nbsp;</td><td class="mdescRight">The tag. <a href="#a913fa35ea765b8879c4d53addb132999"></a><br/></td></tr>
+<tr><td class="memItemLeft" >&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<a class="el" href="group__basic.html#gaf8657e81f0b8b05d1a081001fc6cb8bd">yaml_char_t</a> *&nbsp;&nbsp;&nbsp;<a class="el" href="structyaml__event__s.html#a23436bdddb447d0fc217bab5c5b04a36">value</a></td></tr>
+<tr><td class="mdescLeft">&nbsp;</td><td class="mdescRight">The scalar value. <a href="#a17c9d9624b3ddd4de23ae546d918845b"></a><br/></td></tr>
+<tr><td class="memItemLeft" >&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;size_t&nbsp;&nbsp;&nbsp;<a class="el" href="structyaml__event__s.html#a15618ee917746d28d97ad8eb9639e141">length</a></td></tr>
+<tr><td class="mdescLeft">&nbsp;</td><td class="mdescRight">The length of the scalar value. <a href="#a7248ad38a1e64cdc43a340436c8eac57"></a><br/></td></tr>
+<tr><td class="memItemLeft" >&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;int&nbsp;&nbsp;&nbsp;<a class="el" href="structyaml__event__s.html#ac3600acbcc6b4787f1ec3511976a3151">plain_implicit</a></td></tr>
+<tr><td class="mdescLeft">&nbsp;</td><td class="mdescRight">Is the tag optional for the plain style? <br/></td></tr>
+<tr><td class="memItemLeft" >&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;int&nbsp;&nbsp;&nbsp;<a class="el" href="structyaml__event__s.html#a9ce2441d08d9cf6a1bf9f28f5ee17f68">quoted_implicit</a></td></tr>
+<tr><td class="mdescLeft">&nbsp;</td><td class="mdescRight">Is the tag optional for any non-plain style? <br/></td></tr>
+<tr><td class="memItemLeft" >&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<a class="el" href="group__styles.html#ga3fa6405631e1afe5bd5c488a6c5e8065">yaml_scalar_style_t</a>&nbsp;&nbsp;&nbsp;<a class="el" href="structyaml__event__s.html#ab107f895698f70560a5c344fc60ff498">style</a></td></tr>
+<tr><td class="mdescLeft">&nbsp;</td><td class="mdescRight">The scalar style. <a href="#aa5120877f103458dafeb2b3401db48a7"></a><br/></td></tr>
+<tr><td class="memItemLeft" valign="top">&nbsp;&nbsp;&nbsp;}&nbsp;&nbsp;&nbsp;<a class="el" href="structyaml__event__s.html#a3753b4c5d10040d75f7c7f4b56c42549">scalar</a></td></tr>
+<tr><td class="mdescLeft">&nbsp;</td><td class="mdescRight">The scalar parameters (for <code>YAML_SCALAR_EVENT</code>). <a href="#a0a7341bdebeafdef53c194c58c5e7c6a"></a><br/></td></tr>
+<tr><td class="memItemLeft" >&nbsp;&nbsp;&nbsp;struct {</td></tr>
+<tr><td class="memItemLeft" >&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<a class="el" href="group__basic.html#gaf8657e81f0b8b05d1a081001fc6cb8bd">yaml_char_t</a> *&nbsp;&nbsp;&nbsp;<a class="el" href="structyaml__event__s.html#aaa97ab683d28e5f611042d0fbd929125">anchor</a></td></tr>
+<tr><td class="mdescLeft">&nbsp;</td><td class="mdescRight">The anchor. <a href="#a71f42bf1df3bce8d507b86053d89c358"></a><br/></td></tr>
+<tr><td class="memItemLeft" >&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<a class="el" href="group__basic.html#gaf8657e81f0b8b05d1a081001fc6cb8bd">yaml_char_t</a> *&nbsp;&nbsp;&nbsp;<a class="el" href="structyaml__event__s.html#a4daf9ed2683d79f2be7e89ca7d06801c">tag</a></td></tr>
+<tr><td class="mdescLeft">&nbsp;</td><td class="mdescRight">The tag. <a href="#ac72857c4595b7d09e347ad11501a6ec9"></a><br/></td></tr>
+<tr><td class="memItemLeft" >&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;int&nbsp;&nbsp;&nbsp;<a class="el" href="structyaml__event__s.html#a3cbb10e276d55890ee2fa802dd6290e1">implicit</a></td></tr>
+<tr><td class="mdescLeft">&nbsp;</td><td class="mdescRight">Is the tag optional? <br/></td></tr>
+<tr><td class="memItemLeft" >&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<a class="el" href="group__styles.html#ga58a1123d271e56c72de6abf852ac4dc2">yaml_sequence_style_t</a>&nbsp;&nbsp;&nbsp;<a class="el" href="structyaml__event__s.html#a2ac1305583a8e7e2247738116bca6b3b">style</a></td></tr>
+<tr><td class="mdescLeft">&nbsp;</td><td class="mdescRight">The sequence style. <a href="#a3f09e9a5cf28b12a08f5153930bb0b28"></a><br/></td></tr>
+<tr><td class="memItemLeft" valign="top">&nbsp;&nbsp;&nbsp;}&nbsp;&nbsp;&nbsp;<a class="el" href="structyaml__event__s.html#a632895e022fbf29ab24a816893a8580f">sequence_start</a></td></tr>
+<tr><td class="mdescLeft">&nbsp;</td><td class="mdescRight">The sequence parameters (for <code>YAML_SEQUENCE_START_EVENT</code>). <a href="#a156b5563dccc610642741d483c2f7f55"></a><br/></td></tr>
+<tr><td class="memItemLeft" >&nbsp;&nbsp;&nbsp;struct {</td></tr>
+<tr><td class="memItemLeft" >&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<a class="el" href="group__basic.html#gaf8657e81f0b8b05d1a081001fc6cb8bd">yaml_char_t</a> *&nbsp;&nbsp;&nbsp;<a class="el" href="structyaml__event__s.html#aaa97ab683d28e5f611042d0fbd929125">anchor</a></td></tr>
+<tr><td class="mdescLeft">&nbsp;</td><td class="mdescRight">The anchor. <a href="#a14cdf779ff4c2efd724a7542ddedb998"></a><br/></td></tr>
+<tr><td class="memItemLeft" >&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<a class="el" href="group__basic.html#gaf8657e81f0b8b05d1a081001fc6cb8bd">yaml_char_t</a> *&nbsp;&nbsp;&nbsp;<a class="el" href="structyaml__event__s.html#a4daf9ed2683d79f2be7e89ca7d06801c">tag</a></td></tr>
+<tr><td class="mdescLeft">&nbsp;</td><td class="mdescRight">The tag. <a href="#a27c16c57f4792cc812ffbe8734d29b49"></a><br/></td></tr>
+<tr><td class="memItemLeft" >&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;int&nbsp;&nbsp;&nbsp;<a class="el" href="structyaml__event__s.html#a3cbb10e276d55890ee2fa802dd6290e1">implicit</a></td></tr>
+<tr><td class="mdescLeft">&nbsp;</td><td class="mdescRight">Is the tag optional? <br/></td></tr>
+<tr><td class="memItemLeft" >&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<a class="el" href="group__styles.html#gab47523846a5c5960e07367a28ea9750a">yaml_mapping_style_t</a>&nbsp;&nbsp;&nbsp;<a class="el" href="structyaml__event__s.html#a682a60e9a72e100357a38dd6434ad4f9">style</a></td></tr>
+<tr><td class="mdescLeft">&nbsp;</td><td class="mdescRight">The mapping style. <a href="#abb3d2e89121c1467f0a1c9997e78c451"></a><br/></td></tr>
+<tr><td class="memItemLeft" valign="top">&nbsp;&nbsp;&nbsp;}&nbsp;&nbsp;&nbsp;<a class="el" href="structyaml__event__s.html#a361b28413783f92797e6bfe03e9abaa1">mapping_start</a></td></tr>
+<tr><td class="mdescLeft">&nbsp;</td><td class="mdescRight">The mapping parameters (for <code>YAML_MAPPING_START_EVENT</code>). <a href="#aba2083c0a410a41e7246b49abe9c0a1c"></a><br/></td></tr>
+<tr><td class="memItemLeft" valign="top">}&nbsp;</td><td class="memItemRight" valign="bottom"><a class="el" href="structyaml__event__s.html#a0b8f9cce08e49459e4bab89035dbf6c6">data</a></td></tr>
+<tr><td class="mdescLeft">&nbsp;</td><td class="mdescRight">The event data. <a href="#a0b8f9cce08e49459e4bab89035dbf6c6"></a><br/></td></tr>
+<tr><td class="memItemLeft" align="right" valign="top"><a class="el" href="structyaml__mark__s.html">yaml_mark_t</a>&nbsp;</td><td class="memItemRight" valign="bottom"><a class="el" href="structyaml__event__s.html#aeaf86eb588e75232e1b73e8213eb3e31">start_mark</a></td></tr>
+<tr><td class="mdescLeft">&nbsp;</td><td class="mdescRight">The beginning of the event. <a href="#aeaf86eb588e75232e1b73e8213eb3e31"></a><br/></td></tr>
+<tr><td class="memItemLeft" align="right" valign="top"><a class="el" href="structyaml__mark__s.html">yaml_mark_t</a>&nbsp;</td><td class="memItemRight" valign="bottom"><a class="el" href="structyaml__event__s.html#a9307f91473094c229738b03d223bc4ba">end_mark</a></td></tr>
+<tr><td class="mdescLeft">&nbsp;</td><td class="mdescRight">The end of the event. <a href="#a9307f91473094c229738b03d223bc4ba"></a><br/></td></tr>
+</table>
+<hr/><a name="_details"></a><h2>Detailed Description</h2>
+<p>The event structure. </p>
+<hr/><h2>Field Documentation</h2>
+<a class="anchor" id="aff08bc3df4859d5b3a804e8c011cac51"></a><!-- doxytag: member="yaml_event_s::type" ref="aff08bc3df4859d5b3a804e8c011cac51" args="" -->
+<div class="memitem">
+<div class="memproto">
+ <table class="memname">
+ <tr>
+ <td class="memname"><a class="el" href="group__events.html#ga8934661be36bd7c9d17a8af69eff89a1">yaml_event_type_t</a> <a class="el" href="structyaml__event__s.html#aff08bc3df4859d5b3a804e8c011cac51">yaml_event_s::type</a></td>
+ </tr>
+ </table>
+</div>
+<div class="memdoc">
+
+<p>The event type. </p>
+
+</div>
+</div>
+<a class="anchor" id="a92139ba6ae79089fd9a2f5f4aeaf733f"></a><!-- doxytag: member="yaml_event_s::encoding" ref="a92139ba6ae79089fd9a2f5f4aeaf733f" args="" -->
+<div class="memitem">
+<div class="memproto">
+ <table class="memname">
+ <tr>
+ <td class="memname"><a class="el" href="group__basic.html#ga2170996d7e636397b5e6bc0c1b7df7c6">yaml_encoding_t</a> <a class="el" href="structyaml__event__s.html#a92139ba6ae79089fd9a2f5f4aeaf733f">yaml_event_s::encoding</a></td>
+ </tr>
+ </table>
+</div>
+<div class="memdoc">
+
+<p>The document encoding. </p>
+
+</div>
+</div>
+<a class="anchor" id="a18946df9b7c815dd7fb30103c02a9e24"></a><!-- doxytag: member="yaml_event_s::stream_start" ref="a18946df9b7c815dd7fb30103c02a9e24" args="" -->
+<div class="memitem">
+<div class="memproto">
+ <table class="memname">
+ <tr>
+ <td class="memname">struct { ... } <a class="el" href="structyaml__event__s.html#a18946df9b7c815dd7fb30103c02a9e24">yaml_event_s::stream_start</a></td>
+ </tr>
+ </table>
+</div>
+<div class="memdoc">
+
+<p>The stream parameters (for <code>YAML_STREAM_START_EVENT</code>). </p>
+
+</div>
+</div>
+<a class="anchor" id="a5cef7981358ecefdf9d4780b3eacd39b"></a><!-- doxytag: member="yaml_event_s::version_directive" ref="a5cef7981358ecefdf9d4780b3eacd39b" args="" -->
+<div class="memitem">
+<div class="memproto">
+ <table class="memname">
+ <tr>
+ <td class="memname"><a class="el" href="structyaml__version__directive__s.html">yaml_version_directive_t</a>* <a class="el" href="structyaml__event__s.html#a5cef7981358ecefdf9d4780b3eacd39b">yaml_event_s::version_directive</a></td>
+ </tr>
+ </table>
+</div>
+<div class="memdoc">
+
+<p>The version directive. </p>
+
+</div>
+</div>
+<a class="anchor" id="a74d7f521a559305585009ab503bee16b"></a><!-- doxytag: member="yaml_event_s::start" ref="a74d7f521a559305585009ab503bee16b" args="" -->
+<div class="memitem">
+<div class="memproto">
+ <table class="memname">
+ <tr>
+ <td class="memname"><a class="el" href="structyaml__tag__directive__s.html">yaml_tag_directive_t</a>* <a class="el" href="structyaml__event__s.html#a74d7f521a559305585009ab503bee16b">yaml_event_s::start</a></td>
+ </tr>
+ </table>
+</div>
+<div class="memdoc">
+
+<p>The beginning of the tag directives list. </p>
+
+</div>
+</div>
+<a class="anchor" id="a115b4a9797f3a72cd78d42c85100317c"></a><!-- doxytag: member="yaml_event_s::end" ref="a115b4a9797f3a72cd78d42c85100317c" args="" -->
+<div class="memitem">
+<div class="memproto">
+ <table class="memname">
+ <tr>
+ <td class="memname"><a class="el" href="structyaml__tag__directive__s.html">yaml_tag_directive_t</a>* <a class="el" href="structyaml__event__s.html#a115b4a9797f3a72cd78d42c85100317c">yaml_event_s::end</a></td>
+ </tr>
+ </table>
+</div>
+<div class="memdoc">
+
+<p>The end of the tag directives list. </p>
+
+</div>
+</div>
+<a class="anchor" id="a162ce89a77e706d68649d40e1a520e1f"></a><!-- doxytag: member="yaml_event_s::tag_directives" ref="a162ce89a77e706d68649d40e1a520e1f" args="" -->
+<div class="memitem">
+<div class="memproto">
+ <table class="memname">
+ <tr>
+ <td class="memname">struct { ... } ::@16 <a class="el" href="structyaml__event__s.html#a162ce89a77e706d68649d40e1a520e1f">yaml_event_s::tag_directives</a></td>
+ </tr>
+ </table>
+</div>
+<div class="memdoc">
+
+<p>The list of tag directives. </p>
+
+</div>
+</div>
+<a class="anchor" id="a3cbb10e276d55890ee2fa802dd6290e1"></a><!-- doxytag: member="yaml_event_s::implicit" ref="a3cbb10e276d55890ee2fa802dd6290e1" args="" -->
+<div class="memitem">
+<div class="memproto">
+ <table class="memname">
+ <tr>
+ <td class="memname">int <a class="el" href="structyaml__event__s.html#a3cbb10e276d55890ee2fa802dd6290e1">yaml_event_s::implicit</a></td>
+ </tr>
+ </table>
+</div>
+<div class="memdoc">
+
+<p>Is the document indicator implicit? </p>
+<p>Is the tag optional?</p>
+<p>Is the document end indicator implicit? </p>
+
+</div>
+</div>
+<a class="anchor" id="aed593fadbeb898d6d90b0c62522a82cc"></a><!-- doxytag: member="yaml_event_s::document_start" ref="aed593fadbeb898d6d90b0c62522a82cc" args="" -->
+<div class="memitem">
+<div class="memproto">
+ <table class="memname">
+ <tr>
+ <td class="memname">struct { ... } <a class="el" href="structyaml__event__s.html#aed593fadbeb898d6d90b0c62522a82cc">yaml_event_s::document_start</a></td>
+ </tr>
+ </table>
+</div>
+<div class="memdoc">
+
+<p>The document parameters (for <code>YAML_DOCUMENT_START_EVENT</code>). </p>
+
+</div>
+</div>
+<a class="anchor" id="acffec5f24c01bb6bfb0c93a9bf1a803e"></a><!-- doxytag: member="yaml_event_s::document_end" ref="acffec5f24c01bb6bfb0c93a9bf1a803e" args="" -->
+<div class="memitem">
+<div class="memproto">
+ <table class="memname">
+ <tr>
+ <td class="memname">struct { ... } <a class="el" href="structyaml__event__s.html#acffec5f24c01bb6bfb0c93a9bf1a803e">yaml_event_s::document_end</a></td>
+ </tr>
+ </table>
+</div>
+<div class="memdoc">
+
+<p>The document end parameters (for <code>YAML_DOCUMENT_END_EVENT</code>). </p>
+
+</div>
+</div>
+<a class="anchor" id="aaa97ab683d28e5f611042d0fbd929125"></a><!-- doxytag: member="yaml_event_s::anchor" ref="aaa97ab683d28e5f611042d0fbd929125" args="" -->
+<div class="memitem">
+<div class="memproto">
+ <table class="memname">
+ <tr>
+ <td class="memname"><a class="el" href="group__basic.html#gaf8657e81f0b8b05d1a081001fc6cb8bd">yaml_char_t</a>* <a class="el" href="structyaml__event__s.html#aaa97ab683d28e5f611042d0fbd929125">yaml_event_s::anchor</a></td>
+ </tr>
+ </table>
+</div>
+<div class="memdoc">
+
+<p>The anchor. </p>
+
+</div>
+</div>
+<a class="anchor" id="ac21f0f1e12207b8fd4f02496259f6c0b"></a><!-- doxytag: member="yaml_event_s::alias" ref="ac21f0f1e12207b8fd4f02496259f6c0b" args="" -->
+<div class="memitem">
+<div class="memproto">
+ <table class="memname">
+ <tr>
+ <td class="memname">struct { ... } <a class="el" href="structyaml__event__s.html#ac21f0f1e12207b8fd4f02496259f6c0b">yaml_event_s::alias</a></td>
+ </tr>
+ </table>
+</div>
+<div class="memdoc">
+
+<p>The alias parameters (for <code>YAML_ALIAS_EVENT</code>). </p>
+
+</div>
+</div>
+<a class="anchor" id="a4daf9ed2683d79f2be7e89ca7d06801c"></a><!-- doxytag: member="yaml_event_s::tag" ref="a4daf9ed2683d79f2be7e89ca7d06801c" args="" -->
+<div class="memitem">
+<div class="memproto">
+ <table class="memname">
+ <tr>
+ <td class="memname"><a class="el" href="group__basic.html#gaf8657e81f0b8b05d1a081001fc6cb8bd">yaml_char_t</a>* <a class="el" href="structyaml__event__s.html#a4daf9ed2683d79f2be7e89ca7d06801c">yaml_event_s::tag</a></td>
+ </tr>
+ </table>
+</div>
+<div class="memdoc">
+
+<p>The tag. </p>
+
+</div>
+</div>
+<a class="anchor" id="a23436bdddb447d0fc217bab5c5b04a36"></a><!-- doxytag: member="yaml_event_s::value" ref="a23436bdddb447d0fc217bab5c5b04a36" args="" -->
+<div class="memitem">
+<div class="memproto">
+ <table class="memname">
+ <tr>
+ <td class="memname"><a class="el" href="group__basic.html#gaf8657e81f0b8b05d1a081001fc6cb8bd">yaml_char_t</a>* <a class="el" href="structyaml__event__s.html#a23436bdddb447d0fc217bab5c5b04a36">yaml_event_s::value</a></td>
+ </tr>
+ </table>
+</div>
+<div class="memdoc">
+
+<p>The scalar value. </p>
+
+</div>
+</div>
+<a class="anchor" id="a15618ee917746d28d97ad8eb9639e141"></a><!-- doxytag: member="yaml_event_s::length" ref="a15618ee917746d28d97ad8eb9639e141" args="" -->
+<div class="memitem">
+<div class="memproto">
+ <table class="memname">
+ <tr>
+ <td class="memname">size_t <a class="el" href="structyaml__event__s.html#a15618ee917746d28d97ad8eb9639e141">yaml_event_s::length</a></td>
+ </tr>
+ </table>
+</div>
+<div class="memdoc">
+
+<p>The length of the scalar value. </p>
+
+</div>
+</div>
+<a class="anchor" id="ab107f895698f70560a5c344fc60ff498"></a><!-- doxytag: member="yaml_event_s::style" ref="ab107f895698f70560a5c344fc60ff498" args="" -->
+<div class="memitem">
+<div class="memproto">
+ <table class="memname">
+ <tr>
+ <td class="memname"><a class="el" href="group__styles.html#ga3fa6405631e1afe5bd5c488a6c5e8065">yaml_scalar_style_t</a> <a class="el" href="structyaml__event__s.html#ab107f895698f70560a5c344fc60ff498">yaml_event_s::style</a></td>
+ </tr>
+ </table>
+</div>
+<div class="memdoc">
+
+<p>The scalar style. </p>
+
+</div>
+</div>
+<a class="anchor" id="a3753b4c5d10040d75f7c7f4b56c42549"></a><!-- doxytag: member="yaml_event_s::scalar" ref="a3753b4c5d10040d75f7c7f4b56c42549" args="" -->
+<div class="memitem">
+<div class="memproto">
+ <table class="memname">
+ <tr>
+ <td class="memname">struct { ... } <a class="el" href="structyaml__event__s.html#a3753b4c5d10040d75f7c7f4b56c42549">yaml_event_s::scalar</a></td>
+ </tr>
+ </table>
+</div>
+<div class="memdoc">
+
+<p>The scalar parameters (for <code>YAML_SCALAR_EVENT</code>). </p>
+
+</div>
+</div>
+<a class="anchor" id="a2ac1305583a8e7e2247738116bca6b3b"></a><!-- doxytag: member="yaml_event_s::style" ref="a2ac1305583a8e7e2247738116bca6b3b" args="" -->
+<div class="memitem">
+<div class="memproto">
+ <table class="memname">
+ <tr>
+ <td class="memname"><a class="el" href="group__styles.html#ga58a1123d271e56c72de6abf852ac4dc2">yaml_sequence_style_t</a> <a class="el" href="structyaml__event__s.html#ab107f895698f70560a5c344fc60ff498">yaml_event_s::style</a></td>
+ </tr>
+ </table>
+</div>
+<div class="memdoc">
+
+<p>The sequence style. </p>
+
+</div>
+</div>
+<a class="anchor" id="a632895e022fbf29ab24a816893a8580f"></a><!-- doxytag: member="yaml_event_s::sequence_start" ref="a632895e022fbf29ab24a816893a8580f" args="" -->
+<div class="memitem">
+<div class="memproto">
+ <table class="memname">
+ <tr>
+ <td class="memname">struct { ... } <a class="el" href="structyaml__event__s.html#a632895e022fbf29ab24a816893a8580f">yaml_event_s::sequence_start</a></td>
+ </tr>
+ </table>
+</div>
+<div class="memdoc">
+
+<p>The sequence parameters (for <code>YAML_SEQUENCE_START_EVENT</code>). </p>
+
+</div>
+</div>
+<a class="anchor" id="a682a60e9a72e100357a38dd6434ad4f9"></a><!-- doxytag: member="yaml_event_s::style" ref="a682a60e9a72e100357a38dd6434ad4f9" args="" -->
+<div class="memitem">
+<div class="memproto">
+ <table class="memname">
+ <tr>
+ <td class="memname"><a class="el" href="group__styles.html#gab47523846a5c5960e07367a28ea9750a">yaml_mapping_style_t</a> <a class="el" href="structyaml__event__s.html#ab107f895698f70560a5c344fc60ff498">yaml_event_s::style</a></td>
+ </tr>
+ </table>
+</div>
+<div class="memdoc">
+
+<p>The mapping style. </p>
+
+</div>
+</div>
+<a class="anchor" id="a361b28413783f92797e6bfe03e9abaa1"></a><!-- doxytag: member="yaml_event_s::mapping_start" ref="a361b28413783f92797e6bfe03e9abaa1" args="" -->
+<div class="memitem">
+<div class="memproto">
+ <table class="memname">
+ <tr>
+ <td class="memname">struct { ... } <a class="el" href="structyaml__event__s.html#a361b28413783f92797e6bfe03e9abaa1">yaml_event_s::mapping_start</a></td>
+ </tr>
+ </table>
+</div>
+<div class="memdoc">
+
+<p>The mapping parameters (for <code>YAML_MAPPING_START_EVENT</code>). </p>
+
+</div>
+</div>
+<a class="anchor" id="a0b8f9cce08e49459e4bab89035dbf6c6"></a><!-- doxytag: member="yaml_event_s::data" ref="a0b8f9cce08e49459e4bab89035dbf6c6" args="" -->
+<div class="memitem">
+<div class="memproto">
+ <table class="memname">
+ <tr>
+ <td class="memname">union { ... } <a class="el" href="structyaml__event__s.html#a0b8f9cce08e49459e4bab89035dbf6c6">yaml_event_s::data</a></td>
+ </tr>
+ </table>
+</div>
+<div class="memdoc">
+
+<p>The event data. </p>
+
+</div>
+</div>
+<a class="anchor" id="aeaf86eb588e75232e1b73e8213eb3e31"></a><!-- doxytag: member="yaml_event_s::start_mark" ref="aeaf86eb588e75232e1b73e8213eb3e31" args="" -->
+<div class="memitem">
+<div class="memproto">
+ <table class="memname">
+ <tr>
+ <td class="memname"><a class="el" href="structyaml__mark__s.html">yaml_mark_t</a> <a class="el" href="structyaml__event__s.html#aeaf86eb588e75232e1b73e8213eb3e31">yaml_event_s::start_mark</a></td>
+ </tr>
+ </table>
+</div>
+<div class="memdoc">
+
+<p>The beginning of the event. </p>
+
+</div>
+</div>
+<a class="anchor" id="a9307f91473094c229738b03d223bc4ba"></a><!-- doxytag: member="yaml_event_s::end_mark" ref="a9307f91473094c229738b03d223bc4ba" args="" -->
+<div class="memitem">
+<div class="memproto">
+ <table class="memname">
+ <tr>
+ <td class="memname"><a class="el" href="structyaml__mark__s.html">yaml_mark_t</a> <a class="el" href="structyaml__event__s.html#a9307f91473094c229738b03d223bc4ba">yaml_event_s::end_mark</a></td>
+ </tr>
+ </table>
+</div>
+<div class="memdoc">
+
+<p>The end of the event. </p>
+
+</div>
+</div>
+<hr/>The documentation for this struct was generated from the following file:<ul>
+<li><a class="el" href="yaml_8h.html">yaml.h</a></li>
+</ul>
+</div>
+<hr class="footer"/><address class="footer"><small>Generated on Mon May 30 2011 22:00:00 for yaml by&nbsp;
+<a href="http://www.doxygen.org/index.html">
+<img class="footer" src="doxygen.png" alt="doxygen"/></a> 1.7.1 </small></address>
+</body>
+</html>
diff --git a/contrib/libyaml/doc/html/structyaml__mark__s.html b/contrib/libyaml/doc/html/structyaml__mark__s.html
new file mode 100644
index 0000000..e5f47ab
--- /dev/null
+++ b/contrib/libyaml/doc/html/structyaml__mark__s.html
@@ -0,0 +1,108 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head>
+<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/>
+<title>yaml: yaml_mark_s Struct Reference</title>
+<link href="tabs.css" rel="stylesheet" type="text/css"/>
+<link href="doxygen.css" rel="stylesheet" type="text/css"/>
+</head>
+<body>
+<!-- Generated by Doxygen 1.7.1 -->
+<div class="navigation" id="top">
+ <div class="tabs">
+ <ul class="tablist">
+ <li><a href="index.html"><span>Main&nbsp;Page</span></a></li>
+ <li><a href="modules.html"><span>Modules</span></a></li>
+ <li class="current"><a href="annotated.html"><span>Data&nbsp;Structures</span></a></li>
+ <li><a href="files.html"><span>Files</span></a></li>
+ </ul>
+ </div>
+ <div class="tabs2">
+ <ul class="tablist">
+ <li><a href="annotated.html"><span>Data&nbsp;Structures</span></a></li>
+ <li><a href="functions.html"><span>Data&nbsp;Fields</span></a></li>
+ </ul>
+ </div>
+</div>
+<div class="header">
+ <div class="summary">
+<a href="#pub-attribs">Data Fields</a> </div>
+ <div class="headertitle">
+<h1>yaml_mark_s Struct Reference<br/>
+<small>
+[<a class="el" href="group__basic.html">Basic Types</a>]</small>
+</h1> </div>
+</div>
+<div class="contents">
+<!-- doxytag: class="yaml_mark_s" -->
+<p>The pointer position.
+<a href="#_details">More...</a></p>
+
+<p><code>#include &lt;yaml.h&gt;</code></p>
+<table class="memberdecls">
+<tr><td colspan="2"><h2><a name="pub-attribs"></a>
+Data Fields</h2></td></tr>
+<tr><td class="memItemLeft" align="right" valign="top">size_t&nbsp;</td><td class="memItemRight" valign="bottom"><a class="el" href="structyaml__mark__s.html#a525306fb424a79f0b0d5a7d3990aa596">index</a></td></tr>
+<tr><td class="mdescLeft">&nbsp;</td><td class="mdescRight">The position index. <a href="#a525306fb424a79f0b0d5a7d3990aa596"></a><br/></td></tr>
+<tr><td class="memItemLeft" align="right" valign="top">size_t&nbsp;</td><td class="memItemRight" valign="bottom"><a class="el" href="structyaml__mark__s.html#a55952e426fc8a5f180a5e9c907ca926c">line</a></td></tr>
+<tr><td class="mdescLeft">&nbsp;</td><td class="mdescRight">The position line. <a href="#a55952e426fc8a5f180a5e9c907ca926c"></a><br/></td></tr>
+<tr><td class="memItemLeft" align="right" valign="top">size_t&nbsp;</td><td class="memItemRight" valign="bottom"><a class="el" href="structyaml__mark__s.html#aaa18357a6fb2bb377b969ce9ff589797">column</a></td></tr>
+<tr><td class="mdescLeft">&nbsp;</td><td class="mdescRight">The position column. <a href="#aaa18357a6fb2bb377b969ce9ff589797"></a><br/></td></tr>
+</table>
+<hr/><a name="_details"></a><h2>Detailed Description</h2>
+<p>The pointer position. </p>
+<hr/><h2>Field Documentation</h2>
+<a class="anchor" id="a525306fb424a79f0b0d5a7d3990aa596"></a><!-- doxytag: member="yaml_mark_s::index" ref="a525306fb424a79f0b0d5a7d3990aa596" args="" -->
+<div class="memitem">
+<div class="memproto">
+ <table class="memname">
+ <tr>
+ <td class="memname">size_t <a class="el" href="structyaml__mark__s.html#a525306fb424a79f0b0d5a7d3990aa596">yaml_mark_s::index</a></td>
+ </tr>
+ </table>
+</div>
+<div class="memdoc">
+
+<p>The position index. </p>
+
+</div>
+</div>
+<a class="anchor" id="a55952e426fc8a5f180a5e9c907ca926c"></a><!-- doxytag: member="yaml_mark_s::line" ref="a55952e426fc8a5f180a5e9c907ca926c" args="" -->
+<div class="memitem">
+<div class="memproto">
+ <table class="memname">
+ <tr>
+ <td class="memname">size_t <a class="el" href="structyaml__mark__s.html#a55952e426fc8a5f180a5e9c907ca926c">yaml_mark_s::line</a></td>
+ </tr>
+ </table>
+</div>
+<div class="memdoc">
+
+<p>The position line. </p>
+
+</div>
+</div>
+<a class="anchor" id="aaa18357a6fb2bb377b969ce9ff589797"></a><!-- doxytag: member="yaml_mark_s::column" ref="aaa18357a6fb2bb377b969ce9ff589797" args="" -->
+<div class="memitem">
+<div class="memproto">
+ <table class="memname">
+ <tr>
+ <td class="memname">size_t <a class="el" href="structyaml__mark__s.html#aaa18357a6fb2bb377b969ce9ff589797">yaml_mark_s::column</a></td>
+ </tr>
+ </table>
+</div>
+<div class="memdoc">
+
+<p>The position column. </p>
+
+</div>
+</div>
+<hr/>The documentation for this struct was generated from the following file:<ul>
+<li><a class="el" href="yaml_8h.html">yaml.h</a></li>
+</ul>
+</div>
+<hr class="footer"/><address class="footer"><small>Generated on Mon May 30 2011 22:00:00 for yaml by&nbsp;
+<a href="http://www.doxygen.org/index.html">
+<img class="footer" src="doxygen.png" alt="doxygen"/></a> 1.7.1 </small></address>
+</body>
+</html>
diff --git a/contrib/libyaml/doc/html/structyaml__node__pair__s.html b/contrib/libyaml/doc/html/structyaml__node__pair__s.html
new file mode 100644
index 0000000..3e00076
--- /dev/null
+++ b/contrib/libyaml/doc/html/structyaml__node__pair__s.html
@@ -0,0 +1,91 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head>
+<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/>
+<title>yaml: yaml_node_pair_s Struct Reference</title>
+<link href="tabs.css" rel="stylesheet" type="text/css"/>
+<link href="doxygen.css" rel="stylesheet" type="text/css"/>
+</head>
+<body>
+<!-- Generated by Doxygen 1.7.1 -->
+<div class="navigation" id="top">
+ <div class="tabs">
+ <ul class="tablist">
+ <li><a href="index.html"><span>Main&nbsp;Page</span></a></li>
+ <li><a href="modules.html"><span>Modules</span></a></li>
+ <li class="current"><a href="annotated.html"><span>Data&nbsp;Structures</span></a></li>
+ <li><a href="files.html"><span>Files</span></a></li>
+ </ul>
+ </div>
+ <div class="tabs2">
+ <ul class="tablist">
+ <li><a href="annotated.html"><span>Data&nbsp;Structures</span></a></li>
+ <li><a href="functions.html"><span>Data&nbsp;Fields</span></a></li>
+ </ul>
+ </div>
+</div>
+<div class="header">
+ <div class="summary">
+<a href="#pub-attribs">Data Fields</a> </div>
+ <div class="headertitle">
+<h1>yaml_node_pair_s Struct Reference<br/>
+<small>
+[<a class="el" href="group__nodes.html">Nodes</a>]</small>
+</h1> </div>
+</div>
+<div class="contents">
+<!-- doxytag: class="yaml_node_pair_s" -->
+<p>An element of a mapping node.
+<a href="#_details">More...</a></p>
+
+<p><code>#include &lt;yaml.h&gt;</code></p>
+<table class="memberdecls">
+<tr><td colspan="2"><h2><a name="pub-attribs"></a>
+Data Fields</h2></td></tr>
+<tr><td class="memItemLeft" align="right" valign="top">int&nbsp;</td><td class="memItemRight" valign="bottom"><a class="el" href="structyaml__node__pair__s.html#ac83746eb40b6b3a84f6da3143658ed4e">key</a></td></tr>
+<tr><td class="mdescLeft">&nbsp;</td><td class="mdescRight">The key of the element. <a href="#ac83746eb40b6b3a84f6da3143658ed4e"></a><br/></td></tr>
+<tr><td class="memItemLeft" align="right" valign="top">int&nbsp;</td><td class="memItemRight" valign="bottom"><a class="el" href="structyaml__node__pair__s.html#a56c1de2c11d509462d1bf03803bb8ab1">value</a></td></tr>
+<tr><td class="mdescLeft">&nbsp;</td><td class="mdescRight">The value of the element. <a href="#a56c1de2c11d509462d1bf03803bb8ab1"></a><br/></td></tr>
+</table>
+<hr/><a name="_details"></a><h2>Detailed Description</h2>
+<p>An element of a mapping node. </p>
+<hr/><h2>Field Documentation</h2>
+<a class="anchor" id="ac83746eb40b6b3a84f6da3143658ed4e"></a><!-- doxytag: member="yaml_node_pair_s::key" ref="ac83746eb40b6b3a84f6da3143658ed4e" args="" -->
+<div class="memitem">
+<div class="memproto">
+ <table class="memname">
+ <tr>
+ <td class="memname">int <a class="el" href="structyaml__node__pair__s.html#ac83746eb40b6b3a84f6da3143658ed4e">yaml_node_pair_s::key</a></td>
+ </tr>
+ </table>
+</div>
+<div class="memdoc">
+
+<p>The key of the element. </p>
+
+</div>
+</div>
+<a class="anchor" id="a56c1de2c11d509462d1bf03803bb8ab1"></a><!-- doxytag: member="yaml_node_pair_s::value" ref="a56c1de2c11d509462d1bf03803bb8ab1" args="" -->
+<div class="memitem">
+<div class="memproto">
+ <table class="memname">
+ <tr>
+ <td class="memname">int <a class="el" href="structyaml__node__pair__s.html#a56c1de2c11d509462d1bf03803bb8ab1">yaml_node_pair_s::value</a></td>
+ </tr>
+ </table>
+</div>
+<div class="memdoc">
+
+<p>The value of the element. </p>
+
+</div>
+</div>
+<hr/>The documentation for this struct was generated from the following file:<ul>
+<li><a class="el" href="yaml_8h.html">yaml.h</a></li>
+</ul>
+</div>
+<hr class="footer"/><address class="footer"><small>Generated on Mon May 30 2011 22:00:00 for yaml by&nbsp;
+<a href="http://www.doxygen.org/index.html">
+<img class="footer" src="doxygen.png" alt="doxygen"/></a> 1.7.1 </small></address>
+</body>
+</html>
diff --git a/contrib/libyaml/doc/html/structyaml__node__s.html b/contrib/libyaml/doc/html/structyaml__node__s.html
new file mode 100644
index 0000000..46029b7
--- /dev/null
+++ b/contrib/libyaml/doc/html/structyaml__node__s.html
@@ -0,0 +1,420 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head>
+<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/>
+<title>yaml: yaml_node_s Struct Reference</title>
+<link href="tabs.css" rel="stylesheet" type="text/css"/>
+<link href="doxygen.css" rel="stylesheet" type="text/css"/>
+</head>
+<body>
+<!-- Generated by Doxygen 1.7.1 -->
+<div class="navigation" id="top">
+ <div class="tabs">
+ <ul class="tablist">
+ <li><a href="index.html"><span>Main&nbsp;Page</span></a></li>
+ <li><a href="modules.html"><span>Modules</span></a></li>
+ <li class="current"><a href="annotated.html"><span>Data&nbsp;Structures</span></a></li>
+ <li><a href="files.html"><span>Files</span></a></li>
+ </ul>
+ </div>
+ <div class="tabs2">
+ <ul class="tablist">
+ <li><a href="annotated.html"><span>Data&nbsp;Structures</span></a></li>
+ <li><a href="functions.html"><span>Data&nbsp;Fields</span></a></li>
+ </ul>
+ </div>
+</div>
+<div class="header">
+ <div class="summary">
+<a href="#pub-attribs">Data Fields</a> </div>
+ <div class="headertitle">
+<h1>yaml_node_s Struct Reference<br/>
+<small>
+[<a class="el" href="group__nodes.html">Nodes</a>]</small>
+</h1> </div>
+</div>
+<div class="contents">
+<!-- doxytag: class="yaml_node_s" -->
+<p>The node structure.
+<a href="#_details">More...</a></p>
+
+<p><code>#include &lt;yaml.h&gt;</code></p>
+<table class="memberdecls">
+<tr><td colspan="2"><h2><a name="pub-attribs"></a>
+Data Fields</h2></td></tr>
+<tr><td class="memItemLeft" align="right" valign="top"><a class="el" href="group__nodes.html#gabe020d2fc42d3e896549e9f97da622d2">yaml_node_type_t</a>&nbsp;</td><td class="memItemRight" valign="bottom"><a class="el" href="structyaml__node__s.html#a1db4ea72e13be65ec42339ce47d19669">type</a></td></tr>
+<tr><td class="mdescLeft">&nbsp;</td><td class="mdescRight">The node type. <a href="#a1db4ea72e13be65ec42339ce47d19669"></a><br/></td></tr>
+<tr><td class="memItemLeft" align="right" valign="top"><a class="el" href="group__basic.html#gaf8657e81f0b8b05d1a081001fc6cb8bd">yaml_char_t</a> *&nbsp;</td><td class="memItemRight" valign="bottom"><a class="el" href="structyaml__node__s.html#aa753358ea6d9d221b7b188832d47fefa">tag</a></td></tr>
+<tr><td class="mdescLeft">&nbsp;</td><td class="mdescRight">The node tag. <a href="#aa753358ea6d9d221b7b188832d47fefa"></a><br/></td></tr>
+<tr><td class="memItemLeft" >union {</td></tr>
+<tr><td class="memItemLeft" >&nbsp;&nbsp;&nbsp;struct {</td></tr>
+<tr><td class="memItemLeft" >&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<a class="el" href="group__basic.html#gaf8657e81f0b8b05d1a081001fc6cb8bd">yaml_char_t</a> *&nbsp;&nbsp;&nbsp;<a class="el" href="structyaml__node__s.html#a0d444412a29609d62699267ae72f971d">value</a></td></tr>
+<tr><td class="mdescLeft">&nbsp;</td><td class="mdescRight">The scalar value. <a href="#a0ce51acf3b3e7e3798fd59db6048215a"></a><br/></td></tr>
+<tr><td class="memItemLeft" >&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;size_t&nbsp;&nbsp;&nbsp;<a class="el" href="structyaml__node__s.html#ad90dd9926d9debbaa48eb5339bd9fc36">length</a></td></tr>
+<tr><td class="mdescLeft">&nbsp;</td><td class="mdescRight">The length of the scalar value. <a href="#aebc3bbc2fe05ccf793cfd9d0697d7411"></a><br/></td></tr>
+<tr><td class="memItemLeft" >&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<a class="el" href="group__styles.html#ga3fa6405631e1afe5bd5c488a6c5e8065">yaml_scalar_style_t</a>&nbsp;&nbsp;&nbsp;<a class="el" href="structyaml__node__s.html#a362960375516e77a130c412ef10ef55d">style</a></td></tr>
+<tr><td class="mdescLeft">&nbsp;</td><td class="mdescRight">The scalar style. <a href="#aedd8f01db928d283efb35d07bd594118"></a><br/></td></tr>
+<tr><td class="memItemLeft" valign="top">&nbsp;&nbsp;&nbsp;}&nbsp;&nbsp;&nbsp;<a class="el" href="structyaml__node__s.html#a688583a2649848aed700d7e07d9efac9">scalar</a></td></tr>
+<tr><td class="mdescLeft">&nbsp;</td><td class="mdescRight">The scalar parameters (for <code>YAML_SCALAR_NODE</code>). <a href="#a20ef91ea5b107f7e160f6626ae94e757"></a><br/></td></tr>
+<tr><td class="memItemLeft" >&nbsp;&nbsp;&nbsp;struct {</td></tr>
+<tr><td class="memItemLeft" >&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;struct {</td></tr>
+<tr><td class="memItemLeft" >&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<a class="el" href="group__nodes.html#ga7cc3581582e778b00c04e99cd3656860">yaml_node_item_t</a> *&nbsp;&nbsp;&nbsp;<a class="el" href="structyaml__node__s.html#a2e1001a0a7b068d4b2543a93d4cf60d4">start</a></td></tr>
+<tr><td class="mdescLeft">&nbsp;</td><td class="mdescRight">The beginning of the stack. <a href="#adff33843f3a55f50dab6319a3622112e"></a><br/></td></tr>
+<tr><td class="memItemLeft" >&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<a class="el" href="group__nodes.html#ga7cc3581582e778b00c04e99cd3656860">yaml_node_item_t</a> *&nbsp;&nbsp;&nbsp;<a class="el" href="structyaml__node__s.html#ac9b3d891f9fcd5462289823716deca0e">end</a></td></tr>
+<tr><td class="mdescLeft">&nbsp;</td><td class="mdescRight">The end of the stack. <a href="#aadabab91314f9a90437abd04f6ff07cb"></a><br/></td></tr>
+<tr><td class="memItemLeft" >&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<a class="el" href="group__nodes.html#ga7cc3581582e778b00c04e99cd3656860">yaml_node_item_t</a> *&nbsp;&nbsp;&nbsp;<a class="el" href="structyaml__node__s.html#a510326726569a06a11119f12649787cf">top</a></td></tr>
+<tr><td class="mdescLeft">&nbsp;</td><td class="mdescRight">The top of the stack. <a href="#a87ff5c5f9cfa26fb410a2fdfef4af6e6"></a><br/></td></tr>
+<tr><td class="memItemLeft" valign="top">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;&nbsp;&nbsp;<a class="el" href="structyaml__node__s.html#a6b340541cc012ac5aacdcaa46ced097a">items</a></td></tr>
+<tr><td class="mdescLeft">&nbsp;</td><td class="mdescRight">The stack of sequence items. <a href="#a20d9072496e270ec80741ae436cfc78c"></a><br/></td></tr>
+<tr><td class="memItemLeft" >&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<a class="el" href="group__styles.html#ga58a1123d271e56c72de6abf852ac4dc2">yaml_sequence_style_t</a>&nbsp;&nbsp;&nbsp;<a class="el" href="structyaml__node__s.html#a242be04ec3709138264175e3e5b50dbe">style</a></td></tr>
+<tr><td class="mdescLeft">&nbsp;</td><td class="mdescRight">The sequence style. <a href="#aef5300a10030a153ce20e58bc2e1c886"></a><br/></td></tr>
+<tr><td class="memItemLeft" valign="top">&nbsp;&nbsp;&nbsp;}&nbsp;&nbsp;&nbsp;<a class="el" href="structyaml__node__s.html#afe215962139fac93b965cc2acd71452b">sequence</a></td></tr>
+<tr><td class="mdescLeft">&nbsp;</td><td class="mdescRight">The sequence parameters (for <code>YAML_SEQUENCE_NODE</code>). <a href="#ab302f3c85f1b7f6896a7571479e0d748"></a><br/></td></tr>
+<tr><td class="memItemLeft" >&nbsp;&nbsp;&nbsp;struct {</td></tr>
+<tr><td class="memItemLeft" >&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;struct {</td></tr>
+<tr><td class="memItemLeft" >&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<a class="el" href="structyaml__node__pair__s.html">yaml_node_pair_t</a> *&nbsp;&nbsp;&nbsp;<a class="el" href="structyaml__node__s.html#a82afddfe1cf7f1a346d931ad4896d3de">start</a></td></tr>
+<tr><td class="mdescLeft">&nbsp;</td><td class="mdescRight">The beginning of the stack. <a href="#ae3264b106666197e1c01601a5b8c5f69"></a><br/></td></tr>
+<tr><td class="memItemLeft" >&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<a class="el" href="structyaml__node__pair__s.html">yaml_node_pair_t</a> *&nbsp;&nbsp;&nbsp;<a class="el" href="structyaml__node__s.html#a1827ba7f3e7f7e94171fa20ade25345d">end</a></td></tr>
+<tr><td class="mdescLeft">&nbsp;</td><td class="mdescRight">The end of the stack. <a href="#ad4193067b681fb09b4e0ce5d7be32824"></a><br/></td></tr>
+<tr><td class="memItemLeft" >&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<a class="el" href="structyaml__node__pair__s.html">yaml_node_pair_t</a> *&nbsp;&nbsp;&nbsp;<a class="el" href="structyaml__node__s.html#aa420f88720907fe02b1d1595c9351d59">top</a></td></tr>
+<tr><td class="mdescLeft">&nbsp;</td><td class="mdescRight">The top of the stack. <a href="#a3b512e63e6089f84064e4938d79d232e"></a><br/></td></tr>
+<tr><td class="memItemLeft" valign="top">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;&nbsp;&nbsp;<a class="el" href="structyaml__node__s.html#a830a080bbed021eb230ef644e4680909">pairs</a></td></tr>
+<tr><td class="mdescLeft">&nbsp;</td><td class="mdescRight">The stack of mapping pairs (key, value). <a href="#ac44360d96e1cf1d21434dad925b34abd"></a><br/></td></tr>
+<tr><td class="memItemLeft" >&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<a class="el" href="group__styles.html#gab47523846a5c5960e07367a28ea9750a">yaml_mapping_style_t</a>&nbsp;&nbsp;&nbsp;<a class="el" href="structyaml__node__s.html#a5b80d97f64e2867927404fedb65949c6">style</a></td></tr>
+<tr><td class="mdescLeft">&nbsp;</td><td class="mdescRight">The mapping style. <a href="#a4071cd026bfc0eb097b8dac6c3b7cbb5"></a><br/></td></tr>
+<tr><td class="memItemLeft" valign="top">&nbsp;&nbsp;&nbsp;}&nbsp;&nbsp;&nbsp;<a class="el" href="structyaml__node__s.html#ab18dc5c573885a08a92e113dcb7fb361">mapping</a></td></tr>
+<tr><td class="mdescLeft">&nbsp;</td><td class="mdescRight">The mapping parameters (for <code>YAML_MAPPING_NODE</code>). <a href="#a37018c73209f623ca1e38c8506533080"></a><br/></td></tr>
+<tr><td class="memItemLeft" valign="top">}&nbsp;</td><td class="memItemRight" valign="bottom"><a class="el" href="structyaml__node__s.html#a7e1be921e921f2d0911e450a063b1344">data</a></td></tr>
+<tr><td class="mdescLeft">&nbsp;</td><td class="mdescRight">The node data. <a href="#a7e1be921e921f2d0911e450a063b1344"></a><br/></td></tr>
+<tr><td class="memItemLeft" align="right" valign="top"><a class="el" href="structyaml__mark__s.html">yaml_mark_t</a>&nbsp;</td><td class="memItemRight" valign="bottom"><a class="el" href="structyaml__node__s.html#ac17afa3b3a9ff4703bb4983163bfae5c">start_mark</a></td></tr>
+<tr><td class="mdescLeft">&nbsp;</td><td class="mdescRight">The beginning of the node. <a href="#ac17afa3b3a9ff4703bb4983163bfae5c"></a><br/></td></tr>
+<tr><td class="memItemLeft" align="right" valign="top"><a class="el" href="structyaml__mark__s.html">yaml_mark_t</a>&nbsp;</td><td class="memItemRight" valign="bottom"><a class="el" href="structyaml__node__s.html#a63144671fd16f94f72c6d537360f7328">end_mark</a></td></tr>
+<tr><td class="mdescLeft">&nbsp;</td><td class="mdescRight">The end of the node. <a href="#a63144671fd16f94f72c6d537360f7328"></a><br/></td></tr>
+</table>
+<hr/><a name="_details"></a><h2>Detailed Description</h2>
+<p>The node structure. </p>
+<hr/><h2>Field Documentation</h2>
+<a class="anchor" id="a1db4ea72e13be65ec42339ce47d19669"></a><!-- doxytag: member="yaml_node_s::type" ref="a1db4ea72e13be65ec42339ce47d19669" args="" -->
+<div class="memitem">
+<div class="memproto">
+ <table class="memname">
+ <tr>
+ <td class="memname"><a class="el" href="group__nodes.html#gabe020d2fc42d3e896549e9f97da622d2">yaml_node_type_t</a> <a class="el" href="structyaml__node__s.html#a1db4ea72e13be65ec42339ce47d19669">yaml_node_s::type</a></td>
+ </tr>
+ </table>
+</div>
+<div class="memdoc">
+
+<p>The node type. </p>
+
+</div>
+</div>
+<a class="anchor" id="aa753358ea6d9d221b7b188832d47fefa"></a><!-- doxytag: member="yaml_node_s::tag" ref="aa753358ea6d9d221b7b188832d47fefa" args="" -->
+<div class="memitem">
+<div class="memproto">
+ <table class="memname">
+ <tr>
+ <td class="memname"><a class="el" href="group__basic.html#gaf8657e81f0b8b05d1a081001fc6cb8bd">yaml_char_t</a>* <a class="el" href="structyaml__node__s.html#aa753358ea6d9d221b7b188832d47fefa">yaml_node_s::tag</a></td>
+ </tr>
+ </table>
+</div>
+<div class="memdoc">
+
+<p>The node tag. </p>
+
+</div>
+</div>
+<a class="anchor" id="a0d444412a29609d62699267ae72f971d"></a><!-- doxytag: member="yaml_node_s::value" ref="a0d444412a29609d62699267ae72f971d" args="" -->
+<div class="memitem">
+<div class="memproto">
+ <table class="memname">
+ <tr>
+ <td class="memname"><a class="el" href="group__basic.html#gaf8657e81f0b8b05d1a081001fc6cb8bd">yaml_char_t</a>* <a class="el" href="structyaml__node__s.html#a0d444412a29609d62699267ae72f971d">yaml_node_s::value</a></td>
+ </tr>
+ </table>
+</div>
+<div class="memdoc">
+
+<p>The scalar value. </p>
+
+</div>
+</div>
+<a class="anchor" id="ad90dd9926d9debbaa48eb5339bd9fc36"></a><!-- doxytag: member="yaml_node_s::length" ref="ad90dd9926d9debbaa48eb5339bd9fc36" args="" -->
+<div class="memitem">
+<div class="memproto">
+ <table class="memname">
+ <tr>
+ <td class="memname">size_t <a class="el" href="structyaml__node__s.html#ad90dd9926d9debbaa48eb5339bd9fc36">yaml_node_s::length</a></td>
+ </tr>
+ </table>
+</div>
+<div class="memdoc">
+
+<p>The length of the scalar value. </p>
+
+</div>
+</div>
+<a class="anchor" id="a362960375516e77a130c412ef10ef55d"></a><!-- doxytag: member="yaml_node_s::style" ref="a362960375516e77a130c412ef10ef55d" args="" -->
+<div class="memitem">
+<div class="memproto">
+ <table class="memname">
+ <tr>
+ <td class="memname"><a class="el" href="group__styles.html#ga3fa6405631e1afe5bd5c488a6c5e8065">yaml_scalar_style_t</a> <a class="el" href="structyaml__node__s.html#a362960375516e77a130c412ef10ef55d">yaml_node_s::style</a></td>
+ </tr>
+ </table>
+</div>
+<div class="memdoc">
+
+<p>The scalar style. </p>
+
+</div>
+</div>
+<a class="anchor" id="a688583a2649848aed700d7e07d9efac9"></a><!-- doxytag: member="yaml_node_s::scalar" ref="a688583a2649848aed700d7e07d9efac9" args="" -->
+<div class="memitem">
+<div class="memproto">
+ <table class="memname">
+ <tr>
+ <td class="memname">struct { ... } <a class="el" href="structyaml__node__s.html#a688583a2649848aed700d7e07d9efac9">yaml_node_s::scalar</a></td>
+ </tr>
+ </table>
+</div>
+<div class="memdoc">
+
+<p>The scalar parameters (for <code>YAML_SCALAR_NODE</code>). </p>
+
+</div>
+</div>
+<a class="anchor" id="a2e1001a0a7b068d4b2543a93d4cf60d4"></a><!-- doxytag: member="yaml_node_s::start" ref="a2e1001a0a7b068d4b2543a93d4cf60d4" args="" -->
+<div class="memitem">
+<div class="memproto">
+ <table class="memname">
+ <tr>
+ <td class="memname"><a class="el" href="group__nodes.html#ga7cc3581582e778b00c04e99cd3656860">yaml_node_item_t</a>* <a class="el" href="structyaml__node__s.html#a2e1001a0a7b068d4b2543a93d4cf60d4">yaml_node_s::start</a></td>
+ </tr>
+ </table>
+</div>
+<div class="memdoc">
+
+<p>The beginning of the stack. </p>
+
+</div>
+</div>
+<a class="anchor" id="ac9b3d891f9fcd5462289823716deca0e"></a><!-- doxytag: member="yaml_node_s::end" ref="ac9b3d891f9fcd5462289823716deca0e" args="" -->
+<div class="memitem">
+<div class="memproto">
+ <table class="memname">
+ <tr>
+ <td class="memname"><a class="el" href="group__nodes.html#ga7cc3581582e778b00c04e99cd3656860">yaml_node_item_t</a>* <a class="el" href="structyaml__node__s.html#ac9b3d891f9fcd5462289823716deca0e">yaml_node_s::end</a></td>
+ </tr>
+ </table>
+</div>
+<div class="memdoc">
+
+<p>The end of the stack. </p>
+
+</div>
+</div>
+<a class="anchor" id="a510326726569a06a11119f12649787cf"></a><!-- doxytag: member="yaml_node_s::top" ref="a510326726569a06a11119f12649787cf" args="" -->
+<div class="memitem">
+<div class="memproto">
+ <table class="memname">
+ <tr>
+ <td class="memname"><a class="el" href="group__nodes.html#ga7cc3581582e778b00c04e99cd3656860">yaml_node_item_t</a>* <a class="el" href="structyaml__node__s.html#a510326726569a06a11119f12649787cf">yaml_node_s::top</a></td>
+ </tr>
+ </table>
+</div>
+<div class="memdoc">
+
+<p>The top of the stack. </p>
+
+</div>
+</div>
+<a class="anchor" id="a6b340541cc012ac5aacdcaa46ced097a"></a><!-- doxytag: member="yaml_node_s::items" ref="a6b340541cc012ac5aacdcaa46ced097a" args="" -->
+<div class="memitem">
+<div class="memproto">
+ <table class="memname">
+ <tr>
+ <td class="memname">struct { ... } ::@21 <a class="el" href="structyaml__node__s.html#a6b340541cc012ac5aacdcaa46ced097a">yaml_node_s::items</a></td>
+ </tr>
+ </table>
+</div>
+<div class="memdoc">
+
+<p>The stack of sequence items. </p>
+
+</div>
+</div>
+<a class="anchor" id="a242be04ec3709138264175e3e5b50dbe"></a><!-- doxytag: member="yaml_node_s::style" ref="a242be04ec3709138264175e3e5b50dbe" args="" -->
+<div class="memitem">
+<div class="memproto">
+ <table class="memname">
+ <tr>
+ <td class="memname"><a class="el" href="group__styles.html#ga58a1123d271e56c72de6abf852ac4dc2">yaml_sequence_style_t</a> <a class="el" href="structyaml__node__s.html#a362960375516e77a130c412ef10ef55d">yaml_node_s::style</a></td>
+ </tr>
+ </table>
+</div>
+<div class="memdoc">
+
+<p>The sequence style. </p>
+
+</div>
+</div>
+<a class="anchor" id="afe215962139fac93b965cc2acd71452b"></a><!-- doxytag: member="yaml_node_s::sequence" ref="afe215962139fac93b965cc2acd71452b" args="" -->
+<div class="memitem">
+<div class="memproto">
+ <table class="memname">
+ <tr>
+ <td class="memname">struct { ... } <a class="el" href="structyaml__node__s.html#afe215962139fac93b965cc2acd71452b">yaml_node_s::sequence</a></td>
+ </tr>
+ </table>
+</div>
+<div class="memdoc">
+
+<p>The sequence parameters (for <code>YAML_SEQUENCE_NODE</code>). </p>
+
+</div>
+</div>
+<a class="anchor" id="a82afddfe1cf7f1a346d931ad4896d3de"></a><!-- doxytag: member="yaml_node_s::start" ref="a82afddfe1cf7f1a346d931ad4896d3de" args="" -->
+<div class="memitem">
+<div class="memproto">
+ <table class="memname">
+ <tr>
+ <td class="memname"><a class="el" href="structyaml__node__pair__s.html">yaml_node_pair_t</a>* <a class="el" href="structyaml__node__s.html#a2e1001a0a7b068d4b2543a93d4cf60d4">yaml_node_s::start</a></td>
+ </tr>
+ </table>
+</div>
+<div class="memdoc">
+
+<p>The beginning of the stack. </p>
+
+</div>
+</div>
+<a class="anchor" id="a1827ba7f3e7f7e94171fa20ade25345d"></a><!-- doxytag: member="yaml_node_s::end" ref="a1827ba7f3e7f7e94171fa20ade25345d" args="" -->
+<div class="memitem">
+<div class="memproto">
+ <table class="memname">
+ <tr>
+ <td class="memname"><a class="el" href="structyaml__node__pair__s.html">yaml_node_pair_t</a>* <a class="el" href="structyaml__node__s.html#ac9b3d891f9fcd5462289823716deca0e">yaml_node_s::end</a></td>
+ </tr>
+ </table>
+</div>
+<div class="memdoc">
+
+<p>The end of the stack. </p>
+
+</div>
+</div>
+<a class="anchor" id="aa420f88720907fe02b1d1595c9351d59"></a><!-- doxytag: member="yaml_node_s::top" ref="aa420f88720907fe02b1d1595c9351d59" args="" -->
+<div class="memitem">
+<div class="memproto">
+ <table class="memname">
+ <tr>
+ <td class="memname"><a class="el" href="structyaml__node__pair__s.html">yaml_node_pair_t</a>* <a class="el" href="structyaml__node__s.html#a510326726569a06a11119f12649787cf">yaml_node_s::top</a></td>
+ </tr>
+ </table>
+</div>
+<div class="memdoc">
+
+<p>The top of the stack. </p>
+
+</div>
+</div>
+<a class="anchor" id="a830a080bbed021eb230ef644e4680909"></a><!-- doxytag: member="yaml_node_s::pairs" ref="a830a080bbed021eb230ef644e4680909" args="" -->
+<div class="memitem">
+<div class="memproto">
+ <table class="memname">
+ <tr>
+ <td class="memname">struct { ... } ::@22 <a class="el" href="structyaml__node__s.html#a830a080bbed021eb230ef644e4680909">yaml_node_s::pairs</a></td>
+ </tr>
+ </table>
+</div>
+<div class="memdoc">
+
+<p>The stack of mapping pairs (key, value). </p>
+
+</div>
+</div>
+<a class="anchor" id="a5b80d97f64e2867927404fedb65949c6"></a><!-- doxytag: member="yaml_node_s::style" ref="a5b80d97f64e2867927404fedb65949c6" args="" -->
+<div class="memitem">
+<div class="memproto">
+ <table class="memname">
+ <tr>
+ <td class="memname"><a class="el" href="group__styles.html#gab47523846a5c5960e07367a28ea9750a">yaml_mapping_style_t</a> <a class="el" href="structyaml__node__s.html#a362960375516e77a130c412ef10ef55d">yaml_node_s::style</a></td>
+ </tr>
+ </table>
+</div>
+<div class="memdoc">
+
+<p>The mapping style. </p>
+
+</div>
+</div>
+<a class="anchor" id="ab18dc5c573885a08a92e113dcb7fb361"></a><!-- doxytag: member="yaml_node_s::mapping" ref="ab18dc5c573885a08a92e113dcb7fb361" args="" -->
+<div class="memitem">
+<div class="memproto">
+ <table class="memname">
+ <tr>
+ <td class="memname">struct { ... } <a class="el" href="structyaml__node__s.html#ab18dc5c573885a08a92e113dcb7fb361">yaml_node_s::mapping</a></td>
+ </tr>
+ </table>
+</div>
+<div class="memdoc">
+
+<p>The mapping parameters (for <code>YAML_MAPPING_NODE</code>). </p>
+
+</div>
+</div>
+<a class="anchor" id="a7e1be921e921f2d0911e450a063b1344"></a><!-- doxytag: member="yaml_node_s::data" ref="a7e1be921e921f2d0911e450a063b1344" args="" -->
+<div class="memitem">
+<div class="memproto">
+ <table class="memname">
+ <tr>
+ <td class="memname">union { ... } <a class="el" href="structyaml__node__s.html#a7e1be921e921f2d0911e450a063b1344">yaml_node_s::data</a></td>
+ </tr>
+ </table>
+</div>
+<div class="memdoc">
+
+<p>The node data. </p>
+
+</div>
+</div>
+<a class="anchor" id="ac17afa3b3a9ff4703bb4983163bfae5c"></a><!-- doxytag: member="yaml_node_s::start_mark" ref="ac17afa3b3a9ff4703bb4983163bfae5c" args="" -->
+<div class="memitem">
+<div class="memproto">
+ <table class="memname">
+ <tr>
+ <td class="memname"><a class="el" href="structyaml__mark__s.html">yaml_mark_t</a> <a class="el" href="structyaml__node__s.html#ac17afa3b3a9ff4703bb4983163bfae5c">yaml_node_s::start_mark</a></td>
+ </tr>
+ </table>
+</div>
+<div class="memdoc">
+
+<p>The beginning of the node. </p>
+
+</div>
+</div>
+<a class="anchor" id="a63144671fd16f94f72c6d537360f7328"></a><!-- doxytag: member="yaml_node_s::end_mark" ref="a63144671fd16f94f72c6d537360f7328" args="" -->
+<div class="memitem">
+<div class="memproto">
+ <table class="memname">
+ <tr>
+ <td class="memname"><a class="el" href="structyaml__mark__s.html">yaml_mark_t</a> <a class="el" href="structyaml__node__s.html#a63144671fd16f94f72c6d537360f7328">yaml_node_s::end_mark</a></td>
+ </tr>
+ </table>
+</div>
+<div class="memdoc">
+
+<p>The end of the node. </p>
+
+</div>
+</div>
+<hr/>The documentation for this struct was generated from the following file:<ul>
+<li><a class="el" href="yaml_8h.html">yaml.h</a></li>
+</ul>
+</div>
+<hr class="footer"/><address class="footer"><small>Generated on Mon May 30 2011 22:00:00 for yaml by&nbsp;
+<a href="http://www.doxygen.org/index.html">
+<img class="footer" src="doxygen.png" alt="doxygen"/></a> 1.7.1 </small></address>
+</body>
+</html>
diff --git a/contrib/libyaml/doc/html/structyaml__parser__s.html b/contrib/libyaml/doc/html/structyaml__parser__s.html
new file mode 100644
index 0000000..5402cb2
--- /dev/null
+++ b/contrib/libyaml/doc/html/structyaml__parser__s.html
@@ -0,0 +1,1229 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head>
+<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/>
+<title>yaml: yaml_parser_s Struct Reference</title>
+<link href="tabs.css" rel="stylesheet" type="text/css"/>
+<link href="doxygen.css" rel="stylesheet" type="text/css"/>
+</head>
+<body>
+<!-- Generated by Doxygen 1.7.1 -->
+<div class="navigation" id="top">
+ <div class="tabs">
+ <ul class="tablist">
+ <li><a href="index.html"><span>Main&nbsp;Page</span></a></li>
+ <li><a href="modules.html"><span>Modules</span></a></li>
+ <li class="current"><a href="annotated.html"><span>Data&nbsp;Structures</span></a></li>
+ <li><a href="files.html"><span>Files</span></a></li>
+ </ul>
+ </div>
+ <div class="tabs2">
+ <ul class="tablist">
+ <li><a href="annotated.html"><span>Data&nbsp;Structures</span></a></li>
+ <li><a href="functions.html"><span>Data&nbsp;Fields</span></a></li>
+ </ul>
+ </div>
+</div>
+<div class="header">
+ <div class="headertitle">
+<h1>yaml_parser_s Struct Reference<br/>
+<small>
+[<a class="el" href="group__parser.html">Parser Definitions</a>]</small>
+</h1> </div>
+</div>
+<div class="contents">
+<!-- doxytag: class="yaml_parser_s" -->
+<p>The parser structure.
+<a href="#_details">More...</a></p>
+
+<p><code>#include &lt;yaml.h&gt;</code></p>
+<table class="memberdecls">
+<tr><td colspan="2"><h2><a name="pub-attribs"></a>
+Data Fields</h2></td></tr>
+<tr><td class="memItemLeft" align="right" valign="top">const unsigned char *&nbsp;</td><td class="memItemRight" valign="bottom"><a class="el" href="structyaml__parser__s.html#a8cdb2fed4bb17b1d62d29fa06c53fef6">start</a></td></tr>
+<tr><td class="mdescLeft">&nbsp;</td><td class="mdescRight">The string start pointer. <a href="#a8cdb2fed4bb17b1d62d29fa06c53fef6"></a><br/></td></tr>
+<tr><td class="memItemLeft" align="right" valign="top">const unsigned char *&nbsp;</td><td class="memItemRight" valign="bottom"><a class="el" href="structyaml__parser__s.html#aad74ffeb7f2eef0a12e34b0aac263ff3">end</a></td></tr>
+<tr><td class="mdescLeft">&nbsp;</td><td class="mdescRight">The string end pointer. <a href="#aad74ffeb7f2eef0a12e34b0aac263ff3"></a><br/></td></tr>
+<tr><td class="memItemLeft" align="right" valign="top">const unsigned char *&nbsp;</td><td class="memItemRight" valign="bottom"><a class="el" href="structyaml__parser__s.html#a3406d2ba7e969c09344d4ced8c855007">current</a></td></tr>
+<tr><td class="mdescLeft">&nbsp;</td><td class="mdescRight">The string current position. <a href="#a3406d2ba7e969c09344d4ced8c855007"></a><br/></td></tr>
+<tr><td class="memItemLeft" >struct {</td></tr>
+<tr><td class="memItemLeft" >&nbsp;&nbsp;&nbsp;const unsigned char *&nbsp;&nbsp;&nbsp;<a class="el" href="structyaml__parser__s.html#a8cdb2fed4bb17b1d62d29fa06c53fef6">start</a></td></tr>
+<tr><td class="mdescLeft">&nbsp;</td><td class="mdescRight">The string start pointer. <a href="#a5eb8c81f118c8e4a41eaa2ccd4c79c14"></a><br/></td></tr>
+<tr><td class="memItemLeft" >&nbsp;&nbsp;&nbsp;const unsigned char *&nbsp;&nbsp;&nbsp;<a class="el" href="structyaml__parser__s.html#aad74ffeb7f2eef0a12e34b0aac263ff3">end</a></td></tr>
+<tr><td class="mdescLeft">&nbsp;</td><td class="mdescRight">The string end pointer. <a href="#a2d5483a8cbfd576737c5d8020bc19d2f"></a><br/></td></tr>
+<tr><td class="memItemLeft" >&nbsp;&nbsp;&nbsp;const unsigned char *&nbsp;&nbsp;&nbsp;<a class="el" href="structyaml__parser__s.html#a3406d2ba7e969c09344d4ced8c855007">current</a></td></tr>
+<tr><td class="mdescLeft">&nbsp;</td><td class="mdescRight">The string current position. <a href="#a19b7d0d276bc06d52fbcffad29ad1f7d"></a><br/></td></tr>
+<tr><td class="memItemLeft" valign="top">}&nbsp;</td><td class="memItemRight" valign="bottom"><a class="el" href="structyaml__parser__s.html#a44fa7ca68030680244f3743ce5e35702">string</a></td></tr>
+<tr><td class="mdescLeft">&nbsp;</td><td class="mdescRight">String input data. <a href="#a44fa7ca68030680244f3743ce5e35702"></a><br/></td></tr>
+<tr><td class="memItemLeft" align="right" valign="top">FILE *&nbsp;</td><td class="memItemRight" valign="bottom"><a class="el" href="structyaml__parser__s.html#ae69c2974e3c4c37e941a0e1971be15a9">file</a></td></tr>
+<tr><td class="mdescLeft">&nbsp;</td><td class="mdescRight">File input data. <a href="#ae69c2974e3c4c37e941a0e1971be15a9"></a><br/></td></tr>
+<tr><td class="memItemLeft" align="right" valign="top"><a class="el" href="group__basic.html#gaf8657e81f0b8b05d1a081001fc6cb8bd">yaml_char_t</a> *&nbsp;</td><td class="memItemRight" valign="bottom"><a class="el" href="structyaml__parser__s.html#a5cdddcbd18566acc760a660a88f93ffd">start</a></td></tr>
+<tr><td class="mdescLeft">&nbsp;</td><td class="mdescRight">The beginning of the buffer. <a href="#a5cdddcbd18566acc760a660a88f93ffd"></a><br/></td></tr>
+<tr><td class="memItemLeft" align="right" valign="top"><a class="el" href="group__basic.html#gaf8657e81f0b8b05d1a081001fc6cb8bd">yaml_char_t</a> *&nbsp;</td><td class="memItemRight" valign="bottom"><a class="el" href="structyaml__parser__s.html#a6ff1f802eb95bc45f13e8e73ec009828">end</a></td></tr>
+<tr><td class="mdescLeft">&nbsp;</td><td class="mdescRight">The end of the buffer. <a href="#a6ff1f802eb95bc45f13e8e73ec009828"></a><br/></td></tr>
+<tr><td class="memItemLeft" align="right" valign="top"><a class="el" href="group__basic.html#gaf8657e81f0b8b05d1a081001fc6cb8bd">yaml_char_t</a> *&nbsp;</td><td class="memItemRight" valign="bottom"><a class="el" href="structyaml__parser__s.html#a8199466e3578374b3f984b6c0c4e2ae4">pointer</a></td></tr>
+<tr><td class="mdescLeft">&nbsp;</td><td class="mdescRight">The current position of the buffer. <a href="#a8199466e3578374b3f984b6c0c4e2ae4"></a><br/></td></tr>
+<tr><td class="memItemLeft" align="right" valign="top"><a class="el" href="group__basic.html#gaf8657e81f0b8b05d1a081001fc6cb8bd">yaml_char_t</a> *&nbsp;</td><td class="memItemRight" valign="bottom"><a class="el" href="structyaml__parser__s.html#aea4d8da24939825b2fadd368a71ec7de">last</a></td></tr>
+<tr><td class="mdescLeft">&nbsp;</td><td class="mdescRight">The last filled position of the buffer. <a href="#aea4d8da24939825b2fadd368a71ec7de"></a><br/></td></tr>
+<tr><td class="memItemLeft" align="right" valign="top">unsigned char *&nbsp;</td><td class="memItemRight" valign="bottom"><a class="el" href="structyaml__parser__s.html#a6c08a94c21dfe1611c0d89aef0d3c46d">start</a></td></tr>
+<tr><td class="mdescLeft">&nbsp;</td><td class="mdescRight">The beginning of the buffer. <a href="#a6c08a94c21dfe1611c0d89aef0d3c46d"></a><br/></td></tr>
+<tr><td class="memItemLeft" align="right" valign="top">unsigned char *&nbsp;</td><td class="memItemRight" valign="bottom"><a class="el" href="structyaml__parser__s.html#aa768a9c29ae2c3015fdb84ea313844e2">end</a></td></tr>
+<tr><td class="mdescLeft">&nbsp;</td><td class="mdescRight">The end of the buffer. <a href="#aa768a9c29ae2c3015fdb84ea313844e2"></a><br/></td></tr>
+<tr><td class="memItemLeft" align="right" valign="top">unsigned char *&nbsp;</td><td class="memItemRight" valign="bottom"><a class="el" href="structyaml__parser__s.html#abea626790abfbcaeeb72a3772dc69e43">pointer</a></td></tr>
+<tr><td class="mdescLeft">&nbsp;</td><td class="mdescRight">The current position of the buffer. <a href="#abea626790abfbcaeeb72a3772dc69e43"></a><br/></td></tr>
+<tr><td class="memItemLeft" align="right" valign="top">unsigned char *&nbsp;</td><td class="memItemRight" valign="bottom"><a class="el" href="structyaml__parser__s.html#a3ad1ccaf979092ece82bc981c5a22fb0">last</a></td></tr>
+<tr><td class="mdescLeft">&nbsp;</td><td class="mdescRight">The last filled position of the buffer. <a href="#a3ad1ccaf979092ece82bc981c5a22fb0"></a><br/></td></tr>
+<tr><td class="memItemLeft" align="right" valign="top"><a class="el" href="structyaml__token__s.html">yaml_token_t</a> *&nbsp;</td><td class="memItemRight" valign="bottom"><a class="el" href="structyaml__parser__s.html#a5f33f5c8f19c1c124cba4857ab2a05c7">start</a></td></tr>
+<tr><td class="mdescLeft">&nbsp;</td><td class="mdescRight">The beginning of the tokens queue. <a href="#a5f33f5c8f19c1c124cba4857ab2a05c7"></a><br/></td></tr>
+<tr><td class="memItemLeft" align="right" valign="top"><a class="el" href="structyaml__token__s.html">yaml_token_t</a> *&nbsp;</td><td class="memItemRight" valign="bottom"><a class="el" href="structyaml__parser__s.html#a41594b6495f4d31edb977cafb8cbaf78">end</a></td></tr>
+<tr><td class="mdescLeft">&nbsp;</td><td class="mdescRight">The end of the tokens queue. <a href="#a41594b6495f4d31edb977cafb8cbaf78"></a><br/></td></tr>
+<tr><td class="memItemLeft" align="right" valign="top"><a class="el" href="structyaml__token__s.html">yaml_token_t</a> *&nbsp;</td><td class="memItemRight" valign="bottom"><a class="el" href="structyaml__parser__s.html#aa1c7a1248ca22159a3e60ba45b386507">head</a></td></tr>
+<tr><td class="mdescLeft">&nbsp;</td><td class="mdescRight">The head of the tokens queue. <a href="#aa1c7a1248ca22159a3e60ba45b386507"></a><br/></td></tr>
+<tr><td class="memItemLeft" align="right" valign="top"><a class="el" href="structyaml__token__s.html">yaml_token_t</a> *&nbsp;</td><td class="memItemRight" valign="bottom"><a class="el" href="structyaml__parser__s.html#a22ad26583d8d1264e982188358aa79b6">tail</a></td></tr>
+<tr><td class="mdescLeft">&nbsp;</td><td class="mdescRight">The tail of the tokens queue. <a href="#a22ad26583d8d1264e982188358aa79b6"></a><br/></td></tr>
+<tr><td class="memItemLeft" align="right" valign="top">int *&nbsp;</td><td class="memItemRight" valign="bottom"><a class="el" href="structyaml__parser__s.html#ab7208590a6852001ff8e4343a97b0c24">start</a></td></tr>
+<tr><td class="mdescLeft">&nbsp;</td><td class="mdescRight">The beginning of the stack. <a href="#ab7208590a6852001ff8e4343a97b0c24"></a><br/></td></tr>
+<tr><td class="memItemLeft" align="right" valign="top">int *&nbsp;</td><td class="memItemRight" valign="bottom"><a class="el" href="structyaml__parser__s.html#a6d8295bd62c7bb7be9486a1b4d71e736">end</a></td></tr>
+<tr><td class="mdescLeft">&nbsp;</td><td class="mdescRight">The end of the stack. <a href="#a6d8295bd62c7bb7be9486a1b4d71e736"></a><br/></td></tr>
+<tr><td class="memItemLeft" align="right" valign="top">int *&nbsp;</td><td class="memItemRight" valign="bottom"><a class="el" href="structyaml__parser__s.html#a9f1f879ba84bc51fa8feb1f47190aa23">top</a></td></tr>
+<tr><td class="mdescLeft">&nbsp;</td><td class="mdescRight">The top of the stack. <a href="#a9f1f879ba84bc51fa8feb1f47190aa23"></a><br/></td></tr>
+<tr><td class="memItemLeft" align="right" valign="top"><a class="el" href="structyaml__simple__key__s.html">yaml_simple_key_t</a> *&nbsp;</td><td class="memItemRight" valign="bottom"><a class="el" href="structyaml__parser__s.html#ac311a6d962e0f67dd11759b8999630c6">start</a></td></tr>
+<tr><td class="mdescLeft">&nbsp;</td><td class="mdescRight">The beginning of the stack. <a href="#ac311a6d962e0f67dd11759b8999630c6"></a><br/></td></tr>
+<tr><td class="memItemLeft" align="right" valign="top"><a class="el" href="structyaml__simple__key__s.html">yaml_simple_key_t</a> *&nbsp;</td><td class="memItemRight" valign="bottom"><a class="el" href="structyaml__parser__s.html#ae8416ffcb48c78a575ee21872d5aa698">end</a></td></tr>
+<tr><td class="mdescLeft">&nbsp;</td><td class="mdescRight">The end of the stack. <a href="#ae8416ffcb48c78a575ee21872d5aa698"></a><br/></td></tr>
+<tr><td class="memItemLeft" align="right" valign="top"><a class="el" href="structyaml__simple__key__s.html">yaml_simple_key_t</a> *&nbsp;</td><td class="memItemRight" valign="bottom"><a class="el" href="structyaml__parser__s.html#ae610673669f06d46146198a346796276">top</a></td></tr>
+<tr><td class="mdescLeft">&nbsp;</td><td class="mdescRight">The top of the stack. <a href="#ae610673669f06d46146198a346796276"></a><br/></td></tr>
+<tr><td class="memItemLeft" align="right" valign="top"><a class="el" href="group__parser.html#ga52b56d3e3cee0f9ba460978802a8c83b">yaml_parser_state_t</a> *&nbsp;</td><td class="memItemRight" valign="bottom"><a class="el" href="structyaml__parser__s.html#adfdc33f6f53dce4bee87f11821d879b7">start</a></td></tr>
+<tr><td class="mdescLeft">&nbsp;</td><td class="mdescRight">The beginning of the stack. <a href="#adfdc33f6f53dce4bee87f11821d879b7"></a><br/></td></tr>
+<tr><td class="memItemLeft" align="right" valign="top"><a class="el" href="group__parser.html#ga52b56d3e3cee0f9ba460978802a8c83b">yaml_parser_state_t</a> *&nbsp;</td><td class="memItemRight" valign="bottom"><a class="el" href="structyaml__parser__s.html#a211a0aedc964ba8cd07cb7875faa464b">end</a></td></tr>
+<tr><td class="mdescLeft">&nbsp;</td><td class="mdescRight">The end of the stack. <a href="#a211a0aedc964ba8cd07cb7875faa464b"></a><br/></td></tr>
+<tr><td class="memItemLeft" align="right" valign="top"><a class="el" href="group__parser.html#ga52b56d3e3cee0f9ba460978802a8c83b">yaml_parser_state_t</a> *&nbsp;</td><td class="memItemRight" valign="bottom"><a class="el" href="structyaml__parser__s.html#af3eecdcdeeb183d16e4219749620df0c">top</a></td></tr>
+<tr><td class="mdescLeft">&nbsp;</td><td class="mdescRight">The top of the stack. <a href="#af3eecdcdeeb183d16e4219749620df0c"></a><br/></td></tr>
+<tr><td class="memItemLeft" align="right" valign="top"><a class="el" href="structyaml__mark__s.html">yaml_mark_t</a> *&nbsp;</td><td class="memItemRight" valign="bottom"><a class="el" href="structyaml__parser__s.html#ab5a3789882819f2fd69f2cd9deaac8f6">start</a></td></tr>
+<tr><td class="mdescLeft">&nbsp;</td><td class="mdescRight">The beginning of the stack. <a href="#ab5a3789882819f2fd69f2cd9deaac8f6"></a><br/></td></tr>
+<tr><td class="memItemLeft" align="right" valign="top"><a class="el" href="structyaml__mark__s.html">yaml_mark_t</a> *&nbsp;</td><td class="memItemRight" valign="bottom"><a class="el" href="structyaml__parser__s.html#aad019da255ea73adf31d4b1aeac86bb2">end</a></td></tr>
+<tr><td class="mdescLeft">&nbsp;</td><td class="mdescRight">The end of the stack. <a href="#aad019da255ea73adf31d4b1aeac86bb2"></a><br/></td></tr>
+<tr><td class="memItemLeft" align="right" valign="top"><a class="el" href="structyaml__mark__s.html">yaml_mark_t</a> *&nbsp;</td><td class="memItemRight" valign="bottom"><a class="el" href="structyaml__parser__s.html#ab2678112fd2eaa8f588f2d6217aabc9d">top</a></td></tr>
+<tr><td class="mdescLeft">&nbsp;</td><td class="mdescRight">The top of the stack. <a href="#ab2678112fd2eaa8f588f2d6217aabc9d"></a><br/></td></tr>
+<tr><td class="memItemLeft" align="right" valign="top"><a class="el" href="structyaml__tag__directive__s.html">yaml_tag_directive_t</a> *&nbsp;</td><td class="memItemRight" valign="bottom"><a class="el" href="structyaml__parser__s.html#a3614f6d6e673e8177e4555c9ecf830fb">start</a></td></tr>
+<tr><td class="mdescLeft">&nbsp;</td><td class="mdescRight">The beginning of the list. <a href="#a3614f6d6e673e8177e4555c9ecf830fb"></a><br/></td></tr>
+<tr><td class="memItemLeft" align="right" valign="top"><a class="el" href="structyaml__tag__directive__s.html">yaml_tag_directive_t</a> *&nbsp;</td><td class="memItemRight" valign="bottom"><a class="el" href="structyaml__parser__s.html#aa7fdc1ff8342636119934ac824a2ecc8">end</a></td></tr>
+<tr><td class="mdescLeft">&nbsp;</td><td class="mdescRight">The end of the list. <a href="#aa7fdc1ff8342636119934ac824a2ecc8"></a><br/></td></tr>
+<tr><td class="memItemLeft" align="right" valign="top"><a class="el" href="structyaml__tag__directive__s.html">yaml_tag_directive_t</a> *&nbsp;</td><td class="memItemRight" valign="bottom"><a class="el" href="structyaml__parser__s.html#a490eddbfcc27787e47de631a3d2e09a8">top</a></td></tr>
+<tr><td class="mdescLeft">&nbsp;</td><td class="mdescRight">The top of the list. <a href="#a490eddbfcc27787e47de631a3d2e09a8"></a><br/></td></tr>
+<tr><td class="memItemLeft" align="right" valign="top"><a class="el" href="structyaml__alias__data__s.html">yaml_alias_data_t</a> *&nbsp;</td><td class="memItemRight" valign="bottom"><a class="el" href="structyaml__parser__s.html#ab9eddd3a112c3a4547bf87f6936aba94">start</a></td></tr>
+<tr><td class="mdescLeft">&nbsp;</td><td class="mdescRight">The beginning of the list. <a href="#ab9eddd3a112c3a4547bf87f6936aba94"></a><br/></td></tr>
+<tr><td class="memItemLeft" align="right" valign="top"><a class="el" href="structyaml__alias__data__s.html">yaml_alias_data_t</a> *&nbsp;</td><td class="memItemRight" valign="bottom"><a class="el" href="structyaml__parser__s.html#a4011d41483171958bbf0b5124bde97c8">end</a></td></tr>
+<tr><td class="mdescLeft">&nbsp;</td><td class="mdescRight">The end of the list. <a href="#a4011d41483171958bbf0b5124bde97c8"></a><br/></td></tr>
+<tr><td class="memItemLeft" align="right" valign="top"><a class="el" href="structyaml__alias__data__s.html">yaml_alias_data_t</a> *&nbsp;</td><td class="memItemRight" valign="bottom"><a class="el" href="structyaml__parser__s.html#a24a3f3138b44de1914a3e54dbe0aeff7">top</a></td></tr>
+<tr><td class="mdescLeft">&nbsp;</td><td class="mdescRight">The top of the list. <a href="#a24a3f3138b44de1914a3e54dbe0aeff7"></a><br/></td></tr>
+<tr><td colspan="2"><div class="groupHeader">Error handling</div></td></tr>
+<tr><td colspan="2"><div class="groupText"><p><a class="anchor" id="amgrpaf042bafd560f7bd09b37efa40772311"></a> </p>
+</div></td></tr>
+<tr><td class="memItemLeft" align="right" valign="top"><a class="el" href="group__basic.html#ga1a449f0c1b023e2ef1a596093c018e73">yaml_error_type_t</a>&nbsp;</td><td class="memItemRight" valign="bottom"><a class="el" href="structyaml__parser__s.html#a6c5c3488ff22c8a4d234ca8587fa1472">error</a></td></tr>
+<tr><td class="mdescLeft">&nbsp;</td><td class="mdescRight">Error type. <a href="#a6c5c3488ff22c8a4d234ca8587fa1472"></a><br/></td></tr>
+<tr><td class="memItemLeft" align="right" valign="top">const char *&nbsp;</td><td class="memItemRight" valign="bottom"><a class="el" href="structyaml__parser__s.html#a3dd8a43294cd420a433595a7a7d6e73d">problem</a></td></tr>
+<tr><td class="mdescLeft">&nbsp;</td><td class="mdescRight">Error description. <a href="#a3dd8a43294cd420a433595a7a7d6e73d"></a><br/></td></tr>
+<tr><td class="memItemLeft" align="right" valign="top">size_t&nbsp;</td><td class="memItemRight" valign="bottom"><a class="el" href="structyaml__parser__s.html#ae2d62a2ad45671c6dd89e18fb7c1c5bd">problem_offset</a></td></tr>
+<tr><td class="mdescLeft">&nbsp;</td><td class="mdescRight">The byte about which the problem occured. <a href="#ae2d62a2ad45671c6dd89e18fb7c1c5bd"></a><br/></td></tr>
+<tr><td class="memItemLeft" align="right" valign="top">int&nbsp;</td><td class="memItemRight" valign="bottom"><a class="el" href="structyaml__parser__s.html#a8694691b20824f6595873b728cb3bc0f">problem_value</a></td></tr>
+<tr><td class="mdescLeft">&nbsp;</td><td class="mdescRight">The problematic value (<code>-1</code> is none). <a href="#a8694691b20824f6595873b728cb3bc0f"></a><br/></td></tr>
+<tr><td class="memItemLeft" align="right" valign="top"><a class="el" href="structyaml__mark__s.html">yaml_mark_t</a>&nbsp;</td><td class="memItemRight" valign="bottom"><a class="el" href="structyaml__parser__s.html#a595b5412d39a4a9e441e5ad34fb059d9">problem_mark</a></td></tr>
+<tr><td class="mdescLeft">&nbsp;</td><td class="mdescRight">The problem position. <a href="#a595b5412d39a4a9e441e5ad34fb059d9"></a><br/></td></tr>
+<tr><td class="memItemLeft" align="right" valign="top">const char *&nbsp;</td><td class="memItemRight" valign="bottom"><a class="el" href="structyaml__parser__s.html#a6779b67a23bbf7c401e4257d5875ae6b">context</a></td></tr>
+<tr><td class="mdescLeft">&nbsp;</td><td class="mdescRight">The error context. <a href="#a6779b67a23bbf7c401e4257d5875ae6b"></a><br/></td></tr>
+<tr><td class="memItemLeft" align="right" valign="top"><a class="el" href="structyaml__mark__s.html">yaml_mark_t</a>&nbsp;</td><td class="memItemRight" valign="bottom"><a class="el" href="structyaml__parser__s.html#ace259eec6e570f94b98b252e1a632e88">context_mark</a></td></tr>
+<tr><td class="mdescLeft">&nbsp;</td><td class="mdescRight">The context position. <a href="#ace259eec6e570f94b98b252e1a632e88"></a><br/></td></tr>
+<tr><td colspan="2"><div class="groupHeader">Reader stuff</div></td></tr>
+<tr><td colspan="2"><div class="groupText"><p><a class="anchor" id="amgrpa1d775bd432fe4cf2fa9b7ee98808371"></a> </p>
+</div></td></tr>
+<tr><td class="memItemLeft" align="right" valign="top"><a class="el" href="group__parser.html#ga4982f7e4e001ddb47d2819f38f0cd9d6">yaml_read_handler_t</a> *&nbsp;</td><td class="memItemRight" valign="bottom"><a class="el" href="structyaml__parser__s.html#a8c3af47a7a0750d437cba34699fcad30">read_handler</a></td></tr>
+<tr><td class="mdescLeft">&nbsp;</td><td class="mdescRight">Read handler. <a href="#a8c3af47a7a0750d437cba34699fcad30"></a><br/></td></tr>
+<tr><td class="memItemLeft" align="right" valign="top">void *&nbsp;</td><td class="memItemRight" valign="bottom"><a class="el" href="structyaml__parser__s.html#a11f265cd495e814c8ee7d3dd78ff2ca9">read_handler_data</a></td></tr>
+<tr><td class="mdescLeft">&nbsp;</td><td class="mdescRight">A pointer for passing to the read handler. <a href="#a11f265cd495e814c8ee7d3dd78ff2ca9"></a><br/></td></tr>
+<tr><td class="memItemLeft" >union {</td></tr>
+<tr><td class="memItemLeft" >&nbsp;&nbsp;&nbsp;struct {</td></tr>
+<tr><td class="memItemLeft" >&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;const unsigned char *&nbsp;&nbsp;&nbsp;<a class="el" href="structyaml__parser__s.html#a8cdb2fed4bb17b1d62d29fa06c53fef6">start</a></td></tr>
+<tr><td class="mdescLeft">&nbsp;</td><td class="mdescRight">The string start pointer. <a href="#a5eb8c81f118c8e4a41eaa2ccd4c79c14"></a><br/></td></tr>
+<tr><td class="memItemLeft" >&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;const unsigned char *&nbsp;&nbsp;&nbsp;<a class="el" href="structyaml__parser__s.html#aad74ffeb7f2eef0a12e34b0aac263ff3">end</a></td></tr>
+<tr><td class="mdescLeft">&nbsp;</td><td class="mdescRight">The string end pointer. <a href="#a2d5483a8cbfd576737c5d8020bc19d2f"></a><br/></td></tr>
+<tr><td class="memItemLeft" >&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;const unsigned char *&nbsp;&nbsp;&nbsp;<a class="el" href="structyaml__parser__s.html#a3406d2ba7e969c09344d4ced8c855007">current</a></td></tr>
+<tr><td class="mdescLeft">&nbsp;</td><td class="mdescRight">The string current position. <a href="#a19b7d0d276bc06d52fbcffad29ad1f7d"></a><br/></td></tr>
+<tr><td class="memItemLeft" valign="top">&nbsp;&nbsp;&nbsp;}&nbsp;&nbsp;&nbsp;<a class="el" href="structyaml__parser__s.html#a44fa7ca68030680244f3743ce5e35702">string</a></td></tr>
+<tr><td class="mdescLeft">&nbsp;</td><td class="mdescRight">String input data. <a href="#a5cc6c00b4ccae1e4ea13aaad22e7b2ef"></a><br/></td></tr>
+<tr><td class="memItemLeft" >&nbsp;&nbsp;&nbsp;FILE *&nbsp;&nbsp;&nbsp;<a class="el" href="structyaml__parser__s.html#ae69c2974e3c4c37e941a0e1971be15a9">file</a></td></tr>
+<tr><td class="mdescLeft">&nbsp;</td><td class="mdescRight">File input data. <a href="#ab0fda82263c92cabb545e0d449c77369"></a><br/></td></tr>
+<tr><td class="memItemLeft" valign="top">}&nbsp;</td><td class="memItemRight" valign="bottom"><a class="el" href="structyaml__parser__s.html#ae800ef7fd42ad8bcbb69b116da3a7f53">input</a></td></tr>
+<tr><td class="mdescLeft">&nbsp;</td><td class="mdescRight">Standard (string or file) input data. <a href="#ae800ef7fd42ad8bcbb69b116da3a7f53"></a><br/></td></tr>
+<tr><td class="memItemLeft" align="right" valign="top"><a class="anchor" id="a6129a99d45aee14ec705aa54dbb493b7"></a><!-- doxytag: member="yaml_parser_s::eof" ref="a6129a99d45aee14ec705aa54dbb493b7" args="" -->
+int&nbsp;</td><td class="memItemRight" valign="bottom"><a class="el" href="structyaml__parser__s.html#a6129a99d45aee14ec705aa54dbb493b7">eof</a></td></tr>
+<tr><td class="mdescLeft">&nbsp;</td><td class="mdescRight">EOF flag. <br/></td></tr>
+<tr><td class="memItemLeft" >struct {</td></tr>
+<tr><td class="memItemLeft" >&nbsp;&nbsp;&nbsp;<a class="el" href="group__basic.html#gaf8657e81f0b8b05d1a081001fc6cb8bd">yaml_char_t</a> *&nbsp;&nbsp;&nbsp;<a class="el" href="structyaml__parser__s.html#a5cdddcbd18566acc760a660a88f93ffd">start</a></td></tr>
+<tr><td class="mdescLeft">&nbsp;</td><td class="mdescRight">The beginning of the buffer. <a href="#ac01cce9c2391bda21ad630c46e8b9ccc"></a><br/></td></tr>
+<tr><td class="memItemLeft" >&nbsp;&nbsp;&nbsp;<a class="el" href="group__basic.html#gaf8657e81f0b8b05d1a081001fc6cb8bd">yaml_char_t</a> *&nbsp;&nbsp;&nbsp;<a class="el" href="structyaml__parser__s.html#a6ff1f802eb95bc45f13e8e73ec009828">end</a></td></tr>
+<tr><td class="mdescLeft">&nbsp;</td><td class="mdescRight">The end of the buffer. <a href="#ad3b74e756cd6cdb097d0bcd499bbb487"></a><br/></td></tr>
+<tr><td class="memItemLeft" >&nbsp;&nbsp;&nbsp;<a class="el" href="group__basic.html#gaf8657e81f0b8b05d1a081001fc6cb8bd">yaml_char_t</a> *&nbsp;&nbsp;&nbsp;<a class="el" href="structyaml__parser__s.html#a8199466e3578374b3f984b6c0c4e2ae4">pointer</a></td></tr>
+<tr><td class="mdescLeft">&nbsp;</td><td class="mdescRight">The current position of the buffer. <a href="#a2f74b5c84928465c7b0e57840f8a860e"></a><br/></td></tr>
+<tr><td class="memItemLeft" >&nbsp;&nbsp;&nbsp;<a class="el" href="group__basic.html#gaf8657e81f0b8b05d1a081001fc6cb8bd">yaml_char_t</a> *&nbsp;&nbsp;&nbsp;<a class="el" href="structyaml__parser__s.html#aea4d8da24939825b2fadd368a71ec7de">last</a></td></tr>
+<tr><td class="mdescLeft">&nbsp;</td><td class="mdescRight">The last filled position of the buffer. <a href="#a6dff533b402c756a6faeb39f9148a97f"></a><br/></td></tr>
+<tr><td class="memItemLeft" valign="top">}&nbsp;</td><td class="memItemRight" valign="bottom"><a class="el" href="structyaml__parser__s.html#afc56b6252bd75ec87edec5c80a5c733e">buffer</a></td></tr>
+<tr><td class="mdescLeft">&nbsp;</td><td class="mdescRight">The working buffer. <a href="#afc56b6252bd75ec87edec5c80a5c733e"></a><br/></td></tr>
+<tr><td class="memItemLeft" align="right" valign="top"><a class="anchor" id="ad1392f74681fd839482d0b87ca2e404e"></a><!-- doxytag: member="yaml_parser_s::unread" ref="ad1392f74681fd839482d0b87ca2e404e" args="" -->
+size_t&nbsp;</td><td class="memItemRight" valign="bottom"><b>unread</b></td></tr>
+<tr><td class="memItemLeft" >struct {</td></tr>
+<tr><td class="memItemLeft" >&nbsp;&nbsp;&nbsp;unsigned char *&nbsp;&nbsp;&nbsp;<a class="el" href="structyaml__parser__s.html#a6c08a94c21dfe1611c0d89aef0d3c46d">start</a></td></tr>
+<tr><td class="mdescLeft">&nbsp;</td><td class="mdescRight">The beginning of the buffer. <a href="#a1daeb12d14760b585f67e46fd3e3e10b"></a><br/></td></tr>
+<tr><td class="memItemLeft" >&nbsp;&nbsp;&nbsp;unsigned char *&nbsp;&nbsp;&nbsp;<a class="el" href="structyaml__parser__s.html#aa768a9c29ae2c3015fdb84ea313844e2">end</a></td></tr>
+<tr><td class="mdescLeft">&nbsp;</td><td class="mdescRight">The end of the buffer. <a href="#aa6e3b009a73e00ad57f678ea5399f74e"></a><br/></td></tr>
+<tr><td class="memItemLeft" >&nbsp;&nbsp;&nbsp;unsigned char *&nbsp;&nbsp;&nbsp;<a class="el" href="structyaml__parser__s.html#abea626790abfbcaeeb72a3772dc69e43">pointer</a></td></tr>
+<tr><td class="mdescLeft">&nbsp;</td><td class="mdescRight">The current position of the buffer. <a href="#a67e4a62d614c7fb41ec7c8a8850b5f84"></a><br/></td></tr>
+<tr><td class="memItemLeft" >&nbsp;&nbsp;&nbsp;unsigned char *&nbsp;&nbsp;&nbsp;<a class="el" href="structyaml__parser__s.html#a3ad1ccaf979092ece82bc981c5a22fb0">last</a></td></tr>
+<tr><td class="mdescLeft">&nbsp;</td><td class="mdescRight">The last filled position of the buffer. <a href="#a82350d65a4f39d40bba0939a2fe9d1f0"></a><br/></td></tr>
+<tr><td class="memItemLeft" valign="top">}&nbsp;</td><td class="memItemRight" valign="bottom"><a class="el" href="structyaml__parser__s.html#ae3e8481ceabdbf6796a7dc6265f740ac">raw_buffer</a></td></tr>
+<tr><td class="mdescLeft">&nbsp;</td><td class="mdescRight">The raw buffer. <a href="#ae3e8481ceabdbf6796a7dc6265f740ac"></a><br/></td></tr>
+<tr><td class="memItemLeft" align="right" valign="top"><a class="el" href="group__basic.html#ga2170996d7e636397b5e6bc0c1b7df7c6">yaml_encoding_t</a>&nbsp;</td><td class="memItemRight" valign="bottom"><a class="el" href="structyaml__parser__s.html#a4f062e9d1fb1082bbf3996e46214905a">encoding</a></td></tr>
+<tr><td class="mdescLeft">&nbsp;</td><td class="mdescRight">The input encoding. <a href="#a4f062e9d1fb1082bbf3996e46214905a"></a><br/></td></tr>
+<tr><td class="memItemLeft" align="right" valign="top">size_t&nbsp;</td><td class="memItemRight" valign="bottom"><a class="el" href="structyaml__parser__s.html#a04a7ba684ce49b2300c236c561439b13">offset</a></td></tr>
+<tr><td class="mdescLeft">&nbsp;</td><td class="mdescRight">The offset of the current position (in bytes). <a href="#a04a7ba684ce49b2300c236c561439b13"></a><br/></td></tr>
+<tr><td class="memItemLeft" align="right" valign="top"><a class="el" href="structyaml__mark__s.html">yaml_mark_t</a>&nbsp;</td><td class="memItemRight" valign="bottom"><a class="el" href="structyaml__parser__s.html#aaeeb58dc348e6e6f89d6a7c8fea8f734">mark</a></td></tr>
+<tr><td class="mdescLeft">&nbsp;</td><td class="mdescRight">The mark of the current position. <a href="#aaeeb58dc348e6e6f89d6a7c8fea8f734"></a><br/></td></tr>
+<tr><td colspan="2"><div class="groupHeader">Scanner stuff</div></td></tr>
+<tr><td colspan="2"><div class="groupText"><p><a class="anchor" id="amgrpfb195ad33d77c2be631ff24fdf0cfc3a"></a> </p>
+</div></td></tr>
+<tr><td class="memItemLeft" align="right" valign="top"><a class="anchor" id="a7fecde5abcce11406c271f7db08f7a05"></a><!-- doxytag: member="yaml_parser_s::stream_start_produced" ref="a7fecde5abcce11406c271f7db08f7a05" args="" -->
+int&nbsp;</td><td class="memItemRight" valign="bottom"><a class="el" href="structyaml__parser__s.html#a7fecde5abcce11406c271f7db08f7a05">stream_start_produced</a></td></tr>
+<tr><td class="mdescLeft">&nbsp;</td><td class="mdescRight">Have we started to scan the input stream? <br/></td></tr>
+<tr><td class="memItemLeft" align="right" valign="top"><a class="anchor" id="a63ccf04d623f36c04b62cfd1fc6fccb5"></a><!-- doxytag: member="yaml_parser_s::stream_end_produced" ref="a63ccf04d623f36c04b62cfd1fc6fccb5" args="" -->
+int&nbsp;</td><td class="memItemRight" valign="bottom"><a class="el" href="structyaml__parser__s.html#a63ccf04d623f36c04b62cfd1fc6fccb5">stream_end_produced</a></td></tr>
+<tr><td class="mdescLeft">&nbsp;</td><td class="mdescRight">Have we reached the end of the input stream? <br/></td></tr>
+<tr><td class="memItemLeft" align="right" valign="top">int&nbsp;</td><td class="memItemRight" valign="bottom"><a class="el" href="structyaml__parser__s.html#a6a4bbbd3f58533e0969b7218c1e73fd4">flow_level</a></td></tr>
+<tr><td class="mdescLeft">&nbsp;</td><td class="mdescRight">The number of unclosed '[' and '{' indicators. <a href="#a6a4bbbd3f58533e0969b7218c1e73fd4"></a><br/></td></tr>
+<tr><td class="memItemLeft" >struct {</td></tr>
+<tr><td class="memItemLeft" >&nbsp;&nbsp;&nbsp;<a class="el" href="structyaml__token__s.html">yaml_token_t</a> *&nbsp;&nbsp;&nbsp;<a class="el" href="structyaml__parser__s.html#a5f33f5c8f19c1c124cba4857ab2a05c7">start</a></td></tr>
+<tr><td class="mdescLeft">&nbsp;</td><td class="mdescRight">The beginning of the tokens queue. <a href="#a9c6fc4c0a8fd8dcf961aac909acb7718"></a><br/></td></tr>
+<tr><td class="memItemLeft" >&nbsp;&nbsp;&nbsp;<a class="el" href="structyaml__token__s.html">yaml_token_t</a> *&nbsp;&nbsp;&nbsp;<a class="el" href="structyaml__parser__s.html#a41594b6495f4d31edb977cafb8cbaf78">end</a></td></tr>
+<tr><td class="mdescLeft">&nbsp;</td><td class="mdescRight">The end of the tokens queue. <a href="#a481c1f8e677db68faec1db4749808507"></a><br/></td></tr>
+<tr><td class="memItemLeft" >&nbsp;&nbsp;&nbsp;<a class="el" href="structyaml__token__s.html">yaml_token_t</a> *&nbsp;&nbsp;&nbsp;<a class="el" href="structyaml__parser__s.html#aa1c7a1248ca22159a3e60ba45b386507">head</a></td></tr>
+<tr><td class="mdescLeft">&nbsp;</td><td class="mdescRight">The head of the tokens queue. <a href="#a3751871749eab9bc74641b0ca9cf3ba5"></a><br/></td></tr>
+<tr><td class="memItemLeft" >&nbsp;&nbsp;&nbsp;<a class="el" href="structyaml__token__s.html">yaml_token_t</a> *&nbsp;&nbsp;&nbsp;<a class="el" href="structyaml__parser__s.html#a22ad26583d8d1264e982188358aa79b6">tail</a></td></tr>
+<tr><td class="mdescLeft">&nbsp;</td><td class="mdescRight">The tail of the tokens queue. <a href="#a015c56f37ac5f07d28ab57bbe7ba1d52"></a><br/></td></tr>
+<tr><td class="memItemLeft" valign="top">}&nbsp;</td><td class="memItemRight" valign="bottom"><a class="el" href="structyaml__parser__s.html#a96d39b8333411d741ee1c13aa4141682">tokens</a></td></tr>
+<tr><td class="mdescLeft">&nbsp;</td><td class="mdescRight">The tokens queue. <a href="#a96d39b8333411d741ee1c13aa4141682"></a><br/></td></tr>
+<tr><td class="memItemLeft" align="right" valign="top">size_t&nbsp;</td><td class="memItemRight" valign="bottom"><a class="el" href="structyaml__parser__s.html#a7358e72ad071fec3185a833a3a245690">tokens_parsed</a></td></tr>
+<tr><td class="mdescLeft">&nbsp;</td><td class="mdescRight">The number of tokens fetched from the queue. <a href="#a7358e72ad071fec3185a833a3a245690"></a><br/></td></tr>
+<tr><td class="memItemLeft" align="right" valign="top"><a class="anchor" id="a9b7d951a1195653cc109c1c54b4dacdc"></a><!-- doxytag: member="yaml_parser_s::token_available" ref="a9b7d951a1195653cc109c1c54b4dacdc" args="" -->
+int&nbsp;</td><td class="memItemRight" valign="bottom"><b>token_available</b></td></tr>
+<tr><td class="memItemLeft" >struct {</td></tr>
+<tr><td class="memItemLeft" >&nbsp;&nbsp;&nbsp;int *&nbsp;&nbsp;&nbsp;<a class="el" href="structyaml__parser__s.html#ab7208590a6852001ff8e4343a97b0c24">start</a></td></tr>
+<tr><td class="mdescLeft">&nbsp;</td><td class="mdescRight">The beginning of the stack. <a href="#a44803ad89b68920a090e136086a20fd2"></a><br/></td></tr>
+<tr><td class="memItemLeft" >&nbsp;&nbsp;&nbsp;int *&nbsp;&nbsp;&nbsp;<a class="el" href="structyaml__parser__s.html#a6d8295bd62c7bb7be9486a1b4d71e736">end</a></td></tr>
+<tr><td class="mdescLeft">&nbsp;</td><td class="mdescRight">The end of the stack. <a href="#a28604e312c434fce97e454b8936b42f1"></a><br/></td></tr>
+<tr><td class="memItemLeft" >&nbsp;&nbsp;&nbsp;int *&nbsp;&nbsp;&nbsp;<a class="el" href="structyaml__parser__s.html#a9f1f879ba84bc51fa8feb1f47190aa23">top</a></td></tr>
+<tr><td class="mdescLeft">&nbsp;</td><td class="mdescRight">The top of the stack. <a href="#a987982928ff91538d6048f90549348d9"></a><br/></td></tr>
+<tr><td class="memItemLeft" valign="top">}&nbsp;</td><td class="memItemRight" valign="bottom"><a class="el" href="structyaml__parser__s.html#a2e29feac36a89f644d9640d44df62b74">indents</a></td></tr>
+<tr><td class="mdescLeft">&nbsp;</td><td class="mdescRight">The indentation levels stack. <a href="#a2e29feac36a89f644d9640d44df62b74"></a><br/></td></tr>
+<tr><td class="memItemLeft" align="right" valign="top">int&nbsp;</td><td class="memItemRight" valign="bottom"><a class="el" href="structyaml__parser__s.html#abad00703b649df32ee0d7b00b2f10403">indent</a></td></tr>
+<tr><td class="mdescLeft">&nbsp;</td><td class="mdescRight">The current indentation level. <a href="#abad00703b649df32ee0d7b00b2f10403"></a><br/></td></tr>
+<tr><td class="memItemLeft" align="right" valign="top"><a class="anchor" id="acc85a7bfddc7ae9114cf115e43c89126"></a><!-- doxytag: member="yaml_parser_s::simple_key_allowed" ref="acc85a7bfddc7ae9114cf115e43c89126" args="" -->
+int&nbsp;</td><td class="memItemRight" valign="bottom"><a class="el" href="structyaml__parser__s.html#acc85a7bfddc7ae9114cf115e43c89126">simple_key_allowed</a></td></tr>
+<tr><td class="mdescLeft">&nbsp;</td><td class="mdescRight">May a simple key occur at the current position? <br/></td></tr>
+<tr><td class="memItemLeft" >struct {</td></tr>
+<tr><td class="memItemLeft" >&nbsp;&nbsp;&nbsp;<a class="el" href="structyaml__simple__key__s.html">yaml_simple_key_t</a> *&nbsp;&nbsp;&nbsp;<a class="el" href="structyaml__parser__s.html#ac311a6d962e0f67dd11759b8999630c6">start</a></td></tr>
+<tr><td class="mdescLeft">&nbsp;</td><td class="mdescRight">The beginning of the stack. <a href="#a414c3c0d12344dde24703dfd9a844e23"></a><br/></td></tr>
+<tr><td class="memItemLeft" >&nbsp;&nbsp;&nbsp;<a class="el" href="structyaml__simple__key__s.html">yaml_simple_key_t</a> *&nbsp;&nbsp;&nbsp;<a class="el" href="structyaml__parser__s.html#ae8416ffcb48c78a575ee21872d5aa698">end</a></td></tr>
+<tr><td class="mdescLeft">&nbsp;</td><td class="mdescRight">The end of the stack. <a href="#a5ad9bad1923052d8eff04a5631d7b5da"></a><br/></td></tr>
+<tr><td class="memItemLeft" >&nbsp;&nbsp;&nbsp;<a class="el" href="structyaml__simple__key__s.html">yaml_simple_key_t</a> *&nbsp;&nbsp;&nbsp;<a class="el" href="structyaml__parser__s.html#ae610673669f06d46146198a346796276">top</a></td></tr>
+<tr><td class="mdescLeft">&nbsp;</td><td class="mdescRight">The top of the stack. <a href="#a4a17211b35ee7f7d885902ebf13c9426"></a><br/></td></tr>
+<tr><td class="memItemLeft" valign="top">}&nbsp;</td><td class="memItemRight" valign="bottom"><a class="el" href="structyaml__parser__s.html#ad5ce7de476c58fb6e1fdabbcc1c51659">simple_keys</a></td></tr>
+<tr><td class="mdescLeft">&nbsp;</td><td class="mdescRight">The stack of simple keys. <a href="#ad5ce7de476c58fb6e1fdabbcc1c51659"></a><br/></td></tr>
+<tr><td colspan="2"><div class="groupHeader">Parser stuff</div></td></tr>
+<tr><td colspan="2"><div class="groupText"><p><a class="anchor" id="amgrpe542ea8734d95b6b32a66b2e35c2d9ea"></a> </p>
+</div></td></tr>
+<tr><td class="memItemLeft" >struct {</td></tr>
+<tr><td class="memItemLeft" >&nbsp;&nbsp;&nbsp;<a class="el" href="group__parser.html#ga52b56d3e3cee0f9ba460978802a8c83b">yaml_parser_state_t</a> *&nbsp;&nbsp;&nbsp;<a class="el" href="structyaml__parser__s.html#adfdc33f6f53dce4bee87f11821d879b7">start</a></td></tr>
+<tr><td class="mdescLeft">&nbsp;</td><td class="mdescRight">The beginning of the stack. <a href="#afff2e238e449c67833f741ae6e2d124d"></a><br/></td></tr>
+<tr><td class="memItemLeft" >&nbsp;&nbsp;&nbsp;<a class="el" href="group__parser.html#ga52b56d3e3cee0f9ba460978802a8c83b">yaml_parser_state_t</a> *&nbsp;&nbsp;&nbsp;<a class="el" href="structyaml__parser__s.html#a211a0aedc964ba8cd07cb7875faa464b">end</a></td></tr>
+<tr><td class="mdescLeft">&nbsp;</td><td class="mdescRight">The end of the stack. <a href="#a6e334a3d6d88644cea2f791810bad09d"></a><br/></td></tr>
+<tr><td class="memItemLeft" >&nbsp;&nbsp;&nbsp;<a class="el" href="group__parser.html#ga52b56d3e3cee0f9ba460978802a8c83b">yaml_parser_state_t</a> *&nbsp;&nbsp;&nbsp;<a class="el" href="structyaml__parser__s.html#af3eecdcdeeb183d16e4219749620df0c">top</a></td></tr>
+<tr><td class="mdescLeft">&nbsp;</td><td class="mdescRight">The top of the stack. <a href="#a60349e05e14b4e2a33270ef54cb872ce"></a><br/></td></tr>
+<tr><td class="memItemLeft" valign="top">}&nbsp;</td><td class="memItemRight" valign="bottom"><a class="el" href="structyaml__parser__s.html#a57aa3c5fbfcaed8c17e046f0778c92bf">states</a></td></tr>
+<tr><td class="mdescLeft">&nbsp;</td><td class="mdescRight">The parser states stack. <a href="#a57aa3c5fbfcaed8c17e046f0778c92bf"></a><br/></td></tr>
+<tr><td class="memItemLeft" align="right" valign="top"><a class="el" href="group__parser.html#ga52b56d3e3cee0f9ba460978802a8c83b">yaml_parser_state_t</a>&nbsp;</td><td class="memItemRight" valign="bottom"><a class="el" href="structyaml__parser__s.html#a069d39cdf587ac2188e69d8fb018be64">state</a></td></tr>
+<tr><td class="mdescLeft">&nbsp;</td><td class="mdescRight">The current parser state. <a href="#a069d39cdf587ac2188e69d8fb018be64"></a><br/></td></tr>
+<tr><td class="memItemLeft" >struct {</td></tr>
+<tr><td class="memItemLeft" >&nbsp;&nbsp;&nbsp;<a class="el" href="structyaml__mark__s.html">yaml_mark_t</a> *&nbsp;&nbsp;&nbsp;<a class="el" href="structyaml__parser__s.html#ab5a3789882819f2fd69f2cd9deaac8f6">start</a></td></tr>
+<tr><td class="mdescLeft">&nbsp;</td><td class="mdescRight">The beginning of the stack. <a href="#a938eb2080b4e7e2da3203d3786d328fb"></a><br/></td></tr>
+<tr><td class="memItemLeft" >&nbsp;&nbsp;&nbsp;<a class="el" href="structyaml__mark__s.html">yaml_mark_t</a> *&nbsp;&nbsp;&nbsp;<a class="el" href="structyaml__parser__s.html#aad019da255ea73adf31d4b1aeac86bb2">end</a></td></tr>
+<tr><td class="mdescLeft">&nbsp;</td><td class="mdescRight">The end of the stack. <a href="#a2443b99c701a8318bab9287c78b3d80d"></a><br/></td></tr>
+<tr><td class="memItemLeft" >&nbsp;&nbsp;&nbsp;<a class="el" href="structyaml__mark__s.html">yaml_mark_t</a> *&nbsp;&nbsp;&nbsp;<a class="el" href="structyaml__parser__s.html#ab2678112fd2eaa8f588f2d6217aabc9d">top</a></td></tr>
+<tr><td class="mdescLeft">&nbsp;</td><td class="mdescRight">The top of the stack. <a href="#ad5872b2645fb5b6787fe457e37d22744"></a><br/></td></tr>
+<tr><td class="memItemLeft" valign="top">}&nbsp;</td><td class="memItemRight" valign="bottom"><a class="el" href="structyaml__parser__s.html#ad78837ae36e35d523e02c43d1ae3f30e">marks</a></td></tr>
+<tr><td class="mdescLeft">&nbsp;</td><td class="mdescRight">The stack of marks. <a href="#ad78837ae36e35d523e02c43d1ae3f30e"></a><br/></td></tr>
+<tr><td class="memItemLeft" >struct {</td></tr>
+<tr><td class="memItemLeft" >&nbsp;&nbsp;&nbsp;<a class="el" href="structyaml__tag__directive__s.html">yaml_tag_directive_t</a> *&nbsp;&nbsp;&nbsp;<a class="el" href="structyaml__parser__s.html#a3614f6d6e673e8177e4555c9ecf830fb">start</a></td></tr>
+<tr><td class="mdescLeft">&nbsp;</td><td class="mdescRight">The beginning of the list. <a href="#a497da4ab8dcb95fe2fb1bde052937ca0"></a><br/></td></tr>
+<tr><td class="memItemLeft" >&nbsp;&nbsp;&nbsp;<a class="el" href="structyaml__tag__directive__s.html">yaml_tag_directive_t</a> *&nbsp;&nbsp;&nbsp;<a class="el" href="structyaml__parser__s.html#aa7fdc1ff8342636119934ac824a2ecc8">end</a></td></tr>
+<tr><td class="mdescLeft">&nbsp;</td><td class="mdescRight">The end of the list. <a href="#a35efde4cda0469376a15ee2b687b64c5"></a><br/></td></tr>
+<tr><td class="memItemLeft" >&nbsp;&nbsp;&nbsp;<a class="el" href="structyaml__tag__directive__s.html">yaml_tag_directive_t</a> *&nbsp;&nbsp;&nbsp;<a class="el" href="structyaml__parser__s.html#a490eddbfcc27787e47de631a3d2e09a8">top</a></td></tr>
+<tr><td class="mdescLeft">&nbsp;</td><td class="mdescRight">The top of the list. <a href="#a534e281da90863c1026de3d0c35ab2be"></a><br/></td></tr>
+<tr><td class="memItemLeft" valign="top">}&nbsp;</td><td class="memItemRight" valign="bottom"><a class="el" href="structyaml__parser__s.html#a9bdfc1888d4e30ffb43146377d44fba0">tag_directives</a></td></tr>
+<tr><td class="mdescLeft">&nbsp;</td><td class="mdescRight">The list of TAG directives. <a href="#a9bdfc1888d4e30ffb43146377d44fba0"></a><br/></td></tr>
+<tr><td colspan="2"><div class="groupHeader">Dumper stuff</div></td></tr>
+<tr><td colspan="2"><div class="groupText"><p><a class="anchor" id="amgrp07d3f44098630ad2efbb005f4d3493a8"></a> </p>
+</div></td></tr>
+<tr><td class="memItemLeft" >struct {</td></tr>
+<tr><td class="memItemLeft" >&nbsp;&nbsp;&nbsp;<a class="el" href="structyaml__alias__data__s.html">yaml_alias_data_t</a> *&nbsp;&nbsp;&nbsp;<a class="el" href="structyaml__parser__s.html#ab9eddd3a112c3a4547bf87f6936aba94">start</a></td></tr>
+<tr><td class="mdescLeft">&nbsp;</td><td class="mdescRight">The beginning of the list. <a href="#a476e5ca1bf38f2e545ee4f1a183ef5b9"></a><br/></td></tr>
+<tr><td class="memItemLeft" >&nbsp;&nbsp;&nbsp;<a class="el" href="structyaml__alias__data__s.html">yaml_alias_data_t</a> *&nbsp;&nbsp;&nbsp;<a class="el" href="structyaml__parser__s.html#a4011d41483171958bbf0b5124bde97c8">end</a></td></tr>
+<tr><td class="mdescLeft">&nbsp;</td><td class="mdescRight">The end of the list. <a href="#a7ef3b21719ac6a28c50e5db67d9453ce"></a><br/></td></tr>
+<tr><td class="memItemLeft" >&nbsp;&nbsp;&nbsp;<a class="el" href="structyaml__alias__data__s.html">yaml_alias_data_t</a> *&nbsp;&nbsp;&nbsp;<a class="el" href="structyaml__parser__s.html#a24a3f3138b44de1914a3e54dbe0aeff7">top</a></td></tr>
+<tr><td class="mdescLeft">&nbsp;</td><td class="mdescRight">The top of the list. <a href="#a834b2dd0efe6d80cdb1138d737605421"></a><br/></td></tr>
+<tr><td class="memItemLeft" valign="top">}&nbsp;</td><td class="memItemRight" valign="bottom"><a class="el" href="structyaml__parser__s.html#a0c10698207d727f9e5d9ced627d130ef">aliases</a></td></tr>
+<tr><td class="mdescLeft">&nbsp;</td><td class="mdescRight">The alias data. <a href="#a0c10698207d727f9e5d9ced627d130ef"></a><br/></td></tr>
+<tr><td class="memItemLeft" align="right" valign="top"><a class="el" href="structyaml__document__s.html">yaml_document_t</a> *&nbsp;</td><td class="memItemRight" valign="bottom"><a class="el" href="structyaml__parser__s.html#ac3dad5822f49d86cfddc2e5e415a158c">document</a></td></tr>
+<tr><td class="mdescLeft">&nbsp;</td><td class="mdescRight">The currently parsed document. <a href="#ac3dad5822f49d86cfddc2e5e415a158c"></a><br/></td></tr>
+</table>
+<hr/><a name="_details"></a><h2>Detailed Description</h2>
+<p>The parser structure. </p>
+<p>All members are internal. Manage the structure using the <code>yaml_parser_</code> family of functions. </p>
+<hr/><h2>Field Documentation</h2>
+<a class="anchor" id="a6c5c3488ff22c8a4d234ca8587fa1472"></a><!-- doxytag: member="yaml_parser_s::error" ref="a6c5c3488ff22c8a4d234ca8587fa1472" args="" -->
+<div class="memitem">
+<div class="memproto">
+ <table class="memname">
+ <tr>
+ <td class="memname"><a class="el" href="group__basic.html#ga1a449f0c1b023e2ef1a596093c018e73">yaml_error_type_t</a> <a class="el" href="structyaml__parser__s.html#a6c5c3488ff22c8a4d234ca8587fa1472">yaml_parser_s::error</a></td>
+ </tr>
+ </table>
+</div>
+<div class="memdoc">
+
+<p>Error type. </p>
+
+</div>
+</div>
+<a class="anchor" id="a3dd8a43294cd420a433595a7a7d6e73d"></a><!-- doxytag: member="yaml_parser_s::problem" ref="a3dd8a43294cd420a433595a7a7d6e73d" args="" -->
+<div class="memitem">
+<div class="memproto">
+ <table class="memname">
+ <tr>
+ <td class="memname">const char* <a class="el" href="structyaml__parser__s.html#a3dd8a43294cd420a433595a7a7d6e73d">yaml_parser_s::problem</a></td>
+ </tr>
+ </table>
+</div>
+<div class="memdoc">
+
+<p>Error description. </p>
+
+</div>
+</div>
+<a class="anchor" id="ae2d62a2ad45671c6dd89e18fb7c1c5bd"></a><!-- doxytag: member="yaml_parser_s::problem_offset" ref="ae2d62a2ad45671c6dd89e18fb7c1c5bd" args="" -->
+<div class="memitem">
+<div class="memproto">
+ <table class="memname">
+ <tr>
+ <td class="memname">size_t <a class="el" href="structyaml__parser__s.html#ae2d62a2ad45671c6dd89e18fb7c1c5bd">yaml_parser_s::problem_offset</a></td>
+ </tr>
+ </table>
+</div>
+<div class="memdoc">
+
+<p>The byte about which the problem occured. </p>
+
+</div>
+</div>
+<a class="anchor" id="a8694691b20824f6595873b728cb3bc0f"></a><!-- doxytag: member="yaml_parser_s::problem_value" ref="a8694691b20824f6595873b728cb3bc0f" args="" -->
+<div class="memitem">
+<div class="memproto">
+ <table class="memname">
+ <tr>
+ <td class="memname">int <a class="el" href="structyaml__parser__s.html#a8694691b20824f6595873b728cb3bc0f">yaml_parser_s::problem_value</a></td>
+ </tr>
+ </table>
+</div>
+<div class="memdoc">
+
+<p>The problematic value (<code>-1</code> is none). </p>
+
+</div>
+</div>
+<a class="anchor" id="a595b5412d39a4a9e441e5ad34fb059d9"></a><!-- doxytag: member="yaml_parser_s::problem_mark" ref="a595b5412d39a4a9e441e5ad34fb059d9" args="" -->
+<div class="memitem">
+<div class="memproto">
+ <table class="memname">
+ <tr>
+ <td class="memname"><a class="el" href="structyaml__mark__s.html">yaml_mark_t</a> <a class="el" href="structyaml__parser__s.html#a595b5412d39a4a9e441e5ad34fb059d9">yaml_parser_s::problem_mark</a></td>
+ </tr>
+ </table>
+</div>
+<div class="memdoc">
+
+<p>The problem position. </p>
+
+</div>
+</div>
+<a class="anchor" id="a6779b67a23bbf7c401e4257d5875ae6b"></a><!-- doxytag: member="yaml_parser_s::context" ref="a6779b67a23bbf7c401e4257d5875ae6b" args="" -->
+<div class="memitem">
+<div class="memproto">
+ <table class="memname">
+ <tr>
+ <td class="memname">const char* <a class="el" href="structyaml__parser__s.html#a6779b67a23bbf7c401e4257d5875ae6b">yaml_parser_s::context</a></td>
+ </tr>
+ </table>
+</div>
+<div class="memdoc">
+
+<p>The error context. </p>
+
+</div>
+</div>
+<a class="anchor" id="ace259eec6e570f94b98b252e1a632e88"></a><!-- doxytag: member="yaml_parser_s::context_mark" ref="ace259eec6e570f94b98b252e1a632e88" args="" -->
+<div class="memitem">
+<div class="memproto">
+ <table class="memname">
+ <tr>
+ <td class="memname"><a class="el" href="structyaml__mark__s.html">yaml_mark_t</a> <a class="el" href="structyaml__parser__s.html#ace259eec6e570f94b98b252e1a632e88">yaml_parser_s::context_mark</a></td>
+ </tr>
+ </table>
+</div>
+<div class="memdoc">
+
+<p>The context position. </p>
+
+</div>
+</div>
+<a class="anchor" id="a8c3af47a7a0750d437cba34699fcad30"></a><!-- doxytag: member="yaml_parser_s::read_handler" ref="a8c3af47a7a0750d437cba34699fcad30" args="" -->
+<div class="memitem">
+<div class="memproto">
+ <table class="memname">
+ <tr>
+ <td class="memname"><a class="el" href="group__parser.html#ga4982f7e4e001ddb47d2819f38f0cd9d6">yaml_read_handler_t</a>* <a class="el" href="structyaml__parser__s.html#a8c3af47a7a0750d437cba34699fcad30">yaml_parser_s::read_handler</a></td>
+ </tr>
+ </table>
+</div>
+<div class="memdoc">
+
+<p>Read handler. </p>
+
+</div>
+</div>
+<a class="anchor" id="a11f265cd495e814c8ee7d3dd78ff2ca9"></a><!-- doxytag: member="yaml_parser_s::read_handler_data" ref="a11f265cd495e814c8ee7d3dd78ff2ca9" args="" -->
+<div class="memitem">
+<div class="memproto">
+ <table class="memname">
+ <tr>
+ <td class="memname">void* <a class="el" href="structyaml__parser__s.html#a11f265cd495e814c8ee7d3dd78ff2ca9">yaml_parser_s::read_handler_data</a></td>
+ </tr>
+ </table>
+</div>
+<div class="memdoc">
+
+<p>A pointer for passing to the read handler. </p>
+
+</div>
+</div>
+<a class="anchor" id="a8cdb2fed4bb17b1d62d29fa06c53fef6"></a><!-- doxytag: member="yaml_parser_s::start" ref="a8cdb2fed4bb17b1d62d29fa06c53fef6" args="" -->
+<div class="memitem">
+<div class="memproto">
+ <table class="memname">
+ <tr>
+ <td class="memname">const unsigned char* <a class="el" href="structyaml__parser__s.html#a8cdb2fed4bb17b1d62d29fa06c53fef6">yaml_parser_s::start</a></td>
+ </tr>
+ </table>
+</div>
+<div class="memdoc">
+
+<p>The string start pointer. </p>
+
+</div>
+</div>
+<a class="anchor" id="aad74ffeb7f2eef0a12e34b0aac263ff3"></a><!-- doxytag: member="yaml_parser_s::end" ref="aad74ffeb7f2eef0a12e34b0aac263ff3" args="" -->
+<div class="memitem">
+<div class="memproto">
+ <table class="memname">
+ <tr>
+ <td class="memname">const unsigned char* <a class="el" href="structyaml__parser__s.html#aad74ffeb7f2eef0a12e34b0aac263ff3">yaml_parser_s::end</a></td>
+ </tr>
+ </table>
+</div>
+<div class="memdoc">
+
+<p>The string end pointer. </p>
+
+</div>
+</div>
+<a class="anchor" id="a3406d2ba7e969c09344d4ced8c855007"></a><!-- doxytag: member="yaml_parser_s::current" ref="a3406d2ba7e969c09344d4ced8c855007" args="" -->
+<div class="memitem">
+<div class="memproto">
+ <table class="memname">
+ <tr>
+ <td class="memname">const unsigned char* <a class="el" href="structyaml__parser__s.html#a3406d2ba7e969c09344d4ced8c855007">yaml_parser_s::current</a></td>
+ </tr>
+ </table>
+</div>
+<div class="memdoc">
+
+<p>The string current position. </p>
+
+</div>
+</div>
+<a class="anchor" id="a44fa7ca68030680244f3743ce5e35702"></a><!-- doxytag: member="yaml_parser_s::string" ref="a44fa7ca68030680244f3743ce5e35702" args="" -->
+<div class="memitem">
+<div class="memproto">
+ <table class="memname">
+ <tr>
+ <td class="memname">struct { ... } <a class="el" href="structyaml__parser__s.html#a44fa7ca68030680244f3743ce5e35702">yaml_parser_s::string</a></td>
+ </tr>
+ </table>
+</div>
+<div class="memdoc">
+
+<p>String input data. </p>
+
+</div>
+</div>
+<a class="anchor" id="ae69c2974e3c4c37e941a0e1971be15a9"></a><!-- doxytag: member="yaml_parser_s::file" ref="ae69c2974e3c4c37e941a0e1971be15a9" args="" -->
+<div class="memitem">
+<div class="memproto">
+ <table class="memname">
+ <tr>
+ <td class="memname">FILE* <a class="el" href="structyaml__parser__s.html#ae69c2974e3c4c37e941a0e1971be15a9">yaml_parser_s::file</a></td>
+ </tr>
+ </table>
+</div>
+<div class="memdoc">
+
+<p>File input data. </p>
+
+</div>
+</div>
+<a class="anchor" id="ae800ef7fd42ad8bcbb69b116da3a7f53"></a><!-- doxytag: member="yaml_parser_s::input" ref="ae800ef7fd42ad8bcbb69b116da3a7f53" args="" -->
+<div class="memitem">
+<div class="memproto">
+ <table class="memname">
+ <tr>
+ <td class="memname">union { ... } <a class="el" href="structyaml__parser__s.html#ae800ef7fd42ad8bcbb69b116da3a7f53">yaml_parser_s::input</a></td>
+ </tr>
+ </table>
+</div>
+<div class="memdoc">
+
+<p>Standard (string or file) input data. </p>
+
+</div>
+</div>
+<a class="anchor" id="a5cdddcbd18566acc760a660a88f93ffd"></a><!-- doxytag: member="yaml_parser_s::start" ref="a5cdddcbd18566acc760a660a88f93ffd" args="" -->
+<div class="memitem">
+<div class="memproto">
+ <table class="memname">
+ <tr>
+ <td class="memname"><a class="el" href="group__basic.html#gaf8657e81f0b8b05d1a081001fc6cb8bd">yaml_char_t</a>* <a class="el" href="structyaml__parser__s.html#a8cdb2fed4bb17b1d62d29fa06c53fef6">yaml_parser_s::start</a></td>
+ </tr>
+ </table>
+</div>
+<div class="memdoc">
+
+<p>The beginning of the buffer. </p>
+
+</div>
+</div>
+<a class="anchor" id="a6ff1f802eb95bc45f13e8e73ec009828"></a><!-- doxytag: member="yaml_parser_s::end" ref="a6ff1f802eb95bc45f13e8e73ec009828" args="" -->
+<div class="memitem">
+<div class="memproto">
+ <table class="memname">
+ <tr>
+ <td class="memname"><a class="el" href="group__basic.html#gaf8657e81f0b8b05d1a081001fc6cb8bd">yaml_char_t</a>* <a class="el" href="structyaml__parser__s.html#aad74ffeb7f2eef0a12e34b0aac263ff3">yaml_parser_s::end</a></td>
+ </tr>
+ </table>
+</div>
+<div class="memdoc">
+
+<p>The end of the buffer. </p>
+
+</div>
+</div>
+<a class="anchor" id="a8199466e3578374b3f984b6c0c4e2ae4"></a><!-- doxytag: member="yaml_parser_s::pointer" ref="a8199466e3578374b3f984b6c0c4e2ae4" args="" -->
+<div class="memitem">
+<div class="memproto">
+ <table class="memname">
+ <tr>
+ <td class="memname"><a class="el" href="group__basic.html#gaf8657e81f0b8b05d1a081001fc6cb8bd">yaml_char_t</a>* <a class="el" href="structyaml__parser__s.html#a8199466e3578374b3f984b6c0c4e2ae4">yaml_parser_s::pointer</a></td>
+ </tr>
+ </table>
+</div>
+<div class="memdoc">
+
+<p>The current position of the buffer. </p>
+
+</div>
+</div>
+<a class="anchor" id="aea4d8da24939825b2fadd368a71ec7de"></a><!-- doxytag: member="yaml_parser_s::last" ref="aea4d8da24939825b2fadd368a71ec7de" args="" -->
+<div class="memitem">
+<div class="memproto">
+ <table class="memname">
+ <tr>
+ <td class="memname"><a class="el" href="group__basic.html#gaf8657e81f0b8b05d1a081001fc6cb8bd">yaml_char_t</a>* <a class="el" href="structyaml__parser__s.html#aea4d8da24939825b2fadd368a71ec7de">yaml_parser_s::last</a></td>
+ </tr>
+ </table>
+</div>
+<div class="memdoc">
+
+<p>The last filled position of the buffer. </p>
+
+</div>
+</div>
+<a class="anchor" id="afc56b6252bd75ec87edec5c80a5c733e"></a><!-- doxytag: member="yaml_parser_s::buffer" ref="afc56b6252bd75ec87edec5c80a5c733e" args="" -->
+<div class="memitem">
+<div class="memproto">
+ <table class="memname">
+ <tr>
+ <td class="memname">struct { ... } <a class="el" href="structyaml__parser__s.html#afc56b6252bd75ec87edec5c80a5c733e">yaml_parser_s::buffer</a></td>
+ </tr>
+ </table>
+</div>
+<div class="memdoc">
+
+<p>The working buffer. </p>
+
+</div>
+</div>
+<a class="anchor" id="a6c08a94c21dfe1611c0d89aef0d3c46d"></a><!-- doxytag: member="yaml_parser_s::start" ref="a6c08a94c21dfe1611c0d89aef0d3c46d" args="" -->
+<div class="memitem">
+<div class="memproto">
+ <table class="memname">
+ <tr>
+ <td class="memname">unsigned char* <a class="el" href="structyaml__parser__s.html#a8cdb2fed4bb17b1d62d29fa06c53fef6">yaml_parser_s::start</a></td>
+ </tr>
+ </table>
+</div>
+<div class="memdoc">
+
+<p>The beginning of the buffer. </p>
+
+</div>
+</div>
+<a class="anchor" id="aa768a9c29ae2c3015fdb84ea313844e2"></a><!-- doxytag: member="yaml_parser_s::end" ref="aa768a9c29ae2c3015fdb84ea313844e2" args="" -->
+<div class="memitem">
+<div class="memproto">
+ <table class="memname">
+ <tr>
+ <td class="memname">unsigned char* <a class="el" href="structyaml__parser__s.html#aad74ffeb7f2eef0a12e34b0aac263ff3">yaml_parser_s::end</a></td>
+ </tr>
+ </table>
+</div>
+<div class="memdoc">
+
+<p>The end of the buffer. </p>
+
+</div>
+</div>
+<a class="anchor" id="abea626790abfbcaeeb72a3772dc69e43"></a><!-- doxytag: member="yaml_parser_s::pointer" ref="abea626790abfbcaeeb72a3772dc69e43" args="" -->
+<div class="memitem">
+<div class="memproto">
+ <table class="memname">
+ <tr>
+ <td class="memname">unsigned char* <a class="el" href="structyaml__parser__s.html#a8199466e3578374b3f984b6c0c4e2ae4">yaml_parser_s::pointer</a></td>
+ </tr>
+ </table>
+</div>
+<div class="memdoc">
+
+<p>The current position of the buffer. </p>
+
+</div>
+</div>
+<a class="anchor" id="a3ad1ccaf979092ece82bc981c5a22fb0"></a><!-- doxytag: member="yaml_parser_s::last" ref="a3ad1ccaf979092ece82bc981c5a22fb0" args="" -->
+<div class="memitem">
+<div class="memproto">
+ <table class="memname">
+ <tr>
+ <td class="memname">unsigned char* <a class="el" href="structyaml__parser__s.html#aea4d8da24939825b2fadd368a71ec7de">yaml_parser_s::last</a></td>
+ </tr>
+ </table>
+</div>
+<div class="memdoc">
+
+<p>The last filled position of the buffer. </p>
+
+</div>
+</div>
+<a class="anchor" id="ae3e8481ceabdbf6796a7dc6265f740ac"></a><!-- doxytag: member="yaml_parser_s::raw_buffer" ref="ae3e8481ceabdbf6796a7dc6265f740ac" args="" -->
+<div class="memitem">
+<div class="memproto">
+ <table class="memname">
+ <tr>
+ <td class="memname">struct { ... } <a class="el" href="structyaml__parser__s.html#ae3e8481ceabdbf6796a7dc6265f740ac">yaml_parser_s::raw_buffer</a></td>
+ </tr>
+ </table>
+</div>
+<div class="memdoc">
+
+<p>The raw buffer. </p>
+
+</div>
+</div>
+<a class="anchor" id="a4f062e9d1fb1082bbf3996e46214905a"></a><!-- doxytag: member="yaml_parser_s::encoding" ref="a4f062e9d1fb1082bbf3996e46214905a" args="" -->
+<div class="memitem">
+<div class="memproto">
+ <table class="memname">
+ <tr>
+ <td class="memname"><a class="el" href="group__basic.html#ga2170996d7e636397b5e6bc0c1b7df7c6">yaml_encoding_t</a> <a class="el" href="structyaml__parser__s.html#a4f062e9d1fb1082bbf3996e46214905a">yaml_parser_s::encoding</a></td>
+ </tr>
+ </table>
+</div>
+<div class="memdoc">
+
+<p>The input encoding. </p>
+
+</div>
+</div>
+<a class="anchor" id="a04a7ba684ce49b2300c236c561439b13"></a><!-- doxytag: member="yaml_parser_s::offset" ref="a04a7ba684ce49b2300c236c561439b13" args="" -->
+<div class="memitem">
+<div class="memproto">
+ <table class="memname">
+ <tr>
+ <td class="memname">size_t <a class="el" href="structyaml__parser__s.html#a04a7ba684ce49b2300c236c561439b13">yaml_parser_s::offset</a></td>
+ </tr>
+ </table>
+</div>
+<div class="memdoc">
+
+<p>The offset of the current position (in bytes). </p>
+
+</div>
+</div>
+<a class="anchor" id="aaeeb58dc348e6e6f89d6a7c8fea8f734"></a><!-- doxytag: member="yaml_parser_s::mark" ref="aaeeb58dc348e6e6f89d6a7c8fea8f734" args="" -->
+<div class="memitem">
+<div class="memproto">
+ <table class="memname">
+ <tr>
+ <td class="memname"><a class="el" href="structyaml__mark__s.html">yaml_mark_t</a> <a class="el" href="structyaml__parser__s.html#aaeeb58dc348e6e6f89d6a7c8fea8f734">yaml_parser_s::mark</a></td>
+ </tr>
+ </table>
+</div>
+<div class="memdoc">
+
+<p>The mark of the current position. </p>
+
+</div>
+</div>
+<a class="anchor" id="a6a4bbbd3f58533e0969b7218c1e73fd4"></a><!-- doxytag: member="yaml_parser_s::flow_level" ref="a6a4bbbd3f58533e0969b7218c1e73fd4" args="" -->
+<div class="memitem">
+<div class="memproto">
+ <table class="memname">
+ <tr>
+ <td class="memname">int <a class="el" href="structyaml__parser__s.html#a6a4bbbd3f58533e0969b7218c1e73fd4">yaml_parser_s::flow_level</a></td>
+ </tr>
+ </table>
+</div>
+<div class="memdoc">
+
+<p>The number of unclosed '[' and '{' indicators. </p>
+
+</div>
+</div>
+<a class="anchor" id="a5f33f5c8f19c1c124cba4857ab2a05c7"></a><!-- doxytag: member="yaml_parser_s::start" ref="a5f33f5c8f19c1c124cba4857ab2a05c7" args="" -->
+<div class="memitem">
+<div class="memproto">
+ <table class="memname">
+ <tr>
+ <td class="memname"><a class="el" href="structyaml__token__s.html">yaml_token_t</a>* <a class="el" href="structyaml__parser__s.html#a8cdb2fed4bb17b1d62d29fa06c53fef6">yaml_parser_s::start</a></td>
+ </tr>
+ </table>
+</div>
+<div class="memdoc">
+
+<p>The beginning of the tokens queue. </p>
+
+</div>
+</div>
+<a class="anchor" id="a41594b6495f4d31edb977cafb8cbaf78"></a><!-- doxytag: member="yaml_parser_s::end" ref="a41594b6495f4d31edb977cafb8cbaf78" args="" -->
+<div class="memitem">
+<div class="memproto">
+ <table class="memname">
+ <tr>
+ <td class="memname"><a class="el" href="structyaml__token__s.html">yaml_token_t</a>* <a class="el" href="structyaml__parser__s.html#aad74ffeb7f2eef0a12e34b0aac263ff3">yaml_parser_s::end</a></td>
+ </tr>
+ </table>
+</div>
+<div class="memdoc">
+
+<p>The end of the tokens queue. </p>
+
+</div>
+</div>
+<a class="anchor" id="aa1c7a1248ca22159a3e60ba45b386507"></a><!-- doxytag: member="yaml_parser_s::head" ref="aa1c7a1248ca22159a3e60ba45b386507" args="" -->
+<div class="memitem">
+<div class="memproto">
+ <table class="memname">
+ <tr>
+ <td class="memname"><a class="el" href="structyaml__token__s.html">yaml_token_t</a>* <a class="el" href="structyaml__parser__s.html#aa1c7a1248ca22159a3e60ba45b386507">yaml_parser_s::head</a></td>
+ </tr>
+ </table>
+</div>
+<div class="memdoc">
+
+<p>The head of the tokens queue. </p>
+
+</div>
+</div>
+<a class="anchor" id="a22ad26583d8d1264e982188358aa79b6"></a><!-- doxytag: member="yaml_parser_s::tail" ref="a22ad26583d8d1264e982188358aa79b6" args="" -->
+<div class="memitem">
+<div class="memproto">
+ <table class="memname">
+ <tr>
+ <td class="memname"><a class="el" href="structyaml__token__s.html">yaml_token_t</a>* <a class="el" href="structyaml__parser__s.html#a22ad26583d8d1264e982188358aa79b6">yaml_parser_s::tail</a></td>
+ </tr>
+ </table>
+</div>
+<div class="memdoc">
+
+<p>The tail of the tokens queue. </p>
+
+</div>
+</div>
+<a class="anchor" id="a96d39b8333411d741ee1c13aa4141682"></a><!-- doxytag: member="yaml_parser_s::tokens" ref="a96d39b8333411d741ee1c13aa4141682" args="" -->
+<div class="memitem">
+<div class="memproto">
+ <table class="memname">
+ <tr>
+ <td class="memname">struct { ... } <a class="el" href="structyaml__parser__s.html#a96d39b8333411d741ee1c13aa4141682">yaml_parser_s::tokens</a></td>
+ </tr>
+ </table>
+</div>
+<div class="memdoc">
+
+<p>The tokens queue. </p>
+
+</div>
+</div>
+<a class="anchor" id="a7358e72ad071fec3185a833a3a245690"></a><!-- doxytag: member="yaml_parser_s::tokens_parsed" ref="a7358e72ad071fec3185a833a3a245690" args="" -->
+<div class="memitem">
+<div class="memproto">
+ <table class="memname">
+ <tr>
+ <td class="memname">size_t <a class="el" href="structyaml__parser__s.html#a7358e72ad071fec3185a833a3a245690">yaml_parser_s::tokens_parsed</a></td>
+ </tr>
+ </table>
+</div>
+<div class="memdoc">
+
+<p>The number of tokens fetched from the queue. </p>
+
+</div>
+</div>
+<a class="anchor" id="ab7208590a6852001ff8e4343a97b0c24"></a><!-- doxytag: member="yaml_parser_s::start" ref="ab7208590a6852001ff8e4343a97b0c24" args="" -->
+<div class="memitem">
+<div class="memproto">
+ <table class="memname">
+ <tr>
+ <td class="memname">int* <a class="el" href="structyaml__parser__s.html#a8cdb2fed4bb17b1d62d29fa06c53fef6">yaml_parser_s::start</a></td>
+ </tr>
+ </table>
+</div>
+<div class="memdoc">
+
+<p>The beginning of the stack. </p>
+
+</div>
+</div>
+<a class="anchor" id="a6d8295bd62c7bb7be9486a1b4d71e736"></a><!-- doxytag: member="yaml_parser_s::end" ref="a6d8295bd62c7bb7be9486a1b4d71e736" args="" -->
+<div class="memitem">
+<div class="memproto">
+ <table class="memname">
+ <tr>
+ <td class="memname">int* <a class="el" href="structyaml__parser__s.html#aad74ffeb7f2eef0a12e34b0aac263ff3">yaml_parser_s::end</a></td>
+ </tr>
+ </table>
+</div>
+<div class="memdoc">
+
+<p>The end of the stack. </p>
+
+</div>
+</div>
+<a class="anchor" id="a9f1f879ba84bc51fa8feb1f47190aa23"></a><!-- doxytag: member="yaml_parser_s::top" ref="a9f1f879ba84bc51fa8feb1f47190aa23" args="" -->
+<div class="memitem">
+<div class="memproto">
+ <table class="memname">
+ <tr>
+ <td class="memname">int* <a class="el" href="structyaml__parser__s.html#a9f1f879ba84bc51fa8feb1f47190aa23">yaml_parser_s::top</a></td>
+ </tr>
+ </table>
+</div>
+<div class="memdoc">
+
+<p>The top of the stack. </p>
+
+</div>
+</div>
+<a class="anchor" id="a2e29feac36a89f644d9640d44df62b74"></a><!-- doxytag: member="yaml_parser_s::indents" ref="a2e29feac36a89f644d9640d44df62b74" args="" -->
+<div class="memitem">
+<div class="memproto">
+ <table class="memname">
+ <tr>
+ <td class="memname">struct { ... } <a class="el" href="structyaml__parser__s.html#a2e29feac36a89f644d9640d44df62b74">yaml_parser_s::indents</a></td>
+ </tr>
+ </table>
+</div>
+<div class="memdoc">
+
+<p>The indentation levels stack. </p>
+
+</div>
+</div>
+<a class="anchor" id="abad00703b649df32ee0d7b00b2f10403"></a><!-- doxytag: member="yaml_parser_s::indent" ref="abad00703b649df32ee0d7b00b2f10403" args="" -->
+<div class="memitem">
+<div class="memproto">
+ <table class="memname">
+ <tr>
+ <td class="memname">int <a class="el" href="structyaml__parser__s.html#abad00703b649df32ee0d7b00b2f10403">yaml_parser_s::indent</a></td>
+ </tr>
+ </table>
+</div>
+<div class="memdoc">
+
+<p>The current indentation level. </p>
+
+</div>
+</div>
+<a class="anchor" id="ac311a6d962e0f67dd11759b8999630c6"></a><!-- doxytag: member="yaml_parser_s::start" ref="ac311a6d962e0f67dd11759b8999630c6" args="" -->
+<div class="memitem">
+<div class="memproto">
+ <table class="memname">
+ <tr>
+ <td class="memname"><a class="el" href="structyaml__simple__key__s.html">yaml_simple_key_t</a>* <a class="el" href="structyaml__parser__s.html#a8cdb2fed4bb17b1d62d29fa06c53fef6">yaml_parser_s::start</a></td>
+ </tr>
+ </table>
+</div>
+<div class="memdoc">
+
+<p>The beginning of the stack. </p>
+
+</div>
+</div>
+<a class="anchor" id="ae8416ffcb48c78a575ee21872d5aa698"></a><!-- doxytag: member="yaml_parser_s::end" ref="ae8416ffcb48c78a575ee21872d5aa698" args="" -->
+<div class="memitem">
+<div class="memproto">
+ <table class="memname">
+ <tr>
+ <td class="memname"><a class="el" href="structyaml__simple__key__s.html">yaml_simple_key_t</a>* <a class="el" href="structyaml__parser__s.html#aad74ffeb7f2eef0a12e34b0aac263ff3">yaml_parser_s::end</a></td>
+ </tr>
+ </table>
+</div>
+<div class="memdoc">
+
+<p>The end of the stack. </p>
+
+</div>
+</div>
+<a class="anchor" id="ae610673669f06d46146198a346796276"></a><!-- doxytag: member="yaml_parser_s::top" ref="ae610673669f06d46146198a346796276" args="" -->
+<div class="memitem">
+<div class="memproto">
+ <table class="memname">
+ <tr>
+ <td class="memname"><a class="el" href="structyaml__simple__key__s.html">yaml_simple_key_t</a>* <a class="el" href="structyaml__parser__s.html#a9f1f879ba84bc51fa8feb1f47190aa23">yaml_parser_s::top</a></td>
+ </tr>
+ </table>
+</div>
+<div class="memdoc">
+
+<p>The top of the stack. </p>
+
+</div>
+</div>
+<a class="anchor" id="ad5ce7de476c58fb6e1fdabbcc1c51659"></a><!-- doxytag: member="yaml_parser_s::simple_keys" ref="ad5ce7de476c58fb6e1fdabbcc1c51659" args="" -->
+<div class="memitem">
+<div class="memproto">
+ <table class="memname">
+ <tr>
+ <td class="memname">struct { ... } <a class="el" href="structyaml__parser__s.html#ad5ce7de476c58fb6e1fdabbcc1c51659">yaml_parser_s::simple_keys</a></td>
+ </tr>
+ </table>
+</div>
+<div class="memdoc">
+
+<p>The stack of simple keys. </p>
+
+</div>
+</div>
+<a class="anchor" id="adfdc33f6f53dce4bee87f11821d879b7"></a><!-- doxytag: member="yaml_parser_s::start" ref="adfdc33f6f53dce4bee87f11821d879b7" args="" -->
+<div class="memitem">
+<div class="memproto">
+ <table class="memname">
+ <tr>
+ <td class="memname"><a class="el" href="group__parser.html#ga52b56d3e3cee0f9ba460978802a8c83b">yaml_parser_state_t</a>* <a class="el" href="structyaml__parser__s.html#a8cdb2fed4bb17b1d62d29fa06c53fef6">yaml_parser_s::start</a></td>
+ </tr>
+ </table>
+</div>
+<div class="memdoc">
+
+<p>The beginning of the stack. </p>
+
+</div>
+</div>
+<a class="anchor" id="a211a0aedc964ba8cd07cb7875faa464b"></a><!-- doxytag: member="yaml_parser_s::end" ref="a211a0aedc964ba8cd07cb7875faa464b" args="" -->
+<div class="memitem">
+<div class="memproto">
+ <table class="memname">
+ <tr>
+ <td class="memname"><a class="el" href="group__parser.html#ga52b56d3e3cee0f9ba460978802a8c83b">yaml_parser_state_t</a>* <a class="el" href="structyaml__parser__s.html#aad74ffeb7f2eef0a12e34b0aac263ff3">yaml_parser_s::end</a></td>
+ </tr>
+ </table>
+</div>
+<div class="memdoc">
+
+<p>The end of the stack. </p>
+
+</div>
+</div>
+<a class="anchor" id="af3eecdcdeeb183d16e4219749620df0c"></a><!-- doxytag: member="yaml_parser_s::top" ref="af3eecdcdeeb183d16e4219749620df0c" args="" -->
+<div class="memitem">
+<div class="memproto">
+ <table class="memname">
+ <tr>
+ <td class="memname"><a class="el" href="group__parser.html#ga52b56d3e3cee0f9ba460978802a8c83b">yaml_parser_state_t</a>* <a class="el" href="structyaml__parser__s.html#a9f1f879ba84bc51fa8feb1f47190aa23">yaml_parser_s::top</a></td>
+ </tr>
+ </table>
+</div>
+<div class="memdoc">
+
+<p>The top of the stack. </p>
+
+</div>
+</div>
+<a class="anchor" id="a57aa3c5fbfcaed8c17e046f0778c92bf"></a><!-- doxytag: member="yaml_parser_s::states" ref="a57aa3c5fbfcaed8c17e046f0778c92bf" args="" -->
+<div class="memitem">
+<div class="memproto">
+ <table class="memname">
+ <tr>
+ <td class="memname">struct { ... } <a class="el" href="structyaml__parser__s.html#a57aa3c5fbfcaed8c17e046f0778c92bf">yaml_parser_s::states</a></td>
+ </tr>
+ </table>
+</div>
+<div class="memdoc">
+
+<p>The parser states stack. </p>
+
+</div>
+</div>
+<a class="anchor" id="a069d39cdf587ac2188e69d8fb018be64"></a><!-- doxytag: member="yaml_parser_s::state" ref="a069d39cdf587ac2188e69d8fb018be64" args="" -->
+<div class="memitem">
+<div class="memproto">
+ <table class="memname">
+ <tr>
+ <td class="memname"><a class="el" href="group__parser.html#ga52b56d3e3cee0f9ba460978802a8c83b">yaml_parser_state_t</a> <a class="el" href="structyaml__parser__s.html#a069d39cdf587ac2188e69d8fb018be64">yaml_parser_s::state</a></td>
+ </tr>
+ </table>
+</div>
+<div class="memdoc">
+
+<p>The current parser state. </p>
+
+</div>
+</div>
+<a class="anchor" id="ab5a3789882819f2fd69f2cd9deaac8f6"></a><!-- doxytag: member="yaml_parser_s::start" ref="ab5a3789882819f2fd69f2cd9deaac8f6" args="" -->
+<div class="memitem">
+<div class="memproto">
+ <table class="memname">
+ <tr>
+ <td class="memname"><a class="el" href="structyaml__mark__s.html">yaml_mark_t</a>* <a class="el" href="structyaml__parser__s.html#a8cdb2fed4bb17b1d62d29fa06c53fef6">yaml_parser_s::start</a></td>
+ </tr>
+ </table>
+</div>
+<div class="memdoc">
+
+<p>The beginning of the stack. </p>
+
+</div>
+</div>
+<a class="anchor" id="aad019da255ea73adf31d4b1aeac86bb2"></a><!-- doxytag: member="yaml_parser_s::end" ref="aad019da255ea73adf31d4b1aeac86bb2" args="" -->
+<div class="memitem">
+<div class="memproto">
+ <table class="memname">
+ <tr>
+ <td class="memname"><a class="el" href="structyaml__mark__s.html">yaml_mark_t</a>* <a class="el" href="structyaml__parser__s.html#aad74ffeb7f2eef0a12e34b0aac263ff3">yaml_parser_s::end</a></td>
+ </tr>
+ </table>
+</div>
+<div class="memdoc">
+
+<p>The end of the stack. </p>
+
+</div>
+</div>
+<a class="anchor" id="ab2678112fd2eaa8f588f2d6217aabc9d"></a><!-- doxytag: member="yaml_parser_s::top" ref="ab2678112fd2eaa8f588f2d6217aabc9d" args="" -->
+<div class="memitem">
+<div class="memproto">
+ <table class="memname">
+ <tr>
+ <td class="memname"><a class="el" href="structyaml__mark__s.html">yaml_mark_t</a>* <a class="el" href="structyaml__parser__s.html#a9f1f879ba84bc51fa8feb1f47190aa23">yaml_parser_s::top</a></td>
+ </tr>
+ </table>
+</div>
+<div class="memdoc">
+
+<p>The top of the stack. </p>
+
+</div>
+</div>
+<a class="anchor" id="ad78837ae36e35d523e02c43d1ae3f30e"></a><!-- doxytag: member="yaml_parser_s::marks" ref="ad78837ae36e35d523e02c43d1ae3f30e" args="" -->
+<div class="memitem">
+<div class="memproto">
+ <table class="memname">
+ <tr>
+ <td class="memname">struct { ... } <a class="el" href="structyaml__parser__s.html#ad78837ae36e35d523e02c43d1ae3f30e">yaml_parser_s::marks</a></td>
+ </tr>
+ </table>
+</div>
+<div class="memdoc">
+
+<p>The stack of marks. </p>
+
+</div>
+</div>
+<a class="anchor" id="a3614f6d6e673e8177e4555c9ecf830fb"></a><!-- doxytag: member="yaml_parser_s::start" ref="a3614f6d6e673e8177e4555c9ecf830fb" args="" -->
+<div class="memitem">
+<div class="memproto">
+ <table class="memname">
+ <tr>
+ <td class="memname"><a class="el" href="structyaml__tag__directive__s.html">yaml_tag_directive_t</a>* <a class="el" href="structyaml__parser__s.html#a8cdb2fed4bb17b1d62d29fa06c53fef6">yaml_parser_s::start</a></td>
+ </tr>
+ </table>
+</div>
+<div class="memdoc">
+
+<p>The beginning of the list. </p>
+
+</div>
+</div>
+<a class="anchor" id="aa7fdc1ff8342636119934ac824a2ecc8"></a><!-- doxytag: member="yaml_parser_s::end" ref="aa7fdc1ff8342636119934ac824a2ecc8" args="" -->
+<div class="memitem">
+<div class="memproto">
+ <table class="memname">
+ <tr>
+ <td class="memname"><a class="el" href="structyaml__tag__directive__s.html">yaml_tag_directive_t</a>* <a class="el" href="structyaml__parser__s.html#aad74ffeb7f2eef0a12e34b0aac263ff3">yaml_parser_s::end</a></td>
+ </tr>
+ </table>
+</div>
+<div class="memdoc">
+
+<p>The end of the list. </p>
+
+</div>
+</div>
+<a class="anchor" id="a490eddbfcc27787e47de631a3d2e09a8"></a><!-- doxytag: member="yaml_parser_s::top" ref="a490eddbfcc27787e47de631a3d2e09a8" args="" -->
+<div class="memitem">
+<div class="memproto">
+ <table class="memname">
+ <tr>
+ <td class="memname"><a class="el" href="structyaml__tag__directive__s.html">yaml_tag_directive_t</a>* <a class="el" href="structyaml__parser__s.html#a9f1f879ba84bc51fa8feb1f47190aa23">yaml_parser_s::top</a></td>
+ </tr>
+ </table>
+</div>
+<div class="memdoc">
+
+<p>The top of the list. </p>
+
+</div>
+</div>
+<a class="anchor" id="a9bdfc1888d4e30ffb43146377d44fba0"></a><!-- doxytag: member="yaml_parser_s::tag_directives" ref="a9bdfc1888d4e30ffb43146377d44fba0" args="" -->
+<div class="memitem">
+<div class="memproto">
+ <table class="memname">
+ <tr>
+ <td class="memname">struct { ... } <a class="el" href="structyaml__parser__s.html#a9bdfc1888d4e30ffb43146377d44fba0">yaml_parser_s::tag_directives</a></td>
+ </tr>
+ </table>
+</div>
+<div class="memdoc">
+
+<p>The list of TAG directives. </p>
+
+</div>
+</div>
+<a class="anchor" id="ab9eddd3a112c3a4547bf87f6936aba94"></a><!-- doxytag: member="yaml_parser_s::start" ref="ab9eddd3a112c3a4547bf87f6936aba94" args="" -->
+<div class="memitem">
+<div class="memproto">
+ <table class="memname">
+ <tr>
+ <td class="memname"><a class="el" href="structyaml__alias__data__s.html">yaml_alias_data_t</a>* <a class="el" href="structyaml__parser__s.html#a8cdb2fed4bb17b1d62d29fa06c53fef6">yaml_parser_s::start</a></td>
+ </tr>
+ </table>
+</div>
+<div class="memdoc">
+
+<p>The beginning of the list. </p>
+
+</div>
+</div>
+<a class="anchor" id="a4011d41483171958bbf0b5124bde97c8"></a><!-- doxytag: member="yaml_parser_s::end" ref="a4011d41483171958bbf0b5124bde97c8" args="" -->
+<div class="memitem">
+<div class="memproto">
+ <table class="memname">
+ <tr>
+ <td class="memname"><a class="el" href="structyaml__alias__data__s.html">yaml_alias_data_t</a>* <a class="el" href="structyaml__parser__s.html#aad74ffeb7f2eef0a12e34b0aac263ff3">yaml_parser_s::end</a></td>
+ </tr>
+ </table>
+</div>
+<div class="memdoc">
+
+<p>The end of the list. </p>
+
+</div>
+</div>
+<a class="anchor" id="a24a3f3138b44de1914a3e54dbe0aeff7"></a><!-- doxytag: member="yaml_parser_s::top" ref="a24a3f3138b44de1914a3e54dbe0aeff7" args="" -->
+<div class="memitem">
+<div class="memproto">
+ <table class="memname">
+ <tr>
+ <td class="memname"><a class="el" href="structyaml__alias__data__s.html">yaml_alias_data_t</a>* <a class="el" href="structyaml__parser__s.html#a9f1f879ba84bc51fa8feb1f47190aa23">yaml_parser_s::top</a></td>
+ </tr>
+ </table>
+</div>
+<div class="memdoc">
+
+<p>The top of the list. </p>
+
+</div>
+</div>
+<a class="anchor" id="a0c10698207d727f9e5d9ced627d130ef"></a><!-- doxytag: member="yaml_parser_s::aliases" ref="a0c10698207d727f9e5d9ced627d130ef" args="" -->
+<div class="memitem">
+<div class="memproto">
+ <table class="memname">
+ <tr>
+ <td class="memname">struct { ... } <a class="el" href="structyaml__parser__s.html#a0c10698207d727f9e5d9ced627d130ef">yaml_parser_s::aliases</a></td>
+ </tr>
+ </table>
+</div>
+<div class="memdoc">
+
+<p>The alias data. </p>
+
+</div>
+</div>
+<a class="anchor" id="ac3dad5822f49d86cfddc2e5e415a158c"></a><!-- doxytag: member="yaml_parser_s::document" ref="ac3dad5822f49d86cfddc2e5e415a158c" args="" -->
+<div class="memitem">
+<div class="memproto">
+ <table class="memname">
+ <tr>
+ <td class="memname"><a class="el" href="structyaml__document__s.html">yaml_document_t</a>* <a class="el" href="structyaml__parser__s.html#ac3dad5822f49d86cfddc2e5e415a158c">yaml_parser_s::document</a></td>
+ </tr>
+ </table>
+</div>
+<div class="memdoc">
+
+<p>The currently parsed document. </p>
+
+</div>
+</div>
+<hr/>The documentation for this struct was generated from the following file:<ul>
+<li><a class="el" href="yaml_8h.html">yaml.h</a></li>
+</ul>
+</div>
+<hr class="footer"/><address class="footer"><small>Generated on Mon May 30 2011 22:00:01 for yaml by&nbsp;
+<a href="http://www.doxygen.org/index.html">
+<img class="footer" src="doxygen.png" alt="doxygen"/></a> 1.7.1 </small></address>
+</body>
+</html>
diff --git a/contrib/libyaml/doc/html/structyaml__simple__key__s.html b/contrib/libyaml/doc/html/structyaml__simple__key__s.html
new file mode 100644
index 0000000..d6e2e7a
--- /dev/null
+++ b/contrib/libyaml/doc/html/structyaml__simple__key__s.html
@@ -0,0 +1,97 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head>
+<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/>
+<title>yaml: yaml_simple_key_s Struct Reference</title>
+<link href="tabs.css" rel="stylesheet" type="text/css"/>
+<link href="doxygen.css" rel="stylesheet" type="text/css"/>
+</head>
+<body>
+<!-- Generated by Doxygen 1.7.1 -->
+<div class="navigation" id="top">
+ <div class="tabs">
+ <ul class="tablist">
+ <li><a href="index.html"><span>Main&nbsp;Page</span></a></li>
+ <li><a href="modules.html"><span>Modules</span></a></li>
+ <li class="current"><a href="annotated.html"><span>Data&nbsp;Structures</span></a></li>
+ <li><a href="files.html"><span>Files</span></a></li>
+ </ul>
+ </div>
+ <div class="tabs2">
+ <ul class="tablist">
+ <li><a href="annotated.html"><span>Data&nbsp;Structures</span></a></li>
+ <li><a href="functions.html"><span>Data&nbsp;Fields</span></a></li>
+ </ul>
+ </div>
+</div>
+<div class="header">
+ <div class="summary">
+<a href="#pub-attribs">Data Fields</a> </div>
+ <div class="headertitle">
+<h1>yaml_simple_key_s Struct Reference<br/>
+<small>
+[<a class="el" href="group__parser.html">Parser Definitions</a>]</small>
+</h1> </div>
+</div>
+<div class="contents">
+<!-- doxytag: class="yaml_simple_key_s" -->
+<p>This structure holds information about a potential simple key.
+<a href="#_details">More...</a></p>
+
+<p><code>#include &lt;yaml.h&gt;</code></p>
+<table class="memberdecls">
+<tr><td colspan="2"><h2><a name="pub-attribs"></a>
+Data Fields</h2></td></tr>
+<tr><td class="memItemLeft" align="right" valign="top"><a class="anchor" id="aad311b0fa599db04657a5177ec331f07"></a><!-- doxytag: member="yaml_simple_key_s::possible" ref="aad311b0fa599db04657a5177ec331f07" args="" -->
+int&nbsp;</td><td class="memItemRight" valign="bottom"><a class="el" href="structyaml__simple__key__s.html#aad311b0fa599db04657a5177ec331f07">possible</a></td></tr>
+<tr><td class="mdescLeft">&nbsp;</td><td class="mdescRight">Is a simple key possible? <br/></td></tr>
+<tr><td class="memItemLeft" align="right" valign="top"><a class="anchor" id="acacccea26520e74c4c61f170fdcbb4c3"></a><!-- doxytag: member="yaml_simple_key_s::required" ref="acacccea26520e74c4c61f170fdcbb4c3" args="" -->
+int&nbsp;</td><td class="memItemRight" valign="bottom"><a class="el" href="structyaml__simple__key__s.html#acacccea26520e74c4c61f170fdcbb4c3">required</a></td></tr>
+<tr><td class="mdescLeft">&nbsp;</td><td class="mdescRight">Is a simple key required? <br/></td></tr>
+<tr><td class="memItemLeft" align="right" valign="top">size_t&nbsp;</td><td class="memItemRight" valign="bottom"><a class="el" href="structyaml__simple__key__s.html#ae098916893ad7415c5c041dd45d24a86">token_number</a></td></tr>
+<tr><td class="mdescLeft">&nbsp;</td><td class="mdescRight">The number of the token. <a href="#ae098916893ad7415c5c041dd45d24a86"></a><br/></td></tr>
+<tr><td class="memItemLeft" align="right" valign="top"><a class="el" href="structyaml__mark__s.html">yaml_mark_t</a>&nbsp;</td><td class="memItemRight" valign="bottom"><a class="el" href="structyaml__simple__key__s.html#ad0f5dd11cbf2e4d6d81376511e2b6dfb">mark</a></td></tr>
+<tr><td class="mdescLeft">&nbsp;</td><td class="mdescRight">The position mark. <a href="#ad0f5dd11cbf2e4d6d81376511e2b6dfb"></a><br/></td></tr>
+</table>
+<hr/><a name="_details"></a><h2>Detailed Description</h2>
+<p>This structure holds information about a potential simple key. </p>
+<hr/><h2>Field Documentation</h2>
+<a class="anchor" id="ae098916893ad7415c5c041dd45d24a86"></a><!-- doxytag: member="yaml_simple_key_s::token_number" ref="ae098916893ad7415c5c041dd45d24a86" args="" -->
+<div class="memitem">
+<div class="memproto">
+ <table class="memname">
+ <tr>
+ <td class="memname">size_t <a class="el" href="structyaml__simple__key__s.html#ae098916893ad7415c5c041dd45d24a86">yaml_simple_key_s::token_number</a></td>
+ </tr>
+ </table>
+</div>
+<div class="memdoc">
+
+<p>The number of the token. </p>
+
+</div>
+</div>
+<a class="anchor" id="ad0f5dd11cbf2e4d6d81376511e2b6dfb"></a><!-- doxytag: member="yaml_simple_key_s::mark" ref="ad0f5dd11cbf2e4d6d81376511e2b6dfb" args="" -->
+<div class="memitem">
+<div class="memproto">
+ <table class="memname">
+ <tr>
+ <td class="memname"><a class="el" href="structyaml__mark__s.html">yaml_mark_t</a> <a class="el" href="structyaml__simple__key__s.html#ad0f5dd11cbf2e4d6d81376511e2b6dfb">yaml_simple_key_s::mark</a></td>
+ </tr>
+ </table>
+</div>
+<div class="memdoc">
+
+<p>The position mark. </p>
+
+</div>
+</div>
+<hr/>The documentation for this struct was generated from the following file:<ul>
+<li><a class="el" href="yaml_8h.html">yaml.h</a></li>
+</ul>
+</div>
+<hr class="footer"/><address class="footer"><small>Generated on Mon May 30 2011 22:00:01 for yaml by&nbsp;
+<a href="http://www.doxygen.org/index.html">
+<img class="footer" src="doxygen.png" alt="doxygen"/></a> 1.7.1 </small></address>
+</body>
+</html>
diff --git a/contrib/libyaml/doc/html/structyaml__tag__directive__s.html b/contrib/libyaml/doc/html/structyaml__tag__directive__s.html
new file mode 100644
index 0000000..3d75cae
--- /dev/null
+++ b/contrib/libyaml/doc/html/structyaml__tag__directive__s.html
@@ -0,0 +1,91 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head>
+<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/>
+<title>yaml: yaml_tag_directive_s Struct Reference</title>
+<link href="tabs.css" rel="stylesheet" type="text/css"/>
+<link href="doxygen.css" rel="stylesheet" type="text/css"/>
+</head>
+<body>
+<!-- Generated by Doxygen 1.7.1 -->
+<div class="navigation" id="top">
+ <div class="tabs">
+ <ul class="tablist">
+ <li><a href="index.html"><span>Main&nbsp;Page</span></a></li>
+ <li><a href="modules.html"><span>Modules</span></a></li>
+ <li class="current"><a href="annotated.html"><span>Data&nbsp;Structures</span></a></li>
+ <li><a href="files.html"><span>Files</span></a></li>
+ </ul>
+ </div>
+ <div class="tabs2">
+ <ul class="tablist">
+ <li><a href="annotated.html"><span>Data&nbsp;Structures</span></a></li>
+ <li><a href="functions.html"><span>Data&nbsp;Fields</span></a></li>
+ </ul>
+ </div>
+</div>
+<div class="header">
+ <div class="summary">
+<a href="#pub-attribs">Data Fields</a> </div>
+ <div class="headertitle">
+<h1>yaml_tag_directive_s Struct Reference<br/>
+<small>
+[<a class="el" href="group__basic.html">Basic Types</a>]</small>
+</h1> </div>
+</div>
+<div class="contents">
+<!-- doxytag: class="yaml_tag_directive_s" -->
+<p>The tag directive data.
+<a href="#_details">More...</a></p>
+
+<p><code>#include &lt;yaml.h&gt;</code></p>
+<table class="memberdecls">
+<tr><td colspan="2"><h2><a name="pub-attribs"></a>
+Data Fields</h2></td></tr>
+<tr><td class="memItemLeft" align="right" valign="top"><a class="el" href="group__basic.html#gaf8657e81f0b8b05d1a081001fc6cb8bd">yaml_char_t</a> *&nbsp;</td><td class="memItemRight" valign="bottom"><a class="el" href="structyaml__tag__directive__s.html#a9934c62f2b18fd087a95af25c7739490">handle</a></td></tr>
+<tr><td class="mdescLeft">&nbsp;</td><td class="mdescRight">The tag handle. <a href="#a9934c62f2b18fd087a95af25c7739490"></a><br/></td></tr>
+<tr><td class="memItemLeft" align="right" valign="top"><a class="el" href="group__basic.html#gaf8657e81f0b8b05d1a081001fc6cb8bd">yaml_char_t</a> *&nbsp;</td><td class="memItemRight" valign="bottom"><a class="el" href="structyaml__tag__directive__s.html#a514850fefaafbe65b2322da8c193a896">prefix</a></td></tr>
+<tr><td class="mdescLeft">&nbsp;</td><td class="mdescRight">The tag prefix. <a href="#a514850fefaafbe65b2322da8c193a896"></a><br/></td></tr>
+</table>
+<hr/><a name="_details"></a><h2>Detailed Description</h2>
+<p>The tag directive data. </p>
+<hr/><h2>Field Documentation</h2>
+<a class="anchor" id="a9934c62f2b18fd087a95af25c7739490"></a><!-- doxytag: member="yaml_tag_directive_s::handle" ref="a9934c62f2b18fd087a95af25c7739490" args="" -->
+<div class="memitem">
+<div class="memproto">
+ <table class="memname">
+ <tr>
+ <td class="memname"><a class="el" href="group__basic.html#gaf8657e81f0b8b05d1a081001fc6cb8bd">yaml_char_t</a>* <a class="el" href="structyaml__tag__directive__s.html#a9934c62f2b18fd087a95af25c7739490">yaml_tag_directive_s::handle</a></td>
+ </tr>
+ </table>
+</div>
+<div class="memdoc">
+
+<p>The tag handle. </p>
+
+</div>
+</div>
+<a class="anchor" id="a514850fefaafbe65b2322da8c193a896"></a><!-- doxytag: member="yaml_tag_directive_s::prefix" ref="a514850fefaafbe65b2322da8c193a896" args="" -->
+<div class="memitem">
+<div class="memproto">
+ <table class="memname">
+ <tr>
+ <td class="memname"><a class="el" href="group__basic.html#gaf8657e81f0b8b05d1a081001fc6cb8bd">yaml_char_t</a>* <a class="el" href="structyaml__tag__directive__s.html#a514850fefaafbe65b2322da8c193a896">yaml_tag_directive_s::prefix</a></td>
+ </tr>
+ </table>
+</div>
+<div class="memdoc">
+
+<p>The tag prefix. </p>
+
+</div>
+</div>
+<hr/>The documentation for this struct was generated from the following file:<ul>
+<li><a class="el" href="yaml_8h.html">yaml.h</a></li>
+</ul>
+</div>
+<hr class="footer"/><address class="footer"><small>Generated on Mon May 30 2011 22:00:01 for yaml by&nbsp;
+<a href="http://www.doxygen.org/index.html">
+<img class="footer" src="doxygen.png" alt="doxygen"/></a> 1.7.1 </small></address>
+</body>
+</html>
diff --git a/contrib/libyaml/doc/html/structyaml__token__s.html b/contrib/libyaml/doc/html/structyaml__token__s.html
new file mode 100644
index 0000000..95326d4
--- /dev/null
+++ b/contrib/libyaml/doc/html/structyaml__token__s.html
@@ -0,0 +1,413 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head>
+<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/>
+<title>yaml: yaml_token_s Struct Reference</title>
+<link href="tabs.css" rel="stylesheet" type="text/css"/>
+<link href="doxygen.css" rel="stylesheet" type="text/css"/>
+</head>
+<body>
+<!-- Generated by Doxygen 1.7.1 -->
+<div class="navigation" id="top">
+ <div class="tabs">
+ <ul class="tablist">
+ <li><a href="index.html"><span>Main&nbsp;Page</span></a></li>
+ <li><a href="modules.html"><span>Modules</span></a></li>
+ <li class="current"><a href="annotated.html"><span>Data&nbsp;Structures</span></a></li>
+ <li><a href="files.html"><span>Files</span></a></li>
+ </ul>
+ </div>
+ <div class="tabs2">
+ <ul class="tablist">
+ <li><a href="annotated.html"><span>Data&nbsp;Structures</span></a></li>
+ <li><a href="functions.html"><span>Data&nbsp;Fields</span></a></li>
+ </ul>
+ </div>
+</div>
+<div class="header">
+ <div class="summary">
+<a href="#pub-attribs">Data Fields</a> </div>
+ <div class="headertitle">
+<h1>yaml_token_s Struct Reference<br/>
+<small>
+[<a class="el" href="group__tokens.html">Tokens</a>]</small>
+</h1> </div>
+</div>
+<div class="contents">
+<!-- doxytag: class="yaml_token_s" -->
+<p>The token structure.
+<a href="#_details">More...</a></p>
+
+<p><code>#include &lt;yaml.h&gt;</code></p>
+<table class="memberdecls">
+<tr><td colspan="2"><h2><a name="pub-attribs"></a>
+Data Fields</h2></td></tr>
+<tr><td class="memItemLeft" align="right" valign="top"><a class="el" href="group__tokens.html#gaba51dda022dced02f8df2224ab7993f7">yaml_token_type_t</a>&nbsp;</td><td class="memItemRight" valign="bottom"><a class="el" href="structyaml__token__s.html#aa8aeb89e2e74f5e2f199484177d0ea14">type</a></td></tr>
+<tr><td class="mdescLeft">&nbsp;</td><td class="mdescRight">The token type. <a href="#aa8aeb89e2e74f5e2f199484177d0ea14"></a><br/></td></tr>
+<tr><td class="memItemLeft" >union {</td></tr>
+<tr><td class="memItemLeft" >&nbsp;&nbsp;&nbsp;struct {</td></tr>
+<tr><td class="memItemLeft" >&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<a class="el" href="group__basic.html#ga2170996d7e636397b5e6bc0c1b7df7c6">yaml_encoding_t</a>&nbsp;&nbsp;&nbsp;<a class="el" href="structyaml__token__s.html#aab75b9cb91438e0e1efe2522652cf478">encoding</a></td></tr>
+<tr><td class="mdescLeft">&nbsp;</td><td class="mdescRight">The stream encoding. <a href="#acf58af547ea8738fdacec6203bf36181"></a><br/></td></tr>
+<tr><td class="memItemLeft" valign="top">&nbsp;&nbsp;&nbsp;}&nbsp;&nbsp;&nbsp;<a class="el" href="structyaml__token__s.html#aab66b62f4507f4fd0e9d2b7548f588e6">stream_start</a></td></tr>
+<tr><td class="mdescLeft">&nbsp;</td><td class="mdescRight">The stream start (for <code>YAML_STREAM_START_TOKEN</code>). <a href="#adb58948fd65e0ea196efc9b86d45e3b4"></a><br/></td></tr>
+<tr><td class="memItemLeft" >&nbsp;&nbsp;&nbsp;struct {</td></tr>
+<tr><td class="memItemLeft" >&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<a class="el" href="group__basic.html#gaf8657e81f0b8b05d1a081001fc6cb8bd">yaml_char_t</a> *&nbsp;&nbsp;&nbsp;<a class="el" href="structyaml__token__s.html#a97ce52329d6093b63fba36817f8bd549">value</a></td></tr>
+<tr><td class="mdescLeft">&nbsp;</td><td class="mdescRight">The alias value. <a href="#a0c1e109d2ef827b8ff3c6039f1ab5304"></a><br/></td></tr>
+<tr><td class="memItemLeft" valign="top">&nbsp;&nbsp;&nbsp;}&nbsp;&nbsp;&nbsp;<a class="el" href="structyaml__token__s.html#a1f942353efa1972a38a0763afefabe0c">alias</a></td></tr>
+<tr><td class="mdescLeft">&nbsp;</td><td class="mdescRight">The alias (for <code>YAML_ALIAS_TOKEN</code>). <a href="#ab4bd38c29f849e26e58d917e22b802c4"></a><br/></td></tr>
+<tr><td class="memItemLeft" >&nbsp;&nbsp;&nbsp;struct {</td></tr>
+<tr><td class="memItemLeft" >&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<a class="el" href="group__basic.html#gaf8657e81f0b8b05d1a081001fc6cb8bd">yaml_char_t</a> *&nbsp;&nbsp;&nbsp;<a class="el" href="structyaml__token__s.html#a97ce52329d6093b63fba36817f8bd549">value</a></td></tr>
+<tr><td class="mdescLeft">&nbsp;</td><td class="mdescRight">The anchor value. <a href="#ad1f0eeb2d39e429a3aa58a945d3024e9"></a><br/></td></tr>
+<tr><td class="memItemLeft" valign="top">&nbsp;&nbsp;&nbsp;}&nbsp;&nbsp;&nbsp;<a class="el" href="structyaml__token__s.html#acc0f6636995f5fe332604b74571e6cfa">anchor</a></td></tr>
+<tr><td class="mdescLeft">&nbsp;</td><td class="mdescRight">The anchor (for <code>YAML_ANCHOR_TOKEN</code>). <a href="#a6dc7c18502384e0ee0b1e5b152e5a36e"></a><br/></td></tr>
+<tr><td class="memItemLeft" >&nbsp;&nbsp;&nbsp;struct {</td></tr>
+<tr><td class="memItemLeft" >&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<a class="el" href="group__basic.html#gaf8657e81f0b8b05d1a081001fc6cb8bd">yaml_char_t</a> *&nbsp;&nbsp;&nbsp;<a class="el" href="structyaml__token__s.html#a01665687653c945a6666dd9debaecd65">handle</a></td></tr>
+<tr><td class="mdescLeft">&nbsp;</td><td class="mdescRight">The tag handle. <a href="#a5c3336fcd32c354305a2a03eb628ce9a"></a><br/></td></tr>
+<tr><td class="memItemLeft" >&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<a class="el" href="group__basic.html#gaf8657e81f0b8b05d1a081001fc6cb8bd">yaml_char_t</a> *&nbsp;&nbsp;&nbsp;<a class="el" href="structyaml__token__s.html#a61344c49b73da5821cb06cab4cbab505">suffix</a></td></tr>
+<tr><td class="mdescLeft">&nbsp;</td><td class="mdescRight">The tag suffix. <a href="#af361bdbfd57dfbd0fd8e913ec45bc31d"></a><br/></td></tr>
+<tr><td class="memItemLeft" valign="top">&nbsp;&nbsp;&nbsp;}&nbsp;&nbsp;&nbsp;<a class="el" href="structyaml__token__s.html#ab281db5b7563c5489726768fe0fbaac7">tag</a></td></tr>
+<tr><td class="mdescLeft">&nbsp;</td><td class="mdescRight">The tag (for <code>YAML_TAG_TOKEN</code>). <a href="#a95c8695bfca2ebef6b09b2319fd9f85c"></a><br/></td></tr>
+<tr><td class="memItemLeft" >&nbsp;&nbsp;&nbsp;struct {</td></tr>
+<tr><td class="memItemLeft" >&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<a class="el" href="group__basic.html#gaf8657e81f0b8b05d1a081001fc6cb8bd">yaml_char_t</a> *&nbsp;&nbsp;&nbsp;<a class="el" href="structyaml__token__s.html#a97ce52329d6093b63fba36817f8bd549">value</a></td></tr>
+<tr><td class="mdescLeft">&nbsp;</td><td class="mdescRight">The scalar value. <a href="#a6d5102b2d4c24ccfe2b31b5fd68c1c27"></a><br/></td></tr>
+<tr><td class="memItemLeft" >&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;size_t&nbsp;&nbsp;&nbsp;<a class="el" href="structyaml__token__s.html#a06e51daf74cf78103e00608c3c9132e2">length</a></td></tr>
+<tr><td class="mdescLeft">&nbsp;</td><td class="mdescRight">The length of the scalar value. <a href="#a2d7788630968cb11c8a23a741225fafb"></a><br/></td></tr>
+<tr><td class="memItemLeft" >&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<a class="el" href="group__styles.html#ga3fa6405631e1afe5bd5c488a6c5e8065">yaml_scalar_style_t</a>&nbsp;&nbsp;&nbsp;<a class="el" href="structyaml__token__s.html#a530a8c4d78feaf5496fb9f461674382b">style</a></td></tr>
+<tr><td class="mdescLeft">&nbsp;</td><td class="mdescRight">The scalar style. <a href="#aa351d3a0dfa05dcb5f4fe32b2ec17ee8"></a><br/></td></tr>
+<tr><td class="memItemLeft" valign="top">&nbsp;&nbsp;&nbsp;}&nbsp;&nbsp;&nbsp;<a class="el" href="structyaml__token__s.html#a35e3629351176dd91b38cbfc827a8b00">scalar</a></td></tr>
+<tr><td class="mdescLeft">&nbsp;</td><td class="mdescRight">The scalar value (for <code>YAML_SCALAR_TOKEN</code>). <a href="#a79006467d4e0499e9e40c90c372001fa"></a><br/></td></tr>
+<tr><td class="memItemLeft" >&nbsp;&nbsp;&nbsp;struct {</td></tr>
+<tr><td class="memItemLeft" >&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;int&nbsp;&nbsp;&nbsp;<a class="el" href="structyaml__token__s.html#aac2ed466afd0390872774238dfcd152c">major</a></td></tr>
+<tr><td class="mdescLeft">&nbsp;</td><td class="mdescRight">The major version number. <a href="#a3203d856f6a5009df37e4930069f1937"></a><br/></td></tr>
+<tr><td class="memItemLeft" >&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;int&nbsp;&nbsp;&nbsp;<a class="el" href="structyaml__token__s.html#a97b9f537b24e8413e9fddc6a4b183d30">minor</a></td></tr>
+<tr><td class="mdescLeft">&nbsp;</td><td class="mdescRight">The minor version number. <a href="#aa7c8fc59e31a6687eaf21bb22f734f98"></a><br/></td></tr>
+<tr><td class="memItemLeft" valign="top">&nbsp;&nbsp;&nbsp;}&nbsp;&nbsp;&nbsp;<a class="el" href="structyaml__token__s.html#a41b30a59ca22d1020d6af4cc7cc0da47">version_directive</a></td></tr>
+<tr><td class="mdescLeft">&nbsp;</td><td class="mdescRight">The version directive (for <code>YAML_VERSION_DIRECTIVE_TOKEN</code>). <a href="#a25a5300107549a7b1ad7c32b69df26e4"></a><br/></td></tr>
+<tr><td class="memItemLeft" >&nbsp;&nbsp;&nbsp;struct {</td></tr>
+<tr><td class="memItemLeft" >&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<a class="el" href="group__basic.html#gaf8657e81f0b8b05d1a081001fc6cb8bd">yaml_char_t</a> *&nbsp;&nbsp;&nbsp;<a class="el" href="structyaml__token__s.html#a01665687653c945a6666dd9debaecd65">handle</a></td></tr>
+<tr><td class="mdescLeft">&nbsp;</td><td class="mdescRight">The tag handle. <a href="#a6bfa655778494408d518fc3cbf89dd97"></a><br/></td></tr>
+<tr><td class="memItemLeft" >&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<a class="el" href="group__basic.html#gaf8657e81f0b8b05d1a081001fc6cb8bd">yaml_char_t</a> *&nbsp;&nbsp;&nbsp;<a class="el" href="structyaml__token__s.html#a561b3730b9999cfe1010e77aca49c5b8">prefix</a></td></tr>
+<tr><td class="mdescLeft">&nbsp;</td><td class="mdescRight">The tag prefix. <a href="#a0c67ae3b7638531ee9efc8bd102ac723"></a><br/></td></tr>
+<tr><td class="memItemLeft" valign="top">&nbsp;&nbsp;&nbsp;}&nbsp;&nbsp;&nbsp;<a class="el" href="structyaml__token__s.html#aa8a1b9eeee539233e8461773894f4ea0">tag_directive</a></td></tr>
+<tr><td class="mdescLeft">&nbsp;</td><td class="mdescRight">The tag directive (for <code>YAML_TAG_DIRECTIVE_TOKEN</code>). <a href="#a677d9e84bc7535dc814556c4624c61db"></a><br/></td></tr>
+<tr><td class="memItemLeft" valign="top">}&nbsp;</td><td class="memItemRight" valign="bottom"><a class="el" href="structyaml__token__s.html#aedb5be9b6b8f5ef6c129575e84f63605">data</a></td></tr>
+<tr><td class="mdescLeft">&nbsp;</td><td class="mdescRight">The token data. <a href="#aedb5be9b6b8f5ef6c129575e84f63605"></a><br/></td></tr>
+<tr><td class="memItemLeft" align="right" valign="top"><a class="el" href="structyaml__mark__s.html">yaml_mark_t</a>&nbsp;</td><td class="memItemRight" valign="bottom"><a class="el" href="structyaml__token__s.html#abdc5f4f2059c5a7bfe8e810b49a53980">start_mark</a></td></tr>
+<tr><td class="mdescLeft">&nbsp;</td><td class="mdescRight">The beginning of the token. <a href="#abdc5f4f2059c5a7bfe8e810b49a53980"></a><br/></td></tr>
+<tr><td class="memItemLeft" align="right" valign="top"><a class="el" href="structyaml__mark__s.html">yaml_mark_t</a>&nbsp;</td><td class="memItemRight" valign="bottom"><a class="el" href="structyaml__token__s.html#a97f08b38dfb0a5be26ef8831864a5311">end_mark</a></td></tr>
+<tr><td class="mdescLeft">&nbsp;</td><td class="mdescRight">The end of the token. <a href="#a97f08b38dfb0a5be26ef8831864a5311"></a><br/></td></tr>
+</table>
+<hr/><a name="_details"></a><h2>Detailed Description</h2>
+<p>The token structure. </p>
+<hr/><h2>Field Documentation</h2>
+<a class="anchor" id="aa8aeb89e2e74f5e2f199484177d0ea14"></a><!-- doxytag: member="yaml_token_s::type" ref="aa8aeb89e2e74f5e2f199484177d0ea14" args="" -->
+<div class="memitem">
+<div class="memproto">
+ <table class="memname">
+ <tr>
+ <td class="memname"><a class="el" href="group__tokens.html#gaba51dda022dced02f8df2224ab7993f7">yaml_token_type_t</a> <a class="el" href="structyaml__token__s.html#aa8aeb89e2e74f5e2f199484177d0ea14">yaml_token_s::type</a></td>
+ </tr>
+ </table>
+</div>
+<div class="memdoc">
+
+<p>The token type. </p>
+
+</div>
+</div>
+<a class="anchor" id="aab75b9cb91438e0e1efe2522652cf478"></a><!-- doxytag: member="yaml_token_s::encoding" ref="aab75b9cb91438e0e1efe2522652cf478" args="" -->
+<div class="memitem">
+<div class="memproto">
+ <table class="memname">
+ <tr>
+ <td class="memname"><a class="el" href="group__basic.html#ga2170996d7e636397b5e6bc0c1b7df7c6">yaml_encoding_t</a> <a class="el" href="structyaml__token__s.html#aab75b9cb91438e0e1efe2522652cf478">yaml_token_s::encoding</a></td>
+ </tr>
+ </table>
+</div>
+<div class="memdoc">
+
+<p>The stream encoding. </p>
+
+</div>
+</div>
+<a class="anchor" id="aab66b62f4507f4fd0e9d2b7548f588e6"></a><!-- doxytag: member="yaml_token_s::stream_start" ref="aab66b62f4507f4fd0e9d2b7548f588e6" args="" -->
+<div class="memitem">
+<div class="memproto">
+ <table class="memname">
+ <tr>
+ <td class="memname">struct { ... } <a class="el" href="structyaml__token__s.html#aab66b62f4507f4fd0e9d2b7548f588e6">yaml_token_s::stream_start</a></td>
+ </tr>
+ </table>
+</div>
+<div class="memdoc">
+
+<p>The stream start (for <code>YAML_STREAM_START_TOKEN</code>). </p>
+
+</div>
+</div>
+<a class="anchor" id="a97ce52329d6093b63fba36817f8bd549"></a><!-- doxytag: member="yaml_token_s::value" ref="a97ce52329d6093b63fba36817f8bd549" args="" -->
+<div class="memitem">
+<div class="memproto">
+ <table class="memname">
+ <tr>
+ <td class="memname"><a class="el" href="group__basic.html#gaf8657e81f0b8b05d1a081001fc6cb8bd">yaml_char_t</a>* <a class="el" href="structyaml__token__s.html#a97ce52329d6093b63fba36817f8bd549">yaml_token_s::value</a></td>
+ </tr>
+ </table>
+</div>
+<div class="memdoc">
+
+<p>The alias value. </p>
+<p>The scalar value.</p>
+<p>The anchor value.</p>
+
+</div>
+</div>
+<a class="anchor" id="a1f942353efa1972a38a0763afefabe0c"></a><!-- doxytag: member="yaml_token_s::alias" ref="a1f942353efa1972a38a0763afefabe0c" args="" -->
+<div class="memitem">
+<div class="memproto">
+ <table class="memname">
+ <tr>
+ <td class="memname">struct { ... } <a class="el" href="structyaml__token__s.html#a1f942353efa1972a38a0763afefabe0c">yaml_token_s::alias</a></td>
+ </tr>
+ </table>
+</div>
+<div class="memdoc">
+
+<p>The alias (for <code>YAML_ALIAS_TOKEN</code>). </p>
+
+</div>
+</div>
+<a class="anchor" id="acc0f6636995f5fe332604b74571e6cfa"></a><!-- doxytag: member="yaml_token_s::anchor" ref="acc0f6636995f5fe332604b74571e6cfa" args="" -->
+<div class="memitem">
+<div class="memproto">
+ <table class="memname">
+ <tr>
+ <td class="memname">struct { ... } <a class="el" href="structyaml__token__s.html#acc0f6636995f5fe332604b74571e6cfa">yaml_token_s::anchor</a></td>
+ </tr>
+ </table>
+</div>
+<div class="memdoc">
+
+<p>The anchor (for <code>YAML_ANCHOR_TOKEN</code>). </p>
+
+</div>
+</div>
+<a class="anchor" id="a01665687653c945a6666dd9debaecd65"></a><!-- doxytag: member="yaml_token_s::handle" ref="a01665687653c945a6666dd9debaecd65" args="" -->
+<div class="memitem">
+<div class="memproto">
+ <table class="memname">
+ <tr>
+ <td class="memname"><a class="el" href="group__basic.html#gaf8657e81f0b8b05d1a081001fc6cb8bd">yaml_char_t</a>* <a class="el" href="structyaml__token__s.html#a01665687653c945a6666dd9debaecd65">yaml_token_s::handle</a></td>
+ </tr>
+ </table>
+</div>
+<div class="memdoc">
+
+<p>The tag handle. </p>
+
+</div>
+</div>
+<a class="anchor" id="a61344c49b73da5821cb06cab4cbab505"></a><!-- doxytag: member="yaml_token_s::suffix" ref="a61344c49b73da5821cb06cab4cbab505" args="" -->
+<div class="memitem">
+<div class="memproto">
+ <table class="memname">
+ <tr>
+ <td class="memname"><a class="el" href="group__basic.html#gaf8657e81f0b8b05d1a081001fc6cb8bd">yaml_char_t</a>* <a class="el" href="structyaml__token__s.html#a61344c49b73da5821cb06cab4cbab505">yaml_token_s::suffix</a></td>
+ </tr>
+ </table>
+</div>
+<div class="memdoc">
+
+<p>The tag suffix. </p>
+
+</div>
+</div>
+<a class="anchor" id="ab281db5b7563c5489726768fe0fbaac7"></a><!-- doxytag: member="yaml_token_s::tag" ref="ab281db5b7563c5489726768fe0fbaac7" args="" -->
+<div class="memitem">
+<div class="memproto">
+ <table class="memname">
+ <tr>
+ <td class="memname">struct { ... } <a class="el" href="structyaml__token__s.html#ab281db5b7563c5489726768fe0fbaac7">yaml_token_s::tag</a></td>
+ </tr>
+ </table>
+</div>
+<div class="memdoc">
+
+<p>The tag (for <code>YAML_TAG_TOKEN</code>). </p>
+
+</div>
+</div>
+<a class="anchor" id="a06e51daf74cf78103e00608c3c9132e2"></a><!-- doxytag: member="yaml_token_s::length" ref="a06e51daf74cf78103e00608c3c9132e2" args="" -->
+<div class="memitem">
+<div class="memproto">
+ <table class="memname">
+ <tr>
+ <td class="memname">size_t <a class="el" href="structyaml__token__s.html#a06e51daf74cf78103e00608c3c9132e2">yaml_token_s::length</a></td>
+ </tr>
+ </table>
+</div>
+<div class="memdoc">
+
+<p>The length of the scalar value. </p>
+
+</div>
+</div>
+<a class="anchor" id="a530a8c4d78feaf5496fb9f461674382b"></a><!-- doxytag: member="yaml_token_s::style" ref="a530a8c4d78feaf5496fb9f461674382b" args="" -->
+<div class="memitem">
+<div class="memproto">
+ <table class="memname">
+ <tr>
+ <td class="memname"><a class="el" href="group__styles.html#ga3fa6405631e1afe5bd5c488a6c5e8065">yaml_scalar_style_t</a> <a class="el" href="structyaml__token__s.html#a530a8c4d78feaf5496fb9f461674382b">yaml_token_s::style</a></td>
+ </tr>
+ </table>
+</div>
+<div class="memdoc">
+
+<p>The scalar style. </p>
+
+</div>
+</div>
+<a class="anchor" id="a35e3629351176dd91b38cbfc827a8b00"></a><!-- doxytag: member="yaml_token_s::scalar" ref="a35e3629351176dd91b38cbfc827a8b00" args="" -->
+<div class="memitem">
+<div class="memproto">
+ <table class="memname">
+ <tr>
+ <td class="memname">struct { ... } <a class="el" href="structyaml__token__s.html#a35e3629351176dd91b38cbfc827a8b00">yaml_token_s::scalar</a></td>
+ </tr>
+ </table>
+</div>
+<div class="memdoc">
+
+<p>The scalar value (for <code>YAML_SCALAR_TOKEN</code>). </p>
+
+</div>
+</div>
+<a class="anchor" id="aac2ed466afd0390872774238dfcd152c"></a><!-- doxytag: member="yaml_token_s::major" ref="aac2ed466afd0390872774238dfcd152c" args="" -->
+<div class="memitem">
+<div class="memproto">
+ <table class="memname">
+ <tr>
+ <td class="memname">int <a class="el" href="structyaml__token__s.html#aac2ed466afd0390872774238dfcd152c">yaml_token_s::major</a></td>
+ </tr>
+ </table>
+</div>
+<div class="memdoc">
+
+<p>The major version number. </p>
+
+</div>
+</div>
+<a class="anchor" id="a97b9f537b24e8413e9fddc6a4b183d30"></a><!-- doxytag: member="yaml_token_s::minor" ref="a97b9f537b24e8413e9fddc6a4b183d30" args="" -->
+<div class="memitem">
+<div class="memproto">
+ <table class="memname">
+ <tr>
+ <td class="memname">int <a class="el" href="structyaml__token__s.html#a97b9f537b24e8413e9fddc6a4b183d30">yaml_token_s::minor</a></td>
+ </tr>
+ </table>
+</div>
+<div class="memdoc">
+
+<p>The minor version number. </p>
+
+</div>
+</div>
+<a class="anchor" id="a41b30a59ca22d1020d6af4cc7cc0da47"></a><!-- doxytag: member="yaml_token_s::version_directive" ref="a41b30a59ca22d1020d6af4cc7cc0da47" args="" -->
+<div class="memitem">
+<div class="memproto">
+ <table class="memname">
+ <tr>
+ <td class="memname">struct { ... } <a class="el" href="structyaml__token__s.html#a41b30a59ca22d1020d6af4cc7cc0da47">yaml_token_s::version_directive</a></td>
+ </tr>
+ </table>
+</div>
+<div class="memdoc">
+
+<p>The version directive (for <code>YAML_VERSION_DIRECTIVE_TOKEN</code>). </p>
+
+</div>
+</div>
+<a class="anchor" id="a561b3730b9999cfe1010e77aca49c5b8"></a><!-- doxytag: member="yaml_token_s::prefix" ref="a561b3730b9999cfe1010e77aca49c5b8" args="" -->
+<div class="memitem">
+<div class="memproto">
+ <table class="memname">
+ <tr>
+ <td class="memname"><a class="el" href="group__basic.html#gaf8657e81f0b8b05d1a081001fc6cb8bd">yaml_char_t</a>* <a class="el" href="structyaml__token__s.html#a561b3730b9999cfe1010e77aca49c5b8">yaml_token_s::prefix</a></td>
+ </tr>
+ </table>
+</div>
+<div class="memdoc">
+
+<p>The tag prefix. </p>
+
+</div>
+</div>
+<a class="anchor" id="aa8a1b9eeee539233e8461773894f4ea0"></a><!-- doxytag: member="yaml_token_s::tag_directive" ref="aa8a1b9eeee539233e8461773894f4ea0" args="" -->
+<div class="memitem">
+<div class="memproto">
+ <table class="memname">
+ <tr>
+ <td class="memname">struct { ... } <a class="el" href="structyaml__token__s.html#aa8a1b9eeee539233e8461773894f4ea0">yaml_token_s::tag_directive</a></td>
+ </tr>
+ </table>
+</div>
+<div class="memdoc">
+
+<p>The tag directive (for <code>YAML_TAG_DIRECTIVE_TOKEN</code>). </p>
+
+</div>
+</div>
+<a class="anchor" id="aedb5be9b6b8f5ef6c129575e84f63605"></a><!-- doxytag: member="yaml_token_s::data" ref="aedb5be9b6b8f5ef6c129575e84f63605" args="" -->
+<div class="memitem">
+<div class="memproto">
+ <table class="memname">
+ <tr>
+ <td class="memname">union { ... } <a class="el" href="structyaml__token__s.html#aedb5be9b6b8f5ef6c129575e84f63605">yaml_token_s::data</a></td>
+ </tr>
+ </table>
+</div>
+<div class="memdoc">
+
+<p>The token data. </p>
+
+</div>
+</div>
+<a class="anchor" id="abdc5f4f2059c5a7bfe8e810b49a53980"></a><!-- doxytag: member="yaml_token_s::start_mark" ref="abdc5f4f2059c5a7bfe8e810b49a53980" args="" -->
+<div class="memitem">
+<div class="memproto">
+ <table class="memname">
+ <tr>
+ <td class="memname"><a class="el" href="structyaml__mark__s.html">yaml_mark_t</a> <a class="el" href="structyaml__token__s.html#abdc5f4f2059c5a7bfe8e810b49a53980">yaml_token_s::start_mark</a></td>
+ </tr>
+ </table>
+</div>
+<div class="memdoc">
+
+<p>The beginning of the token. </p>
+
+</div>
+</div>
+<a class="anchor" id="a97f08b38dfb0a5be26ef8831864a5311"></a><!-- doxytag: member="yaml_token_s::end_mark" ref="a97f08b38dfb0a5be26ef8831864a5311" args="" -->
+<div class="memitem">
+<div class="memproto">
+ <table class="memname">
+ <tr>
+ <td class="memname"><a class="el" href="structyaml__mark__s.html">yaml_mark_t</a> <a class="el" href="structyaml__token__s.html#a97f08b38dfb0a5be26ef8831864a5311">yaml_token_s::end_mark</a></td>
+ </tr>
+ </table>
+</div>
+<div class="memdoc">
+
+<p>The end of the token. </p>
+
+</div>
+</div>
+<hr/>The documentation for this struct was generated from the following file:<ul>
+<li><a class="el" href="yaml_8h.html">yaml.h</a></li>
+</ul>
+</div>
+<hr class="footer"/><address class="footer"><small>Generated on Mon May 30 2011 22:00:01 for yaml by&nbsp;
+<a href="http://www.doxygen.org/index.html">
+<img class="footer" src="doxygen.png" alt="doxygen"/></a> 1.7.1 </small></address>
+</body>
+</html>
diff --git a/contrib/libyaml/doc/html/structyaml__version__directive__s.html b/contrib/libyaml/doc/html/structyaml__version__directive__s.html
new file mode 100644
index 0000000..e689223
--- /dev/null
+++ b/contrib/libyaml/doc/html/structyaml__version__directive__s.html
@@ -0,0 +1,91 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head>
+<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/>
+<title>yaml: yaml_version_directive_s Struct Reference</title>
+<link href="tabs.css" rel="stylesheet" type="text/css"/>
+<link href="doxygen.css" rel="stylesheet" type="text/css"/>
+</head>
+<body>
+<!-- Generated by Doxygen 1.7.1 -->
+<div class="navigation" id="top">
+ <div class="tabs">
+ <ul class="tablist">
+ <li><a href="index.html"><span>Main&nbsp;Page</span></a></li>
+ <li><a href="modules.html"><span>Modules</span></a></li>
+ <li class="current"><a href="annotated.html"><span>Data&nbsp;Structures</span></a></li>
+ <li><a href="files.html"><span>Files</span></a></li>
+ </ul>
+ </div>
+ <div class="tabs2">
+ <ul class="tablist">
+ <li><a href="annotated.html"><span>Data&nbsp;Structures</span></a></li>
+ <li><a href="functions.html"><span>Data&nbsp;Fields</span></a></li>
+ </ul>
+ </div>
+</div>
+<div class="header">
+ <div class="summary">
+<a href="#pub-attribs">Data Fields</a> </div>
+ <div class="headertitle">
+<h1>yaml_version_directive_s Struct Reference<br/>
+<small>
+[<a class="el" href="group__basic.html">Basic Types</a>]</small>
+</h1> </div>
+</div>
+<div class="contents">
+<!-- doxytag: class="yaml_version_directive_s" -->
+<p>The version directive data.
+<a href="#_details">More...</a></p>
+
+<p><code>#include &lt;yaml.h&gt;</code></p>
+<table class="memberdecls">
+<tr><td colspan="2"><h2><a name="pub-attribs"></a>
+Data Fields</h2></td></tr>
+<tr><td class="memItemLeft" align="right" valign="top">int&nbsp;</td><td class="memItemRight" valign="bottom"><a class="el" href="structyaml__version__directive__s.html#ad27326ff94b7772027c3009d1dd5e52b">major</a></td></tr>
+<tr><td class="mdescLeft">&nbsp;</td><td class="mdescRight">The major version number. <a href="#ad27326ff94b7772027c3009d1dd5e52b"></a><br/></td></tr>
+<tr><td class="memItemLeft" align="right" valign="top">int&nbsp;</td><td class="memItemRight" valign="bottom"><a class="el" href="structyaml__version__directive__s.html#a89f074113501e6e150503f34b046dbd1">minor</a></td></tr>
+<tr><td class="mdescLeft">&nbsp;</td><td class="mdescRight">The minor version number. <a href="#a89f074113501e6e150503f34b046dbd1"></a><br/></td></tr>
+</table>
+<hr/><a name="_details"></a><h2>Detailed Description</h2>
+<p>The version directive data. </p>
+<hr/><h2>Field Documentation</h2>
+<a class="anchor" id="ad27326ff94b7772027c3009d1dd5e52b"></a><!-- doxytag: member="yaml_version_directive_s::major" ref="ad27326ff94b7772027c3009d1dd5e52b" args="" -->
+<div class="memitem">
+<div class="memproto">
+ <table class="memname">
+ <tr>
+ <td class="memname">int <a class="el" href="structyaml__version__directive__s.html#ad27326ff94b7772027c3009d1dd5e52b">yaml_version_directive_s::major</a></td>
+ </tr>
+ </table>
+</div>
+<div class="memdoc">
+
+<p>The major version number. </p>
+
+</div>
+</div>
+<a class="anchor" id="a89f074113501e6e150503f34b046dbd1"></a><!-- doxytag: member="yaml_version_directive_s::minor" ref="a89f074113501e6e150503f34b046dbd1" args="" -->
+<div class="memitem">
+<div class="memproto">
+ <table class="memname">
+ <tr>
+ <td class="memname">int <a class="el" href="structyaml__version__directive__s.html#a89f074113501e6e150503f34b046dbd1">yaml_version_directive_s::minor</a></td>
+ </tr>
+ </table>
+</div>
+<div class="memdoc">
+
+<p>The minor version number. </p>
+
+</div>
+</div>
+<hr/>The documentation for this struct was generated from the following file:<ul>
+<li><a class="el" href="yaml_8h.html">yaml.h</a></li>
+</ul>
+</div>
+<hr class="footer"/><address class="footer"><small>Generated on Mon May 30 2011 22:00:01 for yaml by&nbsp;
+<a href="http://www.doxygen.org/index.html">
+<img class="footer" src="doxygen.png" alt="doxygen"/></a> 1.7.1 </small></address>
+</body>
+</html>
diff --git a/contrib/libyaml/doc/html/tab_a.png b/contrib/libyaml/doc/html/tab_a.png
new file mode 100644
index 0000000..2d99ef2
--- /dev/null
+++ b/contrib/libyaml/doc/html/tab_a.png
Binary files differ
diff --git a/contrib/libyaml/doc/html/tab_b.png b/contrib/libyaml/doc/html/tab_b.png
new file mode 100644
index 0000000..b2c3d2b
--- /dev/null
+++ b/contrib/libyaml/doc/html/tab_b.png
Binary files differ
diff --git a/contrib/libyaml/doc/html/tab_h.png b/contrib/libyaml/doc/html/tab_h.png
new file mode 100644
index 0000000..c11f48f
--- /dev/null
+++ b/contrib/libyaml/doc/html/tab_h.png
Binary files differ
diff --git a/contrib/libyaml/doc/html/tab_s.png b/contrib/libyaml/doc/html/tab_s.png
new file mode 100644
index 0000000..978943a
--- /dev/null
+++ b/contrib/libyaml/doc/html/tab_s.png
Binary files differ
diff --git a/contrib/libyaml/doc/html/tabs.css b/contrib/libyaml/doc/html/tabs.css
new file mode 100644
index 0000000..2192056
--- /dev/null
+++ b/contrib/libyaml/doc/html/tabs.css
@@ -0,0 +1,59 @@
+.tabs, .tabs2, .tabs3 {
+ background-image: url('tab_b.png');
+ width: 100%;
+ z-index: 101;
+ font-size: 13px;
+}
+
+.tabs2 {
+ font-size: 10px;
+}
+.tabs3 {
+ font-size: 9px;
+}
+
+.tablist {
+ margin: 0;
+ padding: 0;
+ display: table;
+}
+
+.tablist li {
+ float: left;
+ display: table-cell;
+ background-image: url('tab_b.png');
+ line-height: 36px;
+ list-style: none;
+}
+
+.tablist a {
+ display: block;
+ padding: 0 20px;
+ font-weight: bold;
+ background-image:url('tab_s.png');
+ background-repeat:no-repeat;
+ background-position:right;
+ color: #283A5D;
+ text-shadow: 0px 1px 1px rgba(255, 255, 255, 0.9);
+ text-decoration: none;
+ outline: none;
+}
+
+.tabs3 .tablist a {
+ padding: 0 10px;
+}
+
+.tablist a:hover {
+ background-image: url('tab_h.png');
+ background-repeat:repeat-x;
+ color: #fff;
+ text-shadow: 0px 1px 1px rgba(0, 0, 0, 1.0);
+ text-decoration: none;
+}
+
+.tablist li.current a {
+ background-image: url('tab_a.png');
+ background-repeat:repeat-x;
+ color: #fff;
+ text-shadow: 0px 1px 1px rgba(0, 0, 0, 1.0);
+}
diff --git a/contrib/libyaml/doc/html/yaml_8h.html b/contrib/libyaml/doc/html/yaml_8h.html
new file mode 100644
index 0000000..ed9d0b8
--- /dev/null
+++ b/contrib/libyaml/doc/html/yaml_8h.html
@@ -0,0 +1,525 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head>
+<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/>
+<title>yaml: yaml.h File Reference</title>
+<link href="tabs.css" rel="stylesheet" type="text/css"/>
+<link href="doxygen.css" rel="stylesheet" type="text/css"/>
+</head>
+<body>
+<!-- Generated by Doxygen 1.7.1 -->
+<div class="navigation" id="top">
+ <div class="tabs">
+ <ul class="tablist">
+ <li><a href="index.html"><span>Main&nbsp;Page</span></a></li>
+ <li><a href="modules.html"><span>Modules</span></a></li>
+ <li><a href="annotated.html"><span>Data&nbsp;Structures</span></a></li>
+ <li class="current"><a href="files.html"><span>Files</span></a></li>
+ </ul>
+ </div>
+ <div class="tabs2">
+ <ul class="tablist">
+ <li><a href="files.html"><span>File&nbsp;List</span></a></li>
+ <li><a href="globals.html"><span>Globals</span></a></li>
+ </ul>
+ </div>
+</div>
+<div class="header">
+ <div class="summary">
+<a href="#nested-classes">Data Structures</a> &#124;
+<a href="#define-members">Defines</a> &#124;
+<a href="#typedef-members">Typedefs</a> &#124;
+<a href="#enum-members">Enumerations</a> &#124;
+<a href="#func-members">Functions</a> </div>
+ <div class="headertitle">
+<h1>yaml.h File Reference</h1> </div>
+</div>
+<div class="contents">
+
+<p>Public interface for libyaml.
+<a href="#_details">More...</a></p>
+<code>#include &lt;stdlib.h&gt;</code><br/>
+<code>#include &lt;stdio.h&gt;</code><br/>
+<code>#include &lt;string.h&gt;</code><br/>
+<table class="memberdecls">
+<tr><td colspan="2"><h2><a name="nested-classes"></a>
+Data Structures</h2></td></tr>
+<tr><td class="memItemLeft" align="right" valign="top">struct &nbsp;</td><td class="memItemRight" valign="bottom"><a class="el" href="structyaml__version__directive__s.html">yaml_version_directive_s</a></td></tr>
+<tr><td class="mdescLeft">&nbsp;</td><td class="mdescRight">The version directive data. <a href="structyaml__version__directive__s.html#_details">More...</a><br/></td></tr>
+<tr><td class="memItemLeft" align="right" valign="top">struct &nbsp;</td><td class="memItemRight" valign="bottom"><a class="el" href="structyaml__tag__directive__s.html">yaml_tag_directive_s</a></td></tr>
+<tr><td class="mdescLeft">&nbsp;</td><td class="mdescRight">The tag directive data. <a href="structyaml__tag__directive__s.html#_details">More...</a><br/></td></tr>
+<tr><td class="memItemLeft" align="right" valign="top">struct &nbsp;</td><td class="memItemRight" valign="bottom"><a class="el" href="structyaml__mark__s.html">yaml_mark_s</a></td></tr>
+<tr><td class="mdescLeft">&nbsp;</td><td class="mdescRight">The pointer position. <a href="structyaml__mark__s.html#_details">More...</a><br/></td></tr>
+<tr><td class="memItemLeft" align="right" valign="top">struct &nbsp;</td><td class="memItemRight" valign="bottom"><a class="el" href="structyaml__token__s.html">yaml_token_s</a></td></tr>
+<tr><td class="mdescLeft">&nbsp;</td><td class="mdescRight">The token structure. <a href="structyaml__token__s.html#_details">More...</a><br/></td></tr>
+<tr><td class="memItemLeft" align="right" valign="top">struct &nbsp;</td><td class="memItemRight" valign="bottom"><a class="el" href="structyaml__event__s.html">yaml_event_s</a></td></tr>
+<tr><td class="mdescLeft">&nbsp;</td><td class="mdescRight">The event structure. <a href="structyaml__event__s.html#_details">More...</a><br/></td></tr>
+<tr><td class="memItemLeft" align="right" valign="top">struct &nbsp;</td><td class="memItemRight" valign="bottom"><a class="el" href="structyaml__node__pair__s.html">yaml_node_pair_s</a></td></tr>
+<tr><td class="mdescLeft">&nbsp;</td><td class="mdescRight">An element of a mapping node. <a href="structyaml__node__pair__s.html#_details">More...</a><br/></td></tr>
+<tr><td class="memItemLeft" align="right" valign="top">struct &nbsp;</td><td class="memItemRight" valign="bottom"><a class="el" href="structyaml__node__s.html">yaml_node_s</a></td></tr>
+<tr><td class="mdescLeft">&nbsp;</td><td class="mdescRight">The node structure. <a href="structyaml__node__s.html#_details">More...</a><br/></td></tr>
+<tr><td class="memItemLeft" align="right" valign="top">struct &nbsp;</td><td class="memItemRight" valign="bottom"><a class="el" href="structyaml__document__s.html">yaml_document_s</a></td></tr>
+<tr><td class="mdescLeft">&nbsp;</td><td class="mdescRight">The document structure. <a href="structyaml__document__s.html#_details">More...</a><br/></td></tr>
+<tr><td class="memItemLeft" align="right" valign="top">struct &nbsp;</td><td class="memItemRight" valign="bottom"><a class="el" href="structyaml__simple__key__s.html">yaml_simple_key_s</a></td></tr>
+<tr><td class="mdescLeft">&nbsp;</td><td class="mdescRight">This structure holds information about a potential simple key. <a href="structyaml__simple__key__s.html#_details">More...</a><br/></td></tr>
+<tr><td class="memItemLeft" align="right" valign="top">struct &nbsp;</td><td class="memItemRight" valign="bottom"><a class="el" href="structyaml__alias__data__s.html">yaml_alias_data_s</a></td></tr>
+<tr><td class="mdescLeft">&nbsp;</td><td class="mdescRight">This structure holds aliases data. <a href="structyaml__alias__data__s.html#_details">More...</a><br/></td></tr>
+<tr><td class="memItemLeft" align="right" valign="top">struct &nbsp;</td><td class="memItemRight" valign="bottom"><a class="el" href="structyaml__parser__s.html">yaml_parser_s</a></td></tr>
+<tr><td class="mdescLeft">&nbsp;</td><td class="mdescRight">The parser structure. <a href="structyaml__parser__s.html#_details">More...</a><br/></td></tr>
+<tr><td class="memItemLeft" align="right" valign="top">struct &nbsp;</td><td class="memItemRight" valign="bottom"><a class="el" href="structyaml__emitter__s.html">yaml_emitter_s</a></td></tr>
+<tr><td class="mdescLeft">&nbsp;</td><td class="mdescRight">The emitter structure. <a href="structyaml__emitter__s.html#_details">More...</a><br/></td></tr>
+<tr><td colspan="2"><h2><a name="define-members"></a>
+Defines</h2></td></tr>
+<tr><td class="memItemLeft" align="right" valign="top">#define&nbsp;</td><td class="memItemRight" valign="bottom"><a class="el" href="group__export.html#ga0791fd3e1d85ed53711b1feaae131f93">YAML_DECLARE</a>(type)&nbsp;&nbsp;&nbsp;type</td></tr>
+<tr><td class="mdescLeft">&nbsp;</td><td class="mdescRight">The public API declaration. <a href="group__export.html#ga0791fd3e1d85ed53711b1feaae131f93"></a><br/></td></tr>
+<tr><td class="memItemLeft" align="right" valign="top">#define&nbsp;</td><td class="memItemRight" valign="bottom"><a class="el" href="group__nodes.html#gadfa882b6e42a3a993d12392d55260b00">YAML_NULL_TAG</a>&nbsp;&nbsp;&nbsp;&quot;tag:yaml.org,2002:null&quot;</td></tr>
+<tr><td class="mdescLeft">&nbsp;</td><td class="mdescRight">The tag <code>!!null</code> with the only possible value: <code>null</code>. <a href="group__nodes.html#gadfa882b6e42a3a993d12392d55260b00"></a><br/></td></tr>
+<tr><td class="memItemLeft" align="right" valign="top">#define&nbsp;</td><td class="memItemRight" valign="bottom"><a class="el" href="group__nodes.html#ga312629a1f51e91b136352db988d4d771">YAML_BOOL_TAG</a>&nbsp;&nbsp;&nbsp;&quot;tag:yaml.org,2002:bool&quot;</td></tr>
+<tr><td class="mdescLeft">&nbsp;</td><td class="mdescRight">The tag <code>!!bool</code> with the values: <code>true</code> and <code>falce</code>. <a href="group__nodes.html#ga312629a1f51e91b136352db988d4d771"></a><br/></td></tr>
+<tr><td class="memItemLeft" align="right" valign="top">#define&nbsp;</td><td class="memItemRight" valign="bottom"><a class="el" href="group__nodes.html#gac5dbc6d1f556663edf8db88d6113e931">YAML_STR_TAG</a>&nbsp;&nbsp;&nbsp;&quot;tag:yaml.org,2002:str&quot;</td></tr>
+<tr><td class="mdescLeft">&nbsp;</td><td class="mdescRight">The tag <code>!!str</code> for string values. <a href="group__nodes.html#gac5dbc6d1f556663edf8db88d6113e931"></a><br/></td></tr>
+<tr><td class="memItemLeft" align="right" valign="top">#define&nbsp;</td><td class="memItemRight" valign="bottom"><a class="el" href="group__nodes.html#ga83263cdb4ffa6ad2f7d9a87281979ff5">YAML_INT_TAG</a>&nbsp;&nbsp;&nbsp;&quot;tag:yaml.org,2002:int&quot;</td></tr>
+<tr><td class="mdescLeft">&nbsp;</td><td class="mdescRight">The tag <code>!!int</code> for integer values. <a href="group__nodes.html#ga83263cdb4ffa6ad2f7d9a87281979ff5"></a><br/></td></tr>
+<tr><td class="memItemLeft" align="right" valign="top">#define&nbsp;</td><td class="memItemRight" valign="bottom"><a class="el" href="group__nodes.html#ga6ab2ec71fc47cb24f1003b9acdb92843">YAML_FLOAT_TAG</a>&nbsp;&nbsp;&nbsp;&quot;tag:yaml.org,2002:float&quot;</td></tr>
+<tr><td class="mdescLeft">&nbsp;</td><td class="mdescRight">The tag <code>!!float</code> for float values. <a href="group__nodes.html#ga6ab2ec71fc47cb24f1003b9acdb92843"></a><br/></td></tr>
+<tr><td class="memItemLeft" align="right" valign="top">#define&nbsp;</td><td class="memItemRight" valign="bottom"><a class="el" href="group__nodes.html#ga3e27cca7191234f2e8c95eaf3bc99a73">YAML_TIMESTAMP_TAG</a>&nbsp;&nbsp;&nbsp;&quot;tag:yaml.org,2002:timestamp&quot;</td></tr>
+<tr><td class="mdescLeft">&nbsp;</td><td class="mdescRight">The tag <code>!!timestamp</code> for date and time values. <a href="group__nodes.html#ga3e27cca7191234f2e8c95eaf3bc99a73"></a><br/></td></tr>
+<tr><td class="memItemLeft" align="right" valign="top">#define&nbsp;</td><td class="memItemRight" valign="bottom"><a class="el" href="group__nodes.html#gaa8284b30f9c9e3f10f6a69c9b882f417">YAML_SEQ_TAG</a>&nbsp;&nbsp;&nbsp;&quot;tag:yaml.org,2002:seq&quot;</td></tr>
+<tr><td class="mdescLeft">&nbsp;</td><td class="mdescRight">The tag <code>!!seq</code> is used to denote sequences. <a href="group__nodes.html#gaa8284b30f9c9e3f10f6a69c9b882f417"></a><br/></td></tr>
+<tr><td class="memItemLeft" align="right" valign="top">#define&nbsp;</td><td class="memItemRight" valign="bottom"><a class="el" href="group__nodes.html#ga22ae99cf3ac014dd76873268fd068c12">YAML_MAP_TAG</a>&nbsp;&nbsp;&nbsp;&quot;tag:yaml.org,2002:map&quot;</td></tr>
+<tr><td class="mdescLeft">&nbsp;</td><td class="mdescRight">The tag <code>!!map</code> is used to denote mapping. <a href="group__nodes.html#ga22ae99cf3ac014dd76873268fd068c12"></a><br/></td></tr>
+<tr><td class="memItemLeft" align="right" valign="top">#define&nbsp;</td><td class="memItemRight" valign="bottom"><a class="el" href="group__nodes.html#gaf6b0c4e819b8f6915515a4f70065aaaa">YAML_DEFAULT_SCALAR_TAG</a>&nbsp;&nbsp;&nbsp;YAML_STR_TAG</td></tr>
+<tr><td class="mdescLeft">&nbsp;</td><td class="mdescRight">The default scalar tag is <code>!!str</code>. <a href="group__nodes.html#gaf6b0c4e819b8f6915515a4f70065aaaa"></a><br/></td></tr>
+<tr><td class="memItemLeft" align="right" valign="top">#define&nbsp;</td><td class="memItemRight" valign="bottom"><a class="el" href="group__nodes.html#gaf195b67002518702e27746d6b4da6124">YAML_DEFAULT_SEQUENCE_TAG</a>&nbsp;&nbsp;&nbsp;YAML_SEQ_TAG</td></tr>
+<tr><td class="mdescLeft">&nbsp;</td><td class="mdescRight">The default sequence tag is <code>!!seq</code>. <a href="group__nodes.html#gaf195b67002518702e27746d6b4da6124"></a><br/></td></tr>
+<tr><td class="memItemLeft" align="right" valign="top">#define&nbsp;</td><td class="memItemRight" valign="bottom"><a class="el" href="group__nodes.html#gaf7b1f8f0ce5665794510cd3841802a5f">YAML_DEFAULT_MAPPING_TAG</a>&nbsp;&nbsp;&nbsp;YAML_MAP_TAG</td></tr>
+<tr><td class="mdescLeft">&nbsp;</td><td class="mdescRight">The default mapping tag is <code>!!map</code>. <a href="group__nodes.html#gaf7b1f8f0ce5665794510cd3841802a5f"></a><br/></td></tr>
+<tr><td colspan="2"><h2><a name="typedef-members"></a>
+Typedefs</h2></td></tr>
+<tr><td class="memItemLeft" align="right" valign="top">typedef unsigned char&nbsp;</td><td class="memItemRight" valign="bottom"><a class="el" href="group__basic.html#gaf8657e81f0b8b05d1a081001fc6cb8bd">yaml_char_t</a></td></tr>
+<tr><td class="mdescLeft">&nbsp;</td><td class="mdescRight">The character type (UTF-8 octet). <a href="group__basic.html#gaf8657e81f0b8b05d1a081001fc6cb8bd"></a><br/></td></tr>
+<tr><td class="memItemLeft" align="right" valign="top">typedef struct <br class="typebreak"/>
+<a class="el" href="structyaml__version__directive__s.html">yaml_version_directive_s</a>&nbsp;</td><td class="memItemRight" valign="bottom"><a class="el" href="group__basic.html#ga2fc55608333fbe6df17cf891be709b72">yaml_version_directive_t</a></td></tr>
+<tr><td class="mdescLeft">&nbsp;</td><td class="mdescRight">The version directive data. <a href="group__basic.html#ga2fc55608333fbe6df17cf891be709b72"></a><br/></td></tr>
+<tr><td class="memItemLeft" align="right" valign="top">typedef struct <a class="el" href="structyaml__tag__directive__s.html">yaml_tag_directive_s</a>&nbsp;</td><td class="memItemRight" valign="bottom"><a class="el" href="group__basic.html#ga0b4bc4871b0c9104e32d40d5f3803674">yaml_tag_directive_t</a></td></tr>
+<tr><td class="mdescLeft">&nbsp;</td><td class="mdescRight">The tag directive data. <a href="group__basic.html#ga0b4bc4871b0c9104e32d40d5f3803674"></a><br/></td></tr>
+<tr><td class="memItemLeft" align="right" valign="top">typedef enum <a class="el" href="group__basic.html#gab88ee52b5d722e644c1cb4d1afcccdd9">yaml_encoding_e</a>&nbsp;</td><td class="memItemRight" valign="bottom"><a class="el" href="group__basic.html#ga2170996d7e636397b5e6bc0c1b7df7c6">yaml_encoding_t</a></td></tr>
+<tr><td class="mdescLeft">&nbsp;</td><td class="mdescRight">The stream encoding. <a href="group__basic.html#ga2170996d7e636397b5e6bc0c1b7df7c6"></a><br/></td></tr>
+<tr><td class="memItemLeft" align="right" valign="top">typedef enum <a class="el" href="group__basic.html#ga912ad8c893126133fab5e4231db3017e">yaml_break_e</a>&nbsp;</td><td class="memItemRight" valign="bottom"><a class="el" href="group__basic.html#ga64d1365e1acd4deeab50d6b48e39cb6d">yaml_break_t</a></td></tr>
+<tr><td class="mdescLeft">&nbsp;</td><td class="mdescRight">Line break types. <a href="group__basic.html#ga64d1365e1acd4deeab50d6b48e39cb6d"></a><br/></td></tr>
+<tr><td class="memItemLeft" align="right" valign="top">typedef enum <a class="el" href="group__basic.html#ga2efbcde2e82238117982b789c5a8ea01">yaml_error_type_e</a>&nbsp;</td><td class="memItemRight" valign="bottom"><a class="el" href="group__basic.html#ga1a449f0c1b023e2ef1a596093c018e73">yaml_error_type_t</a></td></tr>
+<tr><td class="mdescLeft">&nbsp;</td><td class="mdescRight">Many bad things could happen with the parser and emitter. <a href="group__basic.html#ga1a449f0c1b023e2ef1a596093c018e73"></a><br/></td></tr>
+<tr><td class="memItemLeft" align="right" valign="top">typedef struct <a class="el" href="structyaml__mark__s.html">yaml_mark_s</a>&nbsp;</td><td class="memItemRight" valign="bottom"><a class="el" href="group__basic.html#ga232eacba89691b841ba941338a302bfd">yaml_mark_t</a></td></tr>
+<tr><td class="mdescLeft">&nbsp;</td><td class="mdescRight">The pointer position. <a href="group__basic.html#ga232eacba89691b841ba941338a302bfd"></a><br/></td></tr>
+<tr><td class="memItemLeft" align="right" valign="top">typedef enum <a class="el" href="group__styles.html#ga435ae8886b70c16830d853b6c566e2e0">yaml_scalar_style_e</a>&nbsp;</td><td class="memItemRight" valign="bottom"><a class="el" href="group__styles.html#ga3fa6405631e1afe5bd5c488a6c5e8065">yaml_scalar_style_t</a></td></tr>
+<tr><td class="mdescLeft">&nbsp;</td><td class="mdescRight">Scalar styles. <a href="group__styles.html#ga3fa6405631e1afe5bd5c488a6c5e8065"></a><br/></td></tr>
+<tr><td class="memItemLeft" align="right" valign="top">typedef enum <a class="el" href="group__styles.html#ga5079a4ab96e398371c60423abd88ccc0">yaml_sequence_style_e</a>&nbsp;</td><td class="memItemRight" valign="bottom"><a class="el" href="group__styles.html#ga58a1123d271e56c72de6abf852ac4dc2">yaml_sequence_style_t</a></td></tr>
+<tr><td class="mdescLeft">&nbsp;</td><td class="mdescRight">Sequence styles. <a href="group__styles.html#ga58a1123d271e56c72de6abf852ac4dc2"></a><br/></td></tr>
+<tr><td class="memItemLeft" align="right" valign="top">typedef enum <a class="el" href="group__styles.html#ga1efef592e2e3df6f00432c04ef77d98f">yaml_mapping_style_e</a>&nbsp;</td><td class="memItemRight" valign="bottom"><a class="el" href="group__styles.html#gab47523846a5c5960e07367a28ea9750a">yaml_mapping_style_t</a></td></tr>
+<tr><td class="mdescLeft">&nbsp;</td><td class="mdescRight">Mapping styles. <a href="group__styles.html#gab47523846a5c5960e07367a28ea9750a"></a><br/></td></tr>
+<tr><td class="memItemLeft" align="right" valign="top">typedef enum <a class="el" href="group__tokens.html#gaae955b10aa6b5f922de64873bf4ccdbd">yaml_token_type_e</a>&nbsp;</td><td class="memItemRight" valign="bottom"><a class="el" href="group__tokens.html#gaba51dda022dced02f8df2224ab7993f7">yaml_token_type_t</a></td></tr>
+<tr><td class="mdescLeft">&nbsp;</td><td class="mdescRight">Token types. <a href="group__tokens.html#gaba51dda022dced02f8df2224ab7993f7"></a><br/></td></tr>
+<tr><td class="memItemLeft" align="right" valign="top">typedef struct <a class="el" href="structyaml__token__s.html">yaml_token_s</a>&nbsp;</td><td class="memItemRight" valign="bottom"><a class="el" href="group__tokens.html#ga1ed3dc460e62aee8270c5d63d5734bbb">yaml_token_t</a></td></tr>
+<tr><td class="mdescLeft">&nbsp;</td><td class="mdescRight">The token structure. <a href="group__tokens.html#ga1ed3dc460e62aee8270c5d63d5734bbb"></a><br/></td></tr>
+<tr><td class="memItemLeft" align="right" valign="top">typedef enum <a class="el" href="group__events.html#ga454fccebae859c188fe3e7fa3299577c">yaml_event_type_e</a>&nbsp;</td><td class="memItemRight" valign="bottom"><a class="el" href="group__events.html#ga8934661be36bd7c9d17a8af69eff89a1">yaml_event_type_t</a></td></tr>
+<tr><td class="mdescLeft">&nbsp;</td><td class="mdescRight">Event types. <a href="group__events.html#ga8934661be36bd7c9d17a8af69eff89a1"></a><br/></td></tr>
+<tr><td class="memItemLeft" align="right" valign="top">typedef struct <a class="el" href="structyaml__event__s.html">yaml_event_s</a>&nbsp;</td><td class="memItemRight" valign="bottom"><a class="el" href="group__events.html#ga3b392d9716c4920cabefdd29e78dd542">yaml_event_t</a></td></tr>
+<tr><td class="mdescLeft">&nbsp;</td><td class="mdescRight">The event structure. <a href="group__events.html#ga3b392d9716c4920cabefdd29e78dd542"></a><br/></td></tr>
+<tr><td class="memItemLeft" align="right" valign="top">typedef enum <a class="el" href="group__nodes.html#ga0897d4b6bdd1b56c7a5fa0ff17b4f798">yaml_node_type_e</a>&nbsp;</td><td class="memItemRight" valign="bottom"><a class="el" href="group__nodes.html#gabe020d2fc42d3e896549e9f97da622d2">yaml_node_type_t</a></td></tr>
+<tr><td class="mdescLeft">&nbsp;</td><td class="mdescRight">Node types. <a href="group__nodes.html#gabe020d2fc42d3e896549e9f97da622d2"></a><br/></td></tr>
+<tr><td class="memItemLeft" align="right" valign="top">typedef struct <a class="el" href="structyaml__node__s.html">yaml_node_s</a>&nbsp;</td><td class="memItemRight" valign="bottom"><a class="el" href="group__nodes.html#ga9eaaa233b120b9d9db47de93c294c40f">yaml_node_t</a></td></tr>
+<tr><td class="mdescLeft">&nbsp;</td><td class="mdescRight">The forward definition of a document node structure. <a href="group__nodes.html#ga9eaaa233b120b9d9db47de93c294c40f"></a><br/></td></tr>
+<tr><td class="memItemLeft" align="right" valign="top">typedef int&nbsp;</td><td class="memItemRight" valign="bottom"><a class="el" href="group__nodes.html#ga7cc3581582e778b00c04e99cd3656860">yaml_node_item_t</a></td></tr>
+<tr><td class="mdescLeft">&nbsp;</td><td class="mdescRight">An element of a sequence node. <a href="group__nodes.html#ga7cc3581582e778b00c04e99cd3656860"></a><br/></td></tr>
+<tr><td class="memItemLeft" align="right" valign="top">typedef struct <a class="el" href="structyaml__node__pair__s.html">yaml_node_pair_s</a>&nbsp;</td><td class="memItemRight" valign="bottom"><a class="el" href="group__nodes.html#ga90f1c8b83c5c38dc4016afc1cc2050c4">yaml_node_pair_t</a></td></tr>
+<tr><td class="mdescLeft">&nbsp;</td><td class="mdescRight">An element of a mapping node. <a href="group__nodes.html#ga90f1c8b83c5c38dc4016afc1cc2050c4"></a><br/></td></tr>
+<tr><td class="memItemLeft" align="right" valign="top">typedef struct <a class="el" href="structyaml__document__s.html">yaml_document_s</a>&nbsp;</td><td class="memItemRight" valign="bottom"><a class="el" href="group__nodes.html#gad94e064e95baeb22e4f7acc7804e8479">yaml_document_t</a></td></tr>
+<tr><td class="mdescLeft">&nbsp;</td><td class="mdescRight">The document structure. <a href="group__nodes.html#gad94e064e95baeb22e4f7acc7804e8479"></a><br/></td></tr>
+<tr><td class="memItemLeft" align="right" valign="top">typedef int&nbsp;</td><td class="memItemRight" valign="bottom"><a class="el" href="group__parser.html#ga4982f7e4e001ddb47d2819f38f0cd9d6">yaml_read_handler_t</a> (void *data, unsigned char *buffer, size_t size, size_t *size_read)</td></tr>
+<tr><td class="mdescLeft">&nbsp;</td><td class="mdescRight">The prototype of a read handler. <a href="group__parser.html#ga4982f7e4e001ddb47d2819f38f0cd9d6"></a><br/></td></tr>
+<tr><td class="memItemLeft" align="right" valign="top"><a class="anchor" id="gae5570fbb7ab7c8332cd666f3a9c26591"></a><!-- doxytag: member="yaml.h::yaml_simple_key_t" ref="gae5570fbb7ab7c8332cd666f3a9c26591" args="" -->
+typedef struct <a class="el" href="structyaml__simple__key__s.html">yaml_simple_key_s</a>&nbsp;</td><td class="memItemRight" valign="bottom"><a class="el" href="group__parser.html#gae5570fbb7ab7c8332cd666f3a9c26591">yaml_simple_key_t</a></td></tr>
+<tr><td class="mdescLeft">&nbsp;</td><td class="mdescRight">This structure holds information about a potential simple key. <br/></td></tr>
+<tr><td class="memItemLeft" align="right" valign="top"><a class="anchor" id="ga52b56d3e3cee0f9ba460978802a8c83b"></a><!-- doxytag: member="yaml.h::yaml_parser_state_t" ref="ga52b56d3e3cee0f9ba460978802a8c83b" args="" -->
+typedef enum <a class="el" href="group__parser.html#gad39c19e7b0df6f542ca97806535b57c5">yaml_parser_state_e</a>&nbsp;</td><td class="memItemRight" valign="bottom"><a class="el" href="group__parser.html#ga52b56d3e3cee0f9ba460978802a8c83b">yaml_parser_state_t</a></td></tr>
+<tr><td class="mdescLeft">&nbsp;</td><td class="mdescRight">The states of the parser. <br/></td></tr>
+<tr><td class="memItemLeft" align="right" valign="top"><a class="anchor" id="ga1434228b82f5f90d3c8ccda816e9ca9d"></a><!-- doxytag: member="yaml.h::yaml_alias_data_t" ref="ga1434228b82f5f90d3c8ccda816e9ca9d" args="" -->
+typedef struct <a class="el" href="structyaml__alias__data__s.html">yaml_alias_data_s</a>&nbsp;</td><td class="memItemRight" valign="bottom"><a class="el" href="group__parser.html#ga1434228b82f5f90d3c8ccda816e9ca9d">yaml_alias_data_t</a></td></tr>
+<tr><td class="mdescLeft">&nbsp;</td><td class="mdescRight">This structure holds aliases data. <br/></td></tr>
+<tr><td class="memItemLeft" align="right" valign="top">typedef struct <a class="el" href="structyaml__parser__s.html">yaml_parser_s</a>&nbsp;</td><td class="memItemRight" valign="bottom"><a class="el" href="group__parser.html#gafdc6319cb28a8b8034542b29be85b0c4">yaml_parser_t</a></td></tr>
+<tr><td class="mdescLeft">&nbsp;</td><td class="mdescRight">The parser structure. <a href="group__parser.html#gafdc6319cb28a8b8034542b29be85b0c4"></a><br/></td></tr>
+<tr><td class="memItemLeft" align="right" valign="top">typedef int&nbsp;</td><td class="memItemRight" valign="bottom"><a class="el" href="group__emitter.html#ga1669659aacbe631ad406c78fce1f5379">yaml_write_handler_t</a> (void *data, unsigned char *buffer, size_t size)</td></tr>
+<tr><td class="mdescLeft">&nbsp;</td><td class="mdescRight">The prototype of a write handler. <a href="group__emitter.html#ga1669659aacbe631ad406c78fce1f5379"></a><br/></td></tr>
+<tr><td class="memItemLeft" align="right" valign="top">typedef enum <a class="el" href="group__emitter.html#ga387b79da11c3941e43a56947263aa721">yaml_emitter_state_e</a>&nbsp;</td><td class="memItemRight" valign="bottom"><a class="el" href="group__emitter.html#ga0889461fa3efe8eee881aef48a4ba6b2">yaml_emitter_state_t</a></td></tr>
+<tr><td class="mdescLeft">&nbsp;</td><td class="mdescRight">The emitter states. <a href="group__emitter.html#ga0889461fa3efe8eee881aef48a4ba6b2"></a><br/></td></tr>
+<tr><td class="memItemLeft" align="right" valign="top">typedef struct <a class="el" href="structyaml__emitter__s.html">yaml_emitter_s</a>&nbsp;</td><td class="memItemRight" valign="bottom"><a class="el" href="group__emitter.html#ga4ce3e054f0016c49d9e8c36d359e710b">yaml_emitter_t</a></td></tr>
+<tr><td class="mdescLeft">&nbsp;</td><td class="mdescRight">The emitter structure. <a href="group__emitter.html#ga4ce3e054f0016c49d9e8c36d359e710b"></a><br/></td></tr>
+<tr><td colspan="2"><h2><a name="enum-members"></a>
+Enumerations</h2></td></tr>
+<tr><td class="memItemLeft" align="right" valign="top">enum &nbsp;</td><td class="memItemRight" valign="bottom"><a class="el" href="group__basic.html#gab88ee52b5d722e644c1cb4d1afcccdd9">yaml_encoding_e</a> { <br/>
+&nbsp;&nbsp;<a class="el" href="group__basic.html#ggab88ee52b5d722e644c1cb4d1afcccdd9ab61d2a81b8e698e642ce6ad69612fa7f">YAML_ANY_ENCODING</a>,
+<br/>
+&nbsp;&nbsp;<a class="el" href="group__basic.html#ggab88ee52b5d722e644c1cb4d1afcccdd9a5bacbc5e68fc0c25baedf87e3be25a28">YAML_UTF8_ENCODING</a>,
+<br/>
+&nbsp;&nbsp;<a class="el" href="group__basic.html#ggab88ee52b5d722e644c1cb4d1afcccdd9ac68c68725ec1f6492e59fd388fd123c9">YAML_UTF16LE_ENCODING</a>,
+<br/>
+&nbsp;&nbsp;<a class="el" href="group__basic.html#ggab88ee52b5d722e644c1cb4d1afcccdd9a9f4fcb99a71d3416239f343f1334780b">YAML_UTF16BE_ENCODING</a>
+<br/>
+ }</td></tr>
+<tr><td class="mdescLeft">&nbsp;</td><td class="mdescRight"><p>The stream encoding. </p>
+ <a href="group__basic.html#gab88ee52b5d722e644c1cb4d1afcccdd9">More...</a><br/></td></tr>
+<tr><td class="memItemLeft" align="right" valign="top">enum &nbsp;</td><td class="memItemRight" valign="bottom"><a class="el" href="group__basic.html#ga912ad8c893126133fab5e4231db3017e">yaml_break_e</a> { <br/>
+&nbsp;&nbsp;<a class="el" href="group__basic.html#gga912ad8c893126133fab5e4231db3017ea052bd56adef565c33a86fcc05b49513f">YAML_ANY_BREAK</a>,
+<br/>
+&nbsp;&nbsp;<a class="el" href="group__basic.html#gga912ad8c893126133fab5e4231db3017ea116a98ba4ed0bacfdf098a7d5beeb9d4">YAML_CR_BREAK</a>,
+<br/>
+&nbsp;&nbsp;<a class="el" href="group__basic.html#gga912ad8c893126133fab5e4231db3017ea23bf395462dcd045e22303be6f3f7781">YAML_LN_BREAK</a>,
+<br/>
+&nbsp;&nbsp;<a class="el" href="group__basic.html#gga912ad8c893126133fab5e4231db3017ea15f8daa406870ebfe82b85781c2468f3">YAML_CRLN_BREAK</a>
+<br/>
+ }</td></tr>
+<tr><td class="mdescLeft">&nbsp;</td><td class="mdescRight"><p>Line break types. </p>
+ <a href="group__basic.html#ga912ad8c893126133fab5e4231db3017e">More...</a><br/></td></tr>
+<tr><td class="memItemLeft" align="right" valign="top">enum &nbsp;</td><td class="memItemRight" valign="bottom"><a class="el" href="group__basic.html#ga2efbcde2e82238117982b789c5a8ea01">yaml_error_type_e</a> { <br/>
+&nbsp;&nbsp;<a class="el" href="group__basic.html#gga2efbcde2e82238117982b789c5a8ea01a24cadfb5364769959ad8647649d1e86f">YAML_NO_ERROR</a>,
+<br/>
+&nbsp;&nbsp;<a class="el" href="group__basic.html#gga2efbcde2e82238117982b789c5a8ea01a57be0407d1f344206d9673c9571bde53">YAML_MEMORY_ERROR</a>,
+<br/>
+&nbsp;&nbsp;<a class="el" href="group__basic.html#gga2efbcde2e82238117982b789c5a8ea01a9216f41a453dc36b090cdc1ca9f89637">YAML_READER_ERROR</a>,
+<br/>
+&nbsp;&nbsp;<a class="el" href="group__basic.html#gga2efbcde2e82238117982b789c5a8ea01a6f8d865d9a25b385146660d8260d3d6f">YAML_SCANNER_ERROR</a>,
+<br/>
+&nbsp;&nbsp;<a class="el" href="group__basic.html#gga2efbcde2e82238117982b789c5a8ea01a0e12c79d8586bc61470e3088b666078b">YAML_PARSER_ERROR</a>,
+<br/>
+&nbsp;&nbsp;<a class="el" href="group__basic.html#gga2efbcde2e82238117982b789c5a8ea01a43d6eb640e50a1b1ec843cc54ab15f2b">YAML_COMPOSER_ERROR</a>,
+<br/>
+&nbsp;&nbsp;<a class="el" href="group__basic.html#gga2efbcde2e82238117982b789c5a8ea01ae80fef003be3d7e72ed7acae7984004c">YAML_WRITER_ERROR</a>,
+<br/>
+&nbsp;&nbsp;<a class="el" href="group__basic.html#gga2efbcde2e82238117982b789c5a8ea01a8ec99a26382dd2853a5550027f6e9db1">YAML_EMITTER_ERROR</a>
+<br/>
+ }</td></tr>
+<tr><td class="mdescLeft">&nbsp;</td><td class="mdescRight"><p>Many bad things could happen with the parser and emitter. </p>
+ <a href="group__basic.html#ga2efbcde2e82238117982b789c5a8ea01">More...</a><br/></td></tr>
+<tr><td class="memItemLeft" align="right" valign="top">enum &nbsp;</td><td class="memItemRight" valign="bottom"><a class="el" href="group__styles.html#ga435ae8886b70c16830d853b6c566e2e0">yaml_scalar_style_e</a> { <br/>
+&nbsp;&nbsp;<a class="el" href="group__styles.html#gga435ae8886b70c16830d853b6c566e2e0aead38b3e6846302ee032927267c34ae0">YAML_ANY_SCALAR_STYLE</a>,
+<br/>
+&nbsp;&nbsp;<a class="el" href="group__styles.html#gga435ae8886b70c16830d853b6c566e2e0afd62a761a36cf56e1f0414fb391db0e6">YAML_PLAIN_SCALAR_STYLE</a>,
+<br/>
+&nbsp;&nbsp;<a class="el" href="group__styles.html#gga435ae8886b70c16830d853b6c566e2e0a68a2af452008e3af3f6de14318dfb2c6">YAML_SINGLE_QUOTED_SCALAR_STYLE</a>,
+<br/>
+&nbsp;&nbsp;<a class="el" href="group__styles.html#gga435ae8886b70c16830d853b6c566e2e0af6fdfd14690361f4937d67d1f0f011d3">YAML_DOUBLE_QUOTED_SCALAR_STYLE</a>,
+<br/>
+&nbsp;&nbsp;<a class="el" href="group__styles.html#gga435ae8886b70c16830d853b6c566e2e0a542d1ac1bf5c3434df3d2a757d0a8ca0">YAML_LITERAL_SCALAR_STYLE</a>,
+<br/>
+&nbsp;&nbsp;<a class="el" href="group__styles.html#gga435ae8886b70c16830d853b6c566e2e0aa67c3de37dc127986b08bdbe07cee607">YAML_FOLDED_SCALAR_STYLE</a>
+<br/>
+ }</td></tr>
+<tr><td class="mdescLeft">&nbsp;</td><td class="mdescRight"><p>Scalar styles. </p>
+ <a href="group__styles.html#ga435ae8886b70c16830d853b6c566e2e0">More...</a><br/></td></tr>
+<tr><td class="memItemLeft" align="right" valign="top">enum &nbsp;</td><td class="memItemRight" valign="bottom"><a class="el" href="group__styles.html#ga5079a4ab96e398371c60423abd88ccc0">yaml_sequence_style_e</a> { <br/>
+&nbsp;&nbsp;<a class="el" href="group__styles.html#gga5079a4ab96e398371c60423abd88ccc0a5a10d6f70339876b76e5a002dd16212f">YAML_ANY_SEQUENCE_STYLE</a>,
+<br/>
+&nbsp;&nbsp;<a class="el" href="group__styles.html#gga5079a4ab96e398371c60423abd88ccc0a65f99099ef4ecdcf99bbdd798b5dcbb5">YAML_BLOCK_SEQUENCE_STYLE</a>,
+<br/>
+&nbsp;&nbsp;<a class="el" href="group__styles.html#gga5079a4ab96e398371c60423abd88ccc0ae511554b654ebca464d1feec12501d80">YAML_FLOW_SEQUENCE_STYLE</a>
+<br/>
+ }</td></tr>
+<tr><td class="mdescLeft">&nbsp;</td><td class="mdescRight"><p>Sequence styles. </p>
+ <a href="group__styles.html#ga5079a4ab96e398371c60423abd88ccc0">More...</a><br/></td></tr>
+<tr><td class="memItemLeft" align="right" valign="top">enum &nbsp;</td><td class="memItemRight" valign="bottom"><a class="el" href="group__styles.html#ga1efef592e2e3df6f00432c04ef77d98f">yaml_mapping_style_e</a> { <br/>
+&nbsp;&nbsp;<a class="el" href="group__styles.html#gga1efef592e2e3df6f00432c04ef77d98fac580a83312204ea142c3d08a4954a74a">YAML_ANY_MAPPING_STYLE</a>,
+<br/>
+&nbsp;&nbsp;<a class="el" href="group__styles.html#gga1efef592e2e3df6f00432c04ef77d98fad5e70fe97009c8247a45f4620f071874">YAML_BLOCK_MAPPING_STYLE</a>,
+<br/>
+&nbsp;&nbsp;<a class="el" href="group__styles.html#gga1efef592e2e3df6f00432c04ef77d98fa4c5425077b0310cbf84e1d73e20b42d3">YAML_FLOW_MAPPING_STYLE</a>
+<br/>
+ }</td></tr>
+<tr><td class="mdescLeft">&nbsp;</td><td class="mdescRight"><p>Mapping styles. </p>
+ <a href="group__styles.html#ga1efef592e2e3df6f00432c04ef77d98f">More...</a><br/></td></tr>
+<tr><td class="memItemLeft" align="right" valign="top">enum &nbsp;</td><td class="memItemRight" valign="bottom"><a class="el" href="group__tokens.html#gaae955b10aa6b5f922de64873bf4ccdbd">yaml_token_type_e</a> { <br/>
+&nbsp;&nbsp;<a class="el" href="group__tokens.html#ggaae955b10aa6b5f922de64873bf4ccdbda66c1b8eec0cc6402c0fb4b2d1b017f92">YAML_NO_TOKEN</a>,
+<br/>
+&nbsp;&nbsp;<a class="el" href="group__tokens.html#ggaae955b10aa6b5f922de64873bf4ccdbdaf5f42f2d5025e5629034848d2e1db6c9">YAML_STREAM_START_TOKEN</a>,
+<br/>
+&nbsp;&nbsp;<a class="el" href="group__tokens.html#ggaae955b10aa6b5f922de64873bf4ccdbda020a0a266ed7fc4902dd02750512dc19">YAML_STREAM_END_TOKEN</a>,
+<br/>
+&nbsp;&nbsp;<a class="el" href="group__tokens.html#ggaae955b10aa6b5f922de64873bf4ccdbdaa15a96ec81c00c7db8f83628a89542e4">YAML_VERSION_DIRECTIVE_TOKEN</a>,
+<br/>
+&nbsp;&nbsp;<a class="el" href="group__tokens.html#ggaae955b10aa6b5f922de64873bf4ccdbdaed517a61b868769e2bfced40678be414">YAML_TAG_DIRECTIVE_TOKEN</a>,
+<br/>
+&nbsp;&nbsp;<a class="el" href="group__tokens.html#ggaae955b10aa6b5f922de64873bf4ccdbdabcafcdb506886387f93cca734ddfd670">YAML_DOCUMENT_START_TOKEN</a>,
+<br/>
+&nbsp;&nbsp;<a class="el" href="group__tokens.html#ggaae955b10aa6b5f922de64873bf4ccdbda8d0908a82229f44d5ea92a2c380f4579">YAML_DOCUMENT_END_TOKEN</a>,
+<br/>
+&nbsp;&nbsp;<a class="el" href="group__tokens.html#ggaae955b10aa6b5f922de64873bf4ccdbda4bfddc427da159168ee47267cbeea94f">YAML_BLOCK_SEQUENCE_START_TOKEN</a>,
+<br/>
+&nbsp;&nbsp;<a class="el" href="group__tokens.html#ggaae955b10aa6b5f922de64873bf4ccdbda9a95db99bd99f7f9b4e1e879106297dc">YAML_BLOCK_MAPPING_START_TOKEN</a>,
+<br/>
+&nbsp;&nbsp;<a class="el" href="group__tokens.html#ggaae955b10aa6b5f922de64873bf4ccdbda439948425097b4fc853f39f0de14a5ff">YAML_BLOCK_END_TOKEN</a>,
+<br/>
+&nbsp;&nbsp;<a class="el" href="group__tokens.html#ggaae955b10aa6b5f922de64873bf4ccdbda862a2390be4abd59bb7bf55b18d9260c">YAML_FLOW_SEQUENCE_START_TOKEN</a>,
+<br/>
+&nbsp;&nbsp;<a class="el" href="group__tokens.html#ggaae955b10aa6b5f922de64873bf4ccdbdab3496580bee30936f756e0102e98f331">YAML_FLOW_SEQUENCE_END_TOKEN</a>,
+<br/>
+&nbsp;&nbsp;<a class="el" href="group__tokens.html#ggaae955b10aa6b5f922de64873bf4ccdbdaff68a3f7c000c5294211eef8f4156100">YAML_FLOW_MAPPING_START_TOKEN</a>,
+<br/>
+&nbsp;&nbsp;<a class="el" href="group__tokens.html#ggaae955b10aa6b5f922de64873bf4ccdbdaad99bf47234572d9d0eeea7669d1e769">YAML_FLOW_MAPPING_END_TOKEN</a>,
+<br/>
+&nbsp;&nbsp;<a class="el" href="group__tokens.html#ggaae955b10aa6b5f922de64873bf4ccdbdaa9bdf1d6da41fcd4d356c7bcfa0227b4">YAML_BLOCK_ENTRY_TOKEN</a>,
+<br/>
+&nbsp;&nbsp;<a class="el" href="group__tokens.html#ggaae955b10aa6b5f922de64873bf4ccdbdaf11ab5655350e4cf0559f78382daa93f">YAML_FLOW_ENTRY_TOKEN</a>,
+<br/>
+&nbsp;&nbsp;<a class="el" href="group__tokens.html#ggaae955b10aa6b5f922de64873bf4ccdbda94d701c1f5bb8a392bb45b7cbf4bc2a5">YAML_KEY_TOKEN</a>,
+<br/>
+&nbsp;&nbsp;<a class="el" href="group__tokens.html#ggaae955b10aa6b5f922de64873bf4ccdbdaac46e8a6a6e0614de322c7b53d785b4e">YAML_VALUE_TOKEN</a>,
+<br/>
+&nbsp;&nbsp;<a class="el" href="group__tokens.html#ggaae955b10aa6b5f922de64873bf4ccdbda080c398f6fc31f9ab35c7cf94cf948c2">YAML_ALIAS_TOKEN</a>,
+<br/>
+&nbsp;&nbsp;<a class="el" href="group__tokens.html#ggaae955b10aa6b5f922de64873bf4ccdbda7f0855938c5ccc4820b68ddd7985a5d0">YAML_ANCHOR_TOKEN</a>,
+<br/>
+&nbsp;&nbsp;<a class="el" href="group__tokens.html#ggaae955b10aa6b5f922de64873bf4ccdbda8f02c514b72f29bd3c26b7c832d8152d">YAML_TAG_TOKEN</a>,
+<br/>
+&nbsp;&nbsp;<a class="el" href="group__tokens.html#ggaae955b10aa6b5f922de64873bf4ccdbda107a78f31dd9857d06e9ead7936ea51e">YAML_SCALAR_TOKEN</a>
+<br/>
+ }</td></tr>
+<tr><td class="mdescLeft">&nbsp;</td><td class="mdescRight"><p>Token types. </p>
+ <a href="group__tokens.html#gaae955b10aa6b5f922de64873bf4ccdbd">More...</a><br/></td></tr>
+<tr><td class="memItemLeft" align="right" valign="top">enum &nbsp;</td><td class="memItemRight" valign="bottom"><a class="el" href="group__events.html#ga454fccebae859c188fe3e7fa3299577c">yaml_event_type_e</a> { <br/>
+&nbsp;&nbsp;<a class="el" href="group__events.html#gga454fccebae859c188fe3e7fa3299577caefda9f31823fe534f094f4241d5e5eac">YAML_NO_EVENT</a>,
+<br/>
+&nbsp;&nbsp;<a class="el" href="group__events.html#gga454fccebae859c188fe3e7fa3299577caa742e9970f14d1fe7ce4d178d79e8465">YAML_STREAM_START_EVENT</a>,
+<br/>
+&nbsp;&nbsp;<a class="el" href="group__events.html#gga454fccebae859c188fe3e7fa3299577ca4a5e76ed540645102a13352af2503d3b">YAML_STREAM_END_EVENT</a>,
+<br/>
+&nbsp;&nbsp;<a class="el" href="group__events.html#gga454fccebae859c188fe3e7fa3299577caf4ca2b0f538029cf054cdebd09d3d6d3">YAML_DOCUMENT_START_EVENT</a>,
+<br/>
+&nbsp;&nbsp;<a class="el" href="group__events.html#gga454fccebae859c188fe3e7fa3299577ca355ec471f963827c96512e529676276f">YAML_DOCUMENT_END_EVENT</a>,
+<br/>
+&nbsp;&nbsp;<a class="el" href="group__events.html#gga454fccebae859c188fe3e7fa3299577ca8c3ce47705cfbd49a87a32bdbe544eb7">YAML_ALIAS_EVENT</a>,
+<br/>
+&nbsp;&nbsp;<a class="el" href="group__events.html#gga454fccebae859c188fe3e7fa3299577ca8b16dc795bb228e33d647d1bdf683713">YAML_SCALAR_EVENT</a>,
+<br/>
+&nbsp;&nbsp;<a class="el" href="group__events.html#gga454fccebae859c188fe3e7fa3299577cad90ccd43e238221f542defa3c8eaf093">YAML_SEQUENCE_START_EVENT</a>,
+<br/>
+&nbsp;&nbsp;<a class="el" href="group__events.html#gga454fccebae859c188fe3e7fa3299577ca2a8af98529275987d73eb307b6a92898">YAML_SEQUENCE_END_EVENT</a>,
+<br/>
+&nbsp;&nbsp;<a class="el" href="group__events.html#gga454fccebae859c188fe3e7fa3299577ca0f6982f6d1c325ee71af518c2c66dae8">YAML_MAPPING_START_EVENT</a>,
+<br/>
+&nbsp;&nbsp;<a class="el" href="group__events.html#gga454fccebae859c188fe3e7fa3299577cadc3dc55f17056a657005fecfb80fbd30">YAML_MAPPING_END_EVENT</a>
+<br/>
+ }</td></tr>
+<tr><td class="mdescLeft">&nbsp;</td><td class="mdescRight"><p>Event types. </p>
+ <a href="group__events.html#ga454fccebae859c188fe3e7fa3299577c">More...</a><br/></td></tr>
+<tr><td class="memItemLeft" align="right" valign="top">enum &nbsp;</td><td class="memItemRight" valign="bottom"><a class="el" href="group__nodes.html#ga0897d4b6bdd1b56c7a5fa0ff17b4f798">yaml_node_type_e</a> { <br/>
+&nbsp;&nbsp;<a class="el" href="group__nodes.html#gga0897d4b6bdd1b56c7a5fa0ff17b4f798a0fa87c0e89c4d4136cb47165e6917739">YAML_NO_NODE</a>,
+<br/>
+&nbsp;&nbsp;<a class="el" href="group__nodes.html#gga0897d4b6bdd1b56c7a5fa0ff17b4f798a413ec8ce6b728c9ace703d194b370a45">YAML_SCALAR_NODE</a>,
+<br/>
+&nbsp;&nbsp;<a class="el" href="group__nodes.html#gga0897d4b6bdd1b56c7a5fa0ff17b4f798a6c03b52f7ee737982eac5e4001faac15">YAML_SEQUENCE_NODE</a>,
+<br/>
+&nbsp;&nbsp;<a class="el" href="group__nodes.html#gga0897d4b6bdd1b56c7a5fa0ff17b4f798ac1a08580e3a70973583fc85e3e097ee6">YAML_MAPPING_NODE</a>
+<br/>
+ }</td></tr>
+<tr><td class="mdescLeft">&nbsp;</td><td class="mdescRight"><p>Node types. </p>
+ <a href="group__nodes.html#ga0897d4b6bdd1b56c7a5fa0ff17b4f798">More...</a><br/></td></tr>
+<tr><td class="memItemLeft" align="right" valign="top">enum &nbsp;</td><td class="memItemRight" valign="bottom"><a class="el" href="group__parser.html#gad39c19e7b0df6f542ca97806535b57c5">yaml_parser_state_e</a> { <br/>
+&nbsp;&nbsp;<a class="el" href="group__parser.html#ggad39c19e7b0df6f542ca97806535b57c5ae7b52e16bf002db5cf2944596d8c880e">YAML_PARSE_STREAM_START_STATE</a>,
+<br/>
+&nbsp;&nbsp;<a class="el" href="group__parser.html#ggad39c19e7b0df6f542ca97806535b57c5a8255725d67d5bd3574fc7df4db1c6c84">YAML_PARSE_IMPLICIT_DOCUMENT_START_STATE</a>,
+<br/>
+&nbsp;&nbsp;<a class="el" href="group__parser.html#ggad39c19e7b0df6f542ca97806535b57c5aa06d10f700d245caecfc6074a6c52fde">YAML_PARSE_DOCUMENT_START_STATE</a>,
+<br/>
+&nbsp;&nbsp;<a class="el" href="group__parser.html#ggad39c19e7b0df6f542ca97806535b57c5ae444c7652c8029b0ef80068eaaaa3d4d">YAML_PARSE_DOCUMENT_CONTENT_STATE</a>,
+<br/>
+&nbsp;&nbsp;<a class="el" href="group__parser.html#ggad39c19e7b0df6f542ca97806535b57c5aeef06d7f13fa4501146a5b9876c98239">YAML_PARSE_DOCUMENT_END_STATE</a>,
+<br/>
+&nbsp;&nbsp;<a class="el" href="group__parser.html#ggad39c19e7b0df6f542ca97806535b57c5ae1893c0835bacf05cdc21ed181fb75f1">YAML_PARSE_BLOCK_NODE_STATE</a>,
+<br/>
+&nbsp;&nbsp;<a class="el" href="group__parser.html#ggad39c19e7b0df6f542ca97806535b57c5acbd390af0d3919fe0382d03c284ff3b5">YAML_PARSE_BLOCK_NODE_OR_INDENTLESS_SEQUENCE_STATE</a>,
+<br/>
+&nbsp;&nbsp;<a class="el" href="group__parser.html#ggad39c19e7b0df6f542ca97806535b57c5a5bb321f9d18c5b208a71c04bbcbd1d01">YAML_PARSE_FLOW_NODE_STATE</a>,
+<br/>
+&nbsp;&nbsp;<a class="el" href="group__parser.html#ggad39c19e7b0df6f542ca97806535b57c5a5bb5f95fc5f1a258ee8e9db0ed25b2d9">YAML_PARSE_BLOCK_SEQUENCE_FIRST_ENTRY_STATE</a>,
+<br/>
+&nbsp;&nbsp;<a class="el" href="group__parser.html#ggad39c19e7b0df6f542ca97806535b57c5a8a6cb1f12fe08eee7fc2fa854dbd5b1a">YAML_PARSE_BLOCK_SEQUENCE_ENTRY_STATE</a>,
+<br/>
+&nbsp;&nbsp;<a class="el" href="group__parser.html#ggad39c19e7b0df6f542ca97806535b57c5af7095f2141cf9887489e832f0ec61fbd">YAML_PARSE_INDENTLESS_SEQUENCE_ENTRY_STATE</a>,
+<br/>
+&nbsp;&nbsp;<a class="el" href="group__parser.html#ggad39c19e7b0df6f542ca97806535b57c5afebcb5bbd67d112d9ecfa633155f0644">YAML_PARSE_BLOCK_MAPPING_FIRST_KEY_STATE</a>,
+<br/>
+&nbsp;&nbsp;<a class="el" href="group__parser.html#ggad39c19e7b0df6f542ca97806535b57c5a2df81c86e90b874b415ecb19e72efe45">YAML_PARSE_BLOCK_MAPPING_KEY_STATE</a>,
+<br/>
+&nbsp;&nbsp;<a class="el" href="group__parser.html#ggad39c19e7b0df6f542ca97806535b57c5ae94acf5685fa1538b225413f154465c2">YAML_PARSE_BLOCK_MAPPING_VALUE_STATE</a>,
+<br/>
+&nbsp;&nbsp;<a class="el" href="group__parser.html#ggad39c19e7b0df6f542ca97806535b57c5a3f54830989c12cc4a63494df792eeb08">YAML_PARSE_FLOW_SEQUENCE_FIRST_ENTRY_STATE</a>,
+<br/>
+&nbsp;&nbsp;<a class="el" href="group__parser.html#ggad39c19e7b0df6f542ca97806535b57c5a0e50f3841eb0d37ad159e64c4a9a1171">YAML_PARSE_FLOW_SEQUENCE_ENTRY_STATE</a>,
+<br/>
+&nbsp;&nbsp;<a class="el" href="group__parser.html#ggad39c19e7b0df6f542ca97806535b57c5a563e11601cf3a1d2a3efc1feb1b696a3">YAML_PARSE_FLOW_SEQUENCE_ENTRY_MAPPING_KEY_STATE</a>,
+<br/>
+&nbsp;&nbsp;<a class="el" href="group__parser.html#ggad39c19e7b0df6f542ca97806535b57c5a9e5ebb4bee4541e7a7025689c7fc66eb">YAML_PARSE_FLOW_SEQUENCE_ENTRY_MAPPING_VALUE_STATE</a>,
+<br/>
+&nbsp;&nbsp;<a class="el" href="group__parser.html#ggad39c19e7b0df6f542ca97806535b57c5a397fd87de9227c64e5308481930b5eeb">YAML_PARSE_FLOW_SEQUENCE_ENTRY_MAPPING_END_STATE</a>,
+<br/>
+&nbsp;&nbsp;<a class="el" href="group__parser.html#ggad39c19e7b0df6f542ca97806535b57c5a91ac4bbb6629e2b768a3305fb707b7cd">YAML_PARSE_FLOW_MAPPING_FIRST_KEY_STATE</a>,
+<br/>
+&nbsp;&nbsp;<a class="el" href="group__parser.html#ggad39c19e7b0df6f542ca97806535b57c5a924f8eb891dc7527bf4db594a0b1bff8">YAML_PARSE_FLOW_MAPPING_KEY_STATE</a>,
+<br/>
+&nbsp;&nbsp;<a class="el" href="group__parser.html#ggad39c19e7b0df6f542ca97806535b57c5a3ba351f6cfba029248ada2c0720246d4">YAML_PARSE_FLOW_MAPPING_VALUE_STATE</a>,
+<br/>
+&nbsp;&nbsp;<a class="el" href="group__parser.html#ggad39c19e7b0df6f542ca97806535b57c5a5a8ec0af5c3314c1ad5e0569b6a5d6d2">YAML_PARSE_FLOW_MAPPING_EMPTY_VALUE_STATE</a>,
+<br/>
+&nbsp;&nbsp;<a class="el" href="group__parser.html#ggad39c19e7b0df6f542ca97806535b57c5a51fd3d45693e2240251996def375a2a2">YAML_PARSE_END_STATE</a>
+<br/>
+ }</td></tr>
+<tr><td class="mdescLeft">&nbsp;</td><td class="mdescRight"><p>The states of the parser. </p>
+ <a href="group__parser.html#gad39c19e7b0df6f542ca97806535b57c5">More...</a><br/></td></tr>
+<tr><td class="memItemLeft" align="right" valign="top">enum &nbsp;</td><td class="memItemRight" valign="bottom"><a class="el" href="group__emitter.html#ga387b79da11c3941e43a56947263aa721">yaml_emitter_state_e</a> { <br/>
+&nbsp;&nbsp;<a class="el" href="group__emitter.html#gga387b79da11c3941e43a56947263aa721aa013a33dab710fe9a30ba014af27b81d">YAML_EMIT_STREAM_START_STATE</a>,
+<br/>
+&nbsp;&nbsp;<a class="el" href="group__emitter.html#gga387b79da11c3941e43a56947263aa721ab1ae25188f02581a137f66c4b6e084ae">YAML_EMIT_FIRST_DOCUMENT_START_STATE</a>,
+<br/>
+&nbsp;&nbsp;<a class="el" href="group__emitter.html#gga387b79da11c3941e43a56947263aa721a678d8c3146f0b2c84e0fc537a9b1109f">YAML_EMIT_DOCUMENT_START_STATE</a>,
+<br/>
+&nbsp;&nbsp;<a class="el" href="group__emitter.html#gga387b79da11c3941e43a56947263aa721a5ce3ed6155496a6fbd7384e310c58bec">YAML_EMIT_DOCUMENT_CONTENT_STATE</a>,
+<br/>
+&nbsp;&nbsp;<a class="el" href="group__emitter.html#gga387b79da11c3941e43a56947263aa721a100cad4538be033202da4bb85f8443d3">YAML_EMIT_DOCUMENT_END_STATE</a>,
+<br/>
+&nbsp;&nbsp;<a class="el" href="group__emitter.html#gga387b79da11c3941e43a56947263aa721a5a36fc535f3a5720fbb86712959e5654">YAML_EMIT_FLOW_SEQUENCE_FIRST_ITEM_STATE</a>,
+<br/>
+&nbsp;&nbsp;<a class="el" href="group__emitter.html#gga387b79da11c3941e43a56947263aa721aded45f1dee80027d7b9c6ce061c08767">YAML_EMIT_FLOW_SEQUENCE_ITEM_STATE</a>,
+<br/>
+&nbsp;&nbsp;<a class="el" href="group__emitter.html#gga387b79da11c3941e43a56947263aa721ab811f3d642dacc7c413af2c32356f894">YAML_EMIT_FLOW_MAPPING_FIRST_KEY_STATE</a>,
+<br/>
+&nbsp;&nbsp;<a class="el" href="group__emitter.html#gga387b79da11c3941e43a56947263aa721ababf835ee5cd4c6de2231e2a49e40626">YAML_EMIT_FLOW_MAPPING_KEY_STATE</a>,
+<br/>
+&nbsp;&nbsp;<a class="el" href="group__emitter.html#gga387b79da11c3941e43a56947263aa721aa6f687a6b57e727f0e7b7a2687ad7383">YAML_EMIT_FLOW_MAPPING_SIMPLE_VALUE_STATE</a>,
+<br/>
+&nbsp;&nbsp;<a class="el" href="group__emitter.html#gga387b79da11c3941e43a56947263aa721acb6dbcb535248b8fde779aeedc957b2e">YAML_EMIT_FLOW_MAPPING_VALUE_STATE</a>,
+<br/>
+&nbsp;&nbsp;<a class="el" href="group__emitter.html#gga387b79da11c3941e43a56947263aa721a68af7c090c6d0187788e390341f0cc4d">YAML_EMIT_BLOCK_SEQUENCE_FIRST_ITEM_STATE</a>,
+<br/>
+&nbsp;&nbsp;<a class="el" href="group__emitter.html#gga387b79da11c3941e43a56947263aa721a8197c180c3cefee7b67304e17b52c5ff">YAML_EMIT_BLOCK_SEQUENCE_ITEM_STATE</a>,
+<br/>
+&nbsp;&nbsp;<a class="el" href="group__emitter.html#gga387b79da11c3941e43a56947263aa721aee36d46c1facecfd73fab73e3343226e">YAML_EMIT_BLOCK_MAPPING_FIRST_KEY_STATE</a>,
+<br/>
+&nbsp;&nbsp;<a class="el" href="group__emitter.html#gga387b79da11c3941e43a56947263aa721a58495cae63b8c3d7c389b1281baeec05">YAML_EMIT_BLOCK_MAPPING_KEY_STATE</a>,
+<br/>
+&nbsp;&nbsp;<a class="el" href="group__emitter.html#gga387b79da11c3941e43a56947263aa721a4aa3c6bf2f2d976c47289c741d7a8704">YAML_EMIT_BLOCK_MAPPING_SIMPLE_VALUE_STATE</a>,
+<br/>
+&nbsp;&nbsp;<a class="el" href="group__emitter.html#gga387b79da11c3941e43a56947263aa721a7e0f7fac64fc64bb2bc9fe2ec93ca564">YAML_EMIT_BLOCK_MAPPING_VALUE_STATE</a>,
+<br/>
+&nbsp;&nbsp;<a class="el" href="group__emitter.html#gga387b79da11c3941e43a56947263aa721a2a0232912eaf4eeb06594ee6157dfbc0">YAML_EMIT_END_STATE</a>
+<br/>
+ }</td></tr>
+<tr><td class="mdescLeft">&nbsp;</td><td class="mdescRight"><p>The emitter states. </p>
+ <a href="group__emitter.html#ga387b79da11c3941e43a56947263aa721">More...</a><br/></td></tr>
+<tr><td colspan="2"><h2><a name="func-members"></a>
+Functions</h2></td></tr>
+<tr><td class="memItemLeft" align="right" valign="top">const char *&nbsp;</td><td class="memItemRight" valign="bottom"><a class="el" href="group__version.html#gaf1ba5c1c34e809db5047d79a9fa85a73">yaml_get_version_string</a> (void)</td></tr>
+<tr><td class="mdescLeft">&nbsp;</td><td class="mdescRight">Get the library version as a string. <a href="group__version.html#gaf1ba5c1c34e809db5047d79a9fa85a73"></a><br/></td></tr>
+<tr><td class="memItemLeft" align="right" valign="top">void&nbsp;</td><td class="memItemRight" valign="bottom"><a class="el" href="group__version.html#gaec764c91f3e181ae63d3d59b7980fe78">yaml_get_version</a> (int *major, int *minor, int *patch)</td></tr>
+<tr><td class="mdescLeft">&nbsp;</td><td class="mdescRight">Get the library version numbers. <a href="group__version.html#gaec764c91f3e181ae63d3d59b7980fe78"></a><br/></td></tr>
+<tr><td class="memItemLeft" align="right" valign="top">void&nbsp;</td><td class="memItemRight" valign="bottom"><a class="el" href="group__tokens.html#ga3140131870e38e27f92a8fd286e5c004">yaml_token_delete</a> (<a class="el" href="structyaml__token__s.html">yaml_token_t</a> *token)</td></tr>
+<tr><td class="mdescLeft">&nbsp;</td><td class="mdescRight">Free any memory allocated for a token object. <a href="group__tokens.html#ga3140131870e38e27f92a8fd286e5c004"></a><br/></td></tr>
+<tr><td class="memItemLeft" align="right" valign="top">int&nbsp;</td><td class="memItemRight" valign="bottom"><a class="el" href="group__events.html#ga0650d255b23d9aae13c839f4ab3ec2ab">yaml_stream_start_event_initialize</a> (<a class="el" href="structyaml__event__s.html">yaml_event_t</a> *event, <a class="el" href="group__basic.html#ga2170996d7e636397b5e6bc0c1b7df7c6">yaml_encoding_t</a> encoding)</td></tr>
+<tr><td class="mdescLeft">&nbsp;</td><td class="mdescRight">Create the STREAM-START event. <a href="group__events.html#ga0650d255b23d9aae13c839f4ab3ec2ab"></a><br/></td></tr>
+<tr><td class="memItemLeft" align="right" valign="top">int&nbsp;</td><td class="memItemRight" valign="bottom"><a class="el" href="group__events.html#ga84cf0c3ff01251c852c71624e64df9fe">yaml_stream_end_event_initialize</a> (<a class="el" href="structyaml__event__s.html">yaml_event_t</a> *event)</td></tr>
+<tr><td class="mdescLeft">&nbsp;</td><td class="mdescRight">Create the STREAM-END event. <a href="group__events.html#ga84cf0c3ff01251c852c71624e64df9fe"></a><br/></td></tr>
+<tr><td class="memItemLeft" align="right" valign="top">int&nbsp;</td><td class="memItemRight" valign="bottom"><a class="el" href="group__events.html#ga527e89302e1c969fbea5aa45664bf51c">yaml_document_start_event_initialize</a> (<a class="el" href="structyaml__event__s.html">yaml_event_t</a> *event, <a class="el" href="structyaml__version__directive__s.html">yaml_version_directive_t</a> *version_directive, <a class="el" href="structyaml__tag__directive__s.html">yaml_tag_directive_t</a> *tag_directives_start, <a class="el" href="structyaml__tag__directive__s.html">yaml_tag_directive_t</a> *tag_directives_end, int implicit)</td></tr>
+<tr><td class="mdescLeft">&nbsp;</td><td class="mdescRight">Create the DOCUMENT-START event. <a href="group__events.html#ga527e89302e1c969fbea5aa45664bf51c"></a><br/></td></tr>
+<tr><td class="memItemLeft" align="right" valign="top">int&nbsp;</td><td class="memItemRight" valign="bottom"><a class="el" href="group__events.html#ga8bae16548ee88f8a5ca15204f8c30344">yaml_document_end_event_initialize</a> (<a class="el" href="structyaml__event__s.html">yaml_event_t</a> *event, int implicit)</td></tr>
+<tr><td class="mdescLeft">&nbsp;</td><td class="mdescRight">Create the DOCUMENT-END event. <a href="group__events.html#ga8bae16548ee88f8a5ca15204f8c30344"></a><br/></td></tr>
+<tr><td class="memItemLeft" align="right" valign="top">int&nbsp;</td><td class="memItemRight" valign="bottom"><a class="el" href="group__events.html#gade4c15b75eb9a8035e04d4f0dd23f005">yaml_alias_event_initialize</a> (<a class="el" href="structyaml__event__s.html">yaml_event_t</a> *event, <a class="el" href="group__basic.html#gaf8657e81f0b8b05d1a081001fc6cb8bd">yaml_char_t</a> *anchor)</td></tr>
+<tr><td class="mdescLeft">&nbsp;</td><td class="mdescRight">Create an ALIAS event. <a href="group__events.html#gade4c15b75eb9a8035e04d4f0dd23f005"></a><br/></td></tr>
+<tr><td class="memItemLeft" align="right" valign="top">int&nbsp;</td><td class="memItemRight" valign="bottom"><a class="el" href="group__events.html#gafc60a1a437385e19e6fb3be075958c8c">yaml_scalar_event_initialize</a> (<a class="el" href="structyaml__event__s.html">yaml_event_t</a> *event, <a class="el" href="group__basic.html#gaf8657e81f0b8b05d1a081001fc6cb8bd">yaml_char_t</a> *anchor, <a class="el" href="group__basic.html#gaf8657e81f0b8b05d1a081001fc6cb8bd">yaml_char_t</a> *tag, <a class="el" href="group__basic.html#gaf8657e81f0b8b05d1a081001fc6cb8bd">yaml_char_t</a> *value, int length, int plain_implicit, int quoted_implicit, <a class="el" href="group__styles.html#ga3fa6405631e1afe5bd5c488a6c5e8065">yaml_scalar_style_t</a> style)</td></tr>
+<tr><td class="mdescLeft">&nbsp;</td><td class="mdescRight">Create a SCALAR event. <a href="group__events.html#gafc60a1a437385e19e6fb3be075958c8c"></a><br/></td></tr>
+<tr><td class="memItemLeft" align="right" valign="top">int&nbsp;</td><td class="memItemRight" valign="bottom"><a class="el" href="group__events.html#ga53aea428c768d7b131923d08c904b4eb">yaml_sequence_start_event_initialize</a> (<a class="el" href="structyaml__event__s.html">yaml_event_t</a> *event, <a class="el" href="group__basic.html#gaf8657e81f0b8b05d1a081001fc6cb8bd">yaml_char_t</a> *anchor, <a class="el" href="group__basic.html#gaf8657e81f0b8b05d1a081001fc6cb8bd">yaml_char_t</a> *tag, int implicit, <a class="el" href="group__styles.html#ga58a1123d271e56c72de6abf852ac4dc2">yaml_sequence_style_t</a> style)</td></tr>
+<tr><td class="mdescLeft">&nbsp;</td><td class="mdescRight">Create a SEQUENCE-START event. <a href="group__events.html#ga53aea428c768d7b131923d08c904b4eb"></a><br/></td></tr>
+<tr><td class="memItemLeft" align="right" valign="top">int&nbsp;</td><td class="memItemRight" valign="bottom"><a class="el" href="group__events.html#ga99fdfa4b9d42b64d8171c9b22f334b1c">yaml_sequence_end_event_initialize</a> (<a class="el" href="structyaml__event__s.html">yaml_event_t</a> *event)</td></tr>
+<tr><td class="mdescLeft">&nbsp;</td><td class="mdescRight">Create a SEQUENCE-END event. <a href="group__events.html#ga99fdfa4b9d42b64d8171c9b22f334b1c"></a><br/></td></tr>
+<tr><td class="memItemLeft" align="right" valign="top">int&nbsp;</td><td class="memItemRight" valign="bottom"><a class="el" href="group__events.html#ga0603cf8d20f0b6dfc3be04b6360134aa">yaml_mapping_start_event_initialize</a> (<a class="el" href="structyaml__event__s.html">yaml_event_t</a> *event, <a class="el" href="group__basic.html#gaf8657e81f0b8b05d1a081001fc6cb8bd">yaml_char_t</a> *anchor, <a class="el" href="group__basic.html#gaf8657e81f0b8b05d1a081001fc6cb8bd">yaml_char_t</a> *tag, int implicit, <a class="el" href="group__styles.html#gab47523846a5c5960e07367a28ea9750a">yaml_mapping_style_t</a> style)</td></tr>
+<tr><td class="mdescLeft">&nbsp;</td><td class="mdescRight">Create a MAPPING-START event. <a href="group__events.html#ga0603cf8d20f0b6dfc3be04b6360134aa"></a><br/></td></tr>
+<tr><td class="memItemLeft" align="right" valign="top">int&nbsp;</td><td class="memItemRight" valign="bottom"><a class="el" href="group__events.html#ga3afaf8b3aca2ec902a4e268f12adb0c2">yaml_mapping_end_event_initialize</a> (<a class="el" href="structyaml__event__s.html">yaml_event_t</a> *event)</td></tr>
+<tr><td class="mdescLeft">&nbsp;</td><td class="mdescRight">Create a MAPPING-END event. <a href="group__events.html#ga3afaf8b3aca2ec902a4e268f12adb0c2"></a><br/></td></tr>
+<tr><td class="memItemLeft" align="right" valign="top">void&nbsp;</td><td class="memItemRight" valign="bottom"><a class="el" href="group__events.html#ga5330d62ef52856aa53188137cb93a6a1">yaml_event_delete</a> (<a class="el" href="structyaml__event__s.html">yaml_event_t</a> *event)</td></tr>
+<tr><td class="mdescLeft">&nbsp;</td><td class="mdescRight">Free any memory allocated for an event object. <a href="group__events.html#ga5330d62ef52856aa53188137cb93a6a1"></a><br/></td></tr>
+<tr><td class="memItemLeft" align="right" valign="top">int&nbsp;</td><td class="memItemRight" valign="bottom"><a class="el" href="group__nodes.html#ga62a485c96f3b7962436a0da5e6f3cc89">yaml_document_initialize</a> (<a class="el" href="structyaml__document__s.html">yaml_document_t</a> *document, <a class="el" href="structyaml__version__directive__s.html">yaml_version_directive_t</a> *version_directive, <a class="el" href="structyaml__tag__directive__s.html">yaml_tag_directive_t</a> *tag_directives_start, <a class="el" href="structyaml__tag__directive__s.html">yaml_tag_directive_t</a> *tag_directives_end, int start_implicit, int end_implicit)</td></tr>
+<tr><td class="mdescLeft">&nbsp;</td><td class="mdescRight">Create a YAML document. <a href="group__nodes.html#ga62a485c96f3b7962436a0da5e6f3cc89"></a><br/></td></tr>
+<tr><td class="memItemLeft" align="right" valign="top">void&nbsp;</td><td class="memItemRight" valign="bottom"><a class="el" href="group__nodes.html#ga2754b1544fb4e110e83fafbc708b0672">yaml_document_delete</a> (<a class="el" href="structyaml__document__s.html">yaml_document_t</a> *document)</td></tr>
+<tr><td class="mdescLeft">&nbsp;</td><td class="mdescRight">Delete a YAML document and all its nodes. <a href="group__nodes.html#ga2754b1544fb4e110e83fafbc708b0672"></a><br/></td></tr>
+<tr><td class="memItemLeft" align="right" valign="top"><a class="el" href="structyaml__node__s.html">yaml_node_t</a> *&nbsp;</td><td class="memItemRight" valign="bottom"><a class="el" href="group__nodes.html#gafa1feabc9747dbded4dca24e27d3c21a">yaml_document_get_node</a> (<a class="el" href="structyaml__document__s.html">yaml_document_t</a> *document, int index)</td></tr>
+<tr><td class="mdescLeft">&nbsp;</td><td class="mdescRight">Get a node of a YAML document. <a href="group__nodes.html#gafa1feabc9747dbded4dca24e27d3c21a"></a><br/></td></tr>
+<tr><td class="memItemLeft" align="right" valign="top"><a class="el" href="structyaml__node__s.html">yaml_node_t</a> *&nbsp;</td><td class="memItemRight" valign="bottom"><a class="el" href="group__nodes.html#ga40eeaa68fb2f3be34c4fe34e7597d324">yaml_document_get_root_node</a> (<a class="el" href="structyaml__document__s.html">yaml_document_t</a> *document)</td></tr>
+<tr><td class="mdescLeft">&nbsp;</td><td class="mdescRight">Get the root of a YAML document node. <a href="group__nodes.html#ga40eeaa68fb2f3be34c4fe34e7597d324"></a><br/></td></tr>
+<tr><td class="memItemLeft" align="right" valign="top">int&nbsp;</td><td class="memItemRight" valign="bottom"><a class="el" href="group__nodes.html#ga45dab8b983b58a005557d4b01f5057b0">yaml_document_add_scalar</a> (<a class="el" href="structyaml__document__s.html">yaml_document_t</a> *document, <a class="el" href="group__basic.html#gaf8657e81f0b8b05d1a081001fc6cb8bd">yaml_char_t</a> *tag, <a class="el" href="group__basic.html#gaf8657e81f0b8b05d1a081001fc6cb8bd">yaml_char_t</a> *value, int length, <a class="el" href="group__styles.html#ga3fa6405631e1afe5bd5c488a6c5e8065">yaml_scalar_style_t</a> style)</td></tr>
+<tr><td class="mdescLeft">&nbsp;</td><td class="mdescRight">Create a SCALAR node and attach it to the document. <a href="group__nodes.html#ga45dab8b983b58a005557d4b01f5057b0"></a><br/></td></tr>
+<tr><td class="memItemLeft" align="right" valign="top">int&nbsp;</td><td class="memItemRight" valign="bottom"><a class="el" href="group__nodes.html#ga83b2f7fdd9a439397a42016bddad7786">yaml_document_add_sequence</a> (<a class="el" href="structyaml__document__s.html">yaml_document_t</a> *document, <a class="el" href="group__basic.html#gaf8657e81f0b8b05d1a081001fc6cb8bd">yaml_char_t</a> *tag, <a class="el" href="group__styles.html#ga58a1123d271e56c72de6abf852ac4dc2">yaml_sequence_style_t</a> style)</td></tr>
+<tr><td class="mdescLeft">&nbsp;</td><td class="mdescRight">Create a SEQUENCE node and attach it to the document. <a href="group__nodes.html#ga83b2f7fdd9a439397a42016bddad7786"></a><br/></td></tr>
+<tr><td class="memItemLeft" align="right" valign="top">int&nbsp;</td><td class="memItemRight" valign="bottom"><a class="el" href="group__nodes.html#ga45a9f8288704f99cd81dc5cb31329d34">yaml_document_add_mapping</a> (<a class="el" href="structyaml__document__s.html">yaml_document_t</a> *document, <a class="el" href="group__basic.html#gaf8657e81f0b8b05d1a081001fc6cb8bd">yaml_char_t</a> *tag, <a class="el" href="group__styles.html#gab47523846a5c5960e07367a28ea9750a">yaml_mapping_style_t</a> style)</td></tr>
+<tr><td class="mdescLeft">&nbsp;</td><td class="mdescRight">Create a MAPPING node and attach it to the document. <a href="group__nodes.html#ga45a9f8288704f99cd81dc5cb31329d34"></a><br/></td></tr>
+<tr><td class="memItemLeft" align="right" valign="top">int&nbsp;</td><td class="memItemRight" valign="bottom"><a class="el" href="group__nodes.html#ga16435917cd6c0261cd390fa8cf173b1b">yaml_document_append_sequence_item</a> (<a class="el" href="structyaml__document__s.html">yaml_document_t</a> *document, int sequence, int item)</td></tr>
+<tr><td class="mdescLeft">&nbsp;</td><td class="mdescRight">Add an item to a SEQUENCE node. <a href="group__nodes.html#ga16435917cd6c0261cd390fa8cf173b1b"></a><br/></td></tr>
+<tr><td class="memItemLeft" align="right" valign="top">int&nbsp;</td><td class="memItemRight" valign="bottom"><a class="el" href="group__nodes.html#ga2db27002d8a9ae06b1729d0ee06553d2">yaml_document_append_mapping_pair</a> (<a class="el" href="structyaml__document__s.html">yaml_document_t</a> *document, int mapping, int key, int value)</td></tr>
+<tr><td class="mdescLeft">&nbsp;</td><td class="mdescRight">Add a pair of a key and a value to a MAPPING node. <a href="group__nodes.html#ga2db27002d8a9ae06b1729d0ee06553d2"></a><br/></td></tr>
+<tr><td class="memItemLeft" align="right" valign="top">int&nbsp;</td><td class="memItemRight" valign="bottom"><a class="el" href="group__parser.html#gacc37ceeb5847e38a3fe24eb0c9b53965">yaml_parser_initialize</a> (<a class="el" href="structyaml__parser__s.html">yaml_parser_t</a> *parser)</td></tr>
+<tr><td class="mdescLeft">&nbsp;</td><td class="mdescRight">Initialize a parser. <a href="group__parser.html#gacc37ceeb5847e38a3fe24eb0c9b53965"></a><br/></td></tr>
+<tr><td class="memItemLeft" align="right" valign="top">void&nbsp;</td><td class="memItemRight" valign="bottom"><a class="el" href="group__parser.html#gaa27150107c4667c1024ec0651e2ac26b">yaml_parser_delete</a> (<a class="el" href="structyaml__parser__s.html">yaml_parser_t</a> *parser)</td></tr>
+<tr><td class="mdescLeft">&nbsp;</td><td class="mdescRight">Destroy a parser. <a href="group__parser.html#gaa27150107c4667c1024ec0651e2ac26b"></a><br/></td></tr>
+<tr><td class="memItemLeft" align="right" valign="top">void&nbsp;</td><td class="memItemRight" valign="bottom"><a class="el" href="group__parser.html#ga08a94762bf5f4c61f72c1da0a407df0d">yaml_parser_set_input_string</a> (<a class="el" href="structyaml__parser__s.html">yaml_parser_t</a> *parser, const unsigned char *input, size_t size)</td></tr>
+<tr><td class="mdescLeft">&nbsp;</td><td class="mdescRight">Set a string input. <a href="group__parser.html#ga08a94762bf5f4c61f72c1da0a407df0d"></a><br/></td></tr>
+<tr><td class="memItemLeft" align="right" valign="top">void&nbsp;</td><td class="memItemRight" valign="bottom"><a class="el" href="group__parser.html#gac3f00f8beb2365b1e4569692d64696b6">yaml_parser_set_input_file</a> (<a class="el" href="structyaml__parser__s.html">yaml_parser_t</a> *parser, FILE *file)</td></tr>
+<tr><td class="mdescLeft">&nbsp;</td><td class="mdescRight">Set a file input. <a href="group__parser.html#gac3f00f8beb2365b1e4569692d64696b6"></a><br/></td></tr>
+<tr><td class="memItemLeft" align="right" valign="top">void&nbsp;</td><td class="memItemRight" valign="bottom"><a class="el" href="group__parser.html#gabc67581bfa771a3e787d907d6914b8d9">yaml_parser_set_input</a> (<a class="el" href="structyaml__parser__s.html">yaml_parser_t</a> *parser, <a class="el" href="group__parser.html#ga4982f7e4e001ddb47d2819f38f0cd9d6">yaml_read_handler_t</a> *handler, void *data)</td></tr>
+<tr><td class="mdescLeft">&nbsp;</td><td class="mdescRight">Set a generic input handler. <a href="group__parser.html#gabc67581bfa771a3e787d907d6914b8d9"></a><br/></td></tr>
+<tr><td class="memItemLeft" align="right" valign="top">void&nbsp;</td><td class="memItemRight" valign="bottom"><a class="el" href="group__parser.html#ga9565b64975570ed34612a19adf02ae6a">yaml_parser_set_encoding</a> (<a class="el" href="structyaml__parser__s.html">yaml_parser_t</a> *parser, <a class="el" href="group__basic.html#ga2170996d7e636397b5e6bc0c1b7df7c6">yaml_encoding_t</a> encoding)</td></tr>
+<tr><td class="mdescLeft">&nbsp;</td><td class="mdescRight">Set the source encoding. <a href="group__parser.html#ga9565b64975570ed34612a19adf02ae6a"></a><br/></td></tr>
+<tr><td class="memItemLeft" align="right" valign="top">int&nbsp;</td><td class="memItemRight" valign="bottom"><a class="el" href="group__parser.html#ga6c2144f131ebd600a075d4ba654540f7">yaml_parser_scan</a> (<a class="el" href="structyaml__parser__s.html">yaml_parser_t</a> *parser, <a class="el" href="structyaml__token__s.html">yaml_token_t</a> *token)</td></tr>
+<tr><td class="mdescLeft">&nbsp;</td><td class="mdescRight">Scan the input stream and produce the next token. <a href="group__parser.html#ga6c2144f131ebd600a075d4ba654540f7"></a><br/></td></tr>
+<tr><td class="memItemLeft" align="right" valign="top">int&nbsp;</td><td class="memItemRight" valign="bottom"><a class="el" href="group__parser.html#ga559312fb137533d8b7e07f224fe0ec8f">yaml_parser_parse</a> (<a class="el" href="structyaml__parser__s.html">yaml_parser_t</a> *parser, <a class="el" href="structyaml__event__s.html">yaml_event_t</a> *event)</td></tr>
+<tr><td class="mdescLeft">&nbsp;</td><td class="mdescRight">Parse the input stream and produce the next parsing event. <a href="group__parser.html#ga559312fb137533d8b7e07f224fe0ec8f"></a><br/></td></tr>
+<tr><td class="memItemLeft" align="right" valign="top">int&nbsp;</td><td class="memItemRight" valign="bottom"><a class="el" href="group__parser.html#ga9ef7d6e9494766b5880c389bc431d138">yaml_parser_load</a> (<a class="el" href="structyaml__parser__s.html">yaml_parser_t</a> *parser, <a class="el" href="structyaml__document__s.html">yaml_document_t</a> *document)</td></tr>
+<tr><td class="mdescLeft">&nbsp;</td><td class="mdescRight">Parse the input stream and produce the next YAML document. <a href="group__parser.html#ga9ef7d6e9494766b5880c389bc431d138"></a><br/></td></tr>
+<tr><td class="memItemLeft" align="right" valign="top">int&nbsp;</td><td class="memItemRight" valign="bottom"><a class="el" href="group__emitter.html#ga83649205374285802fc27aa293ecd111">yaml_emitter_initialize</a> (<a class="el" href="structyaml__emitter__s.html">yaml_emitter_t</a> *emitter)</td></tr>
+<tr><td class="mdescLeft">&nbsp;</td><td class="mdescRight">Initialize an emitter. <a href="group__emitter.html#ga83649205374285802fc27aa293ecd111"></a><br/></td></tr>
+<tr><td class="memItemLeft" align="right" valign="top">void&nbsp;</td><td class="memItemRight" valign="bottom"><a class="el" href="group__emitter.html#gad705212f3a5150e3f00075fd90bc8c3d">yaml_emitter_delete</a> (<a class="el" href="structyaml__emitter__s.html">yaml_emitter_t</a> *emitter)</td></tr>
+<tr><td class="mdescLeft">&nbsp;</td><td class="mdescRight">Destroy an emitter. <a href="group__emitter.html#gad705212f3a5150e3f00075fd90bc8c3d"></a><br/></td></tr>
+<tr><td class="memItemLeft" align="right" valign="top">void&nbsp;</td><td class="memItemRight" valign="bottom"><a class="el" href="group__emitter.html#ga62725c0f616f634588374d1a4c0ed35a">yaml_emitter_set_output_string</a> (<a class="el" href="structyaml__emitter__s.html">yaml_emitter_t</a> *emitter, unsigned char *output, size_t size, size_t *size_written)</td></tr>
+<tr><td class="mdescLeft">&nbsp;</td><td class="mdescRight">Set a string output. <a href="group__emitter.html#ga62725c0f616f634588374d1a4c0ed35a"></a><br/></td></tr>
+<tr><td class="memItemLeft" align="right" valign="top">void&nbsp;</td><td class="memItemRight" valign="bottom"><a class="el" href="group__emitter.html#gaf7610c61b303bde9c701024c10ece024">yaml_emitter_set_output_file</a> (<a class="el" href="structyaml__emitter__s.html">yaml_emitter_t</a> *emitter, FILE *file)</td></tr>
+<tr><td class="mdescLeft">&nbsp;</td><td class="mdescRight">Set a file output. <a href="group__emitter.html#gaf7610c61b303bde9c701024c10ece024"></a><br/></td></tr>
+<tr><td class="memItemLeft" align="right" valign="top">void&nbsp;</td><td class="memItemRight" valign="bottom"><a class="el" href="group__emitter.html#gac85a6a212ed7b469fb426a3451d15922">yaml_emitter_set_output</a> (<a class="el" href="structyaml__emitter__s.html">yaml_emitter_t</a> *emitter, <a class="el" href="group__emitter.html#ga1669659aacbe631ad406c78fce1f5379">yaml_write_handler_t</a> *handler, void *data)</td></tr>
+<tr><td class="mdescLeft">&nbsp;</td><td class="mdescRight">Set a generic output handler. <a href="group__emitter.html#gac85a6a212ed7b469fb426a3451d15922"></a><br/></td></tr>
+<tr><td class="memItemLeft" align="right" valign="top">void&nbsp;</td><td class="memItemRight" valign="bottom"><a class="el" href="group__emitter.html#gabc22888ec8bf942199acbf38f7a0b9bb">yaml_emitter_set_encoding</a> (<a class="el" href="structyaml__emitter__s.html">yaml_emitter_t</a> *emitter, <a class="el" href="group__basic.html#ga2170996d7e636397b5e6bc0c1b7df7c6">yaml_encoding_t</a> encoding)</td></tr>
+<tr><td class="mdescLeft">&nbsp;</td><td class="mdescRight">Set the output encoding. <a href="group__emitter.html#gabc22888ec8bf942199acbf38f7a0b9bb"></a><br/></td></tr>
+<tr><td class="memItemLeft" align="right" valign="top">void&nbsp;</td><td class="memItemRight" valign="bottom"><a class="el" href="group__emitter.html#ga62713a8130e11d95cbefa95a2eb3ac4b">yaml_emitter_set_canonical</a> (<a class="el" href="structyaml__emitter__s.html">yaml_emitter_t</a> *emitter, int canonical)</td></tr>
+<tr><td class="mdescLeft">&nbsp;</td><td class="mdescRight">Set if the output should be in the "canonical" format as in the YAML specification. <a href="group__emitter.html#ga62713a8130e11d95cbefa95a2eb3ac4b"></a><br/></td></tr>
+<tr><td class="memItemLeft" align="right" valign="top">void&nbsp;</td><td class="memItemRight" valign="bottom"><a class="el" href="group__emitter.html#ga07eca3c344053a9028b4a84291cdf4d7">yaml_emitter_set_indent</a> (<a class="el" href="structyaml__emitter__s.html">yaml_emitter_t</a> *emitter, int indent)</td></tr>
+<tr><td class="mdescLeft">&nbsp;</td><td class="mdescRight">Set the intendation increment. <a href="group__emitter.html#ga07eca3c344053a9028b4a84291cdf4d7"></a><br/></td></tr>
+<tr><td class="memItemLeft" align="right" valign="top">void&nbsp;</td><td class="memItemRight" valign="bottom"><a class="el" href="group__emitter.html#gaa91ae0fa8af5ab67e64567e08f4458c2">yaml_emitter_set_width</a> (<a class="el" href="structyaml__emitter__s.html">yaml_emitter_t</a> *emitter, int width)</td></tr>
+<tr><td class="mdescLeft">&nbsp;</td><td class="mdescRight">Set the preferred line width. <a href="group__emitter.html#gaa91ae0fa8af5ab67e64567e08f4458c2"></a><br/></td></tr>
+<tr><td class="memItemLeft" align="right" valign="top">void&nbsp;</td><td class="memItemRight" valign="bottom"><a class="el" href="group__emitter.html#gaa59e7dcf24cb9b614c32af6c3e949fc3">yaml_emitter_set_unicode</a> (<a class="el" href="structyaml__emitter__s.html">yaml_emitter_t</a> *emitter, int unicode)</td></tr>
+<tr><td class="mdescLeft">&nbsp;</td><td class="mdescRight">Set if unescaped non-ASCII characters are allowed. <a href="group__emitter.html#gaa59e7dcf24cb9b614c32af6c3e949fc3"></a><br/></td></tr>
+<tr><td class="memItemLeft" align="right" valign="top">void&nbsp;</td><td class="memItemRight" valign="bottom"><a class="el" href="group__emitter.html#ga04b5494f0b8244eec359579c31d5e20c">yaml_emitter_set_break</a> (<a class="el" href="structyaml__emitter__s.html">yaml_emitter_t</a> *emitter, <a class="el" href="group__basic.html#ga64d1365e1acd4deeab50d6b48e39cb6d">yaml_break_t</a> line_break)</td></tr>
+<tr><td class="mdescLeft">&nbsp;</td><td class="mdescRight">Set the preferred line break. <a href="group__emitter.html#ga04b5494f0b8244eec359579c31d5e20c"></a><br/></td></tr>
+<tr><td class="memItemLeft" align="right" valign="top">int&nbsp;</td><td class="memItemRight" valign="bottom"><a class="el" href="group__emitter.html#ga4d6c0f8e712797e2660e69479fdae433">yaml_emitter_emit</a> (<a class="el" href="structyaml__emitter__s.html">yaml_emitter_t</a> *emitter, <a class="el" href="structyaml__event__s.html">yaml_event_t</a> *event)</td></tr>
+<tr><td class="mdescLeft">&nbsp;</td><td class="mdescRight">Emit an event. <a href="group__emitter.html#ga4d6c0f8e712797e2660e69479fdae433"></a><br/></td></tr>
+<tr><td class="memItemLeft" align="right" valign="top">int&nbsp;</td><td class="memItemRight" valign="bottom"><a class="el" href="group__emitter.html#gae323c34e378040106f24c7b5ab834b16">yaml_emitter_open</a> (<a class="el" href="structyaml__emitter__s.html">yaml_emitter_t</a> *emitter)</td></tr>
+<tr><td class="mdescLeft">&nbsp;</td><td class="mdescRight">Start a YAML stream. <a href="group__emitter.html#gae323c34e378040106f24c7b5ab834b16"></a><br/></td></tr>
+<tr><td class="memItemLeft" align="right" valign="top">int&nbsp;</td><td class="memItemRight" valign="bottom"><a class="el" href="group__emitter.html#gaa91442864679280985df14b2d96b8c42">yaml_emitter_close</a> (<a class="el" href="structyaml__emitter__s.html">yaml_emitter_t</a> *emitter)</td></tr>
+<tr><td class="mdescLeft">&nbsp;</td><td class="mdescRight">Finish a YAML stream. <a href="group__emitter.html#gaa91442864679280985df14b2d96b8c42"></a><br/></td></tr>
+<tr><td class="memItemLeft" align="right" valign="top">int&nbsp;</td><td class="memItemRight" valign="bottom"><a class="el" href="group__emitter.html#ga5f0306abe9bff373b5bc339913b3769c">yaml_emitter_dump</a> (<a class="el" href="structyaml__emitter__s.html">yaml_emitter_t</a> *emitter, <a class="el" href="structyaml__document__s.html">yaml_document_t</a> *document)</td></tr>
+<tr><td class="mdescLeft">&nbsp;</td><td class="mdescRight">Emit a YAML document. <a href="group__emitter.html#ga5f0306abe9bff373b5bc339913b3769c"></a><br/></td></tr>
+<tr><td class="memItemLeft" align="right" valign="top">int&nbsp;</td><td class="memItemRight" valign="bottom"><a class="el" href="group__emitter.html#gacaf24456e2bf85bc5654cbd7d828055f">yaml_emitter_flush</a> (<a class="el" href="structyaml__emitter__s.html">yaml_emitter_t</a> *emitter)</td></tr>
+<tr><td class="mdescLeft">&nbsp;</td><td class="mdescRight">Flush the accumulated characters to the output. <a href="group__emitter.html#gacaf24456e2bf85bc5654cbd7d828055f"></a><br/></td></tr>
+</table>
+<hr/><a name="_details"></a><h2>Detailed Description</h2>
+<p>Public interface for libyaml. </p>
+<p>Include the header file with the code: </p>
+<div class="fragment"><pre class="fragment"><span class="preprocessor"> #include &lt;<a class="code" href="yaml_8h.html" title="Public interface for libyaml.">yaml.h</a>&gt;</span>
+</pre></div> </div>
+<hr class="footer"/><address class="footer"><small>Generated on Mon May 30 2011 22:00:00 for yaml by&nbsp;
+<a href="http://www.doxygen.org/index.html">
+<img class="footer" src="doxygen.png" alt="doxygen"/></a> 1.7.1 </small></address>
+</body>
+</html>
diff --git a/contrib/libyaml/include/Makefile.am b/contrib/libyaml/include/Makefile.am
new file mode 100644
index 0000000..f81863c
--- /dev/null
+++ b/contrib/libyaml/include/Makefile.am
@@ -0,0 +1,17 @@
+INCLUDES = yaml.h
+DOXYGEN_CFG = $(top_srcdir)/doc/doxygen.cfg
+
+nobase_include_HEADERS = $(INCLUDES)
+
+if DOXYGEN
+
+html: $(INCLUDES) $(DOXYGEN_CFG)
+ PACKAGE=$(PACKAGE) VERSION=$(VERSION) top_srcdir=$(top_srcdir) top_builddir=$(top_builddir) doxygen $(DOXYGEN_CFG)
+
+endif
+
+maintainer-clean-local:
+ -rm -rf $(top_builddir)/doc/html
+
+dist-hook: html
+ cp -a $(top_builddir)/doc/html $(top_distdir)/doc
diff --git a/contrib/libyaml/include/Makefile.in b/contrib/libyaml/include/Makefile.in
new file mode 100644
index 0000000..d7fba23
--- /dev/null
+++ b/contrib/libyaml/include/Makefile.in
@@ -0,0 +1,470 @@
+# Makefile.in generated by automake 1.11.1 from Makefile.am.
+# @configure_input@
+
+# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
+# 2003, 2004, 2005, 2006, 2007, 2008, 2009 Free Software Foundation,
+# Inc.
+# This Makefile.in is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
+# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+# PARTICULAR PURPOSE.
+
+@SET_MAKE@
+
+VPATH = @srcdir@
+pkgdatadir = $(datadir)/@PACKAGE@
+pkgincludedir = $(includedir)/@PACKAGE@
+pkglibdir = $(libdir)/@PACKAGE@
+pkglibexecdir = $(libexecdir)/@PACKAGE@
+am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
+install_sh_DATA = $(install_sh) -c -m 644
+install_sh_PROGRAM = $(install_sh) -c
+install_sh_SCRIPT = $(install_sh) -c
+INSTALL_HEADER = $(INSTALL_DATA)
+transform = $(program_transform_name)
+NORMAL_INSTALL = :
+PRE_INSTALL = :
+POST_INSTALL = :
+NORMAL_UNINSTALL = :
+PRE_UNINSTALL = :
+POST_UNINSTALL = :
+build_triplet = @build@
+host_triplet = @host@
+subdir = include
+DIST_COMMON = $(nobase_include_HEADERS) $(srcdir)/Makefile.am \
+ $(srcdir)/Makefile.in
+ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
+am__aclocal_m4_deps = $(top_srcdir)/configure.ac
+am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
+ $(ACLOCAL_M4)
+mkinstalldirs = $(install_sh) -d
+CONFIG_HEADER = $(top_builddir)/config.h
+CONFIG_CLEAN_FILES =
+CONFIG_CLEAN_VPATH_FILES =
+SOURCES =
+DIST_SOURCES =
+am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`;
+am__vpath_adj = case $$p in \
+ $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \
+ *) f=$$p;; \
+ esac;
+am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`;
+am__install_max = 40
+am__nobase_strip_setup = \
+ srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'`
+am__nobase_strip = \
+ for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||"
+am__nobase_list = $(am__nobase_strip_setup); \
+ for p in $$list; do echo "$$p $$p"; done | \
+ sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \
+ $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \
+ if (++n[$$2] == $(am__install_max)) \
+ { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \
+ END { for (dir in files) print dir, files[dir] }'
+am__base_list = \
+ sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \
+ sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g'
+am__installdirs = "$(DESTDIR)$(includedir)"
+HEADERS = $(nobase_include_HEADERS)
+ETAGS = etags
+CTAGS = ctags
+DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
+ACLOCAL = @ACLOCAL@
+AMTAR = @AMTAR@
+AR = @AR@
+AUTOCONF = @AUTOCONF@
+AUTOHEADER = @AUTOHEADER@
+AUTOMAKE = @AUTOMAKE@
+AWK = @AWK@
+CC = @CC@
+CCDEPMODE = @CCDEPMODE@
+CFLAGS = @CFLAGS@
+CPP = @CPP@
+CPPFLAGS = @CPPFLAGS@
+CYGPATH_W = @CYGPATH_W@
+DEFS = @DEFS@
+DEPDIR = @DEPDIR@
+DOXYGEN = @DOXYGEN@
+DSYMUTIL = @DSYMUTIL@
+DUMPBIN = @DUMPBIN@
+ECHO_C = @ECHO_C@
+ECHO_N = @ECHO_N@
+ECHO_T = @ECHO_T@
+EGREP = @EGREP@
+EXEEXT = @EXEEXT@
+FGREP = @FGREP@
+GREP = @GREP@
+INSTALL = @INSTALL@
+INSTALL_DATA = @INSTALL_DATA@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@
+INSTALL_SCRIPT = @INSTALL_SCRIPT@
+INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
+LD = @LD@
+LDFLAGS = @LDFLAGS@
+LIBOBJS = @LIBOBJS@
+LIBS = @LIBS@
+LIBTOOL = @LIBTOOL@
+LIPO = @LIPO@
+LN_S = @LN_S@
+LTLIBOBJS = @LTLIBOBJS@
+MAKEINFO = @MAKEINFO@
+MKDIR_P = @MKDIR_P@
+NM = @NM@
+NMEDIT = @NMEDIT@
+OBJDUMP = @OBJDUMP@
+OBJEXT = @OBJEXT@
+OTOOL = @OTOOL@
+OTOOL64 = @OTOOL64@
+PACKAGE = @PACKAGE@
+PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
+PACKAGE_NAME = @PACKAGE_NAME@
+PACKAGE_STRING = @PACKAGE_STRING@
+PACKAGE_TARNAME = @PACKAGE_TARNAME@
+PACKAGE_URL = @PACKAGE_URL@
+PACKAGE_VERSION = @PACKAGE_VERSION@
+PATH_SEPARATOR = @PATH_SEPARATOR@
+RANLIB = @RANLIB@
+SED = @SED@
+SET_MAKE = @SET_MAKE@
+SHELL = @SHELL@
+STRIP = @STRIP@
+VERSION = @VERSION@
+YAML_LT_AGE = @YAML_LT_AGE@
+YAML_LT_CURRENT = @YAML_LT_CURRENT@
+YAML_LT_RELEASE = @YAML_LT_RELEASE@
+YAML_LT_REVISION = @YAML_LT_REVISION@
+abs_builddir = @abs_builddir@
+abs_srcdir = @abs_srcdir@
+abs_top_builddir = @abs_top_builddir@
+abs_top_srcdir = @abs_top_srcdir@
+ac_ct_CC = @ac_ct_CC@
+ac_ct_DUMPBIN = @ac_ct_DUMPBIN@
+am__include = @am__include@
+am__leading_dot = @am__leading_dot@
+am__quote = @am__quote@
+am__tar = @am__tar@
+am__untar = @am__untar@
+bindir = @bindir@
+build = @build@
+build_alias = @build_alias@
+build_cpu = @build_cpu@
+build_os = @build_os@
+build_vendor = @build_vendor@
+builddir = @builddir@
+datadir = @datadir@
+datarootdir = @datarootdir@
+docdir = @docdir@
+dvidir = @dvidir@
+exec_prefix = @exec_prefix@
+host = @host@
+host_alias = @host_alias@
+host_cpu = @host_cpu@
+host_os = @host_os@
+host_vendor = @host_vendor@
+htmldir = @htmldir@
+includedir = @includedir@
+infodir = @infodir@
+install_sh = @install_sh@
+libdir = @libdir@
+libexecdir = @libexecdir@
+localedir = @localedir@
+localstatedir = @localstatedir@
+lt_ECHO = @lt_ECHO@
+mandir = @mandir@
+mkdir_p = @mkdir_p@
+oldincludedir = @oldincludedir@
+pdfdir = @pdfdir@
+prefix = @prefix@
+program_transform_name = @program_transform_name@
+psdir = @psdir@
+sbindir = @sbindir@
+sharedstatedir = @sharedstatedir@
+srcdir = @srcdir@
+sysconfdir = @sysconfdir@
+target_alias = @target_alias@
+top_build_prefix = @top_build_prefix@
+top_builddir = @top_builddir@
+top_srcdir = @top_srcdir@
+INCLUDES = yaml.h
+DOXYGEN_CFG = $(top_srcdir)/doc/doxygen.cfg
+nobase_include_HEADERS = $(INCLUDES)
+all: all-am
+
+.SUFFIXES:
+$(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps)
+ @for dep in $?; do \
+ case '$(am__configure_deps)' in \
+ *$$dep*) \
+ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \
+ && { if test -f $@; then exit 0; else break; fi; }; \
+ exit 1;; \
+ esac; \
+ done; \
+ echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign include/Makefile'; \
+ $(am__cd) $(top_srcdir) && \
+ $(AUTOMAKE) --foreign include/Makefile
+.PRECIOUS: Makefile
+Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
+ @case '$?' in \
+ *config.status*) \
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \
+ *) \
+ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \
+ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \
+ esac;
+
+$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+
+$(top_srcdir)/configure: $(am__configure_deps)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(ACLOCAL_M4): $(am__aclocal_m4_deps)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(am__aclocal_m4_deps):
+
+mostlyclean-libtool:
+ -rm -f *.lo
+
+clean-libtool:
+ -rm -rf .libs _libs
+install-nobase_includeHEADERS: $(nobase_include_HEADERS)
+ @$(NORMAL_INSTALL)
+ test -z "$(includedir)" || $(MKDIR_P) "$(DESTDIR)$(includedir)"
+ @list='$(nobase_include_HEADERS)'; test -n "$(includedir)" || list=; \
+ $(am__nobase_list) | while read dir files; do \
+ xfiles=; for file in $$files; do \
+ if test -f "$$file"; then xfiles="$$xfiles $$file"; \
+ else xfiles="$$xfiles $(srcdir)/$$file"; fi; done; \
+ test -z "$$xfiles" || { \
+ test "x$$dir" = x. || { \
+ echo "$(MKDIR_P) '$(DESTDIR)$(includedir)/$$dir'"; \
+ $(MKDIR_P) "$(DESTDIR)$(includedir)/$$dir"; }; \
+ echo " $(INSTALL_HEADER) $$xfiles '$(DESTDIR)$(includedir)/$$dir'"; \
+ $(INSTALL_HEADER) $$xfiles "$(DESTDIR)$(includedir)/$$dir" || exit $$?; }; \
+ done
+
+uninstall-nobase_includeHEADERS:
+ @$(NORMAL_UNINSTALL)
+ @list='$(nobase_include_HEADERS)'; test -n "$(includedir)" || list=; \
+ $(am__nobase_strip_setup); files=`$(am__nobase_strip)`; \
+ test -n "$$files" || exit 0; \
+ echo " ( cd '$(DESTDIR)$(includedir)' && rm -f" $$files ")"; \
+ cd "$(DESTDIR)$(includedir)" && rm -f $$files
+
+ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES)
+ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
+ unique=`for i in $$list; do \
+ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+ done | \
+ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \
+ END { if (nonempty) { for (i in files) print i; }; }'`; \
+ mkid -fID $$unique
+tags: TAGS
+
+TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \
+ $(TAGS_FILES) $(LISP)
+ set x; \
+ here=`pwd`; \
+ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
+ unique=`for i in $$list; do \
+ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+ done | \
+ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \
+ END { if (nonempty) { for (i in files) print i; }; }'`; \
+ shift; \
+ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \
+ test -n "$$unique" || unique=$$empty_fix; \
+ if test $$# -gt 0; then \
+ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
+ "$$@" $$unique; \
+ else \
+ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
+ $$unique; \
+ fi; \
+ fi
+ctags: CTAGS
+CTAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \
+ $(TAGS_FILES) $(LISP)
+ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
+ unique=`for i in $$list; do \
+ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+ done | \
+ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \
+ END { if (nonempty) { for (i in files) print i; }; }'`; \
+ test -z "$(CTAGS_ARGS)$$unique" \
+ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \
+ $$unique
+
+GTAGS:
+ here=`$(am__cd) $(top_builddir) && pwd` \
+ && $(am__cd) $(top_srcdir) \
+ && gtags -i $(GTAGS_ARGS) "$$here"
+
+distclean-tags:
+ -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
+
+distdir: $(DISTFILES)
+ @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+ list='$(DISTFILES)'; \
+ dist_files=`for file in $$list; do echo $$file; done | \
+ sed -e "s|^$$srcdirstrip/||;t" \
+ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \
+ case $$dist_files in \
+ */*) $(MKDIR_P) `echo "$$dist_files" | \
+ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \
+ sort -u` ;; \
+ esac; \
+ for file in $$dist_files; do \
+ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
+ if test -d $$d/$$file; then \
+ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \
+ if test -d "$(distdir)/$$file"; then \
+ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
+ fi; \
+ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
+ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \
+ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
+ fi; \
+ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \
+ else \
+ test -f "$(distdir)/$$file" \
+ || cp -p $$d/$$file "$(distdir)/$$file" \
+ || exit 1; \
+ fi; \
+ done
+ $(MAKE) $(AM_MAKEFLAGS) \
+ top_distdir="$(top_distdir)" distdir="$(distdir)" \
+ dist-hook
+check-am: all-am
+check: check-am
+all-am: Makefile $(HEADERS)
+installdirs:
+ for dir in "$(DESTDIR)$(includedir)"; do \
+ test -z "$$dir" || $(MKDIR_P) "$$dir"; \
+ done
+install: install-am
+install-exec: install-exec-am
+install-data: install-data-am
+uninstall: uninstall-am
+
+install-am: all-am
+ @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
+
+installcheck: installcheck-am
+install-strip:
+ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+ `test -z '$(STRIP)' || \
+ echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install
+mostlyclean-generic:
+
+clean-generic:
+
+distclean-generic:
+ -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
+ -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES)
+
+maintainer-clean-generic:
+ @echo "This command is intended for maintainers to use"
+ @echo "it deletes files that may require special tools to rebuild."
+clean: clean-am
+
+clean-am: clean-generic clean-libtool mostlyclean-am
+
+distclean: distclean-am
+ -rm -f Makefile
+distclean-am: clean-am distclean-generic distclean-tags
+
+dvi: dvi-am
+
+dvi-am:
+
+@DOXYGEN_FALSE@html: html-am
+
+html-am:
+
+info: info-am
+
+info-am:
+
+install-data-am: install-nobase_includeHEADERS
+
+install-dvi: install-dvi-am
+
+install-dvi-am:
+
+install-exec-am:
+
+install-html: install-html-am
+
+install-html-am:
+
+install-info: install-info-am
+
+install-info-am:
+
+install-man:
+
+install-pdf: install-pdf-am
+
+install-pdf-am:
+
+install-ps: install-ps-am
+
+install-ps-am:
+
+installcheck-am:
+
+maintainer-clean: maintainer-clean-am
+ -rm -f Makefile
+maintainer-clean-am: distclean-am maintainer-clean-generic \
+ maintainer-clean-local
+
+mostlyclean: mostlyclean-am
+
+mostlyclean-am: mostlyclean-generic mostlyclean-libtool
+
+pdf: pdf-am
+
+pdf-am:
+
+ps: ps-am
+
+ps-am:
+
+uninstall-am: uninstall-nobase_includeHEADERS
+
+.MAKE: install-am install-strip
+
+.PHONY: CTAGS GTAGS all all-am check check-am clean clean-generic \
+ clean-libtool ctags dist-hook distclean distclean-generic \
+ distclean-libtool distclean-tags distdir dvi dvi-am html \
+ html-am info info-am install install-am install-data \
+ install-data-am install-dvi install-dvi-am install-exec \
+ install-exec-am install-html install-html-am install-info \
+ install-info-am install-man install-nobase_includeHEADERS \
+ install-pdf install-pdf-am install-ps install-ps-am \
+ install-strip installcheck installcheck-am installdirs \
+ maintainer-clean maintainer-clean-generic \
+ maintainer-clean-local mostlyclean mostlyclean-generic \
+ mostlyclean-libtool pdf pdf-am ps ps-am tags uninstall \
+ uninstall-am uninstall-nobase_includeHEADERS
+
+
+@DOXYGEN_TRUE@html: $(INCLUDES) $(DOXYGEN_CFG)
+@DOXYGEN_TRUE@ PACKAGE=$(PACKAGE) VERSION=$(VERSION) top_srcdir=$(top_srcdir) top_builddir=$(top_builddir) doxygen $(DOXYGEN_CFG)
+
+maintainer-clean-local:
+ -rm -rf $(top_builddir)/doc/html
+
+dist-hook: html
+ cp -a $(top_builddir)/doc/html $(top_distdir)/doc
+
+# Tell versions [3.59,3.63) of GNU make to not export all variables.
+# Otherwise a system limit (for SysV at least) may be exceeded.
+.NOEXPORT:
diff --git a/contrib/libyaml/include/yaml.h b/contrib/libyaml/include/yaml.h
new file mode 100644
index 0000000..5a04d36
--- /dev/null
+++ b/contrib/libyaml/include/yaml.h
@@ -0,0 +1,1971 @@
+/**
+ * @file yaml.h
+ * @brief Public interface for libyaml.
+ *
+ * Include the header file with the code:
+ * @code
+ * #include <yaml.h>
+ * @endcode
+ */
+
+#ifndef YAML_H
+#define YAML_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+
+/**
+ * @defgroup export Export Definitions
+ * @{
+ */
+
+/** The public API declaration. */
+
+#ifdef _WIN32
+# if defined(YAML_DECLARE_STATIC)
+# define YAML_DECLARE(type) type
+# elif defined(YAML_DECLARE_EXPORT)
+# define YAML_DECLARE(type) __declspec(dllexport) type
+# else
+# define YAML_DECLARE(type) __declspec(dllimport) type
+# endif
+#else
+# define YAML_DECLARE(type) type
+#endif
+
+/** @} */
+
+/**
+ * @defgroup version Version Information
+ * @{
+ */
+
+/**
+ * Get the library version as a string.
+ *
+ * @returns The function returns the pointer to a static string of the form
+ * @c "X.Y.Z", where @c X is the major version number, @c Y is a minor version
+ * number, and @c Z is the patch version number.
+ */
+
+YAML_DECLARE(const char *)
+yaml_get_version_string(void);
+
+/**
+ * Get the library version numbers.
+ *
+ * @param[out] major Major version number.
+ * @param[out] minor Minor version number.
+ * @param[out] patch Patch version number.
+ */
+
+YAML_DECLARE(void)
+yaml_get_version(int *major, int *minor, int *patch);
+
+/** @} */
+
+/**
+ * @defgroup basic Basic Types
+ * @{
+ */
+
+/** The character type (UTF-8 octet). */
+typedef unsigned char yaml_char_t;
+
+/** The version directive data. */
+typedef struct yaml_version_directive_s {
+ /** The major version number. */
+ int major;
+ /** The minor version number. */
+ int minor;
+} yaml_version_directive_t;
+
+/** The tag directive data. */
+typedef struct yaml_tag_directive_s {
+ /** The tag handle. */
+ yaml_char_t *handle;
+ /** The tag prefix. */
+ yaml_char_t *prefix;
+} yaml_tag_directive_t;
+
+/** The stream encoding. */
+typedef enum yaml_encoding_e {
+ /** Let the parser choose the encoding. */
+ YAML_ANY_ENCODING,
+ /** The default UTF-8 encoding. */
+ YAML_UTF8_ENCODING,
+ /** The UTF-16-LE encoding with BOM. */
+ YAML_UTF16LE_ENCODING,
+ /** The UTF-16-BE encoding with BOM. */
+ YAML_UTF16BE_ENCODING
+} yaml_encoding_t;
+
+/** Line break types. */
+
+typedef enum yaml_break_e {
+ /** Let the parser choose the break type. */
+ YAML_ANY_BREAK,
+ /** Use CR for line breaks (Mac style). */
+ YAML_CR_BREAK,
+ /** Use LN for line breaks (Unix style). */
+ YAML_LN_BREAK,
+ /** Use CR LN for line breaks (DOS style). */
+ YAML_CRLN_BREAK
+} yaml_break_t;
+
+/** Many bad things could happen with the parser and emitter. */
+typedef enum yaml_error_type_e {
+ /** No error is produced. */
+ YAML_NO_ERROR,
+
+ /** Cannot allocate or reallocate a block of memory. */
+ YAML_MEMORY_ERROR,
+
+ /** Cannot read or decode the input stream. */
+ YAML_READER_ERROR,
+ /** Cannot scan the input stream. */
+ YAML_SCANNER_ERROR,
+ /** Cannot parse the input stream. */
+ YAML_PARSER_ERROR,
+ /** Cannot compose a YAML document. */
+ YAML_COMPOSER_ERROR,
+
+ /** Cannot write to the output stream. */
+ YAML_WRITER_ERROR,
+ /** Cannot emit a YAML stream. */
+ YAML_EMITTER_ERROR
+} yaml_error_type_t;
+
+/** The pointer position. */
+typedef struct yaml_mark_s {
+ /** The position index. */
+ size_t index;
+
+ /** The position line. */
+ size_t line;
+
+ /** The position column. */
+ size_t column;
+} yaml_mark_t;
+
+/** @} */
+
+/**
+ * @defgroup styles Node Styles
+ * @{
+ */
+
+/** Scalar styles. */
+typedef enum yaml_scalar_style_e {
+ /** Let the emitter choose the style. */
+ YAML_ANY_SCALAR_STYLE,
+
+ /** The plain scalar style. */
+ YAML_PLAIN_SCALAR_STYLE,
+
+ /** The single-quoted scalar style. */
+ YAML_SINGLE_QUOTED_SCALAR_STYLE,
+ /** The double-quoted scalar style. */
+ YAML_DOUBLE_QUOTED_SCALAR_STYLE,
+
+ /** The literal scalar style. */
+ YAML_LITERAL_SCALAR_STYLE,
+ /** The folded scalar style. */
+ YAML_FOLDED_SCALAR_STYLE
+} yaml_scalar_style_t;
+
+/** Sequence styles. */
+typedef enum yaml_sequence_style_e {
+ /** Let the emitter choose the style. */
+ YAML_ANY_SEQUENCE_STYLE,
+
+ /** The block sequence style. */
+ YAML_BLOCK_SEQUENCE_STYLE,
+ /** The flow sequence style. */
+ YAML_FLOW_SEQUENCE_STYLE
+} yaml_sequence_style_t;
+
+/** Mapping styles. */
+typedef enum yaml_mapping_style_e {
+ /** Let the emitter choose the style. */
+ YAML_ANY_MAPPING_STYLE,
+
+ /** The block mapping style. */
+ YAML_BLOCK_MAPPING_STYLE,
+ /** The flow mapping style. */
+ YAML_FLOW_MAPPING_STYLE
+/* YAML_FLOW_SET_MAPPING_STYLE */
+} yaml_mapping_style_t;
+
+/** @} */
+
+/**
+ * @defgroup tokens Tokens
+ * @{
+ */
+
+/** Token types. */
+typedef enum yaml_token_type_e {
+ /** An empty token. */
+ YAML_NO_TOKEN,
+
+ /** A STREAM-START token. */
+ YAML_STREAM_START_TOKEN,
+ /** A STREAM-END token. */
+ YAML_STREAM_END_TOKEN,
+
+ /** A VERSION-DIRECTIVE token. */
+ YAML_VERSION_DIRECTIVE_TOKEN,
+ /** A TAG-DIRECTIVE token. */
+ YAML_TAG_DIRECTIVE_TOKEN,
+ /** A DOCUMENT-START token. */
+ YAML_DOCUMENT_START_TOKEN,
+ /** A DOCUMENT-END token. */
+ YAML_DOCUMENT_END_TOKEN,
+
+ /** A BLOCK-SEQUENCE-START token. */
+ YAML_BLOCK_SEQUENCE_START_TOKEN,
+ /** A BLOCK-SEQUENCE-END token. */
+ YAML_BLOCK_MAPPING_START_TOKEN,
+ /** A BLOCK-END token. */
+ YAML_BLOCK_END_TOKEN,
+
+ /** A FLOW-SEQUENCE-START token. */
+ YAML_FLOW_SEQUENCE_START_TOKEN,
+ /** A FLOW-SEQUENCE-END token. */
+ YAML_FLOW_SEQUENCE_END_TOKEN,
+ /** A FLOW-MAPPING-START token. */
+ YAML_FLOW_MAPPING_START_TOKEN,
+ /** A FLOW-MAPPING-END token. */
+ YAML_FLOW_MAPPING_END_TOKEN,
+
+ /** A BLOCK-ENTRY token. */
+ YAML_BLOCK_ENTRY_TOKEN,
+ /** A FLOW-ENTRY token. */
+ YAML_FLOW_ENTRY_TOKEN,
+ /** A KEY token. */
+ YAML_KEY_TOKEN,
+ /** A VALUE token. */
+ YAML_VALUE_TOKEN,
+
+ /** An ALIAS token. */
+ YAML_ALIAS_TOKEN,
+ /** An ANCHOR token. */
+ YAML_ANCHOR_TOKEN,
+ /** A TAG token. */
+ YAML_TAG_TOKEN,
+ /** A SCALAR token. */
+ YAML_SCALAR_TOKEN
+} yaml_token_type_t;
+
+/** The token structure. */
+typedef struct yaml_token_s {
+
+ /** The token type. */
+ yaml_token_type_t type;
+
+ /** The token data. */
+ union {
+
+ /** The stream start (for @c YAML_STREAM_START_TOKEN). */
+ struct {
+ /** The stream encoding. */
+ yaml_encoding_t encoding;
+ } stream_start;
+
+ /** The alias (for @c YAML_ALIAS_TOKEN). */
+ struct {
+ /** The alias value. */
+ yaml_char_t *value;
+ } alias;
+
+ /** The anchor (for @c YAML_ANCHOR_TOKEN). */
+ struct {
+ /** The anchor value. */
+ yaml_char_t *value;
+ } anchor;
+
+ /** The tag (for @c YAML_TAG_TOKEN). */
+ struct {
+ /** The tag handle. */
+ yaml_char_t *handle;
+ /** The tag suffix. */
+ yaml_char_t *suffix;
+ } tag;
+
+ /** The scalar value (for @c YAML_SCALAR_TOKEN). */
+ struct {
+ /** The scalar value. */
+ yaml_char_t *value;
+ /** The length of the scalar value. */
+ size_t length;
+ /** The scalar style. */
+ yaml_scalar_style_t style;
+ } scalar;
+
+ /** The version directive (for @c YAML_VERSION_DIRECTIVE_TOKEN). */
+ struct {
+ /** The major version number. */
+ int major;
+ /** The minor version number. */
+ int minor;
+ } version_directive;
+
+ /** The tag directive (for @c YAML_TAG_DIRECTIVE_TOKEN). */
+ struct {
+ /** The tag handle. */
+ yaml_char_t *handle;
+ /** The tag prefix. */
+ yaml_char_t *prefix;
+ } tag_directive;
+
+ } data;
+
+ /** The beginning of the token. */
+ yaml_mark_t start_mark;
+ /** The end of the token. */
+ yaml_mark_t end_mark;
+
+} yaml_token_t;
+
+/**
+ * Free any memory allocated for a token object.
+ *
+ * @param[in,out] token A token object.
+ */
+
+YAML_DECLARE(void)
+yaml_token_delete(yaml_token_t *token);
+
+/** @} */
+
+/**
+ * @defgroup events Events
+ * @{
+ */
+
+/** Event types. */
+typedef enum yaml_event_type_e {
+ /** An empty event. */
+ YAML_NO_EVENT,
+
+ /** A STREAM-START event. */
+ YAML_STREAM_START_EVENT,
+ /** A STREAM-END event. */
+ YAML_STREAM_END_EVENT,
+
+ /** A DOCUMENT-START event. */
+ YAML_DOCUMENT_START_EVENT,
+ /** A DOCUMENT-END event. */
+ YAML_DOCUMENT_END_EVENT,
+
+ /** An ALIAS event. */
+ YAML_ALIAS_EVENT,
+ /** A SCALAR event. */
+ YAML_SCALAR_EVENT,
+
+ /** A SEQUENCE-START event. */
+ YAML_SEQUENCE_START_EVENT,
+ /** A SEQUENCE-END event. */
+ YAML_SEQUENCE_END_EVENT,
+
+ /** A MAPPING-START event. */
+ YAML_MAPPING_START_EVENT,
+ /** A MAPPING-END event. */
+ YAML_MAPPING_END_EVENT
+} yaml_event_type_t;
+
+/** The event structure. */
+typedef struct yaml_event_s {
+
+ /** The event type. */
+ yaml_event_type_t type;
+
+ /** The event data. */
+ union {
+
+ /** The stream parameters (for @c YAML_STREAM_START_EVENT). */
+ struct {
+ /** The document encoding. */
+ yaml_encoding_t encoding;
+ } stream_start;
+
+ /** The document parameters (for @c YAML_DOCUMENT_START_EVENT). */
+ struct {
+ /** The version directive. */
+ yaml_version_directive_t *version_directive;
+
+ /** The list of tag directives. */
+ struct {
+ /** The beginning of the tag directives list. */
+ yaml_tag_directive_t *start;
+ /** The end of the tag directives list. */
+ yaml_tag_directive_t *end;
+ } tag_directives;
+
+ /** Is the document indicator implicit? */
+ int implicit;
+ } document_start;
+
+ /** The document end parameters (for @c YAML_DOCUMENT_END_EVENT). */
+ struct {
+ /** Is the document end indicator implicit? */
+ int implicit;
+ } document_end;
+
+ /** The alias parameters (for @c YAML_ALIAS_EVENT). */
+ struct {
+ /** The anchor. */
+ yaml_char_t *anchor;
+ } alias;
+
+ /** The scalar parameters (for @c YAML_SCALAR_EVENT). */
+ struct {
+ /** The anchor. */
+ yaml_char_t *anchor;
+ /** The tag. */
+ yaml_char_t *tag;
+ /** The scalar value. */
+ yaml_char_t *value;
+ /** The length of the scalar value. */
+ size_t length;
+ /** Is the tag optional for the plain style? */
+ int plain_implicit;
+ /** Is the tag optional for any non-plain style? */
+ int quoted_implicit;
+ /** The scalar style. */
+ yaml_scalar_style_t style;
+ } scalar;
+
+ /** The sequence parameters (for @c YAML_SEQUENCE_START_EVENT). */
+ struct {
+ /** The anchor. */
+ yaml_char_t *anchor;
+ /** The tag. */
+ yaml_char_t *tag;
+ /** Is the tag optional? */
+ int implicit;
+ /** The sequence style. */
+ yaml_sequence_style_t style;
+ } sequence_start;
+
+ /** The mapping parameters (for @c YAML_MAPPING_START_EVENT). */
+ struct {
+ /** The anchor. */
+ yaml_char_t *anchor;
+ /** The tag. */
+ yaml_char_t *tag;
+ /** Is the tag optional? */
+ int implicit;
+ /** The mapping style. */
+ yaml_mapping_style_t style;
+ } mapping_start;
+
+ } data;
+
+ /** The beginning of the event. */
+ yaml_mark_t start_mark;
+ /** The end of the event. */
+ yaml_mark_t end_mark;
+
+} yaml_event_t;
+
+/**
+ * Create the STREAM-START event.
+ *
+ * @param[out] event An empty event object.
+ * @param[in] encoding The stream encoding.
+ *
+ * @returns @c 1 if the function succeeded, @c 0 on error.
+ */
+
+YAML_DECLARE(int)
+yaml_stream_start_event_initialize(yaml_event_t *event,
+ yaml_encoding_t encoding);
+
+/**
+ * Create the STREAM-END event.
+ *
+ * @param[out] event An empty event object.
+ *
+ * @returns @c 1 if the function succeeded, @c 0 on error.
+ */
+
+YAML_DECLARE(int)
+yaml_stream_end_event_initialize(yaml_event_t *event);
+
+/**
+ * Create the DOCUMENT-START event.
+ *
+ * The @a implicit argument is considered as a stylistic parameter and may be
+ * ignored by the emitter.
+ *
+ * @param[out] event An empty event object.
+ * @param[in] version_directive The %YAML directive value or
+ * @c NULL.
+ * @param[in] tag_directives_start The beginning of the %TAG
+ * directives list.
+ * @param[in] tag_directives_end The end of the %TAG directives
+ * list.
+ * @param[in] implicit If the document start indicator is
+ * implicit.
+ *
+ * @returns @c 1 if the function succeeded, @c 0 on error.
+ */
+
+YAML_DECLARE(int)
+yaml_document_start_event_initialize(yaml_event_t *event,
+ yaml_version_directive_t *version_directive,
+ yaml_tag_directive_t *tag_directives_start,
+ yaml_tag_directive_t *tag_directives_end,
+ int implicit);
+
+/**
+ * Create the DOCUMENT-END event.
+ *
+ * The @a implicit argument is considered as a stylistic parameter and may be
+ * ignored by the emitter.
+ *
+ * @param[out] event An empty event object.
+ * @param[in] implicit If the document end indicator is implicit.
+ *
+ * @returns @c 1 if the function succeeded, @c 0 on error.
+ */
+
+YAML_DECLARE(int)
+yaml_document_end_event_initialize(yaml_event_t *event, int implicit);
+
+/**
+ * Create an ALIAS event.
+ *
+ * @param[out] event An empty event object.
+ * @param[in] anchor The anchor value.
+ *
+ * @returns @c 1 if the function succeeded, @c 0 on error.
+ */
+
+YAML_DECLARE(int)
+yaml_alias_event_initialize(yaml_event_t *event, yaml_char_t *anchor);
+
+/**
+ * Create a SCALAR event.
+ *
+ * The @a style argument may be ignored by the emitter.
+ *
+ * Either the @a tag attribute or one of the @a plain_implicit and
+ * @a quoted_implicit flags must be set.
+ *
+ * @param[out] event An empty event object.
+ * @param[in] anchor The scalar anchor or @c NULL.
+ * @param[in] tag The scalar tag or @c NULL.
+ * @param[in] value The scalar value.
+ * @param[in] length The length of the scalar value.
+ * @param[in] plain_implicit If the tag may be omitted for the plain
+ * style.
+ * @param[in] quoted_implicit If the tag may be omitted for any
+ * non-plain style.
+ * @param[in] style The scalar style.
+ *
+ * @returns @c 1 if the function succeeded, @c 0 on error.
+ */
+
+YAML_DECLARE(int)
+yaml_scalar_event_initialize(yaml_event_t *event,
+ yaml_char_t *anchor, yaml_char_t *tag,
+ yaml_char_t *value, int length,
+ int plain_implicit, int quoted_implicit,
+ yaml_scalar_style_t style);
+
+/**
+ * Create a SEQUENCE-START event.
+ *
+ * The @a style argument may be ignored by the emitter.
+ *
+ * Either the @a tag attribute or the @a implicit flag must be set.
+ *
+ * @param[out] event An empty event object.
+ * @param[in] anchor The sequence anchor or @c NULL.
+ * @param[in] tag The sequence tag or @c NULL.
+ * @param[in] implicit If the tag may be omitted.
+ * @param[in] style The sequence style.
+ *
+ * @returns @c 1 if the function succeeded, @c 0 on error.
+ */
+
+YAML_DECLARE(int)
+yaml_sequence_start_event_initialize(yaml_event_t *event,
+ yaml_char_t *anchor, yaml_char_t *tag, int implicit,
+ yaml_sequence_style_t style);
+
+/**
+ * Create a SEQUENCE-END event.
+ *
+ * @param[out] event An empty event object.
+ *
+ * @returns @c 1 if the function succeeded, @c 0 on error.
+ */
+
+YAML_DECLARE(int)
+yaml_sequence_end_event_initialize(yaml_event_t *event);
+
+/**
+ * Create a MAPPING-START event.
+ *
+ * The @a style argument may be ignored by the emitter.
+ *
+ * Either the @a tag attribute or the @a implicit flag must be set.
+ *
+ * @param[out] event An empty event object.
+ * @param[in] anchor The mapping anchor or @c NULL.
+ * @param[in] tag The mapping tag or @c NULL.
+ * @param[in] implicit If the tag may be omitted.
+ * @param[in] style The mapping style.
+ *
+ * @returns @c 1 if the function succeeded, @c 0 on error.
+ */
+
+YAML_DECLARE(int)
+yaml_mapping_start_event_initialize(yaml_event_t *event,
+ yaml_char_t *anchor, yaml_char_t *tag, int implicit,
+ yaml_mapping_style_t style);
+
+/**
+ * Create a MAPPING-END event.
+ *
+ * @param[out] event An empty event object.
+ *
+ * @returns @c 1 if the function succeeded, @c 0 on error.
+ */
+
+YAML_DECLARE(int)
+yaml_mapping_end_event_initialize(yaml_event_t *event);
+
+/**
+ * Free any memory allocated for an event object.
+ *
+ * @param[in,out] event An event object.
+ */
+
+YAML_DECLARE(void)
+yaml_event_delete(yaml_event_t *event);
+
+/** @} */
+
+/**
+ * @defgroup nodes Nodes
+ * @{
+ */
+
+/** The tag @c !!null with the only possible value: @c null. */
+#define YAML_NULL_TAG "tag:yaml.org,2002:null"
+/** The tag @c !!bool with the values: @c true and @c falce. */
+#define YAML_BOOL_TAG "tag:yaml.org,2002:bool"
+/** The tag @c !!str for string values. */
+#define YAML_STR_TAG "tag:yaml.org,2002:str"
+/** The tag @c !!int for integer values. */
+#define YAML_INT_TAG "tag:yaml.org,2002:int"
+/** The tag @c !!float for float values. */
+#define YAML_FLOAT_TAG "tag:yaml.org,2002:float"
+/** The tag @c !!timestamp for date and time values. */
+#define YAML_TIMESTAMP_TAG "tag:yaml.org,2002:timestamp"
+
+/** The tag @c !!seq is used to denote sequences. */
+#define YAML_SEQ_TAG "tag:yaml.org,2002:seq"
+/** The tag @c !!map is used to denote mapping. */
+#define YAML_MAP_TAG "tag:yaml.org,2002:map"
+
+/** The default scalar tag is @c !!str. */
+#define YAML_DEFAULT_SCALAR_TAG YAML_STR_TAG
+/** The default sequence tag is @c !!seq. */
+#define YAML_DEFAULT_SEQUENCE_TAG YAML_SEQ_TAG
+/** The default mapping tag is @c !!map. */
+#define YAML_DEFAULT_MAPPING_TAG YAML_MAP_TAG
+
+/** Node types. */
+typedef enum yaml_node_type_e {
+ /** An empty node. */
+ YAML_NO_NODE,
+
+ /** A scalar node. */
+ YAML_SCALAR_NODE,
+ /** A sequence node. */
+ YAML_SEQUENCE_NODE,
+ /** A mapping node. */
+ YAML_MAPPING_NODE
+} yaml_node_type_t;
+
+/** The forward definition of a document node structure. */
+typedef struct yaml_node_s yaml_node_t;
+
+/** An element of a sequence node. */
+typedef int yaml_node_item_t;
+
+/** An element of a mapping node. */
+typedef struct yaml_node_pair_s {
+ /** The key of the element. */
+ int key;
+ /** The value of the element. */
+ int value;
+} yaml_node_pair_t;
+
+/** The node structure. */
+struct yaml_node_s {
+
+ /** The node type. */
+ yaml_node_type_t type;
+
+ /** The node tag. */
+ yaml_char_t *tag;
+
+ /** The node data. */
+ union {
+
+ /** The scalar parameters (for @c YAML_SCALAR_NODE). */
+ struct {
+ /** The scalar value. */
+ yaml_char_t *value;
+ /** The length of the scalar value. */
+ size_t length;
+ /** The scalar style. */
+ yaml_scalar_style_t style;
+ } scalar;
+
+ /** The sequence parameters (for @c YAML_SEQUENCE_NODE). */
+ struct {
+ /** The stack of sequence items. */
+ struct {
+ /** The beginning of the stack. */
+ yaml_node_item_t *start;
+ /** The end of the stack. */
+ yaml_node_item_t *end;
+ /** The top of the stack. */
+ yaml_node_item_t *top;
+ } items;
+ /** The sequence style. */
+ yaml_sequence_style_t style;
+ } sequence;
+
+ /** The mapping parameters (for @c YAML_MAPPING_NODE). */
+ struct {
+ /** The stack of mapping pairs (key, value). */
+ struct {
+ /** The beginning of the stack. */
+ yaml_node_pair_t *start;
+ /** The end of the stack. */
+ yaml_node_pair_t *end;
+ /** The top of the stack. */
+ yaml_node_pair_t *top;
+ } pairs;
+ /** The mapping style. */
+ yaml_mapping_style_t style;
+ } mapping;
+
+ } data;
+
+ /** The beginning of the node. */
+ yaml_mark_t start_mark;
+ /** The end of the node. */
+ yaml_mark_t end_mark;
+
+};
+
+/** The document structure. */
+typedef struct yaml_document_s {
+
+ /** The document nodes. */
+ struct {
+ /** The beginning of the stack. */
+ yaml_node_t *start;
+ /** The end of the stack. */
+ yaml_node_t *end;
+ /** The top of the stack. */
+ yaml_node_t *top;
+ } nodes;
+
+ /** The version directive. */
+ yaml_version_directive_t *version_directive;
+
+ /** The list of tag directives. */
+ struct {
+ /** The beginning of the tag directives list. */
+ yaml_tag_directive_t *start;
+ /** The end of the tag directives list. */
+ yaml_tag_directive_t *end;
+ } tag_directives;
+
+ /** Is the document start indicator implicit? */
+ int start_implicit;
+ /** Is the document end indicator implicit? */
+ int end_implicit;
+
+ /** The beginning of the document. */
+ yaml_mark_t start_mark;
+ /** The end of the document. */
+ yaml_mark_t end_mark;
+
+} yaml_document_t;
+
+/**
+ * Create a YAML document.
+ *
+ * @param[out] document An empty document object.
+ * @param[in] version_directive The %YAML directive value or
+ * @c NULL.
+ * @param[in] tag_directives_start The beginning of the %TAG
+ * directives list.
+ * @param[in] tag_directives_end The end of the %TAG directives
+ * list.
+ * @param[in] start_implicit If the document start indicator is
+ * implicit.
+ * @param[in] end_implicit If the document end indicator is
+ * implicit.
+ *
+ * @returns @c 1 if the function succeeded, @c 0 on error.
+ */
+
+YAML_DECLARE(int)
+yaml_document_initialize(yaml_document_t *document,
+ yaml_version_directive_t *version_directive,
+ yaml_tag_directive_t *tag_directives_start,
+ yaml_tag_directive_t *tag_directives_end,
+ int start_implicit, int end_implicit);
+
+/**
+ * Delete a YAML document and all its nodes.
+ *
+ * @param[in,out] document A document object.
+ */
+
+YAML_DECLARE(void)
+yaml_document_delete(yaml_document_t *document);
+
+/**
+ * Get a node of a YAML document.
+ *
+ * The pointer returned by this function is valid until any of the functions
+ * modifying the documents are called.
+ *
+ * @param[in] document A document object.
+ * @param[in] index The node id.
+ *
+ * @returns the node objct or @c NULL if @c node_id is out of range.
+ */
+
+YAML_DECLARE(yaml_node_t *)
+yaml_document_get_node(yaml_document_t *document, int index);
+
+/**
+ * Get the root of a YAML document node.
+ *
+ * The root object is the first object added to the document.
+ *
+ * The pointer returned by this function is valid until any of the functions
+ * modifying the documents are called.
+ *
+ * An empty document produced by the parser signifies the end of a YAML
+ * stream.
+ *
+ * @param[in] document A document object.
+ *
+ * @returns the node object or @c NULL if the document is empty.
+ */
+
+YAML_DECLARE(yaml_node_t *)
+yaml_document_get_root_node(yaml_document_t *document);
+
+/**
+ * Create a SCALAR node and attach it to the document.
+ *
+ * The @a style argument may be ignored by the emitter.
+ *
+ * @param[in,out] document A document object.
+ * @param[in] tag The scalar tag.
+ * @param[in] value The scalar value.
+ * @param[in] length The length of the scalar value.
+ * @param[in] style The scalar style.
+ *
+ * @returns the node id or @c 0 on error.
+ */
+
+YAML_DECLARE(int)
+yaml_document_add_scalar(yaml_document_t *document,
+ yaml_char_t *tag, yaml_char_t *value, int length,
+ yaml_scalar_style_t style);
+
+/**
+ * Create a SEQUENCE node and attach it to the document.
+ *
+ * The @a style argument may be ignored by the emitter.
+ *
+ * @param[in,out] document A document object.
+ * @param[in] tag The sequence tag.
+ * @param[in] style The sequence style.
+ *
+ * @returns the node id or @c 0 on error.
+ */
+
+YAML_DECLARE(int)
+yaml_document_add_sequence(yaml_document_t *document,
+ yaml_char_t *tag, yaml_sequence_style_t style);
+
+/**
+ * Create a MAPPING node and attach it to the document.
+ *
+ * The @a style argument may be ignored by the emitter.
+ *
+ * @param[in,out] document A document object.
+ * @param[in] tag The sequence tag.
+ * @param[in] style The sequence style.
+ *
+ * @returns the node id or @c 0 on error.
+ */
+
+YAML_DECLARE(int)
+yaml_document_add_mapping(yaml_document_t *document,
+ yaml_char_t *tag, yaml_mapping_style_t style);
+
+/**
+ * Add an item to a SEQUENCE node.
+ *
+ * @param[in,out] document A document object.
+ * @param[in] sequence The sequence node id.
+ * @param[in] item The item node id.
+*
+ * @returns @c 1 if the function succeeded, @c 0 on error.
+ */
+
+YAML_DECLARE(int)
+yaml_document_append_sequence_item(yaml_document_t *document,
+ int sequence, int item);
+
+/**
+ * Add a pair of a key and a value to a MAPPING node.
+ *
+ * @param[in,out] document A document object.
+ * @param[in] mapping The mapping node id.
+ * @param[in] key The key node id.
+ * @param[in] value The value node id.
+*
+ * @returns @c 1 if the function succeeded, @c 0 on error.
+ */
+
+YAML_DECLARE(int)
+yaml_document_append_mapping_pair(yaml_document_t *document,
+ int mapping, int key, int value);
+
+/** @} */
+
+/**
+ * @defgroup parser Parser Definitions
+ * @{
+ */
+
+/**
+ * The prototype of a read handler.
+ *
+ * The read handler is called when the parser needs to read more bytes from the
+ * source. The handler should write not more than @a size bytes to the @a
+ * buffer. The number of written bytes should be set to the @a length variable.
+ *
+ * @param[in,out] data A pointer to an application data specified by
+ * yaml_parser_set_input().
+ * @param[out] buffer The buffer to write the data from the source.
+ * @param[in] size The size of the buffer.
+ * @param[out] size_read The actual number of bytes read from the source.
+ *
+ * @returns On success, the handler should return @c 1. If the handler failed,
+ * the returned value should be @c 0. On EOF, the handler should set the
+ * @a size_read to @c 0 and return @c 1.
+ */
+
+typedef int yaml_read_handler_t(void *data, unsigned char *buffer, size_t size,
+ size_t *size_read);
+
+/**
+ * This structure holds information about a potential simple key.
+ */
+
+typedef struct yaml_simple_key_s {
+ /** Is a simple key possible? */
+ int possible;
+
+ /** Is a simple key required? */
+ int required;
+
+ /** The number of the token. */
+ size_t token_number;
+
+ /** The position mark. */
+ yaml_mark_t mark;
+} yaml_simple_key_t;
+
+/**
+ * The states of the parser.
+ */
+typedef enum yaml_parser_state_e {
+ /** Expect STREAM-START. */
+ YAML_PARSE_STREAM_START_STATE,
+ /** Expect the beginning of an implicit document. */
+ YAML_PARSE_IMPLICIT_DOCUMENT_START_STATE,
+ /** Expect DOCUMENT-START. */
+ YAML_PARSE_DOCUMENT_START_STATE,
+ /** Expect the content of a document. */
+ YAML_PARSE_DOCUMENT_CONTENT_STATE,
+ /** Expect DOCUMENT-END. */
+ YAML_PARSE_DOCUMENT_END_STATE,
+ /** Expect a block node. */
+ YAML_PARSE_BLOCK_NODE_STATE,
+ /** Expect a block node or indentless sequence. */
+ YAML_PARSE_BLOCK_NODE_OR_INDENTLESS_SEQUENCE_STATE,
+ /** Expect a flow node. */
+ YAML_PARSE_FLOW_NODE_STATE,
+ /** Expect the first entry of a block sequence. */
+ YAML_PARSE_BLOCK_SEQUENCE_FIRST_ENTRY_STATE,
+ /** Expect an entry of a block sequence. */
+ YAML_PARSE_BLOCK_SEQUENCE_ENTRY_STATE,
+ /** Expect an entry of an indentless sequence. */
+ YAML_PARSE_INDENTLESS_SEQUENCE_ENTRY_STATE,
+ /** Expect the first key of a block mapping. */
+ YAML_PARSE_BLOCK_MAPPING_FIRST_KEY_STATE,
+ /** Expect a block mapping key. */
+ YAML_PARSE_BLOCK_MAPPING_KEY_STATE,
+ /** Expect a block mapping value. */
+ YAML_PARSE_BLOCK_MAPPING_VALUE_STATE,
+ /** Expect the first entry of a flow sequence. */
+ YAML_PARSE_FLOW_SEQUENCE_FIRST_ENTRY_STATE,
+ /** Expect an entry of a flow sequence. */
+ YAML_PARSE_FLOW_SEQUENCE_ENTRY_STATE,
+ /** Expect a key of an ordered mapping. */
+ YAML_PARSE_FLOW_SEQUENCE_ENTRY_MAPPING_KEY_STATE,
+ /** Expect a value of an ordered mapping. */
+ YAML_PARSE_FLOW_SEQUENCE_ENTRY_MAPPING_VALUE_STATE,
+ /** Expect the and of an ordered mapping entry. */
+ YAML_PARSE_FLOW_SEQUENCE_ENTRY_MAPPING_END_STATE,
+ /** Expect the first key of a flow mapping. */
+ YAML_PARSE_FLOW_MAPPING_FIRST_KEY_STATE,
+ /** Expect a key of a flow mapping. */
+ YAML_PARSE_FLOW_MAPPING_KEY_STATE,
+ /** Expect a value of a flow mapping. */
+ YAML_PARSE_FLOW_MAPPING_VALUE_STATE,
+ /** Expect an empty value of a flow mapping. */
+ YAML_PARSE_FLOW_MAPPING_EMPTY_VALUE_STATE,
+ /** Expect nothing. */
+ YAML_PARSE_END_STATE
+} yaml_parser_state_t;
+
+/**
+ * This structure holds aliases data.
+ */
+
+typedef struct yaml_alias_data_s {
+ /** The anchor. */
+ yaml_char_t *anchor;
+ /** The node id. */
+ int index;
+ /** The anchor mark. */
+ yaml_mark_t mark;
+} yaml_alias_data_t;
+
+/**
+ * The parser structure.
+ *
+ * All members are internal. Manage the structure using the @c yaml_parser_
+ * family of functions.
+ */
+
+typedef struct yaml_parser_s {
+
+ /**
+ * @name Error handling
+ * @{
+ */
+
+ /** Error type. */
+ yaml_error_type_t error;
+ /** Error description. */
+ const char *problem;
+ /** The byte about which the problem occured. */
+ size_t problem_offset;
+ /** The problematic value (@c -1 is none). */
+ int problem_value;
+ /** The problem position. */
+ yaml_mark_t problem_mark;
+ /** The error context. */
+ const char *context;
+ /** The context position. */
+ yaml_mark_t context_mark;
+
+ /**
+ * @}
+ */
+
+ /**
+ * @name Reader stuff
+ * @{
+ */
+
+ /** Read handler. */
+ yaml_read_handler_t *read_handler;
+
+ /** A pointer for passing to the read handler. */
+ void *read_handler_data;
+
+ /** Standard (string or file) input data. */
+ union {
+ /** String input data. */
+ struct {
+ /** The string start pointer. */
+ const unsigned char *start;
+ /** The string end pointer. */
+ const unsigned char *end;
+ /** The string current position. */
+ const unsigned char *current;
+ } string;
+
+ /** File input data. */
+ FILE *file;
+ } input;
+
+ /** EOF flag */
+ int eof;
+
+ /** The working buffer. */
+ struct {
+ /** The beginning of the buffer. */
+ yaml_char_t *start;
+ /** The end of the buffer. */
+ yaml_char_t *end;
+ /** The current position of the buffer. */
+ yaml_char_t *pointer;
+ /** The last filled position of the buffer. */
+ yaml_char_t *last;
+ } buffer;
+
+ /* The number of unread characters in the buffer. */
+ size_t unread;
+
+ /** The raw buffer. */
+ struct {
+ /** The beginning of the buffer. */
+ unsigned char *start;
+ /** The end of the buffer. */
+ unsigned char *end;
+ /** The current position of the buffer. */
+ unsigned char *pointer;
+ /** The last filled position of the buffer. */
+ unsigned char *last;
+ } raw_buffer;
+
+ /** The input encoding. */
+ yaml_encoding_t encoding;
+
+ /** The offset of the current position (in bytes). */
+ size_t offset;
+
+ /** The mark of the current position. */
+ yaml_mark_t mark;
+
+ /**
+ * @}
+ */
+
+ /**
+ * @name Scanner stuff
+ * @{
+ */
+
+ /** Have we started to scan the input stream? */
+ int stream_start_produced;
+
+ /** Have we reached the end of the input stream? */
+ int stream_end_produced;
+
+ /** The number of unclosed '[' and '{' indicators. */
+ int flow_level;
+
+ /** The tokens queue. */
+ struct {
+ /** The beginning of the tokens queue. */
+ yaml_token_t *start;
+ /** The end of the tokens queue. */
+ yaml_token_t *end;
+ /** The head of the tokens queue. */
+ yaml_token_t *head;
+ /** The tail of the tokens queue. */
+ yaml_token_t *tail;
+ } tokens;
+
+ /** The number of tokens fetched from the queue. */
+ size_t tokens_parsed;
+
+ /* Does the tokens queue contain a token ready for dequeueing. */
+ int token_available;
+
+ /** The indentation levels stack. */
+ struct {
+ /** The beginning of the stack. */
+ int *start;
+ /** The end of the stack. */
+ int *end;
+ /** The top of the stack. */
+ int *top;
+ } indents;
+
+ /** The current indentation level. */
+ int indent;
+
+ /** May a simple key occur at the current position? */
+ int simple_key_allowed;
+
+ /** The stack of simple keys. */
+ struct {
+ /** The beginning of the stack. */
+ yaml_simple_key_t *start;
+ /** The end of the stack. */
+ yaml_simple_key_t *end;
+ /** The top of the stack. */
+ yaml_simple_key_t *top;
+ } simple_keys;
+
+ /**
+ * @}
+ */
+
+ /**
+ * @name Parser stuff
+ * @{
+ */
+
+ /** The parser states stack. */
+ struct {
+ /** The beginning of the stack. */
+ yaml_parser_state_t *start;
+ /** The end of the stack. */
+ yaml_parser_state_t *end;
+ /** The top of the stack. */
+ yaml_parser_state_t *top;
+ } states;
+
+ /** The current parser state. */
+ yaml_parser_state_t state;
+
+ /** The stack of marks. */
+ struct {
+ /** The beginning of the stack. */
+ yaml_mark_t *start;
+ /** The end of the stack. */
+ yaml_mark_t *end;
+ /** The top of the stack. */
+ yaml_mark_t *top;
+ } marks;
+
+ /** The list of TAG directives. */
+ struct {
+ /** The beginning of the list. */
+ yaml_tag_directive_t *start;
+ /** The end of the list. */
+ yaml_tag_directive_t *end;
+ /** The top of the list. */
+ yaml_tag_directive_t *top;
+ } tag_directives;
+
+ /**
+ * @}
+ */
+
+ /**
+ * @name Dumper stuff
+ * @{
+ */
+
+ /** The alias data. */
+ struct {
+ /** The beginning of the list. */
+ yaml_alias_data_t *start;
+ /** The end of the list. */
+ yaml_alias_data_t *end;
+ /** The top of the list. */
+ yaml_alias_data_t *top;
+ } aliases;
+
+ /** The currently parsed document. */
+ yaml_document_t *document;
+
+ /**
+ * @}
+ */
+
+} yaml_parser_t;
+
+/**
+ * Initialize a parser.
+ *
+ * This function creates a new parser object. An application is responsible
+ * for destroying the object using the yaml_parser_delete() function.
+ *
+ * @param[out] parser An empty parser object.
+ *
+ * @returns @c 1 if the function succeeded, @c 0 on error.
+ */
+
+YAML_DECLARE(int)
+yaml_parser_initialize(yaml_parser_t *parser);
+
+/**
+ * Destroy a parser.
+ *
+ * @param[in,out] parser A parser object.
+ */
+
+YAML_DECLARE(void)
+yaml_parser_delete(yaml_parser_t *parser);
+
+/**
+ * Set a string input.
+ *
+ * Note that the @a input pointer must be valid while the @a parser object
+ * exists. The application is responsible for destroing @a input after
+ * destroying the @a parser.
+ *
+ * @param[in,out] parser A parser object.
+ * @param[in] input A source data.
+ * @param[in] size The length of the source data in bytes.
+ */
+
+YAML_DECLARE(void)
+yaml_parser_set_input_string(yaml_parser_t *parser,
+ const unsigned char *input, size_t size);
+
+/**
+ * Set a file input.
+ *
+ * @a file should be a file object open for reading. The application is
+ * responsible for closing the @a file.
+ *
+ * @param[in,out] parser A parser object.
+ * @param[in] file An open file.
+ */
+
+YAML_DECLARE(void)
+yaml_parser_set_input_file(yaml_parser_t *parser, FILE *file);
+
+/**
+ * Set a generic input handler.
+ *
+ * @param[in,out] parser A parser object.
+ * @param[in] handler A read handler.
+ * @param[in] data Any application data for passing to the read
+ * handler.
+ */
+
+YAML_DECLARE(void)
+yaml_parser_set_input(yaml_parser_t *parser,
+ yaml_read_handler_t *handler, void *data);
+
+/**
+ * Set the source encoding.
+ *
+ * @param[in,out] parser A parser object.
+ * @param[in] encoding The source encoding.
+ */
+
+YAML_DECLARE(void)
+yaml_parser_set_encoding(yaml_parser_t *parser, yaml_encoding_t encoding);
+
+/**
+ * Scan the input stream and produce the next token.
+ *
+ * Call the function subsequently to produce a sequence of tokens corresponding
+ * to the input stream. The initial token has the type
+ * @c YAML_STREAM_START_TOKEN while the ending token has the type
+ * @c YAML_STREAM_END_TOKEN.
+ *
+ * An application is responsible for freeing any buffers associated with the
+ * produced token object using the @c yaml_token_delete function.
+ *
+ * An application must not alternate the calls of yaml_parser_scan() with the
+ * calls of yaml_parser_parse() or yaml_parser_load(). Doing this will break
+ * the parser.
+ *
+ * @param[in,out] parser A parser object.
+ * @param[out] token An empty token object.
+ *
+ * @returns @c 1 if the function succeeded, @c 0 on error.
+ */
+
+YAML_DECLARE(int)
+yaml_parser_scan(yaml_parser_t *parser, yaml_token_t *token);
+
+/**
+ * Parse the input stream and produce the next parsing event.
+ *
+ * Call the function subsequently to produce a sequence of events corresponding
+ * to the input stream. The initial event has the type
+ * @c YAML_STREAM_START_EVENT while the ending event has the type
+ * @c YAML_STREAM_END_EVENT.
+ *
+ * An application is responsible for freeing any buffers associated with the
+ * produced event object using the yaml_event_delete() function.
+ *
+ * An application must not alternate the calls of yaml_parser_parse() with the
+ * calls of yaml_parser_scan() or yaml_parser_load(). Doing this will break the
+ * parser.
+ *
+ * @param[in,out] parser A parser object.
+ * @param[out] event An empty event object.
+ *
+ * @returns @c 1 if the function succeeded, @c 0 on error.
+ */
+
+YAML_DECLARE(int)
+yaml_parser_parse(yaml_parser_t *parser, yaml_event_t *event);
+
+/**
+ * Parse the input stream and produce the next YAML document.
+ *
+ * Call this function subsequently to produce a sequence of documents
+ * constituting the input stream.
+ *
+ * If the produced document has no root node, it means that the document
+ * end has been reached.
+ *
+ * An application is responsible for freeing any data associated with the
+ * produced document object using the yaml_document_delete() function.
+ *
+ * An application must not alternate the calls of yaml_parser_load() with the
+ * calls of yaml_parser_scan() or yaml_parser_parse(). Doing this will break
+ * the parser.
+ *
+ * @param[in,out] parser A parser object.
+ * @param[out] document An empty document object.
+ *
+ * @return @c 1 if the function succeeded, @c 0 on error.
+ */
+
+YAML_DECLARE(int)
+yaml_parser_load(yaml_parser_t *parser, yaml_document_t *document);
+
+/** @} */
+
+/**
+ * @defgroup emitter Emitter Definitions
+ * @{
+ */
+
+/**
+ * The prototype of a write handler.
+ *
+ * The write handler is called when the emitter needs to flush the accumulated
+ * characters to the output. The handler should write @a size bytes of the
+ * @a buffer to the output.
+ *
+ * @param[in,out] data A pointer to an application data specified by
+ * yaml_emitter_set_output().
+ * @param[in] buffer The buffer with bytes to be written.
+ * @param[in] size The size of the buffer.
+ *
+ * @returns On success, the handler should return @c 1. If the handler failed,
+ * the returned value should be @c 0.
+ */
+
+typedef int yaml_write_handler_t(void *data, unsigned char *buffer, size_t size);
+
+/** The emitter states. */
+typedef enum yaml_emitter_state_e {
+ /** Expect STREAM-START. */
+ YAML_EMIT_STREAM_START_STATE,
+ /** Expect the first DOCUMENT-START or STREAM-END. */
+ YAML_EMIT_FIRST_DOCUMENT_START_STATE,
+ /** Expect DOCUMENT-START or STREAM-END. */
+ YAML_EMIT_DOCUMENT_START_STATE,
+ /** Expect the content of a document. */
+ YAML_EMIT_DOCUMENT_CONTENT_STATE,
+ /** Expect DOCUMENT-END. */
+ YAML_EMIT_DOCUMENT_END_STATE,
+ /** Expect the first item of a flow sequence. */
+ YAML_EMIT_FLOW_SEQUENCE_FIRST_ITEM_STATE,
+ /** Expect an item of a flow sequence. */
+ YAML_EMIT_FLOW_SEQUENCE_ITEM_STATE,
+ /** Expect the first key of a flow mapping. */
+ YAML_EMIT_FLOW_MAPPING_FIRST_KEY_STATE,
+ /** Expect a key of a flow mapping. */
+ YAML_EMIT_FLOW_MAPPING_KEY_STATE,
+ /** Expect a value for a simple key of a flow mapping. */
+ YAML_EMIT_FLOW_MAPPING_SIMPLE_VALUE_STATE,
+ /** Expect a value of a flow mapping. */
+ YAML_EMIT_FLOW_MAPPING_VALUE_STATE,
+ /** Expect the first item of a block sequence. */
+ YAML_EMIT_BLOCK_SEQUENCE_FIRST_ITEM_STATE,
+ /** Expect an item of a block sequence. */
+ YAML_EMIT_BLOCK_SEQUENCE_ITEM_STATE,
+ /** Expect the first key of a block mapping. */
+ YAML_EMIT_BLOCK_MAPPING_FIRST_KEY_STATE,
+ /** Expect the key of a block mapping. */
+ YAML_EMIT_BLOCK_MAPPING_KEY_STATE,
+ /** Expect a value for a simple key of a block mapping. */
+ YAML_EMIT_BLOCK_MAPPING_SIMPLE_VALUE_STATE,
+ /** Expect a value of a block mapping. */
+ YAML_EMIT_BLOCK_MAPPING_VALUE_STATE,
+ /** Expect nothing. */
+ YAML_EMIT_END_STATE
+} yaml_emitter_state_t;
+
+/**
+ * The emitter structure.
+ *
+ * All members are internal. Manage the structure using the @c yaml_emitter_
+ * family of functions.
+ */
+
+typedef struct yaml_emitter_s {
+
+ /**
+ * @name Error handling
+ * @{
+ */
+
+ /** Error type. */
+ yaml_error_type_t error;
+ /** Error description. */
+ const char *problem;
+
+ /**
+ * @}
+ */
+
+ /**
+ * @name Writer stuff
+ * @{
+ */
+
+ /** Write handler. */
+ yaml_write_handler_t *write_handler;
+
+ /** A pointer for passing to the white handler. */
+ void *write_handler_data;
+
+ /** Standard (string or file) output data. */
+ union {
+ /** String output data. */
+ struct {
+ /** The buffer pointer. */
+ unsigned char *buffer;
+ /** The buffer size. */
+ size_t size;
+ /** The number of written bytes. */
+ size_t *size_written;
+ } string;
+
+ /** File output data. */
+ FILE *file;
+ } output;
+
+ /** The working buffer. */
+ struct {
+ /** The beginning of the buffer. */
+ yaml_char_t *start;
+ /** The end of the buffer. */
+ yaml_char_t *end;
+ /** The current position of the buffer. */
+ yaml_char_t *pointer;
+ /** The last filled position of the buffer. */
+ yaml_char_t *last;
+ } buffer;
+
+ /** The raw buffer. */
+ struct {
+ /** The beginning of the buffer. */
+ unsigned char *start;
+ /** The end of the buffer. */
+ unsigned char *end;
+ /** The current position of the buffer. */
+ unsigned char *pointer;
+ /** The last filled position of the buffer. */
+ unsigned char *last;
+ } raw_buffer;
+
+ /** The stream encoding. */
+ yaml_encoding_t encoding;
+
+ /**
+ * @}
+ */
+
+ /**
+ * @name Emitter stuff
+ * @{
+ */
+
+ /** If the output is in the canonical style? */
+ int canonical;
+ /** The number of indentation spaces. */
+ int best_indent;
+ /** The preferred width of the output lines. */
+ int best_width;
+ /** Allow unescaped non-ASCII characters? */
+ int unicode;
+ /** The preferred line break. */
+ yaml_break_t line_break;
+
+ /** The stack of states. */
+ struct {
+ /** The beginning of the stack. */
+ yaml_emitter_state_t *start;
+ /** The end of the stack. */
+ yaml_emitter_state_t *end;
+ /** The top of the stack. */
+ yaml_emitter_state_t *top;
+ } states;
+
+ /** The current emitter state. */
+ yaml_emitter_state_t state;
+
+ /** The event queue. */
+ struct {
+ /** The beginning of the event queue. */
+ yaml_event_t *start;
+ /** The end of the event queue. */
+ yaml_event_t *end;
+ /** The head of the event queue. */
+ yaml_event_t *head;
+ /** The tail of the event queue. */
+ yaml_event_t *tail;
+ } events;
+
+ /** The stack of indentation levels. */
+ struct {
+ /** The beginning of the stack. */
+ int *start;
+ /** The end of the stack. */
+ int *end;
+ /** The top of the stack. */
+ int *top;
+ } indents;
+
+ /** The list of tag directives. */
+ struct {
+ /** The beginning of the list. */
+ yaml_tag_directive_t *start;
+ /** The end of the list. */
+ yaml_tag_directive_t *end;
+ /** The top of the list. */
+ yaml_tag_directive_t *top;
+ } tag_directives;
+
+ /** The current indentation level. */
+ int indent;
+
+ /** The current flow level. */
+ int flow_level;
+
+ /** Is it the document root context? */
+ int root_context;
+ /** Is it a sequence context? */
+ int sequence_context;
+ /** Is it a mapping context? */
+ int mapping_context;
+ /** Is it a simple mapping key context? */
+ int simple_key_context;
+
+ /** The current line. */
+ int line;
+ /** The current column. */
+ int column;
+ /** If the last character was a whitespace? */
+ int whitespace;
+ /** If the last character was an indentation character (' ', '-', '?', ':')? */
+ int indention;
+ /** If an explicit document end is required? */
+ int open_ended;
+
+ /** Anchor analysis. */
+ struct {
+ /** The anchor value. */
+ yaml_char_t *anchor;
+ /** The anchor length. */
+ size_t anchor_length;
+ /** Is it an alias? */
+ int alias;
+ } anchor_data;
+
+ /** Tag analysis. */
+ struct {
+ /** The tag handle. */
+ yaml_char_t *handle;
+ /** The tag handle length. */
+ size_t handle_length;
+ /** The tag suffix. */
+ yaml_char_t *suffix;
+ /** The tag suffix length. */
+ size_t suffix_length;
+ } tag_data;
+
+ /** Scalar analysis. */
+ struct {
+ /** The scalar value. */
+ yaml_char_t *value;
+ /** The scalar length. */
+ size_t length;
+ /** Does the scalar contain line breaks? */
+ int multiline;
+ /** Can the scalar be expessed in the flow plain style? */
+ int flow_plain_allowed;
+ /** Can the scalar be expressed in the block plain style? */
+ int block_plain_allowed;
+ /** Can the scalar be expressed in the single quoted style? */
+ int single_quoted_allowed;
+ /** Can the scalar be expressed in the literal or folded styles? */
+ int block_allowed;
+ /** The output style. */
+ yaml_scalar_style_t style;
+ } scalar_data;
+
+ /**
+ * @}
+ */
+
+ /**
+ * @name Dumper stuff
+ * @{
+ */
+
+ /** If the stream was already opened? */
+ int opened;
+ /** If the stream was already closed? */
+ int closed;
+
+ /** The information associated with the document nodes. */
+ struct {
+ /** The number of references. */
+ int references;
+ /** The anchor id. */
+ int anchor;
+ /** If the node has been emitted? */
+ int serialized;
+ } *anchors;
+
+ /** The last assigned anchor id. */
+ int last_anchor_id;
+
+ /** The currently emitted document. */
+ yaml_document_t *document;
+
+ /**
+ * @}
+ */
+
+} yaml_emitter_t;
+
+/**
+ * Initialize an emitter.
+ *
+ * This function creates a new emitter object. An application is responsible
+ * for destroying the object using the yaml_emitter_delete() function.
+ *
+ * @param[out] emitter An empty parser object.
+ *
+ * @returns @c 1 if the function succeeded, @c 0 on error.
+ */
+
+YAML_DECLARE(int)
+yaml_emitter_initialize(yaml_emitter_t *emitter);
+
+/**
+ * Destroy an emitter.
+ *
+ * @param[in,out] emitter An emitter object.
+ */
+
+YAML_DECLARE(void)
+yaml_emitter_delete(yaml_emitter_t *emitter);
+
+/**
+ * Set a string output.
+ *
+ * The emitter will write the output characters to the @a output buffer of the
+ * size @a size. The emitter will set @a size_written to the number of written
+ * bytes. If the buffer is smaller than required, the emitter produces the
+ * YAML_WRITE_ERROR error.
+ *
+ * @param[in,out] emitter An emitter object.
+ * @param[in] output An output buffer.
+ * @param[in] size The buffer size.
+ * @param[in] size_written The pointer to save the number of written
+ * bytes.
+ */
+
+YAML_DECLARE(void)
+yaml_emitter_set_output_string(yaml_emitter_t *emitter,
+ unsigned char *output, size_t size, size_t *size_written);
+
+/**
+ * Set a file output.
+ *
+ * @a file should be a file object open for writing. The application is
+ * responsible for closing the @a file.
+ *
+ * @param[in,out] emitter An emitter object.
+ * @param[in] file An open file.
+ */
+
+YAML_DECLARE(void)
+yaml_emitter_set_output_file(yaml_emitter_t *emitter, FILE *file);
+
+/**
+ * Set a generic output handler.
+ *
+ * @param[in,out] emitter An emitter object.
+ * @param[in] handler A write handler.
+ * @param[in] data Any application data for passing to the write
+ * handler.
+ */
+
+YAML_DECLARE(void)
+yaml_emitter_set_output(yaml_emitter_t *emitter,
+ yaml_write_handler_t *handler, void *data);
+
+/**
+ * Set the output encoding.
+ *
+ * @param[in,out] emitter An emitter object.
+ * @param[in] encoding The output encoding.
+ */
+
+YAML_DECLARE(void)
+yaml_emitter_set_encoding(yaml_emitter_t *emitter, yaml_encoding_t encoding);
+
+/**
+ * Set if the output should be in the "canonical" format as in the YAML
+ * specification.
+ *
+ * @param[in,out] emitter An emitter object.
+ * @param[in] canonical If the output is canonical.
+ */
+
+YAML_DECLARE(void)
+yaml_emitter_set_canonical(yaml_emitter_t *emitter, int canonical);
+
+/**
+ * Set the intendation increment.
+ *
+ * @param[in,out] emitter An emitter object.
+ * @param[in] indent The indentation increment (1 < . < 10).
+ */
+
+YAML_DECLARE(void)
+yaml_emitter_set_indent(yaml_emitter_t *emitter, int indent);
+
+/**
+ * Set the preferred line width. @c -1 means unlimited.
+ *
+ * @param[in,out] emitter An emitter object.
+ * @param[in] width The preferred line width.
+ */
+
+YAML_DECLARE(void)
+yaml_emitter_set_width(yaml_emitter_t *emitter, int width);
+
+/**
+ * Set if unescaped non-ASCII characters are allowed.
+ *
+ * @param[in,out] emitter An emitter object.
+ * @param[in] unicode If unescaped Unicode characters are allowed.
+ */
+
+YAML_DECLARE(void)
+yaml_emitter_set_unicode(yaml_emitter_t *emitter, int unicode);
+
+/**
+ * Set the preferred line break.
+ *
+ * @param[in,out] emitter An emitter object.
+ * @param[in] line_break The preferred line break.
+ */
+
+YAML_DECLARE(void)
+yaml_emitter_set_break(yaml_emitter_t *emitter, yaml_break_t line_break);
+
+/**
+ * Emit an event.
+ *
+ * The event object may be generated using the yaml_parser_parse() function.
+ * The emitter takes the responsibility for the event object and destroys its
+ * content after it is emitted. The event object is destroyed even if the
+ * function fails.
+ *
+ * @param[in,out] emitter An emitter object.
+ * @param[in,out] event An event object.
+ *
+ * @returns @c 1 if the function succeeded, @c 0 on error.
+ */
+
+YAML_DECLARE(int)
+yaml_emitter_emit(yaml_emitter_t *emitter, yaml_event_t *event);
+
+/**
+ * Start a YAML stream.
+ *
+ * This function should be used before yaml_emitter_dump() is called.
+ *
+ * @param[in,out] emitter An emitter object.
+ *
+ * @returns @c 1 if the function succeeded, @c 0 on error.
+ */
+
+YAML_DECLARE(int)
+yaml_emitter_open(yaml_emitter_t *emitter);
+
+/**
+ * Finish a YAML stream.
+ *
+ * This function should be used after yaml_emitter_dump() is called.
+ *
+ * @param[in,out] emitter An emitter object.
+ *
+ * @returns @c 1 if the function succeeded, @c 0 on error.
+ */
+
+YAML_DECLARE(int)
+yaml_emitter_close(yaml_emitter_t *emitter);
+
+/**
+ * Emit a YAML document.
+ *
+ * The documen object may be generated using the yaml_parser_load() function
+ * or the yaml_document_initialize() function. The emitter takes the
+ * responsibility for the document object and destoys its content after
+ * it is emitted. The document object is destroyedeven if the function fails.
+ *
+ * @param[in,out] emitter An emitter object.
+ * @param[in,out] document A document object.
+ *
+ * @returns @c 1 if the function succeeded, @c 0 on error.
+ */
+
+YAML_DECLARE(int)
+yaml_emitter_dump(yaml_emitter_t *emitter, yaml_document_t *document);
+
+/**
+ * Flush the accumulated characters to the output.
+ *
+ * @param[in,out] emitter An emitter object.
+ *
+ * @returns @c 1 if the function succeeded, @c 0 on error.
+ */
+
+YAML_DECLARE(int)
+yaml_emitter_flush(yaml_emitter_t *emitter);
+
+/** @} */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* #ifndef YAML_H */
+
diff --git a/contrib/libyaml/src/Makefile.am b/contrib/libyaml/src/Makefile.am
new file mode 100644
index 0000000..724a1b2
--- /dev/null
+++ b/contrib/libyaml/src/Makefile.am
@@ -0,0 +1,4 @@
+AM_CPPFLAGS = -I$(top_srcdir)/include
+lib_LTLIBRARIES = libyaml.la
+libyaml_la_SOURCES = yaml_private.h api.c reader.c scanner.c parser.c loader.c writer.c emitter.c dumper.c
+libyaml_la_LDFLAGS = -release $(YAML_LT_RELEASE) -version-info $(YAML_LT_CURRENT):$(YAML_LT_REVISION):$(YAML_LT_AGE)
diff --git a/contrib/libyaml/src/Makefile.in b/contrib/libyaml/src/Makefile.in
new file mode 100644
index 0000000..50e3737
--- /dev/null
+++ b/contrib/libyaml/src/Makefile.in
@@ -0,0 +1,529 @@
+# Makefile.in generated by automake 1.11.1 from Makefile.am.
+# @configure_input@
+
+# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
+# 2003, 2004, 2005, 2006, 2007, 2008, 2009 Free Software Foundation,
+# Inc.
+# This Makefile.in is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
+# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+# PARTICULAR PURPOSE.
+
+@SET_MAKE@
+
+VPATH = @srcdir@
+pkgdatadir = $(datadir)/@PACKAGE@
+pkgincludedir = $(includedir)/@PACKAGE@
+pkglibdir = $(libdir)/@PACKAGE@
+pkglibexecdir = $(libexecdir)/@PACKAGE@
+am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
+install_sh_DATA = $(install_sh) -c -m 644
+install_sh_PROGRAM = $(install_sh) -c
+install_sh_SCRIPT = $(install_sh) -c
+INSTALL_HEADER = $(INSTALL_DATA)
+transform = $(program_transform_name)
+NORMAL_INSTALL = :
+PRE_INSTALL = :
+POST_INSTALL = :
+NORMAL_UNINSTALL = :
+PRE_UNINSTALL = :
+POST_UNINSTALL = :
+build_triplet = @build@
+host_triplet = @host@
+subdir = src
+DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in
+ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
+am__aclocal_m4_deps = $(top_srcdir)/configure.ac
+am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
+ $(ACLOCAL_M4)
+mkinstalldirs = $(install_sh) -d
+CONFIG_HEADER = $(top_builddir)/config.h
+CONFIG_CLEAN_FILES =
+CONFIG_CLEAN_VPATH_FILES =
+am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`;
+am__vpath_adj = case $$p in \
+ $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \
+ *) f=$$p;; \
+ esac;
+am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`;
+am__install_max = 40
+am__nobase_strip_setup = \
+ srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'`
+am__nobase_strip = \
+ for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||"
+am__nobase_list = $(am__nobase_strip_setup); \
+ for p in $$list; do echo "$$p $$p"; done | \
+ sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \
+ $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \
+ if (++n[$$2] == $(am__install_max)) \
+ { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \
+ END { for (dir in files) print dir, files[dir] }'
+am__base_list = \
+ sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \
+ sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g'
+am__installdirs = "$(DESTDIR)$(libdir)"
+LTLIBRARIES = $(lib_LTLIBRARIES)
+libyaml_la_LIBADD =
+am_libyaml_la_OBJECTS = api.lo reader.lo scanner.lo parser.lo \
+ loader.lo writer.lo emitter.lo dumper.lo
+libyaml_la_OBJECTS = $(am_libyaml_la_OBJECTS)
+libyaml_la_LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) \
+ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \
+ $(libyaml_la_LDFLAGS) $(LDFLAGS) -o $@
+DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir)
+depcomp = $(SHELL) $(top_srcdir)/config/depcomp
+am__depfiles_maybe = depfiles
+am__mv = mv -f
+COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \
+ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
+LTCOMPILE = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \
+ --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \
+ $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
+CCLD = $(CC)
+LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \
+ --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) \
+ $(LDFLAGS) -o $@
+SOURCES = $(libyaml_la_SOURCES)
+DIST_SOURCES = $(libyaml_la_SOURCES)
+ETAGS = etags
+CTAGS = ctags
+DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
+ACLOCAL = @ACLOCAL@
+AMTAR = @AMTAR@
+AR = @AR@
+AUTOCONF = @AUTOCONF@
+AUTOHEADER = @AUTOHEADER@
+AUTOMAKE = @AUTOMAKE@
+AWK = @AWK@
+CC = @CC@
+CCDEPMODE = @CCDEPMODE@
+CFLAGS = @CFLAGS@
+CPP = @CPP@
+CPPFLAGS = @CPPFLAGS@
+CYGPATH_W = @CYGPATH_W@
+DEFS = @DEFS@
+DEPDIR = @DEPDIR@
+DOXYGEN = @DOXYGEN@
+DSYMUTIL = @DSYMUTIL@
+DUMPBIN = @DUMPBIN@
+ECHO_C = @ECHO_C@
+ECHO_N = @ECHO_N@
+ECHO_T = @ECHO_T@
+EGREP = @EGREP@
+EXEEXT = @EXEEXT@
+FGREP = @FGREP@
+GREP = @GREP@
+INSTALL = @INSTALL@
+INSTALL_DATA = @INSTALL_DATA@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@
+INSTALL_SCRIPT = @INSTALL_SCRIPT@
+INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
+LD = @LD@
+LDFLAGS = @LDFLAGS@
+LIBOBJS = @LIBOBJS@
+LIBS = @LIBS@
+LIBTOOL = @LIBTOOL@
+LIPO = @LIPO@
+LN_S = @LN_S@
+LTLIBOBJS = @LTLIBOBJS@
+MAKEINFO = @MAKEINFO@
+MKDIR_P = @MKDIR_P@
+NM = @NM@
+NMEDIT = @NMEDIT@
+OBJDUMP = @OBJDUMP@
+OBJEXT = @OBJEXT@
+OTOOL = @OTOOL@
+OTOOL64 = @OTOOL64@
+PACKAGE = @PACKAGE@
+PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
+PACKAGE_NAME = @PACKAGE_NAME@
+PACKAGE_STRING = @PACKAGE_STRING@
+PACKAGE_TARNAME = @PACKAGE_TARNAME@
+PACKAGE_URL = @PACKAGE_URL@
+PACKAGE_VERSION = @PACKAGE_VERSION@
+PATH_SEPARATOR = @PATH_SEPARATOR@
+RANLIB = @RANLIB@
+SED = @SED@
+SET_MAKE = @SET_MAKE@
+SHELL = @SHELL@
+STRIP = @STRIP@
+VERSION = @VERSION@
+YAML_LT_AGE = @YAML_LT_AGE@
+YAML_LT_CURRENT = @YAML_LT_CURRENT@
+YAML_LT_RELEASE = @YAML_LT_RELEASE@
+YAML_LT_REVISION = @YAML_LT_REVISION@
+abs_builddir = @abs_builddir@
+abs_srcdir = @abs_srcdir@
+abs_top_builddir = @abs_top_builddir@
+abs_top_srcdir = @abs_top_srcdir@
+ac_ct_CC = @ac_ct_CC@
+ac_ct_DUMPBIN = @ac_ct_DUMPBIN@
+am__include = @am__include@
+am__leading_dot = @am__leading_dot@
+am__quote = @am__quote@
+am__tar = @am__tar@
+am__untar = @am__untar@
+bindir = @bindir@
+build = @build@
+build_alias = @build_alias@
+build_cpu = @build_cpu@
+build_os = @build_os@
+build_vendor = @build_vendor@
+builddir = @builddir@
+datadir = @datadir@
+datarootdir = @datarootdir@
+docdir = @docdir@
+dvidir = @dvidir@
+exec_prefix = @exec_prefix@
+host = @host@
+host_alias = @host_alias@
+host_cpu = @host_cpu@
+host_os = @host_os@
+host_vendor = @host_vendor@
+htmldir = @htmldir@
+includedir = @includedir@
+infodir = @infodir@
+install_sh = @install_sh@
+libdir = @libdir@
+libexecdir = @libexecdir@
+localedir = @localedir@
+localstatedir = @localstatedir@
+lt_ECHO = @lt_ECHO@
+mandir = @mandir@
+mkdir_p = @mkdir_p@
+oldincludedir = @oldincludedir@
+pdfdir = @pdfdir@
+prefix = @prefix@
+program_transform_name = @program_transform_name@
+psdir = @psdir@
+sbindir = @sbindir@
+sharedstatedir = @sharedstatedir@
+srcdir = @srcdir@
+sysconfdir = @sysconfdir@
+target_alias = @target_alias@
+top_build_prefix = @top_build_prefix@
+top_builddir = @top_builddir@
+top_srcdir = @top_srcdir@
+AM_CPPFLAGS = -I$(top_srcdir)/include
+lib_LTLIBRARIES = libyaml.la
+libyaml_la_SOURCES = yaml_private.h api.c reader.c scanner.c parser.c loader.c writer.c emitter.c dumper.c
+libyaml_la_LDFLAGS = -release $(YAML_LT_RELEASE) -version-info $(YAML_LT_CURRENT):$(YAML_LT_REVISION):$(YAML_LT_AGE)
+all: all-am
+
+.SUFFIXES:
+.SUFFIXES: .c .lo .o .obj
+$(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps)
+ @for dep in $?; do \
+ case '$(am__configure_deps)' in \
+ *$$dep*) \
+ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \
+ && { if test -f $@; then exit 0; else break; fi; }; \
+ exit 1;; \
+ esac; \
+ done; \
+ echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign src/Makefile'; \
+ $(am__cd) $(top_srcdir) && \
+ $(AUTOMAKE) --foreign src/Makefile
+.PRECIOUS: Makefile
+Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
+ @case '$?' in \
+ *config.status*) \
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \
+ *) \
+ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \
+ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \
+ esac;
+
+$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+
+$(top_srcdir)/configure: $(am__configure_deps)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(ACLOCAL_M4): $(am__aclocal_m4_deps)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(am__aclocal_m4_deps):
+install-libLTLIBRARIES: $(lib_LTLIBRARIES)
+ @$(NORMAL_INSTALL)
+ test -z "$(libdir)" || $(MKDIR_P) "$(DESTDIR)$(libdir)"
+ @list='$(lib_LTLIBRARIES)'; test -n "$(libdir)" || list=; \
+ list2=; for p in $$list; do \
+ if test -f $$p; then \
+ list2="$$list2 $$p"; \
+ else :; fi; \
+ done; \
+ test -z "$$list2" || { \
+ echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 '$(DESTDIR)$(libdir)'"; \
+ $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 "$(DESTDIR)$(libdir)"; \
+ }
+
+uninstall-libLTLIBRARIES:
+ @$(NORMAL_UNINSTALL)
+ @list='$(lib_LTLIBRARIES)'; test -n "$(libdir)" || list=; \
+ for p in $$list; do \
+ $(am__strip_dir) \
+ echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f '$(DESTDIR)$(libdir)/$$f'"; \
+ $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f "$(DESTDIR)$(libdir)/$$f"; \
+ done
+
+clean-libLTLIBRARIES:
+ -test -z "$(lib_LTLIBRARIES)" || rm -f $(lib_LTLIBRARIES)
+ @list='$(lib_LTLIBRARIES)'; for p in $$list; do \
+ dir="`echo $$p | sed -e 's|/[^/]*$$||'`"; \
+ test "$$dir" != "$$p" || dir=.; \
+ echo "rm -f \"$${dir}/so_locations\""; \
+ rm -f "$${dir}/so_locations"; \
+ done
+libyaml.la: $(libyaml_la_OBJECTS) $(libyaml_la_DEPENDENCIES)
+ $(libyaml_la_LINK) -rpath $(libdir) $(libyaml_la_OBJECTS) $(libyaml_la_LIBADD) $(LIBS)
+
+mostlyclean-compile:
+ -rm -f *.$(OBJEXT)
+
+distclean-compile:
+ -rm -f *.tab.c
+
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/api.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dumper.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/emitter.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/loader.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/parser.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/reader.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/scanner.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/writer.Plo@am__quote@
+
+.c.o:
+@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
+@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(COMPILE) -c $<
+
+.c.obj:
+@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'`
+@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(COMPILE) -c `$(CYGPATH_W) '$<'`
+
+.c.lo:
+@am__fastdepCC_TRUE@ $(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
+@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(LTCOMPILE) -c -o $@ $<
+
+mostlyclean-libtool:
+ -rm -f *.lo
+
+clean-libtool:
+ -rm -rf .libs _libs
+
+ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES)
+ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
+ unique=`for i in $$list; do \
+ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+ done | \
+ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \
+ END { if (nonempty) { for (i in files) print i; }; }'`; \
+ mkid -fID $$unique
+tags: TAGS
+
+TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \
+ $(TAGS_FILES) $(LISP)
+ set x; \
+ here=`pwd`; \
+ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
+ unique=`for i in $$list; do \
+ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+ done | \
+ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \
+ END { if (nonempty) { for (i in files) print i; }; }'`; \
+ shift; \
+ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \
+ test -n "$$unique" || unique=$$empty_fix; \
+ if test $$# -gt 0; then \
+ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
+ "$$@" $$unique; \
+ else \
+ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
+ $$unique; \
+ fi; \
+ fi
+ctags: CTAGS
+CTAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \
+ $(TAGS_FILES) $(LISP)
+ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
+ unique=`for i in $$list; do \
+ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+ done | \
+ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \
+ END { if (nonempty) { for (i in files) print i; }; }'`; \
+ test -z "$(CTAGS_ARGS)$$unique" \
+ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \
+ $$unique
+
+GTAGS:
+ here=`$(am__cd) $(top_builddir) && pwd` \
+ && $(am__cd) $(top_srcdir) \
+ && gtags -i $(GTAGS_ARGS) "$$here"
+
+distclean-tags:
+ -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
+
+distdir: $(DISTFILES)
+ @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+ list='$(DISTFILES)'; \
+ dist_files=`for file in $$list; do echo $$file; done | \
+ sed -e "s|^$$srcdirstrip/||;t" \
+ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \
+ case $$dist_files in \
+ */*) $(MKDIR_P) `echo "$$dist_files" | \
+ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \
+ sort -u` ;; \
+ esac; \
+ for file in $$dist_files; do \
+ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
+ if test -d $$d/$$file; then \
+ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \
+ if test -d "$(distdir)/$$file"; then \
+ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
+ fi; \
+ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
+ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \
+ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
+ fi; \
+ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \
+ else \
+ test -f "$(distdir)/$$file" \
+ || cp -p $$d/$$file "$(distdir)/$$file" \
+ || exit 1; \
+ fi; \
+ done
+check-am: all-am
+check: check-am
+all-am: Makefile $(LTLIBRARIES)
+installdirs:
+ for dir in "$(DESTDIR)$(libdir)"; do \
+ test -z "$$dir" || $(MKDIR_P) "$$dir"; \
+ done
+install: install-am
+install-exec: install-exec-am
+install-data: install-data-am
+uninstall: uninstall-am
+
+install-am: all-am
+ @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
+
+installcheck: installcheck-am
+install-strip:
+ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+ `test -z '$(STRIP)' || \
+ echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install
+mostlyclean-generic:
+
+clean-generic:
+
+distclean-generic:
+ -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
+ -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES)
+
+maintainer-clean-generic:
+ @echo "This command is intended for maintainers to use"
+ @echo "it deletes files that may require special tools to rebuild."
+clean: clean-am
+
+clean-am: clean-generic clean-libLTLIBRARIES clean-libtool \
+ mostlyclean-am
+
+distclean: distclean-am
+ -rm -rf ./$(DEPDIR)
+ -rm -f Makefile
+distclean-am: clean-am distclean-compile distclean-generic \
+ distclean-tags
+
+dvi: dvi-am
+
+dvi-am:
+
+html: html-am
+
+html-am:
+
+info: info-am
+
+info-am:
+
+install-data-am:
+
+install-dvi: install-dvi-am
+
+install-dvi-am:
+
+install-exec-am: install-libLTLIBRARIES
+
+install-html: install-html-am
+
+install-html-am:
+
+install-info: install-info-am
+
+install-info-am:
+
+install-man:
+
+install-pdf: install-pdf-am
+
+install-pdf-am:
+
+install-ps: install-ps-am
+
+install-ps-am:
+
+installcheck-am:
+
+maintainer-clean: maintainer-clean-am
+ -rm -rf ./$(DEPDIR)
+ -rm -f Makefile
+maintainer-clean-am: distclean-am maintainer-clean-generic
+
+mostlyclean: mostlyclean-am
+
+mostlyclean-am: mostlyclean-compile mostlyclean-generic \
+ mostlyclean-libtool
+
+pdf: pdf-am
+
+pdf-am:
+
+ps: ps-am
+
+ps-am:
+
+uninstall-am: uninstall-libLTLIBRARIES
+
+.MAKE: install-am install-strip
+
+.PHONY: CTAGS GTAGS all all-am check check-am clean clean-generic \
+ clean-libLTLIBRARIES clean-libtool ctags distclean \
+ distclean-compile distclean-generic distclean-libtool \
+ distclean-tags distdir dvi dvi-am html html-am info info-am \
+ install install-am install-data install-data-am install-dvi \
+ install-dvi-am install-exec install-exec-am install-html \
+ install-html-am install-info install-info-am \
+ install-libLTLIBRARIES install-man install-pdf install-pdf-am \
+ install-ps install-ps-am install-strip installcheck \
+ installcheck-am installdirs maintainer-clean \
+ maintainer-clean-generic mostlyclean mostlyclean-compile \
+ mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \
+ tags uninstall uninstall-am uninstall-libLTLIBRARIES
+
+
+# Tell versions [3.59,3.63) of GNU make to not export all variables.
+# Otherwise a system limit (for SysV at least) may be exceeded.
+.NOEXPORT:
diff --git a/contrib/libyaml/src/api.c b/contrib/libyaml/src/api.c
new file mode 100644
index 0000000..0c4732e
--- /dev/null
+++ b/contrib/libyaml/src/api.c
@@ -0,0 +1,1392 @@
+
+#include "yaml_private.h"
+
+/*
+ * Get the library version.
+ */
+
+YAML_DECLARE(const char *)
+yaml_get_version_string(void)
+{
+ return YAML_VERSION_STRING;
+}
+
+/*
+ * Get the library version numbers.
+ */
+
+YAML_DECLARE(void)
+yaml_get_version(int *major, int *minor, int *patch)
+{
+ *major = YAML_VERSION_MAJOR;
+ *minor = YAML_VERSION_MINOR;
+ *patch = YAML_VERSION_PATCH;
+}
+
+/*
+ * Allocate a dynamic memory block.
+ */
+
+YAML_DECLARE(void *)
+yaml_malloc(size_t size)
+{
+ return malloc(size ? size : 1);
+}
+
+/*
+ * Reallocate a dynamic memory block.
+ */
+
+YAML_DECLARE(void *)
+yaml_realloc(void *ptr, size_t size)
+{
+ return ptr ? realloc(ptr, size ? size : 1) : malloc(size ? size : 1);
+}
+
+/*
+ * Free a dynamic memory block.
+ */
+
+YAML_DECLARE(void)
+yaml_free(void *ptr)
+{
+ if (ptr) free(ptr);
+}
+
+/*
+ * Duplicate a string.
+ */
+
+YAML_DECLARE(yaml_char_t *)
+yaml_strdup(const yaml_char_t *str)
+{
+ if (!str)
+ return NULL;
+
+ return (yaml_char_t *)strdup((char *)str);
+}
+
+/*
+ * Extend a string.
+ */
+
+YAML_DECLARE(int)
+yaml_string_extend(yaml_char_t **start,
+ yaml_char_t **pointer, yaml_char_t **end)
+{
+ yaml_char_t *new_start = yaml_realloc(*start, (*end - *start)*2);
+
+ if (!new_start) return 0;
+
+ memset(new_start + (*end - *start), 0, *end - *start);
+
+ *pointer = new_start + (*pointer - *start);
+ *end = new_start + (*end - *start)*2;
+ *start = new_start;
+
+ return 1;
+}
+
+/*
+ * Append a string B to a string A.
+ */
+
+YAML_DECLARE(int)
+yaml_string_join(
+ yaml_char_t **a_start, yaml_char_t **a_pointer, yaml_char_t **a_end,
+ yaml_char_t **b_start, yaml_char_t **b_pointer, yaml_char_t **b_end)
+{
+ if (*b_start == *b_pointer)
+ return 1;
+
+ while (*a_end - *a_pointer <= *b_pointer - *b_start) {
+ if (!yaml_string_extend(a_start, a_pointer, a_end))
+ return 0;
+ }
+
+ memcpy(*a_pointer, *b_start, *b_pointer - *b_start);
+ *a_pointer += *b_pointer - *b_start;
+
+ return 1;
+}
+
+/*
+ * Extend a stack.
+ */
+
+YAML_DECLARE(int)
+yaml_stack_extend(void **start, void **top, void **end)
+{
+ void *new_start = yaml_realloc(*start, ((char *)*end - (char *)*start)*2);
+
+ if (!new_start) return 0;
+
+ *top = (char *)new_start + ((char *)*top - (char *)*start);
+ *end = (char *)new_start + ((char *)*end - (char *)*start)*2;
+ *start = new_start;
+
+ return 1;
+}
+
+/*
+ * Extend or move a queue.
+ */
+
+YAML_DECLARE(int)
+yaml_queue_extend(void **start, void **head, void **tail, void **end)
+{
+ /* Check if we need to resize the queue. */
+
+ if (*start == *head && *tail == *end) {
+ void *new_start = yaml_realloc(*start,
+ ((char *)*end - (char *)*start)*2);
+
+ if (!new_start) return 0;
+
+ *head = (char *)new_start + ((char *)*head - (char *)*start);
+ *tail = (char *)new_start + ((char *)*tail - (char *)*start);
+ *end = (char *)new_start + ((char *)*end - (char *)*start)*2;
+ *start = new_start;
+ }
+
+ /* Check if we need to move the queue at the beginning of the buffer. */
+
+ if (*tail == *end) {
+ if (*head != *tail) {
+ memmove(*start, *head, (char *)*tail - (char *)*head);
+ }
+ *tail = (char *)*tail - (char *)*head + (char *)*start;
+ *head = *start;
+ }
+
+ return 1;
+}
+
+
+/*
+ * Create a new parser object.
+ */
+
+YAML_DECLARE(int)
+yaml_parser_initialize(yaml_parser_t *parser)
+{
+ assert(parser); /* Non-NULL parser object expected. */
+
+ memset(parser, 0, sizeof(yaml_parser_t));
+ if (!BUFFER_INIT(parser, parser->raw_buffer, INPUT_RAW_BUFFER_SIZE))
+ goto error;
+ if (!BUFFER_INIT(parser, parser->buffer, INPUT_BUFFER_SIZE))
+ goto error;
+ if (!QUEUE_INIT(parser, parser->tokens, INITIAL_QUEUE_SIZE))
+ goto error;
+ if (!STACK_INIT(parser, parser->indents, INITIAL_STACK_SIZE))
+ goto error;
+ if (!STACK_INIT(parser, parser->simple_keys, INITIAL_STACK_SIZE))
+ goto error;
+ if (!STACK_INIT(parser, parser->states, INITIAL_STACK_SIZE))
+ goto error;
+ if (!STACK_INIT(parser, parser->marks, INITIAL_STACK_SIZE))
+ goto error;
+ if (!STACK_INIT(parser, parser->tag_directives, INITIAL_STACK_SIZE))
+ goto error;
+
+ return 1;
+
+error:
+
+ BUFFER_DEL(parser, parser->raw_buffer);
+ BUFFER_DEL(parser, parser->buffer);
+ QUEUE_DEL(parser, parser->tokens);
+ STACK_DEL(parser, parser->indents);
+ STACK_DEL(parser, parser->simple_keys);
+ STACK_DEL(parser, parser->states);
+ STACK_DEL(parser, parser->marks);
+ STACK_DEL(parser, parser->tag_directives);
+
+ return 0;
+}
+
+/*
+ * Destroy a parser object.
+ */
+
+YAML_DECLARE(void)
+yaml_parser_delete(yaml_parser_t *parser)
+{
+ assert(parser); /* Non-NULL parser object expected. */
+
+ BUFFER_DEL(parser, parser->raw_buffer);
+ BUFFER_DEL(parser, parser->buffer);
+ while (!QUEUE_EMPTY(parser, parser->tokens)) {
+ yaml_token_delete(&DEQUEUE(parser, parser->tokens));
+ }
+ QUEUE_DEL(parser, parser->tokens);
+ STACK_DEL(parser, parser->indents);
+ STACK_DEL(parser, parser->simple_keys);
+ STACK_DEL(parser, parser->states);
+ STACK_DEL(parser, parser->marks);
+ while (!STACK_EMPTY(parser, parser->tag_directives)) {
+ yaml_tag_directive_t tag_directive = POP(parser, parser->tag_directives);
+ yaml_free(tag_directive.handle);
+ yaml_free(tag_directive.prefix);
+ }
+ STACK_DEL(parser, parser->tag_directives);
+
+ memset(parser, 0, sizeof(yaml_parser_t));
+}
+
+/*
+ * String read handler.
+ */
+
+static int
+yaml_string_read_handler(void *data, unsigned char *buffer, size_t size,
+ size_t *size_read)
+{
+ yaml_parser_t *parser = data;
+
+ if (parser->input.string.current == parser->input.string.end) {
+ *size_read = 0;
+ return 1;
+ }
+
+ if (size > (size_t)(parser->input.string.end
+ - parser->input.string.current)) {
+ size = parser->input.string.end - parser->input.string.current;
+ }
+
+ memcpy(buffer, parser->input.string.current, size);
+ parser->input.string.current += size;
+ *size_read = size;
+ return 1;
+}
+
+/*
+ * File read handler.
+ */
+
+static int
+yaml_file_read_handler(void *data, unsigned char *buffer, size_t size,
+ size_t *size_read)
+{
+ yaml_parser_t *parser = data;
+
+ *size_read = fread(buffer, 1, size, parser->input.file);
+ return !ferror(parser->input.file);
+}
+
+/*
+ * Set a string input.
+ */
+
+YAML_DECLARE(void)
+yaml_parser_set_input_string(yaml_parser_t *parser,
+ const unsigned char *input, size_t size)
+{
+ assert(parser); /* Non-NULL parser object expected. */
+ assert(!parser->read_handler); /* You can set the source only once. */
+ assert(input); /* Non-NULL input string expected. */
+
+ parser->read_handler = yaml_string_read_handler;
+ parser->read_handler_data = parser;
+
+ parser->input.string.start = input;
+ parser->input.string.current = input;
+ parser->input.string.end = input+size;
+}
+
+/*
+ * Set a file input.
+ */
+
+YAML_DECLARE(void)
+yaml_parser_set_input_file(yaml_parser_t *parser, FILE *file)
+{
+ assert(parser); /* Non-NULL parser object expected. */
+ assert(!parser->read_handler); /* You can set the source only once. */
+ assert(file); /* Non-NULL file object expected. */
+
+ parser->read_handler = yaml_file_read_handler;
+ parser->read_handler_data = parser;
+
+ parser->input.file = file;
+}
+
+/*
+ * Set a generic input.
+ */
+
+YAML_DECLARE(void)
+yaml_parser_set_input(yaml_parser_t *parser,
+ yaml_read_handler_t *handler, void *data)
+{
+ assert(parser); /* Non-NULL parser object expected. */
+ assert(!parser->read_handler); /* You can set the source only once. */
+ assert(handler); /* Non-NULL read handler expected. */
+
+ parser->read_handler = handler;
+ parser->read_handler_data = data;
+}
+
+/*
+ * Set the source encoding.
+ */
+
+YAML_DECLARE(void)
+yaml_parser_set_encoding(yaml_parser_t *parser, yaml_encoding_t encoding)
+{
+ assert(parser); /* Non-NULL parser object expected. */
+ assert(!parser->encoding); /* Encoding is already set or detected. */
+
+ parser->encoding = encoding;
+}
+
+/*
+ * Create a new emitter object.
+ */
+
+YAML_DECLARE(int)
+yaml_emitter_initialize(yaml_emitter_t *emitter)
+{
+ assert(emitter); /* Non-NULL emitter object expected. */
+
+ memset(emitter, 0, sizeof(yaml_emitter_t));
+ if (!BUFFER_INIT(emitter, emitter->buffer, OUTPUT_BUFFER_SIZE))
+ goto error;
+ if (!BUFFER_INIT(emitter, emitter->raw_buffer, OUTPUT_RAW_BUFFER_SIZE))
+ goto error;
+ if (!STACK_INIT(emitter, emitter->states, INITIAL_STACK_SIZE))
+ goto error;
+ if (!QUEUE_INIT(emitter, emitter->events, INITIAL_QUEUE_SIZE))
+ goto error;
+ if (!STACK_INIT(emitter, emitter->indents, INITIAL_STACK_SIZE))
+ goto error;
+ if (!STACK_INIT(emitter, emitter->tag_directives, INITIAL_STACK_SIZE))
+ goto error;
+
+ return 1;
+
+error:
+
+ BUFFER_DEL(emitter, emitter->buffer);
+ BUFFER_DEL(emitter, emitter->raw_buffer);
+ STACK_DEL(emitter, emitter->states);
+ QUEUE_DEL(emitter, emitter->events);
+ STACK_DEL(emitter, emitter->indents);
+ STACK_DEL(emitter, emitter->tag_directives);
+
+ return 0;
+}
+
+/*
+ * Destroy an emitter object.
+ */
+
+YAML_DECLARE(void)
+yaml_emitter_delete(yaml_emitter_t *emitter)
+{
+ assert(emitter); /* Non-NULL emitter object expected. */
+
+ BUFFER_DEL(emitter, emitter->buffer);
+ BUFFER_DEL(emitter, emitter->raw_buffer);
+ STACK_DEL(emitter, emitter->states);
+ while (!QUEUE_EMPTY(emitter, emitter->events)) {
+ yaml_event_delete(&DEQUEUE(emitter, emitter->events));
+ }
+ QUEUE_DEL(emitter, emitter->events);
+ STACK_DEL(emitter, emitter->indents);
+ while (!STACK_EMPTY(empty, emitter->tag_directives)) {
+ yaml_tag_directive_t tag_directive = POP(emitter, emitter->tag_directives);
+ yaml_free(tag_directive.handle);
+ yaml_free(tag_directive.prefix);
+ }
+ STACK_DEL(emitter, emitter->tag_directives);
+ yaml_free(emitter->anchors);
+
+ memset(emitter, 0, sizeof(yaml_emitter_t));
+}
+
+/*
+ * String write handler.
+ */
+
+static int
+yaml_string_write_handler(void *data, unsigned char *buffer, size_t size)
+{
+ yaml_emitter_t *emitter = data;
+
+ if (emitter->output.string.size + *emitter->output.string.size_written
+ < size) {
+ memcpy(emitter->output.string.buffer
+ + *emitter->output.string.size_written,
+ buffer,
+ emitter->output.string.size
+ - *emitter->output.string.size_written);
+ *emitter->output.string.size_written = emitter->output.string.size;
+ return 0;
+ }
+
+ memcpy(emitter->output.string.buffer
+ + *emitter->output.string.size_written, buffer, size);
+ *emitter->output.string.size_written += size;
+ return 1;
+}
+
+/*
+ * File write handler.
+ */
+
+static int
+yaml_file_write_handler(void *data, unsigned char *buffer, size_t size)
+{
+ yaml_emitter_t *emitter = data;
+
+ return (fwrite(buffer, 1, size, emitter->output.file) == size);
+}
+/*
+ * Set a string output.
+ */
+
+YAML_DECLARE(void)
+yaml_emitter_set_output_string(yaml_emitter_t *emitter,
+ unsigned char *output, size_t size, size_t *size_written)
+{
+ assert(emitter); /* Non-NULL emitter object expected. */
+ assert(!emitter->write_handler); /* You can set the output only once. */
+ assert(output); /* Non-NULL output string expected. */
+
+ emitter->write_handler = yaml_string_write_handler;
+ emitter->write_handler_data = emitter;
+
+ emitter->output.string.buffer = output;
+ emitter->output.string.size = size;
+ emitter->output.string.size_written = size_written;
+ *size_written = 0;
+}
+
+/*
+ * Set a file output.
+ */
+
+YAML_DECLARE(void)
+yaml_emitter_set_output_file(yaml_emitter_t *emitter, FILE *file)
+{
+ assert(emitter); /* Non-NULL emitter object expected. */
+ assert(!emitter->write_handler); /* You can set the output only once. */
+ assert(file); /* Non-NULL file object expected. */
+
+ emitter->write_handler = yaml_file_write_handler;
+ emitter->write_handler_data = emitter;
+
+ emitter->output.file = file;
+}
+
+/*
+ * Set a generic output handler.
+ */
+
+YAML_DECLARE(void)
+yaml_emitter_set_output(yaml_emitter_t *emitter,
+ yaml_write_handler_t *handler, void *data)
+{
+ assert(emitter); /* Non-NULL emitter object expected. */
+ assert(!emitter->write_handler); /* You can set the output only once. */
+ assert(handler); /* Non-NULL handler object expected. */
+
+ emitter->write_handler = handler;
+ emitter->write_handler_data = data;
+}
+
+/*
+ * Set the output encoding.
+ */
+
+YAML_DECLARE(void)
+yaml_emitter_set_encoding(yaml_emitter_t *emitter, yaml_encoding_t encoding)
+{
+ assert(emitter); /* Non-NULL emitter object expected. */
+ assert(!emitter->encoding); /* You can set encoding only once. */
+
+ emitter->encoding = encoding;
+}
+
+/*
+ * Set the canonical output style.
+ */
+
+YAML_DECLARE(void)
+yaml_emitter_set_canonical(yaml_emitter_t *emitter, int canonical)
+{
+ assert(emitter); /* Non-NULL emitter object expected. */
+
+ emitter->canonical = (canonical != 0);
+}
+
+/*
+ * Set the indentation increment.
+ */
+
+YAML_DECLARE(void)
+yaml_emitter_set_indent(yaml_emitter_t *emitter, int indent)
+{
+ assert(emitter); /* Non-NULL emitter object expected. */
+
+ emitter->best_indent = (1 < indent && indent < 10) ? indent : 2;
+}
+
+/*
+ * Set the preferred line width.
+ */
+
+YAML_DECLARE(void)
+yaml_emitter_set_width(yaml_emitter_t *emitter, int width)
+{
+ assert(emitter); /* Non-NULL emitter object expected. */
+
+ emitter->best_width = (width >= 0) ? width : -1;
+}
+
+/*
+ * Set if unescaped non-ASCII characters are allowed.
+ */
+
+YAML_DECLARE(void)
+yaml_emitter_set_unicode(yaml_emitter_t *emitter, int unicode)
+{
+ assert(emitter); /* Non-NULL emitter object expected. */
+
+ emitter->unicode = (unicode != 0);
+}
+
+/*
+ * Set the preferred line break character.
+ */
+
+YAML_DECLARE(void)
+yaml_emitter_set_break(yaml_emitter_t *emitter, yaml_break_t line_break)
+{
+ assert(emitter); /* Non-NULL emitter object expected. */
+
+ emitter->line_break = line_break;
+}
+
+/*
+ * Destroy a token object.
+ */
+
+YAML_DECLARE(void)
+yaml_token_delete(yaml_token_t *token)
+{
+ assert(token); /* Non-NULL token object expected. */
+
+ switch (token->type)
+ {
+ case YAML_TAG_DIRECTIVE_TOKEN:
+ yaml_free(token->data.tag_directive.handle);
+ yaml_free(token->data.tag_directive.prefix);
+ break;
+
+ case YAML_ALIAS_TOKEN:
+ yaml_free(token->data.alias.value);
+ break;
+
+ case YAML_ANCHOR_TOKEN:
+ yaml_free(token->data.anchor.value);
+ break;
+
+ case YAML_TAG_TOKEN:
+ yaml_free(token->data.tag.handle);
+ yaml_free(token->data.tag.suffix);
+ break;
+
+ case YAML_SCALAR_TOKEN:
+ yaml_free(token->data.scalar.value);
+ break;
+
+ default:
+ break;
+ }
+
+ memset(token, 0, sizeof(yaml_token_t));
+}
+
+/*
+ * Check if a string is a valid UTF-8 sequence.
+ *
+ * Check 'reader.c' for more details on UTF-8 encoding.
+ */
+
+static int
+yaml_check_utf8(yaml_char_t *start, size_t length)
+{
+ yaml_char_t *end = start+length;
+ yaml_char_t *pointer = start;
+
+ while (pointer < end) {
+ unsigned char octet;
+ unsigned int width;
+ unsigned int value;
+ size_t k;
+
+ octet = pointer[0];
+ width = (octet & 0x80) == 0x00 ? 1 :
+ (octet & 0xE0) == 0xC0 ? 2 :
+ (octet & 0xF0) == 0xE0 ? 3 :
+ (octet & 0xF8) == 0xF0 ? 4 : 0;
+ value = (octet & 0x80) == 0x00 ? octet & 0x7F :
+ (octet & 0xE0) == 0xC0 ? octet & 0x1F :
+ (octet & 0xF0) == 0xE0 ? octet & 0x0F :
+ (octet & 0xF8) == 0xF0 ? octet & 0x07 : 0;
+ if (!width) return 0;
+ if (pointer+width > end) return 0;
+ for (k = 1; k < width; k ++) {
+ octet = pointer[k];
+ if ((octet & 0xC0) != 0x80) return 0;
+ value = (value << 6) + (octet & 0x3F);
+ }
+ if (!((width == 1) ||
+ (width == 2 && value >= 0x80) ||
+ (width == 3 && value >= 0x800) ||
+ (width == 4 && value >= 0x10000))) return 0;
+
+ pointer += width;
+ }
+
+ return 1;
+}
+
+/*
+ * Create STREAM-START.
+ */
+
+YAML_DECLARE(int)
+yaml_stream_start_event_initialize(yaml_event_t *event,
+ yaml_encoding_t encoding)
+{
+ yaml_mark_t mark = { 0, 0, 0 };
+
+ assert(event); /* Non-NULL event object is expected. */
+
+ STREAM_START_EVENT_INIT(*event, encoding, mark, mark);
+
+ return 1;
+}
+
+/*
+ * Create STREAM-END.
+ */
+
+YAML_DECLARE(int)
+yaml_stream_end_event_initialize(yaml_event_t *event)
+{
+ yaml_mark_t mark = { 0, 0, 0 };
+
+ assert(event); /* Non-NULL event object is expected. */
+
+ STREAM_END_EVENT_INIT(*event, mark, mark);
+
+ return 1;
+}
+
+/*
+ * Create DOCUMENT-START.
+ */
+
+YAML_DECLARE(int)
+yaml_document_start_event_initialize(yaml_event_t *event,
+ yaml_version_directive_t *version_directive,
+ yaml_tag_directive_t *tag_directives_start,
+ yaml_tag_directive_t *tag_directives_end,
+ int implicit)
+{
+ struct {
+ yaml_error_type_t error;
+ } context;
+ yaml_mark_t mark = { 0, 0, 0 };
+ yaml_version_directive_t *version_directive_copy = NULL;
+ struct {
+ yaml_tag_directive_t *start;
+ yaml_tag_directive_t *end;
+ yaml_tag_directive_t *top;
+ } tag_directives_copy = { NULL, NULL, NULL };
+ yaml_tag_directive_t value = { NULL, NULL };
+
+ assert(event); /* Non-NULL event object is expected. */
+ assert((tag_directives_start && tag_directives_end) ||
+ (tag_directives_start == tag_directives_end));
+ /* Valid tag directives are expected. */
+
+ if (version_directive) {
+ version_directive_copy = yaml_malloc(sizeof(yaml_version_directive_t));
+ if (!version_directive_copy) goto error;
+ version_directive_copy->major = version_directive->major;
+ version_directive_copy->minor = version_directive->minor;
+ }
+
+ if (tag_directives_start != tag_directives_end) {
+ yaml_tag_directive_t *tag_directive;
+ if (!STACK_INIT(&context, tag_directives_copy, INITIAL_STACK_SIZE))
+ goto error;
+ for (tag_directive = tag_directives_start;
+ tag_directive != tag_directives_end; tag_directive ++) {
+ assert(tag_directive->handle);
+ assert(tag_directive->prefix);
+ if (!yaml_check_utf8(tag_directive->handle,
+ strlen((char *)tag_directive->handle)))
+ goto error;
+ if (!yaml_check_utf8(tag_directive->prefix,
+ strlen((char *)tag_directive->prefix)))
+ goto error;
+ value.handle = yaml_strdup(tag_directive->handle);
+ value.prefix = yaml_strdup(tag_directive->prefix);
+ if (!value.handle || !value.prefix) goto error;
+ if (!PUSH(&context, tag_directives_copy, value))
+ goto error;
+ value.handle = NULL;
+ value.prefix = NULL;
+ }
+ }
+
+ DOCUMENT_START_EVENT_INIT(*event, version_directive_copy,
+ tag_directives_copy.start, tag_directives_copy.top,
+ implicit, mark, mark);
+
+ return 1;
+
+error:
+ yaml_free(version_directive_copy);
+ while (!STACK_EMPTY(context, tag_directives_copy)) {
+ yaml_tag_directive_t value = POP(context, tag_directives_copy);
+ yaml_free(value.handle);
+ yaml_free(value.prefix);
+ }
+ STACK_DEL(context, tag_directives_copy);
+ yaml_free(value.handle);
+ yaml_free(value.prefix);
+
+ return 0;
+}
+
+/*
+ * Create DOCUMENT-END.
+ */
+
+YAML_DECLARE(int)
+yaml_document_end_event_initialize(yaml_event_t *event, int implicit)
+{
+ yaml_mark_t mark = { 0, 0, 0 };
+
+ assert(event); /* Non-NULL emitter object is expected. */
+
+ DOCUMENT_END_EVENT_INIT(*event, implicit, mark, mark);
+
+ return 1;
+}
+
+/*
+ * Create ALIAS.
+ */
+
+YAML_DECLARE(int)
+yaml_alias_event_initialize(yaml_event_t *event, yaml_char_t *anchor)
+{
+ yaml_mark_t mark = { 0, 0, 0 };
+ yaml_char_t *anchor_copy = NULL;
+
+ assert(event); /* Non-NULL event object is expected. */
+ assert(anchor); /* Non-NULL anchor is expected. */
+
+ if (!yaml_check_utf8(anchor, strlen((char *)anchor))) return 0;
+
+ anchor_copy = yaml_strdup(anchor);
+ if (!anchor_copy)
+ return 0;
+
+ ALIAS_EVENT_INIT(*event, anchor_copy, mark, mark);
+
+ return 1;
+}
+
+/*
+ * Create SCALAR.
+ */
+
+YAML_DECLARE(int)
+yaml_scalar_event_initialize(yaml_event_t *event,
+ yaml_char_t *anchor, yaml_char_t *tag,
+ yaml_char_t *value, int length,
+ int plain_implicit, int quoted_implicit,
+ yaml_scalar_style_t style)
+{
+ yaml_mark_t mark = { 0, 0, 0 };
+ yaml_char_t *anchor_copy = NULL;
+ yaml_char_t *tag_copy = NULL;
+ yaml_char_t *value_copy = NULL;
+
+ assert(event); /* Non-NULL event object is expected. */
+ assert(value); /* Non-NULL anchor is expected. */
+
+ if (anchor) {
+ if (!yaml_check_utf8(anchor, strlen((char *)anchor))) goto error;
+ anchor_copy = yaml_strdup(anchor);
+ if (!anchor_copy) goto error;
+ }
+
+ if (tag) {
+ if (!yaml_check_utf8(tag, strlen((char *)tag))) goto error;
+ tag_copy = yaml_strdup(tag);
+ if (!tag_copy) goto error;
+ }
+
+ if (length < 0) {
+ length = strlen((char *)value);
+ }
+
+ if (!yaml_check_utf8(value, length)) goto error;
+ value_copy = yaml_malloc(length+1);
+ if (!value_copy) goto error;
+ memcpy(value_copy, value, length);
+ value_copy[length] = '\0';
+
+ SCALAR_EVENT_INIT(*event, anchor_copy, tag_copy, value_copy, length,
+ plain_implicit, quoted_implicit, style, mark, mark);
+
+ return 1;
+
+error:
+ yaml_free(anchor_copy);
+ yaml_free(tag_copy);
+ yaml_free(value_copy);
+
+ return 0;
+}
+
+/*
+ * Create SEQUENCE-START.
+ */
+
+YAML_DECLARE(int)
+yaml_sequence_start_event_initialize(yaml_event_t *event,
+ yaml_char_t *anchor, yaml_char_t *tag, int implicit,
+ yaml_sequence_style_t style)
+{
+ yaml_mark_t mark = { 0, 0, 0 };
+ yaml_char_t *anchor_copy = NULL;
+ yaml_char_t *tag_copy = NULL;
+
+ assert(event); /* Non-NULL event object is expected. */
+
+ if (anchor) {
+ if (!yaml_check_utf8(anchor, strlen((char *)anchor))) goto error;
+ anchor_copy = yaml_strdup(anchor);
+ if (!anchor_copy) goto error;
+ }
+
+ if (tag) {
+ if (!yaml_check_utf8(tag, strlen((char *)tag))) goto error;
+ tag_copy = yaml_strdup(tag);
+ if (!tag_copy) goto error;
+ }
+
+ SEQUENCE_START_EVENT_INIT(*event, anchor_copy, tag_copy,
+ implicit, style, mark, mark);
+
+ return 1;
+
+error:
+ yaml_free(anchor_copy);
+ yaml_free(tag_copy);
+
+ return 0;
+}
+
+/*
+ * Create SEQUENCE-END.
+ */
+
+YAML_DECLARE(int)
+yaml_sequence_end_event_initialize(yaml_event_t *event)
+{
+ yaml_mark_t mark = { 0, 0, 0 };
+
+ assert(event); /* Non-NULL event object is expected. */
+
+ SEQUENCE_END_EVENT_INIT(*event, mark, mark);
+
+ return 1;
+}
+
+/*
+ * Create MAPPING-START.
+ */
+
+YAML_DECLARE(int)
+yaml_mapping_start_event_initialize(yaml_event_t *event,
+ yaml_char_t *anchor, yaml_char_t *tag, int implicit,
+ yaml_mapping_style_t style)
+{
+ yaml_mark_t mark = { 0, 0, 0 };
+ yaml_char_t *anchor_copy = NULL;
+ yaml_char_t *tag_copy = NULL;
+
+ assert(event); /* Non-NULL event object is expected. */
+
+ if (anchor) {
+ if (!yaml_check_utf8(anchor, strlen((char *)anchor))) goto error;
+ anchor_copy = yaml_strdup(anchor);
+ if (!anchor_copy) goto error;
+ }
+
+ if (tag) {
+ if (!yaml_check_utf8(tag, strlen((char *)tag))) goto error;
+ tag_copy = yaml_strdup(tag);
+ if (!tag_copy) goto error;
+ }
+
+ MAPPING_START_EVENT_INIT(*event, anchor_copy, tag_copy,
+ implicit, style, mark, mark);
+
+ return 1;
+
+error:
+ yaml_free(anchor_copy);
+ yaml_free(tag_copy);
+
+ return 0;
+}
+
+/*
+ * Create MAPPING-END.
+ */
+
+YAML_DECLARE(int)
+yaml_mapping_end_event_initialize(yaml_event_t *event)
+{
+ yaml_mark_t mark = { 0, 0, 0 };
+
+ assert(event); /* Non-NULL event object is expected. */
+
+ MAPPING_END_EVENT_INIT(*event, mark, mark);
+
+ return 1;
+}
+
+/*
+ * Destroy an event object.
+ */
+
+YAML_DECLARE(void)
+yaml_event_delete(yaml_event_t *event)
+{
+ yaml_tag_directive_t *tag_directive;
+
+ assert(event); /* Non-NULL event object expected. */
+
+ switch (event->type)
+ {
+ case YAML_DOCUMENT_START_EVENT:
+ yaml_free(event->data.document_start.version_directive);
+ for (tag_directive = event->data.document_start.tag_directives.start;
+ tag_directive != event->data.document_start.tag_directives.end;
+ tag_directive++) {
+ yaml_free(tag_directive->handle);
+ yaml_free(tag_directive->prefix);
+ }
+ yaml_free(event->data.document_start.tag_directives.start);
+ break;
+
+ case YAML_ALIAS_EVENT:
+ yaml_free(event->data.alias.anchor);
+ break;
+
+ case YAML_SCALAR_EVENT:
+ yaml_free(event->data.scalar.anchor);
+ yaml_free(event->data.scalar.tag);
+ yaml_free(event->data.scalar.value);
+ break;
+
+ case YAML_SEQUENCE_START_EVENT:
+ yaml_free(event->data.sequence_start.anchor);
+ yaml_free(event->data.sequence_start.tag);
+ break;
+
+ case YAML_MAPPING_START_EVENT:
+ yaml_free(event->data.mapping_start.anchor);
+ yaml_free(event->data.mapping_start.tag);
+ break;
+
+ default:
+ break;
+ }
+
+ memset(event, 0, sizeof(yaml_event_t));
+}
+
+/*
+ * Create a document object.
+ */
+
+YAML_DECLARE(int)
+yaml_document_initialize(yaml_document_t *document,
+ yaml_version_directive_t *version_directive,
+ yaml_tag_directive_t *tag_directives_start,
+ yaml_tag_directive_t *tag_directives_end,
+ int start_implicit, int end_implicit)
+{
+ struct {
+ yaml_error_type_t error;
+ } context;
+ struct {
+ yaml_node_t *start;
+ yaml_node_t *end;
+ yaml_node_t *top;
+ } nodes = { NULL, NULL, NULL };
+ yaml_version_directive_t *version_directive_copy = NULL;
+ struct {
+ yaml_tag_directive_t *start;
+ yaml_tag_directive_t *end;
+ yaml_tag_directive_t *top;
+ } tag_directives_copy = { NULL, NULL, NULL };
+ yaml_tag_directive_t value = { NULL, NULL };
+ yaml_mark_t mark = { 0, 0, 0 };
+
+ assert(document); /* Non-NULL document object is expected. */
+ assert((tag_directives_start && tag_directives_end) ||
+ (tag_directives_start == tag_directives_end));
+ /* Valid tag directives are expected. */
+
+ if (!STACK_INIT(&context, nodes, INITIAL_STACK_SIZE)) goto error;
+
+ if (version_directive) {
+ version_directive_copy = yaml_malloc(sizeof(yaml_version_directive_t));
+ if (!version_directive_copy) goto error;
+ version_directive_copy->major = version_directive->major;
+ version_directive_copy->minor = version_directive->minor;
+ }
+
+ if (tag_directives_start != tag_directives_end) {
+ yaml_tag_directive_t *tag_directive;
+ if (!STACK_INIT(&context, tag_directives_copy, INITIAL_STACK_SIZE))
+ goto error;
+ for (tag_directive = tag_directives_start;
+ tag_directive != tag_directives_end; tag_directive ++) {
+ assert(tag_directive->handle);
+ assert(tag_directive->prefix);
+ if (!yaml_check_utf8(tag_directive->handle,
+ strlen((char *)tag_directive->handle)))
+ goto error;
+ if (!yaml_check_utf8(tag_directive->prefix,
+ strlen((char *)tag_directive->prefix)))
+ goto error;
+ value.handle = yaml_strdup(tag_directive->handle);
+ value.prefix = yaml_strdup(tag_directive->prefix);
+ if (!value.handle || !value.prefix) goto error;
+ if (!PUSH(&context, tag_directives_copy, value))
+ goto error;
+ value.handle = NULL;
+ value.prefix = NULL;
+ }
+ }
+
+ DOCUMENT_INIT(*document, nodes.start, nodes.end, version_directive_copy,
+ tag_directives_copy.start, tag_directives_copy.top,
+ start_implicit, end_implicit, mark, mark);
+
+ return 1;
+
+error:
+ STACK_DEL(&context, nodes);
+ yaml_free(version_directive_copy);
+ while (!STACK_EMPTY(&context, tag_directives_copy)) {
+ yaml_tag_directive_t value = POP(&context, tag_directives_copy);
+ yaml_free(value.handle);
+ yaml_free(value.prefix);
+ }
+ STACK_DEL(&context, tag_directives_copy);
+ yaml_free(value.handle);
+ yaml_free(value.prefix);
+
+ return 0;
+}
+
+/*
+ * Destroy a document object.
+ */
+
+YAML_DECLARE(void)
+yaml_document_delete(yaml_document_t *document)
+{
+ struct {
+ yaml_error_type_t error;
+ } context;
+ yaml_tag_directive_t *tag_directive;
+
+ context.error = YAML_NO_ERROR; /* Eliminate a compliler warning. */
+
+ assert(document); /* Non-NULL document object is expected. */
+
+ while (!STACK_EMPTY(&context, document->nodes)) {
+ yaml_node_t node = POP(&context, document->nodes);
+ yaml_free(node.tag);
+ switch (node.type) {
+ case YAML_SCALAR_NODE:
+ yaml_free(node.data.scalar.value);
+ break;
+ case YAML_SEQUENCE_NODE:
+ STACK_DEL(&context, node.data.sequence.items);
+ break;
+ case YAML_MAPPING_NODE:
+ STACK_DEL(&context, node.data.mapping.pairs);
+ break;
+ default:
+ assert(0); /* Should not happen. */
+ }
+ }
+ STACK_DEL(&context, document->nodes);
+
+ yaml_free(document->version_directive);
+ for (tag_directive = document->tag_directives.start;
+ tag_directive != document->tag_directives.end;
+ tag_directive++) {
+ yaml_free(tag_directive->handle);
+ yaml_free(tag_directive->prefix);
+ }
+ yaml_free(document->tag_directives.start);
+
+ memset(document, 0, sizeof(yaml_document_t));
+}
+
+/**
+ * Get a document node.
+ */
+
+YAML_DECLARE(yaml_node_t *)
+yaml_document_get_node(yaml_document_t *document, int index)
+{
+ assert(document); /* Non-NULL document object is expected. */
+
+ if (index > 0 && document->nodes.start + index <= document->nodes.top) {
+ return document->nodes.start + index - 1;
+ }
+ return NULL;
+}
+
+/**
+ * Get the root object.
+ */
+
+YAML_DECLARE(yaml_node_t *)
+yaml_document_get_root_node(yaml_document_t *document)
+{
+ assert(document); /* Non-NULL document object is expected. */
+
+ if (document->nodes.top != document->nodes.start) {
+ return document->nodes.start;
+ }
+ return NULL;
+}
+
+/*
+ * Add a scalar node to a document.
+ */
+
+YAML_DECLARE(int)
+yaml_document_add_scalar(yaml_document_t *document,
+ yaml_char_t *tag, yaml_char_t *value, int length,
+ yaml_scalar_style_t style)
+{
+ struct {
+ yaml_error_type_t error;
+ } context;
+ yaml_mark_t mark = { 0, 0, 0 };
+ yaml_char_t *tag_copy = NULL;
+ yaml_char_t *value_copy = NULL;
+ yaml_node_t node;
+
+ assert(document); /* Non-NULL document object is expected. */
+ assert(value); /* Non-NULL value is expected. */
+
+ if (!tag) {
+ tag = (yaml_char_t *)YAML_DEFAULT_SCALAR_TAG;
+ }
+
+ if (!yaml_check_utf8(tag, strlen((char *)tag))) goto error;
+ tag_copy = yaml_strdup(tag);
+ if (!tag_copy) goto error;
+
+ if (length < 0) {
+ length = strlen((char *)value);
+ }
+
+ if (!yaml_check_utf8(value, length)) goto error;
+ value_copy = yaml_malloc(length+1);
+ if (!value_copy) goto error;
+ memcpy(value_copy, value, length);
+ value_copy[length] = '\0';
+
+ SCALAR_NODE_INIT(node, tag_copy, value_copy, length, style, mark, mark);
+ if (!PUSH(&context, document->nodes, node)) goto error;
+
+ return document->nodes.top - document->nodes.start;
+
+error:
+ yaml_free(tag_copy);
+ yaml_free(value_copy);
+
+ return 0;
+}
+
+/*
+ * Add a sequence node to a document.
+ */
+
+YAML_DECLARE(int)
+yaml_document_add_sequence(yaml_document_t *document,
+ yaml_char_t *tag, yaml_sequence_style_t style)
+{
+ struct {
+ yaml_error_type_t error;
+ } context;
+ yaml_mark_t mark = { 0, 0, 0 };
+ yaml_char_t *tag_copy = NULL;
+ struct {
+ yaml_node_item_t *start;
+ yaml_node_item_t *end;
+ yaml_node_item_t *top;
+ } items = { NULL, NULL, NULL };
+ yaml_node_t node;
+
+ assert(document); /* Non-NULL document object is expected. */
+
+ if (!tag) {
+ tag = (yaml_char_t *)YAML_DEFAULT_SEQUENCE_TAG;
+ }
+
+ if (!yaml_check_utf8(tag, strlen((char *)tag))) goto error;
+ tag_copy = yaml_strdup(tag);
+ if (!tag_copy) goto error;
+
+ if (!STACK_INIT(&context, items, INITIAL_STACK_SIZE)) goto error;
+
+ SEQUENCE_NODE_INIT(node, tag_copy, items.start, items.end,
+ style, mark, mark);
+ if (!PUSH(&context, document->nodes, node)) goto error;
+
+ return document->nodes.top - document->nodes.start;
+
+error:
+ STACK_DEL(&context, items);
+ yaml_free(tag_copy);
+
+ return 0;
+}
+
+/*
+ * Add a mapping node to a document.
+ */
+
+YAML_DECLARE(int)
+yaml_document_add_mapping(yaml_document_t *document,
+ yaml_char_t *tag, yaml_mapping_style_t style)
+{
+ struct {
+ yaml_error_type_t error;
+ } context;
+ yaml_mark_t mark = { 0, 0, 0 };
+ yaml_char_t *tag_copy = NULL;
+ struct {
+ yaml_node_pair_t *start;
+ yaml_node_pair_t *end;
+ yaml_node_pair_t *top;
+ } pairs = { NULL, NULL, NULL };
+ yaml_node_t node;
+
+ assert(document); /* Non-NULL document object is expected. */
+
+ if (!tag) {
+ tag = (yaml_char_t *)YAML_DEFAULT_MAPPING_TAG;
+ }
+
+ if (!yaml_check_utf8(tag, strlen((char *)tag))) goto error;
+ tag_copy = yaml_strdup(tag);
+ if (!tag_copy) goto error;
+
+ if (!STACK_INIT(&context, pairs, INITIAL_STACK_SIZE)) goto error;
+
+ MAPPING_NODE_INIT(node, tag_copy, pairs.start, pairs.end,
+ style, mark, mark);
+ if (!PUSH(&context, document->nodes, node)) goto error;
+
+ return document->nodes.top - document->nodes.start;
+
+error:
+ STACK_DEL(&context, pairs);
+ yaml_free(tag_copy);
+
+ return 0;
+}
+
+/*
+ * Append an item to a sequence node.
+ */
+
+YAML_DECLARE(int)
+yaml_document_append_sequence_item(yaml_document_t *document,
+ int sequence, int item)
+{
+ struct {
+ yaml_error_type_t error;
+ } context;
+
+ assert(document); /* Non-NULL document is required. */
+ assert(sequence > 0
+ && document->nodes.start + sequence <= document->nodes.top);
+ /* Valid sequence id is required. */
+ assert(document->nodes.start[sequence-1].type == YAML_SEQUENCE_NODE);
+ /* A sequence node is required. */
+ assert(item > 0 && document->nodes.start + item <= document->nodes.top);
+ /* Valid item id is required. */
+
+ if (!PUSH(&context,
+ document->nodes.start[sequence-1].data.sequence.items, item))
+ return 0;
+
+ return 1;
+}
+
+/*
+ * Append a pair of a key and a value to a mapping node.
+ */
+
+YAML_DECLARE(int)
+yaml_document_append_mapping_pair(yaml_document_t *document,
+ int mapping, int key, int value)
+{
+ struct {
+ yaml_error_type_t error;
+ } context;
+
+ yaml_node_pair_t pair;
+
+ assert(document); /* Non-NULL document is required. */
+ assert(mapping > 0
+ && document->nodes.start + mapping <= document->nodes.top);
+ /* Valid mapping id is required. */
+ assert(document->nodes.start[mapping-1].type == YAML_MAPPING_NODE);
+ /* A mapping node is required. */
+ assert(key > 0 && document->nodes.start + key <= document->nodes.top);
+ /* Valid key id is required. */
+ assert(value > 0 && document->nodes.start + value <= document->nodes.top);
+ /* Valid value id is required. */
+
+ pair.key = key;
+ pair.value = value;
+
+ if (!PUSH(&context,
+ document->nodes.start[mapping-1].data.mapping.pairs, pair))
+ return 0;
+
+ return 1;
+}
+
+
diff --git a/contrib/libyaml/src/dumper.c b/contrib/libyaml/src/dumper.c
new file mode 100644
index 0000000..203c6a7
--- /dev/null
+++ b/contrib/libyaml/src/dumper.c
@@ -0,0 +1,394 @@
+
+#include "yaml_private.h"
+
+/*
+ * API functions.
+ */
+
+YAML_DECLARE(int)
+yaml_emitter_open(yaml_emitter_t *emitter);
+
+YAML_DECLARE(int)
+yaml_emitter_close(yaml_emitter_t *emitter);
+
+YAML_DECLARE(int)
+yaml_emitter_dump(yaml_emitter_t *emitter, yaml_document_t *document);
+
+/*
+ * Clean up functions.
+ */
+
+static void
+yaml_emitter_delete_document_and_anchors(yaml_emitter_t *emitter);
+
+/*
+ * Anchor functions.
+ */
+
+static void
+yaml_emitter_anchor_node(yaml_emitter_t *emitter, int index);
+
+static yaml_char_t *
+yaml_emitter_generate_anchor(yaml_emitter_t *emitter, int anchor_id);
+
+
+/*
+ * Serialize functions.
+ */
+
+static int
+yaml_emitter_dump_node(yaml_emitter_t *emitter, int index);
+
+static int
+yaml_emitter_dump_alias(yaml_emitter_t *emitter, yaml_char_t *anchor);
+
+static int
+yaml_emitter_dump_scalar(yaml_emitter_t *emitter, yaml_node_t *node,
+ yaml_char_t *anchor);
+
+static int
+yaml_emitter_dump_sequence(yaml_emitter_t *emitter, yaml_node_t *node,
+ yaml_char_t *anchor);
+
+static int
+yaml_emitter_dump_mapping(yaml_emitter_t *emitter, yaml_node_t *node,
+ yaml_char_t *anchor);
+
+/*
+ * Issue a STREAM-START event.
+ */
+
+YAML_DECLARE(int)
+yaml_emitter_open(yaml_emitter_t *emitter)
+{
+ yaml_event_t event;
+ yaml_mark_t mark = { 0, 0, 0 };
+
+ assert(emitter); /* Non-NULL emitter object is required. */
+ assert(!emitter->opened); /* Emitter should not be opened yet. */
+
+ STREAM_START_EVENT_INIT(event, YAML_ANY_ENCODING, mark, mark);
+
+ if (!yaml_emitter_emit(emitter, &event)) {
+ return 0;
+ }
+
+ emitter->opened = 1;
+
+ return 1;
+}
+
+/*
+ * Issue a STREAM-END event.
+ */
+
+YAML_DECLARE(int)
+yaml_emitter_close(yaml_emitter_t *emitter)
+{
+ yaml_event_t event;
+ yaml_mark_t mark = { 0, 0, 0 };
+
+ assert(emitter); /* Non-NULL emitter object is required. */
+ assert(emitter->opened); /* Emitter should be opened. */
+
+ if (emitter->closed) return 1;
+
+ STREAM_END_EVENT_INIT(event, mark, mark);
+
+ if (!yaml_emitter_emit(emitter, &event)) {
+ return 0;
+ }
+
+ emitter->closed = 1;
+
+ return 1;
+}
+
+/*
+ * Dump a YAML document.
+ */
+
+YAML_DECLARE(int)
+yaml_emitter_dump(yaml_emitter_t *emitter, yaml_document_t *document)
+{
+ yaml_event_t event;
+ yaml_mark_t mark = { 0, 0, 0 };
+
+ assert(emitter); /* Non-NULL emitter object is required. */
+ assert(document); /* Non-NULL emitter object is expected. */
+
+ emitter->document = document;
+
+ if (!emitter->opened) {
+ if (!yaml_emitter_open(emitter)) goto error;
+ }
+
+ if (STACK_EMPTY(emitter, document->nodes)) {
+ if (!yaml_emitter_close(emitter)) goto error;
+ yaml_emitter_delete_document_and_anchors(emitter);
+ return 1;
+ }
+
+ assert(emitter->opened); /* Emitter should be opened. */
+
+ emitter->anchors = yaml_malloc(sizeof(*(emitter->anchors))
+ * (document->nodes.top - document->nodes.start));
+ if (!emitter->anchors) goto error;
+ memset(emitter->anchors, 0, sizeof(*(emitter->anchors))
+ * (document->nodes.top - document->nodes.start));
+
+ DOCUMENT_START_EVENT_INIT(event, document->version_directive,
+ document->tag_directives.start, document->tag_directives.end,
+ document->start_implicit, mark, mark);
+ if (!yaml_emitter_emit(emitter, &event)) goto error;
+
+ yaml_emitter_anchor_node(emitter, 1);
+ if (!yaml_emitter_dump_node(emitter, 1)) goto error;
+
+ DOCUMENT_END_EVENT_INIT(event, document->end_implicit, mark, mark);
+ if (!yaml_emitter_emit(emitter, &event)) goto error;
+
+ yaml_emitter_delete_document_and_anchors(emitter);
+
+ return 1;
+
+error:
+
+ yaml_emitter_delete_document_and_anchors(emitter);
+
+ return 0;
+}
+
+/*
+ * Clean up the emitter object after a document is dumped.
+ */
+
+static void
+yaml_emitter_delete_document_and_anchors(yaml_emitter_t *emitter)
+{
+ int index;
+
+ if (!emitter->anchors) {
+ yaml_document_delete(emitter->document);
+ emitter->document = NULL;
+ return;
+ }
+
+ for (index = 0; emitter->document->nodes.start + index
+ < emitter->document->nodes.top; index ++) {
+ yaml_node_t node = emitter->document->nodes.start[index];
+ if (!emitter->anchors[index].serialized) {
+ yaml_free(node.tag);
+ if (node.type == YAML_SCALAR_NODE) {
+ yaml_free(node.data.scalar.value);
+ }
+ }
+ if (node.type == YAML_SEQUENCE_NODE) {
+ STACK_DEL(emitter, node.data.sequence.items);
+ }
+ if (node.type == YAML_MAPPING_NODE) {
+ STACK_DEL(emitter, node.data.mapping.pairs);
+ }
+ }
+
+ STACK_DEL(emitter, emitter->document->nodes);
+ yaml_free(emitter->anchors);
+
+ emitter->anchors = NULL;
+ emitter->last_anchor_id = 0;
+ emitter->document = NULL;
+}
+
+/*
+ * Check the references of a node and assign the anchor id if needed.
+ */
+
+static void
+yaml_emitter_anchor_node(yaml_emitter_t *emitter, int index)
+{
+ yaml_node_t *node = emitter->document->nodes.start + index - 1;
+ yaml_node_item_t *item;
+ yaml_node_pair_t *pair;
+
+ emitter->anchors[index-1].references ++;
+
+ if (emitter->anchors[index-1].references == 1) {
+ switch (node->type) {
+ case YAML_SEQUENCE_NODE:
+ for (item = node->data.sequence.items.start;
+ item < node->data.sequence.items.top; item ++) {
+ yaml_emitter_anchor_node(emitter, *item);
+ }
+ break;
+ case YAML_MAPPING_NODE:
+ for (pair = node->data.mapping.pairs.start;
+ pair < node->data.mapping.pairs.top; pair ++) {
+ yaml_emitter_anchor_node(emitter, pair->key);
+ yaml_emitter_anchor_node(emitter, pair->value);
+ }
+ break;
+ default:
+ break;
+ }
+ }
+
+ else if (emitter->anchors[index-1].references == 2) {
+ emitter->anchors[index-1].anchor = (++ emitter->last_anchor_id);
+ }
+}
+
+/*
+ * Generate a textual representation for an anchor.
+ */
+
+#define ANCHOR_TEMPLATE "id%03d"
+#define ANCHOR_TEMPLATE_LENGTH 16
+
+static yaml_char_t *
+yaml_emitter_generate_anchor(yaml_emitter_t *emitter, int anchor_id)
+{
+ yaml_char_t *anchor = yaml_malloc(ANCHOR_TEMPLATE_LENGTH);
+
+ if (!anchor) return NULL;
+
+ sprintf((char *)anchor, ANCHOR_TEMPLATE, anchor_id);
+
+ return anchor;
+}
+
+/*
+ * Serialize a node.
+ */
+
+static int
+yaml_emitter_dump_node(yaml_emitter_t *emitter, int index)
+{
+ yaml_node_t *node = emitter->document->nodes.start + index - 1;
+ int anchor_id = emitter->anchors[index-1].anchor;
+ yaml_char_t *anchor = NULL;
+
+ if (anchor_id) {
+ anchor = yaml_emitter_generate_anchor(emitter, anchor_id);
+ if (!anchor) return 0;
+ }
+
+ if (emitter->anchors[index-1].serialized) {
+ return yaml_emitter_dump_alias(emitter, anchor);
+ }
+
+ emitter->anchors[index-1].serialized = 1;
+
+ switch (node->type) {
+ case YAML_SCALAR_NODE:
+ return yaml_emitter_dump_scalar(emitter, node, anchor);
+ case YAML_SEQUENCE_NODE:
+ return yaml_emitter_dump_sequence(emitter, node, anchor);
+ case YAML_MAPPING_NODE:
+ return yaml_emitter_dump_mapping(emitter, node, anchor);
+ default:
+ assert(0); /* Could not happen. */
+ break;
+ }
+
+ return 0; /* Could not happen. */
+}
+
+/*
+ * Serialize an alias.
+ */
+
+static int
+yaml_emitter_dump_alias(yaml_emitter_t *emitter, yaml_char_t *anchor)
+{
+ yaml_event_t event;
+ yaml_mark_t mark = { 0, 0, 0 };
+
+ ALIAS_EVENT_INIT(event, anchor, mark, mark);
+
+ return yaml_emitter_emit(emitter, &event);
+}
+
+/*
+ * Serialize a scalar.
+ */
+
+static int
+yaml_emitter_dump_scalar(yaml_emitter_t *emitter, yaml_node_t *node,
+ yaml_char_t *anchor)
+{
+ yaml_event_t event;
+ yaml_mark_t mark = { 0, 0, 0 };
+
+ int plain_implicit = (strcmp((char *)node->tag,
+ YAML_DEFAULT_SCALAR_TAG) == 0);
+ int quoted_implicit = (strcmp((char *)node->tag,
+ YAML_DEFAULT_SCALAR_TAG) == 0);
+
+ SCALAR_EVENT_INIT(event, anchor, node->tag, node->data.scalar.value,
+ node->data.scalar.length, plain_implicit, quoted_implicit,
+ node->data.scalar.style, mark, mark);
+
+ return yaml_emitter_emit(emitter, &event);
+}
+
+/*
+ * Serialize a sequence.
+ */
+
+static int
+yaml_emitter_dump_sequence(yaml_emitter_t *emitter, yaml_node_t *node,
+ yaml_char_t *anchor)
+{
+ yaml_event_t event;
+ yaml_mark_t mark = { 0, 0, 0 };
+
+ int implicit = (strcmp((char *)node->tag, YAML_DEFAULT_SEQUENCE_TAG) == 0);
+
+ yaml_node_item_t *item;
+
+ SEQUENCE_START_EVENT_INIT(event, anchor, node->tag, implicit,
+ node->data.sequence.style, mark, mark);
+ if (!yaml_emitter_emit(emitter, &event)) return 0;
+
+ for (item = node->data.sequence.items.start;
+ item < node->data.sequence.items.top; item ++) {
+ if (!yaml_emitter_dump_node(emitter, *item)) return 0;
+ }
+
+ SEQUENCE_END_EVENT_INIT(event, mark, mark);
+ if (!yaml_emitter_emit(emitter, &event)) return 0;
+
+ return 1;
+}
+
+/*
+ * Serialize a mapping.
+ */
+
+static int
+yaml_emitter_dump_mapping(yaml_emitter_t *emitter, yaml_node_t *node,
+ yaml_char_t *anchor)
+{
+ yaml_event_t event;
+ yaml_mark_t mark = { 0, 0, 0 };
+
+ int implicit = (strcmp((char *)node->tag, YAML_DEFAULT_MAPPING_TAG) == 0);
+
+ yaml_node_pair_t *pair;
+
+ MAPPING_START_EVENT_INIT(event, anchor, node->tag, implicit,
+ node->data.mapping.style, mark, mark);
+ if (!yaml_emitter_emit(emitter, &event)) return 0;
+
+ for (pair = node->data.mapping.pairs.start;
+ pair < node->data.mapping.pairs.top; pair ++) {
+ if (!yaml_emitter_dump_node(emitter, pair->key)) return 0;
+ if (!yaml_emitter_dump_node(emitter, pair->value)) return 0;
+ }
+
+ MAPPING_END_EVENT_INIT(event, mark, mark);
+ if (!yaml_emitter_emit(emitter, &event)) return 0;
+
+ return 1;
+}
+
diff --git a/contrib/libyaml/src/emitter.c b/contrib/libyaml/src/emitter.c
new file mode 100644
index 0000000..c4b56a2
--- /dev/null
+++ b/contrib/libyaml/src/emitter.c
@@ -0,0 +1,2329 @@
+
+#include "yaml_private.h"
+
+/*
+ * Flush the buffer if needed.
+ */
+
+#define FLUSH(emitter) \
+ ((emitter->buffer.pointer+5 < emitter->buffer.end) \
+ || yaml_emitter_flush(emitter))
+
+/*
+ * Put a character to the output buffer.
+ */
+
+#define PUT(emitter,value) \
+ (FLUSH(emitter) \
+ && (*(emitter->buffer.pointer++) = (yaml_char_t)(value), \
+ emitter->column ++, \
+ 1))
+
+/*
+ * Put a line break to the output buffer.
+ */
+
+#define PUT_BREAK(emitter) \
+ (FLUSH(emitter) \
+ && ((emitter->line_break == YAML_CR_BREAK ? \
+ (*(emitter->buffer.pointer++) = (yaml_char_t) '\r') : \
+ emitter->line_break == YAML_LN_BREAK ? \
+ (*(emitter->buffer.pointer++) = (yaml_char_t) '\n') : \
+ emitter->line_break == YAML_CRLN_BREAK ? \
+ (*(emitter->buffer.pointer++) = (yaml_char_t) '\r', \
+ *(emitter->buffer.pointer++) = (yaml_char_t) '\n') : 0), \
+ emitter->column = 0, \
+ emitter->line ++, \
+ 1))
+
+/*
+ * Copy a character from a string into buffer.
+ */
+
+#define WRITE(emitter,string) \
+ (FLUSH(emitter) \
+ && (COPY(emitter->buffer,string), \
+ emitter->column ++, \
+ 1))
+
+/*
+ * Copy a line break character from a string into buffer.
+ */
+
+#define WRITE_BREAK(emitter,string) \
+ (FLUSH(emitter) \
+ && (CHECK(string,'\n') ? \
+ (PUT_BREAK(emitter), \
+ string.pointer ++, \
+ 1) : \
+ (COPY(emitter->buffer,string), \
+ emitter->column = 0, \
+ emitter->line ++, \
+ 1)))
+
+/*
+ * API functions.
+ */
+
+YAML_DECLARE(int)
+yaml_emitter_emit(yaml_emitter_t *emitter, yaml_event_t *event);
+
+/*
+ * Utility functions.
+ */
+
+static int
+yaml_emitter_set_emitter_error(yaml_emitter_t *emitter, const char *problem);
+
+static int
+yaml_emitter_need_more_events(yaml_emitter_t *emitter);
+
+static int
+yaml_emitter_append_tag_directive(yaml_emitter_t *emitter,
+ yaml_tag_directive_t value, int allow_duplicates);
+
+static int
+yaml_emitter_increase_indent(yaml_emitter_t *emitter,
+ int flow, int indentless);
+
+/*
+ * State functions.
+ */
+
+static int
+yaml_emitter_state_machine(yaml_emitter_t *emitter, yaml_event_t *event);
+
+static int
+yaml_emitter_emit_stream_start(yaml_emitter_t *emitter,
+ yaml_event_t *event);
+
+static int
+yaml_emitter_emit_document_start(yaml_emitter_t *emitter,
+ yaml_event_t *event, int first);
+
+static int
+yaml_emitter_emit_document_content(yaml_emitter_t *emitter,
+ yaml_event_t *event);
+
+static int
+yaml_emitter_emit_document_end(yaml_emitter_t *emitter,
+ yaml_event_t *event);
+
+static int
+yaml_emitter_emit_flow_sequence_item(yaml_emitter_t *emitter,
+ yaml_event_t *event, int first);
+
+static int
+yaml_emitter_emit_flow_mapping_key(yaml_emitter_t *emitter,
+ yaml_event_t *event, int first);
+
+static int
+yaml_emitter_emit_flow_mapping_value(yaml_emitter_t *emitter,
+ yaml_event_t *event, int simple);
+
+static int
+yaml_emitter_emit_block_sequence_item(yaml_emitter_t *emitter,
+ yaml_event_t *event, int first);
+
+static int
+yaml_emitter_emit_block_mapping_key(yaml_emitter_t *emitter,
+ yaml_event_t *event, int first);
+
+static int
+yaml_emitter_emit_block_mapping_value(yaml_emitter_t *emitter,
+ yaml_event_t *event, int simple);
+
+static int
+yaml_emitter_emit_node(yaml_emitter_t *emitter, yaml_event_t *event,
+ int root, int sequence, int mapping, int simple_key);
+
+static int
+yaml_emitter_emit_alias(yaml_emitter_t *emitter, yaml_event_t *event);
+
+static int
+yaml_emitter_emit_scalar(yaml_emitter_t *emitter, yaml_event_t *event);
+
+static int
+yaml_emitter_emit_sequence_start(yaml_emitter_t *emitter, yaml_event_t *event);
+
+static int
+yaml_emitter_emit_mapping_start(yaml_emitter_t *emitter, yaml_event_t *event);
+
+/*
+ * Checkers.
+ */
+
+static int
+yaml_emitter_check_empty_document(yaml_emitter_t *emitter);
+
+static int
+yaml_emitter_check_empty_sequence(yaml_emitter_t *emitter);
+
+static int
+yaml_emitter_check_empty_mapping(yaml_emitter_t *emitter);
+
+static int
+yaml_emitter_check_simple_key(yaml_emitter_t *emitter);
+
+static int
+yaml_emitter_select_scalar_style(yaml_emitter_t *emitter, yaml_event_t *event);
+
+/*
+ * Processors.
+ */
+
+static int
+yaml_emitter_process_anchor(yaml_emitter_t *emitter);
+
+static int
+yaml_emitter_process_tag(yaml_emitter_t *emitter);
+
+static int
+yaml_emitter_process_scalar(yaml_emitter_t *emitter);
+
+/*
+ * Analyzers.
+ */
+
+static int
+yaml_emitter_analyze_version_directive(yaml_emitter_t *emitter,
+ yaml_version_directive_t version_directive);
+
+static int
+yaml_emitter_analyze_tag_directive(yaml_emitter_t *emitter,
+ yaml_tag_directive_t tag_directive);
+
+static int
+yaml_emitter_analyze_anchor(yaml_emitter_t *emitter,
+ yaml_char_t *anchor, int alias);
+
+static int
+yaml_emitter_analyze_tag(yaml_emitter_t *emitter,
+ yaml_char_t *tag);
+
+static int
+yaml_emitter_analyze_scalar(yaml_emitter_t *emitter,
+ yaml_char_t *value, size_t length);
+
+static int
+yaml_emitter_analyze_event(yaml_emitter_t *emitter,
+ yaml_event_t *event);
+
+/*
+ * Writers.
+ */
+
+static int
+yaml_emitter_write_bom(yaml_emitter_t *emitter);
+
+static int
+yaml_emitter_write_indent(yaml_emitter_t *emitter);
+
+static int
+yaml_emitter_write_indicator(yaml_emitter_t *emitter,
+ char *indicator, int need_whitespace,
+ int is_whitespace, int is_indention);
+
+static int
+yaml_emitter_write_anchor(yaml_emitter_t *emitter,
+ yaml_char_t *value, size_t length);
+
+static int
+yaml_emitter_write_tag_handle(yaml_emitter_t *emitter,
+ yaml_char_t *value, size_t length);
+
+static int
+yaml_emitter_write_tag_content(yaml_emitter_t *emitter,
+ yaml_char_t *value, size_t length, int need_whitespace);
+
+static int
+yaml_emitter_write_plain_scalar(yaml_emitter_t *emitter,
+ yaml_char_t *value, size_t length, int allow_breaks);
+
+static int
+yaml_emitter_write_single_quoted_scalar(yaml_emitter_t *emitter,
+ yaml_char_t *value, size_t length, int allow_breaks);
+
+static int
+yaml_emitter_write_double_quoted_scalar(yaml_emitter_t *emitter,
+ yaml_char_t *value, size_t length, int allow_breaks);
+
+static int
+yaml_emitter_write_block_scalar_hints(yaml_emitter_t *emitter,
+ yaml_string_t string);
+
+static int
+yaml_emitter_write_literal_scalar(yaml_emitter_t *emitter,
+ yaml_char_t *value, size_t length);
+
+static int
+yaml_emitter_write_folded_scalar(yaml_emitter_t *emitter,
+ yaml_char_t *value, size_t length);
+
+/*
+ * Set an emitter error and return 0.
+ */
+
+static int
+yaml_emitter_set_emitter_error(yaml_emitter_t *emitter, const char *problem)
+{
+ emitter->error = YAML_EMITTER_ERROR;
+ emitter->problem = problem;
+
+ return 0;
+}
+
+/*
+ * Emit an event.
+ */
+
+YAML_DECLARE(int)
+yaml_emitter_emit(yaml_emitter_t *emitter, yaml_event_t *event)
+{
+ if (!ENQUEUE(emitter, emitter->events, *event)) {
+ yaml_event_delete(event);
+ return 0;
+ }
+
+ while (!yaml_emitter_need_more_events(emitter)) {
+ if (!yaml_emitter_analyze_event(emitter, emitter->events.head))
+ return 0;
+ if (!yaml_emitter_state_machine(emitter, emitter->events.head))
+ return 0;
+ yaml_event_delete(&DEQUEUE(emitter, emitter->events));
+ }
+
+ return 1;
+}
+
+/*
+ * Check if we need to accumulate more events before emitting.
+ *
+ * We accumulate extra
+ * - 1 event for DOCUMENT-START
+ * - 2 events for SEQUENCE-START
+ * - 3 events for MAPPING-START
+ */
+
+static int
+yaml_emitter_need_more_events(yaml_emitter_t *emitter)
+{
+ int level = 0;
+ int accumulate = 0;
+ yaml_event_t *event;
+
+ if (QUEUE_EMPTY(emitter, emitter->events))
+ return 1;
+
+ switch (emitter->events.head->type) {
+ case YAML_DOCUMENT_START_EVENT:
+ accumulate = 1;
+ break;
+ case YAML_SEQUENCE_START_EVENT:
+ accumulate = 2;
+ break;
+ case YAML_MAPPING_START_EVENT:
+ accumulate = 3;
+ break;
+ default:
+ return 0;
+ }
+
+ if (emitter->events.tail - emitter->events.head > accumulate)
+ return 0;
+
+ for (event = emitter->events.head; event != emitter->events.tail; event ++) {
+ switch (event->type) {
+ case YAML_STREAM_START_EVENT:
+ case YAML_DOCUMENT_START_EVENT:
+ case YAML_SEQUENCE_START_EVENT:
+ case YAML_MAPPING_START_EVENT:
+ level += 1;
+ break;
+ case YAML_STREAM_END_EVENT:
+ case YAML_DOCUMENT_END_EVENT:
+ case YAML_SEQUENCE_END_EVENT:
+ case YAML_MAPPING_END_EVENT:
+ level -= 1;
+ break;
+ default:
+ break;
+ }
+ if (!level)
+ return 0;
+ }
+
+ return 1;
+}
+
+/*
+ * Append a directive to the directives stack.
+ */
+
+static int
+yaml_emitter_append_tag_directive(yaml_emitter_t *emitter,
+ yaml_tag_directive_t value, int allow_duplicates)
+{
+ yaml_tag_directive_t *tag_directive;
+ yaml_tag_directive_t copy = { NULL, NULL };
+
+ for (tag_directive = emitter->tag_directives.start;
+ tag_directive != emitter->tag_directives.top; tag_directive ++) {
+ if (strcmp((char *)value.handle, (char *)tag_directive->handle) == 0) {
+ if (allow_duplicates)
+ return 1;
+ return yaml_emitter_set_emitter_error(emitter,
+ "duplicate %TAG directive");
+ }
+ }
+
+ copy.handle = yaml_strdup(value.handle);
+ copy.prefix = yaml_strdup(value.prefix);
+ if (!copy.handle || !copy.prefix) {
+ emitter->error = YAML_MEMORY_ERROR;
+ goto error;
+ }
+
+ if (!PUSH(emitter, emitter->tag_directives, copy))
+ goto error;
+
+ return 1;
+
+error:
+ yaml_free(copy.handle);
+ yaml_free(copy.prefix);
+ return 0;
+}
+
+/*
+ * Increase the indentation level.
+ */
+
+static int
+yaml_emitter_increase_indent(yaml_emitter_t *emitter,
+ int flow, int indentless)
+{
+ if (!PUSH(emitter, emitter->indents, emitter->indent))
+ return 0;
+
+ if (emitter->indent < 0) {
+ emitter->indent = flow ? emitter->best_indent : 0;
+ }
+ else if (!indentless) {
+ emitter->indent += emitter->best_indent;
+ }
+
+ return 1;
+}
+
+/*
+ * State dispatcher.
+ */
+
+static int
+yaml_emitter_state_machine(yaml_emitter_t *emitter, yaml_event_t *event)
+{
+ switch (emitter->state)
+ {
+ case YAML_EMIT_STREAM_START_STATE:
+ return yaml_emitter_emit_stream_start(emitter, event);
+
+ case YAML_EMIT_FIRST_DOCUMENT_START_STATE:
+ return yaml_emitter_emit_document_start(emitter, event, 1);
+
+ case YAML_EMIT_DOCUMENT_START_STATE:
+ return yaml_emitter_emit_document_start(emitter, event, 0);
+
+ case YAML_EMIT_DOCUMENT_CONTENT_STATE:
+ return yaml_emitter_emit_document_content(emitter, event);
+
+ case YAML_EMIT_DOCUMENT_END_STATE:
+ return yaml_emitter_emit_document_end(emitter, event);
+
+ case YAML_EMIT_FLOW_SEQUENCE_FIRST_ITEM_STATE:
+ return yaml_emitter_emit_flow_sequence_item(emitter, event, 1);
+
+ case YAML_EMIT_FLOW_SEQUENCE_ITEM_STATE:
+ return yaml_emitter_emit_flow_sequence_item(emitter, event, 0);
+
+ case YAML_EMIT_FLOW_MAPPING_FIRST_KEY_STATE:
+ return yaml_emitter_emit_flow_mapping_key(emitter, event, 1);
+
+ case YAML_EMIT_FLOW_MAPPING_KEY_STATE:
+ return yaml_emitter_emit_flow_mapping_key(emitter, event, 0);
+
+ case YAML_EMIT_FLOW_MAPPING_SIMPLE_VALUE_STATE:
+ return yaml_emitter_emit_flow_mapping_value(emitter, event, 1);
+
+ case YAML_EMIT_FLOW_MAPPING_VALUE_STATE:
+ return yaml_emitter_emit_flow_mapping_value(emitter, event, 0);
+
+ case YAML_EMIT_BLOCK_SEQUENCE_FIRST_ITEM_STATE:
+ return yaml_emitter_emit_block_sequence_item(emitter, event, 1);
+
+ case YAML_EMIT_BLOCK_SEQUENCE_ITEM_STATE:
+ return yaml_emitter_emit_block_sequence_item(emitter, event, 0);
+
+ case YAML_EMIT_BLOCK_MAPPING_FIRST_KEY_STATE:
+ return yaml_emitter_emit_block_mapping_key(emitter, event, 1);
+
+ case YAML_EMIT_BLOCK_MAPPING_KEY_STATE:
+ return yaml_emitter_emit_block_mapping_key(emitter, event, 0);
+
+ case YAML_EMIT_BLOCK_MAPPING_SIMPLE_VALUE_STATE:
+ return yaml_emitter_emit_block_mapping_value(emitter, event, 1);
+
+ case YAML_EMIT_BLOCK_MAPPING_VALUE_STATE:
+ return yaml_emitter_emit_block_mapping_value(emitter, event, 0);
+
+ case YAML_EMIT_END_STATE:
+ return yaml_emitter_set_emitter_error(emitter,
+ "expected nothing after STREAM-END");
+
+ default:
+ assert(1); /* Invalid state. */
+ }
+
+ return 0;
+}
+
+/*
+ * Expect STREAM-START.
+ */
+
+static int
+yaml_emitter_emit_stream_start(yaml_emitter_t *emitter,
+ yaml_event_t *event)
+{
+ if (event->type == YAML_STREAM_START_EVENT)
+ {
+ if (!emitter->encoding) {
+ emitter->encoding = event->data.stream_start.encoding;
+ }
+
+ if (!emitter->encoding) {
+ emitter->encoding = YAML_UTF8_ENCODING;
+ }
+
+ if (emitter->best_indent < 2 || emitter->best_indent > 9) {
+ emitter->best_indent = 2;
+ }
+
+ if (emitter->best_width >= 0
+ && emitter->best_width <= emitter->best_indent*2) {
+ emitter->best_width = 80;
+ }
+
+ if (emitter->best_width < 0) {
+ emitter->best_width = INT_MAX;
+ }
+
+ if (!emitter->line_break) {
+ emitter->line_break = YAML_LN_BREAK;
+ }
+
+ emitter->indent = -1;
+
+ emitter->line = 0;
+ emitter->column = 0;
+ emitter->whitespace = 1;
+ emitter->indention = 1;
+
+ if (emitter->encoding != YAML_UTF8_ENCODING) {
+ if (!yaml_emitter_write_bom(emitter))
+ return 0;
+ }
+
+ emitter->state = YAML_EMIT_FIRST_DOCUMENT_START_STATE;
+
+ return 1;
+ }
+
+ return yaml_emitter_set_emitter_error(emitter,
+ "expected STREAM-START");
+}
+
+/*
+ * Expect DOCUMENT-START or STREAM-END.
+ */
+
+static int
+yaml_emitter_emit_document_start(yaml_emitter_t *emitter,
+ yaml_event_t *event, int first)
+{
+ if (event->type == YAML_DOCUMENT_START_EVENT)
+ {
+ yaml_tag_directive_t default_tag_directives[] = {
+ {(yaml_char_t *)"!", (yaml_char_t *)"!"},
+ {(yaml_char_t *)"!!", (yaml_char_t *)"tag:yaml.org,2002:"},
+ {NULL, NULL}
+ };
+ yaml_tag_directive_t *tag_directive;
+ int implicit;
+
+ if (event->data.document_start.version_directive) {
+ if (!yaml_emitter_analyze_version_directive(emitter,
+ *event->data.document_start.version_directive))
+ return 0;
+ }
+
+ for (tag_directive = event->data.document_start.tag_directives.start;
+ tag_directive != event->data.document_start.tag_directives.end;
+ tag_directive ++) {
+ if (!yaml_emitter_analyze_tag_directive(emitter, *tag_directive))
+ return 0;
+ if (!yaml_emitter_append_tag_directive(emitter, *tag_directive, 0))
+ return 0;
+ }
+
+ for (tag_directive = default_tag_directives;
+ tag_directive->handle; tag_directive ++) {
+ if (!yaml_emitter_append_tag_directive(emitter, *tag_directive, 1))
+ return 0;
+ }
+
+ implicit = event->data.document_start.implicit;
+ if (!first || emitter->canonical) {
+ implicit = 0;
+ }
+
+ if ((event->data.document_start.version_directive ||
+ (event->data.document_start.tag_directives.start
+ != event->data.document_start.tag_directives.end)) &&
+ emitter->open_ended)
+ {
+ if (!yaml_emitter_write_indicator(emitter, "...", 1, 0, 0))
+ return 0;
+ if (!yaml_emitter_write_indent(emitter))
+ return 0;
+ }
+
+ if (event->data.document_start.version_directive) {
+ implicit = 0;
+ if (!yaml_emitter_write_indicator(emitter, "%YAML", 1, 0, 0))
+ return 0;
+ if (!yaml_emitter_write_indicator(emitter, "1.1", 1, 0, 0))
+ return 0;
+ if (!yaml_emitter_write_indent(emitter))
+ return 0;
+ }
+
+ if (event->data.document_start.tag_directives.start
+ != event->data.document_start.tag_directives.end) {
+ implicit = 0;
+ for (tag_directive = event->data.document_start.tag_directives.start;
+ tag_directive != event->data.document_start.tag_directives.end;
+ tag_directive ++) {
+ if (!yaml_emitter_write_indicator(emitter, "%TAG", 1, 0, 0))
+ return 0;
+ if (!yaml_emitter_write_tag_handle(emitter, tag_directive->handle,
+ strlen((char *)tag_directive->handle)))
+ return 0;
+ if (!yaml_emitter_write_tag_content(emitter, tag_directive->prefix,
+ strlen((char *)tag_directive->prefix), 1))
+ return 0;
+ if (!yaml_emitter_write_indent(emitter))
+ return 0;
+ }
+ }
+
+ if (yaml_emitter_check_empty_document(emitter)) {
+ implicit = 0;
+ }
+
+ if (!implicit) {
+ if (!yaml_emitter_write_indent(emitter))
+ return 0;
+ if (!yaml_emitter_write_indicator(emitter, "---", 1, 0, 0))
+ return 0;
+ if (emitter->canonical) {
+ if (!yaml_emitter_write_indent(emitter))
+ return 0;
+ }
+ }
+
+ emitter->state = YAML_EMIT_DOCUMENT_CONTENT_STATE;
+
+ return 1;
+ }
+
+ else if (event->type == YAML_STREAM_END_EVENT)
+ {
+ if (emitter->open_ended)
+ {
+ if (!yaml_emitter_write_indicator(emitter, "...", 1, 0, 0))
+ return 0;
+ if (!yaml_emitter_write_indent(emitter))
+ return 0;
+ }
+
+ if (!yaml_emitter_flush(emitter))
+ return 0;
+
+ emitter->state = YAML_EMIT_END_STATE;
+
+ return 1;
+ }
+
+ return yaml_emitter_set_emitter_error(emitter,
+ "expected DOCUMENT-START or STREAM-END");
+}
+
+/*
+ * Expect the root node.
+ */
+
+static int
+yaml_emitter_emit_document_content(yaml_emitter_t *emitter,
+ yaml_event_t *event)
+{
+ if (!PUSH(emitter, emitter->states, YAML_EMIT_DOCUMENT_END_STATE))
+ return 0;
+
+ return yaml_emitter_emit_node(emitter, event, 1, 0, 0, 0);
+}
+
+/*
+ * Expect DOCUMENT-END.
+ */
+
+static int
+yaml_emitter_emit_document_end(yaml_emitter_t *emitter,
+ yaml_event_t *event)
+{
+ if (event->type == YAML_DOCUMENT_END_EVENT)
+ {
+ if (!yaml_emitter_write_indent(emitter))
+ return 0;
+ if (!event->data.document_end.implicit) {
+ if (!yaml_emitter_write_indicator(emitter, "...", 1, 0, 0))
+ return 0;
+ if (!yaml_emitter_write_indent(emitter))
+ return 0;
+ }
+ if (!yaml_emitter_flush(emitter))
+ return 0;
+
+ emitter->state = YAML_EMIT_DOCUMENT_START_STATE;
+
+ while (!STACK_EMPTY(emitter, emitter->tag_directives)) {
+ yaml_tag_directive_t tag_directive = POP(emitter,
+ emitter->tag_directives);
+ yaml_free(tag_directive.handle);
+ yaml_free(tag_directive.prefix);
+ }
+
+ return 1;
+ }
+
+ return yaml_emitter_set_emitter_error(emitter,
+ "expected DOCUMENT-END");
+}
+
+/*
+ *
+ * Expect a flow item node.
+ */
+
+static int
+yaml_emitter_emit_flow_sequence_item(yaml_emitter_t *emitter,
+ yaml_event_t *event, int first)
+{
+ if (first)
+ {
+ if (!yaml_emitter_write_indicator(emitter, "[", 1, 1, 0))
+ return 0;
+ if (!yaml_emitter_increase_indent(emitter, 1, 0))
+ return 0;
+ emitter->flow_level ++;
+ }
+
+ if (event->type == YAML_SEQUENCE_END_EVENT)
+ {
+ emitter->flow_level --;
+ emitter->indent = POP(emitter, emitter->indents);
+ if (emitter->canonical && !first) {
+ if (!yaml_emitter_write_indicator(emitter, ",", 0, 0, 0))
+ return 0;
+ if (!yaml_emitter_write_indent(emitter))
+ return 0;
+ }
+ if (!yaml_emitter_write_indicator(emitter, "]", 0, 0, 0))
+ return 0;
+ emitter->state = POP(emitter, emitter->states);
+
+ return 1;
+ }
+
+ if (!first) {
+ if (!yaml_emitter_write_indicator(emitter, ",", 0, 0, 0))
+ return 0;
+ }
+
+ if (emitter->canonical || emitter->column > emitter->best_width) {
+ if (!yaml_emitter_write_indent(emitter))
+ return 0;
+ }
+ if (!PUSH(emitter, emitter->states, YAML_EMIT_FLOW_SEQUENCE_ITEM_STATE))
+ return 0;
+
+ return yaml_emitter_emit_node(emitter, event, 0, 1, 0, 0);
+}
+
+/*
+ * Expect a flow key node.
+ */
+
+static int
+yaml_emitter_emit_flow_mapping_key(yaml_emitter_t *emitter,
+ yaml_event_t *event, int first)
+{
+ if (first)
+ {
+ if (!yaml_emitter_write_indicator(emitter, "{", 1, 1, 0))
+ return 0;
+ if (!yaml_emitter_increase_indent(emitter, 1, 0))
+ return 0;
+ emitter->flow_level ++;
+ }
+
+ if (event->type == YAML_MAPPING_END_EVENT)
+ {
+ emitter->flow_level --;
+ emitter->indent = POP(emitter, emitter->indents);
+ if (emitter->canonical && !first) {
+ if (!yaml_emitter_write_indicator(emitter, ",", 0, 0, 0))
+ return 0;
+ if (!yaml_emitter_write_indent(emitter))
+ return 0;
+ }
+ if (!yaml_emitter_write_indicator(emitter, "}", 0, 0, 0))
+ return 0;
+ emitter->state = POP(emitter, emitter->states);
+
+ return 1;
+ }
+
+ if (!first) {
+ if (!yaml_emitter_write_indicator(emitter, ",", 0, 0, 0))
+ return 0;
+ }
+ if (emitter->canonical || emitter->column > emitter->best_width) {
+ if (!yaml_emitter_write_indent(emitter))
+ return 0;
+ }
+
+ if (!emitter->canonical && yaml_emitter_check_simple_key(emitter))
+ {
+ if (!PUSH(emitter, emitter->states,
+ YAML_EMIT_FLOW_MAPPING_SIMPLE_VALUE_STATE))
+ return 0;
+
+ return yaml_emitter_emit_node(emitter, event, 0, 0, 1, 1);
+ }
+ else
+ {
+ if (!yaml_emitter_write_indicator(emitter, "?", 1, 0, 0))
+ return 0;
+ if (!PUSH(emitter, emitter->states,
+ YAML_EMIT_FLOW_MAPPING_VALUE_STATE))
+ return 0;
+
+ return yaml_emitter_emit_node(emitter, event, 0, 0, 1, 0);
+ }
+}
+
+/*
+ * Expect a flow value node.
+ */
+
+static int
+yaml_emitter_emit_flow_mapping_value(yaml_emitter_t *emitter,
+ yaml_event_t *event, int simple)
+{
+ if (simple) {
+ if (!yaml_emitter_write_indicator(emitter, ":", 0, 0, 0))
+ return 0;
+ }
+ else {
+ if (emitter->canonical || emitter->column > emitter->best_width) {
+ if (!yaml_emitter_write_indent(emitter))
+ return 0;
+ }
+ if (!yaml_emitter_write_indicator(emitter, ":", 1, 0, 0))
+ return 0;
+ }
+ if (!PUSH(emitter, emitter->states, YAML_EMIT_FLOW_MAPPING_KEY_STATE))
+ return 0;
+ return yaml_emitter_emit_node(emitter, event, 0, 0, 1, 0);
+}
+
+/*
+ * Expect a block item node.
+ */
+
+static int
+yaml_emitter_emit_block_sequence_item(yaml_emitter_t *emitter,
+ yaml_event_t *event, int first)
+{
+ if (first)
+ {
+ if (!yaml_emitter_increase_indent(emitter, 0,
+ (emitter->mapping_context && !emitter->indention)))
+ return 0;
+ }
+
+ if (event->type == YAML_SEQUENCE_END_EVENT)
+ {
+ emitter->indent = POP(emitter, emitter->indents);
+ emitter->state = POP(emitter, emitter->states);
+
+ return 1;
+ }
+
+ if (!yaml_emitter_write_indent(emitter))
+ return 0;
+ if (!yaml_emitter_write_indicator(emitter, "-", 1, 0, 1))
+ return 0;
+ if (!PUSH(emitter, emitter->states,
+ YAML_EMIT_BLOCK_SEQUENCE_ITEM_STATE))
+ return 0;
+
+ return yaml_emitter_emit_node(emitter, event, 0, 1, 0, 0);
+}
+
+/*
+ * Expect a block key node.
+ */
+
+static int
+yaml_emitter_emit_block_mapping_key(yaml_emitter_t *emitter,
+ yaml_event_t *event, int first)
+{
+ if (first)
+ {
+ if (!yaml_emitter_increase_indent(emitter, 0, 0))
+ return 0;
+ }
+
+ if (event->type == YAML_MAPPING_END_EVENT)
+ {
+ emitter->indent = POP(emitter, emitter->indents);
+ emitter->state = POP(emitter, emitter->states);
+
+ return 1;
+ }
+
+ if (!yaml_emitter_write_indent(emitter))
+ return 0;
+
+ if (yaml_emitter_check_simple_key(emitter))
+ {
+ if (!PUSH(emitter, emitter->states,
+ YAML_EMIT_BLOCK_MAPPING_SIMPLE_VALUE_STATE))
+ return 0;
+
+ return yaml_emitter_emit_node(emitter, event, 0, 0, 1, 1);
+ }
+ else
+ {
+ if (!yaml_emitter_write_indicator(emitter, "?", 1, 0, 1))
+ return 0;
+ if (!PUSH(emitter, emitter->states,
+ YAML_EMIT_BLOCK_MAPPING_VALUE_STATE))
+ return 0;
+
+ return yaml_emitter_emit_node(emitter, event, 0, 0, 1, 0);
+ }
+}
+
+/*
+ * Expect a block value node.
+ */
+
+static int
+yaml_emitter_emit_block_mapping_value(yaml_emitter_t *emitter,
+ yaml_event_t *event, int simple)
+{
+ if (simple) {
+ if (!yaml_emitter_write_indicator(emitter, ":", 0, 0, 0))
+ return 0;
+ }
+ else {
+ if (!yaml_emitter_write_indent(emitter))
+ return 0;
+ if (!yaml_emitter_write_indicator(emitter, ":", 1, 0, 1))
+ return 0;
+ }
+ if (!PUSH(emitter, emitter->states,
+ YAML_EMIT_BLOCK_MAPPING_KEY_STATE))
+ return 0;
+
+ return yaml_emitter_emit_node(emitter, event, 0, 0, 1, 0);
+}
+
+/*
+ * Expect a node.
+ */
+
+static int
+yaml_emitter_emit_node(yaml_emitter_t *emitter, yaml_event_t *event,
+ int root, int sequence, int mapping, int simple_key)
+{
+ emitter->root_context = root;
+ emitter->sequence_context = sequence;
+ emitter->mapping_context = mapping;
+ emitter->simple_key_context = simple_key;
+
+ switch (event->type)
+ {
+ case YAML_ALIAS_EVENT:
+ return yaml_emitter_emit_alias(emitter, event);
+
+ case YAML_SCALAR_EVENT:
+ return yaml_emitter_emit_scalar(emitter, event);
+
+ case YAML_SEQUENCE_START_EVENT:
+ return yaml_emitter_emit_sequence_start(emitter, event);
+
+ case YAML_MAPPING_START_EVENT:
+ return yaml_emitter_emit_mapping_start(emitter, event);
+
+ default:
+ return yaml_emitter_set_emitter_error(emitter,
+ "expected SCALAR, SEQUENCE-START, MAPPING-START, or ALIAS");
+ }
+
+ return 0;
+}
+
+/*
+ * Expect ALIAS.
+ */
+
+static int
+yaml_emitter_emit_alias(yaml_emitter_t *emitter, yaml_event_t *event)
+{
+ if (!yaml_emitter_process_anchor(emitter))
+ return 0;
+ emitter->state = POP(emitter, emitter->states);
+
+ return 1;
+}
+
+/*
+ * Expect SCALAR.
+ */
+
+static int
+yaml_emitter_emit_scalar(yaml_emitter_t *emitter, yaml_event_t *event)
+{
+ if (!yaml_emitter_select_scalar_style(emitter, event))
+ return 0;
+ if (!yaml_emitter_process_anchor(emitter))
+ return 0;
+ if (!yaml_emitter_process_tag(emitter))
+ return 0;
+ if (!yaml_emitter_increase_indent(emitter, 1, 0))
+ return 0;
+ if (!yaml_emitter_process_scalar(emitter))
+ return 0;
+ emitter->indent = POP(emitter, emitter->indents);
+ emitter->state = POP(emitter, emitter->states);
+
+ return 1;
+}
+
+/*
+ * Expect SEQUENCE-START.
+ */
+
+static int
+yaml_emitter_emit_sequence_start(yaml_emitter_t *emitter, yaml_event_t *event)
+{
+ if (!yaml_emitter_process_anchor(emitter))
+ return 0;
+ if (!yaml_emitter_process_tag(emitter))
+ return 0;
+
+ if (emitter->flow_level || emitter->canonical
+ || event->data.sequence_start.style == YAML_FLOW_SEQUENCE_STYLE
+ || yaml_emitter_check_empty_sequence(emitter)) {
+ emitter->state = YAML_EMIT_FLOW_SEQUENCE_FIRST_ITEM_STATE;
+ }
+ else {
+ emitter->state = YAML_EMIT_BLOCK_SEQUENCE_FIRST_ITEM_STATE;
+ }
+
+ return 1;
+}
+
+/*
+ * Expect MAPPING-START.
+ */
+
+static int
+yaml_emitter_emit_mapping_start(yaml_emitter_t *emitter, yaml_event_t *event)
+{
+ if (!yaml_emitter_process_anchor(emitter))
+ return 0;
+ if (!yaml_emitter_process_tag(emitter))
+ return 0;
+
+ if (emitter->flow_level || emitter->canonical
+ || event->data.mapping_start.style == YAML_FLOW_MAPPING_STYLE
+ || yaml_emitter_check_empty_mapping(emitter)) {
+ emitter->state = YAML_EMIT_FLOW_MAPPING_FIRST_KEY_STATE;
+ }
+ else {
+ emitter->state = YAML_EMIT_BLOCK_MAPPING_FIRST_KEY_STATE;
+ }
+
+ return 1;
+}
+
+/*
+ * Check if the document content is an empty scalar.
+ */
+
+static int
+yaml_emitter_check_empty_document(yaml_emitter_t *emitter)
+{
+ return 0;
+}
+
+/*
+ * Check if the next events represent an empty sequence.
+ */
+
+static int
+yaml_emitter_check_empty_sequence(yaml_emitter_t *emitter)
+{
+ if (emitter->events.tail - emitter->events.head < 2)
+ return 0;
+
+ return (emitter->events.head[0].type == YAML_SEQUENCE_START_EVENT
+ && emitter->events.head[1].type == YAML_SEQUENCE_END_EVENT);
+}
+
+/*
+ * Check if the next events represent an empty mapping.
+ */
+
+static int
+yaml_emitter_check_empty_mapping(yaml_emitter_t *emitter)
+{
+ if (emitter->events.tail - emitter->events.head < 2)
+ return 0;
+
+ return (emitter->events.head[0].type == YAML_MAPPING_START_EVENT
+ && emitter->events.head[1].type == YAML_MAPPING_END_EVENT);
+}
+
+/*
+ * Check if the next node can be expressed as a simple key.
+ */
+
+static int
+yaml_emitter_check_simple_key(yaml_emitter_t *emitter)
+{
+ yaml_event_t *event = emitter->events.head;
+ size_t length = 0;
+
+ switch (event->type)
+ {
+ case YAML_ALIAS_EVENT:
+ length += emitter->anchor_data.anchor_length;
+ break;
+
+ case YAML_SCALAR_EVENT:
+ if (emitter->scalar_data.multiline)
+ return 0;
+ length += emitter->anchor_data.anchor_length
+ + emitter->tag_data.handle_length
+ + emitter->tag_data.suffix_length
+ + emitter->scalar_data.length;
+ break;
+
+ case YAML_SEQUENCE_START_EVENT:
+ if (!yaml_emitter_check_empty_sequence(emitter))
+ return 0;
+ length += emitter->anchor_data.anchor_length
+ + emitter->tag_data.handle_length
+ + emitter->tag_data.suffix_length;
+ break;
+
+ case YAML_MAPPING_START_EVENT:
+ if (!yaml_emitter_check_empty_mapping(emitter))
+ return 0;
+ length += emitter->anchor_data.anchor_length
+ + emitter->tag_data.handle_length
+ + emitter->tag_data.suffix_length;
+ break;
+
+ default:
+ return 0;
+ }
+
+ if (length > 128)
+ return 0;
+
+ return 1;
+}
+
+/*
+ * Determine an acceptable scalar style.
+ */
+
+static int
+yaml_emitter_select_scalar_style(yaml_emitter_t *emitter, yaml_event_t *event)
+{
+ yaml_scalar_style_t style = event->data.scalar.style;
+ int no_tag = (!emitter->tag_data.handle && !emitter->tag_data.suffix);
+
+ if (no_tag && !event->data.scalar.plain_implicit
+ && !event->data.scalar.quoted_implicit) {
+ return yaml_emitter_set_emitter_error(emitter,
+ "neither tag nor implicit flags are specified");
+ }
+
+ if (style == YAML_ANY_SCALAR_STYLE)
+ style = YAML_PLAIN_SCALAR_STYLE;
+
+ if (emitter->canonical)
+ style = YAML_DOUBLE_QUOTED_SCALAR_STYLE;
+
+ if (emitter->simple_key_context && emitter->scalar_data.multiline)
+ style = YAML_DOUBLE_QUOTED_SCALAR_STYLE;
+
+ if (style == YAML_PLAIN_SCALAR_STYLE)
+ {
+ if ((emitter->flow_level && !emitter->scalar_data.flow_plain_allowed)
+ || (!emitter->flow_level && !emitter->scalar_data.block_plain_allowed))
+ style = YAML_SINGLE_QUOTED_SCALAR_STYLE;
+ if (!emitter->scalar_data.length
+ && (emitter->flow_level || emitter->simple_key_context))
+ style = YAML_SINGLE_QUOTED_SCALAR_STYLE;
+ if (no_tag && !event->data.scalar.plain_implicit)
+ style = YAML_SINGLE_QUOTED_SCALAR_STYLE;
+ }
+
+ if (style == YAML_SINGLE_QUOTED_SCALAR_STYLE)
+ {
+ if (!emitter->scalar_data.single_quoted_allowed)
+ style = YAML_DOUBLE_QUOTED_SCALAR_STYLE;
+ }
+
+ if (style == YAML_LITERAL_SCALAR_STYLE || style == YAML_FOLDED_SCALAR_STYLE)
+ {
+ if (!emitter->scalar_data.block_allowed
+ || emitter->flow_level || emitter->simple_key_context)
+ style = YAML_DOUBLE_QUOTED_SCALAR_STYLE;
+ }
+
+ if (no_tag && !event->data.scalar.quoted_implicit
+ && style != YAML_PLAIN_SCALAR_STYLE)
+ {
+ emitter->tag_data.handle = (yaml_char_t *)"!";
+ emitter->tag_data.handle_length = 1;
+ }
+
+ emitter->scalar_data.style = style;
+
+ return 1;
+}
+
+/*
+ * Write an achor.
+ */
+
+static int
+yaml_emitter_process_anchor(yaml_emitter_t *emitter)
+{
+ if (!emitter->anchor_data.anchor)
+ return 1;
+
+ if (!yaml_emitter_write_indicator(emitter,
+ (emitter->anchor_data.alias ? "*" : "&"), 1, 0, 0))
+ return 0;
+
+ return yaml_emitter_write_anchor(emitter,
+ emitter->anchor_data.anchor, emitter->anchor_data.anchor_length);
+}
+
+/*
+ * Write a tag.
+ */
+
+static int
+yaml_emitter_process_tag(yaml_emitter_t *emitter)
+{
+ if (!emitter->tag_data.handle && !emitter->tag_data.suffix)
+ return 1;
+
+ if (emitter->tag_data.handle)
+ {
+ if (!yaml_emitter_write_tag_handle(emitter, emitter->tag_data.handle,
+ emitter->tag_data.handle_length))
+ return 0;
+ if (emitter->tag_data.suffix) {
+ if (!yaml_emitter_write_tag_content(emitter, emitter->tag_data.suffix,
+ emitter->tag_data.suffix_length, 0))
+ return 0;
+ }
+ }
+ else
+ {
+ if (!yaml_emitter_write_indicator(emitter, "!<", 1, 0, 0))
+ return 0;
+ if (!yaml_emitter_write_tag_content(emitter, emitter->tag_data.suffix,
+ emitter->tag_data.suffix_length, 0))
+ return 0;
+ if (!yaml_emitter_write_indicator(emitter, ">", 0, 0, 0))
+ return 0;
+ }
+
+ return 1;
+}
+
+/*
+ * Write a scalar.
+ */
+
+static int
+yaml_emitter_process_scalar(yaml_emitter_t *emitter)
+{
+ switch (emitter->scalar_data.style)
+ {
+ case YAML_PLAIN_SCALAR_STYLE:
+ return yaml_emitter_write_plain_scalar(emitter,
+ emitter->scalar_data.value, emitter->scalar_data.length,
+ !emitter->simple_key_context);
+
+ case YAML_SINGLE_QUOTED_SCALAR_STYLE:
+ return yaml_emitter_write_single_quoted_scalar(emitter,
+ emitter->scalar_data.value, emitter->scalar_data.length,
+ !emitter->simple_key_context);
+
+ case YAML_DOUBLE_QUOTED_SCALAR_STYLE:
+ return yaml_emitter_write_double_quoted_scalar(emitter,
+ emitter->scalar_data.value, emitter->scalar_data.length,
+ !emitter->simple_key_context);
+
+ case YAML_LITERAL_SCALAR_STYLE:
+ return yaml_emitter_write_literal_scalar(emitter,
+ emitter->scalar_data.value, emitter->scalar_data.length);
+
+ case YAML_FOLDED_SCALAR_STYLE:
+ return yaml_emitter_write_folded_scalar(emitter,
+ emitter->scalar_data.value, emitter->scalar_data.length);
+
+ default:
+ assert(1); /* Impossible. */
+ }
+
+ return 0;
+}
+
+/*
+ * Check if a %YAML directive is valid.
+ */
+
+static int
+yaml_emitter_analyze_version_directive(yaml_emitter_t *emitter,
+ yaml_version_directive_t version_directive)
+{
+ if (version_directive.major != 1 || version_directive.minor != 1) {
+ return yaml_emitter_set_emitter_error(emitter,
+ "incompatible %YAML directive");
+ }
+
+ return 1;
+}
+
+/*
+ * Check if a %TAG directive is valid.
+ */
+
+static int
+yaml_emitter_analyze_tag_directive(yaml_emitter_t *emitter,
+ yaml_tag_directive_t tag_directive)
+{
+ yaml_string_t handle;
+ yaml_string_t prefix;
+ size_t handle_length;
+ size_t prefix_length;
+
+ handle_length = strlen((char *)tag_directive.handle);
+ prefix_length = strlen((char *)tag_directive.prefix);
+ STRING_ASSIGN(handle, tag_directive.handle, handle_length);
+ STRING_ASSIGN(prefix, tag_directive.prefix, prefix_length);
+
+ if (handle.start == handle.end) {
+ return yaml_emitter_set_emitter_error(emitter,
+ "tag handle must not be empty");
+ }
+
+ if (handle.start[0] != '!') {
+ return yaml_emitter_set_emitter_error(emitter,
+ "tag handle must start with '!'");
+ }
+
+ if (handle.end[-1] != '!') {
+ return yaml_emitter_set_emitter_error(emitter,
+ "tag handle must end with '!'");
+ }
+
+ handle.pointer ++;
+
+ while (handle.pointer < handle.end-1) {
+ if (!IS_ALPHA(handle)) {
+ return yaml_emitter_set_emitter_error(emitter,
+ "tag handle must contain alphanumerical characters only");
+ }
+ MOVE(handle);
+ }
+
+ if (prefix.start == prefix.end) {
+ return yaml_emitter_set_emitter_error(emitter,
+ "tag prefix must not be empty");
+ }
+
+ return 1;
+}
+
+/*
+ * Check if an anchor is valid.
+ */
+
+static int
+yaml_emitter_analyze_anchor(yaml_emitter_t *emitter,
+ yaml_char_t *anchor, int alias)
+{
+ size_t anchor_length;
+ yaml_string_t string;
+
+ anchor_length = strlen((char *)anchor);
+ STRING_ASSIGN(string, anchor, anchor_length);
+
+ if (string.start == string.end) {
+ return yaml_emitter_set_emitter_error(emitter, alias ?
+ "alias value must not be empty" :
+ "anchor value must not be empty");
+ }
+
+ while (string.pointer != string.end) {
+ if (!IS_ALPHA(string)) {
+ return yaml_emitter_set_emitter_error(emitter, alias ?
+ "alias value must contain alphanumerical characters only" :
+ "anchor value must contain alphanumerical characters only");
+ }
+ MOVE(string);
+ }
+
+ emitter->anchor_data.anchor = string.start;
+ emitter->anchor_data.anchor_length = string.end - string.start;
+ emitter->anchor_data.alias = alias;
+
+ return 1;
+}
+
+/*
+ * Check if a tag is valid.
+ */
+
+static int
+yaml_emitter_analyze_tag(yaml_emitter_t *emitter,
+ yaml_char_t *tag)
+{
+ size_t tag_length;
+ yaml_string_t string;
+ yaml_tag_directive_t *tag_directive;
+
+ tag_length = strlen((char *)tag);
+ STRING_ASSIGN(string, tag, tag_length);
+
+ if (string.start == string.end) {
+ return yaml_emitter_set_emitter_error(emitter,
+ "tag value must not be empty");
+ }
+
+ for (tag_directive = emitter->tag_directives.start;
+ tag_directive != emitter->tag_directives.top; tag_directive ++) {
+ size_t prefix_length = strlen((char *)tag_directive->prefix);
+ if (prefix_length < (size_t)(string.end - string.start)
+ && strncmp((char *)tag_directive->prefix, (char *)string.start,
+ prefix_length) == 0)
+ {
+ emitter->tag_data.handle = tag_directive->handle;
+ emitter->tag_data.handle_length =
+ strlen((char *)tag_directive->handle);
+ emitter->tag_data.suffix = string.start + prefix_length;
+ emitter->tag_data.suffix_length =
+ (string.end - string.start) - prefix_length;
+ return 1;
+ }
+ }
+
+ emitter->tag_data.suffix = string.start;
+ emitter->tag_data.suffix_length = string.end - string.start;
+
+ return 1;
+}
+
+/*
+ * Check if a scalar is valid.
+ */
+
+static int
+yaml_emitter_analyze_scalar(yaml_emitter_t *emitter,
+ yaml_char_t *value, size_t length)
+{
+ yaml_string_t string;
+
+ int block_indicators = 0;
+ int flow_indicators = 0;
+ int line_breaks = 0;
+ int special_characters = 0;
+
+ int leading_space = 0;
+ int leading_break = 0;
+ int trailing_space = 0;
+ int trailing_break = 0;
+ int break_space = 0;
+ int space_break = 0;
+
+ int preceeded_by_whitespace = 0;
+ int followed_by_whitespace = 0;
+ int previous_space = 0;
+ int previous_break = 0;
+
+ STRING_ASSIGN(string, value, length);
+
+ emitter->scalar_data.value = value;
+ emitter->scalar_data.length = length;
+
+ if (string.start == string.end)
+ {
+ emitter->scalar_data.multiline = 0;
+ emitter->scalar_data.flow_plain_allowed = 0;
+ emitter->scalar_data.block_plain_allowed = 1;
+ emitter->scalar_data.single_quoted_allowed = 1;
+ emitter->scalar_data.block_allowed = 0;
+
+ return 1;
+ }
+
+ if ((CHECK_AT(string, '-', 0)
+ && CHECK_AT(string, '-', 1)
+ && CHECK_AT(string, '-', 2))
+ || (CHECK_AT(string, '.', 0)
+ && CHECK_AT(string, '.', 1)
+ && CHECK_AT(string, '.', 2))) {
+ block_indicators = 1;
+ flow_indicators = 1;
+ }
+
+ preceeded_by_whitespace = 1;
+ followed_by_whitespace = IS_BLANKZ_AT(string, WIDTH(string));
+
+ while (string.pointer != string.end)
+ {
+ if (string.start == string.pointer)
+ {
+ if (CHECK(string, '#') || CHECK(string, ',')
+ || CHECK(string, '[') || CHECK(string, ']')
+ || CHECK(string, '{') || CHECK(string, '}')
+ || CHECK(string, '&') || CHECK(string, '*')
+ || CHECK(string, '!') || CHECK(string, '|')
+ || CHECK(string, '>') || CHECK(string, '\'')
+ || CHECK(string, '"') || CHECK(string, '%')
+ || CHECK(string, '@') || CHECK(string, '`')) {
+ flow_indicators = 1;
+ block_indicators = 1;
+ }
+
+ if (CHECK(string, '?') || CHECK(string, ':')) {
+ flow_indicators = 1;
+ if (followed_by_whitespace) {
+ block_indicators = 1;
+ }
+ }
+
+ if (CHECK(string, '-') && followed_by_whitespace) {
+ flow_indicators = 1;
+ block_indicators = 1;
+ }
+ }
+ else
+ {
+ if (CHECK(string, ',') || CHECK(string, '?')
+ || CHECK(string, '[') || CHECK(string, ']')
+ || CHECK(string, '{') || CHECK(string, '}')) {
+ flow_indicators = 1;
+ }
+
+ if (CHECK(string, ':')) {
+ flow_indicators = 1;
+ if (followed_by_whitespace) {
+ block_indicators = 1;
+ }
+ }
+
+ if (CHECK(string, '#') && preceeded_by_whitespace) {
+ flow_indicators = 1;
+ block_indicators = 1;
+ }
+ }
+
+ if (!IS_PRINTABLE(string)
+ || (!IS_ASCII(string) && !emitter->unicode)) {
+ special_characters = 1;
+ }
+
+ if (IS_BREAK(string)) {
+ line_breaks = 1;
+ }
+
+ if (IS_SPACE(string))
+ {
+ if (string.start == string.pointer) {
+ leading_space = 1;
+ }
+ if (string.pointer+WIDTH(string) == string.end) {
+ trailing_space = 1;
+ }
+ if (previous_break) {
+ break_space = 1;
+ }
+ previous_space = 1;
+ previous_break = 0;
+ }
+ else if (IS_BREAK(string))
+ {
+ if (string.start == string.pointer) {
+ leading_break = 1;
+ }
+ if (string.pointer+WIDTH(string) == string.end) {
+ trailing_break = 1;
+ }
+ if (previous_space) {
+ space_break = 1;
+ }
+ previous_space = 0;
+ previous_break = 1;
+ }
+ else
+ {
+ previous_space = 0;
+ previous_break = 0;
+ }
+
+ preceeded_by_whitespace = IS_BLANKZ(string);
+ MOVE(string);
+ if (string.pointer != string.end) {
+ followed_by_whitespace = IS_BLANKZ_AT(string, WIDTH(string));
+ }
+ }
+
+ emitter->scalar_data.multiline = line_breaks;
+
+ emitter->scalar_data.flow_plain_allowed = 1;
+ emitter->scalar_data.block_plain_allowed = 1;
+ emitter->scalar_data.single_quoted_allowed = 1;
+ emitter->scalar_data.block_allowed = 1;
+
+ if (leading_space || leading_break || trailing_space || trailing_break) {
+ emitter->scalar_data.flow_plain_allowed = 0;
+ emitter->scalar_data.block_plain_allowed = 0;
+ }
+
+ if (trailing_space) {
+ emitter->scalar_data.block_allowed = 0;
+ }
+
+ if (break_space) {
+ emitter->scalar_data.flow_plain_allowed = 0;
+ emitter->scalar_data.block_plain_allowed = 0;
+ emitter->scalar_data.single_quoted_allowed = 0;
+ }
+
+ if (space_break || special_characters) {
+ emitter->scalar_data.flow_plain_allowed = 0;
+ emitter->scalar_data.block_plain_allowed = 0;
+ emitter->scalar_data.single_quoted_allowed = 0;
+ emitter->scalar_data.block_allowed = 0;
+ }
+
+ if (line_breaks) {
+ emitter->scalar_data.flow_plain_allowed = 0;
+ emitter->scalar_data.block_plain_allowed = 0;
+ }
+
+ if (flow_indicators) {
+ emitter->scalar_data.flow_plain_allowed = 0;
+ }
+
+ if (block_indicators) {
+ emitter->scalar_data.block_plain_allowed = 0;
+ }
+
+ return 1;
+}
+
+/*
+ * Check if the event data is valid.
+ */
+
+static int
+yaml_emitter_analyze_event(yaml_emitter_t *emitter,
+ yaml_event_t *event)
+{
+ emitter->anchor_data.anchor = NULL;
+ emitter->anchor_data.anchor_length = 0;
+ emitter->tag_data.handle = NULL;
+ emitter->tag_data.handle_length = 0;
+ emitter->tag_data.suffix = NULL;
+ emitter->tag_data.suffix_length = 0;
+ emitter->scalar_data.value = NULL;
+ emitter->scalar_data.length = 0;
+
+ switch (event->type)
+ {
+ case YAML_ALIAS_EVENT:
+ if (!yaml_emitter_analyze_anchor(emitter,
+ event->data.alias.anchor, 1))
+ return 0;
+ return 1;
+
+ case YAML_SCALAR_EVENT:
+ if (event->data.scalar.anchor) {
+ if (!yaml_emitter_analyze_anchor(emitter,
+ event->data.scalar.anchor, 0))
+ return 0;
+ }
+ if (event->data.scalar.tag && (emitter->canonical ||
+ (!event->data.scalar.plain_implicit
+ && !event->data.scalar.quoted_implicit))) {
+ if (!yaml_emitter_analyze_tag(emitter, event->data.scalar.tag))
+ return 0;
+ }
+ if (!yaml_emitter_analyze_scalar(emitter,
+ event->data.scalar.value, event->data.scalar.length))
+ return 0;
+ return 1;
+
+ case YAML_SEQUENCE_START_EVENT:
+ if (event->data.sequence_start.anchor) {
+ if (!yaml_emitter_analyze_anchor(emitter,
+ event->data.sequence_start.anchor, 0))
+ return 0;
+ }
+ if (event->data.sequence_start.tag && (emitter->canonical ||
+ !event->data.sequence_start.implicit)) {
+ if (!yaml_emitter_analyze_tag(emitter,
+ event->data.sequence_start.tag))
+ return 0;
+ }
+ return 1;
+
+ case YAML_MAPPING_START_EVENT:
+ if (event->data.mapping_start.anchor) {
+ if (!yaml_emitter_analyze_anchor(emitter,
+ event->data.mapping_start.anchor, 0))
+ return 0;
+ }
+ if (event->data.mapping_start.tag && (emitter->canonical ||
+ !event->data.mapping_start.implicit)) {
+ if (!yaml_emitter_analyze_tag(emitter,
+ event->data.mapping_start.tag))
+ return 0;
+ }
+ return 1;
+
+ default:
+ return 1;
+ }
+}
+
+/*
+ * Write the BOM character.
+ */
+
+static int
+yaml_emitter_write_bom(yaml_emitter_t *emitter)
+{
+ if (!FLUSH(emitter)) return 0;
+
+ *(emitter->buffer.pointer++) = (yaml_char_t) '\xEF';
+ *(emitter->buffer.pointer++) = (yaml_char_t) '\xBB';
+ *(emitter->buffer.pointer++) = (yaml_char_t) '\xBF';
+
+ return 1;
+}
+
+static int
+yaml_emitter_write_indent(yaml_emitter_t *emitter)
+{
+ int indent = (emitter->indent >= 0) ? emitter->indent : 0;
+
+ if (!emitter->indention || emitter->column > indent
+ || (emitter->column == indent && !emitter->whitespace)) {
+ if (!PUT_BREAK(emitter)) return 0;
+ }
+
+ while (emitter->column < indent) {
+ if (!PUT(emitter, ' ')) return 0;
+ }
+
+ emitter->whitespace = 1;
+ emitter->indention = 1;
+
+ return 1;
+}
+
+static int
+yaml_emitter_write_indicator(yaml_emitter_t *emitter,
+ char *indicator, int need_whitespace,
+ int is_whitespace, int is_indention)
+{
+ size_t indicator_length;
+ yaml_string_t string;
+
+ indicator_length = strlen(indicator);
+ STRING_ASSIGN(string, (yaml_char_t *)indicator, indicator_length);
+
+ if (need_whitespace && !emitter->whitespace) {
+ if (!PUT(emitter, ' ')) return 0;
+ }
+
+ while (string.pointer != string.end) {
+ if (!WRITE(emitter, string)) return 0;
+ }
+
+ emitter->whitespace = is_whitespace;
+ emitter->indention = (emitter->indention && is_indention);
+ emitter->open_ended = 0;
+
+ return 1;
+}
+
+static int
+yaml_emitter_write_anchor(yaml_emitter_t *emitter,
+ yaml_char_t *value, size_t length)
+{
+ yaml_string_t string;
+ STRING_ASSIGN(string, value, length);
+
+ while (string.pointer != string.end) {
+ if (!WRITE(emitter, string)) return 0;
+ }
+
+ emitter->whitespace = 0;
+ emitter->indention = 0;
+
+ return 1;
+}
+
+static int
+yaml_emitter_write_tag_handle(yaml_emitter_t *emitter,
+ yaml_char_t *value, size_t length)
+{
+ yaml_string_t string;
+ STRING_ASSIGN(string, value, length);
+
+ if (!emitter->whitespace) {
+ if (!PUT(emitter, ' ')) return 0;
+ }
+
+ while (string.pointer != string.end) {
+ if (!WRITE(emitter, string)) return 0;
+ }
+
+ emitter->whitespace = 0;
+ emitter->indention = 0;
+
+ return 1;
+}
+
+static int
+yaml_emitter_write_tag_content(yaml_emitter_t *emitter,
+ yaml_char_t *value, size_t length,
+ int need_whitespace)
+{
+ yaml_string_t string;
+ STRING_ASSIGN(string, value, length);
+
+ if (need_whitespace && !emitter->whitespace) {
+ if (!PUT(emitter, ' ')) return 0;
+ }
+
+ while (string.pointer != string.end) {
+ if (IS_ALPHA(string)
+ || CHECK(string, ';') || CHECK(string, '/')
+ || CHECK(string, '?') || CHECK(string, ':')
+ || CHECK(string, '@') || CHECK(string, '&')
+ || CHECK(string, '=') || CHECK(string, '+')
+ || CHECK(string, '$') || CHECK(string, ',')
+ || CHECK(string, '_') || CHECK(string, '.')
+ || CHECK(string, '~') || CHECK(string, '*')
+ || CHECK(string, '\'') || CHECK(string, '(')
+ || CHECK(string, ')') || CHECK(string, '[')
+ || CHECK(string, ']')) {
+ if (!WRITE(emitter, string)) return 0;
+ }
+ else {
+ int width = WIDTH(string);
+ unsigned int value;
+ while (width --) {
+ value = *(string.pointer++);
+ if (!PUT(emitter, '%')) return 0;
+ if (!PUT(emitter, (value >> 4)
+ + ((value >> 4) < 10 ? '0' : 'A' - 10)))
+ return 0;
+ if (!PUT(emitter, (value & 0x0F)
+ + ((value & 0x0F) < 10 ? '0' : 'A' - 10)))
+ return 0;
+ }
+ }
+ }
+
+ emitter->whitespace = 0;
+ emitter->indention = 0;
+
+ return 1;
+}
+
+static int
+yaml_emitter_write_plain_scalar(yaml_emitter_t *emitter,
+ yaml_char_t *value, size_t length, int allow_breaks)
+{
+ yaml_string_t string;
+ int spaces = 0;
+ int breaks = 0;
+
+ STRING_ASSIGN(string, value, length);
+
+ if (!emitter->whitespace) {
+ if (!PUT(emitter, ' ')) return 0;
+ }
+
+ while (string.pointer != string.end)
+ {
+ if (IS_SPACE(string))
+ {
+ if (allow_breaks && !spaces
+ && emitter->column > emitter->best_width
+ && !IS_SPACE_AT(string, 1)) {
+ if (!yaml_emitter_write_indent(emitter)) return 0;
+ MOVE(string);
+ }
+ else {
+ if (!WRITE(emitter, string)) return 0;
+ }
+ spaces = 1;
+ }
+ else if (IS_BREAK(string))
+ {
+ if (!breaks && CHECK(string, '\n')) {
+ if (!PUT_BREAK(emitter)) return 0;
+ }
+ if (!WRITE_BREAK(emitter, string)) return 0;
+ emitter->indention = 1;
+ breaks = 1;
+ }
+ else
+ {
+ if (breaks) {
+ if (!yaml_emitter_write_indent(emitter)) return 0;
+ }
+ if (!WRITE(emitter, string)) return 0;
+ emitter->indention = 0;
+ spaces = 0;
+ breaks = 0;
+ }
+ }
+
+ emitter->whitespace = 0;
+ emitter->indention = 0;
+ if (emitter->root_context)
+ {
+ emitter->open_ended = 1;
+ }
+
+ return 1;
+}
+
+static int
+yaml_emitter_write_single_quoted_scalar(yaml_emitter_t *emitter,
+ yaml_char_t *value, size_t length, int allow_breaks)
+{
+ yaml_string_t string;
+ int spaces = 0;
+ int breaks = 0;
+
+ STRING_ASSIGN(string, value, length);
+
+ if (!yaml_emitter_write_indicator(emitter, "'", 1, 0, 0))
+ return 0;
+
+ while (string.pointer != string.end)
+ {
+ if (IS_SPACE(string))
+ {
+ if (allow_breaks && !spaces
+ && emitter->column > emitter->best_width
+ && string.pointer != string.start
+ && string.pointer != string.end - 1
+ && !IS_SPACE_AT(string, 1)) {
+ if (!yaml_emitter_write_indent(emitter)) return 0;
+ MOVE(string);
+ }
+ else {
+ if (!WRITE(emitter, string)) return 0;
+ }
+ spaces = 1;
+ }
+ else if (IS_BREAK(string))
+ {
+ if (!breaks && CHECK(string, '\n')) {
+ if (!PUT_BREAK(emitter)) return 0;
+ }
+ if (!WRITE_BREAK(emitter, string)) return 0;
+ emitter->indention = 1;
+ breaks = 1;
+ }
+ else
+ {
+ if (breaks) {
+ if (!yaml_emitter_write_indent(emitter)) return 0;
+ }
+ if (CHECK(string, '\'')) {
+ if (!PUT(emitter, '\'')) return 0;
+ }
+ if (!WRITE(emitter, string)) return 0;
+ emitter->indention = 0;
+ spaces = 0;
+ breaks = 0;
+ }
+ }
+
+ if (!yaml_emitter_write_indicator(emitter, "'", 0, 0, 0))
+ return 0;
+
+ emitter->whitespace = 0;
+ emitter->indention = 0;
+
+ return 1;
+}
+
+static int
+yaml_emitter_write_double_quoted_scalar(yaml_emitter_t *emitter,
+ yaml_char_t *value, size_t length, int allow_breaks)
+{
+ yaml_string_t string;
+ int spaces = 0;
+
+ STRING_ASSIGN(string, value, length);
+
+ if (!yaml_emitter_write_indicator(emitter, "\"", 1, 0, 0))
+ return 0;
+
+ while (string.pointer != string.end)
+ {
+ if (!IS_PRINTABLE(string) || (!emitter->unicode && !IS_ASCII(string))
+ || IS_BOM(string) || IS_BREAK(string)
+ || CHECK(string, '"') || CHECK(string, '\\'))
+ {
+ unsigned char octet;
+ unsigned int width;
+ unsigned int value;
+ int k;
+
+ octet = string.pointer[0];
+ width = (octet & 0x80) == 0x00 ? 1 :
+ (octet & 0xE0) == 0xC0 ? 2 :
+ (octet & 0xF0) == 0xE0 ? 3 :
+ (octet & 0xF8) == 0xF0 ? 4 : 0;
+ value = (octet & 0x80) == 0x00 ? octet & 0x7F :
+ (octet & 0xE0) == 0xC0 ? octet & 0x1F :
+ (octet & 0xF0) == 0xE0 ? octet & 0x0F :
+ (octet & 0xF8) == 0xF0 ? octet & 0x07 : 0;
+ for (k = 1; k < (int)width; k ++) {
+ octet = string.pointer[k];
+ value = (value << 6) + (octet & 0x3F);
+ }
+ string.pointer += width;
+
+ if (!PUT(emitter, '\\')) return 0;
+
+ switch (value)
+ {
+ case 0x00:
+ if (!PUT(emitter, '0')) return 0;
+ break;
+
+ case 0x07:
+ if (!PUT(emitter, 'a')) return 0;
+ break;
+
+ case 0x08:
+ if (!PUT(emitter, 'b')) return 0;
+ break;
+
+ case 0x09:
+ if (!PUT(emitter, 't')) return 0;
+ break;
+
+ case 0x0A:
+ if (!PUT(emitter, 'n')) return 0;
+ break;
+
+ case 0x0B:
+ if (!PUT(emitter, 'v')) return 0;
+ break;
+
+ case 0x0C:
+ if (!PUT(emitter, 'f')) return 0;
+ break;
+
+ case 0x0D:
+ if (!PUT(emitter, 'r')) return 0;
+ break;
+
+ case 0x1B:
+ if (!PUT(emitter, 'e')) return 0;
+ break;
+
+ case 0x22:
+ if (!PUT(emitter, '\"')) return 0;
+ break;
+
+ case 0x5C:
+ if (!PUT(emitter, '\\')) return 0;
+ break;
+
+ case 0x85:
+ if (!PUT(emitter, 'N')) return 0;
+ break;
+
+ case 0xA0:
+ if (!PUT(emitter, '_')) return 0;
+ break;
+
+ case 0x2028:
+ if (!PUT(emitter, 'L')) return 0;
+ break;
+
+ case 0x2029:
+ if (!PUT(emitter, 'P')) return 0;
+ break;
+
+ default:
+ if (value <= 0xFF) {
+ if (!PUT(emitter, 'x')) return 0;
+ width = 2;
+ }
+ else if (value <= 0xFFFF) {
+ if (!PUT(emitter, 'u')) return 0;
+ width = 4;
+ }
+ else {
+ if (!PUT(emitter, 'U')) return 0;
+ width = 8;
+ }
+ for (k = (width-1)*4; k >= 0; k -= 4) {
+ int digit = (value >> k) & 0x0F;
+ if (!PUT(emitter, digit + (digit < 10 ? '0' : 'A'-10)))
+ return 0;
+ }
+ }
+ spaces = 0;
+ }
+ else if (IS_SPACE(string))
+ {
+ if (allow_breaks && !spaces
+ && emitter->column > emitter->best_width
+ && string.pointer != string.start
+ && string.pointer != string.end - 1) {
+ if (!yaml_emitter_write_indent(emitter)) return 0;
+ if (IS_SPACE_AT(string, 1)) {
+ if (!PUT(emitter, '\\')) return 0;
+ }
+ MOVE(string);
+ }
+ else {
+ if (!WRITE(emitter, string)) return 0;
+ }
+ spaces = 1;
+ }
+ else
+ {
+ if (!WRITE(emitter, string)) return 0;
+ spaces = 0;
+ }
+ }
+
+ if (!yaml_emitter_write_indicator(emitter, "\"", 0, 0, 0))
+ return 0;
+
+ emitter->whitespace = 0;
+ emitter->indention = 0;
+
+ return 1;
+}
+
+static int
+yaml_emitter_write_block_scalar_hints(yaml_emitter_t *emitter,
+ yaml_string_t string)
+{
+ char indent_hint[2];
+ char *chomp_hint = NULL;
+
+ if (IS_SPACE(string) || IS_BREAK(string))
+ {
+ indent_hint[0] = '0' + (char)emitter->best_indent;
+ indent_hint[1] = '\0';
+ if (!yaml_emitter_write_indicator(emitter, indent_hint, 0, 0, 0))
+ return 0;
+ }
+
+ emitter->open_ended = 0;
+
+ string.pointer = string.end;
+ if (string.start == string.pointer)
+ {
+ chomp_hint = "-";
+ }
+ else
+ {
+ do {
+ string.pointer --;
+ } while ((*string.pointer & 0xC0) == 0x80);
+ if (!IS_BREAK(string))
+ {
+ chomp_hint = "-";
+ }
+ else if (string.start == string.pointer)
+ {
+ chomp_hint = "+";
+ emitter->open_ended = 1;
+ }
+ else
+ {
+ do {
+ string.pointer --;
+ } while ((*string.pointer & 0xC0) == 0x80);
+ if (IS_BREAK(string))
+ {
+ chomp_hint = "+";
+ emitter->open_ended = 1;
+ }
+ }
+ }
+
+ if (chomp_hint)
+ {
+ if (!yaml_emitter_write_indicator(emitter, chomp_hint, 0, 0, 0))
+ return 0;
+ }
+
+ return 1;
+}
+
+static int
+yaml_emitter_write_literal_scalar(yaml_emitter_t *emitter,
+ yaml_char_t *value, size_t length)
+{
+ yaml_string_t string;
+ int breaks = 1;
+
+ STRING_ASSIGN(string, value, length);
+
+ if (!yaml_emitter_write_indicator(emitter, "|", 1, 0, 0))
+ return 0;
+ if (!yaml_emitter_write_block_scalar_hints(emitter, string))
+ return 0;
+ if (!PUT_BREAK(emitter)) return 0;
+ emitter->indention = 1;
+ emitter->whitespace = 1;
+
+ while (string.pointer != string.end)
+ {
+ if (IS_BREAK(string))
+ {
+ if (!WRITE_BREAK(emitter, string)) return 0;
+ emitter->indention = 1;
+ breaks = 1;
+ }
+ else
+ {
+ if (breaks) {
+ if (!yaml_emitter_write_indent(emitter)) return 0;
+ }
+ if (!WRITE(emitter, string)) return 0;
+ emitter->indention = 0;
+ breaks = 0;
+ }
+ }
+
+ return 1;
+}
+
+static int
+yaml_emitter_write_folded_scalar(yaml_emitter_t *emitter,
+ yaml_char_t *value, size_t length)
+{
+ yaml_string_t string;
+ int breaks = 1;
+ int leading_spaces = 1;
+
+ STRING_ASSIGN(string, value, length);
+
+ if (!yaml_emitter_write_indicator(emitter, ">", 1, 0, 0))
+ return 0;
+ if (!yaml_emitter_write_block_scalar_hints(emitter, string))
+ return 0;
+ if (!PUT_BREAK(emitter)) return 0;
+ emitter->indention = 1;
+ emitter->whitespace = 1;
+
+ while (string.pointer != string.end)
+ {
+ if (IS_BREAK(string))
+ {
+ if (!breaks && !leading_spaces && CHECK(string, '\n')) {
+ int k = 0;
+ while (IS_BREAK_AT(string, k)) {
+ k += WIDTH_AT(string, k);
+ }
+ if (!IS_BLANKZ_AT(string, k)) {
+ if (!PUT_BREAK(emitter)) return 0;
+ }
+ }
+ if (!WRITE_BREAK(emitter, string)) return 0;
+ emitter->indention = 1;
+ breaks = 1;
+ }
+ else
+ {
+ if (breaks) {
+ if (!yaml_emitter_write_indent(emitter)) return 0;
+ leading_spaces = IS_BLANK(string);
+ }
+ if (!breaks && IS_SPACE(string) && !IS_SPACE_AT(string, 1)
+ && emitter->column > emitter->best_width) {
+ if (!yaml_emitter_write_indent(emitter)) return 0;
+ MOVE(string);
+ }
+ else {
+ if (!WRITE(emitter, string)) return 0;
+ }
+ emitter->indention = 0;
+ breaks = 0;
+ }
+ }
+
+ return 1;
+}
+
diff --git a/contrib/libyaml/src/loader.c b/contrib/libyaml/src/loader.c
new file mode 100644
index 0000000..9d3d912
--- /dev/null
+++ b/contrib/libyaml/src/loader.c
@@ -0,0 +1,432 @@
+
+#include "yaml_private.h"
+
+/*
+ * API functions.
+ */
+
+YAML_DECLARE(int)
+yaml_parser_load(yaml_parser_t *parser, yaml_document_t *document);
+
+/*
+ * Error handling.
+ */
+
+static int
+yaml_parser_set_composer_error(yaml_parser_t *parser,
+ const char *problem, yaml_mark_t problem_mark);
+
+static int
+yaml_parser_set_composer_error_context(yaml_parser_t *parser,
+ const char *context, yaml_mark_t context_mark,
+ const char *problem, yaml_mark_t problem_mark);
+
+
+/*
+ * Alias handling.
+ */
+
+static int
+yaml_parser_register_anchor(yaml_parser_t *parser,
+ int index, yaml_char_t *anchor);
+
+/*
+ * Clean up functions.
+ */
+
+static void
+yaml_parser_delete_aliases(yaml_parser_t *parser);
+
+/*
+ * Composer functions.
+ */
+
+static int
+yaml_parser_load_document(yaml_parser_t *parser, yaml_event_t *first_event);
+
+static int
+yaml_parser_load_node(yaml_parser_t *parser, yaml_event_t *first_event);
+
+static int
+yaml_parser_load_alias(yaml_parser_t *parser, yaml_event_t *first_event);
+
+static int
+yaml_parser_load_scalar(yaml_parser_t *parser, yaml_event_t *first_event);
+
+static int
+yaml_parser_load_sequence(yaml_parser_t *parser, yaml_event_t *first_event);
+
+static int
+yaml_parser_load_mapping(yaml_parser_t *parser, yaml_event_t *first_event);
+
+/*
+ * Load the next document of the stream.
+ */
+
+YAML_DECLARE(int)
+yaml_parser_load(yaml_parser_t *parser, yaml_document_t *document)
+{
+ yaml_event_t event;
+
+ assert(parser); /* Non-NULL parser object is expected. */
+ assert(document); /* Non-NULL document object is expected. */
+
+ memset(document, 0, sizeof(yaml_document_t));
+ if (!STACK_INIT(parser, document->nodes, INITIAL_STACK_SIZE))
+ goto error;
+
+ if (!parser->stream_start_produced) {
+ if (!yaml_parser_parse(parser, &event)) goto error;
+ assert(event.type == YAML_STREAM_START_EVENT);
+ /* STREAM-START is expected. */
+ }
+
+ if (parser->stream_end_produced) {
+ return 1;
+ }
+
+ if (!yaml_parser_parse(parser, &event)) goto error;
+ if (event.type == YAML_STREAM_END_EVENT) {
+ return 1;
+ }
+
+ if (!STACK_INIT(parser, parser->aliases, INITIAL_STACK_SIZE))
+ goto error;
+
+ parser->document = document;
+
+ if (!yaml_parser_load_document(parser, &event)) goto error;
+
+ yaml_parser_delete_aliases(parser);
+ parser->document = NULL;
+
+ return 1;
+
+error:
+
+ yaml_parser_delete_aliases(parser);
+ yaml_document_delete(document);
+ parser->document = NULL;
+
+ return 0;
+}
+
+/*
+ * Set composer error.
+ */
+
+static int
+yaml_parser_set_composer_error(yaml_parser_t *parser,
+ const char *problem, yaml_mark_t problem_mark)
+{
+ parser->error = YAML_COMPOSER_ERROR;
+ parser->problem = problem;
+ parser->problem_mark = problem_mark;
+
+ return 0;
+}
+
+/*
+ * Set composer error with context.
+ */
+
+static int
+yaml_parser_set_composer_error_context(yaml_parser_t *parser,
+ const char *context, yaml_mark_t context_mark,
+ const char *problem, yaml_mark_t problem_mark)
+{
+ parser->error = YAML_COMPOSER_ERROR;
+ parser->context = context;
+ parser->context_mark = context_mark;
+ parser->problem = problem;
+ parser->problem_mark = problem_mark;
+
+ return 0;
+}
+
+/*
+ * Delete the stack of aliases.
+ */
+
+static void
+yaml_parser_delete_aliases(yaml_parser_t *parser)
+{
+ while (!STACK_EMPTY(parser, parser->aliases)) {
+ yaml_free(POP(parser, parser->aliases).anchor);
+ }
+ STACK_DEL(parser, parser->aliases);
+}
+
+/*
+ * Compose a document object.
+ */
+
+static int
+yaml_parser_load_document(yaml_parser_t *parser, yaml_event_t *first_event)
+{
+ yaml_event_t event;
+
+ assert(first_event->type == YAML_DOCUMENT_START_EVENT);
+ /* DOCUMENT-START is expected. */
+
+ parser->document->version_directive
+ = first_event->data.document_start.version_directive;
+ parser->document->tag_directives.start
+ = first_event->data.document_start.tag_directives.start;
+ parser->document->tag_directives.end
+ = first_event->data.document_start.tag_directives.end;
+ parser->document->start_implicit
+ = first_event->data.document_start.implicit;
+ parser->document->start_mark = first_event->start_mark;
+
+ if (!yaml_parser_parse(parser, &event)) return 0;
+
+ if (!yaml_parser_load_node(parser, &event)) return 0;
+
+ if (!yaml_parser_parse(parser, &event)) return 0;
+ assert(event.type == YAML_DOCUMENT_END_EVENT);
+ /* DOCUMENT-END is expected. */
+
+ parser->document->end_implicit = event.data.document_end.implicit;
+ parser->document->end_mark = event.end_mark;
+
+ return 1;
+}
+
+/*
+ * Compose a node.
+ */
+
+static int
+yaml_parser_load_node(yaml_parser_t *parser, yaml_event_t *first_event)
+{
+ switch (first_event->type) {
+ case YAML_ALIAS_EVENT:
+ return yaml_parser_load_alias(parser, first_event);
+ case YAML_SCALAR_EVENT:
+ return yaml_parser_load_scalar(parser, first_event);
+ case YAML_SEQUENCE_START_EVENT:
+ return yaml_parser_load_sequence(parser, first_event);
+ case YAML_MAPPING_START_EVENT:
+ return yaml_parser_load_mapping(parser, first_event);
+ default:
+ assert(0); /* Could not happen. */
+ return 0;
+ }
+
+ return 0;
+}
+
+/*
+ * Add an anchor.
+ */
+
+static int
+yaml_parser_register_anchor(yaml_parser_t *parser,
+ int index, yaml_char_t *anchor)
+{
+ yaml_alias_data_t data;
+ yaml_alias_data_t *alias_data;
+
+ if (!anchor) return 1;
+
+ data.anchor = anchor;
+ data.index = index;
+ data.mark = parser->document->nodes.start[index-1].start_mark;
+
+ for (alias_data = parser->aliases.start;
+ alias_data != parser->aliases.top; alias_data ++) {
+ if (strcmp((char *)alias_data->anchor, (char *)anchor) == 0) {
+ yaml_free(anchor);
+ return yaml_parser_set_composer_error_context(parser,
+ "found duplicate anchor; first occurence",
+ alias_data->mark, "second occurence", data.mark);
+ }
+ }
+
+ if (!PUSH(parser, parser->aliases, data)) {
+ yaml_free(anchor);
+ return 0;
+ }
+
+ return 1;
+}
+
+/*
+ * Compose a node corresponding to an alias.
+ */
+
+static int
+yaml_parser_load_alias(yaml_parser_t *parser, yaml_event_t *first_event)
+{
+ yaml_char_t *anchor = first_event->data.alias.anchor;
+ yaml_alias_data_t *alias_data;
+
+ for (alias_data = parser->aliases.start;
+ alias_data != parser->aliases.top; alias_data ++) {
+ if (strcmp((char *)alias_data->anchor, (char *)anchor) == 0) {
+ yaml_free(anchor);
+ return alias_data->index;
+ }
+ }
+
+ yaml_free(anchor);
+ return yaml_parser_set_composer_error(parser, "found undefined alias",
+ first_event->start_mark);
+}
+
+/*
+ * Compose a scalar node.
+ */
+
+static int
+yaml_parser_load_scalar(yaml_parser_t *parser, yaml_event_t *first_event)
+{
+ yaml_node_t node;
+ int index;
+ yaml_char_t *tag = first_event->data.scalar.tag;
+
+ if (!tag || strcmp((char *)tag, "!") == 0) {
+ yaml_free(tag);
+ tag = yaml_strdup((yaml_char_t *)YAML_DEFAULT_SCALAR_TAG);
+ if (!tag) goto error;
+ }
+
+ SCALAR_NODE_INIT(node, tag, first_event->data.scalar.value,
+ first_event->data.scalar.length, first_event->data.scalar.style,
+ first_event->start_mark, first_event->end_mark);
+
+ if (!PUSH(parser, parser->document->nodes, node)) goto error;
+
+ index = parser->document->nodes.top - parser->document->nodes.start;
+
+ if (!yaml_parser_register_anchor(parser, index,
+ first_event->data.scalar.anchor)) return 0;
+
+ return index;
+
+error:
+ yaml_free(tag);
+ yaml_free(first_event->data.scalar.anchor);
+ yaml_free(first_event->data.scalar.value);
+ return 0;
+}
+
+/*
+ * Compose a sequence node.
+ */
+
+static int
+yaml_parser_load_sequence(yaml_parser_t *parser, yaml_event_t *first_event)
+{
+ yaml_event_t event;
+ yaml_node_t node;
+ struct {
+ yaml_node_item_t *start;
+ yaml_node_item_t *end;
+ yaml_node_item_t *top;
+ } items = { NULL, NULL, NULL };
+ int index, item_index;
+ yaml_char_t *tag = first_event->data.sequence_start.tag;
+
+ if (!tag || strcmp((char *)tag, "!") == 0) {
+ yaml_free(tag);
+ tag = yaml_strdup((yaml_char_t *)YAML_DEFAULT_SEQUENCE_TAG);
+ if (!tag) goto error;
+ }
+
+ if (!STACK_INIT(parser, items, INITIAL_STACK_SIZE)) goto error;
+
+ SEQUENCE_NODE_INIT(node, tag, items.start, items.end,
+ first_event->data.sequence_start.style,
+ first_event->start_mark, first_event->end_mark);
+
+ if (!PUSH(parser, parser->document->nodes, node)) goto error;
+
+ index = parser->document->nodes.top - parser->document->nodes.start;
+
+ if (!yaml_parser_register_anchor(parser, index,
+ first_event->data.sequence_start.anchor)) return 0;
+
+ if (!yaml_parser_parse(parser, &event)) return 0;
+
+ while (event.type != YAML_SEQUENCE_END_EVENT) {
+ item_index = yaml_parser_load_node(parser, &event);
+ if (!item_index) return 0;
+ if (!PUSH(parser,
+ parser->document->nodes.start[index-1].data.sequence.items,
+ item_index)) return 0;
+ if (!yaml_parser_parse(parser, &event)) return 0;
+ }
+
+ parser->document->nodes.start[index-1].end_mark = event.end_mark;
+
+ return index;
+
+error:
+ yaml_free(tag);
+ yaml_free(first_event->data.sequence_start.anchor);
+ return 0;
+}
+
+/*
+ * Compose a mapping node.
+ */
+
+static int
+yaml_parser_load_mapping(yaml_parser_t *parser, yaml_event_t *first_event)
+{
+ yaml_event_t event;
+ yaml_node_t node;
+ struct {
+ yaml_node_pair_t *start;
+ yaml_node_pair_t *end;
+ yaml_node_pair_t *top;
+ } pairs = { NULL, NULL, NULL };
+ int index;
+ yaml_node_pair_t pair;
+ yaml_char_t *tag = first_event->data.mapping_start.tag;
+
+ if (!tag || strcmp((char *)tag, "!") == 0) {
+ yaml_free(tag);
+ tag = yaml_strdup((yaml_char_t *)YAML_DEFAULT_MAPPING_TAG);
+ if (!tag) goto error;
+ }
+
+ if (!STACK_INIT(parser, pairs, INITIAL_STACK_SIZE)) goto error;
+
+ MAPPING_NODE_INIT(node, tag, pairs.start, pairs.end,
+ first_event->data.mapping_start.style,
+ first_event->start_mark, first_event->end_mark);
+
+ if (!PUSH(parser, parser->document->nodes, node)) goto error;
+
+ index = parser->document->nodes.top - parser->document->nodes.start;
+
+ if (!yaml_parser_register_anchor(parser, index,
+ first_event->data.mapping_start.anchor)) return 0;
+
+ if (!yaml_parser_parse(parser, &event)) return 0;
+
+ while (event.type != YAML_MAPPING_END_EVENT) {
+ pair.key = yaml_parser_load_node(parser, &event);
+ if (!pair.key) return 0;
+ if (!yaml_parser_parse(parser, &event)) return 0;
+ pair.value = yaml_parser_load_node(parser, &event);
+ if (!pair.value) return 0;
+ if (!PUSH(parser,
+ parser->document->nodes.start[index-1].data.mapping.pairs,
+ pair)) return 0;
+ if (!yaml_parser_parse(parser, &event)) return 0;
+ }
+
+ parser->document->nodes.start[index-1].end_mark = event.end_mark;
+
+ return index;
+
+error:
+ yaml_free(tag);
+ yaml_free(first_event->data.mapping_start.anchor);
+ return 0;
+}
+
diff --git a/contrib/libyaml/src/parser.c b/contrib/libyaml/src/parser.c
new file mode 100644
index 0000000..eb2a2c7
--- /dev/null
+++ b/contrib/libyaml/src/parser.c
@@ -0,0 +1,1374 @@
+
+/*
+ * The parser implements the following grammar:
+ *
+ * stream ::= STREAM-START implicit_document? explicit_document* STREAM-END
+ * implicit_document ::= block_node DOCUMENT-END*
+ * explicit_document ::= DIRECTIVE* DOCUMENT-START block_node? DOCUMENT-END*
+ * block_node_or_indentless_sequence ::=
+ * ALIAS
+ * | properties (block_content | indentless_block_sequence)?
+ * | block_content
+ * | indentless_block_sequence
+ * block_node ::= ALIAS
+ * | properties block_content?
+ * | block_content
+ * flow_node ::= ALIAS
+ * | properties flow_content?
+ * | flow_content
+ * properties ::= TAG ANCHOR? | ANCHOR TAG?
+ * block_content ::= block_collection | flow_collection | SCALAR
+ * flow_content ::= flow_collection | SCALAR
+ * block_collection ::= block_sequence | block_mapping
+ * flow_collection ::= flow_sequence | flow_mapping
+ * block_sequence ::= BLOCK-SEQUENCE-START (BLOCK-ENTRY block_node?)* BLOCK-END
+ * indentless_sequence ::= (BLOCK-ENTRY block_node?)+
+ * block_mapping ::= BLOCK-MAPPING_START
+ * ((KEY block_node_or_indentless_sequence?)?
+ * (VALUE block_node_or_indentless_sequence?)?)*
+ * BLOCK-END
+ * flow_sequence ::= FLOW-SEQUENCE-START
+ * (flow_sequence_entry FLOW-ENTRY)*
+ * flow_sequence_entry?
+ * FLOW-SEQUENCE-END
+ * flow_sequence_entry ::= flow_node | KEY flow_node? (VALUE flow_node?)?
+ * flow_mapping ::= FLOW-MAPPING-START
+ * (flow_mapping_entry FLOW-ENTRY)*
+ * flow_mapping_entry?
+ * FLOW-MAPPING-END
+ * flow_mapping_entry ::= flow_node | KEY flow_node? (VALUE flow_node?)?
+ */
+
+#include "yaml_private.h"
+
+/*
+ * Peek the next token in the token queue.
+ */
+
+#define PEEK_TOKEN(parser) \
+ ((parser->token_available || yaml_parser_fetch_more_tokens(parser)) ? \
+ parser->tokens.head : NULL)
+
+/*
+ * Remove the next token from the queue (must be called after PEEK_TOKEN).
+ */
+
+#define SKIP_TOKEN(parser) \
+ (parser->token_available = 0, \
+ parser->tokens_parsed ++, \
+ parser->stream_end_produced = \
+ (parser->tokens.head->type == YAML_STREAM_END_TOKEN), \
+ parser->tokens.head ++)
+
+/*
+ * Public API declarations.
+ */
+
+YAML_DECLARE(int)
+yaml_parser_parse(yaml_parser_t *parser, yaml_event_t *event);
+
+/*
+ * Error handling.
+ */
+
+static int
+yaml_parser_set_parser_error(yaml_parser_t *parser,
+ const char *problem, yaml_mark_t problem_mark);
+
+static int
+yaml_parser_set_parser_error_context(yaml_parser_t *parser,
+ const char *context, yaml_mark_t context_mark,
+ const char *problem, yaml_mark_t problem_mark);
+
+/*
+ * State functions.
+ */
+
+static int
+yaml_parser_state_machine(yaml_parser_t *parser, yaml_event_t *event);
+
+static int
+yaml_parser_parse_stream_start(yaml_parser_t *parser, yaml_event_t *event);
+
+static int
+yaml_parser_parse_document_start(yaml_parser_t *parser, yaml_event_t *event,
+ int implicit);
+
+static int
+yaml_parser_parse_document_content(yaml_parser_t *parser, yaml_event_t *event);
+
+static int
+yaml_parser_parse_document_end(yaml_parser_t *parser, yaml_event_t *event);
+
+static int
+yaml_parser_parse_node(yaml_parser_t *parser, yaml_event_t *event,
+ int block, int indentless_sequence);
+
+static int
+yaml_parser_parse_block_sequence_entry(yaml_parser_t *parser,
+ yaml_event_t *event, int first);
+
+static int
+yaml_parser_parse_indentless_sequence_entry(yaml_parser_t *parser,
+ yaml_event_t *event);
+
+static int
+yaml_parser_parse_block_mapping_key(yaml_parser_t *parser,
+ yaml_event_t *event, int first);
+
+static int
+yaml_parser_parse_block_mapping_value(yaml_parser_t *parser,
+ yaml_event_t *event);
+
+static int
+yaml_parser_parse_flow_sequence_entry(yaml_parser_t *parser,
+ yaml_event_t *event, int first);
+
+static int
+yaml_parser_parse_flow_sequence_entry_mapping_key(yaml_parser_t *parser,
+ yaml_event_t *event);
+
+static int
+yaml_parser_parse_flow_sequence_entry_mapping_value(yaml_parser_t *parser,
+ yaml_event_t *event);
+
+static int
+yaml_parser_parse_flow_sequence_entry_mapping_end(yaml_parser_t *parser,
+ yaml_event_t *event);
+
+static int
+yaml_parser_parse_flow_mapping_key(yaml_parser_t *parser,
+ yaml_event_t *event, int first);
+
+static int
+yaml_parser_parse_flow_mapping_value(yaml_parser_t *parser,
+ yaml_event_t *event, int empty);
+
+/*
+ * Utility functions.
+ */
+
+static int
+yaml_parser_process_empty_scalar(yaml_parser_t *parser,
+ yaml_event_t *event, yaml_mark_t mark);
+
+static int
+yaml_parser_process_directives(yaml_parser_t *parser,
+ yaml_version_directive_t **version_directive_ref,
+ yaml_tag_directive_t **tag_directives_start_ref,
+ yaml_tag_directive_t **tag_directives_end_ref);
+
+static int
+yaml_parser_append_tag_directive(yaml_parser_t *parser,
+ yaml_tag_directive_t value, int allow_duplicates, yaml_mark_t mark);
+
+/*
+ * Get the next event.
+ */
+
+YAML_DECLARE(int)
+yaml_parser_parse(yaml_parser_t *parser, yaml_event_t *event)
+{
+ assert(parser); /* Non-NULL parser object is expected. */
+ assert(event); /* Non-NULL event object is expected. */
+
+ /* Erase the event object. */
+
+ memset(event, 0, sizeof(yaml_event_t));
+
+ /* No events after the end of the stream or error. */
+
+ if (parser->stream_end_produced || parser->error ||
+ parser->state == YAML_PARSE_END_STATE) {
+ return 1;
+ }
+
+ /* Generate the next event. */
+
+ return yaml_parser_state_machine(parser, event);
+}
+
+/*
+ * Set parser error.
+ */
+
+static int
+yaml_parser_set_parser_error(yaml_parser_t *parser,
+ const char *problem, yaml_mark_t problem_mark)
+{
+ parser->error = YAML_PARSER_ERROR;
+ parser->problem = problem;
+ parser->problem_mark = problem_mark;
+
+ return 0;
+}
+
+static int
+yaml_parser_set_parser_error_context(yaml_parser_t *parser,
+ const char *context, yaml_mark_t context_mark,
+ const char *problem, yaml_mark_t problem_mark)
+{
+ parser->error = YAML_PARSER_ERROR;
+ parser->context = context;
+ parser->context_mark = context_mark;
+ parser->problem = problem;
+ parser->problem_mark = problem_mark;
+
+ return 0;
+}
+
+
+/*
+ * State dispatcher.
+ */
+
+static int
+yaml_parser_state_machine(yaml_parser_t *parser, yaml_event_t *event)
+{
+ switch (parser->state)
+ {
+ case YAML_PARSE_STREAM_START_STATE:
+ return yaml_parser_parse_stream_start(parser, event);
+
+ case YAML_PARSE_IMPLICIT_DOCUMENT_START_STATE:
+ return yaml_parser_parse_document_start(parser, event, 1);
+
+ case YAML_PARSE_DOCUMENT_START_STATE:
+ return yaml_parser_parse_document_start(parser, event, 0);
+
+ case YAML_PARSE_DOCUMENT_CONTENT_STATE:
+ return yaml_parser_parse_document_content(parser, event);
+
+ case YAML_PARSE_DOCUMENT_END_STATE:
+ return yaml_parser_parse_document_end(parser, event);
+
+ case YAML_PARSE_BLOCK_NODE_STATE:
+ return yaml_parser_parse_node(parser, event, 1, 0);
+
+ case YAML_PARSE_BLOCK_NODE_OR_INDENTLESS_SEQUENCE_STATE:
+ return yaml_parser_parse_node(parser, event, 1, 1);
+
+ case YAML_PARSE_FLOW_NODE_STATE:
+ return yaml_parser_parse_node(parser, event, 0, 0);
+
+ case YAML_PARSE_BLOCK_SEQUENCE_FIRST_ENTRY_STATE:
+ return yaml_parser_parse_block_sequence_entry(parser, event, 1);
+
+ case YAML_PARSE_BLOCK_SEQUENCE_ENTRY_STATE:
+ return yaml_parser_parse_block_sequence_entry(parser, event, 0);
+
+ case YAML_PARSE_INDENTLESS_SEQUENCE_ENTRY_STATE:
+ return yaml_parser_parse_indentless_sequence_entry(parser, event);
+
+ case YAML_PARSE_BLOCK_MAPPING_FIRST_KEY_STATE:
+ return yaml_parser_parse_block_mapping_key(parser, event, 1);
+
+ case YAML_PARSE_BLOCK_MAPPING_KEY_STATE:
+ return yaml_parser_parse_block_mapping_key(parser, event, 0);
+
+ case YAML_PARSE_BLOCK_MAPPING_VALUE_STATE:
+ return yaml_parser_parse_block_mapping_value(parser, event);
+
+ case YAML_PARSE_FLOW_SEQUENCE_FIRST_ENTRY_STATE:
+ return yaml_parser_parse_flow_sequence_entry(parser, event, 1);
+
+ case YAML_PARSE_FLOW_SEQUENCE_ENTRY_STATE:
+ return yaml_parser_parse_flow_sequence_entry(parser, event, 0);
+
+ case YAML_PARSE_FLOW_SEQUENCE_ENTRY_MAPPING_KEY_STATE:
+ return yaml_parser_parse_flow_sequence_entry_mapping_key(parser, event);
+
+ case YAML_PARSE_FLOW_SEQUENCE_ENTRY_MAPPING_VALUE_STATE:
+ return yaml_parser_parse_flow_sequence_entry_mapping_value(parser, event);
+
+ case YAML_PARSE_FLOW_SEQUENCE_ENTRY_MAPPING_END_STATE:
+ return yaml_parser_parse_flow_sequence_entry_mapping_end(parser, event);
+
+ case YAML_PARSE_FLOW_MAPPING_FIRST_KEY_STATE:
+ return yaml_parser_parse_flow_mapping_key(parser, event, 1);
+
+ case YAML_PARSE_FLOW_MAPPING_KEY_STATE:
+ return yaml_parser_parse_flow_mapping_key(parser, event, 0);
+
+ case YAML_PARSE_FLOW_MAPPING_VALUE_STATE:
+ return yaml_parser_parse_flow_mapping_value(parser, event, 0);
+
+ case YAML_PARSE_FLOW_MAPPING_EMPTY_VALUE_STATE:
+ return yaml_parser_parse_flow_mapping_value(parser, event, 1);
+
+ default:
+ assert(1); /* Invalid state. */
+ }
+
+ return 0;
+}
+
+/*
+ * Parse the production:
+ * stream ::= STREAM-START implicit_document? explicit_document* STREAM-END
+ * ************
+ */
+
+static int
+yaml_parser_parse_stream_start(yaml_parser_t *parser, yaml_event_t *event)
+{
+ yaml_token_t *token;
+
+ token = PEEK_TOKEN(parser);
+ if (!token) return 0;
+
+ if (token->type != YAML_STREAM_START_TOKEN) {
+ return yaml_parser_set_parser_error(parser,
+ "did not find expected <stream-start>", token->start_mark);
+ }
+
+ parser->state = YAML_PARSE_IMPLICIT_DOCUMENT_START_STATE;
+ STREAM_START_EVENT_INIT(*event, token->data.stream_start.encoding,
+ token->start_mark, token->start_mark);
+ SKIP_TOKEN(parser);
+
+ return 1;
+}
+
+/*
+ * Parse the productions:
+ * implicit_document ::= block_node DOCUMENT-END*
+ * *
+ * explicit_document ::= DIRECTIVE* DOCUMENT-START block_node? DOCUMENT-END*
+ * *************************
+ */
+
+static int
+yaml_parser_parse_document_start(yaml_parser_t *parser, yaml_event_t *event,
+ int implicit)
+{
+ yaml_token_t *token;
+ yaml_version_directive_t *version_directive = NULL;
+ struct {
+ yaml_tag_directive_t *start;
+ yaml_tag_directive_t *end;
+ } tag_directives = { NULL, NULL };
+
+ token = PEEK_TOKEN(parser);
+ if (!token) return 0;
+
+ /* Parse extra document end indicators. */
+
+ if (!implicit)
+ {
+ while (token->type == YAML_DOCUMENT_END_TOKEN) {
+ SKIP_TOKEN(parser);
+ token = PEEK_TOKEN(parser);
+ if (!token) return 0;
+ }
+ }
+
+ /* Parse an implicit document. */
+
+ if (implicit && token->type != YAML_VERSION_DIRECTIVE_TOKEN &&
+ token->type != YAML_TAG_DIRECTIVE_TOKEN &&
+ token->type != YAML_DOCUMENT_START_TOKEN &&
+ token->type != YAML_STREAM_END_TOKEN)
+ {
+ if (!yaml_parser_process_directives(parser, NULL, NULL, NULL))
+ return 0;
+ if (!PUSH(parser, parser->states, YAML_PARSE_DOCUMENT_END_STATE))
+ return 0;
+ parser->state = YAML_PARSE_BLOCK_NODE_STATE;
+ DOCUMENT_START_EVENT_INIT(*event, NULL, NULL, NULL, 1,
+ token->start_mark, token->start_mark);
+ return 1;
+ }
+
+ /* Parse an explicit document. */
+
+ else if (token->type != YAML_STREAM_END_TOKEN)
+ {
+ yaml_mark_t start_mark, end_mark;
+ start_mark = token->start_mark;
+ if (!yaml_parser_process_directives(parser, &version_directive,
+ &tag_directives.start, &tag_directives.end))
+ return 0;
+ token = PEEK_TOKEN(parser);
+ if (!token) goto error;
+ if (token->type != YAML_DOCUMENT_START_TOKEN) {
+ yaml_parser_set_parser_error(parser,
+ "did not find expected <document start>", token->start_mark);
+ goto error;
+ }
+ if (!PUSH(parser, parser->states, YAML_PARSE_DOCUMENT_END_STATE))
+ goto error;
+ parser->state = YAML_PARSE_DOCUMENT_CONTENT_STATE;
+ end_mark = token->end_mark;
+ DOCUMENT_START_EVENT_INIT(*event, version_directive,
+ tag_directives.start, tag_directives.end, 0,
+ start_mark, end_mark);
+ SKIP_TOKEN(parser);
+ version_directive = NULL;
+ tag_directives.start = tag_directives.end = NULL;
+ return 1;
+ }
+
+ /* Parse the stream end. */
+
+ else
+ {
+ parser->state = YAML_PARSE_END_STATE;
+ STREAM_END_EVENT_INIT(*event, token->start_mark, token->end_mark);
+ SKIP_TOKEN(parser);
+ return 1;
+ }
+
+error:
+ yaml_free(version_directive);
+ while (tag_directives.start != tag_directives.end) {
+ yaml_free(tag_directives.end[-1].handle);
+ yaml_free(tag_directives.end[-1].prefix);
+ tag_directives.end --;
+ }
+ yaml_free(tag_directives.start);
+ return 0;
+}
+
+/*
+ * Parse the productions:
+ * explicit_document ::= DIRECTIVE* DOCUMENT-START block_node? DOCUMENT-END*
+ * ***********
+ */
+
+static int
+yaml_parser_parse_document_content(yaml_parser_t *parser, yaml_event_t *event)
+{
+ yaml_token_t *token;
+
+ token = PEEK_TOKEN(parser);
+ if (!token) return 0;
+
+ if (token->type == YAML_VERSION_DIRECTIVE_TOKEN ||
+ token->type == YAML_TAG_DIRECTIVE_TOKEN ||
+ token->type == YAML_DOCUMENT_START_TOKEN ||
+ token->type == YAML_DOCUMENT_END_TOKEN ||
+ token->type == YAML_STREAM_END_TOKEN) {
+ parser->state = POP(parser, parser->states);
+ return yaml_parser_process_empty_scalar(parser, event,
+ token->start_mark);
+ }
+ else {
+ return yaml_parser_parse_node(parser, event, 1, 0);
+ }
+}
+
+/*
+ * Parse the productions:
+ * implicit_document ::= block_node DOCUMENT-END*
+ * *************
+ * explicit_document ::= DIRECTIVE* DOCUMENT-START block_node? DOCUMENT-END*
+ * *************
+ */
+
+static int
+yaml_parser_parse_document_end(yaml_parser_t *parser, yaml_event_t *event)
+{
+ yaml_token_t *token;
+ yaml_mark_t start_mark, end_mark;
+ int implicit = 1;
+
+ token = PEEK_TOKEN(parser);
+ if (!token) return 0;
+
+ start_mark = end_mark = token->start_mark;
+
+ if (token->type == YAML_DOCUMENT_END_TOKEN) {
+ end_mark = token->end_mark;
+ SKIP_TOKEN(parser);
+ implicit = 0;
+ }
+
+ while (!STACK_EMPTY(parser, parser->tag_directives)) {
+ yaml_tag_directive_t tag_directive = POP(parser, parser->tag_directives);
+ yaml_free(tag_directive.handle);
+ yaml_free(tag_directive.prefix);
+ }
+
+ parser->state = YAML_PARSE_DOCUMENT_START_STATE;
+ DOCUMENT_END_EVENT_INIT(*event, implicit, start_mark, end_mark);
+
+ return 1;
+}
+
+/*
+ * Parse the productions:
+ * block_node_or_indentless_sequence ::=
+ * ALIAS
+ * *****
+ * | properties (block_content | indentless_block_sequence)?
+ * ********** *
+ * | block_content | indentless_block_sequence
+ * *
+ * block_node ::= ALIAS
+ * *****
+ * | properties block_content?
+ * ********** *
+ * | block_content
+ * *
+ * flow_node ::= ALIAS
+ * *****
+ * | properties flow_content?
+ * ********** *
+ * | flow_content
+ * *
+ * properties ::= TAG ANCHOR? | ANCHOR TAG?
+ * *************************
+ * block_content ::= block_collection | flow_collection | SCALAR
+ * ******
+ * flow_content ::= flow_collection | SCALAR
+ * ******
+ */
+
+static int
+yaml_parser_parse_node(yaml_parser_t *parser, yaml_event_t *event,
+ int block, int indentless_sequence)
+{
+ yaml_token_t *token;
+ yaml_char_t *anchor = NULL;
+ yaml_char_t *tag_handle = NULL;
+ yaml_char_t *tag_suffix = NULL;
+ yaml_char_t *tag = NULL;
+ yaml_mark_t start_mark, end_mark, tag_mark;
+ int implicit;
+
+ token = PEEK_TOKEN(parser);
+ if (!token) return 0;
+
+ if (token->type == YAML_ALIAS_TOKEN)
+ {
+ parser->state = POP(parser, parser->states);
+ ALIAS_EVENT_INIT(*event, token->data.alias.value,
+ token->start_mark, token->end_mark);
+ SKIP_TOKEN(parser);
+ return 1;
+ }
+
+ else
+ {
+ start_mark = end_mark = token->start_mark;
+
+ if (token->type == YAML_ANCHOR_TOKEN)
+ {
+ anchor = token->data.anchor.value;
+ start_mark = token->start_mark;
+ end_mark = token->end_mark;
+ SKIP_TOKEN(parser);
+ token = PEEK_TOKEN(parser);
+ if (!token) goto error;
+ if (token->type == YAML_TAG_TOKEN)
+ {
+ tag_handle = token->data.tag.handle;
+ tag_suffix = token->data.tag.suffix;
+ tag_mark = token->start_mark;
+ end_mark = token->end_mark;
+ SKIP_TOKEN(parser);
+ token = PEEK_TOKEN(parser);
+ if (!token) goto error;
+ }
+ }
+ else if (token->type == YAML_TAG_TOKEN)
+ {
+ tag_handle = token->data.tag.handle;
+ tag_suffix = token->data.tag.suffix;
+ start_mark = tag_mark = token->start_mark;
+ end_mark = token->end_mark;
+ SKIP_TOKEN(parser);
+ token = PEEK_TOKEN(parser);
+ if (!token) goto error;
+ if (token->type == YAML_ANCHOR_TOKEN)
+ {
+ anchor = token->data.anchor.value;
+ end_mark = token->end_mark;
+ SKIP_TOKEN(parser);
+ token = PEEK_TOKEN(parser);
+ if (!token) goto error;
+ }
+ }
+
+ if (tag_handle) {
+ if (!*tag_handle) {
+ tag = tag_suffix;
+ yaml_free(tag_handle);
+ tag_handle = tag_suffix = NULL;
+ }
+ else {
+ yaml_tag_directive_t *tag_directive;
+ for (tag_directive = parser->tag_directives.start;
+ tag_directive != parser->tag_directives.top;
+ tag_directive ++) {
+ if (strcmp((char *)tag_directive->handle, (char *)tag_handle) == 0) {
+ size_t prefix_len = strlen((char *)tag_directive->prefix);
+ size_t suffix_len = strlen((char *)tag_suffix);
+ tag = yaml_malloc(prefix_len+suffix_len+1);
+ if (!tag) {
+ parser->error = YAML_MEMORY_ERROR;
+ goto error;
+ }
+ memcpy(tag, tag_directive->prefix, prefix_len);
+ memcpy(tag+prefix_len, tag_suffix, suffix_len);
+ tag[prefix_len+suffix_len] = '\0';
+ yaml_free(tag_handle);
+ yaml_free(tag_suffix);
+ tag_handle = tag_suffix = NULL;
+ break;
+ }
+ }
+ if (!tag) {
+ yaml_parser_set_parser_error_context(parser,
+ "while parsing a node", start_mark,
+ "found undefined tag handle", tag_mark);
+ goto error;
+ }
+ }
+ }
+
+ implicit = (!tag || !*tag);
+ if (indentless_sequence && token->type == YAML_BLOCK_ENTRY_TOKEN) {
+ end_mark = token->end_mark;
+ parser->state = YAML_PARSE_INDENTLESS_SEQUENCE_ENTRY_STATE;
+ SEQUENCE_START_EVENT_INIT(*event, anchor, tag, implicit,
+ YAML_BLOCK_SEQUENCE_STYLE, start_mark, end_mark);
+ return 1;
+ }
+ else {
+ if (token->type == YAML_SCALAR_TOKEN) {
+ int plain_implicit = 0;
+ int quoted_implicit = 0;
+ end_mark = token->end_mark;
+ if ((token->data.scalar.style == YAML_PLAIN_SCALAR_STYLE && !tag)
+ || (tag && strcmp((char *)tag, "!") == 0)) {
+ plain_implicit = 1;
+ }
+ else if (!tag) {
+ quoted_implicit = 1;
+ }
+ parser->state = POP(parser, parser->states);
+ SCALAR_EVENT_INIT(*event, anchor, tag,
+ token->data.scalar.value, token->data.scalar.length,
+ plain_implicit, quoted_implicit,
+ token->data.scalar.style, start_mark, end_mark);
+ SKIP_TOKEN(parser);
+ return 1;
+ }
+ else if (token->type == YAML_FLOW_SEQUENCE_START_TOKEN) {
+ end_mark = token->end_mark;
+ parser->state = YAML_PARSE_FLOW_SEQUENCE_FIRST_ENTRY_STATE;
+ SEQUENCE_START_EVENT_INIT(*event, anchor, tag, implicit,
+ YAML_FLOW_SEQUENCE_STYLE, start_mark, end_mark);
+ return 1;
+ }
+ else if (token->type == YAML_FLOW_MAPPING_START_TOKEN) {
+ end_mark = token->end_mark;
+ parser->state = YAML_PARSE_FLOW_MAPPING_FIRST_KEY_STATE;
+ MAPPING_START_EVENT_INIT(*event, anchor, tag, implicit,
+ YAML_FLOW_MAPPING_STYLE, start_mark, end_mark);
+ return 1;
+ }
+ else if (block && token->type == YAML_BLOCK_SEQUENCE_START_TOKEN) {
+ end_mark = token->end_mark;
+ parser->state = YAML_PARSE_BLOCK_SEQUENCE_FIRST_ENTRY_STATE;
+ SEQUENCE_START_EVENT_INIT(*event, anchor, tag, implicit,
+ YAML_BLOCK_SEQUENCE_STYLE, start_mark, end_mark);
+ return 1;
+ }
+ else if (block && token->type == YAML_BLOCK_MAPPING_START_TOKEN) {
+ end_mark = token->end_mark;
+ parser->state = YAML_PARSE_BLOCK_MAPPING_FIRST_KEY_STATE;
+ MAPPING_START_EVENT_INIT(*event, anchor, tag, implicit,
+ YAML_BLOCK_MAPPING_STYLE, start_mark, end_mark);
+ return 1;
+ }
+ else if (anchor || tag) {
+ yaml_char_t *value = yaml_malloc(1);
+ if (!value) {
+ parser->error = YAML_MEMORY_ERROR;
+ goto error;
+ }
+ value[0] = '\0';
+ parser->state = POP(parser, parser->states);
+ SCALAR_EVENT_INIT(*event, anchor, tag, value, 0,
+ implicit, 0, YAML_PLAIN_SCALAR_STYLE,
+ start_mark, end_mark);
+ return 1;
+ }
+ else {
+ yaml_parser_set_parser_error_context(parser,
+ (block ? "while parsing a block node"
+ : "while parsing a flow node"), start_mark,
+ "did not find expected node content", token->start_mark);
+ goto error;
+ }
+ }
+ }
+
+error:
+ yaml_free(anchor);
+ yaml_free(tag_handle);
+ yaml_free(tag_suffix);
+ yaml_free(tag);
+
+ return 0;
+}
+
+/*
+ * Parse the productions:
+ * block_sequence ::= BLOCK-SEQUENCE-START (BLOCK-ENTRY block_node?)* BLOCK-END
+ * ******************** *********** * *********
+ */
+
+static int
+yaml_parser_parse_block_sequence_entry(yaml_parser_t *parser,
+ yaml_event_t *event, int first)
+{
+ yaml_token_t *token;
+
+ if (first) {
+ token = PEEK_TOKEN(parser);
+ if (!PUSH(parser, parser->marks, token->start_mark))
+ return 0;
+ SKIP_TOKEN(parser);
+ }
+
+ token = PEEK_TOKEN(parser);
+ if (!token) return 0;
+
+ if (token->type == YAML_BLOCK_ENTRY_TOKEN)
+ {
+ yaml_mark_t mark = token->end_mark;
+ SKIP_TOKEN(parser);
+ token = PEEK_TOKEN(parser);
+ if (!token) return 0;
+ if (token->type != YAML_BLOCK_ENTRY_TOKEN &&
+ token->type != YAML_BLOCK_END_TOKEN) {
+ if (!PUSH(parser, parser->states,
+ YAML_PARSE_BLOCK_SEQUENCE_ENTRY_STATE))
+ return 0;
+ return yaml_parser_parse_node(parser, event, 1, 0);
+ }
+ else {
+ parser->state = YAML_PARSE_BLOCK_SEQUENCE_ENTRY_STATE;
+ return yaml_parser_process_empty_scalar(parser, event, mark);
+ }
+ }
+
+ else if (token->type == YAML_BLOCK_END_TOKEN)
+ {
+ yaml_mark_t dummy_mark; /* Used to eliminate a compiler warning. */
+ parser->state = POP(parser, parser->states);
+ dummy_mark = POP(parser, parser->marks);
+ SEQUENCE_END_EVENT_INIT(*event, token->start_mark, token->end_mark);
+ SKIP_TOKEN(parser);
+ return 1;
+ }
+
+ else
+ {
+ return yaml_parser_set_parser_error_context(parser,
+ "while parsing a block collection", POP(parser, parser->marks),
+ "did not find expected '-' indicator", token->start_mark);
+ }
+}
+
+/*
+ * Parse the productions:
+ * indentless_sequence ::= (BLOCK-ENTRY block_node?)+
+ * *********** *
+ */
+
+static int
+yaml_parser_parse_indentless_sequence_entry(yaml_parser_t *parser,
+ yaml_event_t *event)
+{
+ yaml_token_t *token;
+
+ token = PEEK_TOKEN(parser);
+ if (!token) return 0;
+
+ if (token->type == YAML_BLOCK_ENTRY_TOKEN)
+ {
+ yaml_mark_t mark = token->end_mark;
+ SKIP_TOKEN(parser);
+ token = PEEK_TOKEN(parser);
+ if (!token) return 0;
+ if (token->type != YAML_BLOCK_ENTRY_TOKEN &&
+ token->type != YAML_KEY_TOKEN &&
+ token->type != YAML_VALUE_TOKEN &&
+ token->type != YAML_BLOCK_END_TOKEN) {
+ if (!PUSH(parser, parser->states,
+ YAML_PARSE_INDENTLESS_SEQUENCE_ENTRY_STATE))
+ return 0;
+ return yaml_parser_parse_node(parser, event, 1, 0);
+ }
+ else {
+ parser->state = YAML_PARSE_INDENTLESS_SEQUENCE_ENTRY_STATE;
+ return yaml_parser_process_empty_scalar(parser, event, mark);
+ }
+ }
+
+ else
+ {
+ parser->state = POP(parser, parser->states);
+ SEQUENCE_END_EVENT_INIT(*event, token->start_mark, token->start_mark);
+ return 1;
+ }
+}
+
+/*
+ * Parse the productions:
+ * block_mapping ::= BLOCK-MAPPING_START
+ * *******************
+ * ((KEY block_node_or_indentless_sequence?)?
+ * *** *
+ * (VALUE block_node_or_indentless_sequence?)?)*
+ *
+ * BLOCK-END
+ * *********
+ */
+
+static int
+yaml_parser_parse_block_mapping_key(yaml_parser_t *parser,
+ yaml_event_t *event, int first)
+{
+ yaml_token_t *token;
+
+ if (first) {
+ token = PEEK_TOKEN(parser);
+ if (!PUSH(parser, parser->marks, token->start_mark))
+ return 0;
+ SKIP_TOKEN(parser);
+ }
+
+ token = PEEK_TOKEN(parser);
+ if (!token) return 0;
+
+ if (token->type == YAML_KEY_TOKEN)
+ {
+ yaml_mark_t mark = token->end_mark;
+ SKIP_TOKEN(parser);
+ token = PEEK_TOKEN(parser);
+ if (!token) return 0;
+ if (token->type != YAML_KEY_TOKEN &&
+ token->type != YAML_VALUE_TOKEN &&
+ token->type != YAML_BLOCK_END_TOKEN) {
+ if (!PUSH(parser, parser->states,
+ YAML_PARSE_BLOCK_MAPPING_VALUE_STATE))
+ return 0;
+ return yaml_parser_parse_node(parser, event, 1, 1);
+ }
+ else {
+ parser->state = YAML_PARSE_BLOCK_MAPPING_VALUE_STATE;
+ return yaml_parser_process_empty_scalar(parser, event, mark);
+ }
+ }
+
+ else if (token->type == YAML_BLOCK_END_TOKEN)
+ {
+ yaml_mark_t dummy_mark; /* Used to eliminate a compiler warning. */
+ parser->state = POP(parser, parser->states);
+ dummy_mark = POP(parser, parser->marks);
+ MAPPING_END_EVENT_INIT(*event, token->start_mark, token->end_mark);
+ SKIP_TOKEN(parser);
+ return 1;
+ }
+
+ else
+ {
+ return yaml_parser_set_parser_error_context(parser,
+ "while parsing a block mapping", POP(parser, parser->marks),
+ "did not find expected key", token->start_mark);
+ }
+}
+
+/*
+ * Parse the productions:
+ * block_mapping ::= BLOCK-MAPPING_START
+ *
+ * ((KEY block_node_or_indentless_sequence?)?
+ *
+ * (VALUE block_node_or_indentless_sequence?)?)*
+ * ***** *
+ * BLOCK-END
+ *
+ */
+
+static int
+yaml_parser_parse_block_mapping_value(yaml_parser_t *parser,
+ yaml_event_t *event)
+{
+ yaml_token_t *token;
+
+ token = PEEK_TOKEN(parser);
+ if (!token) return 0;
+
+ if (token->type == YAML_VALUE_TOKEN)
+ {
+ yaml_mark_t mark = token->end_mark;
+ SKIP_TOKEN(parser);
+ token = PEEK_TOKEN(parser);
+ if (!token) return 0;
+ if (token->type != YAML_KEY_TOKEN &&
+ token->type != YAML_VALUE_TOKEN &&
+ token->type != YAML_BLOCK_END_TOKEN) {
+ if (!PUSH(parser, parser->states,
+ YAML_PARSE_BLOCK_MAPPING_KEY_STATE))
+ return 0;
+ return yaml_parser_parse_node(parser, event, 1, 1);
+ }
+ else {
+ parser->state = YAML_PARSE_BLOCK_MAPPING_KEY_STATE;
+ return yaml_parser_process_empty_scalar(parser, event, mark);
+ }
+ }
+
+ else
+ {
+ parser->state = YAML_PARSE_BLOCK_MAPPING_KEY_STATE;
+ return yaml_parser_process_empty_scalar(parser, event, token->start_mark);
+ }
+}
+
+/*
+ * Parse the productions:
+ * flow_sequence ::= FLOW-SEQUENCE-START
+ * *******************
+ * (flow_sequence_entry FLOW-ENTRY)*
+ * * **********
+ * flow_sequence_entry?
+ * *
+ * FLOW-SEQUENCE-END
+ * *****************
+ * flow_sequence_entry ::= flow_node | KEY flow_node? (VALUE flow_node?)?
+ * *
+ */
+
+static int
+yaml_parser_parse_flow_sequence_entry(yaml_parser_t *parser,
+ yaml_event_t *event, int first)
+{
+ yaml_token_t *token;
+ yaml_mark_t dummy_mark; /* Used to eliminate a compiler warning. */
+
+ if (first) {
+ token = PEEK_TOKEN(parser);
+ if (!PUSH(parser, parser->marks, token->start_mark))
+ return 0;
+ SKIP_TOKEN(parser);
+ }
+
+ token = PEEK_TOKEN(parser);
+ if (!token) return 0;
+
+ if (token->type != YAML_FLOW_SEQUENCE_END_TOKEN)
+ {
+ if (!first) {
+ if (token->type == YAML_FLOW_ENTRY_TOKEN) {
+ SKIP_TOKEN(parser);
+ token = PEEK_TOKEN(parser);
+ if (!token) return 0;
+ }
+ else {
+ return yaml_parser_set_parser_error_context(parser,
+ "while parsing a flow sequence", POP(parser, parser->marks),
+ "did not find expected ',' or ']'", token->start_mark);
+ }
+ }
+
+ if (token->type == YAML_KEY_TOKEN) {
+ parser->state = YAML_PARSE_FLOW_SEQUENCE_ENTRY_MAPPING_KEY_STATE;
+ MAPPING_START_EVENT_INIT(*event, NULL, NULL,
+ 1, YAML_FLOW_MAPPING_STYLE,
+ token->start_mark, token->end_mark);
+ SKIP_TOKEN(parser);
+ return 1;
+ }
+
+ else if (token->type != YAML_FLOW_SEQUENCE_END_TOKEN) {
+ if (!PUSH(parser, parser->states,
+ YAML_PARSE_FLOW_SEQUENCE_ENTRY_STATE))
+ return 0;
+ return yaml_parser_parse_node(parser, event, 0, 0);
+ }
+ }
+
+ parser->state = POP(parser, parser->states);
+ dummy_mark = POP(parser, parser->marks);
+ SEQUENCE_END_EVENT_INIT(*event, token->start_mark, token->end_mark);
+ SKIP_TOKEN(parser);
+ return 1;
+}
+
+/*
+ * Parse the productions:
+ * flow_sequence_entry ::= flow_node | KEY flow_node? (VALUE flow_node?)?
+ * *** *
+ */
+
+static int
+yaml_parser_parse_flow_sequence_entry_mapping_key(yaml_parser_t *parser,
+ yaml_event_t *event)
+{
+ yaml_token_t *token;
+
+ token = PEEK_TOKEN(parser);
+ if (!token) return 0;
+
+ if (token->type != YAML_VALUE_TOKEN && token->type != YAML_FLOW_ENTRY_TOKEN
+ && token->type != YAML_FLOW_SEQUENCE_END_TOKEN) {
+ if (!PUSH(parser, parser->states,
+ YAML_PARSE_FLOW_SEQUENCE_ENTRY_MAPPING_VALUE_STATE))
+ return 0;
+ return yaml_parser_parse_node(parser, event, 0, 0);
+ }
+ else {
+ yaml_mark_t mark = token->end_mark;
+ SKIP_TOKEN(parser);
+ parser->state = YAML_PARSE_FLOW_SEQUENCE_ENTRY_MAPPING_VALUE_STATE;
+ return yaml_parser_process_empty_scalar(parser, event, mark);
+ }
+}
+
+/*
+ * Parse the productions:
+ * flow_sequence_entry ::= flow_node | KEY flow_node? (VALUE flow_node?)?
+ * ***** *
+ */
+
+static int
+yaml_parser_parse_flow_sequence_entry_mapping_value(yaml_parser_t *parser,
+ yaml_event_t *event)
+{
+ yaml_token_t *token;
+
+ token = PEEK_TOKEN(parser);
+ if (!token) return 0;
+
+ if (token->type == YAML_VALUE_TOKEN) {
+ SKIP_TOKEN(parser);
+ token = PEEK_TOKEN(parser);
+ if (!token) return 0;
+ if (token->type != YAML_FLOW_ENTRY_TOKEN
+ && token->type != YAML_FLOW_SEQUENCE_END_TOKEN) {
+ if (!PUSH(parser, parser->states,
+ YAML_PARSE_FLOW_SEQUENCE_ENTRY_MAPPING_END_STATE))
+ return 0;
+ return yaml_parser_parse_node(parser, event, 0, 0);
+ }
+ }
+ parser->state = YAML_PARSE_FLOW_SEQUENCE_ENTRY_MAPPING_END_STATE;
+ return yaml_parser_process_empty_scalar(parser, event, token->start_mark);
+}
+
+/*
+ * Parse the productions:
+ * flow_sequence_entry ::= flow_node | KEY flow_node? (VALUE flow_node?)?
+ * *
+ */
+
+static int
+yaml_parser_parse_flow_sequence_entry_mapping_end(yaml_parser_t *parser,
+ yaml_event_t *event)
+{
+ yaml_token_t *token;
+
+ token = PEEK_TOKEN(parser);
+ if (!token) return 0;
+
+ parser->state = YAML_PARSE_FLOW_SEQUENCE_ENTRY_STATE;
+
+ MAPPING_END_EVENT_INIT(*event, token->start_mark, token->start_mark);
+ return 1;
+}
+
+/*
+ * Parse the productions:
+ * flow_mapping ::= FLOW-MAPPING-START
+ * ******************
+ * (flow_mapping_entry FLOW-ENTRY)*
+ * * **********
+ * flow_mapping_entry?
+ * ******************
+ * FLOW-MAPPING-END
+ * ****************
+ * flow_mapping_entry ::= flow_node | KEY flow_node? (VALUE flow_node?)?
+ * * *** *
+ */
+
+static int
+yaml_parser_parse_flow_mapping_key(yaml_parser_t *parser,
+ yaml_event_t *event, int first)
+{
+ yaml_token_t *token;
+ yaml_mark_t dummy_mark; /* Used to eliminate a compiler warning. */
+
+ if (first) {
+ token = PEEK_TOKEN(parser);
+ if (!PUSH(parser, parser->marks, token->start_mark))
+ return 0;
+ SKIP_TOKEN(parser);
+ }
+
+ token = PEEK_TOKEN(parser);
+ if (!token) return 0;
+
+ if (token->type != YAML_FLOW_MAPPING_END_TOKEN)
+ {
+ if (!first) {
+ if (token->type == YAML_FLOW_ENTRY_TOKEN) {
+ SKIP_TOKEN(parser);
+ token = PEEK_TOKEN(parser);
+ if (!token) return 0;
+ }
+ else {
+ return yaml_parser_set_parser_error_context(parser,
+ "while parsing a flow mapping", POP(parser, parser->marks),
+ "did not find expected ',' or '}'", token->start_mark);
+ }
+ }
+
+ if (token->type == YAML_KEY_TOKEN) {
+ SKIP_TOKEN(parser);
+ token = PEEK_TOKEN(parser);
+ if (!token) return 0;
+ if (token->type != YAML_VALUE_TOKEN
+ && token->type != YAML_FLOW_ENTRY_TOKEN
+ && token->type != YAML_FLOW_MAPPING_END_TOKEN) {
+ if (!PUSH(parser, parser->states,
+ YAML_PARSE_FLOW_MAPPING_VALUE_STATE))
+ return 0;
+ return yaml_parser_parse_node(parser, event, 0, 0);
+ }
+ else {
+ parser->state = YAML_PARSE_FLOW_MAPPING_VALUE_STATE;
+ return yaml_parser_process_empty_scalar(parser, event,
+ token->start_mark);
+ }
+ }
+ else if (token->type != YAML_FLOW_MAPPING_END_TOKEN) {
+ if (!PUSH(parser, parser->states,
+ YAML_PARSE_FLOW_MAPPING_EMPTY_VALUE_STATE))
+ return 0;
+ return yaml_parser_parse_node(parser, event, 0, 0);
+ }
+ }
+
+ parser->state = POP(parser, parser->states);
+ dummy_mark = POP(parser, parser->marks);
+ MAPPING_END_EVENT_INIT(*event, token->start_mark, token->end_mark);
+ SKIP_TOKEN(parser);
+ return 1;
+}
+
+/*
+ * Parse the productions:
+ * flow_mapping_entry ::= flow_node | KEY flow_node? (VALUE flow_node?)?
+ * * ***** *
+ */
+
+static int
+yaml_parser_parse_flow_mapping_value(yaml_parser_t *parser,
+ yaml_event_t *event, int empty)
+{
+ yaml_token_t *token;
+
+ token = PEEK_TOKEN(parser);
+ if (!token) return 0;
+
+ if (empty) {
+ parser->state = YAML_PARSE_FLOW_MAPPING_KEY_STATE;
+ return yaml_parser_process_empty_scalar(parser, event,
+ token->start_mark);
+ }
+
+ if (token->type == YAML_VALUE_TOKEN) {
+ SKIP_TOKEN(parser);
+ token = PEEK_TOKEN(parser);
+ if (!token) return 0;
+ if (token->type != YAML_FLOW_ENTRY_TOKEN
+ && token->type != YAML_FLOW_MAPPING_END_TOKEN) {
+ if (!PUSH(parser, parser->states,
+ YAML_PARSE_FLOW_MAPPING_KEY_STATE))
+ return 0;
+ return yaml_parser_parse_node(parser, event, 0, 0);
+ }
+ }
+
+ parser->state = YAML_PARSE_FLOW_MAPPING_KEY_STATE;
+ return yaml_parser_process_empty_scalar(parser, event, token->start_mark);
+}
+
+/*
+ * Generate an empty scalar event.
+ */
+
+static int
+yaml_parser_process_empty_scalar(yaml_parser_t *parser, yaml_event_t *event,
+ yaml_mark_t mark)
+{
+ yaml_char_t *value;
+
+ value = yaml_malloc(1);
+ if (!value) {
+ parser->error = YAML_MEMORY_ERROR;
+ return 0;
+ }
+ value[0] = '\0';
+
+ SCALAR_EVENT_INIT(*event, NULL, NULL, value, 0,
+ 1, 0, YAML_PLAIN_SCALAR_STYLE, mark, mark);
+
+ return 1;
+}
+
+/*
+ * Parse directives.
+ */
+
+static int
+yaml_parser_process_directives(yaml_parser_t *parser,
+ yaml_version_directive_t **version_directive_ref,
+ yaml_tag_directive_t **tag_directives_start_ref,
+ yaml_tag_directive_t **tag_directives_end_ref)
+{
+ yaml_tag_directive_t default_tag_directives[] = {
+ {(yaml_char_t *)"!", (yaml_char_t *)"!"},
+ {(yaml_char_t *)"!!", (yaml_char_t *)"tag:yaml.org,2002:"},
+ {NULL, NULL}
+ };
+ yaml_tag_directive_t *default_tag_directive;
+ yaml_version_directive_t *version_directive = NULL;
+ struct {
+ yaml_tag_directive_t *start;
+ yaml_tag_directive_t *end;
+ yaml_tag_directive_t *top;
+ } tag_directives = { NULL, NULL, NULL };
+ yaml_token_t *token;
+
+ if (!STACK_INIT(parser, tag_directives, INITIAL_STACK_SIZE))
+ goto error;
+
+ token = PEEK_TOKEN(parser);
+ if (!token) goto error;
+
+ while (token->type == YAML_VERSION_DIRECTIVE_TOKEN ||
+ token->type == YAML_TAG_DIRECTIVE_TOKEN)
+ {
+ if (token->type == YAML_VERSION_DIRECTIVE_TOKEN) {
+ if (version_directive) {
+ yaml_parser_set_parser_error(parser,
+ "found duplicate %YAML directive", token->start_mark);
+ goto error;
+ }
+ if (token->data.version_directive.major != 1
+ || token->data.version_directive.minor != 1) {
+ yaml_parser_set_parser_error(parser,
+ "found incompatible YAML document", token->start_mark);
+ goto error;
+ }
+ version_directive = yaml_malloc(sizeof(yaml_version_directive_t));
+ if (!version_directive) {
+ parser->error = YAML_MEMORY_ERROR;
+ goto error;
+ }
+ version_directive->major = token->data.version_directive.major;
+ version_directive->minor = token->data.version_directive.minor;
+ }
+
+ else if (token->type == YAML_TAG_DIRECTIVE_TOKEN) {
+ yaml_tag_directive_t value;
+ value.handle = token->data.tag_directive.handle;
+ value.prefix = token->data.tag_directive.prefix;
+
+ if (!yaml_parser_append_tag_directive(parser, value, 0,
+ token->start_mark))
+ goto error;
+ if (!PUSH(parser, tag_directives, value))
+ goto error;
+ }
+
+ SKIP_TOKEN(parser);
+ token = PEEK_TOKEN(parser);
+ if (!token) goto error;
+ }
+
+ for (default_tag_directive = default_tag_directives;
+ default_tag_directive->handle; default_tag_directive++) {
+ if (!yaml_parser_append_tag_directive(parser, *default_tag_directive, 1,
+ token->start_mark))
+ goto error;
+ }
+
+ if (version_directive_ref) {
+ *version_directive_ref = version_directive;
+ }
+ if (tag_directives_start_ref) {
+ if (STACK_EMPTY(parser, tag_directives)) {
+ *tag_directives_start_ref = *tag_directives_end_ref = NULL;
+ STACK_DEL(parser, tag_directives);
+ }
+ else {
+ *tag_directives_start_ref = tag_directives.start;
+ *tag_directives_end_ref = tag_directives.top;
+ }
+ }
+ else {
+ STACK_DEL(parser, tag_directives);
+ }
+
+ return 1;
+
+error:
+ yaml_free(version_directive);
+ while (!STACK_EMPTY(parser, tag_directives)) {
+ yaml_tag_directive_t tag_directive = POP(parser, tag_directives);
+ yaml_free(tag_directive.handle);
+ yaml_free(tag_directive.prefix);
+ }
+ STACK_DEL(parser, tag_directives);
+ return 0;
+}
+
+/*
+ * Append a tag directive to the directives stack.
+ */
+
+static int
+yaml_parser_append_tag_directive(yaml_parser_t *parser,
+ yaml_tag_directive_t value, int allow_duplicates, yaml_mark_t mark)
+{
+ yaml_tag_directive_t *tag_directive;
+ yaml_tag_directive_t copy = { NULL, NULL };
+
+ for (tag_directive = parser->tag_directives.start;
+ tag_directive != parser->tag_directives.top; tag_directive ++) {
+ if (strcmp((char *)value.handle, (char *)tag_directive->handle) == 0) {
+ if (allow_duplicates)
+ return 1;
+ return yaml_parser_set_parser_error(parser,
+ "found duplicate %TAG directive", mark);
+ }
+ }
+
+ copy.handle = yaml_strdup(value.handle);
+ copy.prefix = yaml_strdup(value.prefix);
+ if (!copy.handle || !copy.prefix) {
+ parser->error = YAML_MEMORY_ERROR;
+ goto error;
+ }
+
+ if (!PUSH(parser, parser->tag_directives, copy))
+ goto error;
+
+ return 1;
+
+error:
+ yaml_free(copy.handle);
+ yaml_free(copy.prefix);
+ return 0;
+}
+
diff --git a/contrib/libyaml/src/reader.c b/contrib/libyaml/src/reader.c
new file mode 100644
index 0000000..829e32d
--- /dev/null
+++ b/contrib/libyaml/src/reader.c
@@ -0,0 +1,465 @@
+
+#include "yaml_private.h"
+
+/*
+ * Declarations.
+ */
+
+static int
+yaml_parser_set_reader_error(yaml_parser_t *parser, const char *problem,
+ size_t offset, int value);
+
+static int
+yaml_parser_update_raw_buffer(yaml_parser_t *parser);
+
+static int
+yaml_parser_determine_encoding(yaml_parser_t *parser);
+
+YAML_DECLARE(int)
+yaml_parser_update_buffer(yaml_parser_t *parser, size_t length);
+
+/*
+ * Set the reader error and return 0.
+ */
+
+static int
+yaml_parser_set_reader_error(yaml_parser_t *parser, const char *problem,
+ size_t offset, int value)
+{
+ parser->error = YAML_READER_ERROR;
+ parser->problem = problem;
+ parser->problem_offset = offset;
+ parser->problem_value = value;
+
+ return 0;
+}
+
+/*
+ * Byte order marks.
+ */
+
+#define BOM_UTF8 "\xef\xbb\xbf"
+#define BOM_UTF16LE "\xff\xfe"
+#define BOM_UTF16BE "\xfe\xff"
+
+/*
+ * Determine the input stream encoding by checking the BOM symbol. If no BOM is
+ * found, the UTF-8 encoding is assumed. Return 1 on success, 0 on failure.
+ */
+
+static int
+yaml_parser_determine_encoding(yaml_parser_t *parser)
+{
+ /* Ensure that we had enough bytes in the raw buffer. */
+
+ while (!parser->eof
+ && parser->raw_buffer.last - parser->raw_buffer.pointer < 3) {
+ if (!yaml_parser_update_raw_buffer(parser)) {
+ return 0;
+ }
+ }
+
+ /* Determine the encoding. */
+
+ if (parser->raw_buffer.last - parser->raw_buffer.pointer >= 2
+ && !memcmp(parser->raw_buffer.pointer, BOM_UTF16LE, 2)) {
+ parser->encoding = YAML_UTF16LE_ENCODING;
+ parser->raw_buffer.pointer += 2;
+ parser->offset += 2;
+ }
+ else if (parser->raw_buffer.last - parser->raw_buffer.pointer >= 2
+ && !memcmp(parser->raw_buffer.pointer, BOM_UTF16BE, 2)) {
+ parser->encoding = YAML_UTF16BE_ENCODING;
+ parser->raw_buffer.pointer += 2;
+ parser->offset += 2;
+ }
+ else if (parser->raw_buffer.last - parser->raw_buffer.pointer >= 3
+ && !memcmp(parser->raw_buffer.pointer, BOM_UTF8, 3)) {
+ parser->encoding = YAML_UTF8_ENCODING;
+ parser->raw_buffer.pointer += 3;
+ parser->offset += 3;
+ }
+ else {
+ parser->encoding = YAML_UTF8_ENCODING;
+ }
+
+ return 1;
+}
+
+/*
+ * Update the raw buffer.
+ */
+
+static int
+yaml_parser_update_raw_buffer(yaml_parser_t *parser)
+{
+ size_t size_read = 0;
+
+ /* Return if the raw buffer is full. */
+
+ if (parser->raw_buffer.start == parser->raw_buffer.pointer
+ && parser->raw_buffer.last == parser->raw_buffer.end)
+ return 1;
+
+ /* Return on EOF. */
+
+ if (parser->eof) return 1;
+
+ /* Move the remaining bytes in the raw buffer to the beginning. */
+
+ if (parser->raw_buffer.start < parser->raw_buffer.pointer
+ && parser->raw_buffer.pointer < parser->raw_buffer.last) {
+ memmove(parser->raw_buffer.start, parser->raw_buffer.pointer,
+ parser->raw_buffer.last - parser->raw_buffer.pointer);
+ }
+ parser->raw_buffer.last -=
+ parser->raw_buffer.pointer - parser->raw_buffer.start;
+ parser->raw_buffer.pointer = parser->raw_buffer.start;
+
+ /* Call the read handler to fill the buffer. */
+
+ if (!parser->read_handler(parser->read_handler_data, parser->raw_buffer.last,
+ parser->raw_buffer.end - parser->raw_buffer.last, &size_read)) {
+ return yaml_parser_set_reader_error(parser, "input error",
+ parser->offset, -1);
+ }
+ parser->raw_buffer.last += size_read;
+ if (!size_read) {
+ parser->eof = 1;
+ }
+
+ return 1;
+}
+
+/*
+ * Ensure that the buffer contains at least `length` characters.
+ * Return 1 on success, 0 on failure.
+ *
+ * The length is supposed to be significantly less that the buffer size.
+ */
+
+YAML_DECLARE(int)
+yaml_parser_update_buffer(yaml_parser_t *parser, size_t length)
+{
+ int first = 1;
+
+ assert(parser->read_handler); /* Read handler must be set. */
+
+ /* If the EOF flag is set and the raw buffer is empty, do nothing. */
+
+ if (parser->eof && parser->raw_buffer.pointer == parser->raw_buffer.last)
+ return 1;
+
+ /* Return if the buffer contains enough characters. */
+
+ if (parser->unread >= length)
+ return 1;
+
+ /* Determine the input encoding if it is not known yet. */
+
+ if (!parser->encoding) {
+ if (!yaml_parser_determine_encoding(parser))
+ return 0;
+ }
+
+ /* Move the unread characters to the beginning of the buffer. */
+
+ if (parser->buffer.start < parser->buffer.pointer
+ && parser->buffer.pointer < parser->buffer.last) {
+ size_t size = parser->buffer.last - parser->buffer.pointer;
+ memmove(parser->buffer.start, parser->buffer.pointer, size);
+ parser->buffer.pointer = parser->buffer.start;
+ parser->buffer.last = parser->buffer.start + size;
+ }
+ else if (parser->buffer.pointer == parser->buffer.last) {
+ parser->buffer.pointer = parser->buffer.start;
+ parser->buffer.last = parser->buffer.start;
+ }
+
+ /* Fill the buffer until it has enough characters. */
+
+ while (parser->unread < length)
+ {
+ /* Fill the raw buffer if necessary. */
+
+ if (!first || parser->raw_buffer.pointer == parser->raw_buffer.last) {
+ if (!yaml_parser_update_raw_buffer(parser)) return 0;
+ }
+ first = 0;
+
+ /* Decode the raw buffer. */
+
+ while (parser->raw_buffer.pointer != parser->raw_buffer.last)
+ {
+ unsigned int value = 0, value2 = 0;
+ int incomplete = 0;
+ unsigned char octet;
+ unsigned int width = 0;
+ int low, high;
+ size_t k;
+ size_t raw_unread = parser->raw_buffer.last - parser->raw_buffer.pointer;
+
+ /* Decode the next character. */
+
+ switch (parser->encoding)
+ {
+ case YAML_UTF8_ENCODING:
+
+ /*
+ * Decode a UTF-8 character. Check RFC 3629
+ * (http://www.ietf.org/rfc/rfc3629.txt) for more details.
+ *
+ * The following table (taken from the RFC) is used for
+ * decoding.
+ *
+ * Char. number range | UTF-8 octet sequence
+ * (hexadecimal) | (binary)
+ * --------------------+------------------------------------
+ * 0000 0000-0000 007F | 0xxxxxxx
+ * 0000 0080-0000 07FF | 110xxxxx 10xxxxxx
+ * 0000 0800-0000 FFFF | 1110xxxx 10xxxxxx 10xxxxxx
+ * 0001 0000-0010 FFFF | 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx
+ *
+ * Additionally, the characters in the range 0xD800-0xDFFF
+ * are prohibited as they are reserved for use with UTF-16
+ * surrogate pairs.
+ */
+
+ /* Determine the length of the UTF-8 sequence. */
+
+ octet = parser->raw_buffer.pointer[0];
+ width = (octet & 0x80) == 0x00 ? 1 :
+ (octet & 0xE0) == 0xC0 ? 2 :
+ (octet & 0xF0) == 0xE0 ? 3 :
+ (octet & 0xF8) == 0xF0 ? 4 : 0;
+
+ /* Check if the leading octet is valid. */
+
+ if (!width)
+ return yaml_parser_set_reader_error(parser,
+ "invalid leading UTF-8 octet",
+ parser->offset, octet);
+
+ /* Check if the raw buffer contains an incomplete character. */
+
+ if (width > raw_unread) {
+ if (parser->eof) {
+ return yaml_parser_set_reader_error(parser,
+ "incomplete UTF-8 octet sequence",
+ parser->offset, -1);
+ }
+ incomplete = 1;
+ break;
+ }
+
+ /* Decode the leading octet. */
+
+ value = (octet & 0x80) == 0x00 ? octet & 0x7F :
+ (octet & 0xE0) == 0xC0 ? octet & 0x1F :
+ (octet & 0xF0) == 0xE0 ? octet & 0x0F :
+ (octet & 0xF8) == 0xF0 ? octet & 0x07 : 0;
+
+ /* Check and decode the trailing octets. */
+
+ for (k = 1; k < width; k ++)
+ {
+ octet = parser->raw_buffer.pointer[k];
+
+ /* Check if the octet is valid. */
+
+ if ((octet & 0xC0) != 0x80)
+ return yaml_parser_set_reader_error(parser,
+ "invalid trailing UTF-8 octet",
+ parser->offset+k, octet);
+
+ /* Decode the octet. */
+
+ value = (value << 6) + (octet & 0x3F);
+ }
+
+ /* Check the length of the sequence against the value. */
+
+ if (!((width == 1) ||
+ (width == 2 && value >= 0x80) ||
+ (width == 3 && value >= 0x800) ||
+ (width == 4 && value >= 0x10000)))
+ return yaml_parser_set_reader_error(parser,
+ "invalid length of a UTF-8 sequence",
+ parser->offset, -1);
+
+ /* Check the range of the value. */
+
+ if ((value >= 0xD800 && value <= 0xDFFF) || value > 0x10FFFF)
+ return yaml_parser_set_reader_error(parser,
+ "invalid Unicode character",
+ parser->offset, value);
+
+ break;
+
+ case YAML_UTF16LE_ENCODING:
+ case YAML_UTF16BE_ENCODING:
+
+ low = (parser->encoding == YAML_UTF16LE_ENCODING ? 0 : 1);
+ high = (parser->encoding == YAML_UTF16LE_ENCODING ? 1 : 0);
+
+ /*
+ * The UTF-16 encoding is not as simple as one might
+ * naively think. Check RFC 2781
+ * (http://www.ietf.org/rfc/rfc2781.txt).
+ *
+ * Normally, two subsequent bytes describe a Unicode
+ * character. However a special technique (called a
+ * surrogate pair) is used for specifying character
+ * values larger than 0xFFFF.
+ *
+ * A surrogate pair consists of two pseudo-characters:
+ * high surrogate area (0xD800-0xDBFF)
+ * low surrogate area (0xDC00-0xDFFF)
+ *
+ * The following formulas are used for decoding
+ * and encoding characters using surrogate pairs:
+ *
+ * U = U' + 0x10000 (0x01 00 00 <= U <= 0x10 FF FF)
+ * U' = yyyyyyyyyyxxxxxxxxxx (0 <= U' <= 0x0F FF FF)
+ * W1 = 110110yyyyyyyyyy
+ * W2 = 110111xxxxxxxxxx
+ *
+ * where U is the character value, W1 is the high surrogate
+ * area, W2 is the low surrogate area.
+ */
+
+ /* Check for incomplete UTF-16 character. */
+
+ if (raw_unread < 2) {
+ if (parser->eof) {
+ return yaml_parser_set_reader_error(parser,
+ "incomplete UTF-16 character",
+ parser->offset, -1);
+ }
+ incomplete = 1;
+ break;
+ }
+
+ /* Get the character. */
+
+ value = parser->raw_buffer.pointer[low]
+ + (parser->raw_buffer.pointer[high] << 8);
+
+ /* Check for unexpected low surrogate area. */
+
+ if ((value & 0xFC00) == 0xDC00)
+ return yaml_parser_set_reader_error(parser,
+ "unexpected low surrogate area",
+ parser->offset, value);
+
+ /* Check for a high surrogate area. */
+
+ if ((value & 0xFC00) == 0xD800) {
+
+ width = 4;
+
+ /* Check for incomplete surrogate pair. */
+
+ if (raw_unread < 4) {
+ if (parser->eof) {
+ return yaml_parser_set_reader_error(parser,
+ "incomplete UTF-16 surrogate pair",
+ parser->offset, -1);
+ }
+ incomplete = 1;
+ break;
+ }
+
+ /* Get the next character. */
+
+ value2 = parser->raw_buffer.pointer[low+2]
+ + (parser->raw_buffer.pointer[high+2] << 8);
+
+ /* Check for a low surrogate area. */
+
+ if ((value2 & 0xFC00) != 0xDC00)
+ return yaml_parser_set_reader_error(parser,
+ "expected low surrogate area",
+ parser->offset+2, value2);
+
+ /* Generate the value of the surrogate pair. */
+
+ value = 0x10000 + ((value & 0x3FF) << 10) + (value2 & 0x3FF);
+ }
+
+ else {
+ width = 2;
+ }
+
+ break;
+
+ default:
+ assert(1); /* Impossible. */
+ }
+
+ /* Check if the raw buffer contains enough bytes to form a character. */
+
+ if (incomplete) break;
+
+ /*
+ * Check if the character is in the allowed range:
+ * #x9 | #xA | #xD | [#x20-#x7E] (8 bit)
+ * | #x85 | [#xA0-#xD7FF] | [#xE000-#xFFFD] (16 bit)
+ * | [#x10000-#x10FFFF] (32 bit)
+ */
+
+ if (! (value == 0x09 || value == 0x0A || value == 0x0D
+ || (value >= 0x20 && value <= 0x7E)
+ || (value == 0x85) || (value >= 0xA0 && value <= 0xD7FF)
+ || (value >= 0xE000 && value <= 0xFFFD)
+ || (value >= 0x10000 && value <= 0x10FFFF)))
+ return yaml_parser_set_reader_error(parser,
+ "control characters are not allowed",
+ parser->offset, value);
+
+ /* Move the raw pointers. */
+
+ parser->raw_buffer.pointer += width;
+ parser->offset += width;
+
+ /* Finally put the character into the buffer. */
+
+ /* 0000 0000-0000 007F -> 0xxxxxxx */
+ if (value <= 0x7F) {
+ *(parser->buffer.last++) = value;
+ }
+ /* 0000 0080-0000 07FF -> 110xxxxx 10xxxxxx */
+ else if (value <= 0x7FF) {
+ *(parser->buffer.last++) = 0xC0 + (value >> 6);
+ *(parser->buffer.last++) = 0x80 + (value & 0x3F);
+ }
+ /* 0000 0800-0000 FFFF -> 1110xxxx 10xxxxxx 10xxxxxx */
+ else if (value <= 0xFFFF) {
+ *(parser->buffer.last++) = 0xE0 + (value >> 12);
+ *(parser->buffer.last++) = 0x80 + ((value >> 6) & 0x3F);
+ *(parser->buffer.last++) = 0x80 + (value & 0x3F);
+ }
+ /* 0001 0000-0010 FFFF -> 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx */
+ else {
+ *(parser->buffer.last++) = 0xF0 + (value >> 18);
+ *(parser->buffer.last++) = 0x80 + ((value >> 12) & 0x3F);
+ *(parser->buffer.last++) = 0x80 + ((value >> 6) & 0x3F);
+ *(parser->buffer.last++) = 0x80 + (value & 0x3F);
+ }
+
+ parser->unread ++;
+ }
+
+ /* On EOF, put NUL into the buffer and return. */
+
+ if (parser->eof) {
+ *(parser->buffer.last++) = '\0';
+ parser->unread ++;
+ return 1;
+ }
+
+ }
+
+ return 1;
+}
+
diff --git a/contrib/libyaml/src/scanner.c b/contrib/libyaml/src/scanner.c
new file mode 100644
index 0000000..a2e8619
--- /dev/null
+++ b/contrib/libyaml/src/scanner.c
@@ -0,0 +1,3570 @@
+
+/*
+ * Introduction
+ * ************
+ *
+ * The following notes assume that you are familiar with the YAML specification
+ * (http://yaml.org/spec/cvs/current.html). We mostly follow it, although in
+ * some cases we are less restrictive that it requires.
+ *
+ * The process of transforming a YAML stream into a sequence of events is
+ * divided on two steps: Scanning and Parsing.
+ *
+ * The Scanner transforms the input stream into a sequence of tokens, while the
+ * parser transform the sequence of tokens produced by the Scanner into a
+ * sequence of parsing events.
+ *
+ * The Scanner is rather clever and complicated. The Parser, on the contrary,
+ * is a straightforward implementation of a recursive-descendant parser (or,
+ * LL(1) parser, as it is usually called).
+ *
+ * Actually there are two issues of Scanning that might be called "clever", the
+ * rest is quite straightforward. The issues are "block collection start" and
+ * "simple keys". Both issues are explained below in details.
+ *
+ * Here the Scanning step is explained and implemented. We start with the list
+ * of all the tokens produced by the Scanner together with short descriptions.
+ *
+ * Now, tokens:
+ *
+ * STREAM-START(encoding) # The stream start.
+ * STREAM-END # The stream end.
+ * VERSION-DIRECTIVE(major,minor) # The '%YAML' directive.
+ * TAG-DIRECTIVE(handle,prefix) # The '%TAG' directive.
+ * DOCUMENT-START # '---'
+ * DOCUMENT-END # '...'
+ * BLOCK-SEQUENCE-START # Indentation increase denoting a block
+ * BLOCK-MAPPING-START # sequence or a block mapping.
+ * BLOCK-END # Indentation decrease.
+ * FLOW-SEQUENCE-START # '['
+ * FLOW-SEQUENCE-END # ']'
+ * BLOCK-SEQUENCE-START # '{'
+ * BLOCK-SEQUENCE-END # '}'
+ * BLOCK-ENTRY # '-'
+ * FLOW-ENTRY # ','
+ * KEY # '?' or nothing (simple keys).
+ * VALUE # ':'
+ * ALIAS(anchor) # '*anchor'
+ * ANCHOR(anchor) # '&anchor'
+ * TAG(handle,suffix) # '!handle!suffix'
+ * SCALAR(value,style) # A scalar.
+ *
+ * The following two tokens are "virtual" tokens denoting the beginning and the
+ * end of the stream:
+ *
+ * STREAM-START(encoding)
+ * STREAM-END
+ *
+ * We pass the information about the input stream encoding with the
+ * STREAM-START token.
+ *
+ * The next two tokens are responsible for tags:
+ *
+ * VERSION-DIRECTIVE(major,minor)
+ * TAG-DIRECTIVE(handle,prefix)
+ *
+ * Example:
+ *
+ * %YAML 1.1
+ * %TAG ! !foo
+ * %TAG !yaml! tag:yaml.org,2002:
+ * ---
+ *
+ * The correspoding sequence of tokens:
+ *
+ * STREAM-START(utf-8)
+ * VERSION-DIRECTIVE(1,1)
+ * TAG-DIRECTIVE("!","!foo")
+ * TAG-DIRECTIVE("!yaml","tag:yaml.org,2002:")
+ * DOCUMENT-START
+ * STREAM-END
+ *
+ * Note that the VERSION-DIRECTIVE and TAG-DIRECTIVE tokens occupy a whole
+ * line.
+ *
+ * The document start and end indicators are represented by:
+ *
+ * DOCUMENT-START
+ * DOCUMENT-END
+ *
+ * Note that if a YAML stream contains an implicit document (without '---'
+ * and '...' indicators), no DOCUMENT-START and DOCUMENT-END tokens will be
+ * produced.
+ *
+ * In the following examples, we present whole documents together with the
+ * produced tokens.
+ *
+ * 1. An implicit document:
+ *
+ * 'a scalar'
+ *
+ * Tokens:
+ *
+ * STREAM-START(utf-8)
+ * SCALAR("a scalar",single-quoted)
+ * STREAM-END
+ *
+ * 2. An explicit document:
+ *
+ * ---
+ * 'a scalar'
+ * ...
+ *
+ * Tokens:
+ *
+ * STREAM-START(utf-8)
+ * DOCUMENT-START
+ * SCALAR("a scalar",single-quoted)
+ * DOCUMENT-END
+ * STREAM-END
+ *
+ * 3. Several documents in a stream:
+ *
+ * 'a scalar'
+ * ---
+ * 'another scalar'
+ * ---
+ * 'yet another scalar'
+ *
+ * Tokens:
+ *
+ * STREAM-START(utf-8)
+ * SCALAR("a scalar",single-quoted)
+ * DOCUMENT-START
+ * SCALAR("another scalar",single-quoted)
+ * DOCUMENT-START
+ * SCALAR("yet another scalar",single-quoted)
+ * STREAM-END
+ *
+ * We have already introduced the SCALAR token above. The following tokens are
+ * used to describe aliases, anchors, tag, and scalars:
+ *
+ * ALIAS(anchor)
+ * ANCHOR(anchor)
+ * TAG(handle,suffix)
+ * SCALAR(value,style)
+ *
+ * The following series of examples illustrate the usage of these tokens:
+ *
+ * 1. A recursive sequence:
+ *
+ * &A [ *A ]
+ *
+ * Tokens:
+ *
+ * STREAM-START(utf-8)
+ * ANCHOR("A")
+ * FLOW-SEQUENCE-START
+ * ALIAS("A")
+ * FLOW-SEQUENCE-END
+ * STREAM-END
+ *
+ * 2. A tagged scalar:
+ *
+ * !!float "3.14" # A good approximation.
+ *
+ * Tokens:
+ *
+ * STREAM-START(utf-8)
+ * TAG("!!","float")
+ * SCALAR("3.14",double-quoted)
+ * STREAM-END
+ *
+ * 3. Various scalar styles:
+ *
+ * --- # Implicit empty plain scalars do not produce tokens.
+ * --- a plain scalar
+ * --- 'a single-quoted scalar'
+ * --- "a double-quoted scalar"
+ * --- |-
+ * a literal scalar
+ * --- >-
+ * a folded
+ * scalar
+ *
+ * Tokens:
+ *
+ * STREAM-START(utf-8)
+ * DOCUMENT-START
+ * DOCUMENT-START
+ * SCALAR("a plain scalar",plain)
+ * DOCUMENT-START
+ * SCALAR("a single-quoted scalar",single-quoted)
+ * DOCUMENT-START
+ * SCALAR("a double-quoted scalar",double-quoted)
+ * DOCUMENT-START
+ * SCALAR("a literal scalar",literal)
+ * DOCUMENT-START
+ * SCALAR("a folded scalar",folded)
+ * STREAM-END
+ *
+ * Now it's time to review collection-related tokens. We will start with
+ * flow collections:
+ *
+ * FLOW-SEQUENCE-START
+ * FLOW-SEQUENCE-END
+ * FLOW-MAPPING-START
+ * FLOW-MAPPING-END
+ * FLOW-ENTRY
+ * KEY
+ * VALUE
+ *
+ * The tokens FLOW-SEQUENCE-START, FLOW-SEQUENCE-END, FLOW-MAPPING-START, and
+ * FLOW-MAPPING-END represent the indicators '[', ']', '{', and '}'
+ * correspondingly. FLOW-ENTRY represent the ',' indicator. Finally the
+ * indicators '?' and ':', which are used for denoting mapping keys and values,
+ * are represented by the KEY and VALUE tokens.
+ *
+ * The following examples show flow collections:
+ *
+ * 1. A flow sequence:
+ *
+ * [item 1, item 2, item 3]
+ *
+ * Tokens:
+ *
+ * STREAM-START(utf-8)
+ * FLOW-SEQUENCE-START
+ * SCALAR("item 1",plain)
+ * FLOW-ENTRY
+ * SCALAR("item 2",plain)
+ * FLOW-ENTRY
+ * SCALAR("item 3",plain)
+ * FLOW-SEQUENCE-END
+ * STREAM-END
+ *
+ * 2. A flow mapping:
+ *
+ * {
+ * a simple key: a value, # Note that the KEY token is produced.
+ * ? a complex key: another value,
+ * }
+ *
+ * Tokens:
+ *
+ * STREAM-START(utf-8)
+ * FLOW-MAPPING-START
+ * KEY
+ * SCALAR("a simple key",plain)
+ * VALUE
+ * SCALAR("a value",plain)
+ * FLOW-ENTRY
+ * KEY
+ * SCALAR("a complex key",plain)
+ * VALUE
+ * SCALAR("another value",plain)
+ * FLOW-ENTRY
+ * FLOW-MAPPING-END
+ * STREAM-END
+ *
+ * A simple key is a key which is not denoted by the '?' indicator. Note that
+ * the Scanner still produce the KEY token whenever it encounters a simple key.
+ *
+ * For scanning block collections, the following tokens are used (note that we
+ * repeat KEY and VALUE here):
+ *
+ * BLOCK-SEQUENCE-START
+ * BLOCK-MAPPING-START
+ * BLOCK-END
+ * BLOCK-ENTRY
+ * KEY
+ * VALUE
+ *
+ * The tokens BLOCK-SEQUENCE-START and BLOCK-MAPPING-START denote indentation
+ * increase that precedes a block collection (cf. the INDENT token in Python).
+ * The token BLOCK-END denote indentation decrease that ends a block collection
+ * (cf. the DEDENT token in Python). However YAML has some syntax pecularities
+ * that makes detections of these tokens more complex.
+ *
+ * The tokens BLOCK-ENTRY, KEY, and VALUE are used to represent the indicators
+ * '-', '?', and ':' correspondingly.
+ *
+ * The following examples show how the tokens BLOCK-SEQUENCE-START,
+ * BLOCK-MAPPING-START, and BLOCK-END are emitted by the Scanner:
+ *
+ * 1. Block sequences:
+ *
+ * - item 1
+ * - item 2
+ * -
+ * - item 3.1
+ * - item 3.2
+ * -
+ * key 1: value 1
+ * key 2: value 2
+ *
+ * Tokens:
+ *
+ * STREAM-START(utf-8)
+ * BLOCK-SEQUENCE-START
+ * BLOCK-ENTRY
+ * SCALAR("item 1",plain)
+ * BLOCK-ENTRY
+ * SCALAR("item 2",plain)
+ * BLOCK-ENTRY
+ * BLOCK-SEQUENCE-START
+ * BLOCK-ENTRY
+ * SCALAR("item 3.1",plain)
+ * BLOCK-ENTRY
+ * SCALAR("item 3.2",plain)
+ * BLOCK-END
+ * BLOCK-ENTRY
+ * BLOCK-MAPPING-START
+ * KEY
+ * SCALAR("key 1",plain)
+ * VALUE
+ * SCALAR("value 1",plain)
+ * KEY
+ * SCALAR("key 2",plain)
+ * VALUE
+ * SCALAR("value 2",plain)
+ * BLOCK-END
+ * BLOCK-END
+ * STREAM-END
+ *
+ * 2. Block mappings:
+ *
+ * a simple key: a value # The KEY token is produced here.
+ * ? a complex key
+ * : another value
+ * a mapping:
+ * key 1: value 1
+ * key 2: value 2
+ * a sequence:
+ * - item 1
+ * - item 2
+ *
+ * Tokens:
+ *
+ * STREAM-START(utf-8)
+ * BLOCK-MAPPING-START
+ * KEY
+ * SCALAR("a simple key",plain)
+ * VALUE
+ * SCALAR("a value",plain)
+ * KEY
+ * SCALAR("a complex key",plain)
+ * VALUE
+ * SCALAR("another value",plain)
+ * KEY
+ * SCALAR("a mapping",plain)
+ * BLOCK-MAPPING-START
+ * KEY
+ * SCALAR("key 1",plain)
+ * VALUE
+ * SCALAR("value 1",plain)
+ * KEY
+ * SCALAR("key 2",plain)
+ * VALUE
+ * SCALAR("value 2",plain)
+ * BLOCK-END
+ * KEY
+ * SCALAR("a sequence",plain)
+ * VALUE
+ * BLOCK-SEQUENCE-START
+ * BLOCK-ENTRY
+ * SCALAR("item 1",plain)
+ * BLOCK-ENTRY
+ * SCALAR("item 2",plain)
+ * BLOCK-END
+ * BLOCK-END
+ * STREAM-END
+ *
+ * YAML does not always require to start a new block collection from a new
+ * line. If the current line contains only '-', '?', and ':' indicators, a new
+ * block collection may start at the current line. The following examples
+ * illustrate this case:
+ *
+ * 1. Collections in a sequence:
+ *
+ * - - item 1
+ * - item 2
+ * - key 1: value 1
+ * key 2: value 2
+ * - ? complex key
+ * : complex value
+ *
+ * Tokens:
+ *
+ * STREAM-START(utf-8)
+ * BLOCK-SEQUENCE-START
+ * BLOCK-ENTRY
+ * BLOCK-SEQUENCE-START
+ * BLOCK-ENTRY
+ * SCALAR("item 1",plain)
+ * BLOCK-ENTRY
+ * SCALAR("item 2",plain)
+ * BLOCK-END
+ * BLOCK-ENTRY
+ * BLOCK-MAPPING-START
+ * KEY
+ * SCALAR("key 1",plain)
+ * VALUE
+ * SCALAR("value 1",plain)
+ * KEY
+ * SCALAR("key 2",plain)
+ * VALUE
+ * SCALAR("value 2",plain)
+ * BLOCK-END
+ * BLOCK-ENTRY
+ * BLOCK-MAPPING-START
+ * KEY
+ * SCALAR("complex key")
+ * VALUE
+ * SCALAR("complex value")
+ * BLOCK-END
+ * BLOCK-END
+ * STREAM-END
+ *
+ * 2. Collections in a mapping:
+ *
+ * ? a sequence
+ * : - item 1
+ * - item 2
+ * ? a mapping
+ * : key 1: value 1
+ * key 2: value 2
+ *
+ * Tokens:
+ *
+ * STREAM-START(utf-8)
+ * BLOCK-MAPPING-START
+ * KEY
+ * SCALAR("a sequence",plain)
+ * VALUE
+ * BLOCK-SEQUENCE-START
+ * BLOCK-ENTRY
+ * SCALAR("item 1",plain)
+ * BLOCK-ENTRY
+ * SCALAR("item 2",plain)
+ * BLOCK-END
+ * KEY
+ * SCALAR("a mapping",plain)
+ * VALUE
+ * BLOCK-MAPPING-START
+ * KEY
+ * SCALAR("key 1",plain)
+ * VALUE
+ * SCALAR("value 1",plain)
+ * KEY
+ * SCALAR("key 2",plain)
+ * VALUE
+ * SCALAR("value 2",plain)
+ * BLOCK-END
+ * BLOCK-END
+ * STREAM-END
+ *
+ * YAML also permits non-indented sequences if they are included into a block
+ * mapping. In this case, the token BLOCK-SEQUENCE-START is not produced:
+ *
+ * key:
+ * - item 1 # BLOCK-SEQUENCE-START is NOT produced here.
+ * - item 2
+ *
+ * Tokens:
+ *
+ * STREAM-START(utf-8)
+ * BLOCK-MAPPING-START
+ * KEY
+ * SCALAR("key",plain)
+ * VALUE
+ * BLOCK-ENTRY
+ * SCALAR("item 1",plain)
+ * BLOCK-ENTRY
+ * SCALAR("item 2",plain)
+ * BLOCK-END
+ */
+
+#include "yaml_private.h"
+
+/*
+ * Ensure that the buffer contains the required number of characters.
+ * Return 1 on success, 0 on failure (reader error or memory error).
+ */
+
+#define CACHE(parser,length) \
+ (parser->unread >= (length) \
+ ? 1 \
+ : yaml_parser_update_buffer(parser, (length)))
+
+/*
+ * Advance the buffer pointer.
+ */
+
+#define SKIP(parser) \
+ (parser->mark.index ++, \
+ parser->mark.column ++, \
+ parser->unread --, \
+ parser->buffer.pointer += WIDTH(parser->buffer))
+
+#define SKIP_LINE(parser) \
+ (IS_CRLF(parser->buffer) ? \
+ (parser->mark.index += 2, \
+ parser->mark.column = 0, \
+ parser->mark.line ++, \
+ parser->unread -= 2, \
+ parser->buffer.pointer += 2) : \
+ IS_BREAK(parser->buffer) ? \
+ (parser->mark.index ++, \
+ parser->mark.column = 0, \
+ parser->mark.line ++, \
+ parser->unread --, \
+ parser->buffer.pointer += WIDTH(parser->buffer)) : 0)
+
+/*
+ * Copy a character to a string buffer and advance pointers.
+ */
+
+#define READ(parser,string) \
+ (STRING_EXTEND(parser,string) ? \
+ (COPY(string,parser->buffer), \
+ parser->mark.index ++, \
+ parser->mark.column ++, \
+ parser->unread --, \
+ 1) : 0)
+
+/*
+ * Copy a line break character to a string buffer and advance pointers.
+ */
+
+#define READ_LINE(parser,string) \
+ (STRING_EXTEND(parser,string) ? \
+ (((CHECK_AT(parser->buffer,'\r',0) \
+ && CHECK_AT(parser->buffer,'\n',1)) ? /* CR LF -> LF */ \
+ (*((string).pointer++) = (yaml_char_t) '\n', \
+ parser->buffer.pointer += 2, \
+ parser->mark.index += 2, \
+ parser->mark.column = 0, \
+ parser->mark.line ++, \
+ parser->unread -= 2) : \
+ (CHECK_AT(parser->buffer,'\r',0) \
+ || CHECK_AT(parser->buffer,'\n',0)) ? /* CR|LF -> LF */ \
+ (*((string).pointer++) = (yaml_char_t) '\n', \
+ parser->buffer.pointer ++, \
+ parser->mark.index ++, \
+ parser->mark.column = 0, \
+ parser->mark.line ++, \
+ parser->unread --) : \
+ (CHECK_AT(parser->buffer,'\xC2',0) \
+ && CHECK_AT(parser->buffer,'\x85',1)) ? /* NEL -> LF */ \
+ (*((string).pointer++) = (yaml_char_t) '\n', \
+ parser->buffer.pointer += 2, \
+ parser->mark.index ++, \
+ parser->mark.column = 0, \
+ parser->mark.line ++, \
+ parser->unread --) : \
+ (CHECK_AT(parser->buffer,'\xE2',0) && \
+ CHECK_AT(parser->buffer,'\x80',1) && \
+ (CHECK_AT(parser->buffer,'\xA8',2) || \
+ CHECK_AT(parser->buffer,'\xA9',2))) ? /* LS|PS -> LS|PS */ \
+ (*((string).pointer++) = *(parser->buffer.pointer++), \
+ *((string).pointer++) = *(parser->buffer.pointer++), \
+ *((string).pointer++) = *(parser->buffer.pointer++), \
+ parser->mark.index ++, \
+ parser->mark.column = 0, \
+ parser->mark.line ++, \
+ parser->unread --) : 0), \
+ 1) : 0)
+
+/*
+ * Public API declarations.
+ */
+
+YAML_DECLARE(int)
+yaml_parser_scan(yaml_parser_t *parser, yaml_token_t *token);
+
+/*
+ * Error handling.
+ */
+
+static int
+yaml_parser_set_scanner_error(yaml_parser_t *parser, const char *context,
+ yaml_mark_t context_mark, const char *problem);
+
+/*
+ * High-level token API.
+ */
+
+YAML_DECLARE(int)
+yaml_parser_fetch_more_tokens(yaml_parser_t *parser);
+
+static int
+yaml_parser_fetch_next_token(yaml_parser_t *parser);
+
+/*
+ * Potential simple keys.
+ */
+
+static int
+yaml_parser_stale_simple_keys(yaml_parser_t *parser);
+
+static int
+yaml_parser_save_simple_key(yaml_parser_t *parser);
+
+static int
+yaml_parser_remove_simple_key(yaml_parser_t *parser);
+
+static int
+yaml_parser_increase_flow_level(yaml_parser_t *parser);
+
+static int
+yaml_parser_decrease_flow_level(yaml_parser_t *parser);
+
+/*
+ * Indentation treatment.
+ */
+
+static int
+yaml_parser_roll_indent(yaml_parser_t *parser, int column,
+ int number, yaml_token_type_t type, yaml_mark_t mark);
+
+static int
+yaml_parser_unroll_indent(yaml_parser_t *parser, int column);
+
+/*
+ * Token fetchers.
+ */
+
+static int
+yaml_parser_fetch_stream_start(yaml_parser_t *parser);
+
+static int
+yaml_parser_fetch_stream_end(yaml_parser_t *parser);
+
+static int
+yaml_parser_fetch_directive(yaml_parser_t *parser);
+
+static int
+yaml_parser_fetch_document_indicator(yaml_parser_t *parser,
+ yaml_token_type_t type);
+
+static int
+yaml_parser_fetch_flow_collection_start(yaml_parser_t *parser,
+ yaml_token_type_t type);
+
+static int
+yaml_parser_fetch_flow_collection_end(yaml_parser_t *parser,
+ yaml_token_type_t type);
+
+static int
+yaml_parser_fetch_flow_entry(yaml_parser_t *parser);
+
+static int
+yaml_parser_fetch_block_entry(yaml_parser_t *parser);
+
+static int
+yaml_parser_fetch_key(yaml_parser_t *parser);
+
+static int
+yaml_parser_fetch_value(yaml_parser_t *parser);
+
+static int
+yaml_parser_fetch_anchor(yaml_parser_t *parser, yaml_token_type_t type);
+
+static int
+yaml_parser_fetch_tag(yaml_parser_t *parser);
+
+static int
+yaml_parser_fetch_block_scalar(yaml_parser_t *parser, int literal);
+
+static int
+yaml_parser_fetch_flow_scalar(yaml_parser_t *parser, int single);
+
+static int
+yaml_parser_fetch_plain_scalar(yaml_parser_t *parser);
+
+/*
+ * Token scanners.
+ */
+
+static int
+yaml_parser_scan_to_next_token(yaml_parser_t *parser);
+
+static int
+yaml_parser_scan_directive(yaml_parser_t *parser, yaml_token_t *token);
+
+static int
+yaml_parser_scan_directive_name(yaml_parser_t *parser,
+ yaml_mark_t start_mark, yaml_char_t **name);
+
+static int
+yaml_parser_scan_version_directive_value(yaml_parser_t *parser,
+ yaml_mark_t start_mark, int *major, int *minor);
+
+static int
+yaml_parser_scan_version_directive_number(yaml_parser_t *parser,
+ yaml_mark_t start_mark, int *number);
+
+static int
+yaml_parser_scan_tag_directive_value(yaml_parser_t *parser,
+ yaml_mark_t mark, yaml_char_t **handle, yaml_char_t **prefix);
+
+static int
+yaml_parser_scan_anchor(yaml_parser_t *parser, yaml_token_t *token,
+ yaml_token_type_t type);
+
+static int
+yaml_parser_scan_tag(yaml_parser_t *parser, yaml_token_t *token);
+
+static int
+yaml_parser_scan_tag_handle(yaml_parser_t *parser, int directive,
+ yaml_mark_t start_mark, yaml_char_t **handle);
+
+static int
+yaml_parser_scan_tag_uri(yaml_parser_t *parser, int directive,
+ yaml_char_t *head, yaml_mark_t start_mark, yaml_char_t **uri);
+
+static int
+yaml_parser_scan_uri_escapes(yaml_parser_t *parser, int directive,
+ yaml_mark_t start_mark, yaml_string_t *string);
+
+static int
+yaml_parser_scan_block_scalar(yaml_parser_t *parser, yaml_token_t *token,
+ int literal);
+
+static int
+yaml_parser_scan_block_scalar_breaks(yaml_parser_t *parser,
+ int *indent, yaml_string_t *breaks,
+ yaml_mark_t start_mark, yaml_mark_t *end_mark);
+
+static int
+yaml_parser_scan_flow_scalar(yaml_parser_t *parser, yaml_token_t *token,
+ int single);
+
+static int
+yaml_parser_scan_plain_scalar(yaml_parser_t *parser, yaml_token_t *token);
+
+/*
+ * Get the next token.
+ */
+
+YAML_DECLARE(int)
+yaml_parser_scan(yaml_parser_t *parser, yaml_token_t *token)
+{
+ assert(parser); /* Non-NULL parser object is expected. */
+ assert(token); /* Non-NULL token object is expected. */
+
+ /* Erase the token object. */
+
+ memset(token, 0, sizeof(yaml_token_t));
+
+ /* No tokens after STREAM-END or error. */
+
+ if (parser->stream_end_produced || parser->error) {
+ return 1;
+ }
+
+ /* Ensure that the tokens queue contains enough tokens. */
+
+ if (!parser->token_available) {
+ if (!yaml_parser_fetch_more_tokens(parser))
+ return 0;
+ }
+
+ /* Fetch the next token from the queue. */
+
+ *token = DEQUEUE(parser, parser->tokens);
+ parser->token_available = 0;
+ parser->tokens_parsed ++;
+
+ if (token->type == YAML_STREAM_END_TOKEN) {
+ parser->stream_end_produced = 1;
+ }
+
+ return 1;
+}
+
+/*
+ * Set the scanner error and return 0.
+ */
+
+static int
+yaml_parser_set_scanner_error(yaml_parser_t *parser, const char *context,
+ yaml_mark_t context_mark, const char *problem)
+{
+ parser->error = YAML_SCANNER_ERROR;
+ parser->context = context;
+ parser->context_mark = context_mark;
+ parser->problem = problem;
+ parser->problem_mark = parser->mark;
+
+ return 0;
+}
+
+/*
+ * Ensure that the tokens queue contains at least one token which can be
+ * returned to the Parser.
+ */
+
+YAML_DECLARE(int)
+yaml_parser_fetch_more_tokens(yaml_parser_t *parser)
+{
+ int need_more_tokens;
+
+ /* While we need more tokens to fetch, do it. */
+
+ while (1)
+ {
+ /*
+ * Check if we really need to fetch more tokens.
+ */
+
+ need_more_tokens = 0;
+
+ if (parser->tokens.head == parser->tokens.tail)
+ {
+ /* Queue is empty. */
+
+ need_more_tokens = 1;
+ }
+ else
+ {
+ yaml_simple_key_t *simple_key;
+
+ /* Check if any potential simple key may occupy the head position. */
+
+ if (!yaml_parser_stale_simple_keys(parser))
+ return 0;
+
+ for (simple_key = parser->simple_keys.start;
+ simple_key != parser->simple_keys.top; simple_key++) {
+ if (simple_key->possible
+ && simple_key->token_number == parser->tokens_parsed) {
+ need_more_tokens = 1;
+ break;
+ }
+ }
+ }
+
+ /* We are finished. */
+
+ if (!need_more_tokens)
+ break;
+
+ /* Fetch the next token. */
+
+ if (!yaml_parser_fetch_next_token(parser))
+ return 0;
+ }
+
+ parser->token_available = 1;
+
+ return 1;
+}
+
+/*
+ * The dispatcher for token fetchers.
+ */
+
+static int
+yaml_parser_fetch_next_token(yaml_parser_t *parser)
+{
+ /* Ensure that the buffer is initialized. */
+
+ if (!CACHE(parser, 1))
+ return 0;
+
+ /* Check if we just started scanning. Fetch STREAM-START then. */
+
+ if (!parser->stream_start_produced)
+ return yaml_parser_fetch_stream_start(parser);
+
+ /* Eat whitespaces and comments until we reach the next token. */
+
+ if (!yaml_parser_scan_to_next_token(parser))
+ return 0;
+
+ /* Remove obsolete potential simple keys. */
+
+ if (!yaml_parser_stale_simple_keys(parser))
+ return 0;
+
+ /* Check the indentation level against the current column. */
+
+ if (!yaml_parser_unroll_indent(parser, parser->mark.column))
+ return 0;
+
+ /*
+ * Ensure that the buffer contains at least 4 characters. 4 is the length
+ * of the longest indicators ('--- ' and '... ').
+ */
+
+ if (!CACHE(parser, 4))
+ return 0;
+
+ /* Is it the end of the stream? */
+
+ if (IS_Z(parser->buffer))
+ return yaml_parser_fetch_stream_end(parser);
+
+ /* Is it a directive? */
+
+ if (parser->mark.column == 0 && CHECK(parser->buffer, '%'))
+ return yaml_parser_fetch_directive(parser);
+
+ /* Is it the document start indicator? */
+
+ if (parser->mark.column == 0
+ && CHECK_AT(parser->buffer, '-', 0)
+ && CHECK_AT(parser->buffer, '-', 1)
+ && CHECK_AT(parser->buffer, '-', 2)
+ && IS_BLANKZ_AT(parser->buffer, 3))
+ return yaml_parser_fetch_document_indicator(parser,
+ YAML_DOCUMENT_START_TOKEN);
+
+ /* Is it the document end indicator? */
+
+ if (parser->mark.column == 0
+ && CHECK_AT(parser->buffer, '.', 0)
+ && CHECK_AT(parser->buffer, '.', 1)
+ && CHECK_AT(parser->buffer, '.', 2)
+ && IS_BLANKZ_AT(parser->buffer, 3))
+ return yaml_parser_fetch_document_indicator(parser,
+ YAML_DOCUMENT_END_TOKEN);
+
+ /* Is it the flow sequence start indicator? */
+
+ if (CHECK(parser->buffer, '['))
+ return yaml_parser_fetch_flow_collection_start(parser,
+ YAML_FLOW_SEQUENCE_START_TOKEN);
+
+ /* Is it the flow mapping start indicator? */
+
+ if (CHECK(parser->buffer, '{'))
+ return yaml_parser_fetch_flow_collection_start(parser,
+ YAML_FLOW_MAPPING_START_TOKEN);
+
+ /* Is it the flow sequence end indicator? */
+
+ if (CHECK(parser->buffer, ']'))
+ return yaml_parser_fetch_flow_collection_end(parser,
+ YAML_FLOW_SEQUENCE_END_TOKEN);
+
+ /* Is it the flow mapping end indicator? */
+
+ if (CHECK(parser->buffer, '}'))
+ return yaml_parser_fetch_flow_collection_end(parser,
+ YAML_FLOW_MAPPING_END_TOKEN);
+
+ /* Is it the flow entry indicator? */
+
+ if (CHECK(parser->buffer, ','))
+ return yaml_parser_fetch_flow_entry(parser);
+
+ /* Is it the block entry indicator? */
+
+ if (CHECK(parser->buffer, '-') && IS_BLANKZ_AT(parser->buffer, 1))
+ return yaml_parser_fetch_block_entry(parser);
+
+ /* Is it the key indicator? */
+
+ if (CHECK(parser->buffer, '?')
+ && (parser->flow_level || IS_BLANKZ_AT(parser->buffer, 1)))
+ return yaml_parser_fetch_key(parser);
+
+ /* Is it the value indicator? */
+
+ if (CHECK(parser->buffer, ':')
+ && (parser->flow_level || IS_BLANKZ_AT(parser->buffer, 1)))
+ return yaml_parser_fetch_value(parser);
+
+ /* Is it an alias? */
+
+ if (CHECK(parser->buffer, '*'))
+ return yaml_parser_fetch_anchor(parser, YAML_ALIAS_TOKEN);
+
+ /* Is it an anchor? */
+
+ if (CHECK(parser->buffer, '&'))
+ return yaml_parser_fetch_anchor(parser, YAML_ANCHOR_TOKEN);
+
+ /* Is it a tag? */
+
+ if (CHECK(parser->buffer, '!'))
+ return yaml_parser_fetch_tag(parser);
+
+ /* Is it a literal scalar? */
+
+ if (CHECK(parser->buffer, '|') && !parser->flow_level)
+ return yaml_parser_fetch_block_scalar(parser, 1);
+
+ /* Is it a folded scalar? */
+
+ if (CHECK(parser->buffer, '>') && !parser->flow_level)
+ return yaml_parser_fetch_block_scalar(parser, 0);
+
+ /* Is it a single-quoted scalar? */
+
+ if (CHECK(parser->buffer, '\''))
+ return yaml_parser_fetch_flow_scalar(parser, 1);
+
+ /* Is it a double-quoted scalar? */
+
+ if (CHECK(parser->buffer, '"'))
+ return yaml_parser_fetch_flow_scalar(parser, 0);
+
+ /*
+ * Is it a plain scalar?
+ *
+ * A plain scalar may start with any non-blank characters except
+ *
+ * '-', '?', ':', ',', '[', ']', '{', '}',
+ * '#', '&', '*', '!', '|', '>', '\'', '\"',
+ * '%', '@', '`'.
+ *
+ * In the block context (and, for the '-' indicator, in the flow context
+ * too), it may also start with the characters
+ *
+ * '-', '?', ':'
+ *
+ * if it is followed by a non-space character.
+ *
+ * The last rule is more restrictive than the specification requires.
+ */
+
+ if (!(IS_BLANKZ(parser->buffer) || CHECK(parser->buffer, '-')
+ || CHECK(parser->buffer, '?') || CHECK(parser->buffer, ':')
+ || CHECK(parser->buffer, ',') || CHECK(parser->buffer, '[')
+ || CHECK(parser->buffer, ']') || CHECK(parser->buffer, '{')
+ || CHECK(parser->buffer, '}') || CHECK(parser->buffer, '#')
+ || CHECK(parser->buffer, '&') || CHECK(parser->buffer, '*')
+ || CHECK(parser->buffer, '!') || CHECK(parser->buffer, '|')
+ || CHECK(parser->buffer, '>') || CHECK(parser->buffer, '\'')
+ || CHECK(parser->buffer, '"') || CHECK(parser->buffer, '%')
+ || CHECK(parser->buffer, '@') || CHECK(parser->buffer, '`')) ||
+ (CHECK(parser->buffer, '-') && !IS_BLANK_AT(parser->buffer, 1)) ||
+ (!parser->flow_level &&
+ (CHECK(parser->buffer, '?') || CHECK(parser->buffer, ':'))
+ && !IS_BLANKZ_AT(parser->buffer, 1)))
+ return yaml_parser_fetch_plain_scalar(parser);
+
+ /*
+ * If we don't determine the token type so far, it is an error.
+ */
+
+ return yaml_parser_set_scanner_error(parser,
+ "while scanning for the next token", parser->mark,
+ "found character that cannot start any token");
+}
+
+/*
+ * Check the list of potential simple keys and remove the positions that
+ * cannot contain simple keys anymore.
+ */
+
+static int
+yaml_parser_stale_simple_keys(yaml_parser_t *parser)
+{
+ yaml_simple_key_t *simple_key;
+
+ /* Check for a potential simple key for each flow level. */
+
+ for (simple_key = parser->simple_keys.start;
+ simple_key != parser->simple_keys.top; simple_key ++)
+ {
+ /*
+ * The specification requires that a simple key
+ *
+ * - is limited to a single line,
+ * - is shorter than 1024 characters.
+ */
+
+ if (simple_key->possible
+ && (simple_key->mark.line < parser->mark.line
+ || simple_key->mark.index+1024 < parser->mark.index)) {
+
+ /* Check if the potential simple key to be removed is required. */
+
+ if (simple_key->required) {
+ return yaml_parser_set_scanner_error(parser,
+ "while scanning a simple key", simple_key->mark,
+ "could not find expected ':'");
+ }
+
+ simple_key->possible = 0;
+ }
+ }
+
+ return 1;
+}
+
+/*
+ * Check if a simple key may start at the current position and add it if
+ * needed.
+ */
+
+static int
+yaml_parser_save_simple_key(yaml_parser_t *parser)
+{
+ /*
+ * A simple key is required at the current position if the scanner is in
+ * the block context and the current column coincides with the indentation
+ * level.
+ */
+
+ int required = (!parser->flow_level
+ && parser->indent == (int)parser->mark.column);
+
+ /*
+ * A simple key is required only when it is the first token in the current
+ * line. Therefore it is always allowed. But we add a check anyway.
+ */
+
+ assert(parser->simple_key_allowed || !required); /* Impossible. */
+
+ /*
+ * If the current position may start a simple key, save it.
+ */
+
+ if (parser->simple_key_allowed)
+ {
+ yaml_simple_key_t simple_key;
+ simple_key.possible = 1;
+ simple_key.required = required;
+ simple_key.token_number =
+ parser->tokens_parsed + (parser->tokens.tail - parser->tokens.head);
+ simple_key.mark = parser->mark;
+
+ if (!yaml_parser_remove_simple_key(parser)) return 0;
+
+ *(parser->simple_keys.top-1) = simple_key;
+ }
+
+ return 1;
+}
+
+/*
+ * Remove a potential simple key at the current flow level.
+ */
+
+static int
+yaml_parser_remove_simple_key(yaml_parser_t *parser)
+{
+ yaml_simple_key_t *simple_key = parser->simple_keys.top-1;
+
+ if (simple_key->possible)
+ {
+ /* If the key is required, it is an error. */
+
+ if (simple_key->required) {
+ return yaml_parser_set_scanner_error(parser,
+ "while scanning a simple key", simple_key->mark,
+ "could not find expected ':'");
+ }
+ }
+
+ /* Remove the key from the stack. */
+
+ simple_key->possible = 0;
+
+ return 1;
+}
+
+/*
+ * Increase the flow level and resize the simple key list if needed.
+ */
+
+static int
+yaml_parser_increase_flow_level(yaml_parser_t *parser)
+{
+ yaml_simple_key_t empty_simple_key = { 0, 0, 0, { 0, 0, 0 } };
+
+ /* Reset the simple key on the next level. */
+
+ if (!PUSH(parser, parser->simple_keys, empty_simple_key))
+ return 0;
+
+ /* Increase the flow level. */
+
+ parser->flow_level++;
+
+ return 1;
+}
+
+/*
+ * Decrease the flow level.
+ */
+
+static int
+yaml_parser_decrease_flow_level(yaml_parser_t *parser)
+{
+ yaml_simple_key_t dummy_key; /* Used to eliminate a compiler warning. */
+
+ if (parser->flow_level) {
+ parser->flow_level --;
+ dummy_key = POP(parser, parser->simple_keys);
+ }
+
+ return 1;
+}
+
+/*
+ * Push the current indentation level to the stack and set the new level
+ * the current column is greater than the indentation level. In this case,
+ * append or insert the specified token into the token queue.
+ *
+ */
+
+static int
+yaml_parser_roll_indent(yaml_parser_t *parser, int column,
+ int number, yaml_token_type_t type, yaml_mark_t mark)
+{
+ yaml_token_t token;
+
+ /* In the flow context, do nothing. */
+
+ if (parser->flow_level)
+ return 1;
+
+ if (parser->indent < column)
+ {
+ /*
+ * Push the current indentation level to the stack and set the new
+ * indentation level.
+ */
+
+ if (!PUSH(parser, parser->indents, parser->indent))
+ return 0;
+
+ parser->indent = column;
+
+ /* Create a token and insert it into the queue. */
+
+ TOKEN_INIT(token, type, mark, mark);
+
+ if (number == -1) {
+ if (!ENQUEUE(parser, parser->tokens, token))
+ return 0;
+ }
+ else {
+ if (!QUEUE_INSERT(parser,
+ parser->tokens, number - parser->tokens_parsed, token))
+ return 0;
+ }
+ }
+
+ return 1;
+}
+
+/*
+ * Pop indentation levels from the indents stack until the current level
+ * becomes less or equal to the column. For each intendation level, append
+ * the BLOCK-END token.
+ */
+
+
+static int
+yaml_parser_unroll_indent(yaml_parser_t *parser, int column)
+{
+ yaml_token_t token;
+
+ /* In the flow context, do nothing. */
+
+ if (parser->flow_level)
+ return 1;
+
+ /* Loop through the intendation levels in the stack. */
+
+ while (parser->indent > column)
+ {
+ /* Create a token and append it to the queue. */
+
+ TOKEN_INIT(token, YAML_BLOCK_END_TOKEN, parser->mark, parser->mark);
+
+ if (!ENQUEUE(parser, parser->tokens, token))
+ return 0;
+
+ /* Pop the indentation level. */
+
+ parser->indent = POP(parser, parser->indents);
+ }
+
+ return 1;
+}
+
+/*
+ * Initialize the scanner and produce the STREAM-START token.
+ */
+
+static int
+yaml_parser_fetch_stream_start(yaml_parser_t *parser)
+{
+ yaml_simple_key_t simple_key = { 0, 0, 0, { 0, 0, 0 } };
+ yaml_token_t token;
+
+ /* Set the initial indentation. */
+
+ parser->indent = -1;
+
+ /* Initialize the simple key stack. */
+
+ if (!PUSH(parser, parser->simple_keys, simple_key))
+ return 0;
+
+ /* A simple key is allowed at the beginning of the stream. */
+
+ parser->simple_key_allowed = 1;
+
+ /* We have started. */
+
+ parser->stream_start_produced = 1;
+
+ /* Create the STREAM-START token and append it to the queue. */
+
+ STREAM_START_TOKEN_INIT(token, parser->encoding,
+ parser->mark, parser->mark);
+
+ if (!ENQUEUE(parser, parser->tokens, token))
+ return 0;
+
+ return 1;
+}
+
+/*
+ * Produce the STREAM-END token and shut down the scanner.
+ */
+
+static int
+yaml_parser_fetch_stream_end(yaml_parser_t *parser)
+{
+ yaml_token_t token;
+
+ /* Force new line. */
+
+ if (parser->mark.column != 0) {
+ parser->mark.column = 0;
+ parser->mark.line ++;
+ }
+
+ /* Reset the indentation level. */
+
+ if (!yaml_parser_unroll_indent(parser, -1))
+ return 0;
+
+ /* Reset simple keys. */
+
+ if (!yaml_parser_remove_simple_key(parser))
+ return 0;
+
+ parser->simple_key_allowed = 0;
+
+ /* Create the STREAM-END token and append it to the queue. */
+
+ STREAM_END_TOKEN_INIT(token, parser->mark, parser->mark);
+
+ if (!ENQUEUE(parser, parser->tokens, token))
+ return 0;
+
+ return 1;
+}
+
+/*
+ * Produce a VERSION-DIRECTIVE or TAG-DIRECTIVE token.
+ */
+
+static int
+yaml_parser_fetch_directive(yaml_parser_t *parser)
+{
+ yaml_token_t token;
+
+ /* Reset the indentation level. */
+
+ if (!yaml_parser_unroll_indent(parser, -1))
+ return 0;
+
+ /* Reset simple keys. */
+
+ if (!yaml_parser_remove_simple_key(parser))
+ return 0;
+
+ parser->simple_key_allowed = 0;
+
+ /* Create the YAML-DIRECTIVE or TAG-DIRECTIVE token. */
+
+ if (!yaml_parser_scan_directive(parser, &token))
+ return 0;
+
+ /* Append the token to the queue. */
+
+ if (!ENQUEUE(parser, parser->tokens, token)) {
+ yaml_token_delete(&token);
+ return 0;
+ }
+
+ return 1;
+}
+
+/*
+ * Produce the DOCUMENT-START or DOCUMENT-END token.
+ */
+
+static int
+yaml_parser_fetch_document_indicator(yaml_parser_t *parser,
+ yaml_token_type_t type)
+{
+ yaml_mark_t start_mark, end_mark;
+ yaml_token_t token;
+
+ /* Reset the indentation level. */
+
+ if (!yaml_parser_unroll_indent(parser, -1))
+ return 0;
+
+ /* Reset simple keys. */
+
+ if (!yaml_parser_remove_simple_key(parser))
+ return 0;
+
+ parser->simple_key_allowed = 0;
+
+ /* Consume the token. */
+
+ start_mark = parser->mark;
+
+ SKIP(parser);
+ SKIP(parser);
+ SKIP(parser);
+
+ end_mark = parser->mark;
+
+ /* Create the DOCUMENT-START or DOCUMENT-END token. */
+
+ TOKEN_INIT(token, type, start_mark, end_mark);
+
+ /* Append the token to the queue. */
+
+ if (!ENQUEUE(parser, parser->tokens, token))
+ return 0;
+
+ return 1;
+}
+
+/*
+ * Produce the FLOW-SEQUENCE-START or FLOW-MAPPING-START token.
+ */
+
+static int
+yaml_parser_fetch_flow_collection_start(yaml_parser_t *parser,
+ yaml_token_type_t type)
+{
+ yaml_mark_t start_mark, end_mark;
+ yaml_token_t token;
+
+ /* The indicators '[' and '{' may start a simple key. */
+
+ if (!yaml_parser_save_simple_key(parser))
+ return 0;
+
+ /* Increase the flow level. */
+
+ if (!yaml_parser_increase_flow_level(parser))
+ return 0;
+
+ /* A simple key may follow the indicators '[' and '{'. */
+
+ parser->simple_key_allowed = 1;
+
+ /* Consume the token. */
+
+ start_mark = parser->mark;
+ SKIP(parser);
+ end_mark = parser->mark;
+
+ /* Create the FLOW-SEQUENCE-START of FLOW-MAPPING-START token. */
+
+ TOKEN_INIT(token, type, start_mark, end_mark);
+
+ /* Append the token to the queue. */
+
+ if (!ENQUEUE(parser, parser->tokens, token))
+ return 0;
+
+ return 1;
+}
+
+/*
+ * Produce the FLOW-SEQUENCE-END or FLOW-MAPPING-END token.
+ */
+
+static int
+yaml_parser_fetch_flow_collection_end(yaml_parser_t *parser,
+ yaml_token_type_t type)
+{
+ yaml_mark_t start_mark, end_mark;
+ yaml_token_t token;
+
+ /* Reset any potential simple key on the current flow level. */
+
+ if (!yaml_parser_remove_simple_key(parser))
+ return 0;
+
+ /* Decrease the flow level. */
+
+ if (!yaml_parser_decrease_flow_level(parser))
+ return 0;
+
+ /* No simple keys after the indicators ']' and '}'. */
+
+ parser->simple_key_allowed = 0;
+
+ /* Consume the token. */
+
+ start_mark = parser->mark;
+ SKIP(parser);
+ end_mark = parser->mark;
+
+ /* Create the FLOW-SEQUENCE-END of FLOW-MAPPING-END token. */
+
+ TOKEN_INIT(token, type, start_mark, end_mark);
+
+ /* Append the token to the queue. */
+
+ if (!ENQUEUE(parser, parser->tokens, token))
+ return 0;
+
+ return 1;
+}
+
+/*
+ * Produce the FLOW-ENTRY token.
+ */
+
+static int
+yaml_parser_fetch_flow_entry(yaml_parser_t *parser)
+{
+ yaml_mark_t start_mark, end_mark;
+ yaml_token_t token;
+
+ /* Reset any potential simple keys on the current flow level. */
+
+ if (!yaml_parser_remove_simple_key(parser))
+ return 0;
+
+ /* Simple keys are allowed after ','. */
+
+ parser->simple_key_allowed = 1;
+
+ /* Consume the token. */
+
+ start_mark = parser->mark;
+ SKIP(parser);
+ end_mark = parser->mark;
+
+ /* Create the FLOW-ENTRY token and append it to the queue. */
+
+ TOKEN_INIT(token, YAML_FLOW_ENTRY_TOKEN, start_mark, end_mark);
+
+ if (!ENQUEUE(parser, parser->tokens, token))
+ return 0;
+
+ return 1;
+}
+
+/*
+ * Produce the BLOCK-ENTRY token.
+ */
+
+static int
+yaml_parser_fetch_block_entry(yaml_parser_t *parser)
+{
+ yaml_mark_t start_mark, end_mark;
+ yaml_token_t token;
+
+ /* Check if the scanner is in the block context. */
+
+ if (!parser->flow_level)
+ {
+ /* Check if we are allowed to start a new entry. */
+
+ if (!parser->simple_key_allowed) {
+ return yaml_parser_set_scanner_error(parser, NULL, parser->mark,
+ "block sequence entries are not allowed in this context");
+ }
+
+ /* Add the BLOCK-SEQUENCE-START token if needed. */
+
+ if (!yaml_parser_roll_indent(parser, parser->mark.column, -1,
+ YAML_BLOCK_SEQUENCE_START_TOKEN, parser->mark))
+ return 0;
+ }
+ else
+ {
+ /*
+ * It is an error for the '-' indicator to occur in the flow context,
+ * but we let the Parser detect and report about it because the Parser
+ * is able to point to the context.
+ */
+ }
+
+ /* Reset any potential simple keys on the current flow level. */
+
+ if (!yaml_parser_remove_simple_key(parser))
+ return 0;
+
+ /* Simple keys are allowed after '-'. */
+
+ parser->simple_key_allowed = 1;
+
+ /* Consume the token. */
+
+ start_mark = parser->mark;
+ SKIP(parser);
+ end_mark = parser->mark;
+
+ /* Create the BLOCK-ENTRY token and append it to the queue. */
+
+ TOKEN_INIT(token, YAML_BLOCK_ENTRY_TOKEN, start_mark, end_mark);
+
+ if (!ENQUEUE(parser, parser->tokens, token))
+ return 0;
+
+ return 1;
+}
+
+/*
+ * Produce the KEY token.
+ */
+
+static int
+yaml_parser_fetch_key(yaml_parser_t *parser)
+{
+ yaml_mark_t start_mark, end_mark;
+ yaml_token_t token;
+
+ /* In the block context, additional checks are required. */
+
+ if (!parser->flow_level)
+ {
+ /* Check if we are allowed to start a new key (not nessesary simple). */
+
+ if (!parser->simple_key_allowed) {
+ return yaml_parser_set_scanner_error(parser, NULL, parser->mark,
+ "mapping keys are not allowed in this context");
+ }
+
+ /* Add the BLOCK-MAPPING-START token if needed. */
+
+ if (!yaml_parser_roll_indent(parser, parser->mark.column, -1,
+ YAML_BLOCK_MAPPING_START_TOKEN, parser->mark))
+ return 0;
+ }
+
+ /* Reset any potential simple keys on the current flow level. */
+
+ if (!yaml_parser_remove_simple_key(parser))
+ return 0;
+
+ /* Simple keys are allowed after '?' in the block context. */
+
+ parser->simple_key_allowed = (!parser->flow_level);
+
+ /* Consume the token. */
+
+ start_mark = parser->mark;
+ SKIP(parser);
+ end_mark = parser->mark;
+
+ /* Create the KEY token and append it to the queue. */
+
+ TOKEN_INIT(token, YAML_KEY_TOKEN, start_mark, end_mark);
+
+ if (!ENQUEUE(parser, parser->tokens, token))
+ return 0;
+
+ return 1;
+}
+
+/*
+ * Produce the VALUE token.
+ */
+
+static int
+yaml_parser_fetch_value(yaml_parser_t *parser)
+{
+ yaml_mark_t start_mark, end_mark;
+ yaml_token_t token;
+ yaml_simple_key_t *simple_key = parser->simple_keys.top-1;
+
+ /* Have we found a simple key? */
+
+ if (simple_key->possible)
+ {
+
+ /* Create the KEY token and insert it into the queue. */
+
+ TOKEN_INIT(token, YAML_KEY_TOKEN, simple_key->mark, simple_key->mark);
+
+ if (!QUEUE_INSERT(parser, parser->tokens,
+ simple_key->token_number - parser->tokens_parsed, token))
+ return 0;
+
+ /* In the block context, we may need to add the BLOCK-MAPPING-START token. */
+
+ if (!yaml_parser_roll_indent(parser, simple_key->mark.column,
+ simple_key->token_number,
+ YAML_BLOCK_MAPPING_START_TOKEN, simple_key->mark))
+ return 0;
+
+ /* Remove the simple key. */
+
+ simple_key->possible = 0;
+
+ /* A simple key cannot follow another simple key. */
+
+ parser->simple_key_allowed = 0;
+ }
+ else
+ {
+ /* The ':' indicator follows a complex key. */
+
+ /* In the block context, extra checks are required. */
+
+ if (!parser->flow_level)
+ {
+ /* Check if we are allowed to start a complex value. */
+
+ if (!parser->simple_key_allowed) {
+ return yaml_parser_set_scanner_error(parser, NULL, parser->mark,
+ "mapping values are not allowed in this context");
+ }
+
+ /* Add the BLOCK-MAPPING-START token if needed. */
+
+ if (!yaml_parser_roll_indent(parser, parser->mark.column, -1,
+ YAML_BLOCK_MAPPING_START_TOKEN, parser->mark))
+ return 0;
+ }
+
+ /* Simple keys after ':' are allowed in the block context. */
+
+ parser->simple_key_allowed = (!parser->flow_level);
+ }
+
+ /* Consume the token. */
+
+ start_mark = parser->mark;
+ SKIP(parser);
+ end_mark = parser->mark;
+
+ /* Create the VALUE token and append it to the queue. */
+
+ TOKEN_INIT(token, YAML_VALUE_TOKEN, start_mark, end_mark);
+
+ if (!ENQUEUE(parser, parser->tokens, token))
+ return 0;
+
+ return 1;
+}
+
+/*
+ * Produce the ALIAS or ANCHOR token.
+ */
+
+static int
+yaml_parser_fetch_anchor(yaml_parser_t *parser, yaml_token_type_t type)
+{
+ yaml_token_t token;
+
+ /* An anchor or an alias could be a simple key. */
+
+ if (!yaml_parser_save_simple_key(parser))
+ return 0;
+
+ /* A simple key cannot follow an anchor or an alias. */
+
+ parser->simple_key_allowed = 0;
+
+ /* Create the ALIAS or ANCHOR token and append it to the queue. */
+
+ if (!yaml_parser_scan_anchor(parser, &token, type))
+ return 0;
+
+ if (!ENQUEUE(parser, parser->tokens, token)) {
+ yaml_token_delete(&token);
+ return 0;
+ }
+ return 1;
+}
+
+/*
+ * Produce the TAG token.
+ */
+
+static int
+yaml_parser_fetch_tag(yaml_parser_t *parser)
+{
+ yaml_token_t token;
+
+ /* A tag could be a simple key. */
+
+ if (!yaml_parser_save_simple_key(parser))
+ return 0;
+
+ /* A simple key cannot follow a tag. */
+
+ parser->simple_key_allowed = 0;
+
+ /* Create the TAG token and append it to the queue. */
+
+ if (!yaml_parser_scan_tag(parser, &token))
+ return 0;
+
+ if (!ENQUEUE(parser, parser->tokens, token)) {
+ yaml_token_delete(&token);
+ return 0;
+ }
+
+ return 1;
+}
+
+/*
+ * Produce the SCALAR(...,literal) or SCALAR(...,folded) tokens.
+ */
+
+static int
+yaml_parser_fetch_block_scalar(yaml_parser_t *parser, int literal)
+{
+ yaml_token_t token;
+
+ /* Remove any potential simple keys. */
+
+ if (!yaml_parser_remove_simple_key(parser))
+ return 0;
+
+ /* A simple key may follow a block scalar. */
+
+ parser->simple_key_allowed = 1;
+
+ /* Create the SCALAR token and append it to the queue. */
+
+ if (!yaml_parser_scan_block_scalar(parser, &token, literal))
+ return 0;
+
+ if (!ENQUEUE(parser, parser->tokens, token)) {
+ yaml_token_delete(&token);
+ return 0;
+ }
+
+ return 1;
+}
+
+/*
+ * Produce the SCALAR(...,single-quoted) or SCALAR(...,double-quoted) tokens.
+ */
+
+static int
+yaml_parser_fetch_flow_scalar(yaml_parser_t *parser, int single)
+{
+ yaml_token_t token;
+
+ /* A plain scalar could be a simple key. */
+
+ if (!yaml_parser_save_simple_key(parser))
+ return 0;
+
+ /* A simple key cannot follow a flow scalar. */
+
+ parser->simple_key_allowed = 0;
+
+ /* Create the SCALAR token and append it to the queue. */
+
+ if (!yaml_parser_scan_flow_scalar(parser, &token, single))
+ return 0;
+
+ if (!ENQUEUE(parser, parser->tokens, token)) {
+ yaml_token_delete(&token);
+ return 0;
+ }
+
+ return 1;
+}
+
+/*
+ * Produce the SCALAR(...,plain) token.
+ */
+
+static int
+yaml_parser_fetch_plain_scalar(yaml_parser_t *parser)
+{
+ yaml_token_t token;
+
+ /* A plain scalar could be a simple key. */
+
+ if (!yaml_parser_save_simple_key(parser))
+ return 0;
+
+ /* A simple key cannot follow a flow scalar. */
+
+ parser->simple_key_allowed = 0;
+
+ /* Create the SCALAR token and append it to the queue. */
+
+ if (!yaml_parser_scan_plain_scalar(parser, &token))
+ return 0;
+
+ if (!ENQUEUE(parser, parser->tokens, token)) {
+ yaml_token_delete(&token);
+ return 0;
+ }
+
+ return 1;
+}
+
+/*
+ * Eat whitespaces and comments until the next token is found.
+ */
+
+static int
+yaml_parser_scan_to_next_token(yaml_parser_t *parser)
+{
+ /* Until the next token is not found. */
+
+ while (1)
+ {
+ /* Allow the BOM mark to start a line. */
+
+ if (!CACHE(parser, 1)) return 0;
+
+ if (parser->mark.column == 0 && IS_BOM(parser->buffer))
+ SKIP(parser);
+
+ /*
+ * Eat whitespaces.
+ *
+ * Tabs are allowed:
+ *
+ * - in the flow context;
+ * - in the block context, but not at the beginning of the line or
+ * after '-', '?', or ':' (complex value).
+ */
+
+ if (!CACHE(parser, 1)) return 0;
+
+ while (CHECK(parser->buffer,' ') ||
+ ((parser->flow_level || !parser->simple_key_allowed) &&
+ CHECK(parser->buffer, '\t'))) {
+ SKIP(parser);
+ if (!CACHE(parser, 1)) return 0;
+ }
+
+ /* Eat a comment until a line break. */
+
+ if (CHECK(parser->buffer, '#')) {
+ while (!IS_BREAKZ(parser->buffer)) {
+ SKIP(parser);
+ if (!CACHE(parser, 1)) return 0;
+ }
+ }
+
+ /* If it is a line break, eat it. */
+
+ if (IS_BREAK(parser->buffer))
+ {
+ if (!CACHE(parser, 2)) return 0;
+ SKIP_LINE(parser);
+
+ /* In the block context, a new line may start a simple key. */
+
+ if (!parser->flow_level) {
+ parser->simple_key_allowed = 1;
+ }
+ }
+ else
+ {
+ /* We have found a token. */
+
+ break;
+ }
+ }
+
+ return 1;
+}
+
+/*
+ * Scan a YAML-DIRECTIVE or TAG-DIRECTIVE token.
+ *
+ * Scope:
+ * %YAML 1.1 # a comment \n
+ * ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ * %TAG !yaml! tag:yaml.org,2002: \n
+ * ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ */
+
+int
+yaml_parser_scan_directive(yaml_parser_t *parser, yaml_token_t *token)
+{
+ yaml_mark_t start_mark, end_mark;
+ yaml_char_t *name = NULL;
+ int major, minor;
+ yaml_char_t *handle = NULL, *prefix = NULL;
+
+ /* Eat '%'. */
+
+ start_mark = parser->mark;
+
+ SKIP(parser);
+
+ /* Scan the directive name. */
+
+ if (!yaml_parser_scan_directive_name(parser, start_mark, &name))
+ goto error;
+
+ /* Is it a YAML directive? */
+
+ if (strcmp((char *)name, "YAML") == 0)
+ {
+ /* Scan the VERSION directive value. */
+
+ if (!yaml_parser_scan_version_directive_value(parser, start_mark,
+ &major, &minor))
+ goto error;
+
+ end_mark = parser->mark;
+
+ /* Create a VERSION-DIRECTIVE token. */
+
+ VERSION_DIRECTIVE_TOKEN_INIT(*token, major, minor,
+ start_mark, end_mark);
+ }
+
+ /* Is it a TAG directive? */
+
+ else if (strcmp((char *)name, "TAG") == 0)
+ {
+ /* Scan the TAG directive value. */
+
+ if (!yaml_parser_scan_tag_directive_value(parser, start_mark,
+ &handle, &prefix))
+ goto error;
+
+ end_mark = parser->mark;
+
+ /* Create a TAG-DIRECTIVE token. */
+
+ TAG_DIRECTIVE_TOKEN_INIT(*token, handle, prefix,
+ start_mark, end_mark);
+ }
+
+ /* Unknown directive. */
+
+ else
+ {
+ yaml_parser_set_scanner_error(parser, "while scanning a directive",
+ start_mark, "found uknown directive name");
+ goto error;
+ }
+
+ /* Eat the rest of the line including any comments. */
+
+ if (!CACHE(parser, 1)) goto error;
+
+ while (IS_BLANK(parser->buffer)) {
+ SKIP(parser);
+ if (!CACHE(parser, 1)) goto error;
+ }
+
+ if (CHECK(parser->buffer, '#')) {
+ while (!IS_BREAKZ(parser->buffer)) {
+ SKIP(parser);
+ if (!CACHE(parser, 1)) goto error;
+ }
+ }
+
+ /* Check if we are at the end of the line. */
+
+ if (!IS_BREAKZ(parser->buffer)) {
+ yaml_parser_set_scanner_error(parser, "while scanning a directive",
+ start_mark, "did not find expected comment or line break");
+ goto error;
+ }
+
+ /* Eat a line break. */
+
+ if (IS_BREAK(parser->buffer)) {
+ if (!CACHE(parser, 2)) goto error;
+ SKIP_LINE(parser);
+ }
+
+ yaml_free(name);
+
+ return 1;
+
+error:
+ yaml_free(prefix);
+ yaml_free(handle);
+ yaml_free(name);
+ return 0;
+}
+
+/*
+ * Scan the directive name.
+ *
+ * Scope:
+ * %YAML 1.1 # a comment \n
+ * ^^^^
+ * %TAG !yaml! tag:yaml.org,2002: \n
+ * ^^^
+ */
+
+static int
+yaml_parser_scan_directive_name(yaml_parser_t *parser,
+ yaml_mark_t start_mark, yaml_char_t **name)
+{
+ yaml_string_t string = NULL_STRING;
+
+ if (!STRING_INIT(parser, string, INITIAL_STRING_SIZE)) goto error;
+
+ /* Consume the directive name. */
+
+ if (!CACHE(parser, 1)) goto error;
+
+ while (IS_ALPHA(parser->buffer))
+ {
+ if (!READ(parser, string)) goto error;
+ if (!CACHE(parser, 1)) goto error;
+ }
+
+ /* Check if the name is empty. */
+
+ if (string.start == string.pointer) {
+ yaml_parser_set_scanner_error(parser, "while scanning a directive",
+ start_mark, "could not find expected directive name");
+ goto error;
+ }
+
+ /* Check for an blank character after the name. */
+
+ if (!IS_BLANKZ(parser->buffer)) {
+ yaml_parser_set_scanner_error(parser, "while scanning a directive",
+ start_mark, "found unexpected non-alphabetical character");
+ goto error;
+ }
+
+ *name = string.start;
+
+ return 1;
+
+error:
+ STRING_DEL(parser, string);
+ return 0;
+}
+
+/*
+ * Scan the value of VERSION-DIRECTIVE.
+ *
+ * Scope:
+ * %YAML 1.1 # a comment \n
+ * ^^^^^^
+ */
+
+static int
+yaml_parser_scan_version_directive_value(yaml_parser_t *parser,
+ yaml_mark_t start_mark, int *major, int *minor)
+{
+ /* Eat whitespaces. */
+
+ if (!CACHE(parser, 1)) return 0;
+
+ while (IS_BLANK(parser->buffer)) {
+ SKIP(parser);
+ if (!CACHE(parser, 1)) return 0;
+ }
+
+ /* Consume the major version number. */
+
+ if (!yaml_parser_scan_version_directive_number(parser, start_mark, major))
+ return 0;
+
+ /* Eat '.'. */
+
+ if (!CHECK(parser->buffer, '.')) {
+ return yaml_parser_set_scanner_error(parser, "while scanning a %YAML directive",
+ start_mark, "did not find expected digit or '.' character");
+ }
+
+ SKIP(parser);
+
+ /* Consume the minor version number. */
+
+ if (!yaml_parser_scan_version_directive_number(parser, start_mark, minor))
+ return 0;
+
+ return 1;
+}
+
+#define MAX_NUMBER_LENGTH 9
+
+/*
+ * Scan the version number of VERSION-DIRECTIVE.
+ *
+ * Scope:
+ * %YAML 1.1 # a comment \n
+ * ^
+ * %YAML 1.1 # a comment \n
+ * ^
+ */
+
+static int
+yaml_parser_scan_version_directive_number(yaml_parser_t *parser,
+ yaml_mark_t start_mark, int *number)
+{
+ int value = 0;
+ size_t length = 0;
+
+ /* Repeat while the next character is digit. */
+
+ if (!CACHE(parser, 1)) return 0;
+
+ while (IS_DIGIT(parser->buffer))
+ {
+ /* Check if the number is too long. */
+
+ if (++length > MAX_NUMBER_LENGTH) {
+ return yaml_parser_set_scanner_error(parser, "while scanning a %YAML directive",
+ start_mark, "found extremely long version number");
+ }
+
+ value = value*10 + AS_DIGIT(parser->buffer);
+
+ SKIP(parser);
+
+ if (!CACHE(parser, 1)) return 0;
+ }
+
+ /* Check if the number was present. */
+
+ if (!length) {
+ return yaml_parser_set_scanner_error(parser, "while scanning a %YAML directive",
+ start_mark, "did not find expected version number");
+ }
+
+ *number = value;
+
+ return 1;
+}
+
+/*
+ * Scan the value of a TAG-DIRECTIVE token.
+ *
+ * Scope:
+ * %TAG !yaml! tag:yaml.org,2002: \n
+ * ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ */
+
+static int
+yaml_parser_scan_tag_directive_value(yaml_parser_t *parser,
+ yaml_mark_t start_mark, yaml_char_t **handle, yaml_char_t **prefix)
+{
+ yaml_char_t *handle_value = NULL;
+ yaml_char_t *prefix_value = NULL;
+
+ /* Eat whitespaces. */
+
+ if (!CACHE(parser, 1)) goto error;
+
+ while (IS_BLANK(parser->buffer)) {
+ SKIP(parser);
+ if (!CACHE(parser, 1)) goto error;
+ }
+
+ /* Scan a handle. */
+
+ if (!yaml_parser_scan_tag_handle(parser, 1, start_mark, &handle_value))
+ goto error;
+
+ /* Expect a whitespace. */
+
+ if (!CACHE(parser, 1)) goto error;
+
+ if (!IS_BLANK(parser->buffer)) {
+ yaml_parser_set_scanner_error(parser, "while scanning a %TAG directive",
+ start_mark, "did not find expected whitespace");
+ goto error;
+ }
+
+ /* Eat whitespaces. */
+
+ while (IS_BLANK(parser->buffer)) {
+ SKIP(parser);
+ if (!CACHE(parser, 1)) goto error;
+ }
+
+ /* Scan a prefix. */
+
+ if (!yaml_parser_scan_tag_uri(parser, 1, NULL, start_mark, &prefix_value))
+ goto error;
+
+ /* Expect a whitespace or line break. */
+
+ if (!CACHE(parser, 1)) goto error;
+
+ if (!IS_BLANKZ(parser->buffer)) {
+ yaml_parser_set_scanner_error(parser, "while scanning a %TAG directive",
+ start_mark, "did not find expected whitespace or line break");
+ goto error;
+ }
+
+ *handle = handle_value;
+ *prefix = prefix_value;
+
+ return 1;
+
+error:
+ yaml_free(handle_value);
+ yaml_free(prefix_value);
+ return 0;
+}
+
+static int
+yaml_parser_scan_anchor(yaml_parser_t *parser, yaml_token_t *token,
+ yaml_token_type_t type)
+{
+ int length = 0;
+ yaml_mark_t start_mark, end_mark;
+ yaml_string_t string = NULL_STRING;
+
+ if (!STRING_INIT(parser, string, INITIAL_STRING_SIZE)) goto error;
+
+ /* Eat the indicator character. */
+
+ start_mark = parser->mark;
+
+ SKIP(parser);
+
+ /* Consume the value. */
+
+ if (!CACHE(parser, 1)) goto error;
+
+ while (IS_ALPHA(parser->buffer)) {
+ if (!READ(parser, string)) goto error;
+ if (!CACHE(parser, 1)) goto error;
+ length ++;
+ }
+
+ end_mark = parser->mark;
+
+ /*
+ * Check if length of the anchor is greater than 0 and it is followed by
+ * a whitespace character or one of the indicators:
+ *
+ * '?', ':', ',', ']', '}', '%', '@', '`'.
+ */
+
+ if (!length || !(IS_BLANKZ(parser->buffer) || CHECK(parser->buffer, '?')
+ || CHECK(parser->buffer, ':') || CHECK(parser->buffer, ',')
+ || CHECK(parser->buffer, ']') || CHECK(parser->buffer, '}')
+ || CHECK(parser->buffer, '%') || CHECK(parser->buffer, '@')
+ || CHECK(parser->buffer, '`'))) {
+ yaml_parser_set_scanner_error(parser, type == YAML_ANCHOR_TOKEN ?
+ "while scanning an anchor" : "while scanning an alias", start_mark,
+ "did not find expected alphabetic or numeric character");
+ goto error;
+ }
+
+ /* Create a token. */
+
+ if (type == YAML_ANCHOR_TOKEN) {
+ ANCHOR_TOKEN_INIT(*token, string.start, start_mark, end_mark);
+ }
+ else {
+ ALIAS_TOKEN_INIT(*token, string.start, start_mark, end_mark);
+ }
+
+ return 1;
+
+error:
+ STRING_DEL(parser, string);
+ return 0;
+}
+
+/*
+ * Scan a TAG token.
+ */
+
+static int
+yaml_parser_scan_tag(yaml_parser_t *parser, yaml_token_t *token)
+{
+ yaml_char_t *handle = NULL;
+ yaml_char_t *suffix = NULL;
+ yaml_mark_t start_mark, end_mark;
+
+ start_mark = parser->mark;
+
+ /* Check if the tag is in the canonical form. */
+
+ if (!CACHE(parser, 2)) goto error;
+
+ if (CHECK_AT(parser->buffer, '<', 1))
+ {
+ /* Set the handle to '' */
+
+ handle = yaml_malloc(1);
+ if (!handle) goto error;
+ handle[0] = '\0';
+
+ /* Eat '!<' */
+
+ SKIP(parser);
+ SKIP(parser);
+
+ /* Consume the tag value. */
+
+ if (!yaml_parser_scan_tag_uri(parser, 0, NULL, start_mark, &suffix))
+ goto error;
+
+ /* Check for '>' and eat it. */
+
+ if (!CHECK(parser->buffer, '>')) {
+ yaml_parser_set_scanner_error(parser, "while scanning a tag",
+ start_mark, "did not find the expected '>'");
+ goto error;
+ }
+
+ SKIP(parser);
+ }
+ else
+ {
+ /* The tag has either the '!suffix' or the '!handle!suffix' form. */
+
+ /* First, try to scan a handle. */
+
+ if (!yaml_parser_scan_tag_handle(parser, 0, start_mark, &handle))
+ goto error;
+
+ /* Check if it is, indeed, handle. */
+
+ if (handle[0] == '!' && handle[1] != '\0' && handle[strlen((char *)handle)-1] == '!')
+ {
+ /* Scan the suffix now. */
+
+ if (!yaml_parser_scan_tag_uri(parser, 0, NULL, start_mark, &suffix))
+ goto error;
+ }
+ else
+ {
+ /* It wasn't a handle after all. Scan the rest of the tag. */
+
+ if (!yaml_parser_scan_tag_uri(parser, 0, handle, start_mark, &suffix))
+ goto error;
+
+ /* Set the handle to '!'. */
+
+ yaml_free(handle);
+ handle = yaml_malloc(2);
+ if (!handle) goto error;
+ handle[0] = '!';
+ handle[1] = '\0';
+
+ /*
+ * A special case: the '!' tag. Set the handle to '' and the
+ * suffix to '!'.
+ */
+
+ if (suffix[0] == '\0') {
+ yaml_char_t *tmp = handle;
+ handle = suffix;
+ suffix = tmp;
+ }
+ }
+ }
+
+ /* Check the character which ends the tag. */
+
+ if (!CACHE(parser, 1)) goto error;
+
+ if (!IS_BLANKZ(parser->buffer)) {
+ yaml_parser_set_scanner_error(parser, "while scanning a tag",
+ start_mark, "did not find expected whitespace or line break");
+ goto error;
+ }
+
+ end_mark = parser->mark;
+
+ /* Create a token. */
+
+ TAG_TOKEN_INIT(*token, handle, suffix, start_mark, end_mark);
+
+ return 1;
+
+error:
+ yaml_free(handle);
+ yaml_free(suffix);
+ return 0;
+}
+
+/*
+ * Scan a tag handle.
+ */
+
+static int
+yaml_parser_scan_tag_handle(yaml_parser_t *parser, int directive,
+ yaml_mark_t start_mark, yaml_char_t **handle)
+{
+ yaml_string_t string = NULL_STRING;
+
+ if (!STRING_INIT(parser, string, INITIAL_STRING_SIZE)) goto error;
+
+ /* Check the initial '!' character. */
+
+ if (!CACHE(parser, 1)) goto error;
+
+ if (!CHECK(parser->buffer, '!')) {
+ yaml_parser_set_scanner_error(parser, directive ?
+ "while scanning a tag directive" : "while scanning a tag",
+ start_mark, "did not find expected '!'");
+ goto error;
+ }
+
+ /* Copy the '!' character. */
+
+ if (!READ(parser, string)) goto error;
+
+ /* Copy all subsequent alphabetical and numerical characters. */
+
+ if (!CACHE(parser, 1)) goto error;
+
+ while (IS_ALPHA(parser->buffer))
+ {
+ if (!READ(parser, string)) goto error;
+ if (!CACHE(parser, 1)) goto error;
+ }
+
+ /* Check if the trailing character is '!' and copy it. */
+
+ if (CHECK(parser->buffer, '!'))
+ {
+ if (!READ(parser, string)) goto error;
+ }
+ else
+ {
+ /*
+ * It's either the '!' tag or not really a tag handle. If it's a %TAG
+ * directive, it's an error. If it's a tag token, it must be a part of
+ * URI.
+ */
+
+ if (directive && !(string.start[0] == '!' && string.start[1] == '\0')) {
+ yaml_parser_set_scanner_error(parser, "while parsing a tag directive",
+ start_mark, "did not find expected '!'");
+ goto error;
+ }
+ }
+
+ *handle = string.start;
+
+ return 1;
+
+error:
+ STRING_DEL(parser, string);
+ return 0;
+}
+
+/*
+ * Scan a tag.
+ */
+
+static int
+yaml_parser_scan_tag_uri(yaml_parser_t *parser, int directive,
+ yaml_char_t *head, yaml_mark_t start_mark, yaml_char_t **uri)
+{
+ size_t length = head ? strlen((char *)head) : 0;
+ yaml_string_t string = NULL_STRING;
+
+ if (!STRING_INIT(parser, string, INITIAL_STRING_SIZE)) goto error;
+
+ /* Resize the string to include the head. */
+
+ while (string.end - string.start <= (int)length) {
+ if (!yaml_string_extend(&string.start, &string.pointer, &string.end)) {
+ parser->error = YAML_MEMORY_ERROR;
+ goto error;
+ }
+ }
+
+ /*
+ * Copy the head if needed.
+ *
+ * Note that we don't copy the leading '!' character.
+ */
+
+ if (length > 1) {
+ memcpy(string.start, head+1, length-1);
+ string.pointer += length-1;
+ }
+
+ /* Scan the tag. */
+
+ if (!CACHE(parser, 1)) goto error;
+
+ /*
+ * The set of characters that may appear in URI is as follows:
+ *
+ * '0'-'9', 'A'-'Z', 'a'-'z', '_', '-', ';', '/', '?', ':', '@', '&',
+ * '=', '+', '$', ',', '.', '!', '~', '*', '\'', '(', ')', '[', ']',
+ * '%'.
+ */
+
+ while (IS_ALPHA(parser->buffer) || CHECK(parser->buffer, ';')
+ || CHECK(parser->buffer, '/') || CHECK(parser->buffer, '?')
+ || CHECK(parser->buffer, ':') || CHECK(parser->buffer, '@')
+ || CHECK(parser->buffer, '&') || CHECK(parser->buffer, '=')
+ || CHECK(parser->buffer, '+') || CHECK(parser->buffer, '$')
+ || CHECK(parser->buffer, ',') || CHECK(parser->buffer, '.')
+ || CHECK(parser->buffer, '!') || CHECK(parser->buffer, '~')
+ || CHECK(parser->buffer, '*') || CHECK(parser->buffer, '\'')
+ || CHECK(parser->buffer, '(') || CHECK(parser->buffer, ')')
+ || CHECK(parser->buffer, '[') || CHECK(parser->buffer, ']')
+ || CHECK(parser->buffer, '%'))
+ {
+ /* Check if it is a URI-escape sequence. */
+
+ if (CHECK(parser->buffer, '%')) {
+ if (!yaml_parser_scan_uri_escapes(parser,
+ directive, start_mark, &string)) goto error;
+ }
+ else {
+ if (!READ(parser, string)) goto error;
+ }
+
+ length ++;
+ if (!CACHE(parser, 1)) goto error;
+ }
+
+ /* Check if the tag is non-empty. */
+
+ if (!length) {
+ if (!STRING_EXTEND(parser, string))
+ goto error;
+
+ yaml_parser_set_scanner_error(parser, directive ?
+ "while parsing a %TAG directive" : "while parsing a tag",
+ start_mark, "did not find expected tag URI");
+ goto error;
+ }
+
+ *uri = string.start;
+
+ return 1;
+
+error:
+ STRING_DEL(parser, string);
+ return 0;
+}
+
+/*
+ * Decode an URI-escape sequence corresponding to a single UTF-8 character.
+ */
+
+static int
+yaml_parser_scan_uri_escapes(yaml_parser_t *parser, int directive,
+ yaml_mark_t start_mark, yaml_string_t *string)
+{
+ int width = 0;
+
+ /* Decode the required number of characters. */
+
+ do {
+
+ unsigned char octet = 0;
+
+ /* Check for a URI-escaped octet. */
+
+ if (!CACHE(parser, 3)) return 0;
+
+ if (!(CHECK(parser->buffer, '%')
+ && IS_HEX_AT(parser->buffer, 1)
+ && IS_HEX_AT(parser->buffer, 2))) {
+ return yaml_parser_set_scanner_error(parser, directive ?
+ "while parsing a %TAG directive" : "while parsing a tag",
+ start_mark, "did not find URI escaped octet");
+ }
+
+ /* Get the octet. */
+
+ octet = (AS_HEX_AT(parser->buffer, 1) << 4) + AS_HEX_AT(parser->buffer, 2);
+
+ /* If it is the leading octet, determine the length of the UTF-8 sequence. */
+
+ if (!width)
+ {
+ width = (octet & 0x80) == 0x00 ? 1 :
+ (octet & 0xE0) == 0xC0 ? 2 :
+ (octet & 0xF0) == 0xE0 ? 3 :
+ (octet & 0xF8) == 0xF0 ? 4 : 0;
+ if (!width) {
+ return yaml_parser_set_scanner_error(parser, directive ?
+ "while parsing a %TAG directive" : "while parsing a tag",
+ start_mark, "found an incorrect leading UTF-8 octet");
+ }
+ }
+ else
+ {
+ /* Check if the trailing octet is correct. */
+
+ if ((octet & 0xC0) != 0x80) {
+ return yaml_parser_set_scanner_error(parser, directive ?
+ "while parsing a %TAG directive" : "while parsing a tag",
+ start_mark, "found an incorrect trailing UTF-8 octet");
+ }
+ }
+
+ /* Copy the octet and move the pointers. */
+
+ *(string->pointer++) = octet;
+ SKIP(parser);
+ SKIP(parser);
+ SKIP(parser);
+
+ } while (--width);
+
+ return 1;
+}
+
+/*
+ * Scan a block scalar.
+ */
+
+static int
+yaml_parser_scan_block_scalar(yaml_parser_t *parser, yaml_token_t *token,
+ int literal)
+{
+ yaml_mark_t start_mark;
+ yaml_mark_t end_mark;
+ yaml_string_t string = NULL_STRING;
+ yaml_string_t leading_break = NULL_STRING;
+ yaml_string_t trailing_breaks = NULL_STRING;
+ int chomping = 0;
+ int increment = 0;
+ int indent = 0;
+ int leading_blank = 0;
+ int trailing_blank = 0;
+
+ if (!STRING_INIT(parser, string, INITIAL_STRING_SIZE)) goto error;
+ if (!STRING_INIT(parser, leading_break, INITIAL_STRING_SIZE)) goto error;
+ if (!STRING_INIT(parser, trailing_breaks, INITIAL_STRING_SIZE)) goto error;
+
+ /* Eat the indicator '|' or '>'. */
+
+ start_mark = parser->mark;
+
+ SKIP(parser);
+
+ /* Scan the additional block scalar indicators. */
+
+ if (!CACHE(parser, 1)) goto error;
+
+ /* Check for a chomping indicator. */
+
+ if (CHECK(parser->buffer, '+') || CHECK(parser->buffer, '-'))
+ {
+ /* Set the chomping method and eat the indicator. */
+
+ chomping = CHECK(parser->buffer, '+') ? +1 : -1;
+
+ SKIP(parser);
+
+ /* Check for an indentation indicator. */
+
+ if (!CACHE(parser, 1)) goto error;
+
+ if (IS_DIGIT(parser->buffer))
+ {
+ /* Check that the intendation is greater than 0. */
+
+ if (CHECK(parser->buffer, '0')) {
+ yaml_parser_set_scanner_error(parser, "while scanning a block scalar",
+ start_mark, "found an intendation indicator equal to 0");
+ goto error;
+ }
+
+ /* Get the intendation level and eat the indicator. */
+
+ increment = AS_DIGIT(parser->buffer);
+
+ SKIP(parser);
+ }
+ }
+
+ /* Do the same as above, but in the opposite order. */
+
+ else if (IS_DIGIT(parser->buffer))
+ {
+ if (CHECK(parser->buffer, '0')) {
+ yaml_parser_set_scanner_error(parser, "while scanning a block scalar",
+ start_mark, "found an intendation indicator equal to 0");
+ goto error;
+ }
+
+ increment = AS_DIGIT(parser->buffer);
+
+ SKIP(parser);
+
+ if (!CACHE(parser, 1)) goto error;
+
+ if (CHECK(parser->buffer, '+') || CHECK(parser->buffer, '-')) {
+ chomping = CHECK(parser->buffer, '+') ? +1 : -1;
+
+ SKIP(parser);
+ }
+ }
+
+ /* Eat whitespaces and comments to the end of the line. */
+
+ if (!CACHE(parser, 1)) goto error;
+
+ while (IS_BLANK(parser->buffer)) {
+ SKIP(parser);
+ if (!CACHE(parser, 1)) goto error;
+ }
+
+ if (CHECK(parser->buffer, '#')) {
+ while (!IS_BREAKZ(parser->buffer)) {
+ SKIP(parser);
+ if (!CACHE(parser, 1)) goto error;
+ }
+ }
+
+ /* Check if we are at the end of the line. */
+
+ if (!IS_BREAKZ(parser->buffer)) {
+ yaml_parser_set_scanner_error(parser, "while scanning a block scalar",
+ start_mark, "did not find expected comment or line break");
+ goto error;
+ }
+
+ /* Eat a line break. */
+
+ if (IS_BREAK(parser->buffer)) {
+ if (!CACHE(parser, 2)) goto error;
+ SKIP_LINE(parser);
+ }
+
+ end_mark = parser->mark;
+
+ /* Set the intendation level if it was specified. */
+
+ if (increment) {
+ indent = parser->indent >= 0 ? parser->indent+increment : increment;
+ }
+
+ /* Scan the leading line breaks and determine the indentation level if needed. */
+
+ if (!yaml_parser_scan_block_scalar_breaks(parser, &indent, &trailing_breaks,
+ start_mark, &end_mark)) goto error;
+
+ /* Scan the block scalar content. */
+
+ if (!CACHE(parser, 1)) goto error;
+
+ while ((int)parser->mark.column == indent && !IS_Z(parser->buffer))
+ {
+ /*
+ * We are at the beginning of a non-empty line.
+ */
+
+ /* Is it a trailing whitespace? */
+
+ trailing_blank = IS_BLANK(parser->buffer);
+
+ /* Check if we need to fold the leading line break. */
+
+ if (!literal && (*leading_break.start == '\n')
+ && !leading_blank && !trailing_blank)
+ {
+ /* Do we need to join the lines by space? */
+
+ if (*trailing_breaks.start == '\0') {
+ if (!STRING_EXTEND(parser, string)) goto error;
+ *(string.pointer ++) = ' ';
+ }
+
+ CLEAR(parser, leading_break);
+ }
+ else {
+ if (!JOIN(parser, string, leading_break)) goto error;
+ CLEAR(parser, leading_break);
+ }
+
+ /* Append the remaining line breaks. */
+
+ if (!JOIN(parser, string, trailing_breaks)) goto error;
+ CLEAR(parser, trailing_breaks);
+
+ /* Is it a leading whitespace? */
+
+ leading_blank = IS_BLANK(parser->buffer);
+
+ /* Consume the current line. */
+
+ while (!IS_BREAKZ(parser->buffer)) {
+ if (!READ(parser, string)) goto error;
+ if (!CACHE(parser, 1)) goto error;
+ }
+
+ /* Consume the line break. */
+
+ if (!CACHE(parser, 2)) goto error;
+
+ if (!READ_LINE(parser, leading_break)) goto error;
+
+ /* Eat the following intendation spaces and line breaks. */
+
+ if (!yaml_parser_scan_block_scalar_breaks(parser,
+ &indent, &trailing_breaks, start_mark, &end_mark)) goto error;
+ }
+
+ /* Chomp the tail. */
+
+ if (chomping != -1) {
+ if (!JOIN(parser, string, leading_break)) goto error;
+ }
+ if (chomping == 1) {
+ if (!JOIN(parser, string, trailing_breaks)) goto error;
+ }
+
+ /* Create a token. */
+
+ SCALAR_TOKEN_INIT(*token, string.start, string.pointer-string.start,
+ literal ? YAML_LITERAL_SCALAR_STYLE : YAML_FOLDED_SCALAR_STYLE,
+ start_mark, end_mark);
+
+ STRING_DEL(parser, leading_break);
+ STRING_DEL(parser, trailing_breaks);
+
+ return 1;
+
+error:
+ STRING_DEL(parser, string);
+ STRING_DEL(parser, leading_break);
+ STRING_DEL(parser, trailing_breaks);
+
+ return 0;
+}
+
+/*
+ * Scan intendation spaces and line breaks for a block scalar. Determine the
+ * intendation level if needed.
+ */
+
+static int
+yaml_parser_scan_block_scalar_breaks(yaml_parser_t *parser,
+ int *indent, yaml_string_t *breaks,
+ yaml_mark_t start_mark, yaml_mark_t *end_mark)
+{
+ int max_indent = 0;
+
+ *end_mark = parser->mark;
+
+ /* Eat the intendation spaces and line breaks. */
+
+ while (1)
+ {
+ /* Eat the intendation spaces. */
+
+ if (!CACHE(parser, 1)) return 0;
+
+ while ((!*indent || (int)parser->mark.column < *indent)
+ && IS_SPACE(parser->buffer)) {
+ SKIP(parser);
+ if (!CACHE(parser, 1)) return 0;
+ }
+
+ if ((int)parser->mark.column > max_indent)
+ max_indent = (int)parser->mark.column;
+
+ /* Check for a tab character messing the intendation. */
+
+ if ((!*indent || (int)parser->mark.column < *indent)
+ && IS_TAB(parser->buffer)) {
+ return yaml_parser_set_scanner_error(parser, "while scanning a block scalar",
+ start_mark, "found a tab character where an intendation space is expected");
+ }
+
+ /* Have we found a non-empty line? */
+
+ if (!IS_BREAK(parser->buffer)) break;
+
+ /* Consume the line break. */
+
+ if (!CACHE(parser, 2)) return 0;
+ if (!READ_LINE(parser, *breaks)) return 0;
+ *end_mark = parser->mark;
+ }
+
+ /* Determine the indentation level if needed. */
+
+ if (!*indent) {
+ *indent = max_indent;
+ if (*indent < parser->indent + 1)
+ *indent = parser->indent + 1;
+ if (*indent < 1)
+ *indent = 1;
+ }
+
+ return 1;
+}
+
+/*
+ * Scan a quoted scalar.
+ */
+
+static int
+yaml_parser_scan_flow_scalar(yaml_parser_t *parser, yaml_token_t *token,
+ int single)
+{
+ yaml_mark_t start_mark;
+ yaml_mark_t end_mark;
+ yaml_string_t string = NULL_STRING;
+ yaml_string_t leading_break = NULL_STRING;
+ yaml_string_t trailing_breaks = NULL_STRING;
+ yaml_string_t whitespaces = NULL_STRING;
+ int leading_blanks;
+
+ if (!STRING_INIT(parser, string, INITIAL_STRING_SIZE)) goto error;
+ if (!STRING_INIT(parser, leading_break, INITIAL_STRING_SIZE)) goto error;
+ if (!STRING_INIT(parser, trailing_breaks, INITIAL_STRING_SIZE)) goto error;
+ if (!STRING_INIT(parser, whitespaces, INITIAL_STRING_SIZE)) goto error;
+
+ /* Eat the left quote. */
+
+ start_mark = parser->mark;
+
+ SKIP(parser);
+
+ /* Consume the content of the quoted scalar. */
+
+ while (1)
+ {
+ /* Check that there are no document indicators at the beginning of the line. */
+
+ if (!CACHE(parser, 4)) goto error;
+
+ if (parser->mark.column == 0 &&
+ ((CHECK_AT(parser->buffer, '-', 0) &&
+ CHECK_AT(parser->buffer, '-', 1) &&
+ CHECK_AT(parser->buffer, '-', 2)) ||
+ (CHECK_AT(parser->buffer, '.', 0) &&
+ CHECK_AT(parser->buffer, '.', 1) &&
+ CHECK_AT(parser->buffer, '.', 2))) &&
+ IS_BLANKZ_AT(parser->buffer, 3))
+ {
+ yaml_parser_set_scanner_error(parser, "while scanning a quoted scalar",
+ start_mark, "found unexpected document indicator");
+ goto error;
+ }
+
+ /* Check for EOF. */
+
+ if (IS_Z(parser->buffer)) {
+ yaml_parser_set_scanner_error(parser, "while scanning a quoted scalar",
+ start_mark, "found unexpected end of stream");
+ goto error;
+ }
+
+ /* Consume non-blank characters. */
+
+ if (!CACHE(parser, 2)) goto error;
+
+ leading_blanks = 0;
+
+ while (!IS_BLANKZ(parser->buffer))
+ {
+ /* Check for an escaped single quote. */
+
+ if (single && CHECK_AT(parser->buffer, '\'', 0)
+ && CHECK_AT(parser->buffer, '\'', 1))
+ {
+ if (!STRING_EXTEND(parser, string)) goto error;
+ *(string.pointer++) = '\'';
+ SKIP(parser);
+ SKIP(parser);
+ }
+
+ /* Check for the right quote. */
+
+ else if (CHECK(parser->buffer, single ? '\'' : '"'))
+ {
+ break;
+ }
+
+ /* Check for an escaped line break. */
+
+ else if (!single && CHECK(parser->buffer, '\\')
+ && IS_BREAK_AT(parser->buffer, 1))
+ {
+ if (!CACHE(parser, 3)) goto error;
+ SKIP(parser);
+ SKIP_LINE(parser);
+ leading_blanks = 1;
+ break;
+ }
+
+ /* Check for an escape sequence. */
+
+ else if (!single && CHECK(parser->buffer, '\\'))
+ {
+ size_t code_length = 0;
+
+ if (!STRING_EXTEND(parser, string)) goto error;
+
+ /* Check the escape character. */
+
+ switch (parser->buffer.pointer[1])
+ {
+ case '0':
+ *(string.pointer++) = '\0';
+ break;
+
+ case 'a':
+ *(string.pointer++) = '\x07';
+ break;
+
+ case 'b':
+ *(string.pointer++) = '\x08';
+ break;
+
+ case 't':
+ case '\t':
+ *(string.pointer++) = '\x09';
+ break;
+
+ case 'n':
+ *(string.pointer++) = '\x0A';
+ break;
+
+ case 'v':
+ *(string.pointer++) = '\x0B';
+ break;
+
+ case 'f':
+ *(string.pointer++) = '\x0C';
+ break;
+
+ case 'r':
+ *(string.pointer++) = '\x0D';
+ break;
+
+ case 'e':
+ *(string.pointer++) = '\x1B';
+ break;
+
+ case ' ':
+ *(string.pointer++) = '\x20';
+ break;
+
+ case '"':
+ *(string.pointer++) = '"';
+ break;
+
+ case '\'':
+ *(string.pointer++) = '\'';
+ break;
+
+ case '\\':
+ *(string.pointer++) = '\\';
+ break;
+
+ case 'N': /* NEL (#x85) */
+ *(string.pointer++) = '\xC2';
+ *(string.pointer++) = '\x85';
+ break;
+
+ case '_': /* #xA0 */
+ *(string.pointer++) = '\xC2';
+ *(string.pointer++) = '\xA0';
+ break;
+
+ case 'L': /* LS (#x2028) */
+ *(string.pointer++) = '\xE2';
+ *(string.pointer++) = '\x80';
+ *(string.pointer++) = '\xA8';
+ break;
+
+ case 'P': /* PS (#x2029) */
+ *(string.pointer++) = '\xE2';
+ *(string.pointer++) = '\x80';
+ *(string.pointer++) = '\xA9';
+ break;
+
+ case 'x':
+ code_length = 2;
+ break;
+
+ case 'u':
+ code_length = 4;
+ break;
+
+ case 'U':
+ code_length = 8;
+ break;
+
+ default:
+ yaml_parser_set_scanner_error(parser, "while parsing a quoted scalar",
+ start_mark, "found unknown escape character");
+ goto error;
+ }
+
+ SKIP(parser);
+ SKIP(parser);
+
+ /* Consume an arbitrary escape code. */
+
+ if (code_length)
+ {
+ unsigned int value = 0;
+ size_t k;
+
+ /* Scan the character value. */
+
+ if (!CACHE(parser, code_length)) goto error;
+
+ for (k = 0; k < code_length; k ++) {
+ if (!IS_HEX_AT(parser->buffer, k)) {
+ yaml_parser_set_scanner_error(parser, "while parsing a quoted scalar",
+ start_mark, "did not find expected hexdecimal number");
+ goto error;
+ }
+ value = (value << 4) + AS_HEX_AT(parser->buffer, k);
+ }
+
+ /* Check the value and write the character. */
+
+ if ((value >= 0xD800 && value <= 0xDFFF) || value > 0x10FFFF) {
+ yaml_parser_set_scanner_error(parser, "while parsing a quoted scalar",
+ start_mark, "found invalid Unicode character escape code");
+ goto error;
+ }
+
+ if (value <= 0x7F) {
+ *(string.pointer++) = value;
+ }
+ else if (value <= 0x7FF) {
+ *(string.pointer++) = 0xC0 + (value >> 6);
+ *(string.pointer++) = 0x80 + (value & 0x3F);
+ }
+ else if (value <= 0xFFFF) {
+ *(string.pointer++) = 0xE0 + (value >> 12);
+ *(string.pointer++) = 0x80 + ((value >> 6) & 0x3F);
+ *(string.pointer++) = 0x80 + (value & 0x3F);
+ }
+ else {
+ *(string.pointer++) = 0xF0 + (value >> 18);
+ *(string.pointer++) = 0x80 + ((value >> 12) & 0x3F);
+ *(string.pointer++) = 0x80 + ((value >> 6) & 0x3F);
+ *(string.pointer++) = 0x80 + (value & 0x3F);
+ }
+
+ /* Advance the pointer. */
+
+ for (k = 0; k < code_length; k ++) {
+ SKIP(parser);
+ }
+ }
+ }
+
+ else
+ {
+ /* It is a non-escaped non-blank character. */
+
+ if (!READ(parser, string)) goto error;
+ }
+
+ if (!CACHE(parser, 2)) goto error;
+ }
+
+ /* Check if we are at the end of the scalar. */
+
+ if (CHECK(parser->buffer, single ? '\'' : '"'))
+ break;
+
+ /* Consume blank characters. */
+
+ if (!CACHE(parser, 1)) goto error;
+
+ while (IS_BLANK(parser->buffer) || IS_BREAK(parser->buffer))
+ {
+ if (IS_BLANK(parser->buffer))
+ {
+ /* Consume a space or a tab character. */
+
+ if (!leading_blanks) {
+ if (!READ(parser, whitespaces)) goto error;
+ }
+ else {
+ SKIP(parser);
+ }
+ }
+ else
+ {
+ if (!CACHE(parser, 2)) goto error;
+
+ /* Check if it is a first line break. */
+
+ if (!leading_blanks)
+ {
+ CLEAR(parser, whitespaces);
+ if (!READ_LINE(parser, leading_break)) goto error;
+ leading_blanks = 1;
+ }
+ else
+ {
+ if (!READ_LINE(parser, trailing_breaks)) goto error;
+ }
+ }
+ if (!CACHE(parser, 1)) goto error;
+ }
+
+ /* Join the whitespaces or fold line breaks. */
+
+ if (leading_blanks)
+ {
+ /* Do we need to fold line breaks? */
+
+ if (leading_break.start[0] == '\n') {
+ if (trailing_breaks.start[0] == '\0') {
+ if (!STRING_EXTEND(parser, string)) goto error;
+ *(string.pointer++) = ' ';
+ }
+ else {
+ if (!JOIN(parser, string, trailing_breaks)) goto error;
+ CLEAR(parser, trailing_breaks);
+ }
+ CLEAR(parser, leading_break);
+ }
+ else {
+ if (!JOIN(parser, string, leading_break)) goto error;
+ if (!JOIN(parser, string, trailing_breaks)) goto error;
+ CLEAR(parser, leading_break);
+ CLEAR(parser, trailing_breaks);
+ }
+ }
+ else
+ {
+ if (!JOIN(parser, string, whitespaces)) goto error;
+ CLEAR(parser, whitespaces);
+ }
+ }
+
+ /* Eat the right quote. */
+
+ SKIP(parser);
+
+ end_mark = parser->mark;
+
+ /* Create a token. */
+
+ SCALAR_TOKEN_INIT(*token, string.start, string.pointer-string.start,
+ single ? YAML_SINGLE_QUOTED_SCALAR_STYLE : YAML_DOUBLE_QUOTED_SCALAR_STYLE,
+ start_mark, end_mark);
+
+ STRING_DEL(parser, leading_break);
+ STRING_DEL(parser, trailing_breaks);
+ STRING_DEL(parser, whitespaces);
+
+ return 1;
+
+error:
+ STRING_DEL(parser, string);
+ STRING_DEL(parser, leading_break);
+ STRING_DEL(parser, trailing_breaks);
+ STRING_DEL(parser, whitespaces);
+
+ return 0;
+}
+
+/*
+ * Scan a plain scalar.
+ */
+
+static int
+yaml_parser_scan_plain_scalar(yaml_parser_t *parser, yaml_token_t *token)
+{
+ yaml_mark_t start_mark;
+ yaml_mark_t end_mark;
+ yaml_string_t string = NULL_STRING;
+ yaml_string_t leading_break = NULL_STRING;
+ yaml_string_t trailing_breaks = NULL_STRING;
+ yaml_string_t whitespaces = NULL_STRING;
+ int leading_blanks = 0;
+ int indent = parser->indent+1;
+
+ if (!STRING_INIT(parser, string, INITIAL_STRING_SIZE)) goto error;
+ if (!STRING_INIT(parser, leading_break, INITIAL_STRING_SIZE)) goto error;
+ if (!STRING_INIT(parser, trailing_breaks, INITIAL_STRING_SIZE)) goto error;
+ if (!STRING_INIT(parser, whitespaces, INITIAL_STRING_SIZE)) goto error;
+
+ start_mark = end_mark = parser->mark;
+
+ /* Consume the content of the plain scalar. */
+
+ while (1)
+ {
+ /* Check for a document indicator. */
+
+ if (!CACHE(parser, 4)) goto error;
+
+ if (parser->mark.column == 0 &&
+ ((CHECK_AT(parser->buffer, '-', 0) &&
+ CHECK_AT(parser->buffer, '-', 1) &&
+ CHECK_AT(parser->buffer, '-', 2)) ||
+ (CHECK_AT(parser->buffer, '.', 0) &&
+ CHECK_AT(parser->buffer, '.', 1) &&
+ CHECK_AT(parser->buffer, '.', 2))) &&
+ IS_BLANKZ_AT(parser->buffer, 3)) break;
+
+ /* Check for a comment. */
+
+ if (CHECK(parser->buffer, '#'))
+ break;
+
+ /* Consume non-blank characters. */
+
+ while (!IS_BLANKZ(parser->buffer))
+ {
+ /* Check for 'x:x' in the flow context. TODO: Fix the test "spec-08-13". */
+
+ if (parser->flow_level
+ && CHECK(parser->buffer, ':')
+ && !IS_BLANKZ_AT(parser->buffer, 1)) {
+ yaml_parser_set_scanner_error(parser, "while scanning a plain scalar",
+ start_mark, "found unexpected ':'");
+ goto error;
+ }
+
+ /* Check for indicators that may end a plain scalar. */
+
+ if ((CHECK(parser->buffer, ':') && IS_BLANKZ_AT(parser->buffer, 1))
+ || (parser->flow_level &&
+ (CHECK(parser->buffer, ',') || CHECK(parser->buffer, ':')
+ || CHECK(parser->buffer, '?') || CHECK(parser->buffer, '[')
+ || CHECK(parser->buffer, ']') || CHECK(parser->buffer, '{')
+ || CHECK(parser->buffer, '}'))))
+ break;
+
+ /* Check if we need to join whitespaces and breaks. */
+
+ if (leading_blanks || whitespaces.start != whitespaces.pointer)
+ {
+ if (leading_blanks)
+ {
+ /* Do we need to fold line breaks? */
+
+ if (leading_break.start[0] == '\n') {
+ if (trailing_breaks.start[0] == '\0') {
+ if (!STRING_EXTEND(parser, string)) goto error;
+ *(string.pointer++) = ' ';
+ }
+ else {
+ if (!JOIN(parser, string, trailing_breaks)) goto error;
+ CLEAR(parser, trailing_breaks);
+ }
+ CLEAR(parser, leading_break);
+ }
+ else {
+ if (!JOIN(parser, string, leading_break)) goto error;
+ if (!JOIN(parser, string, trailing_breaks)) goto error;
+ CLEAR(parser, leading_break);
+ CLEAR(parser, trailing_breaks);
+ }
+
+ leading_blanks = 0;
+ }
+ else
+ {
+ if (!JOIN(parser, string, whitespaces)) goto error;
+ CLEAR(parser, whitespaces);
+ }
+ }
+
+ /* Copy the character. */
+
+ if (!READ(parser, string)) goto error;
+
+ end_mark = parser->mark;
+
+ if (!CACHE(parser, 2)) goto error;
+ }
+
+ /* Is it the end? */
+
+ if (!(IS_BLANK(parser->buffer) || IS_BREAK(parser->buffer)))
+ break;
+
+ /* Consume blank characters. */
+
+ if (!CACHE(parser, 1)) goto error;
+
+ while (IS_BLANK(parser->buffer) || IS_BREAK(parser->buffer))
+ {
+ if (IS_BLANK(parser->buffer))
+ {
+ /* Check for tab character that abuse intendation. */
+
+ if (leading_blanks && (int)parser->mark.column < indent
+ && IS_TAB(parser->buffer)) {
+ yaml_parser_set_scanner_error(parser, "while scanning a plain scalar",
+ start_mark, "found a tab character that violate intendation");
+ goto error;
+ }
+
+ /* Consume a space or a tab character. */
+
+ if (!leading_blanks) {
+ if (!READ(parser, whitespaces)) goto error;
+ }
+ else {
+ SKIP(parser);
+ }
+ }
+ else
+ {
+ if (!CACHE(parser, 2)) goto error;
+
+ /* Check if it is a first line break. */
+
+ if (!leading_blanks)
+ {
+ CLEAR(parser, whitespaces);
+ if (!READ_LINE(parser, leading_break)) goto error;
+ leading_blanks = 1;
+ }
+ else
+ {
+ if (!READ_LINE(parser, trailing_breaks)) goto error;
+ }
+ }
+ if (!CACHE(parser, 1)) goto error;
+ }
+
+ /* Check intendation level. */
+
+ if (!parser->flow_level && (int)parser->mark.column < indent)
+ break;
+ }
+
+ /* Create a token. */
+
+ SCALAR_TOKEN_INIT(*token, string.start, string.pointer-string.start,
+ YAML_PLAIN_SCALAR_STYLE, start_mark, end_mark);
+
+ /* Note that we change the 'simple_key_allowed' flag. */
+
+ if (leading_blanks) {
+ parser->simple_key_allowed = 1;
+ }
+
+ STRING_DEL(parser, leading_break);
+ STRING_DEL(parser, trailing_breaks);
+ STRING_DEL(parser, whitespaces);
+
+ return 1;
+
+error:
+ STRING_DEL(parser, string);
+ STRING_DEL(parser, leading_break);
+ STRING_DEL(parser, trailing_breaks);
+ STRING_DEL(parser, whitespaces);
+
+ return 0;
+}
+
diff --git a/contrib/libyaml/src/writer.c b/contrib/libyaml/src/writer.c
new file mode 100644
index 0000000..b90019f
--- /dev/null
+++ b/contrib/libyaml/src/writer.c
@@ -0,0 +1,141 @@
+
+#include "yaml_private.h"
+
+/*
+ * Declarations.
+ */
+
+static int
+yaml_emitter_set_writer_error(yaml_emitter_t *emitter, const char *problem);
+
+YAML_DECLARE(int)
+yaml_emitter_flush(yaml_emitter_t *emitter);
+
+/*
+ * Set the writer error and return 0.
+ */
+
+static int
+yaml_emitter_set_writer_error(yaml_emitter_t *emitter, const char *problem)
+{
+ emitter->error = YAML_WRITER_ERROR;
+ emitter->problem = problem;
+
+ return 0;
+}
+
+/*
+ * Flush the output buffer.
+ */
+
+YAML_DECLARE(int)
+yaml_emitter_flush(yaml_emitter_t *emitter)
+{
+ int low, high;
+
+ assert(emitter); /* Non-NULL emitter object is expected. */
+ assert(emitter->write_handler); /* Write handler must be set. */
+ assert(emitter->encoding); /* Output encoding must be set. */
+
+ emitter->buffer.last = emitter->buffer.pointer;
+ emitter->buffer.pointer = emitter->buffer.start;
+
+ /* Check if the buffer is empty. */
+
+ if (emitter->buffer.start == emitter->buffer.last) {
+ return 1;
+ }
+
+ /* If the output encoding is UTF-8, we don't need to recode the buffer. */
+
+ if (emitter->encoding == YAML_UTF8_ENCODING)
+ {
+ if (emitter->write_handler(emitter->write_handler_data,
+ emitter->buffer.start,
+ emitter->buffer.last - emitter->buffer.start)) {
+ emitter->buffer.last = emitter->buffer.start;
+ emitter->buffer.pointer = emitter->buffer.start;
+ return 1;
+ }
+ else {
+ return yaml_emitter_set_writer_error(emitter, "write error");
+ }
+ }
+
+ /* Recode the buffer into the raw buffer. */
+
+ low = (emitter->encoding == YAML_UTF16LE_ENCODING ? 0 : 1);
+ high = (emitter->encoding == YAML_UTF16LE_ENCODING ? 1 : 0);
+
+ while (emitter->buffer.pointer != emitter->buffer.last)
+ {
+ unsigned char octet;
+ unsigned int width;
+ unsigned int value;
+ size_t k;
+
+ /*
+ * See the "reader.c" code for more details on UTF-8 encoding. Note
+ * that we assume that the buffer contains a valid UTF-8 sequence.
+ */
+
+ /* Read the next UTF-8 character. */
+
+ octet = emitter->buffer.pointer[0];
+
+ width = (octet & 0x80) == 0x00 ? 1 :
+ (octet & 0xE0) == 0xC0 ? 2 :
+ (octet & 0xF0) == 0xE0 ? 3 :
+ (octet & 0xF8) == 0xF0 ? 4 : 0;
+
+ value = (octet & 0x80) == 0x00 ? octet & 0x7F :
+ (octet & 0xE0) == 0xC0 ? octet & 0x1F :
+ (octet & 0xF0) == 0xE0 ? octet & 0x0F :
+ (octet & 0xF8) == 0xF0 ? octet & 0x07 : 0;
+
+ for (k = 1; k < width; k ++) {
+ octet = emitter->buffer.pointer[k];
+ value = (value << 6) + (octet & 0x3F);
+ }
+
+ emitter->buffer.pointer += width;
+
+ /* Write the character. */
+
+ if (value < 0x10000)
+ {
+ emitter->raw_buffer.last[high] = value >> 8;
+ emitter->raw_buffer.last[low] = value & 0xFF;
+
+ emitter->raw_buffer.last += 2;
+ }
+ else
+ {
+ /* Write the character using a surrogate pair (check "reader.c"). */
+
+ value -= 0x10000;
+ emitter->raw_buffer.last[high] = 0xD8 + (value >> 18);
+ emitter->raw_buffer.last[low] = (value >> 10) & 0xFF;
+ emitter->raw_buffer.last[high+2] = 0xDC + ((value >> 8) & 0xFF);
+ emitter->raw_buffer.last[low+2] = value & 0xFF;
+
+ emitter->raw_buffer.last += 4;
+ }
+ }
+
+ /* Write the raw buffer. */
+
+ if (emitter->write_handler(emitter->write_handler_data,
+ emitter->raw_buffer.start,
+ emitter->raw_buffer.last - emitter->raw_buffer.start)) {
+ emitter->buffer.last = emitter->buffer.start;
+ emitter->buffer.pointer = emitter->buffer.start;
+ emitter->raw_buffer.last = emitter->raw_buffer.start;
+ emitter->raw_buffer.pointer = emitter->raw_buffer.start;
+ return 1;
+ }
+ else {
+ return yaml_emitter_set_writer_error(emitter, "write error");
+ }
+}
+
diff --git a/contrib/libyaml/src/yaml_private.h b/contrib/libyaml/src/yaml_private.h
new file mode 100644
index 0000000..ed5ea66
--- /dev/null
+++ b/contrib/libyaml/src/yaml_private.h
@@ -0,0 +1,640 @@
+
+#if HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <yaml.h>
+
+#include <assert.h>
+#include <limits.h>
+
+/*
+ * Memory management.
+ */
+
+YAML_DECLARE(void *)
+yaml_malloc(size_t size);
+
+YAML_DECLARE(void *)
+yaml_realloc(void *ptr, size_t size);
+
+YAML_DECLARE(void)
+yaml_free(void *ptr);
+
+YAML_DECLARE(yaml_char_t *)
+yaml_strdup(const yaml_char_t *);
+
+/*
+ * Reader: Ensure that the buffer contains at least `length` characters.
+ */
+
+YAML_DECLARE(int)
+yaml_parser_update_buffer(yaml_parser_t *parser, size_t length);
+
+/*
+ * Scanner: Ensure that the token stack contains at least one token ready.
+ */
+
+YAML_DECLARE(int)
+yaml_parser_fetch_more_tokens(yaml_parser_t *parser);
+
+/*
+ * The size of the input raw buffer.
+ */
+
+#define INPUT_RAW_BUFFER_SIZE 16384
+
+/*
+ * The size of the input buffer.
+ *
+ * It should be possible to decode the whole raw buffer.
+ */
+
+#define INPUT_BUFFER_SIZE (INPUT_RAW_BUFFER_SIZE*3)
+
+/*
+ * The size of the output buffer.
+ */
+
+#define OUTPUT_BUFFER_SIZE 16384
+
+/*
+ * The size of the output raw buffer.
+ *
+ * It should be possible to encode the whole output buffer.
+ */
+
+#define OUTPUT_RAW_BUFFER_SIZE (OUTPUT_BUFFER_SIZE*2+2)
+
+/*
+ * The size of other stacks and queues.
+ */
+
+#define INITIAL_STACK_SIZE 16
+#define INITIAL_QUEUE_SIZE 16
+#define INITIAL_STRING_SIZE 16
+
+/*
+ * Buffer management.
+ */
+
+#define BUFFER_INIT(context,buffer,size) \
+ (((buffer).start = yaml_malloc(size)) ? \
+ ((buffer).last = (buffer).pointer = (buffer).start, \
+ (buffer).end = (buffer).start+(size), \
+ 1) : \
+ ((context)->error = YAML_MEMORY_ERROR, \
+ 0))
+
+#define BUFFER_DEL(context,buffer) \
+ (yaml_free((buffer).start), \
+ (buffer).start = (buffer).pointer = (buffer).end = 0)
+
+/*
+ * String management.
+ */
+
+typedef struct {
+ yaml_char_t *start;
+ yaml_char_t *end;
+ yaml_char_t *pointer;
+} yaml_string_t;
+
+YAML_DECLARE(int)
+yaml_string_extend(yaml_char_t **start,
+ yaml_char_t **pointer, yaml_char_t **end);
+
+YAML_DECLARE(int)
+yaml_string_join(
+ yaml_char_t **a_start, yaml_char_t **a_pointer, yaml_char_t **a_end,
+ yaml_char_t **b_start, yaml_char_t **b_pointer, yaml_char_t **b_end);
+
+#define NULL_STRING { NULL, NULL, NULL }
+
+#define STRING(string,length) { (string), (string)+(length), (string) }
+
+#define STRING_ASSIGN(value,string,length) \
+ ((value).start = (string), \
+ (value).end = (string)+(length), \
+ (value).pointer = (string))
+
+#define STRING_INIT(context,string,size) \
+ (((string).start = yaml_malloc(size)) ? \
+ ((string).pointer = (string).start, \
+ (string).end = (string).start+(size), \
+ memset((string).start, 0, (size)), \
+ 1) : \
+ ((context)->error = YAML_MEMORY_ERROR, \
+ 0))
+
+#define STRING_DEL(context,string) \
+ (yaml_free((string).start), \
+ (string).start = (string).pointer = (string).end = 0)
+
+#define STRING_EXTEND(context,string) \
+ (((string).pointer+5 < (string).end) \
+ || yaml_string_extend(&(string).start, \
+ &(string).pointer, &(string).end))
+
+#define CLEAR(context,string) \
+ ((string).pointer = (string).start, \
+ memset((string).start, 0, (string).end-(string).start))
+
+#define JOIN(context,string_a,string_b) \
+ ((yaml_string_join(&(string_a).start, &(string_a).pointer, \
+ &(string_a).end, &(string_b).start, \
+ &(string_b).pointer, &(string_b).end)) ? \
+ ((string_b).pointer = (string_b).start, \
+ 1) : \
+ ((context)->error = YAML_MEMORY_ERROR, \
+ 0))
+
+/*
+ * String check operations.
+ */
+
+/*
+ * Check the octet at the specified position.
+ */
+
+#define CHECK_AT(string,octet,offset) \
+ ((string).pointer[offset] == (yaml_char_t)(octet))
+
+/*
+ * Check the current octet in the buffer.
+ */
+
+#define CHECK(string,octet) CHECK_AT((string),(octet),0)
+
+/*
+ * Check if the character at the specified position is an alphabetical
+ * character, a digit, '_', or '-'.
+ */
+
+#define IS_ALPHA_AT(string,offset) \
+ (((string).pointer[offset] >= (yaml_char_t) '0' && \
+ (string).pointer[offset] <= (yaml_char_t) '9') || \
+ ((string).pointer[offset] >= (yaml_char_t) 'A' && \
+ (string).pointer[offset] <= (yaml_char_t) 'Z') || \
+ ((string).pointer[offset] >= (yaml_char_t) 'a' && \
+ (string).pointer[offset] <= (yaml_char_t) 'z') || \
+ (string).pointer[offset] == '_' || \
+ (string).pointer[offset] == '-')
+
+#define IS_ALPHA(string) IS_ALPHA_AT((string),0)
+
+/*
+ * Check if the character at the specified position is a digit.
+ */
+
+#define IS_DIGIT_AT(string,offset) \
+ (((string).pointer[offset] >= (yaml_char_t) '0' && \
+ (string).pointer[offset] <= (yaml_char_t) '9'))
+
+#define IS_DIGIT(string) IS_DIGIT_AT((string),0)
+
+/*
+ * Get the value of a digit.
+ */
+
+#define AS_DIGIT_AT(string,offset) \
+ ((string).pointer[offset] - (yaml_char_t) '0')
+
+#define AS_DIGIT(string) AS_DIGIT_AT((string),0)
+
+/*
+ * Check if the character at the specified position is a hex-digit.
+ */
+
+#define IS_HEX_AT(string,offset) \
+ (((string).pointer[offset] >= (yaml_char_t) '0' && \
+ (string).pointer[offset] <= (yaml_char_t) '9') || \
+ ((string).pointer[offset] >= (yaml_char_t) 'A' && \
+ (string).pointer[offset] <= (yaml_char_t) 'F') || \
+ ((string).pointer[offset] >= (yaml_char_t) 'a' && \
+ (string).pointer[offset] <= (yaml_char_t) 'f'))
+
+#define IS_HEX(string) IS_HEX_AT((string),0)
+
+/*
+ * Get the value of a hex-digit.
+ */
+
+#define AS_HEX_AT(string,offset) \
+ (((string).pointer[offset] >= (yaml_char_t) 'A' && \
+ (string).pointer[offset] <= (yaml_char_t) 'F') ? \
+ ((string).pointer[offset] - (yaml_char_t) 'A' + 10) : \
+ ((string).pointer[offset] >= (yaml_char_t) 'a' && \
+ (string).pointer[offset] <= (yaml_char_t) 'f') ? \
+ ((string).pointer[offset] - (yaml_char_t) 'a' + 10) : \
+ ((string).pointer[offset] - (yaml_char_t) '0'))
+
+#define AS_HEX(string) AS_HEX_AT((string),0)
+
+/*
+ * Check if the character is ASCII.
+ */
+
+#define IS_ASCII_AT(string,offset) \
+ ((string).pointer[offset] <= (yaml_char_t) '\x7F')
+
+#define IS_ASCII(string) IS_ASCII_AT((string),0)
+
+/*
+ * Check if the character can be printed unescaped.
+ */
+
+#define IS_PRINTABLE_AT(string,offset) \
+ (((string).pointer[offset] == 0x0A) /* . == #x0A */ \
+ || ((string).pointer[offset] >= 0x20 /* #x20 <= . <= #x7E */ \
+ && (string).pointer[offset] <= 0x7E) \
+ || ((string).pointer[offset] == 0xC2 /* #0xA0 <= . <= #xD7FF */ \
+ && (string).pointer[offset+1] >= 0xA0) \
+ || ((string).pointer[offset] > 0xC2 \
+ && (string).pointer[offset] < 0xED) \
+ || ((string).pointer[offset] == 0xED \
+ && (string).pointer[offset+1] < 0xA0) \
+ || ((string).pointer[offset] == 0xEE) \
+ || ((string).pointer[offset] == 0xEF /* #xE000 <= . <= #xFFFD */ \
+ && !((string).pointer[offset+1] == 0xBB /* && . != #xFEFF */ \
+ && (string).pointer[offset+2] == 0xBF) \
+ && !((string).pointer[offset+1] == 0xBF \
+ && ((string).pointer[offset+2] == 0xBE \
+ || (string).pointer[offset+2] == 0xBF))))
+
+#define IS_PRINTABLE(string) IS_PRINTABLE_AT((string),0)
+
+/*
+ * Check if the character at the specified position is NUL.
+ */
+
+#define IS_Z_AT(string,offset) CHECK_AT((string),'\0',(offset))
+
+#define IS_Z(string) IS_Z_AT((string),0)
+
+/*
+ * Check if the character at the specified position is BOM.
+ */
+
+#define IS_BOM_AT(string,offset) \
+ (CHECK_AT((string),'\xEF',(offset)) \
+ && CHECK_AT((string),'\xBB',(offset)+1) \
+ && CHECK_AT((string),'\xBF',(offset)+2)) /* BOM (#xFEFF) */
+
+#define IS_BOM(string) IS_BOM_AT(string,0)
+
+/*
+ * Check if the character at the specified position is space.
+ */
+
+#define IS_SPACE_AT(string,offset) CHECK_AT((string),' ',(offset))
+
+#define IS_SPACE(string) IS_SPACE_AT((string),0)
+
+/*
+ * Check if the character at the specified position is tab.
+ */
+
+#define IS_TAB_AT(string,offset) CHECK_AT((string),'\t',(offset))
+
+#define IS_TAB(string) IS_TAB_AT((string),0)
+
+/*
+ * Check if the character at the specified position is blank (space or tab).
+ */
+
+#define IS_BLANK_AT(string,offset) \
+ (IS_SPACE_AT((string),(offset)) || IS_TAB_AT((string),(offset)))
+
+#define IS_BLANK(string) IS_BLANK_AT((string),0)
+
+/*
+ * Check if the character at the specified position is a line break.
+ */
+
+#define IS_BREAK_AT(string,offset) \
+ (CHECK_AT((string),'\r',(offset)) /* CR (#xD)*/ \
+ || CHECK_AT((string),'\n',(offset)) /* LF (#xA) */ \
+ || (CHECK_AT((string),'\xC2',(offset)) \
+ && CHECK_AT((string),'\x85',(offset)+1)) /* NEL (#x85) */ \
+ || (CHECK_AT((string),'\xE2',(offset)) \
+ && CHECK_AT((string),'\x80',(offset)+1) \
+ && CHECK_AT((string),'\xA8',(offset)+2)) /* LS (#x2028) */ \
+ || (CHECK_AT((string),'\xE2',(offset)) \
+ && CHECK_AT((string),'\x80',(offset)+1) \
+ && CHECK_AT((string),'\xA9',(offset)+2))) /* PS (#x2029) */
+
+#define IS_BREAK(string) IS_BREAK_AT((string),0)
+
+#define IS_CRLF_AT(string,offset) \
+ (CHECK_AT((string),'\r',(offset)) && CHECK_AT((string),'\n',(offset)+1))
+
+#define IS_CRLF(string) IS_CRLF_AT((string),0)
+
+/*
+ * Check if the character is a line break or NUL.
+ */
+
+#define IS_BREAKZ_AT(string,offset) \
+ (IS_BREAK_AT((string),(offset)) || IS_Z_AT((string),(offset)))
+
+#define IS_BREAKZ(string) IS_BREAKZ_AT((string),0)
+
+/*
+ * Check if the character is a line break, space, or NUL.
+ */
+
+#define IS_SPACEZ_AT(string,offset) \
+ (IS_SPACE_AT((string),(offset)) || IS_BREAKZ_AT((string),(offset)))
+
+#define IS_SPACEZ(string) IS_SPACEZ_AT((string),0)
+
+/*
+ * Check if the character is a line break, space, tab, or NUL.
+ */
+
+#define IS_BLANKZ_AT(string,offset) \
+ (IS_BLANK_AT((string),(offset)) || IS_BREAKZ_AT((string),(offset)))
+
+#define IS_BLANKZ(string) IS_BLANKZ_AT((string),0)
+
+/*
+ * Determine the width of the character.
+ */
+
+#define WIDTH_AT(string,offset) \
+ (((string).pointer[offset] & 0x80) == 0x00 ? 1 : \
+ ((string).pointer[offset] & 0xE0) == 0xC0 ? 2 : \
+ ((string).pointer[offset] & 0xF0) == 0xE0 ? 3 : \
+ ((string).pointer[offset] & 0xF8) == 0xF0 ? 4 : 0)
+
+#define WIDTH(string) WIDTH_AT((string),0)
+
+/*
+ * Move the string pointer to the next character.
+ */
+
+#define MOVE(string) ((string).pointer += WIDTH((string)))
+
+/*
+ * Copy a character and move the pointers of both strings.
+ */
+
+#define COPY(string_a,string_b) \
+ ((*(string_b).pointer & 0x80) == 0x00 ? \
+ (*((string_a).pointer++) = *((string_b).pointer++)) : \
+ (*(string_b).pointer & 0xE0) == 0xC0 ? \
+ (*((string_a).pointer++) = *((string_b).pointer++), \
+ *((string_a).pointer++) = *((string_b).pointer++)) : \
+ (*(string_b).pointer & 0xF0) == 0xE0 ? \
+ (*((string_a).pointer++) = *((string_b).pointer++), \
+ *((string_a).pointer++) = *((string_b).pointer++), \
+ *((string_a).pointer++) = *((string_b).pointer++)) : \
+ (*(string_b).pointer & 0xF8) == 0xF0 ? \
+ (*((string_a).pointer++) = *((string_b).pointer++), \
+ *((string_a).pointer++) = *((string_b).pointer++), \
+ *((string_a).pointer++) = *((string_b).pointer++), \
+ *((string_a).pointer++) = *((string_b).pointer++)) : 0)
+
+/*
+ * Stack and queue management.
+ */
+
+YAML_DECLARE(int)
+yaml_stack_extend(void **start, void **top, void **end);
+
+YAML_DECLARE(int)
+yaml_queue_extend(void **start, void **head, void **tail, void **end);
+
+#define STACK_INIT(context,stack,size) \
+ (((stack).start = yaml_malloc((size)*sizeof(*(stack).start))) ? \
+ ((stack).top = (stack).start, \
+ (stack).end = (stack).start+(size), \
+ 1) : \
+ ((context)->error = YAML_MEMORY_ERROR, \
+ 0))
+
+#define STACK_DEL(context,stack) \
+ (yaml_free((stack).start), \
+ (stack).start = (stack).top = (stack).end = 0)
+
+#define STACK_EMPTY(context,stack) \
+ ((stack).start == (stack).top)
+
+#define PUSH(context,stack,value) \
+ (((stack).top != (stack).end \
+ || yaml_stack_extend((void **)&(stack).start, \
+ (void **)&(stack).top, (void **)&(stack).end)) ? \
+ (*((stack).top++) = value, \
+ 1) : \
+ ((context)->error = YAML_MEMORY_ERROR, \
+ 0))
+
+#define POP(context,stack) \
+ (*(--(stack).top))
+
+#define QUEUE_INIT(context,queue,size) \
+ (((queue).start = yaml_malloc((size)*sizeof(*(queue).start))) ? \
+ ((queue).head = (queue).tail = (queue).start, \
+ (queue).end = (queue).start+(size), \
+ 1) : \
+ ((context)->error = YAML_MEMORY_ERROR, \
+ 0))
+
+#define QUEUE_DEL(context,queue) \
+ (yaml_free((queue).start), \
+ (queue).start = (queue).head = (queue).tail = (queue).end = 0)
+
+#define QUEUE_EMPTY(context,queue) \
+ ((queue).head == (queue).tail)
+
+#define ENQUEUE(context,queue,value) \
+ (((queue).tail != (queue).end \
+ || yaml_queue_extend((void **)&(queue).start, (void **)&(queue).head, \
+ (void **)&(queue).tail, (void **)&(queue).end)) ? \
+ (*((queue).tail++) = value, \
+ 1) : \
+ ((context)->error = YAML_MEMORY_ERROR, \
+ 0))
+
+#define DEQUEUE(context,queue) \
+ (*((queue).head++))
+
+#define QUEUE_INSERT(context,queue,index,value) \
+ (((queue).tail != (queue).end \
+ || yaml_queue_extend((void **)&(queue).start, (void **)&(queue).head, \
+ (void **)&(queue).tail, (void **)&(queue).end)) ? \
+ (memmove((queue).head+(index)+1,(queue).head+(index), \
+ ((queue).tail-(queue).head-(index))*sizeof(*(queue).start)), \
+ *((queue).head+(index)) = value, \
+ (queue).tail++, \
+ 1) : \
+ ((context)->error = YAML_MEMORY_ERROR, \
+ 0))
+
+/*
+ * Token initializers.
+ */
+
+#define TOKEN_INIT(token,token_type,token_start_mark,token_end_mark) \
+ (memset(&(token), 0, sizeof(yaml_token_t)), \
+ (token).type = (token_type), \
+ (token).start_mark = (token_start_mark), \
+ (token).end_mark = (token_end_mark))
+
+#define STREAM_START_TOKEN_INIT(token,token_encoding,start_mark,end_mark) \
+ (TOKEN_INIT((token),YAML_STREAM_START_TOKEN,(start_mark),(end_mark)), \
+ (token).data.stream_start.encoding = (token_encoding))
+
+#define STREAM_END_TOKEN_INIT(token,start_mark,end_mark) \
+ (TOKEN_INIT((token),YAML_STREAM_END_TOKEN,(start_mark),(end_mark)))
+
+#define ALIAS_TOKEN_INIT(token,token_value,start_mark,end_mark) \
+ (TOKEN_INIT((token),YAML_ALIAS_TOKEN,(start_mark),(end_mark)), \
+ (token).data.alias.value = (token_value))
+
+#define ANCHOR_TOKEN_INIT(token,token_value,start_mark,end_mark) \
+ (TOKEN_INIT((token),YAML_ANCHOR_TOKEN,(start_mark),(end_mark)), \
+ (token).data.anchor.value = (token_value))
+
+#define TAG_TOKEN_INIT(token,token_handle,token_suffix,start_mark,end_mark) \
+ (TOKEN_INIT((token),YAML_TAG_TOKEN,(start_mark),(end_mark)), \
+ (token).data.tag.handle = (token_handle), \
+ (token).data.tag.suffix = (token_suffix))
+
+#define SCALAR_TOKEN_INIT(token,token_value,token_length,token_style,start_mark,end_mark) \
+ (TOKEN_INIT((token),YAML_SCALAR_TOKEN,(start_mark),(end_mark)), \
+ (token).data.scalar.value = (token_value), \
+ (token).data.scalar.length = (token_length), \
+ (token).data.scalar.style = (token_style))
+
+#define VERSION_DIRECTIVE_TOKEN_INIT(token,token_major,token_minor,start_mark,end_mark) \
+ (TOKEN_INIT((token),YAML_VERSION_DIRECTIVE_TOKEN,(start_mark),(end_mark)), \
+ (token).data.version_directive.major = (token_major), \
+ (token).data.version_directive.minor = (token_minor))
+
+#define TAG_DIRECTIVE_TOKEN_INIT(token,token_handle,token_prefix,start_mark,end_mark) \
+ (TOKEN_INIT((token),YAML_TAG_DIRECTIVE_TOKEN,(start_mark),(end_mark)), \
+ (token).data.tag_directive.handle = (token_handle), \
+ (token).data.tag_directive.prefix = (token_prefix))
+
+/*
+ * Event initializers.
+ */
+
+#define EVENT_INIT(event,event_type,event_start_mark,event_end_mark) \
+ (memset(&(event), 0, sizeof(yaml_event_t)), \
+ (event).type = (event_type), \
+ (event).start_mark = (event_start_mark), \
+ (event).end_mark = (event_end_mark))
+
+#define STREAM_START_EVENT_INIT(event,event_encoding,start_mark,end_mark) \
+ (EVENT_INIT((event),YAML_STREAM_START_EVENT,(start_mark),(end_mark)), \
+ (event).data.stream_start.encoding = (event_encoding))
+
+#define STREAM_END_EVENT_INIT(event,start_mark,end_mark) \
+ (EVENT_INIT((event),YAML_STREAM_END_EVENT,(start_mark),(end_mark)))
+
+#define DOCUMENT_START_EVENT_INIT(event,event_version_directive, \
+ event_tag_directives_start,event_tag_directives_end,event_implicit,start_mark,end_mark) \
+ (EVENT_INIT((event),YAML_DOCUMENT_START_EVENT,(start_mark),(end_mark)), \
+ (event).data.document_start.version_directive = (event_version_directive), \
+ (event).data.document_start.tag_directives.start = (event_tag_directives_start), \
+ (event).data.document_start.tag_directives.end = (event_tag_directives_end), \
+ (event).data.document_start.implicit = (event_implicit))
+
+#define DOCUMENT_END_EVENT_INIT(event,event_implicit,start_mark,end_mark) \
+ (EVENT_INIT((event),YAML_DOCUMENT_END_EVENT,(start_mark),(end_mark)), \
+ (event).data.document_end.implicit = (event_implicit))
+
+#define ALIAS_EVENT_INIT(event,event_anchor,start_mark,end_mark) \
+ (EVENT_INIT((event),YAML_ALIAS_EVENT,(start_mark),(end_mark)), \
+ (event).data.alias.anchor = (event_anchor))
+
+#define SCALAR_EVENT_INIT(event,event_anchor,event_tag,event_value,event_length, \
+ event_plain_implicit, event_quoted_implicit,event_style,start_mark,end_mark) \
+ (EVENT_INIT((event),YAML_SCALAR_EVENT,(start_mark),(end_mark)), \
+ (event).data.scalar.anchor = (event_anchor), \
+ (event).data.scalar.tag = (event_tag), \
+ (event).data.scalar.value = (event_value), \
+ (event).data.scalar.length = (event_length), \
+ (event).data.scalar.plain_implicit = (event_plain_implicit), \
+ (event).data.scalar.quoted_implicit = (event_quoted_implicit), \
+ (event).data.scalar.style = (event_style))
+
+#define SEQUENCE_START_EVENT_INIT(event,event_anchor,event_tag, \
+ event_implicit,event_style,start_mark,end_mark) \
+ (EVENT_INIT((event),YAML_SEQUENCE_START_EVENT,(start_mark),(end_mark)), \
+ (event).data.sequence_start.anchor = (event_anchor), \
+ (event).data.sequence_start.tag = (event_tag), \
+ (event).data.sequence_start.implicit = (event_implicit), \
+ (event).data.sequence_start.style = (event_style))
+
+#define SEQUENCE_END_EVENT_INIT(event,start_mark,end_mark) \
+ (EVENT_INIT((event),YAML_SEQUENCE_END_EVENT,(start_mark),(end_mark)))
+
+#define MAPPING_START_EVENT_INIT(event,event_anchor,event_tag, \
+ event_implicit,event_style,start_mark,end_mark) \
+ (EVENT_INIT((event),YAML_MAPPING_START_EVENT,(start_mark),(end_mark)), \
+ (event).data.mapping_start.anchor = (event_anchor), \
+ (event).data.mapping_start.tag = (event_tag), \
+ (event).data.mapping_start.implicit = (event_implicit), \
+ (event).data.mapping_start.style = (event_style))
+
+#define MAPPING_END_EVENT_INIT(event,start_mark,end_mark) \
+ (EVENT_INIT((event),YAML_MAPPING_END_EVENT,(start_mark),(end_mark)))
+
+/*
+ * Document initializer.
+ */
+
+#define DOCUMENT_INIT(document,document_nodes_start,document_nodes_end, \
+ document_version_directive,document_tag_directives_start, \
+ document_tag_directives_end,document_start_implicit, \
+ document_end_implicit,document_start_mark,document_end_mark) \
+ (memset(&(document), 0, sizeof(yaml_document_t)), \
+ (document).nodes.start = (document_nodes_start), \
+ (document).nodes.end = (document_nodes_end), \
+ (document).nodes.top = (document_nodes_start), \
+ (document).version_directive = (document_version_directive), \
+ (document).tag_directives.start = (document_tag_directives_start), \
+ (document).tag_directives.end = (document_tag_directives_end), \
+ (document).start_implicit = (document_start_implicit), \
+ (document).end_implicit = (document_end_implicit), \
+ (document).start_mark = (document_start_mark), \
+ (document).end_mark = (document_end_mark))
+
+/*
+ * Node initializers.
+ */
+
+#define NODE_INIT(node,node_type,node_tag,node_start_mark,node_end_mark) \
+ (memset(&(node), 0, sizeof(yaml_node_t)), \
+ (node).type = (node_type), \
+ (node).tag = (node_tag), \
+ (node).start_mark = (node_start_mark), \
+ (node).end_mark = (node_end_mark))
+
+#define SCALAR_NODE_INIT(node,node_tag,node_value,node_length, \
+ node_style,start_mark,end_mark) \
+ (NODE_INIT((node),YAML_SCALAR_NODE,(node_tag),(start_mark),(end_mark)), \
+ (node).data.scalar.value = (node_value), \
+ (node).data.scalar.length = (node_length), \
+ (node).data.scalar.style = (node_style))
+
+#define SEQUENCE_NODE_INIT(node,node_tag,node_items_start,node_items_end, \
+ node_style,start_mark,end_mark) \
+ (NODE_INIT((node),YAML_SEQUENCE_NODE,(node_tag),(start_mark),(end_mark)), \
+ (node).data.sequence.items.start = (node_items_start), \
+ (node).data.sequence.items.end = (node_items_end), \
+ (node).data.sequence.items.top = (node_items_start), \
+ (node).data.sequence.style = (node_style))
+
+#define MAPPING_NODE_INIT(node,node_tag,node_pairs_start,node_pairs_end, \
+ node_style,start_mark,end_mark) \
+ (NODE_INIT((node),YAML_MAPPING_NODE,(node_tag),(start_mark),(end_mark)), \
+ (node).data.mapping.pairs.start = (node_pairs_start), \
+ (node).data.mapping.pairs.end = (node_pairs_end), \
+ (node).data.mapping.pairs.top = (node_pairs_start), \
+ (node).data.mapping.style = (node_style))
+
diff --git a/contrib/libyaml/tests/Makefile.am b/contrib/libyaml/tests/Makefile.am
new file mode 100644
index 0000000..72e84d2
--- /dev/null
+++ b/contrib/libyaml/tests/Makefile.am
@@ -0,0 +1,8 @@
+AM_CPPFLAGS = -I$(top_srcdir)/include
+#AM_CFLAGS = -Wno-pointer-sign
+LDADD = $(top_builddir)/src/libyaml.la
+TESTS = test-version test-reader
+check_PROGRAMS = test-version test-reader
+noinst_PROGRAMS = run-scanner run-parser run-loader run-emitter run-dumper \
+ example-reformatter example-reformatter-alt \
+ example-deconstructor example-deconstructor-alt
diff --git a/contrib/libyaml/tests/Makefile.in b/contrib/libyaml/tests/Makefile.in
new file mode 100644
index 0000000..2939d9f
--- /dev/null
+++ b/contrib/libyaml/tests/Makefile.in
@@ -0,0 +1,672 @@
+# Makefile.in generated by automake 1.11.1 from Makefile.am.
+# @configure_input@
+
+# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
+# 2003, 2004, 2005, 2006, 2007, 2008, 2009 Free Software Foundation,
+# Inc.
+# This Makefile.in is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
+# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+# PARTICULAR PURPOSE.
+
+@SET_MAKE@
+
+VPATH = @srcdir@
+pkgdatadir = $(datadir)/@PACKAGE@
+pkgincludedir = $(includedir)/@PACKAGE@
+pkglibdir = $(libdir)/@PACKAGE@
+pkglibexecdir = $(libexecdir)/@PACKAGE@
+am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
+install_sh_DATA = $(install_sh) -c -m 644
+install_sh_PROGRAM = $(install_sh) -c
+install_sh_SCRIPT = $(install_sh) -c
+INSTALL_HEADER = $(INSTALL_DATA)
+transform = $(program_transform_name)
+NORMAL_INSTALL = :
+PRE_INSTALL = :
+POST_INSTALL = :
+NORMAL_UNINSTALL = :
+PRE_UNINSTALL = :
+POST_UNINSTALL = :
+build_triplet = @build@
+host_triplet = @host@
+TESTS = test-version$(EXEEXT) test-reader$(EXEEXT)
+check_PROGRAMS = test-version$(EXEEXT) test-reader$(EXEEXT)
+noinst_PROGRAMS = run-scanner$(EXEEXT) run-parser$(EXEEXT) \
+ run-loader$(EXEEXT) run-emitter$(EXEEXT) run-dumper$(EXEEXT) \
+ example-reformatter$(EXEEXT) example-reformatter-alt$(EXEEXT) \
+ example-deconstructor$(EXEEXT) \
+ example-deconstructor-alt$(EXEEXT)
+subdir = tests
+DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in
+ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
+am__aclocal_m4_deps = $(top_srcdir)/configure.ac
+am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
+ $(ACLOCAL_M4)
+mkinstalldirs = $(install_sh) -d
+CONFIG_HEADER = $(top_builddir)/config.h
+CONFIG_CLEAN_FILES =
+CONFIG_CLEAN_VPATH_FILES =
+PROGRAMS = $(noinst_PROGRAMS)
+example_deconstructor_SOURCES = example-deconstructor.c
+example_deconstructor_OBJECTS = example-deconstructor.$(OBJEXT)
+example_deconstructor_LDADD = $(LDADD)
+example_deconstructor_DEPENDENCIES = $(top_builddir)/src/libyaml.la
+example_deconstructor_alt_SOURCES = example-deconstructor-alt.c
+example_deconstructor_alt_OBJECTS = \
+ example-deconstructor-alt.$(OBJEXT)
+example_deconstructor_alt_LDADD = $(LDADD)
+example_deconstructor_alt_DEPENDENCIES = \
+ $(top_builddir)/src/libyaml.la
+example_reformatter_SOURCES = example-reformatter.c
+example_reformatter_OBJECTS = example-reformatter.$(OBJEXT)
+example_reformatter_LDADD = $(LDADD)
+example_reformatter_DEPENDENCIES = $(top_builddir)/src/libyaml.la
+example_reformatter_alt_SOURCES = example-reformatter-alt.c
+example_reformatter_alt_OBJECTS = example-reformatter-alt.$(OBJEXT)
+example_reformatter_alt_LDADD = $(LDADD)
+example_reformatter_alt_DEPENDENCIES = $(top_builddir)/src/libyaml.la
+run_dumper_SOURCES = run-dumper.c
+run_dumper_OBJECTS = run-dumper.$(OBJEXT)
+run_dumper_LDADD = $(LDADD)
+run_dumper_DEPENDENCIES = $(top_builddir)/src/libyaml.la
+run_emitter_SOURCES = run-emitter.c
+run_emitter_OBJECTS = run-emitter.$(OBJEXT)
+run_emitter_LDADD = $(LDADD)
+run_emitter_DEPENDENCIES = $(top_builddir)/src/libyaml.la
+run_loader_SOURCES = run-loader.c
+run_loader_OBJECTS = run-loader.$(OBJEXT)
+run_loader_LDADD = $(LDADD)
+run_loader_DEPENDENCIES = $(top_builddir)/src/libyaml.la
+run_parser_SOURCES = run-parser.c
+run_parser_OBJECTS = run-parser.$(OBJEXT)
+run_parser_LDADD = $(LDADD)
+run_parser_DEPENDENCIES = $(top_builddir)/src/libyaml.la
+run_scanner_SOURCES = run-scanner.c
+run_scanner_OBJECTS = run-scanner.$(OBJEXT)
+run_scanner_LDADD = $(LDADD)
+run_scanner_DEPENDENCIES = $(top_builddir)/src/libyaml.la
+test_reader_SOURCES = test-reader.c
+test_reader_OBJECTS = test-reader.$(OBJEXT)
+test_reader_LDADD = $(LDADD)
+test_reader_DEPENDENCIES = $(top_builddir)/src/libyaml.la
+test_version_SOURCES = test-version.c
+test_version_OBJECTS = test-version.$(OBJEXT)
+test_version_LDADD = $(LDADD)
+test_version_DEPENDENCIES = $(top_builddir)/src/libyaml.la
+DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir)
+depcomp = $(SHELL) $(top_srcdir)/config/depcomp
+am__depfiles_maybe = depfiles
+am__mv = mv -f
+COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \
+ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
+LTCOMPILE = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \
+ --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \
+ $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
+CCLD = $(CC)
+LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \
+ --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) \
+ $(LDFLAGS) -o $@
+SOURCES = example-deconstructor.c example-deconstructor-alt.c \
+ example-reformatter.c example-reformatter-alt.c run-dumper.c \
+ run-emitter.c run-loader.c run-parser.c run-scanner.c \
+ test-reader.c test-version.c
+DIST_SOURCES = example-deconstructor.c example-deconstructor-alt.c \
+ example-reformatter.c example-reformatter-alt.c run-dumper.c \
+ run-emitter.c run-loader.c run-parser.c run-scanner.c \
+ test-reader.c test-version.c
+ETAGS = etags
+CTAGS = ctags
+am__tty_colors = \
+red=; grn=; lgn=; blu=; std=
+DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
+ACLOCAL = @ACLOCAL@
+AMTAR = @AMTAR@
+AR = @AR@
+AUTOCONF = @AUTOCONF@
+AUTOHEADER = @AUTOHEADER@
+AUTOMAKE = @AUTOMAKE@
+AWK = @AWK@
+CC = @CC@
+CCDEPMODE = @CCDEPMODE@
+CFLAGS = @CFLAGS@
+CPP = @CPP@
+CPPFLAGS = @CPPFLAGS@
+CYGPATH_W = @CYGPATH_W@
+DEFS = @DEFS@
+DEPDIR = @DEPDIR@
+DOXYGEN = @DOXYGEN@
+DSYMUTIL = @DSYMUTIL@
+DUMPBIN = @DUMPBIN@
+ECHO_C = @ECHO_C@
+ECHO_N = @ECHO_N@
+ECHO_T = @ECHO_T@
+EGREP = @EGREP@
+EXEEXT = @EXEEXT@
+FGREP = @FGREP@
+GREP = @GREP@
+INSTALL = @INSTALL@
+INSTALL_DATA = @INSTALL_DATA@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@
+INSTALL_SCRIPT = @INSTALL_SCRIPT@
+INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
+LD = @LD@
+LDFLAGS = @LDFLAGS@
+LIBOBJS = @LIBOBJS@
+LIBS = @LIBS@
+LIBTOOL = @LIBTOOL@
+LIPO = @LIPO@
+LN_S = @LN_S@
+LTLIBOBJS = @LTLIBOBJS@
+MAKEINFO = @MAKEINFO@
+MKDIR_P = @MKDIR_P@
+NM = @NM@
+NMEDIT = @NMEDIT@
+OBJDUMP = @OBJDUMP@
+OBJEXT = @OBJEXT@
+OTOOL = @OTOOL@
+OTOOL64 = @OTOOL64@
+PACKAGE = @PACKAGE@
+PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
+PACKAGE_NAME = @PACKAGE_NAME@
+PACKAGE_STRING = @PACKAGE_STRING@
+PACKAGE_TARNAME = @PACKAGE_TARNAME@
+PACKAGE_URL = @PACKAGE_URL@
+PACKAGE_VERSION = @PACKAGE_VERSION@
+PATH_SEPARATOR = @PATH_SEPARATOR@
+RANLIB = @RANLIB@
+SED = @SED@
+SET_MAKE = @SET_MAKE@
+SHELL = @SHELL@
+STRIP = @STRIP@
+VERSION = @VERSION@
+YAML_LT_AGE = @YAML_LT_AGE@
+YAML_LT_CURRENT = @YAML_LT_CURRENT@
+YAML_LT_RELEASE = @YAML_LT_RELEASE@
+YAML_LT_REVISION = @YAML_LT_REVISION@
+abs_builddir = @abs_builddir@
+abs_srcdir = @abs_srcdir@
+abs_top_builddir = @abs_top_builddir@
+abs_top_srcdir = @abs_top_srcdir@
+ac_ct_CC = @ac_ct_CC@
+ac_ct_DUMPBIN = @ac_ct_DUMPBIN@
+am__include = @am__include@
+am__leading_dot = @am__leading_dot@
+am__quote = @am__quote@
+am__tar = @am__tar@
+am__untar = @am__untar@
+bindir = @bindir@
+build = @build@
+build_alias = @build_alias@
+build_cpu = @build_cpu@
+build_os = @build_os@
+build_vendor = @build_vendor@
+builddir = @builddir@
+datadir = @datadir@
+datarootdir = @datarootdir@
+docdir = @docdir@
+dvidir = @dvidir@
+exec_prefix = @exec_prefix@
+host = @host@
+host_alias = @host_alias@
+host_cpu = @host_cpu@
+host_os = @host_os@
+host_vendor = @host_vendor@
+htmldir = @htmldir@
+includedir = @includedir@
+infodir = @infodir@
+install_sh = @install_sh@
+libdir = @libdir@
+libexecdir = @libexecdir@
+localedir = @localedir@
+localstatedir = @localstatedir@
+lt_ECHO = @lt_ECHO@
+mandir = @mandir@
+mkdir_p = @mkdir_p@
+oldincludedir = @oldincludedir@
+pdfdir = @pdfdir@
+prefix = @prefix@
+program_transform_name = @program_transform_name@
+psdir = @psdir@
+sbindir = @sbindir@
+sharedstatedir = @sharedstatedir@
+srcdir = @srcdir@
+sysconfdir = @sysconfdir@
+target_alias = @target_alias@
+top_build_prefix = @top_build_prefix@
+top_builddir = @top_builddir@
+top_srcdir = @top_srcdir@
+AM_CPPFLAGS = -I$(top_srcdir)/include
+#AM_CFLAGS = -Wno-pointer-sign
+LDADD = $(top_builddir)/src/libyaml.la
+all: all-am
+
+.SUFFIXES:
+.SUFFIXES: .c .lo .o .obj
+$(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps)
+ @for dep in $?; do \
+ case '$(am__configure_deps)' in \
+ *$$dep*) \
+ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \
+ && { if test -f $@; then exit 0; else break; fi; }; \
+ exit 1;; \
+ esac; \
+ done; \
+ echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign tests/Makefile'; \
+ $(am__cd) $(top_srcdir) && \
+ $(AUTOMAKE) --foreign tests/Makefile
+.PRECIOUS: Makefile
+Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
+ @case '$?' in \
+ *config.status*) \
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \
+ *) \
+ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \
+ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \
+ esac;
+
+$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+
+$(top_srcdir)/configure: $(am__configure_deps)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(ACLOCAL_M4): $(am__aclocal_m4_deps)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(am__aclocal_m4_deps):
+
+clean-checkPROGRAMS:
+ @list='$(check_PROGRAMS)'; test -n "$$list" || exit 0; \
+ echo " rm -f" $$list; \
+ rm -f $$list || exit $$?; \
+ test -n "$(EXEEXT)" || exit 0; \
+ list=`for p in $$list; do echo "$$p"; done | sed 's/$(EXEEXT)$$//'`; \
+ echo " rm -f" $$list; \
+ rm -f $$list
+
+clean-noinstPROGRAMS:
+ @list='$(noinst_PROGRAMS)'; test -n "$$list" || exit 0; \
+ echo " rm -f" $$list; \
+ rm -f $$list || exit $$?; \
+ test -n "$(EXEEXT)" || exit 0; \
+ list=`for p in $$list; do echo "$$p"; done | sed 's/$(EXEEXT)$$//'`; \
+ echo " rm -f" $$list; \
+ rm -f $$list
+example-deconstructor$(EXEEXT): $(example_deconstructor_OBJECTS) $(example_deconstructor_DEPENDENCIES)
+ @rm -f example-deconstructor$(EXEEXT)
+ $(LINK) $(example_deconstructor_OBJECTS) $(example_deconstructor_LDADD) $(LIBS)
+example-deconstructor-alt$(EXEEXT): $(example_deconstructor_alt_OBJECTS) $(example_deconstructor_alt_DEPENDENCIES)
+ @rm -f example-deconstructor-alt$(EXEEXT)
+ $(LINK) $(example_deconstructor_alt_OBJECTS) $(example_deconstructor_alt_LDADD) $(LIBS)
+example-reformatter$(EXEEXT): $(example_reformatter_OBJECTS) $(example_reformatter_DEPENDENCIES)
+ @rm -f example-reformatter$(EXEEXT)
+ $(LINK) $(example_reformatter_OBJECTS) $(example_reformatter_LDADD) $(LIBS)
+example-reformatter-alt$(EXEEXT): $(example_reformatter_alt_OBJECTS) $(example_reformatter_alt_DEPENDENCIES)
+ @rm -f example-reformatter-alt$(EXEEXT)
+ $(LINK) $(example_reformatter_alt_OBJECTS) $(example_reformatter_alt_LDADD) $(LIBS)
+run-dumper$(EXEEXT): $(run_dumper_OBJECTS) $(run_dumper_DEPENDENCIES)
+ @rm -f run-dumper$(EXEEXT)
+ $(LINK) $(run_dumper_OBJECTS) $(run_dumper_LDADD) $(LIBS)
+run-emitter$(EXEEXT): $(run_emitter_OBJECTS) $(run_emitter_DEPENDENCIES)
+ @rm -f run-emitter$(EXEEXT)
+ $(LINK) $(run_emitter_OBJECTS) $(run_emitter_LDADD) $(LIBS)
+run-loader$(EXEEXT): $(run_loader_OBJECTS) $(run_loader_DEPENDENCIES)
+ @rm -f run-loader$(EXEEXT)
+ $(LINK) $(run_loader_OBJECTS) $(run_loader_LDADD) $(LIBS)
+run-parser$(EXEEXT): $(run_parser_OBJECTS) $(run_parser_DEPENDENCIES)
+ @rm -f run-parser$(EXEEXT)
+ $(LINK) $(run_parser_OBJECTS) $(run_parser_LDADD) $(LIBS)
+run-scanner$(EXEEXT): $(run_scanner_OBJECTS) $(run_scanner_DEPENDENCIES)
+ @rm -f run-scanner$(EXEEXT)
+ $(LINK) $(run_scanner_OBJECTS) $(run_scanner_LDADD) $(LIBS)
+test-reader$(EXEEXT): $(test_reader_OBJECTS) $(test_reader_DEPENDENCIES)
+ @rm -f test-reader$(EXEEXT)
+ $(LINK) $(test_reader_OBJECTS) $(test_reader_LDADD) $(LIBS)
+test-version$(EXEEXT): $(test_version_OBJECTS) $(test_version_DEPENDENCIES)
+ @rm -f test-version$(EXEEXT)
+ $(LINK) $(test_version_OBJECTS) $(test_version_LDADD) $(LIBS)
+
+mostlyclean-compile:
+ -rm -f *.$(OBJEXT)
+
+distclean-compile:
+ -rm -f *.tab.c
+
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/example-deconstructor-alt.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/example-deconstructor.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/example-reformatter-alt.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/example-reformatter.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/run-dumper.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/run-emitter.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/run-loader.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/run-parser.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/run-scanner.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test-reader.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test-version.Po@am__quote@
+
+.c.o:
+@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
+@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(COMPILE) -c $<
+
+.c.obj:
+@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'`
+@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(COMPILE) -c `$(CYGPATH_W) '$<'`
+
+.c.lo:
+@am__fastdepCC_TRUE@ $(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
+@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(LTCOMPILE) -c -o $@ $<
+
+mostlyclean-libtool:
+ -rm -f *.lo
+
+clean-libtool:
+ -rm -rf .libs _libs
+
+ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES)
+ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
+ unique=`for i in $$list; do \
+ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+ done | \
+ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \
+ END { if (nonempty) { for (i in files) print i; }; }'`; \
+ mkid -fID $$unique
+tags: TAGS
+
+TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \
+ $(TAGS_FILES) $(LISP)
+ set x; \
+ here=`pwd`; \
+ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
+ unique=`for i in $$list; do \
+ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+ done | \
+ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \
+ END { if (nonempty) { for (i in files) print i; }; }'`; \
+ shift; \
+ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \
+ test -n "$$unique" || unique=$$empty_fix; \
+ if test $$# -gt 0; then \
+ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
+ "$$@" $$unique; \
+ else \
+ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
+ $$unique; \
+ fi; \
+ fi
+ctags: CTAGS
+CTAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \
+ $(TAGS_FILES) $(LISP)
+ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
+ unique=`for i in $$list; do \
+ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+ done | \
+ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \
+ END { if (nonempty) { for (i in files) print i; }; }'`; \
+ test -z "$(CTAGS_ARGS)$$unique" \
+ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \
+ $$unique
+
+GTAGS:
+ here=`$(am__cd) $(top_builddir) && pwd` \
+ && $(am__cd) $(top_srcdir) \
+ && gtags -i $(GTAGS_ARGS) "$$here"
+
+distclean-tags:
+ -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
+
+check-TESTS: $(TESTS)
+ @failed=0; all=0; xfail=0; xpass=0; skip=0; \
+ srcdir=$(srcdir); export srcdir; \
+ list=' $(TESTS) '; \
+ $(am__tty_colors); \
+ if test -n "$$list"; then \
+ for tst in $$list; do \
+ if test -f ./$$tst; then dir=./; \
+ elif test -f $$tst; then dir=; \
+ else dir="$(srcdir)/"; fi; \
+ if $(TESTS_ENVIRONMENT) $${dir}$$tst; then \
+ all=`expr $$all + 1`; \
+ case " $(XFAIL_TESTS) " in \
+ *[\ \ ]$$tst[\ \ ]*) \
+ xpass=`expr $$xpass + 1`; \
+ failed=`expr $$failed + 1`; \
+ col=$$red; res=XPASS; \
+ ;; \
+ *) \
+ col=$$grn; res=PASS; \
+ ;; \
+ esac; \
+ elif test $$? -ne 77; then \
+ all=`expr $$all + 1`; \
+ case " $(XFAIL_TESTS) " in \
+ *[\ \ ]$$tst[\ \ ]*) \
+ xfail=`expr $$xfail + 1`; \
+ col=$$lgn; res=XFAIL; \
+ ;; \
+ *) \
+ failed=`expr $$failed + 1`; \
+ col=$$red; res=FAIL; \
+ ;; \
+ esac; \
+ else \
+ skip=`expr $$skip + 1`; \
+ col=$$blu; res=SKIP; \
+ fi; \
+ echo "$${col}$$res$${std}: $$tst"; \
+ done; \
+ if test "$$all" -eq 1; then \
+ tests="test"; \
+ All=""; \
+ else \
+ tests="tests"; \
+ All="All "; \
+ fi; \
+ if test "$$failed" -eq 0; then \
+ if test "$$xfail" -eq 0; then \
+ banner="$$All$$all $$tests passed"; \
+ else \
+ if test "$$xfail" -eq 1; then failures=failure; else failures=failures; fi; \
+ banner="$$All$$all $$tests behaved as expected ($$xfail expected $$failures)"; \
+ fi; \
+ else \
+ if test "$$xpass" -eq 0; then \
+ banner="$$failed of $$all $$tests failed"; \
+ else \
+ if test "$$xpass" -eq 1; then passes=pass; else passes=passes; fi; \
+ banner="$$failed of $$all $$tests did not behave as expected ($$xpass unexpected $$passes)"; \
+ fi; \
+ fi; \
+ dashes="$$banner"; \
+ skipped=""; \
+ if test "$$skip" -ne 0; then \
+ if test "$$skip" -eq 1; then \
+ skipped="($$skip test was not run)"; \
+ else \
+ skipped="($$skip tests were not run)"; \
+ fi; \
+ test `echo "$$skipped" | wc -c` -le `echo "$$banner" | wc -c` || \
+ dashes="$$skipped"; \
+ fi; \
+ report=""; \
+ if test "$$failed" -ne 0 && test -n "$(PACKAGE_BUGREPORT)"; then \
+ report="Please report to $(PACKAGE_BUGREPORT)"; \
+ test `echo "$$report" | wc -c` -le `echo "$$banner" | wc -c` || \
+ dashes="$$report"; \
+ fi; \
+ dashes=`echo "$$dashes" | sed s/./=/g`; \
+ if test "$$failed" -eq 0; then \
+ echo "$$grn$$dashes"; \
+ else \
+ echo "$$red$$dashes"; \
+ fi; \
+ echo "$$banner"; \
+ test -z "$$skipped" || echo "$$skipped"; \
+ test -z "$$report" || echo "$$report"; \
+ echo "$$dashes$$std"; \
+ test "$$failed" -eq 0; \
+ else :; fi
+
+distdir: $(DISTFILES)
+ @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+ list='$(DISTFILES)'; \
+ dist_files=`for file in $$list; do echo $$file; done | \
+ sed -e "s|^$$srcdirstrip/||;t" \
+ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \
+ case $$dist_files in \
+ */*) $(MKDIR_P) `echo "$$dist_files" | \
+ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \
+ sort -u` ;; \
+ esac; \
+ for file in $$dist_files; do \
+ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
+ if test -d $$d/$$file; then \
+ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \
+ if test -d "$(distdir)/$$file"; then \
+ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
+ fi; \
+ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
+ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \
+ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
+ fi; \
+ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \
+ else \
+ test -f "$(distdir)/$$file" \
+ || cp -p $$d/$$file "$(distdir)/$$file" \
+ || exit 1; \
+ fi; \
+ done
+check-am: all-am
+ $(MAKE) $(AM_MAKEFLAGS) $(check_PROGRAMS)
+ $(MAKE) $(AM_MAKEFLAGS) check-TESTS
+check: check-am
+all-am: Makefile $(PROGRAMS)
+installdirs:
+install: install-am
+install-exec: install-exec-am
+install-data: install-data-am
+uninstall: uninstall-am
+
+install-am: all-am
+ @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
+
+installcheck: installcheck-am
+install-strip:
+ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+ `test -z '$(STRIP)' || \
+ echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install
+mostlyclean-generic:
+
+clean-generic:
+
+distclean-generic:
+ -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
+ -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES)
+
+maintainer-clean-generic:
+ @echo "This command is intended for maintainers to use"
+ @echo "it deletes files that may require special tools to rebuild."
+clean: clean-am
+
+clean-am: clean-checkPROGRAMS clean-generic clean-libtool \
+ clean-noinstPROGRAMS mostlyclean-am
+
+distclean: distclean-am
+ -rm -rf ./$(DEPDIR)
+ -rm -f Makefile
+distclean-am: clean-am distclean-compile distclean-generic \
+ distclean-tags
+
+dvi: dvi-am
+
+dvi-am:
+
+html: html-am
+
+html-am:
+
+info: info-am
+
+info-am:
+
+install-data-am:
+
+install-dvi: install-dvi-am
+
+install-dvi-am:
+
+install-exec-am:
+
+install-html: install-html-am
+
+install-html-am:
+
+install-info: install-info-am
+
+install-info-am:
+
+install-man:
+
+install-pdf: install-pdf-am
+
+install-pdf-am:
+
+install-ps: install-ps-am
+
+install-ps-am:
+
+installcheck-am:
+
+maintainer-clean: maintainer-clean-am
+ -rm -rf ./$(DEPDIR)
+ -rm -f Makefile
+maintainer-clean-am: distclean-am maintainer-clean-generic
+
+mostlyclean: mostlyclean-am
+
+mostlyclean-am: mostlyclean-compile mostlyclean-generic \
+ mostlyclean-libtool
+
+pdf: pdf-am
+
+pdf-am:
+
+ps: ps-am
+
+ps-am:
+
+uninstall-am:
+
+.MAKE: check-am install-am install-strip
+
+.PHONY: CTAGS GTAGS all all-am check check-TESTS check-am clean \
+ clean-checkPROGRAMS clean-generic clean-libtool \
+ clean-noinstPROGRAMS ctags distclean distclean-compile \
+ distclean-generic distclean-libtool distclean-tags distdir dvi \
+ dvi-am html html-am info info-am install install-am \
+ install-data install-data-am install-dvi install-dvi-am \
+ install-exec install-exec-am install-html install-html-am \
+ install-info install-info-am install-man install-pdf \
+ install-pdf-am install-ps install-ps-am install-strip \
+ installcheck installcheck-am installdirs maintainer-clean \
+ maintainer-clean-generic mostlyclean mostlyclean-compile \
+ mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \
+ tags uninstall uninstall-am
+
+
+# Tell versions [3.59,3.63) of GNU make to not export all variables.
+# Otherwise a system limit (for SysV at least) may be exceeded.
+.NOEXPORT:
diff --git a/contrib/libyaml/tests/example-deconstructor-alt.c b/contrib/libyaml/tests/example-deconstructor-alt.c
new file mode 100644
index 0000000..7da194a
--- /dev/null
+++ b/contrib/libyaml/tests/example-deconstructor-alt.c
@@ -0,0 +1,800 @@
+
+#include <yaml.h>
+
+#include <stdlib.h>
+#include <stdio.h>
+
+int
+main(int argc, char *argv[])
+{
+ int help = 0;
+ int canonical = 0;
+ int unicode = 0;
+ int k;
+ int done = 0;
+
+ yaml_parser_t parser;
+ yaml_emitter_t emitter;
+ yaml_event_t input_event;
+ yaml_document_t output_document;
+
+ int root;
+
+ /* Clear the objects. */
+
+ memset(&parser, 0, sizeof(parser));
+ memset(&emitter, 0, sizeof(emitter));
+ memset(&input_event, 0, sizeof(input_event));
+ memset(&output_document, 0, sizeof(output_document));
+
+ /* Analyze command line options. */
+
+ for (k = 1; k < argc; k ++)
+ {
+ if (strcmp(argv[k], "-h") == 0
+ || strcmp(argv[k], "--help") == 0) {
+ help = 1;
+ }
+
+ else if (strcmp(argv[k], "-c") == 0
+ || strcmp(argv[k], "--canonical") == 0) {
+ canonical = 1;
+ }
+
+ else if (strcmp(argv[k], "-u") == 0
+ || strcmp(argv[k], "--unicode") == 0) {
+ unicode = 1;
+ }
+
+ else {
+ fprintf(stderr, "Unrecognized option: %s\n"
+ "Try `%s --help` for more information.\n",
+ argv[k], argv[0]);
+ return 1;
+ }
+ }
+
+ /* Display the help string. */
+
+ if (help)
+ {
+ printf("%s <input\n"
+ "or\n%s -h | --help\nDeconstruct a YAML stream\n\nOptions:\n"
+ "-h, --help\t\tdisplay this help and exit\n"
+ "-c, --canonical\t\toutput in the canonical YAML format\n"
+ "-u, --unicode\t\toutput unescaped non-ASCII characters\n",
+ argv[0], argv[0]);
+ return 0;
+ }
+
+ /* Initialize the parser and emitter objects. */
+
+ if (!yaml_parser_initialize(&parser)) {
+ fprintf(stderr, "Could not initialize the parser object\n");
+ return 1;
+ }
+
+ if (!yaml_emitter_initialize(&emitter)) {
+ yaml_parser_delete(&parser);
+ fprintf(stderr, "Could not inialize the emitter object\n");
+ return 1;
+ }
+
+ /* Set the parser parameters. */
+
+ yaml_parser_set_input_file(&parser, stdin);
+
+ /* Set the emitter parameters. */
+
+ yaml_emitter_set_output_file(&emitter, stdout);
+
+ yaml_emitter_set_canonical(&emitter, canonical);
+ yaml_emitter_set_unicode(&emitter, unicode);
+
+ /* Create and emit the STREAM-START event. */
+
+ if (!yaml_emitter_open(&emitter))
+ goto emitter_error;
+
+ /* Create a output_document object. */
+
+ if (!yaml_document_initialize(&output_document, NULL, NULL, NULL, 0, 0))
+ goto document_error;
+
+ /* Create the root sequence. */
+
+ root = yaml_document_add_sequence(&output_document, NULL,
+ YAML_BLOCK_SEQUENCE_STYLE);
+ if (!root) goto document_error;
+
+ /* Loop through the input events. */
+
+ while (!done)
+ {
+ int properties, key, value, map, seq;
+
+ /* Get the next event. */
+
+ if (!yaml_parser_parse(&parser, &input_event))
+ goto parser_error;
+
+ /* Check if this is the stream end. */
+
+ if (input_event.type == YAML_STREAM_END_EVENT) {
+ done = 1;
+ }
+
+ /* Create a mapping node and attach it to the root sequence. */
+
+ properties = yaml_document_add_mapping(&output_document, NULL,
+ YAML_BLOCK_MAPPING_STYLE);
+ if (!properties) goto document_error;
+ if (!yaml_document_append_sequence_item(&output_document,
+ root, properties)) goto document_error;
+
+ /* Analyze the event. */
+
+ switch (input_event.type)
+ {
+ case YAML_STREAM_START_EVENT:
+
+ /* Add 'type': 'STREAM-START'. */
+
+ key = yaml_document_add_scalar(&output_document, NULL,
+ "type", -1, YAML_PLAIN_SCALAR_STYLE);
+ if (!key) goto document_error;
+ value = yaml_document_add_scalar(&output_document, NULL,
+ "STREAM-START", -1, YAML_PLAIN_SCALAR_STYLE);
+ if (!value) goto document_error;
+ if (!yaml_document_append_mapping_pair(&output_document,
+ properties, key, value)) goto document_error;
+
+ /* Add 'encoding': <encoding>. */
+
+ if (input_event.data.stream_start.encoding)
+ {
+ yaml_encoding_t encoding
+ = input_event.data.stream_start.encoding;
+
+ key = yaml_document_add_scalar(&output_document, NULL,
+ "encoding", -1, YAML_PLAIN_SCALAR_STYLE);
+ if (!key) goto document_error;
+ value = yaml_document_add_scalar(&output_document, NULL,
+ (encoding == YAML_UTF8_ENCODING ? "utf-8" :
+ encoding == YAML_UTF16LE_ENCODING ? "utf-16-le" :
+ encoding == YAML_UTF16BE_ENCODING ? "utf-16-be" :
+ "unknown"), -1, YAML_PLAIN_SCALAR_STYLE);
+ if (!value) goto document_error;
+ if (!yaml_document_append_mapping_pair(&output_document,
+ properties, key, value)) goto document_error;
+ }
+
+ break;
+
+ case YAML_STREAM_END_EVENT:
+
+ /* Add 'type': 'STREAM-END'. */
+
+ key = yaml_document_add_scalar(&output_document, NULL,
+ "type", -1, YAML_PLAIN_SCALAR_STYLE);
+ if (!key) goto document_error;
+ value = yaml_document_add_scalar(&output_document, NULL,
+ "STREAM-END", -1, YAML_PLAIN_SCALAR_STYLE);
+ if (!value) goto document_error;
+ if (!yaml_document_append_mapping_pair(&output_document,
+ properties, key, value)) goto document_error;
+
+ break;
+
+ case YAML_DOCUMENT_START_EVENT:
+
+ /* Add 'type': 'DOCUMENT-START'. */
+
+ key = yaml_document_add_scalar(&output_document, NULL,
+ "type", -1, YAML_PLAIN_SCALAR_STYLE);
+ if (!key) goto document_error;
+ value = yaml_document_add_scalar(&output_document, NULL,
+ "DOCUMENT-START", -1, YAML_PLAIN_SCALAR_STYLE);
+ if (!value) goto document_error;
+ if (!yaml_document_append_mapping_pair(&output_document,
+ properties, key, value)) goto document_error;
+
+ /* Display the output_document version numbers. */
+
+ if (input_event.data.document_start.version_directive)
+ {
+ yaml_version_directive_t *version
+ = input_event.data.document_start.version_directive;
+ char number[64];
+
+ /* Add 'version': {}. */
+
+ key = yaml_document_add_scalar(&output_document, NULL,
+ "version", -1, YAML_PLAIN_SCALAR_STYLE);
+ if (!key) goto document_error;
+ map = yaml_document_add_mapping(&output_document, NULL,
+ YAML_FLOW_MAPPING_STYLE);
+ if (!map) goto document_error;
+ if (!yaml_document_append_mapping_pair(&output_document,
+ properties, key, map)) goto document_error;
+
+ /* Add 'major': <number>. */
+
+ key = yaml_document_add_scalar(&output_document, NULL,
+ "major", -1, YAML_PLAIN_SCALAR_STYLE);
+ if (!key) goto document_error;
+ sprintf(number, "%d", version->major);
+ value = yaml_document_add_scalar(&output_document, YAML_INT_TAG,
+ number, -1, YAML_PLAIN_SCALAR_STYLE);
+ if (!value) goto document_error;
+ if (!yaml_document_append_mapping_pair(&output_document,
+ map, key, value)) goto document_error;
+
+ /* Add 'minor': <number>. */
+
+ key = yaml_document_add_scalar(&output_document, NULL,
+ "minor", -1, YAML_PLAIN_SCALAR_STYLE);
+ if (!key) goto document_error;
+ sprintf(number, "%d", version->minor);
+ value = yaml_document_add_scalar(&output_document, YAML_INT_TAG,
+ number, -1, YAML_PLAIN_SCALAR_STYLE);
+ if (!value) goto document_error;
+ if (!yaml_document_append_mapping_pair(&output_document,
+ map, key, value)) goto document_error;
+ }
+
+ /* Display the output_document tag directives. */
+
+ if (input_event.data.document_start.tag_directives.start
+ != input_event.data.document_start.tag_directives.end)
+ {
+ yaml_tag_directive_t *tag;
+
+ /* Add 'tags': []. */
+
+ key = yaml_document_add_scalar(&output_document, NULL,
+ "tags", -1, YAML_PLAIN_SCALAR_STYLE);
+ if (!key) goto document_error;
+ seq = yaml_document_add_sequence(&output_document, NULL,
+ YAML_BLOCK_SEQUENCE_STYLE);
+ if (!seq) goto document_error;
+ if (!yaml_document_append_mapping_pair(&output_document,
+ properties, key, seq)) goto document_error;
+
+ for (tag = input_event.data.document_start.tag_directives.start;
+ tag != input_event.data.document_start.tag_directives.end;
+ tag ++)
+ {
+ /* Add {}. */
+
+ map = yaml_document_add_mapping(&output_document, NULL,
+ YAML_FLOW_MAPPING_STYLE);
+ if (!map) goto document_error;
+ if (!yaml_document_append_sequence_item(&output_document,
+ seq, map)) goto document_error;
+
+ /* Add 'handle': <handle>. */
+
+ key = yaml_document_add_scalar(&output_document, NULL,
+ "handle", -1, YAML_PLAIN_SCALAR_STYLE);
+ if (!key) goto document_error;
+ value = yaml_document_add_scalar(&output_document, NULL,
+ tag->handle, -1, YAML_DOUBLE_QUOTED_SCALAR_STYLE);
+ if (!value) goto document_error;
+ if (!yaml_document_append_mapping_pair(&output_document,
+ map, key, value)) goto document_error;
+
+ /* Add 'prefix': <prefix>. */
+
+ key = yaml_document_add_scalar(&output_document, NULL,
+ "prefix", -1, YAML_PLAIN_SCALAR_STYLE);
+ if (!key) goto document_error;
+ value = yaml_document_add_scalar(&output_document, NULL,
+ tag->prefix, -1, YAML_DOUBLE_QUOTED_SCALAR_STYLE);
+ if (!value) goto document_error;
+ if (!yaml_document_append_mapping_pair(&output_document,
+ map, key, value)) goto document_error;
+ }
+ }
+
+ /* Add 'implicit': <flag>. */
+
+ key = yaml_document_add_scalar(&output_document, NULL,
+ "implicit", -1, YAML_PLAIN_SCALAR_STYLE);
+ if (!key) goto document_error;
+ value = yaml_document_add_scalar(&output_document, YAML_BOOL_TAG,
+ (input_event.data.document_start.implicit ?
+ "true" : "false"), -1, YAML_PLAIN_SCALAR_STYLE);
+ if (!value) goto document_error;
+ if (!yaml_document_append_mapping_pair(&output_document,
+ properties, key, value)) goto document_error;
+
+ break;
+
+ case YAML_DOCUMENT_END_EVENT:
+
+ /* Add 'type': 'DOCUMENT-END'. */
+
+ key = yaml_document_add_scalar(&output_document, NULL,
+ "type", -1, YAML_PLAIN_SCALAR_STYLE);
+ if (!key) goto document_error;
+ value = yaml_document_add_scalar(&output_document, NULL,
+ "DOCUMENT-END", -1, YAML_PLAIN_SCALAR_STYLE);
+ if (!value) goto document_error;
+ if (!yaml_document_append_mapping_pair(&output_document,
+ properties, key, value)) goto document_error;
+
+ /* Add 'implicit': <flag>. */
+
+ key = yaml_document_add_scalar(&output_document, NULL,
+ "implicit", -1, YAML_PLAIN_SCALAR_STYLE);
+ if (!key) goto document_error;
+ value = yaml_document_add_scalar(&output_document, YAML_BOOL_TAG,
+ (input_event.data.document_end.implicit ?
+ "true" : "false"), -1, YAML_PLAIN_SCALAR_STYLE);
+ if (!value) goto document_error;
+ if (!yaml_document_append_mapping_pair(&output_document,
+ properties, key, value)) goto document_error;
+
+ break;
+
+ case YAML_ALIAS_EVENT:
+
+ /* Add 'type': 'ALIAS'. */
+
+ key = yaml_document_add_scalar(&output_document, NULL,
+ "type", -1, YAML_PLAIN_SCALAR_STYLE);
+ if (!key) goto document_error;
+ value = yaml_document_add_scalar(&output_document, NULL,
+ "ALIAS", -1, YAML_PLAIN_SCALAR_STYLE);
+ if (!value) goto document_error;
+ if (!yaml_document_append_mapping_pair(&output_document,
+ properties, key, value)) goto document_error;
+
+ /* Add 'anchor': <anchor>. */
+
+ key = yaml_document_add_scalar(&output_document, NULL,
+ "anchor", -1, YAML_PLAIN_SCALAR_STYLE);
+ if (!key) goto document_error;
+ value = yaml_document_add_scalar(&output_document, NULL,
+ input_event.data.alias.anchor, -1,
+ YAML_DOUBLE_QUOTED_SCALAR_STYLE);
+ if (!value) goto document_error;
+ if (!yaml_document_append_mapping_pair(&output_document,
+ properties, key, value)) goto document_error;
+
+ break;
+
+ case YAML_SCALAR_EVENT:
+
+ /* Add 'type': 'SCALAR'. */
+
+ key = yaml_document_add_scalar(&output_document, NULL,
+ "type", -1, YAML_PLAIN_SCALAR_STYLE);
+ if (!key) goto document_error;
+ value = yaml_document_add_scalar(&output_document, NULL,
+ "SCALAR", -1, YAML_PLAIN_SCALAR_STYLE);
+ if (!value) goto document_error;
+ if (!yaml_document_append_mapping_pair(&output_document,
+ properties, key, value)) goto document_error;
+
+ /* Add 'anchor': <anchor>. */
+
+ if (input_event.data.scalar.anchor)
+ {
+ key = yaml_document_add_scalar(&output_document, NULL,
+ "anchor", -1, YAML_PLAIN_SCALAR_STYLE);
+ if (!key) goto document_error;
+ value = yaml_document_add_scalar(&output_document, NULL,
+ input_event.data.scalar.anchor, -1,
+ YAML_DOUBLE_QUOTED_SCALAR_STYLE);
+ if (!value) goto document_error;
+ if (!yaml_document_append_mapping_pair(&output_document,
+ properties, key, value)) goto document_error;
+ }
+
+ /* Add 'tag': <tag>. */
+
+ if (input_event.data.scalar.tag)
+ {
+ key = yaml_document_add_scalar(&output_document, NULL,
+ "tag", -1, YAML_PLAIN_SCALAR_STYLE);
+ if (!key) goto document_error;
+ value = yaml_document_add_scalar(&output_document, NULL,
+ input_event.data.scalar.tag, -1,
+ YAML_DOUBLE_QUOTED_SCALAR_STYLE);
+ if (!value) goto document_error;
+ if (!yaml_document_append_mapping_pair(&output_document,
+ properties, key, value)) goto document_error;
+ }
+
+ /* Add 'value': <value>. */
+
+ key = yaml_document_add_scalar(&output_document, NULL,
+ "value", -1, YAML_PLAIN_SCALAR_STYLE);
+ if (!key) goto document_error;
+ value = yaml_document_add_scalar(&output_document, NULL,
+ input_event.data.scalar.value,
+ input_event.data.scalar.length,
+ YAML_DOUBLE_QUOTED_SCALAR_STYLE);
+ if (!value) goto document_error;
+ if (!yaml_document_append_mapping_pair(&output_document,
+ properties, key, value)) goto document_error;
+
+ /* Display if the scalar tag is implicit. */
+
+ /* Add 'implicit': {} */
+
+ key = yaml_document_add_scalar(&output_document, NULL,
+ "version", -1, YAML_PLAIN_SCALAR_STYLE);
+ if (!key) goto document_error;
+ map = yaml_document_add_mapping(&output_document, NULL,
+ YAML_FLOW_MAPPING_STYLE);
+ if (!map) goto document_error;
+ if (!yaml_document_append_mapping_pair(&output_document,
+ properties, key, map)) goto document_error;
+
+ /* Add 'plain': <flag>. */
+
+ key = yaml_document_add_scalar(&output_document, NULL,
+ "plain", -1, YAML_PLAIN_SCALAR_STYLE);
+ if (!key) goto document_error;
+ value = yaml_document_add_scalar(&output_document, YAML_BOOL_TAG,
+ (input_event.data.scalar.plain_implicit ?
+ "true" : "false"), -1, YAML_PLAIN_SCALAR_STYLE);
+ if (!value) goto document_error;
+ if (!yaml_document_append_mapping_pair(&output_document,
+ map, key, value)) goto document_error;
+
+ /* Add 'quoted': <flag>. */
+
+ key = yaml_document_add_scalar(&output_document, NULL,
+ "quoted", -1, YAML_PLAIN_SCALAR_STYLE);
+ if (!key) goto document_error;
+ value = yaml_document_add_scalar(&output_document, YAML_BOOL_TAG,
+ (input_event.data.scalar.quoted_implicit ?
+ "true" : "false"), -1, YAML_PLAIN_SCALAR_STYLE);
+ if (!value) goto document_error;
+ if (!yaml_document_append_mapping_pair(&output_document,
+ map, key, value)) goto document_error;
+
+ /* Display the style information. */
+
+ if (input_event.data.scalar.style)
+ {
+ yaml_scalar_style_t style = input_event.data.scalar.style;
+
+ /* Add 'style': <style>. */
+
+ key = yaml_document_add_scalar(&output_document, NULL,
+ "style", -1, YAML_PLAIN_SCALAR_STYLE);
+ if (!key) goto document_error;
+ value = yaml_document_add_scalar(&output_document, NULL,
+ (style == YAML_PLAIN_SCALAR_STYLE ? "plain" :
+ style == YAML_SINGLE_QUOTED_SCALAR_STYLE ?
+ "single-quoted" :
+ style == YAML_DOUBLE_QUOTED_SCALAR_STYLE ?
+ "double-quoted" :
+ style == YAML_LITERAL_SCALAR_STYLE ? "literal" :
+ style == YAML_FOLDED_SCALAR_STYLE ? "folded" :
+ "unknown"), -1, YAML_PLAIN_SCALAR_STYLE);
+ if (!value) goto document_error;
+ if (!yaml_document_append_mapping_pair(&output_document,
+ properties, key, value)) goto document_error;
+ }
+
+ break;
+
+ case YAML_SEQUENCE_START_EVENT:
+
+ /* Add 'type': 'SEQUENCE-START'. */
+
+ key = yaml_document_add_scalar(&output_document, NULL,
+ "type", -1, YAML_PLAIN_SCALAR_STYLE);
+ if (!key) goto document_error;
+ value = yaml_document_add_scalar(&output_document, NULL,
+ "SEQUENCE-START", -1, YAML_PLAIN_SCALAR_STYLE);
+ if (!value) goto document_error;
+ if (!yaml_document_append_mapping_pair(&output_document,
+ properties, key, value)) goto document_error;
+
+ /* Add 'anchor': <anchor>. */
+
+ if (input_event.data.sequence_start.anchor)
+ {
+ key = yaml_document_add_scalar(&output_document, NULL,
+ "anchor", -1, YAML_PLAIN_SCALAR_STYLE);
+ if (!key) goto document_error;
+ value = yaml_document_add_scalar(&output_document, NULL,
+ input_event.data.sequence_start.anchor, -1,
+ YAML_DOUBLE_QUOTED_SCALAR_STYLE);
+ if (!value) goto document_error;
+ if (!yaml_document_append_mapping_pair(&output_document,
+ properties, key, value)) goto document_error;
+ }
+
+ /* Add 'tag': <tag>. */
+
+ if (input_event.data.sequence_start.tag)
+ {
+ key = yaml_document_add_scalar(&output_document, NULL,
+ "tag", -1, YAML_PLAIN_SCALAR_STYLE);
+ if (!key) goto document_error;
+ value = yaml_document_add_scalar(&output_document, NULL,
+ input_event.data.sequence_start.tag, -1,
+ YAML_DOUBLE_QUOTED_SCALAR_STYLE);
+ if (!value) goto document_error;
+ if (!yaml_document_append_mapping_pair(&output_document,
+ properties, key, value)) goto document_error;
+ }
+
+ /* Add 'implicit': <flag>. */
+
+ key = yaml_document_add_scalar(&output_document, NULL,
+ "implicit", -1, YAML_PLAIN_SCALAR_STYLE);
+ if (!key) goto document_error;
+ value = yaml_document_add_scalar(&output_document, YAML_BOOL_TAG,
+ (input_event.data.sequence_start.implicit ?
+ "true" : "false"), -1, YAML_PLAIN_SCALAR_STYLE);
+ if (!value) goto document_error;
+ if (!yaml_document_append_mapping_pair(&output_document,
+ properties, key, value)) goto document_error;
+
+ /* Display the style information. */
+
+ if (input_event.data.sequence_start.style)
+ {
+ yaml_sequence_style_t style
+ = input_event.data.sequence_start.style;
+
+ /* Add 'style': <style>. */
+
+ key = yaml_document_add_scalar(&output_document, NULL,
+ "style", -1, YAML_PLAIN_SCALAR_STYLE);
+ if (!key) goto document_error;
+ value = yaml_document_add_scalar(&output_document, NULL,
+ (style == YAML_BLOCK_SEQUENCE_STYLE ? "block" :
+ style == YAML_FLOW_SEQUENCE_STYLE ? "flow" :
+ "unknown"), -1, YAML_PLAIN_SCALAR_STYLE);
+ if (!value) goto document_error;
+ if (!yaml_document_append_mapping_pair(&output_document,
+ properties, key, value)) goto document_error;
+ }
+
+ break;
+
+ case YAML_SEQUENCE_END_EVENT:
+
+ /* Add 'type': 'SEQUENCE-END'. */
+
+ key = yaml_document_add_scalar(&output_document, NULL,
+ "type", -1, YAML_PLAIN_SCALAR_STYLE);
+ if (!key) goto document_error;
+ value = yaml_document_add_scalar(&output_document, NULL,
+ "SEQUENCE-END", -1, YAML_PLAIN_SCALAR_STYLE);
+ if (!value) goto document_error;
+ if (!yaml_document_append_mapping_pair(&output_document,
+ properties, key, value)) goto document_error;
+
+ break;
+
+ case YAML_MAPPING_START_EVENT:
+
+ /* Add 'type': 'MAPPING-START'. */
+
+ key = yaml_document_add_scalar(&output_document, NULL,
+ "type", -1, YAML_PLAIN_SCALAR_STYLE);
+ if (!key) goto document_error;
+ value = yaml_document_add_scalar(&output_document, NULL,
+ "MAPPING-START", -1, YAML_PLAIN_SCALAR_STYLE);
+ if (!value) goto document_error;
+ if (!yaml_document_append_mapping_pair(&output_document,
+ properties, key, value)) goto document_error;
+
+ /* Add 'anchor': <anchor>. */
+
+ if (input_event.data.mapping_start.anchor)
+ {
+ key = yaml_document_add_scalar(&output_document, NULL,
+ "anchor", -1, YAML_PLAIN_SCALAR_STYLE);
+ if (!key) goto document_error;
+ value = yaml_document_add_scalar(&output_document, NULL,
+ input_event.data.mapping_start.anchor, -1,
+ YAML_DOUBLE_QUOTED_SCALAR_STYLE);
+ if (!value) goto document_error;
+ if (!yaml_document_append_mapping_pair(&output_document,
+ properties, key, value)) goto document_error;
+ }
+
+ /* Add 'tag': <tag>. */
+
+ if (input_event.data.mapping_start.tag)
+ {
+ key = yaml_document_add_scalar(&output_document, NULL,
+ "tag", -1, YAML_PLAIN_SCALAR_STYLE);
+ if (!key) goto document_error;
+ value = yaml_document_add_scalar(&output_document, NULL,
+ input_event.data.mapping_start.tag, -1,
+ YAML_DOUBLE_QUOTED_SCALAR_STYLE);
+ if (!value) goto document_error;
+ if (!yaml_document_append_mapping_pair(&output_document,
+ properties, key, value)) goto document_error;
+ }
+
+ /* Add 'implicit': <flag>. */
+
+ key = yaml_document_add_scalar(&output_document, NULL,
+ "implicit", -1, YAML_PLAIN_SCALAR_STYLE);
+ if (!key) goto document_error;
+ value = yaml_document_add_scalar(&output_document, YAML_BOOL_TAG,
+ (input_event.data.mapping_start.implicit ?
+ "true" : "false"), -1, YAML_PLAIN_SCALAR_STYLE);
+ if (!value) goto document_error;
+ if (!yaml_document_append_mapping_pair(&output_document,
+ properties, key, value)) goto document_error;
+
+ /* Display the style information. */
+
+ if (input_event.data.sequence_start.style)
+ {
+ yaml_sequence_style_t style
+ = input_event.data.mapping_start.style;
+
+ /* Add 'style': <style>. */
+
+ key = yaml_document_add_scalar(&output_document, NULL,
+ "style", -1, YAML_PLAIN_SCALAR_STYLE);
+ if (!key) goto document_error;
+ value = yaml_document_add_scalar(&output_document, NULL,
+ (style == YAML_BLOCK_MAPPING_STYLE ? "block" :
+ style == YAML_FLOW_MAPPING_STYLE ? "flow" :
+ "unknown"), -1, YAML_PLAIN_SCALAR_STYLE);
+ if (!value) goto document_error;
+ if (!yaml_document_append_mapping_pair(&output_document,
+ properties, key, value)) goto document_error;
+ }
+
+ break;
+
+ case YAML_MAPPING_END_EVENT:
+
+ /* Add 'type': 'MAPPING-END'. */
+
+ key = yaml_document_add_scalar(&output_document, NULL,
+ "type", -1, YAML_PLAIN_SCALAR_STYLE);
+ if (!key) goto document_error;
+ value = yaml_document_add_scalar(&output_document, NULL,
+ "MAPPING-END", -1, YAML_PLAIN_SCALAR_STYLE);
+ if (!value) goto document_error;
+ if (!yaml_document_append_mapping_pair(&output_document,
+ properties, key, value)) goto document_error;
+
+ break;
+
+ default:
+ /* It couldn't really happen. */
+ break;
+ }
+
+ /* Delete the event object. */
+
+ yaml_event_delete(&input_event);
+ }
+
+ if (!yaml_emitter_dump(&emitter, &output_document))
+ goto emitter_error;
+ if (!yaml_emitter_close(&emitter))
+ goto emitter_error;
+
+ yaml_parser_delete(&parser);
+ yaml_emitter_delete(&emitter);
+
+ return 0;
+
+parser_error:
+
+ /* Display a parser error message. */
+
+ switch (parser.error)
+ {
+ case YAML_MEMORY_ERROR:
+ fprintf(stderr, "Memory error: Not enough memory for parsing\n");
+ break;
+
+ case YAML_READER_ERROR:
+ if (parser.problem_value != -1) {
+ fprintf(stderr, "Reader error: %s: #%X at %d\n", parser.problem,
+ parser.problem_value, parser.problem_offset);
+ }
+ else {
+ fprintf(stderr, "Reader error: %s at %d\n", parser.problem,
+ parser.problem_offset);
+ }
+ break;
+
+ case YAML_SCANNER_ERROR:
+ if (parser.context) {
+ fprintf(stderr, "Scanner error: %s at line %d, column %d\n"
+ "%s at line %d, column %d\n", parser.context,
+ parser.context_mark.line+1, parser.context_mark.column+1,
+ parser.problem, parser.problem_mark.line+1,
+ parser.problem_mark.column+1);
+ }
+ else {
+ fprintf(stderr, "Scanner error: %s at line %d, column %d\n",
+ parser.problem, parser.problem_mark.line+1,
+ parser.problem_mark.column+1);
+ }
+ break;
+
+ case YAML_PARSER_ERROR:
+ if (parser.context) {
+ fprintf(stderr, "Parser error: %s at line %d, column %d\n"
+ "%s at line %d, column %d\n", parser.context,
+ parser.context_mark.line+1, parser.context_mark.column+1,
+ parser.problem, parser.problem_mark.line+1,
+ parser.problem_mark.column+1);
+ }
+ else {
+ fprintf(stderr, "Parser error: %s at line %d, column %d\n",
+ parser.problem, parser.problem_mark.line+1,
+ parser.problem_mark.column+1);
+ }
+ break;
+
+ default:
+ /* Couldn't happen. */
+ fprintf(stderr, "Internal error\n");
+ break;
+ }
+
+ yaml_event_delete(&input_event);
+ yaml_document_delete(&output_document);
+ yaml_parser_delete(&parser);
+ yaml_emitter_delete(&emitter);
+
+ return 1;
+
+emitter_error:
+
+ /* Display an emitter error message. */
+
+ switch (emitter.error)
+ {
+ case YAML_MEMORY_ERROR:
+ fprintf(stderr, "Memory error: Not enough memory for emitting\n");
+ break;
+
+ case YAML_WRITER_ERROR:
+ fprintf(stderr, "Writer error: %s\n", emitter.problem);
+ break;
+
+ case YAML_EMITTER_ERROR:
+ fprintf(stderr, "Emitter error: %s\n", emitter.problem);
+ break;
+
+ default:
+ /* Couldn't happen. */
+ fprintf(stderr, "Internal error\n");
+ break;
+ }
+
+ yaml_event_delete(&input_event);
+ yaml_document_delete(&output_document);
+ yaml_parser_delete(&parser);
+ yaml_emitter_delete(&emitter);
+
+ return 1;
+
+document_error:
+
+ fprintf(stderr, "Memory error: Not enough memory for creating a document\n");
+
+ yaml_event_delete(&input_event);
+ yaml_document_delete(&output_document);
+ yaml_parser_delete(&parser);
+ yaml_emitter_delete(&emitter);
+
+ return 1;
+}
+
diff --git a/contrib/libyaml/tests/example-deconstructor.c b/contrib/libyaml/tests/example-deconstructor.c
new file mode 100644
index 0000000..fec7d59
--- /dev/null
+++ b/contrib/libyaml/tests/example-deconstructor.c
@@ -0,0 +1,1130 @@
+
+#include <yaml.h>
+
+#include <stdlib.h>
+#include <stdio.h>
+
+int
+main(int argc, char *argv[])
+{
+ int help = 0;
+ int canonical = 0;
+ int unicode = 0;
+ int k;
+ int done = 0;
+
+ yaml_parser_t parser;
+ yaml_emitter_t emitter;
+ yaml_event_t input_event;
+ yaml_event_t output_event;
+
+ /* Clear the objects. */
+
+ memset(&parser, 0, sizeof(parser));
+ memset(&emitter, 0, sizeof(emitter));
+ memset(&input_event, 0, sizeof(input_event));
+ memset(&output_event, 0, sizeof(output_event));
+
+ /* Analyze command line options. */
+
+ for (k = 1; k < argc; k ++)
+ {
+ if (strcmp(argv[k], "-h") == 0
+ || strcmp(argv[k], "--help") == 0) {
+ help = 1;
+ }
+
+ else if (strcmp(argv[k], "-c") == 0
+ || strcmp(argv[k], "--canonical") == 0) {
+ canonical = 1;
+ }
+
+ else if (strcmp(argv[k], "-u") == 0
+ || strcmp(argv[k], "--unicode") == 0) {
+ unicode = 1;
+ }
+
+ else {
+ fprintf(stderr, "Unrecognized option: %s\n"
+ "Try `%s --help` for more information.\n",
+ argv[k], argv[0]);
+ return 1;
+ }
+ }
+
+ /* Display the help string. */
+
+ if (help)
+ {
+ printf("%s <input\n"
+ "or\n%s -h | --help\nDeconstruct a YAML stream\n\nOptions:\n"
+ "-h, --help\t\tdisplay this help and exit\n"
+ "-c, --canonical\t\toutput in the canonical YAML format\n"
+ "-u, --unicode\t\toutput unescaped non-ASCII characters\n",
+ argv[0], argv[0]);
+ return 0;
+ }
+
+ /* Initialize the parser and emitter objects. */
+
+ if (!yaml_parser_initialize(&parser)) {
+ fprintf(stderr, "Could not initialize the parser object\n");
+ return 1;
+ }
+
+ if (!yaml_emitter_initialize(&emitter)) {
+ yaml_parser_delete(&parser);
+ fprintf(stderr, "Could not inialize the emitter object\n");
+ return 1;
+ }
+
+ /* Set the parser parameters. */
+
+ yaml_parser_set_input_file(&parser, stdin);
+
+ /* Set the emitter parameters. */
+
+ yaml_emitter_set_output_file(&emitter, stdout);
+
+ yaml_emitter_set_canonical(&emitter, canonical);
+ yaml_emitter_set_unicode(&emitter, unicode);
+
+ /* Create and emit the STREAM-START event. */
+
+ if (!yaml_stream_start_event_initialize(&output_event, YAML_UTF8_ENCODING))
+ goto event_error;
+ if (!yaml_emitter_emit(&emitter, &output_event))
+ goto emitter_error;
+
+ /* Create and emit the DOCUMENT-START event. */
+
+ if (!yaml_document_start_event_initialize(&output_event,
+ NULL, NULL, NULL, 0))
+ goto event_error;
+ if (!yaml_emitter_emit(&emitter, &output_event))
+ goto emitter_error;
+
+ /* Create and emit the SEQUENCE-START event. */
+
+ if (!yaml_sequence_start_event_initialize(&output_event,
+ NULL, "tag:yaml.org,2002:seq", 1,
+ YAML_BLOCK_SEQUENCE_STYLE))
+ goto event_error;
+ if (!yaml_emitter_emit(&emitter, &output_event))
+ goto emitter_error;
+
+ /* Loop through the input events. */
+
+ while (!done)
+ {
+ /* Get the next event. */
+
+ if (!yaml_parser_parse(&parser, &input_event))
+ goto parser_error;
+
+ /* Check if this is the stream end. */
+
+ if (input_event.type == YAML_STREAM_END_EVENT) {
+ done = 1;
+ }
+
+ /* Create and emit a MAPPING-START event. */
+
+ if (!yaml_mapping_start_event_initialize(&output_event,
+ NULL, "tag:yaml.org,2002:map", 1,
+ YAML_BLOCK_MAPPING_STYLE))
+ goto event_error;
+ if (!yaml_emitter_emit(&emitter, &output_event))
+ goto emitter_error;
+
+ /* Analyze the event. */
+
+ switch (input_event.type)
+ {
+ case YAML_STREAM_START_EVENT:
+
+ /* Write 'type'. */
+
+ if (!yaml_scalar_event_initialize(&output_event,
+ NULL, "tag:yaml.org,2002:str", "type", -1,
+ 1, 1, YAML_PLAIN_SCALAR_STYLE))
+ goto event_error;
+ if (!yaml_emitter_emit(&emitter, &output_event))
+ goto emitter_error;
+
+ /* Write 'STREAM-START'. */
+
+ if (!yaml_scalar_event_initialize(&output_event,
+ NULL, "tag:yaml.org,2002:str", "STREAM-START", -1,
+ 1, 1, YAML_PLAIN_SCALAR_STYLE))
+ goto event_error;
+ if (!yaml_emitter_emit(&emitter, &output_event))
+ goto emitter_error;
+
+ /* Display encoding information. */
+
+ if (input_event.data.stream_start.encoding)
+ {
+ yaml_encoding_t encoding
+ = input_event.data.stream_start.encoding;
+
+ /* Write 'encoding'. */
+
+ if (!yaml_scalar_event_initialize(&output_event,
+ NULL, "tag:yaml.org,2002:str", "encoding", -1,
+ 1, 1, YAML_PLAIN_SCALAR_STYLE))
+ goto event_error;
+ if (!yaml_emitter_emit(&emitter, &output_event))
+ goto emitter_error;
+
+ /* Write the stream encoding. */
+
+ if (!yaml_scalar_event_initialize(&output_event,
+ NULL, "tag:yaml.org,2002:str",
+ (encoding == YAML_UTF8_ENCODING ? "utf-8" :
+ encoding == YAML_UTF16LE_ENCODING ? "utf-16-le" :
+ encoding == YAML_UTF16BE_ENCODING ? "utf-16-be" :
+ "unknown"), -1,
+ 1, 1, YAML_PLAIN_SCALAR_STYLE))
+ goto event_error;
+ if (!yaml_emitter_emit(&emitter, &output_event))
+ goto emitter_error;
+ }
+
+ break;
+
+ case YAML_STREAM_END_EVENT:
+
+ /* Write 'type'. */
+
+ if (!yaml_scalar_event_initialize(&output_event,
+ NULL, "tag:yaml.org,2002:str", "type", -1,
+ 1, 1, YAML_PLAIN_SCALAR_STYLE))
+ goto event_error;
+ if (!yaml_emitter_emit(&emitter, &output_event))
+ goto emitter_error;
+
+ /* Write 'STREAM-END'. */
+
+ if (!yaml_scalar_event_initialize(&output_event,
+ NULL, "tag:yaml.org,2002:str", "STREAM-END", -1,
+ 1, 1, YAML_PLAIN_SCALAR_STYLE))
+ goto event_error;
+ if (!yaml_emitter_emit(&emitter, &output_event))
+ goto emitter_error;
+
+ break;
+
+ case YAML_DOCUMENT_START_EVENT:
+
+ /* Write 'type'. */
+
+ if (!yaml_scalar_event_initialize(&output_event,
+ NULL, "tag:yaml.org,2002:str", "type", -1,
+ 1, 1, YAML_PLAIN_SCALAR_STYLE))
+ goto event_error;
+ if (!yaml_emitter_emit(&emitter, &output_event))
+ goto emitter_error;
+
+ /* Write 'DOCUMENT-START'. */
+
+ if (!yaml_scalar_event_initialize(&output_event,
+ NULL, "tag:yaml.org,2002:str", "DOCUMENT-START", -1,
+ 1, 1, YAML_PLAIN_SCALAR_STYLE))
+ goto event_error;
+ if (!yaml_emitter_emit(&emitter, &output_event))
+ goto emitter_error;
+
+ /* Display the document version numbers. */
+
+ if (input_event.data.document_start.version_directive)
+ {
+ yaml_version_directive_t *version
+ = input_event.data.document_start.version_directive;
+ char number[64];
+
+ /* Write 'version'. */
+
+ if (!yaml_scalar_event_initialize(&output_event,
+ NULL, "tag:yaml.org,2002:str", "version", -1,
+ 1, 1, YAML_PLAIN_SCALAR_STYLE))
+ goto event_error;
+ if (!yaml_emitter_emit(&emitter, &output_event))
+ goto emitter_error;
+
+ /* Write '{'. */
+
+ if (!yaml_mapping_start_event_initialize(&output_event,
+ NULL, "tag:yaml.org,2002:map", 1,
+ YAML_FLOW_MAPPING_STYLE))
+ goto event_error;
+ if (!yaml_emitter_emit(&emitter, &output_event))
+ goto emitter_error;
+
+ /* Write 'major'. */
+
+ if (!yaml_scalar_event_initialize(&output_event,
+ NULL, "tag:yaml.org,2002:str", "major", -1,
+ 1, 1, YAML_PLAIN_SCALAR_STYLE))
+ goto event_error;
+ if (!yaml_emitter_emit(&emitter, &output_event))
+ goto emitter_error;
+
+ /* Write a number. */
+
+ sprintf(number, "%d", version->major);
+ if (!yaml_scalar_event_initialize(&output_event,
+ NULL, "tag:yaml.org,2002:int", number, -1,
+ 1, 1, YAML_PLAIN_SCALAR_STYLE))
+ goto event_error;
+ if (!yaml_emitter_emit(&emitter, &output_event))
+ goto emitter_error;
+
+ /* Write 'minor'. */
+
+ if (!yaml_scalar_event_initialize(&output_event,
+ NULL, "tag:yaml.org,2002:str", "minor", -1,
+ 1, 1, YAML_PLAIN_SCALAR_STYLE))
+ goto event_error;
+ if (!yaml_emitter_emit(&emitter, &output_event))
+ goto emitter_error;
+
+ /* Write a number. */
+
+ sprintf(number, "%d", version->minor);
+ if (!yaml_scalar_event_initialize(&output_event,
+ NULL, "tag:yaml.org,2002:int", number, -1,
+ 1, 1, YAML_PLAIN_SCALAR_STYLE))
+ goto event_error;
+ if (!yaml_emitter_emit(&emitter, &output_event))
+ goto emitter_error;
+
+ /* Write '}'. */
+
+ if (!yaml_mapping_end_event_initialize(&output_event))
+ goto event_error;
+ if (!yaml_emitter_emit(&emitter, &output_event))
+ goto emitter_error;
+ }
+
+ /* Display the document tag directives. */
+
+ if (input_event.data.document_start.tag_directives.start
+ != input_event.data.document_start.tag_directives.end)
+ {
+ yaml_tag_directive_t *tag;
+
+ /* Write 'tags'. */
+
+ if (!yaml_scalar_event_initialize(&output_event,
+ NULL, "tag:yaml.org,2002:str", "tags", -1,
+ 1, 1, YAML_PLAIN_SCALAR_STYLE))
+ goto event_error;
+ if (!yaml_emitter_emit(&emitter, &output_event))
+ goto emitter_error;
+
+ /* Start a block sequence. */
+
+ if (!yaml_sequence_start_event_initialize(&output_event,
+ NULL, "tag:yaml.org,2002:seq", 1,
+ YAML_BLOCK_SEQUENCE_STYLE))
+ goto event_error;
+ if (!yaml_emitter_emit(&emitter, &output_event))
+ goto emitter_error;
+
+ for (tag = input_event.data.document_start.tag_directives.start;
+ tag != input_event.data.document_start.tag_directives.end;
+ tag ++)
+ {
+ /* Write '{'. */
+
+ if (!yaml_mapping_start_event_initialize(&output_event,
+ NULL, "tag:yaml.org,2002:map", 1,
+ YAML_FLOW_MAPPING_STYLE))
+ goto event_error;
+ if (!yaml_emitter_emit(&emitter, &output_event))
+ goto emitter_error;
+
+ /* Write 'handle'. */
+
+ if (!yaml_scalar_event_initialize(&output_event,
+ NULL, "tag:yaml.org,2002:str", "handle", -1,
+ 1, 1, YAML_PLAIN_SCALAR_STYLE))
+ goto event_error;
+ if (!yaml_emitter_emit(&emitter, &output_event))
+ goto emitter_error;
+
+ /* Write the tag directive handle. */
+
+ if (!yaml_scalar_event_initialize(&output_event,
+ NULL, "tag:yaml.org,2002:str",
+ tag->handle, -1,
+ 0, 1, YAML_DOUBLE_QUOTED_SCALAR_STYLE))
+ goto event_error;
+ if (!yaml_emitter_emit(&emitter, &output_event))
+ goto emitter_error;
+
+ /* Write 'prefix'. */
+
+ if (!yaml_scalar_event_initialize(&output_event,
+ NULL, "tag:yaml.org,2002:str", "prefix", -1,
+ 1, 1, YAML_PLAIN_SCALAR_STYLE))
+ goto event_error;
+ if (!yaml_emitter_emit(&emitter, &output_event))
+ goto emitter_error;
+
+ /* Write the tag directive prefix. */
+
+ if (!yaml_scalar_event_initialize(&output_event,
+ NULL, "tag:yaml.org,2002:str",
+ tag->prefix, -1,
+ 0, 1, YAML_DOUBLE_QUOTED_SCALAR_STYLE))
+ goto event_error;
+ if (!yaml_emitter_emit(&emitter, &output_event))
+ goto emitter_error;
+
+ /* Write '}'. */
+
+ if (!yaml_mapping_end_event_initialize(&output_event))
+ goto event_error;
+ if (!yaml_emitter_emit(&emitter, &output_event))
+ goto emitter_error;
+ }
+
+ /* End a block sequence. */
+
+ if (!yaml_sequence_end_event_initialize(&output_event))
+ goto event_error;
+ if (!yaml_emitter_emit(&emitter, &output_event))
+ goto emitter_error;
+ }
+
+ /* Write 'implicit'. */
+
+ if (!yaml_scalar_event_initialize(&output_event,
+ NULL, "tag:yaml.org,2002:str", "implicit", -1,
+ 1, 1, YAML_PLAIN_SCALAR_STYLE))
+ goto event_error;
+ if (!yaml_emitter_emit(&emitter, &output_event))
+ goto emitter_error;
+
+ /* Write if the document is implicit. */
+
+ if (!yaml_scalar_event_initialize(&output_event,
+ NULL, "tag:yaml.org,2002:bool",
+ (input_event.data.document_start.implicit ?
+ "true" : "false"), -1,
+ 1, 0, YAML_PLAIN_SCALAR_STYLE))
+ goto event_error;
+ if (!yaml_emitter_emit(&emitter, &output_event))
+ goto emitter_error;
+
+ break;
+
+ case YAML_DOCUMENT_END_EVENT:
+
+ /* Write 'type'. */
+
+ if (!yaml_scalar_event_initialize(&output_event,
+ NULL, "tag:yaml.org,2002:str", "type", -1,
+ 1, 1, YAML_PLAIN_SCALAR_STYLE))
+ goto event_error;
+ if (!yaml_emitter_emit(&emitter, &output_event))
+ goto emitter_error;
+
+ /* Write 'DOCUMENT-END'. */
+
+ if (!yaml_scalar_event_initialize(&output_event,
+ NULL, "tag:yaml.org,2002:str", "DOCUMENT-END", -1,
+ 1, 1, YAML_PLAIN_SCALAR_STYLE))
+ goto event_error;
+ if (!yaml_emitter_emit(&emitter, &output_event))
+ goto emitter_error;
+
+ /* Write 'implicit'. */
+
+ if (!yaml_scalar_event_initialize(&output_event,
+ NULL, "tag:yaml.org,2002:str", "implicit", -1,
+ 1, 1, YAML_PLAIN_SCALAR_STYLE))
+ goto event_error;
+ if (!yaml_emitter_emit(&emitter, &output_event))
+ goto emitter_error;
+
+ /* Write if the document is implicit. */
+
+ if (!yaml_scalar_event_initialize(&output_event,
+ NULL, "tag:yaml.org,2002:bool",
+ (input_event.data.document_end.implicit ?
+ "true" : "false"), -1,
+ 1, 0, YAML_PLAIN_SCALAR_STYLE))
+ goto event_error;
+ if (!yaml_emitter_emit(&emitter, &output_event))
+ goto emitter_error;
+
+ break;
+
+ case YAML_ALIAS_EVENT:
+
+ /* Write 'type'. */
+
+ if (!yaml_scalar_event_initialize(&output_event,
+ NULL, "tag:yaml.org,2002:str", "type", -1,
+ 1, 1, YAML_PLAIN_SCALAR_STYLE))
+ goto event_error;
+ if (!yaml_emitter_emit(&emitter, &output_event))
+ goto emitter_error;
+
+ /* Write 'ALIAS'. */
+
+ if (!yaml_scalar_event_initialize(&output_event,
+ NULL, "tag:yaml.org,2002:str", "ALIAS", -1,
+ 1, 1, YAML_PLAIN_SCALAR_STYLE))
+ goto event_error;
+ if (!yaml_emitter_emit(&emitter, &output_event))
+ goto emitter_error;
+
+ /* Write 'anchor'. */
+
+ if (!yaml_scalar_event_initialize(&output_event,
+ NULL, "tag:yaml.org,2002:str", "anchor", -1,
+ 1, 1, YAML_PLAIN_SCALAR_STYLE))
+ goto event_error;
+ if (!yaml_emitter_emit(&emitter, &output_event))
+ goto emitter_error;
+
+ /* Write the alias anchor. */
+
+ if (!yaml_scalar_event_initialize(&output_event,
+ NULL, "tag:yaml.org,2002:str",
+ input_event.data.alias.anchor, -1,
+ 0, 1, YAML_DOUBLE_QUOTED_SCALAR_STYLE))
+ goto event_error;
+ if (!yaml_emitter_emit(&emitter, &output_event))
+ goto emitter_error;
+
+ break;
+
+ case YAML_SCALAR_EVENT:
+
+ /* Write 'type'. */
+
+ if (!yaml_scalar_event_initialize(&output_event,
+ NULL, "tag:yaml.org,2002:str", "type", -1,
+ 1, 1, YAML_PLAIN_SCALAR_STYLE))
+ goto event_error;
+ if (!yaml_emitter_emit(&emitter, &output_event))
+ goto emitter_error;
+
+ /* Write 'SCALAR'. */
+
+ if (!yaml_scalar_event_initialize(&output_event,
+ NULL, "tag:yaml.org,2002:str", "SCALAR", -1,
+ 1, 1, YAML_PLAIN_SCALAR_STYLE))
+ goto event_error;
+ if (!yaml_emitter_emit(&emitter, &output_event))
+ goto emitter_error;
+
+ /* Display the scalar anchor. */
+
+ if (input_event.data.scalar.anchor)
+ {
+ /* Write 'anchor'. */
+
+ if (!yaml_scalar_event_initialize(&output_event,
+ NULL, "tag:yaml.org,2002:str", "anchor", -1,
+ 1, 1, YAML_PLAIN_SCALAR_STYLE))
+ goto event_error;
+ if (!yaml_emitter_emit(&emitter, &output_event))
+ goto emitter_error;
+
+ /* Write the scalar anchor. */
+
+ if (!yaml_scalar_event_initialize(&output_event,
+ NULL, "tag:yaml.org,2002:str",
+ input_event.data.scalar.anchor, -1,
+ 0, 1, YAML_DOUBLE_QUOTED_SCALAR_STYLE))
+ goto event_error;
+ if (!yaml_emitter_emit(&emitter, &output_event))
+ goto emitter_error;
+ }
+
+ /* Display the scalar tag. */
+
+ if (input_event.data.scalar.tag)
+ {
+ /* Write 'tag'. */
+
+ if (!yaml_scalar_event_initialize(&output_event,
+ NULL, "tag:yaml.org,2002:str", "tag", -1,
+ 1, 1, YAML_PLAIN_SCALAR_STYLE))
+ goto event_error;
+ if (!yaml_emitter_emit(&emitter, &output_event))
+ goto emitter_error;
+
+ /* Write the scalar tag. */
+
+ if (!yaml_scalar_event_initialize(&output_event,
+ NULL, "tag:yaml.org,2002:str",
+ input_event.data.scalar.tag, -1,
+ 0, 1, YAML_DOUBLE_QUOTED_SCALAR_STYLE))
+ goto event_error;
+ if (!yaml_emitter_emit(&emitter, &output_event))
+ goto emitter_error;
+ }
+
+ /* Display the scalar value. */
+
+ /* Write 'value'. */
+
+ if (!yaml_scalar_event_initialize(&output_event,
+ NULL, "tag:yaml.org,2002:str", "value", -1,
+ 1, 1, YAML_PLAIN_SCALAR_STYLE))
+ goto event_error;
+ if (!yaml_emitter_emit(&emitter, &output_event))
+ goto emitter_error;
+
+ /* Write the scalar value. */
+
+ if (!yaml_scalar_event_initialize(&output_event,
+ NULL, "tag:yaml.org,2002:str",
+ input_event.data.scalar.value,
+ input_event.data.scalar.length,
+ 0, 1, YAML_DOUBLE_QUOTED_SCALAR_STYLE))
+ goto event_error;
+ if (!yaml_emitter_emit(&emitter, &output_event))
+ goto emitter_error;
+
+ /* Display if the scalar tag is implicit. */
+
+ /* Write 'implicit'. */
+
+ if (!yaml_scalar_event_initialize(&output_event,
+ NULL, "tag:yaml.org,2002:str", "implicit", -1,
+ 1, 1, YAML_PLAIN_SCALAR_STYLE))
+ goto event_error;
+ if (!yaml_emitter_emit(&emitter, &output_event))
+ goto emitter_error;
+
+ /* Write '{'. */
+
+ if (!yaml_mapping_start_event_initialize(&output_event,
+ NULL, "tag:yaml.org,2002:map", 1,
+ YAML_FLOW_MAPPING_STYLE))
+ goto event_error;
+ if (!yaml_emitter_emit(&emitter, &output_event))
+ goto emitter_error;
+
+ /* Write 'plain'. */
+
+ if (!yaml_scalar_event_initialize(&output_event,
+ NULL, "tag:yaml.org,2002:str", "plain", -1,
+ 1, 1, YAML_PLAIN_SCALAR_STYLE))
+ goto event_error;
+ if (!yaml_emitter_emit(&emitter, &output_event))
+ goto emitter_error;
+
+ /* Write if the scalar is implicit in the plain style. */
+
+ if (!yaml_scalar_event_initialize(&output_event,
+ NULL, "tag:yaml.org,2002:bool",
+ (input_event.data.scalar.plain_implicit ?
+ "true" : "false"), -1,
+ 1, 0, YAML_PLAIN_SCALAR_STYLE))
+ goto event_error;
+ if (!yaml_emitter_emit(&emitter, &output_event))
+ goto emitter_error;
+
+ /* Write 'quoted'. */
+
+ if (!yaml_scalar_event_initialize(&output_event,
+ NULL, "tag:yaml.org,2002:str", "non-plain", -1,
+ 1, 1, YAML_PLAIN_SCALAR_STYLE))
+ goto event_error;
+ if (!yaml_emitter_emit(&emitter, &output_event))
+ goto emitter_error;
+
+ /* Write if the scalar is implicit in a non-plain style. */
+
+ if (!yaml_scalar_event_initialize(&output_event,
+ NULL, "tag:yaml.org,2002:bool",
+ (input_event.data.scalar.quoted_implicit ?
+ "true" : "false"), -1,
+ 1, 0, YAML_PLAIN_SCALAR_STYLE))
+ goto event_error;
+ if (!yaml_emitter_emit(&emitter, &output_event))
+ goto emitter_error;
+
+ /* Write '}'. */
+
+ if (!yaml_mapping_end_event_initialize(&output_event))
+ goto event_error;
+ if (!yaml_emitter_emit(&emitter, &output_event))
+ goto emitter_error;
+
+ /* Display the style information. */
+
+ if (input_event.data.scalar.style)
+ {
+ yaml_scalar_style_t style = input_event.data.scalar.style;
+
+ /* Write 'style'. */
+
+ if (!yaml_scalar_event_initialize(&output_event,
+ NULL, "tag:yaml.org,2002:str", "style", -1,
+ 1, 1, YAML_PLAIN_SCALAR_STYLE))
+ goto event_error;
+ if (!yaml_emitter_emit(&emitter, &output_event))
+ goto emitter_error;
+
+ /* Write the scalar style. */
+
+ if (!yaml_scalar_event_initialize(&output_event,
+ NULL, "tag:yaml.org,2002:str",
+ (style == YAML_PLAIN_SCALAR_STYLE ? "plain" :
+ style == YAML_SINGLE_QUOTED_SCALAR_STYLE ?
+ "single-quoted" :
+ style == YAML_DOUBLE_QUOTED_SCALAR_STYLE ?
+ "double-quoted" :
+ style == YAML_LITERAL_SCALAR_STYLE ? "literal" :
+ style == YAML_FOLDED_SCALAR_STYLE ? "folded" :
+ "unknown"), -1,
+ 1, 1, YAML_PLAIN_SCALAR_STYLE))
+ goto event_error;
+ if (!yaml_emitter_emit(&emitter, &output_event))
+ goto emitter_error;
+ }
+
+ break;
+
+ case YAML_SEQUENCE_START_EVENT:
+
+ /* Write 'type'. */
+
+ if (!yaml_scalar_event_initialize(&output_event,
+ NULL, "tag:yaml.org,2002:str", "type", -1,
+ 1, 1, YAML_PLAIN_SCALAR_STYLE))
+ goto event_error;
+ if (!yaml_emitter_emit(&emitter, &output_event))
+ goto emitter_error;
+
+ /* Write 'SEQUENCE-START'. */
+
+ if (!yaml_scalar_event_initialize(&output_event,
+ NULL, "tag:yaml.org,2002:str", "SEQUENCE-START", -1,
+ 1, 1, YAML_PLAIN_SCALAR_STYLE))
+ goto event_error;
+ if (!yaml_emitter_emit(&emitter, &output_event))
+ goto emitter_error;
+
+ /* Display the sequence anchor. */
+
+ if (input_event.data.sequence_start.anchor)
+ {
+ /* Write 'anchor'. */
+
+ if (!yaml_scalar_event_initialize(&output_event,
+ NULL, "tag:yaml.org,2002:str", "anchor", -1,
+ 1, 1, YAML_PLAIN_SCALAR_STYLE))
+ goto event_error;
+ if (!yaml_emitter_emit(&emitter, &output_event))
+ goto emitter_error;
+
+ /* Write the sequence anchor. */
+
+ if (!yaml_scalar_event_initialize(&output_event,
+ NULL, "tag:yaml.org,2002:str",
+ input_event.data.sequence_start.anchor, -1,
+ 0, 1, YAML_DOUBLE_QUOTED_SCALAR_STYLE))
+ goto event_error;
+ if (!yaml_emitter_emit(&emitter, &output_event))
+ goto emitter_error;
+ }
+
+ /* Display the sequence tag. */
+
+ if (input_event.data.sequence_start.tag)
+ {
+ /* Write 'tag'. */
+
+ if (!yaml_scalar_event_initialize(&output_event,
+ NULL, "tag:yaml.org,2002:str", "tag", -1,
+ 1, 1, YAML_PLAIN_SCALAR_STYLE))
+ goto event_error;
+ if (!yaml_emitter_emit(&emitter, &output_event))
+ goto emitter_error;
+
+ /* Write the sequence tag. */
+
+ if (!yaml_scalar_event_initialize(&output_event,
+ NULL, "tag:yaml.org,2002:str",
+ input_event.data.sequence_start.tag, -1,
+ 0, 1, YAML_DOUBLE_QUOTED_SCALAR_STYLE))
+ goto event_error;
+ if (!yaml_emitter_emit(&emitter, &output_event))
+ goto emitter_error;
+ }
+
+ /* Write 'implicit'. */
+
+ if (!yaml_scalar_event_initialize(&output_event,
+ NULL, "tag:yaml.org,2002:str", "implicit", -1,
+ 1, 1, YAML_PLAIN_SCALAR_STYLE))
+ goto event_error;
+ if (!yaml_emitter_emit(&emitter, &output_event))
+ goto emitter_error;
+
+ /* Write if the sequence tag is implicit. */
+
+ if (!yaml_scalar_event_initialize(&output_event,
+ NULL, "tag:yaml.org,2002:bool",
+ (input_event.data.sequence_start.implicit ?
+ "true" : "false"), -1,
+ 1, 0, YAML_PLAIN_SCALAR_STYLE))
+ goto event_error;
+ if (!yaml_emitter_emit(&emitter, &output_event))
+ goto emitter_error;
+
+ /* Display the style information. */
+
+ if (input_event.data.sequence_start.style)
+ {
+ yaml_sequence_style_t style
+ = input_event.data.sequence_start.style;
+
+ /* Write 'style'. */
+
+ if (!yaml_scalar_event_initialize(&output_event,
+ NULL, "tag:yaml.org,2002:str", "style", -1,
+ 1, 1, YAML_PLAIN_SCALAR_STYLE))
+ goto event_error;
+ if (!yaml_emitter_emit(&emitter, &output_event))
+ goto emitter_error;
+
+ /* Write the scalar style. */
+
+ if (!yaml_scalar_event_initialize(&output_event,
+ NULL, "tag:yaml.org,2002:str",
+ (style == YAML_BLOCK_SEQUENCE_STYLE ? "block" :
+ style == YAML_FLOW_SEQUENCE_STYLE ? "flow" :
+ "unknown"), -1,
+ 1, 1, YAML_PLAIN_SCALAR_STYLE))
+ goto event_error;
+ if (!yaml_emitter_emit(&emitter, &output_event))
+ goto emitter_error;
+ }
+
+ break;
+
+ case YAML_SEQUENCE_END_EVENT:
+
+ /* Write 'type'. */
+
+ if (!yaml_scalar_event_initialize(&output_event,
+ NULL, "tag:yaml.org,2002:str", "type", -1,
+ 1, 1, YAML_PLAIN_SCALAR_STYLE))
+ goto event_error;
+ if (!yaml_emitter_emit(&emitter, &output_event))
+ goto emitter_error;
+
+ /* Write 'SEQUENCE-END'. */
+
+ if (!yaml_scalar_event_initialize(&output_event,
+ NULL, "tag:yaml.org,2002:str", "SEQUENCE-END", -1,
+ 1, 1, YAML_PLAIN_SCALAR_STYLE))
+ goto event_error;
+ if (!yaml_emitter_emit(&emitter, &output_event))
+ goto emitter_error;
+
+ break;
+
+ case YAML_MAPPING_START_EVENT:
+
+ /* Write 'type'. */
+
+ if (!yaml_scalar_event_initialize(&output_event,
+ NULL, "tag:yaml.org,2002:str", "type", -1,
+ 1, 1, YAML_PLAIN_SCALAR_STYLE))
+ goto event_error;
+ if (!yaml_emitter_emit(&emitter, &output_event))
+ goto emitter_error;
+
+ /* Write 'MAPPING-START'. */
+
+ if (!yaml_scalar_event_initialize(&output_event,
+ NULL, "tag:yaml.org,2002:str", "MAPPING-START", -1,
+ 1, 1, YAML_PLAIN_SCALAR_STYLE))
+ goto event_error;
+ if (!yaml_emitter_emit(&emitter, &output_event))
+ goto emitter_error;
+
+ /* Display the mapping anchor. */
+
+ if (input_event.data.mapping_start.anchor)
+ {
+ /* Write 'anchor'. */
+
+ if (!yaml_scalar_event_initialize(&output_event,
+ NULL, "tag:yaml.org,2002:str", "anchor", -1,
+ 1, 1, YAML_PLAIN_SCALAR_STYLE))
+ goto event_error;
+ if (!yaml_emitter_emit(&emitter, &output_event))
+ goto emitter_error;
+
+ /* Write the mapping anchor. */
+
+ if (!yaml_scalar_event_initialize(&output_event,
+ NULL, "tag:yaml.org,2002:str",
+ input_event.data.mapping_start.anchor, -1,
+ 0, 1, YAML_DOUBLE_QUOTED_SCALAR_STYLE))
+ goto event_error;
+ if (!yaml_emitter_emit(&emitter, &output_event))
+ goto emitter_error;
+ }
+
+ /* Display the mapping tag. */
+
+ if (input_event.data.mapping_start.tag)
+ {
+ /* Write 'tag'. */
+
+ if (!yaml_scalar_event_initialize(&output_event,
+ NULL, "tag:yaml.org,2002:str", "tag", -1,
+ 1, 1, YAML_PLAIN_SCALAR_STYLE))
+ goto event_error;
+ if (!yaml_emitter_emit(&emitter, &output_event))
+ goto emitter_error;
+
+ /* Write the mapping tag. */
+
+ if (!yaml_scalar_event_initialize(&output_event,
+ NULL, "tag:yaml.org,2002:str",
+ input_event.data.mapping_start.tag, -1,
+ 0, 1, YAML_DOUBLE_QUOTED_SCALAR_STYLE))
+ goto event_error;
+ if (!yaml_emitter_emit(&emitter, &output_event))
+ goto emitter_error;
+ }
+
+ /* Write 'implicit'. */
+
+ if (!yaml_scalar_event_initialize(&output_event,
+ NULL, "tag:yaml.org,2002:str", "implicit", -1,
+ 1, 1, YAML_PLAIN_SCALAR_STYLE))
+ goto event_error;
+ if (!yaml_emitter_emit(&emitter, &output_event))
+ goto emitter_error;
+
+ /* Write if the mapping tag is implicit. */
+
+ if (!yaml_scalar_event_initialize(&output_event,
+ NULL, "tag:yaml.org,2002:bool",
+ (input_event.data.mapping_start.implicit ?
+ "true" : "false"), -1,
+ 1, 0, YAML_PLAIN_SCALAR_STYLE))
+ goto event_error;
+ if (!yaml_emitter_emit(&emitter, &output_event))
+ goto emitter_error;
+
+ /* Display the style information. */
+
+ if (input_event.data.mapping_start.style)
+ {
+ yaml_mapping_style_t style
+ = input_event.data.mapping_start.style;
+
+ /* Write 'style'. */
+
+ if (!yaml_scalar_event_initialize(&output_event,
+ NULL, "tag:yaml.org,2002:str", "style", -1,
+ 1, 1, YAML_PLAIN_SCALAR_STYLE))
+ goto event_error;
+ if (!yaml_emitter_emit(&emitter, &output_event))
+ goto emitter_error;
+
+ /* Write the scalar style. */
+
+ if (!yaml_scalar_event_initialize(&output_event,
+ NULL, "tag:yaml.org,2002:str",
+ (style == YAML_BLOCK_MAPPING_STYLE ? "block" :
+ style == YAML_FLOW_MAPPING_STYLE ? "flow" :
+ "unknown"), -1,
+ 1, 1, YAML_PLAIN_SCALAR_STYLE))
+ goto event_error;
+ if (!yaml_emitter_emit(&emitter, &output_event))
+ goto emitter_error;
+ }
+
+ break;
+
+ case YAML_MAPPING_END_EVENT:
+
+ /* Write 'type'. */
+
+ if (!yaml_scalar_event_initialize(&output_event,
+ NULL, "tag:yaml.org,2002:str", "type", -1,
+ 1, 1, YAML_PLAIN_SCALAR_STYLE))
+ goto event_error;
+ if (!yaml_emitter_emit(&emitter, &output_event))
+ goto emitter_error;
+
+ /* Write 'MAPPING-END'. */
+
+ if (!yaml_scalar_event_initialize(&output_event,
+ NULL, "tag:yaml.org,2002:str", "MAPPING-END", -1,
+ 1, 1, YAML_PLAIN_SCALAR_STYLE))
+ goto event_error;
+ if (!yaml_emitter_emit(&emitter, &output_event))
+ goto emitter_error;
+
+ break;
+
+ default:
+ /* It couldn't really happen. */
+ break;
+ }
+
+ /* Delete the event object. */
+
+ yaml_event_delete(&input_event);
+
+ /* Create and emit a MAPPING-END event. */
+
+ if (!yaml_mapping_end_event_initialize(&output_event))
+ goto event_error;
+ if (!yaml_emitter_emit(&emitter, &output_event))
+ goto emitter_error;
+ }
+
+ /* Create and emit the SEQUENCE-END event. */
+
+ if (!yaml_sequence_end_event_initialize(&output_event))
+ goto event_error;
+ if (!yaml_emitter_emit(&emitter, &output_event))
+ goto emitter_error;
+
+ /* Create and emit the DOCUMENT-END event. */
+
+ if (!yaml_document_end_event_initialize(&output_event, 0))
+ goto event_error;
+ if (!yaml_emitter_emit(&emitter, &output_event))
+ goto emitter_error;
+
+ /* Create and emit the STREAM-END event. */
+
+ if (!yaml_stream_end_event_initialize(&output_event))
+ goto event_error;
+ if (!yaml_emitter_emit(&emitter, &output_event))
+ goto emitter_error;
+
+ yaml_parser_delete(&parser);
+ yaml_emitter_delete(&emitter);
+
+ return 0;
+
+parser_error:
+
+ /* Display a parser error message. */
+
+ switch (parser.error)
+ {
+ case YAML_MEMORY_ERROR:
+ fprintf(stderr, "Memory error: Not enough memory for parsing\n");
+ break;
+
+ case YAML_READER_ERROR:
+ if (parser.problem_value != -1) {
+ fprintf(stderr, "Reader error: %s: #%X at %d\n", parser.problem,
+ parser.problem_value, parser.problem_offset);
+ }
+ else {
+ fprintf(stderr, "Reader error: %s at %d\n", parser.problem,
+ parser.problem_offset);
+ }
+ break;
+
+ case YAML_SCANNER_ERROR:
+ if (parser.context) {
+ fprintf(stderr, "Scanner error: %s at line %d, column %d\n"
+ "%s at line %d, column %d\n", parser.context,
+ parser.context_mark.line+1, parser.context_mark.column+1,
+ parser.problem, parser.problem_mark.line+1,
+ parser.problem_mark.column+1);
+ }
+ else {
+ fprintf(stderr, "Scanner error: %s at line %d, column %d\n",
+ parser.problem, parser.problem_mark.line+1,
+ parser.problem_mark.column+1);
+ }
+ break;
+
+ case YAML_PARSER_ERROR:
+ if (parser.context) {
+ fprintf(stderr, "Parser error: %s at line %d, column %d\n"
+ "%s at line %d, column %d\n", parser.context,
+ parser.context_mark.line+1, parser.context_mark.column+1,
+ parser.problem, parser.problem_mark.line+1,
+ parser.problem_mark.column+1);
+ }
+ else {
+ fprintf(stderr, "Parser error: %s at line %d, column %d\n",
+ parser.problem, parser.problem_mark.line+1,
+ parser.problem_mark.column+1);
+ }
+ break;
+
+ default:
+ /* Couldn't happen. */
+ fprintf(stderr, "Internal error\n");
+ break;
+ }
+
+ yaml_event_delete(&input_event);
+ yaml_event_delete(&output_event);
+ yaml_parser_delete(&parser);
+ yaml_emitter_delete(&emitter);
+
+ return 1;
+
+emitter_error:
+
+ /* Display an emitter error message. */
+
+ switch (emitter.error)
+ {
+ case YAML_MEMORY_ERROR:
+ fprintf(stderr, "Memory error: Not enough memory for emitting\n");
+ break;
+
+ case YAML_WRITER_ERROR:
+ fprintf(stderr, "Writer error: %s\n", emitter.problem);
+ break;
+
+ case YAML_EMITTER_ERROR:
+ fprintf(stderr, "Emitter error: %s\n", emitter.problem);
+ break;
+
+ default:
+ /* Couldn't happen. */
+ fprintf(stderr, "Internal error\n");
+ break;
+ }
+
+ yaml_event_delete(&input_event);
+ yaml_event_delete(&output_event);
+ yaml_parser_delete(&parser);
+ yaml_emitter_delete(&emitter);
+
+ return 1;
+
+event_error:
+
+ fprintf(stderr, "Memory error: Not enough memory for creating an event\n");
+
+ yaml_event_delete(&input_event);
+ yaml_event_delete(&output_event);
+ yaml_parser_delete(&parser);
+ yaml_emitter_delete(&emitter);
+
+ return 1;
+}
+
diff --git a/contrib/libyaml/tests/example-reformatter-alt.c b/contrib/libyaml/tests/example-reformatter-alt.c
new file mode 100644
index 0000000..550e06c
--- /dev/null
+++ b/contrib/libyaml/tests/example-reformatter-alt.c
@@ -0,0 +1,217 @@
+
+#include <yaml.h>
+
+#include <stdlib.h>
+#include <stdio.h>
+
+int
+main(int argc, char *argv[])
+{
+ int help = 0;
+ int canonical = 0;
+ int unicode = 0;
+ int k;
+ int done = 0;
+
+ yaml_parser_t parser;
+ yaml_emitter_t emitter;
+ yaml_document_t document;
+
+ /* Clear the objects. */
+
+ memset(&parser, 0, sizeof(parser));
+ memset(&emitter, 0, sizeof(emitter));
+ memset(&document, 0, sizeof(document));
+
+ /* Analyze command line options. */
+
+ for (k = 1; k < argc; k ++)
+ {
+ if (strcmp(argv[k], "-h") == 0
+ || strcmp(argv[k], "--help") == 0) {
+ help = 1;
+ }
+
+ else if (strcmp(argv[k], "-c") == 0
+ || strcmp(argv[k], "--canonical") == 0) {
+ canonical = 1;
+ }
+
+ else if (strcmp(argv[k], "-u") == 0
+ || strcmp(argv[k], "--unicode") == 0) {
+ unicode = 1;
+ }
+
+ else {
+ fprintf(stderr, "Unrecognized option: %s\n"
+ "Try `%s --help` for more information.\n",
+ argv[k], argv[0]);
+ return 1;
+ }
+ }
+
+ /* Display the help string. */
+
+ if (help)
+ {
+ printf("%s [--canonical] [--unicode] <input >output\n"
+ "or\n%s -h | --help\nReformat a YAML stream\n\nOptions:\n"
+ "-h, --help\t\tdisplay this help and exit\n"
+ "-c, --canonical\t\toutput in the canonical YAML format\n"
+ "-u, --unicode\t\toutput unescaped non-ASCII characters\n",
+ argv[0], argv[0]);
+ return 0;
+ }
+
+ /* Initialize the parser and emitter objects. */
+
+ if (!yaml_parser_initialize(&parser))
+ goto parser_error;
+
+ if (!yaml_emitter_initialize(&emitter))
+ goto emitter_error;
+
+ /* Set the parser parameters. */
+
+ yaml_parser_set_input_file(&parser, stdin);
+
+ /* Set the emitter parameters. */
+
+ yaml_emitter_set_output_file(&emitter, stdout);
+
+ yaml_emitter_set_canonical(&emitter, canonical);
+ yaml_emitter_set_unicode(&emitter, unicode);
+
+ /* The main loop. */
+
+ while (!done)
+ {
+ /* Get the next event. */
+
+ if (!yaml_parser_load(&parser, &document))
+ goto parser_error;
+
+ /* Check if this is the stream end. */
+
+ if (!yaml_document_get_root_node(&document)) {
+ done = 1;
+ }
+
+ /* Emit the event. */
+
+ if (!yaml_emitter_dump(&emitter, &document))
+ goto emitter_error;
+ }
+
+ yaml_parser_delete(&parser);
+ yaml_emitter_delete(&emitter);
+
+ return 0;
+
+parser_error:
+
+ /* Display a parser error message. */
+
+ switch (parser.error)
+ {
+ case YAML_MEMORY_ERROR:
+ fprintf(stderr, "Memory error: Not enough memory for parsing\n");
+ break;
+
+ case YAML_READER_ERROR:
+ if (parser.problem_value != -1) {
+ fprintf(stderr, "Reader error: %s: #%X at %d\n", parser.problem,
+ parser.problem_value, parser.problem_offset);
+ }
+ else {
+ fprintf(stderr, "Reader error: %s at %d\n", parser.problem,
+ parser.problem_offset);
+ }
+ break;
+
+ case YAML_SCANNER_ERROR:
+ if (parser.context) {
+ fprintf(stderr, "Scanner error: %s at line %d, column %d\n"
+ "%s at line %d, column %d\n", parser.context,
+ parser.context_mark.line+1, parser.context_mark.column+1,
+ parser.problem, parser.problem_mark.line+1,
+ parser.problem_mark.column+1);
+ }
+ else {
+ fprintf(stderr, "Scanner error: %s at line %d, column %d\n",
+ parser.problem, parser.problem_mark.line+1,
+ parser.problem_mark.column+1);
+ }
+ break;
+
+ case YAML_PARSER_ERROR:
+ if (parser.context) {
+ fprintf(stderr, "Parser error: %s at line %d, column %d\n"
+ "%s at line %d, column %d\n", parser.context,
+ parser.context_mark.line+1, parser.context_mark.column+1,
+ parser.problem, parser.problem_mark.line+1,
+ parser.problem_mark.column+1);
+ }
+ else {
+ fprintf(stderr, "Parser error: %s at line %d, column %d\n",
+ parser.problem, parser.problem_mark.line+1,
+ parser.problem_mark.column+1);
+ }
+ break;
+
+ case YAML_COMPOSER_ERROR:
+ if (parser.context) {
+ fprintf(stderr, "Composer error: %s at line %d, column %d\n"
+ "%s at line %d, column %d\n", parser.context,
+ parser.context_mark.line+1, parser.context_mark.column+1,
+ parser.problem, parser.problem_mark.line+1,
+ parser.problem_mark.column+1);
+ }
+ else {
+ fprintf(stderr, "Composer error: %s at line %d, column %d\n",
+ parser.problem, parser.problem_mark.line+1,
+ parser.problem_mark.column+1);
+ }
+ break;
+
+ default:
+ /* Couldn't happen. */
+ fprintf(stderr, "Internal error\n");
+ break;
+ }
+
+ yaml_parser_delete(&parser);
+ yaml_emitter_delete(&emitter);
+
+ return 1;
+
+emitter_error:
+
+ /* Display an emitter error message. */
+
+ switch (emitter.error)
+ {
+ case YAML_MEMORY_ERROR:
+ fprintf(stderr, "Memory error: Not enough memory for emitting\n");
+ break;
+
+ case YAML_WRITER_ERROR:
+ fprintf(stderr, "Writer error: %s\n", emitter.problem);
+ break;
+
+ case YAML_EMITTER_ERROR:
+ fprintf(stderr, "Emitter error: %s\n", emitter.problem);
+ break;
+
+ default:
+ /* Couldn't happen. */
+ fprintf(stderr, "Internal error\n");
+ break;
+ }
+
+ yaml_parser_delete(&parser);
+ yaml_emitter_delete(&emitter);
+
+ return 1;
+}
+
diff --git a/contrib/libyaml/tests/example-reformatter.c b/contrib/libyaml/tests/example-reformatter.c
new file mode 100644
index 0000000..946d556
--- /dev/null
+++ b/contrib/libyaml/tests/example-reformatter.c
@@ -0,0 +1,202 @@
+
+#include <yaml.h>
+
+#include <stdlib.h>
+#include <stdio.h>
+
+int
+main(int argc, char *argv[])
+{
+ int help = 0;
+ int canonical = 0;
+ int unicode = 0;
+ int k;
+ int done = 0;
+
+ yaml_parser_t parser;
+ yaml_emitter_t emitter;
+ yaml_event_t event;
+
+ /* Clear the objects. */
+
+ memset(&parser, 0, sizeof(parser));
+ memset(&emitter, 0, sizeof(emitter));
+ memset(&event, 0, sizeof(event));
+
+ /* Analyze command line options. */
+
+ for (k = 1; k < argc; k ++)
+ {
+ if (strcmp(argv[k], "-h") == 0
+ || strcmp(argv[k], "--help") == 0) {
+ help = 1;
+ }
+
+ else if (strcmp(argv[k], "-c") == 0
+ || strcmp(argv[k], "--canonical") == 0) {
+ canonical = 1;
+ }
+
+ else if (strcmp(argv[k], "-u") == 0
+ || strcmp(argv[k], "--unicode") == 0) {
+ unicode = 1;
+ }
+
+ else {
+ fprintf(stderr, "Unrecognized option: %s\n"
+ "Try `%s --help` for more information.\n",
+ argv[k], argv[0]);
+ return 1;
+ }
+ }
+
+ /* Display the help string. */
+
+ if (help)
+ {
+ printf("%s [--canonical] [--unicode] <input >output\n"
+ "or\n%s -h | --help\nReformat a YAML stream\n\nOptions:\n"
+ "-h, --help\t\tdisplay this help and exit\n"
+ "-c, --canonical\t\toutput in the canonical YAML format\n"
+ "-u, --unicode\t\toutput unescaped non-ASCII characters\n",
+ argv[0], argv[0]);
+ return 0;
+ }
+
+ /* Initialize the parser and emitter objects. */
+
+ if (!yaml_parser_initialize(&parser))
+ goto parser_error;
+
+ if (!yaml_emitter_initialize(&emitter))
+ goto emitter_error;
+
+ /* Set the parser parameters. */
+
+ yaml_parser_set_input_file(&parser, stdin);
+
+ /* Set the emitter parameters. */
+
+ yaml_emitter_set_output_file(&emitter, stdout);
+
+ yaml_emitter_set_canonical(&emitter, canonical);
+ yaml_emitter_set_unicode(&emitter, unicode);
+
+ /* The main loop. */
+
+ while (!done)
+ {
+ /* Get the next event. */
+
+ if (!yaml_parser_parse(&parser, &event))
+ goto parser_error;
+
+ /* Check if this is the stream end. */
+
+ if (event.type == YAML_STREAM_END_EVENT) {
+ done = 1;
+ }
+
+ /* Emit the event. */
+
+ if (!yaml_emitter_emit(&emitter, &event))
+ goto emitter_error;
+ }
+
+ yaml_parser_delete(&parser);
+ yaml_emitter_delete(&emitter);
+
+ return 0;
+
+parser_error:
+
+ /* Display a parser error message. */
+
+ switch (parser.error)
+ {
+ case YAML_MEMORY_ERROR:
+ fprintf(stderr, "Memory error: Not enough memory for parsing\n");
+ break;
+
+ case YAML_READER_ERROR:
+ if (parser.problem_value != -1) {
+ fprintf(stderr, "Reader error: %s: #%X at %d\n", parser.problem,
+ parser.problem_value, parser.problem_offset);
+ }
+ else {
+ fprintf(stderr, "Reader error: %s at %d\n", parser.problem,
+ parser.problem_offset);
+ }
+ break;
+
+ case YAML_SCANNER_ERROR:
+ if (parser.context) {
+ fprintf(stderr, "Scanner error: %s at line %d, column %d\n"
+ "%s at line %d, column %d\n", parser.context,
+ parser.context_mark.line+1, parser.context_mark.column+1,
+ parser.problem, parser.problem_mark.line+1,
+ parser.problem_mark.column+1);
+ }
+ else {
+ fprintf(stderr, "Scanner error: %s at line %d, column %d\n",
+ parser.problem, parser.problem_mark.line+1,
+ parser.problem_mark.column+1);
+ }
+ break;
+
+ case YAML_PARSER_ERROR:
+ if (parser.context) {
+ fprintf(stderr, "Parser error: %s at line %d, column %d\n"
+ "%s at line %d, column %d\n", parser.context,
+ parser.context_mark.line+1, parser.context_mark.column+1,
+ parser.problem, parser.problem_mark.line+1,
+ parser.problem_mark.column+1);
+ }
+ else {
+ fprintf(stderr, "Parser error: %s at line %d, column %d\n",
+ parser.problem, parser.problem_mark.line+1,
+ parser.problem_mark.column+1);
+ }
+ break;
+
+ default:
+ /* Couldn't happen. */
+ fprintf(stderr, "Internal error\n");
+ break;
+ }
+
+ yaml_parser_delete(&parser);
+ yaml_emitter_delete(&emitter);
+
+ return 1;
+
+emitter_error:
+
+ /* Display an emitter error message. */
+
+ switch (emitter.error)
+ {
+ case YAML_MEMORY_ERROR:
+ fprintf(stderr, "Memory error: Not enough memory for emitting\n");
+ break;
+
+ case YAML_WRITER_ERROR:
+ fprintf(stderr, "Writer error: %s\n", emitter.problem);
+ break;
+
+ case YAML_EMITTER_ERROR:
+ fprintf(stderr, "Emitter error: %s\n", emitter.problem);
+ break;
+
+ default:
+ /* Couldn't happen. */
+ fprintf(stderr, "Internal error\n");
+ break;
+ }
+
+ yaml_parser_delete(&parser);
+ yaml_emitter_delete(&emitter);
+
+ return 1;
+}
+
diff --git a/contrib/libyaml/tests/run-dumper.c b/contrib/libyaml/tests/run-dumper.c
new file mode 100644
index 0000000..41bead4
--- /dev/null
+++ b/contrib/libyaml/tests/run-dumper.c
@@ -0,0 +1,311 @@
+#include <yaml.h>
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+
+#ifdef NDEBUG
+#undef NDEBUG
+#endif
+#include <assert.h>
+
+#define BUFFER_SIZE 65536
+#define MAX_DOCUMENTS 16
+
+int copy_document(yaml_document_t *document_to, yaml_document_t *document_from)
+{
+ yaml_node_t *node;
+ yaml_node_item_t *item;
+ yaml_node_pair_t *pair;
+
+ if (!yaml_document_initialize(document_to, document_from->version_directive,
+ document_from->tag_directives.start,
+ document_from->tag_directives.end,
+ document_from->start_implicit, document_from->end_implicit))
+ return 0;
+
+ for (node = document_from->nodes.start;
+ node < document_from->nodes.top; node ++) {
+ switch (node->type) {
+ case YAML_SCALAR_NODE:
+ if (!yaml_document_add_scalar(document_to, node->tag,
+ node->data.scalar.value, node->data.scalar.length,
+ node->data.scalar.style)) goto error;
+ break;
+ case YAML_SEQUENCE_NODE:
+ if (!yaml_document_add_sequence(document_to, node->tag,
+ node->data.sequence.style)) goto error;
+ break;
+ case YAML_MAPPING_NODE:
+ if (!yaml_document_add_mapping(document_to, node->tag,
+ node->data.mapping.style)) goto error;
+ break;
+ default:
+ assert(0);
+ break;
+ }
+ }
+
+ for (node = document_from->nodes.start;
+ node < document_from->nodes.top; node ++) {
+ switch (node->type) {
+ case YAML_SEQUENCE_NODE:
+ for (item = node->data.sequence.items.start;
+ item < node->data.sequence.items.top; item ++) {
+ if (!yaml_document_append_sequence_item(document_to,
+ node - document_from->nodes.start + 1,
+ *item)) goto error;
+ }
+ break;
+ case YAML_MAPPING_NODE:
+ for (pair = node->data.mapping.pairs.start;
+ pair < node->data.mapping.pairs.top; pair ++) {
+ if (!yaml_document_append_mapping_pair(document_to,
+ node - document_from->nodes.start + 1,
+ pair->key, pair->value)) goto error;
+ }
+ break;
+ default:
+ break;
+ }
+ }
+ return 1;
+
+error:
+ yaml_document_delete(document_to);
+ return 0;
+}
+
+int compare_nodes(yaml_document_t *document1, int index1,
+ yaml_document_t *document2, int index2)
+{
+ yaml_node_t *node1 = yaml_document_get_node(document1, index1);
+ yaml_node_t *node2 = yaml_document_get_node(document2, index2);
+ int k;
+
+ assert(node1);
+ assert(node2);
+
+ if (node1->type != node2->type)
+ return 0;
+
+ if (strcmp((char *)node1->tag, (char *)node2->tag) != 0) return 0;
+
+ switch (node1->type) {
+ case YAML_SCALAR_NODE:
+ if (node1->data.scalar.length != node2->data.scalar.length)
+ return 0;
+ if (strncmp((char *)node1->data.scalar.value, (char *)node2->data.scalar.value,
+ node1->data.scalar.length) != 0) return 0;
+ break;
+ case YAML_SEQUENCE_NODE:
+ if ((node1->data.sequence.items.top - node1->data.sequence.items.start) !=
+ (node2->data.sequence.items.top - node2->data.sequence.items.start))
+ return 0;
+ for (k = 0; k < (node1->data.sequence.items.top - node1->data.sequence.items.start); k ++) {
+ if (!compare_nodes(document1, node1->data.sequence.items.start[k],
+ document2, node2->data.sequence.items.start[k])) return 0;
+ }
+ break;
+ case YAML_MAPPING_NODE:
+ if ((node1->data.mapping.pairs.top - node1->data.mapping.pairs.start) !=
+ (node2->data.mapping.pairs.top - node2->data.mapping.pairs.start))
+ return 0;
+ for (k = 0; k < (node1->data.mapping.pairs.top - node1->data.mapping.pairs.start); k ++) {
+ if (!compare_nodes(document1, node1->data.mapping.pairs.start[k].key,
+ document2, node2->data.mapping.pairs.start[k].key)) return 0;
+ if (!compare_nodes(document1, node1->data.mapping.pairs.start[k].value,
+ document2, node2->data.mapping.pairs.start[k].value)) return 0;
+ }
+ break;
+ default:
+ assert(0);
+ break;
+ }
+ return 1;
+}
+
+int compare_documents(yaml_document_t *document1, yaml_document_t *document2)
+{
+ int k;
+
+ if ((document1->version_directive && !document2->version_directive)
+ || (!document1->version_directive && document2->version_directive)
+ || (document1->version_directive && document2->version_directive
+ && (document1->version_directive->major != document2->version_directive->major
+ || document1->version_directive->minor != document2->version_directive->minor)))
+ return 0;
+
+ if ((document1->tag_directives.end - document1->tag_directives.start) !=
+ (document2->tag_directives.end - document2->tag_directives.start))
+ return 0;
+ for (k = 0; k < (document1->tag_directives.end - document1->tag_directives.start); k ++) {
+ if ((strcmp((char *)document1->tag_directives.start[k].handle,
+ (char *)document2->tag_directives.start[k].handle) != 0)
+ || (strcmp((char *)document1->tag_directives.start[k].prefix,
+ (char *)document2->tag_directives.start[k].prefix) != 0))
+ return 0;
+ }
+
+ if ((document1->nodes.top - document1->nodes.start) !=
+ (document2->nodes.top - document2->nodes.start))
+ return 0;
+
+ if (document1->nodes.top != document1->nodes.start) {
+ if (!compare_nodes(document1, 1, document2, 1))
+ return 0;
+ }
+
+ return 1;
+}
+
+int print_output(char *name, unsigned char *buffer, size_t size, int count)
+{
+ FILE *file;
+ char data[BUFFER_SIZE];
+ size_t data_size = 1;
+ size_t total_size = 0;
+ if (count >= 0) {
+ printf("FAILED (at the document #%d)\nSOURCE:\n", count+1);
+ }
+ file = fopen(name, "rb");
+ assert(file);
+ while (data_size > 0) {
+ data_size = fread(data, 1, BUFFER_SIZE, file);
+ assert(!ferror(file));
+ if (!data_size) break;
+ assert(fwrite(data, 1, data_size, stdout) == data_size);
+ total_size += data_size;
+ if (feof(file)) break;
+ }
+ fclose(file);
+ printf("#### (length: %d)\n", total_size);
+ printf("OUTPUT:\n%s#### (length: %d)\n", buffer, size);
+ return 0;
+}
+
+int
+main(int argc, char *argv[])
+{
+ int number;
+ int canonical = 0;
+ int unicode = 0;
+
+ number = 1;
+ while (number < argc) {
+ if (strcmp(argv[number], "-c") == 0) {
+ canonical = 1;
+ }
+ else if (strcmp(argv[number], "-u") == 0) {
+ unicode = 1;
+ }
+ else if (argv[number][0] == '-') {
+ printf("Unknown option: '%s'\n", argv[number]);
+ return 0;
+ }
+ if (argv[number][0] == '-') {
+ if (number < argc-1) {
+ memmove(argv+number, argv+number+1, (argc-number-1)*sizeof(char *));
+ }
+ argc --;
+ }
+ else {
+ number ++;
+ }
+ }
+
+ if (argc < 2) {
+ printf("Usage: %s [-c] [-u] file1.yaml ...\n", argv[0]);
+ return 0;
+ }
+
+ for (number = 1; number < argc; number ++)
+ {
+ FILE *file;
+ yaml_parser_t parser;
+ yaml_emitter_t emitter;
+
+ yaml_document_t document;
+ unsigned char buffer[BUFFER_SIZE];
+ size_t written = 0;
+ yaml_document_t documents[MAX_DOCUMENTS];
+ size_t document_number = 0;
+ int done = 0;
+ int count = 0;
+ int error = 0;
+ int k;
+ memset(buffer, 0, BUFFER_SIZE);
+ memset(documents, 0, MAX_DOCUMENTS*sizeof(yaml_document_t));
+
+ printf("[%d] Loading, dumping, and loading again '%s': ", number, argv[number]);
+ fflush(stdout);
+
+ file = fopen(argv[number], "rb");
+ assert(file);
+
+ assert(yaml_parser_initialize(&parser));
+ yaml_parser_set_input_file(&parser, file);
+ assert(yaml_emitter_initialize(&emitter));
+ if (canonical) {
+ yaml_emitter_set_canonical(&emitter, 1);
+ }
+ if (unicode) {
+ yaml_emitter_set_unicode(&emitter, 1);
+ }
+ yaml_emitter_set_output_string(&emitter, buffer, BUFFER_SIZE, &written);
+ yaml_emitter_open(&emitter);
+
+ while (!done)
+ {
+ if (!yaml_parser_load(&parser, &document)) {
+ error = 1;
+ break;
+ }
+
+ done = (!yaml_document_get_root_node(&document));
+ if (!done) {
+ assert(document_number < MAX_DOCUMENTS);
+ assert(copy_document(&(documents[document_number++]), &document));
+ assert(yaml_emitter_dump(&emitter, &document) ||
+ (yaml_emitter_flush(&emitter) && print_output(argv[number], buffer, written, count)));
+ count ++;
+ }
+ else {
+ yaml_document_delete(&document);
+ }
+ }
+
+ yaml_parser_delete(&parser);
+ assert(!fclose(file));
+ yaml_emitter_close(&emitter);
+ yaml_emitter_delete(&emitter);
+
+ if (!error)
+ {
+ count = done = 0;
+ assert(yaml_parser_initialize(&parser));
+ yaml_parser_set_input_string(&parser, buffer, written);
+
+ while (!done)
+ {
+ assert(yaml_parser_load(&parser, &document) || print_output(argv[number], buffer, written, count));
+ done = (!yaml_document_get_root_node(&document));
+ if (!done) {
+ assert(compare_documents(documents+count, &document) || print_output(argv[number], buffer, written, count));
+ count ++;
+ }
+ yaml_document_delete(&document);
+ }
+ yaml_parser_delete(&parser);
+ }
+
+ for (k = 0; k < document_number; k ++) {
+ yaml_document_delete(documents+k);
+ }
+
+ printf("PASSED (length: %d)\n", written);
+ print_output(argv[number], buffer, written, -1);
+ }
+
+ return 0;
+}
diff --git a/contrib/libyaml/tests/run-emitter.c b/contrib/libyaml/tests/run-emitter.c
new file mode 100644
index 0000000..6b246fa
--- /dev/null
+++ b/contrib/libyaml/tests/run-emitter.c
@@ -0,0 +1,327 @@
+#include <yaml.h>
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+
+#ifdef NDEBUG
+#undef NDEBUG
+#endif
+#include <assert.h>
+
+#define BUFFER_SIZE 65536
+#define MAX_EVENTS 1024
+
+int copy_event(yaml_event_t *event_to, yaml_event_t *event_from)
+{
+ switch (event_from->type)
+ {
+ case YAML_STREAM_START_EVENT:
+ return yaml_stream_start_event_initialize(event_to,
+ event_from->data.stream_start.encoding);
+
+ case YAML_STREAM_END_EVENT:
+ return yaml_stream_end_event_initialize(event_to);
+
+ case YAML_DOCUMENT_START_EVENT:
+ return yaml_document_start_event_initialize(event_to,
+ event_from->data.document_start.version_directive,
+ event_from->data.document_start.tag_directives.start,
+ event_from->data.document_start.tag_directives.end,
+ event_from->data.document_start.implicit);
+
+ case YAML_DOCUMENT_END_EVENT:
+ return yaml_document_end_event_initialize(event_to,
+ event_from->data.document_end.implicit);
+
+ case YAML_ALIAS_EVENT:
+ return yaml_alias_event_initialize(event_to,
+ event_from->data.alias.anchor);
+
+ case YAML_SCALAR_EVENT:
+ return yaml_scalar_event_initialize(event_to,
+ event_from->data.scalar.anchor,
+ event_from->data.scalar.tag,
+ event_from->data.scalar.value,
+ event_from->data.scalar.length,
+ event_from->data.scalar.plain_implicit,
+ event_from->data.scalar.quoted_implicit,
+ event_from->data.scalar.style);
+
+ case YAML_SEQUENCE_START_EVENT:
+ return yaml_sequence_start_event_initialize(event_to,
+ event_from->data.sequence_start.anchor,
+ event_from->data.sequence_start.tag,
+ event_from->data.sequence_start.implicit,
+ event_from->data.sequence_start.style);
+
+ case YAML_SEQUENCE_END_EVENT:
+ return yaml_sequence_end_event_initialize(event_to);
+
+ case YAML_MAPPING_START_EVENT:
+ return yaml_mapping_start_event_initialize(event_to,
+ event_from->data.mapping_start.anchor,
+ event_from->data.mapping_start.tag,
+ event_from->data.mapping_start.implicit,
+ event_from->data.mapping_start.style);
+
+ case YAML_MAPPING_END_EVENT:
+ return yaml_mapping_end_event_initialize(event_to);
+
+ default:
+ assert(1);
+ }
+
+ return 0;
+}
+
+int compare_events(yaml_event_t *event1, yaml_event_t *event2)
+{
+ int k;
+
+ if (event1->type != event2->type)
+ return 0;
+
+ switch (event1->type)
+ {
+ case YAML_STREAM_START_EVENT:
+ return 1;
+ /* return (event1->data.stream_start.encoding ==
+ event2->data.stream_start.encoding); */
+
+ case YAML_DOCUMENT_START_EVENT:
+ if ((event1->data.document_start.version_directive && !event2->data.document_start.version_directive)
+ || (!event1->data.document_start.version_directive && event2->data.document_start.version_directive)
+ || (event1->data.document_start.version_directive && event2->data.document_start.version_directive
+ && (event1->data.document_start.version_directive->major != event2->data.document_start.version_directive->major
+ || event1->data.document_start.version_directive->minor != event2->data.document_start.version_directive->minor)))
+ return 0;
+ if ((event1->data.document_start.tag_directives.end - event1->data.document_start.tag_directives.start) !=
+ (event2->data.document_start.tag_directives.end - event2->data.document_start.tag_directives.start))
+ return 0;
+ for (k = 0; k < (event1->data.document_start.tag_directives.end - event1->data.document_start.tag_directives.start); k ++) {
+ if ((strcmp((char *)event1->data.document_start.tag_directives.start[k].handle,
+ (char *)event2->data.document_start.tag_directives.start[k].handle) != 0)
+ || (strcmp((char *)event1->data.document_start.tag_directives.start[k].prefix,
+ (char *)event2->data.document_start.tag_directives.start[k].prefix) != 0))
+ return 0;
+ }
+ /* if (event1->data.document_start.implicit != event2->data.document_start.implicit)
+ return 0; */
+ return 1;
+
+ case YAML_DOCUMENT_END_EVENT:
+ return 1;
+ /* return (event1->data.document_end.implicit ==
+ event2->data.document_end.implicit); */
+
+ case YAML_ALIAS_EVENT:
+ return (strcmp((char *)event1->data.alias.anchor,
+ (char *)event2->data.alias.anchor) == 0);
+
+ case YAML_SCALAR_EVENT:
+ if ((event1->data.scalar.anchor && !event2->data.scalar.anchor)
+ || (!event1->data.scalar.anchor && event2->data.scalar.anchor)
+ || (event1->data.scalar.anchor && event2->data.scalar.anchor
+ && strcmp((char *)event1->data.scalar.anchor,
+ (char *)event2->data.scalar.anchor) != 0))
+ return 0;
+ if ((event1->data.scalar.tag && !event2->data.scalar.tag
+ && strcmp((char *)event1->data.scalar.tag, "!") != 0)
+ || (!event1->data.scalar.tag && event2->data.scalar.tag
+ && strcmp((char *)event2->data.scalar.tag, "!") != 0)
+ || (event1->data.scalar.tag && event2->data.scalar.tag
+ && strcmp((char *)event1->data.scalar.tag,
+ (char *)event2->data.scalar.tag) != 0))
+ return 0;
+ if ((event1->data.scalar.length != event2->data.scalar.length)
+ || memcmp(event1->data.scalar.value, event2->data.scalar.value,
+ event1->data.scalar.length) != 0)
+ return 0;
+ if ((event1->data.scalar.plain_implicit != event2->data.scalar.plain_implicit)
+ || (event2->data.scalar.quoted_implicit != event2->data.scalar.quoted_implicit)
+ /* || (event2->data.scalar.style != event2->data.scalar.style) */)
+ return 0;
+ return 1;
+
+ case YAML_SEQUENCE_START_EVENT:
+ if ((event1->data.sequence_start.anchor && !event2->data.sequence_start.anchor)
+ || (!event1->data.sequence_start.anchor && event2->data.sequence_start.anchor)
+ || (event1->data.sequence_start.anchor && event2->data.sequence_start.anchor
+ && strcmp((char *)event1->data.sequence_start.anchor,
+ (char *)event2->data.sequence_start.anchor) != 0))
+ return 0;
+ if ((event1->data.sequence_start.tag && !event2->data.sequence_start.tag)
+ || (!event1->data.sequence_start.tag && event2->data.sequence_start.tag)
+ || (event1->data.sequence_start.tag && event2->data.sequence_start.tag
+ && strcmp((char *)event1->data.sequence_start.tag,
+ (char *)event2->data.sequence_start.tag) != 0))
+ return 0;
+ if ((event1->data.sequence_start.implicit != event2->data.sequence_start.implicit)
+ /* || (event2->data.sequence_start.style != event2->data.sequence_start.style) */)
+ return 0;
+ return 1;
+
+ case YAML_MAPPING_START_EVENT:
+ if ((event1->data.mapping_start.anchor && !event2->data.mapping_start.anchor)
+ || (!event1->data.mapping_start.anchor && event2->data.mapping_start.anchor)
+ || (event1->data.mapping_start.anchor && event2->data.mapping_start.anchor
+ && strcmp((char *)event1->data.mapping_start.anchor,
+ (char *)event2->data.mapping_start.anchor) != 0))
+ return 0;
+ if ((event1->data.mapping_start.tag && !event2->data.mapping_start.tag)
+ || (!event1->data.mapping_start.tag && event2->data.mapping_start.tag)
+ || (event1->data.mapping_start.tag && event2->data.mapping_start.tag
+ && strcmp((char *)event1->data.mapping_start.tag,
+ (char *)event2->data.mapping_start.tag) != 0))
+ return 0;
+ if ((event1->data.mapping_start.implicit != event2->data.mapping_start.implicit)
+ /* || (event2->data.mapping_start.style != event2->data.mapping_start.style) */)
+ return 0;
+ return 1;
+
+ default:
+ return 1;
+ }
+}
+
+int print_output(char *name, unsigned char *buffer, size_t size, int count)
+{
+ FILE *file;
+ char data[BUFFER_SIZE];
+ size_t data_size = 1;
+ size_t total_size = 0;
+ if (count >= 0) {
+ printf("FAILED (at the event #%d)\nSOURCE:\n", count+1);
+ }
+ file = fopen(name, "rb");
+ assert(file);
+ while (data_size > 0) {
+ data_size = fread(data, 1, BUFFER_SIZE, file);
+ assert(!ferror(file));
+ if (!data_size) break;
+ assert(fwrite(data, 1, data_size, stdout) == data_size);
+ total_size += data_size;
+ if (feof(file)) break;
+ }
+ fclose(file);
+ printf("#### (length: %d)\n", total_size);
+ printf("OUTPUT:\n%s#### (length: %d)\n", buffer, size);
+ return 0;
+}
+
+int
+main(int argc, char *argv[])
+{
+ int number;
+ int canonical = 0;
+ int unicode = 0;
+
+ number = 1;
+ while (number < argc) {
+ if (strcmp(argv[number], "-c") == 0) {
+ canonical = 1;
+ }
+ else if (strcmp(argv[number], "-u") == 0) {
+ unicode = 1;
+ }
+ else if (argv[number][0] == '-') {
+ printf("Unknown option: '%s'\n", argv[number]);
+ return 0;
+ }
+ if (argv[number][0] == '-') {
+ if (number < argc-1) {
+ memmove(argv+number, argv+number+1, (argc-number-1)*sizeof(char *));
+ }
+ argc --;
+ }
+ else {
+ number ++;
+ }
+ }
+
+ if (argc < 2) {
+ printf("Usage: %s [-c] [-u] file1.yaml ...\n", argv[0]);
+ return 0;
+ }
+
+ for (number = 1; number < argc; number ++)
+ {
+ FILE *file;
+ yaml_parser_t parser;
+ yaml_emitter_t emitter;
+ yaml_event_t event;
+ unsigned char buffer[BUFFER_SIZE];
+ size_t written = 0;
+ yaml_event_t events[MAX_EVENTS];
+ size_t event_number = 0;
+ int done = 0;
+ int count = 0;
+ int error = 0;
+ int k;
+ memset(buffer, 0, BUFFER_SIZE);
+ memset(events, 0, MAX_EVENTS*sizeof(yaml_event_t));
+
+ printf("[%d] Parsing, emitting, and parsing again '%s': ", number, argv[number]);
+ fflush(stdout);
+
+ file = fopen(argv[number], "rb");
+ assert(file);
+
+ assert(yaml_parser_initialize(&parser));
+ yaml_parser_set_input_file(&parser, file);
+ assert(yaml_emitter_initialize(&emitter));
+ if (canonical) {
+ yaml_emitter_set_canonical(&emitter, 1);
+ }
+ if (unicode) {
+ yaml_emitter_set_unicode(&emitter, 1);
+ }
+ yaml_emitter_set_output_string(&emitter, buffer, BUFFER_SIZE, &written);
+
+ while (!done)
+ {
+ if (!yaml_parser_parse(&parser, &event)) {
+ error = 1;
+ break;
+ }
+
+ done = (event.type == YAML_STREAM_END_EVENT);
+ assert(event_number < MAX_EVENTS);
+ assert(copy_event(&(events[event_number++]), &event));
+ assert(yaml_emitter_emit(&emitter, &event) ||
+ (yaml_emitter_flush(&emitter) && print_output(argv[number], buffer, written, count)));
+ count ++;
+ }
+
+ yaml_parser_delete(&parser);
+ assert(!fclose(file));
+ yaml_emitter_delete(&emitter);
+
+ if (!error)
+ {
+ count = done = 0;
+ assert(yaml_parser_initialize(&parser));
+ yaml_parser_set_input_string(&parser, buffer, written);
+
+ while (!done)
+ {
+ assert(yaml_parser_parse(&parser, &event) || print_output(argv[number], buffer, written, count));
+ done = (event.type == YAML_STREAM_END_EVENT);
+ assert(compare_events(events+count, &event) || print_output(argv[number], buffer, written, count));
+ yaml_event_delete(&event);
+ count ++;
+ }
+ yaml_parser_delete(&parser);
+ }
+
+ for (k = 0; k < event_number; k ++) {
+ yaml_event_delete(events+k);
+ }
+
+ printf("PASSED (length: %d)\n", written);
+ print_output(argv[number], buffer, written, -1);
+ }
+
+ return 0;
+}
diff --git a/contrib/libyaml/tests/run-loader.c b/contrib/libyaml/tests/run-loader.c
new file mode 100644
index 0000000..8c36b66
--- /dev/null
+++ b/contrib/libyaml/tests/run-loader.c
@@ -0,0 +1,63 @@
+#include <yaml.h>
+
+#include <stdlib.h>
+#include <stdio.h>
+
+#ifdef NDEBUG
+#undef NDEBUG
+#endif
+#include <assert.h>
+
+int
+main(int argc, char *argv[])
+{
+ int number;
+
+ if (argc < 2) {
+ printf("Usage: %s file1.yaml ...\n", argv[0]);
+ return 0;
+ }
+
+ for (number = 1; number < argc; number ++)
+ {
+ FILE *file;
+ yaml_parser_t parser;
+ yaml_document_t document;
+ int done = 0;
+ int count = 0;
+ int error = 0;
+
+ printf("[%d] Loading '%s': ", number, argv[number]);
+ fflush(stdout);
+
+ file = fopen(argv[number], "rb");
+ assert(file);
+
+ assert(yaml_parser_initialize(&parser));
+
+ yaml_parser_set_input_file(&parser, file);
+
+ while (!done)
+ {
+ if (!yaml_parser_load(&parser, &document)) {
+ error = 1;
+ break;
+ }
+
+ done = (!yaml_document_get_root_node(&document));
+
+ yaml_document_delete(&document);
+
+ if (!done) count ++;
+ }
+
+ yaml_parser_delete(&parser);
+
+ assert(!fclose(file));
+
+ printf("%s (%d documents)\n", (error ? "FAILURE" : "SUCCESS"), count);
+ }
+
+ return 0;
+}
+
diff --git a/contrib/libyaml/tests/run-parser.c b/contrib/libyaml/tests/run-parser.c
new file mode 100644
index 0000000..1303112
--- /dev/null
+++ b/contrib/libyaml/tests/run-parser.c
@@ -0,0 +1,63 @@
+#include <yaml.h>
+
+#include <stdlib.h>
+#include <stdio.h>
+
+#ifdef NDEBUG
+#undef NDEBUG
+#endif
+#include <assert.h>
+
+int
+main(int argc, char *argv[])
+{
+ int number;
+
+ if (argc < 2) {
+ printf("Usage: %s file1.yaml ...\n", argv[0]);
+ return 0;
+ }
+
+ for (number = 1; number < argc; number ++)
+ {
+ FILE *file;
+ yaml_parser_t parser;
+ yaml_event_t event;
+ int done = 0;
+ int count = 0;
+ int error = 0;
+
+ printf("[%d] Parsing '%s': ", number, argv[number]);
+ fflush(stdout);
+
+ file = fopen(argv[number], "rb");
+ assert(file);
+
+ assert(yaml_parser_initialize(&parser));
+
+ yaml_parser_set_input_file(&parser, file);
+
+ while (!done)
+ {
+ if (!yaml_parser_parse(&parser, &event)) {
+ error = 1;
+ break;
+ }
+
+ done = (event.type == YAML_STREAM_END_EVENT);
+
+ yaml_event_delete(&event);
+
+ count ++;
+ }
+
+ yaml_parser_delete(&parser);
+
+ assert(!fclose(file));
+
+ printf("%s (%d events)\n", (error ? "FAILURE" : "SUCCESS"), count);
+ }
+
+ return 0;
+}
+
diff --git a/contrib/libyaml/tests/run-scanner.c b/contrib/libyaml/tests/run-scanner.c
new file mode 100644
index 0000000..2c79e7c
--- /dev/null
+++ b/contrib/libyaml/tests/run-scanner.c
@@ -0,0 +1,63 @@
+#include <yaml.h>
+
+#include <stdlib.h>
+#include <stdio.h>
+
+#ifdef NDEBUG
+#undef NDEBUG
+#endif
+#include <assert.h>
+
+int
+main(int argc, char *argv[])
+{
+ int number;
+
+ if (argc < 2) {
+ printf("Usage: %s file1.yaml ...\n", argv[0]);
+ return 0;
+ }
+
+ for (number = 1; number < argc; number ++)
+ {
+ FILE *file;
+ yaml_parser_t parser;
+ yaml_token_t token;
+ int done = 0;
+ int count = 0;
+ int error = 0;
+
+ printf("[%d] Scanning '%s': ", number, argv[number]);
+ fflush(stdout);
+
+ file = fopen(argv[number], "rb");
+ assert(file);
+
+ assert(yaml_parser_initialize(&parser));
+
+ yaml_parser_set_input_file(&parser, file);
+
+ while (!done)
+ {
+ if (!yaml_parser_scan(&parser, &token)) {
+ error = 1;
+ break;
+ }
+
+ done = (token.type == YAML_STREAM_END_TOKEN);
+
+ yaml_token_delete(&token);
+
+ count ++;
+ }
+
+ yaml_parser_delete(&parser);
+
+ assert(!fclose(file));
+
+ printf("%s (%d tokens)\n", (error ? "FAILURE" : "SUCCESS"), count);
+ }
+
+ return 0;
+}
+
diff --git a/contrib/libyaml/tests/test-reader.c b/contrib/libyaml/tests/test-reader.c
new file mode 100644
index 0000000..c6f84cd
--- /dev/null
+++ b/contrib/libyaml/tests/test-reader.c
@@ -0,0 +1,354 @@
+#include <yaml.h>
+
+YAML_DECLARE(int)
+yaml_parser_update_buffer(yaml_parser_t *parser, size_t length);
+
+#include <stdlib.h>
+#include <stdio.h>
+
+#ifdef NDEBUG
+#undef NDEBUG
+#endif
+#include <assert.h>
+
+/*
+ * Test cases are stolen from
+ * http://www.cl.cam.ac.uk/~mgk25/ucs/examples/UTF-8-test.txt
+ */
+
+typedef struct {
+ char *title;
+ char *test;
+ int result;
+} test_case;
+
+test_case utf8_sequences[] = {
+ /* {"title", "test 1|test 2|...|test N!", (0 or 1)}, */
+
+ {"a simple test", "'test' is '\xd0\xbf\xd1\x80\xd0\xbe\xd0\xb2\xd0\xb5\xd1\x80\xd0\xba\xd0\xb0' in Russian!", 1},
+ {"an empty line", "!", 1},
+
+ {"u-0 is a control character", "\x00!", 0},
+ {"u-80 is a control character", "\xc2\x80!", 0},
+ {"u-800 is valid", "\xe0\xa0\x80!", 1},
+ {"u-10000 is valid", "\xf0\x90\x80\x80!", 1},
+ {"5 bytes sequences are not allowed", "\xf8\x88\x80\x80\x80!", 0},
+ {"6 bytes sequences are not allowed", "\xfc\x84\x80\x80\x80\x80!", 0},
+
+ {"u-7f is a control character", "\x7f!", 0},
+ {"u-7FF is valid", "\xdf\xbf!", 1},
+ {"u-FFFF is a control character", "\xef\xbf\xbf!", 0},
+ {"u-1FFFFF is too large", "\xf7\xbf\xbf\xbf!", 0},
+ {"u-3FFFFFF is 5 bytes", "\xfb\xbf\xbf\xbf\xbf!", 0},
+ {"u-7FFFFFFF is 6 bytes", "\xfd\xbf\xbf\xbf\xbf\xbf!", 0},
+
+ {"u-D7FF", "\xed\x9f\xbf!", 1},
+ {"u-E000", "\xee\x80\x80!", 1},
+ {"u-FFFD", "\xef\xbf\xbd!", 1},
+ {"u-10FFFF", "\xf4\x8f\xbf\xbf!", 1},
+ {"u-110000", "\xf4\x90\x80\x80!", 0},
+
+ {"first continuation byte", "\x80!", 0},
+ {"last continuation byte", "\xbf!", 0},
+
+ {"2 continuation bytes", "\x80\xbf!", 0},
+ {"3 continuation bytes", "\x80\xbf\x80!", 0},
+ {"4 continuation bytes", "\x80\xbf\x80\xbf!", 0},
+ {"5 continuation bytes", "\x80\xbf\x80\xbf\x80!", 0},
+ {"6 continuation bytes", "\x80\xbf\x80\xbf\x80\xbf!", 0},
+ {"7 continuation bytes", "\x80\xbf\x80\xbf\x80\xbf\x80!", 0},
+
+ {"sequence of all 64 possible continuation bytes",
+ "\x80|\x81|\x82|\x83|\x84|\x85|\x86|\x87|\x88|\x89|\x8a|\x8b|\x8c|\x8d|\x8e|\x8f|"
+ "\x90|\x91|\x92|\x93|\x94|\x95|\x96|\x97|\x98|\x99|\x9a|\x9b|\x9c|\x9d|\x9e|\x9f|"
+ "\xa0|\xa1|\xa2|\xa3|\xa4|\xa5|\xa6|\xa7|\xa8|\xa9|\xaa|\xab|\xac|\xad|\xae|\xaf|"
+ "\xb0|\xb1|\xb2|\xb3|\xb4|\xb5|\xb6|\xb7|\xb8|\xb9|\xba|\xbb|\xbc|\xbd|\xbe|\xbf!", 0},
+ {"32 first bytes of 2-byte sequences {0xc0-0xdf}",
+ "\xc0 |\xc1 |\xc2 |\xc3 |\xc4 |\xc5 |\xc6 |\xc7 |\xc8 |\xc9 |\xca |\xcb |\xcc |\xcd |\xce |\xcf |"
+ "\xd0 |\xd1 |\xd2 |\xd3 |\xd4 |\xd5 |\xd6 |\xd7 |\xd8 |\xd9 |\xda |\xdb |\xdc |\xdd |\xde |\xdf !", 0},
+ {"16 first bytes of 3-byte sequences {0xe0-0xef}",
+ "\xe0 |\xe1 |\xe2 |\xe3 |\xe4 |\xe5 |\xe6 |\xe7 |\xe8 |\xe9 |\xea |\xeb |\xec |\xed |\xee |\xef !", 0},
+ {"8 first bytes of 4-byte sequences {0xf0-0xf7}", "\xf0 |\xf1 |\xf2 |\xf3 |\xf4 |\xf5 |\xf6 |\xf7 !", 0},
+ {"4 first bytes of 5-byte sequences {0xf8-0xfb}", "\xf8 |\xf9 |\xfa |\xfb !", 0},
+ {"2 first bytes of 6-byte sequences {0xfc-0xfd}", "\xfc |\xfd !", 0},
+
+ {"sequences with last byte missing {u-0}",
+ "\xc0|\xe0\x80|\xf0\x80\x80|\xf8\x80\x80\x80|\xfc\x80\x80\x80\x80!", 0},
+ {"sequences with last byte missing {u-...FF}",
+ "\xdf|\xef\xbf|\xf7\xbf\xbf|\xfb\xbf\xbf\xbf|\xfd\xbf\xbf\xbf\xbf!", 0},
+
+ {"impossible bytes", "\xfe|\xff|\xfe\xfe\xff\xff!", 0},
+
+ {"overlong sequences {u-2f}",
+ "\xc0\xaf|\xe0\x80\xaf|\xf0\x80\x80\xaf|\xf8\x80\x80\x80\xaf|\xfc\x80\x80\x80\x80\xaf!", 0},
+
+ {"maximum overlong sequences",
+ "\xc1\xbf|\xe0\x9f\xbf|\xf0\x8f\xbf\xbf|\xf8\x87\xbf\xbf\xbf|\xfc\x83\xbf\xbf\xbf\xbf!", 0},
+
+ {"overlong representation of the NUL character",
+ "\xc0\x80|\xe0\x80\x80|\xf0\x80\x80\x80|\xf8\x80\x80\x80\x80|\xfc\x80\x80\x80\x80\x80!", 0},
+
+ {"single UTF-16 surrogates",
+ "\xed\xa0\x80|\xed\xad\xbf|\xed\xae\x80|\xed\xaf\xbf|\xed\xb0\x80|\xed\xbe\x80|\xed\xbf\xbf!", 0},
+
+ {"paired UTF-16 surrogates",
+ "\xed\xa0\x80\xed\xb0\x80|\xed\xa0\x80\xed\xbf\xbf|\xed\xad\xbf\xed\xb0\x80|"
+ "\xed\xad\xbf\xed\xbf\xbf|\xed\xae\x80\xed\xb0\x80|\xed\xae\x80\xed\xbf\xbf|"
+ "\xed\xaf\xbf\xed\xb0\x80|\xed\xaf\xbf\xed\xbf\xbf!", 0},
+
+ {"other illegal code positions", "\xef\xbf\xbe|\xef\xbf\xbf!", 0},
+
+ {NULL, NULL, 0}
+};
+
+test_case boms[] = {
+
+ /* {"title", "test!", lenth}, */
+
+ {"no bom (utf-8)", "Hi is \xd0\x9f\xd1\x80\xd0\xb8\xd0\xb2\xd0\xb5\xd1\x82!", 13},
+ {"bom (utf-8)", "\xef\xbb\xbfHi is \xd0\x9f\xd1\x80\xd0\xb8\xd0\xb2\xd0\xb5\xd1\x82!", 13},
+ {"bom (utf-16-le)", "\xff\xfeH\x00i\x00 \x00i\x00s\x00 \x00\x1f\x04@\x04""8\x04""2\x04""5\x04""B\x04!", 13},
+ {"bom (utf-16-be)", "\xfe\xff\x00H\x00i\x00 \x00i\x00s\x00 \x04\x1f\x04@\x04""8\x04""2\x04""5\x04""B!", 13},
+ {NULL, NULL, 0}
+};
+
+char *bom_original = "Hi is \xd0\x9f\xd1\x80\xd0\xb8\xd0\xb2\xd0\xb5\xd1\x82";
+
+int check_utf8_sequences(void)
+{
+ yaml_parser_t parser;
+ int failed = 0;
+ int k;
+ printf("checking utf-8 sequences...\n");
+ for (k = 0; utf8_sequences[k].test; k++) {
+ char *title = utf8_sequences[k].title;
+ int check = utf8_sequences[k].result;
+ int result;
+ char *start = utf8_sequences[k].test;
+ char *end = start;
+ printf("\t%s:\n", title);
+ while(1) {
+ while (*end != '|' && *end != '!') end++;
+ yaml_parser_initialize(&parser);
+ yaml_parser_set_input_string(&parser, (unsigned char *)start, end-start);
+ result = yaml_parser_update_buffer(&parser, end-start);
+ if (result != check) {
+ printf("\t\t- ");
+ failed ++;
+ }
+ else {
+ printf("\t\t+ ");
+ }
+ if (!parser.error) {
+ printf("(no error)\n");
+ }
+ else if (parser.error == YAML_READER_ERROR) {
+ if (parser.problem_value != -1) {
+ printf("(reader error: %s: #%X at %d)\n",
+ parser.problem, parser.problem_value, parser.problem_offset);
+ }
+ else {
+ printf("(reader error: %s at %d)\n",
+ parser.problem, parser.problem_offset);
+ }
+ }
+ if (*end == '!') break;
+ start = ++end;
+ yaml_parser_delete(&parser);
+ };
+ printf("\n");
+ }
+ printf("checking utf-8 sequences: %d fail(s)\n", failed);
+ return failed;
+}
+
+int check_boms(void)
+{
+ yaml_parser_t parser;
+ int failed = 0;
+ int k;
+ printf("checking boms...\n");
+ for (k = 0; boms[k].test; k++) {
+ char *title = boms[k].title;
+ int check = boms[k].result;
+ int result;
+ char *start = boms[k].test;
+ char *end = start;
+ while (*end != '!') end++;
+ printf("\t%s: ", title);
+ yaml_parser_initialize(&parser);
+ yaml_parser_set_input_string(&parser, (unsigned char *)start, end-start);
+ result = yaml_parser_update_buffer(&parser, end-start);
+ if (!result) {
+ printf("- (reader error: %s at %d)\n", parser.problem, parser.problem_offset);
+ failed++;
+ }
+ else {
+ if (parser.unread != check) {
+ printf("- (length=%d while expected length=%d)\n", parser.unread, check);
+ failed++;
+ }
+ else if (memcmp(parser.buffer.start, bom_original, check) != 0) {
+ printf("- (value '%s' does not equal to the original value '%s')\n", parser.buffer.start, bom_original);
+ failed++;
+ }
+ else {
+ printf("+\n");
+ }
+ }
+ yaml_parser_delete(&parser);
+ }
+ printf("checking boms: %d fail(s)\n", failed);
+ return failed;
+}
+
+#define LONG 100000
+
+int check_long_utf8(void)
+{
+ yaml_parser_t parser;
+ int k = 0;
+ int j;
+ int failed = 0;
+ unsigned char ch0, ch1;
+ unsigned char *buffer = malloc(3+LONG*2);
+ assert(buffer);
+ printf("checking a long utf8 sequence...\n");
+ buffer[k++] = '\xef';
+ buffer[k++] = '\xbb';
+ buffer[k++] = '\xbf';
+ for (j = 0; j < LONG; j ++) {
+ if (j % 2) {
+ buffer[k++] = '\xd0';
+ buffer[k++] = '\x90';
+ }
+ else {
+ buffer[k++] = '\xd0';
+ buffer[k++] = '\xaf';
+ }
+ }
+ yaml_parser_initialize(&parser);
+ yaml_parser_set_input_string(&parser, buffer, 3+LONG*2);
+ for (k = 0; k < LONG; k++) {
+ if (!parser.unread) {
+ if (!yaml_parser_update_buffer(&parser, 1)) {
+ printf("\treader error: %s at %d\n", parser.problem, parser.problem_offset);
+ failed = 1;
+ break;
+ }
+ }
+ if (!parser.unread) {
+ printf("\tnot enough characters at %d\n", k);
+ failed = 1;
+ break;
+ }
+ if (k % 2) {
+ ch0 = '\xd0';
+ ch1 = '\x90';
+ }
+ else {
+ ch0 = '\xd0';
+ ch1 = '\xaf';
+ }
+ if (parser.buffer.pointer[0] != ch0 || parser.buffer.pointer[1] != ch1) {
+ printf("\tincorrect UTF-8 sequence: %X %X instead of %X %X\n",
+ (int)parser.buffer.pointer[0], (int)parser.buffer.pointer[1],
+ (int)ch0, (int)ch1);
+ failed = 1;
+ break;
+ }
+ parser.buffer.pointer += 2;
+ parser.unread -= 1;
+ }
+ if (!failed) {
+ if (!yaml_parser_update_buffer(&parser, 1)) {
+ printf("\treader error: %s at %d\n", parser.problem, parser.problem_offset);
+ failed = 1;
+ }
+ else if (parser.buffer.pointer[0] != '\0') {
+ printf("\texpected NUL, found %X (eof=%d, unread=%d)\n", (int)parser.buffer.pointer[0], parser.eof, parser.unread);
+ failed = 1;
+ }
+ }
+ yaml_parser_delete(&parser);
+ free(buffer);
+ printf("checking a long utf8 sequence: %d fail(s)\n", failed);
+ return failed;
+}
+
+int check_long_utf16(void)
+{
+ yaml_parser_t parser;
+ int k = 0;
+ int j;
+ int failed = 0;
+ unsigned char ch0, ch1;
+ unsigned char *buffer = malloc(2+LONG*2);
+ assert(buffer);
+ printf("checking a long utf16 sequence...\n");
+ buffer[k++] = '\xff';
+ buffer[k++] = '\xfe';
+ for (j = 0; j < LONG; j ++) {
+ if (j % 2) {
+ buffer[k++] = '\x10';
+ buffer[k++] = '\x04';
+ }
+ else {
+ buffer[k++] = '/';
+ buffer[k++] = '\x04';
+ }
+ }
+ yaml_parser_initialize(&parser);
+ yaml_parser_set_input_string(&parser, buffer, 2+LONG*2);
+ for (k = 0; k < LONG; k++) {
+ if (!parser.unread) {
+ if (!yaml_parser_update_buffer(&parser, 1)) {
+ printf("\treader error: %s at %d\n", parser.problem, parser.problem_offset);
+ failed = 1;
+ break;
+ }
+ }
+ if (!parser.unread) {
+ printf("\tnot enough characters at %d\n", k);
+ failed = 1;
+ break;
+ }
+ if (k % 2) {
+ ch0 = '\xd0';
+ ch1 = '\x90';
+ }
+ else {
+ ch0 = '\xd0';
+ ch1 = '\xaf';
+ }
+ if (parser.buffer.pointer[0] != ch0 || parser.buffer.pointer[1] != ch1) {
+ printf("\tincorrect UTF-8 sequence: %X %X instead of %X %X\n",
+ (int)parser.buffer.pointer[0], (int)parser.buffer.pointer[1],
+ (int)ch0, (int)ch1);
+ failed = 1;
+ break;
+ }
+ parser.buffer.pointer += 2;
+ parser.unread -= 1;
+ }
+ if (!failed) {
+ if (!yaml_parser_update_buffer(&parser, 1)) {
+ printf("\treader error: %s at %d\n", parser.problem, parser.problem_offset);
+ failed = 1;
+ }
+ else if (parser.buffer.pointer[0] != '\0') {
+ printf("\texpected NUL, found %X (eof=%d, unread=%d)\n", (int)parser.buffer.pointer[0], parser.eof, parser.unread);
+ failed = 1;
+ }
+ }
+ yaml_parser_delete(&parser);
+ free(buffer);
+ printf("checking a long utf16 sequence: %d fail(s)\n", failed);
+ return failed;
+}
+
+int
+main(void)
+{
+ return check_utf8_sequences() + check_boms() + check_long_utf8() + check_long_utf16();
+}
diff --git a/contrib/libyaml/tests/test-version.c b/contrib/libyaml/tests/test-version.c
new file mode 100644
index 0000000..e3e4a16
--- /dev/null
+++ b/contrib/libyaml/tests/test-version.c
@@ -0,0 +1,29 @@
+#include <yaml.h>
+
+#include <stdlib.h>
+#include <stdio.h>
+
+#ifdef NDEBUG
+#undef NDEBUG
+#endif
+#include <assert.h>
+
+int
+main(void)
+{
+ int major = -1;
+ int minor = -1;
+ int patch = -1;
+ char buf[64];
+
+ yaml_get_version(&major, &minor, &patch);
+ sprintf(buf, "%d.%d.%d", major, minor, patch);
+ assert(strcmp(buf, yaml_get_version_string()) == 0);
+
+ /* Print structure sizes. */
+ printf("sizeof(token) = %d\n", sizeof(yaml_token_t));
+ printf("sizeof(event) = %d\n", sizeof(yaml_event_t));
+ printf("sizeof(parser) = %d\n", sizeof(yaml_parser_t));
+
+ return 0;
+}
diff --git a/contrib/libyaml/win32/Makefile.am b/contrib/libyaml/win32/Makefile.am
new file mode 100644
index 0000000..d225c3e
--- /dev/null
+++ b/contrib/libyaml/win32/Makefile.am
@@ -0,0 +1,24 @@
+
+VC6_FILES = vc6/libyaml.dsw vc6/yaml.dsp vc6/yamldll.dsp \
+ vc6/test_version.dsp vc6/test_reader.dsp \
+ vc6/run_scanner.dsp vc6/run_parser.dsp \
+ vc6/run_loader.dsp vc6/run_emitter.dsp vc6/run_dumper.dsp \
+ vc6/example_reformatter.dsp vc6/example_reformatter_alt.dsp \
+ vc6/example_deconstructor.dsp vc6/example_deconstructor_alt.dsp
+
+VS2003_FILES = vs2003/libyaml.sln vs2003/yaml.vcproj vs2003/yamldll.vcproj \
+ vs2003/test_version.vcproj vs2003/test_reader.vcproj \
+ vs2003/run_scanner.vcproj vs2003/run_parser.vcproj \
+ vs2003/run_loader.vcproj vs2003/run_emitter.vcproj vs2003/run_dumper.vcproj \
+ vs2003/example_reformatter.vcproj vs2003/example_reformatter_alt.vcproj \
+ vs2003/example_deconstructor.vcproj vs2003/example_deconstructor_alt.vcproj
+
+VS2008_FILES = vs2008/libyaml.sln vs2008/yaml.vcproj vs2008/yamldll.vcproj \
+ vs2008/test_version.vcproj vs2008/test_reader.vcproj \
+ vs2008/run_scanner.vcproj vs2008/run_parser.vcproj \
+ vs2008/run_loader.vcproj vs2008/run_emitter.vcproj vs2008/run_dumper.vcproj \
+ vs2008/example_reformatter.vcproj vs2008/example_reformatter_alt.vcproj \
+ vs2008/example_deconstructor.vcproj vs2008/example_deconstructor_alt.vcproj
+
+EXTRA_DIST = config.h $(VC6_FILES) $(VS2003_FILES) $(VS2008_FILES)
+
diff --git a/contrib/libyaml/win32/Makefile.in b/contrib/libyaml/win32/Makefile.in
new file mode 100644
index 0000000..35ef58e
--- /dev/null
+++ b/contrib/libyaml/win32/Makefile.in
@@ -0,0 +1,374 @@
+# Makefile.in generated by automake 1.11.1 from Makefile.am.
+# @configure_input@
+
+# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
+# 2003, 2004, 2005, 2006, 2007, 2008, 2009 Free Software Foundation,
+# Inc.
+# This Makefile.in is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
+# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+# PARTICULAR PURPOSE.
+
+@SET_MAKE@
+VPATH = @srcdir@
+pkgdatadir = $(datadir)/@PACKAGE@
+pkgincludedir = $(includedir)/@PACKAGE@
+pkglibdir = $(libdir)/@PACKAGE@
+pkglibexecdir = $(libexecdir)/@PACKAGE@
+am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
+install_sh_DATA = $(install_sh) -c -m 644
+install_sh_PROGRAM = $(install_sh) -c
+install_sh_SCRIPT = $(install_sh) -c
+INSTALL_HEADER = $(INSTALL_DATA)
+transform = $(program_transform_name)
+NORMAL_INSTALL = :
+PRE_INSTALL = :
+POST_INSTALL = :
+NORMAL_UNINSTALL = :
+PRE_UNINSTALL = :
+POST_UNINSTALL = :
+build_triplet = @build@
+host_triplet = @host@
+subdir = win32
+DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in
+ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
+am__aclocal_m4_deps = $(top_srcdir)/configure.ac
+am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
+ $(ACLOCAL_M4)
+mkinstalldirs = $(install_sh) -d
+CONFIG_HEADER = $(top_builddir)/config.h
+CONFIG_CLEAN_FILES =
+CONFIG_CLEAN_VPATH_FILES =
+SOURCES =
+DIST_SOURCES =
+DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
+ACLOCAL = @ACLOCAL@
+AMTAR = @AMTAR@
+AR = @AR@
+AUTOCONF = @AUTOCONF@
+AUTOHEADER = @AUTOHEADER@
+AUTOMAKE = @AUTOMAKE@
+AWK = @AWK@
+CC = @CC@
+CCDEPMODE = @CCDEPMODE@
+CFLAGS = @CFLAGS@
+CPP = @CPP@
+CPPFLAGS = @CPPFLAGS@
+CYGPATH_W = @CYGPATH_W@
+DEFS = @DEFS@
+DEPDIR = @DEPDIR@
+DOXYGEN = @DOXYGEN@
+DSYMUTIL = @DSYMUTIL@
+DUMPBIN = @DUMPBIN@
+ECHO_C = @ECHO_C@
+ECHO_N = @ECHO_N@
+ECHO_T = @ECHO_T@
+EGREP = @EGREP@
+EXEEXT = @EXEEXT@
+FGREP = @FGREP@
+GREP = @GREP@
+INSTALL = @INSTALL@
+INSTALL_DATA = @INSTALL_DATA@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@
+INSTALL_SCRIPT = @INSTALL_SCRIPT@
+INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
+LD = @LD@
+LDFLAGS = @LDFLAGS@
+LIBOBJS = @LIBOBJS@
+LIBS = @LIBS@
+LIBTOOL = @LIBTOOL@
+LIPO = @LIPO@
+LN_S = @LN_S@
+LTLIBOBJS = @LTLIBOBJS@
+MAKEINFO = @MAKEINFO@
+MKDIR_P = @MKDIR_P@
+NM = @NM@
+NMEDIT = @NMEDIT@
+OBJDUMP = @OBJDUMP@
+OBJEXT = @OBJEXT@
+OTOOL = @OTOOL@
+OTOOL64 = @OTOOL64@
+PACKAGE = @PACKAGE@
+PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
+PACKAGE_NAME = @PACKAGE_NAME@
+PACKAGE_STRING = @PACKAGE_STRING@
+PACKAGE_TARNAME = @PACKAGE_TARNAME@
+PACKAGE_URL = @PACKAGE_URL@
+PACKAGE_VERSION = @PACKAGE_VERSION@
+PATH_SEPARATOR = @PATH_SEPARATOR@
+RANLIB = @RANLIB@
+SED = @SED@
+SET_MAKE = @SET_MAKE@
+SHELL = @SHELL@
+STRIP = @STRIP@
+VERSION = @VERSION@
+YAML_LT_AGE = @YAML_LT_AGE@
+YAML_LT_CURRENT = @YAML_LT_CURRENT@
+YAML_LT_RELEASE = @YAML_LT_RELEASE@
+YAML_LT_REVISION = @YAML_LT_REVISION@
+abs_builddir = @abs_builddir@
+abs_srcdir = @abs_srcdir@
+abs_top_builddir = @abs_top_builddir@
+abs_top_srcdir = @abs_top_srcdir@
+ac_ct_CC = @ac_ct_CC@
+ac_ct_DUMPBIN = @ac_ct_DUMPBIN@
+am__include = @am__include@
+am__leading_dot = @am__leading_dot@
+am__quote = @am__quote@
+am__tar = @am__tar@
+am__untar = @am__untar@
+bindir = @bindir@
+build = @build@
+build_alias = @build_alias@
+build_cpu = @build_cpu@
+build_os = @build_os@
+build_vendor = @build_vendor@
+builddir = @builddir@
+datadir = @datadir@
+datarootdir = @datarootdir@
+docdir = @docdir@
+dvidir = @dvidir@
+exec_prefix = @exec_prefix@
+host = @host@
+host_alias = @host_alias@
+host_cpu = @host_cpu@
+host_os = @host_os@
+host_vendor = @host_vendor@
+htmldir = @htmldir@
+includedir = @includedir@
+infodir = @infodir@
+install_sh = @install_sh@
+libdir = @libdir@
+libexecdir = @libexecdir@
+localedir = @localedir@
+localstatedir = @localstatedir@
+lt_ECHO = @lt_ECHO@
+mandir = @mandir@
+mkdir_p = @mkdir_p@
+oldincludedir = @oldincludedir@
+pdfdir = @pdfdir@
+prefix = @prefix@
+program_transform_name = @program_transform_name@
+psdir = @psdir@
+sbindir = @sbindir@
+sharedstatedir = @sharedstatedir@
+srcdir = @srcdir@
+sysconfdir = @sysconfdir@
+target_alias = @target_alias@
+top_build_prefix = @top_build_prefix@
+top_builddir = @top_builddir@
+top_srcdir = @top_srcdir@
+VC6_FILES = vc6/libyaml.dsw vc6/yaml.dsp vc6/yamldll.dsp \
+ vc6/test_version.dsp vc6/test_reader.dsp \
+ vc6/run_scanner.dsp vc6/run_parser.dsp \
+ vc6/run_loader.dsp vc6/run_emitter.dsp vc6/run_dumper.dsp \
+ vc6/example_reformatter.dsp vc6/example_reformatter_alt.dsp \
+ vc6/example_deconstructor.dsp vc6/example_deconstructor_alt.dsp
+
+VS2003_FILES = vs2003/libyaml.sln vs2003/yaml.vcproj vs2003/yamldll.vcproj \
+ vs2003/test_version.vcproj vs2003/test_reader.vcproj \
+ vs2003/run_scanner.vcproj vs2003/run_parser.vcproj \
+ vs2003/run_loader.vcproj vs2003/run_emitter.vcproj vs2003/run_dumper.vcproj \
+ vs2003/example_reformatter.vcproj vs2003/example_reformatter_alt.vcproj \
+ vs2003/example_deconstructor.vcproj vs2003/example_deconstructor_alt.vcproj
+
+VS2008_FILES = vs2008/libyaml.sln vs2008/yaml.vcproj vs2008/yamldll.vcproj \
+ vs2008/test_version.vcproj vs2008/test_reader.vcproj \
+ vs2008/run_scanner.vcproj vs2008/run_parser.vcproj \
+ vs2008/run_loader.vcproj vs2008/run_emitter.vcproj vs2008/run_dumper.vcproj \
+ vs2008/example_reformatter.vcproj vs2008/example_reformatter_alt.vcproj \
+ vs2008/example_deconstructor.vcproj vs2008/example_deconstructor_alt.vcproj
+
+EXTRA_DIST = config.h $(VC6_FILES) $(VS2003_FILES) $(VS2008_FILES)
+all: all-am
+
+.SUFFIXES:
+$(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps)
+ @for dep in $?; do \
+ case '$(am__configure_deps)' in \
+ *$$dep*) \
+ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \
+ && { if test -f $@; then exit 0; else break; fi; }; \
+ exit 1;; \
+ esac; \
+ done; \
+ echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign win32/Makefile'; \
+ $(am__cd) $(top_srcdir) && \
+ $(AUTOMAKE) --foreign win32/Makefile
+.PRECIOUS: Makefile
+Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
+ @case '$?' in \
+ *config.status*) \
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \
+ *) \
+ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \
+ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \
+ esac;
+
+$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+
+$(top_srcdir)/configure: $(am__configure_deps)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(ACLOCAL_M4): $(am__aclocal_m4_deps)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(am__aclocal_m4_deps):
+
+mostlyclean-libtool:
+ -rm -f *.lo
+
+clean-libtool:
+ -rm -rf .libs _libs
+tags: TAGS
+TAGS:
+
+ctags: CTAGS
+CTAGS:
+
+
+distdir: $(DISTFILES)
+ @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+ list='$(DISTFILES)'; \
+ dist_files=`for file in $$list; do echo $$file; done | \
+ sed -e "s|^$$srcdirstrip/||;t" \
+ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \
+ case $$dist_files in \
+ */*) $(MKDIR_P) `echo "$$dist_files" | \
+ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \
+ sort -u` ;; \
+ esac; \
+ for file in $$dist_files; do \
+ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
+ if test -d $$d/$$file; then \
+ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \
+ if test -d "$(distdir)/$$file"; then \
+ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
+ fi; \
+ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
+ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \
+ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
+ fi; \
+ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \
+ else \
+ test -f "$(distdir)/$$file" \
+ || cp -p $$d/$$file "$(distdir)/$$file" \
+ || exit 1; \
+ fi; \
+ done
+check-am: all-am
+check: check-am
+all-am: Makefile
+installdirs:
+install: install-am
+install-exec: install-exec-am
+install-data: install-data-am
+uninstall: uninstall-am
+
+install-am: all-am
+ @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
+
+installcheck: installcheck-am
+install-strip:
+ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+ `test -z '$(STRIP)' || \
+ echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install
+mostlyclean-generic:
+
+clean-generic:
+
+distclean-generic:
+ -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
+ -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES)
+
+maintainer-clean-generic:
+ @echo "This command is intended for maintainers to use"
+ @echo "it deletes files that may require special tools to rebuild."
+clean: clean-am
+
+clean-am: clean-generic clean-libtool mostlyclean-am
+
+distclean: distclean-am
+ -rm -f Makefile
+distclean-am: clean-am distclean-generic
+
+dvi: dvi-am
+
+dvi-am:
+
+html: html-am
+
+html-am:
+
+info: info-am
+
+info-am:
+
+install-data-am:
+
+install-dvi: install-dvi-am
+
+install-dvi-am:
+
+install-exec-am:
+
+install-html: install-html-am
+
+install-html-am:
+
+install-info: install-info-am
+
+install-info-am:
+
+install-man:
+
+install-pdf: install-pdf-am
+
+install-pdf-am:
+
+install-ps: install-ps-am
+
+install-ps-am:
+
+installcheck-am:
+
+maintainer-clean: maintainer-clean-am
+ -rm -f Makefile
+maintainer-clean-am: distclean-am maintainer-clean-generic
+
+mostlyclean: mostlyclean-am
+
+mostlyclean-am: mostlyclean-generic mostlyclean-libtool
+
+pdf: pdf-am
+
+pdf-am:
+
+ps: ps-am
+
+ps-am:
+
+uninstall-am:
+
+.MAKE: install-am install-strip
+
+.PHONY: all all-am check check-am clean clean-generic clean-libtool \
+ distclean distclean-generic distclean-libtool distdir dvi \
+ dvi-am html html-am info info-am install install-am \
+ install-data install-data-am install-dvi install-dvi-am \
+ install-exec install-exec-am install-html install-html-am \
+ install-info install-info-am install-man install-pdf \
+ install-pdf-am install-ps install-ps-am install-strip \
+ installcheck installcheck-am installdirs maintainer-clean \
+ maintainer-clean-generic mostlyclean mostlyclean-generic \
+ mostlyclean-libtool pdf pdf-am ps ps-am uninstall uninstall-am
+
+
+# Tell versions [3.59,3.63) of GNU make to not export all variables.
+# Otherwise a system limit (for SysV at least) may be exceeded.
+.NOEXPORT:
diff --git a/contrib/libyaml/win32/config.h b/contrib/libyaml/win32/config.h
new file mode 100644
index 0000000..731b62d
--- /dev/null
+++ b/contrib/libyaml/win32/config.h
@@ -0,0 +1,4 @@
+#define YAML_VERSION_MAJOR 0
+#define YAML_VERSION_MINOR 1
+#define YAML_VERSION_PATCH 4
+#define YAML_VERSION_STRING "0.1.4"
diff --git a/contrib/libyaml/win32/vc6/example_deconstructor.dsp b/contrib/libyaml/win32/vc6/example_deconstructor.dsp
new file mode 100644
index 0000000..aafde40
--- /dev/null
+++ b/contrib/libyaml/win32/vc6/example_deconstructor.dsp
@@ -0,0 +1,102 @@
+# Microsoft Developer Studio Project File - Name="example_deconstructor" - Package Owner=<4>
+# Microsoft Developer Studio Generated Build File, Format Version 6.00
+# ** DO NOT EDIT **
+
+# TARGTYPE "Win32 (x86) Console Application" 0x0103
+
+CFG=example_deconstructor - Win32 Debug
+!MESSAGE This is not a valid makefile. To build this project using NMAKE,
+!MESSAGE use the Export Makefile command and run
+!MESSAGE
+!MESSAGE NMAKE /f "example_deconstructor.mak".
+!MESSAGE
+!MESSAGE You can specify a configuration when running NMAKE
+!MESSAGE by defining the macro CFG on the command line. For example:
+!MESSAGE
+!MESSAGE NMAKE /f "example_deconstructor.mak" CFG="example_deconstructor - Win32 Debug"
+!MESSAGE
+!MESSAGE Possible choices for configuration are:
+!MESSAGE
+!MESSAGE "example_deconstructor - Win32 Release" (based on "Win32 (x86) Console Application")
+!MESSAGE "example_deconstructor - Win32 Debug" (based on "Win32 (x86) Console Application")
+!MESSAGE
+
+# Begin Project
+# PROP AllowPerConfigDependencies 0
+# PROP Scc_ProjName ""
+# PROP Scc_LocalPath ""
+CPP=cl.exe
+RSC=rc.exe
+
+!IF "$(CFG)" == "example_deconstructor - Win32 Release"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 0
+# PROP BASE Output_Dir "Release"
+# PROP BASE Intermediate_Dir "Release"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 0
+# PROP Output_Dir "Output/Release/bin"
+# PROP Intermediate_Dir "Build/Release/bin"
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
+# ADD CPP /nologo /MD /W3 /GX /O2 /I "../../include" /D "NDEBUG" /D "WIN32" /D "_CONSOLE" /D "_MBCS" /D "YAML_DECLARE_STATIC" /YX /FD /c
+# ADD BASE RSC /l 0x409 /d "NDEBUG"
+# ADD RSC /l 0x409 /d "NDEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386
+# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386
+
+!ELSEIF "$(CFG)" == "example_deconstructor - Win32 Debug"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 1
+# PROP BASE Output_Dir "Debug"
+# PROP BASE Intermediate_Dir "Debug"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 1
+# PROP Output_Dir "Output/Debug/bin"
+# PROP Intermediate_Dir "Build/Debug/bin"
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c
+# ADD CPP /nologo /MDd /W3 /Gm /GX /ZI /Od /I "../../include" /D "_DEBUG" /D "WIN32" /D "_CONSOLE" /D "_MBCS" /D "YAML_DECLARE_STATIC" /YX /FD /GZ /c
+# ADD BASE RSC /l 0x409 /d "_DEBUG"
+# ADD RSC /l 0x409 /d "_DEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept
+# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept
+
+!ENDIF
+
+# Begin Target
+
+# Name "example_deconstructor - Win32 Release"
+# Name "example_deconstructor - Win32 Debug"
+# Begin Group "Source Files"
+
+# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"
+# Begin Source File
+
+SOURCE="..\..\tests\example-deconstructor.c"
+# End Source File
+# End Group
+# Begin Group "Header Files"
+
+# PROP Default_Filter "h;hpp;hxx;hm;inl"
+# End Group
+# Begin Group "Resource Files"
+
+# PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe"
+# End Group
+# End Target
+# End Project
diff --git a/contrib/libyaml/win32/vc6/example_deconstructor_alt.dsp b/contrib/libyaml/win32/vc6/example_deconstructor_alt.dsp
new file mode 100644
index 0000000..8540fcb
--- /dev/null
+++ b/contrib/libyaml/win32/vc6/example_deconstructor_alt.dsp
@@ -0,0 +1,102 @@
+# Microsoft Developer Studio Project File - Name="example_deconstructor_alt" - Package Owner=<4>
+# Microsoft Developer Studio Generated Build File, Format Version 6.00
+# ** DO NOT EDIT **
+
+# TARGTYPE "Win32 (x86) Console Application" 0x0103
+
+CFG=example_deconstructor_alt - Win32 Debug
+!MESSAGE This is not a valid makefile. To build this project using NMAKE,
+!MESSAGE use the Export Makefile command and run
+!MESSAGE
+!MESSAGE NMAKE /f "example_deconstructor_alt.mak".
+!MESSAGE
+!MESSAGE You can specify a configuration when running NMAKE
+!MESSAGE by defining the macro CFG on the command line. For example:
+!MESSAGE
+!MESSAGE NMAKE /f "example_deconstructor_alt.mak" CFG="example_deconstructor_alt - Win32 Debug"
+!MESSAGE
+!MESSAGE Possible choices for configuration are:
+!MESSAGE
+!MESSAGE "example_deconstructor_alt - Win32 Release" (based on "Win32 (x86) Console Application")
+!MESSAGE "example_deconstructor_alt - Win32 Debug" (based on "Win32 (x86) Console Application")
+!MESSAGE
+
+# Begin Project
+# PROP AllowPerConfigDependencies 0
+# PROP Scc_ProjName ""
+# PROP Scc_LocalPath ""
+CPP=cl.exe
+RSC=rc.exe
+
+!IF "$(CFG)" == "example_deconstructor_alt - Win32 Release"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 0
+# PROP BASE Output_Dir "Release"
+# PROP BASE Intermediate_Dir "Release"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 0
+# PROP Output_Dir "Output/Release/bin"
+# PROP Intermediate_Dir "Build/Release/bin"
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
+# ADD CPP /nologo /MD /W3 /GX /O2 /I "../../include" /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /D "YAML_DECLARE_STATIC" /YX /FD /c
+# ADD BASE RSC /l 0x409 /d "NDEBUG"
+# ADD RSC /l 0x409 /d "NDEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386
+# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386
+
+!ELSEIF "$(CFG)" == "example_deconstructor_alt - Win32 Debug"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 1
+# PROP BASE Output_Dir "Debug"
+# PROP BASE Intermediate_Dir "Debug"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 1
+# PROP Output_Dir "Output/Debug/bin"
+# PROP Intermediate_Dir "Build/Debug/bin"
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c
+# ADD CPP /nologo /MDd /W3 /Gm /GX /ZI /Od /I "../../include" /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /D "YAML_DECLARE_STATIC" /YX /FD /GZ /c
+# ADD BASE RSC /l 0x409 /d "_DEBUG"
+# ADD RSC /l 0x409 /d "_DEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept
+# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept
+
+!ENDIF
+
+# Begin Target
+
+# Name "example_deconstructor_alt - Win32 Release"
+# Name "example_deconstructor_alt - Win32 Debug"
+# Begin Group "Source Files"
+
+# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"
+# Begin Source File
+
+SOURCE="..\..\tests\example-deconstructor-alt.c"
+# End Source File
+# End Group
+# Begin Group "Header Files"
+
+# PROP Default_Filter "h;hpp;hxx;hm;inl"
+# End Group
+# Begin Group "Resource Files"
+
+# PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe"
+# End Group
+# End Target
+# End Project
diff --git a/contrib/libyaml/win32/vc6/example_reformatter.dsp b/contrib/libyaml/win32/vc6/example_reformatter.dsp
new file mode 100644
index 0000000..8ddafb2
--- /dev/null
+++ b/contrib/libyaml/win32/vc6/example_reformatter.dsp
@@ -0,0 +1,102 @@
+# Microsoft Developer Studio Project File - Name="example_reformatter" - Package Owner=<4>
+# Microsoft Developer Studio Generated Build File, Format Version 6.00
+# ** DO NOT EDIT **
+
+# TARGTYPE "Win32 (x86) Console Application" 0x0103
+
+CFG=example_reformatter - Win32 Debug
+!MESSAGE This is not a valid makefile. To build this project using NMAKE,
+!MESSAGE use the Export Makefile command and run
+!MESSAGE
+!MESSAGE NMAKE /f "example_reformatter.mak".
+!MESSAGE
+!MESSAGE You can specify a configuration when running NMAKE
+!MESSAGE by defining the macro CFG on the command line. For example:
+!MESSAGE
+!MESSAGE NMAKE /f "example_reformatter.mak" CFG="example_reformatter - Win32 Debug"
+!MESSAGE
+!MESSAGE Possible choices for configuration are:
+!MESSAGE
+!MESSAGE "example_reformatter - Win32 Release" (based on "Win32 (x86) Console Application")
+!MESSAGE "example_reformatter - Win32 Debug" (based on "Win32 (x86) Console Application")
+!MESSAGE
+
+# Begin Project
+# PROP AllowPerConfigDependencies 0
+# PROP Scc_ProjName ""
+# PROP Scc_LocalPath ""
+CPP=cl.exe
+RSC=rc.exe
+
+!IF "$(CFG)" == "example_reformatter - Win32 Release"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 0
+# PROP BASE Output_Dir "Release"
+# PROP BASE Intermediate_Dir "Release"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 0
+# PROP Output_Dir "Output/Release/bin"
+# PROP Intermediate_Dir "Build/Release/bin"
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
+# ADD CPP /nologo /MD /W3 /GX /O2 /I "../../include" /D "NDEBUG" /D "WIN32" /D "_CONSOLE" /D "_MBCS" /D "YAML_DECLARE_STATIC" /YX /FD /c
+# ADD BASE RSC /l 0x409 /d "NDEBUG"
+# ADD RSC /l 0x409 /d "NDEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386
+# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386
+
+!ELSEIF "$(CFG)" == "example_reformatter - Win32 Debug"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 1
+# PROP BASE Output_Dir "Debug"
+# PROP BASE Intermediate_Dir "Debug"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 1
+# PROP Output_Dir "Output/Debug/bin"
+# PROP Intermediate_Dir "Build/Debug/bin"
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c
+# ADD CPP /nologo /MDd /W3 /Gm /GX /ZI /Od /I "../../include" /D "_DEBUG" /D "WIN32" /D "_CONSOLE" /D "_MBCS" /D "YAML_DECLARE_STATIC" /YX /FD /GZ /c
+# ADD BASE RSC /l 0x409 /d "_DEBUG"
+# ADD RSC /l 0x409 /d "_DEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept
+# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept
+
+!ENDIF
+
+# Begin Target
+
+# Name "example_reformatter - Win32 Release"
+# Name "example_reformatter - Win32 Debug"
+# Begin Group "Source Files"
+
+# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"
+# Begin Source File
+
+SOURCE="..\..\tests\example-reformatter.c"
+# End Source File
+# End Group
+# Begin Group "Header Files"
+
+# PROP Default_Filter "h;hpp;hxx;hm;inl"
+# End Group
+# Begin Group "Resource Files"
+
+# PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe"
+# End Group
+# End Target
+# End Project
diff --git a/contrib/libyaml/win32/vc6/example_reformatter_alt.dsp b/contrib/libyaml/win32/vc6/example_reformatter_alt.dsp
new file mode 100644
index 0000000..cc08a26
--- /dev/null
+++ b/contrib/libyaml/win32/vc6/example_reformatter_alt.dsp
@@ -0,0 +1,102 @@
+# Microsoft Developer Studio Project File - Name="example_reformatter_alt" - Package Owner=<4>
+# Microsoft Developer Studio Generated Build File, Format Version 6.00
+# ** DO NOT EDIT **
+
+# TARGTYPE "Win32 (x86) Console Application" 0x0103
+
+CFG=example_reformatter_alt - Win32 Debug
+!MESSAGE This is not a valid makefile. To build this project using NMAKE,
+!MESSAGE use the Export Makefile command and run
+!MESSAGE
+!MESSAGE NMAKE /f "example_reformatter_alt.mak".
+!MESSAGE
+!MESSAGE You can specify a configuration when running NMAKE
+!MESSAGE by defining the macro CFG on the command line. For example:
+!MESSAGE
+!MESSAGE NMAKE /f "example_reformatter_alt.mak" CFG="example_reformatter_alt - Win32 Debug"
+!MESSAGE
+!MESSAGE Possible choices for configuration are:
+!MESSAGE
+!MESSAGE "example_reformatter_alt - Win32 Release" (based on "Win32 (x86) Console Application")
+!MESSAGE "example_reformatter_alt - Win32 Debug" (based on "Win32 (x86) Console Application")
+!MESSAGE
+
+# Begin Project
+# PROP AllowPerConfigDependencies 0
+# PROP Scc_ProjName ""
+# PROP Scc_LocalPath ""
+CPP=cl.exe
+RSC=rc.exe
+
+!IF "$(CFG)" == "example_reformatter_alt - Win32 Release"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 0
+# PROP BASE Output_Dir "Release"
+# PROP BASE Intermediate_Dir "Release"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 0
+# PROP Output_Dir "Output/Release/bin"
+# PROP Intermediate_Dir "Build/Release/bin"
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
+# ADD CPP /nologo /MD /W3 /GX /O2 /I "../../include" /D "NDEBUG" /D "WIN32" /D "_CONSOLE" /D "_MBCS" /D "YAML_DECLARE_STATIC" /YX /FD /c
+# ADD BASE RSC /l 0x409 /d "NDEBUG"
+# ADD RSC /l 0x409 /d "NDEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386
+# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386
+
+!ELSEIF "$(CFG)" == "example_reformatter_alt - Win32 Debug"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 1
+# PROP BASE Output_Dir "Debug"
+# PROP BASE Intermediate_Dir "Debug"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 1
+# PROP Output_Dir "Output/Debug/bin"
+# PROP Intermediate_Dir "Build/Debug/bin"
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c
+# ADD CPP /nologo /MDd /W3 /Gm /GX /ZI /Od /I "../../include" /D "_DEBUG" /D "WIN32" /D "_CONSOLE" /D "_MBCS" /D "YAML_DECLARE_STATIC" /YX /FD /GZ /c
+# ADD BASE RSC /l 0x409 /d "_DEBUG"
+# ADD RSC /l 0x409 /d "_DEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept
+# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept
+
+!ENDIF
+
+# Begin Target
+
+# Name "example_reformatter_alt - Win32 Release"
+# Name "example_reformatter_alt - Win32 Debug"
+# Begin Group "Source Files"
+
+# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"
+# Begin Source File
+
+SOURCE="..\..\tests\example-reformatter-alt.c"
+# End Source File
+# End Group
+# Begin Group "Header Files"
+
+# PROP Default_Filter "h;hpp;hxx;hm;inl"
+# End Group
+# Begin Group "Resource Files"
+
+# PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe"
+# End Group
+# End Target
+# End Project
diff --git a/contrib/libyaml/win32/vc6/libyaml.dsw b/contrib/libyaml/win32/vc6/libyaml.dsw
new file mode 100644
index 0000000..6981318
--- /dev/null
+++ b/contrib/libyaml/win32/vc6/libyaml.dsw
@@ -0,0 +1,206 @@
+Microsoft Developer Studio Workspace File, Format Version 6.00
+# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE!
+
+###############################################################################
+
+Project: "example_deconstructor"=".\example_deconstructor.dsp" - Package Owner=<4>
+
+Package=<5>
+{{{
+}}}
+
+Package=<4>
+{{{
+ Begin Project Dependency
+ Project_Dep_Name yaml
+ End Project Dependency
+}}}
+
+###############################################################################
+
+Project: "example_deconstructor_alt"=".\example_deconstructor_alt.dsp" - Package Owner=<4>
+
+Package=<5>
+{{{
+}}}
+
+Package=<4>
+{{{
+ Begin Project Dependency
+ Project_Dep_Name yaml
+ End Project Dependency
+}}}
+
+###############################################################################
+
+Project: "example_reformatter"=".\example_reformatter.dsp" - Package Owner=<4>
+
+Package=<5>
+{{{
+}}}
+
+Package=<4>
+{{{
+ Begin Project Dependency
+ Project_Dep_Name yaml
+ End Project Dependency
+}}}
+
+###############################################################################
+
+Project: "example_reformatter_alt"=".\example_reformatter_alt.dsp" - Package Owner=<4>
+
+Package=<5>
+{{{
+}}}
+
+Package=<4>
+{{{
+ Begin Project Dependency
+ Project_Dep_Name yaml
+ End Project Dependency
+}}}
+
+###############################################################################
+
+Project: "run_dumper"=".\run_dumper.dsp" - Package Owner=<4>
+
+Package=<5>
+{{{
+}}}
+
+Package=<4>
+{{{
+ Begin Project Dependency
+ Project_Dep_Name yaml
+ End Project Dependency
+}}}
+
+###############################################################################
+
+Project: "run_emitter"=".\run_emitter.dsp" - Package Owner=<4>
+
+Package=<5>
+{{{
+}}}
+
+Package=<4>
+{{{
+ Begin Project Dependency
+ Project_Dep_Name yaml
+ End Project Dependency
+}}}
+
+###############################################################################
+
+Project: "run_loader"=".\run_loader.dsp" - Package Owner=<4>
+
+Package=<5>
+{{{
+}}}
+
+Package=<4>
+{{{
+ Begin Project Dependency
+ Project_Dep_Name yaml
+ End Project Dependency
+}}}
+
+###############################################################################
+
+Project: "run_parser"=".\run_parser.dsp" - Package Owner=<4>
+
+Package=<5>
+{{{
+}}}
+
+Package=<4>
+{{{
+ Begin Project Dependency
+ Project_Dep_Name yaml
+ End Project Dependency
+}}}
+
+###############################################################################
+
+Project: "run_scanner"=".\run_scanner.dsp" - Package Owner=<4>
+
+Package=<5>
+{{{
+}}}
+
+Package=<4>
+{{{
+ Begin Project Dependency
+ Project_Dep_Name yaml
+ End Project Dependency
+}}}
+
+###############################################################################
+
+Project: "test_reader"=".\test_reader.dsp" - Package Owner=<4>
+
+Package=<5>
+{{{
+}}}
+
+Package=<4>
+{{{
+ Begin Project Dependency
+ Project_Dep_Name yaml
+ End Project Dependency
+}}}
+
+###############################################################################
+
+Project: "test_version"=".\test_version.dsp" - Package Owner=<4>
+
+Package=<5>
+{{{
+}}}
+
+Package=<4>
+{{{
+ Begin Project Dependency
+ Project_Dep_Name yaml
+ End Project Dependency
+}}}
+
+###############################################################################
+
+Project: "yaml"=".\yaml.dsp" - Package Owner=<4>
+
+Package=<5>
+{{{
+}}}
+
+Package=<4>
+{{{
+}}}
+
+###############################################################################
+
+Project: "yamldll"=".\yamldll.dsp" - Package Owner=<4>
+
+Package=<5>
+{{{
+}}}
+
+Package=<4>
+{{{
+}}}
+
+###############################################################################
+
+Global:
+
+Package=<5>
+{{{
+}}}
+
+Package=<3>
+{{{
+}}}
+
+###############################################################################
+
diff --git a/contrib/libyaml/win32/vc6/run_dumper.dsp b/contrib/libyaml/win32/vc6/run_dumper.dsp
new file mode 100644
index 0000000..fea12a8
--- /dev/null
+++ b/contrib/libyaml/win32/vc6/run_dumper.dsp
@@ -0,0 +1,102 @@
+# Microsoft Developer Studio Project File - Name="run_dumper" - Package Owner=<4>
+# Microsoft Developer Studio Generated Build File, Format Version 6.00
+# ** DO NOT EDIT **
+
+# TARGTYPE "Win32 (x86) Console Application" 0x0103
+
+CFG=run_dumper - Win32 Debug
+!MESSAGE This is not a valid makefile. To build this project using NMAKE,
+!MESSAGE use the Export Makefile command and run
+!MESSAGE
+!MESSAGE NMAKE /f "run_dumper.mak".
+!MESSAGE
+!MESSAGE You can specify a configuration when running NMAKE
+!MESSAGE by defining the macro CFG on the command line. For example:
+!MESSAGE
+!MESSAGE NMAKE /f "run_dumper.mak" CFG="run_dumper - Win32 Debug"
+!MESSAGE
+!MESSAGE Possible choices for configuration are:
+!MESSAGE
+!MESSAGE "run_dumper - Win32 Release" (based on "Win32 (x86) Console Application")
+!MESSAGE "run_dumper - Win32 Debug" (based on "Win32 (x86) Console Application")
+!MESSAGE
+
+# Begin Project
+# PROP AllowPerConfigDependencies 0
+# PROP Scc_ProjName ""
+# PROP Scc_LocalPath ""
+CPP=cl.exe
+RSC=rc.exe
+
+!IF "$(CFG)" == "run_dumper - Win32 Release"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 0
+# PROP BASE Output_Dir "Release"
+# PROP BASE Intermediate_Dir "Release"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 0
+# PROP Output_Dir "Output/Release/bin"
+# PROP Intermediate_Dir "Build/Release/bin"
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
+# ADD CPP /nologo /MD /W3 /GX /O2 /I "../../include" /D "NDEBUG" /D "WIN32" /D "_CONSOLE" /D "_MBCS" /D "YAML_DECLARE_STATIC" /YX /FD /c
+# ADD BASE RSC /l 0x409 /d "NDEBUG"
+# ADD RSC /l 0x409 /d "NDEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386
+# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386
+
+!ELSEIF "$(CFG)" == "run_dumper - Win32 Debug"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 1
+# PROP BASE Output_Dir "Debug"
+# PROP BASE Intermediate_Dir "Debug"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 1
+# PROP Output_Dir "Output/Debug/bin"
+# PROP Intermediate_Dir "Build/Debug/bin"
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c
+# ADD CPP /nologo /MDd /W3 /Gm /GX /ZI /Od /I "../../include" /D "_DEBUG" /D "WIN32" /D "_CONSOLE" /D "_MBCS" /D "YAML_DECLARE_STATIC" /YX /FD /GZ /c
+# ADD BASE RSC /l 0x409 /d "_DEBUG"
+# ADD RSC /l 0x409 /d "_DEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept
+# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept
+
+!ENDIF
+
+# Begin Target
+
+# Name "run_dumper - Win32 Release"
+# Name "run_dumper - Win32 Debug"
+# Begin Group "Source Files"
+
+# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"
+# Begin Source File
+
+SOURCE="..\..\tests\run-dumper.c"
+# End Source File
+# End Group
+# Begin Group "Header Files"
+
+# PROP Default_Filter "h;hpp;hxx;hm;inl"
+# End Group
+# Begin Group "Resource Files"
+
+# PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe"
+# End Group
+# End Target
+# End Project
diff --git a/contrib/libyaml/win32/vc6/run_emitter.dsp b/contrib/libyaml/win32/vc6/run_emitter.dsp
new file mode 100644
index 0000000..e5793a9
--- /dev/null
+++ b/contrib/libyaml/win32/vc6/run_emitter.dsp
@@ -0,0 +1,102 @@
+# Microsoft Developer Studio Project File - Name="run_emitter" - Package Owner=<4>
+# Microsoft Developer Studio Generated Build File, Format Version 6.00
+# ** DO NOT EDIT **
+
+# TARGTYPE "Win32 (x86) Console Application" 0x0103
+
+CFG=run_emitter - Win32 Debug
+!MESSAGE This is not a valid makefile. To build this project using NMAKE,
+!MESSAGE use the Export Makefile command and run
+!MESSAGE
+!MESSAGE NMAKE /f "run_emitter.mak".
+!MESSAGE
+!MESSAGE You can specify a configuration when running NMAKE
+!MESSAGE by defining the macro CFG on the command line. For example:
+!MESSAGE
+!MESSAGE NMAKE /f "run_emitter.mak" CFG="run_emitter - Win32 Debug"
+!MESSAGE
+!MESSAGE Possible choices for configuration are:
+!MESSAGE
+!MESSAGE "run_emitter - Win32 Release" (based on "Win32 (x86) Console Application")
+!MESSAGE "run_emitter - Win32 Debug" (based on "Win32 (x86) Console Application")
+!MESSAGE
+
+# Begin Project
+# PROP AllowPerConfigDependencies 0
+# PROP Scc_ProjName ""
+# PROP Scc_LocalPath ""
+CPP=cl.exe
+RSC=rc.exe
+
+!IF "$(CFG)" == "run_emitter - Win32 Release"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 0
+# PROP BASE Output_Dir "Release"
+# PROP BASE Intermediate_Dir "Release"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 0
+# PROP Output_Dir "Output/Release/bin"
+# PROP Intermediate_Dir "Build/Release/bin"
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
+# ADD CPP /nologo /MD /W3 /GX /O2 /I "../../include" /D "NDEBUG" /D "WIN32" /D "_CONSOLE" /D "_MBCS" /D "YAML_DECLARE_STATIC" /YX /FD /c
+# ADD BASE RSC /l 0x409 /d "NDEBUG"
+# ADD RSC /l 0x409 /d "NDEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386
+# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386
+
+!ELSEIF "$(CFG)" == "run_emitter - Win32 Debug"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 1
+# PROP BASE Output_Dir "Debug"
+# PROP BASE Intermediate_Dir "Debug"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 1
+# PROP Output_Dir "Output/Debug/bin"
+# PROP Intermediate_Dir "Build/Debug/bin"
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c
+# ADD CPP /nologo /MDd /W3 /Gm /GX /ZI /Od /I "../../include" /D "_DEBUG" /D "WIN32" /D "_CONSOLE" /D "_MBCS" /D "YAML_DECLARE_STATIC" /YX /FD /GZ /c
+# ADD BASE RSC /l 0x409 /d "_DEBUG"
+# ADD RSC /l 0x409 /d "_DEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept
+# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept
+
+!ENDIF
+
+# Begin Target
+
+# Name "run_emitter - Win32 Release"
+# Name "run_emitter - Win32 Debug"
+# Begin Group "Source Files"
+
+# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"
+# Begin Source File
+
+SOURCE="..\..\tests\run-emitter.c"
+# End Source File
+# End Group
+# Begin Group "Header Files"
+
+# PROP Default_Filter "h;hpp;hxx;hm;inl"
+# End Group
+# Begin Group "Resource Files"
+
+# PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe"
+# End Group
+# End Target
+# End Project
diff --git a/contrib/libyaml/win32/vc6/run_loader.dsp b/contrib/libyaml/win32/vc6/run_loader.dsp
new file mode 100644
index 0000000..3f6cd44
--- /dev/null
+++ b/contrib/libyaml/win32/vc6/run_loader.dsp
@@ -0,0 +1,102 @@
+# Microsoft Developer Studio Project File - Name="run_loader" - Package Owner=<4>
+# Microsoft Developer Studio Generated Build File, Format Version 6.00
+# ** DO NOT EDIT **
+
+# TARGTYPE "Win32 (x86) Console Application" 0x0103
+
+CFG=run_loader - Win32 Debug
+!MESSAGE This is not a valid makefile. To build this project using NMAKE,
+!MESSAGE use the Export Makefile command and run
+!MESSAGE
+!MESSAGE NMAKE /f "run_loader.mak".
+!MESSAGE
+!MESSAGE You can specify a configuration when running NMAKE
+!MESSAGE by defining the macro CFG on the command line. For example:
+!MESSAGE
+!MESSAGE NMAKE /f "run_loader.mak" CFG="run_loader - Win32 Debug"
+!MESSAGE
+!MESSAGE Possible choices for configuration are:
+!MESSAGE
+!MESSAGE "run_loader - Win32 Release" (based on "Win32 (x86) Console Application")
+!MESSAGE "run_loader - Win32 Debug" (based on "Win32 (x86) Console Application")
+!MESSAGE
+
+# Begin Project
+# PROP AllowPerConfigDependencies 0
+# PROP Scc_ProjName ""
+# PROP Scc_LocalPath ""
+CPP=cl.exe
+RSC=rc.exe
+
+!IF "$(CFG)" == "run_loader - Win32 Release"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 0
+# PROP BASE Output_Dir "Release"
+# PROP BASE Intermediate_Dir "Release"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 0
+# PROP Output_Dir "Output/Release/bin"
+# PROP Intermediate_Dir "Build/Release/bin"
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
+# ADD CPP /nologo /MD /W3 /GX /O2 /I "../../include" /D "NDEBUG" /D "WIN32" /D "_CONSOLE" /D "_MBCS" /D "YAML_DECLARE_STATIC" /YX /FD /c
+# ADD BASE RSC /l 0x409 /d "NDEBUG"
+# ADD RSC /l 0x409 /d "NDEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386
+# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386
+
+!ELSEIF "$(CFG)" == "run_loader - Win32 Debug"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 1
+# PROP BASE Output_Dir "Debug"
+# PROP BASE Intermediate_Dir "Debug"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 1
+# PROP Output_Dir "Output/Debug/bin"
+# PROP Intermediate_Dir "Build/Debug/bin"
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c
+# ADD CPP /nologo /MDd /W3 /Gm /GX /ZI /Od /I "../../include" /D "_DEBUG" /D "WIN32" /D "_CONSOLE" /D "_MBCS" /D "YAML_DECLARE_STATIC" /YX /FD /GZ /c
+# ADD BASE RSC /l 0x409 /d "_DEBUG"
+# ADD RSC /l 0x409 /d "_DEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept
+# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept
+
+!ENDIF
+
+# Begin Target
+
+# Name "run_loader - Win32 Release"
+# Name "run_loader - Win32 Debug"
+# Begin Group "Source Files"
+
+# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"
+# Begin Source File
+
+SOURCE="..\..\tests\run-loader.c"
+# End Source File
+# End Group
+# Begin Group "Header Files"
+
+# PROP Default_Filter "h;hpp;hxx;hm;inl"
+# End Group
+# Begin Group "Resource Files"
+
+# PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe"
+# End Group
+# End Target
+# End Project
diff --git a/contrib/libyaml/win32/vc6/run_parser.dsp b/contrib/libyaml/win32/vc6/run_parser.dsp
new file mode 100644
index 0000000..1b2dd20
--- /dev/null
+++ b/contrib/libyaml/win32/vc6/run_parser.dsp
@@ -0,0 +1,102 @@
+# Microsoft Developer Studio Project File - Name="run_parser" - Package Owner=<4>
+# Microsoft Developer Studio Generated Build File, Format Version 6.00
+# ** DO NOT EDIT **
+
+# TARGTYPE "Win32 (x86) Console Application" 0x0103
+
+CFG=run_parser - Win32 Debug
+!MESSAGE This is not a valid makefile. To build this project using NMAKE,
+!MESSAGE use the Export Makefile command and run
+!MESSAGE
+!MESSAGE NMAKE /f "run_parser.mak".
+!MESSAGE
+!MESSAGE You can specify a configuration when running NMAKE
+!MESSAGE by defining the macro CFG on the command line. For example:
+!MESSAGE
+!MESSAGE NMAKE /f "run_parser.mak" CFG="run_parser - Win32 Debug"
+!MESSAGE
+!MESSAGE Possible choices for configuration are:
+!MESSAGE
+!MESSAGE "run_parser - Win32 Release" (based on "Win32 (x86) Console Application")
+!MESSAGE "run_parser - Win32 Debug" (based on "Win32 (x86) Console Application")
+!MESSAGE
+
+# Begin Project
+# PROP AllowPerConfigDependencies 0
+# PROP Scc_ProjName ""
+# PROP Scc_LocalPath ""
+CPP=cl.exe
+RSC=rc.exe
+
+!IF "$(CFG)" == "run_parser - Win32 Release"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 0
+# PROP BASE Output_Dir "Release"
+# PROP BASE Intermediate_Dir "Release"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 0
+# PROP Output_Dir "Output/Release/bin"
+# PROP Intermediate_Dir "Build/Release/bin"
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
+# ADD CPP /nologo /MD /W3 /GX /O2 /I "../../include" /D "NDEBUG" /D "WIN32" /D "_CONSOLE" /D "_MBCS" /D "YAML_DECLARE_STATIC" /YX /FD /c
+# ADD BASE RSC /l 0x409 /d "NDEBUG"
+# ADD RSC /l 0x409 /d "NDEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386
+# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386
+
+!ELSEIF "$(CFG)" == "run_parser - Win32 Debug"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 1
+# PROP BASE Output_Dir "Debug"
+# PROP BASE Intermediate_Dir "Debug"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 1
+# PROP Output_Dir "Output/Debug/bin"
+# PROP Intermediate_Dir "Build/Debug/bin"
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c
+# ADD CPP /nologo /MDd /W3 /Gm /GX /ZI /Od /I "../../include" /D "_DEBUG" /D "WIN32" /D "_CONSOLE" /D "_MBCS" /D "YAML_DECLARE_STATIC" /YX /FD /GZ /c
+# ADD BASE RSC /l 0x409 /d "_DEBUG"
+# ADD RSC /l 0x409 /d "_DEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept
+# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept
+
+!ENDIF
+
+# Begin Target
+
+# Name "run_parser - Win32 Release"
+# Name "run_parser - Win32 Debug"
+# Begin Group "Source Files"
+
+# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"
+# Begin Source File
+
+SOURCE="..\..\tests\run-parser.c"
+# End Source File
+# End Group
+# Begin Group "Header Files"
+
+# PROP Default_Filter "h;hpp;hxx;hm;inl"
+# End Group
+# Begin Group "Resource Files"
+
+# PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe"
+# End Group
+# End Target
+# End Project
diff --git a/contrib/libyaml/win32/vc6/run_scanner.dsp b/contrib/libyaml/win32/vc6/run_scanner.dsp
new file mode 100644
index 0000000..fd63545
--- /dev/null
+++ b/contrib/libyaml/win32/vc6/run_scanner.dsp
@@ -0,0 +1,102 @@
+# Microsoft Developer Studio Project File - Name="run_scanner" - Package Owner=<4>
+# Microsoft Developer Studio Generated Build File, Format Version 6.00
+# ** DO NOT EDIT **
+
+# TARGTYPE "Win32 (x86) Console Application" 0x0103
+
+CFG=run_scanner - Win32 Debug
+!MESSAGE This is not a valid makefile. To build this project using NMAKE,
+!MESSAGE use the Export Makefile command and run
+!MESSAGE
+!MESSAGE NMAKE /f "run_scanner.mak".
+!MESSAGE
+!MESSAGE You can specify a configuration when running NMAKE
+!MESSAGE by defining the macro CFG on the command line. For example:
+!MESSAGE
+!MESSAGE NMAKE /f "run_scanner.mak" CFG="run_scanner - Win32 Debug"
+!MESSAGE
+!MESSAGE Possible choices for configuration are:
+!MESSAGE
+!MESSAGE "run_scanner - Win32 Release" (based on "Win32 (x86) Console Application")
+!MESSAGE "run_scanner - Win32 Debug" (based on "Win32 (x86) Console Application")
+!MESSAGE
+
+# Begin Project
+# PROP AllowPerConfigDependencies 0
+# PROP Scc_ProjName ""
+# PROP Scc_LocalPath ""
+CPP=cl.exe
+RSC=rc.exe
+
+!IF "$(CFG)" == "run_scanner - Win32 Release"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 0
+# PROP BASE Output_Dir "Release"
+# PROP BASE Intermediate_Dir "Release"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 0
+# PROP Output_Dir "Output/Release/bin"
+# PROP Intermediate_Dir "Build/Release/bin"
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
+# ADD CPP /nologo /MD /W3 /GX /O2 /I "../../include" /D "NDEBUG" /D "WIN32" /D "_CONSOLE" /D "_MBCS" /D "YAML_DECLARE_STATIC" /YX /FD /c
+# ADD BASE RSC /l 0x409 /d "NDEBUG"
+# ADD RSC /l 0x409 /d "NDEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386
+# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386
+
+!ELSEIF "$(CFG)" == "run_scanner - Win32 Debug"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 1
+# PROP BASE Output_Dir "Debug"
+# PROP BASE Intermediate_Dir "Debug"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 1
+# PROP Output_Dir "Output/Debug/bin"
+# PROP Intermediate_Dir "Build/Debug/bin"
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c
+# ADD CPP /nologo /MDd /W3 /Gm /GX /ZI /Od /I "../../include" /D "_DEBUG" /D "WIN32" /D "_CONSOLE" /D "_MBCS" /D "YAML_DECLARE_STATIC" /YX /FD /GZ /c
+# ADD BASE RSC /l 0x409 /d "_DEBUG"
+# ADD RSC /l 0x409 /d "_DEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept
+# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept
+
+!ENDIF
+
+# Begin Target
+
+# Name "run_scanner - Win32 Release"
+# Name "run_scanner - Win32 Debug"
+# Begin Group "Source Files"
+
+# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"
+# Begin Source File
+
+SOURCE="..\..\tests\run-scanner.c"
+# End Source File
+# End Group
+# Begin Group "Header Files"
+
+# PROP Default_Filter "h;hpp;hxx;hm;inl"
+# End Group
+# Begin Group "Resource Files"
+
+# PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe"
+# End Group
+# End Target
+# End Project
diff --git a/contrib/libyaml/win32/vc6/test_reader.dsp b/contrib/libyaml/win32/vc6/test_reader.dsp
new file mode 100644
index 0000000..450119a
--- /dev/null
+++ b/contrib/libyaml/win32/vc6/test_reader.dsp
@@ -0,0 +1,102 @@
+# Microsoft Developer Studio Project File - Name="test_reader" - Package Owner=<4>
+# Microsoft Developer Studio Generated Build File, Format Version 6.00
+# ** DO NOT EDIT **
+
+# TARGTYPE "Win32 (x86) Console Application" 0x0103
+
+CFG=test_reader - Win32 Debug
+!MESSAGE This is not a valid makefile. To build this project using NMAKE,
+!MESSAGE use the Export Makefile command and run
+!MESSAGE
+!MESSAGE NMAKE /f "test_reader.mak".
+!MESSAGE
+!MESSAGE You can specify a configuration when running NMAKE
+!MESSAGE by defining the macro CFG on the command line. For example:
+!MESSAGE
+!MESSAGE NMAKE /f "test_reader.mak" CFG="test_reader - Win32 Debug"
+!MESSAGE
+!MESSAGE Possible choices for configuration are:
+!MESSAGE
+!MESSAGE "test_reader - Win32 Release" (based on "Win32 (x86) Console Application")
+!MESSAGE "test_reader - Win32 Debug" (based on "Win32 (x86) Console Application")
+!MESSAGE
+
+# Begin Project
+# PROP AllowPerConfigDependencies 0
+# PROP Scc_ProjName ""
+# PROP Scc_LocalPath ""
+CPP=cl.exe
+RSC=rc.exe
+
+!IF "$(CFG)" == "test_reader - Win32 Release"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 0
+# PROP BASE Output_Dir "Release"
+# PROP BASE Intermediate_Dir "Release"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 0
+# PROP Output_Dir "Output/Release/bin"
+# PROP Intermediate_Dir "Build/Release/bin"
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
+# ADD CPP /nologo /MD /W3 /GX /O2 /I "../../include" /D "NDEBUG" /D "WIN32" /D "_CONSOLE" /D "_MBCS" /D "YAML_DECLARE_STATIC" /YX /FD /c
+# ADD BASE RSC /l 0x409 /d "NDEBUG"
+# ADD RSC /l 0x409 /d "NDEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386
+# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386
+
+!ELSEIF "$(CFG)" == "test_reader - Win32 Debug"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 1
+# PROP BASE Output_Dir "Debug"
+# PROP BASE Intermediate_Dir "Debug"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 1
+# PROP Output_Dir "Output/Debug/bin"
+# PROP Intermediate_Dir "Build/Debug/bin"
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c
+# ADD CPP /nologo /MDd /W3 /Gm /GX /ZI /Od /I "../../include" /D "_DEBUG" /D "WIN32" /D "_CONSOLE" /D "_MBCS" /D "YAML_DECLARE_STATIC" /YX /FD /GZ /c
+# ADD BASE RSC /l 0x409 /d "_DEBUG"
+# ADD RSC /l 0x409 /d "_DEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept
+# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept
+
+!ENDIF
+
+# Begin Target
+
+# Name "test_reader - Win32 Release"
+# Name "test_reader - Win32 Debug"
+# Begin Group "Source Files"
+
+# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"
+# Begin Source File
+
+SOURCE="..\..\tests\test-reader.c"
+# End Source File
+# End Group
+# Begin Group "Header Files"
+
+# PROP Default_Filter "h;hpp;hxx;hm;inl"
+# End Group
+# Begin Group "Resource Files"
+
+# PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe"
+# End Group
+# End Target
+# End Project
diff --git a/contrib/libyaml/win32/vc6/test_version.dsp b/contrib/libyaml/win32/vc6/test_version.dsp
new file mode 100644
index 0000000..423c467
--- /dev/null
+++ b/contrib/libyaml/win32/vc6/test_version.dsp
@@ -0,0 +1,102 @@
+# Microsoft Developer Studio Project File - Name="test_version" - Package Owner=<4>
+# Microsoft Developer Studio Generated Build File, Format Version 6.00
+# ** DO NOT EDIT **
+
+# TARGTYPE "Win32 (x86) Console Application" 0x0103
+
+CFG=test_version - Win32 Debug
+!MESSAGE This is not a valid makefile. To build this project using NMAKE,
+!MESSAGE use the Export Makefile command and run
+!MESSAGE
+!MESSAGE NMAKE /f "test_version.mak".
+!MESSAGE
+!MESSAGE You can specify a configuration when running NMAKE
+!MESSAGE by defining the macro CFG on the command line. For example:
+!MESSAGE
+!MESSAGE NMAKE /f "test_version.mak" CFG="test_version - Win32 Debug"
+!MESSAGE
+!MESSAGE Possible choices for configuration are:
+!MESSAGE
+!MESSAGE "test_version - Win32 Release" (based on "Win32 (x86) Console Application")
+!MESSAGE "test_version - Win32 Debug" (based on "Win32 (x86) Console Application")
+!MESSAGE
+
+# Begin Project
+# PROP AllowPerConfigDependencies 0
+# PROP Scc_ProjName ""
+# PROP Scc_LocalPath ""
+CPP=cl.exe
+RSC=rc.exe
+
+!IF "$(CFG)" == "test_version - Win32 Release"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 0
+# PROP BASE Output_Dir "Release"
+# PROP BASE Intermediate_Dir "Release"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 0
+# PROP Output_Dir "Output/Release/bin"
+# PROP Intermediate_Dir "Build/Release/bin"
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
+# ADD CPP /nologo /MD /W3 /GX /O2 /I "../../include" /D "NDEBUG" /D "WIN32" /D "_CONSOLE" /D "_MBCS" /D "YAML_DECLARE_STATIC" /YX /FD /c
+# ADD BASE RSC /l 0x409 /d "NDEBUG"
+# ADD RSC /l 0x409 /d "NDEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386
+# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386
+
+!ELSEIF "$(CFG)" == "test_version - Win32 Debug"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 1
+# PROP BASE Output_Dir "Debug"
+# PROP BASE Intermediate_Dir "Debug"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 1
+# PROP Output_Dir "Output/Debug/bin"
+# PROP Intermediate_Dir "Build/Debug/bin"
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c
+# ADD CPP /nologo /MDd /W3 /Gm /GX /ZI /Od /I "../../include" /D "_DEBUG" /D "WIN32" /D "_CONSOLE" /D "_MBCS" /D "YAML_DECLARE_STATIC" /YX /FD /GZ /c
+# ADD BASE RSC /l 0x409 /d "_DEBUG"
+# ADD RSC /l 0x409 /d "_DEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept
+# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept
+
+!ENDIF
+
+# Begin Target
+
+# Name "test_version - Win32 Release"
+# Name "test_version - Win32 Debug"
+# Begin Group "Source Files"
+
+# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"
+# Begin Source File
+
+SOURCE="..\..\tests\test-version.c"
+# End Source File
+# End Group
+# Begin Group "Header Files"
+
+# PROP Default_Filter "h;hpp;hxx;hm;inl"
+# End Group
+# Begin Group "Resource Files"
+
+# PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe"
+# End Group
+# End Target
+# End Project
diff --git a/contrib/libyaml/win32/vc6/yaml.dsp b/contrib/libyaml/win32/vc6/yaml.dsp
new file mode 100644
index 0000000..9535520
--- /dev/null
+++ b/contrib/libyaml/win32/vc6/yaml.dsp
@@ -0,0 +1,136 @@
+# Microsoft Developer Studio Project File - Name="yaml" - Package Owner=<4>
+# Microsoft Developer Studio Generated Build File, Format Version 6.00
+# ** DO NOT EDIT **
+
+# TARGTYPE "Win32 (x86) Static Library" 0x0104
+
+CFG=yaml - Win32 Debug
+!MESSAGE This is not a valid makefile. To build this project using NMAKE,
+!MESSAGE use the Export Makefile command and run
+!MESSAGE
+!MESSAGE NMAKE /f "yaml.mak".
+!MESSAGE
+!MESSAGE You can specify a configuration when running NMAKE
+!MESSAGE by defining the macro CFG on the command line. For example:
+!MESSAGE
+!MESSAGE NMAKE /f "yaml.mak" CFG="yaml - Win32 Debug"
+!MESSAGE
+!MESSAGE Possible choices for configuration are:
+!MESSAGE
+!MESSAGE "yaml - Win32 Release" (based on "Win32 (x86) Static Library")
+!MESSAGE "yaml - Win32 Debug" (based on "Win32 (x86) Static Library")
+!MESSAGE
+
+# Begin Project
+# PROP AllowPerConfigDependencies 0
+# PROP Scc_ProjName ""
+# PROP Scc_LocalPath ""
+CPP=cl.exe
+RSC=rc.exe
+
+!IF "$(CFG)" == "yaml - Win32 Release"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 0
+# PROP BASE Output_Dir "Release"
+# PROP BASE Intermediate_Dir "Release"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 0
+# PROP Output_Dir "Output/Release/lib"
+# PROP Intermediate_Dir "Build/Release/lib"
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_MBCS" /D "_LIB" /YX /FD /c
+# ADD CPP /nologo /MD /W3 /GX /O2 /I ".." /I "..\..\include" /D "NDEBUG" /D "WIN32" /D "_MBCS" /D "_LIB" /D "HAVE_CONFIG_H" /D "YAML_DECLARE_STATIC" /YX /FD /c
+# ADD BASE RSC /l 0x409 /d "NDEBUG"
+# ADD RSC /l 0x409 /d "NDEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LIB32=link.exe -lib
+# ADD BASE LIB32 /nologo
+# ADD LIB32 /nologo
+
+!ELSEIF "$(CFG)" == "yaml - Win32 Debug"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 1
+# PROP BASE Output_Dir "Debug"
+# PROP BASE Intermediate_Dir "Debug"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 1
+# PROP Output_Dir "Output/Debug/lib"
+# PROP Intermediate_Dir "Build/Debug/lib"
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_MBCS" /D "_LIB" /YX /FD /GZ /c
+# ADD CPP /nologo /MDd /W3 /Gm /GX /ZI /Od /I ".." /I "..\..\include" /D "_DEBUG" /D "WIN32" /D "_MBCS" /D "_LIB" /D "HAVE_CONFIG_H" /D "YAML_DECLARE_STATIC" /YX /FD /GZ /c
+# ADD BASE RSC /l 0x409 /d "_DEBUG"
+# ADD RSC /l 0x409 /d "_DEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LIB32=link.exe -lib
+# ADD BASE LIB32 /nologo
+# ADD LIB32 /nologo
+
+!ENDIF
+
+# Begin Target
+
+# Name "yaml - Win32 Release"
+# Name "yaml - Win32 Debug"
+# Begin Group "Source Files"
+
+# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"
+# Begin Source File
+
+SOURCE=..\..\src\api.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\src\dumper.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\src\emitter.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\src\loader.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\src\parser.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\src\reader.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\src\scanner.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\src\writer.c
+# End Source File
+# End Group
+# Begin Group "Header Files"
+
+# PROP Default_Filter "h;hpp;hxx;hm;inl"
+# Begin Source File
+
+SOURCE=..\config.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\include\yaml.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\src\yaml_private.h
+# End Source File
+# End Group
+# End Target
+# End Project
diff --git a/contrib/libyaml/win32/vc6/yamldll.dsp b/contrib/libyaml/win32/vc6/yamldll.dsp
new file mode 100644
index 0000000..cc7895e
--- /dev/null
+++ b/contrib/libyaml/win32/vc6/yamldll.dsp
@@ -0,0 +1,147 @@
+# Microsoft Developer Studio Project File - Name="yamldll" - Package Owner=<4>
+# Microsoft Developer Studio Generated Build File, Format Version 6.00
+# ** DO NOT EDIT **
+
+# TARGTYPE "Win32 (x86) Dynamic-Link Library" 0x0102
+
+CFG=yamldll - Win32 Debug
+!MESSAGE This is not a valid makefile. To build this project using NMAKE,
+!MESSAGE use the Export Makefile command and run
+!MESSAGE
+!MESSAGE NMAKE /f "yamldll.mak".
+!MESSAGE
+!MESSAGE You can specify a configuration when running NMAKE
+!MESSAGE by defining the macro CFG on the command line. For example:
+!MESSAGE
+!MESSAGE NMAKE /f "yamldll.mak" CFG="yamldll - Win32 Debug"
+!MESSAGE
+!MESSAGE Possible choices for configuration are:
+!MESSAGE
+!MESSAGE "yamldll - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library")
+!MESSAGE "yamldll - Win32 Debug" (based on "Win32 (x86) Dynamic-Link Library")
+!MESSAGE
+
+# Begin Project
+# PROP AllowPerConfigDependencies 0
+# PROP Scc_ProjName ""
+# PROP Scc_LocalPath ""
+CPP=cl.exe
+MTL=midl.exe
+RSC=rc.exe
+
+!IF "$(CFG)" == "yamldll - Win32 Release"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 0
+# PROP BASE Output_Dir "Release"
+# PROP BASE Intermediate_Dir "Release"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 0
+# PROP Output_Dir "Output/Release/lib/DLL"
+# PROP Intermediate_Dir "Build/Release/lib/DLL"
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /MT /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "YAMLDLL_EXPORTS" /YX /FD /c
+# ADD CPP /nologo /MD /W3 /GX /O2 /I ".." /I "..\..\include" /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "HAVE_CONFIG_H" /D "YAML_DECLARE_EXPORT" /YX /FD /c
+# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32
+# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32
+# ADD BASE RSC /l 0x409 /d "NDEBUG"
+# ADD RSC /l 0x409 /d "NDEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /machine:I386
+# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /machine:I386 /out:"Output/Release/lib/DLL/yaml.dll"
+
+!ELSEIF "$(CFG)" == "yamldll - Win32 Debug"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 1
+# PROP BASE Output_Dir "Debug"
+# PROP BASE Intermediate_Dir "Debug"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 1
+# PROP Output_Dir "Output/Debug/lib/DLL"
+# PROP Intermediate_Dir "Build/Debug/lib/DLL"
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "YAMLDLL_EXPORTS" /YX /FD /GZ /c
+# ADD CPP /nologo /MDd /W3 /Gm /GX /ZI /Od /I ".." /I "..\..\include" /D "_DEBUG" /D "WIN32" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "HAVE_CONFIG_H" /D "YAML_DECLARE_EXPORT" /YX /FD /GZ /c
+# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32
+# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32
+# ADD BASE RSC /l 0x409 /d "_DEBUG"
+# ADD RSC /l 0x409 /d "_DEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /debug /machine:I386 /pdbtype:sept
+# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /debug /machine:I386 /out:"Output/Debug/lib/DLL/yaml.dll" /pdbtype:sept
+
+!ENDIF
+
+# Begin Target
+
+# Name "yamldll - Win32 Release"
+# Name "yamldll - Win32 Debug"
+# Begin Group "Source Files"
+
+# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"
+# Begin Source File
+
+SOURCE=..\..\src\api.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\src\dumper.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\src\emitter.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\src\loader.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\src\parser.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\src\reader.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\src\scanner.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\src\writer.c
+# End Source File
+# End Group
+# Begin Group "Header Files"
+
+# PROP Default_Filter "h;hpp;hxx;hm;inl"
+# Begin Source File
+
+SOURCE=..\config.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\include\yaml.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\src\yaml_private.h
+# End Source File
+# End Group
+# Begin Group "Resource Files"
+
+# PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe"
+# End Group
+# End Target
+# End Project
diff --git a/contrib/libyaml/win32/vs2003/example_deconstructor.vcproj b/contrib/libyaml/win32/vs2003/example_deconstructor.vcproj
new file mode 100644
index 0000000..0b5f56d
--- /dev/null
+++ b/contrib/libyaml/win32/vs2003/example_deconstructor.vcproj
@@ -0,0 +1,134 @@
+<?xml version="1.0" encoding="windows-1251"?>
+<VisualStudioProject
+ ProjectType="Visual C++"
+ Version="7.10"
+ Name="example_deconstructor"
+ ProjectGUID="{F8C735BD-5D83-4E21-8548-7984792033DB}"
+ Keyword="Win32Proj">
+ <Platforms>
+ <Platform
+ Name="Win32"/>
+ </Platforms>
+ <Configurations>
+ <Configuration
+ Name="Debug|Win32"
+ OutputDirectory="Output\Debug\bin"
+ IntermediateDirectory="Build\Debug\bin"
+ ConfigurationType="1"
+ CharacterSet="2">
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="0"
+ AdditionalIncludeDirectories="../../include"
+ PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE;YAML_DECLARE_STATIC"
+ MinimalRebuild="TRUE"
+ BasicRuntimeChecks="3"
+ RuntimeLibrary="3"
+ UsePrecompiledHeader="0"
+ WarningLevel="3"
+ Detect64BitPortabilityProblems="TRUE"
+ DebugInformationFormat="4"/>
+ <Tool
+ Name="VCCustomBuildTool"/>
+ <Tool
+ Name="VCLinkerTool"
+ OutputFile="$(OutDir)/example_deconstructor.exe"
+ LinkIncremental="2"
+ GenerateDebugInformation="TRUE"
+ ProgramDatabaseFile="$(OutDir)/example_deconstructor.pdb"
+ SubSystem="1"
+ TargetMachine="1"/>
+ <Tool
+ Name="VCMIDLTool"/>
+ <Tool
+ Name="VCPostBuildEventTool"/>
+ <Tool
+ Name="VCPreBuildEventTool"/>
+ <Tool
+ Name="VCPreLinkEventTool"/>
+ <Tool
+ Name="VCResourceCompilerTool"/>
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"/>
+ <Tool
+ Name="VCXMLDataGeneratorTool"/>
+ <Tool
+ Name="VCWebDeploymentTool"/>
+ <Tool
+ Name="VCManagedWrapperGeneratorTool"/>
+ <Tool
+ Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
+ </Configuration>
+ <Configuration
+ Name="Release|Win32"
+ OutputDirectory="Output\Release\bin"
+ IntermediateDirectory="Build\Release\bin"
+ ConfigurationType="1"
+ CharacterSet="2">
+ <Tool
+ Name="VCCLCompilerTool"
+ AdditionalIncludeDirectories="../../include"
+ PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE;YAML_DECLARE_STATIC"
+ RuntimeLibrary="2"
+ UsePrecompiledHeader="0"
+ WarningLevel="3"
+ Detect64BitPortabilityProblems="TRUE"
+ DebugInformationFormat="3"/>
+ <Tool
+ Name="VCCustomBuildTool"/>
+ <Tool
+ Name="VCLinkerTool"
+ OutputFile="$(OutDir)/example_deconstructor.exe"
+ LinkIncremental="1"
+ GenerateDebugInformation="TRUE"
+ SubSystem="1"
+ OptimizeReferences="2"
+ EnableCOMDATFolding="2"
+ TargetMachine="1"/>
+ <Tool
+ Name="VCMIDLTool"/>
+ <Tool
+ Name="VCPostBuildEventTool"/>
+ <Tool
+ Name="VCPreBuildEventTool"/>
+ <Tool
+ Name="VCPreLinkEventTool"/>
+ <Tool
+ Name="VCResourceCompilerTool"/>
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"/>
+ <Tool
+ Name="VCXMLDataGeneratorTool"/>
+ <Tool
+ Name="VCWebDeploymentTool"/>
+ <Tool
+ Name="VCManagedWrapperGeneratorTool"/>
+ <Tool
+ Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
+ </Configuration>
+ </Configurations>
+ <References>
+ </References>
+ <Files>
+ <Filter
+ Name="Source Files"
+ Filter="cpp;c;cxx;def;odl;idl;hpj;bat;asm;asmx"
+ UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}">
+ <File
+ RelativePath="..\..\tests\example-deconstructor.c">
+ </File>
+ </Filter>
+ <Filter
+ Name="Header Files"
+ Filter="h;hpp;hxx;hm;inl;inc;xsd"
+ UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}">
+ </Filter>
+ <Filter
+ Name="Resource Files"
+ Filter="rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx"
+ UniqueIdentifier="{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}">
+ </Filter>
+ </Files>
+ <Globals>
+ </Globals>
+</VisualStudioProject>
diff --git a/contrib/libyaml/win32/vs2003/example_deconstructor_alt.vcproj b/contrib/libyaml/win32/vs2003/example_deconstructor_alt.vcproj
new file mode 100644
index 0000000..7efbc41
--- /dev/null
+++ b/contrib/libyaml/win32/vs2003/example_deconstructor_alt.vcproj
@@ -0,0 +1,134 @@
+<?xml version="1.0" encoding="windows-1251"?>
+<VisualStudioProject
+ ProjectType="Visual C++"
+ Version="7.10"
+ Name="example_deconstructor_alt"
+ ProjectGUID="{AEBABE36-E103-4E4B-84D4-B4546285C35A}"
+ Keyword="Win32Proj">
+ <Platforms>
+ <Platform
+ Name="Win32"/>
+ </Platforms>
+ <Configurations>
+ <Configuration
+ Name="Debug|Win32"
+ OutputDirectory="Output\Debug\bin"
+ IntermediateDirectory="Build\Debug\bin"
+ ConfigurationType="1"
+ CharacterSet="2">
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="0"
+ AdditionalIncludeDirectories="../../include"
+ PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE;YAML_DECLARE_STATIC"
+ MinimalRebuild="TRUE"
+ BasicRuntimeChecks="3"
+ RuntimeLibrary="3"
+ UsePrecompiledHeader="0"
+ WarningLevel="3"
+ Detect64BitPortabilityProblems="TRUE"
+ DebugInformationFormat="4"/>
+ <Tool
+ Name="VCCustomBuildTool"/>
+ <Tool
+ Name="VCLinkerTool"
+ OutputFile="$(OutDir)/example_deconstructor_alt.exe"
+ LinkIncremental="2"
+ GenerateDebugInformation="TRUE"
+ ProgramDatabaseFile="$(OutDir)/example_deconstructor_alt.pdb"
+ SubSystem="1"
+ TargetMachine="1"/>
+ <Tool
+ Name="VCMIDLTool"/>
+ <Tool
+ Name="VCPostBuildEventTool"/>
+ <Tool
+ Name="VCPreBuildEventTool"/>
+ <Tool
+ Name="VCPreLinkEventTool"/>
+ <Tool
+ Name="VCResourceCompilerTool"/>
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"/>
+ <Tool
+ Name="VCXMLDataGeneratorTool"/>
+ <Tool
+ Name="VCWebDeploymentTool"/>
+ <Tool
+ Name="VCManagedWrapperGeneratorTool"/>
+ <Tool
+ Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
+ </Configuration>
+ <Configuration
+ Name="Release|Win32"
+ OutputDirectory="Output\Release\bin"
+ IntermediateDirectory="Build\Release\bin"
+ ConfigurationType="1"
+ CharacterSet="2">
+ <Tool
+ Name="VCCLCompilerTool"
+ AdditionalIncludeDirectories="../../include"
+ PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE;YAML_DECLARE_STATIC"
+ RuntimeLibrary="2"
+ UsePrecompiledHeader="0"
+ WarningLevel="3"
+ Detect64BitPortabilityProblems="TRUE"
+ DebugInformationFormat="3"/>
+ <Tool
+ Name="VCCustomBuildTool"/>
+ <Tool
+ Name="VCLinkerTool"
+ OutputFile="$(OutDir)/example_deconstructor_alt.exe"
+ LinkIncremental="1"
+ GenerateDebugInformation="TRUE"
+ SubSystem="1"
+ OptimizeReferences="2"
+ EnableCOMDATFolding="2"
+ TargetMachine="1"/>
+ <Tool
+ Name="VCMIDLTool"/>
+ <Tool
+ Name="VCPostBuildEventTool"/>
+ <Tool
+ Name="VCPreBuildEventTool"/>
+ <Tool
+ Name="VCPreLinkEventTool"/>
+ <Tool
+ Name="VCResourceCompilerTool"/>
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"/>
+ <Tool
+ Name="VCXMLDataGeneratorTool"/>
+ <Tool
+ Name="VCWebDeploymentTool"/>
+ <Tool
+ Name="VCManagedWrapperGeneratorTool"/>
+ <Tool
+ Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
+ </Configuration>
+ </Configurations>
+ <References>
+ </References>
+ <Files>
+ <Filter
+ Name="Source Files"
+ Filter="cpp;c;cxx;def;odl;idl;hpj;bat;asm;asmx"
+ UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}">
+ <File
+ RelativePath="..\..\tests\example-deconstructor-alt.c">
+ </File>
+ </Filter>
+ <Filter
+ Name="Header Files"
+ Filter="h;hpp;hxx;hm;inl;inc;xsd"
+ UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}">
+ </Filter>
+ <Filter
+ Name="Resource Files"
+ Filter="rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx"
+ UniqueIdentifier="{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}">
+ </Filter>
+ </Files>
+ <Globals>
+ </Globals>
+</VisualStudioProject>
diff --git a/contrib/libyaml/win32/vs2003/example_reformatter.vcproj b/contrib/libyaml/win32/vs2003/example_reformatter.vcproj
new file mode 100644
index 0000000..5564922
--- /dev/null
+++ b/contrib/libyaml/win32/vs2003/example_reformatter.vcproj
@@ -0,0 +1,134 @@
+<?xml version="1.0" encoding="windows-1251"?>
+<VisualStudioProject
+ ProjectType="Visual C++"
+ Version="7.10"
+ Name="example_reformatter"
+ ProjectGUID="{BC86310C-0914-4F66-9272-30FD09900D70}"
+ Keyword="Win32Proj">
+ <Platforms>
+ <Platform
+ Name="Win32"/>
+ </Platforms>
+ <Configurations>
+ <Configuration
+ Name="Debug|Win32"
+ OutputDirectory="Output\Debug\bin"
+ IntermediateDirectory="Build\Debug\bin"
+ ConfigurationType="1"
+ CharacterSet="2">
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="0"
+ AdditionalIncludeDirectories="../../include"
+ PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE;YAML_DECLARE_STATIC"
+ MinimalRebuild="TRUE"
+ BasicRuntimeChecks="3"
+ RuntimeLibrary="3"
+ UsePrecompiledHeader="0"
+ WarningLevel="3"
+ Detect64BitPortabilityProblems="TRUE"
+ DebugInformationFormat="4"/>
+ <Tool
+ Name="VCCustomBuildTool"/>
+ <Tool
+ Name="VCLinkerTool"
+ OutputFile="$(OutDir)/example_reformatter.exe"
+ LinkIncremental="2"
+ GenerateDebugInformation="TRUE"
+ ProgramDatabaseFile="$(OutDir)/example_reformatter.pdb"
+ SubSystem="1"
+ TargetMachine="1"/>
+ <Tool
+ Name="VCMIDLTool"/>
+ <Tool
+ Name="VCPostBuildEventTool"/>
+ <Tool
+ Name="VCPreBuildEventTool"/>
+ <Tool
+ Name="VCPreLinkEventTool"/>
+ <Tool
+ Name="VCResourceCompilerTool"/>
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"/>
+ <Tool
+ Name="VCXMLDataGeneratorTool"/>
+ <Tool
+ Name="VCWebDeploymentTool"/>
+ <Tool
+ Name="VCManagedWrapperGeneratorTool"/>
+ <Tool
+ Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
+ </Configuration>
+ <Configuration
+ Name="Release|Win32"
+ OutputDirectory="Output\Release\bin"
+ IntermediateDirectory="Build\Release\bin"
+ ConfigurationType="1"
+ CharacterSet="2">
+ <Tool
+ Name="VCCLCompilerTool"
+ AdditionalIncludeDirectories="../../include"
+ PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE;YAML_DECLARE_STATIC"
+ RuntimeLibrary="2"
+ UsePrecompiledHeader="0"
+ WarningLevel="3"
+ Detect64BitPortabilityProblems="TRUE"
+ DebugInformationFormat="3"/>
+ <Tool
+ Name="VCCustomBuildTool"/>
+ <Tool
+ Name="VCLinkerTool"
+ OutputFile="$(OutDir)/example_reformatter.exe"
+ LinkIncremental="1"
+ GenerateDebugInformation="TRUE"
+ SubSystem="1"
+ OptimizeReferences="2"
+ EnableCOMDATFolding="2"
+ TargetMachine="1"/>
+ <Tool
+ Name="VCMIDLTool"/>
+ <Tool
+ Name="VCPostBuildEventTool"/>
+ <Tool
+ Name="VCPreBuildEventTool"/>
+ <Tool
+ Name="VCPreLinkEventTool"/>
+ <Tool
+ Name="VCResourceCompilerTool"/>
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"/>
+ <Tool
+ Name="VCXMLDataGeneratorTool"/>
+ <Tool
+ Name="VCWebDeploymentTool"/>
+ <Tool
+ Name="VCManagedWrapperGeneratorTool"/>
+ <Tool
+ Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
+ </Configuration>
+ </Configurations>
+ <References>
+ </References>
+ <Files>
+ <Filter
+ Name="Source Files"
+ Filter="cpp;c;cxx;def;odl;idl;hpj;bat;asm;asmx"
+ UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}">
+ <File
+ RelativePath="..\..\tests\example-reformatter.c">
+ </File>
+ </Filter>
+ <Filter
+ Name="Header Files"
+ Filter="h;hpp;hxx;hm;inl;inc;xsd"
+ UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}">
+ </Filter>
+ <Filter
+ Name="Resource Files"
+ Filter="rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx"
+ UniqueIdentifier="{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}">
+ </Filter>
+ </Files>
+ <Globals>
+ </Globals>
+</VisualStudioProject>
diff --git a/contrib/libyaml/win32/vs2003/example_reformatter_alt.vcproj b/contrib/libyaml/win32/vs2003/example_reformatter_alt.vcproj
new file mode 100644
index 0000000..ea4c77d
--- /dev/null
+++ b/contrib/libyaml/win32/vs2003/example_reformatter_alt.vcproj
@@ -0,0 +1,134 @@
+<?xml version="1.0" encoding="windows-1251"?>
+<VisualStudioProject
+ ProjectType="Visual C++"
+ Version="7.10"
+ Name="example_reformatter_alt"
+ ProjectGUID="{C0209B44-8A45-4D9E-B430-100679BC6B2D}"
+ Keyword="Win32Proj">
+ <Platforms>
+ <Platform
+ Name="Win32"/>
+ </Platforms>
+ <Configurations>
+ <Configuration
+ Name="Debug|Win32"
+ OutputDirectory="Output\Debug\bin"
+ IntermediateDirectory="Build\Debug\bin"
+ ConfigurationType="1"
+ CharacterSet="2">
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="0"
+ AdditionalIncludeDirectories="../../include"
+ PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE;YAML_DECLARE_STATIC"
+ MinimalRebuild="TRUE"
+ BasicRuntimeChecks="3"
+ RuntimeLibrary="3"
+ UsePrecompiledHeader="0"
+ WarningLevel="3"
+ Detect64BitPortabilityProblems="TRUE"
+ DebugInformationFormat="4"/>
+ <Tool
+ Name="VCCustomBuildTool"/>
+ <Tool
+ Name="VCLinkerTool"
+ OutputFile="$(OutDir)/example_reformatter_alt.exe"
+ LinkIncremental="2"
+ GenerateDebugInformation="TRUE"
+ ProgramDatabaseFile="$(OutDir)/example_reformatter_alt.pdb"
+ SubSystem="1"
+ TargetMachine="1"/>
+ <Tool
+ Name="VCMIDLTool"/>
+ <Tool
+ Name="VCPostBuildEventTool"/>
+ <Tool
+ Name="VCPreBuildEventTool"/>
+ <Tool
+ Name="VCPreLinkEventTool"/>
+ <Tool
+ Name="VCResourceCompilerTool"/>
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"/>
+ <Tool
+ Name="VCXMLDataGeneratorTool"/>
+ <Tool
+ Name="VCWebDeploymentTool"/>
+ <Tool
+ Name="VCManagedWrapperGeneratorTool"/>
+ <Tool
+ Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
+ </Configuration>
+ <Configuration
+ Name="Release|Win32"
+ OutputDirectory="Output\Release\bin"
+ IntermediateDirectory="Build\Release\bin"
+ ConfigurationType="1"
+ CharacterSet="2">
+ <Tool
+ Name="VCCLCompilerTool"
+ AdditionalIncludeDirectories="../../include"
+ PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE;YAML_DECLARE_STATIC"
+ RuntimeLibrary="2"
+ UsePrecompiledHeader="0"
+ WarningLevel="3"
+ Detect64BitPortabilityProblems="TRUE"
+ DebugInformationFormat="3"/>
+ <Tool
+ Name="VCCustomBuildTool"/>
+ <Tool
+ Name="VCLinkerTool"
+ OutputFile="$(OutDir)/example_reformatter_alt.exe"
+ LinkIncremental="1"
+ GenerateDebugInformation="TRUE"
+ SubSystem="1"
+ OptimizeReferences="2"
+ EnableCOMDATFolding="2"
+ TargetMachine="1"/>
+ <Tool
+ Name="VCMIDLTool"/>
+ <Tool
+ Name="VCPostBuildEventTool"/>
+ <Tool
+ Name="VCPreBuildEventTool"/>
+ <Tool
+ Name="VCPreLinkEventTool"/>
+ <Tool
+ Name="VCResourceCompilerTool"/>
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"/>
+ <Tool
+ Name="VCXMLDataGeneratorTool"/>
+ <Tool
+ Name="VCWebDeploymentTool"/>
+ <Tool
+ Name="VCManagedWrapperGeneratorTool"/>
+ <Tool
+ Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
+ </Configuration>
+ </Configurations>
+ <References>
+ </References>
+ <Files>
+ <Filter
+ Name="Source Files"
+ Filter="cpp;c;cxx;def;odl;idl;hpj;bat;asm;asmx"
+ UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}">
+ <File
+ RelativePath="..\..\tests\example-reformatter-alt.c">
+ </File>
+ </Filter>
+ <Filter
+ Name="Header Files"
+ Filter="h;hpp;hxx;hm;inl;inc;xsd"
+ UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}">
+ </Filter>
+ <Filter
+ Name="Resource Files"
+ Filter="rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx"
+ UniqueIdentifier="{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}">
+ </Filter>
+ </Files>
+ <Globals>
+ </Globals>
+</VisualStudioProject>
diff --git a/contrib/libyaml/win32/vs2003/libyaml.sln b/contrib/libyaml/win32/vs2003/libyaml.sln
new file mode 100644
index 0000000..6f8f6d5
--- /dev/null
+++ b/contrib/libyaml/win32/vs2003/libyaml.sln
@@ -0,0 +1,128 @@
+Microsoft Visual Studio Solution File, Format Version 8.00
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "yaml", "yaml.vcproj", "{5CE8051A-3F0C-4C39-B1C0-3338E48BA60F}"
+ ProjectSection(ProjectDependencies) = postProject
+ EndProjectSection
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "yamldll", "yamldll.vcproj", "{019A6F4C-E704-4879-8E53-622BD4BC9C89}"
+ ProjectSection(ProjectDependencies) = postProject
+ EndProjectSection
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "example_deconstructor_alt", "example_deconstructor_alt.vcproj", "{AEBABE36-E103-4E4B-84D4-B4546285C35A}"
+ ProjectSection(ProjectDependencies) = postProject
+ {5CE8051A-3F0C-4C39-B1C0-3338E48BA60F} = {5CE8051A-3F0C-4C39-B1C0-3338E48BA60F}
+ EndProjectSection
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "example_deconstructor", "example_deconstructor.vcproj", "{F8C735BD-5D83-4E21-8548-7984792033DB}"
+ ProjectSection(ProjectDependencies) = postProject
+ {5CE8051A-3F0C-4C39-B1C0-3338E48BA60F} = {5CE8051A-3F0C-4C39-B1C0-3338E48BA60F}
+ EndProjectSection
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "example_reformatter", "example_reformatter.vcproj", "{BC86310C-0914-4F66-9272-30FD09900D70}"
+ ProjectSection(ProjectDependencies) = postProject
+ {5CE8051A-3F0C-4C39-B1C0-3338E48BA60F} = {5CE8051A-3F0C-4C39-B1C0-3338E48BA60F}
+ EndProjectSection
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "example_reformatter_alt", "example_reformatter_alt.vcproj", "{C0209B44-8A45-4D9E-B430-100679BC6B2D}"
+ ProjectSection(ProjectDependencies) = postProject
+ {5CE8051A-3F0C-4C39-B1C0-3338E48BA60F} = {5CE8051A-3F0C-4C39-B1C0-3338E48BA60F}
+ EndProjectSection
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "run_dumper", "run_dumper.vcproj", "{99AD9500-BD7A-4996-9FA2-2E4EAE7E6BCB}"
+ ProjectSection(ProjectDependencies) = postProject
+ {5CE8051A-3F0C-4C39-B1C0-3338E48BA60F} = {5CE8051A-3F0C-4C39-B1C0-3338E48BA60F}
+ EndProjectSection
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "run_emitter", "run_emitter.vcproj", "{CBA602BE-8FE4-4E68-A401-3C537EAA7239}"
+ ProjectSection(ProjectDependencies) = postProject
+ {5CE8051A-3F0C-4C39-B1C0-3338E48BA60F} = {5CE8051A-3F0C-4C39-B1C0-3338E48BA60F}
+ EndProjectSection
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "run_loader", "run_loader.vcproj", "{B9549FB7-A259-4518-A9CD-9D2108C2C728}"
+ ProjectSection(ProjectDependencies) = postProject
+ {5CE8051A-3F0C-4C39-B1C0-3338E48BA60F} = {5CE8051A-3F0C-4C39-B1C0-3338E48BA60F}
+ EndProjectSection
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "run_parser", "run_parser.vcproj", "{8EC75FB4-951D-4A19-8DCD-ED2E97E4B234}"
+ ProjectSection(ProjectDependencies) = postProject
+ {5CE8051A-3F0C-4C39-B1C0-3338E48BA60F} = {5CE8051A-3F0C-4C39-B1C0-3338E48BA60F}
+ EndProjectSection
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "run_scanner", "run_scanner.vcproj", "{5D3F321E-4A86-4842-9F45-105A7F373104}"
+ ProjectSection(ProjectDependencies) = postProject
+ {5CE8051A-3F0C-4C39-B1C0-3338E48BA60F} = {5CE8051A-3F0C-4C39-B1C0-3338E48BA60F}
+ EndProjectSection
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "test_reader", "test_reader.vcproj", "{898C9408-2480-4BF8-97B0-B1464B7BB5C4}"
+ ProjectSection(ProjectDependencies) = postProject
+ {5CE8051A-3F0C-4C39-B1C0-3338E48BA60F} = {5CE8051A-3F0C-4C39-B1C0-3338E48BA60F}
+ EndProjectSection
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "test_version", "test_version.vcproj", "{BF6CA7A9-0767-4A4E-BC42-9B7C8E105991}"
+ ProjectSection(ProjectDependencies) = postProject
+ {5CE8051A-3F0C-4C39-B1C0-3338E48BA60F} = {5CE8051A-3F0C-4C39-B1C0-3338E48BA60F}
+ EndProjectSection
+EndProject
+Global
+ GlobalSection(SolutionConfiguration) = preSolution
+ Debug = Debug
+ Release = Release
+ EndGlobalSection
+ GlobalSection(ProjectConfiguration) = postSolution
+ {5CE8051A-3F0C-4C39-B1C0-3338E48BA60F}.Debug.ActiveCfg = Debug|Win32
+ {5CE8051A-3F0C-4C39-B1C0-3338E48BA60F}.Debug.Build.0 = Debug|Win32
+ {5CE8051A-3F0C-4C39-B1C0-3338E48BA60F}.Release.ActiveCfg = Release|Win32
+ {5CE8051A-3F0C-4C39-B1C0-3338E48BA60F}.Release.Build.0 = Release|Win32
+ {019A6F4C-E704-4879-8E53-622BD4BC9C89}.Debug.ActiveCfg = Debug|Win32
+ {019A6F4C-E704-4879-8E53-622BD4BC9C89}.Debug.Build.0 = Debug|Win32
+ {019A6F4C-E704-4879-8E53-622BD4BC9C89}.Release.ActiveCfg = Release|Win32
+ {019A6F4C-E704-4879-8E53-622BD4BC9C89}.Release.Build.0 = Release|Win32
+ {AEBABE36-E103-4E4B-84D4-B4546285C35A}.Debug.ActiveCfg = Debug|Win32
+ {AEBABE36-E103-4E4B-84D4-B4546285C35A}.Debug.Build.0 = Debug|Win32
+ {AEBABE36-E103-4E4B-84D4-B4546285C35A}.Release.ActiveCfg = Release|Win32
+ {AEBABE36-E103-4E4B-84D4-B4546285C35A}.Release.Build.0 = Release|Win32
+ {F8C735BD-5D83-4E21-8548-7984792033DB}.Debug.ActiveCfg = Debug|Win32
+ {F8C735BD-5D83-4E21-8548-7984792033DB}.Debug.Build.0 = Debug|Win32
+ {F8C735BD-5D83-4E21-8548-7984792033DB}.Release.ActiveCfg = Release|Win32
+ {F8C735BD-5D83-4E21-8548-7984792033DB}.Release.Build.0 = Release|Win32
+ {BC86310C-0914-4F66-9272-30FD09900D70}.Debug.ActiveCfg = Debug|Win32
+ {BC86310C-0914-4F66-9272-30FD09900D70}.Debug.Build.0 = Debug|Win32
+ {BC86310C-0914-4F66-9272-30FD09900D70}.Release.ActiveCfg = Release|Win32
+ {BC86310C-0914-4F66-9272-30FD09900D70}.Release.Build.0 = Release|Win32
+ {C0209B44-8A45-4D9E-B430-100679BC6B2D}.Debug.ActiveCfg = Debug|Win32
+ {C0209B44-8A45-4D9E-B430-100679BC6B2D}.Debug.Build.0 = Debug|Win32
+ {C0209B44-8A45-4D9E-B430-100679BC6B2D}.Release.ActiveCfg = Release|Win32
+ {C0209B44-8A45-4D9E-B430-100679BC6B2D}.Release.Build.0 = Release|Win32
+ {99AD9500-BD7A-4996-9FA2-2E4EAE7E6BCB}.Debug.ActiveCfg = Debug|Win32
+ {99AD9500-BD7A-4996-9FA2-2E4EAE7E6BCB}.Debug.Build.0 = Debug|Win32
+ {99AD9500-BD7A-4996-9FA2-2E4EAE7E6BCB}.Release.ActiveCfg = Release|Win32
+ {99AD9500-BD7A-4996-9FA2-2E4EAE7E6BCB}.Release.Build.0 = Release|Win32
+ {CBA602BE-8FE4-4E68-A401-3C537EAA7239}.Debug.ActiveCfg = Debug|Win32
+ {CBA602BE-8FE4-4E68-A401-3C537EAA7239}.Debug.Build.0 = Debug|Win32
+ {CBA602BE-8FE4-4E68-A401-3C537EAA7239}.Release.ActiveCfg = Release|Win32
+ {CBA602BE-8FE4-4E68-A401-3C537EAA7239}.Release.Build.0 = Release|Win32
+ {B9549FB7-A259-4518-A9CD-9D2108C2C728}.Debug.ActiveCfg = Debug|Win32
+ {B9549FB7-A259-4518-A9CD-9D2108C2C728}.Debug.Build.0 = Debug|Win32
+ {B9549FB7-A259-4518-A9CD-9D2108C2C728}.Release.ActiveCfg = Release|Win32
+ {B9549FB7-A259-4518-A9CD-9D2108C2C728}.Release.Build.0 = Release|Win32
+ {8EC75FB4-951D-4A19-8DCD-ED2E97E4B234}.Debug.ActiveCfg = Debug|Win32
+ {8EC75FB4-951D-4A19-8DCD-ED2E97E4B234}.Debug.Build.0 = Debug|Win32
+ {8EC75FB4-951D-4A19-8DCD-ED2E97E4B234}.Release.ActiveCfg = Release|Win32
+ {8EC75FB4-951D-4A19-8DCD-ED2E97E4B234}.Release.Build.0 = Release|Win32
+ {5D3F321E-4A86-4842-9F45-105A7F373104}.Debug.ActiveCfg = Debug|Win32
+ {5D3F321E-4A86-4842-9F45-105A7F373104}.Debug.Build.0 = Debug|Win32
+ {5D3F321E-4A86-4842-9F45-105A7F373104}.Release.ActiveCfg = Release|Win32
+ {5D3F321E-4A86-4842-9F45-105A7F373104}.Release.Build.0 = Release|Win32
+ {898C9408-2480-4BF8-97B0-B1464B7BB5C4}.Debug.ActiveCfg = Debug|Win32
+ {898C9408-2480-4BF8-97B0-B1464B7BB5C4}.Debug.Build.0 = Debug|Win32
+ {898C9408-2480-4BF8-97B0-B1464B7BB5C4}.Release.ActiveCfg = Release|Win32
+ {898C9408-2480-4BF8-97B0-B1464B7BB5C4}.Release.Build.0 = Release|Win32
+ {BF6CA7A9-0767-4A4E-BC42-9B7C8E105991}.Debug.ActiveCfg = Debug|Win32
+ {BF6CA7A9-0767-4A4E-BC42-9B7C8E105991}.Debug.Build.0 = Debug|Win32
+ {BF6CA7A9-0767-4A4E-BC42-9B7C8E105991}.Release.ActiveCfg = Release|Win32
+ {BF6CA7A9-0767-4A4E-BC42-9B7C8E105991}.Release.Build.0 = Release|Win32
+ EndGlobalSection
+ GlobalSection(ExtensibilityGlobals) = postSolution
+ EndGlobalSection
+ GlobalSection(ExtensibilityAddIns) = postSolution
+ EndGlobalSection
+EndGlobal
diff --git a/contrib/libyaml/win32/vs2003/run_dumper.vcproj b/contrib/libyaml/win32/vs2003/run_dumper.vcproj
new file mode 100644
index 0000000..713df63
--- /dev/null
+++ b/contrib/libyaml/win32/vs2003/run_dumper.vcproj
@@ -0,0 +1,134 @@
+<?xml version="1.0" encoding="windows-1251"?>
+<VisualStudioProject
+ ProjectType="Visual C++"
+ Version="7.10"
+ Name="run_dumper"
+ ProjectGUID="{99AD9500-BD7A-4996-9FA2-2E4EAE7E6BCB}"
+ Keyword="Win32Proj">
+ <Platforms>
+ <Platform
+ Name="Win32"/>
+ </Platforms>
+ <Configurations>
+ <Configuration
+ Name="Debug|Win32"
+ OutputDirectory="Output\Debug\bin"
+ IntermediateDirectory="Build\Debug\bin"
+ ConfigurationType="1"
+ CharacterSet="2">
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="0"
+ AdditionalIncludeDirectories="../../include"
+ PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE;YAML_DECLARE_STATIC"
+ MinimalRebuild="TRUE"
+ BasicRuntimeChecks="3"
+ RuntimeLibrary="3"
+ UsePrecompiledHeader="0"
+ WarningLevel="3"
+ Detect64BitPortabilityProblems="TRUE"
+ DebugInformationFormat="4"/>
+ <Tool
+ Name="VCCustomBuildTool"/>
+ <Tool
+ Name="VCLinkerTool"
+ OutputFile="$(OutDir)/run_dumper.exe"
+ LinkIncremental="2"
+ GenerateDebugInformation="TRUE"
+ ProgramDatabaseFile="$(OutDir)/run_dumper.pdb"
+ SubSystem="1"
+ TargetMachine="1"/>
+ <Tool
+ Name="VCMIDLTool"/>
+ <Tool
+ Name="VCPostBuildEventTool"/>
+ <Tool
+ Name="VCPreBuildEventTool"/>
+ <Tool
+ Name="VCPreLinkEventTool"/>
+ <Tool
+ Name="VCResourceCompilerTool"/>
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"/>
+ <Tool
+ Name="VCXMLDataGeneratorTool"/>
+ <Tool
+ Name="VCWebDeploymentTool"/>
+ <Tool
+ Name="VCManagedWrapperGeneratorTool"/>
+ <Tool
+ Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
+ </Configuration>
+ <Configuration
+ Name="Release|Win32"
+ OutputDirectory="Output\Release\bin"
+ IntermediateDirectory="Build\Release\bin"
+ ConfigurationType="1"
+ CharacterSet="2">
+ <Tool
+ Name="VCCLCompilerTool"
+ AdditionalIncludeDirectories="../../include"
+ PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE;YAML_DECLARE_STATIC"
+ RuntimeLibrary="2"
+ UsePrecompiledHeader="0"
+ WarningLevel="3"
+ Detect64BitPortabilityProblems="TRUE"
+ DebugInformationFormat="3"/>
+ <Tool
+ Name="VCCustomBuildTool"/>
+ <Tool
+ Name="VCLinkerTool"
+ OutputFile="$(OutDir)/run_dumper.exe"
+ LinkIncremental="1"
+ GenerateDebugInformation="TRUE"
+ SubSystem="1"
+ OptimizeReferences="2"
+ EnableCOMDATFolding="2"
+ TargetMachine="1"/>
+ <Tool
+ Name="VCMIDLTool"/>
+ <Tool
+ Name="VCPostBuildEventTool"/>
+ <Tool
+ Name="VCPreBuildEventTool"/>
+ <Tool
+ Name="VCPreLinkEventTool"/>
+ <Tool
+ Name="VCResourceCompilerTool"/>
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"/>
+ <Tool
+ Name="VCXMLDataGeneratorTool"/>
+ <Tool
+ Name="VCWebDeploymentTool"/>
+ <Tool
+ Name="VCManagedWrapperGeneratorTool"/>
+ <Tool
+ Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
+ </Configuration>
+ </Configurations>
+ <References>
+ </References>
+ <Files>
+ <Filter
+ Name="Source Files"
+ Filter="cpp;c;cxx;def;odl;idl;hpj;bat;asm;asmx"
+ UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}">
+ <File
+ RelativePath="..\..\tests\run-dumper.c">
+ </File>
+ </Filter>
+ <Filter
+ Name="Header Files"
+ Filter="h;hpp;hxx;hm;inl;inc;xsd"
+ UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}">
+ </Filter>
+ <Filter
+ Name="Resource Files"
+ Filter="rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx"
+ UniqueIdentifier="{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}">
+ </Filter>
+ </Files>
+ <Globals>
+ </Globals>
+</VisualStudioProject>
diff --git a/contrib/libyaml/win32/vs2003/run_emitter.vcproj b/contrib/libyaml/win32/vs2003/run_emitter.vcproj
new file mode 100644
index 0000000..65705ce
--- /dev/null
+++ b/contrib/libyaml/win32/vs2003/run_emitter.vcproj
@@ -0,0 +1,134 @@
+<?xml version="1.0" encoding="windows-1251"?>
+<VisualStudioProject
+ ProjectType="Visual C++"
+ Version="7.10"
+ Name="run_emitter"
+ ProjectGUID="{CBA602BE-8FE4-4E68-A401-3C537EAA7239}"
+ Keyword="Win32Proj">
+ <Platforms>
+ <Platform
+ Name="Win32"/>
+ </Platforms>
+ <Configurations>
+ <Configuration
+ Name="Debug|Win32"
+ OutputDirectory="Output\Debug\bin"
+ IntermediateDirectory="Build\Debug\bin"
+ ConfigurationType="1"
+ CharacterSet="2">
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="0"
+ AdditionalIncludeDirectories="../../include"
+ PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE;YAML_DECLARE_STATIC"
+ MinimalRebuild="TRUE"
+ BasicRuntimeChecks="3"
+ RuntimeLibrary="3"
+ UsePrecompiledHeader="0"
+ WarningLevel="3"
+ Detect64BitPortabilityProblems="TRUE"
+ DebugInformationFormat="4"/>
+ <Tool
+ Name="VCCustomBuildTool"/>
+ <Tool
+ Name="VCLinkerTool"
+ OutputFile="$(OutDir)/run_emitter.exe"
+ LinkIncremental="2"
+ GenerateDebugInformation="TRUE"
+ ProgramDatabaseFile="$(OutDir)/run_emitter.pdb"
+ SubSystem="1"
+ TargetMachine="1"/>
+ <Tool
+ Name="VCMIDLTool"/>
+ <Tool
+ Name="VCPostBuildEventTool"/>
+ <Tool
+ Name="VCPreBuildEventTool"/>
+ <Tool
+ Name="VCPreLinkEventTool"/>
+ <Tool
+ Name="VCResourceCompilerTool"/>
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"/>
+ <Tool
+ Name="VCXMLDataGeneratorTool"/>
+ <Tool
+ Name="VCWebDeploymentTool"/>
+ <Tool
+ Name="VCManagedWrapperGeneratorTool"/>
+ <Tool
+ Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
+ </Configuration>
+ <Configuration
+ Name="Release|Win32"
+ OutputDirectory="Output\Release\bin"
+ IntermediateDirectory="Build\Release\bin"
+ ConfigurationType="1"
+ CharacterSet="2">
+ <Tool
+ Name="VCCLCompilerTool"
+ AdditionalIncludeDirectories="../../include"
+ PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE;YAML_DECLARE_STATIC"
+ RuntimeLibrary="2"
+ UsePrecompiledHeader="0"
+ WarningLevel="3"
+ Detect64BitPortabilityProblems="TRUE"
+ DebugInformationFormat="3"/>
+ <Tool
+ Name="VCCustomBuildTool"/>
+ <Tool
+ Name="VCLinkerTool"
+ OutputFile="$(OutDir)/run_emitter.exe"
+ LinkIncremental="1"
+ GenerateDebugInformation="TRUE"
+ SubSystem="1"
+ OptimizeReferences="2"
+ EnableCOMDATFolding="2"
+ TargetMachine="1"/>
+ <Tool
+ Name="VCMIDLTool"/>
+ <Tool
+ Name="VCPostBuildEventTool"/>
+ <Tool
+ Name="VCPreBuildEventTool"/>
+ <Tool
+ Name="VCPreLinkEventTool"/>
+ <Tool
+ Name="VCResourceCompilerTool"/>
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"/>
+ <Tool
+ Name="VCXMLDataGeneratorTool"/>
+ <Tool
+ Name="VCWebDeploymentTool"/>
+ <Tool
+ Name="VCManagedWrapperGeneratorTool"/>
+ <Tool
+ Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
+ </Configuration>
+ </Configurations>
+ <References>
+ </References>
+ <Files>
+ <Filter
+ Name="Source Files"
+ Filter="cpp;c;cxx;def;odl;idl;hpj;bat;asm;asmx"
+ UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}">
+ <File
+ RelativePath="..\..\tests\run-emitter.c">
+ </File>
+ </Filter>
+ <Filter
+ Name="Header Files"
+ Filter="h;hpp;hxx;hm;inl;inc;xsd"
+ UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}">
+ </Filter>
+ <Filter
+ Name="Resource Files"
+ Filter="rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx"
+ UniqueIdentifier="{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}">
+ </Filter>
+ </Files>
+ <Globals>
+ </Globals>
+</VisualStudioProject>
diff --git a/contrib/libyaml/win32/vs2003/run_loader.vcproj b/contrib/libyaml/win32/vs2003/run_loader.vcproj
new file mode 100644
index 0000000..e891ca2
--- /dev/null
+++ b/contrib/libyaml/win32/vs2003/run_loader.vcproj
@@ -0,0 +1,134 @@
+<?xml version="1.0" encoding="windows-1251"?>
+<VisualStudioProject
+ ProjectType="Visual C++"
+ Version="7.10"
+ Name="run_loader"
+ ProjectGUID="{B9549FB7-A259-4518-A9CD-9D2108C2C728}"
+ Keyword="Win32Proj">
+ <Platforms>
+ <Platform
+ Name="Win32"/>
+ </Platforms>
+ <Configurations>
+ <Configuration
+ Name="Debug|Win32"
+ OutputDirectory="Output\Debug\bin"
+ IntermediateDirectory="Build\Debug\bin"
+ ConfigurationType="1"
+ CharacterSet="2">
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="0"
+ AdditionalIncludeDirectories="../../include"
+ PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE;YAML_DECLARE_STATIC"
+ MinimalRebuild="TRUE"
+ BasicRuntimeChecks="3"
+ RuntimeLibrary="3"
+ UsePrecompiledHeader="0"
+ WarningLevel="3"
+ Detect64BitPortabilityProblems="TRUE"
+ DebugInformationFormat="4"/>
+ <Tool
+ Name="VCCustomBuildTool"/>
+ <Tool
+ Name="VCLinkerTool"
+ OutputFile="$(OutDir)/run_loader.exe"
+ LinkIncremental="2"
+ GenerateDebugInformation="TRUE"
+ ProgramDatabaseFile="$(OutDir)/run_loader.pdb"
+ SubSystem="1"
+ TargetMachine="1"/>
+ <Tool
+ Name="VCMIDLTool"/>
+ <Tool
+ Name="VCPostBuildEventTool"/>
+ <Tool
+ Name="VCPreBuildEventTool"/>
+ <Tool
+ Name="VCPreLinkEventTool"/>
+ <Tool
+ Name="VCResourceCompilerTool"/>
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"/>
+ <Tool
+ Name="VCXMLDataGeneratorTool"/>
+ <Tool
+ Name="VCWebDeploymentTool"/>
+ <Tool
+ Name="VCManagedWrapperGeneratorTool"/>
+ <Tool
+ Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
+ </Configuration>
+ <Configuration
+ Name="Release|Win32"
+ OutputDirectory="Output\Release\bin"
+ IntermediateDirectory="Build\Release\bin"
+ ConfigurationType="1"
+ CharacterSet="2">
+ <Tool
+ Name="VCCLCompilerTool"
+ AdditionalIncludeDirectories="../../include"
+ PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE;YAML_DECLARE_STATIC"
+ RuntimeLibrary="2"
+ UsePrecompiledHeader="0"
+ WarningLevel="3"
+ Detect64BitPortabilityProblems="TRUE"
+ DebugInformationFormat="3"/>
+ <Tool
+ Name="VCCustomBuildTool"/>
+ <Tool
+ Name="VCLinkerTool"
+ OutputFile="$(OutDir)/run_loader.exe"
+ LinkIncremental="1"
+ GenerateDebugInformation="TRUE"
+ SubSystem="1"
+ OptimizeReferences="2"
+ EnableCOMDATFolding="2"
+ TargetMachine="1"/>
+ <Tool
+ Name="VCMIDLTool"/>
+ <Tool
+ Name="VCPostBuildEventTool"/>
+ <Tool
+ Name="VCPreBuildEventTool"/>
+ <Tool
+ Name="VCPreLinkEventTool"/>
+ <Tool
+ Name="VCResourceCompilerTool"/>
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"/>
+ <Tool
+ Name="VCXMLDataGeneratorTool"/>
+ <Tool
+ Name="VCWebDeploymentTool"/>
+ <Tool
+ Name="VCManagedWrapperGeneratorTool"/>
+ <Tool
+ Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
+ </Configuration>
+ </Configurations>
+ <References>
+ </References>
+ <Files>
+ <Filter
+ Name="Source Files"
+ Filter="cpp;c;cxx;def;odl;idl;hpj;bat;asm;asmx"
+ UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}">
+ <File
+ RelativePath="..\..\tests\run-loader.c">
+ </File>
+ </Filter>
+ <Filter
+ Name="Header Files"
+ Filter="h;hpp;hxx;hm;inl;inc;xsd"
+ UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}">
+ </Filter>
+ <Filter
+ Name="Resource Files"
+ Filter="rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx"
+ UniqueIdentifier="{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}">
+ </Filter>
+ </Files>
+ <Globals>
+ </Globals>
+</VisualStudioProject>
diff --git a/contrib/libyaml/win32/vs2003/run_parser.vcproj b/contrib/libyaml/win32/vs2003/run_parser.vcproj
new file mode 100644
index 0000000..49393ee
--- /dev/null
+++ b/contrib/libyaml/win32/vs2003/run_parser.vcproj
@@ -0,0 +1,134 @@
+<?xml version="1.0" encoding="windows-1251"?>
+<VisualStudioProject
+ ProjectType="Visual C++"
+ Version="7.10"
+ Name="run_parser"
+ ProjectGUID="{8EC75FB4-951D-4A19-8DCD-ED2E97E4B234}"
+ Keyword="Win32Proj">
+ <Platforms>
+ <Platform
+ Name="Win32"/>
+ </Platforms>
+ <Configurations>
+ <Configuration
+ Name="Debug|Win32"
+ OutputDirectory="Output\Debug\bin"
+ IntermediateDirectory="Build\Debug\bin"
+ ConfigurationType="1"
+ CharacterSet="2">
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="0"
+ AdditionalIncludeDirectories="../../include"
+ PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE;YAML_DECLARE_STATIC"
+ MinimalRebuild="TRUE"
+ BasicRuntimeChecks="3"
+ RuntimeLibrary="3"
+ UsePrecompiledHeader="0"
+ WarningLevel="3"
+ Detect64BitPortabilityProblems="TRUE"
+ DebugInformationFormat="4"/>
+ <Tool
+ Name="VCCustomBuildTool"/>
+ <Tool
+ Name="VCLinkerTool"
+ OutputFile="$(OutDir)/run_parser.exe"
+ LinkIncremental="2"
+ GenerateDebugInformation="TRUE"
+ ProgramDatabaseFile="$(OutDir)/run_parser.pdb"
+ SubSystem="1"
+ TargetMachine="1"/>
+ <Tool
+ Name="VCMIDLTool"/>
+ <Tool
+ Name="VCPostBuildEventTool"/>
+ <Tool
+ Name="VCPreBuildEventTool"/>
+ <Tool
+ Name="VCPreLinkEventTool"/>
+ <Tool
+ Name="VCResourceCompilerTool"/>
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"/>
+ <Tool
+ Name="VCXMLDataGeneratorTool"/>
+ <Tool
+ Name="VCWebDeploymentTool"/>
+ <Tool
+ Name="VCManagedWrapperGeneratorTool"/>
+ <Tool
+ Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
+ </Configuration>
+ <Configuration
+ Name="Release|Win32"
+ OutputDirectory="Output\Release\bin"
+ IntermediateDirectory="Build\Release\bin"
+ ConfigurationType="1"
+ CharacterSet="2">
+ <Tool
+ Name="VCCLCompilerTool"
+ AdditionalIncludeDirectories="../../include"
+ PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE;YAML_DECLARE_STATIC"
+ RuntimeLibrary="2"
+ UsePrecompiledHeader="0"
+ WarningLevel="3"
+ Detect64BitPortabilityProblems="TRUE"
+ DebugInformationFormat="3"/>
+ <Tool
+ Name="VCCustomBuildTool"/>
+ <Tool
+ Name="VCLinkerTool"
+ OutputFile="$(OutDir)/run_parser.exe"
+ LinkIncremental="1"
+ GenerateDebugInformation="TRUE"
+ SubSystem="1"
+ OptimizeReferences="2"
+ EnableCOMDATFolding="2"
+ TargetMachine="1"/>
+ <Tool
+ Name="VCMIDLTool"/>
+ <Tool
+ Name="VCPostBuildEventTool"/>
+ <Tool
+ Name="VCPreBuildEventTool"/>
+ <Tool
+ Name="VCPreLinkEventTool"/>
+ <Tool
+ Name="VCResourceCompilerTool"/>
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"/>
+ <Tool
+ Name="VCXMLDataGeneratorTool"/>
+ <Tool
+ Name="VCWebDeploymentTool"/>
+ <Tool
+ Name="VCManagedWrapperGeneratorTool"/>
+ <Tool
+ Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
+ </Configuration>
+ </Configurations>
+ <References>
+ </References>
+ <Files>
+ <Filter
+ Name="Source Files"
+ Filter="cpp;c;cxx;def;odl;idl;hpj;bat;asm;asmx"
+ UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}">
+ <File
+ RelativePath="..\..\tests\run-parser.c">
+ </File>
+ </Filter>
+ <Filter
+ Name="Header Files"
+ Filter="h;hpp;hxx;hm;inl;inc;xsd"
+ UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}">
+ </Filter>
+ <Filter
+ Name="Resource Files"
+ Filter="rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx"
+ UniqueIdentifier="{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}">
+ </Filter>
+ </Files>
+ <Globals>
+ </Globals>
+</VisualStudioProject>
diff --git a/contrib/libyaml/win32/vs2003/run_scanner.vcproj b/contrib/libyaml/win32/vs2003/run_scanner.vcproj
new file mode 100644
index 0000000..626b252
--- /dev/null
+++ b/contrib/libyaml/win32/vs2003/run_scanner.vcproj
@@ -0,0 +1,134 @@
+<?xml version="1.0" encoding="windows-1251"?>
+<VisualStudioProject
+ ProjectType="Visual C++"
+ Version="7.10"
+ Name="run_scanner"
+ ProjectGUID="{5D3F321E-4A86-4842-9F45-105A7F373104}"
+ Keyword="Win32Proj">
+ <Platforms>
+ <Platform
+ Name="Win32"/>
+ </Platforms>
+ <Configurations>
+ <Configuration
+ Name="Debug|Win32"
+ OutputDirectory="Output\Debug\bin"
+ IntermediateDirectory="Build\Debug\bin"
+ ConfigurationType="1"
+ CharacterSet="2">
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="0"
+ AdditionalIncludeDirectories="../../include"
+ PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE;YAML_DECLARE_STATIC"
+ MinimalRebuild="TRUE"
+ BasicRuntimeChecks="3"
+ RuntimeLibrary="3"
+ UsePrecompiledHeader="0"
+ WarningLevel="3"
+ Detect64BitPortabilityProblems="TRUE"
+ DebugInformationFormat="4"/>
+ <Tool
+ Name="VCCustomBuildTool"/>
+ <Tool
+ Name="VCLinkerTool"
+ OutputFile="$(OutDir)/run_scanner.exe"
+ LinkIncremental="2"
+ GenerateDebugInformation="TRUE"
+ ProgramDatabaseFile="$(OutDir)/run_scanner.pdb"
+ SubSystem="1"
+ TargetMachine="1"/>
+ <Tool
+ Name="VCMIDLTool"/>
+ <Tool
+ Name="VCPostBuildEventTool"/>
+ <Tool
+ Name="VCPreBuildEventTool"/>
+ <Tool
+ Name="VCPreLinkEventTool"/>
+ <Tool
+ Name="VCResourceCompilerTool"/>
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"/>
+ <Tool
+ Name="VCXMLDataGeneratorTool"/>
+ <Tool
+ Name="VCWebDeploymentTool"/>
+ <Tool
+ Name="VCManagedWrapperGeneratorTool"/>
+ <Tool
+ Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
+ </Configuration>
+ <Configuration
+ Name="Release|Win32"
+ OutputDirectory="Output\Release\bin"
+ IntermediateDirectory="Build\Release\bin"
+ ConfigurationType="1"
+ CharacterSet="2">
+ <Tool
+ Name="VCCLCompilerTool"
+ AdditionalIncludeDirectories="../../include"
+ PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE;YAML_DECLARE_STATIC"
+ RuntimeLibrary="2"
+ UsePrecompiledHeader="0"
+ WarningLevel="3"
+ Detect64BitPortabilityProblems="TRUE"
+ DebugInformationFormat="3"/>
+ <Tool
+ Name="VCCustomBuildTool"/>
+ <Tool
+ Name="VCLinkerTool"
+ OutputFile="$(OutDir)/run_scanner.exe"
+ LinkIncremental="1"
+ GenerateDebugInformation="TRUE"
+ SubSystem="1"
+ OptimizeReferences="2"
+ EnableCOMDATFolding="2"
+ TargetMachine="1"/>
+ <Tool
+ Name="VCMIDLTool"/>
+ <Tool
+ Name="VCPostBuildEventTool"/>
+ <Tool
+ Name="VCPreBuildEventTool"/>
+ <Tool
+ Name="VCPreLinkEventTool"/>
+ <Tool
+ Name="VCResourceCompilerTool"/>
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"/>
+ <Tool
+ Name="VCXMLDataGeneratorTool"/>
+ <Tool
+ Name="VCWebDeploymentTool"/>
+ <Tool
+ Name="VCManagedWrapperGeneratorTool"/>
+ <Tool
+ Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
+ </Configuration>
+ </Configurations>
+ <References>
+ </References>
+ <Files>
+ <Filter
+ Name="Source Files"
+ Filter="cpp;c;cxx;def;odl;idl;hpj;bat;asm;asmx"
+ UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}">
+ <File
+ RelativePath="..\..\tests\run-scanner.c">
+ </File>
+ </Filter>
+ <Filter
+ Name="Header Files"
+ Filter="h;hpp;hxx;hm;inl;inc;xsd"
+ UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}">
+ </Filter>
+ <Filter
+ Name="Resource Files"
+ Filter="rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx"
+ UniqueIdentifier="{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}">
+ </Filter>
+ </Files>
+ <Globals>
+ </Globals>
+</VisualStudioProject>
diff --git a/contrib/libyaml/win32/vs2003/test_reader.vcproj b/contrib/libyaml/win32/vs2003/test_reader.vcproj
new file mode 100644
index 0000000..7f646fe
--- /dev/null
+++ b/contrib/libyaml/win32/vs2003/test_reader.vcproj
@@ -0,0 +1,134 @@
+<?xml version="1.0" encoding="windows-1251"?>
+<VisualStudioProject
+ ProjectType="Visual C++"
+ Version="7.10"
+ Name="test_reader"
+ ProjectGUID="{898C9408-2480-4BF8-97B0-B1464B7BB5C4}"
+ Keyword="Win32Proj">
+ <Platforms>
+ <Platform
+ Name="Win32"/>
+ </Platforms>
+ <Configurations>
+ <Configuration
+ Name="Debug|Win32"
+ OutputDirectory="Output\Debug\bin"
+ IntermediateDirectory="Build\Debug\bin"
+ ConfigurationType="1"
+ CharacterSet="2">
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="0"
+ AdditionalIncludeDirectories="../../include"
+ PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE;YAML_DECLARE_STATIC"
+ MinimalRebuild="TRUE"
+ BasicRuntimeChecks="3"
+ RuntimeLibrary="3"
+ UsePrecompiledHeader="0"
+ WarningLevel="3"
+ Detect64BitPortabilityProblems="TRUE"
+ DebugInformationFormat="4"/>
+ <Tool
+ Name="VCCustomBuildTool"/>
+ <Tool
+ Name="VCLinkerTool"
+ OutputFile="$(OutDir)/test_reader.exe"
+ LinkIncremental="2"
+ GenerateDebugInformation="TRUE"
+ ProgramDatabaseFile="$(OutDir)/test_reader.pdb"
+ SubSystem="1"
+ TargetMachine="1"/>
+ <Tool
+ Name="VCMIDLTool"/>
+ <Tool
+ Name="VCPostBuildEventTool"/>
+ <Tool
+ Name="VCPreBuildEventTool"/>
+ <Tool
+ Name="VCPreLinkEventTool"/>
+ <Tool
+ Name="VCResourceCompilerTool"/>
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"/>
+ <Tool
+ Name="VCXMLDataGeneratorTool"/>
+ <Tool
+ Name="VCWebDeploymentTool"/>
+ <Tool
+ Name="VCManagedWrapperGeneratorTool"/>
+ <Tool
+ Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
+ </Configuration>
+ <Configuration
+ Name="Release|Win32"
+ OutputDirectory="Output\Release\bin"
+ IntermediateDirectory="Build\Release\bin"
+ ConfigurationType="1"
+ CharacterSet="2">
+ <Tool
+ Name="VCCLCompilerTool"
+ AdditionalIncludeDirectories="../../include"
+ PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE;YAML_DECLARE_STATIC"
+ RuntimeLibrary="2"
+ UsePrecompiledHeader="0"
+ WarningLevel="3"
+ Detect64BitPortabilityProblems="TRUE"
+ DebugInformationFormat="3"/>
+ <Tool
+ Name="VCCustomBuildTool"/>
+ <Tool
+ Name="VCLinkerTool"
+ OutputFile="$(OutDir)/test_reader.exe"
+ LinkIncremental="1"
+ GenerateDebugInformation="TRUE"
+ SubSystem="1"
+ OptimizeReferences="2"
+ EnableCOMDATFolding="2"
+ TargetMachine="1"/>
+ <Tool
+ Name="VCMIDLTool"/>
+ <Tool
+ Name="VCPostBuildEventTool"/>
+ <Tool
+ Name="VCPreBuildEventTool"/>
+ <Tool
+ Name="VCPreLinkEventTool"/>
+ <Tool
+ Name="VCResourceCompilerTool"/>
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"/>
+ <Tool
+ Name="VCXMLDataGeneratorTool"/>
+ <Tool
+ Name="VCWebDeploymentTool"/>
+ <Tool
+ Name="VCManagedWrapperGeneratorTool"/>
+ <Tool
+ Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
+ </Configuration>
+ </Configurations>
+ <References>
+ </References>
+ <Files>
+ <Filter
+ Name="Source Files"
+ Filter="cpp;c;cxx;def;odl;idl;hpj;bat;asm;asmx"
+ UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}">
+ <File
+ RelativePath="..\..\tests\test-reader.c">
+ </File>
+ </Filter>
+ <Filter
+ Name="Header Files"
+ Filter="h;hpp;hxx;hm;inl;inc;xsd"
+ UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}">
+ </Filter>
+ <Filter
+ Name="Resource Files"
+ Filter="rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx"
+ UniqueIdentifier="{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}">
+ </Filter>
+ </Files>
+ <Globals>
+ </Globals>
+</VisualStudioProject>
diff --git a/contrib/libyaml/win32/vs2003/test_version.vcproj b/contrib/libyaml/win32/vs2003/test_version.vcproj
new file mode 100644
index 0000000..df4a4da
--- /dev/null
+++ b/contrib/libyaml/win32/vs2003/test_version.vcproj
@@ -0,0 +1,134 @@
+<?xml version="1.0" encoding="windows-1251"?>
+<VisualStudioProject
+ ProjectType="Visual C++"
+ Version="7.10"
+ Name="test_version"
+ ProjectGUID="{BF6CA7A9-0767-4A4E-BC42-9B7C8E105991}"
+ Keyword="Win32Proj">
+ <Platforms>
+ <Platform
+ Name="Win32"/>
+ </Platforms>
+ <Configurations>
+ <Configuration
+ Name="Debug|Win32"
+ OutputDirectory="Output\Debug\bin"
+ IntermediateDirectory="Build\Debug\bin"
+ ConfigurationType="1"
+ CharacterSet="2">
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="0"
+ AdditionalIncludeDirectories="../../include"
+ PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE;YAML_DECLARE_STATIC"
+ MinimalRebuild="TRUE"
+ BasicRuntimeChecks="3"
+ RuntimeLibrary="3"
+ UsePrecompiledHeader="0"
+ WarningLevel="3"
+ Detect64BitPortabilityProblems="TRUE"
+ DebugInformationFormat="4"/>
+ <Tool
+ Name="VCCustomBuildTool"/>
+ <Tool
+ Name="VCLinkerTool"
+ OutputFile="$(OutDir)/test_version.exe"
+ LinkIncremental="2"
+ GenerateDebugInformation="TRUE"
+ ProgramDatabaseFile="$(OutDir)/test_version.pdb"
+ SubSystem="1"
+ TargetMachine="1"/>
+ <Tool
+ Name="VCMIDLTool"/>
+ <Tool
+ Name="VCPostBuildEventTool"/>
+ <Tool
+ Name="VCPreBuildEventTool"/>
+ <Tool
+ Name="VCPreLinkEventTool"/>
+ <Tool
+ Name="VCResourceCompilerTool"/>
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"/>
+ <Tool
+ Name="VCXMLDataGeneratorTool"/>
+ <Tool
+ Name="VCWebDeploymentTool"/>
+ <Tool
+ Name="VCManagedWrapperGeneratorTool"/>
+ <Tool
+ Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
+ </Configuration>
+ <Configuration
+ Name="Release|Win32"
+ OutputDirectory="Output\Release\bin"
+ IntermediateDirectory="Build\Release\bin"
+ ConfigurationType="1"
+ CharacterSet="2">
+ <Tool
+ Name="VCCLCompilerTool"
+ AdditionalIncludeDirectories="../../include"
+ PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE;YAML_DECLARE_STATIC"
+ RuntimeLibrary="2"
+ UsePrecompiledHeader="0"
+ WarningLevel="3"
+ Detect64BitPortabilityProblems="TRUE"
+ DebugInformationFormat="3"/>
+ <Tool
+ Name="VCCustomBuildTool"/>
+ <Tool
+ Name="VCLinkerTool"
+ OutputFile="$(OutDir)/test_version.exe"
+ LinkIncremental="1"
+ GenerateDebugInformation="TRUE"
+ SubSystem="1"
+ OptimizeReferences="2"
+ EnableCOMDATFolding="2"
+ TargetMachine="1"/>
+ <Tool
+ Name="VCMIDLTool"/>
+ <Tool
+ Name="VCPostBuildEventTool"/>
+ <Tool
+ Name="VCPreBuildEventTool"/>
+ <Tool
+ Name="VCPreLinkEventTool"/>
+ <Tool
+ Name="VCResourceCompilerTool"/>
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"/>
+ <Tool
+ Name="VCXMLDataGeneratorTool"/>
+ <Tool
+ Name="VCWebDeploymentTool"/>
+ <Tool
+ Name="VCManagedWrapperGeneratorTool"/>
+ <Tool
+ Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
+ </Configuration>
+ </Configurations>
+ <References>
+ </References>
+ <Files>
+ <Filter
+ Name="Source Files"
+ Filter="cpp;c;cxx;def;odl;idl;hpj;bat;asm;asmx"
+ UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}">
+ <File
+ RelativePath="..\..\tests\test-version.c">
+ </File>
+ </Filter>
+ <Filter
+ Name="Header Files"
+ Filter="h;hpp;hxx;hm;inl;inc;xsd"
+ UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}">
+ </Filter>
+ <Filter
+ Name="Resource Files"
+ Filter="rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx"
+ UniqueIdentifier="{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}">
+ </Filter>
+ </Files>
+ <Globals>
+ </Globals>
+</VisualStudioProject>
diff --git a/contrib/libyaml/win32/vs2003/yaml.vcproj b/contrib/libyaml/win32/vs2003/yaml.vcproj
new file mode 100644
index 0000000..252eb08
--- /dev/null
+++ b/contrib/libyaml/win32/vs2003/yaml.vcproj
@@ -0,0 +1,149 @@
+<?xml version="1.0" encoding="windows-1251"?>
+<VisualStudioProject
+ ProjectType="Visual C++"
+ Version="7.10"
+ Name="yaml"
+ ProjectGUID="{5CE8051A-3F0C-4C39-B1C0-3338E48BA60F}"
+ Keyword="Win32Proj">
+ <Platforms>
+ <Platform
+ Name="Win32"/>
+ </Platforms>
+ <Configurations>
+ <Configuration
+ Name="Debug|Win32"
+ OutputDirectory="Output\Debug\lib"
+ IntermediateDirectory="Build\Debug\lib"
+ ConfigurationType="4"
+ CharacterSet="2">
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="0"
+ AdditionalIncludeDirectories="..;../../include"
+ PreprocessorDefinitions="HAVE_CONFIG_H;YAML_DECLARE_STATIC"
+ MinimalRebuild="TRUE"
+ BasicRuntimeChecks="3"
+ RuntimeLibrary="3"
+ UsePrecompiledHeader="0"
+ WarningLevel="3"
+ Detect64BitPortabilityProblems="TRUE"
+ DebugInformationFormat="4"/>
+ <Tool
+ Name="VCCustomBuildTool"/>
+ <Tool
+ Name="VCLibrarianTool"
+ OutputFile="$(OutDir)/yaml.lib"/>
+ <Tool
+ Name="VCMIDLTool"/>
+ <Tool
+ Name="VCPostBuildEventTool"/>
+ <Tool
+ Name="VCPreBuildEventTool"/>
+ <Tool
+ Name="VCPreLinkEventTool"/>
+ <Tool
+ Name="VCResourceCompilerTool"/>
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"/>
+ <Tool
+ Name="VCXMLDataGeneratorTool"/>
+ <Tool
+ Name="VCManagedWrapperGeneratorTool"/>
+ <Tool
+ Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
+ </Configuration>
+ <Configuration
+ Name="Release|Win32"
+ OutputDirectory="Output\Release\lib"
+ IntermediateDirectory="Build\Release\lib"
+ ConfigurationType="4"
+ CharacterSet="2">
+ <Tool
+ Name="VCCLCompilerTool"
+ AdditionalIncludeDirectories="..;../../include"
+ PreprocessorDefinitions="HAVE_CONFIG_H;YAML_DECLARE_STATIC"
+ RuntimeLibrary="2"
+ UsePrecompiledHeader="0"
+ WarningLevel="3"
+ Detect64BitPortabilityProblems="TRUE"
+ DebugInformationFormat="3"/>
+ <Tool
+ Name="VCCustomBuildTool"/>
+ <Tool
+ Name="VCLibrarianTool"
+ OutputFile="$(OutDir)/yaml.lib"/>
+ <Tool
+ Name="VCMIDLTool"/>
+ <Tool
+ Name="VCPostBuildEventTool"/>
+ <Tool
+ Name="VCPreBuildEventTool"/>
+ <Tool
+ Name="VCPreLinkEventTool"/>
+ <Tool
+ Name="VCResourceCompilerTool"/>
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"/>
+ <Tool
+ Name="VCXMLDataGeneratorTool"/>
+ <Tool
+ Name="VCManagedWrapperGeneratorTool"/>
+ <Tool
+ Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
+ </Configuration>
+ </Configurations>
+ <References>
+ </References>
+ <Files>
+ <Filter
+ Name="Source Files"
+ Filter="cpp;c;cxx;def;odl;idl;hpj;bat;asm;asmx"
+ UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}">
+ <File
+ RelativePath="..\..\src\api.c">
+ </File>
+ <File
+ RelativePath="..\..\src\dumper.c">
+ </File>
+ <File
+ RelativePath="..\..\src\emitter.c">
+ </File>
+ <File
+ RelativePath="..\..\src\loader.c">
+ </File>
+ <File
+ RelativePath="..\..\src\parser.c">
+ </File>
+ <File
+ RelativePath="..\..\src\reader.c">
+ </File>
+ <File
+ RelativePath="..\..\src\scanner.c">
+ </File>
+ <File
+ RelativePath="..\..\src\writer.c">
+ </File>
+ </Filter>
+ <Filter
+ Name="Header Files"
+ Filter="h;hpp;hxx;hm;inl;inc;xsd"
+ UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}">
+ <File
+ RelativePath="..\config.h">
+ </File>
+ <File
+ RelativePath="..\..\include\yaml.h">
+ </File>
+ <File
+ RelativePath="..\..\src\yaml_private.h">
+ </File>
+ </Filter>
+ <Filter
+ Name="Resource Files"
+ Filter="rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx"
+ UniqueIdentifier="{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}">
+ </Filter>
+ </Files>
+ <Globals>
+ </Globals>
+</VisualStudioProject>
diff --git a/contrib/libyaml/win32/vs2003/yamldll.vcproj b/contrib/libyaml/win32/vs2003/yamldll.vcproj
new file mode 100644
index 0000000..7d472cef
--- /dev/null
+++ b/contrib/libyaml/win32/vs2003/yamldll.vcproj
@@ -0,0 +1,166 @@
+<?xml version="1.0" encoding="windows-1251"?>
+<VisualStudioProject
+ ProjectType="Visual C++"
+ Version="7.10"
+ Name="yamldll"
+ ProjectGUID="{019A6F4C-E704-4879-8E53-622BD4BC9C89}"
+ Keyword="Win32Proj">
+ <Platforms>
+ <Platform
+ Name="Win32"/>
+ </Platforms>
+ <Configurations>
+ <Configuration
+ Name="Debug|Win32"
+ OutputDirectory="Output\Debug\lib\DLL"
+ IntermediateDirectory="Build\Debug\lib\DLL"
+ ConfigurationType="2"
+ CharacterSet="2">
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="0"
+ AdditionalIncludeDirectories="..;../../include"
+ PreprocessorDefinitions="HAVE_CONFIG_H;YAML_DECLARE_EXPORT"
+ MinimalRebuild="TRUE"
+ BasicRuntimeChecks="3"
+ RuntimeLibrary="3"
+ UsePrecompiledHeader="0"
+ WarningLevel="3"
+ Detect64BitPortabilityProblems="TRUE"
+ DebugInformationFormat="4"/>
+ <Tool
+ Name="VCCustomBuildTool"/>
+ <Tool
+ Name="VCLinkerTool"
+ OutputFile="$(OutDir)/yaml.dll"
+ LinkIncremental="2"
+ GenerateDebugInformation="TRUE"
+ ProgramDatabaseFile="$(OutDir)/yaml.pdb"
+ SubSystem="2"
+ ImportLibrary="$(OutDir)/yaml.lib"
+ TargetMachine="1"/>
+ <Tool
+ Name="VCMIDLTool"/>
+ <Tool
+ Name="VCPostBuildEventTool"/>
+ <Tool
+ Name="VCPreBuildEventTool"/>
+ <Tool
+ Name="VCPreLinkEventTool"/>
+ <Tool
+ Name="VCResourceCompilerTool"/>
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"/>
+ <Tool
+ Name="VCXMLDataGeneratorTool"/>
+ <Tool
+ Name="VCWebDeploymentTool"/>
+ <Tool
+ Name="VCManagedWrapperGeneratorTool"/>
+ <Tool
+ Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
+ </Configuration>
+ <Configuration
+ Name="Release|Win32"
+ OutputDirectory="Output\Release\lib\DLL"
+ IntermediateDirectory="Build\Release\lib\DLL"
+ ConfigurationType="2"
+ CharacterSet="2">
+ <Tool
+ Name="VCCLCompilerTool"
+ AdditionalIncludeDirectories="..;../../include"
+ PreprocessorDefinitions="HAVE_CONFIG_H;YAML_DECLARE_EXPORT"
+ RuntimeLibrary="2"
+ UsePrecompiledHeader="0"
+ WarningLevel="3"
+ Detect64BitPortabilityProblems="TRUE"
+ DebugInformationFormat="3"/>
+ <Tool
+ Name="VCCustomBuildTool"/>
+ <Tool
+ Name="VCLinkerTool"
+ OutputFile="$(OutDir)/yaml.dll"
+ LinkIncremental="1"
+ GenerateDebugInformation="TRUE"
+ SubSystem="2"
+ OptimizeReferences="2"
+ EnableCOMDATFolding="2"
+ ImportLibrary="$(OutDir)/yaml.lib"
+ TargetMachine="1"/>
+ <Tool
+ Name="VCMIDLTool"/>
+ <Tool
+ Name="VCPostBuildEventTool"/>
+ <Tool
+ Name="VCPreBuildEventTool"/>
+ <Tool
+ Name="VCPreLinkEventTool"/>
+ <Tool
+ Name="VCResourceCompilerTool"/>
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"/>
+ <Tool
+ Name="VCXMLDataGeneratorTool"/>
+ <Tool
+ Name="VCWebDeploymentTool"/>
+ <Tool
+ Name="VCManagedWrapperGeneratorTool"/>
+ <Tool
+ Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
+ </Configuration>
+ </Configurations>
+ <References>
+ </References>
+ <Files>
+ <Filter
+ Name="Source Files"
+ Filter="cpp;c;cxx;def;odl;idl;hpj;bat;asm;asmx"
+ UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}">
+ <File
+ RelativePath="..\..\src\api.c">
+ </File>
+ <File
+ RelativePath="..\..\src\dumper.c">
+ </File>
+ <File
+ RelativePath="..\..\src\emitter.c">
+ </File>
+ <File
+ RelativePath="..\..\src\loader.c">
+ </File>
+ <File
+ RelativePath="..\..\src\parser.c">
+ </File>
+ <File
+ RelativePath="..\..\src\reader.c">
+ </File>
+ <File
+ RelativePath="..\..\src\scanner.c">
+ </File>
+ <File
+ RelativePath="..\..\src\writer.c">
+ </File>
+ </Filter>
+ <Filter
+ Name="Header Files"
+ Filter="h;hpp;hxx;hm;inl;inc;xsd"
+ UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}">
+ <File
+ RelativePath="..\config.h">
+ </File>
+ <File
+ RelativePath="..\..\include\yaml.h">
+ </File>
+ <File
+ RelativePath="..\..\src\yaml_private.h">
+ </File>
+ </Filter>
+ <Filter
+ Name="Resource Files"
+ Filter="rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx"
+ UniqueIdentifier="{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}">
+ </Filter>
+ </Files>
+ <Globals>
+ </Globals>
+</VisualStudioProject>
diff --git a/contrib/libyaml/win32/vs2008/example_deconstructor.vcproj b/contrib/libyaml/win32/vs2008/example_deconstructor.vcproj
new file mode 100644
index 0000000..a02a5ba
--- /dev/null
+++ b/contrib/libyaml/win32/vs2008/example_deconstructor.vcproj
@@ -0,0 +1,201 @@
+<?xml version="1.0" encoding="windows-1251"?>
+<VisualStudioProject
+ ProjectType="Visual C++"
+ Version="9,00"
+ Name="example_deconstructor"
+ ProjectGUID="{F8C735BD-5D83-4E21-8548-7984792033DB}"
+ Keyword="Win32Proj"
+ TargetFrameworkVersion="131072"
+ >
+ <Platforms>
+ <Platform
+ Name="Win32"
+ />
+ </Platforms>
+ <ToolFiles>
+ </ToolFiles>
+ <Configurations>
+ <Configuration
+ Name="Debug|Win32"
+ OutputDirectory="Output\Debug\bin"
+ IntermediateDirectory="Build\Debug\bin"
+ ConfigurationType="1"
+ InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops"
+ CharacterSet="2"
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="0"
+ AdditionalIncludeDirectories="../../include"
+ PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE;YAML_DECLARE_STATIC"
+ MinimalRebuild="true"
+ BasicRuntimeChecks="3"
+ RuntimeLibrary="3"
+ UsePrecompiledHeader="0"
+ WarningLevel="3"
+ Detect64BitPortabilityProblems="true"
+ DebugInformationFormat="4"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLinkerTool"
+ OutputFile="$(OutDir)/example_deconstructor.exe"
+ LinkIncremental="2"
+ GenerateDebugInformation="true"
+ ProgramDatabaseFile="$(OutDir)/example_deconstructor.pdb"
+ SubSystem="1"
+ RandomizedBaseAddress="1"
+ DataExecutionPrevention="0"
+ TargetMachine="1"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCManifestTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCAppVerifierTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ />
+ </Configuration>
+ <Configuration
+ Name="Release|Win32"
+ OutputDirectory="Output\Release\bin"
+ IntermediateDirectory="Build\Release\bin"
+ ConfigurationType="1"
+ InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops"
+ CharacterSet="2"
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ AdditionalIncludeDirectories="../../include"
+ PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE;YAML_DECLARE_STATIC"
+ RuntimeLibrary="2"
+ UsePrecompiledHeader="0"
+ WarningLevel="3"
+ Detect64BitPortabilityProblems="true"
+ DebugInformationFormat="3"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLinkerTool"
+ OutputFile="$(OutDir)/example_deconstructor.exe"
+ LinkIncremental="1"
+ GenerateDebugInformation="true"
+ SubSystem="1"
+ OptimizeReferences="2"
+ EnableCOMDATFolding="2"
+ RandomizedBaseAddress="1"
+ DataExecutionPrevention="0"
+ TargetMachine="1"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCManifestTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCAppVerifierTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ />
+ </Configuration>
+ </Configurations>
+ <References>
+ </References>
+ <Files>
+ <Filter
+ Name="Source Files"
+ Filter="cpp;c;cxx;def;odl;idl;hpj;bat;asm;asmx"
+ UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}"
+ >
+ <File
+ RelativePath="..\..\tests\example-deconstructor.c"
+ >
+ </File>
+ </Filter>
+ <Filter
+ Name="Header Files"
+ Filter="h;hpp;hxx;hm;inl;inc;xsd"
+ UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}"
+ >
+ </Filter>
+ <Filter
+ Name="Resource Files"
+ Filter="rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx"
+ UniqueIdentifier="{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}"
+ >
+ </Filter>
+ </Files>
+ <Globals>
+ </Globals>
+</VisualStudioProject>
diff --git a/contrib/libyaml/win32/vs2008/example_deconstructor_alt.vcproj b/contrib/libyaml/win32/vs2008/example_deconstructor_alt.vcproj
new file mode 100644
index 0000000..169cb99
--- /dev/null
+++ b/contrib/libyaml/win32/vs2008/example_deconstructor_alt.vcproj
@@ -0,0 +1,201 @@
+<?xml version="1.0" encoding="windows-1251"?>
+<VisualStudioProject
+ ProjectType="Visual C++"
+ Version="9,00"
+ Name="example_deconstructor_alt"
+ ProjectGUID="{AEBABE36-E103-4E4B-84D4-B4546285C35A}"
+ Keyword="Win32Proj"
+ TargetFrameworkVersion="131072"
+ >
+ <Platforms>
+ <Platform
+ Name="Win32"
+ />
+ </Platforms>
+ <ToolFiles>
+ </ToolFiles>
+ <Configurations>
+ <Configuration
+ Name="Debug|Win32"
+ OutputDirectory="Output\Debug\bin"
+ IntermediateDirectory="Build\Debug\bin"
+ ConfigurationType="1"
+ InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops"
+ CharacterSet="2"
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="0"
+ AdditionalIncludeDirectories="../../include"
+ PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE;YAML_DECLARE_STATIC"
+ MinimalRebuild="true"
+ BasicRuntimeChecks="3"
+ RuntimeLibrary="3"
+ UsePrecompiledHeader="0"
+ WarningLevel="3"
+ Detect64BitPortabilityProblems="true"
+ DebugInformationFormat="4"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLinkerTool"
+ OutputFile="$(OutDir)/example_deconstructor_alt.exe"
+ LinkIncremental="2"
+ GenerateDebugInformation="true"
+ ProgramDatabaseFile="$(OutDir)/example_deconstructor_alt.pdb"
+ SubSystem="1"
+ RandomizedBaseAddress="1"
+ DataExecutionPrevention="0"
+ TargetMachine="1"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCManifestTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCAppVerifierTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ />
+ </Configuration>
+ <Configuration
+ Name="Release|Win32"
+ OutputDirectory="Output\Release\bin"
+ IntermediateDirectory="Build\Release\bin"
+ ConfigurationType="1"
+ InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops"
+ CharacterSet="2"
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ AdditionalIncludeDirectories="../../include"
+ PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE;YAML_DECLARE_STATIC"
+ RuntimeLibrary="2"
+ UsePrecompiledHeader="0"
+ WarningLevel="3"
+ Detect64BitPortabilityProblems="true"
+ DebugInformationFormat="3"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLinkerTool"
+ OutputFile="$(OutDir)/example_deconstructor_alt.exe"
+ LinkIncremental="1"
+ GenerateDebugInformation="true"
+ SubSystem="1"
+ OptimizeReferences="2"
+ EnableCOMDATFolding="2"
+ RandomizedBaseAddress="1"
+ DataExecutionPrevention="0"
+ TargetMachine="1"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCManifestTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCAppVerifierTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ />
+ </Configuration>
+ </Configurations>
+ <References>
+ </References>
+ <Files>
+ <Filter
+ Name="Source Files"
+ Filter="cpp;c;cxx;def;odl;idl;hpj;bat;asm;asmx"
+ UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}"
+ >
+ <File
+ RelativePath="..\..\tests\example-deconstructor-alt.c"
+ >
+ </File>
+ </Filter>
+ <Filter
+ Name="Header Files"
+ Filter="h;hpp;hxx;hm;inl;inc;xsd"
+ UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}"
+ >
+ </Filter>
+ <Filter
+ Name="Resource Files"
+ Filter="rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx"
+ UniqueIdentifier="{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}"
+ >
+ </Filter>
+ </Files>
+ <Globals>
+ </Globals>
+</VisualStudioProject>
diff --git a/contrib/libyaml/win32/vs2008/example_reformatter.vcproj b/contrib/libyaml/win32/vs2008/example_reformatter.vcproj
new file mode 100644
index 0000000..c2e1cee
--- /dev/null
+++ b/contrib/libyaml/win32/vs2008/example_reformatter.vcproj
@@ -0,0 +1,201 @@
+<?xml version="1.0" encoding="windows-1251"?>
+<VisualStudioProject
+ ProjectType="Visual C++"
+ Version="9,00"
+ Name="example_reformatter"
+ ProjectGUID="{BC86310C-0914-4F66-9272-30FD09900D70}"
+ Keyword="Win32Proj"
+ TargetFrameworkVersion="131072"
+ >
+ <Platforms>
+ <Platform
+ Name="Win32"
+ />
+ </Platforms>
+ <ToolFiles>
+ </ToolFiles>
+ <Configurations>
+ <Configuration
+ Name="Debug|Win32"
+ OutputDirectory="Output\Debug\bin"
+ IntermediateDirectory="Build\Debug\bin"
+ ConfigurationType="1"
+ InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops"
+ CharacterSet="2"
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="0"
+ AdditionalIncludeDirectories="../../include"
+ PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE;YAML_DECLARE_STATIC"
+ MinimalRebuild="true"
+ BasicRuntimeChecks="3"
+ RuntimeLibrary="3"
+ UsePrecompiledHeader="0"
+ WarningLevel="3"
+ Detect64BitPortabilityProblems="true"
+ DebugInformationFormat="4"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLinkerTool"
+ OutputFile="$(OutDir)/example_reformatter.exe"
+ LinkIncremental="2"
+ GenerateDebugInformation="true"
+ ProgramDatabaseFile="$(OutDir)/example_reformatter.pdb"
+ SubSystem="1"
+ RandomizedBaseAddress="1"
+ DataExecutionPrevention="0"
+ TargetMachine="1"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCManifestTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCAppVerifierTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ />
+ </Configuration>
+ <Configuration
+ Name="Release|Win32"
+ OutputDirectory="Output\Release\bin"
+ IntermediateDirectory="Build\Release\bin"
+ ConfigurationType="1"
+ InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops"
+ CharacterSet="2"
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ AdditionalIncludeDirectories="../../include"
+ PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE;YAML_DECLARE_STATIC"
+ RuntimeLibrary="2"
+ UsePrecompiledHeader="0"
+ WarningLevel="3"
+ Detect64BitPortabilityProblems="true"
+ DebugInformationFormat="3"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLinkerTool"
+ OutputFile="$(OutDir)/example_reformatter.exe"
+ LinkIncremental="1"
+ GenerateDebugInformation="true"
+ SubSystem="1"
+ OptimizeReferences="2"
+ EnableCOMDATFolding="2"
+ RandomizedBaseAddress="1"
+ DataExecutionPrevention="0"
+ TargetMachine="1"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCManifestTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCAppVerifierTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ />
+ </Configuration>
+ </Configurations>
+ <References>
+ </References>
+ <Files>
+ <Filter
+ Name="Source Files"
+ Filter="cpp;c;cxx;def;odl;idl;hpj;bat;asm;asmx"
+ UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}"
+ >
+ <File
+ RelativePath="..\..\tests\example-reformatter.c"
+ >
+ </File>
+ </Filter>
+ <Filter
+ Name="Header Files"
+ Filter="h;hpp;hxx;hm;inl;inc;xsd"
+ UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}"
+ >
+ </Filter>
+ <Filter
+ Name="Resource Files"
+ Filter="rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx"
+ UniqueIdentifier="{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}"
+ >
+ </Filter>
+ </Files>
+ <Globals>
+ </Globals>
+</VisualStudioProject>
diff --git a/contrib/libyaml/win32/vs2008/example_reformatter_alt.vcproj b/contrib/libyaml/win32/vs2008/example_reformatter_alt.vcproj
new file mode 100644
index 0000000..28e5b0f
--- /dev/null
+++ b/contrib/libyaml/win32/vs2008/example_reformatter_alt.vcproj
@@ -0,0 +1,201 @@
+<?xml version="1.0" encoding="windows-1251"?>
+<VisualStudioProject
+ ProjectType="Visual C++"
+ Version="9,00"
+ Name="example_reformatter_alt"
+ ProjectGUID="{C0209B44-8A45-4D9E-B430-100679BC6B2D}"
+ Keyword="Win32Proj"
+ TargetFrameworkVersion="131072"
+ >
+ <Platforms>
+ <Platform
+ Name="Win32"
+ />
+ </Platforms>
+ <ToolFiles>
+ </ToolFiles>
+ <Configurations>
+ <Configuration
+ Name="Debug|Win32"
+ OutputDirectory="Output\Debug\bin"
+ IntermediateDirectory="Build\Debug\bin"
+ ConfigurationType="1"
+ InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops"
+ CharacterSet="2"
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="0"
+ AdditionalIncludeDirectories="../../include"
+ PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE;YAML_DECLARE_STATIC"
+ MinimalRebuild="true"
+ BasicRuntimeChecks="3"
+ RuntimeLibrary="3"
+ UsePrecompiledHeader="0"
+ WarningLevel="3"
+ Detect64BitPortabilityProblems="true"
+ DebugInformationFormat="4"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLinkerTool"
+ OutputFile="$(OutDir)/example_reformatter_alt.exe"
+ LinkIncremental="2"
+ GenerateDebugInformation="true"
+ ProgramDatabaseFile="$(OutDir)/example_reformatter_alt.pdb"
+ SubSystem="1"
+ RandomizedBaseAddress="1"
+ DataExecutionPrevention="0"
+ TargetMachine="1"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCManifestTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCAppVerifierTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ />
+ </Configuration>
+ <Configuration
+ Name="Release|Win32"
+ OutputDirectory="Output\Release\bin"
+ IntermediateDirectory="Build\Release\bin"
+ ConfigurationType="1"
+ InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops"
+ CharacterSet="2"
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ AdditionalIncludeDirectories="../../include"
+ PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE;YAML_DECLARE_STATIC"
+ RuntimeLibrary="2"
+ UsePrecompiledHeader="0"
+ WarningLevel="3"
+ Detect64BitPortabilityProblems="true"
+ DebugInformationFormat="3"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLinkerTool"
+ OutputFile="$(OutDir)/example_reformatter_alt.exe"
+ LinkIncremental="1"
+ GenerateDebugInformation="true"
+ SubSystem="1"
+ OptimizeReferences="2"
+ EnableCOMDATFolding="2"
+ RandomizedBaseAddress="1"
+ DataExecutionPrevention="0"
+ TargetMachine="1"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCManifestTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCAppVerifierTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ />
+ </Configuration>
+ </Configurations>
+ <References>
+ </References>
+ <Files>
+ <Filter
+ Name="Source Files"
+ Filter="cpp;c;cxx;def;odl;idl;hpj;bat;asm;asmx"
+ UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}"
+ >
+ <File
+ RelativePath="..\..\tests\example-reformatter-alt.c"
+ >
+ </File>
+ </Filter>
+ <Filter
+ Name="Header Files"
+ Filter="h;hpp;hxx;hm;inl;inc;xsd"
+ UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}"
+ >
+ </Filter>
+ <Filter
+ Name="Resource Files"
+ Filter="rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx"
+ UniqueIdentifier="{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}"
+ >
+ </Filter>
+ </Files>
+ <Globals>
+ </Globals>
+</VisualStudioProject>
diff --git a/contrib/libyaml/win32/vs2008/libyaml.sln b/contrib/libyaml/win32/vs2008/libyaml.sln
new file mode 100644
index 0000000..4b1610a
--- /dev/null
+++ b/contrib/libyaml/win32/vs2008/libyaml.sln
@@ -0,0 +1,124 @@
+Microsoft Visual Studio Solution File, Format Version 10.00
+# Visual Studio 2008
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "yaml", "yaml.vcproj", "{5CE8051A-3F0C-4C39-B1C0-3338E48BA60F}"
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "yamldll", "yamldll.vcproj", "{019A6F4C-E704-4879-8E53-622BD4BC9C89}"
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "example_deconstructor_alt", "example_deconstructor_alt.vcproj", "{AEBABE36-E103-4E4B-84D4-B4546285C35A}"
+ ProjectSection(ProjectDependencies) = postProject
+ {5CE8051A-3F0C-4C39-B1C0-3338E48BA60F} = {5CE8051A-3F0C-4C39-B1C0-3338E48BA60F}
+ EndProjectSection
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "example_deconstructor", "example_deconstructor.vcproj", "{F8C735BD-5D83-4E21-8548-7984792033DB}"
+ ProjectSection(ProjectDependencies) = postProject
+ {5CE8051A-3F0C-4C39-B1C0-3338E48BA60F} = {5CE8051A-3F0C-4C39-B1C0-3338E48BA60F}
+ EndProjectSection
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "example_reformatter", "example_reformatter.vcproj", "{BC86310C-0914-4F66-9272-30FD09900D70}"
+ ProjectSection(ProjectDependencies) = postProject
+ {5CE8051A-3F0C-4C39-B1C0-3338E48BA60F} = {5CE8051A-3F0C-4C39-B1C0-3338E48BA60F}
+ EndProjectSection
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "example_reformatter_alt", "example_reformatter_alt.vcproj", "{C0209B44-8A45-4D9E-B430-100679BC6B2D}"
+ ProjectSection(ProjectDependencies) = postProject
+ {5CE8051A-3F0C-4C39-B1C0-3338E48BA60F} = {5CE8051A-3F0C-4C39-B1C0-3338E48BA60F}
+ EndProjectSection
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "run_dumper", "run_dumper.vcproj", "{99AD9500-BD7A-4996-9FA2-2E4EAE7E6BCB}"
+ ProjectSection(ProjectDependencies) = postProject
+ {5CE8051A-3F0C-4C39-B1C0-3338E48BA60F} = {5CE8051A-3F0C-4C39-B1C0-3338E48BA60F}
+ EndProjectSection
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "run_emitter", "run_emitter.vcproj", "{CBA602BE-8FE4-4E68-A401-3C537EAA7239}"
+ ProjectSection(ProjectDependencies) = postProject
+ {5CE8051A-3F0C-4C39-B1C0-3338E48BA60F} = {5CE8051A-3F0C-4C39-B1C0-3338E48BA60F}
+ EndProjectSection
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "run_loader", "run_loader.vcproj", "{B9549FB7-A259-4518-A9CD-9D2108C2C728}"
+ ProjectSection(ProjectDependencies) = postProject
+ {5CE8051A-3F0C-4C39-B1C0-3338E48BA60F} = {5CE8051A-3F0C-4C39-B1C0-3338E48BA60F}
+ EndProjectSection
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "run_parser", "run_parser.vcproj", "{8EC75FB4-951D-4A19-8DCD-ED2E97E4B234}"
+ ProjectSection(ProjectDependencies) = postProject
+ {5CE8051A-3F0C-4C39-B1C0-3338E48BA60F} = {5CE8051A-3F0C-4C39-B1C0-3338E48BA60F}
+ EndProjectSection
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "run_scanner", "run_scanner.vcproj", "{5D3F321E-4A86-4842-9F45-105A7F373104}"
+ ProjectSection(ProjectDependencies) = postProject
+ {5CE8051A-3F0C-4C39-B1C0-3338E48BA60F} = {5CE8051A-3F0C-4C39-B1C0-3338E48BA60F}
+ EndProjectSection
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "test_reader", "test_reader.vcproj", "{898C9408-2480-4BF8-97B0-B1464B7BB5C4}"
+ ProjectSection(ProjectDependencies) = postProject
+ {5CE8051A-3F0C-4C39-B1C0-3338E48BA60F} = {5CE8051A-3F0C-4C39-B1C0-3338E48BA60F}
+ EndProjectSection
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "test_version", "test_version.vcproj", "{BF6CA7A9-0767-4A4E-BC42-9B7C8E105991}"
+ ProjectSection(ProjectDependencies) = postProject
+ {5CE8051A-3F0C-4C39-B1C0-3338E48BA60F} = {5CE8051A-3F0C-4C39-B1C0-3338E48BA60F}
+ EndProjectSection
+EndProject
+Global
+ GlobalSection(SolutionConfigurationPlatforms) = preSolution
+ Debug|Win32 = Debug|Win32
+ Release|Win32 = Release|Win32
+ EndGlobalSection
+ GlobalSection(ProjectConfigurationPlatforms) = postSolution
+ {5CE8051A-3F0C-4C39-B1C0-3338E48BA60F}.Debug|Win32.ActiveCfg = Debug|Win32
+ {5CE8051A-3F0C-4C39-B1C0-3338E48BA60F}.Debug|Win32.Build.0 = Debug|Win32
+ {5CE8051A-3F0C-4C39-B1C0-3338E48BA60F}.Release|Win32.ActiveCfg = Release|Win32
+ {5CE8051A-3F0C-4C39-B1C0-3338E48BA60F}.Release|Win32.Build.0 = Release|Win32
+ {019A6F4C-E704-4879-8E53-622BD4BC9C89}.Debug|Win32.ActiveCfg = Debug|Win32
+ {019A6F4C-E704-4879-8E53-622BD4BC9C89}.Debug|Win32.Build.0 = Debug|Win32
+ {019A6F4C-E704-4879-8E53-622BD4BC9C89}.Release|Win32.ActiveCfg = Release|Win32
+ {019A6F4C-E704-4879-8E53-622BD4BC9C89}.Release|Win32.Build.0 = Release|Win32
+ {AEBABE36-E103-4E4B-84D4-B4546285C35A}.Debug|Win32.ActiveCfg = Debug|Win32
+ {AEBABE36-E103-4E4B-84D4-B4546285C35A}.Debug|Win32.Build.0 = Debug|Win32
+ {AEBABE36-E103-4E4B-84D4-B4546285C35A}.Release|Win32.ActiveCfg = Release|Win32
+ {AEBABE36-E103-4E4B-84D4-B4546285C35A}.Release|Win32.Build.0 = Release|Win32
+ {F8C735BD-5D83-4E21-8548-7984792033DB}.Debug|Win32.ActiveCfg = Debug|Win32
+ {F8C735BD-5D83-4E21-8548-7984792033DB}.Debug|Win32.Build.0 = Debug|Win32
+ {F8C735BD-5D83-4E21-8548-7984792033DB}.Release|Win32.ActiveCfg = Release|Win32
+ {F8C735BD-5D83-4E21-8548-7984792033DB}.Release|Win32.Build.0 = Release|Win32
+ {BC86310C-0914-4F66-9272-30FD09900D70}.Debug|Win32.ActiveCfg = Debug|Win32
+ {BC86310C-0914-4F66-9272-30FD09900D70}.Debug|Win32.Build.0 = Debug|Win32
+ {BC86310C-0914-4F66-9272-30FD09900D70}.Release|Win32.ActiveCfg = Release|Win32
+ {BC86310C-0914-4F66-9272-30FD09900D70}.Release|Win32.Build.0 = Release|Win32
+ {C0209B44-8A45-4D9E-B430-100679BC6B2D}.Debug|Win32.ActiveCfg = Debug|Win32
+ {C0209B44-8A45-4D9E-B430-100679BC6B2D}.Debug|Win32.Build.0 = Debug|Win32
+ {C0209B44-8A45-4D9E-B430-100679BC6B2D}.Release|Win32.ActiveCfg = Release|Win32
+ {C0209B44-8A45-4D9E-B430-100679BC6B2D}.Release|Win32.Build.0 = Release|Win32
+ {99AD9500-BD7A-4996-9FA2-2E4EAE7E6BCB}.Debug|Win32.ActiveCfg = Debug|Win32
+ {99AD9500-BD7A-4996-9FA2-2E4EAE7E6BCB}.Debug|Win32.Build.0 = Debug|Win32
+ {99AD9500-BD7A-4996-9FA2-2E4EAE7E6BCB}.Release|Win32.ActiveCfg = Release|Win32
+ {99AD9500-BD7A-4996-9FA2-2E4EAE7E6BCB}.Release|Win32.Build.0 = Release|Win32
+ {CBA602BE-8FE4-4E68-A401-3C537EAA7239}.Debug|Win32.ActiveCfg = Debug|Win32
+ {CBA602BE-8FE4-4E68-A401-3C537EAA7239}.Debug|Win32.Build.0 = Debug|Win32
+ {CBA602BE-8FE4-4E68-A401-3C537EAA7239}.Release|Win32.ActiveCfg = Release|Win32
+ {CBA602BE-8FE4-4E68-A401-3C537EAA7239}.Release|Win32.Build.0 = Release|Win32
+ {B9549FB7-A259-4518-A9CD-9D2108C2C728}.Debug|Win32.ActiveCfg = Debug|Win32
+ {B9549FB7-A259-4518-A9CD-9D2108C2C728}.Debug|Win32.Build.0 = Debug|Win32
+ {B9549FB7-A259-4518-A9CD-9D2108C2C728}.Release|Win32.ActiveCfg = Release|Win32
+ {B9549FB7-A259-4518-A9CD-9D2108C2C728}.Release|Win32.Build.0 = Release|Win32
+ {8EC75FB4-951D-4A19-8DCD-ED2E97E4B234}.Debug|Win32.ActiveCfg = Debug|Win32
+ {8EC75FB4-951D-4A19-8DCD-ED2E97E4B234}.Debug|Win32.Build.0 = Debug|Win32
+ {8EC75FB4-951D-4A19-8DCD-ED2E97E4B234}.Release|Win32.ActiveCfg = Release|Win32
+ {8EC75FB4-951D-4A19-8DCD-ED2E97E4B234}.Release|Win32.Build.0 = Release|Win32
+ {5D3F321E-4A86-4842-9F45-105A7F373104}.Debug|Win32.ActiveCfg = Debug|Win32
+ {5D3F321E-4A86-4842-9F45-105A7F373104}.Debug|Win32.Build.0 = Debug|Win32
+ {5D3F321E-4A86-4842-9F45-105A7F373104}.Release|Win32.ActiveCfg = Release|Win32
+ {5D3F321E-4A86-4842-9F45-105A7F373104}.Release|Win32.Build.0 = Release|Win32
+ {898C9408-2480-4BF8-97B0-B1464B7BB5C4}.Debug|Win32.ActiveCfg = Debug|Win32
+ {898C9408-2480-4BF8-97B0-B1464B7BB5C4}.Debug|Win32.Build.0 = Debug|Win32
+ {898C9408-2480-4BF8-97B0-B1464B7BB5C4}.Release|Win32.ActiveCfg = Release|Win32
+ {898C9408-2480-4BF8-97B0-B1464B7BB5C4}.Release|Win32.Build.0 = Release|Win32
+ {BF6CA7A9-0767-4A4E-BC42-9B7C8E105991}.Debug|Win32.ActiveCfg = Debug|Win32
+ {BF6CA7A9-0767-4A4E-BC42-9B7C8E105991}.Debug|Win32.Build.0 = Debug|Win32
+ {BF6CA7A9-0767-4A4E-BC42-9B7C8E105991}.Release|Win32.ActiveCfg = Release|Win32
+ {BF6CA7A9-0767-4A4E-BC42-9B7C8E105991}.Release|Win32.Build.0 = Release|Win32
+ EndGlobalSection
+ GlobalSection(SolutionProperties) = preSolution
+ HideSolutionNode = FALSE
+ EndGlobalSection
+EndGlobal
diff --git a/contrib/libyaml/win32/vs2008/run_dumper.vcproj b/contrib/libyaml/win32/vs2008/run_dumper.vcproj
new file mode 100644
index 0000000..36f1da0
--- /dev/null
+++ b/contrib/libyaml/win32/vs2008/run_dumper.vcproj
@@ -0,0 +1,201 @@
+<?xml version="1.0" encoding="windows-1251"?>
+<VisualStudioProject
+ ProjectType="Visual C++"
+ Version="9,00"
+ Name="run_dumper"
+ ProjectGUID="{99AD9500-BD7A-4996-9FA2-2E4EAE7E6BCB}"
+ Keyword="Win32Proj"
+ TargetFrameworkVersion="131072"
+ >
+ <Platforms>
+ <Platform
+ Name="Win32"
+ />
+ </Platforms>
+ <ToolFiles>
+ </ToolFiles>
+ <Configurations>
+ <Configuration
+ Name="Debug|Win32"
+ OutputDirectory="Output\Debug\bin"
+ IntermediateDirectory="Build\Debug\bin"
+ ConfigurationType="1"
+ InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops"
+ CharacterSet="2"
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="0"
+ AdditionalIncludeDirectories="../../include"
+ PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE;YAML_DECLARE_STATIC"
+ MinimalRebuild="true"
+ BasicRuntimeChecks="3"
+ RuntimeLibrary="3"
+ UsePrecompiledHeader="0"
+ WarningLevel="3"
+ Detect64BitPortabilityProblems="true"
+ DebugInformationFormat="4"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLinkerTool"
+ OutputFile="$(OutDir)/run_dumper.exe"
+ LinkIncremental="2"
+ GenerateDebugInformation="true"
+ ProgramDatabaseFile="$(OutDir)/run_dumper.pdb"
+ SubSystem="1"
+ RandomizedBaseAddress="1"
+ DataExecutionPrevention="0"
+ TargetMachine="1"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCManifestTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCAppVerifierTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ />
+ </Configuration>
+ <Configuration
+ Name="Release|Win32"
+ OutputDirectory="Output\Release\bin"
+ IntermediateDirectory="Build\Release\bin"
+ ConfigurationType="1"
+ InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops"
+ CharacterSet="2"
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ AdditionalIncludeDirectories="../../include"
+ PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE;YAML_DECLARE_STATIC"
+ RuntimeLibrary="2"
+ UsePrecompiledHeader="0"
+ WarningLevel="3"
+ Detect64BitPortabilityProblems="true"
+ DebugInformationFormat="3"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLinkerTool"
+ OutputFile="$(OutDir)/run_dumper.exe"
+ LinkIncremental="1"
+ GenerateDebugInformation="true"
+ SubSystem="1"
+ OptimizeReferences="2"
+ EnableCOMDATFolding="2"
+ RandomizedBaseAddress="1"
+ DataExecutionPrevention="0"
+ TargetMachine="1"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCManifestTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCAppVerifierTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ />
+ </Configuration>
+ </Configurations>
+ <References>
+ </References>
+ <Files>
+ <Filter
+ Name="Source Files"
+ Filter="cpp;c;cxx;def;odl;idl;hpj;bat;asm;asmx"
+ UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}"
+ >
+ <File
+ RelativePath="..\..\tests\run-dumper.c"
+ >
+ </File>
+ </Filter>
+ <Filter
+ Name="Header Files"
+ Filter="h;hpp;hxx;hm;inl;inc;xsd"
+ UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}"
+ >
+ </Filter>
+ <Filter
+ Name="Resource Files"
+ Filter="rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx"
+ UniqueIdentifier="{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}"
+ >
+ </Filter>
+ </Files>
+ <Globals>
+ </Globals>
+</VisualStudioProject>
diff --git a/contrib/libyaml/win32/vs2008/run_emitter.vcproj b/contrib/libyaml/win32/vs2008/run_emitter.vcproj
new file mode 100644
index 0000000..3021f2d
--- /dev/null
+++ b/contrib/libyaml/win32/vs2008/run_emitter.vcproj
@@ -0,0 +1,201 @@
+<?xml version="1.0" encoding="windows-1251"?>
+<VisualStudioProject
+ ProjectType="Visual C++"
+ Version="9,00"
+ Name="run_emitter"
+ ProjectGUID="{CBA602BE-8FE4-4E68-A401-3C537EAA7239}"
+ Keyword="Win32Proj"
+ TargetFrameworkVersion="131072"
+ >
+ <Platforms>
+ <Platform
+ Name="Win32"
+ />
+ </Platforms>
+ <ToolFiles>
+ </ToolFiles>
+ <Configurations>
+ <Configuration
+ Name="Debug|Win32"
+ OutputDirectory="Output\Debug\bin"
+ IntermediateDirectory="Build\Debug\bin"
+ ConfigurationType="1"
+ InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops"
+ CharacterSet="2"
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="0"
+ AdditionalIncludeDirectories="../../include"
+ PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE;YAML_DECLARE_STATIC"
+ MinimalRebuild="true"
+ BasicRuntimeChecks="3"
+ RuntimeLibrary="3"
+ UsePrecompiledHeader="0"
+ WarningLevel="3"
+ Detect64BitPortabilityProblems="true"
+ DebugInformationFormat="4"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLinkerTool"
+ OutputFile="$(OutDir)/run_emitter.exe"
+ LinkIncremental="2"
+ GenerateDebugInformation="true"
+ ProgramDatabaseFile="$(OutDir)/run_emitter.pdb"
+ SubSystem="1"
+ RandomizedBaseAddress="1"
+ DataExecutionPrevention="0"
+ TargetMachine="1"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCManifestTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCAppVerifierTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ />
+ </Configuration>
+ <Configuration
+ Name="Release|Win32"
+ OutputDirectory="Output\Release\bin"
+ IntermediateDirectory="Build\Release\bin"
+ ConfigurationType="1"
+ InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops"
+ CharacterSet="2"
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ AdditionalIncludeDirectories="../../include"
+ PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE;YAML_DECLARE_STATIC"
+ RuntimeLibrary="2"
+ UsePrecompiledHeader="0"
+ WarningLevel="3"
+ Detect64BitPortabilityProblems="true"
+ DebugInformationFormat="3"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLinkerTool"
+ OutputFile="$(OutDir)/run_emitter.exe"
+ LinkIncremental="1"
+ GenerateDebugInformation="true"
+ SubSystem="1"
+ OptimizeReferences="2"
+ EnableCOMDATFolding="2"
+ RandomizedBaseAddress="1"
+ DataExecutionPrevention="0"
+ TargetMachine="1"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCManifestTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCAppVerifierTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ />
+ </Configuration>
+ </Configurations>
+ <References>
+ </References>
+ <Files>
+ <Filter
+ Name="Source Files"
+ Filter="cpp;c;cxx;def;odl;idl;hpj;bat;asm;asmx"
+ UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}"
+ >
+ <File
+ RelativePath="..\..\tests\run-emitter.c"
+ >
+ </File>
+ </Filter>
+ <Filter
+ Name="Header Files"
+ Filter="h;hpp;hxx;hm;inl;inc;xsd"
+ UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}"
+ >
+ </Filter>
+ <Filter
+ Name="Resource Files"
+ Filter="rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx"
+ UniqueIdentifier="{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}"
+ >
+ </Filter>
+ </Files>
+ <Globals>
+ </Globals>
+</VisualStudioProject>
diff --git a/contrib/libyaml/win32/vs2008/run_loader.vcproj b/contrib/libyaml/win32/vs2008/run_loader.vcproj
new file mode 100644
index 0000000..e2f1d62
--- /dev/null
+++ b/contrib/libyaml/win32/vs2008/run_loader.vcproj
@@ -0,0 +1,201 @@
+<?xml version="1.0" encoding="windows-1251"?>
+<VisualStudioProject
+ ProjectType="Visual C++"
+ Version="9,00"
+ Name="run_loader"
+ ProjectGUID="{B9549FB7-A259-4518-A9CD-9D2108C2C728}"
+ Keyword="Win32Proj"
+ TargetFrameworkVersion="131072"
+ >
+ <Platforms>
+ <Platform
+ Name="Win32"
+ />
+ </Platforms>
+ <ToolFiles>
+ </ToolFiles>
+ <Configurations>
+ <Configuration
+ Name="Debug|Win32"
+ OutputDirectory="Output\Debug\bin"
+ IntermediateDirectory="Build\Debug\bin"
+ ConfigurationType="1"
+ InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops"
+ CharacterSet="2"
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="0"
+ AdditionalIncludeDirectories="../../include"
+ PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE;YAML_DECLARE_STATIC"
+ MinimalRebuild="true"
+ BasicRuntimeChecks="3"
+ RuntimeLibrary="3"
+ UsePrecompiledHeader="0"
+ WarningLevel="3"
+ Detect64BitPortabilityProblems="true"
+ DebugInformationFormat="4"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLinkerTool"
+ OutputFile="$(OutDir)/run_loader.exe"
+ LinkIncremental="2"
+ GenerateDebugInformation="true"
+ ProgramDatabaseFile="$(OutDir)/run_loader.pdb"
+ SubSystem="1"
+ RandomizedBaseAddress="1"
+ DataExecutionPrevention="0"
+ TargetMachine="1"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCManifestTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCAppVerifierTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ />
+ </Configuration>
+ <Configuration
+ Name="Release|Win32"
+ OutputDirectory="Output\Release\bin"
+ IntermediateDirectory="Build\Release\bin"
+ ConfigurationType="1"
+ InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops"
+ CharacterSet="2"
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ AdditionalIncludeDirectories="../../include"
+ PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE;YAML_DECLARE_STATIC"
+ RuntimeLibrary="2"
+ UsePrecompiledHeader="0"
+ WarningLevel="3"
+ Detect64BitPortabilityProblems="true"
+ DebugInformationFormat="3"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLinkerTool"
+ OutputFile="$(OutDir)/run_loader.exe"
+ LinkIncremental="1"
+ GenerateDebugInformation="true"
+ SubSystem="1"
+ OptimizeReferences="2"
+ EnableCOMDATFolding="2"
+ RandomizedBaseAddress="1"
+ DataExecutionPrevention="0"
+ TargetMachine="1"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCManifestTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCAppVerifierTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ />
+ </Configuration>
+ </Configurations>
+ <References>
+ </References>
+ <Files>
+ <Filter
+ Name="Source Files"
+ Filter="cpp;c;cxx;def;odl;idl;hpj;bat;asm;asmx"
+ UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}"
+ >
+ <File
+ RelativePath="..\..\tests\run-loader.c"
+ >
+ </File>
+ </Filter>
+ <Filter
+ Name="Header Files"
+ Filter="h;hpp;hxx;hm;inl;inc;xsd"
+ UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}"
+ >
+ </Filter>
+ <Filter
+ Name="Resource Files"
+ Filter="rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx"
+ UniqueIdentifier="{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}"
+ >
+ </Filter>
+ </Files>
+ <Globals>
+ </Globals>
+</VisualStudioProject>
diff --git a/contrib/libyaml/win32/vs2008/run_parser.vcproj b/contrib/libyaml/win32/vs2008/run_parser.vcproj
new file mode 100644
index 0000000..c98799d
--- /dev/null
+++ b/contrib/libyaml/win32/vs2008/run_parser.vcproj
@@ -0,0 +1,201 @@
+<?xml version="1.0" encoding="windows-1251"?>
+<VisualStudioProject
+ ProjectType="Visual C++"
+ Version="9,00"
+ Name="run_parser"
+ ProjectGUID="{8EC75FB4-951D-4A19-8DCD-ED2E97E4B234}"
+ Keyword="Win32Proj"
+ TargetFrameworkVersion="131072"
+ >
+ <Platforms>
+ <Platform
+ Name="Win32"
+ />
+ </Platforms>
+ <ToolFiles>
+ </ToolFiles>
+ <Configurations>
+ <Configuration
+ Name="Debug|Win32"
+ OutputDirectory="Output\Debug\bin"
+ IntermediateDirectory="Build\Debug\bin"
+ ConfigurationType="1"
+ InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops"
+ CharacterSet="2"
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="0"
+ AdditionalIncludeDirectories="../../include"
+ PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE;YAML_DECLARE_STATIC"
+ MinimalRebuild="true"
+ BasicRuntimeChecks="3"
+ RuntimeLibrary="3"
+ UsePrecompiledHeader="0"
+ WarningLevel="3"
+ Detect64BitPortabilityProblems="true"
+ DebugInformationFormat="4"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLinkerTool"
+ OutputFile="$(OutDir)/run_parser.exe"
+ LinkIncremental="2"
+ GenerateDebugInformation="true"
+ ProgramDatabaseFile="$(OutDir)/run_parser.pdb"
+ SubSystem="1"
+ RandomizedBaseAddress="1"
+ DataExecutionPrevention="0"
+ TargetMachine="1"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCManifestTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCAppVerifierTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ />
+ </Configuration>
+ <Configuration
+ Name="Release|Win32"
+ OutputDirectory="Output\Release\bin"
+ IntermediateDirectory="Build\Release\bin"
+ ConfigurationType="1"
+ InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops"
+ CharacterSet="2"
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ AdditionalIncludeDirectories="../../include"
+ PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE;YAML_DECLARE_STATIC"
+ RuntimeLibrary="2"
+ UsePrecompiledHeader="0"
+ WarningLevel="3"
+ Detect64BitPortabilityProblems="true"
+ DebugInformationFormat="3"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLinkerTool"
+ OutputFile="$(OutDir)/run_parser.exe"
+ LinkIncremental="1"
+ GenerateDebugInformation="true"
+ SubSystem="1"
+ OptimizeReferences="2"
+ EnableCOMDATFolding="2"
+ RandomizedBaseAddress="1"
+ DataExecutionPrevention="0"
+ TargetMachine="1"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCManifestTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCAppVerifierTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ />
+ </Configuration>
+ </Configurations>
+ <References>
+ </References>
+ <Files>
+ <Filter
+ Name="Source Files"
+ Filter="cpp;c;cxx;def;odl;idl;hpj;bat;asm;asmx"
+ UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}"
+ >
+ <File
+ RelativePath="..\..\tests\run-parser.c"
+ >
+ </File>
+ </Filter>
+ <Filter
+ Name="Header Files"
+ Filter="h;hpp;hxx;hm;inl;inc;xsd"
+ UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}"
+ >
+ </Filter>
+ <Filter
+ Name="Resource Files"
+ Filter="rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx"
+ UniqueIdentifier="{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}"
+ >
+ </Filter>
+ </Files>
+ <Globals>
+ </Globals>
+</VisualStudioProject>
diff --git a/contrib/libyaml/win32/vs2008/run_scanner.vcproj b/contrib/libyaml/win32/vs2008/run_scanner.vcproj
new file mode 100644
index 0000000..458ffc1
--- /dev/null
+++ b/contrib/libyaml/win32/vs2008/run_scanner.vcproj
@@ -0,0 +1,201 @@
+<?xml version="1.0" encoding="windows-1251"?>
+<VisualStudioProject
+ ProjectType="Visual C++"
+ Version="9,00"
+ Name="run_scanner"
+ ProjectGUID="{5D3F321E-4A86-4842-9F45-105A7F373104}"
+ Keyword="Win32Proj"
+ TargetFrameworkVersion="131072"
+ >
+ <Platforms>
+ <Platform
+ Name="Win32"
+ />
+ </Platforms>
+ <ToolFiles>
+ </ToolFiles>
+ <Configurations>
+ <Configuration
+ Name="Debug|Win32"
+ OutputDirectory="Output\Debug\bin"
+ IntermediateDirectory="Build\Debug\bin"
+ ConfigurationType="1"
+ InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops"
+ CharacterSet="2"
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="0"
+ AdditionalIncludeDirectories="../../include"
+ PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE;YAML_DECLARE_STATIC"
+ MinimalRebuild="true"
+ BasicRuntimeChecks="3"
+ RuntimeLibrary="3"
+ UsePrecompiledHeader="0"
+ WarningLevel="3"
+ Detect64BitPortabilityProblems="true"
+ DebugInformationFormat="4"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLinkerTool"
+ OutputFile="$(OutDir)/run_scanner.exe"
+ LinkIncremental="2"
+ GenerateDebugInformation="true"
+ ProgramDatabaseFile="$(OutDir)/run_scanner.pdb"
+ SubSystem="1"
+ RandomizedBaseAddress="1"
+ DataExecutionPrevention="0"
+ TargetMachine="1"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCManifestTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCAppVerifierTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ />
+ </Configuration>
+ <Configuration
+ Name="Release|Win32"
+ OutputDirectory="Output\Release\bin"
+ IntermediateDirectory="Build\Release\bin"
+ ConfigurationType="1"
+ InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops"
+ CharacterSet="2"
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ AdditionalIncludeDirectories="../../include"
+ PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE;YAML_DECLARE_STATIC"
+ RuntimeLibrary="2"
+ UsePrecompiledHeader="0"
+ WarningLevel="3"
+ Detect64BitPortabilityProblems="true"
+ DebugInformationFormat="3"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLinkerTool"
+ OutputFile="$(OutDir)/run_scanner.exe"
+ LinkIncremental="1"
+ GenerateDebugInformation="true"
+ SubSystem="1"
+ OptimizeReferences="2"
+ EnableCOMDATFolding="2"
+ RandomizedBaseAddress="1"
+ DataExecutionPrevention="0"
+ TargetMachine="1"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCManifestTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCAppVerifierTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ />
+ </Configuration>
+ </Configurations>
+ <References>
+ </References>
+ <Files>
+ <Filter
+ Name="Source Files"
+ Filter="cpp;c;cxx;def;odl;idl;hpj;bat;asm;asmx"
+ UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}"
+ >
+ <File
+ RelativePath="..\..\tests\run-scanner.c"
+ >
+ </File>
+ </Filter>
+ <Filter
+ Name="Header Files"
+ Filter="h;hpp;hxx;hm;inl;inc;xsd"
+ UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}"
+ >
+ </Filter>
+ <Filter
+ Name="Resource Files"
+ Filter="rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx"
+ UniqueIdentifier="{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}"
+ >
+ </Filter>
+ </Files>
+ <Globals>
+ </Globals>
+</VisualStudioProject>
diff --git a/contrib/libyaml/win32/vs2008/test_reader.vcproj b/contrib/libyaml/win32/vs2008/test_reader.vcproj
new file mode 100644
index 0000000..ff384a3
--- /dev/null
+++ b/contrib/libyaml/win32/vs2008/test_reader.vcproj
@@ -0,0 +1,201 @@
+<?xml version="1.0" encoding="windows-1251"?>
+<VisualStudioProject
+ ProjectType="Visual C++"
+ Version="9,00"
+ Name="test_reader"
+ ProjectGUID="{898C9408-2480-4BF8-97B0-B1464B7BB5C4}"
+ Keyword="Win32Proj"
+ TargetFrameworkVersion="131072"
+ >
+ <Platforms>
+ <Platform
+ Name="Win32"
+ />
+ </Platforms>
+ <ToolFiles>
+ </ToolFiles>
+ <Configurations>
+ <Configuration
+ Name="Debug|Win32"
+ OutputDirectory="Output\Debug\bin"
+ IntermediateDirectory="Build\Debug\bin"
+ ConfigurationType="1"
+ InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops"
+ CharacterSet="2"
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="0"
+ AdditionalIncludeDirectories="../../include"
+ PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE;YAML_DECLARE_STATIC"
+ MinimalRebuild="true"
+ BasicRuntimeChecks="3"
+ RuntimeLibrary="3"
+ UsePrecompiledHeader="0"
+ WarningLevel="3"
+ Detect64BitPortabilityProblems="true"
+ DebugInformationFormat="4"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLinkerTool"
+ OutputFile="$(OutDir)/test_reader.exe"
+ LinkIncremental="2"
+ GenerateDebugInformation="true"
+ ProgramDatabaseFile="$(OutDir)/test_reader.pdb"
+ SubSystem="1"
+ RandomizedBaseAddress="1"
+ DataExecutionPrevention="0"
+ TargetMachine="1"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCManifestTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCAppVerifierTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ />
+ </Configuration>
+ <Configuration
+ Name="Release|Win32"
+ OutputDirectory="Output\Release\bin"
+ IntermediateDirectory="Build\Release\bin"
+ ConfigurationType="1"
+ InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops"
+ CharacterSet="2"
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ AdditionalIncludeDirectories="../../include"
+ PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE;YAML_DECLARE_STATIC"
+ RuntimeLibrary="2"
+ UsePrecompiledHeader="0"
+ WarningLevel="3"
+ Detect64BitPortabilityProblems="true"
+ DebugInformationFormat="3"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLinkerTool"
+ OutputFile="$(OutDir)/test_reader.exe"
+ LinkIncremental="1"
+ GenerateDebugInformation="true"
+ SubSystem="1"
+ OptimizeReferences="2"
+ EnableCOMDATFolding="2"
+ RandomizedBaseAddress="1"
+ DataExecutionPrevention="0"
+ TargetMachine="1"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCManifestTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCAppVerifierTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ />
+ </Configuration>
+ </Configurations>
+ <References>
+ </References>
+ <Files>
+ <Filter
+ Name="Source Files"
+ Filter="cpp;c;cxx;def;odl;idl;hpj;bat;asm;asmx"
+ UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}"
+ >
+ <File
+ RelativePath="..\..\tests\test-reader.c"
+ >
+ </File>
+ </Filter>
+ <Filter
+ Name="Header Files"
+ Filter="h;hpp;hxx;hm;inl;inc;xsd"
+ UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}"
+ >
+ </Filter>
+ <Filter
+ Name="Resource Files"
+ Filter="rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx"
+ UniqueIdentifier="{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}"
+ >
+ </Filter>
+ </Files>
+ <Globals>
+ </Globals>
+</VisualStudioProject>
diff --git a/contrib/libyaml/win32/vs2008/test_version.vcproj b/contrib/libyaml/win32/vs2008/test_version.vcproj
new file mode 100644
index 0000000..6ee630f
--- /dev/null
+++ b/contrib/libyaml/win32/vs2008/test_version.vcproj
@@ -0,0 +1,201 @@
+<?xml version="1.0" encoding="windows-1251"?>
+<VisualStudioProject
+ ProjectType="Visual C++"
+ Version="9,00"
+ Name="test_version"
+ ProjectGUID="{BF6CA7A9-0767-4A4E-BC42-9B7C8E105991}"
+ Keyword="Win32Proj"
+ TargetFrameworkVersion="131072"
+ >
+ <Platforms>
+ <Platform
+ Name="Win32"
+ />
+ </Platforms>
+ <ToolFiles>
+ </ToolFiles>
+ <Configurations>
+ <Configuration
+ Name="Debug|Win32"
+ OutputDirectory="Output\Debug\bin"
+ IntermediateDirectory="Build\Debug\bin"
+ ConfigurationType="1"
+ InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops"
+ CharacterSet="2"
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="0"
+ AdditionalIncludeDirectories="../../include"
+ PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE;YAML_DECLARE_STATIC"
+ MinimalRebuild="true"
+ BasicRuntimeChecks="3"
+ RuntimeLibrary="3"
+ UsePrecompiledHeader="0"
+ WarningLevel="3"
+ Detect64BitPortabilityProblems="true"
+ DebugInformationFormat="4"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLinkerTool"
+ OutputFile="$(OutDir)/test_version.exe"
+ LinkIncremental="2"
+ GenerateDebugInformation="true"
+ ProgramDatabaseFile="$(OutDir)/test_version.pdb"
+ SubSystem="1"
+ RandomizedBaseAddress="1"
+ DataExecutionPrevention="0"
+ TargetMachine="1"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCManifestTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCAppVerifierTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ />
+ </Configuration>
+ <Configuration
+ Name="Release|Win32"
+ OutputDirectory="Output\Release\bin"
+ IntermediateDirectory="Build\Release\bin"
+ ConfigurationType="1"
+ InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops"
+ CharacterSet="2"
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ AdditionalIncludeDirectories="../../include"
+ PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE;YAML_DECLARE_STATIC"
+ RuntimeLibrary="2"
+ UsePrecompiledHeader="0"
+ WarningLevel="3"
+ Detect64BitPortabilityProblems="true"
+ DebugInformationFormat="3"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLinkerTool"
+ OutputFile="$(OutDir)/test_version.exe"
+ LinkIncremental="1"
+ GenerateDebugInformation="true"
+ SubSystem="1"
+ OptimizeReferences="2"
+ EnableCOMDATFolding="2"
+ RandomizedBaseAddress="1"
+ DataExecutionPrevention="0"
+ TargetMachine="1"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCManifestTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCAppVerifierTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ />
+ </Configuration>
+ </Configurations>
+ <References>
+ </References>
+ <Files>
+ <Filter
+ Name="Source Files"
+ Filter="cpp;c;cxx;def;odl;idl;hpj;bat;asm;asmx"
+ UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}"
+ >
+ <File
+ RelativePath="..\..\tests\test-version.c"
+ >
+ </File>
+ </Filter>
+ <Filter
+ Name="Header Files"
+ Filter="h;hpp;hxx;hm;inl;inc;xsd"
+ UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}"
+ >
+ </Filter>
+ <Filter
+ Name="Resource Files"
+ Filter="rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx"
+ UniqueIdentifier="{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}"
+ >
+ </Filter>
+ </Files>
+ <Globals>
+ </Globals>
+</VisualStudioProject>
diff --git a/contrib/libyaml/win32/vs2008/yaml.vcproj b/contrib/libyaml/win32/vs2008/yaml.vcproj
new file mode 100644
index 0000000..ad87e1f0
--- /dev/null
+++ b/contrib/libyaml/win32/vs2008/yaml.vcproj
@@ -0,0 +1,215 @@
+<?xml version="1.0" encoding="windows-1251"?>
+<VisualStudioProject
+ ProjectType="Visual C++"
+ Version="9,00"
+ Name="yaml"
+ ProjectGUID="{5CE8051A-3F0C-4C39-B1C0-3338E48BA60F}"
+ RootNamespace="yaml"
+ Keyword="Win32Proj"
+ TargetFrameworkVersion="131072"
+ >
+ <Platforms>
+ <Platform
+ Name="Win32"
+ />
+ </Platforms>
+ <ToolFiles>
+ </ToolFiles>
+ <Configurations>
+ <Configuration
+ Name="Debug|Win32"
+ OutputDirectory="Output\Debug\lib"
+ IntermediateDirectory="Build\Debug\lib"
+ ConfigurationType="4"
+ InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops"
+ CharacterSet="2"
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="0"
+ AdditionalIncludeDirectories="..;../../include"
+ PreprocessorDefinitions="HAVE_CONFIG_H;YAML_DECLARE_STATIC"
+ MinimalRebuild="true"
+ BasicRuntimeChecks="3"
+ RuntimeLibrary="3"
+ UsePrecompiledHeader="0"
+ WarningLevel="3"
+ Detect64BitPortabilityProblems="true"
+ DebugInformationFormat="4"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLibrarianTool"
+ OutputFile="$(OutDir)/yaml.lib"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ />
+ </Configuration>
+ <Configuration
+ Name="Release|Win32"
+ OutputDirectory="Output\Release\lib"
+ IntermediateDirectory="Build\Release\lib"
+ ConfigurationType="4"
+ InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops"
+ CharacterSet="2"
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ AdditionalIncludeDirectories="..;../../include"
+ PreprocessorDefinitions="HAVE_CONFIG_H;YAML_DECLARE_STATIC"
+ RuntimeLibrary="2"
+ UsePrecompiledHeader="0"
+ WarningLevel="3"
+ Detect64BitPortabilityProblems="true"
+ DebugInformationFormat="3"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLibrarianTool"
+ OutputFile="$(OutDir)/yaml.lib"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ />
+ </Configuration>
+ </Configurations>
+ <References>
+ </References>
+ <Files>
+ <Filter
+ Name="Source Files"
+ Filter="cpp;c;cxx;def;odl;idl;hpj;bat;asm;asmx"
+ UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}"
+ >
+ <File
+ RelativePath="..\..\src\api.c"
+ >
+ </File>
+ <File
+ RelativePath="..\..\src\dumper.c"
+ >
+ </File>
+ <File
+ RelativePath="..\..\src\emitter.c"
+ >
+ </File>
+ <File
+ RelativePath="..\..\src\loader.c"
+ >
+ </File>
+ <File
+ RelativePath="..\..\src\parser.c"
+ >
+ </File>
+ <File
+ RelativePath="..\..\src\reader.c"
+ >
+ </File>
+ <File
+ RelativePath="..\..\src\scanner.c"
+ >
+ </File>
+ <File
+ RelativePath="..\..\src\writer.c"
+ >
+ </File>
+ </Filter>
+ <Filter
+ Name="Header Files"
+ Filter="h;hpp;hxx;hm;inl;inc;xsd"
+ UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}"
+ >
+ <File
+ RelativePath="..\config.h"
+ >
+ </File>
+ <File
+ RelativePath="..\..\include\yaml.h"
+ >
+ </File>
+ <File
+ RelativePath="..\..\src\yaml_private.h"
+ >
+ </File>
+ </Filter>
+ <Filter
+ Name="Resource Files"
+ Filter="rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx"
+ UniqueIdentifier="{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}"
+ >
+ </Filter>
+ </Files>
+ <Globals>
+ </Globals>
+</VisualStudioProject>
diff --git a/contrib/libyaml/win32/vs2008/yamldll.vcproj b/contrib/libyaml/win32/vs2008/yamldll.vcproj
new file mode 100644
index 0000000..6bd95f2
--- /dev/null
+++ b/contrib/libyaml/win32/vs2008/yamldll.vcproj
@@ -0,0 +1,243 @@
+<?xml version="1.0" encoding="windows-1251"?>
+<VisualStudioProject
+ ProjectType="Visual C++"
+ Version="9,00"
+ Name="yamldll"
+ ProjectGUID="{019A6F4C-E704-4879-8E53-622BD4BC9C89}"
+ Keyword="Win32Proj"
+ TargetFrameworkVersion="131072"
+ >
+ <Platforms>
+ <Platform
+ Name="Win32"
+ />
+ </Platforms>
+ <ToolFiles>
+ </ToolFiles>
+ <Configurations>
+ <Configuration
+ Name="Debug|Win32"
+ OutputDirectory="Output\Debug\lib\DLL"
+ IntermediateDirectory="Build\Debug\lib\DLL"
+ ConfigurationType="2"
+ InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops"
+ CharacterSet="2"
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="0"
+ AdditionalIncludeDirectories="..;../../include"
+ PreprocessorDefinitions="HAVE_CONFIG_H;YAML_DECLARE_EXPORT"
+ MinimalRebuild="true"
+ BasicRuntimeChecks="3"
+ RuntimeLibrary="3"
+ UsePrecompiledHeader="0"
+ WarningLevel="3"
+ Detect64BitPortabilityProblems="true"
+ DebugInformationFormat="4"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLinkerTool"
+ OutputFile="$(OutDir)/yaml.dll"
+ LinkIncremental="2"
+ GenerateDebugInformation="true"
+ ProgramDatabaseFile="$(OutDir)/yaml.pdb"
+ SubSystem="2"
+ RandomizedBaseAddress="1"
+ DataExecutionPrevention="0"
+ ImportLibrary="$(OutDir)/yaml.lib"
+ TargetMachine="1"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCManifestTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCAppVerifierTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ />
+ </Configuration>
+ <Configuration
+ Name="Release|Win32"
+ OutputDirectory="Output\Release\lib\DLL"
+ IntermediateDirectory="Build\Release\lib\DLL"
+ ConfigurationType="2"
+ InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops"
+ CharacterSet="2"
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ AdditionalIncludeDirectories="..;../../include"
+ PreprocessorDefinitions="HAVE_CONFIG_H;YAML_DECLARE_EXPORT"
+ RuntimeLibrary="2"
+ UsePrecompiledHeader="0"
+ WarningLevel="3"
+ Detect64BitPortabilityProblems="true"
+ DebugInformationFormat="3"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLinkerTool"
+ OutputFile="$(OutDir)/yaml.dll"
+ LinkIncremental="1"
+ GenerateDebugInformation="true"
+ SubSystem="2"
+ OptimizeReferences="2"
+ EnableCOMDATFolding="2"
+ RandomizedBaseAddress="1"
+ DataExecutionPrevention="0"
+ ImportLibrary="$(OutDir)/yaml.lib"
+ TargetMachine="1"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCManifestTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCAppVerifierTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ />
+ </Configuration>
+ </Configurations>
+ <References>
+ </References>
+ <Files>
+ <Filter
+ Name="Source Files"
+ Filter="cpp;c;cxx;def;odl;idl;hpj;bat;asm;asmx"
+ UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}"
+ >
+ <File
+ RelativePath="..\..\src\api.c"
+ >
+ </File>
+ <File
+ RelativePath="..\..\src\dumper.c"
+ >
+ </File>
+ <File
+ RelativePath="..\..\src\emitter.c"
+ >
+ </File>
+ <File
+ RelativePath="..\..\src\loader.c"
+ >
+ </File>
+ <File
+ RelativePath="..\..\src\parser.c"
+ >
+ </File>
+ <File
+ RelativePath="..\..\src\reader.c"
+ >
+ </File>
+ <File
+ RelativePath="..\..\src\scanner.c"
+ >
+ </File>
+ <File
+ RelativePath="..\..\src\writer.c"
+ >
+ </File>
+ </Filter>
+ <Filter
+ Name="Header Files"
+ Filter="h;hpp;hxx;hm;inl;inc;xsd"
+ UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}"
+ >
+ <File
+ RelativePath="..\config.h"
+ >
+ </File>
+ <File
+ RelativePath="..\..\include\yaml.h"
+ >
+ </File>
+ <File
+ RelativePath="..\..\src\yaml_private.h"
+ >
+ </File>
+ </Filter>
+ <Filter
+ Name="Resource Files"
+ Filter="rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx"
+ UniqueIdentifier="{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}"
+ >
+ </Filter>
+ </Files>
+ <Globals>
+ </Globals>
+</VisualStudioProject>
diff --git a/contrib/libyaml/yaml-0.1.pc.in b/contrib/libyaml/yaml-0.1.pc.in
new file mode 100644
index 0000000..c566abf
--- /dev/null
+++ b/contrib/libyaml/yaml-0.1.pc.in
@@ -0,0 +1,10 @@
+prefix=@prefix@
+exec_prefix=@exec_prefix@
+includedir=@includedir@
+libdir=@libdir@
+
+Name: LibYAML
+Description: Library to parse and emit YAML
+Version: @PACKAGE_VERSION@
+Cflags:
+Libs: -L${libdir} -lyaml
diff --git a/contrib/openbsm/etc/audit_event b/contrib/openbsm/etc/audit_event
index f82841a..49b5f9d 100644
--- a/contrib/openbsm/etc/audit_event
+++ b/contrib/openbsm/etc/audit_event
@@ -568,6 +568,8 @@
43204:AUE_CAP_IOCTLS_GET:cap_ioctls_get(2):fm
43205:AUE_CAP_FCNTLS_LIMIT:cap_fcntls_limit(2):fm
43206:AUE_CAP_FCNTLS_GET:cap_fcntls_get(2):fm
+43207:AUE_BINDAT:bindat(2):nt
+43208:AUE_CONNECTAT:connectat(2):nt
#
# Solaris userspace events.
#
diff --git a/contrib/openpam/doc/man/openpam_straddch.3 b/contrib/openpam/doc/man/openpam_straddch.3
index c555824..ea11c93 100644
--- a/contrib/openpam/doc/man/openpam_straddch.3
+++ b/contrib/openpam/doc/man/openpam_straddch.3
@@ -34,7 +34,7 @@
.\"
.\" $Id$
.\"
-.Dd May 26, 2012
+.Dd March 3, 2013
.Dt OPENPAM_STRADDCH 3
.Os
.Sh NAME
@@ -73,6 +73,21 @@ and
argument point to variables used to hold the size
of the buffer and the length of the string it contains, respectively.
.Pp
+The final argument,
+.Fa ch ,
+is the character that should be appended to
+the string. If
+.Fa ch
+is 0, nothing is appended, but a new buffer is
+still allocated if
+.Fa str
+is NULL. This can be used to
+.Do
+bootstrap
+.Dc
+the
+string.
+.Pp
If a new buffer is allocated or an existing buffer is reallocated to
make room for the additional character,
.Fa str
@@ -91,7 +106,9 @@ If the
function is successful, it increments the
integer variable pointed to by
.Fa len
-and returns 0.
+(unless
+.Fa ch
+was 0) and returns 0.
Otherwise, it leaves the variables pointed to by
.Fa str ,
.Fa size
diff --git a/contrib/openpam/lib/openpam_readline.c b/contrib/openpam/lib/openpam_readline.c
index 014acfb..047ab8369 100644
--- a/contrib/openpam/lib/openpam_readline.c
+++ b/contrib/openpam/lib/openpam_readline.c
@@ -62,11 +62,9 @@ openpam_readline(FILE *f, int *lineno, size_t *lenp)
size_t len, size;
int ch;
- if ((line = malloc(size = MIN_LINE_LENGTH)) == NULL) {
- openpam_log(PAM_LOG_ERROR, "malloc(): %m");
+ line = NULL;
+ if (openpam_straddch(&line, &size, &len, 0) != 0)
return (NULL);
- }
- len = 0;
for (;;) {
ch = fgetc(f);
/* strip comment */
diff --git a/contrib/openpam/lib/openpam_readword.c b/contrib/openpam/lib/openpam_readword.c
index 74a4d46..1c0e9b6 100644
--- a/contrib/openpam/lib/openpam_readword.c
+++ b/contrib/openpam/lib/openpam_readword.c
@@ -86,13 +86,8 @@ openpam_readword(FILE *f, int *lineno, size_t *lenp)
/* begin quote */
quote = ch;
/* edge case: empty quoted string */
- if (word == NULL && (word = malloc(1)) == NULL) {
- openpam_log(PAM_LOG_ERROR, "malloc(): %m");
- errno = ENOMEM;
+ if (openpam_straddch(&word, &size, &len, 0) != 0)
return (NULL);
- }
- *word = '\0';
- size = 1;
} else if (ch == quote && !escape) {
/* end quote */
quote = 0;
diff --git a/crypto/openssh/FREEBSD-upgrade b/crypto/openssh/FREEBSD-upgrade
index 03b7dbf..0d88fb7 100644
--- a/crypto/openssh/FREEBSD-upgrade
+++ b/crypto/openssh/FREEBSD-upgrade
@@ -43,6 +43,7 @@
7) Run configure with the appropriate arguments:
$ ./configure --prefix=/usr --sysconfdir=/etc/ssh \
+ --disable-lastlog --disable-utmp --disable-wtmp \
--with-pam --with-tcp-wrappers --with-libedit \
--with-ssl-engine
diff --git a/crypto/openssh/config.h b/crypto/openssh/config.h
index 49f4ec3..782708b 100644
--- a/crypto/openssh/config.h
+++ b/crypto/openssh/config.h
@@ -17,6 +17,9 @@
/* Define if your resolver libs need this for getrrsetbyname */
/* #undef BIND_8_COMPAT */
+/* The system has incomplete BSM API */
+/* #undef BROKEN_BSM_API */
+
/* Define if cmsg_type is not passed correctly */
/* #undef BROKEN_CMSG_TYPE */
@@ -97,7 +100,7 @@
/* #undef DISABLE_FD_PASSING */
/* Define if you don't want to use lastlog */
-/* #undef DISABLE_LASTLOG */
+#define DISABLE_LASTLOG 1
/* Define if you don't want to use your system's login() call */
/* #undef DISABLE_LOGIN */
@@ -307,7 +310,7 @@
#define HAVE_DECL__GETSHORT 0
/* Define if you have /dev/ptmx */
-#define HAVE_DEV_PTMX 1
+/* #undef HAVE_DEV_PTMX */
/* Define if you have /dev/ptc */
/* #undef HAVE_DEV_PTS_AND_PTC */
@@ -316,7 +319,7 @@
#define HAVE_DIRENT_H 1
/* Define to 1 if you have the `dirfd' function. */
-/* #undef HAVE_DIRFD */
+#define HAVE_DIRFD 1
/* Define to 1 if you have the `dirname' function. */
#define HAVE_DIRNAME 1
@@ -501,6 +504,9 @@
/* Define if HEADER.ad exists in arpa/nameser.h */
#define HAVE_HEADER_AD 1
+/* Define to 1 if you have the `HMAC_CTX_init' function. */
+#define HAVE_HMAC_CTX_INIT 1
+
/* Define if you have ut_host in utmp.h */
/* #undef HAVE_HOST_IN_UTMP */
@@ -552,6 +558,9 @@
/* Define to 1 if you have the <lastlog.h> header file. */
/* #undef HAVE_LASTLOG_H */
+/* Define if you want ldns support */
+/* #undef HAVE_LDNS */
+
/* Define to 1 if you have the <libaudit.h> header file. */
/* #undef HAVE_LIBAUDIT_H */
@@ -594,10 +603,19 @@
/* Define to 1 if you have the <limits.h> header file. */
#define HAVE_LIMITS_H 1
+/* Define to 1 if you have the <linux/audit.h> header file. */
+/* #undef HAVE_LINUX_AUDIT_H */
+
+/* Define to 1 if you have the <linux/filter.h> header file. */
+/* #undef HAVE_LINUX_FILTER_H */
+
/* Define to 1 if you have the <linux/if_tun.h> header file. */
/* #undef HAVE_LINUX_IF_TUN_H */
-/* Define if your libraries define login() */
+/* Define to 1 if you have the <linux/seccomp.h> header file. */
+/* #undef HAVE_LINUX_SECCOMP_H */
+
+/* Define to 1 if you have the `login' function. */
/* #undef HAVE_LOGIN */
/* Define to 1 if you have the <login_cap.h> header file. */
@@ -805,6 +823,9 @@
/* Define to 1 if you have the `setgroups' function. */
#define HAVE_SETGROUPS 1
+/* Define to 1 if you have the `setlinebuf' function. */
+#define HAVE_SETLINEBUF 1
+
/* Define to 1 if you have the `setlogin' function. */
#define HAVE_SETLOGIN 1
@@ -931,6 +952,9 @@
/* Define to 1 if you have the `strmode' function. */
#define HAVE_STRMODE 1
+/* Define to 1 if you have the `strnlen' function. */
+#define HAVE_STRNLEN 1
+
/* Define to 1 if you have the `strnvis' function. */
/* #undef HAVE_STRNVIS */
@@ -1172,7 +1196,7 @@
/* #undef HAVE_VHANGUP */
/* Define to 1 if you have the <vis.h> header file. */
-#define HAVE_VIS_H 1
+/* #undef HAVE_VIS_H */
/* Define to 1 if you have the `vsnprintf' function. */
#define HAVE_VSNPRINTF 1
@@ -1351,15 +1375,21 @@
/* Sandbox using setrlimit(2) */
#define SANDBOX_RLIMIT 1
+/* Sandbox using seccomp filter */
+/* #undef SANDBOX_SECCOMP_FILTER */
+
+/* setrlimit RLIMIT_FSIZE works */
+/* #undef SANDBOX_SKIP_RLIMIT_FSIZE */
+
/* Sandbox using systrace(4) */
/* #undef SANDBOX_SYSTRACE */
+/* Specify the system call convention in use */
+/* #undef SECCOMP_AUDIT_ARCH */
+
/* Define if your platform breaks doing a seteuid before a setuid */
/* #undef SETEUID_BREAKS_SETUID */
-/* The size of `char', as computed by sizeof. */
-#define SIZEOF_CHAR 1
-
/* The size of `int', as computed by sizeof. */
#define SIZEOF_INT 4
@@ -1500,6 +1530,11 @@
/* Define if xauth is found in your path */
/* #undef XAUTH_PATH */
+/* Enable large inode numbers on Mac OS X 10.5. */
+#ifndef _DARWIN_USE_64_BIT_INODE
+# define _DARWIN_USE_64_BIT_INODE 1
+#endif
+
/* Number of bits in a file offset, on hosts where this is settable. */
/* #undef _FILE_OFFSET_BITS */
diff --git a/etc/devd.conf b/etc/devd.conf
index d379ab0..5339bae 100644
--- a/etc/devd.conf
+++ b/etc/devd.conf
@@ -34,7 +34,7 @@ options {
# NB: DETACH events are ignored; the kernel should handle all cleanup
# (routes, arp cache). Beware of races against immediate create
# of a device with the same name; e.g.
-# ifconfig bridge0 destroy; ifconfig bridge0 create
+# ifconfig bridge0 destroy; ifconfig bridge0 create
#
notify 0 {
match "system" "IFNET";
@@ -165,7 +165,7 @@ notify 100 {
};
#
-# Rescan scsi device-names on attach, but not detach. However, it is
+# Rescan SCSI device-names on attach, but not detach. However, it is
# disabled by default due to reports of problems.
#
attach 0 {
@@ -305,13 +305,13 @@ detach 10 {
# events. See the ACPI specification for more information about
# notifies. Here is the information returned for each subsystem:
#
-# ACAD: AC line state (0 is offline, 1 is online)
-# Button: Button pressed (0 for power, 1 for sleep)
-# CMBAT: ACPI battery events
-# Lid: Lid state (0 is closed, 1 is open)
-# RCTL: Resource limits
+# ACAD: AC line state (0 is offline, 1 is online)
+# Button: Button pressed (0 for power, 1 for sleep)
+# CMBAT: ACPI battery events
+# Lid: Lid state (0 is closed, 1 is open)
+# RCTL: Resource limits
# Suspend, Resume: Suspend and resume notification
-# Thermal: ACPI thermal zone events
+# Thermal: ACPI thermal zone events
#
# This example calls a script when the AC state changes, passing the
# notify value as the first argument. If the state is 0x00, it might
diff --git a/etc/portsnap.conf b/etc/portsnap.conf
index c209445..eca429f 100644
--- a/etc/portsnap.conf
+++ b/etc/portsnap.conf
@@ -30,6 +30,5 @@ KEYPRINT=9b5feee6d69f170e3dd0a2c8e469ddbd64f13f978f2f3aede40c98633216c330
# REFUSE korean polish portuguese russian ukrainian vietnamese
# List of INDEX files to build and the DESCRIBE file to use for each
-INDEX INDEX-7 DESCRIBE.7
INDEX INDEX-8 DESCRIBE.8
INDEX INDEX-9 DESCRIBE.9
diff --git a/lib/Makefile b/lib/Makefile
index 7a0ec02..8846164 100644
--- a/lib/Makefile
+++ b/lib/Makefile
@@ -119,6 +119,7 @@ SUBDIR= ${SUBDIR_ORDERED} \
${_libvmmapi} \
libwrap \
liby \
+ libyaml \
libz \
${_atf} \
${_bind} \
diff --git a/lib/libc/string/Makefile.inc b/lib/libc/string/Makefile.inc
index f98dc92..b997b7b 100644
--- a/lib/libc/string/Makefile.inc
+++ b/lib/libc/string/Makefile.inc
@@ -46,7 +46,8 @@ MLINKS+=strcasecmp.3 strncasecmp.3 \
strcasecmp.3 strcasecmp_l.3 \
strcasecmp.3 strncasecmp_l.3
MLINKS+=strcat.3 strncat.3
-MLINKS+=strchr.3 strrchr.3
+MLINKS+=strchr.3 strrchr.3 \
+ strchr.3 strchrnul.3
MLINKS+=strcmp.3 strncmp.3
MLINKS+=strcoll.3 strcoll_l.3
MLINKS+=strcpy.3 stpcpy.3 \
diff --git a/lib/libc/sys/Makefile.inc b/lib/libc/sys/Makefile.inc
index 03c0090..62aab6c 100644
--- a/lib/libc/sys/Makefile.inc
+++ b/lib/libc/sys/Makefile.inc
@@ -91,6 +91,7 @@ MAN+= abort2.2 \
aio_waitcomplete.2 \
aio_write.2 \
bind.2 \
+ bindat.2 \
brk.2 \
cap_enter.2 \
cap_fcntls_limit.2 \
@@ -105,6 +106,7 @@ MAN+= abort2.2 \
close.2 \
closefrom.2 \
connect.2 \
+ connectat.2 \
cpuset.2 \
cpuset_getaffinity.2 \
dup.2 \
diff --git a/lib/libc/sys/Symbol.map b/lib/libc/sys/Symbol.map
index 7738e46..fc00064 100644
--- a/lib/libc/sys/Symbol.map
+++ b/lib/libc/sys/Symbol.map
@@ -378,6 +378,7 @@ FBSD_1.2 {
};
FBSD_1.3 {
+ bindat;
cap_fcntls_get;
cap_fcntls_limit;
cap_ioctls_get;
@@ -386,6 +387,7 @@ FBSD_1.3 {
cap_rights_limit;
cap_sandboxed;
clock_getcpuclockid2;
+ connectat;
ffclock_getcounter;
ffclock_getestimate;
ffclock_setestimate;
diff --git a/lib/libc/sys/bindat.2 b/lib/libc/sys/bindat.2
new file mode 100644
index 0000000..9274679
--- /dev/null
+++ b/lib/libc/sys/bindat.2
@@ -0,0 +1,109 @@
+.\" Copyright (c) 2013 The FreeBSD Foundation
+.\" All rights reserved.
+.\"
+.\" This documentation was written by Pawel Jakub Dawidek under sponsorship from
+.\" the FreeBSD Foundation.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE AUTHORS AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" $FreeBSD$
+.\"
+.Dd February 13, 2013
+.Dt BINDAT 2
+.Os
+.Sh NAME
+.Nm bindat
+.Nd assign a local protocol address to a socket
+.Sh LIBRARY
+.Lb libc
+.Sh SYNOPSIS
+.In sys/types.h
+.In sys/socket.h
+.Pp
+.In fcntl.h
+.Ft int
+.Fn bindat "int fd" "int s" "const struct sockaddr *addr" "socklen_t addrlen"
+.Sh DESCRIPTION
+The
+.Fn bindat
+system call assigns the local protocol address to a socket.
+It works just like the
+.Xr bind 2
+system call with two exceptions:
+.Pp
+.Bl -enum -offset indent -compact
+.It
+It is limited to sockets in the PF_LOCAL domain.
+.Pp
+.It
+If the file path stored in the
+.Fa sun_path
+field of the sockaddr_un structure is a relative path, it is located relative
+to the directory associated with the file descriptor
+.Fa fd .
+If
+.Fn bindat
+is passed the special value
+.Dv AT_FDCWD
+in the
+.Fa fd
+parameter, the current working directory is used and the behavior is identical
+to a call to
+.Xr bind 2 .
+.El
+.Sh RETURN VALUES
+.Rv -std bindat
+.Sh ERRORS
+The
+.Fn bindat
+system call may fail with the same errors as the
+.Xr bind 2
+system call for a UNIX domain socket or with the following errors:
+.Bl -tag -width Er
+.It Bq Er EBADF
+The
+.Fa sun_path
+field does not specify an absolute path and the
+.Fa fd
+argument is neither
+.Dv AT_FDCWD
+nor a valid file descriptor.
+.It Bq Er ENOTDIR
+The
+.Fa sun_path
+field is not an absolute path and
+.Fa fd
+is neither
+.Dv AT_FDCWD
+nor a file descriptor associated with a directory.
+.El
+.Sh SEE ALSO
+.Xr bind 2 ,
+.Xr connectat 2 ,
+.Xr socket 2 ,
+.Xr unix 4
+.Sh AUTHORS
+The
+.Nm
+was developed by
+.An Pawel Jakub Dawidek Aq pawel@dawidek.net
+under sponsorship from the FreeBSD Foundation.
diff --git a/lib/libc/sys/cap_rights_limit.2 b/lib/libc/sys/cap_rights_limit.2
index 0c527aa..d0605af 100644
--- a/lib/libc/sys/cap_rights_limit.2
+++ b/lib/libc/sys/cap_rights_limit.2
@@ -104,12 +104,20 @@ or
and that socket options set with
.Xr setsockopt 2
may also affect binding behavior.
+.It Dv CAP_BINDAT
+Permit
+.Xr bindat 2 .
+This right has to be present on the directory descriptor.
.It Dv CAP_CONNECT
Permit
.Xr connect 2 ;
also required for
.Xr sendto 2
with a non-NULL destination address.
+.It Dv CAP_CONNECTAT
+Permit
+.Xr connectat 2 .
+This right has to be present on the directory descriptor.
.It Dv CAP_CREATE
Permit
.Xr openat 2
@@ -511,11 +519,13 @@ argument points at an invalid address.
.Xr aio_read 2 ,
.Xr aio_write 2 ,
.Xr bind 2 ,
+.Xr bindat 2 ,
.Xr cap_enter 2 ,
.Xr cap_fcntls_limit 2 ,
.Xr cap_ioctls_limit 2 ,
.Xr cap_rights_limit 2 ,
.Xr connect 2 ,
+.Xr connectat 2 ,
.Xr dup 2 ,
.Xr dup2 2 ,
.Xr extattr_delete_fd 2 ,
diff --git a/lib/libc/sys/connectat.2 b/lib/libc/sys/connectat.2
new file mode 100644
index 0000000..8cebf98
--- /dev/null
+++ b/lib/libc/sys/connectat.2
@@ -0,0 +1,109 @@
+.\" Copyright (c) 2013 The FreeBSD Foundation
+.\" All rights reserved.
+.\"
+.\" This documentation was written by Pawel Jakub Dawidek under sponsorship from
+.\" the FreeBSD Foundation.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE AUTHORS AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" $FreeBSD$
+.\"
+.Dd February 13, 2013
+.Dt CONNECTAT 2
+.Os
+.Sh NAME
+.Nm connectat
+.Nd initiate a connection on a socket
+.Sh LIBRARY
+.Lb libc
+.Sh SYNOPSIS
+.In sys/types.h
+.In sys/socket.h
+.Pp
+.In fcntl.h
+.Ft int
+.Fn connectat "int fd" "int s" "const struct sockaddr *name" "socklen_t namelen"
+.Sh DESCRIPTION
+The
+.Fn connectat
+system call initiates a connection on a socket.
+It works just like the
+.Xr connect 2
+system call with two exceptions:
+.Pp
+.Bl -enum -offset indent -compact
+.It
+It is limited to sockets in the PF_LOCAL domain.
+.Pp
+.It
+If the file path stored in the
+.Fa sun_path
+field of the sockaddr_un structure is a relative path, it is located relative
+to the directory associated with the file descriptor
+.Fa fd .
+If
+.Fn connectat
+is passed the special value
+.Dv AT_FDCWD
+in the
+.Fa fd
+parameter, the current working directory is used and the behavior is identical
+to a call to
+.Xr connect 2 .
+.El
+.Sh RETURN VALUES
+.Rv -std connectat
+.Sh ERRORS
+The
+.Fn connectat
+system call may fail with the same errors as the
+.Xr connect 2
+system call for a UNIX domain socket or with the following errors:
+.Bl -tag -width Er
+.It Bq Er EBADF
+The
+.Fa sun_path
+field does not specify an absolute path and the
+.Fa fd
+argument is neither
+.Dv AT_FDCWD
+nor a valid file descriptor.
+.It Bq Er ENOTDIR
+The
+.Fa sun_path
+field is not an absolute path and
+.Fa fd
+is neither
+.Dv AT_FDCWD
+nor a file descriptor associated with a directory.
+.El
+.Sh SEE ALSO
+.Xr bindat 2 ,
+.Xr connect 2 ,
+.Xr socket 2 ,
+.Xr unix 4
+.Sh AUTHORS
+The
+.Nm
+was developed by
+.An Pawel Jakub Dawidek Aq pawel@dawidek.net
+under sponsorship from the FreeBSD Foundation.
diff --git a/lib/libprocstat/ntfs.c b/lib/libprocstat/ntfs.c
deleted file mode 100644
index 888e6cd..0000000
--- a/lib/libprocstat/ntfs.c
+++ /dev/null
@@ -1,71 +0,0 @@
-/*-
- * Copyright (c) 2005-2009 Stanislav Sedov <stas@FreeBSD.org>
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-#include <sys/cdefs.h>
-__FBSDID("$FreeBSD$");
-
-#include <sys/param.h>
-#include <sys/stat.h>
-#include <sys/time.h>
-#include <sys/vnode.h>
-#include <sys/mount.h>
-
-#include <netinet/in.h>
-
-#include <assert.h>
-#include <err.h>
-#include <kvm.h>
-#include <stdlib.h>
-
-#include <fs/ntfs/ntfs.h>
-#include <fs/ntfs/ntfs_inode.h>
-
-#include "libprocstat.h"
-#include "common_kvm.h"
-
-int
-ntfs_filestat(kvm_t *kd, struct vnode *vp, struct vnstat *vn)
-{
- struct fnode fnod;
- struct ntnode node;
- int error;
-
- assert(kd);
- assert(vn);
- error = kvm_read_all(kd, (unsigned long)VTOF(vp), &fnod, sizeof(fnod));
- if (error != 0) {
- warnx("can't read ntfs fnode at %p", (void *)VTOF(vp));
- return (1);
- }
- error = kvm_read_all(kd, (unsigned long)FTONT(&fnod), &node,
- sizeof(node));
- if (error != 0) {
- warnx("can't read ntfs node at %p", (void *)FTONT(&fnod));
- return (1);
- }
- vn->vn_fileid = node.i_number;
- vn->vn_fsid = dev2udev(kd, node.i_dev);
- return (0);
-}
diff --git a/lib/libstand/Makefile b/lib/libstand/Makefile
index cfc39e9..2886e92 100644
--- a/lib/libstand/Makefile
+++ b/lib/libstand/Makefile
@@ -67,6 +67,9 @@ SRCS+= divsi3.S
.else
# Compiler support functions
.PATH: ${.CURDIR}/../../contrib/compiler-rt/lib/
+# __clzsi2 and ctzsi2 for various builtin functions
+SRCS+= clzsi2.c ctzsi2.c
+# Divide and modulus functions called by the compiler
SRCS+= divmoddi4.c divmodsi4.c divdi3.c divsi3.c moddi3.c modsi3.c
SRCS+= udivmoddi4.c udivmodsi4.c udivdi3.c udivsi3.c umoddi3.c umodsi3.c
diff --git a/lib/libutil/gr_util.c b/lib/libutil/gr_util.c
index 3f7e199..8df3999 100644
--- a/lib/libutil/gr_util.c
+++ b/lib/libutil/gr_util.c
@@ -49,6 +49,8 @@ static char group_dir[PATH_MAX];
static char group_file[PATH_MAX];
static char tempname[PATH_MAX];
static int initialized;
+static size_t grmemlen(const struct group *, const char *, int *);
+static struct group *grcopy(const struct group *gr, struct group *newgr, const char *, int ndx);
/*
* Initialize statics
@@ -429,90 +431,121 @@ gr_make(const struct group *gr)
struct group *
gr_dup(const struct group *gr)
{
+ return (gr_add(gr, NULL));
+}
+/*
+ * Add a new member name to a struct group.
+ */
+struct group *
+gr_add(const struct group *gr, const char *newmember)
+{
struct group *newgr;
- char *dst;
size_t len;
- int ndx;
int num_mem;
- /* Calculate size of the group. */
- len = sizeof(*newgr);
- if (gr->gr_name != NULL)
- len += strlen(gr->gr_name) + 1;
- if (gr->gr_passwd != NULL)
- len += strlen(gr->gr_passwd) + 1;
- if (gr->gr_mem != NULL) {
- for (num_mem = 0; gr->gr_mem[num_mem] != NULL; num_mem++)
- len += strlen(gr->gr_mem[num_mem]) + 1;
- len += (num_mem + 1) * sizeof(*gr->gr_mem);
- } else
- num_mem = -1;
+ num_mem = 0;
+ len = grmemlen(gr, newmember, &num_mem);
/* Create new group and copy old group into it. */
if ((newgr = malloc(len)) == NULL)
return (NULL);
- /* point new gr_mem to end of struct + 1 */
- if (gr->gr_mem != NULL)
+ return (grcopy(gr, newgr, newmember, num_mem));
+}
+
+/* It is safer to walk the pointers given at gr_mem since there is no
+ * guarantee the gr_mem + strings are continguous in the given struct group
+ * but compact the new group into the following form.
+ *
+ * The new struct is laid out like this in memory. The example given is
+ * for a group with two members only.
+ *
+ * {
+ * (char *name)
+ * (char *passwd)
+ * (int gid)
+ * (gr_mem * newgrp + sizeof(struct group) + sizeof(**)) points to gr_mem area
+ * gr_mem area
+ * (member1 *)
+ * (member2 *)
+ * (NULL)
+ * (name string)
+ * (passwd string)
+ * (member1 string)
+ * (member2 string)
+ * }
+ */
+/*
+ * Copy the guts of a group plus given name to a preallocated group struct
+ */
+static struct group *
+grcopy(const struct group *gr, struct group *newgr, const char *name, int ndx)
+{
+ char *dst;
+ int i;
+
+ if (name != NULL)
+ ndx++;
+ /* point new gr_mem to end of struct + 1 if there are names */
+ if (ndx != 0)
newgr->gr_mem = (char **)(newgr + 1);
else
newgr->gr_mem = NULL;
/* point dst after the end of all the gr_mem pointers in newgr */
- dst = (char *)&newgr->gr_mem[num_mem + 1];
+ dst = (char *)&newgr->gr_mem[ndx + 1];
if (gr->gr_name != NULL) {
newgr->gr_name = dst;
dst = stpcpy(dst, gr->gr_name) + 1;
- } else {
+ } else
newgr->gr_name = NULL;
- }
if (gr->gr_passwd != NULL) {
newgr->gr_passwd = dst;
dst = stpcpy(dst, gr->gr_passwd) + 1;
- } else {
+ } else
newgr->gr_passwd = NULL;
- }
newgr->gr_gid = gr->gr_gid;
- if (gr->gr_mem != NULL) {
- for (ndx = 0; ndx < num_mem; ndx++) {
- newgr->gr_mem[ndx] = dst;
- dst = stpcpy(dst, gr->gr_mem[ndx]) + 1;
+ if (ndx != 0) {
+ for (i = 0; gr->gr_mem[i] != NULL; i++) {
+ newgr->gr_mem[i] = dst;
+ dst = stpcpy(dst, gr->gr_mem[i]) + 1;
+ }
+ if (name != NULL) {
+ newgr->gr_mem[i++] = dst;
+ dst = stpcpy(dst, name) + 1;
}
- newgr->gr_mem[ndx] = NULL;
+ newgr->gr_mem[i] = NULL;
}
return (newgr);
}
/*
- * Add a new member name to a struct group.
+ * Calculate length of a struct group + given name
*/
-struct group *
-gr_add(struct group *gr, char *newmember)
+static size_t
+grmemlen(const struct group *gr, const char *name, int *num_mem)
{
- size_t mlen;
- int num_mem=0;
- char **members;
- struct group *newgr;
-
- if (newmember == NULL)
- return(gr_dup(gr));
+ size_t len;
+ int i;
+ if (gr == NULL)
+ return (0);
+ /* Calculate size of the group. */
+ len = sizeof(*gr);
+ if (gr->gr_name != NULL)
+ len += strlen(gr->gr_name) + 1;
+ if (gr->gr_passwd != NULL)
+ len += strlen(gr->gr_passwd) + 1;
if (gr->gr_mem != NULL) {
- for (num_mem = 0; gr->gr_mem[num_mem] != NULL; num_mem++) {
- if (strcmp(gr->gr_mem[num_mem], newmember) == 0) {
- errno = EEXIST;
- return (NULL);
- }
+ for (len = i = 0; gr->gr_mem[i] != NULL; i++) {
+ len += strlen(gr->gr_mem[i]) + 1;
+ len += sizeof(*gr->gr_mem);
}
+ *num_mem = i;
}
- /* Allocate enough for current pointers + 1 more and NULL marker */
- mlen = (num_mem + 2) * sizeof(*gr->gr_mem);
- if ((members = malloc(mlen)) == NULL)
- return (NULL);
- memcpy(members, gr->gr_mem, num_mem * sizeof(*gr->gr_mem));
- members[num_mem++] = newmember;
- members[num_mem] = NULL;
- gr->gr_mem = members;
- newgr = gr_dup(gr);
- free(members);
- return (newgr);
+ if (name != NULL) {
+ len += strlen(name) + 1;
+ if (gr->gr_mem == NULL)
+ len += sizeof(*gr->gr_mem);
+ }
+ return(len);
}
/*
diff --git a/lib/libutil/libutil.h b/lib/libutil/libutil.h
index b1b2405..b8b9836 100644
--- a/lib/libutil/libutil.h
+++ b/lib/libutil/libutil.h
@@ -167,7 +167,7 @@ int gr_copy(int __ffd, int _tfd, const struct group *_gr,
struct group *
gr_dup(const struct group *_gr);
struct group *
- gr_add(struct group *_gr, char *_newmember);
+ gr_add(const struct group *_gr, const char *_newmember);
int gr_equal(const struct group *_gr1, const struct group *_gr2);
void gr_fini(void);
int gr_init(const char *_dir, const char *_master);
diff --git a/lib/libyaml/Makefile b/lib/libyaml/Makefile
new file mode 100644
index 0000000..5ecec78
--- /dev/null
+++ b/lib/libyaml/Makefile
@@ -0,0 +1,24 @@
+# $FreeBSD$
+
+LIBYAML= ${.CURDIR}/../../contrib/libyaml
+
+LIB= bsdyml
+SHLIB_MAJOR= 0
+INCS= bsdyml.h
+SRCS= api.c dumper.c emitter.c loader.c \
+ parser.c reader.c scanner.c writer.c
+MAN= libbsdyml.3
+
+.PATH: ${LIBYAML}/src ${LIBYAML}/include
+CLEANFILES= bsdyml.h
+
+WARNS?= 1
+CFLAGS+= -I${LIBYAML}/include \
+ -I${LIBYAML} \
+ -I${.CURDIR} \
+ -DHAVE_CONFIG_H
+
+bsdyml.h: yaml.h
+ cp -f ${.ALLSRC} ${.TARGET}
+
+.include <bsd.lib.mk>
diff --git a/lib/libyaml/config.h b/lib/libyaml/config.h
new file mode 100644
index 0000000..7032919
--- /dev/null
+++ b/lib/libyaml/config.h
@@ -0,0 +1,83 @@
+/* $FreeBSD$ */
+
+/* config.h. Generated from config.h.in by configure. */
+/* config.h.in. Generated from configure.ac by autoheader. */
+
+/* Define to 1 if you have the <dlfcn.h> header file. */
+#define HAVE_DLFCN_H 1
+
+/* Define to 1 if you have the <inttypes.h> header file. */
+#define HAVE_INTTYPES_H 1
+
+/* Define to 1 if you have the <memory.h> header file. */
+#define HAVE_MEMORY_H 1
+
+/* Define to 1 if you have the <stdint.h> header file. */
+#define HAVE_STDINT_H 1
+
+/* Define to 1 if you have the <stdlib.h> header file. */
+#define HAVE_STDLIB_H 1
+
+/* Define to 1 if you have the <strings.h> header file. */
+#define HAVE_STRINGS_H 1
+
+/* Define to 1 if you have the <string.h> header file. */
+#define HAVE_STRING_H 1
+
+/* Define to 1 if you have the <sys/stat.h> header file. */
+#define HAVE_SYS_STAT_H 1
+
+/* Define to 1 if you have the <sys/types.h> header file. */
+#define HAVE_SYS_TYPES_H 1
+
+/* Define to 1 if you have the <unistd.h> header file. */
+#define HAVE_UNISTD_H 1
+
+/* Define to the sub-directory in which libtool stores uninstalled libraries.
+ */
+#define LT_OBJDIR ".libs/"
+
+/* Name of package */
+#define PACKAGE "yaml"
+
+/* Define to the address where bug reports for this package should be sent. */
+#define PACKAGE_BUGREPORT "http://pyyaml.org/newticket?component=libyaml"
+
+/* Define to the full name of this package. */
+#define PACKAGE_NAME "yaml"
+
+/* Define to the full name and version of this package. */
+#define PACKAGE_STRING "yaml 0.1.4"
+
+/* Define to the one symbol short name of this package. */
+#define PACKAGE_TARNAME "yaml"
+
+/* Define to the home page for this package. */
+#define PACKAGE_URL ""
+
+/* Define to the version of this package. */
+#define PACKAGE_VERSION "0.1.4"
+
+/* Define to 1 if you have the ANSI C header files. */
+#define STDC_HEADERS 1
+
+/* Version number of package */
+#define VERSION "0.1.4"
+
+/* Define the major version number. */
+#define YAML_VERSION_MAJOR 0
+
+/* Define the minor version number. */
+#define YAML_VERSION_MINOR 1
+
+/* Define the patch version number. */
+#define YAML_VERSION_PATCH 4
+
+/* Define the version string. */
+#define YAML_VERSION_STRING "0.1.4"
+
+/* Define to empty if `const' does not conform to ANSI C. */
+/* #undef const */
+
+/* Define to `unsigned int' if <sys/types.h> does not define. */
+/* #undef size_t */
diff --git a/sbin/mount_ext2fs/mount_ext2fs.8 b/lib/libyaml/libbsdyml.3
index 91a315e..927c47c 100644
--- a/sbin/mount_ext2fs/mount_ext2fs.8
+++ b/lib/libyaml/libbsdyml.3
@@ -1,5 +1,5 @@
-.\" Copyright (c) 1993, 1994
-.\" The Regents of the University of California. All rights reserved.
+.\" Copyright (c) 2013 Baptiste Daroussin <bapt@FreeBSD.org>
+.\" All rights reserved.
.\"
.\" Redistribution and use in source and binary forms, with or without
.\" modification, are permitted provided that the following conditions
@@ -9,14 +9,11 @@
.\" 2. Redistributions in binary form must reproduce the above copyright
.\" notice, this list of conditions and the following disclaimer in the
.\" documentation and/or other materials provided with the distribution.
-.\" 4. Neither the name of the University nor the names of its contributors
-.\" may be used to endorse or promote products derived from this software
-.\" without specific prior written permission.
.\"
-.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+.\" THIS SOFTWARE IS PROVIDED BY THE AUTHORS AND CONTRIBUTORS ``AS IS'' AND
.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
-.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE
.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
@@ -27,46 +24,38 @@
.\"
.\" $FreeBSD$
.\"
-.Dd January 31, 1996
-.Dt MOUNT_EXT2FS 8
+.Dd March 05, 2013
+.Dt LIBBSDYML 3
.Os
.Sh NAME
-.Nm mount_ext2fs
-.Nd mount an ext2fs file system
+.Nm libbsdyml
+.Nd LibYAML library for parsing and emitting YAML
.Sh SYNOPSIS
-.Nm
-.Op Fl o Ar options
-.Ar special
-.Ar node
+.In bsdyml.h
.Sh DESCRIPTION
The
.Nm
-utility attaches an ext2fs file system
-.Ar special
-device on to the file system tree at the point
-.Ar node .
-.Pp
-This command is normally executed by
-.Xr mount 8
-at boot time.
+library is a verbatim copy of the LibYAML version 0.1.4
.Pp
-The options are as follows:
-.Bl -tag -width indent
-.It Fl o
-Options are specified with a
-.Fl o
-flag followed by a comma separated string of options.
-See the
-.Xr mount 8
-man page for possible options and their meanings.
-.El
-.Sh SEE ALSO
-.Xr mount 2 ,
-.Xr unmount 2 ,
-.Xr fstab 5 ,
-.Xr mount 8
-.Sh HISTORY
The
.Nm
-utility first appeared in
-.Fx 2.2 .
+library is intended to be used within the
+.Fx
+base system only.
+Use of the
+.Nm
+library for other purposes is not supported and discouraged.
+.Pp
+To avoid version and autoconfiguration issues, the library has been
+renamed to
+.Nm
+rather than retain the original LibYAML library and include file names
+to prevent confusion and autoconfiguration issues for 3rd party
+software.
+.Sh SEE ALSO
+For full documentation, please see the LibYAML webpage at
+.Pa http://pyyaml.org/wiki/LibYAML .
+.Sh AUTHORS
+.An -nosplit
+The original LibYAML was written by
+.An Kirill Simonov Aq xi@resolvent.net .
diff --git a/sbin/devd/devd.cc b/sbin/devd/devd.cc
index 46f3623..9448775 100644
--- a/sbin/devd/devd.cc
+++ b/sbin/devd/devd.cc
@@ -116,7 +116,7 @@ static struct pidfh *pfh;
int Dflag;
int dflag;
int nflag;
-int romeo_must_die = 0;
+static volatile sig_atomic_t romeo_must_die = 0;
static const char *configfile = CF;
@@ -319,7 +319,7 @@ media::do_match(config &c)
// the name of interest, first try device-name and fall back
// to subsystem if none exists.
value = c.get_variable("device-name");
- if (value.length() == 0)
+ if (value.empty())
value = c.get_variable("subsystem");
if (Dflag)
fprintf(stderr, "Testing media type of %s against 0x%x\n",
@@ -460,7 +460,7 @@ config::open_pidfile()
{
pid_t otherpid;
- if (_pidfile == "")
+ if (_pidfile.empty())
return;
pfh = pidfile_open(_pidfile.c_str(), 0600, &otherpid);
if (pfh == NULL) {
@@ -528,7 +528,7 @@ config::add_notify(int prio, event_proc *p)
void
config::set_pidfile(const char *fn)
{
- _pidfile = string(fn);
+ _pidfile = fn;
}
void
@@ -585,7 +585,7 @@ config::expand_one(const char *&src, string &dst)
src++;
// $$ -> $
if (*src == '$') {
- dst.append(src++, 1);
+ dst += *src++;
return;
}
@@ -593,7 +593,7 @@ config::expand_one(const char *&src, string &dst)
// Not sure if I want to support this or not, so for now we just pass
// it through.
if (*src == '(') {
- dst.append("$");
+ dst += '$';
count = 1;
/* If the string ends before ) is matched , return. */
while (count > 0 && *src) {
@@ -601,23 +601,23 @@ config::expand_one(const char *&src, string &dst)
count--;
else if (*src == '(')
count++;
- dst.append(src++, 1);
+ dst += *src++;
}
return;
}
- // ${^A-Za-z] -> $\1
+ // $[^A-Za-z] -> $\1
if (!isalpha(*src)) {
- dst.append("$");
- dst.append(src++, 1);
+ dst += '$';
+ dst += *src++;
return;
}
// $var -> replace with value
do {
- buffer.append(src++, 1);
+ buffer += *src++;
} while (is_id_char(*src));
- dst.append(get_variable(buffer.c_str()));
+ dst.append(get_variable(buffer));
}
const string
@@ -653,7 +653,7 @@ config::expand_string(const char *src, const char *prepend, const char *append)
}
bool
-config::chop_var(char *&buffer, char *&lhs, char *&rhs)
+config::chop_var(char *&buffer, char *&lhs, char *&rhs) const
{
char *walker;
@@ -912,9 +912,7 @@ event_loop(void)
server_fd = create_socket(PIPE);
accepting = 1;
max_fd = max(fd, server_fd) + 1;
- while (1) {
- if (romeo_must_die)
- break;
+ while (!romeo_must_die) {
if (!once && !dflag && !nflag) {
// Check to see if we have any events pending.
tv.tv_sec = 0;
@@ -1076,8 +1074,7 @@ set_variable(const char *var, const char *val)
static void
gensighand(int)
{
- romeo_must_die++;
- _exit(0);
+ romeo_must_die = 1;
}
static void
diff --git a/sbin/devd/devd.hh b/sbin/devd/devd.hh
index a48d07b..c8a7610 100644
--- a/sbin/devd/devd.hh
+++ b/sbin/devd/devd.hh
@@ -41,8 +41,6 @@ class config;
class var_list
{
public:
- var_list() {}
- virtual ~var_list() {}
/** Set a variable in this var list.
*/
void set_variable(const std::string &var, const std::string &val);
@@ -68,7 +66,6 @@ private:
struct eps
{
public:
- eps() {}
virtual ~eps() {}
/** Does this eps match the current config?
*/
@@ -144,7 +141,7 @@ private:
class config
{
public:
- config() : _pidfile("") { push_var_table(); }
+ config() { push_var_table(); }
virtual ~config() { reset(); }
void add_attach(int, event_proc *);
void add_detach(int, event_proc *);
@@ -172,7 +169,7 @@ protected:
void parse_files_in_dir(const char *dirname);
void expand_one(const char *&src, std::string &dst);
bool is_id_char(char) const;
- bool chop_var(char *&buffer, char *&lhs, char *&rhs);
+ bool chop_var(char *&buffer, char *&lhs, char *&rhs) const;
private:
std::vector<std::string> _dir_list;
std::string _pidfile;
diff --git a/sbin/ipfw/ipfw2.c b/sbin/ipfw/ipfw2.c
index 530f319..ae5d2aa 100644
--- a/sbin/ipfw/ipfw2.c
+++ b/sbin/ipfw/ipfw2.c
@@ -64,6 +64,22 @@ int ipfw_socket = -1;
#define s6_addr32 __u6_addr.__u6_addr32
#endif
+#define CHECK_LENGTH(v, len) do { \
+ if ((v) < (len)) \
+ errx(EX_DATAERR, "Rule too long"); \
+ } while (0)
+/*
+ * Check if we have enough space in cmd buffer. Note that since
+ * first 8? u32 words are reserved by reserved header, full cmd
+ * buffer can't be used, so we need to protect from buffer overrun
+ * only. At the beginnig, cblen is less than actual buffer size by
+ * size of ipfw_insn_u32 instruction + 1 u32 work. This eliminates need
+ * for checking small instructions fitting in given range.
+ * We also (ab)use the fact that ipfw_insn is always the first field
+ * for any custom instruction.
+ */
+#define CHECK_CMDLEN CHECK_LENGTH(cblen, F_LEN((ipfw_insn *)cmd))
+
#define GET_UINT_ARG(arg, min, max, tok, s_x) do { \
if (!av[0]) \
errx(EX_USAGE, "%s: missing argument", match_value(s_x, tok)); \
@@ -653,7 +669,7 @@ strtoport(char *s, char **end, int base, int proto)
* Fill the body of the command with the list of port ranges.
*/
static int
-fill_newports(ipfw_insn_u16 *cmd, char *av, int proto)
+fill_newports(ipfw_insn_u16 *cmd, char *av, int proto, int cblen)
{
uint16_t a, b, *p = cmd->ports;
int i = 0;
@@ -664,6 +680,8 @@ fill_newports(ipfw_insn_u16 *cmd, char *av, int proto)
if (s == av) /* empty or invalid argument */
return (0);
+ CHECK_LENGTH(cblen, i + 2);
+
switch (*s) {
case '-': /* a range */
av = s + 1;
@@ -2068,7 +2086,7 @@ lookup_host (char *host, struct in_addr *ipaddr)
* We can have multiple comma-separated address/mask entries.
*/
static void
-fill_ip(ipfw_insn_ip *cmd, char *av)
+fill_ip(ipfw_insn_ip *cmd, char *av, int cblen)
{
int len = 0;
uint32_t *d = ((ipfw_insn_u32 *)cmd)->d;
@@ -2108,6 +2126,8 @@ fill_ip(ipfw_insn_ip *cmd, char *av)
int masklen;
char md, nd = '\0';
+ CHECK_LENGTH(cblen, F_INSN_SIZE(ipfw_insn) + 2 + len);
+
if (p) {
md = *p;
*p++ = '\0';
@@ -2366,11 +2386,13 @@ ipfw_delete(char *av[])
* patterns which match interfaces.
*/
static void
-fill_iface(ipfw_insn_if *cmd, char *arg)
+fill_iface(ipfw_insn_if *cmd, char *arg, int cblen)
{
cmd->name[0] = '\0';
cmd->o.len |= F_INSN_SIZE(ipfw_insn_if);
+ CHECK_CMDLEN;
+
/* Parse the interface or address */
if (strcmp(arg, "any") == 0)
cmd->o.len = 0; /* effectively ignore this command */
@@ -2441,8 +2463,10 @@ get_mac_addr_mask(const char *p, uint8_t *addr, uint8_t *mask)
* the new command in case it has been clobbered before.
*/
static ipfw_insn *
-next_cmd(ipfw_insn *cmd)
+next_cmd(ipfw_insn *cmd, int *len)
{
+ *len -= F_LEN(cmd);
+ CHECK_LENGTH(*len, 0);
cmd += F_LEN(cmd);
bzero(cmd, sizeof(*cmd));
return cmd;
@@ -2452,7 +2476,7 @@ next_cmd(ipfw_insn *cmd)
* Takes arguments and copies them into a comment
*/
static void
-fill_comment(ipfw_insn *cmd, char **av)
+fill_comment(ipfw_insn *cmd, char **av, int cblen)
{
int i, l;
char *p = (char *)(cmd + 1);
@@ -2470,6 +2494,8 @@ fill_comment(ipfw_insn *cmd, char **av)
"comment too long (max 80 chars)");
l = 1 + (l+3)/4;
cmd->len = (cmd->len & (F_NOT | F_OR)) | l;
+ CHECK_CMDLEN;
+
for (i = 0; av[i] != NULL; i++) {
strcpy(p, av[i]);
p += strlen(av[i]);
@@ -2495,7 +2521,7 @@ fill_cmd(ipfw_insn *cmd, enum ipfw_opcodes opcode, int flags, uint16_t arg)
* two microinstructions, and returns the pointer to the last one.
*/
static ipfw_insn *
-add_mac(ipfw_insn *cmd, char *av[])
+add_mac(ipfw_insn *cmd, char *av[], int cblen)
{
ipfw_insn_mac *mac;
@@ -2504,6 +2530,7 @@ add_mac(ipfw_insn *cmd, char *av[])
cmd->opcode = O_MACADDR2;
cmd->len = (cmd->len & (F_NOT | F_OR)) | F_INSN_SIZE(ipfw_insn_mac);
+ CHECK_CMDLEN;
mac = (ipfw_insn_mac *)cmd;
get_mac_addr_mask(av[0], mac->addr, mac->mask); /* dst */
@@ -2513,12 +2540,13 @@ add_mac(ipfw_insn *cmd, char *av[])
}
static ipfw_insn *
-add_mactype(ipfw_insn *cmd, char *av)
+add_mactype(ipfw_insn *cmd, char *av, int cblen)
{
if (!av)
errx(EX_DATAERR, "missing MAC type");
if (strcmp(av, "any") != 0) { /* we have a non-null type */
- fill_newports((ipfw_insn_u16 *)cmd, av, IPPROTO_ETHERTYPE);
+ fill_newports((ipfw_insn_u16 *)cmd, av, IPPROTO_ETHERTYPE,
+ cblen);
cmd->opcode = O_MAC_TYPE;
return cmd;
} else
@@ -2587,9 +2615,9 @@ add_proto_compat(ipfw_insn *cmd, char *av, u_char *protop)
}
static ipfw_insn *
-add_srcip(ipfw_insn *cmd, char *av)
+add_srcip(ipfw_insn *cmd, char *av, int cblen)
{
- fill_ip((ipfw_insn_ip *)cmd, av);
+ fill_ip((ipfw_insn_ip *)cmd, av, cblen);
if (cmd->opcode == O_IP_DST_SET) /* set */
cmd->opcode = O_IP_SRC_SET;
else if (cmd->opcode == O_IP_DST_LOOKUP) /* table */
@@ -2604,9 +2632,9 @@ add_srcip(ipfw_insn *cmd, char *av)
}
static ipfw_insn *
-add_dstip(ipfw_insn *cmd, char *av)
+add_dstip(ipfw_insn *cmd, char *av, int cblen)
{
- fill_ip((ipfw_insn_ip *)cmd, av);
+ fill_ip((ipfw_insn_ip *)cmd, av, cblen);
if (cmd->opcode == O_IP_DST_SET) /* set */
;
else if (cmd->opcode == O_IP_DST_LOOKUP) /* table */
@@ -2621,12 +2649,12 @@ add_dstip(ipfw_insn *cmd, char *av)
}
static ipfw_insn *
-add_ports(ipfw_insn *cmd, char *av, u_char proto, int opcode)
+add_ports(ipfw_insn *cmd, char *av, u_char proto, int opcode, int cblen)
{
/* XXX "any" is trapped before. Perhaps "to" */
if (_substrcmp(av, "any") == 0) {
return NULL;
- } else if (fill_newports((ipfw_insn_u16 *)cmd, av, proto)) {
+ } else if (fill_newports((ipfw_insn_u16 *)cmd, av, proto, cblen)) {
/* XXX todo: check that we have a protocol with ports */
cmd->opcode = opcode;
return cmd;
@@ -2635,7 +2663,7 @@ add_ports(ipfw_insn *cmd, char *av, u_char proto, int opcode)
}
static ipfw_insn *
-add_src(ipfw_insn *cmd, char *av, u_char proto)
+add_src(ipfw_insn *cmd, char *av, u_char proto, int cblen)
{
struct in6_addr a;
char *host, *ch;
@@ -2648,11 +2676,11 @@ add_src(ipfw_insn *cmd, char *av, u_char proto)
if (proto == IPPROTO_IPV6 || strcmp(av, "me6") == 0 ||
inet_pton(AF_INET6, host, &a) == 1)
- ret = add_srcip6(cmd, av);
+ ret = add_srcip6(cmd, av, cblen);
/* XXX: should check for IPv4, not !IPv6 */
if (ret == NULL && (proto == IPPROTO_IP || strcmp(av, "me") == 0 ||
inet_pton(AF_INET6, host, &a) != 1))
- ret = add_srcip(cmd, av);
+ ret = add_srcip(cmd, av, cblen);
if (ret == NULL && strcmp(av, "any") != 0)
ret = cmd;
@@ -2661,7 +2689,7 @@ add_src(ipfw_insn *cmd, char *av, u_char proto)
}
static ipfw_insn *
-add_dst(ipfw_insn *cmd, char *av, u_char proto)
+add_dst(ipfw_insn *cmd, char *av, u_char proto, int cblen)
{
struct in6_addr a;
char *host, *ch;
@@ -2674,11 +2702,11 @@ add_dst(ipfw_insn *cmd, char *av, u_char proto)
if (proto == IPPROTO_IPV6 || strcmp(av, "me6") == 0 ||
inet_pton(AF_INET6, host, &a) == 1)
- ret = add_dstip6(cmd, av);
+ ret = add_dstip6(cmd, av, cblen);
/* XXX: should check for IPv4, not !IPv6 */
if (ret == NULL && (proto == IPPROTO_IP || strcmp(av, "me") == 0 ||
inet_pton(AF_INET6, host, &a) != 1))
- ret = add_dstip(cmd, av);
+ ret = add_dstip(cmd, av, cblen);
if (ret == NULL && strcmp(av, "any") != 0)
ret = cmd;
@@ -2708,6 +2736,7 @@ ipfw_add(char *av[])
* go into actbuf[].
*/
static uint32_t rulebuf[255], actbuf[255], cmdbuf[255];
+ int rblen, ablen, cblen;
ipfw_insn *src, *dst, *cmd, *action, *prev=NULL;
ipfw_insn *first_cmd; /* first match pattern */
@@ -2738,6 +2767,15 @@ ipfw_add(char *av[])
cmd = (ipfw_insn *)cmdbuf;
action = (ipfw_insn *)actbuf;
+ rblen = sizeof(rulebuf) / sizeof(rulebuf[0]);
+ rblen -= offsetof(struct ip_fw, cmd) / sizeof(rulebuf[0]);
+ ablen = sizeof(actbuf) / sizeof(actbuf[0]);
+ cblen = sizeof(cmdbuf) / sizeof(cmdbuf[0]);
+ cblen -= F_INSN_SIZE(ipfw_insn_u32) + 1;
+
+#define CHECK_RBUFLEN(len) { CHECK_LENGTH(rblen, len); rblen -= len; }
+#define CHECK_ACTLEN CHECK_LENGTH(ablen, action->len)
+
av++;
/* [rule N] -- Rule number optional */
@@ -2769,6 +2807,7 @@ ipfw_add(char *av[])
i = match_token(rule_actions, *av);
av++;
action->len = 1; /* default */
+ CHECK_ACTLEN;
switch(i) {
case TOK_CHECKSTATE:
have_state = action;
@@ -2820,6 +2859,7 @@ ipfw_add(char *av[])
case TOK_NAT:
action->opcode = O_NAT;
action->len = F_INSN_SIZE(ipfw_insn_nat);
+ CHECK_ACTLEN;
if (_substrcmp(*av, "global") == 0) {
action->arg1 = 0;
av++;
@@ -2936,6 +2976,7 @@ chkarg:
action->opcode = O_FORWARD_IP;
action->len = F_INSN_SIZE(ipfw_insn_sa);
+ CHECK_ACTLEN;
/*
* In the kernel we assume AF_INET and use only
@@ -2952,6 +2993,7 @@ chkarg:
action->opcode = O_FORWARD_IP6;
action->len = F_INSN_SIZE(ipfw_insn_sa6);
+ CHECK_ACTLEN;
p->sa.sin6_len = sizeof(struct sockaddr_in6);
p->sa.sin6_family = AF_INET6;
@@ -3005,7 +3047,7 @@ chkarg:
default:
errx(EX_DATAERR, "invalid action %s\n", av[-1]);
}
- action = next_cmd(action);
+ action = next_cmd(action, &ablen);
/*
* [altq queuename] -- altq tag, optional
@@ -3027,6 +3069,7 @@ chkarg:
"log cannot be specified more than once");
have_log = (ipfw_insn *)c;
cmd->len = F_INSN_SIZE(ipfw_insn_log);
+ CHECK_CMDLEN;
cmd->opcode = O_LOG;
if (av[0] && _substrcmp(*av, "logamount") == 0) {
av++;
@@ -3040,9 +3083,14 @@ chkarg:
} else {
len = sizeof(c->max_log);
if (sysctlbyname("net.inet.ip.fw.verbose_limit",
- &c->max_log, &len, NULL, 0) == -1)
+ &c->max_log, &len, NULL, 0) == -1) {
+ if (co.test_only) {
+ c->max_log = 0;
+ break;
+ }
errx(1, "sysctlbyname(\"%s\")",
"net.inet.ip.fw.verbose_limit");
+ }
}
}
break;
@@ -3058,6 +3106,7 @@ chkarg:
"altq cannot be specified more than once");
have_altq = (ipfw_insn *)a;
cmd->len = F_INSN_SIZE(ipfw_insn_altq);
+ CHECK_CMDLEN;
cmd->opcode = O_ALTQ;
a->qid = altq_name_to_qid(*av);
av++;
@@ -3083,7 +3132,7 @@ chkarg:
default:
abort();
}
- cmd = next_cmd(cmd);
+ cmd = next_cmd(cmd, &cblen);
}
if (have_state) /* must be a check-state, we are done */
@@ -3168,7 +3217,7 @@ chkarg:
av++;
if (F_LEN(cmd) != 0) {
prev = cmd;
- cmd = next_cmd(cmd);
+ cmd = next_cmd(cmd, &cblen);
}
} else if (first_cmd != cmd) {
errx(EX_DATAERR, "invalid protocol ``%s''", *av);
@@ -3189,11 +3238,11 @@ chkarg:
OR_START(source_ip);
NOT_BLOCK; /* optional "not" */
NEED1("missing source address");
- if (add_src(cmd, *av, proto)) {
+ if (add_src(cmd, *av, proto, cblen)) {
av++;
if (F_LEN(cmd) != 0) { /* ! any */
prev = cmd;
- cmd = next_cmd(cmd);
+ cmd = next_cmd(cmd, &cblen);
}
} else
errx(EX_USAGE, "bad source address %s", *av);
@@ -3205,10 +3254,10 @@ chkarg:
NOT_BLOCK; /* optional "not" */
if ( av[0] != NULL ) {
if (_substrcmp(*av, "any") == 0 ||
- add_ports(cmd, *av, proto, O_IP_SRCPORT)) {
+ add_ports(cmd, *av, proto, O_IP_SRCPORT, cblen)) {
av++;
if (F_LEN(cmd) != 0)
- cmd = next_cmd(cmd);
+ cmd = next_cmd(cmd, &cblen);
}
}
@@ -3225,11 +3274,11 @@ chkarg:
OR_START(dest_ip);
NOT_BLOCK; /* optional "not" */
NEED1("missing dst address");
- if (add_dst(cmd, *av, proto)) {
+ if (add_dst(cmd, *av, proto, cblen)) {
av++;
if (F_LEN(cmd) != 0) { /* ! any */
prev = cmd;
- cmd = next_cmd(cmd);
+ cmd = next_cmd(cmd, &cblen);
}
} else
errx( EX_USAGE, "bad destination address %s", *av);
@@ -3241,10 +3290,10 @@ chkarg:
NOT_BLOCK; /* optional "not" */
if (av[0]) {
if (_substrcmp(*av, "any") == 0 ||
- add_ports(cmd, *av, proto, O_IP_DSTPORT)) {
+ add_ports(cmd, *av, proto, O_IP_DSTPORT, cblen)) {
av++;
if (F_LEN(cmd) != 0)
- cmd = next_cmd(cmd);
+ cmd = next_cmd(cmd, &cblen);
}
}
@@ -3332,7 +3381,7 @@ read_options:
case TOK_VIA:
NEED1("recv, xmit, via require interface name"
" or address");
- fill_iface((ipfw_insn_if *)cmd, av[0]);
+ fill_iface((ipfw_insn_if *)cmd, av[0], cblen);
av++;
if (F_LEN(cmd) == 0) /* not a valid address */
break;
@@ -3352,14 +3401,14 @@ read_options:
case TOK_ICMP6TYPES:
NEED1("icmptypes requires list of types");
- fill_icmp6types((ipfw_insn_icmp6 *)cmd, *av);
+ fill_icmp6types((ipfw_insn_icmp6 *)cmd, *av, cblen);
av++;
break;
case TOK_IPTTL:
NEED1("ipttl requires TTL");
if (strpbrk(*av, "-,")) {
- if (!add_ports(cmd, *av, 0, O_IPTTL))
+ if (!add_ports(cmd, *av, 0, O_IPTTL, cblen))
errx(EX_DATAERR, "invalid ipttl %s", *av);
} else
fill_cmd(cmd, O_IPTTL, 0, strtoul(*av, NULL, 0));
@@ -3369,7 +3418,7 @@ read_options:
case TOK_IPID:
NEED1("ipid requires id");
if (strpbrk(*av, "-,")) {
- if (!add_ports(cmd, *av, 0, O_IPID))
+ if (!add_ports(cmd, *av, 0, O_IPID, cblen))
errx(EX_DATAERR, "invalid ipid %s", *av);
} else
fill_cmd(cmd, O_IPID, 0, strtoul(*av, NULL, 0));
@@ -3379,7 +3428,7 @@ read_options:
case TOK_IPLEN:
NEED1("iplen requires length");
if (strpbrk(*av, "-,")) {
- if (!add_ports(cmd, *av, 0, O_IPLEN))
+ if (!add_ports(cmd, *av, 0, O_IPLEN, cblen))
errx(EX_DATAERR, "invalid ip len %s", *av);
} else
fill_cmd(cmd, O_IPLEN, 0, strtoul(*av, NULL, 0));
@@ -3475,7 +3524,7 @@ read_options:
case TOK_TCPDATALEN:
NEED1("tcpdatalen requires length");
if (strpbrk(*av, "-,")) {
- if (!add_ports(cmd, *av, 0, O_TCPDATALEN))
+ if (!add_ports(cmd, *av, 0, O_TCPDATALEN, cblen))
errx(EX_DATAERR, "invalid tcpdata len %s", *av);
} else
fill_cmd(cmd, O_TCPDATALEN, 0,
@@ -3501,7 +3550,7 @@ read_options:
case TOK_TCPWIN:
NEED1("tcpwin requires length");
if (strpbrk(*av, "-,")) {
- if (!add_ports(cmd, *av, 0, O_TCPWIN))
+ if (!add_ports(cmd, *av, 0, O_TCPWIN, cblen))
errx(EX_DATAERR, "invalid tcpwin len %s", *av);
} else
fill_cmd(cmd, O_TCPWIN, 0,
@@ -3540,6 +3589,7 @@ read_options:
have_state = cmd;
cmd->len = F_INSN_SIZE(ipfw_insn_limit);
+ CHECK_CMDLEN;
cmd->opcode = O_LIMIT;
c->limit_mask = c->conn_limit = 0;
@@ -3571,28 +3621,28 @@ read_options:
case TOK_SRCIP:
NEED1("missing source IP");
- if (add_srcip(cmd, *av)) {
+ if (add_srcip(cmd, *av, cblen)) {
av++;
}
break;
case TOK_DSTIP:
NEED1("missing destination IP");
- if (add_dstip(cmd, *av)) {
+ if (add_dstip(cmd, *av, cblen)) {
av++;
}
break;
case TOK_SRCIP6:
NEED1("missing source IP6");
- if (add_srcip6(cmd, *av)) {
+ if (add_srcip6(cmd, *av, cblen)) {
av++;
}
break;
case TOK_DSTIP6:
NEED1("missing destination IP6");
- if (add_dstip6(cmd, *av)) {
+ if (add_dstip6(cmd, *av, cblen)) {
av++;
}
break;
@@ -3600,7 +3650,7 @@ read_options:
case TOK_SRCPORT:
NEED1("missing source port");
if (_substrcmp(*av, "any") == 0 ||
- add_ports(cmd, *av, proto, O_IP_SRCPORT)) {
+ add_ports(cmd, *av, proto, O_IP_SRCPORT, cblen)) {
av++;
} else
errx(EX_DATAERR, "invalid source port %s", *av);
@@ -3609,7 +3659,7 @@ read_options:
case TOK_DSTPORT:
NEED1("missing destination port");
if (_substrcmp(*av, "any") == 0 ||
- add_ports(cmd, *av, proto, O_IP_DSTPORT)) {
+ add_ports(cmd, *av, proto, O_IP_DSTPORT, cblen)) {
av++;
} else
errx(EX_DATAERR, "invalid destination port %s",
@@ -3617,13 +3667,13 @@ read_options:
break;
case TOK_MAC:
- if (add_mac(cmd, av))
+ if (add_mac(cmd, av, cblen))
av += 2;
break;
case TOK_MACTYPE:
NEED1("missing mac type");
- if (!add_mactype(cmd, *av))
+ if (!add_mactype(cmd, *av, cblen))
errx(EX_DATAERR, "invalid mac type %s", *av);
av++;
break;
@@ -3661,18 +3711,18 @@ read_options:
if (proto != IPPROTO_IPV6 )
errx( EX_USAGE, "flow-id filter is active "
"only for ipv6 protocol\n");
- fill_flow6( (ipfw_insn_u32 *) cmd, *av );
+ fill_flow6( (ipfw_insn_u32 *) cmd, *av, cblen);
av++;
break;
case TOK_COMMENT:
- fill_comment(cmd, av);
+ fill_comment(cmd, av, cblen);
av[0]=NULL;
break;
case TOK_TAGGED:
if (av[0] && strpbrk(*av, "-,")) {
- if (!add_ports(cmd, *av, 0, O_TAGGED))
+ if (!add_ports(cmd, *av, 0, O_TAGGED, cblen))
errx(EX_DATAERR, "tagged: invalid tag"
" list: %s", *av);
}
@@ -3725,7 +3775,7 @@ read_options:
}
if (F_LEN(cmd) > 0) { /* prepare to advance */
prev = cmd;
- cmd = next_cmd(cmd);
+ cmd = next_cmd(cmd, &cblen);
}
}
@@ -3754,12 +3804,13 @@ done:
*/
if (have_state && have_state->opcode != O_CHECK_STATE) {
fill_cmd(dst, O_PROBE_STATE, 0, 0);
- dst = next_cmd(dst);
+ dst = next_cmd(dst, &rblen);
}
/* copy all commands but O_LOG, O_KEEP_STATE, O_LIMIT, O_ALTQ, O_TAG */
for (src = (ipfw_insn *)cmdbuf; src != cmd; src += i) {
i = F_LEN(src);
+ CHECK_RBUFLEN(i);
switch (src->opcode) {
case O_LOG:
@@ -3779,6 +3830,7 @@ done:
*/
if (have_state && have_state->opcode != O_CHECK_STATE) {
i = F_LEN(have_state);
+ CHECK_RBUFLEN(i);
bcopy(have_state, dst, i * sizeof(uint32_t));
dst += i;
}
@@ -3790,24 +3842,29 @@ done:
/* put back O_LOG, O_ALTQ, O_TAG if necessary */
if (have_log) {
i = F_LEN(have_log);
+ CHECK_RBUFLEN(i);
bcopy(have_log, dst, i * sizeof(uint32_t));
dst += i;
}
if (have_altq) {
i = F_LEN(have_altq);
+ CHECK_RBUFLEN(i);
bcopy(have_altq, dst, i * sizeof(uint32_t));
dst += i;
}
if (have_tag) {
i = F_LEN(have_tag);
+ CHECK_RBUFLEN(i);
bcopy(have_tag, dst, i * sizeof(uint32_t));
dst += i;
}
+
/*
* copy all other actions
*/
for (src = (ipfw_insn *)actbuf; src != action; src += i) {
i = F_LEN(src);
+ CHECK_RBUFLEN(i);
bcopy(src, dst, i * sizeof(uint32_t));
dst += i;
}
@@ -3912,6 +3969,7 @@ ipfw_flush(int force)
static void table_list(uint16_t num, int need_header);
+static void table_fill_xentry(char *arg, ipfw_table_xentry *xent);
/*
* This one handles all table-related commands
@@ -3927,16 +3985,19 @@ ipfw_table_handler(int ac, char *av[])
int do_add;
int is_all;
size_t len;
- char *p;
- uint32_t a, type, mask, addrlen;
+ uint32_t a, mask;
uint32_t tables_max;
mask = 0; // XXX uninitialized ?
len = sizeof(tables_max);
if (sysctlbyname("net.inet.ip.fw.tables_max", &tables_max, &len,
- NULL, 0) == -1)
- errx(1, "Can't determine maximum number of ipfw tables. "
- "Perhaps you forgot to load ipfw module?");
+ NULL, 0) == -1) {
+ if (co.test_only)
+ tables_max = 128; /* Old conservative default */
+ else
+ errx(1, "Can't determine maximum number of ipfw tables."
+ " Perhaps you forgot to load ipfw module?");
+ }
memset(&xent, 0, sizeof(xent));
@@ -3965,57 +4026,8 @@ ipfw_table_handler(int ac, char *av[])
ac--; av++;
if (!ac)
errx(EX_USAGE, "address required");
- /*
- * Let's try to guess type by agrument.
- * Possible types:
- * 1) IPv4[/mask]
- * 2) IPv6[/mask]
- * 3) interface name
- * 4) port ?
- */
- type = 0;
- if (ishexnumber(*av[0])) {
- /* Remove / if exists */
- if ((p = strchr(*av, '/')) != NULL) {
- *p = '\0';
- mask = atoi(p + 1);
- }
-
- if (inet_pton(AF_INET, *av, &xent.k.addr6) == 1) {
- type = IPFW_TABLE_CIDR;
- if ((p != NULL) && (mask > 32))
- errx(EX_DATAERR, "bad IPv4 mask width: %s", p + 1);
- xent.masklen = p ? mask : 32;
- addrlen = sizeof(struct in_addr);
- } else if (inet_pton(AF_INET6, *av, &xent.k.addr6) == 1) {
- type = IPFW_TABLE_CIDR;
- if ((p != NULL) && (mask > 128))
- errx(EX_DATAERR, "bad IPv6 mask width: %s", p + 1);
- xent.masklen = p ? mask : 128;
- addrlen = sizeof(struct in6_addr);
- }
- }
-
- if ((type == 0) && (strchr(*av, '.') == NULL)) {
- /* Assume interface name. Copy significant data only */
- mask = MIN(strlen(*av), IF_NAMESIZE - 1);
- memcpy(xent.k.iface, *av, mask);
- /* Set mask to exact match */
- xent.masklen = 8 * IF_NAMESIZE;
- type = IPFW_TABLE_INTERFACE;
- addrlen = IF_NAMESIZE;
- }
- if (type == 0) {
- if (lookup_host(*av, (struct in_addr *)&xent.k.addr6) != 0)
- errx(EX_NOHOST, "hostname ``%s'' unknown", *av);
- xent.masklen = 32;
- type = IPFW_TABLE_CIDR;
- addrlen = sizeof(struct in_addr);
- }
-
- xent.type = type;
- xent.len = offsetof(ipfw_table_xentry, k) + addrlen;
+ table_fill_xentry(*av, &xent);
ac--; av++;
if (do_add && ac) {
@@ -4065,6 +4077,93 @@ ipfw_table_handler(int ac, char *av[])
}
static void
+table_fill_xentry(char *arg, ipfw_table_xentry *xent)
+{
+ int addrlen, mask, masklen, type;
+ struct in6_addr *paddr;
+ uint32_t *pkey;
+ char *p;
+ uint32_t key;
+
+ mask = 0;
+ type = 0;
+ addrlen = 0;
+ masklen = 0;
+
+ /*
+ * Let's try to guess type by agrument.
+ * Possible types:
+ * 1) IPv4[/mask]
+ * 2) IPv6[/mask]
+ * 3) interface name
+ * 4) port, uid/gid or other u32 key (base 10 format)
+ * 5) hostname
+ */
+ paddr = &xent->k.addr6;
+ if (ishexnumber(*arg) != 0 || *arg == ':') {
+ /* Remove / if exists */
+ if ((p = strchr(arg, '/')) != NULL) {
+ *p = '\0';
+ mask = atoi(p + 1);
+ }
+
+ if (inet_pton(AF_INET, arg, paddr) == 1) {
+ if (p != NULL && mask > 32)
+ errx(EX_DATAERR, "bad IPv4 mask width: %s",
+ p + 1);
+
+ type = IPFW_TABLE_CIDR;
+ masklen = p ? mask : 32;
+ addrlen = sizeof(struct in_addr);
+ } else if (inet_pton(AF_INET6, arg, paddr) == 1) {
+ if (IN6_IS_ADDR_V4COMPAT(paddr))
+ errx(EX_DATAERR,
+ "Use IPv4 instead of v4-compatible");
+ if (p != NULL && mask > 128)
+ errx(EX_DATAERR, "bad IPv6 mask width: %s",
+ p + 1);
+
+ type = IPFW_TABLE_CIDR;
+ masklen = p ? mask : 128;
+ addrlen = sizeof(struct in6_addr);
+ } else {
+ /* Port or any other key */
+ key = strtol(arg, &p, 10);
+ /* Skip non-base 10 entries like 'fa1' */
+ if (p != arg) {
+ pkey = (uint32_t *)paddr;
+ *pkey = htonl(key);
+ type = IPFW_TABLE_CIDR;
+ addrlen = sizeof(uint32_t);
+ }
+ }
+ }
+
+ if (type == 0 && strchr(arg, '.') == NULL) {
+ /* Assume interface name. Copy significant data only */
+ mask = MIN(strlen(arg), IF_NAMESIZE - 1);
+ memcpy(xent->k.iface, arg, mask);
+ /* Set mask to exact match */
+ masklen = 8 * IF_NAMESIZE;
+ type = IPFW_TABLE_INTERFACE;
+ addrlen = IF_NAMESIZE;
+ }
+
+ if (type == 0) {
+ if (lookup_host(arg, (struct in_addr *)paddr) != 0)
+ errx(EX_NOHOST, "hostname ``%s'' unknown", arg);
+
+ masklen = 32;
+ type = IPFW_TABLE_CIDR;
+ addrlen = sizeof(struct in_addr);
+ }
+
+ xent->type = type;
+ xent->masklen = masklen;
+ xent->len = offsetof(ipfw_table_xentry, k) + addrlen;
+}
+
+static void
table_list(uint16_t num, int need_header)
{
ipfw_xtable *tbl;
@@ -4107,8 +4206,8 @@ table_list(uint16_t num, int need_header)
tval = xent->value;
addr6 = &xent->k.addr6;
- if ((addr6->s6_addr32[0] == 0) && (addr6->s6_addr32[1] == 0) &&
- (addr6->s6_addr32[2] == 0)) {
+
+ if (IN6_IS_ADDR_V4COMPAT(addr6)) {
/* IPv4 address */
inet_ntop(AF_INET, &addr6->s6_addr32[3], tbuf, sizeof(tbuf));
} else {
diff --git a/sbin/ipfw/ipfw2.h b/sbin/ipfw/ipfw2.h
index bade0dd..81e0ba8 100644
--- a/sbin/ipfw/ipfw2.h
+++ b/sbin/ipfw/ipfw2.h
@@ -283,10 +283,10 @@ void print_flow6id(struct _ipfw_insn_u32 *cmd);
void print_icmp6types(struct _ipfw_insn_u32 *cmd);
void print_ext6hdr(struct _ipfw_insn *cmd );
-struct _ipfw_insn *add_srcip6(struct _ipfw_insn *cmd, char *av);
-struct _ipfw_insn *add_dstip6(struct _ipfw_insn *cmd, char *av);
+struct _ipfw_insn *add_srcip6(struct _ipfw_insn *cmd, char *av, int cblen);
+struct _ipfw_insn *add_dstip6(struct _ipfw_insn *cmd, char *av, int cblen);
-void fill_flow6(struct _ipfw_insn_u32 *cmd, char *av );
+void fill_flow6(struct _ipfw_insn_u32 *cmd, char *av, int cblen);
void fill_unreach6_code(u_short *codep, char *str);
-void fill_icmp6types(struct _ipfw_insn_icmp6 *cmd, char *av);
+void fill_icmp6types(struct _ipfw_insn_icmp6 *cmd, char *av, int cblen);
int fill_ext6hdr(struct _ipfw_insn *cmd, char *av);
diff --git a/sbin/ipfw/ipv6.c b/sbin/ipfw/ipv6.c
index 6326590..ee9bb62 100644
--- a/sbin/ipfw/ipv6.c
+++ b/sbin/ipfw/ipv6.c
@@ -42,6 +42,11 @@
#include <netinet/ip_fw.h>
#include <arpa/inet.h>
+#define CHECK_LENGTH(v, len) do { \
+ if ((v) < (len)) \
+ errx(EX_DATAERR, "Rule too long"); \
+ } while (0)
+
static struct _s_x icmp6codes[] = {
{ "no-route", ICMP6_DST_UNREACH_NOROUTE },
{ "admin-prohib", ICMP6_DST_UNREACH_ADMIN },
@@ -131,10 +136,12 @@ print_ip6(ipfw_insn_ip6 *cmd, char const *s)
}
void
-fill_icmp6types(ipfw_insn_icmp6 *cmd, char *av)
+fill_icmp6types(ipfw_insn_icmp6 *cmd, char *av, int cblen)
{
uint8_t type;
+ CHECK_LENGTH(cblen, F_INSN_SIZE(ipfw_insn_icmp6));
+
bzero(cmd, sizeof(*cmd));
while (*av) {
if (*av == ',')
@@ -327,7 +334,7 @@ lookup_host6 (char *host, struct in6_addr *ip6addr)
* Return 1 on success, 0 on failure.
*/
static int
-fill_ip6(ipfw_insn_ip6 *cmd, char *av)
+fill_ip6(ipfw_insn_ip6 *cmd, char *av, int cblen)
{
int len = 0;
struct in6_addr *d = &(cmd->addr6);
@@ -379,6 +386,8 @@ fill_ip6(ipfw_insn_ip6 *cmd, char *av)
int masklen;
char md = '\0';
+ CHECK_LENGTH(cblen, 1 + len + 2 * F_INSN_SIZE(struct in6_addr));
+
if ((p = strpbrk(av, "/,")) ) {
md = *p; /* save the separator */
*p = '\0'; /* terminate address string */
@@ -453,7 +462,7 @@ fill_ip6(ipfw_insn_ip6 *cmd, char *av)
* additional flow-id we want to filter, the basic is 1
*/
void
-fill_flow6( ipfw_insn_u32 *cmd, char *av )
+fill_flow6( ipfw_insn_u32 *cmd, char *av, int cblen)
{
u_int32_t type; /* Current flow number */
u_int16_t nflow = 0; /* Current flow index */
@@ -461,6 +470,8 @@ fill_flow6( ipfw_insn_u32 *cmd, char *av )
cmd->d[0] = 0; /* Initializing the base number*/
while (s) {
+ CHECK_LENGTH(cblen, F_INSN_SIZE(ipfw_insn_u32) + nflow + 1);
+
av = strsep( &s, ",") ;
type = strtoul(av, &av, 0);
if (*av != ',' && *av != '\0')
@@ -481,10 +492,10 @@ fill_flow6( ipfw_insn_u32 *cmd, char *av )
}
ipfw_insn *
-add_srcip6(ipfw_insn *cmd, char *av)
+add_srcip6(ipfw_insn *cmd, char *av, int cblen)
{
- fill_ip6((ipfw_insn_ip6 *)cmd, av);
+ fill_ip6((ipfw_insn_ip6 *)cmd, av, cblen);
if (cmd->opcode == O_IP_DST_SET) /* set */
cmd->opcode = O_IP_SRC_SET;
else if (cmd->opcode == O_IP_DST_LOOKUP) /* table */
@@ -503,10 +514,10 @@ add_srcip6(ipfw_insn *cmd, char *av)
}
ipfw_insn *
-add_dstip6(ipfw_insn *cmd, char *av)
+add_dstip6(ipfw_insn *cmd, char *av, int cblen)
{
- fill_ip6((ipfw_insn_ip6 *)cmd, av);
+ fill_ip6((ipfw_insn_ip6 *)cmd, av, cblen);
if (cmd->opcode == O_IP_DST_SET) /* set */
;
else if (cmd->opcode == O_IP_DST_LOOKUP) /* table */
diff --git a/sbin/mount_cd9660/mount_cd9660.8 b/sbin/mount_cd9660/mount_cd9660.8
index 909af40..b471686 100644
--- a/sbin/mount_cd9660/mount_cd9660.8
+++ b/sbin/mount_cd9660/mount_cd9660.8
@@ -32,7 +32,7 @@
.\" @(#)mount_cd9660.8 8.3 (Berkeley) 3/27/94
.\" $FreeBSD$
.\"
-.Dd October 3, 2005
+.Dd March 5, 2013
.Dt MOUNT_CD9660 8
.Os
.Sh NAME
@@ -80,7 +80,7 @@ See the
man page for possible options and their meanings.
The following cd9660 specific options are available:
.Pp
-.Bl -tag -width "nostrictjoliet" -compact
+.Bl -tag -width "brokenjoliet" -compact
.It Cm extatt
Same as
.Fl e .
@@ -93,7 +93,7 @@ Same as
.It Cm norrip
Same as
.Fl r .
-.It Cm nostrictjoliet
+.It Cm brokenjoliet
Same as
.Fl b .
.El
diff --git a/sbin/mount_cd9660/mount_cd9660.c b/sbin/mount_cd9660/mount_cd9660.c
index 2215966..7ea6064 100644
--- a/sbin/mount_cd9660/mount_cd9660.c
+++ b/sbin/mount_cd9660/mount_cd9660.c
@@ -83,7 +83,7 @@ main(int argc, char **argv)
{
struct iovec *iov;
int iovlen;
- int ch, mntflags, opts;
+ int ch, mntflags;
char *dev, *dir, *p, *val, mntpath[MAXPATHLEN];
int verbose;
int ssector; /* starting sector, 0 for 1st session */
@@ -91,7 +91,7 @@ main(int argc, char **argv)
iov = NULL;
iovlen = 0;
- mntflags = opts = verbose = 0;
+ mntflags = verbose = 0;
ssector = -1;
while ((ch = getopt(argc, argv, "begjo:rs:vC:")) != -1)
@@ -109,7 +109,7 @@ main(int argc, char **argv)
build_iovec(&iov, &iovlen, "nojoliet", NULL, (size_t)-1);
break;
case 'o':
- getmntopts(optarg, mopts, &mntflags, &opts);
+ getmntopts(optarg, mopts, &mntflags, NULL);
p = strchr(optarg, '=');
val = NULL;
if (p != NULL) {
diff --git a/sbin/mount_ext2fs/Makefile b/sbin/mount_ext2fs/Makefile
deleted file mode 100644
index 08a0c3c..0000000
--- a/sbin/mount_ext2fs/Makefile
+++ /dev/null
@@ -1,14 +0,0 @@
-# @(#)Makefile 8.3 (Berkeley) 3/27/94
-# $FreeBSD$
-
-PROG= mount_ext2fs
-SRCS= mount_ext2fs.c getmntopts.c
-MAN= mount_ext2fs.8
-
-WARNS?= 2
-MOUNT= ${.CURDIR}/../mount
-CFLAGS+= -I${MOUNT}
-
-.PATH: ${MOUNT}
-
-.include <bsd.prog.mk>
diff --git a/sbin/mount_ext2fs/mount_ext2fs.c b/sbin/mount_ext2fs/mount_ext2fs.c
deleted file mode 100644
index 8753997..0000000
--- a/sbin/mount_ext2fs/mount_ext2fs.c
+++ /dev/null
@@ -1,125 +0,0 @@
-/*-
- * Copyright (c) 1993, 1994
- * The Regents of the University of California. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-#ifndef lint
-static const char copyright[] =
-"@(#) Copyright (c) 1993, 1994\n\
- The Regents of the University of California. All rights reserved.\n";
-#endif /* not lint */
-
-#ifndef lint
-/*
-static char sccsid[] = "@(#)mount_lfs.c 8.3 (Berkeley) 3/27/94";
-*/
-static const char rcsid[] =
- "$FreeBSD$";
-#endif /* not lint */
-
-#include <sys/param.h>
-#include <sys/mount.h>
-#include <sys/uio.h>
-
-#include <err.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <sysexits.h>
-#include <unistd.h>
-
-#include "mntopts.h"
-
-static void usage(void);
-
-int
-main(int argc, char *argv[])
-{
- struct iovec *iov;
- int ch, iovlen;
- char *fs_name, *fspec, mntpath[MAXPATHLEN];
- char *fstype;
-
- fstype = strrchr(argv[0], '_');
- if (fstype == NULL)
- errx(EX_USAGE, "argv[0] must end in _fstype");
- else
- ++fstype;
-
- iov = NULL;
- iovlen = 0;
- while ((ch = getopt(argc, argv, "o:")) != -1)
- switch (ch) {
- case 'o': {
- char *p = NULL;
- char *val = strdup("");
- p = strchr(optarg, '=');
- if (p != NULL) {
- free(val);
- *p = '\0';
- val = p + 1;
- }
- build_iovec(&iov, &iovlen, optarg, val, strlen(val)+1);
- }
- break;
- case '?':
- default:
- usage();
- }
- argc -= optind;
- argv += optind;
-
- if (argc != 2)
- usage();
-
- fspec = argv[0]; /* the name of the device file */
- fs_name = argv[1]; /* the mount point */
-
- /*
- * Resolve the mountpoint with realpath(3) and remove unnecessary
- * slashes from the devicename if there are any.
- */
- if (checkpath(fs_name, mntpath) != 0)
- err(EX_USAGE, "%s", mntpath);
- (void)rmslashes(fspec, fspec);
-
- build_iovec(&iov, &iovlen, "fstype", fstype, strlen(fstype) + 1);
- build_iovec(&iov, &iovlen, "fspath", mntpath, strlen(mntpath) + 1);
- build_iovec(&iov, &iovlen, "from", fspec, strlen(fspec) + 1);
-
- if (nmount(iov, iovlen, 0) < 0)
- err(EX_OSERR, "%s", fspec);
- return (0);
-}
-
-static void
-usage()
-{
- (void)fprintf(stderr,
- "usage: mount_ext2fs [-o options] special node\n");
- exit(EX_USAGE);
-}
diff --git a/sbin/mount_hpfs/Makefile b/sbin/mount_hpfs/Makefile
deleted file mode 100644
index 9e65b8e..0000000
--- a/sbin/mount_hpfs/Makefile
+++ /dev/null
@@ -1,14 +0,0 @@
-#
-# $FreeBSD$
-#
-
-PROG= mount_hpfs
-SRCS= mount_hpfs.c getmntopts.c
-MAN= mount_hpfs.8
-
-MOUNT= ${.CURDIR}/../mount
-CFLAGS+= -I${MOUNT} -DHPFS
-
-.PATH: ${MOUNT}
-
-.include <bsd.prog.mk>
diff --git a/sbin/mount_hpfs/mount_hpfs.8 b/sbin/mount_hpfs/mount_hpfs.8
deleted file mode 100644
index 81e3ea3..0000000
--- a/sbin/mount_hpfs/mount_hpfs.8
+++ /dev/null
@@ -1,100 +0,0 @@
-.\"
-.\" Copyright (c) 1993,1994 Christopher G. Demetriou
-.\" Copyright (c) 1999 Semen Ustimenko <semenu@FreeBSD.org>
-.\" All rights reserved.
-.\"
-.\" Redistribution and use in source and binary forms, with or without
-.\" modification, are permitted provided that the following conditions
-.\" are met:
-.\" 1. Redistributions of source code must retain the above copyright
-.\" notice, this list of conditions and the following disclaimer.
-.\" 2. Redistributions in binary form must reproduce the above copyright
-.\" notice, this list of conditions and the following disclaimer in the
-.\" documentation and/or other materials provided with the distribution.
-.\" 3. All advertising materials mentioning features or use of this software
-.\" must display the following acknowledgment:
-.\" This product includes software developed by Christopher G. Demetriou.
-.\" 3. The name of the author may not be used to endorse or promote products
-.\" derived from this software without specific prior written permission
-.\"
-.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
-.\" IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
-.\" OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
-.\" IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
-.\" INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
-.\" NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-.\" DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-.\" THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-.\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
-.\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-.\"
-.\" $FreeBSD$
-.\"
-.Dd May 20, 1999
-.Dt MOUNT_HPFS 8
-.Os
-.Sh NAME
-.Nm mount_hpfs
-.Nd mount an HPFS file system
-.Sh SYNOPSIS
-.Nm
-.Op Fl o Ar options
-.Op Fl u Ar uid
-.Op Fl g Ar gid
-.Op Fl m Ar mask
-.Pa special
-.Pa node
-.Sh DESCRIPTION
-The
-.Nm
-utility attaches the HPFS file system residing on the device
-.Pa special
-to the global file system namespace at the location
-indicated by
-.Pa node .
-This command is normally executed by
-.Xr mount 8
-at boot time, but can be used by any user to mount an
-HPFS file system on any directory that they own (provided,
-of course, that they have appropriate access to the device that
-contains the file system).
-.Pp
-The options are as follows:
-.Bl -tag -width Ds
-.It Fl u Ar uid
-Set the owner of the files in the file system to
-.Ar uid .
-The default owner is the owner of the directory
-on which the file system is being mounted.
-.It Fl g Ar gid
-Set the group of the files in the file system to
-.Ar gid .
-The default group is the group of the directory
-on which the file system is being mounted.
-.It Fl m Ar mask
-Specify the maximum file permissions for files
-in the file system.
-.El
-.Sh EXAMPLES
-To mount an hpfs volume located in /dev/wd1s1:
-.Bd -literal -offset indent
-# mount_hpfs /dev/wd1s1 /mnt
-.Ed
-.Sh WRITING
-There is limited writing ability and it is not well-tested.
-It is strongly recommended to mount readonly!
-.Sh SEE ALSO
-.Xr mount 2 ,
-.Xr unmount 2 ,
-.Xr fstab 5 ,
-.Xr mount 8
-.Sh HISTORY
-The
-.Nm
-utility first appeared in
-.Fx 3.0 .
-.Sh AUTHORS
-HPFS kernel implementation,
-.Nm
-and manual were written by
-.An Semen Ustimenko Aq semenu@FreeBSD.org .
diff --git a/sbin/mount_hpfs/mount_hpfs.c b/sbin/mount_hpfs/mount_hpfs.c
deleted file mode 100644
index 0106377..0000000
--- a/sbin/mount_hpfs/mount_hpfs.c
+++ /dev/null
@@ -1,244 +0,0 @@
-/*
- * Copyright (c) 1994 Christopher G. Demetriou
- * Copyright (c) 1999 Semen Ustimenko (semenu@FreeBSD.org)
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by Christopher G. Demetriou.
- * 4. The name of the author may not be used to endorse or promote products
- * derived from this software without specific prior written permission
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
- * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * $FreeBSD$
- */
-
-#include <sys/cdefs.h>
-#include <sys/param.h>
-#include <sys/mount.h>
-#include <sys/stat.h>
-#include <fs/hpfs/hpfsmount.h>
-#include <ctype.h>
-#include <err.h>
-#include <grp.h>
-#include <pwd.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <sysexits.h>
-#include <unistd.h>
-
-#include "mntopts.h"
-
-static struct mntopt mopts[] = {
- MOPT_STDOPTS,
- MOPT_END
-};
-
-static gid_t a_gid(char *);
-static uid_t a_uid(char *);
-static mode_t a_mask(char *);
-static void usage(void) __dead2;
-static void load_u2wtable(struct hpfs_args *, char *);
-
-int
-main(int argc, char *argv[])
-{
- struct hpfs_args args;
- struct stat sb;
- int c, mntflags, set_gid, set_uid, set_mask;
- int forcerw = 0;
- char *dev, *dir, ndir[MAXPATHLEN];
-
- mntflags = set_gid = set_uid = set_mask = 0;
- (void)memset(&args, '\0', sizeof(args));
-
- while ((c = getopt(argc, argv, "u:g:m:o:c:W:F")) != -1) {
- switch (c) {
- case 'F':
- forcerw=1;
- break;
- case 'u':
- args.uid = a_uid(optarg);
- set_uid = 1;
- break;
- case 'g':
- args.gid = a_gid(optarg);
- set_gid = 1;
- break;
- case 'm':
- args.mode = a_mask(optarg);
- set_mask = 1;
- break;
- case 'o':
- getmntopts(optarg, mopts, &mntflags, 0);
- break;
- case 'W':
- load_u2wtable(&args, optarg);
- args.flags |= HPFSMNT_TABLES;
- break;
- case '?':
- default:
- usage();
- break;
- }
- }
-
- if (optind + 2 != argc)
- usage();
-
- if (!(mntflags & MNT_RDONLY) && !forcerw) {
- warnx("Write support is BETA, you need -F flag to enable RW mount!");
- exit (111);
- }
-
- dev = argv[optind];
- dir = argv[optind + 1];
- if (dir[0] != '/') {
- warnx("\"%s\" is a relative path", dir);
- if (getcwd(ndir, sizeof(ndir)) == NULL)
- err(EX_OSERR, "getcwd");
- strncat(ndir, "/", sizeof(ndir) - strlen(ndir) - 1);
- strncat(ndir, dir, sizeof(ndir) - strlen(ndir) - 1);
- dir = ndir;
- warnx("using \"%s\" instead", dir);
- }
-
- args.fspec = dev;
- args.export.ex_root = 65534; /* unchecked anyway on DOS fs */
- if (mntflags & MNT_RDONLY)
- args.export.ex_flags = MNT_EXRDONLY;
- else
- args.export.ex_flags = 0;
-
- if (!set_gid || !set_uid || !set_mask) {
- if (stat(dir, &sb) == -1)
- err(EX_OSERR, "stat %s", dir);
-
- if (!set_uid)
- args.uid = sb.st_uid;
- if (!set_gid)
- args.gid = sb.st_gid;
- if (!set_mask)
- args.mode = sb.st_mode & (S_IRWXU | S_IRWXG | S_IRWXO);
- }
-
- if (mount("hpfs", dir, mntflags, &args) < 0)
- err(EX_OSERR, "%s", dev);
-
- exit (0);
-}
-
-gid_t
-a_gid(char *s)
-{
- struct group *gr;
- char *gname;
- gid_t gid;
-
- if ((gr = getgrnam(s)) != NULL)
- gid = gr->gr_gid;
- else {
- for (gname = s; *s && isdigit(*s); ++s);
- if (!*s)
- gid = atoi(gname);
- else
- errx(EX_NOUSER, "unknown group id: %s", gname);
- }
- return (gid);
-}
-
-uid_t
-a_uid(char *s)
-{
- struct passwd *pw;
- char *uname;
- uid_t uid;
-
- if ((pw = getpwnam(s)) != NULL)
- uid = pw->pw_uid;
- else {
- for (uname = s; *s && isdigit(*s); ++s);
- if (!*s)
- uid = atoi(uname);
- else
- errx(EX_NOUSER, "unknown user id: %s", uname);
- }
- return (uid);
-}
-
-mode_t
-a_mask(char *s)
-{
- int done, rv=0;
- char *ep;
-
- done = 0;
- if (*s >= '0' && *s <= '7') {
- done = 1;
- rv = strtol(optarg, &ep, 8);
- }
- if (!done || rv < 0 || *ep)
- errx(EX_USAGE, "invalid file mode: %s", s);
- return (rv);
-}
-
-void
-usage(void)
-{
- fprintf(stderr, "usage: mount_hpfs [-u user] [-g group] [-m mask] bdev dir\n");
- exit(EX_USAGE);
-}
-
-void
-load_u2wtable (struct hpfs_args *pargs, char *name)
-{
- FILE *f;
- int i, code;
- char buf[128];
- char *fn;
-
- if (*name == '/')
- fn = name;
- else {
- snprintf(buf, sizeof(buf), "/usr/libdata/msdosfs/%s", name);
- buf[127] = '\0';
- fn = buf;
- }
- if ((f = fopen(fn, "r")) == NULL)
- err(EX_NOINPUT, "%s", fn);
- for (i = 0; i < 128; i++) {
- if (fscanf(f, "%i", &code) != 1)
- errx(EX_DATAERR, "u2w: missing item number %d", i);
- /* pargs->u2w[i] = code; */
- }
- for (i = 0; i < 128; i++) {
- if (fscanf(f, "%i", &code) != 1)
- errx(EX_DATAERR, "d2u: missing item number %d", i);
- pargs->d2u[i] = code;
- }
- for (i = 0; i < 128; i++) {
- if (fscanf(f, "%i", &code) != 1)
- errx(EX_DATAERR, "u2d: missing item number %d", i);
- pargs->u2d[i] = code;
- }
- fclose(f);
-}
diff --git a/sbin/mount_msdosfs/mount_msdosfs.c b/sbin/mount_msdosfs/mount_msdosfs.c
index 3da673d..8814fdd 100644
--- a/sbin/mount_msdosfs/mount_msdosfs.c
+++ b/sbin/mount_msdosfs/mount_msdosfs.c
@@ -69,7 +69,7 @@ main(int argc, char **argv)
struct iovec *iov = NULL;
int iovlen = 0;
struct stat sb;
- int c, mntflags, set_gid, set_uid, set_mask, set_dirmask;
+ int c, set_gid, set_uid, set_mask, set_dirmask;
char *dev, *dir, mntpath[MAXPATHLEN], *csp;
char fstype[] = "msdosfs";
char errmsg[255] = {0};
@@ -78,9 +78,8 @@ main(int argc, char **argv)
mode_t mask = 0, dirmask = 0;
uid_t uid = 0;
gid_t gid = 0;
- getmnt_silent = 1;
- mntflags = set_gid = set_uid = set_mask = set_dirmask = 0;
+ set_gid = set_uid = set_mask = set_dirmask = 0;
while ((c = getopt(argc, argv, "sl9u:g:m:M:o:L:D:W:")) != -1) {
switch (c) {
@@ -219,7 +218,7 @@ main(int argc, char **argv)
build_iovec_argf(&iov, &iovlen, "mask", "%u", mask);
build_iovec_argf(&iov, &iovlen, "dirmask", "%u", dirmask);
- if (nmount(iov, iovlen, mntflags) < 0) {
+ if (nmount(iov, iovlen, 0) < 0) {
if (errmsg[0])
err(1, "%s: %s", dev, errmsg);
else
diff --git a/sbin/mount_nfs/mount_nfs.c b/sbin/mount_nfs/mount_nfs.c
index d71e952..bd016f3 100644
--- a/sbin/mount_nfs/mount_nfs.c
+++ b/sbin/mount_nfs/mount_nfs.c
@@ -130,7 +130,7 @@ enum tryret {
TRYRET_LOCALERR /* Local failure. */
};
-static int fallback_mount(struct iovec *iov, int iovlen, int mntflags);
+static int fallback_mount(struct iovec *iov, int iovlen);
static int sec_name_to_num(char *sec);
static char *sec_num_to_name(int num);
static int getnfsargs(char *, struct iovec **iov, int *iovlen);
@@ -149,13 +149,12 @@ main(int argc, char *argv[])
{
int c;
struct iovec *iov;
- int mntflags, num, iovlen;
+ int num, iovlen;
int osversion;
char *name, *p, *spec, *fstype;
char mntpath[MAXPATHLEN], errmsg[255];
char hostname[MAXHOSTNAMELEN + 1], *gssname, gssn[MAXHOSTNAMELEN + 50];
- mntflags = 0;
iov = NULL;
iovlen = 0;
memset(errmsg, 0, sizeof(errmsg));
@@ -427,10 +426,10 @@ main(int argc, char *argv[])
*/
osversion = getosreldate();
if (osversion >= 702100) {
- if (nmount(iov, iovlen, mntflags))
+ if (nmount(iov, iovlen, 0))
err(1, "%s, %s", mntpath, errmsg);
} else {
- if (fallback_mount(iov, iovlen, mntflags))
+ if (fallback_mount(iov, iovlen))
err(1, "%s, %s", mntpath, errmsg);
}
@@ -473,7 +472,7 @@ copyopt(struct iovec **newiov, int *newiovlen,
* parameters. It should be eventually be removed.
*/
static int
-fallback_mount(struct iovec *iov, int iovlen, int mntflags)
+fallback_mount(struct iovec *iov, int iovlen)
{
struct nfs_args args = {
.version = NFS_ARGSVERSION,
@@ -663,7 +662,7 @@ fallback_mount(struct iovec *iov, int iovlen, int mntflags)
copyopt(&newiov, &newiovlen, iov, iovlen, "fspath");
copyopt(&newiov, &newiovlen, iov, iovlen, "errmsg");
- return nmount(newiov, newiovlen, mntflags);
+ return nmount(newiov, newiovlen, 0);
}
static int
diff --git a/sbin/mount_ntfs/Makefile b/sbin/mount_ntfs/Makefile
deleted file mode 100644
index 416f1ac..0000000
--- a/sbin/mount_ntfs/Makefile
+++ /dev/null
@@ -1,20 +0,0 @@
-#
-# $FreeBSD$
-#
-
-PROG= mount_ntfs
-SRCS= mount_ntfs.c getmntopts.c
-MAN= mount_ntfs.8
-DPADD= ${LIBKICONV}
-LDADD= -lkiconv
-
-MOUNT= ${.CURDIR}/../mount
-CFLAGS+= -I${MOUNT}
-
-# Needs to be dynamically linked for optional dlopen() access to
-# userland libiconv
-NO_SHARED?= NO
-
-.PATH: ${MOUNT}
-
-.include <bsd.prog.mk>
diff --git a/sbin/mount_ntfs/mount_ntfs.8 b/sbin/mount_ntfs/mount_ntfs.8
deleted file mode 100644
index eb8ba69..0000000
--- a/sbin/mount_ntfs/mount_ntfs.8
+++ /dev/null
@@ -1,173 +0,0 @@
-.\"
-.\" Copyright (c) 1993,1994 Christopher G. Demetriou
-.\" Copyright (c) 1999 Semen Ustimenko
-.\" All rights reserved.
-.\"
-.\" Redistribution and use in source and binary forms, with or without
-.\" modification, are permitted provided that the following conditions
-.\" are met:
-.\" 1. Redistributions of source code must retain the above copyright
-.\" notice, this list of conditions and the following disclaimer.
-.\" 2. Redistributions in binary form must reproduce the above copyright
-.\" notice, this list of conditions and the following disclaimer in the
-.\" documentation and/or other materials provided with the distribution.
-.\" 3. All advertising materials mentioning features or use of this software
-.\" must display the following acknowledgment:
-.\" This product includes software developed by Christopher G. Demetriou.
-.\" 3. The name of the author may not be used to endorse or promote products
-.\" derived from this software without specific prior written permission
-.\"
-.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
-.\" IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
-.\" OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
-.\" IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
-.\" INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
-.\" NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-.\" DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-.\" THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-.\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
-.\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-.\"
-.\" $FreeBSD$
-.\"
-.Dd November 17, 2007
-.Dt MOUNT_NTFS 8
-.Os
-.Sh NAME
-.Nm mount_ntfs
-.Nd mount an NTFS file system
-.Sh SYNOPSIS
-.Nm
-.Op Fl a
-.Op Fl i
-.Op Fl u Ar user
-.Op Fl g Ar group
-.Op Fl m Ar mask
-.Op Fl C Ar charset
-.Op Fl W Ar u2wtable
-.Pa special
-.Pa node
-.Sh DESCRIPTION
-The
-.Nm
-utility attaches the NTFS file system residing on the device
-.Pa special
-to the global file system namespace at the location
-indicated by
-.Pa node .
-This command is normally executed by
-.Xr mount 8
-at boot time, but can be used by any user to mount an
-NTFS file system on any directory that they own (provided,
-of course, that they have appropriate access to the device that
-contains the file system).
-.Pp
-The options are as follows:
-.Bl -tag -width Ds
-.It Fl a
-Force behaviour to return MS-DOS 8.3 names also on
-.Fn readdir .
-.It Fl i
-Make name lookup case insensitive for all names except POSIX names.
-.It Fl u Ar user
-Set the owner of the files in the file system to
-.Ar user .
-The default owner is the owner of the directory
-on which the file system is being mounted.
-.It Fl g Ar group
-Set the group of the files in the file system to
-.Ar group .
-The default group is the group of the directory
-on which the file system is being mounted.
-.It Fl m Ar mask
-Specify the maximum file permissions for files
-in the file system.
-Only the nine low-order bits of
-.Ar mask
-are used.
-.It Fl C Ar charset
-Specify local
-.Ar charset
-to convert Unicode file names.
-Currently only reading is supported, thus the file system is to be
-mounted read-only.
-.It Fl W Ar u2wtable
-Specify
-.Ux
-to
-.Tn Unicode
-translation table.
-See
-.Xr mount_msdosfs 8
-for the description of this option.
-.Bf Em
-This option is preserved for backward compatibility purpose only,
-and will be removed in the future.
-Please do not use this option.
-.Ef
-.El
-.Sh FEATURES
-NTFS file attributes are accessed in following way:
-.Bd -literal -offset indent
-foo[[:ATTRTYPE]:ATTRNAME]
-.Ed
-.Pp
-.Sq ATTRTYPE
-is one of the identifiers listed in $AttrDef file of
-volume.
-Default is $DATA.
-.Sq ATTRNAME
-is an attribute name.
-Default is none.
-.Sh EXAMPLES
-To mount an NTFS volume located in
-.Pa /dev/ad1s1 :
-.Pp
-.Dl "mount_ntfs /dev/ad1s1 /mnt"
-.Pp
-To get the volume name (in Unicode):
-.Pp
-.Dl "cat /mnt/\e$Volume:\e$VOLUME_NAME"
-.Pp
-To read directory raw data:
-.Pp
-.Dl "cat /mnt/foodir:\e$INDEX_ROOT:\e$I30"
-.Pp
-To mount a Japanese NTFS volume located in
-.Pa /dev/ad0s1 :
-.Pp
-.Dl "mount_ntfs -C eucJP /dev/ad0s1 /mnt"
-.Sh WRITING
-There is limited writing ability.
-Limitations: file must be nonresident
-and must not contain any sparces (uninitialized areas); compressed
-files are also not supported.
-The file name must not contain multibyte characters.
-.Sh SEE ALSO
-.Xr mount 2 ,
-.Xr unmount 2 ,
-.Xr fstab 5 ,
-.Xr mount 8 ,
-.Xr mount_msdosfs 8
-.Sh HISTORY
-The
-.Nm
-utility first appeared in
-.Fx 3.0 .
-.Pp
-The Unicode conversion routine was added by
-.An Ryuichiro Imura Aq imura@ryu16.org
-in 2003.
-.Sh AUTHORS
-The NTFS kernel implementation,
-.Nm
-utility, and manual were written by
-.An Semen Ustimenko Aq semenu@FreeBSD.org .
-.Sh CAVEATS
-This utility is primarily used for read access to an NTFS volume.
-See the
-.Sx WRITING
-section for details about writing to an NTFS volume.
-.Pp
-For a full read-write NTFS support consider sysutils/fusefs-ntfs
-port/package.
diff --git a/sbin/mount_ntfs/mount_ntfs.c b/sbin/mount_ntfs/mount_ntfs.c
deleted file mode 100644
index e46ac21..0000000
--- a/sbin/mount_ntfs/mount_ntfs.c
+++ /dev/null
@@ -1,280 +0,0 @@
-/*
- * Copyright (c) 1994 Christopher G. Demetriou
- * Copyright (c) 1999 Semen Ustimenko
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by Christopher G. Demetriou.
- * 4. The name of the author may not be used to endorse or promote products
- * derived from this software without specific prior written permission
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
- * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * $FreeBSD$
- *
- */
-
-#include <sys/cdefs.h>
-#include <sys/param.h>
-#define NTFS
-#include <sys/mount.h>
-#include <sys/stat.h>
-#include <sys/module.h>
-#include <sys/iconv.h>
-#include <sys/linker.h>
-#include <fs/ntfs/ntfsmount.h>
-#include <ctype.h>
-#include <err.h>
-#include <grp.h>
-#include <pwd.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <sysexits.h>
-#include <unistd.h>
-#include <libutil.h>
-
-#include "mntopts.h"
-
-#define TRANSITION_PERIOD_HACK
-
-static struct mntopt mopts[] = {
- MOPT_STDOPTS,
- MOPT_END
-};
-
-static gid_t a_gid(char *);
-static uid_t a_uid(char *);
-static mode_t a_mask(char *);
-static void usage(void) __dead2;
-
-static int set_charset(struct ntfs_args *);
-
-int
-main(int argc, char *argv[])
-{
- struct ntfs_args args;
- struct stat sb;
- int c, mntflags, set_gid, set_uid, set_mask;
- char *dev, *dir, mntpath[MAXPATHLEN];
-
- mntflags = set_gid = set_uid = set_mask = 0;
- (void)memset(&args, '\0', sizeof(args));
- args.cs_ntfs = NULL;
- args.cs_local = NULL;
-
-#ifdef TRANSITION_PERIOD_HACK
- while ((c = getopt(argc, argv, "aiu:g:m:o:C:W:")) != -1) {
-#else
- while ((c = getopt(argc, argv, "aiu:g:m:o:C:")) != -1) {
-#endif
- switch (c) {
- case 'u':
- args.uid = a_uid(optarg);
- set_uid = 1;
- break;
- case 'g':
- args.gid = a_gid(optarg);
- set_gid = 1;
- break;
- case 'm':
- args.mode = a_mask(optarg);
- set_mask = 1;
- break;
- case 'i':
- args.flag |= NTFS_MFLAG_CASEINS;
- break;
- case 'a':
- args.flag |= NTFS_MFLAG_ALLNAMES;
- break;
- case 'o':
- getmntopts(optarg, mopts, &mntflags, 0);
- break;
- case 'C':
- args.cs_local = malloc(ICONV_CSNMAXLEN);
- if (args.cs_local == NULL)
- err(EX_OSERR, "malloc()");
- strncpy(args.cs_local,
- kiconv_quirkcs(optarg, KICONV_VENDOR_MICSFT),
- ICONV_CSNMAXLEN);
- break;
-#ifdef TRANSITION_PERIOD_HACK
- case 'W':
- args.cs_local = malloc(ICONV_CSNMAXLEN);
- if (args.cs_local == NULL)
- err(EX_OSERR, "malloc()");
- if (strcmp(optarg, "iso22dos") == 0) {
- strcpy(args.cs_local, "ISO8859-2");
- } else if (strcmp(optarg, "iso72dos") == 0) {
- strcpy(args.cs_local, "ISO8859-7");
- } else if (strcmp(optarg, "koi2dos") == 0) {
- strcpy(args.cs_local, "KOI8-R");
- } else if (strcmp(optarg, "koi8u2dos") == 0) {
- strcpy(args.cs_local, "KOI8-U");
- } else {
- err(EX_NOINPUT, "%s", optarg);
- }
- break;
-#endif /* TRANSITION_PERIOD_HACK */
- case '?':
- default:
- usage();
- break;
- }
- }
-
- if (optind + 2 != argc)
- usage();
-
- dev = argv[optind];
- dir = argv[optind + 1];
-
- if (args.cs_local) {
- if (set_charset(&args) == -1)
- err(EX_OSERR, "ntfs_iconv");
- args.flag |= NTFS_MFLAG_KICONV;
- /*
- * XXX
- * Force to be MNT_RDONLY,
- * since only reading is supported right now,
- */
- mntflags |= MNT_RDONLY;
- }
-
- /*
- * Resolve the mountpoint with realpath(3) and remove unnecessary
- * slashes from the devicename if there are any.
- */
- if (checkpath(dir, mntpath) != 0)
- err(EX_USAGE, "%s", mntpath);
- (void)rmslashes(dev, dev);
-
- args.fspec = dev;
- args.export.ex_root = 65534; /* unchecked anyway on DOS fs */
- if (mntflags & MNT_RDONLY)
- args.export.ex_flags = MNT_EXRDONLY;
- else
- args.export.ex_flags = 0;
- if (!set_gid || !set_uid || !set_mask) {
- if (stat(mntpath, &sb) == -1)
- err(EX_OSERR, "stat %s", mntpath);
-
- if (!set_uid)
- args.uid = sb.st_uid;
- if (!set_gid)
- args.gid = sb.st_gid;
- if (!set_mask)
- args.mode = sb.st_mode & (S_IRWXU | S_IRWXG | S_IRWXO);
- }
-
- if (mount("ntfs", mntpath, mntflags, &args) < 0)
- err(EX_OSERR, "%s", dev);
-
- exit (0);
-}
-
-gid_t
-a_gid(char *s)
-{
- struct group *gr;
- char *gname;
- gid_t gid;
-
- if ((gr = getgrnam(s)) != NULL)
- gid = gr->gr_gid;
- else {
- for (gname = s; *s && isdigit(*s); ++s);
- if (!*s)
- gid = atoi(gname);
- else
- errx(EX_NOUSER, "unknown group id: %s", gname);
- }
- return (gid);
-}
-
-uid_t
-a_uid(char *s)
-{
- struct passwd *pw;
- char *uname;
- uid_t uid;
-
- if ((pw = getpwnam(s)) != NULL)
- uid = pw->pw_uid;
- else {
- for (uname = s; *s && isdigit(*s); ++s);
- if (!*s)
- uid = atoi(uname);
- else
- errx(EX_NOUSER, "unknown user id: %s", uname);
- }
- return (uid);
-}
-
-mode_t
-a_mask(char *s)
-{
- int done, rv=0;
- char *ep;
-
- done = 0;
- if (*s >= '0' && *s <= '7') {
- done = 1;
- rv = strtol(optarg, &ep, 8);
- }
- if (!done || rv < 0 || *ep)
- errx(EX_USAGE, "invalid file mode: %s", s);
- return (rv);
-}
-
-void
-usage(void)
-{
-#ifdef TRANSITION_PERIOD_HACK
- fprintf(stderr, "%s\n%s\n",
- "usage: mount_ntfs [-a] [-i] [-u user] [-g group] [-m mask]",
- " [-C charset] [-W u2wtable] special node");
-#else
- fprintf(stderr, "usage: mount_ntfs [-a] [-i] [-u user] [-g group] [-m mask] [-C charset] special node\n");
-#endif
- exit(EX_USAGE);
-}
-
-int
-set_charset(struct ntfs_args *pargs)
-{
- int error;
-
- if (modfind("ntfs_iconv") < 0)
- if (kldload("ntfs_iconv") < 0 || modfind("ntfs_iconv") < 0) {
- warnx( "cannot find or load \"ntfs_iconv\" kernel module");
- return (-1);
- }
-
- if ((pargs->cs_ntfs = malloc(ICONV_CSNMAXLEN)) == NULL)
- return (-1);
- strncpy(pargs->cs_ntfs, ENCODING_UNICODE, ICONV_CSNMAXLEN);
- error = kiconv_add_xlat16_cspairs(pargs->cs_ntfs, pargs->cs_local);
- if (error)
- return (-1);
-
- return (0);
-}
diff --git a/sbin/mount_nullfs/mount_nullfs.c b/sbin/mount_nullfs/mount_nullfs.c
index aaf66e5..e08599f 100644
--- a/sbin/mount_nullfs/mount_nullfs.c
+++ b/sbin/mount_nullfs/mount_nullfs.c
@@ -68,12 +68,11 @@ main(int argc, char *argv[])
char source[MAXPATHLEN];
char target[MAXPATHLEN];
char errmsg[255];
- int ch, mntflags, iovlen;
+ int ch, iovlen;
char nullfs[] = "nullfs";
iov = NULL;
iovlen = 0;
- mntflags = 0;
errmsg[0] = '\0';
while ((ch = getopt(argc, argv, "o:")) != -1)
switch(ch) {
@@ -111,7 +110,7 @@ main(int argc, char *argv[])
build_iovec(&iov, &iovlen, "fspath", source, (size_t)-1);
build_iovec(&iov, &iovlen, "target", target, (size_t)-1);
build_iovec(&iov, &iovlen, "errmsg", errmsg, sizeof(errmsg));
- if (nmount(iov, iovlen, mntflags) < 0) {
+ if (nmount(iov, iovlen, 0) < 0) {
if (errmsg[0] != 0)
err(1, "%s: %s", source, errmsg);
else
diff --git a/sbin/mount_reiserfs/Makefile b/sbin/mount_reiserfs/Makefile
deleted file mode 100644
index 686629f..0000000
--- a/sbin/mount_reiserfs/Makefile
+++ /dev/null
@@ -1,13 +0,0 @@
-# $FreeBSD$
-
-PROG = mount_reiserfs
-SRCS = mount_reiserfs.c getmntopts.c
-MAN = mount_reiserfs.8
-
-# mount_reiserfs needs mntopts.h and getmntopts.c from src/sbin/mount/
-MOUNT ?= ${.CURDIR}/../mount
-CFLAGS += -I${MOUNT}
-
-.PATH: ${MOUNT}
-
-.include <bsd.prog.mk>
diff --git a/sbin/mount_reiserfs/mount_reiserfs.8 b/sbin/mount_reiserfs/mount_reiserfs.8
deleted file mode 100644
index f246475..0000000
--- a/sbin/mount_reiserfs/mount_reiserfs.8
+++ /dev/null
@@ -1,90 +0,0 @@
-.\"
-.\" Copyright (c) 1993,1994 Christopher G. Demetriou
-.\" Copyright (c) 1999 Semen Ustimenko
-.\" Copyright (c) 2005 Jean-Sébastien Pédron
-.\" All rights reserved.
-.\"
-.\" Redistribution and use in source and binary forms, with or without
-.\" modification, are permitted provided that the following conditions
-.\" are met:
-.\" 1. Redistributions of source code must retain the above copyright
-.\" notice, this list of conditions and the following disclaimer.
-.\" 2. Redistributions in binary form must reproduce the above copyright
-.\" notice, this list of conditions and the following disclaimer in the
-.\" documentation and/or other materials provided with the distribution.
-.\" 3. All advertising materials mentioning features or use of this software
-.\" must display the following acknowledgment:
-.\" This product includes software developed by Christopher G. Demetriou.
-.\" 3. The name of the author may not be used to endorse or promote products
-.\" derived from this software without specific prior written permission
-.\"
-.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
-.\" IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
-.\" OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
-.\" IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
-.\" INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
-.\" NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-.\" DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-.\" THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-.\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
-.\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-.\"
-.\" $FreeBSD$
-.\"
-.Dd February 3, 2005
-.Dt MOUNT_REISERFS 8
-.Os
-.Sh NAME
-.Nm mount_reiserfs
-.Nd "mount a ReiserFS file system"
-.Sh SYNOPSIS
-.Nm
-.Ar special
-.Ar node
-.Sh DESCRIPTION
-The
-.Nm
-utility attaches the ReiserFS file system residing on the device
-.Ar special
-to the global file system namespace at the location
-indicated by
-.Ar node .
-.Pp
-This command is normally executed by
-.Xr mount 8
-at boot time, but can be used by any user to mount a
-ReiserFS file system on any directory that they own (provided,
-of course, that they have appropriate access to the device that
-contains the file system).
-.Sh EXAMPLES
-To mount a ReiserFS volume located in
-.Pa /dev/ad1s1 :
-.Pp
-.Dl "mount_reiserfs /dev/ad1s1 /mnt"
-.Sh SEE ALSO
-.Xr mount 2 ,
-.Xr unmount 2 ,
-.Xr fstab 5 ,
-.Xr mount 8
-.Sh HISTORY
-The
-.Nm
-utility first appeared in
-.Fx 6.0 .
-.Sh AUTHORS
-.An -nosplit
-The ReiserFS kernel implementation was written by
-.An Hans Reiser
-.Pq Pa http://www.namesys.com/ ,
-and ported to
-.Fx
-by
-.An Jean-S\['e]bastien P\['e]dron Aq dumbbell@FreeBSD.org .
-.Pp
-The
-.Nm
-utility and manual were written by
-.An Jean-S\['e]bastien P\['e]dron Aq dumbbell@FreeBSD.org .
-.Sh CAVEATS
-This utility is primarily used for read access to a ReiserFS volume.
-Writing to a volume is currently unsupported.
diff --git a/sbin/mount_reiserfs/mount_reiserfs.c b/sbin/mount_reiserfs/mount_reiserfs.c
deleted file mode 100644
index bf62526..0000000
--- a/sbin/mount_reiserfs/mount_reiserfs.c
+++ /dev/null
@@ -1,108 +0,0 @@
-/*-
- * Copyright (c) 2005 Jean-Sébastien Pédron
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * $FreeBSD$
- */
-
-#include <sys/param.h>
-#include <sys/mount.h>
-#include <sys/uio.h>
-
-#include <err.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <sysexits.h>
-#include <unistd.h>
-
-#include "mntopts.h"
-
-struct mntopt mopts[] = {
- MOPT_STDOPTS,
- MOPT_END
-};
-
-void usage(void);
-
-int
-main(int argc, char *argv[])
-{
- struct iovec *iov;
- int ch, mntflags, iovlen;
- char *dev, *dir, mntpath[MAXPATHLEN];
- char fstype[] = "reiserfs";
-
- mntflags = 0;
- while ((ch = getopt(argc, argv, "o:")) != -1) {
- switch(ch) {
- case 'o':
- getmntopts(optarg, mopts, &mntflags, 0);
- break;
- case '?':
- default:
- usage();
- }
- }
- argc -= optind;
- argv += optind;
-
- if (argc != 2)
- usage();
-
- dev = argv[0];
- dir = argv[1];
-
- /*
- * Resolve the mountpoint with realpath(3) and remove unnecessary
- * slashes from the devicename if there are any.
- */
- if (checkpath(dir, mntpath) != 0)
- err(EX_USAGE, "%s", mntpath);
- (void)rmslashes(dev, dev);
-
- /* Read-only support for now */
- mntflags |= MNT_RDONLY;
-
- /* Prepare the options vector for nmount(). build_iovec() is declared
- * in mntopts.h. */
- iov = NULL;
- iovlen = 0;
- build_iovec(&iov, &iovlen, "fstype", fstype, (size_t)-1);
- build_iovec(&iov, &iovlen, "fspath", mntpath, (size_t)-1);
- build_iovec(&iov, &iovlen, "from", dev, (size_t)-1);
-
- if (nmount(iov, iovlen, mntflags) < 0)
- err(EX_OSERR, "%s", dev);
-
- exit(0);
-}
-
-void
-usage(void)
-{
- fprintf(stderr,
- "usage: mount_reiserfs [-o options] special node\n");
- exit(EX_USAGE);
-}
diff --git a/sbin/mount_std/Makefile b/sbin/mount_std/Makefile
deleted file mode 100644
index 44ff9ef..0000000
--- a/sbin/mount_std/Makefile
+++ /dev/null
@@ -1,23 +0,0 @@
-# @(#)Makefile 8.2 (Berkeley) 3/27/94
-# $FreeBSD$
-
-PROG= mount_std
-SRCS= mount_std.c getmntopts.c
-MAN= mount_std.8
-MLINKS= mount_std.8 mount_devfs.8 \
- mount_std.8 mount_fdescfs.8 \
- mount_std.8 mount_linprocfs.8 \
- mount_std.8 mount_procfs.8
-
-MOUNT= ${.CURDIR}/../mount
-CFLAGS+= -I${MOUNT}
-WARNS?= 3
-
-.PATH: ${MOUNT}
-
-LINKS= ${BINDIR}/mount_std ${BINDIR}/mount_devfs \
- ${BINDIR}/mount_std ${BINDIR}/mount_fdescfs \
- ${BINDIR}/mount_std ${BINDIR}/mount_linprocfs \
- ${BINDIR}/mount_std ${BINDIR}/mount_procfs
-
-.include <bsd.prog.mk>
diff --git a/sbin/mount_std/mount_std.8 b/sbin/mount_std/mount_std.8
deleted file mode 100644
index 0aeeba8..0000000
--- a/sbin/mount_std/mount_std.8
+++ /dev/null
@@ -1,167 +0,0 @@
-.\"
-.\" Copyright (c) 1992, 1993, 1994
-.\" The Regents of the University of California. All rights reserved.
-.\" All rights reserved.
-.\"
-.\" This code is derived from software donated to Berkeley by
-.\" Jan-Simon Pendry.
-.\"
-.\" Redistribution and use in source and binary forms, with or without
-.\" modification, are permitted provided that the following conditions
-.\" are met:
-.\" 1. Redistributions of source code must retain the above copyright
-.\" notice, this list of conditions and the following disclaimer.
-.\" 2. Redistributions in binary form must reproduce the above copyright
-.\" notice, this list of conditions and the following disclaimer in the
-.\" documentation and/or other materials provided with the distribution.
-.\" 4. Neither the name of the University nor the names of its contributors
-.\" may be used to endorse or promote products derived from this software
-.\" without specific prior written permission.
-.\"
-.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
-.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
-.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
-.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
-.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
-.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
-.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
-.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
-.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
-.\" SUCH DAMAGE.
-.\"
-.\" $FreeBSD$
-.\"
-.Dd November 26, 2004
-.Dt MOUNT_STD 8
-.Os
-.Sh NAME
-.Nm mount_std ,
-.Nm mount_devfs ,
-.Nm mount_fdescfs ,
-.Nm mount_linprocfs ,
-.Nm mount_procfs
-.Nd mount
-.Dq standard
-file systems
-.Sh SYNOPSIS
-.Nm mount_ Ns Ar fsname
-.Op Fl o Ar options
-.Ar "fs"
-.Ar mount_point
-.Sh DESCRIPTION
-The
-.Nm
-utility is a generic mechanism for attaching ``standard'' file systems to
-the file system.
-The
-.Nm
-utility currently supports the following file systems:
-.Nm devfs ,
-.Nm fdescfs ,
-.Nm linprocfs
-and
-.Nm procfs .
-A ``standard'' file system is one which:
-.Bl -enum -offset indent
-.It
-accepts only the standard
-.Fl o
-options
-.Dq ro ,
-.Dq rw ,
-.Dq noexec ,
-.Dq nosuid ,
-and
-.Dq union .
-.It
-has a kernel file system module name the same as its user-visible name.
-.It
-requires no other special processing on the part of the
-.Nm
-utility.
-.El
-.Pp
-The options are as follows:
-.Bl -tag -width indent
-.It Fl o
-Options are specified with a
-.Fl o
-flag followed by a comma separated string of options.
-See the
-.Xr mount 8
-man page for possible options and their meanings.
-.El
-.Pp
-The
-.Nm
-utility examines its zeroth command-line argument (the name by which
-it was called) to determine the type of file system to be mounted.
-If
-it is called by a name which does not end in
-.Dq Li _ Ns Ar fsname ,
-.Nm
-will assume (for compatibility
-with
-.Xr mount 8 )
-that the zeroth argument contains only the name of the file system type.
-The
-.Nm
-utility is normally installed with appropriate links to commands for
-the distributed file systems which can be mounted in this way;
-for information on the function of each file system, see the manual page
-for that specific
-.Nm mount_ Ns Ar fsname
-utility.
-.Pp
-Refer to the following manual pages for detailed information
-on these file systems:
-.Xr devfs 5 ,
-.Xr fdescfs 5 ,
-.Xr linprocfs 5
-and
-.Xr procfs 5 .
-.Sh DIAGNOSTICS
-.Bl -diag
-.It argv[0] must end in _fsname
-The
-.Nm
-utility was called with a zeroth argument of
-.Dq Li mount_std .
-.It %s file system not available
-The specified file system type was not present in the kernel and no
-loadable module for it was found.
-.El
-.Sh SEE ALSO
-.Xr mount 2 ,
-.Xr unmount 2 ,
-.Xr getvfsbyname 3 ,
-.Xr devfs 5 ,
-.Xr fdescfs 5 ,
-.Xr fstab 5 ,
-.Xr linprocfs 5 ,
-.Xr procfs 5 ,
-.Xr mount 8
-.Sh HISTORY
-The
-.Nm
-utility first appeared in
-.Fx 2.2 .
-Loadable file system modules first appeared in
-.Fx 2.0 .
-The
-.Dq fdescfs
-and
-.Dq procfs
-file system types first appeared in
-.Fx 2.0 ;
-the
-.Dq devfs
-file system type first appeared in
-.Fx 2.2 ;
-the
-.Dq linprocfs
-file system type first appeared in
-.Fx 4.0 .
-.Sh CAVEATS
-None of the ``standard'' file systems may be NFS-exported.
diff --git a/sbin/mount_std/mount_std.c b/sbin/mount_std/mount_std.c
deleted file mode 100644
index c7f1643..0000000
--- a/sbin/mount_std/mount_std.c
+++ /dev/null
@@ -1,160 +0,0 @@
-/*
- * Copyright (c) 1990, 1992 Jan-Simon Pendry
- * Copyright (c) 1992, 1993, 1994
- * The Regents of the University of California. All rights reserved.
- *
- * This code is derived from software contributed to Berkeley by
- * Jan-Simon Pendry.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-#ifndef lint
-static const char copyright[] =
-"@(#) Copyright (c) 1992, 1993, 1994\n\
- The Regents of the University of California. All rights reserved.\n";
-#endif /* not lint */
-
-#include <sys/cdefs.h>
-__FBSDID("$FreeBSD$");
-
-#include <sys/param.h>
-#include <sys/mount.h>
-#include <sys/uio.h>
-
-#include <err.h>
-#include <errno.h>
-#include <stdio.h>
-#include <signal.h>
-#include <stdlib.h>
-#include <string.h>
-#include <sysexits.h>
-#include <unistd.h>
-
-#include "mntopts.h"
-
-static struct mntopt mopts[] = {
- MOPT_STDOPTS,
- MOPT_END
-};
-
-static char *fsname;
-static volatile sig_atomic_t caughtsig;
-
-static void usage(void) __dead2;
-
-static void
-catchsig(int s __unused)
-{
- caughtsig = 1;
-}
-
-int
-main(int argc, char *argv[])
-{
- int ch, mntflags;
- char mntpath[MAXPATHLEN];
- struct iovec iov[4];
- int error;
-
- /*
- * XXX
- * mount(8) calls the mount programs with an argv[0] which is
- * /just/ the file system name. So, if there is no underscore
- * in argv[0], we assume that we are being called from mount(8)
- * and that argv[0] is thus the name of the file system type.
- */
- fsname = strrchr(argv[0], '_');
- if (fsname) {
- if (strcmp(fsname, "_std") == 0)
- errx(EX_USAGE, "argv[0] must end in _fsname");
- fsname++;
- } else {
- fsname = argv[0];
- }
-
- mntflags = 0;
- while ((ch = getopt(argc, argv, "o:")) != -1)
- switch (ch) {
- case 'o':
- getmntopts(optarg, mopts, &mntflags, 0);
- break;
- case '?':
- default:
- usage();
- }
- argc -= optind;
- argv += optind;
-
- if (argc != 2)
- usage();
-
- /* resolve the mountpoint with realpath(3) */
- if (checkpath(argv[1], mntpath) != 0)
- err(EX_USAGE, "%s", mntpath);
-
- iov[0].iov_base = "fstype";
- iov[0].iov_len = sizeof("fstype");
- iov[1].iov_base = fsname;
- iov[1].iov_len = strlen(iov[1].iov_base) + 1;
- iov[2].iov_base = "fspath";
- iov[2].iov_len = sizeof("fspath");
- iov[3].iov_base = mntpath;
- iov[3].iov_len = strlen(mntpath) + 1;
-
- /*
- * nmount(2) would kill us with SIGSYS if the kernel doesn't have it.
- * This design bug is inconvenient. We must catch the signal and not
- * just ignore it because of a plain bug: nmount(2) would return
- * EINVAL instead of the correct ENOSYS if the kernel doesn't have it
- * and we don't let the signal kill us. EINVAL is too ambiguous.
- * This bug in 4.4BSD-Lite1 was fixed in 4.4BSD-Lite2 but is still in
- * FreeBSD-5.0.
- */
- signal(SIGSYS, catchsig);
- error = nmount(iov, 4, mntflags);
- signal(SIGSYS, SIG_DFL);
-
- /*
- * Try with the old mount syscall in the case
- * this file system has not been converted yet,
- * or the user didn't recompile his kernel.
- */
- if (error && (errno == EOPNOTSUPP || errno == ENOSYS || caughtsig))
- error = mount(fsname, mntpath, mntflags, NULL);
-
- if (error)
- err(EX_OSERR, NULL);
- exit(0);
-}
-
-void
-usage(void)
-{
- (void)fprintf(stderr,
- "usage: mount_%s [-o options] what_to_mount mount_point\n",
- fsname);
- exit(EX_USAGE);
-}
diff --git a/sbin/mount_udf/Makefile b/sbin/mount_udf/Makefile
index c5351fd..06ad9a7 100644
--- a/sbin/mount_udf/Makefile
+++ b/sbin/mount_udf/Makefile
@@ -9,7 +9,6 @@ LDADD= -lkiconv
MOUNT= ${.CURDIR}/../mount
CFLAGS+= -I${MOUNT} -I${.CURDIR}/../../sys
.PATH: ${MOUNT}
-WARNS?= 1
# Needs to be dynamically linked for optional dlopen() access to
# userland libiconv
diff --git a/sbin/mount_udf/mount_udf.c b/sbin/mount_udf/mount_udf.c
index 8ee1286..01fa44f 100644
--- a/sbin/mount_udf/mount_udf.c
+++ b/sbin/mount_udf/mount_udf.c
@@ -73,18 +73,19 @@ void usage(void);
int
main(int argc, char **argv)
{
- struct iovec iov[12];
- int ch, i, mntflags, opts, udf_flags;
- char *dev, *dir, mntpath[MAXPATHLEN];
- char *cs_disk, *cs_local;
- int verbose;
+ char mntpath[MAXPATHLEN];
+ char fstype[] = "udf";
+ struct iovec *iov;
+ char *cs_disk, *cs_local, *dev, *dir;
+ int ch, i, iovlen, mntflags, udf_flags, verbose;
- i = mntflags = opts = udf_flags = verbose = 0;
+ i = iovlen = mntflags = udf_flags = verbose = 0;
cs_disk = cs_local = NULL;
+ iov = NULL;
while ((ch = getopt(argc, argv, "o:vC:")) != -1)
switch (ch) {
case 'o':
- getmntopts(optarg, mopts, &mntflags, &opts);
+ getmntopts(optarg, mopts, &mntflags, NULL);
break;
case 'v':
verbose++;
@@ -120,32 +121,13 @@ main(int argc, char **argv)
*/
mntflags |= MNT_RDONLY;
- iov[i].iov_base = "fstype";
- iov[i++].iov_len = sizeof("fstype");
- iov[i].iov_base = "udf";
- iov[i].iov_len = strlen(iov[i].iov_base) + 1;
- i++;
- iov[i].iov_base = "fspath";
- iov[i++].iov_len = sizeof("fspath");
- iov[i].iov_base = mntpath;
- iov[i++].iov_len = strlen(mntpath) + 1;
- iov[i].iov_base = "from";
- iov[i++].iov_len = sizeof("from");
- iov[i].iov_base = dev;
- iov[i++].iov_len = strlen(dev) + 1;
- iov[i].iov_base = "flags";
- iov[i++].iov_len = sizeof("flags");
- iov[i].iov_base = &udf_flags;
- iov[i++].iov_len = sizeof(udf_flags);
+ build_iovec(&iov, &iovlen, "fstype", fstype, (size_t)-1);
+ build_iovec(&iov, &iovlen, "fspath", mntpath, (size_t)-1);
+ build_iovec(&iov, &iovlen, "from", dev, (size_t)-1);
+ build_iovec(&iov, &iovlen, "flags", &udf_flags, sizeof(udf_flags));
if (udf_flags & UDFMNT_KICONV) {
- iov[i].iov_base = "cs_disk";
- iov[i++].iov_len = sizeof("cs_disk");
- iov[i].iov_base = cs_disk;
- iov[i++].iov_len = strlen(cs_disk) + 1;
- iov[i].iov_base = "cs_local";
- iov[i++].iov_len = sizeof("cs_local");
- iov[i].iov_base = cs_local;
- iov[i++].iov_len = strlen(cs_local) + 1;
+ build_iovec(&iov, &iovlen, "cs_disk", cs_disk, (size_t)-1);
+ build_iovec(&iov, &iovlen, "cs_local", cs_local, (size_t)-1);
}
if (nmount(iov, i, mntflags) < 0)
err(1, "%s", dev);
diff --git a/sbin/mount_unionfs/mount_unionfs.c b/sbin/mount_unionfs/mount_unionfs.c
index c42bf04..1026ecf 100644
--- a/sbin/mount_unionfs/mount_unionfs.c
+++ b/sbin/mount_unionfs/mount_unionfs.c
@@ -129,7 +129,7 @@ int
main(int argc, char *argv[])
{
struct iovec *iov;
- int ch, mntflags, iovlen;
+ int ch, iovlen;
char source [MAXPATHLEN], target[MAXPATHLEN], errmsg[255];
char uid_str[20], gid_str[20];
char fstype[] = "unionfs";
@@ -137,7 +137,6 @@ main(int argc, char *argv[])
iov = NULL;
iovlen = 0;
- mntflags = 0;
memset(errmsg, 0, sizeof(errmsg));
while ((ch = getopt(argc, argv, "bo:")) != -1) {
@@ -190,7 +189,7 @@ main(int argc, char *argv[])
build_iovec(&iov, &iovlen, "from", target, (size_t)-1);
build_iovec(&iov, &iovlen, "errmsg", errmsg, sizeof(errmsg));
- if (nmount(iov, iovlen, mntflags))
+ if (nmount(iov, iovlen, 0))
err(EX_OSERR, "%s: %s", source, errmsg);
exit(0);
}
diff --git a/share/examples/portal/README b/share/examples/portal/README
deleted file mode 100644
index d8dc1fc..0000000
--- a/share/examples/portal/README
+++ /dev/null
@@ -1,65 +0,0 @@
-$FreeBSD$
-
-This contains a couple of examples for using the portal filing system.
-
-The portal file system provides a way of obtaining a file descriptor
-to a filesystem object (i.e. something that is accessed by open(2),
-pipe(2), socket(2) or socketpair(2)) via the filesystem namespace.
-At present the only file descriptor supported are TCP sockets and
-files.
-
-NOTE!!!! The portal file system is experimental in nature and should
-not be considered secure, use with caution.
-
-First off mount the filesystem using something like:
-
-# mount_portalfs /usr/share/examples/portal/portal.conf /p
-
-Then you should be able to do things like
-# cat /p/tcp/localhost/daytime
-Sun Nov 22 17:50:09 1998
-(assuming inetd is running the daytime service, by default it is off)
-
-Welcome to FreeBSD!
-
-# mkdir -p /tmp/root
-# cd /tmp/root
-# mkdir bin p
-# cp /bin/sh /bin/cat bin
-# mount_portalfs /usr/share/examples/portal/portal.conf /tmp/root/p
-# chroot /tmp/root
-# pwd
-/
-# echo *
-bin p
-# cat /etc/motd
-cat: /etc/motd: No such file or directory
-# cat /p/fs/etc/motd
-FreeBSD 2.2.6-RELEASE (COMPUTER) #0: Sat Aug 22 17:11:37 BST 1998
-
-Welcome to FreeBSD!
-
-Finally, a very simple example of the listening server is available,
-fire up two xterms. In the first
-
-xterm-1$ cat /p/tcplisten/ANY/6666
-(the ANY is a wildcard just like using INADDR_ANY, any resolvable host
-can be used).
-
-In the second xterm
-xterm-2$ echo "hello there" >/p/tcp/localhost/6666
-
-You should see the "hello there" string appear on the first terminal.
-
-Unprivilged users can't create servers on privalged ports.
-xterm-1$ cat /p/tcplisten/ANY/666
-cat: /p/tcplisten/ANY/666: Operation not permitted
-
-but root can
-xterm-1# cat /p/tcplisten/ANY/666
-
-In the second
-xterm-2$ echo "hello there" >/p/tcp/localhost/666
-should produce the expected response.
-
-You can also swap the client/server read and write commands etc.
diff --git a/share/examples/portal/portal.conf b/share/examples/portal/portal.conf
deleted file mode 100644
index aa7e282..0000000
--- a/share/examples/portal/portal.conf
+++ /dev/null
@@ -1,3 +0,0 @@
-tcp/ tcp tcp/
-tcplisten/ tcplisten tcplisten/
-fs/ file fs/
diff --git a/share/man/man4/coda.4 b/share/man/man4/coda.4
deleted file mode 100644
index e1799ef..0000000
--- a/share/man/man4/coda.4
+++ /dev/null
@@ -1,82 +0,0 @@
-.\" Copyright (c) 2008 Robert N. M. Watson
-.\" All rights reserved.
-.\"
-.\" Redistribution and use in source and binary forms, with or without
-.\" modification, are permitted provided that the following conditions
-.\" are met:
-.\" 1. Redistributions of source code must retain the above copyright
-.\" notice, this list of conditions and the following disclaimer.
-.\" 2. Redistributions in binary form must reproduce the above copyright
-.\" notice, this list of conditions and the following disclaimer in the
-.\" documentation and/or other materials provided with the distribution.
-.\"
-.\" THIS SOFTWARE IS PROVIDED BY THE AUTHORS AND CONTRIBUTORS ``AS IS'' AND
-.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
-.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE
-.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
-.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
-.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
-.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
-.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
-.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
-.\" SUCH DAMAGE.
-.\"
-.\" $FreeBSD$
-.\"
-.Dd January 21, 2008
-.Dt CODA 4
-.Os
-.Sh NAME
-.Nm coda
-.Nd Coda Distributed File System
-.Sh SYNOPSIS
-To compile this driver into the kernel,
-place the following lines in your
-kernel configuration file:
-.Bd -ragged -offset indent
-.Cd "options CODA"
-.Ed
-.Pp
-Alternatively, to load the driver as a
-module at boot time, place the following line in
-.Xr loader.conf 5 :
-.Bd -literal -offset indent
-coda_load="YES"
-.Ed
-.Pp
-To load as a kernel loadable module after boot:
-.Pp
-.Dl "kldload coda"
-.Sh DESCRIPTION
-The
-.Nm
-kernel module allows the experimental, third-party Coda distributed file
-system client to be used with
-.Fx .
-The module allows the userspace Coda client daemon, Venus, to present the
-Coda distributed file system namespace via the local
-.Pa /coda
-file system mountpoint via the
-.Pa /dev/cfs0
-special device.
-.Pp
-To use Coda, the Coda client software package must also be installed; more
-information on Coda may be found in the Coda documentation distributed with
-that package.
-.Sh SEE ALSO
-.Xr loader.conf 5 ,
-.Xr kldload 8
-.Sh HISTORY
-Support for
-.Nm
-first appeared in
-.Fx 3.0 .
-.Sh AUTHORS
-This manual page was written by
-.An Robert Watson Aq rwatson@FreeBSD.org .
-.Sh BUGS
-The
-Coda distributed file system is considered experimental, and production
-deployment should occur only after careful consideration of the risks of
-deploying experimental software.
diff --git a/share/man/man4/eventtimers.4 b/share/man/man4/eventtimers.4
index 4db4420..656c8e0 100644
--- a/share/man/man4/eventtimers.4
+++ b/share/man/man4/eventtimers.4
@@ -143,14 +143,6 @@ By default this options is disabled.
If chosen timer is per-CPU
and runs in periodic mode, this option has no effect - all interrupts are
always generating.
-.It Va kern.eventtimer.activetick
-makes each CPU to receive all kinds of timer interrupts when they are busy.
-Disabling it allows to skip some
-.Fn hardclock
-calls in some cases.
-By default this options is enabled.
-If chosen timer is per-CPU, this option has no effect - all interrupts are
-always generating, as timer reprogramming is too expensive for that case.
.El
.Sh SEE ALSO
.Xr apic 4 ,
diff --git a/share/man/man4/mvs.4 b/share/man/man4/mvs.4
index 5c8d8cc..be8c3ea 100644
--- a/share/man/man4/mvs.4
+++ b/share/man/man4/mvs.4
@@ -24,7 +24,7 @@
.\"
.\" $FreeBSD$
.\"
-.Dd April 27, 2010
+.Dd March 3, 2013
.Dt MVS 4
.Os
.Sh NAME
@@ -62,7 +62,7 @@ command latency.
.It Va hint.mvs. Ns Ar X Ns Va .cccc
defines number of completed commands for CCC, which trigger interrupt without
waiting for specified coalescing timeout.
-.It Va hint.mvs. Ns Ar X Ns Va .pm_level
+.It Va hint.mvsch. Ns Ar X Ns Va .pm_level
controls SATA interface Power Management for the specified channel,
allowing some power to be saved at the cost of additional command
latency.
@@ -82,7 +82,7 @@ driver initiates SLUMBER PM state transition 125ms after port becomes idle.
Note that interface Power Management is not compatible with
device presence detection.
A manual bus reset is needed on device hot-plug.
-.It Va hint.mvs. Ns Ar X Ns Va .sata_rev
+.It Va hint.mvsch. Ns Ar X Ns Va .sata_rev
setting to nonzero value limits maximum SATA revision (speed).
Values 1, 2 and 3 are respectively 1.5, 3 and 6Gbps.
.El
diff --git a/share/man/man4/zyd.4 b/share/man/man4/zyd.4
index ba8f573..5a1f0a5 100644
--- a/share/man/man4/zyd.4
+++ b/share/man/man4/zyd.4
@@ -32,7 +32,7 @@
.\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
.\" THE POSSIBILITY OF SUCH DAMAGE.
.\"
-.Dd October 2, 2009
+.Dd March 7, 2013
.Dt ZYD 4
.Os
.Sh NAME
@@ -121,6 +121,7 @@ driver:
.It X-Micro XWL-11GUZX
.It Yakumo QuickWLAN USB
.It Zonet ZEW2501
+.It ZyXEL ZyAIR G-202
.It ZyXEL ZyAIR G-220
.El
.Sh EXAMPLES
diff --git a/share/man/man5/xfs.5 b/share/man/man5/xfs.5
deleted file mode 100644
index 67504aa..0000000
--- a/share/man/man5/xfs.5
+++ /dev/null
@@ -1,108 +0,0 @@
-.\"
-.\" Copyright (c) 2007 Craig Rodrigues
-.\" All rights reserved.
-.\"
-.\" Redistribution and use in source and binary forms, with or without
-.\" modification, are permitted provided that the following conditions
-.\" are met:
-.\" 1. Redistributions of source code must retain the above copyright
-.\" notice, this list of conditions and the following disclaimer.
-.\" 2. Redistributions in binary form must reproduce the above copyright
-.\" notice, this list of conditions and the following disclaimer in the
-.\" documentation and/or other materials provided with the distribution.
-.\"
-.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
-.\" IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
-.\" OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
-.\" IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
-.\" INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
-.\" NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-.\" DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-.\" THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-.\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
-.\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-.\"
-.\" $FreeBSD$
-.\"
-.Dd January 16, 2011
-.Dt XFS 5
-.Os
-.Sh NAME
-.Nm xfs
-.Nd "XFS file system"
-.Sh SYNOPSIS
-To link into the kernel:
-.Bd -ragged -offset indent
-.Cd "options XFS"
-.Ed
-.Pp
-To load as a kernel loadable module:
-.Pp
-.Dl "kldload xfs"
-.Sh DESCRIPTION
-The
-.Nm
-driver will permit the
-.Fx
-kernel to access
-.Tn XFS
-file systems.
-.Sh EXAMPLES
-To mount a
-.Nm
-volume located on
-.Pa /dev/ad1s1 :
-.Pp
-.Dl "mount -t xfs -o ro /dev/ad1s1 /mnt"
-.Sh SEE ALSO
-.Xr nmount 2 ,
-.Xr unmount 2 ,
-.Xr fstab 5 ,
-.Xr mount 8
-.Sh NOTES
-The
-.Pa sysutils/xfsprogs
-port contains the
-.Cm mkfs.xfs
-utility for
-creating XFS file systems, and also other utilities for analyzing,
-and repairing XFS file systems.
-.Sh HISTORY
-XFS was originally written by SGI for the IRIX operating system.
-SGI ported XFS to Linux, and released the source code under the GNU
-Public License. For more details, see:
-.Pa http://oss.sgi.com/projects/xfs
-.Pp
-The port to
-.Fx
-was based on the Linux port, and started by
-.An -nosplit
-.An Russell Cattelan Aq cattelan@xfs.org ,
-.An Alexander Kabaev Aq kan@FreeBSD.org ,
-and
-.An Craig Rodrigues Aq rodrigc@FreeBSD.org .
-.Pp
-The
-.Nm
-file system support
-first appeared in
-.Fx 7.0 .
-.Sh AUTHORS
-This manual page was written by
-.An Craig Rodrigues Aq rodrigc@FreeBSD.org .
-.Sh CAVEATS
-The port of XFS to
-.Fx
-is currently incomplete.
-Only read-only access is supported for XFS volumes.
-Writing to a volume is not supported.
-.Pp
-The
-.Fl p
-flag to
-.Cm mkfs.xfs
-can be used to create an XFS file system which is populated with files
-and other metadata.
-This can be used to quickly create a read-only file system which
-can be tested on
-.Fx .
diff --git a/share/man/man7/development.7 b/share/man/man7/development.7
index 3da1858..58e6892 100644
--- a/share/man/man7/development.7
+++ b/share/man/man7/development.7
@@ -23,7 +23,7 @@
.\"
.\" $FreeBSD$
.\"
-.Dd September 19, 2012
+.Dd March 7, 2013
.Dt DEVELOPMENT 7
.Os
.Sh NAME
@@ -109,9 +109,9 @@ your clients automatically pick up the changes.
.Bd -literal -offset 4n
mkdir /FreeBSD
cd /FreeBSD
-svn co svn://svn.freebsd.org/ports/head ports
-svn co svn://svn.freebsd.org/doc/head doc
-svn co svn://svn.freebsd.org/base/head src
+svn co https://svn.freebsd.org/ports/head ports
+svn co https://svn.freebsd.org/doc/head doc
+svn co https://svn.freebsd.org/base/head src
cd /usr
rm -rf src
ln -s /FreeBSD/src src
diff --git a/share/man/man7/ports.7 b/share/man/man7/ports.7
index 35a2231..1243655 100644
--- a/share/man/man7/ports.7
+++ b/share/man/man7/ports.7
@@ -490,27 +490,17 @@ single file
.Bl -tag -width ".Pa /usr/ports/Mk/bsd.port.mk" -compact
.It Pa /usr/ports
The default ports directory
-.No ( Fx
-and
-.Ox ) .
-.It Pa /usr/pkgsrc
-The default ports directory
-.Pq Nx .
.It Pa /usr/ports/Mk/bsd.port.mk
The big Kahuna.
.El
.Sh SEE ALSO
.Xr make 1 ,
-.Xr pkg_add 1 ,
-.Xr pkg_create 1 ,
-.Xr pkg_delete 1 ,
-.Xr pkg_info 1 ,
-.Xr pkg_version 1
+.Xr pkg 8 ,
+.Xr portsnap 8
.Pp
The following are part of the ports collection:
.Pp
.Xr portaudit 1 ,
-.Xr portcheckout 1 ,
.Xr portlint 1
.Rs
.%B "The FreeBSD Handbook"
diff --git a/share/man/man9/Makefile b/share/man/man9/Makefile
index 8e96d64..fa7cc8a 100644
--- a/share/man/man9/Makefile
+++ b/share/man/man9/Makefile
@@ -1196,9 +1196,13 @@ MLINKS+=signal.9 cursig.9 \
signal.9 SIG_STOPSIGMASK.9 \
signal.9 trapsignal.9
MLINKS+=sleep.9 msleep.9 \
+ sleep.9 msleep_sbt.9 \
sleep.9 msleep_spin.9 \
+ sleep.9 msleep_spin_sbt.9 \
sleep.9 pause.9 \
+ sleep.9 pause_sbt.9 \
sleep.9 tsleep.9 \
+ sleep.9 tsleep_sbt.9 \
sleep.9 wakeup.9 \
sleep.9 wakeup_one.9
MLINKS+=sleepqueue.9 init_sleepqueues.9 \
@@ -1213,6 +1217,7 @@ MLINKS+=sleepqueue.9 init_sleepqueues.9 \
sleepqueue.9 sleepq_release.9 \
sleepqueue.9 sleepq_remove.9 \
sleepqueue.9 sleepq_set_timeout.9 \
+ sleepqueue.9 sleepq_set_timeout_sbt.9 \
sleepqueue.9 sleepq_signal.9 \
sleepqueue.9 sleepq_timedwait.9 \
sleepqueue.9 sleepq_timedwait_sig.9 \
@@ -1335,6 +1340,9 @@ MLINKS+=timeout.9 callout.9 \
timeout.9 callout_init_rw.9 \
timeout.9 callout_pending.9 \
timeout.9 callout_reset.9 \
+ timeout.9 callout_reset_sbt.9 \
+ timeout.9 callout_reset_on.9 \
+ timeout.9 callout_reset_sbt_on.9 \
timeout.9 callout_schedule.9 \
timeout.9 callout_stop.9 \
timeout.9 untimeout.9
diff --git a/share/man/man9/condvar.9 b/share/man/man9/condvar.9
index 7b89d46..4a4e874 100644
--- a/share/man/man9/condvar.9
+++ b/share/man/man9/condvar.9
@@ -26,7 +26,7 @@
.\"
.\" $FreeBSD$
.\"
-.Dd June 5, 2007
+.Dd February 19, 2013
.Dt CONDVAR 9
.Os
.Sh NAME
@@ -37,7 +37,9 @@
.Nm cv_wait_sig ,
.Nm cv_wait_unlock ,
.Nm cv_timedwait ,
+.Nm cv_timedwait_sbt ,
.Nm cv_timedwait_sig ,
+.Nm cv_timedwait_sig_sbt ,
.Nm cv_signal ,
.Nm cv_broadcast ,
.Nm cv_broadcastpri ,
@@ -60,7 +62,13 @@
.Ft int
.Fn cv_timedwait "struct cv *cvp" "lock" "int timo"
.Ft int
+.Fn cv_timedwait_sbt "struct cv *cvp" "lock" "sbintime_t sbt" \
+"sbintime_t pr" "int flags"
+.Ft int
.Fn cv_timedwait_sig "struct cv *cvp" "lock" "int timo"
+.Ft int
+.Fn cv_timedwait_sig_sbt "struct cv *cvp" "lock" "sbintime_t sbt" \
+"sbintime_t pr" "int flags"
.Ft void
.Fn cv_signal "struct cv *cvp"
.Ft void
@@ -191,6 +199,25 @@ if a signal is caught, or 0 if signaled via
.Fn cv_signal
or
.Fn cv_broadcast .
+.Pp
+.Fn cv_timedwait_sbt
+and
+.Fn cv_timedwait_sig_sbt
+functions take
+.Fa sbt
+argument instead of
+.Fa timo .
+It allows to specify relative or absolute unblock time with higher resolution
+in form of
+.Vt sbintime_t .
+The parameter
+.Fa pr
+allows to specify wanted absolute event precision.
+The parameter
+.Fa flags
+allows to pass additional
+.Fn callout_reset_sbt
+flags.
.Sh RETURN VALUES
If successful,
.Fn cv_wait_sig ,
@@ -230,4 +257,5 @@ Timeout expired.
.Xr rwlock 9 ,
.Xr sema 9 ,
.Xr sleep 9 ,
-.Xr sx 9
+.Xr sx 9 ,
+.Xr timeout 9
diff --git a/share/man/man9/sleep.9 b/share/man/man9/sleep.9
index e65a189..4ac9d45 100644
--- a/share/man/man9/sleep.9
+++ b/share/man/man9/sleep.9
@@ -25,14 +25,18 @@
.\"
.\" $FreeBSD$
.\"
-.Dd December 12, 2009
+.Dd February 19, 2013
.Dt SLEEP 9
.Os
.Sh NAME
.Nm msleep ,
+.Nm msleep_sbt ,
.Nm msleep_spin ,
+.Nm msleep_spin_sbt ,
.Nm pause ,
+.Nm pause_sbt ,
.Nm tsleep ,
+.Nm tsleep_sbt ,
.Nm wakeup
.Nd wait for events
.Sh SYNOPSIS
@@ -42,11 +46,23 @@
.Ft int
.Fn msleep "void *chan" "struct mtx *mtx" "int priority" "const char *wmesg" "int timo"
.Ft int
+.Fn msleep_sbt "void *chan" "struct mtx *mtx" "int priority" \
+"const char *wmesg" "sbintime_t sbt" "sbintime_t pr" "int flags"
+.Ft int
.Fn msleep_spin "void *chan" "struct mtx *mtx" "const char *wmesg" "int timo"
+.Ft int
+.Fn msleep_spin_sbt "void *chan" "struct mtx *mtx" "const char *wmesg" \
+"sbintime_t sbt" "sbintime_t pr" "int flags"
.Ft void
.Fn pause "const char *wmesg" "int timo"
+.Ft void
+.Fn pause_sbt "const char *wmesg" "sbintime_t sbt" "sbintime_t pr" \
+ "int flags"
.Ft int
.Fn tsleep "void *chan" "int priority" "const char *wmesg" "int timo"
+.Ft int
+.Fn tsleep_sbt "void *chan" "int priority" "const char *wmesg" \
+"sbintime_t sbt" "sbintime_t pr" "int flags"
.Ft void
.Fn wakeup "void *chan"
.Ft void
@@ -148,6 +164,27 @@ If the timeout expires,
then the sleep function will return
.Er EWOULDBLOCK .
.Pp
+.Fn msleep_sbt ,
+.Fn msleep_spin_sbt ,
+.Fn pause_sbt
+and
+.Fn tsleep_sbt
+functions take
+.Fa sbt
+parameter instead of
+.Fa timo .
+It allows to specify relative or absolite wakeup time with higher resolution
+in form of
+.Vt sbintime_t .
+The parameter
+.Fa pr
+allows to specify wanted absolute event precision.
+The parameter
+.Fa flags
+allows to pass additional
+.Fn callout_reset_sbt
+flags.
+.Pp
Several of the sleep functions including
.Fn msleep ,
.Fn msleep_spin ,
@@ -301,7 +338,8 @@ A non-zero timeout was specified and the timeout expired.
.Xr mi_switch 9 ,
.Xr mtx_sleep 9 ,
.Xr rw_sleep 9 ,
-.Xr sx_sleep 9
+.Xr sx_sleep 9 ,
+.Xr timeout 9
.Sh HISTORY
The functions
.Fn sleep
diff --git a/share/man/man9/sleepqueue.9 b/share/man/man9/sleepqueue.9
index 22971d8..8557b9f 100644
--- a/share/man/man9/sleepqueue.9
+++ b/share/man/man9/sleepqueue.9
@@ -23,7 +23,7 @@
.\"
.\" $FreeBSD$
.\"
-.Dd January 8, 2010
+.Dd February 19, 2013
.Dt SLEEPQUEUE 9
.Os
.Sh NAME
@@ -41,6 +41,7 @@
.Nm sleepq_remove ,
.Nm sleepq_signal ,
.Nm sleepq_set_timeout ,
+.Nm sleepq_set_timeout_sbt ,
.Nm sleepq_sleepcnt ,
.Nm sleepq_timedwait ,
.Nm sleepq_timedwait_sig ,
@@ -79,6 +80,9 @@
.Fn sleepq_signal "void *wchan" "int flags" "int pri" "int queue"
.Ft void
.Fn sleepq_set_timeout "void *wchan" "int timo"
+.Ft void
+.Fn sleepq_set_timeout_sbt "void *wchan" "sbintime_t sbt" \
+"sbintime_t pr" "int flags"
.Ft u_int
.Fn sleepq_sleepcnt "void *wchan" "int queue"
.Ft int
@@ -231,6 +235,23 @@ The
.Fa timo
parameter should specify the timeout value in ticks.
.Pp
+.Fn sleepq_set_timeout_sbt
+function takes
+.Fa sbt
+argument instead of
+.Fa timo .
+It allows to specify relative or absolute wakeup time with higher resolution
+in form of
+.Vt sbintime_t .
+The parameter
+.Fa pr
+allows to specify wanted absolute event precision.
+The parameter
+.Fa flags
+allows to pass additional
+.Fn callout_reset_sbt
+flags.
+.Pp
The current thread may be marked interruptible by calling
.Fn sleepq_catch_signals
with
@@ -400,4 +421,5 @@ than manipulating sleep queues directly.
.Xr condvar 9 ,
.Xr runqueue 9 ,
.Xr scheduler 9 ,
-.Xr sleep 9
+.Xr sleep 9 ,
+.Xr timeout 9
diff --git a/share/man/man9/timeout.9 b/share/man/man9/timeout.9
index c671467..c63c201 100644
--- a/share/man/man9/timeout.9
+++ b/share/man/man9/timeout.9
@@ -29,7 +29,7 @@
.\"
.\" $FreeBSD$
.\"
-.Dd November 1, 2012
+.Dd February 19, 2013
.Dt TIMEOUT 9
.Os
.Sh NAME
@@ -44,6 +44,9 @@
.Nm callout_reset ,
.Nm callout_reset_on ,
.Nm callout_reset_curcpu ,
+.Nm callout_reset_sbt ,
+.Nm callout_reset_sbt_on ,
+.Nm callout_reset_sbt_curcpu ,
.Nm callout_schedule ,
.Nm callout_schedule_on ,
.Nm callout_schedule_curcpu ,
@@ -82,6 +85,9 @@ struct callout_handle handle = CALLOUT_HANDLE_INITIALIZER(&handle);
.Fn callout_reset_on "struct callout *c" "int ticks" "timeout_t *func" \
"void *arg" "int cpu"
.Ft int
+.Fn callout_reset_sbt_on "struct callout *c" "sbintime_t sbt" \
+"sbintime_t pr" "timeout_t *func" "void *arg" "int cpu" "int flags"
+.Ft int
.Fn callout_reset_curcpu "struct callout *c" "int ticks" "timeout_t *func" \
"void *arg"
.Ft int
@@ -326,6 +332,33 @@ and
.Fn callout_schedule
but take an extra parameter specifying the target CPU for the callout.
.Pp
+The function
+.Fn callout_reset_sbt_on
+allows to get higher time resolution, taking relative or absolute time
+and precision instead of relative ticks count.
+If specified time is in past, it will be silently converted to present
+to run handler as soon as possible.
+.Pp
+The following
+.Fa flags
+may be specified:
+.Bl -tag -width ".Dv C_DIRECT_EXEC"
+.It Dv C_ALSOLUTE
+Handle the
+.Fa sbt
+argument as absolute time of the event since boot, or relative time otherwise.
+.It Dv C_DIRECT_EXEC
+Run handler directly from hardware interrupt context instead of softclock swi.
+It is faster, but puts more constraints on handlers.
+Handlers may use only spin mutexes for locking, and they must be fast because
+they run with absolute priority.
+.It Fn C_PREL
+Specifies relative event time precision as binary logarithm of time interval
+divided by acceptable time deviation: 1 -- 1/2, 2 -- 1/4, etc.
+Smaller value allows to aggregate more events in one timer interrupt to
+reduce processing overhead and power consumption.
+.El
+.Pp
The functions
.Fn callout_reset_curcpu
and
diff --git a/share/mk/bsd.libnames.mk b/share/mk/bsd.libnames.mk
index d742142..9b3e31f 100644
--- a/share/mk/bsd.libnames.mk
+++ b/share/mk/bsd.libnames.mk
@@ -25,6 +25,7 @@ LIBBIND9?= ${DESTDIR}${LIBDIR}/libbind9.a
.endif
LIBBLUETOOTH?= ${DESTDIR}${LIBDIR}/libbluetooth.a
LIBBSDXML?= ${DESTDIR}${LIBDIR}/libbsdxml.a
+LIBBSDYML?= ${DESTDIR}${LIBDIR}/libbsdyml.a
LIBBSM?= ${DESTDIR}${LIBDIR}/libbsm.a
LIBBSNMP?= ${DESTDIR}${LIBDIR}/libbsnmp.a
LIBBZ2?= ${DESTDIR}${LIBDIR}/libbz2.a
diff --git a/sys/amd64/conf/GENERIC b/sys/amd64/conf/GENERIC
index 3988195..577cf4b 100644
--- a/sys/amd64/conf/GENERIC
+++ b/sys/amd64/conf/GENERIC
@@ -138,7 +138,10 @@ device sa # Sequential Access (tape etc)
device cd # CD
device pass # Passthrough device (direct ATA/SCSI access)
device ses # Enclosure Services (SES and SAF-TE)
-#device ctl # CAM Target Layer
+device ctl # CAM Target Layer
+options CTL_DISABLE # Disable CTL by default to save memory.
+ # Re-enable with kern.cam.ctl.disable=0 in
+ # /boot/loader.conf
# RAID controllers interfaced to the SCSI subsystem
device amr # AMI MegaRAID
diff --git a/sys/amd64/conf/NOTES b/sys/amd64/conf/NOTES
index a4371f7..7a41464 100644
--- a/sys/amd64/conf/NOTES
+++ b/sys/amd64/conf/NOTES
@@ -442,6 +442,13 @@ options SAFE_RNDTEST # enable rndtest support
#
# VirtIO support
+#
+# The virtio entry provides a generic bus for use by the device drivers.
+# It must be combined with an interface that communicates with the host.
+# Multiple such interfaces defined by the VirtIO specification. FreeBSD
+# only has support for PCI. Therefore, virtio_pci must be statically
+# compiled in or loaded as a module for the device drivers to function.
+#
device virtio # Generic VirtIO bus (required)
device virtio_pci # VirtIO PCI Interface
device vtnet # VirtIO Ethernet device
diff --git a/sys/arm/arm/busdma_machdep-v6.c b/sys/arm/arm/busdma_machdep-v6.c
index c87f857..ab69683 100644
--- a/sys/arm/arm/busdma_machdep-v6.c
+++ b/sys/arm/arm/busdma_machdep-v6.c
@@ -1007,6 +1007,9 @@ _bus_dmamap_load_buffer(bus_dma_tag_t dmat,
} else {
sl = &map->slist[map->sync_count - 1];
if (map->sync_count == 0 ||
+#ifdef ARM_L2_PIPT
+ curaddr != sl->busaddr + sl->datacount ||
+#endif
vaddr != sl->vaddr + sl->datacount) {
if (++map->sync_count > dmat->nsegments)
goto cleanup;
diff --git a/sys/arm/arm/swtch.S b/sys/arm/arm/swtch.S
index 4c422e8..4257557 100644
--- a/sys/arm/arm/swtch.S
+++ b/sys/arm/arm/swtch.S
@@ -211,10 +211,12 @@ ENTRY(cpu_throw)
GET_PCPU(r6)
str r7, [r6, #PC_CURPCB]
+ add sp, sp, #4;
ldmfd sp!, {r4-r7, pc}
ENTRY(cpu_switch)
stmfd sp!, {r4-r7, lr}
+ sub sp, sp, #4;
mov r6, r2 /* Save the mutex */
.Lswitch_resume:
@@ -488,6 +490,7 @@ ENTRY(cpu_switch)
* Pull the registers that got pushed when either savectx() or
* cpu_switch() was called and return.
*/
+ add sp, sp, #4;
ldmfd sp!, {r4-r7, pc}
#ifdef DIAGNOSTIC
.Lswitch_bogons:
@@ -501,6 +504,7 @@ ENTRY(cpu_switch)
#endif
ENTRY(savectx)
stmfd sp!, {r4-r7, lr}
+ sub sp, sp, #4
/*
* r0 = pcb
*/
@@ -528,6 +532,7 @@ ENTRY(savectx)
bl _C_LABEL(vfp_store)
1:
#endif /* ARM_VFP_SUPPORT */
+ add sp, sp, #4;
ldmfd sp!, {r4-r7, pc}
ENTRY(fork_trampoline)
diff --git a/sys/arm/arm/vm_machdep.c b/sys/arm/arm/vm_machdep.c
index 97b8b76..29a213f 100644
--- a/sys/arm/arm/vm_machdep.c
+++ b/sys/arm/arm/vm_machdep.c
@@ -73,6 +73,12 @@ __FBSDID("$FreeBSD$");
#include <machine/md_var.h>
+/*
+ * struct switchframe must be a multiple of 8 for correct stack alignment
+ */
+CTASSERT(sizeof(struct switchframe) == 24);
+CTASSERT(sizeof(struct trapframe) == 76);
+
#ifndef NSFBUFS
#define NSFBUFS (512 + maxusers * 16)
#endif
@@ -131,8 +137,8 @@ cpu_fork(register struct thread *td1, register struct proc *p2,
pcb2->un_32.pcb32_sp = td2->td_kstack +
USPACE_SVC_STACK_TOP - sizeof(*pcb2);
pmap_activate(td2);
- td2->td_frame = tf =
- (struct trapframe *)pcb2->un_32.pcb32_sp - 1;
+ td2->td_frame = tf = (struct trapframe *)STACKALIGN(
+ pcb2->un_32.pcb32_sp - sizeof(struct trapframe));
*tf = *td1->td_frame;
sf = (struct switchframe *)tf - 1;
sf->sf_r4 = (u_int)fork_return;
@@ -142,6 +148,8 @@ cpu_fork(register struct thread *td1, register struct proc *p2,
tf->tf_r0 = 0;
tf->tf_r1 = 0;
pcb2->un_32.pcb32_sp = (u_int)sf;
+ KASSERT((pcb2->un_32.pcb32_sp & 7) == 0,
+ ("cpu_fork: Incorrect stack alignment"));
/* Setup to release spin count in fork_exit(). */
td2->td_md.md_spinlock_count = 1;
@@ -345,6 +353,8 @@ cpu_set_upcall(struct thread *td, struct thread *td0)
tf->tf_r0 = 0;
td->td_pcb->un_32.pcb32_sp = (u_int)sf;
td->td_pcb->un_32.pcb32_und_sp = td->td_kstack + USPACE_UNDEF_STACK_TOP;
+ KASSERT((td->td_pcb->un_32.pcb32_sp & 7) == 0,
+ ("cpu_set_upcall: Incorrect stack alignment"));
/* Setup to release spin count in fork_exit(). */
td->td_md.md_spinlock_count = 1;
@@ -438,6 +448,8 @@ cpu_set_fork_handler(struct thread *td, void (*func)(void *), void *arg)
sf->sf_r4 = (u_int)func;
sf->sf_r5 = (u_int)arg;
td->td_pcb->un_32.pcb32_sp = (u_int)sf;
+ KASSERT((td->td_pcb->un_32.pcb32_sp & 7) == 0,
+ ("cpu_set_fork_handler: Incorrect stack alignment"));
}
/*
diff --git a/sys/arm/broadcom/bcm2835/bcm2835_dma.c b/sys/arm/broadcom/bcm2835/bcm2835_dma.c
index 5e1c9dc..429ba7c 100644
--- a/sys/arm/broadcom/bcm2835/bcm2835_dma.c
+++ b/sys/arm/broadcom/bcm2835/bcm2835_dma.c
@@ -199,6 +199,7 @@ bcm_dma_reset(device_t dev, int ch)
/* Reset control block */
cb = sc->sc_dma_ch[ch].cb;
bzero(cb, sizeof(cb));
+ cb->info = INFO_WAIT_RESP;
}
static int
@@ -615,6 +616,7 @@ bcm_dma_intr(void *arg)
debug & DEBUG_ERROR_MASK, ch->ch);
bus_write_4(sc->sc_mem, BCM_DMA_DEBUG(ch->ch),
debug & DEBUG_ERROR_MASK);
+ bcm_dma_reset(sc->sc_dev, ch->ch);
}
if (cs & CS_INT) {
diff --git a/sys/arm/include/frame.h b/sys/arm/include/frame.h
index a24eccc..09ba55f 100644
--- a/sys/arm/include/frame.h
+++ b/sys/arm/include/frame.h
@@ -138,10 +138,14 @@ typedef struct irqframe {
} irqframe_t;
/*
- * Switch frame
+ * Switch frame.
+ *
+ * It is important this is a multiple of 8 bytes so the stack is correctly
+ * aligned when we create new threads.
*/
struct switchframe {
+ u_int pad; /* Used to pad the struct to a multiple of 8-bytes */
u_int sf_r4;
u_int sf_r5;
u_int sf_r6;
diff --git a/sys/bsm/audit_kevents.h b/sys/bsm/audit_kevents.h
index 9d71fa2..d56a96b 100644
--- a/sys/bsm/audit_kevents.h
+++ b/sys/bsm/audit_kevents.h
@@ -608,6 +608,8 @@
#define AUE_CAP_IOCTLS_GET 43204 /* TrustedBSD. */
#define AUE_CAP_FCNTLS_LIMIT 43205 /* TrustedBSD. */
#define AUE_CAP_FCNTLS_GET 43206 /* TrustedBSD. */
+#define AUE_BINDAT 43207 /* TrustedBSD. */
+#define AUE_CONNECTAT 43208 /* TrustedBSD. */
/*
* Darwin BSM uses a number of AUE_O_* definitions, which are aliased to the
diff --git a/sys/cam/ctl/ctl.c b/sys/cam/ctl/ctl.c
index 768332e..1884c7b 100644
--- a/sys/cam/ctl/ctl.c
+++ b/sys/cam/ctl/ctl.c
@@ -78,6 +78,8 @@ __FBSDID("$FreeBSD$");
#include <cam/ctl/ctl_scsi_all.h>
#include <cam/ctl/ctl_error.h>
+#include "opt_ctl.h"
+
struct ctl_softc *control_softc = NULL;
/*
@@ -317,7 +319,11 @@ static int persis_offset;
static uint8_t ctl_pause_rtr;
static int ctl_is_single;
static int index_to_aps_page;
+#ifdef CTL_DISABLE
+int ctl_disable = 1;
+#else
int ctl_disable = 0;
+#endif
SYSCTL_NODE(_kern_cam, OID_AUTO, ctl, CTLFLAG_RD, 0, "CAM Target Layer");
SYSCTL_INT(_kern_cam_ctl, OID_AUTO, disable, CTLFLAG_RDTUN, &ctl_disable, 0,
diff --git a/sys/cddl/compat/opensolaris/sys/kcondvar.h b/sys/cddl/compat/opensolaris/sys/kcondvar.h
index 0422ba0..7c68842 100644
--- a/sys/cddl/compat/opensolaris/sys/kcondvar.h
+++ b/sys/cddl/compat/opensolaris/sys/kcondvar.h
@@ -55,7 +55,7 @@ typedef enum {
_name = #cv; \
cv_init((cv), _name); \
} while (0)
-#define cv_init(cv, name, type, arg) zfs_cv_init((cv), (name), (type), (arg))
+#define cv_init(cv, name, type, arg) zfs_cv_init(cv, name, type, arg)
#endif /* _KERNEL */
diff --git a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/bpobj.c b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/bpobj.c
index 1920da4..3e55663 100644
--- a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/bpobj.c
+++ b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/bpobj.c
@@ -20,7 +20,7 @@
*/
/*
* Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
- * Copyright (c) 2012 by Delphix. All rights reserved.
+ * Copyright (c) 2013 by Delphix. All rights reserved.
*/
#include <sys/bpobj.h>
@@ -414,6 +414,12 @@ bpobj_enqueue_subobj(bpobj_t *bpo, uint64_t subobj, dmu_tx_t *tx)
VERIFY3U(0, ==, dmu_buf_hold(bpo->bpo_os, subsubobjs,
0, FTAG, &subdb, 0));
+ /*
+ * Make sure that we are not asking dmu_write()
+ * to write more data than we have in our buffer.
+ */
+ VERIFY3U(subdb->db_size, >=,
+ numsubsub * sizeof (subobj));
dmu_write(bpo->bpo_os, bpo->bpo_phys->bpo_subobjs,
bpo->bpo_phys->bpo_num_subobjs * sizeof (subobj),
numsubsub * sizeof (subobj), subdb->db_data, tx);
diff --git a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dmu.c b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dmu.c
index fc606d5..60c5c7f 100644
--- a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dmu.c
+++ b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dmu.c
@@ -1711,7 +1711,7 @@ dmu_object_info_from_dnode(dnode_t *dn, dmu_object_info_t *doi)
doi->doi_checksum = dn->dn_checksum;
doi->doi_compress = dn->dn_compress;
doi->doi_physical_blocks_512 = (DN_USED_BYTES(dnp) + 256) >> 9;
- doi->doi_max_offset = (dnp->dn_maxblkid + 1) * dn->dn_datablksz;
+ doi->doi_max_offset = (dn->dn_maxblkid + 1) * dn->dn_datablksz;
doi->doi_fill_count = 0;
for (int i = 0; i < dnp->dn_nblkptr; i++)
doi->doi_fill_count += dnp->dn_blkptr[i].blk_fill;
diff --git a/sys/cddl/contrib/opensolaris/uts/intel/dtrace/fasttrap_isa.c b/sys/cddl/contrib/opensolaris/uts/intel/dtrace/fasttrap_isa.c
index d0db808..65991af 100644
--- a/sys/cddl/contrib/opensolaris/uts/intel/dtrace/fasttrap_isa.c
+++ b/sys/cddl/contrib/opensolaris/uts/intel/dtrace/fasttrap_isa.c
@@ -1034,6 +1034,7 @@ fasttrap_pid_probe(struct reg *rp)
#endif
PROC_LOCK(p);
+ _PHOLD(p);
pid = p->p_pid;
#if defined(sun)
pid_mtx = &cpu_core[CPU->cpu_id].cpuc_pid_lock;
@@ -1059,6 +1060,7 @@ fasttrap_pid_probe(struct reg *rp)
#if defined(sun)
mutex_exit(pid_mtx);
#endif
+ _PRELE(p);
PROC_UNLOCK(p);
return (-1);
}
@@ -1732,7 +1734,6 @@ fasttrap_pid_probe(struct reg *rp)
ASSERT(i <= sizeof (scratch));
-
#if defined(sun)
if (fasttrap_copyout(scratch, (char *)addr, i)) {
#else
@@ -1794,7 +1795,11 @@ done:
}
rp->r_rip = new_pc;
- set_regs(curthread, rp);
+
+ PROC_LOCK(p);
+ proc_write_regs(curthread, rp);
+ _PRELE(p);
+ PROC_UNLOCK(p);
return (0);
}
diff --git a/sys/compat/freebsd32/freebsd32_proto.h b/sys/compat/freebsd32/freebsd32_proto.h
index 52156bd..0e5d3f7 100644
--- a/sys/compat/freebsd32/freebsd32_proto.h
+++ b/sys/compat/freebsd32/freebsd32_proto.h
@@ -3,7 +3,7 @@
*
* DO NOT EDIT-- this file is automatically generated.
* $FreeBSD$
- * created from FreeBSD: head/sys/compat/freebsd32/syscalls.master 247602 2013-03-02 00:53:12Z pjd
+ * created from FreeBSD: head/sys/compat/freebsd32/syscalls.master 247667 2013-03-02 21:11:30Z pjd
*/
#ifndef _FREEBSD32_SYSPROTO_H_
diff --git a/sys/compat/freebsd32/freebsd32_syscall.h b/sys/compat/freebsd32/freebsd32_syscall.h
index 4b689d3..4f1549e 100644
--- a/sys/compat/freebsd32/freebsd32_syscall.h
+++ b/sys/compat/freebsd32/freebsd32_syscall.h
@@ -3,7 +3,7 @@
*
* DO NOT EDIT-- this file is automatically generated.
* $FreeBSD$
- * created from FreeBSD: head/sys/compat/freebsd32/syscalls.master 247602 2013-03-02 00:53:12Z pjd
+ * created from FreeBSD: head/sys/compat/freebsd32/syscalls.master 247667 2013-03-02 21:11:30Z pjd
*/
#define FREEBSD32_SYS_syscall 0
@@ -435,4 +435,6 @@
#define FREEBSD32_SYS_cap_ioctls_get 535
#define FREEBSD32_SYS_cap_fcntls_limit 536
#define FREEBSD32_SYS_cap_fcntls_get 537
-#define FREEBSD32_SYS_MAXSYSCALL 538
+#define FREEBSD32_SYS_bindat 538
+#define FREEBSD32_SYS_connectat 539
+#define FREEBSD32_SYS_MAXSYSCALL 540
diff --git a/sys/compat/freebsd32/freebsd32_syscalls.c b/sys/compat/freebsd32/freebsd32_syscalls.c
index 4878b200..0f7a7c3 100644
--- a/sys/compat/freebsd32/freebsd32_syscalls.c
+++ b/sys/compat/freebsd32/freebsd32_syscalls.c
@@ -3,7 +3,7 @@
*
* DO NOT EDIT-- this file is automatically generated.
* $FreeBSD$
- * created from FreeBSD: head/sys/compat/freebsd32/syscalls.master 247602 2013-03-02 00:53:12Z pjd
+ * created from FreeBSD: head/sys/compat/freebsd32/syscalls.master 247667 2013-03-02 21:11:30Z pjd
*/
const char *freebsd32_syscallnames[] = {
@@ -561,4 +561,6 @@ const char *freebsd32_syscallnames[] = {
"cap_ioctls_get", /* 535 = cap_ioctls_get */
"cap_fcntls_limit", /* 536 = cap_fcntls_limit */
"cap_fcntls_get", /* 537 = cap_fcntls_get */
+ "bindat", /* 538 = bindat */
+ "connectat", /* 539 = connectat */
};
diff --git a/sys/compat/freebsd32/freebsd32_sysent.c b/sys/compat/freebsd32/freebsd32_sysent.c
index 65da2c7..2a47edb 100644
--- a/sys/compat/freebsd32/freebsd32_sysent.c
+++ b/sys/compat/freebsd32/freebsd32_sysent.c
@@ -3,7 +3,7 @@
*
* DO NOT EDIT-- this file is automatically generated.
* $FreeBSD$
- * created from FreeBSD: head/sys/compat/freebsd32/syscalls.master 247602 2013-03-02 00:53:12Z pjd
+ * created from FreeBSD: head/sys/compat/freebsd32/syscalls.master 247667 2013-03-02 21:11:30Z pjd
*/
#include "opt_compat.h"
@@ -598,4 +598,6 @@ struct sysent freebsd32_sysent[] = {
{ AS(cap_ioctls_get_args), (sy_call_t *)sys_cap_ioctls_get, AUE_CAP_IOCTLS_GET, NULL, 0, 0, 0, SY_THR_STATIC }, /* 535 = cap_ioctls_get */
{ AS(cap_fcntls_limit_args), (sy_call_t *)sys_cap_fcntls_limit, AUE_CAP_FCNTLS_LIMIT, NULL, 0, 0, 0, SY_THR_STATIC }, /* 536 = cap_fcntls_limit */
{ AS(cap_fcntls_get_args), (sy_call_t *)sys_cap_fcntls_get, AUE_CAP_FCNTLS_GET, NULL, 0, 0, 0, SY_THR_STATIC }, /* 537 = cap_fcntls_get */
+ { AS(bindat_args), (sy_call_t *)sys_bindat, AUE_BINDAT, NULL, 0, 0, 0, SY_THR_STATIC }, /* 538 = bindat */
+ { AS(connectat_args), (sy_call_t *)sys_connectat, AUE_CONNECTAT, NULL, 0, 0, 0, SY_THR_STATIC }, /* 539 = connectat */
};
diff --git a/sys/compat/freebsd32/freebsd32_systrace_args.c b/sys/compat/freebsd32/freebsd32_systrace_args.c
index e2d7adb..d23974a 100644
--- a/sys/compat/freebsd32/freebsd32_systrace_args.c
+++ b/sys/compat/freebsd32/freebsd32_systrace_args.c
@@ -3130,6 +3130,26 @@ systrace_args(int sysnum, void *params, uint64_t *uarg, int *n_args)
*n_args = 2;
break;
}
+ /* bindat */
+ case 538: {
+ struct bindat_args *p = params;
+ iarg[0] = p->fd; /* int */
+ iarg[1] = p->s; /* int */
+ uarg[2] = (intptr_t) p->name; /* caddr_t */
+ iarg[3] = p->namelen; /* int */
+ *n_args = 4;
+ break;
+ }
+ /* connectat */
+ case 539: {
+ struct connectat_args *p = params;
+ iarg[0] = p->fd; /* int */
+ iarg[1] = p->s; /* int */
+ uarg[2] = (intptr_t) p->name; /* caddr_t */
+ iarg[3] = p->namelen; /* int */
+ *n_args = 4;
+ break;
+ }
default:
*n_args = 0;
break;
@@ -8356,6 +8376,44 @@ systrace_entry_setargdesc(int sysnum, int ndx, char *desc, size_t descsz)
break;
};
break;
+ /* bindat */
+ case 538:
+ switch(ndx) {
+ case 0:
+ p = "int";
+ break;
+ case 1:
+ p = "int";
+ break;
+ case 2:
+ p = "caddr_t";
+ break;
+ case 3:
+ p = "int";
+ break;
+ default:
+ break;
+ };
+ break;
+ /* connectat */
+ case 539:
+ switch(ndx) {
+ case 0:
+ p = "int";
+ break;
+ case 1:
+ p = "int";
+ break;
+ case 2:
+ p = "caddr_t";
+ break;
+ case 3:
+ p = "int";
+ break;
+ default:
+ break;
+ };
+ break;
default:
break;
};
@@ -10143,6 +10201,16 @@ systrace_return_setargdesc(int sysnum, int ndx, char *desc, size_t descsz)
if (ndx == 0 || ndx == 1)
p = "int";
break;
+ /* bindat */
+ case 538:
+ if (ndx == 0 || ndx == 1)
+ p = "int";
+ break;
+ /* connectat */
+ case 539:
+ if (ndx == 0 || ndx == 1)
+ p = "int";
+ break;
default:
break;
};
diff --git a/sys/compat/freebsd32/syscalls.master b/sys/compat/freebsd32/syscalls.master
index 6552d13..655296c 100644
--- a/sys/compat/freebsd32/syscalls.master
+++ b/sys/compat/freebsd32/syscalls.master
@@ -1015,3 +1015,7 @@
uint32_t fcntlrights); }
537 AUE_CAP_FCNTLS_GET NOPROTO { int cap_fcntls_get(int fd, \
uint32_t *fcntlrightsp); }
+538 AUE_BINDAT NOPROTO { int bindat(int fd, int s, caddr_t name, \
+ int namelen); }
+539 AUE_CONNECTAT NOPROTO { int connectat(int fd, int s, caddr_t name, \
+ int namelen); }
diff --git a/sys/compat/linprocfs/linprocfs.c b/sys/compat/linprocfs/linprocfs.c
index 5c24e05..a49a9bc 100644
--- a/sys/compat/linprocfs/linprocfs.c
+++ b/sys/compat/linprocfs/linprocfs.c
@@ -386,8 +386,7 @@ linprocfs_domtab(PFS_FILL_ARGS)
sbuf_printf(sb, " 0 0\n");
}
mtx_unlock(&mountlist_mtx);
- if (flep != NULL)
- free(flep, M_TEMP);
+ free(flep, M_TEMP);
return (error);
}
@@ -447,8 +446,7 @@ linprocfs_dopartitions(PFS_FILL_ARGS)
}
g_topology_unlock();
- if (flep != NULL)
- free(flep, M_TEMP);
+ free(flep, M_TEMP);
return (error);
}
diff --git a/sys/compat/linux/linux_file.c b/sys/compat/linux/linux_file.c
index 346d178..7e4ac380 100644
--- a/sys/compat/linux/linux_file.c
+++ b/sys/compat/linux/linux_file.c
@@ -517,8 +517,7 @@ eof:
td->td_retval[0] = nbytes - resid;
out:
- if (cookies)
- free(cookies, M_TEMP);
+ free(cookies, M_TEMP);
VOP_UNLOCK(vp, 0);
foffset_unlock(fp, off, 0);
diff --git a/sys/compat/linux/linux_socket.c b/sys/compat/linux/linux_socket.c
index cd288f8..36b23ac 100644
--- a/sys/compat/linux/linux_socket.c
+++ b/sys/compat/linux/linux_socket.c
@@ -1443,10 +1443,8 @@ out:
bad:
free(iov, M_IOV);
- if (control != NULL)
- m_freem(control);
- if (linux_cmsg != NULL)
- free(linux_cmsg, M_TEMP);
+ m_freem(control);
+ free(linux_cmsg, M_TEMP);
return (error);
}
diff --git a/sys/conf/NOTES b/sys/conf/NOTES
index 5d26093..27c3380 100644
--- a/sys/conf/NOTES
+++ b/sys/conf/NOTES
@@ -259,6 +259,8 @@ options SX_NOINLINE
# SMP Debugging Options:
#
+# CALLOUT_PROFILING enables rudimentary profiling of the callwheel data
+# structure used as backend in callout(9).
# PREEMPTION allows the threads that are in the kernel to be preempted by
# higher priority [interrupt] threads. It helps with interactivity
# and allows interrupt threads to run sooner rather than waiting.
@@ -297,6 +299,9 @@ options LOCK_PROFILING
options MPROF_BUFFERS="1536"
options MPROF_HASH_SIZE="1543"
+# Profiling for the callout(9) backend.
+options CALLOUT_PROFILING
+
# Profiling for internal hash tables.
options SLEEPQUEUE_PROFILING
options TURNSTILE_PROFILING
diff --git a/sys/conf/files.amd64 b/sys/conf/files.amd64
index 131a1e7..5e659b9 100644
--- a/sys/conf/files.amd64
+++ b/sys/conf/files.amd64
@@ -393,11 +393,11 @@ dev/virtio/virtio.c optional virtio
dev/virtio/virtqueue.c optional virtio
dev/virtio/virtio_bus_if.m optional virtio
dev/virtio/virtio_if.m optional virtio
-dev/virtio/pci/virtio_pci.c optional virtio_pci virtio pci
-dev/virtio/network/if_vtnet.c optional vtnet virtio
-dev/virtio/block/virtio_blk.c optional virtio_blk virtio
-dev/virtio/balloon/virtio_balloon.c optional virtio_balloon virtio
-dev/virtio/scsi/virtio_scsi.c optional virtio_scsi virtio scbus
+dev/virtio/pci/virtio_pci.c optional virtio_pci
+dev/virtio/network/if_vtnet.c optional vtnet
+dev/virtio/block/virtio_blk.c optional virtio_blk
+dev/virtio/balloon/virtio_balloon.c optional virtio_balloon
+dev/virtio/scsi/virtio_scsi.c optional virtio_scsi
isa/syscons_isa.c optional sc
isa/vga_isa.c optional vga
kern/kern_clocksource.c standard
diff --git a/sys/conf/files.i386 b/sys/conf/files.i386
index fd536af..f4c595a 100644
--- a/sys/conf/files.i386
+++ b/sys/conf/files.i386
@@ -374,11 +374,11 @@ dev/virtio/virtio.c optional virtio
dev/virtio/virtqueue.c optional virtio
dev/virtio/virtio_bus_if.m optional virtio
dev/virtio/virtio_if.m optional virtio
-dev/virtio/pci/virtio_pci.c optional virtio_pci virtio pci
-dev/virtio/network/if_vtnet.c optional vtnet virtio
-dev/virtio/block/virtio_blk.c optional virtio_blk virtio
-dev/virtio/balloon/virtio_balloon.c optional virtio_balloon virtio
-dev/virtio/scsi/virtio_scsi.c optional virtio_scsi virtio scbus
+dev/virtio/pci/virtio_pci.c optional virtio_pci
+dev/virtio/network/if_vtnet.c optional vtnet
+dev/virtio/block/virtio_blk.c optional virtio_blk
+dev/virtio/balloon/virtio_balloon.c optional virtio_balloon
+dev/virtio/scsi/virtio_scsi.c optional virtio_scsi
i386/acpica/acpi_machdep.c optional acpi
acpi_wakecode.o optional acpi \
dependency "$S/i386/acpica/acpi_wakecode.S assym.s" \
diff --git a/sys/conf/options b/sys/conf/options
index ab5d153..ec9271d 100644
--- a/sys/conf/options
+++ b/sys/conf/options
@@ -68,6 +68,7 @@ TEXTDUMP_VERBOSE opt_ddb.h
ADAPTIVE_LOCKMGRS
ALQ
AUDIT opt_global.h
+CALLOUT_PROFILING
CAPABILITIES opt_capsicum.h
CAPABILITY_MODE opt_capsicum.h
COMPAT_43 opt_compat.h
@@ -328,6 +329,9 @@ SCSI_PT_DEFAULT_TIMEOUT opt_pt.h
# Options used only in cam/scsi/scsi_ses.c
SES_ENABLE_PASSTHROUGH opt_ses.h
+# Options used only in cam/ctl
+CTL_DISABLE opt_ctl.h
+
# Options used in dev/sym/ (Symbios SCSI driver).
SYM_SETUP_LP_PROBE_MAP opt_sym.h #-Low Priority Probe Map (bits)
# Allows the ncr to take precedence
diff --git a/sys/contrib/altq/altq/altq_hfsc.c b/sys/contrib/altq/altq/altq_hfsc.c
index bced145..f436bd5 100644
--- a/sys/contrib/altq/altq/altq_hfsc.c
+++ b/sys/contrib/altq/altq/altq_hfsc.c
@@ -104,14 +104,10 @@ static void update_ed(struct hfsc_class *, int);
static void update_d(struct hfsc_class *, int);
static void init_vf(struct hfsc_class *, int);
static void update_vf(struct hfsc_class *, int, u_int64_t);
-static ellist_t *ellist_alloc(void);
-static void ellist_destroy(ellist_t *);
static void ellist_insert(struct hfsc_class *);
static void ellist_remove(struct hfsc_class *);
static void ellist_update(struct hfsc_class *);
-struct hfsc_class *ellist_get_mindl(ellist_t *, u_int64_t);
-static actlist_t *actlist_alloc(void);
-static void actlist_destroy(actlist_t *);
+struct hfsc_class *hfsc_get_mindl(struct hfsc_if *, u_int64_t);
static void actlist_insert(struct hfsc_class *);
static void actlist_remove(struct hfsc_class *);
static void actlist_update(struct hfsc_class *);
@@ -204,12 +200,7 @@ hfsc_add_altq(struct pf_altq *a)
if (hif == NULL)
return (ENOMEM);
- hif->hif_eligible = ellist_alloc();
- if (hif->hif_eligible == NULL) {
- free(hif, M_DEVBUF);
- return (ENOMEM);
- }
-
+ TAILQ_INIT(&hif->hif_eligible);
hif->hif_ifq = &ifp->if_snd;
/* keep the state in pf_altq */
@@ -230,8 +221,6 @@ hfsc_remove_altq(struct pf_altq *a)
(void)hfsc_clear_interface(hif);
(void)hfsc_class_destroy(hif->hif_rootclass);
- ellist_destroy(hif->hif_eligible);
-
free(hif, M_DEVBUF);
return (0);
@@ -408,9 +397,7 @@ hfsc_class_create(struct hfsc_if *hif, struct service_curve *rsc,
if (cl->cl_q == NULL)
goto err_ret;
- cl->cl_actc = actlist_alloc();
- if (cl->cl_actc == NULL)
- goto err_ret;
+ TAILQ_INIT(&cl->cl_actc);
if (qlimit == 0)
qlimit = 50; /* use default */
@@ -544,8 +531,6 @@ hfsc_class_create(struct hfsc_if *hif, struct service_curve *rsc,
return (cl);
err_ret:
- if (cl->cl_actc != NULL)
- actlist_destroy(cl->cl_actc);
if (cl->cl_red != NULL) {
#ifdef ALTQ_RIO
if (q_is_rio(cl->cl_q))
@@ -620,8 +605,6 @@ hfsc_class_destroy(struct hfsc_class *cl)
IFQ_UNLOCK(cl->cl_hif->hif_ifq);
splx(s);
- actlist_destroy(cl->cl_actc);
-
if (cl->cl_red != NULL) {
#ifdef ALTQ_RIO
if (q_is_rio(cl->cl_q))
@@ -774,7 +757,7 @@ hfsc_dequeue(struct ifaltq *ifq, int op)
* find the class with the minimum deadline among
* the eligible classes.
*/
- if ((cl = ellist_get_mindl(hif->hif_eligible, cur_time))
+ if ((cl = hfsc_get_mindl(hif, cur_time))
!= NULL) {
realtime = 1;
} else {
@@ -994,7 +977,7 @@ init_vf(struct hfsc_class *cl, int len)
go_active = 0;
if (go_active) {
- max_cl = actlist_last(cl->cl_parent->cl_actc);
+ max_cl = TAILQ_LAST(&cl->cl_parent->cl_actc, acthead);
if (max_cl != NULL) {
/*
* set vt to the average of the min and max
@@ -1159,12 +1142,12 @@ update_cfmin(struct hfsc_class *cl)
struct hfsc_class *p;
u_int64_t cfmin;
- if (TAILQ_EMPTY(cl->cl_actc)) {
+ if (TAILQ_EMPTY(&cl->cl_actc)) {
cl->cl_cfmin = 0;
return;
}
cfmin = HT_INFINITY;
- TAILQ_FOREACH(p, cl->cl_actc, cl_actlist) {
+ TAILQ_FOREACH(p, &cl->cl_actc, cl_actlist) {
if (p->cl_f == 0) {
cl->cl_cfmin = 0;
return;
@@ -1184,22 +1167,6 @@ update_cfmin(struct hfsc_class *cl)
* there is one eligible list per interface.
*/
-static ellist_t *
-ellist_alloc(void)
-{
- ellist_t *head;
-
- head = malloc(sizeof(ellist_t), M_DEVBUF, M_WAITOK);
- TAILQ_INIT(head);
- return (head);
-}
-
-static void
-ellist_destroy(ellist_t *head)
-{
- free(head, M_DEVBUF);
-}
-
static void
ellist_insert(struct hfsc_class *cl)
{
@@ -1207,13 +1174,13 @@ ellist_insert(struct hfsc_class *cl)
struct hfsc_class *p;
/* check the last entry first */
- if ((p = TAILQ_LAST(hif->hif_eligible, _eligible)) == NULL ||
+ if ((p = TAILQ_LAST(&hif->hif_eligible, elighead)) == NULL ||
p->cl_e <= cl->cl_e) {
- TAILQ_INSERT_TAIL(hif->hif_eligible, cl, cl_ellist);
+ TAILQ_INSERT_TAIL(&hif->hif_eligible, cl, cl_ellist);
return;
}
- TAILQ_FOREACH(p, hif->hif_eligible, cl_ellist) {
+ TAILQ_FOREACH(p, &hif->hif_eligible, cl_ellist) {
if (cl->cl_e < p->cl_e) {
TAILQ_INSERT_BEFORE(p, cl, cl_ellist);
return;
@@ -1227,7 +1194,7 @@ ellist_remove(struct hfsc_class *cl)
{
struct hfsc_if *hif = cl->cl_hif;
- TAILQ_REMOVE(hif->hif_eligible, cl, cl_ellist);
+ TAILQ_REMOVE(&hif->hif_eligible, cl, cl_ellist);
}
static void
@@ -1245,11 +1212,11 @@ ellist_update(struct hfsc_class *cl)
return;
/* check the last entry */
- last = TAILQ_LAST(hif->hif_eligible, _eligible);
+ last = TAILQ_LAST(&hif->hif_eligible, elighead);
ASSERT(last != NULL);
if (last->cl_e <= cl->cl_e) {
- TAILQ_REMOVE(hif->hif_eligible, cl, cl_ellist);
- TAILQ_INSERT_TAIL(hif->hif_eligible, cl, cl_ellist);
+ TAILQ_REMOVE(&hif->hif_eligible, cl, cl_ellist);
+ TAILQ_INSERT_TAIL(&hif->hif_eligible, cl, cl_ellist);
return;
}
@@ -1259,7 +1226,7 @@ ellist_update(struct hfsc_class *cl)
*/
while ((p = TAILQ_NEXT(p, cl_ellist)) != NULL) {
if (cl->cl_e < p->cl_e) {
- TAILQ_REMOVE(hif->hif_eligible, cl, cl_ellist);
+ TAILQ_REMOVE(&hif->hif_eligible, cl, cl_ellist);
TAILQ_INSERT_BEFORE(p, cl, cl_ellist);
return;
}
@@ -1269,11 +1236,11 @@ ellist_update(struct hfsc_class *cl)
/* find the class with the minimum deadline among the eligible classes */
struct hfsc_class *
-ellist_get_mindl(ellist_t *head, u_int64_t cur_time)
+hfsc_get_mindl(struct hfsc_if *hif, u_int64_t cur_time)
{
struct hfsc_class *p, *cl = NULL;
- TAILQ_FOREACH(p, head, cl_ellist) {
+ TAILQ_FOREACH(p, &hif->hif_eligible, cl_ellist) {
if (p->cl_e > cur_time)
break;
if (cl == NULL || p->cl_d < cl->cl_d)
@@ -1287,34 +1254,20 @@ ellist_get_mindl(ellist_t *head, u_int64_t cur_time)
* by their virtual time.
* each intermediate class has one active children list.
*/
-static actlist_t *
-actlist_alloc(void)
-{
- actlist_t *head;
-
- head = malloc(sizeof(actlist_t), M_DEVBUF, M_WAITOK);
- TAILQ_INIT(head);
- return (head);
-}
static void
-actlist_destroy(actlist_t *head)
-{
- free(head, M_DEVBUF);
-}
-static void
actlist_insert(struct hfsc_class *cl)
{
struct hfsc_class *p;
/* check the last entry first */
- if ((p = TAILQ_LAST(cl->cl_parent->cl_actc, _active)) == NULL
+ if ((p = TAILQ_LAST(&cl->cl_parent->cl_actc, acthead)) == NULL
|| p->cl_vt <= cl->cl_vt) {
- TAILQ_INSERT_TAIL(cl->cl_parent->cl_actc, cl, cl_actlist);
+ TAILQ_INSERT_TAIL(&cl->cl_parent->cl_actc, cl, cl_actlist);
return;
}
- TAILQ_FOREACH(p, cl->cl_parent->cl_actc, cl_actlist) {
+ TAILQ_FOREACH(p, &cl->cl_parent->cl_actc, cl_actlist) {
if (cl->cl_vt < p->cl_vt) {
TAILQ_INSERT_BEFORE(p, cl, cl_actlist);
return;
@@ -1326,7 +1279,7 @@ actlist_insert(struct hfsc_class *cl)
static void
actlist_remove(struct hfsc_class *cl)
{
- TAILQ_REMOVE(cl->cl_parent->cl_actc, cl, cl_actlist);
+ TAILQ_REMOVE(&cl->cl_parent->cl_actc, cl, cl_actlist);
}
static void
@@ -1344,11 +1297,11 @@ actlist_update(struct hfsc_class *cl)
return;
/* check the last entry */
- last = TAILQ_LAST(cl->cl_parent->cl_actc, _active);
+ last = TAILQ_LAST(&cl->cl_parent->cl_actc, acthead);
ASSERT(last != NULL);
if (last->cl_vt <= cl->cl_vt) {
- TAILQ_REMOVE(cl->cl_parent->cl_actc, cl, cl_actlist);
- TAILQ_INSERT_TAIL(cl->cl_parent->cl_actc, cl, cl_actlist);
+ TAILQ_REMOVE(&cl->cl_parent->cl_actc, cl, cl_actlist);
+ TAILQ_INSERT_TAIL(&cl->cl_parent->cl_actc, cl, cl_actlist);
return;
}
@@ -1358,7 +1311,7 @@ actlist_update(struct hfsc_class *cl)
*/
while ((p = TAILQ_NEXT(p, cl_actlist)) != NULL) {
if (cl->cl_vt < p->cl_vt) {
- TAILQ_REMOVE(cl->cl_parent->cl_actc, cl, cl_actlist);
+ TAILQ_REMOVE(&cl->cl_parent->cl_actc, cl, cl_actlist);
TAILQ_INSERT_BEFORE(p, cl, cl_actlist);
return;
}
@@ -1371,7 +1324,7 @@ actlist_firstfit(struct hfsc_class *cl, u_int64_t cur_time)
{
struct hfsc_class *p;
- TAILQ_FOREACH(p, cl->cl_actc, cl_actlist) {
+ TAILQ_FOREACH(p, &cl->cl_actc, cl_actlist) {
if (p->cl_f <= cur_time)
return (p);
}
diff --git a/sys/contrib/altq/altq/altq_hfsc.h b/sys/contrib/altq/altq/altq_hfsc.h
index 91ba3d1..d04b378 100644
--- a/sys/contrib/altq/altq/altq_hfsc.h
+++ b/sys/contrib/altq/altq/altq_hfsc.h
@@ -218,16 +218,6 @@ struct runtime_sc {
u_int64_t ism2; /* scaled inverse-slope of the 2nd segment */
};
-/* for TAILQ based ellist and actlist implementation */
-struct hfsc_class;
-typedef TAILQ_HEAD(_eligible, hfsc_class) ellist_t;
-typedef TAILQ_ENTRY(hfsc_class) elentry_t;
-typedef TAILQ_HEAD(_active, hfsc_class) actlist_t;
-typedef TAILQ_ENTRY(hfsc_class) actentry_t;
-#define ellist_first(s) TAILQ_FIRST(s)
-#define actlist_first(s) TAILQ_FIRST(s)
-#define actlist_last(s) TAILQ_LAST(s, _active)
-
struct hfsc_class {
u_int cl_id; /* class id (just for debug) */
u_int32_t cl_handle; /* class handle */
@@ -277,10 +267,10 @@ struct hfsc_class {
u_int cl_vtperiod; /* vt period sequence no */
u_int cl_parentperiod; /* parent's vt period seqno */
int cl_nactive; /* number of active children */
- actlist_t *cl_actc; /* active children list */
- actentry_t cl_actlist; /* active children list entry */
- elentry_t cl_ellist; /* eligible list entry */
+ TAILQ_HEAD(acthead, hfsc_class) cl_actc; /* active children list */
+ TAILQ_ENTRY(hfsc_class) cl_actlist; /* active children list entry */
+ TAILQ_ENTRY(hfsc_class) cl_ellist; /* eligible list entry */
struct {
struct pktcntr xmit_cnt;
@@ -304,7 +294,7 @@ struct hfsc_if {
u_int hif_packets; /* # of packets in the tree */
u_int hif_classid; /* class id sequence number */
- ellist_t *hif_eligible; /* eligible list */
+ TAILQ_HEAD(elighead, hfsc_class) hif_eligible; /* eligible list */
#ifdef ALTQ3_CLFIER_COMPAT
struct acc_classifier hif_classifier;
diff --git a/sys/dev/ath/ath_hal/ah.h b/sys/dev/ath/ath_hal/ah.h
index ca2e7ca..0deb9c9 100644
--- a/sys/dev/ath/ath_hal/ah.h
+++ b/sys/dev/ath/ath_hal/ah.h
@@ -1527,11 +1527,13 @@ struct ath_hal {
struct ath_desc *, u_int);
void __ahdecl(*ah_set11nAggrLast)(struct ath_hal *,
struct ath_desc *);
-
void __ahdecl(*ah_clr11nAggr)(struct ath_hal *,
struct ath_desc *);
void __ahdecl(*ah_set11nBurstDuration)(struct ath_hal *,
struct ath_desc *, u_int);
+ void __ahdecl(*ah_set11nVirtMoreFrag)(struct ath_hal *,
+ struct ath_desc *, u_int);
+
HAL_BOOL __ahdecl(*ah_getMibCycleCounts) (struct ath_hal *,
HAL_SURVEY_SAMPLE *);
diff --git a/sys/dev/ath/ath_hal/ar5416/ar5416.h b/sys/dev/ath/ath_hal/ar5416/ar5416.h
index 98dcf5e..c5ff6ae 100644
--- a/sys/dev/ath/ath_hal/ar5416/ar5416.h
+++ b/sys/dev/ath/ath_hal/ar5416/ar5416.h
@@ -409,8 +409,9 @@ extern void ar5416Set11nAggrFirst(struct ath_hal *ah, struct ath_desc *ds,
u_int aggrLen, u_int numDelims);
extern void ar5416Set11nAggrMiddle(struct ath_hal *ah, struct ath_desc *ds, u_int numDelims);
extern void ar5416Set11nAggrLast(struct ath_hal *ah, struct ath_desc *ds);
-
extern void ar5416Clr11nAggr(struct ath_hal *ah, struct ath_desc *ds);
+extern void ar5416Set11nVirtualMoreFrag(struct ath_hal *ah,
+ struct ath_desc *ds, u_int vmf);
extern void ar5416Set11nBurstDuration(struct ath_hal *ah, struct ath_desc *ds, u_int burstDuration);
diff --git a/sys/dev/ath/ath_hal/ar5416/ar5416_attach.c b/sys/dev/ath/ath_hal/ar5416/ar5416_attach.c
index 9a0a479..fd00ea7 100644
--- a/sys/dev/ath/ath_hal/ar5416/ar5416_attach.c
+++ b/sys/dev/ath/ath_hal/ar5416/ar5416_attach.c
@@ -194,6 +194,7 @@ ar5416InitState(struct ath_hal_5416 *ahp5416, uint16_t devid, HAL_SOFTC sc,
ah->ah_set11nMac2040 = ar5416Set11nMac2040;
ah->ah_get11nRxClear = ar5416Get11nRxClear;
ah->ah_set11nRxClear = ar5416Set11nRxClear;
+ ah->ah_set11nVirtMoreFrag = ar5416Set11nVirtualMoreFrag;
/* Interrupt functions */
ah->ah_isInterruptPending = ar5416IsInterruptPending;
diff --git a/sys/dev/ath/ath_hal/ar5416/ar5416_xmit.c b/sys/dev/ath/ath_hal/ar5416/ar5416_xmit.c
index 118a43b..f671175 100644
--- a/sys/dev/ath/ath_hal/ar5416/ar5416_xmit.c
+++ b/sys/dev/ath/ath_hal/ar5416/ar5416_xmit.c
@@ -825,6 +825,17 @@ ar5416Clr11nAggr(struct ath_hal *ah, struct ath_desc *ds)
ads->ds_ctl6 &= ~AR_AggrLen;
}
+void
+ar5416Set11nVirtualMoreFrag(struct ath_hal *ah, struct ath_desc *ds,
+ u_int vmf)
+{
+ struct ar5416_desc *ads = AR5416DESC(ds);
+ if (vmf)
+ ads->ds_ctl0 |= AR_VirtMoreFrag;
+ else
+ ads->ds_ctl0 &= ~AR_VirtMoreFrag;
+}
+
/*
* Program the burst duration, with the included BA delta if it's
* applicable.
diff --git a/sys/dev/ath/if_athvar.h b/sys/dev/ath/if_athvar.h
index 42442de..06cffb6 100644
--- a/sys/dev/ath/if_athvar.h
+++ b/sys/dev/ath/if_athvar.h
@@ -1297,6 +1297,8 @@ void ath_intr(void *);
((*(_ah)->ah_set11nBurstDuration)((_ah), (_ds), (_dur)))
#define ath_hal_clr11n_aggr(_ah, _ds) \
((*(_ah)->ah_clr11nAggr)((_ah), (_ds)))
+#define ath_hal_set11n_virtmorefrag(_ah, _ds, _v) \
+ ((*(_ah)->ah_set11nVirtMoreFrag)((_ah), (_ds), (_v)))
#define ath_hal_gpioCfgOutput(_ah, _gpio, _type) \
((*(_ah)->ah_gpioCfgOutput)((_ah), (_gpio), (_type)))
diff --git a/sys/dev/drm2/drmP.h b/sys/dev/drm2/drmP.h
index 542844e..8a456f1 100644
--- a/sys/dev/drm2/drmP.h
+++ b/sys/dev/drm2/drmP.h
@@ -229,6 +229,7 @@ typedef void irqreturn_t;
#define IRQ_NONE /* nothing */
#define unlikely(x) __builtin_expect(!!(x), 0)
+#define likely(x) __builtin_expect(!!(x), 1)
#define container_of(ptr, type, member) ({ \
__typeof( ((type *)0)->member ) *__mptr = (ptr); \
(type *)( (char *)__mptr - offsetof(type,member) );})
@@ -906,6 +907,7 @@ struct drm_device {
struct drm_minor *control; /**< Control node for card */
struct drm_minor *primary; /**< render type primary screen head */
+ void *drm_ttm_bo;
struct unrhdr *drw_unrhdr;
/* RB tree of drawable infos */
RB_HEAD(drawable_tree, bsd_drm_drawable_info) drw_head;
@@ -1302,10 +1304,14 @@ void drm_gem_release(struct drm_device *dev, struct drm_file *file_priv);
int drm_gem_create_mmap_offset(struct drm_gem_object *obj);
void drm_gem_free_mmap_offset(struct drm_gem_object *obj);
-int drm_gem_mmap_single(struct cdev *kdev, vm_ooffset_t *offset, vm_size_t size,
- struct vm_object **obj_res, int nprot);
+int drm_gem_mmap_single(struct drm_device *dev, vm_ooffset_t *offset,
+ vm_size_t size, struct vm_object **obj_res, int nprot);
void drm_gem_pager_dtr(void *obj);
+struct ttm_bo_device;
+int ttm_bo_mmap_single(struct ttm_bo_device *bdev, vm_ooffset_t *offset,
+ vm_size_t size, struct vm_object **obj_res, int nprot);
+
void drm_device_lock_mtx(struct drm_device *dev);
void drm_device_unlock_mtx(struct drm_device *dev);
int drm_device_sleep_mtx(struct drm_device *dev, void *chan, int flags,
diff --git a/sys/dev/drm2/drm_drv.c b/sys/dev/drm2/drm_drv.c
index 483aff5..c45bda1 100644
--- a/sys/dev/drm2/drm_drv.c
+++ b/sys/dev/drm2/drm_drv.c
@@ -58,6 +58,8 @@ static int drm_load(struct drm_device *dev);
static void drm_unload(struct drm_device *dev);
static drm_pci_id_list_t *drm_find_description(int vendor, int device,
drm_pci_id_list_t *idlist);
+static int drm_mmap_single(struct cdev *kdev, vm_ooffset_t *offset,
+ vm_size_t size, struct vm_object **obj_res, int nprot);
static int
drm_modevent(module_t mod, int type, void *data)
@@ -187,7 +189,7 @@ static struct cdevsw drm_cdevsw = {
.d_ioctl = drm_ioctl,
.d_poll = drm_poll,
.d_mmap = drm_mmap,
- .d_mmap_single = drm_gem_mmap_single,
+ .d_mmap_single = drm_mmap_single,
.d_name = "drm",
.d_flags = D_TRACKCLOSE
};
@@ -955,6 +957,23 @@ drm_add_busid_modesetting(struct drm_device *dev, struct sysctl_ctx_list *ctx,
return (0);
}
+static int
+drm_mmap_single(struct cdev *kdev, vm_ooffset_t *offset, vm_size_t size,
+ struct vm_object **obj_res, int nprot)
+{
+ struct drm_device *dev;
+
+ dev = drm_get_device_from_kdev(kdev);
+ if ((dev->driver->driver_features & DRIVER_GEM) != 0) {
+ return (drm_gem_mmap_single(dev, offset, size, obj_res, nprot));
+ } else if (dev->drm_ttm_bo != NULL) {
+ return (ttm_bo_mmap_single(dev->drm_ttm_bo, offset, size,
+ obj_res, nprot));
+ } else {
+ return (ENODEV);
+ }
+}
+
#if DRM_LINUX
#include <sys/sysproto.h>
diff --git a/sys/dev/drm2/drm_gem.c b/sys/dev/drm2/drm_gem.c
index f2c3e08..a792839 100644
--- a/sys/dev/drm2/drm_gem.c
+++ b/sys/dev/drm2/drm_gem.c
@@ -441,16 +441,12 @@ drm_gem_free_mmap_offset(struct drm_gem_object *obj)
}
int
-drm_gem_mmap_single(struct cdev *kdev, vm_ooffset_t *offset, vm_size_t size,
+drm_gem_mmap_single(struct drm_device *dev, vm_ooffset_t *offset, vm_size_t size,
struct vm_object **obj_res, int nprot)
{
- struct drm_device *dev;
struct drm_gem_object *gem_obj;
struct vm_object *vm_obj;
- dev = drm_get_device_from_kdev(kdev);
- if ((dev->driver->driver_features & DRIVER_GEM) == 0)
- return (ENODEV);
DRM_LOCK(dev);
gem_obj = drm_gem_object_from_offset(dev, *offset);
if (gem_obj == NULL) {
diff --git a/sys/dev/drm2/drm_global.c b/sys/dev/drm2/drm_global.c
new file mode 100644
index 0000000..992d061
--- /dev/null
+++ b/sys/dev/drm2/drm_global.c
@@ -0,0 +1,110 @@
+/**************************************************************************
+ *
+ * Copyright 2008-2009 VMware, Inc., Palo Alto, CA., USA
+ * All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sub license, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the
+ * next paragraph) shall be included in all copies or substantial portions
+ * of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDERS, AUTHORS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM,
+ * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
+ * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
+ * USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ **************************************************************************/
+/*
+ * Authors: Thomas Hellstrom <thellstrom-at-vmware-dot-com>
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include <dev/drm2/drmP.h>
+#include <dev/drm2/drm_global.h>
+
+MALLOC_DEFINE(M_DRM_GLOBAL, "drm_global", "DRM Global Items");
+
+struct drm_global_item {
+ struct sx mutex;
+ void *object;
+ int refcount;
+};
+
+static struct drm_global_item glob[DRM_GLOBAL_NUM];
+
+void drm_global_init(void)
+{
+ int i;
+
+ for (i = 0; i < DRM_GLOBAL_NUM; ++i) {
+ struct drm_global_item *item = &glob[i];
+ sx_init(&item->mutex, "drmgi");
+ item->object = NULL;
+ item->refcount = 0;
+ }
+}
+
+void drm_global_release(void)
+{
+ int i;
+ for (i = 0; i < DRM_GLOBAL_NUM; ++i) {
+ struct drm_global_item *item = &glob[i];
+ MPASS(item->object == NULL);
+ MPASS(item->refcount == 0);
+ sx_destroy(&item->mutex);
+ }
+}
+
+int drm_global_item_ref(struct drm_global_reference *ref)
+{
+ int ret;
+ struct drm_global_item *item = &glob[ref->global_type];
+ void *object;
+
+ sx_xlock(&item->mutex);
+ if (item->refcount == 0) {
+ item->object = malloc(ref->size, M_DRM_GLOBAL,
+ M_WAITOK | M_ZERO);
+
+ ref->object = item->object;
+ ret = ref->init(ref);
+ if (unlikely(ret != 0))
+ goto out_err;
+
+ }
+ ++item->refcount;
+ ref->object = item->object;
+ object = item->object;
+ sx_xunlock(&item->mutex);
+ return 0;
+out_err:
+ sx_xunlock(&item->mutex);
+ item->object = NULL;
+ return ret;
+}
+
+void drm_global_item_unref(struct drm_global_reference *ref)
+{
+ struct drm_global_item *item = &glob[ref->global_type];
+
+ sx_xlock(&item->mutex);
+ MPASS(item->refcount != 0);
+ MPASS(ref->object == item->object);
+ if (--item->refcount == 0) {
+ ref->release(ref);
+ item->object = NULL;
+ }
+ sx_xunlock(&item->mutex);
+}
diff --git a/sys/dev/drm2/drm_global.h b/sys/dev/drm2/drm_global.h
new file mode 100644
index 0000000..f45b015
--- /dev/null
+++ b/sys/dev/drm2/drm_global.h
@@ -0,0 +1,56 @@
+/**************************************************************************
+ *
+ * Copyright 2008-2009 VMware, Inc., Palo Alto, CA., USA
+ * All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sub license, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the
+ * next paragraph) shall be included in all copies or substantial portions
+ * of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDERS, AUTHORS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM,
+ * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
+ * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
+ * USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ **************************************************************************/
+/*
+ * Authors: Thomas Hellstrom <thellstrom-at-vmware-dot-com>
+ */
+/* $FreeBSD$ */
+
+#ifndef _DRM_GLOBAL_H_
+#define _DRM_GLOBAL_H_
+enum drm_global_types {
+ DRM_GLOBAL_TTM_MEM = 0,
+ DRM_GLOBAL_TTM_BO,
+ DRM_GLOBAL_TTM_OBJECT,
+ DRM_GLOBAL_NUM
+};
+
+struct drm_global_reference {
+ enum drm_global_types global_type;
+ size_t size;
+ void *object;
+ int (*init) (struct drm_global_reference *);
+ void (*release) (struct drm_global_reference *);
+};
+
+extern void drm_global_init(void);
+extern void drm_global_release(void);
+extern int drm_global_item_ref(struct drm_global_reference *ref);
+extern void drm_global_item_unref(struct drm_global_reference *ref);
+
+MALLOC_DECLARE(M_DRM_GLOBAL);
+
+#endif
diff --git a/sys/dev/drm2/drm_mm.c b/sys/dev/drm2/drm_mm.c
index cb35fc0..3617b05 100644
--- a/sys/dev/drm2/drm_mm.c
+++ b/sys/dev/drm2/drm_mm.c
@@ -561,3 +561,40 @@ void drm_mm_takedown(struct drm_mm * mm)
KASSERT(mm->num_unused == 0, ("num_unused != 0"));
}
+
+void drm_mm_debug_table(struct drm_mm *mm, const char *prefix)
+{
+ struct drm_mm_node *entry;
+ unsigned long total_used = 0, total_free = 0, total = 0;
+ unsigned long hole_start, hole_end, hole_size;
+
+ hole_start = drm_mm_hole_node_start(&mm->head_node);
+ hole_end = drm_mm_hole_node_end(&mm->head_node);
+ hole_size = hole_end - hole_start;
+ if (hole_size)
+ printf("%s 0x%08lx-0x%08lx: %8lu: free\n",
+ prefix, hole_start, hole_end,
+ hole_size);
+ total_free += hole_size;
+
+ drm_mm_for_each_node(entry, mm) {
+ printf("%s 0x%08lx-0x%08lx: %8lu: used\n",
+ prefix, entry->start, entry->start + entry->size,
+ entry->size);
+ total_used += entry->size;
+
+ if (entry->hole_follows) {
+ hole_start = drm_mm_hole_node_start(entry);
+ hole_end = drm_mm_hole_node_end(entry);
+ hole_size = hole_end - hole_start;
+ printf("%s 0x%08lx-0x%08lx: %8lu: free\n",
+ prefix, hole_start, hole_end,
+ hole_size);
+ total_free += hole_size;
+ }
+ }
+ total = total_free + total_used;
+
+ printf("%s total: %lu, used %lu free %lu\n", prefix, total,
+ total_used, total_free);
+}
diff --git a/sys/dev/drm2/drm_mm.h b/sys/dev/drm2/drm_mm.h
index 7b173af..7150e24 100644
--- a/sys/dev/drm2/drm_mm.h
+++ b/sys/dev/drm2/drm_mm.h
@@ -182,4 +182,6 @@ void drm_mm_init_scan_with_range(struct drm_mm *mm, unsigned long size,
int drm_mm_scan_add_block(struct drm_mm_node *node);
int drm_mm_scan_remove_block(struct drm_mm_node *node);
+void drm_mm_debug_table(struct drm_mm *mm, const char *prefix);
+
#endif
diff --git a/sys/dev/drm2/ttm/ttm_agp_backend.c b/sys/dev/drm2/ttm/ttm_agp_backend.c
new file mode 100644
index 0000000..48f2193
--- /dev/null
+++ b/sys/dev/drm2/ttm/ttm_agp_backend.c
@@ -0,0 +1,145 @@
+/**************************************************************************
+ *
+ * Copyright (c) 2006-2009 VMware, Inc., Palo Alto, CA., USA
+ * All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sub license, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the
+ * next paragraph) shall be included in all copies or substantial portions
+ * of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDERS, AUTHORS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM,
+ * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
+ * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
+ * USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ **************************************************************************/
+/*
+ * Authors: Thomas Hellstrom <thellstrom-at-vmware-dot-com>
+ * Keith Packard.
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include <dev/drm2/drmP.h>
+#include <dev/drm2/ttm/ttm_module.h>
+#include <dev/drm2/ttm/ttm_bo_driver.h>
+#include <dev/drm2/ttm/ttm_page_alloc.h>
+#ifdef TTM_HAS_AGP
+#include <dev/drm2/ttm/ttm_placement.h>
+
+struct ttm_agp_backend {
+ struct ttm_tt ttm;
+ struct agp_memory *mem;
+ device_t bridge;
+};
+
+MALLOC_DEFINE(M_TTM_AGP, "ttm_agp", "TTM AGP Backend");
+
+static int ttm_agp_bind(struct ttm_tt *ttm, struct ttm_mem_reg *bo_mem)
+{
+ struct ttm_agp_backend *agp_be = container_of(ttm, struct ttm_agp_backend, ttm);
+ struct drm_mm_node *node = bo_mem->mm_node;
+ struct agp_memory *mem;
+ int ret, cached = (bo_mem->placement & TTM_PL_FLAG_CACHED);
+ unsigned i;
+
+ mem = agp_alloc_memory(agp_be->bridge, AGP_USER_MEMORY, ttm->num_pages);
+ if (unlikely(mem == NULL))
+ return -ENOMEM;
+
+ mem->page_count = 0;
+ for (i = 0; i < ttm->num_pages; i++) {
+ vm_page_t page = ttm->pages[i];
+
+ if (!page)
+ page = ttm->dummy_read_page;
+
+ mem->pages[mem->page_count++] = page;
+ }
+ agp_be->mem = mem;
+
+ mem->is_flushed = 1;
+ mem->type = (cached) ? AGP_USER_CACHED_MEMORY : AGP_USER_MEMORY;
+
+ ret = agp_bind_memory(mem, node->start);
+ if (ret)
+ pr_err("AGP Bind memory failed\n");
+
+ return ret;
+}
+
+static int ttm_agp_unbind(struct ttm_tt *ttm)
+{
+ struct ttm_agp_backend *agp_be = container_of(ttm, struct ttm_agp_backend, ttm);
+
+ if (agp_be->mem) {
+ if (agp_be->mem->is_bound)
+ return agp_unbind_memory(agp_be->mem);
+ agp_free_memory(agp_be->mem);
+ agp_be->mem = NULL;
+ }
+ return 0;
+}
+
+static void ttm_agp_destroy(struct ttm_tt *ttm)
+{
+ struct ttm_agp_backend *agp_be = container_of(ttm, struct ttm_agp_backend, ttm);
+
+ if (agp_be->mem)
+ ttm_agp_unbind(ttm);
+ ttm_tt_fini(ttm);
+ free(agp_be, M_TTM_AGP);
+}
+
+static struct ttm_backend_func ttm_agp_func = {
+ .bind = ttm_agp_bind,
+ .unbind = ttm_agp_unbind,
+ .destroy = ttm_agp_destroy,
+};
+
+struct ttm_tt *ttm_agp_tt_create(struct ttm_bo_device *bdev,
+ device_t bridge,
+ unsigned long size, uint32_t page_flags,
+ vm_page_t dummy_read_page)
+{
+ struct ttm_agp_backend *agp_be;
+
+ agp_be = malloc(sizeof(*agp_be), M_TTM_AGP, M_WAITOK | M_ZERO);
+
+ agp_be->mem = NULL;
+ agp_be->bridge = bridge;
+ agp_be->ttm.func = &ttm_agp_func;
+
+ if (ttm_tt_init(&agp_be->ttm, bdev, size, page_flags, dummy_read_page)) {
+ return NULL;
+ }
+
+ return &agp_be->ttm;
+}
+
+int ttm_agp_tt_populate(struct ttm_tt *ttm)
+{
+ if (ttm->state != tt_unpopulated)
+ return 0;
+
+ return ttm_pool_populate(ttm);
+}
+
+void ttm_agp_tt_unpopulate(struct ttm_tt *ttm)
+{
+ ttm_pool_unpopulate(ttm);
+}
+
+#endif
diff --git a/sys/dev/drm2/ttm/ttm_bo.c b/sys/dev/drm2/ttm/ttm_bo.c
new file mode 100644
index 0000000..12e5131
--- /dev/null
+++ b/sys/dev/drm2/ttm/ttm_bo.c
@@ -0,0 +1,1820 @@
+/**************************************************************************
+ *
+ * Copyright (c) 2006-2009 VMware, Inc., Palo Alto, CA., USA
+ * All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sub license, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the
+ * next paragraph) shall be included in all copies or substantial portions
+ * of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDERS, AUTHORS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM,
+ * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
+ * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
+ * USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ **************************************************************************/
+/*
+ * Authors: Thomas Hellstrom <thellstrom-at-vmware-dot-com>
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include <dev/drm2/drmP.h>
+#include <dev/drm2/ttm/ttm_module.h>
+#include <dev/drm2/ttm/ttm_bo_driver.h>
+#include <dev/drm2/ttm/ttm_placement.h>
+
+#define TTM_ASSERT_LOCKED(param)
+#define TTM_DEBUG(fmt, arg...)
+#define TTM_BO_HASH_ORDER 13
+
+static int ttm_bo_setup_vm(struct ttm_buffer_object *bo);
+static int ttm_bo_swapout(struct ttm_mem_shrink *shrink);
+static void ttm_bo_global_kobj_release(struct ttm_bo_global *glob);
+
+MALLOC_DEFINE(M_TTM_BO, "ttm_bo", "TTM Buffer Objects");
+
+static inline int ttm_mem_type_from_flags(uint32_t flags, uint32_t *mem_type)
+{
+ int i;
+
+ for (i = 0; i <= TTM_PL_PRIV5; i++)
+ if (flags & (1 << i)) {
+ *mem_type = i;
+ return 0;
+ }
+ return -EINVAL;
+}
+
+static void ttm_mem_type_debug(struct ttm_bo_device *bdev, int mem_type)
+{
+ struct ttm_mem_type_manager *man = &bdev->man[mem_type];
+
+ printf(" has_type: %d\n", man->has_type);
+ printf(" use_type: %d\n", man->use_type);
+ printf(" flags: 0x%08X\n", man->flags);
+ printf(" gpu_offset: 0x%08lX\n", man->gpu_offset);
+ printf(" size: %ju\n", (uintmax_t)man->size);
+ printf(" available_caching: 0x%08X\n", man->available_caching);
+ printf(" default_caching: 0x%08X\n", man->default_caching);
+ if (mem_type != TTM_PL_SYSTEM)
+ (*man->func->debug)(man, TTM_PFX);
+}
+
+static void ttm_bo_mem_space_debug(struct ttm_buffer_object *bo,
+ struct ttm_placement *placement)
+{
+ int i, ret, mem_type;
+
+ printf("No space for %p (%lu pages, %luK, %luM)\n",
+ bo, bo->mem.num_pages, bo->mem.size >> 10,
+ bo->mem.size >> 20);
+ for (i = 0; i < placement->num_placement; i++) {
+ ret = ttm_mem_type_from_flags(placement->placement[i],
+ &mem_type);
+ if (ret)
+ return;
+ printf(" placement[%d]=0x%08X (%d)\n",
+ i, placement->placement[i], mem_type);
+ ttm_mem_type_debug(bo->bdev, mem_type);
+ }
+}
+
+#if 0
+static ssize_t ttm_bo_global_show(struct ttm_bo_global *glob,
+ char *buffer)
+{
+
+ return snprintf(buffer, PAGE_SIZE, "%lu\n",
+ (unsigned long) atomic_read(&glob->bo_count));
+}
+#endif
+
+static inline uint32_t ttm_bo_type_flags(unsigned type)
+{
+ return 1 << (type);
+}
+
+static void ttm_bo_release_list(struct ttm_buffer_object *bo)
+{
+ struct ttm_bo_device *bdev = bo->bdev;
+ size_t acc_size = bo->acc_size;
+
+ MPASS(atomic_read(&bo->list_kref) == 0);
+ MPASS(atomic_read(&bo->kref) == 0);
+ MPASS(atomic_read(&bo->cpu_writers) == 0);
+ MPASS(bo->sync_obj == NULL);
+ MPASS(bo->mem.mm_node == NULL);
+ MPASS(list_empty(&bo->lru));
+ MPASS(list_empty(&bo->ddestroy));
+
+ if (bo->ttm)
+ ttm_tt_destroy(bo->ttm);
+ atomic_dec(&bo->glob->bo_count);
+ if (bo->destroy)
+ bo->destroy(bo);
+ else {
+ free(bo, M_TTM_BO);
+ }
+ ttm_mem_global_free(bdev->glob->mem_glob, acc_size);
+}
+
+int
+ttm_bo_wait_unreserved_locked(struct ttm_buffer_object *bo, bool interruptible)
+{
+ const char *wmsg;
+ int flags, ret;
+
+ ret = 0;
+ if (interruptible) {
+ flags = PCATCH;
+ wmsg = "ttbowi";
+ } else {
+ flags = 0;
+ wmsg = "ttbowu";
+ }
+ while (!ttm_bo_is_reserved(bo)) {
+ ret = -msleep(bo, &bo->glob->lru_lock, flags, wmsg, 0);
+ if (ret != 0)
+ break;
+ }
+ return (ret);
+}
+
+void ttm_bo_add_to_lru(struct ttm_buffer_object *bo)
+{
+ struct ttm_bo_device *bdev = bo->bdev;
+ struct ttm_mem_type_manager *man;
+
+ MPASS(ttm_bo_is_reserved(bo));
+
+ if (!(bo->mem.placement & TTM_PL_FLAG_NO_EVICT)) {
+
+ MPASS(list_empty(&bo->lru));
+
+ man = &bdev->man[bo->mem.mem_type];
+ list_add_tail(&bo->lru, &man->lru);
+ refcount_acquire(&bo->list_kref);
+
+ if (bo->ttm != NULL) {
+ list_add_tail(&bo->swap, &bo->glob->swap_lru);
+ refcount_acquire(&bo->list_kref);
+ }
+ }
+}
+
+int ttm_bo_del_from_lru(struct ttm_buffer_object *bo)
+{
+ int put_count = 0;
+
+ if (!list_empty(&bo->swap)) {
+ list_del_init(&bo->swap);
+ ++put_count;
+ }
+ if (!list_empty(&bo->lru)) {
+ list_del_init(&bo->lru);
+ ++put_count;
+ }
+
+ /*
+ * TODO: Add a driver hook to delete from
+ * driver-specific LRU's here.
+ */
+
+ return put_count;
+}
+
+int ttm_bo_reserve_locked(struct ttm_buffer_object *bo,
+ bool interruptible,
+ bool no_wait, bool use_sequence, uint32_t sequence)
+{
+ int ret;
+
+ while (unlikely(atomic_read(&bo->reserved) != 0)) {
+ /**
+ * Deadlock avoidance for multi-bo reserving.
+ */
+ if (use_sequence && bo->seq_valid) {
+ /**
+ * We've already reserved this one.
+ */
+ if (unlikely(sequence == bo->val_seq))
+ return -EDEADLK;
+ /**
+ * Already reserved by a thread that will not back
+ * off for us. We need to back off.
+ */
+ if (unlikely(sequence - bo->val_seq < (1 << 31)))
+ return -EAGAIN;
+ }
+
+ if (no_wait)
+ return -EBUSY;
+
+ ret = ttm_bo_wait_unreserved_locked(bo, interruptible);
+ if (unlikely(ret))
+ return ret;
+ }
+
+ atomic_set(&bo->reserved, 1);
+ if (use_sequence) {
+ /**
+ * Wake up waiters that may need to recheck for deadlock,
+ * if we decreased the sequence number.
+ */
+ if (unlikely((bo->val_seq - sequence < (1 << 31))
+ || !bo->seq_valid))
+ wakeup(bo);
+
+ bo->val_seq = sequence;
+ bo->seq_valid = true;
+ } else {
+ bo->seq_valid = false;
+ }
+
+ return 0;
+}
+
+void ttm_bo_list_ref_sub(struct ttm_buffer_object *bo, int count,
+ bool never_free)
+{
+ u_int old;
+
+ old = atomic_fetchadd_int(&bo->list_kref, -count);
+ if (old <= count) {
+ if (never_free)
+ panic("ttm_bo_ref_buf");
+ ttm_bo_release_list(bo);
+ }
+}
+
+int ttm_bo_reserve(struct ttm_buffer_object *bo,
+ bool interruptible,
+ bool no_wait, bool use_sequence, uint32_t sequence)
+{
+ struct ttm_bo_global *glob = bo->glob;
+ int put_count = 0;
+ int ret;
+
+ mtx_lock(&glob->lru_lock);
+ ret = ttm_bo_reserve_locked(bo, interruptible, no_wait, use_sequence,
+ sequence);
+ if (likely(ret == 0))
+ put_count = ttm_bo_del_from_lru(bo);
+ mtx_unlock(&glob->lru_lock);
+
+ ttm_bo_list_ref_sub(bo, put_count, true);
+
+ return ret;
+}
+
+void ttm_bo_unreserve_locked(struct ttm_buffer_object *bo)
+{
+ ttm_bo_add_to_lru(bo);
+ atomic_set(&bo->reserved, 0);
+ wakeup(bo);
+}
+
+void ttm_bo_unreserve(struct ttm_buffer_object *bo)
+{
+ struct ttm_bo_global *glob = bo->glob;
+
+ mtx_lock(&glob->lru_lock);
+ ttm_bo_unreserve_locked(bo);
+ mtx_unlock(&glob->lru_lock);
+}
+
+/*
+ * Call bo->mutex locked.
+ */
+static int ttm_bo_add_ttm(struct ttm_buffer_object *bo, bool zero_alloc)
+{
+ struct ttm_bo_device *bdev = bo->bdev;
+ struct ttm_bo_global *glob = bo->glob;
+ int ret = 0;
+ uint32_t page_flags = 0;
+
+ TTM_ASSERT_LOCKED(&bo->mutex);
+ bo->ttm = NULL;
+
+ if (bdev->need_dma32)
+ page_flags |= TTM_PAGE_FLAG_DMA32;
+
+ switch (bo->type) {
+ case ttm_bo_type_device:
+ if (zero_alloc)
+ page_flags |= TTM_PAGE_FLAG_ZERO_ALLOC;
+ case ttm_bo_type_kernel:
+ bo->ttm = bdev->driver->ttm_tt_create(bdev, bo->num_pages << PAGE_SHIFT,
+ page_flags, glob->dummy_read_page);
+ if (unlikely(bo->ttm == NULL))
+ ret = -ENOMEM;
+ break;
+ case ttm_bo_type_sg:
+ bo->ttm = bdev->driver->ttm_tt_create(bdev, bo->num_pages << PAGE_SHIFT,
+ page_flags | TTM_PAGE_FLAG_SG,
+ glob->dummy_read_page);
+ if (unlikely(bo->ttm == NULL)) {
+ ret = -ENOMEM;
+ break;
+ }
+ bo->ttm->sg = bo->sg;
+ break;
+ default:
+ printf("[TTM] Illegal buffer object type\n");
+ ret = -EINVAL;
+ break;
+ }
+
+ return ret;
+}
+
+static int ttm_bo_handle_move_mem(struct ttm_buffer_object *bo,
+ struct ttm_mem_reg *mem,
+ bool evict, bool interruptible,
+ bool no_wait_gpu)
+{
+ struct ttm_bo_device *bdev = bo->bdev;
+ bool old_is_pci = ttm_mem_reg_is_pci(bdev, &bo->mem);
+ bool new_is_pci = ttm_mem_reg_is_pci(bdev, mem);
+ struct ttm_mem_type_manager *old_man = &bdev->man[bo->mem.mem_type];
+ struct ttm_mem_type_manager *new_man = &bdev->man[mem->mem_type];
+ int ret = 0;
+
+ if (old_is_pci || new_is_pci ||
+ ((mem->placement & bo->mem.placement & TTM_PL_MASK_CACHING) == 0)) {
+ ret = ttm_mem_io_lock(old_man, true);
+ if (unlikely(ret != 0))
+ goto out_err;
+ ttm_bo_unmap_virtual_locked(bo);
+ ttm_mem_io_unlock(old_man);
+ }
+
+ /*
+ * Create and bind a ttm if required.
+ */
+
+ if (!(new_man->flags & TTM_MEMTYPE_FLAG_FIXED)) {
+ if (bo->ttm == NULL) {
+ bool zero = !(old_man->flags & TTM_MEMTYPE_FLAG_FIXED);
+ ret = ttm_bo_add_ttm(bo, zero);
+ if (ret)
+ goto out_err;
+ }
+
+ ret = ttm_tt_set_placement_caching(bo->ttm, mem->placement);
+ if (ret)
+ goto out_err;
+
+ if (mem->mem_type != TTM_PL_SYSTEM) {
+ ret = ttm_tt_bind(bo->ttm, mem);
+ if (ret)
+ goto out_err;
+ }
+
+ if (bo->mem.mem_type == TTM_PL_SYSTEM) {
+ if (bdev->driver->move_notify)
+ bdev->driver->move_notify(bo, mem);
+ bo->mem = *mem;
+ mem->mm_node = NULL;
+ goto moved;
+ }
+ }
+
+ if (bdev->driver->move_notify)
+ bdev->driver->move_notify(bo, mem);
+
+ if (!(old_man->flags & TTM_MEMTYPE_FLAG_FIXED) &&
+ !(new_man->flags & TTM_MEMTYPE_FLAG_FIXED))
+ ret = ttm_bo_move_ttm(bo, evict, no_wait_gpu, mem);
+ else if (bdev->driver->move)
+ ret = bdev->driver->move(bo, evict, interruptible,
+ no_wait_gpu, mem);
+ else
+ ret = ttm_bo_move_memcpy(bo, evict, no_wait_gpu, mem);
+
+ if (ret) {
+ if (bdev->driver->move_notify) {
+ struct ttm_mem_reg tmp_mem = *mem;
+ *mem = bo->mem;
+ bo->mem = tmp_mem;
+ bdev->driver->move_notify(bo, mem);
+ bo->mem = *mem;
+ }
+
+ goto out_err;
+ }
+
+moved:
+ if (bo->evicted) {
+ ret = bdev->driver->invalidate_caches(bdev, bo->mem.placement);
+ if (ret)
+ printf("[TTM] Can not flush read caches\n");
+ bo->evicted = false;
+ }
+
+ if (bo->mem.mm_node) {
+ bo->offset = (bo->mem.start << PAGE_SHIFT) +
+ bdev->man[bo->mem.mem_type].gpu_offset;
+ bo->cur_placement = bo->mem.placement;
+ } else
+ bo->offset = 0;
+
+ return 0;
+
+out_err:
+ new_man = &bdev->man[bo->mem.mem_type];
+ if ((new_man->flags & TTM_MEMTYPE_FLAG_FIXED) && bo->ttm) {
+ ttm_tt_unbind(bo->ttm);
+ ttm_tt_destroy(bo->ttm);
+ bo->ttm = NULL;
+ }
+
+ return ret;
+}
+
+/**
+ * Call bo::reserved.
+ * Will release GPU memory type usage on destruction.
+ * This is the place to put in driver specific hooks to release
+ * driver private resources.
+ * Will release the bo::reserved lock.
+ */
+
+static void ttm_bo_cleanup_memtype_use(struct ttm_buffer_object *bo)
+{
+ if (bo->bdev->driver->move_notify)
+ bo->bdev->driver->move_notify(bo, NULL);
+
+ if (bo->ttm) {
+ ttm_tt_unbind(bo->ttm);
+ ttm_tt_destroy(bo->ttm);
+ bo->ttm = NULL;
+ }
+ ttm_bo_mem_put(bo, &bo->mem);
+
+ atomic_set(&bo->reserved, 0);
+ wakeup(&bo);
+
+ /*
+ * Since the final reference to this bo may not be dropped by
+ * the current task we have to put a memory barrier here to make
+ * sure the changes done in this function are always visible.
+ *
+ * This function only needs protection against the final kref_put.
+ */
+ mb();
+}
+
+static void ttm_bo_cleanup_refs_or_queue(struct ttm_buffer_object *bo)
+{
+ struct ttm_bo_device *bdev = bo->bdev;
+ struct ttm_bo_global *glob = bo->glob;
+ struct ttm_bo_driver *driver = bdev->driver;
+ void *sync_obj = NULL;
+ int put_count;
+ int ret;
+
+ mtx_lock(&glob->lru_lock);
+ ret = ttm_bo_reserve_locked(bo, false, true, false, 0);
+
+ mtx_lock(&bdev->fence_lock);
+ (void) ttm_bo_wait(bo, false, false, true);
+ if (!ret && !bo->sync_obj) {
+ mtx_unlock(&bdev->fence_lock);
+ put_count = ttm_bo_del_from_lru(bo);
+
+ mtx_unlock(&glob->lru_lock);
+ ttm_bo_cleanup_memtype_use(bo);
+
+ ttm_bo_list_ref_sub(bo, put_count, true);
+
+ return;
+ }
+ if (bo->sync_obj)
+ sync_obj = driver->sync_obj_ref(bo->sync_obj);
+ mtx_unlock(&bdev->fence_lock);
+
+ if (!ret) {
+ atomic_set(&bo->reserved, 0);
+ wakeup(bo);
+ }
+
+ refcount_acquire(&bo->list_kref);
+ list_add_tail(&bo->ddestroy, &bdev->ddestroy);
+ mtx_unlock(&glob->lru_lock);
+
+ if (sync_obj) {
+ driver->sync_obj_flush(sync_obj);
+ driver->sync_obj_unref(&sync_obj);
+ }
+ taskqueue_enqueue_timeout(taskqueue_thread, &bdev->wq,
+ ((hz / 100) < 1) ? 1 : hz / 100);
+}
+
+/**
+ * function ttm_bo_cleanup_refs_and_unlock
+ * If bo idle, remove from delayed- and lru lists, and unref.
+ * If not idle, do nothing.
+ *
+ * Must be called with lru_lock and reservation held, this function
+ * will drop both before returning.
+ *
+ * @interruptible Any sleeps should occur interruptibly.
+ * @no_wait_gpu Never wait for gpu. Return -EBUSY instead.
+ */
+
+static int ttm_bo_cleanup_refs_and_unlock(struct ttm_buffer_object *bo,
+ bool interruptible,
+ bool no_wait_gpu)
+{
+ struct ttm_bo_device *bdev = bo->bdev;
+ struct ttm_bo_driver *driver = bdev->driver;
+ struct ttm_bo_global *glob = bo->glob;
+ int put_count;
+ int ret;
+
+ mtx_lock(&bdev->fence_lock);
+ ret = ttm_bo_wait(bo, false, false, true);
+
+ if (ret && !no_wait_gpu) {
+ void *sync_obj;
+
+ /*
+ * Take a reference to the fence and unreserve,
+ * at this point the buffer should be dead, so
+ * no new sync objects can be attached.
+ */
+ sync_obj = driver->sync_obj_ref(bo->sync_obj);
+ mtx_unlock(&bdev->fence_lock);
+
+ atomic_set(&bo->reserved, 0);
+ wakeup(bo);
+ mtx_unlock(&glob->lru_lock);
+
+ ret = driver->sync_obj_wait(sync_obj, false, interruptible);
+ driver->sync_obj_unref(&sync_obj);
+ if (ret)
+ return ret;
+
+ /*
+ * remove sync_obj with ttm_bo_wait, the wait should be
+ * finished, and no new wait object should have been added.
+ */
+ mtx_lock(&bdev->fence_lock);
+ ret = ttm_bo_wait(bo, false, false, true);
+ mtx_unlock(&bdev->fence_lock);
+ if (ret)
+ return ret;
+
+ mtx_lock(&glob->lru_lock);
+ ret = ttm_bo_reserve_locked(bo, false, true, false, 0);
+
+ /*
+ * We raced, and lost, someone else holds the reservation now,
+ * and is probably busy in ttm_bo_cleanup_memtype_use.
+ *
+ * Even if it's not the case, because we finished waiting any
+ * delayed destruction would succeed, so just return success
+ * here.
+ */
+ if (ret) {
+ mtx_unlock(&glob->lru_lock);
+ return 0;
+ }
+ } else
+ mtx_unlock(&bdev->fence_lock);
+
+ if (ret || unlikely(list_empty(&bo->ddestroy))) {
+ atomic_set(&bo->reserved, 0);
+ wakeup(bo);
+ mtx_unlock(&glob->lru_lock);
+ return ret;
+ }
+
+ put_count = ttm_bo_del_from_lru(bo);
+ list_del_init(&bo->ddestroy);
+ ++put_count;
+
+ mtx_unlock(&glob->lru_lock);
+ ttm_bo_cleanup_memtype_use(bo);
+
+ ttm_bo_list_ref_sub(bo, put_count, true);
+
+ return 0;
+}
+
+/**
+ * Traverse the delayed list, and call ttm_bo_cleanup_refs on all
+ * encountered buffers.
+ */
+
+static int ttm_bo_delayed_delete(struct ttm_bo_device *bdev, bool remove_all)
+{
+ struct ttm_bo_global *glob = bdev->glob;
+ struct ttm_buffer_object *entry = NULL;
+ int ret = 0;
+
+ mtx_lock(&glob->lru_lock);
+ if (list_empty(&bdev->ddestroy))
+ goto out_unlock;
+
+ entry = list_first_entry(&bdev->ddestroy,
+ struct ttm_buffer_object, ddestroy);
+ refcount_acquire(&entry->list_kref);
+
+ for (;;) {
+ struct ttm_buffer_object *nentry = NULL;
+
+ if (entry->ddestroy.next != &bdev->ddestroy) {
+ nentry = list_first_entry(&entry->ddestroy,
+ struct ttm_buffer_object, ddestroy);
+ refcount_acquire(&nentry->list_kref);
+ }
+
+ ret = ttm_bo_reserve_locked(entry, false, !remove_all, false, 0);
+ if (!ret)
+ ret = ttm_bo_cleanup_refs_and_unlock(entry, false,
+ !remove_all);
+ else
+ mtx_unlock(&glob->lru_lock);
+
+ if (refcount_release(&entry->list_kref))
+ ttm_bo_release_list(entry);
+ entry = nentry;
+
+ if (ret || !entry)
+ goto out;
+
+ mtx_lock(&glob->lru_lock);
+ if (list_empty(&entry->ddestroy))
+ break;
+ }
+
+out_unlock:
+ mtx_unlock(&glob->lru_lock);
+out:
+ if (entry && refcount_release(&entry->list_kref))
+ ttm_bo_release_list(entry);
+ return ret;
+}
+
+static void ttm_bo_delayed_workqueue(void *arg, int pending __unused)
+{
+ struct ttm_bo_device *bdev = arg;
+
+ if (ttm_bo_delayed_delete(bdev, false)) {
+ taskqueue_enqueue_timeout(taskqueue_thread, &bdev->wq,
+ ((hz / 100) < 1) ? 1 : hz / 100);
+ }
+}
+
+static void ttm_bo_release(struct ttm_buffer_object *bo)
+{
+ struct ttm_bo_device *bdev = bo->bdev;
+ struct ttm_mem_type_manager *man = &bdev->man[bo->mem.mem_type];
+
+ rw_wlock(&bdev->vm_lock);
+ if (likely(bo->vm_node != NULL)) {
+ RB_REMOVE(ttm_bo_device_buffer_objects,
+ &bdev->addr_space_rb, bo);
+ drm_mm_put_block(bo->vm_node);
+ bo->vm_node = NULL;
+ }
+ rw_wunlock(&bdev->vm_lock);
+ ttm_mem_io_lock(man, false);
+ ttm_mem_io_free_vm(bo);
+ ttm_mem_io_unlock(man);
+ ttm_bo_cleanup_refs_or_queue(bo);
+ if (refcount_release(&bo->list_kref))
+ ttm_bo_release_list(bo);
+}
+
+void ttm_bo_unref(struct ttm_buffer_object **p_bo)
+{
+ struct ttm_buffer_object *bo = *p_bo;
+
+ *p_bo = NULL;
+ if (refcount_release(&bo->kref))
+ ttm_bo_release(bo);
+}
+
+int ttm_bo_lock_delayed_workqueue(struct ttm_bo_device *bdev)
+{
+ int pending;
+
+ taskqueue_cancel_timeout(taskqueue_thread, &bdev->wq, &pending);
+ if (pending)
+ taskqueue_drain_timeout(taskqueue_thread, &bdev->wq);
+ return (pending);
+}
+
+void ttm_bo_unlock_delayed_workqueue(struct ttm_bo_device *bdev, int resched)
+{
+ if (resched) {
+ taskqueue_enqueue_timeout(taskqueue_thread, &bdev->wq,
+ ((hz / 100) < 1) ? 1 : hz / 100);
+ }
+}
+
+static int ttm_bo_evict(struct ttm_buffer_object *bo, bool interruptible,
+ bool no_wait_gpu)
+{
+ struct ttm_bo_device *bdev = bo->bdev;
+ struct ttm_mem_reg evict_mem;
+ struct ttm_placement placement;
+ int ret = 0;
+
+ mtx_lock(&bdev->fence_lock);
+ ret = ttm_bo_wait(bo, false, interruptible, no_wait_gpu);
+ mtx_unlock(&bdev->fence_lock);
+
+ if (unlikely(ret != 0)) {
+ if (ret != -ERESTART) {
+ printf("[TTM] Failed to expire sync object before buffer eviction\n");
+ }
+ goto out;
+ }
+
+ MPASS(ttm_bo_is_reserved(bo));
+
+ evict_mem = bo->mem;
+ evict_mem.mm_node = NULL;
+ evict_mem.bus.io_reserved_vm = false;
+ evict_mem.bus.io_reserved_count = 0;
+
+ placement.fpfn = 0;
+ placement.lpfn = 0;
+ placement.num_placement = 0;
+ placement.num_busy_placement = 0;
+ bdev->driver->evict_flags(bo, &placement);
+ ret = ttm_bo_mem_space(bo, &placement, &evict_mem, interruptible,
+ no_wait_gpu);
+ if (ret) {
+ if (ret != -ERESTART) {
+ printf("[TTM] Failed to find memory space for buffer 0x%p eviction\n",
+ bo);
+ ttm_bo_mem_space_debug(bo, &placement);
+ }
+ goto out;
+ }
+
+ ret = ttm_bo_handle_move_mem(bo, &evict_mem, true, interruptible,
+ no_wait_gpu);
+ if (ret) {
+ if (ret != -ERESTART)
+ printf("[TTM] Buffer eviction failed\n");
+ ttm_bo_mem_put(bo, &evict_mem);
+ goto out;
+ }
+ bo->evicted = true;
+out:
+ return ret;
+}
+
+static int ttm_mem_evict_first(struct ttm_bo_device *bdev,
+ uint32_t mem_type,
+ bool interruptible,
+ bool no_wait_gpu)
+{
+ struct ttm_bo_global *glob = bdev->glob;
+ struct ttm_mem_type_manager *man = &bdev->man[mem_type];
+ struct ttm_buffer_object *bo;
+ int ret = -EBUSY, put_count;
+
+ mtx_lock(&glob->lru_lock);
+ list_for_each_entry(bo, &man->lru, lru) {
+ ret = ttm_bo_reserve_locked(bo, false, true, false, 0);
+ if (!ret)
+ break;
+ }
+
+ if (ret) {
+ mtx_unlock(&glob->lru_lock);
+ return ret;
+ }
+
+ refcount_acquire(&bo->list_kref);
+
+ if (!list_empty(&bo->ddestroy)) {
+ ret = ttm_bo_cleanup_refs_and_unlock(bo, interruptible,
+ no_wait_gpu);
+ if (refcount_release(&bo->list_kref))
+ ttm_bo_release_list(bo);
+ return ret;
+ }
+
+ put_count = ttm_bo_del_from_lru(bo);
+ mtx_unlock(&glob->lru_lock);
+
+ MPASS(ret == 0);
+
+ ttm_bo_list_ref_sub(bo, put_count, true);
+
+ ret = ttm_bo_evict(bo, interruptible, no_wait_gpu);
+ ttm_bo_unreserve(bo);
+
+ if (refcount_release(&bo->list_kref))
+ ttm_bo_release_list(bo);
+ return ret;
+}
+
+void ttm_bo_mem_put(struct ttm_buffer_object *bo, struct ttm_mem_reg *mem)
+{
+ struct ttm_mem_type_manager *man = &bo->bdev->man[mem->mem_type];
+
+ if (mem->mm_node)
+ (*man->func->put_node)(man, mem);
+}
+
+/**
+ * Repeatedly evict memory from the LRU for @mem_type until we create enough
+ * space, or we've evicted everything and there isn't enough space.
+ */
+static int ttm_bo_mem_force_space(struct ttm_buffer_object *bo,
+ uint32_t mem_type,
+ struct ttm_placement *placement,
+ struct ttm_mem_reg *mem,
+ bool interruptible,
+ bool no_wait_gpu)
+{
+ struct ttm_bo_device *bdev = bo->bdev;
+ struct ttm_mem_type_manager *man = &bdev->man[mem_type];
+ int ret;
+
+ do {
+ ret = (*man->func->get_node)(man, bo, placement, mem);
+ if (unlikely(ret != 0))
+ return ret;
+ if (mem->mm_node)
+ break;
+ ret = ttm_mem_evict_first(bdev, mem_type,
+ interruptible, no_wait_gpu);
+ if (unlikely(ret != 0))
+ return ret;
+ } while (1);
+ if (mem->mm_node == NULL)
+ return -ENOMEM;
+ mem->mem_type = mem_type;
+ return 0;
+}
+
+static uint32_t ttm_bo_select_caching(struct ttm_mem_type_manager *man,
+ uint32_t cur_placement,
+ uint32_t proposed_placement)
+{
+ uint32_t caching = proposed_placement & TTM_PL_MASK_CACHING;
+ uint32_t result = proposed_placement & ~TTM_PL_MASK_CACHING;
+
+ /**
+ * Keep current caching if possible.
+ */
+
+ if ((cur_placement & caching) != 0)
+ result |= (cur_placement & caching);
+ else if ((man->default_caching & caching) != 0)
+ result |= man->default_caching;
+ else if ((TTM_PL_FLAG_CACHED & caching) != 0)
+ result |= TTM_PL_FLAG_CACHED;
+ else if ((TTM_PL_FLAG_WC & caching) != 0)
+ result |= TTM_PL_FLAG_WC;
+ else if ((TTM_PL_FLAG_UNCACHED & caching) != 0)
+ result |= TTM_PL_FLAG_UNCACHED;
+
+ return result;
+}
+
+static bool ttm_bo_mt_compatible(struct ttm_mem_type_manager *man,
+ uint32_t mem_type,
+ uint32_t proposed_placement,
+ uint32_t *masked_placement)
+{
+ uint32_t cur_flags = ttm_bo_type_flags(mem_type);
+
+ if ((cur_flags & proposed_placement & TTM_PL_MASK_MEM) == 0)
+ return false;
+
+ if ((proposed_placement & man->available_caching) == 0)
+ return false;
+
+ cur_flags |= (proposed_placement & man->available_caching);
+
+ *masked_placement = cur_flags;
+ return true;
+}
+
+/**
+ * Creates space for memory region @mem according to its type.
+ *
+ * This function first searches for free space in compatible memory types in
+ * the priority order defined by the driver. If free space isn't found, then
+ * ttm_bo_mem_force_space is attempted in priority order to evict and find
+ * space.
+ */
+int ttm_bo_mem_space(struct ttm_buffer_object *bo,
+ struct ttm_placement *placement,
+ struct ttm_mem_reg *mem,
+ bool interruptible,
+ bool no_wait_gpu)
+{
+ struct ttm_bo_device *bdev = bo->bdev;
+ struct ttm_mem_type_manager *man;
+ uint32_t mem_type = TTM_PL_SYSTEM;
+ uint32_t cur_flags = 0;
+ bool type_found = false;
+ bool type_ok = false;
+ bool has_erestartsys = false;
+ int i, ret;
+
+ mem->mm_node = NULL;
+ for (i = 0; i < placement->num_placement; ++i) {
+ ret = ttm_mem_type_from_flags(placement->placement[i],
+ &mem_type);
+ if (ret)
+ return ret;
+ man = &bdev->man[mem_type];
+
+ type_ok = ttm_bo_mt_compatible(man,
+ mem_type,
+ placement->placement[i],
+ &cur_flags);
+
+ if (!type_ok)
+ continue;
+
+ cur_flags = ttm_bo_select_caching(man, bo->mem.placement,
+ cur_flags);
+ /*
+ * Use the access and other non-mapping-related flag bits from
+ * the memory placement flags to the current flags
+ */
+ ttm_flag_masked(&cur_flags, placement->placement[i],
+ ~TTM_PL_MASK_MEMTYPE);
+
+ if (mem_type == TTM_PL_SYSTEM)
+ break;
+
+ if (man->has_type && man->use_type) {
+ type_found = true;
+ ret = (*man->func->get_node)(man, bo, placement, mem);
+ if (unlikely(ret))
+ return ret;
+ }
+ if (mem->mm_node)
+ break;
+ }
+
+ if ((type_ok && (mem_type == TTM_PL_SYSTEM)) || mem->mm_node) {
+ mem->mem_type = mem_type;
+ mem->placement = cur_flags;
+ return 0;
+ }
+
+ if (!type_found)
+ return -EINVAL;
+
+ for (i = 0; i < placement->num_busy_placement; ++i) {
+ ret = ttm_mem_type_from_flags(placement->busy_placement[i],
+ &mem_type);
+ if (ret)
+ return ret;
+ man = &bdev->man[mem_type];
+ if (!man->has_type)
+ continue;
+ if (!ttm_bo_mt_compatible(man,
+ mem_type,
+ placement->busy_placement[i],
+ &cur_flags))
+ continue;
+
+ cur_flags = ttm_bo_select_caching(man, bo->mem.placement,
+ cur_flags);
+ /*
+ * Use the access and other non-mapping-related flag bits from
+ * the memory placement flags to the current flags
+ */
+ ttm_flag_masked(&cur_flags, placement->busy_placement[i],
+ ~TTM_PL_MASK_MEMTYPE);
+
+
+ if (mem_type == TTM_PL_SYSTEM) {
+ mem->mem_type = mem_type;
+ mem->placement = cur_flags;
+ mem->mm_node = NULL;
+ return 0;
+ }
+
+ ret = ttm_bo_mem_force_space(bo, mem_type, placement, mem,
+ interruptible, no_wait_gpu);
+ if (ret == 0 && mem->mm_node) {
+ mem->placement = cur_flags;
+ return 0;
+ }
+ if (ret == -ERESTART)
+ has_erestartsys = true;
+ }
+ ret = (has_erestartsys) ? -ERESTART : -ENOMEM;
+ return ret;
+}
+
+static
+int ttm_bo_move_buffer(struct ttm_buffer_object *bo,
+ struct ttm_placement *placement,
+ bool interruptible,
+ bool no_wait_gpu)
+{
+ int ret = 0;
+ struct ttm_mem_reg mem;
+ struct ttm_bo_device *bdev = bo->bdev;
+
+ MPASS(ttm_bo_is_reserved(bo));
+
+ /*
+ * FIXME: It's possible to pipeline buffer moves.
+ * Have the driver move function wait for idle when necessary,
+ * instead of doing it here.
+ */
+ mtx_lock(&bdev->fence_lock);
+ ret = ttm_bo_wait(bo, false, interruptible, no_wait_gpu);
+ mtx_unlock(&bdev->fence_lock);
+ if (ret)
+ return ret;
+ mem.num_pages = bo->num_pages;
+ mem.size = mem.num_pages << PAGE_SHIFT;
+ mem.page_alignment = bo->mem.page_alignment;
+ mem.bus.io_reserved_vm = false;
+ mem.bus.io_reserved_count = 0;
+ /*
+ * Determine where to move the buffer.
+ */
+ ret = ttm_bo_mem_space(bo, placement, &mem,
+ interruptible, no_wait_gpu);
+ if (ret)
+ goto out_unlock;
+ ret = ttm_bo_handle_move_mem(bo, &mem, false,
+ interruptible, no_wait_gpu);
+out_unlock:
+ if (ret && mem.mm_node)
+ ttm_bo_mem_put(bo, &mem);
+ return ret;
+}
+
+static int ttm_bo_mem_compat(struct ttm_placement *placement,
+ struct ttm_mem_reg *mem)
+{
+ int i;
+
+ if (mem->mm_node && placement->lpfn != 0 &&
+ (mem->start < placement->fpfn ||
+ mem->start + mem->num_pages > placement->lpfn))
+ return -1;
+
+ for (i = 0; i < placement->num_placement; i++) {
+ if ((placement->placement[i] & mem->placement &
+ TTM_PL_MASK_CACHING) &&
+ (placement->placement[i] & mem->placement &
+ TTM_PL_MASK_MEM))
+ return i;
+ }
+ return -1;
+}
+
+int ttm_bo_validate(struct ttm_buffer_object *bo,
+ struct ttm_placement *placement,
+ bool interruptible,
+ bool no_wait_gpu)
+{
+ int ret;
+
+ MPASS(ttm_bo_is_reserved(bo));
+ /* Check that range is valid */
+ if (placement->lpfn || placement->fpfn)
+ if (placement->fpfn > placement->lpfn ||
+ (placement->lpfn - placement->fpfn) < bo->num_pages)
+ return -EINVAL;
+ /*
+ * Check whether we need to move buffer.
+ */
+ ret = ttm_bo_mem_compat(placement, &bo->mem);
+ if (ret < 0) {
+ ret = ttm_bo_move_buffer(bo, placement, interruptible,
+ no_wait_gpu);
+ if (ret)
+ return ret;
+ } else {
+ /*
+ * Use the access and other non-mapping-related flag bits from
+ * the compatible memory placement flags to the active flags
+ */
+ ttm_flag_masked(&bo->mem.placement, placement->placement[ret],
+ ~TTM_PL_MASK_MEMTYPE);
+ }
+ /*
+ * We might need to add a TTM.
+ */
+ if (bo->mem.mem_type == TTM_PL_SYSTEM && bo->ttm == NULL) {
+ ret = ttm_bo_add_ttm(bo, true);
+ if (ret)
+ return ret;
+ }
+ return 0;
+}
+
+int ttm_bo_check_placement(struct ttm_buffer_object *bo,
+ struct ttm_placement *placement)
+{
+ MPASS(!((placement->fpfn || placement->lpfn) &&
+ (bo->mem.num_pages > (placement->lpfn - placement->fpfn))));
+
+ return 0;
+}
+
+int ttm_bo_init(struct ttm_bo_device *bdev,
+ struct ttm_buffer_object *bo,
+ unsigned long size,
+ enum ttm_bo_type type,
+ struct ttm_placement *placement,
+ uint32_t page_alignment,
+ bool interruptible,
+ struct vm_object *persistent_swap_storage,
+ size_t acc_size,
+ struct sg_table *sg,
+ void (*destroy) (struct ttm_buffer_object *))
+{
+ int ret = 0;
+ unsigned long num_pages;
+ struct ttm_mem_global *mem_glob = bdev->glob->mem_glob;
+
+ ret = ttm_mem_global_alloc(mem_glob, acc_size, false, false);
+ if (ret) {
+ printf("[TTM] Out of kernel memory\n");
+ if (destroy)
+ (*destroy)(bo);
+ else
+ free(bo, M_TTM_BO);
+ return -ENOMEM;
+ }
+
+ num_pages = (size + PAGE_SIZE - 1) >> PAGE_SHIFT;
+ if (num_pages == 0) {
+ printf("[TTM] Illegal buffer object size\n");
+ if (destroy)
+ (*destroy)(bo);
+ else
+ free(bo, M_TTM_BO);
+ ttm_mem_global_free(mem_glob, acc_size);
+ return -EINVAL;
+ }
+ bo->destroy = destroy;
+
+ refcount_init(&bo->kref, 1);
+ refcount_init(&bo->list_kref, 1);
+ atomic_set(&bo->cpu_writers, 0);
+ atomic_set(&bo->reserved, 1);
+ INIT_LIST_HEAD(&bo->lru);
+ INIT_LIST_HEAD(&bo->ddestroy);
+ INIT_LIST_HEAD(&bo->swap);
+ INIT_LIST_HEAD(&bo->io_reserve_lru);
+ bo->bdev = bdev;
+ bo->glob = bdev->glob;
+ bo->type = type;
+ bo->num_pages = num_pages;
+ bo->mem.size = num_pages << PAGE_SHIFT;
+ bo->mem.mem_type = TTM_PL_SYSTEM;
+ bo->mem.num_pages = bo->num_pages;
+ bo->mem.mm_node = NULL;
+ bo->mem.page_alignment = page_alignment;
+ bo->mem.bus.io_reserved_vm = false;
+ bo->mem.bus.io_reserved_count = 0;
+ bo->priv_flags = 0;
+ bo->mem.placement = (TTM_PL_FLAG_SYSTEM | TTM_PL_FLAG_CACHED);
+ bo->seq_valid = false;
+ bo->persistent_swap_storage = persistent_swap_storage;
+ bo->acc_size = acc_size;
+ bo->sg = sg;
+ atomic_inc(&bo->glob->bo_count);
+
+ ret = ttm_bo_check_placement(bo, placement);
+ if (unlikely(ret != 0))
+ goto out_err;
+
+ /*
+ * For ttm_bo_type_device buffers, allocate
+ * address space from the device.
+ */
+ if (bo->type == ttm_bo_type_device ||
+ bo->type == ttm_bo_type_sg) {
+ ret = ttm_bo_setup_vm(bo);
+ if (ret)
+ goto out_err;
+ }
+
+ ret = ttm_bo_validate(bo, placement, interruptible, false);
+ if (ret)
+ goto out_err;
+
+ ttm_bo_unreserve(bo);
+ return 0;
+
+out_err:
+ ttm_bo_unreserve(bo);
+ ttm_bo_unref(&bo);
+
+ return ret;
+}
+
+size_t ttm_bo_acc_size(struct ttm_bo_device *bdev,
+ unsigned long bo_size,
+ unsigned struct_size)
+{
+ unsigned npages = (PAGE_ALIGN(bo_size)) >> PAGE_SHIFT;
+ size_t size = 0;
+
+ size += ttm_round_pot(struct_size);
+ size += PAGE_ALIGN(npages * sizeof(void *));
+ size += ttm_round_pot(sizeof(struct ttm_tt));
+ return size;
+}
+
+size_t ttm_bo_dma_acc_size(struct ttm_bo_device *bdev,
+ unsigned long bo_size,
+ unsigned struct_size)
+{
+ unsigned npages = (PAGE_ALIGN(bo_size)) >> PAGE_SHIFT;
+ size_t size = 0;
+
+ size += ttm_round_pot(struct_size);
+ size += PAGE_ALIGN(npages * sizeof(void *));
+ size += PAGE_ALIGN(npages * sizeof(dma_addr_t));
+ size += ttm_round_pot(sizeof(struct ttm_dma_tt));
+ return size;
+}
+
+int ttm_bo_create(struct ttm_bo_device *bdev,
+ unsigned long size,
+ enum ttm_bo_type type,
+ struct ttm_placement *placement,
+ uint32_t page_alignment,
+ bool interruptible,
+ struct vm_object *persistent_swap_storage,
+ struct ttm_buffer_object **p_bo)
+{
+ struct ttm_buffer_object *bo;
+ size_t acc_size;
+ int ret;
+
+ bo = malloc(sizeof(*bo), M_TTM_BO, M_WAITOK | M_ZERO);
+ acc_size = ttm_bo_acc_size(bdev, size, sizeof(struct ttm_buffer_object));
+ ret = ttm_bo_init(bdev, bo, size, type, placement, page_alignment,
+ interruptible, persistent_swap_storage, acc_size,
+ NULL, NULL);
+ if (likely(ret == 0))
+ *p_bo = bo;
+
+ return ret;
+}
+
+static int ttm_bo_force_list_clean(struct ttm_bo_device *bdev,
+ unsigned mem_type, bool allow_errors)
+{
+ struct ttm_mem_type_manager *man = &bdev->man[mem_type];
+ struct ttm_bo_global *glob = bdev->glob;
+ int ret;
+
+ /*
+ * Can't use standard list traversal since we're unlocking.
+ */
+
+ mtx_lock(&glob->lru_lock);
+ while (!list_empty(&man->lru)) {
+ mtx_unlock(&glob->lru_lock);
+ ret = ttm_mem_evict_first(bdev, mem_type, false, false);
+ if (ret) {
+ if (allow_errors) {
+ return ret;
+ } else {
+ printf("[TTM] Cleanup eviction failed\n");
+ }
+ }
+ mtx_lock(&glob->lru_lock);
+ }
+ mtx_unlock(&glob->lru_lock);
+ return 0;
+}
+
+int ttm_bo_clean_mm(struct ttm_bo_device *bdev, unsigned mem_type)
+{
+ struct ttm_mem_type_manager *man;
+ int ret = -EINVAL;
+
+ if (mem_type >= TTM_NUM_MEM_TYPES) {
+ printf("[TTM] Illegal memory type %d\n", mem_type);
+ return ret;
+ }
+ man = &bdev->man[mem_type];
+
+ if (!man->has_type) {
+ printf("[TTM] Trying to take down uninitialized memory manager type %u\n",
+ mem_type);
+ return ret;
+ }
+
+ man->use_type = false;
+ man->has_type = false;
+
+ ret = 0;
+ if (mem_type > 0) {
+ ttm_bo_force_list_clean(bdev, mem_type, false);
+
+ ret = (*man->func->takedown)(man);
+ }
+
+ return ret;
+}
+
+int ttm_bo_evict_mm(struct ttm_bo_device *bdev, unsigned mem_type)
+{
+ struct ttm_mem_type_manager *man = &bdev->man[mem_type];
+
+ if (mem_type == 0 || mem_type >= TTM_NUM_MEM_TYPES) {
+ printf("[TTM] Illegal memory manager memory type %u\n", mem_type);
+ return -EINVAL;
+ }
+
+ if (!man->has_type) {
+ printf("[TTM] Memory type %u has not been initialized\n", mem_type);
+ return 0;
+ }
+
+ return ttm_bo_force_list_clean(bdev, mem_type, true);
+}
+
+int ttm_bo_init_mm(struct ttm_bo_device *bdev, unsigned type,
+ unsigned long p_size)
+{
+ int ret = -EINVAL;
+ struct ttm_mem_type_manager *man;
+
+ MPASS(type < TTM_NUM_MEM_TYPES);
+ man = &bdev->man[type];
+ MPASS(!man->has_type);
+ man->io_reserve_fastpath = true;
+ man->use_io_reserve_lru = false;
+ sx_init(&man->io_reserve_mutex, "ttmman");
+ INIT_LIST_HEAD(&man->io_reserve_lru);
+
+ ret = bdev->driver->init_mem_type(bdev, type, man);
+ if (ret)
+ return ret;
+ man->bdev = bdev;
+
+ ret = 0;
+ if (type != TTM_PL_SYSTEM) {
+ ret = (*man->func->init)(man, p_size);
+ if (ret)
+ return ret;
+ }
+ man->has_type = true;
+ man->use_type = true;
+ man->size = p_size;
+
+ INIT_LIST_HEAD(&man->lru);
+
+ return 0;
+}
+
+static void ttm_bo_global_kobj_release(struct ttm_bo_global *glob)
+{
+
+ ttm_mem_unregister_shrink(glob->mem_glob, &glob->shrink);
+ vm_page_free(glob->dummy_read_page);
+ free(glob, M_DRM_GLOBAL);
+}
+
+void ttm_bo_global_release(struct drm_global_reference *ref)
+{
+ struct ttm_bo_global *glob = ref->object;
+
+ if (refcount_release(&glob->kobj_ref))
+ ttm_bo_global_kobj_release(glob);
+}
+
+int ttm_bo_global_init(struct drm_global_reference *ref)
+{
+ struct ttm_bo_global_ref *bo_ref =
+ container_of(ref, struct ttm_bo_global_ref, ref);
+ struct ttm_bo_global *glob = ref->object;
+ int ret;
+
+ sx_init(&glob->device_list_mutex, "ttmdlm");
+ mtx_init(&glob->lru_lock, "ttmlru", NULL, MTX_DEF);
+ glob->mem_glob = bo_ref->mem_glob;
+ glob->dummy_read_page = vm_page_alloc_contig(NULL, 0,
+ VM_ALLOC_NORMAL | VM_ALLOC_NOOBJ,
+ 1, 0, VM_MAX_ADDRESS, PAGE_SIZE, 0, VM_MEMATTR_UNCACHEABLE);
+
+ if (unlikely(glob->dummy_read_page == NULL)) {
+ ret = -ENOMEM;
+ goto out_no_drp;
+ }
+
+ INIT_LIST_HEAD(&glob->swap_lru);
+ INIT_LIST_HEAD(&glob->device_list);
+
+ ttm_mem_init_shrink(&glob->shrink, ttm_bo_swapout);
+ ret = ttm_mem_register_shrink(glob->mem_glob, &glob->shrink);
+ if (unlikely(ret != 0)) {
+ printf("[TTM] Could not register buffer object swapout\n");
+ goto out_no_shrink;
+ }
+
+ atomic_set(&glob->bo_count, 0);
+
+ refcount_init(&glob->kobj_ref, 1);
+ return (0);
+
+out_no_shrink:
+ vm_page_free(glob->dummy_read_page);
+out_no_drp:
+ free(glob, M_DRM_GLOBAL);
+ return ret;
+}
+
+int ttm_bo_device_release(struct ttm_bo_device *bdev)
+{
+ int ret = 0;
+ unsigned i = TTM_NUM_MEM_TYPES;
+ struct ttm_mem_type_manager *man;
+ struct ttm_bo_global *glob = bdev->glob;
+
+ while (i--) {
+ man = &bdev->man[i];
+ if (man->has_type) {
+ man->use_type = false;
+ if ((i != TTM_PL_SYSTEM) && ttm_bo_clean_mm(bdev, i)) {
+ ret = -EBUSY;
+ printf("[TTM] DRM memory manager type %d is not clean\n",
+ i);
+ }
+ man->has_type = false;
+ }
+ }
+
+ sx_xlock(&glob->device_list_mutex);
+ list_del(&bdev->device_list);
+ sx_xunlock(&glob->device_list_mutex);
+
+ if (taskqueue_cancel_timeout(taskqueue_thread, &bdev->wq, NULL))
+ taskqueue_drain_timeout(taskqueue_thread, &bdev->wq);
+
+ while (ttm_bo_delayed_delete(bdev, true))
+ ;
+
+ mtx_lock(&glob->lru_lock);
+ if (list_empty(&bdev->ddestroy))
+ TTM_DEBUG("Delayed destroy list was clean\n");
+
+ if (list_empty(&bdev->man[0].lru))
+ TTM_DEBUG("Swap list was clean\n");
+ mtx_unlock(&glob->lru_lock);
+
+ MPASS(drm_mm_clean(&bdev->addr_space_mm));
+ rw_wlock(&bdev->vm_lock);
+ drm_mm_takedown(&bdev->addr_space_mm);
+ rw_wunlock(&bdev->vm_lock);
+
+ return ret;
+}
+
+int ttm_bo_device_init(struct ttm_bo_device *bdev,
+ struct ttm_bo_global *glob,
+ struct ttm_bo_driver *driver,
+ uint64_t file_page_offset,
+ bool need_dma32)
+{
+ int ret = -EINVAL;
+
+ rw_init(&bdev->vm_lock, "ttmvml");
+ bdev->driver = driver;
+
+ memset(bdev->man, 0, sizeof(bdev->man));
+
+ /*
+ * Initialize the system memory buffer type.
+ * Other types need to be driver / IOCTL initialized.
+ */
+ ret = ttm_bo_init_mm(bdev, TTM_PL_SYSTEM, 0);
+ if (unlikely(ret != 0))
+ goto out_no_sys;
+
+ RB_INIT(&bdev->addr_space_rb);
+ ret = drm_mm_init(&bdev->addr_space_mm, file_page_offset, 0x10000000);
+ if (unlikely(ret != 0))
+ goto out_no_addr_mm;
+
+ TIMEOUT_TASK_INIT(taskqueue_thread, &bdev->wq, 0,
+ ttm_bo_delayed_workqueue, bdev);
+ INIT_LIST_HEAD(&bdev->ddestroy);
+ bdev->dev_mapping = NULL;
+ bdev->glob = glob;
+ bdev->need_dma32 = need_dma32;
+ bdev->val_seq = 0;
+ mtx_init(&bdev->fence_lock, "ttmfence", NULL, MTX_DEF);
+ sx_xlock(&glob->device_list_mutex);
+ list_add_tail(&bdev->device_list, &glob->device_list);
+ sx_xunlock(&glob->device_list_mutex);
+
+ return 0;
+out_no_addr_mm:
+ ttm_bo_clean_mm(bdev, 0);
+out_no_sys:
+ return ret;
+}
+
+/*
+ * buffer object vm functions.
+ */
+
+bool ttm_mem_reg_is_pci(struct ttm_bo_device *bdev, struct ttm_mem_reg *mem)
+{
+ struct ttm_mem_type_manager *man = &bdev->man[mem->mem_type];
+
+ if (!(man->flags & TTM_MEMTYPE_FLAG_FIXED)) {
+ if (mem->mem_type == TTM_PL_SYSTEM)
+ return false;
+
+ if (man->flags & TTM_MEMTYPE_FLAG_CMA)
+ return false;
+
+ if (mem->placement & TTM_PL_FLAG_CACHED)
+ return false;
+ }
+ return true;
+}
+
+void ttm_bo_unmap_virtual_locked(struct ttm_buffer_object *bo)
+{
+ struct ttm_bo_device *bdev = bo->bdev;
+ /* off_t offset = (off_t)bo->addr_space_offset;XXXKIB */
+ /* off_t holelen = ((off_t)bo->mem.num_pages) << PAGE_SHIFT;XXXKIB */
+
+ if (!bdev->dev_mapping)
+ return;
+ /* unmap_mapping_range(bdev->dev_mapping, offset, holelen, 1); XXXKIB */
+ ttm_mem_io_free_vm(bo);
+}
+
+void ttm_bo_unmap_virtual(struct ttm_buffer_object *bo)
+{
+ struct ttm_bo_device *bdev = bo->bdev;
+ struct ttm_mem_type_manager *man = &bdev->man[bo->mem.mem_type];
+
+ ttm_mem_io_lock(man, false);
+ ttm_bo_unmap_virtual_locked(bo);
+ ttm_mem_io_unlock(man);
+}
+
+static void ttm_bo_vm_insert_rb(struct ttm_buffer_object *bo)
+{
+ struct ttm_bo_device *bdev = bo->bdev;
+
+ /* The caller acquired bdev->vm_lock. */
+ RB_INSERT(ttm_bo_device_buffer_objects, &bdev->addr_space_rb, bo);
+}
+
+/**
+ * ttm_bo_setup_vm:
+ *
+ * @bo: the buffer to allocate address space for
+ *
+ * Allocate address space in the drm device so that applications
+ * can mmap the buffer and access the contents. This only
+ * applies to ttm_bo_type_device objects as others are not
+ * placed in the drm device address space.
+ */
+
+static int ttm_bo_setup_vm(struct ttm_buffer_object *bo)
+{
+ struct ttm_bo_device *bdev = bo->bdev;
+ int ret;
+
+retry_pre_get:
+ ret = drm_mm_pre_get(&bdev->addr_space_mm);
+ if (unlikely(ret != 0))
+ return ret;
+
+ rw_wlock(&bdev->vm_lock);
+ bo->vm_node = drm_mm_search_free(&bdev->addr_space_mm,
+ bo->mem.num_pages, 0, 0);
+
+ if (unlikely(bo->vm_node == NULL)) {
+ ret = -ENOMEM;
+ goto out_unlock;
+ }
+
+ bo->vm_node = drm_mm_get_block_atomic(bo->vm_node,
+ bo->mem.num_pages, 0);
+
+ if (unlikely(bo->vm_node == NULL)) {
+ rw_wunlock(&bdev->vm_lock);
+ goto retry_pre_get;
+ }
+
+ ttm_bo_vm_insert_rb(bo);
+ rw_wunlock(&bdev->vm_lock);
+ bo->addr_space_offset = ((uint64_t) bo->vm_node->start) << PAGE_SHIFT;
+
+ return 0;
+out_unlock:
+ rw_wunlock(&bdev->vm_lock);
+ return ret;
+}
+
+int ttm_bo_wait(struct ttm_buffer_object *bo,
+ bool lazy, bool interruptible, bool no_wait)
+{
+ struct ttm_bo_driver *driver = bo->bdev->driver;
+ struct ttm_bo_device *bdev = bo->bdev;
+ void *sync_obj;
+ int ret = 0;
+
+ if (likely(bo->sync_obj == NULL))
+ return 0;
+
+ while (bo->sync_obj) {
+
+ if (driver->sync_obj_signaled(bo->sync_obj)) {
+ void *tmp_obj = bo->sync_obj;
+ bo->sync_obj = NULL;
+ clear_bit(TTM_BO_PRIV_FLAG_MOVING, &bo->priv_flags);
+ mtx_unlock(&bdev->fence_lock);
+ driver->sync_obj_unref(&tmp_obj);
+ mtx_lock(&bdev->fence_lock);
+ continue;
+ }
+
+ if (no_wait)
+ return -EBUSY;
+
+ sync_obj = driver->sync_obj_ref(bo->sync_obj);
+ mtx_unlock(&bdev->fence_lock);
+ ret = driver->sync_obj_wait(sync_obj,
+ lazy, interruptible);
+ if (unlikely(ret != 0)) {
+ driver->sync_obj_unref(&sync_obj);
+ mtx_lock(&bdev->fence_lock);
+ return ret;
+ }
+ mtx_lock(&bdev->fence_lock);
+ if (likely(bo->sync_obj == sync_obj)) {
+ void *tmp_obj = bo->sync_obj;
+ bo->sync_obj = NULL;
+ clear_bit(TTM_BO_PRIV_FLAG_MOVING,
+ &bo->priv_flags);
+ mtx_unlock(&bdev->fence_lock);
+ driver->sync_obj_unref(&sync_obj);
+ driver->sync_obj_unref(&tmp_obj);
+ mtx_lock(&bdev->fence_lock);
+ } else {
+ mtx_unlock(&bdev->fence_lock);
+ driver->sync_obj_unref(&sync_obj);
+ mtx_lock(&bdev->fence_lock);
+ }
+ }
+ return 0;
+}
+
+int ttm_bo_synccpu_write_grab(struct ttm_buffer_object *bo, bool no_wait)
+{
+ struct ttm_bo_device *bdev = bo->bdev;
+ int ret = 0;
+
+ /*
+ * Using ttm_bo_reserve makes sure the lru lists are updated.
+ */
+
+ ret = ttm_bo_reserve(bo, true, no_wait, false, 0);
+ if (unlikely(ret != 0))
+ return ret;
+ mtx_lock(&bdev->fence_lock);
+ ret = ttm_bo_wait(bo, false, true, no_wait);
+ mtx_unlock(&bdev->fence_lock);
+ if (likely(ret == 0))
+ atomic_inc(&bo->cpu_writers);
+ ttm_bo_unreserve(bo);
+ return ret;
+}
+
+void ttm_bo_synccpu_write_release(struct ttm_buffer_object *bo)
+{
+ atomic_dec(&bo->cpu_writers);
+}
+
+/**
+ * A buffer object shrink method that tries to swap out the first
+ * buffer object on the bo_global::swap_lru list.
+ */
+
+static int ttm_bo_swapout(struct ttm_mem_shrink *shrink)
+{
+ struct ttm_bo_global *glob =
+ container_of(shrink, struct ttm_bo_global, shrink);
+ struct ttm_buffer_object *bo;
+ int ret = -EBUSY;
+ int put_count;
+ uint32_t swap_placement = (TTM_PL_FLAG_CACHED | TTM_PL_FLAG_SYSTEM);
+
+ mtx_lock(&glob->lru_lock);
+ list_for_each_entry(bo, &glob->swap_lru, swap) {
+ ret = ttm_bo_reserve_locked(bo, false, true, false, 0);
+ if (!ret)
+ break;
+ }
+
+ if (ret) {
+ mtx_unlock(&glob->lru_lock);
+ return ret;
+ }
+
+ refcount_acquire(&bo->list_kref);
+
+ if (!list_empty(&bo->ddestroy)) {
+ ret = ttm_bo_cleanup_refs_and_unlock(bo, false, false);
+ if (refcount_release(&bo->list_kref))
+ ttm_bo_release_list(bo);
+ return ret;
+ }
+
+ put_count = ttm_bo_del_from_lru(bo);
+ mtx_unlock(&glob->lru_lock);
+
+ ttm_bo_list_ref_sub(bo, put_count, true);
+
+ /**
+ * Wait for GPU, then move to system cached.
+ */
+
+ mtx_lock(&bo->bdev->fence_lock);
+ ret = ttm_bo_wait(bo, false, false, false);
+ mtx_unlock(&bo->bdev->fence_lock);
+
+ if (unlikely(ret != 0))
+ goto out;
+
+ if ((bo->mem.placement & swap_placement) != swap_placement) {
+ struct ttm_mem_reg evict_mem;
+
+ evict_mem = bo->mem;
+ evict_mem.mm_node = NULL;
+ evict_mem.placement = TTM_PL_FLAG_SYSTEM | TTM_PL_FLAG_CACHED;
+ evict_mem.mem_type = TTM_PL_SYSTEM;
+
+ ret = ttm_bo_handle_move_mem(bo, &evict_mem, true,
+ false, false);
+ if (unlikely(ret != 0))
+ goto out;
+ }
+
+ ttm_bo_unmap_virtual(bo);
+
+ /**
+ * Swap out. Buffer will be swapped in again as soon as
+ * anyone tries to access a ttm page.
+ */
+
+ if (bo->bdev->driver->swap_notify)
+ bo->bdev->driver->swap_notify(bo);
+
+ ret = ttm_tt_swapout(bo->ttm, bo->persistent_swap_storage);
+out:
+
+ /**
+ *
+ * Unreserve without putting on LRU to avoid swapping out an
+ * already swapped buffer.
+ */
+
+ atomic_set(&bo->reserved, 0);
+ wakeup(bo);
+ if (refcount_release(&bo->list_kref))
+ ttm_bo_release_list(bo);
+ return ret;
+}
+
+void ttm_bo_swapout_all(struct ttm_bo_device *bdev)
+{
+ while (ttm_bo_swapout(&bdev->glob->shrink) == 0)
+ ;
+}
diff --git a/sys/dev/drm2/ttm/ttm_bo_api.h b/sys/dev/drm2/ttm/ttm_bo_api.h
new file mode 100644
index 0000000..4b16ebd
--- /dev/null
+++ b/sys/dev/drm2/ttm/ttm_bo_api.h
@@ -0,0 +1,740 @@
+/**************************************************************************
+ *
+ * Copyright (c) 2006-2009 VMware, Inc., Palo Alto, CA., USA
+ * All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sub license, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the
+ * next paragraph) shall be included in all copies or substantial portions
+ * of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDERS, AUTHORS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM,
+ * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
+ * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
+ * USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ **************************************************************************/
+/*
+ * Authors: Thomas Hellstrom <thellstrom-at-vmware-dot-com>
+ */
+/* $FreeBSD$ */
+
+#ifndef _TTM_BO_API_H_
+#define _TTM_BO_API_H_
+
+#include <dev/drm2/drmP.h>
+
+struct ttm_bo_device;
+
+struct drm_mm_node;
+
+
+/**
+ * struct ttm_placement
+ *
+ * @fpfn: first valid page frame number to put the object
+ * @lpfn: last valid page frame number to put the object
+ * @num_placement: number of preferred placements
+ * @placement: preferred placements
+ * @num_busy_placement: number of preferred placements when need to evict buffer
+ * @busy_placement: preferred placements when need to evict buffer
+ *
+ * Structure indicating the placement you request for an object.
+ */
+struct ttm_placement {
+ unsigned fpfn;
+ unsigned lpfn;
+ unsigned num_placement;
+ const uint32_t *placement;
+ unsigned num_busy_placement;
+ const uint32_t *busy_placement;
+};
+
+/**
+ * struct ttm_bus_placement
+ *
+ * @addr: mapped virtual address
+ * @base: bus base address
+ * @is_iomem: is this io memory ?
+ * @size: size in byte
+ * @offset: offset from the base address
+ * @io_reserved_vm: The VM system has a refcount in @io_reserved_count
+ * @io_reserved_count: Refcounting the numbers of callers to ttm_mem_io_reserve
+ *
+ * Structure indicating the bus placement of an object.
+ */
+struct ttm_bus_placement {
+ void *addr;
+ unsigned long base;
+ unsigned long size;
+ unsigned long offset;
+ bool is_iomem;
+ bool io_reserved_vm;
+ uint64_t io_reserved_count;
+};
+
+
+/**
+ * struct ttm_mem_reg
+ *
+ * @mm_node: Memory manager node.
+ * @size: Requested size of memory region.
+ * @num_pages: Actual size of memory region in pages.
+ * @page_alignment: Page alignment.
+ * @placement: Placement flags.
+ * @bus: Placement on io bus accessible to the CPU
+ *
+ * Structure indicating the placement and space resources used by a
+ * buffer object.
+ */
+
+struct ttm_mem_reg {
+ void *mm_node;
+ unsigned long start;
+ unsigned long size;
+ unsigned long num_pages;
+ uint32_t page_alignment;
+ uint32_t mem_type;
+ uint32_t placement;
+ struct ttm_bus_placement bus;
+};
+
+/**
+ * enum ttm_bo_type
+ *
+ * @ttm_bo_type_device: These are 'normal' buffers that can
+ * be mmapped by user space. Each of these bos occupy a slot in the
+ * device address space, that can be used for normal vm operations.
+ *
+ * @ttm_bo_type_kernel: These buffers are like ttm_bo_type_device buffers,
+ * but they cannot be accessed from user-space. For kernel-only use.
+ *
+ * @ttm_bo_type_sg: Buffer made from dmabuf sg table shared with another
+ * driver.
+ */
+
+enum ttm_bo_type {
+ ttm_bo_type_device,
+ ttm_bo_type_kernel,
+ ttm_bo_type_sg
+};
+
+struct ttm_tt;
+
+/**
+ * struct ttm_buffer_object
+ *
+ * @bdev: Pointer to the buffer object device structure.
+ * @type: The bo type.
+ * @destroy: Destruction function. If NULL, kfree is used.
+ * @num_pages: Actual number of pages.
+ * @addr_space_offset: Address space offset.
+ * @acc_size: Accounted size for this object.
+ * @kref: Reference count of this buffer object. When this refcount reaches
+ * zero, the object is put on the delayed delete list.
+ * @list_kref: List reference count of this buffer object. This member is
+ * used to avoid destruction while the buffer object is still on a list.
+ * Lru lists may keep one refcount, the delayed delete list, and kref != 0
+ * keeps one refcount. When this refcount reaches zero,
+ * the object is destroyed.
+ * @event_queue: Queue for processes waiting on buffer object status change.
+ * @mem: structure describing current placement.
+ * @persistent_swap_storage: Usually the swap storage is deleted for buffers
+ * pinned in physical memory. If this behaviour is not desired, this member
+ * holds a pointer to a persistent shmem object.
+ * @ttm: TTM structure holding system pages.
+ * @evicted: Whether the object was evicted without user-space knowing.
+ * @cpu_writes: For synchronization. Number of cpu writers.
+ * @lru: List head for the lru list.
+ * @ddestroy: List head for the delayed destroy list.
+ * @swap: List head for swap LRU list.
+ * @val_seq: Sequence of the validation holding the @reserved lock.
+ * Used to avoid starvation when many processes compete to validate the
+ * buffer. This member is protected by the bo_device::lru_lock.
+ * @seq_valid: The value of @val_seq is valid. This value is protected by
+ * the bo_device::lru_lock.
+ * @reserved: Deadlock-free lock used for synchronization state transitions.
+ * @sync_obj: Pointer to a synchronization object.
+ * @priv_flags: Flags describing buffer object internal state.
+ * @vm_rb: Rb node for the vm rb tree.
+ * @vm_node: Address space manager node.
+ * @offset: The current GPU offset, which can have different meanings
+ * depending on the memory type. For SYSTEM type memory, it should be 0.
+ * @cur_placement: Hint of current placement.
+ *
+ * Base class for TTM buffer object, that deals with data placement and CPU
+ * mappings. GPU mappings are really up to the driver, but for simpler GPUs
+ * the driver can usually use the placement offset @offset directly as the
+ * GPU virtual address. For drivers implementing multiple
+ * GPU memory manager contexts, the driver should manage the address space
+ * in these contexts separately and use these objects to get the correct
+ * placement and caching for these GPU maps. This makes it possible to use
+ * these objects for even quite elaborate memory management schemes.
+ * The destroy member, the API visibility of this object makes it possible
+ * to derive driver specific types.
+ */
+
+struct ttm_buffer_object {
+ /**
+ * Members constant at init.
+ */
+
+ struct ttm_bo_global *glob;
+ struct ttm_bo_device *bdev;
+ enum ttm_bo_type type;
+ void (*destroy) (struct ttm_buffer_object *);
+ unsigned long num_pages;
+ uint64_t addr_space_offset;
+ size_t acc_size;
+
+ /**
+ * Members not needing protection.
+ */
+
+ u_int kref;
+ u_int list_kref;
+ /* wait_queue_head_t event_queue; */
+
+ /**
+ * Members protected by the bo::reserved lock.
+ */
+
+ struct ttm_mem_reg mem;
+ struct vm_object *persistent_swap_storage;
+ struct ttm_tt *ttm;
+ bool evicted;
+
+ /**
+ * Members protected by the bo::reserved lock only when written to.
+ */
+
+ atomic_t cpu_writers;
+
+ /**
+ * Members protected by the bdev::lru_lock.
+ */
+
+ struct list_head lru;
+ struct list_head ddestroy;
+ struct list_head swap;
+ struct list_head io_reserve_lru;
+ uint32_t val_seq;
+ bool seq_valid;
+
+ /**
+ * Members protected by the bdev::lru_lock
+ * only when written to.
+ */
+
+ atomic_t reserved;
+
+ /**
+ * Members protected by struct buffer_object_device::fence_lock
+ * In addition, setting sync_obj to anything else
+ * than NULL requires bo::reserved to be held. This allows for
+ * checking NULL while reserved but not holding the mentioned lock.
+ */
+
+ void *sync_obj;
+ unsigned long priv_flags;
+
+ /**
+ * Members protected by the bdev::vm_lock
+ */
+
+ RB_ENTRY(ttm_buffer_object) vm_rb;
+ struct drm_mm_node *vm_node;
+
+
+ /**
+ * Special members that are protected by the reserve lock
+ * and the bo::lock when written to. Can be read with
+ * either of these locks held.
+ */
+
+ unsigned long offset;
+ uint32_t cur_placement;
+
+ struct sg_table *sg;
+};
+
+/**
+ * struct ttm_bo_kmap_obj
+ *
+ * @virtual: The current kernel virtual address.
+ * @page: The page when kmap'ing a single page.
+ * @bo_kmap_type: Type of bo_kmap.
+ *
+ * Object describing a kernel mapping. Since a TTM bo may be located
+ * in various memory types with various caching policies, the
+ * mapping can either be an ioremap, a vmap, a kmap or part of a
+ * premapped region.
+ */
+
+#define TTM_BO_MAP_IOMEM_MASK 0x80
+struct ttm_bo_kmap_obj {
+ void *virtual;
+ struct vm_page *page;
+ struct sf_buf *sf;
+ int num_pages;
+ unsigned long size;
+ enum {
+ ttm_bo_map_iomap = 1 | TTM_BO_MAP_IOMEM_MASK,
+ ttm_bo_map_vmap = 2,
+ ttm_bo_map_kmap = 3,
+ ttm_bo_map_premapped = 4 | TTM_BO_MAP_IOMEM_MASK,
+ } bo_kmap_type;
+ struct ttm_buffer_object *bo;
+};
+
+/**
+ * ttm_bo_reference - reference a struct ttm_buffer_object
+ *
+ * @bo: The buffer object.
+ *
+ * Returns a refcounted pointer to a buffer object.
+ */
+
+static inline struct ttm_buffer_object *
+ttm_bo_reference(struct ttm_buffer_object *bo)
+{
+ refcount_acquire(&bo->kref);
+ return bo;
+}
+
+/**
+ * ttm_bo_wait - wait for buffer idle.
+ *
+ * @bo: The buffer object.
+ * @interruptible: Use interruptible wait.
+ * @no_wait: Return immediately if buffer is busy.
+ *
+ * This function must be called with the bo::mutex held, and makes
+ * sure any previous rendering to the buffer is completed.
+ * Note: It might be necessary to block validations before the
+ * wait by reserving the buffer.
+ * Returns -EBUSY if no_wait is true and the buffer is busy.
+ * Returns -ERESTARTSYS if interrupted by a signal.
+ */
+extern int ttm_bo_wait(struct ttm_buffer_object *bo, bool lazy,
+ bool interruptible, bool no_wait);
+/**
+ * ttm_bo_validate
+ *
+ * @bo: The buffer object.
+ * @placement: Proposed placement for the buffer object.
+ * @interruptible: Sleep interruptible if sleeping.
+ * @no_wait_gpu: Return immediately if the GPU is busy.
+ *
+ * Changes placement and caching policy of the buffer object
+ * according proposed placement.
+ * Returns
+ * -EINVAL on invalid proposed placement.
+ * -ENOMEM on out-of-memory condition.
+ * -EBUSY if no_wait is true and buffer busy.
+ * -ERESTARTSYS if interrupted by a signal.
+ */
+extern int ttm_bo_validate(struct ttm_buffer_object *bo,
+ struct ttm_placement *placement,
+ bool interruptible,
+ bool no_wait_gpu);
+
+/**
+ * ttm_bo_unref
+ *
+ * @bo: The buffer object.
+ *
+ * Unreference and clear a pointer to a buffer object.
+ */
+extern void ttm_bo_unref(struct ttm_buffer_object **bo);
+
+
+/**
+ * ttm_bo_list_ref_sub
+ *
+ * @bo: The buffer object.
+ * @count: The number of references with which to decrease @bo::list_kref;
+ * @never_free: The refcount should not reach zero with this operation.
+ *
+ * Release @count lru list references to this buffer object.
+ */
+extern void ttm_bo_list_ref_sub(struct ttm_buffer_object *bo, int count,
+ bool never_free);
+
+/**
+ * ttm_bo_add_to_lru
+ *
+ * @bo: The buffer object.
+ *
+ * Add this bo to the relevant mem type lru and, if it's backed by
+ * system pages (ttms) to the swap list.
+ * This function must be called with struct ttm_bo_global::lru_lock held, and
+ * is typically called immediately prior to unreserving a bo.
+ */
+extern void ttm_bo_add_to_lru(struct ttm_buffer_object *bo);
+
+/**
+ * ttm_bo_del_from_lru
+ *
+ * @bo: The buffer object.
+ *
+ * Remove this bo from all lru lists used to lookup and reserve an object.
+ * This function must be called with struct ttm_bo_global::lru_lock held,
+ * and is usually called just immediately after the bo has been reserved to
+ * avoid recursive reservation from lru lists.
+ */
+extern int ttm_bo_del_from_lru(struct ttm_buffer_object *bo);
+
+
+/**
+ * ttm_bo_lock_delayed_workqueue
+ *
+ * Prevent the delayed workqueue from running.
+ * Returns
+ * True if the workqueue was queued at the time
+ */
+extern int ttm_bo_lock_delayed_workqueue(struct ttm_bo_device *bdev);
+
+/**
+ * ttm_bo_unlock_delayed_workqueue
+ *
+ * Allows the delayed workqueue to run.
+ */
+extern void ttm_bo_unlock_delayed_workqueue(struct ttm_bo_device *bdev,
+ int resched);
+
+/**
+ * ttm_bo_synccpu_write_grab
+ *
+ * @bo: The buffer object:
+ * @no_wait: Return immediately if buffer is busy.
+ *
+ * Synchronizes a buffer object for CPU RW access. This means
+ * command submission that affects the buffer will return -EBUSY
+ * until ttm_bo_synccpu_write_release is called.
+ *
+ * Returns
+ * -EBUSY if the buffer is busy and no_wait is true.
+ * -ERESTARTSYS if interrupted by a signal.
+ */
+extern int
+ttm_bo_synccpu_write_grab(struct ttm_buffer_object *bo, bool no_wait);
+
+/**
+ * ttm_bo_synccpu_write_release:
+ *
+ * @bo : The buffer object.
+ *
+ * Releases a synccpu lock.
+ */
+extern void ttm_bo_synccpu_write_release(struct ttm_buffer_object *bo);
+
+/**
+ * ttm_bo_acc_size
+ *
+ * @bdev: Pointer to a ttm_bo_device struct.
+ * @bo_size: size of the buffer object in byte.
+ * @struct_size: size of the structure holding buffer object datas
+ *
+ * Returns size to account for a buffer object
+ */
+size_t ttm_bo_acc_size(struct ttm_bo_device *bdev,
+ unsigned long bo_size,
+ unsigned struct_size);
+size_t ttm_bo_dma_acc_size(struct ttm_bo_device *bdev,
+ unsigned long bo_size,
+ unsigned struct_size);
+
+/**
+ * ttm_bo_init
+ *
+ * @bdev: Pointer to a ttm_bo_device struct.
+ * @bo: Pointer to a ttm_buffer_object to be initialized.
+ * @size: Requested size of buffer object.
+ * @type: Requested type of buffer object.
+ * @flags: Initial placement flags.
+ * @page_alignment: Data alignment in pages.
+ * @interruptible: If needing to sleep to wait for GPU resources,
+ * sleep interruptible.
+ * @persistent_swap_storage: Usually the swap storage is deleted for buffers
+ * pinned in physical memory. If this behaviour is not desired, this member
+ * holds a pointer to a persistent shmem object. Typically, this would
+ * point to the shmem object backing a GEM object if TTM is used to back a
+ * GEM user interface.
+ * @acc_size: Accounted size for this object.
+ * @destroy: Destroy function. Use NULL for kfree().
+ *
+ * This function initializes a pre-allocated struct ttm_buffer_object.
+ * As this object may be part of a larger structure, this function,
+ * together with the @destroy function,
+ * enables driver-specific objects derived from a ttm_buffer_object.
+ * On successful return, the object kref and list_kref are set to 1.
+ * If a failure occurs, the function will call the @destroy function, or
+ * kfree() if @destroy is NULL. Thus, after a failure, dereferencing @bo is
+ * illegal and will likely cause memory corruption.
+ *
+ * Returns
+ * -ENOMEM: Out of memory.
+ * -EINVAL: Invalid placement flags.
+ * -ERESTARTSYS: Interrupted by signal while sleeping waiting for resources.
+ */
+
+extern int ttm_bo_init(struct ttm_bo_device *bdev,
+ struct ttm_buffer_object *bo,
+ unsigned long size,
+ enum ttm_bo_type type,
+ struct ttm_placement *placement,
+ uint32_t page_alignment,
+ bool interrubtible,
+ struct vm_object *persistent_swap_storage,
+ size_t acc_size,
+ struct sg_table *sg,
+ void (*destroy) (struct ttm_buffer_object *));
+
+/**
+ * ttm_bo_synccpu_object_init
+ *
+ * @bdev: Pointer to a ttm_bo_device struct.
+ * @bo: Pointer to a ttm_buffer_object to be initialized.
+ * @size: Requested size of buffer object.
+ * @type: Requested type of buffer object.
+ * @flags: Initial placement flags.
+ * @page_alignment: Data alignment in pages.
+ * @interruptible: If needing to sleep while waiting for GPU resources,
+ * sleep interruptible.
+ * @persistent_swap_storage: Usually the swap storage is deleted for buffers
+ * pinned in physical memory. If this behaviour is not desired, this member
+ * holds a pointer to a persistent shmem object. Typically, this would
+ * point to the shmem object backing a GEM object if TTM is used to back a
+ * GEM user interface.
+ * @p_bo: On successful completion *p_bo points to the created object.
+ *
+ * This function allocates a ttm_buffer_object, and then calls ttm_bo_init
+ * on that object. The destroy function is set to kfree().
+ * Returns
+ * -ENOMEM: Out of memory.
+ * -EINVAL: Invalid placement flags.
+ * -ERESTARTSYS: Interrupted by signal while waiting for resources.
+ */
+
+extern int ttm_bo_create(struct ttm_bo_device *bdev,
+ unsigned long size,
+ enum ttm_bo_type type,
+ struct ttm_placement *placement,
+ uint32_t page_alignment,
+ bool interruptible,
+ struct vm_object *persistent_swap_storage,
+ struct ttm_buffer_object **p_bo);
+
+/**
+ * ttm_bo_check_placement
+ *
+ * @bo: the buffer object.
+ * @placement: placements
+ *
+ * Performs minimal validity checking on an intended change of
+ * placement flags.
+ * Returns
+ * -EINVAL: Intended change is invalid or not allowed.
+ */
+extern int ttm_bo_check_placement(struct ttm_buffer_object *bo,
+ struct ttm_placement *placement);
+
+/**
+ * ttm_bo_init_mm
+ *
+ * @bdev: Pointer to a ttm_bo_device struct.
+ * @mem_type: The memory type.
+ * @p_size: size managed area in pages.
+ *
+ * Initialize a manager for a given memory type.
+ * Note: if part of driver firstopen, it must be protected from a
+ * potentially racing lastclose.
+ * Returns:
+ * -EINVAL: invalid size or memory type.
+ * -ENOMEM: Not enough memory.
+ * May also return driver-specified errors.
+ */
+
+extern int ttm_bo_init_mm(struct ttm_bo_device *bdev, unsigned type,
+ unsigned long p_size);
+/**
+ * ttm_bo_clean_mm
+ *
+ * @bdev: Pointer to a ttm_bo_device struct.
+ * @mem_type: The memory type.
+ *
+ * Take down a manager for a given memory type after first walking
+ * the LRU list to evict any buffers left alive.
+ *
+ * Normally, this function is part of lastclose() or unload(), and at that
+ * point there shouldn't be any buffers left created by user-space, since
+ * there should've been removed by the file descriptor release() method.
+ * However, before this function is run, make sure to signal all sync objects,
+ * and verify that the delayed delete queue is empty. The driver must also
+ * make sure that there are no NO_EVICT buffers present in this memory type
+ * when the call is made.
+ *
+ * If this function is part of a VT switch, the caller must make sure that
+ * there are no appications currently validating buffers before this
+ * function is called. The caller can do that by first taking the
+ * struct ttm_bo_device::ttm_lock in write mode.
+ *
+ * Returns:
+ * -EINVAL: invalid or uninitialized memory type.
+ * -EBUSY: There are still buffers left in this memory type.
+ */
+
+extern int ttm_bo_clean_mm(struct ttm_bo_device *bdev, unsigned mem_type);
+
+/**
+ * ttm_bo_evict_mm
+ *
+ * @bdev: Pointer to a ttm_bo_device struct.
+ * @mem_type: The memory type.
+ *
+ * Evicts all buffers on the lru list of the memory type.
+ * This is normally part of a VT switch or an
+ * out-of-memory-space-due-to-fragmentation handler.
+ * The caller must make sure that there are no other processes
+ * currently validating buffers, and can do that by taking the
+ * struct ttm_bo_device::ttm_lock in write mode.
+ *
+ * Returns:
+ * -EINVAL: Invalid or uninitialized memory type.
+ * -ERESTARTSYS: The call was interrupted by a signal while waiting to
+ * evict a buffer.
+ */
+
+extern int ttm_bo_evict_mm(struct ttm_bo_device *bdev, unsigned mem_type);
+
+/**
+ * ttm_kmap_obj_virtual
+ *
+ * @map: A struct ttm_bo_kmap_obj returned from ttm_bo_kmap.
+ * @is_iomem: Pointer to an integer that on return indicates 1 if the
+ * virtual map is io memory, 0 if normal memory.
+ *
+ * Returns the virtual address of a buffer object area mapped by ttm_bo_kmap.
+ * If *is_iomem is 1 on return, the virtual address points to an io memory area,
+ * that should strictly be accessed by the iowriteXX() and similar functions.
+ */
+
+static inline void *ttm_kmap_obj_virtual(struct ttm_bo_kmap_obj *map,
+ bool *is_iomem)
+{
+ *is_iomem = !!(map->bo_kmap_type & TTM_BO_MAP_IOMEM_MASK);
+ return map->virtual;
+}
+
+/**
+ * ttm_bo_kmap
+ *
+ * @bo: The buffer object.
+ * @start_page: The first page to map.
+ * @num_pages: Number of pages to map.
+ * @map: pointer to a struct ttm_bo_kmap_obj representing the map.
+ *
+ * Sets up a kernel virtual mapping, using ioremap, vmap or kmap to the
+ * data in the buffer object. The ttm_kmap_obj_virtual function can then be
+ * used to obtain a virtual address to the data.
+ *
+ * Returns
+ * -ENOMEM: Out of memory.
+ * -EINVAL: Invalid range.
+ */
+
+extern int ttm_bo_kmap(struct ttm_buffer_object *bo, unsigned long start_page,
+ unsigned long num_pages, struct ttm_bo_kmap_obj *map);
+
+/**
+ * ttm_bo_kunmap
+ *
+ * @map: Object describing the map to unmap.
+ *
+ * Unmaps a kernel map set up by ttm_bo_kmap.
+ */
+
+extern void ttm_bo_kunmap(struct ttm_bo_kmap_obj *map);
+
+/**
+ * ttm_fbdev_mmap - mmap fbdev memory backed by a ttm buffer object.
+ *
+ * @vma: vma as input from the fbdev mmap method.
+ * @bo: The bo backing the address space. The address space will
+ * have the same size as the bo, and start at offset 0.
+ *
+ * This function is intended to be called by the fbdev mmap method
+ * if the fbdev address space is to be backed by a bo.
+ */
+
+/* XXXKIB
+extern int ttm_fbdev_mmap(struct vm_area_struct *vma,
+ struct ttm_buffer_object *bo);
+*/
+/**
+ * ttm_bo_mmap - mmap out of the ttm device address space.
+ *
+ * @filp: filp as input from the mmap method.
+ * @vma: vma as input from the mmap method.
+ * @bdev: Pointer to the ttm_bo_device with the address space manager.
+ *
+ * This function is intended to be called by the device mmap method.
+ * if the device address space is to be backed by the bo manager.
+ */
+/* XXXKIB
+extern int ttm_bo_mmap(struct file *filp, struct vm_area_struct *vma,
+ struct ttm_bo_device *bdev);
+*/
+/**
+ * ttm_bo_io
+ *
+ * @bdev: Pointer to the struct ttm_bo_device.
+ * @filp: Pointer to the struct file attempting to read / write.
+ * @wbuf: User-space pointer to address of buffer to write. NULL on read.
+ * @rbuf: User-space pointer to address of buffer to read into.
+ * Null on write.
+ * @count: Number of bytes to read / write.
+ * @f_pos: Pointer to current file position.
+ * @write: 1 for read, 0 for write.
+ *
+ * This function implements read / write into ttm buffer objects, and is
+ * intended to
+ * be called from the fops::read and fops::write method.
+ * Returns:
+ * See man (2) write, man(2) read. In particular,
+ * the function may return -ERESTARTSYS if
+ * interrupted by a signal.
+ */
+
+extern ssize_t ttm_bo_io(struct ttm_bo_device *bdev, struct file *filp,
+ const char *wbuf, char *rbuf,
+ size_t count, off_t *f_pos, bool write);
+
+extern void ttm_bo_swapout_all(struct ttm_bo_device *bdev);
+
+/**
+ * ttm_bo_is_reserved - return an indication if a ttm buffer object is reserved
+ *
+ * @bo: The buffer object to check.
+ *
+ * This function returns an indication if a bo is reserved or not, and should
+ * only be used to print an error when it is not from incorrect api usage, since
+ * there's no guarantee that it is the caller that is holding the reservation.
+ */
+static inline bool ttm_bo_is_reserved(struct ttm_buffer_object *bo)
+{
+ return atomic_read(&bo->reserved);
+}
+
+#endif
diff --git a/sys/dev/drm2/ttm/ttm_bo_driver.h b/sys/dev/drm2/ttm/ttm_bo_driver.h
new file mode 100644
index 0000000..3f08976
--- /dev/null
+++ b/sys/dev/drm2/ttm/ttm_bo_driver.h
@@ -0,0 +1,1018 @@
+/**************************************************************************
+ *
+ * Copyright (c) 2006-2009 Vmware, Inc., Palo Alto, CA., USA
+ * All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sub license, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the
+ * next paragraph) shall be included in all copies or substantial portions
+ * of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDERS, AUTHORS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM,
+ * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
+ * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
+ * USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ **************************************************************************/
+/*
+ * Authors: Thomas Hellstrom <thellstrom-at-vmware-dot-com>
+ */
+/* $FreeBSD$ */
+
+#ifndef _TTM_BO_DRIVER_H_
+#define _TTM_BO_DRIVER_H_
+
+#include <dev/drm2/drmP.h>
+#include <dev/drm2/ttm/ttm_bo_api.h>
+#include <dev/drm2/ttm/ttm_memory.h>
+#include <dev/drm2/ttm/ttm_module.h>
+#include <dev/drm2/drm_global.h>
+#include <sys/rwlock.h>
+#include <sys/tree.h>
+
+struct ttm_backend_func {
+ /**
+ * struct ttm_backend_func member bind
+ *
+ * @ttm: Pointer to a struct ttm_tt.
+ * @bo_mem: Pointer to a struct ttm_mem_reg describing the
+ * memory type and location for binding.
+ *
+ * Bind the backend pages into the aperture in the location
+ * indicated by @bo_mem. This function should be able to handle
+ * differences between aperture and system page sizes.
+ */
+ int (*bind) (struct ttm_tt *ttm, struct ttm_mem_reg *bo_mem);
+
+ /**
+ * struct ttm_backend_func member unbind
+ *
+ * @ttm: Pointer to a struct ttm_tt.
+ *
+ * Unbind previously bound backend pages. This function should be
+ * able to handle differences between aperture and system page sizes.
+ */
+ int (*unbind) (struct ttm_tt *ttm);
+
+ /**
+ * struct ttm_backend_func member destroy
+ *
+ * @ttm: Pointer to a struct ttm_tt.
+ *
+ * Destroy the backend. This will be call back from ttm_tt_destroy so
+ * don't call ttm_tt_destroy from the callback or infinite loop.
+ */
+ void (*destroy) (struct ttm_tt *ttm);
+};
+
+#define TTM_PAGE_FLAG_WRITE (1 << 3)
+#define TTM_PAGE_FLAG_SWAPPED (1 << 4)
+#define TTM_PAGE_FLAG_PERSISTENT_SWAP (1 << 5)
+#define TTM_PAGE_FLAG_ZERO_ALLOC (1 << 6)
+#define TTM_PAGE_FLAG_DMA32 (1 << 7)
+#define TTM_PAGE_FLAG_SG (1 << 8)
+
+enum ttm_caching_state {
+ tt_uncached,
+ tt_wc,
+ tt_cached
+};
+
+/**
+ * struct ttm_tt
+ *
+ * @bdev: Pointer to a struct ttm_bo_device.
+ * @func: Pointer to a struct ttm_backend_func that describes
+ * the backend methods.
+ * @dummy_read_page: Page to map where the ttm_tt page array contains a NULL
+ * pointer.
+ * @pages: Array of pages backing the data.
+ * @num_pages: Number of pages in the page array.
+ * @bdev: Pointer to the current struct ttm_bo_device.
+ * @be: Pointer to the ttm backend.
+ * @swap_storage: Pointer to shmem struct file for swap storage.
+ * @caching_state: The current caching state of the pages.
+ * @state: The current binding state of the pages.
+ *
+ * This is a structure holding the pages, caching- and aperture binding
+ * status for a buffer object that isn't backed by fixed (VRAM / AGP)
+ * memory.
+ */
+
+struct ttm_tt {
+ struct ttm_bo_device *bdev;
+ struct ttm_backend_func *func;
+ struct vm_page *dummy_read_page;
+ struct vm_page **pages;
+ uint32_t page_flags;
+ unsigned long num_pages;
+ struct sg_table *sg; /* for SG objects via dma-buf */
+ struct ttm_bo_global *glob;
+ struct vm_object *swap_storage;
+ enum ttm_caching_state caching_state;
+ enum {
+ tt_bound,
+ tt_unbound,
+ tt_unpopulated,
+ } state;
+};
+
+/**
+ * struct ttm_dma_tt
+ *
+ * @ttm: Base ttm_tt struct.
+ * @dma_address: The DMA (bus) addresses of the pages
+ * @pages_list: used by some page allocation backend
+ *
+ * This is a structure holding the pages, caching- and aperture binding
+ * status for a buffer object that isn't backed by fixed (VRAM / AGP)
+ * memory.
+ */
+struct ttm_dma_tt {
+ struct ttm_tt ttm;
+ dma_addr_t *dma_address;
+ struct list_head pages_list;
+};
+
+#define TTM_MEMTYPE_FLAG_FIXED (1 << 0) /* Fixed (on-card) PCI memory */
+#define TTM_MEMTYPE_FLAG_MAPPABLE (1 << 1) /* Memory mappable */
+#define TTM_MEMTYPE_FLAG_CMA (1 << 3) /* Can't map aperture */
+
+struct ttm_mem_type_manager;
+
+struct ttm_mem_type_manager_func {
+ /**
+ * struct ttm_mem_type_manager member init
+ *
+ * @man: Pointer to a memory type manager.
+ * @p_size: Implementation dependent, but typically the size of the
+ * range to be managed in pages.
+ *
+ * Called to initialize a private range manager. The function is
+ * expected to initialize the man::priv member.
+ * Returns 0 on success, negative error code on failure.
+ */
+ int (*init)(struct ttm_mem_type_manager *man, unsigned long p_size);
+
+ /**
+ * struct ttm_mem_type_manager member takedown
+ *
+ * @man: Pointer to a memory type manager.
+ *
+ * Called to undo the setup done in init. All allocated resources
+ * should be freed.
+ */
+ int (*takedown)(struct ttm_mem_type_manager *man);
+
+ /**
+ * struct ttm_mem_type_manager member get_node
+ *
+ * @man: Pointer to a memory type manager.
+ * @bo: Pointer to the buffer object we're allocating space for.
+ * @placement: Placement details.
+ * @mem: Pointer to a struct ttm_mem_reg to be filled in.
+ *
+ * This function should allocate space in the memory type managed
+ * by @man. Placement details if
+ * applicable are given by @placement. If successful,
+ * @mem::mm_node should be set to a non-null value, and
+ * @mem::start should be set to a value identifying the beginning
+ * of the range allocated, and the function should return zero.
+ * If the memory region accommodate the buffer object, @mem::mm_node
+ * should be set to NULL, and the function should return 0.
+ * If a system error occurred, preventing the request to be fulfilled,
+ * the function should return a negative error code.
+ *
+ * Note that @mem::mm_node will only be dereferenced by
+ * struct ttm_mem_type_manager functions and optionally by the driver,
+ * which has knowledge of the underlying type.
+ *
+ * This function may not be called from within atomic context, so
+ * an implementation can and must use either a mutex or a spinlock to
+ * protect any data structures managing the space.
+ */
+ int (*get_node)(struct ttm_mem_type_manager *man,
+ struct ttm_buffer_object *bo,
+ struct ttm_placement *placement,
+ struct ttm_mem_reg *mem);
+
+ /**
+ * struct ttm_mem_type_manager member put_node
+ *
+ * @man: Pointer to a memory type manager.
+ * @mem: Pointer to a struct ttm_mem_reg to be filled in.
+ *
+ * This function frees memory type resources previously allocated
+ * and that are identified by @mem::mm_node and @mem::start. May not
+ * be called from within atomic context.
+ */
+ void (*put_node)(struct ttm_mem_type_manager *man,
+ struct ttm_mem_reg *mem);
+
+ /**
+ * struct ttm_mem_type_manager member debug
+ *
+ * @man: Pointer to a memory type manager.
+ * @prefix: Prefix to be used in printout to identify the caller.
+ *
+ * This function is called to print out the state of the memory
+ * type manager to aid debugging of out-of-memory conditions.
+ * It may not be called from within atomic context.
+ */
+ void (*debug)(struct ttm_mem_type_manager *man, const char *prefix);
+};
+
+/**
+ * struct ttm_mem_type_manager
+ *
+ * @has_type: The memory type has been initialized.
+ * @use_type: The memory type is enabled.
+ * @flags: TTM_MEMTYPE_XX flags identifying the traits of the memory
+ * managed by this memory type.
+ * @gpu_offset: If used, the GPU offset of the first managed page of
+ * fixed memory or the first managed location in an aperture.
+ * @size: Size of the managed region.
+ * @available_caching: A mask of available caching types, TTM_PL_FLAG_XX,
+ * as defined in ttm_placement_common.h
+ * @default_caching: The default caching policy used for a buffer object
+ * placed in this memory type if the user doesn't provide one.
+ * @func: structure pointer implementing the range manager. See above
+ * @priv: Driver private closure for @func.
+ * @io_reserve_mutex: Mutex optionally protecting shared io_reserve structures
+ * @use_io_reserve_lru: Use an lru list to try to unreserve io_mem_regions
+ * reserved by the TTM vm system.
+ * @io_reserve_lru: Optional lru list for unreserving io mem regions.
+ * @io_reserve_fastpath: Only use bdev::driver::io_mem_reserve to obtain
+ * static information. bdev::driver::io_mem_free is never used.
+ * @lru: The lru list for this memory type.
+ *
+ * This structure is used to identify and manage memory types for a device.
+ * It's set up by the ttm_bo_driver::init_mem_type method.
+ */
+
+
+
+struct ttm_mem_type_manager {
+ struct ttm_bo_device *bdev;
+
+ /*
+ * No protection. Constant from start.
+ */
+
+ bool has_type;
+ bool use_type;
+ uint32_t flags;
+ unsigned long gpu_offset;
+ uint64_t size;
+ uint32_t available_caching;
+ uint32_t default_caching;
+ const struct ttm_mem_type_manager_func *func;
+ void *priv;
+ struct sx io_reserve_mutex;
+ bool use_io_reserve_lru;
+ bool io_reserve_fastpath;
+
+ /*
+ * Protected by @io_reserve_mutex:
+ */
+
+ struct list_head io_reserve_lru;
+
+ /*
+ * Protected by the global->lru_lock.
+ */
+
+ struct list_head lru;
+};
+
+/**
+ * struct ttm_bo_driver
+ *
+ * @create_ttm_backend_entry: Callback to create a struct ttm_backend.
+ * @invalidate_caches: Callback to invalidate read caches when a buffer object
+ * has been evicted.
+ * @init_mem_type: Callback to initialize a struct ttm_mem_type_manager
+ * structure.
+ * @evict_flags: Callback to obtain placement flags when a buffer is evicted.
+ * @move: Callback for a driver to hook in accelerated functions to
+ * move a buffer.
+ * If set to NULL, a potentially slow memcpy() move is used.
+ * @sync_obj_signaled: See ttm_fence_api.h
+ * @sync_obj_wait: See ttm_fence_api.h
+ * @sync_obj_flush: See ttm_fence_api.h
+ * @sync_obj_unref: See ttm_fence_api.h
+ * @sync_obj_ref: See ttm_fence_api.h
+ */
+
+struct ttm_bo_driver {
+ /**
+ * ttm_tt_create
+ *
+ * @bdev: pointer to a struct ttm_bo_device:
+ * @size: Size of the data needed backing.
+ * @page_flags: Page flags as identified by TTM_PAGE_FLAG_XX flags.
+ * @dummy_read_page: See struct ttm_bo_device.
+ *
+ * Create a struct ttm_tt to back data with system memory pages.
+ * No pages are actually allocated.
+ * Returns:
+ * NULL: Out of memory.
+ */
+ struct ttm_tt *(*ttm_tt_create)(struct ttm_bo_device *bdev,
+ unsigned long size,
+ uint32_t page_flags,
+ struct vm_page *dummy_read_page);
+
+ /**
+ * ttm_tt_populate
+ *
+ * @ttm: The struct ttm_tt to contain the backing pages.
+ *
+ * Allocate all backing pages
+ * Returns:
+ * -ENOMEM: Out of memory.
+ */
+ int (*ttm_tt_populate)(struct ttm_tt *ttm);
+
+ /**
+ * ttm_tt_unpopulate
+ *
+ * @ttm: The struct ttm_tt to contain the backing pages.
+ *
+ * Free all backing page
+ */
+ void (*ttm_tt_unpopulate)(struct ttm_tt *ttm);
+
+ /**
+ * struct ttm_bo_driver member invalidate_caches
+ *
+ * @bdev: the buffer object device.
+ * @flags: new placement of the rebound buffer object.
+ *
+ * A previosly evicted buffer has been rebound in a
+ * potentially new location. Tell the driver that it might
+ * consider invalidating read (texture) caches on the next command
+ * submission as a consequence.
+ */
+
+ int (*invalidate_caches) (struct ttm_bo_device *bdev, uint32_t flags);
+ int (*init_mem_type) (struct ttm_bo_device *bdev, uint32_t type,
+ struct ttm_mem_type_manager *man);
+ /**
+ * struct ttm_bo_driver member evict_flags:
+ *
+ * @bo: the buffer object to be evicted
+ *
+ * Return the bo flags for a buffer which is not mapped to the hardware.
+ * These will be placed in proposed_flags so that when the move is
+ * finished, they'll end up in bo->mem.flags
+ */
+
+ void(*evict_flags) (struct ttm_buffer_object *bo,
+ struct ttm_placement *placement);
+ /**
+ * struct ttm_bo_driver member move:
+ *
+ * @bo: the buffer to move
+ * @evict: whether this motion is evicting the buffer from
+ * the graphics address space
+ * @interruptible: Use interruptible sleeps if possible when sleeping.
+ * @no_wait: whether this should give up and return -EBUSY
+ * if this move would require sleeping
+ * @new_mem: the new memory region receiving the buffer
+ *
+ * Move a buffer between two memory regions.
+ */
+ int (*move) (struct ttm_buffer_object *bo,
+ bool evict, bool interruptible,
+ bool no_wait_gpu,
+ struct ttm_mem_reg *new_mem);
+
+ /**
+ * struct ttm_bo_driver_member verify_access
+ *
+ * @bo: Pointer to a buffer object.
+ * @filp: Pointer to a struct file trying to access the object.
+ * FreeBSD: use devfs_get_cdevpriv etc.
+ *
+ * Called from the map / write / read methods to verify that the
+ * caller is permitted to access the buffer object.
+ * This member may be set to NULL, which will refuse this kind of
+ * access for all buffer objects.
+ * This function should return 0 if access is granted, -EPERM otherwise.
+ */
+ int (*verify_access) (struct ttm_buffer_object *bo);
+
+ /**
+ * In case a driver writer dislikes the TTM fence objects,
+ * the driver writer can replace those with sync objects of
+ * his / her own. If it turns out that no driver writer is
+ * using these. I suggest we remove these hooks and plug in
+ * fences directly. The bo driver needs the following functionality:
+ * See the corresponding functions in the fence object API
+ * documentation.
+ */
+
+ bool (*sync_obj_signaled) (void *sync_obj);
+ int (*sync_obj_wait) (void *sync_obj,
+ bool lazy, bool interruptible);
+ int (*sync_obj_flush) (void *sync_obj);
+ void (*sync_obj_unref) (void **sync_obj);
+ void *(*sync_obj_ref) (void *sync_obj);
+
+ /* hook to notify driver about a driver move so it
+ * can do tiling things */
+ void (*move_notify)(struct ttm_buffer_object *bo,
+ struct ttm_mem_reg *new_mem);
+ /* notify the driver we are taking a fault on this BO
+ * and have reserved it */
+ int (*fault_reserve_notify)(struct ttm_buffer_object *bo);
+
+ /**
+ * notify the driver that we're about to swap out this bo
+ */
+ void (*swap_notify) (struct ttm_buffer_object *bo);
+
+ /**
+ * Driver callback on when mapping io memory (for bo_move_memcpy
+ * for instance). TTM will take care to call io_mem_free whenever
+ * the mapping is not use anymore. io_mem_reserve & io_mem_free
+ * are balanced.
+ */
+ int (*io_mem_reserve)(struct ttm_bo_device *bdev, struct ttm_mem_reg *mem);
+ void (*io_mem_free)(struct ttm_bo_device *bdev, struct ttm_mem_reg *mem);
+};
+
+/**
+ * struct ttm_bo_global_ref - Argument to initialize a struct ttm_bo_global.
+ */
+
+struct ttm_bo_global_ref {
+ struct drm_global_reference ref;
+ struct ttm_mem_global *mem_glob;
+};
+
+/**
+ * struct ttm_bo_global - Buffer object driver global data.
+ *
+ * @mem_glob: Pointer to a struct ttm_mem_global object for accounting.
+ * @dummy_read_page: Pointer to a dummy page used for mapping requests
+ * of unpopulated pages.
+ * @shrink: A shrink callback object used for buffer object swap.
+ * @device_list_mutex: Mutex protecting the device list.
+ * This mutex is held while traversing the device list for pm options.
+ * @lru_lock: Spinlock protecting the bo subsystem lru lists.
+ * @device_list: List of buffer object devices.
+ * @swap_lru: Lru list of buffer objects used for swapping.
+ */
+
+struct ttm_bo_global {
+ u_int kobj_ref;
+
+ /**
+ * Constant after init.
+ */
+
+ struct ttm_mem_global *mem_glob;
+ struct vm_page *dummy_read_page;
+ struct ttm_mem_shrink shrink;
+ struct sx device_list_mutex;
+ struct mtx lru_lock;
+
+ /**
+ * Protected by device_list_mutex.
+ */
+ struct list_head device_list;
+
+ /**
+ * Protected by the lru_lock.
+ */
+ struct list_head swap_lru;
+
+ /**
+ * Internal protection.
+ */
+ atomic_t bo_count;
+};
+
+
+#define TTM_NUM_MEM_TYPES 8
+
+#define TTM_BO_PRIV_FLAG_MOVING 0 /* Buffer object is moving and needs
+ idling before CPU mapping */
+#define TTM_BO_PRIV_FLAG_MAX 1
+/**
+ * struct ttm_bo_device - Buffer object driver device-specific data.
+ *
+ * @driver: Pointer to a struct ttm_bo_driver struct setup by the driver.
+ * @man: An array of mem_type_managers.
+ * @fence_lock: Protects the synchronizing members on *all* bos belonging
+ * to this device.
+ * @addr_space_mm: Range manager for the device address space.
+ * lru_lock: Spinlock that protects the buffer+device lru lists and
+ * ddestroy lists.
+ * @val_seq: Current validation sequence.
+ * @dev_mapping: A pointer to the struct address_space representing the
+ * device address space.
+ * @wq: Work queue structure for the delayed delete workqueue.
+ *
+ */
+
+struct ttm_bo_device {
+
+ /*
+ * Constant after bo device init / atomic.
+ */
+ struct list_head device_list;
+ struct ttm_bo_global *glob;
+ struct ttm_bo_driver *driver;
+ struct rwlock vm_lock;
+ struct ttm_mem_type_manager man[TTM_NUM_MEM_TYPES];
+ struct mtx fence_lock;
+ /*
+ * Protected by the vm lock.
+ */
+ RB_HEAD(ttm_bo_device_buffer_objects, ttm_buffer_object) addr_space_rb;
+ struct drm_mm addr_space_mm;
+
+ /*
+ * Protected by the global:lru lock.
+ */
+ struct list_head ddestroy;
+ uint32_t val_seq;
+
+ /*
+ * Protected by load / firstopen / lastclose /unload sync.
+ */
+
+ struct address_space *dev_mapping;
+
+ /*
+ * Internal protection.
+ */
+
+ struct timeout_task wq;
+
+ bool need_dma32;
+};
+
+/**
+ * ttm_flag_masked
+ *
+ * @old: Pointer to the result and original value.
+ * @new: New value of bits.
+ * @mask: Mask of bits to change.
+ *
+ * Convenience function to change a number of bits identified by a mask.
+ */
+
+static inline uint32_t
+ttm_flag_masked(uint32_t *old, uint32_t new, uint32_t mask)
+{
+ *old ^= (*old ^ new) & mask;
+ return *old;
+}
+
+/**
+ * ttm_tt_init
+ *
+ * @ttm: The struct ttm_tt.
+ * @bdev: pointer to a struct ttm_bo_device:
+ * @size: Size of the data needed backing.
+ * @page_flags: Page flags as identified by TTM_PAGE_FLAG_XX flags.
+ * @dummy_read_page: See struct ttm_bo_device.
+ *
+ * Create a struct ttm_tt to back data with system memory pages.
+ * No pages are actually allocated.
+ * Returns:
+ * NULL: Out of memory.
+ */
+extern int ttm_tt_init(struct ttm_tt *ttm, struct ttm_bo_device *bdev,
+ unsigned long size, uint32_t page_flags,
+ struct vm_page *dummy_read_page);
+extern int ttm_dma_tt_init(struct ttm_dma_tt *ttm_dma, struct ttm_bo_device *bdev,
+ unsigned long size, uint32_t page_flags,
+ struct vm_page *dummy_read_page);
+
+/**
+ * ttm_tt_fini
+ *
+ * @ttm: the ttm_tt structure.
+ *
+ * Free memory of ttm_tt structure
+ */
+extern void ttm_tt_fini(struct ttm_tt *ttm);
+extern void ttm_dma_tt_fini(struct ttm_dma_tt *ttm_dma);
+
+/**
+ * ttm_ttm_bind:
+ *
+ * @ttm: The struct ttm_tt containing backing pages.
+ * @bo_mem: The struct ttm_mem_reg identifying the binding location.
+ *
+ * Bind the pages of @ttm to an aperture location identified by @bo_mem
+ */
+extern int ttm_tt_bind(struct ttm_tt *ttm, struct ttm_mem_reg *bo_mem);
+
+/**
+ * ttm_ttm_destroy:
+ *
+ * @ttm: The struct ttm_tt.
+ *
+ * Unbind, unpopulate and destroy common struct ttm_tt.
+ */
+extern void ttm_tt_destroy(struct ttm_tt *ttm);
+
+/**
+ * ttm_ttm_unbind:
+ *
+ * @ttm: The struct ttm_tt.
+ *
+ * Unbind a struct ttm_tt.
+ */
+extern void ttm_tt_unbind(struct ttm_tt *ttm);
+
+/**
+ * ttm_tt_swapin:
+ *
+ * @ttm: The struct ttm_tt.
+ *
+ * Swap in a previously swap out ttm_tt.
+ */
+extern int ttm_tt_swapin(struct ttm_tt *ttm);
+
+/**
+ * ttm_tt_cache_flush:
+ *
+ * @pages: An array of pointers to struct page:s to flush.
+ * @num_pages: Number of pages to flush.
+ *
+ * Flush the data of the indicated pages from the cpu caches.
+ * This is used when changing caching attributes of the pages from
+ * cache-coherent.
+ */
+extern void ttm_tt_cache_flush(struct vm_page *pages[], unsigned long num_pages);
+
+/**
+ * ttm_tt_set_placement_caching:
+ *
+ * @ttm A struct ttm_tt the backing pages of which will change caching policy.
+ * @placement: Flag indicating the desired caching policy.
+ *
+ * This function will change caching policy of any default kernel mappings of
+ * the pages backing @ttm. If changing from cached to uncached or
+ * write-combined,
+ * all CPU caches will first be flushed to make sure the data of the pages
+ * hit RAM. This function may be very costly as it involves global TLB
+ * and cache flushes and potential page splitting / combining.
+ */
+extern int ttm_tt_set_placement_caching(struct ttm_tt *ttm, uint32_t placement);
+extern int ttm_tt_swapout(struct ttm_tt *ttm,
+ struct vm_object *persistent_swap_storage);
+
+/*
+ * ttm_bo.c
+ */
+
+/**
+ * ttm_mem_reg_is_pci
+ *
+ * @bdev: Pointer to a struct ttm_bo_device.
+ * @mem: A valid struct ttm_mem_reg.
+ *
+ * Returns true if the memory described by @mem is PCI memory,
+ * false otherwise.
+ */
+extern bool ttm_mem_reg_is_pci(struct ttm_bo_device *bdev,
+ struct ttm_mem_reg *mem);
+
+/**
+ * ttm_bo_mem_space
+ *
+ * @bo: Pointer to a struct ttm_buffer_object. the data of which
+ * we want to allocate space for.
+ * @proposed_placement: Proposed new placement for the buffer object.
+ * @mem: A struct ttm_mem_reg.
+ * @interruptible: Sleep interruptible when sliping.
+ * @no_wait_gpu: Return immediately if the GPU is busy.
+ *
+ * Allocate memory space for the buffer object pointed to by @bo, using
+ * the placement flags in @mem, potentially evicting other idle buffer objects.
+ * This function may sleep while waiting for space to become available.
+ * Returns:
+ * -EBUSY: No space available (only if no_wait == 1).
+ * -ENOMEM: Could not allocate memory for the buffer object, either due to
+ * fragmentation or concurrent allocators.
+ * -ERESTARTSYS: An interruptible sleep was interrupted by a signal.
+ */
+extern int ttm_bo_mem_space(struct ttm_buffer_object *bo,
+ struct ttm_placement *placement,
+ struct ttm_mem_reg *mem,
+ bool interruptible,
+ bool no_wait_gpu);
+
+extern void ttm_bo_mem_put(struct ttm_buffer_object *bo,
+ struct ttm_mem_reg *mem);
+extern void ttm_bo_mem_put_locked(struct ttm_buffer_object *bo,
+ struct ttm_mem_reg *mem);
+
+extern void ttm_bo_global_release(struct drm_global_reference *ref);
+extern int ttm_bo_global_init(struct drm_global_reference *ref);
+
+extern int ttm_bo_device_release(struct ttm_bo_device *bdev);
+
+/**
+ * ttm_bo_device_init
+ *
+ * @bdev: A pointer to a struct ttm_bo_device to initialize.
+ * @glob: A pointer to an initialized struct ttm_bo_global.
+ * @driver: A pointer to a struct ttm_bo_driver set up by the caller.
+ * @file_page_offset: Offset into the device address space that is available
+ * for buffer data. This ensures compatibility with other users of the
+ * address space.
+ *
+ * Initializes a struct ttm_bo_device:
+ * Returns:
+ * !0: Failure.
+ */
+extern int ttm_bo_device_init(struct ttm_bo_device *bdev,
+ struct ttm_bo_global *glob,
+ struct ttm_bo_driver *driver,
+ uint64_t file_page_offset, bool need_dma32);
+
+/**
+ * ttm_bo_unmap_virtual
+ *
+ * @bo: tear down the virtual mappings for this BO
+ */
+extern void ttm_bo_unmap_virtual(struct ttm_buffer_object *bo);
+
+/**
+ * ttm_bo_unmap_virtual
+ *
+ * @bo: tear down the virtual mappings for this BO
+ *
+ * The caller must take ttm_mem_io_lock before calling this function.
+ */
+extern void ttm_bo_unmap_virtual_locked(struct ttm_buffer_object *bo);
+
+extern int ttm_mem_io_reserve_vm(struct ttm_buffer_object *bo);
+extern void ttm_mem_io_free_vm(struct ttm_buffer_object *bo);
+extern int ttm_mem_io_lock(struct ttm_mem_type_manager *man,
+ bool interruptible);
+extern void ttm_mem_io_unlock(struct ttm_mem_type_manager *man);
+
+
+/**
+ * ttm_bo_reserve:
+ *
+ * @bo: A pointer to a struct ttm_buffer_object.
+ * @interruptible: Sleep interruptible if waiting.
+ * @no_wait: Don't sleep while trying to reserve, rather return -EBUSY.
+ * @use_sequence: If @bo is already reserved, Only sleep waiting for
+ * it to become unreserved if @sequence < (@bo)->sequence.
+ *
+ * Locks a buffer object for validation. (Or prevents other processes from
+ * locking it for validation) and removes it from lru lists, while taking
+ * a number of measures to prevent deadlocks.
+ *
+ * Deadlocks may occur when two processes try to reserve multiple buffers in
+ * different order, either by will or as a result of a buffer being evicted
+ * to make room for a buffer already reserved. (Buffers are reserved before
+ * they are evicted). The following algorithm prevents such deadlocks from
+ * occurring:
+ * 1) Buffers are reserved with the lru spinlock held. Upon successful
+ * reservation they are removed from the lru list. This stops a reserved buffer
+ * from being evicted. However the lru spinlock is released between the time
+ * a buffer is selected for eviction and the time it is reserved.
+ * Therefore a check is made when a buffer is reserved for eviction, that it
+ * is still the first buffer in the lru list, before it is removed from the
+ * list. @check_lru == 1 forces this check. If it fails, the function returns
+ * -EINVAL, and the caller should then choose a new buffer to evict and repeat
+ * the procedure.
+ * 2) Processes attempting to reserve multiple buffers other than for eviction,
+ * (typically execbuf), should first obtain a unique 32-bit
+ * validation sequence number,
+ * and call this function with @use_sequence == 1 and @sequence == the unique
+ * sequence number. If upon call of this function, the buffer object is already
+ * reserved, the validation sequence is checked against the validation
+ * sequence of the process currently reserving the buffer,
+ * and if the current validation sequence is greater than that of the process
+ * holding the reservation, the function returns -EAGAIN. Otherwise it sleeps
+ * waiting for the buffer to become unreserved, after which it retries
+ * reserving.
+ * The caller should, when receiving an -EAGAIN error
+ * release all its buffer reservations, wait for @bo to become unreserved, and
+ * then rerun the validation with the same validation sequence. This procedure
+ * will always guarantee that the process with the lowest validation sequence
+ * will eventually succeed, preventing both deadlocks and starvation.
+ *
+ * Returns:
+ * -EAGAIN: The reservation may cause a deadlock.
+ * Release all buffer reservations, wait for @bo to become unreserved and
+ * try again. (only if use_sequence == 1).
+ * -ERESTARTSYS: A wait for the buffer to become unreserved was interrupted by
+ * a signal. Release all buffer reservations and return to user-space.
+ * -EBUSY: The function needed to sleep, but @no_wait was true
+ * -EDEADLK: Bo already reserved using @sequence. This error code will only
+ * be returned if @use_sequence is set to true.
+ */
+extern int ttm_bo_reserve(struct ttm_buffer_object *bo,
+ bool interruptible,
+ bool no_wait, bool use_sequence, uint32_t sequence);
+
+
+/**
+ * ttm_bo_reserve_locked:
+ *
+ * @bo: A pointer to a struct ttm_buffer_object.
+ * @interruptible: Sleep interruptible if waiting.
+ * @no_wait: Don't sleep while trying to reserve, rather return -EBUSY.
+ * @use_sequence: If @bo is already reserved, Only sleep waiting for
+ * it to become unreserved if @sequence < (@bo)->sequence.
+ *
+ * Must be called with struct ttm_bo_global::lru_lock held,
+ * and will not remove reserved buffers from the lru lists.
+ * The function may release the LRU spinlock if it needs to sleep.
+ * Otherwise identical to ttm_bo_reserve.
+ *
+ * Returns:
+ * -EAGAIN: The reservation may cause a deadlock.
+ * Release all buffer reservations, wait for @bo to become unreserved and
+ * try again. (only if use_sequence == 1).
+ * -ERESTARTSYS: A wait for the buffer to become unreserved was interrupted by
+ * a signal. Release all buffer reservations and return to user-space.
+ * -EBUSY: The function needed to sleep, but @no_wait was true
+ * -EDEADLK: Bo already reserved using @sequence. This error code will only
+ * be returned if @use_sequence is set to true.
+ */
+extern int ttm_bo_reserve_locked(struct ttm_buffer_object *bo,
+ bool interruptible,
+ bool no_wait, bool use_sequence,
+ uint32_t sequence);
+
+/**
+ * ttm_bo_unreserve
+ *
+ * @bo: A pointer to a struct ttm_buffer_object.
+ *
+ * Unreserve a previous reservation of @bo.
+ */
+extern void ttm_bo_unreserve(struct ttm_buffer_object *bo);
+
+/**
+ * ttm_bo_unreserve_locked
+ *
+ * @bo: A pointer to a struct ttm_buffer_object.
+ *
+ * Unreserve a previous reservation of @bo.
+ * Needs to be called with struct ttm_bo_global::lru_lock held.
+ */
+extern void ttm_bo_unreserve_locked(struct ttm_buffer_object *bo);
+
+/**
+ * ttm_bo_wait_unreserved
+ *
+ * @bo: A pointer to a struct ttm_buffer_object.
+ *
+ * Wait for a struct ttm_buffer_object to become unreserved.
+ * This is typically used in the execbuf code to relax cpu-usage when
+ * a potential deadlock condition backoff.
+ */
+extern int ttm_bo_wait_unreserved_locked(struct ttm_buffer_object *bo,
+ bool interruptible);
+
+/*
+ * ttm_bo_util.c
+ */
+
+/**
+ * ttm_bo_move_ttm
+ *
+ * @bo: A pointer to a struct ttm_buffer_object.
+ * @evict: 1: This is an eviction. Don't try to pipeline.
+ * @no_wait_gpu: Return immediately if the GPU is busy.
+ * @new_mem: struct ttm_mem_reg indicating where to move.
+ *
+ * Optimized move function for a buffer object with both old and
+ * new placement backed by a TTM. The function will, if successful,
+ * free any old aperture space, and set (@new_mem)->mm_node to NULL,
+ * and update the (@bo)->mem placement flags. If unsuccessful, the old
+ * data remains untouched, and it's up to the caller to free the
+ * memory space indicated by @new_mem.
+ * Returns:
+ * !0: Failure.
+ */
+
+extern int ttm_bo_move_ttm(struct ttm_buffer_object *bo,
+ bool evict, bool no_wait_gpu,
+ struct ttm_mem_reg *new_mem);
+
+/**
+ * ttm_bo_move_memcpy
+ *
+ * @bo: A pointer to a struct ttm_buffer_object.
+ * @evict: 1: This is an eviction. Don't try to pipeline.
+ * @no_wait_gpu: Return immediately if the GPU is busy.
+ * @new_mem: struct ttm_mem_reg indicating where to move.
+ *
+ * Fallback move function for a mappable buffer object in mappable memory.
+ * The function will, if successful,
+ * free any old aperture space, and set (@new_mem)->mm_node to NULL,
+ * and update the (@bo)->mem placement flags. If unsuccessful, the old
+ * data remains untouched, and it's up to the caller to free the
+ * memory space indicated by @new_mem.
+ * Returns:
+ * !0: Failure.
+ */
+
+extern int ttm_bo_move_memcpy(struct ttm_buffer_object *bo,
+ bool evict, bool no_wait_gpu,
+ struct ttm_mem_reg *new_mem);
+
+/**
+ * ttm_bo_free_old_node
+ *
+ * @bo: A pointer to a struct ttm_buffer_object.
+ *
+ * Utility function to free an old placement after a successful move.
+ */
+extern void ttm_bo_free_old_node(struct ttm_buffer_object *bo);
+
+/**
+ * ttm_bo_move_accel_cleanup.
+ *
+ * @bo: A pointer to a struct ttm_buffer_object.
+ * @sync_obj: A sync object that signals when moving is complete.
+ * @evict: This is an evict move. Don't return until the buffer is idle.
+ * @no_wait_gpu: Return immediately if the GPU is busy.
+ * @new_mem: struct ttm_mem_reg indicating where to move.
+ *
+ * Accelerated move function to be called when an accelerated move
+ * has been scheduled. The function will create a new temporary buffer object
+ * representing the old placement, and put the sync object on both buffer
+ * objects. After that the newly created buffer object is unref'd to be
+ * destroyed when the move is complete. This will help pipeline
+ * buffer moves.
+ */
+
+extern int ttm_bo_move_accel_cleanup(struct ttm_buffer_object *bo,
+ void *sync_obj,
+ bool evict, bool no_wait_gpu,
+ struct ttm_mem_reg *new_mem);
+/**
+ * ttm_io_prot
+ *
+ * @c_state: Caching state.
+ * @tmp: Page protection flag for a normal, cached mapping.
+ *
+ * Utility function that returns the pgprot_t that should be used for
+ * setting up a PTE with the caching model indicated by @c_state.
+ */
+extern vm_memattr_t ttm_io_prot(uint32_t caching_flags);
+
+extern const struct ttm_mem_type_manager_func ttm_bo_manager_func;
+
+#if (defined(CONFIG_AGP) || (defined(CONFIG_AGP_MODULE) && defined(MODULE)))
+#define TTM_HAS_AGP
+#include <linux/agp_backend.h>
+
+/**
+ * ttm_agp_tt_create
+ *
+ * @bdev: Pointer to a struct ttm_bo_device.
+ * @bridge: The agp bridge this device is sitting on.
+ * @size: Size of the data needed backing.
+ * @page_flags: Page flags as identified by TTM_PAGE_FLAG_XX flags.
+ * @dummy_read_page: See struct ttm_bo_device.
+ *
+ *
+ * Create a TTM backend that uses the indicated AGP bridge as an aperture
+ * for TT memory. This function uses the linux agpgart interface to
+ * bind and unbind memory backing a ttm_tt.
+ */
+extern struct ttm_tt *ttm_agp_tt_create(struct ttm_bo_device *bdev,
+ struct agp_bridge_data *bridge,
+ unsigned long size, uint32_t page_flags,
+ struct vm_page *dummy_read_page);
+int ttm_agp_tt_populate(struct ttm_tt *ttm);
+void ttm_agp_tt_unpopulate(struct ttm_tt *ttm);
+#endif
+
+int ttm_bo_cmp_rb_tree_items(struct ttm_buffer_object *a,
+ struct ttm_buffer_object *b);
+
+RB_PROTOTYPE(ttm_bo_device_buffer_objects, ttm_buffer_object, vm_rb,
+ ttm_bo_cmp_rb_tree_items);
+
+#endif
diff --git a/sys/dev/drm2/ttm/ttm_bo_manager.c b/sys/dev/drm2/ttm/ttm_bo_manager.c
new file mode 100644
index 0000000..4686511
--- /dev/null
+++ b/sys/dev/drm2/ttm/ttm_bo_manager.c
@@ -0,0 +1,157 @@
+/**************************************************************************
+ *
+ * Copyright (c) 2007-2010 VMware, Inc., Palo Alto, CA., USA
+ * All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sub license, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the
+ * next paragraph) shall be included in all copies or substantial portions
+ * of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDERS, AUTHORS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM,
+ * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
+ * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
+ * USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ **************************************************************************/
+/*
+ * Authors: Thomas Hellstrom <thellstrom-at-vmware-dot-com>
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include <dev/drm2/drmP.h>
+#include <dev/drm2/ttm/ttm_module.h>
+#include <dev/drm2/ttm/ttm_bo_driver.h>
+#include <dev/drm2/ttm/ttm_placement.h>
+#include <dev/drm2/drm_mm.h>
+
+/**
+ * Currently we use a spinlock for the lock, but a mutex *may* be
+ * more appropriate to reduce scheduling latency if the range manager
+ * ends up with very fragmented allocation patterns.
+ */
+
+struct ttm_range_manager {
+ struct drm_mm mm;
+ struct mtx lock;
+};
+
+MALLOC_DEFINE(M_TTM_RMAN, "ttm_rman", "TTM Range Manager");
+
+static int ttm_bo_man_get_node(struct ttm_mem_type_manager *man,
+ struct ttm_buffer_object *bo,
+ struct ttm_placement *placement,
+ struct ttm_mem_reg *mem)
+{
+ struct ttm_range_manager *rman = (struct ttm_range_manager *) man->priv;
+ struct drm_mm *mm = &rman->mm;
+ struct drm_mm_node *node = NULL;
+ unsigned long lpfn;
+ int ret;
+
+ lpfn = placement->lpfn;
+ if (!lpfn)
+ lpfn = man->size;
+ do {
+ ret = drm_mm_pre_get(mm);
+ if (unlikely(ret))
+ return ret;
+
+ mtx_lock(&rman->lock);
+ node = drm_mm_search_free_in_range(mm,
+ mem->num_pages, mem->page_alignment,
+ placement->fpfn, lpfn, 1);
+ if (unlikely(node == NULL)) {
+ mtx_unlock(&rman->lock);
+ return 0;
+ }
+ node = drm_mm_get_block_atomic_range(node, mem->num_pages,
+ mem->page_alignment,
+ placement->fpfn,
+ lpfn);
+ mtx_unlock(&rman->lock);
+ } while (node == NULL);
+
+ mem->mm_node = node;
+ mem->start = node->start;
+ return 0;
+}
+
+static void ttm_bo_man_put_node(struct ttm_mem_type_manager *man,
+ struct ttm_mem_reg *mem)
+{
+ struct ttm_range_manager *rman = (struct ttm_range_manager *) man->priv;
+
+ if (mem->mm_node) {
+ mtx_lock(&rman->lock);
+ drm_mm_put_block(mem->mm_node);
+ mtx_unlock(&rman->lock);
+ mem->mm_node = NULL;
+ }
+}
+
+static int ttm_bo_man_init(struct ttm_mem_type_manager *man,
+ unsigned long p_size)
+{
+ struct ttm_range_manager *rman;
+ int ret;
+
+ rman = malloc(sizeof(*rman), M_TTM_RMAN, M_ZERO | M_WAITOK);
+ ret = drm_mm_init(&rman->mm, 0, p_size);
+ if (ret) {
+ free(rman, M_TTM_RMAN);
+ return ret;
+ }
+
+ mtx_init(&rman->lock, "ttmrman", NULL, MTX_DEF);
+ man->priv = rman;
+ return 0;
+}
+
+static int ttm_bo_man_takedown(struct ttm_mem_type_manager *man)
+{
+ struct ttm_range_manager *rman = (struct ttm_range_manager *) man->priv;
+ struct drm_mm *mm = &rman->mm;
+
+ mtx_lock(&rman->lock);
+ if (drm_mm_clean(mm)) {
+ drm_mm_takedown(mm);
+ mtx_unlock(&rman->lock);
+ mtx_destroy(&rman->lock);
+ free(rman, M_TTM_RMAN);
+ man->priv = NULL;
+ return 0;
+ }
+ mtx_unlock(&rman->lock);
+ return -EBUSY;
+}
+
+static void ttm_bo_man_debug(struct ttm_mem_type_manager *man,
+ const char *prefix)
+{
+ struct ttm_range_manager *rman = (struct ttm_range_manager *) man->priv;
+
+ mtx_lock(&rman->lock);
+ drm_mm_debug_table(&rman->mm, prefix);
+ mtx_unlock(&rman->lock);
+}
+
+const struct ttm_mem_type_manager_func ttm_bo_manager_func = {
+ ttm_bo_man_init,
+ ttm_bo_man_takedown,
+ ttm_bo_man_get_node,
+ ttm_bo_man_put_node,
+ ttm_bo_man_debug
+};
diff --git a/sys/dev/drm2/ttm/ttm_bo_util.c b/sys/dev/drm2/ttm/ttm_bo_util.c
new file mode 100644
index 0000000..139d134
--- /dev/null
+++ b/sys/dev/drm2/ttm/ttm_bo_util.c
@@ -0,0 +1,658 @@
+/**************************************************************************
+ *
+ * Copyright (c) 2007-2009 VMware, Inc., Palo Alto, CA., USA
+ * All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sub license, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the
+ * next paragraph) shall be included in all copies or substantial portions
+ * of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDERS, AUTHORS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM,
+ * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
+ * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
+ * USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ **************************************************************************/
+/*
+ * Authors: Thomas Hellstrom <thellstrom-at-vmware-dot-com>
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include <dev/drm2/drmP.h>
+#include <dev/drm2/ttm/ttm_bo_driver.h>
+#include <dev/drm2/ttm/ttm_placement.h>
+#include <sys/sf_buf.h>
+
+void ttm_bo_free_old_node(struct ttm_buffer_object *bo)
+{
+ ttm_bo_mem_put(bo, &bo->mem);
+}
+
+int ttm_bo_move_ttm(struct ttm_buffer_object *bo,
+ bool evict,
+ bool no_wait_gpu, struct ttm_mem_reg *new_mem)
+{
+ struct ttm_tt *ttm = bo->ttm;
+ struct ttm_mem_reg *old_mem = &bo->mem;
+ int ret;
+
+ if (old_mem->mem_type != TTM_PL_SYSTEM) {
+ ttm_tt_unbind(ttm);
+ ttm_bo_free_old_node(bo);
+ ttm_flag_masked(&old_mem->placement, TTM_PL_FLAG_SYSTEM,
+ TTM_PL_MASK_MEM);
+ old_mem->mem_type = TTM_PL_SYSTEM;
+ }
+
+ ret = ttm_tt_set_placement_caching(ttm, new_mem->placement);
+ if (unlikely(ret != 0))
+ return ret;
+
+ if (new_mem->mem_type != TTM_PL_SYSTEM) {
+ ret = ttm_tt_bind(ttm, new_mem);
+ if (unlikely(ret != 0))
+ return ret;
+ }
+
+ *old_mem = *new_mem;
+ new_mem->mm_node = NULL;
+
+ return 0;
+}
+
+int ttm_mem_io_lock(struct ttm_mem_type_manager *man, bool interruptible)
+{
+ if (likely(man->io_reserve_fastpath))
+ return 0;
+
+ if (interruptible) {
+ if (sx_xlock_sig(&man->io_reserve_mutex))
+ return (-EINTR);
+ else
+ return (0);
+ }
+
+ sx_xlock(&man->io_reserve_mutex);
+ return 0;
+}
+
+void ttm_mem_io_unlock(struct ttm_mem_type_manager *man)
+{
+ if (likely(man->io_reserve_fastpath))
+ return;
+
+ sx_xunlock(&man->io_reserve_mutex);
+}
+
+static int ttm_mem_io_evict(struct ttm_mem_type_manager *man)
+{
+ struct ttm_buffer_object *bo;
+
+ if (!man->use_io_reserve_lru || list_empty(&man->io_reserve_lru))
+ return -EAGAIN;
+
+ bo = list_first_entry(&man->io_reserve_lru,
+ struct ttm_buffer_object,
+ io_reserve_lru);
+ list_del_init(&bo->io_reserve_lru);
+ ttm_bo_unmap_virtual_locked(bo);
+
+ return 0;
+}
+
+static int ttm_mem_io_reserve(struct ttm_bo_device *bdev,
+ struct ttm_mem_reg *mem)
+{
+ struct ttm_mem_type_manager *man = &bdev->man[mem->mem_type];
+ int ret = 0;
+
+ if (!bdev->driver->io_mem_reserve)
+ return 0;
+ if (likely(man->io_reserve_fastpath))
+ return bdev->driver->io_mem_reserve(bdev, mem);
+
+ if (bdev->driver->io_mem_reserve &&
+ mem->bus.io_reserved_count++ == 0) {
+retry:
+ ret = bdev->driver->io_mem_reserve(bdev, mem);
+ if (ret == -EAGAIN) {
+ ret = ttm_mem_io_evict(man);
+ if (ret == 0)
+ goto retry;
+ }
+ }
+ return ret;
+}
+
+static void ttm_mem_io_free(struct ttm_bo_device *bdev,
+ struct ttm_mem_reg *mem)
+{
+ struct ttm_mem_type_manager *man = &bdev->man[mem->mem_type];
+
+ if (likely(man->io_reserve_fastpath))
+ return;
+
+ if (bdev->driver->io_mem_reserve &&
+ --mem->bus.io_reserved_count == 0 &&
+ bdev->driver->io_mem_free)
+ bdev->driver->io_mem_free(bdev, mem);
+
+}
+
+int ttm_mem_io_reserve_vm(struct ttm_buffer_object *bo)
+{
+ struct ttm_mem_reg *mem = &bo->mem;
+ int ret;
+
+ if (!mem->bus.io_reserved_vm) {
+ struct ttm_mem_type_manager *man =
+ &bo->bdev->man[mem->mem_type];
+
+ ret = ttm_mem_io_reserve(bo->bdev, mem);
+ if (unlikely(ret != 0))
+ return ret;
+ mem->bus.io_reserved_vm = true;
+ if (man->use_io_reserve_lru)
+ list_add_tail(&bo->io_reserve_lru,
+ &man->io_reserve_lru);
+ }
+ return 0;
+}
+
+void ttm_mem_io_free_vm(struct ttm_buffer_object *bo)
+{
+ struct ttm_mem_reg *mem = &bo->mem;
+
+ if (mem->bus.io_reserved_vm) {
+ mem->bus.io_reserved_vm = false;
+ list_del_init(&bo->io_reserve_lru);
+ ttm_mem_io_free(bo->bdev, mem);
+ }
+}
+
+static
+int ttm_mem_reg_ioremap(struct ttm_bo_device *bdev, struct ttm_mem_reg *mem,
+ void **virtual)
+{
+ struct ttm_mem_type_manager *man = &bdev->man[mem->mem_type];
+ int ret;
+ void *addr;
+
+ *virtual = NULL;
+ (void) ttm_mem_io_lock(man, false);
+ ret = ttm_mem_io_reserve(bdev, mem);
+ ttm_mem_io_unlock(man);
+ if (ret || !mem->bus.is_iomem)
+ return ret;
+
+ if (mem->bus.addr) {
+ addr = mem->bus.addr;
+ } else {
+ addr = pmap_mapdev_attr(mem->bus.base + mem->bus.offset,
+ mem->bus.size, (mem->placement & TTM_PL_FLAG_WC) ?
+ VM_MEMATTR_WRITE_COMBINING : VM_MEMATTR_UNCACHEABLE);
+ if (!addr) {
+ (void) ttm_mem_io_lock(man, false);
+ ttm_mem_io_free(bdev, mem);
+ ttm_mem_io_unlock(man);
+ return -ENOMEM;
+ }
+ }
+ *virtual = addr;
+ return 0;
+}
+
+static
+void ttm_mem_reg_iounmap(struct ttm_bo_device *bdev, struct ttm_mem_reg *mem,
+ void *virtual)
+{
+ struct ttm_mem_type_manager *man;
+
+ man = &bdev->man[mem->mem_type];
+
+ if (virtual && mem->bus.addr == NULL)
+ pmap_unmapdev((vm_offset_t)virtual, mem->bus.size);
+ (void) ttm_mem_io_lock(man, false);
+ ttm_mem_io_free(bdev, mem);
+ ttm_mem_io_unlock(man);
+}
+
+static int ttm_copy_io_page(void *dst, void *src, unsigned long page)
+{
+ uint32_t *dstP =
+ (uint32_t *) ((unsigned long)dst + (page << PAGE_SHIFT));
+ uint32_t *srcP =
+ (uint32_t *) ((unsigned long)src + (page << PAGE_SHIFT));
+
+ int i;
+ for (i = 0; i < PAGE_SIZE / sizeof(uint32_t); ++i)
+ /* iowrite32(ioread32(srcP++), dstP++); */
+ *dstP++ = *srcP++;
+ return 0;
+}
+
+static int ttm_copy_io_ttm_page(struct ttm_tt *ttm, void *src,
+ unsigned long page,
+ vm_memattr_t prot)
+{
+ vm_page_t d = ttm->pages[page];
+ void *dst;
+
+ if (!d)
+ return -ENOMEM;
+
+ src = (void *)((unsigned long)src + (page << PAGE_SHIFT));
+
+ /* XXXKIB can't sleep ? */
+ dst = pmap_mapdev_attr(VM_PAGE_TO_PHYS(d), PAGE_SIZE, prot);
+ if (!dst)
+ return -ENOMEM;
+
+ memcpy(dst, src, PAGE_SIZE);
+
+ pmap_unmapdev((vm_offset_t)dst, PAGE_SIZE);
+
+ return 0;
+}
+
+static int ttm_copy_ttm_io_page(struct ttm_tt *ttm, void *dst,
+ unsigned long page,
+ vm_memattr_t prot)
+{
+ vm_page_t s = ttm->pages[page];
+ void *src;
+
+ if (!s)
+ return -ENOMEM;
+
+ dst = (void *)((unsigned long)dst + (page << PAGE_SHIFT));
+ src = pmap_mapdev_attr(VM_PAGE_TO_PHYS(s), PAGE_SIZE, prot);
+ if (!src)
+ return -ENOMEM;
+
+ memcpy(dst, src, PAGE_SIZE);
+
+ pmap_unmapdev((vm_offset_t)src, PAGE_SIZE);
+
+ return 0;
+}
+
+int ttm_bo_move_memcpy(struct ttm_buffer_object *bo,
+ bool evict, bool no_wait_gpu,
+ struct ttm_mem_reg *new_mem)
+{
+ struct ttm_bo_device *bdev = bo->bdev;
+ struct ttm_mem_type_manager *man = &bdev->man[new_mem->mem_type];
+ struct ttm_tt *ttm = bo->ttm;
+ struct ttm_mem_reg *old_mem = &bo->mem;
+ struct ttm_mem_reg old_copy = *old_mem;
+ void *old_iomap;
+ void *new_iomap;
+ int ret;
+ unsigned long i;
+ unsigned long page;
+ unsigned long add = 0;
+ int dir;
+
+ ret = ttm_mem_reg_ioremap(bdev, old_mem, &old_iomap);
+ if (ret)
+ return ret;
+ ret = ttm_mem_reg_ioremap(bdev, new_mem, &new_iomap);
+ if (ret)
+ goto out;
+
+ if (old_iomap == NULL && new_iomap == NULL)
+ goto out2;
+ if (old_iomap == NULL && ttm == NULL)
+ goto out2;
+
+ if (ttm->state == tt_unpopulated) {
+ ret = ttm->bdev->driver->ttm_tt_populate(ttm);
+ if (ret)
+ goto out1;
+ }
+
+ add = 0;
+ dir = 1;
+
+ if ((old_mem->mem_type == new_mem->mem_type) &&
+ (new_mem->start < old_mem->start + old_mem->size)) {
+ dir = -1;
+ add = new_mem->num_pages - 1;
+ }
+
+ for (i = 0; i < new_mem->num_pages; ++i) {
+ page = i * dir + add;
+ if (old_iomap == NULL) {
+ vm_memattr_t prot = ttm_io_prot(old_mem->placement);
+ ret = ttm_copy_ttm_io_page(ttm, new_iomap, page,
+ prot);
+ } else if (new_iomap == NULL) {
+ vm_memattr_t prot = ttm_io_prot(new_mem->placement);
+ ret = ttm_copy_io_ttm_page(ttm, old_iomap, page,
+ prot);
+ } else
+ ret = ttm_copy_io_page(new_iomap, old_iomap, page);
+ if (ret)
+ goto out1;
+ }
+ mb();
+out2:
+ old_copy = *old_mem;
+ *old_mem = *new_mem;
+ new_mem->mm_node = NULL;
+
+ if ((man->flags & TTM_MEMTYPE_FLAG_FIXED) && (ttm != NULL)) {
+ ttm_tt_unbind(ttm);
+ ttm_tt_destroy(ttm);
+ bo->ttm = NULL;
+ }
+
+out1:
+ ttm_mem_reg_iounmap(bdev, old_mem, new_iomap);
+out:
+ ttm_mem_reg_iounmap(bdev, &old_copy, old_iomap);
+ ttm_bo_mem_put(bo, &old_copy);
+ return ret;
+}
+
+MALLOC_DEFINE(M_TTM_TRANSF_OBJ, "ttm_transf_obj", "TTM Transfer Objects");
+
+static void ttm_transfered_destroy(struct ttm_buffer_object *bo)
+{
+ free(bo, M_TTM_TRANSF_OBJ);
+}
+
+/**
+ * ttm_buffer_object_transfer
+ *
+ * @bo: A pointer to a struct ttm_buffer_object.
+ * @new_obj: A pointer to a pointer to a newly created ttm_buffer_object,
+ * holding the data of @bo with the old placement.
+ *
+ * This is a utility function that may be called after an accelerated move
+ * has been scheduled. A new buffer object is created as a placeholder for
+ * the old data while it's being copied. When that buffer object is idle,
+ * it can be destroyed, releasing the space of the old placement.
+ * Returns:
+ * !0: Failure.
+ */
+
+static int ttm_buffer_object_transfer(struct ttm_buffer_object *bo,
+ struct ttm_buffer_object **new_obj)
+{
+ struct ttm_buffer_object *fbo;
+ struct ttm_bo_device *bdev = bo->bdev;
+ struct ttm_bo_driver *driver = bdev->driver;
+
+ fbo = malloc(sizeof(*fbo), M_TTM_TRANSF_OBJ, M_ZERO | M_WAITOK);
+ *fbo = *bo;
+
+ /**
+ * Fix up members that we shouldn't copy directly:
+ * TODO: Explicit member copy would probably be better here.
+ */
+
+ INIT_LIST_HEAD(&fbo->ddestroy);
+ INIT_LIST_HEAD(&fbo->lru);
+ INIT_LIST_HEAD(&fbo->swap);
+ INIT_LIST_HEAD(&fbo->io_reserve_lru);
+ fbo->vm_node = NULL;
+ atomic_set(&fbo->cpu_writers, 0);
+
+ fbo->sync_obj = driver->sync_obj_ref(bo->sync_obj);
+ refcount_init(&fbo->list_kref, 1);
+ refcount_init(&fbo->kref, 1);
+ fbo->destroy = &ttm_transfered_destroy;
+ fbo->acc_size = 0;
+
+ *new_obj = fbo;
+ return 0;
+}
+
+vm_memattr_t
+ttm_io_prot(uint32_t caching_flags)
+{
+#if defined(__i386__) || defined(__amd64__)
+ if (caching_flags & TTM_PL_FLAG_WC)
+ return (VM_MEMATTR_WRITE_COMBINING);
+ else
+ /*
+ * We do not support i386, look at the linux source
+ * for the reason of the comment.
+ */
+ return (VM_MEMATTR_UNCACHEABLE);
+#else
+#error Port me
+#endif
+}
+
+static int ttm_bo_ioremap(struct ttm_buffer_object *bo,
+ unsigned long offset,
+ unsigned long size,
+ struct ttm_bo_kmap_obj *map)
+{
+ struct ttm_mem_reg *mem = &bo->mem;
+
+ if (bo->mem.bus.addr) {
+ map->bo_kmap_type = ttm_bo_map_premapped;
+ map->virtual = (void *)(((u8 *)bo->mem.bus.addr) + offset);
+ } else {
+ map->bo_kmap_type = ttm_bo_map_iomap;
+ map->virtual = pmap_mapdev_attr(bo->mem.bus.base +
+ bo->mem.bus.offset + offset, size,
+ (mem->placement & TTM_PL_FLAG_WC) ?
+ VM_MEMATTR_WRITE_COMBINING : VM_MEMATTR_UNCACHEABLE);
+ map->size = size;
+ }
+ return (!map->virtual) ? -ENOMEM : 0;
+}
+
+static int ttm_bo_kmap_ttm(struct ttm_buffer_object *bo,
+ unsigned long start_page,
+ unsigned long num_pages,
+ struct ttm_bo_kmap_obj *map)
+{
+ struct ttm_mem_reg *mem = &bo->mem;
+ vm_memattr_t prot;
+ struct ttm_tt *ttm = bo->ttm;
+ int i, ret;
+
+ MPASS(ttm != NULL);
+
+ if (ttm->state == tt_unpopulated) {
+ ret = ttm->bdev->driver->ttm_tt_populate(ttm);
+ if (ret)
+ return ret;
+ }
+
+ if (num_pages == 1 && (mem->placement & TTM_PL_FLAG_CACHED)) {
+ /*
+ * We're mapping a single page, and the desired
+ * page protection is consistent with the bo.
+ */
+
+ map->bo_kmap_type = ttm_bo_map_kmap;
+ map->page = ttm->pages[start_page];
+ map->sf = sf_buf_alloc(map->page, 0);
+ map->virtual = (void *)sf_buf_kva(map->sf);
+ } else {
+ /*
+ * We need to use vmap to get the desired page protection
+ * or to make the buffer object look contiguous.
+ */
+ prot = (mem->placement & TTM_PL_FLAG_CACHED) ?
+ VM_MEMATTR_WRITE_COMBINING :
+ ttm_io_prot(mem->placement);
+ map->bo_kmap_type = ttm_bo_map_vmap;
+ map->num_pages = num_pages;
+ map->virtual = (void *)kmem_alloc_nofault(kernel_map,
+ num_pages * PAGE_SIZE);
+ if (map->virtual != NULL) {
+ for (i = 0; i < num_pages; i++) {
+ /* XXXKIB hack */
+ pmap_page_set_memattr(ttm->pages[start_page +
+ i], prot);
+ }
+ pmap_qenter((vm_offset_t)map->virtual,
+ &ttm->pages[start_page], num_pages);
+ }
+ }
+ return (!map->virtual) ? -ENOMEM : 0;
+}
+
+int ttm_bo_kmap(struct ttm_buffer_object *bo,
+ unsigned long start_page, unsigned long num_pages,
+ struct ttm_bo_kmap_obj *map)
+{
+ struct ttm_mem_type_manager *man =
+ &bo->bdev->man[bo->mem.mem_type];
+ unsigned long offset, size;
+ int ret;
+
+ MPASS(list_empty(&bo->swap));
+ map->virtual = NULL;
+ map->bo = bo;
+ if (num_pages > bo->num_pages)
+ return -EINVAL;
+ if (start_page > bo->num_pages)
+ return -EINVAL;
+#if 0
+ if (num_pages > 1 && !DRM_SUSER(DRM_CURPROC))
+ return -EPERM;
+#endif
+ (void) ttm_mem_io_lock(man, false);
+ ret = ttm_mem_io_reserve(bo->bdev, &bo->mem);
+ ttm_mem_io_unlock(man);
+ if (ret)
+ return ret;
+ if (!bo->mem.bus.is_iomem) {
+ return ttm_bo_kmap_ttm(bo, start_page, num_pages, map);
+ } else {
+ offset = start_page << PAGE_SHIFT;
+ size = num_pages << PAGE_SHIFT;
+ return ttm_bo_ioremap(bo, offset, size, map);
+ }
+}
+
+void ttm_bo_kunmap(struct ttm_bo_kmap_obj *map)
+{
+ struct ttm_buffer_object *bo = map->bo;
+ struct ttm_mem_type_manager *man =
+ &bo->bdev->man[bo->mem.mem_type];
+
+ if (!map->virtual)
+ return;
+ switch (map->bo_kmap_type) {
+ case ttm_bo_map_iomap:
+ pmap_unmapdev((vm_offset_t)map->virtual, map->size);
+ break;
+ case ttm_bo_map_vmap:
+ pmap_qremove((vm_offset_t)(map->virtual), map->num_pages);
+ kmem_free(kernel_map, (vm_offset_t)map->virtual,
+ map->num_pages * PAGE_SIZE);
+ break;
+ case ttm_bo_map_kmap:
+ sf_buf_free(map->sf);
+ break;
+ case ttm_bo_map_premapped:
+ break;
+ default:
+ MPASS(0);
+ }
+ (void) ttm_mem_io_lock(man, false);
+ ttm_mem_io_free(map->bo->bdev, &map->bo->mem);
+ ttm_mem_io_unlock(man);
+ map->virtual = NULL;
+ map->page = NULL;
+ map->sf = NULL;
+}
+
+int ttm_bo_move_accel_cleanup(struct ttm_buffer_object *bo,
+ void *sync_obj,
+ bool evict,
+ bool no_wait_gpu,
+ struct ttm_mem_reg *new_mem)
+{
+ struct ttm_bo_device *bdev = bo->bdev;
+ struct ttm_bo_driver *driver = bdev->driver;
+ struct ttm_mem_type_manager *man = &bdev->man[new_mem->mem_type];
+ struct ttm_mem_reg *old_mem = &bo->mem;
+ int ret;
+ struct ttm_buffer_object *ghost_obj;
+ void *tmp_obj = NULL;
+
+ mtx_lock(&bdev->fence_lock);
+ if (bo->sync_obj) {
+ tmp_obj = bo->sync_obj;
+ bo->sync_obj = NULL;
+ }
+ bo->sync_obj = driver->sync_obj_ref(sync_obj);
+ if (evict) {
+ ret = ttm_bo_wait(bo, false, false, false);
+ mtx_unlock(&bdev->fence_lock);
+ if (tmp_obj)
+ driver->sync_obj_unref(&tmp_obj);
+ if (ret)
+ return ret;
+
+ if ((man->flags & TTM_MEMTYPE_FLAG_FIXED) &&
+ (bo->ttm != NULL)) {
+ ttm_tt_unbind(bo->ttm);
+ ttm_tt_destroy(bo->ttm);
+ bo->ttm = NULL;
+ }
+ ttm_bo_free_old_node(bo);
+ } else {
+ /**
+ * This should help pipeline ordinary buffer moves.
+ *
+ * Hang old buffer memory on a new buffer object,
+ * and leave it to be released when the GPU
+ * operation has completed.
+ */
+
+ set_bit(TTM_BO_PRIV_FLAG_MOVING, &bo->priv_flags);
+
+ /* ttm_buffer_object_transfer accesses bo->sync_obj */
+ ret = ttm_buffer_object_transfer(bo, &ghost_obj);
+ mtx_unlock(&bdev->fence_lock);
+ if (tmp_obj)
+ driver->sync_obj_unref(&tmp_obj);
+
+ if (ret)
+ return ret;
+
+ /**
+ * If we're not moving to fixed memory, the TTM object
+ * needs to stay alive. Otherwhise hang it on the ghost
+ * bo to be unbound and destroyed.
+ */
+
+ if (!(man->flags & TTM_MEMTYPE_FLAG_FIXED))
+ ghost_obj->ttm = NULL;
+ else
+ bo->ttm = NULL;
+
+ ttm_bo_unreserve(ghost_obj);
+ ttm_bo_unref(&ghost_obj);
+ }
+
+ *old_mem = *new_mem;
+ new_mem->mm_node = NULL;
+
+ return 0;
+}
diff --git a/sys/dev/drm2/ttm/ttm_bo_vm.c b/sys/dev/drm2/ttm/ttm_bo_vm.c
new file mode 100644
index 0000000..3eb4cc7
--- /dev/null
+++ b/sys/dev/drm2/ttm/ttm_bo_vm.c
@@ -0,0 +1,492 @@
+/**************************************************************************
+ *
+ * Copyright (c) 2006-2009 VMware, Inc., Palo Alto, CA., USA
+ * All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sub license, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the
+ * next paragraph) shall be included in all copies or substantial portions
+ * of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDERS, AUTHORS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM,
+ * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
+ * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
+ * USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ **************************************************************************/
+/*
+ * Authors: Thomas Hellstrom <thellstrom-at-vmware-dot-com>
+ */
+/*
+ * Copyright (c) 2013 The FreeBSD Foundation
+ * All rights reserved.
+ *
+ * Portions of this software were developed by Konstantin Belousov
+ * <kib@FreeBSD.org> under sponsorship from the FreeBSD Foundation.
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include "opt_vm.h"
+
+#include <dev/drm2/drmP.h>
+#include <dev/drm2/ttm/ttm_module.h>
+#include <dev/drm2/ttm/ttm_bo_driver.h>
+#include <dev/drm2/ttm/ttm_placement.h>
+
+#include <vm/vm.h>
+#include <vm/vm_page.h>
+
+#define TTM_BO_VM_NUM_PREFAULT 16
+
+RB_GENERATE(ttm_bo_device_buffer_objects, ttm_buffer_object, vm_rb,
+ ttm_bo_cmp_rb_tree_items);
+
+int
+ttm_bo_cmp_rb_tree_items(struct ttm_buffer_object *a,
+ struct ttm_buffer_object *b)
+{
+
+ if (a->vm_node->start < b->vm_node->start) {
+ return (-1);
+ } else if (a->vm_node->start > b->vm_node->start) {
+ return (1);
+ } else {
+ return (0);
+ }
+}
+
+static struct ttm_buffer_object *ttm_bo_vm_lookup_rb(struct ttm_bo_device *bdev,
+ unsigned long page_start,
+ unsigned long num_pages)
+{
+ unsigned long cur_offset;
+ struct ttm_buffer_object *bo;
+ struct ttm_buffer_object *best_bo = NULL;
+
+ RB_FOREACH(bo, ttm_bo_device_buffer_objects, &bdev->addr_space_rb) {
+ cur_offset = bo->vm_node->start;
+ if (page_start >= cur_offset) {
+ best_bo = bo;
+ if (page_start == cur_offset)
+ break;
+ }
+ }
+
+ if (unlikely(best_bo == NULL))
+ return NULL;
+
+ if (unlikely((best_bo->vm_node->start + best_bo->num_pages) <
+ (page_start + num_pages)))
+ return NULL;
+
+ return best_bo;
+}
+
+static int
+ttm_bo_vm_fault(vm_object_t vm_obj, vm_ooffset_t offset,
+ int prot, vm_page_t *mres)
+{
+
+ struct ttm_buffer_object *bo = vm_obj->handle;
+ struct ttm_bo_device *bdev = bo->bdev;
+ struct ttm_tt *ttm = NULL;
+ vm_page_t m, oldm;
+ int ret;
+ int retval = VM_PAGER_OK;
+ struct ttm_mem_type_manager *man =
+ &bdev->man[bo->mem.mem_type];
+
+ vm_object_pip_add(vm_obj, 1);
+ oldm = *mres;
+ if (oldm != NULL) {
+ vm_page_lock(oldm);
+ vm_page_remove(oldm);
+ vm_page_unlock(oldm);
+ *mres = NULL;
+ } else
+ oldm = NULL;
+retry:
+ VM_OBJECT_WUNLOCK(vm_obj);
+ m = NULL;
+
+reserve:
+ mtx_lock(&bo->glob->lru_lock);
+ ret = ttm_bo_reserve_locked(bo, false, false, false, 0);
+ mtx_unlock(&bo->glob->lru_lock);
+ if (unlikely(ret != 0)) {
+ if (ret == -EBUSY) {
+ kern_yield(0);
+ goto reserve;
+ }
+ }
+
+ if (bdev->driver->fault_reserve_notify) {
+ ret = bdev->driver->fault_reserve_notify(bo);
+ switch (ret) {
+ case 0:
+ break;
+ case -EBUSY:
+ case -ERESTART:
+ case -EINTR:
+ kern_yield(0);
+ goto reserve;
+ default:
+ retval = VM_PAGER_ERROR;
+ goto out_unlock;
+ }
+ }
+
+ /*
+ * Wait for buffer data in transit, due to a pipelined
+ * move.
+ */
+
+ mtx_lock(&bdev->fence_lock);
+ if (test_bit(TTM_BO_PRIV_FLAG_MOVING, &bo->priv_flags)) {
+ ret = ttm_bo_wait(bo, false, true, false);
+ mtx_unlock(&bdev->fence_lock);
+ if (unlikely(ret != 0)) {
+ retval = VM_PAGER_ERROR;
+ goto out_unlock;
+ }
+ } else
+ mtx_unlock(&bdev->fence_lock);
+
+ ret = ttm_mem_io_lock(man, true);
+ if (unlikely(ret != 0)) {
+ retval = VM_PAGER_ERROR;
+ goto out_unlock;
+ }
+ ret = ttm_mem_io_reserve_vm(bo);
+ if (unlikely(ret != 0)) {
+ retval = VM_PAGER_ERROR;
+ goto out_io_unlock;
+ }
+
+ /*
+ * Strictly, we're not allowed to modify vma->vm_page_prot here,
+ * since the mmap_sem is only held in read mode. However, we
+ * modify only the caching bits of vma->vm_page_prot and
+ * consider those bits protected by
+ * the bo->mutex, as we should be the only writers.
+ * There shouldn't really be any readers of these bits except
+ * within vm_insert_mixed()? fork?
+ *
+ * TODO: Add a list of vmas to the bo, and change the
+ * vma->vm_page_prot when the object changes caching policy, with
+ * the correct locks held.
+ */
+ if (!bo->mem.bus.is_iomem) {
+ /* Allocate all page at once, most common usage */
+ ttm = bo->ttm;
+ if (ttm->bdev->driver->ttm_tt_populate(ttm)) {
+ retval = VM_PAGER_ERROR;
+ goto out_io_unlock;
+ }
+ }
+
+ if (bo->mem.bus.is_iomem) {
+ m = vm_phys_fictitious_to_vm_page(bo->mem.bus.base +
+ bo->mem.bus.offset + offset);
+ pmap_page_set_memattr(m, ttm_io_prot(bo->mem.placement));
+ } else {
+ ttm = bo->ttm;
+ m = ttm->pages[OFF_TO_IDX(offset)];
+ if (unlikely(!m)) {
+ retval = VM_PAGER_ERROR;
+ goto out_io_unlock;
+ }
+ pmap_page_set_memattr(m,
+ (bo->mem.placement & TTM_PL_FLAG_CACHED) ?
+ VM_MEMATTR_WRITE_BACK : ttm_io_prot(bo->mem.placement));
+ }
+
+ VM_OBJECT_WLOCK(vm_obj);
+ if ((m->flags & VPO_BUSY) != 0) {
+ vm_page_sleep(m, "ttmpbs");
+ ttm_mem_io_unlock(man);
+ ttm_bo_unreserve(bo);
+ goto retry;
+ }
+ m->valid = VM_PAGE_BITS_ALL;
+ *mres = m;
+ vm_page_lock(m);
+ vm_page_insert(m, vm_obj, OFF_TO_IDX(offset));
+ vm_page_unlock(m);
+ vm_page_busy(m);
+
+ if (oldm != NULL) {
+ vm_page_lock(oldm);
+ vm_page_free(oldm);
+ vm_page_unlock(oldm);
+ }
+
+out_io_unlock1:
+ ttm_mem_io_unlock(man);
+out_unlock1:
+ ttm_bo_unreserve(bo);
+ vm_object_pip_wakeup(vm_obj);
+ return (retval);
+
+out_io_unlock:
+ VM_OBJECT_WLOCK(vm_obj);
+ goto out_io_unlock1;
+
+out_unlock:
+ VM_OBJECT_WLOCK(vm_obj);
+ goto out_unlock1;
+}
+
+static int
+ttm_bo_vm_ctor(void *handle, vm_ooffset_t size, vm_prot_t prot,
+ vm_ooffset_t foff, struct ucred *cred, u_short *color)
+{
+ struct ttm_buffer_object *bo = handle;
+
+ *color = 0;
+ (void)ttm_bo_reference(bo);
+ return (0);
+}
+
+static void
+ttm_bo_vm_dtor(void *handle)
+{
+ struct ttm_buffer_object *bo = handle;
+
+ ttm_bo_unref(&bo);
+}
+
+static struct cdev_pager_ops ttm_pager_ops = {
+ .cdev_pg_fault = ttm_bo_vm_fault,
+ .cdev_pg_ctor = ttm_bo_vm_ctor,
+ .cdev_pg_dtor = ttm_bo_vm_dtor
+};
+
+int
+ttm_bo_mmap_single(struct ttm_bo_device *bdev, vm_ooffset_t *offset, vm_size_t size,
+ struct vm_object **obj_res, int nprot)
+{
+ struct ttm_bo_driver *driver;
+ struct ttm_buffer_object *bo;
+ struct vm_object *vm_obj;
+ int ret;
+
+ rw_wlock(&bdev->vm_lock);
+ bo = ttm_bo_vm_lookup_rb(bdev, OFF_TO_IDX(*offset), OFF_TO_IDX(size));
+ if (likely(bo != NULL))
+ refcount_acquire(&bo->kref);
+ rw_wunlock(&bdev->vm_lock);
+
+ if (unlikely(bo == NULL)) {
+ printf("[TTM] Could not find buffer object to map\n");
+ return (EINVAL);
+ }
+
+ driver = bo->bdev->driver;
+ if (unlikely(!driver->verify_access)) {
+ ret = EPERM;
+ goto out_unref;
+ }
+ ret = -driver->verify_access(bo);
+ if (unlikely(ret != 0))
+ goto out_unref;
+
+ vm_obj = cdev_pager_allocate(bo, OBJT_MGTDEVICE, &ttm_pager_ops,
+ size, nprot, 0, curthread->td_ucred);
+ if (vm_obj == NULL) {
+ ret = EINVAL;
+ goto out_unref;
+ }
+ /*
+ * Note: We're transferring the bo reference to vm_obj->handle here.
+ */
+ *offset = 0;
+ *obj_res = vm_obj;
+ return 0;
+out_unref:
+ ttm_bo_unref(&bo);
+ return ret;
+}
+
+#if 0
+int ttm_fbdev_mmap(struct vm_area_struct *vma, struct ttm_buffer_object *bo)
+{
+ if (vma->vm_pgoff != 0)
+ return -EACCES;
+
+ vma->vm_ops = &ttm_bo_vm_ops;
+ vma->vm_private_data = ttm_bo_reference(bo);
+ vma->vm_flags |= VM_IO | VM_MIXEDMAP | VM_DONTEXPAND;
+ return 0;
+}
+
+ssize_t ttm_bo_io(struct ttm_bo_device *bdev, struct file *filp,
+ const char __user *wbuf, char __user *rbuf, size_t count,
+ loff_t *f_pos, bool write)
+{
+ struct ttm_buffer_object *bo;
+ struct ttm_bo_driver *driver;
+ struct ttm_bo_kmap_obj map;
+ unsigned long dev_offset = (*f_pos >> PAGE_SHIFT);
+ unsigned long kmap_offset;
+ unsigned long kmap_end;
+ unsigned long kmap_num;
+ size_t io_size;
+ unsigned int page_offset;
+ char *virtual;
+ int ret;
+ bool no_wait = false;
+ bool dummy;
+
+ read_lock(&bdev->vm_lock);
+ bo = ttm_bo_vm_lookup_rb(bdev, dev_offset, 1);
+ if (likely(bo != NULL))
+ ttm_bo_reference(bo);
+ read_unlock(&bdev->vm_lock);
+
+ if (unlikely(bo == NULL))
+ return -EFAULT;
+
+ driver = bo->bdev->driver;
+ if (unlikely(!driver->verify_access)) {
+ ret = -EPERM;
+ goto out_unref;
+ }
+
+ ret = driver->verify_access(bo, filp);
+ if (unlikely(ret != 0))
+ goto out_unref;
+
+ kmap_offset = dev_offset - bo->vm_node->start;
+ if (unlikely(kmap_offset >= bo->num_pages)) {
+ ret = -EFBIG;
+ goto out_unref;
+ }
+
+ page_offset = *f_pos & ~PAGE_MASK;
+ io_size = bo->num_pages - kmap_offset;
+ io_size = (io_size << PAGE_SHIFT) - page_offset;
+ if (count < io_size)
+ io_size = count;
+
+ kmap_end = (*f_pos + count - 1) >> PAGE_SHIFT;
+ kmap_num = kmap_end - kmap_offset + 1;
+
+ ret = ttm_bo_reserve(bo, true, no_wait, false, 0);
+
+ switch (ret) {
+ case 0:
+ break;
+ case -EBUSY:
+ ret = -EAGAIN;
+ goto out_unref;
+ default:
+ goto out_unref;
+ }
+
+ ret = ttm_bo_kmap(bo, kmap_offset, kmap_num, &map);
+ if (unlikely(ret != 0)) {
+ ttm_bo_unreserve(bo);
+ goto out_unref;
+ }
+
+ virtual = ttm_kmap_obj_virtual(&map, &dummy);
+ virtual += page_offset;
+
+ if (write)
+ ret = copy_from_user(virtual, wbuf, io_size);
+ else
+ ret = copy_to_user(rbuf, virtual, io_size);
+
+ ttm_bo_kunmap(&map);
+ ttm_bo_unreserve(bo);
+ ttm_bo_unref(&bo);
+
+ if (unlikely(ret != 0))
+ return -EFBIG;
+
+ *f_pos += io_size;
+
+ return io_size;
+out_unref:
+ ttm_bo_unref(&bo);
+ return ret;
+}
+
+ssize_t ttm_bo_fbdev_io(struct ttm_buffer_object *bo, const char __user *wbuf,
+ char __user *rbuf, size_t count, loff_t *f_pos,
+ bool write)
+{
+ struct ttm_bo_kmap_obj map;
+ unsigned long kmap_offset;
+ unsigned long kmap_end;
+ unsigned long kmap_num;
+ size_t io_size;
+ unsigned int page_offset;
+ char *virtual;
+ int ret;
+ bool no_wait = false;
+ bool dummy;
+
+ kmap_offset = (*f_pos >> PAGE_SHIFT);
+ if (unlikely(kmap_offset >= bo->num_pages))
+ return -EFBIG;
+
+ page_offset = *f_pos & ~PAGE_MASK;
+ io_size = bo->num_pages - kmap_offset;
+ io_size = (io_size << PAGE_SHIFT) - page_offset;
+ if (count < io_size)
+ io_size = count;
+
+ kmap_end = (*f_pos + count - 1) >> PAGE_SHIFT;
+ kmap_num = kmap_end - kmap_offset + 1;
+
+ ret = ttm_bo_reserve(bo, true, no_wait, false, 0);
+
+ switch (ret) {
+ case 0:
+ break;
+ case -EBUSY:
+ return -EAGAIN;
+ default:
+ return ret;
+ }
+
+ ret = ttm_bo_kmap(bo, kmap_offset, kmap_num, &map);
+ if (unlikely(ret != 0)) {
+ ttm_bo_unreserve(bo);
+ return ret;
+ }
+
+ virtual = ttm_kmap_obj_virtual(&map, &dummy);
+ virtual += page_offset;
+
+ if (write)
+ ret = copy_from_user(virtual, wbuf, io_size);
+ else
+ ret = copy_to_user(rbuf, virtual, io_size);
+
+ ttm_bo_kunmap(&map);
+ ttm_bo_unreserve(bo);
+ ttm_bo_unref(&bo);
+
+ if (unlikely(ret != 0))
+ return ret;
+
+ *f_pos += io_size;
+
+ return io_size;
+}
+#endif
diff --git a/sys/dev/drm2/ttm/ttm_execbuf_util.c b/sys/dev/drm2/ttm/ttm_execbuf_util.c
new file mode 100644
index 0000000..ce5cf15
--- /dev/null
+++ b/sys/dev/drm2/ttm/ttm_execbuf_util.c
@@ -0,0 +1,230 @@
+/**************************************************************************
+ *
+ * Copyright (c) 2006-2009 VMware, Inc., Palo Alto, CA., USA
+ * All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sub license, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the
+ * next paragraph) shall be included in all copies or substantial portions
+ * of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDERS, AUTHORS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM,
+ * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
+ * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
+ * USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ **************************************************************************/
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include <dev/drm2/drmP.h>
+#include <dev/drm2/ttm/ttm_execbuf_util.h>
+#include <dev/drm2/ttm/ttm_bo_driver.h>
+#include <dev/drm2/ttm/ttm_placement.h>
+
+static void ttm_eu_backoff_reservation_locked(struct list_head *list)
+{
+ struct ttm_validate_buffer *entry;
+
+ list_for_each_entry(entry, list, head) {
+ struct ttm_buffer_object *bo = entry->bo;
+ if (!entry->reserved)
+ continue;
+
+ if (entry->removed) {
+ ttm_bo_add_to_lru(bo);
+ entry->removed = false;
+
+ }
+ entry->reserved = false;
+ atomic_set(&bo->reserved, 0);
+ wakeup(bo);
+ }
+}
+
+static void ttm_eu_del_from_lru_locked(struct list_head *list)
+{
+ struct ttm_validate_buffer *entry;
+
+ list_for_each_entry(entry, list, head) {
+ struct ttm_buffer_object *bo = entry->bo;
+ if (!entry->reserved)
+ continue;
+
+ if (!entry->removed) {
+ entry->put_count = ttm_bo_del_from_lru(bo);
+ entry->removed = true;
+ }
+ }
+}
+
+static void ttm_eu_list_ref_sub(struct list_head *list)
+{
+ struct ttm_validate_buffer *entry;
+
+ list_for_each_entry(entry, list, head) {
+ struct ttm_buffer_object *bo = entry->bo;
+
+ if (entry->put_count) {
+ ttm_bo_list_ref_sub(bo, entry->put_count, true);
+ entry->put_count = 0;
+ }
+ }
+}
+
+static int ttm_eu_wait_unreserved_locked(struct list_head *list,
+ struct ttm_buffer_object *bo)
+{
+ int ret;
+
+ ttm_eu_del_from_lru_locked(list);
+ ret = ttm_bo_wait_unreserved_locked(bo, true);
+ if (unlikely(ret != 0))
+ ttm_eu_backoff_reservation_locked(list);
+ return ret;
+}
+
+
+void ttm_eu_backoff_reservation(struct list_head *list)
+{
+ struct ttm_validate_buffer *entry;
+ struct ttm_bo_global *glob;
+
+ if (list_empty(list))
+ return;
+
+ entry = list_first_entry(list, struct ttm_validate_buffer, head);
+ glob = entry->bo->glob;
+ mtx_lock(&glob->lru_lock);
+ ttm_eu_backoff_reservation_locked(list);
+ mtx_unlock(&glob->lru_lock);
+}
+
+/*
+ * Reserve buffers for validation.
+ *
+ * If a buffer in the list is marked for CPU access, we back off and
+ * wait for that buffer to become free for GPU access.
+ *
+ * If a buffer is reserved for another validation, the validator with
+ * the highest validation sequence backs off and waits for that buffer
+ * to become unreserved. This prevents deadlocks when validating multiple
+ * buffers in different orders.
+ */
+
+int ttm_eu_reserve_buffers(struct list_head *list)
+{
+ struct ttm_bo_global *glob;
+ struct ttm_validate_buffer *entry;
+ int ret;
+ uint32_t val_seq;
+
+ if (list_empty(list))
+ return 0;
+
+ list_for_each_entry(entry, list, head) {
+ entry->reserved = false;
+ entry->put_count = 0;
+ entry->removed = false;
+ }
+
+ entry = list_first_entry(list, struct ttm_validate_buffer, head);
+ glob = entry->bo->glob;
+
+ mtx_lock(&glob->lru_lock);
+retry_locked:
+ val_seq = entry->bo->bdev->val_seq++;
+
+ list_for_each_entry(entry, list, head) {
+ struct ttm_buffer_object *bo = entry->bo;
+
+retry_this_bo:
+ ret = ttm_bo_reserve_locked(bo, true, true, true, val_seq);
+ switch (ret) {
+ case 0:
+ break;
+ case -EBUSY:
+ ret = ttm_eu_wait_unreserved_locked(list, bo);
+ if (unlikely(ret != 0)) {
+ mtx_unlock(&glob->lru_lock);
+ ttm_eu_list_ref_sub(list);
+ return ret;
+ }
+ goto retry_this_bo;
+ case -EAGAIN:
+ ttm_eu_backoff_reservation_locked(list);
+ ttm_eu_list_ref_sub(list);
+ ret = ttm_bo_wait_unreserved_locked(bo, true);
+ if (unlikely(ret != 0)) {
+ mtx_unlock(&glob->lru_lock);
+ return ret;
+ }
+ goto retry_locked;
+ default:
+ ttm_eu_backoff_reservation_locked(list);
+ mtx_unlock(&glob->lru_lock);
+ ttm_eu_list_ref_sub(list);
+ return ret;
+ }
+
+ entry->reserved = true;
+ if (unlikely(atomic_read(&bo->cpu_writers) > 0)) {
+ ttm_eu_backoff_reservation_locked(list);
+ mtx_unlock(&glob->lru_lock);
+ ttm_eu_list_ref_sub(list);
+ return -EBUSY;
+ }
+ }
+
+ ttm_eu_del_from_lru_locked(list);
+ mtx_unlock(&glob->lru_lock);
+ ttm_eu_list_ref_sub(list);
+
+ return 0;
+}
+
+void ttm_eu_fence_buffer_objects(struct list_head *list, void *sync_obj)
+{
+ struct ttm_validate_buffer *entry;
+ struct ttm_buffer_object *bo;
+ struct ttm_bo_global *glob;
+ struct ttm_bo_device *bdev;
+ struct ttm_bo_driver *driver;
+
+ if (list_empty(list))
+ return;
+
+ bo = list_first_entry(list, struct ttm_validate_buffer, head)->bo;
+ bdev = bo->bdev;
+ driver = bdev->driver;
+ glob = bo->glob;
+
+ mtx_lock(&glob->lru_lock);
+ mtx_lock(&bdev->fence_lock);
+
+ list_for_each_entry(entry, list, head) {
+ bo = entry->bo;
+ entry->old_sync_obj = bo->sync_obj;
+ bo->sync_obj = driver->sync_obj_ref(sync_obj);
+ ttm_bo_unreserve_locked(bo);
+ entry->reserved = false;
+ }
+ mtx_unlock(&bdev->fence_lock);
+ mtx_unlock(&glob->lru_lock);
+
+ list_for_each_entry(entry, list, head) {
+ if (entry->old_sync_obj)
+ driver->sync_obj_unref(&entry->old_sync_obj);
+ }
+}
diff --git a/sys/dev/drm2/ttm/ttm_execbuf_util.h b/sys/dev/drm2/ttm/ttm_execbuf_util.h
new file mode 100644
index 0000000..68b0eba
--- /dev/null
+++ b/sys/dev/drm2/ttm/ttm_execbuf_util.h
@@ -0,0 +1,109 @@
+/**************************************************************************
+ *
+ * Copyright (c) 2006-2009 VMware, Inc., Palo Alto, CA., USA
+ * All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sub license, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the
+ * next paragraph) shall be included in all copies or substantial portions
+ * of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDERS, AUTHORS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM,
+ * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
+ * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
+ * USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ **************************************************************************/
+/*
+ * Authors: Thomas Hellstrom <thellstrom-at-vmware-dot-com>
+ */
+/* $FreeBSD$ */
+
+#ifndef _TTM_EXECBUF_UTIL_H_
+#define _TTM_EXECBUF_UTIL_H_
+
+#include <dev/drm2/ttm/ttm_bo_api.h>
+
+/**
+ * struct ttm_validate_buffer
+ *
+ * @head: list head for thread-private list.
+ * @bo: refcounted buffer object pointer.
+ * @reserved: Indicates whether @bo has been reserved for validation.
+ * @removed: Indicates whether @bo has been removed from lru lists.
+ * @put_count: Number of outstanding references on bo::list_kref.
+ * @old_sync_obj: Pointer to a sync object about to be unreferenced
+ */
+
+struct ttm_validate_buffer {
+ struct list_head head;
+ struct ttm_buffer_object *bo;
+ bool reserved;
+ bool removed;
+ int put_count;
+ void *old_sync_obj;
+};
+
+/**
+ * function ttm_eu_backoff_reservation
+ *
+ * @list: thread private list of ttm_validate_buffer structs.
+ *
+ * Undoes all buffer validation reservations for bos pointed to by
+ * the list entries.
+ */
+
+extern void ttm_eu_backoff_reservation(struct list_head *list);
+
+/**
+ * function ttm_eu_reserve_buffers
+ *
+ * @list: thread private list of ttm_validate_buffer structs.
+ *
+ * Tries to reserve bos pointed to by the list entries for validation.
+ * If the function returns 0, all buffers are marked as "unfenced",
+ * taken off the lru lists and are not synced for write CPU usage.
+ *
+ * If the function detects a deadlock due to multiple threads trying to
+ * reserve the same buffers in reverse order, all threads except one will
+ * back off and retry. This function may sleep while waiting for
+ * CPU write reservations to be cleared, and for other threads to
+ * unreserve their buffers.
+ *
+ * This function may return -ERESTART or -EAGAIN if the calling process
+ * receives a signal while waiting. In that case, no buffers on the list
+ * will be reserved upon return.
+ *
+ * Buffers reserved by this function should be unreserved by
+ * a call to either ttm_eu_backoff_reservation() or
+ * ttm_eu_fence_buffer_objects() when command submission is complete or
+ * has failed.
+ */
+
+extern int ttm_eu_reserve_buffers(struct list_head *list);
+
+/**
+ * function ttm_eu_fence_buffer_objects.
+ *
+ * @list: thread private list of ttm_validate_buffer structs.
+ * @sync_obj: The new sync object for the buffers.
+ *
+ * This function should be called when command submission is complete, and
+ * it will add a new sync object to bos pointed to by entries on @list.
+ * It also unreserves all buffers, putting them on lru lists.
+ *
+ */
+
+extern void ttm_eu_fence_buffer_objects(struct list_head *list, void *sync_obj);
+
+#endif
diff --git a/sys/dev/drm2/ttm/ttm_lock.c b/sys/dev/drm2/ttm/ttm_lock.c
new file mode 100644
index 0000000..8ec3041
--- /dev/null
+++ b/sys/dev/drm2/ttm/ttm_lock.c
@@ -0,0 +1,340 @@
+/**************************************************************************
+ *
+ * Copyright (c) 2007-2009 VMware, Inc., Palo Alto, CA., USA
+ * All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sub license, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the
+ * next paragraph) shall be included in all copies or substantial portions
+ * of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDERS, AUTHORS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM,
+ * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
+ * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
+ * USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ **************************************************************************/
+/*
+ * Authors: Thomas Hellstrom <thellstrom-at-vmware-dot-com>
+ */
+/*
+ * Copyright (c) 2013 The FreeBSD Foundation
+ * All rights reserved.
+ *
+ * Portions of this software were developed by Konstantin Belousov
+ * <kib@FreeBSD.org> under sponsorship from the FreeBSD Foundation.
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include <dev/drm2/ttm/ttm_lock.h>
+#include <dev/drm2/ttm/ttm_module.h>
+
+#define TTM_WRITE_LOCK_PENDING (1 << 0)
+#define TTM_VT_LOCK_PENDING (1 << 1)
+#define TTM_SUSPEND_LOCK_PENDING (1 << 2)
+#define TTM_VT_LOCK (1 << 3)
+#define TTM_SUSPEND_LOCK (1 << 4)
+
+void ttm_lock_init(struct ttm_lock *lock)
+{
+ mtx_init(&lock->lock, "ttmlk", NULL, MTX_DEF);
+ lock->rw = 0;
+ lock->flags = 0;
+ lock->kill_takers = false;
+ lock->signal = SIGKILL;
+}
+
+static void
+ttm_lock_send_sig(int signo)
+{
+ struct proc *p;
+
+ p = curproc; /* XXXKIB curthread ? */
+ PROC_LOCK(p);
+ kern_psignal(p, signo);
+ PROC_UNLOCK(p);
+}
+
+void ttm_read_unlock(struct ttm_lock *lock)
+{
+ mtx_lock(&lock->lock);
+ if (--lock->rw == 0)
+ wakeup(lock);
+ mtx_unlock(&lock->lock);
+}
+
+static bool __ttm_read_lock(struct ttm_lock *lock)
+{
+ bool locked = false;
+
+ if (unlikely(lock->kill_takers)) {
+ ttm_lock_send_sig(lock->signal);
+ return false;
+ }
+ if (lock->rw >= 0 && lock->flags == 0) {
+ ++lock->rw;
+ locked = true;
+ }
+ return locked;
+}
+
+int
+ttm_read_lock(struct ttm_lock *lock, bool interruptible)
+{
+ const char *wmsg;
+ int flags, ret;
+
+ ret = 0;
+ if (interruptible) {
+ flags = PCATCH;
+ wmsg = "ttmri";
+ } else {
+ flags = 0;
+ wmsg = "ttmr";
+ }
+ mtx_lock(&lock->lock);
+ while (!__ttm_read_lock(lock)) {
+ ret = msleep(lock, &lock->lock, flags, wmsg, 0);
+ if (ret != 0)
+ break;
+ }
+ return (-ret);
+}
+
+static bool __ttm_read_trylock(struct ttm_lock *lock, bool *locked)
+{
+ bool block = true;
+
+ *locked = false;
+
+ if (unlikely(lock->kill_takers)) {
+ ttm_lock_send_sig(lock->signal);
+ return false;
+ }
+ if (lock->rw >= 0 && lock->flags == 0) {
+ ++lock->rw;
+ block = false;
+ *locked = true;
+ } else if (lock->flags == 0) {
+ block = false;
+ }
+
+ return !block;
+}
+
+int ttm_read_trylock(struct ttm_lock *lock, bool interruptible)
+{
+ const char *wmsg;
+ int flags, ret;
+ bool locked;
+
+ ret = 0;
+ if (interruptible) {
+ flags = PCATCH;
+ wmsg = "ttmrti";
+ } else {
+ flags = 0;
+ wmsg = "ttmrt";
+ }
+ mtx_lock(&lock->lock);
+ while (!__ttm_read_trylock(lock, &locked)) {
+ ret = msleep(lock, &lock->lock, flags, wmsg, 0);
+ if (ret != 0)
+ break;
+ }
+ MPASS(!locked || ret == 0);
+ mtx_unlock(&lock->lock);
+
+ return (locked) ? 0 : -EBUSY;
+}
+
+void ttm_write_unlock(struct ttm_lock *lock)
+{
+ mtx_lock(&lock->lock);
+ lock->rw = 0;
+ wakeup(lock);
+ mtx_unlock(&lock->lock);
+}
+
+static bool __ttm_write_lock(struct ttm_lock *lock)
+{
+ bool locked = false;
+
+ if (unlikely(lock->kill_takers)) {
+ ttm_lock_send_sig(lock->signal);
+ return false;
+ }
+ if (lock->rw == 0 && ((lock->flags & ~TTM_WRITE_LOCK_PENDING) == 0)) {
+ lock->rw = -1;
+ lock->flags &= ~TTM_WRITE_LOCK_PENDING;
+ locked = true;
+ } else {
+ lock->flags |= TTM_WRITE_LOCK_PENDING;
+ }
+ return locked;
+}
+
+int
+ttm_write_lock(struct ttm_lock *lock, bool interruptible)
+{
+ const char *wmsg;
+ int flags, ret;
+
+ ret = 0;
+ if (interruptible) {
+ flags = PCATCH;
+ wmsg = "ttmwi";
+ } else {
+ flags = 0;
+ wmsg = "ttmw";
+ }
+ mtx_lock(&lock->lock);
+ /* XXXKIB: linux uses __ttm_read_lock for uninterruptible sleeps */
+ while (!__ttm_write_lock(lock)) {
+ ret = msleep(lock, &lock->lock, flags, wmsg, 0);
+ if (interruptible && ret != 0) {
+ lock->flags &= ~TTM_WRITE_LOCK_PENDING;
+ wakeup(lock);
+ break;
+ }
+ }
+ mtx_unlock(&lock->lock);
+
+ return (-ret);
+}
+
+void ttm_write_lock_downgrade(struct ttm_lock *lock)
+{
+ mtx_lock(&lock->lock);
+ lock->rw = 1;
+ wakeup(lock);
+ mtx_unlock(&lock->lock);
+}
+
+static int __ttm_vt_unlock(struct ttm_lock *lock)
+{
+ int ret = 0;
+
+ mtx_lock(&lock->lock);
+ if (unlikely(!(lock->flags & TTM_VT_LOCK)))
+ ret = -EINVAL;
+ lock->flags &= ~TTM_VT_LOCK;
+ wakeup(lock);
+ mtx_unlock(&lock->lock);
+
+ return ret;
+}
+
+static void ttm_vt_lock_remove(struct ttm_base_object **p_base)
+{
+ struct ttm_base_object *base = *p_base;
+ struct ttm_lock *lock = container_of(base, struct ttm_lock, base);
+ int ret;
+
+ *p_base = NULL;
+ ret = __ttm_vt_unlock(lock);
+ MPASS(ret == 0);
+}
+
+static bool __ttm_vt_lock(struct ttm_lock *lock)
+{
+ bool locked = false;
+
+ if (lock->rw == 0) {
+ lock->flags &= ~TTM_VT_LOCK_PENDING;
+ lock->flags |= TTM_VT_LOCK;
+ locked = true;
+ } else {
+ lock->flags |= TTM_VT_LOCK_PENDING;
+ }
+ return locked;
+}
+
+int ttm_vt_lock(struct ttm_lock *lock,
+ bool interruptible,
+ struct ttm_object_file *tfile)
+{
+ const char *wmsg;
+ int flags, ret;
+
+ ret = 0;
+ if (interruptible) {
+ flags = PCATCH;
+ wmsg = "ttmwi";
+ } else {
+ flags = 0;
+ wmsg = "ttmw";
+ }
+ mtx_lock(&lock->lock);
+ while (!__ttm_vt_lock(lock)) {
+ ret = msleep(lock, &lock->lock, flags, wmsg, 0);
+ if (interruptible && ret != 0) {
+ lock->flags &= ~TTM_VT_LOCK_PENDING;
+ wakeup(lock);
+ break;
+ }
+ }
+
+ /*
+ * Add a base-object, the destructor of which will
+ * make sure the lock is released if the client dies
+ * while holding it.
+ */
+
+ ret = ttm_base_object_init(tfile, &lock->base, false,
+ ttm_lock_type, &ttm_vt_lock_remove, NULL);
+ if (ret)
+ (void)__ttm_vt_unlock(lock);
+ else
+ lock->vt_holder = tfile;
+
+ return (-ret);
+}
+
+int ttm_vt_unlock(struct ttm_lock *lock)
+{
+ return ttm_ref_object_base_unref(lock->vt_holder,
+ lock->base.hash.key, TTM_REF_USAGE);
+}
+
+void ttm_suspend_unlock(struct ttm_lock *lock)
+{
+ mtx_lock(&lock->lock);
+ lock->flags &= ~TTM_SUSPEND_LOCK;
+ wakeup(lock);
+ mtx_unlock(&lock->lock);
+}
+
+static bool __ttm_suspend_lock(struct ttm_lock *lock)
+{
+ bool locked = false;
+
+ if (lock->rw == 0) {
+ lock->flags &= ~TTM_SUSPEND_LOCK_PENDING;
+ lock->flags |= TTM_SUSPEND_LOCK;
+ locked = true;
+ } else {
+ lock->flags |= TTM_SUSPEND_LOCK_PENDING;
+ }
+ return locked;
+}
+
+void ttm_suspend_lock(struct ttm_lock *lock)
+{
+ mtx_lock(&lock->lock);
+ while (!__ttm_suspend_lock(lock))
+ msleep(lock, &lock->lock, 0, "ttms", 0);
+ mtx_unlock(&lock->lock);
+}
diff --git a/sys/dev/drm2/ttm/ttm_lock.h b/sys/dev/drm2/ttm/ttm_lock.h
new file mode 100644
index 0000000..6d45457
--- /dev/null
+++ b/sys/dev/drm2/ttm/ttm_lock.h
@@ -0,0 +1,228 @@
+/**************************************************************************
+ *
+ * Copyright (c) 2007-2009 VMware, Inc., Palo Alto, CA., USA
+ * All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sub license, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the
+ * next paragraph) shall be included in all copies or substantial portions
+ * of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDERS, AUTHORS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM,
+ * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
+ * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
+ * USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ **************************************************************************/
+/*
+ * Authors: Thomas Hellstrom <thellstrom-at-vmware-dot-com>
+ */
+/* $FreeBSD$ */
+
+/** @file ttm_lock.h
+ * This file implements a simple replacement for the buffer manager use
+ * of the DRM heavyweight hardware lock.
+ * The lock is a read-write lock. Taking it in read mode and write mode
+ * is relatively fast, and intended for in-kernel use only.
+ *
+ * The vt mode is used only when there is a need to block all
+ * user-space processes from validating buffers.
+ * It's allowed to leave kernel space with the vt lock held.
+ * If a user-space process dies while having the vt-lock,
+ * it will be released during the file descriptor release. The vt lock
+ * excludes write lock and read lock.
+ *
+ * The suspend mode is used to lock out all TTM users when preparing for
+ * and executing suspend operations.
+ *
+ */
+
+#ifndef _TTM_LOCK_H_
+#define _TTM_LOCK_H_
+
+#include <dev/drm2/drmP.h>
+#include <dev/drm2/drm.h>
+#include <dev/drm2/ttm/ttm_object.h>
+
+/**
+ * struct ttm_lock
+ *
+ * @base: ttm base object used solely to release the lock if the client
+ * holding the lock dies.
+ * @queue: Queue for processes waiting for lock change-of-status.
+ * @lock: Spinlock protecting some lock members.
+ * @rw: Read-write lock counter. Protected by @lock.
+ * @flags: Lock state. Protected by @lock.
+ * @kill_takers: Boolean whether to kill takers of the lock.
+ * @signal: Signal to send when kill_takers is true.
+ */
+
+struct ttm_lock {
+ struct ttm_base_object base;
+ struct mtx lock;
+ int32_t rw;
+ uint32_t flags;
+ bool kill_takers;
+ int signal;
+ struct ttm_object_file *vt_holder;
+};
+
+
+/**
+ * ttm_lock_init
+ *
+ * @lock: Pointer to a struct ttm_lock
+ * Initializes the lock.
+ */
+extern void ttm_lock_init(struct ttm_lock *lock);
+
+/**
+ * ttm_read_unlock
+ *
+ * @lock: Pointer to a struct ttm_lock
+ *
+ * Releases a read lock.
+ */
+extern void ttm_read_unlock(struct ttm_lock *lock);
+
+/**
+ * ttm_read_lock
+ *
+ * @lock: Pointer to a struct ttm_lock
+ * @interruptible: Interruptible sleeping while waiting for a lock.
+ *
+ * Takes the lock in read mode.
+ * Returns:
+ * -ERESTARTSYS If interrupted by a signal and interruptible is true.
+ */
+extern int ttm_read_lock(struct ttm_lock *lock, bool interruptible);
+
+/**
+ * ttm_read_trylock
+ *
+ * @lock: Pointer to a struct ttm_lock
+ * @interruptible: Interruptible sleeping while waiting for a lock.
+ *
+ * Tries to take the lock in read mode. If the lock is already held
+ * in write mode, the function will return -EBUSY. If the lock is held
+ * in vt or suspend mode, the function will sleep until these modes
+ * are unlocked.
+ *
+ * Returns:
+ * -EBUSY The lock was already held in write mode.
+ * -ERESTARTSYS If interrupted by a signal and interruptible is true.
+ */
+extern int ttm_read_trylock(struct ttm_lock *lock, bool interruptible);
+
+/**
+ * ttm_lock_downgrade
+ *
+ * @lock: Pointer to a struct ttm_lock
+ *
+ * Downgrades a write lock to a read lock.
+ */
+extern void ttm_lock_downgrade(struct ttm_lock *lock);
+
+/**
+ * ttm_suspend_lock
+ *
+ * @lock: Pointer to a struct ttm_lock
+ *
+ * Takes the lock in suspend mode. Excludes read and write mode.
+ */
+extern void ttm_suspend_lock(struct ttm_lock *lock);
+
+/**
+ * ttm_suspend_unlock
+ *
+ * @lock: Pointer to a struct ttm_lock
+ *
+ * Releases a suspend lock
+ */
+extern void ttm_suspend_unlock(struct ttm_lock *lock);
+
+/**
+ * ttm_vt_lock
+ *
+ * @lock: Pointer to a struct ttm_lock
+ * @interruptible: Interruptible sleeping while waiting for a lock.
+ * @tfile: Pointer to a struct ttm_object_file to register the lock with.
+ *
+ * Takes the lock in vt mode.
+ * Returns:
+ * -ERESTARTSYS If interrupted by a signal and interruptible is true.
+ * -ENOMEM: Out of memory when locking.
+ */
+extern int ttm_vt_lock(struct ttm_lock *lock, bool interruptible,
+ struct ttm_object_file *tfile);
+
+/**
+ * ttm_vt_unlock
+ *
+ * @lock: Pointer to a struct ttm_lock
+ *
+ * Releases a vt lock.
+ * Returns:
+ * -EINVAL If the lock was not held.
+ */
+extern int ttm_vt_unlock(struct ttm_lock *lock);
+
+/**
+ * ttm_write_unlock
+ *
+ * @lock: Pointer to a struct ttm_lock
+ *
+ * Releases a write lock.
+ */
+extern void ttm_write_unlock(struct ttm_lock *lock);
+
+/**
+ * ttm_write_lock
+ *
+ * @lock: Pointer to a struct ttm_lock
+ * @interruptible: Interruptible sleeping while waiting for a lock.
+ *
+ * Takes the lock in write mode.
+ * Returns:
+ * -ERESTARTSYS If interrupted by a signal and interruptible is true.
+ */
+extern int ttm_write_lock(struct ttm_lock *lock, bool interruptible);
+
+void ttm_write_lock_downgrade(struct ttm_lock *lock);
+
+/**
+ * ttm_lock_set_kill
+ *
+ * @lock: Pointer to a struct ttm_lock
+ * @val: Boolean whether to kill processes taking the lock.
+ * @signal: Signal to send to the process taking the lock.
+ *
+ * The kill-when-taking-lock functionality is used to kill processes that keep
+ * on using the TTM functionality when its resources has been taken down, for
+ * example when the X server exits. A typical sequence would look like this:
+ * - X server takes lock in write mode.
+ * - ttm_lock_set_kill() is called with @val set to true.
+ * - As part of X server exit, TTM resources are taken down.
+ * - X server releases the lock on file release.
+ * - Another dri client wants to render, takes the lock and is killed.
+ *
+ */
+static inline void ttm_lock_set_kill(struct ttm_lock *lock, bool val,
+ int signal)
+{
+ lock->kill_takers = val;
+ if (val)
+ lock->signal = signal;
+}
+
+#endif
diff --git a/sys/dev/drm2/ttm/ttm_memory.c b/sys/dev/drm2/ttm/ttm_memory.c
new file mode 100644
index 0000000..ee74d94
--- /dev/null
+++ b/sys/dev/drm2/ttm/ttm_memory.c
@@ -0,0 +1,471 @@
+/**************************************************************************
+ *
+ * Copyright (c) 2006-2009 VMware, Inc., Palo Alto, CA., USA
+ * All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sub license, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the
+ * next paragraph) shall be included in all copies or substantial portions
+ * of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDERS, AUTHORS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM,
+ * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
+ * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
+ * USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ **************************************************************************/
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include <dev/drm2/drmP.h>
+#include <dev/drm2/ttm/ttm_memory.h>
+#include <dev/drm2/ttm/ttm_module.h>
+#include <dev/drm2/ttm/ttm_page_alloc.h>
+
+#define TTM_MEMORY_ALLOC_RETRIES 4
+
+struct ttm_mem_zone {
+ u_int kobj_ref;
+ struct ttm_mem_global *glob;
+ const char *name;
+ uint64_t zone_mem;
+ uint64_t emer_mem;
+ uint64_t max_mem;
+ uint64_t swap_limit;
+ uint64_t used_mem;
+};
+
+MALLOC_DEFINE(M_TTM_ZONE, "ttm_zone", "TTM Zone");
+
+static void ttm_mem_zone_kobj_release(struct ttm_mem_zone *zone)
+{
+
+ printf("pTTM] Zone %7s: Used memory at exit: %llu kiB\n",
+ zone->name, (unsigned long long)zone->used_mem >> 10);
+ free(zone, M_TTM_ZONE);
+}
+
+#if 0
+/* XXXKIB sysctl */
+static ssize_t ttm_mem_zone_show(struct ttm_mem_zone *zone;
+ struct attribute *attr,
+ char *buffer)
+{
+ uint64_t val = 0;
+
+ mtx_lock(&zone->glob->lock);
+ if (attr == &ttm_mem_sys)
+ val = zone->zone_mem;
+ else if (attr == &ttm_mem_emer)
+ val = zone->emer_mem;
+ else if (attr == &ttm_mem_max)
+ val = zone->max_mem;
+ else if (attr == &ttm_mem_swap)
+ val = zone->swap_limit;
+ else if (attr == &ttm_mem_used)
+ val = zone->used_mem;
+ mtx_unlock(&zone->glob->lock);
+
+ return snprintf(buffer, PAGE_SIZE, "%llu\n",
+ (unsigned long long) val >> 10);
+}
+#endif
+
+static void ttm_check_swapping(struct ttm_mem_global *glob);
+
+#if 0
+/* XXXKIB sysctl */
+static ssize_t ttm_mem_zone_store(struct ttm_mem_zone *zone,
+ struct attribute *attr,
+ const char *buffer,
+ size_t size)
+{
+ int chars;
+ unsigned long val;
+ uint64_t val64;
+
+ chars = sscanf(buffer, "%lu", &val);
+ if (chars == 0)
+ return size;
+
+ val64 = val;
+ val64 <<= 10;
+
+ mtx_lock(&zone->glob->lock);
+ if (val64 > zone->zone_mem)
+ val64 = zone->zone_mem;
+ if (attr == &ttm_mem_emer) {
+ zone->emer_mem = val64;
+ if (zone->max_mem > val64)
+ zone->max_mem = val64;
+ } else if (attr == &ttm_mem_max) {
+ zone->max_mem = val64;
+ if (zone->emer_mem < val64)
+ zone->emer_mem = val64;
+ } else if (attr == &ttm_mem_swap)
+ zone->swap_limit = val64;
+ mtx_unlock(&zone->glob->lock);
+
+ ttm_check_swapping(zone->glob);
+
+ return size;
+}
+#endif
+
+static void ttm_mem_global_kobj_release(struct ttm_mem_global *glob)
+{
+
+ free(glob, M_TTM_ZONE);
+}
+
+static bool ttm_zones_above_swap_target(struct ttm_mem_global *glob,
+ bool from_wq, uint64_t extra)
+{
+ unsigned int i;
+ struct ttm_mem_zone *zone;
+ uint64_t target;
+
+ for (i = 0; i < glob->num_zones; ++i) {
+ zone = glob->zones[i];
+
+ if (from_wq)
+ target = zone->swap_limit;
+ else if (priv_check(curthread, PRIV_VM_MLOCK) == 0)
+ target = zone->emer_mem;
+ else
+ target = zone->max_mem;
+
+ target = (extra > target) ? 0ULL : target;
+
+ if (zone->used_mem > target)
+ return true;
+ }
+ return false;
+}
+
+/**
+ * At this point we only support a single shrink callback.
+ * Extend this if needed, perhaps using a linked list of callbacks.
+ * Note that this function is reentrant:
+ * many threads may try to swap out at any given time.
+ */
+
+static void ttm_shrink(struct ttm_mem_global *glob, bool from_wq,
+ uint64_t extra)
+{
+ int ret;
+ struct ttm_mem_shrink *shrink;
+
+ mtx_lock(&glob->lock);
+ if (glob->shrink == NULL)
+ goto out;
+
+ while (ttm_zones_above_swap_target(glob, from_wq, extra)) {
+ shrink = glob->shrink;
+ mtx_unlock(&glob->lock);
+ ret = shrink->do_shrink(shrink);
+ mtx_lock(&glob->lock);
+ if (unlikely(ret != 0))
+ goto out;
+ }
+out:
+ mtx_unlock(&glob->lock);
+}
+
+
+
+static void ttm_shrink_work(void *arg, int pending __unused)
+{
+ struct ttm_mem_global *glob = arg;
+
+ ttm_shrink(glob, true, 0ULL);
+}
+
+static int ttm_mem_init_kernel_zone(struct ttm_mem_global *glob,
+ uint64_t mem)
+{
+ struct ttm_mem_zone *zone;
+
+ zone = malloc(sizeof(*zone), M_TTM_ZONE, M_WAITOK | M_ZERO);
+
+ zone->name = "kernel";
+ zone->zone_mem = mem;
+ zone->max_mem = mem >> 1;
+ zone->emer_mem = (mem >> 1) + (mem >> 2);
+ zone->swap_limit = zone->max_mem - (mem >> 3);
+ zone->used_mem = 0;
+ zone->glob = glob;
+ glob->zone_kernel = zone;
+ refcount_init(&zone->kobj_ref, 1);
+ glob->zones[glob->num_zones++] = zone;
+ return 0;
+}
+
+static int ttm_mem_init_dma32_zone(struct ttm_mem_global *glob,
+ uint64_t mem)
+{
+ struct ttm_mem_zone *zone;
+
+ zone = malloc(sizeof(*zone), M_TTM_ZONE, M_WAITOK | M_ZERO);
+
+ /**
+ * No special dma32 zone needed.
+ */
+
+ if (mem <= ((uint64_t) 1ULL << 32)) {
+ free(zone, M_TTM_ZONE);
+ return 0;
+ }
+
+ /*
+ * Limit max dma32 memory to 4GB for now
+ * until we can figure out how big this
+ * zone really is.
+ */
+
+ mem = ((uint64_t) 1ULL << 32);
+ zone->name = "dma32";
+ zone->zone_mem = mem;
+ zone->max_mem = mem >> 1;
+ zone->emer_mem = (mem >> 1) + (mem >> 2);
+ zone->swap_limit = zone->max_mem - (mem >> 3);
+ zone->used_mem = 0;
+ zone->glob = glob;
+ glob->zone_dma32 = zone;
+ refcount_init(&zone->kobj_ref, 1);
+ glob->zones[glob->num_zones++] = zone;
+ return 0;
+}
+
+int ttm_mem_global_init(struct ttm_mem_global *glob)
+{
+ u_int64_t mem;
+ int ret;
+ int i;
+ struct ttm_mem_zone *zone;
+
+ mtx_init(&glob->lock, "ttmgz", NULL, MTX_DEF);
+ glob->swap_queue = taskqueue_create("ttm_swap", M_WAITOK,
+ taskqueue_thread_enqueue, &glob->swap_queue);
+ taskqueue_start_threads(&glob->swap_queue, 1, PVM, "ttm swap");
+ TASK_INIT(&glob->work, 0, ttm_shrink_work, glob);
+
+ refcount_init(&glob->kobj_ref, 1);
+
+ mem = physmem * PAGE_SIZE;
+
+ ret = ttm_mem_init_kernel_zone(glob, mem);
+ if (unlikely(ret != 0))
+ goto out_no_zone;
+ ret = ttm_mem_init_dma32_zone(glob, mem);
+ if (unlikely(ret != 0))
+ goto out_no_zone;
+ for (i = 0; i < glob->num_zones; ++i) {
+ zone = glob->zones[i];
+ printf("[TTM] Zone %7s: Available graphics memory: %llu kiB\n",
+ zone->name, (unsigned long long)zone->max_mem >> 10);
+ }
+ ttm_page_alloc_init(glob, glob->zone_kernel->max_mem/(2*PAGE_SIZE));
+ ttm_dma_page_alloc_init(glob, glob->zone_kernel->max_mem/(2*PAGE_SIZE));
+ return 0;
+out_no_zone:
+ ttm_mem_global_release(glob);
+ return ret;
+}
+
+void ttm_mem_global_release(struct ttm_mem_global *glob)
+{
+ unsigned int i;
+ struct ttm_mem_zone *zone;
+
+ /* let the page allocator first stop the shrink work. */
+ ttm_page_alloc_fini();
+ ttm_dma_page_alloc_fini();
+
+ taskqueue_drain(glob->swap_queue, &glob->work);
+ taskqueue_free(glob->swap_queue);
+ glob->swap_queue = NULL;
+ for (i = 0; i < glob->num_zones; ++i) {
+ zone = glob->zones[i];
+ if (refcount_release(&zone->kobj_ref))
+ ttm_mem_zone_kobj_release(zone);
+ }
+ if (refcount_release(&glob->kobj_ref))
+ ttm_mem_global_kobj_release(glob);
+}
+
+static void ttm_check_swapping(struct ttm_mem_global *glob)
+{
+ bool needs_swapping = false;
+ unsigned int i;
+ struct ttm_mem_zone *zone;
+
+ mtx_lock(&glob->lock);
+ for (i = 0; i < glob->num_zones; ++i) {
+ zone = glob->zones[i];
+ if (zone->used_mem > zone->swap_limit) {
+ needs_swapping = true;
+ break;
+ }
+ }
+
+ mtx_unlock(&glob->lock);
+
+ if (unlikely(needs_swapping))
+ taskqueue_enqueue(glob->swap_queue, &glob->work);
+
+}
+
+static void ttm_mem_global_free_zone(struct ttm_mem_global *glob,
+ struct ttm_mem_zone *single_zone,
+ uint64_t amount)
+{
+ unsigned int i;
+ struct ttm_mem_zone *zone;
+
+ mtx_lock(&glob->lock);
+ for (i = 0; i < glob->num_zones; ++i) {
+ zone = glob->zones[i];
+ if (single_zone && zone != single_zone)
+ continue;
+ zone->used_mem -= amount;
+ }
+ mtx_unlock(&glob->lock);
+}
+
+void ttm_mem_global_free(struct ttm_mem_global *glob,
+ uint64_t amount)
+{
+ return ttm_mem_global_free_zone(glob, NULL, amount);
+}
+
+static int ttm_mem_global_reserve(struct ttm_mem_global *glob,
+ struct ttm_mem_zone *single_zone,
+ uint64_t amount, bool reserve)
+{
+ uint64_t limit;
+ int ret = -ENOMEM;
+ unsigned int i;
+ struct ttm_mem_zone *zone;
+
+ mtx_lock(&glob->lock);
+ for (i = 0; i < glob->num_zones; ++i) {
+ zone = glob->zones[i];
+ if (single_zone && zone != single_zone)
+ continue;
+
+ limit = (priv_check(curthread, PRIV_VM_MLOCK) == 0) ?
+ zone->emer_mem : zone->max_mem;
+
+ if (zone->used_mem > limit)
+ goto out_unlock;
+ }
+
+ if (reserve) {
+ for (i = 0; i < glob->num_zones; ++i) {
+ zone = glob->zones[i];
+ if (single_zone && zone != single_zone)
+ continue;
+ zone->used_mem += amount;
+ }
+ }
+
+ ret = 0;
+out_unlock:
+ mtx_unlock(&glob->lock);
+ ttm_check_swapping(glob);
+
+ return ret;
+}
+
+
+static int ttm_mem_global_alloc_zone(struct ttm_mem_global *glob,
+ struct ttm_mem_zone *single_zone,
+ uint64_t memory,
+ bool no_wait, bool interruptible)
+{
+ int count = TTM_MEMORY_ALLOC_RETRIES;
+
+ while (unlikely(ttm_mem_global_reserve(glob,
+ single_zone,
+ memory, true)
+ != 0)) {
+ if (no_wait)
+ return -ENOMEM;
+ if (unlikely(count-- == 0))
+ return -ENOMEM;
+ ttm_shrink(glob, false, memory + (memory >> 2) + 16);
+ }
+
+ return 0;
+}
+
+int ttm_mem_global_alloc(struct ttm_mem_global *glob, uint64_t memory,
+ bool no_wait, bool interruptible)
+{
+ /**
+ * Normal allocations of kernel memory are registered in
+ * all zones.
+ */
+
+ return ttm_mem_global_alloc_zone(glob, NULL, memory, no_wait,
+ interruptible);
+}
+
+#define page_to_pfn(pp) OFF_TO_IDX(VM_PAGE_TO_PHYS(pp))
+
+int ttm_mem_global_alloc_page(struct ttm_mem_global *glob,
+ struct vm_page *page,
+ bool no_wait, bool interruptible)
+{
+
+ struct ttm_mem_zone *zone = NULL;
+
+ /**
+ * Page allocations may be registed in a single zone
+ * only if highmem or !dma32.
+ */
+
+ if (glob->zone_dma32 && page_to_pfn(page) > 0x00100000UL)
+ zone = glob->zone_kernel;
+ return ttm_mem_global_alloc_zone(glob, zone, PAGE_SIZE, no_wait,
+ interruptible);
+}
+
+void ttm_mem_global_free_page(struct ttm_mem_global *glob, struct vm_page *page)
+{
+ struct ttm_mem_zone *zone = NULL;
+
+ if (glob->zone_dma32 && page_to_pfn(page) > 0x00100000UL)
+ zone = glob->zone_kernel;
+ ttm_mem_global_free_zone(glob, zone, PAGE_SIZE);
+}
+
+
+size_t ttm_round_pot(size_t size)
+{
+ if ((size & (size - 1)) == 0)
+ return size;
+ else if (size > PAGE_SIZE)
+ return PAGE_ALIGN(size);
+ else {
+ size_t tmp_size = 4;
+
+ while (tmp_size < size)
+ tmp_size <<= 1;
+
+ return tmp_size;
+ }
+ return 0;
+}
diff --git a/sys/dev/drm2/ttm/ttm_memory.h b/sys/dev/drm2/ttm/ttm_memory.h
new file mode 100644
index 0000000..53263c6
--- /dev/null
+++ b/sys/dev/drm2/ttm/ttm_memory.h
@@ -0,0 +1,149 @@
+/**************************************************************************
+ *
+ * Copyright (c) 2006-2009 VMware, Inc., Palo Alto, CA., USA
+ * All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sub license, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the
+ * next paragraph) shall be included in all copies or substantial portions
+ * of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDERS, AUTHORS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM,
+ * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
+ * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
+ * USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ **************************************************************************/
+/* $FreeBSD$ */
+
+#ifndef TTM_MEMORY_H
+#define TTM_MEMORY_H
+
+/**
+ * struct ttm_mem_shrink - callback to shrink TTM memory usage.
+ *
+ * @do_shrink: The callback function.
+ *
+ * Arguments to the do_shrink functions are intended to be passed using
+ * inheritance. That is, the argument class derives from struct ttm_mem_shrink,
+ * and can be accessed using container_of().
+ */
+
+struct ttm_mem_shrink {
+ int (*do_shrink) (struct ttm_mem_shrink *);
+};
+
+/**
+ * struct ttm_mem_global - Global memory accounting structure.
+ *
+ * @shrink: A single callback to shrink TTM memory usage. Extend this
+ * to a linked list to be able to handle multiple callbacks when needed.
+ * @swap_queue: A workqueue to handle shrinking in low memory situations. We
+ * need a separate workqueue since it will spend a lot of time waiting
+ * for the GPU, and this will otherwise block other workqueue tasks(?)
+ * At this point we use only a single-threaded workqueue.
+ * @work: The workqueue callback for the shrink queue.
+ * @lock: Lock to protect the @shrink - and the memory accounting members,
+ * that is, essentially the whole structure with some exceptions.
+ * @zones: Array of pointers to accounting zones.
+ * @num_zones: Number of populated entries in the @zones array.
+ * @zone_kernel: Pointer to the kernel zone.
+ * @zone_highmem: Pointer to the highmem zone if there is one.
+ * @zone_dma32: Pointer to the dma32 zone if there is one.
+ *
+ * Note that this structure is not per device. It should be global for all
+ * graphics devices.
+ */
+
+#define TTM_MEM_MAX_ZONES 2
+struct ttm_mem_zone;
+struct ttm_mem_global {
+ u_int kobj_ref;
+ struct ttm_mem_shrink *shrink;
+ struct taskqueue *swap_queue;
+ struct task work;
+ struct mtx lock;
+ struct ttm_mem_zone *zones[TTM_MEM_MAX_ZONES];
+ unsigned int num_zones;
+ struct ttm_mem_zone *zone_kernel;
+ struct ttm_mem_zone *zone_dma32;
+};
+
+/**
+ * ttm_mem_init_shrink - initialize a struct ttm_mem_shrink object
+ *
+ * @shrink: The object to initialize.
+ * @func: The callback function.
+ */
+
+static inline void ttm_mem_init_shrink(struct ttm_mem_shrink *shrink,
+ int (*func) (struct ttm_mem_shrink *))
+{
+ shrink->do_shrink = func;
+}
+
+/**
+ * ttm_mem_register_shrink - register a struct ttm_mem_shrink object.
+ *
+ * @glob: The struct ttm_mem_global object to register with.
+ * @shrink: An initialized struct ttm_mem_shrink object to register.
+ *
+ * Returns:
+ * -EBUSY: There's already a callback registered. (May change).
+ */
+
+static inline int ttm_mem_register_shrink(struct ttm_mem_global *glob,
+ struct ttm_mem_shrink *shrink)
+{
+ mtx_lock(&glob->lock);
+ if (glob->shrink != NULL) {
+ mtx_unlock(&glob->lock);
+ return -EBUSY;
+ }
+ glob->shrink = shrink;
+ mtx_unlock(&glob->lock);
+ return 0;
+}
+
+/**
+ * ttm_mem_unregister_shrink - unregister a struct ttm_mem_shrink object.
+ *
+ * @glob: The struct ttm_mem_global object to unregister from.
+ * @shrink: A previously registert struct ttm_mem_shrink object.
+ *
+ */
+
+static inline void ttm_mem_unregister_shrink(struct ttm_mem_global *glob,
+ struct ttm_mem_shrink *shrink)
+{
+ mtx_lock(&glob->lock);
+ MPASS(glob->shrink == shrink);
+ glob->shrink = NULL;
+ mtx_unlock(&glob->lock);
+}
+
+struct vm_page;
+
+extern int ttm_mem_global_init(struct ttm_mem_global *glob);
+extern void ttm_mem_global_release(struct ttm_mem_global *glob);
+extern int ttm_mem_global_alloc(struct ttm_mem_global *glob, uint64_t memory,
+ bool no_wait, bool interruptible);
+extern void ttm_mem_global_free(struct ttm_mem_global *glob,
+ uint64_t amount);
+extern int ttm_mem_global_alloc_page(struct ttm_mem_global *glob,
+ struct vm_page *page,
+ bool no_wait, bool interruptible);
+extern void ttm_mem_global_free_page(struct ttm_mem_global *glob,
+ struct vm_page *page);
+extern size_t ttm_round_pot(size_t size);
+#endif
diff --git a/sys/dev/drm2/ttm/ttm_module.h b/sys/dev/drm2/ttm/ttm_module.h
new file mode 100644
index 0000000..b1ce2bc
--- /dev/null
+++ b/sys/dev/drm2/ttm/ttm_module.h
@@ -0,0 +1,37 @@
+/**************************************************************************
+ *
+ * Copyright 2008-2009 VMware, Inc., Palo Alto, CA., USA
+ * All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sub license, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the
+ * next paragraph) shall be included in all copies or substantial portions
+ * of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDERS, AUTHORS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM,
+ * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
+ * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
+ * USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ **************************************************************************/
+/*
+ * Authors: Thomas Hellstrom <thellstrom-at-vmware-dot-com>
+ */
+/* $FreeBSD$ */
+
+#ifndef _TTM_MODULE_H_
+#define _TTM_MODULE_H_
+
+#define TTM_PFX "[TTM] "
+
+#endif /* _TTM_MODULE_H_ */
diff --git a/sys/dev/drm2/ttm/ttm_object.c b/sys/dev/drm2/ttm/ttm_object.c
new file mode 100644
index 0000000..fd48044
--- /dev/null
+++ b/sys/dev/drm2/ttm/ttm_object.c
@@ -0,0 +1,455 @@
+/**************************************************************************
+ *
+ * Copyright (c) 2009 VMware, Inc., Palo Alto, CA., USA
+ * All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sub license, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the
+ * next paragraph) shall be included in all copies or substantial portions
+ * of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDERS, AUTHORS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM,
+ * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
+ * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
+ * USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ **************************************************************************/
+/*
+ * Authors: Thomas Hellstrom <thellstrom-at-vmware-dot-com>
+ */
+/** @file ttm_ref_object.c
+ *
+ * Base- and reference object implementation for the various
+ * ttm objects. Implements reference counting, minimal security checks
+ * and release on file close.
+ */
+
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+/**
+ * struct ttm_object_file
+ *
+ * @tdev: Pointer to the ttm_object_device.
+ *
+ * @lock: Lock that protects the ref_list list and the
+ * ref_hash hash tables.
+ *
+ * @ref_list: List of ttm_ref_objects to be destroyed at
+ * file release.
+ *
+ * @ref_hash: Hash tables of ref objects, one per ttm_ref_type,
+ * for fast lookup of ref objects given a base object.
+ */
+
+#define pr_fmt(fmt) "[TTM] " fmt
+
+#include <dev/drm2/drmP.h>
+#include <dev/drm2/drm.h>
+#include <sys/rwlock.h>
+#include <dev/drm2/ttm/ttm_object.h>
+#include <dev/drm2/ttm/ttm_module.h>
+
+struct ttm_object_file {
+ struct ttm_object_device *tdev;
+ struct rwlock lock;
+ struct list_head ref_list;
+ struct drm_open_hash ref_hash[TTM_REF_NUM];
+ u_int refcount;
+};
+
+/**
+ * struct ttm_object_device
+ *
+ * @object_lock: lock that protects the object_hash hash table.
+ *
+ * @object_hash: hash table for fast lookup of object global names.
+ *
+ * @object_count: Per device object count.
+ *
+ * This is the per-device data structure needed for ttm object management.
+ */
+
+struct ttm_object_device {
+ struct rwlock object_lock;
+ struct drm_open_hash object_hash;
+ atomic_t object_count;
+ struct ttm_mem_global *mem_glob;
+};
+
+/**
+ * struct ttm_ref_object
+ *
+ * @hash: Hash entry for the per-file object reference hash.
+ *
+ * @head: List entry for the per-file list of ref-objects.
+ *
+ * @kref: Ref count.
+ *
+ * @obj: Base object this ref object is referencing.
+ *
+ * @ref_type: Type of ref object.
+ *
+ * This is similar to an idr object, but it also has a hash table entry
+ * that allows lookup with a pointer to the referenced object as a key. In
+ * that way, one can easily detect whether a base object is referenced by
+ * a particular ttm_object_file. It also carries a ref count to avoid creating
+ * multiple ref objects if a ttm_object_file references the same base
+ * object more than once.
+ */
+
+struct ttm_ref_object {
+ struct drm_hash_item hash;
+ struct list_head head;
+ u_int kref;
+ enum ttm_ref_type ref_type;
+ struct ttm_base_object *obj;
+ struct ttm_object_file *tfile;
+};
+
+MALLOC_DEFINE(M_TTM_OBJ_FILE, "ttm_obj_file", "TTM File Objects");
+
+static inline struct ttm_object_file *
+ttm_object_file_ref(struct ttm_object_file *tfile)
+{
+ refcount_acquire(&tfile->refcount);
+ return tfile;
+}
+
+static void ttm_object_file_destroy(struct ttm_object_file *tfile)
+{
+
+ free(tfile, M_TTM_OBJ_FILE);
+}
+
+
+static inline void ttm_object_file_unref(struct ttm_object_file **p_tfile)
+{
+ struct ttm_object_file *tfile = *p_tfile;
+
+ *p_tfile = NULL;
+ if (refcount_release(&tfile->refcount))
+ ttm_object_file_destroy(tfile);
+}
+
+
+int ttm_base_object_init(struct ttm_object_file *tfile,
+ struct ttm_base_object *base,
+ bool shareable,
+ enum ttm_object_type object_type,
+ void (*rcount_release) (struct ttm_base_object **),
+ void (*ref_obj_release) (struct ttm_base_object *,
+ enum ttm_ref_type ref_type))
+{
+ struct ttm_object_device *tdev = tfile->tdev;
+ int ret;
+
+ base->shareable = shareable;
+ base->tfile = ttm_object_file_ref(tfile);
+ base->refcount_release = rcount_release;
+ base->ref_obj_release = ref_obj_release;
+ base->object_type = object_type;
+ refcount_init(&base->refcount, 1);
+ rw_init(&tdev->object_lock, "ttmbao");
+ rw_wlock(&tdev->object_lock);
+ ret = drm_ht_just_insert_please(&tdev->object_hash,
+ &base->hash,
+ (unsigned long)base, 31, 0, 0);
+ rw_wunlock(&tdev->object_lock);
+ if (unlikely(ret != 0))
+ goto out_err0;
+
+ ret = ttm_ref_object_add(tfile, base, TTM_REF_USAGE, NULL);
+ if (unlikely(ret != 0))
+ goto out_err1;
+
+ ttm_base_object_unref(&base);
+
+ return 0;
+out_err1:
+ rw_wlock(&tdev->object_lock);
+ (void)drm_ht_remove_item(&tdev->object_hash, &base->hash);
+ rw_wunlock(&tdev->object_lock);
+out_err0:
+ return ret;
+}
+
+static void ttm_release_base(struct ttm_base_object *base)
+{
+ struct ttm_object_device *tdev = base->tfile->tdev;
+
+ (void)drm_ht_remove_item(&tdev->object_hash, &base->hash);
+ rw_wunlock(&tdev->object_lock);
+ /*
+ * Note: We don't use synchronize_rcu() here because it's far
+ * too slow. It's up to the user to free the object using
+ * call_rcu() or ttm_base_object_kfree().
+ */
+
+ if (base->refcount_release) {
+ ttm_object_file_unref(&base->tfile);
+ base->refcount_release(&base);
+ }
+ rw_wlock(&tdev->object_lock);
+}
+
+void ttm_base_object_unref(struct ttm_base_object **p_base)
+{
+ struct ttm_base_object *base = *p_base;
+ struct ttm_object_device *tdev = base->tfile->tdev;
+
+ *p_base = NULL;
+
+ /*
+ * Need to take the lock here to avoid racing with
+ * users trying to look up the object.
+ */
+
+ rw_wlock(&tdev->object_lock);
+ if (refcount_release(&base->refcount))
+ ttm_release_base(base);
+ rw_wunlock(&tdev->object_lock);
+}
+
+struct ttm_base_object *ttm_base_object_lookup(struct ttm_object_file *tfile,
+ uint32_t key)
+{
+ struct ttm_object_device *tdev = tfile->tdev;
+ struct ttm_base_object *base;
+ struct drm_hash_item *hash;
+ int ret;
+
+ rw_rlock(&tdev->object_lock);
+ ret = drm_ht_find_item(&tdev->object_hash, key, &hash);
+
+ if (ret == 0) {
+ base = drm_hash_entry(hash, struct ttm_base_object, hash);
+ refcount_acquire(&base->refcount);
+ }
+ rw_runlock(&tdev->object_lock);
+
+ if (unlikely(ret != 0))
+ return NULL;
+
+ if (tfile != base->tfile && !base->shareable) {
+ printf("[TTM] Attempted access of non-shareable object %p\n",
+ base);
+ ttm_base_object_unref(&base);
+ return NULL;
+ }
+
+ return base;
+}
+
+MALLOC_DEFINE(M_TTM_OBJ_REF, "ttm_obj_ref", "TTM Ref Objects");
+
+int ttm_ref_object_add(struct ttm_object_file *tfile,
+ struct ttm_base_object *base,
+ enum ttm_ref_type ref_type, bool *existed)
+{
+ struct drm_open_hash *ht = &tfile->ref_hash[ref_type];
+ struct ttm_ref_object *ref;
+ struct drm_hash_item *hash;
+ struct ttm_mem_global *mem_glob = tfile->tdev->mem_glob;
+ int ret = -EINVAL;
+
+ if (existed != NULL)
+ *existed = true;
+
+ while (ret == -EINVAL) {
+ rw_rlock(&tfile->lock);
+ ret = drm_ht_find_item(ht, base->hash.key, &hash);
+
+ if (ret == 0) {
+ ref = drm_hash_entry(hash, struct ttm_ref_object, hash);
+ refcount_acquire(&ref->kref);
+ rw_runlock(&tfile->lock);
+ break;
+ }
+
+ rw_runlock(&tfile->lock);
+ ret = ttm_mem_global_alloc(mem_glob, sizeof(*ref),
+ false, false);
+ if (unlikely(ret != 0))
+ return ret;
+ ref = malloc(sizeof(*ref), M_TTM_OBJ_REF, M_WAITOK);
+ if (unlikely(ref == NULL)) {
+ ttm_mem_global_free(mem_glob, sizeof(*ref));
+ return -ENOMEM;
+ }
+
+ ref->hash.key = base->hash.key;
+ ref->obj = base;
+ ref->tfile = tfile;
+ ref->ref_type = ref_type;
+ refcount_init(&ref->kref, 1);
+
+ rw_wlock(&tfile->lock);
+ ret = drm_ht_insert_item(ht, &ref->hash);
+
+ if (ret == 0) {
+ list_add_tail(&ref->head, &tfile->ref_list);
+ refcount_acquire(&base->refcount);
+ rw_wunlock(&tfile->lock);
+ if (existed != NULL)
+ *existed = false;
+ break;
+ }
+
+ rw_wunlock(&tfile->lock);
+ MPASS(ret == -EINVAL);
+
+ ttm_mem_global_free(mem_glob, sizeof(*ref));
+ free(ref, M_TTM_OBJ_REF);
+ }
+
+ return ret;
+}
+
+static void ttm_ref_object_release(struct ttm_ref_object *ref)
+{
+ struct ttm_base_object *base = ref->obj;
+ struct ttm_object_file *tfile = ref->tfile;
+ struct drm_open_hash *ht;
+ struct ttm_mem_global *mem_glob = tfile->tdev->mem_glob;
+
+ ht = &tfile->ref_hash[ref->ref_type];
+ (void)drm_ht_remove_item(ht, &ref->hash);
+ list_del(&ref->head);
+ rw_wunlock(&tfile->lock);
+
+ if (ref->ref_type != TTM_REF_USAGE && base->ref_obj_release)
+ base->ref_obj_release(base, ref->ref_type);
+
+ ttm_base_object_unref(&ref->obj);
+ ttm_mem_global_free(mem_glob, sizeof(*ref));
+ free(ref, M_TTM_OBJ_REF);
+ rw_wlock(&tfile->lock);
+}
+
+int ttm_ref_object_base_unref(struct ttm_object_file *tfile,
+ unsigned long key, enum ttm_ref_type ref_type)
+{
+ struct drm_open_hash *ht = &tfile->ref_hash[ref_type];
+ struct ttm_ref_object *ref;
+ struct drm_hash_item *hash;
+ int ret;
+
+ rw_wlock(&tfile->lock);
+ ret = drm_ht_find_item(ht, key, &hash);
+ if (unlikely(ret != 0)) {
+ rw_wunlock(&tfile->lock);
+ return -EINVAL;
+ }
+ ref = drm_hash_entry(hash, struct ttm_ref_object, hash);
+ if (refcount_release(&ref->kref))
+ ttm_ref_object_release(ref);
+ rw_wunlock(&tfile->lock);
+ return 0;
+}
+
+void ttm_object_file_release(struct ttm_object_file **p_tfile)
+{
+ struct ttm_ref_object *ref;
+ struct list_head *list;
+ unsigned int i;
+ struct ttm_object_file *tfile = *p_tfile;
+
+ *p_tfile = NULL;
+ rw_wlock(&tfile->lock);
+
+ /*
+ * Since we release the lock within the loop, we have to
+ * restart it from the beginning each time.
+ */
+
+ while (!list_empty(&tfile->ref_list)) {
+ list = tfile->ref_list.next;
+ ref = list_entry(list, struct ttm_ref_object, head);
+ ttm_ref_object_release(ref);
+ }
+
+ for (i = 0; i < TTM_REF_NUM; ++i)
+ drm_ht_remove(&tfile->ref_hash[i]);
+
+ rw_wunlock(&tfile->lock);
+ ttm_object_file_unref(&tfile);
+}
+
+struct ttm_object_file *ttm_object_file_init(struct ttm_object_device *tdev,
+ unsigned int hash_order)
+{
+ struct ttm_object_file *tfile;
+ unsigned int i;
+ unsigned int j = 0;
+ int ret;
+
+ tfile = malloc(sizeof(*tfile), M_TTM_OBJ_FILE, M_WAITOK);
+ rw_init(&tfile->lock, "ttmfo");
+ tfile->tdev = tdev;
+ refcount_init(&tfile->refcount, 1);
+ INIT_LIST_HEAD(&tfile->ref_list);
+
+ for (i = 0; i < TTM_REF_NUM; ++i) {
+ ret = drm_ht_create(&tfile->ref_hash[i], hash_order);
+ if (ret) {
+ j = i;
+ goto out_err;
+ }
+ }
+
+ return tfile;
+out_err:
+ for (i = 0; i < j; ++i)
+ drm_ht_remove(&tfile->ref_hash[i]);
+
+ free(tfile, M_TTM_OBJ_FILE);
+
+ return NULL;
+}
+
+MALLOC_DEFINE(M_TTM_OBJ_DEV, "ttm_obj_dev", "TTM Device Objects");
+
+struct ttm_object_device *ttm_object_device_init(struct ttm_mem_global
+ *mem_glob,
+ unsigned int hash_order)
+{
+ struct ttm_object_device *tdev;
+ int ret;
+
+ tdev = malloc(sizeof(*tdev), M_TTM_OBJ_DEV, M_WAITOK);
+ tdev->mem_glob = mem_glob;
+ rw_init(&tdev->object_lock, "ttmdo");
+ atomic_set(&tdev->object_count, 0);
+ ret = drm_ht_create(&tdev->object_hash, hash_order);
+
+ if (ret == 0)
+ return tdev;
+
+ free(tdev, M_TTM_OBJ_DEV);
+ return NULL;
+}
+
+void ttm_object_device_release(struct ttm_object_device **p_tdev)
+{
+ struct ttm_object_device *tdev = *p_tdev;
+
+ *p_tdev = NULL;
+
+ rw_wlock(&tdev->object_lock);
+ drm_ht_remove(&tdev->object_hash);
+ rw_wunlock(&tdev->object_lock);
+
+ free(tdev, M_TTM_OBJ_DEV);
+}
diff --git a/sys/dev/drm2/ttm/ttm_object.h b/sys/dev/drm2/ttm/ttm_object.h
new file mode 100644
index 0000000..8a286f1
--- /dev/null
+++ b/sys/dev/drm2/ttm/ttm_object.h
@@ -0,0 +1,271 @@
+/**************************************************************************
+ *
+ * Copyright (c) 2006-2009 VMware, Inc., Palo Alto, CA., USA
+ * All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sub license, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the
+ * next paragraph) shall be included in all copies or substantial portions
+ * of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDERS, AUTHORS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM,
+ * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
+ * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
+ * USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ **************************************************************************/
+/*
+ * Authors: Thomas Hellstrom <thellstrom-at-vmware-dot-com>
+ */
+/* $FreeBSD$ */
+/** @file ttm_object.h
+ *
+ * Base- and reference object implementation for the various
+ * ttm objects. Implements reference counting, minimal security checks
+ * and release on file close.
+ */
+
+#ifndef _TTM_OBJECT_H_
+#define _TTM_OBJECT_H_
+
+#include <dev/drm2/drm_hashtab.h>
+#include <dev/drm2/ttm/ttm_memory.h>
+
+/**
+ * enum ttm_ref_type
+ *
+ * Describes what type of reference a ref object holds.
+ *
+ * TTM_REF_USAGE is a simple refcount on a base object.
+ *
+ * TTM_REF_SYNCCPU_READ is a SYNCCPU_READ reference on a
+ * buffer object.
+ *
+ * TTM_REF_SYNCCPU_WRITE is a SYNCCPU_WRITE reference on a
+ * buffer object.
+ *
+ */
+
+enum ttm_ref_type {
+ TTM_REF_USAGE,
+ TTM_REF_SYNCCPU_READ,
+ TTM_REF_SYNCCPU_WRITE,
+ TTM_REF_NUM
+};
+
+/**
+ * enum ttm_object_type
+ *
+ * One entry per ttm object type.
+ * Device-specific types should use the
+ * ttm_driver_typex types.
+ */
+
+enum ttm_object_type {
+ ttm_fence_type,
+ ttm_buffer_type,
+ ttm_lock_type,
+ ttm_driver_type0 = 256,
+ ttm_driver_type1,
+ ttm_driver_type2,
+ ttm_driver_type3,
+ ttm_driver_type4,
+ ttm_driver_type5
+};
+
+struct ttm_object_file;
+struct ttm_object_device;
+
+/**
+ * struct ttm_base_object
+ *
+ * @hash: hash entry for the per-device object hash.
+ * @type: derived type this object is base class for.
+ * @shareable: Other ttm_object_files can access this object.
+ *
+ * @tfile: Pointer to ttm_object_file of the creator.
+ * NULL if the object was not created by a user request.
+ * (kernel object).
+ *
+ * @refcount: Number of references to this object, not
+ * including the hash entry. A reference to a base object can
+ * only be held by a ref object.
+ *
+ * @refcount_release: A function to be called when there are
+ * no more references to this object. This function should
+ * destroy the object (or make sure destruction eventually happens),
+ * and when it is called, the object has
+ * already been taken out of the per-device hash. The parameter
+ * "base" should be set to NULL by the function.
+ *
+ * @ref_obj_release: A function to be called when a reference object
+ * with another ttm_ref_type than TTM_REF_USAGE is deleted.
+ * This function may, for example, release a lock held by a user-space
+ * process.
+ *
+ * This struct is intended to be used as a base struct for objects that
+ * are visible to user-space. It provides a global name, race-safe
+ * access and refcounting, minimal access contol and hooks for unref actions.
+ */
+
+struct ttm_base_object {
+ /* struct rcu_head rhead;XXXKIB */
+ struct drm_hash_item hash;
+ enum ttm_object_type object_type;
+ bool shareable;
+ struct ttm_object_file *tfile;
+ u_int refcount;
+ void (*refcount_release) (struct ttm_base_object **base);
+ void (*ref_obj_release) (struct ttm_base_object *base,
+ enum ttm_ref_type ref_type);
+};
+
+/**
+ * ttm_base_object_init
+ *
+ * @tfile: Pointer to a struct ttm_object_file.
+ * @base: The struct ttm_base_object to initialize.
+ * @shareable: This object is shareable with other applcations.
+ * (different @tfile pointers.)
+ * @type: The object type.
+ * @refcount_release: See the struct ttm_base_object description.
+ * @ref_obj_release: See the struct ttm_base_object description.
+ *
+ * Initializes a struct ttm_base_object.
+ */
+
+extern int ttm_base_object_init(struct ttm_object_file *tfile,
+ struct ttm_base_object *base,
+ bool shareable,
+ enum ttm_object_type type,
+ void (*refcount_release) (struct ttm_base_object
+ **),
+ void (*ref_obj_release) (struct ttm_base_object
+ *,
+ enum ttm_ref_type
+ ref_type));
+
+/**
+ * ttm_base_object_lookup
+ *
+ * @tfile: Pointer to a struct ttm_object_file.
+ * @key: Hash key
+ *
+ * Looks up a struct ttm_base_object with the key @key.
+ * Also verifies that the object is visible to the application, by
+ * comparing the @tfile argument and checking the object shareable flag.
+ */
+
+extern struct ttm_base_object *ttm_base_object_lookup(struct ttm_object_file
+ *tfile, uint32_t key);
+
+/**
+ * ttm_base_object_unref
+ *
+ * @p_base: Pointer to a pointer referencing a struct ttm_base_object.
+ *
+ * Decrements the base object refcount and clears the pointer pointed to by
+ * p_base.
+ */
+
+extern void ttm_base_object_unref(struct ttm_base_object **p_base);
+
+/**
+ * ttm_ref_object_add.
+ *
+ * @tfile: A struct ttm_object_file representing the application owning the
+ * ref_object.
+ * @base: The base object to reference.
+ * @ref_type: The type of reference.
+ * @existed: Upon completion, indicates that an identical reference object
+ * already existed, and the refcount was upped on that object instead.
+ *
+ * Adding a ref object to a base object is basically like referencing the
+ * base object, but a user-space application holds the reference. When the
+ * file corresponding to @tfile is closed, all its reference objects are
+ * deleted. A reference object can have different types depending on what
+ * it's intended for. It can be refcounting to prevent object destruction,
+ * When user-space takes a lock, it can add a ref object to that lock to
+ * make sure the lock is released if the application dies. A ref object
+ * will hold a single reference on a base object.
+ */
+extern int ttm_ref_object_add(struct ttm_object_file *tfile,
+ struct ttm_base_object *base,
+ enum ttm_ref_type ref_type, bool *existed);
+/**
+ * ttm_ref_object_base_unref
+ *
+ * @key: Key representing the base object.
+ * @ref_type: Ref type of the ref object to be dereferenced.
+ *
+ * Unreference a ref object with type @ref_type
+ * on the base object identified by @key. If there are no duplicate
+ * references, the ref object will be destroyed and the base object
+ * will be unreferenced.
+ */
+extern int ttm_ref_object_base_unref(struct ttm_object_file *tfile,
+ unsigned long key,
+ enum ttm_ref_type ref_type);
+
+/**
+ * ttm_object_file_init - initialize a struct ttm_object file
+ *
+ * @tdev: A struct ttm_object device this file is initialized on.
+ * @hash_order: Order of the hash table used to hold the reference objects.
+ *
+ * This is typically called by the file_ops::open function.
+ */
+
+extern struct ttm_object_file *ttm_object_file_init(struct ttm_object_device
+ *tdev,
+ unsigned int hash_order);
+
+/**
+ * ttm_object_file_release - release data held by a ttm_object_file
+ *
+ * @p_tfile: Pointer to pointer to the ttm_object_file object to release.
+ * *p_tfile will be set to NULL by this function.
+ *
+ * Releases all data associated by a ttm_object_file.
+ * Typically called from file_ops::release. The caller must
+ * ensure that there are no concurrent users of tfile.
+ */
+
+extern void ttm_object_file_release(struct ttm_object_file **p_tfile);
+
+/**
+ * ttm_object device init - initialize a struct ttm_object_device
+ *
+ * @hash_order: Order of hash table used to hash the base objects.
+ *
+ * This function is typically called on device initialization to prepare
+ * data structures needed for ttm base and ref objects.
+ */
+
+extern struct ttm_object_device *ttm_object_device_init
+ (struct ttm_mem_global *mem_glob, unsigned int hash_order);
+
+/**
+ * ttm_object_device_release - release data held by a ttm_object_device
+ *
+ * @p_tdev: Pointer to pointer to the ttm_object_device object to release.
+ * *p_tdev will be set to NULL by this function.
+ *
+ * Releases all data associated by a ttm_object_device.
+ * Typically called from driver::unload before the destruction of the
+ * device private data structure.
+ */
+
+extern void ttm_object_device_release(struct ttm_object_device **p_tdev);
+
+#endif
diff --git a/sys/dev/drm2/ttm/ttm_page_alloc.c b/sys/dev/drm2/ttm/ttm_page_alloc.c
new file mode 100644
index 0000000..9a30a46
--- /dev/null
+++ b/sys/dev/drm2/ttm/ttm_page_alloc.c
@@ -0,0 +1,900 @@
+/*
+ * Copyright (c) Red Hat Inc.
+
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sub license,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the
+ * next paragraph) shall be included in all copies or substantial portions
+ * of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ *
+ * Authors: Dave Airlie <airlied@redhat.com>
+ * Jerome Glisse <jglisse@redhat.com>
+ * Pauli Nieminen <suokkos@gmail.com>
+ */
+/*
+ * Copyright (c) 2013 The FreeBSD Foundation
+ * All rights reserved.
+ *
+ * Portions of this software were developed by Konstantin Belousov
+ * <kib@FreeBSD.org> under sponsorship from the FreeBSD Foundation.
+ */
+
+/* simple list based uncached page pool
+ * - Pool collects resently freed pages for reuse
+ * - Use page->lru to keep a free list
+ * - doesn't track currently in use pages
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include <dev/drm2/drmP.h>
+#include <dev/drm2/ttm/ttm_bo_driver.h>
+#include <dev/drm2/ttm/ttm_page_alloc.h>
+
+#ifdef TTM_HAS_AGP
+#include <asm/agp.h>
+#endif
+
+#define VM_ALLOC_DMA32 VM_ALLOC_RESERVED1
+
+#define NUM_PAGES_TO_ALLOC (PAGE_SIZE/sizeof(vm_page_t))
+#define SMALL_ALLOCATION 16
+#define FREE_ALL_PAGES (~0U)
+/* times are in msecs */
+#define PAGE_FREE_INTERVAL 1000
+
+/**
+ * struct ttm_page_pool - Pool to reuse recently allocated uc/wc pages.
+ *
+ * @lock: Protects the shared pool from concurrnet access. Must be used with
+ * irqsave/irqrestore variants because pool allocator maybe called from
+ * delayed work.
+ * @fill_lock: Prevent concurrent calls to fill.
+ * @list: Pool of free uc/wc pages for fast reuse.
+ * @gfp_flags: Flags to pass for alloc_page.
+ * @npages: Number of pages in pool.
+ */
+struct ttm_page_pool {
+ struct mtx lock;
+ bool fill_lock;
+ bool dma32;
+ struct pglist list;
+ int ttm_page_alloc_flags;
+ unsigned npages;
+ char *name;
+ unsigned long nfrees;
+ unsigned long nrefills;
+};
+
+/**
+ * Limits for the pool. They are handled without locks because only place where
+ * they may change is in sysfs store. They won't have immediate effect anyway
+ * so forcing serialization to access them is pointless.
+ */
+
+struct ttm_pool_opts {
+ unsigned alloc_size;
+ unsigned max_size;
+ unsigned small;
+};
+
+#define NUM_POOLS 4
+
+/**
+ * struct ttm_pool_manager - Holds memory pools for fst allocation
+ *
+ * Manager is read only object for pool code so it doesn't need locking.
+ *
+ * @free_interval: minimum number of jiffies between freeing pages from pool.
+ * @page_alloc_inited: reference counting for pool allocation.
+ * @work: Work that is used to shrink the pool. Work is only run when there is
+ * some pages to free.
+ * @small_allocation: Limit in number of pages what is small allocation.
+ *
+ * @pools: All pool objects in use.
+ **/
+struct ttm_pool_manager {
+ unsigned int kobj_ref;
+ eventhandler_tag lowmem_handler;
+ struct ttm_pool_opts options;
+
+ union {
+ struct ttm_page_pool u_pools[NUM_POOLS];
+ struct _utag {
+ struct ttm_page_pool u_wc_pool;
+ struct ttm_page_pool u_uc_pool;
+ struct ttm_page_pool u_wc_pool_dma32;
+ struct ttm_page_pool u_uc_pool_dma32;
+ } _ut;
+ } _u;
+};
+
+#define pools _u.u_pools
+#define wc_pool _u._ut.u_wc_pool
+#define uc_pool _u._ut.u_uc_pool
+#define wc_pool_dma32 _u._ut.u_wc_pool_dma32
+#define uc_pool_dma32 _u._ut.u_uc_pool_dma32
+
+MALLOC_DEFINE(M_TTM_POOLMGR, "ttm_poolmgr", "TTM Pool Manager");
+
+static void
+ttm_vm_page_free(vm_page_t m)
+{
+
+ KASSERT(m->object == NULL, ("ttm page %p is owned", m));
+ KASSERT(m->wire_count == 1, ("ttm lost wire %p", m));
+ KASSERT((m->flags & PG_FICTITIOUS) != 0, ("ttm lost fictitious %p", m));
+ KASSERT((m->oflags & VPO_UNMANAGED) == 0, ("ttm got unmanaged %p", m));
+ m->flags &= ~PG_FICTITIOUS;
+ m->oflags |= VPO_UNMANAGED;
+ vm_page_unwire(m, 0);
+ vm_page_free(m);
+}
+
+static vm_memattr_t
+ttm_caching_state_to_vm(enum ttm_caching_state cstate)
+{
+
+ switch (cstate) {
+ case tt_uncached:
+ return (VM_MEMATTR_UNCACHEABLE);
+ case tt_wc:
+ return (VM_MEMATTR_WRITE_COMBINING);
+ case tt_cached:
+ return (VM_MEMATTR_WRITE_BACK);
+ }
+ panic("caching state %d\n", cstate);
+}
+
+static void ttm_pool_kobj_release(struct ttm_pool_manager *m)
+{
+
+ free(m, M_TTM_POOLMGR);
+}
+
+#if 0
+/* XXXKIB sysctl */
+static ssize_t ttm_pool_store(struct ttm_pool_manager *m,
+ struct attribute *attr, const char *buffer, size_t size)
+{
+ int chars;
+ unsigned val;
+ chars = sscanf(buffer, "%u", &val);
+ if (chars == 0)
+ return size;
+
+ /* Convert kb to number of pages */
+ val = val / (PAGE_SIZE >> 10);
+
+ if (attr == &ttm_page_pool_max)
+ m->options.max_size = val;
+ else if (attr == &ttm_page_pool_small)
+ m->options.small = val;
+ else if (attr == &ttm_page_pool_alloc_size) {
+ if (val > NUM_PAGES_TO_ALLOC*8) {
+ pr_err("Setting allocation size to %lu is not allowed. Recommended size is %lu\n",
+ NUM_PAGES_TO_ALLOC*(PAGE_SIZE >> 7),
+ NUM_PAGES_TO_ALLOC*(PAGE_SIZE >> 10));
+ return size;
+ } else if (val > NUM_PAGES_TO_ALLOC) {
+ pr_warn("Setting allocation size to larger than %lu is not recommended\n",
+ NUM_PAGES_TO_ALLOC*(PAGE_SIZE >> 10));
+ }
+ m->options.alloc_size = val;
+ }
+
+ return size;
+}
+
+static ssize_t ttm_pool_show(struct ttm_pool_manager *m,
+ struct attribute *attr, char *buffer)
+{
+ unsigned val = 0;
+
+ if (attr == &ttm_page_pool_max)
+ val = m->options.max_size;
+ else if (attr == &ttm_page_pool_small)
+ val = m->options.small;
+ else if (attr == &ttm_page_pool_alloc_size)
+ val = m->options.alloc_size;
+
+ val = val * (PAGE_SIZE >> 10);
+
+ return snprintf(buffer, PAGE_SIZE, "%u\n", val);
+}
+#endif
+
+static struct ttm_pool_manager *_manager;
+
+static int set_pages_array_wb(vm_page_t *pages, int addrinarray)
+{
+ vm_page_t m;
+ int i;
+
+ for (i = 0; i < addrinarray; i++) {
+ m = pages[i];
+#ifdef TTM_HAS_AGP
+ unmap_page_from_agp(m);
+#endif
+ pmap_page_set_memattr(m, VM_MEMATTR_WRITE_BACK);
+ }
+ return 0;
+}
+
+static int set_pages_array_wc(vm_page_t *pages, int addrinarray)
+{
+ vm_page_t m;
+ int i;
+
+ for (i = 0; i < addrinarray; i++) {
+ m = pages[i];
+#ifdef TTM_HAS_AGP
+ map_page_into_agp(pages[i]);
+#endif
+ pmap_page_set_memattr(m, VM_MEMATTR_WRITE_COMBINING);
+ }
+ return 0;
+}
+
+static int set_pages_array_uc(vm_page_t *pages, int addrinarray)
+{
+ vm_page_t m;
+ int i;
+
+ for (i = 0; i < addrinarray; i++) {
+ m = pages[i];
+#ifdef TTM_HAS_AGP
+ map_page_into_agp(pages[i]);
+#endif
+ pmap_page_set_memattr(m, VM_MEMATTR_UNCACHEABLE);
+ }
+ return 0;
+}
+
+/**
+ * Select the right pool or requested caching state and ttm flags. */
+static struct ttm_page_pool *ttm_get_pool(int flags,
+ enum ttm_caching_state cstate)
+{
+ int pool_index;
+
+ if (cstate == tt_cached)
+ return NULL;
+
+ if (cstate == tt_wc)
+ pool_index = 0x0;
+ else
+ pool_index = 0x1;
+
+ if (flags & TTM_PAGE_FLAG_DMA32)
+ pool_index |= 0x2;
+
+ return &_manager->pools[pool_index];
+}
+
+/* set memory back to wb and free the pages. */
+static void ttm_pages_put(vm_page_t *pages, unsigned npages)
+{
+ unsigned i;
+
+ /* Our VM handles vm memattr automatically on the page free. */
+ if (set_pages_array_wb(pages, npages))
+ printf("[TTM] Failed to set %d pages to wb!\n", npages);
+ for (i = 0; i < npages; ++i)
+ ttm_vm_page_free(pages[i]);
+}
+
+static void ttm_pool_update_free_locked(struct ttm_page_pool *pool,
+ unsigned freed_pages)
+{
+ pool->npages -= freed_pages;
+ pool->nfrees += freed_pages;
+}
+
+/**
+ * Free pages from pool.
+ *
+ * To prevent hogging the ttm_swap process we only free NUM_PAGES_TO_ALLOC
+ * number of pages in one go.
+ *
+ * @pool: to free the pages from
+ * @free_all: If set to true will free all pages in pool
+ **/
+static int ttm_page_pool_free(struct ttm_page_pool *pool, unsigned nr_free)
+{
+ vm_page_t p, p1;
+ vm_page_t *pages_to_free;
+ unsigned freed_pages = 0,
+ npages_to_free = nr_free;
+
+ if (NUM_PAGES_TO_ALLOC < nr_free)
+ npages_to_free = NUM_PAGES_TO_ALLOC;
+
+ pages_to_free = malloc(npages_to_free * sizeof(vm_page_t),
+ M_TEMP, M_WAITOK | M_ZERO);
+
+restart:
+ mtx_lock(&pool->lock);
+
+ TAILQ_FOREACH_REVERSE_SAFE(p, &pool->list, pglist, pageq, p1) {
+ if (freed_pages >= npages_to_free)
+ break;
+
+ pages_to_free[freed_pages++] = p;
+ /* We can only remove NUM_PAGES_TO_ALLOC at a time. */
+ if (freed_pages >= NUM_PAGES_TO_ALLOC) {
+ /* remove range of pages from the pool */
+ TAILQ_REMOVE(&pool->list, p, pageq);
+
+ ttm_pool_update_free_locked(pool, freed_pages);
+ /**
+ * Because changing page caching is costly
+ * we unlock the pool to prevent stalling.
+ */
+ mtx_unlock(&pool->lock);
+
+ ttm_pages_put(pages_to_free, freed_pages);
+ if (likely(nr_free != FREE_ALL_PAGES))
+ nr_free -= freed_pages;
+
+ if (NUM_PAGES_TO_ALLOC >= nr_free)
+ npages_to_free = nr_free;
+ else
+ npages_to_free = NUM_PAGES_TO_ALLOC;
+
+ freed_pages = 0;
+
+ /* free all so restart the processing */
+ if (nr_free)
+ goto restart;
+
+ /* Not allowed to fall through or break because
+ * following context is inside spinlock while we are
+ * outside here.
+ */
+ goto out;
+
+ }
+ }
+
+ /* remove range of pages from the pool */
+ if (freed_pages) {
+ TAILQ_REMOVE(&pool->list, p, pageq);
+
+ ttm_pool_update_free_locked(pool, freed_pages);
+ nr_free -= freed_pages;
+ }
+
+ mtx_unlock(&pool->lock);
+
+ if (freed_pages)
+ ttm_pages_put(pages_to_free, freed_pages);
+out:
+ free(pages_to_free, M_TEMP);
+ return nr_free;
+}
+
+/* Get good estimation how many pages are free in pools */
+static int ttm_pool_get_num_unused_pages(void)
+{
+ unsigned i;
+ int total = 0;
+ for (i = 0; i < NUM_POOLS; ++i)
+ total += _manager->pools[i].npages;
+
+ return total;
+}
+
+/**
+ * Callback for mm to request pool to reduce number of page held.
+ */
+static int ttm_pool_mm_shrink(void *arg)
+{
+ static unsigned int start_pool = 0;
+ unsigned i;
+ unsigned pool_offset = atomic_fetchadd_int(&start_pool, 1);
+ struct ttm_page_pool *pool;
+ int shrink_pages = 100; /* XXXKIB */
+
+ pool_offset = pool_offset % NUM_POOLS;
+ /* select start pool in round robin fashion */
+ for (i = 0; i < NUM_POOLS; ++i) {
+ unsigned nr_free = shrink_pages;
+ if (shrink_pages == 0)
+ break;
+ pool = &_manager->pools[(i + pool_offset)%NUM_POOLS];
+ shrink_pages = ttm_page_pool_free(pool, nr_free);
+ }
+ /* return estimated number of unused pages in pool */
+ return ttm_pool_get_num_unused_pages();
+}
+
+static void ttm_pool_mm_shrink_init(struct ttm_pool_manager *manager)
+{
+
+ manager->lowmem_handler = EVENTHANDLER_REGISTER(vm_lowmem,
+ ttm_pool_mm_shrink, manager, EVENTHANDLER_PRI_ANY);
+}
+
+static void ttm_pool_mm_shrink_fini(struct ttm_pool_manager *manager)
+{
+
+ EVENTHANDLER_DEREGISTER(vm_lowmem, manager->lowmem_handler);
+}
+
+static int ttm_set_pages_caching(vm_page_t *pages,
+ enum ttm_caching_state cstate, unsigned cpages)
+{
+ int r = 0;
+ /* Set page caching */
+ switch (cstate) {
+ case tt_uncached:
+ r = set_pages_array_uc(pages, cpages);
+ if (r)
+ printf("[TTM] Failed to set %d pages to uc!\n", cpages);
+ break;
+ case tt_wc:
+ r = set_pages_array_wc(pages, cpages);
+ if (r)
+ printf("[TTM] Failed to set %d pages to wc!\n", cpages);
+ break;
+ default:
+ break;
+ }
+ return r;
+}
+
+/**
+ * Free pages the pages that failed to change the caching state. If there is
+ * any pages that have changed their caching state already put them to the
+ * pool.
+ */
+static void ttm_handle_caching_state_failure(struct pglist *pages,
+ int ttm_flags, enum ttm_caching_state cstate,
+ vm_page_t *failed_pages, unsigned cpages)
+{
+ unsigned i;
+ /* Failed pages have to be freed */
+ for (i = 0; i < cpages; ++i) {
+ TAILQ_REMOVE(pages, failed_pages[i], pageq);
+ ttm_vm_page_free(failed_pages[i]);
+ }
+}
+
+/**
+ * Allocate new pages with correct caching.
+ *
+ * This function is reentrant if caller updates count depending on number of
+ * pages returned in pages array.
+ */
+static int ttm_alloc_new_pages(struct pglist *pages, int ttm_alloc_flags,
+ int ttm_flags, enum ttm_caching_state cstate, unsigned count)
+{
+ vm_page_t *caching_array;
+ vm_page_t p;
+ int r = 0;
+ unsigned i, cpages, aflags;
+ unsigned max_cpages = min(count,
+ (unsigned)(PAGE_SIZE/sizeof(vm_page_t)));
+
+ aflags = VM_ALLOC_NORMAL | VM_ALLOC_WIRED | VM_ALLOC_NOOBJ |
+ ((ttm_alloc_flags & TTM_PAGE_FLAG_ZERO_ALLOC) != 0 ?
+ VM_ALLOC_ZERO : 0);
+
+ /* allocate array for page caching change */
+ caching_array = malloc(max_cpages * sizeof(vm_page_t), M_TEMP,
+ M_WAITOK | M_ZERO);
+
+ for (i = 0, cpages = 0; i < count; ++i) {
+ p = vm_page_alloc_contig(NULL, 0, aflags, 1, 0,
+ (ttm_alloc_flags & TTM_PAGE_FLAG_DMA32) ? 0xffffffff :
+ VM_MAX_ADDRESS, PAGE_SIZE, 0,
+ ttm_caching_state_to_vm(cstate));
+ if (!p) {
+ printf("[TTM] Unable to get page %u\n", i);
+
+ /* store already allocated pages in the pool after
+ * setting the caching state */
+ if (cpages) {
+ r = ttm_set_pages_caching(caching_array,
+ cstate, cpages);
+ if (r)
+ ttm_handle_caching_state_failure(pages,
+ ttm_flags, cstate,
+ caching_array, cpages);
+ }
+ r = -ENOMEM;
+ goto out;
+ }
+ p->oflags &= ~VPO_UNMANAGED;
+ p->flags |= PG_FICTITIOUS;
+
+#ifdef CONFIG_HIGHMEM /* KIB: nop */
+ /* gfp flags of highmem page should never be dma32 so we
+ * we should be fine in such case
+ */
+ if (!PageHighMem(p))
+#endif
+ {
+ caching_array[cpages++] = p;
+ if (cpages == max_cpages) {
+
+ r = ttm_set_pages_caching(caching_array,
+ cstate, cpages);
+ if (r) {
+ ttm_handle_caching_state_failure(pages,
+ ttm_flags, cstate,
+ caching_array, cpages);
+ goto out;
+ }
+ cpages = 0;
+ }
+ }
+
+ TAILQ_INSERT_HEAD(pages, p, pageq);
+ }
+
+ if (cpages) {
+ r = ttm_set_pages_caching(caching_array, cstate, cpages);
+ if (r)
+ ttm_handle_caching_state_failure(pages,
+ ttm_flags, cstate,
+ caching_array, cpages);
+ }
+out:
+ free(caching_array, M_TEMP);
+
+ return r;
+}
+
+/**
+ * Fill the given pool if there aren't enough pages and the requested number of
+ * pages is small.
+ */
+static void ttm_page_pool_fill_locked(struct ttm_page_pool *pool,
+ int ttm_flags, enum ttm_caching_state cstate, unsigned count)
+{
+ vm_page_t p;
+ int r;
+ unsigned cpages = 0;
+ /**
+ * Only allow one pool fill operation at a time.
+ * If pool doesn't have enough pages for the allocation new pages are
+ * allocated from outside of pool.
+ */
+ if (pool->fill_lock)
+ return;
+
+ pool->fill_lock = true;
+
+ /* If allocation request is small and there are not enough
+ * pages in a pool we fill the pool up first. */
+ if (count < _manager->options.small
+ && count > pool->npages) {
+ struct pglist new_pages;
+ unsigned alloc_size = _manager->options.alloc_size;
+
+ /**
+ * Can't change page caching if in irqsave context. We have to
+ * drop the pool->lock.
+ */
+ mtx_unlock(&pool->lock);
+
+ TAILQ_INIT(&new_pages);
+ r = ttm_alloc_new_pages(&new_pages, pool->ttm_page_alloc_flags,
+ ttm_flags, cstate, alloc_size);
+ mtx_lock(&pool->lock);
+
+ if (!r) {
+ TAILQ_CONCAT(&pool->list, &new_pages, pageq);
+ ++pool->nrefills;
+ pool->npages += alloc_size;
+ } else {
+ printf("[TTM] Failed to fill pool (%p)\n", pool);
+ /* If we have any pages left put them to the pool. */
+ TAILQ_FOREACH(p, &pool->list, pageq) {
+ ++cpages;
+ }
+ TAILQ_CONCAT(&pool->list, &new_pages, pageq);
+ pool->npages += cpages;
+ }
+
+ }
+ pool->fill_lock = false;
+}
+
+/**
+ * Cut 'count' number of pages from the pool and put them on the return list.
+ *
+ * @return count of pages still required to fulfill the request.
+ */
+static unsigned ttm_page_pool_get_pages(struct ttm_page_pool *pool,
+ struct pglist *pages,
+ int ttm_flags,
+ enum ttm_caching_state cstate,
+ unsigned count)
+{
+ vm_page_t p;
+ unsigned i;
+
+ mtx_lock(&pool->lock);
+ ttm_page_pool_fill_locked(pool, ttm_flags, cstate, count);
+
+ if (count >= pool->npages) {
+ /* take all pages from the pool */
+ TAILQ_CONCAT(pages, &pool->list, pageq);
+ count -= pool->npages;
+ pool->npages = 0;
+ goto out;
+ }
+ for (i = 0; i < count; i++) {
+ p = TAILQ_FIRST(&pool->list);
+ TAILQ_REMOVE(&pool->list, p, pageq);
+ TAILQ_INSERT_TAIL(pages, p, pageq);
+ }
+ pool->npages -= count;
+ count = 0;
+out:
+ mtx_unlock(&pool->lock);
+ return count;
+}
+
+/* Put all pages in pages list to correct pool to wait for reuse */
+static void ttm_put_pages(vm_page_t *pages, unsigned npages, int flags,
+ enum ttm_caching_state cstate)
+{
+ struct ttm_page_pool *pool = ttm_get_pool(flags, cstate);
+ unsigned i;
+
+ if (pool == NULL) {
+ /* No pool for this memory type so free the pages */
+ for (i = 0; i < npages; i++) {
+ if (pages[i]) {
+ ttm_vm_page_free(pages[i]);
+ pages[i] = NULL;
+ }
+ }
+ return;
+ }
+
+ mtx_lock(&pool->lock);
+ for (i = 0; i < npages; i++) {
+ if (pages[i]) {
+ TAILQ_INSERT_TAIL(&pool->list, pages[i], pageq);
+ pages[i] = NULL;
+ pool->npages++;
+ }
+ }
+ /* Check that we don't go over the pool limit */
+ npages = 0;
+ if (pool->npages > _manager->options.max_size) {
+ npages = pool->npages - _manager->options.max_size;
+ /* free at least NUM_PAGES_TO_ALLOC number of pages
+ * to reduce calls to set_memory_wb */
+ if (npages < NUM_PAGES_TO_ALLOC)
+ npages = NUM_PAGES_TO_ALLOC;
+ }
+ mtx_unlock(&pool->lock);
+ if (npages)
+ ttm_page_pool_free(pool, npages);
+}
+
+/*
+ * On success pages list will hold count number of correctly
+ * cached pages.
+ */
+static int ttm_get_pages(vm_page_t *pages, unsigned npages, int flags,
+ enum ttm_caching_state cstate)
+{
+ struct ttm_page_pool *pool = ttm_get_pool(flags, cstate);
+ struct pglist plist;
+ vm_page_t p = NULL;
+ int gfp_flags, aflags;
+ unsigned count;
+ int r;
+
+ aflags = VM_ALLOC_NORMAL | VM_ALLOC_NOOBJ | VM_ALLOC_WIRED |
+ ((flags & TTM_PAGE_FLAG_ZERO_ALLOC) != 0 ? VM_ALLOC_ZERO : 0);
+
+ /* No pool for cached pages */
+ if (pool == NULL) {
+ for (r = 0; r < npages; ++r) {
+ p = vm_page_alloc_contig(NULL, 0, aflags, 1, 0,
+ (flags & TTM_PAGE_FLAG_DMA32) ? 0xffffffff :
+ VM_MAX_ADDRESS, PAGE_SIZE,
+ 0, ttm_caching_state_to_vm(cstate));
+ if (!p) {
+ printf("[TTM] Unable to allocate page\n");
+ return -ENOMEM;
+ }
+ p->oflags &= ~VPO_UNMANAGED;
+ p->flags |= PG_FICTITIOUS;
+ pages[r] = p;
+ }
+ return 0;
+ }
+
+ /* combine zero flag to pool flags */
+ gfp_flags = flags | pool->ttm_page_alloc_flags;
+
+ /* First we take pages from the pool */
+ TAILQ_INIT(&plist);
+ npages = ttm_page_pool_get_pages(pool, &plist, flags, cstate, npages);
+ count = 0;
+ TAILQ_FOREACH(p, &plist, pageq) {
+ pages[count++] = p;
+ }
+
+ /* clear the pages coming from the pool if requested */
+ if (flags & TTM_PAGE_FLAG_ZERO_ALLOC) {
+ TAILQ_FOREACH(p, &plist, pageq) {
+ pmap_zero_page(p);
+ }
+ }
+
+ /* If pool didn't have enough pages allocate new one. */
+ if (npages > 0) {
+ /* ttm_alloc_new_pages doesn't reference pool so we can run
+ * multiple requests in parallel.
+ **/
+ TAILQ_INIT(&plist);
+ r = ttm_alloc_new_pages(&plist, gfp_flags, flags, cstate,
+ npages);
+ TAILQ_FOREACH(p, &plist, pageq) {
+ pages[count++] = p;
+ }
+ if (r) {
+ /* If there is any pages in the list put them back to
+ * the pool. */
+ printf("[TTM] Failed to allocate extra pages for large request\n");
+ ttm_put_pages(pages, count, flags, cstate);
+ return r;
+ }
+ }
+
+ return 0;
+}
+
+static void ttm_page_pool_init_locked(struct ttm_page_pool *pool, int flags,
+ char *name)
+{
+ mtx_init(&pool->lock, "ttmpool", NULL, MTX_DEF);
+ pool->fill_lock = false;
+ TAILQ_INIT(&pool->list);
+ pool->npages = pool->nfrees = 0;
+ pool->ttm_page_alloc_flags = flags;
+ pool->name = name;
+}
+
+int ttm_page_alloc_init(struct ttm_mem_global *glob, unsigned max_pages)
+{
+
+ if (_manager != NULL)
+ printf("[TTM] manager != NULL\n");
+ printf("[TTM] Initializing pool allocator\n");
+
+ _manager = malloc(sizeof(*_manager), M_TTM_POOLMGR, M_WAITOK | M_ZERO);
+
+ ttm_page_pool_init_locked(&_manager->wc_pool, 0, "wc");
+ ttm_page_pool_init_locked(&_manager->uc_pool, 0, "uc");
+ ttm_page_pool_init_locked(&_manager->wc_pool_dma32,
+ TTM_PAGE_FLAG_DMA32, "wc dma");
+ ttm_page_pool_init_locked(&_manager->uc_pool_dma32,
+ TTM_PAGE_FLAG_DMA32, "uc dma");
+
+ _manager->options.max_size = max_pages;
+ _manager->options.small = SMALL_ALLOCATION;
+ _manager->options.alloc_size = NUM_PAGES_TO_ALLOC;
+
+ refcount_init(&_manager->kobj_ref, 1);
+ ttm_pool_mm_shrink_init(_manager);
+
+ return 0;
+}
+
+void ttm_page_alloc_fini(void)
+{
+ int i;
+
+ printf("[TTM] Finalizing pool allocator\n");
+ ttm_pool_mm_shrink_fini(_manager);
+
+ for (i = 0; i < NUM_POOLS; ++i)
+ ttm_page_pool_free(&_manager->pools[i], FREE_ALL_PAGES);
+
+ if (refcount_release(&_manager->kobj_ref))
+ ttm_pool_kobj_release(_manager);
+ _manager = NULL;
+}
+
+int ttm_pool_populate(struct ttm_tt *ttm)
+{
+ struct ttm_mem_global *mem_glob = ttm->glob->mem_glob;
+ unsigned i;
+ int ret;
+
+ if (ttm->state != tt_unpopulated)
+ return 0;
+
+ for (i = 0; i < ttm->num_pages; ++i) {
+ ret = ttm_get_pages(&ttm->pages[i], 1,
+ ttm->page_flags,
+ ttm->caching_state);
+ if (ret != 0) {
+ ttm_pool_unpopulate(ttm);
+ return -ENOMEM;
+ }
+
+ ret = ttm_mem_global_alloc_page(mem_glob, ttm->pages[i],
+ false, false);
+ if (unlikely(ret != 0)) {
+ ttm_pool_unpopulate(ttm);
+ return -ENOMEM;
+ }
+ }
+
+ if (unlikely(ttm->page_flags & TTM_PAGE_FLAG_SWAPPED)) {
+ ret = ttm_tt_swapin(ttm);
+ if (unlikely(ret != 0)) {
+ ttm_pool_unpopulate(ttm);
+ return ret;
+ }
+ }
+
+ ttm->state = tt_unbound;
+ return 0;
+}
+
+void ttm_pool_unpopulate(struct ttm_tt *ttm)
+{
+ unsigned i;
+
+ for (i = 0; i < ttm->num_pages; ++i) {
+ if (ttm->pages[i]) {
+ ttm_mem_global_free_page(ttm->glob->mem_glob,
+ ttm->pages[i]);
+ ttm_put_pages(&ttm->pages[i], 1,
+ ttm->page_flags,
+ ttm->caching_state);
+ }
+ }
+ ttm->state = tt_unpopulated;
+}
+
+#if 0
+/* XXXKIB sysctl */
+int ttm_page_alloc_debugfs(struct seq_file *m, void *data)
+{
+ struct ttm_page_pool *p;
+ unsigned i;
+ char *h[] = {"pool", "refills", "pages freed", "size"};
+ if (!_manager) {
+ seq_printf(m, "No pool allocator running.\n");
+ return 0;
+ }
+ seq_printf(m, "%6s %12s %13s %8s\n",
+ h[0], h[1], h[2], h[3]);
+ for (i = 0; i < NUM_POOLS; ++i) {
+ p = &_manager->pools[i];
+
+ seq_printf(m, "%6s %12ld %13ld %8d\n",
+ p->name, p->nrefills,
+ p->nfrees, p->npages);
+ }
+ return 0;
+}
+#endif
diff --git a/sys/dev/drm2/ttm/ttm_page_alloc.h b/sys/dev/drm2/ttm/ttm_page_alloc.h
new file mode 100644
index 0000000..0824e2d
--- /dev/null
+++ b/sys/dev/drm2/ttm/ttm_page_alloc.h
@@ -0,0 +1,103 @@
+/*
+ * Copyright (c) Red Hat Inc.
+
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sub license,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the
+ * next paragraph) shall be included in all copies or substantial portions
+ * of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ *
+ * Authors: Dave Airlie <airlied@redhat.com>
+ * Jerome Glisse <jglisse@redhat.com>
+ */
+/* $FreeBSD$ */
+#ifndef TTM_PAGE_ALLOC
+#define TTM_PAGE_ALLOC
+
+#include <dev/drm2/ttm/ttm_bo_driver.h>
+#include <dev/drm2/ttm/ttm_memory.h>
+
+/**
+ * Initialize pool allocator.
+ */
+int ttm_page_alloc_init(struct ttm_mem_global *glob, unsigned max_pages);
+/**
+ * Free pool allocator.
+ */
+void ttm_page_alloc_fini(void);
+
+/**
+ * ttm_pool_populate:
+ *
+ * @ttm: The struct ttm_tt to contain the backing pages.
+ *
+ * Add backing pages to all of @ttm
+ */
+extern int ttm_pool_populate(struct ttm_tt *ttm);
+
+/**
+ * ttm_pool_unpopulate:
+ *
+ * @ttm: The struct ttm_tt which to free backing pages.
+ *
+ * Free all pages of @ttm
+ */
+extern void ttm_pool_unpopulate(struct ttm_tt *ttm);
+
+/**
+ * Output the state of pools to debugfs file
+ */
+/* XXXKIB
+extern int ttm_page_alloc_debugfs(struct seq_file *m, void *data);
+*/
+
+#ifdef CONFIG_SWIOTLB
+/**
+ * Initialize pool allocator.
+ */
+int ttm_dma_page_alloc_init(struct ttm_mem_global *glob, unsigned max_pages);
+
+/**
+ * Free pool allocator.
+ */
+void ttm_dma_page_alloc_fini(void);
+
+/**
+ * Output the state of pools to debugfs file
+ */
+extern int ttm_dma_page_alloc_debugfs(struct seq_file *m, void *data);
+
+extern int ttm_dma_populate(struct ttm_dma_tt *ttm_dma, struct device *dev);
+extern void ttm_dma_unpopulate(struct ttm_dma_tt *ttm_dma, struct device *dev);
+
+#else
+static inline int ttm_dma_page_alloc_init(struct ttm_mem_global *glob,
+ unsigned max_pages)
+{
+ return -ENODEV;
+}
+
+static inline void ttm_dma_page_alloc_fini(void) { return; }
+
+/* XXXKIB
+static inline int ttm_dma_page_alloc_debugfs(struct seq_file *m, void *data)
+{
+ return 0;
+}
+*/
+#endif
+
+#endif
diff --git a/sys/dev/drm2/ttm/ttm_page_alloc_dma.c b/sys/dev/drm2/ttm/ttm_page_alloc_dma.c
new file mode 100644
index 0000000..a5c6fed
--- /dev/null
+++ b/sys/dev/drm2/ttm/ttm_page_alloc_dma.c
@@ -0,0 +1,1134 @@
+/*
+ * Copyright 2011 (c) Oracle Corp.
+
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sub license,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the
+ * next paragraph) shall be included in all copies or substantial portions
+ * of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ *
+ * Author: Konrad Rzeszutek Wilk <konrad.wilk@oracle.com>
+ */
+
+/*
+ * A simple DMA pool losely based on dmapool.c. It has certain advantages
+ * over the DMA pools:
+ * - Pool collects resently freed pages for reuse (and hooks up to
+ * the shrinker).
+ * - Tracks currently in use pages
+ * - Tracks whether the page is UC, WB or cached (and reverts to WB
+ * when freed).
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#define pr_fmt(fmt) "[TTM] " fmt
+
+#include <linux/dma-mapping.h>
+#include <linux/list.h>
+#include <linux/seq_file.h> /* for seq_printf */
+#include <linux/slab.h>
+#include <linux/spinlock.h>
+#include <linux/highmem.h>
+#include <linux/mm_types.h>
+#include <linux/module.h>
+#include <linux/mm.h>
+#include <linux/atomic.h>
+#include <linux/device.h>
+#include <linux/kthread.h>
+#include <drm/ttm/ttm_bo_driver.h>
+#include <drm/ttm/ttm_page_alloc.h>
+#ifdef TTM_HAS_AGP
+#include <asm/agp.h>
+#endif
+
+#define NUM_PAGES_TO_ALLOC (PAGE_SIZE/sizeof(struct page *))
+#define SMALL_ALLOCATION 4
+#define FREE_ALL_PAGES (~0U)
+/* times are in msecs */
+#define IS_UNDEFINED (0)
+#define IS_WC (1<<1)
+#define IS_UC (1<<2)
+#define IS_CACHED (1<<3)
+#define IS_DMA32 (1<<4)
+
+enum pool_type {
+ POOL_IS_UNDEFINED,
+ POOL_IS_WC = IS_WC,
+ POOL_IS_UC = IS_UC,
+ POOL_IS_CACHED = IS_CACHED,
+ POOL_IS_WC_DMA32 = IS_WC | IS_DMA32,
+ POOL_IS_UC_DMA32 = IS_UC | IS_DMA32,
+ POOL_IS_CACHED_DMA32 = IS_CACHED | IS_DMA32,
+};
+/*
+ * The pool structure. There are usually six pools:
+ * - generic (not restricted to DMA32):
+ * - write combined, uncached, cached.
+ * - dma32 (up to 2^32 - so up 4GB):
+ * - write combined, uncached, cached.
+ * for each 'struct device'. The 'cached' is for pages that are actively used.
+ * The other ones can be shrunk by the shrinker API if neccessary.
+ * @pools: The 'struct device->dma_pools' link.
+ * @type: Type of the pool
+ * @lock: Protects the inuse_list and free_list from concurrnet access. Must be
+ * used with irqsave/irqrestore variants because pool allocator maybe called
+ * from delayed work.
+ * @inuse_list: Pool of pages that are in use. The order is very important and
+ * it is in the order that the TTM pages that are put back are in.
+ * @free_list: Pool of pages that are free to be used. No order requirements.
+ * @dev: The device that is associated with these pools.
+ * @size: Size used during DMA allocation.
+ * @npages_free: Count of available pages for re-use.
+ * @npages_in_use: Count of pages that are in use.
+ * @nfrees: Stats when pool is shrinking.
+ * @nrefills: Stats when the pool is grown.
+ * @gfp_flags: Flags to pass for alloc_page.
+ * @name: Name of the pool.
+ * @dev_name: Name derieved from dev - similar to how dev_info works.
+ * Used during shutdown as the dev_info during release is unavailable.
+ */
+struct dma_pool {
+ struct list_head pools; /* The 'struct device->dma_pools link */
+ enum pool_type type;
+ spinlock_t lock;
+ struct list_head inuse_list;
+ struct list_head free_list;
+ struct device *dev;
+ unsigned size;
+ unsigned npages_free;
+ unsigned npages_in_use;
+ unsigned long nfrees; /* Stats when shrunk. */
+ unsigned long nrefills; /* Stats when grown. */
+ gfp_t gfp_flags;
+ char name[13]; /* "cached dma32" */
+ char dev_name[64]; /* Constructed from dev */
+};
+
+/*
+ * The accounting page keeping track of the allocated page along with
+ * the DMA address.
+ * @page_list: The link to the 'page_list' in 'struct dma_pool'.
+ * @vaddr: The virtual address of the page
+ * @dma: The bus address of the page. If the page is not allocated
+ * via the DMA API, it will be -1.
+ */
+struct dma_page {
+ struct list_head page_list;
+ void *vaddr;
+ struct page *p;
+ dma_addr_t dma;
+};
+
+/*
+ * Limits for the pool. They are handled without locks because only place where
+ * they may change is in sysfs store. They won't have immediate effect anyway
+ * so forcing serialization to access them is pointless.
+ */
+
+struct ttm_pool_opts {
+ unsigned alloc_size;
+ unsigned max_size;
+ unsigned small;
+};
+
+/*
+ * Contains the list of all of the 'struct device' and their corresponding
+ * DMA pools. Guarded by _mutex->lock.
+ * @pools: The link to 'struct ttm_pool_manager->pools'
+ * @dev: The 'struct device' associated with the 'pool'
+ * @pool: The 'struct dma_pool' associated with the 'dev'
+ */
+struct device_pools {
+ struct list_head pools;
+ struct device *dev;
+ struct dma_pool *pool;
+};
+
+/*
+ * struct ttm_pool_manager - Holds memory pools for fast allocation
+ *
+ * @lock: Lock used when adding/removing from pools
+ * @pools: List of 'struct device' and 'struct dma_pool' tuples.
+ * @options: Limits for the pool.
+ * @npools: Total amount of pools in existence.
+ * @shrinker: The structure used by [un|]register_shrinker
+ */
+struct ttm_pool_manager {
+ struct mutex lock;
+ struct list_head pools;
+ struct ttm_pool_opts options;
+ unsigned npools;
+ struct shrinker mm_shrink;
+ struct kobject kobj;
+};
+
+static struct ttm_pool_manager *_manager;
+
+static struct attribute ttm_page_pool_max = {
+ .name = "pool_max_size",
+ .mode = S_IRUGO | S_IWUSR
+};
+static struct attribute ttm_page_pool_small = {
+ .name = "pool_small_allocation",
+ .mode = S_IRUGO | S_IWUSR
+};
+static struct attribute ttm_page_pool_alloc_size = {
+ .name = "pool_allocation_size",
+ .mode = S_IRUGO | S_IWUSR
+};
+
+static struct attribute *ttm_pool_attrs[] = {
+ &ttm_page_pool_max,
+ &ttm_page_pool_small,
+ &ttm_page_pool_alloc_size,
+ NULL
+};
+
+static void ttm_pool_kobj_release(struct kobject *kobj)
+{
+ struct ttm_pool_manager *m =
+ container_of(kobj, struct ttm_pool_manager, kobj);
+ kfree(m);
+}
+
+static ssize_t ttm_pool_store(struct kobject *kobj, struct attribute *attr,
+ const char *buffer, size_t size)
+{
+ struct ttm_pool_manager *m =
+ container_of(kobj, struct ttm_pool_manager, kobj);
+ int chars;
+ unsigned val;
+ chars = sscanf(buffer, "%u", &val);
+ if (chars == 0)
+ return size;
+
+ /* Convert kb to number of pages */
+ val = val / (PAGE_SIZE >> 10);
+
+ if (attr == &ttm_page_pool_max)
+ m->options.max_size = val;
+ else if (attr == &ttm_page_pool_small)
+ m->options.small = val;
+ else if (attr == &ttm_page_pool_alloc_size) {
+ if (val > NUM_PAGES_TO_ALLOC*8) {
+ pr_err("Setting allocation size to %lu is not allowed. Recommended size is %lu\n",
+ NUM_PAGES_TO_ALLOC*(PAGE_SIZE >> 7),
+ NUM_PAGES_TO_ALLOC*(PAGE_SIZE >> 10));
+ return size;
+ } else if (val > NUM_PAGES_TO_ALLOC) {
+ pr_warn("Setting allocation size to larger than %lu is not recommended\n",
+ NUM_PAGES_TO_ALLOC*(PAGE_SIZE >> 10));
+ }
+ m->options.alloc_size = val;
+ }
+
+ return size;
+}
+
+static ssize_t ttm_pool_show(struct kobject *kobj, struct attribute *attr,
+ char *buffer)
+{
+ struct ttm_pool_manager *m =
+ container_of(kobj, struct ttm_pool_manager, kobj);
+ unsigned val = 0;
+
+ if (attr == &ttm_page_pool_max)
+ val = m->options.max_size;
+ else if (attr == &ttm_page_pool_small)
+ val = m->options.small;
+ else if (attr == &ttm_page_pool_alloc_size)
+ val = m->options.alloc_size;
+
+ val = val * (PAGE_SIZE >> 10);
+
+ return snprintf(buffer, PAGE_SIZE, "%u\n", val);
+}
+
+static const struct sysfs_ops ttm_pool_sysfs_ops = {
+ .show = &ttm_pool_show,
+ .store = &ttm_pool_store,
+};
+
+static struct kobj_type ttm_pool_kobj_type = {
+ .release = &ttm_pool_kobj_release,
+ .sysfs_ops = &ttm_pool_sysfs_ops,
+ .default_attrs = ttm_pool_attrs,
+};
+
+#ifndef CONFIG_X86
+static int set_pages_array_wb(struct page **pages, int addrinarray)
+{
+#ifdef TTM_HAS_AGP
+ int i;
+
+ for (i = 0; i < addrinarray; i++)
+ unmap_page_from_agp(pages[i]);
+#endif
+ return 0;
+}
+
+static int set_pages_array_wc(struct page **pages, int addrinarray)
+{
+#ifdef TTM_HAS_AGP
+ int i;
+
+ for (i = 0; i < addrinarray; i++)
+ map_page_into_agp(pages[i]);
+#endif
+ return 0;
+}
+
+static int set_pages_array_uc(struct page **pages, int addrinarray)
+{
+#ifdef TTM_HAS_AGP
+ int i;
+
+ for (i = 0; i < addrinarray; i++)
+ map_page_into_agp(pages[i]);
+#endif
+ return 0;
+}
+#endif /* for !CONFIG_X86 */
+
+static int ttm_set_pages_caching(struct dma_pool *pool,
+ struct page **pages, unsigned cpages)
+{
+ int r = 0;
+ /* Set page caching */
+ if (pool->type & IS_UC) {
+ r = set_pages_array_uc(pages, cpages);
+ if (r)
+ pr_err("%s: Failed to set %d pages to uc!\n",
+ pool->dev_name, cpages);
+ }
+ if (pool->type & IS_WC) {
+ r = set_pages_array_wc(pages, cpages);
+ if (r)
+ pr_err("%s: Failed to set %d pages to wc!\n",
+ pool->dev_name, cpages);
+ }
+ return r;
+}
+
+static void __ttm_dma_free_page(struct dma_pool *pool, struct dma_page *d_page)
+{
+ dma_addr_t dma = d_page->dma;
+ dma_free_coherent(pool->dev, pool->size, d_page->vaddr, dma);
+
+ kfree(d_page);
+ d_page = NULL;
+}
+static struct dma_page *__ttm_dma_alloc_page(struct dma_pool *pool)
+{
+ struct dma_page *d_page;
+
+ d_page = kmalloc(sizeof(struct dma_page), GFP_KERNEL);
+ if (!d_page)
+ return NULL;
+
+ d_page->vaddr = dma_alloc_coherent(pool->dev, pool->size,
+ &d_page->dma,
+ pool->gfp_flags);
+ if (d_page->vaddr)
+ d_page->p = virt_to_page(d_page->vaddr);
+ else {
+ kfree(d_page);
+ d_page = NULL;
+ }
+ return d_page;
+}
+static enum pool_type ttm_to_type(int flags, enum ttm_caching_state cstate)
+{
+ enum pool_type type = IS_UNDEFINED;
+
+ if (flags & TTM_PAGE_FLAG_DMA32)
+ type |= IS_DMA32;
+ if (cstate == tt_cached)
+ type |= IS_CACHED;
+ else if (cstate == tt_uncached)
+ type |= IS_UC;
+ else
+ type |= IS_WC;
+
+ return type;
+}
+
+static void ttm_pool_update_free_locked(struct dma_pool *pool,
+ unsigned freed_pages)
+{
+ pool->npages_free -= freed_pages;
+ pool->nfrees += freed_pages;
+
+}
+
+/* set memory back to wb and free the pages. */
+static void ttm_dma_pages_put(struct dma_pool *pool, struct list_head *d_pages,
+ struct page *pages[], unsigned npages)
+{
+ struct dma_page *d_page, *tmp;
+
+ /* Don't set WB on WB page pool. */
+ if (npages && !(pool->type & IS_CACHED) &&
+ set_pages_array_wb(pages, npages))
+ pr_err("%s: Failed to set %d pages to wb!\n",
+ pool->dev_name, npages);
+
+ list_for_each_entry_safe(d_page, tmp, d_pages, page_list) {
+ list_del(&d_page->page_list);
+ __ttm_dma_free_page(pool, d_page);
+ }
+}
+
+static void ttm_dma_page_put(struct dma_pool *pool, struct dma_page *d_page)
+{
+ /* Don't set WB on WB page pool. */
+ if (!(pool->type & IS_CACHED) && set_pages_array_wb(&d_page->p, 1))
+ pr_err("%s: Failed to set %d pages to wb!\n",
+ pool->dev_name, 1);
+
+ list_del(&d_page->page_list);
+ __ttm_dma_free_page(pool, d_page);
+}
+
+/*
+ * Free pages from pool.
+ *
+ * To prevent hogging the ttm_swap process we only free NUM_PAGES_TO_ALLOC
+ * number of pages in one go.
+ *
+ * @pool: to free the pages from
+ * @nr_free: If set to true will free all pages in pool
+ **/
+static unsigned ttm_dma_page_pool_free(struct dma_pool *pool, unsigned nr_free)
+{
+ unsigned long irq_flags;
+ struct dma_page *dma_p, *tmp;
+ struct page **pages_to_free;
+ struct list_head d_pages;
+ unsigned freed_pages = 0,
+ npages_to_free = nr_free;
+
+ if (NUM_PAGES_TO_ALLOC < nr_free)
+ npages_to_free = NUM_PAGES_TO_ALLOC;
+#if 0
+ if (nr_free > 1) {
+ pr_debug("%s: (%s:%d) Attempting to free %d (%d) pages\n",
+ pool->dev_name, pool->name, current->pid,
+ npages_to_free, nr_free);
+ }
+#endif
+ pages_to_free = kmalloc(npages_to_free * sizeof(struct page *),
+ GFP_KERNEL);
+
+ if (!pages_to_free) {
+ pr_err("%s: Failed to allocate memory for pool free operation\n",
+ pool->dev_name);
+ return 0;
+ }
+ INIT_LIST_HEAD(&d_pages);
+restart:
+ spin_lock_irqsave(&pool->lock, irq_flags);
+
+ /* We picking the oldest ones off the list */
+ list_for_each_entry_safe_reverse(dma_p, tmp, &pool->free_list,
+ page_list) {
+ if (freed_pages >= npages_to_free)
+ break;
+
+ /* Move the dma_page from one list to another. */
+ list_move(&dma_p->page_list, &d_pages);
+
+ pages_to_free[freed_pages++] = dma_p->p;
+ /* We can only remove NUM_PAGES_TO_ALLOC at a time. */
+ if (freed_pages >= NUM_PAGES_TO_ALLOC) {
+
+ ttm_pool_update_free_locked(pool, freed_pages);
+ /**
+ * Because changing page caching is costly
+ * we unlock the pool to prevent stalling.
+ */
+ spin_unlock_irqrestore(&pool->lock, irq_flags);
+
+ ttm_dma_pages_put(pool, &d_pages, pages_to_free,
+ freed_pages);
+
+ INIT_LIST_HEAD(&d_pages);
+
+ if (likely(nr_free != FREE_ALL_PAGES))
+ nr_free -= freed_pages;
+
+ if (NUM_PAGES_TO_ALLOC >= nr_free)
+ npages_to_free = nr_free;
+ else
+ npages_to_free = NUM_PAGES_TO_ALLOC;
+
+ freed_pages = 0;
+
+ /* free all so restart the processing */
+ if (nr_free)
+ goto restart;
+
+ /* Not allowed to fall through or break because
+ * following context is inside spinlock while we are
+ * outside here.
+ */
+ goto out;
+
+ }
+ }
+
+ /* remove range of pages from the pool */
+ if (freed_pages) {
+ ttm_pool_update_free_locked(pool, freed_pages);
+ nr_free -= freed_pages;
+ }
+
+ spin_unlock_irqrestore(&pool->lock, irq_flags);
+
+ if (freed_pages)
+ ttm_dma_pages_put(pool, &d_pages, pages_to_free, freed_pages);
+out:
+ kfree(pages_to_free);
+ return nr_free;
+}
+
+static void ttm_dma_free_pool(struct device *dev, enum pool_type type)
+{
+ struct device_pools *p;
+ struct dma_pool *pool;
+
+ if (!dev)
+ return;
+
+ mutex_lock(&_manager->lock);
+ list_for_each_entry_reverse(p, &_manager->pools, pools) {
+ if (p->dev != dev)
+ continue;
+ pool = p->pool;
+ if (pool->type != type)
+ continue;
+
+ list_del(&p->pools);
+ kfree(p);
+ _manager->npools--;
+ break;
+ }
+ list_for_each_entry_reverse(pool, &dev->dma_pools, pools) {
+ if (pool->type != type)
+ continue;
+ /* Takes a spinlock.. */
+ ttm_dma_page_pool_free(pool, FREE_ALL_PAGES);
+ WARN_ON(((pool->npages_in_use + pool->npages_free) != 0));
+ /* This code path is called after _all_ references to the
+ * struct device has been dropped - so nobody should be
+ * touching it. In case somebody is trying to _add_ we are
+ * guarded by the mutex. */
+ list_del(&pool->pools);
+ kfree(pool);
+ break;
+ }
+ mutex_unlock(&_manager->lock);
+}
+
+/*
+ * On free-ing of the 'struct device' this deconstructor is run.
+ * Albeit the pool might have already been freed earlier.
+ */
+static void ttm_dma_pool_release(struct device *dev, void *res)
+{
+ struct dma_pool *pool = *(struct dma_pool **)res;
+
+ if (pool)
+ ttm_dma_free_pool(dev, pool->type);
+}
+
+static int ttm_dma_pool_match(struct device *dev, void *res, void *match_data)
+{
+ return *(struct dma_pool **)res == match_data;
+}
+
+static struct dma_pool *ttm_dma_pool_init(struct device *dev, gfp_t flags,
+ enum pool_type type)
+{
+ char *n[] = {"wc", "uc", "cached", " dma32", "unknown",};
+ enum pool_type t[] = {IS_WC, IS_UC, IS_CACHED, IS_DMA32, IS_UNDEFINED};
+ struct device_pools *sec_pool = NULL;
+ struct dma_pool *pool = NULL, **ptr;
+ unsigned i;
+ int ret = -ENODEV;
+ char *p;
+
+ if (!dev)
+ return NULL;
+
+ ptr = devres_alloc(ttm_dma_pool_release, sizeof(*ptr), GFP_KERNEL);
+ if (!ptr)
+ return NULL;
+
+ ret = -ENOMEM;
+
+ pool = kmalloc_node(sizeof(struct dma_pool), GFP_KERNEL,
+ dev_to_node(dev));
+ if (!pool)
+ goto err_mem;
+
+ sec_pool = kmalloc_node(sizeof(struct device_pools), GFP_KERNEL,
+ dev_to_node(dev));
+ if (!sec_pool)
+ goto err_mem;
+
+ INIT_LIST_HEAD(&sec_pool->pools);
+ sec_pool->dev = dev;
+ sec_pool->pool = pool;
+
+ INIT_LIST_HEAD(&pool->free_list);
+ INIT_LIST_HEAD(&pool->inuse_list);
+ INIT_LIST_HEAD(&pool->pools);
+ spin_lock_init(&pool->lock);
+ pool->dev = dev;
+ pool->npages_free = pool->npages_in_use = 0;
+ pool->nfrees = 0;
+ pool->gfp_flags = flags;
+ pool->size = PAGE_SIZE;
+ pool->type = type;
+ pool->nrefills = 0;
+ p = pool->name;
+ for (i = 0; i < 5; i++) {
+ if (type & t[i]) {
+ p += snprintf(p, sizeof(pool->name) - (p - pool->name),
+ "%s", n[i]);
+ }
+ }
+ *p = 0;
+ /* We copy the name for pr_ calls b/c when dma_pool_destroy is called
+ * - the kobj->name has already been deallocated.*/
+ snprintf(pool->dev_name, sizeof(pool->dev_name), "%s %s",
+ dev_driver_string(dev), dev_name(dev));
+ mutex_lock(&_manager->lock);
+ /* You can get the dma_pool from either the global: */
+ list_add(&sec_pool->pools, &_manager->pools);
+ _manager->npools++;
+ /* or from 'struct device': */
+ list_add(&pool->pools, &dev->dma_pools);
+ mutex_unlock(&_manager->lock);
+
+ *ptr = pool;
+ devres_add(dev, ptr);
+
+ return pool;
+err_mem:
+ devres_free(ptr);
+ kfree(sec_pool);
+ kfree(pool);
+ return ERR_PTR(ret);
+}
+
+static struct dma_pool *ttm_dma_find_pool(struct device *dev,
+ enum pool_type type)
+{
+ struct dma_pool *pool, *tmp, *found = NULL;
+
+ if (type == IS_UNDEFINED)
+ return found;
+
+ /* NB: We iterate on the 'struct dev' which has no spinlock, but
+ * it does have a kref which we have taken. The kref is taken during
+ * graphic driver loading - in the drm_pci_init it calls either
+ * pci_dev_get or pci_register_driver which both end up taking a kref
+ * on 'struct device'.
+ *
+ * On teardown, the graphic drivers end up quiescing the TTM (put_pages)
+ * and calls the dev_res deconstructors: ttm_dma_pool_release. The nice
+ * thing is at that point of time there are no pages associated with the
+ * driver so this function will not be called.
+ */
+ list_for_each_entry_safe(pool, tmp, &dev->dma_pools, pools) {
+ if (pool->type != type)
+ continue;
+ found = pool;
+ break;
+ }
+ return found;
+}
+
+/*
+ * Free pages the pages that failed to change the caching state. If there
+ * are pages that have changed their caching state already put them to the
+ * pool.
+ */
+static void ttm_dma_handle_caching_state_failure(struct dma_pool *pool,
+ struct list_head *d_pages,
+ struct page **failed_pages,
+ unsigned cpages)
+{
+ struct dma_page *d_page, *tmp;
+ struct page *p;
+ unsigned i = 0;
+
+ p = failed_pages[0];
+ if (!p)
+ return;
+ /* Find the failed page. */
+ list_for_each_entry_safe(d_page, tmp, d_pages, page_list) {
+ if (d_page->p != p)
+ continue;
+ /* .. and then progress over the full list. */
+ list_del(&d_page->page_list);
+ __ttm_dma_free_page(pool, d_page);
+ if (++i < cpages)
+ p = failed_pages[i];
+ else
+ break;
+ }
+
+}
+
+/*
+ * Allocate 'count' pages, and put 'need' number of them on the
+ * 'pages' and as well on the 'dma_address' starting at 'dma_offset' offset.
+ * The full list of pages should also be on 'd_pages'.
+ * We return zero for success, and negative numbers as errors.
+ */
+static int ttm_dma_pool_alloc_new_pages(struct dma_pool *pool,
+ struct list_head *d_pages,
+ unsigned count)
+{
+ struct page **caching_array;
+ struct dma_page *dma_p;
+ struct page *p;
+ int r = 0;
+ unsigned i, cpages;
+ unsigned max_cpages = min(count,
+ (unsigned)(PAGE_SIZE/sizeof(struct page *)));
+
+ /* allocate array for page caching change */
+ caching_array = kmalloc(max_cpages*sizeof(struct page *), GFP_KERNEL);
+
+ if (!caching_array) {
+ pr_err("%s: Unable to allocate table for new pages\n",
+ pool->dev_name);
+ return -ENOMEM;
+ }
+
+ if (count > 1) {
+ pr_debug("%s: (%s:%d) Getting %d pages\n",
+ pool->dev_name, pool->name, current->pid, count);
+ }
+
+ for (i = 0, cpages = 0; i < count; ++i) {
+ dma_p = __ttm_dma_alloc_page(pool);
+ if (!dma_p) {
+ pr_err("%s: Unable to get page %u\n",
+ pool->dev_name, i);
+
+ /* store already allocated pages in the pool after
+ * setting the caching state */
+ if (cpages) {
+ r = ttm_set_pages_caching(pool, caching_array,
+ cpages);
+ if (r)
+ ttm_dma_handle_caching_state_failure(
+ pool, d_pages, caching_array,
+ cpages);
+ }
+ r = -ENOMEM;
+ goto out;
+ }
+ p = dma_p->p;
+#ifdef CONFIG_HIGHMEM
+ /* gfp flags of highmem page should never be dma32 so we
+ * we should be fine in such case
+ */
+ if (!PageHighMem(p))
+#endif
+ {
+ caching_array[cpages++] = p;
+ if (cpages == max_cpages) {
+ /* Note: Cannot hold the spinlock */
+ r = ttm_set_pages_caching(pool, caching_array,
+ cpages);
+ if (r) {
+ ttm_dma_handle_caching_state_failure(
+ pool, d_pages, caching_array,
+ cpages);
+ goto out;
+ }
+ cpages = 0;
+ }
+ }
+ list_add(&dma_p->page_list, d_pages);
+ }
+
+ if (cpages) {
+ r = ttm_set_pages_caching(pool, caching_array, cpages);
+ if (r)
+ ttm_dma_handle_caching_state_failure(pool, d_pages,
+ caching_array, cpages);
+ }
+out:
+ kfree(caching_array);
+ return r;
+}
+
+/*
+ * @return count of pages still required to fulfill the request.
+ */
+static int ttm_dma_page_pool_fill_locked(struct dma_pool *pool,
+ unsigned long *irq_flags)
+{
+ unsigned count = _manager->options.small;
+ int r = pool->npages_free;
+
+ if (count > pool->npages_free) {
+ struct list_head d_pages;
+
+ INIT_LIST_HEAD(&d_pages);
+
+ spin_unlock_irqrestore(&pool->lock, *irq_flags);
+
+ /* Returns how many more are neccessary to fulfill the
+ * request. */
+ r = ttm_dma_pool_alloc_new_pages(pool, &d_pages, count);
+
+ spin_lock_irqsave(&pool->lock, *irq_flags);
+ if (!r) {
+ /* Add the fresh to the end.. */
+ list_splice(&d_pages, &pool->free_list);
+ ++pool->nrefills;
+ pool->npages_free += count;
+ r = count;
+ } else {
+ struct dma_page *d_page;
+ unsigned cpages = 0;
+
+ pr_err("%s: Failed to fill %s pool (r:%d)!\n",
+ pool->dev_name, pool->name, r);
+
+ list_for_each_entry(d_page, &d_pages, page_list) {
+ cpages++;
+ }
+ list_splice_tail(&d_pages, &pool->free_list);
+ pool->npages_free += cpages;
+ r = cpages;
+ }
+ }
+ return r;
+}
+
+/*
+ * @return count of pages still required to fulfill the request.
+ * The populate list is actually a stack (not that is matters as TTM
+ * allocates one page at a time.
+ */
+static int ttm_dma_pool_get_pages(struct dma_pool *pool,
+ struct ttm_dma_tt *ttm_dma,
+ unsigned index)
+{
+ struct dma_page *d_page;
+ struct ttm_tt *ttm = &ttm_dma->ttm;
+ unsigned long irq_flags;
+ int count, r = -ENOMEM;
+
+ spin_lock_irqsave(&pool->lock, irq_flags);
+ count = ttm_dma_page_pool_fill_locked(pool, &irq_flags);
+ if (count) {
+ d_page = list_first_entry(&pool->free_list, struct dma_page, page_list);
+ ttm->pages[index] = d_page->p;
+ ttm_dma->dma_address[index] = d_page->dma;
+ list_move_tail(&d_page->page_list, &ttm_dma->pages_list);
+ r = 0;
+ pool->npages_in_use += 1;
+ pool->npages_free -= 1;
+ }
+ spin_unlock_irqrestore(&pool->lock, irq_flags);
+ return r;
+}
+
+/*
+ * On success pages list will hold count number of correctly
+ * cached pages. On failure will hold the negative return value (-ENOMEM, etc).
+ */
+int ttm_dma_populate(struct ttm_dma_tt *ttm_dma, struct device *dev)
+{
+ struct ttm_tt *ttm = &ttm_dma->ttm;
+ struct ttm_mem_global *mem_glob = ttm->glob->mem_glob;
+ struct dma_pool *pool;
+ enum pool_type type;
+ unsigned i;
+ gfp_t gfp_flags;
+ int ret;
+
+ if (ttm->state != tt_unpopulated)
+ return 0;
+
+ type = ttm_to_type(ttm->page_flags, ttm->caching_state);
+ if (ttm->page_flags & TTM_PAGE_FLAG_DMA32)
+ gfp_flags = GFP_USER | GFP_DMA32;
+ else
+ gfp_flags = GFP_HIGHUSER;
+ if (ttm->page_flags & TTM_PAGE_FLAG_ZERO_ALLOC)
+ gfp_flags |= __GFP_ZERO;
+
+ pool = ttm_dma_find_pool(dev, type);
+ if (!pool) {
+ pool = ttm_dma_pool_init(dev, gfp_flags, type);
+ if (IS_ERR_OR_NULL(pool)) {
+ return -ENOMEM;
+ }
+ }
+
+ INIT_LIST_HEAD(&ttm_dma->pages_list);
+ for (i = 0; i < ttm->num_pages; ++i) {
+ ret = ttm_dma_pool_get_pages(pool, ttm_dma, i);
+ if (ret != 0) {
+ ttm_dma_unpopulate(ttm_dma, dev);
+ return -ENOMEM;
+ }
+
+ ret = ttm_mem_global_alloc_page(mem_glob, ttm->pages[i],
+ false, false);
+ if (unlikely(ret != 0)) {
+ ttm_dma_unpopulate(ttm_dma, dev);
+ return -ENOMEM;
+ }
+ }
+
+ if (unlikely(ttm->page_flags & TTM_PAGE_FLAG_SWAPPED)) {
+ ret = ttm_tt_swapin(ttm);
+ if (unlikely(ret != 0)) {
+ ttm_dma_unpopulate(ttm_dma, dev);
+ return ret;
+ }
+ }
+
+ ttm->state = tt_unbound;
+ return 0;
+}
+EXPORT_SYMBOL_GPL(ttm_dma_populate);
+
+/* Get good estimation how many pages are free in pools */
+static int ttm_dma_pool_get_num_unused_pages(void)
+{
+ struct device_pools *p;
+ unsigned total = 0;
+
+ mutex_lock(&_manager->lock);
+ list_for_each_entry(p, &_manager->pools, pools)
+ total += p->pool->npages_free;
+ mutex_unlock(&_manager->lock);
+ return total;
+}
+
+/* Put all pages in pages list to correct pool to wait for reuse */
+void ttm_dma_unpopulate(struct ttm_dma_tt *ttm_dma, struct device *dev)
+{
+ struct ttm_tt *ttm = &ttm_dma->ttm;
+ struct dma_pool *pool;
+ struct dma_page *d_page, *next;
+ enum pool_type type;
+ bool is_cached = false;
+ unsigned count = 0, i, npages = 0;
+ unsigned long irq_flags;
+
+ type = ttm_to_type(ttm->page_flags, ttm->caching_state);
+ pool = ttm_dma_find_pool(dev, type);
+ if (!pool)
+ return;
+
+ is_cached = (ttm_dma_find_pool(pool->dev,
+ ttm_to_type(ttm->page_flags, tt_cached)) == pool);
+
+ /* make sure pages array match list and count number of pages */
+ list_for_each_entry(d_page, &ttm_dma->pages_list, page_list) {
+ ttm->pages[count] = d_page->p;
+ count++;
+ }
+
+ spin_lock_irqsave(&pool->lock, irq_flags);
+ pool->npages_in_use -= count;
+ if (is_cached) {
+ pool->nfrees += count;
+ } else {
+ pool->npages_free += count;
+ list_splice(&ttm_dma->pages_list, &pool->free_list);
+ npages = count;
+ if (pool->npages_free > _manager->options.max_size) {
+ npages = pool->npages_free - _manager->options.max_size;
+ /* free at least NUM_PAGES_TO_ALLOC number of pages
+ * to reduce calls to set_memory_wb */
+ if (npages < NUM_PAGES_TO_ALLOC)
+ npages = NUM_PAGES_TO_ALLOC;
+ }
+ }
+ spin_unlock_irqrestore(&pool->lock, irq_flags);
+
+ if (is_cached) {
+ list_for_each_entry_safe(d_page, next, &ttm_dma->pages_list, page_list) {
+ ttm_mem_global_free_page(ttm->glob->mem_glob,
+ d_page->p);
+ ttm_dma_page_put(pool, d_page);
+ }
+ } else {
+ for (i = 0; i < count; i++) {
+ ttm_mem_global_free_page(ttm->glob->mem_glob,
+ ttm->pages[i]);
+ }
+ }
+
+ INIT_LIST_HEAD(&ttm_dma->pages_list);
+ for (i = 0; i < ttm->num_pages; i++) {
+ ttm->pages[i] = NULL;
+ ttm_dma->dma_address[i] = 0;
+ }
+
+ /* shrink pool if necessary (only on !is_cached pools)*/
+ if (npages)
+ ttm_dma_page_pool_free(pool, npages);
+ ttm->state = tt_unpopulated;
+}
+EXPORT_SYMBOL_GPL(ttm_dma_unpopulate);
+
+/**
+ * Callback for mm to request pool to reduce number of page held.
+ */
+static int ttm_dma_pool_mm_shrink(struct shrinker *shrink,
+ struct shrink_control *sc)
+{
+ static atomic_t start_pool = ATOMIC_INIT(0);
+ unsigned idx = 0;
+ unsigned pool_offset = atomic_add_return(1, &start_pool);
+ unsigned shrink_pages = sc->nr_to_scan;
+ struct device_pools *p;
+
+ if (list_empty(&_manager->pools))
+ return 0;
+
+ mutex_lock(&_manager->lock);
+ pool_offset = pool_offset % _manager->npools;
+ list_for_each_entry(p, &_manager->pools, pools) {
+ unsigned nr_free;
+
+ if (!p->dev)
+ continue;
+ if (shrink_pages == 0)
+ break;
+ /* Do it in round-robin fashion. */
+ if (++idx < pool_offset)
+ continue;
+ nr_free = shrink_pages;
+ shrink_pages = ttm_dma_page_pool_free(p->pool, nr_free);
+ pr_debug("%s: (%s:%d) Asked to shrink %d, have %d more to go\n",
+ p->pool->dev_name, p->pool->name, current->pid,
+ nr_free, shrink_pages);
+ }
+ mutex_unlock(&_manager->lock);
+ /* return estimated number of unused pages in pool */
+ return ttm_dma_pool_get_num_unused_pages();
+}
+
+static void ttm_dma_pool_mm_shrink_init(struct ttm_pool_manager *manager)
+{
+ manager->mm_shrink.shrink = &ttm_dma_pool_mm_shrink;
+ manager->mm_shrink.seeks = 1;
+ register_shrinker(&manager->mm_shrink);
+}
+
+static void ttm_dma_pool_mm_shrink_fini(struct ttm_pool_manager *manager)
+{
+ unregister_shrinker(&manager->mm_shrink);
+}
+
+int ttm_dma_page_alloc_init(struct ttm_mem_global *glob, unsigned max_pages)
+{
+ int ret = -ENOMEM;
+
+ WARN_ON(_manager);
+
+ pr_info("Initializing DMA pool allocator\n");
+
+ _manager = kzalloc(sizeof(*_manager), GFP_KERNEL);
+ if (!_manager)
+ goto err;
+
+ mutex_init(&_manager->lock);
+ INIT_LIST_HEAD(&_manager->pools);
+
+ _manager->options.max_size = max_pages;
+ _manager->options.small = SMALL_ALLOCATION;
+ _manager->options.alloc_size = NUM_PAGES_TO_ALLOC;
+
+ /* This takes care of auto-freeing the _manager */
+ ret = kobject_init_and_add(&_manager->kobj, &ttm_pool_kobj_type,
+ &glob->kobj, "dma_pool");
+ if (unlikely(ret != 0)) {
+ kobject_put(&_manager->kobj);
+ goto err;
+ }
+ ttm_dma_pool_mm_shrink_init(_manager);
+ return 0;
+err:
+ return ret;
+}
+
+void ttm_dma_page_alloc_fini(void)
+{
+ struct device_pools *p, *t;
+
+ pr_info("Finalizing DMA pool allocator\n");
+ ttm_dma_pool_mm_shrink_fini(_manager);
+
+ list_for_each_entry_safe_reverse(p, t, &_manager->pools, pools) {
+ dev_dbg(p->dev, "(%s:%d) Freeing.\n", p->pool->name,
+ current->pid);
+ WARN_ON(devres_destroy(p->dev, ttm_dma_pool_release,
+ ttm_dma_pool_match, p->pool));
+ ttm_dma_free_pool(p->dev, p->pool->type);
+ }
+ kobject_put(&_manager->kobj);
+ _manager = NULL;
+}
+
+int ttm_dma_page_alloc_debugfs(struct seq_file *m, void *data)
+{
+ struct device_pools *p;
+ struct dma_pool *pool = NULL;
+ char *h[] = {"pool", "refills", "pages freed", "inuse", "available",
+ "name", "virt", "busaddr"};
+
+ if (!_manager) {
+ seq_printf(m, "No pool allocator running.\n");
+ return 0;
+ }
+ seq_printf(m, "%13s %12s %13s %8s %8s %8s\n",
+ h[0], h[1], h[2], h[3], h[4], h[5]);
+ mutex_lock(&_manager->lock);
+ list_for_each_entry(p, &_manager->pools, pools) {
+ struct device *dev = p->dev;
+ if (!dev)
+ continue;
+ pool = p->pool;
+ seq_printf(m, "%13s %12ld %13ld %8d %8d %8s\n",
+ pool->name, pool->nrefills,
+ pool->nfrees, pool->npages_in_use,
+ pool->npages_free,
+ pool->dev_name);
+ }
+ mutex_unlock(&_manager->lock);
+ return 0;
+}
+EXPORT_SYMBOL_GPL(ttm_dma_page_alloc_debugfs);
diff --git a/sys/dev/drm2/ttm/ttm_placement.h b/sys/dev/drm2/ttm/ttm_placement.h
new file mode 100644
index 0000000..20e1b4c
--- /dev/null
+++ b/sys/dev/drm2/ttm/ttm_placement.h
@@ -0,0 +1,93 @@
+/**************************************************************************
+ *
+ * Copyright (c) 2006-2009 VMware, Inc., Palo Alto, CA., USA
+ * All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sub license, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the
+ * next paragraph) shall be included in all copies or substantial portions
+ * of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDERS, AUTHORS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM,
+ * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
+ * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
+ * USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ **************************************************************************/
+/*
+ * Authors: Thomas Hellstrom <thellstrom-at-vmware-dot-com>
+ */
+/* $FreeBSD$ */
+
+#ifndef _TTM_PLACEMENT_H_
+#define _TTM_PLACEMENT_H_
+/*
+ * Memory regions for data placement.
+ */
+
+#define TTM_PL_SYSTEM 0
+#define TTM_PL_TT 1
+#define TTM_PL_VRAM 2
+#define TTM_PL_PRIV0 3
+#define TTM_PL_PRIV1 4
+#define TTM_PL_PRIV2 5
+#define TTM_PL_PRIV3 6
+#define TTM_PL_PRIV4 7
+#define TTM_PL_PRIV5 8
+#define TTM_PL_SWAPPED 15
+
+#define TTM_PL_FLAG_SYSTEM (1 << TTM_PL_SYSTEM)
+#define TTM_PL_FLAG_TT (1 << TTM_PL_TT)
+#define TTM_PL_FLAG_VRAM (1 << TTM_PL_VRAM)
+#define TTM_PL_FLAG_PRIV0 (1 << TTM_PL_PRIV0)
+#define TTM_PL_FLAG_PRIV1 (1 << TTM_PL_PRIV1)
+#define TTM_PL_FLAG_PRIV2 (1 << TTM_PL_PRIV2)
+#define TTM_PL_FLAG_PRIV3 (1 << TTM_PL_PRIV3)
+#define TTM_PL_FLAG_PRIV4 (1 << TTM_PL_PRIV4)
+#define TTM_PL_FLAG_PRIV5 (1 << TTM_PL_PRIV5)
+#define TTM_PL_FLAG_SWAPPED (1 << TTM_PL_SWAPPED)
+#define TTM_PL_MASK_MEM 0x0000FFFF
+
+/*
+ * Other flags that affects data placement.
+ * TTM_PL_FLAG_CACHED indicates cache-coherent mappings
+ * if available.
+ * TTM_PL_FLAG_SHARED means that another application may
+ * reference the buffer.
+ * TTM_PL_FLAG_NO_EVICT means that the buffer may never
+ * be evicted to make room for other buffers.
+ */
+
+#define TTM_PL_FLAG_CACHED (1 << 16)
+#define TTM_PL_FLAG_UNCACHED (1 << 17)
+#define TTM_PL_FLAG_WC (1 << 18)
+#define TTM_PL_FLAG_SHARED (1 << 20)
+#define TTM_PL_FLAG_NO_EVICT (1 << 21)
+
+#define TTM_PL_MASK_CACHING (TTM_PL_FLAG_CACHED | \
+ TTM_PL_FLAG_UNCACHED | \
+ TTM_PL_FLAG_WC)
+
+#define TTM_PL_MASK_MEMTYPE (TTM_PL_MASK_MEM | TTM_PL_MASK_CACHING)
+
+/*
+ * Access flags to be used for CPU- and GPU- mappings.
+ * The idea is that the TTM synchronization mechanism will
+ * allow concurrent READ access and exclusive write access.
+ * Currently GPU- and CPU accesses are exclusive.
+ */
+
+#define TTM_ACCESS_READ (1 << 0)
+#define TTM_ACCESS_WRITE (1 << 1)
+
+#endif
diff --git a/sys/dev/drm2/ttm/ttm_tt.c b/sys/dev/drm2/ttm/ttm_tt.c
new file mode 100644
index 0000000..35c22df
--- /dev/null
+++ b/sys/dev/drm2/ttm/ttm_tt.c
@@ -0,0 +1,370 @@
+/**************************************************************************
+ *
+ * Copyright (c) 2006-2009 VMware, Inc., Palo Alto, CA., USA
+ * All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sub license, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the
+ * next paragraph) shall be included in all copies or substantial portions
+ * of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDERS, AUTHORS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM,
+ * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
+ * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
+ * USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ **************************************************************************/
+/*
+ * Authors: Thomas Hellstrom <thellstrom-at-vmware-dot-com>
+ */
+/*
+ * Copyright (c) 2013 The FreeBSD Foundation
+ * All rights reserved.
+ *
+ * Portions of this software were developed by Konstantin Belousov
+ * <kib@FreeBSD.org> under sponsorship from the FreeBSD Foundation.
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include <dev/drm2/drmP.h>
+#include <dev/drm2/ttm/ttm_module.h>
+#include <dev/drm2/ttm/ttm_bo_driver.h>
+#include <dev/drm2/ttm/ttm_placement.h>
+#include <dev/drm2/ttm/ttm_page_alloc.h>
+
+MALLOC_DEFINE(M_TTM_PD, "ttm_pd", "TTM Page Directories");
+
+/**
+ * Allocates storage for pointers to the pages that back the ttm.
+ */
+static void ttm_tt_alloc_page_directory(struct ttm_tt *ttm)
+{
+ ttm->pages = malloc(ttm->num_pages * sizeof(void *),
+ M_TTM_PD, M_WAITOK | M_ZERO);
+}
+
+static void ttm_dma_tt_alloc_page_directory(struct ttm_dma_tt *ttm)
+{
+ ttm->ttm.pages = malloc(ttm->ttm.num_pages * sizeof(void *),
+ M_TTM_PD, M_WAITOK | M_ZERO);
+ ttm->dma_address = malloc(ttm->ttm.num_pages *
+ sizeof(*ttm->dma_address), M_TTM_PD, M_WAITOK);
+}
+
+#if defined(__i386__) || defined(__amd64__)
+static inline int ttm_tt_set_page_caching(vm_page_t p,
+ enum ttm_caching_state c_old,
+ enum ttm_caching_state c_new)
+{
+
+ /* XXXKIB our VM does not need this. */
+#if 0
+ if (c_old != tt_cached) {
+ /* p isn't in the default caching state, set it to
+ * writeback first to free its current memtype. */
+ pmap_page_set_memattr(p, VM_MEMATTR_WRITE_BACK);
+ }
+#endif
+
+ if (c_new == tt_wc)
+ pmap_page_set_memattr(p, VM_MEMATTR_WRITE_COMBINING);
+ else if (c_new == tt_uncached)
+ pmap_page_set_memattr(p, VM_MEMATTR_UNCACHEABLE);
+
+ return (0);
+}
+#else
+static inline int ttm_tt_set_page_caching(vm_page_t p,
+ enum ttm_caching_state c_old,
+ enum ttm_caching_state c_new)
+{
+ return 0;
+}
+#endif
+
+/*
+ * Change caching policy for the linear kernel map
+ * for range of pages in a ttm.
+ */
+
+static int ttm_tt_set_caching(struct ttm_tt *ttm,
+ enum ttm_caching_state c_state)
+{
+ int i, j;
+ vm_page_t cur_page;
+ int ret;
+
+ if (ttm->caching_state == c_state)
+ return 0;
+
+ if (ttm->state == tt_unpopulated) {
+ /* Change caching but don't populate */
+ ttm->caching_state = c_state;
+ return 0;
+ }
+
+ if (ttm->caching_state == tt_cached)
+ drm_clflush_pages(ttm->pages, ttm->num_pages);
+
+ for (i = 0; i < ttm->num_pages; ++i) {
+ cur_page = ttm->pages[i];
+ if (likely(cur_page != NULL)) {
+ ret = ttm_tt_set_page_caching(cur_page,
+ ttm->caching_state,
+ c_state);
+ if (unlikely(ret != 0))
+ goto out_err;
+ }
+ }
+
+ ttm->caching_state = c_state;
+
+ return 0;
+
+out_err:
+ for (j = 0; j < i; ++j) {
+ cur_page = ttm->pages[j];
+ if (cur_page != NULL) {
+ (void)ttm_tt_set_page_caching(cur_page, c_state,
+ ttm->caching_state);
+ }
+ }
+
+ return ret;
+}
+
+int ttm_tt_set_placement_caching(struct ttm_tt *ttm, uint32_t placement)
+{
+ enum ttm_caching_state state;
+
+ if (placement & TTM_PL_FLAG_WC)
+ state = tt_wc;
+ else if (placement & TTM_PL_FLAG_UNCACHED)
+ state = tt_uncached;
+ else
+ state = tt_cached;
+
+ return ttm_tt_set_caching(ttm, state);
+}
+
+void ttm_tt_destroy(struct ttm_tt *ttm)
+{
+ if (unlikely(ttm == NULL))
+ return;
+
+ if (ttm->state == tt_bound) {
+ ttm_tt_unbind(ttm);
+ }
+
+ if (likely(ttm->pages != NULL)) {
+ ttm->bdev->driver->ttm_tt_unpopulate(ttm);
+ }
+
+ if (!(ttm->page_flags & TTM_PAGE_FLAG_PERSISTENT_SWAP) &&
+ ttm->swap_storage)
+ vm_object_deallocate(ttm->swap_storage);
+
+ ttm->swap_storage = NULL;
+ ttm->func->destroy(ttm);
+}
+
+int ttm_tt_init(struct ttm_tt *ttm, struct ttm_bo_device *bdev,
+ unsigned long size, uint32_t page_flags,
+ vm_page_t dummy_read_page)
+{
+ ttm->bdev = bdev;
+ ttm->glob = bdev->glob;
+ ttm->num_pages = (size + PAGE_SIZE - 1) >> PAGE_SHIFT;
+ ttm->caching_state = tt_cached;
+ ttm->page_flags = page_flags;
+ ttm->dummy_read_page = dummy_read_page;
+ ttm->state = tt_unpopulated;
+ ttm->swap_storage = NULL;
+
+ ttm_tt_alloc_page_directory(ttm);
+ if (!ttm->pages) {
+ ttm_tt_destroy(ttm);
+ printf("Failed allocating page table\n");
+ return -ENOMEM;
+ }
+ return 0;
+}
+
+void ttm_tt_fini(struct ttm_tt *ttm)
+{
+ free(ttm->pages, M_TTM_PD);
+ ttm->pages = NULL;
+}
+
+int ttm_dma_tt_init(struct ttm_dma_tt *ttm_dma, struct ttm_bo_device *bdev,
+ unsigned long size, uint32_t page_flags,
+ vm_page_t dummy_read_page)
+{
+ struct ttm_tt *ttm = &ttm_dma->ttm;
+
+ ttm->bdev = bdev;
+ ttm->glob = bdev->glob;
+ ttm->num_pages = (size + PAGE_SIZE - 1) >> PAGE_SHIFT;
+ ttm->caching_state = tt_cached;
+ ttm->page_flags = page_flags;
+ ttm->dummy_read_page = dummy_read_page;
+ ttm->state = tt_unpopulated;
+ ttm->swap_storage = NULL;
+
+ INIT_LIST_HEAD(&ttm_dma->pages_list);
+ ttm_dma_tt_alloc_page_directory(ttm_dma);
+ if (!ttm->pages || !ttm_dma->dma_address) {
+ ttm_tt_destroy(ttm);
+ printf("Failed allocating page table\n");
+ return -ENOMEM;
+ }
+ return 0;
+}
+
+void ttm_dma_tt_fini(struct ttm_dma_tt *ttm_dma)
+{
+ struct ttm_tt *ttm = &ttm_dma->ttm;
+
+ free(ttm->pages, M_TTM_PD);
+ ttm->pages = NULL;
+ free(ttm_dma->dma_address, M_TTM_PD);
+ ttm_dma->dma_address = NULL;
+}
+
+void ttm_tt_unbind(struct ttm_tt *ttm)
+{
+ int ret;
+
+ if (ttm->state == tt_bound) {
+ ret = ttm->func->unbind(ttm);
+ MPASS(ret == 0);
+ ttm->state = tt_unbound;
+ }
+}
+
+int ttm_tt_bind(struct ttm_tt *ttm, struct ttm_mem_reg *bo_mem)
+{
+ int ret = 0;
+
+ if (!ttm)
+ return -EINVAL;
+
+ if (ttm->state == tt_bound)
+ return 0;
+
+ ret = ttm->bdev->driver->ttm_tt_populate(ttm);
+ if (ret)
+ return ret;
+
+ ret = ttm->func->bind(ttm, bo_mem);
+ if (unlikely(ret != 0))
+ return ret;
+
+ ttm->state = tt_bound;
+
+ return 0;
+}
+
+int ttm_tt_swapin(struct ttm_tt *ttm)
+{
+ vm_object_t obj;
+ vm_page_t from_page, to_page;
+ int i, ret, rv;
+
+ obj = ttm->swap_storage;
+
+ VM_OBJECT_WLOCK(obj);
+ vm_object_pip_add(obj, 1);
+ for (i = 0; i < ttm->num_pages; ++i) {
+ from_page = vm_page_grab(obj, i, VM_ALLOC_RETRY);
+ if (from_page->valid != VM_PAGE_BITS_ALL) {
+ if (vm_pager_has_page(obj, i, NULL, NULL)) {
+ rv = vm_pager_get_pages(obj, &from_page, 1, 0);
+ if (rv != VM_PAGER_OK) {
+ vm_page_lock(from_page);
+ vm_page_free(from_page);
+ vm_page_unlock(from_page);
+ ret = -EIO;
+ goto err_ret;
+ }
+ } else
+ vm_page_zero_invalid(from_page, TRUE);
+ }
+ to_page = ttm->pages[i];
+ if (unlikely(to_page == NULL)) {
+ vm_page_wakeup(from_page);
+ ret = -ENOMEM;
+ goto err_ret;
+ }
+ pmap_copy_page(from_page, to_page);
+ vm_page_wakeup(from_page);
+ }
+ vm_object_pip_wakeup(obj);
+ VM_OBJECT_WUNLOCK(obj);
+
+ if (!(ttm->page_flags & TTM_PAGE_FLAG_PERSISTENT_SWAP))
+ vm_object_deallocate(obj);
+ ttm->swap_storage = NULL;
+ ttm->page_flags &= ~TTM_PAGE_FLAG_SWAPPED;
+ return (0);
+
+err_ret:
+ vm_object_pip_wakeup(obj);
+ VM_OBJECT_WUNLOCK(obj);
+ return (ret);
+}
+
+int ttm_tt_swapout(struct ttm_tt *ttm, vm_object_t persistent_swap_storage)
+{
+ vm_object_t obj;
+ vm_page_t from_page, to_page;
+ int i;
+
+ MPASS(ttm->state == tt_unbound || ttm->state == tt_unpopulated);
+ MPASS(ttm->caching_state == tt_cached);
+
+ if (persistent_swap_storage == NULL) {
+ obj = vm_pager_allocate(OBJT_SWAP, NULL,
+ IDX_TO_OFF(ttm->num_pages), VM_PROT_DEFAULT, 0,
+ curthread->td_ucred);
+ if (obj == NULL) {
+ printf("[TTM] Failed allocating swap storage\n");
+ return (-ENOMEM);
+ }
+ } else
+ obj = persistent_swap_storage;
+
+ VM_OBJECT_WLOCK(obj);
+ vm_object_pip_add(obj, 1);
+ for (i = 0; i < ttm->num_pages; ++i) {
+ from_page = ttm->pages[i];
+ if (unlikely(from_page == NULL))
+ continue;
+ to_page = vm_page_grab(obj, i, VM_ALLOC_RETRY);
+ pmap_copy_page(from_page, to_page);
+ vm_page_dirty(to_page);
+ to_page->valid = VM_PAGE_BITS_ALL;
+ vm_page_wakeup(to_page);
+ }
+ vm_object_pip_wakeup(obj);
+ VM_OBJECT_WUNLOCK(obj);
+
+ ttm->bdev->driver->ttm_tt_unpopulate(ttm);
+ ttm->swap_storage = obj;
+ ttm->page_flags |= TTM_PAGE_FLAG_SWAPPED;
+ if (persistent_swap_storage != NULL)
+ ttm->page_flags |= TTM_PAGE_FLAG_PERSISTENT_SWAP;
+ return (0);
+}
diff --git a/sys/dev/hwpmc/hwpmc_soft.c b/sys/dev/hwpmc/hwpmc_soft.c
index 48e297e..56af775 100644
--- a/sys/dev/hwpmc/hwpmc_soft.c
+++ b/sys/dev/hwpmc/hwpmc_soft.c
@@ -45,8 +45,6 @@ __FBSDID("$FreeBSD$");
#define SOFT_CAPS (PMC_CAP_READ | PMC_CAP_WRITE | PMC_CAP_INTERRUPT | \
PMC_CAP_USER | PMC_CAP_SYSTEM)
-PMC_SOFT_DECLARE( , , clock, prof);
-
struct soft_descr {
struct pmc_descr pm_descr; /* "base class" */
};
@@ -126,9 +124,10 @@ soft_allocate_pmc(int cpu, int ri, struct pmc *pm,
if (ps == NULL)
return (EINVAL);
pmc_soft_ev_release(ps);
+ /* Module unload is protected by pmc SX lock. */
+ if (ps->ps_alloc != NULL)
+ ps->ps_alloc();
- if (ev == pmc___clock_prof.ps_ev.pm_ev_code)
- cpu_startprofclock();
return (0);
}
@@ -315,6 +314,8 @@ static int
soft_release_pmc(int cpu, int ri, struct pmc *pmc)
{
struct pmc_hw *phw;
+ enum pmc_event ev;
+ struct pmc_soft *ps;
(void) pmc;
@@ -328,8 +329,16 @@ soft_release_pmc(int cpu, int ri, struct pmc *pmc)
KASSERT(phw->phw_pmc == NULL,
("[soft,%d] PHW pmc %p non-NULL", __LINE__, phw->phw_pmc));
- if (pmc->pm_event == pmc___clock_prof.ps_ev.pm_ev_code)
- cpu_stopprofclock();
+ ev = pmc->pm_event;
+
+ /* Check if event is registered. */
+ ps = pmc_soft_ev_acquire(ev);
+ KASSERT(ps != NULL,
+ ("[soft,%d] unregistered event %d", __LINE__, ev));
+ pmc_soft_ev_release(ps);
+ /* Module unload is protected by pmc SX lock. */
+ if (ps->ps_release != NULL)
+ ps->ps_release();
return (0);
}
diff --git a/sys/dev/ixgbe/LICENSE b/sys/dev/ixgbe/LICENSE
index 0d4f1db..d446282 100644
--- a/sys/dev/ixgbe/LICENSE
+++ b/sys/dev/ixgbe/LICENSE
@@ -1,6 +1,6 @@
/******************************************************************************
- Copyright (c) 2001-2011, Intel Corporation
+ Copyright (c) 2001-2013, Intel Corporation
All rights reserved.
Redistribution and use in source and binary forms, with or without
diff --git a/sys/dev/ixgbe/ixgbe.c b/sys/dev/ixgbe/ixgbe.c
index 0b77437..9977803 100644
--- a/sys/dev/ixgbe/ixgbe.c
+++ b/sys/dev/ixgbe/ixgbe.c
@@ -1,6 +1,6 @@
/******************************************************************************
- Copyright (c) 2001-2012, Intel Corporation
+ Copyright (c) 2001-2013, Intel Corporation
All rights reserved.
Redistribution and use in source and binary forms, with or without
@@ -47,7 +47,7 @@ int ixgbe_display_debug_stats = 0;
/*********************************************************************
* Driver version
*********************************************************************/
-char ixgbe_driver_version[] = "2.5.0";
+char ixgbe_driver_version[] = "2.5.7 - HEAD";
/*********************************************************************
* PCI Device ID Table
@@ -83,7 +83,7 @@ static ixgbe_vendor_info_t ixgbe_vendor_info_array[] =
{IXGBE_INTEL_VENDOR_ID, IXGBE_DEV_ID_82599_SFP_SF2, 0, 0, 0},
{IXGBE_INTEL_VENDOR_ID, IXGBE_DEV_ID_82599_SFP_FCOE, 0, 0, 0},
{IXGBE_INTEL_VENDOR_ID, IXGBE_DEV_ID_82599EN_SFP, 0, 0, 0},
- {IXGBE_INTEL_VENDOR_ID, IXGBE_DEV_ID_X540T1, 0, 0, 0},
+ {IXGBE_INTEL_VENDOR_ID, IXGBE_DEV_ID_82599_SFP_SF_QP, 0, 0, 0},
{IXGBE_INTEL_VENDOR_ID, IXGBE_DEV_ID_X540T, 0, 0, 0},
/* required last entry */
{0, 0, 0, 0, 0}
@@ -216,7 +216,6 @@ static device_method_t ixgbe_methods[] = {
DEVMETHOD(device_attach, ixgbe_attach),
DEVMETHOD(device_detach, ixgbe_detach),
DEVMETHOD(device_shutdown, ixgbe_shutdown),
-
DEVMETHOD_END
};
@@ -596,6 +595,9 @@ ixgbe_attach(device_t dev)
"PCIE, or x4 PCIE 2 slot is required.\n");
}
+ /* Set an initial default flow control value */
+ adapter->fc = ixgbe_fc_full;
+
/* let hardware know driver is loaded */
ctrl_ext = IXGBE_READ_REG(hw, IXGBE_CTRL_EXT);
ctrl_ext |= IXGBE_CTRL_EXT_DRV_LOAD;
@@ -652,7 +654,7 @@ ixgbe_detach(device_t dev)
for (int i = 0; i < adapter->num_queues; i++, que++, txr++) {
if (que->tq) {
-#ifdef IXGBE_LEGACY_TX
+#ifndef IXGBE_LEGACY_TX
taskqueue_drain(que->tq, &txr->txq_task);
#endif
taskqueue_drain(que->tq, &que->que_task);
@@ -1310,7 +1312,7 @@ ixgbe_init_locked(struct adapter *adapter)
tmp = IXGBE_LOW_DV(frame);
hw->fc.low_water[0] = IXGBE_BT2KB(tmp);
- adapter->fc = hw->fc.requested_mode = ixgbe_fc_full;
+ hw->fc.requested_mode = adapter->fc;
hw->fc.pause_time = IXGBE_FC_PAUSE;
hw->fc.send_xon = TRUE;
}
@@ -1680,7 +1682,7 @@ ixgbe_media_status(struct ifnet * ifp, struct ifmediareq * ifmr)
ifmr->ifm_active |= IFM_100_TX | IFM_FDX;
break;
case IXGBE_LINK_SPEED_1GB_FULL:
- ifmr->ifm_active |= adapter->optics | IFM_FDX;
+ ifmr->ifm_active |= IFM_1000_SX | IFM_FDX;
break;
case IXGBE_LINK_SPEED_10GB_FULL:
ifmr->ifm_active |= adapter->optics | IFM_FDX;
@@ -1932,18 +1934,6 @@ ixgbe_set_multi(struct adapter *adapter)
bzero(mta, sizeof(u8) * IXGBE_ETH_LENGTH_OF_ADDRESS *
MAX_NUM_MULTICAST_ADDRESSES);
- fctrl = IXGBE_READ_REG(&adapter->hw, IXGBE_FCTRL);
- fctrl |= (IXGBE_FCTRL_UPE | IXGBE_FCTRL_MPE);
- if (ifp->if_flags & IFF_PROMISC)
- fctrl |= (IXGBE_FCTRL_UPE | IXGBE_FCTRL_MPE);
- else if (ifp->if_flags & IFF_ALLMULTI) {
- fctrl |= IXGBE_FCTRL_MPE;
- fctrl &= ~IXGBE_FCTRL_UPE;
- } else
- fctrl &= ~(IXGBE_FCTRL_UPE | IXGBE_FCTRL_MPE);
-
- IXGBE_WRITE_REG(&adapter->hw, IXGBE_FCTRL, fctrl);
-
#if __FreeBSD_version < 800000
IF_ADDR_LOCK(ifp);
#else
@@ -1952,6 +1942,8 @@ ixgbe_set_multi(struct adapter *adapter)
TAILQ_FOREACH(ifma, &ifp->if_multiaddrs, ifma_link) {
if (ifma->ifma_addr->sa_family != AF_LINK)
continue;
+ if (mcnt == MAX_NUM_MULTICAST_ADDRESSES)
+ break;
bcopy(LLADDR((struct sockaddr_dl *) ifma->ifma_addr),
&mta[mcnt * IXGBE_ETH_LENGTH_OF_ADDRESS],
IXGBE_ETH_LENGTH_OF_ADDRESS);
@@ -1963,9 +1955,24 @@ ixgbe_set_multi(struct adapter *adapter)
if_maddr_runlock(ifp);
#endif
- update_ptr = mta;
- ixgbe_update_mc_addr_list(&adapter->hw,
- update_ptr, mcnt, ixgbe_mc_array_itr, TRUE);
+ fctrl = IXGBE_READ_REG(&adapter->hw, IXGBE_FCTRL);
+ fctrl |= (IXGBE_FCTRL_UPE | IXGBE_FCTRL_MPE);
+ if (ifp->if_flags & IFF_PROMISC)
+ fctrl |= (IXGBE_FCTRL_UPE | IXGBE_FCTRL_MPE);
+ else if (mcnt >= MAX_NUM_MULTICAST_ADDRESSES ||
+ ifp->if_flags & IFF_ALLMULTI) {
+ fctrl |= IXGBE_FCTRL_MPE;
+ fctrl &= ~IXGBE_FCTRL_UPE;
+ } else
+ fctrl &= ~(IXGBE_FCTRL_UPE | IXGBE_FCTRL_MPE);
+
+ IXGBE_WRITE_REG(&adapter->hw, IXGBE_FCTRL, fctrl);
+
+ if (mcnt < MAX_NUM_MULTICAST_ADDRESSES) {
+ update_ptr = mta;
+ ixgbe_update_mc_addr_list(&adapter->hw,
+ update_ptr, mcnt, ixgbe_mc_array_itr, TRUE);
+ }
return;
}
@@ -2172,7 +2179,7 @@ ixgbe_setup_optics(struct adapter *adapter)
{
struct ixgbe_hw *hw = &adapter->hw;
int layer;
-
+
layer = ixgbe_get_supported_physical_layer(hw);
if (layer & IXGBE_PHYSICAL_LAYER_10GBASE_T) {
@@ -2651,7 +2658,7 @@ ixgbe_config_link(struct adapter *adapter)
taskqueue_enqueue(adapter->tq, &adapter->mod_task);
} else {
if (hw->mac.ops.check_link)
- err = ixgbe_check_link(hw, &autoneg,
+ err = ixgbe_check_link(hw, &adapter->link_speed,
&adapter->link_up, FALSE);
if (err)
goto out;
@@ -2662,8 +2669,8 @@ ixgbe_config_link(struct adapter *adapter)
if (err)
goto out;
if (hw->mac.ops.setup_link)
- err = hw->mac.ops.setup_link(hw, autoneg,
- negotiate, adapter->link_up);
+ err = hw->mac.ops.setup_link(hw,
+ autoneg, adapter->link_up);
}
out:
return;
@@ -3713,6 +3720,8 @@ ixgbe_refresh_mbufs(struct rx_ring *rxr, int limit)
M_PKTHDR, rxr->mbuf_sz);
if (mp == NULL)
goto update;
+ if (adapter->max_frame_size <= (MCLBYTES - ETHER_ALIGN))
+ m_adj(mp, ETHER_ALIGN);
} else
mp = rxbuf->buf;
@@ -4408,7 +4417,6 @@ ixgbe_rxeof(struct ix_queue *que)
/* Make sure bad packets are discarded */
if (((staterr & IXGBE_RXDADV_ERR_FRAME_ERR_MASK) != 0) ||
(rxr->discard)) {
- ifp->if_ierrors++;
rxr->rx_discarded++;
if (eop)
rxr->discard = FALSE;
@@ -4734,14 +4742,25 @@ ixgbe_enable_intr(struct adapter *adapter)
/* Enable Fan Failure detection */
if (hw->device_id == IXGBE_DEV_ID_82598AT)
mask |= IXGBE_EIMS_GPI_SDP1;
- else {
- mask |= IXGBE_EIMS_ECC;
- mask |= IXGBE_EIMS_GPI_SDP0;
- mask |= IXGBE_EIMS_GPI_SDP1;
- mask |= IXGBE_EIMS_GPI_SDP2;
+
+ switch (adapter->hw.mac.type) {
+ case ixgbe_mac_82599EB:
+ mask |= IXGBE_EIMS_ECC;
+ mask |= IXGBE_EIMS_GPI_SDP0;
+ mask |= IXGBE_EIMS_GPI_SDP1;
+ mask |= IXGBE_EIMS_GPI_SDP2;
+#ifdef IXGBE_FDIR
+ mask |= IXGBE_EIMS_FLOW_DIR;
+#endif
+ break;
+ case ixgbe_mac_X540:
+ mask |= IXGBE_EIMS_ECC;
#ifdef IXGBE_FDIR
- mask |= IXGBE_EIMS_FLOW_DIR;
+ mask |= IXGBE_EIMS_FLOW_DIR;
#endif
+ /* falls through */
+ default:
+ break;
}
IXGBE_WRITE_REG(hw, IXGBE_EIMS, mask);
@@ -4969,7 +4988,7 @@ ixgbe_handle_msf(void *context, int pending)
if ((!autoneg) && (hw->mac.ops.get_link_capabilities))
hw->mac.ops.get_link_capabilities(hw, &autoneg, &negotiate);
if (hw->mac.ops.setup_link)
- hw->mac.ops.setup_link(hw, autoneg, negotiate, TRUE);
+ hw->mac.ops.setup_link(hw, autoneg, TRUE);
return;
}
@@ -5013,6 +5032,11 @@ ixgbe_update_stats_counters(struct adapter *adapter)
adapter->stats.errbc += IXGBE_READ_REG(hw, IXGBE_ERRBC);
adapter->stats.mspdc += IXGBE_READ_REG(hw, IXGBE_MSPDC);
+ /*
+ ** Note: these are for the 8 possible traffic classes,
+ ** which in current implementation is unused,
+ ** therefore only 0 should read real data.
+ */
for (int i = 0; i < 8; i++) {
u32 mp;
mp = IXGBE_READ_REG(hw, IXGBE_MPC(i));
@@ -5022,13 +5046,20 @@ ixgbe_update_stats_counters(struct adapter *adapter)
adapter->stats.mpc[i] += mp;
/* Running comprehensive total for stats display */
total_missed_rx += adapter->stats.mpc[i];
- if (hw->mac.type == ixgbe_mac_82598EB)
+ if (hw->mac.type == ixgbe_mac_82598EB) {
adapter->stats.rnbc[i] +=
IXGBE_READ_REG(hw, IXGBE_RNBC(i));
+ adapter->stats.qbtc[i] +=
+ IXGBE_READ_REG(hw, IXGBE_QBTC(i));
+ adapter->stats.qbrc[i] +=
+ IXGBE_READ_REG(hw, IXGBE_QBRC(i));
+ adapter->stats.pxonrxc[i] +=
+ IXGBE_READ_REG(hw, IXGBE_PXONRXC(i));
+ } else
+ adapter->stats.pxonrxc[i] +=
+ IXGBE_READ_REG(hw, IXGBE_PXONRXCNT(i));
adapter->stats.pxontxc[i] +=
IXGBE_READ_REG(hw, IXGBE_PXONTXC(i));
- adapter->stats.pxonrxc[i] +=
- IXGBE_READ_REG(hw, IXGBE_PXONRXC(i));
adapter->stats.pxofftxc[i] +=
IXGBE_READ_REG(hw, IXGBE_PXOFFTXC(i));
adapter->stats.pxoffrxc[i] +=
@@ -5039,12 +5070,6 @@ ixgbe_update_stats_counters(struct adapter *adapter)
for (int i = 0; i < 16; i++) {
adapter->stats.qprc[i] += IXGBE_READ_REG(hw, IXGBE_QPRC(i));
adapter->stats.qptc[i] += IXGBE_READ_REG(hw, IXGBE_QPTC(i));
- adapter->stats.qbrc[i] += IXGBE_READ_REG(hw, IXGBE_QBRC(i));
- adapter->stats.qbrc[i] +=
- ((u64)IXGBE_READ_REG(hw, IXGBE_QBRC(i)) << 32);
- adapter->stats.qbtc[i] += IXGBE_READ_REG(hw, IXGBE_QBTC(i));
- adapter->stats.qbtc[i] +=
- ((u64)IXGBE_READ_REG(hw, IXGBE_QBTC(i)) << 32);
adapter->stats.qprdc[i] += IXGBE_READ_REG(hw, IXGBE_QPRDC(i));
}
adapter->stats.mlfc += IXGBE_READ_REG(hw, IXGBE_MLFC);
@@ -5141,8 +5166,8 @@ ixgbe_update_stats_counters(struct adapter *adapter)
ifp->if_collisions = 0;
/* Rx Errors */
- ifp->if_ierrors = total_missed_rx + adapter->stats.crcerrs +
- adapter->stats.rlec;
+ ifp->if_iqdrops = total_missed_rx;
+ ifp->if_ierrors = adapter->stats.crcerrs + adapter->stats.rlec;
}
/** ixgbe_sysctl_tdh_handler - Handler function
@@ -5528,10 +5553,13 @@ ixgbe_set_flowcntl(SYSCTL_HANDLER_ARGS)
ixgbe_disable_rx_drop(adapter);
break;
case ixgbe_fc_none:
- default:
adapter->hw.fc.requested_mode = ixgbe_fc_none;
if (adapter->num_queues > 1)
ixgbe_enable_rx_drop(adapter);
+ break;
+ default:
+ adapter->fc = last;
+ return (EINVAL);
}
/* Don't autoneg if forcing a value */
adapter->hw.fc.disable_fc_autoneg = TRUE;
@@ -5560,7 +5588,7 @@ ixgbe_set_advertise(SYSCTL_HANDLER_ARGS)
last = adapter->advertise;
error = sysctl_handle_int(oidp, &adapter->advertise, 0, req);
- if ((error) || (adapter->advertise == -1))
+ if ((error) || (req->newptr == NULL))
return (error);
if (adapter->advertise == last) /* no change */
@@ -5568,11 +5596,11 @@ ixgbe_set_advertise(SYSCTL_HANDLER_ARGS)
if (!((hw->phy.media_type == ixgbe_media_type_copper) ||
(hw->phy.multispeed_fiber)))
- return (error);
+ return (EINVAL);
if ((adapter->advertise == 2) && (hw->mac.type != ixgbe_mac_X540)) {
device_printf(dev, "Set Advertise: 100Mb on X540 only\n");
- return (error);
+ return (EINVAL);
}
if (adapter->advertise == 1)
@@ -5582,11 +5610,13 @@ ixgbe_set_advertise(SYSCTL_HANDLER_ARGS)
else if (adapter->advertise == 3)
speed = IXGBE_LINK_SPEED_1GB_FULL |
IXGBE_LINK_SPEED_10GB_FULL;
- else /* bogus value */
- return (error);
+ else { /* bogus value */
+ adapter->advertise = last;
+ return (EINVAL);
+ }
hw->mac.autotry_restart = TRUE;
- hw->mac.ops.setup_link(hw, speed, TRUE, TRUE);
+ hw->mac.ops.setup_link(hw, speed, TRUE);
return (error);
}
diff --git a/sys/dev/ixgbe/ixgbe_82598.c b/sys/dev/ixgbe/ixgbe_82598.c
index 9d3164c..de3185a 100644
--- a/sys/dev/ixgbe/ixgbe_82598.c
+++ b/sys/dev/ixgbe/ixgbe_82598.c
@@ -1,6 +1,6 @@
/******************************************************************************
- Copyright (c) 2001-2012, Intel Corporation
+ Copyright (c) 2001-2013, Intel Corporation
All rights reserved.
Redistribution and use in source and binary forms, with or without
@@ -49,18 +49,17 @@ static s32 ixgbe_check_mac_link_82598(struct ixgbe_hw *hw,
bool link_up_wait_to_complete);
static s32 ixgbe_setup_mac_link_82598(struct ixgbe_hw *hw,
ixgbe_link_speed speed,
- bool autoneg,
bool autoneg_wait_to_complete);
static s32 ixgbe_setup_copper_link_82598(struct ixgbe_hw *hw,
ixgbe_link_speed speed,
- bool autoneg,
bool autoneg_wait_to_complete);
static s32 ixgbe_reset_hw_82598(struct ixgbe_hw *hw);
static s32 ixgbe_clear_vmdq_82598(struct ixgbe_hw *hw, u32 rar, u32 vmdq);
static s32 ixgbe_clear_vfta_82598(struct ixgbe_hw *hw);
static void ixgbe_set_rxpba_82598(struct ixgbe_hw *hw, int num_pb,
u32 headroom, int strategy);
-
+static s32 ixgbe_read_i2c_sff8472_82598(struct ixgbe_hw *hw, u8 byte_offset,
+ u8 *sff8472_data);
/**
* ixgbe_set_pcie_completion_timeout - set pci-e completion timeout
* @hw: pointer to the HW structure
@@ -155,6 +154,7 @@ s32 ixgbe_init_ops_82598(struct ixgbe_hw *hw)
/* SFP+ Module */
phy->ops.read_i2c_eeprom = &ixgbe_read_i2c_eeprom_82598;
+ phy->ops.read_i2c_sff8472 = &ixgbe_read_i2c_sff8472_82598;
/* Link */
mac->ops.check_link = &ixgbe_check_mac_link_82598;
@@ -712,15 +712,15 @@ out:
* ixgbe_setup_mac_link_82598 - Set MAC link speed
* @hw: pointer to hardware structure
* @speed: new link speed
- * @autoneg: TRUE if autonegotiation enabled
* @autoneg_wait_to_complete: TRUE when waiting for completion is needed
*
* Set the link speed in the AUTOC register and restarts link.
**/
static s32 ixgbe_setup_mac_link_82598(struct ixgbe_hw *hw,
- ixgbe_link_speed speed, bool autoneg,
+ ixgbe_link_speed speed,
bool autoneg_wait_to_complete)
{
+ bool autoneg = FALSE;
s32 status = IXGBE_SUCCESS;
ixgbe_link_speed link_capabilities = IXGBE_LINK_SPEED_UNKNOWN;
u32 curr_autoc = IXGBE_READ_REG(hw, IXGBE_AUTOC);
@@ -766,14 +766,12 @@ static s32 ixgbe_setup_mac_link_82598(struct ixgbe_hw *hw,
* ixgbe_setup_copper_link_82598 - Set the PHY autoneg advertised field
* @hw: pointer to hardware structure
* @speed: new link speed
- * @autoneg: TRUE if autonegotiation enabled
* @autoneg_wait_to_complete: TRUE if waiting is needed to complete
*
* Sets the link speed in the AUTOC register in the MAC and restarts link.
**/
static s32 ixgbe_setup_copper_link_82598(struct ixgbe_hw *hw,
ixgbe_link_speed speed,
- bool autoneg,
bool autoneg_wait_to_complete)
{
s32 status;
@@ -781,7 +779,7 @@ static s32 ixgbe_setup_copper_link_82598(struct ixgbe_hw *hw,
DEBUGFUNC("ixgbe_setup_copper_link_82598");
/* Setup the PHY according to input speed */
- status = hw->phy.ops.setup_link_speed(hw, speed, autoneg,
+ status = hw->phy.ops.setup_link_speed(hw, speed,
autoneg_wait_to_complete);
/* Set up MAC */
ixgbe_start_mac_link_82598(hw, autoneg_wait_to_complete);
@@ -1102,15 +1100,16 @@ s32 ixgbe_write_analog_reg8_82598(struct ixgbe_hw *hw, u32 reg, u8 val)
}
/**
- * ixgbe_read_i2c_eeprom_82598 - Reads 8 bit word over I2C interface.
+ * ixgbe_read_i2c_phy_82598 - Reads 8 bit word over I2C interface.
* @hw: pointer to hardware structure
- * @byte_offset: EEPROM byte offset to read
+ * @dev_addr: address to read from
+ * @byte_offset: byte offset to read from dev_addr
* @eeprom_data: value read
*
* Performs 8 byte read operation to SFP module's EEPROM over I2C interface.
**/
-s32 ixgbe_read_i2c_eeprom_82598(struct ixgbe_hw *hw, u8 byte_offset,
- u8 *eeprom_data)
+static s32 ixgbe_read_i2c_phy_82598(struct ixgbe_hw *hw, u8 dev_addr,
+ u8 byte_offset, u8 *eeprom_data)
{
s32 status = IXGBE_SUCCESS;
u16 sfp_addr = 0;
@@ -1118,7 +1117,7 @@ s32 ixgbe_read_i2c_eeprom_82598(struct ixgbe_hw *hw, u8 byte_offset,
u16 sfp_stat = 0;
u32 i;
- DEBUGFUNC("ixgbe_read_i2c_eeprom_82598");
+ DEBUGFUNC("ixgbe_read_i2c_phy_82598");
if (hw->phy.type == ixgbe_phy_nl) {
/*
@@ -1126,7 +1125,7 @@ s32 ixgbe_read_i2c_eeprom_82598(struct ixgbe_hw *hw, u8 byte_offset,
* 0xC30D. These registers are used to talk to the SFP+
* module's EEPROM through the SDA/SCL (I2C) interface.
*/
- sfp_addr = (IXGBE_I2C_EEPROM_DEV_ADDR << 8) + byte_offset;
+ sfp_addr = (dev_addr << 8) + byte_offset;
sfp_addr = (sfp_addr | IXGBE_I2C_EEPROM_READ_MASK);
hw->phy.ops.write_reg(hw,
IXGBE_MDIO_PMA_PMD_SDA_SCL_ADDR,
@@ -1158,7 +1157,6 @@ s32 ixgbe_read_i2c_eeprom_82598(struct ixgbe_hw *hw, u8 byte_offset,
*eeprom_data = (u8)(sfp_data >> 8);
} else {
status = IXGBE_ERR_PHY;
- goto out;
}
out:
@@ -1166,6 +1164,36 @@ out:
}
/**
+ * ixgbe_read_i2c_eeprom_82598 - Reads 8 bit word over I2C interface.
+ * @hw: pointer to hardware structure
+ * @byte_offset: EEPROM byte offset to read
+ * @eeprom_data: value read
+ *
+ * Performs 8 byte read operation to SFP module's EEPROM over I2C interface.
+ **/
+s32 ixgbe_read_i2c_eeprom_82598(struct ixgbe_hw *hw, u8 byte_offset,
+ u8 *eeprom_data)
+{
+ return ixgbe_read_i2c_phy_82598(hw, IXGBE_I2C_EEPROM_DEV_ADDR,
+ byte_offset, eeprom_data);
+}
+
+/**
+ * ixgbe_read_i2c_sff8472_82598 - Reads 8 bit word over I2C interface.
+ * @hw: pointer to hardware structure
+ * @byte_offset: byte offset at address 0xA2
+ * @eeprom_data: value read
+ *
+ * Performs 8 byte read operation to SFP module's SFF-8472 data over I2C
+ **/
+static s32 ixgbe_read_i2c_sff8472_82598(struct ixgbe_hw *hw, u8 byte_offset,
+ u8 *sff8472_data)
+{
+ return ixgbe_read_i2c_phy_82598(hw, IXGBE_I2C_EEPROM_DEV_ADDR2,
+ byte_offset, sff8472_data);
+}
+
+/**
* ixgbe_get_supported_physical_layer_82598 - Returns physical layer type
* @hw: pointer to hardware structure
*
diff --git a/sys/dev/ixgbe/ixgbe_82599.c b/sys/dev/ixgbe/ixgbe_82599.c
index 083f7e1..592440b 100644
--- a/sys/dev/ixgbe/ixgbe_82599.c
+++ b/sys/dev/ixgbe/ixgbe_82599.c
@@ -1,6 +1,6 @@
/******************************************************************************
- Copyright (c) 2001-2012, Intel Corporation
+ Copyright (c) 2001-2013, Intel Corporation
All rights reserved.
Redistribution and use in source and binary forms, with or without
@@ -40,7 +40,6 @@
static s32 ixgbe_setup_copper_link_82599(struct ixgbe_hw *hw,
ixgbe_link_speed speed,
- bool autoneg,
bool autoneg_wait_to_complete);
static s32 ixgbe_verify_fw_version_82599(struct ixgbe_hw *hw);
static s32 ixgbe_read_eeprom_82599(struct ixgbe_hw *hw,
@@ -48,14 +47,37 @@ static s32 ixgbe_read_eeprom_82599(struct ixgbe_hw *hw,
static s32 ixgbe_read_eeprom_buffer_82599(struct ixgbe_hw *hw, u16 offset,
u16 words, u16 *data);
+static bool ixgbe_mng_enabled(struct ixgbe_hw *hw)
+{
+ u32 fwsm, manc, factps;
+
+ fwsm = IXGBE_READ_REG(hw, IXGBE_FWSM);
+ if ((fwsm & IXGBE_FWSM_MODE_MASK) != IXGBE_FWSM_FW_MODE_PT)
+ return FALSE;
+
+ manc = IXGBE_READ_REG(hw, IXGBE_MANC);
+ if (!(manc & IXGBE_MANC_RCV_TCO_EN))
+ return FALSE;
+
+ factps = IXGBE_READ_REG(hw, IXGBE_FACTPS);
+ if (factps & IXGBE_FACTPS_MNGCG)
+ return FALSE;
+
+ return TRUE;
+}
+
void ixgbe_init_mac_link_ops_82599(struct ixgbe_hw *hw)
{
struct ixgbe_mac_info *mac = &hw->mac;
DEBUGFUNC("ixgbe_init_mac_link_ops_82599");
- /* enable the laser control functions for SFP+ fiber */
- if (mac->ops.get_media_type(hw) == ixgbe_media_type_fiber) {
+ /*
+ * enable the laser control functions for SFP+ fiber
+ * and MNG not enabled
+ */
+ if ((mac->ops.get_media_type(hw) == ixgbe_media_type_fiber) &&
+ !(ixgbe_mng_enabled(hw))) {
mac->ops.disable_tx_laser =
&ixgbe_disable_tx_laser_multispeed_fiber;
mac->ops.enable_tx_laser =
@@ -135,9 +157,8 @@ init_phy_ops_out:
s32 ixgbe_setup_sfp_modules_82599(struct ixgbe_hw *hw)
{
s32 ret_val = IXGBE_SUCCESS;
- u32 reg_anlp1 = 0;
- u32 i = 0;
u16 list_offset, data_offset, data_value;
+ bool got_lock = FALSE;
DEBUGFUNC("ixgbe_setup_sfp_modules_82599");
@@ -171,28 +192,39 @@ s32 ixgbe_setup_sfp_modules_82599(struct ixgbe_hw *hw)
/* Delay obtaining semaphore again to allow FW access */
msec_delay(hw->eeprom.semaphore_delay);
- /* Now restart DSP by setting Restart_AN and clearing LMS */
- IXGBE_WRITE_REG(hw, IXGBE_AUTOC, ((IXGBE_READ_REG(hw,
- IXGBE_AUTOC) & ~IXGBE_AUTOC_LMS_MASK) |
- IXGBE_AUTOC_AN_RESTART));
-
- /* Wait for AN to leave state 0 */
- for (i = 0; i < 10; i++) {
- msec_delay(4);
- reg_anlp1 = IXGBE_READ_REG(hw, IXGBE_ANLP1);
- if (reg_anlp1 & IXGBE_ANLP1_AN_STATE_MASK)
- break;
+ /* Need SW/FW semaphore around AUTOC writes if LESM on,
+ * likewise reset_pipeline requires lock as it also writes
+ * AUTOC.
+ */
+ if (ixgbe_verify_lesm_fw_enabled_82599(hw)) {
+ ret_val = hw->mac.ops.acquire_swfw_sync(hw,
+ IXGBE_GSSR_MAC_CSR_SM);
+ if (ret_val != IXGBE_SUCCESS) {
+ ret_val = IXGBE_ERR_SWFW_SYNC;
+ goto setup_sfp_out;
+ }
+
+ got_lock = TRUE;
+ }
+
+ /* Restart DSP and set SFI mode */
+ IXGBE_WRITE_REG(hw, IXGBE_AUTOC, ((hw->mac.orig_autoc) |
+ IXGBE_AUTOC_LMS_10G_SERIAL));
+ hw->mac.cached_autoc = IXGBE_READ_REG(hw, IXGBE_AUTOC);
+ ret_val = ixgbe_reset_pipeline_82599(hw);
+
+ if (got_lock) {
+ hw->mac.ops.release_swfw_sync(hw,
+ IXGBE_GSSR_MAC_CSR_SM);
+ got_lock = FALSE;
}
- if (!(reg_anlp1 & IXGBE_ANLP1_AN_STATE_MASK)) {
+
+ if (ret_val) {
DEBUGOUT("sfp module setup not complete\n");
ret_val = IXGBE_ERR_SFP_SETUP_NOT_COMPLETE;
goto setup_sfp_out;
}
- /* Restart DSP by setting Restart_AN and return to SFI mode */
- IXGBE_WRITE_REG(hw, IXGBE_AUTOC, (IXGBE_READ_REG(hw,
- IXGBE_AUTOC) | IXGBE_AUTOC_LMS_10G_SERIAL |
- IXGBE_AUTOC_AN_RESTART));
}
setup_sfp_out:
@@ -216,7 +248,7 @@ s32 ixgbe_init_ops_82599(struct ixgbe_hw *hw)
DEBUGFUNC("ixgbe_init_ops_82599");
- ret_val = ixgbe_init_phy_ops_generic(hw);
+ ixgbe_init_phy_ops_generic(hw);
ret_val = ixgbe_init_ops_generic(hw);
/* PHY */
@@ -289,13 +321,13 @@ s32 ixgbe_init_ops_82599(struct ixgbe_hw *hw)
* ixgbe_get_link_capabilities_82599 - Determines link capabilities
* @hw: pointer to hardware structure
* @speed: pointer to link speed
- * @negotiation: TRUE when autoneg or autotry is enabled
+ * @autoneg: TRUE when autoneg or autotry is enabled
*
* Determines the link capabilities by reading the AUTOC register.
**/
s32 ixgbe_get_link_capabilities_82599(struct ixgbe_hw *hw,
ixgbe_link_speed *speed,
- bool *negotiation)
+ bool *autoneg)
{
s32 status = IXGBE_SUCCESS;
u32 autoc = 0;
@@ -309,7 +341,7 @@ s32 ixgbe_get_link_capabilities_82599(struct ixgbe_hw *hw,
hw->phy.sfp_type == ixgbe_sfp_type_1g_sx_core0 ||
hw->phy.sfp_type == ixgbe_sfp_type_1g_sx_core1) {
*speed = IXGBE_LINK_SPEED_1GB_FULL;
- *negotiation = TRUE;
+ *autoneg = TRUE;
goto out;
}
@@ -326,22 +358,22 @@ s32 ixgbe_get_link_capabilities_82599(struct ixgbe_hw *hw,
switch (autoc & IXGBE_AUTOC_LMS_MASK) {
case IXGBE_AUTOC_LMS_1G_LINK_NO_AN:
*speed = IXGBE_LINK_SPEED_1GB_FULL;
- *negotiation = FALSE;
+ *autoneg = FALSE;
break;
case IXGBE_AUTOC_LMS_10G_LINK_NO_AN:
*speed = IXGBE_LINK_SPEED_10GB_FULL;
- *negotiation = FALSE;
+ *autoneg = FALSE;
break;
case IXGBE_AUTOC_LMS_1G_AN:
*speed = IXGBE_LINK_SPEED_1GB_FULL;
- *negotiation = TRUE;
+ *autoneg = TRUE;
break;
case IXGBE_AUTOC_LMS_10G_SERIAL:
*speed = IXGBE_LINK_SPEED_10GB_FULL;
- *negotiation = FALSE;
+ *autoneg = FALSE;
break;
case IXGBE_AUTOC_LMS_KX4_KX_KR:
@@ -353,7 +385,7 @@ s32 ixgbe_get_link_capabilities_82599(struct ixgbe_hw *hw,
*speed |= IXGBE_LINK_SPEED_10GB_FULL;
if (autoc & IXGBE_AUTOC_KX_SUPP)
*speed |= IXGBE_LINK_SPEED_1GB_FULL;
- *negotiation = TRUE;
+ *autoneg = TRUE;
break;
case IXGBE_AUTOC_LMS_KX4_KX_KR_SGMII:
@@ -364,12 +396,12 @@ s32 ixgbe_get_link_capabilities_82599(struct ixgbe_hw *hw,
*speed |= IXGBE_LINK_SPEED_10GB_FULL;
if (autoc & IXGBE_AUTOC_KX_SUPP)
*speed |= IXGBE_LINK_SPEED_1GB_FULL;
- *negotiation = TRUE;
+ *autoneg = TRUE;
break;
case IXGBE_AUTOC_LMS_SGMII_1G_100M:
*speed = IXGBE_LINK_SPEED_1GB_FULL | IXGBE_LINK_SPEED_100_FULL;
- *negotiation = FALSE;
+ *autoneg = FALSE;
break;
default:
@@ -381,7 +413,7 @@ s32 ixgbe_get_link_capabilities_82599(struct ixgbe_hw *hw,
if (hw->phy.multispeed_fiber) {
*speed |= IXGBE_LINK_SPEED_10GB_FULL |
IXGBE_LINK_SPEED_1GB_FULL;
- *negotiation = TRUE;
+ *autoneg = TRUE;
}
out:
@@ -424,6 +456,7 @@ enum ixgbe_media_type ixgbe_get_media_type_82599(struct ixgbe_hw *hw)
case IXGBE_DEV_ID_82599_SFP_FCOE:
case IXGBE_DEV_ID_82599_SFP_EM:
case IXGBE_DEV_ID_82599_SFP_SF2:
+ case IXGBE_DEV_ID_82599_SFP_SF_QP:
case IXGBE_DEV_ID_82599EN_SFP:
media_type = ixgbe_media_type_fiber;
break;
@@ -433,6 +466,10 @@ enum ixgbe_media_type ixgbe_get_media_type_82599(struct ixgbe_hw *hw)
case IXGBE_DEV_ID_82599_T3_LOM:
media_type = ixgbe_media_type_copper;
break;
+ case IXGBE_DEV_ID_82599_BYPASS:
+ media_type = ixgbe_media_type_fiber_fixed;
+ hw->phy.multispeed_fiber = TRUE;
+ break;
default:
media_type = ixgbe_media_type_unknown;
break;
@@ -456,17 +493,32 @@ s32 ixgbe_start_mac_link_82599(struct ixgbe_hw *hw,
u32 links_reg;
u32 i;
s32 status = IXGBE_SUCCESS;
+ bool got_lock = FALSE;
DEBUGFUNC("ixgbe_start_mac_link_82599");
+ /* reset_pipeline requires us to hold this lock as it writes to
+ * AUTOC.
+ */
+ if (ixgbe_verify_lesm_fw_enabled_82599(hw)) {
+ status = hw->mac.ops.acquire_swfw_sync(hw,
+ IXGBE_GSSR_MAC_CSR_SM);
+ if (status != IXGBE_SUCCESS)
+ goto out;
+
+ got_lock = TRUE;
+ }
+
/* Restart link */
- autoc_reg = IXGBE_READ_REG(hw, IXGBE_AUTOC);
- autoc_reg |= IXGBE_AUTOC_AN_RESTART;
- IXGBE_WRITE_REG(hw, IXGBE_AUTOC, autoc_reg);
+ ixgbe_reset_pipeline_82599(hw);
+
+ if (got_lock)
+ hw->mac.ops.release_swfw_sync(hw, IXGBE_GSSR_MAC_CSR_SM);
/* Only poll for autoneg to complete if specified to do so */
if (autoneg_wait_to_complete) {
+ autoc_reg = IXGBE_READ_REG(hw, IXGBE_AUTOC);
if ((autoc_reg & IXGBE_AUTOC_LMS_MASK) ==
IXGBE_AUTOC_LMS_KX4_KX_KR ||
(autoc_reg & IXGBE_AUTOC_LMS_MASK) ==
@@ -490,6 +542,7 @@ s32 ixgbe_start_mac_link_82599(struct ixgbe_hw *hw,
/* Add delay to filter out noises during initial link setup */
msec_delay(50);
+out:
return status;
}
@@ -555,16 +608,84 @@ void ixgbe_flap_tx_laser_multispeed_fiber(struct ixgbe_hw *hw)
}
/**
+ * ixgbe_set_fiber_fixed_speed - Set module link speed for fixed fiber
+ * @hw: pointer to hardware structure
+ * @speed: link speed to set
+ *
+ * We set the module speed differently for fixed fiber. For other
+ * multi-speed devices we don't have an error value so here if we
+ * detect an error we just log it and exit.
+ */
+static void ixgbe_set_fiber_fixed_speed(struct ixgbe_hw *hw,
+ ixgbe_link_speed speed)
+{
+ s32 status;
+ u8 rs, eeprom_data;
+
+ switch (speed) {
+ case IXGBE_LINK_SPEED_10GB_FULL:
+ /* one bit mask same as setting on */
+ rs = IXGBE_SFF_SOFT_RS_SELECT_10G;
+ break;
+ case IXGBE_LINK_SPEED_1GB_FULL:
+ rs = IXGBE_SFF_SOFT_RS_SELECT_1G;
+ break;
+ default:
+ DEBUGOUT("Invalid fixed module speed\n");
+ return;
+ }
+
+ /* Set RS0 */
+ status = hw->phy.ops.read_i2c_byte(hw, IXGBE_SFF_SFF_8472_OSCB,
+ IXGBE_I2C_EEPROM_DEV_ADDR2,
+ &eeprom_data);
+ if (status) {
+ DEBUGOUT("Failed to read Rx Rate Select RS0\n");
+ goto out;
+ }
+
+ eeprom_data = (eeprom_data & ~IXGBE_SFF_SOFT_RS_SELECT_MASK) & rs;
+
+ status = hw->phy.ops.write_i2c_byte(hw, IXGBE_SFF_SFF_8472_OSCB,
+ IXGBE_I2C_EEPROM_DEV_ADDR2,
+ eeprom_data);
+ if (status) {
+ DEBUGOUT("Failed to write Rx Rate Select RS0\n");
+ goto out;
+ }
+
+ /* Set RS1 */
+ status = hw->phy.ops.read_i2c_byte(hw, IXGBE_SFF_SFF_8472_ESCB,
+ IXGBE_I2C_EEPROM_DEV_ADDR2,
+ &eeprom_data);
+ if (status) {
+ DEBUGOUT("Failed to read Rx Rate Select RS1\n");
+ goto out;
+ }
+
+ eeprom_data = (eeprom_data & ~IXGBE_SFF_SOFT_RS_SELECT_MASK) & rs;
+
+ status = hw->phy.ops.write_i2c_byte(hw, IXGBE_SFF_SFF_8472_ESCB,
+ IXGBE_I2C_EEPROM_DEV_ADDR2,
+ eeprom_data);
+ if (status) {
+ DEBUGOUT("Failed to write Rx Rate Select RS1\n");
+ goto out;
+ }
+out:
+ return;
+}
+
+/**
* ixgbe_setup_mac_link_multispeed_fiber - Set MAC link speed
* @hw: pointer to hardware structure
* @speed: new link speed
- * @autoneg: TRUE if autonegotiation enabled
* @autoneg_wait_to_complete: TRUE when waiting for completion is needed
*
* Set the link speed in the AUTOC register and restarts link.
**/
s32 ixgbe_setup_mac_link_multispeed_fiber(struct ixgbe_hw *hw,
- ixgbe_link_speed speed, bool autoneg,
+ ixgbe_link_speed speed,
bool autoneg_wait_to_complete)
{
s32 status = IXGBE_SUCCESS;
@@ -573,13 +694,12 @@ s32 ixgbe_setup_mac_link_multispeed_fiber(struct ixgbe_hw *hw,
u32 speedcnt = 0;
u32 esdp_reg = IXGBE_READ_REG(hw, IXGBE_ESDP);
u32 i = 0;
- bool link_up = FALSE;
- bool negotiation;
+ bool autoneg, link_up = FALSE;
DEBUGFUNC("ixgbe_setup_mac_link_multispeed_fiber");
/* Mask off requested but non-supported speeds */
- status = ixgbe_get_link_capabilities(hw, &link_speed, &negotiation);
+ status = ixgbe_get_link_capabilities(hw, &link_speed, &autoneg);
if (status != IXGBE_SUCCESS)
return status;
@@ -602,16 +722,20 @@ s32 ixgbe_setup_mac_link_multispeed_fiber(struct ixgbe_hw *hw,
goto out;
/* Set the module link speed */
- esdp_reg |= (IXGBE_ESDP_SDP5_DIR | IXGBE_ESDP_SDP5);
- IXGBE_WRITE_REG(hw, IXGBE_ESDP, esdp_reg);
- IXGBE_WRITE_FLUSH(hw);
+ if (hw->phy.media_type == ixgbe_media_type_fiber_fixed) {
+ ixgbe_set_fiber_fixed_speed(hw,
+ IXGBE_LINK_SPEED_10GB_FULL);
+ } else {
+ esdp_reg |= (IXGBE_ESDP_SDP5_DIR | IXGBE_ESDP_SDP5);
+ IXGBE_WRITE_REG(hw, IXGBE_ESDP, esdp_reg);
+ IXGBE_WRITE_FLUSH(hw);
+ }
/* Allow module to change analog characteristics (1G->10G) */
msec_delay(40);
status = ixgbe_setup_mac_link_82599(hw,
IXGBE_LINK_SPEED_10GB_FULL,
- autoneg,
autoneg_wait_to_complete);
if (status != IXGBE_SUCCESS)
return status;
@@ -653,17 +777,21 @@ s32 ixgbe_setup_mac_link_multispeed_fiber(struct ixgbe_hw *hw,
goto out;
/* Set the module link speed */
- esdp_reg &= ~IXGBE_ESDP_SDP5;
- esdp_reg |= IXGBE_ESDP_SDP5_DIR;
- IXGBE_WRITE_REG(hw, IXGBE_ESDP, esdp_reg);
- IXGBE_WRITE_FLUSH(hw);
+ if (hw->phy.media_type == ixgbe_media_type_fiber_fixed) {
+ ixgbe_set_fiber_fixed_speed(hw,
+ IXGBE_LINK_SPEED_1GB_FULL);
+ } else {
+ esdp_reg &= ~IXGBE_ESDP_SDP5;
+ esdp_reg |= IXGBE_ESDP_SDP5_DIR;
+ IXGBE_WRITE_REG(hw, IXGBE_ESDP, esdp_reg);
+ IXGBE_WRITE_FLUSH(hw);
+ }
/* Allow module to change analog characteristics (10G->1G) */
msec_delay(40);
status = ixgbe_setup_mac_link_82599(hw,
IXGBE_LINK_SPEED_1GB_FULL,
- autoneg,
autoneg_wait_to_complete);
if (status != IXGBE_SUCCESS)
return status;
@@ -690,7 +818,7 @@ s32 ixgbe_setup_mac_link_multispeed_fiber(struct ixgbe_hw *hw,
*/
if (speedcnt > 1)
status = ixgbe_setup_mac_link_multispeed_fiber(hw,
- highest_link_speed, autoneg, autoneg_wait_to_complete);
+ highest_link_speed, autoneg_wait_to_complete);
out:
/* Set autoneg_advertised value based on input link speed */
@@ -709,13 +837,12 @@ out:
* ixgbe_setup_mac_link_smartspeed - Set MAC link speed using SmartSpeed
* @hw: pointer to hardware structure
* @speed: new link speed
- * @autoneg: TRUE if autonegotiation enabled
* @autoneg_wait_to_complete: TRUE when waiting for completion is needed
*
* Implements the Intel SmartSpeed algorithm.
**/
s32 ixgbe_setup_mac_link_smartspeed(struct ixgbe_hw *hw,
- ixgbe_link_speed speed, bool autoneg,
+ ixgbe_link_speed speed,
bool autoneg_wait_to_complete)
{
s32 status = IXGBE_SUCCESS;
@@ -748,7 +875,7 @@ s32 ixgbe_setup_mac_link_smartspeed(struct ixgbe_hw *hw,
/* First, try to get link with full advertisement */
hw->phy.smart_speed_active = FALSE;
for (j = 0; j < IXGBE_SMARTSPEED_MAX_RETRIES; j++) {
- status = ixgbe_setup_mac_link_82599(hw, speed, autoneg,
+ status = ixgbe_setup_mac_link_82599(hw, speed,
autoneg_wait_to_complete);
if (status != IXGBE_SUCCESS)
goto out;
@@ -783,7 +910,7 @@ s32 ixgbe_setup_mac_link_smartspeed(struct ixgbe_hw *hw,
/* Turn SmartSpeed on to disable KR support */
hw->phy.smart_speed_active = TRUE;
- status = ixgbe_setup_mac_link_82599(hw, speed, autoneg,
+ status = ixgbe_setup_mac_link_82599(hw, speed,
autoneg_wait_to_complete);
if (status != IXGBE_SUCCESS)
goto out;
@@ -808,7 +935,7 @@ s32 ixgbe_setup_mac_link_smartspeed(struct ixgbe_hw *hw,
/* We didn't get link. Turn SmartSpeed back off. */
hw->phy.smart_speed_active = FALSE;
- status = ixgbe_setup_mac_link_82599(hw, speed, autoneg,
+ status = ixgbe_setup_mac_link_82599(hw, speed,
autoneg_wait_to_complete);
out:
@@ -822,32 +949,30 @@ out:
* ixgbe_setup_mac_link_82599 - Set MAC link speed
* @hw: pointer to hardware structure
* @speed: new link speed
- * @autoneg: TRUE if autonegotiation enabled
* @autoneg_wait_to_complete: TRUE when waiting for completion is needed
*
* Set the link speed in the AUTOC register and restarts link.
**/
s32 ixgbe_setup_mac_link_82599(struct ixgbe_hw *hw,
- ixgbe_link_speed speed, bool autoneg,
+ ixgbe_link_speed speed,
bool autoneg_wait_to_complete)
{
+ bool autoneg = FALSE;
s32 status = IXGBE_SUCCESS;
- u32 autoc = IXGBE_READ_REG(hw, IXGBE_AUTOC);
+ u32 autoc, pma_pmd_1g, link_mode, start_autoc;
u32 autoc2 = IXGBE_READ_REG(hw, IXGBE_AUTOC2);
- u32 start_autoc = autoc;
u32 orig_autoc = 0;
- u32 link_mode = autoc & IXGBE_AUTOC_LMS_MASK;
- u32 pma_pmd_1g = autoc & IXGBE_AUTOC_1G_PMA_PMD_MASK;
u32 pma_pmd_10g_serial = autoc2 & IXGBE_AUTOC2_10G_SERIAL_PMA_PMD_MASK;
u32 links_reg;
u32 i;
ixgbe_link_speed link_capabilities = IXGBE_LINK_SPEED_UNKNOWN;
+ bool got_lock = FALSE;
DEBUGFUNC("ixgbe_setup_mac_link_82599");
/* Check to see if speed passed in is supported. */
status = ixgbe_get_link_capabilities(hw, &link_capabilities, &autoneg);
- if (status != IXGBE_SUCCESS)
+ if (status)
goto out;
speed &= link_capabilities;
@@ -859,9 +984,14 @@ s32 ixgbe_setup_mac_link_82599(struct ixgbe_hw *hw,
/* Use stored value (EEPROM defaults) of AUTOC to find KR/KX4 support*/
if (hw->mac.orig_link_settings_stored)
- orig_autoc = hw->mac.orig_autoc;
+ autoc = hw->mac.orig_autoc;
else
- orig_autoc = autoc;
+ autoc = IXGBE_READ_REG(hw, IXGBE_AUTOC);
+
+ orig_autoc = autoc;
+ start_autoc = hw->mac.cached_autoc;
+ link_mode = autoc & IXGBE_AUTOC_LMS_MASK;
+ pma_pmd_1g = autoc & IXGBE_AUTOC_1G_PMA_PMD_MASK;
if (link_mode == IXGBE_AUTOC_LMS_KX4_KX_KR ||
link_mode == IXGBE_AUTOC_LMS_KX4_KX_KR_1G_AN ||
@@ -900,9 +1030,31 @@ s32 ixgbe_setup_mac_link_82599(struct ixgbe_hw *hw,
}
if (autoc != start_autoc) {
+ /* Need SW/FW semaphore around AUTOC writes if LESM is on,
+ * likewise reset_pipeline requires us to hold this lock as
+ * it also writes to AUTOC.
+ */
+ if (ixgbe_verify_lesm_fw_enabled_82599(hw)) {
+ status = hw->mac.ops.acquire_swfw_sync(hw,
+ IXGBE_GSSR_MAC_CSR_SM);
+ if (status != IXGBE_SUCCESS) {
+ status = IXGBE_ERR_SWFW_SYNC;
+ goto out;
+ }
+
+ got_lock = TRUE;
+ }
+
/* Restart link */
- autoc |= IXGBE_AUTOC_AN_RESTART;
IXGBE_WRITE_REG(hw, IXGBE_AUTOC, autoc);
+ hw->mac.cached_autoc = autoc;
+ ixgbe_reset_pipeline_82599(hw);
+
+ if (got_lock) {
+ hw->mac.ops.release_swfw_sync(hw,
+ IXGBE_GSSR_MAC_CSR_SM);
+ got_lock = FALSE;
+ }
/* Only poll for autoneg to complete if specified to do so */
if (autoneg_wait_to_complete) {
@@ -937,14 +1089,12 @@ out:
* ixgbe_setup_copper_link_82599 - Set the PHY autoneg advertised field
* @hw: pointer to hardware structure
* @speed: new link speed
- * @autoneg: TRUE if autonegotiation enabled
* @autoneg_wait_to_complete: TRUE if waiting is needed to complete
*
* Restarts link on PHY and MAC based on settings passed in.
**/
static s32 ixgbe_setup_copper_link_82599(struct ixgbe_hw *hw,
ixgbe_link_speed speed,
- bool autoneg,
bool autoneg_wait_to_complete)
{
s32 status;
@@ -952,7 +1102,7 @@ static s32 ixgbe_setup_copper_link_82599(struct ixgbe_hw *hw,
DEBUGFUNC("ixgbe_setup_copper_link_82599");
/* Setup the PHY according to input speed */
- status = hw->phy.ops.setup_link_speed(hw, speed, autoneg,
+ status = hw->phy.ops.setup_link_speed(hw, speed,
autoneg_wait_to_complete);
/* Set up MAC */
ixgbe_start_mac_link_82599(hw, autoneg_wait_to_complete);
@@ -1056,14 +1206,45 @@ mac_reset_top:
*/
autoc = IXGBE_READ_REG(hw, IXGBE_AUTOC);
autoc2 = IXGBE_READ_REG(hw, IXGBE_AUTOC2);
+
+ /* Enable link if disabled in NVM */
+ if (autoc2 & IXGBE_AUTOC2_LINK_DISABLE_MASK) {
+ autoc2 &= ~IXGBE_AUTOC2_LINK_DISABLE_MASK;
+ IXGBE_WRITE_REG(hw, IXGBE_AUTOC2, autoc2);
+ IXGBE_WRITE_FLUSH(hw);
+ }
+
if (hw->mac.orig_link_settings_stored == FALSE) {
hw->mac.orig_autoc = autoc;
hw->mac.orig_autoc2 = autoc2;
+ hw->mac.cached_autoc = autoc;
hw->mac.orig_link_settings_stored = TRUE;
} else {
- if (autoc != hw->mac.orig_autoc)
- IXGBE_WRITE_REG(hw, IXGBE_AUTOC, (hw->mac.orig_autoc |
- IXGBE_AUTOC_AN_RESTART));
+ if (autoc != hw->mac.orig_autoc) {
+ /* Need SW/FW semaphore around AUTOC writes if LESM is
+ * on, likewise reset_pipeline requires us to hold
+ * this lock as it also writes to AUTOC.
+ */
+ bool got_lock = FALSE;
+ if (ixgbe_verify_lesm_fw_enabled_82599(hw)) {
+ status = hw->mac.ops.acquire_swfw_sync(hw,
+ IXGBE_GSSR_MAC_CSR_SM);
+ if (status != IXGBE_SUCCESS) {
+ status = IXGBE_ERR_SWFW_SYNC;
+ goto reset_hw_out;
+ }
+
+ got_lock = TRUE;
+ }
+
+ IXGBE_WRITE_REG(hw, IXGBE_AUTOC, hw->mac.orig_autoc);
+ hw->mac.cached_autoc = hw->mac.orig_autoc;
+ ixgbe_reset_pipeline_82599(hw);
+
+ if (got_lock)
+ hw->mac.ops.release_swfw_sync(hw,
+ IXGBE_GSSR_MAC_CSR_SM);
+ }
if ((autoc2 & IXGBE_AUTOC2_UPPER_MASK) !=
(hw->mac.orig_autoc2 & IXGBE_AUTOC2_UPPER_MASK)) {
@@ -1168,7 +1349,7 @@ s32 ixgbe_reinit_fdir_tables_82599(struct ixgbe_hw *hw)
if (IXGBE_READ_REG(hw, IXGBE_FDIRCTRL) &
IXGBE_FDIRCTRL_INIT_DONE)
break;
- usec_delay(10);
+ msec_delay(1);
}
if (i >= IXGBE_FDIR_INIT_DONE_POLL) {
DEBUGOUT("Flow Director Signature poll time exceeded!\n");
@@ -2094,7 +2275,7 @@ s32 ixgbe_enable_rx_dma_82599(struct ixgbe_hw *hw, u32 regval)
* Returns IXGBE_ERR_EEPROM_VERSION if the FW is not present or
* if the FW version is not supported.
**/
-static s32 ixgbe_verify_fw_version_82599(struct ixgbe_hw *hw)
+s32 ixgbe_verify_fw_version_82599(struct ixgbe_hw *hw)
{
s32 status = IXGBE_ERR_EEPROM_VERSION;
u16 fw_offset, fw_ptp_cfg_offset;
@@ -2243,4 +2424,55 @@ static s32 ixgbe_read_eeprom_82599(struct ixgbe_hw *hw,
return ret_val;
}
+/**
+ * ixgbe_reset_pipeline_82599 - perform pipeline reset
+ *
+ * @hw: pointer to hardware structure
+ *
+ * Reset pipeline by asserting Restart_AN together with LMS change to ensure
+ * full pipeline reset
+ **/
+s32 ixgbe_reset_pipeline_82599(struct ixgbe_hw *hw)
+{
+ s32 ret_val;
+ u32 anlp1_reg = 0;
+ u32 i, autoc_reg, autoc2_reg;
+
+ /* Enable link if disabled in NVM */
+ autoc2_reg = IXGBE_READ_REG(hw, IXGBE_AUTOC2);
+ if (autoc2_reg & IXGBE_AUTOC2_LINK_DISABLE_MASK) {
+ autoc2_reg &= ~IXGBE_AUTOC2_LINK_DISABLE_MASK;
+ IXGBE_WRITE_REG(hw, IXGBE_AUTOC2, autoc2_reg);
+ IXGBE_WRITE_FLUSH(hw);
+ }
+
+ autoc_reg = hw->mac.cached_autoc;
+ autoc_reg |= IXGBE_AUTOC_AN_RESTART;
+ /* Write AUTOC register with toggled LMS[2] bit and Restart_AN */
+ IXGBE_WRITE_REG(hw, IXGBE_AUTOC, autoc_reg ^ IXGBE_AUTOC_LMS_1G_AN);
+ /* Wait for AN to leave state 0 */
+ for (i = 0; i < 10; i++) {
+ msec_delay(4);
+ anlp1_reg = IXGBE_READ_REG(hw, IXGBE_ANLP1);
+ if (anlp1_reg & IXGBE_ANLP1_AN_STATE_MASK)
+ break;
+ }
+
+ if (!(anlp1_reg & IXGBE_ANLP1_AN_STATE_MASK)) {
+ DEBUGOUT("auto negotiation not completed\n");
+ ret_val = IXGBE_ERR_RESET_FAILED;
+ goto reset_pipeline_out;
+ }
+
+ ret_val = IXGBE_SUCCESS;
+
+reset_pipeline_out:
+ /* Write AUTOC register with original LMS field and Restart_AN */
+ IXGBE_WRITE_REG(hw, IXGBE_AUTOC, autoc_reg);
+ IXGBE_WRITE_FLUSH(hw);
+
+ return ret_val;
+}
+
+
diff --git a/sys/dev/ixgbe/ixgbe_82599.h b/sys/dev/ixgbe/ixgbe_82599.h
index dca39b7..a77d153 100644
--- a/sys/dev/ixgbe/ixgbe_82599.h
+++ b/sys/dev/ixgbe/ixgbe_82599.h
@@ -1,6 +1,6 @@
/******************************************************************************
- Copyright (c) 2001-2012, Intel Corporation
+ Copyright (c) 2001-2013, Intel Corporation
All rights reserved.
Redistribution and use in source and binary forms, with or without
@@ -42,15 +42,15 @@ void ixgbe_disable_tx_laser_multispeed_fiber(struct ixgbe_hw *hw);
void ixgbe_enable_tx_laser_multispeed_fiber(struct ixgbe_hw *hw);
void ixgbe_flap_tx_laser_multispeed_fiber(struct ixgbe_hw *hw);
s32 ixgbe_setup_mac_link_multispeed_fiber(struct ixgbe_hw *hw,
- ixgbe_link_speed speed, bool autoneg,
+ ixgbe_link_speed speed,
bool autoneg_wait_to_complete);
s32 ixgbe_setup_mac_link_smartspeed(struct ixgbe_hw *hw,
- ixgbe_link_speed speed, bool autoneg,
+ ixgbe_link_speed speed,
bool autoneg_wait_to_complete);
s32 ixgbe_start_mac_link_82599(struct ixgbe_hw *hw,
bool autoneg_wait_to_complete);
s32 ixgbe_setup_mac_link_82599(struct ixgbe_hw *hw, ixgbe_link_speed speed,
- bool autoneg, bool autoneg_wait_to_complete);
+ bool autoneg_wait_to_complete);
s32 ixgbe_setup_sfp_modules_82599(struct ixgbe_hw *hw);
void ixgbe_init_mac_link_ops_82599(struct ixgbe_hw *hw);
s32 ixgbe_reset_hw_82599(struct ixgbe_hw *hw);
@@ -61,5 +61,4 @@ s32 ixgbe_identify_phy_82599(struct ixgbe_hw *hw);
s32 ixgbe_init_phy_ops_82599(struct ixgbe_hw *hw);
u32 ixgbe_get_supported_physical_layer_82599(struct ixgbe_hw *hw);
s32 ixgbe_enable_rx_dma_82599(struct ixgbe_hw *hw, u32 regval);
-bool ixgbe_verify_lesm_fw_enabled_82599(struct ixgbe_hw *hw);
#endif /* _IXGBE_82599_H_ */
diff --git a/sys/dev/ixgbe/ixgbe_api.c b/sys/dev/ixgbe/ixgbe_api.c
index faee9d3..61876fb 100644
--- a/sys/dev/ixgbe/ixgbe_api.c
+++ b/sys/dev/ixgbe/ixgbe_api.c
@@ -1,6 +1,6 @@
/******************************************************************************
- Copyright (c) 2001-2012, Intel Corporation
+ Copyright (c) 2001-2013, Intel Corporation
All rights reserved.
Redistribution and use in source and binary forms, with or without
@@ -93,53 +93,53 @@ s32 ixgbe_set_mac_type(struct ixgbe_hw *hw)
DEBUGFUNC("ixgbe_set_mac_type\n");
- if (hw->vendor_id == IXGBE_INTEL_VENDOR_ID) {
- switch (hw->device_id) {
- case IXGBE_DEV_ID_82598:
- case IXGBE_DEV_ID_82598_BX:
- case IXGBE_DEV_ID_82598AF_SINGLE_PORT:
- case IXGBE_DEV_ID_82598AF_DUAL_PORT:
- case IXGBE_DEV_ID_82598AT:
- case IXGBE_DEV_ID_82598AT2:
- case IXGBE_DEV_ID_82598EB_CX4:
- case IXGBE_DEV_ID_82598_CX4_DUAL_PORT:
- case IXGBE_DEV_ID_82598_DA_DUAL_PORT:
- case IXGBE_DEV_ID_82598_SR_DUAL_PORT_EM:
- case IXGBE_DEV_ID_82598EB_XF_LR:
- case IXGBE_DEV_ID_82598EB_SFP_LOM:
- hw->mac.type = ixgbe_mac_82598EB;
- break;
- case IXGBE_DEV_ID_82599_KX4:
- case IXGBE_DEV_ID_82599_KX4_MEZZ:
- case IXGBE_DEV_ID_82599_XAUI_LOM:
- case IXGBE_DEV_ID_82599_COMBO_BACKPLANE:
- case IXGBE_DEV_ID_82599_KR:
- case IXGBE_DEV_ID_82599_SFP:
- case IXGBE_DEV_ID_82599_BACKPLANE_FCOE:
- case IXGBE_DEV_ID_82599_SFP_FCOE:
- case IXGBE_DEV_ID_82599_SFP_EM:
- case IXGBE_DEV_ID_82599_SFP_SF2:
- case IXGBE_DEV_ID_82599EN_SFP:
- case IXGBE_DEV_ID_82599_CX4:
- case IXGBE_DEV_ID_82599_T3_LOM:
- hw->mac.type = ixgbe_mac_82599EB;
- break;
- case IXGBE_DEV_ID_82599_VF:
- hw->mac.type = ixgbe_mac_82599_vf;
- break;
- case IXGBE_DEV_ID_X540_VF:
- hw->mac.type = ixgbe_mac_X540_vf;
- break;
- case IXGBE_DEV_ID_X540T:
- case IXGBE_DEV_ID_X540T1:
- hw->mac.type = ixgbe_mac_X540;
- break;
- default:
- ret_val = IXGBE_ERR_DEVICE_NOT_SUPPORTED;
- break;
- }
- } else {
+ switch (hw->device_id) {
+ case IXGBE_DEV_ID_82598:
+ case IXGBE_DEV_ID_82598_BX:
+ case IXGBE_DEV_ID_82598AF_SINGLE_PORT:
+ case IXGBE_DEV_ID_82598AF_DUAL_PORT:
+ case IXGBE_DEV_ID_82598AT:
+ case IXGBE_DEV_ID_82598AT2:
+ case IXGBE_DEV_ID_82598EB_CX4:
+ case IXGBE_DEV_ID_82598_CX4_DUAL_PORT:
+ case IXGBE_DEV_ID_82598_DA_DUAL_PORT:
+ case IXGBE_DEV_ID_82598_SR_DUAL_PORT_EM:
+ case IXGBE_DEV_ID_82598EB_XF_LR:
+ case IXGBE_DEV_ID_82598EB_SFP_LOM:
+ hw->mac.type = ixgbe_mac_82598EB;
+ break;
+ case IXGBE_DEV_ID_82599_KX4:
+ case IXGBE_DEV_ID_82599_KX4_MEZZ:
+ case IXGBE_DEV_ID_82599_XAUI_LOM:
+ case IXGBE_DEV_ID_82599_COMBO_BACKPLANE:
+ case IXGBE_DEV_ID_82599_KR:
+ case IXGBE_DEV_ID_82599_SFP:
+ case IXGBE_DEV_ID_82599_BACKPLANE_FCOE:
+ case IXGBE_DEV_ID_82599_SFP_FCOE:
+ case IXGBE_DEV_ID_82599_SFP_EM:
+ case IXGBE_DEV_ID_82599_SFP_SF2:
+ case IXGBE_DEV_ID_82599_SFP_SF_QP:
+ case IXGBE_DEV_ID_82599EN_SFP:
+ case IXGBE_DEV_ID_82599_CX4:
+ case IXGBE_DEV_ID_82599_BYPASS:
+ case IXGBE_DEV_ID_82599_T3_LOM:
+ hw->mac.type = ixgbe_mac_82599EB;
+ break;
+ case IXGBE_DEV_ID_82599_VF:
+ case IXGBE_DEV_ID_82599_VF_HV:
+ hw->mac.type = ixgbe_mac_82599_vf;
+ break;
+ case IXGBE_DEV_ID_X540_VF:
+ case IXGBE_DEV_ID_X540_VF_HV:
+ hw->mac.type = ixgbe_mac_X540_vf;
+ break;
+ case IXGBE_DEV_ID_X540T:
+ case IXGBE_DEV_ID_X540_BYPASS:
+ hw->mac.type = ixgbe_mac_X540;
+ break;
+ default:
ret_val = IXGBE_ERR_DEVICE_NOT_SUPPORTED;
+ break;
}
DEBUGOUT2("ixgbe_set_mac_type found mac: %d, returns: %d\n",
@@ -507,16 +507,14 @@ s32 ixgbe_check_phy_link(struct ixgbe_hw *hw, ixgbe_link_speed *speed,
* ixgbe_setup_phy_link_speed - Set auto advertise
* @hw: pointer to hardware structure
* @speed: new link speed
- * @autoneg: TRUE if autonegotiation enabled
*
* Sets the auto advertised capabilities
**/
s32 ixgbe_setup_phy_link_speed(struct ixgbe_hw *hw, ixgbe_link_speed speed,
- bool autoneg,
bool autoneg_wait_to_complete)
{
return ixgbe_call_func(hw, hw->phy.ops.setup_link_speed, (hw, speed,
- autoneg, autoneg_wait_to_complete),
+ autoneg_wait_to_complete),
IXGBE_NOT_IMPLEMENTED);
}
@@ -576,17 +574,15 @@ void ixgbe_flap_tx_laser(struct ixgbe_hw *hw)
* ixgbe_setup_link - Set link speed
* @hw: pointer to hardware structure
* @speed: new link speed
- * @autoneg: TRUE if autonegotiation enabled
*
* Configures link settings. Restarts the link.
* Performs autonegotiation if needed.
**/
s32 ixgbe_setup_link(struct ixgbe_hw *hw, ixgbe_link_speed speed,
- bool autoneg,
bool autoneg_wait_to_complete)
{
return ixgbe_call_func(hw, hw->mac.ops.setup_link, (hw, speed,
- autoneg, autoneg_wait_to_complete),
+ autoneg_wait_to_complete),
IXGBE_NOT_IMPLEMENTED);
}
diff --git a/sys/dev/ixgbe/ixgbe_api.h b/sys/dev/ixgbe/ixgbe_api.h
index 3a9e0cf..507792f 100644
--- a/sys/dev/ixgbe/ixgbe_api.h
+++ b/sys/dev/ixgbe/ixgbe_api.h
@@ -1,6 +1,6 @@
/******************************************************************************
- Copyright (c) 2001-2012, Intel Corporation
+ Copyright (c) 2001-2013, Intel Corporation
All rights reserved.
Redistribution and use in source and binary forms, with or without
@@ -72,13 +72,12 @@ s32 ixgbe_check_phy_link(struct ixgbe_hw *hw,
bool *link_up);
s32 ixgbe_setup_phy_link_speed(struct ixgbe_hw *hw,
ixgbe_link_speed speed,
- bool autoneg,
bool autoneg_wait_to_complete);
void ixgbe_disable_tx_laser(struct ixgbe_hw *hw);
void ixgbe_enable_tx_laser(struct ixgbe_hw *hw);
void ixgbe_flap_tx_laser(struct ixgbe_hw *hw);
s32 ixgbe_setup_link(struct ixgbe_hw *hw, ixgbe_link_speed speed,
- bool autoneg, bool autoneg_wait_to_complete);
+ bool autoneg_wait_to_complete);
s32 ixgbe_check_link(struct ixgbe_hw *hw, ixgbe_link_speed *speed,
bool *link_up, bool link_up_wait_to_complete);
s32 ixgbe_get_link_capabilities(struct ixgbe_hw *hw, ixgbe_link_speed *speed,
@@ -159,6 +158,7 @@ void ixgbe_atr_compute_perfect_hash_82599(union ixgbe_atr_input *input,
union ixgbe_atr_input *mask);
u32 ixgbe_atr_compute_sig_hash_82599(union ixgbe_atr_hash_dword input,
union ixgbe_atr_hash_dword common);
+bool ixgbe_verify_lesm_fw_enabled_82599(struct ixgbe_hw *hw);
s32 ixgbe_read_i2c_byte(struct ixgbe_hw *hw, u8 byte_offset, u8 dev_addr,
u8 *data);
s32 ixgbe_write_i2c_byte(struct ixgbe_hw *hw, u8 byte_offset, u8 dev_addr,
diff --git a/sys/dev/ixgbe/ixgbe_common.c b/sys/dev/ixgbe/ixgbe_common.c
index 51806d6..be8736f 100644
--- a/sys/dev/ixgbe/ixgbe_common.c
+++ b/sys/dev/ixgbe/ixgbe_common.c
@@ -1,6 +1,6 @@
/******************************************************************************
- Copyright (c) 2001-2012, Intel Corporation
+ Copyright (c) 2001-2013, Intel Corporation
All rights reserved.
Redistribution and use in source and binary forms, with or without
@@ -147,16 +147,14 @@ s32 ixgbe_init_ops_generic(struct ixgbe_hw *hw)
* function check the device id to see if the associated phy supports
* autoneg flow control.
**/
-static s32 ixgbe_device_supports_autoneg_fc(struct ixgbe_hw *hw)
+s32 ixgbe_device_supports_autoneg_fc(struct ixgbe_hw *hw)
{
DEBUGFUNC("ixgbe_device_supports_autoneg_fc");
switch (hw->device_id) {
- case IXGBE_DEV_ID_X540T:
- case IXGBE_DEV_ID_X540T1:
- return IXGBE_SUCCESS;
case IXGBE_DEV_ID_82599_T3_LOM:
+ case IXGBE_DEV_ID_X540T:
return IXGBE_SUCCESS;
default:
return IXGBE_ERR_FC_NOT_SUPPORTED;
@@ -174,6 +172,7 @@ static s32 ixgbe_setup_fc(struct ixgbe_hw *hw)
s32 ret_val = IXGBE_SUCCESS;
u32 reg = 0, reg_bp = 0;
u16 reg_cu = 0;
+ bool got_lock = FALSE;
DEBUGFUNC("ixgbe_setup_fc");
@@ -200,6 +199,7 @@ static s32 ixgbe_setup_fc(struct ixgbe_hw *hw)
* we link at 10G, the 1G advertisement is harmless and vice versa.
*/
switch (hw->phy.media_type) {
+ case ixgbe_media_type_fiber_fixed:
case ixgbe_media_type_fiber:
case ixgbe_media_type_backplane:
reg = IXGBE_READ_REG(hw, IXGBE_PCS1GANA);
@@ -297,7 +297,28 @@ static s32 ixgbe_setup_fc(struct ixgbe_hw *hw)
*/
if (hw->phy.media_type == ixgbe_media_type_backplane) {
reg_bp |= IXGBE_AUTOC_AN_RESTART;
+ /* Need the SW/FW semaphore around AUTOC writes if 82599 and
+ * LESM is on, likewise reset_pipeline requries the lock as
+ * it also writes AUTOC.
+ */
+ if ((hw->mac.type == ixgbe_mac_82599EB) &&
+ ixgbe_verify_lesm_fw_enabled_82599(hw)) {
+ ret_val = hw->mac.ops.acquire_swfw_sync(hw,
+ IXGBE_GSSR_MAC_CSR_SM);
+ if (ret_val != IXGBE_SUCCESS) {
+ ret_val = IXGBE_ERR_SWFW_SYNC;
+ goto out;
+ }
+ got_lock = TRUE;
+ }
+
IXGBE_WRITE_REG(hw, IXGBE_AUTOC, reg_bp);
+ if (hw->mac.type == ixgbe_mac_82599EB)
+ ixgbe_reset_pipeline_82599(hw);
+
+ if (got_lock)
+ hw->mac.ops.release_swfw_sync(hw,
+ IXGBE_GSSR_MAC_CSR_SM);
} else if ((hw->phy.media_type == ixgbe_media_type_copper) &&
(ixgbe_device_supports_autoneg_fc(hw) == IXGBE_SUCCESS)) {
hw->phy.ops.write_reg(hw, IXGBE_MDIO_AUTO_NEG_ADVT,
@@ -680,6 +701,195 @@ s32 ixgbe_read_pba_num_generic(struct ixgbe_hw *hw, u32 *pba_num)
}
/**
+ * ixgbe_read_pba_raw
+ * @hw: pointer to the HW structure
+ * @eeprom_buf: optional pointer to EEPROM image
+ * @eeprom_buf_size: size of EEPROM image in words
+ * @max_pba_block_size: PBA block size limit
+ * @pba: pointer to output PBA structure
+ *
+ * Reads PBA from EEPROM image when eeprom_buf is not NULL.
+ * Reads PBA from physical EEPROM device when eeprom_buf is NULL.
+ *
+ **/
+s32 ixgbe_read_pba_raw(struct ixgbe_hw *hw, u16 *eeprom_buf,
+ u32 eeprom_buf_size, u16 max_pba_block_size,
+ struct ixgbe_pba *pba)
+{
+ s32 ret_val;
+ u16 pba_block_size;
+
+ if (pba == NULL)
+ return IXGBE_ERR_PARAM;
+
+ if (eeprom_buf == NULL) {
+ ret_val = hw->eeprom.ops.read_buffer(hw, IXGBE_PBANUM0_PTR, 2,
+ &pba->word[0]);
+ if (ret_val)
+ return ret_val;
+ } else {
+ if (eeprom_buf_size > IXGBE_PBANUM1_PTR) {
+ pba->word[0] = eeprom_buf[IXGBE_PBANUM0_PTR];
+ pba->word[1] = eeprom_buf[IXGBE_PBANUM1_PTR];
+ } else {
+ return IXGBE_ERR_PARAM;
+ }
+ }
+
+ if (pba->word[0] == IXGBE_PBANUM_PTR_GUARD) {
+ if (pba->pba_block == NULL)
+ return IXGBE_ERR_PARAM;
+
+ ret_val = ixgbe_get_pba_block_size(hw, eeprom_buf,
+ eeprom_buf_size,
+ &pba_block_size);
+ if (ret_val)
+ return ret_val;
+
+ if (pba_block_size > max_pba_block_size)
+ return IXGBE_ERR_PARAM;
+
+ if (eeprom_buf == NULL) {
+ ret_val = hw->eeprom.ops.read_buffer(hw, pba->word[1],
+ pba_block_size,
+ pba->pba_block);
+ if (ret_val)
+ return ret_val;
+ } else {
+ if (eeprom_buf_size > (u32)(pba->word[1] +
+ pba->pba_block[0])) {
+ memcpy(pba->pba_block,
+ &eeprom_buf[pba->word[1]],
+ pba_block_size * sizeof(u16));
+ } else {
+ return IXGBE_ERR_PARAM;
+ }
+ }
+ }
+
+ return IXGBE_SUCCESS;
+}
+
+/**
+ * ixgbe_write_pba_raw
+ * @hw: pointer to the HW structure
+ * @eeprom_buf: optional pointer to EEPROM image
+ * @eeprom_buf_size: size of EEPROM image in words
+ * @pba: pointer to PBA structure
+ *
+ * Writes PBA to EEPROM image when eeprom_buf is not NULL.
+ * Writes PBA to physical EEPROM device when eeprom_buf is NULL.
+ *
+ **/
+s32 ixgbe_write_pba_raw(struct ixgbe_hw *hw, u16 *eeprom_buf,
+ u32 eeprom_buf_size, struct ixgbe_pba *pba)
+{
+ s32 ret_val;
+
+ if (pba == NULL)
+ return IXGBE_ERR_PARAM;
+
+ if (eeprom_buf == NULL) {
+ ret_val = hw->eeprom.ops.write_buffer(hw, IXGBE_PBANUM0_PTR, 2,
+ &pba->word[0]);
+ if (ret_val)
+ return ret_val;
+ } else {
+ if (eeprom_buf_size > IXGBE_PBANUM1_PTR) {
+ eeprom_buf[IXGBE_PBANUM0_PTR] = pba->word[0];
+ eeprom_buf[IXGBE_PBANUM1_PTR] = pba->word[1];
+ } else {
+ return IXGBE_ERR_PARAM;
+ }
+ }
+
+ if (pba->word[0] == IXGBE_PBANUM_PTR_GUARD) {
+ if (pba->pba_block == NULL)
+ return IXGBE_ERR_PARAM;
+
+ if (eeprom_buf == NULL) {
+ ret_val = hw->eeprom.ops.write_buffer(hw, pba->word[1],
+ pba->pba_block[0],
+ pba->pba_block);
+ if (ret_val)
+ return ret_val;
+ } else {
+ if (eeprom_buf_size > (u32)(pba->word[1] +
+ pba->pba_block[0])) {
+ memcpy(&eeprom_buf[pba->word[1]],
+ pba->pba_block,
+ pba->pba_block[0] * sizeof(u16));
+ } else {
+ return IXGBE_ERR_PARAM;
+ }
+ }
+ }
+
+ return IXGBE_SUCCESS;
+}
+
+/**
+ * ixgbe_get_pba_block_size
+ * @hw: pointer to the HW structure
+ * @eeprom_buf: optional pointer to EEPROM image
+ * @eeprom_buf_size: size of EEPROM image in words
+ * @pba_data_size: pointer to output variable
+ *
+ * Returns the size of the PBA block in words. Function operates on EEPROM
+ * image if the eeprom_buf pointer is not NULL otherwise it accesses physical
+ * EEPROM device.
+ *
+ **/
+s32 ixgbe_get_pba_block_size(struct ixgbe_hw *hw, u16 *eeprom_buf,
+ u32 eeprom_buf_size, u16 *pba_block_size)
+{
+ s32 ret_val;
+ u16 pba_word[2];
+ u16 length;
+
+ DEBUGFUNC("ixgbe_get_pba_block_size");
+
+ if (eeprom_buf == NULL) {
+ ret_val = hw->eeprom.ops.read_buffer(hw, IXGBE_PBANUM0_PTR, 2,
+ &pba_word[0]);
+ if (ret_val)
+ return ret_val;
+ } else {
+ if (eeprom_buf_size > IXGBE_PBANUM1_PTR) {
+ pba_word[0] = eeprom_buf[IXGBE_PBANUM0_PTR];
+ pba_word[1] = eeprom_buf[IXGBE_PBANUM1_PTR];
+ } else {
+ return IXGBE_ERR_PARAM;
+ }
+ }
+
+ if (pba_word[0] == IXGBE_PBANUM_PTR_GUARD) {
+ if (eeprom_buf == NULL) {
+ ret_val = hw->eeprom.ops.read(hw, pba_word[1] + 0,
+ &length);
+ if (ret_val)
+ return ret_val;
+ } else {
+ if (eeprom_buf_size > pba_word[1])
+ length = eeprom_buf[pba_word[1] + 0];
+ else
+ return IXGBE_ERR_PARAM;
+ }
+
+ if (length == 0xFFFF || length == 0)
+ return IXGBE_ERR_PBA_SECTION;
+ } else {
+ /* PBA number in legacy format, there is no PBA Block. */
+ length = 0;
+ }
+
+ if (pba_block_size != NULL)
+ *pba_block_size = length;
+
+ return IXGBE_SUCCESS;
+}
+
+/**
* ixgbe_get_mac_addr_generic - Generic get MAC address
* @hw: pointer to hardware structure
* @mac_addr: Adapter MAC address
@@ -1268,7 +1478,7 @@ s32 ixgbe_read_eerd_buffer_generic(struct ixgbe_hw *hw, u16 offset,
}
for (i = 0; i < words; i++) {
- eerd = ((offset + i) << IXGBE_EEPROM_RW_ADDR_SHIFT) +
+ eerd = ((offset + i) << IXGBE_EEPROM_RW_ADDR_SHIFT) |
IXGBE_EEPROM_RW_REG_START;
IXGBE_WRITE_REG(hw, IXGBE_EERD, eerd);
@@ -2719,6 +2929,7 @@ void ixgbe_fc_autoneg(struct ixgbe_hw *hw)
switch (hw->phy.media_type) {
/* Autoneg flow control on fiber adapters */
+ case ixgbe_media_type_fiber_fixed:
case ixgbe_media_type_fiber:
if (speed == IXGBE_LINK_SPEED_1GB_FULL)
ret_val = ixgbe_fc_autoneg_fiber(hw);
@@ -2965,6 +3176,7 @@ s32 ixgbe_blink_led_start_generic(struct ixgbe_hw *hw, u32 index)
bool link_up = 0;
u32 autoc_reg = IXGBE_READ_REG(hw, IXGBE_AUTOC);
u32 led_reg = IXGBE_READ_REG(hw, IXGBE_LEDCTL);
+ s32 ret_val = IXGBE_SUCCESS;
DEBUGFUNC("ixgbe_blink_led_start_generic");
@@ -2975,10 +3187,29 @@ s32 ixgbe_blink_led_start_generic(struct ixgbe_hw *hw, u32 index)
hw->mac.ops.check_link(hw, &speed, &link_up, FALSE);
if (!link_up) {
+ /* Need the SW/FW semaphore around AUTOC writes if 82599 and
+ * LESM is on.
+ */
+ bool got_lock = FALSE;
+ if ((hw->mac.type == ixgbe_mac_82599EB) &&
+ ixgbe_verify_lesm_fw_enabled_82599(hw)) {
+ ret_val = hw->mac.ops.acquire_swfw_sync(hw,
+ IXGBE_GSSR_MAC_CSR_SM);
+ if (ret_val != IXGBE_SUCCESS) {
+ ret_val = IXGBE_ERR_SWFW_SYNC;
+ goto out;
+ }
+ got_lock = TRUE;
+ }
+
autoc_reg |= IXGBE_AUTOC_AN_RESTART;
autoc_reg |= IXGBE_AUTOC_FLU;
IXGBE_WRITE_REG(hw, IXGBE_AUTOC, autoc_reg);
IXGBE_WRITE_FLUSH(hw);
+
+ if (got_lock)
+ hw->mac.ops.release_swfw_sync(hw,
+ IXGBE_GSSR_MAC_CSR_SM);
msec_delay(10);
}
@@ -2987,7 +3218,8 @@ s32 ixgbe_blink_led_start_generic(struct ixgbe_hw *hw, u32 index)
IXGBE_WRITE_REG(hw, IXGBE_LEDCTL, led_reg);
IXGBE_WRITE_FLUSH(hw);
- return IXGBE_SUCCESS;
+out:
+ return ret_val;
}
/**
@@ -2999,21 +3231,43 @@ s32 ixgbe_blink_led_stop_generic(struct ixgbe_hw *hw, u32 index)
{
u32 autoc_reg = IXGBE_READ_REG(hw, IXGBE_AUTOC);
u32 led_reg = IXGBE_READ_REG(hw, IXGBE_LEDCTL);
+ s32 ret_val = IXGBE_SUCCESS;
+ bool got_lock = FALSE;
DEBUGFUNC("ixgbe_blink_led_stop_generic");
+ /* Need the SW/FW semaphore around AUTOC writes if 82599 and
+ * LESM is on.
+ */
+ if ((hw->mac.type == ixgbe_mac_82599EB) &&
+ ixgbe_verify_lesm_fw_enabled_82599(hw)) {
+ ret_val = hw->mac.ops.acquire_swfw_sync(hw,
+ IXGBE_GSSR_MAC_CSR_SM);
+ if (ret_val != IXGBE_SUCCESS) {
+ ret_val = IXGBE_ERR_SWFW_SYNC;
+ goto out;
+ }
+ got_lock = TRUE;
+ }
autoc_reg &= ~IXGBE_AUTOC_FLU;
autoc_reg |= IXGBE_AUTOC_AN_RESTART;
IXGBE_WRITE_REG(hw, IXGBE_AUTOC, autoc_reg);
+ if (hw->mac.type == ixgbe_mac_82599EB)
+ ixgbe_reset_pipeline_82599(hw);
+
+ if (got_lock)
+ hw->mac.ops.release_swfw_sync(hw, IXGBE_GSSR_MAC_CSR_SM);
+
led_reg &= ~IXGBE_LED_MODE_MASK(index);
led_reg &= ~IXGBE_LED_BLINK(index);
led_reg |= IXGBE_LED_LINK_ACTIVE << IXGBE_LED_MODE_SHIFT(index);
IXGBE_WRITE_REG(hw, IXGBE_LEDCTL, led_reg);
IXGBE_WRITE_FLUSH(hw);
- return IXGBE_SUCCESS;
+out:
+ return ret_val;
}
/**
@@ -3882,7 +4136,7 @@ void ixgbe_enable_relaxed_ordering_gen2(struct ixgbe_hw *hw)
* Calculates the checksum for some buffer on a specified length. The
* checksum calculated is returned.
**/
-static u8 ixgbe_calculate_checksum(u8 *buffer, u32 length)
+u8 ixgbe_calculate_checksum(u8 *buffer, u32 length)
{
u32 i;
u8 sum = 0;
@@ -3908,8 +4162,8 @@ static u8 ixgbe_calculate_checksum(u8 *buffer, u32 length)
* Communicates with the manageability block. On success return IXGBE_SUCCESS
* else return IXGBE_ERR_HOST_INTERFACE_COMMAND.
**/
-static s32 ixgbe_host_interface_command(struct ixgbe_hw *hw, u32 *buffer,
- u32 length)
+s32 ixgbe_host_interface_command(struct ixgbe_hw *hw, u32 *buffer,
+ u32 length)
{
u32 hicr, i, bi;
u32 hdr_size = sizeof(struct ixgbe_hic_hdr);
diff --git a/sys/dev/ixgbe/ixgbe_common.h b/sys/dev/ixgbe/ixgbe_common.h
index 3bbc537..cd9a13d 100644
--- a/sys/dev/ixgbe/ixgbe_common.h
+++ b/sys/dev/ixgbe/ixgbe_common.h
@@ -1,6 +1,6 @@
/******************************************************************************
- Copyright (c) 2001-2012, Intel Corporation
+ Copyright (c) 2001-2013, Intel Corporation
All rights reserved.
Redistribution and use in source and binary forms, with or without
@@ -41,9 +41,14 @@
IXGBE_WRITE_REG(hw, reg, (u32) value); \
IXGBE_WRITE_REG(hw, reg + 4, (u32) (value >> 32)); \
} while (0)
+#if !defined(NO_READ_PBA_RAW) || !defined(NO_WRITE_PBA_RAW)
+struct ixgbe_pba {
+ u16 word[2];
+ u16 *pba_block;
+};
+#endif
u16 ixgbe_get_pcie_msix_count_generic(struct ixgbe_hw *hw);
-
s32 ixgbe_init_ops_generic(struct ixgbe_hw *hw);
s32 ixgbe_init_hw_generic(struct ixgbe_hw *hw);
s32 ixgbe_start_hw_generic(struct ixgbe_hw *hw);
@@ -52,6 +57,13 @@ s32 ixgbe_clear_hw_cntrs_generic(struct ixgbe_hw *hw);
s32 ixgbe_read_pba_num_generic(struct ixgbe_hw *hw, u32 *pba_num);
s32 ixgbe_read_pba_string_generic(struct ixgbe_hw *hw, u8 *pba_num,
u32 pba_num_size);
+s32 ixgbe_read_pba_raw(struct ixgbe_hw *hw, u16 *eeprom_buf,
+ u32 eeprom_buf_size, u16 max_pba_block_size,
+ struct ixgbe_pba *pba);
+s32 ixgbe_write_pba_raw(struct ixgbe_hw *hw, u16 *eeprom_buf,
+ u32 eeprom_buf_size, struct ixgbe_pba *pba);
+s32 ixgbe_get_pba_block_size(struct ixgbe_hw *hw, u16 *eeprom_buf,
+ u32 eeprom_buf_size, u16 *pba_block_size);
s32 ixgbe_get_mac_addr_generic(struct ixgbe_hw *hw, u8 *mac_addr);
s32 ixgbe_get_bus_info_generic(struct ixgbe_hw *hw);
void ixgbe_set_lan_id_multi_port_pcie(struct ixgbe_hw *hw);
@@ -96,6 +108,7 @@ s32 ixgbe_disable_sec_rx_path_generic(struct ixgbe_hw *hw);
s32 ixgbe_enable_sec_rx_path_generic(struct ixgbe_hw *hw);
s32 ixgbe_fc_enable_generic(struct ixgbe_hw *hw);
+s32 ixgbe_device_supports_autoneg_fc(struct ixgbe_hw *hw);
void ixgbe_fc_autoneg(struct ixgbe_hw *hw);
s32 ixgbe_validate_mac_addr(u8 *mac_addr);
@@ -137,5 +150,11 @@ void ixgbe_set_rxpba_generic(struct ixgbe_hw *hw, int num_pb, u32 headroom,
void ixgbe_enable_relaxed_ordering_gen2(struct ixgbe_hw *hw);
s32 ixgbe_set_fw_drv_ver_generic(struct ixgbe_hw *hw, u8 maj, u8 min,
u8 build, u8 ver);
+u8 ixgbe_calculate_checksum(u8 *buffer, u32 length);
+s32 ixgbe_host_interface_command(struct ixgbe_hw *hw, u32 *buffer,
+ u32 length);
void ixgbe_clear_tx_pending(struct ixgbe_hw *hw);
+
+extern s32 ixgbe_reset_pipeline_82599(struct ixgbe_hw *hw);
+
#endif /* IXGBE_COMMON */
diff --git a/sys/dev/ixgbe/ixgbe_mbx.h b/sys/dev/ixgbe/ixgbe_mbx.h
index 8ad18cb..adcba9e 100644
--- a/sys/dev/ixgbe/ixgbe_mbx.h
+++ b/sys/dev/ixgbe/ixgbe_mbx.h
@@ -1,6 +1,6 @@
/******************************************************************************
- Copyright (c) 2001-2012, Intel Corporation
+ Copyright (c) 2001-2013, Intel Corporation
All rights reserved.
Redistribution and use in source and binary forms, with or without
@@ -84,8 +84,20 @@
#define IXGBE_VF_SET_MAC_ADDR 0x02 /* VF requests PF to set MAC addr */
#define IXGBE_VF_SET_MULTICAST 0x03 /* VF requests PF to set MC addr */
#define IXGBE_VF_SET_VLAN 0x04 /* VF requests PF to set VLAN */
+
+/* mailbox API, version 1.0 VF requests */
#define IXGBE_VF_SET_LPE 0x05 /* VF requests PF to set VMOLR.LPE */
#define IXGBE_VF_SET_MACVLAN 0x06 /* VF requests PF for unicast filter */
+#define IXGBE_VF_API_NEGOTIATE 0x08 /* negotiate API version */
+
+/* mailbox API, version 1.1 VF requests */
+#define IXGBE_VF_GET_QUEUES 0x09 /* get queue configuration */
+
+/* GET_QUEUES return data indices within the mailbox */
+#define IXGBE_VF_TX_QUEUES 1 /* number of Tx queues supported */
+#define IXGBE_VF_RX_QUEUES 2 /* number of Rx queues supported */
+#define IXGBE_VF_TRANS_VLAN 3 /* Indication of port vlan */
+#define IXGBE_VF_DEF_QUEUE 4 /* Default queue offset */
/* length of permanent address message returned from PF */
#define IXGBE_VF_PERMADDR_MSG_LEN 4
diff --git a/sys/dev/ixgbe/ixgbe_osdep.h b/sys/dev/ixgbe/ixgbe_osdep.h
index a07a625..afd5ab0 100644
--- a/sys/dev/ixgbe/ixgbe_osdep.h
+++ b/sys/dev/ixgbe/ixgbe_osdep.h
@@ -1,6 +1,6 @@
/******************************************************************************
- Copyright (c) 2001-2012, Intel Corporation
+ Copyright (c) 2001-2013, Intel Corporation
All rights reserved.
Redistribution and use in source and binary forms, with or without
@@ -91,6 +91,9 @@
#define CMD_MEM_WRT_INVALIDATE 0x0010 /* BIT_4 */
#define PCI_COMMAND_REGISTER PCIR_COMMAND
+/* Shared code dropped this define.. */
+#define IXGBE_INTEL_VENDOR_ID 0x8086
+
/* Bunch of defines for shared code bogosity */
#define UNREFERENCED_PARAMETER(_p)
#define UNREFERENCED_1PARAMETER(_p)
diff --git a/sys/dev/ixgbe/ixgbe_phy.c b/sys/dev/ixgbe/ixgbe_phy.c
index 3f262f9..b22797f 100644
--- a/sys/dev/ixgbe/ixgbe_phy.c
+++ b/sys/dev/ixgbe/ixgbe_phy.c
@@ -1,6 +1,6 @@
/******************************************************************************
- Copyright (c) 2001-2012, Intel Corporation
+ Copyright (c) 2001-2013, Intel Corporation
All rights reserved.
Redistribution and use in source and binary forms, with or without
@@ -47,6 +47,8 @@ static void ixgbe_raise_i2c_clk(struct ixgbe_hw *hw, u32 *i2cctl);
static void ixgbe_lower_i2c_clk(struct ixgbe_hw *hw, u32 *i2cctl);
static s32 ixgbe_set_i2c_data(struct ixgbe_hw *hw, u32 *i2cctl, bool data);
static bool ixgbe_get_i2c_data(u32 *i2cctl);
+static s32 ixgbe_read_i2c_sff8472_generic(struct ixgbe_hw *hw, u8 byte_offset,
+ u8 *sff8472_data);
/**
* ixgbe_init_phy_ops_generic - Inits PHY function ptrs
@@ -71,6 +73,7 @@ s32 ixgbe_init_phy_ops_generic(struct ixgbe_hw *hw)
phy->ops.get_firmware_version = ixgbe_get_phy_firmware_version_generic;
phy->ops.read_i2c_byte = &ixgbe_read_i2c_byte_generic;
phy->ops.write_i2c_byte = &ixgbe_write_i2c_byte_generic;
+ phy->ops.read_i2c_sff8472 = &ixgbe_read_i2c_sff8472_generic;
phy->ops.read_i2c_eeprom = &ixgbe_read_i2c_eeprom_generic;
phy->ops.write_i2c_eeprom = &ixgbe_write_i2c_eeprom_generic;
phy->ops.i2c_bus_clear = &ixgbe_i2c_bus_clear;
@@ -563,14 +566,12 @@ s32 ixgbe_setup_phy_link_generic(struct ixgbe_hw *hw)
* ixgbe_setup_phy_link_speed_generic - Sets the auto advertised capabilities
* @hw: pointer to hardware structure
* @speed: new link speed
- * @autoneg: TRUE if autonegotiation enabled
**/
s32 ixgbe_setup_phy_link_speed_generic(struct ixgbe_hw *hw,
ixgbe_link_speed speed,
- bool autoneg,
bool autoneg_wait_to_complete)
{
- UNREFERENCED_2PARAMETER(autoneg, autoneg_wait_to_complete);
+ UNREFERENCED_1PARAMETER(autoneg_wait_to_complete);
DEBUGFUNC("ixgbe_setup_phy_link_speed_generic");
@@ -969,9 +970,7 @@ s32 ixgbe_identify_sfp_module_generic(struct ixgbe_hw *hw)
IXGBE_SFF_IDENTIFIER,
&identifier);
- if (status == IXGBE_ERR_SWFW_SYNC ||
- status == IXGBE_ERR_I2C ||
- status == IXGBE_ERR_SFP_NOT_PRESENT)
+ if (status != IXGBE_SUCCESS)
goto err_read_i2c_eeprom;
/* LAN ID is needed for sfp_type determination */
@@ -985,26 +984,20 @@ s32 ixgbe_identify_sfp_module_generic(struct ixgbe_hw *hw)
IXGBE_SFF_1GBE_COMP_CODES,
&comp_codes_1g);
- if (status == IXGBE_ERR_SWFW_SYNC ||
- status == IXGBE_ERR_I2C ||
- status == IXGBE_ERR_SFP_NOT_PRESENT)
+ if (status != IXGBE_SUCCESS)
goto err_read_i2c_eeprom;
status = hw->phy.ops.read_i2c_eeprom(hw,
IXGBE_SFF_10GBE_COMP_CODES,
&comp_codes_10g);
- if (status == IXGBE_ERR_SWFW_SYNC ||
- status == IXGBE_ERR_I2C ||
- status == IXGBE_ERR_SFP_NOT_PRESENT)
+ if (status != IXGBE_SUCCESS)
goto err_read_i2c_eeprom;
status = hw->phy.ops.read_i2c_eeprom(hw,
IXGBE_SFF_CABLE_TECHNOLOGY,
&cable_tech);
- if (status == IXGBE_ERR_SWFW_SYNC ||
- status == IXGBE_ERR_I2C ||
- status == IXGBE_ERR_SFP_NOT_PRESENT)
+ if (status != IXGBE_SUCCESS)
goto err_read_i2c_eeprom;
/* ID Module
@@ -1102,27 +1095,21 @@ s32 ixgbe_identify_sfp_module_generic(struct ixgbe_hw *hw)
IXGBE_SFF_VENDOR_OUI_BYTE0,
&oui_bytes[0]);
- if (status == IXGBE_ERR_SWFW_SYNC ||
- status == IXGBE_ERR_I2C ||
- status == IXGBE_ERR_SFP_NOT_PRESENT)
+ if (status != IXGBE_SUCCESS)
goto err_read_i2c_eeprom;
status = hw->phy.ops.read_i2c_eeprom(hw,
IXGBE_SFF_VENDOR_OUI_BYTE1,
&oui_bytes[1]);
- if (status == IXGBE_ERR_SWFW_SYNC ||
- status == IXGBE_ERR_I2C ||
- status == IXGBE_ERR_SFP_NOT_PRESENT)
+ if (status != IXGBE_SUCCESS)
goto err_read_i2c_eeprom;
status = hw->phy.ops.read_i2c_eeprom(hw,
IXGBE_SFF_VENDOR_OUI_BYTE2,
&oui_bytes[2]);
- if (status == IXGBE_ERR_SWFW_SYNC ||
- status == IXGBE_ERR_I2C ||
- status == IXGBE_ERR_SFP_NOT_PRESENT)
+ if (status != IXGBE_SUCCESS)
goto err_read_i2c_eeprom;
vendor_oui =
@@ -1333,6 +1320,22 @@ s32 ixgbe_read_i2c_eeprom_generic(struct ixgbe_hw *hw, u8 byte_offset,
}
/**
+ * ixgbe_read_i2c_sff8472_generic - Reads 8 bit word over I2C interface
+ * @hw: pointer to hardware structure
+ * @byte_offset: byte offset at address 0xA2
+ * @eeprom_data: value read
+ *
+ * Performs byte read operation to SFP module's SFF-8472 data over I2C
+ **/
+static s32 ixgbe_read_i2c_sff8472_generic(struct ixgbe_hw *hw, u8 byte_offset,
+ u8 *sff8472_data)
+{
+ return hw->phy.ops.read_i2c_byte(hw, byte_offset,
+ IXGBE_I2C_EEPROM_DEV_ADDR2,
+ sff8472_data);
+}
+
+/**
* ixgbe_write_i2c_eeprom_generic - Writes 8 bit EEPROM word over I2C interface
* @hw: pointer to hardware structure
* @byte_offset: EEPROM byte offset to write
@@ -1425,9 +1428,9 @@ s32 ixgbe_read_i2c_byte_generic(struct ixgbe_hw *hw, u8 byte_offset,
break;
fail:
+ ixgbe_i2c_bus_clear(hw);
hw->mac.ops.release_swfw_sync(hw, swfw_mask);
msec_delay(100);
- ixgbe_i2c_bus_clear(hw);
retry++;
if (retry < max_retry)
DEBUGOUT("I2C byte read error - Retrying.\n");
diff --git a/sys/dev/ixgbe/ixgbe_phy.h b/sys/dev/ixgbe/ixgbe_phy.h
index 017ea88..5b2e28b 100644
--- a/sys/dev/ixgbe/ixgbe_phy.h
+++ b/sys/dev/ixgbe/ixgbe_phy.h
@@ -1,6 +1,6 @@
/******************************************************************************
- Copyright (c) 2001-2012, Intel Corporation
+ Copyright (c) 2001-2013, Intel Corporation
All rights reserved.
Redistribution and use in source and binary forms, with or without
@@ -36,7 +36,9 @@
#define _IXGBE_PHY_H_
#include "ixgbe_type.h"
-#define IXGBE_I2C_EEPROM_DEV_ADDR 0xA0
+#define IXGBE_I2C_EEPROM_DEV_ADDR 0xA0
+#define IXGBE_I2C_EEPROM_DEV_ADDR2 0xA2
+#define IXGBE_I2C_EEPROM_BANK_LEN 0xFF
/* EEPROM byte offsets */
#define IXGBE_SFF_IDENTIFIER 0x0
@@ -48,6 +50,10 @@
#define IXGBE_SFF_10GBE_COMP_CODES 0x3
#define IXGBE_SFF_CABLE_TECHNOLOGY 0x8
#define IXGBE_SFF_CABLE_SPEC_COMP 0x3C
+#define IXGBE_SFF_SFF_8472_SWAP 0x5C
+#define IXGBE_SFF_SFF_8472_COMP 0x5E
+#define IXGBE_SFF_SFF_8472_OSCB 0x6E
+#define IXGBE_SFF_SFF_8472_ESCB 0x76
/* Bitmasks */
#define IXGBE_SFF_DA_PASSIVE_CABLE 0x4
@@ -58,6 +64,9 @@
#define IXGBE_SFF_1GBASET_CAPABLE 0x8
#define IXGBE_SFF_10GBASESR_CAPABLE 0x10
#define IXGBE_SFF_10GBASELR_CAPABLE 0x20
+#define IXGBE_SFF_SOFT_RS_SELECT_MASK 0x8
+#define IXGBE_SFF_SOFT_RS_SELECT_10G 0x8
+#define IXGBE_SFF_SOFT_RS_SELECT_1G 0x0
#define IXGBE_I2C_EEPROM_READ_MASK 0x100
#define IXGBE_I2C_EEPROM_STATUS_MASK 0x3
#define IXGBE_I2C_EEPROM_STATUS_NO_OPERATION 0x0
@@ -95,6 +104,14 @@
#define IXGBE_TN_LASI_STATUS_REG 0x9005
#define IXGBE_TN_LASI_STATUS_TEMP_ALARM 0x0008
+/* SFP+ SFF-8472 Compliance */
+#define IXGBE_SFF_SFF_8472_UNSUP 0x00
+#define IXGBE_SFF_SFF_8472_REV_9_3 0x01
+#define IXGBE_SFF_SFF_8472_REV_9_5 0x02
+#define IXGBE_SFF_SFF_8472_REV_10_2 0x03
+#define IXGBE_SFF_SFF_8472_REV_10_4 0x04
+#define IXGBE_SFF_SFF_8472_REV_11_0 0x05
+
s32 ixgbe_init_phy_ops_generic(struct ixgbe_hw *hw);
bool ixgbe_validate_phy_addr(struct ixgbe_hw *hw, u32 phy_addr);
enum ixgbe_phy_type ixgbe_get_phy_type_from_id(u32 phy_id);
@@ -108,7 +125,6 @@ s32 ixgbe_write_phy_reg_generic(struct ixgbe_hw *hw, u32 reg_addr,
s32 ixgbe_setup_phy_link_generic(struct ixgbe_hw *hw);
s32 ixgbe_setup_phy_link_speed_generic(struct ixgbe_hw *hw,
ixgbe_link_speed speed,
- bool autoneg,
bool autoneg_wait_to_complete);
s32 ixgbe_get_copper_link_capabilities_generic(struct ixgbe_hw *hw,
ixgbe_link_speed *speed,
diff --git a/sys/dev/ixgbe/ixgbe_type.h b/sys/dev/ixgbe/ixgbe_type.h
index 52944fd..344097d 100644
--- a/sys/dev/ixgbe/ixgbe_type.h
+++ b/sys/dev/ixgbe/ixgbe_type.h
@@ -1,6 +1,6 @@
/******************************************************************************
- Copyright (c) 2001-2012, Intel Corporation
+ Copyright (c) 2001-2013, Intel Corporation
All rights reserved.
Redistribution and use in source and binary forms, with or without
@@ -38,9 +38,6 @@
#include "ixgbe_osdep.h"
-/* Vendor ID */
-#define IXGBE_INTEL_VENDOR_ID 0x8086
-
/* Device IDs */
#define IXGBE_DEV_ID_82598 0x10B6
#define IXGBE_DEV_ID_82598_BX 0x1508
@@ -62,18 +59,24 @@
#define IXGBE_DEV_ID_82599_CX4 0x10F9
#define IXGBE_DEV_ID_82599_SFP 0x10FB
#define IXGBE_SUBDEV_ID_82599_SFP 0x11A9
+#define IXGBE_SUBDEV_ID_82599_RNDC 0x1F72
#define IXGBE_SUBDEV_ID_82599_560FLR 0x17D0
+#define IXGBE_SUBDEV_ID_82599_ECNA_DP 0x0470
#define IXGBE_DEV_ID_82599_BACKPLANE_FCOE 0x152A
#define IXGBE_DEV_ID_82599_SFP_FCOE 0x1529
#define IXGBE_DEV_ID_82599_SFP_EM 0x1507
#define IXGBE_DEV_ID_82599_SFP_SF2 0x154D
+#define IXGBE_DEV_ID_82599_SFP_SF_QP 0x154A
#define IXGBE_DEV_ID_82599EN_SFP 0x1557
#define IXGBE_DEV_ID_82599_XAUI_LOM 0x10FC
#define IXGBE_DEV_ID_82599_T3_LOM 0x151C
#define IXGBE_DEV_ID_82599_VF 0x10ED
-#define IXGBE_DEV_ID_X540_VF 0x1515
+#define IXGBE_DEV_ID_82599_VF_HV 0x152E
+#define IXGBE_DEV_ID_82599_BYPASS 0x155D
#define IXGBE_DEV_ID_X540T 0x1528
-#define IXGBE_DEV_ID_X540T1 0x1560
+#define IXGBE_DEV_ID_X540_VF 0x1515
+#define IXGBE_DEV_ID_X540_VF_HV 0x1530
+#define IXGBE_DEV_ID_X540_BYPASS 0x155C
/* General Registers */
#define IXGBE_CTRL 0x00000
@@ -280,6 +283,7 @@
#define IXGBE_RETA(_i) (0x05C00 + ((_i) * 4)) /* 32 of these (0-31) */
#define IXGBE_RSSRK(_i) (0x05C80 + ((_i) * 4)) /* 10 of these (0-9) */
+
/* Flow Director registers */
#define IXGBE_FDIRCTRL 0x0EE00
#define IXGBE_FDIRHKEY 0x0EE68
@@ -360,11 +364,16 @@
#define IXGBE_WUPL 0x05900
#define IXGBE_WUPM 0x05A00 /* wake up pkt memory 0x5A00-0x5A7C */
+
#define IXGBE_FHFT(_n) (0x09000 + (_n * 0x100)) /* Flex host filter table */
/* Ext Flexible Host Filter Table */
#define IXGBE_FHFT_EXT(_n) (0x09800 + (_n * 0x100))
+/* Four Flexible Filters are supported */
#define IXGBE_FLEXIBLE_FILTER_COUNT_MAX 4
+
+/* Six Flexible Filters are supported */
+#define IXGBE_FLEXIBLE_FILTER_COUNT_MAX_6 6
#define IXGBE_EXT_FLEXIBLE_FILTER_COUNT_MAX 2
/* Each Flexible Filter is at most 128 (0x80) bytes in length */
@@ -396,10 +405,11 @@
#define IXGBE_WUFC_FLX3 0x00080000 /* Flexible Filter 3 Enable */
#define IXGBE_WUFC_FLX4 0x00100000 /* Flexible Filter 4 Enable */
#define IXGBE_WUFC_FLX5 0x00200000 /* Flexible Filter 5 Enable */
-#define IXGBE_WUFC_FLX_FILTERS 0x000F0000 /* Mask for 4 flex filters */
+#define IXGBE_WUFC_FLX_FILTERS 0x000F0000 /* Mask for 4 flex filters */
/* Mask for Ext. flex filters */
#define IXGBE_WUFC_EXT_FLX_FILTERS 0x00300000
-#define IXGBE_WUFC_ALL_FILTERS 0x003F00FF /* Mask for all wakeup filters */
+#define IXGBE_WUFC_ALL_FILTERS 0x000F00FF /* Mask all 4 flex filters */
+#define IXGBE_WUFC_ALL_FILTERS_6 0x003F00FF /* Mask all 6 flex filters */
#define IXGBE_WUFC_FLX_OFFSET 16 /* Offset to the Flexible Filters bits */
/* Wake Up Status */
@@ -420,7 +430,6 @@
#define IXGBE_WUS_FLX5 IXGBE_WUFC_FLX5
#define IXGBE_WUS_FLX_FILTERS IXGBE_WUFC_FLX_FILTERS
-/* Wake Up Packet Length */
#define IXGBE_WUPL_LENGTH_MASK 0xFFFF
/* DCB registers */
@@ -574,6 +583,7 @@
#define IXGBE_RTTBCNRTT 0x05150
#define IXGBE_RTTBCNRD 0x0498C
+
/* FCoE DMA Context Registers */
#define IXGBE_FCPTRL 0x02410 /* FC User Desc. PTR Low */
#define IXGBE_FCPTRH 0x02414 /* FC USer Desc. PTR High */
@@ -754,11 +764,14 @@
#define IXGBE_BMCIP_IPADDR_VALID 0x00000002
/* Management Bit Fields and Masks */
+#define IXGBE_MANC_RCV_TCO_EN 0x00020000 /* Rcv TCO packet enable */
#define IXGBE_MANC_EN_BMC2OS 0x10000000 /* Ena BMC2OS and OS2BMC traffic */
#define IXGBE_MANC_EN_BMC2OS_SHIFT 28
/* Firmware Semaphore Register */
#define IXGBE_FWSM_MODE_MASK 0xE
+#define IXGBE_FWSM_TS_ENABLED 0x1
+#define IXGBE_FWSM_FW_MODE_PT 0x4
/* ARC Subsystem registers */
#define IXGBE_HICR 0x15F00
@@ -1014,6 +1027,7 @@
#define IXGBE_RSCCTL_MAXDESC_4 0x04
#define IXGBE_RSCCTL_MAXDESC_8 0x08
#define IXGBE_RSCCTL_MAXDESC_16 0x0C
+#define IXGBE_RSCCTL_TS_DIS 0x02
/* RSCDBU Bit Masks */
#define IXGBE_RSCDBU_RSCSMALDIS_MASK 0x0000007F
@@ -1026,7 +1040,7 @@
#define IXGBE_RDRXCTL_DMAIDONE 0x00000008 /* DMA init cycle done */
#define IXGBE_RDRXCTL_AGGDIS 0x00010000 /* Aggregation disable */
#define IXGBE_RDRXCTL_RSCFRSTSIZE 0x003E0000 /* RSC First packet size */
-#define IXGBE_RDRXCTL_RSCLLIDIS 0x00800000 /* Disabl RSC compl on LLI */
+#define IXGBE_RDRXCTL_RSCLLIDIS 0x00800000 /* Disable RSC compl on LLI*/
#define IXGBE_RDRXCTL_RSCACKC 0x02000000 /* must set 1 when RSC ena */
#define IXGBE_RDRXCTL_FCOE_WRFIX 0x04000000 /* must set 1 when RSC ena */
@@ -1052,6 +1066,7 @@
#define IXGBE_CTRL_RST_MASK (IXGBE_CTRL_LNK_RST | IXGBE_CTRL_RST)
/* FACTPS */
+#define IXGBE_FACTPS_MNGCG 0x20000000 /* Manageblility Clock Gated */
#define IXGBE_FACTPS_LFS 0x40000000 /* LAN Function Select */
/* MHADD Bit Masks */
@@ -1590,6 +1605,7 @@ enum {
#define IXGBE_ESDP_SDP7 0x00000080 /* SDP7 Data Value */
#define IXGBE_ESDP_SDP0_DIR 0x00000100 /* SDP0 IO direction */
#define IXGBE_ESDP_SDP1_DIR 0x00000200 /* SDP1 IO direction */
+#define IXGBE_ESDP_SDP2_DIR 0x00000400 /* SDP1 IO direction */
#define IXGBE_ESDP_SDP3_DIR 0x00000800 /* SDP3 IO direction */
#define IXGBE_ESDP_SDP4_DIR 0x00001000 /* SDP4 IO direction */
#define IXGBE_ESDP_SDP5_DIR 0x00002000 /* SDP5 IO direction */
@@ -1668,6 +1684,7 @@ enum {
#define IXGBE_AUTOC2_10G_KR (0x0 << IXGBE_AUTOC2_10G_SERIAL_PMA_PMD_SHIFT)
#define IXGBE_AUTOC2_10G_XFI (0x1 << IXGBE_AUTOC2_10G_SERIAL_PMA_PMD_SHIFT)
#define IXGBE_AUTOC2_10G_SFI (0x2 << IXGBE_AUTOC2_10G_SERIAL_PMA_PMD_SHIFT)
+#define IXGBE_AUTOC2_LINK_DISABLE_MASK 0x70000000
#define IXGBE_MACC_FLU 0x00000001
#define IXGBE_MACC_FSV_10G 0x00030000
@@ -1838,7 +1855,7 @@ enum {
#define IXGBE_ETH_LENGTH_OF_ADDRESS 6
#define IXGBE_EEPROM_PAGE_SIZE_MAX 128
-#define IXGBE_EEPROM_RD_BUFFER_MAX_COUNT 512 /* words rd in burst */
+#define IXGBE_EEPROM_RD_BUFFER_MAX_COUNT 256 /* words rd in burst */
#define IXGBE_EEPROM_WR_BUFFER_MAX_COUNT 256 /* words wr in burst */
#ifndef IXGBE_EEPROM_GRANT_ATTEMPTS
@@ -2524,7 +2541,6 @@ typedef u32 ixgbe_link_speed;
IXGBE_LINK_SPEED_1GB_FULL | \
IXGBE_LINK_SPEED_10GB_FULL)
-
/* Physical layer type */
typedef u32 ixgbe_physical_layer;
#define IXGBE_PHYSICAL_LAYER_UNKNOWN 0
@@ -2757,6 +2773,7 @@ enum ixgbe_sfp_type {
enum ixgbe_media_type {
ixgbe_media_type_unknown = 0,
ixgbe_media_type_fiber,
+ ixgbe_media_type_fiber_fixed,
ixgbe_media_type_copper,
ixgbe_media_type_backplane,
ixgbe_media_type_cx4,
@@ -2975,7 +2992,7 @@ struct ixgbe_mac_operations {
void (*disable_tx_laser)(struct ixgbe_hw *);
void (*enable_tx_laser)(struct ixgbe_hw *);
void (*flap_tx_laser)(struct ixgbe_hw *);
- s32 (*setup_link)(struct ixgbe_hw *, ixgbe_link_speed, bool, bool);
+ s32 (*setup_link)(struct ixgbe_hw *, ixgbe_link_speed, bool);
s32 (*check_link)(struct ixgbe_hw *, ixgbe_link_speed *, bool *, bool);
s32 (*get_link_capabilities)(struct ixgbe_hw *, ixgbe_link_speed *,
bool *);
@@ -3026,12 +3043,12 @@ struct ixgbe_phy_operations {
s32 (*read_reg)(struct ixgbe_hw *, u32, u32, u16 *);
s32 (*write_reg)(struct ixgbe_hw *, u32, u32, u16);
s32 (*setup_link)(struct ixgbe_hw *);
- s32 (*setup_link_speed)(struct ixgbe_hw *, ixgbe_link_speed, bool,
- bool);
+ s32 (*setup_link_speed)(struct ixgbe_hw *, ixgbe_link_speed, bool);
s32 (*check_link)(struct ixgbe_hw *, ixgbe_link_speed *, bool *);
s32 (*get_firmware_version)(struct ixgbe_hw *, u16 *);
s32 (*read_i2c_byte)(struct ixgbe_hw *, u8, u8, u8 *);
s32 (*write_i2c_byte)(struct ixgbe_hw *, u8, u8, u8);
+ s32 (*read_i2c_sff8472)(struct ixgbe_hw *, u8 , u8 *);
s32 (*read_i2c_eeprom)(struct ixgbe_hw *, u8 , u8 *);
s32 (*write_i2c_eeprom)(struct ixgbe_hw *, u8, u8);
void (*i2c_bus_clear)(struct ixgbe_hw *);
@@ -3069,7 +3086,9 @@ struct ixgbe_mac_info {
u32 max_tx_queues;
u32 max_rx_queues;
u32 orig_autoc;
+ u32 cached_autoc;
u8 san_mac_rar_index;
+ bool get_link_status;
u32 orig_autoc2;
u16 max_msix_vectors;
bool arc_subsystem_valid;
@@ -3142,6 +3161,7 @@ struct ixgbe_hw {
u16 subsystem_vendor_id;
u8 revision_id;
bool adapter_stopped;
+ int api_version;
bool force_full_reset;
bool allow_unsupported_sfp;
};
@@ -3185,6 +3205,7 @@ struct ixgbe_hw {
#define IXGBE_ERR_INVALID_ARGUMENT -32
#define IXGBE_ERR_HOST_INTERFACE_COMMAND -33
#define IXGBE_ERR_OUT_OF_MEM -34
+#define IXGBE_ERR_FEATURE_NOT_SUPPORTED -36
#define IXGBE_NOT_IMPLEMENTED 0x7FFFFFFF
diff --git a/sys/dev/ixgbe/ixgbe_vf.c b/sys/dev/ixgbe/ixgbe_vf.c
index 9e3dd72..14834a2 100644
--- a/sys/dev/ixgbe/ixgbe_vf.c
+++ b/sys/dev/ixgbe/ixgbe_vf.c
@@ -1,6 +1,6 @@
/******************************************************************************
- Copyright (c) 2001-2012, Intel Corporation
+ Copyright (c) 2001-2013, Intel Corporation
All rights reserved.
Redistribution and use in source and binary forms, with or without
@@ -142,6 +142,7 @@ s32 ixgbe_reset_hw_vf(struct ixgbe_hw *hw)
/* Call adapter stop to disable tx/rx and clear interrupts */
hw->mac.ops.stop_adapter(hw);
+
DEBUGOUT("Issuing a function level reset to MAC\n");
ctrl = IXGBE_VFREAD_REG(hw, IXGBE_VFCTRL) | IXGBE_CTRL_RST;
@@ -272,6 +273,17 @@ static s32 ixgbe_mta_vector(struct ixgbe_hw *hw, u8 *mc_addr)
return vector;
}
+static void ixgbevf_write_msg_read_ack(struct ixgbe_hw *hw,
+ u32 *msg, u16 size)
+{
+ struct ixgbe_mbx_info *mbx = &hw->mbx;
+ u32 retmsg[IXGBE_VFMAILBOX_SIZE];
+ s32 retval = mbx->ops.write_posted(hw, msg, size, 0);
+
+ if (!retval)
+ mbx->ops.read_posted(hw, retmsg, size, 0);
+}
+
/**
* ixgbe_set_rar_vf - set device MAC address
* @hw: pointer to hardware structure
@@ -463,11 +475,10 @@ s32 ixgbevf_set_uc_addr_vf(struct ixgbe_hw *hw, u32 index, u8 *addr)
*
* Set the link speed in the AUTOC register and restarts link.
**/
-s32 ixgbe_setup_mac_link_vf(struct ixgbe_hw *hw,
- ixgbe_link_speed speed, bool autoneg,
+s32 ixgbe_setup_mac_link_vf(struct ixgbe_hw *hw, ixgbe_link_speed speed,
bool autoneg_wait_to_complete)
{
- UNREFERENCED_4PARAMETER(hw, speed, autoneg, autoneg_wait_to_complete);
+ UNREFERENCED_3PARAMETER(hw, speed, autoneg_wait_to_complete);
return IXGBE_SUCCESS;
}
@@ -483,23 +494,26 @@ s32 ixgbe_setup_mac_link_vf(struct ixgbe_hw *hw,
s32 ixgbe_check_mac_link_vf(struct ixgbe_hw *hw, ixgbe_link_speed *speed,
bool *link_up, bool autoneg_wait_to_complete)
{
+ struct ixgbe_mbx_info *mbx = &hw->mbx;
+ struct ixgbe_mac_info *mac = &hw->mac;
+ s32 ret_val = IXGBE_SUCCESS;
u32 links_reg;
+ u32 in_msg = 0;
UNREFERENCED_1PARAMETER(autoneg_wait_to_complete);
- if (!(hw->mbx.ops.check_for_rst(hw, 0))) {
- *link_up = FALSE;
- *speed = 0;
- return -1;
- }
+ /* If we were hit with a reset drop the link */
+ if (!mbx->ops.check_for_rst(hw, 0) || !mbx->timeout)
+ mac->get_link_status = TRUE;
- links_reg = IXGBE_VFREAD_REG(hw, IXGBE_VFLINKS);
+ if (!mac->get_link_status)
+ goto out;
- if (links_reg & IXGBE_LINKS_UP)
- *link_up = TRUE;
- else
- *link_up = FALSE;
+ /* if link status is down no point in checking to see if pf is up */
+ links_reg = IXGBE_READ_REG(hw, IXGBE_VFLINKS);
+ if (!(links_reg & IXGBE_LINKS_UP))
+ goto out;
- switch (links_reg & IXGBE_LINKS_SPEED_10G_82599) {
+ switch (links_reg & IXGBE_LINKS_SPEED_82599) {
case IXGBE_LINKS_SPEED_10G_82599:
*speed = IXGBE_LINK_SPEED_10GB_FULL;
break;
@@ -511,6 +525,87 @@ s32 ixgbe_check_mac_link_vf(struct ixgbe_hw *hw, ixgbe_link_speed *speed,
break;
}
+ /* if the read failed it could just be a mailbox collision, best wait
+ * until we are called again and don't report an error
+ */
+ if (mbx->ops.read(hw, &in_msg, 1, 0))
+ goto out;
+
+ if (!(in_msg & IXGBE_VT_MSGTYPE_CTS)) {
+ /* msg is not CTS and is NACK we must have lost CTS status */
+ if (in_msg & IXGBE_VT_MSGTYPE_NACK)
+ ret_val = -1;
+ goto out;
+ }
+
+ /* the pf is talking, if we timed out in the past we reinit */
+ if (!mbx->timeout) {
+ ret_val = -1;
+ goto out;
+ }
+
+ /* if we passed all the tests above then the link is up and we no
+ * longer need to check for link
+ */
+ mac->get_link_status = FALSE;
+
+out:
+ *link_up = !mac->get_link_status;
+ return ret_val;
+}
+
+/**
+ * ixgbevf_rlpml_set_vf - Set the maximum receive packet length
+ * @hw: pointer to the HW structure
+ * @max_size: value to assign to max frame size
+ **/
+void ixgbevf_rlpml_set_vf(struct ixgbe_hw *hw, u16 max_size)
+{
+ u32 msgbuf[2];
+
+ msgbuf[0] = IXGBE_VF_SET_LPE;
+ msgbuf[1] = max_size;
+ ixgbevf_write_msg_read_ack(hw, msgbuf, 2);
+}
+
+/**
+ * ixgbevf_negotiate_api_version - Negotiate supported API version
+ * @hw: pointer to the HW structure
+ * @api: integer containing requested API version
+ **/
+int ixgbevf_negotiate_api_version(struct ixgbe_hw *hw, int api)
+{
+ int err;
+ u32 msg[3];
+
+ /* Negotiate the mailbox API version */
+ msg[0] = IXGBE_VF_API_NEGOTIATE;
+ msg[1] = api;
+ msg[2] = 0;
+ err = hw->mbx.ops.write_posted(hw, msg, 3, 0);
+
+ if (!err)
+ err = hw->mbx.ops.read_posted(hw, msg, 3, 0);
+
+ if (!err) {
+ msg[0] &= ~IXGBE_VT_MSGTYPE_CTS;
+
+ /* Store value and return 0 on success */
+ if (msg[0] == (IXGBE_VF_API_NEGOTIATE | IXGBE_VT_MSGTYPE_ACK)) {
+ hw->api_version = api;
+ return 0;
+ }
+
+ err = IXGBE_ERR_INVALID_ARGUMENT;
+ }
+
+ return err;
+}
+
+int ixgbevf_get_queues(struct ixgbe_hw *hw, unsigned int *num_tcs,
+ unsigned int *default_tc)
+{
+ UNREFERENCED_3PARAMETER(hw, num_tcs, default_tc);
return IXGBE_SUCCESS;
}
diff --git a/sys/dev/ixgbe/ixgbe_vf.h b/sys/dev/ixgbe/ixgbe_vf.h
index 5c77ba4..8500768 100644
--- a/sys/dev/ixgbe/ixgbe_vf.h
+++ b/sys/dev/ixgbe/ixgbe_vf.h
@@ -1,6 +1,6 @@
/******************************************************************************
- Copyright (c) 2001-2012, Intel Corporation
+ Copyright (c) 2001-2013, Intel Corporation
All rights reserved.
Redistribution and use in source and binary forms, with or without
@@ -39,6 +39,9 @@
#define IXGBE_VF_MAX_TX_QUEUES 8
#define IXGBE_VF_MAX_RX_QUEUES 8
+/* DCB define */
+#define IXGBE_VF_MAX_TRAFFIC_CLASS 8
+
#define IXGBE_VFCTRL 0x00000
#define IXGBE_VFSTATUS 0x00008
#define IXGBE_VFLINKS 0x00010
@@ -117,7 +120,7 @@ u32 ixgbe_get_num_of_tx_queues_vf(struct ixgbe_hw *hw);
u32 ixgbe_get_num_of_rx_queues_vf(struct ixgbe_hw *hw);
s32 ixgbe_get_mac_addr_vf(struct ixgbe_hw *hw, u8 *mac_addr);
s32 ixgbe_setup_mac_link_vf(struct ixgbe_hw *hw, ixgbe_link_speed speed,
- bool autoneg, bool autoneg_wait_to_complete);
+ bool autoneg_wait_to_complete);
s32 ixgbe_check_mac_link_vf(struct ixgbe_hw *hw, ixgbe_link_speed *speed,
bool *link_up, bool autoneg_wait_to_complete);
s32 ixgbe_set_rar_vf(struct ixgbe_hw *hw, u32 index, u8 *addr, u32 vmdq,
@@ -127,5 +130,9 @@ s32 ixgbe_update_mc_addr_list_vf(struct ixgbe_hw *hw, u8 *mc_addr_list,
u32 mc_addr_count, ixgbe_mc_addr_itr,
bool clear);
s32 ixgbe_set_vfta_vf(struct ixgbe_hw *hw, u32 vlan, u32 vind, bool vlan_on);
+void ixgbevf_rlpml_set_vf(struct ixgbe_hw *hw, u16 max_size);
+int ixgbevf_negotiate_api_version(struct ixgbe_hw *hw, int api);
+int ixgbevf_get_queues(struct ixgbe_hw *hw, unsigned int *num_tcs,
+ unsigned int *default_tc);
#endif /* __IXGBE_VF_H__ */
diff --git a/sys/dev/ixgbe/ixgbe_x540.c b/sys/dev/ixgbe/ixgbe_x540.c
index 0635cda..9c7d5cc 100644
--- a/sys/dev/ixgbe/ixgbe_x540.c
+++ b/sys/dev/ixgbe/ixgbe_x540.c
@@ -1,6 +1,6 @@
/******************************************************************************
- Copyright (c) 2001-2012, Intel Corporation
+ Copyright (c) 2001-2013, Intel Corporation
All rights reserved.
Redistribution and use in source and binary forms, with or without
@@ -116,6 +116,7 @@ s32 ixgbe_init_ops_X540(struct ixgbe_hw *hw)
mac->ops.setup_rxpba = &ixgbe_set_rxpba_generic;
mac->ops.check_link = &ixgbe_check_mac_link_generic;
+
mac->mcft_size = 128;
mac->vft_size = 128;
mac->num_rar_entries = 128;
@@ -177,16 +178,14 @@ enum ixgbe_media_type ixgbe_get_media_type_X540(struct ixgbe_hw *hw)
* ixgbe_setup_mac_link_X540 - Sets the auto advertised capabilities
* @hw: pointer to hardware structure
* @speed: new link speed
- * @autoneg: TRUE if autonegotiation enabled
* @autoneg_wait_to_complete: TRUE when waiting for completion is needed
**/
s32 ixgbe_setup_mac_link_X540(struct ixgbe_hw *hw,
- ixgbe_link_speed speed, bool autoneg,
+ ixgbe_link_speed speed,
bool autoneg_wait_to_complete)
{
DEBUGFUNC("ixgbe_setup_mac_link_X540");
- return hw->phy.ops.setup_link_speed(hw, speed, autoneg,
- autoneg_wait_to_complete);
+ return hw->phy.ops.setup_link_speed(hw, speed, autoneg_wait_to_complete);
}
/**
@@ -973,3 +972,4 @@ s32 ixgbe_blink_led_stop_X540(struct ixgbe_hw *hw, u32 index)
return IXGBE_SUCCESS;
}
+
diff --git a/sys/dev/ixgbe/ixgbe_x540.h b/sys/dev/ixgbe/ixgbe_x540.h
index 29cf8bb..a553874 100644
--- a/sys/dev/ixgbe/ixgbe_x540.h
+++ b/sys/dev/ixgbe/ixgbe_x540.h
@@ -1,6 +1,6 @@
/******************************************************************************
- Copyright (c) 2001-2012, Intel Corporation
+ Copyright (c) 2001-2013, Intel Corporation
All rights reserved.
Redistribution and use in source and binary forms, with or without
@@ -41,7 +41,7 @@ s32 ixgbe_get_link_capabilities_X540(struct ixgbe_hw *hw,
ixgbe_link_speed *speed, bool *autoneg);
enum ixgbe_media_type ixgbe_get_media_type_X540(struct ixgbe_hw *hw);
s32 ixgbe_setup_mac_link_X540(struct ixgbe_hw *hw, ixgbe_link_speed speed,
- bool autoneg, bool link_up_wait_to_complete);
+ bool link_up_wait_to_complete);
s32 ixgbe_reset_hw_X540(struct ixgbe_hw *hw);
s32 ixgbe_start_hw_X540(struct ixgbe_hw *hw);
u32 ixgbe_get_supported_physical_layer_X540(struct ixgbe_hw *hw);
diff --git a/sys/dev/ixgbe/ixv.c b/sys/dev/ixgbe/ixv.c
index b3a3d64..47a707d 100644
--- a/sys/dev/ixgbe/ixv.c
+++ b/sys/dev/ixgbe/ixv.c
@@ -1,6 +1,6 @@
/******************************************************************************
- Copyright (c) 2001-2012, Intel Corporation
+ Copyright (c) 2001-2013, Intel Corporation
All rights reserved.
Redistribution and use in source and binary forms, with or without
@@ -169,7 +169,6 @@ static device_method_t ixv_methods[] = {
DEVMETHOD(device_attach, ixv_attach),
DEVMETHOD(device_detach, ixv_detach),
DEVMETHOD(device_shutdown, ixv_shutdown),
-
DEVMETHOD_END
};
@@ -1891,7 +1890,6 @@ ixv_config_link(struct adapter *adapter)
{
struct ixgbe_hw *hw = &adapter->hw;
u32 autoneg, err = 0;
- bool negotiate = TRUE;
if (hw->mac.ops.check_link)
err = hw->mac.ops.check_link(hw, &autoneg,
@@ -1900,8 +1898,8 @@ ixv_config_link(struct adapter *adapter)
goto out;
if (hw->mac.ops.setup_link)
- err = hw->mac.ops.setup_link(hw, autoneg,
- negotiate, adapter->link_up);
+ err = hw->mac.ops.setup_link(hw,
+ autoneg, adapter->link_up);
out:
return;
}
diff --git a/sys/dev/nvme/nvme.c b/sys/dev/nvme/nvme.c
index ed5dbdb..8e646b7 100644
--- a/sys/dev/nvme/nvme.c
+++ b/sys/dev/nvme/nvme.c
@@ -200,13 +200,11 @@ nvme_modevent(module_t mod, int type, void *arg)
void
nvme_dump_command(struct nvme_command *cmd)
{
- printf("opc:%x f:%x r1:%x cid:%x nsid:%x r2:%x r3:%x "
- "mptr:%qx prp1:%qx prp2:%qx cdw:%x %x %x %x %x %x\n",
+ printf(
+"opc:%x f:%x r1:%x cid:%x nsid:%x r2:%x r3:%x mptr:%jx prp1:%jx prp2:%jx cdw:%x %x %x %x %x %x\n",
cmd->opc, cmd->fuse, cmd->rsvd1, cmd->cid, cmd->nsid,
cmd->rsvd2, cmd->rsvd3,
- (long long unsigned int)cmd->mptr,
- (long long unsigned int)cmd->prp1,
- (long long unsigned int)cmd->prp2,
+ (uintmax_t)cmd->mptr, (uintmax_t)cmd->prp1, (uintmax_t)cmd->prp2,
cmd->cdw10, cmd->cdw11, cmd->cdw12, cmd->cdw13, cmd->cdw14,
cmd->cdw15);
}
diff --git a/sys/dev/nvme/nvme_ctrlr.c b/sys/dev/nvme/nvme_ctrlr.c
index 1ddf9cc..7ed2f7e 100644
--- a/sys/dev/nvme/nvme_ctrlr.c
+++ b/sys/dev/nvme/nvme_ctrlr.c
@@ -131,8 +131,8 @@ nvme_ctrlr_setup_chatham(struct nvme_controller *ctrlr)
ctrlr->chatham_lbas = chatham_read_4(ctrlr, 0x8068) - 0x110;
ctrlr->chatham_size = ctrlr->chatham_lbas * 512;
- device_printf(ctrlr->dev, "Chatham size: %lld\n",
- (long long)ctrlr->chatham_size);
+ device_printf(ctrlr->dev, "Chatham size: %jd\n",
+ (intmax_t)ctrlr->chatham_size);
reg1 = reg2 = reg3 = ctrlr->chatham_size - 1;
diff --git a/sys/dev/oce/oce_hw.c b/sys/dev/oce/oce_hw.c
index e68ba7a..274c4d1 100644
--- a/sys/dev/oce/oce_hw.c
+++ b/sys/dev/oce/oce_hw.c
@@ -405,11 +405,6 @@ oce_create_nw_interface(POCE_SOFTC sc)
sc->if_cap_flags = capab_en_flags;
- /* Enable VLAN Promisc on HW */
- rc = oce_config_vlan(sc, (uint8_t) sc->if_id, NULL, 0, 1, 1);
- if (rc)
- goto error;
-
/* set default flow control */
rc = oce_set_flow_control(sc, sc->flow_control);
if (rc)
@@ -477,12 +472,9 @@ oce_hw_start(POCE_SOFTC sc)
return 1;
if (link.logical_link_status == NTWK_LOGICAL_LINK_UP) {
- sc->ifp->if_drv_flags |= IFF_DRV_RUNNING;
sc->link_status = NTWK_LOGICAL_LINK_UP;
if_link_state_change(sc->ifp, LINK_STATE_UP);
} else {
- sc->ifp->if_drv_flags &=
- ~(IFF_DRV_RUNNING | IFF_DRV_OACTIVE);
sc->link_status = NTWK_LOGICAL_LINK_DOWN;
if_link_state_change(sc->ifp, LINK_STATE_DOWN);
}
diff --git a/sys/dev/oce/oce_hw.h b/sys/dev/oce/oce_hw.h
index 0e79218..aac0a8a 100644
--- a/sys/dev/oce/oce_hw.h
+++ b/sys/dev/oce/oce_hw.h
@@ -38,6 +38,8 @@
/* $FreeBSD$ */
+/* $FreeBSD$ */
+
#include <sys/types.h>
#undef _BIG_ENDIAN /* TODO */
@@ -155,7 +157,10 @@
#define ASYNC_EVENT_LINK_UP 0x1
#define ASYNC_EVENT_LINK_DOWN 0x0
#define ASYNC_EVENT_GRP5 0x5
+#define ASYNC_EVENT_CODE_DEBUG 0x6
#define ASYNC_EVENT_PVID_STATE 0x3
+#define ASYNC_EVENT_DEBUG_QNQ 0x1
+#define ASYNC_EVENT_CODE_SLIPORT 0x11
#define VLAN_VID_MASK 0x0FFF
/* port link_status */
@@ -707,6 +712,17 @@ struct oce_async_event_grp5_pvid_state {
uint32_t code;
};
+/* async event indicating outer VLAN tag in QnQ */
+struct oce_async_event_qnq {
+ uint8_t valid; /* Indicates if outer VLAN is valid */
+ uint8_t rsvd0;
+ uint16_t vlan_tag;
+ uint32_t event_tag;
+ uint8_t rsvd1[4];
+ uint32_t code;
+} ;
+
+
typedef union oce_mq_ext_ctx_u {
uint32_t dw[6];
struct {
@@ -750,6 +766,44 @@ typedef union oce_mq_ext_ctx_u {
/* dw5 */
uint32_t dw8rsvd1;
} v0;
+ struct {
+ #ifdef _BIG_ENDIAN
+ /* dw0 */
+ uint32_t cq_id:16;
+ uint32_t num_pages:16;
+ /* dw1 */
+ uint32_t async_evt_bitmap;
+ /* dw2 */
+ uint32_t dw5rsvd2:12;
+ uint32_t ring_size:4;
+ uint32_t async_cq_id:16;
+ /* dw3 */
+ uint32_t valid:1;
+ uint32_t dw6rsvd1:31;
+ /* dw4 */
+ uint32_t dw7rsvd1:31;
+ uint32_t async_cq_valid:1;
+ #else
+ /* dw0 */
+ uint32_t num_pages:16;
+ uint32_t cq_id:16;
+ /* dw1 */
+ uint32_t async_evt_bitmap;
+ /* dw2 */
+ uint32_t async_cq_id:16;
+ uint32_t ring_size:4;
+ uint32_t dw5rsvd2:12;
+ /* dw3 */
+ uint32_t dw6rsvd1:31;
+ uint32_t valid:1;
+ /* dw4 */
+ uint32_t async_cq_valid:1;
+ uint32_t dw7rsvd1:31;
+ #endif
+ /* dw5 */
+ uint32_t dw8rsvd1;
+ } v1;
+
} oce_mq_ext_ctx_t;
@@ -826,6 +880,7 @@ enum COMMON_SUBSYSTEM_OPCODES {
OPCODE_COMMON_SET_BEACON_CONFIG = 69,
OPCODE_COMMON_GET_BEACON_CONFIG = 70,
OPCODE_COMMON_GET_PHYSICAL_LINK_CONFIG = 71,
+ OPCODE_COMMON_READ_TRANSRECEIVER_DATA = 73,
OPCODE_COMMON_GET_OEM_ATTRIBUTES = 76,
OPCODE_COMMON_GET_PORT_NAME = 77,
OPCODE_COMMON_GET_CONFIG_SIGNATURE = 78,
@@ -1724,6 +1779,12 @@ struct mbx_set_common_iface_rx_filter {
} params;
};
+struct be_set_eqd {
+ uint32_t eq_id;
+ uint32_t phase;
+ uint32_t dm;
+};
+
/* [41] OPCODE_COMMON_MODIFY_EQ_DELAY */
struct mbx_modify_common_eq_delay {
struct mbx_hdr hdr;
@@ -1743,6 +1804,76 @@ struct mbx_modify_common_eq_delay {
} params;
};
+/* [32] OPCODE_COMMON_GET_CNTL_ATTRIBUTES */
+
+struct mgmt_hba_attr {
+ int8_t flashrom_ver_str[32];
+ int8_t manufac_name[32];
+ uint32_t supp_modes;
+ int8_t seeprom_ver_lo;
+ int8_t seeprom_ver_hi;
+ int8_t rsvd0[2];
+ uint32_t ioctl_data_struct_ver;
+ uint32_t ep_fw_data_struct_ver;
+ uint8_t ncsi_ver_str[12];
+ uint32_t def_ext_to;
+ int8_t cntl_mod_num[32];
+ int8_t cntl_desc[64];
+ int8_t cntl_ser_num[32];
+ int8_t ip_ver_str[32];
+ int8_t fw_ver_str[32];
+ int8_t bios_ver_str[32];
+ int8_t redboot_ver_str[32];
+ int8_t drv_ver_str[32];
+ int8_t fw_on_flash_ver_str[32];
+ uint32_t funcs_supp;
+ uint16_t max_cdblen;
+ uint8_t asic_rev;
+ uint8_t gen_guid[16];
+ uint8_t hba_port_count;
+ uint16_t default_link_down_timeout;
+ uint8_t iscsi_ver_min_max;
+ uint8_t multifunc_dev;
+ uint8_t cache_valid;
+ uint8_t hba_status;
+ uint8_t max_domains_supp;
+ uint8_t phy_port;
+ uint32_t fw_post_status;
+ uint32_t hba_mtu[8];
+ uint8_t iSCSI_feat;
+ uint8_t asic_gen;
+ uint8_t future_u8[2];
+ uint32_t future_u32[3];
+};
+
+struct mgmt_cntl_attr {
+ struct mgmt_hba_attr hba_attr;
+ uint16_t pci_vendor_id;
+ uint16_t pci_device_id;
+ uint16_t pci_sub_vendor_id;
+ uint16_t pci_sub_system_id;
+ uint8_t pci_bus_num;
+ uint8_t pci_dev_num;
+ uint8_t pci_func_num;
+ uint8_t interface_type;
+ uint64_t unique_id;
+ uint8_t netfilters;
+ uint8_t rsvd0[3];
+ uint32_t future_u32[4];
+};
+
+struct mbx_common_get_cntl_attr {
+ struct mbx_hdr hdr;
+ union {
+ struct {
+ uint32_t rsvd0;
+ } req;
+ struct {
+ struct mgmt_cntl_attr cntl_attr_info;
+ } rsp;
+ } params;
+};
+
/* [59] OPCODE_ADD_COMMON_IFACE_MAC */
struct mbx_add_common_iface_mac {
struct mbx_hdr hdr;
@@ -1785,6 +1916,23 @@ struct ioctl_common_function_reset {
struct mbx_hdr hdr;
};
+/* [73] OPCODE_COMMON_READ_TRANSRECEIVER_DATA */
+struct mbx_read_common_transrecv_data {
+ struct mbx_hdr hdr;
+ union {
+ struct {
+ uint32_t page_num;
+ uint32_t port;
+ } req;
+ struct {
+ uint32_t page_num;
+ uint32_t port;
+ uint32_t page_data[32];
+ } rsp;
+ } params;
+
+};
+
/* [80] OPCODE_COMMON_FUNCTION_LINK_CONFIG */
struct mbx_common_func_link_cfg {
struct mbx_hdr hdr;
@@ -2110,7 +2258,9 @@ enum RSS_ENABLE_FLAGS {
RSS_ENABLE_IPV4 = 0x1, /* (IPV4 HASH enabled ) */
RSS_ENABLE_TCP_IPV4 = 0x2, /* (TCP IPV4 Hash enabled) */
RSS_ENABLE_IPV6 = 0x4, /* (IPV6 HASH enabled) */
- RSS_ENABLE_TCP_IPV6 = 0x8 /* (TCP IPV6 HASH */
+ RSS_ENABLE_TCP_IPV6 = 0x8, /* (TCP IPV6 HASH */
+ RSS_ENABLE_UDP_IPV4 = 0x10, /* UDP IPV4 HASH */
+ RSS_ENABLE_UDP_IPV6 = 0x20 /* UDP IPV6 HASH */
};
#define RSS_ENABLE (RSS_ENABLE_IPV4 | RSS_ENABLE_TCP_IPV4)
#define RSS_DISABLE RSS_ENABLE_NONE
diff --git a/sys/dev/oce/oce_if.c b/sys/dev/oce/oce_if.c
index 426acd9..48cdb16 100644
--- a/sys/dev/oce/oce_if.c
+++ b/sys/dev/oce/oce_if.c
@@ -36,6 +36,7 @@
* Costa Mesa, CA 92626
*/
+
/* $FreeBSD$ */
#include "opt_inet6.h"
@@ -94,7 +95,8 @@ static void setup_max_queues_want(POCE_SOFTC sc);
static void update_queues_got(POCE_SOFTC sc);
static void process_link_state(POCE_SOFTC sc,
struct oce_async_cqe_link_state *acqe);
-
+static int oce_tx_asic_stall_verify(POCE_SOFTC sc, struct mbuf *m);
+static struct mbuf *oce_insert_vlan_tag(POCE_SOFTC sc, struct mbuf *m, boolean_t *complete);
/* IP specific */
#if defined(INET6) || defined(INET)
@@ -266,8 +268,6 @@ oce_attach(device_t dev)
rc = callout_reset(&sc->timer, 2 * hz, oce_local_timer, sc);
if (rc)
goto stats_free;
-#ifdef DEV_NETMAP
-#endif /* DEV_NETMAP */
return 0;
@@ -485,7 +485,7 @@ oce_multiq_start(struct ifnet *ifp, struct mbuf *m)
struct oce_wq *wq = NULL;
int queue_index = 0;
int status = 0;
-
+
if ((m->m_flags & M_FLOWID) != 0)
queue_index = m->m_pkthdr.flowid % sc->nwqs;
@@ -568,6 +568,7 @@ oce_intr(void *arg, int pending)
eq_arm:
oce_arm_eq(sc, eq->eq_id, 0, TRUE, FALSE);
+
return;
}
@@ -633,6 +634,8 @@ oce_fast_isr(void *arg)
taskqueue_enqueue_fast(ii->tq, &ii->task);
+ ii->eq->intr++;
+
return FILTER_HANDLED;
}
@@ -780,6 +783,7 @@ oce_tx(POCE_SOFTC sc, struct mbuf **mpp, int wq_index)
struct oce_nic_frag_wqe *nicfrag;
int num_wqes;
uint32_t reg_value;
+ boolean_t complete = TRUE;
m = *mpp;
if (!m)
@@ -790,6 +794,15 @@ oce_tx(POCE_SOFTC sc, struct mbuf **mpp, int wq_index)
goto free_ret;
}
+ if(oce_tx_asic_stall_verify(sc, m)) {
+ m = oce_insert_vlan_tag(sc, m, &complete);
+ if(!m) {
+ device_printf(sc->dev, "Insertion unsuccessful\n");
+ return 0;
+ }
+
+ }
+
if (m->m_pkthdr.csum_flags & CSUM_TSO) {
/* consolidate packet buffers for TSO/LSO segment offload */
#if defined(INET6) || defined(INET)
@@ -837,15 +850,15 @@ retry:
nichdr->u0.dw[2] = 0;
nichdr->u0.dw[3] = 0;
- nichdr->u0.s.complete = 1;
+ nichdr->u0.s.complete = complete;
nichdr->u0.s.event = 1;
nichdr->u0.s.crc = 1;
nichdr->u0.s.forward = 0;
nichdr->u0.s.ipcs = (m->m_pkthdr.csum_flags & CSUM_IP) ? 1 : 0;
nichdr->u0.s.udpcs =
- (m->m_pkthdr.csum_flags & CSUM_UDP) ? 1 : 0;
+ (m->m_pkthdr.csum_flags & CSUM_UDP) ? 1 : 0;
nichdr->u0.s.tcpcs =
- (m->m_pkthdr.csum_flags & CSUM_TCP) ? 1 : 0;
+ (m->m_pkthdr.csum_flags & CSUM_TCP) ? 1 : 0;
nichdr->u0.s.num_wqe = num_wqes;
nichdr->u0.s.total_length = m->m_pkthdr.len;
if (m->m_flags & M_VLANTAG) {
@@ -895,7 +908,7 @@ retry:
wq->tx_stats.tx_wrbs += num_wqes;
wq->tx_stats.tx_bytes += m->m_pkthdr.len;
wq->tx_stats.tx_pkts++;
-
+
bus_dmamap_sync(wq->ring->dma.tag, wq->ring->dma.map,
BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE);
reg_value = (num_wqes << 16) | wq->wq_id;
@@ -1081,6 +1094,9 @@ oce_start(struct ifnet *ifp)
if ((ifp->if_drv_flags & (IFF_DRV_RUNNING | IFF_DRV_OACTIVE)) !=
IFF_DRV_RUNNING)
return;
+
+ if (!sc->link_status)
+ return;
do {
IF_DEQUEUE(&sc->ifp->if_snd, m);
@@ -1303,7 +1319,6 @@ oce_rx(struct oce_rq *rq, uint32_t rqe_idx, struct oce_nic_rx_cqe *cqe)
#if defined(INET6) || defined(INET)
/* Try to queue to LRO */
if (IF_LRO_ENABLED(sc) &&
- !(m->m_flags & M_VLANTAG) &&
(cqe->u0.s.ip_cksum_pass) &&
(cqe->u0.s.l4_cksum_pass) &&
(!cqe->u0.s.ip_ver) &&
@@ -1343,13 +1358,6 @@ oce_discard_rx_comp(struct oce_rq *rq, struct oce_nic_rx_cqe *cqe)
POCE_SOFTC sc = (POCE_SOFTC) rq->parent;
int num_frags = cqe->u0.s.num_fragments;
- if (IS_XE201(sc) && cqe->u0.s.error) {
- /* Lancer A0 workaround
- * num_frags will be 1 more than actual in case of error
- */
- if (num_frags)
- num_frags -= 1;
- }
for (i = 0; i < num_frags; i++) {
if (rq->packets_out == rq->packets_in) {
device_printf(sc->dev,
@@ -1458,7 +1466,7 @@ oce_free_lro(POCE_SOFTC sc)
tcp_lro_free(lro);
}
}
-#endif /* INET6 || INET */
+#endif
int
oce_alloc_rx_bufs(struct oce_rq *rq, int count)
@@ -1471,7 +1479,7 @@ oce_alloc_rx_bufs(struct oce_rq *rq, int count)
struct oce_nic_rqe *rqe;
pd_rxulp_db_t rxdb_reg;
-
+ bzero(&rxdb_reg, sizeof(pd_rxulp_db_t));
for (i = 0; i < count; i++) {
in = rq->packets_in + 1;
if (in == OCE_RQ_PACKET_ARRAY_SIZE)
@@ -1512,14 +1520,12 @@ oce_alloc_rx_bufs(struct oce_rq *rq, int count)
}
if (added != 0) {
for (i = added / OCE_MAX_RQ_POSTS; i > 0; i--) {
- DELAY(1);
rxdb_reg.bits.num_posted = OCE_MAX_RQ_POSTS;
rxdb_reg.bits.qid = rq->rq_id;
OCE_WRITE_REG32(sc, db, PD_RXULP_DB, rxdb_reg.dw0);
added -= OCE_MAX_RQ_POSTS;
}
if (added > 0) {
- DELAY(1);
rxdb_reg.bits.qid = rq->rq_id;
rxdb_reg.bits.num_posted = added;
OCE_WRITE_REG32(sc, db, PD_RXULP_DB, rxdb_reg.dw0);
@@ -1554,13 +1560,8 @@ oce_rq_handler(void *arg)
} else {
rq->rx_stats.rxcp_err++;
sc->ifp->if_ierrors++;
- if (IS_XE201(sc))
- /* Lancer A0 no buffer workaround */
- oce_discard_rx_comp(rq, cqe);
- else
- /* Post L3/L4 errors to stack.*/
- oce_rx(rq, cqe->u0.s.frag_index, cqe);
-
+ /* Post L3/L4 errors to stack.*/
+ oce_rx(rq, cqe->u0.s.frag_index, cqe);
}
rq->rx_stats.rx_compl++;
cqe->u0.dw[2] = 0;
@@ -1757,18 +1758,18 @@ oce_handle_passthrough(struct ifnet *ifp, caddr_t data)
uint32_t req_size;
struct mbx_hdr req;
OCE_DMA_MEM dma_mem;
-
+ struct mbx_common_get_cntl_attr *fw_cmd;
if (copyin(priv_data, cookie, strlen(IOCTL_COOKIE)))
return EFAULT;
-
+
if (memcmp(cookie, IOCTL_COOKIE, strlen(IOCTL_COOKIE)))
return EINVAL;
-
+
ioctl_ptr = (char *)priv_data + strlen(IOCTL_COOKIE);
if (copyin(ioctl_ptr, &req, sizeof(struct mbx_hdr)))
return EFAULT;
-
+
req_size = le32toh(req.u0.req.request_length);
if (req_size > 65536)
return EINVAL;
@@ -1792,12 +1793,86 @@ oce_handle_passthrough(struct ifnet *ifp, caddr_t data)
if (copyout(OCE_DMAPTR(&dma_mem,char), ioctl_ptr, req_size))
rc = EFAULT;
+ /*
+ firmware is filling all the attributes for this ioctl except
+ the driver version..so fill it
+ */
+ if(req.u0.rsp.opcode == OPCODE_COMMON_GET_CNTL_ATTRIBUTES) {
+ fw_cmd = (struct mbx_common_get_cntl_attr *) ioctl_ptr;
+ strncpy(fw_cmd->params.rsp.cntl_attr_info.hba_attr.drv_ver_str,
+ COMPONENT_REVISION, strlen(COMPONENT_REVISION));
+ }
+
dma_free:
oce_dma_free(sc, &dma_mem);
return rc;
}
+static void
+oce_eqd_set_periodic(POCE_SOFTC sc)
+{
+ struct oce_set_eqd set_eqd[OCE_MAX_EQ];
+ struct oce_aic_obj *aic;
+ struct oce_eq *eqo;
+ uint64_t now = 0, delta;
+ int eqd, i, num = 0;
+ uint32_t ips = 0;
+ int tps;
+
+ for (i = 0 ; i < sc->neqs; i++) {
+ eqo = sc->eq[i];
+ aic = &sc->aic_obj[i];
+ /* When setting the static eq delay from the user space */
+ if (!aic->enable) {
+ eqd = aic->et_eqd;
+ goto modify_eqd;
+ }
+
+ now = ticks;
+
+ /* Over flow check */
+ if ((now < aic->ticks) || (eqo->intr < aic->intr_prev))
+ goto done;
+
+ delta = now - aic->ticks;
+ tps = delta/hz;
+
+ /* Interrupt rate based on elapsed ticks */
+ if(tps)
+ ips = (uint32_t)(eqo->intr - aic->intr_prev) / tps;
+
+ if (ips > INTR_RATE_HWM)
+ eqd = aic->cur_eqd + 20;
+ else if (ips < INTR_RATE_LWM)
+ eqd = aic->cur_eqd / 2;
+ else
+ goto done;
+
+ if (eqd < 10)
+ eqd = 0;
+
+ /* Make sure that the eq delay is in the known range */
+ eqd = min(eqd, aic->max_eqd);
+ eqd = max(eqd, aic->min_eqd);
+
+modify_eqd:
+ if (eqd != aic->cur_eqd) {
+ set_eqd[num].delay_multiplier = (eqd * 65)/100;
+ set_eqd[num].eq_id = eqo->eq_id;
+ aic->cur_eqd = eqd;
+ num++;
+ }
+done:
+ aic->intr_prev = eqo->intr;
+ aic->ticks = now;
+ }
+
+ /* Is there atleast one eq that needs to be modified? */
+ if(num)
+ oce_mbox_eqd_modify_periodic(sc, set_eqd, num);
+
+}
static void
oce_local_timer(void *arg)
@@ -1813,6 +1888,10 @@ oce_local_timer(void *arg)
for (i = 0; i < sc->nwqs; i++)
oce_tx_restart(sc, sc->wq[i]);
+ /* calculate and set the eq delay for optimal interrupt rate */
+ if (IS_BE(sc))
+ oce_eqd_set_periodic(sc);
+
callout_reset(&sc->timer, hz, oce_local_timer, sc);
}
@@ -1849,17 +1928,17 @@ oce_if_deactivate(POCE_SOFTC sc)
/* Stop intrs and finish any bottom halves pending */
oce_hw_intr_disable(sc);
- /* Since taskqueue_drain takes a Giant Lock, We should not acquire
- any other lock. So unlock device lock and require after
- completing taskqueue_drain.
- */
- UNLOCK(&sc->dev_lock);
+ /* Since taskqueue_drain takes a Gaint Lock, We should not acquire
+ any other lock. So unlock device lock and require after
+ completing taskqueue_drain.
+ */
+ UNLOCK(&sc->dev_lock);
for (i = 0; i < sc->intr_count; i++) {
if (sc->intrs[i].tq != NULL) {
taskqueue_drain(sc->intrs[i].tq, &sc->intrs[i].task);
}
}
- LOCK(&sc->dev_lock);
+ LOCK(&sc->dev_lock);
/* Delete RX queue in card with flush param */
oce_stop_rx(sc);
@@ -1874,7 +1953,7 @@ oce_if_deactivate(POCE_SOFTC sc)
/* But still we need to get MCC aync events.
So enable intrs and also arm first EQ
- */
+ */
oce_hw_intr_enable(sc);
oce_arm_eq(sc, sc->eq[0]->eq_id, 0, TRUE, FALSE);
@@ -1947,6 +2026,7 @@ oce_mq_handler(void *arg)
struct oce_mq_cqe *cqe;
struct oce_async_cqe_link_state *acqe;
struct oce_async_event_grp5_pvid_state *gcqe;
+ struct oce_async_event_qnq *dbgcqe;
bus_dmamap_sync(cq->ring->dma.tag,
@@ -1973,6 +2053,14 @@ oce_mq_handler(void *arg)
sc->pvid = 0;
}
+ else if(evt_type == ASYNC_EVENT_CODE_DEBUG &&
+ optype == ASYNC_EVENT_DEBUG_QNQ) {
+ dbgcqe =
+ (struct oce_async_event_qnq *)cqe;
+ if(dbgcqe->valid)
+ sc->qnqid = dbgcqe->vlan_tag;
+ sc->qnq_debug_event = TRUE;
+ }
}
cqe->u0.dw[3] = 0;
RING_GET(cq->ring, 1);
@@ -2032,3 +2120,79 @@ update_queues_got(POCE_SOFTC sc)
}
}
+static int
+oce_check_ipv6_ext_hdr(struct mbuf *m)
+{
+ struct ether_header *eh = mtod(m, struct ether_header *);
+ caddr_t m_datatemp = m->m_data;
+
+ if (eh->ether_type == htons(ETHERTYPE_IPV6)) {
+ m->m_data += sizeof(struct ether_header);
+ struct ip6_hdr *ip6 = mtod(m, struct ip6_hdr *);
+
+ if((ip6->ip6_nxt != IPPROTO_TCP) && \
+ (ip6->ip6_nxt != IPPROTO_UDP)){
+ struct ip6_ext *ip6e = NULL;
+ m->m_data += sizeof(struct ip6_hdr);
+
+ ip6e = (struct ip6_ext *) mtod(m, struct ip6_ext *);
+ if(ip6e->ip6e_len == 0xff) {
+ m->m_data = m_datatemp;
+ return TRUE;
+ }
+ }
+ m->m_data = m_datatemp;
+ }
+ return FALSE;
+}
+
+static int
+is_be3_a1(POCE_SOFTC sc)
+{
+ if((sc->flags & OCE_FLAGS_BE3) && ((sc->asic_revision & 0xFF) < 2)) {
+ return TRUE;
+ }
+ return FALSE;
+}
+
+static struct mbuf *
+oce_insert_vlan_tag(POCE_SOFTC sc, struct mbuf *m, boolean_t *complete)
+{
+ uint16_t vlan_tag = 0;
+
+ if(!M_WRITABLE(m))
+ return NULL;
+
+ /* Embed vlan tag in the packet if it is not part of it */
+ if(m->m_flags & M_VLANTAG) {
+ vlan_tag = EVL_VLANOFTAG(m->m_pkthdr.ether_vtag);
+ m->m_flags &= ~M_VLANTAG;
+ }
+
+ /* if UMC, ignore vlan tag insertion and instead insert pvid */
+ if(sc->pvid) {
+ if(!vlan_tag)
+ vlan_tag = sc->pvid;
+ *complete = FALSE;
+ }
+
+ if(vlan_tag) {
+ m = ether_vlanencap(m, vlan_tag);
+ }
+
+ if(sc->qnqid) {
+ m = ether_vlanencap(m, sc->qnqid);
+ *complete = FALSE;
+ }
+ return m;
+}
+
+static int
+oce_tx_asic_stall_verify(POCE_SOFTC sc, struct mbuf *m)
+{
+ if(is_be3_a1(sc) && IS_QNQ_OR_UMC(sc) && \
+ oce_check_ipv6_ext_hdr(m)) {
+ return TRUE;
+ }
+ return FALSE;
+}
diff --git a/sys/dev/oce/oce_if.h b/sys/dev/oce/oce_if.h
index 6428f88..ee684bd 100644
--- a/sys/dev/oce/oce_if.h
+++ b/sys/dev/oce/oce_if.h
@@ -36,6 +36,7 @@
* Costa Mesa, CA 92626
*/
+
/* $FreeBSD$ */
#include <sys/param.h>
@@ -87,9 +88,7 @@
#include "oce_hw.h"
-/* OCE device driver module component revision informaiton */
-#define COMPONENT_REVISION "4.2.127.0"
-
+#define COMPONENT_REVISION "4.6.95.0"
/* OCE devices supported by this driver */
#define PCI_VENDOR_EMULEX 0x10df /* Emulex */
@@ -132,7 +131,7 @@ extern int mp_ncpus; /* system's total active cpu cores */
#define OCE_RQ_BUF_SIZE 2048
#define OCE_LSO_MAX_SIZE (64 * 1024)
#define LONG_TIMEOUT 30
-#define OCE_MAX_JUMBO_FRAME_SIZE 16360
+#define OCE_MAX_JUMBO_FRAME_SIZE 9018
#define OCE_MAX_MTU (OCE_MAX_JUMBO_FRAME_SIZE - \
ETHER_VLAN_ENCAP_LEN - \
ETHER_HDR_LEN)
@@ -481,7 +480,27 @@ struct oce_drv_stats {
} u0;
};
+#define INTR_RATE_HWM 15000
+#define INTR_RATE_LWM 10000
+
+#define OCE_MAX_EQD 128u
+#define OCE_MIN_EQD 50u
+
+struct oce_set_eqd {
+ uint32_t eq_id;
+ uint32_t phase;
+ uint32_t delay_multiplier;
+};
+struct oce_aic_obj { /* Adaptive interrupt coalescing (AIC) info */
+ boolean_t enable;
+ uint32_t min_eqd; /* in usecs */
+ uint32_t max_eqd; /* in usecs */
+ uint32_t cur_eqd; /* in usecs */
+ uint32_t et_eqd; /* configured value when aic is off */
+ uint64_t ticks;
+ uint64_t intr_prev;
+};
#define MAX_LOCK_DESC_LEN 32
struct oce_lock {
@@ -565,6 +584,7 @@ struct oce_eq {
int cq_valid;
struct eq_config eq_cfg;
int vector;
+ uint64_t intr;
};
enum cq_len {
@@ -827,6 +847,9 @@ typedef struct oce_softc {
uint32_t flow_control;
uint32_t promisc;
+
+ struct oce_aic_obj aic_obj[OCE_MAX_EQ];
+
/*Vlan Filtering related */
eventhandler_tag vlan_attach;
eventhandler_tag vlan_detach;
@@ -837,7 +860,9 @@ typedef struct oce_softc {
struct oce_drv_stats oce_stats_info;
struct callout timer;
int8_t be3_native;
- uint32_t pvid;
+ uint16_t qnq_debug_event;
+ uint16_t qnqid;
+ uint16_t pvid;
} OCE_SOFTC, *POCE_SOFTC;
@@ -996,6 +1021,9 @@ int oce_mbox_create_wq(struct oce_wq *wq);
int oce_mbox_create_eq(struct oce_eq *eq);
int oce_mbox_cq_create(struct oce_cq *cq, uint32_t ncoalesce,
uint32_t is_eventable);
+int oce_mbox_read_transrecv_data(POCE_SOFTC sc, uint32_t page_num);
+void oce_mbox_eqd_modify_periodic(POCE_SOFTC sc, struct oce_set_eqd *set_eqd,
+ int num);
void mbx_common_req_hdr_init(struct mbx_hdr *hdr,
uint8_t dom,
uint8_t port,
@@ -1076,3 +1104,12 @@ static inline uint32_t oce_highbit(uint32_t x)
return 0;
}
+#define TRANSCEIVER_DATA_NUM_ELE 64
+#define TRANSCEIVER_DATA_SIZE 256
+#define TRANSCEIVER_A0_SIZE 128
+#define TRANSCEIVER_A2_SIZE 128
+#define PAGE_NUM_A0 0xa0
+#define PAGE_NUM_A2 0xa2
+#define IS_QNQ_OR_UMC(sc) ((sc->pvid && (sc->function_mode & FNM_UMC_MODE ))\
+ || (sc->qnqid && (sc->function_mode & FNM_FLEX10_MODE)))
+
diff --git a/sys/dev/oce/oce_mbox.c b/sys/dev/oce/oce_mbox.c
index 07107a2..2db5934 100644
--- a/sys/dev/oce/oce_mbox.c
+++ b/sys/dev/oce/oce_mbox.c
@@ -37,10 +37,12 @@
*/
+
/* $FreeBSD$ */
-#include "oce_if.h"
+#include "oce_if.h"
+extern uint32_t sfp_vpd_dump_buffer[TRANSCEIVER_DATA_NUM_ELE];
/**
* @brief Reset (firmware) common function
@@ -276,12 +278,17 @@ oce_get_fw_version(POCE_SOFTC sc)
DW_SWAP(u32ptr(&mbx), mbx.payload_length + OCE_BMBX_RHDR_SZ);
ret = oce_mbox_post(sc, &mbx, NULL);
- if (ret)
- return ret;
+ if (!ret)
+ ret = fwcmd->hdr.u0.rsp.status;
+ if (ret) {
+ device_printf(sc->dev,"%s failed - cmd status: %d\n",
+ __FUNCTION__, ret);
+ goto error;
+ }
bcopy(fwcmd->params.rsp.fw_ver_str, sc->fw_version, 32);
-
- return 0;
+error:
+ return ret;
}
@@ -428,15 +435,20 @@ oce_read_mac_addr(POCE_SOFTC sc, uint32_t if_id,
DW_SWAP(u32ptr(&mbx), mbx.payload_length + OCE_BMBX_RHDR_SZ);
ret = oce_mbox_post(sc, &mbx, NULL);
- if (ret)
- return ret;
+ if (!ret)
+ ret = fwcmd->hdr.u0.rsp.status;
+ if (ret) {
+ device_printf(sc->dev,"%s failed - cmd status: %d\n",
+ __FUNCTION__, ret);
+ goto error;
+ }
/* copy the mac addres in the output parameter */
mac->size_of_struct = fwcmd->params.rsp.mac.size_of_struct;
bcopy(&fwcmd->params.rsp.mac.mac_addr[0], &mac->mac_addr[0],
mac->size_of_struct);
-
- return 0;
+error:
+ return ret;
}
/**
@@ -466,8 +478,13 @@ oce_get_fw_config(POCE_SOFTC sc)
DW_SWAP(u32ptr(&mbx), mbx.payload_length + OCE_BMBX_RHDR_SZ);
ret = oce_mbox_post(sc, &mbx, NULL);
- if (ret)
- return ret;
+ if (!ret)
+ ret = fwcmd->hdr.u0.rsp.status;
+ if (ret) {
+ device_printf(sc->dev,"%s failed - cmd status: %d\n",
+ __FUNCTION__, ret);
+ goto error;
+ }
DW_SWAP(u32ptr(fwcmd), sizeof(struct mbx_common_query_fw_config));
@@ -485,7 +502,8 @@ oce_get_fw_config(POCE_SOFTC sc)
sc->max_rx_rings = fwcmd->params.rsp.ulp[1].lro_rqid_tot;
}
- return 0;
+error:
+ return ret;
}
@@ -540,15 +558,20 @@ oce_if_create(POCE_SOFTC sc,
DW_SWAP(u32ptr(&mbx), OCE_BMBX_RHDR_SZ);
rc = oce_mbox_post(sc, &mbx, NULL);
- if (rc)
- return rc;
+ if (!rc)
+ rc = fwcmd->hdr.u0.rsp.status;
+ if (rc) {
+ device_printf(sc->dev,"%s failed - cmd status: %d\n",
+ __FUNCTION__, rc);
+ goto error;
+ }
*if_id = LE_32(fwcmd->params.rsp.if_id);
if (mac_addr != NULL)
sc->pmac_id = LE_32(fwcmd->params.rsp.pmac_id);
-
- return 0;
+error:
+ return rc;
}
/**
@@ -581,6 +604,11 @@ oce_if_del(POCE_SOFTC sc, uint32_t if_id)
DW_SWAP(u32ptr(&mbx), mbx.payload_length + OCE_BMBX_RHDR_SZ);
rc = oce_mbox_post(sc, &mbx, NULL);
+ if (!rc)
+ rc = fwcmd->hdr.u0.rsp.status;
+ if (rc)
+ device_printf(sc->dev,"%s failed - cmd status: %d\n",
+ __FUNCTION__, rc);
return rc;
}
@@ -628,8 +656,12 @@ oce_config_vlan(POCE_SOFTC sc,
DW_SWAP(u32ptr(&mbx), (OCE_BMBX_RHDR_SZ + mbx.payload_length));
rc = oce_mbox_post(sc, &mbx, NULL);
-
- return rc;
+ if (!rc)
+ rc = fwcmd->hdr.u0.rsp.status;
+ if (rc)
+ device_printf(sc->dev,"%s failed - cmd status: %d\n",
+ __FUNCTION__, rc);
+ return 0;
}
@@ -667,7 +699,11 @@ oce_set_flow_control(POCE_SOFTC sc, uint32_t flow_control)
DW_SWAP(u32ptr(&mbx), mbx.payload_length + OCE_BMBX_RHDR_SZ);
rc = oce_mbox_post(sc, &mbx, NULL);
-
+ if (!rc)
+ rc = fwcmd->hdr.u0.rsp.status;
+ if (rc)
+ device_printf(sc->dev,"%s failed - cmd status: %d\n",
+ __FUNCTION__, rc);
return rc;
}
@@ -726,20 +762,28 @@ oce_config_nic_rss(POCE_SOFTC sc, uint32_t if_id, uint16_t enable_rss)
struct oce_mbx mbx;
struct mbx_config_nic_rss *fwcmd =
(struct mbx_config_nic_rss *)&mbx.payload;
+ int version;
bzero(&mbx, sizeof(struct oce_mbx));
+ if (IS_XE201(sc)) {
+ version = OCE_MBX_VER_V1;
+ fwcmd->params.req.enable_rss = RSS_ENABLE_UDP_IPV4 |
+ RSS_ENABLE_UDP_IPV6;
+ } else
+ version = OCE_MBX_VER_V0;
+
mbx_common_req_hdr_init(&fwcmd->hdr, 0, 0,
MBX_SUBSYSTEM_NIC,
NIC_CONFIG_RSS,
MBX_TIMEOUT_SEC,
sizeof(struct mbx_config_nic_rss),
- OCE_MBX_VER_V0);
+ version);
if (enable_rss)
- fwcmd->params.req.enable_rss = (RSS_ENABLE_IPV4 |
- RSS_ENABLE_TCP_IPV4 |
- RSS_ENABLE_IPV6 |
- RSS_ENABLE_TCP_IPV6);
+ fwcmd->params.req.enable_rss |= (RSS_ENABLE_IPV4 |
+ RSS_ENABLE_TCP_IPV4 |
+ RSS_ENABLE_IPV6 |
+ RSS_ENABLE_TCP_IPV6);
fwcmd->params.req.flush = OCE_FLUSH;
fwcmd->params.req.if_id = LE_32(if_id);
@@ -753,9 +797,12 @@ oce_config_nic_rss(POCE_SOFTC sc, uint32_t if_id, uint16_t enable_rss)
DW_SWAP(u32ptr(&mbx), mbx.payload_length + OCE_BMBX_RHDR_SZ);
rc = oce_mbox_post(sc, &mbx, NULL);
-
+ if (!rc)
+ rc = fwcmd->hdr.u0.rsp.status;
+ if (rc)
+ device_printf(sc->dev,"%s failed - cmd status: %d\n",
+ __FUNCTION__, rc);
}
-
return rc;
}
@@ -834,7 +881,12 @@ oce_set_common_iface_rx_filter(POCE_SOFTC sc, POCE_DMA_MEM sgl)
DW_SWAP(u32ptr(&mbx), mbx.payload_length + OCE_BMBX_RHDR_SZ);
rc = oce_mbox_post(sc, &mbx, NULL);
- return rc;
+ if (!rc)
+ rc = fwcmd->hdr.u0.rsp.status;
+ if (rc)
+ device_printf(sc->dev,"%s failed - cmd status: %d\n",
+ __FUNCTION__, rc);
+ return 0;
}
/**
@@ -848,17 +900,19 @@ oce_get_link_status(POCE_SOFTC sc, struct link_status *link)
{
struct oce_mbx mbx;
struct mbx_query_common_link_config *fwcmd;
- int rc = 0;
+ int rc = 0, version;
bzero(&mbx, sizeof(struct oce_mbx));
+ IS_XE201(sc) ? (version = OCE_MBX_VER_V1) : (version = OCE_MBX_VER_V0);
+
fwcmd = (struct mbx_query_common_link_config *)&mbx.payload;
mbx_common_req_hdr_init(&fwcmd->hdr, 0, 0,
MBX_SUBSYSTEM_COMMON,
OPCODE_COMMON_QUERY_LINK_CONFIG,
MBX_TIMEOUT_SEC,
sizeof(struct mbx_query_common_link_config),
- OCE_MBX_VER_V0);
+ version);
mbx.u0.s.embedded = 1;
mbx.payload_length = sizeof(struct mbx_query_common_link_config);
@@ -866,15 +920,18 @@ oce_get_link_status(POCE_SOFTC sc, struct link_status *link)
rc = oce_mbox_post(sc, &mbx, NULL);
+ if (!rc)
+ rc = fwcmd->hdr.u0.rsp.status;
if (rc) {
- device_printf(sc->dev, "Could not get link speed: %d\n", rc);
- } else {
- /* interpret response */
- bcopy(&fwcmd->params.rsp, link, sizeof(struct link_status));
- link->logical_link_status = LE_32(link->logical_link_status);
- link->qos_link_speed = LE_16(link->qos_link_speed);
+ device_printf(sc->dev,"%s failed - cmd status: %d\n",
+ __FUNCTION__, rc);
+ goto error;
}
-
+ /* interpret response */
+ bcopy(&fwcmd->params.rsp, link, sizeof(struct link_status));
+ link->logical_link_status = LE_32(link->logical_link_status);
+ link->qos_link_speed = LE_16(link->qos_link_speed);
+error:
return rc;
}
@@ -916,11 +973,11 @@ oce_mbox_get_nic_stats_v0(POCE_SOFTC sc, POCE_DMA_MEM pstats_dma_mem)
oce_dma_sync(pstats_dma_mem, BUS_DMASYNC_POSTWRITE);
- if (rc) {
- device_printf(sc->dev,
- "Could not get nic statistics: %d\n", rc);
- }
-
+ if (!rc)
+ rc = fwcmd->hdr.u0.rsp.status;
+ if (rc)
+ device_printf(sc->dev,"%s failed - cmd status: %d\n",
+ __FUNCTION__, rc);
return rc;
}
@@ -966,10 +1023,11 @@ oce_mbox_get_nic_stats(POCE_SOFTC sc, POCE_DMA_MEM pstats_dma_mem)
rc = oce_mbox_post(sc, &mbx, NULL);
oce_dma_sync(pstats_dma_mem, BUS_DMASYNC_POSTWRITE);
- if (rc) {
- device_printf(sc->dev,
- "Could not get nic statistics: %d\n", rc);
- }
+ if (!rc)
+ rc = fwcmd->hdr.u0.rsp.status;
+ if (rc)
+ device_printf(sc->dev,"%s failed - cmd status: %d\n",
+ __FUNCTION__, rc);
return rc;
}
@@ -1001,7 +1059,7 @@ oce_mbox_get_pport_stats(POCE_SOFTC sc, POCE_DMA_MEM pstats_dma_mem,
OCE_MBX_VER_V0);
fwcmd->params.req.reset_stats = reset_stats;
- fwcmd->params.req.port_number = sc->if_id;
+ fwcmd->params.req.port_number = sc->port_id;
mbx.u0.s.embedded = 0; /* stats too large for embedded mbx rsp */
mbx.u0.s.sge_count = 1; /* using scatter gather instead */
@@ -1017,11 +1075,11 @@ oce_mbox_get_pport_stats(POCE_SOFTC sc, POCE_DMA_MEM pstats_dma_mem,
rc = oce_mbox_post(sc, &mbx, NULL);
oce_dma_sync(pstats_dma_mem, BUS_DMASYNC_POSTWRITE);
- if (rc != 0) {
- device_printf(sc->dev,
- "Could not get physical port statistics: %d\n", rc);
- }
-
+ if (!rc)
+ rc = fwcmd->hdr.u0.rsp.status;
+ if (rc)
+ device_printf(sc->dev,"%s failed - cmd status: %d\n",
+ __FUNCTION__, rc);
return rc;
}
@@ -1070,11 +1128,11 @@ oce_mbox_get_vport_stats(POCE_SOFTC sc, POCE_DMA_MEM pstats_dma_mem,
rc = oce_mbox_post(sc, &mbx, NULL);
oce_dma_sync(pstats_dma_mem, BUS_DMASYNC_POSTWRITE);
- if (rc != 0) {
- device_printf(sc->dev,
- "Could not get physical port statistics: %d\n", rc);
- }
-
+ if (!rc)
+ rc = fwcmd->hdr.u0.rsp.status;
+ if (rc)
+ device_printf(sc->dev,"%s failed - cmd status: %d\n",
+ __FUNCTION__, rc);
return rc;
}
@@ -1115,7 +1173,11 @@ oce_update_multicast(POCE_SOFTC sc, POCE_DMA_MEM pdma_mem)
DW_SWAP(u32ptr(&mbx), mbx.payload_length + OCE_BMBX_RHDR_SZ);
rc = oce_mbox_post(sc, &mbx, NULL);
-
+ if (!rc)
+ rc = req->hdr.u0.rsp.status;
+ if (rc)
+ device_printf(sc->dev,"%s failed - cmd status: %d\n",
+ __FUNCTION__, rc);
return rc;
}
@@ -1176,11 +1238,15 @@ oce_mbox_macaddr_add(POCE_SOFTC sc, uint8_t *mac_addr,
mbx.payload_length = sizeof(struct mbx_add_common_iface_mac);
DW_SWAP(u32ptr(&mbx), mbx.payload_length + OCE_BMBX_RHDR_SZ);
rc = oce_mbox_post(sc, &mbx, NULL);
- if (rc)
- return rc;
-
+ if (!rc)
+ rc = fwcmd->hdr.u0.rsp.status;
+ if (rc) {
+ device_printf(sc->dev,"%s failed - cmd status: %d\n",
+ __FUNCTION__, rc);
+ goto error;
+ }
*pmac_id = fwcmd->params.rsp.pmac_id;
-
+error:
return rc;
}
@@ -1210,6 +1276,11 @@ oce_mbox_macaddr_del(POCE_SOFTC sc, uint32_t if_id, uint32_t pmac_id)
DW_SWAP(u32ptr(&mbx), mbx.payload_length + OCE_BMBX_RHDR_SZ);
rc = oce_mbox_post(sc, &mbx, NULL);
+ if (!rc)
+ rc = fwcmd->hdr.u0.rsp.status;
+ if (rc)
+ device_printf(sc->dev,"%s failed - cmd status: %d\n",
+ __FUNCTION__, rc);
return rc;
}
@@ -1242,12 +1313,17 @@ oce_mbox_check_native_mode(POCE_SOFTC sc)
DW_SWAP(u32ptr(&mbx), mbx.payload_length + OCE_BMBX_RHDR_SZ);
rc = oce_mbox_post(sc, &mbx, NULL);
- //if (rc != 0) This can fail in legacy mode. So skip
- // FN_LEAVE(rc);
-
+ if (!rc)
+ rc = fwcmd->hdr.u0.rsp.status;
+ if (rc) {
+ device_printf(sc->dev,"%s failed - cmd status: %d\n",
+ __FUNCTION__, rc);
+ goto error;
+ }
sc->be3_native = fwcmd->params.rsp.capability_flags
& CAP_BE3_NATIVE_ERX_API;
+error:
return 0;
}
@@ -1282,6 +1358,11 @@ oce_mbox_cmd_set_loopback(POCE_SOFTC sc, uint8_t port_num,
DW_SWAP(u32ptr(&mbx), mbx.payload_length + OCE_BMBX_RHDR_SZ);
rc = oce_mbox_post(sc, &mbx, NULL);
+ if (!rc)
+ rc = fwcmd->hdr.u0.rsp.status;
+ if (rc)
+ device_printf(sc->dev,"%s failed - cmd status: %d\n",
+ __FUNCTION__, rc);
return rc;
@@ -1320,10 +1401,13 @@ oce_mbox_cmd_test_loopback(POCE_SOFTC sc, uint32_t port_num,
DW_SWAP(u32ptr(&mbx), mbx.payload_length + OCE_BMBX_RHDR_SZ);
rc = oce_mbox_post(sc, &mbx, NULL);
+ if (!rc)
+ rc = fwcmd->hdr.u0.rsp.status;
if (rc)
- return rc;
+ device_printf(sc->dev,"%s failed - cmd status: %d\n",
+ __FUNCTION__, rc);
- return(fwcmd->params.rsp.status);
+ return rc;
}
int
@@ -1362,11 +1446,11 @@ oce_mbox_write_flashrom(POCE_SOFTC sc, uint32_t optype,uint32_t opcode,
/* post the command */
rc = oce_mbox_post(sc, &mbx, NULL);
- if (rc) {
- device_printf(sc->dev, "Write FlashROM mbox post failed\n");
- } else {
- rc = fwcmd->hdr.u0.rsp.status;
- }
+ if (!rc)
+ rc = fwcmd->hdr.u0.rsp.status;
+ if (rc)
+ device_printf(sc->dev,"%s failed - cmd status: %d\n",
+ __FUNCTION__, rc);
return rc;
@@ -1408,12 +1492,15 @@ oce_mbox_get_flashrom_crc(POCE_SOFTC sc, uint8_t *flash_crc,
/* post the command */
rc = oce_mbox_post(sc, &mbx, NULL);
+ if (!rc)
+ rc = fwcmd->hdr.u0.rsp.status;
if (rc) {
- device_printf(sc->dev, "Read FlashROM CRC mbox post failed\n");
- } else {
- bcopy(fwcmd->data_buffer, flash_crc, 4);
- rc = fwcmd->hdr.u0.rsp.status;
+ device_printf(sc->dev,"%s failed - cmd status: %d\n",
+ __FUNCTION__, rc);
+ goto error;
}
+ bcopy(fwcmd->data_buffer, flash_crc, 4);
+error:
return rc;
}
@@ -1440,20 +1527,22 @@ oce_mbox_get_phy_info(POCE_SOFTC sc, struct oce_phy_info *phy_info)
/* now post the command */
rc = oce_mbox_post(sc, &mbx, NULL);
+ if (!rc)
+ rc = fwcmd->hdr.u0.rsp.status;
if (rc) {
- device_printf(sc->dev, "Read PHY info mbox post failed\n");
- } else {
- rc = fwcmd->hdr.u0.rsp.status;
- phy_info->phy_type = fwcmd->params.rsp.phy_info.phy_type;
- phy_info->interface_type =
- fwcmd->params.rsp.phy_info.interface_type;
- phy_info->auto_speeds_supported =
- fwcmd->params.rsp.phy_info.auto_speeds_supported;
- phy_info->fixed_speeds_supported =
- fwcmd->params.rsp.phy_info.fixed_speeds_supported;
- phy_info->misc_params =fwcmd->params.rsp.phy_info.misc_params;
-
+ device_printf(sc->dev,"%s failed - cmd status: %d\n",
+ __FUNCTION__, rc);
+ goto error;
}
+ phy_info->phy_type = fwcmd->params.rsp.phy_info.phy_type;
+ phy_info->interface_type =
+ fwcmd->params.rsp.phy_info.interface_type;
+ phy_info->auto_speeds_supported =
+ fwcmd->params.rsp.phy_info.auto_speeds_supported;
+ phy_info->fixed_speeds_supported =
+ fwcmd->params.rsp.phy_info.fixed_speeds_supported;
+ phy_info->misc_params =fwcmd->params.rsp.phy_info.misc_params;
+error:
return rc;
}
@@ -1499,14 +1588,16 @@ oce_mbox_lancer_write_flashrom(POCE_SOFTC sc, uint32_t data_size,
/* post the command */
rc = oce_mbox_post(sc, &mbx, NULL);
+ if (!rc)
+ rc = fwcmd->params.rsp.status;
if (rc) {
- device_printf(sc->dev,
- "Write Lancer FlashROM mbox post failed\n");
- } else {
- *written_data = fwcmd->params.rsp.actual_write_length;
- *additional_status = fwcmd->params.rsp.additional_status;
- rc = fwcmd->params.rsp.status;
+ device_printf(sc->dev,"%s failed - cmd status: %d\n",
+ __FUNCTION__, rc);
+ goto error;
}
+ *written_data = fwcmd->params.rsp.actual_write_length;
+ *additional_status = fwcmd->params.rsp.additional_status;
+error:
return rc;
}
@@ -1553,15 +1644,16 @@ oce_mbox_create_rq(struct oce_rq *rq)
mbx.payload_length = sizeof(struct mbx_create_nic_rq);
rc = oce_mbox_post(sc, &mbx, NULL);
- if (rc)
+ if (!rc)
+ rc = fwcmd->hdr.u0.rsp.status;
+ if (rc) {
+ device_printf(sc->dev,"%s failed - cmd status: %d\n",
+ __FUNCTION__, rc);
goto error;
-
+ }
rq->rq_id = fwcmd->params.rsp.rq_id;
rq->rss_cpuid = fwcmd->params.rsp.rss_cpuid;
-
- return 0;
error:
- device_printf(sc->dev, "Mbox Create RQ failed\n");
return rc;
}
@@ -1603,14 +1695,15 @@ oce_mbox_create_wq(struct oce_wq *wq)
mbx.payload_length = sizeof(struct mbx_create_nic_wq);
rc = oce_mbox_post(sc, &mbx, NULL);
- if (rc)
+ if (!rc)
+ rc = fwcmd->hdr.u0.rsp.status;
+ if (rc) {
+ device_printf(sc->dev,"%s failed - cmd status: %d\n",
+ __FUNCTION__, rc);
goto error;
-
+ }
wq->wq_id = LE_16(fwcmd->params.rsp.wq_id);
-
- return 0;
error:
- device_printf(sc->dev, "Mbox Create WQ failed\n");
return rc;
}
@@ -1649,14 +1742,15 @@ oce_mbox_create_eq(struct oce_eq *eq)
mbx.payload_length = sizeof(struct mbx_create_common_eq);
rc = oce_mbox_post(sc, &mbx, NULL);
- if (rc)
+ if (!rc)
+ rc = fwcmd->hdr.u0.rsp.status;
+ if (rc) {
+ device_printf(sc->dev,"%s failed - cmd status: %d\n",
+ __FUNCTION__, rc);
goto error;
-
+ }
eq->eq_id = LE_16(fwcmd->params.rsp.eq_id);
-
- return 0;
error:
- device_printf(sc->dev, "Mbox Create EQ failed\n");
return rc;
}
@@ -1726,14 +1820,125 @@ oce_mbox_cq_create(struct oce_cq *cq, uint32_t ncoalesce, uint32_t is_eventable)
mbx.payload_length = sizeof(struct mbx_create_common_cq);
rc = oce_mbox_post(sc, &mbx, NULL);
- if (rc)
+ if (!rc)
+ rc = fwcmd->hdr.u0.rsp.status;
+ if (rc) {
+ device_printf(sc->dev,"%s failed - cmd status: %d\n",
+ __FUNCTION__, rc);
goto error;
-
+ }
cq->cq_id = LE_16(fwcmd->params.rsp.cq_id);
+error:
+ return rc;
- return 0;
+}
+
+int
+oce_mbox_read_transrecv_data(POCE_SOFTC sc, uint32_t page_num)
+{
+ int rc = 0;
+ struct oce_mbx mbx;
+ struct mbx_read_common_transrecv_data *fwcmd;
+ struct oce_mq_sge *sgl;
+ OCE_DMA_MEM dma;
+
+ /* Allocate DMA mem*/
+ if (oce_dma_alloc(sc, sizeof(struct mbx_read_common_transrecv_data),
+ &dma, 0))
+ return ENOMEM;
+
+ fwcmd = OCE_DMAPTR(&dma, struct mbx_read_common_transrecv_data);
+ bzero(fwcmd, sizeof(struct mbx_read_common_transrecv_data));
+
+ bzero(&mbx, sizeof(struct oce_mbx));
+ mbx_common_req_hdr_init(&fwcmd->hdr, 0, 0,
+ MBX_SUBSYSTEM_COMMON,
+ OPCODE_COMMON_READ_TRANSRECEIVER_DATA,
+ MBX_TIMEOUT_SEC,
+ sizeof(struct mbx_read_common_transrecv_data),
+ OCE_MBX_VER_V0);
+
+ /* fill rest of mbx */
+ mbx.u0.s.embedded = 0;
+ mbx.payload_length = sizeof(struct mbx_read_common_transrecv_data);
+ mbx.u0.s.sge_count = 1;
+ sgl = &mbx.payload.u0.u1.sgl[0];
+ sgl->pa_hi = htole32(upper_32_bits(dma.paddr));
+ sgl->pa_lo = htole32((dma.paddr) & 0xFFFFFFFF);
+ sgl->length = htole32(mbx.payload_length);
+ DW_SWAP(u32ptr(&mbx), mbx.payload_length + OCE_BMBX_RHDR_SZ);
+
+ fwcmd->params.req.port = LE_32(sc->port_id);
+ fwcmd->params.req.page_num = LE_32(page_num);
+
+ /* command post */
+ rc = oce_mbox_post(sc, &mbx, NULL);
+ if (!rc)
+ rc = fwcmd->hdr.u0.rsp.status;
+ if (rc) {
+ device_printf(sc->dev,"%s failed - cmd status: %d\n",
+ __FUNCTION__, rc);
+ goto error;
+ }
+ if(fwcmd->params.rsp.page_num == PAGE_NUM_A0)
+ {
+ bcopy((char *)fwcmd->params.rsp.page_data,
+ (char *)&sfp_vpd_dump_buffer[0],
+ TRANSCEIVER_A0_SIZE);
+ }
+
+ if(fwcmd->params.rsp.page_num == PAGE_NUM_A2)
+ {
+ bcopy((char *)fwcmd->params.rsp.page_data,
+ (char *)&sfp_vpd_dump_buffer[32],
+ TRANSCEIVER_A2_SIZE);
+ }
error:
- device_printf(sc->dev, "Mbox Create CQ failed\n");
return rc;
+}
+void
+oce_mbox_eqd_modify_periodic(POCE_SOFTC sc, struct oce_set_eqd *set_eqd,
+ int num)
+{
+ struct oce_mbx mbx;
+ struct mbx_modify_common_eq_delay *fwcmd;
+ int rc = 0;
+ int i = 0;
+
+ bzero(&mbx, sizeof(struct oce_mbx));
+
+ /* Initialize MODIFY_EQ_DELAY ioctl header */
+ fwcmd = (struct mbx_modify_common_eq_delay *)&mbx.payload;
+ mbx_common_req_hdr_init(&fwcmd->hdr, 0, 0,
+ MBX_SUBSYSTEM_COMMON,
+ OPCODE_COMMON_MODIFY_EQ_DELAY,
+ MBX_TIMEOUT_SEC,
+ sizeof(struct mbx_modify_common_eq_delay),
+ OCE_MBX_VER_V0);
+ /* fill rest of mbx */
+ mbx.u0.s.embedded = 1;
+ mbx.payload_length = sizeof(struct mbx_modify_common_eq_delay);
+ DW_SWAP(u32ptr(&mbx), mbx.payload_length + OCE_BMBX_RHDR_SZ);
+
+ fwcmd->params.req.num_eq = num;
+ for (i = 0; i < num; i++) {
+ fwcmd->params.req.delay[i].eq_id =
+ htole32(set_eqd[i].eq_id);
+ fwcmd->params.req.delay[i].phase = 0;
+ fwcmd->params.req.delay[i].dm =
+ htole32(set_eqd[i].delay_multiplier);
+ }
+
+
+ /* command post */
+ rc = oce_mbox_post(sc, &mbx, NULL);
+
+ if (!rc)
+ rc = fwcmd->hdr.u0.rsp.status;
+ if (rc)
+ device_printf(sc->dev,"%s failed - cmd status: %d\n",
+ __FUNCTION__, rc);
}
+
+
diff --git a/sys/dev/oce/oce_queue.c b/sys/dev/oce/oce_queue.c
index 580853e..82972ee 100644
--- a/sys/dev/oce/oce_queue.c
+++ b/sys/dev/oce/oce_queue.c
@@ -36,8 +36,11 @@
* Costa Mesa, CA 92626
*/
+
+
/* $FreeBSD$ */
+
#include "oce_if.h"
/*****************************************************
@@ -89,6 +92,7 @@ oce_queue_init_all(POCE_SOFTC sc)
int rc = 0, i, vector;
struct oce_wq *wq;
struct oce_rq *rq;
+ struct oce_aic_obj *aic;
/* alloc TX/RX queues */
for_all_wq_queues(sc, wq, i) {
@@ -113,6 +117,13 @@ oce_queue_init_all(POCE_SOFTC sc)
/* create all of the event queues */
for (vector = 0; vector < sc->intr_count; vector++) {
+ /* setup aic defaults for each event queue */
+ aic = &sc->aic_obj[vector];
+ aic->max_eqd = OCE_MAX_EQD;
+ aic->min_eqd = OCE_MIN_EQD;
+ aic->et_eqd = OCE_MIN_EQD;
+ aic->enable = TRUE;
+
sc->eq[vector] = oce_eq_create(sc, EQ_LEN_1024, EQE_SIZE_4,
0, vector);
if (!sc->eq[vector])
@@ -657,8 +668,7 @@ oce_mq_create(POCE_SOFTC sc, struct oce_eq *eq, uint32_t q_len)
oce_mq_ext_ctx_t *ctx;
uint32_t num_pages;
uint32_t page_size;
- uint32_t version;
-
+ int version;
cq = oce_cq_create(sc, eq, CQ_LEN_256,
sizeof(struct oce_mq_cqe), 1, 1, 0, 0);
@@ -680,8 +690,8 @@ oce_mq_create(POCE_SOFTC sc, struct oce_eq *eq, uint32_t q_len)
bzero(&mbx, sizeof(struct oce_mbx));
+ IS_XE201(sc) ? (version = OCE_MBX_VER_V1) : (version = OCE_MBX_VER_V0);
fwcmd = (struct mbx_create_common_mq_ex *)&mbx.payload;
- version = OCE_MBX_VER_V0;
mbx_common_req_hdr_init(&fwcmd->hdr, 0, 0,
MBX_SUBSYSTEM_COMMON,
OPCODE_COMMON_CREATE_MQ_EXT,
@@ -693,21 +703,41 @@ oce_mq_create(POCE_SOFTC sc, struct oce_eq *eq, uint32_t q_len)
page_size = mq->ring->num_items * mq->ring->item_size;
ctx = &fwcmd->params.req.context;
- ctx->v0.num_pages = num_pages;
- ctx->v0.cq_id = cq->cq_id;
- ctx->v0.ring_size = OCE_LOG2(q_len) + 1;
- ctx->v0.valid = 1;
- /* Subscribe to Link State and Group 5 Events(bits 1 and 5 set) */
- ctx->v0.async_evt_bitmap = 0xffffffff;
+
+ if (IS_XE201(sc)) {
+ ctx->v1.num_pages = num_pages;
+ ctx->v1.ring_size = OCE_LOG2(q_len) + 1;
+ ctx->v1.cq_id = cq->cq_id;
+ ctx->v1.valid = 1;
+ ctx->v1.async_cq_id = cq->cq_id;
+ ctx->v1.async_cq_valid = 1;
+ /* Subscribe to Link State and Group 5 Events(bits 1 & 5 set) */
+ ctx->v1.async_evt_bitmap |= LE_32(0x00000022);
+ ctx->v1.async_evt_bitmap |= LE_32(1 << ASYNC_EVENT_CODE_DEBUG);
+ ctx->v1.async_evt_bitmap |=
+ LE_32(1 << ASYNC_EVENT_CODE_SLIPORT);
+ }
+ else {
+ ctx->v0.num_pages = num_pages;
+ ctx->v0.cq_id = cq->cq_id;
+ ctx->v0.ring_size = OCE_LOG2(q_len) + 1;
+ ctx->v0.valid = 1;
+ /* Subscribe to Link State and Group5 Events(bits 1 & 5 set) */
+ ctx->v0.async_evt_bitmap = 0xffffffff;
+ }
mbx.u0.s.embedded = 1;
mbx.payload_length = sizeof(struct mbx_create_common_mq_ex);
DW_SWAP(u32ptr(&mbx), mbx.payload_length + OCE_BMBX_RHDR_SZ);
rc = oce_mbox_post(sc, &mbx, NULL);
- if (rc)
+ if (!rc)
+ rc = fwcmd->hdr.u0.rsp.status;
+ if (rc) {
+ device_printf(sc->dev,"%s failed - cmd status: %d\n",
+ __FUNCTION__, rc);
goto error;
-
+ }
mq->mq_id = LE_16(fwcmd->params.rsp.mq_id);
mq->cq = cq;
eq->cq[eq->cq_valid] = cq;
@@ -824,10 +854,11 @@ oce_destroy_q(POCE_SOFTC sc, struct oce_mbx *mbx, size_t req_size,
DW_SWAP(u32ptr(mbx), mbx->payload_length + OCE_BMBX_RHDR_SZ);
rc = oce_mbox_post(sc, mbx, NULL);
-
- if (rc != 0)
- device_printf(sc->dev, "Failed to del q\n");
-
+ if (!rc)
+ rc = hdr->u0.rsp.status;
+ if (rc)
+ device_printf(sc->dev,"%s failed - cmd status: %d\n",
+ __FUNCTION__, rc);
return rc;
}
diff --git a/sys/dev/oce/oce_sysctl.c b/sys/dev/oce/oce_sysctl.c
index 93117f6..d8a88de 100644
--- a/sys/dev/oce/oce_sysctl.c
+++ b/sys/dev/oce/oce_sysctl.c
@@ -38,6 +38,9 @@
/* $FreeBSD$ */
+/* $FreeBSD$ */
+
+
#include "oce_if.h"
static void copy_stats_to_sc_xe201(POCE_SOFTC sc);
@@ -49,6 +52,7 @@ static int oce_sys_fwupgrade(SYSCTL_HANDLER_ARGS);
static int oce_be3_flashdata(POCE_SOFTC sc, const struct firmware
*fw, int num_imgs);
static int oce_lancer_fwupgrade(POCE_SOFTC sc, const struct firmware *fw);
+static int oce_sysctl_sfp_vpd_dump(SYSCTL_HANDLER_ARGS);
static boolean_t oce_phy_flashing_required(POCE_SOFTC sc);
static boolean_t oce_img_flashing_required(POCE_SOFTC sc, const char *p,
int img_optype, uint32_t img_offset,
@@ -61,7 +65,7 @@ static void oce_add_stats_sysctls_xe201(POCE_SOFTC sc,
struct sysctl_oid *stats_node);
extern char component_revision[32];
-
+uint32_t sfp_vpd_dump_buffer[TRANSCEIVER_DATA_NUM_ELE];
void
oce_add_sysctls(POCE_SOFTC sc)
@@ -93,7 +97,8 @@ oce_add_sysctls(POCE_SOFTC sc)
sizeof(oce_max_rsp_handled),
"Maximum receive frames handled per interupt");
- if (sc->function_mode & FNM_FLEX10_MODE)
+ if ((sc->function_mode & FNM_FLEX10_MODE) ||
+ (sc->function_mode & FNM_UMC_MODE))
SYSCTL_ADD_UINT(ctx, child,
OID_AUTO, "speed",
CTLFLAG_RD,
@@ -121,6 +126,19 @@ oce_add_sysctls(POCE_SOFTC sc)
CTLTYPE_STRING | CTLFLAG_RW, (void *)sc, 0,
oce_sys_fwupgrade, "A", "Firmware ufi file");
+ /*
+ * Dumps Transceiver data
+ * "sysctl dev.oce.0.sfp_vpd_dump=0"
+ * "sysctl -x dev.oce.0.sfp_vpd_dump_buffer" for hex dump
+ * "sysctl -b dev.oce.0.sfp_vpd_dump_buffer > sfp.bin" for binary dump
+ */
+ SYSCTL_ADD_PROC(ctx, child, OID_AUTO, "sfp_vpd_dump",
+ CTLTYPE_INT | CTLFLAG_RW, (void *)sc, 0, oce_sysctl_sfp_vpd_dump,
+ "I", "Initiate a sfp_vpd_dump operation");
+ SYSCTL_ADD_OPAQUE(ctx, child, OID_AUTO, "sfp_vpd_dump_buffer",
+ CTLFLAG_RD, sfp_vpd_dump_buffer,
+ TRANSCEIVER_DATA_SIZE, "IU", "Access sfp_vpd_dump buffer");
+
stats_node = SYSCTL_ADD_NODE(ctx, child, OID_AUTO, "stats",
CTLFLAG_RD, NULL, "Ethernet Statistics");
@@ -133,7 +151,6 @@ oce_add_sysctls(POCE_SOFTC sc)
}
-
static uint32_t
oce_loopback_test(struct oce_softc *sc, uint8_t loopback_type)
{
@@ -147,7 +164,6 @@ oce_loopback_test(struct oce_softc *sc, uint8_t loopback_type)
return status;
}
-
static int
oce_sysctl_loopback(SYSCTL_HANDLER_ARGS)
{
@@ -1303,3 +1319,31 @@ oce_refresh_nic_stats(POCE_SOFTC sc)
return rc;
}
+
+static int
+oce_sysctl_sfp_vpd_dump(SYSCTL_HANDLER_ARGS)
+{
+ int result = 0, error;
+ int rc = 0;
+ POCE_SOFTC sc = (POCE_SOFTC) arg1;
+
+ /* sysctl default handler */
+ error = sysctl_handle_int(oidp, &result, 0, req);
+ if (error || !req->newptr)
+ return (error);
+
+ if(result == -1) {
+ return EINVAL;
+ }
+ bzero((char *)sfp_vpd_dump_buffer, TRANSCEIVER_DATA_SIZE);
+
+ rc = oce_mbox_read_transrecv_data(sc, PAGE_NUM_A0);
+ if(rc)
+ return rc;
+
+ rc = oce_mbox_read_transrecv_data(sc, PAGE_NUM_A2);
+ if(rc)
+ return rc;
+
+ return rc;
+}
diff --git a/sys/dev/oce/oce_util.c b/sys/dev/oce/oce_util.c
index 7b227ac..b71c02d 100644
--- a/sys/dev/oce/oce_util.c
+++ b/sys/dev/oce/oce_util.c
@@ -36,8 +36,10 @@
* Costa Mesa, CA 92626
*/
+
/* $FreeBSD$ */
+
#include "oce_if.h"
static void oce_dma_map_ring(void *arg,
@@ -71,7 +73,8 @@ oce_dma_alloc(POCE_SOFTC sc, bus_size_t size, POCE_DMA_MEM dma, int flags)
if (rc == 0) {
rc = bus_dmamem_alloc(dma->tag,
&dma->ptr,
- BUS_DMA_NOWAIT | BUS_DMA_COHERENT,
+ BUS_DMA_NOWAIT | BUS_DMA_COHERENT |
+ BUS_DMA_ZERO,
&dma->map);
}
diff --git a/sys/dev/pci/pci.c b/sys/dev/pci/pci.c
index 649a494..79d5e57 100644
--- a/sys/dev/pci/pci.c
+++ b/sys/dev/pci/pci.c
@@ -234,10 +234,11 @@ static const struct pci_quirk pci_quirks[] = {
{ 0x74501022, PCI_QUIRK_DISABLE_MSI, 0, 0 },
/*
- * MSI-X doesn't work with at least LSI SAS1068E passed through by
- * VMware.
+ * MSI-X allocation doesn't work properly for devices passed through
+ * by VMware up to at least ESXi 5.1.
*/
- { 0x079015ad, PCI_QUIRK_DISABLE_MSI, 0, 0 },
+ { 0x079015ad, PCI_QUIRK_DISABLE_MSI, 0, 0 }, /* PCI/PCI-X */
+ { 0x07a015ad, PCI_QUIRK_DISABLE_MSI, 0, 0 }, /* PCIe */
/*
* Some virtualization environments emulate an older chipset
@@ -3643,11 +3644,11 @@ pci_print_child(device_t dev, device_t child)
return (retval);
}
-static struct
+static const struct
{
- int class;
- int subclass;
- char *desc;
+ int class;
+ int subclass;
+ const char *desc;
} pci_nomatch_tab[] = {
{PCIC_OLD, -1, "old"},
{PCIC_OLD, PCIS_OLD_NONVGA, "non-VGA display device"},
@@ -3739,8 +3740,9 @@ static struct
void
pci_probe_nomatch(device_t dev, device_t child)
{
- int i;
- char *cp, *scp, *device;
+ int i;
+ const char *cp, *scp;
+ char *device;
/*
* Look for a listing for this device in a loaded device database.
@@ -3773,7 +3775,6 @@ pci_probe_nomatch(device_t dev, device_t child)
printf(" at device %d.%d (no driver attached)\n",
pci_get_slot(child), pci_get_function(child));
pci_cfg_save(child, device_get_ivars(child), 1);
- return;
}
/*
diff --git a/sys/dev/random/randomdev_soft.c b/sys/dev/random/randomdev_soft.c
index 420a82a..004066eb 100644
--- a/sys/dev/random/randomdev_soft.c
+++ b/sys/dev/random/randomdev_soft.c
@@ -242,10 +242,10 @@ random_kthread(void *arg __unused)
local_count = 0;
/* Process until told to stop */
+ mtx_lock_spin(&harvest_mtx);
for (; random_kthread_control >= 0;) {
/* Cycle through all the entropy sources */
- mtx_lock_spin(&harvest_mtx);
for (source = RANDOM_START; source < ENTROPYSOURCE; source++) {
/*
* Drain entropy source records into a thread-local
@@ -270,7 +270,6 @@ random_kthread(void *arg __unused)
emptyfifo.count += local_count;
local_count = 0;
}
- mtx_unlock_spin(&harvest_mtx);
KASSERT(local_count == 0, ("random_kthread: local_count %d",
local_count));
@@ -283,9 +282,11 @@ random_kthread(void *arg __unused)
random_kthread_control = 0;
/* Work done, so don't belabour the issue */
- pause("-", hz / 10);
+ msleep_spin_sbt(&random_kthread_control, &harvest_mtx,
+ "-", SBT_1S / 10, 0, C_PREL(1));
}
+ mtx_unlock_spin(&harvest_mtx);
random_set_wakeup_exit(&random_kthread_control);
/* NOTREACHED */
diff --git a/sys/dev/sound/pci/hda/hdaa_patches.c b/sys/dev/sound/pci/hda/hdaa_patches.c
index 41d51d7..ef3124a 100644
--- a/sys/dev/sound/pci/hda/hdaa_patches.c
+++ b/sys/dev/sound/pci/hda/hdaa_patches.c
@@ -333,6 +333,23 @@ hdac_pin_patch(struct hdaa_widget *w)
patch = "as=1 seq=15";
break;
}
+ } else if (id == HDA_CODEC_CX20590 &&
+ (subid == LENOVO_X1_SUBVENDOR ||
+ subid == LENOVO_X220_SUBVENDOR ||
+ subid == LENOVO_T420_SUBVENDOR ||
+ subid == LENOVO_T520_SUBVENDOR)) {
+ switch (nid) {
+ case 25:
+ patch = "as=1 seq=15";
+ break;
+ }
+ } else if (id == HDA_CODEC_ALC269 &&
+ subid == LENOVO_X1CRBN_SUBVENDOR) {
+ switch (nid) {
+ case 21:
+ patch = "as=1 seq=15";
+ break;
+ }
}
if (patch != NULL)
diff --git a/sys/dev/sound/pci/hda/hdac.h b/sys/dev/sound/pci/hda/hdac.h
index 9f9d687..e82b6ae 100644
--- a/sys/dev/sound/pci/hda/hdac.h
+++ b/sys/dev/sound/pci/hda/hdac.h
@@ -220,7 +220,12 @@
#define LENOVO_3KN200_SUBVENDOR HDA_MODEL_CONSTRUCT(LENOVO, 0x384e)
#define LENOVO_B450_SUBVENDOR HDA_MODEL_CONSTRUCT(LENOVO, 0x3a0d)
#define LENOVO_TCA55_SUBVENDOR HDA_MODEL_CONSTRUCT(LENOVO, 0x1015)
+#define LENOVO_X1_SUBVENDOR HDA_MODEL_CONSTRUCT(LENOVO, 0x21e8)
+#define LENOVO_X1CRBN_SUBVENDOR HDA_MODEL_CONSTRUCT(LENOVO, 0x21f9)
+#define LENOVO_X220_SUBVENDOR HDA_MODEL_CONSTRUCT(LENOVO, 0x21da)
#define LENOVO_X300_SUBVENDOR HDA_MODEL_CONSTRUCT(LENOVO, 0x20ac)
+#define LENOVO_T420_SUBVENDOR HDA_MODEL_CONSTRUCT(LENOVO, 0x21ce)
+#define LENOVO_T520_SUBVENDOR HDA_MODEL_CONSTRUCT(LENOVO, 0x21cf)
#define LENOVO_ALL_SUBVENDOR HDA_MODEL_CONSTRUCT(LENOVO, 0xffff)
/* Samsung */
diff --git a/sys/dev/sound/pci/hda/hdacc.c b/sys/dev/sound/pci/hda/hdacc.c
index 55bf4af..c9282c9 100644
--- a/sys/dev/sound/pci/hda/hdacc.c
+++ b/sys/dev/sound/pci/hda/hdacc.c
@@ -460,8 +460,12 @@ hdacc_attach(device_t dev)
static int
hdacc_detach(device_t dev)
{
+ struct hdacc_softc *codec = device_get_softc(dev);
+ int error;
- return (device_delete_children(dev));
+ error = device_delete_children(dev);
+ free(codec->fgs, M_HDACC);
+ return (error);
}
static int
diff --git a/sys/dev/syscons/syscons.c b/sys/dev/syscons/syscons.c
index 8094ea3..b863f90 100644
--- a/sys/dev/syscons/syscons.c
+++ b/sys/dev/syscons/syscons.c
@@ -506,6 +506,8 @@ sc_attach_unit(int unit, int flags)
sc = sc_get_softc(unit, flags & SC_KERNEL_CONSOLE);
sc->config = flags;
+ callout_init(&sc->ctimeout, 0);
+ callout_init(&sc->cblink, 0);
scp = sc_get_stat(sc->dev[0]);
if (sc_console == NULL) /* sc_console_unit < 0 */
sc_console = scp;
@@ -1831,13 +1833,11 @@ static void
scrn_timer(void *arg)
{
#ifndef PC98
- static int kbd_interval = 0;
+ static time_t kbd_time_stamp = 0;
#endif
- struct timeval tv;
sc_softc_t *sc;
scr_stat *scp;
- int again;
- int s;
+ int again, rate;
again = (arg != NULL);
if (arg != NULL)
@@ -1847,18 +1847,18 @@ scrn_timer(void *arg)
else
return;
+ /* find the vty to update */
+ scp = sc->cur_scp;
+
/* don't do anything when we are performing some I/O operations */
- if (suspend_in_progress || sc->font_loading_in_progress) {
- if (again)
- timeout(scrn_timer, sc, hz / 10);
- return;
- }
- s = spltty();
+ if (suspend_in_progress || sc->font_loading_in_progress)
+ goto done;
#ifndef PC98
if ((sc->kbd == NULL) && (sc->config & SC_AUTODETECT_KBD)) {
/* try to allocate a keyboard automatically */
- if (++kbd_interval >= 25) {
+ if (kbd_time_stamp != time_uptime) {
+ kbd_time_stamp = time_uptime;
sc->keyboard = sc_allocate_keyboard(sc, -1);
if (sc->keyboard >= 0) {
sc->kbd = kbd_get_keyboard(sc->keyboard);
@@ -1867,25 +1867,20 @@ scrn_timer(void *arg)
update_kbd_state(sc->cur_scp, sc->cur_scp->status,
LOCK_MASK);
}
- kbd_interval = 0;
}
}
#endif /* PC98 */
- /* find the vty to update */
- scp = sc->cur_scp;
-
/* should we stop the screen saver? */
- getmicrouptime(&tv);
if (debugger > 0 || panicstr || shutdown_in_progress)
sc_touch_scrn_saver();
if (run_scrn_saver) {
- if (tv.tv_sec > sc->scrn_time_stamp + scrn_blank_time)
+ if (time_uptime > sc->scrn_time_stamp + scrn_blank_time)
sc->flags |= SC_SCRN_IDLE;
else
sc->flags &= ~SC_SCRN_IDLE;
} else {
- sc->scrn_time_stamp = tv.tv_sec;
+ sc->scrn_time_stamp = time_uptime;
sc->flags &= ~SC_SCRN_IDLE;
if (scrn_blank_time > 0)
run_scrn_saver = TRUE;
@@ -1898,12 +1893,8 @@ scrn_timer(void *arg)
/* should we just return ? */
if (sc->blink_in_progress || sc->switch_in_progress
- || sc->write_in_progress) {
- if (again)
- timeout(scrn_timer, sc, hz / 10);
- splx(s);
- return;
- }
+ || sc->write_in_progress)
+ goto done;
/* Update the screen */
scp = sc->cur_scp; /* cur_scp may have changed... */
@@ -1917,9 +1908,19 @@ scrn_timer(void *arg)
(*current_saver)(sc, TRUE);
#endif
- if (again)
- timeout(scrn_timer, sc, hz / 25);
- splx(s);
+done:
+ if (again) {
+ /*
+ * Use reduced "refresh" rate if we are in graphics and that is not a
+ * graphical screen saver. In such case we just have nothing to do.
+ */
+ if (ISGRAPHSC(scp) && !(sc->flags & SC_SCRN_BLANKED))
+ rate = 2;
+ else
+ rate = 30;
+ callout_reset_sbt(&sc->ctimeout, SBT_1S / rate, 0,
+ scrn_timer, sc, C_PREL(1));
+ }
}
static int
@@ -3863,7 +3864,8 @@ blink_screen(void *arg)
(*scp->rndr->draw)(scp, 0, scp->xsize*scp->ysize,
scp->sc->blink_in_progress & 1);
scp->sc->blink_in_progress--;
- timeout(blink_screen, scp, hz / 10);
+ callout_reset_sbt(&scp->sc->cblink, SBT_1S / 15, 0,
+ blink_screen, scp, C_PREL(0));
}
}
diff --git a/sys/dev/syscons/syscons.h b/sys/dev/syscons/syscons.h
index 23a7bba..353b67f 100644
--- a/sys/dev/syscons/syscons.h
+++ b/sys/dev/syscons/syscons.h
@@ -269,6 +269,8 @@ typedef struct sc_softc {
#ifdef KDB
int sc_altbrk;
#endif
+ struct callout ctimeout;
+ struct callout cblink;
} sc_softc_t;
/* virtual screen */
diff --git a/sys/dev/virtio/block/virtio_blk.c b/sys/dev/virtio/block/virtio_blk.c
index cb628f6..21d7703 100644
--- a/sys/dev/virtio/block/virtio_blk.c
+++ b/sys/dev/virtio/block/virtio_blk.c
@@ -72,6 +72,7 @@ struct vtblk_softc {
#define VTBLK_FLAG_DETACH 0x0004
#define VTBLK_FLAG_SUSPEND 0x0008
#define VTBLK_FLAG_DUMPING 0x0010
+#define VTBLK_FLAG_BARRIER 0x0020
struct virtqueue *vtblk_vq;
struct sglist *vtblk_sglist;
@@ -81,7 +82,8 @@ struct vtblk_softc {
TAILQ_HEAD(, vtblk_request)
vtblk_req_free;
TAILQ_HEAD(, vtblk_request)
- vtblk_req_ready;
+ vtblk_req_ready;
+ struct vtblk_request *vtblk_req_ordered;
struct taskqueue *vtblk_tq;
struct task vtblk_intr_task;
@@ -278,9 +280,10 @@ vtblk_attach(device_t dev)
if (virtio_with_feature(dev, VIRTIO_RING_F_INDIRECT_DESC))
sc->vtblk_flags |= VTBLK_FLAG_INDIRECT;
-
if (virtio_with_feature(dev, VIRTIO_BLK_F_RO))
sc->vtblk_flags |= VTBLK_FLAG_READONLY;
+ if (virtio_with_feature(dev, VIRTIO_BLK_F_BARRIER))
+ sc->vtblk_flags |= VTBLK_FLAG_BARRIER;
/* Get local copy of config. */
virtio_read_device_config(dev, 0, &blkcfg,
@@ -766,25 +769,45 @@ vtblk_bio_request(struct vtblk_softc *sc)
bp->bio_cmd);
}
- if (bp->bio_flags & BIO_ORDERED)
- req->vbr_hdr.type |= VIRTIO_BLK_T_BARRIER;
-
return (req);
}
static int
vtblk_execute_request(struct vtblk_softc *sc, struct vtblk_request *req)
{
+ struct virtqueue *vq;
struct sglist *sg;
struct bio *bp;
- int readable, writable, error;
+ int ordered, readable, writable, error;
+ vq = sc->vtblk_vq;
sg = sc->vtblk_sglist;
bp = req->vbr_bp;
+ ordered = 0;
writable = 0;
VTBLK_LOCK_ASSERT(sc);
+ /*
+ * Wait until the ordered request completes before
+ * executing subsequent requests.
+ */
+ if (sc->vtblk_req_ordered != NULL)
+ return (EBUSY);
+
+ if (bp->bio_flags & BIO_ORDERED) {
+ if ((sc->vtblk_flags & VTBLK_FLAG_BARRIER) == 0) {
+ /*
+ * This request will be executed once all
+ * the in-flight requests are completed.
+ */
+ if (!virtqueue_empty(vq))
+ return (EBUSY);
+ ordered = 1;
+ } else
+ req->vbr_hdr.type |= VIRTIO_BLK_T_BARRIER;
+ }
+
sglist_reset(sg);
sglist_append(sg, &req->vbr_hdr, sizeof(struct virtio_blk_outhdr));
@@ -802,10 +825,13 @@ vtblk_execute_request(struct vtblk_softc *sc, struct vtblk_request *req)
writable++;
sglist_append(sg, &req->vbr_ack, sizeof(uint8_t));
-
readable = sg->sg_nseg - writable;
- return (virtqueue_enqueue(sc->vtblk_vq, req, sg, readable, writable));
+ error = virtqueue_enqueue(vq, req, sg, readable, writable);
+ if (error == 0 && ordered)
+ sc->vtblk_req_ordered = req;
+
+ return (error);
}
static int
@@ -1013,6 +1039,12 @@ vtblk_finish_completed(struct vtblk_softc *sc)
while ((req = virtqueue_dequeue(sc->vtblk_vq, NULL)) != NULL) {
bp = req->vbr_bp;
+ if (sc->vtblk_req_ordered != NULL) {
+ /* This should be the only outstanding request. */
+ MPASS(sc->vtblk_req_ordered == req);
+ sc->vtblk_req_ordered = NULL;
+ }
+
error = vtblk_request_error(req);
if (error)
disk_err(bp, "hard error", -1, 1);
@@ -1039,6 +1071,7 @@ vtblk_drain_vq(struct vtblk_softc *sc, int skip_done)
vtblk_enqueue_request(sc, req);
}
+ sc->vtblk_req_ordered = NULL;
KASSERT(virtqueue_empty(vq), ("virtqueue not empty"));
}
diff --git a/sys/fs/coda/README b/sys/fs/coda/README
deleted file mode 100644
index 19de799..0000000
--- a/sys/fs/coda/README
+++ /dev/null
@@ -1,62 +0,0 @@
-$FreeBSD$
-
- Announcing the Availability of the
- Coda Distributed
- Filesystem
- for
- BSD Unix Systems
-
- Coda is a distributed filesystem like NFS and AFS. It is
-freely available, like NFS. But it functions much like AFS in being a
-"stateful" filesystem. Coda and AFS cache files on your local
-machine to improve performance. But Coda goes a step further than AFS
-by letting you access the cached files when there is no available
-network, viz. disconnected laptops and network outages. In Coda, both
-the client and server are outside the kernel which makes them easier
-to experiment with.
-
-To get more information on Coda, I would like to refer people to
- http://www.coda.cs.cmu.edu
-There is a wealth of documents, papers, and theses there. There is
-also a good introduction to the Coda File System in
- http://www.coda.cs.cmu.edu/ljpaper/lj.html
-
-Coda was originally developed as an academic prototype/testbed. It is
-being polished and rewritten where necessary. Coda is a work in
-progress and does have bugs. It is, though, very usable. Our
-interest is in making Coda available to as many people as possible and
-to have Coda evolve and flourish.
-
-The bulk of the Coda filesystem code supports the Coda client
-program, the Coda server program and the utilities needed by both.
-All these programs are unix programs and can run equally well on any
-Unix platform. Our main development thrust is improving these
-programs. There is a small part of Coda that deals with the kernel to
-filesystem interface. This code is OS specific (but should not be
-platform specific).
-
-Coda is currently available for several OS's and platforms:
- Freebsd-2.2.5: i386
- Freebsd-2.2.6: i386
- Freebsd -current: i386
- linux 2.0: i386 & sparc
- linux 2.1: i386 & sparc
- NetBSD 1.3: i386
- NetBSD -current: i386
-The relevant sources, binaries, and docs can be found in
- ftp://ftp.coda.cs.cmu.edu/pub/coda/
-
-We intend to come out with new Coda releases often, not daily. We
-don't want to slight any OS/platform not mentioned above. We are just
-limited in our resources as to what we can support internally. We
-will be happy to integrate OpenBSD support as well as other OS
-support. Also, adding platform support should be relatively easy and
-we can discuss this. The only difficulty is that Coda has a light weight
-process package. It does some manipulations in assembler which would
-have to be redone for a different platform.
-
-There are several mailing lists @coda.cs.cmu.edu that discuss coda:
-coda-announce and linux-coda. We are going to revise linux-coda to be
-OS neutral, since it is mainly Coda we want to discuss. We appreciate
-comments, feedback, bug reports, bug fixes, enhancements, etc.
-
diff --git a/sys/fs/coda/TODO b/sys/fs/coda/TODO
deleted file mode 100644
index a0a618a..0000000
--- a/sys/fs/coda/TODO
+++ /dev/null
@@ -1,16 +0,0 @@
-OOPS:
- FreeBSD does not fsync!!!
-
-Near term:
- Fix bug in executing/mapping new files.
- cfs_mount bug: interaction with cfs_inactive no cfs_unsave.
- vref/vn_lock == vget except no VXWANT which may be on.
- Review locks: vn_lock/VOP_UNLOCK/lockmgr ...
-
-Medium term:
- Add missing VFS methods.
- Do performance profile.
- Tune hash algorithm used in cfs_subr.
- Make MPSAFE
-
-$FreeBSD$
diff --git a/sys/fs/coda/cnode.h b/sys/fs/coda/cnode.h
deleted file mode 100644
index 27531a4..0000000
--- a/sys/fs/coda/cnode.h
+++ /dev/null
@@ -1,206 +0,0 @@
-/*-
- *
- * Coda: an Experimental Distributed File System
- * Release 3.1
- *
- * Copyright (c) 1987-1998 Carnegie Mellon University
- * All Rights Reserved
- *
- * Permission to use, copy, modify and distribute this software and its
- * documentation is hereby granted, provided that both the copyright
- * notice and this permission notice appear in all copies of the
- * software, derivative works or modified versions, and any portions
- * thereof, and that both notices appear in supporting documentation, and
- * that credit is given to Carnegie Mellon University in all documents
- * and publicity pertaining to direct or indirect use of this code or its
- * derivatives.
- *
- * CODA IS AN EXPERIMENTAL SOFTWARE SYSTEM AND IS KNOWN TO HAVE BUGS,
- * SOME OF WHICH MAY HAVE SERIOUS CONSEQUENCES. CARNEGIE MELLON ALLOWS
- * FREE USE OF THIS SOFTWARE IN ITS "AS IS" CONDITION. CARNEGIE MELLON
- * DISCLAIMS ANY LIABILITY OF ANY KIND FOR ANY DAMAGES WHATSOEVER
- * RESULTING DIRECTLY OR INDIRECTLY FROM THE USE OF THIS SOFTWARE OR OF
- * ANY DERIVATIVE WORK.
- *
- * Carnegie Mellon encourages users of this software to return any
- * improvements or extensions that they make, and to grant Carnegie
- * Mellon the rights to redistribute these changes without encumbrance.
- *
- * @(#) src/sys/coda/cnode.h,v 1.1.1.1 1998/08/29 21:14:52 rvb Exp $
- * $FreeBSD$
- *
- */
-
-/*-
- * Mach Operating System
- * Copyright (c) 1990 Carnegie-Mellon University
- * Copyright (c) 1989 Carnegie-Mellon University
- * All rights reserved. The CMU software License Agreement specifies
- * the terms and conditions for use and redistribution.
- */
-
-/*
- * This code was written for the Coda filesystem at Carnegie Mellon University.
- * Contributers include David Steere, James Kistler, and M. Satyanarayanan.
- */
-
-#ifndef _CNODE_H_
-#define _CNODE_H_
-
-#include <sys/vnode.h>
-#include <sys/lock.h>
-
-MALLOC_DECLARE(M_CODA);
-
-/*
- * Cnode lookup stuff.
- *
- * NOTE: CODA_CACHESIZE must be a power of 2 for cfshash to work!
- */
-#define CODA_CACHESIZE 512
-
-#define CODA_ALLOC(ptr, cast, size) do { \
- ptr = (cast)malloc((unsigned long) size, M_CODA, M_WAITOK); \
- if (ptr == NULL) \
- panic("kernel malloc returns 0 at %s:%d\n", __FILE__, \
- __LINE__); \
-} while (0)
-
-#define CODA_FREE(ptr, size) free((ptr), M_CODA)
-
-/*
- * Used to select debugging statements throughout the cfs code.
- */
-extern int codadebug;
-extern int coda_printf_delay;
-extern int coda_vnop_print_entry;
-extern int coda_psdev_print_entry;
-extern int coda_vfsop_print_entry;
-
-#define CODADBGMSK(N) (1 << N)
-
-#define CODADEBUG(N, STMT) do { \
- if (codadebug & CODADBGMSK(N)) { \
- STMT \
- } \
-} while (0)
-
-#define myprintf(args) do { \
- if (coda_printf_delay) \
- DELAY(coda_printf_delay); \
- printf args ; \
-} while (0)
-
-struct cnode {
- struct vnode *c_vnode;
- u_short c_flags; /* flags (see below) */
- struct CodaFid c_fid; /* file handle */
- struct vnode *c_ovp; /* open vnode pointer */
- u_short c_ocount; /* count of openers */
- u_short c_owrite; /* count of open for write */
- struct vattr c_vattr; /* attributes */
- char *c_symlink; /* pointer to symbolic link */
- u_short c_symlen; /* length of symbolic link */
- uid_t c_cached_uid; /* cached uid */
- accmode_t c_cached_mode; /* cached access mode */
- struct cnode *c_next; /* links if on FreeBSD machine */
-};
-#define VTOC(vp) ((struct cnode *)(vp)->v_data)
-#define CTOV(cp) ((struct vnode *)((cp)->c_vnode))
-
-/* flags */
-#define C_VATTR 0x01 /* Validity of vattr in the cnode */
-#define C_SYMLINK 0x02 /* Validity of symlink pointer in the Code */
-#define C_ACCCACHE 0x04 /* Validity of access cache */
-#define C_WANTED 0x08 /* Set if lock wanted */
-#define C_LOCKED 0x10 /* Set if lock held */
-#define C_UNMOUNTING 0X20 /* Set if unmounting */
-#define C_PURGING 0x40 /* Set if purging a fid */
-
-#define VALID_VATTR(cp) ((cp->c_flags) & C_VATTR)
-#define VALID_SYMLINK(cp) ((cp->c_flags) & C_SYMLINK)
-#define VALID_ACCCACHE(cp) ((cp->c_flags) & C_ACCCACHE)
-#define IS_UNMOUNTING(cp) ((cp)->c_flags & C_UNMOUNTING)
-
-struct vcomm {
- u_long vc_seq;
- struct selinfo vc_selproc;
- TAILQ_HEAD(, vmsg) vc_requests;
- TAILQ_HEAD(, vmsg) vc_replies;
- int vc_open;
-};
-
-#define VC_OPEN(vcp) ((vcp)->vc_open == 1)
-#define MARK_VC_CLOSED(vcp) (vcp)->vc_open = 0
-#define MARK_VC_OPEN(vcp) (vcp)->vc_open = 1
-
-struct coda_clstat {
- int ncalls; /* client requests */
- int nbadcalls; /* upcall failures */
- int reqs[CODA_NCALLS]; /* count of each request */
-};
-extern struct coda_clstat coda_clstat;
-
-/*
- * CODA structure to hold mount/filesystem information.
- */
-struct coda_mntinfo {
- struct vnode *mi_rootvp;
- struct mount *mi_vfsp;
- struct vcomm mi_vcomm;
- struct cdev *dev;
- int mi_started;
- LIST_ENTRY(coda_mntinfo) mi_list;
-};
-struct coda_mntinfo *dev2coda_mntinfo(struct cdev *dev);
-
-/*
- * vfs pointer to mount info.
- */
-#define vftomi(vfsp) ((struct coda_mntinfo *)(vfsp->mnt_data))
-#define CODA_MOUNTED(vfsp) (vftomi((vfsp)) != NULL)
-
-/*
- * vnode pointer to mount info.
- */
-#define vtomi(vp) ((struct coda_mntinfo *)(vp->v_mount->mnt_data))
-
-/*
- * Used for identifying usage of "Control" object.
- */
-extern struct vnode *coda_ctlvp;
-#define IS_CTL_VP(vp) ((vp) == coda_ctlvp)
-#define IS_CTL_NAME(vp, name, l) ((l == CODA_CONTROLLEN) \
- && ((vp) == vtomi((vp))->mi_rootvp) && \
- strncmp(name, CODA_CONTROL, l) == 0)
-
-/*
- * An enum to tell us whether something that will remove a reference to a
- * cnode was a downcall or not.
- */
-enum dc_status {
- IS_DOWNCALL = 6,
- NOT_DOWNCALL = 7
-};
-
-/* cfs_psdev.h */
-int coda_call(struct coda_mntinfo *mntinfo, int inSize, int *outSize,
- caddr_t buffer);
-
-extern int coda_kernel_version;
-
-/* cfs_subr.h */
-int handleDownCall(struct coda_mntinfo *mnt, int opcode,
- union outputArgs *out);
-void coda_unmounting(struct mount *whoIam);
-int coda_vmflush(struct cnode *cp);
-
-/* cfs_vnodeops.h */
-struct cnode *make_coda_node(struct CodaFid *fid, struct mount *vfsp,
- short type);
-int coda_vnodeopstats_init(void);
-
-/* sigh */
-#define CODA_RDWR ((u_long) 31)
-
-#endif /* _CNODE_H_ */
diff --git a/sys/fs/coda/coda.h b/sys/fs/coda/coda.h
deleted file mode 100644
index 2cfb712..0000000
--- a/sys/fs/coda/coda.h
+++ /dev/null
@@ -1,838 +0,0 @@
-/*-
- *
- * Coda: an Experimental Distributed File System
- * Release 3.1
- *
- * Copyright (c) 1987-1998 Carnegie Mellon University
- * All Rights Reserved
- *
- * Permission to use, copy, modify and distribute this software and its
- * documentation is hereby granted, provided that both the copyright
- * notice and this permission notice appear in all copies of the
- * software, derivative works or modified versions, and any portions
- * thereof, and that both notices appear in supporting documentation, and
- * that credit is given to Carnegie Mellon University in all documents
- * and publicity pertaining to direct or indirect use of this code or its
- * derivatives.
- *
- * CODA IS AN EXPERIMENTAL SOFTWARE SYSTEM AND IS KNOWN TO HAVE BUGS,
- * SOME OF WHICH MAY HAVE SERIOUS CONSEQUENCES. CARNEGIE MELLON ALLOWS
- * FREE USE OF THIS SOFTWARE IN ITS "AS IS" CONDITION. CARNEGIE MELLON
- * DISCLAIMS ANY LIABILITY OF ANY KIND FOR ANY DAMAGES WHATSOEVER
- * RESULTING DIRECTLY OR INDIRECTLY FROM THE USE OF THIS SOFTWARE OR OF
- * ANY DERIVATIVE WORK.
- *
- * Carnegie Mellon encourages users of this software to return any
- * improvements or extensions that they make, and to grant Carnegie
- * Mellon the rights to redistribute these changes without encumbrance.
- *
- * @(#) src/sys/coda/coda.h,v 1.1.1.1 1998/08/29 21:14:52 rvb Exp $
- * $FreeBSD$
- *
- */
-
-
-/*
- *
- * Based on cfs.h from Mach, but revamped for increased simplicity.
- * Linux modifications by Peter Braam, Aug 1996
- */
-
-#ifndef _CODA_HEADER_
-#define _CODA_HEADER_
-
-#ifdef _KERNEL
-#include "opt_coda.h" /* for CODA_COMPAT_5 option */
-#endif
-
-/* Avoid CODA_COMPAT_5 redefinition in coda5 module */
-#if defined (CODA5_MODULE) && !defined(CODA_COMPAT_5)
-#define CODA_COMPAT_5
-#endif
-
-/* Catch new _KERNEL defn for NetBSD */
-#ifdef __NetBSD__
-#include <sys/types.h>
-#endif
-
-#ifndef CODA_MAXSYMLINKS
-#define CODA_MAXSYMLINKS 10
-#endif
-
-#if defined(DJGPP) || defined(__CYGWIN32__)
-#ifdef _KERNEL
-typedef unsigned long u_long;
-typedef unsigned int u_int;
-typedef unsigned short u_short;
-typedef u_long ino_t;
-typedef u_long struct cdev *;
-typedef void * caddr_t;
-#ifdef DOS
-typedef unsigned __int64 u_quad_t;
-#else
-typedef unsigned long long u_quad_t;
-#endif
-
-#define inline
-
-struct timespec {
- long ts_sec;
- long ts_nsec;
-};
-#else /* DJGPP but not _KERNEL */
-#include <sys/types.h>
-#include <sys/time.h>
-typedef unsigned long long u_quad_t;
-#endif /* !_KERNEL */
-#endif /* !DJGPP */
-
-
-#if defined(__linux__)
-#define cdev_t u_quad_t
-#if !defined(_UQUAD_T_) && (!defined(__GLIBC__) || __GLIBC__ < 2)
-#define _UQUAD_T_ 1
-typedef unsigned long long u_quad_t;
-#endif
-#else
-#define cdev_t dev_t
-#endif
-
-#ifdef __CYGWIN32__
-typedef unsigned char u_int8_t;
-struct timespec {
- time_t tv_sec; /* seconds */
- long tv_nsec; /* nanoseconds */
-};
-#endif
-
-typedef u_int32_t cuid_t;
-typedef u_int32_t cgid_t;
-
-/*
- * Cfs constants
- */
-#define CODA_MAXNAMLEN 255
-#define CODA_MAXPATHLEN 1024
-#define CODA_MAXSYMLINK 10
-
-/* these are Coda's version of O_RDONLY etc combinations
- * to deal with VFS open modes
- */
-#define C_O_READ 0x001
-#define C_O_WRITE 0x002
-#define C_O_TRUNC 0x010
-#define C_O_EXCL 0x100
-#define C_O_CREAT 0x200
-
-/* these are to find mode bits in Venus */
-#define C_M_READ 00400
-#define C_M_WRITE 00200
-
-/* for access Venus will use */
-#define C_A_C_OK 8 /* Test for writing upon create. */
-#define C_A_R_OK 4 /* Test for read permission. */
-#define C_A_W_OK 2 /* Test for write permission. */
-#define C_A_X_OK 1 /* Test for execute permission. */
-#define C_A_F_OK 0 /* Test for existence. */
-
-
-#ifndef _VENUS_DIRENT_T_
-#define _VENUS_DIRENT_T_ 1
-struct venus_dirent {
- unsigned int d_fileno; /* file number of entry */
- unsigned short d_reclen; /* length of this record */
- unsigned char d_type; /* file type, see below */
- unsigned char d_namlen; /* length of string in d_name */
- char d_name[CODA_MAXNAMLEN + 1];/* name must be no longer than this */
-};
-#undef DIRSIZ
-#define DIRSIZ(dp) ((sizeof (struct venus_dirent) - (CODA_MAXNAMLEN+1)) + \
- (((dp)->d_namlen+1 + 3) &~ 3))
-
-/*
- * File types
- */
-#define CDT_UNKNOWN 0
-#define CDT_FIFO 1
-#define CDT_CHR 2
-#define CDT_DIR 4
-#define CDT_BLK 6
-#define CDT_REG 8
-#define CDT_LNK 10
-#define CDT_SOCK 12
-#define CDT_WHT 14
-
-/*
- * Convert between stat structure types and directory types.
- */
-#define IFTOCDT(mode) (((mode) & 0170000) >> 12)
-#define CDTTOIF(dirtype) ((dirtype) << 12)
-
-#endif
-
-#ifdef CODA_COMPAT_5
-
-struct CodaFid {
- u_long Volume;
- u_long Vnode;
- u_long Unique;
-};
-
-static __inline__ ino_t coda_f2i(struct CodaFid *fid)
-{
- if (!fid) return 0;
- return (fid->Unique + (fid->Vnode<<10) + (fid->Volume<<20));
-}
-
-static __inline__ char * coda_f2s(struct CodaFid *fid)
-{
- static char fid_str [35];
- snprintf (fid_str, 35, "[%lx.%lx.%lx]", fid->Volume,
- fid->Vnode, fid->Unique);
- return fid_str;
-}
-
-static __inline__ int coda_fid_eq (struct CodaFid *fid1, struct CodaFid *fid2)
-{
- return (fid1->Volume == fid2->Volume &&
- fid1->Vnode == fid2->Vnode &&
- fid1->Unique == fid2->Unique);
-}
-
-struct coda_cred {
- u_int32_t cr_uid, cr_euid, cr_suid, cr_fsuid; /* Real, efftve, set, fs uid*/
- u_int32_t cr_groupid, cr_egid, cr_sgid, cr_fsgid; /* same for groups */
-};
-
-#else /* CODA_COMPAT_5 */
-
-struct CodaFid {
- u_int32_t opaque[4];
-};
-
-static __inline__ ino_t coda_f2i(struct CodaFid *fid)
-{
- if ( ! fid )
- return 0;
- return (fid->opaque[3] ^ (fid->opaque[2]<<10) ^ (fid->opaque[1]<<20) ^ fid->opaque[0]);
-}
-
-static __inline__ char * coda_f2s(struct CodaFid *fid)
- {
- static char fid_str [35];
- snprintf (fid_str, 35, "[%x.%x.%x.%x]", fid->opaque[0],
- fid->opaque[1], fid->opaque[2], fid->opaque[3]);
- return fid_str;
- }
-
-static __inline__ int coda_fid_eq (struct CodaFid *fid1, struct CodaFid *fid2)
-{
- return (fid1->opaque[0] == fid2->opaque[0] &&
- fid1->opaque[1] == fid2->opaque[1] &&
- fid1->opaque[2] == fid2->opaque[2] &&
- fid1->opaque[3] == fid2->opaque[3]);
-}
-
-#endif /* CODA_COMPAT_5 */
-
-#ifndef _VENUS_VATTR_T_
-#define _VENUS_VATTR_T_
-/*
- * Vnode types. VNON means no type.
- */
-enum coda_vtype { C_VNON, C_VREG, C_VDIR, C_VBLK, C_VCHR, C_VLNK, C_VSOCK, C_VFIFO, C_VBAD };
-
-struct coda_vattr {
- long va_type; /* vnode type (for create) */
- u_short va_mode; /* files access mode and type */
- short va_nlink; /* number of references to file */
- cuid_t va_uid; /* owner user id */
- cgid_t va_gid; /* owner group id */
- long va_fileid; /* file id */
- u_quad_t va_size; /* file size in bytes */
- long va_blocksize; /* blocksize preferred for i/o */
- struct timespec va_atime; /* time of last access */
- struct timespec va_mtime; /* time of last modification */
- struct timespec va_ctime; /* time file changed */
- u_long va_gen; /* generation number of file */
- u_long va_flags; /* flags defined for file */
- cdev_t va_rdev; /* device special file represents */
- u_quad_t va_bytes; /* bytes of disk space held by file */
- u_quad_t va_filerev; /* file modification number */
-};
-
-#endif
-
-/* structure used by CODA_STATFS for getting cache information from venus */
-struct coda_statfs {
- int32_t f_blocks;
- int32_t f_bfree;
- int32_t f_bavail;
- int32_t f_files;
- int32_t f_ffree;
-};
-
-/*
- * Kernel <--> Venus communications.
- */
-
-#define CODA_ROOT 2
-#define CODA_OPEN_BY_FD 3
-#define CODA_OPEN 4
-#define CODA_CLOSE 5
-#define CODA_IOCTL 6
-#define CODA_GETATTR 7
-#define CODA_SETATTR 8
-#define CODA_ACCESS 9
-#define CODA_LOOKUP 10
-#define CODA_CREATE 11
-#define CODA_REMOVE 12
-#define CODA_LINK 13
-#define CODA_RENAME 14
-#define CODA_MKDIR 15
-#define CODA_RMDIR 16
-#define CODA_READDIR 17
-#define CODA_SYMLINK 18
-#define CODA_READLINK 19
-#define CODA_FSYNC 20
-#define CODA_INACTIVE 21
-#define CODA_VGET 22
-#define CODA_SIGNAL 23
-#define CODA_REPLACE 24
-#define CODA_FLUSH 25
-#define CODA_PURGEUSER 26
-#define CODA_ZAPFILE 27
-#define CODA_ZAPDIR 28
-#define CODA_PURGEFID 30
-#define CODA_OPEN_BY_PATH 31
-#define CODA_RESOLVE 32
-#define CODA_REINTEGRATE 33
-#define CODA_STATFS 34
-#define CODA_NCALLS 35
-
-#define DOWNCALL(opcode) (opcode >= CODA_REPLACE && opcode <= CODA_PURGEFID)
-
-#define VC_MAXDATASIZE 8192
-#define VC_MAXMSGSIZE sizeof(union inputArgs)+sizeof(union outputArgs) +\
- VC_MAXDATASIZE
-
-#define CIOC_KERNEL_VERSION _IOWR('c', 10, int)
-#if 0
- /* don't care about kernel version number */
-#define CODA_KERNEL_VERSION 0
- /* The old venus 4.6 compatible interface */
-#define CODA_KERNEL_VERSION 1
-#endif /* realms/cells */
-#ifdef CODA_COMPAT_5
- /* venus_lookup gets an extra parameter to aid windows.*/
-#define CODA_KERNEL_VERSION 2
-#else
- /* 128-bit fids for realms */
-#define CODA_KERNEL_VERSION 3
-#endif
-
-/*
- * Venus <-> Coda RPC arguments
- */
-#ifdef CODA_COMPAT_5
-struct coda_in_hdr {
- unsigned long opcode;
- unsigned long unique; /* Keep multiple outstanding msgs distinct */
- u_short pid; /* Common to all */
- u_short pgid; /* Common to all */
- u_short sid; /* Common to all */
- struct coda_cred cred; /* Common to all */
-};
-#else
-struct coda_in_hdr {
- u_int32_t opcode;
- u_int32_t unique; /* Keep multiple outstanding msgs distinct */
- pid_t pid;
- pid_t pgid;
- cuid_t uid;
-};
-#endif
-
-/* Really important that opcode and unique are 1st two fields! */
-struct coda_out_hdr {
- u_int32_t opcode;
- u_int32_t unique;
- u_int32_t result;
-};
-
-/* coda_root: NO_IN */
-struct coda_root_out {
- struct coda_out_hdr oh;
- struct CodaFid Fid;
-};
-
-struct coda_root_in {
- struct coda_in_hdr in;
-};
-
-/* coda_sync: */
-/* Nothing needed for coda_sync */
-
-/* coda_open: */
-struct coda_open_in {
- struct coda_in_hdr ih;
- struct CodaFid Fid;
- int flags;
-};
-
-struct coda_open_out {
- struct coda_out_hdr oh;
- cdev_t dev;
- ino_t inode;
-};
-
-
-/* coda_close: */
-struct coda_close_in {
- struct coda_in_hdr ih;
- struct CodaFid Fid;
- int flags;
-};
-
-struct coda_close_out {
- struct coda_out_hdr out;
-};
-
-/* coda_ioctl: */
-struct coda_ioctl_in {
- struct coda_in_hdr ih;
- struct CodaFid Fid;
- int cmd;
- int len;
- int rwflag;
- char *data; /* Place holder for data. */
-};
-
-struct coda_ioctl_out {
- struct coda_out_hdr oh;
- int len;
- caddr_t data; /* Place holder for data. */
-};
-
-
-/* coda_getattr: */
-struct coda_getattr_in {
- struct coda_in_hdr ih;
- struct CodaFid Fid;
-};
-
-struct coda_getattr_out {
- struct coda_out_hdr oh;
- struct coda_vattr attr;
-};
-
-
-/* coda_setattr: NO_OUT */
-struct coda_setattr_in {
- struct coda_in_hdr ih;
- struct CodaFid Fid;
- struct coda_vattr attr;
-};
-
-struct coda_setattr_out {
- struct coda_out_hdr out;
-};
-
-/* coda_access: NO_OUT */
-struct coda_access_in {
- struct coda_in_hdr ih;
- struct CodaFid Fid;
- int flags;
-};
-
-struct coda_access_out {
- struct coda_out_hdr out;
-};
-
-
-/* lookup flags */
-#define CLU_CASE_SENSITIVE 0x01
-#define CLU_CASE_INSENSITIVE 0x02
-
-/* coda_lookup: */
-struct coda_lookup_in {
- struct coda_in_hdr ih;
- struct CodaFid Fid;
- int name; /* Place holder for data. */
- int flags;
-};
-
-struct coda_lookup_out {
- struct coda_out_hdr oh;
- struct CodaFid Fid;
- int vtype;
-};
-
-
-/* coda_create: */
-struct coda_create_in {
- struct coda_in_hdr ih;
- struct CodaFid Fid;
- struct coda_vattr attr;
- int excl;
- int mode;
- int name; /* Place holder for data. */
-};
-
-struct coda_create_out {
- struct coda_out_hdr oh;
- struct CodaFid Fid;
- struct coda_vattr attr;
-};
-
-
-/* coda_remove: NO_OUT */
-struct coda_remove_in {
- struct coda_in_hdr ih;
- struct CodaFid Fid;
- int name; /* Place holder for data. */
-};
-
-struct coda_remove_out {
- struct coda_out_hdr out;
-};
-
-/* coda_link: NO_OUT */
-struct coda_link_in {
- struct coda_in_hdr ih;
- struct CodaFid sourceFid; /* cnode to link *to* */
- struct CodaFid destFid; /* Directory in which to place link */
- int tname; /* Place holder for data. */
-};
-
-struct coda_link_out {
- struct coda_out_hdr out;
-};
-
-
-/* coda_rename: NO_OUT */
-struct coda_rename_in {
- struct coda_in_hdr ih;
- struct CodaFid sourceFid;
- int srcname;
- struct CodaFid destFid;
- int destname;
-};
-
-struct coda_rename_out {
- struct coda_out_hdr out;
-};
-
-/* coda_mkdir: */
-struct coda_mkdir_in {
- struct coda_in_hdr ih;
- struct CodaFid Fid;
- struct coda_vattr attr;
- int name; /* Place holder for data. */
-};
-
-struct coda_mkdir_out {
- struct coda_out_hdr oh;
- struct CodaFid Fid;
- struct coda_vattr attr;
-};
-
-
-/* coda_rmdir: NO_OUT */
-struct coda_rmdir_in {
- struct coda_in_hdr ih;
- struct CodaFid Fid;
- int name; /* Place holder for data. */
-};
-
-struct coda_rmdir_out {
- struct coda_out_hdr out;
-};
-
-/* coda_readdir: */
-struct coda_readdir_in {
- struct coda_in_hdr ih;
- struct CodaFid Fid;
- int count;
- int offset;
-};
-
-struct coda_readdir_out {
- struct coda_out_hdr oh;
- int size;
- caddr_t data; /* Place holder for data. */
-};
-
-/* coda_symlink: NO_OUT */
-struct coda_symlink_in {
- struct coda_in_hdr ih;
- struct CodaFid Fid; /* Directory to put symlink in */
- int srcname;
- struct coda_vattr attr;
- int tname;
-};
-
-struct coda_symlink_out {
- struct coda_out_hdr out;
-};
-
-/* coda_readlink: */
-struct coda_readlink_in {
- struct coda_in_hdr ih;
- struct CodaFid Fid;
-};
-
-struct coda_readlink_out {
- struct coda_out_hdr oh;
- int count;
- caddr_t data; /* Place holder for data. */
-};
-
-
-/* coda_fsync: NO_OUT */
-struct coda_fsync_in {
- struct coda_in_hdr ih;
- struct CodaFid Fid;
-};
-
-struct coda_fsync_out {
- struct coda_out_hdr out;
-};
-
-/* coda_inactive: NO_OUT */
-struct coda_inactive_in {
- struct coda_in_hdr ih;
- struct CodaFid Fid;
-};
-
-/* coda_vget: */
-struct coda_vget_in {
- struct coda_in_hdr ih;
- struct CodaFid Fid;
-};
-
-struct coda_vget_out {
- struct coda_out_hdr oh;
- struct CodaFid Fid;
- int vtype;
-};
-
-
-/* CODA_SIGNAL is out-of-band, doesn't need data. */
-/* CODA_INVALIDATE is a venus->kernel call */
-/* CODA_FLUSH is a venus->kernel call */
-
-/* coda_purgeuser: */
-/* CODA_PURGEUSER is a venus->kernel call */
-struct coda_purgeuser_out {
- struct coda_out_hdr oh;
-#ifdef CODA_COMPAT_5
- struct coda_cred cred;
-#else
- cuid_t uid;
-#endif
-};
-
-/* coda_zapfile: */
-/* CODA_ZAPFILE is a venus->kernel call */
-struct coda_zapfile_out {
- struct coda_out_hdr oh;
- struct CodaFid Fid;
-};
-
-/* coda_zapdir: */
-/* CODA_ZAPDIR is a venus->kernel call */
-struct coda_zapdir_out {
- struct coda_out_hdr oh;
- struct CodaFid Fid;
-};
-
-/* coda_zapnode: */
-/* CODA_ZAPVNODE is a venus->kernel call */
-struct coda_zapvnode_out {
- struct coda_out_hdr oh;
-#ifdef CODA_COMPAT_5
- struct coda_cred cred;
-#endif
- struct CodaFid Fid;
-};
-
-/* coda_purgefid: */
-/* CODA_PURGEFID is a venus->kernel call */
-struct coda_purgefid_out {
- struct coda_out_hdr oh;
- struct CodaFid Fid;
-};
-
-/* coda_replace: */
-/* CODA_REPLACE is a venus->kernel call */
-struct coda_replace_out { /* coda_replace is a venus->kernel call */
- struct coda_out_hdr oh;
- struct CodaFid NewFid;
- struct CodaFid OldFid;
-};
-
-/* coda_open_by_fd: */
-struct coda_open_by_fd_in {
- struct coda_in_hdr ih;
- struct CodaFid Fid;
- int flags;
-};
-
-struct coda_open_by_fd_out {
- struct coda_out_hdr oh;
- int fd;
-#ifdef _KERNEL
- /* not passed from userspace but used in-kernel only */
- struct vnode *vp;
-#endif
-};
-
-/* coda_open_by_path: */
-struct coda_open_by_path_in {
- struct coda_in_hdr ih;
- struct CodaFid Fid;
- int flags;
-};
-
-struct coda_open_by_path_out {
- struct coda_out_hdr oh;
- int path;
-};
-
-/* coda_statfs: NO_IN */
-struct coda_statfs_in {
- struct coda_in_hdr ih;
-};
-
-struct coda_statfs_out {
- struct coda_out_hdr oh;
- struct coda_statfs stat;
-};
-
-/*
- * Occasionally, we don't cache the fid returned by CODA_LOOKUP.
- * For instance, if the fid is inconsistent.
- * This case is handled by setting the top bit of the type result parameter.
- */
-#define CODA_NOCACHE 0x80000000
-
-union inputArgs {
- struct coda_in_hdr ih; /* NB: every struct below begins with an ih */
- struct coda_open_in coda_open;
- struct coda_close_in coda_close;
- struct coda_ioctl_in coda_ioctl;
- struct coda_getattr_in coda_getattr;
- struct coda_setattr_in coda_setattr;
- struct coda_access_in coda_access;
- struct coda_lookup_in coda_lookup;
- struct coda_create_in coda_create;
- struct coda_remove_in coda_remove;
- struct coda_link_in coda_link;
- struct coda_rename_in coda_rename;
- struct coda_mkdir_in coda_mkdir;
- struct coda_rmdir_in coda_rmdir;
- struct coda_readdir_in coda_readdir;
- struct coda_symlink_in coda_symlink;
- struct coda_readlink_in coda_readlink;
- struct coda_fsync_in coda_fsync;
- struct coda_vget_in coda_vget;
- struct coda_open_by_fd_in coda_open_by_fd;
- struct coda_open_by_path_in coda_open_by_path;
- struct coda_statfs_in coda_statfs;
-};
-
-union outputArgs {
- struct coda_out_hdr oh; /* NB: every struct below begins with an oh */
- struct coda_root_out coda_root;
- struct coda_open_out coda_open;
- struct coda_ioctl_out coda_ioctl;
- struct coda_getattr_out coda_getattr;
- struct coda_lookup_out coda_lookup;
- struct coda_create_out coda_create;
- struct coda_mkdir_out coda_mkdir;
- struct coda_readdir_out coda_readdir;
- struct coda_readlink_out coda_readlink;
- struct coda_vget_out coda_vget;
- struct coda_purgeuser_out coda_purgeuser;
- struct coda_zapfile_out coda_zapfile;
- struct coda_zapdir_out coda_zapdir;
- struct coda_zapvnode_out coda_zapvnode;
- struct coda_purgefid_out coda_purgefid;
- struct coda_replace_out coda_replace;
- struct coda_open_by_fd_out coda_open_by_fd;
- struct coda_open_by_path_out coda_open_by_path;
- struct coda_statfs_out coda_statfs;
-};
-
-union coda_downcalls {
- /* CODA_INVALIDATE is a venus->kernel call */
- /* CODA_FLUSH is a venus->kernel call */
- struct coda_purgeuser_out purgeuser;
- struct coda_zapfile_out zapfile;
- struct coda_zapdir_out zapdir;
- struct coda_zapvnode_out zapvnode;
- struct coda_purgefid_out purgefid;
- struct coda_replace_out replace;
-};
-
-
-/*
- * Used for identifying usage of "Control" and pioctls
- */
-
-#define PIOCPARM_MASK 0x0000ffff
-struct ViceIoctl {
- caddr_t in, out; /* Data to be transferred in, or out */
- unsigned short in_size; /* Size of input buffer <= 8K */
- unsigned short out_size; /* Maximum size of output buffer, <= 8K */
-};
-
-#if defined(__CYGWIN32__) || defined(DJGPP)
-struct PioctlData {
- unsigned long cmd;
- const char *path;
- int follow;
- struct ViceIoctl vi;
-};
-#else
-struct PioctlData {
- const char *path;
- int follow;
- struct ViceIoctl vi;
-};
-#endif
-
-#define CODA_CONTROL ".CONTROL"
-#define CODA_CONTROLLEN 8
-#define CTL_VOL -1
-#define CTL_VNO -1
-#define CTL_UNI -1
-#define CTL_INO -1
-#define CTL_FILE "/coda/.CONTROL"
-
-#ifdef CODA_COMPAT_5
-#define CTL_FID { -1, -1, -1 }
-#define IS_CTL_FID(fidp) ((fidp)->Volume == -1 &&\
- (fidp)->Vnode == -1 &&\
- (fidp)->Unique == -1)
-#define INVAL_FID { 0, 0, 0 }
-#else
-#define CTL_FID { { -1, -1, -1, -1 } }
-#define IS_CTL_FID(fidp) ((fidp)->opaque[1] == CTL_VOL && \
- (fidp)->opaque[2] == CTL_VNO && \
- (fidp)->opaque[3] == CTL_UNI)
-#define INVAL_FID { { 0, 0, 0, 0 } }
-#endif
-
-/* Data passed to mount */
-
-#define CODA_MOUNT_VERSION 1
-
-struct coda_mount_data {
- int version;
- int fd; /* Opened device */
-};
-
-#endif
-
diff --git a/sys/fs/coda/coda_fbsd.c b/sys/fs/coda/coda_fbsd.c
deleted file mode 100644
index 62d0857..0000000
--- a/sys/fs/coda/coda_fbsd.c
+++ /dev/null
@@ -1,148 +0,0 @@
-/*-
- * Coda: an Experimental Distributed File System
- * Release 3.1
- *
- * Copyright (c) 1987-1998 Carnegie Mellon University
- * All Rights Reserved
- *
- * Permission to use, copy, modify and distribute this software and its
- * documentation is hereby granted, provided that both the copyright
- * notice and this permission notice appear in all copies of the
- * software, derivative works or modified versions, and any portions
- * thereof, and that both notices appear in supporting documentation, and
- * that credit is given to Carnegie Mellon University in all documents
- * and publicity pertaining to direct or indirect use of this code or its
- * derivatives.
- *
- * CODA IS AN EXPERIMENTAL SOFTWARE SYSTEM AND IS KNOWN TO HAVE BUGS,
- * SOME OF WHICH MAY HAVE SERIOUS CONSEQUENCES. CARNEGIE MELLON ALLOWS
- * FREE USE OF THIS SOFTWARE IN ITS "AS IS" CONDITION. CARNEGIE MELLON
- * DISCLAIMS ANY LIABILITY OF ANY KIND FOR ANY DAMAGES WHATSOEVER
- * RESULTING DIRECTLY OR INDIRECTLY FROM THE USE OF THIS SOFTWARE OR OF
- * ANY DERIVATIVE WORK.
- *
- * Carnegie Mellon encourages users of this software to return any
- * improvements or extensions that they make, and to grant Carnegie
- * Mellon the rights to redistribute these changes without encumbrance.
- *
- * @(#) src/sys/coda/coda_fbsd.cr,v 1.1.1.1 1998/08/29 21:14:52 rvb Exp $
- */
-
-#include <sys/cdefs.h>
-__FBSDID("$FreeBSD$");
-
-#include <sys/param.h>
-#include <sys/systm.h>
-#include <sys/conf.h>
-#include <sys/fcntl.h>
-#include <sys/kernel.h>
-#include <sys/lock.h>
-#include <sys/malloc.h>
-#include <sys/module.h>
-#include <sys/ucred.h>
-#include <sys/vnode.h>
-
-#include <vm/vm.h>
-#include <vm/vnode_pager.h>
-
-#include <fs/coda/coda.h>
-#include <fs/coda/cnode.h>
-#include <fs/coda/coda_vnops.h>
-#include <fs/coda/coda_psdev.h>
-
-static struct cdevsw codadevsw = {
- .d_version = D_VERSION,
- .d_flags = D_NEEDGIANT,
- .d_open = vc_open,
- .d_close = vc_close,
- .d_read = vc_read,
- .d_write = vc_write,
- .d_ioctl = vc_ioctl,
- .d_poll = vc_poll,
- .d_name = "coda",
-};
-
-static eventhandler_tag clonetag;
-
-static LIST_HEAD(, coda_mntinfo) coda_mnttbl;
-
-/*
- * For DEVFS, using bpf & tun drivers as examples.
- *
- * XXX: Why use a cloned interface, aren't we really just interested in
- * having a single /dev/cfs0? It's not clear the coda module knows what to
- * do with more than one.
- */
-static void coda_fbsd_clone(void *arg, struct ucred *cred, char *name,
- int namelen, struct cdev **dev);
-
-static int
-codadev_modevent(module_t mod, int type, void *data)
-{
- struct coda_mntinfo *mnt;
-
- switch (type) {
- case MOD_LOAD:
- LIST_INIT(&coda_mnttbl);
- clonetag = EVENTHANDLER_REGISTER(dev_clone, coda_fbsd_clone,
- 0, 1000);
- break;
-
- case MOD_UNLOAD:
- /*
- * XXXRW: At the very least, a busy check should occur here
- * to prevent untimely unload. Much more serious collection
- * of allocated memory needs to take place; right now we leak
- * like a sieve.
- */
- EVENTHANDLER_DEREGISTER(dev_clone, clonetag);
- while ((mnt = LIST_FIRST(&coda_mnttbl)) != NULL) {
- LIST_REMOVE(mnt, mi_list);
- destroy_dev(mnt->dev);
- free(mnt, M_CODA);
- }
- break;
-
- default:
- return (EOPNOTSUPP);
- }
- return (0);
-}
-
-static moduledata_t codadev_mod = {
- "codadev",
- codadev_modevent,
- NULL
-};
-DECLARE_MODULE(codadev, codadev_mod, SI_SUB_DRIVERS, SI_ORDER_MIDDLE);
-
-static void
-coda_fbsd_clone(void *arg, struct ucred *cred, char *name, int namelen,
- struct cdev **dev)
-{
- struct coda_mntinfo *mnt;
- int u;
-
- if (*dev != NULL)
- return;
- if (dev_stdclone(name, NULL, "cfs", &u) != 1)
- return;
- *dev = make_dev(&codadevsw, u, UID_ROOT, GID_WHEEL, 0600,
- "cfs%d", u);
- dev_ref(*dev);
- mnt = malloc(sizeof(struct coda_mntinfo), M_CODA, M_WAITOK|M_ZERO);
- LIST_INSERT_HEAD(&coda_mnttbl, mnt, mi_list);
- mnt->dev = *dev;
-}
-
-struct coda_mntinfo *
-dev2coda_mntinfo(struct cdev *dev)
-{
- struct coda_mntinfo *mnt;
-
- LIST_FOREACH(mnt, &coda_mnttbl, mi_list) {
- if (mnt->dev == dev)
- return (mnt);
- }
- return (NULL);
-}
diff --git a/sys/fs/coda/coda_io.h b/sys/fs/coda/coda_io.h
deleted file mode 100644
index 6058cf0..0000000
--- a/sys/fs/coda/coda_io.h
+++ /dev/null
@@ -1,73 +0,0 @@
-/*-
- *
- * Coda: an Experimental Distributed File System
- * Release 3.1
- *
- * Copyright (c) 1987-1998 Carnegie Mellon University
- * All Rights Reserved
- *
- * Permission to use, copy, modify and distribute this software and its
- * documentation is hereby granted, provided that both the copyright
- * notice and this permission notice appear in all copies of the
- * software, derivative works or modified versions, and any portions
- * thereof, and that both notices appear in supporting documentation, and
- * that credit is given to Carnegie Mellon University in all documents
- * and publicity pertaining to direct or indirect use of this code or its
- * derivatives.
- *
- * CODA IS AN EXPERIMENTAL SOFTWARE SYSTEM AND IS KNOWN TO HAVE BUGS,
- * SOME OF WHICH MAY HAVE SERIOUS CONSEQUENCES. CARNEGIE MELLON ALLOWS
- * FREE USE OF THIS SOFTWARE IN ITS "AS IS" CONDITION. CARNEGIE MELLON
- * DISCLAIMS ANY LIABILITY OF ANY KIND FOR ANY DAMAGES WHATSOEVER
- * RESULTING DIRECTLY OR INDIRECTLY FROM THE USE OF THIS SOFTWARE OR OF
- * ANY DERIVATIVE WORK.
- *
- * Carnegie Mellon encourages users of this software to return any
- * improvements or extensions that they make, and to grant Carnegie
- * Mellon the rights to redistribute these changes without encumbrance.
- *
- * @(#) src/sys/coda/coda_io.h,v 1.1.1.1 1998/08/29 21:14:52 rvb Exp $
- * $FreeBSD$
- *
- */
-
-/*-
- * Mach Operating System
- * Copyright (c) 1990 Carnegie-Mellon University
- * Copyright (c) 1989 Carnegie-Mellon University
- * All rights reserved. The CMU software License Agreement specifies
- * the terms and conditions for use and redistribution.
- */
-
-/*
- * This code was written for the Coda filesystem at Carnegie Mellon University.
- * Contributers include David Steere, James Kistler, and M. Satyanarayanan.
- */
-
-#ifndef _CODAIO_H_
-#define _CODAIO_H_
-
-/*
- * Define ioctl commands for vcioctl, /dev/cfs.
- *
- * Resize Coda namecache.
- */
-#define CODARESIZE _IOW('c', 1, struct coda_resize)
-
-/*
- * Collect statistics.
- */
-#define CODASTATS _IO('c', 2)
-
-/*
- * Print cache.
- */
-#define CODAPRINT _IO('c', 3)
-#define CODATEST _IO('c', 4)
-
-struct coda_resize {
- int hashsize;
- int heapsize;
-};
-
-#endif /* !_CODAIO_H_ */
diff --git a/sys/fs/coda/coda_opstats.h b/sys/fs/coda/coda_opstats.h
deleted file mode 100644
index 36805e8..0000000
--- a/sys/fs/coda/coda_opstats.h
+++ /dev/null
@@ -1,130 +0,0 @@
-/*-
- *
- * Coda: an Experimental Distributed File System
- * Release 3.1
- *
- * Copyright (c) 1987-1998 Carnegie Mellon University
- * All Rights Reserved
- *
- * Permission to use, copy, modify and distribute this software and its
- * documentation is hereby granted, provided that both the copyright
- * notice and this permission notice appear in all copies of the
- * software, derivative works or modified versions, and any portions
- * thereof, and that both notices appear in supporting documentation, and
- * that credit is given to Carnegie Mellon University in all documents
- * and publicity pertaining to direct or indirect use of this code or its
- * derivatives.
- *
- * CODA IS AN EXPERIMENTAL SOFTWARE SYSTEM AND IS KNOWN TO HAVE BUGS,
- * SOME OF WHICH MAY HAVE SERIOUS CONSEQUENCES. CARNEGIE MELLON ALLOWS
- * FREE USE OF THIS SOFTWARE IN ITS "AS IS" CONDITION. CARNEGIE MELLON
- * DISCLAIMS ANY LIABILITY OF ANY KIND FOR ANY DAMAGES WHATSOEVER
- * RESULTING DIRECTLY OR INDIRECTLY FROM THE USE OF THIS SOFTWARE OR OF
- * ANY DERIVATIVE WORK.
- *
- * Carnegie Mellon encourages users of this software to return any
- * improvements or extensions that they make, and to grant Carnegie
- * Mellon the rights to redistribute these changes without encumbrance.
- *
- * @(#) src/sys/coda/coda_opstats.h,v 1.1.1.1 1998/08/29 21:14:52 rvb Exp $
- * $FreeBSD$
- *
- */
-
-#ifndef _CODA_OPSTATS_H_
-#define _CODA_OPSTATS_H_
-
-/*
- * Operation stats: what the minicache can intercept that *isn't* seen by
- * venus. These stats are kept to augment the stats maintained by the
- * Volume-Session mechanism.
- */
-
-/*-
- * vfsops:
- * mount: not currently bounced to Venus
- * umount: nope
- * root: only first call, rest is cached.
- * statfs: none (bogus)
- * sync: none (bogus)
- * vget: all
- */
-#define CODA_MOUNT_STATS 0
-#define CODA_UMOUNT_STATS 1
-#define CODA_ROOT_STATS 2
-#define CODA_STATFS_STATS 3
-#define CODA_SYNC_STATS 4
-#define CODA_VGET_STATS 5
-#define CODA_VFSOPS_SIZE 6
-
-/*-
- * vnodeops:
- * open: all to venus
- * close: all to venus
- * rdrw: bogus. Maybe redirected to UFS.
- * May call open/close for internal opens/closes
- * (Does exec not call open?)
- * ioctl: causes a lookupname
- * passes through
- * select: can't get there from here.
- * getattr: can be satsified by cache
- * setattr: all go through
- * access: can be satisfied by cache
- * readlink: can be satisfied by cache
- * fsync: passes through
- * inactive: passes through
- * lookup: can be satisfied by cache
- * create: passes through
- * remove: passes through
- * link: passes through
- * rename: passes through
- * mkdir: passes through
- * rmdir: passes through
- * symlink: passes through
- * readdir: may be redirected to UFS
- * may cause an "internal" open/close
- */
-#define CODA_OPEN_STATS 0
-#define CODA_CLOSE_STATS 1
-#define CODA_RDWR_STATS 2
-#define CODA_IOCTL_STATS 3
-#define CODA_SELECT_STATS 4
-#define CODA_GETATTR_STATS 5
-#define CODA_SETATTR_STATS 6
-#define CODA_ACCESS_STATS 7
-#define CODA_READLINK_STATS 8
-#define CODA_FSYNC_STATS 9
-#define CODA_INACTIVE_STATS 10
-#define CODA_LOOKUP_STATS 11
-#define CODA_CREATE_STATS 12
-#define CODA_REMOVE_STATS 13
-#define CODA_LINK_STATS 14
-#define CODA_RENAME_STATS 15
-#define CODA_MKDIR_STATS 16
-#define CODA_RMDIR_STATS 17
-#define CODA_SYMLINK_STATS 18
-#define CODA_READDIR_STATS 19
-#define CODA_VNODEOPS_SIZE 20
-
-/*
- * I propose the following structres:
- */
-struct coda_op_stats {
- int opcode; /* vfs opcode */
- long entries; /* number of times call attempted */
- long sat_intrn; /* number of times call satisfied by cache */
- long unsat_intrn; /* number of times call failed in cache, but */
- /* was not bounced to venus proper. */
- long gen_intrn; /* number of times call generated internally */
- /* (do we need that?) */
-};
-
-/*
- * With each call to the minicache, we'll bump the counters whenver a call is
- * satisfied internally (through the cache or through a redirect), and
- * whenever an operation is caused internally. Then, we can add the total
- * operations caught by the minicache to the world-wide totals, and leave a
- * caveat for the specific graphs later.
- */
-
-#endif /* !_CODA_OPSTATS_H_ */
diff --git a/sys/fs/coda/coda_pioctl.h b/sys/fs/coda/coda_pioctl.h
deleted file mode 100644
index 3c9d0c6..0000000
--- a/sys/fs/coda/coda_pioctl.h
+++ /dev/null
@@ -1,69 +0,0 @@
-/*-
- *
- * Coda: an Experimental Distributed File System
- * Release 3.1
- *
- * Copyright (c) 1987-1998 Carnegie Mellon University
- * All Rights Reserved
- *
- * Permission to use, copy, modify and distribute this software and its
- * documentation is hereby granted, provided that both the copyright
- * notice and this permission notice appear in all copies of the
- * software, derivative works or modified versions, and any portions
- * thereof, and that both notices appear in supporting documentation, and
- * that credit is given to Carnegie Mellon University in all documents
- * and publicity pertaining to direct or indirect use of this code or its
- * derivatives.
- *
- * CODA IS AN EXPERIMENTAL SOFTWARE SYSTEM AND IS KNOWN TO HAVE BUGS,
- * SOME OF WHICH MAY HAVE SERIOUS CONSEQUENCES. CARNEGIE MELLON ALLOWS
- * FREE USE OF THIS SOFTWARE IN ITS "AS IS" CONDITION. CARNEGIE MELLON
- * DISCLAIMS ANY LIABILITY OF ANY KIND FOR ANY DAMAGES WHATSOEVER
- * RESULTING DIRECTLY OR INDIRECTLY FROM THE USE OF THIS SOFTWARE OR OF
- * ANY DERIVATIVE WORK.
- *
- * Carnegie Mellon encourages users of this software to return any
- * improvements or extensions that they make, and to grant Carnegie
- * Mellon the rights to redistribute these changes without encumbrance.
- *
- * @(#) src/sys/coda/coda_pioctl.h,v 1.1.1.1 1998/08/29 21:14:52 rvb Exp $
- * $FreeBSD$
- *
- */
-
-/*-
- * Mach Operating System
- * Copyright (c) 1989 Carnegie-Mellon University
- * Copyright (c) 1988 Carnegie-Mellon University
- * Copyright (c) 1987 Carnegie-Mellon University
- * All rights reserved. The CMU software License Agreement specifies
- * the terms and conditions for use and redistribution.
- */
-
-/*
- * ITC Remote filesystem - vice ioctl interface module
- *
- * TODO: Find /usr/local/include/viceioctl.h.
- */
-
-#ifndef _SYS_PIOCTL_H_
-#define _SYS_PIOCTL_H_
-
-/*
- * The 2K limits above are a consequence of the size of the kernel buffer
- * used to buffer requests from the user to venus--2*MAXPATHLEN. The buffer
- * pointers may be null, or the counts may be 0 if there are no input or
- * output parameters.
- */
-#define _VICEIOCTL(id) ((unsigned int )_IOW('V', id, struct ViceIoctl))
-
-/*
- * Use this macro to define up to 256 vice ioctl's. These ioctl's all
- * potentially have in/out parameters--this depends upon the values in the
- * ViceIoctl structure. This structure is itself passed into the kernel by
- * the normal ioctl parameter passing mechanism.
- */
-#define _VALIDVICEIOCTL(com) (com >= _VICEIOCTL(0) && \
- com <= _VICEIOCTL(255))
-
-#endif /* !_SYS_PIOCTL_H_ */
diff --git a/sys/fs/coda/coda_psdev.c b/sys/fs/coda/coda_psdev.c
deleted file mode 100644
index e982a2c..0000000
--- a/sys/fs/coda/coda_psdev.c
+++ /dev/null
@@ -1,675 +0,0 @@
-/*-
- * Coda: an Experimental Distributed File System
- * Release 3.1
- *
- * Copyright (c) 1987-1998 Carnegie Mellon University
- * All Rights Reserved
- *
- * Permission to use, copy, modify and distribute this software and its
- * documentation is hereby granted, provided that both the copyright
- * notice and this permission notice appear in all copies of the
- * software, derivative works or modified versions, and any portions
- * thereof, and that both notices appear in supporting documentation, and
- * that credit is given to Carnegie Mellon University in all documents
- * and publicity pertaining to direct or indirect use of this code or its
- * derivatives.
- *
- * CODA IS AN EXPERIMENTAL SOFTWARE SYSTEM AND IS KNOWN TO HAVE BUGS,
- * SOME OF WHICH MAY HAVE SERIOUS CONSEQUENCES. CARNEGIE MELLON ALLOWS
- * FREE USE OF THIS SOFTWARE IN ITS "AS IS" CONDITION. CARNEGIE MELLON
- * DISCLAIMS ANY LIABILITY OF ANY KIND FOR ANY DAMAGES WHATSOEVER
- * RESULTING DIRECTLY OR INDIRECTLY FROM THE USE OF THIS SOFTWARE OR OF
- * ANY DERIVATIVE WORK.
- *
- * Carnegie Mellon encourages users of this software to return any
- * improvements or extensions that they make, and to grant Carnegie
- * Mellon the rights to redistribute these changes without encumbrance.
- *
- * @(#) src/sys/coda/coda_psdev.c,v 1.1.1.1 1998/08/29 21:14:52 rvb Exp $
- */
-/*-
- * Mach Operating System
- * Copyright (c) 1989 Carnegie-Mellon University
- * All rights reserved. The CMU software License Agreement specifies
- * the terms and conditions for use and redistribution.
- */
-
-/*
- * This code was written for the Coda filesystem at Carnegie Mellon
- * University. Contributers include David Steere, James Kistler, and
- * M. Satyanarayanan. */
-
-/*
- * These routines define the psuedo device for communication between Coda's
- * Venus and Minicache in Mach 2.6. They used to be in cfs_subr.c, but I
- * moved them to make it easier to port the Minicache without porting coda.
- * -- DCS 10/12/94
- */
-
-/*
- * These routines are the device entry points for Venus.
- */
-
-#include <sys/cdefs.h>
-__FBSDID("$FreeBSD$");
-
-#include <sys/param.h>
-#include <sys/systm.h>
-#include <sys/capability.h>
-#include <sys/conf.h>
-#include <sys/ioccom.h>
-#include <sys/kernel.h>
-#include <sys/lock.h>
-#include <sys/malloc.h>
-#include <sys/file.h> /* must come after sys/malloc.h */
-#include <sys/mount.h>
-#include <sys/mutex.h>
-#include <sys/poll.h>
-#include <sys/proc.h>
-#include <sys/filedesc.h>
-
-#include <fs/coda/coda.h>
-#include <fs/coda/cnode.h>
-#include <fs/coda/coda_io.h>
-#include <fs/coda/coda_psdev.h>
-
-/*
- * Variables to determine how Coda sleeps and whether or not it is
- * interruptible when it does sleep waiting for Venus.
- */
-/* #define CTL_C */
-
-#ifdef CTL_C
-#include <sys/signalvar.h>
-#endif
-
-int coda_psdev_print_entry = 0;
-static int outstanding_upcalls = 0;
-int coda_call_sleep = PZERO - 1;
-#ifdef CTL_C
-int coda_pcatch = PCATCH;
-#else
-#endif
-
-#define ENTRY do { \
- if (coda_psdev_print_entry) \
- myprintf(("Entered %s\n", __func__)); \
-} while (0)
-
-struct vmsg {
- TAILQ_ENTRY(vmsg) vm_chain;
- caddr_t vm_data;
- u_short vm_flags;
- u_short vm_inSize; /* Size is at most 5000 bytes */
- u_short vm_outSize;
- u_short vm_opcode; /* Copied from data to save ptr deref */
- int vm_unique;
- caddr_t vm_sleep; /* Not used by Mach. */
-};
-
-#define VM_READ 1
-#define VM_WRITE 2
-#define VM_INTR 4 /* Unused. */
-
-int
-vc_open(struct cdev *dev, int flag, int mode, struct thread *td)
-{
- struct vcomm *vcp;
- struct coda_mntinfo *mnt;
-
- ENTRY;
- mnt = dev2coda_mntinfo(dev);
- KASSERT(mnt, ("Coda: tried to open uninitialized cfs device"));
- vcp = &mnt->mi_vcomm;
- if (VC_OPEN(vcp))
- return (EBUSY);
- bzero(&(vcp->vc_selproc), sizeof (struct selinfo));
- TAILQ_INIT(&vcp->vc_requests);
- TAILQ_INIT(&vcp->vc_replies);
- MARK_VC_OPEN(vcp);
- mnt->mi_vfsp = NULL;
- mnt->mi_rootvp = NULL;
- return (0);
-}
-
-int
-vc_close(struct cdev *dev, int flag, int mode, struct thread *td)
-{
- struct vcomm *vcp;
- struct vmsg *vmp, *nvmp = NULL;
- struct coda_mntinfo *mi;
- int err;
-
- ENTRY;
- mi = dev2coda_mntinfo(dev);
- KASSERT(mi, ("Coda: closing unknown cfs device"));
- vcp = &mi->mi_vcomm;
- KASSERT(VC_OPEN(vcp), ("Coda: closing unopened cfs device"));
-
- /*
- * Prevent future operations on this vfs from succeeding by
- * auto-unmounting any vfs mounted via this device. This frees user
- * or sysadm from having to remember where all mount points are
- * located. Put this before WAKEUPs to avoid queuing new messages
- * between the WAKEUP and the unmount (which can happen if we're
- * unlucky).
- */
- if (mi->mi_rootvp == NULL) {
- /*
- * Just a simple open/close with no mount.
- */
- MARK_VC_CLOSED(vcp);
- return (0);
- }
-
- /*
- * Let unmount know this is for real.
- */
- VTOC(mi->mi_rootvp)->c_flags |= C_UNMOUNTING;
- coda_unmounting(mi->mi_vfsp);
-
- /*
- * Wakeup clients so they can return.
- */
- outstanding_upcalls = 0;
- TAILQ_FOREACH_SAFE(vmp, &vcp->vc_requests, vm_chain, nvmp) {
- /*
- * Free signal request messages and don't wakeup cause no one
- * is waiting.
- */
- if (vmp->vm_opcode == CODA_SIGNAL) {
- CODA_FREE((caddr_t)vmp->vm_data,
- (u_int)VC_IN_NO_DATA);
- CODA_FREE((caddr_t)vmp, (u_int)sizeof(struct vmsg));
- continue;
- }
- outstanding_upcalls++;
- wakeup(&vmp->vm_sleep);
- }
- TAILQ_FOREACH(vmp, &vcp->vc_replies, vm_chain) {
- outstanding_upcalls++;
- wakeup(&vmp->vm_sleep);
- }
- MARK_VC_CLOSED(vcp);
- if (outstanding_upcalls) {
-#ifdef CODA_VERBOSE
- printf("presleep: outstanding_upcalls = %d\n",
- outstanding_upcalls);
-#endif
- (void) tsleep(&outstanding_upcalls, coda_call_sleep,
- "coda_umount", 0);
-#ifdef CODA_VERBOSE
- printf("postsleep: outstanding_upcalls = %d\n",
- outstanding_upcalls);
-#endif
- }
- err = dounmount(mi->mi_vfsp, flag, td);
- if (err)
- myprintf(("Error %d unmounting vfs in vcclose(%s)\n", err,
- devtoname(dev)));
- return (0);
-}
-
-int
-vc_read(struct cdev *dev, struct uio *uiop, int flag)
-{
- struct vcomm *vcp;
- struct vmsg *vmp;
- int error = 0;
-
- ENTRY;
- vcp = &dev2coda_mntinfo(dev)->mi_vcomm;
-
- /*
- * Get message at head of request queue.
- */
- vmp = TAILQ_FIRST(&vcp->vc_requests);
- if (vmp == NULL)
- return (0); /* Nothing to read */
-
- /*
- * Move the input args into userspace.
- *
- * XXXRW: This is not safe in the presence of >1 reader, as vmp is
- * still on the head of the list.
- */
- uiop->uio_rw = UIO_READ;
- error = uiomove(vmp->vm_data, vmp->vm_inSize, uiop);
- if (error) {
- myprintf(("vcread: error (%d) on uiomove\n", error));
- error = EINVAL;
- }
- TAILQ_REMOVE(&vcp->vc_requests, vmp, vm_chain);
-
- /*
- * If request was a signal, free up the message and don't enqueue it
- * in the reply queue.
- */
- if (vmp->vm_opcode == CODA_SIGNAL) {
- if (codadebug)
- myprintf(("vcread: signal msg (%d, %d)\n",
- vmp->vm_opcode, vmp->vm_unique));
- CODA_FREE((caddr_t)vmp->vm_data, (u_int)VC_IN_NO_DATA);
- CODA_FREE((caddr_t)vmp, (u_int)sizeof(struct vmsg));
- return (error);
- }
- vmp->vm_flags |= VM_READ;
- TAILQ_INSERT_TAIL(&vcp->vc_replies, vmp, vm_chain);
- return (error);
-}
-
-int
-vc_write(struct cdev *dev, struct uio *uiop, int flag)
-{
- struct vcomm *vcp;
- struct vmsg *vmp;
- struct coda_out_hdr *out;
- u_long seq;
- u_long opcode;
- int buf[2];
- int error = 0;
-
- ENTRY;
- vcp = &dev2coda_mntinfo(dev)->mi_vcomm;
-
- /*
- * Peek at the opcode, unique without transfering the data.
- */
- uiop->uio_rw = UIO_WRITE;
- error = uiomove((caddr_t)buf, sizeof(int) * 2, uiop);
- if (error) {
- myprintf(("vcwrite: error (%d) on uiomove\n", error));
- return (EINVAL);
- }
- opcode = buf[0];
- seq = buf[1];
- if (codadebug)
- myprintf(("vcwrite got a call for %ld.%ld\n", opcode, seq));
- if (DOWNCALL(opcode)) {
- union outputArgs pbuf;
-
- /*
- * Get the rest of the data.
- */
- uiop->uio_rw = UIO_WRITE;
- error = uiomove((caddr_t)&pbuf.coda_purgeuser.oh.result,
- sizeof(pbuf) - (sizeof(int)*2), uiop);
- if (error) {
- myprintf(("vcwrite: error (%d) on uiomove (Op %ld "
- "seq %ld)\n", error, opcode, seq));
- return (EINVAL);
- }
- return (handleDownCall(dev2coda_mntinfo(dev), opcode, &pbuf));
- }
-
- /*
- * Look for the message on the (waiting for) reply queue.
- */
- TAILQ_FOREACH(vmp, &vcp->vc_replies, vm_chain) {
- if (vmp->vm_unique == seq)
- break;
- }
- if (vmp == NULL) {
- if (codadebug)
- myprintf(("vcwrite: msg (%ld, %ld) not found\n",
- opcode, seq));
- return (ESRCH);
- }
-
- /*
- * Remove the message from the reply queue.
- */
- TAILQ_REMOVE(&vcp->vc_replies, vmp, vm_chain);
-
- /*
- * Move data into response buffer.
- */
- out = (struct coda_out_hdr *)vmp->vm_data;
-
- /*
- * Don't need to copy opcode and uniquifier.
- *
- * Get the rest of the data.
- */
- if (vmp->vm_outSize < uiop->uio_resid) {
- myprintf(("vcwrite: more data than asked for (%d < %zd)\n",
- vmp->vm_outSize, uiop->uio_resid));
-
- /*
- * Notify caller of the error.
- */
- wakeup(&vmp->vm_sleep);
- return (EINVAL);
- }
-
- /*
- * Save the value.
- */
- buf[0] = uiop->uio_resid;
- uiop->uio_rw = UIO_WRITE;
- error = uiomove((caddr_t) &out->result, vmp->vm_outSize -
- (sizeof(int) * 2), uiop);
- if (error) {
- myprintf(("vcwrite: error (%d) on uiomove (op %ld seq %ld)\n",
- error, opcode, seq));
- return (EINVAL);
- }
-
- /*
- * I don't think these are used, but just in case.
- *
- * XXX - aren't these two already correct? -bnoble
- */
- out->opcode = opcode;
- out->unique = seq;
- vmp->vm_outSize = buf[0]; /* Amount of data transferred? */
- vmp->vm_flags |= VM_WRITE;
- error = 0;
- if (opcode == CODA_OPEN_BY_FD) {
- struct coda_open_by_fd_out *tmp =
- (struct coda_open_by_fd_out *)out;
- struct file *fp;
- struct vnode *vp = NULL;
-
- if (tmp->oh.result == 0) {
- error = getvnode(uiop->uio_td->td_proc->p_fd, CAP_WRITE,
- tmp->fd, &fp);
- if (!error) {
- /*
- * XXX: Since the whole driver runs with
- * Giant, don't actually need to acquire it
- * explicitly here yet.
- */
- mtx_lock(&Giant);
- vp = fp->f_vnode;
- VREF(vp);
- fdrop(fp, uiop->uio_td);
- mtx_unlock(&Giant);
- }
- }
- tmp->vp = vp;
- }
- wakeup(&vmp->vm_sleep);
- return (error);
-}
-
-int
-vc_ioctl(struct cdev *dev, u_long cmd, caddr_t addr, int flag,
- struct thread *t)
-{
-
- ENTRY;
- switch(cmd) {
- case CODARESIZE:
- return (ENODEV);
-
- case CODASTATS:
- return (ENODEV);
-
- case CODAPRINT:
- return (ENODEV);
-
- case CIOC_KERNEL_VERSION:
- switch (*(u_int *)addr) {
- case 0:
- *(u_int *)addr = coda_kernel_version;
- return (0);
-
- case 1:
- case 2:
- if (coda_kernel_version != *(u_int *)addr)
- return (ENOENT);
- else
- return (0);
-
- default:
- return (ENOENT);
- }
-
- default:
- return (EINVAL);
- }
-}
-
-int
-vc_poll(struct cdev *dev, int events, struct thread *td)
-{
- struct vcomm *vcp;
- int event_msk = 0;
-
- ENTRY;
- vcp = &dev2coda_mntinfo(dev)->mi_vcomm;
- event_msk = events & (POLLIN|POLLRDNORM);
- if (!event_msk)
- return (0);
- if (!TAILQ_EMPTY(&vcp->vc_requests))
- return (events & (POLLIN|POLLRDNORM));
- selrecord(td, &(vcp->vc_selproc));
- return (0);
-}
-
-/*
- * Statistics.
- */
-struct coda_clstat coda_clstat;
-
-/*
- * Key question: whether to sleep interuptably or uninteruptably when waiting
- * for Venus. The former seems better (cause you can ^C a job), but then
- * GNU-EMACS completion breaks. Use tsleep with no timeout, and no longjmp
- * happens. But, when sleeping "uninterruptibly", we don't get told if it
- * returns abnormally (e.g. kill -9).
- */
-int
-coda_call(struct coda_mntinfo *mntinfo, int inSize, int *outSize,
- caddr_t buffer)
-{
- struct vcomm *vcp;
- struct vmsg *vmp;
- int error;
-#ifdef CTL_C
- struct thread *td = curthread;
- struct proc *p = td->td_proc;
- sigset_t psig_omask;
- sigset_t tempset;
- int i;
-#endif
-
- /*
- * Unlikely, but could be a race condition with a dying warden.
- */
- if (mntinfo == NULL)
- return ENODEV;
- vcp = &(mntinfo->mi_vcomm);
- coda_clstat.ncalls++;
- coda_clstat.reqs[((struct coda_in_hdr *)buffer)->opcode]++;
- if (!VC_OPEN(vcp))
- return (ENODEV);
- CODA_ALLOC(vmp,struct vmsg *,sizeof(struct vmsg));
-
- /*
- * Format the request message.
- */
- vmp->vm_data = buffer;
- vmp->vm_flags = 0;
- vmp->vm_inSize = inSize;
- vmp->vm_outSize
- = *outSize ? *outSize : inSize; /* |buffer| >= inSize */
- vmp->vm_opcode = ((struct coda_in_hdr *)buffer)->opcode;
- vmp->vm_unique = ++vcp->vc_seq;
- if (codadebug)
- myprintf(("Doing a call for %d.%d\n", vmp->vm_opcode,
- vmp->vm_unique));
-
- /*
- * Fill in the common input args.
- */
- ((struct coda_in_hdr *)buffer)->unique = vmp->vm_unique;
-
- /*
- * Append msg to request queue and poke Venus.
- */
- TAILQ_INSERT_TAIL(&vcp->vc_requests, vmp, vm_chain);
- selwakeuppri(&(vcp->vc_selproc), coda_call_sleep);
-
- /*
- * We can be interrupted while we wait for Venus to process our
- * request. If the interrupt occurs before Venus has read the
- * request, we dequeue and return. If it occurs after the read but
- * before the reply, we dequeue, send a signal message, and return.
- * If it occurs after the reply we ignore it. In no case do we want
- * to restart the syscall. If it was interrupted by a venus shutdown
- * (vcclose), return ENODEV.
- *
- * Ignore return, we have to check anyway.
- */
-#ifdef CTL_C
- /*
- * This is work in progress. Setting coda_pcatch lets tsleep
- * reawaken on a ^c or ^z. The problem is that emacs sets certain
- * interrupts as SA_RESTART. This means that we should exit sleep
- * handle the "signal" and then go to sleep again. Mostly this is
- * done by letting the syscall complete and be restarted. We are not
- * idempotent and can not do this. A better solution is necessary.
- */
- i = 0;
- PROC_LOCK(p);
- psig_omask = td->td_sigmask;
- do {
- error = msleep(&vmp->vm_sleep, &p->p_mtx,
- (coda_call_sleep|coda_pcatch), "coda_call", hz*2);
- if (error == 0)
- break;
- else if (error == EWOULDBLOCK) {
-#ifdef CODA_VERBOSE
- printf("coda_call: tsleep TIMEOUT %d sec\n", 2+2*i);
-#endif
- }
- else {
- SIGEMPTYSET(tempset);
- SIGADDSET(tempset, SIGIO);
- if (SIGSETEQ(td->td_siglist, tempset)) {
- SIGADDSET(td->td_sigmask, SIGIO);
-#ifdef CODA_VERBOSE
- printf("coda_call: tsleep returns %d SIGIO, "
- "cnt %d\n", error, i);
-#endif
- } else {
- SIGDELSET(tempset, SIGIO);
- SIGADDSET(tempset, SIGALRM);
- if (SIGSETEQ(td->td_siglist, tempset)) {
- SIGADDSET(td->td_sigmask, SIGALRM);
-#ifdef CODA_VERBOSE
- printf("coda_call: tsleep returns "
- "%d SIGALRM, cnt %d\n", error, i);
-#endif
- } else {
-#ifdef CODA_VERBOSE
- printf("coda_call: tsleep returns "
- "%d, cnt %d\n", error, i);
-#endif
-
-#ifdef notyet
- tempset = td->td_siglist;
- SIGSETNAND(tempset, td->td_sigmask);
- printf("coda_call: siglist = %p, "
- "sigmask = %p, mask %p\n",
- td->td_siglist, td->td_sigmask,
- tempset);
- break;
- SIGSETOR(td->td_sigmask, td->td_siglist);
- tempset = td->td_siglist;
- SIGSETNAND(tempset, td->td_sigmask);
- printf("coda_call: new mask, "
- "siglist = %p, sigmask = %p, "
- "mask %p\n", td->td_siglist,
- td->td_sigmask, tempset);
-#endif
- }
- }
- }
- } while (error && i++ < 128 && VC_OPEN(vcp));
- td->td_sigmask = psig_omask;
- signotify(td);
- PROC_UNLOCK(p);
-#else
- (void)tsleep(&vmp->vm_sleep, coda_call_sleep, "coda_call", 0);
-#endif
- if (VC_OPEN(vcp)) {
- /*
- * Venus is still alive.
- *
- * Op went through, interrupt or not...
- */
- if (vmp->vm_flags & VM_WRITE) {
- error = 0;
- *outSize = vmp->vm_outSize;
- } else if (!(vmp->vm_flags & VM_READ)) {
- /* Interrupted before venus read it. */
-#ifdef CODA_VERBOSE
- if (1)
-#else
- if (codadebug)
-#endif
- myprintf(("interrupted before read: op = "
- "%d.%d, flags = %x\n", vmp->vm_opcode,
- vmp->vm_unique, vmp->vm_flags));
- TAILQ_REMOVE(&vcp->vc_requests, vmp, vm_chain);
- error = EINTR;
- } else {
- /*
- * (!(vmp->vm_flags & VM_WRITE)) means interrupted
- * after upcall started.
- *
- * Interrupted after start of upcall, send venus a
- * signal.
- */
- struct coda_in_hdr *dog;
- struct vmsg *svmp;
-
-#ifdef CODA_VERBOSE
- if (1)
-#else
- if (codadebug)
-#endif
- myprintf(("Sending Venus a signal: op = "
- "%d.%d, flags = %x\n", vmp->vm_opcode,
- vmp->vm_unique, vmp->vm_flags));
- TAILQ_REMOVE(&vcp->vc_requests, vmp, vm_chain);
- error = EINTR;
- CODA_ALLOC(svmp, struct vmsg *, sizeof(struct vmsg));
- CODA_ALLOC((svmp->vm_data), char *,
- sizeof(struct coda_in_hdr));
- dog = (struct coda_in_hdr *)svmp->vm_data;
- svmp->vm_flags = 0;
- dog->opcode = svmp->vm_opcode = CODA_SIGNAL;
- dog->unique = svmp->vm_unique = vmp->vm_unique;
- svmp->vm_inSize = sizeof (struct coda_in_hdr);
-/*??? rvb */ svmp->vm_outSize = sizeof (struct coda_in_hdr);
- if (codadebug)
- myprintf(("coda_call: enqueing signal msg "
- "(%d, %d)\n", svmp->vm_opcode,
- svmp->vm_unique));
-
- /*
- * Insert at head of queue!
- *
- * XXXRW: Actually, the tail.
- */
- TAILQ_INSERT_TAIL(&vcp->vc_requests, svmp, vm_chain);
- selwakeuppri(&(vcp->vc_selproc), coda_call_sleep);
- }
- } else {
- /* If venus died (!VC_OPEN(vcp)) */
- if (codadebug)
- myprintf(("vcclose woke op %d.%d flags %d\n",
- vmp->vm_opcode, vmp->vm_unique, vmp->vm_flags));
- error = ENODEV;
- }
- CODA_FREE(vmp, sizeof(struct vmsg));
- if (outstanding_upcalls > 0 && (--outstanding_upcalls == 0))
- wakeup(&outstanding_upcalls);
- if (!error)
- error = ((struct coda_out_hdr *)buffer)->result;
- return (error);
-}
diff --git a/sys/fs/coda/coda_psdev.h b/sys/fs/coda/coda_psdev.h
deleted file mode 100644
index 021456b..0000000
--- a/sys/fs/coda/coda_psdev.h
+++ /dev/null
@@ -1,46 +0,0 @@
-/*-
- *
- * Coda: an Experimental Distributed File System
- * Release 3.1
- *
- * Copyright (c) 1998 Carnegie Mellon University
- * All Rights Reserved
- *
- * Permission to use, copy, modify and distribute this software and its
- * documentation is hereby granted, provided that both the copyright
- * notice and this permission notice appear in all copies of the
- * software, derivative works or modified versions, and any portions
- * thereof, and that both notices appear in supporting documentation, and
- * that credit is given to Carnegie Mellon University in all documents
- * and publicity pertaining to direct or indirect use of this code or its
- * derivatives.
- *
- * CODA IS AN EXPERIMENTAL SOFTWARE SYSTEM AND IS KNOWN TO HAVE BUGS,
- * SOME OF WHICH MAY HAVE SERIOUS CONSEQUENCES. CARNEGIE MELLON ALLOWS
- * FREE USE OF THIS SOFTWARE IN ITS "AS IS" CONDITION. CARNEGIE MELLON
- * DISCLAIMS ANY LIABILITY OF ANY KIND FOR ANY DAMAGES WHATSOEVER
- * RESULTING DIRECTLY OR INDIRECTLY FROM THE USE OF THIS SOFTWARE OR OF
- * ANY DERIVATIVE WORK.
- *
- * Carnegie Mellon encourages users of this software to return any
- * improvements or extensions that they make, and to grant Carnegie
- * Mellon the rights to redistribute these changes without encumbrance.
- *
- * @(#) src/sys/coda/coda_psdev.c,v 1.1.1.1 1998/08/29 21:14:52 rvb Exp $
- * $FreeBSD$
- */
-
-#ifndef _CODA_PSDEV_H_
-#define _CODA_PSDEV_H_
-
-/*
- * Prototypes for cfs device operations.
- */
-d_open_t vc_open;
-d_close_t vc_close;
-d_read_t vc_read;
-d_write_t vc_write;
-d_ioctl_t vc_ioctl;
-d_poll_t vc_poll;
-
-#endif /* !_CODA_PSDEV_H_ */
diff --git a/sys/fs/coda/coda_subr.c b/sys/fs/coda/coda_subr.c
deleted file mode 100644
index a7ae354..0000000
--- a/sys/fs/coda/coda_subr.c
+++ /dev/null
@@ -1,628 +0,0 @@
-/*-
- * Coda: an Experimental Distributed File System
- * Release 3.1
- *
- * Copyright (c) 1987-1998 Carnegie Mellon University
- * All Rights Reserved
- *
- * Permission to use, copy, modify and distribute this software and its
- * documentation is hereby granted, provided that both the copyright
- * notice and this permission notice appear in all copies of the
- * software, derivative works or modified versions, and any portions
- * thereof, and that both notices appear in supporting documentation, and
- * that credit is given to Carnegie Mellon University in all documents
- * and publicity pertaining to direct or indirect use of this code or its
- * derivatives.
- *
- * CODA IS AN EXPERIMENTAL SOFTWARE SYSTEM AND IS KNOWN TO HAVE BUGS,
- * SOME OF WHICH MAY HAVE SERIOUS CONSEQUENCES. CARNEGIE MELLON ALLOWS
- * FREE USE OF THIS SOFTWARE IN ITS "AS IS" CONDITION. CARNEGIE MELLON
- * DISCLAIMS ANY LIABILITY OF ANY KIND FOR ANY DAMAGES WHATSOEVER
- * RESULTING DIRECTLY OR INDIRECTLY FROM THE USE OF THIS SOFTWARE OR OF
- * ANY DERIVATIVE WORK.
- *
- * Carnegie Mellon encourages users of this software to return any
- * improvements or extensions that they make, and to grant Carnegie
- * Mellon the rights to redistribute these changes without encumbrance.
- *
- * @(#) src/sys/coda/coda_subr.c,v 1.1.1.1 1998/08/29 21:14:52 rvb Exp $
- */
-
-/*-
- * Mach Operating System
- * Copyright (c) 1989 Carnegie-Mellon University
- * All rights reserved. The CMU software License Agreement specifies
- * the terms and conditions for use and redistribution.
- */
-
-/*
- * This code was written for the Coda filesystem at Carnegie Mellon
- * University. Contributers include David Steere, James Kistler, and
- * M. Satyanarayanan.
- */
-
-/*-
- * NOTES: rvb
- * 1. Added coda_unmounting to mark all cnodes as being UNMOUNTING. This
- * has to be done before dounmount is called. Because some of the
- * routines that dounmount calls before coda_unmounted might try to
- * force flushes to venus. The vnode pager does this.
- * 2. coda_unmounting marks all cnodes scanning coda_cache.
- * 3. cfs_checkunmounting (under DEBUG) checks all cnodes by chasing the
- * vnodes under the /coda mount point.
- * 4. coda_cacheprint (under DEBUG) prints names with vnode/cnode address.
- */
-
-#include <sys/cdefs.h>
-__FBSDID("$FreeBSD$");
-
-#include <sys/param.h>
-#include <sys/systm.h>
-#include <sys/lock.h>
-#include <sys/malloc.h>
-#include <sys/mutex.h>
-#include <sys/mount.h>
-
-#include <fs/coda/coda.h>
-#include <fs/coda/cnode.h>
-#include <fs/coda/coda_subr.h>
-
-static int coda_active = 0;
-static int coda_reuse = 0;
-static int coda_new = 0;
-
-static struct cnode *coda_freelist = NULL;
-static struct cnode *coda_cache[CODA_CACHESIZE];
-
-#define CNODE_NEXT(cp) ((cp)->c_next)
-
-#ifdef CODA_COMPAT_5
-#define coda_hash(fid) (((fid)->Volume + (fid)->Vnode) & (CODA_CACHESIZE-1))
-#define IS_DIR(cnode) (cnode.Vnode & 0x1)
-#else
-#define coda_hash(fid) (coda_f2i(fid) & (CODA_CACHESIZE-1))
-#define IS_DIR(cnode) (cnode.opaque[2] & 0x1)
-#endif
-
-/*
- * Allocate a cnode.
- */
-struct cnode *
-coda_alloc(void)
-{
- struct cnode *cp;
-
- if (coda_freelist != NULL) {
- cp = coda_freelist;
- coda_freelist = CNODE_NEXT(cp);
- coda_reuse++;
- } else {
- CODA_ALLOC(cp, struct cnode *, sizeof(struct cnode));
-
- /*
- * FreeBSD vnodes don't have any Pager info in them ('cause
- * there are no external pagers, duh!).
- */
-#define VNODE_VM_INFO_INIT(vp) /* MT */
- VNODE_VM_INFO_INIT(CTOV(cp));
- coda_new++;
- }
- bzero(cp, sizeof (struct cnode));
- return (cp);
-}
-
-/*
- * Deallocate a cnode.
- */
-void
-coda_free(struct cnode *cp)
-{
-
- CNODE_NEXT(cp) = coda_freelist;
- coda_freelist = cp;
-}
-
-/*
- * Put a cnode in the hash table.
- */
-void
-coda_save(struct cnode *cp)
-{
-
- CNODE_NEXT(cp) = coda_cache[coda_hash(&cp->c_fid)];
- coda_cache[coda_hash(&cp->c_fid)] = cp;
-}
-
-/*
- * Remove a cnode from the hash table.
- */
-void
-coda_unsave(struct cnode *cp)
-{
- struct cnode *ptr;
- struct cnode *ptrprev = NULL;
-
- ptr = coda_cache[coda_hash(&cp->c_fid)];
- while (ptr != NULL) {
- if (ptr == cp) {
- if (ptrprev == NULL)
- coda_cache[coda_hash(&cp->c_fid)] =
- CNODE_NEXT(ptr);
- else
- CNODE_NEXT(ptrprev) = CNODE_NEXT(ptr);
- CNODE_NEXT(cp) = (struct cnode *)NULL;
- return;
- }
- ptrprev = ptr;
- ptr = CNODE_NEXT(ptr);
- }
-}
-
-/*
- * Lookup a cnode by fid. If the cnode is dying, it is bogus so skip it.
- *
- * NOTE: this allows multiple cnodes with same fid -- dcs 1/25/95
- */
-struct cnode *
-coda_find(struct CodaFid *fid)
-{
- struct cnode *cp;
-
- cp = coda_cache[coda_hash(fid)];
- while (cp) {
- if (coda_fid_eq(&(cp->c_fid), fid) && (!IS_UNMOUNTING(cp))) {
- coda_active++;
- return (cp);
- }
- cp = CNODE_NEXT(cp);
- }
- return (NULL);
-}
-
-/*
- * Clear all cached access control decisions from Coda.
- */
-static void
-coda_acccache_purge(struct mount *mnt)
-{
- struct cnode *cp;
- int hash;
-
- for (hash = 0; hash < CODA_CACHESIZE; hash++) {
- for (cp = coda_cache[hash]; cp != NULL;
- cp = CNODE_NEXT(cp)) {
- if (CTOV(cp)->v_mount == mnt && VALID_ACCCACHE(cp)) {
- CODADEBUG(CODA_FLUSH, myprintf(("acccache "
- "purge fid %s uid %d mode 0x%x\n",
- coda_f2s(&cp->c_fid), cp->c_cached_uid,
- (int)cp->c_cached_mode)););
- cp->c_flags &= ~C_ACCCACHE;
- }
- }
- }
-}
-
-/*
- * When a user loses their tokens (or other related events), we invalidate
- * any cached access rights in the access cache. In the Linux version of
- * Coda, we maintain a global epoch and simply bump it to invalidate all
- * cached results generated in the epoch. For now, we walk all cnodes and
- * manually invalidate just that uid in FreeBSD.
- */
-static void
-coda_acccache_purgeuser(struct mount *mnt, uid_t uid)
-{
- struct cnode *cp;
- int hash;
-
- for (hash = 0; hash < CODA_CACHESIZE; hash++) {
- for (cp = coda_cache[hash]; cp != NULL;
- cp = CNODE_NEXT(cp)) {
- if (CTOV(cp)->v_mount == mnt &&
- VALID_ACCCACHE(cp) && (cp->c_cached_uid == uid)) {
- CODADEBUG(CODA_PURGEUSER, myprintf((
- "acccache purgeuser fid %s uid %d mode "
- "0x%x\n", coda_f2s(&cp->c_fid),
- cp->c_cached_uid, (int)cp->c_cached_mode)););
- cp->c_flags &= ~C_ACCCACHE;
- }
- }
- }
-}
-
-/*
- * coda_kill is called as a side effect to vcopen. To prevent any cnodes
- * left around from an earlier run of a venus or warden from causing problems
- * with the new instance, mark any outstanding cnodes as dying. Future
- * operations on these cnodes should fail (excepting coda_inactive of
- * course!). Since multiple venii/wardens can be running, only kill the
- * cnodes for a particular entry in the coda_mnttbl. -- DCS 12/1/94
- *
- * XXX: I don't believe any special behavior is required with respect to the
- * global namecache here, as /coda will have unmounted and hence cache_flush
- * will have run...?
- */
-int
-coda_kill(struct mount *whoIam, enum dc_status dcstat)
-{
- int hash, count = 0;
- struct cnode *cp;
-
- /*-
- * Algorithm is as follows:
- * Second, flush whatever vnodes we can from the name cache.
- *
- * Finally, step through whatever is left and mark them dying.
- * This prevents any operation at all.
- *
- * This is slightly overkill, but should work. Eventually it'd be
- * nice to only flush those entries from the namecache that reference
- * a vnode in this vfs.
- *
- * XXXRW: Perhaps we no longer need to purge the name cache when
- * using the VFS name cache, as unmount will do that.
- */
- cache_purgevfs(whoIam);
- for (hash = 0; hash < CODA_CACHESIZE; hash++) {
- for (cp = coda_cache[hash];cp != NULL;
- cp = CNODE_NEXT(cp)) {
- if (CTOV(cp)->v_mount == whoIam) {
-#ifdef DEBUG
- printf("coda_kill: vp %p, cp %p\n", CTOV(cp),
- cp);
-#endif
- count++;
- CODADEBUG(CODA_FLUSH, myprintf(("Live cnode "
- "fid %s flags %d count %d\n",
- coda_f2s(&cp->c_fid), cp->c_flags,
- vrefcnt(CTOV(cp)))););
- }
- }
- }
- return (count);
-}
-
-/*
- * There are two reasons why a cnode may be in use, it may be in the name
- * cache or it may be executing.
- */
-void
-coda_flush(struct coda_mntinfo *mnt, enum dc_status dcstat)
-{
- int hash;
- struct cnode *cp;
-
- coda_clstat.ncalls++;
- coda_clstat.reqs[CODA_FLUSH]++;
-
- coda_acccache_purge(mnt->mi_vfsp);
- cache_purgevfs(mnt->mi_vfsp);
- for (hash = 0; hash < CODA_CACHESIZE; hash++) {
- for (cp = coda_cache[hash]; cp != NULL;
- cp = CNODE_NEXT(cp)) {
- /*
- * Only files that can be executed need to be flushed
- * from the VM.
- *
- * NOTE: Currently this doesn't do anything, but
- * perhaps it should?
- */
- if (!IS_DIR(cp->c_fid))
- coda_vmflush(cp);
- }
- }
-}
-
-/*
- * As a debugging measure, print out any cnodes that lived through a name
- * cache flush.
- */
-void
-coda_testflush(void)
-{
- int hash;
- struct cnode *cp;
-
- for (hash = 0; hash < CODA_CACHESIZE; hash++) {
- for (cp = coda_cache[hash]; cp != NULL;
- cp = CNODE_NEXT(cp))
- myprintf(("Live cnode fid %s count %d\n",
- coda_f2s(&cp->c_fid), CTOV(cp)->v_usecount));
- }
-}
-
-/*
- * First, step through all cnodes and mark them unmounting. FreeBSD kernels
- * may try to fsync them now that venus is dead, which would be a bad thing.
- */
-void
-coda_unmounting(struct mount *whoIam)
-{
- int hash;
- struct cnode *cp;
-
- for (hash = 0; hash < CODA_CACHESIZE; hash++) {
- for (cp = coda_cache[hash]; cp != NULL;
- cp = CNODE_NEXT(cp)) {
- if (CTOV(cp)->v_mount == whoIam) {
- if (cp->c_flags & (C_LOCKED|C_WANTED)) {
- printf("coda_unmounting: Unlocking "
- "%p\n", cp);
- cp->c_flags &= ~(C_LOCKED|C_WANTED);
- wakeup((caddr_t) cp);
- }
- cp->c_flags |= C_UNMOUNTING;
- }
- }
- }
-}
-
-#ifdef DEBUG
-void
-coda_checkunmounting(struct mount *mp)
-{
- struct vnode *vp, *nvp;
- struct cnode *cp;
- int count = 0, bad = 0;
-
- MNT_VNODE_FOREACH_ALL(vp, mp, nvp) {
- cp = VTOC(vp);
- count++;
- if (!(cp->c_flags & C_UNMOUNTING)) {
- bad++;
- printf("vp %p, cp %p missed\n", vp, cp);
- cp->c_flags |= C_UNMOUNTING;
- }
- VI_UNLOCK(vp);
- }
-}
-
-void
-coda_cacheprint(struct mount *whoIam)
-{
- int hash;
- struct cnode *cp;
- int count = 0;
-
- printf("coda_cacheprint: coda_ctlvp %p, cp %p", coda_ctlvp,
- VTOC(coda_ctlvp));
-
-#if 0
- coda_nc_name(VTOC(coda_ctlvp));
-#endif
- printf("\n");
- for (hash = 0; hash < CODA_CACHESIZE; hash++) {
- for (cp = coda_cache[hash]; cp != NULL;
- cp = CNODE_NEXT(cp)) {
- if (CTOV(cp)->v_mount == whoIam) {
- printf("coda_cacheprint: vp %p, cp %p",
- CTOV(cp), cp);
-#if 0
- coda_nc_name(cp);
-#endif
- printf("\n");
- count++;
- }
- }
- }
- printf("coda_cacheprint: count %d\n", count);
-}
-#endif
-
-/*-
- * There are 6 cases where invalidations occur. The semantics of each is
- * listed here:
- *
- * CODA_FLUSH -- Flush all entries from the name cache and the cnode
- * cache.
- *
- * CODA_PURGEUSER -- Flush all entries from the name cache for a specific
- * user. This call is a result of token expiration.
- *
- * The next two are the result of callbacks on a file or directory:
- *
- * CODA_ZAPDIR -- Flush the attributes for the dir from its cnode. Zap
- * all children of this directory from the namecache.
- *
- * CODA_ZAPFILE -- Flush the attributes for a file.
- *
- * The fifth is a result of Venus detecting an inconsistent file:
- *
- * CODA_PURGEFID -- Flush the attribute for the file; if it is a dir (odd
- * vnode), purge its children from the namecache; remove
- * the file from the namecache.
- *
- * The sixth allows Venus to replace local fids with global ones during
- * reintegration.
- *
- * CODA_REPLACE -- Replace one CodaFid with another throughout the name
- * cache.
- */
-int
-handleDownCall(struct coda_mntinfo *mnt, int opcode, union outputArgs *out)
-{
- int error;
-
- /*
- * Handle invalidate requests.
- */
- switch (opcode) {
- case CODA_FLUSH: {
- coda_flush(mnt, IS_DOWNCALL);
-
- /* Print any remaining cnodes. */
- CODADEBUG(CODA_FLUSH, coda_testflush(););
- return (0);
- }
-
- case CODA_PURGEUSER: {
- coda_clstat.ncalls++;
- coda_clstat.reqs[CODA_PURGEUSER]++;
-
- /* XXX - need to prevent fsync's. */
-
- /*
- * Purge any access cache entries for the uid.
- */
-#ifdef CODA_COMPAT_5
- coda_acccache_purgeuser(mnt->mi_vfsp,
- out->coda_purgeuser.cred.cr_uid);
-#else
- coda_acccache_purgeuser(mnt->mi_vfsp,
- out->coda_purgeuser.uid);
-#endif
- return (0);
- }
-
- case CODA_ZAPFILE: {
- struct cnode *cp;
-
- error = 0;
- coda_clstat.ncalls++;
- coda_clstat.reqs[CODA_ZAPFILE]++;
- cp = coda_find(&out->coda_zapfile.Fid);
- if (cp != NULL) {
- vref(CTOV(cp));
- cache_purge(CTOV(cp));
- cp->c_flags &= ~(C_VATTR | C_ACCCACHE);
- ASSERT_VOP_LOCKED(CTOV(cp), "coda HandleDownCall");
- if (VOP_IS_TEXT(CTOV(cp)))
- error = coda_vmflush(cp);
- CODADEBUG(CODA_ZAPFILE,
- myprintf(("zapfile: fid = %s, refcnt = %d, error = "
- "%d\n", coda_f2s(&cp->c_fid),
- CTOV(cp)->v_usecount - 1, error)););
- if (vrefcnt(CTOV(cp)) == 1)
- cp->c_flags |= C_PURGING;
- vrele(CTOV(cp));
- }
- return (error);
- }
-
- case CODA_ZAPDIR: {
- struct cnode *cp;
-
- coda_clstat.ncalls++;
- coda_clstat.reqs[CODA_ZAPDIR]++;
- cp = coda_find(&out->coda_zapdir.Fid);
- if (cp != NULL) {
- vref(CTOV(cp));
- cache_purge(CTOV(cp));
- cp->c_flags &= ~(C_VATTR | C_ACCCACHE);
- CODADEBUG(CODA_ZAPDIR, myprintf(("zapdir: fid = %s, "
- "refcnt = %d\n", coda_f2s(&cp->c_fid),
- CTOV(cp)->v_usecount - 1)););
- if (vrefcnt(CTOV(cp)) == 1)
- cp->c_flags |= C_PURGING;
- vrele(CTOV(cp));
- }
- return (0);
- }
-
- case CODA_PURGEFID: {
- struct cnode *cp;
-
- error = 0;
- coda_clstat.ncalls++;
- coda_clstat.reqs[CODA_PURGEFID]++;
- cp = coda_find(&out->coda_purgefid.Fid);
- if (cp != NULL) {
- vref(CTOV(cp));
- cache_purge(CTOV(cp));
- cp->c_flags &= ~(C_VATTR | C_ACCCACHE);
- ASSERT_VOP_LOCKED(CTOV(cp), "coda HandleDownCall");
- if (!(IS_DIR(out->coda_purgefid.Fid))
- && VOP_IS_TEXT(CTOV(cp)))
- error = coda_vmflush(cp);
- CODADEBUG(CODA_PURGEFID, myprintf(("purgefid: fid "
- "= %s, refcnt = %d, error = %d\n",
- coda_f2s(&cp->c_fid),
- CTOV(cp)->v_usecount - 1, error)););
- if (vrefcnt(CTOV(cp)) == 1)
- cp->c_flags |= C_PURGING;
- vrele(CTOV(cp));
- }
- return (error);
- }
-
- case CODA_REPLACE: {
- struct cnode *cp = NULL;
-
- coda_clstat.ncalls++;
- coda_clstat.reqs[CODA_REPLACE]++;
- cp = coda_find(&out->coda_replace.OldFid);
- if (cp != NULL) {
- /*
- * Remove the cnode from the hash table, replace the
- * fid, and reinsert. Clear the attribute cache as
- * the "inode number" may have changed (it's just a
- * hash of the fid, and the fid is changing).
- */
- vref(CTOV(cp));
- coda_unsave(cp);
- cp->c_fid = out->coda_replace.NewFid;
- cp->c_flags &= ~C_VATTR;
- coda_save(cp);
- CODADEBUG(CODA_REPLACE, myprintf(("replace: oldfid "
- "= %s, newfid = %s, cp = %p\n",
- coda_f2s(&out->coda_replace.OldFid),
- coda_f2s(&cp->c_fid), cp)););
- vrele(CTOV(cp));
- }
- return (0);
- }
- default:
- myprintf(("handleDownCall: unknown opcode %d\n", opcode));
- return (EINVAL);
- }
-}
-
-int
-coda_vmflush(struct cnode *cp)
-{
-
- return (0);
-}
-
-/*
- * Kernel-internal debugging switches.
- */
-void
-coda_debugon(void)
-{
-
- codadebug = -1;
- coda_vnop_print_entry = 1;
- coda_psdev_print_entry = 1;
- coda_vfsop_print_entry = 1;
-}
-
-void
-coda_debugoff(void)
-{
-
- codadebug = 0;
- coda_vnop_print_entry = 0;
- coda_psdev_print_entry = 0;
- coda_vfsop_print_entry = 0;
-}
-
-/*-
- * Utilities used by both client and server
- * Standard levels:
- * 0) no debugging
- * 1) hard failures
- * 2) soft failures
- * 3) current test software
- * 4) main procedure entry points
- * 5) main procedure exit points
- * 6) utility procedure entry points
- * 7) utility procedure exit points
- * 8) obscure procedure entry points
- * 9) obscure procedure exit points
- * 10) random stuff
- * 11) all <= 1
- * 12) all <= 2
- * 13) all <= 3
- * ...
- */
diff --git a/sys/fs/coda/coda_subr.h b/sys/fs/coda/coda_subr.h
deleted file mode 100644
index b8edfd3..0000000
--- a/sys/fs/coda/coda_subr.h
+++ /dev/null
@@ -1,49 +0,0 @@
-/*-
- *
- * Coda: an Experimental Distributed File System
- * Release 3.1
- *
- * Copyright (c) 1987-1998 Carnegie Mellon University
- * All Rights Reserved
- *
- * Permission to use, copy, modify and distribute this software and its
- * documentation is hereby granted, provided that both the copyright
- * notice and this permission notice appear in all copies of the
- * software, derivative works or modified versions, and any portions
- * thereof, and that both notices appear in supporting documentation, and
- * that credit is given to Carnegie Mellon University in all documents
- * and publicity pertaining to direct or indirect use of this code or its
- * derivatives.
- *
- * CODA IS AN EXPERIMENTAL SOFTWARE SYSTEM AND IS KNOWN TO HAVE BUGS,
- * SOME OF WHICH MAY HAVE SERIOUS CONSEQUENCES. CARNEGIE MELLON ALLOWS
- * FREE USE OF THIS SOFTWARE IN ITS "AS IS" CONDITION. CARNEGIE MELLON
- * DISCLAIMS ANY LIABILITY OF ANY KIND FOR ANY DAMAGES WHATSOEVER
- * RESULTING DIRECTLY OR INDIRECTLY FROM THE USE OF THIS SOFTWARE OR OF
- * ANY DERIVATIVE WORK.
- *
- * Carnegie Mellon encourages users of this software to return any
- * improvements or extensions that they make, and to grant Carnegie
- * Mellon the rights to redistribute these changes without encumbrance.
- *
- * @(#) src/sys/coda/coda_subr.h,v 1.1.1.1 1998/08/29 21:14:52 rvb Exp $
- * $FreeBSD$
- */
-
-#ifndef _CODA_SUBR_H_
-#define _CODA_SUBR_H_
-
-struct cnode *coda_alloc(void);
-void coda_free(struct cnode *cp);
-struct cnode *coda_find(struct CodaFid *fid);
-void coda_flush(struct coda_mntinfo *mnt, enum dc_status dcstat);
-void coda_testflush(void);
-void coda_checkunmounting(struct mount *mp);
-void coda_cacheprint(struct mount *whoIam);
-void coda_debugon(void);
-void coda_debugoff(void);
-int coda_kill(struct mount *whoIam, enum dc_status dcstat);
-void coda_save(struct cnode *cp);
-void coda_unsave(struct cnode *cp);
-
-#endif /* !_CODA_SUBR_H_ */
diff --git a/sys/fs/coda/coda_venus.c b/sys/fs/coda/coda_venus.c
deleted file mode 100644
index 9d012dd..0000000
--- a/sys/fs/coda/coda_venus.c
+++ /dev/null
@@ -1,705 +0,0 @@
-/*-
- * Coda: an Experimental Distributed File System
- * Release 3.1
- *
- * Copyright (c) 1987-1998 Carnegie Mellon University
- * All Rights Reserved
- *
- * Permission to use, copy, modify and distribute this software and its
- * documentation is hereby granted, provided that both the copyright
- * notice and this permission notice appear in all copies of the
- * software, derivative works or modified versions, and any portions
- * thereof, and that both notices appear in supporting documentation, and
- * that credit is given to Carnegie Mellon University in all documents
- * and publicity pertaining to direct or indirect use of this code or its
- * derivatives.
- *
- * CODA IS AN EXPERIMENTAL SOFTWARE SYSTEM AND IS KNOWN TO HAVE BUGS,
- * SOME OF WHICH MAY HAVE SERIOUS CONSEQUENCES. CARNEGIE MELLON ALLOWS
- * FREE USE OF THIS SOFTWARE IN ITS "AS IS" CONDITION. CARNEGIE MELLON
- * DISCLAIMS ANY LIABILITY OF ANY KIND FOR ANY DAMAGES WHATSOEVER
- * RESULTING DIRECTLY OR INDIRECTLY FROM THE USE OF THIS SOFTWARE OR OF
- * ANY DERIVATIVE WORK.
- *
- * Carnegie Mellon encourages users of this software to return any
- * improvements or extensions that they make, and to grant Carnegie
- * Mellon the rights to redistribute these changes without encumbrance.
- *
- * @(#) src/sys/cfs/coda_venus.c,v 1.1.1.1 1998/08/29 21:14:52 rvb Exp $
- */
-
-#include <sys/cdefs.h>
-__FBSDID("$FreeBSD$");
-
-#include <sys/param.h>
-#include <sys/systm.h>
-#include <sys/fcntl.h>
-#include <sys/ioccom.h>
-#include <sys/lock.h>
-#include <sys/malloc.h>
-#include <sys/mutex.h>
-#include <sys/proc.h>
-#include <sys/sx.h>
-
-#include <fs/coda/coda.h>
-#include <fs/coda/cnode.h>
-#include <fs/coda/coda_venus.h>
-#include <fs/coda/coda_pioctl.h>
-
-#define DECL_NO_IN(name) \
- struct coda_in_hdr *inp; \
- struct name ## _out *outp; \
- int name ## _size = sizeof (struct coda_in_hdr); \
- int Isize = sizeof (struct coda_in_hdr); \
- int Osize = sizeof (struct name ## _out); \
- int error
-
-#define DECL(name) \
- struct name ## _in *inp; \
- struct name ## _out *outp; \
- int name ## _size = sizeof (struct name ## _in); \
- int Isize = sizeof (struct name ## _in); \
- int Osize = sizeof (struct name ## _out); \
- int error
-
-#define DECL_NO_OUT(name) \
- struct name ## _in *inp; \
- struct coda_out_hdr *outp; \
- int name ## _size = sizeof (struct name ## _in); \
- int Isize = sizeof (struct name ## _in); \
- int Osize = sizeof (struct coda_out_hdr); \
- int error
-
-#define ALLOC_NO_IN(name) \
- if (Osize > name ## _size) \
- name ## _size = Osize; \
- CODA_ALLOC(inp, struct coda_in_hdr *, name ## _size); \
- outp = (struct name ## _out *) inp
-
-#define ALLOC(name) \
- if (Osize > name ## _size) \
- name ## _size = Osize; \
- CODA_ALLOC(inp, struct name ## _in *, name ## _size); \
- outp = (struct name ## _out *) inp
-
-#define ALLOC_NO_OUT(name) \
- if (Osize > name ## _size) \
- name ## _size = Osize; \
- CODA_ALLOC(inp, struct name ## _in *, name ## _size); \
- outp = (struct coda_out_hdr *) inp
-
-#define STRCPY(struc, name, len) \
- bcopy(name, (char *)inp + (int)inp->struc, len); \
- ((char*)inp + (int)inp->struc)[len++] = 0; \
- Isize += len
-
-#ifdef CODA_COMPAT_5
-#define INIT_IN(in, op, ident, p) do { \
- (in)->opcode = (op); \
- sx_slock(&proctree_lock); \
- (in)->pid = p ? p->p_pid : -1; \
- (in)->pgid = p ? p->p_pgid : -1; \
- (in)->sid = (p && p->p_session && p->p_session->s_leader) ? \
- (p->p_session->s_leader->p_pid) : -1; \
- sx_sunlock(&proctree_lock); \
- if (ident != NOCRED) { \
- (in)->cred.cr_uid = ident->cr_uid; \
- (in)->cred.cr_groupid = ident->cr_gid; \
- } else { \
- bzero(&((in)->cred),sizeof(struct coda_cred)); \
- (in)->cred.cr_uid = -1; \
- (in)->cred.cr_groupid = -1; \
- } \
-} while (0)
-#else
-#define INIT_IN(in, op, ident, p) do { \
- (in)->opcode = (op); \
- (in)->pid = p ? p->p_pid : -1; \
- (in)->pgid = p ? p->p_pgid : -1; \
- if (ident != NOCRED) \
- (in)->uid = ident->cr_uid; \
- else \
- (in)->uid = -1; \
-} while (0)
-#endif
-
-#define CNV_OFLAG(to, from) do { \
- to = 0; \
- if (from & FREAD) to |= C_O_READ; \
- if (from & FWRITE) to |= C_O_WRITE; \
- if (from & O_TRUNC) to |= C_O_TRUNC; \
- if (from & O_EXCL) to |= C_O_EXCL; \
- if (from & O_CREAT) to |= C_O_CREAT; \
-} while (0)
-
-#define CNV_VV2V_ATTR(top, fromp) do { \
- (top)->va_type = (fromp)->va_type; \
- (top)->va_mode = (fromp)->va_mode; \
- (top)->va_nlink = (fromp)->va_nlink; \
- (top)->va_uid = (fromp)->va_uid; \
- (top)->va_gid = (fromp)->va_gid; \
- (top)->va_fsid = VNOVAL; \
- (top)->va_fileid = (fromp)->va_fileid; \
- (top)->va_size = (fromp)->va_size; \
- (top)->va_blocksize = (fromp)->va_blocksize; \
- (top)->va_atime = (fromp)->va_atime; \
- (top)->va_mtime = (fromp)->va_mtime; \
- (top)->va_ctime = (fromp)->va_ctime; \
- (top)->va_gen = (fromp)->va_gen; \
- (top)->va_flags = (fromp)->va_flags; \
- (top)->va_rdev = (fromp)->va_rdev; \
- (top)->va_bytes = (fromp)->va_bytes; \
- (top)->va_filerev = (fromp)->va_filerev; \
- (top)->va_vaflags = VNOVAL; \
- (top)->va_spare = VNOVAL; \
-} while (0)
-
-#define CNV_V2VV_ATTR(top, fromp) do { \
- (top)->va_type = (fromp)->va_type; \
- (top)->va_mode = (fromp)->va_mode; \
- (top)->va_nlink = (fromp)->va_nlink; \
- (top)->va_uid = (fromp)->va_uid; \
- (top)->va_gid = (fromp)->va_gid; \
- (top)->va_fileid = (fromp)->va_fileid; \
- (top)->va_size = (fromp)->va_size; \
- (top)->va_blocksize = (fromp)->va_blocksize; \
- (top)->va_atime = (fromp)->va_atime; \
- (top)->va_mtime = (fromp)->va_mtime; \
- (top)->va_ctime = (fromp)->va_ctime; \
- (top)->va_gen = (fromp)->va_gen; \
- (top)->va_flags = (fromp)->va_flags; \
- (top)->va_rdev = (fromp)->va_rdev; \
- (top)->va_bytes = (fromp)->va_bytes; \
- (top)->va_filerev = (fromp)->va_filerev; \
-} while (0)
-
-int coda_kernel_version = CODA_KERNEL_VERSION;
-
-int
-venus_root(void *mdp, struct ucred *cred, struct proc *p,
- /*out*/ struct CodaFid *VFid)
-{
- DECL_NO_IN(coda_root); /* sets Isize & Osize */
- ALLOC_NO_IN(coda_root); /* sets inp & outp */
-
- /* send the open to venus. */
- INIT_IN(inp, CODA_ROOT, cred, p);
-
- error = coda_call(mdp, Isize, &Osize, (char *)inp);
- if (!error)
- *VFid = outp->Fid;
-
- CODA_FREE(inp, coda_root_size);
- return (error);
-}
-
-int
-venus_open(void *mdp, struct CodaFid *fid, int flag, struct ucred *cred,
- struct proc *p, /*out*/ struct vnode **vp)
-{
- int cflag;
- DECL(coda_open_by_fd); /* sets Isize & Osize */
- ALLOC(coda_open_by_fd); /* sets inp & outp */
-
- /* send the open to venus. */
- INIT_IN(&inp->ih, CODA_OPEN_BY_FD, cred, p);
- inp->Fid = *fid;
- CNV_OFLAG(cflag, flag);
- inp->flags = cflag;
-
- error = coda_call(mdp, Isize, &Osize, (char *)inp);
- *vp = error ? NULL : outp->vp;
-
- CODA_FREE(inp, coda_open_by_fd_size);
- return (error);
-}
-
-int
-venus_close(void *mdp, struct CodaFid *fid, int flag, struct ucred *cred,
- struct proc *p)
-{
- int cflag;
- DECL_NO_OUT(coda_close); /* sets Isize & Osize */
- ALLOC_NO_OUT(coda_close); /* sets inp & outp */
-
- INIT_IN(&inp->ih, CODA_CLOSE, cred, p);
- inp->Fid = *fid;
- CNV_OFLAG(cflag, flag);
- inp->flags = cflag;
-
- error = coda_call(mdp, Isize, &Osize, (char *)inp);
-
- CODA_FREE(inp, coda_close_size);
- return (error);
-}
-
-/*
- * These two calls will not exist!!! The container file is read/written
- * directly.
- */
-void
-venus_read(void)
-{
-}
-
-void
-venus_write(void)
-{
-}
-
-/*
- * This is a bit sad too. the ioctl's are for the control file, not for
- * normal files.
- */
-int
-venus_ioctl(void *mdp, struct CodaFid *fid, int com, int flag, caddr_t data,
- struct ucred *cred, struct proc *p)
-{
- DECL(coda_ioctl); /* sets Isize & Osize */
- struct PioctlData *iap = (struct PioctlData *)data;
- int tmp;
-
- coda_ioctl_size = VC_MAXMSGSIZE;
- ALLOC(coda_ioctl); /* sets inp & outp */
-
- INIT_IN(&inp->ih, CODA_IOCTL, cred, p);
- inp->Fid = *fid;
-
- /*
- * Command was mutated by increasing its size field to reflect the
- * path and follow args. we need to subtract that out before sending
- * the command to venus.
- */
- inp->cmd = (com & ~(IOCPARM_MASK << 16));
- tmp = ((com >> 16) & IOCPARM_MASK) - sizeof (char *) - sizeof (int);
- inp->cmd |= (tmp & IOCPARM_MASK) << 16;
-
- if (iap->vi.in_size > VC_MAXMSGSIZE ||
- iap->vi.out_size > VC_MAXMSGSIZE) {
- CODA_FREE(inp, coda_ioctl_size);
- return (EINVAL);
- }
-
- inp->rwflag = flag;
- inp->len = iap->vi.in_size;
- inp->data = (char *)(sizeof (struct coda_ioctl_in));
-
- error = copyin(iap->vi.in, (char*)inp + (long)inp->data,
- iap->vi.in_size);
- if (error) {
- CODA_FREE(inp, coda_ioctl_size);
- return (error);
- }
-
- Osize = VC_MAXMSGSIZE;
- error = coda_call(mdp, Isize + iap->vi.in_size, &Osize, (char *)inp);
-
- /*
- * Copy out the out buffer.
- */
- if (!error) {
- if (outp->len > iap->vi.out_size)
- error = EINVAL;
- else
- error = copyout((char *)outp + (long)outp->data,
- iap->vi.out, iap->vi.out_size);
- }
-
- CODA_FREE(inp, coda_ioctl_size);
- return (error);
-}
-
-int
-venus_getattr(void *mdp, struct CodaFid *fid, struct ucred *cred,
- struct vattr *vap)
-{
- struct proc *p;
- DECL(coda_getattr); /* sets Isize & Osize */
- ALLOC(coda_getattr); /* sets inp & outp */
-
- /*
- * Send the open to venus.
- */
- p = curthread->td_proc;
- INIT_IN(&inp->ih, CODA_GETATTR, cred, p);
- inp->Fid = *fid;
-
- error = coda_call(mdp, Isize, &Osize, (char *)inp);
- if (!error)
- CNV_VV2V_ATTR(vap, &outp->attr);
-
- CODA_FREE(inp, coda_getattr_size);
- return (error);
-}
-
-int
-venus_setattr(void *mdp, struct CodaFid *fid, struct vattr *vap,
- struct ucred *cred)
-{
- struct proc *p;
- DECL_NO_OUT(coda_setattr); /* sets Isize & Osize */
- ALLOC_NO_OUT(coda_setattr); /* sets inp & outp */
-
- /*
- * Send the open to venus.
- */
- p = curthread->td_proc;
- INIT_IN(&inp->ih, CODA_SETATTR, cred, p);
- inp->Fid = *fid;
- CNV_V2VV_ATTR(&inp->attr, vap);
-
- error = coda_call(mdp, Isize, &Osize, (char *)inp);
-
- CODA_FREE(inp, coda_setattr_size);
- return (error);
-}
-
-int
-venus_access(void *mdp, struct CodaFid *fid, accmode_t accmode,
- struct ucred *cred, struct proc *p)
-{
- DECL_NO_OUT(coda_access); /* sets Isize & Osize */
- ALLOC_NO_OUT(coda_access); /* sets inp & outp */
-
- /*
- * Send the open to venus.
- */
- INIT_IN(&inp->ih, CODA_ACCESS, cred, p);
- inp->Fid = *fid;
-
- /*
- * NOTE: FreeBSD and Venus internals use the "data" in the low 3
- * bits. Hence, the conversion.
- *
- * XXX: We cast accmode_t variable into an int.
- */
- inp->flags = (int)accmode>>6;
-
- error = coda_call(mdp, Isize, &Osize, (char *)inp);
-
- CODA_FREE(inp, coda_access_size);
- return (error);
-}
-
-int
-venus_readlink(void *mdp, struct CodaFid *fid, struct ucred *cred,
- struct proc *p, /*out*/ char **str, int *len)
-{
- DECL(coda_readlink); /* sets Isize & Osize */
- coda_readlink_size += CODA_MAXPATHLEN;
- ALLOC(coda_readlink); /* sets inp & outp */
-
- /*
- * Send the open to venus.
- */
- INIT_IN(&inp->ih, CODA_READLINK, cred, p);
- inp->Fid = *fid;
-
- Osize += CODA_MAXPATHLEN;
- error = coda_call(mdp, Isize, &Osize, (char *)inp);
- if (!error) {
- CODA_ALLOC(*str, char *, outp->count);
- *len = outp->count;
- bcopy((char *)outp + (long)outp->data, *str, *len);
- }
-
- CODA_FREE(inp, coda_readlink_size);
- return (error);
-}
-
-int
-venus_fsync(void *mdp, struct CodaFid *fid, struct proc *p)
-{
- DECL_NO_OUT(coda_fsync); /* sets Isize & Osize */
- ALLOC_NO_OUT(coda_fsync); /* sets inp & outp */
-
- /*
- * Send the open to venus.
- *
- * XXX: should be cached mount cred.
- */
- INIT_IN(&inp->ih, CODA_FSYNC, NOCRED, p);
- inp->Fid = *fid;
-
- error = coda_call(mdp, Isize, &Osize, (char *)inp);
-
- CODA_FREE(inp, coda_fsync_size);
- return (error);
-}
-
-int
-venus_lookup(void *mdp, struct CodaFid *fid, const char *nm, int len,
- struct ucred *cred, struct proc *p, /*out*/ struct CodaFid *VFid,
- int *vtype)
-{
- DECL(coda_lookup); /* sets Isize & Osize */
- coda_lookup_size += len + 1;
- ALLOC(coda_lookup); /* sets inp & outp */
-
- /*
- * Send the open to venus.
- */
- INIT_IN(&inp->ih, CODA_LOOKUP, cred, p);
- inp->Fid = *fid;
-
- /*
- * NOTE: Between version 1 and version 2 we have added an extra flag
- * field to this structure. But because the string was at the end
- * and because of the wierd way we represent strings by having the
- * slot point to where the string characters are in the "heap", we
- * can just slip the flag parameter in after the string slot pointer
- * and veni that don't know better won't see this new flag field ...
- * Otherwise we'd need two different venus_lookup functions.
- */
- inp->name = Isize;
- inp->flags = CLU_CASE_SENSITIVE; /* doesn't really matter for BSD */
- STRCPY(name, nm, len); /* increments Isize */
-
- error = coda_call(mdp, Isize, &Osize, (char *)inp);
- if (!error) {
- *VFid = outp->Fid;
- *vtype = outp->vtype;
- }
-
- CODA_FREE(inp, coda_lookup_size);
- return (error);
-}
-
-int
-venus_create(void *mdp, struct CodaFid *fid, const char *nm, int len,
- int exclusive, int mode, struct vattr *va, struct ucred *cred,
- struct proc *p, /*out*/ struct CodaFid *VFid, struct vattr *attr)
-{
- DECL(coda_create); /* sets Isize & Osize */
- coda_create_size += len + 1;
- ALLOC(coda_create); /* sets inp & outp */
-
- /*
- * Send the open to venus.
- */
- INIT_IN(&inp->ih, CODA_CREATE, cred, p);
- inp->Fid = *fid;
- inp->excl = exclusive ? C_O_EXCL : 0;
- inp->mode = mode;
- CNV_V2VV_ATTR(&inp->attr, va);
-
- inp->name = Isize;
- STRCPY(name, nm, len); /* increments Isize */
-
- error = coda_call(mdp, Isize, &Osize, (char *)inp);
- if (!error) {
- *VFid = outp->Fid;
- CNV_VV2V_ATTR(attr, &outp->attr);
- }
-
- CODA_FREE(inp, coda_create_size);
- return (error);
-}
-
-int
-venus_remove(void *mdp, struct CodaFid *fid, const char *nm, int len,
- struct ucred *cred, struct proc *p)
-{
- DECL_NO_OUT(coda_remove); /* sets Isize & Osize */
- coda_remove_size += len + 1;
- ALLOC_NO_OUT(coda_remove); /* sets inp & outp */
-
- /*
- * Send the open to venus.
- */
- INIT_IN(&inp->ih, CODA_REMOVE, cred, p);
- inp->Fid = *fid;
-
- inp->name = Isize;
- STRCPY(name, nm, len); /* increments Isize */
-
- error = coda_call(mdp, Isize, &Osize, (char *)inp);
-
- CODA_FREE(inp, coda_remove_size);
- return (error);
-}
-
-int
-venus_link(void *mdp, struct CodaFid *fid, struct CodaFid *tfid,
- const char *nm, int len, struct ucred *cred, struct proc *p)
-{
- DECL_NO_OUT(coda_link); /* sets Isize & Osize */
- coda_link_size += len + 1;
- ALLOC_NO_OUT(coda_link); /* sets inp & outp */
-
- /*
- * Send the open to venus.
- */
- INIT_IN(&inp->ih, CODA_LINK, cred, p);
- inp->sourceFid = *fid;
- inp->destFid = *tfid;
-
- inp->tname = Isize;
- STRCPY(tname, nm, len); /* increments Isize */
-
- error = coda_call(mdp, Isize, &Osize, (char *)inp);
-
- CODA_FREE(inp, coda_link_size);
- return (error);
-}
-
-int
-venus_rename(void *mdp, struct CodaFid *fid, struct CodaFid *tfid,
- const char *nm, int len, const char *tnm, int tlen, struct ucred *cred,
- struct proc *p)
-{
- DECL_NO_OUT(coda_rename); /* sets Isize & Osize */
- coda_rename_size += len + 1 + tlen + 1;
- ALLOC_NO_OUT(coda_rename); /* sets inp & outp */
-
- /*
- * Send the open to venus.
- */
- INIT_IN(&inp->ih, CODA_RENAME, cred, p);
- inp->sourceFid = *fid;
- inp->destFid = *tfid;
-
- inp->srcname = Isize;
- STRCPY(srcname, nm, len); /* increments Isize */
-
- inp->destname = Isize;
- STRCPY(destname, tnm, tlen); /* increments Isize */
-
- error = coda_call(mdp, Isize, &Osize, (char *)inp);
-
- CODA_FREE(inp, coda_rename_size);
- return (error);
-}
-
-int
-venus_mkdir(void *mdp, struct CodaFid *fid, const char *nm, int len,
- struct vattr *va, struct ucred *cred, struct proc *p,
- /*out*/ struct CodaFid *VFid, struct vattr *ova)
-{
- DECL(coda_mkdir); /* sets Isize & Osize */
- coda_mkdir_size += len + 1;
- ALLOC(coda_mkdir); /* sets inp & outp */
-
- /*
- * Send the open to venus.
- */
- INIT_IN(&inp->ih, CODA_MKDIR, cred, p);
- inp->Fid = *fid;
- CNV_V2VV_ATTR(&inp->attr, va);
-
- inp->name = Isize;
- STRCPY(name, nm, len); /* increments Isize */
-
- error = coda_call(mdp, Isize, &Osize, (char *)inp);
- if (!error) {
- *VFid = outp->Fid;
- CNV_VV2V_ATTR(ova, &outp->attr);
- }
-
- CODA_FREE(inp, coda_mkdir_size);
- return (error);
-}
-
-int
-venus_rmdir(void *mdp, struct CodaFid *fid, const char *nm, int len,
- struct ucred *cred, struct proc *p)
-{
- DECL_NO_OUT(coda_rmdir); /* sets Isize & Osize */
- coda_rmdir_size += len + 1;
- ALLOC_NO_OUT(coda_rmdir); /* sets inp & outp */
-
- /*
- * Send the open to venus.
- */
- INIT_IN(&inp->ih, CODA_RMDIR, cred, p);
- inp->Fid = *fid;
-
- inp->name = Isize;
- STRCPY(name, nm, len); /* increments Isize */
-
- error = coda_call(mdp, Isize, &Osize, (char *)inp);
-
- CODA_FREE(inp, coda_rmdir_size);
- return (error);
-}
-
-int
-venus_symlink(void *mdp, struct CodaFid *fid, const char *lnm, int llen,
- const char *nm, int len, struct vattr *va, struct ucred *cred,
- struct proc *p)
-{
- DECL_NO_OUT(coda_symlink); /* sets Isize & Osize */
- coda_symlink_size += llen + 1 + len + 1;
- ALLOC_NO_OUT(coda_symlink); /* sets inp & outp */
-
- /*
- * Send the open to venus.
- */
- INIT_IN(&inp->ih, CODA_SYMLINK, cred, p);
- inp->Fid = *fid;
- CNV_V2VV_ATTR(&inp->attr, va);
-
- inp->srcname = Isize;
- STRCPY(srcname, lnm, llen); /* increments Isize */
-
- inp->tname = Isize;
- STRCPY(tname, nm, len); /* increments Isize */
-
- error = coda_call(mdp, Isize, &Osize, (char *)inp);
-
- CODA_FREE(inp, coda_symlink_size);
- return (error);
-}
-
-/*
- * XXX: Unused.
- */
-int
-venus_readdir(void *mdp, struct CodaFid *fid, int count, int offset,
- struct ucred *cred, struct proc *p, /*out*/ char *buffer, int *len)
-{
- DECL(coda_readdir); /* sets Isize & Osize */
- coda_readdir_size = VC_MAXMSGSIZE;
- ALLOC(coda_readdir); /* sets inp & outp */
-
- /*
- * Send the open to venus.
- */
- INIT_IN(&inp->ih, CODA_READDIR, cred, p);
- inp->Fid = *fid;
- inp->count = count;
- inp->offset = offset;
-
- Osize = VC_MAXMSGSIZE;
- error = coda_call(mdp, Isize, &Osize, (char *)inp);
- if (!error) {
- bcopy((char *)outp + (long)outp->data, buffer, outp->size);
- *len = outp->size;
- }
-
- CODA_FREE(inp, coda_readdir_size);
- return (error);
-}
-
-int
-venus_fhtovp(void *mdp, struct CodaFid *fid, struct ucred *cred,
- struct proc *p, /*out*/ struct CodaFid *VFid, int *vtype)
-{
- DECL(coda_vget); /* sets Isize & Osize */
- ALLOC(coda_vget); /* sets inp & outp */
-
- /*
- * Send the open to Venus.
- */
- INIT_IN(&inp->ih, CODA_VGET, cred, p);
- inp->Fid = *fid;
-
- error = coda_call(mdp, Isize, &Osize, (char *)inp);
- if (!error) {
- *VFid = outp->Fid;
- *vtype = outp->vtype;
- }
-
- CODA_FREE(inp, coda_vget_size);
- return (error);
-}
diff --git a/sys/fs/coda/coda_venus.h b/sys/fs/coda/coda_venus.h
deleted file mode 100644
index 95f1c57..0000000
--- a/sys/fs/coda/coda_venus.h
+++ /dev/null
@@ -1,83 +0,0 @@
-/*-
- *
- * Coda: an Experimental Distributed File System
- * Release 3.1
- *
- * Copyright (c) 1987-1998 Carnegie Mellon University
- * All Rights Reserved
- *
- * Permission to use, copy, modify and distribute this software and its
- * documentation is hereby granted, provided that both the copyright
- * notice and this permission notice appear in all copies of the
- * software, derivative works or modified versions, and any portions
- * thereof, and that both notices appear in supporting documentation, and
- * that credit is given to Carnegie Mellon University in all documents
- * and publicity pertaining to direct or indirect use of this code or its
- * derivatives.
- *
- * CODA IS AN EXPERIMENTAL SOFTWARE SYSTEM AND IS KNOWN TO HAVE BUGS,
- * SOME OF WHICH MAY HAVE SERIOUS CONSEQUENCES. CARNEGIE MELLON ALLOWS
- * FREE USE OF THIS SOFTWARE IN ITS "AS IS" CONDITION. CARNEGIE MELLON
- * DISCLAIMS ANY LIABILITY OF ANY KIND FOR ANY DAMAGES WHATSOEVER
- * RESULTING DIRECTLY OR INDIRECTLY FROM THE USE OF THIS SOFTWARE OR OF
- * ANY DERIVATIVE WORK.
- *
- * Carnegie Mellon encourages users of this software to return any
- * improvements or extensions that they make, and to grant Carnegie
- * Mellon the rights to redistribute these changes without encumbrance.
- *
- * @(#) src/sys/coda/coda_venus.h,v 1.1.1.1 1998/08/29 21:14:52 rvb Exp $
- * $FreeBSD$
- */
-
-#ifndef _CODA_VENUS_H_
-#define _CODA_VENUS_H_
-
-int venus_root(void *mdp, struct ucred *cred, struct proc *p,
- /*out*/ struct CodaFid *VFid);
-int venus_open(void *mdp, struct CodaFid *fid, int flag,
- struct ucred *cred, struct proc *p, /*out*/ struct vnode **vp);
-int venus_close(void *mdp, struct CodaFid *fid, int flag,
- struct ucred *cred, struct proc *p);
-void venus_read(void);
-void venus_write(void);
-int venus_ioctl(void *mdp, struct CodaFid *fid, int com, int flag,
- caddr_t data, struct ucred *cred, struct proc *p);
-int venus_getattr(void *mdp, struct CodaFid *fid, struct ucred *cred,
- struct vattr *vap);
-int venus_setattr(void *mdp, struct CodaFid *fid, struct vattr *vap,
- struct ucred *cred);
-int venus_access(void *mdp, struct CodaFid *fid, int mode,
- struct ucred *cred, struct proc *p);
-int venus_readlink(void *mdp, struct CodaFid *fid, struct ucred *cred,
- struct proc *p, /*out*/ char **str, int *len);
-int venus_fsync(void *mdp, struct CodaFid *fid, struct proc *p);
-int venus_lookup(void *mdp, struct CodaFid *fid, const char *nm, int len,
- struct ucred *cred, struct proc *p, /*out*/ struct CodaFid *VFid,
- int *vtype);
-int venus_create(void *mdp, struct CodaFid *fid, const char *nm, int len,
- int exclusive, int mode, struct vattr *va, struct ucred *cred,
- struct proc *p, /*out*/ struct CodaFid *VFid,
- struct vattr *attr);
-int venus_remove(void *mdp, struct CodaFid *fid, const char *nm, int len,
- struct ucred *cred, struct proc *p);
-int venus_link(void *mdp, struct CodaFid *fid, struct CodaFid *tfid,
- const char *nm, int len, struct ucred *cred, struct proc *p);
-int venus_rename(void *mdp, struct CodaFid *fid, struct CodaFid *tfid,
- const char *nm, int len, const char *tnm, int tlen,
- struct ucred *cred, struct proc *p);
-int venus_mkdir(void *mdp, struct CodaFid *fid, const char *nm, int len,
- struct vattr *va, struct ucred *cred, struct proc *p,
- /*out*/ struct CodaFid *VFid, struct vattr *ova);
-int venus_rmdir(void *mdp, struct CodaFid *fid, const char *nm, int len,
- struct ucred *cred, struct proc *p);
-int venus_symlink(void *mdp, struct CodaFid *fid, const char *lnm,
- int llen, const char *nm, int len, struct vattr *va,
- struct ucred *cred, struct proc *p);
-int venus_readdir(void *mdp, struct CodaFid *fid, int count, int offset,
- struct ucred *cred, struct proc *p, /*out*/ char *buffer,
- int *len);
-int venus_fhtovp(void *mdp, struct CodaFid *fid, struct ucred *cred,
- struct proc *p, /*out*/ struct CodaFid *VFid, int *vtype);
-
-#endif /* !_CODA_VENUS_H_ */
diff --git a/sys/fs/coda/coda_vfsops.c b/sys/fs/coda/coda_vfsops.c
deleted file mode 100644
index 90660c6..0000000
--- a/sys/fs/coda/coda_vfsops.c
+++ /dev/null
@@ -1,446 +0,0 @@
-/*-
- * Coda: an Experimental Distributed File System
- * Release 3.1
- *
- * Copyright (c) 1987-1998 Carnegie Mellon University
- * All Rights Reserved
- *
- * Permission to use, copy, modify and distribute this software and its
- * documentation is hereby granted, provided that both the copyright
- * notice and this permission notice appear in all copies of the
- * software, derivative works or modified versions, and any portions
- * thereof, and that both notices appear in supporting documentation, and
- * that credit is given to Carnegie Mellon University in all documents
- * and publicity pertaining to direct or indirect use of this code or its
- * derivatives.
- *
- * CODA IS AN EXPERIMENTAL SOFTWARE SYSTEM AND IS KNOWN TO HAVE BUGS,
- * SOME OF WHICH MAY HAVE SERIOUS CONSEQUENCES. CARNEGIE MELLON ALLOWS
- * FREE USE OF THIS SOFTWARE IN ITS "AS IS" CONDITION. CARNEGIE MELLON
- * DISCLAIMS ANY LIABILITY OF ANY KIND FOR ANY DAMAGES WHATSOEVER
- * RESULTING DIRECTLY OR INDIRECTLY FROM THE USE OF THIS SOFTWARE OR OF
- * ANY DERIVATIVE WORK.
- *
- * Carnegie Mellon encourages users of this software to return any
- * improvements or extensions that they make, and to grant Carnegie
- * Mellon the rights to redistribute these changes without encumbrance.
- *
- * @(#) src/sys/cfs/coda_vfsops.c,v 1.1.1.1 1998/08/29 21:14:52 rvb Exp $
- */
-
-/*-
- * Mach Operating System
- * Copyright (c) 1989 Carnegie-Mellon University
- * All rights reserved. The CMU software License Agreement specifies
- * the terms and conditions for use and redistribution.
- */
-
-/*
- * This code was written for the Coda filesystem at Carnegie Mellon
- * University. Contributers include David Steere, James Kistler, and
- * M. Satyanarayanan.
- */
-
-#include <sys/cdefs.h>
-__FBSDID("$FreeBSD$");
-
-#include <sys/param.h>
-#include <sys/systm.h>
-#include <sys/conf.h>
-#include <sys/fcntl.h>
-#include <sys/kernel.h>
-#include <sys/lock.h>
-#include <sys/malloc.h>
-#include <sys/mount.h>
-#include <sys/namei.h>
-#include <sys/proc.h>
-
-#include <fs/coda/coda.h>
-#include <fs/coda/cnode.h>
-#include <fs/coda/coda_vfsops.h>
-#include <fs/coda/coda_venus.h>
-#include <fs/coda/coda_subr.h>
-#include <fs/coda/coda_opstats.h>
-
-MALLOC_DEFINE(M_CODA, "coda", "Various Coda Structures");
-
-int codadebug = 0;
-int coda_vfsop_print_entry = 0;
-#define ENTRY do { \
- if (coda_vfsop_print_entry) \
- myprintf(("Entered %s\n", __func__)); \
-} while (0)
-
-struct vnode *coda_ctlvp;
-
-/*
- * Structure to keep statistics of internally generated/satisfied calls.
- */
-static struct coda_op_stats coda_vfsopstats[CODA_VFSOPS_SIZE];
-
-#define MARK_ENTRY(op) (coda_vfsopstats[op].entries++)
-#define MARK_INT_SAT(op) (coda_vfsopstats[op].sat_intrn++)
-#define MARK_INT_FAIL(op) (coda_vfsopstats[op].unsat_intrn++)
-#define MARK_INT_GEN(op) (coda_vfsopstats[op].gen_intrn++)
-
-int
-coda_vfsopstats_init(void)
-{
- int i;
-
- for (i=0; i<CODA_VFSOPS_SIZE;i++) {
- coda_vfsopstats[i].opcode = i;
- coda_vfsopstats[i].entries = 0;
- coda_vfsopstats[i].sat_intrn = 0;
- coda_vfsopstats[i].unsat_intrn = 0;
- coda_vfsopstats[i].gen_intrn = 0;
- }
- return (0);
-}
-
-static const char *coda_opts[] = { "from", NULL };
-/*
- * cfs mount vfsop
- *
- * Set up mount info record and attach it to vfs struct.
- */
-/*ARGSUSED*/
-int
-coda_mount(struct mount *vfsp)
-{
- struct vnode *dvp;
- struct cnode *cp;
- struct cdev *dev;
- struct coda_mntinfo *mi;
- struct vnode *rootvp;
- struct CodaFid rootfid = INVAL_FID;
- struct CodaFid ctlfid = CTL_FID;
- int error;
- struct nameidata ndp;
- ENTRY;
- char *from;
-
- if (vfs_filteropt(vfsp->mnt_optnew, coda_opts))
- return (EINVAL);
- from = vfs_getopts(vfsp->mnt_optnew, "from", &error);
- if (error)
- return (error);
- coda_vfsopstats_init();
- coda_vnodeopstats_init();
- MARK_ENTRY(CODA_MOUNT_STATS);
- if (CODA_MOUNTED(vfsp)) {
- MARK_INT_FAIL(CODA_MOUNT_STATS);
- return (EBUSY);
- }
-
- /*
- * Validate mount device. Similar to getmdev().
- */
- NDINIT(&ndp, LOOKUP, FOLLOW, UIO_SYSSPACE, from, curthread);
- error = namei(&ndp);
- dvp = ndp.ni_vp;
- if (error) {
- MARK_INT_FAIL(CODA_MOUNT_STATS);
- return (error);
- }
- if (dvp->v_type != VCHR) {
- MARK_INT_FAIL(CODA_MOUNT_STATS);
- vrele(dvp);
- NDFREE(&ndp, NDF_ONLY_PNBUF);
- return (ENXIO);
- }
- dev = dvp->v_rdev;
- vrele(dvp);
- NDFREE(&ndp, NDF_ONLY_PNBUF);
-
- /*
- * Initialize the mount record and link it to the vfs struct.
- */
- mi = dev2coda_mntinfo(dev);
- if (!mi) {
- MARK_INT_FAIL(CODA_MOUNT_STATS);
- printf("Coda mount: %s is not a cfs device\n", from);
- return (ENXIO);
- }
- if (!VC_OPEN(&mi->mi_vcomm)) {
- MARK_INT_FAIL(CODA_MOUNT_STATS);
- return (ENODEV);
- }
-
- /*
- * No initialization (here) of mi_vcomm!
- */
- vfsp->mnt_data = mi;
- vfs_getnewfsid (vfsp);
- mi->mi_vfsp = vfsp;
- mi->mi_started = 0; /* XXX See coda_root() */
-
- /*
- * Make a root vnode to placate the Vnode interface, but don't
- * actually make the CODA_ROOT call to venus until the first call to
- * coda_root in case a server is down while venus is starting.
- */
- cp = make_coda_node(&rootfid, vfsp, VDIR);
- rootvp = CTOV(cp);
- rootvp->v_vflag |= VV_ROOT;
- cp = make_coda_node(&ctlfid, vfsp, VREG);
- coda_ctlvp = CTOV(cp);
-
- /*
- * Add vfs and rootvp to chain of vfs hanging off mntinfo.
- */
- mi->mi_vfsp = vfsp;
- mi->mi_rootvp = rootvp;
- vfs_mountedfrom(vfsp, from);
-
- /*
- * Error is currently guaranteed to be zero, but in case some code
- * changes...
- */
- CODADEBUG(1, myprintf(("coda_mount returned %d\n", error)););
- if (error)
- MARK_INT_FAIL(CODA_MOUNT_STATS);
- else
- MARK_INT_SAT(CODA_MOUNT_STATS);
- return (error);
-}
-
-int
-coda_unmount(struct mount *vfsp, int mntflags)
-{
- struct coda_mntinfo *mi = vftomi(vfsp);
- int active, error = 0;
-
- ENTRY;
- MARK_ENTRY(CODA_UMOUNT_STATS);
- if (!CODA_MOUNTED(vfsp)) {
- MARK_INT_FAIL(CODA_UMOUNT_STATS);
- return (EINVAL);
- }
- if (mi->mi_vfsp == vfsp) {
- /*
- * We found the victim.
- */
- if (!IS_UNMOUNTING(VTOC(mi->mi_rootvp)))
- return (EBUSY); /* Venus is still running */
-#ifdef DEBUG
- printf("coda_unmount: ROOT: vp %p, cp %p\n", mi->mi_rootvp,
- VTOC(mi->mi_rootvp));
-#endif
- vrele(mi->mi_rootvp);
- mi->mi_rootvp = NULL;
- vrele(coda_ctlvp);
- coda_ctlvp = NULL;
- active = coda_kill(vfsp, NOT_DOWNCALL);
- error = vflush(mi->mi_vfsp, 0, FORCECLOSE, curthread);
-#ifdef CODA_VERBOSE
- printf("coda_unmount: active = %d, vflush active %d\n",
- active, error);
-#endif
- error = 0;
- /*
- * I'm going to take this out to allow lookups to go through.
- * I'm not sure it's important anyway. -- DCS 2/2/94
- */
- /* vfsp->VFS_DATA = NULL; */
-
- /*
- * No more vfsp's to hold onto.
- */
- mi->mi_vfsp = NULL;
-
- if (error)
- MARK_INT_FAIL(CODA_UMOUNT_STATS);
- else
- MARK_INT_SAT(CODA_UMOUNT_STATS);
- return (error);
- }
- return (EINVAL);
-}
-
-/*
- * Find root of cfs.
- */
-int
-coda_root(struct mount *vfsp, int flags, struct vnode **vpp)
-{
- struct coda_mntinfo *mi = vftomi(vfsp);
- int error;
- struct proc *p;
- struct thread *td;
- struct CodaFid VFid;
- static const struct CodaFid invalfid = INVAL_FID;
-
- td = curthread;
- p = td->td_proc;
- ENTRY;
- MARK_ENTRY(CODA_ROOT_STATS);
- if (vfsp == mi->mi_vfsp) {
- /*
- * Cache the root across calls. We only need to pass the
- * request on to Venus if the root vnode is the dummy we
- * installed in coda_mount() with all c_fid members zeroed.
- *
- * XXX In addition, we assume that the first call to
- * coda_root() is from vfs_mount() (before the call to
- * checkdirs()) and return the dummy root node to avoid a
- * deadlock. This bug is fixed in the Coda CVS repository
- * but not in any released versions as of 6 Mar 2003.
- */
- if (memcmp(&VTOC(mi->mi_rootvp)->c_fid, &invalfid,
- sizeof(struct CodaFid)) != 0 || mi->mi_started == 0) {
- /*
- * Found valid root.
- */
- *vpp = mi->mi_rootvp;
- mi->mi_started = 1;
-
- /*
- * On Mach, this is vref. On FreeBSD, vref +
- * vn_lock.
- */
- vref(*vpp);
- vn_lock(*vpp, LK_EXCLUSIVE | LK_RETRY);
- MARK_INT_SAT(CODA_ROOT_STATS);
- return (0);
- }
- }
-
- error = venus_root(vftomi(vfsp), td->td_ucred, p, &VFid);
- if (!error) {
- /*
- * Save the new rootfid in the cnode, and rehash the cnode
- * into the cnode hash with the new fid key.
- */
- coda_unsave(VTOC(mi->mi_rootvp));
- VTOC(mi->mi_rootvp)->c_fid = VFid;
- coda_save(VTOC(mi->mi_rootvp));
- *vpp = mi->mi_rootvp;
- vref(*vpp);
- vn_lock(*vpp, LK_EXCLUSIVE | LK_RETRY);
- MARK_INT_SAT(CODA_ROOT_STATS);
- } else if (error == ENODEV || error == EINTR) {
- /*
- * Gross hack here!
- *
- * If Venus fails to respond to the CODA_ROOT call, coda_call
- * returns ENODEV. Return the uninitialized root vnode to
- * allow vfs operations such as unmount to continue. Without
- * this hack, there is no way to do an unmount if Venus dies
- * before a successful CODA_ROOT call is done. All vnode
- * operations will fail.
- */
- *vpp = mi->mi_rootvp;
- vref(*vpp);
- vn_lock(*vpp, LK_EXCLUSIVE | LK_RETRY);
- MARK_INT_FAIL(CODA_ROOT_STATS);
- error = 0;
- } else {
- CODADEBUG(CODA_ROOT, myprintf(("error %d in CODA_ROOT\n",
- error)););
- MARK_INT_FAIL(CODA_ROOT_STATS);
- }
- return (error);
-}
-
-/*
- * Get filesystem statistics.
- */
-int
-coda_statfs(struct mount *vfsp, struct statfs *sbp)
-{
-
- ENTRY;
- MARK_ENTRY(CODA_STATFS_STATS);
- if (!CODA_MOUNTED(vfsp)) {
- MARK_INT_FAIL(CODA_STATFS_STATS);
- return (EINVAL);
- }
-
- /*
- * XXX - what to do about f_flags, others? --bnoble
- *
- * We just make up free space counts that are sufficiently large.
- */
- sbp->f_flags = 0;
- sbp->f_bsize = 8192; /* XXX */
- sbp->f_iosize = 8192; /* XXX */
-#define CODA_SFS_SIZ 0x8AB75D
- sbp->f_blocks = CODA_SFS_SIZ;
- sbp->f_bfree = CODA_SFS_SIZ;
- sbp->f_bavail = CODA_SFS_SIZ;
- sbp->f_files = CODA_SFS_SIZ;
- sbp->f_ffree = CODA_SFS_SIZ;
- MARK_INT_SAT(CODA_STATFS_STATS);
- return (0);
-}
-
-/*
- * Flush any pending I/O.
- */
-int
-coda_sync(struct mount *vfsp, int waitfor)
-{
-
- ENTRY;
- MARK_ENTRY(CODA_SYNC_STATS);
- MARK_INT_SAT(CODA_SYNC_STATS);
- return (0);
-}
-
-/*
- * fhtovp is now what vget used to be in 4.3-derived systems. For some silly
- * reason, vget is now keyed by a 32 bit ino_t, rather than a type-specific
- * fid.
- *
- * XXX: coda_fhtovp is currently not hooked up, so no NFS export for Coda.
- * We leave it here in the hopes that someone will find it someday and hook
- * it up. Among other things, it will need some reworking to match the
- * vfs_fhtovp_t prototype.
- */
-int
-coda_fhtovp(struct mount *vfsp, struct fid *fhp, struct mbuf *nam,
- struct vnode **vpp, int *exflagsp, struct ucred **creadanonp)
-{
- struct cfid *cfid = (struct cfid *)fhp;
- struct cnode *cp = NULL;
- int error;
- struct thread *td = curthread; /* XXX -mach */
- struct proc *p = td->td_proc;
- struct CodaFid VFid;
- int vtype;
-
- ENTRY;
- MARK_ENTRY(CODA_VGET_STATS);
-
- /*
- * Check for vget of control object.
- */
- if (IS_CTL_FID(&cfid->cfid_fid)) {
- *vpp = coda_ctlvp;
- vref(coda_ctlvp);
- MARK_INT_SAT(CODA_VGET_STATS);
- return (0);
- }
- error = venus_fhtovp(vftomi(vfsp), &cfid->cfid_fid, td->td_ucred, p,
- &VFid, &vtype);
- if (error) {
- CODADEBUG(CODA_VGET, myprintf(("vget error %d\n",error)););
- *vpp = NULL;
- } else {
- CODADEBUG(CODA_VGET, myprintf(("vget: %s type %d result "
- "%d\n", coda_f2s(&VFid), vtype, error)););
- cp = make_coda_node(&VFid, vfsp, vtype);
- *vpp = CTOV(cp);
- }
- return (error);
-}
-
-struct vfsops coda_vfsops = {
- .vfs_mount = coda_mount,
- .vfs_root = coda_root,
- .vfs_statfs = coda_statfs,
- .vfs_sync = coda_sync,
- .vfs_unmount = coda_unmount,
-};
-VFS_SET(coda_vfsops, coda, VFCF_NETWORK);
diff --git a/sys/fs/coda/coda_vfsops.h b/sys/fs/coda/coda_vfsops.h
deleted file mode 100644
index e5b3a11..0000000
--- a/sys/fs/coda/coda_vfsops.h
+++ /dev/null
@@ -1,60 +0,0 @@
-/*-
- *
- * Coda: an Experimental Distributed File System
- * Release 3.1
- *
- * Copyright (c) 1987-1998 Carnegie Mellon University
- * All Rights Reserved
- *
- * Permission to use, copy, modify and distribute this software and its
- * documentation is hereby granted, provided that both the copyright
- * notice and this permission notice appear in all copies of the
- * software, derivative works or modified versions, and any portions
- * thereof, and that both notices appear in supporting documentation, and
- * that credit is given to Carnegie Mellon University in all documents
- * and publicity pertaining to direct or indirect use of this code or its
- * derivatives.
- *
- * CODA IS AN EXPERIMENTAL SOFTWARE SYSTEM AND IS KNOWN TO HAVE BUGS,
- * SOME OF WHICH MAY HAVE SERIOUS CONSEQUENCES. CARNEGIE MELLON ALLOWS
- * FREE USE OF THIS SOFTWARE IN ITS "AS IS" CONDITION. CARNEGIE MELLON
- * DISCLAIMS ANY LIABILITY OF ANY KIND FOR ANY DAMAGES WHATSOEVER
- * RESULTING DIRECTLY OR INDIRECTLY FROM THE USE OF THIS SOFTWARE OR OF
- * ANY DERIVATIVE WORK.
- *
- * Carnegie Mellon encourages users of this software to return any
- * improvements or extensions that they make, and to grant Carnegie
- * Mellon the rights to redistribute these changes without encumbrance.
- *
- * @(#) src/sys/cfs/coda_vfsops.h,v 1.1.1.1 1998/08/29 21:14:52 rvb Exp $
- * $FreeBSD$
- */
-
-#ifndef _CODA_VFSOPS_H_
-#define _CODA_VFSOPS_H_
-
-/*
- * cfid structure:
- *
- * This overlays the fid structure (see vfs.h); only used below and will
- * probably go away.
- */
-struct cfid {
- u_short cfid_len;
- u_short padding;
- struct CodaFid cfid_fid;
-};
-
-struct mbuf;
-struct mount;
-int coda_vfsopstats_init(void);
-int coda_fhtovp(struct mount *, struct fid *, struct mbuf *,
- struct vnode **, int *, struct ucred **);
-
-vfs_mount_t coda_mount;
-vfs_unmount_t coda_unmount;
-vfs_root_t coda_root;
-vfs_statfs_t coda_statfs;
-vfs_sync_t coda_sync;
-
-#endif /* !_CODA_VFSOPS_H_ */
diff --git a/sys/fs/coda/coda_vnops.c b/sys/fs/coda/coda_vnops.c
deleted file mode 100644
index 51fb307..0000000
--- a/sys/fs/coda/coda_vnops.c
+++ /dev/null
@@ -1,1738 +0,0 @@
-/*-
- * Coda: an Experimental Distributed File System
- * Release 3.1
- *
- * Copyright (c) 1987-1998 Carnegie Mellon University
- * All Rights Reserved
- *
- * Permission to use, copy, modify and distribute this software and its
- * documentation is hereby granted, provided that both the copyright
- * notice and this permission notice appear in all copies of the
- * software, derivative works or modified versions, and any portions
- * thereof, and that both notices appear in supporting documentation, and
- * that credit is given to Carnegie Mellon University in all documents
- * and publicity pertaining to direct or indirect use of this code or its
- * derivatives.
- *
- * CODA IS AN EXPERIMENTAL SOFTWARE SYSTEM AND IS KNOWN TO HAVE BUGS,
- * SOME OF WHICH MAY HAVE SERIOUS CONSEQUENCES. CARNEGIE MELLON ALLOWS
- * FREE USE OF THIS SOFTWARE IN ITS "AS IS" CONDITION. CARNEGIE MELLON
- * DISCLAIMS ANY LIABILITY OF ANY KIND FOR ANY DAMAGES WHATSOEVER
- * RESULTING DIRECTLY OR INDIRECTLY FROM THE USE OF THIS SOFTWARE OR OF
- * ANY DERIVATIVE WORK.
- *
- * Carnegie Mellon encourages users of this software to return any
- * improvements or extensions that they make, and to grant Carnegie
- * Mellon the rights to redistribute these changes without encumbrance.
- *
- * @(#) src/sys/coda/coda_vnops.c,v 1.1.1.1 1998/08/29 21:14:52 rvb Exp $
- */
-/*
- * Mach Operating System
- * Copyright (c) 1990 Carnegie-Mellon University
- * Copyright (c) 1989 Carnegie-Mellon University
- * All rights reserved. The CMU software License Agreement specifies
- * the terms and conditions for use and redistribution.
- */
-
-/*
- * This code was written for the Coda filesystem at Carnegie Mellon
- * University. Contributers include David Steere, James Kistler, and
- * M. Satyanarayanan.
- */
-
-#include <sys/cdefs.h>
-__FBSDID("$FreeBSD$");
-
-#include <sys/param.h>
-#include <sys/systm.h>
-#include <sys/acct.h>
-#include <sys/errno.h>
-#include <sys/fcntl.h>
-#include <sys/kernel.h>
-#include <sys/lock.h>
-#include <sys/malloc.h>
-#include <sys/file.h> /* Must come after sys/malloc.h */
-#include <sys/mount.h>
-#include <sys/mutex.h>
-#include <sys/namei.h>
-#include <sys/proc.h>
-#include <sys/uio.h>
-#include <sys/unistd.h>
-
-#include <vm/vm.h>
-#include <vm/vm_object.h>
-#include <vm/vm_extern.h>
-
-#include <fs/coda/coda.h>
-#include <fs/coda/cnode.h>
-#include <fs/coda/coda_vnops.h>
-#include <fs/coda/coda_venus.h>
-#include <fs/coda/coda_opstats.h>
-#include <fs/coda/coda_subr.h>
-#include <fs/coda/coda_pioctl.h>
-
-/*
- * These flags select various performance enhancements.
- */
-static int coda_attr_cache = 1; /* Set to cache attributes. */
-static int coda_symlink_cache = 1; /* Set to cache symbolic links. */
-static int coda_access_cache = 1; /* Set to cache some access checks. */
-
-/*
- * Structure to keep track of vfs calls.
- */
-static struct coda_op_stats coda_vnodeopstats[CODA_VNODEOPS_SIZE];
-
-#define MARK_ENTRY(op) (coda_vnodeopstats[op].entries++)
-#define MARK_INT_SAT(op) (coda_vnodeopstats[op].sat_intrn++)
-#define MARK_INT_FAIL(op) (coda_vnodeopstats[op].unsat_intrn++)
-#define MARK_INT_GEN(op) (coda_vnodeopstats[op].gen_intrn++)
-
-/*
- * What we are delaying for in printf.
- */
-int coda_printf_delay = 0; /* In microseconds */
-int coda_vnop_print_entry = 0;
-static int coda_lockdebug = 0;
-
-/*
- * Some FreeBSD details:
- *
- * codadev_modevent is called at boot time or module load time.
- */
-#define ENTRY do { \
- if (coda_vnop_print_entry) \
- myprintf(("Entered %s\n", __func__)); \
-} while (0)
-
-/*
- * Definition of the vnode operation vector.
- */
-struct vop_vector coda_vnodeops = {
- .vop_default = &default_vnodeops,
- .vop_cachedlookup = coda_lookup, /* uncached lookup */
- .vop_lookup = vfs_cache_lookup, /* namecache lookup */
- .vop_create = coda_create, /* create */
- .vop_open = coda_open, /* open */
- .vop_close = coda_close, /* close */
- .vop_access = coda_access, /* access */
- .vop_getattr = coda_getattr, /* getattr */
- .vop_setattr = coda_setattr, /* setattr */
- .vop_read = coda_read, /* read */
- .vop_write = coda_write, /* write */
- .vop_ioctl = coda_ioctl, /* ioctl */
- .vop_fsync = coda_fsync, /* fsync */
- .vop_remove = coda_remove, /* remove */
- .vop_link = coda_link, /* link */
- .vop_rename = coda_rename, /* rename */
- .vop_mkdir = coda_mkdir, /* mkdir */
- .vop_rmdir = coda_rmdir, /* rmdir */
- .vop_symlink = coda_symlink, /* symlink */
- .vop_readdir = coda_readdir, /* readdir */
- .vop_readlink = coda_readlink, /* readlink */
- .vop_inactive = coda_inactive, /* inactive */
- .vop_reclaim = coda_reclaim, /* reclaim */
- .vop_lock1 = coda_lock, /* lock */
- .vop_unlock = coda_unlock, /* unlock */
- .vop_bmap = VOP_EOPNOTSUPP, /* bmap */
- .vop_print = VOP_NULL, /* print */
- .vop_islocked = coda_islocked, /* islocked */
- .vop_pathconf = coda_pathconf, /* pathconf */
- .vop_poll = vop_stdpoll,
- .vop_getpages = vop_stdgetpages, /* pager intf.*/
- .vop_putpages = vop_stdputpages, /* pager intf.*/
- .vop_getwritemount = vop_stdgetwritemount,
-#if 0
- /* missing */
- .vop_cachedlookup = ufs_lookup,
- .vop_whiteout = ufs_whiteout,
-#endif
-
-};
-
-static void coda_print_vattr(struct vattr *attr);
-
-int
-coda_vnodeopstats_init(void)
-{
- int i;
-
- for(i=0; i<CODA_VNODEOPS_SIZE; i++) {
- coda_vnodeopstats[i].opcode = i;
- coda_vnodeopstats[i].entries = 0;
- coda_vnodeopstats[i].sat_intrn = 0;
- coda_vnodeopstats[i].unsat_intrn = 0;
- coda_vnodeopstats[i].gen_intrn = 0;
- }
- return (0);
-}
-
-/*
- * coda_open calls Venus which returns an open file descriptor the cache file
- * holding the data. We get the vnode while we are still in the context of
- * the venus process in coda_psdev.c. This vnode is then passed back to the
- * caller and opened.
- */
-int
-coda_open(struct vop_open_args *ap)
-{
-
- /*
- * FreeBSD can pass the O_EXCL flag in mode, even though the check
- * has already happened. Venus defensively assumes that if open is
- * passed the EXCL, it must be a bug. We strip the flag here.
- */
- /* true args */
- struct vnode **vpp = &(ap->a_vp);
- struct cnode *cp = VTOC(*vpp);
- int flag = ap->a_mode & (~O_EXCL);
- struct ucred *cred = ap->a_cred;
- struct thread *td = ap->a_td;
- /* locals */
- int error;
- struct vnode *vp;
-
- MARK_ENTRY(CODA_OPEN_STATS);
-
- /*
- * Check for open of control file.
- */
- if (IS_CTL_VP(*vpp)) {
- /* XXX */
- /* if (WRITEABLE(flag)) */
- if (flag & (FWRITE | O_TRUNC | O_CREAT | O_EXCL)) {
- MARK_INT_FAIL(CODA_OPEN_STATS);
- return (EACCES);
- }
- MARK_INT_SAT(CODA_OPEN_STATS);
- return (0);
- }
- error = venus_open(vtomi((*vpp)), &cp->c_fid, flag, cred,
- td->td_proc, &vp);
- if (error)
- return (error);
- CODADEBUG(CODA_OPEN, myprintf(("open: vp %p result %d\n", vp,
- error)););
-
- /*
- * Save the vnode pointer for the cache file.
- */
- if (cp->c_ovp == NULL) {
- cp->c_ovp = vp;
- } else {
- if (cp->c_ovp != vp)
- panic("coda_open: cp->c_ovp != ITOV(ip)");
- }
- cp->c_ocount++;
-
- /*
- * Flush the attribute cached if writing the file.
- */
- if (flag & FWRITE) {
- cp->c_owrite++;
- cp->c_flags &= ~C_VATTR;
- }
-
- /*
- * Open the cache file.
- */
- vn_lock(vp, LK_EXCLUSIVE | LK_RETRY);
- error = VOP_OPEN(vp, flag, cred, td, NULL);
- if (error) {
- VOP_UNLOCK(vp, 0);
- printf("coda_open: VOP_OPEN on container failed %d\n", error);
- return (error);
- }
- (*vpp)->v_object = vp->v_object;
- VOP_UNLOCK(vp, 0);
- return (0);
-}
-
-/*
- * Close the cache file used for I/O and notify Venus.
- */
-int
-coda_close(struct vop_close_args *ap)
-{
- /* true args */
- struct vnode *vp = ap->a_vp;
- struct cnode *cp = VTOC(vp);
- int flag = ap->a_fflag;
- struct ucred *cred = ap->a_cred;
- struct thread *td = ap->a_td;
- /* locals */
- int error;
-
- MARK_ENTRY(CODA_CLOSE_STATS);
-
- /*
- * Check for close of control file.
- */
- if (IS_CTL_VP(vp)) {
- MARK_INT_SAT(CODA_CLOSE_STATS);
- return (0);
- }
- if (cp->c_ovp) {
- vn_lock(cp->c_ovp, LK_EXCLUSIVE | LK_RETRY);
- /* Do errors matter here? */
- VOP_CLOSE(cp->c_ovp, flag, cred, td);
- vput(cp->c_ovp);
- }
-#ifdef CODA_VERBOSE
- else
- printf("coda_close: NO container vp %p/cp %p\n", vp, cp);
-#endif
- if (--cp->c_ocount == 0)
- cp->c_ovp = NULL;
-
- /*
- * File was opened for write.
- */
- if (flag & FWRITE)
- --cp->c_owrite;
- if (!IS_UNMOUNTING(cp))
- error = venus_close(vtomi(vp), &cp->c_fid, flag, cred,
- td->td_proc);
- else
- error = ENODEV;
- CODADEBUG(CODA_CLOSE, myprintf(("close: result %d\n",error)););
- return (error);
-}
-
-int
-coda_read(struct vop_read_args *ap)
-{
-
- ENTRY;
- return (coda_rdwr(ap->a_vp, ap->a_uio, UIO_READ, ap->a_ioflag,
- ap->a_cred, ap->a_uio->uio_td));
-}
-
-int
-coda_write(struct vop_write_args *ap)
-{
-
- ENTRY;
- return (coda_rdwr(ap->a_vp, ap->a_uio, UIO_WRITE, ap->a_ioflag,
- ap->a_cred, ap->a_uio->uio_td));
-}
-
-int
-coda_rdwr(struct vnode *vp, struct uio *uiop, enum uio_rw rw, int ioflag,
- struct ucred *cred, struct thread *td)
-{
- /* upcall decl */
- /* NOTE: container file operation!!! */
- /* locals */
- struct cnode *cp = VTOC(vp);
- struct vnode *cfvp = cp->c_ovp;
- int opened_internally = 0;
- int error = 0;
-
- MARK_ENTRY(CODA_RDWR_STATS);
- CODADEBUG(CODA_RDWR, myprintf(("coda_rdwr(%d, %p, %zd, %lld, %d)\n",
- rw, (void *)uiop->uio_iov->iov_base, uiop->uio_resid,
- (long long)uiop->uio_offset, uiop->uio_segflg)););
-
- /*
- * Check for rdwr of control object.
- */
- if (IS_CTL_VP(vp)) {
- MARK_INT_FAIL(CODA_RDWR_STATS);
- return (EINVAL);
- }
-
- /*
- * If file is not already open this must be a page {read,write}
- * request and we should open it internally.
- */
- if (cfvp == NULL) {
- opened_internally = 1;
- MARK_INT_GEN(CODA_OPEN_STATS);
- error = VOP_OPEN(vp, (rw == UIO_READ ? FREAD : FWRITE), cred,
- td, NULL);
-#ifdef CODA_VERBOSE
- printf("coda_rdwr: Internally Opening %p\n", vp);
-#endif
- if (error) {
- printf("coda_rdwr: VOP_OPEN on container failed "
- "%d\n", error);
- return (error);
- }
- cfvp = cp->c_ovp;
- }
-
- /*
- * Have UFS handle the call.
- */
- CODADEBUG(CODA_RDWR, myprintf(("indirect rdwr: fid = %s, refcnt = "
- "%d\n", coda_f2s(&cp->c_fid), CTOV(cp)->v_usecount)););
- vn_lock(cfvp, LK_EXCLUSIVE | LK_RETRY);
- if (rw == UIO_READ) {
- error = VOP_READ(cfvp, uiop, ioflag, cred);
- } else {
- error = VOP_WRITE(cfvp, uiop, ioflag, cred);
- /*
- * ufs_write updates the vnode_pager_setsize for the
- * vnode/object.
- *
- * XXX: Since we now share vm objects between layers, this is
- * probably unnecessary.
- */
- {
- struct vattr attr;
- if (VOP_GETATTR(cfvp, &attr, cred) == 0)
- vnode_pager_setsize(vp, attr.va_size);
- }
- }
- VOP_UNLOCK(cfvp, 0);
- if (error)
- MARK_INT_FAIL(CODA_RDWR_STATS);
- else
- MARK_INT_SAT(CODA_RDWR_STATS);
-
- /*
- * Do an internal close if necessary.
- */
- if (opened_internally) {
- MARK_INT_GEN(CODA_CLOSE_STATS);
- (void)VOP_CLOSE(vp, (rw == UIO_READ ? FREAD : FWRITE), cred,
- td);
- }
-
- /*
- * Invalidate cached attributes if writing.
- */
- if (rw == UIO_WRITE)
- cp->c_flags &= ~C_VATTR;
- return (error);
-}
-
-int
-coda_ioctl(struct vop_ioctl_args *ap)
-{
- /* true args */
- struct vnode *vp = ap->a_vp;
- int com = ap->a_command;
- caddr_t data = ap->a_data;
- int flag = ap->a_fflag;
- struct ucred *cred = ap->a_cred;
- struct thread *td = ap->a_td;
- /* locals */
- int error;
- struct vnode *tvp;
- struct nameidata ndp;
- struct PioctlData *iap = (struct PioctlData *)data;
-
- MARK_ENTRY(CODA_IOCTL_STATS);
- CODADEBUG(CODA_IOCTL, myprintf(("in coda_ioctl on %s\n", iap->path)););
-
- /*
- * Don't check for operation on a dying object, for ctlvp it
- * shouldn't matter.
- *
- * Must be control object to succeed.
- */
- if (!IS_CTL_VP(vp)) {
- MARK_INT_FAIL(CODA_IOCTL_STATS);
- CODADEBUG(CODA_IOCTL, myprintf(("coda_ioctl error: vp != "
- "ctlvp")););
- return (EOPNOTSUPP);
- }
-
- /*
- * Look up the pathname.
- *
- * Should we use the name cache here? It would get it from lookupname
- * sooner or later anyway, right?
- */
- NDINIT(&ndp, LOOKUP, (iap->follow ? FOLLOW : NOFOLLOW),
- UIO_USERSPACE, iap->path, td);
- error = namei(&ndp);
- tvp = ndp.ni_vp;
- if (error) {
- MARK_INT_FAIL(CODA_IOCTL_STATS);
- CODADEBUG(CODA_IOCTL, myprintf(("coda_ioctl error: lookup "
- "returns %d\n", error)););
- return (error);
- }
-
- /*
- * Make sure this is a coda style cnode, but it may be a different
- * vfsp.
- */
- if (tvp->v_op != &coda_vnodeops) {
- vrele(tvp);
- NDFREE(&ndp, NDF_ONLY_PNBUF);
- MARK_INT_FAIL(CODA_IOCTL_STATS);
- CODADEBUG(CODA_IOCTL,
- myprintf(("coda_ioctl error: %s not a coda object\n",
- iap->path)););
- return (EINVAL);
- }
- if (iap->vi.in_size > VC_MAXDATASIZE ||
- iap->vi.out_size > VC_MAXDATASIZE) {
- NDFREE(&ndp, 0);
- return (EINVAL);
- }
- error = venus_ioctl(vtomi(tvp), &((VTOC(tvp))->c_fid), com, flag,
- data, cred, td->td_proc);
- if (error)
- MARK_INT_FAIL(CODA_IOCTL_STATS);
- else
- CODADEBUG(CODA_IOCTL, myprintf(("Ioctl returns %d \n",
- error)););
- vrele(tvp);
- NDFREE(&ndp, NDF_ONLY_PNBUF);
- return (error);
-}
-
-/*
- * To reduce the cost of a user-level venus;we cache attributes in the
- * kernel. Each cnode has storage allocated for an attribute. If c_vattr is
- * valid, return a reference to it. Otherwise, get the attributes from venus
- * and store them in the cnode. There is some question if this method is a
- * security leak. But I think that in order to make this call, the user must
- * have done a lookup and opened the file, and therefore should already have
- * access.
- */
-int
-coda_getattr(struct vop_getattr_args *ap)
-{
- /* true args */
- struct vnode *vp = ap->a_vp;
- struct cnode *cp = VTOC(vp);
- struct vattr *vap = ap->a_vap;
- struct ucred *cred = ap->a_cred;
- /* locals */
- struct vnode *convp;
- int error, size;
-
- MARK_ENTRY(CODA_GETATTR_STATS);
- if (IS_UNMOUNTING(cp))
- return (ENODEV);
-
- /*
- * Check for getattr of control object.
- */
- if (IS_CTL_VP(vp)) {
- MARK_INT_FAIL(CODA_GETATTR_STATS);
- return (ENOENT);
- }
-
- /*
- * Check to see if the attributes have already been cached.
- */
- if (VALID_VATTR(cp)) {
- CODADEBUG(CODA_GETATTR, myprintf(("attr cache hit: %s\n",
- coda_f2s(&cp->c_fid))););
- CODADEBUG(CODA_GETATTR, if (!(codadebug & ~CODA_GETATTR))
- coda_print_vattr(&cp->c_vattr););
- *vap = cp->c_vattr;
- MARK_INT_SAT(CODA_GETATTR_STATS);
- return (0);
- }
- error = venus_getattr(vtomi(vp), &cp->c_fid, cred, vap);
- if (!error) {
- CODADEBUG(CODA_GETATTR, myprintf(("getattr miss %s: result "
- "%d\n", coda_f2s(&cp->c_fid), error)););
- CODADEBUG(CODA_GETATTR, if (!(codadebug & ~CODA_GETATTR))
- coda_print_vattr(vap););
-
- /*
- * XXX: Since we now share vm objects between layers, this is
- * probably unnecessary.
- */
- size = vap->va_size;
- convp = cp->c_ovp;
- if (convp != NULL)
- vnode_pager_setsize(convp, size);
-
- /*
- * If not open for write, store attributes in cnode.
- */
- if ((cp->c_owrite == 0) && (coda_attr_cache)) {
- cp->c_vattr = *vap;
- cp->c_flags |= C_VATTR;
- }
- }
- return (error);
-}
-
-int
-coda_setattr(struct vop_setattr_args *ap)
-{
- /* true args */
- struct vnode *vp = ap->a_vp;
- struct cnode *cp = VTOC(vp);
- struct vattr *vap = ap->a_vap;
- struct ucred *cred = ap->a_cred;
- /* locals */
- struct vnode *convp;
- int error, size;
-
- MARK_ENTRY(CODA_SETATTR_STATS);
-
- /*
- * Check for setattr of control object.
- */
- if (IS_CTL_VP(vp)) {
- MARK_INT_FAIL(CODA_SETATTR_STATS);
- return (ENOENT);
- }
- if (codadebug & CODADBGMSK(CODA_SETATTR))
- coda_print_vattr(vap);
- error = venus_setattr(vtomi(vp), &cp->c_fid, vap, cred);
- if (!error)
- cp->c_flags &= ~(C_VATTR | C_ACCCACHE);
-
- /*
- * XXX: Since we now share vm objects between layers, this is
- * probably unnecessary.
- *
- * XXX: Shouldn't we only be doing this "set" if C_VATTR remains
- * valid after venus_setattr()?
- */
- size = vap->va_size;
- convp = cp->c_ovp;
- if (size != VNOVAL && convp != NULL)
- vnode_pager_setsize(convp, size);
- CODADEBUG(CODA_SETATTR, myprintf(("setattr %d\n", error)););
- return (error);
-}
-
-int
-coda_access(struct vop_access_args *ap)
-{
- /* true args */
- struct vnode *vp = ap->a_vp;
- struct cnode *cp = VTOC(vp);
- accmode_t accmode = ap->a_accmode;
- struct ucred *cred = ap->a_cred;
- struct thread *td = ap->a_td;
- /* locals */
- int error;
-
- MARK_ENTRY(CODA_ACCESS_STATS);
-
- /*
- * Check for access of control object. Only read access is allowed
- * on it.
- */
- if (IS_CTL_VP(vp)) {
- /*
- * Bogus hack - all will be marked as successes.
- */
- MARK_INT_SAT(CODA_ACCESS_STATS);
- return (((accmode & VREAD) && !(accmode & (VWRITE | VEXEC)))
- ? 0 : EACCES);
- }
-
- /*
- * We maintain a one-entry LRU positive access cache with each cnode.
- * In principle we could also track negative results, and for more
- * than one uid, but we don't yet. Venus is responsible for
- * invalidating this cache as required.
- */
- if (coda_access_cache && VALID_ACCCACHE(cp) &&
- (cred->cr_uid == cp->c_cached_uid) &&
- (accmode & cp->c_cached_mode) == accmode) {
- MARK_INT_SAT(CODA_ACCESS_STATS);
- return (0);
- }
- error = venus_access(vtomi(vp), &cp->c_fid, accmode, cred, td->td_proc);
- if (error == 0 && coda_access_cache) {
- /*-
- * When we have a new successful request, we consider three
- * cases:
- *
- * - No initialized access cache, in which case cache the
- * result.
- * - Cached result for a different user, in which case we
- * replace the entry.
- * - Cached result for the same user, in which case we add
- * any newly granted rights to the cached mode.
- *
- * XXXRW: If we ever move to something more interesting than
- * uid-based token lookup, we'll need to change this.
- */
- cp->c_flags |= C_ACCCACHE;
- if (cp->c_cached_uid != cred->cr_uid) {
- cp->c_cached_mode = accmode;
- cp->c_cached_uid = cred->cr_uid;
- } else
- cp->c_cached_mode |= accmode;
- }
- return (error);
-}
-
-int
-coda_readlink(struct vop_readlink_args *ap)
-{
- /* true args */
- struct vnode *vp = ap->a_vp;
- struct cnode *cp = VTOC(vp);
- struct uio *uiop = ap->a_uio;
- struct ucred *cred = ap->a_cred;
- struct thread *td = ap->a_uio->uio_td;
- /* locals */
- int error;
- char *str;
- int len;
-
- MARK_ENTRY(CODA_READLINK_STATS);
-
- /*
- * Check for readlink of control object.
- */
- if (IS_CTL_VP(vp)) {
- MARK_INT_FAIL(CODA_READLINK_STATS);
- return (ENOENT);
- }
- if ((coda_symlink_cache) && (VALID_SYMLINK(cp))) {
- /*
- * Symlink was cached.
- */
- uiop->uio_rw = UIO_READ;
- error = uiomove(cp->c_symlink, (int)cp->c_symlen, uiop);
- if (error)
- MARK_INT_FAIL(CODA_READLINK_STATS);
- else
- MARK_INT_SAT(CODA_READLINK_STATS);
- return (error);
- }
- error = venus_readlink(vtomi(vp), &cp->c_fid, cred, td != NULL ?
- td->td_proc : NULL, &str, &len);
- if (!error) {
- uiop->uio_rw = UIO_READ;
- error = uiomove(str, len, uiop);
- if (coda_symlink_cache) {
- cp->c_symlink = str;
- cp->c_symlen = len;
- cp->c_flags |= C_SYMLINK;
- } else
- CODA_FREE(str, len);
- }
- CODADEBUG(CODA_READLINK, myprintf(("in readlink result %d\n",
- error)););
- return (error);
-}
-
-int
-coda_fsync(struct vop_fsync_args *ap)
-{
- /* true args */
- struct vnode *vp = ap->a_vp;
- struct cnode *cp = VTOC(vp);
- struct thread *td = ap->a_td;
- /* locals */
- struct vnode *convp = cp->c_ovp;
- int error;
-
- MARK_ENTRY(CODA_FSYNC_STATS);
-
- /*
- * Check for fsync on an unmounting object.
- *
- * XXX: Is this comment true on FreeBSD? It seems likely, since
- * unmounting is fairly non-atomic.
- *
- * The NetBSD kernel, in it's infinite wisdom, can try to fsync after
- * an unmount has been initiated. This is a Bad Thing, which we have
- * to avoid. Not a legitimate failure for stats.
- */
- if (IS_UNMOUNTING(cp))
- return (ENODEV);
-
- /*
- * Check for fsync of control object.
- */
- if (IS_CTL_VP(vp)) {
- MARK_INT_SAT(CODA_FSYNC_STATS);
- return (0);
- }
- if (convp != NULL) {
- vn_lock(convp, LK_EXCLUSIVE | LK_RETRY);
- VOP_FSYNC(convp, MNT_WAIT, td);
- VOP_UNLOCK(convp, 0);
- }
-
- /*
- * We see fsyncs with usecount == 1 then usecount == 0. For now we
- * ignore them.
- */
-#if 0
- VI_LOCK(vp);
- if (!vp->v_usecount) {
- printf("coda_fsync on vnode %p with %d usecount. "
- "c_flags = %x (%x)\n", vp, vp->v_usecount, cp->c_flags,
- cp->c_flags&C_PURGING);
- }
- VI_UNLOCK(vp);
-#endif
-
- /*
- * We can expect fsync on any vnode at all if venus is purging it.
- * Venus can't very well answer the fsync request, now can it?
- * Hopefully, it won't have to, because hopefully, venus preserves
- * the (possibly untrue) invariant that it never purges an open
- * vnode. Hopefully.
- */
- if (cp->c_flags & C_PURGING)
- return (0);
-
- /* XXX: needs research */
- return (0);
- error = venus_fsync(vtomi(vp), &cp->c_fid, td->td_proc);
- CODADEBUG(CODA_FSYNC, myprintf(("in fsync result %d\n", error)););
- return (error);
-}
-
-int
-coda_inactive(struct vop_inactive_args *ap)
-{
- /*
- * XXX - at the moment, inactive doesn't look at cred, and doesn't
- * have a proc pointer. Oops.
- */
- /* true args */
- struct vnode *vp = ap->a_vp;
- struct cnode *cp = VTOC(vp);
- struct ucred *cred __attribute__((unused)) = NULL;
- struct thread *td __attribute__((unused)) = curthread;
- /* upcall decl */
- /* locals */
-
- /*
- * We don't need to send inactive to venus - DCS.
- */
- MARK_ENTRY(CODA_INACTIVE_STATS);
- CODADEBUG(CODA_INACTIVE, myprintf(("in inactive, %s, vfsp %p\n",
- coda_f2s(&cp->c_fid), vp->v_mount)););
- vp->v_object = NULL;
-
- /*
- * If an array has been allocated to hold the symlink, deallocate it.
- */
- if ((coda_symlink_cache) && (VALID_SYMLINK(cp))) {
- if (cp->c_symlink == NULL)
- panic("coda_inactive: null symlink pointer in cnode");
- CODA_FREE(cp->c_symlink, cp->c_symlen);
- cp->c_flags &= ~C_SYMLINK;
- cp->c_symlen = 0;
- }
-
- /*
- * Remove it from the table so it can't be found.
- */
- coda_unsave(cp);
- if ((struct coda_mntinfo *)(vp->v_mount->mnt_data) == NULL) {
- myprintf(("Help! vfsp->vfs_data was NULL, but vnode %p "
- "wasn't dying\n", vp));
- panic("badness in coda_inactive\n");
- }
- if (IS_UNMOUNTING(cp)) {
-#ifdef DEBUG
- printf("coda_inactive: IS_UNMOUNTING use %d: vp %p, cp %p\n",
- vrefcnt(vp), vp, cp);
- if (cp->c_ovp != NULL)
- printf("coda_inactive: cp->ovp != NULL use %d: vp "
- "%p, cp %p\n", vrefcnt(vp), vp, cp);
-#endif
- } else
- vgone(vp);
- MARK_INT_SAT(CODA_INACTIVE_STATS);
- return (0);
-}
-
-/*
- * Remote filesystem operations having to do with directory manipulation.
- */
-
-/*
- * In FreeBSD, lookup returns the vnode locked.
- */
-int
-coda_lookup(struct vop_cachedlookup_args *ap)
-{
- /* true args */
- struct vnode *dvp = ap->a_dvp;
- struct cnode *dcp = VTOC(dvp);
- struct vnode **vpp = ap->a_vpp;
- /*
- * It looks as though ap->a_cnp->ni_cnd->cn_nameptr holds the rest of
- * the string to xlate, and that we must try to get at least
- * ap->a_cnp->ni_cnd->cn_namelen of those characters to macth. I
- * could be wrong.
- */
- struct componentname *cnp = ap->a_cnp;
- struct ucred *cred = cnp->cn_cred;
- struct thread *td = cnp->cn_thread;
- /* locals */
- struct cnode *cp;
- const char *nm = cnp->cn_nameptr;
- int len = cnp->cn_namelen;
- struct CodaFid VFid;
- int vtype;
- int error = 0;
-
- MARK_ENTRY(CODA_LOOKUP_STATS);
- CODADEBUG(CODA_LOOKUP, myprintf(("lookup: %s in %s\n", nm,
- coda_f2s(&dcp->c_fid))););
-
- /*
- * Check for lookup of control object.
- */
- if (IS_CTL_NAME(dvp, nm, len)) {
- *vpp = coda_ctlvp;
- vref(*vpp);
- MARK_INT_SAT(CODA_LOOKUP_STATS);
- goto exit;
- }
- if (len+1 > CODA_MAXNAMLEN) {
- MARK_INT_FAIL(CODA_LOOKUP_STATS);
- CODADEBUG(CODA_LOOKUP, myprintf(("name too long: lookup, "
- "%s (%s)\n", coda_f2s(&dcp->c_fid), nm)););
- *vpp = NULL;
- error = EINVAL;
- goto exit;
- }
-
- error = venus_lookup(vtomi(dvp), &dcp->c_fid, nm, len, cred,
- td->td_proc, &VFid, &vtype);
- if (error) {
- MARK_INT_FAIL(CODA_LOOKUP_STATS);
- CODADEBUG(CODA_LOOKUP, myprintf(("lookup error on %s "
- "(%s)%d\n", coda_f2s(&dcp->c_fid), nm, error)););
- *vpp = NULL;
- } else {
- MARK_INT_SAT(CODA_LOOKUP_STATS);
- CODADEBUG(CODA_LOOKUP, myprintf(("lookup: %s type %o "
- "result %d\n", coda_f2s(&VFid), vtype, error)););
- cp = make_coda_node(&VFid, dvp->v_mount, vtype);
- *vpp = CTOV(cp);
-
- /*
- * Enter the new vnode in the namecache only if the top bit
- * isn't set.
- *
- * And don't enter a new vnode for an invalid one!
- */
- if (!(vtype & CODA_NOCACHE) && (cnp->cn_flags & MAKEENTRY))
- cache_enter(dvp, *vpp, cnp);
- }
-exit:
- /*
- * If we are creating, and this was the last name to be looked up,
- * and the error was ENOENT, then there really shouldn't be an error
- * and we can make the leaf NULL and return success. Since this is
- * supposed to work under Mach as well as FreeBSD, we're leaving this
- * fn wrapped. We also must tell lookup/namei that we need to save
- * the last component of the name. (Create will have to free the
- * name buffer later...lucky us...).
- */
- if (((cnp->cn_nameiop == CREATE) || (cnp->cn_nameiop == RENAME))
- && (cnp->cn_flags & ISLASTCN) && (error == ENOENT)) {
- error = EJUSTRETURN;
- cnp->cn_flags |= SAVENAME;
- *ap->a_vpp = NULL;
- }
-
- /*
- * If we are removing, and we are at the last element, and we found
- * it, then we need to keep the name around so that the removal will
- * go ahead as planned. Unfortunately, this will probably also lock
- * the to-be-removed vnode, which may or may not be a good idea.
- * I'll have to look at the bits of coda_remove to make sure. We'll
- * only save the name if we did in fact find the name, otherwise
- * coda_remove won't have a chance to free the pathname.
- */
- if ((cnp->cn_nameiop == DELETE) && (cnp->cn_flags & ISLASTCN)
- && !error)
- cnp->cn_flags |= SAVENAME;
-
- /*
- * If the lookup went well, we need to (potentially?) unlock the
- * parent, and lock the child. We are only responsible for checking
- * to see if the parent is supposed to be unlocked before we return.
- * We must always lock the child (provided there is one, and (the
- * parent isn't locked or it isn't the same as the parent.) Simple,
- * huh? We can never leave the parent locked unless we are ISLASTCN.
- */
- if (!error || (error == EJUSTRETURN)) {
- if (cnp->cn_flags & ISDOTDOT) {
- VOP_UNLOCK(dvp, 0);
- /*
- * The parent is unlocked. As long as there is a
- * child, lock it without bothering to check anything
- * else.
- */
- if (*ap->a_vpp)
- vn_lock(*ap->a_vpp, LK_EXCLUSIVE | LK_RETRY);
- vn_lock(dvp, LK_RETRY|LK_EXCLUSIVE);
- } else {
- /*
- * The parent is locked, and may be the same as the
- * child. If different, go ahead and lock it.
- */
- if (*ap->a_vpp && (*ap->a_vpp != dvp))
- vn_lock(*ap->a_vpp, LK_EXCLUSIVE | LK_RETRY);
- }
- } else {
- /*
- * If the lookup failed, we need to ensure that the leaf is
- * NULL.
- *
- * Don't change any locking?
- */
- *ap->a_vpp = NULL;
- }
- return (error);
-}
-
-/*ARGSUSED*/
-int
-coda_create(struct vop_create_args *ap)
-{
- /* true args */
- struct vnode *dvp = ap->a_dvp;
- struct cnode *dcp = VTOC(dvp);
- struct vattr *va = ap->a_vap;
- int exclusive = 1;
- int mode = ap->a_vap->va_mode;
- struct vnode **vpp = ap->a_vpp;
- struct componentname *cnp = ap->a_cnp;
- struct ucred *cred = cnp->cn_cred;
- struct thread *td = cnp->cn_thread;
- /* locals */
- int error;
- struct cnode *cp;
- const char *nm = cnp->cn_nameptr;
- int len = cnp->cn_namelen;
- struct CodaFid VFid;
- struct vattr attr;
-
- MARK_ENTRY(CODA_CREATE_STATS);
-
- /*
- * All creates are exclusive XXX.
- *
- * I'm assuming the 'mode' argument is the file mode bits XXX.
- *
- * Check for create of control object.
- */
- if (IS_CTL_NAME(dvp, nm, len)) {
- *vpp = (struct vnode *)0;
- MARK_INT_FAIL(CODA_CREATE_STATS);
- return (EACCES);
- }
- error = venus_create(vtomi(dvp), &dcp->c_fid, nm, len, exclusive,
- mode, va, cred, td->td_proc, &VFid, &attr);
- if (!error) {
- /*
- * If this is an exclusive create, panic if the file already
- * exists.
- *
- * Venus should have detected the file and reported EEXIST.
- */
- if ((exclusive == 1) && (coda_find(&VFid) != NULL))
- panic("cnode existed for newly created file!");
- cp = make_coda_node(&VFid, dvp->v_mount, attr.va_type);
- *vpp = CTOV(cp);
-
- /*
- * Update va to reflect the new attributes.
- */
- (*va) = attr;
-
- /*
- * Update the attribute cache and mark it as valid.
- */
- if (coda_attr_cache) {
- VTOC(*vpp)->c_vattr = attr;
- VTOC(*vpp)->c_flags |= C_VATTR;
- }
-
- /*
- * Invalidate the parent's attr cache, the modification time
- * has changed.
- */
- VTOC(dvp)->c_flags &= ~C_VATTR;
- cache_enter(dvp, *vpp, cnp);
- CODADEBUG(CODA_CREATE, myprintf(("create: %s, result %d\n",
- coda_f2s(&VFid), error)););
- } else {
- *vpp = (struct vnode *)0;
- CODADEBUG(CODA_CREATE, myprintf(("create error %d\n",
- error)););
- }
- if (!error) {
- if (cnp->cn_flags & MAKEENTRY)
- cache_enter(dvp, *vpp, cnp);
- if (cnp->cn_flags & LOCKLEAF)
- vn_lock(*ap->a_vpp, LK_EXCLUSIVE | LK_RETRY);
- } else if (error == ENOENT) {
- /*
- * XXXRW: We only enter a negative entry if ENOENT is
- * returned, not other errors. But will Venus invalidate dvp
- * properly in all cases when new files appear via the
- * network rather than a local operation?
- */
- if (cnp->cn_flags & MAKEENTRY)
- cache_enter(dvp, NULL, cnp);
- }
- return (error);
-}
-
-int
-coda_remove(struct vop_remove_args *ap)
-{
- /* true args */
- struct vnode *vp = ap->a_vp;
- struct vnode *dvp = ap->a_dvp;
- struct cnode *cp = VTOC(dvp);
- struct componentname *cnp = ap->a_cnp;
- struct ucred *cred = cnp->cn_cred;
- struct thread *td = cnp->cn_thread;
- /* locals */
- int error;
- const char *nm = cnp->cn_nameptr;
- int len = cnp->cn_namelen;
-#if 0
- struct cnode *tp;
-#endif
-
- MARK_ENTRY(CODA_REMOVE_STATS);
- CODADEBUG(CODA_REMOVE, myprintf(("remove: %s in %s\n", nm,
- coda_f2s(&cp->c_fid))););
-
- /*
- * Check for remove of control object.
- */
- if (IS_CTL_NAME(dvp, nm, len)) {
- MARK_INT_FAIL(CODA_REMOVE_STATS);
- return (ENOENT);
- }
-
- /*
- * Invalidate the parent's attr cache, the modification time has
- * changed. We don't yet know if the last reference to the file is
- * being removed, but we do know the reference count on the child has
- * changed, so invalidate its attr cache also.
- */
- VTOC(dvp)->c_flags &= ~C_VATTR;
- VTOC(vp)->c_flags &= ~(C_VATTR | C_ACCCACHE);
- error = venus_remove(vtomi(dvp), &cp->c_fid, nm, len, cred,
- td->td_proc);
- cache_purge(vp);
- CODADEBUG(CODA_REMOVE, myprintf(("in remove result %d\n",error)););
- return (error);
-}
-
-int
-coda_link(struct vop_link_args *ap)
-{
- /* true args */
- struct vnode *vp = ap->a_vp;
- struct cnode *cp = VTOC(vp);
- struct vnode *tdvp = ap->a_tdvp;
- struct cnode *tdcp = VTOC(tdvp);
- struct componentname *cnp = ap->a_cnp;
- struct ucred *cred = cnp->cn_cred;
- struct thread *td = cnp->cn_thread;
- /* locals */
- int error;
- const char *nm = cnp->cn_nameptr;
- int len = cnp->cn_namelen;
-
- MARK_ENTRY(CODA_LINK_STATS);
-
- if (codadebug & CODADBGMSK(CODA_LINK)) {
- myprintf(("nb_link: vp fid: %s\n", coda_f2s(&cp->c_fid)));
- myprintf(("nb_link: tdvp fid: %s)\n",
- coda_f2s(&tdcp->c_fid)));
- }
- if (codadebug & CODADBGMSK(CODA_LINK)) {
- myprintf(("link: vp fid: %s\n", coda_f2s(&cp->c_fid)));
- myprintf(("link: tdvp fid: %s\n", coda_f2s(&tdcp->c_fid)));
- }
-
- /*
- * Check for link to/from control object.
- */
- if (IS_CTL_NAME(tdvp, nm, len) || IS_CTL_VP(vp)) {
- MARK_INT_FAIL(CODA_LINK_STATS);
- return (EACCES);
- }
- error = venus_link(vtomi(vp), &cp->c_fid, &tdcp->c_fid, nm, len,
- cred, td->td_proc);
-
- /*
- * Invalidate the parent's attr cache, the modification time has
- * changed.
- */
- VTOC(tdvp)->c_flags &= ~C_VATTR;
- VTOC(vp)->c_flags &= ~C_VATTR;
- CODADEBUG(CODA_LINK, myprintf(("in link result %d\n",error)););
- return (error);
-}
-
-int
-coda_rename(struct vop_rename_args *ap)
-{
- /* true args */
- struct vnode *fvp = ap->a_fvp;
- struct vnode *tvp = ap->a_tvp;
- struct vnode *odvp = ap->a_fdvp;
- struct cnode *odcp = VTOC(odvp);
- struct componentname *fcnp = ap->a_fcnp;
- struct vnode *ndvp = ap->a_tdvp;
- struct cnode *ndcp = VTOC(ndvp);
- struct componentname *tcnp = ap->a_tcnp;
- struct ucred *cred = fcnp->cn_cred;
- struct thread *td = fcnp->cn_thread;
- /* true args */
- int error;
- const char *fnm = fcnp->cn_nameptr;
- int flen = fcnp->cn_namelen;
- const char *tnm = tcnp->cn_nameptr;
- int tlen = tcnp->cn_namelen;
-
- MARK_ENTRY(CODA_RENAME_STATS);
-
- /*
- * Check for rename involving control object.
- */
- if (IS_CTL_NAME(odvp, fnm, flen) || IS_CTL_NAME(ndvp, tnm, tlen)) {
- MARK_INT_FAIL(CODA_RENAME_STATS);
- return (EACCES);
- }
-
- /*
- * Remove the entries for both source and target directories, which
- * should catch references to the children. Perhaps we could purge
- * less?
- */
- cache_purge(odvp);
- cache_purge(ndvp);
-
- /*
- * Invalidate parent directories as modification times have changed.
- * Invalidate access cache on renamed file as rights may have
- * changed.
- */
- VTOC(odvp)->c_flags &= ~C_VATTR;
- VTOC(ndvp)->c_flags &= ~C_VATTR;
- VTOC(fvp)->c_flags &= ~C_ACCCACHE;
- if (flen+1 > CODA_MAXNAMLEN) {
- MARK_INT_FAIL(CODA_RENAME_STATS);
- error = EINVAL;
- goto exit;
- }
- if (tlen+1 > CODA_MAXNAMLEN) {
- MARK_INT_FAIL(CODA_RENAME_STATS);
- error = EINVAL;
- goto exit;
- }
- error = venus_rename(vtomi(odvp), &odcp->c_fid, &ndcp->c_fid, fnm,
- flen, tnm, tlen, cred, td->td_proc);
-exit:
- CODADEBUG(CODA_RENAME, myprintf(("in rename result %d\n",error)););
-
- /*
- * Update namecache to reflect that the names of various objects may
- * have changed (or gone away entirely).
- */
- cache_purge(fvp);
- cache_purge(tvp);
-
- /*
- * Release parents first, then children.
- */
- vrele(odvp);
- if (tvp) {
- if (tvp == ndvp)
- vrele(ndvp);
- else
- vput(ndvp);
- vput(tvp);
- } else
- vput(ndvp);
- vrele(fvp);
- return (error);
-}
-
-int
-coda_mkdir(struct vop_mkdir_args *ap)
-{
- /* true args */
- struct vnode *dvp = ap->a_dvp;
- struct cnode *dcp = VTOC(dvp);
- struct componentname *cnp = ap->a_cnp;
- struct vattr *va = ap->a_vap;
- struct vnode **vpp = ap->a_vpp;
- struct ucred *cred = cnp->cn_cred;
- struct thread *td = cnp->cn_thread;
- /* locals */
- int error;
- const char *nm = cnp->cn_nameptr;
- int len = cnp->cn_namelen;
- struct cnode *cp;
- struct CodaFid VFid;
- struct vattr ova;
-
- MARK_ENTRY(CODA_MKDIR_STATS);
-
- /*
- * Check for mkdir of target object.
- */
- if (IS_CTL_NAME(dvp, nm, len)) {
- *vpp = (struct vnode *)0;
- MARK_INT_FAIL(CODA_MKDIR_STATS);
- return (EACCES);
- }
- if (len+1 > CODA_MAXNAMLEN) {
- *vpp = (struct vnode *)0;
- MARK_INT_FAIL(CODA_MKDIR_STATS);
- return (EACCES);
- }
- error = venus_mkdir(vtomi(dvp), &dcp->c_fid, nm, len, va, cred,
- td->td_proc, &VFid, &ova);
- if (!error) {
- if (coda_find(&VFid) != NULL)
- panic("cnode existed for newly created directory!");
- cp = make_coda_node(&VFid, dvp->v_mount, va->va_type);
- *vpp = CTOV(cp);
-
- /*
- * Enter the new vnode in the Name Cache.
- */
- if (cnp->cn_flags & MAKEENTRY)
- cache_enter(dvp, *vpp, cnp);
-
- /*
- * Update the attr cache and mark as valid.
- */
- if (coda_attr_cache) {
- VTOC(*vpp)->c_vattr = ova;
- VTOC(*vpp)->c_flags |= C_VATTR;
- }
-
- /*
- * Invalidate the parent's attr cache, the modification time
- * has changed.
- */
- VTOC(dvp)->c_flags &= ~C_VATTR;
- vn_lock(*vpp, LK_EXCLUSIVE | LK_RETRY);
- CODADEBUG( CODA_MKDIR, myprintf(("mkdir: %s result %d\n",
- coda_f2s(&VFid), error)););
- } else {
- *vpp = NULL;
- CODADEBUG(CODA_MKDIR, myprintf(("mkdir error %d\n",error)););
- }
- return (error);
-}
-
-int
-coda_rmdir(struct vop_rmdir_args *ap)
-{
- /* true args */
- struct vnode *vp = ap->a_vp;
- struct vnode *dvp = ap->a_dvp;
- struct cnode *dcp = VTOC(dvp);
- struct componentname *cnp = ap->a_cnp;
- struct ucred *cred = cnp->cn_cred;
- struct thread *td = cnp->cn_thread;
- /* true args */
- int error;
- const char *nm = cnp->cn_nameptr;
- int len = cnp->cn_namelen;
-#if 0
- struct cnode *cp;
-#endif
-
- MARK_ENTRY(CODA_RMDIR_STATS);
-
- /*
- * Check for rmdir of control object.
- */
- if (IS_CTL_NAME(dvp, nm, len)) {
- MARK_INT_FAIL(CODA_RMDIR_STATS);
- return (ENOENT);
- }
-
- /*
- * Possibly somewhat conservative purging, perhaps we just need to
- * purge vp?
- */
- cache_purge(dvp);
- cache_purge(vp);
-
- /*
- * Invalidate the parent's attr cache, the modification time has
- * changed.
- */
- dcp->c_flags &= ~C_VATTR;
- error = venus_rmdir(vtomi(dvp), &dcp->c_fid, nm, len, cred,
- td->td_proc);
- CODADEBUG(CODA_RMDIR, myprintf(("in rmdir result %d\n", error)););
- return (error);
-}
-
-int
-coda_symlink(struct vop_symlink_args *ap)
-{
- /* true args */
- struct vnode *tdvp = ap->a_dvp;
- struct cnode *tdcp = VTOC(tdvp);
- struct componentname *cnp = ap->a_cnp;
- struct vattr *tva = ap->a_vap;
- char *path = ap->a_target;
- struct ucred *cred = cnp->cn_cred;
- struct thread *td = cnp->cn_thread;
- struct vnode **vpp = ap->a_vpp;
- /* locals */
- int error;
-
- /*-
- * XXX I'm assuming the following things about coda_symlink's
- * arguments:
- * t(foo) is the new name/parent/etc being created.
- * lname is the contents of the new symlink.
- */
- char *nm = cnp->cn_nameptr;
- int len = cnp->cn_namelen;
- int plen = strlen(path);
-
- /*
- * Here's the strategy for the moment: perform the symlink, then do a
- * lookup to grab the resulting vnode. I know this requires two
- * communications with Venus for a new sybolic link, but that's the
- * way the ball bounces. I don't yet want to change the way the Mach
- * symlink works. When Mach support is deprecated, we should change
- * symlink so that the common case returns the resultant vnode in a
- * vpp argument.
- */
- MARK_ENTRY(CODA_SYMLINK_STATS);
-
- /*
- * Check for symlink of control object.
- */
- if (IS_CTL_NAME(tdvp, nm, len)) {
- MARK_INT_FAIL(CODA_SYMLINK_STATS);
- return (EACCES);
- }
- if (plen+1 > CODA_MAXPATHLEN) {
- MARK_INT_FAIL(CODA_SYMLINK_STATS);
- return (EINVAL);
- }
- if (len+1 > CODA_MAXNAMLEN) {
- MARK_INT_FAIL(CODA_SYMLINK_STATS);
- error = EINVAL;
- goto exit;
- }
- error = venus_symlink(vtomi(tdvp), &tdcp->c_fid, path, plen, nm, len,
- tva, cred, td->td_proc);
-
- /*
- * Invalidate the parent's attr cache, the modification time has
- * changed.
- */
- tdcp->c_flags &= ~C_VATTR;
- if (error == 0)
- error = VOP_LOOKUP(tdvp, vpp, cnp);
-exit:
- CODADEBUG(CODA_SYMLINK, myprintf(("in symlink result %d\n",error)););
- return (error);
-}
-
-/*
- * Read directory entries.
- *
- * XXX: This forwards the operator straight to the cache vnode using
- * VOP_READDIR(), rather than calling venus_readdir(). Why?
- */
-int
-coda_readdir(struct vop_readdir_args *ap)
-{
- /* true args */
- struct vnode *vp = ap->a_vp;
- struct cnode *cp = VTOC(vp);
- struct uio *uiop = ap->a_uio;
- struct ucred *cred = ap->a_cred;
- int *eofflag = ap->a_eofflag;
- u_long **cookies = ap->a_cookies;
- int *ncookies = ap->a_ncookies;
- struct thread *td = ap->a_uio->uio_td;
- /* upcall decl */
- /* locals */
- int error = 0;
- int opened_internally = 0;
-
- MARK_ENTRY(CODA_READDIR_STATS);
- CODADEBUG(CODA_READDIR, myprintf(("coda_readdir(%p, %zd, %lld, %d)\n",
- (void *)uiop->uio_iov->iov_base, uiop->uio_resid,
- (long long)uiop->uio_offset, uiop->uio_segflg)););
-
- /*
- * Check for readdir of control object.
- */
- if (IS_CTL_VP(vp)) {
- MARK_INT_FAIL(CODA_READDIR_STATS);
- return (ENOENT);
- }
-
- /*
- * If directory is not already open do an "internal open" on it.
- *
- * XXX: Why would this happen? For files, there's memory mapping,
- * execution, and other kernel access paths such as ktrace. For
- * directories, it is less clear.
- */
- if (cp->c_ovp == NULL) {
- opened_internally = 1;
- MARK_INT_GEN(CODA_OPEN_STATS);
- error = VOP_OPEN(vp, FREAD, cred, td, NULL);
- printf("coda_readdir: Internally Opening %p\n", vp);
- if (error) {
- printf("coda_readdir: VOP_OPEN on container failed "
- "%d\n", error);
- return (error);
- }
- }
-
- /*
- * Have UFS handle the call.
- */
- CODADEBUG(CODA_READDIR, myprintf(("indirect readdir: fid = %s, "
- "refcnt = %d\n", coda_f2s(&cp->c_fid), vp->v_usecount)););
- vn_lock(cp->c_ovp, LK_SHARED | LK_RETRY);
- error = VOP_READDIR(cp->c_ovp, uiop, cred, eofflag, ncookies,
- cookies);
- VOP_UNLOCK(cp->c_ovp, 0);
- if (error)
- MARK_INT_FAIL(CODA_READDIR_STATS);
- else
- MARK_INT_SAT(CODA_READDIR_STATS);
-
- /*
- * Do an "internal close" if necessary.
- */
- if (opened_internally) {
- MARK_INT_GEN(CODA_CLOSE_STATS);
- (void)VOP_CLOSE(vp, FREAD, cred, td);
- }
- return (error);
-}
-
-int
-coda_reclaim(struct vop_reclaim_args *ap)
-{
- /* true args */
- struct vnode *vp = ap->a_vp;
- struct cnode *cp = VTOC(vp);
- /* upcall decl */
- /* locals */
-
- /*
- * Forced unmount/flush will let vnodes with non-zero use be
- * destroyed!
- */
- ENTRY;
-
- if (IS_UNMOUNTING(cp)) {
-#ifdef DEBUG
- if (VTOC(vp)->c_ovp) {
- if (IS_UNMOUNTING(cp))
- printf("coda_reclaim: c_ovp not void: vp "
- "%p, cp %p\n", vp, cp);
- }
-#endif
- }
- cache_purge(vp);
- coda_free(VTOC(vp));
- vp->v_data = NULL;
- vp->v_object = NULL;
- return (0);
-}
-
-int
-coda_lock(struct vop_lock1_args *ap)
-{
- /* true args */
- struct vnode *vp = ap->a_vp;
- struct cnode *cp = VTOC(vp);
- /* upcall decl */
- /* locals */
-
- ENTRY;
- if ((ap->a_flags & LK_INTERLOCK) == 0) {
- VI_LOCK(vp);
- ap->a_flags |= LK_INTERLOCK;
- }
- if (coda_lockdebug)
- myprintf(("Attempting lock on %s\n", coda_f2s(&cp->c_fid)));
- return (vop_stdlock(ap));
-}
-
-int
-coda_unlock(struct vop_unlock_args *ap)
-{
- /* true args */
- struct vnode *vp = ap->a_vp;
- struct cnode *cp = VTOC(vp);
- /* upcall decl */
- /* locals */
-
- ENTRY;
- if (coda_lockdebug)
- myprintf(("Attempting unlock on %s\n",
- coda_f2s(&cp->c_fid)));
- return (vop_stdunlock(ap));
-}
-
-int
-coda_islocked(struct vop_islocked_args *ap)
-{
- /* true args */
-
- ENTRY;
- return (vop_stdislocked(ap));
-}
-
-static void
-coda_print_vattr(struct vattr *attr)
-{
- char *typestr;
-
- switch (attr->va_type) {
- case VNON:
- typestr = "VNON";
- break;
-
- case VREG:
- typestr = "VREG";
- break;
-
- case VDIR:
- typestr = "VDIR";
- break;
-
- case VBLK:
- typestr = "VBLK";
- break;
-
- case VCHR:
- typestr = "VCHR";
- break;
-
- case VLNK:
- typestr = "VLNK";
- break;
-
- case VSOCK:
- typestr = "VSCK";
- break;
-
- case VFIFO:
- typestr = "VFFO";
- break;
-
- case VBAD:
- typestr = "VBAD";
- break;
-
- default:
- typestr = "????";
- break;
- }
- myprintf(("attr: type %s mode %d uid %d gid %d fsid %d rdev %d\n",
- typestr, (int)attr->va_mode, (int)attr->va_uid,
- (int)attr->va_gid, (int)attr->va_fsid, (int)attr->va_rdev));
- myprintf((" fileid %d nlink %d size %d blocksize %d bytes %d\n",
- (int)attr->va_fileid, (int)attr->va_nlink, (int)attr->va_size,
- (int)attr->va_blocksize,(int)attr->va_bytes));
- myprintf((" gen %ld flags %ld vaflags %d\n", attr->va_gen,
- attr->va_flags, attr->va_vaflags));
- myprintf((" atime sec %d nsec %d\n", (int)attr->va_atime.tv_sec,
- (int)attr->va_atime.tv_nsec));
- myprintf((" mtime sec %d nsec %d\n", (int)attr->va_mtime.tv_sec,
- (int)attr->va_mtime.tv_nsec));
- myprintf((" ctime sec %d nsec %d\n", (int)attr->va_ctime.tv_sec,
- (int)attr->va_ctime.tv_nsec));
-}
-
-/*
- * How to print a ucred.
- */
-void
-coda_print_cred(struct ucred *cred)
-{
- int i;
-
- myprintf(("ref %d\tuid %d\n",cred->cr_ref,cred->cr_uid));
- for (i=0; i < cred->cr_ngroups; i++)
- myprintf(("\tgroup %d: (%d)\n",i,cred->cr_groups[i]));
- myprintf(("\n"));
-}
-
-/*
- * Return a vnode for the given fid. If no cnode exists for this fid create
- * one and put it in a table hashed by coda_f2i(). If the cnode for this fid
- * is already in the table return it (ref count is incremented by coda_find.
- * The cnode will be flushed from the table when coda_inactive calls
- * coda_unsave.
- */
-struct cnode *
-make_coda_node(struct CodaFid *fid, struct mount *vfsp, short type)
-{
- struct cnode *cp;
- struct vnode *vp;
- int err;
-
- /*
- * XXXRW: This really needs a moderate amount of reworking. We need
- * to properly tolerate failures of getnewvnode() and insmntque(),
- * and callers need to be able to accept an error back from
- * make_coda_node. There may also be more general issues in how we
- * handle forced unmount. Finally, if/when Coda loses its dependency
- * on Giant, the ordering of this needs rethinking.
- */
- cp = coda_find(fid);
- if (cp != NULL) {
- vref(CTOV(cp));
- return (cp);
- }
- cp = coda_alloc();
- cp->c_fid = *fid;
- err = getnewvnode("coda", vfsp, &coda_vnodeops, &vp);
- if (err)
- panic("coda: getnewvnode returned error %d\n", err);
- vp->v_data = cp;
- vp->v_type = type;
- cp->c_vnode = vp;
- coda_save(cp);
- err = insmntque(vp, vfsp);
- if (err != 0)
- printf("coda: insmntque failed: error %d", err);
- return (cp);
-}
-
-int
-coda_pathconf(struct vop_pathconf_args *ap)
-{
-
- switch (ap->a_name) {
- case _PC_NAME_MAX:
- *ap->a_retval = CODA_MAXNAMLEN;
- return (0);
-
- case _PC_PATH_MAX:
- *ap->a_retval = CODA_MAXPATHLEN;
- return (0);
-
- default:
- return (vop_stdpathconf(ap));
- }
-}
diff --git a/sys/fs/coda/coda_vnops.h b/sys/fs/coda/coda_vnops.h
deleted file mode 100644
index e43b09f..0000000
--- a/sys/fs/coda/coda_vnops.h
+++ /dev/null
@@ -1,84 +0,0 @@
-/*-
- *
- * Coda: an Experimental Distributed File System
- * Release 3.1
- *
- * Copyright (c) 1987-1998 Carnegie Mellon University
- * All Rights Reserved
- *
- * Permission to use, copy, modify and distribute this software and its
- * documentation is hereby granted, provided that both the copyright
- * notice and this permission notice appear in all copies of the
- * software, derivative works or modified versions, and any portions
- * thereof, and that both notices appear in supporting documentation, and
- * that credit is given to Carnegie Mellon University in all documents
- * and publicity pertaining to direct or indirect use of this code or its
- * derivatives.
- *
- * CODA IS AN EXPERIMENTAL SOFTWARE SYSTEM AND IS KNOWN TO HAVE BUGS,
- * SOME OF WHICH MAY HAVE SERIOUS CONSEQUENCES. CARNEGIE MELLON ALLOWS
- * FREE USE OF THIS SOFTWARE IN ITS "AS IS" CONDITION. CARNEGIE MELLON
- * DISCLAIMS ANY LIABILITY OF ANY KIND FOR ANY DAMAGES WHATSOEVER
- * RESULTING DIRECTLY OR INDIRECTLY FROM THE USE OF THIS SOFTWARE OR OF
- * ANY DERIVATIVE WORK.
- *
- * Carnegie Mellon encourages users of this software to return any
- * improvements or extensions that they make, and to grant Carnegie
- * Mellon the rights to redistribute these changes without encumbrance.
- *
- * @(#) src/sys/coda/coda_vnops.h,v 1.1.1.1 1998/08/29 21:14:52 rvb Exp $
- * $FreeBSD$
- */
-
-/*
- * Mach Operating System
- * Copyright (c) 1990 Carnegie-Mellon University
- * Copyright (c) 1989 Carnegie-Mellon University
- * All rights reserved. The CMU software License Agreement specifies
- * the terms and conditions for use and redistribution.
- */
-
-/*
- * This code was written for the Coda filesystem at Carnegie Mellon
- * University. Contributers include David Steere, James Kistler, and
- * M. Satyanarayanan.
- */
-
-#ifndef _CODA_VNOPS_H_
-#define _CODA_VNOPS_H_
-
-/*
- * FreeBSD interfaces to the vnodeops.
- */
-vop_open_t coda_open;
-vop_close_t coda_close;
-vop_read_t coda_read;
-vop_write_t coda_write;
-vop_ioctl_t coda_ioctl;
-vop_getattr_t coda_getattr;
-vop_setattr_t coda_setattr;
-vop_access_t coda_access;
-vop_readlink_t coda_readlink;
-vop_fsync_t coda_fsync;
-vop_inactive_t coda_inactive;
-vop_cachedlookup_t coda_lookup;
-vop_create_t coda_create;
-vop_remove_t coda_remove;
-vop_link_t coda_link;
-vop_rename_t coda_rename;
-vop_mkdir_t coda_mkdir;
-vop_rmdir_t coda_rmdir;
-vop_symlink_t coda_symlink;
-vop_readdir_t coda_readdir;
-vop_strategy_t coda_strategy;
-vop_reclaim_t coda_reclaim;
-vop_lock1_t coda_lock;
-vop_unlock_t coda_unlock;
-vop_islocked_t coda_islocked;
-vop_pathconf_t coda_pathconf;
-
-int coda_rdwr(struct vnode *vp, struct uio *uiop, enum uio_rw rw,
- int ioflag, struct ucred *cred, struct thread *td);
-void coda_print_cred(struct ucred *cred);
-
-#endif /* !_CODA_VNOPS_H_ */
diff --git a/sys/fs/hpfs/hpfs.h b/sys/fs/hpfs/hpfs.h
deleted file mode 100644
index fba0c45..0000000
--- a/sys/fs/hpfs/hpfs.h
+++ /dev/null
@@ -1,387 +0,0 @@
-/*-
- * Copyright (c) 1998, 1999 Semen Ustimenko (semenu@FreeBSD.org)
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * $FreeBSD$
- */
-
-/*#define HPFS_DEBUG 10*/
-typedef u_int32_t lsn_t; /* Logical Sector Number */
-typedef struct {
- lsn_t lsn1;
- lsn_t lsn2;
-} rsp_t; /* Redundant Sector Pointer */
-typedef struct {
- u_int32_t cnt;
- lsn_t lsn;
-} sptr_t; /* Storage Pointer */
-
-#define SUBLOCK 0x10
-#define SUSIZE DEV_BSIZE
-#define SPBLOCK 0x11
-#define SPSIZE DEV_BSIZE
-#define BMSIZE (4 * DEV_BSIZE)
-#define HPFS_MAXFILENAME 255
-
-#define SU_MAGIC ((u_int64_t)0xFA53E9C5F995E849)
-struct sublock {
- u_int64_t su_magic;
- u_int8_t su_hpfsver;
- u_int8_t su_fnctver;
- u_int16_t unused;
- lsn_t su_rootfno; /* Root Fnode */
- u_int32_t su_btotal; /* Total blocks */
- u_int32_t su_badbtotal; /* Bad Sectors total */
- rsp_t su_bitmap;
- rsp_t su_badbl;
- u_long su_chkdskdate;
- u_long su_dskoptdate;
- u_int32_t su_dbbsz; /* Sectors in DirBlock Band */
- lsn_t su_dbbstart;
- lsn_t su_dbbend;
- lsn_t su_dbbbitmap;
- char su_volname[0x20];
- lsn_t su_uidt; /* Ptr to User ID Table (8 sect) */
-};
-
-#define SP_MAGIC ((u_int64_t)0xFA5229C5F9911849)
-#define SP_DIRTY 0x0001
-#define SP_SPDBINUSE 0x0002
-#define SP_HFINUSE 0x0004
-#define SP_BADSECT 0x0008
-#define SP_BADBMBL 0x0010
-#define SP_FASTFRMT 0x0020
-#define SP_OLDHPFS 0x0080
-#define SP_IDASD 0x0100
-#define SP_RDASD 0x0200
-#define SP_DASD 0x0400
-#define SP_MMACTIVE 0x0800
-#define SP_DCEACLS 0x1000
-#define SP_DSADDIRTY 0x2000
-struct spblock {
- u_int64_t sp_magic;
- u_int16_t sp_flag;
- u_int8_t sp_mmcontf;
- u_int8_t unused;
- lsn_t sp_hf; /* HotFix list */
- u_int32_t sp_hfinuse; /* HotFixes in use */
- u_int32_t sp_hfavail; /* HotFixes available */
- u_int32_t sp_spdbavail; /* Spare DirBlocks available */
- u_int32_t sp_spdbmax; /* Spare DirBlocks maximum */
- lsn_t sp_cpi;
- u_int32_t sp_cpinum;
- u_int32_t sp_suchecksum;
- u_int32_t sp_spchecksum;
- u_int8_t reserved[0x3C];
- lsn_t sp_spdb[0x65];
-};
-
-#define DE_SPECIAL 0x0001
-#define DE_ACL 0x0002
-#define DE_DOWN 0x0004
-#define DE_END 0x0008
-#define DE_EALIST 0x0010
-#define DE_EPERM 0x0020
-#define DE_EXPLACL 0x0040
-#define DE_NEEDEA 0x0080
-#define DE_RONLY 0x0100
-#define DE_HIDDEN 0x0200
-#define DE_SYSTEM 0x0400
-#define DE_VOLLABEL 0x0800
-#define DE_DIR 0x1000
-#define DE_ARCHIV 0x2000
-#define DE_DOWNLSN(dep) (*(lsn_t *)((caddr_t)(dep) + (dep)->de_reclen - sizeof(lsn_t)))
-#define DE_NEXTDE(dep) ((struct hpfsdirent *)((caddr_t)(dep) + (dep)->de_reclen))
-typedef struct hpfsdirent {
- u_int16_t de_reclen;
- u_int16_t de_flag;
- lsn_t de_fnode;
- u_long de_mtime;
- u_int32_t de_size;
- u_long de_atime;
- u_long de_ctime;
- u_int32_t de_ealen;
- u_int8_t de_flexflag;
- u_int8_t de_cpid;
- u_int8_t de_namelen;
- char de_name[1];
-/* ... de_flex; */
-/* lsn_t de_down; */
-} hpfsdirent_t;
-
-#define D_BSIZE (DEV_BSIZE*4)
-#define D_MAGIC 0x77E40AAE
-#define D_DIRENT(dbp) ((hpfsdirent_t *)((caddr_t)dbp + sizeof(dirblk_t)))
-#define D_DE(dbp, deoff) ((hpfsdirent_t *)((caddr_t)dbp + sizeof(dirblk_t) + (deoff)))
-typedef struct dirblk {
- u_int32_t d_magic;
- u_int32_t d_freeoff; /* Offset of first free byte */
- u_int32_t d_chcnt; /* Change count */
- lsn_t d_parent;
- lsn_t d_self;
-} dirblk_t;
-
-/*
- * Allocation Block (ALBLK)
- */
-#define AB_HBOFFEO 0x01
-#define AB_FNPARENT 0x20
-#define AB_SUGGBSCH 0x40
-#define AB_NODES 0x80
-#define AB_ALLEAF(abp) ((alleaf_t *)((caddr_t)(abp) + sizeof(alblk_t)))
-#define AB_ALNODE(abp) ((alnode_t *)((caddr_t)(abp) + sizeof(alblk_t)))
-#define AB_FREEALP(abp) ((alleaf_t *)((caddr_t)(abp) + (abp)->ab_freeoff))
-#define AB_FREEANP(abp) ((alnode_t *)((caddr_t)(abp) + (abp)->ab_freeoff))
-#define AB_LASTALP(abp) (AB_ALLEAF(abp) + (abp)->ab_busycnt - 1)
-#define AB_LASTANP(abp) (AB_ALNODE(abp) + (abp)->ab_busycnt - 1)
-#define AB_ADDNREC(abp, sz, n) { \
- (abp)->ab_busycnt += (n); \
- (abp)->ab_freecnt -= (n); \
- (abp)->ab_freeoff += (n) * (sz); \
-}
-#define AB_RMNREC(abp, sz, n) { \
- (abp)->ab_busycnt -= (n); \
- (abp)->ab_freecnt += (n); \
- (abp)->ab_freeoff -= (n) * (sz);\
-}
-#define AB_ADDAL(abp) AB_ADDNREC(abp,sizeof(alleaf_t), 1)
-#define AB_ADDAN(abp) AB_ADDNREC(abp,sizeof(alnode_t), 1)
-#define AB_RMAL(abp) AB_RMNREC(abp,sizeof(alleaf_t), 1)
-#define AB_RMAN(abp) AB_RMNREC(abp,sizeof(alnode_t), 1)
-typedef struct alblk {
- u_int8_t ab_flag;
- u_int8_t ab_res[3];
- u_int8_t ab_freecnt;
- u_int8_t ab_busycnt;
- u_int16_t ab_freeoff;
-} alblk_t;
-
-/*
- * FNode
- */
-#define FNODESIZE DEV_BSIZE
-#define FN_MAGIC 0xF7E40AAE
-struct fnode {
- u_int32_t fn_magic;
- u_int64_t fn_readhist;
- u_int8_t fn_namelen;
- char fn_name[0xF]; /* First 15 symbols or less */
- lsn_t fn_parent;
- sptr_t fn_extacl;
- u_int16_t fn_acllen;
- u_int8_t fn_extaclflag;
- u_int8_t fn_histbitcount;
- sptr_t fn_extea;
- u_int16_t fn_ealen; /* Len of EAs in Fnode */
- u_int8_t fn_exteaflag; /* EAs in exteas */
- u_int8_t fn_flag;
- alblk_t fn_ab;
- u_int8_t fn_abd[0x60];
- u_int32_t fn_size;
- u_int32_t fn_reqea;
- u_int8_t fn_uid[0x10];
- u_int16_t fn_intoff;
- u_int8_t fn_1dasdthr;
- u_int8_t fn_dasdthr;
- u_int32_t fn_dasdlim;
- u_int32_t fn_dasdusage;
- u_int8_t fn_int[0x13c];
-};
-
-#define EA_NAME(eap) ((char *)(((caddr_t)(eap)) + sizeof(struct ea)))
-struct ea {
- u_int8_t ea_type; /* 0 - plain val */
- /* 1 - sptr to val */
- /* 3 - lsn point to AlSec, cont. val */
- u_int8_t ea_namelen;
- u_int16_t ea_vallen;
- /*u_int8_t ea_name[]; */
- /*u_int8_t ea_val[]; */
-};
-
-/*
- * Allocation Block Data (ALNODE)
- *
- * NOTE: AlNodes are used when there are too many fragments
- * to represent the data in the AlBlk
- */
-#define AN_SET(anp,nextoff,lsn) { \
- (anp)->an_nextoff = (nextoff); \
- (anp)->an_lsn = (lsn); \
-}
-typedef struct alnode {
- u_int32_t an_nextoff; /* next node offset in blocks */
- lsn_t an_lsn; /* position of AlSec structure */
-} alnode_t;
-
-/*
- * Allocaion Block Data (ALLEAF)
- *
- * NOTE: Leaves are used to point at contiguous block of data
- * (a fragment or an "extent");
- */
-#define AL_SET(alp,off,len,lsn) { \
- (alp)->al_off = (off); \
- (alp)->al_len = (len); \
- (alp)->al_lsn = (lsn); \
-}
-typedef struct alleaf {
- u_int32_t al_off; /* offset in blocks */
- u_int32_t al_len; /* len in blocks */
- lsn_t al_lsn; /* phys position */
-} alleaf_t;
-
-/*
- * Allocation Sector
- *
- * NOTE: AlSecs are not initialized before use, so they ussually
- * look full of junk. Use the AlBlk tto validate the data.
- */
-#define AS_MAGIC 0x37E40AAE
-typedef struct alsec {
- u_int32_t as_magic;
- lsn_t as_self;
- lsn_t as_parent;
- alblk_t as_ab;
- u_int8_t as_abd[0x1E0];
-} alsec_t;
-
-/*
- * Code Page structures
- */
-struct cpdblk {
- u_int16_t b_country; /* Country code */
- u_int16_t b_cpid; /* CP ID */
- u_int16_t b_dbcscnt; /* Count of DBCS ranges in CP */
- char b_upcase[0x80]; /* Case conversion table */
- u_int16_t b_dbcsrange; /* Start/End DBCS range pairs */
-
-};
-
-#define CPD_MAGIC ((u_int32_t)0x894521F7)
-struct cpdsec {
- u_int32_t d_magic;
- u_int16_t d_cpcnt; /* CP Data count */
- u_int16_t d_cpfirst; /* Index of first CP Data */
- u_int32_t d_checksum[3]; /* CP Data checksumms */
- u_int16_t d_offset[3]; /* Offsets of CP Data blocks */
- struct cpdblk d_cpdblk[3]; /* Array of CP Data Blocks */
-};
-
-struct cpiblk {
- u_int16_t b_country; /* Country code */
- u_int16_t b_cpid; /* CP ID */
- u_int32_t b_checksum;
- lsn_t b_cpdsec; /* Pointer to CP Data Sector */
- u_int16_t b_vcpid; /* Volume spec. CP ID */
- u_int16_t b_dbcscnt; /* Count of DBCS ranges in CP */
-};
-
-#define CPI_MAGIC ((u_int32_t)0x494521F7)
-struct cpisec {
- u_int32_t s_magic;
- u_int32_t s_cpicnt; /* Count of CPI's in this sector */
- u_int32_t s_cpifirst; /* Index of first CPI in this sector */
- lsn_t s_next; /* Pointer to next CPI Sector */
- struct cpiblk s_cpi[0x1F]; /* Array of CPI blocks */
-};
-
-struct hpfsmount {
- struct sublock hpm_su;
- struct spblock hpm_sp;
- struct mount * hpm_mp;
- struct vnode * hpm_devvp; /* XXX: lose this, it's in hpfsmount */
- struct g_consumer *hpm_cp;
- struct bufobj *hpm_bo;
- struct cdev *hpm_dev;
- uid_t hpm_uid;
- gid_t hpm_gid;
- mode_t hpm_mode;
-
- lsn_t * hpm_bmind;
- struct cpdblk * hpm_cpdblk; /* Array of CP Data Blocks */
- u_char hpm_u2d[0x80]; /* Unix to DOS Table*/
- u_char hpm_d2u[0x80]; /* DOS to Unix Table*/
-
- u_long hpm_bavail; /* Blocks available */
- u_long hpm_dbnum; /* Data Band number */
- u_int8_t * hpm_bitmap;
-};
-
-#define H_PARVALID 0x0002 /* parent info is valid */
-#define H_CHANGE 0x0004 /* node date was changed */
-#define H_PARCHANGE 0x0008 /* parent node date was changed */
-#define H_INVAL 0x0010 /* Invalid node */
-struct hpfsnode {
- struct mtx h_interlock;
-
- struct hpfsmount *h_hpmp;
- struct fnode h_fn;
- struct vnode * h_vp;
- struct vnode * h_devvp; /* XXX: remove, hpfsmount has it */
- struct cdev *h_dev;
- lsn_t h_no;
- uid_t h_uid;
- gid_t h_gid;
- mode_t h_mode;
- u_int32_t h_flag;
-
- /* parent dir information */
- u_long h_mtime;
- u_long h_atime;
- u_long h_ctime;
- char h_name[HPFS_MAXFILENAME+1]; /* Used to speedup dirent */
- int h_namelen; /* lookup */
-};
-
-/* This overlays the fid structure (see <sys/mount.h>) */
-struct hpfid {
- u_int16_t hpfid_len; /* Length of structure. */
- u_int16_t hpfid_pad; /* Force 32-bit alignment. */
- lsn_t hpfid_ino; /* File number (ino). */
- int32_t hpfid_gen; /* Generation number. */
-};
-
-#if defined(HPFS_DEBUG)
-#define dprintf(a) printf a
-#if HPFS_DEBUG > 1
-#define ddprintf(a) printf a
-#else
-#define ddprintf(a)
-#endif
-#else
-#define dprintf(a)
-#define ddprintf(a)
-#endif
-
-#if __FreeBSD_version >= 300000
-MALLOC_DECLARE(M_HPFSMNT);
-MALLOC_DECLARE(M_HPFSNO);
-#endif
-#define VFSTOHPFS(mp) ((struct hpfsmount *)((mp)->mnt_data))
-#define VTOHP(v) ((struct hpfsnode *)((v)->v_data))
-#define HPTOV(h) ((struct vnode *)((h)->h_vp))
-#define FID(f) (*((lsn_t *)(f)->fid_data))
-
-extern struct vop_vector hpfs_vnodeops;
diff --git a/sys/fs/hpfs/hpfs_alsubr.c b/sys/fs/hpfs/hpfs_alsubr.c
deleted file mode 100644
index 226865f..0000000
--- a/sys/fs/hpfs/hpfs_alsubr.c
+++ /dev/null
@@ -1,907 +0,0 @@
-/*-
- * Copyright (c) 1998, 1999 Semen Ustimenko (semenu@FreeBSD.org)
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * $FreeBSD$
- */
-
-#include <sys/param.h>
-#include <sys/systm.h>
-#include <sys/kernel.h>
-#include <sys/proc.h>
-#include <sys/time.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <sys/vnode.h>
-#include <sys/mount.h>
-#include <sys/namei.h>
-#include <sys/malloc.h>
-#include <sys/bio.h>
-#include <sys/buf.h>
-
-#include <fs/hpfs/hpfs.h>
-#include <fs/hpfs/hpfs_subr.h>
-
-#define AE_DONE 0 /* Nothing to change */
-#define AE_SPLIT 2 /* Split was done, ranp is valid */
-
-int hpfs_addextentr (struct hpfsmount *, lsn_t, alleaf_t *,
- alnode_t *, u_long *);
-int hpfs_allocalsec (struct hpfsmount *, lsn_t, struct buf **);
-int hpfs_alblk2alsec (struct hpfsmount *, alblk_t *, alsec_t **,
- struct buf **);
-int hpfs_splitalsec (struct hpfsmount *, alsec_t *, alsec_t **,
- struct buf **);
-int hpfs_concatalsec (struct hpfsmount *, alsec_t *, alsec_t *,
- alnode_t *);
-
-/*
- * Map file offset to disk offset. hpfsnode have to be locked.
- */
-int
-hpfs_hpbmap(hp, bn, bnp, runp)
- struct hpfsnode *hp;
- daddr_t bn;
- daddr_t *bnp;
- int *runp;
-{
- struct buf *bp;
- alblk_t * abp;
- alleaf_t *alp;
- alnode_t *anp;
- int error, i;
-
- dprintf(("hpfs_hpbmap(0x%x, 0x%x): ",hp->h_no, bn));
-
- bp = NULL;
- abp = &hp->h_fn.fn_ab;
- alp = (alleaf_t *)&hp->h_fn.fn_abd;
- anp = (alnode_t *)&hp->h_fn.fn_abd;
-
-dive:
- if (abp->ab_flag & AB_NODES) {
- for (i=0; i<abp->ab_busycnt; i++, anp++) {
- dprintf(("[0x%x,0x%x] ",anp->an_nextoff,anp->an_lsn));
- if (bn < anp->an_nextoff) {
- alsec_t *asp;
-
- dprintf(("< found | "));
-
- if (bp)
- brelse(bp);
- error = bread(hp->h_devvp, anp->an_lsn,
- DEV_BSIZE, NOCRED, &bp);
- if (error) {
- printf("hpfs_hpbmap: bread error\n");
- brelse(bp);
- return (error);
- }
-
- asp = (alsec_t *) bp->b_data;
- if (asp->as_magic != AS_MAGIC) {
- brelse(bp);
- printf("hpfs_hpbmap: "
- "MAGIC DOESN'T MATCH");
- return (EINVAL);
- }
-
- abp = &asp->as_ab;
- alp = (alleaf_t *)&asp->as_abd;
- anp = (alnode_t *)&asp->as_abd;
-
- goto dive;
- }
- }
- } else {
- for (i=0; i<abp->ab_busycnt; i++, alp++) {
- dprintf(("[0x%x,0x%x,0x%x] ",
- alp->al_off,alp->al_len,alp->al_lsn));
-
- if ((bn >= alp->al_off) &&
- (!alp->al_len || (bn < alp->al_off + alp->al_len))) {
- dprintf(("found, "));
-
- *bnp = bn - alp->al_off + alp->al_lsn;
-
- dprintf((" 0x%x ", *bnp));
-
- if (runp != NULL) {
- if (alp->al_len)
- *runp = alp->al_off - 1 +
- alp->al_len - bn;
- else
- *runp = 3; /* XXX */
-
- dprintf((" 0x%x cont", *runp));
- }
-
- if (bp)
- brelse(bp);
-
- dprintf(("\n"));
- return (0);
- }
- }
- }
-
- dprintf(("END, notfound\n"));
- if (bp)
- brelse(bp);
-
- dprintf(("hpfs_hpbmap: offset too big\n"));
-
- return (EFBIG);
-}
-
-/*
- * Find place and preinitialize AlSec structure
- * AlBlk is initialized to contain AlLeafs.
- */
-int
-hpfs_allocalsec (
- struct hpfsmount *hpmp,
- lsn_t parlsn,
- struct buf **bpp)
-{
- alsec_t * asp;
- struct buf * bp;
- lsn_t lsn;
- int error;
-
- *bpp = NULL;
-
- error = hpfs_bmfblookup(hpmp, &lsn);
- if (error) {
- printf("hpfs_allocalsec: CAN'T ALLOC SPACE FOR AlSec\n");
- return (error);
- }
-
- error = hpfs_bmmarkbusy(hpmp, lsn, 1);
- if (error)
- return (error);
-
- bp = getblk(hpmp->hpm_devvp, lsn, DEV_BSIZE, 0, 0, 0);
- clrbuf(bp);
-
- /* Fill AlSec info */
- asp = (alsec_t *) bp->b_data;
- asp->as_magic = AS_MAGIC;
- asp->as_self = lsn;
- asp->as_parent = parlsn;
-
- /* Fill AlBlk */
- asp->as_ab.ab_flag = 0;
- asp->as_ab.ab_busycnt = 0;
- asp->as_ab.ab_freecnt = 0x28;
- asp->as_ab.ab_freeoff = sizeof(alblk_t);
-
- *bpp = bp;
-
- return (0);
-}
-
-/*
- * Split AlSec structure into new allocated:
- * allocate new AlSec; then move second half of asp's entries in
- * into it; set proper flags.
- *
- * IF AlSec CONTAINS AlNodes, THEN YOU ALMOST EVERYTIME HAVE TO
- * FIX LAST AlNode in OLD AlSec (NEXTOFF TO BE 0xFFFFFFFF).
- * TOGETHER WITH FIXING ALL CHILDREN'S AlSecs (THEY HAVE GOT NEW PARENT).
- */
-int
-hpfs_splitalsec (
- struct hpfsmount *hpmp,
- alsec_t *asp,
- alsec_t **naspp,
- struct buf **nbpp)
-{
- alsec_t *nasp;
- struct buf *nbp;
- alblk_t *abp;
- alblk_t *nabp;
- int error, n1, n2, sz;
-
- error = hpfs_allocalsec(hpmp, asp->as_parent, &nbp);
- if (error)
- return (error);
-
- nasp = (alsec_t *)nbp->b_data;
- nabp = &nasp->as_ab;
- abp = &asp->as_ab;
-
- n1 = (abp->ab_busycnt + 1) / 2;
- n2 = (abp->ab_busycnt - n1);
- sz = (abp->ab_flag & AB_NODES) ? sizeof(alnode_t) : sizeof(alleaf_t);
-
- bcopy((caddr_t)abp + sizeof(alblk_t) + n1 * sz,
- (caddr_t)nabp + sizeof(alblk_t), n2 * sz);
-
- nabp->ab_flag = abp->ab_flag;
- nabp->ab_busycnt = n2;
- nabp->ab_freecnt = (0x1e0 / sz - n2);
- nabp->ab_freeoff += n2 * sz;
-
- abp->ab_busycnt -= n1;
- abp->ab_freecnt += n1;
- abp->ab_freeoff -= n1 * sz;
-
- *naspp = nasp;
- *nbpp = nbp;
-
- return (0);
-}
-
-/*
- * Try to concatenate two AlSec's
- *
- * Moves all entries from AlSec corresponding (as1p, aanp[1]) into
- * corresponding aanp[0] one. If not enought space, then return ENOSPC.
- *
- * WARNING! YOU HAVE TO FIX aanp VALUES YOURSELF LATER:
- * aanp[0].an_nextoff = aanp[1].an_nextoff;
- */
-int
-hpfs_concatalsec (
- struct hpfsmount *hpmp,
- alsec_t *as0p,
- alsec_t *as1p,
- alnode_t *aanp)
-{
- alblk_t *ab0p;
- alblk_t *ab1p;
- int sz;
-
- dprintf(("hpfs_concatalsec: AlSecs at 0x%x and 0x%x \n",
- as0p->as_self,as1p->as_self));
-
- ab0p = &as0p->as_ab;
- ab1p = &as1p->as_ab;
- sz = (ab0p->ab_flag & AB_NODES) ? sizeof(alnode_t) : sizeof(alleaf_t);
-
- if (ab0p->ab_freecnt > ab1p->ab_busycnt) {
- /*
- * Concatenate AlSecs
- */
- if (ab0p->ab_flag & AB_NODES)
- AB_LASTANP(ab0p)->an_nextoff = aanp[0].an_nextoff;
-
- bcopy (AB_ALNODE(ab1p), AB_FREEANP(ab0p),
- ab1p->ab_busycnt * sz);
-
- AB_ADDNREC(ab0p, sz, ab1p->ab_busycnt);
-
- return (0);
- } else {
- /* Not enought space to concatenate */
- return (ENOSPC);
- }
-}
-
-/*
- * Transform AlBlk structure into new allocated
- * AlSec.
- *
- * DOESN'T SET AlSec'S PARENT LSN.
- */
-int
-hpfs_alblk2alsec (
- struct hpfsmount *hpmp,
- alblk_t *abp,
- alsec_t **naspp,
- struct buf **nbpp)
-{
- alsec_t *nasp;
- alblk_t *nabp;
- struct buf *nbp;
- int error, sz;
-
- error = hpfs_allocalsec(hpmp, 0, &nbp);
- if (error)
- return (error);
-
- nasp = (alsec_t *)nbp->b_data;
- nabp = &nasp->as_ab;
-
- sz = (abp->ab_flag & AB_NODES) ? sizeof(alnode_t) : sizeof(alleaf_t);
-
- bcopy (abp, nabp, sizeof(alblk_t) + sz * abp->ab_busycnt);
-
- nabp->ab_freecnt = 0x1e0 / sz - nabp->ab_busycnt;
-
- *naspp = nasp;
- *nbpp = nbp;
-
- return (0);
-}
-
-/*
- * Allocate len blocks and concatenate them to file.
- * If we hadn't found contignous run of len blocks, concatenate
- * as much as we can, and return.
- *
- */
-int
-hpfs_addextent (
- struct hpfsmount *hpmp,
- struct hpfsnode *hp,
- u_long len)
-{
- alblk_t *rabp;
- alnode_t ranp[2];
- alleaf_t al;
- int error;
- u_long pf;
-
- /*
- * We don't know for now start lsn of block
- */
- al.al_lsn = ~0;
- al.al_len = len;
- al.al_off = (hp->h_fn.fn_size + DEV_BSIZE - 1) >> DEV_BSHIFT;
-
- rabp = &hp->h_fn.fn_ab;
-
- /* Init AlBlk if this is first extent */
- if (al.al_off == 0) {
- lsn_t nlsn;
- u_long nlen;
-
- dprintf(("hpfs_addextent: init AlBlk in root\n"));
-
- rabp->ab_busycnt = 0;
- rabp->ab_freecnt = 0x8;
- rabp->ab_freeoff = sizeof(alblk_t);
- rabp->ab_flag = 0;
-
- error = hpfs_bmlookup (hpmp, 0, hp->h_no + 1, al.al_len, &nlsn, &nlen);
- if (error)
- return (error);
-
- error = hpfs_bmmarkbusy(hpmp, nlsn, nlen);
- if (error)
- return (error);
-
- dprintf(("hpfs_addextent: new: 0x%x 0x%lx, ", nlsn, nlen));
-
- AL_SET(AB_FREEALP(rabp), al.al_off, nlen, nlsn);
- AB_ADDAL(rabp);
-
- al.al_off += nlen;
- al.al_len -= nlen;
- }
-
-retry:
- dprintf(("hpfs_addextent: AlBlk: [0x%x, 0x%x, 0x%x] need: 0x%x\n",
- rabp->ab_freecnt, rabp->ab_busycnt, rabp->ab_flag, al.al_len));
-
- while ((al.al_len) && (rabp->ab_freecnt > 0)) {
- if (rabp->ab_flag & AB_NODES) {
- alnode_t *anp;
- /*
- * This is level containing AlNodes, so try to
- * insert recursively into last entry.
- */
- anp = AB_LASTANP(rabp);
- dprintf(("hpfs_addextent: AlNode: [0x%x,0x%x] \n",
- anp->an_nextoff,anp->an_lsn));
-
- /*
- * Try to insert...
- */
- error = hpfs_addextentr (hpmp, anp->an_lsn, &al, ranp, &pf);
- if (error) {
- printf("hpfs_addextent: FAILED %d\n",error);
- return (error);
- }
-
- switch (pf) {
- case AE_SPLIT:
- dprintf(("hpfs_addextent: successful (split)\n"));
- /*
- * Then hpfs_addextentr has split tree below, now
- * we need to fix this level. Particulary:
- * fix last AlNode and add another one.
- */
-
- bcopy(ranp, AB_LASTANP(rabp), sizeof(alnode_t) * 2);
- AB_ADDAN(rabp);
- break;
-
- default:
- case AE_DONE:
- dprintf(("hpfs_addextent: successful\n"));
- break;
- }
- } else {
- alleaf_t *alp;
-
- alp = AB_LASTALP(rabp);
- dprintf(("hpfs_addextent: AlLeaf: [0x%x,0x%x,0x%x] \n",
- alp->al_off,alp->al_len,alp->al_lsn));
-
- /* Check if we trying to add in right place */
- if (alp->al_off + alp->al_len == al.al_off) {
- lsn_t nlsn;
- u_long nlen;
-
- /*
- * Search bitmap for block begining from
- * alp->al_lsn + alp->al_len and long of ralp->al_len
- */
- error = hpfs_bmlookup (hpmp, 0,
- alp->al_lsn + alp->al_len, al.al_len, &nlsn, &nlen);
- if (error)
- return (error);
-
- error = hpfs_bmmarkbusy(hpmp, nlsn, nlen);
- if (error)
- return (error);
-
- dprintf(("hpfs_addextent: new: 0x%x 0x%lx, ", nlsn, nlen));
-
- if (alp->al_lsn + alp->al_len == nlsn) {
- dprintf(("extended existed leaf\n"));
-
- alp->al_len += nlen;
- } else {
- dprintf(("created new leaf\n"));
- AL_SET(AB_FREEALP(rabp), al.al_off, nlen, nlsn);
- AB_ADDAL(rabp);
- }
- al.al_off += nlen;
- al.al_len -= nlen;
- } else {
- printf("hpfs_addextent: INTERNAL INCONSISTENCE\n");
- return (EINVAL);
- }
- }
- }
-
- /*
- * Move AlBlk contain to new AlSec (it will fit more
- * entries) if overflowed (no more free entries).
- */
- if (rabp->ab_freecnt <= 0) {
- struct buf *nbp;
- alsec_t * nrasp;
-
- dprintf(("hpfs_addextent: overflow, convt\n"));
-
- /*
- * Convert AlBlk to new AlSec, it will set
- * AB_FNPARENT also.
- */
- rabp->ab_flag |= AB_FNPARENT;
- error = hpfs_alblk2alsec (hpmp, rabp, &nrasp, &nbp);
- if (error) {
- printf("hpfs_addextent: CAN'T CONVT\n");
- return (error);
- }
- nrasp->as_parent = hp->h_no;
-
- /*
- * Scan all childrens (if exist), set new parent and
- * clean their AB_FNPARENT flag.
- */
- if (rabp->ab_flag & AB_NODES) {
- int i;
- alsec_t * asp;
- alnode_t * anp;
- struct buf * bp;
-
- anp = AB_ALNODE(rabp);
- for (i=0; i<rabp->ab_busycnt; i++) {
- error = hpfs_breadalsec(hpmp, anp->an_lsn, &bp);
- if (error)
- return (error);
-
- asp = (alsec_t *)bp->b_data;
- asp->as_ab.ab_flag &= ~AB_FNPARENT;
- asp->as_parent = nrasp->as_self;
-
- bdwrite(bp);
- anp ++;
- }
- }
-
- /* Convert AlBlk to contain AlNodes */
- rabp->ab_flag = AB_NODES;
- rabp->ab_busycnt = 0;
- rabp->ab_freecnt = 0xC;
- rabp->ab_freeoff = sizeof(alblk_t);
-
- /* Add AlNode for new allocated AlSec */
- AN_SET(AB_FREEANP(rabp), ~0, nrasp->as_self);
- AB_ADDAN(rabp);
-
- bdwrite(nbp);
- }
-
- if (al.al_len) {
- dprintf(("hpfs_addextent: root retry\n"));
- goto retry;
- }
-
- return (0);
-}
-
-/*
- * Descent down to the end of tree, then search for
- * ralp->len contignous run begining from last run's end and
- * concatenate new block! If we can't find one, then...
- */
-int
-hpfs_addextentr (
- struct hpfsmount *hpmp, /* Mix info */
- lsn_t rlsn, /* LSN containing AlSec */
- alleaf_t *ralp, /* AlLeaf to insert */
- alnode_t *ranp, /* New AlNodes' values */
- u_long *resp) /* Mix returning info */
-{
- struct buf *rbp;
- alsec_t *rasp;
- alblk_t *rabp;
- alleaf_t *alp;
- alnode_t *anp;
- int error;
- u_long pf;
- u_long wb;
-
- *resp = 0;
-
- dprintf(("hpfs_addextentr: AlSec at 0x%x\n", rlsn));
-
- error = hpfs_breadalsec(hpmp, rlsn, &rbp);
- if (error)
- return (error);
-
- rasp = (alsec_t *)rbp->b_data;
- rabp = &rasp->as_ab;
- wb = 0;
-
- dprintf(("hpfs_addextentr: AlBlk: [0x%x, 0x%x, 0x%x]\n",
- rabp->ab_freecnt, rabp->ab_busycnt, rabp->ab_flag));
-
- while ((ralp->al_len) && (rabp->ab_freecnt > 0)) {
- if (rabp->ab_flag & AB_NODES) {
- /*
- * This is level containing AlNodes, so try to
- * insert recursively into last entry.
- */
- anp = AB_LASTANP(rabp);
- dprintf(("hpfs_addextentr: AlNode: [0x%x,0x%x] \n",
- anp->an_nextoff,anp->an_lsn));
-
- /*
- * Try to insert...
- */
- error = hpfs_addextentr (hpmp, anp->an_lsn, ralp, ranp, &pf);
- if (error) {
- printf("hpfs_addextentr: FAILED %d\n",error);
- goto fail;
- }
-
- switch (pf) {
- case AE_SPLIT:
- dprintf(("hpfs_addextentr: successful (split)\n"));
- /*
- * Then hpfs_addextentr has split tree below, now
- * we need to fix this level. Particulary:
- * fix last AlNode and add another one.
- */
- bcopy(ranp, AB_LASTANP(rabp), sizeof(alnode_t) * 2);
- AB_ADDAN(rabp);
- wb = 1;
- break;
-
- default:
- case AE_DONE:
- dprintf(("hpfs_addextentr: successful\n"));
- break;
- }
- } else {
- alp = AB_LASTALP(rabp);
- dprintf(("hpfs_addextentr: AlLeaf: [0x%x,0x%x,0x%x] \n",
- alp->al_off,alp->al_len,alp->al_lsn));
-
- /* Check if we trying to add in right place */
- if (alp->al_off + alp->al_len == ralp->al_off) {
- lsn_t nlsn;
- u_long nlen;
- /*
- * Search bitmap for block begining from
- * alp->al_lsn + alp->al_len and long of ralp->al_len
- */
- error = hpfs_bmlookup (hpmp, 0,
- alp->al_lsn + alp->al_len, ralp->al_len, &nlsn, &nlen);
- if (error)
- goto fail;
-
- error = hpfs_bmmarkbusy(hpmp, nlsn, nlen);
- if (error)
- goto fail;
-
- dprintf(("hpfs_addextentr: new: 0x%x 0x%lx, ", nlsn, nlen));
-
- /*
- * If ending of existed entry fits the
- * begining of the extent being added,
- * then we add concatenate two extents.
- */
- if (alp->al_lsn + alp->al_len == nlsn) {
- dprintf(("concat\n"));
- alp->al_len += nlen;
- } else {
- dprintf(("created new leaf\n"));
- AL_SET(AB_FREEALP(rabp), ralp->al_off, nlen, nlsn);
- AB_ADDAL(rabp);
- }
-
- ralp->al_len -= nlen;
- ralp->al_off += nlen;
- } else {
- printf("hpfs_addextentr: INTERNAL INCONSISTENCE\n");
- error = (EINVAL);
- goto fail;
- }
- }
- }
-
- /*
- * Split AlBlk if overflowed.
- */
- if (rabp->ab_freecnt <= 0) {
- struct buf *nbp;
- alsec_t * nrasp;
-
- dprintf(("hpfs_addextentr: overflow, split\n"));
-
- error = hpfs_splitalsec (hpmp, rasp, &nrasp, &nbp);
- if (error) {
- printf("hpfs_addextent: CAN'T SPLIT\n");
- goto fail;
- }
-
- if (rabp->ab_flag & AB_NODES) {
- int i;
- alsec_t * asp;
- alnode_t * anp;
- struct buf * bp;
-
- ranp[0].an_nextoff =
- AB_LASTANP(&rasp->as_ab)->an_nextoff;
-
- /* We need to set left subtree's last entry
- * offset to 0xFFFFFFFF for OS/2 to be able
- * to read our files. It treats absence of
- * 0xFFFFFFFF as error.
- */
- AB_LASTANP(&rasp->as_ab)->an_nextoff = ~0;
-
- /* We need to fix new allocated AlSec's
- * children, becouse their parent has changed.
- */
- anp = AB_ALNODE(&nrasp->as_ab);
- for (i=0; i<nrasp->as_ab.ab_busycnt; i++) {
- error = hpfs_breadalsec(hpmp, anp->an_lsn, &bp);
- if (error) {
- brelse(nbp);
- goto fail;
- }
-
- asp = (alsec_t *)bp->b_data;
- asp->as_parent = nrasp->as_self;
-
- bdwrite(bp);
- anp ++;
- }
- } else {
- ranp[0].an_nextoff =
- AB_ALLEAF(&nrasp->as_ab)->al_off;
- }
-
- ranp[0].an_lsn = rasp->as_self;
- ranp[1].an_nextoff = ~0;
- ranp[1].an_lsn = nrasp->as_self;
-
- bdwrite(nbp);
-
- *resp = AE_SPLIT;
- wb = 1;
- }
-
- if (wb)
- bdwrite (rbp);
- else
- brelse(rbp);
-
- return (0);
-
-fail:
- brelse(rbp);
-
- return (error);
-}
-
-/*
- * Recursive routine walking down the b-tree and deallocating all
- * extents above bn. Returns *resp != 0 if alblk was totally
- * deallocated and may be freed. Tries to keep b-tree.
- *
- * (XXXX) NOTE! THIS ROUTINE WILL NEVER DECREMENT DEPTH OF
- * THE TREE.
- */
-int
-hpfs_truncatealblk (
- struct hpfsmount *hpmp,
- alblk_t *abp,
- lsn_t bn,
- int *resp)
-{
- int error;
- alleaf_t *alp;
- alnode_t *anp;
- alsec_t *asp;
- struct buf *bp;
-
- dprintf(("hpfs_truncatealblk: AlBlk: [0x%x,0x%x, 0x%x]\n",
- abp->ab_freecnt, abp->ab_busycnt, abp->ab_flag));
-
- if (abp->ab_flag & AB_NODES) {
- /*
- * Scan array of AlNodes backward,
- * diving in recursion if needed
- */
- anp = AB_LASTANP(abp);
-
- while (abp->ab_busycnt && (bn <= anp->an_nextoff)) {
- dprintf(("hpfs_truncatealblk: AlNode: [0x%x,0x%x] \n",
- anp->an_nextoff,anp->an_lsn));
-
- error = hpfs_breadalsec(hpmp, anp->an_lsn, &bp);
- if (error)
- return (error);
-
- asp = (alsec_t *)bp->b_data;
-
- error = hpfs_truncatealblk (hpmp,
- &asp->as_ab, bn, resp);
- if (error) {
- brelse(bp);
- return (error);
- }
-
- if (*resp) {
- brelse (bp);
-
- error = hpfs_bmmarkfree(hpmp,
- anp->an_lsn, 1);
- if (error)
- return (error);
-
- AB_RMAN(abp);
- anp --;
- } else {
- /*
- * We have deallocated some entries, some space
- * migth been freed, then try to concat two
- * last AlSec.
- */
- anp->an_nextoff = ~0;
- if (abp->ab_busycnt >= 2) {
- alsec_t *as0p;
- struct buf *b0p;
-
- error = hpfs_breadalsec(hpmp,
- (anp-1)->an_lsn, &b0p);
- if (error)
- return (error);
-
- as0p = (alsec_t *)b0p->b_data;
- error = hpfs_concatalsec(hpmp,
- as0p, asp, anp - 1);
- if (error == ENOSPC) {
- /* Not enought space */
- brelse (b0p);
- bdwrite (bp);
- } else if (error == 0) {
- /* All OK */
- (anp-1)->an_nextoff = anp->an_nextoff;
-
- bdwrite (b0p);
- brelse (bp);
-
- error = hpfs_bmmarkfree(hpmp,
- anp->an_lsn, 1);
- if (error)
- return (error);
-
- AB_RMAN(abp);
- } else {
- /* True error */
- brelse (b0p);
- brelse (bp);
- return (error);
- }
- } else {
- /* Nowhere to concatenate */
- bdwrite (bp);
- }
-
- /* There can not be any more entries
- * over greater bn, becouse last AlSec
- * wasn't freed totally. So go out.
- */
- break;
- }
- }
-
- if (abp->ab_busycnt == 0)
- *resp = 1;
- else
- *resp = 0;
- } else {
- /*
- * Scan array of AlLeafs backward,
- * free all above bn.
- */
- alp = AB_LASTALP(abp);
-
- while (abp->ab_busycnt && (bn < alp->al_off + alp->al_len)){
- dprintf(("hpfs_truncatealblk: AlLeaf: [0x%x,0x%x,0x%x] \n",
- alp->al_off,alp->al_len,alp->al_lsn));
-
- if (bn <= alp->al_off) {
- error = hpfs_bmmarkfree(hpmp, alp->al_lsn,
- alp->al_len);
- if (error)
- return (error);
-
- AB_RMAL(abp);
- alp --;
- } else if ((bn > alp->al_off) &&
- (bn < alp->al_off + alp->al_len)){
- error = hpfs_bmmarkfree(hpmp,
- alp->al_lsn + bn - alp->al_off,
- alp->al_len - bn + alp->al_off);
- if (error)
- return (error);
-
- alp->al_len = bn - alp->al_off;
-
- break;
- } else
- break;
- }
- }
-
- /* Signal parent deallocation, if need */
- if (abp->ab_busycnt == 0)
- *resp = 1;
- else
- *resp = 0;
-
- return (0);
-}
diff --git a/sys/fs/hpfs/hpfs_lookup.c b/sys/fs/hpfs/hpfs_lookup.c
deleted file mode 100644
index 88542cb..0000000
--- a/sys/fs/hpfs/hpfs_lookup.c
+++ /dev/null
@@ -1,213 +0,0 @@
-/*-
- * Copyright (c) 1998, 1999 Semen Ustimenko (semenu@FreeBSD.org)
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * $FreeBSD$
- */
-
-#include <sys/param.h>
-#include <sys/systm.h>
-#include <sys/kernel.h>
-#include <sys/proc.h>
-#include <sys/time.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <sys/vnode.h>
-#include <sys/mount.h>
-#include <sys/namei.h>
-#include <sys/malloc.h>
-#include <sys/bio.h>
-#include <sys/buf.h>
-
-#include <fs/hpfs/hpfs.h>
-#include <fs/hpfs/hpfsmount.h>
-#include <fs/hpfs/hpfs_subr.h>
-
-int hpfs_removedirent (struct hpfsmount *, lsn_t, char *, int, int *);
-
-/*
- * This routine traverse the b+ tree representing directory
- * looking for file named 'name'. Returns buf struct and hpfsdirent
- * pointer. Calling routine is supposed to brelse buffer.
- * name is supposed in Unix encodeing.
- */
-int
-hpfs_genlookupbyname (
- struct hpfsnode *dhp,
- char *name,
- int namelen,
- struct buf **bpp,
- struct hpfsdirent **depp)
-{
- struct hpfsmount *hpmp = dhp->h_hpmp;
- struct buf *bp;
- struct dirblk *dp;
- struct hpfsdirent *dep;
- lsn_t lsn;
- int error, res;
-
- dprintf(("hpfs_genlookupbyname(0x%x, %s (%d)): \n",
- dhp->h_no, name, namelen));
-
- lsn = ((alleaf_t *)dhp->h_fn.fn_abd)->al_lsn;
-dive:
- error = hpfs_breaddirblk (hpmp, lsn, &bp);
- if (error)
- return (error);
-
- dp = (struct dirblk *) bp->b_data;
- dep = D_DIRENT(dp);
-
- while(!(dep->de_flag & DE_END)) {
- dprintf(("no: 0x%x, size: %d, name: %2d:%.*s, flag: 0x%x\n",
- dep->de_fnode, dep->de_size, dep->de_namelen,
- dep->de_namelen, dep->de_name, dep->de_flag));
-
- res = hpfs_cmpfname(hpmp, name, namelen,
- dep->de_name, dep->de_namelen, dep->de_cpid);
- if (res == 0) {
- *bpp = bp;
- *depp = dep;
- return (0);
- } else if (res < 0)
- break;
-
- dep = (hpfsdirent_t *)(((caddr_t)dep) + dep->de_reclen);
- }
-
- if (dep->de_flag & DE_DOWN) {
- lsn = DE_DOWNLSN(dep);
- brelse(bp);
- goto dive;
- }
-
- brelse(bp);
-
- return (ENOENT);
-}
-
-int
-hpfs_makefnode (
- struct vnode * dvp,
- struct vnode ** vpp,
- struct componentname *cnp,
- struct vattr *vap)
-{
-#ifdef HPFS_DEBUG
- register struct hpfsnode *dhp = VTOHP(dvp);
- dprintf(("hpfs_makefnode(0x%x, %s, %ld): \n",
- dhp->h_no, cnp->cn_nameptr, cnp->cn_namelen));
-#endif
-
- return (EOPNOTSUPP);
-}
-
-int
-hpfs_removedirent (
- struct hpfsmount *hpmp,
- lsn_t lsn,
- char *name,
- int namelen,
- int *retp)
-{
-#if 0
- struct buf *bp;
- dirblk_t *dbp;
- struct hpfsdirent *dep;
- int deoff;
- int error, ret;
-
- dprintf(("hpfs_removedirent(0x%x, %.*s, %d): \n",
- lsn, namelen, name, namelen));
-
- error = hpfs_breaddirblk (hpmp, lsn, &bp);
- if (error)
- return (error);
-
- dbp = (dirblk_t *) bp->b_data;
- deoff = sizeof(dirblk_t);
- dep = DB_DIRENT(dbp);
-
- while(!(dep->de_flag & DE_END)) {
- dprintf(("no: 0x%x, size: %d, name: %2d:%.*s, flag: 0x%x\n",
- dep->de_fnode, dep->de_size, dep->de_namelen,
- dep->de_namelen, dep->de_name, dep->de_flag));
-
- res = hpfs_cmpfname(hpmp, name, namelen,
- dep->de_name, dep->de_namelen, dep->de_cpid);
- if (res == 0) {
- if (dep->de_flag & DE_DOWN) {
- /*XXXXXX*/
- } else {
- /* XXX we can copy less */
- bcopy (DE_NEXTDE(dep), dep, DB_BSIZE - deoff - dep->de_reclen);
- dbp->d_freeoff -= dep->de_reclen;
- *retp = 0;
- }
- bdwrite (bp);
- return (0);
- } else if (res < 0)
- break;
-
- deoff += dep->de_reclen;
- dep = DB_NEXTDE(dep);
- }
-
- if (dep->de_flag & DE_DOWN) {
- error = hpfs_removede (hpmp, DE_DOWNLSN(dep), name, namelen, &ret);
- if (error) {
- brelse (bp);
- return (error);
- }
- if (ret == 0) {
- if (deoff > sizeof (dirblk_t)) {
- } else if (deoff + dep->de_reclen < dbp->db_freeoff) {
- }
- }
- } else {
- error = ENOENT;
- }
-
- brelse (bp);
- return (error);
-#endif
- return (EOPNOTSUPP);
-}
-
-int
-hpfs_removefnode (
- struct vnode * dvp,
- struct vnode * vp,
- struct componentname *cnp)
-{
-#ifdef HPFS_DEBUG
- register struct hpfsnode *dhp = VTOHP(dvp);
- register struct hpfsnode *hp = VTOHP(vp);
- dprintf(("hpfs_removefnode(0x%x, 0x%x, %s, %ld): \n",
- dhp->h_no, hp->h_no, cnp->cn_nameptr, cnp->cn_namelen));
-#endif
-
-
- return (EOPNOTSUPP);
-}
diff --git a/sys/fs/hpfs/hpfs_subr.c b/sys/fs/hpfs/hpfs_subr.c
deleted file mode 100644
index c7fe94f..0000000
--- a/sys/fs/hpfs/hpfs_subr.c
+++ /dev/null
@@ -1,869 +0,0 @@
-/*-
- * Copyright (c) 1998, 1999 Semen Ustimenko (semenu@FreeBSD.org)
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * $FreeBSD$
- */
-
-#include <sys/param.h>
-#include <sys/systm.h>
-#include <sys/kernel.h>
-#include <sys/proc.h>
-#include <sys/time.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <sys/vnode.h>
-#include <sys/mount.h>
-#include <sys/namei.h>
-#include <sys/malloc.h>
-#include <sys/bio.h>
-#include <sys/buf.h>
-
-#include <fs/hpfs/hpfs.h>
-#include <fs/hpfs/hpfsmount.h>
-#include <fs/hpfs/hpfs_subr.h>
-
-u_long
-hpfs_checksum(
- u_int8_t *object,
- int size)
-{
- register int i;
- u_long csum=0L;
- for (i=0; i < size; i++) {
- csum += (u_long) *object++;
- csum = (csum << 7) + (csum >> (25));
- }
- return (csum);
-}
-
-void
-hpfs_bmdeinit(
- struct hpfsmount *hpmp)
-{
- struct buf *bp;
- int i;
-
- dprintf(("hpmp_bmdeinit: "));
-
- if (!(hpmp->hpm_mp->mnt_flag & MNT_RDONLY)) {
- /*
- * Write down BitMap.
- */
- for (i=0; i<hpmp->hpm_dbnum; i++) {
- dprintf(("[%d: 0x%x] ", i, hpmp->hpm_bmind[i]));
-
- bp = getblk(hpmp->hpm_devvp, hpmp->hpm_bmind[i],
- BMSIZE, 0, 0, 0);
- clrbuf(bp);
-
- bcopy(hpmp->hpm_bitmap + BMSIZE * i, bp->b_data,
- BMSIZE);
-
- bwrite(bp);
- }
- }
-
- free(hpmp->hpm_bitmap,M_HPFSMNT);
- free(hpmp->hpm_bmind,M_HPFSMNT);
-
- dprintf(("\n"));
-}
-
-/*
- * Initialize BitMap management, includes calculation of
- * available blocks number.
- */
-int
-hpfs_bminit(
- struct hpfsmount *hpmp)
-{
- struct buf *bp;
- int error, i, k;
- u_long dbavail;
-
- dprintf(("hpfs_bminit: "));
-
- hpmp->hpm_dbnum = (hpmp->hpm_su.su_btotal + 0x3FFF) / 0x4000;
-
- dprintf(("0x%lx data bands, ", hpmp->hpm_dbnum));
-
- hpmp->hpm_bmind = malloc(hpmp->hpm_dbnum * sizeof(lsn_t),
- M_HPFSMNT, M_WAITOK);
-
- hpmp->hpm_bitmap = malloc(hpmp->hpm_dbnum * BMSIZE,
- M_HPFSMNT, M_WAITOK);
-
- error = bread(hpmp->hpm_devvp, hpmp->hpm_su.su_bitmap.lsn1,
- ((hpmp->hpm_dbnum + 0x7F) & ~(0x7F)) << 2, NOCRED, &bp);
- if (error) {
- brelse(bp);
- free(hpmp->hpm_bitmap, M_HPFSMNT);
- free(hpmp->hpm_bmind, M_HPFSMNT);
- dprintf((" error %d\n", error));
- return (error);
- }
- bcopy(bp->b_data, hpmp->hpm_bmind, hpmp->hpm_dbnum * sizeof(lsn_t));
-
- brelse(bp);
-
- /*
- * Read in all BitMap
- */
- for (i=0; i<hpmp->hpm_dbnum; i++) {
- dprintf(("[%d: 0x%x] ", i, hpmp->hpm_bmind[i]));
-
- error = bread(hpmp->hpm_devvp, hpmp->hpm_bmind[i],
- BMSIZE, NOCRED, &bp);
- if (error) {
- brelse(bp);
- free(hpmp->hpm_bitmap, M_HPFSMNT);
- free(hpmp->hpm_bmind, M_HPFSMNT);
- dprintf((" error %d\n", error));
- return (error);
- }
- bcopy(bp->b_data, hpmp->hpm_bitmap + BMSIZE * i, BMSIZE);
-
- brelse(bp);
- }
-
- /*
- * Look througth BitMap and count free bits
- */
- dbavail = 0;
- for (i=0; i < hpmp->hpm_su.su_btotal >> 5; i++) {
- register u_int32_t mask;
- for (k=0, mask=1; k < 32; k++, mask<<=1)
- if(((u_int32_t *)hpmp->hpm_bitmap)[i] & mask)
- dbavail ++;
-
- }
- hpmp->hpm_bavail = dbavail;
-
- return (0);
-}
-
-int
-hpfs_cmpfname (
- struct hpfsmount *hpmp,
- char * uname,
- int ulen,
- char * dname,
- int dlen,
- u_int16_t cp)
-{
- register int i, res;
-
- for (i = 0; i < ulen && i < dlen; i++) {
- res = hpfs_toupper(hpmp, hpfs_u2d(hpmp, uname[i]), cp) -
- hpfs_toupper(hpmp, dname[i], cp);
- if (res)
- return res;
- }
- return (ulen - dlen);
-}
-
-int
-hpfs_cpstrnnicmp (
- struct hpfsmount *hpmp,
- char * str1,
- int str1len,
- u_int16_t str1cp,
- char * str2,
- int str2len,
- u_int16_t str2cp)
-{
- int i, res;
-
- for (i = 0; i < str1len && i < str2len; i++) {
- res = (int)hpfs_toupper(hpmp, ((u_char *)str1)[i], str1cp) -
- (int)hpfs_toupper(hpmp, ((u_char *)str2)[i], str2cp);
- if (res)
- return res;
- }
- return (str1len - str2len);
-}
-
-
-int
-hpfs_cpload (
- struct hpfsmount *hpmp,
- struct cpiblk *cpibp,
- struct cpdblk *cpdbp)
-{
- struct buf *bp;
- struct cpdsec * cpdsp;
- int error, i;
-
- error = bread(hpmp->hpm_devvp, cpibp->b_cpdsec, DEV_BSIZE, NOCRED, &bp);
- if (error) {
- brelse(bp);
- return (error);
- }
-
- cpdsp = (struct cpdsec *)bp->b_data;
-
- for (i=cpdsp->d_cpfirst; i<cpdsp->d_cpcnt; i++) {
- if (cpdsp->d_cpdblk[i].b_cpid == cpibp->b_cpid) {
- bcopy(cpdsp->d_cpdblk + i, cpdbp,
- sizeof(struct cpdblk));
-
- brelse(bp);
-
- return (0);
- }
- }
-
- brelse(bp);
-
- return (ENOENT);
-}
-
-
-/*
- * Initialize Code Page information management.
- * Load all copdepages in memory.
- */
-int
-hpfs_cpinit (
- struct mount *mp,
- struct hpfsmount *hpmp)
-{
- struct buf *bp;
- int error, i;
- lsn_t lsn;
- int cpicnt;
- struct cpisec * cpisp;
- struct cpiblk * cpibp;
- struct cpdblk * cpdbp;
-
- dprintf(("hpfs_cpinit: \n"));
-
- error = vfs_copyopt(mp->mnt_optnew, "d2u", hpmp->hpm_d2u,
- sizeof hpmp->hpm_d2u);
- if (error == ENOENT)
- for (i=0x0; i<0x80;i++)
- hpmp->hpm_d2u[i] = i + 0x80;
- else if (error)
- return (error);
-
- error = vfs_copyopt(mp->mnt_optnew, "u2d", hpmp->hpm_u2d,
- sizeof hpmp->hpm_u2d);
- if (error == ENOENT)
- for (i=0x0; i<0x80;i++)
- hpmp->hpm_u2d[i] = i + 0x80;
- else if (error)
- return (error);
-
- cpicnt = hpmp->hpm_sp.sp_cpinum;
-
- hpmp->hpm_cpdblk = malloc(cpicnt * sizeof(struct cpdblk),
- M_HPFSMNT, M_WAITOK);
-
- cpdbp = hpmp->hpm_cpdblk;
- lsn = hpmp->hpm_sp.sp_cpi;
-
- while (cpicnt > 0) {
- error = bread(hpmp->hpm_devvp, lsn, DEV_BSIZE, NOCRED, &bp);
- if (error) {
- brelse(bp);
- return (error);
- }
-
- cpisp = (struct cpisec *)bp->b_data;
-
- cpibp = cpisp->s_cpi;
- for (i=0; i<cpisp->s_cpicnt; i++, cpicnt --, cpdbp++, cpibp++) {
- dprintf(("hpfs_cpinit: Country: %d, CP: %d (%d)\n",
- cpibp->b_country, cpibp->b_cpid,
- cpibp->b_vcpid));
-
- error = hpfs_cpload(hpmp, cpibp, cpdbp);
- if (error) {
- brelse(bp);
- return (error);
- }
- }
- lsn = cpisp->s_next;
- brelse(bp);
- }
-
- return (0);
-}
-
-int
-hpfs_cpdeinit (
- struct hpfsmount *hpmp)
-{
- dprintf(("hpmp_cpdeinit: "));
- free(hpmp->hpm_cpdblk,M_HPFSMNT);
- return (0);
-}
-
-/*
- * Lookup for a run of blocks.
- */
-int
-hpfs_bmlookup (
- struct hpfsmount *hpmp,
- u_long flags, /* 1 means we want right len blocks in run, not less */
- lsn_t lsn, /* We want near this one */
- u_long len, /* We want such long */
- lsn_t *lsnp, /* We got here */
- u_long *lenp) /* We got this long */
-{
- u_int32_t * bitmap;
- register u_int32_t mask;
- int i,k;
- int cband, vcband;
- u_int bandsz;
- int count;
-
- dprintf(("hpfs_bmlookup: lsn: 0x%x, len 0x%lx | Step1\n", lsn, len));
-
- if (lsn > hpmp->hpm_su.su_btotal) {
- printf("hpfs_bmlookup: OUT OF VOLUME\n");
- return ENOSPC;
- }
- if (len > hpmp->hpm_bavail) {
- printf("hpfs_bmlookup: OUT OF SPACE\n");
- return ENOSPC;
- }
- i = lsn >> 5;
- k = lsn & 0x1F;
- mask = 1 << k;
- bitmap = (u_int32_t *)hpmp->hpm_bitmap + i;
-
- if (*bitmap & mask) {
- *lsnp = lsn;
- *lenp = 0;
- for (; k < 32; k++, mask<<=1) {
- if (*bitmap & mask)
- (*lenp) ++;
- else {
- if (flags & 1)
- goto step2;
- else
- return (0);
- }
-
- if (*lenp == len)
- return (0);
- }
-
- bitmap++;
- i++;
- for (; i < hpmp->hpm_su.su_btotal >> 5; i++, bitmap++) {
- for (k=0, mask=1; k < 32; k++, mask<<=1) {
- if (*bitmap & mask)
- (*lenp) ++;
- else {
- if (flags & 1)
- goto step2;
- else
- return (0);
- }
-
- if (*lenp == len)
- return (0);
- }
- }
- return (0);
- }
-
-step2:
- /*
- * Lookup all bands begining from cband, lookup for first block
- */
- cband = (lsn >> 14);
- dprintf(("hpfs_bmlookup: Step2: band 0x%x (0x%lx)\n",
- cband, hpmp->hpm_dbnum));
- for (vcband = 0; vcband < hpmp->hpm_dbnum; vcband ++, cband++) {
- cband = cband % hpmp->hpm_dbnum;
- bandsz = min (hpmp->hpm_su.su_btotal - (cband << 14), 0x4000);
- dprintf(("hpfs_bmlookup: band: %d, sz: 0x%x\n", cband, bandsz));
-
- bitmap = (u_int32_t *)hpmp->hpm_bitmap + (cband << 9);
- *lsnp = cband << 14;
- *lenp = 0;
- count = 0;
- for (i=0; i < bandsz >> 5; i++, bitmap++) {
- for (k=0, mask=1; k < 32; k++, mask<<=1) {
- if (*bitmap & mask) {
- if (count) {
- (*lenp) ++;
- } else {
- count = 1;
- *lsnp = (cband << 14) + (i << 5) + k;
- *lenp = 1;
- }
- } else {
- if ((*lenp) && !(flags & 1)) {
- return (0);
- } else {
- count = 0;
- }
- }
-
- if (*lenp == len)
- return (0);
- }
- }
- if (cband == hpmp->hpm_dbnum - 1) {
- if ((*lenp) && !(flags & 1)) {
- return (0);
- } else {
- count = 0;
- }
- }
- }
-
- return (ENOSPC);
-}
-
-/*
- * Lookup a single free block. XXX Need locking on BitMap operations
- * VERY STUPID ROUTINE!!!
- */
-int
-hpfs_bmfblookup (
- struct hpfsmount *hpmp,
- lsn_t *lp)
-{
- u_int32_t * bitmap;
- int i,k;
-
- dprintf(("hpfs_bmfblookup: "));
-
- bitmap = (u_int32_t *)hpmp->hpm_bitmap;
- for (i=0; i < hpmp->hpm_su.su_btotal >> 5; i++, bitmap++) {
- k = ffs(*bitmap);
- if (k) {
- *lp = (i << 5) + k - 1;
- dprintf((" found: 0x%x\n",*lp));
- return (0);
- }
- }
-
- return (ENOSPC);
-}
-
-/*
- * Mark contignous block of blocks.
- */
-int
-hpfs_bmmark (
- struct hpfsmount *hpmp,
- lsn_t bn,
- u_long bl,
- int state)
-{
- u_int32_t * bitmap;
- int i, didprint = 0;
-
- dprintf(("hpfs_bmmark(0x%x, 0x%lx, %d): \n",bn,bl, state));
-
- if ((bn > hpmp->hpm_su.su_btotal) || (bn+bl > hpmp->hpm_su.su_btotal)) {
- printf("hpfs_bmmark: MARKING OUT OF VOLUME\n");
- return 0;
- }
- bitmap = (u_int32_t *)hpmp->hpm_bitmap;
- bitmap += bn >> 5;
-
- while (bl > 0) {
- for (i = bn & 0x1F; (i < 0x20) && (bl > 0) ; i++, bl--) {
- if (state) {
- if ( *bitmap & (1 << i)) {
- if (!didprint) {
- printf("hpfs_bmmark: ALREADY FREE\n");
- didprint = 1;
- }
- } else
- hpmp->hpm_bavail++;
-
- *bitmap |= (1 << i);
- } else {
- if ((~(*bitmap)) & (1 << i)) {
- if (!didprint) {
- printf("hpfs_bmmark: ALREADY BUSY\n");
- didprint = 1;
- }
- } else
- hpmp->hpm_bavail--;
-
- *bitmap &= ~(1 << i);
- }
- }
- bn = 0;
- bitmap++;
- }
-
- return (0);
-}
-
-
-int
-hpfs_validateparent (
- struct hpfsnode *hp)
-{
- struct hpfsnode *dhp;
- struct vnode *dvp;
- struct hpfsmount *hpmp = hp->h_hpmp;
- struct buf *bp;
- struct dirblk *dp;
- struct hpfsdirent *dep;
- lsn_t lsn, olsn;
- int level, error;
-
- dprintf(("hpfs_validatetimes(0x%x): [parent: 0x%x] ",
- hp->h_no, hp->h_fn.fn_parent));
-
- if (hp->h_no == hp->h_fn.fn_parent) {
- dhp = hp;
- } else {
- error = VFS_VGET(hpmp->hpm_mp, hp->h_fn.fn_parent,
- LK_EXCLUSIVE, &dvp);
- if (error)
- return (error);
- dhp = VTOHP(dvp);
- }
-
- lsn = ((alleaf_t *)dhp->h_fn.fn_abd)->al_lsn;
-
- olsn = 0;
- level = 1;
- bp = NULL;
-
-dive:
- dprintf(("[dive 0x%x] ", lsn));
- if (bp != NULL)
- brelse(bp);
- error = bread(dhp->h_devvp, lsn, D_BSIZE, NOCRED, &bp);
- if (error)
- goto failed;
-
- dp = (struct dirblk *) bp->b_data;
- if (dp->d_magic != D_MAGIC) {
- printf("hpfs_validatetimes: magic doesn't match\n");
- error = EINVAL;
- goto failed;
- }
-
- dep = D_DIRENT(dp);
-
- if (olsn) {
- dprintf(("[restore 0x%x] ", olsn));
-
- while(!(dep->de_flag & DE_END) ) {
- if((dep->de_flag & DE_DOWN) &&
- (olsn == DE_DOWNLSN(dep)))
- break;
- dep = (hpfsdirent_t *)((caddr_t)dep + dep->de_reclen);
- }
-
- if((dep->de_flag & DE_DOWN) && (olsn == DE_DOWNLSN(dep))) {
- if (dep->de_flag & DE_END)
- goto blockdone;
-
- if (hp->h_no == dep->de_fnode) {
- dprintf(("[found] "));
- goto readdone;
- }
-
- dep = (hpfsdirent_t *)((caddr_t)dep + dep->de_reclen);
- } else {
- printf("hpfs_validatetimes: ERROR! oLSN not found\n");
- error = EINVAL;
- goto failed;
- }
- }
-
- olsn = 0;
-
- while(!(dep->de_flag & DE_END)) {
- if(dep->de_flag & DE_DOWN) {
- lsn = DE_DOWNLSN(dep);
- level++;
- goto dive;
- }
-
- if (hp->h_no == dep->de_fnode) {
- dprintf(("[found] "));
- goto readdone;
- }
-
- dep = (hpfsdirent_t *)((caddr_t)dep + dep->de_reclen);
- }
-
- if(dep->de_flag & DE_DOWN) {
- dprintf(("[enddive] "));
- lsn = DE_DOWNLSN(dep);
- level++;
- goto dive;
- }
-
-blockdone:
- dprintf(("[EOB] "));
- olsn = lsn;
- lsn = dp->d_parent;
- level--;
- dprintf(("[level %d] ", level));
- if (level > 0)
- goto dive; /* undive really */
-
- goto failed;
-
-readdone:
- bcopy(dep->de_name,hp->h_name,dep->de_namelen);
- hp->h_name[dep->de_namelen] = '\0';
- hp->h_namelen = dep->de_namelen;
- hp->h_ctime = dep->de_ctime;
- hp->h_atime = dep->de_atime;
- hp->h_mtime = dep->de_mtime;
- hp->h_flag |= H_PARVALID;
-
- dprintf(("[readdone]"));
-
-failed:
- dprintf(("\n"));
- if (bp != NULL)
- brelse(bp);
- if (hp != dhp)
- vput(dvp);
-
- return (error);
-}
-
-struct timespec
-hpfstimetounix (
- u_long hptime)
-{
- struct timespec t;
-
- t.tv_nsec = 0;
- t.tv_sec = hptime;
-
- return t;
-}
-
-/*
- * Write down changes done to parent dir, these are only times for now.
- * hpfsnode have to be locked.
- */
-int
-hpfs_updateparent (
- struct hpfsnode *hp)
-{
- struct hpfsnode *dhp;
- struct vnode *dvp;
- struct hpfsdirent *dep;
- struct buf * bp;
- int error;
-
- dprintf(("hpfs_updateparent(0x%x): \n", hp->h_no));
-
- if (!(hp->h_flag & H_PARCHANGE))
- return (0);
-
- if (!(hp->h_flag & H_PARVALID)) {
- error = hpfs_validateparent (hp);
- if (error)
- return (error);
- }
-
- if (hp->h_no == hp->h_fn.fn_parent) {
- dhp = hp;
- } else {
- error = VFS_VGET(hp->h_hpmp->hpm_mp, hp->h_fn.fn_parent,
- LK_EXCLUSIVE, &dvp);
- if (error)
- return (error);
- dhp = VTOHP(dvp);
- }
-
- error = hpfs_genlookupbyname (dhp, hp->h_name, hp->h_namelen,
- &bp, &dep);
- if (error) {
- goto failed;
- }
-
- dep->de_atime = hp->h_atime;
- dep->de_mtime = hp->h_mtime;
- dep->de_size = hp->h_fn.fn_size;
-
- bdwrite (bp);
-
- hp->h_flag &= ~H_PARCHANGE;
-
- error = 0;
-failed:
- if (hp != dhp)
- vput(dvp);
-
- return (0);
-}
-
-/*
- * Write down on disk changes done to fnode. hpfsnode have to be locked.
- */
-int
-hpfs_update (
- struct hpfsnode *hp)
-{
- struct buf * bp;
-
- dprintf(("hpfs_update(0x%x): \n", hp->h_no));
-
- if (!(hp->h_flag & H_CHANGE))
- return (0);
-
- bp = getblk(hp->h_devvp, hp->h_no, FNODESIZE, 0, 0, 0);
- clrbuf(bp);
-
- bcopy (&hp->h_fn, bp->b_data, sizeof(struct fnode));
- bdwrite (bp);
-
- hp->h_flag &= ~H_CHANGE;
-
- if (hp->h_flag & H_PARCHANGE)
- return (hpfs_updateparent(hp));
-
- return (0);
-}
-
-/*
- * Truncate file to specifed size. hpfsnode have to be locked.
- */
-int
-hpfs_truncate (
- struct hpfsnode *hp,
- u_long size)
-{
- struct hpfsmount *hpmp = hp->h_hpmp;
- lsn_t newblen, oldblen;
- int error, pf;
-
- dprintf(("hpfs_truncate(0x%x, 0x%x -> 0x%lx): ",
- hp->h_no, hp->h_fn.fn_size, size));
-
- newblen = (size + DEV_BSIZE - 1) >> DEV_BSHIFT;
- oldblen = (hp->h_fn.fn_size + DEV_BSIZE - 1) >> DEV_BSHIFT;
-
- dprintf(("blen: 0x%x -> 0x%x\n", oldblen, newblen));
-
- error = hpfs_truncatealblk (hpmp, &hp->h_fn.fn_ab, newblen, &pf);
- if (error)
- return (error);
- if (pf) {
- hp->h_fn.fn_ab.ab_flag = 0;
- hp->h_fn.fn_ab.ab_freecnt = 0x8;
- hp->h_fn.fn_ab.ab_busycnt = 0x0;
- hp->h_fn.fn_ab.ab_freeoff = sizeof(alblk_t);
- }
-
- hp->h_fn.fn_size = size;
-
- hp->h_flag |= (H_CHANGE | H_PARCHANGE);
-
- dprintf(("hpfs_truncate: successful\n"));
-
- return (0);
-}
-
-/*
- * Enlarge file to specifed size. hpfsnode have to be locked.
- */
-int
-hpfs_extend (
- struct hpfsnode *hp,
- u_long size)
-{
- struct hpfsmount *hpmp = hp->h_hpmp;
- lsn_t newblen, oldblen;
- int error;
-
- dprintf(("hpfs_extend(0x%x, 0x%x -> 0x%lx): ",
- hp->h_no, hp->h_fn.fn_size, size));
-
- if (hpmp->hpm_bavail < 0x10)
- return (ENOSPC);
-
- newblen = (size + DEV_BSIZE - 1) >> DEV_BSHIFT;
- oldblen = (hp->h_fn.fn_size + DEV_BSIZE - 1) >> DEV_BSHIFT;
-
- dprintf(("blen: 0x%x -> 0x%x\n", oldblen, newblen));
-
- error = hpfs_addextent(hpmp, hp, newblen - oldblen);
- if (error) {
- printf("hpfs_extend: FAILED TO ADD EXTENT %d\n", error);
- return (error);
- }
-
- hp->h_fn.fn_size = size;
-
- hp->h_flag |= (H_CHANGE | H_PARCHANGE);
-
- dprintf(("hpfs_extend: successful\n"));
-
- return (0);
-}
-
-/*
- * Read AlSec structure, and check if magic is valid.
- * You don't need to brelse buf on error.
- */
-int
-hpfs_breadstruct (
- struct hpfsmount *hpmp,
- lsn_t lsn,
- u_int len,
- u_int32_t magic,
- struct buf **bpp)
-{
- struct buf *bp;
- u_int32_t *mp;
- int error;
-
- dprintf(("hpfs_breadstruct: reading at 0x%x\n", lsn));
-
- *bpp = NULL;
-
- error = bread(hpmp->hpm_devvp, lsn, len, NOCRED, &bp);
- if (error) {
- brelse(bp);
- return (error);
- }
- mp = (u_int32_t *) bp->b_data;
- if (*mp != magic) {
- brelse(bp);
- printf("hpfs_breadstruct: MAGIC DOESN'T MATCH (0x%08x != 0x%08x)\n",
- *mp, magic);
- return (EINVAL);
- }
-
- *bpp = bp;
-
- return (0);
-}
-
diff --git a/sys/fs/hpfs/hpfs_subr.h b/sys/fs/hpfs/hpfs_subr.h
deleted file mode 100644
index e8a24b4..0000000
--- a/sys/fs/hpfs/hpfs_subr.h
+++ /dev/null
@@ -1,89 +0,0 @@
-/*-
- * Copyright (c) 1998, 1999 Semen Ustimenko (semenu@FreeBSD.org)
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * $FreeBSD$
- */
-
-#define hpfs_bmmarkfree(hpmp, bn,bl) hpfs_bmmark(hpmp, bn, bl, 1)
-#define hpfs_bmmarkbusy(hpmp, bn,bl) hpfs_bmmark(hpmp, bn, bl, 0)
-
-u_long hpfs_checksum (u_int8_t *, int);
-
-int hpfs_bminit (struct hpfsmount *);
-void hpfs_bmdeinit (struct hpfsmount *);
-int hpfs_bmfblookup (struct hpfsmount *, lsn_t *);
-int hpfs_bmmark (struct hpfsmount *, lsn_t, u_long, int);
-int hpfs_bmlookup (struct hpfsmount *, u_long, lsn_t, u_long,
- lsn_t *, u_long *);
-
-struct hpfs_args;
-int hpfs_cpinit (struct mount *, struct hpfsmount *);
-int hpfs_cpdeinit (struct hpfsmount *);
-int hpfs_cpload (struct hpfsmount *, struct cpiblk *,
- struct cpdblk *);
-int hpfs_cpstrnnicmp (struct hpfsmount *, char *, int, u_int16_t,
- char *, int, u_int16_t);
-int hpfs_cmpfname (struct hpfsmount *, char *, int,
- char *, int, u_int16_t);
-
-/* XXX Need unsigned conversion? */
-#define hpfs_u2d(hpmp, c) ((((u_char)(c))&0x80)?(hpmp->hpm_u2d[((u_char)(c))&0x7F]):((u_char)(c)))
-#define hpfs_d2u(hpmp, c) ((((u_char)(c))&0x80)?(hpmp->hpm_d2u[((u_char)(c))&0x7F]):((u_char)(c)))
-#define hpfs_toupper(hpmp, c, cp) ((((u_char)(c))&0x80) ? ((u_char)((hpmp)->hpm_cpdblk[(cp)].b_upcase[((u_char)(c))&0x7F])) : ((((u_char)(c)) >= 'a' && ((u_char)(c)) <='z')?(((u_char)(c))-'a'+'A'):((u_char)(c))))
-
-
-int hpfs_truncate (struct hpfsnode *, u_long);
-int hpfs_extend (struct hpfsnode *, u_long);
-
-int hpfs_updateparent (struct hpfsnode *);
-int hpfs_update (struct hpfsnode *);
-
-int hpfs_validateparent (struct hpfsnode *);
-struct timespec hpfstimetounix (u_long);
-int hpfs_genlookupbyname (struct hpfsnode *, char *, int,
- struct buf **, struct hpfsdirent **);
-
-int hpfs_makefnode (struct vnode *, struct vnode **,
- struct componentname *, struct vattr *);
-int hpfs_removefnode (struct vnode *, struct vnode *,
- struct componentname *);
-
-int hpfs_breadstruct (struct hpfsmount *, lsn_t, u_int, u_int32_t,
- struct buf **);
-#define hpfs_breadalsec(hpmp, lsn, bpp) \
- hpfs_breadstruct(hpmp, lsn, DEV_BSIZE, AS_MAGIC, bpp)
-#define hpfs_breaddirblk(hpmp, lsn, bpp) \
- hpfs_breadstruct(hpmp, lsn, D_BSIZE, D_MAGIC, bpp)
-
-#if 0
-#define hpfs_hplock(hp, p) \
- lockmgr(&(hp)->h_intlock, LK_EXCLUSIVE, (p))
-#define hpfs_hpunlock(hp, p) \
- lockmgr(&(hp)->h_intlock, LK_RELEASE, (p))
-#endif
-
-int hpfs_hpbmap (struct hpfsnode *, daddr_t, daddr_t *, int *);
-int hpfs_truncatealblk (struct hpfsmount *, alblk_t *, lsn_t,int *);
-int hpfs_addextent (struct hpfsmount *, struct hpfsnode *, u_long);
diff --git a/sys/fs/hpfs/hpfs_vfsops.c b/sys/fs/hpfs/hpfs_vfsops.c
deleted file mode 100644
index edc37b2..0000000
--- a/sys/fs/hpfs/hpfs_vfsops.c
+++ /dev/null
@@ -1,545 +0,0 @@
-/*-
- * Copyright (c) 1998, 1999 Semen Ustimenko (semenu@FreeBSD.org)
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * $FreeBSD$
- */
-
-
-#include <sys/param.h>
-#include <sys/systm.h>
-#include <sys/namei.h>
-#include <sys/conf.h>
-#include <sys/proc.h>
-#include <sys/kernel.h>
-#include <sys/vnode.h>
-#include <sys/mount.h>
-#include <sys/bio.h>
-#include <sys/buf.h>
-#include <sys/fcntl.h>
-#include <sys/malloc.h>
-
-#include <geom/geom.h>
-#include <geom/geom_vfs.h>
-
-#include <vm/vm.h>
-#include <vm/vm_param.h>
-#include <vm/vm_page.h>
-#include <vm/vm_object.h>
-#include <vm/vm_extern.h>
-
-#include <fs/hpfs/hpfs.h>
-#include <fs/hpfs/hpfsmount.h>
-#include <fs/hpfs/hpfs_subr.h>
-
-MALLOC_DEFINE(M_HPFSMNT, "hpfs_mount", "HPFS mount structure");
-MALLOC_DEFINE(M_HPFSNO, "hpfs_node", "HPFS node structure");
-
-struct sockaddr;
-
-static int hpfs_mountfs(register struct vnode *, struct mount *,
- struct thread *);
-
-static vfs_fhtovp_t hpfs_fhtovp;
-static vfs_vget_t hpfs_vget;
-static vfs_cmount_t hpfs_cmount;
-static vfs_mount_t hpfs_mount;
-static vfs_root_t hpfs_root;
-static vfs_statfs_t hpfs_statfs;
-static vfs_unmount_t hpfs_unmount;
-
-static int
-hpfs_cmount (
- struct mntarg *ma,
- void *data,
- uint64_t flags)
-{
- struct hpfs_args args;
- struct export_args exp;
- int error;
-
- error = copyin(data, (caddr_t)&args, sizeof (struct hpfs_args));
- if (error)
- return (error);
- vfs_oexport_conv(&args.export, &exp);
-
- ma = mount_argsu(ma, "from", args.fspec, MAXPATHLEN);
- ma = mount_arg(ma, "export", &exp, sizeof(exp));
- ma = mount_argf(ma, "uid", "%d", args.uid);
- ma = mount_argf(ma, "gid", "%d", args.gid);
- ma = mount_argf(ma, "mode", "%d", args.mode);
- if (args.flags & HPFSMNT_TABLES) {
- ma = mount_arg(ma, "d2u", args.d2u, sizeof args.d2u);
- ma = mount_arg(ma, "u2d", args.u2d, sizeof args.u2d);
- }
-
- error = kernel_mount(ma, flags);
-
- return (error);
-}
-
-static const char *hpfs_opts[] = {
- "from", "export", "uid", "gid", "mode", "d2u", "u2d", NULL
-};
-
-static int
-hpfs_mount (struct mount *mp)
-{
- int err = 0, error;
- struct vnode *devvp;
- struct thread *td;
- struct nameidata ndp;
- struct export_args export;
- char *from;
-
- td = curthread;
- dprintf(("hpfs_omount():\n"));
- /*
- ***
- * Mounting non-root filesystem or updating a filesystem
- ***
- */
- if (vfs_filteropt(mp->mnt_optnew, hpfs_opts))
- return (EINVAL);
-
- from = vfs_getopts(mp->mnt_optnew, "from", &error);
- if (error)
- return (error);
-
- /*
- * If updating, check whether changing from read-only to
- * read/write; if there is no device name, that's all we do.
- */
- if (mp->mnt_flag & MNT_UPDATE) {
- dprintf(("hpfs_omount: MNT_UPDATE: "));
-
- if (from == NULL) {
- error = vfs_copyopt(mp->mnt_optnew, "export",
- &export, sizeof export);
- if (error)
- return (error);
- dprintf(("export 0x%x\n",args.export.ex_flags));
- err = vfs_export(mp, &export);
- if (err) {
- printf("hpfs_omount: vfs_export failed %d\n",
- err);
- }
- goto success;
- } else {
- dprintf(("name [FAILED]\n"));
- err = EINVAL;
- goto success;
- }
- dprintf(("\n"));
- }
-
- /*
- * Not an update, or updating the name: look up the name
- * and verify that it refers to a sensible block device.
- */
- NDINIT(&ndp, LOOKUP, FOLLOW | LOCKLEAF, UIO_SYSSPACE, from, td);
- err = namei(&ndp);
- if (err) {
- /* can't get devvp!*/
- goto error_1;
- }
-
- devvp = ndp.ni_vp;
-
- if (!vn_isdisk(devvp, &err)) {
- vput(devvp);
- return (err);
- }
-
- /*
- ********************
- * NEW MOUNT
- ********************
- */
-
- /*
- * Since this is a new mount, we want the names for
- * the device and the mount point copied in. If an
- * error occurs, the mountpoint is discarded by the
- * upper level code. Note that vfs_omount() handles
- * copying the mountpoint f_mntonname for us, so we
- * don't have to do it here unless we want to set it
- * to something other than "path" for some rason.
- */
- /* Save "mounted from" info for mount point (NULL pad)*/
- vfs_mountedfrom(mp, from);
-
- err = hpfs_mountfs(devvp, mp, td);
- if (err) {
- vrele(devvp);
- goto error_1;
- }
-
- goto success;
-
-error_1: /* no state to back out*/
- /* XXX: Missing NDFREE(&ndp, ...) */
-
-success:
- return( err);
-}
-
-/*
- * Common code for mount and mountroot
- */
-int
-hpfs_mountfs(devvp, mp, td)
- register struct vnode *devvp;
- struct mount *mp;
- struct thread *td;
-{
- int error, ronly, v;
- struct sublock *sup;
- struct spblock *spp;
- struct hpfsmount *hpmp;
- struct buf *bp = NULL;
- struct vnode *vp;
- struct cdev *dev = devvp->v_rdev;
- struct g_consumer *cp;
- struct bufobj *bo;
-
- if (mp->mnt_flag & MNT_ROOTFS)
- return (EOPNOTSUPP);
- dprintf(("hpfs_mountfs():\n"));
- ronly = (mp->mnt_flag & MNT_RDONLY) != 0;
- /* XXX: use VOP_ACCESS to check FS perms */
- DROP_GIANT();
- g_topology_lock();
- error = g_vfs_open(devvp, &cp, "hpfs", ronly ? 0 : 1);
- g_topology_unlock();
- PICKUP_GIANT();
- VOP_UNLOCK(devvp, 0);
- if (error)
- return (error);
-
- bo = &devvp->v_bufobj;
- bo->bo_private = cp;
- bo->bo_ops = g_vfs_bufops;
-
- /*
- * Do actual mount
- */
- hpmp = malloc(sizeof(struct hpfsmount), M_HPFSMNT, M_WAITOK | M_ZERO);
-
- hpmp->hpm_cp = cp;
- hpmp->hpm_bo = bo;
-
- /* Read in SuperBlock */
- error = bread(devvp, SUBLOCK, SUSIZE, NOCRED, &bp);
- if (error)
- goto failed;
- bcopy(bp->b_data, &hpmp->hpm_su, sizeof(struct sublock));
- brelse(bp); bp = NULL;
-
- /* Read in SpareBlock */
- error = bread(devvp, SPBLOCK, SPSIZE, NOCRED, &bp);
- if (error)
- goto failed;
- bcopy(bp->b_data, &hpmp->hpm_sp, sizeof(struct spblock));
- brelse(bp); bp = NULL;
-
- sup = &hpmp->hpm_su;
- spp = &hpmp->hpm_sp;
-
- /* Check magic */
- if (sup->su_magic != SU_MAGIC) {
- printf("hpfs_mountfs: SuperBlock MAGIC DOESN'T MATCH\n");
- error = EINVAL;
- goto failed;
- }
- if (spp->sp_magic != SP_MAGIC) {
- printf("hpfs_mountfs: SpareBlock MAGIC DOESN'T MATCH\n");
- error = EINVAL;
- goto failed;
- }
-
- mp->mnt_data = hpmp;
- hpmp->hpm_devvp = devvp;
- hpmp->hpm_dev = devvp->v_rdev;
- hpmp->hpm_mp = mp;
- if (vfs_scanopt(mp->mnt_optnew, "uid", "%d", &v) == 1)
- hpmp->hpm_uid = v;
- if (vfs_scanopt(mp->mnt_optnew, "gid", "%d", &v) == 1)
- hpmp->hpm_gid = v;
- if (vfs_scanopt(mp->mnt_optnew, "mode", "%d", &v) == 1)
- hpmp->hpm_mode = v;
-
- error = hpfs_bminit(hpmp);
- if (error)
- goto failed;
-
- error = hpfs_cpinit(mp, hpmp);
- if (error) {
- hpfs_bmdeinit(hpmp);
- goto failed;
- }
-
- error = hpfs_root(mp, LK_EXCLUSIVE, &vp);
- if (error) {
- hpfs_cpdeinit(hpmp);
- hpfs_bmdeinit(hpmp);
- goto failed;
- }
-
- vput(vp);
-
- mp->mnt_stat.f_fsid.val[0] = (long)dev2udev(dev);
- mp->mnt_stat.f_fsid.val[1] = mp->mnt_vfc->vfc_typenum;
- mp->mnt_maxsymlinklen = 0;
- MNT_ILOCK(mp);
- mp->mnt_flag |= MNT_LOCAL;
- MNT_IUNLOCK(mp);
- return (0);
-
-failed:
- if (bp)
- brelse (bp);
- mp->mnt_data = NULL;
- DROP_GIANT();
- g_topology_lock();
- g_vfs_close(cp);
- g_topology_unlock();
- PICKUP_GIANT();
- return (error);
-}
-
-static int
-hpfs_unmount(
- struct mount *mp,
- int mntflags)
-{
- int error, flags;
- register struct hpfsmount *hpmp = VFSTOHPFS(mp);
-
- dprintf(("hpfs_unmount():\n"));
-
- flags = 0;
- if(mntflags & MNT_FORCE)
- flags |= FORCECLOSE;
-
- dprintf(("hpfs_unmount: vflushing...\n"));
-
- error = vflush(mp, 0, flags, curthread);
- if (error) {
- printf("hpfs_unmount: vflush failed: %d\n",error);
- return (error);
- }
-
- vinvalbuf(hpmp->hpm_devvp, V_SAVE, 0, 0);
- DROP_GIANT();
- g_topology_lock();
- g_vfs_close(hpmp->hpm_cp);
- g_topology_unlock();
- PICKUP_GIANT();
- vrele(hpmp->hpm_devvp);
-
- dprintf(("hpfs_umount: freeing memory...\n"));
- hpfs_cpdeinit(hpmp);
- hpfs_bmdeinit(hpmp);
- mp->mnt_data = NULL;
- MNT_ILOCK(mp);
- mp->mnt_flag &= ~MNT_LOCAL;
- MNT_IUNLOCK(mp);
- free(hpmp, M_HPFSMNT);
-
- return (0);
-}
-
-static int
-hpfs_root(
- struct mount *mp,
- int flags,
- struct vnode **vpp)
-{
- int error = 0;
- struct hpfsmount *hpmp = VFSTOHPFS(mp);
-
- dprintf(("hpfs_root():\n"));
- error = VFS_VGET(mp, (ino_t)hpmp->hpm_su.su_rootfno, LK_EXCLUSIVE, vpp);
- if(error) {
- printf("hpfs_root: VFS_VGET failed: %d\n",error);
- return (error);
- }
-
- return (error);
-}
-
-static int
-hpfs_statfs(
- struct mount *mp,
- struct statfs *sbp)
-{
- struct hpfsmount *hpmp = VFSTOHPFS(mp);
-
- dprintf(("hpfs_statfs(): HPFS%d.%d\n",
- hpmp->hpm_su.su_hpfsver, hpmp->hpm_su.su_fnctver));
-
- sbp->f_type = mp->mnt_vfc->vfc_typenum;
- sbp->f_bsize = DEV_BSIZE;
- sbp->f_iosize = DEV_BSIZE;
- sbp->f_blocks = hpmp->hpm_su.su_btotal;
- sbp->f_bfree = sbp->f_bavail = hpmp->hpm_bavail;
- sbp->f_ffree = 0;
- sbp->f_files = 0;
- sbp->f_flags = mp->mnt_flag;
-
- return (0);
-}
-
-/*ARGSUSED*/
-static int
-hpfs_fhtovp(
- struct mount *mp,
- struct fid *fhp,
- int flags,
- struct vnode **vpp)
-{
- struct vnode *nvp;
- struct hpfid *hpfhp = (struct hpfid *)fhp;
- int error;
-
- if ((error = VFS_VGET(mp, hpfhp->hpfid_ino, LK_EXCLUSIVE, &nvp)) != 0) {
- *vpp = NULLVP;
- return (error);
- }
- /* XXX as unlink/rmdir/mkdir/creat are not currently possible
- * with HPFS, we don't need to check anything else for now */
- *vpp = nvp;
-
- return (0);
-}
-
-static int
-hpfs_vget(
- struct mount *mp,
- ino_t ino,
- int flags,
- struct vnode **vpp)
-{
- struct hpfsmount *hpmp = VFSTOHPFS(mp);
- struct vnode *vp;
- struct hpfsnode *hp;
- struct buf *bp;
- int error;
-
- dprintf(("hpfs_vget(0x%x): ",ino));
-
- error = vfs_hash_get(mp, ino, flags, curthread, vpp, NULL, NULL);
- if (error || *vpp != NULL)
- return (error);
-
- *vpp = NULL;
- hp = NULL;
- vp = NULL;
-
- /*
- * We have to lock node creation for a while,
- * but then we have to call getnewvnode(),
- * this may cause hpfs_reclaim() to be called,
- * this may need to VOP_VGET() parent dir for
- * update reasons, and if parent is not in
- * hash, we have to lock node creation...
- * To solve this, we MALLOC, getnewvnode and init while
- * not locked (probability of node appearence
- * at that time is little, and anyway - we'll
- * check for it).
- */
- hp = malloc(sizeof(struct hpfsnode),
- M_HPFSNO, M_WAITOK);
-
- error = getnewvnode("hpfs", mp, &hpfs_vnodeops, &vp);
- if (error) {
- printf("hpfs_vget: can't get new vnode\n");
- free(hp, M_HPFSNO);
- return (error);
- }
-
- dprintf(("prenew "));
-
- vp->v_data = hp;
-
- if (ino == (ino_t)hpmp->hpm_su.su_rootfno)
- vp->v_vflag |= VV_ROOT;
-
-
- mtx_init(&hp->h_interlock, "hpfsnode interlock", NULL, MTX_DEF);
-
- hp->h_flag = H_INVAL;
- hp->h_vp = vp;
- hp->h_hpmp = hpmp;
- hp->h_no = ino;
- hp->h_dev = hpmp->hpm_dev;
- hp->h_uid = hpmp->hpm_uid;
- hp->h_gid = hpmp->hpm_uid;
- hp->h_mode = hpmp->hpm_mode;
- hp->h_devvp = hpmp->hpm_devvp;
-
- lockmgr(vp->v_vnlock, LK_EXCLUSIVE, NULL);
- error = insmntque(vp, mp);
- if (error != 0) {
- free(hp, M_HPFSNO);
- return (error);
- }
- error = vfs_hash_insert(vp, ino, flags, curthread, vpp, NULL, NULL);
- if (error || *vpp != NULL)
- return (error);
-
- error = bread(hpmp->hpm_devvp, ino, FNODESIZE, NOCRED, &bp);
- if (error) {
- printf("hpfs_vget: can't read ino %ju\n", (uintmax_t)ino);
- vput(vp);
- return (error);
- }
- bcopy(bp->b_data, &hp->h_fn, sizeof(struct fnode));
- brelse(bp);
-
- if (hp->h_fn.fn_magic != FN_MAGIC) {
- printf("hpfs_vget: MAGIC DOESN'T MATCH\n");
- vput(vp);
- return (EINVAL);
- }
-
- vp->v_type = hp->h_fn.fn_flag ? VDIR:VREG;
- hp->h_flag &= ~H_INVAL;
-
- *vpp = vp;
-
- return (0);
-}
-
-static struct vfsops hpfs_vfsops = {
- .vfs_fhtovp = hpfs_fhtovp,
- .vfs_cmount = hpfs_cmount,
- .vfs_mount = hpfs_mount,
- .vfs_root = hpfs_root,
- .vfs_statfs = hpfs_statfs,
- .vfs_unmount = hpfs_unmount,
- .vfs_vget = hpfs_vget,
-};
-VFS_SET(hpfs_vfsops, hpfs, 0);
diff --git a/sys/fs/hpfs/hpfs_vnops.c b/sys/fs/hpfs/hpfs_vnops.c
deleted file mode 100644
index 9abe77c..0000000
--- a/sys/fs/hpfs/hpfs_vnops.c
+++ /dev/null
@@ -1,1264 +0,0 @@
-/*-
- * Copyright (c) 1998, 1999 Semen Ustimenko (semenu@FreeBSD.org)
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * $FreeBSD$
- */
-
-#include <sys/param.h>
-#include <sys/systm.h>
-#include <sys/kernel.h>
-#include <sys/proc.h>
-#include <sys/conf.h>
-#include <sys/time.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <sys/vnode.h>
-#include <sys/mount.h>
-#include <sys/namei.h>
-#include <sys/malloc.h>
-#include <sys/bio.h>
-#include <sys/buf.h>
-#include <sys/dirent.h>
-
-#include <vm/vm.h>
-#include <vm/vm_param.h>
-#include <vm/vm_page.h>
-#include <vm/vm_object.h>
-#include <vm/vm_pager.h>
-#include <vm/vnode_pager.h>
-#include <vm/vm_extern.h>
-
-#include <sys/unistd.h> /* for pathconf(2) constants */
-
-#include <fs/hpfs/hpfs.h>
-#include <fs/hpfs/hpfsmount.h>
-#include <fs/hpfs/hpfs_subr.h>
-#include <fs/hpfs/hpfs_ioctl.h>
-
-static int hpfs_de_uiomove(struct hpfsmount *, struct hpfsdirent *,
- struct uio *);
-static vop_ioctl_t hpfs_ioctl;
-static vop_read_t hpfs_read;
-static vop_write_t hpfs_write;
-static vop_getattr_t hpfs_getattr;
-static vop_setattr_t hpfs_setattr;
-static vop_inactive_t hpfs_inactive;
-static vop_print_t hpfs_print;
-static vop_reclaim_t hpfs_reclaim;
-static vop_strategy_t hpfs_strategy;
-static vop_access_t hpfs_access;
-static vop_open_t hpfs_open;
-static vop_close_t hpfs_close;
-static vop_readdir_t hpfs_readdir;
-static vop_cachedlookup_t hpfs_lookup;
-static vop_create_t hpfs_create;
-static vop_remove_t hpfs_remove;
-static vop_bmap_t hpfs_bmap;
-static vop_fsync_t hpfs_fsync;
-static vop_pathconf_t hpfs_pathconf;
-static vop_vptofh_t hpfs_vptofh;
-
-static int
-hpfs_fsync(ap)
- struct vop_fsync_args /* {
- struct vnode *a_vp;
- struct ucred *a_cred;
- int a_waitfor;
- struct thread *a_td;
- } */ *ap;
-{
- /*
- * Flush our dirty buffers.
- */
- vop_stdfsync(ap);
-
- /*
- * Write out the on-disc version of the vnode.
- */
- return hpfs_update(VTOHP(ap->a_vp));
-}
-
-static int
-hpfs_ioctl (
- struct vop_ioctl_args /* {
- struct vnode *a_vp;
- u_long a_command;
- caddr_t a_data;
- int a_fflag;
- struct ucred *a_cred;
- struct thread *a_td;
- } */ *ap)
-{
- register struct vnode *vp = ap->a_vp;
- register struct hpfsnode *hp = VTOHP(vp);
- int error;
-
- printf("hpfs_ioctl(0x%x, 0x%lx, 0x%p, 0x%x): ",
- hp->h_no, ap->a_command, ap->a_data, ap->a_fflag);
-
- switch (ap->a_command) {
- case HPFSIOCGEANUM: {
- u_long eanum;
- u_long passed;
- struct ea *eap;
-
- eanum = 0;
-
- if (hp->h_fn.fn_ealen > 0) {
- eap = (struct ea *)&(hp->h_fn.fn_int);
- passed = 0;
-
- while (passed < hp->h_fn.fn_ealen) {
-
- printf("EAname: %s\n", EA_NAME(eap));
-
- eanum++;
- passed += sizeof(struct ea) +
- eap->ea_namelen + 1 + eap->ea_vallen;
- eap = (struct ea *)((caddr_t)hp->h_fn.fn_int +
- passed);
- }
- error = 0;
- } else {
- error = ENOENT;
- }
-
- printf("%lu eas\n", eanum);
-
- *(u_long *)ap->a_data = eanum;
-
- break;
- }
- case HPFSIOCGEASZ: {
- u_long eanum;
- u_long passed;
- struct ea *eap;
-
- printf("EA%ld\n", *(u_long *)ap->a_data);
-
- eanum = 0;
- if (hp->h_fn.fn_ealen > 0) {
- eap = (struct ea *)&(hp->h_fn.fn_int);
- passed = 0;
-
- error = ENOENT;
- while (passed < hp->h_fn.fn_ealen) {
- printf("EAname: %s\n", EA_NAME(eap));
-
- if (eanum == *(u_long *)ap->a_data) {
- *(u_long *)ap->a_data =
- eap->ea_namelen + 1 +
- eap->ea_vallen;
-
- error = 0;
- break;
- }
-
- eanum++;
- passed += sizeof(struct ea) +
- eap->ea_namelen + 1 + eap->ea_vallen;
- eap = (struct ea *)((caddr_t)hp->h_fn.fn_int +
- passed);
- }
- } else {
- error = ENOENT;
- }
-
- break;
- }
- case HPFSIOCRDEA: {
- u_long eanum;
- u_long passed;
- struct hpfs_rdea *rdeap;
- struct ea *eap;
-
- rdeap = (struct hpfs_rdea *)ap->a_data;
- printf("EA%ld\n", rdeap->ea_no);
-
- eanum = 0;
- if (hp->h_fn.fn_ealen > 0) {
- eap = (struct ea *)&(hp->h_fn.fn_int);
- passed = 0;
-
- error = ENOENT;
- while (passed < hp->h_fn.fn_ealen) {
- printf("EAname: %s\n", EA_NAME(eap));
-
- if (eanum == rdeap->ea_no) {
- rdeap->ea_sz = eap->ea_namelen + 1 +
- eap->ea_vallen;
- copyout(EA_NAME(eap),rdeap->ea_data,
- rdeap->ea_sz);
- error = 0;
- break;
- }
-
- eanum++;
- passed += sizeof(struct ea) +
- eap->ea_namelen + 1 + eap->ea_vallen;
- eap = (struct ea *)((caddr_t)hp->h_fn.fn_int +
- passed);
- }
- } else {
- error = ENOENT;
- }
-
- break;
- }
- default:
- error = ENOTTY;
- break;
- }
- return (error);
-}
-
-/*
- * Map file offset to disk offset.
- */
-int
-hpfs_bmap(ap)
- struct vop_bmap_args /* {
- struct vnode *a_vp;
- daddr_t a_bn;
- struct bufobj **a_bop;
- daddr_t *a_bnp;
- int *a_runp;
- int *a_runb;
- } */ *ap;
-{
- register struct hpfsnode *hp = VTOHP(ap->a_vp);
- daddr_t blkno;
- int error;
-
- if (ap->a_bop != NULL)
- *ap->a_bop = &hp->h_devvp->v_bufobj;
- if (ap->a_runb != NULL)
- *ap->a_runb = 0;
- if (ap->a_bnp == NULL)
- return (0);
-
- dprintf(("hpfs_bmap(0x%x, 0x%x): ",hp->h_no, ap->a_bn));
-
- error = hpfs_hpbmap (hp, ap->a_bn, &blkno, ap->a_runp);
- *ap->a_bnp = blkno;
-
- return (error);
-}
-
-static int
-hpfs_read(ap)
- struct vop_read_args /* {
- struct vnode *a_vp;
- struct uio *a_uio;
- int a_ioflag;
- struct ucred *a_cred;
- } */ *ap;
-{
- register struct vnode *vp = ap->a_vp;
- register struct hpfsnode *hp = VTOHP(vp);
- struct uio *uio = ap->a_uio;
- struct buf *bp;
- u_int xfersz, toread;
- u_int off;
- daddr_t lbn, bn;
- int resid;
- int runl;
- int error = 0;
-
- resid = min (uio->uio_resid, hp->h_fn.fn_size - uio->uio_offset);
-
- dprintf(("hpfs_read(0x%x, off: %d resid: %d, segflg: %d): [resid: 0x%x]\n",hp->h_no,(u_int32_t)uio->uio_offset,uio->uio_resid,uio->uio_segflg, resid));
-
- while (resid) {
- lbn = uio->uio_offset >> DEV_BSHIFT;
- off = uio->uio_offset & (DEV_BSIZE - 1);
- dprintf(("hpfs_read: resid: 0x%x lbn: 0x%x off: 0x%x\n",
- uio->uio_resid, lbn, off));
- error = hpfs_hpbmap(hp, lbn, &bn, &runl);
- if (error)
- return (error);
-
- toread = min(off + resid, min(DFLTPHYS, (runl+1)*DEV_BSIZE));
- xfersz = (toread + DEV_BSIZE - 1) & ~(DEV_BSIZE - 1);
- dprintf(("hpfs_read: bn: 0x%x (0x%x) toread: 0x%x (0x%x)\n",
- bn, runl, toread, xfersz));
-
- if (toread == 0)
- break;
-
- error = bread(hp->h_devvp, bn, xfersz, NOCRED, &bp);
- if (error) {
- brelse(bp);
- break;
- }
-
- error = uiomove(bp->b_data + off, toread - off, uio);
- if(error) {
- brelse(bp);
- break;
- }
- brelse(bp);
- resid -= toread;
- }
- dprintf(("hpfs_read: successful\n"));
- return (error);
-}
-
-static int
-hpfs_write(ap)
- struct vop_write_args /* {
- struct vnode *a_vp;
- struct uio *a_uio;
- int a_ioflag;
- struct ucred *a_cred;
- } */ *ap;
-{
- register struct vnode *vp = ap->a_vp;
- register struct hpfsnode *hp = VTOHP(vp);
- struct uio *uio = ap->a_uio;
- struct buf *bp;
- u_int xfersz, towrite;
- u_int off;
- daddr_t lbn, bn;
- int runl;
- int error = 0;
-
- dprintf(("hpfs_write(0x%x, off: %d resid: %d, segflg: %d):\n",hp->h_no,(u_int32_t)uio->uio_offset,uio->uio_resid,uio->uio_segflg));
-
- if (ap->a_ioflag & IO_APPEND) {
- dprintf(("hpfs_write: APPEND mode\n"));
- uio->uio_offset = hp->h_fn.fn_size;
- }
- if (uio->uio_offset + uio->uio_resid > hp->h_fn.fn_size) {
- error = hpfs_extend (hp, uio->uio_offset + uio->uio_resid);
- if (error) {
- printf("hpfs_write: hpfs_extend FAILED %d\n", error);
- return (error);
- }
- }
-
- while (uio->uio_resid) {
- lbn = uio->uio_offset >> DEV_BSHIFT;
- off = uio->uio_offset & (DEV_BSIZE - 1);
- dprintf(("hpfs_write: resid: 0x%x lbn: 0x%x off: 0x%x\n",
- uio->uio_resid, lbn, off));
- error = hpfs_hpbmap(hp, lbn, &bn, &runl);
- if (error)
- return (error);
-
- towrite = min(off + uio->uio_resid, min(DFLTPHYS, (runl+1)*DEV_BSIZE));
- xfersz = (towrite + DEV_BSIZE - 1) & ~(DEV_BSIZE - 1);
- dprintf(("hpfs_write: bn: 0x%x (0x%x) towrite: 0x%x (0x%x)\n",
- bn, runl, towrite, xfersz));
-
- if ((off == 0) && (towrite == xfersz)) {
- bp = getblk(hp->h_devvp, bn, xfersz, 0, 0, 0);
- clrbuf(bp);
- } else {
- error = bread(hp->h_devvp, bn, xfersz, NOCRED, &bp);
- if (error) {
- brelse(bp);
- return (error);
- }
- }
-
- error = uiomove(bp->b_data + off, towrite - off, uio);
- if(error) {
- brelse(bp);
- return (error);
- }
-
- if (ap->a_ioflag & IO_SYNC)
- bwrite(bp);
- else
- bawrite(bp);
- }
-
- dprintf(("hpfs_write: successful\n"));
- return (0);
-}
-
-/*
- * XXXXX do we need hpfsnode locking inside?
- */
-static int
-hpfs_getattr(ap)
- struct vop_getattr_args /* {
- struct vnode *a_vp;
- struct vattr *a_vap;
- struct ucred *a_cred;
- } */ *ap;
-{
- register struct vnode *vp = ap->a_vp;
- register struct hpfsnode *hp = VTOHP(vp);
- register struct vattr *vap = ap->a_vap;
- int error;
-
- dprintf(("hpfs_getattr(0x%x):\n", hp->h_no));
-
- vap->va_fsid = dev2udev(hp->h_dev);
- vap->va_fileid = hp->h_no;
- vap->va_mode = hp->h_mode;
- vap->va_nlink = 1;
- vap->va_uid = hp->h_uid;
- vap->va_gid = hp->h_gid;
- vap->va_rdev = NODEV;
- vap->va_size = hp->h_fn.fn_size;
- vap->va_bytes = ((hp->h_fn.fn_size + DEV_BSIZE-1) & ~(DEV_BSIZE-1)) +
- DEV_BSIZE;
-
- if (!(hp->h_flag & H_PARVALID)) {
- error = hpfs_validateparent(hp);
- if (error)
- return (error);
- }
- vap->va_atime = hpfstimetounix(hp->h_atime);
- vap->va_mtime = hpfstimetounix(hp->h_mtime);
- vap->va_ctime = hpfstimetounix(hp->h_ctime);
-
- vap->va_flags = 0;
- vap->va_gen = 0;
- vap->va_blocksize = DEV_BSIZE;
- vap->va_type = vp->v_type;
- vap->va_filerev = 0;
-
- return (0);
-}
-
-/*
- * XXXXX do we need hpfsnode locking inside?
- */
-static int
-hpfs_setattr(ap)
- struct vop_setattr_args /* {
- struct vnode *a_vp;
- struct vattr *a_vap;
- struct ucred *a_cred;
- } */ *ap;
-{
- struct vnode *vp = ap->a_vp;
- struct hpfsnode *hp = VTOHP(vp);
- struct vattr *vap = ap->a_vap;
- struct ucred *cred = ap->a_cred;
- struct thread *td = curthread;
- int error;
-
- dprintf(("hpfs_setattr(0x%x):\n", hp->h_no));
-
- /*
- * Check for unsettable attributes.
- */
- if ((vap->va_type != VNON) || (vap->va_nlink != VNOVAL) ||
- (vap->va_fsid != VNOVAL) || (vap->va_fileid != VNOVAL) ||
- (vap->va_blocksize != VNOVAL) || (vap->va_rdev != VNOVAL) ||
- (vap->va_bytes != VNOVAL) || (vap->va_gen != VNOVAL)) {
- dprintf(("hpfs_setattr: changing nonsettable attr\n"));
- return (EINVAL);
- }
-
- /* Can't change flags XXX Could be implemented */
- if (vap->va_flags != VNOVAL) {
- printf("hpfs_setattr: FLAGS CANNOT BE SET\n");
- return (EINVAL);
- }
-
- /* Can't change uid/gid XXX Could be implemented */
- if (vap->va_uid != (uid_t)VNOVAL || vap->va_gid != (gid_t)VNOVAL) {
- printf("hpfs_setattr: UID/GID CANNOT BE SET\n");
- return (EINVAL);
- }
-
- /* Can't change mode XXX Could be implemented */
- if (vap->va_mode != (mode_t)VNOVAL) {
- printf("hpfs_setattr: MODE CANNOT BE SET\n");
- return (EINVAL);
- }
-
- /* Update times */
- if (vap->va_atime.tv_sec != VNOVAL || vap->va_mtime.tv_sec != VNOVAL) {
- if (vp->v_mount->mnt_flag & MNT_RDONLY)
- return (EROFS);
- if (vap->va_vaflags & VA_UTIMES_NULL) {
- error = VOP_ACCESS(vp, VADMIN, cred, td);
- if (error)
- error = VOP_ACCESS(vp, VWRITE, cred, td);
- } else
- error = VOP_ACCESS(vp, VADMIN, cred, td);
- if (vap->va_atime.tv_sec != VNOVAL)
- hp->h_atime = vap->va_atime.tv_sec;
- if (vap->va_mtime.tv_sec != VNOVAL)
- hp->h_mtime = vap->va_mtime.tv_sec;
-
- hp->h_flag |= H_PARCHANGE;
- }
-
- if (vap->va_size != VNOVAL) {
- switch (vp->v_type) {
- case VDIR:
- return (EISDIR);
- case VREG:
- if (vp->v_mount->mnt_flag & MNT_RDONLY)
- return (EROFS);
- break;
- default:
- printf("hpfs_setattr: WRONG v_type\n");
- return (EINVAL);
- }
-
- if (vap->va_size < hp->h_fn.fn_size) {
- error = vtruncbuf(vp, cred, vap->va_size, DEV_BSIZE);
- if (error)
- return (error);
- error = hpfs_truncate(hp, vap->va_size);
- if (error)
- return (error);
-
- } else if (vap->va_size > hp->h_fn.fn_size) {
- vnode_pager_setsize(vp, vap->va_size);
- error = hpfs_extend(hp, vap->va_size);
- if (error)
- return (error);
- }
- }
-
- return (0);
-}
-
-/*
- * Last reference to a node. If necessary, write or delete it.
- */
-int
-hpfs_inactive(ap)
- struct vop_inactive_args /* {
- struct vnode *a_vp;
- } */ *ap;
-{
- register struct vnode *vp = ap->a_vp;
- register struct hpfsnode *hp = VTOHP(vp);
- int error;
-
- dprintf(("hpfs_inactive(0x%x): \n", hp->h_no));
-
- if (hp->h_flag & H_CHANGE) {
- dprintf(("hpfs_inactive: node changed, update\n"));
- error = hpfs_update (hp);
- if (error)
- return (error);
- }
-
- if (hp->h_flag & H_PARCHANGE) {
- dprintf(("hpfs_inactive: parent node changed, update\n"));
- error = hpfs_updateparent (hp);
- if (error)
- return (error);
- }
-
- if (hp->h_flag & H_INVAL) {
- vrecycle(vp);
- return (0);
- }
-
- return (0);
-}
-
-/*
- * Reclaim an inode so that it can be used for other purposes.
- */
-int
-hpfs_reclaim(ap)
- struct vop_reclaim_args /* {
- struct vnode *a_vp;
- } */ *ap;
-{
- register struct vnode *vp = ap->a_vp;
- register struct hpfsnode *hp = VTOHP(vp);
-
- dprintf(("hpfs_reclaim(0x%x0): \n", hp->h_no));
-
- /*
- * Destroy the vm object and flush associated pages.
- */
- vnode_destroy_vobject(vp);
-
- vfs_hash_remove(vp);
-
- mtx_destroy(&hp->h_interlock);
-
- vp->v_data = NULL;
-
- free(hp, M_HPFSNO);
-
- return (0);
-}
-
-static int
-hpfs_print(ap)
- struct vop_print_args /* {
- struct vnode *a_vp;
- } */ *ap;
-{
- register struct vnode *vp = ap->a_vp;
- register struct hpfsnode *hp = VTOHP(vp);
-
- printf("\tino 0x%x\n", hp->h_no);
- return (0);
-}
-
-/*
- * Calculate the logical to physical mapping if not done already,
- * then call the device strategy routine.
- *
- * In order to be able to swap to a file, the hpfs_hpbmap operation may not
- * deadlock on memory. See hpfs_bmap() for details. XXXXXXX (not impl)
- */
-int
-hpfs_strategy(ap)
- struct vop_strategy_args /* {
- struct buf *a_bp;
- } */ *ap;
-{
- register struct buf *bp = ap->a_bp;
- register struct vnode *vp = ap->a_vp;
- register struct hpfsnode *hp = VTOHP(ap->a_vp);
- daddr_t blkno;
- struct bufobj *bo;
- int error;
-
- dprintf(("hpfs_strategy(): \n"));
-
- if (vp->v_type == VBLK || vp->v_type == VCHR)
- panic("hpfs_strategy: spec");
- if (bp->b_blkno == bp->b_lblkno) {
- error = hpfs_hpbmap (hp, bp->b_lblkno, &blkno, NULL);
- bp->b_blkno = blkno;
- if (error) {
- printf("hpfs_strategy: hpfs_bpbmap FAILED %d\n", error);
- bp->b_error = error;
- bp->b_ioflags |= BIO_ERROR;
- bufdone(bp);
- return (0);
- }
- if ((long)bp->b_blkno == -1)
- vfs_bio_clrbuf(bp);
- }
- if ((long)bp->b_blkno == -1) {
- bufdone(bp);
- return (0);
- }
- bp->b_iooffset = dbtob(bp->b_blkno);
- bo = hp->h_hpmp->hpm_bo;
- BO_STRATEGY(bo, bp);
- return (0);
-}
-
-/*
- * XXXXX do we need hpfsnode locking inside?
- */
-int
-hpfs_access(ap)
- struct vop_access_args /* {
- struct vnode *a_vp;
- accmode_t a_accmode;
- struct ucred *a_cred;
- struct thread *a_td;
- } */ *ap;
-{
- struct vnode *vp = ap->a_vp;
- struct hpfsnode *hp = VTOHP(vp);
- accmode_t accmode = ap->a_accmode;
-
- dprintf(("hpfs_access(0x%x):\n", hp->h_no));
-
- /*
- * Disallow write attempts on read-only filesystems;
- * unless the file is a socket, fifo, or a block or
- * character device resident on the filesystem.
- */
- if (accmode & VWRITE) {
- switch ((int)vp->v_type) {
- case VDIR:
- case VLNK:
- case VREG:
- if (vp->v_mount->mnt_flag & MNT_RDONLY)
- return (EROFS);
- break;
- }
- }
-
- return (vaccess(vp->v_type, hp->h_mode, hp->h_uid, hp->h_gid,
- ap->a_accmode, ap->a_cred, NULL));
-}
-
-/*
- * Open called.
- *
- * Nothing to do.
- */
-/* ARGSUSED */
-static int
-hpfs_open(ap)
- struct vop_open_args /* {
- struct vnode *a_vp;
- int a_mode;
- struct ucred *a_cred;
- struct thread *a_td;
- } */ *ap;
-{
-#ifdef HPFS_DEBUG
- register struct vnode *vp = ap->a_vp;
- register struct hpfsnode *hp = VTOHP(vp);
-
- printf("hpfs_open(0x%x):\n",hp->h_no);
-#endif
-
- /*
- * Files marked append-only must be opened for appending.
- */
-
- return (0);
-}
-
-/*
- * Close called.
- *
- * Update the times on the inode.
- */
-/* ARGSUSED */
-static int
-hpfs_close(ap)
- struct vop_close_args /* {
- struct vnode *a_vp;
- int a_fflag;
- struct ucred *a_cred;
- struct thread *a_td;
- } */ *ap;
-{
-#ifdef HPFS_DEBUG
- register struct vnode *vp = ap->a_vp;
- register struct hpfsnode *hp = VTOHP(vp);
-
- printf("hpfs_close: %d\n",hp->h_no);
-#endif
-
- return (0);
-}
-
-static int
-hpfs_de_uiomove (
- struct hpfsmount *hpmp,
- struct hpfsdirent *dep,
- struct uio *uio)
-{
- struct dirent cde;
- int i, error;
-
- dprintf(("[no: 0x%x, size: %d, name: %2d:%.*s, flag: 0x%x] ",
- dep->de_fnode, dep->de_size, dep->de_namelen,
- dep->de_namelen, dep->de_name, dep->de_flag));
-
- /*strncpy(cde.d_name, dep->de_name, dep->de_namelen);*/
- for (i=0; i<dep->de_namelen; i++)
- cde.d_name[i] = hpfs_d2u(hpmp, dep->de_name[i]);
-
- cde.d_name[dep->de_namelen] = '\0';
- cde.d_namlen = dep->de_namelen;
- cde.d_fileno = dep->de_fnode;
- cde.d_type = (dep->de_flag & DE_DIR) ? DT_DIR : DT_REG;
- cde.d_reclen = sizeof(struct dirent);
-
- error = uiomove((char *)&cde, sizeof(struct dirent), uio);
- if (error)
- return (error);
-
- dprintf(("[0x%x] ", uio->uio_resid));
- return (error);
-}
-
-
-static struct dirent hpfs_de_dot = {
- .d_fileno = 0,
- .d_reclen = sizeof(struct dirent),
- .d_type = DT_DIR,
- .d_namlen = 1,
- .d_name = "."
-};
-static struct dirent hpfs_de_dotdot = {
- .d_fileno = 0,
- .d_reclen = sizeof(struct dirent),
- .d_type = DT_DIR,
- .d_namlen = 2,
- .d_name = ".."
-};
-
-int
-hpfs_readdir(ap)
- struct vop_readdir_args /* {
- struct vnode *a_vp;
- struct uio *a_uio;
- struct ucred *a_cred;
- int *a_ncookies;
- u_int **cookies;
- } */ *ap;
-{
- register struct vnode *vp = ap->a_vp;
- register struct hpfsnode *hp = VTOHP(vp);
- struct hpfsmount *hpmp = hp->h_hpmp;
- struct uio *uio = ap->a_uio;
- int ncookies = 0, i, num, cnum;
- int error = 0;
- off_t off;
- struct buf *bp;
- struct dirblk *dp;
- struct hpfsdirent *dep;
- lsn_t olsn;
- lsn_t lsn;
- int level;
-
- dprintf(("hpfs_readdir(0x%x, 0x%x, 0x%x): ",hp->h_no,(u_int32_t)uio->uio_offset,uio->uio_resid));
-
- off = uio->uio_offset;
-
- if( uio->uio_offset < sizeof(struct dirent) ) {
- dprintf((". faked, "));
- hpfs_de_dot.d_fileno = hp->h_no;
- error = uiomove((char *)&hpfs_de_dot,sizeof(struct dirent),uio);
- if(error) {
- return (error);
- }
-
- ncookies ++;
- }
-
- if( uio->uio_offset < 2 * sizeof(struct dirent) ) {
- dprintf((".. faked, "));
- hpfs_de_dotdot.d_fileno = hp->h_fn.fn_parent;
-
- error = uiomove((char *)&hpfs_de_dotdot, sizeof(struct dirent),
- uio);
- if(error) {
- return (error);
- }
-
- ncookies ++;
- }
-
- num = uio->uio_offset / sizeof(struct dirent) - 2;
- cnum = 0;
-
- lsn = ((alleaf_t *)hp->h_fn.fn_abd)->al_lsn;
-
- olsn = 0;
- level = 1;
-
-dive:
- dprintf(("[dive 0x%x] ", lsn));
- error = bread(hp->h_devvp, lsn, D_BSIZE, NOCRED, &bp);
- if (error) {
- brelse(bp);
- return (error);
- }
-
- dp = (struct dirblk *) bp->b_data;
- if (dp->d_magic != D_MAGIC) {
- printf("hpfs_readdir: MAGIC DOESN'T MATCH\n");
- brelse(bp);
- return (EINVAL);
- }
-
- dep = D_DIRENT(dp);
-
- if (olsn) {
- dprintf(("[restore 0x%x] ", olsn));
-
- while(!(dep->de_flag & DE_END) ) {
- if((dep->de_flag & DE_DOWN) &&
- (olsn == DE_DOWNLSN(dep)))
- break;
- dep = (hpfsdirent_t *)((caddr_t)dep + dep->de_reclen);
- }
-
- if((dep->de_flag & DE_DOWN) && (olsn == DE_DOWNLSN(dep))) {
- if (dep->de_flag & DE_END)
- goto blockdone;
-
- if (!(dep->de_flag & DE_SPECIAL)) {
- if (num <= cnum) {
- if (uio->uio_resid < sizeof(struct dirent)) {
- brelse(bp);
- dprintf(("[resid] "));
- goto readdone;
- }
-
- error = hpfs_de_uiomove(hpmp, dep, uio);
- if (error) {
- brelse (bp);
- return (error);
- }
- ncookies++;
-
- if (uio->uio_resid < sizeof(struct dirent)) {
- brelse(bp);
- dprintf(("[resid] "));
- goto readdone;
- }
- }
- cnum++;
- }
-
- dep = (hpfsdirent_t *)((caddr_t)dep + dep->de_reclen);
- } else {
- printf("hpfs_readdir: ERROR! oLSN not found\n");
- brelse(bp);
- return (EINVAL);
- }
- }
-
- olsn = 0;
-
- while(!(dep->de_flag & DE_END)) {
- if(dep->de_flag & DE_DOWN) {
- lsn = DE_DOWNLSN(dep);
- brelse(bp);
- level++;
- goto dive;
- }
-
- if (!(dep->de_flag & DE_SPECIAL)) {
- if (num <= cnum) {
- if (uio->uio_resid < sizeof(struct dirent)) {
- brelse(bp);
- dprintf(("[resid] "));
- goto readdone;
- }
-
- error = hpfs_de_uiomove(hpmp, dep, uio);
- if (error) {
- brelse (bp);
- return (error);
- }
- ncookies++;
-
- if (uio->uio_resid < sizeof(struct dirent)) {
- brelse(bp);
- dprintf(("[resid] "));
- goto readdone;
- }
- }
- cnum++;
- }
-
- dep = (hpfsdirent_t *)((caddr_t)dep + dep->de_reclen);
- }
-
- if(dep->de_flag & DE_DOWN) {
- dprintf(("[enddive] "));
- lsn = DE_DOWNLSN(dep);
- brelse(bp);
- level++;
- goto dive;
- }
-
-blockdone:
- dprintf(("[EOB] "));
- olsn = lsn;
- lsn = dp->d_parent;
- brelse(bp);
- level--;
-
- dprintf(("[level %d] ", level));
-
- if (level > 0)
- goto dive; /* undive really */
-
- if (ap->a_eofflag) {
- dprintf(("[EOF] "));
- *ap->a_eofflag = 1;
- }
-
-readdone:
- dprintf(("[readdone]\n"));
- if (!error && ap->a_ncookies != NULL) {
- struct dirent* dpStart;
- struct dirent* dp;
- u_long *cookies;
- u_long *cookiep;
-
- dprintf(("%d cookies, ",ncookies));
- if (uio->uio_segflg != UIO_SYSSPACE || uio->uio_iovcnt != 1)
- panic("hpfs_readdir: unexpected uio from NFS server");
- dpStart = (struct dirent *)
- ((caddr_t)uio->uio_iov->iov_base -
- (uio->uio_offset - off));
- cookies = malloc(ncookies * sizeof(u_long),
- M_TEMP, M_WAITOK);
- for (dp = dpStart, cookiep = cookies, i=0;
- i < ncookies;
- dp = (struct dirent *)((caddr_t) dp + dp->d_reclen), i++) {
- off += dp->d_reclen;
- *cookiep++ = (u_int) off;
- }
- *ap->a_ncookies = ncookies;
- *ap->a_cookies = cookies;
- }
-
- return (0);
-}
-
-int
-hpfs_lookup(ap)
- struct vop_cachedlookup_args /* {
- struct vnode *a_dvp;
- struct vnode **a_vpp;
- struct componentname *a_cnp;
- } */ *ap;
-{
- register struct vnode *dvp = ap->a_dvp;
- register struct hpfsnode *dhp = VTOHP(dvp);
- struct hpfsmount *hpmp = dhp->h_hpmp;
- struct componentname *cnp = ap->a_cnp;
- struct ucred *cred = cnp->cn_cred;
- int error;
- int nameiop = cnp->cn_nameiop;
- int flags = cnp->cn_flags;
- dprintf(("hpfs_lookup(0x%x, %s, %ld):\n",
- dhp->h_no, cnp->cn_nameptr, cnp->cn_namelen));
-
- if (nameiop != CREATE && nameiop != DELETE && nameiop != LOOKUP) {
- printf("hpfs_lookup: LOOKUP, DELETE and CREATE are only supported\n");
- return (EOPNOTSUPP);
- }
-
- error = VOP_ACCESS(dvp, VEXEC, cred, cnp->cn_thread);
- if(error)
- return (error);
-
- if( (cnp->cn_namelen == 1) &&
- !strncmp(cnp->cn_nameptr,".",1) ) {
- dprintf(("hpfs_lookup(0x%x,...): . faked\n",dhp->h_no));
-
- VREF(dvp);
- *ap->a_vpp = dvp;
-
- return (0);
- } else if( (cnp->cn_namelen == 2) &&
- !strncmp(cnp->cn_nameptr,"..",2) && (flags & ISDOTDOT) ) {
- dprintf(("hpfs_lookup(0x%x,...): .. faked (0x%x)\n",
- dhp->h_no, dhp->h_fn.fn_parent));
-
- if (VFS_VGET(hpmp->hpm_mp, dhp->h_fn.fn_parent,
- LK_NOWAIT | LK_EXCLUSIVE, ap->a_vpp)) {
- VOP_UNLOCK(dvp,0);
- error = VFS_VGET(hpmp->hpm_mp,
- dhp->h_fn.fn_parent, LK_EXCLUSIVE, ap->a_vpp);
- vn_lock(dvp, LK_EXCLUSIVE|LK_RETRY);
- if (error)
- return(error);
- }
- return (0);
- } else {
- struct buf *bp;
- struct hpfsdirent *dep;
- struct hpfsnode *hp;
-
- error = hpfs_genlookupbyname(dhp,
- cnp->cn_nameptr, cnp->cn_namelen, &bp, &dep);
- if (error) {
- if ((error == ENOENT) && (flags & ISLASTCN) &&
- (nameiop == CREATE || nameiop == RENAME)) {
- cnp->cn_flags |= SAVENAME;
- return (EJUSTRETURN);
- }
-
- return (error);
- }
-
- dprintf(("hpfs_lookup: fnode: 0x%x, CPID: 0x%x\n",
- dep->de_fnode, dep->de_cpid));
-
- if (nameiop == DELETE && (flags & ISLASTCN)) {
- error = VOP_ACCESS(dvp, VWRITE, cred, cnp->cn_thread);
- if (error) {
- brelse(bp);
- return (error);
- }
- }
-
- if (dhp->h_no == dep->de_fnode) {
- brelse(bp);
- VREF(dvp);
- *ap->a_vpp = dvp;
- return (0);
- }
-
- error = VFS_VGET(hpmp->hpm_mp, dep->de_fnode, LK_EXCLUSIVE,
- ap->a_vpp);
- if (error) {
- printf("hpfs_lookup: VFS_VGET FAILED %d\n", error);
- brelse(bp);
- return(error);
- }
-
- hp = VTOHP(*ap->a_vpp);
-
- hp->h_mtime = dep->de_mtime;
- hp->h_ctime = dep->de_ctime;
- hp->h_atime = dep->de_atime;
- bcopy(dep->de_name, hp->h_name, dep->de_namelen);
- hp->h_name[dep->de_namelen] = '\0';
- hp->h_namelen = dep->de_namelen;
- hp->h_flag |= H_PARVALID;
-
- brelse(bp);
-
- if ((flags & MAKEENTRY) &&
- (!(flags & ISLASTCN) ||
- (nameiop != DELETE && nameiop != CREATE)))
- cache_enter(dvp, *ap->a_vpp, cnp);
- }
- return (error);
-}
-
-int
-hpfs_remove(ap)
- struct vop_remove_args /* {
- struct vnode *a_dvp;
- struct vnode *a_vp;
- struct componentname *a_cnp;
- } */ *ap;
-{
- int error;
-
- dprintf(("hpfs_remove(0x%x, %s, %ld): \n", VTOHP(ap->a_vp)->h_no,
- ap->a_cnp->cn_nameptr, ap->a_cnp->cn_namelen));
-
- if (ap->a_vp->v_type == VDIR)
- return (EPERM);
-
- error = hpfs_removefnode (ap->a_dvp, ap->a_vp, ap->a_cnp);
- return (error);
-}
-
-int
-hpfs_create(ap)
- struct vop_create_args /* {
- struct vnode *a_dvp;
- struct vnode **a_vpp;
- struct componentname *a_cnp;
- struct vattr *a_vap;
- } */ *ap;
-{
- int error;
-
- dprintf(("hpfs_create(0x%x, %s, %ld): \n", VTOHP(ap->a_dvp)->h_no,
- ap->a_cnp->cn_nameptr, ap->a_cnp->cn_namelen));
-
- if (!(ap->a_cnp->cn_flags & HASBUF))
- panic ("hpfs_create: no name\n");
-
- error = hpfs_makefnode (ap->a_dvp, ap->a_vpp, ap->a_cnp, ap->a_vap);
-
- return (error);
-}
-
-/*
- * Return POSIX pathconf information applicable to NTFS filesystem
- */
-int
-hpfs_pathconf(ap)
- struct vop_pathconf_args /* {
- struct vnode *a_vp;
- int a_name;
- register_t *a_retval;
- } */ *ap;
-{
- switch (ap->a_name) {
- case _PC_LINK_MAX:
- *ap->a_retval = 1;
- return (0);
- case _PC_NAME_MAX:
- *ap->a_retval = HPFS_MAXFILENAME;
- return (0);
- case _PC_PATH_MAX:
- *ap->a_retval = PATH_MAX;
- return (0);
- case _PC_CHOWN_RESTRICTED:
- *ap->a_retval = 1;
- return (0);
- case _PC_NO_TRUNC:
- *ap->a_retval = 0;
- return (0);
- default:
- return (EINVAL);
- }
- /* NOTREACHED */
-}
-
-int
-hpfs_vptofh(ap)
- struct vop_vptofh_args /* {
- struct vnode *a_vp;
- struct fid *a_fhp;
- } */ *ap;
-{
- register struct hpfsnode *hpp;
- register struct hpfid *hpfhp;
-
- hpp = VTOHP(ap->a_vp);
- hpfhp = (struct hpfid *)ap->a_fhp;
- hpfhp->hpfid_len = sizeof(struct hpfid);
- hpfhp->hpfid_ino = hpp->h_no;
- /* hpfhp->hpfid_gen = hpp->h_gen; */
- return (0);
-}
-
-
-/*
- * Global vfs data structures
- */
-struct vop_vector hpfs_vnodeops = {
- .vop_default = &default_vnodeops,
-
- .vop_access = hpfs_access,
- .vop_bmap = hpfs_bmap,
- .vop_cachedlookup = hpfs_lookup,
- .vop_close = hpfs_close,
- .vop_create = hpfs_create,
- .vop_fsync = hpfs_fsync,
- .vop_getattr = hpfs_getattr,
- .vop_inactive = hpfs_inactive,
- .vop_ioctl = hpfs_ioctl,
- .vop_lookup = vfs_cache_lookup,
- .vop_open = hpfs_open,
- .vop_pathconf = hpfs_pathconf,
- .vop_print = hpfs_print,
- .vop_read = hpfs_read,
- .vop_readdir = hpfs_readdir,
- .vop_reclaim = hpfs_reclaim,
- .vop_remove = hpfs_remove,
- .vop_setattr = hpfs_setattr,
- .vop_strategy = hpfs_strategy,
- .vop_write = hpfs_write,
- .vop_vptofh = hpfs_vptofh,
-};
diff --git a/sys/fs/hpfs/hpfsmount.h b/sys/fs/hpfs/hpfsmount.h
deleted file mode 100644
index 5ca42b3..0000000
--- a/sys/fs/hpfs/hpfsmount.h
+++ /dev/null
@@ -1,39 +0,0 @@
-/*-
- * Copyright (c) 1998, 1999 Semen Ustimenko (semenu@FreeBSD.org)
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * $FreeBSD$
- */
-
-#define HPFSMNT_TABLES 0x0001
-struct hpfs_args {
- char *fspec; /* block special device to mount */
- struct oexport_args export; /* network export information */
- uid_t uid; /* uid that owns hpfs files */
- gid_t gid; /* gid that owns hpfs files */
- mode_t mode; /* mask to be applied for hpfs perms */
- u_long flags; /* additional flags */
- u_char d2u[0x80];
- u_char u2d[0x80];
-};
diff --git a/sys/fs/ntfs/ntfs.h b/sys/fs/ntfs/ntfs.h
deleted file mode 100644
index 26e86a9..0000000
--- a/sys/fs/ntfs/ntfs.h
+++ /dev/null
@@ -1,308 +0,0 @@
-/* $NetBSD: ntfs.h,v 1.9 1999/10/31 19:45:26 jdolecek Exp $ */
-
-/*-
- * Copyright (c) 1998, 1999 Semen Ustimenko
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * $FreeBSD$
- */
-
-/*#define NTFS_DEBUG 1*/
-
-typedef uint64_t cn_t;
-typedef uint16_t wchar;
-
-#pragma pack(1)
-#define BBSIZE 1024
-#define BBOFF ((off_t)(0))
-#define BBLOCK 0
-#define NTFS_MFTINO 0
-#define NTFS_VOLUMEINO 3
-#define NTFS_ATTRDEFINO 4
-#define NTFS_ROOTINO 5
-#define NTFS_BITMAPINO 6
-#define NTFS_BOOTINO 7
-#define NTFS_BADCLUSINO 8
-#define NTFS_UPCASEINO 10
-#define NTFS_MAXFILENAME 255
-
-struct fixuphdr {
- uint32_t fh_magic;
- uint16_t fh_foff;
- uint16_t fh_fnum;
-};
-
-#define NTFS_AF_INRUN 0x00000001
-struct attrhdr {
- uint32_t a_type;
- uint32_t reclen;
- uint8_t a_flag;
- uint8_t a_namelen;
- uint8_t a_nameoff;
- uint8_t reserved1;
- uint8_t a_compression;
- uint8_t reserved2;
- uint16_t a_index;
-};
-#define NTFS_A_STD 0x10
-#define NTFS_A_ATTRLIST 0x20
-#define NTFS_A_NAME 0x30
-#define NTFS_A_VOLUMENAME 0x60
-#define NTFS_A_DATA 0x80
-#define NTFS_A_INDXROOT 0x90
-#define NTFS_A_INDX 0xA0
-#define NTFS_A_INDXBITMAP 0xB0
-
-#define NTFS_MAXATTRNAME 255
-struct attr {
- struct attrhdr a_hdr;
- union {
- struct {
- uint16_t a_datalen;
- uint16_t reserved1;
- uint16_t a_dataoff;
- uint16_t a_indexed;
- } a_S_r;
- struct {
- cn_t a_vcnstart;
- cn_t a_vcnend;
- uint16_t a_dataoff;
- uint16_t a_compressalg;
- uint32_t reserved1;
- uint64_t a_allocated;
- uint64_t a_datalen;
- uint64_t a_initialized;
- } a_S_nr;
- } a_S;
-};
-#define a_r a_S.a_S_r
-#define a_nr a_S.a_S_nr
-
-typedef struct {
- uint64_t t_create;
- uint64_t t_write;
- uint64_t t_mftwrite;
- uint64_t t_access;
-} ntfs_times_t;
-
-#define NTFS_FFLAG_RDONLY 0x01LL
-#define NTFS_FFLAG_HIDDEN 0x02LL
-#define NTFS_FFLAG_SYSTEM 0x04LL
-#define NTFS_FFLAG_ARCHIVE 0x20LL
-#define NTFS_FFLAG_COMPRESSED 0x0800LL
-#define NTFS_FFLAG_DIR 0x10000000LL
-
-struct attr_name {
- uint32_t n_pnumber; /* Parent ntnode */
- uint32_t reserved;
- ntfs_times_t n_times;
- uint64_t n_size;
- uint64_t n_attrsz;
- uint64_t n_flag;
- uint8_t n_namelen;
- uint8_t n_nametype;
- uint16_t n_name[1];
-};
-
-#define NTFS_IRFLAG_INDXALLOC 0x00000001
-struct attr_indexroot {
- uint32_t ir_unkn1; /* always 0x30 */
- uint32_t ir_unkn2; /* always 0x1 */
- uint32_t ir_size;/* ??? */
- uint32_t ir_unkn3; /* number of cluster */
- uint32_t ir_unkn4; /* always 0x10 */
- uint32_t ir_datalen; /* sizeof simething */
- uint32_t ir_allocated; /* same as above */
- uint16_t ir_flag;/* ?? always 1 */
- uint16_t ir_unkn7;
-};
-
-struct attr_attrlist {
- uint32_t al_type; /* Attribute type */
- uint16_t reclen; /* length of this entry */
- uint8_t al_namelen; /* Attribute name len */
- uint8_t al_nameoff; /* Name offset from entry start */
- uint64_t al_vcnstart; /* VCN number */
- uint32_t al_inumber; /* Parent ntnode */
- uint32_t reserved;
- uint16_t al_index; /* Attribute index in MFT record */
- uint16_t al_name[1]; /* Name */
-};
-
-#define NTFS_INDXMAGIC (uint32_t)(0x58444E49)
-struct attr_indexalloc {
- struct fixuphdr ia_fixup;
- uint64_t unknown1;
- cn_t ia_bufcn;
- uint16_t ia_hdrsize;
- uint16_t unknown2;
- uint32_t ia_inuse;
- uint32_t ia_allocated;
-};
-
-#define NTFS_IEFLAG_SUBNODE 0x00000001
-#define NTFS_IEFLAG_LAST 0x00000002
-
-struct attr_indexentry {
- uint32_t ie_number;
- uint32_t unknown1;
- uint16_t reclen;
- uint16_t ie_size;
- uint32_t ie_flag; /* 1 - has subnodes, 2 - last */
- uint32_t ie_fpnumber;
- uint32_t unknown2;
- ntfs_times_t ie_ftimes;
- uint64_t ie_fallocated;
- uint64_t ie_fsize;
- uint64_t ie_fflag;
- uint8_t ie_fnamelen;
- uint8_t ie_fnametype;
- wchar ie_fname[NTFS_MAXFILENAME];
- /* cn_t ie_bufcn; buffer with subnodes */
-};
-
-#define NTFS_FILEMAGIC (uint32_t)(0x454C4946)
-#define NTFS_BLOCK_SIZE 512
-#define NTFS_FRFLAG_DIR 0x0002
-struct filerec {
- struct fixuphdr fr_fixup;
- uint8_t reserved[8];
- uint16_t fr_seqnum; /* Sequence number */
- uint16_t fr_nlink;
- uint16_t fr_attroff; /* offset to attributes */
- uint16_t fr_flags; /* 1-nonresident attr, 2-directory */
- uint32_t fr_size;/* hdr + attributes */
- uint32_t fr_allocated; /* allocated length of record */
- uint64_t fr_mainrec; /* main record */
- uint16_t fr_attrnum; /* maximum attr number + 1 ??? */
-};
-
-#define NTFS_ATTRNAME_MAXLEN 0x40
-#define NTFS_ADFLAG_NONRES 0x0080 /* Attrib can be non resident */
-#define NTFS_ADFLAG_INDEX 0x0002 /* Attrib can be indexed */
-struct attrdef {
- wchar ad_name[NTFS_ATTRNAME_MAXLEN];
- uint32_t ad_type;
- uint32_t reserved1[2];
- uint32_t ad_flag;
- uint64_t ad_minlen;
- uint64_t ad_maxlen; /* -1 for nonlimited */
-};
-
-struct ntvattrdef {
- char ad_name[0x40];
- int ad_namelen;
- uint32_t ad_type;
-};
-
-#define NTFS_BBID "NTFS "
-#define NTFS_BBIDLEN 8
-struct bootfile {
- uint8_t reserved1[3]; /* asm jmp near ... */
- uint8_t bf_sysid[8]; /* 'NTFS ' */
- uint16_t bf_bps; /* bytes per sector */
- uint8_t bf_spc; /* sectors per cluster */
- uint8_t reserved2[7]; /* unused (zeroed) */
- uint8_t bf_media; /* media desc. (0xF8) */
- uint8_t reserved3[2];
- uint16_t bf_spt; /* sectors per track */
- uint16_t bf_heads; /* number of heads */
- uint8_t reserver4[12];
- uint64_t bf_spv; /* sectors per volume */
- cn_t bf_mftcn; /* $MFT cluster number */
- cn_t bf_mftmirrcn; /* $MFTMirr cn */
- uint8_t bf_mftrecsz; /* MFT record size (clust) */
- /* 0xF6 inducates 1/4 */
- uint32_t bf_ibsz; /* index buffer size */
- uint32_t bf_volsn; /* volume ser. num. */
-};
-
-#define NTFS_SYSNODESNUM 0x0B
-struct ntfsmount {
- struct mount *ntm_mountp; /* filesystem vfs structure */
- struct bootfile ntm_bootfile;
- struct g_consumer *ntm_cp;
- struct bufobj *ntm_bo;
- struct vnode *ntm_devvp; /* block device mounted vnode */
- struct vnode *ntm_sysvn[NTFS_SYSNODESNUM];
- uint32_t ntm_bpmftrec;
- uid_t ntm_uid;
- gid_t ntm_gid;
- mode_t ntm_mode;
- uint64_t ntm_flag;
- cn_t ntm_cfree;
- struct ntvattrdef *ntm_ad;
- int ntm_adnum;
- wchar * ntm_82u; /* 8bit to Unicode */
- char ** ntm_u28; /* Unicode to 8 bit */
- void * ntm_ic_l2u; /* Local to Unicode (iconv) */
- void * ntm_ic_u2l; /* Unicode to Local (iconv) */
- uint8_t ntm_multiplier; /* NTFS blockno to DEV_BSIZE sectorno */
-};
-
-#define ntm_mftcn ntm_bootfile.bf_mftcn
-#define ntm_mftmirrcn ntm_bootfile.bf_mftmirrcn
-#define ntm_mftrecsz ntm_bootfile.bf_mftrecsz
-#define ntm_spc ntm_bootfile.bf_spc
-#define ntm_bps ntm_bootfile.bf_bps
-
-#pragma pack()
-
-#define NTFS_NEXTREC(s, type) ((type)(((caddr_t) s) + (s)->reclen))
-
-/* Convert mount ptr to ntfsmount ptr. */
-#define VFSTONTFS(mp) ((struct ntfsmount *)((mp)->mnt_data))
-#define VTONT(v) FTONT(VTOF(v))
-#define VTOF(v) ((struct fnode *)((v)->v_data))
-#define FTOV(f) ((f)->f_vp)
-#define FTONT(f) ((f)->f_ip)
-#define ntfs_cntobn(cn) (daddr_t)((cn) * (ntmp->ntm_spc))
-#define ntfs_cntob(cn) (off_t)((cn) * (ntmp)->ntm_spc * (ntmp)->ntm_bps)
-#define ntfs_btocn(off) (cn_t)((off) / ((ntmp)->ntm_spc * (ntmp)->ntm_bps))
-#define ntfs_btocl(off) (cn_t)((off + ntfs_cntob(1) - 1) / ((ntmp)->ntm_spc * (ntmp)->ntm_bps))
-#define ntfs_btocnoff(off) (off_t)((off) % ((ntmp)->ntm_spc * (ntmp)->ntm_bps))
-#define ntfs_bntob(bn) (daddr_t)((bn) * (ntmp)->ntm_bps)
-
-#define ntfs_bpbl (daddr_t)((ntmp)->ntm_bps)
-
-#ifdef MALLOC_DECLARE
-MALLOC_DECLARE(M_NTFSNTNODE);
-MALLOC_DECLARE(M_NTFSFNODE);
-MALLOC_DECLARE(M_NTFSDIR);
-MALLOC_DECLARE(M_NTFSNTHASH);
-#endif
-
-#if defined(NTFS_DEBUG)
-#define dprintf(a) printf a
-#if NTFS_DEBUG > 1
-#define ddprintf(a) printf a
-#else
-#define ddprintf(a) (void)0
-#endif
-#else
-#define dprintf(a) (void)0
-#define ddprintf(a) (void)0
-#endif
-
-extern struct vop_vector ntfs_vnodeops;
diff --git a/sys/fs/ntfs/ntfs_compr.c b/sys/fs/ntfs/ntfs_compr.c
deleted file mode 100644
index dcc82a3..0000000
--- a/sys/fs/ntfs/ntfs_compr.c
+++ /dev/null
@@ -1,111 +0,0 @@
-/* $NetBSD: ntfs_compr.c,v 1.3 1999/07/26 14:02:31 jdolecek Exp $ */
-
-/*-
- * Copyright (c) 1998, 1999 Semen Ustimenko
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * $FreeBSD$
- */
-
-#include <sys/param.h>
-#include <sys/systm.h>
-#include <sys/namei.h>
-#include <sys/vnode.h>
-#include <sys/mount.h>
-#include <sys/file.h>
-
-#include <fs/ntfs/ntfs.h>
-#include <fs/ntfs/ntfs_compr.h>
-
-#define GET_UINT16(addr) (*((u_int16_t *)(addr)))
-
-int
-ntfs_uncompblock(
- u_int8_t * dbuf,
- u_int8_t * cbuf)
-{
- u_int32_t ctag;
- int len, dshift, lmask;
- int blen, boff;
- int i, j;
- int pos, cpos;
-
- len = GET_UINT16(cbuf) & 0xFFF;
- dprintf(("ntfs_uncompblock: block length: %d + 3, 0x%x,0x%04x\n",
- len, len, GET_UINT16(cbuf)));
-
- if (!(GET_UINT16(cbuf) & 0x8000)) {
- if ((len + 1) != NTFS_COMPBLOCK_SIZE) {
- dprintf(("ntfs_uncompblock: len: %x instead of %d\n",
- len, 0xfff));
- }
- memcpy(dbuf, cbuf + 2, len + 1);
- memset(dbuf + len + 1, 0, NTFS_COMPBLOCK_SIZE - 1 - len);
- return len + 3;
- }
- cpos = 2;
- pos = 0;
- while ((cpos < len + 3) && (pos < NTFS_COMPBLOCK_SIZE)) {
- ctag = cbuf[cpos++];
- for (i = 0; (i < 8) && (pos < NTFS_COMPBLOCK_SIZE); i++) {
- if (ctag & 1) {
- for (j = pos - 1, lmask = 0xFFF, dshift = 12;
- j >= 0x10; j >>= 1) {
- dshift--;
- lmask >>= 1;
- }
- boff = -1 - (GET_UINT16(cbuf + cpos) >> dshift);
- blen = 3 + (GET_UINT16(cbuf + cpos) & lmask);
- for (j = 0; (j < blen) && (pos < NTFS_COMPBLOCK_SIZE); j++) {
- dbuf[pos] = dbuf[pos + boff];
- pos++;
- }
- cpos += 2;
- } else {
- dbuf[pos++] = cbuf[cpos++];
- }
- ctag >>= 1;
- }
- }
- return len + 3;
-}
-
-int
-ntfs_uncompunit(
- struct ntfsmount * ntmp,
- u_int8_t * uup,
- u_int8_t * cup)
-{
- int i;
- int off = 0;
- int new;
-
- for (i = 0; i * NTFS_COMPBLOCK_SIZE < ntfs_cntob(NTFS_COMPUNIT_CL); i++) {
- new = ntfs_uncompblock(uup + i * NTFS_COMPBLOCK_SIZE, cup + off);
- if (new == 0)
- return (EINVAL);
- off += new;
- }
- return (0);
-}
diff --git a/sys/fs/ntfs/ntfs_compr.h b/sys/fs/ntfs/ntfs_compr.h
deleted file mode 100644
index e51bc09..0000000
--- a/sys/fs/ntfs/ntfs_compr.h
+++ /dev/null
@@ -1,35 +0,0 @@
-/* $NetBSD: ntfs_compr.h,v 1.3 1999/07/26 14:02:31 jdolecek Exp $ */
-
-/*-
- * Copyright (c) 1998, 1999 Semen Ustimenko
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * $FreeBSD$
- */
-
-#define NTFS_COMPBLOCK_SIZE 0x1000
-#define NTFS_COMPUNIT_CL 16
-
-int ntfs_uncompblock(u_int8_t *, u_int8_t *);
-int ntfs_uncompunit(struct ntfsmount *, u_int8_t *, u_int8_t *);
diff --git a/sys/fs/ntfs/ntfs_iconv.c b/sys/fs/ntfs/ntfs_iconv.c
deleted file mode 100644
index 347306e..0000000
--- a/sys/fs/ntfs/ntfs_iconv.c
+++ /dev/null
@@ -1,36 +0,0 @@
-/*-
- * Copyright (c) 2003 Ryuichiro Imura
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-#include <sys/cdefs.h>
-__FBSDID("$FreeBSD$");
-
-#include <sys/param.h>
-#include <sys/kernel.h>
-#include <sys/module.h>
-#include <sys/mount.h>
-#include <sys/iconv.h>
-
-VFS_DECLARE_ICONV(ntfs);
diff --git a/sys/fs/ntfs/ntfs_ihash.c b/sys/fs/ntfs/ntfs_ihash.c
deleted file mode 100644
index bb40d5c..0000000
--- a/sys/fs/ntfs/ntfs_ihash.c
+++ /dev/null
@@ -1,130 +0,0 @@
-/* $NetBSD: ntfs_ihash.c,v 1.5 1999/09/30 16:56:40 jdolecek Exp $ */
-
-/*-
- * Copyright (c) 1982, 1986, 1989, 1991, 1993, 1995
- * The Regents of the University of California. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * @(#)ufs_ihash.c 8.7 (Berkeley) 5/17/95
- * $FreeBSD$
- */
-
-#include <sys/param.h>
-#include <sys/systm.h>
-#include <sys/kernel.h>
-#include <sys/lock.h>
-#include <sys/vnode.h>
-#include <sys/malloc.h>
-#include <sys/mount.h>
-#include <sys/mutex.h>
-
-#include <fs/ntfs/ntfs.h>
-#include <fs/ntfs/ntfs_inode.h>
-#include <fs/ntfs/ntfs_ihash.h>
-
-MALLOC_DEFINE(M_NTFSNTHASH, "ntfs_nthash", "NTFS ntnode hash tables");
-
-/*
- * Structures associated with inode cacheing.
- */
-static LIST_HEAD(nthashhead, ntnode) *ntfs_nthashtbl;
-static u_long ntfs_nthash; /* size of hash table - 1 */
-#define NTNOHASH(inum) (&ntfs_nthashtbl[(inum) & ntfs_nthash])
-static struct mtx ntfs_nthash_mtx;
-struct lock ntfs_hashlock;
-
-/*
- * Initialize inode hash table.
- */
-void
-ntfs_nthashinit()
-{
- lockinit(&ntfs_hashlock, PINOD, "ntfs_nthashlock", 0, 0);
- ntfs_nthashtbl = hashinit(desiredvnodes, M_NTFSNTHASH, &ntfs_nthash);
- mtx_init(&ntfs_nthash_mtx, "ntfs nthash", NULL, MTX_DEF);
-}
-
-/*
- * Destroy inode hash table.
- */
-void
-ntfs_nthashdestroy(void)
-{
- hashdestroy(ntfs_nthashtbl, M_NTFSNTHASH, ntfs_nthash);
- lockdestroy(&ntfs_hashlock);
- mtx_destroy(&ntfs_nthash_mtx);
-}
-
-/*
- * Use the device/inum pair to find the incore inode, and return a pointer
- * to it. If it is in core, return it, even if it is locked.
- */
-struct ntnode *
-ntfs_nthashlookup(dev, inum)
- struct cdev *dev;
- ino_t inum;
-{
- struct ntnode *ip;
-
- mtx_lock(&ntfs_nthash_mtx);
- LIST_FOREACH(ip, NTNOHASH(inum), i_hash)
- if (inum == ip->i_number && dev == ip->i_dev)
- break;
- mtx_unlock(&ntfs_nthash_mtx);
-
- return (ip);
-}
-
-/*
- * Insert the ntnode into the hash table.
- */
-void
-ntfs_nthashins(ip)
- struct ntnode *ip;
-{
- struct nthashhead *ipp;
-
- mtx_lock(&ntfs_nthash_mtx);
- ipp = NTNOHASH(ip->i_number);
- LIST_INSERT_HEAD(ipp, ip, i_hash);
- ip->i_flag |= IN_HASHED;
- mtx_unlock(&ntfs_nthash_mtx);
-}
-
-/*
- * Remove the inode from the hash table.
- */
-void
-ntfs_nthashrem(ip)
- struct ntnode *ip;
-{
- mtx_lock(&ntfs_nthash_mtx);
- if (ip->i_flag & IN_HASHED) {
- ip->i_flag &= ~IN_HASHED;
- LIST_REMOVE(ip, i_hash);
- }
- mtx_unlock(&ntfs_nthash_mtx);
-}
diff --git a/sys/fs/ntfs/ntfs_ihash.h b/sys/fs/ntfs/ntfs_ihash.h
deleted file mode 100644
index 7df7495..0000000
--- a/sys/fs/ntfs/ntfs_ihash.h
+++ /dev/null
@@ -1,37 +0,0 @@
-/* $NetBSD: ntfs_ihash.h,v 1.4 1999/09/30 16:56:40 jdolecek Exp $ */
-
-/*-
- * Copyright (c) 1998, 1999 Semen Ustimenko
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * $FreeBSD$
- */
-
-extern struct lock ntfs_hashlock;
-void ntfs_nthashinit(void);
-void ntfs_nthashdestroy(void);
-struct ntnode *ntfs_nthashlookup(struct cdev *, ino_t);
-struct ntnode *ntfs_nthashget(struct cdev *, ino_t);
-void ntfs_nthashins(struct ntnode *);
-void ntfs_nthashrem(register struct ntnode *);
diff --git a/sys/fs/ntfs/ntfs_inode.h b/sys/fs/ntfs/ntfs_inode.h
deleted file mode 100644
index c11cfa1..0000000
--- a/sys/fs/ntfs/ntfs_inode.h
+++ /dev/null
@@ -1,101 +0,0 @@
-/* $NetBSD: ntfs_inode.h,v 1.8 1999/10/31 19:45:26 jdolecek Exp $ */
-
-/*-
- * Copyright (c) 1998, 1999 Semen Ustimenko
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * $FreeBSD$
- */
-
-/* These flags are kept in i_flag. */
-#define IN_ACCESS 0x0001 /* Access time update request. */
-#define IN_CHANGE 0x0002 /* Inode change time update request. */
-#define IN_UPDATE 0x0004 /* Modification time update request. */
-#define IN_MODIFIED 0x0008 /* Inode has been modified. */
-#define IN_RENAME 0x0010 /* Inode is being renamed. */
-#define IN_SHLOCK 0x0020 /* File has shared lock. */
-#define IN_EXLOCK 0x0040 /* File has exclusive lock. */
-#define IN_LAZYMOD 0x0080 /* Modified, but don't write yet. */
-#define IN_HASHED 0x0800 /* Inode is on hash list */
-#define IN_LOADED 0x8000 /* ntvattrs loaded */
-#define IN_PRELOADED 0x4000 /* loaded from directory entry */
-
-struct ntnode {
- struct vnode *i_devvp; /* vnode of blk dev we live on */
- struct cdev *i_dev; /* Device associated with the inode. */
-
- LIST_ENTRY(ntnode) i_hash;
- struct ntnode *i_next;
- struct ntnode **i_prev;
- struct ntfsmount *i_mp;
- ino_t i_number;
- u_int32_t i_flag;
-
- /* locking */
- struct lock i_lock;
- struct mtx i_interlock;
- int i_usecount;
-
- LIST_HEAD(,fnode) i_fnlist;
- LIST_HEAD(,ntvattr) i_valist;
-
- long i_nlink; /* MFR */
- ino_t i_mainrec; /* MFR */
- u_int32_t i_frflag; /* MFR */
-};
-
-#define FN_PRELOADED 0x0001
-#define FN_VALID 0x0002
-#define FN_AATTRNAME 0x0004 /* space allocated for f_attrname */
-struct fnode {
- LIST_ENTRY(fnode) f_fnlist;
- struct vnode *f_vp; /* Associatied vnode */
- struct ntnode *f_ip; /* Associated ntnode */
- u_long f_flag;
-
- ntfs_times_t f_times; /* $NAME/dirinfo */
- ino_t f_pnumber; /* $NAME/dirinfo */
- u_int32_t f_fflag; /* $NAME/dirinfo */
- u_int64_t f_size; /* defattr/dirinfo: */
- u_int64_t f_allocated; /* defattr/dirinfo */
-
- u_int32_t f_attrtype;
- char *f_attrname;
-
- /* for ntreaddir */
- u_int32_t f_lastdattr;
- u_int32_t f_lastdblnum;
- u_int32_t f_lastdoff;
- u_int32_t f_lastdnum;
- caddr_t f_dirblbuf;
- u_int32_t f_dirblsz;
-};
-
-/* This overlays the fid structure (see <sys/mount.h>) */
-struct ntfid {
- u_int16_t ntfid_len; /* Length of structure. */
- u_int16_t ntfid_pad; /* Force 32-bit alignment. */
- ino_t ntfid_ino; /* File number (ino). */
- int32_t ntfid_gen; /* Generation number. */
-};
diff --git a/sys/fs/ntfs/ntfs_subr.c b/sys/fs/ntfs/ntfs_subr.c
deleted file mode 100644
index dae7777..0000000
--- a/sys/fs/ntfs/ntfs_subr.c
+++ /dev/null
@@ -1,2029 +0,0 @@
-/* $NetBSD: ntfs_subr.c,v 1.23 1999/10/31 19:45:26 jdolecek Exp $ */
-
-/*-
- * Copyright (c) 1998, 1999 Semen Ustimenko (semenu@FreeBSD.org)
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * $FreeBSD$
- */
-
-#include <sys/param.h>
-#include <sys/types.h>
-#include <sys/systm.h>
-#include <sys/namei.h>
-#include <sys/kernel.h>
-#include <sys/vnode.h>
-#include <sys/mount.h>
-#include <sys/bio.h>
-#include <sys/buf.h>
-#include <sys/file.h>
-#include <sys/malloc.h>
-#include <sys/lock.h>
-#include <sys/iconv.h>
-
-/* #define NTFS_DEBUG 1 */
-#include <fs/ntfs/ntfs.h>
-#include <fs/ntfs/ntfsmount.h>
-#include <fs/ntfs/ntfs_inode.h>
-#include <fs/ntfs/ntfs_vfsops.h>
-#include <fs/ntfs/ntfs_subr.h>
-#include <fs/ntfs/ntfs_compr.h>
-#include <fs/ntfs/ntfs_ihash.h>
-
-static MALLOC_DEFINE(M_NTFSNTVATTR, "ntfs_vattr",
- "NTFS file attribute information");
-static MALLOC_DEFINE(M_NTFSRDATA, "ntfsd_resdata", "NTFS resident data");
-static MALLOC_DEFINE(M_NTFSRUN, "ntfs_vrun", "NTFS vrun storage");
-static MALLOC_DEFINE(M_NTFSDECOMP, "ntfs_decomp",
- "NTFS decompression temporary");
-
-static int ntfs_ntlookupattr(struct ntfsmount *, const char *, int, int *, char **);
-static int ntfs_findvattr(struct ntfsmount *, struct ntnode *, struct ntvattr **, struct ntvattr **, u_int32_t, const char *, size_t, cn_t);
-static int ntfs_uastricmp(struct ntfsmount *, const wchar *, size_t, const char *, size_t);
-static int ntfs_uastrcmp(struct ntfsmount *, const wchar *, size_t, const char *, size_t);
-
-/* table for mapping Unicode chars into uppercase; it's filled upon first
- * ntfs mount, freed upon last ntfs umount */
-static wchar *ntfs_toupper_tab;
-#define NTFS_TOUPPER(ch) (ntfs_toupper_tab[(ch)])
-static struct lock ntfs_toupper_lock;
-static signed int ntfs_toupper_usecount;
-
-struct iconv_functions *ntfs_iconv = NULL;
-
-/* support macro for ntfs_ntvattrget() */
-#define NTFS_AALPCMP(aalp,type,name,namelen) ( \
- (aalp->al_type == type) && (aalp->al_namelen == namelen) && \
- !NTFS_UASTRCMP(aalp->al_name,aalp->al_namelen,name,namelen) )
-
-/*
- *
- */
-int
-ntfs_ntvattrrele(vap)
- struct ntvattr * vap;
-{
- dprintf(("ntfs_ntvattrrele: ino: %ju, type: 0x%x\n",
- (uintmax_t)vap->va_ip->i_number, vap->va_type));
-
- ntfs_ntrele(vap->va_ip);
-
- return (0);
-}
-
-/*
- * find the attribute in the ntnode
- */
-static int
-ntfs_findvattr(ntmp, ip, lvapp, vapp, type, name, namelen, vcn)
- struct ntfsmount *ntmp;
- struct ntnode *ip;
- struct ntvattr **lvapp, **vapp;
- u_int32_t type;
- const char *name;
- size_t namelen;
- cn_t vcn;
-{
- int error;
- struct ntvattr *vap;
-
- if((ip->i_flag & IN_LOADED) == 0) {
- dprintf(("ntfs_findvattr: node not loaded, ino: %ju\n",
- (uintmax_t)ip->i_number));
- error = ntfs_loadntnode(ntmp,ip);
- if (error) {
- printf("ntfs_findvattr: FAILED TO LOAD INO: %ju\n",
- (uintmax_t)ip->i_number);
- return (error);
- }
- }
-
- *lvapp = NULL;
- *vapp = NULL;
- LIST_FOREACH(vap, &ip->i_valist, va_list) {
- ddprintf(("ntfs_findvattr: type: 0x%x, vcn: %d - %d\n", \
- vap->va_type, (u_int32_t) vap->va_vcnstart, \
- (u_int32_t) vap->va_vcnend));
- if ((vap->va_type == type) &&
- (vap->va_vcnstart <= vcn) && (vap->va_vcnend >= vcn) &&
- (vap->va_namelen == namelen) &&
- (strncmp(name, vap->va_name, namelen) == 0)) {
- *vapp = vap;
- ntfs_ntref(vap->va_ip);
- return (0);
- }
- if (vap->va_type == NTFS_A_ATTRLIST)
- *lvapp = vap;
- }
-
- return (-1);
-}
-
-/*
- * Search attribute specifed in ntnode (load ntnode if nessecary).
- * If not found but ATTR_A_ATTRLIST present, read it in and search throught.
- * VOP_VGET node needed, and lookup througth it's ntnode (load if nessesary).
- *
- * ntnode should be locked
- */
-int
-ntfs_ntvattrget(
- struct ntfsmount * ntmp,
- struct ntnode * ip,
- u_int32_t type,
- const char *name,
- cn_t vcn,
- struct ntvattr ** vapp)
-{
- struct ntvattr *lvap = NULL;
- struct attr_attrlist *aalp;
- struct attr_attrlist *nextaalp;
- struct vnode *newvp;
- struct ntnode *newip;
- caddr_t alpool;
- size_t namelen, len;
- int error;
-
- *vapp = NULL;
-
- if (name) {
- dprintf(("ntfs_ntvattrget: " \
- "ino: %ju, type: 0x%x, name: %s, vcn: %d\n", \
- (uintmax_t)ip->i_number, type, name, (uint32_t)vcn));
- namelen = strlen(name);
- } else {
- dprintf(("ntfs_ntvattrget: " \
- "ino: %ju, type: 0x%x, vcn: %d\n", \
- (uintmax_t)ip->i_number, type, (uint32_t)vcn));
- name = "";
- namelen = 0;
- }
-
- error = ntfs_findvattr(ntmp, ip, &lvap, vapp, type, name, namelen, vcn);
- if (error >= 0)
- return (error);
-
- if (!lvap) {
- dprintf(("ntfs_ntvattrget: UNEXISTED ATTRIBUTE: " \
- "ino: %ju, type: 0x%x, name: %s, vcn: %d\n", \
- (uintmax_t)ip->i_number, type, name, (uint32_t)vcn));
- return (ENOENT);
- }
- /* Scan $ATTRIBUTE_LIST for requested attribute */
- len = lvap->va_datalen;
- alpool = malloc(len, M_TEMP, M_WAITOK);
- error = ntfs_readntvattr_plain(ntmp, ip, lvap, 0, len, alpool, &len,
- NULL);
- if (error)
- goto out;
-
- aalp = (struct attr_attrlist *) alpool;
- nextaalp = NULL;
-
- for(; len > 0; aalp = nextaalp) {
- dprintf(("ntfs_ntvattrget: " \
- "attrlist: ino: %ju, attr: 0x%x, vcn: %d\n", \
- (uintmax_t)aalp->al_inumber, aalp->al_type, \
- (uint32_t)aalp->al_vcnstart));
-
- if (len > aalp->reclen) {
- nextaalp = NTFS_NEXTREC(aalp, struct attr_attrlist *);
- } else {
- nextaalp = NULL;
- }
- len -= aalp->reclen;
-
- if (!NTFS_AALPCMP(aalp, type, name, namelen) ||
- (nextaalp && (nextaalp->al_vcnstart <= vcn) &&
- NTFS_AALPCMP(nextaalp, type, name, namelen)))
- continue;
-
- dprintf(("ntfs_ntvattrget: attribute in ino: %ju\n",
- (uintmax_t)aalp->al_inumber));
-
- /* this is not a main record, so we can't use just plain
- vget() */
- error = ntfs_vgetex(ntmp->ntm_mountp, aalp->al_inumber,
- NTFS_A_DATA, NULL, LK_EXCLUSIVE,
- VG_EXT, curthread, &newvp);
- if (error) {
- printf("ntfs_ntvattrget: CAN'T VGET INO: %ju\n",
- (uintmax_t)aalp->al_inumber);
- goto out;
- }
- newip = VTONT(newvp);
- /* XXX have to lock ntnode */
- error = ntfs_findvattr(ntmp, newip, &lvap, vapp,
- type, name, namelen, vcn);
- vput(newvp);
- if (error == 0)
- goto out;
- printf("ntfs_ntvattrget: ATTRLIST ERROR.\n");
- break;
- }
- error = ENOENT;
-
- dprintf(("ntfs_ntvattrget: UNEXISTED ATTRIBUTE: " \
- "ino: %ju, type: 0x%x, name: %.*s, vcn: %d\n", \
- (uintmax_t)ip->i_number, type, (int)namelen, name, (uint32_t)vcn));
-out:
- free(alpool, M_TEMP);
- return (error);
-}
-
-/*
- * Read ntnode from disk, make ntvattr list.
- *
- * ntnode should be locked
- */
-int
-ntfs_loadntnode(
- struct ntfsmount * ntmp,
- struct ntnode * ip)
-{
- struct filerec *mfrp;
- daddr_t bn;
- int error,off;
- struct attr *ap;
- struct ntvattr *nvap;
-
- dprintf(("ntfs_loadntnode: loading ino: %ju\n",
- (uintmax_t)ip->i_number));
-
- mfrp = malloc(ntfs_bntob(ntmp->ntm_bpmftrec),
- M_TEMP, M_WAITOK);
-
- if (ip->i_number < NTFS_SYSNODESNUM) {
- struct buf *bp;
-
- dprintf(("ntfs_loadntnode: read system node\n"));
-
- bn = ntfs_cntobn(ntmp->ntm_mftcn) +
- ntmp->ntm_bpmftrec * ip->i_number;
- bn *= ntmp->ntm_multiplier;
-
- error = bread(ntmp->ntm_devvp,
- bn, ntfs_bntob(ntmp->ntm_bpmftrec),
- NOCRED, &bp);
- if (error) {
- printf("ntfs_loadntnode: BREAD FAILED\n");
- brelse(bp);
- goto out;
- }
- memcpy(mfrp, bp->b_data, ntfs_bntob(ntmp->ntm_bpmftrec));
- bqrelse(bp);
- } else {
- struct vnode *vp;
-
- vp = ntmp->ntm_sysvn[NTFS_MFTINO];
- error = ntfs_readattr(ntmp, VTONT(vp), NTFS_A_DATA, NULL,
- ip->i_number * ntfs_bntob(ntmp->ntm_bpmftrec),
- ntfs_bntob(ntmp->ntm_bpmftrec), mfrp, NULL);
- if (error) {
- printf("ntfs_loadntnode: ntfs_readattr failed\n");
- goto out;
- }
- }
-
- /* Check if magic and fixups are correct */
- error = ntfs_procfixups(ntmp, NTFS_FILEMAGIC, (caddr_t)mfrp,
- ntfs_bntob(ntmp->ntm_bpmftrec));
- if (error) {
- printf("ntfs_loadntnode: BAD MFT RECORD %ju\n",
- (uintmax_t)ip->i_number);
- goto out;
- }
-
- dprintf(("ntfs_loadntnode: load attrs for ino: %ju\n",
- (uintmax_t)ip->i_number));
- off = mfrp->fr_attroff;
- ap = (struct attr *) ((caddr_t)mfrp + off);
-
- LIST_INIT(&ip->i_valist);
-
- while (ap->a_hdr.a_type != -1) {
- error = ntfs_attrtontvattr(ntmp, &nvap, ap);
- if (error)
- break;
- nvap->va_ip = ip;
-
- LIST_INSERT_HEAD(&ip->i_valist, nvap, va_list);
-
- off += ap->a_hdr.reclen;
- ap = (struct attr *) ((caddr_t)mfrp + off);
- }
- if (error) {
- printf("ntfs_loadntnode: failed to load attr ino: %ju\n",
- (uintmax_t)ip->i_number);
- goto out;
- }
-
- ip->i_mainrec = mfrp->fr_mainrec;
- ip->i_nlink = mfrp->fr_nlink;
- ip->i_frflag = mfrp->fr_flags;
-
- ip->i_flag |= IN_LOADED;
-
-out:
- free(mfrp, M_TEMP);
- return (error);
-}
-
-/*
- * Routine locks ntnode and increase usecount, just opposite of
- * ntfs_ntput().
- */
-int
-ntfs_ntget(ip)
- struct ntnode *ip;
-{
- dprintf(("ntfs_ntget: get ntnode %ju: %p, usecount: %d\n",
- (uintmax_t)ip->i_number, ip, ip->i_usecount));
-
- mtx_lock(&ip->i_interlock);
- ip->i_usecount++;
- lockmgr(&ip->i_lock, LK_EXCLUSIVE | LK_INTERLOCK, &ip->i_interlock);
-
- return 0;
-}
-
-/*
- * Routine search ntnode in hash, if found: lock, inc usecount and return.
- * If not in hash allocate structure for ntnode, prefill it, lock,
- * inc count and return.
- *
- * ntnode returned locked
- */
-int
-ntfs_ntlookup(
- struct ntfsmount * ntmp,
- ino_t ino,
- struct ntnode ** ipp)
-{
- struct ntnode *ip;
-
- dprintf(("ntfs_ntlookup: looking for ntnode %d\n", ino));
-
- do {
- ip = ntfs_nthashlookup(ntmp->ntm_devvp->v_rdev, ino);
- if (ip != NULL) {
- ntfs_ntget(ip);
- dprintf(("ntfs_ntlookup: ntnode %d: %p, usecount: %d\n",
- ino, ip, ip->i_usecount));
- *ipp = ip;
- return (0);
- }
- } while (lockmgr(&ntfs_hashlock, LK_EXCLUSIVE | LK_SLEEPFAIL, NULL));
-
- ip = malloc(sizeof(struct ntnode), M_NTFSNTNODE,
- M_WAITOK | M_ZERO);
- ddprintf(("ntfs_ntlookup: allocating ntnode: %d: %p\n", ino, ip));
-
- /* Generic initialization */
- ip->i_devvp = ntmp->ntm_devvp;
- ip->i_dev = ntmp->ntm_devvp->v_rdev;
- ip->i_number = ino;
- ip->i_mp = ntmp;
-
- LIST_INIT(&ip->i_fnlist);
- VREF(ip->i_devvp);
-
- /* init lock and lock the newborn ntnode */
- lockinit(&ip->i_lock, PINOD, "ntnode", 0, 0);
- mtx_init(&ip->i_interlock, "ntnode interlock", NULL, MTX_DEF);
- ntfs_ntget(ip);
-
- ntfs_nthashins(ip);
-
- lockmgr(&ntfs_hashlock, LK_RELEASE, NULL);
-
- *ipp = ip;
-
- dprintf(("ntfs_ntlookup: ntnode %d: %p, usecount: %d\n",
- ino, ip, ip->i_usecount));
-
- return (0);
-}
-
-/*
- * Decrement usecount of ntnode and unlock it, if usecount reach zero,
- * deallocate ntnode.
- *
- * ntnode should be locked on entry, and unlocked on return.
- */
-void
-ntfs_ntput(ip)
- struct ntnode *ip;
-{
- struct ntvattr *vap;
-
- dprintf(("ntfs_ntput: rele ntnode %ju: %p, usecount: %d\n",
- (uintmax_t)ip->i_number, ip, ip->i_usecount));
-
- mtx_lock(&ip->i_interlock);
- ip->i_usecount--;
-
-#ifdef DIAGNOSTIC
- if (ip->i_usecount < 0) {
- panic("ntfs_ntput: ino: %ju usecount: %d \n",
- (uintmax_t)ip->i_number, ip->i_usecount);
- }
-#endif
-
- if (ip->i_usecount > 0) {
- lockmgr(&ip->i_lock, LK_RELEASE|LK_INTERLOCK, &ip->i_interlock);
- return;
- }
-
- dprintf(("ntfs_ntput: deallocating ntnode: %ju\n",
- (uintmax_t)ip->i_number));
-
- if (LIST_FIRST(&ip->i_fnlist))
- panic("ntfs_ntput: ntnode has fnodes\n");
-
- ntfs_nthashrem(ip);
-
- while ((vap = LIST_FIRST(&ip->i_valist)) != NULL) {
- LIST_REMOVE(vap,va_list);
- ntfs_freentvattr(vap);
- }
- lockmgr(&ip->i_lock, LK_RELEASE | LK_INTERLOCK, &ip->i_interlock);
- mtx_destroy(&ip->i_interlock);
- lockdestroy(&ip->i_lock);
- vrele(ip->i_devvp);
- free(ip, M_NTFSNTNODE);
-}
-
-/*
- * increment usecount of ntnode
- */
-void
-ntfs_ntref(ip)
- struct ntnode *ip;
-{
- mtx_lock(&ip->i_interlock);
- ip->i_usecount++;
- mtx_unlock(&ip->i_interlock);
-
- dprintf(("ntfs_ntref: ino %ju, usecount: %d\n",
- (uintmax_t)ip->i_number, ip->i_usecount));
-}
-
-/*
- * Decrement usecount of ntnode.
- */
-void
-ntfs_ntrele(ip)
- struct ntnode *ip;
-{
- dprintf(("ntfs_ntrele: rele ntnode %ju: %p, usecount: %d\n",
- (uintmax_t)ip->i_number, ip, ip->i_usecount));
-
- mtx_lock(&ip->i_interlock);
- ip->i_usecount--;
-
- if (ip->i_usecount < 0)
- panic("ntfs_ntrele: ino: %ju usecount: %d \n",
- (uintmax_t)ip->i_number, ip->i_usecount);
- mtx_unlock(&ip->i_interlock);
-}
-
-/*
- * Deallocate all memory allocated for ntvattr
- */
-void
-ntfs_freentvattr(vap)
- struct ntvattr * vap;
-{
- if (vap->va_flag & NTFS_AF_INRUN) {
- if (vap->va_vruncn)
- free(vap->va_vruncn, M_NTFSRUN);
- if (vap->va_vruncl)
- free(vap->va_vruncl, M_NTFSRUN);
- } else {
- if (vap->va_datap)
- free(vap->va_datap, M_NTFSRDATA);
- }
- free(vap, M_NTFSNTVATTR);
-}
-
-/*
- * Convert disk image of attribute into ntvattr structure,
- * runs are expanded also.
- */
-int
-ntfs_attrtontvattr(
- struct ntfsmount * ntmp,
- struct ntvattr ** rvapp,
- struct attr * rap)
-{
- int error, i;
- struct ntvattr *vap;
-
- error = 0;
- *rvapp = NULL;
-
- vap = malloc(sizeof(struct ntvattr),
- M_NTFSNTVATTR, M_WAITOK | M_ZERO);
- vap->va_ip = NULL;
- vap->va_flag = rap->a_hdr.a_flag;
- vap->va_type = rap->a_hdr.a_type;
- vap->va_compression = rap->a_hdr.a_compression;
- vap->va_index = rap->a_hdr.a_index;
-
- ddprintf(("type: 0x%x, index: %d", vap->va_type, vap->va_index));
-
- vap->va_namelen = rap->a_hdr.a_namelen;
- if (rap->a_hdr.a_namelen) {
- wchar *unp = (wchar *) ((caddr_t) rap + rap->a_hdr.a_nameoff);
- ddprintf((", name:["));
- for (i = 0; i < vap->va_namelen; i++) {
- vap->va_name[i] = unp[i];
- ddprintf(("%c", vap->va_name[i]));
- }
- ddprintf(("]"));
- }
- if (vap->va_flag & NTFS_AF_INRUN) {
- ddprintf((", nonres."));
- vap->va_datalen = rap->a_nr.a_datalen;
- vap->va_allocated = rap->a_nr.a_allocated;
- vap->va_vcnstart = rap->a_nr.a_vcnstart;
- vap->va_vcnend = rap->a_nr.a_vcnend;
- vap->va_compressalg = rap->a_nr.a_compressalg;
- error = ntfs_runtovrun(&(vap->va_vruncn), &(vap->va_vruncl),
- &(vap->va_vruncnt),
- (caddr_t) rap + rap->a_nr.a_dataoff);
- } else {
- vap->va_compressalg = 0;
- ddprintf((", res."));
- vap->va_datalen = rap->a_r.a_datalen;
- vap->va_allocated = rap->a_r.a_datalen;
- vap->va_vcnstart = 0;
- vap->va_vcnend = ntfs_btocn(vap->va_allocated);
- vap->va_datap = malloc(vap->va_datalen,
- M_NTFSRDATA, M_WAITOK);
- memcpy(vap->va_datap, (caddr_t) rap + rap->a_r.a_dataoff,
- rap->a_r.a_datalen);
- }
- ddprintf((", len: %lld", vap->va_datalen));
-
- if (error)
- free(vap, M_NTFSNTVATTR);
- else
- *rvapp = vap;
-
- ddprintf(("\n"));
-
- return (error);
-}
-
-/*
- * Expand run into more utilizable and more memory eating format.
- */
-int
-ntfs_runtovrun(
- cn_t ** rcnp,
- cn_t ** rclp,
- u_long * rcntp,
- u_int8_t * run)
-{
- u_int32_t off;
- u_int32_t sz, i;
- cn_t *cn;
- cn_t *cl;
- u_long cnt;
- cn_t prev;
- cn_t tmp;
-
- off = 0;
- cnt = 0;
- i = 0;
- while (run[off]) {
- off += (run[off] & 0xF) + ((run[off] >> 4) & 0xF) + 1;
- cnt++;
- }
- cn = malloc(cnt * sizeof(cn_t), M_NTFSRUN, M_WAITOK);
- cl = malloc(cnt * sizeof(cn_t), M_NTFSRUN, M_WAITOK);
-
- off = 0;
- cnt = 0;
- prev = 0;
- while (run[off]) {
-
- sz = run[off++];
- cl[cnt] = 0;
-
- for (i = 0; i < (sz & 0xF); i++)
- cl[cnt] += (u_int32_t) run[off++] << (i << 3);
-
- sz >>= 4;
- if (run[off + sz - 1] & 0x80) {
- tmp = ((u_int64_t) - 1) << (sz << 3);
- for (i = 0; i < sz; i++)
- tmp |= (u_int64_t) run[off++] << (i << 3);
- } else {
- tmp = 0;
- for (i = 0; i < sz; i++)
- tmp |= (u_int64_t) run[off++] << (i << 3);
- }
- if (tmp)
- prev = cn[cnt] = prev + tmp;
- else
- cn[cnt] = tmp;
-
- cnt++;
- }
- *rcnp = cn;
- *rclp = cl;
- *rcntp = cnt;
- return (0);
-}
-
-/*
- * Compare unicode and ascii string case insens.
- */
-static int
-ntfs_uastricmp(ntmp, ustr, ustrlen, astr, astrlen)
- struct ntfsmount *ntmp;
- const wchar *ustr;
- size_t ustrlen;
- const char *astr;
- size_t astrlen;
-{
- const char *astrp = astr;
- char tmpbuf[5];
- int len, res;
- size_t i, j, mbstrlen = astrlen;
-
- if (ntmp->ntm_ic_l2u) {
- for (i = 0, j = 0; i < ustrlen && j < astrlen; i++) {
- len = 4;
- res = ((int) NTFS_TOUPPER(ustr[i])) -
- ((int)NTFS_TOUPPER(NTFS_82U(astrp, &len)));
- astrp += len;
- j += len;
- mbstrlen -= len - 1;
-
- if (res)
- return res;
- }
- } else {
- /*
- * We use NTFS_82U(NTFS_U28(c)) to get rid of unicode
- * symbols not covered by translation table
- */
- for (i = 0; i < ustrlen && i < astrlen; i++) {
- res = ((int) NTFS_TOUPPER(NTFS_82U(NTFS_U28(ustr[i]), &len))) -
- ((int)NTFS_TOUPPER(NTFS_82U(astrp, &len)));
- astrp++;
- if (res)
- return res;
- }
- }
- return (ustrlen - mbstrlen);
-}
-
-/*
- * Compare unicode and ascii string case sens.
- */
-static int
-ntfs_uastrcmp(ntmp, ustr, ustrlen, astr, astrlen)
- struct ntfsmount *ntmp;
- const wchar *ustr;
- size_t ustrlen;
- const char *astr;
- size_t astrlen;
-{
- char *c, tmpbuf[5];
- size_t i, j, mbstrlen = astrlen;
- int res;
-
- for (i = 0, j = 0; (i < ustrlen) && (j < astrlen); i++, mbstrlen++) {
- c = NTFS_U28(ustr[i]);
- while (*c != '\0') {
- res = (int) (*c++ - astr[j++]);
- if (res)
- return res;
- mbstrlen--;
- }
- }
- return (ustrlen - mbstrlen);
-}
-
-/*
- * Search fnode in ntnode, if not found allocate and preinitialize.
- *
- * ntnode should be locked on entry.
- */
-int
-ntfs_fget(
- struct ntfsmount *ntmp,
- struct ntnode *ip,
- int attrtype,
- char *attrname,
- struct fnode **fpp)
-{
- struct fnode *fp;
-
- dprintf(("ntfs_fget: ino: %ju, attrtype: 0x%x, attrname: %s\n",
- (uintmax_t)ip->i_number, attrtype, attrname ? attrname : ""));
- *fpp = NULL;
- LIST_FOREACH(fp, &ip->i_fnlist, f_fnlist){
- dprintf(("ntfs_fget: fnode: attrtype: %d, attrname: %s\n",
- fp->f_attrtype, fp->f_attrname?fp->f_attrname:""));
-
- if ((attrtype == fp->f_attrtype) &&
- ((!attrname && !fp->f_attrname) ||
- (attrname && fp->f_attrname &&
- !strcmp(attrname,fp->f_attrname)))){
- dprintf(("ntfs_fget: found existed: %p\n",fp));
- *fpp = fp;
- }
- }
-
- if (*fpp)
- return (0);
-
- fp = malloc(sizeof(struct fnode), M_NTFSFNODE,
- M_WAITOK | M_ZERO);
- dprintf(("ntfs_fget: allocating fnode: %p\n",fp));
-
- fp->f_ip = ip;
- if (attrname) {
- fp->f_flag |= FN_AATTRNAME;
- fp->f_attrname = malloc(strlen(attrname)+1, M_TEMP, M_WAITOK);
- strcpy(fp->f_attrname, attrname);
- } else
- fp->f_attrname = NULL;
- fp->f_attrtype = attrtype;
-
- ntfs_ntref(ip);
-
- LIST_INSERT_HEAD(&ip->i_fnlist, fp, f_fnlist);
-
- *fpp = fp;
-
- return (0);
-}
-
-/*
- * Deallocate fnode, remove it from ntnode's fnode list.
- *
- * ntnode should be locked.
- */
-void
-ntfs_frele(
- struct fnode *fp)
-{
- struct ntnode *ip = FTONT(fp);
-
- dprintf(("ntfs_frele: fnode: %p for %ju: %p\n",
- fp, (uintmax_t)ip->i_number, ip));
-
- dprintf(("ntfs_frele: deallocating fnode\n"));
- LIST_REMOVE(fp,f_fnlist);
- if (fp->f_flag & FN_AATTRNAME)
- free(fp->f_attrname, M_TEMP);
- if (fp->f_dirblbuf)
- free(fp->f_dirblbuf, M_NTFSDIR);
- free(fp, M_NTFSFNODE);
- ntfs_ntrele(ip);
-}
-
-/*
- * Lookup attribute name in format: [[:$ATTR_TYPE]:$ATTR_NAME],
- * $ATTR_TYPE is searched in attrdefs read from $AttrDefs.
- * If $ATTR_TYPE nott specifed, ATTR_A_DATA assumed.
- */
-static int
-ntfs_ntlookupattr(
- struct ntfsmount * ntmp,
- const char * name,
- int namelen,
- int *attrtype,
- char **attrname)
-{
- const char *sys;
- size_t syslen, i;
- struct ntvattrdef *adp;
-
- if (namelen == 0)
- return (0);
-
- if (name[0] == '$') {
- sys = name;
- for (syslen = 0; syslen < namelen; syslen++) {
- if(sys[syslen] == ':') {
- name++;
- namelen--;
- break;
- }
- }
- name += syslen;
- namelen -= syslen;
-
- adp = ntmp->ntm_ad;
- for (i = 0; i < ntmp->ntm_adnum; i++, adp++){
- if (syslen != adp->ad_namelen ||
- strncmp(sys, adp->ad_name, syslen) != 0)
- continue;
-
- *attrtype = adp->ad_type;
- goto out;
- }
- return (ENOENT);
- } else
- *attrtype = NTFS_A_DATA;
-
- out:
- if (namelen) {
- (*attrname) = malloc(namelen, M_TEMP, M_WAITOK);
- memcpy((*attrname), name, namelen);
- (*attrname)[namelen] = '\0';
- }
-
- return (0);
-}
-
-/*
- * Lookup specifed node for filename, matching cnp,
- * return fnode filled.
- */
-int
-ntfs_ntlookupfile(
- struct ntfsmount * ntmp,
- struct vnode * vp,
- struct componentname * cnp,
- struct vnode ** vpp)
-{
- struct fnode *fp = VTOF(vp);
- struct ntnode *ip = FTONT(fp);
- struct ntvattr *vap; /* Root attribute */
- cn_t cn; /* VCN in current attribute */
- caddr_t rdbuf; /* Buffer to read directory's blocks */
- u_int32_t blsize;
- u_int64_t rdsize; /* Length of data to read from current block */
- struct attr_indexentry *iep;
- int error, res, anamelen, fnamelen;
- const char *fname,*aname;
- u_int32_t aoff;
- int attrtype = NTFS_A_DATA;
- char *attrname = NULL;
- struct fnode *nfp;
- struct vnode *nvp;
- enum vtype f_type;
-
- error = ntfs_ntget(ip);
- if (error)
- return (error);
-
- error = ntfs_ntvattrget(ntmp, ip, NTFS_A_INDXROOT, "$I30", 0, &vap);
- if (error || (vap->va_flag & NTFS_AF_INRUN))
- return (ENOTDIR);
-
- blsize = vap->va_a_iroot->ir_size;
- rdsize = vap->va_datalen;
-
- /*
- * Divide file name into: foofilefoofilefoofile[:attrspec]
- * Store like this: fname:fnamelen [aname:anamelen]
- */
- fname = cnp->cn_nameptr;
- aname = NULL;
- anamelen = 0;
- for (fnamelen = 0; fnamelen < cnp->cn_namelen; fnamelen++)
- if(fname[fnamelen] == ':') {
- aname = fname + fnamelen + 1;
- anamelen = cnp->cn_namelen - fnamelen - 1;
- dprintf(("ntfs_ntlookupfile: %s (%d), attr: %s (%d)\n",
- fname, fnamelen, aname, anamelen));
- break;
- }
-
- dprintf(("ntfs_ntlookupfile: blksz: %d, rdsz: %jd\n", blsize, rdsize));
-
- rdbuf = malloc(blsize, M_TEMP, M_WAITOK);
-
- error = ntfs_readattr(ntmp, ip, NTFS_A_INDXROOT, "$I30",
- 0, rdsize, rdbuf, NULL);
- if (error)
- goto fail;
-
- aoff = sizeof(struct attr_indexroot);
-
- do {
- iep = (struct attr_indexentry *) (rdbuf + aoff);
-
- for (; !(iep->ie_flag & NTFS_IEFLAG_LAST) && (rdsize > aoff);
- aoff += iep->reclen,
- iep = (struct attr_indexentry *) (rdbuf + aoff))
- {
- ddprintf(("scan: %d, %d\n",
- (u_int32_t) iep->ie_number,
- (u_int32_t) iep->ie_fnametype));
-
- /* check the name - the case-insensitible check
- * has to come first, to break from this for loop
- * if needed, so we can dive correctly */
- res = NTFS_UASTRICMP(iep->ie_fname, iep->ie_fnamelen,
- fname, fnamelen);
- if (res > 0) break;
- if (res < 0) continue;
-
- if (iep->ie_fnametype == 0 ||
- !(ntmp->ntm_flag & NTFS_MFLAG_CASEINS))
- {
- res = NTFS_UASTRCMP(iep->ie_fname,
- iep->ie_fnamelen, fname, fnamelen);
- if (res != 0) continue;
- }
-
- if (aname) {
- error = ntfs_ntlookupattr(ntmp,
- aname, anamelen,
- &attrtype, &attrname);
- if (error)
- goto fail;
- }
-
- /* Check if we've found ourself */
- if ((iep->ie_number == ip->i_number) &&
- (attrtype == fp->f_attrtype) &&
- ((!attrname && !fp->f_attrname) ||
- (attrname && fp->f_attrname &&
- !strcmp(attrname, fp->f_attrname))))
- {
- VREF(vp);
- *vpp = vp;
- error = 0;
- goto fail;
- }
-
- /* vget node, but don't load it */
- error = ntfs_vgetex(ntmp->ntm_mountp,
- iep->ie_number, attrtype, attrname,
- LK_EXCLUSIVE, VG_DONTLOADIN | VG_DONTVALIDFN,
- curthread, &nvp);
-
- /* free the buffer returned by ntfs_ntlookupattr() */
- if (attrname) {
- free(attrname, M_TEMP);
- attrname = NULL;
- }
-
- if (error)
- goto fail;
-
- nfp = VTOF(nvp);
-
- if (nfp->f_flag & FN_VALID) {
- *vpp = nvp;
- goto fail;
- }
-
- nfp->f_fflag = iep->ie_fflag;
- nfp->f_pnumber = iep->ie_fpnumber;
- nfp->f_times = iep->ie_ftimes;
-
- if((nfp->f_fflag & NTFS_FFLAG_DIR) &&
- (nfp->f_attrtype == NTFS_A_DATA) &&
- (nfp->f_attrname == NULL))
- f_type = VDIR;
- else
- f_type = VREG;
-
- nvp->v_type = f_type;
-
- if ((nfp->f_attrtype == NTFS_A_DATA) &&
- (nfp->f_attrname == NULL))
- {
- /* Opening default attribute */
- nfp->f_size = iep->ie_fsize;
- nfp->f_allocated = iep->ie_fallocated;
- nfp->f_flag |= FN_PRELOADED;
- } else {
- error = ntfs_filesize(ntmp, nfp,
- &nfp->f_size, &nfp->f_allocated);
- if (error) {
- vput(nvp);
- goto fail;
- }
- }
-
- nfp->f_flag &= ~FN_VALID;
- *vpp = nvp;
- goto fail;
- }
-
- /* Dive if possible */
- if (iep->ie_flag & NTFS_IEFLAG_SUBNODE) {
- dprintf(("ntfs_ntlookupfile: diving\n"));
-
- cn = *(cn_t *) (rdbuf + aoff +
- iep->reclen - sizeof(cn_t));
- rdsize = blsize;
-
- error = ntfs_readattr(ntmp, ip, NTFS_A_INDX, "$I30",
- ntfs_cntob(cn), rdsize, rdbuf, NULL);
- if (error)
- goto fail;
-
- error = ntfs_procfixups(ntmp, NTFS_INDXMAGIC,
- rdbuf, rdsize);
- if (error)
- goto fail;
-
- aoff = (((struct attr_indexalloc *) rdbuf)->ia_hdrsize +
- 0x18);
- } else {
- dprintf(("ntfs_ntlookupfile: nowhere to dive :-(\n"));
- error = ENOENT;
- break;
- }
- } while (1);
-
- dprintf(("finish\n"));
-
-fail:
- if (attrname) free(attrname, M_TEMP);
- ntfs_ntvattrrele(vap);
- ntfs_ntput(ip);
- free(rdbuf, M_TEMP);
- return (error);
-}
-
-/*
- * Check if name type is permitted to show.
- */
-int
-ntfs_isnamepermitted(
- struct ntfsmount * ntmp,
- struct attr_indexentry * iep)
-{
- if (ntmp->ntm_flag & NTFS_MFLAG_ALLNAMES)
- return 1;
-
- switch (iep->ie_fnametype) {
- case 2:
- ddprintf(("ntfs_isnamepermitted: skipped DOS name\n"));
- return 0;
- case 0: case 1: case 3:
- return 1;
- default:
- printf("ntfs_isnamepermitted: " \
- "WARNING! Unknown file name type: %d\n",
- iep->ie_fnametype);
- break;
- }
- return 0;
-}
-
-/*
- * Read ntfs dir like stream of attr_indexentry, not like btree of them.
- * This is done by scaning $BITMAP:$I30 for busy clusters and reading them.
- * Ofcouse $INDEX_ROOT:$I30 is read before. Last read values are stored in
- * fnode, so we can skip toward record number num almost immediatly.
- * Anyway this is rather slow routine. The problem is that we don't know
- * how many records are there in $INDEX_ALLOCATION:$I30 block.
- */
-int
-ntfs_ntreaddir(
- struct ntfsmount * ntmp,
- struct fnode * fp,
- u_int32_t num,
- struct attr_indexentry ** riepp)
-{
- struct ntnode *ip = FTONT(fp);
- struct ntvattr *vap = NULL; /* IndexRoot attribute */
- struct ntvattr *bmvap = NULL; /* BitMap attribute */
- struct ntvattr *iavap = NULL; /* IndexAllocation attribute */
- caddr_t rdbuf; /* Buffer to read directory's blocks */
- u_int8_t *bmp = NULL; /* Bitmap */
- u_int32_t blsize; /* Index allocation size (2048) */
- u_int32_t rdsize; /* Length of data to read */
- u_int32_t attrnum; /* Current attribute type */
- u_int32_t cpbl = 1; /* Clusters per directory block */
- u_int32_t blnum;
- struct attr_indexentry *iep;
- int error = ENOENT;
- u_int32_t aoff, cnum;
-
- dprintf(("ntfs_ntreaddir: read ino: %ju, num: %d\n",
- (uintmax_t)ip->i_number, num));
- error = ntfs_ntget(ip);
- if (error)
- return (error);
-
- error = ntfs_ntvattrget(ntmp, ip, NTFS_A_INDXROOT, "$I30", 0, &vap);
- if (error)
- return (ENOTDIR);
-
- if (fp->f_dirblbuf == NULL) {
- fp->f_dirblsz = vap->va_a_iroot->ir_size;
- fp->f_dirblbuf = malloc(max(vap->va_datalen,fp->f_dirblsz),
- M_NTFSDIR, M_WAITOK);
- }
-
- blsize = fp->f_dirblsz;
- rdbuf = fp->f_dirblbuf;
-
- dprintf(("ntfs_ntreaddir: rdbuf: %p, blsize: %d\n", rdbuf, blsize));
-
- if (vap->va_a_iroot->ir_flag & NTFS_IRFLAG_INDXALLOC) {
- error = ntfs_ntvattrget(ntmp, ip, NTFS_A_INDXBITMAP, "$I30",
- 0, &bmvap);
- if (error) {
- error = ENOTDIR;
- goto fail;
- }
- bmp = malloc(bmvap->va_datalen, M_TEMP, M_WAITOK);
- error = ntfs_readattr(ntmp, ip, NTFS_A_INDXBITMAP, "$I30", 0,
- bmvap->va_datalen, bmp, NULL);
- if (error)
- goto fail;
-
- error = ntfs_ntvattrget(ntmp, ip, NTFS_A_INDX, "$I30",
- 0, &iavap);
- if (error) {
- error = ENOTDIR;
- goto fail;
- }
- cpbl = ntfs_btocn(blsize + ntfs_cntob(1) - 1);
- dprintf(("ntfs_ntreaddir: indexalloc: %jd, cpbl: %d\n",
- iavap->va_datalen, cpbl));
- } else {
- dprintf(("ntfs_ntreadidir: w/o BitMap and IndexAllocation\n"));
- iavap = bmvap = NULL;
- bmp = NULL;
- }
-
- /* Try use previous values */
- if ((fp->f_lastdnum < num) && (fp->f_lastdnum != 0)) {
- attrnum = fp->f_lastdattr;
- aoff = fp->f_lastdoff;
- blnum = fp->f_lastdblnum;
- cnum = fp->f_lastdnum;
- } else {
- attrnum = NTFS_A_INDXROOT;
- aoff = sizeof(struct attr_indexroot);
- blnum = 0;
- cnum = 0;
- }
-
- do {
- dprintf(("ntfs_ntreaddir: scan: 0x%x, %d, %d, %d, %d\n",
- attrnum, (u_int32_t) blnum, cnum, num, aoff));
- rdsize = (attrnum == NTFS_A_INDXROOT) ? vap->va_datalen : blsize;
- error = ntfs_readattr(ntmp, ip, attrnum, "$I30",
- ntfs_cntob(blnum * cpbl), rdsize, rdbuf, NULL);
- if (error)
- goto fail;
-
- if (attrnum == NTFS_A_INDX) {
- error = ntfs_procfixups(ntmp, NTFS_INDXMAGIC,
- rdbuf, rdsize);
- if (error)
- goto fail;
- }
- if (aoff == 0)
- aoff = (attrnum == NTFS_A_INDX) ?
- (0x18 + ((struct attr_indexalloc *) rdbuf)->ia_hdrsize) :
- sizeof(struct attr_indexroot);
-
- iep = (struct attr_indexentry *) (rdbuf + aoff);
- for (; !(iep->ie_flag & NTFS_IEFLAG_LAST) && (rdsize > aoff);
- aoff += iep->reclen,
- iep = (struct attr_indexentry *) (rdbuf + aoff))
- {
- if (!ntfs_isnamepermitted(ntmp, iep)) continue;
-
- if (cnum >= num) {
- fp->f_lastdnum = cnum;
- fp->f_lastdoff = aoff;
- fp->f_lastdblnum = blnum;
- fp->f_lastdattr = attrnum;
-
- *riepp = iep;
-
- error = 0;
- goto fail;
- }
- cnum++;
- }
-
- if (iavap) {
- if (attrnum == NTFS_A_INDXROOT)
- blnum = 0;
- else
- blnum++;
-
- while (ntfs_cntob(blnum * cpbl) < iavap->va_datalen) {
- if (bmp[blnum >> 3] & (1 << (blnum & 7)))
- break;
- blnum++;
- }
-
- attrnum = NTFS_A_INDX;
- aoff = 0;
- if (ntfs_cntob(blnum * cpbl) >= iavap->va_datalen)
- break;
- dprintf(("ntfs_ntreaddir: blnum: %d\n", (u_int32_t) blnum));
- }
- } while (iavap);
-
- *riepp = NULL;
- fp->f_lastdnum = 0;
-
-fail:
- if (vap)
- ntfs_ntvattrrele(vap);
- if (bmvap)
- ntfs_ntvattrrele(bmvap);
- if (iavap)
- ntfs_ntvattrrele(iavap);
- if (bmp)
- free(bmp, M_TEMP);
- ntfs_ntput(ip);
- return (error);
-}
-
-/*
- * Convert NTFS times that are in 100 ns units and begins from
- * 1601 Jan 1 into unix times.
- */
-struct timespec
-ntfs_nttimetounix(
- u_int64_t nt)
-{
- struct timespec t;
-
- /* WindowNT times are in 100 ns and from 1601 Jan 1 */
- t.tv_nsec = (nt % (1000 * 1000 * 10)) * 100;
- t.tv_sec = nt / (1000 * 1000 * 10) -
- 369LL * 365LL * 24LL * 60LL * 60LL -
- 89LL * 1LL * 24LL * 60LL * 60LL;
- return (t);
-}
-
-/*
- * Get file times from NTFS_A_NAME attribute.
- */
-int
-ntfs_times(
- struct ntfsmount * ntmp,
- struct ntnode * ip,
- ntfs_times_t * tm)
-{
- struct ntvattr *vap;
- int error;
-
- dprintf(("ntfs_times: ino: %ju...\n", (uintmax_t)ip->i_number));
-
- error = ntfs_ntget(ip);
- if (error)
- return (error);
-
- error = ntfs_ntvattrget(ntmp, ip, NTFS_A_NAME, NULL, 0, &vap);
- if (error) {
- ntfs_ntput(ip);
- return (error);
- }
- *tm = vap->va_a_name->n_times;
- ntfs_ntvattrrele(vap);
- ntfs_ntput(ip);
-
- return (0);
-}
-
-/*
- * Get file sizes from corresponding attribute.
- *
- * ntnode under fnode should be locked.
- */
-int
-ntfs_filesize(
- struct ntfsmount * ntmp,
- struct fnode * fp,
- u_int64_t * size,
- u_int64_t * bytes)
-{
- struct ntvattr *vap;
- struct ntnode *ip = FTONT(fp);
- u_int64_t sz, bn;
- int error;
-
- dprintf(("ntfs_filesize: ino: %ju\n", (uintmax_t)ip->i_number));
-
- error = ntfs_ntvattrget(ntmp, ip,
- fp->f_attrtype, fp->f_attrname, 0, &vap);
- if (error)
- return (error);
-
- bn = vap->va_allocated;
- sz = vap->va_datalen;
-
- dprintf(("ntfs_filesize: %d bytes (%d bytes allocated)\n",
- (u_int32_t) sz, (u_int32_t) bn));
-
- if (size)
- *size = sz;
- if (bytes)
- *bytes = bn;
-
- ntfs_ntvattrrele(vap);
-
- return (0);
-}
-
-/*
- * This is one of read routines.
- *
- * ntnode should be locked.
- */
-int
-ntfs_readntvattr_plain(
- struct ntfsmount * ntmp,
- struct ntnode * ip,
- struct ntvattr * vap,
- off_t roff,
- size_t rsize,
- void *rdata,
- size_t * initp,
- struct uio *uio)
-{
- int error = 0;
- off_t off;
-
- *initp = 0;
- if (vap->va_flag & NTFS_AF_INRUN) {
- int cnt;
- cn_t ccn, ccl, cn, left, cl;
- caddr_t data = rdata;
- struct buf *bp;
- size_t tocopy;
-
- ddprintf(("ntfs_readntvattr_plain: data in run: %ld chains\n",
- vap->va_vruncnt));
-
- off = roff;
- left = rsize;
- ccl = 0;
- ccn = 0;
- cnt = 0;
- while (left && (cnt < vap->va_vruncnt)) {
- ccn = vap->va_vruncn[cnt];
- ccl = vap->va_vruncl[cnt];
-
- ddprintf(("ntfs_readntvattr_plain: " \
- "left %d, cn: 0x%x, cl: %d, off: %d\n", \
- (u_int32_t) left, (u_int32_t) ccn, \
- (u_int32_t) ccl, (u_int32_t) off));
-
- if (ntfs_cntob(ccl) < off) {
- off -= ntfs_cntob(ccl);
- cnt++;
- continue;
- }
- if (ccn || ip->i_number == NTFS_BOOTINO) {
- ccl -= ntfs_btocn(off);
- cn = ccn + ntfs_btocn(off);
- off = ntfs_btocnoff(off);
-
- while (left && ccl) {
- /*
- * Always read single clusters at a
- * time - we need to avoid reading
- * differently-sized blocks at the
- * same disk offsets to avoid
- * confusing the buffer cache.
- */
- tocopy = MIN(left,
- ntfs_cntob(1) - off);
- cl = ntfs_btocl(tocopy + off);
- KASSERT(cl == 1 &&
- tocopy <= ntfs_cntob(1),
- ("single cluster limit mistake"));
-
- ddprintf(("ntfs_readntvattr_plain: " \
- "read: cn: 0x%x cl: %d, " \
- "off: %d len: %d, left: %d\n",
- (u_int32_t) cn,
- (u_int32_t) cl,
- (u_int32_t) off,
- (u_int32_t) tocopy,
- (u_int32_t) left));
- error = bread(ntmp->ntm_devvp,
- ntfs_cntobn(cn)
- * ntmp->ntm_multiplier,
- ntfs_cntob(cl),
- NOCRED, &bp);
- if (error) {
- brelse(bp);
- return (error);
- }
- if (uio) {
- uiomove(bp->b_data + off,
- tocopy, uio);
- } else {
- memcpy(data, bp->b_data + off,
- tocopy);
- }
- brelse(bp);
- data = data + tocopy;
- *initp += tocopy;
- off = 0;
- left -= tocopy;
- cn += cl;
- ccl -= cl;
- }
- } else {
- tocopy = MIN(left, ntfs_cntob(ccl) - off);
- ddprintf(("ntfs_readntvattr_plain: "
- "hole: ccn: 0x%x ccl: %d, off: %d, " \
- " len: %d, left: %d\n",
- (u_int32_t) ccn, (u_int32_t) ccl,
- (u_int32_t) off, (u_int32_t) tocopy,
- (u_int32_t) left));
- left -= tocopy;
- off = 0;
- if (uio) {
- size_t remains = tocopy;
- for(; remains; remains--)
- uiomove("", 1, uio);
- } else
- memset(data, 0, tocopy);
- data = data + tocopy;
- }
- cnt++;
- }
- if (left) {
- printf("ntfs_readntvattr_plain: POSSIBLE RUN ERROR\n");
- error = E2BIG;
- }
- } else {
- ddprintf(("ntfs_readnvattr_plain: data is in mft record\n"));
- if (uio)
- uiomove(vap->va_datap + roff, rsize, uio);
- else
- memcpy(rdata, vap->va_datap + roff, rsize);
- *initp += rsize;
- }
-
- return (error);
-}
-
-/*
- * This is one of read routines.
- */
-int
-ntfs_readattr_plain(
- struct ntfsmount * ntmp,
- struct ntnode * ip,
- u_int32_t attrnum,
- char *attrname,
- off_t roff,
- size_t rsize,
- void *rdata,
- size_t * initp,
- struct uio *uio)
-{
- size_t init;
- int error = 0;
- off_t off = roff, left = rsize, toread;
- caddr_t data = rdata;
- struct ntvattr *vap;
- *initp = 0;
-
- while (left) {
- error = ntfs_ntvattrget(ntmp, ip, attrnum, attrname,
- ntfs_btocn(off), &vap);
- if (error)
- return (error);
- toread = MIN(left, ntfs_cntob(vap->va_vcnend + 1) - off);
- ddprintf(("ntfs_readattr_plain: o: %d, s: %d (%d - %d)\n",
- (u_int32_t) off, (u_int32_t) toread,
- (u_int32_t) vap->va_vcnstart,
- (u_int32_t) vap->va_vcnend));
- error = ntfs_readntvattr_plain(ntmp, ip, vap,
- off - ntfs_cntob(vap->va_vcnstart),
- toread, data, &init, uio);
- if (error) {
- printf("ntfs_readattr_plain: " \
- "ntfs_readntvattr_plain failed: o: %d, s: %d\n",
- (u_int32_t) off, (u_int32_t) toread);
- printf("ntfs_readattr_plain: attrib: %d - %d\n",
- (u_int32_t) vap->va_vcnstart,
- (u_int32_t) vap->va_vcnend);
- ntfs_ntvattrrele(vap);
- break;
- }
- ntfs_ntvattrrele(vap);
- left -= toread;
- off += toread;
- data = data + toread;
- *initp += init;
- }
-
- return (error);
-}
-
-/*
- * This is one of read routines.
- */
-int
-ntfs_readattr(
- struct ntfsmount * ntmp,
- struct ntnode * ip,
- u_int32_t attrnum,
- char *attrname,
- off_t roff,
- size_t rsize,
- void *rdata,
- struct uio *uio)
-{
- int error = 0;
- struct ntvattr *vap;
- size_t init;
-
- ddprintf(("ntfs_readattr: reading %ju: 0x%x, from %jd size %zu bytes\n",
- (uintmax_t)ip->i_number, attrnum, (intmax_t)roff, rsize));
-
- error = ntfs_ntvattrget(ntmp, ip, attrnum, attrname, 0, &vap);
- if (error)
- return (error);
-
- if ((roff > vap->va_datalen) ||
- (roff + rsize > vap->va_datalen)) {
- ddprintf(("ntfs_readattr: offset too big\n"));
- ntfs_ntvattrrele(vap);
- return (E2BIG);
- }
- if (vap->va_compression && vap->va_compressalg) {
- u_int8_t *cup;
- u_int8_t *uup;
- off_t off = roff, left = rsize, tocopy;
- caddr_t data = rdata;
- cn_t cn;
-
- ddprintf(("ntfs_ntreadattr: compression: %d\n",
- vap->va_compressalg));
-
- cup = malloc(ntfs_cntob(NTFS_COMPUNIT_CL),
- M_NTFSDECOMP, M_WAITOK);
- uup = malloc(ntfs_cntob(NTFS_COMPUNIT_CL),
- M_NTFSDECOMP, M_WAITOK);
-
- cn = (ntfs_btocn(roff)) & (~(NTFS_COMPUNIT_CL - 1));
- off = roff - ntfs_cntob(cn);
-
- while (left) {
- error = ntfs_readattr_plain(ntmp, ip, attrnum,
- attrname, ntfs_cntob(cn),
- ntfs_cntob(NTFS_COMPUNIT_CL),
- cup, &init, NULL);
- if (error)
- break;
-
- tocopy = MIN(left, ntfs_cntob(NTFS_COMPUNIT_CL) - off);
-
- if (init == ntfs_cntob(NTFS_COMPUNIT_CL)) {
- if (uio)
- uiomove(cup + off, tocopy, uio);
- else
- memcpy(data, cup + off, tocopy);
- } else if (init == 0) {
- if (uio) {
- size_t remains = tocopy;
- for(; remains; remains--)
- uiomove("", 1, uio);
- }
- else
- memset(data, 0, tocopy);
- } else {
- error = ntfs_uncompunit(ntmp, uup, cup);
- if (error)
- break;
- if (uio)
- uiomove(uup + off, tocopy, uio);
- else
- memcpy(data, uup + off, tocopy);
- }
-
- left -= tocopy;
- data = data + tocopy;
- off += tocopy - ntfs_cntob(NTFS_COMPUNIT_CL);
- cn += NTFS_COMPUNIT_CL;
- }
-
- free(uup, M_NTFSDECOMP);
- free(cup, M_NTFSDECOMP);
- } else
- error = ntfs_readattr_plain(ntmp, ip, attrnum, attrname,
- roff, rsize, rdata, &init, uio);
- ntfs_ntvattrrele(vap);
- return (error);
-}
-
-#if 0
-int
-ntfs_parserun(
- cn_t * cn,
- cn_t * cl,
- u_int8_t * run,
- u_long len,
- u_long *off)
-{
- u_int8_t sz;
- int i;
-
- if (NULL == run) {
- printf("ntfs_parsetun: run == NULL\n");
- return (EINVAL);
- }
- sz = run[(*off)++];
- if (0 == sz) {
- printf("ntfs_parserun: trying to go out of run\n");
- return (E2BIG);
- }
- *cl = 0;
- if ((sz & 0xF) > 8 || (*off) + (sz & 0xF) > len) {
- printf("ntfs_parserun: " \
- "bad run: length too big: sz: 0x%02x (%ld < %ld + sz)\n",
- sz, len, *off);
- return (EINVAL);
- }
- for (i = 0; i < (sz & 0xF); i++)
- *cl += (u_int32_t) run[(*off)++] << (i << 3);
-
- sz >>= 4;
- if ((sz & 0xF) > 8 || (*off) + (sz & 0xF) > len) {
- printf("ntfs_parserun: " \
- "bad run: length too big: sz: 0x%02x (%ld < %ld + sz)\n",
- sz, len, *off);
- return (EINVAL);
- }
- for (i = 0; i < (sz & 0xF); i++)
- *cn += (u_int32_t) run[(*off)++] << (i << 3);
-
- return (0);
-}
-#endif
-
-/*
- * Process fixup routine on given buffer.
- */
-int
-ntfs_procfixups(
- struct ntfsmount * ntmp,
- u_int32_t magic,
- caddr_t buf,
- size_t len)
-{
- struct fixuphdr *fhp = (struct fixuphdr *) buf;
- int i;
- u_int16_t fixup;
- u_int16_t *fxp;
- u_int16_t *cfxp;
-
- if (fhp->fh_magic != magic) {
- printf("ntfs_procfixups: magic doesn't match: %08x != %08x\n",
- fhp->fh_magic, magic);
- return (EINVAL);
- }
- if ((fhp->fh_fnum - 1) * NTFS_BLOCK_SIZE != len) {
- printf("ntfs_procfixups: " \
- "bad fixups number: %d for %ld bytes block\n",
- fhp->fh_fnum, (long)len); /* XXX printf kludge */
- return (EINVAL);
- }
- if (fhp->fh_foff >= ntmp->ntm_spc * ntmp->ntm_mftrecsz * ntmp->ntm_bps) {
- printf("ntfs_procfixups: invalid offset: %x", fhp->fh_foff);
- return (EINVAL);
- }
- fxp = (u_int16_t *) (buf + fhp->fh_foff);
- cfxp = (u_int16_t *) (buf + NTFS_BLOCK_SIZE - 2);
- fixup = *fxp++;
- for (i = 1; i < fhp->fh_fnum; i++, fxp++) {
- if (*cfxp != fixup) {
- printf("ntfs_procfixups: fixup %d doesn't match\n", i);
- return (EINVAL);
- }
- *cfxp = *fxp;
- cfxp = (u_int16_t *) ((caddr_t) cfxp + NTFS_BLOCK_SIZE);
- }
- return (0);
-}
-
-#if 0
-int
-ntfs_runtocn(
- cn_t * cn,
- struct ntfsmount * ntmp,
- u_int8_t * run,
- u_long len,
- cn_t vcn)
-{
- cn_t ccn = 0;
- cn_t ccl = 0;
- u_long off = 0;
- int error = 0;
-
-#if NTFS_DEBUG
- int i;
- printf("ntfs_runtocn: run: %p, %ld bytes, vcn:%ld\n",
- run, len, (u_long) vcn);
- printf("ntfs_runtocn: run: ");
- for (i = 0; i < len; i++)
- printf("0x%02x ", run[i]);
- printf("\n");
-#endif
-
- if (NULL == run) {
- printf("ntfs_runtocn: run == NULL\n");
- return (EINVAL);
- }
- do {
- if (run[off] == 0) {
- printf("ntfs_runtocn: vcn too big\n");
- return (E2BIG);
- }
- vcn -= ccl;
- error = ntfs_parserun(&ccn, &ccl, run, len, &off);
- if (error) {
- printf("ntfs_runtocn: ntfs_parserun failed\n");
- return (error);
- }
- } while (ccl <= vcn);
- *cn = ccn + vcn;
- return (0);
-}
-#endif
-
-/*
- * this initializes toupper table & dependant variables to be ready for
- * later work
- */
-void
-ntfs_toupper_init()
-{
- ntfs_toupper_tab = (wchar *) NULL;
- lockinit(&ntfs_toupper_lock, PVFS, "ntfs_toupper", 0, 0);
- ntfs_toupper_usecount = 0;
-}
-
-void
-ntfs_toupper_destroy(void)
-{
-
- lockdestroy(&ntfs_toupper_lock);
-}
-
-/*
- * if the ntfs_toupper_tab[] is filled already, just raise use count;
- * otherwise read the data from the filesystem we are currently mounting
- */
-int
-ntfs_toupper_use(mp, ntmp)
- struct mount *mp;
- struct ntfsmount *ntmp;
-{
- int error = 0;
- struct vnode *vp;
-
- /* get exclusive access */
- lockmgr(&ntfs_toupper_lock, LK_EXCLUSIVE, NULL);
-
- /* only read the translation data from a file if it hasn't been
- * read already */
- if (ntfs_toupper_tab)
- goto out;
-
- /*
- * Read in Unicode lowercase -> uppercase translation file.
- * XXX for now, just the first 256 entries are used anyway,
- * so don't bother reading more
- */
- ntfs_toupper_tab = malloc(65536 * sizeof(wchar),
- M_NTFSRDATA, M_WAITOK);
-
- if ((error = VFS_VGET(mp, NTFS_UPCASEINO, LK_EXCLUSIVE, &vp)))
- goto out;
- error = ntfs_readattr(ntmp, VTONT(vp), NTFS_A_DATA, NULL,
- 0, 65536*sizeof(wchar), (char *) ntfs_toupper_tab, NULL);
- vput(vp);
-
- out:
- ntfs_toupper_usecount++;
- lockmgr(&ntfs_toupper_lock, LK_RELEASE, NULL);
- return (error);
-}
-
-/*
- * lower the use count and if it reaches zero, free the memory
- * tied by toupper table
- */
-void
-ntfs_toupper_unuse()
-{
- /* get exclusive access */
- lockmgr(&ntfs_toupper_lock, LK_EXCLUSIVE, NULL);
-
- ntfs_toupper_usecount--;
- if (ntfs_toupper_usecount == 0) {
- free(ntfs_toupper_tab, M_NTFSRDATA);
- ntfs_toupper_tab = NULL;
- }
-#ifdef DIAGNOSTIC
- else if (ntfs_toupper_usecount < 0) {
- panic("ntfs_toupper_unuse(): use count negative: %d\n",
- ntfs_toupper_usecount);
- }
-#endif
-
- /* release the lock */
- lockmgr(&ntfs_toupper_lock, LK_RELEASE, NULL);
-}
-
-int
-ntfs_u28_init(
- struct ntfsmount *ntmp,
- wchar *u2w,
- char *cs_local,
- char *cs_ntfs)
-{
- char ** u28;
- int i, j, h, l;
-
- if (ntfs_iconv && cs_local) {
- ntfs_iconv->open(cs_local, cs_ntfs, &ntmp->ntm_ic_u2l);
- return (0);
- }
-
- u28 = malloc(256 * sizeof(char*), M_TEMP, M_WAITOK | M_ZERO);
-
- for (i=0; i<256; i++) {
- h = (u2w[i] >> 8) & 0xFF;
- l = (u2w[i]) &0xFF;
-
- if (u28[h] == NULL) {
- u28[h] = malloc(256 * sizeof(char), M_TEMP, M_WAITOK);
- for (j=0; j<256; j++)
- u28[h][j] = '_';
- }
-
- u28[h][l] = i & 0xFF;
- }
-
- ntmp->ntm_u28 = u28;
-
- return (0);
-}
-
-int
-ntfs_u28_uninit(struct ntfsmount *ntmp)
-{
- char ** u28;
- int i;
-
- if (ntmp->ntm_u28 == NULL) {
- if (ntfs_iconv && ntmp->ntm_ic_u2l) {
- ntfs_iconv->close(ntmp->ntm_ic_u2l);
- }
- return (0);
- }
-
- u28 = ntmp->ntm_u28;
-
- for (i=0; i<256; i++)
- if (u28[i] != NULL)
- free(u28[i], M_TEMP);
-
- free(u28, M_TEMP);
-
- return (0);
-}
-
-int
-ntfs_82u_init(
- struct ntfsmount *ntmp,
- char *cs_local,
- char *cs_ntfs)
-{
- wchar * _82u;
- int i;
-
- if (ntfs_iconv && cs_local) {
- ntfs_iconv->open(cs_ntfs, cs_local, &ntmp->ntm_ic_l2u);
- return (0);
- }
-
- _82u = malloc(256 * sizeof(wchar), M_TEMP, M_WAITOK);
-
- for (i=0; i<256; i++)
- _82u[i] = i;
-
- ntmp->ntm_82u = _82u;
-
- return (0);
-}
-
-int
-ntfs_82u_uninit(struct ntfsmount *ntmp)
-{
-
- if (ntmp->ntm_82u == NULL) {
- if (ntfs_iconv && ntmp->ntm_ic_l2u) {
- ntfs_iconv->close(ntmp->ntm_ic_l2u);
- }
- return (0);
- }
-
- free(ntmp->ntm_82u, M_TEMP);
- return (0);
-}
-
-/*
- * maps the Unicode char to local character
- */
-char *
-ntfs_u28(
- char *outbuf,
- struct ntfsmount *ntmp,
- wchar wc)
-{
- char *p, *outp, inbuf[3];
- size_t ilen, olen;
-
- outp = outbuf;
- if (ntfs_iconv && ntmp->ntm_ic_u2l) {
- ilen = 2;
- olen = 4;
-
- inbuf[0] = (char)(wc>>8);
- inbuf[1] = (char)wc;
- inbuf[2] = '\0';
- p = inbuf;
- ntfs_iconv->convchr(ntmp->ntm_ic_u2l, (const char **)&p, &ilen,
- &outp, &olen);
- if (olen == 4)
- *outp++ = '?';
- *outp = '\0';
- outp = outbuf;
- return (outp);
- }
-
- p = ntmp->ntm_u28[(wc>>8)&0xFF];
- outbuf[0] = (p == NULL) ? '_' : p[wc&0xFF] & 0xFF;
- outbuf[1] = '\0';
- return (outp);
-}
-
-wchar
-ntfs_82u(
- struct ntfsmount *ntmp,
- const char *c,
- int *len)
-{
- char *outp, outbuf[3];
- wchar uc;
- size_t ilen, olen;
-
- if (ntfs_iconv && ntmp->ntm_ic_l2u) {
- ilen = (size_t)*len;
- olen = 2;
-
- outp = outbuf;
- ntfs_iconv->convchr(ntmp->ntm_ic_l2u, &c, &ilen, &outp, &olen);
- *len -= (int)ilen;
- uc = (wchar)((outbuf[0]<<8) | (outbuf[1]&0xFF));
-
- return (uc);
- }
-
- if (ntmp->ntm_82u != NULL)
- return (ntmp->ntm_82u[*c&0xFF]);
-
- return ('?');
-}
-
diff --git a/sys/fs/ntfs/ntfs_subr.h b/sys/fs/ntfs/ntfs_subr.h
deleted file mode 100644
index 9ccbb42..0000000
--- a/sys/fs/ntfs/ntfs_subr.h
+++ /dev/null
@@ -1,120 +0,0 @@
-/* $NetBSD: ntfs_subr.h,v 1.8 1999/10/10 14:48:37 jdolecek Exp $ */
-
-/*-
- * Copyright (c) 1998, 1999 Semen Ustimenko
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * $FreeBSD$
- */
-
-#define VA_LOADED 0x0001
-#define VA_PRELOADED 0x0002
-
-struct ntvattr {
- LIST_ENTRY(ntvattr) va_list;
-
- u_int32_t va_vflag;
- struct vnode *va_vp;
- struct ntnode *va_ip;
-
- u_int32_t va_flag;
- u_int32_t va_type;
- u_int8_t va_namelen;
- char va_name[NTFS_MAXATTRNAME];
-
- u_int32_t va_compression;
- u_int32_t va_compressalg;
- u_int64_t va_datalen;
- u_int64_t va_allocated;
- cn_t va_vcnstart;
- cn_t va_vcnend;
- u_int16_t va_index;
- union {
- struct {
- cn_t * cn;
- cn_t * cl;
- u_long cnt;
- } vrun;
- caddr_t datap;
- struct attr_name *name;
- struct attr_indexroot *iroot;
- struct attr_indexalloc *ialloc;
- } va_d;
-};
-#define va_vruncn va_d.vrun.cn
-#define va_vruncl va_d.vrun.cl
-#define va_vruncnt va_d.vrun.cnt
-#define va_datap va_d.datap
-#define va_a_name va_d.name
-#define va_a_iroot va_d.iroot
-#define va_a_ialloc va_d.ialloc
-
-struct componentname;
-struct fnode;
-struct uio;
-
-int ntfs_procfixups( struct ntfsmount *, u_int32_t, caddr_t, size_t );
-int ntfs_parserun( cn_t *, cn_t *, u_int8_t *, u_long, u_long *);
-int ntfs_runtocn( cn_t *, struct ntfsmount *, u_int8_t *, u_long, cn_t);
-int ntfs_readntvattr_plain( struct ntfsmount *, struct ntnode *, struct ntvattr *, off_t, size_t, void *,size_t *, struct uio *);
-int ntfs_readattr_plain( struct ntfsmount *, struct ntnode *, u_int32_t, char *, off_t, size_t, void *,size_t *, struct uio *);
-int ntfs_readattr( struct ntfsmount *, struct ntnode *, u_int32_t, char *, off_t, size_t, void *, struct uio *);
-int ntfs_filesize( struct ntfsmount *, struct fnode *, u_int64_t *, u_int64_t *);
-int ntfs_times( struct ntfsmount *, struct ntnode *, ntfs_times_t *);
-struct timespec ntfs_nttimetounix( u_int64_t );
-int ntfs_ntreaddir( struct ntfsmount *, struct fnode *, u_int32_t, struct attr_indexentry **);
-int ntfs_runtovrun( cn_t **, cn_t **, u_long *, u_int8_t *);
-int ntfs_attrtontvattr( struct ntfsmount *, struct ntvattr **, struct attr * );
-void ntfs_freentvattr( struct ntvattr * );
-int ntfs_loadntvattrs( struct ntfsmount *, struct vnode *, caddr_t, struct ntvattr **);
-struct ntvattr * ntfs_findntvattr( struct ntfsmount *, struct ntnode *, u_int32_t, cn_t );
-int ntfs_ntlookupfile(struct ntfsmount *, struct vnode *, struct componentname *, struct vnode **);
-int ntfs_isnamepermitted(struct ntfsmount *, struct attr_indexentry * );
-int ntfs_ntvattrrele(struct ntvattr * );
-int ntfs_ntvattrget(struct ntfsmount *, struct ntnode *, u_int32_t, const char *, cn_t , struct ntvattr **);
-int ntfs_ntlookup(struct ntfsmount *, ino_t, struct ntnode **);
-int ntfs_ntget(struct ntnode *);
-void ntfs_ntref(struct ntnode *);
-void ntfs_ntrele(struct ntnode *);
-void ntfs_ntput(struct ntnode *);
-int ntfs_loadntnode( struct ntfsmount *, struct ntnode * );
-void ntfs_toupper_init(void);
-void ntfs_toupper_destroy(void);
-int ntfs_toupper_use(struct mount *, struct ntfsmount *);
-void ntfs_toupper_unuse(void);
-int ntfs_fget(struct ntfsmount *, struct ntnode *, int, char *, struct fnode **);
-void ntfs_frele(struct fnode *);
-
-int ntfs_u28_init(struct ntfsmount *ntmp, wchar *u2w, char *cs_local, char *cs_ntfs);
-int ntfs_u28_uninit(struct ntfsmount *ntmp);
-int ntfs_82u_init(struct ntfsmount *ntmp, char *cs_local, char *cs_ntfs);
-int ntfs_82u_uninit(struct ntfsmount *ntmp);
-char * ntfs_u28(char *outbuf, struct ntfsmount *ntmp, wchar wc);
-wchar ntfs_82u(struct ntfsmount *ntmp, const char *c, int *len);
-#define NTFS_U28(ch) ntfs_u28(tmpbuf, ntmp, (ch))
-#define NTFS_82U(ch, len) ntfs_82u(ntmp, (ch), len)
-#define NTFS_UASTRCMP(ustr, ustrlen, astr, astrlen) \
- ntfs_uastrcmp(ntmp, (ustr), (ustrlen), (astr), (astrlen))
-#define NTFS_UASTRICMP(ustr, ustrlen, astr, astrlen) \
- ntfs_uastricmp(ntmp, (ustr), (ustrlen), (astr), (astrlen))
diff --git a/sys/fs/ntfs/ntfs_vfsops.c b/sys/fs/ntfs/ntfs_vfsops.c
deleted file mode 100644
index c0408dd..0000000
--- a/sys/fs/ntfs/ntfs_vfsops.c
+++ /dev/null
@@ -1,780 +0,0 @@
-/* $NetBSD: ntfs_vfsops.c,v 1.23 1999/11/15 19:38:14 jdolecek Exp $ */
-
-/*-
- * Copyright (c) 1998, 1999 Semen Ustimenko
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * $FreeBSD$
- */
-
-
-#include <sys/param.h>
-#include <sys/systm.h>
-#include <sys/namei.h>
-#include <sys/conf.h>
-#include <sys/priv.h>
-#include <sys/proc.h>
-#include <sys/kernel.h>
-#include <sys/vnode.h>
-#include <sys/mount.h>
-#include <sys/bio.h>
-#include <sys/buf.h>
-#include <sys/fcntl.h>
-#include <sys/malloc.h>
-#include <sys/stat.h>
-#include <sys/systm.h>
-
-#include <geom/geom.h>
-#include <geom/geom_vfs.h>
-
-#include <vm/vm.h>
-#include <vm/vm_param.h>
-#include <vm/vm_page.h>
-#include <vm/vm_object.h>
-#include <vm/vm_extern.h>
-
-/*#define NTFS_DEBUG 1*/
-#include <fs/ntfs/ntfs.h>
-#include <fs/ntfs/ntfs_inode.h>
-#include <fs/ntfs/ntfs_subr.h>
-#include <fs/ntfs/ntfs_vfsops.h>
-#include <fs/ntfs/ntfs_ihash.h>
-#include <fs/ntfs/ntfsmount.h>
-
-static MALLOC_DEFINE(M_NTFSMNT, "ntfs_mount", "NTFS mount structure");
-MALLOC_DEFINE(M_NTFSNTNODE,"ntfs_ntnode", "NTFS ntnode information");
-MALLOC_DEFINE(M_NTFSFNODE,"ntfs_fnode", "NTFS fnode information");
-MALLOC_DEFINE(M_NTFSDIR,"ntfs_dir", "NTFS dir buffer");
-
-static int ntfs_mountfs(register struct vnode *, struct mount *,
- struct thread *);
-static int ntfs_calccfree(struct ntfsmount *ntmp, cn_t *cfreep);
-
-static vfs_init_t ntfs_init;
-static vfs_uninit_t ntfs_uninit;
-static vfs_vget_t ntfs_vget;
-static vfs_fhtovp_t ntfs_fhtovp;
-static vfs_cmount_t ntfs_cmount;
-static vfs_mount_t ntfs_mount;
-static vfs_root_t ntfs_root;
-static vfs_statfs_t ntfs_statfs;
-static vfs_unmount_t ntfs_unmount;
-
-static b_strategy_t ntfs_bufstrategy;
-
-/*
- * Buffer operations for NTFS vnodes.
- * We punt on VOP_BMAP, so we need to do
- * strategy on the file's vnode rather
- * than the underlying device's
- */
-static struct buf_ops ntfs_vnbufops = {
- .bop_name = "NTFS",
- .bop_strategy = ntfs_bufstrategy,
-};
-
-static int
-ntfs_init (
- struct vfsconf *vcp )
-{
- ntfs_nthashinit();
- ntfs_toupper_init();
- return 0;
-}
-
-static int
-ntfs_uninit (
- struct vfsconf *vcp )
-{
- ntfs_toupper_destroy();
- ntfs_nthashdestroy();
- return 0;
-}
-
-static int
-ntfs_cmount (
- struct mntarg *ma,
- void *data,
- uint64_t flags)
-{
- struct ntfs_args args;
- struct export_args exp;
- int error;
-
- error = copyin(data, &args, sizeof(args));
- if (error)
- return (error);
- vfs_oexport_conv(&args.export, &exp);
- ma = mount_argsu(ma, "from", args.fspec, MAXPATHLEN);
- ma = mount_arg(ma, "export", &exp, sizeof(exp));
- ma = mount_argf(ma, "uid", "%d", args.uid);
- ma = mount_argf(ma, "gid", "%d", args.gid);
- ma = mount_argf(ma, "mode", "%d", args.mode);
- ma = mount_argb(ma, args.flag & NTFS_MFLAG_CASEINS, "nocaseins");
- ma = mount_argb(ma, args.flag & NTFS_MFLAG_ALLNAMES, "noallnames");
- if (args.flag & NTFS_MFLAG_KICONV) {
- ma = mount_argsu(ma, "cs_ntfs", args.cs_ntfs, 64);
- ma = mount_argsu(ma, "cs_local", args.cs_local, 64);
- }
-
- error = kernel_mount(ma, flags);
-
- return (error);
-}
-
-static const char *ntfs_opts[] = {
- "from", "export", "uid", "gid", "mode", "caseins", "allnames",
- "kiconv", "cs_ntfs", "cs_local", NULL
-};
-
-static int
-ntfs_mount(struct mount *mp)
-{
- int err = 0, error;
- struct vnode *devvp;
- struct nameidata ndp;
- struct thread *td;
- char *from;
-
- td = curthread;
- if (vfs_filteropt(mp->mnt_optnew, ntfs_opts))
- return (EINVAL);
-
- /* Force mount as read-only. */
- MNT_ILOCK(mp);
- mp->mnt_flag |= MNT_RDONLY;
- MNT_IUNLOCK(mp);
-
- from = vfs_getopts(mp->mnt_optnew, "from", &error);
- if (error)
- return (error);
-
- /*
- * If updating, check whether changing from read-only to
- * read/write.
- */
- if (mp->mnt_flag & MNT_UPDATE) {
- if (vfs_flagopt(mp->mnt_optnew, "export", NULL, 0)) {
- /* Process export requests in vfs_mount.c */
- return (0);
- } else {
- printf("ntfs_mount(): MNT_UPDATE not supported\n");
- return (EINVAL);
- }
- }
-
- /*
- * Not an update, or updating the name: look up the name
- * and verify that it refers to a sensible block device.
- */
- NDINIT(&ndp, LOOKUP, FOLLOW | LOCKLEAF, UIO_SYSSPACE, from, td);
- err = namei(&ndp);
- if (err)
- return (err);
- NDFREE(&ndp, NDF_ONLY_PNBUF);
- devvp = ndp.ni_vp;
-
- if (!vn_isdisk(devvp, &err)) {
- vput(devvp);
- return (err);
- }
-
- /*
- * If mount by non-root, then verify that user has necessary
- * permissions on the device.
- */
- err = VOP_ACCESS(devvp, VREAD, td->td_ucred, td);
- if (err)
- err = priv_check(td, PRIV_VFS_MOUNT_PERM);
- if (err) {
- vput(devvp);
- return (err);
- }
-
-
- /*
- * Since this is a new mount, we want the names for the device and
- * the mount point copied in. If an error occurs, the mountpoint is
- * discarded by the upper level code. Note that vfs_mount() handles
- * copying the mountpoint f_mntonname for us, so we don't have to do
- * it here unless we want to set it to something other than "path"
- * for some rason.
- */
-
- err = ntfs_mountfs(devvp, mp, td);
- if (err == 0) {
-
- /* Save "mounted from" info for mount point. */
- vfs_mountedfrom(mp, from);
- } else
- vrele(devvp);
- return (err);
-}
-
-/*
- * Common code for mount and mountroot
- */
-int
-ntfs_mountfs(devvp, mp, td)
- register struct vnode *devvp;
- struct mount *mp;
- struct thread *td;
-{
- struct buf *bp;
- struct ntfsmount *ntmp;
- struct cdev *dev = devvp->v_rdev;
- int error, i, v;
- struct vnode *vp;
- struct g_consumer *cp;
- struct g_provider *pp;
- char *cs_ntfs, *cs_local;
-
- DROP_GIANT();
- g_topology_lock();
-
- /*
- * XXX: Do not allow more than one consumer to open a device
- * associated with a particular GEOM provider.
- * This disables multiple read-only mounts of a device,
- * but it gets rid of panics in vget() when you try to
- * mount the same device more than once.
- */
- pp = g_dev_getprovider(devvp->v_rdev);
- if ((pp != NULL) && ((pp->acr | pp->acw | pp->ace ) != 0))
- error = EPERM;
- else
- error = g_vfs_open(devvp, &cp, "ntfs", 0);
-
- g_topology_unlock();
- PICKUP_GIANT();
- VOP_UNLOCK(devvp, 0);
- if (error)
- return (error);
-
- bp = NULL;
-
- error = bread(devvp, BBLOCK, BBSIZE, NOCRED, &bp);
- if (error)
- goto out;
- ntmp = malloc( sizeof *ntmp, M_NTFSMNT, M_WAITOK | M_ZERO);
- bcopy( bp->b_data, &ntmp->ntm_bootfile, sizeof(struct bootfile) );
- /*
- * We must not cache the boot block if its size is not exactly
- * one cluster in order to avoid confusing the buffer cache when
- * the boot file is read later by ntfs_readntvattr_plain(), which
- * reads a cluster at a time.
- */
- if (ntfs_cntob(1) != BBSIZE)
- bp->b_flags |= B_NOCACHE;
- brelse( bp );
- bp = NULL;
-
- if (strncmp((const char *)ntmp->ntm_bootfile.bf_sysid, NTFS_BBID, NTFS_BBIDLEN)) {
- error = EINVAL;
- dprintf(("ntfs_mountfs: invalid boot block\n"));
- goto out;
- }
-
- {
- int8_t cpr = ntmp->ntm_mftrecsz;
- if( cpr > 0 )
- ntmp->ntm_bpmftrec = ntmp->ntm_spc * cpr;
- else
- ntmp->ntm_bpmftrec = (1 << (-cpr)) / ntmp->ntm_bps;
- }
- ntmp->ntm_multiplier = ntmp->ntm_bps / DEV_BSIZE;
-
- dprintf(("ntfs_mountfs(): bps: %d, spc: %d, media: %x, mftrecsz: %d (%d sects)\n",
- ntmp->ntm_bps,ntmp->ntm_spc,ntmp->ntm_bootfile.bf_media,
- ntmp->ntm_mftrecsz,ntmp->ntm_bpmftrec));
- dprintf(("ntfs_mountfs(): mftcn: 0x%x|0x%x\n",
- (u_int32_t)ntmp->ntm_mftcn,(u_int32_t)ntmp->ntm_mftmirrcn));
-
- ntmp->ntm_mountp = mp;
- ntmp->ntm_devvp = devvp;
- if (vfs_scanopt(mp->mnt_optnew, "uid", "%d", &v) == 1)
- ntmp->ntm_uid = v;
- if (vfs_scanopt(mp->mnt_optnew, "gid", "%d", &v) == 1)
- ntmp->ntm_gid = v;
- if (vfs_scanopt(mp->mnt_optnew, "mode", "%d", &v) == 1)
- ntmp->ntm_mode = v & ACCESSPERMS;
- vfs_flagopt(mp->mnt_optnew,
- "caseins", &ntmp->ntm_flag, NTFS_MFLAG_CASEINS);
- vfs_flagopt(mp->mnt_optnew,
- "allnames", &ntmp->ntm_flag, NTFS_MFLAG_ALLNAMES);
- ntmp->ntm_cp = cp;
- ntmp->ntm_bo = &devvp->v_bufobj;
-
- cs_local = vfs_getopts(mp->mnt_optnew, "cs_local", &error);
- if (error && error != ENOENT)
- goto out;
- cs_ntfs = vfs_getopts(mp->mnt_optnew, "cs_ntfs", &error);
- if (error && error != ENOENT)
- goto out;
- /* Copy in the 8-bit to Unicode conversion table */
- /* Initialize Unicode to 8-bit table from 8toU table */
- ntfs_82u_init(ntmp, cs_local, cs_ntfs);
- if (cs_local != NULL && cs_ntfs != NULL)
- ntfs_u28_init(ntmp, NULL, cs_local, cs_ntfs);
- else
- ntfs_u28_init(ntmp, ntmp->ntm_82u, cs_local, cs_ntfs);
-
- mp->mnt_data = ntmp;
-
- dprintf(("ntfs_mountfs(): case-%s,%s uid: %d, gid: %d, mode: %o\n",
- (ntmp->ntm_flag & NTFS_MFLAG_CASEINS)?"insens.":"sens.",
- (ntmp->ntm_flag & NTFS_MFLAG_ALLNAMES)?" allnames,":"",
- ntmp->ntm_uid, ntmp->ntm_gid, ntmp->ntm_mode));
-
- /*
- * We read in some system nodes to do not allow
- * reclaim them and to have everytime access to them.
- */
- {
- int pi[3] = { NTFS_MFTINO, NTFS_ROOTINO, NTFS_BITMAPINO };
- for (i=0; i<3; i++) {
- error = VFS_VGET(mp, pi[i], LK_EXCLUSIVE,
- &(ntmp->ntm_sysvn[pi[i]]));
- if(error)
- goto out1;
- ntmp->ntm_sysvn[pi[i]]->v_vflag |= VV_SYSTEM;
- VREF(ntmp->ntm_sysvn[pi[i]]);
- vput(ntmp->ntm_sysvn[pi[i]]);
- }
- }
-
- /* read the Unicode lowercase --> uppercase translation table,
- * if necessary */
- if ((error = ntfs_toupper_use(mp, ntmp)))
- goto out1;
-
- /*
- * Scan $BitMap and count free clusters
- */
- error = ntfs_calccfree(ntmp, &ntmp->ntm_cfree);
- if(error)
- goto out1;
-
- /*
- * Read and translate to internal format attribute
- * definition file.
- */
- {
- int num,j;
- struct attrdef ad;
-
- /* Open $AttrDef */
- error = VFS_VGET(mp, NTFS_ATTRDEFINO, LK_EXCLUSIVE, &vp );
- if(error)
- goto out1;
-
- /* Count valid entries */
- for(num=0;;num++) {
- error = ntfs_readattr(ntmp, VTONT(vp),
- NTFS_A_DATA, NULL,
- num * sizeof(ad), sizeof(ad),
- &ad, NULL);
- if (error)
- goto out1;
- if (ad.ad_name[0] == 0)
- break;
- }
-
- /* Alloc memory for attribute definitions */
- ntmp->ntm_ad = malloc(num * sizeof(struct ntvattrdef),
- M_NTFSMNT, M_WAITOK);
-
- ntmp->ntm_adnum = num;
-
- /* Read them and translate */
- for(i=0;i<num;i++){
- error = ntfs_readattr(ntmp, VTONT(vp),
- NTFS_A_DATA, NULL,
- i * sizeof(ad), sizeof(ad),
- &ad, NULL);
- if (error)
- goto out1;
- j = 0;
- do {
- ntmp->ntm_ad[i].ad_name[j] = ad.ad_name[j];
- } while(ad.ad_name[j++]);
- ntmp->ntm_ad[i].ad_namelen = j - 1;
- ntmp->ntm_ad[i].ad_type = ad.ad_type;
- }
-
- vput(vp);
- }
-
- mp->mnt_stat.f_fsid.val[0] = dev2udev(dev);
- mp->mnt_stat.f_fsid.val[1] = mp->mnt_vfc->vfc_typenum;
- mp->mnt_maxsymlinklen = 0;
- MNT_ILOCK(mp);
- mp->mnt_flag |= MNT_LOCAL;
- MNT_IUNLOCK(mp);
- return (0);
-
-out1:
- for(i=0;i<NTFS_SYSNODESNUM;i++)
- if(ntmp->ntm_sysvn[i]) vrele(ntmp->ntm_sysvn[i]);
-
- if (vflush(mp, 0, 0, td))
- dprintf(("ntfs_mountfs: vflush failed\n"));
-
-out:
- if (bp)
- brelse(bp);
-
- DROP_GIANT();
- g_topology_lock();
- g_vfs_close(cp);
- g_topology_unlock();
- PICKUP_GIANT();
-
- return (error);
-}
-
-static int
-ntfs_unmount(
- struct mount *mp,
- int mntflags)
-{
- struct thread *td;
- struct ntfsmount *ntmp;
- int error, flags, i;
-
- dprintf(("ntfs_unmount: unmounting...\n"));
- td = curthread;
- ntmp = VFSTONTFS(mp);
-
- flags = 0;
- if(mntflags & MNT_FORCE)
- flags |= FORCECLOSE;
-
- dprintf(("ntfs_unmount: vflushing...\n"));
- error = vflush(mp, 0, flags | SKIPSYSTEM, td);
- if (error) {
- printf("ntfs_unmount: vflush failed: %d\n",error);
- return (error);
- }
-
- /* Check if only system vnodes are rest */
- for(i=0;i<NTFS_SYSNODESNUM;i++)
- if((ntmp->ntm_sysvn[i]) &&
- (vrefcnt(ntmp->ntm_sysvn[i]) > 1)) return (EBUSY);
-
- /* Dereference all system vnodes */
- for(i=0;i<NTFS_SYSNODESNUM;i++)
- if(ntmp->ntm_sysvn[i]) vrele(ntmp->ntm_sysvn[i]);
-
- /* vflush system vnodes */
- error = vflush(mp, 0, flags, td);
- if (error)
- printf("ntfs_unmount: vflush failed(sysnodes): %d\n",error);
-
- vinvalbuf(ntmp->ntm_devvp, V_SAVE, 0, 0);
-
- DROP_GIANT();
- g_topology_lock();
- g_vfs_close(ntmp->ntm_cp);
- g_topology_unlock();
- PICKUP_GIANT();
-
- vrele(ntmp->ntm_devvp);
-
- /* free the toupper table, if this has been last mounted ntfs volume */
- ntfs_toupper_unuse();
-
- dprintf(("ntfs_umount: freeing memory...\n"));
- ntfs_u28_uninit(ntmp);
- ntfs_82u_uninit(ntmp);
- mp->mnt_data = NULL;
- MNT_ILOCK(mp);
- mp->mnt_flag &= ~MNT_LOCAL;
- MNT_IUNLOCK(mp);
- free(ntmp->ntm_ad, M_NTFSMNT);
- free(ntmp, M_NTFSMNT);
- return (error);
-}
-
-static int
-ntfs_root(
- struct mount *mp,
- int flags,
- struct vnode **vpp)
-{
- struct vnode *nvp;
- int error = 0;
-
- dprintf(("ntfs_root(): sysvn: %p\n",
- VFSTONTFS(mp)->ntm_sysvn[NTFS_ROOTINO]));
- error = VFS_VGET(mp, (ino_t)NTFS_ROOTINO, LK_EXCLUSIVE, &nvp);
- if(error) {
- printf("ntfs_root: VFS_VGET failed: %d\n",error);
- return (error);
- }
-
- *vpp = nvp;
- return (0);
-}
-
-static int
-ntfs_calccfree(
- struct ntfsmount *ntmp,
- cn_t *cfreep)
-{
- struct vnode *vp;
- u_int8_t *tmp;
- int j, error;
- long cfree = 0;
- size_t bmsize, i;
-
- vp = ntmp->ntm_sysvn[NTFS_BITMAPINO];
-
- bmsize = VTOF(vp)->f_size;
-
- tmp = malloc(bmsize, M_TEMP, M_WAITOK);
-
- error = ntfs_readattr(ntmp, VTONT(vp), NTFS_A_DATA, NULL,
- 0, bmsize, tmp, NULL);
- if (error)
- goto out;
-
- for(i=0;i<bmsize;i++)
- for(j=0;j<8;j++)
- if(~tmp[i] & (1 << j)) cfree++;
- *cfreep = cfree;
-
- out:
- free(tmp, M_TEMP);
- return(error);
-}
-
-static int
-ntfs_statfs(
- struct mount *mp,
- struct statfs *sbp)
-{
- struct ntfsmount *ntmp = VFSTONTFS(mp);
- u_int64_t mftsize,mftallocated;
-
- dprintf(("ntfs_statfs():\n"));
-
- mftsize = VTOF(ntmp->ntm_sysvn[NTFS_MFTINO])->f_size;
- mftallocated = VTOF(ntmp->ntm_sysvn[NTFS_MFTINO])->f_allocated;
-
- sbp->f_type = mp->mnt_vfc->vfc_typenum;
- sbp->f_bsize = ntmp->ntm_bps;
- sbp->f_iosize = ntmp->ntm_bps * ntmp->ntm_spc;
- sbp->f_blocks = ntmp->ntm_bootfile.bf_spv;
- sbp->f_bfree = sbp->f_bavail = ntfs_cntobn(ntmp->ntm_cfree);
- sbp->f_ffree = sbp->f_bfree / ntmp->ntm_bpmftrec;
- sbp->f_files = mftallocated / ntfs_bntob(ntmp->ntm_bpmftrec) +
- sbp->f_ffree;
- sbp->f_flags = mp->mnt_flag;
-
- return (0);
-}
-
-/*ARGSUSED*/
-static int
-ntfs_fhtovp(
- struct mount *mp,
- struct fid *fhp,
- int flags,
- struct vnode **vpp)
-{
- struct vnode *nvp;
- struct ntfid *ntfhp = (struct ntfid *)fhp;
- int error;
-
- ddprintf(("ntfs_fhtovp(): %d\n", ntfhp->ntfid_ino));
-
- if ((error = VFS_VGET(mp, ntfhp->ntfid_ino, LK_EXCLUSIVE, &nvp)) != 0) {
- *vpp = NULLVP;
- return (error);
- }
- /* XXX as unlink/rmdir/mkdir/creat are not currently possible
- * with NTFS, we don't need to check anything else for now */
- *vpp = nvp;
- vnode_create_vobject(nvp, VTOF(nvp)->f_size, curthread);
- return (0);
-}
-
-int
-ntfs_vgetex(
- struct mount *mp,
- ino_t ino,
- u_int32_t attrtype,
- char *attrname,
- u_long lkflags,
- u_long flags,
- struct thread *td,
- struct vnode **vpp)
-{
- int error;
- register struct ntfsmount *ntmp;
- struct ntnode *ip;
- struct fnode *fp;
- struct vnode *vp;
- enum vtype f_type;
-
- dprintf(("ntfs_vgetex: ino: %ju, attr: 0x%x:%s, lkf: 0x%lx, f: 0x%lx\n",
- (uintmax_t)ino, attrtype, attrname ? attrname : "", lkflags,
- (u_long)flags));
-
- ntmp = VFSTONTFS(mp);
- *vpp = NULL;
-
- /* Get ntnode */
- error = ntfs_ntlookup(ntmp, ino, &ip);
- if (error) {
- printf("ntfs_vget: ntfs_ntget failed\n");
- return (error);
- }
-
- /* It may be not initialized fully, so force load it */
- if (!(flags & VG_DONTLOADIN) && !(ip->i_flag & IN_LOADED)) {
- error = ntfs_loadntnode(ntmp, ip);
- if(error) {
- printf("ntfs_vget: CAN'T LOAD ATTRIBUTES FOR INO: %ju\n",
- (uintmax_t)ip->i_number);
- ntfs_ntput(ip);
- return (error);
- }
- }
-
- error = ntfs_fget(ntmp, ip, attrtype, attrname, &fp);
- if (error) {
- printf("ntfs_vget: ntfs_fget failed\n");
- ntfs_ntput(ip);
- return (error);
- }
-
- f_type = VNON;
- if (!(flags & VG_DONTVALIDFN) && !(fp->f_flag & FN_VALID)) {
- if ((ip->i_frflag & NTFS_FRFLAG_DIR) &&
- (fp->f_attrtype == NTFS_A_DATA && fp->f_attrname == NULL)) {
- f_type = VDIR;
- } else if (flags & VG_EXT) {
- f_type = VNON;
- fp->f_size = fp->f_allocated = 0;
- } else {
- f_type = VREG;
-
- error = ntfs_filesize(ntmp, fp,
- &fp->f_size, &fp->f_allocated);
- if (error) {
- ntfs_ntput(ip);
- return (error);
- }
- }
-
- fp->f_flag |= FN_VALID;
- }
-
- if (FTOV(fp)) {
- vget(FTOV(fp), lkflags, td);
- *vpp = FTOV(fp);
- ntfs_ntput(ip);
- return (0);
- }
-
- error = getnewvnode("ntfs", ntmp->ntm_mountp, &ntfs_vnodeops, &vp);
- if(error) {
- ntfs_frele(fp);
- ntfs_ntput(ip);
- return (error);
- }
- /* XXX: Too early for mpsafe fs, lacks vnode lock */
- error = insmntque(vp, ntmp->ntm_mountp);
- if (error) {
- ntfs_frele(fp);
- ntfs_ntput(ip);
- return (error);
- }
- dprintf(("ntfs_vget: vnode: %p for ntnode: %ju\n", vp, (uintmax_t)ino));
-
- fp->f_vp = vp;
- vp->v_data = fp;
- vp->v_type = f_type;
-
- vp->v_bufobj.bo_ops = &ntfs_vnbufops;
- vp->v_bufobj.bo_private = vp;
-
- if (ino == NTFS_ROOTINO)
- vp->v_vflag |= VV_ROOT;
-
- ntfs_ntput(ip);
-
- if (lkflags & LK_TYPE_MASK) {
- error = vn_lock(vp, lkflags);
- if (error) {
- vput(vp);
- return (error);
- }
- }
-
- *vpp = vp;
- return (0);
-
-}
-
-static int
-ntfs_vget(
- struct mount *mp,
- ino_t ino,
- int lkflags,
- struct vnode **vpp)
-{
- return ntfs_vgetex(mp, ino, NTFS_A_DATA, NULL, lkflags, 0,
- curthread, vpp);
-}
-
-static void
-ntfs_bufstrategy(struct bufobj *bo, struct buf *bp)
-{
- struct vnode *vp;
- int rc;
-
- vp = bo->bo_private;
- KASSERT(bo == &vp->v_bufobj, ("BO/VP mismatch: vp %p bo %p != %p",
- vp, &vp->v_bufobj, bo));
- rc = VOP_STRATEGY(vp, bp);
- KASSERT(rc == 0, ("NTFS VOP_STRATEGY failed: bp=%p, "
- "vp=%p, rc=%d", bp, vp, rc));
-}
-
-static struct vfsops ntfs_vfsops = {
- .vfs_fhtovp = ntfs_fhtovp,
- .vfs_init = ntfs_init,
- .vfs_cmount = ntfs_cmount,
- .vfs_mount = ntfs_mount,
- .vfs_root = ntfs_root,
- .vfs_statfs = ntfs_statfs,
- .vfs_uninit = ntfs_uninit,
- .vfs_unmount = ntfs_unmount,
- .vfs_vget = ntfs_vget,
-};
-VFS_SET(ntfs_vfsops, ntfs, VFCF_READONLY);
-MODULE_VERSION(ntfs, 1);
diff --git a/sys/fs/ntfs/ntfs_vfsops.h b/sys/fs/ntfs/ntfs_vfsops.h
deleted file mode 100644
index adb737d..0000000
--- a/sys/fs/ntfs/ntfs_vfsops.h
+++ /dev/null
@@ -1,43 +0,0 @@
-/* $NetBSD: ntfs_vfsops.h,v 1.4 1999/10/10 14:20:33 jdolecek Exp $ */
-
-/*-
- * Copyright (c) 1998, 1999 Semen Ustimenko (semenu@FreeBSD.org)
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * $FreeBSD$
- */
-#define VG_DONTLOADIN 0x0001 /* Tells ntfs_vgetex to do not call */
- /* ntfs_loadntnode() on ntnode, even if */
- /* ntnode not loaded */
-#define VG_DONTVALIDFN 0x0002 /* Tells ntfs_vgetex to do not validate */
- /* fnode */
-#define VG_EXT 0x0004 /* This is not main record */
-
-struct mount;
-struct ntfsmount;
-struct thread;
-struct vnode;
-
-int ntfs_vgetex(struct mount *, ino_t, u_int32_t, char *, u_long, u_long,
- struct thread *, struct vnode **);
diff --git a/sys/fs/ntfs/ntfs_vnops.c b/sys/fs/ntfs/ntfs_vnops.c
deleted file mode 100644
index e78dcef..0000000
--- a/sys/fs/ntfs/ntfs_vnops.c
+++ /dev/null
@@ -1,687 +0,0 @@
-/* $NetBSD: ntfs_vnops.c,v 1.23 1999/10/31 19:45:27 jdolecek Exp $ */
-
-/*-
- * Copyright (c) 1992, 1993
- * The Regents of the University of California. All rights reserved.
- *
- * This code is derived from software contributed to Berkeley by
- * John Heidemann of the UCLA Ficus project.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * $FreeBSD$
- *
- */
-
-#include <sys/param.h>
-#include <sys/systm.h>
-#include <sys/kernel.h>
-#include <sys/time.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <sys/vnode.h>
-#include <sys/mount.h>
-#include <sys/namei.h>
-#include <sys/malloc.h>
-#include <sys/bio.h>
-#include <sys/buf.h>
-#include <sys/dirent.h>
-
-#include <vm/vm.h>
-#include <vm/vm_param.h>
-#include <vm/vm_page.h>
-#include <vm/vm_object.h>
-#include <vm/vm_pager.h>
-#include <vm/vnode_pager.h>
-#include <vm/vm_extern.h>
-
-#include <sys/sysctl.h>
-
-/*#define NTFS_DEBUG 1*/
-#include <fs/ntfs/ntfs.h>
-#include <fs/ntfs/ntfs_inode.h>
-#include <fs/ntfs/ntfs_subr.h>
-
-#include <sys/unistd.h> /* for pathconf(2) constants */
-
-static vop_read_t ntfs_read;
-static vop_getattr_t ntfs_getattr;
-static vop_inactive_t ntfs_inactive;
-static vop_reclaim_t ntfs_reclaim;
-static vop_bmap_t ntfs_bmap;
-static vop_strategy_t ntfs_strategy;
-static vop_access_t ntfs_access;
-static vop_open_t ntfs_open;
-static vop_close_t ntfs_close;
-static vop_readdir_t ntfs_readdir;
-static vop_cachedlookup_t ntfs_lookup;
-static vop_pathconf_t ntfs_pathconf;
-static vop_vptofh_t ntfs_vptofh;
-
-/*
- * This is a noop, simply returning what one has been given.
- */
-int
-ntfs_bmap(ap)
- struct vop_bmap_args /* {
- struct vnode *a_vp;
- daddr_t a_bn;
- struct bufobj **a_bop;
- daddr_t *a_bnp;
- int *a_runp;
- int *a_runb;
- } */ *ap;
-{
- struct vnode *vp = ap->a_vp;
-
- dprintf(("ntfs_bmap: vn: %p, blk: %d\n", ap->a_vp,(u_int32_t)ap->a_bn));
- if (ap->a_bop != NULL)
- *ap->a_bop = &vp->v_bufobj;
- if (ap->a_bnp != NULL)
- *ap->a_bnp = ap->a_bn;
- if (ap->a_runp != NULL)
- *ap->a_runp = 0;
- if (ap->a_runb != NULL)
- *ap->a_runb = 0;
- return (0);
-}
-
-static int
-ntfs_read(ap)
- struct vop_read_args /* {
- struct vnode *a_vp;
- struct uio *a_uio;
- int a_ioflag;
- struct ucred *a_cred;
- } */ *ap;
-{
- register struct vnode *vp = ap->a_vp;
- register struct fnode *fp = VTOF(vp);
- register struct ntnode *ip = FTONT(fp);
- struct uio *uio = ap->a_uio;
- struct ntfsmount *ntmp = ip->i_mp;
- struct buf *bp;
- daddr_t cn;
- int resid, off, toread;
- int error;
-
- dprintf(("ntfs_read: ino: %ju, off: %jd resid: %d, segflg: %d\n",
- (uintmax_t)ip->i_number, (intmax_t)uio->uio_offset,
- uio->uio_resid, uio->uio_segflg));
-
- dprintf(("ntfs_read: filesize: %d",(u_int32_t)fp->f_size));
-
- /* don't allow reading after end of file */
- if (uio->uio_offset > fp->f_size)
- return (0);
-
- resid = MIN(uio->uio_resid, fp->f_size - uio->uio_offset);
-
- dprintf((", resid: %d\n", resid));
-
- error = 0;
- while (resid) {
- cn = ntfs_btocn(uio->uio_offset);
- off = ntfs_btocnoff(uio->uio_offset);
-
- toread = MIN(off + resid, ntfs_cntob(1));
-
- error = bread(vp, cn, ntfs_cntob(1), NOCRED, &bp);
- if (error) {
- brelse(bp);
- break;
- }
-
- error = uiomove(bp->b_data + off, toread - off, uio);
- if(error) {
- brelse(bp);
- break;
- }
- brelse(bp);
-
- resid -= toread - off;
- }
-
- return (error);
-}
-
-static int
-ntfs_getattr(ap)
- struct vop_getattr_args /* {
- struct vnode *a_vp;
- struct vattr *a_vap;
- struct ucred *a_cred;
- struct thread *a_td;
- } */ *ap;
-{
- register struct vnode *vp = ap->a_vp;
- register struct fnode *fp = VTOF(vp);
- register struct ntnode *ip = FTONT(fp);
- register struct vattr *vap = ap->a_vap;
-
- dprintf(("ntfs_getattr: %ju, flags: %d\n",
- (uintmax_t)ip->i_number, ip->i_flag));
-
- vap->va_fsid = dev2udev(ip->i_dev);
- vap->va_fileid = ip->i_number;
- vap->va_mode = ip->i_mp->ntm_mode;
- vap->va_nlink = (ip->i_nlink || ip->i_flag & IN_LOADED ? ip->i_nlink : 1);
- vap->va_uid = ip->i_mp->ntm_uid;
- vap->va_gid = ip->i_mp->ntm_gid;
- vap->va_rdev = NODEV;
- vap->va_size = fp->f_size;
- vap->va_bytes = fp->f_allocated;
- vap->va_atime = ntfs_nttimetounix(fp->f_times.t_access);
- vap->va_mtime = ntfs_nttimetounix(fp->f_times.t_write);
- vap->va_ctime = ntfs_nttimetounix(fp->f_times.t_create);
- vap->va_flags = ip->i_flag;
- vap->va_gen = 0;
- vap->va_blocksize = ip->i_mp->ntm_spc * ip->i_mp->ntm_bps;
- vap->va_type = vp->v_type;
- vap->va_filerev = 0;
- return (0);
-}
-
-/*
- * Last reference to an ntnode. If necessary, write or delete it.
- */
-int
-ntfs_inactive(ap)
- struct vop_inactive_args /* {
- struct vnode *a_vp;
- } */ *ap;
-{
-#ifdef NTFS_DEBUG
- register struct ntnode *ip = VTONT(ap->a_vp);
-#endif
-
- dprintf(("ntfs_inactive: vnode: %p, ntnode: %ju\n", ap->a_vp,
- (uintmax_t)ip->i_number));
-
- /* XXX since we don't support any filesystem changes
- * right now, nothing more needs to be done
- */
- return (0);
-}
-
-/*
- * Reclaim an fnode/ntnode so that it can be used for other purposes.
- */
-int
-ntfs_reclaim(ap)
- struct vop_reclaim_args /* {
- struct vnode *a_vp;
- } */ *ap;
-{
- register struct vnode *vp = ap->a_vp;
- register struct fnode *fp = VTOF(vp);
- register struct ntnode *ip = FTONT(fp);
- int error;
-
- dprintf(("ntfs_reclaim: vnode: %p, ntnode: %ju\n",
- vp, (uintmax_t)ip->i_number));
-
- /*
- * Destroy the vm object and flush associated pages.
- */
- vnode_destroy_vobject(vp);
-
- if ((error = ntfs_ntget(ip)) != 0)
- return (error);
-
- /* Purge old data structures associated with the inode. */
- ntfs_frele(fp);
- ntfs_ntput(ip);
- vp->v_data = NULL;
-
- return (0);
-}
-
-/*
- * Calculate the logical to physical mapping if not done already,
- * then call the device strategy routine.
- */
-int
-ntfs_strategy(ap)
- struct vop_strategy_args /* {
- struct buf *a_bp;
- } */ *ap;
-{
- register struct buf *bp = ap->a_bp;
- register struct vnode *vp = ap->a_vp;
- register struct fnode *fp = VTOF(vp);
- register struct ntnode *ip = FTONT(fp);
- struct ntfsmount *ntmp = ip->i_mp;
- u_int32_t toread;
- int error;
-
- dprintf(("ntfs_strategy: offset: %d, blkno: %d, lblkno: %d\n",
- (u_int32_t)bp->b_offset,(u_int32_t)bp->b_blkno,
- (u_int32_t)bp->b_lblkno));
-
- dprintf(("strategy: bcount: %d flags: 0x%x\n",
- (u_int32_t)bp->b_bcount,bp->b_flags));
-
- KASSERT(bp->b_iocmd == BIO_READ, ("Invalid buffer\n"));
-
- if (ntfs_cntob(bp->b_blkno) >= fp->f_size) {
- clrbuf(bp);
- error = 0;
- } else {
- toread = MIN(bp->b_bcount,
- fp->f_size-ntfs_cntob(bp->b_blkno));
- dprintf(("ntfs_strategy: toread: %d, fsize: %d\n",
- toread,(u_int32_t)fp->f_size));
-
- error = ntfs_readattr(ntmp, ip, fp->f_attrtype,
- fp->f_attrname, ntfs_cntob(bp->b_blkno),
- toread, bp->b_data, NULL);
-
- if (error) {
- printf("ntfs_strategy: ntfs_readattr failed\n");
- bp->b_error = error;
- bp->b_ioflags |= BIO_ERROR;
- }
-
- bzero(bp->b_data + toread, bp->b_bcount - toread);
- }
- bufdone(bp);
- return (0);
-}
-
-int
-ntfs_access(ap)
- struct vop_access_args /* {
- struct vnode *a_vp;
- accmode_t a_accmode;
- struct ucred *a_cred;
- struct thread *a_td;
- } */ *ap;
-{
- struct vnode *vp = ap->a_vp;
- struct ntnode *ip = VTONT(vp);
- accmode_t accmode = ap->a_accmode;
-
- dprintf(("ntfs_access: %d\n",ip->i_number));
-
- /*
- * Disallow write attempts as we assume read-only filesystems;
- * unless the file is a socket, fifo, or a block or
- * character device resident on the filesystem.
- */
- if (accmode & VWRITE) {
- switch ((int)vp->v_type) {
- case VDIR:
- case VLNK:
- case VREG:
- return (EROFS);
- default:
- break;
- }
- }
-
- return (vaccess(vp->v_type, ip->i_mp->ntm_mode, ip->i_mp->ntm_uid,
- ip->i_mp->ntm_gid, ap->a_accmode, ap->a_cred, NULL));
-}
-
-/*
- * Open called.
- *
- * Nothing to do.
- */
-/* ARGSUSED */
-static int
-ntfs_open(ap)
- struct vop_open_args /* {
- struct vnode *a_vp;
- int a_mode;
- struct ucred *a_cred;
- struct thread *a_td;
- } */ *ap;
-{
-#ifdef NTFS_DEBUG
- register struct vnode *vp = ap->a_vp;
- register struct ntnode *ip = VTONT(vp);
-
- printf("ntfs_open: %d\n",ip->i_number);
-#endif
-
- vnode_create_vobject(ap->a_vp, VTOF(ap->a_vp)->f_size, ap->a_td);
-
- /*
- * Files marked append-only must be opened for appending.
- */
-
- return (0);
-}
-
-/*
- * Close called.
- *
- * Update the times on the inode.
- */
-/* ARGSUSED */
-static int
-ntfs_close(ap)
- struct vop_close_args /* {
- struct vnode *a_vp;
- int a_fflag;
- struct ucred *a_cred;
- struct thread *a_td;
- } */ *ap;
-{
-#ifdef NTFS_DEBUG
- register struct vnode *vp = ap->a_vp;
- register struct ntnode *ip = VTONT(vp);
-
- printf("ntfs_close: %d\n",ip->i_number);
-#endif
-
- return (0);
-}
-
-int
-ntfs_readdir(ap)
- struct vop_readdir_args /* {
- struct vnode *a_vp;
- struct uio *a_uio;
- struct ucred *a_cred;
- int *a_ncookies;
- u_int **cookies;
- } */ *ap;
-{
- register struct vnode *vp = ap->a_vp;
- register struct fnode *fp = VTOF(vp);
- register struct ntnode *ip = FTONT(fp);
- struct uio *uio = ap->a_uio;
- struct ntfsmount *ntmp = ip->i_mp;
- int i, j, error = 0;
- char *c, tmpbuf[5];
- u_int32_t faked = 0, num;
- int ncookies = 0;
- struct dirent cde;
- off_t off;
-
- dprintf(("ntfs_readdir %d off: %d resid: %d\n",ip->i_number,(u_int32_t)uio->uio_offset,uio->uio_resid));
-
- off = uio->uio_offset;
-
- /* Simulate . in every dir except ROOT */
- if( ip->i_number != NTFS_ROOTINO ) {
- struct dirent dot = {
- .d_fileno = NTFS_ROOTINO,
- .d_reclen = sizeof(struct dirent),
- .d_type = DT_DIR,
- .d_namlen = 1,
- .d_name = "."
- };
-
- if( uio->uio_offset < sizeof(struct dirent) ) {
- dot.d_fileno = ip->i_number;
- error = uiomove((char *)&dot,sizeof(struct dirent),uio);
- if(error)
- return (error);
-
- ncookies ++;
- }
- }
-
- /* Simulate .. in every dir including ROOT */
- if( uio->uio_offset < 2 * sizeof(struct dirent) ) {
- struct dirent dotdot = {
- .d_fileno = NTFS_ROOTINO,
- .d_reclen = sizeof(struct dirent),
- .d_type = DT_DIR,
- .d_namlen = 2,
- .d_name = ".."
- };
-
- error = uiomove((char *)&dotdot,sizeof(struct dirent),uio);
- if(error)
- return (error);
-
- ncookies ++;
- }
-
- faked = (ip->i_number == NTFS_ROOTINO) ? 1 : 2;
- num = uio->uio_offset / sizeof(struct dirent) - faked;
-
- while( uio->uio_resid >= sizeof(struct dirent) ) {
- struct attr_indexentry *iep;
-
- error = ntfs_ntreaddir(ntmp, fp, num, &iep);
-
- if(error)
- return (error);
-
- if( NULL == iep )
- break;
-
- for(; !(iep->ie_flag & NTFS_IEFLAG_LAST) && (uio->uio_resid >= sizeof(struct dirent));
- iep = NTFS_NEXTREC(iep, struct attr_indexentry *))
- {
- if(!ntfs_isnamepermitted(ntmp,iep))
- continue;
-
- for(i=0, j=0; i<iep->ie_fnamelen; i++) {
- c = NTFS_U28(iep->ie_fname[i]);
- while (*c != '\0')
- cde.d_name[j++] = *c++;
- }
- cde.d_name[j] = '\0';
- dprintf(("ntfs_readdir: elem: %d, fname:[%s] type: %d, flag: %d, ",
- num, cde.d_name, iep->ie_fnametype,
- iep->ie_flag));
- cde.d_namlen = j;
- cde.d_fileno = iep->ie_number;
- cde.d_type = (iep->ie_fflag & NTFS_FFLAG_DIR) ? DT_DIR : DT_REG;
- cde.d_reclen = sizeof(struct dirent);
- dprintf(("%s\n", (cde.d_type == DT_DIR) ? "dir":"reg"));
-
- error = uiomove((char *)&cde, sizeof(struct dirent), uio);
- if(error)
- return (error);
-
- ncookies++;
- num++;
- }
- }
-
- dprintf(("ntfs_readdir: %d entries (%d bytes) read\n",
- ncookies,(u_int)(uio->uio_offset - off)));
- dprintf(("ntfs_readdir: off: %d resid: %d\n",
- (u_int32_t)uio->uio_offset,uio->uio_resid));
-
- if (!error && ap->a_ncookies != NULL) {
- struct dirent* dpStart;
- struct dirent* dp;
- u_long *cookies;
- u_long *cookiep;
-
- ddprintf(("ntfs_readdir: %d cookies\n",ncookies));
- if (uio->uio_segflg != UIO_SYSSPACE || uio->uio_iovcnt != 1)
- panic("ntfs_readdir: unexpected uio from NFS server");
- dpStart = (struct dirent *)
- ((caddr_t)uio->uio_iov->iov_base -
- (uio->uio_offset - off));
- cookies = malloc(ncookies * sizeof(u_long),
- M_TEMP, M_WAITOK);
- for (dp = dpStart, cookiep = cookies, i=0;
- i < ncookies;
- dp = (struct dirent *)((caddr_t) dp + dp->d_reclen), i++) {
- off += dp->d_reclen;
- *cookiep++ = (u_int) off;
- }
- *ap->a_ncookies = ncookies;
- *ap->a_cookies = cookies;
- }
-/*
- if (ap->a_eofflag)
- *ap->a_eofflag = VTONT(ap->a_vp)->i_size <= uio->uio_offset;
-*/
- return (error);
-}
-
-int
-ntfs_lookup(ap)
- struct vop_cachedlookup_args /* {
- struct vnode *a_dvp;
- struct vnode **a_vpp;
- struct componentname *a_cnp;
- } */ *ap;
-{
- register struct vnode *dvp = ap->a_dvp;
- register struct ntnode *dip = VTONT(dvp);
- struct ntfsmount *ntmp = dip->i_mp;
- struct componentname *cnp = ap->a_cnp;
- struct ucred *cred = cnp->cn_cred;
- int error;
- dprintf(("ntfs_lookup: \"%.*s\" (%ld bytes) in %d\n",
- (int)cnp->cn_namelen, cnp->cn_nameptr, cnp->cn_namelen,
- dip->i_number));
-
- error = VOP_ACCESS(dvp, VEXEC, cred, cnp->cn_thread);
- if(error)
- return (error);
-
- if ((cnp->cn_flags & ISLASTCN) &&
- (cnp->cn_nameiop == DELETE || cnp->cn_nameiop == RENAME))
- return (EROFS);
-
- if(cnp->cn_namelen == 1 && cnp->cn_nameptr[0] == '.') {
- dprintf(("ntfs_lookup: faking . directory in %d\n",
- dip->i_number));
-
- VREF(dvp);
- *ap->a_vpp = dvp;
- error = 0;
- } else if (cnp->cn_flags & ISDOTDOT) {
- struct ntvattr *vap;
-
- dprintf(("ntfs_lookup: faking .. directory in %d\n",
- dip->i_number));
-
- error = ntfs_ntvattrget(ntmp, dip, NTFS_A_NAME, NULL, 0, &vap);
- if(error)
- return (error);
-
- VOP_UNLOCK(dvp,0);
- dprintf(("ntfs_lookup: parentdir: %d\n",
- vap->va_a_name->n_pnumber));
- error = VFS_VGET(ntmp->ntm_mountp, vap->va_a_name->n_pnumber,
- LK_EXCLUSIVE, ap->a_vpp);
- ntfs_ntvattrrele(vap);
- if (error) {
- vn_lock(dvp,LK_EXCLUSIVE|LK_RETRY);
- return (error);
- }
- } else {
- error = ntfs_ntlookupfile(ntmp, dvp, cnp, ap->a_vpp);
- if (error) {
- dprintf(("ntfs_ntlookupfile: returned %d\n", error));
- return (error);
- }
-
- dprintf(("ntfs_lookup: found ino: %ju\n",
- (uintmax_t)VTONT(*ap->a_vpp)->i_number));
- }
-
- if (cnp->cn_flags & MAKEENTRY)
- cache_enter(dvp, *ap->a_vpp, cnp);
-
- return (error);
-}
-
-/*
- * Return POSIX pathconf information applicable to NTFS filesystem
- */
-int
-ntfs_pathconf(ap)
- struct vop_pathconf_args *ap;
-{
-
- switch (ap->a_name) {
- case _PC_LINK_MAX:
- *ap->a_retval = 1;
- return (0);
- case _PC_NAME_MAX:
- *ap->a_retval = NTFS_MAXFILENAME;
- return (0);
- case _PC_PATH_MAX:
- *ap->a_retval = PATH_MAX;
- return (0);
- case _PC_CHOWN_RESTRICTED:
- *ap->a_retval = 1;
- return (0);
- case _PC_NO_TRUNC:
- *ap->a_retval = 0;
- return (0);
- default:
- return (EINVAL);
- }
- /* NOTREACHED */
-}
-
-int
-ntfs_vptofh(ap)
- struct vop_vptofh_args /* {
- struct vnode *a_vp;
- struct fid *a_fhp;
- } */ *ap;
-{
- register struct ntnode *ntp;
- register struct ntfid *ntfhp;
-
- ddprintf(("ntfs_fhtovp(): %p\n", ap->a_vp));
-
- ntp = VTONT(ap->a_vp);
- ntfhp = (struct ntfid *)ap->a_fhp;
- ntfhp->ntfid_len = sizeof(struct ntfid);
- ntfhp->ntfid_ino = ntp->i_number;
- /* ntfhp->ntfid_gen = ntp->i_gen; */
- return (0);
-}
-
-/*
- * Global vfs data structures
- */
-struct vop_vector ntfs_vnodeops = {
- .vop_default = &default_vnodeops,
-
- .vop_access = ntfs_access,
- .vop_bmap = ntfs_bmap,
- .vop_cachedlookup = ntfs_lookup,
- .vop_close = ntfs_close,
- .vop_getattr = ntfs_getattr,
- .vop_inactive = ntfs_inactive,
- .vop_lookup = vfs_cache_lookup,
- .vop_open = ntfs_open,
- .vop_pathconf = ntfs_pathconf,
- .vop_read = ntfs_read,
- .vop_readdir = ntfs_readdir,
- .vop_reclaim = ntfs_reclaim,
- .vop_strategy = ntfs_strategy,
- .vop_vptofh = ntfs_vptofh,
-};
diff --git a/sys/fs/ntfs/ntfsmount.h b/sys/fs/ntfs/ntfsmount.h
deleted file mode 100644
index f64652c..0000000
--- a/sys/fs/ntfs/ntfsmount.h
+++ /dev/null
@@ -1,44 +0,0 @@
-/* $NetBSD: ntfsmount.h,v 1.3 1999/07/26 14:02:32 jdolecek Exp $ */
-
-/*-
- * Copyright (c) 1998, 1999 Semen Ustimenko
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * $FreeBSD$
- */
-
-#define NTFS_MFLAG_CASEINS 0x00000001
-#define NTFS_MFLAG_ALLNAMES 0x00000002
-#define NTFS_MFLAG_KICONV 0x00000004
-
-struct ntfs_args {
- char *fspec; /* block special device to mount */
- struct oexport_args export; /* network export information */
- uid_t uid; /* uid that owns ntfs files */
- gid_t gid; /* gid that owns ntfs files */
- mode_t mode; /* mask to be applied for ntfs perms */
- u_long flag; /* additional flags */
- char *cs_ntfs; /* NTFS Charset */
- char *cs_local; /* Local Charset */
-};
diff --git a/sys/fs/portalfs/portal.h b/sys/fs/portalfs/portal.h
deleted file mode 100644
index 1fd2d99..0000000
--- a/sys/fs/portalfs/portal.h
+++ /dev/null
@@ -1,67 +0,0 @@
-/*-
- * Copyright (c) 1992, 1993
- * The Regents of the University of California. All rights reserved.
- *
- * This code is derived from software donated to Berkeley by
- * Jan-Simon Pendry.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * @(#)portal.h 8.4 (Berkeley) 1/21/94
- *
- * $FreeBSD$
- */
-
-struct portal_args {
- char *pa_config; /* Config file */
- int pa_socket; /* Socket to server */
-};
-
-struct portal_cred {
- int pcr_flag; /* File open mode */
- uid_t pcr_uid; /* From ucred */
- short pcr_ngroups; /* From ucred */
- gid_t pcr_groups[XU_NGROUPS]; /* From ucred */
-};
-
-#ifdef _KERNEL
-struct portalmount {
- struct vnode *pm_root; /* Root node */
- struct file *pm_server; /* Held reference to server socket */
-};
-
-struct portalnode {
- int pt_size; /* Length of Arg */
- char *pt_arg; /* Arg to send to server */
- int pt_fileid; /* cookie */
-};
-
-#define VFSTOPORTAL(mp) ((struct portalmount *)((mp)->mnt_data))
-#define VTOPORTAL(vp) ((struct portalnode *)(vp)->v_data)
-
-#define PORTAL_ROOTFILEID 2
-
-extern struct vop_vector portal_vnodeops;
-#endif /* _KERNEL */
diff --git a/sys/fs/portalfs/portal_vfsops.c b/sys/fs/portalfs/portal_vfsops.c
deleted file mode 100644
index 62131dc..0000000
--- a/sys/fs/portalfs/portal_vfsops.c
+++ /dev/null
@@ -1,263 +0,0 @@
-/*-
- * Copyright (c) 1992, 1993, 1995
- * The Regents of the University of California. All rights reserved.
- *
- * This code is derived from software donated to Berkeley by
- * Jan-Simon Pendry.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * @(#)portal_vfsops.c 8.11 (Berkeley) 5/14/95
- *
- * $FreeBSD$
- */
-
-/*
- * Portal Filesystem
- */
-
-#include <sys/param.h>
-#include <sys/systm.h>
-#include <sys/capability.h>
-#include <sys/domain.h>
-#include <sys/filedesc.h>
-#include <sys/kernel.h>
-#include <sys/lock.h>
-#include <sys/mutex.h>
-#include <sys/malloc.h>
-#include <sys/file.h> /* Must come after sys/malloc.h */
-#include <sys/mount.h>
-#include <sys/proc.h>
-#include <sys/protosw.h>
-#include <sys/socket.h>
-#include <sys/socketvar.h>
-#include <sys/vnode.h>
-
-#include <fs/portalfs/portal.h>
-
-static MALLOC_DEFINE(M_PORTALFSMNT, "portal_mount", "PORTAL mount structure");
-
-static vfs_unmount_t portal_unmount;
-static vfs_root_t portal_root;
-static vfs_statfs_t portal_statfs;
-
-static const char *portal_opts[] = {
- "socket", "config",
- NULL
-};
-
-static int
-portal_cmount(struct mntarg *ma, void *data, uint64_t flags)
-{
- struct portal_args args;
- int error;
-
- if (data == NULL)
- return (EINVAL);
- error = copyin(data, &args, sizeof args);
- if (error)
- return (error);
-
- ma = mount_argf(ma, "socket", "%d", args.pa_socket);
- ma = mount_argsu(ma, "config", args.pa_config, MAXPATHLEN);
- error = kernel_mount(ma, flags);
-
- return (error);
-}
-
-/*
- * Mount the per-process file descriptors (/dev/fd)
- */
-static int
-portal_mount(struct mount *mp)
-{
- struct file *fp;
- struct portalmount *fmp;
- struct socket *so;
- struct vnode *rvp;
- struct thread *td;
- struct portalnode *pn;
- int error, v;
- char *p;
-
- td = curthread;
- if (vfs_filteropt(mp->mnt_optnew, portal_opts))
- return (EINVAL);
-
- error = vfs_scanopt(mp->mnt_optnew, "socket", "%d", &v);
- if (error != 1)
- return (EINVAL);
- error = vfs_getopt(mp->mnt_optnew, "config", (void **)&p, NULL);
- if (error)
- return (error);
-
- /*
- * Capsicum is not incompatible with portalfs, but we don't really
- * know what rights are required. In the spirit of "better safe than
- * sorry", pretend that all rights are required for now.
- */
- if ((error = fget(td, v, CAP_MASK_VALID, &fp)) != 0)
- return (error);
- if (fp->f_type != DTYPE_SOCKET) {
- fdrop(fp, td);
- return(ENOTSOCK);
- }
- so = fp->f_data; /* XXX race against userland */
- if (so->so_proto->pr_domain->dom_family != AF_UNIX) {
- fdrop(fp, td);
- return (ESOCKTNOSUPPORT);
- }
-
- pn = malloc(sizeof(struct portalnode),
- M_TEMP, M_WAITOK);
-
- fmp = malloc(sizeof(struct portalmount),
- M_PORTALFSMNT, M_WAITOK); /* XXX */
-
- error = getnewvnode("portal", mp, &portal_vnodeops, &rvp); /* XXX */
- if (error) {
- free(fmp, M_PORTALFSMNT);
- free(pn, M_TEMP);
- fdrop(fp, td);
- return (error);
- }
-
- error = insmntque(rvp, mp); /* XXX: Too early for mpsafe fs */
- if (error != 0) {
- free(fmp, M_PORTALFSMNT);
- free(pn, M_TEMP);
- fdrop(fp, td);
- return (error);
- }
- rvp->v_data = pn;
- rvp->v_type = VDIR;
- rvp->v_vflag |= VV_ROOT;
- VTOPORTAL(rvp)->pt_arg = 0;
- VTOPORTAL(rvp)->pt_size = 0;
- VTOPORTAL(rvp)->pt_fileid = PORTAL_ROOTFILEID;
- fmp->pm_root = rvp;
- fhold(fp);
- fmp->pm_server = fp;
-
- MNT_ILOCK(mp);
- mp->mnt_flag |= MNT_LOCAL;
- MNT_IUNLOCK(mp);
- mp->mnt_data = fmp;
- vfs_getnewfsid(mp);
-
- vfs_mountedfrom(mp, p);
- fdrop(fp, td);
- return (0);
-}
-
-static int
-portal_unmount(mp, mntflags)
- struct mount *mp;
- int mntflags;
-{
- int error, flags = 0;
-
-
- if (mntflags & MNT_FORCE)
- flags |= FORCECLOSE;
-
- /*
- * Clear out buffer cache. I don't think we
- * ever get anything cached at this level at the
- * moment, but who knows...
- */
-#ifdef notyet
- mntflushbuf(mp, 0);
- if (mntinvalbuf(mp, 1))
- return (EBUSY);
-#endif
- /* There is 1 extra root vnode reference (pm_root). */
- error = vflush(mp, 1, flags, curthread);
- if (error)
- return (error);
-
- /*
- * Shutdown the socket. This will cause the select in the
- * daemon to wake up, and then the accept will get ECONNABORTED
- * which it interprets as a request to go and bury itself.
- */
- soshutdown(VFSTOPORTAL(mp)->pm_server->f_data, 2);
- /*
- * Discard reference to underlying file. Must call closef because
- * this may be the last reference.
- */
- closef(VFSTOPORTAL(mp)->pm_server, (struct thread *) 0);
- /*
- * Finally, throw away the portalmount structure
- */
- free(mp->mnt_data, M_PORTALFSMNT); /* XXX */
- mp->mnt_data = NULL;
- return (0);
-}
-
-static int
-portal_root(mp, flags, vpp)
- struct mount *mp;
- int flags;
- struct vnode **vpp;
-{
- struct vnode *vp;
-
- /*
- * Return locked reference to root.
- */
- vp = VFSTOPORTAL(mp)->pm_root;
- VREF(vp);
- vn_lock(vp, LK_EXCLUSIVE | LK_RETRY);
- *vpp = vp;
- return (0);
-}
-
-static int
-portal_statfs(mp, sbp)
- struct mount *mp;
- struct statfs *sbp;
-{
-
- sbp->f_flags = 0;
- sbp->f_bsize = DEV_BSIZE;
- sbp->f_iosize = DEV_BSIZE;
- sbp->f_blocks = 2; /* 1K to keep df happy */
- sbp->f_bfree = 0;
- sbp->f_bavail = 0;
- sbp->f_files = 1; /* Allow for "." */
- sbp->f_ffree = 0; /* See comments above */
- return (0);
-}
-
-static struct vfsops portal_vfsops = {
- .vfs_cmount = portal_cmount,
- .vfs_mount = portal_mount,
- .vfs_root = portal_root,
- .vfs_statfs = portal_statfs,
- .vfs_unmount = portal_unmount,
-};
-
-VFS_SET(portal_vfsops, portalfs, VFCF_SYNTHETIC);
diff --git a/sys/fs/portalfs/portal_vnops.c b/sys/fs/portalfs/portal_vnops.c
deleted file mode 100644
index 6b70dae..0000000
--- a/sys/fs/portalfs/portal_vnops.c
+++ /dev/null
@@ -1,586 +0,0 @@
-/*-
- * Copyright (c) 1992, 1993
- * The Regents of the University of California. All rights reserved.
- *
- * This code is derived from software donated to Berkeley by
- * Jan-Simon Pendry.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * @(#)portal_vnops.c 8.14 (Berkeley) 5/21/95
- *
- * $FreeBSD$
- */
-
-/*
- * Portal Filesystem
- */
-
-#include "opt_capsicum.h"
-
-#include <sys/param.h>
-#include <sys/capability.h>
-#include <sys/fcntl.h>
-#include <sys/file.h>
-#include <sys/kernel.h>
-#include <sys/lock.h>
-#include <sys/malloc.h>
-#include <sys/mbuf.h>
-#include <sys/mount.h>
-#include <sys/mutex.h>
-#include <sys/namei.h>
-#include <sys/proc.h>
-#include <sys/socket.h>
-#include <sys/socketvar.h>
-#include <sys/stat.h>
-#include <sys/syscallsubr.h>
-#include <sys/systm.h>
-#include <sys/un.h>
-#include <sys/unpcb.h>
-#include <sys/vnode.h>
-
-#include <fs/portalfs/portal.h>
-
-#include <net/vnet.h>
-
-static int portal_fileid = PORTAL_ROOTFILEID+1;
-
-static void portal_closefd(struct thread *td, int fd);
-static int portal_connect(struct socket *so, struct socket *so2);
-static vop_getattr_t portal_getattr;
-static vop_lookup_t portal_lookup;
-static vop_open_t portal_open;
-static vop_readdir_t portal_readdir;
-static vop_reclaim_t portal_reclaim;
-static vop_setattr_t portal_setattr;
-
-static void
-portal_closefd(td, fd)
- struct thread *td;
- int fd;
-{
- int error;
-
- error = kern_close(td, fd);
- /*
- * We should never get an error, and there isn't anything
- * we could do if we got one, so just print a message.
- */
- if (error)
- printf("portal_closefd: error = %d\n", error);
-}
-
-/*
- * vp is the current namei directory
- * cnp is the name to locate in that directory...
- */
-static int
-portal_lookup(ap)
- struct vop_lookup_args /* {
- struct vnode * a_dvp;
- struct vnode ** a_vpp;
- struct componentname * a_cnp;
- } */ *ap;
-{
- struct componentname *cnp = ap->a_cnp;
- struct vnode **vpp = ap->a_vpp;
- struct vnode *dvp = ap->a_dvp;
- char *pname = cnp->cn_nameptr;
- struct portalnode *pt;
- int error;
- struct vnode *fvp = NULL;
- char *path;
- int size;
-
- *vpp = NULLVP;
-
- if (cnp->cn_nameiop == DELETE || cnp->cn_nameiop == RENAME)
- return (EROFS);
-
- if (cnp->cn_namelen == 1 && *pname == '.') {
- *vpp = dvp;
- VREF(dvp);
- return (0);
- }
- KASSERT((cnp->cn_flags & ISDOTDOT) == 0,
- ("portal_lookup: Can not handle dotdot lookups."));
-
- /*
- * Do the MALLOC before the getnewvnode since doing so afterward
- * might cause a bogus v_data pointer to get dereferenced
- * elsewhere if MALLOC should block.
- */
- pt = malloc(sizeof(struct portalnode),
- M_TEMP, M_WAITOK);
-
- error = getnewvnode("portal", dvp->v_mount, &portal_vnodeops, &fvp);
- if (error) {
- free(pt, M_TEMP);
- goto bad;
- }
- fvp->v_type = VREG;
- fvp->v_data = pt;
- /*
- * Save all of the remaining pathname and
- * advance the namei next pointer to the end
- * of the string.
- */
- for (size = 0, path = pname; *path; path++)
- size++;
- cnp->cn_consume = size - cnp->cn_namelen;
-
- pt->pt_arg = malloc(size+1, M_TEMP, M_WAITOK);
- pt->pt_size = size+1;
- bcopy(pname, pt->pt_arg, pt->pt_size);
- pt->pt_fileid = portal_fileid++;
-
- *vpp = fvp;
- vn_lock(fvp, LK_EXCLUSIVE | LK_RETRY);
- error = insmntque(fvp, dvp->v_mount);
- if (error != 0) {
- *vpp = NULLVP;
- return (error);
- }
- return (0);
-
-bad:;
- if (fvp)
- vrele(fvp);
- return (error);
-}
-
-static int
-portal_connect(so, so2)
- struct socket *so;
- struct socket *so2;
-{
- /* from unp_connect, bypassing the namei stuff... */
- struct socket *so3;
- struct unpcb *unp2;
- struct unpcb *unp3;
-
- if (so2 == 0)
- return (ECONNREFUSED);
-
- if (so->so_type != so2->so_type)
- return (EPROTOTYPE);
-
- if ((so2->so_options & SO_ACCEPTCONN) == 0)
- return (ECONNREFUSED);
-
- CURVNET_SET(so2->so_vnet);
- if ((so3 = sonewconn(so2, 0)) == 0) {
- CURVNET_RESTORE();
- return (ECONNREFUSED);
- }
- CURVNET_RESTORE();
-
- unp2 = sotounpcb(so2);
- unp3 = sotounpcb(so3);
- if (unp2->unp_addr)
- unp3->unp_addr = (struct sockaddr_un *)
- sodupsockaddr((struct sockaddr *)unp2->unp_addr,
- M_NOWAIT);
- so2 = so3;
-
- return (soconnect2(so, so2));
-}
-
-static int
-portal_open(ap)
- struct vop_open_args /* {
- struct vnode *a_vp;
- int a_mode;
- struct ucred *a_cred;
- struct thread *a_td;
- } */ *ap;
-{
- struct socket *so = NULL;
- struct portalnode *pt;
- struct thread *td = ap->a_td;
- struct vnode *vp = ap->a_vp;
- struct uio auio;
- struct iovec aiov[2];
- int res;
- struct mbuf *cm = NULL;
- struct cmsghdr *cmsg;
- int newfds;
- int *ip;
- int fd;
- int error;
- int len;
- struct portalmount *fmp;
- struct file *fp;
- struct portal_cred pcred;
-
-#ifdef CAPABILITY_MODE
- /*
- * This may require access to a global namespace (e.g. an IP address);
- * disallow it entirely, as we do open(2).
- */
- if (IN_CAPABILITY_MODE(td)) {
-#ifdef KTRACE
- if (KTRPOINT(td, KTR_CAPFAIL))
- ktrcapfail(CAPFAIL_SYSCALL, 0, 0);
-#endif
- return (ECAPMODE);
- }
-#endif
-
- /*
- * Nothing to do when opening the root node.
- */
- if (vp->v_vflag & VV_ROOT)
- return (0);
-
- /*
- * Can't be opened unless the caller is set up
- * to deal with the side effects. Check for this
- * by testing whether td_dupfd has been set.
- */
- if (td->td_dupfd >= 0)
- return (ENODEV);
-
- pt = VTOPORTAL(vp);
- fmp = VFSTOPORTAL(vp->v_mount);
-
- /*
- * Create a new socket.
- */
- error = socreate(AF_UNIX, &so, SOCK_STREAM, 0, ap->a_cred,
- ap->a_td);
- if (error)
- goto bad;
-
- /*
- * Reserve some buffer space
- */
- res = pt->pt_size + sizeof(pcred) + 512; /* XXX */
- error = soreserve(so, res, res);
- if (error)
- goto bad;
-
- /*
- * Kick off connection
- */
- error = portal_connect(so, fmp->pm_server->f_data);
- if (error)
- goto bad;
-
- /*
- * Wait for connection to complete
- */
- /*
- * XXX: Since the mount point is holding a reference on the
- * underlying server socket, it is not easy to find out whether
- * the server process is still running. To handle this problem
- * we loop waiting for the new socket to be connected (something
- * which will only happen if the server is still running) or for
- * the reference count on the server socket to drop to 1, which
- * will happen if the server dies. Sleep for 5 second intervals
- * and keep polling the reference count. XXX.
- */
- SOCK_LOCK(so);
- while ((so->so_state & SS_ISCONNECTING) && so->so_error == 0) {
- if (fmp->pm_server->f_count == 1) {
- SOCK_UNLOCK(so);
- error = ECONNREFUSED;
- goto bad;
- }
- (void) msleep((caddr_t) &so->so_timeo, SOCK_MTX(so), PSOCK,
- "portalcon", 5 * hz);
- }
- SOCK_UNLOCK(so);
-
- if (so->so_error) {
- error = so->so_error;
- goto bad;
- }
-
- /*
- * Set miscellaneous flags
- */
- SOCKBUF_LOCK(&so->so_rcv);
- so->so_rcv.sb_timeo = 0;
- so->so_rcv.sb_flags |= SB_NOINTR;
- SOCKBUF_UNLOCK(&so->so_rcv);
- SOCKBUF_LOCK(&so->so_snd);
- so->so_snd.sb_timeo = 0;
- so->so_snd.sb_flags |= SB_NOINTR;
- SOCKBUF_UNLOCK(&so->so_snd);
-
-
- pcred.pcr_flag = ap->a_mode;
- pcred.pcr_uid = ap->a_cred->cr_uid;
- pcred.pcr_ngroups = MIN(ap->a_cred->cr_ngroups, XU_NGROUPS);
- bcopy(ap->a_cred->cr_groups, pcred.pcr_groups,
- pcred.pcr_ngroups * sizeof(gid_t));
- aiov[0].iov_base = (caddr_t) &pcred;
- aiov[0].iov_len = sizeof(pcred);
- aiov[1].iov_base = pt->pt_arg;
- aiov[1].iov_len = pt->pt_size;
- auio.uio_iov = aiov;
- auio.uio_iovcnt = 2;
- auio.uio_rw = UIO_WRITE;
- auio.uio_segflg = UIO_SYSSPACE;
- auio.uio_td = td;
- auio.uio_offset = 0;
- auio.uio_resid = aiov[0].iov_len + aiov[1].iov_len;
-
- error = sosend(so, (struct sockaddr *) 0, &auio,
- (struct mbuf *) 0, (struct mbuf *) 0, 0 , td);
- if (error)
- goto bad;
-
- len = auio.uio_resid = sizeof(int);
- do {
- struct mbuf *m = NULL;
- int flags = MSG_WAITALL;
- error = soreceive(so, (struct sockaddr **) 0, &auio,
- &m, &cm, &flags);
- if (error)
- goto bad;
-
- /*
- * Grab an error code from the mbuf.
- */
- if (m) {
- m = m_pullup(m, sizeof(int)); /* Needed? */
- if (m) {
- error = *(mtod(m, int *));
- m_freem(m);
- } else {
- error = EINVAL;
- }
- } else {
- if (cm == 0) {
- error = ECONNRESET; /* XXX */
-#ifdef notdef
- break;
-#endif
- }
- }
- } while (cm == 0 && auio.uio_resid == len && !error);
-
- if (cm == 0)
- goto bad;
-
- if (auio.uio_resid) {
- error = 0;
-#ifdef notdef
- error = EMSGSIZE;
- goto bad;
-#endif
- }
-
- /*
- * XXX: Break apart the control message, and retrieve the
- * received file descriptor. Note that more than one descriptor
- * may have been received, or that the rights chain may have more
- * than a single mbuf in it. What to do?
- */
- cmsg = mtod(cm, struct cmsghdr *);
- newfds = (cmsg->cmsg_len - sizeof(*cmsg)) / sizeof (int);
- if (newfds == 0) {
- error = ECONNREFUSED;
- goto bad;
- }
- /*
- * At this point the rights message consists of a control message
- * header, followed by a data region containing a vector of
- * integer file descriptors. The fds were allocated by the action
- * of receiving the control message.
- */
- ip = (int *) (cmsg + 1);
- fd = *ip++;
- if (newfds > 1) {
- /*
- * Close extra fds.
- */
- int i;
- printf("portal_open: %d extra fds\n", newfds - 1);
- for (i = 1; i < newfds; i++) {
- portal_closefd(td, *ip);
- ip++;
- }
- }
-
- /*
- * Check that the mode the file is being opened for is a subset
- * of the mode of the existing descriptor.
- */
- if ((error = fget(td, fd, 0, &fp)) != 0)
- goto bad;
- if (((ap->a_mode & (FREAD|FWRITE)) | fp->f_flag) != fp->f_flag) {
- fdrop(fp, td);
- portal_closefd(td, fd);
- error = EACCES;
- goto bad;
- }
- fdrop(fp, td);
-
- /*
- * Save the dup fd in the proc structure then return the
- * special error code (ENXIO) which causes magic things to
- * happen in vn_open. The whole concept is, well, hmmm.
- */
- td->td_dupfd = fd;
- error = ENXIO;
-
-bad:;
- /*
- * And discard the control message.
- */
- if (cm) {
- m_freem(cm);
- }
-
- if (so) {
- soshutdown(so, 2);
- soclose(so);
- }
- return (error);
-}
-
-static int
-portal_getattr(ap)
- struct vop_getattr_args /* {
- struct vnode *a_vp;
- struct vattr *a_vap;
- struct ucred *a_cred;
- } */ *ap;
-{
- struct vnode *vp = ap->a_vp;
- struct vattr *vap = ap->a_vap;
-
- vap->va_uid = 0;
- vap->va_gid = 0;
- vap->va_size = DEV_BSIZE;
- vap->va_blocksize = DEV_BSIZE;
- nanotime(&vap->va_atime);
- vap->va_mtime = vap->va_atime;
- vap->va_ctime = vap->va_mtime;
- vap->va_gen = 0;
- vap->va_flags = 0;
- vap->va_rdev = NODEV;
- /* vap->va_qbytes = 0; */
- vap->va_bytes = 0;
- vap->va_filerev = 0;
- /* vap->va_qsize = 0; */
- if (vp->v_vflag & VV_ROOT) {
- vap->va_type = VDIR;
- vap->va_mode = S_IRUSR|S_IWUSR|S_IXUSR|
- S_IRGRP|S_IWGRP|S_IXGRP|
- S_IROTH|S_IWOTH|S_IXOTH;
- vap->va_nlink = 2;
- vap->va_fileid = 2;
- } else {
- vap->va_type = VREG;
- vap->va_mode = S_IRUSR|S_IWUSR|
- S_IRGRP|S_IWGRP|
- S_IROTH|S_IWOTH;
- vap->va_nlink = 1;
- vap->va_fileid = VTOPORTAL(vp)->pt_fileid;
- }
- return (0);
-}
-
-static int
-portal_setattr(ap)
- struct vop_setattr_args /* {
- struct vnode *a_vp;
- struct vattr *a_vap;
- struct ucred *a_cred;
- } */ *ap;
-{
-
- /*
- * Can't mess with the root vnode
- */
- if (ap->a_vp->v_vflag & VV_ROOT)
- return (EACCES);
-
- if (ap->a_vap->va_flags != VNOVAL)
- return (EOPNOTSUPP);
-
- return (0);
-}
-
-/*
- * Fake readdir, just return empty directory.
- * It is hard to deal with '.' and '..' so don't bother.
- */
-static int
-portal_readdir(ap)
- struct vop_readdir_args /* {
- struct vnode *a_vp;
- struct uio *a_uio;
- struct ucred *a_cred;
- int *a_eofflag;
- u_long *a_cookies;
- int a_ncookies;
- } */ *ap;
-{
-
- /*
- * We don't allow exporting portal mounts, and currently local
- * requests do not need cookies.
- */
- if (ap->a_ncookies)
- panic("portal_readdir: not hungry");
-
- return (0);
-}
-
-static int
-portal_reclaim(ap)
- struct vop_reclaim_args /* {
- struct vnode *a_vp;
- } */ *ap;
-{
- struct portalnode *pt = VTOPORTAL(ap->a_vp);
-
- if (pt->pt_arg) {
- free((caddr_t) pt->pt_arg, M_TEMP);
- pt->pt_arg = 0;
- }
- free(ap->a_vp->v_data, M_TEMP);
- ap->a_vp->v_data = 0;
-
- return (0);
-}
-
-struct vop_vector portal_vnodeops = {
- .vop_default = &default_vnodeops,
-
- .vop_access = VOP_NULL,
- .vop_getattr = portal_getattr,
- .vop_lookup = portal_lookup,
- .vop_open = portal_open,
- .vop_pathconf = vop_stdpathconf,
- .vop_readdir = portal_readdir,
- .vop_reclaim = portal_reclaim,
- .vop_setattr = portal_setattr,
-};
diff --git a/sys/geom/label/g_label_ntfs.c b/sys/geom/label/g_label_ntfs.c
index 1ee3f79..1ed4a07 100644
--- a/sys/geom/label/g_label_ntfs.c
+++ b/sys/geom/label/g_label_ntfs.c
@@ -32,21 +32,72 @@ __FBSDID("$FreeBSD$");
#include <sys/kernel.h>
#include <sys/malloc.h>
-#include <fs/ntfs/ntfs.h>
-
#include <geom/geom.h>
#include <geom/label/g_label.h>
+#define NTFS_A_VOLUMENAME 0x60
+#define NTFS_FILEMAGIC ((uint32_t)(0x454C4946))
+#define NTFS_VOLUMEINO 3
+
#define G_LABEL_NTFS_DIR "ntfs"
+struct ntfs_attr {
+ uint32_t a_type;
+ uint32_t reclen;
+ uint8_t a_flag;
+ uint8_t a_namelen;
+ uint8_t a_nameoff;
+ uint8_t reserved1;
+ uint8_t a_compression;
+ uint8_t reserved2;
+ uint16_t a_index;
+ uint16_t a_datalen;
+ uint16_t reserved3;
+ uint16_t a_dataoff;
+ uint16_t a_indexed;
+} __packed;
+
+struct ntfs_filerec {
+ uint32_t fr_hdrmagic;
+ uint16_t fr_hdrfoff;
+ uint16_t fr_hdrfnum;
+ uint8_t reserved[8];
+ uint16_t fr_seqnum;
+ uint16_t fr_nlink;
+ uint16_t fr_attroff;
+ uint16_t fr_flags;
+ uint32_t fr_size;
+ uint32_t fr_allocated;
+ uint64_t fr_mainrec;
+ uint16_t fr_attrnum;
+} __packed;
+
+struct ntfs_bootfile {
+ uint8_t reserved1[3];
+ uint8_t bf_sysid[8];
+ uint16_t bf_bps;
+ uint8_t bf_spc;
+ uint8_t reserved2[7];
+ uint8_t bf_media;
+ uint8_t reserved3[2];
+ uint16_t bf_spt;
+ uint16_t bf_heads;
+ uint8_t reserver4[12];
+ uint64_t bf_spv;
+ uint64_t bf_mftcn;
+ uint64_t bf_mftmirrcn;
+ uint8_t bf_mftrecsz;
+ uint32_t bf_ibsz;
+ uint32_t bf_volsn;
+} __packed;
static void
g_label_ntfs_taste(struct g_consumer *cp, char *label, size_t size)
{
struct g_provider *pp;
- struct bootfile *bf;
- struct filerec *fr;
- struct attr *atr;
+ struct ntfs_bootfile *bf;
+ struct ntfs_filerec *fr;
+ struct ntfs_attr *atr;
off_t voloff;
char *filerecp, *ap;
char mftrecsz, vnchar;
@@ -58,7 +109,7 @@ g_label_ntfs_taste(struct g_consumer *cp, char *label, size_t size)
pp = cp->provider;
filerecp = NULL;
- bf = (struct bootfile *)g_read_data(cp, 0, pp->sectorsize, NULL);
+ bf = (struct ntfs_bootfile *)g_read_data(cp, 0, pp->sectorsize, NULL);
if (bf == NULL || strncmp(bf->bf_sysid, "NTFS ", 8) != 0)
goto done;
@@ -75,16 +126,16 @@ g_label_ntfs_taste(struct g_consumer *cp, char *label, size_t size)
filerecp = g_read_data(cp, voloff, recsize, NULL);
if (filerecp == NULL)
goto done;
- fr = (struct filerec *)filerecp;
+ fr = (struct ntfs_filerec *)filerecp;
- if (fr->fr_fixup.fh_magic != NTFS_FILEMAGIC)
+ if (fr->fr_hdrmagic != NTFS_FILEMAGIC)
goto done;
for (ap = filerecp + fr->fr_attroff;
- atr = (struct attr *)ap, atr->a_hdr.a_type != -1;
- ap += atr->a_hdr.reclen) {
- if (atr->a_hdr.a_type == NTFS_A_VOLUMENAME) {
- if(atr->a_r.a_datalen >= size *2){
+ atr = (struct ntfs_attr *)ap, atr->a_type != -1;
+ ap += atr->reclen) {
+ if (atr->a_type == NTFS_A_VOLUMENAME) {
+ if(atr->a_datalen >= size *2){
label[0] = 0;
goto done;
}
@@ -92,8 +143,8 @@ g_label_ntfs_taste(struct g_consumer *cp, char *label, size_t size)
*UNICODE to ASCII.
* Should we need to use iconv(9)?
*/
- for (j = 0; j < atr->a_r.a_datalen; j++) {
- vnchar = *(ap + atr->a_r.a_dataoff + j);
+ for (j = 0; j < atr->a_datalen; j++) {
+ vnchar = *(ap + atr->a_dataoff + j);
if (j & 1) {
if (vnchar) {
label[0] = 0;
diff --git a/sys/geom/part/g_part.c b/sys/geom/part/g_part.c
index e2ba79e..f7f6f55 100644
--- a/sys/geom/part/g_part.c
+++ b/sys/geom/part/g_part.c
@@ -80,6 +80,7 @@ struct g_part_alias_list {
{ "bios-boot", G_PART_ALIAS_BIOS_BOOT },
{ "ebr", G_PART_ALIAS_EBR },
{ "efi", G_PART_ALIAS_EFI },
+ { "fat16", G_PART_ALIAS_MS_FAT16 },
{ "fat32", G_PART_ALIAS_MS_FAT32 },
{ "freebsd", G_PART_ALIAS_FREEBSD },
{ "freebsd-boot", G_PART_ALIAS_FREEBSD_BOOT },
diff --git a/sys/geom/part/g_part.h b/sys/geom/part/g_part.h
index 39bcc9d..05a8c57 100644
--- a/sys/geom/part/g_part.h
+++ b/sys/geom/part/g_part.h
@@ -68,6 +68,7 @@ enum g_part_alias {
G_PART_ALIAS_NETBSD_SWAP, /* A NetBSD swap partition entry. */
G_PART_ALIAS_NETBSD_LFS, /* A NetBSD LFS partition entry. */
G_PART_ALIAS_EBR, /* A EBR partition entry. */
+ G_PART_ALIAS_MS_FAT16, /* A Microsoft FAT16 partition entry. */
G_PART_ALIAS_MS_FAT32, /* A Microsoft FAT32 partition entry. */
G_PART_ALIAS_BIOS_BOOT, /* A GRUB 2 boot partition entry. */
G_PART_ALIAS_VMFS, /* A VMware VMFS partition entry */
diff --git a/sys/geom/part/g_part_mbr.c b/sys/geom/part/g_part_mbr.c
index 619553c..d522d02 100644
--- a/sys/geom/part/g_part_mbr.c
+++ b/sys/geom/part/g_part_mbr.c
@@ -118,6 +118,7 @@ static struct g_part_mbr_alias {
{ DOSPTYP_386BSD, G_PART_ALIAS_FREEBSD },
{ DOSPTYP_EXT, G_PART_ALIAS_EBR },
{ DOSPTYP_NTFS, G_PART_ALIAS_MS_NTFS },
+ { DOSPTYP_FAT16, G_PART_ALIAS_MS_FAT16 },
{ DOSPTYP_FAT32, G_PART_ALIAS_MS_FAT32 },
{ DOSPTYP_EXTLBA, G_PART_ALIAS_EBR },
{ DOSPTYP_LDM, G_PART_ALIAS_MS_LDM_DATA },
diff --git a/sys/geom/raid/md_ddf.c b/sys/geom/raid/md_ddf.c
index 7d4bd1e..c18a319 100644
--- a/sys/geom/raid/md_ddf.c
+++ b/sys/geom/raid/md_ddf.c
@@ -881,7 +881,10 @@ ddf_vol_meta_update(struct ddf_vol_meta *dst, struct ddf_meta *src,
hdr = src->hdr;
vde = &src->vdr->entry[ddf_meta_find_vd(src, GUID)];
vdc = ddf_meta_find_vdc(src, GUID);
- bvd = GET8D(src, vdc->Secondary_Element_Seq);
+ if (GET8D(src, vdc->Secondary_Element_Count) == 1)
+ bvd = 0;
+ else
+ bvd = GET8D(src, vdc->Secondary_Element_Seq);
size = GET16(src, hdr->Configuration_Record_Length) * src->sectorsize;
if (dst->vdc == NULL ||
diff --git a/sys/gnu/fs/xfs/FreeBSD/support/atomic.h b/sys/gnu/fs/xfs/FreeBSD/support/atomic.h
deleted file mode 100644
index 618de8c..0000000
--- a/sys/gnu/fs/xfs/FreeBSD/support/atomic.h
+++ /dev/null
@@ -1,36 +0,0 @@
-#ifndef __XFS_SUPPORT_ATOMIC_H__
-
-#include <sys/types.h>
-#include <machine/atomic.h>
-
-typedef struct {
- volatile unsigned int val;
-} atomic_t;
-
-#define atomic_read(v) ((v)->val)
-#define atomic_set(v, i) ((v)->val = (i))
-
-#define atomic_add(i, v) atomic_add_int(&(v)->val, (i))
-#define atomic_inc(v) atomic_add_int(&(v)->val, 1)
-#define atomic_dec(v) atomic_subtract_int(&(v)->val, 1)
-#define atomic_sub(i, v) atomic_subtract_int(&(v)->val, (i))
-#define atomic_dec_and_test(v) (atomic_fetchadd_int(&(v)->val, -1) == 1)
-
-/*
- * This is used for two variables in XFS, one of which is a debug trace
- * buffer index.
- */
-
-static __inline__ int atomicIncWithWrap(volatile unsigned int *ip, int val)
-{
- unsigned int oldval, newval;
-
- do {
- oldval = *ip;
- newval = (oldval + 1 >= val) ? 0 : oldval + 1;
- } while (atomic_cmpset_rel_int(ip, oldval, newval) == 0);
-
- return oldval;
-}
-
-#endif /* __XFS_SUPPORT_ATOMIC_H__ */
diff --git a/sys/gnu/fs/xfs/FreeBSD/support/debug.c b/sys/gnu/fs/xfs/FreeBSD/support/debug.c
deleted file mode 100644
index cf2ef94..0000000
--- a/sys/gnu/fs/xfs/FreeBSD/support/debug.c
+++ /dev/null
@@ -1,97 +0,0 @@
-/*
- * Copyright (c) 2000 Silicon Graphics, Inc. All Rights Reserved.
- *
- * This program 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.
- *
- * This program is distributed in the hope that it would be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
- *
- * Further, this software is distributed without any warranty that it is
- * free of the rightful claim of any third person regarding infringement
- * or the like. Any license provided herein, whether implied or
- * otherwise, applies only to this software file. Patent licenses, if
- * any, provided herein do not apply to combinations of this program with
- * other software, or any other product whatsoever.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write the Free Software Foundation, Inc., 59
- * Temple Place - Suite 330, Boston MA 02111-1307, USA.
- *
- * Contact information: Silicon Graphics, Inc., 1600 Amphitheatre Pkwy,
- * Mountain View, CA 94043, or:
- *
- * http://www.sgi.com
- *
- * For further information regarding this notice, see:
- *
- * http://oss.sgi.com/projects/GenInfo/SGIGPLNoticeExplan/
- */
-
-
-#include <sys/param.h>
-#include <sys/proc.h>
-#include <sys/kernel.h>
-#include <sys/systm.h>
-#include <sys/sysctl.h>
-#include <machine/stdarg.h>
-
-#include <support/debug.h>
-
-static SYSCTL_NODE(_debug, OID_AUTO, xfs, CTLFLAG_RD, 0, "XFS debug options");
-
-static int verbosity = 10;
-SYSCTL_INT(_debug_xfs, OID_AUTO, verbosity, CTLFLAG_RW, &verbosity, 0, "");
-
-#ifdef DEBUG
-
-static int doass = 1;
-SYSCTL_INT(_debug_xfs, OID_AUTO, assert, CTLFLAG_RW, &doass, 0, "");
-
-void
-assfail(char *a, char *f, int l)
-{
- if (doass == 0) return;
- panic("XFS assertion failed: %s, file: %s, line: %d\n", a, f, l);
-}
-
-int
-get_thread_id(void)
-{
- return curthread->td_proc->p_pid;
-}
-
-#endif
-
-void
-cmn_err(register int level, char *fmt, ...)
-{
- char *fp = fmt;
- char message[256];
- va_list ap;
-
- if (verbosity < level)
- return;
-
- va_start(ap, fmt);
- if (*fmt == '!') fp++;
- vsprintf(message, fp, ap);
- printf("%s\n", message);
- va_end(ap);
-}
-
-
-void
-icmn_err(register int level, char *fmt, va_list ap)
-{
- char message[256];
-
- if (verbosity < level)
- return;
-
- vsprintf(message, fmt, ap);
- printf("cmn_err level %d %s\n",level, message);
-}
-
diff --git a/sys/gnu/fs/xfs/FreeBSD/support/debug.h b/sys/gnu/fs/xfs/FreeBSD/support/debug.h
deleted file mode 100644
index 816a717..0000000
--- a/sys/gnu/fs/xfs/FreeBSD/support/debug.h
+++ /dev/null
@@ -1,79 +0,0 @@
-/*
- * Copyright (c) 2000 Silicon Graphics, Inc. All Rights Reserved.
- *
- * This program 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.
- *
- * This program is distributed in the hope that it would be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
- *
- * Further, this software is distributed without any warranty that it is
- * free of the rightful claim of any third person regarding infringement
- * or the like. Any license provided herein, whether implied or
- * otherwise, applies only to this software file. Patent licenses, if
- * any, provided herein do not apply to combinations of this program with
- * other software, or any other product whatsoever.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write the Free Software Foundation, Inc., 59
- * Temple Place - Suite 330, Boston MA 02111-1307, USA.
- *
- * Contact information: Silicon Graphics, Inc., 1600 Amphitheatre Pkwy,
- * Mountain View, CA 94043, or:
- *
- * http://www.sgi.com
- *
- * For further information regarding this notice, see:
- *
- * http://oss.sgi.com/projects/GenInfo/SGIGPLNoticeExplan/
- */
-#ifndef __XFS_SUPPORT_DEBUG_H__
-#define __XFS_SUPPORT_DEBUG_H__
-
-#include <machine/stdarg.h>
-
-#define CE_DEBUG 7 /* debug */
-#define CE_CONT 6 /* continuation */
-#define CE_NOTE 5 /* notice */
-#define CE_WARN 4 /* warning */
-#define CE_ALERT 1 /* alert */
-#define CE_PANIC 0 /* panic */
-
-extern void icmn_err(int, char *, va_list);
-extern void cmn_err(int, char *, ...);
-
-#define prdev(fmt,targ,args...) \
- printf("Device %s - " fmt "\n", XFS_BUFTARG_NAME(targ), ## args)
-
-#ifndef STATIC
-# define STATIC static
-#endif
-
-#if defined(INVARIANTS)
-# ifndef DEBUG
-# define DEBUG
-# endif
-#endif
-
-#if defined(DEBUG)
-# ifdef lint
-# define ASSERT(EX) ((void)0) /* avoid "constant in conditional" babble */
-# else
-# define ASSERT(EX) ((EX)?((void)0):assfail(#EX, __FILE__, __LINE__))
-# endif /* lint */
-#else /* !DEBUG */
-# define ASSERT(x) ((void)0)
-#endif /* !DEBUG */
-
-#ifdef DEBUG
-extern void assfail(char *, char *, int);
-extern int get_thread_id(void);
-#else
-#define assfail(a, b, c) ((void)0)
-#endif
-
-#define ASSERT_ALWAYS(EX) ((EX)?((void)0):assfail(#EX, __FILE__, __LINE__))
-
-#endif /* __XFS_SUPPORT_DEBUG_H__ */
diff --git a/sys/gnu/fs/xfs/FreeBSD/support/kdb.c b/sys/gnu/fs/xfs/FreeBSD/support/kdb.c
deleted file mode 100644
index b133dfe..0000000
--- a/sys/gnu/fs/xfs/FreeBSD/support/kdb.c
+++ /dev/null
@@ -1,62 +0,0 @@
-#include <sys/param.h>
-#include <sys/kernel.h>
-#include <sys/systm.h>
-
-#include <machine/db_machdep.h>
-
-#include "opt_ddb.h"
-#ifdef DDB
-#include <ddb/ddb.h>
-#endif
-
-#include <support/kdb.h>
-
-#ifdef DDB
-DB_FUNC(xfs, xfs_ddb_cmd, db_cmd_table, CS_MORE, NULL)
-{
- db_error("No commands registered.\n");
-}
-#endif
-
-int
-kdb_register(char *cmd, kdb_func_t func, char *usage, char *help, short minlen)
-{
- return 0;
-}
-
-int
-kdb_unregister(char *cmd)
-{
- return 0;
-}
-
-int
-kdbgetaddrarg(int argc, const char **argv, int *nextarg,
- kdb_machreg_t *value, long *offset, char **name, struct pt_regs *regs)
-{
- return 0;
-}
-
-int
-kdbnearsym(unsigned long addr, kdb_symtab_t *symtab)
-
-{
- return 0;
-}
-
-void
-kdb_printf(const char *fmt, ...)
-{
-}
-
-int
-kdb_getarea_size(void *res, unsigned long addr, size_t size)
-{
- return 0;
-}
-
-int
-kdb_putarea_size(unsigned long addr, void *res, size_t size)
-{
- return 0;
-}
diff --git a/sys/gnu/fs/xfs/FreeBSD/support/kdb.h b/sys/gnu/fs/xfs/FreeBSD/support/kdb.h
deleted file mode 100644
index d85bd6d..0000000
--- a/sys/gnu/fs/xfs/FreeBSD/support/kdb.h
+++ /dev/null
@@ -1,44 +0,0 @@
-#ifndef __XFS_SUPPORT_KGDB_H__
-#define __XFS_SUPPORT_KGDB_H__
-
-#define KDB_ARGCOUNT EINVAL
-
-struct pt_regs
-{
- int dummy;
-};
-
-#define MODULE_AUTHOR(s) static char __module_author[] = s;
-#define MODULE_DESCRIPTION(s) static char __module_description[] = s;
-#define MODULE_LICENSE(s) static char __module_license[] = s
-
-
-typedef int (*kdb_func_t)(int, const char **, const char **, struct pt_regs *);
-typedef register_t kdb_machreg_t;
-
-/*
- * Symbol table format.
- */
-typedef struct __ksymtab {
- unsigned long value; /* Address of symbol */
- const char *sym_name; /* Full symbol name, including any version */
- unsigned long sym_start;
- unsigned long sym_end;
-} kdb_symtab_t;
-
-extern int kdb_register(char *, kdb_func_t, char *, char *, short);
-extern int kdb_unregister(char *);
-
-extern int kdbgetaddrarg(int, const char**, int*, kdb_machreg_t *,
- long *, char **, struct pt_regs *);
-extern int kdbnearsym(unsigned long, kdb_symtab_t *);
-extern void kdb_printf(const char *,...)
- __attribute__ ((format (printf, 1, 2)));
-
-extern int kdb_getarea_size(void *, unsigned long, size_t);
-extern int kdb_putarea_size(unsigned long, void *, size_t);
-
-#define kdb_getarea(x,addr) kdb_getarea_size(&(x), addr, sizeof((x)))
-#define kdb_putarea(addr,x) kdb_putarea_size(addr, &(x), sizeof((x)))
-
-#endif /* __XFS_SUPPORT_KGDB_H__ */
diff --git a/sys/gnu/fs/xfs/FreeBSD/support/kmem.c b/sys/gnu/fs/xfs/FreeBSD/support/kmem.c
deleted file mode 100644
index c98e4bc..0000000
--- a/sys/gnu/fs/xfs/FreeBSD/support/kmem.c
+++ /dev/null
@@ -1,3 +0,0 @@
-#include <support/kmem.h>
-
-MALLOC_DEFINE(M_XFS, "XFSALLOC", "XFS memory");
diff --git a/sys/gnu/fs/xfs/FreeBSD/support/kmem.h b/sys/gnu/fs/xfs/FreeBSD/support/kmem.h
deleted file mode 100644
index 4976008..0000000
--- a/sys/gnu/fs/xfs/FreeBSD/support/kmem.h
+++ /dev/null
@@ -1,86 +0,0 @@
-#ifndef __XFS_SUPPORT_KMEM_H__
-#define __XFS_SUPPORT_KMEM_H__
-
-#include <sys/param.h>
-#include <sys/systm.h>
-#include <sys/malloc.h>
-#include <sys/kernel.h>
-#include <sys/lock.h>
-#include <sys/mutex.h>
-#include <vm/uma.h>
-
-typedef unsigned long xfs_pflags_t;
-
-#define PFLAGS_TEST_NOIO() 0
-#define PFLAGS_TEST_FSTRANS() 0
-
-#define PFLAGS_SET_NOIO(STATEP) do { \
-} while (0)
-
-#define PFLAGS_SET_FSTRANS(STATEP) do { \
-} while (0)
-
-#define PFLAGS_RESTORE(STATEP) do { \
-} while (0)
-
-#define PFLAGS_DUP(OSTATEP, NSTATEP) do { \
-} while (0)
-
-/* Restore the PF_FSTRANS state to what was saved in STATEP */
-#define PFLAGS_RESTORE_FSTRANS(STATEP) do { \
-} while (0)
-
-/*
- * memory management routines
- */
-#define KM_SLEEP M_WAITOK
-#define KM_NOSLEEP M_NOWAIT
-#define KM_NOFS M_WAITOK
-#define KM_MAYFAIL 0
-
-#define kmem_zone uma_zone
-
-typedef struct uma_zone kmem_zone_t;
-typedef struct uma_zone xfs_zone_t;
-
-
-#define KM_ZONE_HWALIGN 0
-#define KM_ZONE_RECLAIM 0
-#define KM_ZONE_SPREAD 0
-
-#define kmem_zone_init(len, name) \
- uma_zcreate(name, len, NULL, NULL, NULL, NULL, 0, 0)
-
-static inline kmem_zone_t *
-kmem_zone_init_flags(int size, char *zone_name, unsigned long flags,
- void (*construct)(void *, kmem_zone_t *, unsigned long))
-{
- return uma_zcreate(zone_name, size, NULL, NULL, NULL, NULL, 0, 0);
-}
-
-#define kmem_zone_free(zone, ptr) \
- uma_zfree(zone, ptr)
-
-static inline void
-kmem_zone_destroy(kmem_zone_t *zone)
-{
- uma_zdestroy(zone);
-}
-
-#define kmem_zone_alloc(zone, flg) \
- uma_zalloc(zone, flg)
-#define kmem_zone_zalloc(zone, flg) \
- uma_zalloc(zone, (flg) | M_ZERO)
-
-#define kmem_alloc(len, flg) \
- malloc(len, M_XFS, flg)
-#define kmem_zalloc(len, flg) \
- malloc(len, M_XFS, (flg) | M_ZERO)
-#define kmem_free(ptr, size) \
- free(ptr, M_XFS)
-#define kmem_realloc(ptr, nsize, osize, flg) \
- realloc(ptr, nsize, M_XFS, flg)
-
-MALLOC_DECLARE(M_XFS);
-
-#endif /* __XFS_SUPPORT_KMEM_H__ */
diff --git a/sys/gnu/fs/xfs/FreeBSD/support/ktrace.c b/sys/gnu/fs/xfs/FreeBSD/support/ktrace.c
deleted file mode 100644
index 45a42bf..0000000
--- a/sys/gnu/fs/xfs/FreeBSD/support/ktrace.c
+++ /dev/null
@@ -1,334 +0,0 @@
-/*
- * Copyright (c) 2000-2003,2005 Silicon Graphics, Inc.
- * All Rights Reserved.
- *
- * 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.
- *
- * This program is distributed in the hope that it would 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 the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- */
-#include <xfs.h>
-
-static kmem_zone_t *ktrace_hdr_zone;
-static kmem_zone_t *ktrace_ent_zone;
-static int ktrace_zentries;
-static struct mtx wrap_lock;
-
-void
-ktrace_init(int zentries)
-{
- ktrace_zentries = zentries;
-
- ktrace_hdr_zone = kmem_zone_init(sizeof(ktrace_t),
- "ktrace_hdr");
- ASSERT(ktrace_hdr_zone);
-
- ktrace_ent_zone = kmem_zone_init(ktrace_zentries
- * sizeof(ktrace_entry_t),
- "ktrace_ent");
- ASSERT(ktrace_ent_zone);
-
- mtx_init(&wrap_lock, "xfsktr", NULL, MTX_DEF);
-}
-
-void
-ktrace_uninit(void)
-{
- kmem_zone_destroy(ktrace_hdr_zone);
- kmem_zone_destroy(ktrace_ent_zone);
-
- mtx_destroy(&wrap_lock);
-}
-
-/*
- * ktrace_alloc()
- *
- * Allocate a ktrace header and enough buffering for the given
- * number of entries.
- */
-ktrace_t *
-ktrace_alloc(int nentries, int sleep)
-{
- ktrace_t *ktp;
- ktrace_entry_t *ktep;
-
- ktp = (ktrace_t*)kmem_zone_alloc(ktrace_hdr_zone, sleep);
-
- if (ktp == (ktrace_t*)NULL) {
- /*
- * KM_SLEEP callers don't expect failure.
- */
- if (sleep & KM_SLEEP)
- panic("ktrace_alloc: NULL memory on KM_SLEEP request!");
-
- return NULL;
- }
-
- /*
- * Special treatment for buffers with the ktrace_zentries entries
- */
- if (nentries == ktrace_zentries) {
- ktep = (ktrace_entry_t*)kmem_zone_zalloc(ktrace_ent_zone,
- sleep);
- } else {
- ktep = (ktrace_entry_t*)kmem_zalloc((nentries * sizeof(*ktep)),
- sleep);
- }
-
- if (ktep == NULL) {
- /*
- * KM_SLEEP callers don't expect failure.
- */
- if (sleep & KM_SLEEP)
- panic("ktrace_alloc: NULL memory on KM_SLEEP request!");
-
- kmem_free(ktp, sizeof(*ktp));
-
- return NULL;
- }
-
- spinlock_init(&(ktp->kt_lock), "kt_lock");
-
- ktp->kt_entries = ktep;
- ktp->kt_nentries = nentries;
- ktp->kt_index = 0;
- ktp->kt_rollover = 0;
- return ktp;
-}
-
-
-/*
- * ktrace_free()
- *
- * Free up the ktrace header and buffer. It is up to the caller
- * to ensure that no-one is referencing it.
- */
-void
-ktrace_free(ktrace_t *ktp)
-{
- int entries_size;
-
- if (ktp == (ktrace_t *)NULL)
- return;
-
- spinlock_destroy(&ktp->kt_lock);
-
- /*
- * Special treatment for the Vnode trace buffer.
- */
- if (ktp->kt_nentries == ktrace_zentries) {
- kmem_zone_free(ktrace_ent_zone, ktp->kt_entries);
- } else {
- entries_size = (int)(ktp->kt_nentries * sizeof(ktrace_entry_t));
-
- kmem_free(ktp->kt_entries, entries_size);
- }
-
- kmem_zone_free(ktrace_hdr_zone, ktp);
-}
-
-
-/*
- * Enter the given values into the "next" entry in the trace buffer.
- * kt_index is always the index of the next entry to be filled.
- */
-void
-ktrace_enter(
- ktrace_t *ktp,
- void *val0,
- void *val1,
- void *val2,
- void *val3,
- void *val4,
- void *val5,
- void *val6,
- void *val7,
- void *val8,
- void *val9,
- void *val10,
- void *val11,
- void *val12,
- void *val13,
- void *val14,
- void *val15)
-{
- int index;
- ktrace_entry_t *ktep;
-
- ASSERT(ktp != NULL);
-
- /*
- * Grab an entry by pushing the index up to the next one.
- */
- mtx_lock(&wrap_lock);
- index = ktp->kt_index;
- if (++ktp->kt_index == ktp->kt_nentries)
- ktp->kt_index = 0;
- mtx_unlock(&wrap_lock);
-
- if (!ktp->kt_rollover && index == ktp->kt_nentries - 1)
- ktp->kt_rollover = 1;
-
- ASSERT((index >= 0) && (index < ktp->kt_nentries));
-
- ktep = &(ktp->kt_entries[index]);
-
- ktep->val[0] = val0;
- ktep->val[1] = val1;
- ktep->val[2] = val2;
- ktep->val[3] = val3;
- ktep->val[4] = val4;
- ktep->val[5] = val5;
- ktep->val[6] = val6;
- ktep->val[7] = val7;
- ktep->val[8] = val8;
- ktep->val[9] = val9;
- ktep->val[10] = val10;
- ktep->val[11] = val11;
- ktep->val[12] = val12;
- ktep->val[13] = val13;
- ktep->val[14] = val14;
- ktep->val[15] = val15;
-}
-
-/*
- * Return the number of entries in the trace buffer.
- */
-int
-ktrace_nentries(
- ktrace_t *ktp)
-{
- if (ktp == NULL) {
- return 0;
- }
-
- return (ktp->kt_rollover ? ktp->kt_nentries : ktp->kt_index);
-}
-
-/*
- * ktrace_first()
- *
- * This is used to find the start of the trace buffer.
- * In conjunction with ktrace_next() it can be used to
- * iterate through the entire trace buffer. This code does
- * not do any locking because it is assumed that it is called
- * from the debugger.
- *
- * The caller must pass in a pointer to a ktrace_snap
- * structure in which we will keep some state used to
- * iterate through the buffer. This state must not touched
- * by any code outside of this module.
- */
-ktrace_entry_t *
-ktrace_first(ktrace_t *ktp, ktrace_snap_t *ktsp)
-{
- ktrace_entry_t *ktep;
- int index;
- int nentries;
-
- if (ktp->kt_rollover)
- index = ktp->kt_index;
- else
- index = 0;
-
- ktsp->ks_start = index;
- ktep = &(ktp->kt_entries[index]);
-
- nentries = ktrace_nentries(ktp);
- index++;
- if (index < nentries) {
- ktsp->ks_index = index;
- } else {
- ktsp->ks_index = 0;
- if (index > nentries)
- ktep = NULL;
- }
- return ktep;
-}
-
-/*
- * ktrace_next()
- *
- * This is used to iterate through the entries of the given
- * trace buffer. The caller must pass in the ktrace_snap_t
- * structure initialized by ktrace_first(). The return value
- * will be either a pointer to the next ktrace_entry or NULL
- * if all of the entries have been traversed.
- */
-ktrace_entry_t *
-ktrace_next(
- ktrace_t *ktp,
- ktrace_snap_t *ktsp)
-{
- int index;
- ktrace_entry_t *ktep;
-
- index = ktsp->ks_index;
- if (index == ktsp->ks_start) {
- ktep = NULL;
- } else {
- ktep = &ktp->kt_entries[index];
- }
-
- index++;
- if (index == ktrace_nentries(ktp)) {
- ktsp->ks_index = 0;
- } else {
- ktsp->ks_index = index;
- }
-
- return ktep;
-}
-
-/*
- * ktrace_skip()
- *
- * Skip the next "count" entries and return the entry after that.
- * Return NULL if this causes us to iterate past the beginning again.
- */
-ktrace_entry_t *
-ktrace_skip(
- ktrace_t *ktp,
- int count,
- ktrace_snap_t *ktsp)
-{
- int index;
- int new_index;
- ktrace_entry_t *ktep;
- int nentries = ktrace_nentries(ktp);
-
- index = ktsp->ks_index;
- new_index = index + count;
- while (new_index >= nentries) {
- new_index -= nentries;
- }
- if (index == ktsp->ks_start) {
- /*
- * We've iterated around to the start, so we're done.
- */
- ktep = NULL;
- } else if ((new_index < index) && (index < ktsp->ks_index)) {
- /*
- * We've skipped past the start again, so we're done.
- */
- ktep = NULL;
- ktsp->ks_index = ktsp->ks_start;
- } else {
- ktep = &(ktp->kt_entries[new_index]);
- new_index++;
- if (new_index == nentries) {
- ktsp->ks_index = 0;
- } else {
- ktsp->ks_index = new_index;
- }
- }
- return ktep;
-}
diff --git a/sys/gnu/fs/xfs/FreeBSD/support/ktrace.h b/sys/gnu/fs/xfs/FreeBSD/support/ktrace.h
deleted file mode 100644
index b566ef8..0000000
--- a/sys/gnu/fs/xfs/FreeBSD/support/ktrace.h
+++ /dev/null
@@ -1,101 +0,0 @@
-/*
- * Copyright (c) 2000-2003 Silicon Graphics, Inc. All Rights Reserved.
- *
- * This program 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.
- *
- * This program is distributed in the hope that it would be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
- *
- * Further, this software is distributed without any warranty that it is
- * free of the rightful claim of any third person regarding infringement
- * or the like. Any license provided herein, whether implied or
- * otherwise, applies only to this software file. Patent licenses, if
- * any, provided herein do not apply to combinations of this program with
- * other software, or any other product whatsoever.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write the Free Software Foundation, Inc., 59
- * Temple Place - Suite 330, Boston MA 02111-1307, USA.
- *
- * Contact information: Silicon Graphics, Inc., 1600 Amphitheatre Pkwy,
- * Mountain View, CA 94043, or:
- *
- * http://www.sgi.com
- *
- * For further information regarding this notice, see:
- *
- * http://oss.sgi.com/projects/GenInfo/SGIGPLNoticeExplan/
- */
-#ifndef __XFS_SUPPORT_KTRACE_H__
-#define __XFS_SUPPORT_KTRACE_H__
-
-#include <support/spin.h>
-
-/*
- * Trace buffer entry structure.
- */
-typedef struct ktrace_entry {
- void *val[16];
-} ktrace_entry_t;
-
-/*
- * Trace buffer header structure.
- */
-typedef struct ktrace {
- lock_t kt_lock; /* mutex to guard counters */
- int kt_nentries; /* number of entries in trace buf */
- int kt_index; /* current index in entries */
- int kt_rollover;
- ktrace_entry_t *kt_entries; /* buffer of entries */
-} ktrace_t;
-
-/*
- * Trace buffer snapshot structure.
- */
-typedef struct ktrace_snap {
- int ks_start; /* kt_index at time of snap */
- int ks_index; /* current index */
-} ktrace_snap_t;
-
-
-#ifdef CONFIG_XFS_TRACE
-
-extern void ktrace_init(int zentries);
-extern void ktrace_uninit(void);
-
-extern ktrace_t *ktrace_alloc(int, int);
-extern void ktrace_free(ktrace_t *);
-
-extern void ktrace_enter(
- ktrace_t *,
- void *,
- void *,
- void *,
- void *,
- void *,
- void *,
- void *,
- void *,
- void *,
- void *,
- void *,
- void *,
- void *,
- void *,
- void *,
- void *);
-
-extern ktrace_entry_t *ktrace_first(ktrace_t *, ktrace_snap_t *);
-extern int ktrace_nentries(ktrace_t *);
-extern ktrace_entry_t *ktrace_next(ktrace_t *, ktrace_snap_t *);
-extern ktrace_entry_t *ktrace_skip(ktrace_t *, int, ktrace_snap_t *);
-
-#else
-#define ktrace_init(x) do { } while (0)
-#define ktrace_uninit() do { } while (0)
-#endif /* CONFIG_XFS_TRACE */
-
-#endif /* __XFS_SUPPORT_KTRACE_H__ */
diff --git a/sys/gnu/fs/xfs/FreeBSD/support/move.h b/sys/gnu/fs/xfs/FreeBSD/support/move.h
deleted file mode 100644
index 856ec03..0000000
--- a/sys/gnu/fs/xfs/FreeBSD/support/move.h
+++ /dev/null
@@ -1,48 +0,0 @@
-/*
- * Copyright (c) 2000-2002 Silicon Graphics, Inc. All Rights Reserved.
- *
- * This program 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.
- *
- * This program is distributed in the hope that it would be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
- *
- * Further, this software is distributed without any warranty that it is
- * free of the rightful claim of any third person regarding infringement
- * or the like. Any license provided herein, whether implied or
- * otherwise, applies only to this software file. Patent licenses, if
- * any, provided herein do not apply to combinations of this program with
- * other software, or any other product whatsoever.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write the Free Software Foundation, Inc., 59
- * Temple Place - Suite 330, Boston MA 02111-1307, USA.
- *
- * Contact information: Silicon Graphics, Inc., 1600 Amphitheatre Pkwy,
- * Mountain View, CA 94043, or:
- *
- * http://www.sgi.com
- *
- * For further information regarding this notice, see:
- *
- * http://oss.sgi.com/projects/GenInfo/SGIGPLNoticeExplan/
- */
-
-#ifndef __XFS_SUPPORT_MOVE_H__
-#define __XFS_SUPPORT_MOVE_H__
-
-#include <sys/uio.h>
-
-typedef struct iovec iovec_t;
-typedef struct uio uio_t;
-
-static __inline__ int
-uio_read(void *buf, int howmuch, struct uio *uiop)
-{
- uiop->uio_rw = UIO_READ;
- return uiomove(buf,howmuch,uiop);
-}
-
-#endif /* __XFS_SUPPORT_MOVE_H__ */
diff --git a/sys/gnu/fs/xfs/FreeBSD/support/mrlock.c b/sys/gnu/fs/xfs/FreeBSD/support/mrlock.c
deleted file mode 100644
index 5955f99..0000000
--- a/sys/gnu/fs/xfs/FreeBSD/support/mrlock.c
+++ /dev/null
@@ -1,14 +0,0 @@
-#include <sys/param.h>
-#include <sys/pcpu.h>
-#include <support/debug.h>
-#include <support/mrlock.h>
-
-int
-ismrlocked(mrlock_t *mrp, int type)
-{
-
- sx_assert(mrp, SX_LOCKED);
- if (type == MR_UPDATE)
- return sx_xlocked(mrp);
- return 1;
-}
diff --git a/sys/gnu/fs/xfs/FreeBSD/support/mrlock.h b/sys/gnu/fs/xfs/FreeBSD/support/mrlock.h
deleted file mode 100644
index b41efc5..0000000
--- a/sys/gnu/fs/xfs/FreeBSD/support/mrlock.h
+++ /dev/null
@@ -1,41 +0,0 @@
-#ifndef __XFS_SUPPORT_MRLOCK_H__
-#define __XFS_SUPPORT_MRLOCK_H__
-
-#include <sys/types.h>
-#include <sys/systm.h>
-#include <sys/lock.h>
-#include <sys/sx.h>
-
-/*
- * Implement mrlocks on FreeBSD that work for XFS.
- * Map mrlock functions to corresponding equivalents in
- * sx.
- */
-typedef struct sx mrlock_t;
-
-#define MR_ACCESS 1
-#define MR_UPDATE 2
-
-/*
- * Compatibility defines, not really used
- */
-#define MRLOCK_BARRIER 0x1
-#define MRLOCK_ALLOW_EQUAL_PRI 0x8
-
-#define mrlock_init(lock, type, name, seq) sx_init(lock, name)
-#define mrtryaccess(lock) sx_try_slock(lock)
-#define mrtryupdate(lock) sx_try_xlock(lock)
-#define mraccess(lock) sx_slock(lock)
-#define mrupdate(lock) sx_xlock(lock)
-#define mrdemote(lock) sx_downgrade(lock)
-#define mrunlock(lock) sx_unlock(lock)
-
-#define mrfree(lock) do { \
- if (sx_xlocked(lock)) \
- sx_xunlock(lock); \
- sx_destroy(lock); \
-} while (0)
-
-int ismrlocked(mrlock_t *mrp, int type);
-
-#endif /* __XFS_SUPPORT_MRLOCK_H__ */
diff --git a/sys/gnu/fs/xfs/FreeBSD/support/mutex.h b/sys/gnu/fs/xfs/FreeBSD/support/mutex.h
deleted file mode 100644
index d9b89b3..0000000
--- a/sys/gnu/fs/xfs/FreeBSD/support/mutex.h
+++ /dev/null
@@ -1,29 +0,0 @@
-#ifndef __XFS_SUPPORT_MUTEX_H__
-#define __XFS_SUPPORT_MUTEX_H__
-
-#include <sys/param.h>
-#include <sys/lock.h>
-#include <sys/mutex.h>
-#include <sys/sx.h>
-
-/*
- * Map the mutex'es from IRIX to FreeBSD. Irix holds mutexes across
- * sleeps, so on FreeBSD we have a choice of sema, sx or lockmgr
- * to use as a underlining implemenation. Go with sx always locked
- * in exclusive mode for now as it gets all the benefits of witness
- * checking.
- */
-typedef struct sx mutex_t;
-
-#define mutex_init(lock, type, name) sx_init(lock, name)
-#define mutex_lock(lock, num) sx_xlock(lock)
-#define mutex_trylock(lock) sx_try_xlock(lock)
-#define mutex_unlock(lock) sx_xunlock(lock)
-#define mutex_destroy(lock) sx_destroy(lock)
-
-/*
- * Type for mutex_init()
- */
-#define MUTEX_DEFAULT 0
-
-#endif /* __XFS_SUPPORT_MUTEX_H__ */
diff --git a/sys/gnu/fs/xfs/FreeBSD/support/rwlock.h b/sys/gnu/fs/xfs/FreeBSD/support/rwlock.h
deleted file mode 100644
index bfbec23..0000000
--- a/sys/gnu/fs/xfs/FreeBSD/support/rwlock.h
+++ /dev/null
@@ -1,23 +0,0 @@
-#ifndef __XFS_SUPPORT_RWLOCK_H__
-#define __XFS_SUPPORT_RWLOCK_H__
-
-#include <sys/param.h>
-#include <sys/lock.h>
-#include <sys/mutex.h>
-#include <sys/sx.h>
-
-typedef struct sx rwlock_t;
-typedef int wait_queue_head_t;
-
-#define rwlock_init(lock) sx_init(lock, "rwlock")
-#define rwlock_destroy(lock) sx_destroy(lock)
-#define read_lock(lock) sx_slock(lock)
-#define read_unlock(lock) sx_sunlock(lock)
-#define write_lock(lock) sx_xlock(lock)
-#define write_trylock(lock) sx_try_xlock(lock)
-#define write_unlock(lock) sx_xunlock(lock)
-#define rwlock_trypromote(lock) sx_try_upgrade(lock)
-#define rwlock_demote(lock) sx_downgrade(lock)
-
-
-#endif /* __XFS_SUPPORT_RWLOCK_H__ */
diff --git a/sys/gnu/fs/xfs/FreeBSD/support/rwsem.h b/sys/gnu/fs/xfs/FreeBSD/support/rwsem.h
deleted file mode 100644
index bb97232..0000000
--- a/sys/gnu/fs/xfs/FreeBSD/support/rwsem.h
+++ /dev/null
@@ -1,21 +0,0 @@
-#ifndef __XFS_SUPPORT_RWSEM_H__
-#define __XFS_SUPPORT_RWSEM_H__
-
-#include <sys/param.h>
-#include <sys/lock.h>
-#include <sys/mutex.h>
-#include <sys/sx.h>
-
-#define rw_semaphore sx
-
-#define init_rwsem(sem) sx_init(sem, "rwsem")
-#define free_rwsem(sem) sx_destroy(sem)
-#define down_read(sem) sx_slock(sem)
-#define down_read_trylock(sem) sx_try_slock(sem)
-#define down_write(sem) sx_xlock(sem)
-#define down_write_trylock(sem) sx_try_xlock(sem)
-#define up_read(sem) sx_sunlock(sem)
-#define up_write(sem) sx_xunlock(sem)
-#define downgrade_write(sem) sx_downgrade(sem)
-
-#endif /* __XFS_SUPPORT_RWSEM_H__ */
diff --git a/sys/gnu/fs/xfs/FreeBSD/support/sema.h b/sys/gnu/fs/xfs/FreeBSD/support/sema.h
deleted file mode 100644
index db7795b..0000000
--- a/sys/gnu/fs/xfs/FreeBSD/support/sema.h
+++ /dev/null
@@ -1,53 +0,0 @@
-/*-
- * Copyright (c) 1992, 1993
- * The Regents of the University of California. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-#ifndef __XFS_SUPPORT_SEMA_H__
-#define __XFS_SUPPORT_SEMA_H__
-
-#include <sys/sema.h>
-
-/*
- * sema_t structure just maps to struct sema in FreeBSD kernel.
- */
-
-typedef struct sema sema_t;
-
-#define init_sema(sp, val, c, d) sema_init(sp, val, c)
-#define initnsema(sp, val, name) sema_init(sp, val, name)
-#define psema(sp, b) sema_wait(sp)
-#define vsema(sp) sema_post(sp)
-#define valusema(sp) sema_value(sp)
-#define freesema(sp) sema_destroy(sp)
-#define cpsema(sp) sema_trywait(sp)
-
-#endif /* __XFS_SUPPORT_SEMA_H__ */
diff --git a/sys/gnu/fs/xfs/FreeBSD/support/spin.h b/sys/gnu/fs/xfs/FreeBSD/support/spin.h
deleted file mode 100644
index e337e32..0000000
--- a/sys/gnu/fs/xfs/FreeBSD/support/spin.h
+++ /dev/null
@@ -1,42 +0,0 @@
-#ifndef __XFS_SUPPORT_SPIN_H__
-#define __XFS_SUPPORT_SPIN_H__
-
-#include <sys/param.h>
-#include <sys/types.h>
-#include <sys/lock.h>
-#include <sys/mutex.h>
-
-#define SPLDECL(s) register_t s
-
-/*
- * Map the spinlocks from IRIX to FreeBSD
- */
-#define spinlock_init(lock, name) mtx_init(lock, name, NULL, MTX_DEF)
-#define spinlock_destroy(lock) mtx_destroy(lock)
-
-/*
- * Map lock_t from IRIX to FreeBSD mutexes
- */
-typedef struct mtx lock_t;
-
-#define nested_spinunlock(lock) mtx_unlock(lock)
-#define nested_spinlock(lock) mtx_lock(lock)
-#define nested_spintrylock(lock) mtx_trylock(lock)
-
-#define spin_lock(lock) mtx_lock(lock)
-#define spin_unlock(lock) mtx_unlock(lock)
-
-#if LOCK_DEBUG > 0
-#define mutex_spinlock(lock) (spin_lock(lock),0)
-#else
-static __inline register_t
-mutex_spinlock(lock_t *lock) { mtx_lock(lock); return 0; }
-#endif
-
-#define mutex_spinunlock(lock, s) \
- do { \
- spin_unlock(lock); \
- if (s != 0) {} \
- } while (0)
-
-#endif /* __XFS_SUPPORT_SPIN_H__ */
diff --git a/sys/gnu/fs/xfs/FreeBSD/support/support.h b/sys/gnu/fs/xfs/FreeBSD/support/support.h
deleted file mode 100644
index d7804fa..0000000
--- a/sys/gnu/fs/xfs/FreeBSD/support/support.h
+++ /dev/null
@@ -1,49 +0,0 @@
-/*
- * Copyright (c) 2000 Silicon Graphics, Inc. All Rights Reserved.
- *
- * This program 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.
- *
- * This program is distributed in the hope that it would be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
- *
- * Further, this software is distributed without any warranty that it is
- * free of the rightful claim of any third person regarding infringement
- * or the like. Any license provided herein, whether implied or
- * otherwise, applies only to this software file. Patent licenses, if
- * any, provided herein do not apply to combinations of this program with
- * other software, or any other product whatsoever.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write the Free Software Foundation, Inc., 59
- * Temple Place - Suite 330, Boston MA 02111-1307, USA.
- *
- * Contact information: Silicon Graphics, Inc., 1600 Amphitheatre Pkwy,
- * Mountain View, CA 94043, or:
- *
- * http://www.sgi.com
- *
- * For further information regarding this notice, see:
- *
- * http://oss.sgi.com/projects/GenInfo/SGIGPLNoticeExplan/
- */
-#ifndef __XFS_SUPPORT_H__
-#define __XFS_SUPPORT_H__
-
-#include <support/types.h>
-#include <support/arch.h>
-#include <support/kmem.h>
-#include <support/mrlock.h>
-#include <support/spin.h>
-#include <support/sv.h>
-#include <support/ktrace.h>
-#include <support/mutex.h>
-#include <support/sema.h>
-#include <support/atomic.h>
-#include <support/debug.h>
-#include <support/uuid.h>
-#include <support/time.h>
-
-#endif /* __XFS_SUPPORT_H__ */
diff --git a/sys/gnu/fs/xfs/FreeBSD/support/sv.h b/sys/gnu/fs/xfs/FreeBSD/support/sv.h
deleted file mode 100644
index 1a378d2..0000000
--- a/sys/gnu/fs/xfs/FreeBSD/support/sv.h
+++ /dev/null
@@ -1,30 +0,0 @@
-#ifndef __XFS_SUPPORT_SV_H__
-#define __XFS_SUPPORT_SV_H__
-
-#include <sys/condvar.h>
-
-/*
- * Synchronisation variables
- *
- * parameters "pri", "svf" and "rts" are not (yet?) implemented
- *
- */
-
-typedef struct cv sv_t;
-
-#define init_sv(sv,type,name,flag) cv_init(sv, name)
-#define sv_init(sv,flag,name) cv_init(sv, name)
-/* sv_wait should exit with lock unlocked */
-#define sv_wait(sv, pri, lock, spl) cv_wait_unlock(sv, lock)
-#define sv_wait_sig(sv, pri, lock, spl) cv_wait_sig_nolock(sv, lock)
-#define sv_signal(sv) cv_signal(sv)
-#define sv_broadcast(sv) cv_broadcast(sv)
-#define sv_destroy(sv) cv_destroy(sv)
-
-#define SV_FIFO 0x0 /* sv_t is FIFO type */
-#define SV_LIFO 0x2 /* sv_t is LIFO type */
-#define SV_PRIO 0x4 /* sv_t is PRIO type */
-#define SV_KEYED 0x6 /* sv_t is KEYED type */
-#define SV_DEFAULT SV_FIFO
-
-#endif /* __XFS_SUPPORT_SV_H__ */
diff --git a/sys/gnu/fs/xfs/FreeBSD/support/time.h b/sys/gnu/fs/xfs/FreeBSD/support/time.h
deleted file mode 100644
index 9b3a974..0000000
--- a/sys/gnu/fs/xfs/FreeBSD/support/time.h
+++ /dev/null
@@ -1,37 +0,0 @@
-/*
- * Copyright (c) 2000 Silicon Graphics, Inc. All Rights Reserved.
- *
- * This program 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.
- *
- * This program is distributed in the hope that it would be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
- *
- * Further, this software is distributed without any warranty that it is
- * free of the rightful claim of any third person regarding infringement
- * or the like. Any license provided herein, whether implied or
- * otherwise, applies only to this software file. Patent licenses, if
- * any, provided herein do not apply to combinations of this program with
- * other software, or any other product whatsoever.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write the Free Software Foundation, Inc., 59
- * Temple Place - Suite 330, Boston MA 02111-1307, USA.
- *
- * Contact information: Silicon Graphics, Inc., 1600 Amphitheatre Pkwy,
- * Mountain View, CA 94043, or:
- *
- * http://www.sgi.com
- *
- * For further information regarding this notice, see:
- *
- * http://oss.sgi.com/projects/GenInfo/SGIGPLNoticeExplan/
- */
-#ifndef __XFS_SUPPORT_TIME_H__
-#define __XFS_SUPPORT_TIME_H__
-
-#define delay(ticks) DELAY(ticks)
-
-#endif /* __XFS_SUPPORT_TIME_H__ */
diff --git a/sys/gnu/fs/xfs/FreeBSD/support/uuid.c b/sys/gnu/fs/xfs/FreeBSD/support/uuid.c
deleted file mode 100644
index 55344c0..0000000
--- a/sys/gnu/fs/xfs/FreeBSD/support/uuid.c
+++ /dev/null
@@ -1,165 +0,0 @@
-/*
- * Copyright (c) 2000-2003 Silicon Graphics, Inc. All Rights Reserved.
- *
- * This program 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.
- *
- * This program is distributed in the hope that it would be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
- *
- * Further, this software is distributed without any warranty that it is
- * free of the rightful claim of any third person regarding infringement
- * or the like. Any license provided herein, whether implied or
- * otherwise, applies only to this software file. Patent licenses, if
- * any, provided herein do not apply to combinations of this program with
- * other software, or any other product whatsoever.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write the Free Software Foundation, Inc., 59
- * Temple Place - Suite 330, Boston MA 02111-1307, USA.
- *
- * Contact information: Silicon Graphics, Inc., 1600 Amphitheatre Pkwy,
- * Mountain View, CA 94043, or:
- *
- * http://www.sgi.com
- *
- * For further information regarding this notice, see:
- *
- * http://oss.sgi.com/projects/GenInfo/SGIGPLNoticeExplan/
- */
-
-#include <xfs_config.h>
-#include <xfs_compat.h>
-#include <xfs_types.h>
-#include <xfs_arch.h>
-
-#include <support/uuid.h>
-#include <support/kmem.h>
-#include <support/debug.h>
-#include <support/mutex.h>
-
-static mutex_t uuid_monitor;
-static int uuid_table_size;
-static uuid_t *uuid_table;
-
-void
-uuid_init(void)
-{
- mutex_init(&uuid_monitor, MUTEX_DEFAULT, "uuid_monitor");
-}
-
-void
-uuid_cleanup(void)
-{
- mutex_destroy(&uuid_monitor);
-}
-
-/*
- * uuid_getnodeuniq - obtain the node unique fields of a UUID.
- *
- * This is not in any way a standard or condoned UUID function;
- * it just something that's needed for user-level file handles.
- */
-void
-uuid_getnodeuniq(uuid_t *uuid, int fsid [2])
-{
- char *uu = (char *)uuid;
-
- /* on IRIX, this function assumes big-endian fields within
- * the uuid, so we use INT_GET to get the same result on
- * little-endian systems
- */
-
- fsid[0] = (INT_GET(*(u_int16_t*)(uu+8), ARCH_CONVERT) << 16) +
- INT_GET(*(u_int16_t*)(uu+4), ARCH_CONVERT);
- fsid[1] = INT_GET(*(u_int32_t*)(uu ), ARCH_CONVERT);
-}
-
-void
-uuid_create_nil(uuid_t *uuid)
-{
- memset(uuid, 0, sizeof(*uuid));
-}
-
-int
-uuid_is_nil(uuid_t *uuid)
-{
- int i;
- char *cp = (char *)uuid;
-
- if (uuid == NULL)
- return 0;
- /* implied check of version number here... */
- for (i = 0; i < sizeof *uuid; i++)
- if (*cp++) return 0; /* not nil */
- return 1; /* is nil */
-}
-
-int
-uuid_equal(uuid_t *uuid1, uuid_t *uuid2)
-{
- return memcmp(uuid1, uuid2, sizeof(uuid_t)) ? 0 : 1;
-}
-
-/*
- * Given a 128-bit uuid, return a 64-bit value by adding the top and bottom
- * 64-bit words. NOTE: This function can not be changed EVER. Although
- * brain-dead, some applications depend on this 64-bit value remaining
- * persistent. Specifically, DMI vendors store the value as a persistent
- * filehandle.
- */
-__uint64_t
-uuid_hash64(uuid_t *uuid)
-{
- __uint64_t *sp = (__uint64_t *)uuid;
-
- return sp[0] + sp[1];
-}
-
-int
-uuid_table_insert(uuid_t *uuid)
-{
- int i, hole;
-
- mutex_lock(&uuid_monitor, PVFS);
- for (i = 0, hole = -1; i < uuid_table_size; i++) {
- if (uuid_is_nil(&uuid_table[i])) {
- hole = i;
- continue;
- }
- if (uuid_equal(uuid, &uuid_table[i])) {
- mutex_unlock(&uuid_monitor);
- return 0;
- }
- }
- if (hole < 0) {
- uuid_table = kmem_realloc(uuid_table,
- (uuid_table_size + 1) * sizeof(*uuid_table),
- uuid_table_size * sizeof(*uuid_table),
- KM_SLEEP);
- hole = uuid_table_size++;
- }
- uuid_table[hole] = *uuid;
- mutex_unlock(&uuid_monitor);
- return 1;
-}
-
-void
-uuid_table_remove(uuid_t *uuid)
-{
- int i;
-
- mutex_lock(&uuid_monitor, PVFS);
- for (i = 0; i < uuid_table_size; i++) {
- if (uuid_is_nil(&uuid_table[i]))
- continue;
- if (!uuid_equal(uuid, &uuid_table[i]))
- continue;
- uuid_create_nil(&uuid_table[i]);
- break;
- }
- ASSERT(i < uuid_table_size);
- mutex_unlock(&uuid_monitor);
-}
diff --git a/sys/gnu/fs/xfs/FreeBSD/support/uuid.h b/sys/gnu/fs/xfs/FreeBSD/support/uuid.h
deleted file mode 100644
index d8f389a..0000000
--- a/sys/gnu/fs/xfs/FreeBSD/support/uuid.h
+++ /dev/null
@@ -1,45 +0,0 @@
-/*
- * Copyright (c) 2000-2003 Silicon Graphics, Inc. All Rights Reserved.
- *
- * This program 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.
- *
- * This program is distributed in the hope that it would be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
- *
- * Further, this software is distributed without any warranty that it is
- * free of the rightful claim of any third person regarding infringement
- * or the like. Any license provided herein, whether implied or
- * otherwise, applies only to this software file. Patent licenses, if
- * any, provided herein do not apply to combinations of this program with
- * other software, or any other product whatsoever.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write the Free Software Foundation, Inc., 59
- * Temple Place - Suite 330, Boston MA 02111-1307, USA.
- *
- * Contact information: Silicon Graphics, Inc., 1600 Amphitheatre Pkwy,
- * Mountain View, CA 94043, or:
- *
- * http://www.sgi.com
- *
- * For further information regarding this notice, see:
- *
- * http://oss.sgi.com/projects/GenInfo/SGIGPLNoticeExplan/
- */
-#ifndef __XFS_SUPPORT_UUID_H__
-#define __XFS_SUPPORT_UUID_H__
-
-void uuid_init(void);
-void uuid_cleanup(void);
-void uuid_create_nil(uuid_t *uuid);
-int uuid_is_nil(uuid_t *uuid);
-int uuid_equal(uuid_t *uuid1, uuid_t *uuid2);
-void uuid_getnodeuniq(uuid_t *uuid, int fsid [2]);
-__uint64_t uuid_hash64(uuid_t *uuid);
-int uuid_table_insert(uuid_t *uuid);
-void uuid_table_remove(uuid_t *uuid);
-
-#endif /* __XFS_SUPPORT_UUID_H__ */
diff --git a/sys/gnu/fs/xfs/FreeBSD/xfs_buf.c b/sys/gnu/fs/xfs/FreeBSD/xfs_buf.c
deleted file mode 100644
index b1821a8..0000000
--- a/sys/gnu/fs/xfs/FreeBSD/xfs_buf.c
+++ /dev/null
@@ -1,334 +0,0 @@
-/*
- * Copyright (c) 2001,2005 Russell Cattelan
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * $FreeBSD$
- */
-
-#include "xfs.h"
-#include "xfs_types.h"
-#include "xfs_inum.h"
-#include "xfs_log.h"
-#include "xfs_trans.h"
-#include "xfs_sb.h"
-#include "xfs_ag.h"
-#include "xfs_dir.h"
-#include "xfs_dir2.h"
-#include "xfs_dmapi.h"
-#include "xfs_mount.h"
-#include "xfs_clnt.h"
-#include "xfs_mountops.h"
-
-#include <geom/geom.h>
-#include <geom/geom_vfs.h>
-
-xfs_buf_t *
-xfs_buf_read_flags(xfs_buftarg_t *target, xfs_daddr_t blkno, size_t len, int flags)
-{
- struct buf *bp;
- KASSERT((target != NULL), ("got NULL buftarg_t"));
-
- if (bread(target->specvp, blkno, BBTOB(len), NOCRED, &bp)) {
- printf("bread failed specvp %p blkno %jd BBTOB(len) %ld\n",
- target->specvp, (intmax_t)blkno, (long)BBTOB(len));
- bp = NULL;
- }
-
- /* not really sure what B_MANAGED really does for us
- * maybe we should drop this and just stick with a locked buf
- */
-
- if (flags & B_MANAGED)
- bp->b_flags |= B_MANAGED;
- xfs_buf_set_target(bp, target);
- return (bp);
-}
-
-xfs_buf_t *
-xfs_buf_get_flags(xfs_buftarg_t *target, xfs_daddr_t blkno, size_t len, int flags)
-{
- struct buf *bp = NULL;
- KASSERT((target != NULL), ("got NULL buftarg_t"));
- bp = getblk(target->specvp, blkno, BBTOB(len), 0, 0, 0);
- if (bp != NULL)
- xfs_buf_set_target(bp, target);
- return (bp);
-}
-
-xfs_buf_t*
-xfs_buf_get_empty(size_t size, xfs_buftarg_t *target)
-{
- struct buf *bp;
-
- bp = geteblk(0, 0);
- if (bp != NULL) {
- bp->b_bufsize = size;
- bp->b_bcount = size;
-
- BUF_ASSERT_HELD(bp);
-
- xfs_buf_set_target(bp, target);
- }
- return (bp);
-}
-
-xfs_buf_t*
-xfs_buf_get_noaddr(size_t len, xfs_buftarg_t *target)
-{
- struct buf *bp;
- if (len >= MAXPHYS)
- return (NULL);
-
- bp = geteblk(len, 0);
- if (bp != NULL) {
- BUF_ASSERT_HELD(bp);
-
- xfs_buf_set_target(bp, target);
- }
- return (bp);
-}
-
-void
-xfs_buf_free(xfs_buf_t *bp)
-{
- bp->b_flags |= B_INVAL;
- BUF_KERNPROC(bp); /* ugly hack #1 */
- if (bp->b_kvasize == 0) {
- bp->b_saveaddr = bp->b_kvabase; /* ugly hack #2 */
- bp->b_data = bp->b_saveaddr;
- bp->b_bcount = 0;
- bp->b_bufsize = 0;
- }
- brelse(bp);
-}
-
-void
-xfs_buf_readahead(
- xfs_buftarg_t *target,
- xfs_daddr_t ioff,
- size_t isize,
- xfs_buf_flags_t flags)
-{
- daddr_t rablkno;
- int rabsize;
-
- rablkno = ioff;
- rabsize = BBTOB(isize);
- breada(target->specvp, &rablkno, &rabsize, 1, NOCRED);
-}
-
-void
-xfs_buf_set_target(xfs_buf_t *bp, xfs_buftarg_t *targ)
-{
- bp->b_bufobj = &targ->specvp->v_bufobj;
- bp->b_caller1 = targ;
-}
-
-xfs_buftarg_t *
-xfs_buf_get_target(xfs_buf_t *bp)
-{
- return (xfs_buftarg_t *)bp->b_caller1;
-}
-
-int
-XFS_bwrite(xfs_buf_t *bp)
-{
- int error;
- if (bp->b_vp == NULL) {
- error = xfs_buf_iorequest(bp);
-
- if ((bp->b_flags & B_ASYNC) == 0) {
- error = bufwait(bp);
-#if 0
- if (BUF_LOCKRECURSED(bp))
- BUF_UNLOCK(bp);
- else
- brelse(bp);
-#endif
- brelse(bp);
- }
- return (error);
- }
- error = bwrite(bp);
- return (error);
-}
-
-void
-xfs_buf_pin(xfs_buf_t *bp)
-{
- bpin(bp);
-}
-
-void
-xfs_buf_unpin(xfs_buf_t *bp)
-{
- bunpin(bp);
-}
-
-int
-xfs_buf_ispin(xfs_buf_t *bp)
-{
- return bp->b_pin_count;
-}
-
-#if 0
-void
-xfs_buf_wait_unpin(
- xfs_buf_t *bp)
-{
- bunpin_wait(bp);
-}
-#endif
-
-/*
- * Move data into or out of a buffer.
- */
-void
-xfs_buf_iomove(
- xfs_buf_t *bp, /* buffer to process */
- size_t boff, /* starting buffer offset */
- size_t bsize, /* length to copy */
- caddr_t data, /* data address */
- xfs_buf_rw_t mode) /* read/write/zero flag */
-{
-
- printf("xfs_buf_iomove NI\n");
-#ifdef RMC
- size_t bend, cpoff, csize;
- struct page *page;
-
- bend = boff + bsize;
- while (boff < bend) {
- page = bp->b_pages[xfs_buf_btoct(boff + bp->b_offset)];
- cpoff = xfs_buf_poff(boff + bp->b_offset);
- csize = min_t(size_t,
- PAGE_CACHE_SIZE-cpoff, bp->b_count_desired-boff);
-
- ASSERT(((csize + cpoff) <= PAGE_CACHE_SIZE));
-
- switch (mode) {
- case XBRW_ZERO:
- memset(page_address(page) + cpoff, 0, csize);
- break;
- case XBRW_READ:
- memcpy(data, page_address(page) + cpoff, csize);
- break;
- case XBRW_WRITE:
- memcpy(page_address(page) + cpoff, data, csize);
- }
-
- boff += csize;
- data += csize;
- }
-#endif
-}
-
-/*
- * Handling of buffer targets (buftargs).
- */
-
-/*
- * Wait for any bufs with callbacks that have been submitted but
- * have not yet returned... walk the hash list for the target.
- */
-void
-xfs_wait_buftarg(
- xfs_buftarg_t *bp)
-{
- printf("xfs_wait_buftarg(%p) NI\n", bp);
-}
-
-int
-xfs_flush_buftarg(
- xfs_buftarg_t *btp,
- int wait)
-{
- int error = 0;
-
- error = vinvalbuf(btp->specvp, V_SAVE | V_NORMAL, 0, 0);
- return error;
-}
-
-void
-xfs_free_buftarg(
- xfs_buftarg_t *btp,
- int external)
-{
- xfs_flush_buftarg(btp, /* wait */ 0);
- kmem_free(btp, sizeof(*btp));
-}
-
-int
-xfs_readonly_buftarg(
- xfs_buftarg_t *btp)
-{
- struct g_consumer *cp;
-
- KASSERT(btp->specvp->v_bufobj.bo_ops == &xfs_bo_ops,
- ("Bogus xfs_buftarg_t pointer"));
- cp = btp->specvp->v_bufobj.bo_private;
- return (cp->acw == 0);
-}
-
-#if 0
-void
-xfs_relse_buftarg(
- xfs_buftarg_t *btp)
-{
- printf("xfs_relse_buftargNI %p\n",btp);
-}
-#endif
-
-unsigned int
-xfs_getsize_buftarg(
- xfs_buftarg_t *btp)
-{
- struct g_consumer *cp;
- cp = btp->specvp->v_bufobj.bo_private;
- return (cp->provider->sectorsize);
-}
-
-int
-xfs_setsize_buftarg(
- xfs_buftarg_t *btp,
- unsigned int blocksize,
- unsigned int sectorsize)
-{
- printf("xfs_setsize_buftarg NI %p\n",btp);
- return 0;
-}
-
-xfs_buftarg_t *
-xfs_alloc_buftarg(
- struct vnode *bdev,
- int external)
-{
- xfs_buftarg_t *btp;
-
- btp = kmem_zalloc(sizeof(*btp), KM_SLEEP);
-
- btp->dev = bdev->v_rdev;
- btp->specvp = bdev;
- return btp;
-}
diff --git a/sys/gnu/fs/xfs/FreeBSD/xfs_buf.h b/sys/gnu/fs/xfs/FreeBSD/xfs_buf.h
deleted file mode 100644
index 34e579d..0000000
--- a/sys/gnu/fs/xfs/FreeBSD/xfs_buf.h
+++ /dev/null
@@ -1,348 +0,0 @@
-/*
- * Copyright (c) 2000-2003 Silicon Graphics, Inc. All Rights Reserved.
- *
- * This program 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.
- *
- * This program is distributed in the hope that it would be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
- *
- * Further, this software is distributed without any warranty that it is
- * free of the rightful claim of any third person regarding infringement
- * or the like. Any license provided herein, whether implied or
- * otherwise, applies only to this software file. Patent licenses, if
- * any, provided herein do not apply to combinations of this program with
- * other software, or any other product whatsoever.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write the Free Software Foundation, Inc., 59
- * Temple Place - Suite 330, Boston MA 02111-1307, USA.
- *
- * Contact information: Silicon Graphics, Inc., 1600 Amphitheatre Pkwy,
- * Mountain View, CA 94043, or:
- *
- * http://www.sgi.com
- *
- * For further information regarding this notice, see:
- *
- * http://oss.sgi.com/projects/GenInfo/SGIGPLNoticeExplan/
- */
-#ifndef __XFS_BUF_H__
-#define __XFS_BUF_H__
-
-#include <sys/bio.h>
-#include <sys/buf.h>
-
-struct xfs_buf;
-struct xfs_mount;
-struct vnode;
-typedef struct buf xfs_buf_t;
-typedef uint32_t xfs_buf_flags_t;
-#define xfs_buf buf
-
-extern struct buf_ops xfs_bo_ops;
-
-typedef enum {
- XBRW_READ = 1, /* transfer into target memory */
- XBRW_WRITE = 2, /* transfer from target memory */
- XBRW_ZERO = 3, /* Zero target memory */
-} xfs_buf_rw_t;
-
-/* Buffer Read and Write Routines */
-extern void xfs_buf_ioend(xfs_buf_t *, int);
-extern void xfs_buf_ioerror(xfs_buf_t *, int);
-extern int xfs_buf_iostart(xfs_buf_t *, xfs_buf_flags_t);
-extern int xfs_buf_iorequest(xfs_buf_t *);
-extern int xfs_buf_iowait(xfs_buf_t *);
-extern void xfs_buf_iomove(xfs_buf_t *, size_t, size_t, xfs_caddr_t, xfs_buf_rw_t);
-
-/* Pinning Buffer Storage in Memory */
-extern void xfs_buf_pin(xfs_buf_t *);
-extern void xfs_buf_unpin(xfs_buf_t *);
-extern int xfs_buf_ispin(xfs_buf_t *);
-
-
-typedef void (*xfs_buf_iodone_t)(struct xfs_buf *); /* call-back function on I/O completion */
-typedef void (*xfs_buf_relse_t)(struct xfs_buf *); /* call-back function on I/O completion */
-typedef int (*xfs_buf_bdstrat_t)(struct xfs_buf *);
-
-typedef struct xfs_buftarg {
- /* this probaby redundant info, but stick with linux conventions for now */
- unsigned int bt_bsize;
- unsigned int bt_sshift;
- size_t bt_smask;
- struct cdev *dev;
- struct vnode *specvp;
-} xfs_buftarg_t;
-
-
-/* Finding and Reading Buffers */
-extern void xfs_buf_readahead(xfs_buftarg_t *, xfs_off_t, size_t, xfs_buf_flags_t);
-/* Misc buffer rountines */
-extern int xfs_readonly_buftarg(xfs_buftarg_t *);
-
-/* These are just for xfs_syncsub... it sets an internal variable
- * then passes it to VOP_FLUSH_PAGES or adds the flags to a newly gotten buf_t
- */
-#define XBF_DONT_BLOCK 0
-
-#define XFS_B_ASYNC B_ASYNC
-#define XFS_B_DELWRI B_DELWRI
-#define XFS_B_READ BIO_READ
-#define XFS_B_WRITE BIO_WRITE
-
-#define XFS_B_STALE B_INVAL
-#define XFS_BUF_LOCK 0
-#define XFS_BUF_TRYLOCK 0
-#define XFS_BUF_MAPPED 0
-#define BUF_BUSY 0
-
-#define XBF_ORDERED 0
-
- /* debugging routines might need this */
-#define XFS_BUF_BFLAGS(x) ((x)->b_flags)
-#define XFS_BUF_ZEROFLAGS(x) ((x)->b_flags = 0)
-#define XFS_BUF_STALE(x) ((x)->b_flags |= (XFS_B_STALE|B_NOCACHE))
-#define XFS_BUF_UNSTALE(x) ((x)->b_flags &= ~(XFS_B_STALE|B_NOCACHE))
-#define XFS_BUF_ISSTALE(x) ((x)->b_flags & (XFS_B_STALE|B_NOCACHE))
-#define XFS_BUF_SUPER_STALE(x) {(x)->b_flags |= (XFS_B_STALE|B_NOCACHE); \
- (x)->b_flags &= ~(XFS_B_DELWRI|B_CACHE);}
-
-#define XFS_BUF_MANAGE B_MANAGED
-#define XFS_BUF_UNMANAGE(x) ((x)->b_flags &= ~B_MANAGED)
-
-#define XFS_BUF_DELAYWRITE(x) ((x)->b_flags |= XFS_B_DELWRI)
-#define XFS_BUF_UNDELAYWRITE(x) ((x)->b_flags &= ~XFS_B_DELWRI)
-#define XFS_BUF_ISDELAYWRITE(x) ((x)->b_flags & XFS_B_DELWRI)
-
-#define XFS_BUF_ERROR(x,no) xfs_buf_set_error((x), (no))
-#define XFS_BUF_GETERROR(x) xfs_buf_get_error(x)
-#define XFS_BUF_ISERROR(x) (((x)->b_ioflags & BIO_ERROR) != 0)
-
-void static __inline__
-xfs_buf_set_error(struct buf *bp, int err)
-{
- bp->b_ioflags |= BIO_ERROR;
- bp->b_error = err;
-}
-
-int static __inline__
-xfs_buf_get_error(struct buf *bp)
-{
- return XFS_BUF_ISERROR(bp) ? (bp->b_error ? bp->b_error : EIO) : 0;
-}
-
-#define XFS_BUF_DONE(x) ((x)->b_flags |= B_CACHE)
-#define XFS_BUF_UNDONE(x) ((x)->b_flags &= ~B_CACHE)
-#define XFS_BUF_ISDONE(x) ((x)->b_flags & B_CACHE)
-
-#define XFS_BUF_BUSY(x) ((x)->b_flags |= BUF_BUSY)
-#define XFS_BUF_UNBUSY(x) ((x)->b_flags &= ~BUF_BUSY)
-#define XFS_BUF_ISBUSY(x) (1)
-
-#define XFS_BUF_ASYNC(x) ((x)->b_flags |= B_ASYNC)
-#define XFS_BUF_UNASYNC(x) ((x)->b_flags &= ~B_ASYNC)
-#define XFS_BUF_ISASYNC(x) ((x)->b_flags & B_ASYNC)
-
-#define XFS_BUF_ORDERED(bp) ((bp)->b_flags |= XBF_ORDERED)
-#define XFS_BUF_UNORDERED(bp) ((bp)->b_flags &= ~XBF_ORDERED)
-#define XFS_BUF_ISORDERED(bp) ((bp)->b_flags & XBF_ORDERED)
-
-#define XFS_BUF_FLUSH(x) ((x)->b_flags |= B_00800000)
-#define XFS_BUF_UNFLUSH(x) ((x)->b_flags &= ~B_00800000)
-#define XFS_BUF_ISFLUSH(x) ((x)->b_flags & B_00800000)
-
-#define XFS_BUF_SHUT(x) printf("XFS_BUF_SHUT not implemented yet\n")
-#define XFS_BUF_UNSHUT(x) printf("XFS_BUF_UNSHUT not implemented yet\n")
-#define XFS_BUF_ISSHUT(x) (0)
-
-#define XFS_BUF_HOLD(x) ((void)0)
-#define XFS_BUF_UNHOLD(x) ((void)0)
-
-#define XFS_BUF_READ(x) ((x)->b_iocmd = BIO_READ)
-#define XFS_BUF_UNREAD(x) ((x)->b_iocmd = 0)
-#define XFS_BUF_ISREAD(x) ((x)->b_iocmd == BIO_READ)
-
-#define XFS_BUF_WRITE(x) ((x)->b_iocmd = BIO_WRITE)
-#define XFS_BUF_UNWRITE(x) ((x)->b_iocmd = 0)
-#define XFS_BUF_ISWRITE(x) ((x)->b_iocmd == BIO_WRITE)
-
-#define XFS_BUF_ISUNINITIAL(x) (0)
-#define XFS_BUF_UNUNINITIAL(x) (0)
-
-#define XFS_BUF_IODONE_FUNC(x) (x)->b_iodone
-#define XFS_BUF_SET_IODONE_FUNC(x, f) (x)->b_iodone = (f)
-#define XFS_BUF_CLR_IODONE_FUNC(x) (x)->b_iodone = NULL
-
-#define XFS_BUF_SET_BDSTRAT_FUNC(x, f) do { if(f != NULL) {} } while(0)
-#define XFS_BUF_CLR_BDSTRAT_FUNC(x) ((void)0)
-
-#define XFS_BUF_BP_ISMAPPED(bp) (1)
-
-#define XFS_BUF_FSPRIVATE(buf, type) \
- ((type)(buf)->b_fsprivate1)
-#define XFS_BUF_SET_FSPRIVATE(buf, value) \
- (buf)->b_fsprivate1 = (void *)(value)
-#define XFS_BUF_FSPRIVATE2(buf, type) \
- ((type)(buf)->b_fsprivate2)
-#define XFS_BUF_SET_FSPRIVATE2(buf, value) \
- (buf)->b_fsprivate2 = (void *)(value)
-#define XFS_BUF_FSPRIVATE3(buf, type) \
- ((type)(buf)->b_fsprivate3)
-#define XFS_BUF_SET_FSPRIVATE3(buf, value) \
- (buf)->b_fsprivate3 = (void *)(value)
-#define XFS_BUF_SET_START(buf) \
- printf("XFS_BUF_SET_START: %s:%d\n", __FILE__, __LINE__)
-
-#define XFS_BUF_SET_BRELSE_FUNC(buf, value) \
- do { \
- printf("XFS_BUF_SET_BRELSE_FUNC: %s:%d\n", \
- __FILE__, __LINE__); \
- if (value != NULL ) {} \
- } while(0)
-
-#define XFS_BUF_PTR(bp) (xfs_caddr_t)((bp)->b_data)
-
-static __inline xfs_caddr_t
-xfs_buf_offset(xfs_buf_t *bp, size_t offset)
-{
- return XFS_BUF_PTR(bp) + offset;
-}
-
-#define XFS_BUF_SET_PTR(bp, val, count) \
- do { \
- (bp)->b_data = (val); \
- (bp)->b_bcount = (count); \
- } while(0)
-
-#define XFS_BUF_ADDR(bp) ((bp)->b_blkno)
-#define XFS_BUF_SET_ADDR(bp, blk) \
- ((bp)->b_blkno = blk)
-#define XFS_BUF_OFFSET(bp) ((bp)->b_offset)
-#define XFS_BUF_SET_OFFSET(bp, off) \
- ((bp)->b_offset = off)
-#define XFS_BUF_COUNT(bp) ((bp)->b_bcount)
-#define XFS_BUF_SET_COUNT(bp, cnt) \
- ((bp)->b_bcount = cnt)
-#define XFS_BUF_SIZE(bp) ((bp)->b_bufsize)
-#define XFS_BUF_SET_SIZE(bp, cnt) \
- ((bp)->b_bufsize = cnt)
-#define XFS_BUF_SET_VTYPE_REF(bp, type, ref)
-#define XFS_BUF_SET_VTYPE(bp, type)
-#define XFS_BUF_SET_REF(bp, ref)
-
-#define XFS_BUF_VALUSEMA(bp) (BUF_ISLOCKED(bp) ? 0 : 1)
-#define XFS_BUF_CPSEMA(bp) \
- (BUF_LOCK(bp, LK_EXCLUSIVE|LK_CANRECURSE | LK_SLEEPFAIL, NULL) == 0)
-
-#define XFS_BUF_PSEMA(bp,x) BUF_LOCK(bp, LK_EXCLUSIVE|LK_CANRECURSE, NULL)
-#define XFS_BUF_VSEMA(bp) BUF_UNLOCK(bp)
-
-#define XFS_BUF_V_IODONESEMA(bp) bdone(bp)
-
-/* setup the buffer target from a buftarg structure */
-#define XFS_BUF_SET_TARGET(bp, target) \
- xfs_buf_set_target(bp, target)
-
-void xfs_buf_set_target(xfs_buf_t *, xfs_buftarg_t *);
-xfs_buftarg_t *xfs_buf_get_target(xfs_buf_t *);
-
-/* return the dev_t being used */
-#define XFS_BUF_TARGET(bp) xfs_buf_get_target(bp)
-#define XFS_BUFTARG_NAME(targp) devtoname((targp)->dev)
-
-#define XFS_BUF_SET_VTYPE_REF(bp, type, ref)
-#define XFS_BUF_SET_VTYPE(bp, type)
-#define XFS_BUF_SET_REF(bp, ref)
-
-#define XFS_BUF_ISPINNED(bp) xfs_buf_ispin(bp)
-
-xfs_buf_t *
-xfs_buf_read_flags(xfs_buftarg_t *, xfs_daddr_t, size_t, int);
-
-#define xfs_buf_read(target, blkno, len, flags) \
- xfs_buf_read_flags(target, blkno, len, \
- XFS_BUF_LOCK | XFS_BUF_MAPPED)
-
-xfs_buf_t *
-xfs_buf_get_flags(xfs_buftarg_t *, xfs_daddr_t, size_t, int);
-
-#define xfs_buf_get(target, blkno, len, flags) \
- xfs_buf_get_flags(target, blkno, len, \
- XFS_BUF_LOCK | XFS_BUF_MAPPED)
-
-/* the return value is never used ... why does linux define this functions this way? */
-static inline int xfs_bawrite(void *mp, xfs_buf_t *bp)
-{
- /* Ditto for xfs_bawrite
- bp->b_fspriv3 = mp;
- bp->b_strat = xfs_bdstrat_cb;
- xfs_buf_delwri_dequeue(bp);
- return xfs_buf_iostart(bp, XBF_WRITE | XBF_ASYNC | _XBF_RUN_QUEUES);
- */
- bawrite(bp);
- return 0;
-}
-
-static inline int xfs_bdwrite(void *mp, xfs_buf_t *bp)
-{
- /* this is for io shutdown checking need to do this at some point RMC */
- /* probably should just change xfs to call a buf write function */
-#if 0 /* RMC */
- bp->b_strat = xfs_bdstrat_cb;
- bp->b_fspriv3 = mp;
- return xfs_buf_iostart(bp, XBF_DELWRI | XBF_ASYNC);
-#endif
- bdwrite(bp);
- return 0;
-}
-
-#define xfs_bpin(bp) xfs_buf_pin(bp)
-#define xfs_bunpin(bp) xfs_buf_unpin(bp)
-
-#define xfs_buf_relse(bp) brelse(bp)
-#define xfs_bp_mapin(bp) bp_mapin(bp)
-#define xfs_xfsd_list_evict(x) _xfs_xfsd_list_evict(x)
-#define xfs_buftrace(x,y) CTR2(KTR_BUF, "%s bp %p flags %X", bp, bp->b_flags)
-#define xfs_biodone(bp) bufdone_finish(bp)
-
-#define xfs_incore(xfs_buftarg,blkno,len,lockit) \
- incore(&xfs_buftarg->specvp->v_bufobj, blkno);
-
-#define xfs_biomove(bp, off, len, data, rw) \
- xfs_buf_iomove((bp), (off), (len), (data), \
- ((rw) == XFS_B_WRITE) ? XBRW_WRITE : XBRW_READ)
-
-#define xfs_biozero(bp, off, len) \
- xfs_buf_iomove((bp), (off), (len), NULL, XBRW_ZERO)
-
-/* already a function xfs_bwrite... fix this */
-#define XFS_bdwrite(bp) bdwrite(bp)
-#define xfs_iowait(bp) bufwait(bp)
-
-#define XFS_bdstrat(bp) xfs_buf_iorequest(bp)
-
-#define xfs_baread(target, rablkno, ralen) \
- xfs_buf_readahead((target), (rablkno), (ralen), XBF_DONT_BLOCK)
-
-struct xfs_mount;
-
-int XFS_bwrite(xfs_buf_t *bp);
-xfs_buf_t* xfs_buf_get_empty(size_t, xfs_buftarg_t *targ);
-xfs_buf_t* xfs_buf_get_noaddr(size_t, xfs_buftarg_t *targ);
-void xfs_buf_free(xfs_buf_t *);
-
-extern void xfs_bwait_unpin(xfs_buf_t *bp);
-extern xfs_buftarg_t *xfs_alloc_buftarg(struct vnode *, int);
-extern void xfs_free_buftarg(xfs_buftarg_t *, int);
-extern void xfs_wait_buftarg(xfs_buftarg_t *);
-extern int xfs_setsize_buftarg(xfs_buftarg_t *, unsigned int, unsigned int);
-extern unsigned int xfs_getsize_buftarg(struct xfs_buftarg *);
-extern int xfs_flush_buftarg(xfs_buftarg_t *, int);
-
-#define xfs_binval(buftarg) xfs_flush_buftarg(buftarg, 1)
-#define XFS_bflush(buftarg) xfs_flush_buftarg(buftarg, 1)
-
-#endif
diff --git a/sys/gnu/fs/xfs/FreeBSD/xfs_compat.h b/sys/gnu/fs/xfs/FreeBSD/xfs_compat.h
deleted file mode 100644
index 55a03c9..0000000
--- a/sys/gnu/fs/xfs/FreeBSD/xfs_compat.h
+++ /dev/null
@@ -1,173 +0,0 @@
-#ifndef __XFS_COMPAT_H__
-#define __XFS_COMPAT_H__
-
-#include <sys/param.h>
-#include <sys/libkern.h>
-#include <sys/limits.h>
-#include <sys/uuid.h>
-#include <sys/conf.h>
-#include <sys/sbuf.h>
-#include <sys/stat.h>
-#include <sys/ioccom.h>
-#include <sys/fcntl.h>
-#include <sys/dirent.h>
-#include <sys/ktr.h>
-#include <sys/kdb.h>
-
-#ifdef _KERNEL
-#define __KERNEL__
-#endif
-
-#define printk printf
-
-#define MAJOR(x) major(x)
-#define MINOR(x) minor(x)
-
-/*
- * SYSV compatibility types missing in FreeBSD.
- */
-typedef unsigned long ulong;
-typedef unsigned int uint;
-typedef unsigned short ushort;
-
-/*
- * Additional type declarations for XFS.
- */
-typedef signed char __s8;
-typedef unsigned char __u8;
-typedef signed short int __s16;
-typedef unsigned short int __u16;
-typedef signed int __s32;
-typedef unsigned int __u32;
-typedef signed long long int __s64;
-typedef unsigned long long int __u64;
-
-/* linus now has sparse which expects big endian or little endian */
-typedef __u16 __be16;
-typedef __u32 __be32;
-typedef __u64 __be64;
-
-/*
- * Linux types with direct FreeBSD conterparts
- */
-typedef off_t loff_t;
-typedef struct timespec timespec_t;
-typedef struct uuid uuid_t;
-typedef struct fid fid_t;
-typedef dev_t os_dev_t;
-
-/*
- * Linux block devices are device vnodes in FreeBSD.
- */
-#define block_device vnode
-
-/*
- * Get the current CPU ID.
- */
-#define smp_processor_id() PCPU_GET(cpuid)
-
-/*
- * FreeBSD does not have BITS_PER_LONG defined.
- */
-#if defined(LONG_BIT)
-#define BITS_PER_LONG LONG_BIT
-#elif defined(__i386__)
-#define BITS_PER_LONG 32
-#endif
-
-#define rol32(x, y) (((x)<<(y))|((x)>>(32-(y))))
-/*
- * boolean_t is enum on Linux, int on FreeBSD.
- * Provide value defines.
- */
-#define B_FALSE 0
-#define B_TRUE 1
-
-/*
- * GCC 3.x static branch prediction hints
- */
-#if __GNUC__ < 3
-#define __builtin_expect(x, expected_value) (x)
-#endif
-
-#ifndef likely
-#define likely(x) __builtin_expect((x), 1)
-#endif
-
-#ifndef unlikely
-#define unlikely(x) __builtin_expect((x), 0)
-#endif
-
-/*
- * ANSI and GCC extension keywords compatibity
- */
-#ifndef inline
-#define inline __inline__
-#endif
-
-#ifndef asm
-#define asm __asm
-#endif
-
-#ifndef typeof
-#define typeof __typeof
-#endif
-
-/*
- * Miscellaneous limit constants
- */
-#define MAX_LFS_FILESIZE 0x7fffffffffffffffLL
-
-/*
- * Map simple functions to their FreeBSD kernel equivalents
- */
-#ifndef copy_to_user
-#define copy_to_user(dst, src, len) copyout((src), (dst), (len))
-#endif
-
-#ifndef copy_from_user
-#define copy_from_user(dst, src, len) copyin((src), (dst), (len))
-#endif
-
-/*
- * Map simple global vairables to FreeBSD kernel equivalents
- */
-#if !defined(xfs_physmem)
-#define xfs_physmem physmem
-#endif
-
-#ifndef HZ
-#define HZ hz
-#endif
-
-/*
- * These should be implemented properly for all architectures
- * we want to support.
- */
-#define get_unaligned(ptr) (*(ptr))
-#define put_unaligned(val, ptr) ((void)( *(ptr) = (val) ))
-
-/*
- * Linux type-safe min/max macros.
- */
-#define min_t(type,x,y) MIN((x),(y))
-#define max_t(type,x,y) MAX((x),(y))
-
-
-typedef struct mtx xfs_mutex_t;
-/*
- * Cedentials manipulation.
- */
-#define current_fsuid(credp) (credp)->cr_uid
-#define current_fsgid(credp) (credp)->cr_groups[0]
-
-#define PAGE_CACHE_SIZE PAGE_SIZE
-
-#define IS_ERR(err) (err)
-
-static inline unsigned long ffz(unsigned long val)
-{
- return ffsl(~val);
-}
-
-#endif /* __XFS_COMPAT_H__ */
diff --git a/sys/gnu/fs/xfs/FreeBSD/xfs_config.h b/sys/gnu/fs/xfs/FreeBSD/xfs_config.h
deleted file mode 100644
index a115f54..0000000
--- a/sys/gnu/fs/xfs/FreeBSD/xfs_config.h
+++ /dev/null
@@ -1,38 +0,0 @@
-#ifndef __XFS_CONFIG_H__
-#define __XFS_CONFIG_H__
-
-#define HAVE_FID 1
-/*
- * Linux config variables, harcoded to values desirable for FreeBSD.
- */
-#define CONFIG_SYSCTL 1
-#define CONFIG_LBD 1
-#define CONFIG_XFS_TRACE 0
-
-/*
- * Tracing.
- */
-#if CONFIG_XFS_TRACE == 1
-#define XFS_ALLOC_TRACE 1
-#define XFS_ALLOC_TRACE 1
-#define XFS_ATTR_TRACE 1
-#define XFS_BLI_TRACE 1
-#define XFS_BMAP_TRACE 1
-#define XFS_BMBT_TRACE 1
-#define XFS_DIR_TRACE 1
-#define XFS_DIR2_TRACE 1
-#define XFS_DQUOT_TRACE 1
-#define XFS_ILOCK_TRACE 1
-#define XFS_LOG_TRACE 1
-#define XFS_RW_TRACE 1
-#endif
-
-/*
- * XFS config defines.
- */
-#define XFS_BIG_BLKNOS 1
-#define XFS_BIG_INUMS 0
-
-#undef XFS_STATS_OFF
-
-#endif /* __XFS_CONFIG_H__ */
diff --git a/sys/gnu/fs/xfs/FreeBSD/xfs_cred.h b/sys/gnu/fs/xfs/FreeBSD/xfs_cred.h
deleted file mode 100644
index bc59977..0000000
--- a/sys/gnu/fs/xfs/FreeBSD/xfs_cred.h
+++ /dev/null
@@ -1,46 +0,0 @@
-/*
- * Copyright (c) 2000-2002 Silicon Graphics, Inc. All Rights Reserved.
- *
- * This program 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.
- *
- * This program is distributed in the hope that it would be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
- *
- * Further, this software is distributed without any warranty that it is
- * free of the rightful claim of any third person regarding infringement
- * or the like. Any license provided herein, whether implied or
- * otherwise, applies only to this software file. Patent licenses, if
- * any, provided herein do not apply to combinations of this program with
- * other software, or any other product whatsoever.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write the Free Software Foundation, Inc., 59
- * Temple Place - Suite 330, Boston MA 02111-1307, USA.
- *
- * Contact information: Silicon Graphics, Inc., 1600 Amphitheatre Pkwy,
- * Mountain View, CA 94043, or:
- *
- * http://www.sgi.com
- *
- * For further information regarding this notice, see:
- *
- * http://oss.sgi.com/projects/GenInfo/SGIGPLNoticeExplan/
- */
-#ifndef __XFS_CRED_H__
-#define __XFS_CRED_H__
-
-#include <sys/ucred.h>
-/*
- * struct cred is struct ucred on FreeBSD
- */
-typedef struct ucred cred_t;
-
-#define cred ucred
-
-#define capable(cap) (1)
-#define capable_cred(cr, cap) (1)
-
-#endif /* __XFS_CRED_H__ */
diff --git a/sys/gnu/fs/xfs/FreeBSD/xfs_dmistubs.c b/sys/gnu/fs/xfs/FreeBSD/xfs_dmistubs.c
deleted file mode 100644
index 8f0eda1..0000000
--- a/sys/gnu/fs/xfs/FreeBSD/xfs_dmistubs.c
+++ /dev/null
@@ -1,144 +0,0 @@
-/*
- * Copyright (c) 2000 Silicon Graphics, Inc. All Rights Reserved.
- *
- * This program 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.
- *
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
- *
- * Further, this software is distributed without any warranty that it is
- * free of the rightful claim of any third person regarding infringement
- * or the like. Any license provided herein, whether implied or
- * otherwise, applies only to this software file. Patent licenses, if
- * any, provided herein do not apply to combinations of this program with
- * other software, or any other product whatsoever.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write the Free Software Foundation, Inc., 59
- * Temple Place - Suite 330, Boston MA 02111-1307, USA.
- *
- * Contact information: Silicon Graphics, Inc., 1600 Amphitheatre Pkwy,
- * Mountain View, CA 94043, or:
- *
- * http://www.sgi.com
- *
- * For further information regarding this notice, see:
- *
- * http://oss.sgi.com/projects/GenInfo/SGIGPLNoticeExplan/
- */
-
-#include "xfs.h"
-
-#include "xfs_types.h"
-#include "xfs_inum.h"
-#include "xfs_log.h"
-#include "xfs_trans.h"
-#include "xfs_sb.h"
-#include "xfs_ag.h"
-#include "xfs_dir.h"
-#include "xfs_dir2.h"
-#include "xfs_dmapi.h"
-#include "xfs_mount.h"
-
-static int nopkg(void);
-
-static __inline int
-nopkg()
-{
- return (ENOSYS);
-}
-
-int dmapi_init(void);
-int
-dmapi_init (void)
-{
- return (0);
-}
-
-void dmapi_uninit(void);
-void
-dmapi_uninit (void)
-{
-}
-
-int dm_data_event(void);
-int
-dm_data_event (void)
-{
- return nopkg();
-}
-
-int dm_namesp_event(void);
-int
-dm_namesp_event (void)
-{
- return nopkg();
-}
-
-/* The following stubs are for routines needed for the X/Open
- * version of DMAPI.
- */
-int xfs_dm_mount(xfs_vfs_t *, xfs_vnode_t *, char *, char *);
-int
-xfs_dm_mount(
- xfs_vfs_t *vfsp,
- xfs_vnode_t *mvp,
- char *dir_name,
- char *fsname)
-{
- return nopkg();
-}
-
-int
-dm_send_destroy_event(bhv_desc_t *bdp, dm_right_t vp_right);
-int
-dm_send_destroy_event(bhv_desc_t *bdp, dm_right_t vp_right)
-{
- return nopkg();
-}
-
-int
-dm_send_mount_event(xfs_vfs_t *vfsp, dm_right_t vfsp_right, bhv_desc_t *bdp,
- dm_right_t vp_right, bhv_desc_t *rootbdp, dm_right_t rootvp_right,
- char *name1, char *name2);
-int
-dm_send_mount_event(xfs_vfs_t *vfsp, dm_right_t vfsp_right, bhv_desc_t *bdp,
- dm_right_t vp_right, bhv_desc_t *rootbdp, dm_right_t rootvp_right,
- char *name1, char *name2)
-{
- return nopkg();
-}
-
-
-int
-dm_send_namesp_event(dm_eventtype_t event, bhv_desc_t *bdp1,
- dm_right_t vp1_right, bhv_desc_t *bdp2, dm_right_t vp2_right,
- char *name1, char *name2, mode_t mode, int retcode, int flags);
-int
-dm_send_namesp_event(dm_eventtype_t event, bhv_desc_t *bdp1,
- dm_right_t vp1_right, bhv_desc_t *bdp2, dm_right_t vp2_right,
- char *name1, char *name2, mode_t mode, int retcode, int flags)
-{
- return nopkg();
-}
-
-
-void
-dm_send_unmount_event(xfs_vfs_t *vfsp, xfs_vnode_t *vp, dm_right_t vfsp_right,
- mode_t mode, int retcode, int flags);
-void
-dm_send_unmount_event(xfs_vfs_t *vfsp, xfs_vnode_t *vp, dm_right_t vfsp_right,
- mode_t mode, int retcode, int flags)
-{
-}
-
-
-int
-dm_vp_to_handle (xfs_vnode_t *vp, xfs_handle_t *handlep);
-int
-dm_vp_to_handle (xfs_vnode_t *vp, xfs_handle_t *handlep)
-{
- return nopkg();
-}
diff --git a/sys/gnu/fs/xfs/FreeBSD/xfs_freebsd.h b/sys/gnu/fs/xfs/FreeBSD/xfs_freebsd.h
deleted file mode 100644
index cc1d8df..0000000
--- a/sys/gnu/fs/xfs/FreeBSD/xfs_freebsd.h
+++ /dev/null
@@ -1,350 +0,0 @@
-/*
- * Copyright (c) 2000-2003 Silicon Graphics, Inc. All Rights Reserved.
- *
- * This program 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.
- *
- * This program is distributed in the hope that it would be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
- *
- * Further, this software is distributed without any warranty that it is
- * free of the rightful claim of any third person regarding infringement
- * or the like. Any license provided herein, whether implied or
- * otherwise, applies only to this software file. Patent licenses, if
- * any, provided herein do not apply to combinations of this program with
- * other software, or any other product whatsoever.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write the Free Software Foundation, Inc., 59
- * Temple Place - Suite 330, Boston MA 02111-1307, USA.
- *
- * Contact information: Silicon Graphics, Inc., 1600 Amphitheatre Pkwy,
- * Mountain View, CA 94043, or:
- *
- * http://www.sgi.com
- *
- * For further information regarding this notice, see:
- *
- * http://oss.sgi.com/projects/GenInfo/SGIGPLNoticeExplan/
- */
-#ifndef __XFS_FREEBSD__
-#define __XFS_FREEBSD__
-
-#include <xfs_config.h>
-#include <xfs_compat.h>
-
-/*
- * Some types are conditional depending on the target system.
- * XFS_BIG_BLKNOS needs block layer disk addresses to be 64 bits.
- * XFS_BIG_INUMS needs the VFS inode number to be 64 bits, as well
- * as requiring XFS_BIG_BLKNOS to be set.
- */
-#define XFS_BIG_BLKNOS 1
-#define XFS_BIG_INUMS 0
-
-#include <xfs_types.h>
-#include <xfs_arch.h>
-
-#include <support/atomic.h>
-#include <support/kmem.h>
-#include <support/mrlock.h>
-#include <support/spin.h>
-#include <support/sv.h>
-#include <support/ktrace.h>
-#include <support/mutex.h>
-#include <support/rwsem.h>
-#include <support/rwlock.h>
-#include <support/sema.h>
-#include <support/debug.h>
-#include <support/move.h>
-#include <support/uuid.h>
-#include <support/time.h>
-
-#include <xfs_behavior.h>
-#include <xfs_cred.h>
-#include <xfs_vfs.h>
-#include <xfs_vnode.h>
-#include <xfs_stats.h>
-#include <xfs_sysctl.h>
-#include <xfs_iops.h>
-#include <xfs_super.h>
-#include <xfs_fs_subr.h>
-#include <xfs_buf.h>
-#include <xfs_frw.h>
-
-/*
- * Feature macros (disable/enable)
- */
-#undef HAVE_REFCACHE /* Do not use refcache. */
-#undef HAVE_SENDFILE /* sendfile(2) is available in FreeBSD. */
-
-#ifndef EVMS_MAJOR
-#define EVMS_MAJOR 117
-#endif
-
-#define restricted_chown xfs_params.restrict_chown.val
-#define irix_sgid_inherit xfs_params.sgid_inherit.val
-#define irix_symlink_mode xfs_params.symlink_mode.val
-#define xfs_panic_mask xfs_params.panic_mask.val
-#define xfs_error_level xfs_params.error_level.val
-#define xfs_syncd_centisecs xfs_params.syncd_timer.val
-#define xfs_probe_dmapi xfs_params.probe_dmapi.val
-#define xfs_probe_ioops xfs_params.probe_ioops.val
-#define xfs_probe_quota xfs_params.probe_quota.val
-#define xfs_stats_clear xfs_params.stats_clear.val
-#define xfs_inherit_sync xfs_params.inherit_sync.val
-#define xfs_inherit_nodump xfs_params.inherit_nodump.val
-#define xfs_inherit_noatime xfs_params.inherit_noatim.val
-#define xfs_buf_timer_centisecs xfs_params.xfs_buf_timer.val
-#define xfs_buf_age_centisecs xfs_params.xfs_buf_age.val
-#define xfs_inherit_nosymlinks xfs_params.inherit_nosym.val
-#define xfs_rotorstep xfs_params.rotorstep.val
-
-#define current_cpu() smp_processor_id()
-#define current_pid() (curthread->td_proc->p_pid)
-
-#define NBPP PAGE_SIZE
-#define DPPSHFT (PAGE_SHIFT - 9)
-#define NDPP (1 << (PAGE_SHIFT - 9))
-#define dtop(DD) (((DD) + NDPP - 1) >> DPPSHFT)
-#define dtopt(DD) ((DD) >> DPPSHFT)
-#define dpoff(DD) ((DD) & (NDPP-1))
-
-#define NBBY 8 /* number of bits per byte */
-#define NBPC PAGE_SIZE /* Number of bytes per click */
-#define BPCSHIFT PAGE_SHIFT /* LOG2(NBPC) if exact */
-
-/* number of BB's per block device block */
-#define BLKDEV_BB BTOBB(BLKDEV_IOSIZE)
-
-/* bytes to clicks */
-#define btoct(x) ((__psunsigned_t)(x)>>BPCSHIFT)
-#define btoc64(x) (((__uint64_t)(x)+(NBPC-1))>>BPCSHIFT)
-#define btoct64(x) ((__uint64_t)(x)>>BPCSHIFT)
-#define io_btoc(x) (((__psunsigned_t)(x)+(IO_NBPC-1))>>IO_BPCSHIFT)
-#define io_btoct(x) ((__psunsigned_t)(x)>>IO_BPCSHIFT)
-
-/* off_t bytes to clicks */
-#define offtoc(x) (((__uint64_t)(x)+(NBPC-1))>>BPCSHIFT)
-#define offtoct(x) ((xfs_off_t)(x)>>BPCSHIFT)
-
-/* clicks to off_t bytes */
-#define ctooff(x) ((xfs_off_t)(x)<<BPCSHIFT)
-
-/* clicks to bytes */
-#define btoct(x) ((__psunsigned_t)(x)>>BPCSHIFT)
-#define ctob64(x) ((__uint64_t)(x)<<BPCSHIFT)
-#define io_ctob(x) ((__psunsigned_t)(x)<<IO_BPCSHIFT)
-
-#ifndef CELL_CAPABLE
-#define FSC_NOTIFY_NAME_CHANGED(vp)
-#endif
-
-#ifndef ENOATTR
-#define ENOATTR ENODATA /* Attribute not found */
-#endif
-
-/* Note: EWRONGFS never visible outside the kernel */
-#define EWRONGFS EINVAL /* Mount with wrong filesystem type */
-
-/*
- * XXX EFSCORRUPTED needs a real value in errno.h. asm-i386/errno.h won't
- * return codes out of its known range in errno.
- * XXX Also note: needs to be < 1000 and fairly unique on Linux (mustn't
- * conflict with any code we use already or any code a driver may use)
- * XXX Some options (currently we do #2):
- * 1/ New error code ["Filesystem is corrupted", _after_ glibc updated]
- * 2/ 990 ["Unknown error 990"]
- * 3/ EUCLEAN ["Structure needs cleaning"]
- * 4/ Convert EFSCORRUPTED to EIO [just prior to return into userspace]
- */
-#define EFSCORRUPTED 990 /* Filesystem is corrupted */
-
-#define SYNCHRONIZE() __compiler_membar()
-#define __return_address __builtin_return_address(0)
-
-/*
- * IRIX (BSD) quotactl makes use of separate commands for user/group,
- * whereas on Linux the syscall encodes this information into the cmd
- * field (see the QCMD macro in quota.h). These macros help keep the
- * code portable - they are not visible from the syscall interface.
- */
-#define Q_XSETGQLIM XQM_CMD(0x8) /* set groups disk limits */
-#define Q_XGETGQUOTA XQM_CMD(0x9) /* get groups disk limits */
-
-/* IRIX uses a dynamic sizing algorithm (ndquot = 200 + numprocs*2) */
-/* we may well need to fine-tune this if it ever becomes an issue. */
-#define DQUOT_MAX_HEURISTIC 1024 /* NR_DQUOTS */
-#define ndquot DQUOT_MAX_HEURISTIC
-
-/* IRIX uses the current size of the name cache to guess a good value */
-/* - this isn't the same but is a good enough starting point for now. */
-#define DQUOT_HASH_HEURISTIC files_stat.nr_files
-
-/* IRIX inodes maintain the project ID also, zero this field on Linux */
-#define DEFAULT_PROJID 0
-#define dfltprid DEFAULT_PROJID
-
-#define FINVIS 0x0102 /* don't update timestamps - XFS */
-
-#define howmany(x, y) (((x)+((y)-1))/(y))
-#define roundup(x, y) ((((x)+((y)-1))/(y))*(y))
-
-#define xfs_sort(a,n,s,fn) qsort(a,n,s,fn)
-
-
-static inline int xfs_itruncate_data(void *ip, xfs_off_t off) {
- printf ("xfs_itruncate_data NI\n");
- return 0;
-}
-
-/*
- * Juggle IRIX device numbers - still used in ondisk structures
- */
-#define XFS_DEV_BITSMAJOR 14
-#define XFS_DEV_BITSMINOR 18
-#define XFS_DEV_MAXMAJ 0x1ff
-#define XFS_DEV_MAXMIN 0x3ffff
-#define XFS_DEV_MAJOR(dev) ((int)(((unsigned)(dev)>>XFS_DEV_BITSMINOR) \
- & XFS_DEV_MAXMAJ))
-#define XFS_DEV_MINOR(dev) ((int)((dev)&XFS_DEV_MAXMIN))
-#define XFS_MKDEV(major,minor) ((xfs_dev_t)(((major)<<XFS_DEV_BITSMINOR) \
- | (minor&XFS_DEV_MAXMIN)))
-
-#define XFS_DEV_TO_KDEVT(dev) mk_kdev(XFS_DEV_MAJOR(dev),XFS_DEV_MINOR(dev))
-
-
-/* Produce a kernel stack trace */
-
-static inline void xfs_stack_trace(void)
-{
- kdb_backtrace();
-}
-
-#define xfs_statvfs_fsid(statp, mp) \
- ({ \
- (statp)->f_fsid.val[0] = /*dev2udev(mp->m_dev) */ 1; \
- (statp)->f_fsid.val[1] = 0; \
- })
-
-
-/* Move the kernel do_div definition off to one side */
-
-#if defined __i386__
-/* For ia32 we need to pull some tricks to get past various versions
- * of the compiler which do not like us using do_div in the middle
- * of large functions.
- */
-static inline __u32 xfs_do_div(void *a, __u32 b, int n)
-{
- __u32 mod;
-
- switch (n) {
- case 4:
- mod = *(__u32 *)a % b;
- *(__u32 *)a = *(__u32 *)a / b;
- return mod;
- case 8:
- {
- unsigned long __upper, __low, __high, __mod;
- __u64 c = *(__u64 *)a;
- __upper = __high = c >> 32;
- __low = c;
- if (__high) {
- __upper = __high % (b);
- __high = __high / (b);
- }
- asm("divl %2":"=a" (__low), "=d" (__mod):"rm" (b), "0" (__low), "1" (__upper));
- asm("":"=A" (c):"a" (__low),"d" (__high));
- *(__u64 *)a = c;
- return __mod;
- }
- }
-
- /* NOTREACHED */
- return 0;
-}
-
-/* Side effect free 64 bit mod operation */
-static inline __u32 xfs_do_mod(void *a, __u32 b, int n)
-{
- switch (n) {
- case 4:
- return *(__u32 *)a % b;
- case 8:
- {
- unsigned long __upper, __low, __high, __mod;
- __u64 c = *(__u64 *)a;
- __upper = __high = c >> 32;
- __low = c;
- if (__high) {
- __upper = __high % (b);
- __high = __high / (b);
- }
- asm("divl %2":"=a" (__low), "=d" (__mod):"rm" (b), "0" (__low), "1" (__upper));
- asm("":"=A" (c):"a" (__low),"d" (__high));
- return __mod;
- }
- }
-
- /* NOTREACHED */
- return 0;
-}
-#else
-
-#define do_div(n, base) ({\
- int __res; \
- __res = ((__u64)(n)) % (__u32)(base); \
- (n) = ((__u64)(n)) / (__u32)(base); \
- __res; })
-
-static inline __u32 xfs_do_div(void *a, __u32 b, int n)
-{
- __u32 mod;
-
- switch (n) {
- case 4:
- mod = *(__u32 *)a % b;
- *(__u32 *)a = *(__u32 *)a / b;
- return mod;
- case 8:
- mod = do_div(*(__u64 *)a, b);
- return mod;
- }
-
- /* NOTREACHED */
- return 0;
-}
-
-/* Side effect free 64 bit mod operation */
-static inline __u32 xfs_do_mod(void *a, __u32 b, int n)
-{
- switch (n) {
- case 4:
- return *(__u32 *)a % b;
- case 8:
- {
- __u64 c = *(__u64 *)a;
- return do_div(c, b);
- }
- }
-
- /* NOTREACHED */
- return 0;
-}
-#endif
-
-#undef do_div
-#define do_div(a, b) xfs_do_div(&(a), (b), sizeof(a))
-#define do_mod(a, b) xfs_do_mod(&(a), (b), sizeof(a))
-
-static inline __uint64_t roundup_64(__uint64_t x, __uint32_t y)
-{
- x += y - 1;
- do_div(x, y);
- return(x * y);
-}
-
-#endif /* __XFS_FREEBSD__ */
diff --git a/sys/gnu/fs/xfs/FreeBSD/xfs_freebsd_iget.c b/sys/gnu/fs/xfs/FreeBSD/xfs_freebsd_iget.c
deleted file mode 100644
index e4e1e8d..0000000
--- a/sys/gnu/fs/xfs/FreeBSD/xfs_freebsd_iget.c
+++ /dev/null
@@ -1,419 +0,0 @@
-/*
- * Copyright (c) 2000-2003 Silicon Graphics, Inc. All Rights Reserved.
- * Copyright (c) 2006 Russell Cattelan Digital Elves, Inc. All Rights Reserved.
- *
- * This program 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.
- *
- * This program is distributed in the hope that it would be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
- *
- * Further, this software is distributed without any warranty that it is
- * free of the rightful claim of any third person regarding infringement
- * or the like. Any license provided herein, whether implied or
- * otherwise, applies only to this software file. Patent licenses, if
- * any, provided herein do not apply to combinations of this program with
- * other software, or any other product whatsoever.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write the Free Software Foundation, Inc., 59
- * Temple Place - Suite 330, Boston MA 02111-1307, USA.
- *
- * Contact information: Silicon Graphics, Inc., 1600 Amphitheatre Pkwy,
- * Mountain View, CA 94043, or:
- *
- * http://www.sgi.com
- *
- * For further information regarding this notice, see:
- *
- * http://oss.sgi.com/projects/GenInfo/SGIGPLNoticeExplan/
- */
-
-#include "xfs.h"
-
-#include "xfs_types.h"
-#include "xfs_bit.h"
-#include "xfs_inum.h"
-#include "xfs_log.h"
-#include "xfs_trans.h"
-#include "xfs_sb.h"
-#include "xfs_ag.h"
-#include "xfs_dir.h"
-#include "xfs_dir2.h"
-#include "xfs_dmapi.h"
-#include "xfs_mount.h"
-#include "xfs_alloc_btree.h"
-#include "xfs_bmap_btree.h"
-#include "xfs_ialloc_btree.h"
-#include "xfs_attr_sf.h"
-#include "xfs_dir_sf.h"
-#include "xfs_dir2_sf.h"
-#include "xfs_dinode.h"
-#include "xfs_inode.h"
-#include "xfs_btree.h"
-#include "xfs_ialloc.h"
-#include "xfs_quota.h"
-#include "xfs_utils.h"
-#include "xfs_vnode.h"
-
-static int xfs_vn_allocate(xfs_mount_t *, xfs_inode_t *, struct xfs_vnode **);
-
-/*
- * Look up an inode by number in the given file system.
- * The inode is looked up in the hash table for the file system
- * represented by the mount point parameter mp. Each bucket of
- * the hash table is guarded by an individual semaphore.
- *
- * If the inode is found in the hash table, its corresponding vnode
- * is obtained with a call to vn_get(). This call takes care of
- * coordination with the reclamation of the inode and vnode. Note
- * that the vmap structure is filled in while holding the hash lock.
- * This gives us the state of the inode/vnode when we found it and
- * is used for coordination in vn_get().
- *
- * If it is not in core, read it in from the file system's device and
- * add the inode into the hash table.
- *
- * The inode is locked according to the value of the lock_flags parameter.
- * This flag parameter indicates how and if the inode's IO lock and inode lock
- * should be taken.
- *
- * mp -- the mount point structure for the current file system. It points
- * to the inode hash table.
- * tp -- a pointer to the current transaction if there is one. This is
- * simply passed through to the xfs_iread() call.
- * ino -- the number of the inode desired. This is the unique identifier
- * within the file system for the inode being requested.
- * lock_flags -- flags indicating how to lock the inode. See the comment
- * for xfs_ilock() for a list of valid values.
- * bno -- the block number starting the buffer containing the inode,
- * if known (as by bulkstat), else 0.
- */
-int
-xfs_iget(
- xfs_mount_t *mp,
- xfs_trans_t *tp,
- xfs_ino_t ino,
- uint flags,
- uint lock_flags,
- xfs_inode_t **ipp,
- xfs_daddr_t bno)
-{
- xfs_ihash_t *ih;
- xfs_inode_t *ip;
- xfs_inode_t *iq;
- xfs_vnode_t *vp;
- ulong version;
- int error;
- /* REFERENCED */
- int newnode;
- xfs_chash_t *ch;
- xfs_chashlist_t *chl, *chlnew;
- vmap_t vmap;
- SPLDECL(s);
-
- XFS_STATS_INC(xs_ig_attempts);
-
- ih = XFS_IHASH(mp, ino);
-
-again:
- read_lock(&ih->ih_lock);
-
- for (ip = ih->ih_next; ip != NULL; ip = ip->i_next) {
- if (ip->i_ino == ino) {
- vp = XFS_ITOV(ip);
- VMAP(vp, vmap);
- /*
- * Inode cache hit: if ip is not at the front of
- * its hash chain, move it there now.
- * Do this with the lock held for update, but
- * do statistics after releasing the lock.
- */
- if (ip->i_prevp != &ih->ih_next
- && rwlock_trypromote(&ih->ih_lock)) {
-
- if ((iq = ip->i_next)) {
- iq->i_prevp = ip->i_prevp;
- }
- *ip->i_prevp = iq;
- iq = ih->ih_next;
- iq->i_prevp = &ip->i_next;
- ip->i_next = iq;
- ip->i_prevp = &ih->ih_next;
- ih->ih_next = ip;
- write_unlock(&ih->ih_lock);
- } else {
- read_unlock(&ih->ih_lock);
- }
-
- XFS_STATS_INC(xs_ig_found);
-
- /*
- * Get a reference to the vnode/inode.
- * vn_get() takes care of coordination with
- * the file system inode release and reclaim
- * functions. If it returns NULL, the inode
- * has been reclaimed so just start the search
- * over again. We probably won't find it,
- * but we could be racing with another cpu
- * looking for the same inode so we have to at
- * least look.
- */
- if (!(vp = vn_get(vp, &vmap))) {
- XFS_STATS_INC(xs_ig_frecycle);
- goto again;
- }
-
- if (lock_flags != 0) {
- ip->i_flags &= ~XFS_IRECLAIM;
- xfs_ilock(ip, lock_flags);
- }
-
- newnode = (ip->i_d.di_mode == 0);
- if (newnode) {
- xfs_iocore_inode_reinit(ip);
- }
- ip->i_flags &= ~XFS_ISTALE;
-
- vn_trace_exit(vp, "xfs_iget.found",
- (inst_t *)__return_address);
- goto return_ip;
- }
- }
-
- /*
- * Inode cache miss: save the hash chain version stamp and unlock
- * the chain, so we don't deadlock in vn_alloc.
- */
- XFS_STATS_INC(xs_ig_missed);
-
- version = ih->ih_version;
-
- read_unlock(&ih->ih_lock);
-
- /*
- * Read the disk inode attributes into a new inode structure and get
- * a new vnode for it. This should also initialize i_ino and i_mount.
- */
- error = xfs_iread(mp, tp, ino, &ip, bno);
- if (error) {
- return error;
- }
-
- error = xfs_vn_allocate(mp, ip, &vp);
- if (error) {
- return error;
- }
- vn_trace_exit(vp, "xfs_iget.alloc", (inst_t *)__return_address);
-
- xfs_inode_lock_init(ip, vp);
- xfs_iocore_inode_init(ip);
-
- if (lock_flags != 0) {
- xfs_ilock(ip, lock_flags);
- }
-
- /*
- * Put ip on its hash chain, unless someone else hashed a duplicate
- * after we released the hash lock.
- */
- write_lock(&ih->ih_lock);
-
- if (ih->ih_version != version) {
- for (iq = ih->ih_next; iq != NULL; iq = iq->i_next) {
- if (iq->i_ino == ino) {
- write_unlock(&ih->ih_lock);
- xfs_idestroy(ip);
-
- XFS_STATS_INC(xs_ig_dup);
- goto again;
- }
- }
- }
-
- /*
- * These values _must_ be set before releasing ihlock!
- */
- ip->i_hash = ih;
- if ((iq = ih->ih_next)) {
- iq->i_prevp = &ip->i_next;
- }
- ip->i_next = iq;
- ip->i_prevp = &ih->ih_next;
- ih->ih_next = ip;
- ip->i_udquot = ip->i_gdquot = NULL;
- ih->ih_version++;
-
- write_unlock(&ih->ih_lock);
-
- /*
- * put ip on its cluster's hash chain
- */
- ASSERT(ip->i_chash == NULL && ip->i_cprev == NULL &&
- ip->i_cnext == NULL);
-
- chlnew = NULL;
- ch = XFS_CHASH(mp, ip->i_blkno);
- chlredo:
- s = mutex_spinlock(&ch->ch_lock);
- for (chl = ch->ch_list; chl != NULL; chl = chl->chl_next) {
- if (chl->chl_blkno == ip->i_blkno) {
-
- /* insert this inode into the doubly-linked list
- * where chl points */
- if ((iq = chl->chl_ip)) {
- ip->i_cprev = iq->i_cprev;
- iq->i_cprev->i_cnext = ip;
- iq->i_cprev = ip;
- ip->i_cnext = iq;
- } else {
- ip->i_cnext = ip;
- ip->i_cprev = ip;
- }
- chl->chl_ip = ip;
- ip->i_chash = chl;
- break;
- }
- }
-
- /* no hash list found for this block; add a new hash list */
- if (chl == NULL) {
- if (chlnew == NULL) {
- mutex_spinunlock(&ch->ch_lock, s);
- ASSERT(xfs_chashlist_zone != NULL);
- chlnew = (xfs_chashlist_t *)
- kmem_zone_alloc(xfs_chashlist_zone,
- KM_SLEEP);
- ASSERT(chlnew != NULL);
- goto chlredo;
- } else {
- ip->i_cnext = ip;
- ip->i_cprev = ip;
- ip->i_chash = chlnew;
- chlnew->chl_ip = ip;
- chlnew->chl_blkno = ip->i_blkno;
- chlnew->chl_next = ch->ch_list;
- ch->ch_list = chlnew;
- chlnew = NULL;
- }
- } else {
- if (chlnew != NULL) {
- kmem_zone_free(xfs_chashlist_zone, chlnew);
- }
- }
-
- mutex_spinunlock(&ch->ch_lock, s);
-
- /*
- * Link ip to its mount and thread it on the mount's inode list.
- */
- XFS_MOUNT_ILOCK(mp);
- if ((iq = mp->m_inodes)) {
- ASSERT(iq->i_mprev->i_mnext == iq);
- ip->i_mprev = iq->i_mprev;
- iq->i_mprev->i_mnext = ip;
- iq->i_mprev = ip;
- ip->i_mnext = iq;
- } else {
- ip->i_mnext = ip;
- ip->i_mprev = ip;
- }
- mp->m_inodes = ip;
-
- XFS_MOUNT_IUNLOCK(mp);
-
- newnode = 1;
-
- return_ip:
- ASSERT(ip->i_df.if_ext_max ==
- XFS_IFORK_DSIZE(ip) / sizeof(xfs_bmbt_rec_t));
-
- ASSERT(((ip->i_d.di_flags & XFS_DIFLAG_REALTIME) != 0) ==
- ((ip->i_iocore.io_flags & XFS_IOCORE_RT) != 0));
-
- *ipp = ip;
-
- /*
- * If we have a real type for an on-disk inode, we can set ops(&unlock)
- * now. If it's a new inode being created, xfs_ialloc will handle it.
- */
- XVFS_INIT_VNODE(XFS_MTOVFS(mp), vp, XFS_ITOBHV(ip), 1);
-
- return 0;
-}
-
-/*
- * Special iput for brand-new inodes that are still locked
- */
-void
-xfs_iput_new(xfs_inode_t *ip,
- uint lock_flags)
-{
- xfs_vnode_t *vp = XFS_ITOV(ip);
-
- vn_trace_entry(vp, "xfs_iput_new", (inst_t *)__return_address);
-
- printf("xfs_iput_new: ip %p\n",ip);
-
- if ((ip->i_d.di_mode == 0)) {
- ASSERT(!(ip->i_flags & XFS_IRECLAIMABLE));
- //vn_mark_bad(vp);
- printf("xfs_iput_new: ip %p di_mode == 0\n",ip);
- /* mabe call vgone here? RMC */
- }
- if (lock_flags)
- xfs_iunlock(ip, lock_flags);
-
- ASSERT_VOP_LOCKED(vp->v_vnode, "xfs_iput_new");
- vput(vp->v_vnode);
-}
-
-extern struct vop_vector xfs_vnops;
-
-static int
-xfs_vn_allocate(xfs_mount_t *mp, xfs_inode_t *ip, struct xfs_vnode **vpp)
-{
- struct vnode *vp;
- struct xfs_vnode *vdata;
- int error;
-
- /* Use zone allocator here? */
- vdata = kmem_zalloc(sizeof(*vdata), KM_SLEEP);
-
- error = getnewvnode("xfs", XVFSTOMNT(XFS_MTOVFS(mp)),
- &xfs_vnops, &vp);
- if (error) {
- kmem_free(vdata, sizeof(*vdata));
- return (error);
- }
-
- vn_lock(vp, LK_EXCLUSIVE | LK_RETRY);
- VN_LOCK_AREC(vp);
- error = insmntque(vp, XVFSTOMNT(XFS_MTOVFS(mp)));
- if (error != 0) {
- kmem_free(vdata, sizeof(*vdata));
- return (error);
- }
-
- vp->v_data = (void *)vdata;
- vdata->v_number= 0;
- vdata->v_inode = ip;
- vdata->v_vfsp = XFS_MTOVFS(mp);
- vdata->v_vnode = vp;
-
- vn_bhv_head_init(VN_BHV_HEAD(vdata), "vnode");
-
-
-#ifdef CONFIG_XFS_VNODE_TRACING
- vp->v_trace = ktrace_alloc(VNODE_TRACE_SIZE, KM_SLEEP);
-#endif /* CONFIG_XFS_VNODE_TRACING */
-
- vn_trace_exit(vp, "vn_initialize", (inst_t *)__return_address);
-
- if (error == 0)
- *vpp = vdata;
-
- return (error);
-}
diff --git a/sys/gnu/fs/xfs/FreeBSD/xfs_frw.c b/sys/gnu/fs/xfs/FreeBSD/xfs_frw.c
deleted file mode 100644
index 557ef1a..0000000
--- a/sys/gnu/fs/xfs/FreeBSD/xfs_frw.c
+++ /dev/null
@@ -1,891 +0,0 @@
-/*
- * Copyright (c) 2000-2003,2005 Silicon Graphics, Inc.
- * All Rights Reserved.
- *
- * 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.
- *
- * This program is distributed in the hope that it would 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 the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- */
-#include "xfs.h"
-#include "xfs_fs.h"
-#include "xfs_bit.h"
-#include "xfs_log.h"
-#include "xfs_inum.h"
-#include "xfs_trans.h"
-#include "xfs_sb.h"
-#include "xfs_ag.h"
-#include "xfs_dir.h"
-#include "xfs_dir2.h"
-#include "xfs_alloc.h"
-#include "xfs_dmapi.h"
-#include "xfs_quota.h"
-#include "xfs_mount.h"
-#include "xfs_bmap_btree.h"
-#include "xfs_alloc_btree.h"
-#include "xfs_ialloc_btree.h"
-#include "xfs_dir_sf.h"
-#include "xfs_dir2_sf.h"
-#include "xfs_attr_sf.h"
-#include "xfs_dinode.h"
-#include "xfs_inode.h"
-#include "xfs_bmap.h"
-#include "xfs_btree.h"
-#include "xfs_ialloc.h"
-#include "xfs_rtalloc.h"
-#include "xfs_error.h"
-#include "xfs_itable.h"
-#include "xfs_rw.h"
-#include "xfs_acl.h"
-#include "xfs_cap.h"
-#include "xfs_mac.h"
-#include "xfs_attr.h"
-#include "xfs_inode_item.h"
-#include "xfs_buf_item.h"
-#include "xfs_utils.h"
-#include "xfs_iomap.h"
-
-#if defined(XFS_RW_TRACE)
-void
-xfs_rw_enter_trace(
- int tag,
- xfs_iocore_t *io,
- const char *buf,
- size_t size,
- loff_t offset,
- int ioflags)
-{
- xfs_inode_t *ip = XFS_IO_INODE(io);
-
- if (ip->i_rwtrace == NULL)
- return;
- ktrace_enter(ip->i_rwtrace,
- (void *)(unsigned long)tag,
- (void *)ip,
- (void *)((unsigned long)((ip->i_d.di_size >> 32) & 0xffffffff)),
- (void *)((unsigned long)(ip->i_d.di_size & 0xffffffff)),
- (void *)(__psint_t)buf,
- (void *)((unsigned long)size),
- (void *)((unsigned long)((offset >> 32) & 0xffffffff)),
- (void *)((unsigned long)(offset & 0xffffffff)),
- (void *)((unsigned long)ioflags),
- (void *)((unsigned long)((io->io_new_size >> 32) & 0xffffffff)),
- (void *)((unsigned long)(io->io_new_size & 0xffffffff)),
- (void *)NULL,
- (void *)NULL,
- (void *)NULL,
- (void *)NULL,
- (void *)NULL);
-}
-
-void
-xfs_inval_cached_trace(
- xfs_iocore_t *io,
- xfs_off_t offset,
- xfs_off_t len,
- xfs_off_t first,
- xfs_off_t last)
-{
- xfs_inode_t *ip = XFS_IO_INODE(io);
-
- if (ip->i_rwtrace == NULL)
- return;
- ktrace_enter(ip->i_rwtrace,
- (void *)(__psint_t)XFS_INVAL_CACHED,
- (void *)ip,
- (void *)((unsigned long)((offset >> 32) & 0xffffffff)),
- (void *)((unsigned long)(offset & 0xffffffff)),
- (void *)((unsigned long)((len >> 32) & 0xffffffff)),
- (void *)((unsigned long)(len & 0xffffffff)),
- (void *)((unsigned long)((first >> 32) & 0xffffffff)),
- (void *)((unsigned long)(first & 0xffffffff)),
- (void *)((unsigned long)((last >> 32) & 0xffffffff)),
- (void *)((unsigned long)(last & 0xffffffff)),
- (void *)NULL,
- (void *)NULL,
- (void *)NULL,
- (void *)NULL,
- (void *)NULL,
- (void *)NULL);
-}
-#endif
-
-/*
- * xfs_iozero
- *
- * xfs_iozero clears the specified range of buffer supplied,
- * and marks all the affected blocks as valid and modified. If
- * an affected block is not allocated, it will be allocated. If
- * an affected block is not completely overwritten, and is not
- * valid before the operation, it will be read from disk before
- * being partially zeroed.
- */
-STATIC int
-xfs_iozero(
- xfs_vnode_t *vp, /* vnode */
- xfs_off_t pos, /* offset in file */
- size_t count, /* size of data to zero */
- xfs_off_t end_size) /* max file size to set */
-{
- int status;
- status = 0; /* XXXKAN: */
-#ifdef XXXKAN
- unsigned bytes;
- struct page *page;
- struct address_space *mapping;
- char *kaddr;
-
- mapping = ip->i_mapping;
- do {
- unsigned long index, offset;
-
- offset = (pos & (PAGE_CACHE_SIZE -1)); /* Within page */
- index = pos >> PAGE_CACHE_SHIFT;
- bytes = PAGE_CACHE_SIZE - offset;
- if (bytes > count)
- bytes = count;
-
- status = -ENOMEM;
- page = grab_cache_page(mapping, index);
- if (!page)
- break;
-
- kaddr = kmap(page);
- status = mapping->a_ops->prepare_write(NULL, page, offset,
- offset + bytes);
- if (status) {
- goto unlock;
- }
-
- memset((void *) (kaddr + offset), 0, bytes);
- flush_dcache_page(page);
- status = mapping->a_ops->commit_write(NULL, page, offset,
- offset + bytes);
- if (!status) {
- pos += bytes;
- count -= bytes;
- if (pos > i_size_read(ip))
- i_size_write(ip, pos < end_size ? pos : end_size);
- }
-
-unlock:
- kunmap(page);
- unlock_page(page);
- page_cache_release(page);
- if (status)
- break;
- } while (count);
-#endif
- return (-status);
-}
-
-ssize_t /* bytes read, or (-) error */
-xfs_read(
- bhv_desc_t *bdp,
- uio_t *uio,
- int ioflags,
- cred_t *credp)
-{
- ssize_t ret, size;
- xfs_fsize_t n;
- xfs_inode_t *ip;
- xfs_mount_t *mp;
-
- ip = XFS_BHVTOI(bdp);
- mp = ip->i_mount;
-
- XFS_STATS_INC(xs_read_calls);
-
- if (unlikely(ioflags & IO_ISDIRECT)) {
- if (((__psint_t)buf & BBMASK) ||
- (uio->uio_offset & mp->m_blockmask) ||
- (uio->uio_resid & mp->m_blockmask)) {
- if (uio->uio_offset >= ip->i_d.di_size) {
- return (0);
- }
- return EINVAL;
- }
- }
-
- if (uio->uio_resid == 0)
- return 0;
- n = XFS_MAXIOFFSET(mp) - uio->uio_offset;
- if (n <= 0)
- return EFBIG;
-
- size = (n < uio->uio_resid)? n : uio->uio_resid;
-
- if (XFS_FORCED_SHUTDOWN(mp)) {
- return EIO;
- }
-
- xfs_ilock(ip, XFS_IOLOCK_SHARED);
-
-#ifdef XXX
- if (DM_EVENT_ENABLED(BHV_TO_VNODE(bdp)->v_vfsp, ip, DM_EVENT_READ) &&
- !(ioflags & IO_INVIS)) {
- int error;
- vrwlock_t locktype = VRWLOCK_READ;
- int dmflags = FILP_DELAY_FLAG(file) | DM_SEM_FLAG_RD(ioflags);
-
- error = XFS_SEND_DATA(mp, DM_EVENT_READ, BHV_TO_VNODE(bdp),
- uio->uio_offset, size, dmflags, &locktype);
- if (error) {
- xfs_iunlock(ip, XFS_IOLOCK_SHARED);
- return (error);
- }
- }
-#endif
-
- ret = xfs_read_file(mp, ip, uio, ioflags);
-
- xfs_iunlock(ip, XFS_IOLOCK_SHARED);
-
- XFS_STATS_ADD(xs_read_bytes, ret);
-
- if (likely((ioflags & IO_INVIS) == 0)) {
- xfs_ichgtime(ip, XFS_ICHGTIME_ACC);
- }
-
- return ret;
-}
-
-/*
- * This routine is called to handle zeroing any space in the last
- * block of the file that is beyond the EOF. We do this since the
- * size is being increased without writing anything to that block
- * and we don't want anyone to read the garbage on the disk.
- */
-STATIC int /* error (positive) */
-xfs_zero_last_block(
- xfs_vnode_t *vp,
- xfs_iocore_t *io,
- xfs_fsize_t isize,
- xfs_fsize_t end_size)
-{
- xfs_fileoff_t last_fsb;
- xfs_mount_t *mp;
- int nimaps;
- int zero_offset;
- int zero_len;
- int error = 0;
- xfs_bmbt_irec_t imap;
- xfs_off_t loff;
-
- ASSERT(ismrlocked(io->io_lock, MR_UPDATE) != 0);
-
- mp = io->io_mount;
-
- zero_offset = XFS_B_FSB_OFFSET(mp, isize);
- if (zero_offset == 0) {
- /*
- * There are no extra bytes in the last block on disk to
- * zero, so return.
- */
- return 0;
- }
-
- last_fsb = XFS_B_TO_FSBT(mp, isize);
- nimaps = 1;
- error = XFS_BMAPI(mp, NULL, io, last_fsb, 1, 0, NULL, 0, &imap,
- &nimaps, NULL, NULL);
- if (error) {
- return error;
- }
- ASSERT(nimaps > 0);
- /*
- * If the block underlying isize is just a hole, then there
- * is nothing to zero.
- */
- if (imap.br_startblock == HOLESTARTBLOCK) {
- return 0;
- }
- /*
- * Zero the part of the last block beyond the EOF, and write it
- * out sync. We need to drop the ilock while we do this so we
- * don't deadlock when the buffer cache calls back to us.
- */
- XFS_IUNLOCK(mp, io, XFS_ILOCK_EXCL| XFS_EXTSIZE_RD);
- loff = XFS_FSB_TO_B(mp, last_fsb);
-
- zero_len = mp->m_sb.sb_blocksize - zero_offset;
-
- error = xfs_iozero(vp, loff + zero_offset, zero_len, end_size);
-
- XFS_ILOCK(mp, io, XFS_ILOCK_EXCL|XFS_EXTSIZE_RD);
- ASSERT(error >= 0);
- return error;
-}
-
-/*
- * Zero any on disk space between the current EOF and the new,
- * larger EOF. This handles the normal case of zeroing the remainder
- * of the last block in the file and the unusual case of zeroing blocks
- * out beyond the size of the file. This second case only happens
- * with fixed size extents and when the system crashes before the inode
- * size was updated but after blocks were allocated. If fill is set,
- * then any holes in the range are filled and zeroed. If not, the holes
- * are left alone as holes.
- */
-
-int /* error (positive) */
-xfs_zero_eof(
- xfs_vnode_t *vp,
- xfs_iocore_t *io,
- xfs_off_t offset, /* starting I/O offset */
- xfs_fsize_t isize, /* current inode size */
- xfs_fsize_t end_size) /* terminal inode size */
-{
- xfs_fileoff_t start_zero_fsb;
- xfs_fileoff_t end_zero_fsb;
- xfs_fileoff_t zero_count_fsb;
- xfs_fileoff_t last_fsb;
- xfs_extlen_t buf_len_fsb;
- xfs_mount_t *mp;
- int nimaps;
- int error = 0;
- xfs_bmbt_irec_t imap;
-
- ASSERT(ismrlocked(io->io_lock, MR_UPDATE));
- ASSERT(ismrlocked(io->io_iolock, MR_UPDATE));
- ASSERT(offset > isize);
-
- mp = io->io_mount;
-
- /*
- * First handle zeroing the block on which isize resides.
- * We only zero a part of that block so it is handled specially.
- */
- error = xfs_zero_last_block(vp, io, isize, end_size);
- if (error) {
- ASSERT(ismrlocked(io->io_lock, MR_UPDATE));
- ASSERT(ismrlocked(io->io_iolock, MR_UPDATE));
- return error;
- }
-
- /*
- * Calculate the range between the new size and the old
- * where blocks needing to be zeroed may exist. To get the
- * block where the last byte in the file currently resides,
- * we need to subtract one from the size and truncate back
- * to a block boundary. We subtract 1 in case the size is
- * exactly on a block boundary.
- */
- last_fsb = isize ? XFS_B_TO_FSBT(mp, isize - 1) : (xfs_fileoff_t)-1;
- start_zero_fsb = XFS_B_TO_FSB(mp, (xfs_ufsize_t)isize);
- end_zero_fsb = XFS_B_TO_FSBT(mp, offset - 1);
- ASSERT((xfs_sfiloff_t)last_fsb < (xfs_sfiloff_t)start_zero_fsb);
- if (last_fsb == end_zero_fsb) {
- /*
- * The size was only incremented on its last block.
- * We took care of that above, so just return.
- */
- return 0;
- }
-
- ASSERT(start_zero_fsb <= end_zero_fsb);
- while (start_zero_fsb <= end_zero_fsb) {
- nimaps = 1;
- zero_count_fsb = end_zero_fsb - start_zero_fsb + 1;
- error = XFS_BMAPI(mp, NULL, io, start_zero_fsb, zero_count_fsb,
- 0, NULL, 0, &imap, &nimaps, NULL, NULL);
- if (error) {
- ASSERT(ismrlocked(io->io_lock, MR_UPDATE));
- ASSERT(ismrlocked(io->io_iolock, MR_UPDATE));
- return error;
- }
- ASSERT(nimaps > 0);
-
- if (imap.br_state == XFS_EXT_UNWRITTEN ||
- imap.br_startblock == HOLESTARTBLOCK) {
- /*
- * This loop handles initializing pages that were
- * partially initialized by the code below this
- * loop. It basically zeroes the part of the page
- * that sits on a hole and sets the page as P_HOLE
- * and calls remapf if it is a mapped file.
- */
- start_zero_fsb = imap.br_startoff + imap.br_blockcount;
- ASSERT(start_zero_fsb <= (end_zero_fsb + 1));
- continue;
- }
-
- /*
- * There are blocks in the range requested.
- * Zero them a single write at a time. We actually
- * don't zero the entire range returned if it is
- * too big and simply loop around to get the rest.
- * That is not the most efficient thing to do, but it
- * is simple and this path should not be exercised often.
- */
- buf_len_fsb = XFS_FILBLKS_MIN(imap.br_blockcount,
- mp->m_writeio_blocks << 8);
- /*
- * Drop the inode lock while we're doing the I/O.
- * We'll still have the iolock to protect us.
- */
- XFS_IUNLOCK(mp, io, XFS_ILOCK_EXCL|XFS_EXTSIZE_RD);
-
- error = xfs_iozero(vp,
- XFS_FSB_TO_B(mp, start_zero_fsb),
- XFS_FSB_TO_B(mp, buf_len_fsb),
- end_size);
-
- if (error) {
- goto out_lock;
- }
-
- start_zero_fsb = imap.br_startoff + buf_len_fsb;
- ASSERT(start_zero_fsb <= (end_zero_fsb + 1));
-
- XFS_ILOCK(mp, io, XFS_ILOCK_EXCL|XFS_EXTSIZE_RD);
- }
-
- return 0;
-
-out_lock:
-
- XFS_ILOCK(mp, io, XFS_ILOCK_EXCL|XFS_EXTSIZE_RD);
- ASSERT(error >= 0);
- return error;
-}
-
-ssize_t /* bytes written, or (-) error */
-xfs_write(
- bhv_desc_t *bdp,
- uio_t *uio,
- int ioflag,
- cred_t *credp)
-{
- xfs_inode_t *xip;
- xfs_mount_t *mp;
- ssize_t ret = 0;
- int error = 0;
- xfs_fsize_t isize, new_size;
- xfs_fsize_t n, limit;
- xfs_fsize_t size;
- xfs_iocore_t *io;
- xfs_vnode_t *vp;
- int iolock;
- //int eventsent = 0;
- vrwlock_t locktype;
- xfs_off_t offset_c;
- xfs_off_t *offset;
- xfs_off_t pos;
-
- XFS_STATS_INC(xs_write_calls);
-
- vp = BHV_TO_VNODE(bdp);
- xip = XFS_BHVTOI(bdp);
-
- io = &xip->i_iocore;
- mp = io->io_mount;
-
- if (XFS_FORCED_SHUTDOWN(xip->i_mount)) {
- return EIO;
- }
-
- size = uio->uio_resid;
- pos = offset_c = uio->uio_offset;
- offset = &offset_c;
-
- if (unlikely(ioflag & IO_ISDIRECT)) {
- if (((__psint_t)buf & BBMASK) ||
- (*offset & mp->m_blockmask) ||
- (size & mp->m_blockmask)) {
- return EINVAL;
- }
- iolock = XFS_IOLOCK_SHARED;
- locktype = VRWLOCK_WRITE_DIRECT;
- } else {
- if (io->io_flags & XFS_IOCORE_RT)
- return EINVAL;
- iolock = XFS_IOLOCK_EXCL;
- locktype = VRWLOCK_WRITE;
- }
-
- iolock = XFS_IOLOCK_EXCL;
- locktype = VRWLOCK_WRITE;
-
- xfs_ilock(xip, XFS_ILOCK_EXCL|iolock);
-
- isize = xip->i_d.di_size;
- limit = XFS_MAXIOFFSET(mp);
-
- if (ioflag & O_APPEND)
- *offset = isize;
-
-//start:
- n = limit - *offset;
- if (n <= 0) {
- xfs_iunlock(xip, XFS_ILOCK_EXCL|iolock);
- return EFBIG;
- }
- if (n < size)
- size = n;
-
- new_size = *offset + size;
- if (new_size > isize) {
- io->io_new_size = new_size;
- }
-
-#ifdef RMC
- /* probably be a long time before if ever that we do dmapi */
- if ((DM_EVENT_ENABLED(vp->v_vfsp, xip, DM_EVENT_WRITE) &&
- !(ioflags & IO_INVIS) && !eventsent)) {
- loff_t savedsize = *offset;
- int dmflags = FILP_DELAY_FLAG(file) | DM_SEM_FLAG_RD(ioflags);
-
- xfs_iunlock(xip, XFS_ILOCK_EXCL);
- error = XFS_SEND_DATA(xip->i_mount, DM_EVENT_WRITE, vp,
- *offset, size,
- dmflags, &locktype);
- if (error) {
- if (iolock) xfs_iunlock(xip, iolock);
- return -error;
- }
- xfs_ilock(xip, XFS_ILOCK_EXCL);
- eventsent = 1;
-
- /*
- * The iolock was dropped and reaquired in XFS_SEND_DATA
- * so we have to recheck the size when appending.
- * We will only "goto start;" once, since having sent the
- * event prevents another call to XFS_SEND_DATA, which is
- * what allows the size to change in the first place.
- */
- if ((file->f_flags & O_APPEND) &&
- savedsize != xip->i_d.di_size) {
- *offset = isize = xip->i_d.di_size;
- goto start;
- }
- }
-#endif
-
- /*
- * If the offset is beyond the size of the file, we have a couple
- * of things to do. First, if there is already space allocated
- * we need to either create holes or zero the disk or ...
- *
- * If there is a page where the previous size lands, we need
- * to zero it out up to the new size.
- */
-
- if (!(ioflag & IO_ISDIRECT) && (*offset > isize && isize)) {
- error = xfs_zero_eof(BHV_TO_VNODE(bdp), io, *offset,
- isize, *offset + size);
- if (error) {
- xfs_iunlock(xip, XFS_ILOCK_EXCL|iolock);
- return(-error);
- }
- }
- xfs_iunlock(xip, XFS_ILOCK_EXCL);
-
-#if 0
- /*
- * If we're writing the file then make sure to clear the
- * setuid and setgid bits if the process is not being run
- * by root. This keeps people from modifying setuid and
- * setgid binaries.
- */
-
- if (((xip->i_d.di_mode & S_ISUID) ||
- ((xip->i_d.di_mode & (S_ISGID | S_IXGRP)) ==
- (S_ISGID | S_IXGRP))) &&
- !capable(CAP_FSETID)) {
- error = xfs_write_clear_setuid(xip);
- if (likely(!error))
- error = -remove_suid(file->f_dentry);
- if (unlikely(error)) {
- xfs_iunlock(xip, iolock);
- goto out_unlock_mutex;
- }
- }
-#endif
-
-
-//retry:
- if (unlikely(ioflag & IO_ISDIRECT)) {
-
-#ifdef RMC
- xfs_off_t pos = *offset;
- struct address_space *mapping = file->f_dentry->d_inode->i_mapping;
- struct inode *inode = mapping->host;
-
- ret = precheck_file_write(file, inode, &size, &pos);
- if (ret || size == 0)
- goto error;
-
- xfs_inval_cached_pages(vp, io, pos, 1, 1);
- inode->i_ctime = inode->i_mtime = CURRENT_TIME;
- /* mark_inode_dirty_sync(inode); - we do this later */
-
- xfs_rw_enter_trace(XFS_DIOWR_ENTER, io, buf, size, pos, ioflags);
- ret = generic_file_direct_IO(WRITE, file, (char *)buf, size, pos);
- xfs_inval_cached_pages(vp, io, pos, 1, 1);
- if (ret > 0)
- *offset += ret;
-#endif
- } else {
- xfs_rw_enter_trace(XFS_WRITE_ENTER, io, buf, size, *offset, ioflags);
- ret = xfs_write_file(xip,uio,ioflag);
- }
-
- xfs_ichgtime(xip, XFS_ICHGTIME_MOD | XFS_ICHGTIME_CHG);
-
-
-//error:
- if (ret <= 0) {
- if (iolock)
- xfs_rwunlock(bdp, locktype);
- return ret;
- }
-
- XFS_STATS_ADD(xs_write_bytes, ret);
-
- if (*offset > xip->i_d.di_size) {
- xfs_ilock(xip, XFS_ILOCK_EXCL);
- if (*offset > xip->i_d.di_size) {
- printf("xfs_write look at doing more here %s:%d\n",__FILE__,__LINE__);
-#ifdef RMC
- struct inode *inode = LINVFS_GET_IP(vp);
- i_size_write(inode, *offset);
- mark_inode_dirty_sync(inode);
-#endif
-
- xip->i_d.di_size = *offset;
- xip->i_update_core = 1;
- xip->i_update_size = 1;
- }
- xfs_iunlock(xip, XFS_ILOCK_EXCL);
- }
-
- /* Handle various SYNC-type writes */
-#if 0
-// if ((file->f_flags & O_SYNC) || IS_SYNC(inode)) {
-#endif
- if (ioflag & IO_SYNC) {
- /*
- * If we're treating this as O_DSYNC and we have not updated the
- * size, force the log.
- */
- if (!(mp->m_flags & XFS_MOUNT_OSYNCISOSYNC) &&
- !(xip->i_update_size)) {
- xfs_inode_log_item_t *iip = xip->i_itemp;
-
- /*
- * If an allocation transaction occurred
- * without extending the size, then we have to force
- * the log up the proper point to ensure that the
- * allocation is permanent. We can't count on
- * the fact that buffered writes lock out direct I/O
- * writes - the direct I/O write could have extended
- * the size nontransactionally, then finished before
- * we started. xfs_write_file will think that the file
- * didn't grow but the update isn't safe unless the
- * size change is logged.
- *
- * Force the log if we've committed a transaction
- * against the inode or if someone else has and
- * the commit record hasn't gone to disk (e.g.
- * the inode is pinned). This guarantees that
- * all changes affecting the inode are permanent
- * when we return.
- */
- if (iip && iip->ili_last_lsn) {
- xfs_log_force(mp, iip->ili_last_lsn,
- XFS_LOG_FORCE | XFS_LOG_SYNC);
- } else if (xfs_ipincount(xip) > 0) {
- xfs_log_force(mp, (xfs_lsn_t)0,
- XFS_LOG_FORCE | XFS_LOG_SYNC);
- }
-
- } else {
- xfs_trans_t *tp;
-
- /*
- * O_SYNC or O_DSYNC _with_ a size update are handled
- * the same way.
- *
- * If the write was synchronous then we need to make
- * sure that the inode modification time is permanent.
- * We'll have updated the timestamp above, so here
- * we use a synchronous transaction to log the inode.
- * It's not fast, but it's necessary.
- *
- * If this a dsync write and the size got changed
- * non-transactionally, then we need to ensure that
- * the size change gets logged in a synchronous
- * transaction.
- */
-
- tp = xfs_trans_alloc(mp, XFS_TRANS_WRITE_SYNC);
- if ((error = xfs_trans_reserve(tp, 0,
- XFS_SWRITE_LOG_RES(mp),
- 0, 0, 0))) {
- /* Transaction reserve failed */
- xfs_trans_cancel(tp, 0);
- } else {
- /* Transaction reserve successful */
- xfs_ilock(xip, XFS_ILOCK_EXCL);
- xfs_trans_ijoin(tp, xip, XFS_ILOCK_EXCL);
- xfs_trans_ihold(tp, xip);
- xfs_trans_log_inode(tp, xip, XFS_ILOG_CORE);
- xfs_trans_set_sync(tp);
- error = xfs_trans_commit(tp, 0, NULL);
- xfs_iunlock(xip, XFS_ILOCK_EXCL);
- }
- if (error)
- goto out_unlock_internal;
- }
-
- xfs_rwunlock(bdp, locktype);
- return ret;
-
- } /* (ioflags & O_SYNC) */
-
-out_unlock_internal:
- xfs_rwunlock(bdp, locktype);
-#if 0
-out_unlock_mutex:
- if (need_i_mutex)
- mutex_unlock(&inode->i_mutex);
-#endif
- //out_nounlocks:
- return -error;
-}
-
-/*
- * Initiate IO on given buffer.
- */
-int
-xfs_buf_iorequest(struct xfs_buf *bp)
-{
- bp->b_flags &= ~(B_INVAL|B_DONE);
- bp->b_ioflags &= ~BIO_ERROR;
-
- if (bp->b_flags & B_ASYNC)
- BUF_KERNPROC(bp);
-
- if (bp->b_vp == NULL) {
- if (bp->b_iocmd == BIO_WRITE) {
- bp->b_flags &= ~(B_DELWRI | B_DEFERRED);
- bufobj_wref(bp->b_bufobj);
- }
-
- bp->b_iooffset = (bp->b_blkno << BBSHIFT);
- bstrategy(bp);
- } else {
- if (bp->b_iocmd == BIO_WRITE) {
- /* Mark the buffer clean */
- bundirty(bp);
- bufobj_wref(bp->b_bufobj);
- vfs_busy_pages(bp, 1);
- } else if (bp->b_iocmd == BIO_READ) {
- vfs_busy_pages(bp, 0);
- }
- bp->b_iooffset = dbtob(bp->b_blkno);
- bstrategy(bp);
- }
- return 0;
-}
-
-/*
- * All xfs metadata buffers except log state machine buffers
- * get this attached as their b_bdstrat callback function.
- * This is so that we can catch a buffer
- * after prematurely unpinning it to forcibly shutdown the filesystem.
- */
-int
-xfs_bdstrat_cb(struct xfs_buf *bp)
-{
- xfs_mount_t *mp;
-
- mp = XFS_BUF_FSPRIVATE3(bp, xfs_mount_t *);
- if (!XFS_FORCED_SHUTDOWN(mp)) {
- xfs_buf_iorequest(bp);
- return 0;
- } else {
- xfs_buftrace("XFS__BDSTRAT IOERROR", bp);
- /*
- * Metadata write that didn't get logged but
- * written delayed anyway. These aren't associated
- * with a transaction, and can be ignored.
- */
- if (XFS_BUF_IODONE_FUNC(bp) == NULL &&
- (XFS_BUF_ISREAD(bp)) == 0)
- return (xfs_bioerror_relse(bp));
- else
- return (xfs_bioerror(bp));
- }
-}
-
-
-int
-xfs_bmap(bhv_desc_t *bdp,
- xfs_off_t offset,
- ssize_t count,
- int flags,
- xfs_iomap_t *iomapp,
- int *niomaps)
-{
- xfs_inode_t *ip = XFS_BHVTOI(bdp);
- xfs_iocore_t *io = &ip->i_iocore;
-
- ASSERT((ip->i_d.di_mode & S_IFMT) == S_IFREG);
- ASSERT(((ip->i_d.di_flags & XFS_DIFLAG_REALTIME) != 0) ==
- ((ip->i_iocore.io_flags & XFS_IOCORE_RT) != 0));
-
- return xfs_iomap(io, offset, count, flags, iomapp, niomaps);
-}
-
-/*
- * Wrapper around bdstrat so that we can stop data
- * from going to disk in case we are shutting down the filesystem.
- * Typically user data goes thru this path; one of the exceptions
- * is the superblock.
- */
-int
-xfsbdstrat(
- struct xfs_mount *mp,
- struct xfs_buf *bp)
-{
- ASSERT(mp);
- if (!XFS_FORCED_SHUTDOWN(mp)) {
-
- xfs_buf_iorequest(bp);
- return 0;
- }
-
- xfs_buftrace("XFSBDSTRAT IOERROR", bp);
- return (xfs_bioerror_relse(bp));
-}
-
-/*
- * If the underlying (data/log/rt) device is readonly, there are some
- * operations that cannot proceed.
- */
-int
-xfs_dev_is_read_only(
- xfs_mount_t *mp,
- char *message)
-{
- if (xfs_readonly_buftarg(mp->m_ddev_targp) ||
- xfs_readonly_buftarg(mp->m_logdev_targp) ||
- (mp->m_rtdev_targp && xfs_readonly_buftarg(mp->m_rtdev_targp))) {
- cmn_err(CE_NOTE,
- "XFS: %s required on read-only device.", message);
- cmn_err(CE_NOTE,
- "XFS: write access unavailable, cannot proceed.");
- return EROFS;
- }
- return 0;
-}
diff --git a/sys/gnu/fs/xfs/FreeBSD/xfs_frw.h b/sys/gnu/fs/xfs/FreeBSD/xfs_frw.h
deleted file mode 100644
index 78d93f9..0000000
--- a/sys/gnu/fs/xfs/FreeBSD/xfs_frw.h
+++ /dev/null
@@ -1,106 +0,0 @@
-/*
- * Copyright (c) 2000-2003 Silicon Graphics, Inc. All Rights Reserved.
- *
- * This program 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.
- *
- * This program is distributed in the hope that it would be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
- *
- * Further, this software is distributed without any warranty that it is
- * free of the rightful claim of any third person regarding infringement
- * or the like. Any license provided herein, whether implied or
- * otherwise, applies only to this software file. Patent licenses, if
- * any, provided herein do not apply to combinations of this program with
- * other software, or any other product whatsoever.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write the Free Software Foundation, Inc., 59
- * Temple Place - Suite 330, Boston MA 02111-1307, USA.
- *
- * Contact information: Silicon Graphics, Inc., 1600 Amphitheatre Pkwy,
- * Mountain View, CA 94043, or:
- *
- * http://www.sgi.com
- *
- * For further information regarding this notice, see:
- *
- * http://oss.sgi.com/projects/GenInfo/SGIGPLNoticeExplan/
- */
-#ifndef __XFS_FRW_H__
-#define __XFS_FRW_H__
-
-struct xfs_vnode;
-struct bhv_desc;
-struct xfs_mount;
-struct xfs_iocore;
-struct xfs_inode;
-struct xfs_bmbt_irec;
-struct xfs_buf;
-struct xfs_iomap;
-
-#if defined(XFS_RW_TRACE)
-/*
- * Defines for the trace mechanisms in xfs_lrw.c.
- */
-#define XFS_RW_KTRACE_SIZE 128
-
-#define XFS_READ_ENTER 1
-#define XFS_WRITE_ENTER 2
-#define XFS_IOMAP_READ_ENTER 3
-#define XFS_IOMAP_WRITE_ENTER 4
-#define XFS_IOMAP_READ_MAP 5
-#define XFS_IOMAP_WRITE_MAP 6
-#define XFS_IOMAP_WRITE_NOSPACE 7
-#define XFS_ITRUNC_START 8
-#define XFS_ITRUNC_FINISH1 9
-#define XFS_ITRUNC_FINISH2 10
-#define XFS_CTRUNC1 11
-#define XFS_CTRUNC2 12
-#define XFS_CTRUNC3 13
-#define XFS_CTRUNC4 14
-#define XFS_CTRUNC5 15
-#define XFS_CTRUNC6 16
-#define XFS_BUNMAPI 17
-#define XFS_INVAL_CACHED 18
-#define XFS_DIORD_ENTER 19
-#define XFS_DIOWR_ENTER 20
-#define XFS_SENDFILE_ENTER 21
-#define XFS_WRITEPAGE_ENTER 22
-#define XFS_RELEASEPAGE_ENTER 23
-#define XFS_IOMAP_ALLOC_ENTER 24
-#define XFS_IOMAP_ALLOC_MAP 25
-#define XFS_IOMAP_UNWRITTEN 26
-extern void xfs_rw_enter_trace(int, struct xfs_iocore *,
- const char *, size_t, loff_t, int);
-extern void xfs_inval_cached_trace(struct xfs_iocore *,
- xfs_off_t, xfs_off_t, xfs_off_t, xfs_off_t);
-#else
-#define xfs_rw_enter_trace(tag, io, buf, size, offset, ioflags)
-#define xfs_inval_cached_trace(io, offset, len, first, last)
-#endif
-
-/*
- * Maximum count of bmaps used by read and write paths.
- */
-#define XFS_MAX_RW_NBMAPS 4
-
-extern int xfs_bmap(struct bhv_desc *, xfs_off_t, ssize_t, int,
- struct xfs_iomap *, int *);
-extern int xfsbdstrat(struct xfs_mount *, struct xfs_buf *);
-extern int xfs_bdstrat_cb(struct xfs_buf *);
-
-extern int xfs_zero_eof(struct xfs_vnode *, struct xfs_iocore *, xfs_off_t,
- xfs_fsize_t, xfs_fsize_t);
-extern void xfs_inval_cached_pages(struct xfs_vnode*, struct xfs_iocore *,
- xfs_off_t, int, int);
-extern ssize_t xfs_read(bhv_desc_t *, uio_t *, int, cred_t *);
-extern ssize_t xfs_write(bhv_desc_t *, uio_t *, int, cred_t *);
-extern int xfs_dev_is_read_only(struct xfs_mount *, char *);
-
-extern int xfs_read_file(struct xfs_mount *mp, struct xfs_inode *ip, struct uio *uio,
- int ioflag);
-extern int xfs_write_file(struct xfs_inode *, struct uio *, int);
-#endif /* __XFS_FRW_H__ */
diff --git a/sys/gnu/fs/xfs/FreeBSD/xfs_fs_subr.c b/sys/gnu/fs/xfs/FreeBSD/xfs_fs_subr.c
deleted file mode 100644
index dec6e2f..0000000
--- a/sys/gnu/fs/xfs/FreeBSD/xfs_fs_subr.c
+++ /dev/null
@@ -1,131 +0,0 @@
-/*
- * Copyright (c) 2000-2002 Silicon Graphics, Inc. All Rights Reserved.
- *
- * This program 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.
- *
- * This program is distributed in the hope that it would be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
- *
- * Further, this software is distributed without any warranty that it is
- * free of the rightful claim of any third person regarding infringement
- * or the like. Any license provided herein, whether implied or
- * otherwise, applies only to this software file. Patent licenses, if
- * any, provided herein do not apply to combinations of this program with
- * other software, or any other product whatsoever.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write the Free Software Foundation, Inc., 59
- * Temple Place - Suite 330, Boston MA 02111-1307, USA.
- *
- * Contact information: Silicon Graphics, Inc., 1600 Amphitheatre Pkwy,
- * Mountain View, CA 94043, or:
- *
- * http://www.sgi.com
- *
- * For further information regarding this notice, see:
- *
- * http://oss.sgi.com/projects/GenInfo/SGIGPLNoticeExplan/
- */
-
-#include "xfs.h"
-
-/*
- * Stub for no-op vnode operations that return error status.
- */
-int
-fs_noerr()
-{
- return 0;
-}
-
-/*
- * Operation unsupported under this file system.
- */
-int
-fs_nosys()
-{
- return ENOSYS;
-}
-
-/*
- * Stub for inactive, strategy, and read/write lock/unlock. Does nothing.
- */
-/* ARGSUSED */
-void
-fs_noval()
-{
-}
-
-/*
- * vnode pcache layer for vnode_tosspages.
- * 'last' parameter unused but left in for IRIX compatibility
- */
-void
-fs_tosspages(
- bhv_desc_t *bdp,
- xfs_off_t first,
- xfs_off_t last,
- int fiopt)
-{
-#ifdef XXXKAN
- vnode_t *vp = BHV_TO_VNODE(bdp);
- struct inode *ip = LINVFS_GET_IP(vp);
-
- if (VN_CACHED(vp))
- truncate_inode_pages(ip->i_mapping, first);
-#endif
-}
-
-
-/*
- * vnode pcache layer for vnode_flushinval_pages.
- * 'last' parameter unused but left in for IRIX compatibility
- */
-void
-fs_flushinval_pages(
- bhv_desc_t *bdp,
- xfs_off_t first,
- xfs_off_t last,
- int fiopt)
-{
-#ifdef XXXKAN
- vnode_t *vp = BHV_TO_VNODE(bdp);
- struct inode *ip = LINVFS_GET_IP(vp);
-
- if (VN_CACHED(vp)) {
- filemap_fdatasync(ip->i_mapping);
- fsync_inode_data_buffers(ip);
- filemap_fdatawait(ip->i_mapping);
-
- truncate_inode_pages(ip->i_mapping, first);
- }
-#endif
-}
-
-/*
- * vnode pcache layer for vnode_flush_pages.
- * 'last' parameter unused but left in for IRIX compatibility
- */
-int
-fs_flush_pages(
- bhv_desc_t *bdp,
- xfs_off_t first,
- xfs_off_t last,
- uint64_t flags,
- int fiopt)
-{
-#ifdef XXXKAN
- vnode_t *vp = BHV_TO_VNODE(bdp);
- struct inode *ip = LINVFS_GET_IP(vp);
-
- if (VN_CACHED(vp)) {
- filemap_fdatasync(ip->i_mapping);
- fsync_inode_data_buffers(ip);
- filemap_fdatawait(ip->i_mapping);
- }
-#endif
- return 0;
-}
diff --git a/sys/gnu/fs/xfs/FreeBSD/xfs_fs_subr.h b/sys/gnu/fs/xfs/FreeBSD/xfs_fs_subr.h
deleted file mode 100644
index 198b8dd..0000000
--- a/sys/gnu/fs/xfs/FreeBSD/xfs_fs_subr.h
+++ /dev/null
@@ -1,49 +0,0 @@
-/*
- * Copyright (c) 2000, 2002 Silicon Graphics, Inc. All Rights Reserved.
- *
- * This program 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.
- *
- * This program is distributed in the hope that it would be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
- *
- * Further, this software is distributed without any warranty that it is
- * free of the rightful claim of any third person regarding infringement
- * or the like. Any license provided herein, whether implied or
- * otherwise, applies only to this software file. Patent licenses, if
- * any, provided herein do not apply to combinations of this program with
- * other software, or any other product whatsoever.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write the Free Software Foundation, Inc., 59
- * Temple Place - Suite 330, Boston MA 02111-1307, USA.
- *
- * Contact information: Silicon Graphics, Inc., 1600 Amphitheatre Pkwy,
- * Mountain View, CA 94043, or:
- *
- * http://www.sgi.com
- *
- * For further information regarding this notice, see:
- *
- * http://oss.sgi.com/projects/GenInfo/SGIGPLNoticeExplan/
- */
-#ifndef __XFS_SUBR_H__
-#define __XFS_SUBR_H__
-
-/*
- * Utilities shared among file system implementations.
- */
-
-struct cred;
-
-extern int fs_noerr(void);
-extern int fs_nosys(void);
-extern int fs_nodev(void);
-extern void fs_noval(void);
-extern void fs_tosspages(bhv_desc_t *, xfs_off_t, xfs_off_t, int);
-extern void fs_flushinval_pages(bhv_desc_t *, xfs_off_t, xfs_off_t, int);
-extern int fs_flush_pages(bhv_desc_t *, xfs_off_t, xfs_off_t, uint64_t, int);
-
-#endif /* __XFS_FS_SUBR_H__ */
diff --git a/sys/gnu/fs/xfs/FreeBSD/xfs_globals.c b/sys/gnu/fs/xfs/FreeBSD/xfs_globals.c
deleted file mode 100644
index 1d4ac81..0000000
--- a/sys/gnu/fs/xfs/FreeBSD/xfs_globals.c
+++ /dev/null
@@ -1,77 +0,0 @@
-/*
- * Copyright (c) 2000-2003 Silicon Graphics, Inc. All Rights Reserved.
- *
- * This program 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.
- *
- * This program is distributed in the hope that it would be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
- *
- * Further, this software is distributed without any warranty that it is
- * free of the rightful claim of any third person regarding infringement
- * or the like. Any license provided herein, whether implied or
- * otherwise, applies only to this software file. Patent licenses, if
- * any, provided herein do not apply to combinations of this program with
- * other software, or any other product whatsoever.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write the Free Software Foundation, Inc., 59
- * Temple Place - Suite 330, Boston MA 02111-1307, USA.
- *
- * Contact information: Silicon Graphics, Inc., 1600 Amphitheatre Pkwy,
- * Mountain View, CA 94043, or:
- *
- * http://www.sgi.com
- *
- * For further information regarding this notice, see:
- *
- * http://oss.sgi.com/projects/GenInfo/SGIGPLNoticeExplan/
- */
-
-/*
- * This file contains globals needed by XFS that were normally defined
- * somewhere else in IRIX.
- */
-
-#include "xfs.h"
-#include "xfs_types.h"
-#include "xfs_bmap_btree.h"
-#include "xfs_bit.h"
-#include "xfs_refcache.h"
-
-/*
- * Tunable XFS parameters. xfs_params is required even when CONFIG_SYSCTL=n,
- * other XFS code uses these values.
- */
-
-xfs_param_t xfs_params = {
- /* MIN DFLT MAX */
-#ifdef HAVE_REFCACHE
- .refcache_size = { 0, 128, XFS_REFCACHE_SIZE_MAX },
- .refcache_purge = { 0, 32, XFS_REFCACHE_SIZE_MAX },
-#endif
- .restrict_chown = { 0, 1, 1 },
- .sgid_inherit = { 0, 0, 1 },
- .symlink_mode = { 0, 0, 1 },
- .panic_mask = { 0, 0, 127 },
- .error_level = { 0, 3, 11 },
- .syncd_timer = { 1*100, 30*100, 7200*100},
- .probe_dmapi = { 0, 0, 1 },
- .probe_ioops = { 0, 0, 1 },
- .probe_quota = { 0, 1, 1 },
- .stats_clear = { 0, 0, 1 },
- .inherit_sync = { 0, 1, 1 },
- .inherit_nodump = { 0, 1, 1 },
- .inherit_noatim = { 0, 1, 1 },
- .xfs_buf_timer = { 100/2, 1*100, 30*100 },
- .xfs_buf_age = { 1*100, 15*100, 7200*100},
- .inherit_nosym = { 0, 0, 1 },
- .rotorstep = { 1, 1, 255 },
-};
-
-/*
- * Global system credential structure.
- */
-cred_t sys_cred_val, *sys_cred = &sys_cred_val;
diff --git a/sys/gnu/fs/xfs/FreeBSD/xfs_ioctl.c b/sys/gnu/fs/xfs/FreeBSD/xfs_ioctl.c
deleted file mode 100644
index ff5582c..0000000
--- a/sys/gnu/fs/xfs/FreeBSD/xfs_ioctl.c
+++ /dev/null
@@ -1,1460 +0,0 @@
-/*
- * Copyright (c) 2000-2005 Silicon Graphics, Inc.
- * All Rights Reserved.
- *
- * 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.
- *
- * This program is distributed in the hope that it would 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 the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- */
-#include "xfs.h"
-#include "xfs_fs.h"
-#include "xfs_bit.h"
-#include "xfs_log.h"
-#include "xfs_inum.h"
-#include "xfs_trans.h"
-#include "xfs_sb.h"
-#include "xfs_ag.h"
-#include "xfs_dir.h"
-#include "xfs_dir2.h"
-#include "xfs_alloc.h"
-#include "xfs_dmapi.h"
-#include "xfs_mount.h"
-#include "xfs_bmap_btree.h"
-#include "xfs_alloc_btree.h"
-#include "xfs_ialloc_btree.h"
-#include "xfs_dir_sf.h"
-#include "xfs_attr_sf.h"
-#include "xfs_dir2_sf.h"
-#include "xfs_dinode.h"
-#include "xfs_inode.h"
-#include "xfs_btree.h"
-#include "xfs_ialloc.h"
-#include "xfs_rtalloc.h"
-#include "xfs_itable.h"
-#include "xfs_error.h"
-#include "xfs_rw.h"
-#include "xfs_acl.h"
-#include "xfs_cap.h"
-#include "xfs_mac.h"
-#include "xfs_attr.h"
-#include "xfs_bmap.h"
-#include "xfs_buf_item.h"
-#include "xfs_utils.h"
-#include "xfs_dfrag.h"
-#include "xfs_fsops.h"
-
-
-#include <sys/file.h>
-#if 1
-/*
- * ioctl commands that are used by Linux filesystems
- */
-#define XFS_IOC_GETXFLAGS _IOR('f', 1, long)
-#define XFS_IOC_SETXFLAGS _IOW('f', 2, long)
-#define XFS_IOC_GETVERSION _IOR('v', 1, long)
-
-#undef copy_to_user
-static __inline__ int
-copy_to_user(void *dst, void *src, int len) {
- memcpy(dst,src,len);
- return 0;
-}
-#undef copy_from_user
-static __inline__ int
-copy_from_user(void *dst, void *src, int len) {
- memcpy(dst,src,len);
- return 0;
-}
-
-/*
- * xfs_find_handle maps from userspace xfs_fsop_handlereq structure to
- * a file or fs handle.
- *
- * XFS_IOC_PATH_TO_FSHANDLE
- * returns fs handle for a mount point or path within that mount point
- * XFS_IOC_FD_TO_HANDLE
- * returns full handle for a FD opened in user space
- * XFS_IOC_PATH_TO_HANDLE
- * returns full handle for a path
- */
-STATIC int
-xfs_find_handle(
- unsigned int cmd,
- void __user *arg)
-{
-#ifdef RMC
- int hsize;
-#endif
- xfs_handle_t handle;
- xfs_fsop_handlereq_t hreq;
-#ifdef RMC
- struct inode *inode;
- xfs_vnode_t *vp;
-#endif
-
- if (copy_from_user(&hreq, arg, sizeof(hreq)))
- return -XFS_ERROR(EFAULT);
-
- memset((char *)&handle, 0, sizeof(handle));
-
- switch (cmd) {
-#if 0
- case XFS_IOC_PATH_TO_FSHANDLE:
- case XFS_IOC_PATH_TO_HANDLE: {
- struct nameidata nd;
- int error;
-
- NDINIT(&nd, LOOKUP, FOLLOW | LOCKLEAF,
- UIO_USERSPACE, hreq.path, td);
- error = namei(&nd);
- if (error)
- return error;
- NDFREE(&nd, NDF_ONLY_PNBUF);
- break;
- }
-
- case XFS_IOC_FD_TO_HANDLE: {
- struct file *file;
- int error;
-
- error = getvnode(td->td_proc->p_fd, hreq.fd, &file);
- if (error)
- return error;
-
- error = vget(vp, LK_EXCLUSIVE, td);
- if (error) {
- fdrop(file);
- return error;
- }
- fdrop(file);
- break;
- }
-#endif
-
- default:
- ASSERT(0);
- return XFS_ERROR(EINVAL);
- }
-
-#ifdef RMC
- if (inode->i_sb->s_magic != XFS_SB_MAGIC) {
- /* we're not in XFS anymore, Toto */
- iput(inode);
- return XFS_ERROR(EINVAL);
- }
-
- switch (inode->i_mode & S_IFMT) {
- case S_IFREG:
- case S_IFDIR:
- case S_IFLNK:
- break;
- default:
- iput(inode);
- return XFS_ERROR(EBADF);
- }
- /* we need the vnode */
- vp = vn_from_inode(inode);
-
- /* now we can grab the fsid */
- memcpy(&handle.ha_fsid, vp->v_vfsp->vfs_altfsid, sizeof(xfs_fsid_t));
- hsize = sizeof(xfs_fsid_t);
-
- if (cmd != XFS_IOC_PATH_TO_FSHANDLE) {
- xfs_inode_t *ip;
- int lock_mode;
-
- /* need to get access to the xfs_inode to read the generation */
- ip = xfs_vtoi(vp);
- ASSERT(ip);
- lock_mode = xfs_ilock_map_shared(ip);
-
- /* fill in fid section of handle from inode */
- handle.ha_fid.xfs_fid_len = sizeof(xfs_fid_t) -
- sizeof(handle.ha_fid.xfs_fid_len);
- handle.ha_fid.xfs_fid_pad = 0;
- handle.ha_fid.xfs_fid_gen = ip->i_d.di_gen;
- handle.ha_fid.xfs_fid_ino = ip->i_ino;
-
- xfs_iunlock_map_shared(ip, lock_mode);
-
- hsize = XFS_HSIZE(handle);
- }
-
- /* now copy our handle into the user buffer & write out the size */
- if (copy_to_user(hreq.ohandle, &handle, hsize) ||
- copy_to_user(hreq.ohandlen, &hsize, sizeof(__s32))) {
- iput(inode);
- return XFS_ERROR(EFAULT);
- }
-
- iput(inode);
-#endif
- return 0;
-}
-
-
-/*
- * Convert userspace handle data into vnode (and inode).
- * We [ab]use the fact that all the fsop_handlereq ioctl calls
- * have a data structure argument whose first component is always
- * a xfs_fsop_handlereq_t, so we can cast to and from this type.
- * This allows us to optimise the copy_from_user calls and gives
- * a handy, shared routine.
- *
- * If no error, caller must always VN_RELE the returned vp.
- */
-STATIC int
-xfs_vget_fsop_handlereq(
- xfs_mount_t *mp,
- struct inode *parinode, /* parent inode pointer */
- xfs_fsop_handlereq_t *hreq,
- xfs_vnode_t **vp,
- struct inode **inode)
-{
-#if 0
- void __user *hanp;
- size_t hlen;
- xfs_fid_t *xfid;
- xfs_handle_t *handlep;
- xfs_handle_t handle;
- xfs_inode_t *ip;
- struct inode *inodep;
- xfs_vnode_t *vpp;
- xfs_ino_t ino;
- __u32 igen;
- int error;
-
- /*
- * Only allow handle opens under a directory.
- */
- if (!S_ISDIR(parinode->i_mode))
- return XFS_ERROR(ENOTDIR);
-
- hanp = hreq->ihandle;
- hlen = hreq->ihandlen;
- handlep = &handle;
-
- if (hlen < sizeof(handlep->ha_fsid) || hlen > sizeof(*handlep))
- return XFS_ERROR(EINVAL);
- if (copy_from_user(handlep, hanp, hlen))
- return XFS_ERROR(EFAULT);
- if (hlen < sizeof(*handlep))
- memset(((char *)handlep) + hlen, 0, sizeof(*handlep) - hlen);
- if (hlen > sizeof(handlep->ha_fsid)) {
- if (handlep->ha_fid.xfs_fid_len !=
- (hlen - sizeof(handlep->ha_fsid)
- - sizeof(handlep->ha_fid.xfs_fid_len))
- || handlep->ha_fid.xfs_fid_pad)
- return XFS_ERROR(EINVAL);
- }
-
- /*
- * Crack the handle, obtain the inode # & generation #
- */
- xfid = (struct xfs_fid *)&handlep->ha_fid;
- if (xfid->xfs_fid_len == sizeof(*xfid) - sizeof(xfid->xfs_fid_len)) {
- ino = xfid->xfs_fid_ino;
- igen = xfid->xfs_fid_gen;
- } else {
- return XFS_ERROR(EINVAL);
- }
-
- /*
- * Get the XFS inode, building a vnode to go with it.
- */
- error = xfs_iget(mp, NULL, ino, 0, XFS_ILOCK_SHARED, &ip, 0);
- if (error)
- return error;
- if (ip == NULL)
- return XFS_ERROR(EIO);
- if (ip->i_d.di_mode == 0 || ip->i_d.di_gen != igen) {
- xfs_iput_new(ip, XFS_ILOCK_SHARED);
- return XFS_ERROR(ENOENT);
- }
-
- vpp = XFS_ITOV(ip);
- inodep = vn_to_inode(vpp);
- xfs_iunlock(ip, XFS_ILOCK_SHARED);
-
- *vp = vpp;
- *inode = inodep;
-#endif
- return 0;
-}
-
-STATIC int
-xfs_open_by_handle(
- xfs_mount_t *mp,
- void __user *arg,
- struct file *parfilp,
- struct inode *parinode)
-{
- int new_fd = 0;
-#if 0
- int error;
- int permflag;
- struct file *filp;
- struct inode *inode;
- struct dentry *dentry;
- xfs_vnode_t *vp;
- xfs_fsop_handlereq_t hreq;
-
- if (!capable(CAP_SYS_ADMIN))
- return -XFS_ERROR(EPERM);
- if (copy_from_user(&hreq, arg, sizeof(xfs_fsop_handlereq_t)))
- return XFS_ERROR(EFAULT);
-
- error = xfs_vget_fsop_handlereq(mp, parinode, &hreq, &vp, &inode);
- if (error)
- return error;
-
- /* Restrict xfs_open_by_handle to directories & regular files. */
- if (!(S_ISREG(inode->i_mode) || S_ISDIR(inode->i_mode))) {
- iput(inode);
- return XFS_ERROR(EINVAL);
- }
-
-#if BITS_PER_LONG != 32
- hreq.oflags |= O_LARGEFILE;
-#endif
- /* Put open permission in namei format. */
- permflag = hreq.oflags;
- if ((permflag+1) & O_ACCMODE)
- permflag++;
- if (permflag & O_TRUNC)
- permflag |= 2;
-
- if ((!(permflag & O_APPEND) || (permflag & O_TRUNC)) &&
- (permflag & FMODE_WRITE) && IS_APPEND(inode)) {
- iput(inode);
- return XFS_ERROR(EPERM);
- }
-
- if ((permflag & FMODE_WRITE) && IS_IMMUTABLE(inode)) {
- iput(inode);
- return XFS_ERROR(EACCES);
- }
-
- /* Can't write directories. */
- if ( S_ISDIR(inode->i_mode) && (permflag & FMODE_WRITE)) {
- iput(inode);
- return XFS_ERROR(EISDIR);
- }
-
- if ((new_fd = get_unused_fd()) < 0) {
- iput(inode);
- return new_fd;
- }
-
- dentry = d_alloc_anon(inode);
- if (dentry == NULL) {
- iput(inode);
- put_unused_fd(new_fd);
- return XFS_ERROR(ENOMEM);
- }
-
- /* Ensure umount returns EBUSY on umounts while this file is open. */
- mntget(parfilp->f_vfsmnt);
-
- /* Create file pointer. */
- filp = dentry_open(dentry, parfilp->f_vfsmnt, hreq.oflags);
- if (IS_ERR(filp)) {
- put_unused_fd(new_fd);
- return -XFS_ERROR(-PTR_ERR(filp));
- }
- if (inode->i_mode & S_IFREG)
- filp->f_op = &xfs_invis_file_operations;
-
- fd_install(new_fd, filp);
-#endif
- return new_fd;
-}
-
-STATIC int
-xfs_readlink_by_handle(
- xfs_mount_t *mp,
- void __user *arg,
- struct file *parfilp,
- struct inode *parinode)
-{
- int error;
- struct iovec aiov;
- struct uio auio;
- struct inode *inode;
- xfs_fsop_handlereq_t hreq;
- xfs_vnode_t *vp = NULL;
- __u32 olen;
-
- if (!capable(CAP_SYS_ADMIN))
- return -XFS_ERROR(EPERM);
- if (copy_from_user(&hreq, arg, sizeof(xfs_fsop_handlereq_t)))
- return -XFS_ERROR(EFAULT);
-
- error = xfs_vget_fsop_handlereq(mp, parinode, &hreq, &vp, &inode);
- if (error)
- return -error;
-
-#if 0
- /* Restrict this handle operation to symlinks only. */
- if (vp->v_type != VLNK) {
- VN_RELE(vp);
- return -XFS_ERROR(EINVAL);
- }
-#endif
-
- if (copy_from_user(&olen, hreq.ohandlen, sizeof(__u32))) {
- VN_RELE(vp);
- return -XFS_ERROR(EFAULT);
- }
- aiov.iov_len = olen;
- aiov.iov_base = hreq.ohandle;
-
- auio.uio_iov = &aiov;
- auio.uio_iovcnt = 1;
- auio.uio_offset = 0;
- auio.uio_segflg = UIO_USERSPACE;
- auio.uio_resid = olen;
-
- XVOP_READLINK(vp, &auio, IO_INVIS, NULL, error);
-
- VN_RELE(vp);
- return (olen - auio.uio_resid);
-}
-
-STATIC int
-xfs_fssetdm_by_handle(
- xfs_mount_t *mp,
- void __user *arg,
- struct file *parfilp,
- struct inode *parinode)
-{
- int error = 0;
-#if 0
- struct fsdmidata fsd;
- xfs_fsop_setdm_handlereq_t dmhreq;
- struct inode *inode;
- bhv_desc_t *bdp;
- xfs_vnode_t *vp;
-
- if (!capable(CAP_MKNOD))
- return XFS_ERROR(EPERM);
- if (copy_from_user(&dmhreq, arg, sizeof(xfs_fsop_setdm_handlereq_t)))
- return XFS_ERROR(EFAULT);
-
- error = xfs_vget_fsop_handlereq(mp, parinode, &dmhreq.hreq, &vp, &inode);
- if (error)
- return error;
-
- if (IS_IMMUTABLE(inode) || IS_APPEND(inode)) {
- VN_RELE(vp);
- return XFS_ERROR(EPERM);
- }
-
- if (copy_from_user(&fsd, dmhreq.data, sizeof(fsd))) {
- VN_RELE(vp);
- return XFS_ERROR(EFAULT);
- }
-
- bdp = bhv_base_unlocked(VN_BHV_HEAD(vp));
- error = xfs_set_dmattrs(bdp, fsd.fsd_dmevmask, fsd.fsd_dmstate, NULL);
-
- VN_RELE(vp);
- if (error)
- return error;
-#endif
- return error;
-}
-
-STATIC int
-xfs_attrlist_by_handle(
- xfs_mount_t *mp,
- void __user *arg,
- struct file *parfilp,
- struct inode *parinode)
-{
- int error = 0;
-#if 0
- attrlist_cursor_kern_t *cursor;
- xfs_fsop_attrlist_handlereq_t al_hreq;
- struct inode *inode;
- xfs_vnode_t *vp;
- char *kbuf;
-
- if (!capable(CAP_SYS_ADMIN))
- return -XFS_ERROR(EPERM);
- if (copy_from_user(&al_hreq, arg, sizeof(xfs_fsop_attrlist_handlereq_t)))
- return -XFS_ERROR(EFAULT);
- if (al_hreq.buflen > XATTR_LIST_MAX)
- return -XFS_ERROR(EINVAL);
-
- error = xfs_vget_fsop_handlereq(mp, parinode, &al_hreq.hreq,
- &vp, &inode);
- if (error)
- goto out;
-
- kbuf = kmalloc(al_hreq.buflen, GFP_KERNEL);
- if (!kbuf)
- goto out_vn_rele;
-
- cursor = (attrlist_cursor_kern_t *)&al_hreq.pos;
- XVOP_ATTR_LIST(vp, kbuf, al_hreq.buflen, al_hreq.flags,
- cursor, NULL, error);
- if (error)
- goto out_kfree;
-
- if (copy_to_user(al_hreq.buffer, kbuf, al_hreq.buflen))
- error = -EFAULT;
-
- out_kfree:
- kfree(kbuf);
- out_vn_rele:
- VN_RELE(vp);
- out:
-#endif
- return error;
-}
-
-#if 0
-STATIC int
-xfs_attrmulti_attr_get(
- xfs_vnode_t *vp,
- char *name,
- char __user *ubuf,
- __uint32_t *len,
- __uint32_t flags)
-{
- int error = EFAULT;
- char *kbuf;
-
- if (*len > XATTR_SIZE_MAX)
- return EINVAL;
- kbuf = kmalloc(*len, GFP_KERNEL);
- if (!kbuf)
- return ENOMEM;
-
- XVOP_ATTR_GET(vp, name, kbuf, len, flags, NULL, error);
- if (error)
- goto out_kfree;
-
- if (copy_to_user(ubuf, kbuf, *len))
- error = EFAULT;
-
- out_kfree:
- kfree(kbuf);
- return error;
-}
-#endif
-
-#if 0
-STATIC int
-xfs_attrmulti_attr_set(
- xfs_vnode_t *vp,
- char *name,
- const char __user *ubuf,
- __uint32_t len,
- __uint32_t flags)
-{
- int error = EFAULT;
- char *kbuf;
-
- if (IS_RDONLY(&vp->v_inode))
- return -EROFS;
- if (IS_IMMUTABLE(&vp->v_inode) || IS_APPEND(&vp->v_inode))
- return EPERM;
- if (len > XATTR_SIZE_MAX)
- return EINVAL;
-
- kbuf = kmalloc(len, GFP_KERNEL);
- if (!kbuf)
- return ENOMEM;
-
- if (copy_from_user(kbuf, ubuf, len))
- goto out_kfree;
-
- XVOP_ATTR_SET(vp, name, kbuf, len, flags, NULL, error);
-
- out_kfree:
- kfree(kbuf);
- return error;
-}
-#endif
-
-#if 0
-STATIC int
-xfs_attrmulti_attr_remove(
- xfs_vnode_t *vp,
- char *name,
- __uint32_t flags)
-{
- int error;
-
- if (IS_RDONLY(&vp->v_inode))
- return -EROFS;
- if (IS_IMMUTABLE(&vp->v_inode) || IS_APPEND(&vp->v_inode))
- return EPERM;
-
- XVOP_ATTR_REMOVE(vp, name, flags, NULL, error);
- return error;
-}
-#endif
-
-STATIC int
-xfs_attrmulti_by_handle(
- xfs_mount_t *mp,
- void __user *arg,
- struct file *parfilp,
- struct inode *parinode)
-{
- int error = 0;
-#if 0
- xfs_attr_multiop_t *ops;
- xfs_fsop_attrmulti_handlereq_t am_hreq;
- struct inode *inode;
- xfs_vnode_t *vp;
- unsigned int i, size;
- char *attr_name;
-
- if (!capable(CAP_SYS_ADMIN))
- return -XFS_ERROR(EPERM);
- if (copy_from_user(&am_hreq, arg, sizeof(xfs_fsop_attrmulti_handlereq_t)))
- return -XFS_ERROR(EFAULT);
-
- error = xfs_vget_fsop_handlereq(mp, parinode, &am_hreq.hreq, &vp, &inode);
- if (error)
- goto out;
-
- error = E2BIG;
- size = am_hreq.opcount * sizeof(attr_multiop_t);
- if (!size || size > 16 * PAGE_SIZE)
- goto out_vn_rele;
-
- error = ENOMEM;
- ops = kmalloc(size, GFP_KERNEL);
- if (!ops)
- goto out_vn_rele;
-
- error = EFAULT;
- if (copy_from_user(ops, am_hreq.ops, size))
- goto out_kfree_ops;
-
- attr_name = kmalloc(MAXNAMELEN, GFP_KERNEL);
- if (!attr_name)
- goto out_kfree_ops;
-
-
- error = 0;
- for (i = 0; i < am_hreq.opcount; i++) {
- ops[i].am_error = strncpy_from_user(attr_name,
- ops[i].am_attrname, MAXNAMELEN);
- if (ops[i].am_error == 0 || ops[i].am_error == MAXNAMELEN)
- error = -ERANGE;
- if (ops[i].am_error < 0)
- break;
-
- switch (ops[i].am_opcode) {
- case ATTR_OP_GET:
- ops[i].am_error = xfs_attrmulti_attr_get(vp,
- attr_name, ops[i].am_attrvalue,
- &ops[i].am_length, ops[i].am_flags);
- break;
- case ATTR_OP_SET:
- ops[i].am_error = xfs_attrmulti_attr_set(vp,
- attr_name, ops[i].am_attrvalue,
- ops[i].am_length, ops[i].am_flags);
- break;
- case ATTR_OP_REMOVE:
- ops[i].am_error = xfs_attrmulti_attr_remove(vp,
- attr_name, ops[i].am_flags);
- break;
- default:
- ops[i].am_error = EINVAL;
- }
- }
-
- if (copy_to_user(am_hreq.ops, ops, size))
- error = XFS_ERROR(EFAULT);
-
- kfree(attr_name);
- out_kfree_ops:
- kfree(ops);
- out_vn_rele:
- VN_RELE(vp);
- out:
-#endif
- return error;
-}
-
-/* prototypes for a few of the stack-hungry cases that have
- * their own functions. Functions are defined after their use
- * so gcc doesn't get fancy and inline them with -03 */
-
-STATIC int
-xfs_ioc_space(
- bhv_desc_t *bdp,
- xfs_vnode_t *vp,
- struct file *filp,
- int flags,
- u_long cmd,
- void __user *arg);
-
-STATIC int
-xfs_ioc_bulkstat(
- xfs_mount_t *mp,
- unsigned int cmd,
- void __user *arg);
-
-STATIC int
-xfs_ioc_fsgeometry_v1(
- xfs_mount_t *mp,
- void __user *arg);
-
-STATIC int
-xfs_ioc_fsgeometry(
- xfs_mount_t *mp,
- void __user *arg);
-
-STATIC int
-xfs_ioc_xattr(
- xfs_vnode_t *vp,
- xfs_inode_t *ip,
- struct file *filp,
- unsigned int cmd,
- void __user *arg);
-
-STATIC int
-xfs_ioc_getbmap(
- bhv_desc_t *bdp,
- struct file *filp,
- int flags,
- unsigned int cmd,
- void __user *arg);
-
-STATIC int
-xfs_ioc_getbmapx(
- bhv_desc_t *bdp,
- void __user *arg);
-
-int
-xfs_ioctl(
- bhv_desc_t *bdp,
- struct inode *inode,
- struct file *filp,
- int ioflags,
- u_long cmd,
- void *arg)
-{
- int error;
- xfs_vnode_t *vp;
- xfs_inode_t *ip;
- xfs_mount_t *mp;
-
-// vp = vn_from_inode(inode);
- vp = BHV_TO_VNODE(bdp);
-
- printf("xfs_ioctl: bdp %p flags 0x%x cmd 0x%lx basecmd 0x%lx arg %p\n",
- bdp, ioflags, cmd,
- IOCBASECMD(cmd),
- arg);
-
-
- vn_trace_entry(vp, "xfs_ioctl", (inst_t *)__return_address);
-
- ip = XFS_BHVTOI(bdp);
- mp = ip->i_mount;
-
-
-#if 0
- if ((cmd << 24 >> 24) == (XFS_IOC_GETBMAPX << 24 >> 24)) {
- cmd = XFS_IOC_GETBMAPX;
- }
-#endif
-
-
-
- switch (cmd) {
-
- case XFS_IOC_ALLOCSP:
- case XFS_IOC_FREESP:
- case XFS_IOC_RESVSP:
- case XFS_IOC_UNRESVSP:
- case XFS_IOC_ALLOCSP64:
- case XFS_IOC_FREESP64:
- case XFS_IOC_RESVSP64:
- case XFS_IOC_UNRESVSP64:
- /*
- * Only allow the sys admin to reserve space unless
- * unwritten extents are enabled.
- */
- if (!XFS_SB_VERSION_HASEXTFLGBIT(&mp->m_sb) &&
- !capable(CAP_SYS_ADMIN))
- return -EPERM;
-
- return xfs_ioc_space(bdp, vp, filp, ioflags, cmd, arg);
-
- case XFS_IOC_DIOINFO: {
- struct dioattr da;
- xfs_buftarg_t *target =
- (ip->i_d.di_flags & XFS_DIFLAG_REALTIME) ?
- mp->m_rtdev_targp : mp->m_ddev_targp;
-
- da.d_mem = da.d_miniosz = 1 << target->bt_sshift;
- da.d_maxiosz = INT_MAX & ~(da.d_miniosz - 1);
-
- if (copy_to_user(arg, &da, sizeof(da)))
- return XFS_ERROR(EFAULT);
- return 0;
- }
-
- case XFS_IOC_FSBULKSTAT_SINGLE:
- case XFS_IOC_FSBULKSTAT:
- case XFS_IOC_FSINUMBERS:
- return xfs_ioc_bulkstat(mp, cmd, arg);
-
- case XFS_IOC_FSGEOMETRY_V1:
- return xfs_ioc_fsgeometry_v1(mp, arg);
-
- case XFS_IOC_FSGEOMETRY:
- return xfs_ioc_fsgeometry(mp, arg);
-
- case XFS_IOC_GETVERSION:
- case XFS_IOC_GETXFLAGS:
- case XFS_IOC_SETXFLAGS:
- case XFS_IOC_FSGETXATTR:
- case XFS_IOC_FSSETXATTR:
- case XFS_IOC_FSGETXATTRA:
- return xfs_ioc_xattr(vp, ip, filp, cmd, arg);
-
- case XFS_IOC_FSSETDM: {
- struct fsdmidata dmi;
-
- if (copy_from_user(&dmi, arg, sizeof(dmi)))
- return XFS_ERROR(EFAULT);
-
- error = xfs_set_dmattrs(bdp, dmi.fsd_dmevmask, dmi.fsd_dmstate,
- NULL);
- return error;
- }
-
- case XFS_IOC_GETBMAP:
- case XFS_IOC_GETBMAPA:
- return xfs_ioc_getbmap(bdp, filp, ioflags, cmd, arg);
-
- case XFS_IOC_GETBMAPX:
- return xfs_ioc_getbmapx(bdp, arg);
-
- case XFS_IOC_FD_TO_HANDLE:
- case XFS_IOC_PATH_TO_HANDLE:
- case XFS_IOC_PATH_TO_FSHANDLE:
- return xfs_find_handle(cmd, arg);
-
- case XFS_IOC_OPEN_BY_HANDLE:
- return xfs_open_by_handle(mp, arg, filp, inode);
-
- case XFS_IOC_FSSETDM_BY_HANDLE:
- return xfs_fssetdm_by_handle(mp, arg, filp, inode);
-
- case XFS_IOC_READLINK_BY_HANDLE:
- return xfs_readlink_by_handle(mp, arg, filp, inode);
-
- case XFS_IOC_ATTRLIST_BY_HANDLE:
- return xfs_attrlist_by_handle(mp, arg, filp, inode);
-
- case XFS_IOC_ATTRMULTI_BY_HANDLE:
- return xfs_attrmulti_by_handle(mp, arg, filp, inode);
-
- case XFS_IOC_SWAPEXT: {
- error = xfs_swapext((struct xfs_swapext __user *)arg);
- return error;
- }
-
- case XFS_IOC_FSCOUNTS: {
- xfs_fsop_counts_t out;
-
- error = xfs_fs_counts(mp, &out);
- if (error)
- return error;
-
- if (copy_to_user(arg, &out, sizeof(out)))
- return XFS_ERROR(EFAULT);
- return 0;
- }
-
- case XFS_IOC_SET_RESBLKS: {
- xfs_fsop_resblks_t inout;
- __uint64_t in;
-
- if (!capable(CAP_SYS_ADMIN))
- return EPERM;
-
- if (copy_from_user(&inout, arg, sizeof(inout)))
- return XFS_ERROR(EFAULT);
-
- /* input parameter is passed in resblks field of structure */
- in = inout.resblks;
- error = xfs_reserve_blocks(mp, &in, &inout);
- if (error)
- return error;
-
- if (copy_to_user(arg, &inout, sizeof(inout)))
- return XFS_ERROR(EFAULT);
- return 0;
- }
-
- case XFS_IOC_GET_RESBLKS: {
- xfs_fsop_resblks_t out;
-
- if (!capable(CAP_SYS_ADMIN))
- return EPERM;
-
- error = xfs_reserve_blocks(mp, NULL, &out);
- if (error)
- return error;
-
- if (copy_to_user(arg, &out, sizeof(out)))
- return XFS_ERROR(EFAULT);
-
- return 0;
- }
-
- case XFS_IOC_FSGROWFSDATA: {
- xfs_growfs_data_t in;
-
- if (!capable(CAP_SYS_ADMIN))
- return EPERM;
-
- if (copy_from_user(&in, arg, sizeof(in)))
- return XFS_ERROR(EFAULT);
-
- error = xfs_growfs_data(mp, &in);
- return error;
- }
-
- case XFS_IOC_FSGROWFSLOG: {
- xfs_growfs_log_t in;
-
- if (!capable(CAP_SYS_ADMIN))
- return EPERM;
-
- if (copy_from_user(&in, arg, sizeof(in)))
- return XFS_ERROR(EFAULT);
-
- error = xfs_growfs_log(mp, &in);
- return error;
- }
-
- case XFS_IOC_FSGROWFSRT: {
- xfs_growfs_rt_t in;
-
- if (!capable(CAP_SYS_ADMIN))
- return EPERM;
-
- if (copy_from_user(&in, arg, sizeof(in)))
- return XFS_ERROR(EFAULT);
-
- error = xfs_growfs_rt(mp, &in);
- return error;
- }
-#if 0
- case XFS_IOC_FREEZE:
- if (!capable(CAP_SYS_ADMIN))
- return -EPERM;
- xfs_fs_freeze(mp);
- return 0;
-
- case XFS_IOC_THAW:
- if (!capable(CAP_SYS_ADMIN))
- return -EPERM;
- xfs_fs_thaw(mp);
- return 0;
-#endif
-
- case XFS_IOC_GOINGDOWN: {
- __uint32_t in;
-
- if (!capable(CAP_SYS_ADMIN))
- return EPERM;
-
- if (copy_from_user(&in, arg, sizeof(__uint32_t)))
- return XFS_ERROR(EFAULT);
-
- error = xfs_fs_goingdown(mp, in);
- return error;
- }
-
- case XFS_IOC_ERROR_INJECTION: {
- xfs_error_injection_t in;
-
- if (!capable(CAP_SYS_ADMIN))
- return EPERM;
-
- if (copy_from_user(&in, arg, sizeof(in)))
- return XFS_ERROR(EFAULT);
-
- error = xfs_errortag_add(in.errtag, mp);
- return error;
- }
-
- case XFS_IOC_ERROR_CLEARALL:
- if (!capable(CAP_SYS_ADMIN))
- return EPERM;
-
- error = xfs_errortag_clearall(mp);
- return error;
-
- default:
- return ENOTTY;
- }
-}
-
-STATIC int
-xfs_ioc_space(
- bhv_desc_t *bdp,
- xfs_vnode_t *vp,
- struct file *filp,
- int ioflags,
- u_long cmd,
- void __user *arg)
-{
- xfs_flock64_t bf;
- int attr_flags = 0;
- int error;
-
-#if 0
- if (vp->v_inode.i_flags & (S_IMMUTABLE|S_APPEND))
- return -XFS_ERROR(EPERM);
-
- if (!(filp->f_mode & FMODE_WRITE))
- return -XFS_ERROR(EBADF);
-#endif
-
- if (!VN_ISREG(vp))
- return -XFS_ERROR(EINVAL);
-
- if (copy_from_user(&bf, arg, sizeof(bf)))
- return -XFS_ERROR(EFAULT);
-
-#if 0
- if (filp->f_flags & (O_NDELAY|O_NONBLOCK))
- attr_flags |= ATTR_NONBLOCK;
-#endif
- if (ioflags & IO_INVIS)
- attr_flags |= ATTR_DMI;
-
- error = xfs_change_file_space(bdp, cmd,
- &bf, filp->f_offset,
- NULL, attr_flags);
- return -error;
-}
-
-STATIC int
-xfs_ioc_bulkstat(
- xfs_mount_t *mp,
- unsigned int cmd,
- void __user *arg)
-{
- xfs_fsop_bulkreq_t bulkreq;
- int count; /* # of records returned */
- xfs_ino_t inlast; /* last inode number */
- int done;
- int error;
-
- /* done = 1 if there are more stats to get and if bulkstat */
- /* should be called again (unused here, but used in dmapi) */
-
-#if 0
- if (!capable(CAP_SYS_ADMIN))
- return -EPERM;
-#endif
-
- if (XFS_FORCED_SHUTDOWN(mp))
- return -XFS_ERROR(EIO);
-
- if (copy_from_user(&bulkreq, arg, sizeof(xfs_fsop_bulkreq_t)))
- return -XFS_ERROR(EFAULT);
-
- if (copy_from_user(&inlast, bulkreq.lastip, sizeof(__s64)))
- return -XFS_ERROR(EFAULT);
-
- if ((count = bulkreq.icount) <= 0)
- return -XFS_ERROR(EINVAL);
-
- if (cmd == XFS_IOC_FSINUMBERS)
- error = xfs_inumbers(mp, &inlast, &count,
- bulkreq.ubuffer);
- else if (cmd == XFS_IOC_FSBULKSTAT_SINGLE)
- error = xfs_bulkstat_single(mp, &inlast,
- bulkreq.ubuffer, &done);
- else { /* XFS_IOC_FSBULKSTAT */
- if (count == 1 && inlast != 0) {
- inlast++;
- error = xfs_bulkstat_single(mp, &inlast,
- bulkreq.ubuffer, &done);
- } else {
- error = xfs_bulkstat(mp, &inlast, &count,
- (bulkstat_one_pf)xfs_bulkstat_one, NULL,
- sizeof(xfs_bstat_t), bulkreq.ubuffer,
- BULKSTAT_FG_QUICK, &done);
- }
- }
-
- if (error)
- return -error;
-
- if (bulkreq.ocount != NULL) {
- if (copy_to_user(bulkreq.lastip, &inlast,
- sizeof(xfs_ino_t)))
- return -XFS_ERROR(EFAULT);
-
- if (copy_to_user(bulkreq.ocount, &count, sizeof(count)))
- return -XFS_ERROR(EFAULT);
- }
-
- return 0;
-}
-
-STATIC int
-xfs_ioc_fsgeometry_v1(
- xfs_mount_t *mp,
- void __user *arg)
-{
- xfs_fsop_geom_v1_t fsgeo;
- int error;
-
- error = xfs_fs_geometry(mp, (xfs_fsop_geom_t *)&fsgeo, 3);
- if (error)
- return -error;
-
- if (copy_to_user(arg, &fsgeo, sizeof(fsgeo)))
- return -XFS_ERROR(EFAULT);
- return 0;
-}
-
-STATIC int
-xfs_ioc_fsgeometry(
- xfs_mount_t *mp,
- void __user *arg)
-{
- xfs_fsop_geom_t fsgeo;
- int error;
-
- error = xfs_fs_geometry(mp, &fsgeo, 4);
- if (error)
- goto error;
-
- printf ("xfs_ioc_fsgeometry: error? %d arg %p\n",error,arg);
-
-#if 0
- if (copy_to_user(arg, &fsgeo, sizeof(fsgeo)))
- return XFS_ERROR(EFAULT);
-#endif
- memcpy(arg, &fsgeo, sizeof(fsgeo));
-
- printf ("xfs_ioc_fsgeometry: error? %d arg %p\n",error,arg);
-error:
- return error;
-}
-
-/*
- * Linux extended inode flags interface.
- */
-#define LINUX_XFLAG_SYNC 0x00000008 /* Synchronous updates */
-#define LINUX_XFLAG_IMMUTABLE 0x00000010 /* Immutable file */
-#define LINUX_XFLAG_APPEND 0x00000020 /* writes to file may only append */
-#define LINUX_XFLAG_NODUMP 0x00000040 /* do not dump file */
-#define LINUX_XFLAG_NOATIME 0x00000080 /* do not update atime */
-
-STATIC unsigned int
-xfs_merge_ioc_xflags(
- unsigned int flags,
- unsigned int start)
-{
- unsigned int xflags = start;
-
- if (flags & LINUX_XFLAG_IMMUTABLE)
- xflags |= XFS_XFLAG_IMMUTABLE;
- else
- xflags &= ~XFS_XFLAG_IMMUTABLE;
- if (flags & LINUX_XFLAG_APPEND)
- xflags |= XFS_XFLAG_APPEND;
- else
- xflags &= ~XFS_XFLAG_APPEND;
- if (flags & LINUX_XFLAG_SYNC)
- xflags |= XFS_XFLAG_SYNC;
- else
- xflags &= ~XFS_XFLAG_SYNC;
- if (flags & LINUX_XFLAG_NOATIME)
- xflags |= XFS_XFLAG_NOATIME;
- else
- xflags &= ~XFS_XFLAG_NOATIME;
- if (flags & LINUX_XFLAG_NODUMP)
- xflags |= XFS_XFLAG_NODUMP;
- else
- xflags &= ~XFS_XFLAG_NODUMP;
-
- return xflags;
-}
-
-STATIC unsigned int
-xfs_di2lxflags(
- __uint16_t di_flags)
-{
- unsigned int flags = 0;
-
- if (di_flags & XFS_DIFLAG_IMMUTABLE)
- flags |= LINUX_XFLAG_IMMUTABLE;
- if (di_flags & XFS_DIFLAG_APPEND)
- flags |= LINUX_XFLAG_APPEND;
- if (di_flags & XFS_DIFLAG_SYNC)
- flags |= LINUX_XFLAG_SYNC;
- if (di_flags & XFS_DIFLAG_NOATIME)
- flags |= LINUX_XFLAG_NOATIME;
- if (di_flags & XFS_DIFLAG_NODUMP)
- flags |= LINUX_XFLAG_NODUMP;
- return flags;
-}
-
-STATIC int
-xfs_ioc_xattr(
- xfs_vnode_t *vp,
- xfs_inode_t *ip,
- struct file *filp,
- unsigned int cmd,
- void __user *arg)
-{
- struct fsxattr fa;
- struct xfs_vattr *vattr;
- int error;
- int attr_flags;
- unsigned int flags;
-
- error = 0;
- attr_flags = 0;
-
- vattr = kmem_alloc(sizeof(struct xfs_vattr), KM_SLEEP);
- if (unlikely(!vattr))
- return ENOMEM;
-
- switch (cmd) {
- case XFS_IOC_FSGETXATTR: {
- vattr->va_mask = XFS_AT_XFLAGS | XFS_AT_EXTSIZE | \
- XFS_AT_NEXTENTS | XFS_AT_PROJID;
- XVOP_GETATTR(vp, vattr, 0, NULL, error);
- if (unlikely(error)) {
- break;
- }
-
- fa.fsx_xflags = vattr->va_xflags;
- fa.fsx_extsize = vattr->va_extsize;
- fa.fsx_nextents = vattr->va_nextents;
- fa.fsx_projid = vattr->va_projid;
-
- if (copy_to_user(arg, &fa, sizeof(fa))) {
- error = EFAULT;
- break;
- }
- break;
- }
-
- case XFS_IOC_FSSETXATTR: {
- if (copy_from_user(&fa, arg, sizeof(fa))) {
- error = EFAULT;
- break;
- }
-
- attr_flags = 0;
-#if 0
- if (filp->f_flags & (O_NDELAY|O_NONBLOCK))
- attr_flags |= ATTR_NONBLOCK;
-#endif
-
- vattr->va_mask = XFS_AT_XFLAGS | XFS_AT_EXTSIZE | XFS_AT_PROJID;
- vattr->va_xflags = fa.fsx_xflags;
- vattr->va_extsize = fa.fsx_extsize;
- vattr->va_projid = fa.fsx_projid;
-
- XVOP_SETATTR(vp, vattr, attr_flags, NULL, error);
-#if 0
- if (likely(!error))
- __vn_revalidate(vp, vattr); /* update flags */
-#endif
- break;
- }
-
- case XFS_IOC_FSGETXATTRA: {
- vattr->va_mask = XFS_AT_XFLAGS | XFS_AT_EXTSIZE | \
- XFS_AT_ANEXTENTS | XFS_AT_PROJID;
- XVOP_GETATTR(vp, vattr, 0, NULL, error);
- if (unlikely(error)) {
- break;
- }
-
- fa.fsx_xflags = vattr->va_xflags;
- fa.fsx_extsize = vattr->va_extsize;
- fa.fsx_nextents = vattr->va_anextents;
- fa.fsx_projid = vattr->va_projid;
-
- if (copy_to_user(arg, &fa, sizeof(fa))) {
- error = EFAULT;
- break;
- }
- break;
- }
-
- case XFS_IOC_GETXFLAGS: {
- flags = xfs_di2lxflags(ip->i_d.di_flags);
- if (copy_to_user(arg, &flags, sizeof(flags)))
- error = EFAULT;
- break;
- }
-
- case XFS_IOC_SETXFLAGS: {
- if (copy_from_user(&flags, arg, sizeof(flags))) {
- error = EFAULT;
- break;
- }
-
- if (flags & ~(LINUX_XFLAG_IMMUTABLE | LINUX_XFLAG_APPEND | \
- LINUX_XFLAG_NOATIME | LINUX_XFLAG_NODUMP | \
- LINUX_XFLAG_SYNC)) {
- error = EOPNOTSUPP;
- break;
- }
-
-#if 0
- attr_flags = 0;
- if (filp->f_flags & (O_NDELAY|O_NONBLOCK))
- attr_flags |= ATTR_NONBLOCK;
-#endif
-
- vattr->va_mask = XFS_AT_XFLAGS;
- vattr->va_xflags = xfs_merge_ioc_xflags(flags,
- xfs_ip2xflags(ip));
-
- XVOP_SETATTR(vp, vattr, attr_flags, NULL, error);
-#if 0
- if (likely(!error))
- __vn_revalidate(vp, vattr); /* update flags */
-#endif
- break;
- }
-
-#if 0
- case XFS_IOC_GETVERSION: {
- flags = vn_to_inode(vp)->i_generation;
- if (copy_to_user(arg, &flags, sizeof(flags)))
- error = EFAULT;
- break;
- }
-#endif
-
- default:
- error = ENOTTY;
- break;
- }
-
- kmem_free(vattr,sizeof(struct xfs_vattr));
- return error;
-}
-
-STATIC int
-xfs_ioc_getbmap(
- bhv_desc_t *bdp,
- struct file *filp,
- int ioflags,
- unsigned int cmd,
- void __user *arg)
-{
- struct getbmap bm;
- int iflags;
- int error;
-
- if (copy_from_user(&bm, arg, sizeof(bm)))
- return -XFS_ERROR(EFAULT);
-
- if (bm.bmv_count < 2)
- return -XFS_ERROR(EINVAL);
-
- iflags = (cmd == XFS_IOC_GETBMAPA ? BMV_IF_ATTRFORK : 0);
- if (ioflags & IO_INVIS)
- iflags |= BMV_IF_NO_DMAPI_READ;
-
- error = xfs_getbmap(bdp, &bm, (struct getbmap __user *)arg+1, iflags);
- if (error)
- return -error;
-
- if (copy_to_user(arg, &bm, sizeof(bm)))
- return -XFS_ERROR(EFAULT);
- return 0;
-}
-
-STATIC int
-xfs_ioc_getbmapx(
- bhv_desc_t *bdp,
- void __user *arg)
-{
- struct getbmapx bmx;
- struct getbmap bm;
- int iflags;
- int error;
-
- printf("%s:%d\n",__FILE__,__LINE__);
- if (copy_from_user(&bmx, arg, sizeof(bmx)))
- return XFS_ERROR(EFAULT);
-
- printf("%s:%d\n",__FILE__,__LINE__);
- if (bmx.bmv_count < 2)
- return XFS_ERROR(EINVAL);
-
- /*
- * Map input getbmapx structure to a getbmap
- * structure for xfs_getbmap.
- */
- GETBMAP_CONVERT(bmx, bm);
-
- iflags = bmx.bmv_iflags;
-
- if (iflags & (~BMV_IF_VALID))
- return XFS_ERROR(EINVAL);
-
- iflags |= BMV_IF_EXTENDED;
-
- printf("%s:%d arg+1 %p arg %p\n",__FILE__,__LINE__,(struct getbmapx __user *)arg+1,arg);
- error = xfs_getbmap(bdp, &bm, (struct getbmapx __user *)arg+1, iflags);
- if (error)
- return error;
-
- printf("%s:%d\n",__FILE__,__LINE__);
- GETBMAP_CONVERT(bm, bmx);
-
- printf("%s:%d\n",__FILE__,__LINE__);
- if (copy_to_user(arg, &bmx, sizeof(bmx)))
- return XFS_ERROR(EFAULT);
-
- printf("%s:%d\n",__FILE__,__LINE__);
- return 0;
-}
-
-#else
-
-int
-xfs_ioctl(
- bhv_desc_t *bdp,
- struct inode *inode,
- struct file *filp,
- int ioflags,
- u_long cmd,
- unsigned long arg)
-{
- return EINVAL;
-}
-
-#endif
diff --git a/sys/gnu/fs/xfs/FreeBSD/xfs_iops.h b/sys/gnu/fs/xfs/FreeBSD/xfs_iops.h
deleted file mode 100644
index 8f585b6..0000000
--- a/sys/gnu/fs/xfs/FreeBSD/xfs_iops.h
+++ /dev/null
@@ -1,61 +0,0 @@
-/*
- * Copyright (c) 2000-2002 Silicon Graphics, Inc. All Rights Reserved.
- *
- * This program 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.
- *
- * This program is distributed in the hope that it would be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
- *
- * Further, this software is distributed without any warranty that it is
- * free of the rightful claim of any third person regarding infringement
- * or the like. Any license provided herein, whether implied or
- * otherwise, applies only to this software file. Patent licenses, if
- * any, provided herein do not apply to combinations of this program with
- * other software, or any other product whatsoever.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write the Free Software Foundation, Inc., 59
- * Temple Place - Suite 330, Boston MA 02111-1307, USA.
- *
- * Contact information: Silicon Graphics, Inc., 1600 Amphitheatre Pkwy,
- * Mountain View, CA 94043, or:
- *
- * http://www.sgi.com
- *
- * For further information regarding this notice, see:
- *
- * http://oss.sgi.com/projects/GenInfo/SGIGPLNoticeExplan/
- */
-#ifndef __XFS_IOPS_H__
-#define __XFS_IOPS_H__
-
-/*
- * Extended system attributes.
- * So far only POSIX ACLs are supported, but this will need to
- * grow in time (capabilities, mandatory access control, etc).
- */
-#define XFS_SYSTEM_NAMESPACE SYSTEM_POSIXACL
-
-/*
- * Define a table of the namespaces XFS supports
- */
-typedef int (*xattr_exists_t)(xfs_vnode_t *);
-
-typedef struct xattr_namespace {
- char *name;
- unsigned int namelen;
- xattr_exists_t exists;
-} xattr_namespace_t;
-
-#define SYSTEM_NAMES 0
-#define ROOT_NAMES 1
-#define USER_NAMES 2
-extern struct xattr_namespace *xfs_namespaces;
-
-extern int xfs_ioctl(struct bhv_desc *, struct inode *, struct file *,
- int, u_long, void *);
-
-#endif /* __XFS_IOPS_H__ */
diff --git a/sys/gnu/fs/xfs/FreeBSD/xfs_mountops.c b/sys/gnu/fs/xfs/FreeBSD/xfs_mountops.c
deleted file mode 100644
index 8597c6c..0000000
--- a/sys/gnu/fs/xfs/FreeBSD/xfs_mountops.c
+++ /dev/null
@@ -1,500 +0,0 @@
-/*
- * Copyright (c) 2001,2006 Alexander Kabaev, Russell Cattelan Digital Elves Inc.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * $FreeBSD$
- */
-
-#include <sys/param.h>
-#include <sys/systm.h>
-#include <sys/kernel.h>
-#include <sys/proc.h>
-#include <sys/malloc.h>
-#include <sys/vnode.h>
-#include <sys/mount.h>
-#include <sys/namei.h>
-
-#include <geom/geom.h>
-#include <geom/geom_vfs.h>
-
-#include "xfs.h"
-#include "xfs_types.h"
-#include "xfs_bit.h"
-#include "xfs_inum.h"
-#include "xfs_log.h"
-#include "xfs_trans.h"
-#include "xfs_sb.h"
-#include "xfs_ag.h"
-#include "xfs_dir.h"
-#include "xfs_dir2.h"
-#include "xfs_dmapi.h"
-#include "xfs_mount.h"
-#include "xfs_alloc_btree.h"
-#include "xfs_bmap_btree.h"
-#include "xfs_ialloc_btree.h"
-#include "xfs_btree.h"
-#include "xfs_attr_sf.h"
-#include "xfs_dir_sf.h"
-#include "xfs_dir2_sf.h"
-#include "xfs_dinode.h"
-#include "xfs_ialloc.h"
-#include "xfs_inode.h"
-#include "xfs_alloc.h"
-#include "xfs_rtalloc.h"
-#include "xfs_bmap.h"
-#include "xfs_error.h"
-#include "xfs_rw.h"
-#include "xfs_quota.h"
-#include "xfs_fsops.h"
-#include "xfs_clnt.h"
-
-#include <xfs_mountops.h>
-
-static MALLOC_DEFINE(M_XFSNODE, "XFS node", "XFS vnode private part");
-
-static vfs_mount_t _xfs_mount;
-static vfs_unmount_t _xfs_unmount;
-static vfs_root_t _xfs_root;
-static vfs_quotactl_t _xfs_quotactl;
-static vfs_statfs_t _xfs_statfs;
-static vfs_sync_t _xfs_sync;
-static vfs_vget_t _xfs_vget;
-static vfs_fhtovp_t _xfs_fhtovp;
-static vfs_init_t _xfs_init;
-static vfs_uninit_t _xfs_uninit;
-static vfs_extattrctl_t _xfs_extattrctl;
-
-static b_strategy_t xfs_geom_strategy;
-
-static const char *xfs_opts[] =
- { "from", "flags", "logbufs", "logbufsize",
- "rtname", "logname", "iosizelog", "sunit",
- "swidth", "export",
- NULL };
-
-static void
-parse_int(struct mount *mp, const char *opt, int *val, int *error)
-{
- char *tmp, *ep;
-
- tmp = vfs_getopts(mp->mnt_optnew, opt, error);
- if (*error != 0) {
- return;
- }
- if (tmp != NULL) {
- *val = (int)strtol(tmp, &ep, 10);
- if (*ep) {
- *error = EINVAL;
- return;
- }
- }
-}
-
-static int
-_xfs_param_copyin(struct mount *mp, struct thread *td)
-{
- struct xfsmount *xmp = MNTTOXFS(mp);
- struct xfs_mount_args *args = &xmp->m_args;
- char *path;
- char *fsname;
- char *rtname;
- char *logname;
- int error;
-
- path = vfs_getopts(mp->mnt_optnew, "fspath", &error);
- if (error)
- return (error);
-
- bzero(args, sizeof(struct xfs_mount_args));
- args->logbufs = -1;
- args->logbufsize = -1;
-
- parse_int(mp, "flags", &args->flags, &error);
- if (error != 0 && error != ENOENT)
- return error;
-
- args->flags |= XFSMNT_32BITINODES;
-
- parse_int(mp, "sunit", &args->sunit, &error);
- if (error != 0 && error != ENOENT)
- return error;
-
- parse_int(mp, "swidth", &args->swidth, &error);
- if (error != 0 && error != ENOENT)
- return error;
-
- parse_int(mp, "logbufs", &args->logbufs, &error);
- if (error != 0 && error != ENOENT)
- return error;
-
- parse_int(mp, "logbufsize", &args->logbufsize, &error);
- if (error != 0 && error != ENOENT)
- return error;
-
- fsname = vfs_getopts(mp->mnt_optnew, "from", &error);
- if (error == 0 && fsname != NULL) {
- strncpy(args->fsname, fsname, sizeof(args->fsname) - 1);
- }
-
- logname = vfs_getopts(mp->mnt_optnew, "logname", &error);
- if (error == 0 && logname != NULL) {
- strncpy(args->logname, logname, sizeof(args->logname) - 1);
- }
-
- rtname = vfs_getopts(mp->mnt_optnew, "rtname", &error);
- if (error == 0 && rtname != NULL) {
- strncpy(args->rtname, rtname, sizeof(args->rtname) - 1);
- }
-
- strncpy(args->mtpt, path, sizeof(args->mtpt));
-
- printf("fsname '%s' logname '%s' rtname '%s'\n"
- "flags 0x%x sunit %d swidth %d logbufs %d logbufsize %d\n",
- args->fsname, args->logname, args->rtname, args->flags,
- args->sunit, args->swidth, args->logbufs, args->logbufsize);
-
- vfs_mountedfrom(mp, args->fsname);
-
- return (0);
-}
-
-static int
-_xfs_mount(struct mount *mp)
-{
- struct xfsmount *xmp;
- struct xfs_vnode *rootvp;
- struct ucred *curcred;
- struct vnode *rvp, *devvp;
- struct cdev *ddev;
- struct g_consumer *cp;
- struct thread *td;
- int error;
-
- td = curthread;
- ddev = NULL;
- cp = NULL;
-
- if (vfs_filteropt(mp->mnt_optnew, xfs_opts))
- return (EINVAL);
-
- if (mp->mnt_flag & MNT_UPDATE)
- return (0);
- if ((mp->mnt_flag & MNT_RDONLY) == 0)
- return (EPERM);
-
- xmp = xfsmount_allocate(mp);
- if (xmp == NULL)
- return (ENOMEM);
-
- if((error = _xfs_param_copyin(mp, td)) != 0)
- goto fail;
-
- curcred = td->td_ucred;
- XVFS_MOUNT(XFSTOVFS(xmp), &xmp->m_args, curcred, error);
- if (error)
- goto fail;
-
- XVFS_ROOT(XFSTOVFS(xmp), &rootvp, error);
- ddev = XFS_VFSTOM(XFSTOVFS(xmp))->m_ddev_targp->dev;
- devvp = XFS_VFSTOM(XFSTOVFS(xmp))->m_ddev_targp->specvp;
- if (error)
- goto fail_unmount;
-
- if (ddev->si_iosize_max != 0)
- mp->mnt_iosize_max = ddev->si_iosize_max;
- if (mp->mnt_iosize_max > MAXPHYS)
- mp->mnt_iosize_max = MAXPHYS;
-
- mp->mnt_flag |= MNT_LOCAL;
- mp->mnt_stat.f_fsid.val[0] = dev2udev(ddev);
- mp->mnt_stat.f_fsid.val[1] = mp->mnt_vfc->vfc_typenum;
-
- if ((error = VFS_STATFS(mp, &mp->mnt_stat)) != 0)
- goto fail_unmount;
-
- rvp = rootvp->v_vnode;
- rvp->v_vflag |= VV_ROOT;
- VN_RELE(rootvp);
-
- return (0);
-
- fail_unmount:
- XVFS_UNMOUNT(XFSTOVFS(xmp), 0, curcred, error);
-
- if (devvp != NULL) {
- cp = devvp->v_bufobj.bo_private;
- if (cp != NULL) {
- DROP_GIANT();
- g_topology_lock();
- g_vfs_close(cp);
- g_topology_unlock();
- PICKUP_GIANT();
- }
- }
-
- fail:
- if (xmp != NULL)
- xfsmount_deallocate(xmp);
-
- return (error);
-}
-
-/*
- * Free reference to null layer
- */
-static int
-_xfs_unmount(mp, mntflags)
- struct mount *mp;
- int mntflags;
-{
- struct vnode *devvp;
- struct g_consumer *cp;
- int error;
- cp = NULL;
- devvp = NULL;
-
- devvp = XFS_VFSTOM((MNTTOVFS(mp)))->m_ddev_targp->specvp;
- if (devvp != NULL)
- cp = devvp->v_bufobj.bo_private;
-
- XVFS_UNMOUNT(MNTTOVFS(mp), 0, curthread->td_ucred, error);
- if (error == 0) {
- if (cp != NULL) {
- DROP_GIANT();
- g_topology_lock();
- g_vfs_close(cp);
- g_topology_unlock();
- PICKUP_GIANT();
- }
- }
- return (error);
-}
-
-static int
-_xfs_root(mp, flags, vpp)
- struct mount *mp;
- int flags;
- struct vnode **vpp;
-{
- xfs_vnode_t *vp;
- int error;
-
- XVFS_ROOT(MNTTOVFS(mp), &vp, error);
- if (error == 0) {
- *vpp = vp->v_vnode;
- VOP_LOCK(*vpp, flags);
- }
- return (error);
-}
-
-static int
-_xfs_quotactl(mp, cmd, uid, arg)
- struct mount *mp;
- int cmd;
- uid_t uid;
- void *arg;
-{
- printf("xfs_quotactl\n");
- return EOPNOTSUPP;
-}
-
-static int
-_xfs_statfs(mp, sbp)
- struct mount *mp;
- struct statfs *sbp;
-{
- int error;
-
- XVFS_STATVFS(MNTTOVFS(mp), sbp, NULL, error);
- if (error)
- return error;
-
- /* Fix up the values XFS statvfs calls does not know about. */
- sbp->f_iosize = sbp->f_bsize;
-
- return (error);
-}
-
-static int
-_xfs_sync(mp, waitfor)
- struct mount *mp;
- int waitfor;
-{
- int error;
- int flags = SYNC_FSDATA|SYNC_ATTR|SYNC_REFCACHE;
-
- if (waitfor == MNT_WAIT)
- flags |= SYNC_WAIT;
- else if (waitfor == MNT_LAZY)
- flags |= SYNC_BDFLUSH;
- XVFS_SYNC(MNTTOVFS(mp), flags, curthread->td_ucred, error);
- return (error);
-}
-
-static int
-_xfs_vget(mp, ino, flags, vpp)
- struct mount *mp;
- ino_t ino;
- int flags;
- struct vnode **vpp;
-{
- xfs_vnode_t *vp = NULL;
- int error;
-
- printf("XVFS_GET_VNODE(MNTTOVFS(mp), &vp, ino, error);\n");
- error = ENOSYS;
- if (error == 0)
- *vpp = vp->v_vnode;
- return (error);
-}
-
-static int
-_xfs_fhtovp(mp, fidp, flags, vpp)
- struct mount *mp;
- struct fid *fidp;
- int flags;
- struct vnode **vpp;
-{
- printf("xfs_fhtovp\n");
- return ENOSYS;
-}
-
-static int
-_xfs_extattrctl(struct mount *mp, int cm,
- struct vnode *filename_v,
- int attrnamespace, const char *attrname)
-{
- printf("xfs_extattrctl\n");
- return ENOSYS;
-}
-
-int
-_xfs_init(vfsp)
- struct vfsconf *vfsp;
-{
- int error;
-
- error = init_xfs_fs();
-
- return (error);
-}
-
-int
-_xfs_uninit(vfsp)
- struct vfsconf *vfsp;
-{
- exit_xfs_fs();
- return 0;
-}
-
-static struct vfsops xfs_fsops = {
- .vfs_mount = _xfs_mount,
- .vfs_unmount = _xfs_unmount,
- .vfs_root = _xfs_root,
- .vfs_quotactl = _xfs_quotactl,
- .vfs_statfs = _xfs_statfs,
- .vfs_sync = _xfs_sync,
- .vfs_vget = _xfs_vget,
- .vfs_fhtovp = _xfs_fhtovp,
- .vfs_init = _xfs_init,
- .vfs_uninit = _xfs_uninit,
- .vfs_extattrctl = _xfs_extattrctl,
-};
-
-VFS_SET(xfs_fsops, xfs, VFCF_READONLY);
-
-/*
- * Copy GEOM VFS functions here to provide a conveniet place to
- * track all XFS-related IO without being distracted by other
- * filesystems which happen to be mounted on the machine at the
- * same time.
- */
-
-static void
-xfs_geom_biodone(struct bio *bip)
-{
- struct buf *bp;
-
- if (bip->bio_error) {
- printf("g_vfs_done():");
- g_print_bio(bip);
- printf("error = %d\n", bip->bio_error);
- }
- bp = bip->bio_caller2;
- bp->b_error = bip->bio_error;
- bp->b_ioflags = bip->bio_flags;
- if (bip->bio_error)
- bp->b_ioflags |= BIO_ERROR;
- bp->b_resid = bp->b_bcount - bip->bio_completed;
- g_destroy_bio(bip);
- mtx_lock(&Giant);
- bufdone(bp);
- mtx_unlock(&Giant);
-}
-
-static void
-xfs_geom_strategy(struct bufobj *bo, struct buf *bp)
-{
- struct g_consumer *cp;
- struct bio *bip;
-
- cp = bo->bo_private;
- G_VALID_CONSUMER(cp);
-
- bip = g_alloc_bio();
- bip->bio_cmd = bp->b_iocmd;
- bip->bio_offset = bp->b_iooffset;
- bip->bio_data = bp->b_data;
- bip->bio_done = xfs_geom_biodone;
- bip->bio_caller2 = bp;
- bip->bio_length = bp->b_bcount;
- g_io_request(bip, cp);
-}
-
-static int
-xfs_geom_bufwrite(struct buf *bp)
-{
- return bufwrite(bp);
-}
-
-static int
-xfs_geom_bufsync(struct bufobj *bo, int waitfor)
-{
-
- return (bufsync(bo, waitfor));
-}
-
-static void
-xfs_geom_bufbdflush(struct bufobj *bo, struct buf *bp)
-{
- bufbdflush(bo, bp);
-}
-
-struct buf_ops xfs_bo_ops = {
- .bop_name = "XFS",
- .bop_write = xfs_geom_bufwrite,
- .bop_strategy = xfs_geom_strategy,
- .bop_sync = xfs_geom_bufsync,
- .bop_bdflush = xfs_geom_bufbdflush,
-};
diff --git a/sys/gnu/fs/xfs/FreeBSD/xfs_mountops.h b/sys/gnu/fs/xfs/FreeBSD/xfs_mountops.h
deleted file mode 100644
index c8a766d..0000000
--- a/sys/gnu/fs/xfs/FreeBSD/xfs_mountops.h
+++ /dev/null
@@ -1,59 +0,0 @@
-/*-
- * Copyright (c) 2001 Alexander Kabaev
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * $FreeBSD$
- */
-#ifndef _XFS_XFS_H_
-#define _XFS_XFS_H_
-
-#define XFSFS_VMAJOR 0
-#define XFS_VMINOR 1
-#define XFS_VERSION ((XFS_VMAJOR << 16) | XFS_VMINOR)
-#define XFS_NAME "xfs"
-
-#ifdef _KERNEL
-
-struct xfsmount {
- struct xfs_mount_args m_args; /* Mount parameters */
- struct mount * m_mp; /* Back pointer */
- xfs_vfs_t m_vfs; /* SHOULD BE FIRST */
-};
-
-#define XFSTOMNT(xmp) ((xmp)->m_mp)
-#define XFSTOVFS(xmp) (&(xmp)->m_vfs)
-
-#define MNTTOXFS(mp) ((struct xfsmount *)((mp)->mnt_data))
-#define MNTTOVFS(mp) XFSTOVFS(MNTTOXFS(mp))
-
-#define VFSTOMNT(vfsp) (vfsp)->vfs_mp
-#define VFSTOXFS(vfsp) MNTTOXFS(VFSTOMNT(vfsp))
-
-struct xfsmount *xfsmount_allocate(struct mount *mp);
-void xfsmount_deallocate(struct xfsmount *xmp);
-
-#endif /* _KERNEL */
-
-#endif /* _XFS_XFS_H*/
-
diff --git a/sys/gnu/fs/xfs/FreeBSD/xfs_node.h b/sys/gnu/fs/xfs/FreeBSD/xfs_node.h
deleted file mode 100644
index d8b613c..0000000
--- a/sys/gnu/fs/xfs/FreeBSD/xfs_node.h
+++ /dev/null
@@ -1,16 +0,0 @@
-#ifndef __XFS_NODE_H__
-#define __XFS_NODE_H__
-
-/*
- * Save one allocation on FreeBSD and always allocate both inode and
- * xfs_vnode struct as a single memory block.
- */
-struct xfs_node
-{
- struct xfs_inode n_inode;
- struct xfs_vnode n_vnode;
-};
-
-#define XFS_CAST_IP2VP(ip) (&((struct xfs_node *)(ip))->n_vnode)
-
-#endif /* __XFS_NODE_H__ */
diff --git a/sys/gnu/fs/xfs/FreeBSD/xfs_stats.c b/sys/gnu/fs/xfs/FreeBSD/xfs_stats.c
deleted file mode 100644
index 40b3056..0000000
--- a/sys/gnu/fs/xfs/FreeBSD/xfs_stats.c
+++ /dev/null
@@ -1,105 +0,0 @@
-/*
- * Copyright (c) 2000-2003 Silicon Graphics, Inc. All Rights Reserved.
- *
- * This program 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.
- *
- * This program is distributed in the hope that it would be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
- *
- * Further, this software is distributed without any warranty that it is
- * free of the rightful claim of any third person regarding infringement
- * or the like. Any license provided herein, whether implied or
- * otherwise, applies only to this software file. Patent licenses, if
- * any, provided herein do not apply to combinations of this program with
- * other software, or any other product whatsoever.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write the Free Software Foundation, Inc., 59
- * Temple Place - Suite 330, Boston MA 02111-1307, USA.
- *
- * Contact information: Silicon Graphics, Inc., 1600 Amphitheatre Pkwy,
- * Mountain View, CA 94043, or:
- *
- * http://www.sgi.com
- *
- * For further information regarding this notice, see:
- *
- * http://oss.sgi.com/projects/GenInfo/SGIGPLNoticeExplan/
- */
-
-#include "xfs.h"
-
-struct xfsstats xfsstats;
-
-STATIC int
-xfs_read_xfsstats(
- char *buffer,
- char **start,
- off_t offset,
- int count,
- int *eof,
- void *data)
-{
- int i, j, len;
- static struct xstats_entry {
- char *desc;
- int endpoint;
- } xstats[] = {
- { "extent_alloc", XFSSTAT_END_EXTENT_ALLOC },
- { "abt", XFSSTAT_END_ALLOC_BTREE },
- { "blk_map", XFSSTAT_END_BLOCK_MAPPING },
- { "bmbt", XFSSTAT_END_BLOCK_MAP_BTREE },
- { "dir", XFSSTAT_END_DIRECTORY_OPS },
- { "trans", XFSSTAT_END_TRANSACTIONS },
- { "ig", XFSSTAT_END_INODE_OPS },
- { "log", XFSSTAT_END_LOG_OPS },
- { "push_ail", XFSSTAT_END_TAIL_PUSHING },
- { "xstrat", XFSSTAT_END_WRITE_CONVERT },
- { "rw", XFSSTAT_END_READ_WRITE_OPS },
- { "attr", XFSSTAT_END_ATTRIBUTE_OPS },
- { "icluster", XFSSTAT_END_INODE_CLUSTER },
- { "vnodes", XFSSTAT_END_VNODE_OPS },
- };
-
- for (i=j=len = 0; i < sizeof(xstats)/sizeof(struct xstats_entry); i++) {
- len += sprintf(buffer + len, "%s", xstats[i].desc);
- /* inner loop does each group */
- while (j < xstats[i].endpoint) {
- len += sprintf(buffer + len, " %u",
- *(((__u32*)&xfsstats) + j));
- j++;
- }
- buffer[len++] = '\n';
- }
- /* extra precision counters */
- len += sprintf(buffer + len, "xpc %ju %ju %ju\n",
- (uintmax_t)xfsstats.xs_xstrat_bytes,
- (uintmax_t)xfsstats.xs_write_bytes,
- (uintmax_t)xfsstats.xs_read_bytes);
-
- if (offset >= len) {
- *start = buffer;
- *eof = 1;
- return 0;
- }
- *start = buffer + offset;
- if ((len -= offset) > count)
- return count;
- *eof = 1;
-
- return len;
-}
-
-void
-xfs_init_procfs(void)
-{
- if (&xfs_read_xfsstats != NULL);
-}
-
-void
-xfs_cleanup_procfs(void)
-{
-}
diff --git a/sys/gnu/fs/xfs/FreeBSD/xfs_stats.h b/sys/gnu/fs/xfs/FreeBSD/xfs_stats.h
deleted file mode 100644
index 04ddc95..0000000
--- a/sys/gnu/fs/xfs/FreeBSD/xfs_stats.h
+++ /dev/null
@@ -1,161 +0,0 @@
-/*
- * Copyright (c) 2000 Silicon Graphics, Inc. All Rights Reserved.
- *
- * This program 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.
- *
- * This program is distributed in the hope that it would be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
- *
- * Further, this software is distributed without any warranty that it is
- * free of the rightful claim of any third person regarding infringement
- * or the like. Any license provided herein, whether implied or
- * otherwise, applies only to this software file. Patent licenses, if
- * any, provided herein do not apply to combinations of this program with
- * other software, or any other product whatsoever.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write the Free Software Foundation, Inc., 59
- * Temple Place - Suite 330, Boston MA 02111-1307, USA.
- *
- * Contact information: Silicon Graphics, Inc., 1600 Amphitheatre Pkwy,
- * Mountain View, CA 94043, or:
- *
- * http://www.sgi.com
- *
- * For further information regarding this notice, see:
- *
- * http://oss.sgi.com/projects/GenInfo/SGIGPLNoticeExplan/
- */
-#ifndef __XFS_STATS_H__
-#define __XFS_STATS_H__
-
-
-#if !defined(XFS_STATS_OFF)
-
-/*
- * XFS global statistics
- */
-struct xfsstats {
-# define XFSSTAT_END_EXTENT_ALLOC 4
- __uint32_t xs_allocx;
- __uint32_t xs_allocb;
- __uint32_t xs_freex;
- __uint32_t xs_freeb;
-# define XFSSTAT_END_ALLOC_BTREE (XFSSTAT_END_EXTENT_ALLOC+4)
- __uint32_t xs_abt_lookup;
- __uint32_t xs_abt_compare;
- __uint32_t xs_abt_insrec;
- __uint32_t xs_abt_delrec;
-# define XFSSTAT_END_BLOCK_MAPPING (XFSSTAT_END_ALLOC_BTREE+7)
- __uint32_t xs_blk_mapr;
- __uint32_t xs_blk_mapw;
- __uint32_t xs_blk_unmap;
- __uint32_t xs_add_exlist;
- __uint32_t xs_del_exlist;
- __uint32_t xs_look_exlist;
- __uint32_t xs_cmp_exlist;
-# define XFSSTAT_END_BLOCK_MAP_BTREE (XFSSTAT_END_BLOCK_MAPPING+4)
- __uint32_t xs_bmbt_lookup;
- __uint32_t xs_bmbt_compare;
- __uint32_t xs_bmbt_insrec;
- __uint32_t xs_bmbt_delrec;
-# define XFSSTAT_END_DIRECTORY_OPS (XFSSTAT_END_BLOCK_MAP_BTREE+4)
- __uint32_t xs_dir_lookup;
- __uint32_t xs_dir_create;
- __uint32_t xs_dir_remove;
- __uint32_t xs_dir_getdents;
-# define XFSSTAT_END_TRANSACTIONS (XFSSTAT_END_DIRECTORY_OPS+3)
- __uint32_t xs_trans_sync;
- __uint32_t xs_trans_async;
- __uint32_t xs_trans_empty;
-# define XFSSTAT_END_INODE_OPS (XFSSTAT_END_TRANSACTIONS+7)
- __uint32_t xs_ig_attempts;
- __uint32_t xs_ig_found;
- __uint32_t xs_ig_frecycle;
- __uint32_t xs_ig_missed;
- __uint32_t xs_ig_dup;
- __uint32_t xs_ig_reclaims;
- __uint32_t xs_ig_attrchg;
-# define XFSSTAT_END_LOG_OPS (XFSSTAT_END_INODE_OPS+5)
- __uint32_t xs_log_writes;
- __uint32_t xs_log_blocks;
- __uint32_t xs_log_noiclogs;
- __uint32_t xs_log_force;
- __uint32_t xs_log_force_sleep;
-# define XFSSTAT_END_TAIL_PUSHING (XFSSTAT_END_LOG_OPS+10)
- __uint32_t xs_try_logspace;
- __uint32_t xs_sleep_logspace;
- __uint32_t xs_push_ail;
- __uint32_t xs_push_ail_success;
- __uint32_t xs_push_ail_pushbuf;
- __uint32_t xs_push_ail_pinned;
- __uint32_t xs_push_ail_locked;
- __uint32_t xs_push_ail_flushing;
- __uint32_t xs_push_ail_restarts;
- __uint32_t xs_push_ail_flush;
-# define XFSSTAT_END_WRITE_CONVERT (XFSSTAT_END_TAIL_PUSHING+2)
- __uint32_t xs_xstrat_quick;
- __uint32_t xs_xstrat_split;
-# define XFSSTAT_END_READ_WRITE_OPS (XFSSTAT_END_WRITE_CONVERT+2)
- __uint32_t xs_write_calls;
- __uint32_t xs_read_calls;
-# define XFSSTAT_END_ATTRIBUTE_OPS (XFSSTAT_END_READ_WRITE_OPS+4)
- __uint32_t xs_attr_get;
- __uint32_t xs_attr_set;
- __uint32_t xs_attr_remove;
- __uint32_t xs_attr_list;
-# define XFSSTAT_END_INODE_CLUSTER (XFSSTAT_END_ATTRIBUTE_OPS+3)
- __uint32_t xs_iflush_count;
- __uint32_t xs_icluster_flushcnt;
- __uint32_t xs_icluster_flushinode;
-# define XFSSTAT_END_VNODE_OPS (XFSSTAT_END_INODE_CLUSTER+8)
- __uint32_t vn_active; /* # vnodes not on free lists */
- __uint32_t vn_alloc; /* # times vn_alloc called */
- __uint32_t vn_get; /* # times vn_get called */
- __uint32_t vn_hold; /* # times vn_hold called */
- __uint32_t vn_rele; /* # times vn_rele called */
- __uint32_t vn_reclaim; /* # times vn_reclaim called */
- __uint32_t vn_remove; /* # times vn_remove called */
- __uint32_t vn_free; /* # times vn_free called */
-#define XFSSTAT_END_BUF (XFSSTAT_END_VNODE_OPS+9)
- __uint32_t pb_get;
- __uint32_t pb_create;
- __uint32_t pb_get_locked;
- __uint32_t pb_get_locked_waited;
- __uint32_t pb_busy_locked;
- __uint32_t pb_miss_locked;
- __uint32_t pb_page_retries;
- __uint32_t pb_page_found;
- __uint32_t pb_get_read;
-/* Extra precision counters */
- __uint64_t xs_xstrat_bytes;
- __uint64_t xs_write_bytes;
- __uint64_t xs_read_bytes;
-};
-
-extern struct xfsstats xfsstats;
-
-# define XFS_STATS_INC(count) ( xfsstats.count++ )
-# define XFS_STATS_DEC(count) ( xfsstats.count-- )
-# define XFS_STATS_ADD(count, inc) ( xfsstats.count += (inc) )
-
-extern void xfs_init_procfs(void);
-extern void xfs_cleanup_procfs(void);
-
-
-#else /* !CONFIG_PROC_FS */
-
-# define XFS_STATS_INC(count)
-# define XFS_STATS_DEC(count)
-# define XFS_STATS_ADD(count, inc)
-
-static __inline void xfs_init_procfs(void) { };
-static __inline void xfs_cleanup_procfs(void) { };
-
-#endif /* !CONFIG_PROC_FS */
-
-#endif /* __XFS_STATS_H__ */
-
diff --git a/sys/gnu/fs/xfs/FreeBSD/xfs_super.c b/sys/gnu/fs/xfs/FreeBSD/xfs_super.c
deleted file mode 100644
index 747a5da..0000000
--- a/sys/gnu/fs/xfs/FreeBSD/xfs_super.c
+++ /dev/null
@@ -1,279 +0,0 @@
-/*
- * Copyright (c) 2000-2005 Silicon Graphics, Inc.
- * All Rights Reserved.
- *
- * 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.
- *
- * This program is distributed in the hope that it would 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 the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- */
-#include "xfs.h"
-#include "xfs_bit.h"
-#include "xfs_log.h"
-#include "xfs_clnt.h"
-#include "xfs_inum.h"
-#include "xfs_trans.h"
-#include "xfs_sb.h"
-#include "xfs_ag.h"
-#include "xfs_dir.h"
-#include "xfs_dir2.h"
-#include "xfs_alloc.h"
-#include "xfs_dmapi.h"
-#include "xfs_quota.h"
-#include "xfs_mount.h"
-#include "xfs_bmap_btree.h"
-#include "xfs_alloc_btree.h"
-#include "xfs_ialloc_btree.h"
-#include "xfs_dir_sf.h"
-#include "xfs_dir2_sf.h"
-#include "xfs_attr_sf.h"
-#include "xfs_dinode.h"
-#include "xfs_inode.h"
-#include "xfs_btree.h"
-#include "xfs_ialloc.h"
-#include "xfs_bmap.h"
-#include "xfs_rtalloc.h"
-#include "xfs_error.h"
-#include "xfs_itable.h"
-#include "xfs_rw.h"
-#include "xfs_acl.h"
-#include "xfs_cap.h"
-#include "xfs_mac.h"
-#include "xfs_attr.h"
-#include "xfs_buf_item.h"
-#include "xfs_utils.h"
-#include "xfs_version.h"
-#include "xfs_buf.h"
-
-#include <sys/priv.h>
-
-#include <geom/geom.h>
-#include <geom/geom_vfs.h>
-
-extern struct vop_vector xfs_fifoops;
-extern struct xfs_vnodeops xfs_vnodeops;
-
-__uint64_t
-xfs_max_file_offset(
- unsigned int blockshift)
-{
-
- return (OFF_MAX);
-}
-
-void
-xfs_initialize_vnode(
- bhv_desc_t *bdp,
- xfs_vnode_t *xvp,
- bhv_desc_t *inode_bhv,
- int unlock)
-{
- xfs_inode_t *ip = XFS_BHVTOI(inode_bhv);
-
- if (!inode_bhv->bd_vobj) {
- xvp->v_vfsp = bhvtovfs(bdp);
- bhv_desc_init(inode_bhv, ip, xvp, &xfs_vnodeops);
- bhv_insert(VN_BHV_HEAD(xvp), inode_bhv);
- }
-
- /*
- * XXX: Use VNON as an indication of freshly allocated vnode
- * which need to be initialized and unlocked.
- * This is _not_ like the same place in Linux version of
- * routine.
- */
-
- if (xvp->v_vnode->v_type != VNON)
- return;
-
- xvp->v_vnode->v_type = IFTOVT(ip->i_d.di_mode);
-
- if (xvp->v_vnode->v_type == VFIFO)
- xvp->v_vnode->v_op = &xfs_fifoops;
-
- ASSERT_VOP_LOCKED(xvp->v_vnode, "xfs_initialize_vnode");
-
- /* For new inodes we need to set the ops vectors,
- * and unlock the inode.
- */
- if (ip->i_d.di_mode != 0 && unlock)
- VOP_UNLOCK(xvp->v_vnode, 0);
-}
-
-#if 0
-struct vnode *
-xfs_get_inode(
- bhv_desc_t *bdp,
- xfs_ino_t ino,
- int flags)
-{
- return NULL;
-}
-#endif
-
-/*ARGSUSED*/
-int
-xfs_blkdev_get(
- xfs_mount_t *mp,
- const char *name,
- struct vnode **bdevp)
-{
- struct nameidata nd;
- struct nameidata *ndp = &nd;
- int error, ronly;
- struct thread *td;
- struct vnode *devvp;
- struct g_consumer *cp;
- struct g_provider *pp;
- accmode_t accmode;
-
- td = curthread;
-
- NDINIT(ndp, LOOKUP, FOLLOW, UIO_SYSSPACE, name, td);
- if ((error = namei(ndp)) != 0)
- return (error);
- NDFREE(ndp, NDF_ONLY_PNBUF);
- devvp = ndp->ni_vp;
-
- if (!vn_isdisk(devvp, &error)) {
- vrele(devvp);
- return (error);
- }
-
- vn_lock(devvp, LK_EXCLUSIVE | LK_RETRY);
-
- ronly = ((XFS_MTOVFS(mp)->vfs_flag & VFS_RDONLY) != 0);
- accmode = VREAD;
- if (!ronly)
- accmode |= VWRITE;
- error = VOP_ACCESS(devvp, accmode, td->td_ucred, td);
- if (error)
- error = priv_check(td, PRIV_VFS_MOUNT_PERM);
- if (error) {
- vput(devvp);
- return (error);
- }
-
- DROP_GIANT();
- g_topology_lock();
-
- /*
- * XXX: Do not allow more than one consumer to open a device
- * associated with a particular GEOM provider.
- * This disables multiple read-only mounts of a device,
- * but it gets rid of panics in bmemfree() when you try to
- * mount the same device more than once.
- * During mounting, XFS does a bread() of the superblock, but does
- * not brelse() it. A subsequent mount of the same device
- * will try to bread() the superblock, resulting in a panic in
- * bremfree(), "buffer not on queue".
- */
- pp = g_dev_getprovider(devvp->v_rdev);
- if ((pp != NULL) && ((pp->acr | pp->acw | pp->ace ) != 0))
- error = EPERM;
- else
- error = g_vfs_open(devvp, &cp, "xfs", ronly ? 0 : 1);
-
- g_topology_unlock();
- PICKUP_GIANT();
-
- if (error) {
- vput(devvp);
- return (error);
- }
- VOP_UNLOCK(devvp, 0);
-
- devvp->v_bufobj.bo_private = cp;
- devvp->v_bufobj.bo_ops = &xfs_bo_ops;
-
- *bdevp = devvp;
- return (0);
-}
-
-void
-xfs_blkdev_put(
- struct vnode *devvp)
-{
- struct g_consumer *cp;
-
- if (devvp == NULL)
- return;
-
- vinvalbuf(devvp, V_SAVE, 0, 0);
-
- cp = devvp->v_bufobj.bo_private;
- DROP_GIANT();
- g_topology_lock();
- g_wither_geom_close(cp->geom, ENXIO);
- g_topology_unlock();
- PICKUP_GIANT();
-
- vrele(devvp);
-}
-
-void
-xfs_mountfs_check_barriers(xfs_mount_t *mp)
-{
- printf("xfs_mountfs_check_barriers NI\n");
-}
-
-void
-xfs_flush_inode(
- xfs_inode_t *ip)
-{
- printf("xfs_flush_inode NI\n");
-}
-
-void
-xfs_flush_device(
- xfs_inode_t *ip)
-{
- printf("xfs_flush_device NI\n");
- xfs_log_force(ip->i_mount, (xfs_lsn_t)0, XFS_LOG_FORCE|XFS_LOG_SYNC);
-}
-
-
-void
-xfs_blkdev_issue_flush(
- xfs_buftarg_t *buftarg)
-{
- printf("xfs_blkdev_issue_flush NI\n");
-}
-
-int
-init_xfs_fs( void )
-{
- static const char message[] =
- XFS_VERSION_STRING " with " XFS_BUILD_OPTIONS " enabled\n";
-
- printf(message);
-
- vn_init();
- xfs_init();
- uuid_init();
-#ifdef RMC
- vfs_initdmapi();
-#endif
- vfs_initquota();
-
- return 0;
-}
-
-void
-exit_xfs_fs(void)
-{
- xfs_cleanup();
- vfs_exitquota();
-#ifdef RMC
- vfs_exitdmapi();
-#endif
-}
-
diff --git a/sys/gnu/fs/xfs/FreeBSD/xfs_super.h b/sys/gnu/fs/xfs/FreeBSD/xfs_super.h
deleted file mode 100644
index 0180451..0000000
--- a/sys/gnu/fs/xfs/FreeBSD/xfs_super.h
+++ /dev/null
@@ -1,113 +0,0 @@
-/*
- * Copyright (c) 2000-2005 Silicon Graphics, Inc.
- * All Rights Reserved.
- *
- * 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.
- *
- * This program is distributed in the hope that it would 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 the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- */
-#ifndef __XFS_SUPER_H__
-#define __XFS_SUPER_H__
-
-#ifdef CONFIG_XFS_DMAPI
-# define vfs_insertdmapi(vfs) vfs_insertops(vfsp, &xfs_dmops)
-# define vfs_initdmapi() dmapi_init()
-# define vfs_exitdmapi() dmapi_uninit()
-#else
-# define vfs_insertdmapi(vfs) do { } while (0)
-# define vfs_initdmapi() do { } while (0)
-# define vfs_exitdmapi() do { } while (0)
-#endif
-
-#ifdef CONFIG_XFS_QUOTA
-# define vfs_insertquota(vfs) vfs_insertops(vfsp, &xfs_qmops)
-# define vfs_initquota() xfs_qm_init()
-# define vfs_exitquota() xfs_qm_exit()
-#else
-# define vfs_insertquota(vfs) do { } while (0)
-# define vfs_initquota() do { } while (0)
-# define vfs_exitquota() do { } while (0)
-#endif
-
-#ifdef CONFIG_XFS_POSIX_ACL
-# define XFS_ACL_STRING "ACLs, "
-# define set_posix_acl_flag(sb) ((sb)->s_flags |= MS_POSIXACL)
-#else
-# define XFS_ACL_STRING
-# define set_posix_acl_flag(sb) do { } while (0)
-#endif
-
-#ifdef CONFIG_XFS_SECURITY
-# define XFS_SECURITY_STRING "security attributes, "
-# define ENOSECURITY 0
-#else
-# define XFS_SECURITY_STRING
-# define ENOSECURITY EOPNOTSUPP
-#endif
-
-#ifdef CONFIG_XFS_RT
-# define XFS_REALTIME_STRING "realtime, "
-#else
-# define XFS_REALTIME_STRING
-#endif
-
-#if XFS_BIG_BLKNOS
-# if XFS_BIG_INUMS
-# define XFS_BIGFS_STRING "large block/inode numbers, "
-# else
-# define XFS_BIGFS_STRING "large block numbers, "
-# endif
-#else
-# define XFS_BIGFS_STRING
-#endif
-
-#ifdef CONFIG_XFS_TRACE
-# define XFS_TRACE_STRING "tracing, "
-#else
-# define XFS_TRACE_STRING
-#endif
-
-#ifdef XFSDEBUG
-# define XFS_DBG_STRING "debug"
-#else
-# define XFS_DBG_STRING "no debug"
-#endif
-
-#define XFS_BUILD_OPTIONS XFS_ACL_STRING \
- XFS_SECURITY_STRING \
- XFS_REALTIME_STRING \
- XFS_BIGFS_STRING \
- XFS_TRACE_STRING \
- XFS_DBG_STRING /* DBG must be last */
-
-struct xfs_inode;
-struct xfs_mount;
-struct xfs_buftarg;
-
-extern __uint64_t xfs_max_file_offset(unsigned int);
-
-extern void xfs_initialize_vnode(bhv_desc_t *, xfs_vnode_t *, bhv_desc_t *, int);
-
-extern void xfs_flush_inode(struct xfs_inode *);
-extern void xfs_flush_device(struct xfs_inode *);
-
-extern int xfs_blkdev_get(struct xfs_mount *, const char *,
- struct block_device **);
-extern void xfs_blkdev_put(struct block_device *);
-extern void xfs_blkdev_issue_flush(struct xfs_buftarg *);
-
-extern struct export_operations xfs_export_operations;
-
-extern int init_xfs_fs(void);
-extern void exit_xfs_fs(void);
-
-#endif /* __XFS_SUPER_H__ */
diff --git a/sys/gnu/fs/xfs/FreeBSD/xfs_sysctl.c b/sys/gnu/fs/xfs/FreeBSD/xfs_sysctl.c
deleted file mode 100644
index 9ba2d45..0000000
--- a/sys/gnu/fs/xfs/FreeBSD/xfs_sysctl.c
+++ /dev/null
@@ -1,43 +0,0 @@
-/*
- * Copyright (c) 2001-2002 Silicon Graphics, Inc. All Rights Reserved.
- *
- * This program 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.
- *
- * This program is distributed in the hope that it would be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
- *
- * Further, this software is distributed without any warranty that it is
- * free of the rightful claim of any third person regarding infringement
- * or the like. Any license provided herein, whether implied or
- * otherwise, applies only to this software file. Patent licenses, if
- * any, provided herein do not apply to combinations of this program with
- * other software, or any other product whatsoever.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write the Free Software Foundation, Inc., 59
- * Temple Place - Suite 330, Boston MA 02111-1307, USA.
- *
- * Contact information: Silicon Graphics, Inc., 1600 Amphitheatre Pkwy,
- * Mountain View, CA 94043, or:
- *
- * http://www.sgi.com
- *
- * For further information regarding this notice, see:
- *
- * http://oss.sgi.com/projects/GenInfo/SGIGPLNoticeExplan/
- */
-
-#include "xfs.h"
-
-void
-xfs_sysctl_register(void)
-{
-}
-
-void
-xfs_sysctl_unregister(void)
-{
-}
diff --git a/sys/gnu/fs/xfs/FreeBSD/xfs_sysctl.h b/sys/gnu/fs/xfs/FreeBSD/xfs_sysctl.h
deleted file mode 100644
index fa68ff0..0000000
--- a/sys/gnu/fs/xfs/FreeBSD/xfs_sysctl.h
+++ /dev/null
@@ -1,102 +0,0 @@
-/*
- * Copyright (c) 2001-2005 Silicon Graphics, Inc.
- * All Rights Reserved.
- *
- * 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.
- *
- * This program is distributed in the hope that it would 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 the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- */
-#ifndef __XFS_SYSCTL_H__
-#define __XFS_SYSCTL_H__
-
-/*
- * Tunable xfs parameters
- */
-
-typedef struct xfs_sysctl_val {
- int min;
- int val;
- int max;
-} xfs_sysctl_val_t;
-
-typedef struct xfs_param {
- xfs_sysctl_val_t refcache_size; /* Size of NFS reference cache. */
- xfs_sysctl_val_t refcache_purge;/* # of entries to purge each time. */
- xfs_sysctl_val_t restrict_chown;/* Root/non-root can give away files.*/
- xfs_sysctl_val_t sgid_inherit; /* Inherit S_ISGID if process' GID is
- * not a member of parent dir GID. */
- xfs_sysctl_val_t symlink_mode; /* Link creat mode affected by umask */
- xfs_sysctl_val_t panic_mask; /* bitmask to cause panic on errors. */
- xfs_sysctl_val_t error_level; /* Degree of reporting for problems */
- xfs_sysctl_val_t syncd_timer; /* Interval between xfssyncd wakeups */
- xfs_sysctl_val_t stats_clear; /* Reset all XFS statistics to zero. */
- xfs_sysctl_val_t probe_dmapi; /* probe for DMAPI module on mount. */
- xfs_sysctl_val_t probe_ioops; /* probe for an IO module on mount. */
- xfs_sysctl_val_t probe_quota; /* probe for quota module on mount. */
- xfs_sysctl_val_t inherit_sync; /* Inherit the "sync" inode flag. */
- xfs_sysctl_val_t inherit_nodump;/* Inherit the "nodump" inode flag. */
- xfs_sysctl_val_t inherit_noatim;/* Inherit the "noatime" inode flag. */
- xfs_sysctl_val_t xfs_buf_timer; /* Interval between xfsbufd wakeups. */
- xfs_sysctl_val_t xfs_buf_age; /* Metadata buffer age before flush. */
- xfs_sysctl_val_t inherit_nosym; /* Inherit the "nosymlinks" flag. */
- xfs_sysctl_val_t rotorstep; /* inode32 AG rotoring control knob */
-} xfs_param_t;
-
-/*
- * xfs_error_level:
- *
- * How much error reporting will be done when internal problems are
- * encountered. These problems normally return an EFSCORRUPTED to their
- * caller, with no other information reported.
- *
- * 0 No error reports
- * 1 Report EFSCORRUPTED errors that will cause a filesystem shutdown
- * 5 Report all EFSCORRUPTED errors (all of the above errors, plus any
- * additional errors that are known to not cause shutdowns)
- *
- * xfs_panic_mask bit 0x8 turns the error reports into panics
- */
-
-enum {
- /* XFS_REFCACHE_SIZE = 1 */
- /* XFS_REFCACHE_PURGE = 2 */
- XFS_RESTRICT_CHOWN = 3,
- XFS_SGID_INHERIT = 4,
- XFS_SYMLINK_MODE = 5,
- XFS_PANIC_MASK = 6,
- XFS_ERRLEVEL = 7,
- XFS_SYNCD_TIMER = 8,
- XFS_PROBE_DMAPI = 9,
- XFS_PROBE_IOOPS = 10,
- XFS_PROBE_QUOTA = 11,
- XFS_STATS_CLEAR = 12,
- XFS_INHERIT_SYNC = 13,
- XFS_INHERIT_NODUMP = 14,
- XFS_INHERIT_NOATIME = 15,
- XFS_BUF_TIMER = 16,
- XFS_BUF_AGE = 17,
- /* XFS_IO_BYPASS = 18 */
- XFS_INHERIT_NOSYM = 19,
- XFS_ROTORSTEP = 20,
-};
-
-extern xfs_param_t xfs_params;
-
-#ifdef CONFIG_SYSCTL
-extern void xfs_sysctl_register(void);
-extern void xfs_sysctl_unregister(void);
-#else
-# define xfs_sysctl_register() do { } while (0)
-# define xfs_sysctl_unregister() do { } while (0)
-#endif /* CONFIG_SYSCTL */
-
-#endif /* __XFS_SYSCTL_H__ */
diff --git a/sys/gnu/fs/xfs/FreeBSD/xfs_version.h b/sys/gnu/fs/xfs/FreeBSD/xfs_version.h
deleted file mode 100644
index 96f9639..0000000
--- a/sys/gnu/fs/xfs/FreeBSD/xfs_version.h
+++ /dev/null
@@ -1,44 +0,0 @@
-/*
- * Copyright (c) 2001-2002 Silicon Graphics, Inc. All Rights Reserved.
- *
- * This program 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.
- *
- * This program is distributed in the hope that it would be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
- *
- * Further, this software is distributed without any warranty that it is
- * free of the rightful claim of any third person regarding infringement
- * or the like. Any license provided herein, whether implied or
- * otherwise, applies only to this software file. Patent licenses, if
- * any, provided herein do not apply to combinations of this program with
- * other software, or any other product whatsoever.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write the Free Software Foundation, Inc., 59
- * Temple Place - Suite 330, Boston MA 02111-1307, USA.
- *
- * Contact information: Silicon Graphics, Inc., 1600 Amphitheatre Pkwy,
- * Mountain View, CA 94043, or:
- *
- * http://www.sgi.com
- *
- * For further information regarding this notice, see:
- *
- * http://oss.sgi.com/projects/GenInfo/SGIGPLNoticeExplan/
- */
-
-/*
- * Dummy file that can contain a timestamp to put into the
- * XFS init string, to help users keep track of what they're
- * running
- */
-
-#ifndef __XFS_VERSION_H__
-#define __XFS_VERSION_H__
-
-#define XFS_VERSION_STRING "SGI XFS"
-
-#endif /* __XFS_VERSION_H__ */
diff --git a/sys/gnu/fs/xfs/FreeBSD/xfs_vfs.c b/sys/gnu/fs/xfs/FreeBSD/xfs_vfs.c
deleted file mode 100644
index ee405b5..0000000
--- a/sys/gnu/fs/xfs/FreeBSD/xfs_vfs.c
+++ /dev/null
@@ -1,356 +0,0 @@
-/*
- * Copyright (c) 2000-2005 Silicon Graphics, Inc.
- * All Rights Reserved.
- *
- * 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.
- *
- * This program is distributed in the hope that it would 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 the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- */
-#include "xfs.h"
-#include "xfs_fs.h"
-#include "xfs_inum.h"
-#include "xfs_log.h"
-#include "xfs_clnt.h"
-#include "xfs_trans.h"
-#include "xfs_sb.h"
-#include "xfs_ag.h"
-#include "xfs_dir.h"
-#include "xfs_dir2.h"
-#include "xfs_imap.h"
-#include "xfs_alloc.h"
-#include "xfs_dmapi.h"
-#include "xfs_mount.h"
-#include "xfs_quota.h"
-
-#include "xfs_mountops.h"
-
-int
-xvfs_mount(
- struct bhv_desc *bdp,
- struct xfs_mount_args *args,
- struct cred *cr)
-{
- struct bhv_desc *next = bdp;
-
- ASSERT(next);
- while (! (bhvtovfsops(next))->xvfs_mount)
- next = BHV_NEXT(next);
- return ((*bhvtovfsops(next)->xvfs_mount)(next, args, cr));
-}
-
-int
-xvfs_parseargs(
- struct bhv_desc *bdp,
- char *s,
- struct xfs_mount_args *args,
- int f)
-{
- struct bhv_desc *next = bdp;
-
- ASSERT(next);
- while (! (bhvtovfsops(next))->xvfs_parseargs)
- next = BHV_NEXT(next);
- return ((*bhvtovfsops(next)->xvfs_parseargs)(next, s, args, f));
-}
-
-int
-xvfs_showargs(
- struct bhv_desc *bdp,
- struct sbuf *m)
-{
- struct bhv_desc *next = bdp;
-
- ASSERT(next);
- while (! (bhvtovfsops(next))->xvfs_showargs)
- next = BHV_NEXT(next);
- return ((*bhvtovfsops(next)->xvfs_showargs)(next, m));
-}
-
-int
-xvfs_unmount(
- struct bhv_desc *bdp,
- int fl,
- struct cred *cr)
-{
- struct bhv_desc *next = bdp;
-
- ASSERT(next);
- while (! (bhvtovfsops(next))->xvfs_unmount)
- next = BHV_NEXT(next);
- return ((*bhvtovfsops(next)->xvfs_unmount)(next, fl, cr));
-}
-
-int
-xvfs_mntupdate(
- struct bhv_desc *bdp,
- int *fl,
- struct xfs_mount_args *args)
-{
- struct bhv_desc *next = bdp;
-
- ASSERT(next);
- while (! (bhvtovfsops(next))->xvfs_mntupdate)
- next = BHV_NEXT(next);
- return ((*bhvtovfsops(next)->xvfs_mntupdate)(next, fl, args));
-}
-
-int
-xvfs_root(
- struct bhv_desc *bdp,
- struct xfs_vnode **vpp)
-{
- struct bhv_desc *next = bdp;
-
- ASSERT(next);
- while (! (bhvtovfsops(next))->xvfs_root)
- next = BHV_NEXT(next);
- return ((*bhvtovfsops(next)->xvfs_root)(next, vpp));
-}
-
-int
-xvfs_statvfs(
- struct bhv_desc *bdp,
- struct statfs *sp,
- struct xfs_vnode *vp)
-{
- struct bhv_desc *next = bdp;
-
- ASSERT(next);
- while (! (bhvtovfsops(next))->xvfs_statvfs)
- next = BHV_NEXT(next);
- return ((*bhvtovfsops(next)->xvfs_statvfs)(next, sp, vp));
-}
-
-int
-xvfs_sync(
- struct bhv_desc *bdp,
- int fl,
- struct cred *cr)
-{
- struct bhv_desc *next = bdp;
-
- ASSERT(next);
- while (! (bhvtovfsops(next))->xvfs_sync)
- next = BHV_NEXT(next);
- return ((*bhvtovfsops(next)->xvfs_sync)(next, fl, cr));
-}
-
-int
-xvfs_vget(
- struct bhv_desc *bdp,
- struct xfs_vnode **vpp,
- struct fid *fidp)
-{
- struct bhv_desc *next = bdp;
-
- ASSERT(next);
- while (! (bhvtovfsops(next))->xvfs_vget)
- next = BHV_NEXT(next);
- return ((*bhvtovfsops(next)->xvfs_vget)(next, vpp, fidp));
-}
-
-int
-xvfs_dmapiops(
- struct bhv_desc *bdp,
- caddr_t addr)
-{
- struct bhv_desc *next = bdp;
-
- ASSERT(next);
- while (! (bhvtovfsops(next))->xvfs_dmapiops)
- next = BHV_NEXT(next);
- return ((*bhvtovfsops(next)->xvfs_dmapiops)(next, addr));
-}
-
-int
-xvfs_quotactl(
- struct bhv_desc *bdp,
- int cmd,
- int id,
- caddr_t addr)
-{
- struct bhv_desc *next = bdp;
-
- ASSERT(next);
- while (! (bhvtovfsops(next))->xvfs_quotactl)
- next = BHV_NEXT(next);
- return ((*bhvtovfsops(next)->xvfs_quotactl)(next, cmd, id, addr));
-}
-
-struct inode *
-xvfs_get_inode(
- struct bhv_desc *bdp,
- xfs_ino_t ino,
- int fl)
-{
- struct bhv_desc *next = bdp;
-
- while (! (bhvtovfsops(next))->xvfs_get_inode)
- next = BHV_NEXTNULL(next);
- return ((*bhvtovfsops(next)->xvfs_get_inode)(next, ino, fl));
-}
-
-void
-xvfs_init_vnode(
- struct bhv_desc *bdp,
- struct xfs_vnode *vp,
- struct bhv_desc *bp,
- int unlock)
-{
- struct bhv_desc *next = bdp;
-
- ASSERT(next);
- while (! (bhvtovfsops(next))->xvfs_init_vnode)
- next = BHV_NEXT(next);
- ((*bhvtovfsops(next)->xvfs_init_vnode)(next, vp, bp, unlock));
-}
-
-void
-xvfs_force_shutdown(
- struct bhv_desc *bdp,
- int fl,
- char *file,
- int line)
-{
- struct bhv_desc *next = bdp;
-
- ASSERT(next);
- while (! (bhvtovfsops(next))->xvfs_force_shutdown)
- next = BHV_NEXT(next);
- ((*bhvtovfsops(next)->xvfs_force_shutdown)(next, fl, file, line));
-}
-
-xfs_vfs_t *
-vfs_allocate(struct mount *mp)
-{
- struct xfs_vfs *vfsp;
- struct xfsmount *xmp;
-
- xmp = kmem_zalloc(sizeof(*xmp), KM_SLEEP);
- vfsp = XFSTOVFS(xmp);
-
- bhv_head_init(VFS_BHVHEAD(vfsp), "vfs");
-
- xmp->m_mp = mp;
- mp->mnt_data = xmp;
- vfsp->vfs_mp = mp;
-
- return vfsp;
-}
-
-void
-vfs_deallocate(
- struct xfs_vfs *vfsp)
-{
- struct xfsmount *xmp;
-
- bhv_head_destroy(VFS_BHVHEAD(vfsp));
-
- xmp = VFSTOXFS(vfsp);
- kmem_free(xmp, sizeof(*xmp));
-}
-
-/*
- * Allocate and initialize a new XFS mount structure
- */
-struct xfsmount *
-xfsmount_allocate(struct mount *mp)
-{
- xfs_vfs_t *vfsp;
-
- vfsp = vfs_allocate(mp);
-
- ASSERT(vfsp);
-
- if (mp->mnt_flag & MNT_RDONLY)
- vfsp->vfs_flag |= VFS_RDONLY;
-
- bhv_insert_all_vfsops(vfsp);
- return (VFSTOXFS(vfsp));
-}
-
-void
-xfsmount_deallocate(struct xfsmount *xmp)
-{
- xfs_vfs_t *vfsp;
-
- vfsp = XFSTOVFS(xmp);
- bhv_remove_all_vfsops(vfsp, 1);
- vfs_deallocate(vfsp);
-}
-
-
-void
-vfs_insertops(
- struct xfs_vfs *vfsp,
- struct bhv_vfsops *vfsops)
-{
- struct bhv_desc *bdp;
-
- bdp = kmem_alloc(sizeof(struct bhv_desc), KM_SLEEP);
- bhv_desc_init(bdp, NULL, vfsp, vfsops);
- bhv_insert(&vfsp->vfs_bh, bdp);
-}
-
-void
-vfs_insertbhv(
- struct xfs_vfs *vfsp,
- struct bhv_desc *bdp,
- struct xvfsops *vfsops,
- void *mount)
-{
- bhv_desc_init(bdp, mount, vfsp, vfsops);
- bhv_insert_initial(&vfsp->vfs_bh, bdp);
-}
-
-void
-bhv_remove_vfsops(
- struct xfs_vfs *vfsp,
- int pos)
-{
- struct bhv_desc *bhv;
-
- bhv = bhv_lookup_range(&vfsp->vfs_bh, pos, pos);
- if (bhv) {
- bhv_remove(&vfsp->vfs_bh, bhv);
- kmem_free(bhv, sizeof(*bhv));
- }
-}
-
-void
-bhv_remove_all_vfsops(
- struct xfs_vfs *vfsp,
- int freebase)
-{
- struct xfs_mount *mp;
-
- bhv_remove_vfsops(vfsp, VFS_POSITION_QM);
- bhv_remove_vfsops(vfsp, VFS_POSITION_DM);
- bhv_remove_vfsops(vfsp, VFS_POSITION_IO);
- if (!freebase)
- return;
- mp = XFS_BHVTOM(bhv_lookup(VFS_BHVHEAD(vfsp), &xfs_vfsops));
- VFS_REMOVEBHV(vfsp, &mp->m_bhv);
- xfs_mount_free(mp, 0);
-}
-
-void
-bhv_insert_all_vfsops(
- struct xfs_vfs *vfsp)
-{
- struct xfs_mount *mp;
-
- mp = xfs_mount_init();
- vfs_insertbhv(vfsp, &mp->m_bhv, &xfs_vfsops, mp);
- vfs_insertdmapi(vfsp);
- vfs_insertquota(vfsp);
-}
diff --git a/sys/gnu/fs/xfs/FreeBSD/xfs_vfs.h b/sys/gnu/fs/xfs/FreeBSD/xfs_vfs.h
deleted file mode 100644
index ada4849..0000000
--- a/sys/gnu/fs/xfs/FreeBSD/xfs_vfs.h
+++ /dev/null
@@ -1,232 +0,0 @@
-/*
- * Copyright (c) 2000-2003 Silicon Graphics, Inc. All Rights Reserved.
- *
- * This program 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.
- *
- * This program is distributed in the hope that it would be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
- *
- * Further, this software is distributed without any warranty that it is
- * free of the rightful claim of any third person regarding infringement
- * or the like. Any license provided herein, whether implied or
- * otherwise, applies only to this software file. Patent licenses, if
- * any, provided herein do not apply to combinations of this program with
- * other software, or any other product whatsoever.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write the Free Software Foundation, Inc., 59
- * Temple Place - Suite 330, Boston MA 02111-1307, USA.
- *
- * Contact information: Silicon Graphics, Inc., 1600 Amphitheatre Pkwy,
- * Mountain View, CA 94043, or:
- *
- * http://www.sgi.com
- *
- * For further information regarding this notice, see:
- *
- * http://oss.sgi.com/projects/GenInfo/SGIGPLNoticeExplan/
- */
-#ifndef __XFS_VFS_H__
-#define __XFS_VFS_H__
-
-#include <sys/mount.h>
-#include "xfs_fs.h"
-
-struct fid;
-struct cred;
-struct xfs_vnode;
-struct statfs;
-struct sbuf;
-struct xfs_mount_args;
-struct mount;
-
-typedef struct statfs xfs_statfs_t;
-
-typedef struct xfs_vfs {
- u_int vfs_flag; /* flags */
- xfs_fsid_t vfs_fsid; /* file system ID */
- xfs_fsid_t *vfs_altfsid; /* An ID fixed for life of FS */
- bhv_head_t vfs_bh; /* head of vfs behavior chain */
- struct mount *vfs_mp; /* FreeBSD mount struct */
-} xfs_vfs_t;
-
-#define MNTTOXVFS(mp) ((struct xfs_vfs*)(mp)->mnt_data)
-#define XVFSTOMNT(vfs) ((vfs)->vfs_mp)
-
-#define vfs_fbhv vfs_bh.bh_first /* 1st on vfs behavior chain */
-
-#define bhvtovfs(bdp) ( (struct xfs_vfs *)BHV_VOBJ(bdp) )
-#define bhvtovfsops(bdp) ( (struct xvfsops *)BHV_OPS(bdp) )
-#define VFS_BHVHEAD(vfs) ( &(vfs)->vfs_bh )
-#define VFS_REMOVEBHV(vfs, bdp) ( bhv_remove(VFS_BHVHEAD(vfs), bdp) )
-
-#define VFS_POSITION_BASE BHV_POSITION_BASE /* chain bottom */
-#define VFS_POSITION_TOP BHV_POSITION_TOP /* chain top */
-#define VFS_POSITION_INVALID BHV_POSITION_INVALID /* invalid pos. num */
-
-typedef enum {
- VFS_BHV_UNKNOWN, /* not specified */
- VFS_BHV_XFS, /* xfs */
- VFS_BHV_DM, /* data migration */
- VFS_BHV_QM, /* quota manager */
- VFS_BHV_IO, /* IO path */
- VFS_BHV_END /* housekeeping end-of-range */
-} vfs_bhv_t;
-
-#define VFS_POSITION_XFS (BHV_POSITION_BASE)
-#define VFS_POSITION_DM (VFS_POSITION_BASE+10)
-#define VFS_POSITION_QM (VFS_POSITION_BASE+20)
-#define VFS_POSITION_IO (VFS_POSITION_BASE+30)
-
-#define VFS_RDONLY 0x0001 /* read-only vfs */
-#define VFS_GRPID 0x0002 /* group-ID assigned from directory */
-#define VFS_DMI 0x0004 /* filesystem has the DMI enabled */
-#define VFS_32BITINODES 0x0008 /* do not use inums above 32 bits */
-#define VFS_END 0x0008 /* max flag */
-
-#define SYNC_ATTR 0x0001 /* sync attributes */
-#define SYNC_CLOSE 0x0002 /* close file system down */
-#define SYNC_DELWRI 0x0004 /* look at delayed writes */
-#define SYNC_WAIT 0x0008 /* wait for i/o to complete */
-#define SYNC_BDFLUSH 0x0010 /* BDFLUSH is calling -- don't block */
-#define SYNC_FSDATA 0x0020 /* flush fs data (e.g. superblocks) */
-#define SYNC_REFCACHE 0x0040 /* prune some of the nfs ref cache */
-#define SYNC_REMOUNT 0x0080 /* remount readonly, no dummy LRs */
-#define SYNC_QUIESCE 0x0100 /* quiesce filesystem for a snapshot */
-
-#define IGET_NOALLOC 0x0001 /* vfs_get_inode may return NULL */
-
-typedef int (*xvfs_mount_t)(bhv_desc_t *,
- struct xfs_mount_args *, struct cred *);
-typedef int (*xvfs_parseargs_t)(bhv_desc_t *, char *,
- struct xfs_mount_args *, int);
-typedef int (*xvfs_showargs_t)(bhv_desc_t *, struct sbuf *);
-typedef int (*xvfs_unmount_t)(bhv_desc_t *, int, struct cred *);
-typedef int (*xvfs_mntupdate_t)(bhv_desc_t *, int *,
- struct xfs_mount_args *);
-typedef int (*xvfs_root_t)(bhv_desc_t *, struct xfs_vnode **);
-typedef int (*xvfs_statvfs_t)(bhv_desc_t *, xfs_statfs_t *, struct xfs_vnode *);
-typedef int (*xvfs_sync_t)(bhv_desc_t *, int, struct cred *);
-typedef int (*xvfs_vget_t)(bhv_desc_t *, struct xfs_vnode **, struct fid *);
-typedef int (*xvfs_dmapiops_t)(bhv_desc_t *, caddr_t);
-typedef int (*xvfs_quotactl_t)(bhv_desc_t *, int, int, caddr_t);
-typedef void (*xvfs_init_vnode_t)(bhv_desc_t *,
- struct xfs_vnode *, bhv_desc_t *, int);
-typedef void (*xvfs_force_shutdown_t)(bhv_desc_t *, int, char *, int);
-typedef struct inode * (*xvfs_get_inode_t)(bhv_desc_t *, xfs_ino_t, int);
-typedef void (*xvfs_freeze_t)(bhv_desc_t *);
-
-typedef struct xvfsops {
- bhv_position_t xvfs_position; /* behavior chain position */
- xvfs_mount_t xvfs_mount; /* mount file system */
- xvfs_parseargs_t xvfs_parseargs; /* parse mount options */
- xvfs_showargs_t xvfs_showargs; /* unparse mount options */
- xvfs_unmount_t xvfs_unmount; /* unmount file system */
- xvfs_mntupdate_t xvfs_mntupdate; /* update file system options */
- xvfs_root_t xvfs_root; /* get root vnode */
- xvfs_statvfs_t xvfs_statvfs; /* file system statistics */
- xvfs_sync_t xvfs_sync; /* flush files */
- xvfs_vget_t xvfs_vget; /* get vnode from fid */
- xvfs_dmapiops_t xvfs_dmapiops; /* data migration */
- xvfs_quotactl_t xvfs_quotactl; /* disk quota */
- xvfs_get_inode_t xvfs_get_inode; /* bhv specific iget */
- xvfs_init_vnode_t xvfs_init_vnode; /* initialize a new vnode */
- xvfs_force_shutdown_t xvfs_force_shutdown; /* crash and burn */
- xvfs_freeze_t xvfs_freeze; /* freeze fs for snapshot */
-} xvfsops_t;
-
-/*
- * VFS's. Operates on vfs structure pointers (starts at bhv head).
- */
-#define VHEAD(v) ((v)->vfs_fbhv)
-#define XVFS_MOUNT(v, ma,cr, rv) ((rv) = xvfs_mount(VHEAD(v), ma,cr))
-#define XVFS_PARSEARGS(v, o,ma,f, rv) ((rv) = xvfs_parseargs(VHEAD(v), o,ma,f))
-#define XVFS_SHOWARGS(v, m, rv) ((rv) = xvfs_showargs(VHEAD(v), m))
-#define XVFS_UNMOUNT(v, f, cr, rv) ((rv) = xvfs_unmount(VHEAD(v), f,cr))
-#define XVFS_MNTUPDATE(v, fl, args, rv) ((rv) = xvfs_mntupdate(VHEAD(v), fl, args))
-#define XVFS_ROOT(v, vpp, rv) ((rv) = xvfs_root(VHEAD(v), vpp))
-#define XVFS_STATVFS(v, sp,vp, rv) ((rv) = xvfs_statvfs(VHEAD(v), sp,vp))
-#define XVFS_SYNC(v, flag,cr, rv) ((rv) = xvfs_sync(VHEAD(v), flag,cr))
-#define XVFS_VGET(v, vpp,fidp, rv) ((rv) = xvfs_vget(VHEAD(v), vpp,fidp))
-#define XVFS_DMAPIOPS(v, p, rv) ((rv) = xvfs_dmapiops(VHEAD(v), p))
-#define XVFS_QUOTACTL(v, c,id,p, rv) ((rv) = xvfs_quotactl(VHEAD(v), c,id,p))
-#define XVFS_GET_INODE(v, ino, fl) ( xvfs_get_inode(VHEAD(v), ino,fl) )
-#define XVFS_INIT_VNODE(v, vp,b,ul) ( xvfs_init_vnode(VHEAD(v), vp,b,ul) )
-#define XVFS_FORCE_SHUTDOWN(v, fl,f,l) ( xvfs_force_shutdown(VHEAD(v), fl,f,l) )
-
-/*
- * PVFS's. Operates on behavior descriptor pointers.
- */
-#define PVFS_MOUNT(b, ma,cr, rv) ((rv) = xvfs_mount(b, ma,cr))
-#define PVFS_PARSEARGS(b, o,ma,f, rv) ((rv) = xvfs_parseargs(b, o,ma,f))
-#define PVFS_SHOWARGS(b, m, rv) ((rv) = xvfs_showargs(b, m))
-#define PVFS_UNMOUNT(b, f,cr, rv) ((rv) = xvfs_unmount(b, f,cr))
-#define PVFS_MNTUPDATE(b, fl, args, rv) ((rv) = xvfs_mntupdate(b, fl, args))
-#define PVFS_ROOT(b, vpp, rv) ((rv) = xvfs_root(b, vpp))
-#define PVFS_STATVFS(b, sp,vp, rv) ((rv) = xvfs_statvfs(b, sp,vp))
-#define PVFS_SYNC(b, flag,cr, rv) ((rv) = xvfs_sync(b, flag,cr))
-#define PVFS_VGET(b, vpp,fidp, rv) ((rv) = xvfs_vget(b, vpp,fidp))
-#define PVFS_DMAPIOPS(b, p, rv) ((rv) = xvfs_dmapiops(b, p))
-#define PVFS_QUOTACTL(b, c,id,p, rv) ((rv) = xvfs_quotactl(b, c,id,p))
-#define PVFS_GET_INODE(b, ino,fl) ( xvfs_get_inode(b, ino,fl) )
-#define PVFS_INIT_VNODE(b, vp,b2,ul) ( xvfs_init_vnode(b, vp,b2,ul) )
-#define PVFS_FORCE_SHUTDOWN(b, fl,f,l) ( xvfs_force_shutdown(b, fl,f,l) )
-
-extern int xvfs_mount(bhv_desc_t *, struct xfs_mount_args *, struct cred *);
-extern int xvfs_parseargs(bhv_desc_t *, char *, struct xfs_mount_args *, int);
-extern int xvfs_showargs(bhv_desc_t *, struct sbuf *);
-extern int xvfs_unmount(bhv_desc_t *, int, struct cred *);
-extern int xvfs_mntupdate(bhv_desc_t *, int *, struct xfs_mount_args *);
-extern int xvfs_root(bhv_desc_t *, struct xfs_vnode **);
-extern int xvfs_statvfs(bhv_desc_t *, xfs_statfs_t *, struct xfs_vnode *);
-extern int xvfs_sync(bhv_desc_t *, int, struct cred *);
-extern int xvfs_vget(bhv_desc_t *, struct xfs_vnode **, struct fid *);
-extern int xvfs_dmapiops(bhv_desc_t *, caddr_t);
-extern int xvfs_quotactl(bhv_desc_t *, int, int, caddr_t);
-extern struct inode *xvfs_get_inode(bhv_desc_t *, xfs_ino_t, int);
-extern void xvfs_init_vnode(bhv_desc_t *, struct xfs_vnode *, bhv_desc_t *, int);
-extern void xvfs_force_shutdown(bhv_desc_t *, int, char *, int);
-
-#define XFS_DMOPS "xfs_dm_operations" /* Data Migration */
-#define XFS_QMOPS "xfs_qm_operations" /* Quota Manager */
-#define XFS_IOOPS "xfs_io_operations" /* I/O subsystem */
-#define XFS_DM_MODULE "xfs_dmapi"
-#define XFS_QM_MODULE "xfs_quota"
-#define XFS_IO_MODULE "xfs_ioops"
-
-typedef struct bhv_vfsops {
- struct xvfsops bhv_common;
- void * bhv_custom;
-} bhv_vfsops_t;
-
-typedef struct bhv_module {
- bhv_desc_t bm_desc;
- const char * bm_name;
- bhv_vfsops_t * bm_ops;
-} bhv_module_t;
-
-#define vfs_bhv_lookup(v, id) ( bhv_lookup_range(&(v)->vfs_bh, (id), (id)) )
-#define vfs_bhv_custom(b) ( ((bhv_vfsops_t *)BHV_OPS(b))->bhv_custom )
-#define vfs_bhv_set_custom(b,o) ( (b)->bhv_custom = (void *)(o))
-#define vfs_bhv_clr_custom(b) ( (b)->bhv_custom = NULL )
-
-extern xfs_vfs_t *vfs_allocate(struct mount *);
-extern void vfs_deallocate(xfs_vfs_t *);
-extern void vfs_insertops(xfs_vfs_t *, bhv_vfsops_t *);
-extern void vfs_insertbhv(xfs_vfs_t *, bhv_desc_t *, xvfsops_t *, void *);
-
-#define bhv_lookup_module(n,m) ( (m) ? \
- inter_module_get_request(n, m) : \
- inter_module_get(n) )
-#define bhv_remove_module(n) inter_module_put(n)
-#define bhv_module_init(n,m,op) inter_module_register(n,m,op)
-#define bhv_module_exit(n) inter_module_unregister(n)
-
-extern void bhv_insert_all_vfsops(struct xfs_vfs *);
-extern void bhv_remove_all_vfsops(struct xfs_vfs *, int);
-extern void bhv_remove_vfsops(struct xfs_vfs *, int);
-
-#endif /* __XFS_VFS_H__ */
diff --git a/sys/gnu/fs/xfs/FreeBSD/xfs_vnode.c b/sys/gnu/fs/xfs/FreeBSD/xfs_vnode.c
deleted file mode 100644
index 3b3f3e5..0000000
--- a/sys/gnu/fs/xfs/FreeBSD/xfs_vnode.c
+++ /dev/null
@@ -1,272 +0,0 @@
-/*
- * Copyright (c) 2000-2003 Silicon Graphics, Inc. All Rights Reserved.
- *
- * This program 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.
- *
- * This program is distributed in the hope that it would be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
- *
- * Further, this software is distributed without any warranty that it is
- * free of the rightful claim of any third person regarding infringement
- * or the like. Any license provided herein, whether implied or
- * otherwise, applies only to this software file. Patent licenses, if
- * any, provided herein do not apply to combinations of this program with
- * other software, or any other product whatsoever.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write the Free Software Foundation, Inc., 59
- * Temple Place - Suite 330, Boston MA 02111-1307, USA.
- *
- * Contact information: Silicon Graphics, Inc., 1600 Amphitheatre Pkwy,
- * Mountain View, CA 94043, or:
- *
- * http://www.sgi.com
- *
- * For further information regarding this notice, see:
- *
- * http://oss.sgi.com/projects/GenInfo/SGIGPLNoticeExplan/
- */
-
-#include "xfs.h"
-#include "xfs_types.h"
-#include "xfs_bit.h"
-#include "xfs_inum.h"
-#include "xfs_log.h"
-#include "xfs_trans.h"
-#include "xfs_trans_priv.h"
-#include "xfs_sb.h"
-#include "xfs_ag.h"
-#include "xfs_dir.h"
-#include "xfs_dir2.h"
-#include "xfs_dmapi.h"
-#include "xfs_mount.h"
-#include "xfs_alloc_btree.h"
-#include "xfs_bmap_btree.h"
-#include "xfs_ialloc_btree.h"
-#include "xfs_btree.h"
-#include "xfs_imap.h"
-#include "xfs_alloc.h"
-#include "xfs_attr_sf.h"
-#include "xfs_dir_sf.h"
-#include "xfs_dir2_sf.h"
-#include "xfs_dinode.h"
-#include "xfs_ialloc.h"
-#include "xfs_inode.h"
-#include "xfs_inode_item.h"
-
-void
-vn_init(void)
-{
-}
-
-void
-vn_iowait(
- struct xfs_vnode *vp)
-{
- printf("vn_iowait doing nothing on FreeBSD?\n");
-}
-
-struct xfs_vnode *
-vn_initialize(
- xfs_vnode_t *vp)
-{
- XFS_STATS_INC(vn_active);
- XFS_STATS_INC(vn_alloc);
-
- /* Initialize the first behavior and the behavior chain head. */
- vn_bhv_head_init(VN_BHV_HEAD(vp), "vnode");
-
-#ifdef CONFIG_XFS_VNODE_TRACING
- vp->v_trace = ktrace_alloc(VNODE_TRACE_SIZE, KM_SLEEP);
-#endif /* CONFIG_XFS_VNODE_TRACING */
-
- vn_trace_exit(vp, "vn_initialize", (inst_t *)__return_address);
- return vp;
-}
-
-/*
- * Get a reference on a vnode. Need to drop vnode reference
- * to accomodate for vhold by VMAP regardless of whether or
- * not we were able to successfully grab the vnode.
- */
-xfs_vnode_t *
-vn_get(
- struct xfs_vnode *xfs_vp,
- vmap_t *vmap)
-{
- struct vnode *vp;
- int error;
-
- XFS_STATS_INC(vn_get);
-
- vp = vmap->v_vp;
-
- error = vget(vp, LK_EXCLUSIVE, curthread);
- vdrop(vp);
- if (error)
- return (NULL);
-
- /*
- * Drop the vnode returned by vget here.
- * VOP_RECLAIM(9) should block on internal XFS locks so that
- * the reclaiming scheme still remains consistent even if the
- * vp is not locked.
- */
- VOP_UNLOCK(vp, 0);
- if (vp->v_data != xfs_vp) {
- vput(vp);
- return (NULL);
- }
-
- vn_trace_exit(vp, "vn_get", (inst_t *)__return_address);
- return xfs_vp;
-}
-
-/*
- * purge a vnode from the cache
- * At this point the vnode is guaranteed to have no references (vn_count == 0)
- * The caller has to make sure that there are no ways someone could
- * get a handle (via vn_get) on the vnode (usually done via a mount/vfs lock).
- */
-void
-vn_purge(struct xfs_vnode *xfs_vp)
-{
- struct vnode *vp;
-
- vn_trace_entry(vp, "vn_purge", (inst_t *)__return_address);
-
- vp = xfs_vp->v_vnode;
-
- vn_lock(vp, LK_EXCLUSIVE);
- if (vp->v_holdcnt == 0)
- vhold(vp);
- vgone(vp);
- VOP_UNLOCK(vp, 0);
-}
-
-void xfs_ichgtime(
- xfs_inode_t *ip,
- int flags)
-{
- timespec_t tv;
-
- vfs_timestamp(&tv);
- if (flags & XFS_ICHGTIME_MOD) {
- ip->i_d.di_mtime.t_sec = (__int32_t)tv.tv_sec;
- ip->i_d.di_mtime.t_nsec = (__int32_t)tv.tv_nsec;
- }
- if (flags & XFS_ICHGTIME_ACC) {
- ip->i_d.di_atime.t_sec = (__int32_t)tv.tv_sec;
- ip->i_d.di_atime.t_nsec = (__int32_t)tv.tv_nsec;
- }
- if (flags & XFS_ICHGTIME_CHG) {
- ip->i_d.di_ctime.t_sec = (__int32_t)tv.tv_sec;
- ip->i_d.di_ctime.t_nsec = (__int32_t)tv.tv_nsec;
- }
-
-//printf ("xfs_ichgtime NI\n");
-
-}
-
-
-/*
- * Bring the atime in the XFS inode uptodate.
- * Used before logging the inode to disk or when the Linux inode goes away.
- */
-
-/*
- * It's unclear if we need this since this is for syncing the linux inode's atime
- * to the xfs inode's atime.
- * Since FreeBSD doesn't have atime in the vnode is there anything to really
- * sync over?
- * For now just make this a update atime call
- */
-
-void
-xfs_synchronize_atime(
- xfs_inode_t *ip)
-{
-#if 0
- xfs_vnode_t *vp;
-#endif
-
- timespec_t tv;
-
-/* vfs_timestamp looks at the system time accuracy variable */
- vfs_timestamp(&tv);
-#if 0
- printf("xfs_synchronize_atime old (%d,%d) new (%d,%ld)\n",
- ip->i_d.di_atime.t_sec,
- ip->i_d.di_atime.t_nsec,
- tv.tv_sec,
- tv.tv_nsec);
-#endif
-
- ip->i_d.di_atime.t_sec = (__int32_t)tv.tv_sec;
- ip->i_d.di_atime.t_nsec = (__int32_t)tv.tv_nsec;
-}
-
-#ifdef RMC
-/*
- * Extracting atime values in various formats
- */
-void vn_atime_to_bstime(struct xfs_vnode *vp, xfs_bstime_t *bs_atime)
-{
- bs_atime->tv_sec = vp->v_inode.i_atime.tv_sec;
- bs_atime->tv_nsec = vp->v_inode.i_atime.tv_nsec;
- printf("vn_atime_to_bstime NI\n");
-}
-#endif
-
-
-#ifdef CONFIG_XFS_VNODE_TRACING
-
-#define KTRACE_ENTER(vp, vk, s, line, ra) \
- ktrace_enter( (vp)->v_trace, \
-/* 0 */ (void *)(__psint_t)(vk), \
-/* 1 */ (void *)(s), \
-/* 2 */ (void *)(__psint_t) line, \
-/* 3 */ (void *)(vn_count(vp)), \
-/* 4 */ (void *)(ra), \
-/* 5 */ (void *)(__psunsigned_t)(vp)->v_flag, \
-/* 6 */ (void *)(__psint_t)smp_processor_id(), \
-/* 7 */ (void *)(__psint_t)(current->pid), \
-/* 8 */ (void *)__return_address, \
-/* 9 */ 0, 0, 0, 0, 0, 0, 0)
-
-/*
- * Vnode tracing code.
- */
-void
-vn_trace_entry(xfs_vnode_t *vp, char *func, inst_t *ra)
-{
- KTRACE_ENTER(vp, VNODE_KTRACE_ENTRY, func, 0, ra);
-}
-
-void
-vn_trace_exit(xfs_vnode_t *vp, char *func, inst_t *ra)
-{
- KTRACE_ENTER(vp, VNODE_KTRACE_EXIT, func, 0, ra);
-}
-
-void
-vn_trace_hold(xfs_vnode_t *vp, char *file, int line, inst_t *ra)
-{
- KTRACE_ENTER(vp, VNODE_KTRACE_HOLD, file, line, ra);
-}
-
-void
-vn_trace_ref(xfs_vnode_t *vp, char *file, int line, inst_t *ra)
-{
- KTRACE_ENTER(vp, VNODE_KTRACE_REF, file, line, ra);
-}
-
-void
-vn_trace_rele(xfs_vnode_t *vp, char *file, int line, inst_t *ra)
-{
- KTRACE_ENTER(vp, VNODE_KTRACE_RELE, file, line, ra);
-}
-#endif /* CONFIG_XFS_VNODE_TRACING */
diff --git a/sys/gnu/fs/xfs/FreeBSD/xfs_vnode.h b/sys/gnu/fs/xfs/FreeBSD/xfs_vnode.h
deleted file mode 100644
index 1e02bb0..0000000
--- a/sys/gnu/fs/xfs/FreeBSD/xfs_vnode.h
+++ /dev/null
@@ -1,673 +0,0 @@
-/*
- * Copyright (c) 2000-2003 Silicon Graphics, Inc. All Rights Reserved.
- *
- * This program 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.
- *
- * This program is distributed in the hope that it would be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
- *
- * Further, this software is distributed without any warranty that it is
- * free of the rightful claim of any third person regarding infringement
- * or the like. Any license provided herein, whether implied or
- * otherwise, applies only to this software file. Patent licenses, if
- * any, provided herein do not apply to combinations of this program with
- * other software, or any other product whatsoever.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write the Free Software Foundation, Inc., 59
- * Temple Place - Suite 330, Boston MA 02111-1307, USA.
- *
- * Contact information: Silicon Graphics, Inc., 1600 Amphitheatre Pkwy,
- * Mountain View, CA 94043, or:
- *
- * http://www.sgi.com
- *
- * For further information regarding this notice, see:
- *
- * http://oss.sgi.com/projects/GenInfo/SGIGPLNoticeExplan/
- *
- * Portions Copyright (c) 1989, 1993
- * The Regents of the University of California. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-#ifndef __XFS_VNODE_H__
-#define __XFS_VNODE_H__
-
-#include <sys/vnode.h>
-#include <sys/namei.h>
-
-struct xfs_iomap;
-typedef struct componentname vname_t;
-typedef bhv_head_t vn_bhv_head_t;
-
-/*
- * MP locking protocols:
- * v_flag, v_vfsp VN_LOCK/VN_UNLOCK
- * v_type read-only or fs-dependent
- */
-typedef struct xfs_vnode {
- __u32 v_flag; /* vnode flags (see below) */
- struct xfs_vfs *v_vfsp; /* ptr to containing VFS */
- xfs_ino_t v_number; /* in-core vnode number */
- vn_bhv_head_t v_bh; /* behavior head */
- struct vnode *v_vnode; /* FreeBSD vnode */
- struct xfs_inode *v_inode; /* XFS inode */
-#ifdef XFS_VNODE_TRACE
- struct ktrace *v_trace; /* trace header structure */
-#endif
-} xfs_vnode_t;
-
-
-/* vnode types */
-#define VN_ISLNK(vp) ((vp)->v_vnode->v_type & VLNK)
-#define VN_ISREG(vp) ((vp)->v_vnode->v_type & VREG)
-#define VN_ISDIR(vp) ((vp)->v_vnode->v_type & VDIR)
-#define VN_ISCHR(vp) ((vp)->v_vnode->v_type & VCHR)
-#define VN_ISBLK(vp) ((vp)->v_vnode->v_type & VBLK)
-#define VN_BAD(vp) ((vp)->v_vnode->v_type & VBAD)
-
-#define v_fbhv v_bh.bh_first /* first behavior */
-#define v_fops v_bh.bh_first->bd_ops /* first behavior ops */
-
-#define VNODE_POSITION_BASE BHV_POSITION_BASE /* chain bottom */
-#define VNODE_POSITION_TOP BHV_POSITION_TOP /* chain top */
-#define VNODE_POSITION_INVALID BHV_POSITION_INVALID /* invalid pos. num */
-
-typedef enum {
- VN_BHV_UNKNOWN, /* not specified */
- VN_BHV_XFS, /* xfs */
- VN_BHV_DM, /* data migration */
- VN_BHV_QM, /* quota manager */
- VN_BHV_IO, /* IO path */
- VN_BHV_END /* housekeeping end-of-range */
-} vn_bhv_t;
-
-#define VNODE_POSITION_XFS (VNODE_POSITION_BASE)
-#define VNODE_POSITION_DM (VNODE_POSITION_BASE+10)
-#define VNODE_POSITION_QM (VNODE_POSITION_BASE+20)
-#define VNODE_POSITION_IO (VNODE_POSITION_BASE+30)
-
-#define VPTOXFSVP(vp) ((struct xfs_vnode *)(vp)->v_data)
-
-/*
- * Macros for dealing with the behavior descriptor inside of the vnode.
- */
-#define BHV_TO_VNODE(bdp) ((xfs_vnode_t *)BHV_VOBJ(bdp))
-#define BHV_TO_VNODE_NULL(bdp) ((xfs_vnode_t *)BHV_VOBJNULL(bdp))
-
-#define VN_BHV_HEAD(vp) ((bhv_head_t *)(&((vp)->v_bh)))
-#define vn_bhv_head_init(bhp,name) bhv_head_init(bhp,name)
-#define vn_bhv_remove(bhp,bdp) bhv_remove(bhp,bdp)
-#define vn_bhv_lookup(bhp,ops) bhv_lookup(bhp,ops)
-#define vn_bhv_lookup_unlocked(bhp,ops) bhv_lookup_unlocked(bhp,ops)
-
-/*
- * Vnode to Linux inode mapping.
- */
-#define LINVFS_GET_VP(inode) ((xfs_vnode_t *)NULL)
-#define LINVFS_GET_IP(vp) ((xfs_inode_t *)NULL)
-
-/*
- * Vnode flags.
- */
-#define VINACT 0x1 /* vnode is being inactivated */
-#define VRECLM 0x2 /* vnode is being reclaimed */
-#define VWAIT 0x4 /* waiting for VINACT/VRECLM to end */
-#define VMODIFIED 0x8 /* XFS inode state possibly differs */
- /* to the Linux inode state. */
-
-/*
- * Values for the VOP_RWLOCK and VOP_RWUNLOCK flags parameter.
- */
-typedef enum vrwlock {
- VRWLOCK_NONE,
- VRWLOCK_READ,
- VRWLOCK_WRITE,
- VRWLOCK_WRITE_DIRECT,
- VRWLOCK_TRY_READ,
- VRWLOCK_TRY_WRITE
-} vrwlock_t;
-
-/*
- * Return values for VOP_INACTIVE. A return value of
- * VN_INACTIVE_NOCACHE implies that the file system behavior
- * has disassociated its state and bhv_desc_t from the vnode.
- */
-#define VN_INACTIVE_CACHE 0
-#define VN_INACTIVE_NOCACHE 1
-
-/*
- * Values for the cmd code given to VOP_VNODE_CHANGE.
- */
-typedef enum vchange {
- VCHANGE_FLAGS_FRLOCKS = 0,
- VCHANGE_FLAGS_ENF_LOCKING = 1,
- VCHANGE_FLAGS_TRUNCATED = 2,
- VCHANGE_FLAGS_PAGE_DIRTY = 3,
- VCHANGE_FLAGS_IOEXCL_COUNT = 4
-} vchange_t;
-
-struct file_lock;
-struct xfs_iomap_s;
-struct xfs_vattr;
-struct attrlist_cursor_kern;
-
-typedef int (*xfs_vop_open_t)(bhv_desc_t *, struct cred *);
-typedef ssize_t (*xfs_vop_read_t)(bhv_desc_t *, uio_t *, int, struct cred *);
-typedef ssize_t (*xfs_vop_write_t)(bhv_desc_t *, uio_t *, int, struct cred *);
-typedef int (*xfs_vop_ioctl_t)(bhv_desc_t *, struct inode *, struct file *,
- int, u_long, void *);
-typedef int (*xfs_vop_getattr_t)(bhv_desc_t *, struct xfs_vattr *, int,
- struct cred *);
-typedef int (*xfs_vop_setattr_t)(bhv_desc_t *, struct xfs_vattr *, int,
- struct cred *);
-typedef int (*xfs_vop_access_t)(bhv_desc_t *, int, struct cred *);
-typedef int (*xfs_vop_lookup_t)(bhv_desc_t *, vname_t *, xfs_vnode_t **,
- int, xfs_vnode_t *, struct cred *);
-typedef int (*xfs_vop_create_t)(bhv_desc_t *, vname_t *, struct xfs_vattr *,
- xfs_vnode_t **, struct cred *);
-typedef int (*xfs_vop_remove_t)(bhv_desc_t *, bhv_desc_t *, vname_t *, struct cred *);
-typedef int (*xfs_vop_link_t)(bhv_desc_t *, xfs_vnode_t *, vname_t *,
- struct cred *);
-typedef int (*xfs_vop_rename_t)(bhv_desc_t *, vname_t *, xfs_vnode_t *, vname_t *,
- struct cred *);
-typedef int (*xfs_vop_mkdir_t)(bhv_desc_t *, vname_t *, struct xfs_vattr *,
- xfs_vnode_t **, struct cred *);
-typedef int (*xfs_vop_rmdir_t)(bhv_desc_t *, vname_t *, struct cred *);
-typedef int (*xfs_vop_readdir_t)(bhv_desc_t *, struct uio *, struct cred *,
- int *);
-typedef int (*xfs_vop_symlink_t)(bhv_desc_t *, vname_t *, struct xfs_vattr *,
- char *, xfs_vnode_t **, struct cred *);
-
-typedef int (*xfs_vop_readlink_t)(bhv_desc_t *, struct uio *, int,
- struct cred *);
-typedef int (*xfs_vop_fsync_t)(bhv_desc_t *, int, struct cred *,
- xfs_off_t, xfs_off_t);
-typedef int (*xfs_vop_inactive_t)(bhv_desc_t *, struct cred *);
-typedef int (*xfs_vop_fid2_t)(bhv_desc_t *, struct fid *);
-typedef int (*xfs_vop_release_t)(bhv_desc_t *);
-typedef int (*xfs_vop_rwlock_t)(bhv_desc_t *, vrwlock_t);
-typedef void (*xfs_vop_rwunlock_t)(bhv_desc_t *, vrwlock_t);
-typedef int (*xfs_vop_frlock_t)(bhv_desc_t *, int, struct file_lock *,int,
- xfs_off_t, struct cred *);
-typedef int (*xfs_vop_bmap_t)(bhv_desc_t *, xfs_off_t, ssize_t, int,
- struct xfs_iomap *, int *);
-typedef int (*xfs_vop_reclaim_t)(bhv_desc_t *);
-typedef int (*xfs_vop_attr_get_t)(bhv_desc_t *, const char *, char *, int *, int,
- struct cred *);
-typedef int (*xfs_vop_attr_set_t)(bhv_desc_t *, const char *, char *, int, int,
- struct cred *);
-typedef int (*xfs_vop_attr_remove_t)(bhv_desc_t *, const char *, int, struct cred *);
-typedef int (*xfs_vop_attr_list_t)(bhv_desc_t *, char *, int, int,
- struct attrlist_cursor_kern *, struct cred *);
-typedef void (*xfs_vop_link_removed_t)(bhv_desc_t *, xfs_vnode_t *, int);
-typedef void (*xfs_vop_vnode_change_t)(bhv_desc_t *, vchange_t, __psint_t);
-typedef void (*xfs_vop_ptossvp_t)(bhv_desc_t *, xfs_off_t, xfs_off_t, int);
-typedef void (*xfs_vop_pflushinvalvp_t)(bhv_desc_t *, xfs_off_t, xfs_off_t, int);
-typedef int (*xfs_vop_pflushvp_t)(bhv_desc_t *, xfs_off_t, xfs_off_t,
- uint64_t, int);
-typedef int (*xfs_vop_iflush_t)(bhv_desc_t *, int);
-
-
-typedef struct xfs_vnodeops {
- bhv_position_t vn_position; /* position within behavior chain */
- xfs_vop_open_t vop_open;
- xfs_vop_read_t vop_read;
- xfs_vop_write_t vop_write;
- xfs_vop_ioctl_t vop_ioctl;
- xfs_vop_getattr_t vop_getattr;
- xfs_vop_setattr_t vop_setattr;
- xfs_vop_access_t vop_access;
- xfs_vop_lookup_t vop_lookup;
- xfs_vop_create_t vop_create;
- xfs_vop_remove_t vop_remove;
- xfs_vop_link_t vop_link;
- xfs_vop_rename_t vop_rename;
- xfs_vop_mkdir_t vop_mkdir;
- xfs_vop_rmdir_t vop_rmdir;
- xfs_vop_readdir_t vop_readdir;
- xfs_vop_symlink_t vop_symlink;
- xfs_vop_readlink_t vop_readlink;
- xfs_vop_fsync_t vop_fsync;
- xfs_vop_inactive_t vop_inactive;
- xfs_vop_fid2_t vop_fid2;
- xfs_vop_rwlock_t vop_rwlock;
- xfs_vop_rwunlock_t vop_rwunlock;
- xfs_vop_frlock_t vop_frlock;
- xfs_vop_bmap_t vop_bmap;
- xfs_vop_reclaim_t vop_reclaim;
- xfs_vop_attr_get_t vop_attr_get;
- xfs_vop_attr_set_t vop_attr_set;
- xfs_vop_attr_remove_t vop_attr_remove;
- xfs_vop_attr_list_t vop_attr_list;
- xfs_vop_link_removed_t vop_link_removed;
- xfs_vop_vnode_change_t vop_vnode_change;
- xfs_vop_ptossvp_t vop_tosspages;
- xfs_vop_pflushinvalvp_t vop_flushinval_pages;
- xfs_vop_pflushvp_t vop_flush_pages;
- xfs_vop_release_t vop_release;
- xfs_vop_iflush_t vop_iflush;
-} xfs_vnodeops_t;
-
-/*
- * VOP's.
- */
-#define _VOP_(op, vp) (*((xfs_vnodeops_t *)(vp)->v_fops)->op)
-
-#define XVOP_READ(vp,uio,ioflags,cr,rv) \
- rv = _VOP_(vop_read, vp)((vp)->v_fbhv,uio,ioflags,cr)
-#define XVOP_WRITE(vp,file,uio,ioflags,cr,rv) \
- rv = _VOP_(vop_write, vp)((vp)->v_fbhv,uio,ioflags,cr)
-#define XVOP_BMAP(vp,of,sz,rw,b,n,rv) \
- rv = _VOP_(vop_bmap, vp)((vp)->v_fbhv,of,sz,rw,b,n)
-#define XVOP_OPEN(vp, cr, rv) \
- rv = _VOP_(vop_open, vp)((vp)->v_fbhv, cr)
-#define XVOP_GETATTR(vp, vap, f, cr, rv) \
- rv = _VOP_(vop_getattr, vp)((vp)->v_fbhv, vap, f, cr)
-#define XVOP_SETATTR(vp, vap, f, cr, rv) \
- rv = _VOP_(vop_setattr, vp)((vp)->v_fbhv, vap, f, cr)
-#define XVOP_ACCESS(vp, accmode, cr, rv) \
- rv = _VOP_(vop_access, vp)((vp)->v_fbhv, accmode, cr)
-#define XVOP_LOOKUP(vp,d,vpp,f,rdir,cr,rv) \
- rv = _VOP_(vop_lookup, vp)((vp)->v_fbhv,d,vpp,f,rdir,cr)
-#define XVOP_CREATE(dvp,d,vap,vpp,cr,rv) \
- rv = _VOP_(vop_create, dvp)((dvp)->v_fbhv,d,vap,vpp,cr)
-#define XVOP_REMOVE(dvp,d,cr,rv) \
- rv = _VOP_(vop_remove, dvp)((dvp)->v_fbhv,d,cr)
-#define XVOP_LINK(tdvp,fvp,d,cr,rv) \
- rv = _VOP_(vop_link, tdvp)((tdvp)->v_fbhv,fvp,d,cr)
-#define XVOP_RENAME(fvp,fnm,tdvp,tnm,cr,rv) \
- rv = _VOP_(vop_rename, fvp)((fvp)->v_fbhv,fnm,tdvp,tnm,cr)
-#define XVOP_MKDIR(dp,d,vap,vpp,cr,rv) \
- rv = _VOP_(vop_mkdir, dp)((dp)->v_fbhv,d,vap,vpp,cr)
-#define XVOP_RMDIR(dp,d,cr,rv) \
- rv = _VOP_(vop_rmdir, dp)((dp)->v_fbhv,d,cr)
-#define XVOP_READDIR(vp,uiop,cr,eofp,rv) \
- rv = _VOP_(vop_readdir, vp)((vp)->v_fbhv,uiop,cr,eofp)
-#define XVOP_SYMLINK(dvp,d,vap,tnm,vpp,cr,rv) \
- rv = _VOP_(vop_symlink, dvp) ((dvp)->v_fbhv,d,vap,tnm,vpp,cr)
-#define XVOP_READLINK(vp,uiop,fl,cr,rv) \
- rv = _VOP_(vop_readlink, vp)((vp)->v_fbhv,uiop,fl,cr)
-
-#define XVOP_FSYNC(vp,f,cr,b,e,rv) \
- rv = _VOP_(vop_fsync, vp)((vp)->v_fbhv,f,cr,b,e)
-#define XVOP_INACTIVE(vp, cr, rv) \
- rv = _VOP_(vop_inactive, vp)((vp)->v_fbhv, cr)
-#define XVOP_RELEASE(vp, rv) \
- rv = _VOP_(vop_release, vp)((vp)->v_fbhv)
-#define XVOP_FID2(vp, fidp, rv) \
- rv = _VOP_(vop_fid2, vp)((vp)->v_fbhv, fidp)
-#define XVOP_RWLOCK(vp,i) \
- (void)_VOP_(vop_rwlock, vp)((vp)->v_fbhv, i)
-#define XVOP_RWLOCK_TRY(vp,i) \
- _VOP_(vop_rwlock, vp)((vp)->v_fbhv, i)
-#define XVOP_RWUNLOCK(vp,i) \
- (void)_VOP_(vop_rwunlock, vp)((vp)->v_fbhv, i)
-#define XVOP_FRLOCK(vp,c,fl,flags,offset,fr,rv) \
- rv = _VOP_(vop_frlock, vp)((vp)->v_fbhv,c,fl,flags,offset,fr)
-#define XVOP_RECLAIM(vp, rv) \
- rv = _VOP_(vop_reclaim, vp)((vp)->v_fbhv)
-#define XVOP_ATTR_GET(vp, name, val, vallenp, fl, cred, rv) \
- rv = _VOP_(vop_attr_get, vp)((vp)->v_fbhv,name,val,vallenp,fl,cred)
-#define XVOP_ATTR_SET(vp, name, val, vallen, fl, cred, rv) \
- rv = _VOP_(vop_attr_set, vp)((vp)->v_fbhv,name,val,vallen,fl,cred)
-#define XVOP_ATTR_REMOVE(vp, name, flags, cred, rv) \
- rv = _VOP_(vop_attr_remove, vp)((vp)->v_fbhv,name,flags,cred)
-#define XVOP_ATTR_LIST(vp, buf, buflen, fl, cursor, cred, rv) \
- rv = _VOP_(vop_attr_list, vp)((vp)->v_fbhv,buf,buflen,fl,cursor,cred)
-#define XVOP_LINK_REMOVED(vp, dvp, linkzero) \
- (void)_VOP_(vop_link_removed, vp)((vp)->v_fbhv, dvp, linkzero)
-#define XVOP_VNODE_CHANGE(vp, cmd, val) \
- (void)_VOP_(vop_vnode_change, vp)((vp)->v_fbhv,cmd,val)
-/*
- * These are page cache functions that now go thru VOPs.
- * 'last' parameter is unused and left in for IRIX compatibility
- */
-#define XVOP_TOSS_PAGES(vp, first, last, fiopt) \
- _VOP_(vop_tosspages, vp)((vp)->v_fbhv,first, last, fiopt)
-/*
- * 'last' parameter is unused and left in for IRIX compatibility
- */
-#define XVOP_FLUSHINVAL_PAGES(vp, first, last, fiopt) \
- _VOP_(vop_flushinval_pages, vp)((vp)->v_fbhv,first,last,fiopt)
-/*
- * 'last' parameter is unused and left in for IRIX compatibility
- */
-#define XVOP_FLUSH_PAGES(vp, first, last, flags, fiopt, rv) \
- rv = _VOP_(vop_flush_pages, vp)((vp)->v_fbhv,first,last,flags,fiopt)
-#define XVOP_IOCTL(vp, inode, filp, fl, cmd, arg, rv) \
- rv = _VOP_(vop_ioctl, vp)((vp)->v_fbhv,inode,filp,fl,cmd,arg)
-#define XVOP_IFLUSH(vp, flags, rv) \
- rv = _VOP_(vop_iflush, vp)((vp)->v_fbhv, flags)
-
-/*
- * Flags for read/write calls - select values from FreeBSD IO_ flags
- * or non-conflicting bits.
- */
-#define IO_ISDIRECT IO_DIRECT /* bypass page cache */
-#define IO_INVIS 0x02000 /* don't update inode timestamps */
-/* #define IO_ISLOCKED 0x04000 don't do inode locking, strictly a CXFS thing */
-
-/*
- * Flags for VOP_IFLUSH call
- */
-#define FLUSH_SYNC 1 /* wait for flush to complete */
-#define FLUSH_INODE 2 /* flush the inode itself */
-#define FLUSH_LOG 4 /* force the last log entry for
- * this inode out to disk */
-
-/*
- * Flush/Invalidate options for VOP_TOSS_PAGES, VOP_FLUSHINVAL_PAGES and
- * VOP_FLUSH_PAGES.
- */
-#define FI_NONE 0 /* none */
-#define FI_REMAPF 1 /* Do a remapf prior to the operation */
-#define FI_REMAPF_LOCKED 2 /* Do a remapf prior to the operation.
- Prevent VM access to the pages until
- the operation completes. */
-
-/*
- * Vnode attributes. va_mask indicates those attributes the caller
- * wants to set or extract.
- */
-typedef struct xfs_vattr {
- int va_mask; /* bit-mask of attributes present */
- mode_t va_mode; /* file access mode and type */
- nlink_t va_nlink; /* number of references to file */
- uid_t va_uid; /* owner user id */
- gid_t va_gid; /* owner group id */
- xfs_ino_t va_nodeid; /* file id */
- xfs_off_t va_size; /* file size in bytes */
- u_long va_blocksize; /* blocksize preferred for i/o */
- struct timespec va_atime; /* time of last access */
- struct timespec va_mtime; /* time of last modification */
- struct timespec va_ctime; /* time file changed */
- u_int va_gen; /* generation number of file */
- xfs_dev_t va_rdev; /* device the special file represents */
- __int64_t va_nblocks; /* number of blocks allocated */
- u_long va_xflags; /* random extended file flags */
- u_long va_extsize; /* file extent size */
- u_long va_nextents; /* number of extents in file */
- u_long va_anextents; /* number of attr extents in file */
- int va_projid; /* project id */
-} xfs_vattr_t;
-
-/*
- * setattr or getattr attributes
- */
-#define XFS_AT_TYPE 0x00000001
-#define XFS_AT_MODE 0x00000002
-#define XFS_AT_UID 0x00000004
-#define XFS_AT_GID 0x00000008
-#define XFS_AT_FSID 0x00000010
-#define XFS_AT_NODEID 0x00000020
-#define XFS_AT_NLINK 0x00000040
-#define XFS_AT_SIZE 0x00000080
-#define XFS_AT_ATIME 0x00000100
-#define XFS_AT_MTIME 0x00000200
-#define XFS_AT_CTIME 0x00000400
-#define XFS_AT_RDEV 0x00000800
-#define XFS_AT_BLKSIZE 0x00001000
-#define XFS_AT_NBLOCKS 0x00002000
-#define XFS_AT_VCODE 0x00004000
-#define XFS_AT_MAC 0x00008000
-#define XFS_AT_UPDATIME 0x00010000
-#define XFS_AT_UPDMTIME 0x00020000
-#define XFS_AT_UPDCTIME 0x00040000
-#define XFS_AT_ACL 0x00080000
-#define XFS_AT_CAP 0x00100000
-#define XFS_AT_INF 0x00200000
-#define XFS_AT_XFLAGS 0x00400000
-#define XFS_AT_EXTSIZE 0x00800000
-#define XFS_AT_NEXTENTS 0x01000000
-#define XFS_AT_ANEXTENTS 0x02000000
-#define XFS_AT_PROJID 0x04000000
-#define XFS_AT_SIZE_NOPERM 0x08000000
-#define XFS_AT_GENCOUNT 0x10000000
-
-#define XFS_AT_ALL (XFS_AT_TYPE|XFS_AT_MODE|XFS_AT_UID|XFS_AT_GID|\
- XFS_AT_FSID|XFS_AT_NODEID|XFS_AT_NLINK|XFS_AT_SIZE|\
- XFS_AT_ATIME|XFS_AT_MTIME|XFS_AT_CTIME|XFS_AT_RDEV|\
- XFS_AT_BLKSIZE|XFS_AT_NBLOCKS|XFS_AT_VCODE|XFS_AT_MAC|\
- XFS_AT_ACL|XFS_AT_CAP|XFS_AT_INF|XFS_AT_XFLAGS|XFS_AT_EXTSIZE|\
- XFS_AT_NEXTENTS|XFS_AT_ANEXTENTS|XFS_AT_PROJID|XFS_AT_GENCOUNT)
-
-#define XFS_AT_STAT (XFS_AT_TYPE|XFS_AT_MODE|XFS_AT_UID|XFS_AT_GID|\
- XFS_AT_FSID|XFS_AT_NODEID|XFS_AT_NLINK|XFS_AT_SIZE|\
- XFS_AT_ATIME|XFS_AT_MTIME|XFS_AT_CTIME|XFS_AT_RDEV|\
- XFS_AT_BLKSIZE|XFS_AT_NBLOCKS|XFS_AT_PROJID)
-
-#define XFS_AT_TIMES (XFS_AT_ATIME|XFS_AT_MTIME|XFS_AT_CTIME)
-
-#define XFS_AT_UPDTIMES (XFS_AT_UPDATIME|XFS_AT_UPDMTIME|XFS_AT_UPDCTIME)
-
-#define XFS_AT_NOSET (XFS_AT_NLINK|XFS_AT_RDEV|XFS_AT_FSID|XFS_AT_NODEID|\
- XFS_AT_TYPE|XFS_AT_BLKSIZE|XFS_AT_NBLOCKS|XFS_AT_VCODE|\
- XFS_AT_NEXTENTS|XFS_AT_ANEXTENTS|XFS_AT_GENCOUNT)
-
-#ifndef __FreeBSD__
-/*
- * Modes.
- */
-#define VSUID S_ISUID /* set user id on execution */
-#define VSGID S_ISGID /* set group id on execution */
-#define VSVTX S_ISVTX /* save swapped text even after use */
-#define VREAD S_IRUSR /* read, write, execute permissions */
-#define VWRITE S_IWUSR
-#define VEXEC S_IXUSR
-#endif /* __FreeBSD__ */
-
-#define MODEMASK ALLPERMS /* mode bits plus permission bits */
-
-/*
- * Check whether mandatory file locking is enabled.
- */
-#define MANDLOCK(vp, mode) \
- ((vp)->v_vnode->v_type == VREG && ((mode) & (S_ISGID|(VEXEC>>3))) == S_ISGID)
-
-extern void vn_init(void);
-extern int vn_wait(struct xfs_vnode *);
-extern void vn_iowait(struct xfs_vnode *);
-extern xfs_vnode_t *vn_initialize(struct xfs_vnode *);
-
-/*
- * Acquiring and invalidating vnodes:
- *
- * if (vn_get(vp, version, 0))
- * ...;
- * vn_purge(vp, version);
- *
- * vn_get and vn_purge must be called with vmap_t arguments, sampled
- * while a lock that the vnode's VOP_RECLAIM function acquires is
- * held, to ensure that the vnode sampled with the lock held isn't
- * recycled (VOP_RECLAIMed) or deallocated between the release of the lock
- * and the subsequent vn_get or vn_purge.
- */
-
-/*
- * vnode_map structures _must_ match vn_epoch and vnode structure sizes.
- */
-typedef struct vnode_map {
- xfs_vfs_t *v_vfsp;
- xfs_ino_t v_ino;
- struct vnode *v_vp;
-} vmap_t;
-
-#if 1
-#define VMAP(vp, vmap) {(vmap).v_vfsp = (vp)->v_vfsp; \
- (vmap).v_vp = (vp)->v_vnode; \
- (vmap).v_ino = (vp)->v_inode->i_ino;\
- vhold((vp)->v_vnode); \
- }
-#endif
-
-extern void vn_purge(struct xfs_vnode *);
-extern xfs_vnode_t *vn_get(struct xfs_vnode *, vmap_t *);
-extern int vn_revalidate(struct xfs_vnode *);
-
-static inline int vn_count(struct xfs_vnode *vp)
-{
- return vp->v_vnode->v_usecount;
-}
-
-/*
- * Vnode reference counting functions (and macros for compatibility).
- */
-extern xfs_vnode_t *vn_hold(struct xfs_vnode *);
-extern void vn_rele(struct xfs_vnode *);
-
-#if defined(XFS_VNODE_TRACE)
-#define VN_HOLD(vp) \
- ((void)vref((vp)->v_vnode), \
- vn_trace_hold(vp, __FILE__, __LINE__, (inst_t *)__return_address))
-#define VN_RELE(vp) \
- (vn_trace_rele(vp, __FILE__, __LINE__, (inst_t *)__return_address), \
- vrele((vp)->v_vnode))
-#else
-#define VN_HOLD(vp) vref((vp)->v_vnode)
-#define VN_RELE(vp) vrele((vp)->v_vnode)
-#endif
-
-/*
- * Vname handling macros.
- */
-#define VNAME(cnp) ((cnp)->cn_nameptr)
-#define VNAMELEN(cnp) ((cnp)->cn_namelen)
-#define VNAME_TO_VNODE(dentry) (printf("VNAME_TO_VNODE NI"), (xfs_vnode_t *)0)
-
-/*
- * Vnode spinlock manipulation.
- */
-#define VN_LOCK(vp) VI_LOCK(vp->v_vnode)
-#define VN_UNLOCK(vp, s) VI_UNLOCK(vp->v_vnode)
-#define VN_FLAGSET(vp,b) vn_flagset(vp,b)
-#define VN_FLAGCLR(vp,b) vn_flagclr(vp,b)
-
-static __inline__ void vn_flagset(struct xfs_vnode *vp, __u32 flag)
-{
- VN_LOCK(vp);
- vp->v_flag |= flag;
- VN_UNLOCK(vp, 0);
-}
-
-static __inline__ void vn_flagclr(struct xfs_vnode *vp, __u32 flag)
-{
- VN_LOCK(vp);
- vp->v_flag &= ~flag;
- VN_UNLOCK(vp, 0);
-}
-
-/*
- * Update modify/access/change times on the vnode
- */
-#define VN_MTIMESET(vp, tvp)
-#define VN_ATIMESET(vp, tvp)
-#define VN_CTIMESET(vp, tvp)
-
-/*
- * Some useful predicates.
- */
-#define VN_MAPPED(vp) 0
-#define VN_CACHED(vp) 0
-#define VN_DIRTY(vp) 0
-#define VMODIFY(vp) VN_FLAGSET(vp, VMODIFIED)
-#define VUNMODIFY(vp) VN_FLAGCLR(vp, VMODIFIED)
-
-
-/*
- * Flags to VOP_SETATTR/VOP_GETATTR.
- */
-#define ATTR_UTIME 0x01 /* non-default utime(2) request */
-#define ATTR_DMI 0x08 /* invocation from a DMI function */
-#define ATTR_LAZY 0x80 /* set/get attributes lazily */
-#define ATTR_NONBLOCK 0x100 /* return EAGAIN if operation would block */
-#define ATTR_NOLOCK 0x200 /* Don't grab any conflicting locks */
-#define ATTR_NOSIZETOK 0x400 /* Don't get the SIZE token */
-
-/*
- * Flags to VOP_FSYNC and VOP_RECLAIM.
- */
-#define FSYNC_NOWAIT 0 /* asynchronous flush */
-#define FSYNC_WAIT 0x1 /* synchronous fsync or forced reclaim */
-#define FSYNC_INVAL 0x2 /* flush and invalidate cached data */
-#define FSYNC_DATA 0x4 /* synchronous fsync of data only */
-
-
-static inline struct xfs_vnode *vn_grab(struct xfs_vnode *vp)
-{
- printf("vn_grab NI\n");
-// struct inode *inode = igrab(vn_to_inode(vp));
-// return inode ? vn_from_inode(inode) : NULL;
- return NULL;
-}
-
-static inline void vn_atime_to_bstime(struct xfs_vnode *vp, xfs_bstime_t *bs_atime)
-{
- printf("%s NI\n", __func__);
-// bs_atime->tv_sec = vp->v_inode.i_atime.tv_sec;
-// bs_atime->tv_nsec = vp->v_inode.i_atime.tv_nsec;
-}
-
-static inline void vn_atime_to_timespec(struct xfs_vnode *vp, struct timespec *ts)
-{
-// *ts = vp->v_vnode->va_atime;
-}
-
-/*
- * Tracking vnode activity.
- */
-#if defined(XFS_VNODE_TRACE)
-
-#define VNODE_TRACE_SIZE 16 /* number of trace entries */
-#define VNODE_KTRACE_ENTRY 1
-#define VNODE_KTRACE_EXIT 2
-#define VNODE_KTRACE_HOLD 3
-#define VNODE_KTRACE_REF 4
-#define VNODE_KTRACE_RELE 5
-
-extern void vn_trace_entry(struct xfs_vnode *, char *, inst_t *);
-extern void vn_trace_exit(struct xfs_vnode *, char *, inst_t *);
-extern void vn_trace_hold(struct xfs_vnode *, char *, int, inst_t *);
-extern void vn_trace_ref(struct xfs_vnode *, char *, int, inst_t *);
-extern void vn_trace_rele(struct xfs_vnode *, char *, int, inst_t *);
-
-
-
-#define VN_TRACE(vp) \
- vn_trace_ref(vp, __FILE__, __LINE__, (inst_t *)__return_address)
-#else
-#define vn_trace_entry(a,b,c)
-#define vn_trace_exit(a,b,c)
-#define vn_trace_hold(a,b,c,d)
-#define vn_trace_ref(a,b,c,d)
-#define vn_trace_rele(a,b,c,d)
-#define VN_TRACE(vp)
-#endif
-
-#endif /* __XFS_VNODE_H__ */
diff --git a/sys/gnu/fs/xfs/FreeBSD/xfs_vnops.c b/sys/gnu/fs/xfs/FreeBSD/xfs_vnops.c
deleted file mode 100644
index 01aa0e5..0000000
--- a/sys/gnu/fs/xfs/FreeBSD/xfs_vnops.c
+++ /dev/null
@@ -1,1680 +0,0 @@
-/*
- * Copyright (c) 2001, Alexander Kabaev
- * Copyright (c) 2006, Russell Cattelan Digital Elves Inc.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * $FreeBSD$
- */
-#include <sys/param.h>
-#include <sys/systm.h>
-#include <sys/namei.h>
-#include <sys/kernel.h>
-#include <sys/fcntl.h>
-#include <sys/mount.h>
-#include <sys/unistd.h>
-#include <sys/vnode.h>
-#include <sys/dirent.h>
-#include <sys/ioccom.h>
-#include <sys/malloc.h>
-#include <sys/extattr.h>
-
-#include <vm/vm.h>
-#include <vm/vm_extern.h>
-#include <vm/vm_object.h>
-#include <vm/vm_page.h>
-#include <vm/vm_pager.h>
-#include <vm/vnode_pager.h>
-
-#define NO_VFS_MACROS
-#include "xfs.h"
-#include "xfs_types.h"
-#include "xfs_bit.h"
-#include "xfs_inum.h"
-#include "xfs_log.h"
-#include "xfs_trans.h"
-#include "xfs_trans_priv.h"
-#include "xfs_sb.h"
-#include "xfs_ag.h"
-#include "xfs_dir.h"
-#include "xfs_dir2.h"
-#include "xfs_dmapi.h"
-#include "xfs_mount.h"
-#include "xfs_alloc_btree.h"
-#include "xfs_bmap_btree.h"
-#include "xfs_ialloc_btree.h"
-#include "xfs_btree.h"
-#include "xfs_imap.h"
-#include "xfs_attr.h"
-#include "xfs_attr_sf.h"
-#include "xfs_dir_sf.h"
-#include "xfs_dir2_sf.h"
-#include "xfs_dinode.h"
-#include "xfs_ialloc.h"
-#include "xfs_alloc.h"
-#include "xfs_inode.h"
-#include "xfs_inode_item.h"
-#include "xfs_acl.h"
-#include "xfs_cap.h"
-#include "xfs_mac.h"
-#include "xfs_iomap.h"
-#include "xfs_clnt.h"
-#include "xfs_mountops.h"
-
-/*
- * Prototypes for XFS vnode operations.
- */
-static vop_access_t _xfs_access;
-static vop_advlock_t _xfs_advlock;
-static vop_bmap_t _xfs_bmap;
-static vop_cachedlookup_t _xfs_cachedlookup;
-static vop_close_t _xfs_close;
-static vop_create_t _xfs_create;
-static vop_deleteextattr_t _xfs_deleteextattr;
-static vop_fsync_t _xfs_fsync;
-static vop_getattr_t _xfs_getattr;
-static vop_getextattr_t _xfs_getextattr;
-static vop_inactive_t _xfs_inactive;
-static vop_ioctl_t _xfs_ioctl;
-static vop_link_t _xfs_link;
-static vop_listextattr_t _xfs_listextattr;
-static vop_mkdir_t _xfs_mkdir;
-static vop_mknod_t _xfs_mknod;
-static vop_open_t _xfs_open;
-static vop_read_t _xfs_read;
-static vop_readdir_t _xfs_readdir;
-static vop_readlink_t _xfs_readlink;
-static vop_reclaim_t _xfs_reclaim;
-static vop_remove_t _xfs_remove;
-static vop_rename_t _xfs_rename;
-static vop_rmdir_t _xfs_rmdir;
-static vop_setattr_t _xfs_setattr;
-static vop_setextattr_t _xfs_setextattr;
-static vop_strategy_t _xfs_strategy;
-static vop_symlink_t _xfs_symlink;
-static vop_write_t _xfs_write;
-static vop_vptofh_t _xfs_vptofh;
-
-struct vop_vector xfs_vnops = {
- .vop_default = &default_vnodeops,
- .vop_access = _xfs_access,
- .vop_advlock = _xfs_advlock,
- .vop_bmap = _xfs_bmap,
- .vop_cachedlookup = _xfs_cachedlookup,
- .vop_close = _xfs_close,
- .vop_create = _xfs_create,
- .vop_deleteextattr = _xfs_deleteextattr,
- .vop_fsync = _xfs_fsync,
- .vop_getattr = _xfs_getattr,
- .vop_getextattr = _xfs_getextattr,
- .vop_inactive = _xfs_inactive,
- .vop_ioctl = _xfs_ioctl,
- .vop_link = _xfs_link,
- .vop_listextattr = _xfs_listextattr,
- .vop_lookup = vfs_cache_lookup,
- .vop_mkdir = _xfs_mkdir,
- .vop_mknod = _xfs_mknod,
- .vop_open = _xfs_open,
- .vop_read = _xfs_read,
- .vop_readdir = _xfs_readdir,
- .vop_readlink = _xfs_readlink,
- .vop_reclaim = _xfs_reclaim,
- .vop_remove = _xfs_remove,
- .vop_rename = _xfs_rename,
- .vop_rmdir = _xfs_rmdir,
- .vop_setattr = _xfs_setattr,
- .vop_setextattr = _xfs_setextattr,
- .vop_strategy = _xfs_strategy,
- .vop_symlink = _xfs_symlink,
- .vop_write = _xfs_write,
- .vop_vptofh = _xfs_vptofh,
-};
-
-/*
- * FIFO's specific operations.
- */
-
-static vop_close_t _xfsfifo_close;
-static vop_read_t _xfsfifo_read;
-static vop_kqfilter_t _xfsfifo_kqfilter;
-static vop_write_t _xfsfifo_write;
-
-struct vop_vector xfs_fifoops = {
- .vop_default = &fifo_specops,
- .vop_access = _xfs_access,
- .vop_close = _xfsfifo_close,
- .vop_fsync = _xfs_fsync,
- .vop_getattr = _xfs_getattr,
- .vop_inactive = _xfs_inactive,
- .vop_kqfilter = _xfsfifo_kqfilter,
- .vop_read = _xfsfifo_read,
- .vop_reclaim = _xfs_reclaim,
- .vop_setattr = _xfs_setattr,
- .vop_write = _xfsfifo_write,
- .vop_vptofh = _xfs_vptofh,
-};
-
-static int
-_xfs_access(
- struct vop_access_args /* {
- struct vnode *a_vp;
- accmode_t a_accmode;
- struct ucred *a_cred;
- struct thread *a_td;
- } */ *ap)
-{
- int error;
-
- XVOP_ACCESS(VPTOXFSVP(ap->a_vp), ap->a_accmode, ap->a_cred, error);
- return (error);
-}
-
-static int
-_xfs_open(
- struct vop_open_args /* {
- struct vnode *a_vp;
- int a_mode;
- struct ucred *a_cred;
- struct thread *a_td;
- struct file *a_fp;
- } */ *ap)
-{
- int error;
-
- XVOP_OPEN(VPTOXFSVP(ap->a_vp), ap->a_cred, error);
- if (error == 0)
- vnode_create_vobject(ap->a_vp, 0, ap->a_td);
- return (error);
-}
-
-static int
-_xfs_close(
- struct vop_close_args /* {
- struct vnodeop_desc *a_desc;
- struct vnode *a_vp;
- int a_fflag;
- struct ucred *a_cred;
- struct thread *a_td;
- } */ *ap)
-{
- int error = 0;
- /* XVOP_CLOSE(VPTOXFSVP(ap->a_vp), NULL, error); */
- return (error);
-}
-
-static int
-_xfs_getattr(
- struct vop_getattr_args /* {
- struct vnode *a_vp;
- struct vattr *a_vap;
- struct ucred *a_cred;
- } */ *ap)
-{
- struct vnode *vp = ap->a_vp;
- struct vattr *vap = ap->a_vap;
- struct mount *mp;
- xfs_vattr_t va;
- int error;
- /* extract the xfs vnode from the private data */
- //xfs_vnode_t *xvp = (xfs_vnode_t *)vp->v_data;
-
- memset(&va,0,sizeof(xfs_vattr_t));
- va.va_mask = XFS_AT_STAT|XFS_AT_GENCOUNT|XFS_AT_XFLAGS;
-
- XVOP_GETATTR(VPTOXFSVP(vp), &va, 0, ap->a_cred, error);
- if (error)
- return (error);
-
- mp = vp->v_mount;
-
- vap->va_type = IFTOVT(((xfs_vnode_t *)vp->v_data)->v_inode->i_d.di_mode);
- vap->va_mode = va.va_mode;
- vap->va_nlink = va.va_nlink;
- vap->va_uid = va.va_uid;
- vap->va_gid = va.va_gid;
- vap->va_fsid = mp->mnt_stat.f_fsid.val[0];
- vap->va_fileid = va.va_nodeid;
- vap->va_size = va.va_size;
- vap->va_blocksize = va.va_blocksize;
- vap->va_atime = va.va_atime;
- vap->va_mtime = va.va_mtime;
- vap->va_ctime = va.va_ctime;
- vap->va_gen = va.va_gen;
- vap->va_rdev = va.va_rdev;
- vap->va_bytes = (va.va_nblocks << BBSHIFT);
-
- /* XFS now supports devices that have block sizes
- * other than 512 so BBSHIFT will work for now
- * but need to get this value from the super block
- */
-
- /*
- * Fields with no direct equivalent in XFS
- */
- vap->va_filerev = 0;
- vap->va_flags = 0;
-
- return (0);
-}
-
-static int
-_xfs_setattr(
- struct vop_setattr_args /* {
- struct vnode *a_vp;
- struct vattr *a_vap;
- struct ucred *a_cred;
- } */ *ap)
-{
- struct vnode *vp = ap->a_vp;
- struct vattr *vap = ap->a_vap;
- xfs_vattr_t va;
- int error;
-
- /*
- * Check for unsettable attributes.
- */
-#ifdef RMC
- if ((vap->va_type != VNON) || (vap->va_nlink != VNOVAL) ||
- (vap->va_fsid != VNOVAL) || (vap->va_fileid != VNOVAL) ||
- (vap->va_blocksize != VNOVAL) || (vap->va_rdev != VNOVAL) ||
- ((int)vap->va_bytes != VNOVAL) || (vap->va_gen != VNOVAL))
- return (EINVAL);
-#endif
-
- memset(&va, 0, sizeof(va));
-
- if (vap->va_uid != (uid_t)VNOVAL) {
- va.va_mask |= XFS_AT_UID;
- va.va_uid = vap->va_uid;
- }
- if (vap->va_gid != (gid_t)VNOVAL) {
- va.va_mask |= XFS_AT_GID;
- va.va_gid = vap->va_gid;
- }
- if (vap->va_size != VNOVAL) {
- va.va_mask |= XFS_AT_SIZE;
- va.va_size = vap->va_size;
- }
- if (vap->va_atime.tv_sec != VNOVAL) {
- va.va_mask |= XFS_AT_ATIME;
- va.va_atime = vap->va_atime;
- }
- if (vap->va_mtime.tv_sec != VNOVAL) {
- va.va_mask |= XFS_AT_MTIME;
- va.va_mtime = vap->va_mtime;
- }
- if (vap->va_ctime.tv_sec != VNOVAL) {
- va.va_mask |= XFS_AT_CTIME;
- va.va_ctime = vap->va_ctime;
- }
- if (vap->va_mode != (mode_t)VNOVAL) {
- va.va_mask |= XFS_AT_MODE;
- va.va_mode = vap->va_mode;
- }
-
- XVOP_SETATTR(VPTOXFSVP(vp), &va, 0, ap->a_cred, error);
- return (error);
-}
-
-static int
-_xfs_inactive(
- struct vop_inactive_args /* {
- struct vnode *a_vp;
- struct thread *a_td;
- } */ *ap)
-{
- struct vnode *vp = ap->a_vp;
- struct thread *td = ap->a_td;
- int error;
-
- XVOP_INACTIVE(VPTOXFSVP(vp), td->td_ucred, error);
- return (error);
-}
-
-static int
-_xfs_read(
- struct vop_read_args /* {
- struct vnode *a_vp;
- struct uio *a_uio;
- int a_ioflag;
- struct ucred *a_cred;
- } */ *ap)
-{
- struct vnode *vp = ap->a_vp;
- struct uio *uio = ap->a_uio;
- int error;
-
- switch (vp->v_type) {
- case VREG:
- break;
- case VDIR:
- return (EISDIR);
- default:
- return (EPERM);
- };
-
- XVOP_READ(VPTOXFSVP(vp), uio, ap->a_ioflag, ap->a_cred, error);
- return error;
-}
-
-int
-xfs_read_file(xfs_mount_t *mp, xfs_inode_t *ip, struct uio *uio, int ioflag)
-{
- xfs_fileoff_t lbn, nextlbn;
- xfs_fsize_t bytesinfile;
- long size, xfersize, blkoffset;
- struct buf *bp;
- struct vnode *vp;
- int error, orig_resid;
- int seqcount;
-
- seqcount = ioflag >> IO_SEQSHIFT;
-
- orig_resid = uio->uio_resid;
- if (orig_resid <= 0)
- return (0);
-
- vp = XFS_ITOV(ip)->v_vnode;
-
- /*
- * Ok so we couldn't do it all in one vm trick...
- * so cycle around trying smaller bites..
- */
- for (error = 0, bp = NULL; uio->uio_resid > 0; bp = NULL) {
- if ((bytesinfile = ip->i_d.di_size - uio->uio_offset) <= 0)
- break;
-
- lbn = XFS_B_TO_FSBT(mp, uio->uio_offset);
- nextlbn = lbn + 1;
-
- /*
- * size of buffer. The buffer representing the
- * end of the file is rounded up to the size of
- * the block type ( fragment or full block,
- * depending ).
- */
- size = mp->m_sb.sb_blocksize;
- blkoffset = XFS_B_FSB_OFFSET(mp, uio->uio_offset);
-
- /*
- * The amount we want to transfer in this iteration is
- * one FS block less the amount of the data before
- * our startpoint (duh!)
- */
- xfersize = mp->m_sb.sb_blocksize - blkoffset;
-
- /*
- * But if we actually want less than the block,
- * or the file doesn't have a whole block more of data,
- * then use the lesser number.
- */
- if (uio->uio_resid < xfersize)
- xfersize = uio->uio_resid;
- if (bytesinfile < xfersize)
- xfersize = bytesinfile;
-
- if (XFS_FSB_TO_B(mp, nextlbn) >= ip->i_d.di_size ) {
- /*
- * Don't do readahead if this is the end of the file.
- */
- error = bread(vp, lbn, size, NOCRED, &bp);
- } else if ((vp->v_mount->mnt_flag & MNT_NOCLUSTERR) == 0) {
- /*
- * Otherwise if we are allowed to cluster,
- * grab as much as we can.
- *
- * XXX This may not be a win if we are not
- * doing sequential access.
- */
- error = cluster_read(vp, ip->i_d.di_size, lbn,
- size, NOCRED, uio->uio_resid, seqcount, &bp);
- } else if (seqcount > 1) {
- /*
- * If we are NOT allowed to cluster, then
- * if we appear to be acting sequentially,
- * fire off a request for a readahead
- * as well as a read. Note that the 4th and 5th
- * arguments point to arrays of the size specified in
- * the 6th argument.
- */
- int nextsize = mp->m_sb.sb_blocksize;
- error = breadn(vp, lbn,
- size, &nextlbn, &nextsize, 1, NOCRED, &bp);
- } else {
- /*
- * Failing all of the above, just read what the
- * user asked for. Interestingly, the same as
- * the first option above.
- */
- error = bread(vp, lbn, size, NOCRED, &bp);
- }
- if (error) {
- brelse(bp);
- bp = NULL;
- break;
- }
-
- /*
- * If IO_DIRECT then set B_DIRECT for the buffer. This
- * will cause us to attempt to release the buffer later on
- * and will cause the buffer cache to attempt to free the
- * underlying pages.
- */
- if (ioflag & IO_DIRECT)
- bp->b_flags |= B_DIRECT;
-
- /*
- * We should only get non-zero b_resid when an I/O error
- * has occurred, which should cause us to break above.
- * However, if the short read did not cause an error,
- * then we want to ensure that we do not uiomove bad
- * or uninitialized data.
- */
- size -= bp->b_resid;
- if (size < xfersize) {
- if (size == 0)
- break;
- xfersize = size;
- }
-
- /*
- * otherwise use the general form
- */
- error = uiomove((char *)bp->b_data + blkoffset,
- (int)xfersize, uio);
-
- if (error)
- break;
-
- if (ioflag & (IO_VMIO|IO_DIRECT) ) {
- /*
- * If there are no dependencies, and it's VMIO,
- * then we don't need the buf, mark it available
- * for freeing. The VM has the data.
- */
- bp->b_flags |= B_RELBUF;
- brelse(bp);
- } else {
- /*
- * Otherwise let whoever
- * made the request take care of
- * freeing it. We just queue
- * it onto another list.
- */
- bqrelse(bp);
- }
- }
-
- /*
- * This can only happen in the case of an error
- * because the loop above resets bp to NULL on each iteration
- * and on normal completion has not set a new value into it.
- * so it must have come from a 'break' statement
- */
- if (bp != NULL) {
- if (ioflag & (IO_VMIO|IO_DIRECT)) {
- bp->b_flags |= B_RELBUF;
- brelse(bp);
- } else
- bqrelse(bp);
- }
-
- return (error);
-}
-
-static int
-_xfs_write(struct vop_write_args /* {
- struct vnode *a_vp;
- struct uio *a_uio;
- int a_ioflag;
- struct ucred *a_cred;
- } */ *ap)
-{
- struct vnode *vp = ap->a_vp;
- struct uio *uio = ap->a_uio;
- int ioflag = ap->a_ioflag;
- int error;
-
- xfs_vnode_t *xvp = (xfs_vnode_t *)vp->v_data;
-
- error = xfs_write(xvp->v_bh.bh_first, uio, ioflag, ap->a_cred);
-
- if (error < 0) {
- printf("Xfs_write got error %d\n",error);
- return -error;
- }
- return 0;
-}
-
-
-int
-xfs_write_file(xfs_inode_t *xip, struct uio *uio, int ioflag)
-{
- struct buf *bp;
- //struct thread *td;
- daddr_t lbn;
- off_t osize = 0;
- off_t offset= 0;
- int blkoffset, error, resid, xfersize;
- int fsblocksize;
- int seqcount;
- xfs_iomap_t iomap;
- int maps = 1;
-
- xfs_vnode_t *xvp = XFS_ITOV(xip);
- struct vnode *vp = xvp->v_vnode;
-
- xfs_mount_t *mp = (&xip->i_iocore)->io_mount;
-
- seqcount = ioflag >> IO_SEQSHIFT;
-
- memset(&iomap,0,sizeof(xfs_iomap_t));
-
- /*
- * Maybe this should be above the vnode op call, but so long as
- * file servers have no limits, I don't think it matters.
- */
-#if 0
- td = uio->uio_td;
- if (vn_rlimit_fsize(vp, uio, uio->uio_td))
- return (EFBIG);
-#endif
-
- resid = uio->uio_resid;
- offset = uio->uio_offset;
- osize = xip->i_d.di_size;
-
- /* xfs bmap wants bytes for both offset and size */
- XVOP_BMAP(xvp,
- uio->uio_offset,
- uio->uio_resid,
- BMAPI_WRITE|BMAPI_DIRECT,
- &iomap, &maps, error);
- if(error) {
- printf("XVOP_BMAP failed\n");
- goto error;
- }
-
- for (error = 0; uio->uio_resid > 0;) {
-
- lbn = XFS_B_TO_FSBT(mp, offset);
- blkoffset = XFS_B_FSB_OFFSET(mp, offset);
- xfersize = mp->m_sb.sb_blocksize - blkoffset;
- fsblocksize = mp->m_sb.sb_blocksize;
-
- if (uio->uio_resid < xfersize)
- xfersize = uio->uio_resid;
-
- /*
- * getblk sets buf by blkno * bo->bo_bsize
- * bo_bsize is set from the mnt point fsize
- * so we call getblk in the case using fsblocks
- * not basic blocks
- */
-
- bp = getblk(vp, lbn, fsblocksize, 0, 0, 0);
- if(!bp) {
- printf("getblk failed\n");
- error = EINVAL;
- break;
- }
-
- if (!(bp->b_flags & B_CACHE) && fsblocksize > xfersize)
- vfs_bio_clrbuf(bp);
-
- if (offset + xfersize > xip->i_d.di_size) {
- xip->i_d.di_size = offset + xfersize;
- vnode_pager_setsize(vp, offset + fsblocksize);
- }
-
- /* move the offset for the next itteration of the loop */
- offset += xfersize;
-
- error = uiomove((char *)bp->b_data + blkoffset, xfersize, uio);
-
- if ((ioflag & IO_VMIO) &&
- (LIST_FIRST(&bp->b_dep) == NULL)) /* in ext2fs? */
- bp->b_flags |= B_RELBUF;
-
- /* force to full direct for now */
- bp->b_flags |= B_DIRECT;
- /* and sync ... the delay path is not pushing data out */
- ioflag |= IO_SYNC;
-
- if (ioflag & IO_SYNC) {
- (void)bwrite(bp);
- } else if (0 /* RMC xfersize + blkoffset == fs->s_frag_size */) {
- if ((vp->v_mount->mnt_flag & MNT_NOCLUSTERW) == 0) {
- bp->b_flags |= B_CLUSTEROK;
- cluster_write(vp, bp, osize, seqcount);
- } else {
- bawrite(bp);
- }
- } else {
- bp->b_flags |= B_CLUSTEROK;
- bdwrite(bp);
- }
- if (error || xfersize == 0)
- break;
- }
- /*
- * If we successfully wrote any data, and we are not the superuser
- * we clear the setuid and setgid bits as a precaution against
- * tampering.
- */
-#if 0
- if (resid > uio->uio_resid && ap->a_cred && ap->a_cred->cr_uid != 0)
- ip->i_mode &= ~(ISUID | ISGID);
-#endif
- if (error) {
- if (ioflag & IO_UNIT) {
-#if 0
- (void)ext2_truncate(vp, osize,
- ioflag & IO_SYNC, ap->a_cred, uio->uio_td);
-#endif
- uio->uio_offset -= resid - uio->uio_resid;
- uio->uio_resid = resid;
- }
- } else if (resid > uio->uio_resid && (ioflag & IO_SYNC)) {
- /* Update the vnode here? */
- }
-
-error:
- return error;
-}
-
-static int
-_xfs_create(
- struct vop_create_args /* {
- struct vnode *a_dvp;
- struct vnode **a_vpp;
- struct componentname *a_cnp;
- struct vattr *a_vap;
- } */ *ap)
-{
- struct vnode *dvp = ap->a_dvp;
- struct vattr *vap = ap->a_vap;
- struct thread *td = curthread;
- struct ucred *credp = td->td_ucred;
- struct componentname *cnp = ap->a_cnp;
- xfs_vnode_t *xvp;
- xfs_vattr_t va;
- int error;
-
- memset(&va, 0, sizeof (va));
- va.va_mask |= XFS_AT_MODE;
- va.va_mode = vap->va_mode;
- va.va_mask |= XFS_AT_TYPE;
- va.va_mode |= VTTOIF(vap->va_type);
-
- xvp = NULL;
- XVOP_CREATE(VPTOXFSVP(dvp), cnp, &va, &xvp, credp, error);
-
- if (error == 0) {
- *ap->a_vpp = xvp->v_vnode;
- VOP_LOCK(xvp->v_vnode, LK_EXCLUSIVE);
- }
-
- return (error);
-}
-
-extern int xfs_remove(bhv_desc_t *, bhv_desc_t *, vname_t *, cred_t *);
-
-static int
-_xfs_remove(
- struct vop_remove_args /* {
- struct vnodeop_desc *a_desc;
- struct vnode * a_dvp;
- struct vnode * a_vp;
- struct componentname * a_cnp;
- } */ *ap)
-{
- struct vnode *vp = ap->a_vp;
- struct thread *td = curthread;
- struct ucred *credp = td->td_ucred;
- /*
- struct vnode *dvp = ap->a_dvp;
- struct componentname *cnp = ap->a_cnp;
- */
- int error;
-
- if (vp->v_type == VDIR || vp->v_usecount != 1)
- return (EPERM);
-
- error = xfs_remove(VPTOXFSVP(ap->a_dvp)->v_bh.bh_first,
- VPTOXFSVP(ap->a_vp)->v_bh.bh_first,
- ap->a_cnp,credp);
-
- cache_purge(vp);
- return error;
-}
-
-static int
-_xfs_rename(
- struct vop_rename_args /* {
- struct vnode *a_fdvp;
- struct vnode *a_fvp;
- struct componentname *a_fcnp;
- struct vnode *a_tdvp;
- struct vnode *a_tvp;
- struct componentname *a_tcnp;
- } */ *ap)
-{
- struct vnode *fvp = ap->a_fvp;
- struct vnode *tvp = ap->a_tvp;
- struct vnode *fdvp = ap->a_fdvp;
- struct vnode *tdvp = ap->a_tdvp;
-/* struct componentname *tcnp = ap->a_tcnp; */
-/* struct componentname *fcnp = ap->a_fcnp;*/
- int error = EPERM;
-
- if (error)
- goto out;
-
- /* Check for cross-device rename */
- if ((fvp->v_mount != tdvp->v_mount) ||
- (tvp && (fvp->v_mount != tvp->v_mount))) {
- error = EXDEV;
- goto out;
- }
-
- if (tvp && tvp->v_usecount > 1) {
- error = EBUSY;
- goto out;
- }
-
- if (fvp->v_type == VDIR) {
- if (tvp != NULL && tvp->v_type == VDIR)
- cache_purge(tdvp);
- cache_purge(fdvp);
- }
-out:
- if (tdvp == tvp)
- vrele(tdvp);
- else
- vput(tdvp);
- if (tvp)
- vput(tvp);
- vrele(fdvp);
- vrele(fvp);
- vgone(fvp);
- if (tvp)
- vgone(tvp);
- return (error);
-}
-
-static int
-_xfs_link(
- struct vop_link_args /* {
- struct vnode *a_tdvp;
- struct vnode *a_vp;
- struct componentname *a_cnp;
- } */ *ap)
-{
- xfs_vnode_t *tdvp, *vp;
- int error;
-
- tdvp = VPTOXFSVP(ap->a_tdvp);
- vp = VPTOXFSVP(ap->a_vp);
- XVOP_LINK(tdvp, vp, ap->a_cnp, NULL, error);
- return (error);
-}
-
-static int
-_xfs_symlink(
- struct vop_symlink_args /* {
- struct vnode *a_dvp;
- struct vnode **a_vpp;
- struct componentname *a_cnp;
- struct vattr *a_vap;
- char *a_target;
- } */ *ap)
-{
- struct thread *td = curthread;
- struct ucred *credp = td->td_ucred;
- xfs_vnode_t *xvp;
- xfs_vattr_t va;
- int error;
-
- memset(&va, 0, sizeof (va));
-
- va.va_mask |= XFS_AT_MODE;
- va.va_mode = ap->a_vap->va_mode | S_IFLNK;
- va.va_mask |= XFS_AT_TYPE;
-
- XVOP_SYMLINK(VPTOXFSVP(ap->a_dvp), ap->a_cnp, &va, ap->a_target,
- &xvp, credp, error);
-
- if (error == 0) {
- *ap->a_vpp = xvp->v_vnode;
- VOP_LOCK(xvp->v_vnode, LK_EXCLUSIVE);
- }
-
- return (error);
-}
-
-static int
-_xfs_mknod(
- struct vop_mknod_args /* {
- struct vnode *a_dvp;
- struct vnode **a_vpp;
- struct componentname *a_cnp;
- struct vattr *a_vap;
- } */ *ap)
-{
- struct vnode *dvp = ap->a_dvp;
- struct vattr *vap = ap->a_vap;
- struct thread *td = curthread;
- struct ucred *credp = td->td_ucred;
- struct componentname *cnp = ap->a_cnp;
- xfs_vnode_t *xvp;
- xfs_vattr_t va;
- int error;
-
- memset(&va, 0, sizeof (va));
- va.va_mask |= XFS_AT_MODE;
- va.va_mode = vap->va_mode | S_IFIFO;
- va.va_mask |= XFS_AT_TYPE;
- va.va_mask |= XFS_AT_RDEV;
- va.va_rdev = vap->va_rdev;
-
- xvp = NULL;
- XVOP_CREATE(VPTOXFSVP(dvp), cnp, &va, &xvp, credp, error);
-
- if (error == 0) {
- *ap->a_vpp = xvp->v_vnode;
- VOP_LOCK(xvp->v_vnode, LK_EXCLUSIVE);
- }
-
- return (error);
-}
-
-static int
-_xfs_mkdir(
- struct vop_mkdir_args /* {
- struct vnode *a_dvp;
- struct vnode **a_vpp;
- struct componentname *a_cnp;
- struct vattr *a_vap;
- } */ *ap)
-{
- struct vnode *dvp = ap->a_dvp;
- struct vattr *vap = ap->a_vap;
- struct thread *td = curthread;
- struct ucred *credp = td->td_ucred;
- struct componentname *cnp = ap->a_cnp;
- xfs_vnode_t *xvp;
- xfs_vattr_t va;
- int error;
-
- memset(&va, 0, sizeof (va));
- va.va_mask |= XFS_AT_MODE;
- va.va_mode = vap->va_mode | S_IFDIR;
- va.va_mask |= XFS_AT_TYPE;
-
- xvp = NULL;
- XVOP_MKDIR(VPTOXFSVP(dvp), cnp, &va, &xvp, credp, error);
-
- if (error == 0) {
- *ap->a_vpp = xvp->v_vnode;
- VOP_LOCK(xvp->v_vnode, LK_EXCLUSIVE);
- }
-
- return (error);
-}
-
-static int
-_xfs_rmdir(
- struct vop_rmdir_args /* {
- struct vnode *a_dvp;
- struct vnode *a_vp;
- struct componentname *a_cnp;
- } */ *ap)
-{
- struct vnode *vp = ap->a_vp;
- struct vnode *dvp = ap->a_dvp;
-/* struct componentname *cnp = ap->a_cnp; */
- int error;
-
- if (dvp == vp)
- return (EINVAL);
-
- error = EPERM;
-
- return (error);
-}
-
-static int
-_xfs_readdir(
- struct vop_readdir_args /* {
- struct vnode *a_vp;
- struct uio *a_uio;
- struct ucred *a_cred;
- int *a_eofflag;
- int *a_ncookies;
- u_long **a_cookies;
- } */ *ap)
-{
- struct vnode *vp = ap->a_vp;
- struct uio *uio = ap->a_uio;
- int error;
- off_t off;
- int eof = 0;
-
- if (vp->v_type != VDIR)
- return (EPERM);
- if (ap->a_ncookies) {
- return (EOPNOTSUPP);
- }
-
- error = 0;
- while (!eof){
- off = (int)uio->uio_offset;
-
- XVOP_READDIR(VPTOXFSVP(vp), uio, NULL, &eof, error);
- if ((uio->uio_offset == off) || error) {
- break;
- }
- }
-
- if (ap->a_eofflag)
- *ap->a_eofflag = (eof != 0);
-
- return (error);
-}
-
-
-static int
-_xfs_readlink(
- struct vop_readlink_args /* {
- struct vnode *a_vp;
- struct uio *a_uio;
- struct ucred *a_cred;
- } */ *ap)
-{
- struct vnode *vp = ap->a_vp;
- struct uio *uio = ap->a_uio;
- struct ucred *cred = ap->a_cred;
- int error;
-
- XVOP_READLINK(VPTOXFSVP(vp), uio, 0, cred, error);
- return (error);
-}
-
-static int
-_xfs_fsync(
- struct vop_fsync_args /* {
- struct vnode * a_vp;
- int a_waitfor;
- struct thread * a_td;
- } */ *ap)
-{
- xfs_vnode_t *vp = VPTOXFSVP(ap->a_vp);
- int flags = FSYNC_DATA;
- int error;
-
- if (ap->a_waitfor == MNT_WAIT)
- flags |= FSYNC_WAIT;
- XVOP_FSYNC(vp, flags, ap->a_td->td_ucred, (xfs_off_t)0, (xfs_off_t)-1, error);
-
- return (error);
-}
-
-static int
-_xfs_bmap(
- struct vop_bmap_args /* {
- struct vnode *a_vp;
- daddr_t a_bn;
- struct bufobj **a_bop;
- daddr_t *a_bnp;
- int *a_runp;
- int *a_runb;
- } */ *ap)
-{
- xfs_iomap_t iomap;
- xfs_off_t offset;
- ssize_t size;
- struct mount *mp;
- struct xfs_mount *xmp;
- struct xfs_vnode *xvp;
- int error, maxrun, retbm;
-
- mp = ap->a_vp->v_mount;
- xmp = XFS_VFSTOM(MNTTOVFS(mp));
- if (ap->a_bop != NULL)
- *ap->a_bop = &xmp->m_ddev_targp->specvp->v_bufobj;
- if (ap->a_bnp == NULL)
- return (0);
-
- xvp = VPTOXFSVP(ap->a_vp);
- retbm = 1;
-
- offset = XFS_FSB_TO_B(xmp, ap->a_bn);
- size = XFS_FSB_TO_B(xmp, 1);
- XVOP_BMAP(xvp, offset, size, BMAPI_READ, &iomap, &retbm, error);
- if (error)
- return (error);
- if (retbm == 0 || iomap.iomap_bn == IOMAP_DADDR_NULL) {
- *ap->a_bnp = (daddr_t)-1;
- if (ap->a_runb)
- *ap->a_runb = 0;
- if (ap->a_runp)
- *ap->a_runp = 0;
- } else {
- *ap->a_bnp = iomap.iomap_bn + btodb(iomap.iomap_delta);
- maxrun = mp->mnt_iosize_max / mp->mnt_stat.f_iosize - 1;
- if (ap->a_runb) {
- *ap->a_runb = XFS_B_TO_FSB(xmp, iomap.iomap_delta);
- if (*ap->a_runb > maxrun)
- *ap->a_runb = maxrun;
- }
- if (ap->a_runp) {
- *ap->a_runp =
- XFS_B_TO_FSB(xmp, iomap.iomap_bsize
- - iomap.iomap_delta - size);
- if (*ap->a_runp > maxrun)
- *ap->a_runp = maxrun;
- }
- }
- return (0);
-}
-
-static int
-_xfs_strategy(
- struct vop_strategy_args /* {
- struct vnode *a_vp;
- struct buf *a_bp;
- } */ *ap)
-{
- daddr_t blkno;
- struct buf *bp;
- struct bufobj *bo;
- struct vnode *vp;
- struct xfs_mount *xmp;
- int error;
-
- bp = ap->a_bp;
- vp = ap->a_vp;
-
- KASSERT(ap->a_vp == ap->a_bp->b_vp, ("%s(%p != %p)",
- __func__, ap->a_vp, ap->a_bp->b_vp));
- if (bp->b_blkno == bp->b_lblkno) {
- error = VOP_BMAP(vp, bp->b_lblkno, NULL, &blkno, NULL, NULL);
- bp->b_blkno = blkno;
- bp->b_iooffset = (blkno << BBSHIFT);
- if (error) {
- bp->b_error = error;
- bp->b_ioflags |= BIO_ERROR;
- bufdone(bp);
- return (0);
- }
- if ((long)bp->b_blkno == -1)
- vfs_bio_clrbuf(bp);
- }
- if ((long)bp->b_blkno == -1) {
- bufdone(bp);
- return (0);
- }
-
- xmp = XFS_VFSTOM(MNTTOVFS(vp->v_mount));
- bo = &xmp->m_ddev_targp->specvp->v_bufobj;
- bo->bo_ops->bop_strategy(bo, bp);
- return (0);
-}
-
-int
-_xfs_ioctl(
- struct vop_ioctl_args /* {
- struct vnode *a_vp;
- u_long a_command;
- caddr_t a_data;
- int fflag;
- struct ucred *cred;
- struct thread *a_td;
- } */ *ap)
-{
-/* struct vnode *vp = ap->a_vp; */
-/* struct thread *p = ap->a_td; */
-/* struct file *fp; */
- int error;
-
- xfs_vnode_t *xvp = VPTOXFSVP(ap->a_vp);
-
- printf("_xfs_ioctl cmd 0x%lx data %p\n",ap->a_command,ap->a_data);
-
-// XVOP_IOCTL(xvp,(void *)NULL,(void *)NULL,ap->a_fflag,ap->a_command,ap->a_data,error);
- error = xfs_ioctl(xvp->v_bh.bh_first,NULL,NULL,ap->a_fflag,ap->a_command,ap->a_data);
-
- return error;
-}
-
-int
-_xfs_advlock(
- struct vop_advlock_args /* {
- struct vnode *a_vp;
- caddr_t a_id;
- int a_op;
- struct flock *a_fl;
- int a_flags;
- } */ *ap)
-{
-/* struct vnode *vp = ap->a_vp;*/
- struct flock *fl = ap->a_fl;
-/* caddr_t id = (caddr_t)1 */ /* ap->a_id */;
-/* int flags = ap->a_flags; */
- off_t start, end, size;
- int error/* , lkop */;
-
- /*KAN: temp */
- return (EOPNOTSUPP);
-
- size = 0;
- error = 0;
- switch (fl->l_whence) {
- case SEEK_SET:
- case SEEK_CUR:
- start = fl->l_start;
- break;
- case SEEK_END:
- start = fl->l_start + size;
- default:
- return (EINVAL);
- }
- if (start < 0)
- return (EINVAL);
- if (fl->l_len == 0)
- end = -1;
- else {
- end = start + fl->l_len - 1;
- if (end < start)
- return (EINVAL);
- }
-#ifdef notyet
- switch (ap->a_op) {
- case F_SETLK:
- error = lf_advlock(ap, &vp->v_lockf, size);
- break;
- case F_UNLCK:
- lf_advlock(ap, &vp->v_lockf, size);
- break;
- case F_GETLK:
- error = lf_advlock(ap, &vp->v_lockf, size);
- break;
- default:
- return (EINVAL);
- }
-#endif
- return (error);
-}
-
-static int
-_xfs_cachedlookup(
- struct vop_cachedlookup_args /* {
- struct vnode * a_dvp;
- struct vnode ** a_vpp;
- struct componentname * a_cnp;
- } */ *ap)
-{
- struct vnode *dvp, *tvp;
- struct xfs_vnode *cvp;
- int islastcn;
- int error;
- struct vnode **vpp = ap->a_vpp;
- struct componentname *cnp = ap->a_cnp;
- struct ucred *cred = cnp->cn_cred;
- int flags = cnp->cn_flags;
- int nameiop = cnp->cn_nameiop;
- struct thread *td = cnp->cn_thread;
-
- char *pname = cnp->cn_nameptr;
- int namelen = cnp->cn_namelen;
-
- *vpp = NULL;
- dvp = ap->a_dvp;
- islastcn = flags & ISLASTCN;
-
- XVOP_LOOKUP(VPTOXFSVP(dvp), cnp, &cvp, 0, NULL, cred, error);
-
- if (error == ENOENT) {
- if ((nameiop == CREATE || nameiop == RENAME ||
- nameiop == DELETE) && islastcn)
- {
- error = VOP_ACCESS(dvp, VWRITE, cred, td);
- if (error)
- return (error);
- cnp->cn_flags |= SAVENAME;
- return (EJUSTRETURN);
- }
- if ((cnp->cn_flags & MAKEENTRY) && nameiop != CREATE)
- cache_enter(dvp, *vpp, cnp);
- return (error);
- }
- if (error)
- return (error);
-
- tvp = cvp->v_vnode;
-
- if (nameiop == DELETE && islastcn) {
- if ((error = vn_lock(tvp, LK_EXCLUSIVE))) {
- vrele(tvp);
- goto err_out;
- }
- *vpp = tvp;
-
- /* Directory should be writable for deletes. */
- error = VOP_ACCESS(dvp, VWRITE, cred, td);
- if (error)
- goto err_out;
-
- /* XXXKAN: Permission checks for sticky dirs? */
- return (0);
- }
-
- if (nameiop == RENAME && islastcn) {
- if ((error = vn_lock(tvp, LK_EXCLUSIVE))) {
- vrele(tvp);
- goto err_out;
- }
- *vpp = tvp;
-
- if ((error = VOP_ACCESS(dvp, VWRITE, cred, td)))
- goto err_out;
- return (0);
- }
-
- if (flags & ISDOTDOT) {
- VOP_UNLOCK(dvp, 0);
- error = vn_lock(tvp, cnp->cn_lkflags);
- if (error) {
- vn_lock(dvp, LK_EXCLUSIVE | LK_RETRY);
- vrele(tvp);
- goto err_out;
- }
- *vpp = tvp;
- } else if (namelen == 1 && pname[0] == '.') {
- *vpp = tvp;
- KASSERT(tvp == dvp, ("not same directory"));
- } else {
- if ((error = vn_lock(tvp, cnp->cn_lkflags))) {
- vrele(tvp);
- goto err_out;
- }
- *vpp = tvp;
- }
-
- if (cnp->cn_flags & MAKEENTRY)
- cache_enter(dvp, *vpp, cnp);
- return (0);
-
-err_out:
- if (*vpp != 0)
- vput(*vpp);
- return (error);
-}
-
-static int
-_xfs_reclaim(
- struct vop_reclaim_args /* {
- struct vnode *a_vp;
- struct thread *a_td;
- } */ *ap)
-{
-
- struct vnode *vp = ap->a_vp;
- struct xfs_vnode *xfs_vp = VPTOXFSVP(vp);
- int error;
-
- XVOP_RECLAIM(xfs_vp, error);
- kmem_free(xfs_vp, sizeof(*xfs_vp));
- vp->v_data = NULL;
- return (error);
-}
-
-static int
-_xfs_kqfilter(
- struct vop_kqfilter_args /* {
- struct vnodeop_desc *a_desc;
- struct vnode *a_vp;
- struct knote *a_kn;
- } */ *ap)
-{
- return (0);
-}
-
-struct xfs_inode *
-xfs_vtoi(struct xfs_vnode *xvp)
-{
- return(XFS_BHVTOI(xvp->v_fbhv));
-}
-
-/*
- * Read wrapper for fifos.
- */
-static int
-_xfsfifo_read(
- struct vop_read_args /* {
- struct vnode *a_vp;
- struct uio *a_uio;
- int a_ioflag;
- struct ucred *a_cred;
- } */ *ap)
-{
- int error, resid;
- struct xfs_inode *ip;
- struct uio *uio;
-
- uio = ap->a_uio;
- resid = uio->uio_resid;
- error = fifo_specops.vop_read(ap);
- ip = xfs_vtoi(VPTOXFSVP(ap->a_vp));
- if ((ap->a_vp->v_mount->mnt_flag & MNT_NOATIME) == 0 && ip != NULL &&
- (uio->uio_resid != resid || (error == 0 && resid != 0)))
- xfs_ichgtime(ip, XFS_ICHGTIME_ACC);
- return (error);
-}
-
-/*
- * Write wrapper for fifos.
- */
-static int
-_xfsfifo_write(
- struct vop_write_args /* {
- struct vnode *a_vp;
- struct uio *a_uio;
- int a_ioflag;
- struct ucred *a_cred;
- } */ *ap)
-{
- int error, resid;
- struct uio *uio;
- struct xfs_inode *ip;
-
- uio = ap->a_uio;
- resid = uio->uio_resid;
- error = fifo_specops.vop_write(ap);
- ip = xfs_vtoi(VPTOXFSVP(ap->a_vp));
- if (ip != NULL && (uio->uio_resid != resid ||
- (error == 0 && resid != 0)))
- xfs_ichgtime(ip, XFS_ICHGTIME_MOD | XFS_ICHGTIME_CHG);
- return (error);
-}
-
-/*
- * Close wrapper for fifos.
- *
- * Update the times on the inode then do device close.
- */
-static int
-_xfsfifo_close(
- struct vop_close_args /* {
- struct vnode *a_vp;
- int a_fflag;
- struct ucred *a_cred;
- struct thread *a_td;
- } */ *ap)
-{
-
- return (fifo_specops.vop_close(ap));
-}
-
-/*
- * Kqfilter wrapper for fifos.
- *
- * Fall through to ufs kqfilter routines if needed
- */
-static int
-_xfsfifo_kqfilter(
- struct vop_kqfilter_args /* {
- struct vnodeop_desc *a_desc;
- struct vnode *a_vp;
- struct knote *a_kn;
- } */ *ap)
-{
- int error;
-
- error = fifo_specops.vop_kqfilter(ap);
- if (error)
- error = _xfs_kqfilter(ap);
- return (error);
-}
-
-static int
-_xfs_getextattr(
- struct vop_getextattr_args /* {
- struct vnode *a_vp;
- int a_attrnamespace;
- const char *a_name;
- struct uio *a_uio;
- size_t *a_size;
- struct ucred *a_cred;
- struct thread *a_td;
- } */ *ap)
-{
- int error;
- char *value;
- int size;
-
- error = extattr_check_cred(ap->a_vp, ap->a_attrnamespace,
- ap->a_cred, ap->a_td, VREAD);
- if (error)
- return (error);
-
- size = ATTR_MAX_VALUELEN;
- value = (char *)kmem_zalloc(size, KM_SLEEP);
- if (value == NULL)
- return (ENOMEM);
-
- XVOP_ATTR_GET(VPTOXFSVP(ap->a_vp), ap->a_name, value, &size, 1,
- ap->a_cred, error);
-
- if (ap->a_uio != NULL) {
- if (ap->a_uio->uio_iov->iov_len < size)
- error = ERANGE;
- else
- uiomove(value, size, ap->a_uio);
- }
-
- if (ap->a_size != NULL)
- *ap->a_size = size;
-
- kmem_free(value, ATTR_MAX_VALUELEN);
- return (error);
-}
-
-static int
-_xfs_listextattr(
- struct vop_listextattr_args /* {
- struct vnode *a_vp;
- int a_attrnamespace;
- struct uio *a_uio;
- size_t *a_size;
- struct ucred *a_cred;
- struct thread *a_td;
- } */ *ap)
-{
- int error;
- char *buf = NULL;
- int buf_len = 0;
- attrlist_cursor_kern_t cursor = { 0 };
- int i;
- char name_len;
- int attrnames_len = 0;
- int xfs_flags = ATTR_KERNAMELS;
-
- error = extattr_check_cred(ap->a_vp, ap->a_attrnamespace,
- ap->a_cred, ap->a_td, VREAD);
- if (error)
- return (error);
-
- if (ap->a_attrnamespace & EXTATTR_NAMESPACE_USER)
- xfs_flags |= ATTR_KERNORMALS;
-
- if (ap->a_attrnamespace & EXTATTR_NAMESPACE_SYSTEM)
- xfs_flags |= ATTR_KERNROOTLS;
-
- if (ap->a_uio == NULL || ap->a_uio->uio_iov[0].iov_base == NULL) {
- xfs_flags |= ATTR_KERNOVAL;
- buf_len = 0;
- } else {
- buf = ap->a_uio->uio_iov[0].iov_base;
- buf_len = ap->a_uio->uio_iov[0].iov_len;
- }
-
- XVOP_ATTR_LIST(VPTOXFSVP(ap->a_vp), buf, buf_len, xfs_flags,
- &cursor, ap->a_cred, error);
- if (error < 0) {
- attrnames_len = -error;
- error = 0;
- }
- if (buf == NULL)
- goto done;
-
- /*
- * extattr_list expects a list of names. Each list
- * entry consists of one byte for the name length, followed
- * by the name (not null terminated)
- */
- name_len=0;
- for(i=attrnames_len-1; i > 0 ; --i) {
- buf[i] = buf[i-1];
- if (buf[i])
- ++name_len;
- else {
- buf[i] = name_len;
- name_len = 0;
- }
- }
- buf[0] = name_len;
-
- if (ap->a_uio != NULL)
- ap->a_uio->uio_resid -= attrnames_len;
-
-done:
- if (ap->a_size != NULL)
- *ap->a_size = attrnames_len;
-
- return (error);
-}
-
-static int
-_xfs_setextattr(struct vop_setextattr_args *ap)
-/*
-vop_setextattr {
- IN struct vnode *a_vp;
- IN int a_attrnamespace;
- IN const char *a_name;
- INOUT struct uio *a_uio;
- IN struct ucred *a_cred;
- IN struct thread *a_td;
-};
-*/
-{
- char *val;
- size_t vallen;
- int error, xfs_flags;
-
- if (ap->a_vp->v_type == VCHR)
- return (EOPNOTSUPP);
-
- if (ap->a_uio == NULL)
- return (EINVAL);
- vallen = ap->a_uio->uio_resid;
- if (vallen > ATTR_MAX_VALUELEN)
- return (EOVERFLOW);
-
- if (ap->a_name[0] == '\0')
- return (EINVAL);
-
- error = extattr_check_cred(ap->a_vp, ap->a_attrnamespace,
- ap->a_cred, ap->a_td, VWRITE);
- if (error)
- return (error);
-
- xfs_flags = 0;
- if (ap->a_attrnamespace & EXTATTR_NAMESPACE_USER)
- xfs_flags |= ATTR_KERNORMALS;
- if (ap->a_attrnamespace & EXTATTR_NAMESPACE_SYSTEM)
- xfs_flags |= ATTR_KERNROOTLS;
-
- val = (char *)kmem_zalloc(vallen, KM_SLEEP);
- if (val == NULL)
- return (ENOMEM);
- error = uiomove(val, (int)vallen, ap->a_uio);
- if (error)
- goto err_out;
-
- XVOP_ATTR_SET(VPTOXFSVP(ap->a_vp), ap->a_name, val, vallen, xfs_flags,
- ap->a_cred, error);
-err_out:
- kmem_free(val, vallen);
- return(error);
-}
-
-static int
-_xfs_deleteextattr(struct vop_deleteextattr_args *ap)
-/*
-vop_deleteextattr {
- IN struct vnode *a_vp;
- IN int a_attrnamespace;
- IN const char *a_name;
- IN struct ucred *a_cred;
- IN struct thread *a_td;
-};
-*/
-{
- int error, xfs_flags;
-
- if (ap->a_vp->v_type == VCHR)
- return (EOPNOTSUPP);
-
- if (ap->a_name[0] == '\0')
- return (EINVAL);
-
- error = extattr_check_cred(ap->a_vp, ap->a_attrnamespace,
- ap->a_cred, ap->a_td, VWRITE);
- if (error)
- return (error);
-
- xfs_flags = 0;
- if (ap->a_attrnamespace & EXTATTR_NAMESPACE_USER)
- xfs_flags |= ATTR_KERNORMALS;
- if (ap->a_attrnamespace & EXTATTR_NAMESPACE_SYSTEM)
- xfs_flags |= ATTR_KERNROOTLS;
-
- XVOP_ATTR_REMOVE(VPTOXFSVP(ap->a_vp), ap->a_name, xfs_flags,
- ap->a_cred, error);
- return (error);
-}
-
-static int
-_xfs_vptofh(struct vop_vptofh_args *ap)
-/*
-vop_vptofh {
- IN struct vnode *a_vp;
- IN struct fid *a_fhp;
-};
-*/
-{
- printf("xfs_vptofh");
- return ENOSYS;
-}
diff --git a/sys/gnu/fs/xfs/xfs.h b/sys/gnu/fs/xfs/xfs.h
deleted file mode 100644
index 0db97bb..0000000
--- a/sys/gnu/fs/xfs/xfs.h
+++ /dev/null
@@ -1,23 +0,0 @@
-
-/*
- * Copyright (c) 2000-2003,2005 Silicon Graphics, Inc.
- * All Rights Reserved.
- *
- * 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.
- *
- * This program is distributed in the hope that it would 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 the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- */
-#ifndef __XFS_H__
-#define __XFS_H__
-
-#include <xfs_freebsd.h>
-#endif /* __XFS_H__ */
diff --git a/sys/gnu/fs/xfs/xfs_acl.c b/sys/gnu/fs/xfs/xfs_acl.c
deleted file mode 100644
index 9e70eb1..0000000
--- a/sys/gnu/fs/xfs/xfs_acl.c
+++ /dev/null
@@ -1,928 +0,0 @@
-/*
- * Copyright (c) 2001-2002,2005 Silicon Graphics, Inc.
- * All Rights Reserved.
- *
- * 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.
- *
- * This program is distributed in the hope that it would 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 the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- */
-#include "xfs.h"
-#include "xfs_fs.h"
-#include "xfs_types.h"
-#include "xfs_bit.h"
-#include "xfs_inum.h"
-#include "xfs_ag.h"
-#include "xfs_dir.h"
-#include "xfs_dir2.h"
-#include "xfs_bmap_btree.h"
-#include "xfs_alloc_btree.h"
-#include "xfs_ialloc_btree.h"
-#include "xfs_dir_sf.h"
-#include "xfs_dir2_sf.h"
-#include "xfs_attr_sf.h"
-#include "xfs_dinode.h"
-#include "xfs_inode.h"
-#include "xfs_btree.h"
-#include "xfs_acl.h"
-#include "xfs_mac.h"
-#include "xfs_attr.h"
-
-#include <linux/capability.h>
-#include <linux/posix_acl_xattr.h>
-
-STATIC int xfs_acl_setmode(xfs_vnode_t *, xfs_acl_t *, int *);
-STATIC void xfs_acl_filter_mode(mode_t, xfs_acl_t *);
-STATIC void xfs_acl_get_endian(xfs_acl_t *);
-STATIC int xfs_acl_access(uid_t, gid_t, xfs_acl_t *, mode_t, cred_t *);
-STATIC int xfs_acl_invalid(xfs_acl_t *);
-STATIC void xfs_acl_sync_mode(mode_t, xfs_acl_t *);
-STATIC void xfs_acl_get_attr(xfs_vnode_t *, xfs_acl_t *, int, int, int *);
-STATIC void xfs_acl_set_attr(xfs_vnode_t *, xfs_acl_t *, int, int *);
-STATIC int xfs_acl_allow_set(xfs_vnode_t *, int);
-
-kmem_zone_t *xfs_acl_zone;
-
-
-/*
- * Test for existence of access ACL attribute as efficiently as possible.
- */
-int
-xfs_acl_vhasacl_access(
- xfs_vnode_t *vp)
-{
- int error;
-
- xfs_acl_get_attr(vp, NULL, _ACL_TYPE_ACCESS, ATTR_KERNOVAL, &error);
- return (error == 0);
-}
-
-/*
- * Test for existence of default ACL attribute as efficiently as possible.
- */
-int
-xfs_acl_vhasacl_default(
- xfs_vnode_t *vp)
-{
- int error;
-
- if (!VN_ISDIR(vp))
- return 0;
- xfs_acl_get_attr(vp, NULL, _ACL_TYPE_DEFAULT, ATTR_KERNOVAL, &error);
- return (error == 0);
-}
-
-/*
- * Convert from extended attribute representation to in-memory for XFS.
- */
-STATIC int
-posix_acl_xattr_to_xfs(
- posix_acl_xattr_header *src,
- size_t size,
- xfs_acl_t *dest)
-{
- posix_acl_xattr_entry *src_entry;
- xfs_acl_entry_t *dest_entry;
- int n;
-
- if (!src || !dest)
- return EINVAL;
-
- if (size < sizeof(posix_acl_xattr_header))
- return EINVAL;
-
- if (src->a_version != cpu_to_le32(POSIX_ACL_XATTR_VERSION))
- return EOPNOTSUPP;
-
- memset(dest, 0, sizeof(xfs_acl_t));
- dest->acl_cnt = posix_acl_xattr_count(size);
- if (dest->acl_cnt < 0 || dest->acl_cnt > XFS_ACL_MAX_ENTRIES)
- return EINVAL;
-
- /*
- * acl_set_file(3) may request that we set default ACLs with
- * zero length -- defend (gracefully) against that here.
- */
- if (!dest->acl_cnt)
- return 0;
-
- src_entry = (posix_acl_xattr_entry *)((char *)src + sizeof(*src));
- dest_entry = &dest->acl_entry[0];
-
- for (n = 0; n < dest->acl_cnt; n++, src_entry++, dest_entry++) {
- dest_entry->ae_perm = le16_to_cpu(src_entry->e_perm);
- if (_ACL_PERM_INVALID(dest_entry->ae_perm))
- return EINVAL;
- dest_entry->ae_tag = le16_to_cpu(src_entry->e_tag);
- switch(dest_entry->ae_tag) {
- case ACL_USER:
- case ACL_GROUP:
- dest_entry->ae_id = le32_to_cpu(src_entry->e_id);
- break;
- case ACL_USER_OBJ:
- case ACL_GROUP_OBJ:
- case ACL_MASK:
- case ACL_OTHER:
- dest_entry->ae_id = ACL_UNDEFINED_ID;
- break;
- default:
- return EINVAL;
- }
- }
- if (xfs_acl_invalid(dest))
- return EINVAL;
-
- return 0;
-}
-
-/*
- * Comparison function called from xfs_sort().
- * Primary key is ae_tag, secondary key is ae_id.
- */
-STATIC int
-xfs_acl_entry_compare(
- const void *va,
- const void *vb)
-{
- xfs_acl_entry_t *a = (xfs_acl_entry_t *)va,
- *b = (xfs_acl_entry_t *)vb;
-
- if (a->ae_tag == b->ae_tag)
- return (a->ae_id - b->ae_id);
- return (a->ae_tag - b->ae_tag);
-}
-
-/*
- * Convert from in-memory XFS to extended attribute representation.
- */
-STATIC int
-posix_acl_xfs_to_xattr(
- xfs_acl_t *src,
- posix_acl_xattr_header *dest,
- size_t size)
-{
- int n;
- size_t new_size = posix_acl_xattr_size(src->acl_cnt);
- posix_acl_xattr_entry *dest_entry;
- xfs_acl_entry_t *src_entry;
-
- if (size < new_size)
- return -ERANGE;
-
- /* Need to sort src XFS ACL by <ae_tag,ae_id> */
- xfs_sort(src->acl_entry, src->acl_cnt, sizeof(src->acl_entry[0]),
- xfs_acl_entry_compare);
-
- dest->a_version = cpu_to_le32(POSIX_ACL_XATTR_VERSION);
- dest_entry = &dest->a_entries[0];
- src_entry = &src->acl_entry[0];
- for (n = 0; n < src->acl_cnt; n++, dest_entry++, src_entry++) {
- dest_entry->e_perm = cpu_to_le16(src_entry->ae_perm);
- if (_ACL_PERM_INVALID(src_entry->ae_perm))
- return -EINVAL;
- dest_entry->e_tag = cpu_to_le16(src_entry->ae_tag);
- switch (src_entry->ae_tag) {
- case ACL_USER:
- case ACL_GROUP:
- dest_entry->e_id = cpu_to_le32(src_entry->ae_id);
- break;
- case ACL_USER_OBJ:
- case ACL_GROUP_OBJ:
- case ACL_MASK:
- case ACL_OTHER:
- dest_entry->e_id = cpu_to_le32(ACL_UNDEFINED_ID);
- break;
- default:
- return -EINVAL;
- }
- }
- return new_size;
-}
-
-int
-xfs_acl_vget(
- xfs_vnode_t *vp,
- void *acl,
- size_t size,
- int kind)
-{
- int error;
- xfs_acl_t *xfs_acl = NULL;
- posix_acl_xattr_header *ext_acl = acl;
- int flags = 0;
-
- VN_HOLD(vp);
- if(size) {
- if (!(_ACL_ALLOC(xfs_acl))) {
- error = ENOMEM;
- goto out;
- }
- memset(xfs_acl, 0, sizeof(xfs_acl_t));
- } else
- flags = ATTR_KERNOVAL;
-
- xfs_acl_get_attr(vp, xfs_acl, kind, flags, &error);
- if (error)
- goto out;
-
- if (!size) {
- error = -posix_acl_xattr_size(XFS_ACL_MAX_ENTRIES);
- } else {
- if (xfs_acl_invalid(xfs_acl)) {
- error = EINVAL;
- goto out;
- }
- if (kind == _ACL_TYPE_ACCESS) {
- xfs_vattr_t va;
-
- va.va_mask = XFS_AT_MODE;
- XVOP_GETATTR(vp, &va, 0, sys_cred, error);
- if (error)
- goto out;
- xfs_acl_sync_mode(va.va_mode, xfs_acl);
- }
- error = -posix_acl_xfs_to_xattr(xfs_acl, ext_acl, size);
- }
-out:
- VN_RELE(vp);
- if(xfs_acl)
- _ACL_FREE(xfs_acl);
- return -error;
-}
-
-int
-xfs_acl_vremove(
- xfs_vnode_t *vp,
- int kind)
-{
- int error;
-
- VN_HOLD(vp);
- error = xfs_acl_allow_set(vp, kind);
- if (!error) {
- XVOP_ATTR_REMOVE(vp, kind == _ACL_TYPE_DEFAULT?
- SGI_ACL_DEFAULT: SGI_ACL_FILE,
- ATTR_ROOT, sys_cred, error);
- if (error == ENOATTR)
- error = 0; /* 'scool */
- }
- VN_RELE(vp);
- return -error;
-}
-
-int
-xfs_acl_vset(
- xfs_vnode_t *vp,
- void *acl,
- size_t size,
- int kind)
-{
- posix_acl_xattr_header *ext_acl = acl;
- xfs_acl_t *xfs_acl;
- int error;
- int basicperms = 0; /* more than std unix perms? */
-
- if (!acl)
- return -EINVAL;
-
- if (!(_ACL_ALLOC(xfs_acl)))
- return -ENOMEM;
-
- error = posix_acl_xattr_to_xfs(ext_acl, size, xfs_acl);
- if (error) {
- _ACL_FREE(xfs_acl);
- return -error;
- }
- if (!xfs_acl->acl_cnt) {
- _ACL_FREE(xfs_acl);
- return 0;
- }
-
- VN_HOLD(vp);
- error = xfs_acl_allow_set(vp, kind);
- if (error)
- goto out;
-
- /* Incoming ACL exists, set file mode based on its value */
- if (kind == _ACL_TYPE_ACCESS)
- xfs_acl_setmode(vp, xfs_acl, &basicperms);
-
- /*
- * If we have more than std unix permissions, set up the actual attr.
- * Otherwise, delete any existing attr. This prevents us from
- * having actual attrs for permissions that can be stored in the
- * standard permission bits.
- */
- if (!basicperms) {
- xfs_acl_set_attr(vp, xfs_acl, kind, &error);
- } else {
- xfs_acl_vremove(vp, _ACL_TYPE_ACCESS);
- }
-
-out:
- VN_RELE(vp);
- _ACL_FREE(xfs_acl);
- return -error;
-}
-
-int
-xfs_acl_iaccess(
- xfs_inode_t *ip,
- mode_t mode,
- cred_t *cr)
-{
- xfs_acl_t *acl;
- int rval;
-
- if (!(_ACL_ALLOC(acl)))
- return -1;
-
- /* If the file has no ACL return -1. */
- rval = sizeof(xfs_acl_t);
- if (xfs_attr_fetch(ip, SGI_ACL_FILE, SGI_ACL_FILE_SIZE,
- (char *)acl, &rval, ATTR_ROOT | ATTR_KERNACCESS, cr)) {
- _ACL_FREE(acl);
- return -1;
- }
- xfs_acl_get_endian(acl);
-
- /* If the file has an empty ACL return -1. */
- if (acl->acl_cnt == XFS_ACL_NOT_PRESENT) {
- _ACL_FREE(acl);
- return -1;
- }
-
- /* Synchronize ACL with mode bits */
- xfs_acl_sync_mode(ip->i_d.di_mode, acl);
-
- rval = xfs_acl_access(ip->i_d.di_uid, ip->i_d.di_gid, acl, mode, cr);
- _ACL_FREE(acl);
- return rval;
-}
-
-STATIC int
-xfs_acl_allow_set(
- xfs_vnode_t *vp,
- int kind)
-{
- xfs_vattr_t va;
- int error;
-
- if (vp->v_inode.i_flags & (S_IMMUTABLE|S_APPEND))
- return EPERM;
- if (kind == _ACL_TYPE_DEFAULT && !VN_ISDIR(vp))
- return ENOTDIR;
- if (vp->v_vfsp->vfs_flag & VFS_RDONLY)
- return EROFS;
- va.va_mask = XFS_AT_UID;
- XVOP_GETATTR(vp, &va, 0, NULL, error);
- if (error)
- return error;
- if (va.va_uid != current->fsuid && !capable(CAP_FOWNER))
- return EPERM;
- return error;
-}
-
-/*
- * The access control process to determine the access permission:
- * if uid == file owner id, use the file owner bits.
- * if gid == file owner group id, use the file group bits.
- * scan ACL for a matching user or group, and use matched entry
- * permission. Use total permissions of all matching group entries,
- * until all acl entries are exhausted. The final permission produced
- * by matching acl entry or entries needs to be & with group permission.
- * if not owner, owning group, or matching entry in ACL, use file
- * other bits.
- */
-STATIC int
-xfs_acl_capability_check(
- mode_t mode,
- cred_t *cr)
-{
- if ((mode & ACL_READ) && !capable_cred(cr, CAP_DAC_READ_SEARCH))
- return EACCES;
- if ((mode & ACL_WRITE) && !capable_cred(cr, CAP_DAC_OVERRIDE))
- return EACCES;
- if ((mode & ACL_EXECUTE) && !capable_cred(cr, CAP_DAC_OVERRIDE))
- return EACCES;
-
- return 0;
-}
-
-/*
- * Note: cr is only used here for the capability check if the ACL test fails.
- * It is not used to find out the credentials uid or groups etc, as was
- * done in IRIX. It is assumed that the uid and groups for the current
- * thread are taken from "current" instead of the cr parameter.
- */
-STATIC int
-xfs_acl_access(
- uid_t fuid,
- gid_t fgid,
- xfs_acl_t *fap,
- mode_t md,
- cred_t *cr)
-{
- xfs_acl_entry_t matched;
- int i, allows;
- int maskallows = -1; /* true, but not 1, either */
- int seen_userobj = 0;
-
- matched.ae_tag = 0; /* Invalid type */
- matched.ae_perm = 0;
- md >>= 6; /* Normalize the bits for comparison */
-
- for (i = 0; i < fap->acl_cnt; i++) {
- /*
- * Break out if we've got a user_obj entry or
- * a user entry and the mask (and have processed USER_OBJ)
- */
- if (matched.ae_tag == ACL_USER_OBJ)
- break;
- if (matched.ae_tag == ACL_USER) {
- if (maskallows != -1 && seen_userobj)
- break;
- if (fap->acl_entry[i].ae_tag != ACL_MASK &&
- fap->acl_entry[i].ae_tag != ACL_USER_OBJ)
- continue;
- }
- /* True if this entry allows the requested access */
- allows = ((fap->acl_entry[i].ae_perm & md) == md);
-
- switch (fap->acl_entry[i].ae_tag) {
- case ACL_USER_OBJ:
- seen_userobj = 1;
- if (fuid != current->fsuid)
- continue;
- matched.ae_tag = ACL_USER_OBJ;
- matched.ae_perm = allows;
- break;
- case ACL_USER:
- if (fap->acl_entry[i].ae_id != current->fsuid)
- continue;
- matched.ae_tag = ACL_USER;
- matched.ae_perm = allows;
- break;
- case ACL_GROUP_OBJ:
- if ((matched.ae_tag == ACL_GROUP_OBJ ||
- matched.ae_tag == ACL_GROUP) && !allows)
- continue;
- if (!in_group_p(fgid))
- continue;
- matched.ae_tag = ACL_GROUP_OBJ;
- matched.ae_perm = allows;
- break;
- case ACL_GROUP:
- if ((matched.ae_tag == ACL_GROUP_OBJ ||
- matched.ae_tag == ACL_GROUP) && !allows)
- continue;
- if (!in_group_p(fap->acl_entry[i].ae_id))
- continue;
- matched.ae_tag = ACL_GROUP;
- matched.ae_perm = allows;
- break;
- case ACL_MASK:
- maskallows = allows;
- break;
- case ACL_OTHER:
- if (matched.ae_tag != 0)
- continue;
- matched.ae_tag = ACL_OTHER;
- matched.ae_perm = allows;
- break;
- }
- }
- /*
- * First possibility is that no matched entry allows access.
- * The capability to override DAC may exist, so check for it.
- */
- switch (matched.ae_tag) {
- case ACL_OTHER:
- case ACL_USER_OBJ:
- if (matched.ae_perm)
- return 0;
- break;
- case ACL_USER:
- case ACL_GROUP_OBJ:
- case ACL_GROUP:
- if (maskallows && matched.ae_perm)
- return 0;
- break;
- case 0:
- break;
- }
-
- return xfs_acl_capability_check(md, cr);
-}
-
-/*
- * ACL validity checker.
- * This acl validation routine checks each ACL entry read in makes sense.
- */
-STATIC int
-xfs_acl_invalid(
- xfs_acl_t *aclp)
-{
- xfs_acl_entry_t *entry, *e;
- int user = 0, group = 0, other = 0, mask = 0;
- int mask_required = 0;
- int i, j;
-
- if (!aclp)
- goto acl_invalid;
-
- if (aclp->acl_cnt > XFS_ACL_MAX_ENTRIES)
- goto acl_invalid;
-
- for (i = 0; i < aclp->acl_cnt; i++) {
- entry = &aclp->acl_entry[i];
- switch (entry->ae_tag) {
- case ACL_USER_OBJ:
- if (user++)
- goto acl_invalid;
- break;
- case ACL_GROUP_OBJ:
- if (group++)
- goto acl_invalid;
- break;
- case ACL_OTHER:
- if (other++)
- goto acl_invalid;
- break;
- case ACL_USER:
- case ACL_GROUP:
- for (j = i + 1; j < aclp->acl_cnt; j++) {
- e = &aclp->acl_entry[j];
- if (e->ae_id == entry->ae_id &&
- e->ae_tag == entry->ae_tag)
- goto acl_invalid;
- }
- mask_required++;
- break;
- case ACL_MASK:
- if (mask++)
- goto acl_invalid;
- break;
- default:
- goto acl_invalid;
- }
- }
- if (!user || !group || !other || (mask_required && !mask))
- goto acl_invalid;
- else
- return 0;
-acl_invalid:
- return EINVAL;
-}
-
-/*
- * Do ACL endian conversion.
- */
-STATIC void
-xfs_acl_get_endian(
- xfs_acl_t *aclp)
-{
- xfs_acl_entry_t *ace, *end;
-
- INT_SET(aclp->acl_cnt, ARCH_CONVERT, aclp->acl_cnt);
- end = &aclp->acl_entry[0]+aclp->acl_cnt;
- for (ace = &aclp->acl_entry[0]; ace < end; ace++) {
- INT_SET(ace->ae_tag, ARCH_CONVERT, ace->ae_tag);
- INT_SET(ace->ae_id, ARCH_CONVERT, ace->ae_id);
- INT_SET(ace->ae_perm, ARCH_CONVERT, ace->ae_perm);
- }
-}
-
-/*
- * Get the ACL from the EA and do endian conversion.
- */
-STATIC void
-xfs_acl_get_attr(
- xfs_vnode_t *vp,
- xfs_acl_t *aclp,
- int kind,
- int flags,
- int *error)
-{
- int len = sizeof(xfs_acl_t);
-
- ASSERT((flags & ATTR_KERNOVAL) ? (aclp == NULL) : 1);
- flags |= ATTR_ROOT;
- XVOP_ATTR_GET(vp,
- kind == _ACL_TYPE_ACCESS ? SGI_ACL_FILE : SGI_ACL_DEFAULT,
- (char *)aclp, &len, flags, sys_cred, *error);
- if (*error || (flags & ATTR_KERNOVAL))
- return;
- xfs_acl_get_endian(aclp);
-}
-
-/*
- * Set the EA with the ACL and do endian conversion.
- */
-STATIC void
-xfs_acl_set_attr(
- xfs_vnode_t *vp,
- xfs_acl_t *aclp,
- int kind,
- int *error)
-{
- xfs_acl_entry_t *ace, *newace, *end;
- xfs_acl_t *newacl;
- int len;
-
- if (!(_ACL_ALLOC(newacl))) {
- *error = ENOMEM;
- return;
- }
-
- len = sizeof(xfs_acl_t) -
- (sizeof(xfs_acl_entry_t) * (XFS_ACL_MAX_ENTRIES - aclp->acl_cnt));
- end = &aclp->acl_entry[0]+aclp->acl_cnt;
- for (ace = &aclp->acl_entry[0], newace = &newacl->acl_entry[0];
- ace < end;
- ace++, newace++) {
- INT_SET(newace->ae_tag, ARCH_CONVERT, ace->ae_tag);
- INT_SET(newace->ae_id, ARCH_CONVERT, ace->ae_id);
- INT_SET(newace->ae_perm, ARCH_CONVERT, ace->ae_perm);
- }
- INT_SET(newacl->acl_cnt, ARCH_CONVERT, aclp->acl_cnt);
- XVOP_ATTR_SET(vp,
- kind == _ACL_TYPE_ACCESS ? SGI_ACL_FILE: SGI_ACL_DEFAULT,
- (char *)newacl, len, ATTR_ROOT, sys_cred, *error);
- _ACL_FREE(newacl);
-}
-
-int
-xfs_acl_vtoacl(
- xfs_vnode_t *vp,
- xfs_acl_t *access_acl,
- xfs_acl_t *default_acl)
-{
- xfs_vattr_t va;
- int error = 0;
-
- if (access_acl) {
- /*
- * Get the Access ACL and the mode. If either cannot
- * be obtained for some reason, invalidate the access ACL.
- */
- xfs_acl_get_attr(vp, access_acl, _ACL_TYPE_ACCESS, 0, &error);
- if (!error) {
- /* Got the ACL, need the mode... */
- va.va_mask = XFS_AT_MODE;
- XVOP_GETATTR(vp, &va, 0, sys_cred, error);
- }
-
- if (error)
- access_acl->acl_cnt = XFS_ACL_NOT_PRESENT;
- else /* We have a good ACL and the file mode, synchronize. */
- xfs_acl_sync_mode(va.va_mode, access_acl);
- }
-
- if (default_acl) {
- xfs_acl_get_attr(vp, default_acl, _ACL_TYPE_DEFAULT, 0, &error);
- if (error)
- default_acl->acl_cnt = XFS_ACL_NOT_PRESENT;
- }
- return error;
-}
-
-/*
- * This function retrieves the parent directory's acl, processes it
- * and lets the child inherit the acl(s) that it should.
- */
-int
-xfs_acl_inherit(
- xfs_vnode_t *vp,
- xfs_vattr_t *vap,
- xfs_acl_t *pdaclp)
-{
- xfs_acl_t *cacl;
- int error = 0;
- int basicperms = 0;
-
- /*
- * If the parent does not have a default ACL, or it's an
- * invalid ACL, we're done.
- */
- if (!vp)
- return 0;
- if (!pdaclp || xfs_acl_invalid(pdaclp))
- return 0;
-
- /*
- * Copy the default ACL of the containing directory to
- * the access ACL of the new file and use the mode that
- * was passed in to set up the correct initial values for
- * the u::,g::[m::], and o:: entries. This is what makes
- * umask() "work" with ACL's.
- */
-
- if (!(_ACL_ALLOC(cacl)))
- return ENOMEM;
-
- memcpy(cacl, pdaclp, sizeof(xfs_acl_t));
- xfs_acl_filter_mode(vap->va_mode, cacl);
- xfs_acl_setmode(vp, cacl, &basicperms);
-
- /*
- * Set the Default and Access ACL on the file. The mode is already
- * set on the file, so we don't need to worry about that.
- *
- * If the new file is a directory, its default ACL is a copy of
- * the containing directory's default ACL.
- */
- if (VN_ISDIR(vp))
- xfs_acl_set_attr(vp, pdaclp, _ACL_TYPE_DEFAULT, &error);
- if (!error && !basicperms)
- xfs_acl_set_attr(vp, cacl, _ACL_TYPE_ACCESS, &error);
- _ACL_FREE(cacl);
- return error;
-}
-
-/*
- * Set up the correct mode on the file based on the supplied ACL. This
- * makes sure that the mode on the file reflects the state of the
- * u::,g::[m::], and o:: entries in the ACL. Since the mode is where
- * the ACL is going to get the permissions for these entries, we must
- * synchronize the mode whenever we set the ACL on a file.
- */
-STATIC int
-xfs_acl_setmode(
- xfs_vnode_t *vp,
- xfs_acl_t *acl,
- int *basicperms)
-{
- xfs_vattr_t va;
- xfs_acl_entry_t *ap;
- xfs_acl_entry_t *gap = NULL;
- int i, error, nomask = 1;
-
- *basicperms = 1;
-
- if (acl->acl_cnt == XFS_ACL_NOT_PRESENT)
- return 0;
-
- /*
- * Copy the u::, g::, o::, and m:: bits from the ACL into the
- * mode. The m:: bits take precedence over the g:: bits.
- */
- va.va_mask = XFS_AT_MODE;
- XVOP_GETATTR(vp, &va, 0, sys_cred, error);
- if (error)
- return error;
-
- va.va_mask = XFS_AT_MODE;
- va.va_mode &= ~(S_IRWXU|S_IRWXG|S_IRWXO);
- ap = acl->acl_entry;
- for (i = 0; i < acl->acl_cnt; ++i) {
- switch (ap->ae_tag) {
- case ACL_USER_OBJ:
- va.va_mode |= ap->ae_perm << 6;
- break;
- case ACL_GROUP_OBJ:
- gap = ap;
- break;
- case ACL_MASK: /* more than just standard modes */
- nomask = 0;
- va.va_mode |= ap->ae_perm << 3;
- *basicperms = 0;
- break;
- case ACL_OTHER:
- va.va_mode |= ap->ae_perm;
- break;
- default: /* more than just standard modes */
- *basicperms = 0;
- break;
- }
- ap++;
- }
-
- /* Set the group bits from ACL_GROUP_OBJ if there's no ACL_MASK */
- if (gap && nomask)
- va.va_mode |= gap->ae_perm << 3;
-
- XVOP_SETATTR(vp, &va, 0, sys_cred, error);
- return error;
-}
-
-/*
- * The permissions for the special ACL entries (u::, g::[m::], o::) are
- * actually stored in the file mode (if there is both a group and a mask,
- * the group is stored in the ACL entry and the mask is stored on the file).
- * This allows the mode to remain automatically in sync with the ACL without
- * the need for a call-back to the ACL system at every point where the mode
- * could change. This function takes the permissions from the specified mode
- * and places it in the supplied ACL.
- *
- * This implementation draws its validity from the fact that, when the ACL
- * was assigned, the mode was copied from the ACL.
- * If the mode did not change, therefore, the mode remains exactly what was
- * taken from the special ACL entries at assignment.
- * If a subsequent chmod() was done, the POSIX spec says that the change in
- * mode must cause an update to the ACL seen at user level and used for
- * access checks. Before and after a mode change, therefore, the file mode
- * most accurately reflects what the special ACL entries should permit/deny.
- *
- * CAVEAT: If someone sets the SGI_ACL_FILE attribute directly,
- * the existing mode bits will override whatever is in the
- * ACL. Similarly, if there is a pre-existing ACL that was
- * never in sync with its mode (owing to a bug in 6.5 and
- * before), it will now magically (or mystically) be
- * synchronized. This could cause slight astonishment, but
- * it is better than inconsistent permissions.
- *
- * The supplied ACL is a template that may contain any combination
- * of special entries. These are treated as place holders when we fill
- * out the ACL. This routine does not add or remove special entries, it
- * simply unites each special entry with its associated set of permissions.
- */
-STATIC void
-xfs_acl_sync_mode(
- mode_t mode,
- xfs_acl_t *acl)
-{
- int i, nomask = 1;
- xfs_acl_entry_t *ap;
- xfs_acl_entry_t *gap = NULL;
-
- /*
- * Set ACL entries. POSIX1003.1eD16 requires that the MASK
- * be set instead of the GROUP entry, if there is a MASK.
- */
- for (ap = acl->acl_entry, i = 0; i < acl->acl_cnt; ap++, i++) {
- switch (ap->ae_tag) {
- case ACL_USER_OBJ:
- ap->ae_perm = (mode >> 6) & 0x7;
- break;
- case ACL_GROUP_OBJ:
- gap = ap;
- break;
- case ACL_MASK:
- nomask = 0;
- ap->ae_perm = (mode >> 3) & 0x7;
- break;
- case ACL_OTHER:
- ap->ae_perm = mode & 0x7;
- break;
- default:
- break;
- }
- }
- /* Set the ACL_GROUP_OBJ if there's no ACL_MASK */
- if (gap && nomask)
- gap->ae_perm = (mode >> 3) & 0x7;
-}
-
-/*
- * When inheriting an Access ACL from a directory Default ACL,
- * the ACL bits are set to the intersection of the ACL default
- * permission bits and the file permission bits in mode. If there
- * are no permission bits on the file then we must not give them
- * the ACL. This is what what makes umask() work with ACLs.
- */
-STATIC void
-xfs_acl_filter_mode(
- mode_t mode,
- xfs_acl_t *acl)
-{
- int i, nomask = 1;
- xfs_acl_entry_t *ap;
- xfs_acl_entry_t *gap = NULL;
-
- /*
- * Set ACL entries. POSIX1003.1eD16 requires that the MASK
- * be merged with GROUP entry, if there is a MASK.
- */
- for (ap = acl->acl_entry, i = 0; i < acl->acl_cnt; ap++, i++) {
- switch (ap->ae_tag) {
- case ACL_USER_OBJ:
- ap->ae_perm &= (mode >> 6) & 0x7;
- break;
- case ACL_GROUP_OBJ:
- gap = ap;
- break;
- case ACL_MASK:
- nomask = 0;
- ap->ae_perm &= (mode >> 3) & 0x7;
- break;
- case ACL_OTHER:
- ap->ae_perm &= mode & 0x7;
- break;
- default:
- break;
- }
- }
- /* Set the ACL_GROUP_OBJ if there's no ACL_MASK */
- if (gap && nomask)
- gap->ae_perm &= (mode >> 3) & 0x7;
-}
-
diff --git a/sys/gnu/fs/xfs/xfs_acl.h b/sys/gnu/fs/xfs/xfs_acl.h
deleted file mode 100644
index 538d0d6..0000000
--- a/sys/gnu/fs/xfs/xfs_acl.h
+++ /dev/null
@@ -1,102 +0,0 @@
-/*
- * Copyright (c) 2001-2005 Silicon Graphics, Inc.
- * All Rights Reserved.
- *
- * 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.
- *
- * This program is distributed in the hope that it would 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 the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- */
-#ifndef __XFS_ACL_H__
-#define __XFS_ACL_H__
-
-/*
- * Access Control Lists
- */
-typedef __uint16_t xfs_acl_perm_t;
-typedef __int32_t xfs_acl_type_t;
-typedef __int32_t xfs_acl_tag_t;
-typedef __int32_t xfs_acl_id_t;
-
-#define XFS_ACL_MAX_ENTRIES 25
-#define XFS_ACL_NOT_PRESENT (-1)
-
-typedef struct xfs_acl_entry {
- xfs_acl_tag_t ae_tag;
- xfs_acl_id_t ae_id;
- xfs_acl_perm_t ae_perm;
-} xfs_acl_entry_t;
-
-typedef struct xfs_acl {
- __int32_t acl_cnt;
- xfs_acl_entry_t acl_entry[XFS_ACL_MAX_ENTRIES];
-} xfs_acl_t;
-
-/* On-disk XFS extended attribute names */
-#define SGI_ACL_FILE "SGI_ACL_FILE"
-#define SGI_ACL_DEFAULT "SGI_ACL_DEFAULT"
-#define SGI_ACL_FILE_SIZE (sizeof(SGI_ACL_FILE)-1)
-#define SGI_ACL_DEFAULT_SIZE (sizeof(SGI_ACL_DEFAULT)-1)
-
-
-#ifdef CONFIG_XFS_POSIX_ACL
-
-struct vattr;
-struct vnode;
-struct xfs_inode;
-
-extern struct kmem_zone *xfs_acl_zone;
-#define xfs_acl_zone_init(zone, name) \
- (zone) = kmem_zone_init(sizeof(xfs_acl_t), (name))
-#define xfs_acl_zone_destroy(zone) kmem_zone_destroy(zone)
-
-extern int xfs_acl_inherit(struct vnode *, struct vattr *, xfs_acl_t *);
-extern int xfs_acl_iaccess(struct xfs_inode *, mode_t, cred_t *);
-extern int xfs_acl_vtoacl(struct vnode *, xfs_acl_t *, xfs_acl_t *);
-extern int xfs_acl_vhasacl_access(struct vnode *);
-extern int xfs_acl_vhasacl_default(struct vnode *);
-extern int xfs_acl_vset(struct vnode *, void *, size_t, int);
-extern int xfs_acl_vget(struct vnode *, void *, size_t, int);
-extern int xfs_acl_vremove(struct vnode *vp, int);
-
-#define _ACL_TYPE_ACCESS 1
-#define _ACL_TYPE_DEFAULT 2
-#define _ACL_PERM_INVALID(perm) ((perm) & ~(ACL_READ|ACL_WRITE|ACL_EXECUTE))
-
-#define _ACL_INHERIT(c,v,d) (xfs_acl_inherit(c,v,d))
-#define _ACL_GET_ACCESS(pv,pa) (xfs_acl_vtoacl(pv,pa,NULL) == 0)
-#define _ACL_GET_DEFAULT(pv,pd) (xfs_acl_vtoacl(pv,NULL,pd) == 0)
-#define _ACL_ACCESS_EXISTS xfs_acl_vhasacl_access
-#define _ACL_DEFAULT_EXISTS xfs_acl_vhasacl_default
-#define _ACL_XFS_IACCESS(i,m,c) (XFS_IFORK_Q(i) ? xfs_acl_iaccess(i,m,c) : -1)
-
-#define _ACL_ALLOC(a) ((a) = kmem_zone_alloc(xfs_acl_zone, KM_SLEEP))
-#define _ACL_FREE(a) ((a)? kmem_zone_free(xfs_acl_zone, (a)):(void)0)
-
-#else
-#define xfs_acl_zone_init(zone,name)
-#define xfs_acl_zone_destroy(zone)
-#define xfs_acl_vset(v,p,sz,t) (-EOPNOTSUPP)
-#define xfs_acl_vget(v,p,sz,t) (-EOPNOTSUPP)
-#define xfs_acl_vremove(v,t) (-EOPNOTSUPP)
-#define xfs_acl_vhasacl_access(v) (0)
-#define xfs_acl_vhasacl_default(v) (0)
-#define _ACL_ALLOC(a) (1) /* successfully allocate nothing */
-#define _ACL_FREE(a) ((void)0)
-#define _ACL_INHERIT(c,v,d) (0)
-#define _ACL_GET_ACCESS(pv,pa) (0)
-#define _ACL_GET_DEFAULT(pv,pd) (0)
-#define _ACL_ACCESS_EXISTS (NULL)
-#define _ACL_DEFAULT_EXISTS (NULL)
-#define _ACL_XFS_IACCESS(i,m,c) (-1)
-#endif
-
-#endif /* __XFS_ACL_H__ */
diff --git a/sys/gnu/fs/xfs/xfs_ag.h b/sys/gnu/fs/xfs/xfs_ag.h
deleted file mode 100644
index dc2361d..0000000
--- a/sys/gnu/fs/xfs/xfs_ag.h
+++ /dev/null
@@ -1,231 +0,0 @@
-/*
- * Copyright (c) 2000-2003,2005 Silicon Graphics, Inc.
- * All Rights Reserved.
- *
- * 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.
- *
- * This program is distributed in the hope that it would 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 the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- */
-#ifndef __XFS_AG_H__
-#define __XFS_AG_H__
-
-/*
- * Allocation group header
- * This is divided into three structures, placed in sequential 512-byte
- * buffers after a copy of the superblock (also in a 512-byte buffer).
- */
-
-struct xfs_buf;
-struct xfs_mount;
-struct xfs_trans;
-
-#define XFS_AGF_MAGIC 0x58414746 /* 'XAGF' */
-#define XFS_AGI_MAGIC 0x58414749 /* 'XAGI' */
-#define XFS_AGF_VERSION 1
-#define XFS_AGI_VERSION 1
-
-#define XFS_AGF_GOOD_VERSION(v) ((v) == XFS_AGF_VERSION)
-#define XFS_AGI_GOOD_VERSION(v) ((v) == XFS_AGI_VERSION)
-
-/*
- * Btree number 0 is bno, 1 is cnt. This value gives the size of the
- * arrays below.
- */
-#define XFS_BTNUM_AGF ((int)XFS_BTNUM_CNTi + 1)
-
-/*
- * The second word of agf_levels in the first a.g. overlaps the EFS
- * superblock's magic number. Since the magic numbers valid for EFS
- * are > 64k, our value cannot be confused for an EFS superblock's.
- */
-
-typedef struct xfs_agf {
- /*
- * Common allocation group header information
- */
- __be32 agf_magicnum; /* magic number == XFS_AGF_MAGIC */
- __be32 agf_versionnum; /* header version == XFS_AGF_VERSION */
- __be32 agf_seqno; /* sequence # starting from 0 */
- __be32 agf_length; /* size in blocks of a.g. */
- /*
- * Freespace information
- */
- __be32 agf_roots[XFS_BTNUM_AGF]; /* root blocks */
- __be32 agf_spare0; /* spare field */
- __be32 agf_levels[XFS_BTNUM_AGF]; /* btree levels */
- __be32 agf_spare1; /* spare field */
- __be32 agf_flfirst; /* first freelist block's index */
- __be32 agf_fllast; /* last freelist block's index */
- __be32 agf_flcount; /* count of blocks in freelist */
- __be32 agf_freeblks; /* total free blocks */
- __be32 agf_longest; /* longest free space */
-} xfs_agf_t;
-
-#define XFS_AGF_MAGICNUM 0x00000001
-#define XFS_AGF_VERSIONNUM 0x00000002
-#define XFS_AGF_SEQNO 0x00000004
-#define XFS_AGF_LENGTH 0x00000008
-#define XFS_AGF_ROOTS 0x00000010
-#define XFS_AGF_LEVELS 0x00000020
-#define XFS_AGF_FLFIRST 0x00000040
-#define XFS_AGF_FLLAST 0x00000080
-#define XFS_AGF_FLCOUNT 0x00000100
-#define XFS_AGF_FREEBLKS 0x00000200
-#define XFS_AGF_LONGEST 0x00000400
-#define XFS_AGF_NUM_BITS 11
-#define XFS_AGF_ALL_BITS ((1 << XFS_AGF_NUM_BITS) - 1)
-
-/* disk block (xfs_daddr_t) in the AG */
-#define XFS_AGF_DADDR(mp) ((xfs_daddr_t)(1 << (mp)->m_sectbb_log))
-#define XFS_AGF_BLOCK(mp) XFS_HDR_BLOCK(mp, XFS_AGF_DADDR(mp))
-#define XFS_BUF_TO_AGF(bp) ((xfs_agf_t *)XFS_BUF_PTR(bp))
-
-
-/*
- * Size of the unlinked inode hash table in the agi.
- */
-#define XFS_AGI_UNLINKED_BUCKETS 64
-
-typedef struct xfs_agi {
- /*
- * Common allocation group header information
- */
- __be32 agi_magicnum; /* magic number == XFS_AGI_MAGIC */
- __be32 agi_versionnum; /* header version == XFS_AGI_VERSION */
- __be32 agi_seqno; /* sequence # starting from 0 */
- __be32 agi_length; /* size in blocks of a.g. */
- /*
- * Inode information
- * Inodes are mapped by interpreting the inode number, so no
- * mapping data is needed here.
- */
- __be32 agi_count; /* count of allocated inodes */
- __be32 agi_root; /* root of inode btree */
- __be32 agi_level; /* levels in inode btree */
- __be32 agi_freecount; /* number of free inodes */
- __be32 agi_newino; /* new inode just allocated */
- __be32 agi_dirino; /* last directory inode chunk */
- /*
- * Hash table of inodes which have been unlinked but are
- * still being referenced.
- */
- __be32 agi_unlinked[XFS_AGI_UNLINKED_BUCKETS];
-} xfs_agi_t;
-
-#define XFS_AGI_MAGICNUM 0x00000001
-#define XFS_AGI_VERSIONNUM 0x00000002
-#define XFS_AGI_SEQNO 0x00000004
-#define XFS_AGI_LENGTH 0x00000008
-#define XFS_AGI_COUNT 0x00000010
-#define XFS_AGI_ROOT 0x00000020
-#define XFS_AGI_LEVEL 0x00000040
-#define XFS_AGI_FREECOUNT 0x00000080
-#define XFS_AGI_NEWINO 0x00000100
-#define XFS_AGI_DIRINO 0x00000200
-#define XFS_AGI_UNLINKED 0x00000400
-#define XFS_AGI_NUM_BITS 11
-#define XFS_AGI_ALL_BITS ((1 << XFS_AGI_NUM_BITS) - 1)
-
-/* disk block (xfs_daddr_t) in the AG */
-#define XFS_AGI_DADDR(mp) ((xfs_daddr_t)(2 << (mp)->m_sectbb_log))
-#define XFS_AGI_BLOCK(mp) XFS_HDR_BLOCK(mp, XFS_AGI_DADDR(mp))
-#define XFS_BUF_TO_AGI(bp) ((xfs_agi_t *)XFS_BUF_PTR(bp))
-
-/*
- * The third a.g. block contains the a.g. freelist, an array
- * of block pointers to blocks owned by the allocation btree code.
- */
-#define XFS_AGFL_DADDR(mp) ((xfs_daddr_t)(3 << (mp)->m_sectbb_log))
-#define XFS_AGFL_BLOCK(mp) XFS_HDR_BLOCK(mp, XFS_AGFL_DADDR(mp))
-#define XFS_AGFL_SIZE(mp) ((mp)->m_sb.sb_sectsize / sizeof(xfs_agblock_t))
-#define XFS_BUF_TO_AGFL(bp) ((xfs_agfl_t *)XFS_BUF_PTR(bp))
-
-typedef struct xfs_agfl {
- xfs_agblock_t agfl_bno[1]; /* actually XFS_AGFL_SIZE(mp) */
-} xfs_agfl_t;
-
-/*
- * Busy block/extent entry. Used in perag to mark blocks that have been freed
- * but whose transactions aren't committed to disk yet.
- */
-typedef struct xfs_perag_busy {
- xfs_agblock_t busy_start;
- xfs_extlen_t busy_length;
- struct xfs_trans *busy_tp; /* transaction that did the free */
-} xfs_perag_busy_t;
-
-/*
- * Per-ag incore structure, copies of information in agf and agi,
- * to improve the performance of allocation group selection.
- *
- * pick sizes which fit in allocation buckets well
- */
-#if (BITS_PER_LONG == 32)
-#define XFS_PAGB_NUM_SLOTS 84
-#elif (BITS_PER_LONG == 64)
-#define XFS_PAGB_NUM_SLOTS 128
-#endif
-
-typedef struct xfs_perag
-{
- char pagf_init; /* this agf's entry is initialized */
- char pagi_init; /* this agi's entry is initialized */
- char pagf_metadata; /* the agf is preferred to be metadata */
- char pagi_inodeok; /* The agi is ok for inodes */
- __uint8_t pagf_levels[XFS_BTNUM_AGF];
- /* # of levels in bno & cnt btree */
- __uint32_t pagf_flcount; /* count of blocks in freelist */
- xfs_extlen_t pagf_freeblks; /* total free blocks */
- xfs_extlen_t pagf_longest; /* longest free space */
- xfs_agino_t pagi_freecount; /* number of free inodes */
-#ifdef __KERNEL__
- lock_t pagb_lock; /* lock for pagb_list */
-#endif
- int pagb_count; /* pagb slots in use */
- xfs_perag_busy_t *pagb_list; /* unstable blocks */
-} xfs_perag_t;
-
-#define XFS_AG_MAXLEVELS(mp) ((mp)->m_ag_maxlevels)
-#define XFS_MIN_FREELIST_RAW(bl,cl,mp) \
- (MIN(bl + 1, XFS_AG_MAXLEVELS(mp)) + MIN(cl + 1, XFS_AG_MAXLEVELS(mp)))
-#define XFS_MIN_FREELIST(a,mp) \
- (XFS_MIN_FREELIST_RAW( \
- be32_to_cpu((a)->agf_levels[XFS_BTNUM_BNOi]), \
- be32_to_cpu((a)->agf_levels[XFS_BTNUM_CNTi]), mp))
-#define XFS_MIN_FREELIST_PAG(pag,mp) \
- (XFS_MIN_FREELIST_RAW( \
- (uint_t)(pag)->pagf_levels[XFS_BTNUM_BNOi], \
- (uint_t)(pag)->pagf_levels[XFS_BTNUM_CNTi], mp))
-
-#define XFS_AGB_TO_FSB(mp,agno,agbno) \
- (((xfs_fsblock_t)(agno) << (mp)->m_sb.sb_agblklog) | (agbno))
-#define XFS_FSB_TO_AGNO(mp,fsbno) \
- ((xfs_agnumber_t)((fsbno) >> (mp)->m_sb.sb_agblklog))
-#define XFS_FSB_TO_AGBNO(mp,fsbno) \
- ((xfs_agblock_t)((fsbno) & XFS_MASK32LO((mp)->m_sb.sb_agblklog)))
-#define XFS_AGB_TO_DADDR(mp,agno,agbno) \
- ((xfs_daddr_t)XFS_FSB_TO_BB(mp, \
- (xfs_fsblock_t)(agno) * (mp)->m_sb.sb_agblocks + (agbno)))
-#define XFS_AG_DADDR(mp,agno,d) (XFS_AGB_TO_DADDR(mp, agno, 0) + (d))
-
-/*
- * For checking for bad ranges of xfs_daddr_t's, covering multiple
- * allocation groups or a single xfs_daddr_t that's a superblock copy.
- */
-#define XFS_AG_CHECK_DADDR(mp,d,len) \
- ((len) == 1 ? \
- ASSERT((d) == XFS_SB_DADDR || \
- XFS_DADDR_TO_AGBNO(mp, d) != XFS_SB_DADDR) : \
- ASSERT(XFS_DADDR_TO_AGNO(mp, d) == \
- XFS_DADDR_TO_AGNO(mp, (d) + (len) - 1)))
-
-#endif /* __XFS_AG_H__ */
diff --git a/sys/gnu/fs/xfs/xfs_alloc.c b/sys/gnu/fs/xfs/xfs_alloc.c
deleted file mode 100644
index 1c2f50e..0000000
--- a/sys/gnu/fs/xfs/xfs_alloc.c
+++ /dev/null
@@ -1,2603 +0,0 @@
-/*
- * Copyright (c) 2000-2002,2005 Silicon Graphics, Inc.
- * All Rights Reserved.
- *
- * 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.
- *
- * This program is distributed in the hope that it would 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 the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- */
-#include "xfs.h"
-#include "xfs_fs.h"
-#include "xfs_types.h"
-#include "xfs_bit.h"
-#include "xfs_log.h"
-#include "xfs_inum.h"
-#include "xfs_trans.h"
-#include "xfs_sb.h"
-#include "xfs_ag.h"
-#include "xfs_dir.h"
-#include "xfs_dir2.h"
-#include "xfs_dmapi.h"
-#include "xfs_mount.h"
-#include "xfs_bmap_btree.h"
-#include "xfs_alloc_btree.h"
-#include "xfs_ialloc_btree.h"
-#include "xfs_dir_sf.h"
-#include "xfs_dir2_sf.h"
-#include "xfs_attr_sf.h"
-#include "xfs_dinode.h"
-#include "xfs_inode.h"
-#include "xfs_btree.h"
-#include "xfs_ialloc.h"
-#include "xfs_alloc.h"
-#include "xfs_error.h"
-
-
-#define XFS_ABSDIFF(a,b) (((a) <= (b)) ? ((b) - (a)) : ((a) - (b)))
-
-#define XFSA_FIXUP_BNO_OK 1
-#define XFSA_FIXUP_CNT_OK 2
-
-STATIC int
-xfs_alloc_search_busy(xfs_trans_t *tp,
- xfs_agnumber_t agno,
- xfs_agblock_t bno,
- xfs_extlen_t len);
-
-#if defined(XFS_ALLOC_TRACE)
-ktrace_t *xfs_alloc_trace_buf;
-
-#define TRACE_ALLOC(s,a) \
- xfs_alloc_trace_alloc(fname, s, a, __LINE__)
-#define TRACE_FREE(s,a,b,x,f) \
- xfs_alloc_trace_free(fname, s, mp, a, b, x, f, __LINE__)
-#define TRACE_MODAGF(s,a,f) \
- xfs_alloc_trace_modagf(fname, s, mp, a, f, __LINE__)
-#define TRACE_BUSY(fname,s,ag,agb,l,sl,tp) \
- xfs_alloc_trace_busy(fname, s, mp, ag, agb, l, sl, tp, XFS_ALLOC_KTRACE_BUSY, __LINE__)
-#define TRACE_UNBUSY(fname,s,ag,sl,tp) \
- xfs_alloc_trace_busy(fname, s, mp, ag, -1, -1, sl, tp, XFS_ALLOC_KTRACE_UNBUSY, __LINE__)
-#define TRACE_BUSYSEARCH(fname,s,ag,agb,l,sl,tp) \
- xfs_alloc_trace_busy(fname, s, mp, ag, agb, l, sl, tp, XFS_ALLOC_KTRACE_BUSYSEARCH, __LINE__)
-#else
-#define TRACE_ALLOC(s,a)
-#define TRACE_FREE(s,a,b,x,f)
-#define TRACE_MODAGF(s,a,f)
-#define TRACE_BUSY(s,a,ag,agb,l,sl,tp)
-#define TRACE_UNBUSY(fname,s,ag,sl,tp)
-#define TRACE_BUSYSEARCH(fname,s,ag,agb,l,sl,tp)
-#endif /* XFS_ALLOC_TRACE */
-
-/*
- * Prototypes for per-ag allocation routines
- */
-
-STATIC int xfs_alloc_ag_vextent_exact(xfs_alloc_arg_t *);
-STATIC int xfs_alloc_ag_vextent_near(xfs_alloc_arg_t *);
-STATIC int xfs_alloc_ag_vextent_size(xfs_alloc_arg_t *);
-STATIC int xfs_alloc_ag_vextent_small(xfs_alloc_arg_t *,
- xfs_btree_cur_t *, xfs_agblock_t *, xfs_extlen_t *, int *);
-
-/*
- * Internal functions.
- */
-
-/*
- * Compute aligned version of the found extent.
- * Takes alignment and min length into account.
- */
-STATIC int /* success (>= minlen) */
-xfs_alloc_compute_aligned(
- xfs_agblock_t foundbno, /* starting block in found extent */
- xfs_extlen_t foundlen, /* length in found extent */
- xfs_extlen_t alignment, /* alignment for allocation */
- xfs_extlen_t minlen, /* minimum length for allocation */
- xfs_agblock_t *resbno, /* result block number */
- xfs_extlen_t *reslen) /* result length */
-{
- xfs_agblock_t bno;
- xfs_extlen_t diff;
- xfs_extlen_t len;
-
- if (alignment > 1 && foundlen >= minlen) {
- bno = roundup(foundbno, alignment);
- diff = bno - foundbno;
- len = diff >= foundlen ? 0 : foundlen - diff;
- } else {
- bno = foundbno;
- len = foundlen;
- }
- *resbno = bno;
- *reslen = len;
- return len >= minlen;
-}
-
-/*
- * Compute best start block and diff for "near" allocations.
- * freelen >= wantlen already checked by caller.
- */
-STATIC xfs_extlen_t /* difference value (absolute) */
-xfs_alloc_compute_diff(
- xfs_agblock_t wantbno, /* target starting block */
- xfs_extlen_t wantlen, /* target length */
- xfs_extlen_t alignment, /* target alignment */
- xfs_agblock_t freebno, /* freespace's starting block */
- xfs_extlen_t freelen, /* freespace's length */
- xfs_agblock_t *newbnop) /* result: best start block from free */
-{
- xfs_agblock_t freeend; /* end of freespace extent */
- xfs_agblock_t newbno1; /* return block number */
- xfs_agblock_t newbno2; /* other new block number */
- xfs_extlen_t newlen1=0; /* length with newbno1 */
- xfs_extlen_t newlen2=0; /* length with newbno2 */
- xfs_agblock_t wantend; /* end of target extent */
-
- ASSERT(freelen >= wantlen);
- freeend = freebno + freelen;
- wantend = wantbno + wantlen;
- if (freebno >= wantbno) {
- if ((newbno1 = roundup(freebno, alignment)) >= freeend)
- newbno1 = NULLAGBLOCK;
- } else if (freeend >= wantend && alignment > 1) {
- newbno1 = roundup(wantbno, alignment);
- newbno2 = newbno1 - alignment;
- if (newbno1 >= freeend)
- newbno1 = NULLAGBLOCK;
- else
- newlen1 = XFS_EXTLEN_MIN(wantlen, freeend - newbno1);
- if (newbno2 < freebno)
- newbno2 = NULLAGBLOCK;
- else
- newlen2 = XFS_EXTLEN_MIN(wantlen, freeend - newbno2);
- if (newbno1 != NULLAGBLOCK && newbno2 != NULLAGBLOCK) {
- if (newlen1 < newlen2 ||
- (newlen1 == newlen2 &&
- XFS_ABSDIFF(newbno1, wantbno) >
- XFS_ABSDIFF(newbno2, wantbno)))
- newbno1 = newbno2;
- } else if (newbno2 != NULLAGBLOCK)
- newbno1 = newbno2;
- } else if (freeend >= wantend) {
- newbno1 = wantbno;
- } else if (alignment > 1) {
- newbno1 = roundup(freeend - wantlen, alignment);
- if (newbno1 > freeend - wantlen &&
- newbno1 - alignment >= freebno)
- newbno1 -= alignment;
- else if (newbno1 >= freeend)
- newbno1 = NULLAGBLOCK;
- } else
- newbno1 = freeend - wantlen;
- *newbnop = newbno1;
- return newbno1 == NULLAGBLOCK ? 0 : XFS_ABSDIFF(newbno1, wantbno);
-}
-
-/*
- * Fix up the length, based on mod and prod.
- * len should be k * prod + mod for some k.
- * If len is too small it is returned unchanged.
- * If len hits maxlen it is left alone.
- */
-STATIC void
-xfs_alloc_fix_len(
- xfs_alloc_arg_t *args) /* allocation argument structure */
-{
- xfs_extlen_t k;
- xfs_extlen_t rlen;
-
- ASSERT(args->mod < args->prod);
- rlen = args->len;
- ASSERT(rlen >= args->minlen);
- ASSERT(rlen <= args->maxlen);
- if (args->prod <= 1 || rlen < args->mod || rlen == args->maxlen ||
- (args->mod == 0 && rlen < args->prod))
- return;
- k = rlen % args->prod;
- if (k == args->mod)
- return;
- if (k > args->mod) {
- if ((int)(rlen = rlen - k - args->mod) < (int)args->minlen)
- return;
- } else {
- if ((int)(rlen = rlen - args->prod - (args->mod - k)) <
- (int)args->minlen)
- return;
- }
- ASSERT(rlen >= args->minlen);
- ASSERT(rlen <= args->maxlen);
- args->len = rlen;
-}
-
-/*
- * Fix up length if there is too little space left in the a.g.
- * Return 1 if ok, 0 if too little, should give up.
- */
-STATIC int
-xfs_alloc_fix_minleft(
- xfs_alloc_arg_t *args) /* allocation argument structure */
-{
- xfs_agf_t *agf; /* a.g. freelist header */
- int diff; /* free space difference */
-
- if (args->minleft == 0)
- return 1;
- agf = XFS_BUF_TO_AGF(args->agbp);
- diff = be32_to_cpu(agf->agf_freeblks)
- + be32_to_cpu(agf->agf_flcount)
- - args->len - args->minleft;
- if (diff >= 0)
- return 1;
- args->len += diff; /* shrink the allocated space */
- if (args->len >= args->minlen)
- return 1;
- args->agbno = NULLAGBLOCK;
- return 0;
-}
-
-/*
- * Update the two btrees, logically removing from freespace the extent
- * starting at rbno, rlen blocks. The extent is contained within the
- * actual (current) free extent fbno for flen blocks.
- * Flags are passed in indicating whether the cursors are set to the
- * relevant records.
- */
-STATIC int /* error code */
-xfs_alloc_fixup_trees(
- xfs_btree_cur_t *cnt_cur, /* cursor for by-size btree */
- xfs_btree_cur_t *bno_cur, /* cursor for by-block btree */
- xfs_agblock_t fbno, /* starting block of free extent */
- xfs_extlen_t flen, /* length of free extent */
- xfs_agblock_t rbno, /* starting block of returned extent */
- xfs_extlen_t rlen, /* length of returned extent */
- int flags) /* flags, XFSA_FIXUP_... */
-{
- int error; /* error code */
- int i; /* operation results */
- xfs_agblock_t nfbno1; /* first new free startblock */
- xfs_agblock_t nfbno2; /* second new free startblock */
- xfs_extlen_t nflen1=0; /* first new free length */
- xfs_extlen_t nflen2=0; /* second new free length */
-
- /*
- * Look up the record in the by-size tree if necessary.
- */
- if (flags & XFSA_FIXUP_CNT_OK) {
-#ifdef DEBUG
- if ((error = xfs_alloc_get_rec(cnt_cur, &nfbno1, &nflen1, &i)))
- return error;
- XFS_WANT_CORRUPTED_RETURN(
- i == 1 && nfbno1 == fbno && nflen1 == flen);
-#endif
- } else {
- if ((error = xfs_alloc_lookup_eq(cnt_cur, fbno, flen, &i)))
- return error;
- XFS_WANT_CORRUPTED_RETURN(i == 1);
- }
- /*
- * Look up the record in the by-block tree if necessary.
- */
- if (flags & XFSA_FIXUP_BNO_OK) {
-#ifdef DEBUG
- if ((error = xfs_alloc_get_rec(bno_cur, &nfbno1, &nflen1, &i)))
- return error;
- XFS_WANT_CORRUPTED_RETURN(
- i == 1 && nfbno1 == fbno && nflen1 == flen);
-#endif
- } else {
- if ((error = xfs_alloc_lookup_eq(bno_cur, fbno, flen, &i)))
- return error;
- XFS_WANT_CORRUPTED_RETURN(i == 1);
- }
-#ifdef DEBUG
- {
- xfs_alloc_block_t *bnoblock;
- xfs_alloc_block_t *cntblock;
-
- if (bno_cur->bc_nlevels == 1 &&
- cnt_cur->bc_nlevels == 1) {
- bnoblock = XFS_BUF_TO_ALLOC_BLOCK(bno_cur->bc_bufs[0]);
- cntblock = XFS_BUF_TO_ALLOC_BLOCK(cnt_cur->bc_bufs[0]);
- XFS_WANT_CORRUPTED_RETURN(
- be16_to_cpu(bnoblock->bb_numrecs) ==
- be16_to_cpu(cntblock->bb_numrecs));
- }
- }
-#endif
- /*
- * Deal with all four cases: the allocated record is contained
- * within the freespace record, so we can have new freespace
- * at either (or both) end, or no freespace remaining.
- */
- if (rbno == fbno && rlen == flen)
- nfbno1 = nfbno2 = NULLAGBLOCK;
- else if (rbno == fbno) {
- nfbno1 = rbno + rlen;
- nflen1 = flen - rlen;
- nfbno2 = NULLAGBLOCK;
- } else if (rbno + rlen == fbno + flen) {
- nfbno1 = fbno;
- nflen1 = flen - rlen;
- nfbno2 = NULLAGBLOCK;
- } else {
- nfbno1 = fbno;
- nflen1 = rbno - fbno;
- nfbno2 = rbno + rlen;
- nflen2 = (fbno + flen) - nfbno2;
- }
- /*
- * Delete the entry from the by-size btree.
- */
- if ((error = xfs_alloc_delete(cnt_cur, &i)))
- return error;
- XFS_WANT_CORRUPTED_RETURN(i == 1);
- /*
- * Add new by-size btree entry(s).
- */
- if (nfbno1 != NULLAGBLOCK) {
- if ((error = xfs_alloc_lookup_eq(cnt_cur, nfbno1, nflen1, &i)))
- return error;
- XFS_WANT_CORRUPTED_RETURN(i == 0);
- if ((error = xfs_alloc_insert(cnt_cur, &i)))
- return error;
- XFS_WANT_CORRUPTED_RETURN(i == 1);
- }
- if (nfbno2 != NULLAGBLOCK) {
- if ((error = xfs_alloc_lookup_eq(cnt_cur, nfbno2, nflen2, &i)))
- return error;
- XFS_WANT_CORRUPTED_RETURN(i == 0);
- if ((error = xfs_alloc_insert(cnt_cur, &i)))
- return error;
- XFS_WANT_CORRUPTED_RETURN(i == 1);
- }
- /*
- * Fix up the by-block btree entry(s).
- */
- if (nfbno1 == NULLAGBLOCK) {
- /*
- * No remaining freespace, just delete the by-block tree entry.
- */
- if ((error = xfs_alloc_delete(bno_cur, &i)))
- return error;
- XFS_WANT_CORRUPTED_RETURN(i == 1);
- } else {
- /*
- * Update the by-block entry to start later|be shorter.
- */
- if ((error = xfs_alloc_update(bno_cur, nfbno1, nflen1)))
- return error;
- }
- if (nfbno2 != NULLAGBLOCK) {
- /*
- * 2 resulting free entries, need to add one.
- */
- if ((error = xfs_alloc_lookup_eq(bno_cur, nfbno2, nflen2, &i)))
- return error;
- XFS_WANT_CORRUPTED_RETURN(i == 0);
- if ((error = xfs_alloc_insert(bno_cur, &i)))
- return error;
- XFS_WANT_CORRUPTED_RETURN(i == 1);
- }
- return 0;
-}
-
-/*
- * Read in the allocation group free block array.
- */
-STATIC int /* error */
-xfs_alloc_read_agfl(
- xfs_mount_t *mp, /* mount point structure */
- xfs_trans_t *tp, /* transaction pointer */
- xfs_agnumber_t agno, /* allocation group number */
- xfs_buf_t **bpp) /* buffer for the ag free block array */
-{
- xfs_buf_t *bp; /* return value */
- int error;
-
- ASSERT(agno != NULLAGNUMBER);
- error = xfs_trans_read_buf(
- mp, tp, mp->m_ddev_targp,
- XFS_AG_DADDR(mp, agno, XFS_AGFL_DADDR(mp)),
- XFS_FSS_TO_BB(mp, 1), 0, &bp);
- if (error)
- return error;
- ASSERT(bp);
- ASSERT(!XFS_BUF_GETERROR(bp));
- XFS_BUF_SET_VTYPE_REF(bp, B_FS_AGFL, XFS_AGFL_REF);
- *bpp = bp;
- return 0;
-}
-
-#if defined(XFS_ALLOC_TRACE)
-/*
- * Add an allocation trace entry for an alloc call.
- */
-STATIC void
-xfs_alloc_trace_alloc(
- char *name, /* function tag string */
- char *str, /* additional string */
- xfs_alloc_arg_t *args, /* allocation argument structure */
- int line) /* source line number */
-{
- ktrace_enter(xfs_alloc_trace_buf,
- (void *)(__psint_t)(XFS_ALLOC_KTRACE_ALLOC | (line << 16)),
- (void *)name,
- (void *)str,
- (void *)args->mp,
- (void *)(__psunsigned_t)args->agno,
- (void *)(__psunsigned_t)args->agbno,
- (void *)(__psunsigned_t)args->minlen,
- (void *)(__psunsigned_t)args->maxlen,
- (void *)(__psunsigned_t)args->mod,
- (void *)(__psunsigned_t)args->prod,
- (void *)(__psunsigned_t)args->minleft,
- (void *)(__psunsigned_t)args->total,
- (void *)(__psunsigned_t)args->alignment,
- (void *)(__psunsigned_t)args->len,
- (void *)((((__psint_t)args->type) << 16) |
- (__psint_t)args->otype),
- (void *)(__psint_t)((args->wasdel << 3) |
- (args->wasfromfl << 2) |
- (args->isfl << 1) |
- (args->userdata << 0)));
-}
-
-/*
- * Add an allocation trace entry for a free call.
- */
-STATIC void
-xfs_alloc_trace_free(
- char *name, /* function tag string */
- char *str, /* additional string */
- xfs_mount_t *mp, /* file system mount point */
- xfs_agnumber_t agno, /* allocation group number */
- xfs_agblock_t agbno, /* a.g. relative block number */
- xfs_extlen_t len, /* length of extent */
- int isfl, /* set if is freelist allocation/free */
- int line) /* source line number */
-{
- ktrace_enter(xfs_alloc_trace_buf,
- (void *)(__psint_t)(XFS_ALLOC_KTRACE_FREE | (line << 16)),
- (void *)name,
- (void *)str,
- (void *)mp,
- (void *)(__psunsigned_t)agno,
- (void *)(__psunsigned_t)agbno,
- (void *)(__psunsigned_t)len,
- (void *)(__psint_t)isfl,
- NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL);
-}
-
-/*
- * Add an allocation trace entry for modifying an agf.
- */
-STATIC void
-xfs_alloc_trace_modagf(
- char *name, /* function tag string */
- char *str, /* additional string */
- xfs_mount_t *mp, /* file system mount point */
- xfs_agf_t *agf, /* new agf value */
- int flags, /* logging flags for agf */
- int line) /* source line number */
-{
- ktrace_enter(xfs_alloc_trace_buf,
- (void *)(__psint_t)(XFS_ALLOC_KTRACE_MODAGF | (line << 16)),
- (void *)name,
- (void *)str,
- (void *)mp,
- (void *)(__psint_t)flags,
- (void *)(__psunsigned_t)be32_to_cpu(agf->agf_seqno),
- (void *)(__psunsigned_t)be32_to_cpu(agf->agf_length),
- (void *)(__psunsigned_t)be32_to_cpu(agf->agf_roots[XFS_BTNUM_BNO]),
- (void *)(__psunsigned_t)be32_to_cpu(agf->agf_roots[XFS_BTNUM_CNT]),
- (void *)(__psunsigned_t)be32_to_cpu(agf->agf_levels[XFS_BTNUM_BNO]),
- (void *)(__psunsigned_t)be32_to_cpu(agf->agf_levels[XFS_BTNUM_CNT]),
- (void *)(__psunsigned_t)be32_to_cpu(agf->agf_flfirst),
- (void *)(__psunsigned_t)be32_to_cpu(agf->agf_fllast),
- (void *)(__psunsigned_t)be32_to_cpu(agf->agf_flcount),
- (void *)(__psunsigned_t)be32_to_cpu(agf->agf_freeblks),
- (void *)(__psunsigned_t)be32_to_cpu(agf->agf_longest));
-}
-
-STATIC void
-xfs_alloc_trace_busy(
- char *name, /* function tag string */
- char *str, /* additional string */
- xfs_mount_t *mp, /* file system mount point */
- xfs_agnumber_t agno, /* allocation group number */
- xfs_agblock_t agbno, /* a.g. relative block number */
- xfs_extlen_t len, /* length of extent */
- int slot, /* perag Busy slot */
- xfs_trans_t *tp,
- int trtype, /* type: add, delete, search */
- int line) /* source line number */
-{
- ktrace_enter(xfs_alloc_trace_buf,
- (void *)(__psint_t)(trtype | (line << 16)),
- (void *)name,
- (void *)str,
- (void *)mp,
- (void *)(__psunsigned_t)agno,
- (void *)(__psunsigned_t)agbno,
- (void *)(__psunsigned_t)len,
- (void *)(__psint_t)slot,
- (void *)tp,
- NULL, NULL, NULL, NULL, NULL, NULL, NULL);
-}
-#endif /* XFS_ALLOC_TRACE */
-
-/*
- * Allocation group level functions.
- */
-
-/*
- * Allocate a variable extent in the allocation group agno.
- * Type and bno are used to determine where in the allocation group the
- * extent will start.
- * Extent's length (returned in *len) will be between minlen and maxlen,
- * and of the form k * prod + mod unless there's nothing that large.
- * Return the starting a.g. block, or NULLAGBLOCK if we can't do it.
- */
-STATIC int /* error */
-xfs_alloc_ag_vextent(
- xfs_alloc_arg_t *args) /* argument structure for allocation */
-{
- int error=0;
-#ifdef XFS_ALLOC_TRACE
- static char fname[] = "xfs_alloc_ag_vextent";
-#endif
-
- ASSERT(args->minlen > 0);
- ASSERT(args->maxlen > 0);
- ASSERT(args->minlen <= args->maxlen);
- ASSERT(args->mod < args->prod);
- ASSERT(args->alignment > 0);
- /*
- * Branch to correct routine based on the type.
- */
- args->wasfromfl = 0;
- switch (args->type) {
- case XFS_ALLOCTYPE_THIS_AG:
- error = xfs_alloc_ag_vextent_size(args);
- break;
- case XFS_ALLOCTYPE_NEAR_BNO:
- error = xfs_alloc_ag_vextent_near(args);
- break;
- case XFS_ALLOCTYPE_THIS_BNO:
- error = xfs_alloc_ag_vextent_exact(args);
- break;
- default:
- ASSERT(0);
- /* NOTREACHED */
- }
- if (error)
- return error;
- /*
- * If the allocation worked, need to change the agf structure
- * (and log it), and the superblock.
- */
- if (args->agbno != NULLAGBLOCK) {
- xfs_agf_t *agf; /* allocation group freelist header */
-#ifdef XFS_ALLOC_TRACE
- xfs_mount_t *mp = args->mp;
-#endif
- long slen = (long)args->len;
-
- ASSERT(args->len >= args->minlen && args->len <= args->maxlen);
- ASSERT(!(args->wasfromfl) || !args->isfl);
- ASSERT(args->agbno % args->alignment == 0);
- if (!(args->wasfromfl)) {
-
- agf = XFS_BUF_TO_AGF(args->agbp);
- be32_add(&agf->agf_freeblks, -(args->len));
- xfs_trans_agblocks_delta(args->tp,
- -((long)(args->len)));
- args->pag->pagf_freeblks -= args->len;
- ASSERT(be32_to_cpu(agf->agf_freeblks) <=
- be32_to_cpu(agf->agf_length));
- TRACE_MODAGF(NULL, agf, XFS_AGF_FREEBLKS);
- xfs_alloc_log_agf(args->tp, args->agbp,
- XFS_AGF_FREEBLKS);
- /* search the busylist for these blocks */
- xfs_alloc_search_busy(args->tp, args->agno,
- args->agbno, args->len);
- }
- if (!args->isfl)
- xfs_trans_mod_sb(args->tp,
- args->wasdel ? XFS_TRANS_SB_RES_FDBLOCKS :
- XFS_TRANS_SB_FDBLOCKS, -slen);
- XFS_STATS_INC(xs_allocx);
- XFS_STATS_ADD(xs_allocb, args->len);
- }
- return 0;
-}
-
-/*
- * Allocate a variable extent at exactly agno/bno.
- * Extent's length (returned in *len) will be between minlen and maxlen,
- * and of the form k * prod + mod unless there's nothing that large.
- * Return the starting a.g. block (bno), or NULLAGBLOCK if we can't do it.
- */
-STATIC int /* error */
-xfs_alloc_ag_vextent_exact(
- xfs_alloc_arg_t *args) /* allocation argument structure */
-{
- xfs_btree_cur_t *bno_cur;/* by block-number btree cursor */
- xfs_btree_cur_t *cnt_cur;/* by count btree cursor */
- xfs_agblock_t end; /* end of allocated extent */
- int error;
- xfs_agblock_t fbno; /* start block of found extent */
- xfs_agblock_t fend; /* end block of found extent */
- xfs_extlen_t flen; /* length of found extent */
-#ifdef XFS_ALLOC_TRACE
- static char fname[] = "xfs_alloc_ag_vextent_exact";
-#endif
- int i; /* success/failure of operation */
- xfs_agblock_t maxend; /* end of maximal extent */
- xfs_agblock_t minend; /* end of minimal extent */
- xfs_extlen_t rlen; /* length of returned extent */
-
- ASSERT(args->alignment == 1);
- /*
- * Allocate/initialize a cursor for the by-number freespace btree.
- */
- bno_cur = xfs_btree_init_cursor(args->mp, args->tp, args->agbp,
- args->agno, XFS_BTNUM_BNO, NULL, 0);
- /*
- * Lookup bno and minlen in the btree (minlen is irrelevant, really).
- * Look for the closest free block <= bno, it must contain bno
- * if any free block does.
- */
- if ((error = xfs_alloc_lookup_le(bno_cur, args->agbno, args->minlen, &i)))
- goto error0;
- if (!i) {
- /*
- * Didn't find it, return null.
- */
- xfs_btree_del_cursor(bno_cur, XFS_BTREE_NOERROR);
- args->agbno = NULLAGBLOCK;
- return 0;
- }
- /*
- * Grab the freespace record.
- */
- if ((error = xfs_alloc_get_rec(bno_cur, &fbno, &flen, &i)))
- goto error0;
- XFS_WANT_CORRUPTED_GOTO(i == 1, error0);
- ASSERT(fbno <= args->agbno);
- minend = args->agbno + args->minlen;
- maxend = args->agbno + args->maxlen;
- fend = fbno + flen;
- /*
- * Give up if the freespace isn't long enough for the minimum request.
- */
- if (fend < minend) {
- xfs_btree_del_cursor(bno_cur, XFS_BTREE_NOERROR);
- args->agbno = NULLAGBLOCK;
- return 0;
- }
- /*
- * End of extent will be smaller of the freespace end and the
- * maximal requested end.
- */
- end = XFS_AGBLOCK_MIN(fend, maxend);
- /*
- * Fix the length according to mod and prod if given.
- */
- args->len = end - args->agbno;
- xfs_alloc_fix_len(args);
- if (!xfs_alloc_fix_minleft(args)) {
- xfs_btree_del_cursor(bno_cur, XFS_BTREE_NOERROR);
- return 0;
- }
- rlen = args->len;
- ASSERT(args->agbno + rlen <= fend);
- end = args->agbno + rlen;
- /*
- * We are allocating agbno for rlen [agbno .. end]
- * Allocate/initialize a cursor for the by-size btree.
- */
- cnt_cur = xfs_btree_init_cursor(args->mp, args->tp, args->agbp,
- args->agno, XFS_BTNUM_CNT, NULL, 0);
- ASSERT(args->agbno + args->len <=
- be32_to_cpu(XFS_BUF_TO_AGF(args->agbp)->agf_length));
- if ((error = xfs_alloc_fixup_trees(cnt_cur, bno_cur, fbno, flen,
- args->agbno, args->len, XFSA_FIXUP_BNO_OK))) {
- xfs_btree_del_cursor(cnt_cur, XFS_BTREE_ERROR);
- goto error0;
- }
- xfs_btree_del_cursor(bno_cur, XFS_BTREE_NOERROR);
- xfs_btree_del_cursor(cnt_cur, XFS_BTREE_NOERROR);
- TRACE_ALLOC("normal", args);
- args->wasfromfl = 0;
- return 0;
-
-error0:
- xfs_btree_del_cursor(bno_cur, XFS_BTREE_ERROR);
- TRACE_ALLOC("error", args);
- return error;
-}
-
-/*
- * Allocate a variable extent near bno in the allocation group agno.
- * Extent's length (returned in len) will be between minlen and maxlen,
- * and of the form k * prod + mod unless there's nothing that large.
- * Return the starting a.g. block, or NULLAGBLOCK if we can't do it.
- */
-STATIC int /* error */
-xfs_alloc_ag_vextent_near(
- xfs_alloc_arg_t *args) /* allocation argument structure */
-{
- xfs_btree_cur_t *bno_cur_gt; /* cursor for bno btree, right side */
- xfs_btree_cur_t *bno_cur_lt; /* cursor for bno btree, left side */
- xfs_btree_cur_t *cnt_cur; /* cursor for count btree */
-#ifdef XFS_ALLOC_TRACE
- static char fname[] = "xfs_alloc_ag_vextent_near";
-#endif
- xfs_agblock_t gtbno; /* start bno of right side entry */
- xfs_agblock_t gtbnoa; /* aligned ... */
- xfs_extlen_t gtdiff; /* difference to right side entry */
- xfs_extlen_t gtlen; /* length of right side entry */
- xfs_extlen_t gtlena; /* aligned ... */
- xfs_agblock_t gtnew; /* useful start bno of right side */
- int error; /* error code */
- int i; /* result code, temporary */
- int j; /* result code, temporary */
- xfs_agblock_t ltbno; /* start bno of left side entry */
- xfs_agblock_t ltbnoa; /* aligned ... */
- xfs_extlen_t ltdiff; /* difference to left side entry */
- /*REFERENCED*/
- xfs_agblock_t ltend; /* end bno of left side entry */
- xfs_extlen_t ltlen; /* length of left side entry */
- xfs_extlen_t ltlena; /* aligned ... */
- xfs_agblock_t ltnew; /* useful start bno of left side */
- xfs_extlen_t rlen; /* length of returned extent */
-#if defined(DEBUG) && defined(__KERNEL__)
- /*
- * Randomly don't execute the first algorithm.
- */
- int dofirst; /* set to do first algorithm */
-
- dofirst = random() & 1;
-#endif
- /*
- * Get a cursor for the by-size btree.
- */
- cnt_cur = xfs_btree_init_cursor(args->mp, args->tp, args->agbp,
- args->agno, XFS_BTNUM_CNT, NULL, 0);
- ltlen = 0;
- bno_cur_lt = bno_cur_gt = NULL;
- /*
- * See if there are any free extents as big as maxlen.
- */
- if ((error = xfs_alloc_lookup_ge(cnt_cur, 0, args->maxlen, &i)))
- goto error0;
- /*
- * If none, then pick up the last entry in the tree unless the
- * tree is empty.
- */
- if (!i) {
- if ((error = xfs_alloc_ag_vextent_small(args, cnt_cur, &ltbno,
- &ltlen, &i)))
- goto error0;
- if (i == 0 || ltlen == 0) {
- xfs_btree_del_cursor(cnt_cur, XFS_BTREE_NOERROR);
- return 0;
- }
- ASSERT(i == 1);
- }
- args->wasfromfl = 0;
- /*
- * First algorithm.
- * If the requested extent is large wrt the freespaces available
- * in this a.g., then the cursor will be pointing to a btree entry
- * near the right edge of the tree. If it's in the last btree leaf
- * block, then we just examine all the entries in that block
- * that are big enough, and pick the best one.
- * This is written as a while loop so we can break out of it,
- * but we never loop back to the top.
- */
- while (xfs_btree_islastblock(cnt_cur, 0)) {
- xfs_extlen_t bdiff;
- int besti=0;
- xfs_extlen_t blen=0;
- xfs_agblock_t bnew=0;
-
-#if defined(DEBUG) && defined(__KERNEL__)
- if (!dofirst)
- break;
-#endif
- /*
- * Start from the entry that lookup found, sequence through
- * all larger free blocks. If we're actually pointing at a
- * record smaller than maxlen, go to the start of this block,
- * and skip all those smaller than minlen.
- */
- if (ltlen || args->alignment > 1) {
- cnt_cur->bc_ptrs[0] = 1;
- do {
- if ((error = xfs_alloc_get_rec(cnt_cur, &ltbno,
- &ltlen, &i)))
- goto error0;
- XFS_WANT_CORRUPTED_GOTO(i == 1, error0);
- if (ltlen >= args->minlen)
- break;
- if ((error = xfs_alloc_increment(cnt_cur, 0, &i)))
- goto error0;
- } while (i);
- ASSERT(ltlen >= args->minlen);
- if (!i)
- break;
- }
- i = cnt_cur->bc_ptrs[0];
- for (j = 1, blen = 0, bdiff = 0;
- !error && j && (blen < args->maxlen || bdiff > 0);
- error = xfs_alloc_increment(cnt_cur, 0, &j)) {
- /*
- * For each entry, decide if it's better than
- * the previous best entry.
- */
- if ((error = xfs_alloc_get_rec(cnt_cur, &ltbno, &ltlen, &i)))
- goto error0;
- XFS_WANT_CORRUPTED_GOTO(i == 1, error0);
- if (!xfs_alloc_compute_aligned(ltbno, ltlen,
- args->alignment, args->minlen,
- &ltbnoa, &ltlena))
- continue;
- args->len = XFS_EXTLEN_MIN(ltlena, args->maxlen);
- xfs_alloc_fix_len(args);
- ASSERT(args->len >= args->minlen);
- if (args->len < blen)
- continue;
- ltdiff = xfs_alloc_compute_diff(args->agbno, args->len,
- args->alignment, ltbno, ltlen, &ltnew);
- if (ltnew != NULLAGBLOCK &&
- (args->len > blen || ltdiff < bdiff)) {
- bdiff = ltdiff;
- bnew = ltnew;
- blen = args->len;
- besti = cnt_cur->bc_ptrs[0];
- }
- }
- /*
- * It didn't work. We COULD be in a case where
- * there's a good record somewhere, so try again.
- */
- if (blen == 0)
- break;
- /*
- * Point at the best entry, and retrieve it again.
- */
- cnt_cur->bc_ptrs[0] = besti;
- if ((error = xfs_alloc_get_rec(cnt_cur, &ltbno, &ltlen, &i)))
- goto error0;
- XFS_WANT_CORRUPTED_GOTO(i == 1, error0);
- ltend = ltbno + ltlen;
- ASSERT(ltend <= be32_to_cpu(XFS_BUF_TO_AGF(args->agbp)->agf_length));
- args->len = blen;
- if (!xfs_alloc_fix_minleft(args)) {
- xfs_btree_del_cursor(cnt_cur, XFS_BTREE_NOERROR);
- TRACE_ALLOC("nominleft", args);
- return 0;
- }
- blen = args->len;
- /*
- * We are allocating starting at bnew for blen blocks.
- */
- args->agbno = bnew;
- ASSERT(bnew >= ltbno);
- ASSERT(bnew + blen <= ltend);
- /*
- * Set up a cursor for the by-bno tree.
- */
- bno_cur_lt = xfs_btree_init_cursor(args->mp, args->tp,
- args->agbp, args->agno, XFS_BTNUM_BNO, NULL, 0);
- /*
- * Fix up the btree entries.
- */
- if ((error = xfs_alloc_fixup_trees(cnt_cur, bno_cur_lt, ltbno,
- ltlen, bnew, blen, XFSA_FIXUP_CNT_OK)))
- goto error0;
- xfs_btree_del_cursor(cnt_cur, XFS_BTREE_NOERROR);
- xfs_btree_del_cursor(bno_cur_lt, XFS_BTREE_NOERROR);
- TRACE_ALLOC("first", args);
- return 0;
- }
- /*
- * Second algorithm.
- * Search in the by-bno tree to the left and to the right
- * simultaneously, until in each case we find a space big enough,
- * or run into the edge of the tree. When we run into the edge,
- * we deallocate that cursor.
- * If both searches succeed, we compare the two spaces and pick
- * the better one.
- * With alignment, it's possible for both to fail; the upper
- * level algorithm that picks allocation groups for allocations
- * is not supposed to do this.
- */
- /*
- * Allocate and initialize the cursor for the leftward search.
- */
- bno_cur_lt = xfs_btree_init_cursor(args->mp, args->tp, args->agbp,
- args->agno, XFS_BTNUM_BNO, NULL, 0);
- /*
- * Lookup <= bno to find the leftward search's starting point.
- */
- if ((error = xfs_alloc_lookup_le(bno_cur_lt, args->agbno, args->maxlen, &i)))
- goto error0;
- if (!i) {
- /*
- * Didn't find anything; use this cursor for the rightward
- * search.
- */
- bno_cur_gt = bno_cur_lt;
- bno_cur_lt = NULL;
- }
- /*
- * Found something. Duplicate the cursor for the rightward search.
- */
- else if ((error = xfs_btree_dup_cursor(bno_cur_lt, &bno_cur_gt)))
- goto error0;
- /*
- * Increment the cursor, so we will point at the entry just right
- * of the leftward entry if any, or to the leftmost entry.
- */
- if ((error = xfs_alloc_increment(bno_cur_gt, 0, &i)))
- goto error0;
- if (!i) {
- /*
- * It failed, there are no rightward entries.
- */
- xfs_btree_del_cursor(bno_cur_gt, XFS_BTREE_NOERROR);
- bno_cur_gt = NULL;
- }
- /*
- * Loop going left with the leftward cursor, right with the
- * rightward cursor, until either both directions give up or
- * we find an entry at least as big as minlen.
- */
- do {
- if (bno_cur_lt) {
- if ((error = xfs_alloc_get_rec(bno_cur_lt, &ltbno, &ltlen, &i)))
- goto error0;
- XFS_WANT_CORRUPTED_GOTO(i == 1, error0);
- if (xfs_alloc_compute_aligned(ltbno, ltlen,
- args->alignment, args->minlen,
- &ltbnoa, &ltlena))
- break;
- if ((error = xfs_alloc_decrement(bno_cur_lt, 0, &i)))
- goto error0;
- if (!i) {
- xfs_btree_del_cursor(bno_cur_lt,
- XFS_BTREE_NOERROR);
- bno_cur_lt = NULL;
- }
- }
- if (bno_cur_gt) {
- if ((error = xfs_alloc_get_rec(bno_cur_gt, &gtbno, &gtlen, &i)))
- goto error0;
- XFS_WANT_CORRUPTED_GOTO(i == 1, error0);
- if (xfs_alloc_compute_aligned(gtbno, gtlen,
- args->alignment, args->minlen,
- &gtbnoa, &gtlena))
- break;
- if ((error = xfs_alloc_increment(bno_cur_gt, 0, &i)))
- goto error0;
- if (!i) {
- xfs_btree_del_cursor(bno_cur_gt,
- XFS_BTREE_NOERROR);
- bno_cur_gt = NULL;
- }
- }
- } while (bno_cur_lt || bno_cur_gt);
- /*
- * Got both cursors still active, need to find better entry.
- */
- if (bno_cur_lt && bno_cur_gt) {
- /*
- * Left side is long enough, look for a right side entry.
- */
- if (ltlena >= args->minlen) {
- /*
- * Fix up the length.
- */
- args->len = XFS_EXTLEN_MIN(ltlena, args->maxlen);
- xfs_alloc_fix_len(args);
- rlen = args->len;
- ltdiff = xfs_alloc_compute_diff(args->agbno, rlen,
- args->alignment, ltbno, ltlen, &ltnew);
- /*
- * Not perfect.
- */
- if (ltdiff) {
- /*
- * Look until we find a better one, run out of
- * space, or run off the end.
- */
- while (bno_cur_lt && bno_cur_gt) {
- if ((error = xfs_alloc_get_rec(
- bno_cur_gt, &gtbno,
- &gtlen, &i)))
- goto error0;
- XFS_WANT_CORRUPTED_GOTO(i == 1, error0);
- xfs_alloc_compute_aligned(gtbno, gtlen,
- args->alignment, args->minlen,
- &gtbnoa, &gtlena);
- /*
- * The left one is clearly better.
- */
- if (gtbnoa >= args->agbno + ltdiff) {
- xfs_btree_del_cursor(
- bno_cur_gt,
- XFS_BTREE_NOERROR);
- bno_cur_gt = NULL;
- break;
- }
- /*
- * If we reach a big enough entry,
- * compare the two and pick the best.
- */
- if (gtlena >= args->minlen) {
- args->len =
- XFS_EXTLEN_MIN(gtlena,
- args->maxlen);
- xfs_alloc_fix_len(args);
- rlen = args->len;
- gtdiff = xfs_alloc_compute_diff(
- args->agbno, rlen,
- args->alignment,
- gtbno, gtlen, &gtnew);
- /*
- * Right side is better.
- */
- if (gtdiff < ltdiff) {
- xfs_btree_del_cursor(
- bno_cur_lt,
- XFS_BTREE_NOERROR);
- bno_cur_lt = NULL;
- }
- /*
- * Left side is better.
- */
- else {
- xfs_btree_del_cursor(
- bno_cur_gt,
- XFS_BTREE_NOERROR);
- bno_cur_gt = NULL;
- }
- break;
- }
- /*
- * Fell off the right end.
- */
- if ((error = xfs_alloc_increment(
- bno_cur_gt, 0, &i)))
- goto error0;
- if (!i) {
- xfs_btree_del_cursor(
- bno_cur_gt,
- XFS_BTREE_NOERROR);
- bno_cur_gt = NULL;
- break;
- }
- }
- }
- /*
- * The left side is perfect, trash the right side.
- */
- else {
- xfs_btree_del_cursor(bno_cur_gt,
- XFS_BTREE_NOERROR);
- bno_cur_gt = NULL;
- }
- }
- /*
- * It's the right side that was found first, look left.
- */
- else {
- /*
- * Fix up the length.
- */
- args->len = XFS_EXTLEN_MIN(gtlena, args->maxlen);
- xfs_alloc_fix_len(args);
- rlen = args->len;
- gtdiff = xfs_alloc_compute_diff(args->agbno, rlen,
- args->alignment, gtbno, gtlen, &gtnew);
- /*
- * Right side entry isn't perfect.
- */
- if (gtdiff) {
- /*
- * Look until we find a better one, run out of
- * space, or run off the end.
- */
- while (bno_cur_lt && bno_cur_gt) {
- if ((error = xfs_alloc_get_rec(
- bno_cur_lt, &ltbno,
- &ltlen, &i)))
- goto error0;
- XFS_WANT_CORRUPTED_GOTO(i == 1, error0);
- xfs_alloc_compute_aligned(ltbno, ltlen,
- args->alignment, args->minlen,
- &ltbnoa, &ltlena);
- /*
- * The right one is clearly better.
- */
- if (ltbnoa <= args->agbno - gtdiff) {
- xfs_btree_del_cursor(
- bno_cur_lt,
- XFS_BTREE_NOERROR);
- bno_cur_lt = NULL;
- break;
- }
- /*
- * If we reach a big enough entry,
- * compare the two and pick the best.
- */
- if (ltlena >= args->minlen) {
- args->len = XFS_EXTLEN_MIN(
- ltlena, args->maxlen);
- xfs_alloc_fix_len(args);
- rlen = args->len;
- ltdiff = xfs_alloc_compute_diff(
- args->agbno, rlen,
- args->alignment,
- ltbno, ltlen, &ltnew);
- /*
- * Left side is better.
- */
- if (ltdiff < gtdiff) {
- xfs_btree_del_cursor(
- bno_cur_gt,
- XFS_BTREE_NOERROR);
- bno_cur_gt = NULL;
- }
- /*
- * Right side is better.
- */
- else {
- xfs_btree_del_cursor(
- bno_cur_lt,
- XFS_BTREE_NOERROR);
- bno_cur_lt = NULL;
- }
- break;
- }
- /*
- * Fell off the left end.
- */
- if ((error = xfs_alloc_decrement(
- bno_cur_lt, 0, &i)))
- goto error0;
- if (!i) {
- xfs_btree_del_cursor(bno_cur_lt,
- XFS_BTREE_NOERROR);
- bno_cur_lt = NULL;
- break;
- }
- }
- }
- /*
- * The right side is perfect, trash the left side.
- */
- else {
- xfs_btree_del_cursor(bno_cur_lt,
- XFS_BTREE_NOERROR);
- bno_cur_lt = NULL;
- }
- }
- }
- /*
- * If we couldn't get anything, give up.
- */
- if (bno_cur_lt == NULL && bno_cur_gt == NULL) {
- TRACE_ALLOC("neither", args);
- args->agbno = NULLAGBLOCK;
- return 0;
- }
- /*
- * At this point we have selected a freespace entry, either to the
- * left or to the right. If it's on the right, copy all the
- * useful variables to the "left" set so we only have one
- * copy of this code.
- */
- if (bno_cur_gt) {
- bno_cur_lt = bno_cur_gt;
- bno_cur_gt = NULL;
- ltbno = gtbno;
- ltbnoa = gtbnoa;
- ltlen = gtlen;
- ltlena = gtlena;
- j = 1;
- } else
- j = 0;
- /*
- * Fix up the length and compute the useful address.
- */
- ltend = ltbno + ltlen;
- args->len = XFS_EXTLEN_MIN(ltlena, args->maxlen);
- xfs_alloc_fix_len(args);
- if (!xfs_alloc_fix_minleft(args)) {
- TRACE_ALLOC("nominleft", args);
- xfs_btree_del_cursor(bno_cur_lt, XFS_BTREE_NOERROR);
- xfs_btree_del_cursor(cnt_cur, XFS_BTREE_NOERROR);
- return 0;
- }
- rlen = args->len;
- (void)xfs_alloc_compute_diff(args->agbno, rlen, args->alignment, ltbno,
- ltlen, &ltnew);
- ASSERT(ltnew >= ltbno);
- ASSERT(ltnew + rlen <= ltend);
- ASSERT(ltnew + rlen <= be32_to_cpu(XFS_BUF_TO_AGF(args->agbp)->agf_length));
- args->agbno = ltnew;
- if ((error = xfs_alloc_fixup_trees(cnt_cur, bno_cur_lt, ltbno, ltlen,
- ltnew, rlen, XFSA_FIXUP_BNO_OK)))
- goto error0;
- TRACE_ALLOC(j ? "gt" : "lt", args);
- xfs_btree_del_cursor(cnt_cur, XFS_BTREE_NOERROR);
- xfs_btree_del_cursor(bno_cur_lt, XFS_BTREE_NOERROR);
- return 0;
-
- error0:
- TRACE_ALLOC("error", args);
- if (cnt_cur != NULL)
- xfs_btree_del_cursor(cnt_cur, XFS_BTREE_ERROR);
- if (bno_cur_lt != NULL)
- xfs_btree_del_cursor(bno_cur_lt, XFS_BTREE_ERROR);
- if (bno_cur_gt != NULL)
- xfs_btree_del_cursor(bno_cur_gt, XFS_BTREE_ERROR);
- return error;
-}
-
-/*
- * Allocate a variable extent anywhere in the allocation group agno.
- * Extent's length (returned in len) will be between minlen and maxlen,
- * and of the form k * prod + mod unless there's nothing that large.
- * Return the starting a.g. block, or NULLAGBLOCK if we can't do it.
- */
-STATIC int /* error */
-xfs_alloc_ag_vextent_size(
- xfs_alloc_arg_t *args) /* allocation argument structure */
-{
- xfs_btree_cur_t *bno_cur; /* cursor for bno btree */
- xfs_btree_cur_t *cnt_cur; /* cursor for cnt btree */
- int error; /* error result */
- xfs_agblock_t fbno; /* start of found freespace */
- xfs_extlen_t flen; /* length of found freespace */
-#ifdef XFS_ALLOC_TRACE
- static char fname[] = "xfs_alloc_ag_vextent_size";
-#endif
- int i; /* temp status variable */
- xfs_agblock_t rbno; /* returned block number */
- xfs_extlen_t rlen; /* length of returned extent */
-
- /*
- * Allocate and initialize a cursor for the by-size btree.
- */
- cnt_cur = xfs_btree_init_cursor(args->mp, args->tp, args->agbp,
- args->agno, XFS_BTNUM_CNT, NULL, 0);
- bno_cur = NULL;
- /*
- * Look for an entry >= maxlen+alignment-1 blocks.
- */
- if ((error = xfs_alloc_lookup_ge(cnt_cur, 0,
- args->maxlen + args->alignment - 1, &i)))
- goto error0;
- /*
- * If none, then pick up the last entry in the tree unless the
- * tree is empty.
- */
- if (!i) {
- if ((error = xfs_alloc_ag_vextent_small(args, cnt_cur, &fbno,
- &flen, &i)))
- goto error0;
- if (i == 0 || flen == 0) {
- xfs_btree_del_cursor(cnt_cur, XFS_BTREE_NOERROR);
- TRACE_ALLOC("noentry", args);
- return 0;
- }
- ASSERT(i == 1);
- }
- /*
- * There's a freespace as big as maxlen+alignment-1, get it.
- */
- else {
- if ((error = xfs_alloc_get_rec(cnt_cur, &fbno, &flen, &i)))
- goto error0;
- XFS_WANT_CORRUPTED_GOTO(i == 1, error0);
- }
- /*
- * In the first case above, we got the last entry in the
- * by-size btree. Now we check to see if the space hits maxlen
- * once aligned; if not, we search left for something better.
- * This can't happen in the second case above.
- */
- xfs_alloc_compute_aligned(fbno, flen, args->alignment, args->minlen,
- &rbno, &rlen);
- rlen = XFS_EXTLEN_MIN(args->maxlen, rlen);
- XFS_WANT_CORRUPTED_GOTO(rlen == 0 ||
- (rlen <= flen && rbno + rlen <= fbno + flen), error0);
- if (rlen < args->maxlen) {
- xfs_agblock_t bestfbno;
- xfs_extlen_t bestflen;
- xfs_agblock_t bestrbno;
- xfs_extlen_t bestrlen;
-
- bestrlen = rlen;
- bestrbno = rbno;
- bestflen = flen;
- bestfbno = fbno;
- for (;;) {
- if ((error = xfs_alloc_decrement(cnt_cur, 0, &i)))
- goto error0;
- if (i == 0)
- break;
- if ((error = xfs_alloc_get_rec(cnt_cur, &fbno, &flen,
- &i)))
- goto error0;
- XFS_WANT_CORRUPTED_GOTO(i == 1, error0);
- if (flen < bestrlen)
- break;
- xfs_alloc_compute_aligned(fbno, flen, args->alignment,
- args->minlen, &rbno, &rlen);
- rlen = XFS_EXTLEN_MIN(args->maxlen, rlen);
- XFS_WANT_CORRUPTED_GOTO(rlen == 0 ||
- (rlen <= flen && rbno + rlen <= fbno + flen),
- error0);
- if (rlen > bestrlen) {
- bestrlen = rlen;
- bestrbno = rbno;
- bestflen = flen;
- bestfbno = fbno;
- if (rlen == args->maxlen)
- break;
- }
- }
- if ((error = xfs_alloc_lookup_eq(cnt_cur, bestfbno, bestflen,
- &i)))
- goto error0;
- XFS_WANT_CORRUPTED_GOTO(i == 1, error0);
- rlen = bestrlen;
- rbno = bestrbno;
- flen = bestflen;
- fbno = bestfbno;
- }
- args->wasfromfl = 0;
- /*
- * Fix up the length.
- */
- args->len = rlen;
- xfs_alloc_fix_len(args);
- if (rlen < args->minlen || !xfs_alloc_fix_minleft(args)) {
- xfs_btree_del_cursor(cnt_cur, XFS_BTREE_NOERROR);
- TRACE_ALLOC("nominleft", args);
- args->agbno = NULLAGBLOCK;
- return 0;
- }
- rlen = args->len;
- XFS_WANT_CORRUPTED_GOTO(rlen <= flen, error0);
- /*
- * Allocate and initialize a cursor for the by-block tree.
- */
- bno_cur = xfs_btree_init_cursor(args->mp, args->tp, args->agbp,
- args->agno, XFS_BTNUM_BNO, NULL, 0);
- if ((error = xfs_alloc_fixup_trees(cnt_cur, bno_cur, fbno, flen,
- rbno, rlen, XFSA_FIXUP_CNT_OK)))
- goto error0;
- xfs_btree_del_cursor(cnt_cur, XFS_BTREE_NOERROR);
- xfs_btree_del_cursor(bno_cur, XFS_BTREE_NOERROR);
- cnt_cur = bno_cur = NULL;
- args->len = rlen;
- args->agbno = rbno;
- XFS_WANT_CORRUPTED_GOTO(
- args->agbno + args->len <=
- be32_to_cpu(XFS_BUF_TO_AGF(args->agbp)->agf_length),
- error0);
- TRACE_ALLOC("normal", args);
- return 0;
-
-error0:
- TRACE_ALLOC("error", args);
- if (cnt_cur)
- xfs_btree_del_cursor(cnt_cur, XFS_BTREE_ERROR);
- if (bno_cur)
- xfs_btree_del_cursor(bno_cur, XFS_BTREE_ERROR);
- return error;
-}
-
-/*
- * Deal with the case where only small freespaces remain.
- * Either return the contents of the last freespace record,
- * or allocate space from the freelist if there is nothing in the tree.
- */
-STATIC int /* error */
-xfs_alloc_ag_vextent_small(
- xfs_alloc_arg_t *args, /* allocation argument structure */
- xfs_btree_cur_t *ccur, /* by-size cursor */
- xfs_agblock_t *fbnop, /* result block number */
- xfs_extlen_t *flenp, /* result length */
- int *stat) /* status: 0-freelist, 1-normal/none */
-{
- int error;
- xfs_agblock_t fbno;
- xfs_extlen_t flen;
-#ifdef XFS_ALLOC_TRACE
- static char fname[] = "xfs_alloc_ag_vextent_small";
-#endif
- int i;
-
- if ((error = xfs_alloc_decrement(ccur, 0, &i)))
- goto error0;
- if (i) {
- if ((error = xfs_alloc_get_rec(ccur, &fbno, &flen, &i)))
- goto error0;
- XFS_WANT_CORRUPTED_GOTO(i == 1, error0);
- }
- /*
- * Nothing in the btree, try the freelist. Make sure
- * to respect minleft even when pulling from the
- * freelist.
- */
- else if (args->minlen == 1 && args->alignment == 1 && !args->isfl &&
- (be32_to_cpu(XFS_BUF_TO_AGF(args->agbp)->agf_flcount)
- > args->minleft)) {
- if ((error = xfs_alloc_get_freelist(args->tp, args->agbp, &fbno)))
- goto error0;
- if (fbno != NULLAGBLOCK) {
- if (args->userdata) {
- xfs_buf_t *bp;
-
- bp = xfs_btree_get_bufs(args->mp, args->tp,
- args->agno, fbno, 0);
- xfs_trans_binval(args->tp, bp);
- }
- args->len = 1;
- args->agbno = fbno;
- XFS_WANT_CORRUPTED_GOTO(
- args->agbno + args->len <=
- be32_to_cpu(XFS_BUF_TO_AGF(args->agbp)->agf_length),
- error0);
- args->wasfromfl = 1;
- TRACE_ALLOC("freelist", args);
- *stat = 0;
- return 0;
- }
- /*
- * Nothing in the freelist.
- */
- else
- flen = 0;
- }
- /*
- * Can't allocate from the freelist for some reason.
- */
- else {
- fbno = NULLAGBLOCK;
- flen = 0;
- }
- /*
- * Can't do the allocation, give up.
- */
- if (flen < args->minlen) {
- args->agbno = NULLAGBLOCK;
- TRACE_ALLOC("notenough", args);
- flen = 0;
- }
- *fbnop = fbno;
- *flenp = flen;
- *stat = 1;
- TRACE_ALLOC("normal", args);
- return 0;
-
-error0:
- TRACE_ALLOC("error", args);
- return error;
-}
-
-/*
- * Free the extent starting at agno/bno for length.
- */
-STATIC int /* error */
-xfs_free_ag_extent(
- xfs_trans_t *tp, /* transaction pointer */
- xfs_buf_t *agbp, /* buffer for a.g. freelist header */
- xfs_agnumber_t agno, /* allocation group number */
- xfs_agblock_t bno, /* starting block number */
- xfs_extlen_t len, /* length of extent */
- int isfl) /* set if is freelist blocks - no sb acctg */
-{
- xfs_btree_cur_t *bno_cur; /* cursor for by-block btree */
- xfs_btree_cur_t *cnt_cur; /* cursor for by-size btree */
- int error; /* error return value */
-#ifdef XFS_ALLOC_TRACE
- static char fname[] = "xfs_free_ag_extent";
-#endif
- xfs_agblock_t gtbno; /* start of right neighbor block */
- xfs_extlen_t gtlen; /* length of right neighbor block */
- int haveleft; /* have a left neighbor block */
- int haveright; /* have a right neighbor block */
- int i; /* temp, result code */
- xfs_agblock_t ltbno; /* start of left neighbor block */
- xfs_extlen_t ltlen; /* length of left neighbor block */
- xfs_mount_t *mp; /* mount point struct for filesystem */
- xfs_agblock_t nbno; /* new starting block of freespace */
- xfs_extlen_t nlen; /* new length of freespace */
-
- mp = tp->t_mountp;
- /*
- * Allocate and initialize a cursor for the by-block btree.
- */
- bno_cur = xfs_btree_init_cursor(mp, tp, agbp, agno, XFS_BTNUM_BNO, NULL,
- 0);
- cnt_cur = NULL;
- /*
- * Look for a neighboring block on the left (lower block numbers)
- * that is contiguous with this space.
- */
- if ((error = xfs_alloc_lookup_le(bno_cur, bno, len, &haveleft)))
- goto error0;
- if (haveleft) {
- /*
- * There is a block to our left.
- */
- if ((error = xfs_alloc_get_rec(bno_cur, &ltbno, &ltlen, &i)))
- goto error0;
- XFS_WANT_CORRUPTED_GOTO(i == 1, error0);
- /*
- * It's not contiguous, though.
- */
- if (ltbno + ltlen < bno)
- haveleft = 0;
- else {
- /*
- * If this failure happens the request to free this
- * space was invalid, it's (partly) already free.
- * Very bad.
- */
- XFS_WANT_CORRUPTED_GOTO(ltbno + ltlen <= bno, error0);
- }
- }
- /*
- * Look for a neighboring block on the right (higher block numbers)
- * that is contiguous with this space.
- */
- if ((error = xfs_alloc_increment(bno_cur, 0, &haveright)))
- goto error0;
- if (haveright) {
- /*
- * There is a block to our right.
- */
- if ((error = xfs_alloc_get_rec(bno_cur, &gtbno, &gtlen, &i)))
- goto error0;
- XFS_WANT_CORRUPTED_GOTO(i == 1, error0);
- /*
- * It's not contiguous, though.
- */
- if (bno + len < gtbno)
- haveright = 0;
- else {
- /*
- * If this failure happens the request to free this
- * space was invalid, it's (partly) already free.
- * Very bad.
- */
- XFS_WANT_CORRUPTED_GOTO(gtbno >= bno + len, error0);
- }
- }
- /*
- * Now allocate and initialize a cursor for the by-size tree.
- */
- cnt_cur = xfs_btree_init_cursor(mp, tp, agbp, agno, XFS_BTNUM_CNT, NULL,
- 0);
- /*
- * Have both left and right contiguous neighbors.
- * Merge all three into a single free block.
- */
- if (haveleft && haveright) {
- /*
- * Delete the old by-size entry on the left.
- */
- if ((error = xfs_alloc_lookup_eq(cnt_cur, ltbno, ltlen, &i)))
- goto error0;
- XFS_WANT_CORRUPTED_GOTO(i == 1, error0);
- if ((error = xfs_alloc_delete(cnt_cur, &i)))
- goto error0;
- XFS_WANT_CORRUPTED_GOTO(i == 1, error0);
- /*
- * Delete the old by-size entry on the right.
- */
- if ((error = xfs_alloc_lookup_eq(cnt_cur, gtbno, gtlen, &i)))
- goto error0;
- XFS_WANT_CORRUPTED_GOTO(i == 1, error0);
- if ((error = xfs_alloc_delete(cnt_cur, &i)))
- goto error0;
- XFS_WANT_CORRUPTED_GOTO(i == 1, error0);
- /*
- * Delete the old by-block entry for the right block.
- */
- if ((error = xfs_alloc_delete(bno_cur, &i)))
- goto error0;
- XFS_WANT_CORRUPTED_GOTO(i == 1, error0);
- /*
- * Move the by-block cursor back to the left neighbor.
- */
- if ((error = xfs_alloc_decrement(bno_cur, 0, &i)))
- goto error0;
- XFS_WANT_CORRUPTED_GOTO(i == 1, error0);
-#ifdef DEBUG
- /*
- * Check that this is the right record: delete didn't
- * mangle the cursor.
- */
- {
- xfs_agblock_t xxbno;
- xfs_extlen_t xxlen;
-
- if ((error = xfs_alloc_get_rec(bno_cur, &xxbno, &xxlen,
- &i)))
- goto error0;
- XFS_WANT_CORRUPTED_GOTO(
- i == 1 && xxbno == ltbno && xxlen == ltlen,
- error0);
- }
-#endif
- /*
- * Update remaining by-block entry to the new, joined block.
- */
- nbno = ltbno;
- nlen = len + ltlen + gtlen;
- if ((error = xfs_alloc_update(bno_cur, nbno, nlen)))
- goto error0;
- }
- /*
- * Have only a left contiguous neighbor.
- * Merge it together with the new freespace.
- */
- else if (haveleft) {
- /*
- * Delete the old by-size entry on the left.
- */
- if ((error = xfs_alloc_lookup_eq(cnt_cur, ltbno, ltlen, &i)))
- goto error0;
- XFS_WANT_CORRUPTED_GOTO(i == 1, error0);
- if ((error = xfs_alloc_delete(cnt_cur, &i)))
- goto error0;
- XFS_WANT_CORRUPTED_GOTO(i == 1, error0);
- /*
- * Back up the by-block cursor to the left neighbor, and
- * update its length.
- */
- if ((error = xfs_alloc_decrement(bno_cur, 0, &i)))
- goto error0;
- XFS_WANT_CORRUPTED_GOTO(i == 1, error0);
- nbno = ltbno;
- nlen = len + ltlen;
- if ((error = xfs_alloc_update(bno_cur, nbno, nlen)))
- goto error0;
- }
- /*
- * Have only a right contiguous neighbor.
- * Merge it together with the new freespace.
- */
- else if (haveright) {
- /*
- * Delete the old by-size entry on the right.
- */
- if ((error = xfs_alloc_lookup_eq(cnt_cur, gtbno, gtlen, &i)))
- goto error0;
- XFS_WANT_CORRUPTED_GOTO(i == 1, error0);
- if ((error = xfs_alloc_delete(cnt_cur, &i)))
- goto error0;
- XFS_WANT_CORRUPTED_GOTO(i == 1, error0);
- /*
- * Update the starting block and length of the right
- * neighbor in the by-block tree.
- */
- nbno = bno;
- nlen = len + gtlen;
- if ((error = xfs_alloc_update(bno_cur, nbno, nlen)))
- goto error0;
- }
- /*
- * No contiguous neighbors.
- * Insert the new freespace into the by-block tree.
- */
- else {
- nbno = bno;
- nlen = len;
- if ((error = xfs_alloc_insert(bno_cur, &i)))
- goto error0;
- XFS_WANT_CORRUPTED_GOTO(i == 1, error0);
- }
- xfs_btree_del_cursor(bno_cur, XFS_BTREE_NOERROR);
- bno_cur = NULL;
- /*
- * In all cases we need to insert the new freespace in the by-size tree.
- */
- if ((error = xfs_alloc_lookup_eq(cnt_cur, nbno, nlen, &i)))
- goto error0;
- XFS_WANT_CORRUPTED_GOTO(i == 0, error0);
- if ((error = xfs_alloc_insert(cnt_cur, &i)))
- goto error0;
- XFS_WANT_CORRUPTED_GOTO(i == 1, error0);
- xfs_btree_del_cursor(cnt_cur, XFS_BTREE_NOERROR);
- cnt_cur = NULL;
- /*
- * Update the freespace totals in the ag and superblock.
- */
- {
- xfs_agf_t *agf;
- xfs_perag_t *pag; /* per allocation group data */
-
- agf = XFS_BUF_TO_AGF(agbp);
- pag = &mp->m_perag[agno];
- be32_add(&agf->agf_freeblks, len);
- xfs_trans_agblocks_delta(tp, len);
- pag->pagf_freeblks += len;
- XFS_WANT_CORRUPTED_GOTO(
- be32_to_cpu(agf->agf_freeblks) <=
- be32_to_cpu(agf->agf_length),
- error0);
- TRACE_MODAGF(NULL, agf, XFS_AGF_FREEBLKS);
- xfs_alloc_log_agf(tp, agbp, XFS_AGF_FREEBLKS);
- if (!isfl)
- xfs_trans_mod_sb(tp, XFS_TRANS_SB_FDBLOCKS, (long)len);
- XFS_STATS_INC(xs_freex);
- XFS_STATS_ADD(xs_freeb, len);
- }
- TRACE_FREE(haveleft ?
- (haveright ? "both" : "left") :
- (haveright ? "right" : "none"),
- agno, bno, len, isfl);
-
- /*
- * Since blocks move to the free list without the coordination
- * used in xfs_bmap_finish, we can't allow block to be available
- * for reallocation and non-transaction writing (user data)
- * until we know that the transaction that moved it to the free
- * list is permanently on disk. We track the blocks by declaring
- * these blocks as "busy"; the busy list is maintained on a per-ag
- * basis and each transaction records which entries should be removed
- * when the iclog commits to disk. If a busy block is allocated,
- * the iclog is pushed up to the LSN that freed the block.
- */
- xfs_alloc_mark_busy(tp, agno, bno, len);
- return 0;
-
- error0:
- TRACE_FREE("error", agno, bno, len, isfl);
- if (bno_cur)
- xfs_btree_del_cursor(bno_cur, XFS_BTREE_ERROR);
- if (cnt_cur)
- xfs_btree_del_cursor(cnt_cur, XFS_BTREE_ERROR);
- return error;
-}
-
-/*
- * Visible (exported) allocation/free functions.
- * Some of these are used just by xfs_alloc_btree.c and this file.
- */
-
-/*
- * Compute and fill in value of m_ag_maxlevels.
- */
-void
-xfs_alloc_compute_maxlevels(
- xfs_mount_t *mp) /* file system mount structure */
-{
- int level;
- uint maxblocks;
- uint maxleafents;
- int minleafrecs;
- int minnoderecs;
-
- maxleafents = (mp->m_sb.sb_agblocks + 1) / 2;
- minleafrecs = mp->m_alloc_mnr[0];
- minnoderecs = mp->m_alloc_mnr[1];
- maxblocks = (maxleafents + minleafrecs - 1) / minleafrecs;
- for (level = 1; maxblocks > 1; level++)
- maxblocks = (maxblocks + minnoderecs - 1) / minnoderecs;
- mp->m_ag_maxlevels = level;
-}
-
-/*
- * Decide whether to use this allocation group for this allocation.
- * If so, fix up the btree freelist's size.
- */
-STATIC int /* error */
-xfs_alloc_fix_freelist(
- xfs_alloc_arg_t *args, /* allocation argument structure */
- int flags) /* XFS_ALLOC_FLAG_... */
-{
- xfs_buf_t *agbp; /* agf buffer pointer */
- xfs_agf_t *agf; /* a.g. freespace structure pointer */
- xfs_buf_t *agflbp;/* agfl buffer pointer */
- xfs_agblock_t bno; /* freelist block */
- xfs_extlen_t delta; /* new blocks needed in freelist */
- int error; /* error result code */
- xfs_extlen_t longest;/* longest extent in allocation group */
- xfs_mount_t *mp; /* file system mount point structure */
- xfs_extlen_t need; /* total blocks needed in freelist */
- xfs_perag_t *pag; /* per-ag information structure */
- xfs_alloc_arg_t targs; /* local allocation arguments */
- xfs_trans_t *tp; /* transaction pointer */
-
- mp = args->mp;
-
- pag = args->pag;
- tp = args->tp;
- if (!pag->pagf_init) {
- if ((error = xfs_alloc_read_agf(mp, tp, args->agno, flags,
- &agbp)))
- return error;
- if (!pag->pagf_init) {
- args->agbp = NULL;
- return 0;
- }
- } else
- agbp = NULL;
-
- /* If this is a metadata preferred pag and we are user data
- * then try somewhere else if we are not being asked to
- * try harder at this point
- */
- if (pag->pagf_metadata && args->userdata && flags) {
- args->agbp = NULL;
- return 0;
- }
-
- need = XFS_MIN_FREELIST_PAG(pag, mp);
- delta = need > pag->pagf_flcount ? need - pag->pagf_flcount : 0;
- /*
- * If it looks like there isn't a long enough extent, or enough
- * total blocks, reject it.
- */
- longest = (pag->pagf_longest > delta) ?
- (pag->pagf_longest - delta) :
- (pag->pagf_flcount > 0 || pag->pagf_longest > 0);
- if (args->minlen + args->alignment + args->minalignslop - 1 > longest ||
- (args->minleft &&
- (int)(pag->pagf_freeblks + pag->pagf_flcount -
- need - args->total) <
- (int)args->minleft)) {
- if (agbp)
- xfs_trans_brelse(tp, agbp);
- args->agbp = NULL;
- return 0;
- }
- /*
- * Get the a.g. freespace buffer.
- * Can fail if we're not blocking on locks, and it's held.
- */
- if (agbp == NULL) {
- if ((error = xfs_alloc_read_agf(mp, tp, args->agno, flags,
- &agbp)))
- return error;
- if (agbp == NULL) {
- args->agbp = NULL;
- return 0;
- }
- }
- /*
- * Figure out how many blocks we should have in the freelist.
- */
- agf = XFS_BUF_TO_AGF(agbp);
- need = XFS_MIN_FREELIST(agf, mp);
- delta = need > be32_to_cpu(agf->agf_flcount) ?
- (need - be32_to_cpu(agf->agf_flcount)) : 0;
- /*
- * If there isn't enough total or single-extent, reject it.
- */
- longest = be32_to_cpu(agf->agf_longest);
- longest = (longest > delta) ? (longest - delta) :
- (be32_to_cpu(agf->agf_flcount) > 0 || longest > 0);
- if (args->minlen + args->alignment + args->minalignslop - 1 > longest ||
- (args->minleft &&
- (int)(be32_to_cpu(agf->agf_freeblks) +
- be32_to_cpu(agf->agf_flcount) - need - args->total) <
- (int)args->minleft)) {
- xfs_trans_brelse(tp, agbp);
- args->agbp = NULL;
- return 0;
- }
- /*
- * Make the freelist shorter if it's too long.
- */
- while (be32_to_cpu(agf->agf_flcount) > need) {
- xfs_buf_t *bp;
-
- if ((error = xfs_alloc_get_freelist(tp, agbp, &bno)))
- return error;
- if ((error = xfs_free_ag_extent(tp, agbp, args->agno, bno, 1, 1)))
- return error;
- bp = xfs_btree_get_bufs(mp, tp, args->agno, bno, 0);
- xfs_trans_binval(tp, bp);
- }
- /*
- * Initialize the args structure.
- */
- targs.tp = tp;
- targs.mp = mp;
- targs.agbp = agbp;
- targs.agno = args->agno;
- targs.mod = targs.minleft = targs.wasdel = targs.userdata =
- targs.minalignslop = 0;
- targs.alignment = targs.minlen = targs.prod = targs.isfl = 1;
- targs.type = XFS_ALLOCTYPE_THIS_AG;
- targs.pag = pag;
- if ((error = xfs_alloc_read_agfl(mp, tp, targs.agno, &agflbp)))
- return error;
- /*
- * Make the freelist longer if it's too short.
- */
- while (be32_to_cpu(agf->agf_flcount) < need) {
- targs.agbno = 0;
- targs.maxlen = need - be32_to_cpu(agf->agf_flcount);
- /*
- * Allocate as many blocks as possible at once.
- */
- if ((error = xfs_alloc_ag_vextent(&targs)))
- return error;
- /*
- * Stop if we run out. Won't happen if callers are obeying
- * the restrictions correctly. Can happen for free calls
- * on a completely full ag.
- */
- if (targs.agbno == NULLAGBLOCK)
- break;
- /*
- * Put each allocated block on the list.
- */
- for (bno = targs.agbno; bno < targs.agbno + targs.len; bno++) {
- if ((error = xfs_alloc_put_freelist(tp, agbp, agflbp,
- bno)))
- return error;
- }
- }
- args->agbp = agbp;
- return 0;
-}
-
-/*
- * Get a block from the freelist.
- * Returns with the buffer for the block gotten.
- */
-int /* error */
-xfs_alloc_get_freelist(
- xfs_trans_t *tp, /* transaction pointer */
- xfs_buf_t *agbp, /* buffer containing the agf structure */
- xfs_agblock_t *bnop) /* block address retrieved from freelist */
-{
- xfs_agf_t *agf; /* a.g. freespace structure */
- xfs_agfl_t *agfl; /* a.g. freelist structure */
- xfs_buf_t *agflbp;/* buffer for a.g. freelist structure */
- xfs_agblock_t bno; /* block number returned */
- int error;
-#ifdef XFS_ALLOC_TRACE
- static char fname[] = "xfs_alloc_get_freelist";
-#endif
- xfs_mount_t *mp; /* mount structure */
- xfs_perag_t *pag; /* per allocation group data */
-
- agf = XFS_BUF_TO_AGF(agbp);
- /*
- * Freelist is empty, give up.
- */
- if (!agf->agf_flcount) {
- *bnop = NULLAGBLOCK;
- return 0;
- }
- /*
- * Read the array of free blocks.
- */
- mp = tp->t_mountp;
- if ((error = xfs_alloc_read_agfl(mp, tp,
- be32_to_cpu(agf->agf_seqno), &agflbp)))
- return error;
- agfl = XFS_BUF_TO_AGFL(agflbp);
- /*
- * Get the block number and update the data structures.
- */
- bno = INT_GET(agfl->agfl_bno[be32_to_cpu(agf->agf_flfirst)], ARCH_CONVERT);
- be32_add(&agf->agf_flfirst, 1);
- xfs_trans_brelse(tp, agflbp);
- if (be32_to_cpu(agf->agf_flfirst) == XFS_AGFL_SIZE(mp))
- agf->agf_flfirst = 0;
- pag = &mp->m_perag[be32_to_cpu(agf->agf_seqno)];
- be32_add(&agf->agf_flcount, -1);
- xfs_trans_agflist_delta(tp, -1);
- pag->pagf_flcount--;
- TRACE_MODAGF(NULL, agf, XFS_AGF_FLFIRST | XFS_AGF_FLCOUNT);
- xfs_alloc_log_agf(tp, agbp, XFS_AGF_FLFIRST | XFS_AGF_FLCOUNT);
- *bnop = bno;
-
- /*
- * As blocks are freed, they are added to the per-ag busy list
- * and remain there until the freeing transaction is committed to
- * disk. Now that we have allocated blocks, this list must be
- * searched to see if a block is being reused. If one is, then
- * the freeing transaction must be pushed to disk NOW by forcing
- * to disk all iclogs up that transaction's LSN.
- */
- xfs_alloc_search_busy(tp, be32_to_cpu(agf->agf_seqno), bno, 1);
- return 0;
-}
-
-/*
- * Log the given fields from the agf structure.
- */
-void
-xfs_alloc_log_agf(
- xfs_trans_t *tp, /* transaction pointer */
- xfs_buf_t *bp, /* buffer for a.g. freelist header */
- int fields) /* mask of fields to be logged (XFS_AGF_...) */
-{
- int first; /* first byte offset */
- int last; /* last byte offset */
- static const short offsets[] = {
- offsetof(xfs_agf_t, agf_magicnum),
- offsetof(xfs_agf_t, agf_versionnum),
- offsetof(xfs_agf_t, agf_seqno),
- offsetof(xfs_agf_t, agf_length),
- offsetof(xfs_agf_t, agf_roots[0]),
- offsetof(xfs_agf_t, agf_levels[0]),
- offsetof(xfs_agf_t, agf_flfirst),
- offsetof(xfs_agf_t, agf_fllast),
- offsetof(xfs_agf_t, agf_flcount),
- offsetof(xfs_agf_t, agf_freeblks),
- offsetof(xfs_agf_t, agf_longest),
- sizeof(xfs_agf_t)
- };
-
- xfs_btree_offsets(fields, offsets, XFS_AGF_NUM_BITS, &first, &last);
- xfs_trans_log_buf(tp, bp, (uint)first, (uint)last);
-}
-
-/*
- * Interface for inode allocation to force the pag data to be initialized.
- */
-int /* error */
-xfs_alloc_pagf_init(
- xfs_mount_t *mp, /* file system mount structure */
- xfs_trans_t *tp, /* transaction pointer */
- xfs_agnumber_t agno, /* allocation group number */
- int flags) /* XFS_ALLOC_FLAGS_... */
-{
- xfs_buf_t *bp;
- int error;
-
- if ((error = xfs_alloc_read_agf(mp, tp, agno, flags, &bp)))
- return error;
- if (bp)
- xfs_trans_brelse(tp, bp);
- return 0;
-}
-
-/*
- * Put the block on the freelist for the allocation group.
- */
-int /* error */
-xfs_alloc_put_freelist(
- xfs_trans_t *tp, /* transaction pointer */
- xfs_buf_t *agbp, /* buffer for a.g. freelist header */
- xfs_buf_t *agflbp,/* buffer for a.g. free block array */
- xfs_agblock_t bno) /* block being freed */
-{
- xfs_agf_t *agf; /* a.g. freespace structure */
- xfs_agfl_t *agfl; /* a.g. free block array */
- xfs_agblock_t *blockp;/* pointer to array entry */
- int error;
-#ifdef XFS_ALLOC_TRACE
- static char fname[] = "xfs_alloc_put_freelist";
-#endif
- xfs_mount_t *mp; /* mount structure */
- xfs_perag_t *pag; /* per allocation group data */
-
- agf = XFS_BUF_TO_AGF(agbp);
- mp = tp->t_mountp;
-
- if (!agflbp && (error = xfs_alloc_read_agfl(mp, tp,
- be32_to_cpu(agf->agf_seqno), &agflbp)))
- return error;
- agfl = XFS_BUF_TO_AGFL(agflbp);
- be32_add(&agf->agf_fllast, 1);
- if (be32_to_cpu(agf->agf_fllast) == XFS_AGFL_SIZE(mp))
- agf->agf_fllast = 0;
- pag = &mp->m_perag[be32_to_cpu(agf->agf_seqno)];
- be32_add(&agf->agf_flcount, 1);
- xfs_trans_agflist_delta(tp, 1);
- pag->pagf_flcount++;
- ASSERT(be32_to_cpu(agf->agf_flcount) <= XFS_AGFL_SIZE(mp));
- blockp = &agfl->agfl_bno[be32_to_cpu(agf->agf_fllast)];
- INT_SET(*blockp, ARCH_CONVERT, bno);
- TRACE_MODAGF(NULL, agf, XFS_AGF_FLLAST | XFS_AGF_FLCOUNT);
- xfs_alloc_log_agf(tp, agbp, XFS_AGF_FLLAST | XFS_AGF_FLCOUNT);
- xfs_trans_log_buf(tp, agflbp,
- (int)((xfs_caddr_t)blockp - (xfs_caddr_t)agfl),
- (int)((xfs_caddr_t)blockp - (xfs_caddr_t)agfl +
- sizeof(xfs_agblock_t) - 1));
- return 0;
-}
-
-/*
- * Read in the allocation group header (free/alloc section).
- */
-int /* error */
-xfs_alloc_read_agf(
- xfs_mount_t *mp, /* mount point structure */
- xfs_trans_t *tp, /* transaction pointer */
- xfs_agnumber_t agno, /* allocation group number */
- int flags, /* XFS_ALLOC_FLAG_... */
- xfs_buf_t **bpp) /* buffer for the ag freelist header */
-{
- xfs_agf_t *agf; /* ag freelist header */
- int agf_ok; /* set if agf is consistent */
- xfs_buf_t *bp; /* return value */
- xfs_perag_t *pag; /* per allocation group data */
- int error;
-
- ASSERT(agno != NULLAGNUMBER);
- error = xfs_trans_read_buf(
- mp, tp, mp->m_ddev_targp,
- XFS_AG_DADDR(mp, agno, XFS_AGF_DADDR(mp)),
- XFS_FSS_TO_BB(mp, 1),
- (flags & XFS_ALLOC_FLAG_TRYLOCK) ? XFS_BUF_TRYLOCK : 0U,
- &bp);
- if (error)
- return error;
- ASSERT(!bp || !XFS_BUF_GETERROR(bp));
- if (!bp) {
- *bpp = NULL;
- return 0;
- }
- /*
- * Validate the magic number of the agf block.
- */
- agf = XFS_BUF_TO_AGF(bp);
- agf_ok =
- be32_to_cpu(agf->agf_magicnum) == XFS_AGF_MAGIC &&
- XFS_AGF_GOOD_VERSION(be32_to_cpu(agf->agf_versionnum)) &&
- be32_to_cpu(agf->agf_freeblks) <= be32_to_cpu(agf->agf_length) &&
- be32_to_cpu(agf->agf_flfirst) < XFS_AGFL_SIZE(mp) &&
- be32_to_cpu(agf->agf_fllast) < XFS_AGFL_SIZE(mp) &&
- be32_to_cpu(agf->agf_flcount) <= XFS_AGFL_SIZE(mp);
- if (unlikely(XFS_TEST_ERROR(!agf_ok, mp, XFS_ERRTAG_ALLOC_READ_AGF,
- XFS_RANDOM_ALLOC_READ_AGF))) {
- XFS_CORRUPTION_ERROR("xfs_alloc_read_agf",
- XFS_ERRLEVEL_LOW, mp, agf);
- xfs_trans_brelse(tp, bp);
- return XFS_ERROR(EFSCORRUPTED);
- }
- pag = &mp->m_perag[agno];
- if (!pag->pagf_init) {
- pag->pagf_freeblks = be32_to_cpu(agf->agf_freeblks);
- pag->pagf_flcount = be32_to_cpu(agf->agf_flcount);
- pag->pagf_longest = be32_to_cpu(agf->agf_longest);
- pag->pagf_levels[XFS_BTNUM_BNOi] =
- be32_to_cpu(agf->agf_levels[XFS_BTNUM_BNOi]);
- pag->pagf_levels[XFS_BTNUM_CNTi] =
- be32_to_cpu(agf->agf_levels[XFS_BTNUM_CNTi]);
- spinlock_init(&pag->pagb_lock, "xfspagb");
- pag->pagb_list = kmem_zalloc(XFS_PAGB_NUM_SLOTS *
- sizeof(xfs_perag_busy_t), KM_SLEEP);
- pag->pagf_init = 1;
- }
-#ifdef DEBUG
- else if (!XFS_FORCED_SHUTDOWN(mp)) {
- ASSERT(pag->pagf_freeblks == be32_to_cpu(agf->agf_freeblks));
- ASSERT(pag->pagf_flcount == be32_to_cpu(agf->agf_flcount));
- ASSERT(pag->pagf_longest == be32_to_cpu(agf->agf_longest));
- ASSERT(pag->pagf_levels[XFS_BTNUM_BNOi] ==
- be32_to_cpu(agf->agf_levels[XFS_BTNUM_BNOi]));
- ASSERT(pag->pagf_levels[XFS_BTNUM_CNTi] ==
- be32_to_cpu(agf->agf_levels[XFS_BTNUM_CNTi]));
- }
-#endif
- XFS_BUF_SET_VTYPE_REF(bp, B_FS_AGF, XFS_AGF_REF);
- *bpp = bp;
- return 0;
-}
-
-/*
- * Allocate an extent (variable-size).
- * Depending on the allocation type, we either look in a single allocation
- * group or loop over the allocation groups to find the result.
- */
-int /* error */
-xfs_alloc_vextent(
- xfs_alloc_arg_t *args) /* allocation argument structure */
-{
- xfs_agblock_t agsize; /* allocation group size */
- int error;
- int flags; /* XFS_ALLOC_FLAG_... locking flags */
-#ifdef XFS_ALLOC_TRACE
- static char fname[] = "xfs_alloc_vextent";
-#endif
- xfs_extlen_t minleft;/* minimum left value, temp copy */
- xfs_mount_t *mp; /* mount structure pointer */
- xfs_agnumber_t sagno; /* starting allocation group number */
- xfs_alloctype_t type; /* input allocation type */
- int bump_rotor = 0;
- int no_min = 0;
- xfs_agnumber_t rotorstep = xfs_rotorstep; /* inode32 agf stepper */
-
- mp = args->mp;
- type = args->otype = args->type;
- args->agbno = NULLAGBLOCK;
- /*
- * Just fix this up, for the case where the last a.g. is shorter
- * (or there's only one a.g.) and the caller couldn't easily figure
- * that out (xfs_bmap_alloc).
- */
- agsize = mp->m_sb.sb_agblocks;
- if (args->maxlen > agsize)
- args->maxlen = agsize;
- if (args->alignment == 0)
- args->alignment = 1;
- ASSERT(XFS_FSB_TO_AGNO(mp, args->fsbno) < mp->m_sb.sb_agcount);
- ASSERT(XFS_FSB_TO_AGBNO(mp, args->fsbno) < agsize);
- ASSERT(args->minlen <= args->maxlen);
- ASSERT(args->minlen <= agsize);
- ASSERT(args->mod < args->prod);
- if (XFS_FSB_TO_AGNO(mp, args->fsbno) >= mp->m_sb.sb_agcount ||
- XFS_FSB_TO_AGBNO(mp, args->fsbno) >= agsize ||
- args->minlen > args->maxlen || args->minlen > agsize ||
- args->mod >= args->prod) {
- args->fsbno = NULLFSBLOCK;
- TRACE_ALLOC("badargs", args);
- return 0;
- }
- minleft = args->minleft;
-
- switch (type) {
- case XFS_ALLOCTYPE_THIS_AG:
- case XFS_ALLOCTYPE_NEAR_BNO:
- case XFS_ALLOCTYPE_THIS_BNO:
- /*
- * These three force us into a single a.g.
- */
- args->agno = XFS_FSB_TO_AGNO(mp, args->fsbno);
- down_read(&mp->m_peraglock);
- args->pag = &mp->m_perag[args->agno];
- args->minleft = 0;
- error = xfs_alloc_fix_freelist(args, 0);
- args->minleft = minleft;
- if (error) {
- TRACE_ALLOC("nofix", args);
- goto error0;
- }
- if (!args->agbp) {
- up_read(&mp->m_peraglock);
- TRACE_ALLOC("noagbp", args);
- break;
- }
- args->agbno = XFS_FSB_TO_AGBNO(mp, args->fsbno);
- if ((error = xfs_alloc_ag_vextent(args)))
- goto error0;
- up_read(&mp->m_peraglock);
- break;
- case XFS_ALLOCTYPE_START_BNO:
- /*
- * Try near allocation first, then anywhere-in-ag after
- * the first a.g. fails.
- */
- if ((args->userdata == XFS_ALLOC_INITIAL_USER_DATA) &&
- (mp->m_flags & XFS_MOUNT_32BITINODES)) {
- args->fsbno = XFS_AGB_TO_FSB(mp,
- ((mp->m_agfrotor / rotorstep) %
- mp->m_sb.sb_agcount), 0);
- bump_rotor = 1;
- }
- args->agbno = XFS_FSB_TO_AGBNO(mp, args->fsbno);
- args->type = XFS_ALLOCTYPE_NEAR_BNO;
- /* FALLTHROUGH */
- case XFS_ALLOCTYPE_ANY_AG:
- case XFS_ALLOCTYPE_START_AG:
- case XFS_ALLOCTYPE_FIRST_AG:
- /*
- * Rotate through the allocation groups looking for a winner.
- */
- if (type == XFS_ALLOCTYPE_ANY_AG) {
- /*
- * Start with the last place we left off.
- */
- args->agno = sagno = (mp->m_agfrotor / rotorstep) %
- mp->m_sb.sb_agcount;
- args->type = XFS_ALLOCTYPE_THIS_AG;
- flags = XFS_ALLOC_FLAG_TRYLOCK;
- } else if (type == XFS_ALLOCTYPE_FIRST_AG) {
- /*
- * Start with allocation group given by bno.
- */
- args->agno = XFS_FSB_TO_AGNO(mp, args->fsbno);
- args->type = XFS_ALLOCTYPE_THIS_AG;
- sagno = 0;
- flags = 0;
- } else {
- if (type == XFS_ALLOCTYPE_START_AG)
- args->type = XFS_ALLOCTYPE_THIS_AG;
- /*
- * Start with the given allocation group.
- */
- args->agno = sagno = XFS_FSB_TO_AGNO(mp, args->fsbno);
- flags = XFS_ALLOC_FLAG_TRYLOCK;
- }
- /*
- * Loop over allocation groups twice; first time with
- * trylock set, second time without.
- */
- down_read(&mp->m_peraglock);
- for (;;) {
- args->pag = &mp->m_perag[args->agno];
- if (no_min) args->minleft = 0;
- error = xfs_alloc_fix_freelist(args, flags);
- args->minleft = minleft;
- if (error) {
- TRACE_ALLOC("nofix", args);
- goto error0;
- }
- /*
- * If we get a buffer back then the allocation will fly.
- */
- if (args->agbp) {
- if ((error = xfs_alloc_ag_vextent(args)))
- goto error0;
- break;
- }
- TRACE_ALLOC("loopfailed", args);
- /*
- * Didn't work, figure out the next iteration.
- */
- if (args->agno == sagno &&
- type == XFS_ALLOCTYPE_START_BNO)
- args->type = XFS_ALLOCTYPE_THIS_AG;
- if (++(args->agno) == mp->m_sb.sb_agcount)
- args->agno = 0;
- /*
- * Reached the starting a.g., must either be done
- * or switch to non-trylock mode.
- */
- if (args->agno == sagno) {
- if (no_min == 1) {
- args->agbno = NULLAGBLOCK;
- TRACE_ALLOC("allfailed", args);
- break;
- }
- if (flags == 0) {
- no_min = 1;
- } else {
- flags = 0;
- if (type == XFS_ALLOCTYPE_START_BNO) {
- args->agbno = XFS_FSB_TO_AGBNO(mp,
- args->fsbno);
- args->type = XFS_ALLOCTYPE_NEAR_BNO;
- }
- }
- }
- }
- up_read(&mp->m_peraglock);
- if (bump_rotor || (type == XFS_ALLOCTYPE_ANY_AG)) {
- if (args->agno == sagno)
- mp->m_agfrotor = (mp->m_agfrotor + 1) %
- (mp->m_sb.sb_agcount * rotorstep);
- else
- mp->m_agfrotor = (args->agno * rotorstep + 1) %
- (mp->m_sb.sb_agcount * rotorstep);
- }
- break;
- default:
- ASSERT(0);
- /* NOTREACHED */
- }
- if (args->agbno == NULLAGBLOCK)
- args->fsbno = NULLFSBLOCK;
- else {
- args->fsbno = XFS_AGB_TO_FSB(mp, args->agno, args->agbno);
-#ifdef DEBUG
- ASSERT(args->len >= args->minlen);
- ASSERT(args->len <= args->maxlen);
- ASSERT(args->agbno % args->alignment == 0);
- XFS_AG_CHECK_DADDR(mp, XFS_FSB_TO_DADDR(mp, args->fsbno),
- args->len);
-#endif
- }
- return 0;
-error0:
- up_read(&mp->m_peraglock);
- return error;
-}
-
-/*
- * Free an extent.
- * Just break up the extent address and hand off to xfs_free_ag_extent
- * after fixing up the freelist.
- */
-int /* error */
-xfs_free_extent(
- xfs_trans_t *tp, /* transaction pointer */
- xfs_fsblock_t bno, /* starting block number of extent */
- xfs_extlen_t len) /* length of extent */
-{
-#ifdef DEBUG
- xfs_agf_t *agf; /* a.g. freespace header */
-#endif
- xfs_alloc_arg_t args; /* allocation argument structure */
- int error;
-
- ASSERT(len != 0);
- args.tp = tp;
- args.mp = tp->t_mountp;
- args.agno = XFS_FSB_TO_AGNO(args.mp, bno);
- ASSERT(args.agno < args.mp->m_sb.sb_agcount);
- args.agbno = XFS_FSB_TO_AGBNO(args.mp, bno);
- args.alignment = 1;
- args.minlen = args.minleft = args.minalignslop = 0;
- down_read(&args.mp->m_peraglock);
- args.pag = &args.mp->m_perag[args.agno];
- if ((error = xfs_alloc_fix_freelist(&args, 0)))
- goto error0;
-#ifdef DEBUG
- ASSERT(args.agbp != NULL);
- agf = XFS_BUF_TO_AGF(args.agbp);
- ASSERT(args.agbno + len <= be32_to_cpu(agf->agf_length));
-#endif
- error = xfs_free_ag_extent(tp, args.agbp, args.agno, args.agbno,
- len, 0);
-error0:
- up_read(&args.mp->m_peraglock);
- return error;
-}
-
-
-/*
- * AG Busy list management
- * The busy list contains block ranges that have been freed but whose
- * transactions have not yet hit disk. If any block listed in a busy
- * list is reused, the transaction that freed it must be forced to disk
- * before continuing to use the block.
- *
- * xfs_alloc_mark_busy - add to the per-ag busy list
- * xfs_alloc_clear_busy - remove an item from the per-ag busy list
- */
-void
-xfs_alloc_mark_busy(xfs_trans_t *tp,
- xfs_agnumber_t agno,
- xfs_agblock_t bno,
- xfs_extlen_t len)
-{
- xfs_mount_t *mp;
- xfs_perag_busy_t *bsy;
- int n;
- SPLDECL(s);
-
- mp = tp->t_mountp;
- s = mutex_spinlock(&mp->m_perag[agno].pagb_lock);
-
- /* search pagb_list for an open slot */
- for (bsy = mp->m_perag[agno].pagb_list, n = 0;
- n < XFS_PAGB_NUM_SLOTS;
- bsy++, n++) {
- if (bsy->busy_tp == NULL) {
- break;
- }
- }
-
- if (n < XFS_PAGB_NUM_SLOTS) {
- bsy = &mp->m_perag[agno].pagb_list[n];
- mp->m_perag[agno].pagb_count++;
- TRACE_BUSY("xfs_alloc_mark_busy", "got", agno, bno, len, n, tp);
- bsy->busy_start = bno;
- bsy->busy_length = len;
- bsy->busy_tp = tp;
- xfs_trans_add_busy(tp, agno, n);
- } else {
- TRACE_BUSY("xfs_alloc_mark_busy", "FULL", agno, bno, len, -1, tp);
- /*
- * The busy list is full! Since it is now not possible to
- * track the free block, make this a synchronous transaction
- * to insure that the block is not reused before this
- * transaction commits.
- */
- xfs_trans_set_sync(tp);
- }
-
- mutex_spinunlock(&mp->m_perag[agno].pagb_lock, s);
-}
-
-void
-xfs_alloc_clear_busy(xfs_trans_t *tp,
- xfs_agnumber_t agno,
- int idx)
-{
- xfs_mount_t *mp;
- xfs_perag_busy_t *list;
- SPLDECL(s);
-
- mp = tp->t_mountp;
-
- s = mutex_spinlock(&mp->m_perag[agno].pagb_lock);
- list = mp->m_perag[agno].pagb_list;
-
- ASSERT(idx < XFS_PAGB_NUM_SLOTS);
- if (list[idx].busy_tp == tp) {
- TRACE_UNBUSY("xfs_alloc_clear_busy", "found", agno, idx, tp);
- list[idx].busy_tp = NULL;
- mp->m_perag[agno].pagb_count--;
- } else {
- TRACE_UNBUSY("xfs_alloc_clear_busy", "missing", agno, idx, tp);
- }
-
- mutex_spinunlock(&mp->m_perag[agno].pagb_lock, s);
-}
-
-
-/*
- * returns non-zero if any of (agno,bno):len is in a busy list
- */
-STATIC int
-xfs_alloc_search_busy(xfs_trans_t *tp,
- xfs_agnumber_t agno,
- xfs_agblock_t bno,
- xfs_extlen_t len)
-{
- xfs_mount_t *mp;
- xfs_perag_busy_t *bsy;
- int n;
- xfs_agblock_t uend, bend;
- xfs_lsn_t lsn;
- int cnt;
- SPLDECL(s);
-
- mp = tp->t_mountp;
-
- s = mutex_spinlock(&mp->m_perag[agno].pagb_lock);
- cnt = mp->m_perag[agno].pagb_count;
-
- uend = bno + len - 1;
-
- /* search pagb_list for this slot, skipping open slots */
- for (bsy = mp->m_perag[agno].pagb_list, n = 0;
- cnt; bsy++, n++) {
-
- /*
- * (start1,length1) within (start2, length2)
- */
- if (bsy->busy_tp != NULL) {
- bend = bsy->busy_start + bsy->busy_length - 1;
- if ((bno > bend) ||
- (uend < bsy->busy_start)) {
- cnt--;
- } else {
- TRACE_BUSYSEARCH("xfs_alloc_search_busy",
- "found1", agno, bno, len, n,
- tp);
- break;
- }
- }
- }
-
- /*
- * If a block was found, force the log through the LSN of the
- * transaction that freed the block
- */
- if (cnt) {
- TRACE_BUSYSEARCH("xfs_alloc_search_busy", "found", agno, bno, len, n, tp);
- lsn = bsy->busy_tp->t_commit_lsn;
- mutex_spinunlock(&mp->m_perag[agno].pagb_lock, s);
- xfs_log_force(mp, lsn, XFS_LOG_FORCE|XFS_LOG_SYNC);
- } else {
- TRACE_BUSYSEARCH("xfs_alloc_search_busy", "not-found", agno, bno, len, n, tp);
- n = -1;
- mutex_spinunlock(&mp->m_perag[agno].pagb_lock, s);
- }
-
- return n;
-}
diff --git a/sys/gnu/fs/xfs/xfs_alloc.h b/sys/gnu/fs/xfs/xfs_alloc.h
deleted file mode 100644
index 2d1f892..0000000
--- a/sys/gnu/fs/xfs/xfs_alloc.h
+++ /dev/null
@@ -1,189 +0,0 @@
-/*
- * Copyright (c) 2000-2002,2005 Silicon Graphics, Inc.
- * All Rights Reserved.
- *
- * 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.
- *
- * This program is distributed in the hope that it would 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 the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- */
-#ifndef __XFS_ALLOC_H__
-#define __XFS_ALLOC_H__
-
-struct xfs_buf;
-struct xfs_mount;
-struct xfs_perag;
-struct xfs_trans;
-
-/*
- * Freespace allocation types. Argument to xfs_alloc_[v]extent.
- */
-typedef enum xfs_alloctype
-{
- XFS_ALLOCTYPE_ANY_AG, /* allocate anywhere, use rotor */
- XFS_ALLOCTYPE_FIRST_AG, /* ... start at ag 0 */
- XFS_ALLOCTYPE_START_AG, /* anywhere, start in this a.g. */
- XFS_ALLOCTYPE_THIS_AG, /* anywhere in this a.g. */
- XFS_ALLOCTYPE_START_BNO, /* near this block else anywhere */
- XFS_ALLOCTYPE_NEAR_BNO, /* in this a.g. and near this block */
- XFS_ALLOCTYPE_THIS_BNO /* at exactly this block */
-} xfs_alloctype_t;
-
-/*
- * Flags for xfs_alloc_fix_freelist.
- */
-#define XFS_ALLOC_FLAG_TRYLOCK 0x00000001 /* use trylock for buffer locking */
-
-/*
- * Argument structure for xfs_alloc routines.
- * This is turned into a structure to avoid having 20 arguments passed
- * down several levels of the stack.
- */
-typedef struct xfs_alloc_arg {
- struct xfs_trans *tp; /* transaction pointer */
- struct xfs_mount *mp; /* file system mount point */
- struct xfs_buf *agbp; /* buffer for a.g. freelist header */
- struct xfs_perag *pag; /* per-ag struct for this agno */
- xfs_fsblock_t fsbno; /* file system block number */
- xfs_agnumber_t agno; /* allocation group number */
- xfs_agblock_t agbno; /* allocation group-relative block # */
- xfs_extlen_t minlen; /* minimum size of extent */
- xfs_extlen_t maxlen; /* maximum size of extent */
- xfs_extlen_t mod; /* mod value for extent size */
- xfs_extlen_t prod; /* prod value for extent size */
- xfs_extlen_t minleft; /* min blocks must be left after us */
- xfs_extlen_t total; /* total blocks needed in xaction */
- xfs_extlen_t alignment; /* align answer to multiple of this */
- xfs_extlen_t minalignslop; /* slop for minlen+alignment calcs */
- xfs_extlen_t len; /* output: actual size of extent */
- xfs_alloctype_t type; /* allocation type XFS_ALLOCTYPE_... */
- xfs_alloctype_t otype; /* original allocation type */
- char wasdel; /* set if allocation was prev delayed */
- char wasfromfl; /* set if allocation is from freelist */
- char isfl; /* set if is freelist blocks - !acctg */
- char userdata; /* set if this is user data */
-} xfs_alloc_arg_t;
-
-/*
- * Defines for userdata
- */
-#define XFS_ALLOC_USERDATA 1 /* allocation is for user data*/
-#define XFS_ALLOC_INITIAL_USER_DATA 2 /* special case start of file */
-
-
-#ifdef __KERNEL__
-
-#if defined(XFS_ALLOC_TRACE)
-/*
- * Allocation tracing buffer size.
- */
-#define XFS_ALLOC_TRACE_SIZE 4096
-extern ktrace_t *xfs_alloc_trace_buf;
-
-/*
- * Types for alloc tracing.
- */
-#define XFS_ALLOC_KTRACE_ALLOC 1
-#define XFS_ALLOC_KTRACE_FREE 2
-#define XFS_ALLOC_KTRACE_MODAGF 3
-#define XFS_ALLOC_KTRACE_BUSY 4
-#define XFS_ALLOC_KTRACE_UNBUSY 5
-#define XFS_ALLOC_KTRACE_BUSYSEARCH 6
-#endif
-
-/*
- * Compute and fill in value of m_ag_maxlevels.
- */
-void
-xfs_alloc_compute_maxlevels(
- struct xfs_mount *mp); /* file system mount structure */
-
-/*
- * Get a block from the freelist.
- * Returns with the buffer for the block gotten.
- */
-int /* error */
-xfs_alloc_get_freelist(
- struct xfs_trans *tp, /* transaction pointer */
- struct xfs_buf *agbp, /* buffer containing the agf structure */
- xfs_agblock_t *bnop); /* block address retrieved from freelist */
-
-/*
- * Log the given fields from the agf structure.
- */
-void
-xfs_alloc_log_agf(
- struct xfs_trans *tp, /* transaction pointer */
- struct xfs_buf *bp, /* buffer for a.g. freelist header */
- int fields);/* mask of fields to be logged (XFS_AGF_...) */
-
-/*
- * Interface for inode allocation to force the pag data to be initialized.
- */
-int /* error */
-xfs_alloc_pagf_init(
- struct xfs_mount *mp, /* file system mount structure */
- struct xfs_trans *tp, /* transaction pointer */
- xfs_agnumber_t agno, /* allocation group number */
- int flags); /* XFS_ALLOC_FLAGS_... */
-
-/*
- * Put the block on the freelist for the allocation group.
- */
-int /* error */
-xfs_alloc_put_freelist(
- struct xfs_trans *tp, /* transaction pointer */
- struct xfs_buf *agbp, /* buffer for a.g. freelist header */
- struct xfs_buf *agflbp,/* buffer for a.g. free block array */
- xfs_agblock_t bno); /* block being freed */
-
-/*
- * Read in the allocation group header (free/alloc section).
- */
-int /* error */
-xfs_alloc_read_agf(
- struct xfs_mount *mp, /* mount point structure */
- struct xfs_trans *tp, /* transaction pointer */
- xfs_agnumber_t agno, /* allocation group number */
- int flags, /* XFS_ALLOC_FLAG_... */
- struct xfs_buf **bpp); /* buffer for the ag freelist header */
-
-/*
- * Allocate an extent (variable-size).
- */
-int /* error */
-xfs_alloc_vextent(
- xfs_alloc_arg_t *args); /* allocation argument structure */
-
-/*
- * Free an extent.
- */
-int /* error */
-xfs_free_extent(
- struct xfs_trans *tp, /* transaction pointer */
- xfs_fsblock_t bno, /* starting block number of extent */
- xfs_extlen_t len); /* length of extent */
-
-void
-xfs_alloc_mark_busy(xfs_trans_t *tp,
- xfs_agnumber_t agno,
- xfs_agblock_t bno,
- xfs_extlen_t len);
-
-void
-xfs_alloc_clear_busy(xfs_trans_t *tp,
- xfs_agnumber_t ag,
- int idx);
-
-
-#endif /* __KERNEL__ */
-
-#endif /* __XFS_ALLOC_H__ */
diff --git a/sys/gnu/fs/xfs/xfs_alloc_btree.c b/sys/gnu/fs/xfs/xfs_alloc_btree.c
deleted file mode 100644
index a1d92da..0000000
--- a/sys/gnu/fs/xfs/xfs_alloc_btree.c
+++ /dev/null
@@ -1,2203 +0,0 @@
-/*
- * Copyright (c) 2000-2001,2005 Silicon Graphics, Inc.
- * All Rights Reserved.
- *
- * 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.
- *
- * This program is distributed in the hope that it would 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 the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- */
-#include "xfs.h"
-#include "xfs_fs.h"
-#include "xfs_types.h"
-#include "xfs_bit.h"
-#include "xfs_log.h"
-#include "xfs_inum.h"
-#include "xfs_trans.h"
-#include "xfs_sb.h"
-#include "xfs_ag.h"
-#include "xfs_dir.h"
-#include "xfs_dir2.h"
-#include "xfs_dmapi.h"
-#include "xfs_mount.h"
-#include "xfs_bmap_btree.h"
-#include "xfs_alloc_btree.h"
-#include "xfs_ialloc_btree.h"
-#include "xfs_dir_sf.h"
-#include "xfs_dir2_sf.h"
-#include "xfs_attr_sf.h"
-#include "xfs_dinode.h"
-#include "xfs_inode.h"
-#include "xfs_btree.h"
-#include "xfs_ialloc.h"
-#include "xfs_alloc.h"
-#include "xfs_error.h"
-
-/*
- * Prototypes for internal functions.
- */
-
-STATIC void xfs_alloc_log_block(xfs_trans_t *, xfs_buf_t *, int);
-STATIC void xfs_alloc_log_keys(xfs_btree_cur_t *, xfs_buf_t *, int, int);
-STATIC void xfs_alloc_log_ptrs(xfs_btree_cur_t *, xfs_buf_t *, int, int);
-STATIC void xfs_alloc_log_recs(xfs_btree_cur_t *, xfs_buf_t *, int, int);
-STATIC int xfs_alloc_lshift(xfs_btree_cur_t *, int, int *);
-STATIC int xfs_alloc_newroot(xfs_btree_cur_t *, int *);
-STATIC int xfs_alloc_rshift(xfs_btree_cur_t *, int, int *);
-STATIC int xfs_alloc_split(xfs_btree_cur_t *, int, xfs_agblock_t *,
- xfs_alloc_key_t *, xfs_btree_cur_t **, int *);
-STATIC int xfs_alloc_updkey(xfs_btree_cur_t *, xfs_alloc_key_t *, int);
-
-/*
- * Internal functions.
- */
-
-/*
- * Single level of the xfs_alloc_delete record deletion routine.
- * Delete record pointed to by cur/level.
- * Remove the record from its block then rebalance the tree.
- * Return 0 for error, 1 for done, 2 to go on to the next level.
- */
-STATIC int /* error */
-xfs_alloc_delrec(
- xfs_btree_cur_t *cur, /* btree cursor */
- int level, /* level removing record from */
- int *stat) /* fail/done/go-on */
-{
- xfs_agf_t *agf; /* allocation group freelist header */
- xfs_alloc_block_t *block; /* btree block record/key lives in */
- xfs_agblock_t bno; /* btree block number */
- xfs_buf_t *bp; /* buffer for block */
- int error; /* error return value */
- int i; /* loop index */
- xfs_alloc_key_t key; /* kp points here if block is level 0 */
- xfs_agblock_t lbno; /* left block's block number */
- xfs_buf_t *lbp; /* left block's buffer pointer */
- xfs_alloc_block_t *left; /* left btree block */
- xfs_alloc_key_t *lkp=NULL; /* left block key pointer */
- xfs_alloc_ptr_t *lpp=NULL; /* left block address pointer */
- int lrecs=0; /* number of records in left block */
- xfs_alloc_rec_t *lrp; /* left block record pointer */
- xfs_mount_t *mp; /* mount structure */
- int ptr; /* index in btree block for this rec */
- xfs_agblock_t rbno; /* right block's block number */
- xfs_buf_t *rbp; /* right block's buffer pointer */
- xfs_alloc_block_t *right; /* right btree block */
- xfs_alloc_key_t *rkp; /* right block key pointer */
- xfs_alloc_ptr_t *rpp; /* right block address pointer */
- int rrecs=0; /* number of records in right block */
- xfs_alloc_rec_t *rrp; /* right block record pointer */
- xfs_btree_cur_t *tcur; /* temporary btree cursor */
-
- /*
- * Get the index of the entry being deleted, check for nothing there.
- */
- ptr = cur->bc_ptrs[level];
- if (ptr == 0) {
- *stat = 0;
- return 0;
- }
- /*
- * Get the buffer & block containing the record or key/ptr.
- */
- bp = cur->bc_bufs[level];
- block = XFS_BUF_TO_ALLOC_BLOCK(bp);
-#ifdef DEBUG
- if ((error = xfs_btree_check_sblock(cur, block, level, bp)))
- return error;
-#endif
- /*
- * Fail if we're off the end of the block.
- */
- if (ptr > be16_to_cpu(block->bb_numrecs)) {
- *stat = 0;
- return 0;
- }
- XFS_STATS_INC(xs_abt_delrec);
- /*
- * It's a nonleaf. Excise the key and ptr being deleted, by
- * sliding the entries past them down one.
- * Log the changed areas of the block.
- */
- if (level > 0) {
- lkp = XFS_ALLOC_KEY_ADDR(block, 1, cur);
- lpp = XFS_ALLOC_PTR_ADDR(block, 1, cur);
-#ifdef DEBUG
- for (i = ptr; i < be16_to_cpu(block->bb_numrecs); i++) {
- if ((error = xfs_btree_check_sptr(cur, be32_to_cpu(lpp[i]), level)))
- return error;
- }
-#endif
- if (ptr < be16_to_cpu(block->bb_numrecs)) {
- memmove(&lkp[ptr - 1], &lkp[ptr],
- (be16_to_cpu(block->bb_numrecs) - ptr) * sizeof(*lkp));
- memmove(&lpp[ptr - 1], &lpp[ptr],
- (be16_to_cpu(block->bb_numrecs) - ptr) * sizeof(*lpp));
- xfs_alloc_log_ptrs(cur, bp, ptr, be16_to_cpu(block->bb_numrecs) - 1);
- xfs_alloc_log_keys(cur, bp, ptr, be16_to_cpu(block->bb_numrecs) - 1);
- }
- }
- /*
- * It's a leaf. Excise the record being deleted, by sliding the
- * entries past it down one. Log the changed areas of the block.
- */
- else {
- lrp = XFS_ALLOC_REC_ADDR(block, 1, cur);
- if (ptr < be16_to_cpu(block->bb_numrecs)) {
- memmove(&lrp[ptr - 1], &lrp[ptr],
- (be16_to_cpu(block->bb_numrecs) - ptr) * sizeof(*lrp));
- xfs_alloc_log_recs(cur, bp, ptr, be16_to_cpu(block->bb_numrecs) - 1);
- }
- /*
- * If it's the first record in the block, we'll need a key
- * structure to pass up to the next level (updkey).
- */
- if (ptr == 1) {
- key.ar_startblock = lrp->ar_startblock;
- key.ar_blockcount = lrp->ar_blockcount;
- lkp = &key;
- }
- }
- /*
- * Decrement and log the number of entries in the block.
- */
- be16_add(&block->bb_numrecs, -1);
- xfs_alloc_log_block(cur->bc_tp, bp, XFS_BB_NUMRECS);
- /*
- * See if the longest free extent in the allocation group was
- * changed by this operation. True if it's the by-size btree, and
- * this is the leaf level, and there is no right sibling block,
- * and this was the last record.
- */
- agf = XFS_BUF_TO_AGF(cur->bc_private.a.agbp);
- mp = cur->bc_mp;
-
- if (level == 0 &&
- cur->bc_btnum == XFS_BTNUM_CNT &&
- be32_to_cpu(block->bb_rightsib) == NULLAGBLOCK &&
- ptr > be16_to_cpu(block->bb_numrecs)) {
- ASSERT(ptr == be16_to_cpu(block->bb_numrecs) + 1);
- /*
- * There are still records in the block. Grab the size
- * from the last one.
- */
- if (be16_to_cpu(block->bb_numrecs)) {
- rrp = XFS_ALLOC_REC_ADDR(block, be16_to_cpu(block->bb_numrecs), cur);
- agf->agf_longest = rrp->ar_blockcount;
- }
- /*
- * No free extents left.
- */
- else
- agf->agf_longest = 0;
- mp->m_perag[be32_to_cpu(agf->agf_seqno)].pagf_longest =
- be32_to_cpu(agf->agf_longest);
- xfs_alloc_log_agf(cur->bc_tp, cur->bc_private.a.agbp,
- XFS_AGF_LONGEST);
- }
- /*
- * Is this the root level? If so, we're almost done.
- */
- if (level == cur->bc_nlevels - 1) {
- /*
- * If this is the root level,
- * and there's only one entry left,
- * and it's NOT the leaf level,
- * then we can get rid of this level.
- */
- if (be16_to_cpu(block->bb_numrecs) == 1 && level > 0) {
- /*
- * lpp is still set to the first pointer in the block.
- * Make it the new root of the btree.
- */
- bno = be32_to_cpu(agf->agf_roots[cur->bc_btnum]);
- agf->agf_roots[cur->bc_btnum] = *lpp;
- be32_add(&agf->agf_levels[cur->bc_btnum], -1);
- mp->m_perag[be32_to_cpu(agf->agf_seqno)].pagf_levels[cur->bc_btnum]--;
- /*
- * Put this buffer/block on the ag's freelist.
- */
- if ((error = xfs_alloc_put_freelist(cur->bc_tp,
- cur->bc_private.a.agbp, NULL, bno)))
- return error;
- /*
- * Since blocks move to the free list without the
- * coordination used in xfs_bmap_finish, we can't allow
- * block to be available for reallocation and
- * non-transaction writing (user data) until we know
- * that the transaction that moved it to the free list
- * is permanently on disk. We track the blocks by
- * declaring these blocks as "busy"; the busy list is
- * maintained on a per-ag basis and each transaction
- * records which entries should be removed when the
- * iclog commits to disk. If a busy block is
- * allocated, the iclog is pushed up to the LSN
- * that freed the block.
- */
- xfs_alloc_mark_busy(cur->bc_tp,
- be32_to_cpu(agf->agf_seqno), bno, 1);
-
- xfs_trans_agbtree_delta(cur->bc_tp, -1);
- xfs_alloc_log_agf(cur->bc_tp, cur->bc_private.a.agbp,
- XFS_AGF_ROOTS | XFS_AGF_LEVELS);
- /*
- * Update the cursor so there's one fewer level.
- */
- xfs_btree_setbuf(cur, level, NULL);
- cur->bc_nlevels--;
- } else if (level > 0 &&
- (error = xfs_alloc_decrement(cur, level, &i)))
- return error;
- *stat = 1;
- return 0;
- }
- /*
- * If we deleted the leftmost entry in the block, update the
- * key values above us in the tree.
- */
- if (ptr == 1 && (error = xfs_alloc_updkey(cur, lkp, level + 1)))
- return error;
- /*
- * If the number of records remaining in the block is at least
- * the minimum, we're done.
- */
- if (be16_to_cpu(block->bb_numrecs) >= XFS_ALLOC_BLOCK_MINRECS(level, cur)) {
- if (level > 0 && (error = xfs_alloc_decrement(cur, level, &i)))
- return error;
- *stat = 1;
- return 0;
- }
- /*
- * Otherwise, we have to move some records around to keep the
- * tree balanced. Look at the left and right sibling blocks to
- * see if we can re-balance by moving only one record.
- */
- rbno = be32_to_cpu(block->bb_rightsib);
- lbno = be32_to_cpu(block->bb_leftsib);
- bno = NULLAGBLOCK;
- ASSERT(rbno != NULLAGBLOCK || lbno != NULLAGBLOCK);
- /*
- * Duplicate the cursor so our btree manipulations here won't
- * disrupt the next level up.
- */
- if ((error = xfs_btree_dup_cursor(cur, &tcur)))
- return error;
- /*
- * If there's a right sibling, see if it's ok to shift an entry
- * out of it.
- */
- if (rbno != NULLAGBLOCK) {
- /*
- * Move the temp cursor to the last entry in the next block.
- * Actually any entry but the first would suffice.
- */
- i = xfs_btree_lastrec(tcur, level);
- XFS_WANT_CORRUPTED_GOTO(i == 1, error0);
- if ((error = xfs_alloc_increment(tcur, level, &i)))
- goto error0;
- XFS_WANT_CORRUPTED_GOTO(i == 1, error0);
- i = xfs_btree_lastrec(tcur, level);
- XFS_WANT_CORRUPTED_GOTO(i == 1, error0);
- /*
- * Grab a pointer to the block.
- */
- rbp = tcur->bc_bufs[level];
- right = XFS_BUF_TO_ALLOC_BLOCK(rbp);
-#ifdef DEBUG
- if ((error = xfs_btree_check_sblock(cur, right, level, rbp)))
- goto error0;
-#endif
- /*
- * Grab the current block number, for future use.
- */
- bno = be32_to_cpu(right->bb_leftsib);
- /*
- * If right block is full enough so that removing one entry
- * won't make it too empty, and left-shifting an entry out
- * of right to us works, we're done.
- */
- if (be16_to_cpu(right->bb_numrecs) - 1 >=
- XFS_ALLOC_BLOCK_MINRECS(level, cur)) {
- if ((error = xfs_alloc_lshift(tcur, level, &i)))
- goto error0;
- if (i) {
- ASSERT(be16_to_cpu(block->bb_numrecs) >=
- XFS_ALLOC_BLOCK_MINRECS(level, cur));
- xfs_btree_del_cursor(tcur,
- XFS_BTREE_NOERROR);
- if (level > 0 &&
- (error = xfs_alloc_decrement(cur, level,
- &i)))
- return error;
- *stat = 1;
- return 0;
- }
- }
- /*
- * Otherwise, grab the number of records in right for
- * future reference, and fix up the temp cursor to point
- * to our block again (last record).
- */
- rrecs = be16_to_cpu(right->bb_numrecs);
- if (lbno != NULLAGBLOCK) {
- i = xfs_btree_firstrec(tcur, level);
- XFS_WANT_CORRUPTED_GOTO(i == 1, error0);
- if ((error = xfs_alloc_decrement(tcur, level, &i)))
- goto error0;
- XFS_WANT_CORRUPTED_GOTO(i == 1, error0);
- }
- }
- /*
- * If there's a left sibling, see if it's ok to shift an entry
- * out of it.
- */
- if (lbno != NULLAGBLOCK) {
- /*
- * Move the temp cursor to the first entry in the
- * previous block.
- */
- i = xfs_btree_firstrec(tcur, level);
- XFS_WANT_CORRUPTED_GOTO(i == 1, error0);
- if ((error = xfs_alloc_decrement(tcur, level, &i)))
- goto error0;
- XFS_WANT_CORRUPTED_GOTO(i == 1, error0);
- xfs_btree_firstrec(tcur, level);
- /*
- * Grab a pointer to the block.
- */
- lbp = tcur->bc_bufs[level];
- left = XFS_BUF_TO_ALLOC_BLOCK(lbp);
-#ifdef DEBUG
- if ((error = xfs_btree_check_sblock(cur, left, level, lbp)))
- goto error0;
-#endif
- /*
- * Grab the current block number, for future use.
- */
- bno = be32_to_cpu(left->bb_rightsib);
- /*
- * If left block is full enough so that removing one entry
- * won't make it too empty, and right-shifting an entry out
- * of left to us works, we're done.
- */
- if (be16_to_cpu(left->bb_numrecs) - 1 >=
- XFS_ALLOC_BLOCK_MINRECS(level, cur)) {
- if ((error = xfs_alloc_rshift(tcur, level, &i)))
- goto error0;
- if (i) {
- ASSERT(be16_to_cpu(block->bb_numrecs) >=
- XFS_ALLOC_BLOCK_MINRECS(level, cur));
- xfs_btree_del_cursor(tcur,
- XFS_BTREE_NOERROR);
- if (level == 0)
- cur->bc_ptrs[0]++;
- *stat = 1;
- return 0;
- }
- }
- /*
- * Otherwise, grab the number of records in right for
- * future reference.
- */
- lrecs = be16_to_cpu(left->bb_numrecs);
- }
- /*
- * Delete the temp cursor, we're done with it.
- */
- xfs_btree_del_cursor(tcur, XFS_BTREE_NOERROR);
- /*
- * If here, we need to do a join to keep the tree balanced.
- */
- ASSERT(bno != NULLAGBLOCK);
- /*
- * See if we can join with the left neighbor block.
- */
- if (lbno != NULLAGBLOCK &&
- lrecs + be16_to_cpu(block->bb_numrecs) <= XFS_ALLOC_BLOCK_MAXRECS(level, cur)) {
- /*
- * Set "right" to be the starting block,
- * "left" to be the left neighbor.
- */
- rbno = bno;
- right = block;
- rbp = bp;
- if ((error = xfs_btree_read_bufs(mp, cur->bc_tp,
- cur->bc_private.a.agno, lbno, 0, &lbp,
- XFS_ALLOC_BTREE_REF)))
- return error;
- left = XFS_BUF_TO_ALLOC_BLOCK(lbp);
- if ((error = xfs_btree_check_sblock(cur, left, level, lbp)))
- return error;
- }
- /*
- * If that won't work, see if we can join with the right neighbor block.
- */
- else if (rbno != NULLAGBLOCK &&
- rrecs + be16_to_cpu(block->bb_numrecs) <=
- XFS_ALLOC_BLOCK_MAXRECS(level, cur)) {
- /*
- * Set "left" to be the starting block,
- * "right" to be the right neighbor.
- */
- lbno = bno;
- left = block;
- lbp = bp;
- if ((error = xfs_btree_read_bufs(mp, cur->bc_tp,
- cur->bc_private.a.agno, rbno, 0, &rbp,
- XFS_ALLOC_BTREE_REF)))
- return error;
- right = XFS_BUF_TO_ALLOC_BLOCK(rbp);
- if ((error = xfs_btree_check_sblock(cur, right, level, rbp)))
- return error;
- }
- /*
- * Otherwise, we can't fix the imbalance.
- * Just return. This is probably a logic error, but it's not fatal.
- */
- else {
- if (level > 0 && (error = xfs_alloc_decrement(cur, level, &i)))
- return error;
- *stat = 1;
- return 0;
- }
- /*
- * We're now going to join "left" and "right" by moving all the stuff
- * in "right" to "left" and deleting "right".
- */
- if (level > 0) {
- /*
- * It's a non-leaf. Move keys and pointers.
- */
- lkp = XFS_ALLOC_KEY_ADDR(left, be16_to_cpu(left->bb_numrecs) + 1, cur);
- lpp = XFS_ALLOC_PTR_ADDR(left, be16_to_cpu(left->bb_numrecs) + 1, cur);
- rkp = XFS_ALLOC_KEY_ADDR(right, 1, cur);
- rpp = XFS_ALLOC_PTR_ADDR(right, 1, cur);
-#ifdef DEBUG
- for (i = 0; i < be16_to_cpu(right->bb_numrecs); i++) {
- if ((error = xfs_btree_check_sptr(cur, be32_to_cpu(rpp[i]), level)))
- return error;
- }
-#endif
- memcpy(lkp, rkp, be16_to_cpu(right->bb_numrecs) * sizeof(*lkp));
- memcpy(lpp, rpp, be16_to_cpu(right->bb_numrecs) * sizeof(*lpp));
- xfs_alloc_log_keys(cur, lbp, be16_to_cpu(left->bb_numrecs) + 1,
- be16_to_cpu(left->bb_numrecs) +
- be16_to_cpu(right->bb_numrecs));
- xfs_alloc_log_ptrs(cur, lbp, be16_to_cpu(left->bb_numrecs) + 1,
- be16_to_cpu(left->bb_numrecs) +
- be16_to_cpu(right->bb_numrecs));
- } else {
- /*
- * It's a leaf. Move records.
- */
- lrp = XFS_ALLOC_REC_ADDR(left, be16_to_cpu(left->bb_numrecs) + 1, cur);
- rrp = XFS_ALLOC_REC_ADDR(right, 1, cur);
- memcpy(lrp, rrp, be16_to_cpu(right->bb_numrecs) * sizeof(*lrp));
- xfs_alloc_log_recs(cur, lbp, be16_to_cpu(left->bb_numrecs) + 1,
- be16_to_cpu(left->bb_numrecs) +
- be16_to_cpu(right->bb_numrecs));
- }
- /*
- * If we joined with the left neighbor, set the buffer in the
- * cursor to the left block, and fix up the index.
- */
- if (bp != lbp) {
- xfs_btree_setbuf(cur, level, lbp);
- cur->bc_ptrs[level] += be16_to_cpu(left->bb_numrecs);
- }
- /*
- * If we joined with the right neighbor and there's a level above
- * us, increment the cursor at that level.
- */
- else if (level + 1 < cur->bc_nlevels &&
- (error = xfs_alloc_increment(cur, level + 1, &i)))
- return error;
- /*
- * Fix up the number of records in the surviving block.
- */
- be16_add(&left->bb_numrecs, be16_to_cpu(right->bb_numrecs));
- /*
- * Fix up the right block pointer in the surviving block, and log it.
- */
- left->bb_rightsib = right->bb_rightsib;
- xfs_alloc_log_block(cur->bc_tp, lbp, XFS_BB_NUMRECS | XFS_BB_RIGHTSIB);
- /*
- * If there is a right sibling now, make it point to the
- * remaining block.
- */
- if (be32_to_cpu(left->bb_rightsib) != NULLAGBLOCK) {
- xfs_alloc_block_t *rrblock;
- xfs_buf_t *rrbp;
-
- if ((error = xfs_btree_read_bufs(mp, cur->bc_tp,
- cur->bc_private.a.agno, be32_to_cpu(left->bb_rightsib), 0,
- &rrbp, XFS_ALLOC_BTREE_REF)))
- return error;
- rrblock = XFS_BUF_TO_ALLOC_BLOCK(rrbp);
- if ((error = xfs_btree_check_sblock(cur, rrblock, level, rrbp)))
- return error;
- rrblock->bb_leftsib = cpu_to_be32(lbno);
- xfs_alloc_log_block(cur->bc_tp, rrbp, XFS_BB_LEFTSIB);
- }
- /*
- * Free the deleting block by putting it on the freelist.
- */
- if ((error = xfs_alloc_put_freelist(cur->bc_tp, cur->bc_private.a.agbp,
- NULL, rbno)))
- return error;
- /*
- * Since blocks move to the free list without the coordination
- * used in xfs_bmap_finish, we can't allow block to be available
- * for reallocation and non-transaction writing (user data)
- * until we know that the transaction that moved it to the free
- * list is permanently on disk. We track the blocks by declaring
- * these blocks as "busy"; the busy list is maintained on a
- * per-ag basis and each transaction records which entries
- * should be removed when the iclog commits to disk. If a
- * busy block is allocated, the iclog is pushed up to the
- * LSN that freed the block.
- */
- xfs_alloc_mark_busy(cur->bc_tp, be32_to_cpu(agf->agf_seqno), bno, 1);
- xfs_trans_agbtree_delta(cur->bc_tp, -1);
-
- /*
- * Adjust the current level's cursor so that we're left referring
- * to the right node, after we're done.
- * If this leaves the ptr value 0 our caller will fix it up.
- */
- if (level > 0)
- cur->bc_ptrs[level]--;
- /*
- * Return value means the next level up has something to do.
- */
- *stat = 2;
- return 0;
-
-error0:
- xfs_btree_del_cursor(tcur, XFS_BTREE_ERROR);
- return error;
-}
-
-/*
- * Insert one record/level. Return information to the caller
- * allowing the next level up to proceed if necessary.
- */
-STATIC int /* error */
-xfs_alloc_insrec(
- xfs_btree_cur_t *cur, /* btree cursor */
- int level, /* level to insert record at */
- xfs_agblock_t *bnop, /* i/o: block number inserted */
- xfs_alloc_rec_t *recp, /* i/o: record data inserted */
- xfs_btree_cur_t **curp, /* output: new cursor replacing cur */
- int *stat) /* output: success/failure */
-{
- xfs_agf_t *agf; /* allocation group freelist header */
- xfs_alloc_block_t *block; /* btree block record/key lives in */
- xfs_buf_t *bp; /* buffer for block */
- int error; /* error return value */
- int i; /* loop index */
- xfs_alloc_key_t key; /* key value being inserted */
- xfs_alloc_key_t *kp; /* pointer to btree keys */
- xfs_agblock_t nbno; /* block number of allocated block */
- xfs_btree_cur_t *ncur; /* new cursor to be used at next lvl */
- xfs_alloc_key_t nkey; /* new key value, from split */
- xfs_alloc_rec_t nrec; /* new record value, for caller */
- int optr; /* old ptr value */
- xfs_alloc_ptr_t *pp; /* pointer to btree addresses */
- int ptr; /* index in btree block for this rec */
- xfs_alloc_rec_t *rp; /* pointer to btree records */
-
- ASSERT(be32_to_cpu(recp->ar_blockcount) > 0);
-
- /*
- * GCC doesn't understand the (arguably complex) control flow in
- * this function and complains about uninitialized structure fields
- * without this.
- */
- memset(&nrec, 0, sizeof(nrec));
-
- /*
- * If we made it to the root level, allocate a new root block
- * and we're done.
- */
- if (level >= cur->bc_nlevels) {
- XFS_STATS_INC(xs_abt_insrec);
- if ((error = xfs_alloc_newroot(cur, &i)))
- return error;
- *bnop = NULLAGBLOCK;
- *stat = i;
- return 0;
- }
- /*
- * Make a key out of the record data to be inserted, and save it.
- */
- key.ar_startblock = recp->ar_startblock;
- key.ar_blockcount = recp->ar_blockcount;
- optr = ptr = cur->bc_ptrs[level];
- /*
- * If we're off the left edge, return failure.
- */
- if (ptr == 0) {
- *stat = 0;
- return 0;
- }
- XFS_STATS_INC(xs_abt_insrec);
- /*
- * Get pointers to the btree buffer and block.
- */
- bp = cur->bc_bufs[level];
- block = XFS_BUF_TO_ALLOC_BLOCK(bp);
-#ifdef DEBUG
- if ((error = xfs_btree_check_sblock(cur, block, level, bp)))
- return error;
- /*
- * Check that the new entry is being inserted in the right place.
- */
- if (ptr <= be16_to_cpu(block->bb_numrecs)) {
- if (level == 0) {
- rp = XFS_ALLOC_REC_ADDR(block, ptr, cur);
- xfs_btree_check_rec(cur->bc_btnum, recp, rp);
- } else {
- kp = XFS_ALLOC_KEY_ADDR(block, ptr, cur);
- xfs_btree_check_key(cur->bc_btnum, &key, kp);
- }
- }
-#endif
- nbno = NULLAGBLOCK;
- ncur = (xfs_btree_cur_t *)0;
- /*
- * If the block is full, we can't insert the new entry until we
- * make the block un-full.
- */
- if (be16_to_cpu(block->bb_numrecs) == XFS_ALLOC_BLOCK_MAXRECS(level, cur)) {
- /*
- * First, try shifting an entry to the right neighbor.
- */
- if ((error = xfs_alloc_rshift(cur, level, &i)))
- return error;
- if (i) {
- /* nothing */
- }
- /*
- * Next, try shifting an entry to the left neighbor.
- */
- else {
- if ((error = xfs_alloc_lshift(cur, level, &i)))
- return error;
- if (i)
- optr = ptr = cur->bc_ptrs[level];
- else {
- /*
- * Next, try splitting the current block in
- * half. If this works we have to re-set our
- * variables because we could be in a
- * different block now.
- */
- if ((error = xfs_alloc_split(cur, level, &nbno,
- &nkey, &ncur, &i)))
- return error;
- if (i) {
- bp = cur->bc_bufs[level];
- block = XFS_BUF_TO_ALLOC_BLOCK(bp);
-#ifdef DEBUG
- if ((error =
- xfs_btree_check_sblock(cur,
- block, level, bp)))
- return error;
-#endif
- ptr = cur->bc_ptrs[level];
- nrec.ar_startblock = nkey.ar_startblock;
- nrec.ar_blockcount = nkey.ar_blockcount;
- }
- /*
- * Otherwise the insert fails.
- */
- else {
- *stat = 0;
- return 0;
- }
- }
- }
- }
- /*
- * At this point we know there's room for our new entry in the block
- * we're pointing at.
- */
- if (level > 0) {
- /*
- * It's a non-leaf entry. Make a hole for the new data
- * in the key and ptr regions of the block.
- */
- kp = XFS_ALLOC_KEY_ADDR(block, 1, cur);
- pp = XFS_ALLOC_PTR_ADDR(block, 1, cur);
-#ifdef DEBUG
- for (i = be16_to_cpu(block->bb_numrecs); i >= ptr; i--) {
- if ((error = xfs_btree_check_sptr(cur, be32_to_cpu(pp[i - 1]), level)))
- return error;
- }
-#endif
- memmove(&kp[ptr], &kp[ptr - 1],
- (be16_to_cpu(block->bb_numrecs) - ptr + 1) * sizeof(*kp));
- memmove(&pp[ptr], &pp[ptr - 1],
- (be16_to_cpu(block->bb_numrecs) - ptr + 1) * sizeof(*pp));
-#ifdef DEBUG
- if ((error = xfs_btree_check_sptr(cur, *bnop, level)))
- return error;
-#endif
- /*
- * Now stuff the new data in, bump numrecs and log the new data.
- */
- kp[ptr - 1] = key;
- pp[ptr - 1] = cpu_to_be32(*bnop);
- be16_add(&block->bb_numrecs, 1);
- xfs_alloc_log_keys(cur, bp, ptr, be16_to_cpu(block->bb_numrecs));
- xfs_alloc_log_ptrs(cur, bp, ptr, be16_to_cpu(block->bb_numrecs));
-#ifdef DEBUG
- if (ptr < be16_to_cpu(block->bb_numrecs))
- xfs_btree_check_key(cur->bc_btnum, kp + ptr - 1,
- kp + ptr);
-#endif
- } else {
- /*
- * It's a leaf entry. Make a hole for the new record.
- */
- rp = XFS_ALLOC_REC_ADDR(block, 1, cur);
- memmove(&rp[ptr], &rp[ptr - 1],
- (be16_to_cpu(block->bb_numrecs) - ptr + 1) * sizeof(*rp));
- /*
- * Now stuff the new record in, bump numrecs
- * and log the new data.
- */
- rp[ptr - 1] = *recp; /* INT_: struct copy */
- be16_add(&block->bb_numrecs, 1);
- xfs_alloc_log_recs(cur, bp, ptr, be16_to_cpu(block->bb_numrecs));
-#ifdef DEBUG
- if (ptr < be16_to_cpu(block->bb_numrecs))
- xfs_btree_check_rec(cur->bc_btnum, rp + ptr - 1,
- rp + ptr);
-#endif
- }
- /*
- * Log the new number of records in the btree header.
- */
- xfs_alloc_log_block(cur->bc_tp, bp, XFS_BB_NUMRECS);
- /*
- * If we inserted at the start of a block, update the parents' keys.
- */
- if (optr == 1 && (error = xfs_alloc_updkey(cur, &key, level + 1)))
- return error;
- /*
- * Look to see if the longest extent in the allocation group
- * needs to be updated.
- */
-
- agf = XFS_BUF_TO_AGF(cur->bc_private.a.agbp);
- if (level == 0 &&
- cur->bc_btnum == XFS_BTNUM_CNT &&
- be32_to_cpu(block->bb_rightsib) == NULLAGBLOCK &&
- be32_to_cpu(recp->ar_blockcount) > be32_to_cpu(agf->agf_longest)) {
- /*
- * If this is a leaf in the by-size btree and there
- * is no right sibling block and this block is bigger
- * than the previous longest block, update it.
- */
- agf->agf_longest = recp->ar_blockcount;
- cur->bc_mp->m_perag[be32_to_cpu(agf->agf_seqno)].pagf_longest
- = be32_to_cpu(recp->ar_blockcount);
- xfs_alloc_log_agf(cur->bc_tp, cur->bc_private.a.agbp,
- XFS_AGF_LONGEST);
- }
- /*
- * Return the new block number, if any.
- * If there is one, give back a record value and a cursor too.
- */
- *bnop = nbno;
- if (nbno != NULLAGBLOCK) {
- *recp = nrec; /* INT_: struct copy */
- *curp = ncur; /* INT_: struct copy */
- }
- *stat = 1;
- return 0;
-}
-
-/*
- * Log header fields from a btree block.
- */
-STATIC void
-xfs_alloc_log_block(
- xfs_trans_t *tp, /* transaction pointer */
- xfs_buf_t *bp, /* buffer containing btree block */
- int fields) /* mask of fields: XFS_BB_... */
-{
- int first; /* first byte offset logged */
- int last; /* last byte offset logged */
- static const short offsets[] = { /* table of offsets */
- offsetof(xfs_alloc_block_t, bb_magic),
- offsetof(xfs_alloc_block_t, bb_level),
- offsetof(xfs_alloc_block_t, bb_numrecs),
- offsetof(xfs_alloc_block_t, bb_leftsib),
- offsetof(xfs_alloc_block_t, bb_rightsib),
- sizeof(xfs_alloc_block_t)
- };
-
- xfs_btree_offsets(fields, offsets, XFS_BB_NUM_BITS, &first, &last);
- xfs_trans_log_buf(tp, bp, first, last);
-}
-
-/*
- * Log keys from a btree block (nonleaf).
- */
-STATIC void
-xfs_alloc_log_keys(
- xfs_btree_cur_t *cur, /* btree cursor */
- xfs_buf_t *bp, /* buffer containing btree block */
- int kfirst, /* index of first key to log */
- int klast) /* index of last key to log */
-{
- xfs_alloc_block_t *block; /* btree block to log from */
- int first; /* first byte offset logged */
- xfs_alloc_key_t *kp; /* key pointer in btree block */
- int last; /* last byte offset logged */
-
- block = XFS_BUF_TO_ALLOC_BLOCK(bp);
- kp = XFS_ALLOC_KEY_ADDR(block, 1, cur);
- first = (int)((xfs_caddr_t)&kp[kfirst - 1] - (xfs_caddr_t)block);
- last = (int)(((xfs_caddr_t)&kp[klast] - 1) - (xfs_caddr_t)block);
- xfs_trans_log_buf(cur->bc_tp, bp, first, last);
-}
-
-/*
- * Log block pointer fields from a btree block (nonleaf).
- */
-STATIC void
-xfs_alloc_log_ptrs(
- xfs_btree_cur_t *cur, /* btree cursor */
- xfs_buf_t *bp, /* buffer containing btree block */
- int pfirst, /* index of first pointer to log */
- int plast) /* index of last pointer to log */
-{
- xfs_alloc_block_t *block; /* btree block to log from */
- int first; /* first byte offset logged */
- int last; /* last byte offset logged */
- xfs_alloc_ptr_t *pp; /* block-pointer pointer in btree blk */
-
- block = XFS_BUF_TO_ALLOC_BLOCK(bp);
- pp = XFS_ALLOC_PTR_ADDR(block, 1, cur);
- first = (int)((xfs_caddr_t)&pp[pfirst - 1] - (xfs_caddr_t)block);
- last = (int)(((xfs_caddr_t)&pp[plast] - 1) - (xfs_caddr_t)block);
- xfs_trans_log_buf(cur->bc_tp, bp, first, last);
-}
-
-/*
- * Log records from a btree block (leaf).
- */
-STATIC void
-xfs_alloc_log_recs(
- xfs_btree_cur_t *cur, /* btree cursor */
- xfs_buf_t *bp, /* buffer containing btree block */
- int rfirst, /* index of first record to log */
- int rlast) /* index of last record to log */
-{
- xfs_alloc_block_t *block; /* btree block to log from */
- int first; /* first byte offset logged */
- int last; /* last byte offset logged */
- xfs_alloc_rec_t *rp; /* record pointer for btree block */
-
-
- block = XFS_BUF_TO_ALLOC_BLOCK(bp);
- rp = XFS_ALLOC_REC_ADDR(block, 1, cur);
-#ifdef DEBUG
- {
- xfs_agf_t *agf;
- xfs_alloc_rec_t *p;
-
- agf = XFS_BUF_TO_AGF(cur->bc_private.a.agbp);
- for (p = &rp[rfirst - 1]; p <= &rp[rlast - 1]; p++)
- ASSERT(be32_to_cpu(p->ar_startblock) +
- be32_to_cpu(p->ar_blockcount) <=
- be32_to_cpu(agf->agf_length));
- }
-#endif
- first = (int)((xfs_caddr_t)&rp[rfirst - 1] - (xfs_caddr_t)block);
- last = (int)(((xfs_caddr_t)&rp[rlast] - 1) - (xfs_caddr_t)block);
- xfs_trans_log_buf(cur->bc_tp, bp, first, last);
-}
-
-/*
- * Lookup the record. The cursor is made to point to it, based on dir.
- * Return 0 if can't find any such record, 1 for success.
- */
-STATIC int /* error */
-xfs_alloc_lookup(
- xfs_btree_cur_t *cur, /* btree cursor */
- xfs_lookup_t dir, /* <=, ==, or >= */
- int *stat) /* success/failure */
-{
- xfs_agblock_t agbno; /* a.g. relative btree block number */
- xfs_agnumber_t agno; /* allocation group number */
- xfs_alloc_block_t *block=NULL; /* current btree block */
- int diff; /* difference for the current key */
- int error; /* error return value */
- int keyno=0; /* current key number */
- int level; /* level in the btree */
- xfs_mount_t *mp; /* file system mount point */
-
- XFS_STATS_INC(xs_abt_lookup);
- /*
- * Get the allocation group header, and the root block number.
- */
- mp = cur->bc_mp;
-
- {
- xfs_agf_t *agf; /* a.g. freespace header */
-
- agf = XFS_BUF_TO_AGF(cur->bc_private.a.agbp);
- agno = be32_to_cpu(agf->agf_seqno);
- agbno = be32_to_cpu(agf->agf_roots[cur->bc_btnum]);
- }
- /*
- * Iterate over each level in the btree, starting at the root.
- * For each level above the leaves, find the key we need, based
- * on the lookup record, then follow the corresponding block
- * pointer down to the next level.
- */
- for (level = cur->bc_nlevels - 1, diff = 1; level >= 0; level--) {
- xfs_buf_t *bp; /* buffer pointer for btree block */
- xfs_daddr_t d; /* disk address of btree block */
-
- /*
- * Get the disk address we're looking for.
- */
- d = XFS_AGB_TO_DADDR(mp, agno, agbno);
- /*
- * If the old buffer at this level is for a different block,
- * throw it away, otherwise just use it.
- */
- bp = cur->bc_bufs[level];
- if (bp && XFS_BUF_ADDR(bp) != d)
- bp = (xfs_buf_t *)0;
- if (!bp) {
- /*
- * Need to get a new buffer. Read it, then
- * set it in the cursor, releasing the old one.
- */
- if ((error = xfs_btree_read_bufs(mp, cur->bc_tp, agno,
- agbno, 0, &bp, XFS_ALLOC_BTREE_REF)))
- return error;
- xfs_btree_setbuf(cur, level, bp);
- /*
- * Point to the btree block, now that we have the buffer
- */
- block = XFS_BUF_TO_ALLOC_BLOCK(bp);
- if ((error = xfs_btree_check_sblock(cur, block, level,
- bp)))
- return error;
- } else
- block = XFS_BUF_TO_ALLOC_BLOCK(bp);
- /*
- * If we already had a key match at a higher level, we know
- * we need to use the first entry in this block.
- */
- if (diff == 0)
- keyno = 1;
- /*
- * Otherwise we need to search this block. Do a binary search.
- */
- else {
- int high; /* high entry number */
- xfs_alloc_key_t *kkbase=NULL;/* base of keys in block */
- xfs_alloc_rec_t *krbase=NULL;/* base of records in block */
- int low; /* low entry number */
-
- /*
- * Get a pointer to keys or records.
- */
- if (level > 0)
- kkbase = XFS_ALLOC_KEY_ADDR(block, 1, cur);
- else
- krbase = XFS_ALLOC_REC_ADDR(block, 1, cur);
- /*
- * Set low and high entry numbers, 1-based.
- */
- low = 1;
- if (!(high = be16_to_cpu(block->bb_numrecs))) {
- /*
- * If the block is empty, the tree must
- * be an empty leaf.
- */
- ASSERT(level == 0 && cur->bc_nlevels == 1);
- cur->bc_ptrs[0] = dir != XFS_LOOKUP_LE;
- *stat = 0;
- return 0;
- }
- /*
- * Binary search the block.
- */
- while (low <= high) {
- xfs_extlen_t blockcount; /* key value */
- xfs_agblock_t startblock; /* key value */
-
- XFS_STATS_INC(xs_abt_compare);
- /*
- * keyno is average of low and high.
- */
- keyno = (low + high) >> 1;
- /*
- * Get startblock & blockcount.
- */
- if (level > 0) {
- xfs_alloc_key_t *kkp;
-
- kkp = kkbase + keyno - 1;
- startblock = be32_to_cpu(kkp->ar_startblock);
- blockcount = be32_to_cpu(kkp->ar_blockcount);
- } else {
- xfs_alloc_rec_t *krp;
-
- krp = krbase + keyno - 1;
- startblock = be32_to_cpu(krp->ar_startblock);
- blockcount = be32_to_cpu(krp->ar_blockcount);
- }
- /*
- * Compute difference to get next direction.
- */
- if (cur->bc_btnum == XFS_BTNUM_BNO)
- diff = (int)startblock -
- (int)cur->bc_rec.a.ar_startblock;
- else if (!(diff = (int)blockcount -
- (int)cur->bc_rec.a.ar_blockcount))
- diff = (int)startblock -
- (int)cur->bc_rec.a.ar_startblock;
- /*
- * Less than, move right.
- */
- if (diff < 0)
- low = keyno + 1;
- /*
- * Greater than, move left.
- */
- else if (diff > 0)
- high = keyno - 1;
- /*
- * Equal, we're done.
- */
- else
- break;
- }
- }
- /*
- * If there are more levels, set up for the next level
- * by getting the block number and filling in the cursor.
- */
- if (level > 0) {
- /*
- * If we moved left, need the previous key number,
- * unless there isn't one.
- */
- if (diff > 0 && --keyno < 1)
- keyno = 1;
- agbno = be32_to_cpu(*XFS_ALLOC_PTR_ADDR(block, keyno, cur));
-#ifdef DEBUG
- if ((error = xfs_btree_check_sptr(cur, agbno, level)))
- return error;
-#endif
- cur->bc_ptrs[level] = keyno;
- }
- }
- /*
- * Done with the search.
- * See if we need to adjust the results.
- */
- if (dir != XFS_LOOKUP_LE && diff < 0) {
- keyno++;
- /*
- * If ge search and we went off the end of the block, but it's
- * not the last block, we're in the wrong block.
- */
- if (dir == XFS_LOOKUP_GE &&
- keyno > be16_to_cpu(block->bb_numrecs) &&
- be32_to_cpu(block->bb_rightsib) != NULLAGBLOCK) {
- int i;
-
- cur->bc_ptrs[0] = keyno;
- if ((error = xfs_alloc_increment(cur, 0, &i)))
- return error;
- XFS_WANT_CORRUPTED_RETURN(i == 1);
- *stat = 1;
- return 0;
- }
- }
- else if (dir == XFS_LOOKUP_LE && diff > 0)
- keyno--;
- cur->bc_ptrs[0] = keyno;
- /*
- * Return if we succeeded or not.
- */
- if (keyno == 0 || keyno > be16_to_cpu(block->bb_numrecs))
- *stat = 0;
- else
- *stat = ((dir != XFS_LOOKUP_EQ) || (diff == 0));
- return 0;
-}
-
-/*
- * Move 1 record left from cur/level if possible.
- * Update cur to reflect the new path.
- */
-STATIC int /* error */
-xfs_alloc_lshift(
- xfs_btree_cur_t *cur, /* btree cursor */
- int level, /* level to shift record on */
- int *stat) /* success/failure */
-{
- int error; /* error return value */
-#ifdef DEBUG
- int i; /* loop index */
-#endif
- xfs_alloc_key_t key; /* key value for leaf level upward */
- xfs_buf_t *lbp; /* buffer for left neighbor block */
- xfs_alloc_block_t *left; /* left neighbor btree block */
- int nrec; /* new number of left block entries */
- xfs_buf_t *rbp; /* buffer for right (current) block */
- xfs_alloc_block_t *right; /* right (current) btree block */
- xfs_alloc_key_t *rkp=NULL; /* key pointer for right block */
- xfs_alloc_ptr_t *rpp=NULL; /* address pointer for right block */
- xfs_alloc_rec_t *rrp=NULL; /* record pointer for right block */
-
- /*
- * Set up variables for this block as "right".
- */
- rbp = cur->bc_bufs[level];
- right = XFS_BUF_TO_ALLOC_BLOCK(rbp);
-#ifdef DEBUG
- if ((error = xfs_btree_check_sblock(cur, right, level, rbp)))
- return error;
-#endif
- /*
- * If we've got no left sibling then we can't shift an entry left.
- */
- if (be32_to_cpu(right->bb_leftsib) == NULLAGBLOCK) {
- *stat = 0;
- return 0;
- }
- /*
- * If the cursor entry is the one that would be moved, don't
- * do it... it's too complicated.
- */
- if (cur->bc_ptrs[level] <= 1) {
- *stat = 0;
- return 0;
- }
- /*
- * Set up the left neighbor as "left".
- */
- if ((error = xfs_btree_read_bufs(cur->bc_mp, cur->bc_tp,
- cur->bc_private.a.agno, be32_to_cpu(right->bb_leftsib),
- 0, &lbp, XFS_ALLOC_BTREE_REF)))
- return error;
- left = XFS_BUF_TO_ALLOC_BLOCK(lbp);
- if ((error = xfs_btree_check_sblock(cur, left, level, lbp)))
- return error;
- /*
- * If it's full, it can't take another entry.
- */
- if (be16_to_cpu(left->bb_numrecs) == XFS_ALLOC_BLOCK_MAXRECS(level, cur)) {
- *stat = 0;
- return 0;
- }
- nrec = be16_to_cpu(left->bb_numrecs) + 1;
- /*
- * If non-leaf, copy a key and a ptr to the left block.
- */
- if (level > 0) {
- xfs_alloc_key_t *lkp; /* key pointer for left block */
- xfs_alloc_ptr_t *lpp; /* address pointer for left block */
-
- lkp = XFS_ALLOC_KEY_ADDR(left, nrec, cur);
- rkp = XFS_ALLOC_KEY_ADDR(right, 1, cur);
- *lkp = *rkp;
- xfs_alloc_log_keys(cur, lbp, nrec, nrec);
- lpp = XFS_ALLOC_PTR_ADDR(left, nrec, cur);
- rpp = XFS_ALLOC_PTR_ADDR(right, 1, cur);
-#ifdef DEBUG
- if ((error = xfs_btree_check_sptr(cur, be32_to_cpu(*rpp), level)))
- return error;
-#endif
- *lpp = *rpp; /* INT_: copy */
- xfs_alloc_log_ptrs(cur, lbp, nrec, nrec);
- xfs_btree_check_key(cur->bc_btnum, lkp - 1, lkp);
- }
- /*
- * If leaf, copy a record to the left block.
- */
- else {
- xfs_alloc_rec_t *lrp; /* record pointer for left block */
-
- lrp = XFS_ALLOC_REC_ADDR(left, nrec, cur);
- rrp = XFS_ALLOC_REC_ADDR(right, 1, cur);
- *lrp = *rrp;
- xfs_alloc_log_recs(cur, lbp, nrec, nrec);
- xfs_btree_check_rec(cur->bc_btnum, lrp - 1, lrp);
- }
- /*
- * Bump and log left's numrecs, decrement and log right's numrecs.
- */
- be16_add(&left->bb_numrecs, 1);
- xfs_alloc_log_block(cur->bc_tp, lbp, XFS_BB_NUMRECS);
- be16_add(&right->bb_numrecs, -1);
- xfs_alloc_log_block(cur->bc_tp, rbp, XFS_BB_NUMRECS);
- /*
- * Slide the contents of right down one entry.
- */
- if (level > 0) {
-#ifdef DEBUG
- for (i = 0; i < be16_to_cpu(right->bb_numrecs); i++) {
- if ((error = xfs_btree_check_sptr(cur, be32_to_cpu(rpp[i + 1]),
- level)))
- return error;
- }
-#endif
- memmove(rkp, rkp + 1, be16_to_cpu(right->bb_numrecs) * sizeof(*rkp));
- memmove(rpp, rpp + 1, be16_to_cpu(right->bb_numrecs) * sizeof(*rpp));
- xfs_alloc_log_keys(cur, rbp, 1, be16_to_cpu(right->bb_numrecs));
- xfs_alloc_log_ptrs(cur, rbp, 1, be16_to_cpu(right->bb_numrecs));
- } else {
- memmove(rrp, rrp + 1, be16_to_cpu(right->bb_numrecs) * sizeof(*rrp));
- xfs_alloc_log_recs(cur, rbp, 1, be16_to_cpu(right->bb_numrecs));
- key.ar_startblock = rrp->ar_startblock;
- key.ar_blockcount = rrp->ar_blockcount;
- rkp = &key;
- }
- /*
- * Update the parent key values of right.
- */
- if ((error = xfs_alloc_updkey(cur, rkp, level + 1)))
- return error;
- /*
- * Slide the cursor value left one.
- */
- cur->bc_ptrs[level]--;
- *stat = 1;
- return 0;
-}
-
-/*
- * Allocate a new root block, fill it in.
- */
-STATIC int /* error */
-xfs_alloc_newroot(
- xfs_btree_cur_t *cur, /* btree cursor */
- int *stat) /* success/failure */
-{
- int error; /* error return value */
- xfs_agblock_t lbno; /* left block number */
- xfs_buf_t *lbp; /* left btree buffer */
- xfs_alloc_block_t *left; /* left btree block */
- xfs_mount_t *mp; /* mount structure */
- xfs_agblock_t nbno; /* new block number */
- xfs_buf_t *nbp; /* new (root) buffer */
- xfs_alloc_block_t *new; /* new (root) btree block */
- int nptr; /* new value for key index, 1 or 2 */
- xfs_agblock_t rbno; /* right block number */
- xfs_buf_t *rbp; /* right btree buffer */
- xfs_alloc_block_t *right; /* right btree block */
-
- mp = cur->bc_mp;
-
- ASSERT(cur->bc_nlevels < XFS_AG_MAXLEVELS(mp));
- /*
- * Get a buffer from the freelist blocks, for the new root.
- */
- if ((error = xfs_alloc_get_freelist(cur->bc_tp, cur->bc_private.a.agbp,
- &nbno)))
- return error;
- /*
- * None available, we fail.
- */
- if (nbno == NULLAGBLOCK) {
- *stat = 0;
- return 0;
- }
- xfs_trans_agbtree_delta(cur->bc_tp, 1);
- nbp = xfs_btree_get_bufs(mp, cur->bc_tp, cur->bc_private.a.agno, nbno,
- 0);
- new = XFS_BUF_TO_ALLOC_BLOCK(nbp);
- /*
- * Set the root data in the a.g. freespace structure.
- */
- {
- xfs_agf_t *agf; /* a.g. freespace header */
- xfs_agnumber_t seqno;
-
- agf = XFS_BUF_TO_AGF(cur->bc_private.a.agbp);
- agf->agf_roots[cur->bc_btnum] = cpu_to_be32(nbno);
- be32_add(&agf->agf_levels[cur->bc_btnum], 1);
- seqno = be32_to_cpu(agf->agf_seqno);
- mp->m_perag[seqno].pagf_levels[cur->bc_btnum]++;
- xfs_alloc_log_agf(cur->bc_tp, cur->bc_private.a.agbp,
- XFS_AGF_ROOTS | XFS_AGF_LEVELS);
- }
- /*
- * At the previous root level there are now two blocks: the old
- * root, and the new block generated when it was split.
- * We don't know which one the cursor is pointing at, so we
- * set up variables "left" and "right" for each case.
- */
- lbp = cur->bc_bufs[cur->bc_nlevels - 1];
- left = XFS_BUF_TO_ALLOC_BLOCK(lbp);
-#ifdef DEBUG
- if ((error = xfs_btree_check_sblock(cur, left, cur->bc_nlevels - 1, lbp)))
- return error;
-#endif
- if (be32_to_cpu(left->bb_rightsib) != NULLAGBLOCK) {
- /*
- * Our block is left, pick up the right block.
- */
- lbno = XFS_DADDR_TO_AGBNO(mp, XFS_BUF_ADDR(lbp));
- rbno = be32_to_cpu(left->bb_rightsib);
- if ((error = xfs_btree_read_bufs(mp, cur->bc_tp,
- cur->bc_private.a.agno, rbno, 0, &rbp,
- XFS_ALLOC_BTREE_REF)))
- return error;
- right = XFS_BUF_TO_ALLOC_BLOCK(rbp);
- if ((error = xfs_btree_check_sblock(cur, right,
- cur->bc_nlevels - 1, rbp)))
- return error;
- nptr = 1;
- } else {
- /*
- * Our block is right, pick up the left block.
- */
- rbp = lbp;
- right = left;
- rbno = XFS_DADDR_TO_AGBNO(mp, XFS_BUF_ADDR(rbp));
- lbno = be32_to_cpu(right->bb_leftsib);
- if ((error = xfs_btree_read_bufs(mp, cur->bc_tp,
- cur->bc_private.a.agno, lbno, 0, &lbp,
- XFS_ALLOC_BTREE_REF)))
- return error;
- left = XFS_BUF_TO_ALLOC_BLOCK(lbp);
- if ((error = xfs_btree_check_sblock(cur, left,
- cur->bc_nlevels - 1, lbp)))
- return error;
- nptr = 2;
- }
- /*
- * Fill in the new block's btree header and log it.
- */
- new->bb_magic = cpu_to_be32(xfs_magics[cur->bc_btnum]);
- new->bb_level = cpu_to_be16(cur->bc_nlevels);
- new->bb_numrecs = cpu_to_be16(2);
- new->bb_leftsib = cpu_to_be32(NULLAGBLOCK);
- new->bb_rightsib = cpu_to_be32(NULLAGBLOCK);
- xfs_alloc_log_block(cur->bc_tp, nbp, XFS_BB_ALL_BITS);
- ASSERT(lbno != NULLAGBLOCK && rbno != NULLAGBLOCK);
- /*
- * Fill in the key data in the new root.
- */
- {
- xfs_alloc_key_t *kp; /* btree key pointer */
-
- kp = XFS_ALLOC_KEY_ADDR(new, 1, cur);
- if (be16_to_cpu(left->bb_level) > 0) {
- kp[0] = *XFS_ALLOC_KEY_ADDR(left, 1, cur); /* INT_: structure copy */
- kp[1] = *XFS_ALLOC_KEY_ADDR(right, 1, cur);/* INT_: structure copy */
- } else {
- xfs_alloc_rec_t *rp; /* btree record pointer */
-
- rp = XFS_ALLOC_REC_ADDR(left, 1, cur);
- kp[0].ar_startblock = rp->ar_startblock;
- kp[0].ar_blockcount = rp->ar_blockcount;
- rp = XFS_ALLOC_REC_ADDR(right, 1, cur);
- kp[1].ar_startblock = rp->ar_startblock;
- kp[1].ar_blockcount = rp->ar_blockcount;
- }
- }
- xfs_alloc_log_keys(cur, nbp, 1, 2);
- /*
- * Fill in the pointer data in the new root.
- */
- {
- xfs_alloc_ptr_t *pp; /* btree address pointer */
-
- pp = XFS_ALLOC_PTR_ADDR(new, 1, cur);
- pp[0] = cpu_to_be32(lbno);
- pp[1] = cpu_to_be32(rbno);
- }
- xfs_alloc_log_ptrs(cur, nbp, 1, 2);
- /*
- * Fix up the cursor.
- */
- xfs_btree_setbuf(cur, cur->bc_nlevels, nbp);
- cur->bc_ptrs[cur->bc_nlevels] = nptr;
- cur->bc_nlevels++;
- *stat = 1;
- return 0;
-}
-
-/*
- * Move 1 record right from cur/level if possible.
- * Update cur to reflect the new path.
- */
-STATIC int /* error */
-xfs_alloc_rshift(
- xfs_btree_cur_t *cur, /* btree cursor */
- int level, /* level to shift record on */
- int *stat) /* success/failure */
-{
- int error; /* error return value */
- int i; /* loop index */
- xfs_alloc_key_t key; /* key value for leaf level upward */
- xfs_buf_t *lbp; /* buffer for left (current) block */
- xfs_alloc_block_t *left; /* left (current) btree block */
- xfs_buf_t *rbp; /* buffer for right neighbor block */
- xfs_alloc_block_t *right; /* right neighbor btree block */
- xfs_alloc_key_t *rkp; /* key pointer for right block */
- xfs_btree_cur_t *tcur; /* temporary cursor */
-
- /*
- * Set up variables for this block as "left".
- */
- lbp = cur->bc_bufs[level];
- left = XFS_BUF_TO_ALLOC_BLOCK(lbp);
-#ifdef DEBUG
- if ((error = xfs_btree_check_sblock(cur, left, level, lbp)))
- return error;
-#endif
- /*
- * If we've got no right sibling then we can't shift an entry right.
- */
- if (be32_to_cpu(left->bb_rightsib) == NULLAGBLOCK) {
- *stat = 0;
- return 0;
- }
- /*
- * If the cursor entry is the one that would be moved, don't
- * do it... it's too complicated.
- */
- if (cur->bc_ptrs[level] >= be16_to_cpu(left->bb_numrecs)) {
- *stat = 0;
- return 0;
- }
- /*
- * Set up the right neighbor as "right".
- */
- if ((error = xfs_btree_read_bufs(cur->bc_mp, cur->bc_tp,
- cur->bc_private.a.agno, be32_to_cpu(left->bb_rightsib),
- 0, &rbp, XFS_ALLOC_BTREE_REF)))
- return error;
- right = XFS_BUF_TO_ALLOC_BLOCK(rbp);
- if ((error = xfs_btree_check_sblock(cur, right, level, rbp)))
- return error;
- /*
- * If it's full, it can't take another entry.
- */
- if (be16_to_cpu(right->bb_numrecs) == XFS_ALLOC_BLOCK_MAXRECS(level, cur)) {
- *stat = 0;
- return 0;
- }
- /*
- * Make a hole at the start of the right neighbor block, then
- * copy the last left block entry to the hole.
- */
- if (level > 0) {
- xfs_alloc_key_t *lkp; /* key pointer for left block */
- xfs_alloc_ptr_t *lpp; /* address pointer for left block */
- xfs_alloc_ptr_t *rpp; /* address pointer for right block */
-
- lkp = XFS_ALLOC_KEY_ADDR(left, be16_to_cpu(left->bb_numrecs), cur);
- lpp = XFS_ALLOC_PTR_ADDR(left, be16_to_cpu(left->bb_numrecs), cur);
- rkp = XFS_ALLOC_KEY_ADDR(right, 1, cur);
- rpp = XFS_ALLOC_PTR_ADDR(right, 1, cur);
-#ifdef DEBUG
- for (i = be16_to_cpu(right->bb_numrecs) - 1; i >= 0; i--) {
- if ((error = xfs_btree_check_sptr(cur, be32_to_cpu(rpp[i]), level)))
- return error;
- }
-#endif
- memmove(rkp + 1, rkp, be16_to_cpu(right->bb_numrecs) * sizeof(*rkp));
- memmove(rpp + 1, rpp, be16_to_cpu(right->bb_numrecs) * sizeof(*rpp));
-#ifdef DEBUG
- if ((error = xfs_btree_check_sptr(cur, be32_to_cpu(*lpp), level)))
- return error;
-#endif
- *rkp = *lkp; /* INT_: copy */
- *rpp = *lpp; /* INT_: copy */
- xfs_alloc_log_keys(cur, rbp, 1, be16_to_cpu(right->bb_numrecs) + 1);
- xfs_alloc_log_ptrs(cur, rbp, 1, be16_to_cpu(right->bb_numrecs) + 1);
- xfs_btree_check_key(cur->bc_btnum, rkp, rkp + 1);
- } else {
- xfs_alloc_rec_t *lrp; /* record pointer for left block */
- xfs_alloc_rec_t *rrp; /* record pointer for right block */
-
- lrp = XFS_ALLOC_REC_ADDR(left, be16_to_cpu(left->bb_numrecs), cur);
- rrp = XFS_ALLOC_REC_ADDR(right, 1, cur);
- memmove(rrp + 1, rrp, be16_to_cpu(right->bb_numrecs) * sizeof(*rrp));
- *rrp = *lrp;
- xfs_alloc_log_recs(cur, rbp, 1, be16_to_cpu(right->bb_numrecs) + 1);
- key.ar_startblock = rrp->ar_startblock;
- key.ar_blockcount = rrp->ar_blockcount;
- rkp = &key;
- xfs_btree_check_rec(cur->bc_btnum, rrp, rrp + 1);
- }
- /*
- * Decrement and log left's numrecs, bump and log right's numrecs.
- */
- be16_add(&left->bb_numrecs, -1);
- xfs_alloc_log_block(cur->bc_tp, lbp, XFS_BB_NUMRECS);
- be16_add(&right->bb_numrecs, 1);
- xfs_alloc_log_block(cur->bc_tp, rbp, XFS_BB_NUMRECS);
- /*
- * Using a temporary cursor, update the parent key values of the
- * block on the right.
- */
- if ((error = xfs_btree_dup_cursor(cur, &tcur)))
- return error;
- i = xfs_btree_lastrec(tcur, level);
- XFS_WANT_CORRUPTED_GOTO(i == 1, error0);
- if ((error = xfs_alloc_increment(tcur, level, &i)) ||
- (error = xfs_alloc_updkey(tcur, rkp, level + 1)))
- goto error0;
- xfs_btree_del_cursor(tcur, XFS_BTREE_NOERROR);
- *stat = 1;
- return 0;
-error0:
- xfs_btree_del_cursor(tcur, XFS_BTREE_ERROR);
- return error;
-}
-
-/*
- * Split cur/level block in half.
- * Return new block number and its first record (to be inserted into parent).
- */
-STATIC int /* error */
-xfs_alloc_split(
- xfs_btree_cur_t *cur, /* btree cursor */
- int level, /* level to split */
- xfs_agblock_t *bnop, /* output: block number allocated */
- xfs_alloc_key_t *keyp, /* output: first key of new block */
- xfs_btree_cur_t **curp, /* output: new cursor */
- int *stat) /* success/failure */
-{
- int error; /* error return value */
- int i; /* loop index/record number */
- xfs_agblock_t lbno; /* left (current) block number */
- xfs_buf_t *lbp; /* buffer for left block */
- xfs_alloc_block_t *left; /* left (current) btree block */
- xfs_agblock_t rbno; /* right (new) block number */
- xfs_buf_t *rbp; /* buffer for right block */
- xfs_alloc_block_t *right; /* right (new) btree block */
-
- /*
- * Allocate the new block from the freelist.
- * If we can't do it, we're toast. Give up.
- */
- if ((error = xfs_alloc_get_freelist(cur->bc_tp, cur->bc_private.a.agbp,
- &rbno)))
- return error;
- if (rbno == NULLAGBLOCK) {
- *stat = 0;
- return 0;
- }
- xfs_trans_agbtree_delta(cur->bc_tp, 1);
- rbp = xfs_btree_get_bufs(cur->bc_mp, cur->bc_tp, cur->bc_private.a.agno,
- rbno, 0);
- /*
- * Set up the new block as "right".
- */
- right = XFS_BUF_TO_ALLOC_BLOCK(rbp);
- /*
- * "Left" is the current (according to the cursor) block.
- */
- lbp = cur->bc_bufs[level];
- left = XFS_BUF_TO_ALLOC_BLOCK(lbp);
-#ifdef DEBUG
- if ((error = xfs_btree_check_sblock(cur, left, level, lbp)))
- return error;
-#endif
- /*
- * Fill in the btree header for the new block.
- */
- right->bb_magic = cpu_to_be32(xfs_magics[cur->bc_btnum]);
- right->bb_level = left->bb_level;
- right->bb_numrecs = cpu_to_be16(be16_to_cpu(left->bb_numrecs) / 2);
- /*
- * Make sure that if there's an odd number of entries now, that
- * each new block will have the same number of entries.
- */
- if ((be16_to_cpu(left->bb_numrecs) & 1) &&
- cur->bc_ptrs[level] <= be16_to_cpu(right->bb_numrecs) + 1)
- be16_add(&right->bb_numrecs, 1);
- i = be16_to_cpu(left->bb_numrecs) - be16_to_cpu(right->bb_numrecs) + 1;
- /*
- * For non-leaf blocks, copy keys and addresses over to the new block.
- */
- if (level > 0) {
- xfs_alloc_key_t *lkp; /* left btree key pointer */
- xfs_alloc_ptr_t *lpp; /* left btree address pointer */
- xfs_alloc_key_t *rkp; /* right btree key pointer */
- xfs_alloc_ptr_t *rpp; /* right btree address pointer */
-
- lkp = XFS_ALLOC_KEY_ADDR(left, i, cur);
- lpp = XFS_ALLOC_PTR_ADDR(left, i, cur);
- rkp = XFS_ALLOC_KEY_ADDR(right, 1, cur);
- rpp = XFS_ALLOC_PTR_ADDR(right, 1, cur);
-#ifdef DEBUG
- for (i = 0; i < be16_to_cpu(right->bb_numrecs); i++) {
- if ((error = xfs_btree_check_sptr(cur, be32_to_cpu(lpp[i]), level)))
- return error;
- }
-#endif
- memcpy(rkp, lkp, be16_to_cpu(right->bb_numrecs) * sizeof(*rkp));
- memcpy(rpp, lpp, be16_to_cpu(right->bb_numrecs) * sizeof(*rpp));
- xfs_alloc_log_keys(cur, rbp, 1, be16_to_cpu(right->bb_numrecs));
- xfs_alloc_log_ptrs(cur, rbp, 1, be16_to_cpu(right->bb_numrecs));
- *keyp = *rkp;
- }
- /*
- * For leaf blocks, copy records over to the new block.
- */
- else {
- xfs_alloc_rec_t *lrp; /* left btree record pointer */
- xfs_alloc_rec_t *rrp; /* right btree record pointer */
-
- lrp = XFS_ALLOC_REC_ADDR(left, i, cur);
- rrp = XFS_ALLOC_REC_ADDR(right, 1, cur);
- memcpy(rrp, lrp, be16_to_cpu(right->bb_numrecs) * sizeof(*rrp));
- xfs_alloc_log_recs(cur, rbp, 1, be16_to_cpu(right->bb_numrecs));
- keyp->ar_startblock = rrp->ar_startblock;
- keyp->ar_blockcount = rrp->ar_blockcount;
- }
- /*
- * Find the left block number by looking in the buffer.
- * Adjust numrecs, sibling pointers.
- */
- lbno = XFS_DADDR_TO_AGBNO(cur->bc_mp, XFS_BUF_ADDR(lbp));
- be16_add(&left->bb_numrecs, -(be16_to_cpu(right->bb_numrecs)));
- right->bb_rightsib = left->bb_rightsib;
- left->bb_rightsib = cpu_to_be32(rbno);
- right->bb_leftsib = cpu_to_be32(lbno);
- xfs_alloc_log_block(cur->bc_tp, rbp, XFS_BB_ALL_BITS);
- xfs_alloc_log_block(cur->bc_tp, lbp, XFS_BB_NUMRECS | XFS_BB_RIGHTSIB);
- /*
- * If there's a block to the new block's right, make that block
- * point back to right instead of to left.
- */
- if (be32_to_cpu(right->bb_rightsib) != NULLAGBLOCK) {
- xfs_alloc_block_t *rrblock; /* rr btree block */
- xfs_buf_t *rrbp; /* buffer for rrblock */
-
- if ((error = xfs_btree_read_bufs(cur->bc_mp, cur->bc_tp,
- cur->bc_private.a.agno, be32_to_cpu(right->bb_rightsib), 0,
- &rrbp, XFS_ALLOC_BTREE_REF)))
- return error;
- rrblock = XFS_BUF_TO_ALLOC_BLOCK(rrbp);
- if ((error = xfs_btree_check_sblock(cur, rrblock, level, rrbp)))
- return error;
- rrblock->bb_leftsib = cpu_to_be32(rbno);
- xfs_alloc_log_block(cur->bc_tp, rrbp, XFS_BB_LEFTSIB);
- }
- /*
- * If the cursor is really in the right block, move it there.
- * If it's just pointing past the last entry in left, then we'll
- * insert there, so don't change anything in that case.
- */
- if (cur->bc_ptrs[level] > be16_to_cpu(left->bb_numrecs) + 1) {
- xfs_btree_setbuf(cur, level, rbp);
- cur->bc_ptrs[level] -= be16_to_cpu(left->bb_numrecs);
- }
- /*
- * If there are more levels, we'll need another cursor which refers to
- * the right block, no matter where this cursor was.
- */
- if (level + 1 < cur->bc_nlevels) {
- if ((error = xfs_btree_dup_cursor(cur, curp)))
- return error;
- (*curp)->bc_ptrs[level + 1]++;
- }
- *bnop = rbno;
- *stat = 1;
- return 0;
-}
-
-/*
- * Update keys at all levels from here to the root along the cursor's path.
- */
-STATIC int /* error */
-xfs_alloc_updkey(
- xfs_btree_cur_t *cur, /* btree cursor */
- xfs_alloc_key_t *keyp, /* new key value to update to */
- int level) /* starting level for update */
-{
- int ptr; /* index of key in block */
-
- /*
- * Go up the tree from this level toward the root.
- * At each level, update the key value to the value input.
- * Stop when we reach a level where the cursor isn't pointing
- * at the first entry in the block.
- */
- for (ptr = 1; ptr == 1 && level < cur->bc_nlevels; level++) {
- xfs_alloc_block_t *block; /* btree block */
- xfs_buf_t *bp; /* buffer for block */
-#ifdef DEBUG
- int error; /* error return value */
-#endif
- xfs_alloc_key_t *kp; /* ptr to btree block keys */
-
- bp = cur->bc_bufs[level];
- block = XFS_BUF_TO_ALLOC_BLOCK(bp);
-#ifdef DEBUG
- if ((error = xfs_btree_check_sblock(cur, block, level, bp)))
- return error;
-#endif
- ptr = cur->bc_ptrs[level];
- kp = XFS_ALLOC_KEY_ADDR(block, ptr, cur);
- *kp = *keyp;
- xfs_alloc_log_keys(cur, bp, ptr, ptr);
- }
- return 0;
-}
-
-/*
- * Externally visible routines.
- */
-
-/*
- * Decrement cursor by one record at the level.
- * For nonzero levels the leaf-ward information is untouched.
- */
-int /* error */
-xfs_alloc_decrement(
- xfs_btree_cur_t *cur, /* btree cursor */
- int level, /* level in btree, 0 is leaf */
- int *stat) /* success/failure */
-{
- xfs_alloc_block_t *block; /* btree block */
- int error; /* error return value */
- int lev; /* btree level */
-
- ASSERT(level < cur->bc_nlevels);
- /*
- * Read-ahead to the left at this level.
- */
- xfs_btree_readahead(cur, level, XFS_BTCUR_LEFTRA);
- /*
- * Decrement the ptr at this level. If we're still in the block
- * then we're done.
- */
- if (--cur->bc_ptrs[level] > 0) {
- *stat = 1;
- return 0;
- }
- /*
- * Get a pointer to the btree block.
- */
- block = XFS_BUF_TO_ALLOC_BLOCK(cur->bc_bufs[level]);
-#ifdef DEBUG
- if ((error = xfs_btree_check_sblock(cur, block, level,
- cur->bc_bufs[level])))
- return error;
-#endif
- /*
- * If we just went off the left edge of the tree, return failure.
- */
- if (be32_to_cpu(block->bb_leftsib) == NULLAGBLOCK) {
- *stat = 0;
- return 0;
- }
- /*
- * March up the tree decrementing pointers.
- * Stop when we don't go off the left edge of a block.
- */
- for (lev = level + 1; lev < cur->bc_nlevels; lev++) {
- if (--cur->bc_ptrs[lev] > 0)
- break;
- /*
- * Read-ahead the left block, we're going to read it
- * in the next loop.
- */
- xfs_btree_readahead(cur, lev, XFS_BTCUR_LEFTRA);
- }
- /*
- * If we went off the root then we are seriously confused.
- */
- ASSERT(lev < cur->bc_nlevels);
- /*
- * Now walk back down the tree, fixing up the cursor's buffer
- * pointers and key numbers.
- */
- for (block = XFS_BUF_TO_ALLOC_BLOCK(cur->bc_bufs[lev]); lev > level; ) {
- xfs_agblock_t agbno; /* block number of btree block */
- xfs_buf_t *bp; /* buffer pointer for block */
-
- agbno = be32_to_cpu(*XFS_ALLOC_PTR_ADDR(block, cur->bc_ptrs[lev], cur));
- if ((error = xfs_btree_read_bufs(cur->bc_mp, cur->bc_tp,
- cur->bc_private.a.agno, agbno, 0, &bp,
- XFS_ALLOC_BTREE_REF)))
- return error;
- lev--;
- xfs_btree_setbuf(cur, lev, bp);
- block = XFS_BUF_TO_ALLOC_BLOCK(bp);
- if ((error = xfs_btree_check_sblock(cur, block, lev, bp)))
- return error;
- cur->bc_ptrs[lev] = be16_to_cpu(block->bb_numrecs);
- }
- *stat = 1;
- return 0;
-}
-
-/*
- * Delete the record pointed to by cur.
- * The cursor refers to the place where the record was (could be inserted)
- * when the operation returns.
- */
-int /* error */
-xfs_alloc_delete(
- xfs_btree_cur_t *cur, /* btree cursor */
- int *stat) /* success/failure */
-{
- int error; /* error return value */
- int i; /* result code */
- int level; /* btree level */
-
- /*
- * Go up the tree, starting at leaf level.
- * If 2 is returned then a join was done; go to the next level.
- * Otherwise we are done.
- */
- for (level = 0, i = 2; i == 2; level++) {
- if ((error = xfs_alloc_delrec(cur, level, &i)))
- return error;
- }
- if (i == 0) {
- for (level = 1; level < cur->bc_nlevels; level++) {
- if (cur->bc_ptrs[level] == 0) {
- if ((error = xfs_alloc_decrement(cur, level, &i)))
- return error;
- break;
- }
- }
- }
- *stat = i;
- return 0;
-}
-
-/*
- * Get the data from the pointed-to record.
- */
-int /* error */
-xfs_alloc_get_rec(
- xfs_btree_cur_t *cur, /* btree cursor */
- xfs_agblock_t *bno, /* output: starting block of extent */
- xfs_extlen_t *len, /* output: length of extent */
- int *stat) /* output: success/failure */
-{
- xfs_alloc_block_t *block; /* btree block */
-#ifdef DEBUG
- int error; /* error return value */
-#endif
- int ptr; /* record number */
-
- ptr = cur->bc_ptrs[0];
- block = XFS_BUF_TO_ALLOC_BLOCK(cur->bc_bufs[0]);
-#ifdef DEBUG
- if ((error = xfs_btree_check_sblock(cur, block, 0, cur->bc_bufs[0])))
- return error;
-#endif
- /*
- * Off the right end or left end, return failure.
- */
- if (ptr > be16_to_cpu(block->bb_numrecs) || ptr <= 0) {
- *stat = 0;
- return 0;
- }
- /*
- * Point to the record and extract its data.
- */
- {
- xfs_alloc_rec_t *rec; /* record data */
-
- rec = XFS_ALLOC_REC_ADDR(block, ptr, cur);
- *bno = be32_to_cpu(rec->ar_startblock);
- *len = be32_to_cpu(rec->ar_blockcount);
- }
- *stat = 1;
- return 0;
-}
-
-/*
- * Increment cursor by one record at the level.
- * For nonzero levels the leaf-ward information is untouched.
- */
-int /* error */
-xfs_alloc_increment(
- xfs_btree_cur_t *cur, /* btree cursor */
- int level, /* level in btree, 0 is leaf */
- int *stat) /* success/failure */
-{
- xfs_alloc_block_t *block; /* btree block */
- xfs_buf_t *bp; /* tree block buffer */
- int error; /* error return value */
- int lev; /* btree level */
-
- ASSERT(level < cur->bc_nlevels);
- /*
- * Read-ahead to the right at this level.
- */
- xfs_btree_readahead(cur, level, XFS_BTCUR_RIGHTRA);
- /*
- * Get a pointer to the btree block.
- */
- bp = cur->bc_bufs[level];
- block = XFS_BUF_TO_ALLOC_BLOCK(bp);
-#ifdef DEBUG
- if ((error = xfs_btree_check_sblock(cur, block, level, bp)))
- return error;
-#endif
- /*
- * Increment the ptr at this level. If we're still in the block
- * then we're done.
- */
- if (++cur->bc_ptrs[level] <= be16_to_cpu(block->bb_numrecs)) {
- *stat = 1;
- return 0;
- }
- /*
- * If we just went off the right edge of the tree, return failure.
- */
- if (be32_to_cpu(block->bb_rightsib) == NULLAGBLOCK) {
- *stat = 0;
- return 0;
- }
- /*
- * March up the tree incrementing pointers.
- * Stop when we don't go off the right edge of a block.
- */
- for (lev = level + 1; lev < cur->bc_nlevels; lev++) {
- bp = cur->bc_bufs[lev];
- block = XFS_BUF_TO_ALLOC_BLOCK(bp);
-#ifdef DEBUG
- if ((error = xfs_btree_check_sblock(cur, block, lev, bp)))
- return error;
-#endif
- if (++cur->bc_ptrs[lev] <= be16_to_cpu(block->bb_numrecs))
- break;
- /*
- * Read-ahead the right block, we're going to read it
- * in the next loop.
- */
- xfs_btree_readahead(cur, lev, XFS_BTCUR_RIGHTRA);
- }
- /*
- * If we went off the root then we are seriously confused.
- */
- ASSERT(lev < cur->bc_nlevels);
- /*
- * Now walk back down the tree, fixing up the cursor's buffer
- * pointers and key numbers.
- */
- for (bp = cur->bc_bufs[lev], block = XFS_BUF_TO_ALLOC_BLOCK(bp);
- lev > level; ) {
- xfs_agblock_t agbno; /* block number of btree block */
-
- agbno = be32_to_cpu(*XFS_ALLOC_PTR_ADDR(block, cur->bc_ptrs[lev], cur));
- if ((error = xfs_btree_read_bufs(cur->bc_mp, cur->bc_tp,
- cur->bc_private.a.agno, agbno, 0, &bp,
- XFS_ALLOC_BTREE_REF)))
- return error;
- lev--;
- xfs_btree_setbuf(cur, lev, bp);
- block = XFS_BUF_TO_ALLOC_BLOCK(bp);
- if ((error = xfs_btree_check_sblock(cur, block, lev, bp)))
- return error;
- cur->bc_ptrs[lev] = 1;
- }
- *stat = 1;
- return 0;
-}
-
-/*
- * Insert the current record at the point referenced by cur.
- * The cursor may be inconsistent on return if splits have been done.
- */
-int /* error */
-xfs_alloc_insert(
- xfs_btree_cur_t *cur, /* btree cursor */
- int *stat) /* success/failure */
-{
- int error; /* error return value */
- int i; /* result value, 0 for failure */
- int level; /* current level number in btree */
- xfs_agblock_t nbno; /* new block number (split result) */
- xfs_btree_cur_t *ncur; /* new cursor (split result) */
- xfs_alloc_rec_t nrec; /* record being inserted this level */
- xfs_btree_cur_t *pcur; /* previous level's cursor */
-
- level = 0;
- nbno = NULLAGBLOCK;
- nrec.ar_startblock = cpu_to_be32(cur->bc_rec.a.ar_startblock);
- nrec.ar_blockcount = cpu_to_be32(cur->bc_rec.a.ar_blockcount);
- ncur = (xfs_btree_cur_t *)0;
- pcur = cur;
- /*
- * Loop going up the tree, starting at the leaf level.
- * Stop when we don't get a split block, that must mean that
- * the insert is finished with this level.
- */
- do {
- /*
- * Insert nrec/nbno into this level of the tree.
- * Note if we fail, nbno will be null.
- */
- if ((error = xfs_alloc_insrec(pcur, level++, &nbno, &nrec, &ncur,
- &i))) {
- if (pcur != cur)
- xfs_btree_del_cursor(pcur, XFS_BTREE_ERROR);
- return error;
- }
- /*
- * See if the cursor we just used is trash.
- * Can't trash the caller's cursor, but otherwise we should
- * if ncur is a new cursor or we're about to be done.
- */
- if (pcur != cur && (ncur || nbno == NULLAGBLOCK)) {
- cur->bc_nlevels = pcur->bc_nlevels;
- xfs_btree_del_cursor(pcur, XFS_BTREE_NOERROR);
- }
- /*
- * If we got a new cursor, switch to it.
- */
- if (ncur) {
- pcur = ncur;
- ncur = (xfs_btree_cur_t *)0;
- }
- } while (nbno != NULLAGBLOCK);
- *stat = i;
- return 0;
-}
-
-/*
- * Lookup the record equal to [bno, len] in the btree given by cur.
- */
-int /* error */
-xfs_alloc_lookup_eq(
- xfs_btree_cur_t *cur, /* btree cursor */
- xfs_agblock_t bno, /* starting block of extent */
- xfs_extlen_t len, /* length of extent */
- int *stat) /* success/failure */
-{
- cur->bc_rec.a.ar_startblock = bno;
- cur->bc_rec.a.ar_blockcount = len;
- return xfs_alloc_lookup(cur, XFS_LOOKUP_EQ, stat);
-}
-
-/*
- * Lookup the first record greater than or equal to [bno, len]
- * in the btree given by cur.
- */
-int /* error */
-xfs_alloc_lookup_ge(
- xfs_btree_cur_t *cur, /* btree cursor */
- xfs_agblock_t bno, /* starting block of extent */
- xfs_extlen_t len, /* length of extent */
- int *stat) /* success/failure */
-{
- cur->bc_rec.a.ar_startblock = bno;
- cur->bc_rec.a.ar_blockcount = len;
- return xfs_alloc_lookup(cur, XFS_LOOKUP_GE, stat);
-}
-
-/*
- * Lookup the first record less than or equal to [bno, len]
- * in the btree given by cur.
- */
-int /* error */
-xfs_alloc_lookup_le(
- xfs_btree_cur_t *cur, /* btree cursor */
- xfs_agblock_t bno, /* starting block of extent */
- xfs_extlen_t len, /* length of extent */
- int *stat) /* success/failure */
-{
- cur->bc_rec.a.ar_startblock = bno;
- cur->bc_rec.a.ar_blockcount = len;
- return xfs_alloc_lookup(cur, XFS_LOOKUP_LE, stat);
-}
-
-/*
- * Update the record referred to by cur, to the value given by [bno, len].
- * This either works (return 0) or gets an EFSCORRUPTED error.
- */
-int /* error */
-xfs_alloc_update(
- xfs_btree_cur_t *cur, /* btree cursor */
- xfs_agblock_t bno, /* starting block of extent */
- xfs_extlen_t len) /* length of extent */
-{
- xfs_alloc_block_t *block; /* btree block to update */
- int error; /* error return value */
- int ptr; /* current record number (updating) */
-
- ASSERT(len > 0);
- /*
- * Pick up the a.g. freelist struct and the current block.
- */
- block = XFS_BUF_TO_ALLOC_BLOCK(cur->bc_bufs[0]);
-#ifdef DEBUG
- if ((error = xfs_btree_check_sblock(cur, block, 0, cur->bc_bufs[0])))
- return error;
-#endif
- /*
- * Get the address of the rec to be updated.
- */
- ptr = cur->bc_ptrs[0];
- {
- xfs_alloc_rec_t *rp; /* pointer to updated record */
-
- rp = XFS_ALLOC_REC_ADDR(block, ptr, cur);
- /*
- * Fill in the new contents and log them.
- */
- rp->ar_startblock = cpu_to_be32(bno);
- rp->ar_blockcount = cpu_to_be32(len);
- xfs_alloc_log_recs(cur, cur->bc_bufs[0], ptr, ptr);
- }
- /*
- * If it's the by-size btree and it's the last leaf block and
- * it's the last record... then update the size of the longest
- * extent in the a.g., which we cache in the a.g. freelist header.
- */
- if (cur->bc_btnum == XFS_BTNUM_CNT &&
- be32_to_cpu(block->bb_rightsib) == NULLAGBLOCK &&
- ptr == be16_to_cpu(block->bb_numrecs)) {
- xfs_agf_t *agf; /* a.g. freespace header */
- xfs_agnumber_t seqno;
-
- agf = XFS_BUF_TO_AGF(cur->bc_private.a.agbp);
- seqno = be32_to_cpu(agf->agf_seqno);
- cur->bc_mp->m_perag[seqno].pagf_longest = len;
- agf->agf_longest = cpu_to_be32(len);
- xfs_alloc_log_agf(cur->bc_tp, cur->bc_private.a.agbp,
- XFS_AGF_LONGEST);
- }
- /*
- * Updating first record in leaf. Pass new key value up to our parent.
- */
- if (ptr == 1) {
- xfs_alloc_key_t key; /* key containing [bno, len] */
-
- key.ar_startblock = cpu_to_be32(bno);
- key.ar_blockcount = cpu_to_be32(len);
- if ((error = xfs_alloc_updkey(cur, &key, 1)))
- return error;
- }
- return 0;
-}
diff --git a/sys/gnu/fs/xfs/xfs_alloc_btree.h b/sys/gnu/fs/xfs/xfs_alloc_btree.h
deleted file mode 100644
index bce81c7..0000000
--- a/sys/gnu/fs/xfs/xfs_alloc_btree.h
+++ /dev/null
@@ -1,159 +0,0 @@
-/*
- * Copyright (c) 2000,2005 Silicon Graphics, Inc.
- * All Rights Reserved.
- *
- * 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.
- *
- * This program is distributed in the hope that it would 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 the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- */
-#ifndef __XFS_ALLOC_BTREE_H__
-#define __XFS_ALLOC_BTREE_H__
-
-/*
- * Freespace on-disk structures
- */
-
-struct xfs_buf;
-struct xfs_btree_cur;
-struct xfs_btree_sblock;
-struct xfs_mount;
-
-/*
- * There are two on-disk btrees, one sorted by blockno and one sorted
- * by blockcount and blockno. All blocks look the same to make the code
- * simpler; if we have time later, we'll make the optimizations.
- */
-#define XFS_ABTB_MAGIC 0x41425442 /* 'ABTB' for bno tree */
-#define XFS_ABTC_MAGIC 0x41425443 /* 'ABTC' for cnt tree */
-
-/*
- * Data record/key structure
- */
-typedef struct xfs_alloc_rec {
- __be32 ar_startblock; /* starting block number */
- __be32 ar_blockcount; /* count of free blocks */
-} xfs_alloc_rec_t, xfs_alloc_key_t;
-
-typedef struct xfs_alloc_rec_incore {
- xfs_agblock_t ar_startblock; /* starting block number */
- xfs_extlen_t ar_blockcount; /* count of free blocks */
-} xfs_alloc_rec_incore_t;
-
-/* btree pointer type */
-typedef __be32 xfs_alloc_ptr_t;
-/* btree block header type */
-typedef struct xfs_btree_sblock xfs_alloc_block_t;
-
-#define XFS_BUF_TO_ALLOC_BLOCK(bp) ((xfs_alloc_block_t *)XFS_BUF_PTR(bp))
-
-/*
- * Real block structures have a size equal to the disk block size.
- */
-#define XFS_ALLOC_BLOCK_SIZE(lev,cur) (1 << (cur)->bc_blocklog)
-#define XFS_ALLOC_BLOCK_MAXRECS(lev,cur) ((cur)->bc_mp->m_alloc_mxr[lev != 0])
-#define XFS_ALLOC_BLOCK_MINRECS(lev,cur) ((cur)->bc_mp->m_alloc_mnr[lev != 0])
-
-/*
- * Minimum and maximum blocksize and sectorsize.
- * The blocksize upper limit is pretty much arbitrary.
- * The sectorsize upper limit is due to sizeof(sb_sectsize).
- */
-#define XFS_MIN_BLOCKSIZE_LOG 9 /* i.e. 512 bytes */
-#define XFS_MAX_BLOCKSIZE_LOG 16 /* i.e. 65536 bytes */
-#define XFS_MIN_BLOCKSIZE (1 << XFS_MIN_BLOCKSIZE_LOG)
-#define XFS_MAX_BLOCKSIZE (1 << XFS_MAX_BLOCKSIZE_LOG)
-#define XFS_MIN_SECTORSIZE_LOG 9 /* i.e. 512 bytes */
-#define XFS_MAX_SECTORSIZE_LOG 15 /* i.e. 32768 bytes */
-#define XFS_MIN_SECTORSIZE (1 << XFS_MIN_SECTORSIZE_LOG)
-#define XFS_MAX_SECTORSIZE (1 << XFS_MAX_SECTORSIZE_LOG)
-
-/*
- * Block numbers in the AG:
- * SB is sector 0, AGF is sector 1, AGI is sector 2, AGFL is sector 3.
- */
-#define XFS_BNO_BLOCK(mp) ((xfs_agblock_t)(XFS_AGFL_BLOCK(mp) + 1))
-#define XFS_CNT_BLOCK(mp) ((xfs_agblock_t)(XFS_BNO_BLOCK(mp) + 1))
-
-/*
- * Record, key, and pointer address macros for btree blocks.
- */
-#define XFS_ALLOC_REC_ADDR(bb,i,cur) \
- XFS_BTREE_REC_ADDR(XFS_ALLOC_BLOCK_SIZE(0,cur), xfs_alloc, \
- bb, i, XFS_ALLOC_BLOCK_MAXRECS(0, cur))
-
-#define XFS_ALLOC_KEY_ADDR(bb,i,cur) \
- XFS_BTREE_KEY_ADDR(XFS_ALLOC_BLOCK_SIZE(1,cur), xfs_alloc, \
- bb, i, XFS_ALLOC_BLOCK_MAXRECS(1, cur))
-
-#define XFS_ALLOC_PTR_ADDR(bb,i,cur) \
- XFS_BTREE_PTR_ADDR(XFS_ALLOC_BLOCK_SIZE(1,cur), xfs_alloc, \
- bb, i, XFS_ALLOC_BLOCK_MAXRECS(1, cur))
-
-/*
- * Decrement cursor by one record at the level.
- * For nonzero levels the leaf-ward information is untouched.
- */
-extern int xfs_alloc_decrement(struct xfs_btree_cur *cur, int level, int *stat);
-
-/*
- * Delete the record pointed to by cur.
- * The cursor refers to the place where the record was (could be inserted)
- * when the operation returns.
- */
-extern int xfs_alloc_delete(struct xfs_btree_cur *cur, int *stat);
-
-/*
- * Get the data from the pointed-to record.
- */
-extern int xfs_alloc_get_rec(struct xfs_btree_cur *cur, xfs_agblock_t *bno,
- xfs_extlen_t *len, int *stat);
-
-/*
- * Increment cursor by one record at the level.
- * For nonzero levels the leaf-ward information is untouched.
- */
-extern int xfs_alloc_increment(struct xfs_btree_cur *cur, int level, int *stat);
-
-/*
- * Insert the current record at the point referenced by cur.
- * The cursor may be inconsistent on return if splits have been done.
- */
-extern int xfs_alloc_insert(struct xfs_btree_cur *cur, int *stat);
-
-/*
- * Lookup the record equal to [bno, len] in the btree given by cur.
- */
-extern int xfs_alloc_lookup_eq(struct xfs_btree_cur *cur, xfs_agblock_t bno,
- xfs_extlen_t len, int *stat);
-
-/*
- * Lookup the first record greater than or equal to [bno, len]
- * in the btree given by cur.
- */
-extern int xfs_alloc_lookup_ge(struct xfs_btree_cur *cur, xfs_agblock_t bno,
- xfs_extlen_t len, int *stat);
-
-/*
- * Lookup the first record less than or equal to [bno, len]
- * in the btree given by cur.
- */
-extern int xfs_alloc_lookup_le(struct xfs_btree_cur *cur, xfs_agblock_t bno,
- xfs_extlen_t len, int *stat);
-
-/*
- * Update the record referred to by cur, to the value given by [bno, len].
- * This either works (return 0) or gets an EFSCORRUPTED error.
- */
-extern int xfs_alloc_update(struct xfs_btree_cur *cur, xfs_agblock_t bno,
- xfs_extlen_t len);
-
-#endif /* __XFS_ALLOC_BTREE_H__ */
diff --git a/sys/gnu/fs/xfs/xfs_arch.h b/sys/gnu/fs/xfs/xfs_arch.h
deleted file mode 100644
index a7d9de5..0000000
--- a/sys/gnu/fs/xfs/xfs_arch.h
+++ /dev/null
@@ -1,239 +0,0 @@
-/*
- * Copyright (c) 2000-2002,2005 Silicon Graphics, Inc.
- * All Rights Reserved.
- *
- * 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.
- *
- * This program is distributed in the hope that it would 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 the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- */
-#ifndef __XFS_ARCH_H__
-#define __XFS_ARCH_H__
-
-#ifndef XFS_BIG_INUMS
-# error XFS_BIG_INUMS must be defined true or false
-#endif
-
-#include <sys/endian.h>
-
-#define __LITTLE_ENDIAN _LITTLE_ENDIAN
-#define __BIG_ENDIAN _BIG_ENDIAN
-#define __BYTE_ORDER _BYTE_ORDER
-#define __user
-/* Compatibiliy defines */
-#define __swab16 __bswap16
-#define __swab32 __bswap32
-#define __swab64 __bswap64
-
-#define ARCH_NOCONVERT 1
-#if _BYTE_ORDER != _LITTLE_ENDIAN
-#define XFS_NATIVE_HOST 1
-# define ARCH_CONVERT ARCH_NOCONVERT
-#else
-#undef XFS_NATIVE_HOST
-#define ARCH_CONVERT 0
-#endif
-
-
-#ifdef XFS_NATIVE_HOST
-#define cpu_to_be16(val) ((__be16)(val))
-#define cpu_to_be32(val) ((__be32)(val))
-#define cpu_to_be64(val) ((__be64)(val))
-#define be16_to_cpu(val) ((__uint16_t)(val))
-#define be32_to_cpu(val) ((__uint32_t)(val))
-#define be64_to_cpu(val) ((__uint64_t)(val))
-#else
-#define cpu_to_be16(val) (__swab16((__uint16_t)(val)))
-#define cpu_to_be32(val) (__swab32((__uint32_t)(val)))
-#define cpu_to_be64(val) (__swab64((__uint64_t)(val)))
-#define be16_to_cpu(val) (__swab16((__be16)(val)))
-#define be32_to_cpu(val) (__swab32((__be32)(val)))
-#define be64_to_cpu(val) (__swab64((__be64)(val)))
-#endif
-
-//#endif /* __KERNEL__ */
-
-/* do we need conversion? */
-//#define ARCH_NOCONVERT 1
-//#ifdef XFS_NATIVE_HOST
-//# define ARCH_CONVERT ARCH_NOCONVERT
-//#else
-//# define ARCH_CONVERT 0
-//#endif
-
-/* generic swapping macros */
-
-#ifndef HAVE_SWABMACROS
-#define INT_SWAP16(type,var) ((typeof(type))(__swab16((__u16)(var))))
-#define INT_SWAP32(type,var) ((typeof(type))(__swab32((__u32)(var))))
-#define INT_SWAP64(type,var) ((typeof(type))(__swab64((__u64)(var))))
-#endif
-
-#define INT_SWAP(type, var) \
- ((sizeof(type) == 8) ? INT_SWAP64(type,var) : \
- ((sizeof(type) == 4) ? INT_SWAP32(type,var) : \
- ((sizeof(type) == 2) ? INT_SWAP16(type,var) : \
- (var))))
-
-/*
- * get and set integers from potentially unaligned locations
- */
-
-#define INT_GET_UNALIGNED_16_BE(pointer) \
- ((__u16)((((__u8*)(pointer))[0] << 8) | (((__u8*)(pointer))[1])))
-#define INT_SET_UNALIGNED_16_BE(pointer,value) \
- { \
- ((__u8*)(pointer))[0] = (((value) >> 8) & 0xff); \
- ((__u8*)(pointer))[1] = (((value) ) & 0xff); \
- }
-
-/* define generic INT_ macros */
-
-#define INT_GET(reference,arch) \
- (((arch) == ARCH_NOCONVERT) \
- ? \
- (reference) \
- : \
- INT_SWAP((reference),(reference)) \
- )
-
-/* does not return a value */
-#define INT_SET(reference,arch,valueref) \
- (__builtin_constant_p(valueref) ? \
- (void)( (reference) = ( ((arch) != ARCH_NOCONVERT) ? (INT_SWAP((reference),(valueref))) : (valueref)) ) : \
- (void)( \
- ((reference) = (valueref)), \
- ( ((arch) != ARCH_NOCONVERT) ? (reference) = INT_SWAP((reference),(reference)) : 0 ) \
- ) \
- )
-
-/* does not return a value */
-#define INT_MOD_EXPR(reference,arch,code) \
- (((arch) == ARCH_NOCONVERT) \
- ? \
- (void)((reference) code) \
- : \
- (void)( \
- (reference) = INT_GET((reference),arch) , \
- ((reference) code), \
- INT_SET(reference, arch, reference) \
- ) \
- )
-
-/* does not return a value */
-#define INT_MOD(reference,arch,delta) \
- (void)( \
- INT_MOD_EXPR(reference,arch,+=(delta)) \
- )
-
-/*
- * INT_COPY - copy a value between two locations with the
- * _same architecture_ but _potentially different sizes_
- *
- * if the types of the two parameters are equal or they are
- * in native architecture, a simple copy is done
- *
- * otherwise, architecture conversions are done
- *
- */
-
-/* does not return a value */
-#define INT_COPY(dst,src,arch) \
- ( \
- ((sizeof(dst) == sizeof(src)) || ((arch) == ARCH_NOCONVERT)) \
- ? \
- (void)((dst) = (src)) \
- : \
- INT_SET(dst, arch, INT_GET(src, arch)) \
- )
-
-/*
- * INT_XLATE - copy a value in either direction between two locations
- * with different architectures
- *
- * dir < 0 - copy from memory to buffer (native to arch)
- * dir > 0 - copy from buffer to memory (arch to native)
- */
-
-/* does not return a value */
-#define INT_XLATE(buf,mem,dir,arch) {\
- ASSERT(dir); \
- if (dir>0) { \
- (mem)=INT_GET(buf, arch); \
- } else { \
- INT_SET(buf, arch, mem); \
- } \
-}
-
-static inline void be16_add(__be16 *a, __s16 b)
-{
- *a = cpu_to_be16(be16_to_cpu(*a) + b);
-}
-
-static inline void be32_add(__be32 *a, __s32 b)
-{
- *a = cpu_to_be32(be32_to_cpu(*a) + b);
-}
-
-static inline void be64_add(__be64 *a, __s64 b)
-{
- *a = cpu_to_be64(be64_to_cpu(*a) + b);
-}
-
-/*
- * In directories inode numbers are stored as unaligned arrays of unsigned
- * 8bit integers on disk.
- *
- * For v1 directories or v2 directories that contain inode numbers that
- * do not fit into 32bit the array has eight members, but the first member
- * is always zero:
- *
- * |unused|48-55|40-47|32-39|24-31|16-23| 8-15| 0- 7|
- *
- * For v2 directories that only contain entries with inode numbers that fit
- * into 32bits a four-member array is used:
- *
- * |24-31|16-23| 8-15| 0- 7|
- */
-
-#define XFS_GET_DIR_INO4(di) \
- (((__u32)(di).i[0] << 24) | ((di).i[1] << 16) | ((di).i[2] << 8) | ((di).i[3]))
-
-#define XFS_PUT_DIR_INO4(from, di) \
-do { \
- (di).i[0] = (((from) & 0xff000000ULL) >> 24); \
- (di).i[1] = (((from) & 0x00ff0000ULL) >> 16); \
- (di).i[2] = (((from) & 0x0000ff00ULL) >> 8); \
- (di).i[3] = ((from) & 0x000000ffULL); \
-} while (0)
-
-#define XFS_DI_HI(di) \
- (((__u32)(di).i[1] << 16) | ((di).i[2] << 8) | ((di).i[3]))
-#define XFS_DI_LO(di) \
- (((__u32)(di).i[4] << 24) | ((di).i[5] << 16) | ((di).i[6] << 8) | ((di).i[7]))
-
-#define XFS_GET_DIR_INO8(di) \
- (((xfs_ino_t)XFS_DI_LO(di) & 0xffffffffULL) | \
- ((xfs_ino_t)XFS_DI_HI(di) << 32))
-
-#define XFS_PUT_DIR_INO8(from, di) \
-do { \
- (di).i[0] = 0; \
- (di).i[1] = (((from) & 0x00ff000000000000ULL) >> 48); \
- (di).i[2] = (((from) & 0x0000ff0000000000ULL) >> 40); \
- (di).i[3] = (((from) & 0x000000ff00000000ULL) >> 32); \
- (di).i[4] = (((from) & 0x00000000ff000000ULL) >> 24); \
- (di).i[5] = (((from) & 0x0000000000ff0000ULL) >> 16); \
- (di).i[6] = (((from) & 0x000000000000ff00ULL) >> 8); \
- (di).i[7] = ((from) & 0x00000000000000ffULL); \
-} while (0)
-
-#endif /* __XFS_ARCH_H__ */
diff --git a/sys/gnu/fs/xfs/xfs_attr.c b/sys/gnu/fs/xfs/xfs_attr.c
deleted file mode 100644
index 3a8122c..0000000
--- a/sys/gnu/fs/xfs/xfs_attr.c
+++ /dev/null
@@ -1,2646 +0,0 @@
-/*
- * Copyright (c) 2000-2005 Silicon Graphics, Inc.
- * All Rights Reserved.
- *
- * 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.
- *
- * This program is distributed in the hope that it would 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 the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- */
-
-//#include <linux/capability.h>
-
-#include "xfs.h"
-#include "xfs_fs.h"
-#include "xfs_types.h"
-#include "xfs_bit.h"
-#include "xfs_log.h"
-#include "xfs_inum.h"
-#include "xfs_trans.h"
-#include "xfs_sb.h"
-#include "xfs_ag.h"
-#include "xfs_dir.h"
-#include "xfs_dir2.h"
-#include "xfs_dmapi.h"
-#include "xfs_mount.h"
-#include "xfs_da_btree.h"
-#include "xfs_bmap_btree.h"
-#include "xfs_alloc_btree.h"
-#include "xfs_ialloc_btree.h"
-#include "xfs_dir_sf.h"
-#include "xfs_dir2_sf.h"
-#include "xfs_attr_sf.h"
-#include "xfs_dinode.h"
-#include "xfs_inode.h"
-#include "xfs_alloc.h"
-#include "xfs_btree.h"
-#include "xfs_inode_item.h"
-#include "xfs_bmap.h"
-#include "xfs_attr.h"
-#include "xfs_attr_leaf.h"
-#include "xfs_error.h"
-#include "xfs_quota.h"
-#include "xfs_trans_space.h"
-#include "xfs_acl.h"
-#include "xfs_rw.h"
-
-/*
- * xfs_attr.c
- *
- * Provide the external interfaces to manage attribute lists.
- */
-
-#define ATTR_SYSCOUNT 2
-STATIC struct attrnames posix_acl_access;
-STATIC struct attrnames posix_acl_default;
-STATIC struct attrnames *attr_system_names[ATTR_SYSCOUNT];
-
-/*========================================================================
- * Function prototypes for the kernel.
- *========================================================================*/
-
-/*
- * Internal routines when attribute list fits inside the inode.
- */
-STATIC int xfs_attr_shortform_addname(xfs_da_args_t *args);
-
-/*
- * Internal routines when attribute list is one block.
- */
-STATIC int xfs_attr_leaf_get(xfs_da_args_t *args);
-STATIC int xfs_attr_leaf_addname(xfs_da_args_t *args);
-STATIC int xfs_attr_leaf_removename(xfs_da_args_t *args);
-STATIC int xfs_attr_leaf_list(xfs_attr_list_context_t *context);
-
-/*
- * Internal routines when attribute list is more than one block.
- */
-STATIC int xfs_attr_node_get(xfs_da_args_t *args);
-STATIC int xfs_attr_node_addname(xfs_da_args_t *args);
-STATIC int xfs_attr_node_removename(xfs_da_args_t *args);
-STATIC int xfs_attr_node_list(xfs_attr_list_context_t *context);
-STATIC int xfs_attr_fillstate(xfs_da_state_t *state);
-STATIC int xfs_attr_refillstate(xfs_da_state_t *state);
-
-/*
- * Routines to manipulate out-of-line attribute values.
- */
-STATIC int xfs_attr_rmtval_get(xfs_da_args_t *args);
-STATIC int xfs_attr_rmtval_set(xfs_da_args_t *args);
-STATIC int xfs_attr_rmtval_remove(xfs_da_args_t *args);
-
-#define ATTR_RMTVALUE_MAPSIZE 1 /* # of map entries at once */
-
-#if defined(XFS_ATTR_TRACE)
-ktrace_t *xfs_attr_trace_buf;
-#endif
-
-
-/*========================================================================
- * Overall external interface routines.
- *========================================================================*/
-
-int
-xfs_attr_fetch(xfs_inode_t *ip, const char *name, int namelen,
- char *value, int *valuelenp, int flags, struct cred *cred)
-{
- xfs_da_args_t args;
- int error;
-
- if ((XFS_IFORK_Q(ip) == 0) ||
- (ip->i_d.di_aformat == XFS_DINODE_FMT_EXTENTS &&
- ip->i_d.di_anextents == 0))
- return(ENOATTR);
-
- /*
- * Fill in the arg structure for this request.
- */
- memset((char *)&args, 0, sizeof(args));
- args.name = name;
- args.namelen = namelen;
- args.value = value;
- args.valuelen = *valuelenp;
- args.flags = flags;
- args.hashval = xfs_da_hashname(args.name, args.namelen);
- args.dp = ip;
- args.whichfork = XFS_ATTR_FORK;
-
- /*
- * Decide on what work routines to call based on the inode size.
- */
- if (XFS_IFORK_Q(ip) == 0 ||
- (ip->i_d.di_aformat == XFS_DINODE_FMT_EXTENTS &&
- ip->i_d.di_anextents == 0)) {
- error = XFS_ERROR(ENOATTR);
- } else if (ip->i_d.di_aformat == XFS_DINODE_FMT_LOCAL) {
- error = xfs_attr_shortform_getvalue(&args);
- } else if (xfs_bmap_one_block(ip, XFS_ATTR_FORK)) {
- error = xfs_attr_leaf_get(&args);
- } else {
- error = xfs_attr_node_get(&args);
- }
-
- /*
- * Return the number of bytes in the value to the caller.
- */
- *valuelenp = args.valuelen;
-
- if (error == EEXIST)
- error = 0;
- return(error);
-}
-
-int
-xfs_attr_get(bhv_desc_t *bdp, const char *name, char *value, int *valuelenp,
- int flags, struct cred *cred)
-{
- xfs_inode_t *ip = XFS_BHVTOI(bdp);
- int error, namelen;
-
- XFS_STATS_INC(xs_attr_get);
-
- if (!name)
- return(EINVAL);
- namelen = strlen(name);
- if (namelen >= MAXNAMELEN)
- return(EFAULT); /* match IRIX behaviour */
-
- if (XFS_FORCED_SHUTDOWN(ip->i_mount))
- return(EIO);
-
- xfs_ilock(ip, XFS_ILOCK_SHARED);
- error = xfs_attr_fetch(ip, name, namelen, value, valuelenp, flags, cred);
- xfs_iunlock(ip, XFS_ILOCK_SHARED);
- return(error);
-}
-
-STATIC int
-xfs_attr_set_int(xfs_inode_t *dp, const char *name, int namelen,
- char *value, int valuelen, int flags)
-{
- xfs_da_args_t args;
- xfs_fsblock_t firstblock;
- xfs_bmap_free_t flist;
- int error, err2, committed;
- int local, size;
- uint nblks;
- xfs_mount_t *mp = dp->i_mount;
- int rsvd = (flags & ATTR_ROOT) != 0;
-
- /*
- * Attach the dquots to the inode.
- */
- if ((error = XFS_QM_DQATTACH(mp, dp, 0)))
- return (error);
-
- /*
- * Determine space new attribute will use, and if it would be
- * "local" or "remote" (note: local != inline).
- */
- size = xfs_attr_leaf_newentsize(namelen, valuelen,
- mp->m_sb.sb_blocksize, &local);
-
- /*
- * If the inode doesn't have an attribute fork, add one.
- * (inode must not be locked when we call this routine)
- */
- if (XFS_IFORK_Q(dp) == 0) {
- if ((error = xfs_bmap_add_attrfork(dp, size, rsvd)))
- return(error);
- }
-
- /*
- * Fill in the arg structure for this request.
- */
- memset((char *)&args, 0, sizeof(args));
- args.name = name;
- args.namelen = namelen;
- args.value = value;
- args.valuelen = valuelen;
- args.flags = flags;
- args.hashval = xfs_da_hashname(args.name, args.namelen);
- args.dp = dp;
- args.firstblock = &firstblock;
- args.flist = &flist;
- args.whichfork = XFS_ATTR_FORK;
- args.addname = 1;
- args.oknoent = 1;
-
- nblks = XFS_DAENTER_SPACE_RES(mp, XFS_ATTR_FORK);
- if (local) {
- if (size > (mp->m_sb.sb_blocksize >> 1)) {
- /* Double split possible */
- nblks <<= 1;
- }
- } else {
- uint dblocks = XFS_B_TO_FSB(mp, valuelen);
- /* Out of line attribute, cannot double split, but make
- * room for the attribute value itself.
- */
- nblks += dblocks;
- nblks += XFS_NEXTENTADD_SPACE_RES(mp, dblocks, XFS_ATTR_FORK);
- }
-
- /* Size is now blocks for attribute data */
- args.total = nblks;
-
- /*
- * Start our first transaction of the day.
- *
- * All future transactions during this code must be "chained" off
- * this one via the trans_dup() call. All transactions will contain
- * the inode, and the inode will always be marked with trans_ihold().
- * Since the inode will be locked in all transactions, we must log
- * the inode in every transaction to let it float upward through
- * the log.
- */
- args.trans = xfs_trans_alloc(mp, XFS_TRANS_ATTR_SET);
-
- /*
- * Root fork attributes can use reserved data blocks for this
- * operation if necessary
- */
-
- if (rsvd)
- args.trans->t_flags |= XFS_TRANS_RESERVE;
-
- if ((error = xfs_trans_reserve(args.trans, (uint) nblks,
- XFS_ATTRSET_LOG_RES(mp, nblks),
- 0, XFS_TRANS_PERM_LOG_RES,
- XFS_ATTRSET_LOG_COUNT))) {
- xfs_trans_cancel(args.trans, 0);
- return(error);
- }
- xfs_ilock(dp, XFS_ILOCK_EXCL);
-
- error = XFS_TRANS_RESERVE_QUOTA_NBLKS(mp, args.trans, dp, nblks, 0,
- rsvd ? XFS_QMOPT_RES_REGBLKS | XFS_QMOPT_FORCE_RES :
- XFS_QMOPT_RES_REGBLKS);
- if (error) {
- xfs_iunlock(dp, XFS_ILOCK_EXCL);
- xfs_trans_cancel(args.trans, XFS_TRANS_RELEASE_LOG_RES);
- return (error);
- }
-
- xfs_trans_ijoin(args.trans, dp, XFS_ILOCK_EXCL);
- xfs_trans_ihold(args.trans, dp);
-
- /*
- * If the attribute list is non-existent or a shortform list,
- * upgrade it to a single-leaf-block attribute list.
- */
- if ((dp->i_d.di_aformat == XFS_DINODE_FMT_LOCAL) ||
- ((dp->i_d.di_aformat == XFS_DINODE_FMT_EXTENTS) &&
- (dp->i_d.di_anextents == 0))) {
-
- /*
- * Build initial attribute list (if required).
- */
- if (dp->i_d.di_aformat == XFS_DINODE_FMT_EXTENTS)
- xfs_attr_shortform_create(&args);
-
- /*
- * Try to add the attr to the attribute list in
- * the inode.
- */
- error = xfs_attr_shortform_addname(&args);
- if (error != ENOSPC) {
- /*
- * Commit the shortform mods, and we're done.
- * NOTE: this is also the error path (EEXIST, etc).
- */
- ASSERT(args.trans != NULL);
-
- /*
- * If this is a synchronous mount, make sure that
- * the transaction goes to disk before returning
- * to the user.
- */
- if (mp->m_flags & XFS_MOUNT_WSYNC) {
- xfs_trans_set_sync(args.trans);
- }
- err2 = xfs_trans_commit(args.trans,
- XFS_TRANS_RELEASE_LOG_RES,
- NULL);
- xfs_iunlock(dp, XFS_ILOCK_EXCL);
-
- /*
- * Hit the inode change time.
- */
- if (!error && (flags & ATTR_KERNOTIME) == 0) {
- xfs_ichgtime(dp, XFS_ICHGTIME_CHG);
- }
- return(error == 0 ? err2 : error);
- }
-
- /*
- * It won't fit in the shortform, transform to a leaf block.
- * GROT: another possible req'mt for a double-split btree op.
- */
- XFS_BMAP_INIT(args.flist, args.firstblock);
- error = xfs_attr_shortform_to_leaf(&args);
- if (!error) {
- error = xfs_bmap_finish(&args.trans, args.flist,
- *args.firstblock, &committed);
- }
- if (error) {
- ASSERT(committed);
- args.trans = NULL;
- xfs_bmap_cancel(&flist);
- goto out;
- }
-
- /*
- * bmap_finish() may have committed the last trans and started
- * a new one. We need the inode to be in all transactions.
- */
- if (committed) {
- xfs_trans_ijoin(args.trans, dp, XFS_ILOCK_EXCL);
- xfs_trans_ihold(args.trans, dp);
- }
-
- /*
- * Commit the leaf transformation. We'll need another (linked)
- * transaction to add the new attribute to the leaf.
- */
- if ((error = xfs_attr_rolltrans(&args.trans, dp)))
- goto out;
-
- }
-
- if (xfs_bmap_one_block(dp, XFS_ATTR_FORK)) {
- error = xfs_attr_leaf_addname(&args);
- } else {
- error = xfs_attr_node_addname(&args);
- }
- if (error) {
- goto out;
- }
-
- /*
- * If this is a synchronous mount, make sure that the
- * transaction goes to disk before returning to the user.
- */
- if (mp->m_flags & XFS_MOUNT_WSYNC) {
- xfs_trans_set_sync(args.trans);
- }
-
- /*
- * Commit the last in the sequence of transactions.
- */
- xfs_trans_log_inode(args.trans, dp, XFS_ILOG_CORE);
- error = xfs_trans_commit(args.trans, XFS_TRANS_RELEASE_LOG_RES,
- NULL);
- xfs_iunlock(dp, XFS_ILOCK_EXCL);
-
- /*
- * Hit the inode change time.
- */
- if (!error && (flags & ATTR_KERNOTIME) == 0) {
- xfs_ichgtime(dp, XFS_ICHGTIME_CHG);
- }
-
- return(error);
-
-out:
- if (args.trans)
- xfs_trans_cancel(args.trans,
- XFS_TRANS_RELEASE_LOG_RES|XFS_TRANS_ABORT);
- xfs_iunlock(dp, XFS_ILOCK_EXCL);
- return(error);
-}
-
-int
-xfs_attr_set(bhv_desc_t *bdp, const char *name, char *value, int valuelen, int flags,
- struct cred *cred)
-{
- xfs_inode_t *dp;
- int namelen;
-
- namelen = strlen(name);
- if (namelen >= MAXNAMELEN)
- return EFAULT; /* match IRIX behaviour */
-
- XFS_STATS_INC(xs_attr_set);
-
- dp = XFS_BHVTOI(bdp);
- if (XFS_FORCED_SHUTDOWN(dp->i_mount))
- return (EIO);
-
- return xfs_attr_set_int(dp, name, namelen, value, valuelen, flags);
-}
-
-/*
- * Generic handler routine to remove a name from an attribute list.
- * Transitions attribute list from Btree to shortform as necessary.
- */
-STATIC int
-xfs_attr_remove_int(xfs_inode_t *dp, const char *name, int namelen, int flags)
-{
- xfs_da_args_t args;
- xfs_fsblock_t firstblock;
- xfs_bmap_free_t flist;
- int error;
- xfs_mount_t *mp = dp->i_mount;
-
- /*
- * Fill in the arg structure for this request.
- */
- memset((char *)&args, 0, sizeof(args));
- args.name = name;
- args.namelen = namelen;
- args.flags = flags;
- args.hashval = xfs_da_hashname(args.name, args.namelen);
- args.dp = dp;
- args.firstblock = &firstblock;
- args.flist = &flist;
- args.total = 0;
- args.whichfork = XFS_ATTR_FORK;
-
- /*
- * Attach the dquots to the inode.
- */
- if ((error = XFS_QM_DQATTACH(mp, dp, 0)))
- return (error);
-
- /*
- * Start our first transaction of the day.
- *
- * All future transactions during this code must be "chained" off
- * this one via the trans_dup() call. All transactions will contain
- * the inode, and the inode will always be marked with trans_ihold().
- * Since the inode will be locked in all transactions, we must log
- * the inode in every transaction to let it float upward through
- * the log.
- */
- args.trans = xfs_trans_alloc(mp, XFS_TRANS_ATTR_RM);
-
- /*
- * Root fork attributes can use reserved data blocks for this
- * operation if necessary
- */
-
- if (flags & ATTR_ROOT)
- args.trans->t_flags |= XFS_TRANS_RESERVE;
-
- if ((error = xfs_trans_reserve(args.trans,
- XFS_ATTRRM_SPACE_RES(mp),
- XFS_ATTRRM_LOG_RES(mp),
- 0, XFS_TRANS_PERM_LOG_RES,
- XFS_ATTRRM_LOG_COUNT))) {
- xfs_trans_cancel(args.trans, 0);
- return(error);
- }
-
- xfs_ilock(dp, XFS_ILOCK_EXCL);
- /*
- * No need to make quota reservations here. We expect to release some
- * blocks not allocate in the common case.
- */
- xfs_trans_ijoin(args.trans, dp, XFS_ILOCK_EXCL);
- xfs_trans_ihold(args.trans, dp);
-
- /*
- * Decide on what work routines to call based on the inode size.
- */
- if (XFS_IFORK_Q(dp) == 0 ||
- (dp->i_d.di_aformat == XFS_DINODE_FMT_EXTENTS &&
- dp->i_d.di_anextents == 0)) {
- error = XFS_ERROR(ENOATTR);
- goto out;
- }
- if (dp->i_d.di_aformat == XFS_DINODE_FMT_LOCAL) {
- ASSERT(dp->i_afp->if_flags & XFS_IFINLINE);
- error = xfs_attr_shortform_remove(&args);
- if (error) {
- goto out;
- }
- } else if (xfs_bmap_one_block(dp, XFS_ATTR_FORK)) {
- error = xfs_attr_leaf_removename(&args);
- } else {
- error = xfs_attr_node_removename(&args);
- }
- if (error) {
- goto out;
- }
-
- /*
- * If this is a synchronous mount, make sure that the
- * transaction goes to disk before returning to the user.
- */
- if (mp->m_flags & XFS_MOUNT_WSYNC) {
- xfs_trans_set_sync(args.trans);
- }
-
- /*
- * Commit the last in the sequence of transactions.
- */
- xfs_trans_log_inode(args.trans, dp, XFS_ILOG_CORE);
- error = xfs_trans_commit(args.trans, XFS_TRANS_RELEASE_LOG_RES,
- NULL);
- xfs_iunlock(dp, XFS_ILOCK_EXCL);
-
- /*
- * Hit the inode change time.
- */
- if (!error && (flags & ATTR_KERNOTIME) == 0) {
- xfs_ichgtime(dp, XFS_ICHGTIME_CHG);
- }
-
- return(error);
-
-out:
- if (args.trans)
- xfs_trans_cancel(args.trans,
- XFS_TRANS_RELEASE_LOG_RES|XFS_TRANS_ABORT);
- xfs_iunlock(dp, XFS_ILOCK_EXCL);
- return(error);
-}
-
-int
-xfs_attr_remove(bhv_desc_t *bdp, const char *name, int flags, struct cred *cred)
-{
- xfs_inode_t *dp;
- int namelen;
-
- namelen = strlen(name);
- if (namelen >= MAXNAMELEN)
- return EFAULT; /* match IRIX behaviour */
-
- XFS_STATS_INC(xs_attr_remove);
-
- dp = XFS_BHVTOI(bdp);
- if (XFS_FORCED_SHUTDOWN(dp->i_mount))
- return (EIO);
-
- xfs_ilock(dp, XFS_ILOCK_SHARED);
- if (XFS_IFORK_Q(dp) == 0 ||
- (dp->i_d.di_aformat == XFS_DINODE_FMT_EXTENTS &&
- dp->i_d.di_anextents == 0)) {
- xfs_iunlock(dp, XFS_ILOCK_SHARED);
- return(XFS_ERROR(ENOATTR));
- }
- xfs_iunlock(dp, XFS_ILOCK_SHARED);
-
- return xfs_attr_remove_int(dp, name, namelen, flags);
-}
-
-/*
- * Generate a list of extended attribute names and optionally
- * also value lengths. Positive return value follows the XFS
- * convention of being an error, zero or negative return code
- * is the length of the buffer returned (negated), indicating
- * success.
- */
-int
-xfs_attr_list(bhv_desc_t *bdp, char *buffer, int bufsize, int flags,
- attrlist_cursor_kern_t *cursor, struct cred *cred)
-{
- xfs_attr_list_context_t context;
- xfs_inode_t *dp;
- int error;
-
- XFS_STATS_INC(xs_attr_list);
-
- /*
- * Validate the cursor.
- */
- if (cursor->pad1 || cursor->pad2)
- return(XFS_ERROR(EINVAL));
- if ((cursor->initted == 0) &&
- (cursor->hashval || cursor->blkno || cursor->offset))
- return(XFS_ERROR(EINVAL));
-
- /*
- * Check for a properly aligned buffer.
- */
- if (((long)buffer) & (sizeof(int)-1))
- return(XFS_ERROR(EFAULT));
- if (flags & ATTR_KERNOVAL)
- bufsize = 0;
-
- /*
- * Initialize the output buffer.
- */
- context.dp = dp = XFS_BHVTOI(bdp);
- context.cursor = cursor;
- context.count = 0;
- context.dupcnt = 0;
- context.resynch = 1;
- context.flags = flags;
- if (!(flags & ATTR_KERNAMELS)) {
- context.bufsize = (bufsize & ~(sizeof(int)-1)); /* align */
- context.firstu = context.bufsize;
- context.alist = (attrlist_t *)buffer;
- context.alist->al_count = 0;
- context.alist->al_more = 0;
- context.alist->al_offset[0] = context.bufsize;
- }
- else {
- context.bufsize = bufsize;
- context.firstu = context.bufsize;
- context.alist = (attrlist_t *)buffer;
- }
-
- if (XFS_FORCED_SHUTDOWN(dp->i_mount))
- return (EIO);
-
- xfs_ilock(dp, XFS_ILOCK_SHARED);
- /*
- * Decide on what work routines to call based on the inode size.
- */
- xfs_attr_trace_l_c("syscall start", &context);
- if (XFS_IFORK_Q(dp) == 0 ||
- (dp->i_d.di_aformat == XFS_DINODE_FMT_EXTENTS &&
- dp->i_d.di_anextents == 0)) {
- error = 0;
- } else if (dp->i_d.di_aformat == XFS_DINODE_FMT_LOCAL) {
- error = xfs_attr_shortform_list(&context);
- } else if (xfs_bmap_one_block(dp, XFS_ATTR_FORK)) {
- error = xfs_attr_leaf_list(&context);
- } else {
- error = xfs_attr_node_list(&context);
- }
- xfs_iunlock(dp, XFS_ILOCK_SHARED);
- xfs_attr_trace_l_c("syscall end", &context);
-
- if (!(context.flags & (ATTR_KERNOVAL|ATTR_KERNAMELS))) {
- ASSERT(error >= 0);
- }
- else { /* must return negated buffer size or the error */
- if (context.count < 0)
- error = XFS_ERROR(ERANGE);
- else
- error = -context.count;
- }
-
- return(error);
-}
-
-int /* error */
-xfs_attr_inactive(xfs_inode_t *dp)
-{
- xfs_trans_t *trans;
- xfs_mount_t *mp;
- int error;
-
- mp = dp->i_mount;
- ASSERT(! XFS_NOT_DQATTACHED(mp, dp));
-
- xfs_ilock(dp, XFS_ILOCK_SHARED);
- if ((XFS_IFORK_Q(dp) == 0) ||
- (dp->i_d.di_aformat == XFS_DINODE_FMT_LOCAL) ||
- (dp->i_d.di_aformat == XFS_DINODE_FMT_EXTENTS &&
- dp->i_d.di_anextents == 0)) {
- xfs_iunlock(dp, XFS_ILOCK_SHARED);
- return(0);
- }
- xfs_iunlock(dp, XFS_ILOCK_SHARED);
-
- /*
- * Start our first transaction of the day.
- *
- * All future transactions during this code must be "chained" off
- * this one via the trans_dup() call. All transactions will contain
- * the inode, and the inode will always be marked with trans_ihold().
- * Since the inode will be locked in all transactions, we must log
- * the inode in every transaction to let it float upward through
- * the log.
- */
- trans = xfs_trans_alloc(mp, XFS_TRANS_ATTRINVAL);
- if ((error = xfs_trans_reserve(trans, 0, XFS_ATTRINVAL_LOG_RES(mp), 0,
- XFS_TRANS_PERM_LOG_RES,
- XFS_ATTRINVAL_LOG_COUNT))) {
- xfs_trans_cancel(trans, 0);
- return(error);
- }
- xfs_ilock(dp, XFS_ILOCK_EXCL);
-
- /*
- * No need to make quota reservations here. We expect to release some
- * blocks, not allocate, in the common case.
- */
- xfs_trans_ijoin(trans, dp, XFS_ILOCK_EXCL);
- xfs_trans_ihold(trans, dp);
-
- /*
- * Decide on what work routines to call based on the inode size.
- */
- if ((XFS_IFORK_Q(dp) == 0) ||
- (dp->i_d.di_aformat == XFS_DINODE_FMT_LOCAL) ||
- (dp->i_d.di_aformat == XFS_DINODE_FMT_EXTENTS &&
- dp->i_d.di_anextents == 0)) {
- error = 0;
- goto out;
- }
- error = xfs_attr_root_inactive(&trans, dp);
- if (error)
- goto out;
- /*
- * signal synchronous inactive transactions unless this
- * is a synchronous mount filesystem in which case we
- * know that we're here because we've been called out of
- * xfs_inactive which means that the last reference is gone
- * and the unlink transaction has already hit the disk so
- * async inactive transactions are safe.
- */
- if ((error = xfs_itruncate_finish(&trans, dp, 0LL, XFS_ATTR_FORK,
- (!(mp->m_flags & XFS_MOUNT_WSYNC)
- ? 1 : 0))))
- goto out;
-
- /*
- * Commit the last in the sequence of transactions.
- */
- xfs_trans_log_inode(trans, dp, XFS_ILOG_CORE);
- error = xfs_trans_commit(trans, XFS_TRANS_RELEASE_LOG_RES,
- NULL);
- xfs_iunlock(dp, XFS_ILOCK_EXCL);
-
- return(error);
-
-out:
- xfs_trans_cancel(trans, XFS_TRANS_RELEASE_LOG_RES|XFS_TRANS_ABORT);
- xfs_iunlock(dp, XFS_ILOCK_EXCL);
- return(error);
-}
-
-
-
-/*========================================================================
- * External routines when attribute list is inside the inode
- *========================================================================*/
-
-/*
- * Add a name to the shortform attribute list structure
- * This is the external routine.
- */
-STATIC int
-xfs_attr_shortform_addname(xfs_da_args_t *args)
-{
- int newsize, forkoff, retval;
-
- retval = xfs_attr_shortform_lookup(args);
- if ((args->flags & ATTR_REPLACE) && (retval == ENOATTR)) {
- return(retval);
- } else if (retval == EEXIST) {
- if (args->flags & ATTR_CREATE)
- return(retval);
- retval = xfs_attr_shortform_remove(args);
- ASSERT(retval == 0);
- }
-
- if (args->namelen >= XFS_ATTR_SF_ENTSIZE_MAX ||
- args->valuelen >= XFS_ATTR_SF_ENTSIZE_MAX)
- return(XFS_ERROR(ENOSPC));
-
- newsize = XFS_ATTR_SF_TOTSIZE(args->dp);
- newsize += XFS_ATTR_SF_ENTSIZE_BYNAME(args->namelen, args->valuelen);
-
- forkoff = xfs_attr_shortform_bytesfit(args->dp, newsize);
- if (!forkoff)
- return(XFS_ERROR(ENOSPC));
-
- xfs_attr_shortform_add(args, forkoff);
- return(0);
-}
-
-
-/*========================================================================
- * External routines when attribute list is one block
- *========================================================================*/
-
-/*
- * Add a name to the leaf attribute list structure
- *
- * This leaf block cannot have a "remote" value, we only call this routine
- * if bmap_one_block() says there is only one block (ie: no remote blks).
- */
-int
-xfs_attr_leaf_addname(xfs_da_args_t *args)
-{
- xfs_inode_t *dp;
- xfs_dabuf_t *bp;
- int retval, error, committed, forkoff;
-
- /*
- * Read the (only) block in the attribute list in.
- */
- dp = args->dp;
- args->blkno = 0;
- error = xfs_da_read_buf(args->trans, args->dp, args->blkno, -1, &bp,
- XFS_ATTR_FORK);
- if (error)
- return(error);
- ASSERT(bp != NULL);
-
- /*
- * Look up the given attribute in the leaf block. Figure out if
- * the given flags produce an error or call for an atomic rename.
- */
- retval = xfs_attr_leaf_lookup_int(bp, args);
- if ((args->flags & ATTR_REPLACE) && (retval == ENOATTR)) {
- xfs_da_brelse(args->trans, bp);
- return(retval);
- } else if (retval == EEXIST) {
- if (args->flags & ATTR_CREATE) { /* pure create op */
- xfs_da_brelse(args->trans, bp);
- return(retval);
- }
- args->rename = 1; /* an atomic rename */
- args->blkno2 = args->blkno; /* set 2nd entry info*/
- args->index2 = args->index;
- args->rmtblkno2 = args->rmtblkno;
- args->rmtblkcnt2 = args->rmtblkcnt;
- }
-
- /*
- * Add the attribute to the leaf block, transitioning to a Btree
- * if required.
- */
- retval = xfs_attr_leaf_add(bp, args);
- xfs_da_buf_done(bp);
- if (retval == ENOSPC) {
- /*
- * Promote the attribute list to the Btree format, then
- * Commit that transaction so that the node_addname() call
- * can manage its own transactions.
- */
- XFS_BMAP_INIT(args->flist, args->firstblock);
- error = xfs_attr_leaf_to_node(args);
- if (!error) {
- error = xfs_bmap_finish(&args->trans, args->flist,
- *args->firstblock, &committed);
- }
- if (error) {
- ASSERT(committed);
- args->trans = NULL;
- xfs_bmap_cancel(args->flist);
- return(error);
- }
-
- /*
- * bmap_finish() may have committed the last trans and started
- * a new one. We need the inode to be in all transactions.
- */
- if (committed) {
- xfs_trans_ijoin(args->trans, dp, XFS_ILOCK_EXCL);
- xfs_trans_ihold(args->trans, dp);
- }
-
- /*
- * Commit the current trans (including the inode) and start
- * a new one.
- */
- if ((error = xfs_attr_rolltrans(&args->trans, dp)))
- return (error);
-
- /*
- * Fob the whole rest of the problem off on the Btree code.
- */
- error = xfs_attr_node_addname(args);
- return(error);
- }
-
- /*
- * Commit the transaction that added the attr name so that
- * later routines can manage their own transactions.
- */
- if ((error = xfs_attr_rolltrans(&args->trans, dp)))
- return (error);
-
- /*
- * If there was an out-of-line value, allocate the blocks we
- * identified for its storage and copy the value. This is done
- * after we create the attribute so that we don't overflow the
- * maximum size of a transaction and/or hit a deadlock.
- */
- if (args->rmtblkno > 0) {
- error = xfs_attr_rmtval_set(args);
- if (error)
- return(error);
- }
-
- /*
- * If this is an atomic rename operation, we must "flip" the
- * incomplete flags on the "new" and "old" attribute/value pairs
- * so that one disappears and one appears atomically. Then we
- * must remove the "old" attribute/value pair.
- */
- if (args->rename) {
- /*
- * In a separate transaction, set the incomplete flag on the
- * "old" attr and clear the incomplete flag on the "new" attr.
- */
- error = xfs_attr_leaf_flipflags(args);
- if (error)
- return(error);
-
- /*
- * Dismantle the "old" attribute/value pair by removing
- * a "remote" value (if it exists).
- */
- args->index = args->index2;
- args->blkno = args->blkno2;
- args->rmtblkno = args->rmtblkno2;
- args->rmtblkcnt = args->rmtblkcnt2;
- if (args->rmtblkno) {
- error = xfs_attr_rmtval_remove(args);
- if (error)
- return(error);
- }
-
- /*
- * Read in the block containing the "old" attr, then
- * remove the "old" attr from that block (neat, huh!)
- */
- error = xfs_da_read_buf(args->trans, args->dp, args->blkno, -1,
- &bp, XFS_ATTR_FORK);
- if (error)
- return(error);
- ASSERT(bp != NULL);
- (void)xfs_attr_leaf_remove(bp, args);
-
- /*
- * If the result is small enough, shrink it all into the inode.
- */
- if ((forkoff = xfs_attr_shortform_allfit(bp, dp))) {
- XFS_BMAP_INIT(args->flist, args->firstblock);
- error = xfs_attr_leaf_to_shortform(bp, args, forkoff);
- /* bp is gone due to xfs_da_shrink_inode */
- if (!error) {
- error = xfs_bmap_finish(&args->trans,
- args->flist,
- *args->firstblock,
- &committed);
- }
- if (error) {
- ASSERT(committed);
- args->trans = NULL;
- xfs_bmap_cancel(args->flist);
- return(error);
- }
-
- /*
- * bmap_finish() may have committed the last trans
- * and started a new one. We need the inode to be
- * in all transactions.
- */
- if (committed) {
- xfs_trans_ijoin(args->trans, dp, XFS_ILOCK_EXCL);
- xfs_trans_ihold(args->trans, dp);
- }
- } else
- xfs_da_buf_done(bp);
-
- /*
- * Commit the remove and start the next trans in series.
- */
- error = xfs_attr_rolltrans(&args->trans, dp);
-
- } else if (args->rmtblkno > 0) {
- /*
- * Added a "remote" value, just clear the incomplete flag.
- */
- error = xfs_attr_leaf_clearflag(args);
- }
- return(error);
-}
-
-/*
- * Remove a name from the leaf attribute list structure
- *
- * This leaf block cannot have a "remote" value, we only call this routine
- * if bmap_one_block() says there is only one block (ie: no remote blks).
- */
-STATIC int
-xfs_attr_leaf_removename(xfs_da_args_t *args)
-{
- xfs_inode_t *dp;
- xfs_dabuf_t *bp;
- int error, committed, forkoff;
-
- /*
- * Remove the attribute.
- */
- dp = args->dp;
- args->blkno = 0;
- error = xfs_da_read_buf(args->trans, args->dp, args->blkno, -1, &bp,
- XFS_ATTR_FORK);
- if (error) {
- return(error);
- }
-
- ASSERT(bp != NULL);
- error = xfs_attr_leaf_lookup_int(bp, args);
- if (error == ENOATTR) {
- xfs_da_brelse(args->trans, bp);
- return(error);
- }
-
- (void)xfs_attr_leaf_remove(bp, args);
-
- /*
- * If the result is small enough, shrink it all into the inode.
- */
- if ((forkoff = xfs_attr_shortform_allfit(bp, dp))) {
- XFS_BMAP_INIT(args->flist, args->firstblock);
- error = xfs_attr_leaf_to_shortform(bp, args, forkoff);
- /* bp is gone due to xfs_da_shrink_inode */
- if (!error) {
- error = xfs_bmap_finish(&args->trans, args->flist,
- *args->firstblock, &committed);
- }
- if (error) {
- ASSERT(committed);
- args->trans = NULL;
- xfs_bmap_cancel(args->flist);
- return(error);
- }
-
- /*
- * bmap_finish() may have committed the last trans and started
- * a new one. We need the inode to be in all transactions.
- */
- if (committed) {
- xfs_trans_ijoin(args->trans, dp, XFS_ILOCK_EXCL);
- xfs_trans_ihold(args->trans, dp);
- }
- } else
- xfs_da_buf_done(bp);
- return(0);
-}
-
-/*
- * Look up a name in a leaf attribute list structure.
- *
- * This leaf block cannot have a "remote" value, we only call this routine
- * if bmap_one_block() says there is only one block (ie: no remote blks).
- */
-STATIC int
-xfs_attr_leaf_get(xfs_da_args_t *args)
-{
- xfs_dabuf_t *bp;
- int error;
-
- args->blkno = 0;
- error = xfs_da_read_buf(args->trans, args->dp, args->blkno, -1, &bp,
- XFS_ATTR_FORK);
- if (error)
- return(error);
- ASSERT(bp != NULL);
-
- error = xfs_attr_leaf_lookup_int(bp, args);
- if (error != EEXIST) {
- xfs_da_brelse(args->trans, bp);
- return(error);
- }
- error = xfs_attr_leaf_getvalue(bp, args);
- xfs_da_brelse(args->trans, bp);
- if (!error && (args->rmtblkno > 0) && !(args->flags & ATTR_KERNOVAL)) {
- error = xfs_attr_rmtval_get(args);
- }
- return(error);
-}
-
-/*
- * Copy out attribute entries for attr_list(), for leaf attribute lists.
- */
-STATIC int
-xfs_attr_leaf_list(xfs_attr_list_context_t *context)
-{
- xfs_attr_leafblock_t *leaf;
- int error;
- xfs_dabuf_t *bp;
-
- context->cursor->blkno = 0;
- error = xfs_da_read_buf(NULL, context->dp, 0, -1, &bp, XFS_ATTR_FORK);
- if (error)
- return(error);
- ASSERT(bp != NULL);
- leaf = bp->data;
- if (unlikely(be16_to_cpu(leaf->hdr.info.magic) != XFS_ATTR_LEAF_MAGIC)) {
- XFS_CORRUPTION_ERROR("xfs_attr_leaf_list", XFS_ERRLEVEL_LOW,
- context->dp->i_mount, leaf);
- xfs_da_brelse(NULL, bp);
- return(XFS_ERROR(EFSCORRUPTED));
- }
-
- (void)xfs_attr_leaf_list_int(bp, context);
- xfs_da_brelse(NULL, bp);
- return(0);
-}
-
-
-/*========================================================================
- * External routines when attribute list size > XFS_LBSIZE(mp).
- *========================================================================*/
-
-/*
- * Add a name to a Btree-format attribute list.
- *
- * This will involve walking down the Btree, and may involve splitting
- * leaf nodes and even splitting intermediate nodes up to and including
- * the root node (a special case of an intermediate node).
- *
- * "Remote" attribute values confuse the issue and atomic rename operations
- * add a whole extra layer of confusion on top of that.
- */
-STATIC int
-xfs_attr_node_addname(xfs_da_args_t *args)
-{
- xfs_da_state_t *state;
- xfs_da_state_blk_t *blk;
- xfs_inode_t *dp;
- xfs_mount_t *mp;
- int committed, retval, error;
-
- /*
- * Fill in bucket of arguments/results/context to carry around.
- */
- dp = args->dp;
- mp = dp->i_mount;
-restart:
- state = xfs_da_state_alloc();
- state->args = args;
- state->mp = mp;
- state->blocksize = state->mp->m_sb.sb_blocksize;
- state->node_ents = state->mp->m_attr_node_ents;
-
- /*
- * Search to see if name already exists, and get back a pointer
- * to where it should go.
- */
- error = xfs_da_node_lookup_int(state, &retval);
- if (error)
- goto out;
- blk = &state->path.blk[ state->path.active-1 ];
- ASSERT(blk->magic == XFS_ATTR_LEAF_MAGIC);
- if ((args->flags & ATTR_REPLACE) && (retval == ENOATTR)) {
- goto out;
- } else if (retval == EEXIST) {
- if (args->flags & ATTR_CREATE)
- goto out;
- args->rename = 1; /* atomic rename op */
- args->blkno2 = args->blkno; /* set 2nd entry info*/
- args->index2 = args->index;
- args->rmtblkno2 = args->rmtblkno;
- args->rmtblkcnt2 = args->rmtblkcnt;
- args->rmtblkno = 0;
- args->rmtblkcnt = 0;
- }
-
- retval = xfs_attr_leaf_add(blk->bp, state->args);
- if (retval == ENOSPC) {
- if (state->path.active == 1) {
- /*
- * Its really a single leaf node, but it had
- * out-of-line values so it looked like it *might*
- * have been a b-tree.
- */
- xfs_da_state_free(state);
- XFS_BMAP_INIT(args->flist, args->firstblock);
- error = xfs_attr_leaf_to_node(args);
- if (!error) {
- error = xfs_bmap_finish(&args->trans,
- args->flist,
- *args->firstblock,
- &committed);
- }
- if (error) {
- ASSERT(committed);
- args->trans = NULL;
- xfs_bmap_cancel(args->flist);
- goto out;
- }
-
- /*
- * bmap_finish() may have committed the last trans
- * and started a new one. We need the inode to be
- * in all transactions.
- */
- if (committed) {
- xfs_trans_ijoin(args->trans, dp, XFS_ILOCK_EXCL);
- xfs_trans_ihold(args->trans, dp);
- }
-
- /*
- * Commit the node conversion and start the next
- * trans in the chain.
- */
- if ((error = xfs_attr_rolltrans(&args->trans, dp)))
- goto out;
-
- goto restart;
- }
-
- /*
- * Split as many Btree elements as required.
- * This code tracks the new and old attr's location
- * in the index/blkno/rmtblkno/rmtblkcnt fields and
- * in the index2/blkno2/rmtblkno2/rmtblkcnt2 fields.
- */
- XFS_BMAP_INIT(args->flist, args->firstblock);
- error = xfs_da_split(state);
- if (!error) {
- error = xfs_bmap_finish(&args->trans, args->flist,
- *args->firstblock, &committed);
- }
- if (error) {
- ASSERT(committed);
- args->trans = NULL;
- xfs_bmap_cancel(args->flist);
- goto out;
- }
-
- /*
- * bmap_finish() may have committed the last trans and started
- * a new one. We need the inode to be in all transactions.
- */
- if (committed) {
- xfs_trans_ijoin(args->trans, dp, XFS_ILOCK_EXCL);
- xfs_trans_ihold(args->trans, dp);
- }
- } else {
- /*
- * Addition succeeded, update Btree hashvals.
- */
- xfs_da_fixhashpath(state, &state->path);
- }
-
- /*
- * Kill the state structure, we're done with it and need to
- * allow the buffers to come back later.
- */
- xfs_da_state_free(state);
- state = NULL;
-
- /*
- * Commit the leaf addition or btree split and start the next
- * trans in the chain.
- */
- if ((error = xfs_attr_rolltrans(&args->trans, dp)))
- goto out;
-
- /*
- * If there was an out-of-line value, allocate the blocks we
- * identified for its storage and copy the value. This is done
- * after we create the attribute so that we don't overflow the
- * maximum size of a transaction and/or hit a deadlock.
- */
- if (args->rmtblkno > 0) {
- error = xfs_attr_rmtval_set(args);
- if (error)
- return(error);
- }
-
- /*
- * If this is an atomic rename operation, we must "flip" the
- * incomplete flags on the "new" and "old" attribute/value pairs
- * so that one disappears and one appears atomically. Then we
- * must remove the "old" attribute/value pair.
- */
- if (args->rename) {
- /*
- * In a separate transaction, set the incomplete flag on the
- * "old" attr and clear the incomplete flag on the "new" attr.
- */
- error = xfs_attr_leaf_flipflags(args);
- if (error)
- goto out;
-
- /*
- * Dismantle the "old" attribute/value pair by removing
- * a "remote" value (if it exists).
- */
- args->index = args->index2;
- args->blkno = args->blkno2;
- args->rmtblkno = args->rmtblkno2;
- args->rmtblkcnt = args->rmtblkcnt2;
- if (args->rmtblkno) {
- error = xfs_attr_rmtval_remove(args);
- if (error)
- return(error);
- }
-
- /*
- * Re-find the "old" attribute entry after any split ops.
- * The INCOMPLETE flag means that we will find the "old"
- * attr, not the "new" one.
- */
- args->flags |= XFS_ATTR_INCOMPLETE;
- state = xfs_da_state_alloc();
- state->args = args;
- state->mp = mp;
- state->blocksize = state->mp->m_sb.sb_blocksize;
- state->node_ents = state->mp->m_attr_node_ents;
- state->inleaf = 0;
- error = xfs_da_node_lookup_int(state, &retval);
- if (error)
- goto out;
-
- /*
- * Remove the name and update the hashvals in the tree.
- */
- blk = &state->path.blk[ state->path.active-1 ];
- ASSERT(blk->magic == XFS_ATTR_LEAF_MAGIC);
- error = xfs_attr_leaf_remove(blk->bp, args);
- xfs_da_fixhashpath(state, &state->path);
-
- /*
- * Check to see if the tree needs to be collapsed.
- */
- if (retval && (state->path.active > 1)) {
- XFS_BMAP_INIT(args->flist, args->firstblock);
- error = xfs_da_join(state);
- if (!error) {
- error = xfs_bmap_finish(&args->trans,
- args->flist,
- *args->firstblock,
- &committed);
- }
- if (error) {
- ASSERT(committed);
- args->trans = NULL;
- xfs_bmap_cancel(args->flist);
- goto out;
- }
-
- /*
- * bmap_finish() may have committed the last trans
- * and started a new one. We need the inode to be
- * in all transactions.
- */
- if (committed) {
- xfs_trans_ijoin(args->trans, dp, XFS_ILOCK_EXCL);
- xfs_trans_ihold(args->trans, dp);
- }
- }
-
- /*
- * Commit and start the next trans in the chain.
- */
- if ((error = xfs_attr_rolltrans(&args->trans, dp)))
- goto out;
-
- } else if (args->rmtblkno > 0) {
- /*
- * Added a "remote" value, just clear the incomplete flag.
- */
- error = xfs_attr_leaf_clearflag(args);
- if (error)
- goto out;
- }
- retval = error = 0;
-
-out:
- if (state)
- xfs_da_state_free(state);
- if (error)
- return(error);
- return(retval);
-}
-
-/*
- * Remove a name from a B-tree attribute list.
- *
- * This will involve walking down the Btree, and may involve joining
- * leaf nodes and even joining intermediate nodes up to and including
- * the root node (a special case of an intermediate node).
- */
-STATIC int
-xfs_attr_node_removename(xfs_da_args_t *args)
-{
- xfs_da_state_t *state;
- xfs_da_state_blk_t *blk;
- xfs_inode_t *dp;
- xfs_dabuf_t *bp;
- int retval, error, committed, forkoff;
-
- /*
- * Tie a string around our finger to remind us where we are.
- */
- dp = args->dp;
- state = xfs_da_state_alloc();
- state->args = args;
- state->mp = dp->i_mount;
- state->blocksize = state->mp->m_sb.sb_blocksize;
- state->node_ents = state->mp->m_attr_node_ents;
-
- /*
- * Search to see if name exists, and get back a pointer to it.
- */
- error = xfs_da_node_lookup_int(state, &retval);
- if (error || (retval != EEXIST)) {
- if (error == 0)
- error = retval;
- goto out;
- }
-
- /*
- * If there is an out-of-line value, de-allocate the blocks.
- * This is done before we remove the attribute so that we don't
- * overflow the maximum size of a transaction and/or hit a deadlock.
- */
- blk = &state->path.blk[ state->path.active-1 ];
- ASSERT(blk->bp != NULL);
- ASSERT(blk->magic == XFS_ATTR_LEAF_MAGIC);
- if (args->rmtblkno > 0) {
- /*
- * Fill in disk block numbers in the state structure
- * so that we can get the buffers back after we commit
- * several transactions in the following calls.
- */
- error = xfs_attr_fillstate(state);
- if (error)
- goto out;
-
- /*
- * Mark the attribute as INCOMPLETE, then bunmapi() the
- * remote value.
- */
- error = xfs_attr_leaf_setflag(args);
- if (error)
- goto out;
- error = xfs_attr_rmtval_remove(args);
- if (error)
- goto out;
-
- /*
- * Refill the state structure with buffers, the prior calls
- * released our buffers.
- */
- error = xfs_attr_refillstate(state);
- if (error)
- goto out;
- }
-
- /*
- * Remove the name and update the hashvals in the tree.
- */
- blk = &state->path.blk[ state->path.active-1 ];
- ASSERT(blk->magic == XFS_ATTR_LEAF_MAGIC);
- retval = xfs_attr_leaf_remove(blk->bp, args);
- xfs_da_fixhashpath(state, &state->path);
-
- /*
- * Check to see if the tree needs to be collapsed.
- */
- if (retval && (state->path.active > 1)) {
- XFS_BMAP_INIT(args->flist, args->firstblock);
- error = xfs_da_join(state);
- if (!error) {
- error = xfs_bmap_finish(&args->trans, args->flist,
- *args->firstblock, &committed);
- }
- if (error) {
- ASSERT(committed);
- args->trans = NULL;
- xfs_bmap_cancel(args->flist);
- goto out;
- }
-
- /*
- * bmap_finish() may have committed the last trans and started
- * a new one. We need the inode to be in all transactions.
- */
- if (committed) {
- xfs_trans_ijoin(args->trans, dp, XFS_ILOCK_EXCL);
- xfs_trans_ihold(args->trans, dp);
- }
-
- /*
- * Commit the Btree join operation and start a new trans.
- */
- if ((error = xfs_attr_rolltrans(&args->trans, dp)))
- goto out;
- }
-
- /*
- * If the result is small enough, push it all into the inode.
- */
- if (xfs_bmap_one_block(dp, XFS_ATTR_FORK)) {
- /*
- * Have to get rid of the copy of this dabuf in the state.
- */
- ASSERT(state->path.active == 1);
- ASSERT(state->path.blk[0].bp);
- xfs_da_buf_done(state->path.blk[0].bp);
- state->path.blk[0].bp = NULL;
-
- error = xfs_da_read_buf(args->trans, args->dp, 0, -1, &bp,
- XFS_ATTR_FORK);
- if (error)
- goto out;
- ASSERT(be16_to_cpu(((xfs_attr_leafblock_t *)
- bp->data)->hdr.info.magic)
- == XFS_ATTR_LEAF_MAGIC);
-
- if ((forkoff = xfs_attr_shortform_allfit(bp, dp))) {
- XFS_BMAP_INIT(args->flist, args->firstblock);
- error = xfs_attr_leaf_to_shortform(bp, args, forkoff);
- /* bp is gone due to xfs_da_shrink_inode */
- if (!error) {
- error = xfs_bmap_finish(&args->trans,
- args->flist,
- *args->firstblock,
- &committed);
- }
- if (error) {
- ASSERT(committed);
- args->trans = NULL;
- xfs_bmap_cancel(args->flist);
- goto out;
- }
-
- /*
- * bmap_finish() may have committed the last trans
- * and started a new one. We need the inode to be
- * in all transactions.
- */
- if (committed) {
- xfs_trans_ijoin(args->trans, dp, XFS_ILOCK_EXCL);
- xfs_trans_ihold(args->trans, dp);
- }
- } else
- xfs_da_brelse(args->trans, bp);
- }
- error = 0;
-
-out:
- xfs_da_state_free(state);
- return(error);
-}
-
-/*
- * Fill in the disk block numbers in the state structure for the buffers
- * that are attached to the state structure.
- * This is done so that we can quickly reattach ourselves to those buffers
- * after some set of transaction commits have released these buffers.
- */
-STATIC int
-xfs_attr_fillstate(xfs_da_state_t *state)
-{
- xfs_da_state_path_t *path;
- xfs_da_state_blk_t *blk;
- int level;
-
- /*
- * Roll down the "path" in the state structure, storing the on-disk
- * block number for those buffers in the "path".
- */
- path = &state->path;
- ASSERT((path->active >= 0) && (path->active < XFS_DA_NODE_MAXDEPTH));
- for (blk = path->blk, level = 0; level < path->active; blk++, level++) {
- if (blk->bp) {
- blk->disk_blkno = xfs_da_blkno(blk->bp);
- xfs_da_buf_done(blk->bp);
- blk->bp = NULL;
- } else {
- blk->disk_blkno = 0;
- }
- }
-
- /*
- * Roll down the "altpath" in the state structure, storing the on-disk
- * block number for those buffers in the "altpath".
- */
- path = &state->altpath;
- ASSERT((path->active >= 0) && (path->active < XFS_DA_NODE_MAXDEPTH));
- for (blk = path->blk, level = 0; level < path->active; blk++, level++) {
- if (blk->bp) {
- blk->disk_blkno = xfs_da_blkno(blk->bp);
- xfs_da_buf_done(blk->bp);
- blk->bp = NULL;
- } else {
- blk->disk_blkno = 0;
- }
- }
-
- return(0);
-}
-
-/*
- * Reattach the buffers to the state structure based on the disk block
- * numbers stored in the state structure.
- * This is done after some set of transaction commits have released those
- * buffers from our grip.
- */
-STATIC int
-xfs_attr_refillstate(xfs_da_state_t *state)
-{
- xfs_da_state_path_t *path;
- xfs_da_state_blk_t *blk;
- int level, error;
-
- /*
- * Roll down the "path" in the state structure, storing the on-disk
- * block number for those buffers in the "path".
- */
- path = &state->path;
- ASSERT((path->active >= 0) && (path->active < XFS_DA_NODE_MAXDEPTH));
- for (blk = path->blk, level = 0; level < path->active; blk++, level++) {
- if (blk->disk_blkno) {
- error = xfs_da_read_buf(state->args->trans,
- state->args->dp,
- blk->blkno, blk->disk_blkno,
- &blk->bp, XFS_ATTR_FORK);
- if (error)
- return(error);
- } else {
- blk->bp = NULL;
- }
- }
-
- /*
- * Roll down the "altpath" in the state structure, storing the on-disk
- * block number for those buffers in the "altpath".
- */
- path = &state->altpath;
- ASSERT((path->active >= 0) && (path->active < XFS_DA_NODE_MAXDEPTH));
- for (blk = path->blk, level = 0; level < path->active; blk++, level++) {
- if (blk->disk_blkno) {
- error = xfs_da_read_buf(state->args->trans,
- state->args->dp,
- blk->blkno, blk->disk_blkno,
- &blk->bp, XFS_ATTR_FORK);
- if (error)
- return(error);
- } else {
- blk->bp = NULL;
- }
- }
-
- return(0);
-}
-
-/*
- * Look up a filename in a node attribute list.
- *
- * This routine gets called for any attribute fork that has more than one
- * block, ie: both true Btree attr lists and for single-leaf-blocks with
- * "remote" values taking up more blocks.
- */
-STATIC int
-xfs_attr_node_get(xfs_da_args_t *args)
-{
- xfs_da_state_t *state;
- xfs_da_state_blk_t *blk;
- int error, retval;
- int i;
-
- state = xfs_da_state_alloc();
- state->args = args;
- state->mp = args->dp->i_mount;
- state->blocksize = state->mp->m_sb.sb_blocksize;
- state->node_ents = state->mp->m_attr_node_ents;
-
- /*
- * Search to see if name exists, and get back a pointer to it.
- */
- error = xfs_da_node_lookup_int(state, &retval);
- if (error) {
- retval = error;
- } else if (retval == EEXIST) {
- blk = &state->path.blk[ state->path.active-1 ];
- ASSERT(blk->bp != NULL);
- ASSERT(blk->magic == XFS_ATTR_LEAF_MAGIC);
-
- /*
- * Get the value, local or "remote"
- */
- retval = xfs_attr_leaf_getvalue(blk->bp, args);
- if (!retval && (args->rmtblkno > 0)
- && !(args->flags & ATTR_KERNOVAL)) {
- retval = xfs_attr_rmtval_get(args);
- }
- }
-
- /*
- * If not in a transaction, we have to release all the buffers.
- */
- for (i = 0; i < state->path.active; i++) {
- xfs_da_brelse(args->trans, state->path.blk[i].bp);
- state->path.blk[i].bp = NULL;
- }
-
- xfs_da_state_free(state);
- return(retval);
-}
-
-STATIC int /* error */
-xfs_attr_node_list(xfs_attr_list_context_t *context)
-{
- attrlist_cursor_kern_t *cursor;
- xfs_attr_leafblock_t *leaf;
- xfs_da_intnode_t *node;
- xfs_da_node_entry_t *btree;
- int error, i;
- xfs_dabuf_t *bp;
-
- cursor = context->cursor;
- cursor->initted = 1;
-
- /*
- * Do all sorts of validation on the passed-in cursor structure.
- * If anything is amiss, ignore the cursor and look up the hashval
- * starting from the btree root.
- */
- bp = NULL;
- if (cursor->blkno > 0) {
- error = xfs_da_read_buf(NULL, context->dp, cursor->blkno, -1,
- &bp, XFS_ATTR_FORK);
- if ((error != 0) && (error != EFSCORRUPTED))
- return(error);
- if (bp) {
- node = bp->data;
- switch (be16_to_cpu(node->hdr.info.magic)) {
- case XFS_DA_NODE_MAGIC:
- xfs_attr_trace_l_cn("wrong blk", context, node);
- xfs_da_brelse(NULL, bp);
- bp = NULL;
- break;
- case XFS_ATTR_LEAF_MAGIC:
- leaf = bp->data;
- if (cursor->hashval > be32_to_cpu(leaf->entries[
- be16_to_cpu(leaf->hdr.count)-1].hashval)) {
- xfs_attr_trace_l_cl("wrong blk",
- context, leaf);
- xfs_da_brelse(NULL, bp);
- bp = NULL;
- } else if (cursor->hashval <=
- be32_to_cpu(leaf->entries[0].hashval)) {
- xfs_attr_trace_l_cl("maybe wrong blk",
- context, leaf);
- xfs_da_brelse(NULL, bp);
- bp = NULL;
- }
- break;
- default:
- xfs_attr_trace_l_c("wrong blk - ??", context);
- xfs_da_brelse(NULL, bp);
- bp = NULL;
- }
- }
- }
-
- /*
- * We did not find what we expected given the cursor's contents,
- * so we start from the top and work down based on the hash value.
- * Note that start of node block is same as start of leaf block.
- */
- if (bp == NULL) {
- cursor->blkno = 0;
- for (;;) {
- error = xfs_da_read_buf(NULL, context->dp,
- cursor->blkno, -1, &bp,
- XFS_ATTR_FORK);
- if (error)
- return(error);
- if (unlikely(bp == NULL)) {
- XFS_ERROR_REPORT("xfs_attr_node_list(2)",
- XFS_ERRLEVEL_LOW,
- context->dp->i_mount);
- return(XFS_ERROR(EFSCORRUPTED));
- }
- node = bp->data;
- if (be16_to_cpu(node->hdr.info.magic)
- == XFS_ATTR_LEAF_MAGIC)
- break;
- if (unlikely(be16_to_cpu(node->hdr.info.magic)
- != XFS_DA_NODE_MAGIC)) {
- XFS_CORRUPTION_ERROR("xfs_attr_node_list(3)",
- XFS_ERRLEVEL_LOW,
- context->dp->i_mount,
- node);
- xfs_da_brelse(NULL, bp);
- return(XFS_ERROR(EFSCORRUPTED));
- }
- btree = node->btree;
- for (i = 0; i < be16_to_cpu(node->hdr.count);
- btree++, i++) {
- if (cursor->hashval
- <= be32_to_cpu(btree->hashval)) {
- cursor->blkno = be32_to_cpu(btree->before);
- xfs_attr_trace_l_cb("descending",
- context, btree);
- break;
- }
- }
- if (i == be16_to_cpu(node->hdr.count)) {
- xfs_da_brelse(NULL, bp);
- return(0);
- }
- xfs_da_brelse(NULL, bp);
- }
- }
- ASSERT(bp != NULL);
-
- /*
- * Roll upward through the blocks, processing each leaf block in
- * order. As long as there is space in the result buffer, keep
- * adding the information.
- */
- for (;;) {
- leaf = bp->data;
- if (unlikely(be16_to_cpu(leaf->hdr.info.magic)
- != XFS_ATTR_LEAF_MAGIC)) {
- XFS_CORRUPTION_ERROR("xfs_attr_node_list(4)",
- XFS_ERRLEVEL_LOW,
- context->dp->i_mount, leaf);
- xfs_da_brelse(NULL, bp);
- return(XFS_ERROR(EFSCORRUPTED));
- }
- error = xfs_attr_leaf_list_int(bp, context);
- if (error || !leaf->hdr.info.forw)
- break; /* not really an error, buffer full or EOF */
- cursor->blkno = be32_to_cpu(leaf->hdr.info.forw);
- xfs_da_brelse(NULL, bp);
- error = xfs_da_read_buf(NULL, context->dp, cursor->blkno, -1,
- &bp, XFS_ATTR_FORK);
- if (error)
- return(error);
- if (unlikely((bp == NULL))) {
- XFS_ERROR_REPORT("xfs_attr_node_list(5)",
- XFS_ERRLEVEL_LOW,
- context->dp->i_mount);
- return(XFS_ERROR(EFSCORRUPTED));
- }
- }
- xfs_da_brelse(NULL, bp);
- return(0);
-}
-
-
-/*========================================================================
- * External routines for manipulating out-of-line attribute values.
- *========================================================================*/
-
-/*
- * Read the value associated with an attribute from the out-of-line buffer
- * that we stored it in.
- */
-STATIC int
-xfs_attr_rmtval_get(xfs_da_args_t *args)
-{
- xfs_bmbt_irec_t map[ATTR_RMTVALUE_MAPSIZE];
- xfs_mount_t *mp;
- xfs_daddr_t dblkno;
- xfs_caddr_t dst;
- xfs_buf_t *bp;
- int nmap, error, tmp, valuelen, blkcnt, i;
- xfs_dablk_t lblkno;
-
- ASSERT(!(args->flags & ATTR_KERNOVAL));
-
- mp = args->dp->i_mount;
- dst = args->value;
- valuelen = args->valuelen;
- lblkno = args->rmtblkno;
- while (valuelen > 0) {
- nmap = ATTR_RMTVALUE_MAPSIZE;
- error = xfs_bmapi(args->trans, args->dp, (xfs_fileoff_t)lblkno,
- args->rmtblkcnt,
- XFS_BMAPI_ATTRFORK | XFS_BMAPI_METADATA,
- NULL, 0, map, &nmap, NULL, NULL);
- if (error)
- return(error);
- ASSERT(nmap >= 1);
-
- for (i = 0; (i < nmap) && (valuelen > 0); i++) {
- ASSERT((map[i].br_startblock != DELAYSTARTBLOCK) &&
- (map[i].br_startblock != HOLESTARTBLOCK));
- dblkno = XFS_FSB_TO_DADDR(mp, map[i].br_startblock);
- blkcnt = XFS_FSB_TO_BB(mp, map[i].br_blockcount);
- error = xfs_read_buf(mp, mp->m_ddev_targp, dblkno,
- blkcnt, XFS_BUF_LOCK, &bp);
- if (error)
- return(error);
-
- tmp = (valuelen < XFS_BUF_SIZE(bp))
- ? valuelen : XFS_BUF_SIZE(bp);
- xfs_biomove(bp, 0, tmp, dst, XFS_B_READ);
- xfs_buf_relse(bp);
- dst += tmp;
- valuelen -= tmp;
-
- lblkno += map[i].br_blockcount;
- }
- }
- ASSERT(valuelen == 0);
- return(0);
-}
-
-/*
- * Write the value associated with an attribute into the out-of-line buffer
- * that we have defined for it.
- */
-STATIC int
-xfs_attr_rmtval_set(xfs_da_args_t *args)
-{
- xfs_mount_t *mp;
- xfs_fileoff_t lfileoff;
- xfs_inode_t *dp;
- xfs_bmbt_irec_t map;
- xfs_daddr_t dblkno;
- xfs_caddr_t src;
- xfs_buf_t *bp;
- xfs_dablk_t lblkno;
- int blkcnt, valuelen, nmap, error, tmp, committed;
-
- dp = args->dp;
- mp = dp->i_mount;
- src = args->value;
-
- /*
- * Find a "hole" in the attribute address space large enough for
- * us to drop the new attribute's value into.
- */
- blkcnt = XFS_B_TO_FSB(mp, args->valuelen);
- lfileoff = 0;
- error = xfs_bmap_first_unused(args->trans, args->dp, blkcnt, &lfileoff,
- XFS_ATTR_FORK);
- if (error) {
- return(error);
- }
- args->rmtblkno = lblkno = (xfs_dablk_t)lfileoff;
- args->rmtblkcnt = blkcnt;
-
- /*
- * Roll through the "value", allocating blocks on disk as required.
- */
- while (blkcnt > 0) {
- /*
- * Allocate a single extent, up to the size of the value.
- */
- XFS_BMAP_INIT(args->flist, args->firstblock);
- nmap = 1;
- error = xfs_bmapi(args->trans, dp, (xfs_fileoff_t)lblkno,
- blkcnt,
- XFS_BMAPI_ATTRFORK | XFS_BMAPI_METADATA |
- XFS_BMAPI_WRITE,
- args->firstblock, args->total, &map, &nmap,
- args->flist, NULL);
- if (!error) {
- error = xfs_bmap_finish(&args->trans, args->flist,
- *args->firstblock, &committed);
- }
- if (error) {
- ASSERT(committed);
- args->trans = NULL;
- xfs_bmap_cancel(args->flist);
- return(error);
- }
-
- /*
- * bmap_finish() may have committed the last trans and started
- * a new one. We need the inode to be in all transactions.
- */
- if (committed) {
- xfs_trans_ijoin(args->trans, dp, XFS_ILOCK_EXCL);
- xfs_trans_ihold(args->trans, dp);
- }
-
- ASSERT(nmap == 1);
- ASSERT((map.br_startblock != DELAYSTARTBLOCK) &&
- (map.br_startblock != HOLESTARTBLOCK));
- lblkno += map.br_blockcount;
- blkcnt -= map.br_blockcount;
-
- /*
- * Start the next trans in the chain.
- */
- if ((error = xfs_attr_rolltrans(&args->trans, dp)))
- return (error);
- }
-
- /*
- * Roll through the "value", copying the attribute value to the
- * already-allocated blocks. Blocks are written synchronously
- * so that we can know they are all on disk before we turn off
- * the INCOMPLETE flag.
- */
- lblkno = args->rmtblkno;
- valuelen = args->valuelen;
- while (valuelen > 0) {
- /*
- * Try to remember where we decided to put the value.
- */
- XFS_BMAP_INIT(args->flist, args->firstblock);
- nmap = 1;
- error = xfs_bmapi(NULL, dp, (xfs_fileoff_t)lblkno,
- args->rmtblkcnt,
- XFS_BMAPI_ATTRFORK | XFS_BMAPI_METADATA,
- args->firstblock, 0, &map, &nmap,
- NULL, NULL);
- if (error) {
- return(error);
- }
- ASSERT(nmap == 1);
- ASSERT((map.br_startblock != DELAYSTARTBLOCK) &&
- (map.br_startblock != HOLESTARTBLOCK));
-
- dblkno = XFS_FSB_TO_DADDR(mp, map.br_startblock),
- blkcnt = XFS_FSB_TO_BB(mp, map.br_blockcount);
-
- bp = xfs_buf_get_flags(mp->m_ddev_targp, dblkno,
- blkcnt, XFS_BUF_LOCK);
- ASSERT(bp);
- ASSERT(!XFS_BUF_GETERROR(bp));
-
- tmp = (valuelen < XFS_BUF_SIZE(bp)) ? valuelen :
- XFS_BUF_SIZE(bp);
- xfs_biomove(bp, 0, tmp, src, XFS_B_WRITE);
- if (tmp < XFS_BUF_SIZE(bp))
- xfs_biozero(bp, tmp, XFS_BUF_SIZE(bp) - tmp);
- if ((error = xfs_bwrite(mp, bp))) {/* GROT: NOTE: synchronous write */
- return (error);
- }
- src += tmp;
- valuelen -= tmp;
-
- lblkno += map.br_blockcount;
- }
- ASSERT(valuelen == 0);
- return(0);
-}
-
-/*
- * Remove the value associated with an attribute by deleting the
- * out-of-line buffer that it is stored on.
- */
-STATIC int
-xfs_attr_rmtval_remove(xfs_da_args_t *args)
-{
- xfs_mount_t *mp;
- xfs_bmbt_irec_t map;
- xfs_buf_t *bp;
- xfs_daddr_t dblkno;
- xfs_dablk_t lblkno;
- int valuelen, blkcnt, nmap, error, done, committed;
-
- mp = args->dp->i_mount;
-
- /*
- * Roll through the "value", invalidating the attribute value's
- * blocks.
- */
- lblkno = args->rmtblkno;
- valuelen = args->rmtblkcnt;
- while (valuelen > 0) {
- /*
- * Try to remember where we decided to put the value.
- */
- XFS_BMAP_INIT(args->flist, args->firstblock);
- nmap = 1;
- error = xfs_bmapi(NULL, args->dp, (xfs_fileoff_t)lblkno,
- args->rmtblkcnt,
- XFS_BMAPI_ATTRFORK | XFS_BMAPI_METADATA,
- args->firstblock, 0, &map, &nmap,
- args->flist, NULL);
- if (error) {
- return(error);
- }
- ASSERT(nmap == 1);
- ASSERT((map.br_startblock != DELAYSTARTBLOCK) &&
- (map.br_startblock != HOLESTARTBLOCK));
-
- dblkno = XFS_FSB_TO_DADDR(mp, map.br_startblock),
- blkcnt = XFS_FSB_TO_BB(mp, map.br_blockcount);
-
- /*
- * If the "remote" value is in the cache, remove it.
- */
- bp = xfs_incore(mp->m_ddev_targp, dblkno, blkcnt,
- XFS_INCORE_TRYLOCK);
- if (bp) {
- XFS_BUF_STALE(bp);
- XFS_BUF_UNDELAYWRITE(bp);
- xfs_buf_relse(bp);
- bp = NULL;
- }
-
- valuelen -= map.br_blockcount;
-
- lblkno += map.br_blockcount;
- }
-
- /*
- * Keep de-allocating extents until the remote-value region is gone.
- */
- lblkno = args->rmtblkno;
- blkcnt = args->rmtblkcnt;
- done = 0;
- while (!done) {
- XFS_BMAP_INIT(args->flist, args->firstblock);
- error = xfs_bunmapi(args->trans, args->dp, lblkno, blkcnt,
- XFS_BMAPI_ATTRFORK | XFS_BMAPI_METADATA,
- 1, args->firstblock, args->flist,
- NULL, &done);
- if (!error) {
- error = xfs_bmap_finish(&args->trans, args->flist,
- *args->firstblock, &committed);
- }
- if (error) {
- ASSERT(committed);
- args->trans = NULL;
- xfs_bmap_cancel(args->flist);
- return(error);
- }
-
- /*
- * bmap_finish() may have committed the last trans and started
- * a new one. We need the inode to be in all transactions.
- */
- if (committed) {
- xfs_trans_ijoin(args->trans, args->dp, XFS_ILOCK_EXCL);
- xfs_trans_ihold(args->trans, args->dp);
- }
-
- /*
- * Close out trans and start the next one in the chain.
- */
- if ((error = xfs_attr_rolltrans(&args->trans, args->dp)))
- return (error);
- }
- return(0);
-}
-
-#if defined(XFS_ATTR_TRACE)
-/*
- * Add a trace buffer entry for an attr_list context structure.
- */
-void
-xfs_attr_trace_l_c(char *where, struct xfs_attr_list_context *context)
-{
- xfs_attr_trace_enter(XFS_ATTR_KTRACE_L_C, where,
- (__psunsigned_t)context->dp,
- (__psunsigned_t)context->cursor->hashval,
- (__psunsigned_t)context->cursor->blkno,
- (__psunsigned_t)context->cursor->offset,
- (__psunsigned_t)context->alist,
- (__psunsigned_t)context->bufsize,
- (__psunsigned_t)context->count,
- (__psunsigned_t)context->firstu,
- (__psunsigned_t)
- ((context->count > 0) &&
- !(context->flags & (ATTR_KERNAMELS|ATTR_KERNOVAL)))
- ? (ATTR_ENTRY(context->alist,
- context->count-1)->a_valuelen)
- : 0,
- (__psunsigned_t)context->dupcnt,
- (__psunsigned_t)context->flags,
- (__psunsigned_t)NULL,
- (__psunsigned_t)NULL,
- (__psunsigned_t)NULL);
-}
-
-/*
- * Add a trace buffer entry for a context structure and a Btree node.
- */
-void
-xfs_attr_trace_l_cn(char *where, struct xfs_attr_list_context *context,
- struct xfs_da_intnode *node)
-{
- xfs_attr_trace_enter(XFS_ATTR_KTRACE_L_CN, where,
- (__psunsigned_t)context->dp,
- (__psunsigned_t)context->cursor->hashval,
- (__psunsigned_t)context->cursor->blkno,
- (__psunsigned_t)context->cursor->offset,
- (__psunsigned_t)context->alist,
- (__psunsigned_t)context->bufsize,
- (__psunsigned_t)context->count,
- (__psunsigned_t)context->firstu,
- (__psunsigned_t)
- ((context->count > 0) &&
- !(context->flags & (ATTR_KERNAMELS|ATTR_KERNOVAL)))
- ? (ATTR_ENTRY(context->alist,
- context->count-1)->a_valuelen)
- : 0,
- (__psunsigned_t)context->dupcnt,
- (__psunsigned_t)context->flags,
- (__psunsigned_t)be16_to_cpu(node->hdr.count),
- (__psunsigned_t)be32_to_cpu(node->btree[0].hashval),
- (__psunsigned_t)be32_to_cpu(node->btree[
- be16_to_cpu(node->hdr.count)-1].hashval));
-}
-
-/*
- * Add a trace buffer entry for a context structure and a Btree element.
- */
-void
-xfs_attr_trace_l_cb(char *where, struct xfs_attr_list_context *context,
- struct xfs_da_node_entry *btree)
-{
- xfs_attr_trace_enter(XFS_ATTR_KTRACE_L_CB, where,
- (__psunsigned_t)context->dp,
- (__psunsigned_t)context->cursor->hashval,
- (__psunsigned_t)context->cursor->blkno,
- (__psunsigned_t)context->cursor->offset,
- (__psunsigned_t)context->alist,
- (__psunsigned_t)context->bufsize,
- (__psunsigned_t)context->count,
- (__psunsigned_t)context->firstu,
- (__psunsigned_t)
- ((context->count > 0) &&
- !(context->flags & (ATTR_KERNAMELS|ATTR_KERNOVAL)))
- ? (ATTR_ENTRY(context->alist,
- context->count-1)->a_valuelen)
- : 0,
- (__psunsigned_t)context->dupcnt,
- (__psunsigned_t)context->flags,
- (__psunsigned_t)be32_to_cpu(btree->hashval),
- (__psunsigned_t)be32_to_cpu(btree->before),
- (__psunsigned_t)NULL);
-}
-
-/*
- * Add a trace buffer entry for a context structure and a leaf block.
- */
-void
-xfs_attr_trace_l_cl(char *where, struct xfs_attr_list_context *context,
- struct xfs_attr_leafblock *leaf)
-{
- xfs_attr_trace_enter(XFS_ATTR_KTRACE_L_CL, where,
- (__psunsigned_t)context->dp,
- (__psunsigned_t)context->cursor->hashval,
- (__psunsigned_t)context->cursor->blkno,
- (__psunsigned_t)context->cursor->offset,
- (__psunsigned_t)context->alist,
- (__psunsigned_t)context->bufsize,
- (__psunsigned_t)context->count,
- (__psunsigned_t)context->firstu,
- (__psunsigned_t)
- ((context->count > 0) &&
- !(context->flags & (ATTR_KERNAMELS|ATTR_KERNOVAL)))
- ? (ATTR_ENTRY(context->alist,
- context->count-1)->a_valuelen)
- : 0,
- (__psunsigned_t)context->dupcnt,
- (__psunsigned_t)context->flags,
- (__psunsigned_t)be16_to_cpu(leaf->hdr.count),
- (__psunsigned_t)be32_to_cpu(leaf->entries[0].hashval),
- (__psunsigned_t)be32_to_cpu(leaf->entries[
- be16_to_cpu(leaf->hdr.count)-1].hashval));
-}
-
-/*
- * Add a trace buffer entry for the arguments given to the routine,
- * generic form.
- */
-void
-xfs_attr_trace_enter(int type, char *where,
- __psunsigned_t a2, __psunsigned_t a3,
- __psunsigned_t a4, __psunsigned_t a5,
- __psunsigned_t a6, __psunsigned_t a7,
- __psunsigned_t a8, __psunsigned_t a9,
- __psunsigned_t a10, __psunsigned_t a11,
- __psunsigned_t a12, __psunsigned_t a13,
- __psunsigned_t a14, __psunsigned_t a15)
-{
- ASSERT(xfs_attr_trace_buf);
- ktrace_enter(xfs_attr_trace_buf, (void *)((__psunsigned_t)type),
- (void *)where,
- (void *)a2, (void *)a3, (void *)a4,
- (void *)a5, (void *)a6, (void *)a7,
- (void *)a8, (void *)a9, (void *)a10,
- (void *)a11, (void *)a12, (void *)a13,
- (void *)a14, (void *)a15);
-}
-#endif /* XFS_ATTR_TRACE */
-
-
-/*========================================================================
- * System (pseudo) namespace attribute interface routines.
- *========================================================================*/
-
-STATIC int
-posix_acl_access_set(
- xfs_vnode_t *vp, char *name, void *data, size_t size, int xflags)
-{
- return xfs_acl_vset(vp, data, size, _ACL_TYPE_ACCESS);
-}
-
-STATIC int
-posix_acl_access_remove(
- struct xfs_vnode *vp, char *name, int xflags)
-{
- return xfs_acl_vremove(vp, _ACL_TYPE_ACCESS);
-}
-
-STATIC int
-posix_acl_access_get(
- xfs_vnode_t *vp, char *name, void *data, size_t size, int xflags)
-{
- return xfs_acl_vget(vp, data, size, _ACL_TYPE_ACCESS);
-}
-
-STATIC int
-posix_acl_access_exists(
- xfs_vnode_t *vp)
-{
- return xfs_acl_vhasacl_access(vp);
-}
-
-STATIC int
-posix_acl_default_set(
- xfs_vnode_t *vp, char *name, void *data, size_t size, int xflags)
-{
- return xfs_acl_vset(vp, data, size, _ACL_TYPE_DEFAULT);
-}
-
-STATIC int
-posix_acl_default_get(
- xfs_vnode_t *vp, char *name, void *data, size_t size, int xflags)
-{
- return xfs_acl_vget(vp, data, size, _ACL_TYPE_DEFAULT);
-}
-
-STATIC int
-posix_acl_default_remove(
- struct xfs_vnode *vp, char *name, int xflags)
-{
- return xfs_acl_vremove(vp, _ACL_TYPE_DEFAULT);
-}
-
-STATIC int
-posix_acl_default_exists(
- xfs_vnode_t *vp)
-{
- return xfs_acl_vhasacl_default(vp);
-}
-
-STATIC struct attrnames posix_acl_access = {
- .attr_name = "posix_acl_access",
- .attr_namelen = sizeof("posix_acl_access") - 1,
- .attr_get = posix_acl_access_get,
- .attr_set = posix_acl_access_set,
- .attr_remove = posix_acl_access_remove,
- .attr_exists = posix_acl_access_exists,
-};
-
-STATIC struct attrnames posix_acl_default = {
- .attr_name = "posix_acl_default",
- .attr_namelen = sizeof("posix_acl_default") - 1,
- .attr_get = posix_acl_default_get,
- .attr_set = posix_acl_default_set,
- .attr_remove = posix_acl_default_remove,
- .attr_exists = posix_acl_default_exists,
-};
-
-STATIC struct attrnames *attr_system_names[] =
- { &posix_acl_access, &posix_acl_default };
-
-
-/*========================================================================
- * Namespace-prefix-style attribute name interface routines.
- *========================================================================*/
-
-STATIC int
-attr_generic_set(
- struct xfs_vnode *vp, char *name, void *data, size_t size, int xflags)
-{
- int error;
-
- XVOP_ATTR_SET(vp, name, data, size, xflags, NULL, error);
- return -error;
-}
-
-STATIC int
-attr_generic_get(
- struct xfs_vnode *vp, char *name, void *data, size_t size, int xflags)
-{
- int error, asize = size;
-
- XVOP_ATTR_GET(vp, name, data, &asize, xflags, NULL, error);
- if (!error)
- return asize;
- return -error;
-}
-
-STATIC int
-attr_generic_remove(
- struct xfs_vnode *vp, char *name, int xflags)
-{
- int error;
-
- XVOP_ATTR_REMOVE(vp, name, xflags, NULL, error);
- return -error;
-}
-
-STATIC int
-attr_generic_listadd(
- attrnames_t *prefix,
- attrnames_t *namesp,
- void *data,
- size_t size,
- ssize_t *result)
-{
- char *p = (char *)data + *result;
-
- *result += prefix->attr_namelen;
- *result += namesp->attr_namelen + 1;
- if (!size)
- return 0;
- if (*result > size)
- return -ERANGE;
- strcpy(p, prefix->attr_name);
- p += prefix->attr_namelen;
- strcpy(p, namesp->attr_name);
- p += namesp->attr_namelen + 1;
- return 0;
-}
-
-STATIC int
-attr_system_list(
- struct xfs_vnode *vp,
- void *data,
- size_t size,
- ssize_t *result)
-{
- attrnames_t *namesp;
- int i, error = 0;
-
- for (i = 0; i < ATTR_SYSCOUNT; i++) {
- namesp = attr_system_names[i];
- if (!namesp->attr_exists || !namesp->attr_exists(vp))
- continue;
- error = attr_generic_listadd(&attr_system, namesp,
- data, size, result);
- if (error)
- break;
- }
- return error;
-}
-
-int
-attr_generic_list(
- struct xfs_vnode *vp, void *data, size_t size, int xflags, ssize_t *result)
-{
- attrlist_cursor_kern_t cursor = { 0 };
- int error;
-
- XVOP_ATTR_LIST(vp, data, size, xflags, &cursor, NULL, error);
- if (error > 0)
- return -error;
- *result = -error;
- return attr_system_list(vp, data, size, result);
-}
-
-attrnames_t *
-attr_lookup_namespace(
- char *name,
- struct attrnames **names,
- int nnames)
-{
- int i;
-
- for (i = 0; i < nnames; i++)
- if (!strncmp(name, names[i]->attr_name, names[i]->attr_namelen))
- return names[i];
- return NULL;
-}
-
-/*
- * Some checks to prevent people abusing EAs to get over quota:
- * - Don't allow modifying user EAs on devices/symlinks;
- * - Don't allow modifying user EAs if sticky bit set;
- */
-STATIC int
-attr_user_capable(
- struct xfs_vnode *vp,
- cred_t *cred)
-{
-#ifdef XXXKAN
- struct inode *inode = vn_to_inode(vp);
-
- if (IS_IMMUTABLE(inode) || IS_APPEND(inode))
- return -EPERM;
- if (!S_ISREG(inode->i_mode) && !S_ISDIR(inode->i_mode) &&
- !capable(CAP_SYS_ADMIN))
- return -EPERM;
- if (S_ISDIR(inode->i_mode) && (inode->i_mode & S_ISVTX) &&
- (current_fsuid(cred) != inode->i_uid) && !capable(CAP_FOWNER))
- return -EPERM;
-#endif
- return 0;
-}
-
-STATIC int
-attr_trusted_capable(
- struct xfs_vnode *vp,
- cred_t *cred)
-{
-#ifdef XXXKAN
- struct inode *inode = vn_to_inode(vp);
-
- if (IS_IMMUTABLE(inode) || IS_APPEND(inode))
- return -EPERM;
- if (!capable(CAP_SYS_ADMIN))
- return -EPERM;
-#endif
- return 0;
-}
-
-STATIC int
-attr_secure_capable(
- struct xfs_vnode *vp,
- cred_t *cred)
-{
- return -ENOSECURITY;
-}
-
-STATIC int
-attr_system_set(
- struct xfs_vnode *vp, char *name, void *data, size_t size, int xflags)
-{
- attrnames_t *namesp;
- int error;
-
- if (xflags & ATTR_CREATE)
- return -EINVAL;
-
- namesp = attr_lookup_namespace(name, attr_system_names, ATTR_SYSCOUNT);
- if (!namesp)
- return -EOPNOTSUPP;
- error = namesp->attr_set(vp, name, data, size, xflags);
-#ifdef XXXKAN
- if (!error)
- error = vn_revalidate(vp);
-#endif
- return error;
-}
-
-STATIC int
-attr_system_get(
- struct xfs_vnode *vp, char *name, void *data, size_t size, int xflags)
-{
- attrnames_t *namesp;
-
- namesp = attr_lookup_namespace(name, attr_system_names, ATTR_SYSCOUNT);
- if (!namesp)
- return -EOPNOTSUPP;
- return namesp->attr_get(vp, name, data, size, xflags);
-}
-
-STATIC int
-attr_system_remove(
- struct xfs_vnode *vp, char *name, int xflags)
-{
- attrnames_t *namesp;
-
- namesp = attr_lookup_namespace(name, attr_system_names, ATTR_SYSCOUNT);
- if (!namesp)
- return -EOPNOTSUPP;
- return namesp->attr_remove(vp, name, xflags);
-}
-
-struct attrnames attr_system = {
- .attr_name = "system.",
- .attr_namelen = sizeof("system.") - 1,
- .attr_flag = ATTR_SYSTEM,
- .attr_get = attr_system_get,
- .attr_set = attr_system_set,
- .attr_remove = attr_system_remove,
- .attr_capable = (attrcapable_t)fs_noerr,
-};
-
-struct attrnames attr_trusted = {
- .attr_name = "trusted.",
- .attr_namelen = sizeof("trusted.") - 1,
- .attr_flag = ATTR_ROOT,
- .attr_get = attr_generic_get,
- .attr_set = attr_generic_set,
- .attr_remove = attr_generic_remove,
- .attr_capable = attr_trusted_capable,
-};
-
-struct attrnames attr_secure = {
- .attr_name = "security.",
- .attr_namelen = sizeof("security.") - 1,
- .attr_flag = ATTR_SECURE,
- .attr_get = attr_generic_get,
- .attr_set = attr_generic_set,
- .attr_remove = attr_generic_remove,
- .attr_capable = attr_secure_capable,
-};
-
-struct attrnames attr_user = {
- .attr_name = "user.",
- .attr_namelen = sizeof("user.") - 1,
- .attr_get = attr_generic_get,
- .attr_set = attr_generic_set,
- .attr_remove = attr_generic_remove,
- .attr_capable = attr_user_capable,
-};
-
-struct attrnames *attr_namespaces[] =
- { &attr_system, &attr_trusted, &attr_secure, &attr_user };
diff --git a/sys/gnu/fs/xfs/xfs_attr.h b/sys/gnu/fs/xfs/xfs_attr.h
deleted file mode 100644
index 6135b1b..0000000
--- a/sys/gnu/fs/xfs/xfs_attr.h
+++ /dev/null
@@ -1,172 +0,0 @@
-/*
- * Copyright (c) 2000,2002-2003,2005 Silicon Graphics, Inc.
- * All Rights Reserved.
- *
- * 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.
- *
- * This program is distributed in the hope that it would 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 the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- */
-#ifndef __XFS_ATTR_H__
-#define __XFS_ATTR_H__
-
-/*
- * xfs_attr.h
- *
- * Large attribute lists are structured around Btrees where all the data
- * elements are in the leaf nodes. Attribute names are hashed into an int,
- * then that int is used as the index into the Btree. Since the hashval
- * of an attribute name may not be unique, we may have duplicate keys.
- * The internal links in the Btree are logical block offsets into the file.
- *
- * Small attribute lists use a different format and are packed as tightly
- * as possible so as to fit into the literal area of the inode.
- */
-
-/*========================================================================
- * External interfaces
- *========================================================================*/
-
-struct cred;
-struct xfs_vnode;
-
-typedef int (*attrset_t)(struct xfs_vnode *, char *, void *, size_t, int);
-typedef int (*attrget_t)(struct xfs_vnode *, char *, void *, size_t, int);
-typedef int (*attrremove_t)(struct xfs_vnode *, char *, int);
-typedef int (*attrexists_t)(struct xfs_vnode *);
-typedef int (*attrcapable_t)(struct xfs_vnode *, struct cred *);
-
-typedef struct attrnames {
- char * attr_name;
- unsigned int attr_namelen;
- unsigned int attr_flag;
- attrget_t attr_get;
- attrset_t attr_set;
- attrremove_t attr_remove;
- attrexists_t attr_exists;
- attrcapable_t attr_capable;
-} attrnames_t;
-
-#define ATTR_NAMECOUNT 4
-extern struct attrnames attr_user;
-extern struct attrnames attr_secure;
-extern struct attrnames attr_system;
-extern struct attrnames attr_trusted;
-extern struct attrnames *attr_namespaces[ATTR_NAMECOUNT];
-
-extern attrnames_t *attr_lookup_namespace(char *, attrnames_t **, int);
-extern int attr_generic_list(struct xfs_vnode *, void *, size_t, int, ssize_t *);
-
-#define ATTR_DONTFOLLOW 0x0001 /* -- unused, from IRIX -- */
-#define ATTR_ROOT 0x0002 /* use attrs in root (trusted) namespace */
-#define ATTR_TRUST 0x0004 /* -- unused, from IRIX -- */
-#define ATTR_SECURE 0x0008 /* use attrs in security namespace */
-#define ATTR_CREATE 0x0010 /* pure create: fail if attr already exists */
-#define ATTR_REPLACE 0x0020 /* pure set: fail if attr does not exist */
-#define ATTR_SYSTEM 0x0100 /* use attrs in system (pseudo) namespace */
-
-#define ATTR_KERNACCESS 0x0400 /* [kernel] iaccess, inode held io-locked */
-#define ATTR_KERNOTIME 0x1000 /* [kernel] don't update inode timestamps */
-#define ATTR_KERNOVAL 0x2000 /* [kernel] get attr size only, not value */
-#define ATTR_KERNAMELS 0x4000 /* [kernel] list attr names (simple list) */
-
-#define ATTR_KERNORMALS 0x0800 /* [kernel] normal attr list: user+secure */
-#define ATTR_KERNROOTLS 0x8000 /* [kernel] include root in the attr list */
-#define ATTR_KERNFULLS (ATTR_KERNORMALS|ATTR_KERNROOTLS)
-
-/*
- * The maximum size (into the kernel or returned from the kernel) of an
- * attribute value or the buffer used for an attr_list() call. Larger
- * sizes will result in an ERANGE return code.
- */
-#define ATTR_MAX_VALUELEN (64*1024) /* max length of a value */
-
-/*
- * Define how lists of attribute names are returned to the user from
- * the attr_list() call. A large, 32bit aligned, buffer is passed in
- * along with its size. We put an array of offsets at the top that each
- * reference an attrlist_ent_t and pack the attrlist_ent_t's at the bottom.
- */
-typedef struct attrlist {
- __s32 al_count; /* number of entries in attrlist */
- __s32 al_more; /* T/F: more attrs (do call again) */
- __s32 al_offset[1]; /* byte offsets of attrs [var-sized] */
-} attrlist_t;
-
-/*
- * Show the interesting info about one attribute. This is what the
- * al_offset[i] entry points to.
- */
-typedef struct attrlist_ent { /* data from attr_list() */
- __u32 a_valuelen; /* number bytes in value of attr */
- char a_name[1]; /* attr name (NULL terminated) */
-} attrlist_ent_t;
-
-/*
- * Given a pointer to the (char*) buffer containing the attr_list() result,
- * and an index, return a pointer to the indicated attribute in the buffer.
- */
-#define ATTR_ENTRY(buffer, index) \
- ((attrlist_ent_t *) \
- &((char *)buffer)[ ((attrlist_t *)(buffer))->al_offset[index] ])
-
-/*
- * Multi-attribute operation vector.
- */
-typedef struct attr_multiop {
- int am_opcode; /* operation to perform (ATTR_OP_GET, etc.) */
- int am_error; /* [out arg] result of this sub-op (an errno) */
- char *am_attrname; /* attribute name to work with */
- char *am_attrvalue; /* [in/out arg] attribute value (raw bytes) */
- int am_length; /* [in/out arg] length of value */
- int am_flags; /* bitwise OR of attr API flags defined above */
-} attr_multiop_t;
-
-#define ATTR_OP_GET 1 /* return the indicated attr's value */
-#define ATTR_OP_SET 2 /* set/create the indicated attr/value pair */
-#define ATTR_OP_REMOVE 3 /* remove the indicated attr */
-
-/*
- * Kernel-internal version of the attrlist cursor.
- */
-typedef struct attrlist_cursor_kern {
- __u32 hashval; /* hash value of next entry to add */
- __u32 blkno; /* block containing entry (suggestion) */
- __u32 offset; /* offset in list of equal-hashvals */
- __u16 pad1; /* padding to match user-level */
- __u8 pad2; /* padding to match user-level */
- __u8 initted; /* T/F: cursor has been initialized */
-} attrlist_cursor_kern_t;
-
-
-/*========================================================================
- * Function prototypes for the kernel.
- *========================================================================*/
-
-struct xfs_inode;
-struct attrlist_cursor_kern;
-struct xfs_da_args;
-
-/*
- * Overall external interface routines.
- */
-int xfs_attr_get(bhv_desc_t *, const char *, char *, int *, int, struct cred *);
-int xfs_attr_set(bhv_desc_t *, const char *, char *, int, int, struct cred *);
-int xfs_attr_remove(bhv_desc_t *, const char *, int, struct cred *);
-int xfs_attr_list(bhv_desc_t *, char *, int, int,
- struct attrlist_cursor_kern *, struct cred *);
-int xfs_attr_inactive(struct xfs_inode *dp);
-
-int xfs_attr_shortform_getvalue(struct xfs_da_args *);
-int xfs_attr_fetch(struct xfs_inode *, const char *, int,
- char *, int *, int, struct cred *);
-
-#endif /* __XFS_ATTR_H__ */
diff --git a/sys/gnu/fs/xfs/xfs_attr_leaf.c b/sys/gnu/fs/xfs/xfs_attr_leaf.c
deleted file mode 100644
index 3a48b41..0000000
--- a/sys/gnu/fs/xfs/xfs_attr_leaf.c
+++ /dev/null
@@ -1,3083 +0,0 @@
-/*
- * Copyright (c) 2000-2005 Silicon Graphics, Inc.
- * All Rights Reserved.
- *
- * 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.
- *
- * This program is distributed in the hope that it would 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 the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- */
-#include "xfs.h"
-#include "xfs_fs.h"
-#include "xfs_types.h"
-#include "xfs_bit.h"
-#include "xfs_log.h"
-#include "xfs_inum.h"
-#include "xfs_trans.h"
-#include "xfs_sb.h"
-#include "xfs_ag.h"
-#include "xfs_dir.h"
-#include "xfs_dir2.h"
-#include "xfs_dmapi.h"
-#include "xfs_mount.h"
-#include "xfs_da_btree.h"
-#include "xfs_bmap_btree.h"
-#include "xfs_alloc_btree.h"
-#include "xfs_ialloc_btree.h"
-#include "xfs_alloc.h"
-#include "xfs_btree.h"
-#include "xfs_dir_sf.h"
-#include "xfs_dir2_sf.h"
-#include "xfs_attr_sf.h"
-#include "xfs_dinode.h"
-#include "xfs_inode.h"
-#include "xfs_inode_item.h"
-#include "xfs_bmap.h"
-#include "xfs_attr.h"
-#include "xfs_attr_leaf.h"
-#include "xfs_error.h"
-
-/*
- * xfs_attr_leaf.c
- *
- * Routines to implement leaf blocks of attributes as Btrees of hashed names.
- */
-
-/*========================================================================
- * Function prototypes for the kernel.
- *========================================================================*/
-
-/*
- * Routines used for growing the Btree.
- */
-STATIC int xfs_attr_leaf_create(xfs_da_args_t *args, xfs_dablk_t which_block,
- xfs_dabuf_t **bpp);
-STATIC int xfs_attr_leaf_add_work(xfs_dabuf_t *leaf_buffer, xfs_da_args_t *args,
- int freemap_index);
-STATIC void xfs_attr_leaf_compact(xfs_trans_t *trans, xfs_dabuf_t *leaf_buffer);
-STATIC void xfs_attr_leaf_rebalance(xfs_da_state_t *state,
- xfs_da_state_blk_t *blk1,
- xfs_da_state_blk_t *blk2);
-STATIC int xfs_attr_leaf_figure_balance(xfs_da_state_t *state,
- xfs_da_state_blk_t *leaf_blk_1,
- xfs_da_state_blk_t *leaf_blk_2,
- int *number_entries_in_blk1,
- int *number_usedbytes_in_blk1);
-
-/*
- * Routines used for shrinking the Btree.
- */
-STATIC int xfs_attr_node_inactive(xfs_trans_t **trans, xfs_inode_t *dp,
- xfs_dabuf_t *bp, int level);
-STATIC int xfs_attr_leaf_inactive(xfs_trans_t **trans, xfs_inode_t *dp,
- xfs_dabuf_t *bp);
-STATIC int xfs_attr_leaf_freextent(xfs_trans_t **trans, xfs_inode_t *dp,
- xfs_dablk_t blkno, int blkcnt);
-
-/*
- * Utility routines.
- */
-STATIC void xfs_attr_leaf_moveents(xfs_attr_leafblock_t *src_leaf,
- int src_start,
- xfs_attr_leafblock_t *dst_leaf,
- int dst_start, int move_count,
- xfs_mount_t *mp);
-STATIC int xfs_attr_leaf_entsize(xfs_attr_leafblock_t *leaf, int index);
-STATIC int xfs_attr_put_listent(xfs_attr_list_context_t *context,
- attrnames_t *, char *name, int namelen,
- int valuelen);
-
-
-/*========================================================================
- * External routines when attribute fork size < XFS_LITINO(mp).
- *========================================================================*/
-
-/*
- * Query whether the requested number of additional bytes of extended
- * attribute space will be able to fit inline.
- * Returns zero if not, else the di_forkoff fork offset to be used in the
- * literal area for attribute data once the new bytes have been added.
- *
- * di_forkoff must be 8 byte aligned, hence is stored as a >>3 value;
- * special case for dev/uuid inodes, they have fixed size data forks.
- */
-int
-xfs_attr_shortform_bytesfit(xfs_inode_t *dp, int bytes)
-{
- int offset;
- int minforkoff; /* lower limit on valid forkoff locations */
- int maxforkoff; /* upper limit on valid forkoff locations */
- xfs_mount_t *mp = dp->i_mount;
-
- offset = (XFS_LITINO(mp) - bytes) >> 3; /* rounded down */
-
- switch (dp->i_d.di_format) {
- case XFS_DINODE_FMT_DEV:
- minforkoff = roundup(sizeof(xfs_dev_t), 8) >> 3;
- return (offset >= minforkoff) ? minforkoff : 0;
- case XFS_DINODE_FMT_UUID:
- minforkoff = roundup(sizeof(uuid_t), 8) >> 3;
- return (offset >= minforkoff) ? minforkoff : 0;
- }
-
- if (!(mp->m_flags & XFS_MOUNT_ATTR2)) {
- if (bytes <= XFS_IFORK_ASIZE(dp))
- return mp->m_attroffset >> 3;
- return 0;
- }
-
- /* data fork btree root can have at least this many key/ptr pairs */
- minforkoff = MAX(dp->i_df.if_bytes, XFS_BMDR_SPACE_CALC(MINDBTPTRS));
- minforkoff = roundup(minforkoff, 8) >> 3;
-
- /* attr fork btree root can have at least this many key/ptr pairs */
- maxforkoff = XFS_LITINO(mp) - XFS_BMDR_SPACE_CALC(MINABTPTRS);
- maxforkoff = maxforkoff >> 3; /* rounded down */
-
- if (offset >= minforkoff && offset < maxforkoff)
- return offset;
- if (offset >= maxforkoff)
- return maxforkoff;
- return 0;
-}
-
-/*
- * Switch on the ATTR2 superblock bit (implies also FEATURES2)
- */
-STATIC void
-xfs_sbversion_add_attr2(xfs_mount_t *mp, xfs_trans_t *tp)
-{
- unsigned long s;
-
- if ((mp->m_flags & XFS_MOUNT_ATTR2) &&
- !(XFS_SB_VERSION_HASATTR2(&mp->m_sb))) {
- s = XFS_SB_LOCK(mp);
- if (!XFS_SB_VERSION_HASATTR2(&mp->m_sb)) {
- XFS_SB_VERSION_ADDATTR2(&mp->m_sb);
- XFS_SB_UNLOCK(mp, s);
- xfs_mod_sb(tp, XFS_SB_VERSIONNUM | XFS_SB_FEATURES2);
- } else
- XFS_SB_UNLOCK(mp, s);
- }
-}
-
-/*
- * Create the initial contents of a shortform attribute list.
- */
-void
-xfs_attr_shortform_create(xfs_da_args_t *args)
-{
- xfs_attr_sf_hdr_t *hdr;
- xfs_inode_t *dp;
- xfs_ifork_t *ifp;
-
- dp = args->dp;
- ASSERT(dp != NULL);
- ifp = dp->i_afp;
- ASSERT(ifp != NULL);
- ASSERT(ifp->if_bytes == 0);
- if (dp->i_d.di_aformat == XFS_DINODE_FMT_EXTENTS) {
- ifp->if_flags &= ~XFS_IFEXTENTS; /* just in case */
- dp->i_d.di_aformat = XFS_DINODE_FMT_LOCAL;
- ifp->if_flags |= XFS_IFINLINE;
- } else {
- ASSERT(ifp->if_flags & XFS_IFINLINE);
- }
- xfs_idata_realloc(dp, sizeof(*hdr), XFS_ATTR_FORK);
- hdr = (xfs_attr_sf_hdr_t *)ifp->if_u1.if_data;
- hdr->count = 0;
- hdr->totsize = cpu_to_be16(sizeof(*hdr));
- xfs_trans_log_inode(args->trans, dp, XFS_ILOG_CORE | XFS_ILOG_ADATA);
-}
-
-/*
- * Add a name/value pair to the shortform attribute list.
- * Overflow from the inode has already been checked for.
- */
-void
-xfs_attr_shortform_add(xfs_da_args_t *args, int forkoff)
-{
- xfs_attr_shortform_t *sf;
- xfs_attr_sf_entry_t *sfe;
- int i, offset, size;
- xfs_mount_t *mp;
- xfs_inode_t *dp;
- xfs_ifork_t *ifp;
-
- dp = args->dp;
- mp = dp->i_mount;
- dp->i_d.di_forkoff = forkoff;
- dp->i_df.if_ext_max =
- XFS_IFORK_DSIZE(dp) / (uint)sizeof(xfs_bmbt_rec_t);
- dp->i_afp->if_ext_max =
- XFS_IFORK_ASIZE(dp) / (uint)sizeof(xfs_bmbt_rec_t);
-
- ifp = dp->i_afp;
- ASSERT(ifp->if_flags & XFS_IFINLINE);
- sf = (xfs_attr_shortform_t *)ifp->if_u1.if_data;
- sfe = &sf->list[0];
- for (i = 0; i < sf->hdr.count; sfe = XFS_ATTR_SF_NEXTENTRY(sfe), i++) {
-#ifdef DEBUG
- if (sfe->namelen != args->namelen)
- continue;
- if (memcmp(args->name, sfe->nameval, args->namelen) != 0)
- continue;
- if (((args->flags & ATTR_SECURE) != 0) !=
- ((sfe->flags & XFS_ATTR_SECURE) != 0))
- continue;
- if (((args->flags & ATTR_ROOT) != 0) !=
- ((sfe->flags & XFS_ATTR_ROOT) != 0))
- continue;
- ASSERT(0);
-#endif
- }
-
- offset = (char *)sfe - (char *)sf;
- size = XFS_ATTR_SF_ENTSIZE_BYNAME(args->namelen, args->valuelen);
- xfs_idata_realloc(dp, size, XFS_ATTR_FORK);
- sf = (xfs_attr_shortform_t *)ifp->if_u1.if_data;
- sfe = (xfs_attr_sf_entry_t *)((char *)sf + offset);
-
- sfe->namelen = args->namelen;
- sfe->valuelen = args->valuelen;
- sfe->flags = (args->flags & ATTR_SECURE) ? XFS_ATTR_SECURE :
- ((args->flags & ATTR_ROOT) ? XFS_ATTR_ROOT : 0);
- memcpy(sfe->nameval, args->name, args->namelen);
- memcpy(&sfe->nameval[args->namelen], args->value, args->valuelen);
- sf->hdr.count++;
- be16_add(&sf->hdr.totsize, size);
- xfs_trans_log_inode(args->trans, dp, XFS_ILOG_CORE | XFS_ILOG_ADATA);
-
- xfs_sbversion_add_attr2(mp, args->trans);
-}
-
-/*
- * Remove an attribute from the shortform attribute list structure.
- */
-int
-xfs_attr_shortform_remove(xfs_da_args_t *args)
-{
- xfs_attr_shortform_t *sf;
- xfs_attr_sf_entry_t *sfe;
- int base, size=0, end, totsize, i;
- xfs_mount_t *mp;
- xfs_inode_t *dp;
-
- dp = args->dp;
- mp = dp->i_mount;
- base = sizeof(xfs_attr_sf_hdr_t);
- sf = (xfs_attr_shortform_t *)dp->i_afp->if_u1.if_data;
- sfe = &sf->list[0];
- end = sf->hdr.count;
- for (i = 0; i < end; sfe = XFS_ATTR_SF_NEXTENTRY(sfe),
- base += size, i++) {
- size = XFS_ATTR_SF_ENTSIZE(sfe);
- if (sfe->namelen != args->namelen)
- continue;
- if (memcmp(sfe->nameval, args->name, args->namelen) != 0)
- continue;
- if (((args->flags & ATTR_SECURE) != 0) !=
- ((sfe->flags & XFS_ATTR_SECURE) != 0))
- continue;
- if (((args->flags & ATTR_ROOT) != 0) !=
- ((sfe->flags & XFS_ATTR_ROOT) != 0))
- continue;
- break;
- }
- if (i == end)
- return(XFS_ERROR(ENOATTR));
-
- /*
- * Fix up the attribute fork data, covering the hole
- */
- end = base + size;
- totsize = be16_to_cpu(sf->hdr.totsize);
- if (end != totsize)
- memmove(&((char *)sf)[base], &((char *)sf)[end], totsize - end);
- sf->hdr.count--;
- be16_add(&sf->hdr.totsize, -size);
-
- /*
- * Fix up the start offset of the attribute fork
- */
- totsize -= size;
- if (totsize == sizeof(xfs_attr_sf_hdr_t) && !args->addname &&
- (mp->m_flags & XFS_MOUNT_ATTR2)) {
- /*
- * Last attribute now removed, revert to original
- * inode format making all literal area available
- * to the data fork once more.
- */
- xfs_idestroy_fork(dp, XFS_ATTR_FORK);
- dp->i_d.di_forkoff = 0;
- dp->i_d.di_aformat = XFS_DINODE_FMT_EXTENTS;
- ASSERT(dp->i_d.di_anextents == 0);
- ASSERT(dp->i_afp == NULL);
- dp->i_df.if_ext_max =
- XFS_IFORK_DSIZE(dp) / (uint)sizeof(xfs_bmbt_rec_t);
- xfs_trans_log_inode(args->trans, dp, XFS_ILOG_CORE);
- } else {
- xfs_idata_realloc(dp, -size, XFS_ATTR_FORK);
- dp->i_d.di_forkoff = xfs_attr_shortform_bytesfit(dp, totsize);
- ASSERT(dp->i_d.di_forkoff);
- ASSERT(totsize > sizeof(xfs_attr_sf_hdr_t) || args->addname ||
- !(mp->m_flags & XFS_MOUNT_ATTR2));
- dp->i_afp->if_ext_max =
- XFS_IFORK_ASIZE(dp) / (uint)sizeof(xfs_bmbt_rec_t);
- dp->i_df.if_ext_max =
- XFS_IFORK_DSIZE(dp) / (uint)sizeof(xfs_bmbt_rec_t);
- xfs_trans_log_inode(args->trans, dp,
- XFS_ILOG_CORE | XFS_ILOG_ADATA);
- }
-
- xfs_sbversion_add_attr2(mp, args->trans);
-
- return(0);
-}
-
-/*
- * Look up a name in a shortform attribute list structure.
- */
-/*ARGSUSED*/
-int
-xfs_attr_shortform_lookup(xfs_da_args_t *args)
-{
- xfs_attr_shortform_t *sf;
- xfs_attr_sf_entry_t *sfe;
- int i;
- xfs_ifork_t *ifp;
-
- ifp = args->dp->i_afp;
- ASSERT(ifp->if_flags & XFS_IFINLINE);
- sf = (xfs_attr_shortform_t *)ifp->if_u1.if_data;
- sfe = &sf->list[0];
- for (i = 0; i < sf->hdr.count;
- sfe = XFS_ATTR_SF_NEXTENTRY(sfe), i++) {
- if (sfe->namelen != args->namelen)
- continue;
- if (memcmp(args->name, sfe->nameval, args->namelen) != 0)
- continue;
- if (((args->flags & ATTR_SECURE) != 0) !=
- ((sfe->flags & XFS_ATTR_SECURE) != 0))
- continue;
- if (((args->flags & ATTR_ROOT) != 0) !=
- ((sfe->flags & XFS_ATTR_ROOT) != 0))
- continue;
- return(XFS_ERROR(EEXIST));
- }
- return(XFS_ERROR(ENOATTR));
-}
-
-/*
- * Look up a name in a shortform attribute list structure.
- */
-/*ARGSUSED*/
-int
-xfs_attr_shortform_getvalue(xfs_da_args_t *args)
-{
- xfs_attr_shortform_t *sf;
- xfs_attr_sf_entry_t *sfe;
- int i;
-
- ASSERT(args->dp->i_d.di_aformat == XFS_IFINLINE);
- sf = (xfs_attr_shortform_t *)args->dp->i_afp->if_u1.if_data;
- sfe = &sf->list[0];
- for (i = 0; i < sf->hdr.count;
- sfe = XFS_ATTR_SF_NEXTENTRY(sfe), i++) {
- if (sfe->namelen != args->namelen)
- continue;
- if (memcmp(args->name, sfe->nameval, args->namelen) != 0)
- continue;
- if (((args->flags & ATTR_SECURE) != 0) !=
- ((sfe->flags & XFS_ATTR_SECURE) != 0))
- continue;
- if (((args->flags & ATTR_ROOT) != 0) !=
- ((sfe->flags & XFS_ATTR_ROOT) != 0))
- continue;
- if (args->flags & ATTR_KERNOVAL) {
- args->valuelen = sfe->valuelen;
- return(XFS_ERROR(EEXIST));
- }
- if (args->valuelen < sfe->valuelen) {
- args->valuelen = sfe->valuelen;
- return(XFS_ERROR(ERANGE));
- }
- args->valuelen = sfe->valuelen;
- memcpy(args->value, &sfe->nameval[args->namelen],
- args->valuelen);
- return(XFS_ERROR(EEXIST));
- }
- return(XFS_ERROR(ENOATTR));
-}
-
-/*
- * Convert from using the shortform to the leaf.
- */
-int
-xfs_attr_shortform_to_leaf(xfs_da_args_t *args)
-{
- xfs_inode_t *dp;
- xfs_attr_shortform_t *sf;
- xfs_attr_sf_entry_t *sfe;
- xfs_da_args_t nargs;
- char *tmpbuffer;
- int error, i, size;
- xfs_dablk_t blkno;
- xfs_dabuf_t *bp;
- xfs_ifork_t *ifp;
-
- dp = args->dp;
- ifp = dp->i_afp;
- sf = (xfs_attr_shortform_t *)ifp->if_u1.if_data;
- size = be16_to_cpu(sf->hdr.totsize);
- tmpbuffer = kmem_alloc(size, KM_SLEEP);
- ASSERT(tmpbuffer != NULL);
- memcpy(tmpbuffer, ifp->if_u1.if_data, size);
- sf = (xfs_attr_shortform_t *)tmpbuffer;
-
- xfs_idata_realloc(dp, -size, XFS_ATTR_FORK);
- bp = NULL;
- error = xfs_da_grow_inode(args, &blkno);
- if (error) {
- /*
- * If we hit an IO error middle of the transaction inside
- * grow_inode(), we may have inconsistent data. Bail out.
- */
- if (error == EIO)
- goto out;
- xfs_idata_realloc(dp, size, XFS_ATTR_FORK); /* try to put */
- memcpy(ifp->if_u1.if_data, tmpbuffer, size); /* it back */
- goto out;
- }
-
- ASSERT(blkno == 0);
- error = xfs_attr_leaf_create(args, blkno, &bp);
- if (error) {
- error = xfs_da_shrink_inode(args, 0, bp);
- bp = NULL;
- if (error)
- goto out;
- xfs_idata_realloc(dp, size, XFS_ATTR_FORK); /* try to put */
- memcpy(ifp->if_u1.if_data, tmpbuffer, size); /* it back */
- goto out;
- }
-
- memset((char *)&nargs, 0, sizeof(nargs));
- nargs.dp = dp;
- nargs.firstblock = args->firstblock;
- nargs.flist = args->flist;
- nargs.total = args->total;
- nargs.whichfork = XFS_ATTR_FORK;
- nargs.trans = args->trans;
- nargs.oknoent = 1;
-
- sfe = &sf->list[0];
- for (i = 0; i < sf->hdr.count; i++) {
- nargs.name = (char *)sfe->nameval;
- nargs.namelen = sfe->namelen;
- nargs.value = (char *)&sfe->nameval[nargs.namelen];
- nargs.valuelen = sfe->valuelen;
- nargs.hashval = xfs_da_hashname((char *)sfe->nameval,
- sfe->namelen);
- nargs.flags = (sfe->flags & XFS_ATTR_SECURE) ? ATTR_SECURE :
- ((sfe->flags & XFS_ATTR_ROOT) ? ATTR_ROOT : 0);
- error = xfs_attr_leaf_lookup_int(bp, &nargs); /* set a->index */
- ASSERT(error == ENOATTR);
- error = xfs_attr_leaf_add(bp, &nargs);
- ASSERT(error != ENOSPC);
- if (error)
- goto out;
- sfe = XFS_ATTR_SF_NEXTENTRY(sfe);
- }
- error = 0;
-
-out:
- if(bp)
- xfs_da_buf_done(bp);
- kmem_free(tmpbuffer, size);
- return(error);
-}
-
-STATIC int
-xfs_attr_shortform_compare(const void *a, const void *b)
-{
- const xfs_attr_sf_sort_t *sa, *sb;
-
- sa = (const xfs_attr_sf_sort_t *)a;
- sb = (const xfs_attr_sf_sort_t *)b;
- if (sa->hash < sb->hash) {
- return(-1);
- } else if (sa->hash > sb->hash) {
- return(1);
- } else {
- return(sa->entno - sb->entno);
- }
-}
-
-/*
- * Copy out entries of shortform attribute lists for attr_list().
- * Shortform attribute lists are not stored in hashval sorted order.
- * If the output buffer is not large enough to hold them all, then we
- * we have to calculate each entries' hashvalue and sort them before
- * we can begin returning them to the user.
- */
-/*ARGSUSED*/
-int
-xfs_attr_shortform_list(xfs_attr_list_context_t *context)
-{
- attrlist_cursor_kern_t *cursor;
- xfs_attr_sf_sort_t *sbuf, *sbp;
- xfs_attr_shortform_t *sf;
- xfs_attr_sf_entry_t *sfe;
- xfs_inode_t *dp;
- int sbsize, nsbuf, count, i;
-
- ASSERT(context != NULL);
- dp = context->dp;
- ASSERT(dp != NULL);
- ASSERT(dp->i_afp != NULL);
- sf = (xfs_attr_shortform_t *)dp->i_afp->if_u1.if_data;
- ASSERT(sf != NULL);
- if (!sf->hdr.count)
- return(0);
- cursor = context->cursor;
- ASSERT(cursor != NULL);
-
- xfs_attr_trace_l_c("sf start", context);
-
- /*
- * If the buffer is large enough, do not bother with sorting.
- * Note the generous fudge factor of 16 overhead bytes per entry.
- */
- if ((dp->i_afp->if_bytes + sf->hdr.count * 16) < context->bufsize) {
- for (i = 0, sfe = &sf->list[0]; i < sf->hdr.count; i++) {
- attrnames_t *namesp;
-
- if (((context->flags & ATTR_SECURE) != 0) !=
- ((sfe->flags & XFS_ATTR_SECURE) != 0) &&
- !(context->flags & ATTR_KERNORMALS)) {
- sfe = XFS_ATTR_SF_NEXTENTRY(sfe);
- continue;
- }
- if (((context->flags & ATTR_ROOT) != 0) !=
- ((sfe->flags & XFS_ATTR_ROOT) != 0) &&
- !(context->flags & ATTR_KERNROOTLS)) {
- sfe = XFS_ATTR_SF_NEXTENTRY(sfe);
- continue;
- }
- namesp = (sfe->flags & XFS_ATTR_SECURE) ? &attr_secure:
- ((sfe->flags & XFS_ATTR_ROOT) ? &attr_trusted :
- &attr_user);
- if (context->flags & ATTR_KERNOVAL) {
- ASSERT(context->flags & ATTR_KERNAMELS);
- context->count += namesp->attr_namelen +
- sfe->namelen + 1;
- }
- else {
- if (xfs_attr_put_listent(context, namesp,
- (char *)sfe->nameval,
- (int)sfe->namelen,
- (int)sfe->valuelen))
- break;
- }
- sfe = XFS_ATTR_SF_NEXTENTRY(sfe);
- }
- xfs_attr_trace_l_c("sf big-gulp", context);
- return(0);
- }
-
- /*
- * It didn't all fit, so we have to sort everything on hashval.
- */
- sbsize = sf->hdr.count * sizeof(*sbuf);
- sbp = sbuf = kmem_alloc(sbsize, KM_SLEEP);
-
- /*
- * Scan the attribute list for the rest of the entries, storing
- * the relevant info from only those that match into a buffer.
- */
- nsbuf = 0;
- for (i = 0, sfe = &sf->list[0]; i < sf->hdr.count; i++) {
- if (unlikely(
- ((char *)sfe < (char *)sf) ||
- ((char *)sfe >= ((char *)sf + dp->i_afp->if_bytes)))) {
- XFS_CORRUPTION_ERROR("xfs_attr_shortform_list",
- XFS_ERRLEVEL_LOW,
- context->dp->i_mount, sfe);
- xfs_attr_trace_l_c("sf corrupted", context);
- kmem_free(sbuf, sbsize);
- return XFS_ERROR(EFSCORRUPTED);
- }
- if (((context->flags & ATTR_SECURE) != 0) !=
- ((sfe->flags & XFS_ATTR_SECURE) != 0) &&
- !(context->flags & ATTR_KERNORMALS)) {
- sfe = XFS_ATTR_SF_NEXTENTRY(sfe);
- continue;
- }
- if (((context->flags & ATTR_ROOT) != 0) !=
- ((sfe->flags & XFS_ATTR_ROOT) != 0) &&
- !(context->flags & ATTR_KERNROOTLS)) {
- sfe = XFS_ATTR_SF_NEXTENTRY(sfe);
- continue;
- }
- sbp->entno = i;
- sbp->hash = xfs_da_hashname((char *)sfe->nameval, sfe->namelen);
- sbp->name = (char *)sfe->nameval;
- sbp->namelen = sfe->namelen;
- /* These are bytes, and both on-disk, don't endian-flip */
- sbp->valuelen = sfe->valuelen;
- sbp->flags = sfe->flags;
- sfe = XFS_ATTR_SF_NEXTENTRY(sfe);
- sbp++;
- nsbuf++;
- }
-
- /*
- * Sort the entries on hash then entno.
- */
- xfs_sort(sbuf, nsbuf, sizeof(*sbuf), xfs_attr_shortform_compare);
-
- /*
- * Re-find our place IN THE SORTED LIST.
- */
- count = 0;
- cursor->initted = 1;
- cursor->blkno = 0;
- for (sbp = sbuf, i = 0; i < nsbuf; i++, sbp++) {
- if (sbp->hash == cursor->hashval) {
- if (cursor->offset == count) {
- break;
- }
- count++;
- } else if (sbp->hash > cursor->hashval) {
- break;
- }
- }
- if (i == nsbuf) {
- kmem_free(sbuf, sbsize);
- xfs_attr_trace_l_c("blk end", context);
- return(0);
- }
-
- /*
- * Loop putting entries into the user buffer.
- */
- for ( ; i < nsbuf; i++, sbp++) {
- attrnames_t *namesp;
-
- namesp = (sbp->flags & XFS_ATTR_SECURE) ? &attr_secure :
- ((sbp->flags & XFS_ATTR_ROOT) ? &attr_trusted :
- &attr_user);
-
- if (cursor->hashval != sbp->hash) {
- cursor->hashval = sbp->hash;
- cursor->offset = 0;
- }
- if (context->flags & ATTR_KERNOVAL) {
- ASSERT(context->flags & ATTR_KERNAMELS);
- context->count += namesp->attr_namelen +
- sbp->namelen + 1;
- } else {
- if (xfs_attr_put_listent(context, namesp,
- sbp->name, sbp->namelen,
- sbp->valuelen))
- break;
- }
- cursor->offset++;
- }
-
- kmem_free(sbuf, sbsize);
- xfs_attr_trace_l_c("sf E-O-F", context);
- return(0);
-}
-
-/*
- * Check a leaf attribute block to see if all the entries would fit into
- * a shortform attribute list.
- */
-int
-xfs_attr_shortform_allfit(xfs_dabuf_t *bp, xfs_inode_t *dp)
-{
- xfs_attr_leafblock_t *leaf;
- xfs_attr_leaf_entry_t *entry;
- xfs_attr_leaf_name_local_t *name_loc;
- int bytes, i;
-
- leaf = bp->data;
- ASSERT(be16_to_cpu(leaf->hdr.info.magic) == XFS_ATTR_LEAF_MAGIC);
-
- entry = &leaf->entries[0];
- bytes = sizeof(struct xfs_attr_sf_hdr);
- for (i = 0; i < be16_to_cpu(leaf->hdr.count); entry++, i++) {
- if (entry->flags & XFS_ATTR_INCOMPLETE)
- continue; /* don't copy partial entries */
- if (!(entry->flags & XFS_ATTR_LOCAL))
- return(0);
- name_loc = XFS_ATTR_LEAF_NAME_LOCAL(leaf, i);
- if (name_loc->namelen >= XFS_ATTR_SF_ENTSIZE_MAX)
- return(0);
- if (be16_to_cpu(name_loc->valuelen) >= XFS_ATTR_SF_ENTSIZE_MAX)
- return(0);
- bytes += sizeof(struct xfs_attr_sf_entry)-1
- + name_loc->namelen
- + be16_to_cpu(name_loc->valuelen);
- }
- if ((dp->i_mount->m_flags & XFS_MOUNT_ATTR2) &&
- (bytes == sizeof(struct xfs_attr_sf_hdr)))
- return(-1);
- return(xfs_attr_shortform_bytesfit(dp, bytes));
-}
-
-/*
- * Convert a leaf attribute list to shortform attribute list
- */
-int
-xfs_attr_leaf_to_shortform(xfs_dabuf_t *bp, xfs_da_args_t *args, int forkoff)
-{
- xfs_attr_leafblock_t *leaf;
- xfs_attr_leaf_entry_t *entry;
- xfs_attr_leaf_name_local_t *name_loc;
- xfs_da_args_t nargs;
- xfs_inode_t *dp;
- char *tmpbuffer;
- int error, i;
-
- dp = args->dp;
- tmpbuffer = kmem_alloc(XFS_LBSIZE(dp->i_mount), KM_SLEEP);
- ASSERT(tmpbuffer != NULL);
-
- ASSERT(bp != NULL);
- memcpy(tmpbuffer, bp->data, XFS_LBSIZE(dp->i_mount));
- leaf = (xfs_attr_leafblock_t *)tmpbuffer;
- ASSERT(be16_to_cpu(leaf->hdr.info.magic) == XFS_ATTR_LEAF_MAGIC);
- memset(bp->data, 0, XFS_LBSIZE(dp->i_mount));
-
- /*
- * Clean out the prior contents of the attribute list.
- */
- error = xfs_da_shrink_inode(args, 0, bp);
- if (error)
- goto out;
-
- if (forkoff == -1) {
- ASSERT(dp->i_mount->m_flags & XFS_MOUNT_ATTR2);
-
- /*
- * Last attribute was removed, revert to original
- * inode format making all literal area available
- * to the data fork once more.
- */
- xfs_idestroy_fork(dp, XFS_ATTR_FORK);
- dp->i_d.di_forkoff = 0;
- dp->i_d.di_aformat = XFS_DINODE_FMT_EXTENTS;
- ASSERT(dp->i_d.di_anextents == 0);
- ASSERT(dp->i_afp == NULL);
- dp->i_df.if_ext_max =
- XFS_IFORK_DSIZE(dp) / (uint)sizeof(xfs_bmbt_rec_t);
- xfs_trans_log_inode(args->trans, dp, XFS_ILOG_CORE);
- goto out;
- }
-
- xfs_attr_shortform_create(args);
-
- /*
- * Copy the attributes
- */
- memset((char *)&nargs, 0, sizeof(nargs));
- nargs.dp = dp;
- nargs.firstblock = args->firstblock;
- nargs.flist = args->flist;
- nargs.total = args->total;
- nargs.whichfork = XFS_ATTR_FORK;
- nargs.trans = args->trans;
- nargs.oknoent = 1;
- entry = &leaf->entries[0];
- for (i = 0; i < be16_to_cpu(leaf->hdr.count); entry++, i++) {
- if (entry->flags & XFS_ATTR_INCOMPLETE)
- continue; /* don't copy partial entries */
- if (!entry->nameidx)
- continue;
- ASSERT(entry->flags & XFS_ATTR_LOCAL);
- name_loc = XFS_ATTR_LEAF_NAME_LOCAL(leaf, i);
- nargs.name = (char *)name_loc->nameval;
- nargs.namelen = name_loc->namelen;
- nargs.value = (char *)&name_loc->nameval[nargs.namelen];
- nargs.valuelen = be16_to_cpu(name_loc->valuelen);
- nargs.hashval = be32_to_cpu(entry->hashval);
- nargs.flags = (entry->flags & XFS_ATTR_SECURE) ? ATTR_SECURE :
- ((entry->flags & XFS_ATTR_ROOT) ? ATTR_ROOT : 0);
- xfs_attr_shortform_add(&nargs, forkoff);
- }
- error = 0;
-
-out:
- kmem_free(tmpbuffer, XFS_LBSIZE(dp->i_mount));
- return(error);
-}
-
-/*
- * Convert from using a single leaf to a root node and a leaf.
- */
-int
-xfs_attr_leaf_to_node(xfs_da_args_t *args)
-{
- xfs_attr_leafblock_t *leaf;
- xfs_da_intnode_t *node;
- xfs_inode_t *dp;
- xfs_dabuf_t *bp1, *bp2;
- xfs_dablk_t blkno;
- int error;
-
- dp = args->dp;
- bp1 = bp2 = NULL;
- error = xfs_da_grow_inode(args, &blkno);
- if (error)
- goto out;
- error = xfs_da_read_buf(args->trans, args->dp, 0, -1, &bp1,
- XFS_ATTR_FORK);
- if (error)
- goto out;
- ASSERT(bp1 != NULL);
- bp2 = NULL;
- error = xfs_da_get_buf(args->trans, args->dp, blkno, -1, &bp2,
- XFS_ATTR_FORK);
- if (error)
- goto out;
- ASSERT(bp2 != NULL);
- memcpy(bp2->data, bp1->data, XFS_LBSIZE(dp->i_mount));
- xfs_da_buf_done(bp1);
- bp1 = NULL;
- xfs_da_log_buf(args->trans, bp2, 0, XFS_LBSIZE(dp->i_mount) - 1);
-
- /*
- * Set up the new root node.
- */
- error = xfs_da_node_create(args, 0, 1, &bp1, XFS_ATTR_FORK);
- if (error)
- goto out;
- node = bp1->data;
- leaf = bp2->data;
- ASSERT(be16_to_cpu(leaf->hdr.info.magic) == XFS_ATTR_LEAF_MAGIC);
- /* both on-disk, don't endian-flip twice */
- node->btree[0].hashval =
- leaf->entries[be16_to_cpu(leaf->hdr.count)-1 ].hashval;
- node->btree[0].before = cpu_to_be32(blkno);
- node->hdr.count = cpu_to_be16(1);
- xfs_da_log_buf(args->trans, bp1, 0, XFS_LBSIZE(dp->i_mount) - 1);
- error = 0;
-out:
- if (bp1)
- xfs_da_buf_done(bp1);
- if (bp2)
- xfs_da_buf_done(bp2);
- return(error);
-}
-
-
-/*========================================================================
- * Routines used for growing the Btree.
- *========================================================================*/
-
-/*
- * Create the initial contents of a leaf attribute list
- * or a leaf in a node attribute list.
- */
-STATIC int
-xfs_attr_leaf_create(xfs_da_args_t *args, xfs_dablk_t blkno, xfs_dabuf_t **bpp)
-{
- xfs_attr_leafblock_t *leaf;
- xfs_attr_leaf_hdr_t *hdr;
- xfs_inode_t *dp;
- xfs_dabuf_t *bp;
- int error;
-
- dp = args->dp;
- ASSERT(dp != NULL);
- error = xfs_da_get_buf(args->trans, args->dp, blkno, -1, &bp,
- XFS_ATTR_FORK);
- if (error)
- return(error);
- ASSERT(bp != NULL);
- leaf = bp->data;
- memset((char *)leaf, 0, XFS_LBSIZE(dp->i_mount));
- hdr = &leaf->hdr;
- hdr->info.magic = cpu_to_be16(XFS_ATTR_LEAF_MAGIC);
- hdr->firstused = cpu_to_be16(XFS_LBSIZE(dp->i_mount));
- if (!hdr->firstused) {
- hdr->firstused = cpu_to_be16(
- XFS_LBSIZE(dp->i_mount) - XFS_ATTR_LEAF_NAME_ALIGN);
- }
-
- hdr->freemap[0].base = cpu_to_be16(sizeof(xfs_attr_leaf_hdr_t));
- hdr->freemap[0].size = cpu_to_be16(be16_to_cpu(hdr->firstused) -
- sizeof(xfs_attr_leaf_hdr_t));
-
- xfs_da_log_buf(args->trans, bp, 0, XFS_LBSIZE(dp->i_mount) - 1);
-
- *bpp = bp;
- return(0);
-}
-
-/*
- * Split the leaf node, rebalance, then add the new entry.
- */
-int
-xfs_attr_leaf_split(xfs_da_state_t *state, xfs_da_state_blk_t *oldblk,
- xfs_da_state_blk_t *newblk)
-{
- xfs_dablk_t blkno;
- int error;
-
- /*
- * Allocate space for a new leaf node.
- */
- ASSERT(oldblk->magic == XFS_ATTR_LEAF_MAGIC);
- error = xfs_da_grow_inode(state->args, &blkno);
- if (error)
- return(error);
- error = xfs_attr_leaf_create(state->args, blkno, &newblk->bp);
- if (error)
- return(error);
- newblk->blkno = blkno;
- newblk->magic = XFS_ATTR_LEAF_MAGIC;
-
- /*
- * Rebalance the entries across the two leaves.
- * NOTE: rebalance() currently depends on the 2nd block being empty.
- */
- xfs_attr_leaf_rebalance(state, oldblk, newblk);
- error = xfs_da_blk_link(state, oldblk, newblk);
- if (error)
- return(error);
-
- /*
- * Save info on "old" attribute for "atomic rename" ops, leaf_add()
- * modifies the index/blkno/rmtblk/rmtblkcnt fields to show the
- * "new" attrs info. Will need the "old" info to remove it later.
- *
- * Insert the "new" entry in the correct block.
- */
- if (state->inleaf)
- error = xfs_attr_leaf_add(oldblk->bp, state->args);
- else
- error = xfs_attr_leaf_add(newblk->bp, state->args);
-
- /*
- * Update last hashval in each block since we added the name.
- */
- oldblk->hashval = xfs_attr_leaf_lasthash(oldblk->bp, NULL);
- newblk->hashval = xfs_attr_leaf_lasthash(newblk->bp, NULL);
- return(error);
-}
-
-/*
- * Add a name to the leaf attribute list structure.
- */
-int
-xfs_attr_leaf_add(xfs_dabuf_t *bp, xfs_da_args_t *args)
-{
- xfs_attr_leafblock_t *leaf;
- xfs_attr_leaf_hdr_t *hdr;
- xfs_attr_leaf_map_t *map;
- int tablesize, entsize, sum, tmp, i;
-
- leaf = bp->data;
- ASSERT(be16_to_cpu(leaf->hdr.info.magic) == XFS_ATTR_LEAF_MAGIC);
- ASSERT((args->index >= 0)
- && (args->index <= be16_to_cpu(leaf->hdr.count)));
- hdr = &leaf->hdr;
- entsize = xfs_attr_leaf_newentsize(args->namelen, args->valuelen,
- args->trans->t_mountp->m_sb.sb_blocksize, NULL);
-
- /*
- * Search through freemap for first-fit on new name length.
- * (may need to figure in size of entry struct too)
- */
- tablesize = (be16_to_cpu(hdr->count) + 1)
- * sizeof(xfs_attr_leaf_entry_t)
- + sizeof(xfs_attr_leaf_hdr_t);
- map = &hdr->freemap[XFS_ATTR_LEAF_MAPSIZE-1];
- for (sum = 0, i = XFS_ATTR_LEAF_MAPSIZE-1; i >= 0; map--, i--) {
- if (tablesize > be16_to_cpu(hdr->firstused)) {
- sum += be16_to_cpu(map->size);
- continue;
- }
- if (!map->size)
- continue; /* no space in this map */
- tmp = entsize;
- if (be16_to_cpu(map->base) < be16_to_cpu(hdr->firstused))
- tmp += sizeof(xfs_attr_leaf_entry_t);
- if (be16_to_cpu(map->size) >= tmp) {
- tmp = xfs_attr_leaf_add_work(bp, args, i);
- return(tmp);
- }
- sum += be16_to_cpu(map->size);
- }
-
- /*
- * If there are no holes in the address space of the block,
- * and we don't have enough freespace, then compaction will do us
- * no good and we should just give up.
- */
- if (!hdr->holes && (sum < entsize))
- return(XFS_ERROR(ENOSPC));
-
- /*
- * Compact the entries to coalesce free space.
- * This may change the hdr->count via dropping INCOMPLETE entries.
- */
- xfs_attr_leaf_compact(args->trans, bp);
-
- /*
- * After compaction, the block is guaranteed to have only one
- * free region, in freemap[0]. If it is not big enough, give up.
- */
- if (be16_to_cpu(hdr->freemap[0].size)
- < (entsize + sizeof(xfs_attr_leaf_entry_t)))
- return(XFS_ERROR(ENOSPC));
-
- return(xfs_attr_leaf_add_work(bp, args, 0));
-}
-
-/*
- * Add a name to a leaf attribute list structure.
- */
-STATIC int
-xfs_attr_leaf_add_work(xfs_dabuf_t *bp, xfs_da_args_t *args, int mapindex)
-{
- xfs_attr_leafblock_t *leaf;
- xfs_attr_leaf_hdr_t *hdr;
- xfs_attr_leaf_entry_t *entry;
- xfs_attr_leaf_name_local_t *name_loc;
- xfs_attr_leaf_name_remote_t *name_rmt;
- xfs_attr_leaf_map_t *map;
- xfs_mount_t *mp;
- int tmp, i;
-
- leaf = bp->data;
- ASSERT(be16_to_cpu(leaf->hdr.info.magic) == XFS_ATTR_LEAF_MAGIC);
- hdr = &leaf->hdr;
- ASSERT((mapindex >= 0) && (mapindex < XFS_ATTR_LEAF_MAPSIZE));
- ASSERT((args->index >= 0) && (args->index <= be16_to_cpu(hdr->count)));
-
- /*
- * Force open some space in the entry array and fill it in.
- */
- entry = &leaf->entries[args->index];
- if (args->index < be16_to_cpu(hdr->count)) {
- tmp = be16_to_cpu(hdr->count) - args->index;
- tmp *= sizeof(xfs_attr_leaf_entry_t);
- memmove((char *)(entry+1), (char *)entry, tmp);
- xfs_da_log_buf(args->trans, bp,
- XFS_DA_LOGRANGE(leaf, entry, tmp + sizeof(*entry)));
- }
- be16_add(&hdr->count, 1);
-
- /*
- * Allocate space for the new string (at the end of the run).
- */
- map = &hdr->freemap[mapindex];
- mp = args->trans->t_mountp;
- ASSERT(be16_to_cpu(map->base) < XFS_LBSIZE(mp));
- ASSERT((be16_to_cpu(map->base) & 0x3) == 0);
- ASSERT(be16_to_cpu(map->size) >=
- xfs_attr_leaf_newentsize(args->namelen, args->valuelen,
- mp->m_sb.sb_blocksize, NULL));
- ASSERT(be16_to_cpu(map->size) < XFS_LBSIZE(mp));
- ASSERT((be16_to_cpu(map->size) & 0x3) == 0);
- be16_add(&map->size,
- -xfs_attr_leaf_newentsize(args->namelen, args->valuelen,
- mp->m_sb.sb_blocksize, &tmp));
- entry->nameidx = cpu_to_be16(be16_to_cpu(map->base) +
- be16_to_cpu(map->size));
- entry->hashval = cpu_to_be32(args->hashval);
- entry->flags = tmp ? XFS_ATTR_LOCAL : 0;
- entry->flags |= (args->flags & ATTR_SECURE) ? XFS_ATTR_SECURE :
- ((args->flags & ATTR_ROOT) ? XFS_ATTR_ROOT : 0);
- if (args->rename) {
- entry->flags |= XFS_ATTR_INCOMPLETE;
- if ((args->blkno2 == args->blkno) &&
- (args->index2 <= args->index)) {
- args->index2++;
- }
- }
- xfs_da_log_buf(args->trans, bp,
- XFS_DA_LOGRANGE(leaf, entry, sizeof(*entry)));
- ASSERT((args->index == 0) ||
- (be32_to_cpu(entry->hashval) >= be32_to_cpu((entry-1)->hashval)));
- ASSERT((args->index == be16_to_cpu(hdr->count)-1) ||
- (be32_to_cpu(entry->hashval) <= be32_to_cpu((entry+1)->hashval)));
-
- /*
- * Copy the attribute name and value into the new space.
- *
- * For "remote" attribute values, simply note that we need to
- * allocate space for the "remote" value. We can't actually
- * allocate the extents in this transaction, and we can't decide
- * which blocks they should be as we might allocate more blocks
- * as part of this transaction (a split operation for example).
- */
- if (entry->flags & XFS_ATTR_LOCAL) {
- name_loc = XFS_ATTR_LEAF_NAME_LOCAL(leaf, args->index);
- name_loc->namelen = args->namelen;
- name_loc->valuelen = cpu_to_be16(args->valuelen);
- memcpy((char *)name_loc->nameval, args->name, args->namelen);
- memcpy((char *)&name_loc->nameval[args->namelen], args->value,
- be16_to_cpu(name_loc->valuelen));
- } else {
- name_rmt = XFS_ATTR_LEAF_NAME_REMOTE(leaf, args->index);
- name_rmt->namelen = args->namelen;
- memcpy((char *)name_rmt->name, args->name, args->namelen);
- entry->flags |= XFS_ATTR_INCOMPLETE;
- /* just in case */
- name_rmt->valuelen = 0;
- name_rmt->valueblk = 0;
- args->rmtblkno = 1;
- args->rmtblkcnt = XFS_B_TO_FSB(mp, args->valuelen);
- }
- xfs_da_log_buf(args->trans, bp,
- XFS_DA_LOGRANGE(leaf, XFS_ATTR_LEAF_NAME(leaf, args->index),
- xfs_attr_leaf_entsize(leaf, args->index)));
-
- /*
- * Update the control info for this leaf node
- */
- if (be16_to_cpu(entry->nameidx) < be16_to_cpu(hdr->firstused)) {
- /* both on-disk, don't endian-flip twice */
- hdr->firstused = entry->nameidx;
- }
- ASSERT(be16_to_cpu(hdr->firstused) >=
- ((be16_to_cpu(hdr->count) * sizeof(*entry)) + sizeof(*hdr)));
- tmp = (be16_to_cpu(hdr->count)-1) * sizeof(xfs_attr_leaf_entry_t)
- + sizeof(xfs_attr_leaf_hdr_t);
- map = &hdr->freemap[0];
- for (i = 0; i < XFS_ATTR_LEAF_MAPSIZE; map++, i++) {
- if (be16_to_cpu(map->base) == tmp) {
- be16_add(&map->base, sizeof(xfs_attr_leaf_entry_t));
- be16_add(&map->size,
- -((int)sizeof(xfs_attr_leaf_entry_t)));
- }
- }
- be16_add(&hdr->usedbytes, xfs_attr_leaf_entsize(leaf, args->index));
- xfs_da_log_buf(args->trans, bp,
- XFS_DA_LOGRANGE(leaf, hdr, sizeof(*hdr)));
- return(0);
-}
-
-/*
- * Garbage collect a leaf attribute list block by copying it to a new buffer.
- */
-STATIC void
-xfs_attr_leaf_compact(xfs_trans_t *trans, xfs_dabuf_t *bp)
-{
- xfs_attr_leafblock_t *leaf_s, *leaf_d;
- xfs_attr_leaf_hdr_t *hdr_s, *hdr_d;
- xfs_mount_t *mp;
- char *tmpbuffer;
-
- mp = trans->t_mountp;
- tmpbuffer = kmem_alloc(XFS_LBSIZE(mp), KM_SLEEP);
- ASSERT(tmpbuffer != NULL);
- memcpy(tmpbuffer, bp->data, XFS_LBSIZE(mp));
- memset(bp->data, 0, XFS_LBSIZE(mp));
-
- /*
- * Copy basic information
- */
- leaf_s = (xfs_attr_leafblock_t *)tmpbuffer;
- leaf_d = bp->data;
- hdr_s = &leaf_s->hdr;
- hdr_d = &leaf_d->hdr;
- hdr_d->info = hdr_s->info; /* struct copy */
- hdr_d->firstused = cpu_to_be16(XFS_LBSIZE(mp));
- /* handle truncation gracefully */
- if (!hdr_d->firstused) {
- hdr_d->firstused = cpu_to_be16(
- XFS_LBSIZE(mp) - XFS_ATTR_LEAF_NAME_ALIGN);
- }
- hdr_d->usedbytes = 0;
- hdr_d->count = 0;
- hdr_d->holes = 0;
- hdr_d->freemap[0].base = cpu_to_be16(sizeof(xfs_attr_leaf_hdr_t));
- hdr_d->freemap[0].size = cpu_to_be16(be16_to_cpu(hdr_d->firstused) -
- sizeof(xfs_attr_leaf_hdr_t));
-
- /*
- * Copy all entry's in the same (sorted) order,
- * but allocate name/value pairs packed and in sequence.
- */
- xfs_attr_leaf_moveents(leaf_s, 0, leaf_d, 0,
- be16_to_cpu(hdr_s->count), mp);
- xfs_da_log_buf(trans, bp, 0, XFS_LBSIZE(mp) - 1);
-
- kmem_free(tmpbuffer, XFS_LBSIZE(mp));
-}
-
-/*
- * Redistribute the attribute list entries between two leaf nodes,
- * taking into account the size of the new entry.
- *
- * NOTE: if new block is empty, then it will get the upper half of the
- * old block. At present, all (one) callers pass in an empty second block.
- *
- * This code adjusts the args->index/blkno and args->index2/blkno2 fields
- * to match what it is doing in splitting the attribute leaf block. Those
- * values are used in "atomic rename" operations on attributes. Note that
- * the "new" and "old" values can end up in different blocks.
- */
-STATIC void
-xfs_attr_leaf_rebalance(xfs_da_state_t *state, xfs_da_state_blk_t *blk1,
- xfs_da_state_blk_t *blk2)
-{
- xfs_da_args_t *args;
- xfs_da_state_blk_t *tmp_blk;
- xfs_attr_leafblock_t *leaf1, *leaf2;
- xfs_attr_leaf_hdr_t *hdr1, *hdr2;
- int count, totallen, max, space, swap;
-
- /*
- * Set up environment.
- */
- ASSERT(blk1->magic == XFS_ATTR_LEAF_MAGIC);
- ASSERT(blk2->magic == XFS_ATTR_LEAF_MAGIC);
- leaf1 = blk1->bp->data;
- leaf2 = blk2->bp->data;
- ASSERT(be16_to_cpu(leaf1->hdr.info.magic) == XFS_ATTR_LEAF_MAGIC);
- ASSERT(be16_to_cpu(leaf2->hdr.info.magic) == XFS_ATTR_LEAF_MAGIC);
- args = state->args;
-
- /*
- * Check ordering of blocks, reverse if it makes things simpler.
- *
- * NOTE: Given that all (current) callers pass in an empty
- * second block, this code should never set "swap".
- */
- swap = 0;
- if (xfs_attr_leaf_order(blk1->bp, blk2->bp)) {
- tmp_blk = blk1;
- blk1 = blk2;
- blk2 = tmp_blk;
- leaf1 = blk1->bp->data;
- leaf2 = blk2->bp->data;
- swap = 1;
- }
- hdr1 = &leaf1->hdr;
- hdr2 = &leaf2->hdr;
-
- /*
- * Examine entries until we reduce the absolute difference in
- * byte usage between the two blocks to a minimum. Then get
- * the direction to copy and the number of elements to move.
- *
- * "inleaf" is true if the new entry should be inserted into blk1.
- * If "swap" is also true, then reverse the sense of "inleaf".
- */
- state->inleaf = xfs_attr_leaf_figure_balance(state, blk1, blk2,
- &count, &totallen);
- if (swap)
- state->inleaf = !state->inleaf;
-
- /*
- * Move any entries required from leaf to leaf:
- */
- if (count < be16_to_cpu(hdr1->count)) {
- /*
- * Figure the total bytes to be added to the destination leaf.
- */
- /* number entries being moved */
- count = be16_to_cpu(hdr1->count) - count;
- space = be16_to_cpu(hdr1->usedbytes) - totallen;
- space += count * sizeof(xfs_attr_leaf_entry_t);
-
- /*
- * leaf2 is the destination, compact it if it looks tight.
- */
- max = be16_to_cpu(hdr2->firstused)
- - sizeof(xfs_attr_leaf_hdr_t);
- max -= be16_to_cpu(hdr2->count) * sizeof(xfs_attr_leaf_entry_t);
- if (space > max) {
- xfs_attr_leaf_compact(args->trans, blk2->bp);
- }
-
- /*
- * Move high entries from leaf1 to low end of leaf2.
- */
- xfs_attr_leaf_moveents(leaf1, be16_to_cpu(hdr1->count) - count,
- leaf2, 0, count, state->mp);
-
- xfs_da_log_buf(args->trans, blk1->bp, 0, state->blocksize-1);
- xfs_da_log_buf(args->trans, blk2->bp, 0, state->blocksize-1);
- } else if (count > be16_to_cpu(hdr1->count)) {
- /*
- * I assert that since all callers pass in an empty
- * second buffer, this code should never execute.
- */
-
- /*
- * Figure the total bytes to be added to the destination leaf.
- */
- /* number entries being moved */
- count -= be16_to_cpu(hdr1->count);
- space = totallen - be16_to_cpu(hdr1->usedbytes);
- space += count * sizeof(xfs_attr_leaf_entry_t);
-
- /*
- * leaf1 is the destination, compact it if it looks tight.
- */
- max = be16_to_cpu(hdr1->firstused)
- - sizeof(xfs_attr_leaf_hdr_t);
- max -= be16_to_cpu(hdr1->count) * sizeof(xfs_attr_leaf_entry_t);
- if (space > max) {
- xfs_attr_leaf_compact(args->trans, blk1->bp);
- }
-
- /*
- * Move low entries from leaf2 to high end of leaf1.
- */
- xfs_attr_leaf_moveents(leaf2, 0, leaf1,
- be16_to_cpu(hdr1->count), count, state->mp);
-
- xfs_da_log_buf(args->trans, blk1->bp, 0, state->blocksize-1);
- xfs_da_log_buf(args->trans, blk2->bp, 0, state->blocksize-1);
- }
-
- /*
- * Copy out last hashval in each block for B-tree code.
- */
- blk1->hashval = be32_to_cpu(
- leaf1->entries[be16_to_cpu(leaf1->hdr.count)-1].hashval);
- blk2->hashval = be32_to_cpu(
- leaf2->entries[be16_to_cpu(leaf2->hdr.count)-1].hashval);
-
- /*
- * Adjust the expected index for insertion.
- * NOTE: this code depends on the (current) situation that the
- * second block was originally empty.
- *
- * If the insertion point moved to the 2nd block, we must adjust
- * the index. We must also track the entry just following the
- * new entry for use in an "atomic rename" operation, that entry
- * is always the "old" entry and the "new" entry is what we are
- * inserting. The index/blkno fields refer to the "old" entry,
- * while the index2/blkno2 fields refer to the "new" entry.
- */
- if (blk1->index > be16_to_cpu(leaf1->hdr.count)) {
- ASSERT(state->inleaf == 0);
- blk2->index = blk1->index - be16_to_cpu(leaf1->hdr.count);
- args->index = args->index2 = blk2->index;
- args->blkno = args->blkno2 = blk2->blkno;
- } else if (blk1->index == be16_to_cpu(leaf1->hdr.count)) {
- if (state->inleaf) {
- args->index = blk1->index;
- args->blkno = blk1->blkno;
- args->index2 = 0;
- args->blkno2 = blk2->blkno;
- } else {
- blk2->index = blk1->index
- - be16_to_cpu(leaf1->hdr.count);
- args->index = args->index2 = blk2->index;
- args->blkno = args->blkno2 = blk2->blkno;
- }
- } else {
- ASSERT(state->inleaf == 1);
- args->index = args->index2 = blk1->index;
- args->blkno = args->blkno2 = blk1->blkno;
- }
-}
-
-/*
- * Examine entries until we reduce the absolute difference in
- * byte usage between the two blocks to a minimum.
- * GROT: Is this really necessary? With other than a 512 byte blocksize,
- * GROT: there will always be enough room in either block for a new entry.
- * GROT: Do a double-split for this case?
- */
-STATIC int
-xfs_attr_leaf_figure_balance(xfs_da_state_t *state,
- xfs_da_state_blk_t *blk1,
- xfs_da_state_blk_t *blk2,
- int *countarg, int *usedbytesarg)
-{
- xfs_attr_leafblock_t *leaf1, *leaf2;
- xfs_attr_leaf_hdr_t *hdr1, *hdr2;
- xfs_attr_leaf_entry_t *entry;
- int count, max, index, totallen, half;
- int lastdelta, foundit, tmp;
-
- /*
- * Set up environment.
- */
- leaf1 = blk1->bp->data;
- leaf2 = blk2->bp->data;
- hdr1 = &leaf1->hdr;
- hdr2 = &leaf2->hdr;
- foundit = 0;
- totallen = 0;
-
- /*
- * Examine entries until we reduce the absolute difference in
- * byte usage between the two blocks to a minimum.
- */
- max = be16_to_cpu(hdr1->count) + be16_to_cpu(hdr2->count);
- half = (max+1) * sizeof(*entry);
- half += be16_to_cpu(hdr1->usedbytes) +
- be16_to_cpu(hdr2->usedbytes) +
- xfs_attr_leaf_newentsize(
- state->args->namelen,
- state->args->valuelen,
- state->blocksize, NULL);
- half /= 2;
- lastdelta = state->blocksize;
- entry = &leaf1->entries[0];
- for (count = index = 0; count < max; entry++, index++, count++) {
-
-#define XFS_ATTR_ABS(A) (((A) < 0) ? -(A) : (A))
- /*
- * The new entry is in the first block, account for it.
- */
- if (count == blk1->index) {
- tmp = totallen + sizeof(*entry) +
- xfs_attr_leaf_newentsize(
- state->args->namelen,
- state->args->valuelen,
- state->blocksize, NULL);
- if (XFS_ATTR_ABS(half - tmp) > lastdelta)
- break;
- lastdelta = XFS_ATTR_ABS(half - tmp);
- totallen = tmp;
- foundit = 1;
- }
-
- /*
- * Wrap around into the second block if necessary.
- */
- if (count == be16_to_cpu(hdr1->count)) {
- leaf1 = leaf2;
- entry = &leaf1->entries[0];
- index = 0;
- }
-
- /*
- * Figure out if next leaf entry would be too much.
- */
- tmp = totallen + sizeof(*entry) + xfs_attr_leaf_entsize(leaf1,
- index);
- if (XFS_ATTR_ABS(half - tmp) > lastdelta)
- break;
- lastdelta = XFS_ATTR_ABS(half - tmp);
- totallen = tmp;
-#undef XFS_ATTR_ABS
- }
-
- /*
- * Calculate the number of usedbytes that will end up in lower block.
- * If new entry not in lower block, fix up the count.
- */
- totallen -= count * sizeof(*entry);
- if (foundit) {
- totallen -= sizeof(*entry) +
- xfs_attr_leaf_newentsize(
- state->args->namelen,
- state->args->valuelen,
- state->blocksize, NULL);
- }
-
- *countarg = count;
- *usedbytesarg = totallen;
- return(foundit);
-}
-
-/*========================================================================
- * Routines used for shrinking the Btree.
- *========================================================================*/
-
-/*
- * Check a leaf block and its neighbors to see if the block should be
- * collapsed into one or the other neighbor. Always keep the block
- * with the smaller block number.
- * If the current block is over 50% full, don't try to join it, return 0.
- * If the block is empty, fill in the state structure and return 2.
- * If it can be collapsed, fill in the state structure and return 1.
- * If nothing can be done, return 0.
- *
- * GROT: allow for INCOMPLETE entries in calculation.
- */
-int
-xfs_attr_leaf_toosmall(xfs_da_state_t *state, int *action)
-{
- xfs_attr_leafblock_t *leaf;
- xfs_da_state_blk_t *blk;
- xfs_da_blkinfo_t *info;
- int count, bytes, forward, error, retval, i;
- xfs_dablk_t blkno;
- xfs_dabuf_t *bp;
-
- /*
- * Check for the degenerate case of the block being over 50% full.
- * If so, it's not worth even looking to see if we might be able
- * to coalesce with a sibling.
- */
- blk = &state->path.blk[ state->path.active-1 ];
- info = blk->bp->data;
- ASSERT(be16_to_cpu(info->magic) == XFS_ATTR_LEAF_MAGIC);
- leaf = (xfs_attr_leafblock_t *)info;
- count = be16_to_cpu(leaf->hdr.count);
- bytes = sizeof(xfs_attr_leaf_hdr_t) +
- count * sizeof(xfs_attr_leaf_entry_t) +
- be16_to_cpu(leaf->hdr.usedbytes);
- if (bytes > (state->blocksize >> 1)) {
- *action = 0; /* blk over 50%, don't try to join */
- return(0);
- }
-
- /*
- * Check for the degenerate case of the block being empty.
- * If the block is empty, we'll simply delete it, no need to
- * coalesce it with a sibling block. We choose (arbitrarily)
- * to merge with the forward block unless it is NULL.
- */
- if (count == 0) {
- /*
- * Make altpath point to the block we want to keep and
- * path point to the block we want to drop (this one).
- */
- forward = (info->forw != 0);
- memcpy(&state->altpath, &state->path, sizeof(state->path));
- error = xfs_da_path_shift(state, &state->altpath, forward,
- 0, &retval);
- if (error)
- return(error);
- if (retval) {
- *action = 0;
- } else {
- *action = 2;
- }
- return(0);
- }
-
- /*
- * Examine each sibling block to see if we can coalesce with
- * at least 25% free space to spare. We need to figure out
- * whether to merge with the forward or the backward block.
- * We prefer coalescing with the lower numbered sibling so as
- * to shrink an attribute list over time.
- */
- /* start with smaller blk num */
- forward = (be32_to_cpu(info->forw) < be32_to_cpu(info->back));
- for (i = 0; i < 2; forward = !forward, i++) {
- if (forward)
- blkno = be32_to_cpu(info->forw);
- else
- blkno = be32_to_cpu(info->back);
- if (blkno == 0)
- continue;
- error = xfs_da_read_buf(state->args->trans, state->args->dp,
- blkno, -1, &bp, XFS_ATTR_FORK);
- if (error)
- return(error);
- ASSERT(bp != NULL);
-
- leaf = (xfs_attr_leafblock_t *)info;
- count = be16_to_cpu(leaf->hdr.count);
- bytes = state->blocksize - (state->blocksize>>2);
- bytes -= be16_to_cpu(leaf->hdr.usedbytes);
- leaf = bp->data;
- ASSERT(be16_to_cpu(leaf->hdr.info.magic) == XFS_ATTR_LEAF_MAGIC);
- count += be16_to_cpu(leaf->hdr.count);
- bytes -= be16_to_cpu(leaf->hdr.usedbytes);
- bytes -= count * sizeof(xfs_attr_leaf_entry_t);
- bytes -= sizeof(xfs_attr_leaf_hdr_t);
- xfs_da_brelse(state->args->trans, bp);
- if (bytes >= 0)
- break; /* fits with at least 25% to spare */
- }
- if (i >= 2) {
- *action = 0;
- return(0);
- }
-
- /*
- * Make altpath point to the block we want to keep (the lower
- * numbered block) and path point to the block we want to drop.
- */
- memcpy(&state->altpath, &state->path, sizeof(state->path));
- if (blkno < blk->blkno) {
- error = xfs_da_path_shift(state, &state->altpath, forward,
- 0, &retval);
- } else {
- error = xfs_da_path_shift(state, &state->path, forward,
- 0, &retval);
- }
- if (error)
- return(error);
- if (retval) {
- *action = 0;
- } else {
- *action = 1;
- }
- return(0);
-}
-
-/*
- * Remove a name from the leaf attribute list structure.
- *
- * Return 1 if leaf is less than 37% full, 0 if >= 37% full.
- * If two leaves are 37% full, when combined they will leave 25% free.
- */
-int
-xfs_attr_leaf_remove(xfs_dabuf_t *bp, xfs_da_args_t *args)
-{
- xfs_attr_leafblock_t *leaf;
- xfs_attr_leaf_hdr_t *hdr;
- xfs_attr_leaf_map_t *map;
- xfs_attr_leaf_entry_t *entry;
- int before, after, smallest, entsize;
- int tablesize, tmp, i;
- xfs_mount_t *mp;
-
- leaf = bp->data;
- ASSERT(be16_to_cpu(leaf->hdr.info.magic) == XFS_ATTR_LEAF_MAGIC);
- hdr = &leaf->hdr;
- mp = args->trans->t_mountp;
- ASSERT((be16_to_cpu(hdr->count) > 0)
- && (be16_to_cpu(hdr->count) < (XFS_LBSIZE(mp)/8)));
- ASSERT((args->index >= 0)
- && (args->index < be16_to_cpu(hdr->count)));
- ASSERT(be16_to_cpu(hdr->firstused) >=
- ((be16_to_cpu(hdr->count) * sizeof(*entry)) + sizeof(*hdr)));
- entry = &leaf->entries[args->index];
- ASSERT(be16_to_cpu(entry->nameidx) >= be16_to_cpu(hdr->firstused));
- ASSERT(be16_to_cpu(entry->nameidx) < XFS_LBSIZE(mp));
-
- /*
- * Scan through free region table:
- * check for adjacency of free'd entry with an existing one,
- * find smallest free region in case we need to replace it,
- * adjust any map that borders the entry table,
- */
- tablesize = be16_to_cpu(hdr->count) * sizeof(xfs_attr_leaf_entry_t)
- + sizeof(xfs_attr_leaf_hdr_t);
- map = &hdr->freemap[0];
- tmp = be16_to_cpu(map->size);
- before = after = -1;
- smallest = XFS_ATTR_LEAF_MAPSIZE - 1;
- entsize = xfs_attr_leaf_entsize(leaf, args->index);
- for (i = 0; i < XFS_ATTR_LEAF_MAPSIZE; map++, i++) {
- ASSERT(be16_to_cpu(map->base) < XFS_LBSIZE(mp));
- ASSERT(be16_to_cpu(map->size) < XFS_LBSIZE(mp));
- if (be16_to_cpu(map->base) == tablesize) {
- be16_add(&map->base,
- -((int)sizeof(xfs_attr_leaf_entry_t)));
- be16_add(&map->size, sizeof(xfs_attr_leaf_entry_t));
- }
-
- if ((be16_to_cpu(map->base) + be16_to_cpu(map->size))
- == be16_to_cpu(entry->nameidx)) {
- before = i;
- } else if (be16_to_cpu(map->base)
- == (be16_to_cpu(entry->nameidx) + entsize)) {
- after = i;
- } else if (be16_to_cpu(map->size) < tmp) {
- tmp = be16_to_cpu(map->size);
- smallest = i;
- }
- }
-
- /*
- * Coalesce adjacent freemap regions,
- * or replace the smallest region.
- */
- if ((before >= 0) || (after >= 0)) {
- if ((before >= 0) && (after >= 0)) {
- map = &hdr->freemap[before];
- be16_add(&map->size, entsize);
- be16_add(&map->size,
- be16_to_cpu(hdr->freemap[after].size));
- hdr->freemap[after].base = 0;
- hdr->freemap[after].size = 0;
- } else if (before >= 0) {
- map = &hdr->freemap[before];
- be16_add(&map->size, entsize);
- } else {
- map = &hdr->freemap[after];
- /* both on-disk, don't endian flip twice */
- map->base = entry->nameidx;
- be16_add(&map->size, entsize);
- }
- } else {
- /*
- * Replace smallest region (if it is smaller than free'd entry)
- */
- map = &hdr->freemap[smallest];
- if (be16_to_cpu(map->size) < entsize) {
- map->base = cpu_to_be16(be16_to_cpu(entry->nameidx));
- map->size = cpu_to_be16(entsize);
- }
- }
-
- /*
- * Did we remove the first entry?
- */
- if (be16_to_cpu(entry->nameidx) == be16_to_cpu(hdr->firstused))
- smallest = 1;
- else
- smallest = 0;
-
- /*
- * Compress the remaining entries and zero out the removed stuff.
- */
- memset(XFS_ATTR_LEAF_NAME(leaf, args->index), 0, entsize);
- be16_add(&hdr->usedbytes, -entsize);
- xfs_da_log_buf(args->trans, bp,
- XFS_DA_LOGRANGE(leaf, XFS_ATTR_LEAF_NAME(leaf, args->index),
- entsize));
-
- tmp = (be16_to_cpu(hdr->count) - args->index)
- * sizeof(xfs_attr_leaf_entry_t);
- memmove((char *)entry, (char *)(entry+1), tmp);
- be16_add(&hdr->count, -1);
- xfs_da_log_buf(args->trans, bp,
- XFS_DA_LOGRANGE(leaf, entry, tmp + sizeof(*entry)));
- entry = &leaf->entries[be16_to_cpu(hdr->count)];
- memset((char *)entry, 0, sizeof(xfs_attr_leaf_entry_t));
-
- /*
- * If we removed the first entry, re-find the first used byte
- * in the name area. Note that if the entry was the "firstused",
- * then we don't have a "hole" in our block resulting from
- * removing the name.
- */
- if (smallest) {
- tmp = XFS_LBSIZE(mp);
- entry = &leaf->entries[0];
- for (i = be16_to_cpu(hdr->count)-1; i >= 0; entry++, i--) {
- ASSERT(be16_to_cpu(entry->nameidx) >=
- be16_to_cpu(hdr->firstused));
- ASSERT(be16_to_cpu(entry->nameidx) < XFS_LBSIZE(mp));
-
- if (be16_to_cpu(entry->nameidx) < tmp)
- tmp = be16_to_cpu(entry->nameidx);
- }
- hdr->firstused = cpu_to_be16(tmp);
- if (!hdr->firstused) {
- hdr->firstused = cpu_to_be16(
- tmp - XFS_ATTR_LEAF_NAME_ALIGN);
- }
- } else {
- hdr->holes = 1; /* mark as needing compaction */
- }
- xfs_da_log_buf(args->trans, bp,
- XFS_DA_LOGRANGE(leaf, hdr, sizeof(*hdr)));
-
- /*
- * Check if leaf is less than 50% full, caller may want to
- * "join" the leaf with a sibling if so.
- */
- tmp = sizeof(xfs_attr_leaf_hdr_t);
- tmp += be16_to_cpu(leaf->hdr.count) * sizeof(xfs_attr_leaf_entry_t);
- tmp += be16_to_cpu(leaf->hdr.usedbytes);
- return(tmp < mp->m_attr_magicpct); /* leaf is < 37% full */
-}
-
-/*
- * Move all the attribute list entries from drop_leaf into save_leaf.
- */
-void
-xfs_attr_leaf_unbalance(xfs_da_state_t *state, xfs_da_state_blk_t *drop_blk,
- xfs_da_state_blk_t *save_blk)
-{
- xfs_attr_leafblock_t *drop_leaf, *save_leaf, *tmp_leaf;
- xfs_attr_leaf_hdr_t *drop_hdr, *save_hdr, *tmp_hdr;
- xfs_mount_t *mp;
- char *tmpbuffer;
-
- /*
- * Set up environment.
- */
- mp = state->mp;
- ASSERT(drop_blk->magic == XFS_ATTR_LEAF_MAGIC);
- ASSERT(save_blk->magic == XFS_ATTR_LEAF_MAGIC);
- drop_leaf = drop_blk->bp->data;
- save_leaf = save_blk->bp->data;
- ASSERT(be16_to_cpu(drop_leaf->hdr.info.magic) == XFS_ATTR_LEAF_MAGIC);
- ASSERT(be16_to_cpu(save_leaf->hdr.info.magic) == XFS_ATTR_LEAF_MAGIC);
- drop_hdr = &drop_leaf->hdr;
- save_hdr = &save_leaf->hdr;
-
- /*
- * Save last hashval from dying block for later Btree fixup.
- */
- drop_blk->hashval = be32_to_cpu(
- drop_leaf->entries[be16_to_cpu(drop_leaf->hdr.count)-1].hashval);
-
- /*
- * Check if we need a temp buffer, or can we do it in place.
- * Note that we don't check "leaf" for holes because we will
- * always be dropping it, toosmall() decided that for us already.
- */
- if (save_hdr->holes == 0) {
- /*
- * dest leaf has no holes, so we add there. May need
- * to make some room in the entry array.
- */
- if (xfs_attr_leaf_order(save_blk->bp, drop_blk->bp)) {
- xfs_attr_leaf_moveents(drop_leaf, 0, save_leaf, 0,
- be16_to_cpu(drop_hdr->count), mp);
- } else {
- xfs_attr_leaf_moveents(drop_leaf, 0, save_leaf,
- be16_to_cpu(save_hdr->count),
- be16_to_cpu(drop_hdr->count), mp);
- }
- } else {
- /*
- * Destination has holes, so we make a temporary copy
- * of the leaf and add them both to that.
- */
- tmpbuffer = kmem_alloc(state->blocksize, KM_SLEEP);
- ASSERT(tmpbuffer != NULL);
- memset(tmpbuffer, 0, state->blocksize);
- tmp_leaf = (xfs_attr_leafblock_t *)tmpbuffer;
- tmp_hdr = &tmp_leaf->hdr;
- tmp_hdr->info = save_hdr->info; /* struct copy */
- tmp_hdr->count = 0;
- tmp_hdr->firstused = cpu_to_be16(state->blocksize);
- if (!tmp_hdr->firstused) {
- tmp_hdr->firstused = cpu_to_be16(
- state->blocksize - XFS_ATTR_LEAF_NAME_ALIGN);
- }
- tmp_hdr->usedbytes = 0;
- if (xfs_attr_leaf_order(save_blk->bp, drop_blk->bp)) {
- xfs_attr_leaf_moveents(drop_leaf, 0, tmp_leaf, 0,
- be16_to_cpu(drop_hdr->count), mp);
- xfs_attr_leaf_moveents(save_leaf, 0, tmp_leaf,
- be16_to_cpu(tmp_leaf->hdr.count),
- be16_to_cpu(save_hdr->count), mp);
- } else {
- xfs_attr_leaf_moveents(save_leaf, 0, tmp_leaf, 0,
- be16_to_cpu(save_hdr->count), mp);
- xfs_attr_leaf_moveents(drop_leaf, 0, tmp_leaf,
- be16_to_cpu(tmp_leaf->hdr.count),
- be16_to_cpu(drop_hdr->count), mp);
- }
- memcpy((char *)save_leaf, (char *)tmp_leaf, state->blocksize);
- kmem_free(tmpbuffer, state->blocksize);
- }
-
- xfs_da_log_buf(state->args->trans, save_blk->bp, 0,
- state->blocksize - 1);
-
- /*
- * Copy out last hashval in each block for B-tree code.
- */
- save_blk->hashval = be32_to_cpu(
- save_leaf->entries[be16_to_cpu(save_leaf->hdr.count)-1].hashval);
-}
-
-/*========================================================================
- * Routines used for finding things in the Btree.
- *========================================================================*/
-
-/*
- * Look up a name in a leaf attribute list structure.
- * This is the internal routine, it uses the caller's buffer.
- *
- * Note that duplicate keys are allowed, but only check within the
- * current leaf node. The Btree code must check in adjacent leaf nodes.
- *
- * Return in args->index the index into the entry[] array of either
- * the found entry, or where the entry should have been (insert before
- * that entry).
- *
- * Don't change the args->value unless we find the attribute.
- */
-int
-xfs_attr_leaf_lookup_int(xfs_dabuf_t *bp, xfs_da_args_t *args)
-{
- xfs_attr_leafblock_t *leaf;
- xfs_attr_leaf_entry_t *entry;
- xfs_attr_leaf_name_local_t *name_loc;
- xfs_attr_leaf_name_remote_t *name_rmt;
- int probe, span;
- xfs_dahash_t hashval;
-
- leaf = bp->data;
- ASSERT(be16_to_cpu(leaf->hdr.info.magic) == XFS_ATTR_LEAF_MAGIC);
- ASSERT(be16_to_cpu(leaf->hdr.count)
- < (XFS_LBSIZE(args->dp->i_mount)/8));
-
- /*
- * Binary search. (note: small blocks will skip this loop)
- */
- hashval = args->hashval;
- probe = span = be16_to_cpu(leaf->hdr.count) / 2;
- for (entry = &leaf->entries[probe]; span > 4;
- entry = &leaf->entries[probe]) {
- span /= 2;
- if (be32_to_cpu(entry->hashval) < hashval)
- probe += span;
- else if (be32_to_cpu(entry->hashval) > hashval)
- probe -= span;
- else
- break;
- }
- ASSERT((probe >= 0) &&
- (!leaf->hdr.count
- || (probe < be16_to_cpu(leaf->hdr.count))));
- ASSERT((span <= 4) || (be32_to_cpu(entry->hashval) == hashval));
-
- /*
- * Since we may have duplicate hashval's, find the first matching
- * hashval in the leaf.
- */
- while ((probe > 0) && (be32_to_cpu(entry->hashval) >= hashval)) {
- entry--;
- probe--;
- }
- while ((probe < be16_to_cpu(leaf->hdr.count)) &&
- (be32_to_cpu(entry->hashval) < hashval)) {
- entry++;
- probe++;
- }
- if ((probe == be16_to_cpu(leaf->hdr.count)) ||
- (be32_to_cpu(entry->hashval) != hashval)) {
- args->index = probe;
- return(XFS_ERROR(ENOATTR));
- }
-
- /*
- * Duplicate keys may be present, so search all of them for a match.
- */
- for ( ; (probe < be16_to_cpu(leaf->hdr.count)) &&
- (be32_to_cpu(entry->hashval) == hashval);
- entry++, probe++) {
-/*
- * GROT: Add code to remove incomplete entries.
- */
- /*
- * If we are looking for INCOMPLETE entries, show only those.
- * If we are looking for complete entries, show only those.
- */
- if ((args->flags & XFS_ATTR_INCOMPLETE) !=
- (entry->flags & XFS_ATTR_INCOMPLETE)) {
- continue;
- }
- if (entry->flags & XFS_ATTR_LOCAL) {
- name_loc = XFS_ATTR_LEAF_NAME_LOCAL(leaf, probe);
- if (name_loc->namelen != args->namelen)
- continue;
- if (memcmp(args->name, (char *)name_loc->nameval,
- args->namelen) != 0)
- continue;
- if (((args->flags & ATTR_SECURE) != 0) !=
- ((entry->flags & XFS_ATTR_SECURE) != 0))
- continue;
- if (((args->flags & ATTR_ROOT) != 0) !=
- ((entry->flags & XFS_ATTR_ROOT) != 0))
- continue;
- args->index = probe;
- return(XFS_ERROR(EEXIST));
- } else {
- name_rmt = XFS_ATTR_LEAF_NAME_REMOTE(leaf, probe);
- if (name_rmt->namelen != args->namelen)
- continue;
- if (memcmp(args->name, (char *)name_rmt->name,
- args->namelen) != 0)
- continue;
- if (((args->flags & ATTR_SECURE) != 0) !=
- ((entry->flags & XFS_ATTR_SECURE) != 0))
- continue;
- if (((args->flags & ATTR_ROOT) != 0) !=
- ((entry->flags & XFS_ATTR_ROOT) != 0))
- continue;
- args->index = probe;
- args->rmtblkno = be32_to_cpu(name_rmt->valueblk);
- args->rmtblkcnt = XFS_B_TO_FSB(args->dp->i_mount,
- be32_to_cpu(name_rmt->valuelen));
- return(XFS_ERROR(EEXIST));
- }
- }
- args->index = probe;
- return(XFS_ERROR(ENOATTR));
-}
-
-/*
- * Get the value associated with an attribute name from a leaf attribute
- * list structure.
- */
-int
-xfs_attr_leaf_getvalue(xfs_dabuf_t *bp, xfs_da_args_t *args)
-{
- int valuelen;
- xfs_attr_leafblock_t *leaf;
- xfs_attr_leaf_entry_t *entry;
- xfs_attr_leaf_name_local_t *name_loc;
- xfs_attr_leaf_name_remote_t *name_rmt;
-
- leaf = bp->data;
- ASSERT(be16_to_cpu(leaf->hdr.info.magic) == XFS_ATTR_LEAF_MAGIC);
- ASSERT(be16_to_cpu(leaf->hdr.count)
- < (XFS_LBSIZE(args->dp->i_mount)/8));
- ASSERT(args->index < be16_to_cpu(leaf->hdr.count));
-
- entry = &leaf->entries[args->index];
- if (entry->flags & XFS_ATTR_LOCAL) {
- name_loc = XFS_ATTR_LEAF_NAME_LOCAL(leaf, args->index);
- ASSERT(name_loc->namelen == args->namelen);
- ASSERT(memcmp(args->name, name_loc->nameval, args->namelen) == 0);
- valuelen = be16_to_cpu(name_loc->valuelen);
- if (args->flags & ATTR_KERNOVAL) {
- args->valuelen = valuelen;
- return(0);
- }
- if (args->valuelen < valuelen) {
- args->valuelen = valuelen;
- return(XFS_ERROR(ERANGE));
- }
- args->valuelen = valuelen;
- memcpy(args->value, &name_loc->nameval[args->namelen], valuelen);
- } else {
- name_rmt = XFS_ATTR_LEAF_NAME_REMOTE(leaf, args->index);
- ASSERT(name_rmt->namelen == args->namelen);
- ASSERT(memcmp(args->name, name_rmt->name, args->namelen) == 0);
- valuelen = be32_to_cpu(name_rmt->valuelen);
- args->rmtblkno = be32_to_cpu(name_rmt->valueblk);
- args->rmtblkcnt = XFS_B_TO_FSB(args->dp->i_mount, valuelen);
- if (args->flags & ATTR_KERNOVAL) {
- args->valuelen = valuelen;
- return(0);
- }
- if (args->valuelen < valuelen) {
- args->valuelen = valuelen;
- return(XFS_ERROR(ERANGE));
- }
- args->valuelen = valuelen;
- }
- return(0);
-}
-
-/*========================================================================
- * Utility routines.
- *========================================================================*/
-
-/*
- * Move the indicated entries from one leaf to another.
- * NOTE: this routine modifies both source and destination leaves.
- */
-/*ARGSUSED*/
-STATIC void
-xfs_attr_leaf_moveents(xfs_attr_leafblock_t *leaf_s, int start_s,
- xfs_attr_leafblock_t *leaf_d, int start_d,
- int count, xfs_mount_t *mp)
-{
- xfs_attr_leaf_hdr_t *hdr_s, *hdr_d;
- xfs_attr_leaf_entry_t *entry_s, *entry_d;
- int desti, tmp, i;
-
- /*
- * Check for nothing to do.
- */
- if (count == 0)
- return;
-
- /*
- * Set up environment.
- */
- ASSERT(be16_to_cpu(leaf_s->hdr.info.magic) == XFS_ATTR_LEAF_MAGIC);
- ASSERT(be16_to_cpu(leaf_d->hdr.info.magic) == XFS_ATTR_LEAF_MAGIC);
- hdr_s = &leaf_s->hdr;
- hdr_d = &leaf_d->hdr;
- ASSERT((be16_to_cpu(hdr_s->count) > 0) &&
- (be16_to_cpu(hdr_s->count) < (XFS_LBSIZE(mp)/8)));
- ASSERT(be16_to_cpu(hdr_s->firstused) >=
- ((be16_to_cpu(hdr_s->count)
- * sizeof(*entry_s))+sizeof(*hdr_s)));
- ASSERT(be16_to_cpu(hdr_d->count) < (XFS_LBSIZE(mp)/8));
- ASSERT(be16_to_cpu(hdr_d->firstused) >=
- ((be16_to_cpu(hdr_d->count)
- * sizeof(*entry_d))+sizeof(*hdr_d)));
-
- ASSERT(start_s < be16_to_cpu(hdr_s->count));
- ASSERT(start_d <= be16_to_cpu(hdr_d->count));
- ASSERT(count <= be16_to_cpu(hdr_s->count));
-
- /*
- * Move the entries in the destination leaf up to make a hole?
- */
- if (start_d < be16_to_cpu(hdr_d->count)) {
- tmp = be16_to_cpu(hdr_d->count) - start_d;
- tmp *= sizeof(xfs_attr_leaf_entry_t);
- entry_s = &leaf_d->entries[start_d];
- entry_d = &leaf_d->entries[start_d + count];
- memmove((char *)entry_d, (char *)entry_s, tmp);
- }
-
- /*
- * Copy all entry's in the same (sorted) order,
- * but allocate attribute info packed and in sequence.
- */
- entry_s = &leaf_s->entries[start_s];
- entry_d = &leaf_d->entries[start_d];
- desti = start_d;
- for (i = 0; i < count; entry_s++, entry_d++, desti++, i++) {
- ASSERT(be16_to_cpu(entry_s->nameidx)
- >= be16_to_cpu(hdr_s->firstused));
- tmp = xfs_attr_leaf_entsize(leaf_s, start_s + i);
-#ifdef GROT
- /*
- * Code to drop INCOMPLETE entries. Difficult to use as we
- * may also need to change the insertion index. Code turned
- * off for 6.2, should be revisited later.
- */
- if (entry_s->flags & XFS_ATTR_INCOMPLETE) { /* skip partials? */
- memset(XFS_ATTR_LEAF_NAME(leaf_s, start_s + i), 0, tmp);
- be16_add(&hdr_s->usedbytes, -tmp);
- be16_add(&hdr_s->count, -1);
- entry_d--; /* to compensate for ++ in loop hdr */
- desti--;
- if ((start_s + i) < offset)
- result++; /* insertion index adjustment */
- } else {
-#endif /* GROT */
- be16_add(&hdr_d->firstused, -tmp);
- /* both on-disk, don't endian flip twice */
- entry_d->hashval = entry_s->hashval;
- /* both on-disk, don't endian flip twice */
- entry_d->nameidx = hdr_d->firstused;
- entry_d->flags = entry_s->flags;
- ASSERT(be16_to_cpu(entry_d->nameidx) + tmp
- <= XFS_LBSIZE(mp));
- memmove(XFS_ATTR_LEAF_NAME(leaf_d, desti),
- XFS_ATTR_LEAF_NAME(leaf_s, start_s + i), tmp);
- ASSERT(be16_to_cpu(entry_s->nameidx) + tmp
- <= XFS_LBSIZE(mp));
- memset(XFS_ATTR_LEAF_NAME(leaf_s, start_s + i), 0, tmp);
- be16_add(&hdr_s->usedbytes, -tmp);
- be16_add(&hdr_d->usedbytes, tmp);
- be16_add(&hdr_s->count, -1);
- be16_add(&hdr_d->count, 1);
- tmp = be16_to_cpu(hdr_d->count)
- * sizeof(xfs_attr_leaf_entry_t)
- + sizeof(xfs_attr_leaf_hdr_t);
- ASSERT(be16_to_cpu(hdr_d->firstused) >= tmp);
-#ifdef GROT
- }
-#endif /* GROT */
- }
-
- /*
- * Zero out the entries we just copied.
- */
- if (start_s == be16_to_cpu(hdr_s->count)) {
- tmp = count * sizeof(xfs_attr_leaf_entry_t);
- entry_s = &leaf_s->entries[start_s];
- ASSERT(((char *)entry_s + tmp) <=
- ((char *)leaf_s + XFS_LBSIZE(mp)));
- memset((char *)entry_s, 0, tmp);
- } else {
- /*
- * Move the remaining entries down to fill the hole,
- * then zero the entries at the top.
- */
- tmp = be16_to_cpu(hdr_s->count) - count;
- tmp *= sizeof(xfs_attr_leaf_entry_t);
- entry_s = &leaf_s->entries[start_s + count];
- entry_d = &leaf_s->entries[start_s];
- memmove((char *)entry_d, (char *)entry_s, tmp);
-
- tmp = count * sizeof(xfs_attr_leaf_entry_t);
- entry_s = &leaf_s->entries[be16_to_cpu(hdr_s->count)];
- ASSERT(((char *)entry_s + tmp) <=
- ((char *)leaf_s + XFS_LBSIZE(mp)));
- memset((char *)entry_s, 0, tmp);
- }
-
- /*
- * Fill in the freemap information
- */
- hdr_d->freemap[0].base = cpu_to_be16(sizeof(xfs_attr_leaf_hdr_t));
- be16_add(&hdr_d->freemap[0].base, be16_to_cpu(hdr_d->count) *
- sizeof(xfs_attr_leaf_entry_t));
- hdr_d->freemap[0].size = cpu_to_be16(be16_to_cpu(hdr_d->firstused)
- - be16_to_cpu(hdr_d->freemap[0].base));
- hdr_d->freemap[1].base = 0;
- hdr_d->freemap[2].base = 0;
- hdr_d->freemap[1].size = 0;
- hdr_d->freemap[2].size = 0;
- hdr_s->holes = 1; /* leaf may not be compact */
-}
-
-/*
- * Compare two leaf blocks "order".
- * Return 0 unless leaf2 should go before leaf1.
- */
-int
-xfs_attr_leaf_order(xfs_dabuf_t *leaf1_bp, xfs_dabuf_t *leaf2_bp)
-{
- xfs_attr_leafblock_t *leaf1, *leaf2;
-
- leaf1 = leaf1_bp->data;
- leaf2 = leaf2_bp->data;
- ASSERT((be16_to_cpu(leaf1->hdr.info.magic) == XFS_ATTR_LEAF_MAGIC) &&
- (be16_to_cpu(leaf2->hdr.info.magic) == XFS_ATTR_LEAF_MAGIC));
- if ((be16_to_cpu(leaf1->hdr.count) > 0) &&
- (be16_to_cpu(leaf2->hdr.count) > 0) &&
- ((be32_to_cpu(leaf2->entries[0].hashval) <
- be32_to_cpu(leaf1->entries[0].hashval)) ||
- (be32_to_cpu(leaf2->entries[
- be16_to_cpu(leaf2->hdr.count)-1].hashval) <
- be32_to_cpu(leaf1->entries[
- be16_to_cpu(leaf1->hdr.count)-1].hashval)))) {
- return(1);
- }
- return(0);
-}
-
-/*
- * Pick up the last hashvalue from a leaf block.
- */
-xfs_dahash_t
-xfs_attr_leaf_lasthash(xfs_dabuf_t *bp, int *count)
-{
- xfs_attr_leafblock_t *leaf;
-
- leaf = bp->data;
- ASSERT(be16_to_cpu(leaf->hdr.info.magic) == XFS_ATTR_LEAF_MAGIC);
- if (count)
- *count = be16_to_cpu(leaf->hdr.count);
- if (!leaf->hdr.count)
- return(0);
- return be32_to_cpu(leaf->entries[be16_to_cpu(leaf->hdr.count)-1].hashval);
-}
-
-/*
- * Calculate the number of bytes used to store the indicated attribute
- * (whether local or remote only calculate bytes in this block).
- */
-STATIC int
-xfs_attr_leaf_entsize(xfs_attr_leafblock_t *leaf, int index)
-{
- xfs_attr_leaf_name_local_t *name_loc;
- xfs_attr_leaf_name_remote_t *name_rmt;
- int size;
-
- ASSERT(be16_to_cpu(leaf->hdr.info.magic) == XFS_ATTR_LEAF_MAGIC);
- if (leaf->entries[index].flags & XFS_ATTR_LOCAL) {
- name_loc = XFS_ATTR_LEAF_NAME_LOCAL(leaf, index);
- size = XFS_ATTR_LEAF_ENTSIZE_LOCAL(name_loc->namelen,
- be16_to_cpu(name_loc->valuelen));
- } else {
- name_rmt = XFS_ATTR_LEAF_NAME_REMOTE(leaf, index);
- size = XFS_ATTR_LEAF_ENTSIZE_REMOTE(name_rmt->namelen);
- }
- return(size);
-}
-
-/*
- * Calculate the number of bytes that would be required to store the new
- * attribute (whether local or remote only calculate bytes in this block).
- * This routine decides as a side effect whether the attribute will be
- * a "local" or a "remote" attribute.
- */
-int
-xfs_attr_leaf_newentsize(int namelen, int valuelen, int blocksize, int *local)
-{
- int size;
-
- size = XFS_ATTR_LEAF_ENTSIZE_LOCAL(namelen, valuelen);
- if (size < XFS_ATTR_LEAF_ENTSIZE_LOCAL_MAX(blocksize)) {
- if (local) {
- *local = 1;
- }
- } else {
- size = XFS_ATTR_LEAF_ENTSIZE_REMOTE(namelen);
- if (local) {
- *local = 0;
- }
- }
- return(size);
-}
-
-/*
- * Copy out attribute list entries for attr_list(), for leaf attribute lists.
- */
-int
-xfs_attr_leaf_list_int(xfs_dabuf_t *bp, xfs_attr_list_context_t *context)
-{
- attrlist_cursor_kern_t *cursor;
- xfs_attr_leafblock_t *leaf;
- xfs_attr_leaf_entry_t *entry;
- xfs_attr_leaf_name_local_t *name_loc;
- xfs_attr_leaf_name_remote_t *name_rmt;
- int retval, i;
-
- ASSERT(bp != NULL);
- leaf = bp->data;
- cursor = context->cursor;
- cursor->initted = 1;
-
- xfs_attr_trace_l_cl("blk start", context, leaf);
-
- /*
- * Re-find our place in the leaf block if this is a new syscall.
- */
- if (context->resynch) {
- entry = &leaf->entries[0];
- for (i = 0; i < be16_to_cpu(leaf->hdr.count); entry++, i++) {
- if (be32_to_cpu(entry->hashval) == cursor->hashval) {
- if (cursor->offset == context->dupcnt) {
- context->dupcnt = 0;
- break;
- }
- context->dupcnt++;
- } else if (be32_to_cpu(entry->hashval) >
- cursor->hashval) {
- context->dupcnt = 0;
- break;
- }
- }
- if (i == be16_to_cpu(leaf->hdr.count)) {
- xfs_attr_trace_l_c("not found", context);
- return(0);
- }
- } else {
- entry = &leaf->entries[0];
- i = 0;
- }
- context->resynch = 0;
-
- /*
- * We have found our place, start copying out the new attributes.
- */
- retval = 0;
- for ( ; (i < be16_to_cpu(leaf->hdr.count))
- && (retval == 0); entry++, i++) {
- attrnames_t *namesp;
-
- if (be32_to_cpu(entry->hashval) != cursor->hashval) {
- cursor->hashval = be32_to_cpu(entry->hashval);
- cursor->offset = 0;
- }
-
- if (entry->flags & XFS_ATTR_INCOMPLETE)
- continue; /* skip incomplete entries */
- if (((context->flags & ATTR_SECURE) != 0) !=
- ((entry->flags & XFS_ATTR_SECURE) != 0) &&
- !(context->flags & ATTR_KERNORMALS))
- continue; /* skip non-matching entries */
- if (((context->flags & ATTR_ROOT) != 0) !=
- ((entry->flags & XFS_ATTR_ROOT) != 0) &&
- !(context->flags & ATTR_KERNROOTLS))
- continue; /* skip non-matching entries */
-
- namesp = (entry->flags & XFS_ATTR_SECURE) ? &attr_secure :
- ((entry->flags & XFS_ATTR_ROOT) ? &attr_trusted :
- &attr_user);
-
- if (entry->flags & XFS_ATTR_LOCAL) {
- name_loc = XFS_ATTR_LEAF_NAME_LOCAL(leaf, i);
- if (context->flags & ATTR_KERNOVAL) {
- ASSERT(context->flags & ATTR_KERNAMELS);
- context->count += namesp->attr_namelen +
- (int)name_loc->namelen + 1;
- } else {
- retval = xfs_attr_put_listent(context, namesp,
- (char *)name_loc->nameval,
- (int)name_loc->namelen,
- be16_to_cpu(name_loc->valuelen));
- }
- } else {
- name_rmt = XFS_ATTR_LEAF_NAME_REMOTE(leaf, i);
- if (context->flags & ATTR_KERNOVAL) {
- ASSERT(context->flags & ATTR_KERNAMELS);
- context->count += namesp->attr_namelen +
- (int)name_rmt->namelen + 1;
- } else {
- retval = xfs_attr_put_listent(context, namesp,
- (char *)name_rmt->name,
- (int)name_rmt->namelen,
- be32_to_cpu(name_rmt->valuelen));
- }
- }
- if (retval == 0) {
- cursor->offset++;
- }
- }
- xfs_attr_trace_l_cl("blk end", context, leaf);
- return(retval);
-}
-
-#define ATTR_ENTBASESIZE /* minimum bytes used by an attr */ \
- (((struct attrlist_ent *) 0)->a_name - (char *) 0)
-#define ATTR_ENTSIZE(namelen) /* actual bytes used by an attr */ \
- ((ATTR_ENTBASESIZE + (namelen) + 1 + sizeof(u_int32_t)-1) \
- & ~(sizeof(u_int32_t)-1))
-
-/*
- * Format an attribute and copy it out to the user's buffer.
- * Take care to check values and protect against them changing later,
- * we may be reading them directly out of a user buffer.
- */
-/*ARGSUSED*/
-STATIC int
-xfs_attr_put_listent(xfs_attr_list_context_t *context,
- attrnames_t *namesp, char *name, int namelen, int valuelen)
-{
- attrlist_ent_t *aep;
- int arraytop;
-
- ASSERT(!(context->flags & ATTR_KERNOVAL));
- if (context->flags & ATTR_KERNAMELS) {
- char *offset;
-
- ASSERT(context->count >= 0);
-
- arraytop = context->count + namesp->attr_namelen + namelen + 1;
- if (arraytop > context->firstu) {
- context->count = -1; /* insufficient space */
- return(1);
- }
- offset = (char *)context->alist + context->count;
- strncpy(offset, namesp->attr_name, namesp->attr_namelen);
- offset += namesp->attr_namelen;
- strncpy(offset, name, namelen); /* real name */
- offset += namelen;
- *offset = '\0';
- context->count += namesp->attr_namelen + namelen + 1;
- return(0);
- }
-
- ASSERT(context->count >= 0);
- ASSERT(context->count < (ATTR_MAX_VALUELEN/8));
- ASSERT(context->firstu >= sizeof(*context->alist));
- ASSERT(context->firstu <= context->bufsize);
-
- arraytop = sizeof(*context->alist) +
- context->count * sizeof(context->alist->al_offset[0]);
- context->firstu -= ATTR_ENTSIZE(namelen);
- if (context->firstu < arraytop) {
- xfs_attr_trace_l_c("buffer full", context);
- context->alist->al_more = 1;
- return(1);
- }
-
- aep = (attrlist_ent_t *)&(((char *)context->alist)[ context->firstu ]);
- aep->a_valuelen = valuelen;
- memcpy(aep->a_name, name, namelen);
- aep->a_name[ namelen ] = 0;
- context->alist->al_offset[ context->count++ ] = context->firstu;
- context->alist->al_count = context->count;
- xfs_attr_trace_l_c("add", context);
- return(0);
-}
-
-/*========================================================================
- * Manage the INCOMPLETE flag in a leaf entry
- *========================================================================*/
-
-/*
- * Clear the INCOMPLETE flag on an entry in a leaf block.
- */
-int
-xfs_attr_leaf_clearflag(xfs_da_args_t *args)
-{
- xfs_attr_leafblock_t *leaf;
- xfs_attr_leaf_entry_t *entry;
- xfs_attr_leaf_name_remote_t *name_rmt;
- xfs_dabuf_t *bp;
- int error;
-#ifdef DEBUG
- xfs_attr_leaf_name_local_t *name_loc;
- int namelen;
- char *name;
-#endif /* DEBUG */
-
- /*
- * Set up the operation.
- */
- error = xfs_da_read_buf(args->trans, args->dp, args->blkno, -1, &bp,
- XFS_ATTR_FORK);
- if (error) {
- return(error);
- }
- ASSERT(bp != NULL);
-
- leaf = bp->data;
- ASSERT(be16_to_cpu(leaf->hdr.info.magic) == XFS_ATTR_LEAF_MAGIC);
- ASSERT(args->index < be16_to_cpu(leaf->hdr.count));
- ASSERT(args->index >= 0);
- entry = &leaf->entries[ args->index ];
- ASSERT(entry->flags & XFS_ATTR_INCOMPLETE);
-
-#ifdef DEBUG
- if (entry->flags & XFS_ATTR_LOCAL) {
- name_loc = XFS_ATTR_LEAF_NAME_LOCAL(leaf, args->index);
- namelen = name_loc->namelen;
- name = (char *)name_loc->nameval;
- } else {
- name_rmt = XFS_ATTR_LEAF_NAME_REMOTE(leaf, args->index);
- namelen = name_rmt->namelen;
- name = (char *)name_rmt->name;
- }
- ASSERT(be32_to_cpu(entry->hashval) == args->hashval);
- ASSERT(namelen == args->namelen);
- ASSERT(memcmp(name, args->name, namelen) == 0);
-#endif /* DEBUG */
-
- entry->flags &= ~XFS_ATTR_INCOMPLETE;
- xfs_da_log_buf(args->trans, bp,
- XFS_DA_LOGRANGE(leaf, entry, sizeof(*entry)));
-
- if (args->rmtblkno) {
- ASSERT((entry->flags & XFS_ATTR_LOCAL) == 0);
- name_rmt = XFS_ATTR_LEAF_NAME_REMOTE(leaf, args->index);
- name_rmt->valueblk = cpu_to_be32(args->rmtblkno);
- name_rmt->valuelen = cpu_to_be32(args->valuelen);
- xfs_da_log_buf(args->trans, bp,
- XFS_DA_LOGRANGE(leaf, name_rmt, sizeof(*name_rmt)));
- }
- xfs_da_buf_done(bp);
-
- /*
- * Commit the flag value change and start the next trans in series.
- */
- error = xfs_attr_rolltrans(&args->trans, args->dp);
-
- return(error);
-}
-
-/*
- * Set the INCOMPLETE flag on an entry in a leaf block.
- */
-int
-xfs_attr_leaf_setflag(xfs_da_args_t *args)
-{
- xfs_attr_leafblock_t *leaf;
- xfs_attr_leaf_entry_t *entry;
- xfs_attr_leaf_name_remote_t *name_rmt;
- xfs_dabuf_t *bp;
- int error;
-
- /*
- * Set up the operation.
- */
- error = xfs_da_read_buf(args->trans, args->dp, args->blkno, -1, &bp,
- XFS_ATTR_FORK);
- if (error) {
- return(error);
- }
- ASSERT(bp != NULL);
-
- leaf = bp->data;
- ASSERT(be16_to_cpu(leaf->hdr.info.magic) == XFS_ATTR_LEAF_MAGIC);
- ASSERT(args->index < be16_to_cpu(leaf->hdr.count));
- ASSERT(args->index >= 0);
- entry = &leaf->entries[ args->index ];
-
- ASSERT((entry->flags & XFS_ATTR_INCOMPLETE) == 0);
- entry->flags |= XFS_ATTR_INCOMPLETE;
- xfs_da_log_buf(args->trans, bp,
- XFS_DA_LOGRANGE(leaf, entry, sizeof(*entry)));
- if ((entry->flags & XFS_ATTR_LOCAL) == 0) {
- name_rmt = XFS_ATTR_LEAF_NAME_REMOTE(leaf, args->index);
- name_rmt->valueblk = 0;
- name_rmt->valuelen = 0;
- xfs_da_log_buf(args->trans, bp,
- XFS_DA_LOGRANGE(leaf, name_rmt, sizeof(*name_rmt)));
- }
- xfs_da_buf_done(bp);
-
- /*
- * Commit the flag value change and start the next trans in series.
- */
- error = xfs_attr_rolltrans(&args->trans, args->dp);
-
- return(error);
-}
-
-/*
- * In a single transaction, clear the INCOMPLETE flag on the leaf entry
- * given by args->blkno/index and set the INCOMPLETE flag on the leaf
- * entry given by args->blkno2/index2.
- *
- * Note that they could be in different blocks, or in the same block.
- */
-int
-xfs_attr_leaf_flipflags(xfs_da_args_t *args)
-{
- xfs_attr_leafblock_t *leaf1, *leaf2;
- xfs_attr_leaf_entry_t *entry1, *entry2;
- xfs_attr_leaf_name_remote_t *name_rmt;
- xfs_dabuf_t *bp1, *bp2;
- int error;
-#ifdef DEBUG
- xfs_attr_leaf_name_local_t *name_loc;
- int namelen1, namelen2;
- char *name1, *name2;
-#endif /* DEBUG */
-
- /*
- * Read the block containing the "old" attr
- */
- error = xfs_da_read_buf(args->trans, args->dp, args->blkno, -1, &bp1,
- XFS_ATTR_FORK);
- if (error) {
- return(error);
- }
- ASSERT(bp1 != NULL);
-
- /*
- * Read the block containing the "new" attr, if it is different
- */
- if (args->blkno2 != args->blkno) {
- error = xfs_da_read_buf(args->trans, args->dp, args->blkno2,
- -1, &bp2, XFS_ATTR_FORK);
- if (error) {
- return(error);
- }
- ASSERT(bp2 != NULL);
- } else {
- bp2 = bp1;
- }
-
- leaf1 = bp1->data;
- ASSERT(be16_to_cpu(leaf1->hdr.info.magic) == XFS_ATTR_LEAF_MAGIC);
- ASSERT(args->index < be16_to_cpu(leaf1->hdr.count));
- ASSERT(args->index >= 0);
- entry1 = &leaf1->entries[ args->index ];
-
- leaf2 = bp2->data;
- ASSERT(be16_to_cpu(leaf2->hdr.info.magic) == XFS_ATTR_LEAF_MAGIC);
- ASSERT(args->index2 < be16_to_cpu(leaf2->hdr.count));
- ASSERT(args->index2 >= 0);
- entry2 = &leaf2->entries[ args->index2 ];
-
-#ifdef DEBUG
- if (entry1->flags & XFS_ATTR_LOCAL) {
- name_loc = XFS_ATTR_LEAF_NAME_LOCAL(leaf1, args->index);
- namelen1 = name_loc->namelen;
- name1 = (char *)name_loc->nameval;
- } else {
- name_rmt = XFS_ATTR_LEAF_NAME_REMOTE(leaf1, args->index);
- namelen1 = name_rmt->namelen;
- name1 = (char *)name_rmt->name;
- }
- if (entry2->flags & XFS_ATTR_LOCAL) {
- name_loc = XFS_ATTR_LEAF_NAME_LOCAL(leaf2, args->index2);
- namelen2 = name_loc->namelen;
- name2 = (char *)name_loc->nameval;
- } else {
- name_rmt = XFS_ATTR_LEAF_NAME_REMOTE(leaf2, args->index2);
- namelen2 = name_rmt->namelen;
- name2 = (char *)name_rmt->name;
- }
- ASSERT(be32_to_cpu(entry1->hashval) == be32_to_cpu(entry2->hashval));
- ASSERT(namelen1 == namelen2);
- ASSERT(memcmp(name1, name2, namelen1) == 0);
-#endif /* DEBUG */
-
- ASSERT(entry1->flags & XFS_ATTR_INCOMPLETE);
- ASSERT((entry2->flags & XFS_ATTR_INCOMPLETE) == 0);
-
- entry1->flags &= ~XFS_ATTR_INCOMPLETE;
- xfs_da_log_buf(args->trans, bp1,
- XFS_DA_LOGRANGE(leaf1, entry1, sizeof(*entry1)));
- if (args->rmtblkno) {
- ASSERT((entry1->flags & XFS_ATTR_LOCAL) == 0);
- name_rmt = XFS_ATTR_LEAF_NAME_REMOTE(leaf1, args->index);
- name_rmt->valueblk = cpu_to_be32(args->rmtblkno);
- name_rmt->valuelen = cpu_to_be32(args->valuelen);
- xfs_da_log_buf(args->trans, bp1,
- XFS_DA_LOGRANGE(leaf1, name_rmt, sizeof(*name_rmt)));
- }
-
- entry2->flags |= XFS_ATTR_INCOMPLETE;
- xfs_da_log_buf(args->trans, bp2,
- XFS_DA_LOGRANGE(leaf2, entry2, sizeof(*entry2)));
- if ((entry2->flags & XFS_ATTR_LOCAL) == 0) {
- name_rmt = XFS_ATTR_LEAF_NAME_REMOTE(leaf2, args->index2);
- name_rmt->valueblk = 0;
- name_rmt->valuelen = 0;
- xfs_da_log_buf(args->trans, bp2,
- XFS_DA_LOGRANGE(leaf2, name_rmt, sizeof(*name_rmt)));
- }
- xfs_da_buf_done(bp1);
- if (bp1 != bp2)
- xfs_da_buf_done(bp2);
-
- /*
- * Commit the flag value change and start the next trans in series.
- */
- error = xfs_attr_rolltrans(&args->trans, args->dp);
-
- return(error);
-}
-
-/*========================================================================
- * Indiscriminately delete the entire attribute fork
- *========================================================================*/
-
-/*
- * Recurse (gasp!) through the attribute nodes until we find leaves.
- * We're doing a depth-first traversal in order to invalidate everything.
- */
-int
-xfs_attr_root_inactive(xfs_trans_t **trans, xfs_inode_t *dp)
-{
- xfs_da_blkinfo_t *info;
- xfs_daddr_t blkno;
- xfs_dabuf_t *bp;
- int error;
-
- /*
- * Read block 0 to see what we have to work with.
- * We only get here if we have extents, since we remove
- * the extents in reverse order the extent containing
- * block 0 must still be there.
- */
- error = xfs_da_read_buf(*trans, dp, 0, -1, &bp, XFS_ATTR_FORK);
- if (error)
- return(error);
- blkno = xfs_da_blkno(bp);
-
- /*
- * Invalidate the tree, even if the "tree" is only a single leaf block.
- * This is a depth-first traversal!
- */
- info = bp->data;
- if (be16_to_cpu(info->magic) == XFS_DA_NODE_MAGIC) {
- error = xfs_attr_node_inactive(trans, dp, bp, 1);
- } else if (be16_to_cpu(info->magic) == XFS_ATTR_LEAF_MAGIC) {
- error = xfs_attr_leaf_inactive(trans, dp, bp);
- } else {
- error = XFS_ERROR(EIO);
- xfs_da_brelse(*trans, bp);
- }
- if (error)
- return(error);
-
- /*
- * Invalidate the incore copy of the root block.
- */
- error = xfs_da_get_buf(*trans, dp, 0, blkno, &bp, XFS_ATTR_FORK);
- if (error)
- return(error);
- xfs_da_binval(*trans, bp); /* remove from cache */
- /*
- * Commit the invalidate and start the next transaction.
- */
- error = xfs_attr_rolltrans(trans, dp);
-
- return (error);
-}
-
-/*
- * Recurse (gasp!) through the attribute nodes until we find leaves.
- * We're doing a depth-first traversal in order to invalidate everything.
- */
-STATIC int
-xfs_attr_node_inactive(xfs_trans_t **trans, xfs_inode_t *dp, xfs_dabuf_t *bp,
- int level)
-{
- xfs_da_blkinfo_t *info;
- xfs_da_intnode_t *node;
- xfs_dablk_t child_fsb;
- xfs_daddr_t parent_blkno, child_blkno;
- int error, count, i;
- xfs_dabuf_t *child_bp;
-
- /*
- * Since this code is recursive (gasp!) we must protect ourselves.
- */
- if (level > XFS_DA_NODE_MAXDEPTH) {
- xfs_da_brelse(*trans, bp); /* no locks for later trans */
- return(XFS_ERROR(EIO));
- }
-
- node = bp->data;
- ASSERT(be16_to_cpu(node->hdr.info.magic) == XFS_DA_NODE_MAGIC);
- parent_blkno = xfs_da_blkno(bp); /* save for re-read later */
- count = be16_to_cpu(node->hdr.count);
- if (!count) {
- xfs_da_brelse(*trans, bp);
- return(0);
- }
- child_fsb = be32_to_cpu(node->btree[0].before);
- xfs_da_brelse(*trans, bp); /* no locks for later trans */
-
- /*
- * If this is the node level just above the leaves, simply loop
- * over the leaves removing all of them. If this is higher up
- * in the tree, recurse downward.
- */
- for (i = 0; i < count; i++) {
- /*
- * Read the subsidiary block to see what we have to work with.
- * Don't do this in a transaction. This is a depth-first
- * traversal of the tree so we may deal with many blocks
- * before we come back to this one.
- */
- error = xfs_da_read_buf(*trans, dp, child_fsb, -2, &child_bp,
- XFS_ATTR_FORK);
- if (error)
- return(error);
- if (child_bp) {
- /* save for re-read later */
- child_blkno = xfs_da_blkno(child_bp);
-
- /*
- * Invalidate the subtree, however we have to.
- */
- info = child_bp->data;
- if (be16_to_cpu(info->magic) == XFS_DA_NODE_MAGIC) {
- error = xfs_attr_node_inactive(trans, dp,
- child_bp, level+1);
- } else if (be16_to_cpu(info->magic) == XFS_ATTR_LEAF_MAGIC) {
- error = xfs_attr_leaf_inactive(trans, dp,
- child_bp);
- } else {
- error = XFS_ERROR(EIO);
- xfs_da_brelse(*trans, child_bp);
- }
- if (error)
- return(error);
-
- /*
- * Remove the subsidiary block from the cache
- * and from the log.
- */
- error = xfs_da_get_buf(*trans, dp, 0, child_blkno,
- &child_bp, XFS_ATTR_FORK);
- if (error)
- return(error);
- xfs_da_binval(*trans, child_bp);
- }
-
- /*
- * If we're not done, re-read the parent to get the next
- * child block number.
- */
- if ((i+1) < count) {
- error = xfs_da_read_buf(*trans, dp, 0, parent_blkno,
- &bp, XFS_ATTR_FORK);
- if (error)
- return(error);
- child_fsb = be32_to_cpu(node->btree[i+1].before);
- xfs_da_brelse(*trans, bp);
- }
- /*
- * Atomically commit the whole invalidate stuff.
- */
- if ((error = xfs_attr_rolltrans(trans, dp)))
- return (error);
- }
-
- return(0);
-}
-
-/*
- * Invalidate all of the "remote" value regions pointed to by a particular
- * leaf block.
- * Note that we must release the lock on the buffer so that we are not
- * caught holding something that the logging code wants to flush to disk.
- */
-STATIC int
-xfs_attr_leaf_inactive(xfs_trans_t **trans, xfs_inode_t *dp, xfs_dabuf_t *bp)
-{
- xfs_attr_leafblock_t *leaf;
- xfs_attr_leaf_entry_t *entry;
- xfs_attr_leaf_name_remote_t *name_rmt;
- xfs_attr_inactive_list_t *list, *lp;
- int error, count, size, tmp, i;
-
- leaf = bp->data;
- ASSERT(be16_to_cpu(leaf->hdr.info.magic) == XFS_ATTR_LEAF_MAGIC);
-
- /*
- * Count the number of "remote" value extents.
- */
- count = 0;
- entry = &leaf->entries[0];
- for (i = 0; i < be16_to_cpu(leaf->hdr.count); entry++, i++) {
- if (be16_to_cpu(entry->nameidx) &&
- ((entry->flags & XFS_ATTR_LOCAL) == 0)) {
- name_rmt = XFS_ATTR_LEAF_NAME_REMOTE(leaf, i);
- if (name_rmt->valueblk)
- count++;
- }
- }
-
- /*
- * If there are no "remote" values, we're done.
- */
- if (count == 0) {
- xfs_da_brelse(*trans, bp);
- return(0);
- }
-
- /*
- * Allocate storage for a list of all the "remote" value extents.
- */
- size = count * sizeof(xfs_attr_inactive_list_t);
- list = (xfs_attr_inactive_list_t *)kmem_alloc(size, KM_SLEEP);
-
- /*
- * Identify each of the "remote" value extents.
- */
- lp = list;
- entry = &leaf->entries[0];
- for (i = 0; i < be16_to_cpu(leaf->hdr.count); entry++, i++) {
- if (be16_to_cpu(entry->nameidx) &&
- ((entry->flags & XFS_ATTR_LOCAL) == 0)) {
- name_rmt = XFS_ATTR_LEAF_NAME_REMOTE(leaf, i);
- if (name_rmt->valueblk) {
- lp->valueblk = be32_to_cpu(name_rmt->valueblk);
- lp->valuelen = XFS_B_TO_FSB(dp->i_mount,
- be32_to_cpu(name_rmt->valuelen));
- lp++;
- }
- }
- }
- xfs_da_brelse(*trans, bp); /* unlock for trans. in freextent() */
-
- /*
- * Invalidate each of the "remote" value extents.
- */
- error = 0;
- for (lp = list, i = 0; i < count; i++, lp++) {
- tmp = xfs_attr_leaf_freextent(trans, dp,
- lp->valueblk, lp->valuelen);
-
- if (error == 0)
- error = tmp; /* save only the 1st errno */
- }
-
- kmem_free((xfs_caddr_t)list, size);
- return(error);
-}
-
-/*
- * Look at all the extents for this logical region,
- * invalidate any buffers that are incore/in transactions.
- */
-STATIC int
-xfs_attr_leaf_freextent(xfs_trans_t **trans, xfs_inode_t *dp,
- xfs_dablk_t blkno, int blkcnt)
-{
- xfs_bmbt_irec_t map;
- xfs_dablk_t tblkno;
- int tblkcnt, dblkcnt, nmap, error;
- xfs_daddr_t dblkno;
- xfs_buf_t *bp;
-
- /*
- * Roll through the "value", invalidating the attribute value's
- * blocks.
- */
- tblkno = blkno;
- tblkcnt = blkcnt;
- while (tblkcnt > 0) {
- /*
- * Try to remember where we decided to put the value.
- */
- nmap = 1;
- error = xfs_bmapi(*trans, dp, (xfs_fileoff_t)tblkno, tblkcnt,
- XFS_BMAPI_ATTRFORK | XFS_BMAPI_METADATA,
- NULL, 0, &map, &nmap, NULL, NULL);
- if (error) {
- return(error);
- }
- ASSERT(nmap == 1);
- ASSERT(map.br_startblock != DELAYSTARTBLOCK);
-
- /*
- * If it's a hole, these are already unmapped
- * so there's nothing to invalidate.
- */
- if (map.br_startblock != HOLESTARTBLOCK) {
-
- dblkno = XFS_FSB_TO_DADDR(dp->i_mount,
- map.br_startblock);
- dblkcnt = XFS_FSB_TO_BB(dp->i_mount,
- map.br_blockcount);
- bp = xfs_trans_get_buf(*trans,
- dp->i_mount->m_ddev_targp,
- dblkno, dblkcnt, XFS_BUF_LOCK);
- xfs_trans_binval(*trans, bp);
- /*
- * Roll to next transaction.
- */
- if ((error = xfs_attr_rolltrans(trans, dp)))
- return (error);
- }
-
- tblkno += map.br_blockcount;
- tblkcnt -= map.br_blockcount;
- }
-
- return(0);
-}
-
-
-/*
- * Roll from one trans in the sequence of PERMANENT transactions to the next.
- */
-int
-xfs_attr_rolltrans(xfs_trans_t **transp, xfs_inode_t *dp)
-{
- xfs_trans_t *trans;
- unsigned int logres, count;
- int error;
-
- /*
- * Ensure that the inode is always logged.
- */
- trans = *transp;
- xfs_trans_log_inode(trans, dp, XFS_ILOG_CORE);
-
- /*
- * Copy the critical parameters from one trans to the next.
- */
- logres = trans->t_log_res;
- count = trans->t_log_count;
- *transp = xfs_trans_dup(trans);
-
- /*
- * Commit the current transaction.
- * If this commit failed, then it'd just unlock those items that
- * are not marked ihold. That also means that a filesystem shutdown
- * is in progress. The caller takes the responsibility to cancel
- * the duplicate transaction that gets returned.
- */
- if ((error = xfs_trans_commit(trans, 0, NULL)))
- return (error);
-
- trans = *transp;
-
- /*
- * Reserve space in the log for th next transaction.
- * This also pushes items in the "AIL", the list of logged items,
- * out to disk if they are taking up space at the tail of the log
- * that we want to use. This requires that either nothing be locked
- * across this call, or that anything that is locked be logged in
- * the prior and the next transactions.
- */
- error = xfs_trans_reserve(trans, 0, logres, 0,
- XFS_TRANS_PERM_LOG_RES, count);
- /*
- * Ensure that the inode is in the new transaction and locked.
- */
- if (!error) {
- xfs_trans_ijoin(trans, dp, XFS_ILOCK_EXCL);
- xfs_trans_ihold(trans, dp);
- }
- return (error);
-
-}
diff --git a/sys/gnu/fs/xfs/xfs_attr_leaf.h b/sys/gnu/fs/xfs/xfs_attr_leaf.h
deleted file mode 100644
index 8b8e3a8..0000000
--- a/sys/gnu/fs/xfs/xfs_attr_leaf.h
+++ /dev/null
@@ -1,282 +0,0 @@
-/*
- * Copyright (c) 2000,2002-2003,2005 Silicon Graphics, Inc.
- * All Rights Reserved.
- *
- * 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.
- *
- * This program is distributed in the hope that it would 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 the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- */
-#ifndef __XFS_ATTR_LEAF_H__
-#define __XFS_ATTR_LEAF_H__
-
-/*
- * Attribute storage layout, internal structure, access macros, etc.
- *
- * Attribute lists are structured around Btrees where all the data
- * elements are in the leaf nodes. Attribute names are hashed into an int,
- * then that int is used as the index into the Btree. Since the hashval
- * of an attribute name may not be unique, we may have duplicate keys. The
- * internal links in the Btree are logical block offsets into the file.
- */
-
-struct attrlist;
-struct attrlist_cursor_kern;
-struct attrnames;
-struct xfs_dabuf;
-struct xfs_da_args;
-struct xfs_da_state;
-struct xfs_da_state_blk;
-struct xfs_inode;
-struct xfs_trans;
-
-/*========================================================================
- * Attribute structure when equal to XFS_LBSIZE(mp) bytes.
- *========================================================================*/
-
-/*
- * This is the structure of the leaf nodes in the Btree.
- *
- * Struct leaf_entry's are packed from the top. Name/values grow from the
- * bottom but are not packed. The freemap contains run-length-encoded entries
- * for the free bytes after the leaf_entry's, but only the N largest such,
- * smaller runs are dropped. When the freemap doesn't show enough space
- * for an allocation, we compact the name/value area and try again. If we
- * still don't have enough space, then we have to split the block. The
- * name/value structs (both local and remote versions) must be 32bit aligned.
- *
- * Since we have duplicate hash keys, for each key that matches, compare
- * the actual name string. The root and intermediate node search always
- * takes the first-in-the-block key match found, so we should only have
- * to work "forw"ard. If none matches, continue with the "forw"ard leaf
- * nodes until the hash key changes or the attribute name is found.
- *
- * We store the fact that an attribute is a ROOT/USER/SECURE attribute in
- * the leaf_entry. The namespaces are independent only because we also look
- * at the namespace bit when we are looking for a matching attribute name.
- *
- * We also store an "incomplete" bit in the leaf_entry. It shows that an
- * attribute is in the middle of being created and should not be shown to
- * the user if we crash during the time that the bit is set. We clear the
- * bit when we have finished setting up the attribute. We do this because
- * we cannot create some large attributes inside a single transaction, and we
- * need some indication that we weren't finished if we crash in the middle.
- */
-#define XFS_ATTR_LEAF_MAPSIZE 3 /* how many freespace slots */
-
-typedef struct xfs_attr_leaf_map { /* RLE map of free bytes */
- __be16 base; /* base of free region */
- __be16 size; /* length of free region */
-} xfs_attr_leaf_map_t;
-
-typedef struct xfs_attr_leaf_hdr { /* constant-structure header block */
- xfs_da_blkinfo_t info; /* block type, links, etc. */
- __be16 count; /* count of active leaf_entry's */
- __be16 usedbytes; /* num bytes of names/values stored */
- __be16 firstused; /* first used byte in name area */
- __u8 holes; /* != 0 if blk needs compaction */
- __u8 pad1;
- xfs_attr_leaf_map_t freemap[XFS_ATTR_LEAF_MAPSIZE];
- /* N largest free regions */
-} xfs_attr_leaf_hdr_t;
-
-typedef struct xfs_attr_leaf_entry { /* sorted on key, not name */
- __be32 hashval; /* hash value of name */
- __be16 nameidx; /* index into buffer of name/value */
- __u8 flags; /* LOCAL/ROOT/SECURE/INCOMPLETE flag */
- __u8 pad2; /* unused pad byte */
-} xfs_attr_leaf_entry_t;
-
-typedef struct xfs_attr_leaf_name_local {
- __be16 valuelen; /* number of bytes in value */
- __u8 namelen; /* length of name bytes */
- __u8 nameval[1]; /* name/value bytes */
-} xfs_attr_leaf_name_local_t;
-
-typedef struct xfs_attr_leaf_name_remote {
- __be32 valueblk; /* block number of value bytes */
- __be32 valuelen; /* number of bytes in value */
- __u8 namelen; /* length of name bytes */
- __u8 name[1]; /* name bytes */
-} xfs_attr_leaf_name_remote_t;
-
-typedef struct xfs_attr_leafblock {
- xfs_attr_leaf_hdr_t hdr; /* constant-structure header block */
- xfs_attr_leaf_entry_t entries[1]; /* sorted on key, not name */
- xfs_attr_leaf_name_local_t namelist; /* grows from bottom of buf */
- xfs_attr_leaf_name_remote_t valuelist; /* grows from bottom of buf */
-} xfs_attr_leafblock_t;
-
-/*
- * Flags used in the leaf_entry[i].flags field.
- * NOTE: the INCOMPLETE bit must not collide with the flags bits specified
- * on the system call, they are "or"ed together for various operations.
- */
-#define XFS_ATTR_LOCAL_BIT 0 /* attr is stored locally */
-#define XFS_ATTR_ROOT_BIT 1 /* limit access to trusted attrs */
-#define XFS_ATTR_SECURE_BIT 2 /* limit access to secure attrs */
-#define XFS_ATTR_INCOMPLETE_BIT 7 /* attr in middle of create/delete */
-#define XFS_ATTR_LOCAL (1 << XFS_ATTR_LOCAL_BIT)
-#define XFS_ATTR_ROOT (1 << XFS_ATTR_ROOT_BIT)
-#define XFS_ATTR_SECURE (1 << XFS_ATTR_SECURE_BIT)
-#define XFS_ATTR_INCOMPLETE (1 << XFS_ATTR_INCOMPLETE_BIT)
-
-/*
- * Alignment for namelist and valuelist entries (since they are mixed
- * there can be only one alignment value)
- */
-#define XFS_ATTR_LEAF_NAME_ALIGN ((uint)sizeof(xfs_dablk_t))
-
-/*
- * Cast typed pointers for "local" and "remote" name/value structs.
- */
-#define XFS_ATTR_LEAF_NAME_REMOTE(leafp,idx) \
- xfs_attr_leaf_name_remote(leafp,idx)
-static inline xfs_attr_leaf_name_remote_t *
-xfs_attr_leaf_name_remote(xfs_attr_leafblock_t *leafp, int idx)
-{
- return (xfs_attr_leaf_name_remote_t *)
- &((char *)leafp)[be16_to_cpu(leafp->entries[idx].nameidx)];
-}
-
-#define XFS_ATTR_LEAF_NAME_LOCAL(leafp,idx) \
- xfs_attr_leaf_name_local(leafp,idx)
-static inline xfs_attr_leaf_name_local_t *
-xfs_attr_leaf_name_local(xfs_attr_leafblock_t *leafp, int idx)
-{
- return (xfs_attr_leaf_name_local_t *)
- &((char *)leafp)[be16_to_cpu(leafp->entries[idx].nameidx)];
-}
-
-#define XFS_ATTR_LEAF_NAME(leafp,idx) \
- xfs_attr_leaf_name(leafp,idx)
-static inline char *xfs_attr_leaf_name(xfs_attr_leafblock_t *leafp, int idx)
-{
- return &((char *)leafp)[be16_to_cpu(leafp->entries[idx].nameidx)];
-}
-
-/*
- * Calculate total bytes used (including trailing pad for alignment) for
- * a "local" name/value structure, a "remote" name/value structure, and
- * a pointer which might be either.
- */
-#define XFS_ATTR_LEAF_ENTSIZE_REMOTE(nlen) \
- xfs_attr_leaf_entsize_remote(nlen)
-static inline int xfs_attr_leaf_entsize_remote(int nlen)
-{
- return ((uint)sizeof(xfs_attr_leaf_name_remote_t) - 1 + (nlen) + \
- XFS_ATTR_LEAF_NAME_ALIGN - 1) & ~(XFS_ATTR_LEAF_NAME_ALIGN - 1);
-}
-
-#define XFS_ATTR_LEAF_ENTSIZE_LOCAL(nlen,vlen) \
- xfs_attr_leaf_entsize_local(nlen,vlen)
-static inline int xfs_attr_leaf_entsize_local(int nlen, int vlen)
-{
- return ((uint)sizeof(xfs_attr_leaf_name_local_t) - 1 + (nlen) + (vlen) +
- XFS_ATTR_LEAF_NAME_ALIGN - 1) & ~(XFS_ATTR_LEAF_NAME_ALIGN - 1);
-}
-
-#define XFS_ATTR_LEAF_ENTSIZE_LOCAL_MAX(bsize) \
- xfs_attr_leaf_entsize_local_max(bsize)
-static inline int xfs_attr_leaf_entsize_local_max(int bsize)
-{
- return (((bsize) >> 1) + ((bsize) >> 2));
-}
-
-
-/*========================================================================
- * Structure used to pass context around among the routines.
- *========================================================================*/
-
-typedef struct xfs_attr_list_context {
- struct xfs_inode *dp; /* inode */
- struct attrlist_cursor_kern *cursor;/* position in list */
- struct attrlist *alist; /* output buffer */
- int count; /* num used entries */
- int dupcnt; /* count dup hashvals seen */
- int bufsize;/* total buffer size */
- int firstu; /* first used byte in buffer */
- int flags; /* from VOP call */
- int resynch;/* T/F: resynch with cursor */
-} xfs_attr_list_context_t;
-
-/*
- * Used to keep a list of "remote value" extents when unlinking an inode.
- */
-typedef struct xfs_attr_inactive_list {
- xfs_dablk_t valueblk; /* block number of value bytes */
- int valuelen; /* number of bytes in value */
-} xfs_attr_inactive_list_t;
-
-
-/*========================================================================
- * Function prototypes for the kernel.
- *========================================================================*/
-
-/*
- * Internal routines when attribute fork size < XFS_LITINO(mp).
- */
-void xfs_attr_shortform_create(struct xfs_da_args *args);
-void xfs_attr_shortform_add(struct xfs_da_args *args, int forkoff);
-int xfs_attr_shortform_lookup(struct xfs_da_args *args);
-int xfs_attr_shortform_to_leaf(struct xfs_da_args *args);
-int xfs_attr_shortform_remove(struct xfs_da_args *args);
-int xfs_attr_shortform_list(struct xfs_attr_list_context *context);
-int xfs_attr_shortform_allfit(struct xfs_dabuf *bp, struct xfs_inode *dp);
-int xfs_attr_shortform_bytesfit(xfs_inode_t *dp, int bytes);
-
-
-/*
- * Internal routines when attribute fork size == XFS_LBSIZE(mp).
- */
-int xfs_attr_leaf_to_node(struct xfs_da_args *args);
-int xfs_attr_leaf_to_shortform(struct xfs_dabuf *bp,
- struct xfs_da_args *args, int forkoff);
-int xfs_attr_leaf_clearflag(struct xfs_da_args *args);
-int xfs_attr_leaf_setflag(struct xfs_da_args *args);
-int xfs_attr_leaf_flipflags(xfs_da_args_t *args);
-
-/*
- * Routines used for growing the Btree.
- */
-int xfs_attr_leaf_split(struct xfs_da_state *state,
- struct xfs_da_state_blk *oldblk,
- struct xfs_da_state_blk *newblk);
-int xfs_attr_leaf_lookup_int(struct xfs_dabuf *leaf,
- struct xfs_da_args *args);
-int xfs_attr_leaf_getvalue(struct xfs_dabuf *bp, struct xfs_da_args *args);
-int xfs_attr_leaf_add(struct xfs_dabuf *leaf_buffer,
- struct xfs_da_args *args);
-int xfs_attr_leaf_remove(struct xfs_dabuf *leaf_buffer,
- struct xfs_da_args *args);
-int xfs_attr_leaf_list_int(struct xfs_dabuf *bp,
- struct xfs_attr_list_context *context);
-
-/*
- * Routines used for shrinking the Btree.
- */
-int xfs_attr_leaf_toosmall(struct xfs_da_state *state, int *retval);
-void xfs_attr_leaf_unbalance(struct xfs_da_state *state,
- struct xfs_da_state_blk *drop_blk,
- struct xfs_da_state_blk *save_blk);
-int xfs_attr_root_inactive(struct xfs_trans **trans, struct xfs_inode *dp);
-
-/*
- * Utility routines.
- */
-xfs_dahash_t xfs_attr_leaf_lasthash(struct xfs_dabuf *bp, int *count);
-int xfs_attr_leaf_order(struct xfs_dabuf *leaf1_bp,
- struct xfs_dabuf *leaf2_bp);
-int xfs_attr_leaf_newentsize(int namelen, int valuelen, int blocksize,
- int *local);
-int xfs_attr_rolltrans(struct xfs_trans **transp, struct xfs_inode *dp);
-
-#endif /* __XFS_ATTR_LEAF_H__ */
diff --git a/sys/gnu/fs/xfs/xfs_attr_sf.h b/sys/gnu/fs/xfs/xfs_attr_sf.h
deleted file mode 100644
index f67f917..0000000
--- a/sys/gnu/fs/xfs/xfs_attr_sf.h
+++ /dev/null
@@ -1,114 +0,0 @@
-/*
- * Copyright (c) 2000,2002,2005 Silicon Graphics, Inc.
- * All Rights Reserved.
- *
- * 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.
- *
- * This program is distributed in the hope that it would 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 the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- */
-#ifndef __XFS_ATTR_SF_H__
-#define __XFS_ATTR_SF_H__
-
-/*
- * Attribute storage when stored inside the inode.
- *
- * Small attribute lists are packed as tightly as possible so as
- * to fit into the literal area of the inode.
- */
-
-struct xfs_inode;
-
-/*
- * Entries are packed toward the top as tight as possible.
- */
-typedef struct xfs_attr_shortform {
- struct xfs_attr_sf_hdr { /* constant-structure header block */
- __be16 totsize; /* total bytes in shortform list */
- __u8 count; /* count of active entries */
- } hdr;
- struct xfs_attr_sf_entry {
- __uint8_t namelen; /* actual length of name (no NULL) */
- __uint8_t valuelen; /* actual length of value (no NULL) */
- __uint8_t flags; /* flags bits (see xfs_attr_leaf.h) */
- __uint8_t nameval[1]; /* name & value bytes concatenated */
- } list[1]; /* variable sized array */
-} xfs_attr_shortform_t;
-typedef struct xfs_attr_sf_hdr xfs_attr_sf_hdr_t;
-typedef struct xfs_attr_sf_entry xfs_attr_sf_entry_t;
-
-/*
- * We generate this then sort it, attr_list() must return things in hash-order.
- */
-typedef struct xfs_attr_sf_sort {
- __uint8_t entno; /* entry number in original list */
- __uint8_t namelen; /* length of name value (no null) */
- __uint8_t valuelen; /* length of value */
- __uint8_t flags; /* flags bits (see xfs_attr_leaf.h) */
- xfs_dahash_t hash; /* this entry's hash value */
- char *name; /* name value, pointer into buffer */
-} xfs_attr_sf_sort_t;
-
-#define XFS_ATTR_SF_ENTSIZE_BYNAME(nlen,vlen) /* space name/value uses */ \
- (((int)sizeof(xfs_attr_sf_entry_t)-1 + (nlen)+(vlen)))
-#define XFS_ATTR_SF_ENTSIZE_MAX /* max space for name&value */ \
- ((1 << (NBBY*(int)sizeof(__uint8_t))) - 1)
-#define XFS_ATTR_SF_ENTSIZE(sfep) /* space an entry uses */ \
- ((int)sizeof(xfs_attr_sf_entry_t)-1 + (sfep)->namelen+(sfep)->valuelen)
-#define XFS_ATTR_SF_NEXTENTRY(sfep) /* next entry in struct */ \
- ((xfs_attr_sf_entry_t *)((char *)(sfep) + XFS_ATTR_SF_ENTSIZE(sfep)))
-#define XFS_ATTR_SF_TOTSIZE(dp) /* total space in use */ \
- (be16_to_cpu(((xfs_attr_shortform_t *) \
- ((dp)->i_afp->if_u1.if_data))->hdr.totsize))
-
-#if defined(XFS_ATTR_TRACE)
-/*
- * Kernel tracing support for attribute lists
- */
-struct xfs_attr_list_context;
-struct xfs_da_intnode;
-struct xfs_da_node_entry;
-struct xfs_attr_leafblock;
-
-#define XFS_ATTR_TRACE_SIZE 4096 /* size of global trace buffer */
-extern ktrace_t *xfs_attr_trace_buf;
-
-/*
- * Trace record types.
- */
-#define XFS_ATTR_KTRACE_L_C 1 /* context */
-#define XFS_ATTR_KTRACE_L_CN 2 /* context, node */
-#define XFS_ATTR_KTRACE_L_CB 3 /* context, btree */
-#define XFS_ATTR_KTRACE_L_CL 4 /* context, leaf */
-
-void xfs_attr_trace_l_c(char *where, struct xfs_attr_list_context *context);
-void xfs_attr_trace_l_cn(char *where, struct xfs_attr_list_context *context,
- struct xfs_da_intnode *node);
-void xfs_attr_trace_l_cb(char *where, struct xfs_attr_list_context *context,
- struct xfs_da_node_entry *btree);
-void xfs_attr_trace_l_cl(char *where, struct xfs_attr_list_context *context,
- struct xfs_attr_leafblock *leaf);
-void xfs_attr_trace_enter(int type, char *where,
- __psunsigned_t a2, __psunsigned_t a3,
- __psunsigned_t a4, __psunsigned_t a5,
- __psunsigned_t a6, __psunsigned_t a7,
- __psunsigned_t a8, __psunsigned_t a9,
- __psunsigned_t a10, __psunsigned_t a11,
- __psunsigned_t a12, __psunsigned_t a13,
- __psunsigned_t a14, __psunsigned_t a15);
-#else
-#define xfs_attr_trace_l_c(w,c)
-#define xfs_attr_trace_l_cn(w,c,n)
-#define xfs_attr_trace_l_cb(w,c,b)
-#define xfs_attr_trace_l_cl(w,c,l)
-#endif /* XFS_ATTR_TRACE */
-
-#endif /* __XFS_ATTR_SF_H__ */
diff --git a/sys/gnu/fs/xfs/xfs_behavior.c b/sys/gnu/fs/xfs/xfs_behavior.c
deleted file mode 100644
index f4fe371..0000000
--- a/sys/gnu/fs/xfs/xfs_behavior.c
+++ /dev/null
@@ -1,203 +0,0 @@
-/*
- * Copyright (c) 2000-2003,2005 Silicon Graphics, Inc.
- * All Rights Reserved.
- *
- * 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.
- *
- * This program is distributed in the hope that it would 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 the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- */
-#include "xfs.h"
-
-/*
- * Source file used to associate/disassociate behaviors with virtualized
- * objects. See xfs_behavior.h for more information about behaviors, etc.
- *
- * The implementation is split between functions in this file and macros
- * in xfs_behavior.h.
- */
-
-/*
- * Insert a new behavior descriptor into a behavior chain.
- *
- * The behavior chain is ordered based on the 'position' number which
- * lives in the first field of the ops vector (higher numbers first).
- *
- * Attempts to insert duplicate ops result in an EINVAL return code.
- * Otherwise, return 0 to indicate success.
- */
-int
-bhv_insert(bhv_head_t *bhp, bhv_desc_t *bdp)
-{
- bhv_desc_t *curdesc, *prev;
- int position;
-
- /*
- * Validate the position value of the new behavior.
- */
- position = BHV_POSITION(bdp);
- ASSERT(position >= BHV_POSITION_BASE && position <= BHV_POSITION_TOP);
-
- /*
- * Find location to insert behavior. Check for duplicates.
- */
- prev = NULL;
- for (curdesc = bhp->bh_first;
- curdesc != NULL;
- curdesc = curdesc->bd_next) {
-
- /* Check for duplication. */
- if (curdesc->bd_ops == bdp->bd_ops) {
- ASSERT(0);
- return EINVAL;
- }
-
- /* Find correct position */
- if (position >= BHV_POSITION(curdesc)) {
- ASSERT(position != BHV_POSITION(curdesc));
- break; /* found it */
- }
-
- prev = curdesc;
- }
-
- if (prev == NULL) {
- /* insert at front of chain */
- bdp->bd_next = bhp->bh_first;
- bhp->bh_first = bdp;
- } else {
- /* insert after prev */
- bdp->bd_next = prev->bd_next;
- prev->bd_next = bdp;
- }
-
- return 0;
-}
-
-/*
- * Remove a behavior descriptor from a position in a behavior chain;
- * the position is guaranteed not to be the first position.
- * Should only be called by the bhv_remove() macro.
- */
-void
-bhv_remove_not_first(bhv_head_t *bhp, bhv_desc_t *bdp)
-{
- bhv_desc_t *curdesc, *prev;
-
- ASSERT(bhp->bh_first != NULL);
- ASSERT(bhp->bh_first->bd_next != NULL);
-
- prev = bhp->bh_first;
- for (curdesc = bhp->bh_first->bd_next;
- curdesc != NULL;
- curdesc = curdesc->bd_next) {
-
- if (curdesc == bdp)
- break; /* found it */
- prev = curdesc;
- }
-
- ASSERT(curdesc == bdp);
- prev->bd_next = bdp->bd_next; /* remove from after prev */
-}
-
-/*
- * Look for a specific ops vector on the specified behavior chain.
- * Return the associated behavior descriptor. Or NULL, if not found.
- */
-bhv_desc_t *
-bhv_lookup(bhv_head_t *bhp, void *ops)
-{
- bhv_desc_t *curdesc;
-
- for (curdesc = bhp->bh_first;
- curdesc != NULL;
- curdesc = curdesc->bd_next) {
-
- if (curdesc->bd_ops == ops)
- return curdesc;
- }
-
- return NULL;
-}
-
-/*
- * Looks for the first behavior within a specified range of positions.
- * Return the associated behavior descriptor. Or NULL, if none found.
- */
-bhv_desc_t *
-bhv_lookup_range(bhv_head_t *bhp, int low, int high)
-{
- bhv_desc_t *curdesc;
-
- for (curdesc = bhp->bh_first;
- curdesc != NULL;
- curdesc = curdesc->bd_next) {
-
- int position = BHV_POSITION(curdesc);
-
- if (position <= high) {
- if (position >= low)
- return curdesc;
- return NULL;
- }
- }
-
- return NULL;
-}
-
-/*
- * Return the base behavior in the chain, or NULL if the chain
- * is empty.
- *
- * The caller has not read locked the behavior chain, so acquire the
- * lock before traversing the chain.
- */
-bhv_desc_t *
-bhv_base(bhv_head_t *bhp)
-{
- bhv_desc_t *curdesc;
-
- for (curdesc = bhp->bh_first;
- curdesc != NULL;
- curdesc = curdesc->bd_next) {
-
- if (curdesc->bd_next == NULL) {
- return curdesc;
- }
- }
-
- return NULL;
-}
-
-void
-bhv_head_init(
- bhv_head_t *bhp,
- char *name)
-{
- bhp->bh_first = NULL;
-}
-
-void
-bhv_insert_initial(
- bhv_head_t *bhp,
- bhv_desc_t *bdp)
-{
- ASSERT(bhp->bh_first == NULL);
- (bhp)->bh_first = bdp;
-}
-
-void
-bhv_head_destroy(
- bhv_head_t *bhp)
-{
- ASSERT(bhp->bh_first == NULL);
-}
diff --git a/sys/gnu/fs/xfs/xfs_behavior.h b/sys/gnu/fs/xfs/xfs_behavior.h
deleted file mode 100644
index 1d8ff10..0000000
--- a/sys/gnu/fs/xfs/xfs_behavior.h
+++ /dev/null
@@ -1,190 +0,0 @@
-/*
- * Copyright (c) 2000-2003,2005 Silicon Graphics, Inc.
- * All Rights Reserved.
- *
- * 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.
- *
- * This program is distributed in the hope that it would 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 the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- */
-#ifndef __XFS_BEHAVIOR_H__
-#define __XFS_BEHAVIOR_H__
-
-/*
- * Header file used to associate behaviors with virtualized objects.
- *
- * A virtualized object is an internal, virtualized representation of
- * OS entities such as persistent files, processes, or sockets. Examples
- * of virtualized objects include vnodes, vprocs, and vsockets. Often
- * a virtualized object is referred to simply as an "object."
- *
- * A behavior is essentially an implementation layer associated with
- * an object. Multiple behaviors for an object are chained together,
- * the order of chaining determining the order of invocation. Each
- * behavior of a given object implements the same set of interfaces
- * (e.g., the VOP interfaces).
- *
- * Behaviors may be dynamically inserted into an object's behavior chain,
- * such that the addition is transparent to consumers that already have
- * references to the object. Typically, a given behavior will be inserted
- * at a particular location in the behavior chain. Insertion of new
- * behaviors is synchronized with operations-in-progress (oip's) so that
- * the oip's always see a consistent view of the chain.
- *
- * The term "interposition" is used to refer to the act of inserting
- * a behavior such that it interposes on (i.e., is inserted in front
- * of) a particular other behavior. A key example of this is when a
- * system implementing distributed single system image wishes to
- * interpose a distribution layer (providing distributed coherency)
- * in front of an object that is otherwise only accessed locally.
- *
- * Note that the traditional vnode/inode combination is simply a virtualized
- * object that has exactly one associated behavior.
- *
- * Behavior synchronization is logic which is necessary under certain
- * circumstances that there is no conflict between ongoing operations
- * traversing the behavior chain and those dynamically modifying the
- * behavior chain. Because behavior synchronization adds extra overhead
- * to virtual operation invocation, we want to restrict, as much as
- * we can, the requirement for this extra code, to those situations
- * in which it is truly necessary.
- *
- * Behavior synchronization is needed whenever there's at least one class
- * of object in the system for which:
- * 1) multiple behaviors for a given object are supported,
- * -- AND --
- * 2a) insertion of a new behavior can happen dynamically at any time during
- * the life of an active object,
- * -- AND --
- * 3a) insertion of a new behavior needs to synchronize with existing
- * ops-in-progress.
- * -- OR --
- * 3b) multiple different behaviors can be dynamically inserted at
- * any time during the life of an active object
- * -- OR --
- * 3c) removal of a behavior can occur at any time during the life of
- * an active object.
- * -- OR --
- * 2b) removal of a behavior can occur at any time during the life of an
- * active object
- *
- */
-
-struct bhv_head_lock;
-
-/*
- * Behavior head. Head of the chain of behaviors.
- * Contained within each virtualized object data structure.
- */
-typedef struct bhv_head {
- struct bhv_desc *bh_first; /* first behavior in chain */
- struct bhv_head_lock *bh_lockp; /* pointer to lock info struct */
-} bhv_head_t;
-
-/*
- * Behavior descriptor. Descriptor associated with each behavior.
- * Contained within the behavior's private data structure.
- */
-typedef struct bhv_desc {
- void *bd_pdata; /* private data for this behavior */
- void *bd_vobj; /* virtual object associated with */
- void *bd_ops; /* ops for this behavior */
- struct bhv_desc *bd_next; /* next behavior in chain */
-} bhv_desc_t;
-
-/*
- * Behavior identity field. A behavior's identity determines the position
- * where it lives within a behavior chain, and it's always the first field
- * of the behavior's ops vector. The optional id field further identifies the
- * subsystem responsible for the behavior.
- */
-typedef struct bhv_identity {
- __u16 bi_id; /* owning subsystem id */
- __u16 bi_position; /* position in chain */
-} bhv_identity_t;
-
-typedef bhv_identity_t bhv_position_t;
-
-#define BHV_IDENTITY_INIT(id,pos) {id, pos}
-#define BHV_IDENTITY_INIT_POSITION(pos) BHV_IDENTITY_INIT(0, pos)
-
-/*
- * Define boundaries of position values.
- */
-#define BHV_POSITION_INVALID 0 /* invalid position number */
-#define BHV_POSITION_BASE 1 /* base (last) implementation layer */
-#define BHV_POSITION_TOP 63 /* top (first) implementation layer */
-
-/*
- * Plumbing macros.
- */
-#define BHV_HEAD_FIRST(bhp) (ASSERT((bhp)->bh_first), (bhp)->bh_first)
-#define BHV_NEXT(bdp) (ASSERT((bdp)->bd_next), (bdp)->bd_next)
-#define BHV_NEXTNULL(bdp) ((bdp)->bd_next)
-#define BHV_VOBJ(bdp) (ASSERT((bdp)->bd_vobj), (bdp)->bd_vobj)
-#define BHV_VOBJNULL(bdp) ((bdp)->bd_vobj)
-#define BHV_PDATA(bdp) (bdp)->bd_pdata
-#define BHV_OPS(bdp) (bdp)->bd_ops
-#define BHV_IDENTITY(bdp) ((bhv_identity_t *)(bdp)->bd_ops)
-#define BHV_POSITION(bdp) (BHV_IDENTITY(bdp)->bi_position)
-
-extern void bhv_head_init(bhv_head_t *, char *);
-extern void bhv_head_destroy(bhv_head_t *);
-extern int bhv_insert(bhv_head_t *, bhv_desc_t *);
-extern void bhv_insert_initial(bhv_head_t *, bhv_desc_t *);
-
-/*
- * Initialize a new behavior descriptor.
- * Arguments:
- * bdp - pointer to behavior descriptor
- * pdata - pointer to behavior's private data
- * vobj - pointer to associated virtual object
- * ops - pointer to ops for this behavior
- */
-#define bhv_desc_init(bdp, pdata, vobj, ops) \
- { \
- (bdp)->bd_pdata = pdata; \
- (bdp)->bd_vobj = vobj; \
- (bdp)->bd_ops = ops; \
- (bdp)->bd_next = NULL; \
- }
-
-/*
- * Remove a behavior descriptor from a behavior chain.
- */
-#define bhv_remove(bhp, bdp) \
- { \
- if ((bhp)->bh_first == (bdp)) { \
- /* \
- * Remove from front of chain. \
- * Atomic wrt oip's. \
- */ \
- (bhp)->bh_first = (bdp)->bd_next; \
- } else { \
- /* remove from non-front of chain */ \
- bhv_remove_not_first(bhp, bdp); \
- } \
- (bdp)->bd_vobj = NULL; \
- }
-
-/*
- * Behavior module prototypes.
- */
-extern void bhv_remove_not_first(bhv_head_t *bhp, bhv_desc_t *bdp);
-extern bhv_desc_t * bhv_lookup(bhv_head_t *bhp, void *ops);
-extern bhv_desc_t * bhv_lookup_range(bhv_head_t *bhp, int low, int high);
-extern bhv_desc_t * bhv_base(bhv_head_t *bhp);
-
-/* No bhv locking on Linux */
-#define bhv_lookup_unlocked bhv_lookup
-#define bhv_base_unlocked bhv_base
-
-#endif /* __XFS_BEHAVIOR_H__ */
diff --git a/sys/gnu/fs/xfs/xfs_bit.c b/sys/gnu/fs/xfs/xfs_bit.c
deleted file mode 100644
index 8b2d8f5..0000000
--- a/sys/gnu/fs/xfs/xfs_bit.c
+++ /dev/null
@@ -1,296 +0,0 @@
-/*
- * Copyright (c) 2000-2005 Silicon Graphics, Inc.
- * All Rights Reserved.
- *
- * 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.
- *
- * This program is distributed in the hope that it would 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 the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- */
-#include "xfs.h"
-#include "xfs_bit.h"
-#include "xfs_log.h"
-#include "xfs_trans.h"
-#include "xfs_buf_item.h"
-
-/*
- * XFS bit manipulation routines, used in non-realtime code.
- */
-
-#ifndef HAVE_ARCH_HIGHBIT
-/*
- * Index of high bit number in byte, -1 for none set, 0..7 otherwise.
- */
-STATIC const char xfs_highbit[256] = {
- -1, 0, 1, 1, 2, 2, 2, 2, /* 00 .. 07 */
- 3, 3, 3, 3, 3, 3, 3, 3, /* 08 .. 0f */
- 4, 4, 4, 4, 4, 4, 4, 4, /* 10 .. 17 */
- 4, 4, 4, 4, 4, 4, 4, 4, /* 18 .. 1f */
- 5, 5, 5, 5, 5, 5, 5, 5, /* 20 .. 27 */
- 5, 5, 5, 5, 5, 5, 5, 5, /* 28 .. 2f */
- 5, 5, 5, 5, 5, 5, 5, 5, /* 30 .. 37 */
- 5, 5, 5, 5, 5, 5, 5, 5, /* 38 .. 3f */
- 6, 6, 6, 6, 6, 6, 6, 6, /* 40 .. 47 */
- 6, 6, 6, 6, 6, 6, 6, 6, /* 48 .. 4f */
- 6, 6, 6, 6, 6, 6, 6, 6, /* 50 .. 57 */
- 6, 6, 6, 6, 6, 6, 6, 6, /* 58 .. 5f */
- 6, 6, 6, 6, 6, 6, 6, 6, /* 60 .. 67 */
- 6, 6, 6, 6, 6, 6, 6, 6, /* 68 .. 6f */
- 6, 6, 6, 6, 6, 6, 6, 6, /* 70 .. 77 */
- 6, 6, 6, 6, 6, 6, 6, 6, /* 78 .. 7f */
- 7, 7, 7, 7, 7, 7, 7, 7, /* 80 .. 87 */
- 7, 7, 7, 7, 7, 7, 7, 7, /* 88 .. 8f */
- 7, 7, 7, 7, 7, 7, 7, 7, /* 90 .. 97 */
- 7, 7, 7, 7, 7, 7, 7, 7, /* 98 .. 9f */
- 7, 7, 7, 7, 7, 7, 7, 7, /* a0 .. a7 */
- 7, 7, 7, 7, 7, 7, 7, 7, /* a8 .. af */
- 7, 7, 7, 7, 7, 7, 7, 7, /* b0 .. b7 */
- 7, 7, 7, 7, 7, 7, 7, 7, /* b8 .. bf */
- 7, 7, 7, 7, 7, 7, 7, 7, /* c0 .. c7 */
- 7, 7, 7, 7, 7, 7, 7, 7, /* c8 .. cf */
- 7, 7, 7, 7, 7, 7, 7, 7, /* d0 .. d7 */
- 7, 7, 7, 7, 7, 7, 7, 7, /* d8 .. df */
- 7, 7, 7, 7, 7, 7, 7, 7, /* e0 .. e7 */
- 7, 7, 7, 7, 7, 7, 7, 7, /* e8 .. ef */
- 7, 7, 7, 7, 7, 7, 7, 7, /* f0 .. f7 */
- 7, 7, 7, 7, 7, 7, 7, 7, /* f8 .. ff */
-};
-#endif
-
-/*
- * Count of bits set in byte, 0..8.
- */
-static const char xfs_countbit[256] = {
- 0, 1, 1, 2, 1, 2, 2, 3, /* 00 .. 07 */
- 1, 2, 2, 3, 2, 3, 3, 4, /* 08 .. 0f */
- 1, 2, 2, 3, 2, 3, 3, 4, /* 10 .. 17 */
- 2, 3, 3, 4, 3, 4, 4, 5, /* 18 .. 1f */
- 1, 2, 2, 3, 2, 3, 3, 4, /* 20 .. 27 */
- 2, 3, 3, 4, 3, 4, 4, 5, /* 28 .. 2f */
- 2, 3, 3, 4, 3, 4, 4, 5, /* 30 .. 37 */
- 3, 4, 4, 5, 4, 5, 5, 6, /* 38 .. 3f */
- 1, 2, 2, 3, 2, 3, 3, 4, /* 40 .. 47 */
- 2, 3, 3, 4, 3, 4, 4, 5, /* 48 .. 4f */
- 2, 3, 3, 4, 3, 4, 4, 5, /* 50 .. 57 */
- 3, 4, 4, 5, 4, 5, 5, 6, /* 58 .. 5f */
- 2, 3, 3, 4, 3, 4, 4, 5, /* 60 .. 67 */
- 3, 4, 4, 5, 4, 5, 5, 6, /* 68 .. 6f */
- 3, 4, 4, 5, 4, 5, 5, 6, /* 70 .. 77 */
- 4, 5, 5, 6, 5, 6, 6, 7, /* 78 .. 7f */
- 1, 2, 2, 3, 2, 3, 3, 4, /* 80 .. 87 */
- 2, 3, 3, 4, 3, 4, 4, 5, /* 88 .. 8f */
- 2, 3, 3, 4, 3, 4, 4, 5, /* 90 .. 97 */
- 3, 4, 4, 5, 4, 5, 5, 6, /* 98 .. 9f */
- 2, 3, 3, 4, 3, 4, 4, 5, /* a0 .. a7 */
- 3, 4, 4, 5, 4, 5, 5, 6, /* a8 .. af */
- 3, 4, 4, 5, 4, 5, 5, 6, /* b0 .. b7 */
- 4, 5, 5, 6, 5, 6, 6, 7, /* b8 .. bf */
- 2, 3, 3, 4, 3, 4, 4, 5, /* c0 .. c7 */
- 3, 4, 4, 5, 4, 5, 5, 6, /* c8 .. cf */
- 3, 4, 4, 5, 4, 5, 5, 6, /* d0 .. d7 */
- 4, 5, 5, 6, 5, 6, 6, 7, /* d8 .. df */
- 3, 4, 4, 5, 4, 5, 5, 6, /* e0 .. e7 */
- 4, 5, 5, 6, 5, 6, 6, 7, /* e8 .. ef */
- 4, 5, 5, 6, 5, 6, 6, 7, /* f0 .. f7 */
- 5, 6, 6, 7, 6, 7, 7, 8, /* f8 .. ff */
-};
-
-/*
- * xfs_highbit32: get high bit set out of 32-bit argument, -1 if none set.
- */
-int
-xfs_highbit32(
- __uint32_t v)
-{
-#ifdef HAVE_ARCH_HIGHBIT
- return highbit32(v);
-#else
- int i;
-
- if (v & 0xffff0000)
- if (v & 0xff000000)
- i = 24;
- else
- i = 16;
- else if (v & 0x0000ffff)
- if (v & 0x0000ff00)
- i = 8;
- else
- i = 0;
- else
- return -1;
- return i + xfs_highbit[(v >> i) & 0xff];
-#endif
-}
-
-/*
- * xfs_lowbit64: get low bit set out of 64-bit argument, -1 if none set.
- */
-int
-xfs_lowbit64(
- __uint64_t v)
-{
- __uint32_t w = (__uint32_t)v;
- int n = 0;
-
- if (w) { /* lower bits */
- n = ffs(w);
- } else { /* upper bits */
- w = (__uint32_t)(v >> 32);
- if (w && (n = ffs(w)))
- n += 32;
- }
- return n - 1;
-}
-
-/*
- * xfs_highbit64: get high bit set out of 64-bit argument, -1 if none set.
- */
-int
-xfs_highbit64(
- __uint64_t v)
-{
- __uint32_t h = (__uint32_t)(v >> 32);
-
- if (h)
- return xfs_highbit32(h) + 32;
- return xfs_highbit32((__uint32_t)v);
-}
-
-
-/*
- * Count the number of bits set in the bitmap starting with bit
- * start_bit. Size is the size of the bitmap in words.
- *
- * Do the counting by mapping a byte value to the number of set
- * bits for that value using the xfs_countbit array, i.e.
- * xfs_countbit[0] == 0, xfs_countbit[1] == 1, xfs_countbit[2] == 1,
- * xfs_countbit[3] == 2, etc.
- */
-int
-xfs_count_bits(uint *map, uint size, uint start_bit)
-{
- register int bits;
- register unsigned char *bytep;
- register unsigned char *end_map;
- int byte_bit;
-
- bits = 0;
- end_map = (char*)(map + size);
- bytep = (char*)(map + (start_bit & ~0x7));
- byte_bit = start_bit & 0x7;
-
- /*
- * If the caller fell off the end of the map, return 0.
- */
- if (bytep >= end_map) {
- return (0);
- }
-
- /*
- * If start_bit is not byte aligned, then process the
- * first byte separately.
- */
- if (byte_bit != 0) {
- /*
- * Shift off the bits we don't want to look at,
- * before indexing into xfs_countbit.
- */
- bits += xfs_countbit[(*bytep >> byte_bit)];
- bytep++;
- }
-
- /*
- * Count the bits in each byte until the end of the bitmap.
- */
- while (bytep < end_map) {
- bits += xfs_countbit[*bytep];
- bytep++;
- }
-
- return (bits);
-}
-
-/*
- * Count the number of contiguous bits set in the bitmap starting with bit
- * start_bit. Size is the size of the bitmap in words.
- */
-int
-xfs_contig_bits(uint *map, uint size, uint start_bit)
-{
- uint * p = ((unsigned int *) map) + (start_bit >> BIT_TO_WORD_SHIFT);
- uint result = 0;
- uint tmp;
-
- size <<= BIT_TO_WORD_SHIFT;
-
- ASSERT(start_bit < size);
- size -= start_bit & ~(NBWORD - 1);
- start_bit &= (NBWORD - 1);
- if (start_bit) {
- tmp = *p++;
- /* set to one first offset bits prior to start */
- tmp |= (~0U >> (NBWORD-start_bit));
- if (tmp != ~0U)
- goto found;
- result += NBWORD;
- size -= NBWORD;
- }
- while (size) {
- if ((tmp = *p++) != ~0U)
- goto found;
- result += NBWORD;
- size -= NBWORD;
- }
- return result - start_bit;
-found:
- return result + ffz(tmp) - start_bit;
-}
-
-/*
- * This takes the bit number to start looking from and
- * returns the next set bit from there. It returns -1
- * if there are no more bits set or the start bit is
- * beyond the end of the bitmap.
- *
- * Size is the number of words, not bytes, in the bitmap.
- */
-int xfs_next_bit(uint *map, uint size, uint start_bit)
-{
- uint * p = ((unsigned int *) map) + (start_bit >> BIT_TO_WORD_SHIFT);
- uint result = start_bit & ~(NBWORD - 1);
- uint tmp;
-
- size <<= BIT_TO_WORD_SHIFT;
-
- if (start_bit >= size)
- return -1;
- size -= result;
- start_bit &= (NBWORD - 1);
- if (start_bit) {
- tmp = *p++;
- /* set to zero first offset bits prior to start */
- tmp &= (~0U << start_bit);
- if (tmp != 0U)
- goto found;
- result += NBWORD;
- size -= NBWORD;
- }
- while (size) {
- if ((tmp = *p++) != 0U)
- goto found;
- result += NBWORD;
- size -= NBWORD;
- }
- return -1;
-found:
- return result + ffs(tmp) - 1;
-}
diff --git a/sys/gnu/fs/xfs/xfs_bit.h b/sys/gnu/fs/xfs/xfs_bit.h
deleted file mode 100644
index 0bbe568..0000000
--- a/sys/gnu/fs/xfs/xfs_bit.h
+++ /dev/null
@@ -1,67 +0,0 @@
-/*
- * Copyright (c) 2000,2002,2005 Silicon Graphics, Inc.
- * All Rights Reserved.
- *
- * 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.
- *
- * This program is distributed in the hope that it would 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 the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- */
-#ifndef __XFS_BIT_H__
-#define __XFS_BIT_H__
-
-/*
- * XFS bit manipulation routines.
- */
-
-/*
- * masks with n high/low bits set, 32-bit values & 64-bit values
- */
-#define XFS_MASK32HI(n) xfs_mask32hi(n)
-static inline __uint32_t xfs_mask32hi(int n)
-{
- return (__uint32_t)-1 << (32 - (n));
-}
-#define XFS_MASK64HI(n) xfs_mask64hi(n)
-static inline __uint64_t xfs_mask64hi(int n)
-{
- return (__uint64_t)-1 << (64 - (n));
-}
-#define XFS_MASK32LO(n) xfs_mask32lo(n)
-static inline __uint32_t xfs_mask32lo(int n)
-{
- return ((__uint32_t)1 << (n)) - 1;
-}
-#define XFS_MASK64LO(n) xfs_mask64lo(n)
-static inline __uint64_t xfs_mask64lo(int n)
-{
- return ((__uint64_t)1 << (n)) - 1;
-}
-
-/* Get high bit set out of 32-bit argument, -1 if none set */
-extern int xfs_highbit32(__uint32_t v);
-
-/* Get low bit set out of 64-bit argument, -1 if none set */
-extern int xfs_lowbit64(__uint64_t v);
-
-/* Get high bit set out of 64-bit argument, -1 if none set */
-extern int xfs_highbit64(__uint64_t);
-
-/* Count set bits in map starting with start_bit */
-extern int xfs_count_bits(uint *map, uint size, uint start_bit);
-
-/* Count continuous one bits in map starting with start_bit */
-extern int xfs_contig_bits(uint *map, uint size, uint start_bit);
-
-/* Find next set bit in map */
-extern int xfs_next_bit(uint *map, uint size, uint start_bit);
-
-#endif /* __XFS_BIT_H__ */
diff --git a/sys/gnu/fs/xfs/xfs_bmap.c b/sys/gnu/fs/xfs/xfs_bmap.c
deleted file mode 100644
index 5c7ab96..0000000
--- a/sys/gnu/fs/xfs/xfs_bmap.c
+++ /dev/null
@@ -1,6547 +0,0 @@
-/*
- * Copyright (c) 2000-2006 Silicon Graphics, Inc.
- * All Rights Reserved.
- *
- * 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.
- *
- * This program is distributed in the hope that it would 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 the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- */
-#include "xfs.h"
-#include "xfs_fs.h"
-#include "xfs_types.h"
-#include "xfs_bit.h"
-#include "xfs_log.h"
-#include "xfs_inum.h"
-#include "xfs_trans.h"
-#include "xfs_sb.h"
-#include "xfs_ag.h"
-#include "xfs_dir.h"
-#include "xfs_dir2.h"
-#include "xfs_da_btree.h"
-#include "xfs_bmap_btree.h"
-#include "xfs_alloc_btree.h"
-#include "xfs_ialloc_btree.h"
-#include "xfs_dir_sf.h"
-#include "xfs_dir2_sf.h"
-#include "xfs_attr_sf.h"
-#include "xfs_dinode.h"
-#include "xfs_inode.h"
-#include "xfs_btree.h"
-#include "xfs_dmapi.h"
-#include "xfs_mount.h"
-#include "xfs_ialloc.h"
-#include "xfs_itable.h"
-#include "xfs_inode_item.h"
-#include "xfs_extfree_item.h"
-#include "xfs_alloc.h"
-#include "xfs_bmap.h"
-#include "xfs_rtalloc.h"
-#include "xfs_error.h"
-#include "xfs_dir_leaf.h"
-#include "xfs_attr_leaf.h"
-#include "xfs_rw.h"
-#include "xfs_quota.h"
-#include "xfs_trans_space.h"
-#include "xfs_buf_item.h"
-
-
-#ifdef DEBUG
-STATIC void
-xfs_bmap_check_leaf_extents(xfs_btree_cur_t *cur, xfs_inode_t *ip, int whichfork);
-#endif
-
-kmem_zone_t *xfs_bmap_free_item_zone;
-
-/*
- * Prototypes for internal bmap routines.
- */
-
-
-/*
- * Called from xfs_bmap_add_attrfork to handle extents format files.
- */
-STATIC int /* error */
-xfs_bmap_add_attrfork_extents(
- xfs_trans_t *tp, /* transaction pointer */
- xfs_inode_t *ip, /* incore inode pointer */
- xfs_fsblock_t *firstblock, /* first block allocated */
- xfs_bmap_free_t *flist, /* blocks to free at commit */
- int *flags); /* inode logging flags */
-
-/*
- * Called from xfs_bmap_add_attrfork to handle local format files.
- */
-STATIC int /* error */
-xfs_bmap_add_attrfork_local(
- xfs_trans_t *tp, /* transaction pointer */
- xfs_inode_t *ip, /* incore inode pointer */
- xfs_fsblock_t *firstblock, /* first block allocated */
- xfs_bmap_free_t *flist, /* blocks to free at commit */
- int *flags); /* inode logging flags */
-
-/*
- * Called by xfs_bmapi to update file extent records and the btree
- * after allocating space (or doing a delayed allocation).
- */
-STATIC int /* error */
-xfs_bmap_add_extent(
- xfs_inode_t *ip, /* incore inode pointer */
- xfs_extnum_t idx, /* extent number to update/insert */
- xfs_btree_cur_t **curp, /* if *curp is null, not a btree */
- xfs_bmbt_irec_t *new, /* new data to add to file extents */
- xfs_fsblock_t *first, /* pointer to firstblock variable */
- xfs_bmap_free_t *flist, /* list of extents to be freed */
- int *logflagsp, /* inode logging flags */
- xfs_extdelta_t *delta, /* Change made to incore extents */
- int whichfork, /* data or attr fork */
- int rsvd); /* OK to allocate reserved blocks */
-
-/*
- * Called by xfs_bmap_add_extent to handle cases converting a delayed
- * allocation to a real allocation.
- */
-STATIC int /* error */
-xfs_bmap_add_extent_delay_real(
- xfs_inode_t *ip, /* incore inode pointer */
- xfs_extnum_t idx, /* extent number to update/insert */
- xfs_btree_cur_t **curp, /* if *curp is null, not a btree */
- xfs_bmbt_irec_t *new, /* new data to add to file extents */
- xfs_filblks_t *dnew, /* new delayed-alloc indirect blocks */
- xfs_fsblock_t *first, /* pointer to firstblock variable */
- xfs_bmap_free_t *flist, /* list of extents to be freed */
- int *logflagsp, /* inode logging flags */
- xfs_extdelta_t *delta, /* Change made to incore extents */
- int rsvd); /* OK to allocate reserved blocks */
-
-/*
- * Called by xfs_bmap_add_extent to handle cases converting a hole
- * to a delayed allocation.
- */
-STATIC int /* error */
-xfs_bmap_add_extent_hole_delay(
- xfs_inode_t *ip, /* incore inode pointer */
- xfs_extnum_t idx, /* extent number to update/insert */
- xfs_btree_cur_t *cur, /* if null, not a btree */
- xfs_bmbt_irec_t *new, /* new data to add to file extents */
- int *logflagsp,/* inode logging flags */
- xfs_extdelta_t *delta, /* Change made to incore extents */
- int rsvd); /* OK to allocate reserved blocks */
-
-/*
- * Called by xfs_bmap_add_extent to handle cases converting a hole
- * to a real allocation.
- */
-STATIC int /* error */
-xfs_bmap_add_extent_hole_real(
- xfs_inode_t *ip, /* incore inode pointer */
- xfs_extnum_t idx, /* extent number to update/insert */
- xfs_btree_cur_t *cur, /* if null, not a btree */
- xfs_bmbt_irec_t *new, /* new data to add to file extents */
- int *logflagsp, /* inode logging flags */
- xfs_extdelta_t *delta, /* Change made to incore extents */
- int whichfork); /* data or attr fork */
-
-/*
- * Called by xfs_bmap_add_extent to handle cases converting an unwritten
- * allocation to a real allocation or vice versa.
- */
-STATIC int /* error */
-xfs_bmap_add_extent_unwritten_real(
- xfs_inode_t *ip, /* incore inode pointer */
- xfs_extnum_t idx, /* extent number to update/insert */
- xfs_btree_cur_t **curp, /* if *curp is null, not a btree */
- xfs_bmbt_irec_t *new, /* new data to add to file extents */
- int *logflagsp, /* inode logging flags */
- xfs_extdelta_t *delta); /* Change made to incore extents */
-
-/*
- * xfs_bmap_alloc is called by xfs_bmapi to allocate an extent for a file.
- * It figures out where to ask the underlying allocator to put the new extent.
- */
-STATIC int /* error */
-xfs_bmap_alloc(
- xfs_bmalloca_t *ap); /* bmap alloc argument struct */
-
-/*
- * Transform a btree format file with only one leaf node, where the
- * extents list will fit in the inode, into an extents format file.
- * Since the file extents are already in-core, all we have to do is
- * give up the space for the btree root and pitch the leaf block.
- */
-STATIC int /* error */
-xfs_bmap_btree_to_extents(
- xfs_trans_t *tp, /* transaction pointer */
- xfs_inode_t *ip, /* incore inode pointer */
- xfs_btree_cur_t *cur, /* btree cursor */
- int *logflagsp, /* inode logging flags */
- int whichfork); /* data or attr fork */
-
-#ifdef DEBUG
-#if 0
-/*
- * Check that the extents list for the inode ip is in the right order.
- */
-STATIC void
-xfs_bmap_check_extents(
- xfs_inode_t *ip, /* incore inode pointer */
- int whichfork); /* data or attr fork */
-#endif
-#endif
-
-/*
- * Called by xfs_bmapi to update file extent records and the btree
- * after removing space (or undoing a delayed allocation).
- */
-STATIC int /* error */
-xfs_bmap_del_extent(
- xfs_inode_t *ip, /* incore inode pointer */
- xfs_trans_t *tp, /* current trans pointer */
- xfs_extnum_t idx, /* extent number to update/insert */
- xfs_bmap_free_t *flist, /* list of extents to be freed */
- xfs_btree_cur_t *cur, /* if null, not a btree */
- xfs_bmbt_irec_t *new, /* new data to add to file extents */
- int *logflagsp,/* inode logging flags */
- xfs_extdelta_t *delta, /* Change made to incore extents */
- int whichfork, /* data or attr fork */
- int rsvd); /* OK to allocate reserved blocks */
-
-/*
- * Remove the entry "free" from the free item list. Prev points to the
- * previous entry, unless "free" is the head of the list.
- */
-STATIC void
-xfs_bmap_del_free(
- xfs_bmap_free_t *flist, /* free item list header */
- xfs_bmap_free_item_t *prev, /* previous item on list, if any */
- xfs_bmap_free_item_t *free); /* list item to be freed */
-
-/*
- * Convert an extents-format file into a btree-format file.
- * The new file will have a root block (in the inode) and a single child block.
- */
-STATIC int /* error */
-xfs_bmap_extents_to_btree(
- xfs_trans_t *tp, /* transaction pointer */
- xfs_inode_t *ip, /* incore inode pointer */
- xfs_fsblock_t *firstblock, /* first-block-allocated */
- xfs_bmap_free_t *flist, /* blocks freed in xaction */
- xfs_btree_cur_t **curp, /* cursor returned to caller */
- int wasdel, /* converting a delayed alloc */
- int *logflagsp, /* inode logging flags */
- int whichfork); /* data or attr fork */
-
-/*
- * Convert a local file to an extents file.
- * This code is sort of bogus, since the file data needs to get
- * logged so it won't be lost. The bmap-level manipulations are ok, though.
- */
-STATIC int /* error */
-xfs_bmap_local_to_extents(
- xfs_trans_t *tp, /* transaction pointer */
- xfs_inode_t *ip, /* incore inode pointer */
- xfs_fsblock_t *firstblock, /* first block allocated in xaction */
- xfs_extlen_t total, /* total blocks needed by transaction */
- int *logflagsp, /* inode logging flags */
- int whichfork); /* data or attr fork */
-
-/*
- * Search the extents list for the inode, for the extent containing bno.
- * If bno lies in a hole, point to the next entry. If bno lies past eof,
- * *eofp will be set, and *prevp will contain the last entry (null if none).
- * Else, *lastxp will be set to the index of the found
- * entry; *gotp will contain the entry.
- */
-STATIC xfs_bmbt_rec_t * /* pointer to found extent entry */
-xfs_bmap_search_extents(
- xfs_inode_t *ip, /* incore inode pointer */
- xfs_fileoff_t bno, /* block number searched for */
- int whichfork, /* data or attr fork */
- int *eofp, /* out: end of file found */
- xfs_extnum_t *lastxp, /* out: last extent index */
- xfs_bmbt_irec_t *gotp, /* out: extent entry found */
- xfs_bmbt_irec_t *prevp); /* out: previous extent entry found */
-
-/*
- * Check the last inode extent to determine whether this allocation will result
- * in blocks being allocated at the end of the file. When we allocate new data
- * blocks at the end of the file which do not start at the previous data block,
- * we will try to align the new blocks at stripe unit boundaries.
- */
-STATIC int /* error */
-xfs_bmap_isaeof(
- xfs_inode_t *ip, /* incore inode pointer */
- xfs_fileoff_t off, /* file offset in fsblocks */
- int whichfork, /* data or attribute fork */
- char *aeof); /* return value */
-
-#ifdef XFS_BMAP_TRACE
-/*
- * Add a bmap trace buffer entry. Base routine for the others.
- */
-STATIC void
-xfs_bmap_trace_addentry(
- int opcode, /* operation */
- char *fname, /* function name */
- char *desc, /* operation description */
- xfs_inode_t *ip, /* incore inode pointer */
- xfs_extnum_t idx, /* index of entry(ies) */
- xfs_extnum_t cnt, /* count of entries, 1 or 2 */
- xfs_bmbt_rec_t *r1, /* first record */
- xfs_bmbt_rec_t *r2, /* second record or null */
- int whichfork); /* data or attr fork */
-
-/*
- * Add bmap trace entry prior to a call to xfs_iext_remove.
- */
-STATIC void
-xfs_bmap_trace_delete(
- char *fname, /* function name */
- char *desc, /* operation description */
- xfs_inode_t *ip, /* incore inode pointer */
- xfs_extnum_t idx, /* index of entry(entries) deleted */
- xfs_extnum_t cnt, /* count of entries deleted, 1 or 2 */
- int whichfork); /* data or attr fork */
-
-/*
- * Add bmap trace entry prior to a call to xfs_iext_insert, or
- * reading in the extents list from the disk (in the btree).
- */
-STATIC void
-xfs_bmap_trace_insert(
- char *fname, /* function name */
- char *desc, /* operation description */
- xfs_inode_t *ip, /* incore inode pointer */
- xfs_extnum_t idx, /* index of entry(entries) inserted */
- xfs_extnum_t cnt, /* count of entries inserted, 1 or 2 */
- xfs_bmbt_irec_t *r1, /* inserted record 1 */
- xfs_bmbt_irec_t *r2, /* inserted record 2 or null */
- int whichfork); /* data or attr fork */
-
-/*
- * Add bmap trace entry after updating an extent record in place.
- */
-STATIC void
-xfs_bmap_trace_post_update(
- char *fname, /* function name */
- char *desc, /* operation description */
- xfs_inode_t *ip, /* incore inode pointer */
- xfs_extnum_t idx, /* index of entry updated */
- int whichfork); /* data or attr fork */
-
-/*
- * Add bmap trace entry prior to updating an extent record in place.
- */
-STATIC void
-xfs_bmap_trace_pre_update(
- char *fname, /* function name */
- char *desc, /* operation description */
- xfs_inode_t *ip, /* incore inode pointer */
- xfs_extnum_t idx, /* index of entry to be updated */
- int whichfork); /* data or attr fork */
-
-#else
-#define xfs_bmap_trace_delete(f,d,ip,i,c,w)
-#define xfs_bmap_trace_insert(f,d,ip,i,c,r1,r2,w)
-#define xfs_bmap_trace_post_update(f,d,ip,i,w)
-#define xfs_bmap_trace_pre_update(f,d,ip,i,w)
-#endif /* XFS_BMAP_TRACE */
-
-/*
- * Compute the worst-case number of indirect blocks that will be used
- * for ip's delayed extent of length "len".
- */
-STATIC xfs_filblks_t
-xfs_bmap_worst_indlen(
- xfs_inode_t *ip, /* incore inode pointer */
- xfs_filblks_t len); /* delayed extent length */
-
-#ifdef DEBUG
-/*
- * Perform various validation checks on the values being returned
- * from xfs_bmapi().
- */
-STATIC void
-xfs_bmap_validate_ret(
- xfs_fileoff_t bno,
- xfs_filblks_t len,
- int flags,
- xfs_bmbt_irec_t *mval,
- int nmap,
- int ret_nmap);
-#else
-#define xfs_bmap_validate_ret(bno,len,flags,mval,onmap,nmap)
-#endif /* DEBUG */
-
-#if defined(XFS_RW_TRACE)
-STATIC void
-xfs_bunmap_trace(
- xfs_inode_t *ip,
- xfs_fileoff_t bno,
- xfs_filblks_t len,
- int flags,
- inst_t *ra);
-#else
-#define xfs_bunmap_trace(ip, bno, len, flags, ra)
-#endif /* XFS_RW_TRACE */
-
-STATIC int
-xfs_bmap_count_tree(
- xfs_mount_t *mp,
- xfs_trans_t *tp,
- xfs_ifork_t *ifp,
- xfs_fsblock_t blockno,
- int levelin,
- int *count);
-
-STATIC int
-xfs_bmap_count_leaves(
- xfs_ifork_t *ifp,
- xfs_extnum_t idx,
- int numrecs,
- int *count);
-
-STATIC int
-xfs_bmap_disk_count_leaves(
- xfs_ifork_t *ifp,
- xfs_mount_t *mp,
- xfs_extnum_t idx,
- xfs_bmbt_block_t *block,
- int numrecs,
- int *count);
-
-/*
- * Bmap internal routines.
- */
-
-/*
- * Called from xfs_bmap_add_attrfork to handle btree format files.
- */
-STATIC int /* error */
-xfs_bmap_add_attrfork_btree(
- xfs_trans_t *tp, /* transaction pointer */
- xfs_inode_t *ip, /* incore inode pointer */
- xfs_fsblock_t *firstblock, /* first block allocated */
- xfs_bmap_free_t *flist, /* blocks to free at commit */
- int *flags) /* inode logging flags */
-{
- xfs_btree_cur_t *cur; /* btree cursor */
- int error; /* error return value */
- xfs_mount_t *mp; /* file system mount struct */
- int stat; /* newroot status */
-
- mp = ip->i_mount;
- if (ip->i_df.if_broot_bytes <= XFS_IFORK_DSIZE(ip))
- *flags |= XFS_ILOG_DBROOT;
- else {
- cur = xfs_btree_init_cursor(mp, tp, NULL, 0, XFS_BTNUM_BMAP, ip,
- XFS_DATA_FORK);
- cur->bc_private.b.flist = flist;
- cur->bc_private.b.firstblock = *firstblock;
- if ((error = xfs_bmbt_lookup_ge(cur, 0, 0, 0, &stat)))
- goto error0;
- ASSERT(stat == 1); /* must be at least one entry */
- if ((error = xfs_bmbt_newroot(cur, flags, &stat)))
- goto error0;
- if (stat == 0) {
- xfs_btree_del_cursor(cur, XFS_BTREE_NOERROR);
- return XFS_ERROR(ENOSPC);
- }
- *firstblock = cur->bc_private.b.firstblock;
- cur->bc_private.b.allocated = 0;
- xfs_btree_del_cursor(cur, XFS_BTREE_NOERROR);
- }
- return 0;
-error0:
- xfs_btree_del_cursor(cur, XFS_BTREE_ERROR);
- return error;
-}
-
-/*
- * Called from xfs_bmap_add_attrfork to handle extents format files.
- */
-STATIC int /* error */
-xfs_bmap_add_attrfork_extents(
- xfs_trans_t *tp, /* transaction pointer */
- xfs_inode_t *ip, /* incore inode pointer */
- xfs_fsblock_t *firstblock, /* first block allocated */
- xfs_bmap_free_t *flist, /* blocks to free at commit */
- int *flags) /* inode logging flags */
-{
- xfs_btree_cur_t *cur; /* bmap btree cursor */
- int error; /* error return value */
-
- if (ip->i_d.di_nextents * sizeof(xfs_bmbt_rec_t) <= XFS_IFORK_DSIZE(ip))
- return 0;
- cur = NULL;
- error = xfs_bmap_extents_to_btree(tp, ip, firstblock, flist, &cur, 0,
- flags, XFS_DATA_FORK);
- if (cur) {
- cur->bc_private.b.allocated = 0;
- xfs_btree_del_cursor(cur,
- error ? XFS_BTREE_ERROR : XFS_BTREE_NOERROR);
- }
- return error;
-}
-
-/*
- * Called from xfs_bmap_add_attrfork to handle local format files.
- */
-STATIC int /* error */
-xfs_bmap_add_attrfork_local(
- xfs_trans_t *tp, /* transaction pointer */
- xfs_inode_t *ip, /* incore inode pointer */
- xfs_fsblock_t *firstblock, /* first block allocated */
- xfs_bmap_free_t *flist, /* blocks to free at commit */
- int *flags) /* inode logging flags */
-{
- xfs_da_args_t dargs; /* args for dir/attr code */
- int error; /* error return value */
- xfs_mount_t *mp; /* mount structure pointer */
-
- if (ip->i_df.if_bytes <= XFS_IFORK_DSIZE(ip))
- return 0;
- if ((ip->i_d.di_mode & S_IFMT) == S_IFDIR) {
- mp = ip->i_mount;
- memset(&dargs, 0, sizeof(dargs));
- dargs.dp = ip;
- dargs.firstblock = firstblock;
- dargs.flist = flist;
- dargs.total = mp->m_dirblkfsbs;
- dargs.whichfork = XFS_DATA_FORK;
- dargs.trans = tp;
- error = XFS_DIR_SHORTFORM_TO_SINGLE(mp, &dargs);
- } else
- error = xfs_bmap_local_to_extents(tp, ip, firstblock, 1, flags,
- XFS_DATA_FORK);
- return error;
-}
-
-/*
- * Called by xfs_bmapi to update file extent records and the btree
- * after allocating space (or doing a delayed allocation).
- */
-STATIC int /* error */
-xfs_bmap_add_extent(
- xfs_inode_t *ip, /* incore inode pointer */
- xfs_extnum_t idx, /* extent number to update/insert */
- xfs_btree_cur_t **curp, /* if *curp is null, not a btree */
- xfs_bmbt_irec_t *new, /* new data to add to file extents */
- xfs_fsblock_t *first, /* pointer to firstblock variable */
- xfs_bmap_free_t *flist, /* list of extents to be freed */
- int *logflagsp, /* inode logging flags */
- xfs_extdelta_t *delta, /* Change made to incore extents */
- int whichfork, /* data or attr fork */
- int rsvd) /* OK to use reserved data blocks */
-{
- xfs_btree_cur_t *cur; /* btree cursor or null */
- xfs_filblks_t da_new; /* new count del alloc blocks used */
- xfs_filblks_t da_old; /* old count del alloc blocks used */
- int error; /* error return value */
-#ifdef XFS_BMAP_TRACE
- static char fname[] = "xfs_bmap_add_extent";
-#endif
- xfs_ifork_t *ifp; /* inode fork ptr */
- int logflags; /* returned value */
- xfs_extnum_t nextents; /* number of extents in file now */
-
- XFS_STATS_INC(xs_add_exlist);
- cur = *curp;
- ifp = XFS_IFORK_PTR(ip, whichfork);
- nextents = ifp->if_bytes / (uint)sizeof(xfs_bmbt_rec_t);
- ASSERT(idx <= nextents);
- da_old = da_new = 0;
- error = 0;
- /*
- * This is the first extent added to a new/empty file.
- * Special case this one, so other routines get to assume there are
- * already extents in the list.
- */
- if (nextents == 0) {
- xfs_bmap_trace_insert(fname, "insert empty", ip, 0, 1, new,
- NULL, whichfork);
- xfs_iext_insert(ifp, 0, 1, new);
- ASSERT(cur == NULL);
- ifp->if_lastex = 0;
- if (!ISNULLSTARTBLOCK(new->br_startblock)) {
- XFS_IFORK_NEXT_SET(ip, whichfork, 1);
- logflags = XFS_ILOG_CORE | XFS_ILOG_FEXT(whichfork);
- } else
- logflags = 0;
- /* DELTA: single new extent */
- if (delta) {
- if (delta->xed_startoff > new->br_startoff)
- delta->xed_startoff = new->br_startoff;
- if (delta->xed_blockcount <
- new->br_startoff + new->br_blockcount)
- delta->xed_blockcount = new->br_startoff +
- new->br_blockcount;
- }
- }
- /*
- * Any kind of new delayed allocation goes here.
- */
- else if (ISNULLSTARTBLOCK(new->br_startblock)) {
- if (cur)
- ASSERT((cur->bc_private.b.flags &
- XFS_BTCUR_BPRV_WASDEL) == 0);
- if ((error = xfs_bmap_add_extent_hole_delay(ip, idx, cur, new,
- &logflags, delta, rsvd)))
- goto done;
- }
- /*
- * Real allocation off the end of the file.
- */
- else if (idx == nextents) {
- if (cur)
- ASSERT((cur->bc_private.b.flags &
- XFS_BTCUR_BPRV_WASDEL) == 0);
- if ((error = xfs_bmap_add_extent_hole_real(ip, idx, cur, new,
- &logflags, delta, whichfork)))
- goto done;
- } else {
- xfs_bmbt_irec_t prev; /* old extent at offset idx */
-
- /*
- * Get the record referred to by idx.
- */
- xfs_bmbt_get_all(xfs_iext_get_ext(ifp, idx), &prev);
- /*
- * If it's a real allocation record, and the new allocation ends
- * after the start of the referred to record, then we're filling
- * in a delayed or unwritten allocation with a real one, or
- * converting real back to unwritten.
- */
- if (!ISNULLSTARTBLOCK(new->br_startblock) &&
- new->br_startoff + new->br_blockcount > prev.br_startoff) {
- if (prev.br_state != XFS_EXT_UNWRITTEN &&
- ISNULLSTARTBLOCK(prev.br_startblock)) {
- da_old = STARTBLOCKVAL(prev.br_startblock);
- if (cur)
- ASSERT(cur->bc_private.b.flags &
- XFS_BTCUR_BPRV_WASDEL);
- if ((error = xfs_bmap_add_extent_delay_real(ip,
- idx, &cur, new, &da_new, first, flist,
- &logflags, delta, rsvd)))
- goto done;
- } else if (new->br_state == XFS_EXT_NORM) {
- ASSERT(new->br_state == XFS_EXT_NORM);
- if ((error = xfs_bmap_add_extent_unwritten_real(
- ip, idx, &cur, new, &logflags, delta)))
- goto done;
- } else {
- ASSERT(new->br_state == XFS_EXT_UNWRITTEN);
- if ((error = xfs_bmap_add_extent_unwritten_real(
- ip, idx, &cur, new, &logflags, delta)))
- goto done;
- }
- ASSERT(*curp == cur || *curp == NULL);
- }
- /*
- * Otherwise we're filling in a hole with an allocation.
- */
- else {
- if (cur)
- ASSERT((cur->bc_private.b.flags &
- XFS_BTCUR_BPRV_WASDEL) == 0);
- if ((error = xfs_bmap_add_extent_hole_real(ip, idx, cur,
- new, &logflags, delta, whichfork)))
- goto done;
- }
- }
-
- ASSERT(*curp == cur || *curp == NULL);
- /*
- * Convert to a btree if necessary.
- */
- if (XFS_IFORK_FORMAT(ip, whichfork) == XFS_DINODE_FMT_EXTENTS &&
- XFS_IFORK_NEXTENTS(ip, whichfork) > ifp->if_ext_max) {
- int tmp_logflags; /* partial log flag return val */
-
- ASSERT(cur == NULL);
- error = xfs_bmap_extents_to_btree(ip->i_transp, ip, first,
- flist, &cur, da_old > 0, &tmp_logflags, whichfork);
- logflags |= tmp_logflags;
- if (error)
- goto done;
- }
- /*
- * Adjust for changes in reserved delayed indirect blocks.
- * Nothing to do for disk quotas here.
- */
- if (da_old || da_new) {
- xfs_filblks_t nblks;
-
- nblks = da_new;
- if (cur)
- nblks += cur->bc_private.b.allocated;
- ASSERT(nblks <= da_old);
- if (nblks < da_old)
- xfs_mod_incore_sb(ip->i_mount, XFS_SBS_FDBLOCKS,
- (int)(da_old - nblks), rsvd);
- }
- /*
- * Clear out the allocated field, done with it now in any case.
- */
- if (cur) {
- cur->bc_private.b.allocated = 0;
- *curp = cur;
- }
-done:
-#ifdef DEBUG
- if (!error)
- xfs_bmap_check_leaf_extents(*curp, ip, whichfork);
-#endif
- *logflagsp = logflags;
- return error;
-}
-
-/*
- * Called by xfs_bmap_add_extent to handle cases converting a delayed
- * allocation to a real allocation.
- */
-STATIC int /* error */
-xfs_bmap_add_extent_delay_real(
- xfs_inode_t *ip, /* incore inode pointer */
- xfs_extnum_t idx, /* extent number to update/insert */
- xfs_btree_cur_t **curp, /* if *curp is null, not a btree */
- xfs_bmbt_irec_t *new, /* new data to add to file extents */
- xfs_filblks_t *dnew, /* new delayed-alloc indirect blocks */
- xfs_fsblock_t *first, /* pointer to firstblock variable */
- xfs_bmap_free_t *flist, /* list of extents to be freed */
- int *logflagsp, /* inode logging flags */
- xfs_extdelta_t *delta, /* Change made to incore extents */
- int rsvd) /* OK to use reserved data block allocation */
-{
- xfs_btree_cur_t *cur; /* btree cursor */
- int diff; /* temp value */
- xfs_bmbt_rec_t *ep; /* extent entry for idx */
- int error; /* error return value */
-#ifdef XFS_BMAP_TRACE
- static char fname[] = "xfs_bmap_add_extent_delay_real";
-#endif
- int i; /* temp state */
- xfs_ifork_t *ifp; /* inode fork pointer */
- xfs_fileoff_t new_endoff; /* end offset of new entry */
- xfs_bmbt_irec_t r[3]; /* neighbor extent entries */
- /* left is 0, right is 1, prev is 2 */
- int rval=0; /* return value (logging flags) */
- int state = 0;/* state bits, accessed thru macros */
- xfs_filblks_t temp=0; /* value for dnew calculations */
- xfs_filblks_t temp2=0;/* value for dnew calculations */
- int tmp_rval; /* partial logging flags */
- enum { /* bit number definitions for state */
- LEFT_CONTIG, RIGHT_CONTIG,
- LEFT_FILLING, RIGHT_FILLING,
- LEFT_DELAY, RIGHT_DELAY,
- LEFT_VALID, RIGHT_VALID
- };
-
-#define LEFT r[0]
-#define RIGHT r[1]
-#define PREV r[2]
-#define MASK(b) (1 << (b))
-#define MASK2(a,b) (MASK(a) | MASK(b))
-#define MASK3(a,b,c) (MASK2(a,b) | MASK(c))
-#define MASK4(a,b,c,d) (MASK3(a,b,c) | MASK(d))
-#define STATE_SET(b,v) ((v) ? (state |= MASK(b)) : (state &= ~MASK(b)))
-#define STATE_TEST(b) (state & MASK(b))
-#define STATE_SET_TEST(b,v) ((v) ? ((state |= MASK(b)), 1) : \
- ((state &= ~MASK(b)), 0))
-#define SWITCH_STATE \
- (state & MASK4(LEFT_FILLING, RIGHT_FILLING, LEFT_CONTIG, RIGHT_CONTIG))
-
- /*
- * Set up a bunch of variables to make the tests simpler.
- */
- cur = *curp;
- ifp = XFS_IFORK_PTR(ip, XFS_DATA_FORK);
- ep = xfs_iext_get_ext(ifp, idx);
- xfs_bmbt_get_all(ep, &PREV);
- new_endoff = new->br_startoff + new->br_blockcount;
- ASSERT(PREV.br_startoff <= new->br_startoff);
- ASSERT(PREV.br_startoff + PREV.br_blockcount >= new_endoff);
- /*
- * Set flags determining what part of the previous delayed allocation
- * extent is being replaced by a real allocation.
- */
- STATE_SET(LEFT_FILLING, PREV.br_startoff == new->br_startoff);
- STATE_SET(RIGHT_FILLING,
- PREV.br_startoff + PREV.br_blockcount == new_endoff);
- /*
- * Check and set flags if this segment has a left neighbor.
- * Don't set contiguous if the combined extent would be too large.
- */
- if (STATE_SET_TEST(LEFT_VALID, idx > 0)) {
- xfs_bmbt_get_all(xfs_iext_get_ext(ifp, idx - 1), &LEFT);
- STATE_SET(LEFT_DELAY, ISNULLSTARTBLOCK(LEFT.br_startblock));
- }
- STATE_SET(LEFT_CONTIG,
- STATE_TEST(LEFT_VALID) && !STATE_TEST(LEFT_DELAY) &&
- LEFT.br_startoff + LEFT.br_blockcount == new->br_startoff &&
- LEFT.br_startblock + LEFT.br_blockcount == new->br_startblock &&
- LEFT.br_state == new->br_state &&
- LEFT.br_blockcount + new->br_blockcount <= MAXEXTLEN);
- /*
- * Check and set flags if this segment has a right neighbor.
- * Don't set contiguous if the combined extent would be too large.
- * Also check for all-three-contiguous being too large.
- */
- if (STATE_SET_TEST(RIGHT_VALID,
- idx <
- ip->i_df.if_bytes / (uint)sizeof(xfs_bmbt_rec_t) - 1)) {
- xfs_bmbt_get_all(xfs_iext_get_ext(ifp, idx + 1), &RIGHT);
- STATE_SET(RIGHT_DELAY, ISNULLSTARTBLOCK(RIGHT.br_startblock));
- }
- STATE_SET(RIGHT_CONTIG,
- STATE_TEST(RIGHT_VALID) && !STATE_TEST(RIGHT_DELAY) &&
- new_endoff == RIGHT.br_startoff &&
- new->br_startblock + new->br_blockcount ==
- RIGHT.br_startblock &&
- new->br_state == RIGHT.br_state &&
- new->br_blockcount + RIGHT.br_blockcount <= MAXEXTLEN &&
- ((state & MASK3(LEFT_CONTIG, LEFT_FILLING, RIGHT_FILLING)) !=
- MASK3(LEFT_CONTIG, LEFT_FILLING, RIGHT_FILLING) ||
- LEFT.br_blockcount + new->br_blockcount + RIGHT.br_blockcount
- <= MAXEXTLEN));
- error = 0;
- /*
- * Switch out based on the FILLING and CONTIG state bits.
- */
- switch (SWITCH_STATE) {
-
- case MASK4(LEFT_FILLING, RIGHT_FILLING, LEFT_CONTIG, RIGHT_CONTIG):
- /*
- * Filling in all of a previously delayed allocation extent.
- * The left and right neighbors are both contiguous with new.
- */
- xfs_bmap_trace_pre_update(fname, "LF|RF|LC|RC", ip, idx - 1,
- XFS_DATA_FORK);
- xfs_bmbt_set_blockcount(xfs_iext_get_ext(ifp, idx - 1),
- LEFT.br_blockcount + PREV.br_blockcount +
- RIGHT.br_blockcount);
- xfs_bmap_trace_post_update(fname, "LF|RF|LC|RC", ip, idx - 1,
- XFS_DATA_FORK);
- xfs_bmap_trace_delete(fname, "LF|RF|LC|RC", ip, idx, 2,
- XFS_DATA_FORK);
- xfs_iext_remove(ifp, idx, 2);
- ip->i_df.if_lastex = idx - 1;
- ip->i_d.di_nextents--;
- if (cur == NULL)
- rval = XFS_ILOG_CORE | XFS_ILOG_DEXT;
- else {
- rval = XFS_ILOG_CORE;
- if ((error = xfs_bmbt_lookup_eq(cur, RIGHT.br_startoff,
- RIGHT.br_startblock,
- RIGHT.br_blockcount, &i)))
- goto done;
- ASSERT(i == 1);
- if ((error = xfs_bmbt_delete(cur, &i)))
- goto done;
- ASSERT(i == 1);
- if ((error = xfs_bmbt_decrement(cur, 0, &i)))
- goto done;
- ASSERT(i == 1);
- if ((error = xfs_bmbt_update(cur, LEFT.br_startoff,
- LEFT.br_startblock,
- LEFT.br_blockcount +
- PREV.br_blockcount +
- RIGHT.br_blockcount, LEFT.br_state)))
- goto done;
- }
- *dnew = 0;
- /* DELTA: Three in-core extents are replaced by one. */
- temp = LEFT.br_startoff;
- temp2 = LEFT.br_blockcount +
- PREV.br_blockcount +
- RIGHT.br_blockcount;
- break;
-
- case MASK3(LEFT_FILLING, RIGHT_FILLING, LEFT_CONTIG):
- /*
- * Filling in all of a previously delayed allocation extent.
- * The left neighbor is contiguous, the right is not.
- */
- xfs_bmap_trace_pre_update(fname, "LF|RF|LC", ip, idx - 1,
- XFS_DATA_FORK);
- xfs_bmbt_set_blockcount(xfs_iext_get_ext(ifp, idx - 1),
- LEFT.br_blockcount + PREV.br_blockcount);
- xfs_bmap_trace_post_update(fname, "LF|RF|LC", ip, idx - 1,
- XFS_DATA_FORK);
- ip->i_df.if_lastex = idx - 1;
- xfs_bmap_trace_delete(fname, "LF|RF|LC", ip, idx, 1,
- XFS_DATA_FORK);
- xfs_iext_remove(ifp, idx, 1);
- if (cur == NULL)
- rval = XFS_ILOG_DEXT;
- else {
- rval = 0;
- if ((error = xfs_bmbt_lookup_eq(cur, LEFT.br_startoff,
- LEFT.br_startblock, LEFT.br_blockcount,
- &i)))
- goto done;
- ASSERT(i == 1);
- if ((error = xfs_bmbt_update(cur, LEFT.br_startoff,
- LEFT.br_startblock,
- LEFT.br_blockcount +
- PREV.br_blockcount, LEFT.br_state)))
- goto done;
- }
- *dnew = 0;
- /* DELTA: Two in-core extents are replaced by one. */
- temp = LEFT.br_startoff;
- temp2 = LEFT.br_blockcount +
- PREV.br_blockcount;
- break;
-
- case MASK3(LEFT_FILLING, RIGHT_FILLING, RIGHT_CONTIG):
- /*
- * Filling in all of a previously delayed allocation extent.
- * The right neighbor is contiguous, the left is not.
- */
- xfs_bmap_trace_pre_update(fname, "LF|RF|RC", ip, idx,
- XFS_DATA_FORK);
- xfs_bmbt_set_startblock(ep, new->br_startblock);
- xfs_bmbt_set_blockcount(ep,
- PREV.br_blockcount + RIGHT.br_blockcount);
- xfs_bmap_trace_post_update(fname, "LF|RF|RC", ip, idx,
- XFS_DATA_FORK);
- ip->i_df.if_lastex = idx;
- xfs_bmap_trace_delete(fname, "LF|RF|RC", ip, idx + 1, 1,
- XFS_DATA_FORK);
- xfs_iext_remove(ifp, idx + 1, 1);
- if (cur == NULL)
- rval = XFS_ILOG_DEXT;
- else {
- rval = 0;
- if ((error = xfs_bmbt_lookup_eq(cur, RIGHT.br_startoff,
- RIGHT.br_startblock,
- RIGHT.br_blockcount, &i)))
- goto done;
- ASSERT(i == 1);
- if ((error = xfs_bmbt_update(cur, PREV.br_startoff,
- new->br_startblock,
- PREV.br_blockcount +
- RIGHT.br_blockcount, PREV.br_state)))
- goto done;
- }
- *dnew = 0;
- /* DELTA: Two in-core extents are replaced by one. */
- temp = PREV.br_startoff;
- temp2 = PREV.br_blockcount +
- RIGHT.br_blockcount;
- break;
-
- case MASK2(LEFT_FILLING, RIGHT_FILLING):
- /*
- * Filling in all of a previously delayed allocation extent.
- * Neither the left nor right neighbors are contiguous with
- * the new one.
- */
- xfs_bmap_trace_pre_update(fname, "LF|RF", ip, idx,
- XFS_DATA_FORK);
- xfs_bmbt_set_startblock(ep, new->br_startblock);
- xfs_bmap_trace_post_update(fname, "LF|RF", ip, idx,
- XFS_DATA_FORK);
- ip->i_df.if_lastex = idx;
- ip->i_d.di_nextents++;
- if (cur == NULL)
- rval = XFS_ILOG_CORE | XFS_ILOG_DEXT;
- else {
- rval = XFS_ILOG_CORE;
- if ((error = xfs_bmbt_lookup_eq(cur, new->br_startoff,
- new->br_startblock, new->br_blockcount,
- &i)))
- goto done;
- ASSERT(i == 0);
- cur->bc_rec.b.br_state = XFS_EXT_NORM;
- if ((error = xfs_bmbt_insert(cur, &i)))
- goto done;
- ASSERT(i == 1);
- }
- *dnew = 0;
- /* DELTA: The in-core extent described by new changed type. */
- temp = new->br_startoff;
- temp2 = new->br_blockcount;
- break;
-
- case MASK2(LEFT_FILLING, LEFT_CONTIG):
- /*
- * Filling in the first part of a previous delayed allocation.
- * The left neighbor is contiguous.
- */
- xfs_bmap_trace_pre_update(fname, "LF|LC", ip, idx - 1,
- XFS_DATA_FORK);
- xfs_bmbt_set_blockcount(xfs_iext_get_ext(ifp, idx - 1),
- LEFT.br_blockcount + new->br_blockcount);
- xfs_bmbt_set_startoff(ep,
- PREV.br_startoff + new->br_blockcount);
- xfs_bmap_trace_post_update(fname, "LF|LC", ip, idx - 1,
- XFS_DATA_FORK);
- temp = PREV.br_blockcount - new->br_blockcount;
- xfs_bmap_trace_pre_update(fname, "LF|LC", ip, idx,
- XFS_DATA_FORK);
- xfs_bmbt_set_blockcount(ep, temp);
- ip->i_df.if_lastex = idx - 1;
- if (cur == NULL)
- rval = XFS_ILOG_DEXT;
- else {
- rval = 0;
- if ((error = xfs_bmbt_lookup_eq(cur, LEFT.br_startoff,
- LEFT.br_startblock, LEFT.br_blockcount,
- &i)))
- goto done;
- ASSERT(i == 1);
- if ((error = xfs_bmbt_update(cur, LEFT.br_startoff,
- LEFT.br_startblock,
- LEFT.br_blockcount +
- new->br_blockcount,
- LEFT.br_state)))
- goto done;
- }
- temp = XFS_FILBLKS_MIN(xfs_bmap_worst_indlen(ip, temp),
- STARTBLOCKVAL(PREV.br_startblock));
- xfs_bmbt_set_startblock(ep, NULLSTARTBLOCK((int)temp));
- xfs_bmap_trace_post_update(fname, "LF|LC", ip, idx,
- XFS_DATA_FORK);
- *dnew = temp;
- /* DELTA: The boundary between two in-core extents moved. */
- temp = LEFT.br_startoff;
- temp2 = LEFT.br_blockcount +
- PREV.br_blockcount;
- break;
-
- case MASK(LEFT_FILLING):
- /*
- * Filling in the first part of a previous delayed allocation.
- * The left neighbor is not contiguous.
- */
- xfs_bmap_trace_pre_update(fname, "LF", ip, idx, XFS_DATA_FORK);
- xfs_bmbt_set_startoff(ep, new_endoff);
- temp = PREV.br_blockcount - new->br_blockcount;
- xfs_bmbt_set_blockcount(ep, temp);
- xfs_bmap_trace_insert(fname, "LF", ip, idx, 1, new, NULL,
- XFS_DATA_FORK);
- xfs_iext_insert(ifp, idx, 1, new);
- ip->i_df.if_lastex = idx;
- ip->i_d.di_nextents++;
- if (cur == NULL)
- rval = XFS_ILOG_CORE | XFS_ILOG_DEXT;
- else {
- rval = XFS_ILOG_CORE;
- if ((error = xfs_bmbt_lookup_eq(cur, new->br_startoff,
- new->br_startblock, new->br_blockcount,
- &i)))
- goto done;
- ASSERT(i == 0);
- cur->bc_rec.b.br_state = XFS_EXT_NORM;
- if ((error = xfs_bmbt_insert(cur, &i)))
- goto done;
- ASSERT(i == 1);
- }
- if (ip->i_d.di_format == XFS_DINODE_FMT_EXTENTS &&
- ip->i_d.di_nextents > ip->i_df.if_ext_max) {
- error = xfs_bmap_extents_to_btree(ip->i_transp, ip,
- first, flist, &cur, 1, &tmp_rval,
- XFS_DATA_FORK);
- rval |= tmp_rval;
- if (error)
- goto done;
- }
- temp = XFS_FILBLKS_MIN(xfs_bmap_worst_indlen(ip, temp),
- STARTBLOCKVAL(PREV.br_startblock) -
- (cur ? cur->bc_private.b.allocated : 0));
- ep = xfs_iext_get_ext(ifp, idx + 1);
- xfs_bmbt_set_startblock(ep, NULLSTARTBLOCK((int)temp));
- xfs_bmap_trace_post_update(fname, "LF", ip, idx + 1,
- XFS_DATA_FORK);
- *dnew = temp;
- /* DELTA: One in-core extent is split in two. */
- temp = PREV.br_startoff;
- temp2 = PREV.br_blockcount;
- break;
-
- case MASK2(RIGHT_FILLING, RIGHT_CONTIG):
- /*
- * Filling in the last part of a previous delayed allocation.
- * The right neighbor is contiguous with the new allocation.
- */
- temp = PREV.br_blockcount - new->br_blockcount;
- xfs_bmap_trace_pre_update(fname, "RF|RC", ip, idx,
- XFS_DATA_FORK);
- xfs_bmap_trace_pre_update(fname, "RF|RC", ip, idx + 1,
- XFS_DATA_FORK);
- xfs_bmbt_set_blockcount(ep, temp);
- xfs_bmbt_set_allf(xfs_iext_get_ext(ifp, idx + 1),
- new->br_startoff, new->br_startblock,
- new->br_blockcount + RIGHT.br_blockcount,
- RIGHT.br_state);
- xfs_bmap_trace_post_update(fname, "RF|RC", ip, idx + 1,
- XFS_DATA_FORK);
- ip->i_df.if_lastex = idx + 1;
- if (cur == NULL)
- rval = XFS_ILOG_DEXT;
- else {
- rval = 0;
- if ((error = xfs_bmbt_lookup_eq(cur, RIGHT.br_startoff,
- RIGHT.br_startblock,
- RIGHT.br_blockcount, &i)))
- goto done;
- ASSERT(i == 1);
- if ((error = xfs_bmbt_update(cur, new->br_startoff,
- new->br_startblock,
- new->br_blockcount +
- RIGHT.br_blockcount,
- RIGHT.br_state)))
- goto done;
- }
- temp = XFS_FILBLKS_MIN(xfs_bmap_worst_indlen(ip, temp),
- STARTBLOCKVAL(PREV.br_startblock));
- xfs_bmbt_set_startblock(ep, NULLSTARTBLOCK((int)temp));
- xfs_bmap_trace_post_update(fname, "RF|RC", ip, idx,
- XFS_DATA_FORK);
- *dnew = temp;
- /* DELTA: The boundary between two in-core extents moved. */
- temp = PREV.br_startoff;
- temp2 = PREV.br_blockcount +
- RIGHT.br_blockcount;
- break;
-
- case MASK(RIGHT_FILLING):
- /*
- * Filling in the last part of a previous delayed allocation.
- * The right neighbor is not contiguous.
- */
- temp = PREV.br_blockcount - new->br_blockcount;
- xfs_bmap_trace_pre_update(fname, "RF", ip, idx, XFS_DATA_FORK);
- xfs_bmbt_set_blockcount(ep, temp);
- xfs_bmap_trace_insert(fname, "RF", ip, idx + 1, 1,
- new, NULL, XFS_DATA_FORK);
- xfs_iext_insert(ifp, idx + 1, 1, new);
- ip->i_df.if_lastex = idx + 1;
- ip->i_d.di_nextents++;
- if (cur == NULL)
- rval = XFS_ILOG_CORE | XFS_ILOG_DEXT;
- else {
- rval = XFS_ILOG_CORE;
- if ((error = xfs_bmbt_lookup_eq(cur, new->br_startoff,
- new->br_startblock, new->br_blockcount,
- &i)))
- goto done;
- ASSERT(i == 0);
- cur->bc_rec.b.br_state = XFS_EXT_NORM;
- if ((error = xfs_bmbt_insert(cur, &i)))
- goto done;
- ASSERT(i == 1);
- }
- if (ip->i_d.di_format == XFS_DINODE_FMT_EXTENTS &&
- ip->i_d.di_nextents > ip->i_df.if_ext_max) {
- error = xfs_bmap_extents_to_btree(ip->i_transp, ip,
- first, flist, &cur, 1, &tmp_rval,
- XFS_DATA_FORK);
- rval |= tmp_rval;
- if (error)
- goto done;
- }
- temp = XFS_FILBLKS_MIN(xfs_bmap_worst_indlen(ip, temp),
- STARTBLOCKVAL(PREV.br_startblock) -
- (cur ? cur->bc_private.b.allocated : 0));
- ep = xfs_iext_get_ext(ifp, idx);
- xfs_bmbt_set_startblock(ep, NULLSTARTBLOCK((int)temp));
- xfs_bmap_trace_post_update(fname, "RF", ip, idx, XFS_DATA_FORK);
- *dnew = temp;
- /* DELTA: One in-core extent is split in two. */
- temp = PREV.br_startoff;
- temp2 = PREV.br_blockcount;
- break;
-
- case 0:
- /*
- * Filling in the middle part of a previous delayed allocation.
- * Contiguity is impossible here.
- * This case is avoided almost all the time.
- */
- temp = new->br_startoff - PREV.br_startoff;
- xfs_bmap_trace_pre_update(fname, "0", ip, idx, XFS_DATA_FORK);
- xfs_bmbt_set_blockcount(ep, temp);
- r[0] = *new;
- r[1].br_startoff = new_endoff;
- temp2 = PREV.br_startoff + PREV.br_blockcount - new_endoff;
- r[1].br_blockcount = temp2;
- xfs_bmap_trace_insert(fname, "0", ip, idx + 1, 2, &r[0], &r[1],
- XFS_DATA_FORK);
- xfs_iext_insert(ifp, idx + 1, 2, &r[0]);
- ip->i_df.if_lastex = idx + 1;
- ip->i_d.di_nextents++;
- if (cur == NULL)
- rval = XFS_ILOG_CORE | XFS_ILOG_DEXT;
- else {
- rval = XFS_ILOG_CORE;
- if ((error = xfs_bmbt_lookup_eq(cur, new->br_startoff,
- new->br_startblock, new->br_blockcount,
- &i)))
- goto done;
- ASSERT(i == 0);
- cur->bc_rec.b.br_state = XFS_EXT_NORM;
- if ((error = xfs_bmbt_insert(cur, &i)))
- goto done;
- ASSERT(i == 1);
- }
- if (ip->i_d.di_format == XFS_DINODE_FMT_EXTENTS &&
- ip->i_d.di_nextents > ip->i_df.if_ext_max) {
- error = xfs_bmap_extents_to_btree(ip->i_transp, ip,
- first, flist, &cur, 1, &tmp_rval,
- XFS_DATA_FORK);
- rval |= tmp_rval;
- if (error)
- goto done;
- }
- temp = xfs_bmap_worst_indlen(ip, temp);
- temp2 = xfs_bmap_worst_indlen(ip, temp2);
- diff = (int)(temp + temp2 - STARTBLOCKVAL(PREV.br_startblock) -
- (cur ? cur->bc_private.b.allocated : 0));
- if (diff > 0 &&
- xfs_mod_incore_sb(ip->i_mount, XFS_SBS_FDBLOCKS, -diff, rsvd)) {
- /*
- * Ick gross gag me with a spoon.
- */
- ASSERT(0); /* want to see if this ever happens! */
- while (diff > 0) {
- if (temp) {
- temp--;
- diff--;
- if (!diff ||
- !xfs_mod_incore_sb(ip->i_mount,
- XFS_SBS_FDBLOCKS, -diff, rsvd))
- break;
- }
- if (temp2) {
- temp2--;
- diff--;
- if (!diff ||
- !xfs_mod_incore_sb(ip->i_mount,
- XFS_SBS_FDBLOCKS, -diff, rsvd))
- break;
- }
- }
- }
- ep = xfs_iext_get_ext(ifp, idx);
- xfs_bmbt_set_startblock(ep, NULLSTARTBLOCK((int)temp));
- xfs_bmap_trace_post_update(fname, "0", ip, idx, XFS_DATA_FORK);
- xfs_bmap_trace_pre_update(fname, "0", ip, idx + 2,
- XFS_DATA_FORK);
- xfs_bmbt_set_startblock(xfs_iext_get_ext(ifp, idx + 2),
- NULLSTARTBLOCK((int)temp2));
- xfs_bmap_trace_post_update(fname, "0", ip, idx + 2,
- XFS_DATA_FORK);
- *dnew = temp + temp2;
- /* DELTA: One in-core extent is split in three. */
- temp = PREV.br_startoff;
- temp2 = PREV.br_blockcount;
- break;
-
- case MASK3(LEFT_FILLING, LEFT_CONTIG, RIGHT_CONTIG):
- case MASK3(RIGHT_FILLING, LEFT_CONTIG, RIGHT_CONTIG):
- case MASK2(LEFT_FILLING, RIGHT_CONTIG):
- case MASK2(RIGHT_FILLING, LEFT_CONTIG):
- case MASK2(LEFT_CONTIG, RIGHT_CONTIG):
- case MASK(LEFT_CONTIG):
- case MASK(RIGHT_CONTIG):
- /*
- * These cases are all impossible.
- */
- ASSERT(0);
- }
- *curp = cur;
- if (delta) {
- temp2 += temp;
- if (delta->xed_startoff > temp)
- delta->xed_startoff = temp;
- if (delta->xed_blockcount < temp2)
- delta->xed_blockcount = temp2;
- }
-done:
- *logflagsp = rval;
- return error;
-#undef LEFT
-#undef RIGHT
-#undef PREV
-#undef MASK
-#undef MASK2
-#undef MASK3
-#undef MASK4
-#undef STATE_SET
-#undef STATE_TEST
-#undef STATE_SET_TEST
-#undef SWITCH_STATE
-}
-
-/*
- * Called by xfs_bmap_add_extent to handle cases converting an unwritten
- * allocation to a real allocation or vice versa.
- */
-STATIC int /* error */
-xfs_bmap_add_extent_unwritten_real(
- xfs_inode_t *ip, /* incore inode pointer */
- xfs_extnum_t idx, /* extent number to update/insert */
- xfs_btree_cur_t **curp, /* if *curp is null, not a btree */
- xfs_bmbt_irec_t *new, /* new data to add to file extents */
- int *logflagsp, /* inode logging flags */
- xfs_extdelta_t *delta) /* Change made to incore extents */
-{
- xfs_btree_cur_t *cur; /* btree cursor */
- xfs_bmbt_rec_t *ep; /* extent entry for idx */
- int error; /* error return value */
-#ifdef XFS_BMAP_TRACE
- static char fname[] = "xfs_bmap_add_extent_unwritten_real";
-#endif
- int i; /* temp state */
- xfs_ifork_t *ifp; /* inode fork pointer */
- xfs_fileoff_t new_endoff; /* end offset of new entry */
- xfs_exntst_t newext; /* new extent state */
- xfs_exntst_t oldext; /* old extent state */
- xfs_bmbt_irec_t r[3]; /* neighbor extent entries */
- /* left is 0, right is 1, prev is 2 */
- int rval=0; /* return value (logging flags) */
- int state = 0;/* state bits, accessed thru macros */
- xfs_filblks_t temp=0;
- xfs_filblks_t temp2=0;
- enum { /* bit number definitions for state */
- LEFT_CONTIG, RIGHT_CONTIG,
- LEFT_FILLING, RIGHT_FILLING,
- LEFT_DELAY, RIGHT_DELAY,
- LEFT_VALID, RIGHT_VALID
- };
-
-#define LEFT r[0]
-#define RIGHT r[1]
-#define PREV r[2]
-#define MASK(b) (1 << (b))
-#define MASK2(a,b) (MASK(a) | MASK(b))
-#define MASK3(a,b,c) (MASK2(a,b) | MASK(c))
-#define MASK4(a,b,c,d) (MASK3(a,b,c) | MASK(d))
-#define STATE_SET(b,v) ((v) ? (state |= MASK(b)) : (state &= ~MASK(b)))
-#define STATE_TEST(b) (state & MASK(b))
-#define STATE_SET_TEST(b,v) ((v) ? ((state |= MASK(b)), 1) : \
- ((state &= ~MASK(b)), 0))
-#define SWITCH_STATE \
- (state & MASK4(LEFT_FILLING, RIGHT_FILLING, LEFT_CONTIG, RIGHT_CONTIG))
-
- /*
- * Set up a bunch of variables to make the tests simpler.
- */
- error = 0;
- cur = *curp;
- ifp = XFS_IFORK_PTR(ip, XFS_DATA_FORK);
- ep = xfs_iext_get_ext(ifp, idx);
- xfs_bmbt_get_all(ep, &PREV);
- newext = new->br_state;
- oldext = (newext == XFS_EXT_UNWRITTEN) ?
- XFS_EXT_NORM : XFS_EXT_UNWRITTEN;
- ASSERT(PREV.br_state == oldext);
- new_endoff = new->br_startoff + new->br_blockcount;
- ASSERT(PREV.br_startoff <= new->br_startoff);
- ASSERT(PREV.br_startoff + PREV.br_blockcount >= new_endoff);
- /*
- * Set flags determining what part of the previous oldext allocation
- * extent is being replaced by a newext allocation.
- */
- STATE_SET(LEFT_FILLING, PREV.br_startoff == new->br_startoff);
- STATE_SET(RIGHT_FILLING,
- PREV.br_startoff + PREV.br_blockcount == new_endoff);
- /*
- * Check and set flags if this segment has a left neighbor.
- * Don't set contiguous if the combined extent would be too large.
- */
- if (STATE_SET_TEST(LEFT_VALID, idx > 0)) {
- xfs_bmbt_get_all(xfs_iext_get_ext(ifp, idx - 1), &LEFT);
- STATE_SET(LEFT_DELAY, ISNULLSTARTBLOCK(LEFT.br_startblock));
- }
- STATE_SET(LEFT_CONTIG,
- STATE_TEST(LEFT_VALID) && !STATE_TEST(LEFT_DELAY) &&
- LEFT.br_startoff + LEFT.br_blockcount == new->br_startoff &&
- LEFT.br_startblock + LEFT.br_blockcount == new->br_startblock &&
- LEFT.br_state == newext &&
- LEFT.br_blockcount + new->br_blockcount <= MAXEXTLEN);
- /*
- * Check and set flags if this segment has a right neighbor.
- * Don't set contiguous if the combined extent would be too large.
- * Also check for all-three-contiguous being too large.
- */
- if (STATE_SET_TEST(RIGHT_VALID,
- idx <
- ip->i_df.if_bytes / (uint)sizeof(xfs_bmbt_rec_t) - 1)) {
- xfs_bmbt_get_all(xfs_iext_get_ext(ifp, idx + 1), &RIGHT);
- STATE_SET(RIGHT_DELAY, ISNULLSTARTBLOCK(RIGHT.br_startblock));
- }
- STATE_SET(RIGHT_CONTIG,
- STATE_TEST(RIGHT_VALID) && !STATE_TEST(RIGHT_DELAY) &&
- new_endoff == RIGHT.br_startoff &&
- new->br_startblock + new->br_blockcount ==
- RIGHT.br_startblock &&
- newext == RIGHT.br_state &&
- new->br_blockcount + RIGHT.br_blockcount <= MAXEXTLEN &&
- ((state & MASK3(LEFT_CONTIG, LEFT_FILLING, RIGHT_FILLING)) !=
- MASK3(LEFT_CONTIG, LEFT_FILLING, RIGHT_FILLING) ||
- LEFT.br_blockcount + new->br_blockcount + RIGHT.br_blockcount
- <= MAXEXTLEN));
- /*
- * Switch out based on the FILLING and CONTIG state bits.
- */
- switch (SWITCH_STATE) {
-
- case MASK4(LEFT_FILLING, RIGHT_FILLING, LEFT_CONTIG, RIGHT_CONTIG):
- /*
- * Setting all of a previous oldext extent to newext.
- * The left and right neighbors are both contiguous with new.
- */
- xfs_bmap_trace_pre_update(fname, "LF|RF|LC|RC", ip, idx - 1,
- XFS_DATA_FORK);
- xfs_bmbt_set_blockcount(xfs_iext_get_ext(ifp, idx - 1),
- LEFT.br_blockcount + PREV.br_blockcount +
- RIGHT.br_blockcount);
- xfs_bmap_trace_post_update(fname, "LF|RF|LC|RC", ip, idx - 1,
- XFS_DATA_FORK);
- xfs_bmap_trace_delete(fname, "LF|RF|LC|RC", ip, idx, 2,
- XFS_DATA_FORK);
- xfs_iext_remove(ifp, idx, 2);
- ip->i_df.if_lastex = idx - 1;
- ip->i_d.di_nextents -= 2;
- if (cur == NULL)
- rval = XFS_ILOG_CORE | XFS_ILOG_DEXT;
- else {
- rval = XFS_ILOG_CORE;
- if ((error = xfs_bmbt_lookup_eq(cur, RIGHT.br_startoff,
- RIGHT.br_startblock,
- RIGHT.br_blockcount, &i)))
- goto done;
- ASSERT(i == 1);
- if ((error = xfs_bmbt_delete(cur, &i)))
- goto done;
- ASSERT(i == 1);
- if ((error = xfs_bmbt_decrement(cur, 0, &i)))
- goto done;
- ASSERT(i == 1);
- if ((error = xfs_bmbt_delete(cur, &i)))
- goto done;
- ASSERT(i == 1);
- if ((error = xfs_bmbt_decrement(cur, 0, &i)))
- goto done;
- ASSERT(i == 1);
- if ((error = xfs_bmbt_update(cur, LEFT.br_startoff,
- LEFT.br_startblock,
- LEFT.br_blockcount + PREV.br_blockcount +
- RIGHT.br_blockcount, LEFT.br_state)))
- goto done;
- }
- /* DELTA: Three in-core extents are replaced by one. */
- temp = LEFT.br_startoff;
- temp2 = LEFT.br_blockcount +
- PREV.br_blockcount +
- RIGHT.br_blockcount;
- break;
-
- case MASK3(LEFT_FILLING, RIGHT_FILLING, LEFT_CONTIG):
- /*
- * Setting all of a previous oldext extent to newext.
- * The left neighbor is contiguous, the right is not.
- */
- xfs_bmap_trace_pre_update(fname, "LF|RF|LC", ip, idx - 1,
- XFS_DATA_FORK);
- xfs_bmbt_set_blockcount(xfs_iext_get_ext(ifp, idx - 1),
- LEFT.br_blockcount + PREV.br_blockcount);
- xfs_bmap_trace_post_update(fname, "LF|RF|LC", ip, idx - 1,
- XFS_DATA_FORK);
- ip->i_df.if_lastex = idx - 1;
- xfs_bmap_trace_delete(fname, "LF|RF|LC", ip, idx, 1,
- XFS_DATA_FORK);
- xfs_iext_remove(ifp, idx, 1);
- ip->i_d.di_nextents--;
- if (cur == NULL)
- rval = XFS_ILOG_CORE | XFS_ILOG_DEXT;
- else {
- rval = XFS_ILOG_CORE;
- if ((error = xfs_bmbt_lookup_eq(cur, PREV.br_startoff,
- PREV.br_startblock, PREV.br_blockcount,
- &i)))
- goto done;
- ASSERT(i == 1);
- if ((error = xfs_bmbt_delete(cur, &i)))
- goto done;
- ASSERT(i == 1);
- if ((error = xfs_bmbt_decrement(cur, 0, &i)))
- goto done;
- ASSERT(i == 1);
- if ((error = xfs_bmbt_update(cur, LEFT.br_startoff,
- LEFT.br_startblock,
- LEFT.br_blockcount + PREV.br_blockcount,
- LEFT.br_state)))
- goto done;
- }
- /* DELTA: Two in-core extents are replaced by one. */
- temp = LEFT.br_startoff;
- temp2 = LEFT.br_blockcount +
- PREV.br_blockcount;
- break;
-
- case MASK3(LEFT_FILLING, RIGHT_FILLING, RIGHT_CONTIG):
- /*
- * Setting all of a previous oldext extent to newext.
- * The right neighbor is contiguous, the left is not.
- */
- xfs_bmap_trace_pre_update(fname, "LF|RF|RC", ip, idx,
- XFS_DATA_FORK);
- xfs_bmbt_set_blockcount(ep,
- PREV.br_blockcount + RIGHT.br_blockcount);
- xfs_bmbt_set_state(ep, newext);
- xfs_bmap_trace_post_update(fname, "LF|RF|RC", ip, idx,
- XFS_DATA_FORK);
- ip->i_df.if_lastex = idx;
- xfs_bmap_trace_delete(fname, "LF|RF|RC", ip, idx + 1, 1,
- XFS_DATA_FORK);
- xfs_iext_remove(ifp, idx + 1, 1);
- ip->i_d.di_nextents--;
- if (cur == NULL)
- rval = XFS_ILOG_CORE | XFS_ILOG_DEXT;
- else {
- rval = XFS_ILOG_CORE;
- if ((error = xfs_bmbt_lookup_eq(cur, RIGHT.br_startoff,
- RIGHT.br_startblock,
- RIGHT.br_blockcount, &i)))
- goto done;
- ASSERT(i == 1);
- if ((error = xfs_bmbt_delete(cur, &i)))
- goto done;
- ASSERT(i == 1);
- if ((error = xfs_bmbt_decrement(cur, 0, &i)))
- goto done;
- ASSERT(i == 1);
- if ((error = xfs_bmbt_update(cur, new->br_startoff,
- new->br_startblock,
- new->br_blockcount + RIGHT.br_blockcount,
- newext)))
- goto done;
- }
- /* DELTA: Two in-core extents are replaced by one. */
- temp = PREV.br_startoff;
- temp2 = PREV.br_blockcount +
- RIGHT.br_blockcount;
- break;
-
- case MASK2(LEFT_FILLING, RIGHT_FILLING):
- /*
- * Setting all of a previous oldext extent to newext.
- * Neither the left nor right neighbors are contiguous with
- * the new one.
- */
- xfs_bmap_trace_pre_update(fname, "LF|RF", ip, idx,
- XFS_DATA_FORK);
- xfs_bmbt_set_state(ep, newext);
- xfs_bmap_trace_post_update(fname, "LF|RF", ip, idx,
- XFS_DATA_FORK);
- ip->i_df.if_lastex = idx;
- if (cur == NULL)
- rval = XFS_ILOG_DEXT;
- else {
- rval = 0;
- if ((error = xfs_bmbt_lookup_eq(cur, new->br_startoff,
- new->br_startblock, new->br_blockcount,
- &i)))
- goto done;
- ASSERT(i == 1);
- if ((error = xfs_bmbt_update(cur, new->br_startoff,
- new->br_startblock, new->br_blockcount,
- newext)))
- goto done;
- }
- /* DELTA: The in-core extent described by new changed type. */
- temp = new->br_startoff;
- temp2 = new->br_blockcount;
- break;
-
- case MASK2(LEFT_FILLING, LEFT_CONTIG):
- /*
- * Setting the first part of a previous oldext extent to newext.
- * The left neighbor is contiguous.
- */
- xfs_bmap_trace_pre_update(fname, "LF|LC", ip, idx - 1,
- XFS_DATA_FORK);
- xfs_bmbt_set_blockcount(xfs_iext_get_ext(ifp, idx - 1),
- LEFT.br_blockcount + new->br_blockcount);
- xfs_bmbt_set_startoff(ep,
- PREV.br_startoff + new->br_blockcount);
- xfs_bmap_trace_post_update(fname, "LF|LC", ip, idx - 1,
- XFS_DATA_FORK);
- xfs_bmap_trace_pre_update(fname, "LF|LC", ip, idx,
- XFS_DATA_FORK);
- xfs_bmbt_set_startblock(ep,
- new->br_startblock + new->br_blockcount);
- xfs_bmbt_set_blockcount(ep,
- PREV.br_blockcount - new->br_blockcount);
- xfs_bmap_trace_post_update(fname, "LF|LC", ip, idx,
- XFS_DATA_FORK);
- ip->i_df.if_lastex = idx - 1;
- if (cur == NULL)
- rval = XFS_ILOG_DEXT;
- else {
- rval = 0;
- if ((error = xfs_bmbt_lookup_eq(cur, PREV.br_startoff,
- PREV.br_startblock, PREV.br_blockcount,
- &i)))
- goto done;
- ASSERT(i == 1);
- if ((error = xfs_bmbt_update(cur,
- PREV.br_startoff + new->br_blockcount,
- PREV.br_startblock + new->br_blockcount,
- PREV.br_blockcount - new->br_blockcount,
- oldext)))
- goto done;
- if ((error = xfs_bmbt_decrement(cur, 0, &i)))
- goto done;
- if (xfs_bmbt_update(cur, LEFT.br_startoff,
- LEFT.br_startblock,
- LEFT.br_blockcount + new->br_blockcount,
- LEFT.br_state))
- goto done;
- }
- /* DELTA: The boundary between two in-core extents moved. */
- temp = LEFT.br_startoff;
- temp2 = LEFT.br_blockcount +
- PREV.br_blockcount;
- break;
-
- case MASK(LEFT_FILLING):
- /*
- * Setting the first part of a previous oldext extent to newext.
- * The left neighbor is not contiguous.
- */
- xfs_bmap_trace_pre_update(fname, "LF", ip, idx, XFS_DATA_FORK);
- ASSERT(ep && xfs_bmbt_get_state(ep) == oldext);
- xfs_bmbt_set_startoff(ep, new_endoff);
- xfs_bmbt_set_blockcount(ep,
- PREV.br_blockcount - new->br_blockcount);
- xfs_bmbt_set_startblock(ep,
- new->br_startblock + new->br_blockcount);
- xfs_bmap_trace_post_update(fname, "LF", ip, idx, XFS_DATA_FORK);
- xfs_bmap_trace_insert(fname, "LF", ip, idx, 1, new, NULL,
- XFS_DATA_FORK);
- xfs_iext_insert(ifp, idx, 1, new);
- ip->i_df.if_lastex = idx;
- ip->i_d.di_nextents++;
- if (cur == NULL)
- rval = XFS_ILOG_CORE | XFS_ILOG_DEXT;
- else {
- rval = XFS_ILOG_CORE;
- if ((error = xfs_bmbt_lookup_eq(cur, PREV.br_startoff,
- PREV.br_startblock, PREV.br_blockcount,
- &i)))
- goto done;
- ASSERT(i == 1);
- if ((error = xfs_bmbt_update(cur,
- PREV.br_startoff + new->br_blockcount,
- PREV.br_startblock + new->br_blockcount,
- PREV.br_blockcount - new->br_blockcount,
- oldext)))
- goto done;
- cur->bc_rec.b = *new;
- if ((error = xfs_bmbt_insert(cur, &i)))
- goto done;
- ASSERT(i == 1);
- }
- /* DELTA: One in-core extent is split in two. */
- temp = PREV.br_startoff;
- temp2 = PREV.br_blockcount;
- break;
-
- case MASK2(RIGHT_FILLING, RIGHT_CONTIG):
- /*
- * Setting the last part of a previous oldext extent to newext.
- * The right neighbor is contiguous with the new allocation.
- */
- xfs_bmap_trace_pre_update(fname, "RF|RC", ip, idx,
- XFS_DATA_FORK);
- xfs_bmap_trace_pre_update(fname, "RF|RC", ip, idx + 1,
- XFS_DATA_FORK);
- xfs_bmbt_set_blockcount(ep,
- PREV.br_blockcount - new->br_blockcount);
- xfs_bmap_trace_post_update(fname, "RF|RC", ip, idx,
- XFS_DATA_FORK);
- xfs_bmbt_set_allf(xfs_iext_get_ext(ifp, idx + 1),
- new->br_startoff, new->br_startblock,
- new->br_blockcount + RIGHT.br_blockcount, newext);
- xfs_bmap_trace_post_update(fname, "RF|RC", ip, idx + 1,
- XFS_DATA_FORK);
- ip->i_df.if_lastex = idx + 1;
- if (cur == NULL)
- rval = XFS_ILOG_DEXT;
- else {
- rval = 0;
- if ((error = xfs_bmbt_lookup_eq(cur, PREV.br_startoff,
- PREV.br_startblock,
- PREV.br_blockcount, &i)))
- goto done;
- ASSERT(i == 1);
- if ((error = xfs_bmbt_update(cur, PREV.br_startoff,
- PREV.br_startblock,
- PREV.br_blockcount - new->br_blockcount,
- oldext)))
- goto done;
- if ((error = xfs_bmbt_increment(cur, 0, &i)))
- goto done;
- if ((error = xfs_bmbt_update(cur, new->br_startoff,
- new->br_startblock,
- new->br_blockcount + RIGHT.br_blockcount,
- newext)))
- goto done;
- }
- /* DELTA: The boundary between two in-core extents moved. */
- temp = PREV.br_startoff;
- temp2 = PREV.br_blockcount +
- RIGHT.br_blockcount;
- break;
-
- case MASK(RIGHT_FILLING):
- /*
- * Setting the last part of a previous oldext extent to newext.
- * The right neighbor is not contiguous.
- */
- xfs_bmap_trace_pre_update(fname, "RF", ip, idx, XFS_DATA_FORK);
- xfs_bmbt_set_blockcount(ep,
- PREV.br_blockcount - new->br_blockcount);
- xfs_bmap_trace_post_update(fname, "RF", ip, idx, XFS_DATA_FORK);
- xfs_bmap_trace_insert(fname, "RF", ip, idx + 1, 1,
- new, NULL, XFS_DATA_FORK);
- xfs_iext_insert(ifp, idx + 1, 1, new);
- ip->i_df.if_lastex = idx + 1;
- ip->i_d.di_nextents++;
- if (cur == NULL)
- rval = XFS_ILOG_CORE | XFS_ILOG_DEXT;
- else {
- rval = XFS_ILOG_CORE;
- if ((error = xfs_bmbt_lookup_eq(cur, PREV.br_startoff,
- PREV.br_startblock, PREV.br_blockcount,
- &i)))
- goto done;
- ASSERT(i == 1);
- if ((error = xfs_bmbt_update(cur, PREV.br_startoff,
- PREV.br_startblock,
- PREV.br_blockcount - new->br_blockcount,
- oldext)))
- goto done;
- if ((error = xfs_bmbt_lookup_eq(cur, new->br_startoff,
- new->br_startblock, new->br_blockcount,
- &i)))
- goto done;
- ASSERT(i == 0);
- cur->bc_rec.b.br_state = XFS_EXT_NORM;
- if ((error = xfs_bmbt_insert(cur, &i)))
- goto done;
- ASSERT(i == 1);
- }
- /* DELTA: One in-core extent is split in two. */
- temp = PREV.br_startoff;
- temp2 = PREV.br_blockcount;
- break;
-
- case 0:
- /*
- * Setting the middle part of a previous oldext extent to
- * newext. Contiguity is impossible here.
- * One extent becomes three extents.
- */
- xfs_bmap_trace_pre_update(fname, "0", ip, idx, XFS_DATA_FORK);
- xfs_bmbt_set_blockcount(ep,
- new->br_startoff - PREV.br_startoff);
- xfs_bmap_trace_post_update(fname, "0", ip, idx, XFS_DATA_FORK);
- r[0] = *new;
- r[1].br_startoff = new_endoff;
- r[1].br_blockcount =
- PREV.br_startoff + PREV.br_blockcount - new_endoff;
- r[1].br_startblock = new->br_startblock + new->br_blockcount;
- r[1].br_state = oldext;
- xfs_bmap_trace_insert(fname, "0", ip, idx + 1, 2, &r[0], &r[1],
- XFS_DATA_FORK);
- xfs_iext_insert(ifp, idx + 1, 2, &r[0]);
- ip->i_df.if_lastex = idx + 1;
- ip->i_d.di_nextents += 2;
- if (cur == NULL)
- rval = XFS_ILOG_CORE | XFS_ILOG_DEXT;
- else {
- rval = XFS_ILOG_CORE;
- if ((error = xfs_bmbt_lookup_eq(cur, PREV.br_startoff,
- PREV.br_startblock, PREV.br_blockcount,
- &i)))
- goto done;
- ASSERT(i == 1);
- /* new right extent - oldext */
- if ((error = xfs_bmbt_update(cur, r[1].br_startoff,
- r[1].br_startblock, r[1].br_blockcount,
- r[1].br_state)))
- goto done;
- /* new left extent - oldext */
- PREV.br_blockcount =
- new->br_startoff - PREV.br_startoff;
- cur->bc_rec.b = PREV;
- if ((error = xfs_bmbt_insert(cur, &i)))
- goto done;
- ASSERT(i == 1);
- if ((error = xfs_bmbt_increment(cur, 0, &i)))
- goto done;
- ASSERT(i == 1);
- /* new middle extent - newext */
- cur->bc_rec.b = *new;
- if ((error = xfs_bmbt_insert(cur, &i)))
- goto done;
- ASSERT(i == 1);
- }
- /* DELTA: One in-core extent is split in three. */
- temp = PREV.br_startoff;
- temp2 = PREV.br_blockcount;
- break;
-
- case MASK3(LEFT_FILLING, LEFT_CONTIG, RIGHT_CONTIG):
- case MASK3(RIGHT_FILLING, LEFT_CONTIG, RIGHT_CONTIG):
- case MASK2(LEFT_FILLING, RIGHT_CONTIG):
- case MASK2(RIGHT_FILLING, LEFT_CONTIG):
- case MASK2(LEFT_CONTIG, RIGHT_CONTIG):
- case MASK(LEFT_CONTIG):
- case MASK(RIGHT_CONTIG):
- /*
- * These cases are all impossible.
- */
- ASSERT(0);
- }
- *curp = cur;
- if (delta) {
- temp2 += temp;
- if (delta->xed_startoff > temp)
- delta->xed_startoff = temp;
- if (delta->xed_blockcount < temp2)
- delta->xed_blockcount = temp2;
- }
-done:
- *logflagsp = rval;
- return error;
-#undef LEFT
-#undef RIGHT
-#undef PREV
-#undef MASK
-#undef MASK2
-#undef MASK3
-#undef MASK4
-#undef STATE_SET
-#undef STATE_TEST
-#undef STATE_SET_TEST
-#undef SWITCH_STATE
-}
-
-/*
- * Called by xfs_bmap_add_extent to handle cases converting a hole
- * to a delayed allocation.
- */
-/*ARGSUSED*/
-STATIC int /* error */
-xfs_bmap_add_extent_hole_delay(
- xfs_inode_t *ip, /* incore inode pointer */
- xfs_extnum_t idx, /* extent number to update/insert */
- xfs_btree_cur_t *cur, /* if null, not a btree */
- xfs_bmbt_irec_t *new, /* new data to add to file extents */
- int *logflagsp, /* inode logging flags */
- xfs_extdelta_t *delta, /* Change made to incore extents */
- int rsvd) /* OK to allocate reserved blocks */
-{
- xfs_bmbt_rec_t *ep; /* extent record for idx */
-#ifdef XFS_BMAP_TRACE
- static char fname[] = "xfs_bmap_add_extent_hole_delay";
-#endif
- xfs_ifork_t *ifp; /* inode fork pointer */
- xfs_bmbt_irec_t left; /* left neighbor extent entry */
- xfs_filblks_t newlen=0; /* new indirect size */
- xfs_filblks_t oldlen=0; /* old indirect size */
- xfs_bmbt_irec_t right; /* right neighbor extent entry */
- int state; /* state bits, accessed thru macros */
- xfs_filblks_t temp=0; /* temp for indirect calculations */
- xfs_filblks_t temp2=0;
- enum { /* bit number definitions for state */
- LEFT_CONTIG, RIGHT_CONTIG,
- LEFT_DELAY, RIGHT_DELAY,
- LEFT_VALID, RIGHT_VALID
- };
-
-#define MASK(b) (1 << (b))
-#define MASK2(a,b) (MASK(a) | MASK(b))
-#define STATE_SET(b,v) ((v) ? (state |= MASK(b)) : (state &= ~MASK(b)))
-#define STATE_TEST(b) (state & MASK(b))
-#define STATE_SET_TEST(b,v) ((v) ? ((state |= MASK(b)), 1) : \
- ((state &= ~MASK(b)), 0))
-#define SWITCH_STATE (state & MASK2(LEFT_CONTIG, RIGHT_CONTIG))
-
- ifp = XFS_IFORK_PTR(ip, XFS_DATA_FORK);
- ep = xfs_iext_get_ext(ifp, idx);
- state = 0;
- ASSERT(ISNULLSTARTBLOCK(new->br_startblock));
- /*
- * Check and set flags if this segment has a left neighbor
- */
- if (STATE_SET_TEST(LEFT_VALID, idx > 0)) {
- xfs_bmbt_get_all(xfs_iext_get_ext(ifp, idx - 1), &left);
- STATE_SET(LEFT_DELAY, ISNULLSTARTBLOCK(left.br_startblock));
- }
- /*
- * Check and set flags if the current (right) segment exists.
- * If it doesn't exist, we're converting the hole at end-of-file.
- */
- if (STATE_SET_TEST(RIGHT_VALID,
- idx <
- ip->i_df.if_bytes / (uint)sizeof(xfs_bmbt_rec_t))) {
- xfs_bmbt_get_all(ep, &right);
- STATE_SET(RIGHT_DELAY, ISNULLSTARTBLOCK(right.br_startblock));
- }
- /*
- * Set contiguity flags on the left and right neighbors.
- * Don't let extents get too large, even if the pieces are contiguous.
- */
- STATE_SET(LEFT_CONTIG,
- STATE_TEST(LEFT_VALID) && STATE_TEST(LEFT_DELAY) &&
- left.br_startoff + left.br_blockcount == new->br_startoff &&
- left.br_blockcount + new->br_blockcount <= MAXEXTLEN);
- STATE_SET(RIGHT_CONTIG,
- STATE_TEST(RIGHT_VALID) && STATE_TEST(RIGHT_DELAY) &&
- new->br_startoff + new->br_blockcount == right.br_startoff &&
- new->br_blockcount + right.br_blockcount <= MAXEXTLEN &&
- (!STATE_TEST(LEFT_CONTIG) ||
- (left.br_blockcount + new->br_blockcount +
- right.br_blockcount <= MAXEXTLEN)));
- /*
- * Switch out based on the contiguity flags.
- */
- switch (SWITCH_STATE) {
-
- case MASK2(LEFT_CONTIG, RIGHT_CONTIG):
- /*
- * New allocation is contiguous with delayed allocations
- * on the left and on the right.
- * Merge all three into a single extent record.
- */
- temp = left.br_blockcount + new->br_blockcount +
- right.br_blockcount;
- xfs_bmap_trace_pre_update(fname, "LC|RC", ip, idx - 1,
- XFS_DATA_FORK);
- xfs_bmbt_set_blockcount(xfs_iext_get_ext(ifp, idx - 1), temp);
- oldlen = STARTBLOCKVAL(left.br_startblock) +
- STARTBLOCKVAL(new->br_startblock) +
- STARTBLOCKVAL(right.br_startblock);
- newlen = xfs_bmap_worst_indlen(ip, temp);
- xfs_bmbt_set_startblock(xfs_iext_get_ext(ifp, idx - 1),
- NULLSTARTBLOCK((int)newlen));
- xfs_bmap_trace_post_update(fname, "LC|RC", ip, idx - 1,
- XFS_DATA_FORK);
- xfs_bmap_trace_delete(fname, "LC|RC", ip, idx, 1,
- XFS_DATA_FORK);
- xfs_iext_remove(ifp, idx, 1);
- ip->i_df.if_lastex = idx - 1;
- /* DELTA: Two in-core extents were replaced by one. */
- temp2 = temp;
- temp = left.br_startoff;
- break;
-
- case MASK(LEFT_CONTIG):
- /*
- * New allocation is contiguous with a delayed allocation
- * on the left.
- * Merge the new allocation with the left neighbor.
- */
- temp = left.br_blockcount + new->br_blockcount;
- xfs_bmap_trace_pre_update(fname, "LC", ip, idx - 1,
- XFS_DATA_FORK);
- xfs_bmbt_set_blockcount(xfs_iext_get_ext(ifp, idx - 1), temp);
- oldlen = STARTBLOCKVAL(left.br_startblock) +
- STARTBLOCKVAL(new->br_startblock);
- newlen = xfs_bmap_worst_indlen(ip, temp);
- xfs_bmbt_set_startblock(xfs_iext_get_ext(ifp, idx - 1),
- NULLSTARTBLOCK((int)newlen));
- xfs_bmap_trace_post_update(fname, "LC", ip, idx - 1,
- XFS_DATA_FORK);
- ip->i_df.if_lastex = idx - 1;
- /* DELTA: One in-core extent grew into a hole. */
- temp2 = temp;
- temp = left.br_startoff;
- break;
-
- case MASK(RIGHT_CONTIG):
- /*
- * New allocation is contiguous with a delayed allocation
- * on the right.
- * Merge the new allocation with the right neighbor.
- */
- xfs_bmap_trace_pre_update(fname, "RC", ip, idx, XFS_DATA_FORK);
- temp = new->br_blockcount + right.br_blockcount;
- oldlen = STARTBLOCKVAL(new->br_startblock) +
- STARTBLOCKVAL(right.br_startblock);
- newlen = xfs_bmap_worst_indlen(ip, temp);
- xfs_bmbt_set_allf(ep, new->br_startoff,
- NULLSTARTBLOCK((int)newlen), temp, right.br_state);
- xfs_bmap_trace_post_update(fname, "RC", ip, idx, XFS_DATA_FORK);
- ip->i_df.if_lastex = idx;
- /* DELTA: One in-core extent grew into a hole. */
- temp2 = temp;
- temp = new->br_startoff;
- break;
-
- case 0:
- /*
- * New allocation is not contiguous with another
- * delayed allocation.
- * Insert a new entry.
- */
- oldlen = newlen = 0;
- xfs_bmap_trace_insert(fname, "0", ip, idx, 1, new, NULL,
- XFS_DATA_FORK);
- xfs_iext_insert(ifp, idx, 1, new);
- ip->i_df.if_lastex = idx;
- /* DELTA: A new in-core extent was added in a hole. */
- temp2 = new->br_blockcount;
- temp = new->br_startoff;
- break;
- }
- if (oldlen != newlen) {
- ASSERT(oldlen > newlen);
- xfs_mod_incore_sb(ip->i_mount, XFS_SBS_FDBLOCKS,
- (int)(oldlen - newlen), rsvd);
- /*
- * Nothing to do for disk quota accounting here.
- */
- }
- if (delta) {
- temp2 += temp;
- if (delta->xed_startoff > temp)
- delta->xed_startoff = temp;
- if (delta->xed_blockcount < temp2)
- delta->xed_blockcount = temp2;
- }
- *logflagsp = 0;
- return 0;
-#undef MASK
-#undef MASK2
-#undef STATE_SET
-#undef STATE_TEST
-#undef STATE_SET_TEST
-#undef SWITCH_STATE
-}
-
-/*
- * Called by xfs_bmap_add_extent to handle cases converting a hole
- * to a real allocation.
- */
-STATIC int /* error */
-xfs_bmap_add_extent_hole_real(
- xfs_inode_t *ip, /* incore inode pointer */
- xfs_extnum_t idx, /* extent number to update/insert */
- xfs_btree_cur_t *cur, /* if null, not a btree */
- xfs_bmbt_irec_t *new, /* new data to add to file extents */
- int *logflagsp, /* inode logging flags */
- xfs_extdelta_t *delta, /* Change made to incore extents */
- int whichfork) /* data or attr fork */
-{
- xfs_bmbt_rec_t *ep; /* pointer to extent entry ins. point */
- int error; /* error return value */
-#ifdef XFS_BMAP_TRACE
- static char fname[] = "xfs_bmap_add_extent_hole_real";
-#endif
- int i; /* temp state */
- xfs_ifork_t *ifp; /* inode fork pointer */
- xfs_bmbt_irec_t left; /* left neighbor extent entry */
- xfs_bmbt_irec_t right; /* right neighbor extent entry */
- int rval=0; /* return value (logging flags) */
- int state; /* state bits, accessed thru macros */
- xfs_filblks_t temp=0;
- xfs_filblks_t temp2=0;
- enum { /* bit number definitions for state */
- LEFT_CONTIG, RIGHT_CONTIG,
- LEFT_DELAY, RIGHT_DELAY,
- LEFT_VALID, RIGHT_VALID
- };
-
-#define MASK(b) (1 << (b))
-#define MASK2(a,b) (MASK(a) | MASK(b))
-#define STATE_SET(b,v) ((v) ? (state |= MASK(b)) : (state &= ~MASK(b)))
-#define STATE_TEST(b) (state & MASK(b))
-#define STATE_SET_TEST(b,v) ((v) ? ((state |= MASK(b)), 1) : \
- ((state &= ~MASK(b)), 0))
-#define SWITCH_STATE (state & MASK2(LEFT_CONTIG, RIGHT_CONTIG))
-
- ifp = XFS_IFORK_PTR(ip, whichfork);
- ASSERT(idx <= ifp->if_bytes / (uint)sizeof(xfs_bmbt_rec_t));
- ep = xfs_iext_get_ext(ifp, idx);
- state = 0;
- /*
- * Check and set flags if this segment has a left neighbor.
- */
- if (STATE_SET_TEST(LEFT_VALID, idx > 0)) {
- xfs_bmbt_get_all(xfs_iext_get_ext(ifp, idx - 1), &left);
- STATE_SET(LEFT_DELAY, ISNULLSTARTBLOCK(left.br_startblock));
- }
- /*
- * Check and set flags if this segment has a current value.
- * Not true if we're inserting into the "hole" at eof.
- */
- if (STATE_SET_TEST(RIGHT_VALID,
- idx <
- ifp->if_bytes / (uint)sizeof(xfs_bmbt_rec_t))) {
- xfs_bmbt_get_all(ep, &right);
- STATE_SET(RIGHT_DELAY, ISNULLSTARTBLOCK(right.br_startblock));
- }
- /*
- * We're inserting a real allocation between "left" and "right".
- * Set the contiguity flags. Don't let extents get too large.
- */
- STATE_SET(LEFT_CONTIG,
- STATE_TEST(LEFT_VALID) && !STATE_TEST(LEFT_DELAY) &&
- left.br_startoff + left.br_blockcount == new->br_startoff &&
- left.br_startblock + left.br_blockcount == new->br_startblock &&
- left.br_state == new->br_state &&
- left.br_blockcount + new->br_blockcount <= MAXEXTLEN);
- STATE_SET(RIGHT_CONTIG,
- STATE_TEST(RIGHT_VALID) && !STATE_TEST(RIGHT_DELAY) &&
- new->br_startoff + new->br_blockcount == right.br_startoff &&
- new->br_startblock + new->br_blockcount ==
- right.br_startblock &&
- new->br_state == right.br_state &&
- new->br_blockcount + right.br_blockcount <= MAXEXTLEN &&
- (!STATE_TEST(LEFT_CONTIG) ||
- left.br_blockcount + new->br_blockcount +
- right.br_blockcount <= MAXEXTLEN));
-
- error = 0;
- /*
- * Select which case we're in here, and implement it.
- */
- switch (SWITCH_STATE) {
-
- case MASK2(LEFT_CONTIG, RIGHT_CONTIG):
- /*
- * New allocation is contiguous with real allocations on the
- * left and on the right.
- * Merge all three into a single extent record.
- */
- xfs_bmap_trace_pre_update(fname, "LC|RC", ip, idx - 1,
- whichfork);
- xfs_bmbt_set_blockcount(xfs_iext_get_ext(ifp, idx - 1),
- left.br_blockcount + new->br_blockcount +
- right.br_blockcount);
- xfs_bmap_trace_post_update(fname, "LC|RC", ip, idx - 1,
- whichfork);
- xfs_bmap_trace_delete(fname, "LC|RC", ip,
- idx, 1, whichfork);
- xfs_iext_remove(ifp, idx, 1);
- ifp->if_lastex = idx - 1;
- XFS_IFORK_NEXT_SET(ip, whichfork,
- XFS_IFORK_NEXTENTS(ip, whichfork) - 1);
- if (cur == NULL) {
- rval = XFS_ILOG_CORE | XFS_ILOG_FEXT(whichfork);
- } else {
- rval = XFS_ILOG_CORE;
- if ((error = xfs_bmbt_lookup_eq(cur,
- right.br_startoff,
- right.br_startblock,
- right.br_blockcount, &i)))
- goto done;
- ASSERT(i == 1);
- if ((error = xfs_bmbt_delete(cur, &i)))
- goto done;
- ASSERT(i == 1);
- if ((error = xfs_bmbt_decrement(cur, 0, &i)))
- goto done;
- ASSERT(i == 1);
- if ((error = xfs_bmbt_update(cur, left.br_startoff,
- left.br_startblock,
- left.br_blockcount +
- new->br_blockcount +
- right.br_blockcount,
- left.br_state)))
- goto done;
- }
- /* DELTA: Two in-core extents were replaced by one. */
- temp = left.br_startoff;
- temp2 = left.br_blockcount +
- new->br_blockcount +
- right.br_blockcount;
- break;
-
- case MASK(LEFT_CONTIG):
- /*
- * New allocation is contiguous with a real allocation
- * on the left.
- * Merge the new allocation with the left neighbor.
- */
- xfs_bmap_trace_pre_update(fname, "LC", ip, idx - 1, whichfork);
- xfs_bmbt_set_blockcount(xfs_iext_get_ext(ifp, idx - 1),
- left.br_blockcount + new->br_blockcount);
- xfs_bmap_trace_post_update(fname, "LC", ip, idx - 1, whichfork);
- ifp->if_lastex = idx - 1;
- if (cur == NULL) {
- rval = XFS_ILOG_FEXT(whichfork);
- } else {
- rval = 0;
- if ((error = xfs_bmbt_lookup_eq(cur,
- left.br_startoff,
- left.br_startblock,
- left.br_blockcount, &i)))
- goto done;
- ASSERT(i == 1);
- if ((error = xfs_bmbt_update(cur, left.br_startoff,
- left.br_startblock,
- left.br_blockcount +
- new->br_blockcount,
- left.br_state)))
- goto done;
- }
- /* DELTA: One in-core extent grew. */
- temp = left.br_startoff;
- temp2 = left.br_blockcount +
- new->br_blockcount;
- break;
-
- case MASK(RIGHT_CONTIG):
- /*
- * New allocation is contiguous with a real allocation
- * on the right.
- * Merge the new allocation with the right neighbor.
- */
- xfs_bmap_trace_pre_update(fname, "RC", ip, idx, whichfork);
- xfs_bmbt_set_allf(ep, new->br_startoff, new->br_startblock,
- new->br_blockcount + right.br_blockcount,
- right.br_state);
- xfs_bmap_trace_post_update(fname, "RC", ip, idx, whichfork);
- ifp->if_lastex = idx;
- if (cur == NULL) {
- rval = XFS_ILOG_FEXT(whichfork);
- } else {
- rval = 0;
- if ((error = xfs_bmbt_lookup_eq(cur,
- right.br_startoff,
- right.br_startblock,
- right.br_blockcount, &i)))
- goto done;
- ASSERT(i == 1);
- if ((error = xfs_bmbt_update(cur, new->br_startoff,
- new->br_startblock,
- new->br_blockcount +
- right.br_blockcount,
- right.br_state)))
- goto done;
- }
- /* DELTA: One in-core extent grew. */
- temp = new->br_startoff;
- temp2 = new->br_blockcount +
- right.br_blockcount;
- break;
-
- case 0:
- /*
- * New allocation is not contiguous with another
- * real allocation.
- * Insert a new entry.
- */
- xfs_bmap_trace_insert(fname, "0", ip, idx, 1, new, NULL,
- whichfork);
- xfs_iext_insert(ifp, idx, 1, new);
- ifp->if_lastex = idx;
- XFS_IFORK_NEXT_SET(ip, whichfork,
- XFS_IFORK_NEXTENTS(ip, whichfork) + 1);
- if (cur == NULL) {
- rval = XFS_ILOG_CORE | XFS_ILOG_FEXT(whichfork);
- } else {
- rval = XFS_ILOG_CORE;
- if ((error = xfs_bmbt_lookup_eq(cur,
- new->br_startoff,
- new->br_startblock,
- new->br_blockcount, &i)))
- goto done;
- ASSERT(i == 0);
- cur->bc_rec.b.br_state = new->br_state;
- if ((error = xfs_bmbt_insert(cur, &i)))
- goto done;
- ASSERT(i == 1);
- }
- /* DELTA: A new extent was added in a hole. */
- temp = new->br_startoff;
- temp2 = new->br_blockcount;
- break;
- }
- if (delta) {
- temp2 += temp;
- if (delta->xed_startoff > temp)
- delta->xed_startoff = temp;
- if (delta->xed_blockcount < temp2)
- delta->xed_blockcount = temp2;
- }
-done:
- *logflagsp = rval;
- return error;
-#undef MASK
-#undef MASK2
-#undef STATE_SET
-#undef STATE_TEST
-#undef STATE_SET_TEST
-#undef SWITCH_STATE
-}
-
-/*
- * Adjust the size of the new extent based on di_extsize and rt extsize.
- */
-STATIC int
-xfs_bmap_extsize_align(
- xfs_mount_t *mp,
- xfs_bmbt_irec_t *gotp, /* next extent pointer */
- xfs_bmbt_irec_t *prevp, /* previous extent pointer */
- xfs_extlen_t extsz, /* align to this extent size */
- int rt, /* is this a realtime inode? */
- int eof, /* is extent at end-of-file? */
- int delay, /* creating delalloc extent? */
- int convert, /* overwriting unwritten extent? */
- xfs_fileoff_t *offp, /* in/out: aligned offset */
- xfs_extlen_t *lenp) /* in/out: aligned length */
-{
- xfs_fileoff_t orig_off; /* original offset */
- xfs_extlen_t orig_alen; /* original length */
- xfs_fileoff_t orig_end; /* original off+len */
- xfs_fileoff_t nexto; /* next file offset */
- xfs_fileoff_t prevo; /* previous file offset */
- xfs_fileoff_t align_off; /* temp for offset */
- xfs_extlen_t align_alen; /* temp for length */
- xfs_extlen_t temp; /* temp for calculations */
-
- if (convert)
- return 0;
-
- orig_off = align_off = *offp;
- orig_alen = align_alen = *lenp;
- orig_end = orig_off + orig_alen;
-
- /*
- * If this request overlaps an existing extent, then don't
- * attempt to perform any additional alignment.
- */
- if (!delay && !eof &&
- (orig_off >= gotp->br_startoff) &&
- (orig_end <= gotp->br_startoff + gotp->br_blockcount)) {
- return 0;
- }
-
- /*
- * If the file offset is unaligned vs. the extent size
- * we need to align it. This will be possible unless
- * the file was previously written with a kernel that didn't
- * perform this alignment, or if a truncate shot us in the
- * foot.
- */
- temp = do_mod(orig_off, extsz);
- if (temp) {
- align_alen += temp;
- align_off -= temp;
- }
- /*
- * Same adjustment for the end of the requested area.
- */
- if ((temp = (align_alen % extsz))) {
- align_alen += extsz - temp;
- }
- /*
- * If the previous block overlaps with this proposed allocation
- * then move the start forward without adjusting the length.
- */
- if (prevp->br_startoff != NULLFILEOFF) {
- if (prevp->br_startblock == HOLESTARTBLOCK)
- prevo = prevp->br_startoff;
- else
- prevo = prevp->br_startoff + prevp->br_blockcount;
- } else
- prevo = 0;
- if (align_off != orig_off && align_off < prevo)
- align_off = prevo;
- /*
- * If the next block overlaps with this proposed allocation
- * then move the start back without adjusting the length,
- * but not before offset 0.
- * This may of course make the start overlap previous block,
- * and if we hit the offset 0 limit then the next block
- * can still overlap too.
- */
- if (!eof && gotp->br_startoff != NULLFILEOFF) {
- if ((delay && gotp->br_startblock == HOLESTARTBLOCK) ||
- (!delay && gotp->br_startblock == DELAYSTARTBLOCK))
- nexto = gotp->br_startoff + gotp->br_blockcount;
- else
- nexto = gotp->br_startoff;
- } else
- nexto = NULLFILEOFF;
- if (!eof &&
- align_off + align_alen != orig_end &&
- align_off + align_alen > nexto)
- align_off = nexto > align_alen ? nexto - align_alen : 0;
- /*
- * If we're now overlapping the next or previous extent that
- * means we can't fit an extsz piece in this hole. Just move
- * the start forward to the first valid spot and set
- * the length so we hit the end.
- */
- if (align_off != orig_off && align_off < prevo)
- align_off = prevo;
- if (align_off + align_alen != orig_end &&
- align_off + align_alen > nexto &&
- nexto != NULLFILEOFF) {
- ASSERT(nexto > prevo);
- align_alen = nexto - align_off;
- }
-
- /*
- * If realtime, and the result isn't a multiple of the realtime
- * extent size we need to remove blocks until it is.
- */
- if (rt && (temp = (align_alen % mp->m_sb.sb_rextsize))) {
- /*
- * We're not covering the original request, or
- * we won't be able to once we fix the length.
- */
- if (orig_off < align_off ||
- orig_end > align_off + align_alen ||
- align_alen - temp < orig_alen)
- return XFS_ERROR(EINVAL);
- /*
- * Try to fix it by moving the start up.
- */
- if (align_off + temp <= orig_off) {
- align_alen -= temp;
- align_off += temp;
- }
- /*
- * Try to fix it by moving the end in.
- */
- else if (align_off + align_alen - temp >= orig_end)
- align_alen -= temp;
- /*
- * Set the start to the minimum then trim the length.
- */
- else {
- align_alen -= orig_off - align_off;
- align_off = orig_off;
- align_alen -= align_alen % mp->m_sb.sb_rextsize;
- }
- /*
- * Result doesn't cover the request, fail it.
- */
- if (orig_off < align_off || orig_end > align_off + align_alen)
- return XFS_ERROR(EINVAL);
- } else {
- ASSERT(orig_off >= align_off);
- ASSERT(orig_end <= align_off + align_alen);
- }
-
-#ifdef DEBUG
- if (!eof && gotp->br_startoff != NULLFILEOFF)
- ASSERT(align_off + align_alen <= gotp->br_startoff);
- if (prevp->br_startoff != NULLFILEOFF)
- ASSERT(align_off >= prevp->br_startoff + prevp->br_blockcount);
-#endif
-
- *lenp = align_alen;
- *offp = align_off;
- return 0;
-}
-
-#define XFS_ALLOC_GAP_UNITS 4
-
-STATIC int
-xfs_bmap_adjacent(
- xfs_bmalloca_t *ap) /* bmap alloc argument struct */
-{
- xfs_fsblock_t adjust; /* adjustment to block numbers */
- xfs_agnumber_t fb_agno; /* ag number of ap->firstblock */
- xfs_mount_t *mp; /* mount point structure */
- int nullfb; /* true if ap->firstblock isn't set */
- int rt; /* true if inode is realtime */
-
-#define ISVALID(x,y) \
- (rt ? \
- (x) < mp->m_sb.sb_rblocks : \
- XFS_FSB_TO_AGNO(mp, x) == XFS_FSB_TO_AGNO(mp, y) && \
- XFS_FSB_TO_AGNO(mp, x) < mp->m_sb.sb_agcount && \
- XFS_FSB_TO_AGBNO(mp, x) < mp->m_sb.sb_agblocks)
-
- mp = ap->ip->i_mount;
- nullfb = ap->firstblock == NULLFSBLOCK;
- rt = XFS_IS_REALTIME_INODE(ap->ip) && ap->userdata;
- fb_agno = nullfb ? NULLAGNUMBER : XFS_FSB_TO_AGNO(mp, ap->firstblock);
- /*
- * If allocating at eof, and there's a previous real block,
- * try to use it's last block as our starting point.
- */
- if (ap->eof && ap->prevp->br_startoff != NULLFILEOFF &&
- !ISNULLSTARTBLOCK(ap->prevp->br_startblock) &&
- ISVALID(ap->prevp->br_startblock + ap->prevp->br_blockcount,
- ap->prevp->br_startblock)) {
- ap->rval = ap->prevp->br_startblock + ap->prevp->br_blockcount;
- /*
- * Adjust for the gap between prevp and us.
- */
- adjust = ap->off -
- (ap->prevp->br_startoff + ap->prevp->br_blockcount);
- if (adjust &&
- ISVALID(ap->rval + adjust, ap->prevp->br_startblock))
- ap->rval += adjust;
- }
- /*
- * If not at eof, then compare the two neighbor blocks.
- * Figure out whether either one gives us a good starting point,
- * and pick the better one.
- */
- else if (!ap->eof) {
- xfs_fsblock_t gotbno; /* right side block number */
- xfs_fsblock_t gotdiff=0; /* right side difference */
- xfs_fsblock_t prevbno; /* left side block number */
- xfs_fsblock_t prevdiff=0; /* left side difference */
-
- /*
- * If there's a previous (left) block, select a requested
- * start block based on it.
- */
- if (ap->prevp->br_startoff != NULLFILEOFF &&
- !ISNULLSTARTBLOCK(ap->prevp->br_startblock) &&
- (prevbno = ap->prevp->br_startblock +
- ap->prevp->br_blockcount) &&
- ISVALID(prevbno, ap->prevp->br_startblock)) {
- /*
- * Calculate gap to end of previous block.
- */
- adjust = prevdiff = ap->off -
- (ap->prevp->br_startoff +
- ap->prevp->br_blockcount);
- /*
- * Figure the startblock based on the previous block's
- * end and the gap size.
- * Heuristic!
- * If the gap is large relative to the piece we're
- * allocating, or using it gives us an invalid block
- * number, then just use the end of the previous block.
- */
- if (prevdiff <= XFS_ALLOC_GAP_UNITS * ap->alen &&
- ISVALID(prevbno + prevdiff,
- ap->prevp->br_startblock))
- prevbno += adjust;
- else
- prevdiff += adjust;
- /*
- * If the firstblock forbids it, can't use it,
- * must use default.
- */
- if (!rt && !nullfb &&
- XFS_FSB_TO_AGNO(mp, prevbno) != fb_agno)
- prevbno = NULLFSBLOCK;
- }
- /*
- * No previous block or can't follow it, just default.
- */
- else
- prevbno = NULLFSBLOCK;
- /*
- * If there's a following (right) block, select a requested
- * start block based on it.
- */
- if (!ISNULLSTARTBLOCK(ap->gotp->br_startblock)) {
- /*
- * Calculate gap to start of next block.
- */
- adjust = gotdiff = ap->gotp->br_startoff - ap->off;
- /*
- * Figure the startblock based on the next block's
- * start and the gap size.
- */
- gotbno = ap->gotp->br_startblock;
- /*
- * Heuristic!
- * If the gap is large relative to the piece we're
- * allocating, or using it gives us an invalid block
- * number, then just use the start of the next block
- * offset by our length.
- */
- if (gotdiff <= XFS_ALLOC_GAP_UNITS * ap->alen &&
- ISVALID(gotbno - gotdiff, gotbno))
- gotbno -= adjust;
- else if (ISVALID(gotbno - ap->alen, gotbno)) {
- gotbno -= ap->alen;
- gotdiff += adjust - ap->alen;
- } else
- gotdiff += adjust;
- /*
- * If the firstblock forbids it, can't use it,
- * must use default.
- */
- if (!rt && !nullfb &&
- XFS_FSB_TO_AGNO(mp, gotbno) != fb_agno)
- gotbno = NULLFSBLOCK;
- }
- /*
- * No next block, just default.
- */
- else
- gotbno = NULLFSBLOCK;
- /*
- * If both valid, pick the better one, else the only good
- * one, else ap->rval is already set (to 0 or the inode block).
- */
- if (prevbno != NULLFSBLOCK && gotbno != NULLFSBLOCK)
- ap->rval = prevdiff <= gotdiff ? prevbno : gotbno;
- else if (prevbno != NULLFSBLOCK)
- ap->rval = prevbno;
- else if (gotbno != NULLFSBLOCK)
- ap->rval = gotbno;
- }
-#undef ISVALID
- return 0;
-}
-
-STATIC int
-xfs_bmap_rtalloc(
- xfs_bmalloca_t *ap) /* bmap alloc argument struct */
-{
- xfs_alloctype_t atype = 0; /* type for allocation routines */
- int error; /* error return value */
- xfs_mount_t *mp; /* mount point structure */
- xfs_extlen_t prod = 0; /* product factor for allocators */
- xfs_extlen_t ralen = 0; /* realtime allocation length */
- xfs_extlen_t align; /* minimum allocation alignment */
- xfs_rtblock_t rtx; /* realtime extent number */
- xfs_rtblock_t rtb;
-
- mp = ap->ip->i_mount;
- align = ap->ip->i_d.di_extsize ?
- ap->ip->i_d.di_extsize : mp->m_sb.sb_rextsize;
- prod = align / mp->m_sb.sb_rextsize;
- error = xfs_bmap_extsize_align(mp, ap->gotp, ap->prevp,
- align, 1, ap->eof, 0,
- ap->conv, &ap->off, &ap->alen);
- if (error)
- return error;
- ASSERT(ap->alen);
- ASSERT(ap->alen % mp->m_sb.sb_rextsize == 0);
-
- /*
- * If the offset & length are not perfectly aligned
- * then kill prod, it will just get us in trouble.
- */
- if (do_mod(ap->off, align) || ap->alen % align)
- prod = 1;
- /*
- * Set ralen to be the actual requested length in rtextents.
- */
- ralen = ap->alen / mp->m_sb.sb_rextsize;
- /*
- * If the old value was close enough to MAXEXTLEN that
- * we rounded up to it, cut it back so it's valid again.
- * Note that if it's a really large request (bigger than
- * MAXEXTLEN), we don't hear about that number, and can't
- * adjust the starting point to match it.
- */
- if (ralen * mp->m_sb.sb_rextsize >= MAXEXTLEN)
- ralen = MAXEXTLEN / mp->m_sb.sb_rextsize;
- /*
- * If it's an allocation to an empty file at offset 0,
- * pick an extent that will space things out in the rt area.
- */
- if (ap->eof && ap->off == 0) {
- error = xfs_rtpick_extent(mp, ap->tp, ralen, &rtx);
- if (error)
- return error;
- ap->rval = rtx * mp->m_sb.sb_rextsize;
- } else {
- ap->rval = 0;
- }
-
- xfs_bmap_adjacent(ap);
-
- /*
- * Realtime allocation, done through xfs_rtallocate_extent.
- */
- atype = ap->rval == 0 ? XFS_ALLOCTYPE_ANY_AG : XFS_ALLOCTYPE_NEAR_BNO;
- do_div(ap->rval, mp->m_sb.sb_rextsize);
- rtb = ap->rval;
- ap->alen = ralen;
- if ((error = xfs_rtallocate_extent(ap->tp, ap->rval, 1, ap->alen,
- &ralen, atype, ap->wasdel, prod, &rtb)))
- return error;
- if (rtb == NULLFSBLOCK && prod > 1 &&
- (error = xfs_rtallocate_extent(ap->tp, ap->rval, 1,
- ap->alen, &ralen, atype,
- ap->wasdel, 1, &rtb)))
- return error;
- ap->rval = rtb;
- if (ap->rval != NULLFSBLOCK) {
- ap->rval *= mp->m_sb.sb_rextsize;
- ralen *= mp->m_sb.sb_rextsize;
- ap->alen = ralen;
- ap->ip->i_d.di_nblocks += ralen;
- xfs_trans_log_inode(ap->tp, ap->ip, XFS_ILOG_CORE);
- if (ap->wasdel)
- ap->ip->i_delayed_blks -= ralen;
- /*
- * Adjust the disk quota also. This was reserved
- * earlier.
- */
- XFS_TRANS_MOD_DQUOT_BYINO(mp, ap->tp, ap->ip,
- ap->wasdel ? XFS_TRANS_DQ_DELRTBCOUNT :
- XFS_TRANS_DQ_RTBCOUNT, (long) ralen);
- } else {
- ap->alen = 0;
- }
- return 0;
-}
-
-STATIC int
-xfs_bmap_btalloc(
- xfs_bmalloca_t *ap) /* bmap alloc argument struct */
-{
- xfs_mount_t *mp; /* mount point structure */
- xfs_alloctype_t atype = 0; /* type for allocation routines */
- xfs_extlen_t align; /* minimum allocation alignment */
- xfs_agnumber_t ag;
- xfs_agnumber_t fb_agno; /* ag number of ap->firstblock */
- xfs_agnumber_t startag;
- xfs_alloc_arg_t args;
- xfs_extlen_t blen;
- xfs_extlen_t delta;
- xfs_extlen_t longest;
- xfs_extlen_t need;
- xfs_extlen_t nextminlen = 0;
- xfs_perag_t *pag;
- int nullfb; /* true if ap->firstblock isn't set */
- int isaligned;
- int notinit;
- int tryagain;
- int error;
-
- mp = ap->ip->i_mount;
- align = (ap->userdata && ap->ip->i_d.di_extsize &&
- (ap->ip->i_d.di_flags & XFS_DIFLAG_EXTSIZE)) ?
- ap->ip->i_d.di_extsize : 0;
- if (unlikely(align)) {
- error = xfs_bmap_extsize_align(mp, ap->gotp, ap->prevp,
- align, 0, ap->eof, 0, ap->conv,
- &ap->off, &ap->alen);
- ASSERT(!error);
- ASSERT(ap->alen);
- }
- nullfb = ap->firstblock == NULLFSBLOCK;
- fb_agno = nullfb ? NULLAGNUMBER : XFS_FSB_TO_AGNO(mp, ap->firstblock);
- if (nullfb)
- ap->rval = XFS_INO_TO_FSB(mp, ap->ip->i_ino);
- else
- ap->rval = ap->firstblock;
-
- xfs_bmap_adjacent(ap);
-
- /*
- * If allowed, use ap->rval; otherwise must use firstblock since
- * it's in the right allocation group.
- */
- if (nullfb || XFS_FSB_TO_AGNO(mp, ap->rval) == fb_agno)
- ;
- else
- ap->rval = ap->firstblock;
- /*
- * Normal allocation, done through xfs_alloc_vextent.
- */
- tryagain = isaligned = 0;
- args.tp = ap->tp;
- args.mp = mp;
- args.fsbno = ap->rval;
- args.maxlen = MIN(ap->alen, mp->m_sb.sb_agblocks);
- blen = 0;
- if (nullfb) {
- args.type = XFS_ALLOCTYPE_START_BNO;
- args.total = ap->total;
- /*
- * Find the longest available space.
- * We're going to try for the whole allocation at once.
- */
- startag = ag = XFS_FSB_TO_AGNO(mp, args.fsbno);
- notinit = 0;
- down_read(&mp->m_peraglock);
- while (blen < ap->alen) {
- pag = &mp->m_perag[ag];
- if (!pag->pagf_init &&
- (error = xfs_alloc_pagf_init(mp, args.tp,
- ag, XFS_ALLOC_FLAG_TRYLOCK))) {
- up_read(&mp->m_peraglock);
- return error;
- }
- /*
- * See xfs_alloc_fix_freelist...
- */
- if (pag->pagf_init) {
- need = XFS_MIN_FREELIST_PAG(pag, mp);
- delta = need > pag->pagf_flcount ?
- need - pag->pagf_flcount : 0;
- longest = (pag->pagf_longest > delta) ?
- (pag->pagf_longest - delta) :
- (pag->pagf_flcount > 0 ||
- pag->pagf_longest > 0);
- if (blen < longest)
- blen = longest;
- } else
- notinit = 1;
- if (++ag == mp->m_sb.sb_agcount)
- ag = 0;
- if (ag == startag)
- break;
- }
- up_read(&mp->m_peraglock);
- /*
- * Since the above loop did a BUF_TRYLOCK, it is
- * possible that there is space for this request.
- */
- if (notinit || blen < ap->minlen)
- args.minlen = ap->minlen;
- /*
- * If the best seen length is less than the request
- * length, use the best as the minimum.
- */
- else if (blen < ap->alen)
- args.minlen = blen;
- /*
- * Otherwise we've seen an extent as big as alen,
- * use that as the minimum.
- */
- else
- args.minlen = ap->alen;
- } else if (ap->low) {
- args.type = XFS_ALLOCTYPE_FIRST_AG;
- args.total = args.minlen = ap->minlen;
- } else {
- args.type = XFS_ALLOCTYPE_NEAR_BNO;
- args.total = ap->total;
- args.minlen = ap->minlen;
- }
- if (unlikely(ap->userdata && ap->ip->i_d.di_extsize &&
- (ap->ip->i_d.di_flags & XFS_DIFLAG_EXTSIZE))) {
- args.prod = ap->ip->i_d.di_extsize;
- if ((args.mod = (xfs_extlen_t)do_mod(ap->off, args.prod)))
- args.mod = (xfs_extlen_t)(args.prod - args.mod);
- } else if (unlikely(mp->m_sb.sb_blocksize >= NBPP)) {
- args.prod = 1;
- args.mod = 0;
- } else {
- args.prod = NBPP >> mp->m_sb.sb_blocklog;
- if ((args.mod = (xfs_extlen_t)(do_mod(ap->off, args.prod))))
- args.mod = (xfs_extlen_t)(args.prod - args.mod);
- }
- /*
- * If we are not low on available data blocks, and the
- * underlying logical volume manager is a stripe, and
- * the file offset is zero then try to allocate data
- * blocks on stripe unit boundary.
- * NOTE: ap->aeof is only set if the allocation length
- * is >= the stripe unit and the allocation offset is
- * at the end of file.
- */
- if (!ap->low && ap->aeof) {
- if (!ap->off) {
- args.alignment = mp->m_dalign;
- atype = args.type;
- isaligned = 1;
- /*
- * Adjust for alignment
- */
- if (blen > args.alignment && blen <= ap->alen)
- args.minlen = blen - args.alignment;
- args.minalignslop = 0;
- } else {
- /*
- * First try an exact bno allocation.
- * If it fails then do a near or start bno
- * allocation with alignment turned on.
- */
- atype = args.type;
- tryagain = 1;
- args.type = XFS_ALLOCTYPE_THIS_BNO;
- args.alignment = 1;
- /*
- * Compute the minlen+alignment for the
- * next case. Set slop so that the value
- * of minlen+alignment+slop doesn't go up
- * between the calls.
- */
- if (blen > mp->m_dalign && blen <= ap->alen)
- nextminlen = blen - mp->m_dalign;
- else
- nextminlen = args.minlen;
- if (nextminlen + mp->m_dalign > args.minlen + 1)
- args.minalignslop =
- nextminlen + mp->m_dalign -
- args.minlen - 1;
- else
- args.minalignslop = 0;
- }
- } else {
- args.alignment = 1;
- args.minalignslop = 0;
- }
- args.minleft = ap->minleft;
- args.wasdel = ap->wasdel;
- args.isfl = 0;
- args.userdata = ap->userdata;
- if ((error = xfs_alloc_vextent(&args)))
- return error;
- if (tryagain && args.fsbno == NULLFSBLOCK) {
- /*
- * Exact allocation failed. Now try with alignment
- * turned on.
- */
- args.type = atype;
- args.fsbno = ap->rval;
- args.alignment = mp->m_dalign;
- args.minlen = nextminlen;
- args.minalignslop = 0;
- isaligned = 1;
- if ((error = xfs_alloc_vextent(&args)))
- return error;
- }
- if (isaligned && args.fsbno == NULLFSBLOCK) {
- /*
- * allocation failed, so turn off alignment and
- * try again.
- */
- args.type = atype;
- args.fsbno = ap->rval;
- args.alignment = 0;
- if ((error = xfs_alloc_vextent(&args)))
- return error;
- }
- if (args.fsbno == NULLFSBLOCK && nullfb &&
- args.minlen > ap->minlen) {
- args.minlen = ap->minlen;
- args.type = XFS_ALLOCTYPE_START_BNO;
- args.fsbno = ap->rval;
- if ((error = xfs_alloc_vextent(&args)))
- return error;
- }
- if (args.fsbno == NULLFSBLOCK && nullfb) {
- args.fsbno = 0;
- args.type = XFS_ALLOCTYPE_FIRST_AG;
- args.total = ap->minlen;
- args.minleft = 0;
- if ((error = xfs_alloc_vextent(&args)))
- return error;
- ap->low = 1;
- }
- if (args.fsbno != NULLFSBLOCK) {
- ap->firstblock = ap->rval = args.fsbno;
- ASSERT(nullfb || fb_agno == args.agno ||
- (ap->low && fb_agno < args.agno));
- ap->alen = args.len;
- ap->ip->i_d.di_nblocks += args.len;
- xfs_trans_log_inode(ap->tp, ap->ip, XFS_ILOG_CORE);
- if (ap->wasdel)
- ap->ip->i_delayed_blks -= args.len;
- /*
- * Adjust the disk quota also. This was reserved
- * earlier.
- */
- XFS_TRANS_MOD_DQUOT_BYINO(mp, ap->tp, ap->ip,
- ap->wasdel ? XFS_TRANS_DQ_DELBCOUNT :
- XFS_TRANS_DQ_BCOUNT,
- (long) args.len);
- } else {
- ap->rval = NULLFSBLOCK;
- ap->alen = 0;
- }
- return 0;
-}
-
-/*
- * xfs_bmap_alloc is called by xfs_bmapi to allocate an extent for a file.
- * It figures out where to ask the underlying allocator to put the new extent.
- */
-STATIC int
-xfs_bmap_alloc(
- xfs_bmalloca_t *ap) /* bmap alloc argument struct */
-{
- if ((ap->ip->i_d.di_flags & XFS_DIFLAG_REALTIME) && ap->userdata)
- return xfs_bmap_rtalloc(ap);
- return xfs_bmap_btalloc(ap);
-}
-
-/*
- * Transform a btree format file with only one leaf node, where the
- * extents list will fit in the inode, into an extents format file.
- * Since the file extents are already in-core, all we have to do is
- * give up the space for the btree root and pitch the leaf block.
- */
-STATIC int /* error */
-xfs_bmap_btree_to_extents(
- xfs_trans_t *tp, /* transaction pointer */
- xfs_inode_t *ip, /* incore inode pointer */
- xfs_btree_cur_t *cur, /* btree cursor */
- int *logflagsp, /* inode logging flags */
- int whichfork) /* data or attr fork */
-{
- /* REFERENCED */
- xfs_bmbt_block_t *cblock;/* child btree block */
- xfs_fsblock_t cbno; /* child block number */
- xfs_buf_t *cbp; /* child block's buffer */
- int error; /* error return value */
- xfs_ifork_t *ifp; /* inode fork data */
- xfs_mount_t *mp; /* mount point structure */
- xfs_bmbt_ptr_t *pp; /* ptr to block address */
- xfs_bmbt_block_t *rblock;/* root btree block */
-
- ifp = XFS_IFORK_PTR(ip, whichfork);
- ASSERT(ifp->if_flags & XFS_IFEXTENTS);
- ASSERT(XFS_IFORK_FORMAT(ip, whichfork) == XFS_DINODE_FMT_BTREE);
- rblock = ifp->if_broot;
- ASSERT(be16_to_cpu(rblock->bb_level) == 1);
- ASSERT(be16_to_cpu(rblock->bb_numrecs) == 1);
- ASSERT(XFS_BMAP_BROOT_MAXRECS(ifp->if_broot_bytes) == 1);
- mp = ip->i_mount;
- pp = XFS_BMAP_BROOT_PTR_ADDR(rblock, 1, ifp->if_broot_bytes);
- *logflagsp = 0;
-#ifdef DEBUG
- if ((error = xfs_btree_check_lptr(cur, INT_GET(*pp, ARCH_CONVERT), 1)))
- return error;
-#endif
- cbno = INT_GET(*pp, ARCH_CONVERT);
- if ((error = xfs_btree_read_bufl(mp, tp, cbno, 0, &cbp,
- XFS_BMAP_BTREE_REF)))
- return error;
- cblock = XFS_BUF_TO_BMBT_BLOCK(cbp);
- if ((error = xfs_btree_check_lblock(cur, cblock, 0, cbp)))
- return error;
- xfs_bmap_add_free(cbno, 1, cur->bc_private.b.flist, mp);
- ip->i_d.di_nblocks--;
- XFS_TRANS_MOD_DQUOT_BYINO(mp, tp, ip, XFS_TRANS_DQ_BCOUNT, -1L);
- xfs_trans_binval(tp, cbp);
- if (cur->bc_bufs[0] == cbp)
- cur->bc_bufs[0] = NULL;
- xfs_iroot_realloc(ip, -1, whichfork);
- ASSERT(ifp->if_broot == NULL);
- ASSERT((ifp->if_flags & XFS_IFBROOT) == 0);
- XFS_IFORK_FMT_SET(ip, whichfork, XFS_DINODE_FMT_EXTENTS);
- *logflagsp = XFS_ILOG_CORE | XFS_ILOG_FEXT(whichfork);
- return 0;
-}
-
-/*
- * Called by xfs_bmapi to update file extent records and the btree
- * after removing space (or undoing a delayed allocation).
- */
-STATIC int /* error */
-xfs_bmap_del_extent(
- xfs_inode_t *ip, /* incore inode pointer */
- xfs_trans_t *tp, /* current transaction pointer */
- xfs_extnum_t idx, /* extent number to update/delete */
- xfs_bmap_free_t *flist, /* list of extents to be freed */
- xfs_btree_cur_t *cur, /* if null, not a btree */
- xfs_bmbt_irec_t *del, /* data to remove from extents */
- int *logflagsp, /* inode logging flags */
- xfs_extdelta_t *delta, /* Change made to incore extents */
- int whichfork, /* data or attr fork */
- int rsvd) /* OK to allocate reserved blocks */
-{
- xfs_filblks_t da_new; /* new delay-alloc indirect blocks */
- xfs_filblks_t da_old; /* old delay-alloc indirect blocks */
- xfs_fsblock_t del_endblock=0; /* first block past del */
- xfs_fileoff_t del_endoff; /* first offset past del */
- int delay; /* current block is delayed allocated */
- int do_fx; /* free extent at end of routine */
- xfs_bmbt_rec_t *ep; /* current extent entry pointer */
- int error; /* error return value */
- int flags; /* inode logging flags */
-#ifdef XFS_BMAP_TRACE
- static char fname[] = "xfs_bmap_del_extent";
-#endif
- xfs_bmbt_irec_t got; /* current extent entry */
- xfs_fileoff_t got_endoff; /* first offset past got */
- int i; /* temp state */
- xfs_ifork_t *ifp; /* inode fork pointer */
- xfs_mount_t *mp; /* mount structure */
- xfs_filblks_t nblks; /* quota/sb block count */
- xfs_bmbt_irec_t new; /* new record to be inserted */
- /* REFERENCED */
- uint qfield; /* quota field to update */
- xfs_filblks_t temp; /* for indirect length calculations */
- xfs_filblks_t temp2; /* for indirect length calculations */
-
- XFS_STATS_INC(xs_del_exlist);
- mp = ip->i_mount;
- ifp = XFS_IFORK_PTR(ip, whichfork);
- ASSERT((idx >= 0) && (idx < ifp->if_bytes /
- (uint)sizeof(xfs_bmbt_rec_t)));
- ASSERT(del->br_blockcount > 0);
- ep = xfs_iext_get_ext(ifp, idx);
- xfs_bmbt_get_all(ep, &got);
- ASSERT(got.br_startoff <= del->br_startoff);
- del_endoff = del->br_startoff + del->br_blockcount;
- got_endoff = got.br_startoff + got.br_blockcount;
- ASSERT(got_endoff >= del_endoff);
- delay = ISNULLSTARTBLOCK(got.br_startblock);
- ASSERT(ISNULLSTARTBLOCK(del->br_startblock) == delay);
- flags = 0;
- qfield = 0;
- error = 0;
- /*
- * If deleting a real allocation, must free up the disk space.
- */
- if (!delay) {
- flags = XFS_ILOG_CORE;
- /*
- * Realtime allocation. Free it and record di_nblocks update.
- */
- if (whichfork == XFS_DATA_FORK &&
- (ip->i_d.di_flags & XFS_DIFLAG_REALTIME)) {
- xfs_fsblock_t bno;
- xfs_filblks_t len;
-
- ASSERT(do_mod(del->br_blockcount,
- mp->m_sb.sb_rextsize) == 0);
- ASSERT(do_mod(del->br_startblock,
- mp->m_sb.sb_rextsize) == 0);
- bno = del->br_startblock;
- len = del->br_blockcount;
- do_div(bno, mp->m_sb.sb_rextsize);
- do_div(len, mp->m_sb.sb_rextsize);
- if ((error = xfs_rtfree_extent(ip->i_transp, bno,
- (xfs_extlen_t)len)))
- goto done;
- do_fx = 0;
- nblks = len * mp->m_sb.sb_rextsize;
- qfield = XFS_TRANS_DQ_RTBCOUNT;
- }
- /*
- * Ordinary allocation.
- */
- else {
- do_fx = 1;
- nblks = del->br_blockcount;
- qfield = XFS_TRANS_DQ_BCOUNT;
- }
- /*
- * Set up del_endblock and cur for later.
- */
- del_endblock = del->br_startblock + del->br_blockcount;
- if (cur) {
- if ((error = xfs_bmbt_lookup_eq(cur, got.br_startoff,
- got.br_startblock, got.br_blockcount,
- &i)))
- goto done;
- ASSERT(i == 1);
- }
- da_old = da_new = 0;
- } else {
- da_old = STARTBLOCKVAL(got.br_startblock);
- da_new = 0;
- nblks = 0;
- do_fx = 0;
- }
- /*
- * Set flag value to use in switch statement.
- * Left-contig is 2, right-contig is 1.
- */
- switch (((got.br_startoff == del->br_startoff) << 1) |
- (got_endoff == del_endoff)) {
- case 3:
- /*
- * Matches the whole extent. Delete the entry.
- */
- xfs_bmap_trace_delete(fname, "3", ip, idx, 1, whichfork);
- xfs_iext_remove(ifp, idx, 1);
- ifp->if_lastex = idx;
- if (delay)
- break;
- XFS_IFORK_NEXT_SET(ip, whichfork,
- XFS_IFORK_NEXTENTS(ip, whichfork) - 1);
- flags |= XFS_ILOG_CORE;
- if (!cur) {
- flags |= XFS_ILOG_FEXT(whichfork);
- break;
- }
- if ((error = xfs_bmbt_delete(cur, &i)))
- goto done;
- ASSERT(i == 1);
- break;
-
- case 2:
- /*
- * Deleting the first part of the extent.
- */
- xfs_bmap_trace_pre_update(fname, "2", ip, idx, whichfork);
- xfs_bmbt_set_startoff(ep, del_endoff);
- temp = got.br_blockcount - del->br_blockcount;
- xfs_bmbt_set_blockcount(ep, temp);
- ifp->if_lastex = idx;
- if (delay) {
- temp = XFS_FILBLKS_MIN(xfs_bmap_worst_indlen(ip, temp),
- da_old);
- xfs_bmbt_set_startblock(ep, NULLSTARTBLOCK((int)temp));
- xfs_bmap_trace_post_update(fname, "2", ip, idx,
- whichfork);
- da_new = temp;
- break;
- }
- xfs_bmbt_set_startblock(ep, del_endblock);
- xfs_bmap_trace_post_update(fname, "2", ip, idx, whichfork);
- if (!cur) {
- flags |= XFS_ILOG_FEXT(whichfork);
- break;
- }
- if ((error = xfs_bmbt_update(cur, del_endoff, del_endblock,
- got.br_blockcount - del->br_blockcount,
- got.br_state)))
- goto done;
- break;
-
- case 1:
- /*
- * Deleting the last part of the extent.
- */
- temp = got.br_blockcount - del->br_blockcount;
- xfs_bmap_trace_pre_update(fname, "1", ip, idx, whichfork);
- xfs_bmbt_set_blockcount(ep, temp);
- ifp->if_lastex = idx;
- if (delay) {
- temp = XFS_FILBLKS_MIN(xfs_bmap_worst_indlen(ip, temp),
- da_old);
- xfs_bmbt_set_startblock(ep, NULLSTARTBLOCK((int)temp));
- xfs_bmap_trace_post_update(fname, "1", ip, idx,
- whichfork);
- da_new = temp;
- break;
- }
- xfs_bmap_trace_post_update(fname, "1", ip, idx, whichfork);
- if (!cur) {
- flags |= XFS_ILOG_FEXT(whichfork);
- break;
- }
- if ((error = xfs_bmbt_update(cur, got.br_startoff,
- got.br_startblock,
- got.br_blockcount - del->br_blockcount,
- got.br_state)))
- goto done;
- break;
-
- case 0:
- /*
- * Deleting the middle of the extent.
- */
- temp = del->br_startoff - got.br_startoff;
- xfs_bmap_trace_pre_update(fname, "0", ip, idx, whichfork);
- xfs_bmbt_set_blockcount(ep, temp);
- new.br_startoff = del_endoff;
- temp2 = got_endoff - del_endoff;
- new.br_blockcount = temp2;
- new.br_state = got.br_state;
- if (!delay) {
- new.br_startblock = del_endblock;
- flags |= XFS_ILOG_CORE;
- if (cur) {
- if ((error = xfs_bmbt_update(cur,
- got.br_startoff,
- got.br_startblock, temp,
- got.br_state)))
- goto done;
- if ((error = xfs_bmbt_increment(cur, 0, &i)))
- goto done;
- cur->bc_rec.b = new;
- error = xfs_bmbt_insert(cur, &i);
- if (error && error != ENOSPC)
- goto done;
- /*
- * If get no-space back from btree insert,
- * it tried a split, and we have a zero
- * block reservation.
- * Fix up our state and return the error.
- */
- if (error == ENOSPC) {
- /*
- * Reset the cursor, don't trust
- * it after any insert operation.
- */
- if ((error = xfs_bmbt_lookup_eq(cur,
- got.br_startoff,
- got.br_startblock,
- temp, &i)))
- goto done;
- ASSERT(i == 1);
- /*
- * Update the btree record back
- * to the original value.
- */
- if ((error = xfs_bmbt_update(cur,
- got.br_startoff,
- got.br_startblock,
- got.br_blockcount,
- got.br_state)))
- goto done;
- /*
- * Reset the extent record back
- * to the original value.
- */
- xfs_bmbt_set_blockcount(ep,
- got.br_blockcount);
- flags = 0;
- error = XFS_ERROR(ENOSPC);
- goto done;
- }
- ASSERT(i == 1);
- } else
- flags |= XFS_ILOG_FEXT(whichfork);
- XFS_IFORK_NEXT_SET(ip, whichfork,
- XFS_IFORK_NEXTENTS(ip, whichfork) + 1);
- } else {
- ASSERT(whichfork == XFS_DATA_FORK);
- temp = xfs_bmap_worst_indlen(ip, temp);
- xfs_bmbt_set_startblock(ep, NULLSTARTBLOCK((int)temp));
- temp2 = xfs_bmap_worst_indlen(ip, temp2);
- new.br_startblock = NULLSTARTBLOCK((int)temp2);
- da_new = temp + temp2;
- while (da_new > da_old) {
- if (temp) {
- temp--;
- da_new--;
- xfs_bmbt_set_startblock(ep,
- NULLSTARTBLOCK((int)temp));
- }
- if (da_new == da_old)
- break;
- if (temp2) {
- temp2--;
- da_new--;
- new.br_startblock =
- NULLSTARTBLOCK((int)temp2);
- }
- }
- }
- xfs_bmap_trace_post_update(fname, "0", ip, idx, whichfork);
- xfs_bmap_trace_insert(fname, "0", ip, idx + 1, 1, &new, NULL,
- whichfork);
- xfs_iext_insert(ifp, idx + 1, 1, &new);
- ifp->if_lastex = idx + 1;
- break;
- }
- /*
- * If we need to, add to list of extents to delete.
- */
- if (do_fx)
- xfs_bmap_add_free(del->br_startblock, del->br_blockcount, flist,
- mp);
- /*
- * Adjust inode # blocks in the file.
- */
- if (nblks)
- ip->i_d.di_nblocks -= nblks;
- /*
- * Adjust quota data.
- */
- if (qfield)
- XFS_TRANS_MOD_DQUOT_BYINO(mp, tp, ip, qfield, (long)-nblks);
-
- /*
- * Account for change in delayed indirect blocks.
- * Nothing to do for disk quota accounting here.
- */
- ASSERT(da_old >= da_new);
- if (da_old > da_new)
- xfs_mod_incore_sb(mp, XFS_SBS_FDBLOCKS, (int)(da_old - da_new),
- rsvd);
- if (delta) {
- /* DELTA: report the original extent. */
- if (delta->xed_startoff > got.br_startoff)
- delta->xed_startoff = got.br_startoff;
- if (delta->xed_blockcount < got.br_startoff+got.br_blockcount)
- delta->xed_blockcount = got.br_startoff +
- got.br_blockcount;
- }
-done:
- *logflagsp = flags;
- return error;
-}
-
-/*
- * Remove the entry "free" from the free item list. Prev points to the
- * previous entry, unless "free" is the head of the list.
- */
-STATIC void
-xfs_bmap_del_free(
- xfs_bmap_free_t *flist, /* free item list header */
- xfs_bmap_free_item_t *prev, /* previous item on list, if any */
- xfs_bmap_free_item_t *free) /* list item to be freed */
-{
- if (prev)
- prev->xbfi_next = free->xbfi_next;
- else
- flist->xbf_first = free->xbfi_next;
- flist->xbf_count--;
- kmem_zone_free(xfs_bmap_free_item_zone, free);
-}
-
-/*
- * Convert an extents-format file into a btree-format file.
- * The new file will have a root block (in the inode) and a single child block.
- */
-STATIC int /* error */
-xfs_bmap_extents_to_btree(
- xfs_trans_t *tp, /* transaction pointer */
- xfs_inode_t *ip, /* incore inode pointer */
- xfs_fsblock_t *firstblock, /* first-block-allocated */
- xfs_bmap_free_t *flist, /* blocks freed in xaction */
- xfs_btree_cur_t **curp, /* cursor returned to caller */
- int wasdel, /* converting a delayed alloc */
- int *logflagsp, /* inode logging flags */
- int whichfork) /* data or attr fork */
-{
- xfs_bmbt_block_t *ablock; /* allocated (child) bt block */
- xfs_buf_t *abp; /* buffer for ablock */
- xfs_alloc_arg_t args; /* allocation arguments */
- xfs_bmbt_rec_t *arp; /* child record pointer */
- xfs_bmbt_block_t *block; /* btree root block */
- xfs_btree_cur_t *cur; /* bmap btree cursor */
- xfs_bmbt_rec_t *ep; /* extent record pointer */
- int error; /* error return value */
- xfs_extnum_t i, cnt; /* extent record index */
- xfs_ifork_t *ifp; /* inode fork pointer */
- xfs_bmbt_key_t *kp; /* root block key pointer */
- xfs_mount_t *mp; /* mount structure */
- xfs_extnum_t nextents; /* number of file extents */
- xfs_bmbt_ptr_t *pp; /* root block address pointer */
-
- ifp = XFS_IFORK_PTR(ip, whichfork);
- ASSERT(XFS_IFORK_FORMAT(ip, whichfork) == XFS_DINODE_FMT_EXTENTS);
- ASSERT(ifp->if_ext_max ==
- XFS_IFORK_SIZE(ip, whichfork) / (uint)sizeof(xfs_bmbt_rec_t));
- /*
- * Make space in the inode incore.
- */
- xfs_iroot_realloc(ip, 1, whichfork);
- ifp->if_flags |= XFS_IFBROOT;
- /*
- * Fill in the root.
- */
- block = ifp->if_broot;
- block->bb_magic = cpu_to_be32(XFS_BMAP_MAGIC);
- block->bb_level = cpu_to_be16(1);
- block->bb_numrecs = cpu_to_be16(1);
- block->bb_leftsib = cpu_to_be64(NULLDFSBNO);
- block->bb_rightsib = cpu_to_be64(NULLDFSBNO);
- /*
- * Need a cursor. Can't allocate until bb_level is filled in.
- */
- mp = ip->i_mount;
- cur = xfs_btree_init_cursor(mp, tp, NULL, 0, XFS_BTNUM_BMAP, ip,
- whichfork);
- cur->bc_private.b.firstblock = *firstblock;
- cur->bc_private.b.flist = flist;
- cur->bc_private.b.flags = wasdel ? XFS_BTCUR_BPRV_WASDEL : 0;
- /*
- * Convert to a btree with two levels, one record in root.
- */
- XFS_IFORK_FMT_SET(ip, whichfork, XFS_DINODE_FMT_BTREE);
- args.tp = tp;
- args.mp = mp;
- if (*firstblock == NULLFSBLOCK) {
- args.type = XFS_ALLOCTYPE_START_BNO;
- args.fsbno = XFS_INO_TO_FSB(mp, ip->i_ino);
- } else if (flist->xbf_low) {
- args.type = XFS_ALLOCTYPE_START_BNO;
- args.fsbno = *firstblock;
- } else {
- args.type = XFS_ALLOCTYPE_NEAR_BNO;
- args.fsbno = *firstblock;
- }
- args.minlen = args.maxlen = args.prod = 1;
- args.total = args.minleft = args.alignment = args.mod = args.isfl =
- args.minalignslop = 0;
- args.wasdel = wasdel;
- *logflagsp = 0;
- if ((error = xfs_alloc_vextent(&args))) {
- xfs_iroot_realloc(ip, -1, whichfork);
- xfs_btree_del_cursor(cur, XFS_BTREE_ERROR);
- return error;
- }
- /*
- * Allocation can't fail, the space was reserved.
- */
- ASSERT(args.fsbno != NULLFSBLOCK);
- ASSERT(*firstblock == NULLFSBLOCK ||
- args.agno == XFS_FSB_TO_AGNO(mp, *firstblock) ||
- (flist->xbf_low &&
- args.agno > XFS_FSB_TO_AGNO(mp, *firstblock)));
- *firstblock = cur->bc_private.b.firstblock = args.fsbno;
- cur->bc_private.b.allocated++;
- ip->i_d.di_nblocks++;
- XFS_TRANS_MOD_DQUOT_BYINO(mp, tp, ip, XFS_TRANS_DQ_BCOUNT, 1L);
- abp = xfs_btree_get_bufl(mp, tp, args.fsbno, 0);
- /*
- * Fill in the child block.
- */
- ablock = XFS_BUF_TO_BMBT_BLOCK(abp);
- ablock->bb_magic = cpu_to_be32(XFS_BMAP_MAGIC);
- ablock->bb_level = 0;
- ablock->bb_leftsib = cpu_to_be64(NULLDFSBNO);
- ablock->bb_rightsib = cpu_to_be64(NULLDFSBNO);
- arp = XFS_BMAP_REC_IADDR(ablock, 1, cur);
- nextents = ifp->if_bytes / (uint)sizeof(xfs_bmbt_rec_t);
- for (cnt = i = 0; i < nextents; i++) {
- ep = xfs_iext_get_ext(ifp, i);
- if (!ISNULLSTARTBLOCK(xfs_bmbt_get_startblock(ep))) {
- arp->l0 = INT_GET(ep->l0, ARCH_CONVERT);
- arp->l1 = INT_GET(ep->l1, ARCH_CONVERT);
- arp++; cnt++;
- }
- }
- ASSERT(cnt == XFS_IFORK_NEXTENTS(ip, whichfork));
- ablock->bb_numrecs = cpu_to_be16(cnt);
- /*
- * Fill in the root key and pointer.
- */
- kp = XFS_BMAP_KEY_IADDR(block, 1, cur);
- arp = XFS_BMAP_REC_IADDR(ablock, 1, cur);
- INT_SET(kp->br_startoff, ARCH_CONVERT, xfs_bmbt_disk_get_startoff(arp));
- pp = XFS_BMAP_PTR_IADDR(block, 1, cur);
- INT_SET(*pp, ARCH_CONVERT, args.fsbno);
- /*
- * Do all this logging at the end so that
- * the root is at the right level.
- */
- xfs_bmbt_log_block(cur, abp, XFS_BB_ALL_BITS);
- xfs_bmbt_log_recs(cur, abp, 1, be16_to_cpu(ablock->bb_numrecs));
- ASSERT(*curp == NULL);
- *curp = cur;
- *logflagsp = XFS_ILOG_CORE | XFS_ILOG_FBROOT(whichfork);
- return 0;
-}
-
-/*
- * Helper routine to reset inode di_forkoff field when switching
- * attribute fork from local to extent format - we reset it where
- * possible to make space available for inline data fork extents.
- */
-STATIC void
-xfs_bmap_forkoff_reset(
- xfs_mount_t *mp,
- xfs_inode_t *ip,
- int whichfork)
-{
- if (whichfork == XFS_ATTR_FORK &&
- (ip->i_d.di_format != XFS_DINODE_FMT_DEV) &&
- (ip->i_d.di_format != XFS_DINODE_FMT_UUID) &&
- ((mp->m_attroffset >> 3) > ip->i_d.di_forkoff)) {
- ip->i_d.di_forkoff = mp->m_attroffset >> 3;
- ip->i_df.if_ext_max = XFS_IFORK_DSIZE(ip) /
- (uint)sizeof(xfs_bmbt_rec_t);
- ip->i_afp->if_ext_max = XFS_IFORK_ASIZE(ip) /
- (uint)sizeof(xfs_bmbt_rec_t);
- }
-}
-
-/*
- * Convert a local file to an extents file.
- * This code is out of bounds for data forks of regular files,
- * since the file data needs to get logged so things will stay consistent.
- * (The bmap-level manipulations are ok, though).
- */
-STATIC int /* error */
-xfs_bmap_local_to_extents(
- xfs_trans_t *tp, /* transaction pointer */
- xfs_inode_t *ip, /* incore inode pointer */
- xfs_fsblock_t *firstblock, /* first block allocated in xaction */
- xfs_extlen_t total, /* total blocks needed by transaction */
- int *logflagsp, /* inode logging flags */
- int whichfork) /* data or attr fork */
-{
- int error; /* error return value */
- int flags; /* logging flags returned */
-#ifdef XFS_BMAP_TRACE
- static char fname[] = "xfs_bmap_local_to_extents";
-#endif
- xfs_ifork_t *ifp; /* inode fork pointer */
-
- /*
- * We don't want to deal with the case of keeping inode data inline yet.
- * So sending the data fork of a regular inode is invalid.
- */
- ASSERT(!((ip->i_d.di_mode & S_IFMT) == S_IFREG &&
- whichfork == XFS_DATA_FORK));
- ifp = XFS_IFORK_PTR(ip, whichfork);
- ASSERT(XFS_IFORK_FORMAT(ip, whichfork) == XFS_DINODE_FMT_LOCAL);
- flags = 0;
- error = 0;
- if (ifp->if_bytes) {
- xfs_alloc_arg_t args; /* allocation arguments */
- xfs_buf_t *bp; /* buffer for extent block */
- xfs_bmbt_rec_t *ep; /* extent record pointer */
-
- args.tp = tp;
- args.mp = ip->i_mount;
- ASSERT((ifp->if_flags &
- (XFS_IFINLINE|XFS_IFEXTENTS|XFS_IFEXTIREC)) == XFS_IFINLINE);
- /*
- * Allocate a block. We know we need only one, since the
- * file currently fits in an inode.
- */
- if (*firstblock == NULLFSBLOCK) {
- args.fsbno = XFS_INO_TO_FSB(args.mp, ip->i_ino);
- args.type = XFS_ALLOCTYPE_START_BNO;
- } else {
- args.fsbno = *firstblock;
- args.type = XFS_ALLOCTYPE_NEAR_BNO;
- }
- args.total = total;
- args.mod = args.minleft = args.alignment = args.wasdel =
- args.isfl = args.minalignslop = 0;
- args.minlen = args.maxlen = args.prod = 1;
- if ((error = xfs_alloc_vextent(&args)))
- goto done;
- /*
- * Can't fail, the space was reserved.
- */
- ASSERT(args.fsbno != NULLFSBLOCK);
- ASSERT(args.len == 1);
- *firstblock = args.fsbno;
- bp = xfs_btree_get_bufl(args.mp, tp, args.fsbno, 0);
- memcpy((char *)XFS_BUF_PTR(bp), ifp->if_u1.if_data,
- ifp->if_bytes);
- xfs_trans_log_buf(tp, bp, 0, ifp->if_bytes - 1);
- xfs_bmap_forkoff_reset(args.mp, ip, whichfork);
- xfs_idata_realloc(ip, -ifp->if_bytes, whichfork);
- xfs_iext_add(ifp, 0, 1);
- ep = xfs_iext_get_ext(ifp, 0);
- xfs_bmbt_set_allf(ep, 0, args.fsbno, 1, XFS_EXT_NORM);
- xfs_bmap_trace_post_update(fname, "new", ip, 0, whichfork);
- XFS_IFORK_NEXT_SET(ip, whichfork, 1);
- ip->i_d.di_nblocks = 1;
- XFS_TRANS_MOD_DQUOT_BYINO(args.mp, tp, ip,
- XFS_TRANS_DQ_BCOUNT, 1L);
- flags |= XFS_ILOG_FEXT(whichfork);
- } else {
- ASSERT(XFS_IFORK_NEXTENTS(ip, whichfork) == 0);
- xfs_bmap_forkoff_reset(ip->i_mount, ip, whichfork);
- }
- ifp->if_flags &= ~XFS_IFINLINE;
- ifp->if_flags |= XFS_IFEXTENTS;
- XFS_IFORK_FMT_SET(ip, whichfork, XFS_DINODE_FMT_EXTENTS);
- flags |= XFS_ILOG_CORE;
-done:
- *logflagsp = flags;
- return error;
-}
-
-/*
- * Search the extent records for the entry containing block bno.
- * If bno lies in a hole, point to the next entry. If bno lies
- * past eof, *eofp will be set, and *prevp will contain the last
- * entry (null if none). Else, *lastxp will be set to the index
- * of the found entry; *gotp will contain the entry.
- */
-xfs_bmbt_rec_t * /* pointer to found extent entry */
-xfs_bmap_search_multi_extents(
- xfs_ifork_t *ifp, /* inode fork pointer */
- xfs_fileoff_t bno, /* block number searched for */
- int *eofp, /* out: end of file found */
- xfs_extnum_t *lastxp, /* out: last extent index */
- xfs_bmbt_irec_t *gotp, /* out: extent entry found */
- xfs_bmbt_irec_t *prevp) /* out: previous extent entry found */
-{
- xfs_bmbt_rec_t *ep; /* extent record pointer */
- xfs_extnum_t lastx; /* last extent index */
-
- /*
- * Initialize the extent entry structure to catch access to
- * uninitialized br_startblock field.
- */
- gotp->br_startoff = 0xffa5a5a5a5a5a5a5LL;
- gotp->br_blockcount = 0xa55a5a5a5a5a5a5aLL;
- gotp->br_state = XFS_EXT_INVALID;
-#if XFS_BIG_BLKNOS
- gotp->br_startblock = 0xffffa5a5a5a5a5a5LL;
-#else
- gotp->br_startblock = 0xffffa5a5;
-#endif
- prevp->br_startoff = NULLFILEOFF;
-
- ep = xfs_iext_bno_to_ext(ifp, bno, &lastx);
- if (lastx > 0) {
- xfs_bmbt_get_all(xfs_iext_get_ext(ifp, lastx - 1), prevp);
- }
- if (lastx < (ifp->if_bytes / (uint)sizeof(xfs_bmbt_rec_t))) {
- xfs_bmbt_get_all(ep, gotp);
- *eofp = 0;
- } else {
- if (lastx > 0) {
- *gotp = *prevp;
- }
- *eofp = 1;
- ep = NULL;
- }
- *lastxp = lastx;
- return ep;
-}
-
-/*
- * Search the extents list for the inode, for the extent containing bno.
- * If bno lies in a hole, point to the next entry. If bno lies past eof,
- * *eofp will be set, and *prevp will contain the last entry (null if none).
- * Else, *lastxp will be set to the index of the found
- * entry; *gotp will contain the entry.
- */
-STATIC xfs_bmbt_rec_t * /* pointer to found extent entry */
-xfs_bmap_search_extents(
- xfs_inode_t *ip, /* incore inode pointer */
- xfs_fileoff_t bno, /* block number searched for */
- int whichfork, /* data or attr fork */
- int *eofp, /* out: end of file found */
- xfs_extnum_t *lastxp, /* out: last extent index */
- xfs_bmbt_irec_t *gotp, /* out: extent entry found */
- xfs_bmbt_irec_t *prevp) /* out: previous extent entry found */
-{
- xfs_ifork_t *ifp; /* inode fork pointer */
- xfs_bmbt_rec_t *ep; /* extent record pointer */
- int rt; /* realtime flag */
-
- XFS_STATS_INC(xs_look_exlist);
- ifp = XFS_IFORK_PTR(ip, whichfork);
-
- ep = xfs_bmap_search_multi_extents(ifp, bno, eofp, lastxp, gotp, prevp);
-
- rt = (whichfork == XFS_DATA_FORK) && XFS_IS_REALTIME_INODE(ip);
- if (unlikely(!rt && !gotp->br_startblock && (*lastxp != NULLEXTNUM))) {
- cmn_err(CE_PANIC,"Access to block zero: fs: <%s> inode: %lld "
- "start_block : %llx start_off : %llx blkcnt : %llx "
- "extent-state : %x \n",
- (ip->i_mount)->m_fsname, (long long)ip->i_ino,
- (unsigned long long)gotp->br_startblock,
- (unsigned long long)gotp->br_startoff,
- (unsigned long long)gotp->br_blockcount,
- gotp->br_state);
- }
- return ep;
-}
-
-
-#ifdef XFS_BMAP_TRACE
-ktrace_t *xfs_bmap_trace_buf;
-
-/*
- * Add a bmap trace buffer entry. Base routine for the others.
- */
-STATIC void
-xfs_bmap_trace_addentry(
- int opcode, /* operation */
- char *fname, /* function name */
- char *desc, /* operation description */
- xfs_inode_t *ip, /* incore inode pointer */
- xfs_extnum_t idx, /* index of entry(ies) */
- xfs_extnum_t cnt, /* count of entries, 1 or 2 */
- xfs_bmbt_rec_t *r1, /* first record */
- xfs_bmbt_rec_t *r2, /* second record or null */
- int whichfork) /* data or attr fork */
-{
- xfs_bmbt_rec_t tr2;
-
- ASSERT(cnt == 1 || cnt == 2);
- ASSERT(r1 != NULL);
- if (cnt == 1) {
- ASSERT(r2 == NULL);
- r2 = &tr2;
- memset(&tr2, 0, sizeof(tr2));
- } else
- ASSERT(r2 != NULL);
- ktrace_enter(xfs_bmap_trace_buf,
- (void *)(__psint_t)(opcode | (whichfork << 16)),
- (void *)fname, (void *)desc, (void *)ip,
- (void *)(__psint_t)idx,
- (void *)(__psint_t)cnt,
- (void *)(__psunsigned_t)(ip->i_ino >> 32),
- (void *)(__psunsigned_t)(unsigned)ip->i_ino,
- (void *)(__psunsigned_t)(r1->l0 >> 32),
- (void *)(__psunsigned_t)(unsigned)(r1->l0),
- (void *)(__psunsigned_t)(r1->l1 >> 32),
- (void *)(__psunsigned_t)(unsigned)(r1->l1),
- (void *)(__psunsigned_t)(r2->l0 >> 32),
- (void *)(__psunsigned_t)(unsigned)(r2->l0),
- (void *)(__psunsigned_t)(r2->l1 >> 32),
- (void *)(__psunsigned_t)(unsigned)(r2->l1)
- );
- ASSERT(ip->i_xtrace);
- ktrace_enter(ip->i_xtrace,
- (void *)(__psint_t)(opcode | (whichfork << 16)),
- (void *)fname, (void *)desc, (void *)ip,
- (void *)(__psint_t)idx,
- (void *)(__psint_t)cnt,
- (void *)(__psunsigned_t)(ip->i_ino >> 32),
- (void *)(__psunsigned_t)(unsigned)ip->i_ino,
- (void *)(__psunsigned_t)(r1->l0 >> 32),
- (void *)(__psunsigned_t)(unsigned)(r1->l0),
- (void *)(__psunsigned_t)(r1->l1 >> 32),
- (void *)(__psunsigned_t)(unsigned)(r1->l1),
- (void *)(__psunsigned_t)(r2->l0 >> 32),
- (void *)(__psunsigned_t)(unsigned)(r2->l0),
- (void *)(__psunsigned_t)(r2->l1 >> 32),
- (void *)(__psunsigned_t)(unsigned)(r2->l1)
- );
-}
-
-/*
- * Add bmap trace entry prior to a call to xfs_iext_remove.
- */
-STATIC void
-xfs_bmap_trace_delete(
- char *fname, /* function name */
- char *desc, /* operation description */
- xfs_inode_t *ip, /* incore inode pointer */
- xfs_extnum_t idx, /* index of entry(entries) deleted */
- xfs_extnum_t cnt, /* count of entries deleted, 1 or 2 */
- int whichfork) /* data or attr fork */
-{
- xfs_ifork_t *ifp; /* inode fork pointer */
-
- ifp = XFS_IFORK_PTR(ip, whichfork);
- xfs_bmap_trace_addentry(XFS_BMAP_KTRACE_DELETE, fname, desc, ip, idx,
- cnt, xfs_iext_get_ext(ifp, idx),
- cnt == 2 ? xfs_iext_get_ext(ifp, idx + 1) : NULL,
- whichfork);
-}
-
-/*
- * Add bmap trace entry prior to a call to xfs_iext_insert, or
- * reading in the extents list from the disk (in the btree).
- */
-STATIC void
-xfs_bmap_trace_insert(
- char *fname, /* function name */
- char *desc, /* operation description */
- xfs_inode_t *ip, /* incore inode pointer */
- xfs_extnum_t idx, /* index of entry(entries) inserted */
- xfs_extnum_t cnt, /* count of entries inserted, 1 or 2 */
- xfs_bmbt_irec_t *r1, /* inserted record 1 */
- xfs_bmbt_irec_t *r2, /* inserted record 2 or null */
- int whichfork) /* data or attr fork */
-{
- xfs_bmbt_rec_t tr1; /* compressed record 1 */
- xfs_bmbt_rec_t tr2; /* compressed record 2 if needed */
-
- xfs_bmbt_set_all(&tr1, r1);
- if (cnt == 2) {
- ASSERT(r2 != NULL);
- xfs_bmbt_set_all(&tr2, r2);
- } else {
- ASSERT(cnt == 1);
- ASSERT(r2 == NULL);
- }
- xfs_bmap_trace_addentry(XFS_BMAP_KTRACE_INSERT, fname, desc, ip, idx,
- cnt, &tr1, cnt == 2 ? &tr2 : NULL, whichfork);
-}
-
-/*
- * Add bmap trace entry after updating an extent record in place.
- */
-STATIC void
-xfs_bmap_trace_post_update(
- char *fname, /* function name */
- char *desc, /* operation description */
- xfs_inode_t *ip, /* incore inode pointer */
- xfs_extnum_t idx, /* index of entry updated */
- int whichfork) /* data or attr fork */
-{
- xfs_ifork_t *ifp; /* inode fork pointer */
-
- ifp = XFS_IFORK_PTR(ip, whichfork);
- xfs_bmap_trace_addentry(XFS_BMAP_KTRACE_POST_UP, fname, desc, ip, idx,
- 1, xfs_iext_get_ext(ifp, idx), NULL, whichfork);
-}
-
-/*
- * Add bmap trace entry prior to updating an extent record in place.
- */
-STATIC void
-xfs_bmap_trace_pre_update(
- char *fname, /* function name */
- char *desc, /* operation description */
- xfs_inode_t *ip, /* incore inode pointer */
- xfs_extnum_t idx, /* index of entry to be updated */
- int whichfork) /* data or attr fork */
-{
- xfs_ifork_t *ifp; /* inode fork pointer */
-
- ifp = XFS_IFORK_PTR(ip, whichfork);
- xfs_bmap_trace_addentry(XFS_BMAP_KTRACE_PRE_UP, fname, desc, ip, idx, 1,
- xfs_iext_get_ext(ifp, idx), NULL, whichfork);
-}
-#endif /* XFS_BMAP_TRACE */
-
-/*
- * Compute the worst-case number of indirect blocks that will be used
- * for ip's delayed extent of length "len".
- */
-STATIC xfs_filblks_t
-xfs_bmap_worst_indlen(
- xfs_inode_t *ip, /* incore inode pointer */
- xfs_filblks_t len) /* delayed extent length */
-{
- int level; /* btree level number */
- int maxrecs; /* maximum record count at this level */
- xfs_mount_t *mp; /* mount structure */
- xfs_filblks_t rval; /* return value */
-
- mp = ip->i_mount;
- maxrecs = mp->m_bmap_dmxr[0];
- for (level = 0, rval = 0;
- level < XFS_BM_MAXLEVELS(mp, XFS_DATA_FORK);
- level++) {
- len += maxrecs - 1;
- do_div(len, maxrecs);
- rval += len;
- if (len == 1)
- return rval + XFS_BM_MAXLEVELS(mp, XFS_DATA_FORK) -
- level - 1;
- if (level == 0)
- maxrecs = mp->m_bmap_dmxr[1];
- }
- return rval;
-}
-
-#if defined(XFS_RW_TRACE)
-STATIC void
-xfs_bunmap_trace(
- xfs_inode_t *ip,
- xfs_fileoff_t bno,
- xfs_filblks_t len,
- int flags,
- inst_t *ra)
-{
- if (ip->i_rwtrace == NULL)
- return;
- ktrace_enter(ip->i_rwtrace,
- (void *)(__psint_t)XFS_BUNMAP,
- (void *)ip,
- (void *)(__psint_t)((ip->i_d.di_size >> 32) & 0xffffffff),
- (void *)(__psint_t)(ip->i_d.di_size & 0xffffffff),
- (void *)(__psint_t)(((xfs_dfiloff_t)bno >> 32) & 0xffffffff),
- (void *)(__psint_t)((xfs_dfiloff_t)bno & 0xffffffff),
- (void *)(__psint_t)len,
- (void *)(__psint_t)flags,
- (void *)current_cpu(),
- (void *)ra,
- (void *)0,
- (void *)0,
- (void *)0,
- (void *)0,
- (void *)0,
- (void *)0);
-}
-#endif
-
-/*
- * Convert inode from non-attributed to attributed.
- * Must not be in a transaction, ip must not be locked.
- */
-int /* error code */
-xfs_bmap_add_attrfork(
- xfs_inode_t *ip, /* incore inode pointer */
- int size, /* space new attribute needs */
- int rsvd) /* xact may use reserved blks */
-{
- xfs_fsblock_t firstblock; /* 1st block/ag allocated */
- xfs_bmap_free_t flist; /* freed extent records */
- xfs_mount_t *mp; /* mount structure */
- xfs_trans_t *tp; /* transaction pointer */
- unsigned long s; /* spinlock spl value */
- int blks; /* space reservation */
- int version = 1; /* superblock attr version */
- int committed; /* xaction was committed */
- int logflags; /* logging flags */
- int error; /* error return value */
-
- ASSERT(XFS_IFORK_Q(ip) == 0);
- ASSERT(ip->i_df.if_ext_max ==
- XFS_IFORK_DSIZE(ip) / (uint)sizeof(xfs_bmbt_rec_t));
-
- mp = ip->i_mount;
- ASSERT(!XFS_NOT_DQATTACHED(mp, ip));
- tp = xfs_trans_alloc(mp, XFS_TRANS_ADDAFORK);
- blks = XFS_ADDAFORK_SPACE_RES(mp);
- if (rsvd)
- tp->t_flags |= XFS_TRANS_RESERVE;
- if ((error = xfs_trans_reserve(tp, blks, XFS_ADDAFORK_LOG_RES(mp), 0,
- XFS_TRANS_PERM_LOG_RES, XFS_ADDAFORK_LOG_COUNT)))
- goto error0;
- xfs_ilock(ip, XFS_ILOCK_EXCL);
- error = XFS_TRANS_RESERVE_QUOTA_NBLKS(mp, tp, ip, blks, 0, rsvd ?
- XFS_QMOPT_RES_REGBLKS | XFS_QMOPT_FORCE_RES :
- XFS_QMOPT_RES_REGBLKS);
- if (error) {
- xfs_iunlock(ip, XFS_ILOCK_EXCL);
- xfs_trans_cancel(tp, XFS_TRANS_RELEASE_LOG_RES);
- return error;
- }
- if (XFS_IFORK_Q(ip))
- goto error1;
- if (ip->i_d.di_aformat != XFS_DINODE_FMT_EXTENTS) {
- /*
- * For inodes coming from pre-6.2 filesystems.
- */
- ASSERT(ip->i_d.di_aformat == 0);
- ip->i_d.di_aformat = XFS_DINODE_FMT_EXTENTS;
- }
- ASSERT(ip->i_d.di_anextents == 0);
- VN_HOLD(XFS_ITOV(ip));
- xfs_trans_ijoin(tp, ip, XFS_ILOCK_EXCL);
- xfs_trans_log_inode(tp, ip, XFS_ILOG_CORE);
- switch (ip->i_d.di_format) {
- case XFS_DINODE_FMT_DEV:
- ip->i_d.di_forkoff = roundup(sizeof(xfs_dev_t), 8) >> 3;
- break;
- case XFS_DINODE_FMT_UUID:
- ip->i_d.di_forkoff = roundup(sizeof(uuid_t), 8) >> 3;
- break;
- case XFS_DINODE_FMT_LOCAL:
- case XFS_DINODE_FMT_EXTENTS:
- case XFS_DINODE_FMT_BTREE:
- ip->i_d.di_forkoff = xfs_attr_shortform_bytesfit(ip, size);
- if (!ip->i_d.di_forkoff)
- ip->i_d.di_forkoff = mp->m_attroffset >> 3;
- else if (mp->m_flags & XFS_MOUNT_ATTR2)
- version = 2;
- break;
- default:
- ASSERT(0);
- error = XFS_ERROR(EINVAL);
- goto error1;
- }
- ip->i_df.if_ext_max =
- XFS_IFORK_DSIZE(ip) / (uint)sizeof(xfs_bmbt_rec_t);
- ASSERT(ip->i_afp == NULL);
- ip->i_afp = kmem_zone_zalloc(xfs_ifork_zone, KM_SLEEP);
- ip->i_afp->if_ext_max =
- XFS_IFORK_ASIZE(ip) / (uint)sizeof(xfs_bmbt_rec_t);
- ip->i_afp->if_flags = XFS_IFEXTENTS;
- logflags = 0;
- XFS_BMAP_INIT(&flist, &firstblock);
- switch (ip->i_d.di_format) {
- case XFS_DINODE_FMT_LOCAL:
- error = xfs_bmap_add_attrfork_local(tp, ip, &firstblock, &flist,
- &logflags);
- break;
- case XFS_DINODE_FMT_EXTENTS:
- error = xfs_bmap_add_attrfork_extents(tp, ip, &firstblock,
- &flist, &logflags);
- break;
- case XFS_DINODE_FMT_BTREE:
- error = xfs_bmap_add_attrfork_btree(tp, ip, &firstblock, &flist,
- &logflags);
- break;
- default:
- error = 0;
- break;
- }
- if (logflags)
- xfs_trans_log_inode(tp, ip, logflags);
- if (error)
- goto error2;
- if (!XFS_SB_VERSION_HASATTR(&mp->m_sb) ||
- (!XFS_SB_VERSION_HASATTR2(&mp->m_sb) && version == 2)) {
- __int64_t sbfields = 0;
-
- s = XFS_SB_LOCK(mp);
- if (!XFS_SB_VERSION_HASATTR(&mp->m_sb)) {
- XFS_SB_VERSION_ADDATTR(&mp->m_sb);
- sbfields |= XFS_SB_VERSIONNUM;
- }
- if (!XFS_SB_VERSION_HASATTR2(&mp->m_sb) && version == 2) {
- XFS_SB_VERSION_ADDATTR2(&mp->m_sb);
- sbfields |= (XFS_SB_VERSIONNUM | XFS_SB_FEATURES2);
- }
- if (sbfields) {
- XFS_SB_UNLOCK(mp, s);
- xfs_mod_sb(tp, sbfields);
- } else
- XFS_SB_UNLOCK(mp, s);
- }
- if ((error = xfs_bmap_finish(&tp, &flist, firstblock, &committed)))
- goto error2;
- error = xfs_trans_commit(tp, XFS_TRANS_PERM_LOG_RES, NULL);
- ASSERT(ip->i_df.if_ext_max ==
- XFS_IFORK_DSIZE(ip) / (uint)sizeof(xfs_bmbt_rec_t));
- return error;
-error2:
- xfs_bmap_cancel(&flist);
-error1:
- ASSERT(ismrlocked(&ip->i_lock,MR_UPDATE));
- xfs_iunlock(ip, XFS_ILOCK_EXCL);
-error0:
- xfs_trans_cancel(tp, XFS_TRANS_RELEASE_LOG_RES|XFS_TRANS_ABORT);
- ASSERT(ip->i_df.if_ext_max ==
- XFS_IFORK_DSIZE(ip) / (uint)sizeof(xfs_bmbt_rec_t));
- return error;
-}
-
-/*
- * Add the extent to the list of extents to be free at transaction end.
- * The list is maintained sorted (by block number).
- */
-/* ARGSUSED */
-void
-xfs_bmap_add_free(
- xfs_fsblock_t bno, /* fs block number of extent */
- xfs_filblks_t len, /* length of extent */
- xfs_bmap_free_t *flist, /* list of extents */
- xfs_mount_t *mp) /* mount point structure */
-{
- xfs_bmap_free_item_t *cur; /* current (next) element */
- xfs_bmap_free_item_t *new; /* new element */
- xfs_bmap_free_item_t *prev; /* previous element */
-#ifdef DEBUG
- xfs_agnumber_t agno;
- xfs_agblock_t agbno;
-
- ASSERT(bno != NULLFSBLOCK);
- ASSERT(len > 0);
- ASSERT(len <= MAXEXTLEN);
- ASSERT(!ISNULLSTARTBLOCK(bno));
- agno = XFS_FSB_TO_AGNO(mp, bno);
- agbno = XFS_FSB_TO_AGBNO(mp, bno);
- ASSERT(agno < mp->m_sb.sb_agcount);
- ASSERT(agbno < mp->m_sb.sb_agblocks);
- ASSERT(len < mp->m_sb.sb_agblocks);
- ASSERT(agbno + len <= mp->m_sb.sb_agblocks);
-#endif
- ASSERT(xfs_bmap_free_item_zone != NULL);
- new = kmem_zone_alloc(xfs_bmap_free_item_zone, KM_SLEEP);
- new->xbfi_startblock = bno;
- new->xbfi_blockcount = (xfs_extlen_t)len;
- for (prev = NULL, cur = flist->xbf_first;
- cur != NULL;
- prev = cur, cur = cur->xbfi_next) {
- if (cur->xbfi_startblock >= bno)
- break;
- }
- if (prev)
- prev->xbfi_next = new;
- else
- flist->xbf_first = new;
- new->xbfi_next = cur;
- flist->xbf_count++;
-}
-
-/*
- * Compute and fill in the value of the maximum depth of a bmap btree
- * in this filesystem. Done once, during mount.
- */
-void
-xfs_bmap_compute_maxlevels(
- xfs_mount_t *mp, /* file system mount structure */
- int whichfork) /* data or attr fork */
-{
- int level; /* btree level */
- uint maxblocks; /* max blocks at this level */
- uint maxleafents; /* max leaf entries possible */
- int maxrootrecs; /* max records in root block */
- int minleafrecs; /* min records in leaf block */
- int minnoderecs; /* min records in node block */
- int sz; /* root block size */
-
- /*
- * The maximum number of extents in a file, hence the maximum
- * number of leaf entries, is controlled by the type of di_nextents
- * (a signed 32-bit number, xfs_extnum_t), or by di_anextents
- * (a signed 16-bit number, xfs_aextnum_t).
- */
- if (whichfork == XFS_DATA_FORK) {
- maxleafents = MAXEXTNUM;
- sz = (mp->m_flags & XFS_MOUNT_ATTR2) ?
- XFS_BMDR_SPACE_CALC(MINDBTPTRS) : mp->m_attroffset;
- } else {
- maxleafents = MAXAEXTNUM;
- sz = (mp->m_flags & XFS_MOUNT_ATTR2) ?
- XFS_BMDR_SPACE_CALC(MINABTPTRS) :
- mp->m_sb.sb_inodesize - mp->m_attroffset;
- }
- maxrootrecs = (int)XFS_BTREE_BLOCK_MAXRECS(sz, xfs_bmdr, 0);
- minleafrecs = mp->m_bmap_dmnr[0];
- minnoderecs = mp->m_bmap_dmnr[1];
- maxblocks = (maxleafents + minleafrecs - 1) / minleafrecs;
- for (level = 1; maxblocks > 1; level++) {
- if (maxblocks <= maxrootrecs)
- maxblocks = 1;
- else
- maxblocks = (maxblocks + minnoderecs - 1) / minnoderecs;
- }
- mp->m_bm_maxlevels[whichfork] = level;
-}
-
-/*
- * Routine to be called at transaction's end by xfs_bmapi, xfs_bunmapi
- * caller. Frees all the extents that need freeing, which must be done
- * last due to locking considerations. We never free any extents in
- * the first transaction. This is to allow the caller to make the first
- * transaction a synchronous one so that the pointers to the data being
- * broken in this transaction will be permanent before the data is actually
- * freed. This is necessary to prevent blocks from being reallocated
- * and written to before the free and reallocation are actually permanent.
- * We do not just make the first transaction synchronous here, because
- * there are more efficient ways to gain the same protection in some cases
- * (see the file truncation code).
- *
- * Return 1 if the given transaction was committed and a new one
- * started, and 0 otherwise in the committed parameter.
- */
-/*ARGSUSED*/
-int /* error */
-xfs_bmap_finish(
- xfs_trans_t **tp, /* transaction pointer addr */
- xfs_bmap_free_t *flist, /* i/o: list extents to free */
- xfs_fsblock_t firstblock, /* controlled ag for allocs */
- int *committed) /* xact committed or not */
-{
- xfs_efd_log_item_t *efd; /* extent free data */
- xfs_efi_log_item_t *efi; /* extent free intention */
- int error; /* error return value */
- xfs_bmap_free_item_t *free; /* free extent item */
- unsigned int logres; /* new log reservation */
- unsigned int logcount; /* new log count */
- xfs_mount_t *mp; /* filesystem mount structure */
- xfs_bmap_free_item_t *next; /* next item on free list */
- xfs_trans_t *ntp; /* new transaction pointer */
-
- ASSERT((*tp)->t_flags & XFS_TRANS_PERM_LOG_RES);
- if (flist->xbf_count == 0) {
- *committed = 0;
- return 0;
- }
- ntp = *tp;
- efi = xfs_trans_get_efi(ntp, flist->xbf_count);
- for (free = flist->xbf_first; free; free = free->xbfi_next)
- xfs_trans_log_efi_extent(ntp, efi, free->xbfi_startblock,
- free->xbfi_blockcount);
- logres = ntp->t_log_res;
- logcount = ntp->t_log_count;
- ntp = xfs_trans_dup(*tp);
- error = xfs_trans_commit(*tp, 0, NULL);
- *tp = ntp;
- *committed = 1;
- /*
- * We have a new transaction, so we should return committed=1,
- * even though we're returning an error.
- */
- if (error) {
- return error;
- }
- if ((error = xfs_trans_reserve(ntp, 0, logres, 0, XFS_TRANS_PERM_LOG_RES,
- logcount)))
- return error;
- efd = xfs_trans_get_efd(ntp, efi, flist->xbf_count);
- for (free = flist->xbf_first; free != NULL; free = next) {
- next = free->xbfi_next;
- if ((error = xfs_free_extent(ntp, free->xbfi_startblock,
- free->xbfi_blockcount))) {
- /*
- * The bmap free list will be cleaned up at a
- * higher level. The EFI will be canceled when
- * this transaction is aborted.
- * Need to force shutdown here to make sure it
- * happens, since this transaction may not be
- * dirty yet.
- */
- mp = ntp->t_mountp;
- if (!XFS_FORCED_SHUTDOWN(mp))
- xfs_force_shutdown(mp,
- (error == EFSCORRUPTED) ?
- XFS_CORRUPT_INCORE :
- XFS_METADATA_IO_ERROR);
- return error;
- }
- xfs_trans_log_efd_extent(ntp, efd, free->xbfi_startblock,
- free->xbfi_blockcount);
- xfs_bmap_del_free(flist, NULL, free);
- }
- return 0;
-}
-
-/*
- * Free up any items left in the list.
- */
-void
-xfs_bmap_cancel(
- xfs_bmap_free_t *flist) /* list of bmap_free_items */
-{
- xfs_bmap_free_item_t *free; /* free list item */
- xfs_bmap_free_item_t *next;
-
- if (flist->xbf_count == 0)
- return;
- ASSERT(flist->xbf_first != NULL);
- for (free = flist->xbf_first; free; free = next) {
- next = free->xbfi_next;
- xfs_bmap_del_free(flist, NULL, free);
- }
- ASSERT(flist->xbf_count == 0);
-}
-
-/*
- * Returns the file-relative block number of the first unused block(s)
- * in the file with at least "len" logically contiguous blocks free.
- * This is the lowest-address hole if the file has holes, else the first block
- * past the end of file.
- * Return 0 if the file is currently local (in-inode).
- */
-int /* error */
-xfs_bmap_first_unused(
- xfs_trans_t *tp, /* transaction pointer */
- xfs_inode_t *ip, /* incore inode */
- xfs_extlen_t len, /* size of hole to find */
- xfs_fileoff_t *first_unused, /* unused block */
- int whichfork) /* data or attr fork */
-{
- xfs_bmbt_rec_t *ep; /* pointer to an extent entry */
- int error; /* error return value */
- int idx; /* extent record index */
- xfs_ifork_t *ifp; /* inode fork pointer */
- xfs_fileoff_t lastaddr; /* last block number seen */
- xfs_fileoff_t lowest; /* lowest useful block */
- xfs_fileoff_t max; /* starting useful block */
- xfs_fileoff_t off; /* offset for this block */
- xfs_extnum_t nextents; /* number of extent entries */
-
- ASSERT(XFS_IFORK_FORMAT(ip, whichfork) == XFS_DINODE_FMT_BTREE ||
- XFS_IFORK_FORMAT(ip, whichfork) == XFS_DINODE_FMT_EXTENTS ||
- XFS_IFORK_FORMAT(ip, whichfork) == XFS_DINODE_FMT_LOCAL);
- if (XFS_IFORK_FORMAT(ip, whichfork) == XFS_DINODE_FMT_LOCAL) {
- *first_unused = 0;
- return 0;
- }
- ifp = XFS_IFORK_PTR(ip, whichfork);
- if (!(ifp->if_flags & XFS_IFEXTENTS) &&
- (error = xfs_iread_extents(tp, ip, whichfork)))
- return error;
- lowest = *first_unused;
- nextents = ifp->if_bytes / (uint)sizeof(xfs_bmbt_rec_t);
- for (idx = 0, lastaddr = 0, max = lowest; idx < nextents; idx++) {
- ep = xfs_iext_get_ext(ifp, idx);
- off = xfs_bmbt_get_startoff(ep);
- /*
- * See if the hole before this extent will work.
- */
- if (off >= lowest + len && off - max >= len) {
- *first_unused = max;
- return 0;
- }
- lastaddr = off + xfs_bmbt_get_blockcount(ep);
- max = XFS_FILEOFF_MAX(lastaddr, lowest);
- }
- *first_unused = max;
- return 0;
-}
-
-/*
- * Returns the file-relative block number of the last block + 1 before
- * last_block (input value) in the file.
- * This is not based on i_size, it is based on the extent records.
- * Returns 0 for local files, as they do not have extent records.
- */
-int /* error */
-xfs_bmap_last_before(
- xfs_trans_t *tp, /* transaction pointer */
- xfs_inode_t *ip, /* incore inode */
- xfs_fileoff_t *last_block, /* last block */
- int whichfork) /* data or attr fork */
-{
- xfs_fileoff_t bno; /* input file offset */
- int eof; /* hit end of file */
- xfs_bmbt_rec_t *ep; /* pointer to last extent */
- int error; /* error return value */
- xfs_bmbt_irec_t got; /* current extent value */
- xfs_ifork_t *ifp; /* inode fork pointer */
- xfs_extnum_t lastx; /* last extent used */
- xfs_bmbt_irec_t prev; /* previous extent value */
-
- if (XFS_IFORK_FORMAT(ip, whichfork) != XFS_DINODE_FMT_BTREE &&
- XFS_IFORK_FORMAT(ip, whichfork) != XFS_DINODE_FMT_EXTENTS &&
- XFS_IFORK_FORMAT(ip, whichfork) != XFS_DINODE_FMT_LOCAL)
- return XFS_ERROR(EIO);
- if (XFS_IFORK_FORMAT(ip, whichfork) == XFS_DINODE_FMT_LOCAL) {
- *last_block = 0;
- return 0;
- }
- ifp = XFS_IFORK_PTR(ip, whichfork);
- if (!(ifp->if_flags & XFS_IFEXTENTS) &&
- (error = xfs_iread_extents(tp, ip, whichfork)))
- return error;
- bno = *last_block - 1;
- ep = xfs_bmap_search_extents(ip, bno, whichfork, &eof, &lastx, &got,
- &prev);
- if (eof || xfs_bmbt_get_startoff(ep) > bno) {
- if (prev.br_startoff == NULLFILEOFF)
- *last_block = 0;
- else
- *last_block = prev.br_startoff + prev.br_blockcount;
- }
- /*
- * Otherwise *last_block is already the right answer.
- */
- return 0;
-}
-
-/*
- * Returns the file-relative block number of the first block past eof in
- * the file. This is not based on i_size, it is based on the extent records.
- * Returns 0 for local files, as they do not have extent records.
- */
-int /* error */
-xfs_bmap_last_offset(
- xfs_trans_t *tp, /* transaction pointer */
- xfs_inode_t *ip, /* incore inode */
- xfs_fileoff_t *last_block, /* last block */
- int whichfork) /* data or attr fork */
-{
- xfs_bmbt_rec_t *ep; /* pointer to last extent */
- int error; /* error return value */
- xfs_ifork_t *ifp; /* inode fork pointer */
- xfs_extnum_t nextents; /* number of extent entries */
-
- if (XFS_IFORK_FORMAT(ip, whichfork) != XFS_DINODE_FMT_BTREE &&
- XFS_IFORK_FORMAT(ip, whichfork) != XFS_DINODE_FMT_EXTENTS &&
- XFS_IFORK_FORMAT(ip, whichfork) != XFS_DINODE_FMT_LOCAL)
- return XFS_ERROR(EIO);
- if (XFS_IFORK_FORMAT(ip, whichfork) == XFS_DINODE_FMT_LOCAL) {
- *last_block = 0;
- return 0;
- }
- ifp = XFS_IFORK_PTR(ip, whichfork);
- if (!(ifp->if_flags & XFS_IFEXTENTS) &&
- (error = xfs_iread_extents(tp, ip, whichfork)))
- return error;
- nextents = ifp->if_bytes / (uint)sizeof(xfs_bmbt_rec_t);
- if (!nextents) {
- *last_block = 0;
- return 0;
- }
- ep = xfs_iext_get_ext(ifp, nextents - 1);
- *last_block = xfs_bmbt_get_startoff(ep) + xfs_bmbt_get_blockcount(ep);
- return 0;
-}
-
-/*
- * Returns whether the selected fork of the inode has exactly one
- * block or not. For the data fork we check this matches di_size,
- * implying the file's range is 0..bsize-1.
- */
-int /* 1=>1 block, 0=>otherwise */
-xfs_bmap_one_block(
- xfs_inode_t *ip, /* incore inode */
- int whichfork) /* data or attr fork */
-{
- xfs_bmbt_rec_t *ep; /* ptr to fork's extent */
- xfs_ifork_t *ifp; /* inode fork pointer */
- int rval; /* return value */
- xfs_bmbt_irec_t s; /* internal version of extent */
-
-#ifndef DEBUG
- if (whichfork == XFS_DATA_FORK)
- return ip->i_d.di_size == ip->i_mount->m_sb.sb_blocksize;
-#endif /* !DEBUG */
- if (XFS_IFORK_NEXTENTS(ip, whichfork) != 1)
- return 0;
- if (XFS_IFORK_FORMAT(ip, whichfork) != XFS_DINODE_FMT_EXTENTS)
- return 0;
- ifp = XFS_IFORK_PTR(ip, whichfork);
- ASSERT(ifp->if_flags & XFS_IFEXTENTS);
- ep = xfs_iext_get_ext(ifp, 0);
- xfs_bmbt_get_all(ep, &s);
- rval = s.br_startoff == 0 && s.br_blockcount == 1;
- if (rval && whichfork == XFS_DATA_FORK)
- ASSERT(ip->i_d.di_size == ip->i_mount->m_sb.sb_blocksize);
- return rval;
-}
-
-/*
- * Read in the extents to if_extents.
- * All inode fields are set up by caller, we just traverse the btree
- * and copy the records in. If the file system cannot contain unwritten
- * extents, the records are checked for no "state" flags.
- */
-int /* error */
-xfs_bmap_read_extents(
- xfs_trans_t *tp, /* transaction pointer */
- xfs_inode_t *ip, /* incore inode */
- int whichfork) /* data or attr fork */
-{
- xfs_bmbt_block_t *block; /* current btree block */
- xfs_fsblock_t bno; /* block # of "block" */
- xfs_buf_t *bp; /* buffer for "block" */
- int error; /* error return value */
- xfs_exntfmt_t exntf; /* XFS_EXTFMT_NOSTATE, if checking */
-#ifdef XFS_BMAP_TRACE
- static char fname[] = "xfs_bmap_read_extents";
-#endif
- xfs_extnum_t i, j; /* index into the extents list */
- xfs_ifork_t *ifp; /* fork structure */
- int level; /* btree level, for checking */
- xfs_mount_t *mp; /* file system mount structure */
- xfs_bmbt_ptr_t *pp; /* pointer to block address */
- /* REFERENCED */
- xfs_extnum_t room; /* number of entries there's room for */
-
- bno = NULLFSBLOCK;
- mp = ip->i_mount;
- ifp = XFS_IFORK_PTR(ip, whichfork);
- exntf = (whichfork != XFS_DATA_FORK) ? XFS_EXTFMT_NOSTATE :
- XFS_EXTFMT_INODE(ip);
- block = ifp->if_broot;
- /*
- * Root level must use BMAP_BROOT_PTR_ADDR macro to get ptr out.
- */
- level = be16_to_cpu(block->bb_level);
- ASSERT(level > 0);
- pp = XFS_BMAP_BROOT_PTR_ADDR(block, 1, ifp->if_broot_bytes);
- ASSERT(INT_GET(*pp, ARCH_CONVERT) != NULLDFSBNO);
- ASSERT(XFS_FSB_TO_AGNO(mp, INT_GET(*pp, ARCH_CONVERT)) < mp->m_sb.sb_agcount);
- ASSERT(XFS_FSB_TO_AGBNO(mp, INT_GET(*pp, ARCH_CONVERT)) < mp->m_sb.sb_agblocks);
- bno = INT_GET(*pp, ARCH_CONVERT);
- /*
- * Go down the tree until leaf level is reached, following the first
- * pointer (leftmost) at each level.
- */
- while (level-- > 0) {
- if ((error = xfs_btree_read_bufl(mp, tp, bno, 0, &bp,
- XFS_BMAP_BTREE_REF)))
- return error;
- block = XFS_BUF_TO_BMBT_BLOCK(bp);
- XFS_WANT_CORRUPTED_GOTO(
- XFS_BMAP_SANITY_CHECK(mp, block, level),
- error0);
- if (level == 0)
- break;
- pp = XFS_BTREE_PTR_ADDR(mp->m_sb.sb_blocksize, xfs_bmbt, block,
- 1, mp->m_bmap_dmxr[1]);
- XFS_WANT_CORRUPTED_GOTO(
- XFS_FSB_SANITY_CHECK(mp, INT_GET(*pp, ARCH_CONVERT)),
- error0);
- bno = INT_GET(*pp, ARCH_CONVERT);
- xfs_trans_brelse(tp, bp);
- }
- /*
- * Here with bp and block set to the leftmost leaf node in the tree.
- */
- room = ifp->if_bytes / (uint)sizeof(xfs_bmbt_rec_t);
- i = 0;
- /*
- * Loop over all leaf nodes. Copy information to the extent records.
- */
- for (;;) {
- xfs_bmbt_rec_t *frp, *trp;
- xfs_fsblock_t nextbno;
- xfs_extnum_t num_recs;
- xfs_extnum_t start;
-
-
- num_recs = be16_to_cpu(block->bb_numrecs);
- if (unlikely(i + num_recs > room)) {
- ASSERT(i + num_recs <= room);
- xfs_fs_repair_cmn_err(CE_WARN, ip->i_mount,
- "corrupt dinode %Lu, (btree extents).",
- (unsigned long long) ip->i_ino);
- XFS_ERROR_REPORT("xfs_bmap_read_extents(1)",
- XFS_ERRLEVEL_LOW,
- ip->i_mount);
- goto error0;
- }
- XFS_WANT_CORRUPTED_GOTO(
- XFS_BMAP_SANITY_CHECK(mp, block, 0),
- error0);
- /*
- * Read-ahead the next leaf block, if any.
- */
- nextbno = be64_to_cpu(block->bb_rightsib);
- if (nextbno != NULLFSBLOCK)
- xfs_btree_reada_bufl(mp, nextbno, 1);
- /*
- * Copy records into the extent records.
- */
- frp = XFS_BTREE_REC_ADDR(mp->m_sb.sb_blocksize, xfs_bmbt,
- block, 1, mp->m_bmap_dmxr[0]);
- start = i;
- for (j = 0; j < num_recs; j++, i++, frp++) {
- trp = xfs_iext_get_ext(ifp, i);
- trp->l0 = INT_GET(frp->l0, ARCH_CONVERT);
- trp->l1 = INT_GET(frp->l1, ARCH_CONVERT);
- }
- if (exntf == XFS_EXTFMT_NOSTATE) {
- /*
- * Check all attribute bmap btree records and
- * any "older" data bmap btree records for a
- * set bit in the "extent flag" position.
- */
- if (unlikely(xfs_check_nostate_extents(ifp,
- start, num_recs))) {
- XFS_ERROR_REPORT("xfs_bmap_read_extents(2)",
- XFS_ERRLEVEL_LOW,
- ip->i_mount);
- goto error0;
- }
- }
- xfs_trans_brelse(tp, bp);
- bno = nextbno;
- /*
- * If we've reached the end, stop.
- */
- if (bno == NULLFSBLOCK)
- break;
- if ((error = xfs_btree_read_bufl(mp, tp, bno, 0, &bp,
- XFS_BMAP_BTREE_REF)))
- return error;
- block = XFS_BUF_TO_BMBT_BLOCK(bp);
- }
- ASSERT(i == (ifp->if_bytes / (uint)sizeof(xfs_bmbt_rec_t)));
- ASSERT(i == XFS_IFORK_NEXTENTS(ip, whichfork));
- xfs_bmap_trace_exlist(fname, ip, i, whichfork);
- return 0;
-error0:
- xfs_trans_brelse(tp, bp);
- return XFS_ERROR(EFSCORRUPTED);
-}
-
-#ifdef XFS_BMAP_TRACE
-/*
- * Add bmap trace insert entries for all the contents of the extent records.
- */
-void
-xfs_bmap_trace_exlist(
- char *fname, /* function name */
- xfs_inode_t *ip, /* incore inode pointer */
- xfs_extnum_t cnt, /* count of entries in the list */
- int whichfork) /* data or attr fork */
-{
- xfs_bmbt_rec_t *ep; /* current extent record */
- xfs_extnum_t idx; /* extent record index */
- xfs_ifork_t *ifp; /* inode fork pointer */
- xfs_bmbt_irec_t s; /* file extent record */
-
- ifp = XFS_IFORK_PTR(ip, whichfork);
- ASSERT(cnt == (ifp->if_bytes / (uint)sizeof(xfs_bmbt_rec_t)));
- for (idx = 0; idx < cnt; idx++) {
- ep = xfs_iext_get_ext(ifp, idx);
- xfs_bmbt_get_all(ep, &s);
- xfs_bmap_trace_insert(fname, "exlist", ip, idx, 1, &s, NULL,
- whichfork);
- }
-}
-#endif
-
-#ifdef DEBUG
-/*
- * Validate that the bmbt_irecs being returned from bmapi are valid
- * given the callers original parameters. Specifically check the
- * ranges of the returned irecs to ensure that they only extent beyond
- * the given parameters if the XFS_BMAPI_ENTIRE flag was set.
- */
-STATIC void
-xfs_bmap_validate_ret(
- xfs_fileoff_t bno,
- xfs_filblks_t len,
- int flags,
- xfs_bmbt_irec_t *mval,
- int nmap,
- int ret_nmap)
-{
- int i; /* index to map values */
-
- ASSERT(ret_nmap <= nmap);
-
- for (i = 0; i < ret_nmap; i++) {
- ASSERT(mval[i].br_blockcount > 0);
- if (!(flags & XFS_BMAPI_ENTIRE)) {
- ASSERT(mval[i].br_startoff >= bno);
- ASSERT(mval[i].br_blockcount <= len);
- ASSERT(mval[i].br_startoff + mval[i].br_blockcount <=
- bno + len);
- } else {
- ASSERT(mval[i].br_startoff < bno + len);
- ASSERT(mval[i].br_startoff + mval[i].br_blockcount >
- bno);
- }
- ASSERT(i == 0 ||
- mval[i - 1].br_startoff + mval[i - 1].br_blockcount ==
- mval[i].br_startoff);
- if ((flags & XFS_BMAPI_WRITE) && !(flags & XFS_BMAPI_DELAY))
- ASSERT(mval[i].br_startblock != DELAYSTARTBLOCK &&
- mval[i].br_startblock != HOLESTARTBLOCK);
- ASSERT(mval[i].br_state == XFS_EXT_NORM ||
- mval[i].br_state == XFS_EXT_UNWRITTEN);
- }
-}
-#endif /* DEBUG */
-
-
-/*
- * Map file blocks to filesystem blocks.
- * File range is given by the bno/len pair.
- * Adds blocks to file if a write ("flags & XFS_BMAPI_WRITE" set)
- * into a hole or past eof.
- * Only allocates blocks from a single allocation group,
- * to avoid locking problems.
- * The returned value in "firstblock" from the first call in a transaction
- * must be remembered and presented to subsequent calls in "firstblock".
- * An upper bound for the number of blocks to be allocated is supplied to
- * the first call in "total"; if no allocation group has that many free
- * blocks then the call will fail (return NULLFSBLOCK in "firstblock").
- */
-int /* error */
-xfs_bmapi(
- xfs_trans_t *tp, /* transaction pointer */
- xfs_inode_t *ip, /* incore inode */
- xfs_fileoff_t bno, /* starting file offs. mapped */
- xfs_filblks_t len, /* length to map in file */
- int flags, /* XFS_BMAPI_... */
- xfs_fsblock_t *firstblock, /* first allocated block
- controls a.g. for allocs */
- xfs_extlen_t total, /* total blocks needed */
- xfs_bmbt_irec_t *mval, /* output: map values */
- int *nmap, /* i/o: mval size/count */
- xfs_bmap_free_t *flist, /* i/o: list extents to free */
- xfs_extdelta_t *delta) /* o: change made to incore extents */
-{
- xfs_fsblock_t abno; /* allocated block number */
- xfs_extlen_t alen; /* allocated extent length */
- xfs_fileoff_t aoff; /* allocated file offset */
- xfs_bmalloca_t bma; /* args for xfs_bmap_alloc */
- xfs_btree_cur_t *cur; /* bmap btree cursor */
- xfs_fileoff_t end; /* end of mapped file region */
- int eof; /* we've hit the end of extents */
- xfs_bmbt_rec_t *ep; /* extent record pointer */
- int error; /* error return */
- xfs_bmbt_irec_t got; /* current file extent record */
- xfs_ifork_t *ifp; /* inode fork pointer */
- xfs_extlen_t indlen; /* indirect blocks length */
- xfs_extnum_t lastx; /* last useful extent number */
- int logflags; /* flags for transaction logging */
- xfs_extlen_t minleft; /* min blocks left after allocation */
- xfs_extlen_t minlen; /* min allocation size */
- xfs_mount_t *mp; /* xfs mount structure */
- int n; /* current extent index */
- int nallocs; /* number of extents alloc\'d */
- xfs_extnum_t nextents; /* number of extents in file */
- xfs_fileoff_t obno; /* old block number (offset) */
- xfs_bmbt_irec_t prev; /* previous file extent record */
- int tmp_logflags; /* temp flags holder */
- int whichfork; /* data or attr fork */
- char inhole; /* current location is hole in file */
- char wasdelay; /* old extent was delayed */
- char wr; /* this is a write request */
- char rt; /* this is a realtime file */
-#ifdef DEBUG
- xfs_fileoff_t orig_bno; /* original block number value */
- int orig_flags; /* original flags arg value */
- xfs_filblks_t orig_len; /* original value of len arg */
- xfs_bmbt_irec_t *orig_mval; /* original value of mval */
- int orig_nmap; /* original value of *nmap */
-
- orig_bno = bno;
- orig_len = len;
- orig_flags = flags;
- orig_mval = mval;
- orig_nmap = *nmap;
-#endif
- ASSERT(*nmap >= 1);
- ASSERT(*nmap <= XFS_BMAP_MAX_NMAP || !(flags & XFS_BMAPI_WRITE));
- whichfork = (flags & XFS_BMAPI_ATTRFORK) ?
- XFS_ATTR_FORK : XFS_DATA_FORK;
- mp = ip->i_mount;
- if (unlikely(XFS_TEST_ERROR(
- (XFS_IFORK_FORMAT(ip, whichfork) != XFS_DINODE_FMT_EXTENTS &&
- XFS_IFORK_FORMAT(ip, whichfork) != XFS_DINODE_FMT_BTREE &&
- XFS_IFORK_FORMAT(ip, whichfork) != XFS_DINODE_FMT_LOCAL),
- mp, XFS_ERRTAG_BMAPIFORMAT, XFS_RANDOM_BMAPIFORMAT))) {
- XFS_ERROR_REPORT("xfs_bmapi", XFS_ERRLEVEL_LOW, mp);
- return XFS_ERROR(EFSCORRUPTED);
- }
- if (XFS_FORCED_SHUTDOWN(mp))
- return XFS_ERROR(EIO);
- rt = (whichfork == XFS_DATA_FORK) && XFS_IS_REALTIME_INODE(ip);
- ifp = XFS_IFORK_PTR(ip, whichfork);
- ASSERT(ifp->if_ext_max ==
- XFS_IFORK_SIZE(ip, whichfork) / (uint)sizeof(xfs_bmbt_rec_t));
- if ((wr = (flags & XFS_BMAPI_WRITE)) != 0)
- XFS_STATS_INC(xs_blk_mapw);
- else
- XFS_STATS_INC(xs_blk_mapr);
- /*
- * IGSTATE flag is used to combine extents which
- * differ only due to the state of the extents.
- * This technique is used from xfs_getbmap()
- * when the caller does not wish to see the
- * separation (which is the default).
- *
- * This technique is also used when writing a
- * buffer which has been partially written,
- * (usually by being flushed during a chunkread),
- * to ensure one write takes place. This also
- * prevents a change in the xfs inode extents at
- * this time, intentionally. This change occurs
- * on completion of the write operation, in
- * xfs_strat_comp(), where the xfs_bmapi() call
- * is transactioned, and the extents combined.
- */
- if ((flags & XFS_BMAPI_IGSTATE) && wr) /* if writing unwritten space */
- wr = 0; /* no allocations are allowed */
- ASSERT(wr || !(flags & XFS_BMAPI_DELAY));
- logflags = 0;
- nallocs = 0;
- cur = NULL;
- if (XFS_IFORK_FORMAT(ip, whichfork) == XFS_DINODE_FMT_LOCAL) {
- ASSERT(wr && tp);
- if ((error = xfs_bmap_local_to_extents(tp, ip,
- firstblock, total, &logflags, whichfork)))
- goto error0;
- }
- if (wr && *firstblock == NULLFSBLOCK) {
- if (XFS_IFORK_FORMAT(ip, whichfork) == XFS_DINODE_FMT_BTREE)
- minleft = be16_to_cpu(ifp->if_broot->bb_level) + 1;
- else
- minleft = 1;
- } else
- minleft = 0;
- if (!(ifp->if_flags & XFS_IFEXTENTS) &&
- (error = xfs_iread_extents(tp, ip, whichfork)))
- goto error0;
- ep = xfs_bmap_search_extents(ip, bno, whichfork, &eof, &lastx, &got,
- &prev);
- nextents = ifp->if_bytes / (uint)sizeof(xfs_bmbt_rec_t);
- n = 0;
- end = bno + len;
- obno = bno;
- bma.ip = NULL;
- if (delta) {
- delta->xed_startoff = NULLFILEOFF;
- delta->xed_blockcount = 0;
- }
- while (bno < end && n < *nmap) {
- /*
- * Reading past eof, act as though there's a hole
- * up to end.
- */
- if (eof && !wr)
- got.br_startoff = end;
- inhole = eof || got.br_startoff > bno;
- wasdelay = wr && !inhole && !(flags & XFS_BMAPI_DELAY) &&
- ISNULLSTARTBLOCK(got.br_startblock);
- /*
- * First, deal with the hole before the allocated space
- * that we found, if any.
- */
- if (wr && (inhole || wasdelay)) {
- /*
- * For the wasdelay case, we could also just
- * allocate the stuff asked for in this bmap call
- * but that wouldn't be as good.
- */
- if (wasdelay && !(flags & XFS_BMAPI_EXACT)) {
- alen = (xfs_extlen_t)got.br_blockcount;
- aoff = got.br_startoff;
- if (lastx != NULLEXTNUM && lastx) {
- ep = xfs_iext_get_ext(ifp, lastx - 1);
- xfs_bmbt_get_all(ep, &prev);
- }
- } else if (wasdelay) {
- alen = (xfs_extlen_t)
- XFS_FILBLKS_MIN(len,
- (got.br_startoff +
- got.br_blockcount) - bno);
- aoff = bno;
- } else {
- alen = (xfs_extlen_t)
- XFS_FILBLKS_MIN(len, MAXEXTLEN);
- if (!eof)
- alen = (xfs_extlen_t)
- XFS_FILBLKS_MIN(alen,
- got.br_startoff - bno);
- aoff = bno;
- }
- minlen = (flags & XFS_BMAPI_CONTIG) ? alen : 1;
- if (flags & XFS_BMAPI_DELAY) {
- xfs_extlen_t extsz;
-
- /* Figure out the extent size, adjust alen */
- if (rt) {
- if (!(extsz = ip->i_d.di_extsize))
- extsz = mp->m_sb.sb_rextsize;
- } else {
- extsz = ip->i_d.di_extsize;
- }
- if (extsz) {
- error = xfs_bmap_extsize_align(mp,
- &got, &prev, extsz,
- rt, eof,
- flags&XFS_BMAPI_DELAY,
- flags&XFS_BMAPI_CONVERT,
- &aoff, &alen);
- ASSERT(!error);
- }
-
- if (rt)
- extsz = alen / mp->m_sb.sb_rextsize;
-
- /*
- * Make a transaction-less quota reservation for
- * delayed allocation blocks. This number gets
- * adjusted later. We return if we haven't
- * allocated blocks already inside this loop.
- */
- if ((error = XFS_TRANS_RESERVE_QUOTA_NBLKS(
- mp, NULL, ip, (long)alen, 0,
- rt ? XFS_QMOPT_RES_RTBLKS :
- XFS_QMOPT_RES_REGBLKS))) {
- if (n == 0) {
- *nmap = 0;
- ASSERT(cur == NULL);
- return error;
- }
- break;
- }
-
- /*
- * Split changing sb for alen and indlen since
- * they could be coming from different places.
- */
- indlen = (xfs_extlen_t)
- xfs_bmap_worst_indlen(ip, alen);
- ASSERT(indlen > 0);
-
- if (rt) {
- error = xfs_mod_incore_sb(mp,
- XFS_SBS_FREXTENTS,
- -(extsz), (flags &
- XFS_BMAPI_RSVBLOCKS));
- } else {
- error = xfs_mod_incore_sb(mp,
- XFS_SBS_FDBLOCKS,
- -(alen), (flags &
- XFS_BMAPI_RSVBLOCKS));
- }
- if (!error) {
- error = xfs_mod_incore_sb(mp,
- XFS_SBS_FDBLOCKS,
- -(indlen), (flags &
- XFS_BMAPI_RSVBLOCKS));
- if (error && rt)
- xfs_mod_incore_sb(mp,
- XFS_SBS_FREXTENTS,
- extsz, (flags &
- XFS_BMAPI_RSVBLOCKS));
- else if (error)
- xfs_mod_incore_sb(mp,
- XFS_SBS_FDBLOCKS,
- alen, (flags &
- XFS_BMAPI_RSVBLOCKS));
- }
-
- if (error) {
- if (XFS_IS_QUOTA_ON(mp))
- /* unreserve the blocks now */
- (void)
- XFS_TRANS_UNRESERVE_QUOTA_NBLKS(
- mp, NULL, ip,
- (long)alen, 0, rt ?
- XFS_QMOPT_RES_RTBLKS :
- XFS_QMOPT_RES_REGBLKS);
- break;
- }
-
- ip->i_delayed_blks += alen;
- abno = NULLSTARTBLOCK(indlen);
- } else {
- /*
- * If first time, allocate and fill in
- * once-only bma fields.
- */
- if (bma.ip == NULL) {
- bma.tp = tp;
- bma.ip = ip;
- bma.prevp = &prev;
- bma.gotp = &got;
- bma.total = total;
- bma.userdata = 0;
- }
- /* Indicate if this is the first user data
- * in the file, or just any user data.
- */
- if (!(flags & XFS_BMAPI_METADATA)) {
- bma.userdata = (aoff == 0) ?
- XFS_ALLOC_INITIAL_USER_DATA :
- XFS_ALLOC_USERDATA;
- }
- /*
- * Fill in changeable bma fields.
- */
- bma.eof = eof;
- bma.firstblock = *firstblock;
- bma.alen = alen;
- bma.off = aoff;
- bma.conv = (flags & XFS_BMAPI_CONVERT) != 0;
- bma.wasdel = wasdelay;
- bma.minlen = minlen;
- bma.low = flist->xbf_low;
- bma.minleft = minleft;
- /*
- * Only want to do the alignment at the
- * eof if it is userdata and allocation length
- * is larger than a stripe unit.
- */
- if (mp->m_dalign && alen >= mp->m_dalign &&
- (!(flags & XFS_BMAPI_METADATA)) &&
- (whichfork == XFS_DATA_FORK)) {
- if ((error = xfs_bmap_isaeof(ip, aoff,
- whichfork, &bma.aeof)))
- goto error0;
- } else
- bma.aeof = 0;
- /*
- * Call allocator.
- */
- if ((error = xfs_bmap_alloc(&bma)))
- goto error0;
- /*
- * Copy out result fields.
- */
- abno = bma.rval;
- if ((flist->xbf_low = bma.low))
- minleft = 0;
- alen = bma.alen;
- aoff = bma.off;
- ASSERT(*firstblock == NULLFSBLOCK ||
- XFS_FSB_TO_AGNO(mp, *firstblock) ==
- XFS_FSB_TO_AGNO(mp, bma.firstblock) ||
- (flist->xbf_low &&
- XFS_FSB_TO_AGNO(mp, *firstblock) <
- XFS_FSB_TO_AGNO(mp, bma.firstblock)));
- *firstblock = bma.firstblock;
- if (cur)
- cur->bc_private.b.firstblock =
- *firstblock;
- if (abno == NULLFSBLOCK)
- break;
- if ((ifp->if_flags & XFS_IFBROOT) && !cur) {
- cur = xfs_btree_init_cursor(mp,
- tp, NULL, 0, XFS_BTNUM_BMAP,
- ip, whichfork);
- cur->bc_private.b.firstblock =
- *firstblock;
- cur->bc_private.b.flist = flist;
- }
- /*
- * Bump the number of extents we've allocated
- * in this call.
- */
- nallocs++;
- }
- if (cur)
- cur->bc_private.b.flags =
- wasdelay ? XFS_BTCUR_BPRV_WASDEL : 0;
- got.br_startoff = aoff;
- got.br_startblock = abno;
- got.br_blockcount = alen;
- got.br_state = XFS_EXT_NORM; /* assume normal */
- /*
- * Determine state of extent, and the filesystem.
- * A wasdelay extent has been initialized, so
- * shouldn't be flagged as unwritten.
- */
- if (wr && XFS_SB_VERSION_HASEXTFLGBIT(&mp->m_sb)) {
- if (!wasdelay && (flags & XFS_BMAPI_PREALLOC))
- got.br_state = XFS_EXT_UNWRITTEN;
- }
- error = xfs_bmap_add_extent(ip, lastx, &cur, &got,
- firstblock, flist, &tmp_logflags, delta,
- whichfork, (flags & XFS_BMAPI_RSVBLOCKS));
- logflags |= tmp_logflags;
- if (error)
- goto error0;
- lastx = ifp->if_lastex;
- ep = xfs_iext_get_ext(ifp, lastx);
- nextents = ifp->if_bytes / (uint)sizeof(xfs_bmbt_rec_t);
- xfs_bmbt_get_all(ep, &got);
- ASSERT(got.br_startoff <= aoff);
- ASSERT(got.br_startoff + got.br_blockcount >=
- aoff + alen);
-#ifdef DEBUG
- if (flags & XFS_BMAPI_DELAY) {
- ASSERT(ISNULLSTARTBLOCK(got.br_startblock));
- ASSERT(STARTBLOCKVAL(got.br_startblock) > 0);
- }
- ASSERT(got.br_state == XFS_EXT_NORM ||
- got.br_state == XFS_EXT_UNWRITTEN);
-#endif
- /*
- * Fall down into the found allocated space case.
- */
- } else if (inhole) {
- /*
- * Reading in a hole.
- */
- mval->br_startoff = bno;
- mval->br_startblock = HOLESTARTBLOCK;
- mval->br_blockcount =
- XFS_FILBLKS_MIN(len, got.br_startoff - bno);
- mval->br_state = XFS_EXT_NORM;
- bno += mval->br_blockcount;
- len -= mval->br_blockcount;
- mval++;
- n++;
- continue;
- }
- /*
- * Then deal with the allocated space we found.
- */
- ASSERT(ep != NULL);
- if (!(flags & XFS_BMAPI_ENTIRE) &&
- (got.br_startoff + got.br_blockcount > obno)) {
- if (obno > bno)
- bno = obno;
- ASSERT((bno >= obno) || (n == 0));
- ASSERT(bno < end);
- mval->br_startoff = bno;
- if (ISNULLSTARTBLOCK(got.br_startblock)) {
- ASSERT(!wr || (flags & XFS_BMAPI_DELAY));
- mval->br_startblock = DELAYSTARTBLOCK;
- } else
- mval->br_startblock =
- got.br_startblock +
- (bno - got.br_startoff);
- /*
- * Return the minimum of what we got and what we
- * asked for for the length. We can use the len
- * variable here because it is modified below
- * and we could have been there before coming
- * here if the first part of the allocation
- * didn't overlap what was asked for.
- */
- mval->br_blockcount =
- XFS_FILBLKS_MIN(end - bno, got.br_blockcount -
- (bno - got.br_startoff));
- mval->br_state = got.br_state;
- ASSERT(mval->br_blockcount <= len);
- } else {
- *mval = got;
- if (ISNULLSTARTBLOCK(mval->br_startblock)) {
- ASSERT(!wr || (flags & XFS_BMAPI_DELAY));
- mval->br_startblock = DELAYSTARTBLOCK;
- }
- }
-
- /*
- * Check if writing previously allocated but
- * unwritten extents.
- */
- if (wr && mval->br_state == XFS_EXT_UNWRITTEN &&
- ((flags & (XFS_BMAPI_PREALLOC|XFS_BMAPI_DELAY)) == 0)) {
- /*
- * Modify (by adding) the state flag, if writing.
- */
- ASSERT(mval->br_blockcount <= len);
- if ((ifp->if_flags & XFS_IFBROOT) && !cur) {
- cur = xfs_btree_init_cursor(mp,
- tp, NULL, 0, XFS_BTNUM_BMAP,
- ip, whichfork);
- cur->bc_private.b.firstblock =
- *firstblock;
- cur->bc_private.b.flist = flist;
- }
- mval->br_state = XFS_EXT_NORM;
- error = xfs_bmap_add_extent(ip, lastx, &cur, mval,
- firstblock, flist, &tmp_logflags, delta,
- whichfork, (flags & XFS_BMAPI_RSVBLOCKS));
- logflags |= tmp_logflags;
- if (error)
- goto error0;
- lastx = ifp->if_lastex;
- ep = xfs_iext_get_ext(ifp, lastx);
- nextents = ifp->if_bytes / (uint)sizeof(xfs_bmbt_rec_t);
- xfs_bmbt_get_all(ep, &got);
- /*
- * We may have combined previously unwritten
- * space with written space, so generate
- * another request.
- */
- if (mval->br_blockcount < len)
- continue;
- }
-
- ASSERT((flags & XFS_BMAPI_ENTIRE) ||
- ((mval->br_startoff + mval->br_blockcount) <= end));
- ASSERT((flags & XFS_BMAPI_ENTIRE) ||
- (mval->br_blockcount <= len) ||
- (mval->br_startoff < obno));
- bno = mval->br_startoff + mval->br_blockcount;
- len = end - bno;
- if (n > 0 && mval->br_startoff == mval[-1].br_startoff) {
- ASSERT(mval->br_startblock == mval[-1].br_startblock);
- ASSERT(mval->br_blockcount > mval[-1].br_blockcount);
- ASSERT(mval->br_state == mval[-1].br_state);
- mval[-1].br_blockcount = mval->br_blockcount;
- mval[-1].br_state = mval->br_state;
- } else if (n > 0 && mval->br_startblock != DELAYSTARTBLOCK &&
- mval[-1].br_startblock != DELAYSTARTBLOCK &&
- mval[-1].br_startblock != HOLESTARTBLOCK &&
- mval->br_startblock ==
- mval[-1].br_startblock + mval[-1].br_blockcount &&
- ((flags & XFS_BMAPI_IGSTATE) ||
- mval[-1].br_state == mval->br_state)) {
- ASSERT(mval->br_startoff ==
- mval[-1].br_startoff + mval[-1].br_blockcount);
- mval[-1].br_blockcount += mval->br_blockcount;
- } else if (n > 0 &&
- mval->br_startblock == DELAYSTARTBLOCK &&
- mval[-1].br_startblock == DELAYSTARTBLOCK &&
- mval->br_startoff ==
- mval[-1].br_startoff + mval[-1].br_blockcount) {
- mval[-1].br_blockcount += mval->br_blockcount;
- mval[-1].br_state = mval->br_state;
- } else if (!((n == 0) &&
- ((mval->br_startoff + mval->br_blockcount) <=
- obno))) {
- mval++;
- n++;
- }
- /*
- * If we're done, stop now. Stop when we've allocated
- * XFS_BMAP_MAX_NMAP extents no matter what. Otherwise
- * the transaction may get too big.
- */
- if (bno >= end || n >= *nmap || nallocs >= *nmap)
- break;
- /*
- * Else go on to the next record.
- */
- ep = xfs_iext_get_ext(ifp, ++lastx);
- if (lastx >= nextents) {
- eof = 1;
- prev = got;
- } else
- xfs_bmbt_get_all(ep, &got);
- }
- ifp->if_lastex = lastx;
- *nmap = n;
- /*
- * Transform from btree to extents, give it cur.
- */
- if (tp && XFS_IFORK_FORMAT(ip, whichfork) == XFS_DINODE_FMT_BTREE &&
- XFS_IFORK_NEXTENTS(ip, whichfork) <= ifp->if_ext_max) {
- ASSERT(wr && cur);
- error = xfs_bmap_btree_to_extents(tp, ip, cur,
- &tmp_logflags, whichfork);
- logflags |= tmp_logflags;
- if (error)
- goto error0;
- }
- ASSERT(ifp->if_ext_max ==
- XFS_IFORK_SIZE(ip, whichfork) / (uint)sizeof(xfs_bmbt_rec_t));
- ASSERT(XFS_IFORK_FORMAT(ip, whichfork) != XFS_DINODE_FMT_BTREE ||
- XFS_IFORK_NEXTENTS(ip, whichfork) > ifp->if_ext_max);
- error = 0;
- if (delta && delta->xed_startoff != NULLFILEOFF) {
- /* A change was actually made.
- * Note that delta->xed_blockount is an offset at this
- * point and needs to be converted to a block count.
- */
- ASSERT(delta->xed_blockcount > delta->xed_startoff);
- delta->xed_blockcount -= delta->xed_startoff;
- }
-error0:
- /*
- * Log everything. Do this after conversion, there's no point in
- * logging the extent records if we've converted to btree format.
- */
- if ((logflags & XFS_ILOG_FEXT(whichfork)) &&
- XFS_IFORK_FORMAT(ip, whichfork) != XFS_DINODE_FMT_EXTENTS)
- logflags &= ~XFS_ILOG_FEXT(whichfork);
- else if ((logflags & XFS_ILOG_FBROOT(whichfork)) &&
- XFS_IFORK_FORMAT(ip, whichfork) != XFS_DINODE_FMT_BTREE)
- logflags &= ~XFS_ILOG_FBROOT(whichfork);
- /*
- * Log whatever the flags say, even if error. Otherwise we might miss
- * detecting a case where the data is changed, there's an error,
- * and it's not logged so we don't shutdown when we should.
- */
- if (logflags) {
- ASSERT(tp && wr);
- xfs_trans_log_inode(tp, ip, logflags);
- }
- if (cur) {
- if (!error) {
- ASSERT(*firstblock == NULLFSBLOCK ||
- XFS_FSB_TO_AGNO(mp, *firstblock) ==
- XFS_FSB_TO_AGNO(mp,
- cur->bc_private.b.firstblock) ||
- (flist->xbf_low &&
- XFS_FSB_TO_AGNO(mp, *firstblock) <
- XFS_FSB_TO_AGNO(mp,
- cur->bc_private.b.firstblock)));
- *firstblock = cur->bc_private.b.firstblock;
- }
- xfs_btree_del_cursor(cur,
- error ? XFS_BTREE_ERROR : XFS_BTREE_NOERROR);
- }
- if (!error)
- xfs_bmap_validate_ret(orig_bno, orig_len, orig_flags, orig_mval,
- orig_nmap, *nmap);
- return error;
-}
-
-/*
- * Map file blocks to filesystem blocks, simple version.
- * One block (extent) only, read-only.
- * For flags, only the XFS_BMAPI_ATTRFORK flag is examined.
- * For the other flag values, the effect is as if XFS_BMAPI_METADATA
- * was set and all the others were clear.
- */
-int /* error */
-xfs_bmapi_single(
- xfs_trans_t *tp, /* transaction pointer */
- xfs_inode_t *ip, /* incore inode */
- int whichfork, /* data or attr fork */
- xfs_fsblock_t *fsb, /* output: mapped block */
- xfs_fileoff_t bno) /* starting file offs. mapped */
-{
- int eof; /* we've hit the end of extents */
- int error; /* error return */
- xfs_bmbt_irec_t got; /* current file extent record */
- xfs_ifork_t *ifp; /* inode fork pointer */
- xfs_extnum_t lastx; /* last useful extent number */
- xfs_bmbt_irec_t prev; /* previous file extent record */
-
- ifp = XFS_IFORK_PTR(ip, whichfork);
- if (unlikely(
- XFS_IFORK_FORMAT(ip, whichfork) != XFS_DINODE_FMT_BTREE &&
- XFS_IFORK_FORMAT(ip, whichfork) != XFS_DINODE_FMT_EXTENTS)) {
- XFS_ERROR_REPORT("xfs_bmapi_single", XFS_ERRLEVEL_LOW,
- ip->i_mount);
- return XFS_ERROR(EFSCORRUPTED);
- }
- if (XFS_FORCED_SHUTDOWN(ip->i_mount))
- return XFS_ERROR(EIO);
- XFS_STATS_INC(xs_blk_mapr);
- if (!(ifp->if_flags & XFS_IFEXTENTS) &&
- (error = xfs_iread_extents(tp, ip, whichfork)))
- return error;
- (void)xfs_bmap_search_extents(ip, bno, whichfork, &eof, &lastx, &got,
- &prev);
- /*
- * Reading past eof, act as though there's a hole
- * up to end.
- */
- if (eof || got.br_startoff > bno) {
- *fsb = NULLFSBLOCK;
- return 0;
- }
- ASSERT(!ISNULLSTARTBLOCK(got.br_startblock));
- ASSERT(bno < got.br_startoff + got.br_blockcount);
- *fsb = got.br_startblock + (bno - got.br_startoff);
- ifp->if_lastex = lastx;
- return 0;
-}
-
-/*
- * Unmap (remove) blocks from a file.
- * If nexts is nonzero then the number of extents to remove is limited to
- * that value. If not all extents in the block range can be removed then
- * *done is set.
- */
-int /* error */
-xfs_bunmapi(
- xfs_trans_t *tp, /* transaction pointer */
- struct xfs_inode *ip, /* incore inode */
- xfs_fileoff_t bno, /* starting offset to unmap */
- xfs_filblks_t len, /* length to unmap in file */
- int flags, /* misc flags */
- xfs_extnum_t nexts, /* number of extents max */
- xfs_fsblock_t *firstblock, /* first allocated block
- controls a.g. for allocs */
- xfs_bmap_free_t *flist, /* i/o: list extents to free */
- xfs_extdelta_t *delta, /* o: change made to incore
- extents */
- int *done) /* set if not done yet */
-{
- xfs_btree_cur_t *cur; /* bmap btree cursor */
- xfs_bmbt_irec_t del; /* extent being deleted */
- int eof; /* is deleting at eof */
- xfs_bmbt_rec_t *ep; /* extent record pointer */
- int error; /* error return value */
- xfs_extnum_t extno; /* extent number in list */
- xfs_bmbt_irec_t got; /* current extent record */
- xfs_ifork_t *ifp; /* inode fork pointer */
- int isrt; /* freeing in rt area */
- xfs_extnum_t lastx; /* last extent index used */
- int logflags; /* transaction logging flags */
- xfs_extlen_t mod; /* rt extent offset */
- xfs_mount_t *mp; /* mount structure */
- xfs_extnum_t nextents; /* number of file extents */
- xfs_bmbt_irec_t prev; /* previous extent record */
- xfs_fileoff_t start; /* first file offset deleted */
- int tmp_logflags; /* partial logging flags */
- int wasdel; /* was a delayed alloc extent */
- int whichfork; /* data or attribute fork */
- int rsvd; /* OK to allocate reserved blocks */
- xfs_fsblock_t sum;
-
- xfs_bunmap_trace(ip, bno, len, flags, (inst_t *)__return_address);
- whichfork = (flags & XFS_BMAPI_ATTRFORK) ?
- XFS_ATTR_FORK : XFS_DATA_FORK;
- ifp = XFS_IFORK_PTR(ip, whichfork);
- if (unlikely(
- XFS_IFORK_FORMAT(ip, whichfork) != XFS_DINODE_FMT_EXTENTS &&
- XFS_IFORK_FORMAT(ip, whichfork) != XFS_DINODE_FMT_BTREE)) {
- XFS_ERROR_REPORT("xfs_bunmapi", XFS_ERRLEVEL_LOW,
- ip->i_mount);
- return XFS_ERROR(EFSCORRUPTED);
- }
- mp = ip->i_mount;
- if (XFS_FORCED_SHUTDOWN(mp))
- return XFS_ERROR(EIO);
- rsvd = (flags & XFS_BMAPI_RSVBLOCKS) != 0;
- ASSERT(len > 0);
- ASSERT(nexts >= 0);
- ASSERT(ifp->if_ext_max ==
- XFS_IFORK_SIZE(ip, whichfork) / (uint)sizeof(xfs_bmbt_rec_t));
- if (!(ifp->if_flags & XFS_IFEXTENTS) &&
- (error = xfs_iread_extents(tp, ip, whichfork)))
- return error;
- nextents = ifp->if_bytes / (uint)sizeof(xfs_bmbt_rec_t);
- if (nextents == 0) {
- *done = 1;
- return 0;
- }
- XFS_STATS_INC(xs_blk_unmap);
- isrt = (whichfork == XFS_DATA_FORK) && XFS_IS_REALTIME_INODE(ip);
- start = bno;
- bno = start + len - 1;
- ep = xfs_bmap_search_extents(ip, bno, whichfork, &eof, &lastx, &got,
- &prev);
- if (delta) {
- delta->xed_startoff = NULLFILEOFF;
- delta->xed_blockcount = 0;
- }
- /*
- * Check to see if the given block number is past the end of the
- * file, back up to the last block if so...
- */
- if (eof) {
- ep = xfs_iext_get_ext(ifp, --lastx);
- xfs_bmbt_get_all(ep, &got);
- bno = got.br_startoff + got.br_blockcount - 1;
- }
- logflags = 0;
- if (ifp->if_flags & XFS_IFBROOT) {
- ASSERT(XFS_IFORK_FORMAT(ip, whichfork) == XFS_DINODE_FMT_BTREE);
- cur = xfs_btree_init_cursor(mp, tp, NULL, 0, XFS_BTNUM_BMAP, ip,
- whichfork);
- cur->bc_private.b.firstblock = *firstblock;
- cur->bc_private.b.flist = flist;
- cur->bc_private.b.flags = 0;
- } else
- cur = NULL;
- extno = 0;
- while (bno != (xfs_fileoff_t)-1 && bno >= start && lastx >= 0 &&
- (nexts == 0 || extno < nexts)) {
- /*
- * Is the found extent after a hole in which bno lives?
- * Just back up to the previous extent, if so.
- */
- if (got.br_startoff > bno) {
- if (--lastx < 0)
- break;
- ep = xfs_iext_get_ext(ifp, lastx);
- xfs_bmbt_get_all(ep, &got);
- }
- /*
- * Is the last block of this extent before the range
- * we're supposed to delete? If so, we're done.
- */
- bno = XFS_FILEOFF_MIN(bno,
- got.br_startoff + got.br_blockcount - 1);
- if (bno < start)
- break;
- /*
- * Then deal with the (possibly delayed) allocated space
- * we found.
- */
- ASSERT(ep != NULL);
- del = got;
- wasdel = ISNULLSTARTBLOCK(del.br_startblock);
- if (got.br_startoff < start) {
- del.br_startoff = start;
- del.br_blockcount -= start - got.br_startoff;
- if (!wasdel)
- del.br_startblock += start - got.br_startoff;
- }
- if (del.br_startoff + del.br_blockcount > bno + 1)
- del.br_blockcount = bno + 1 - del.br_startoff;
- sum = del.br_startblock + del.br_blockcount;
- if (isrt &&
- (mod = do_mod(sum, mp->m_sb.sb_rextsize))) {
- /*
- * Realtime extent not lined up at the end.
- * The extent could have been split into written
- * and unwritten pieces, or we could just be
- * unmapping part of it. But we can't really
- * get rid of part of a realtime extent.
- */
- if (del.br_state == XFS_EXT_UNWRITTEN ||
- !XFS_SB_VERSION_HASEXTFLGBIT(&mp->m_sb)) {
- /*
- * This piece is unwritten, or we're not
- * using unwritten extents. Skip over it.
- */
- ASSERT(bno >= mod);
- bno -= mod > del.br_blockcount ?
- del.br_blockcount : mod;
- if (bno < got.br_startoff) {
- if (--lastx >= 0)
- xfs_bmbt_get_all(xfs_iext_get_ext(
- ifp, lastx), &got);
- }
- continue;
- }
- /*
- * It's written, turn it unwritten.
- * This is better than zeroing it.
- */
- ASSERT(del.br_state == XFS_EXT_NORM);
- ASSERT(xfs_trans_get_block_res(tp) > 0);
- /*
- * If this spans a realtime extent boundary,
- * chop it back to the start of the one we end at.
- */
- if (del.br_blockcount > mod) {
- del.br_startoff += del.br_blockcount - mod;
- del.br_startblock += del.br_blockcount - mod;
- del.br_blockcount = mod;
- }
- del.br_state = XFS_EXT_UNWRITTEN;
- error = xfs_bmap_add_extent(ip, lastx, &cur, &del,
- firstblock, flist, &logflags, delta,
- XFS_DATA_FORK, 0);
- if (error)
- goto error0;
- goto nodelete;
- }
- if (isrt && (mod = do_mod(del.br_startblock, mp->m_sb.sb_rextsize))) {
- /*
- * Realtime extent is lined up at the end but not
- * at the front. We'll get rid of full extents if
- * we can.
- */
- mod = mp->m_sb.sb_rextsize - mod;
- if (del.br_blockcount > mod) {
- del.br_blockcount -= mod;
- del.br_startoff += mod;
- del.br_startblock += mod;
- } else if ((del.br_startoff == start &&
- (del.br_state == XFS_EXT_UNWRITTEN ||
- xfs_trans_get_block_res(tp) == 0)) ||
- !XFS_SB_VERSION_HASEXTFLGBIT(&mp->m_sb)) {
- /*
- * Can't make it unwritten. There isn't
- * a full extent here so just skip it.
- */
- ASSERT(bno >= del.br_blockcount);
- bno -= del.br_blockcount;
- if (bno < got.br_startoff) {
- if (--lastx >= 0)
- xfs_bmbt_get_all(--ep, &got);
- }
- continue;
- } else if (del.br_state == XFS_EXT_UNWRITTEN) {
- /*
- * This one is already unwritten.
- * It must have a written left neighbor.
- * Unwrite the killed part of that one and
- * try again.
- */
- ASSERT(lastx > 0);
- xfs_bmbt_get_all(xfs_iext_get_ext(ifp,
- lastx - 1), &prev);
- ASSERT(prev.br_state == XFS_EXT_NORM);
- ASSERT(!ISNULLSTARTBLOCK(prev.br_startblock));
- ASSERT(del.br_startblock ==
- prev.br_startblock + prev.br_blockcount);
- if (prev.br_startoff < start) {
- mod = start - prev.br_startoff;
- prev.br_blockcount -= mod;
- prev.br_startblock += mod;
- prev.br_startoff = start;
- }
- prev.br_state = XFS_EXT_UNWRITTEN;
- error = xfs_bmap_add_extent(ip, lastx - 1, &cur,
- &prev, firstblock, flist, &logflags,
- delta, XFS_DATA_FORK, 0);
- if (error)
- goto error0;
- goto nodelete;
- } else {
- ASSERT(del.br_state == XFS_EXT_NORM);
- del.br_state = XFS_EXT_UNWRITTEN;
- error = xfs_bmap_add_extent(ip, lastx, &cur,
- &del, firstblock, flist, &logflags,
- delta, XFS_DATA_FORK, 0);
- if (error)
- goto error0;
- goto nodelete;
- }
- }
- if (wasdel) {
- ASSERT(STARTBLOCKVAL(del.br_startblock) > 0);
- /* Update realtime/data freespace, unreserve quota */
- if (isrt) {
- xfs_filblks_t rtexts;
-
- rtexts = XFS_FSB_TO_B(mp, del.br_blockcount);
- do_div(rtexts, mp->m_sb.sb_rextsize);
- xfs_mod_incore_sb(mp, XFS_SBS_FREXTENTS,
- (int)rtexts, rsvd);
- (void)XFS_TRANS_RESERVE_QUOTA_NBLKS(mp,
- NULL, ip, -((long)del.br_blockcount), 0,
- XFS_QMOPT_RES_RTBLKS);
- } else {
- xfs_mod_incore_sb(mp, XFS_SBS_FDBLOCKS,
- (int)del.br_blockcount, rsvd);
- (void)XFS_TRANS_RESERVE_QUOTA_NBLKS(mp,
- NULL, ip, -((long)del.br_blockcount), 0,
- XFS_QMOPT_RES_REGBLKS);
- }
- ip->i_delayed_blks -= del.br_blockcount;
- if (cur)
- cur->bc_private.b.flags |=
- XFS_BTCUR_BPRV_WASDEL;
- } else if (cur)
- cur->bc_private.b.flags &= ~XFS_BTCUR_BPRV_WASDEL;
- /*
- * If it's the case where the directory code is running
- * with no block reservation, and the deleted block is in
- * the middle of its extent, and the resulting insert
- * of an extent would cause transformation to btree format,
- * then reject it. The calling code will then swap
- * blocks around instead.
- * We have to do this now, rather than waiting for the
- * conversion to btree format, since the transaction
- * will be dirty.
- */
- if (!wasdel && xfs_trans_get_block_res(tp) == 0 &&
- XFS_IFORK_FORMAT(ip, whichfork) == XFS_DINODE_FMT_EXTENTS &&
- XFS_IFORK_NEXTENTS(ip, whichfork) >= ifp->if_ext_max &&
- del.br_startoff > got.br_startoff &&
- del.br_startoff + del.br_blockcount <
- got.br_startoff + got.br_blockcount) {
- error = XFS_ERROR(ENOSPC);
- goto error0;
- }
- error = xfs_bmap_del_extent(ip, tp, lastx, flist, cur, &del,
- &tmp_logflags, delta, whichfork, rsvd);
- logflags |= tmp_logflags;
- if (error)
- goto error0;
- bno = del.br_startoff - 1;
-nodelete:
- lastx = ifp->if_lastex;
- /*
- * If not done go on to the next (previous) record.
- * Reset ep in case the extents array was re-alloced.
- */
- ep = xfs_iext_get_ext(ifp, lastx);
- if (bno != (xfs_fileoff_t)-1 && bno >= start) {
- if (lastx >= XFS_IFORK_NEXTENTS(ip, whichfork) ||
- xfs_bmbt_get_startoff(ep) > bno) {
- if (--lastx >= 0)
- ep = xfs_iext_get_ext(ifp, lastx);
- }
- if (lastx >= 0)
- xfs_bmbt_get_all(ep, &got);
- extno++;
- }
- }
- ifp->if_lastex = lastx;
- *done = bno == (xfs_fileoff_t)-1 || bno < start || lastx < 0;
- ASSERT(ifp->if_ext_max ==
- XFS_IFORK_SIZE(ip, whichfork) / (uint)sizeof(xfs_bmbt_rec_t));
- /*
- * Convert to a btree if necessary.
- */
- if (XFS_IFORK_FORMAT(ip, whichfork) == XFS_DINODE_FMT_EXTENTS &&
- XFS_IFORK_NEXTENTS(ip, whichfork) > ifp->if_ext_max) {
- ASSERT(cur == NULL);
- error = xfs_bmap_extents_to_btree(tp, ip, firstblock, flist,
- &cur, 0, &tmp_logflags, whichfork);
- logflags |= tmp_logflags;
- if (error)
- goto error0;
- }
- /*
- * transform from btree to extents, give it cur
- */
- else if (XFS_IFORK_FORMAT(ip, whichfork) == XFS_DINODE_FMT_BTREE &&
- XFS_IFORK_NEXTENTS(ip, whichfork) <= ifp->if_ext_max) {
- ASSERT(cur != NULL);
- error = xfs_bmap_btree_to_extents(tp, ip, cur, &tmp_logflags,
- whichfork);
- logflags |= tmp_logflags;
- if (error)
- goto error0;
- }
- /*
- * transform from extents to local?
- */
- ASSERT(ifp->if_ext_max ==
- XFS_IFORK_SIZE(ip, whichfork) / (uint)sizeof(xfs_bmbt_rec_t));
- error = 0;
- if (delta && delta->xed_startoff != NULLFILEOFF) {
- /* A change was actually made.
- * Note that delta->xed_blockount is an offset at this
- * point and needs to be converted to a block count.
- */
- ASSERT(delta->xed_blockcount > delta->xed_startoff);
- delta->xed_blockcount -= delta->xed_startoff;
- }
-error0:
- /*
- * Log everything. Do this after conversion, there's no point in
- * logging the extent records if we've converted to btree format.
- */
- if ((logflags & XFS_ILOG_FEXT(whichfork)) &&
- XFS_IFORK_FORMAT(ip, whichfork) != XFS_DINODE_FMT_EXTENTS)
- logflags &= ~XFS_ILOG_FEXT(whichfork);
- else if ((logflags & XFS_ILOG_FBROOT(whichfork)) &&
- XFS_IFORK_FORMAT(ip, whichfork) != XFS_DINODE_FMT_BTREE)
- logflags &= ~XFS_ILOG_FBROOT(whichfork);
- /*
- * Log inode even in the error case, if the transaction
- * is dirty we'll need to shut down the filesystem.
- */
- if (logflags)
- xfs_trans_log_inode(tp, ip, logflags);
- if (cur) {
- if (!error) {
- *firstblock = cur->bc_private.b.firstblock;
- cur->bc_private.b.allocated = 0;
- }
- xfs_btree_del_cursor(cur,
- error ? XFS_BTREE_ERROR : XFS_BTREE_NOERROR);
- }
- return error;
-}
-
-#undef copy_to_user
-static __inline__ int
-copy_to_user(void *dst, void *src, int len) {
- memcpy(dst,src,len);
- return 0;
-}
-#undef copy_from_user
-static __inline__ int
-copy_from_user(void *dst, void *src, int len) {
- memcpy(dst,src,len);
- return 0;
-}
-/*
- * Fcntl interface to xfs_bmapi.
- */
-int /* error code */
-xfs_getbmap(
- bhv_desc_t *bdp, /* XFS behavior descriptor*/
- struct getbmap *bmv, /* user bmap structure */
- void __user *ap, /* pointer to user's array */
- int interface) /* interface flags */
-{
- __int64_t bmvend; /* last block requested */
- int error; /* return value */
- __int64_t fixlen; /* length for -1 case */
- int i; /* extent number */
- xfs_inode_t *ip; /* xfs incore inode pointer */
- xfs_vnode_t *vp; /* corresponding vnode */
- int lock; /* lock state */
- xfs_bmbt_irec_t *map; /* buffer for user's data */
- xfs_mount_t *mp; /* file system mount point */
- int nex; /* # of user extents can do */
- int nexleft; /* # of user extents left */
- int subnex; /* # of bmapi's can do */
- int nmap; /* number of map entries */
- struct getbmap out; /* output structure */
- int whichfork; /* data or attr fork */
- int prealloced; /* this is a file with
- * preallocated data space */
- int sh_unwritten; /* true, if unwritten */
- /* extents listed separately */
- int bmapi_flags; /* flags for xfs_bmapi */
- __int32_t oflags; /* getbmapx bmv_oflags field */
-
- vp = BHV_TO_VNODE(bdp);
- ip = XFS_BHVTOI(bdp);
- mp = ip->i_mount;
-
- whichfork = interface & BMV_IF_ATTRFORK ? XFS_ATTR_FORK : XFS_DATA_FORK;
- sh_unwritten = (interface & BMV_IF_PREALLOC) != 0;
-
- /* If the BMV_IF_NO_DMAPI_READ interface bit specified, do not
- * generate a DMAPI read event. Otherwise, if the DM_EVENT_READ
- * bit is set for the file, generate a read event in order
- * that the DMAPI application may do its thing before we return
- * the extents. Usually this means restoring user file data to
- * regions of the file that look like holes.
- *
- * The "old behavior" (from XFS_IOC_GETBMAP) is to not specify
- * BMV_IF_NO_DMAPI_READ so that read events are generated.
- * If this were not true, callers of ioctl( XFS_IOC_GETBMAP )
- * could misinterpret holes in a DMAPI file as true holes,
- * when in fact they may represent offline user data.
- */
- if ( (interface & BMV_IF_NO_DMAPI_READ) == 0
- && DM_EVENT_ENABLED(vp->v_vfsp, ip, DM_EVENT_READ)
- && whichfork == XFS_DATA_FORK) {
-
- error = XFS_SEND_DATA(mp, DM_EVENT_READ, vp, 0, 0, 0, NULL);
- if (error)
- return XFS_ERROR(error);
- }
-
- if (whichfork == XFS_ATTR_FORK) {
- if (XFS_IFORK_Q(ip)) {
- if (ip->i_d.di_aformat != XFS_DINODE_FMT_EXTENTS &&
- ip->i_d.di_aformat != XFS_DINODE_FMT_BTREE &&
- ip->i_d.di_aformat != XFS_DINODE_FMT_LOCAL)
- return XFS_ERROR(EINVAL);
- } else if (unlikely(
- ip->i_d.di_aformat != 0 &&
- ip->i_d.di_aformat != XFS_DINODE_FMT_EXTENTS)) {
- XFS_ERROR_REPORT("xfs_getbmap", XFS_ERRLEVEL_LOW,
- ip->i_mount);
- return XFS_ERROR(EFSCORRUPTED);
- }
- } else if (ip->i_d.di_format != XFS_DINODE_FMT_EXTENTS &&
- ip->i_d.di_format != XFS_DINODE_FMT_BTREE &&
- ip->i_d.di_format != XFS_DINODE_FMT_LOCAL)
- return XFS_ERROR(EINVAL);
- if (whichfork == XFS_DATA_FORK) {
- if ((ip->i_d.di_extsize && (ip->i_d.di_flags &
- (XFS_DIFLAG_REALTIME|XFS_DIFLAG_EXTSIZE))) ||
- ip->i_d.di_flags & (XFS_DIFLAG_PREALLOC|XFS_DIFLAG_APPEND)){
- prealloced = 1;
- fixlen = XFS_MAXIOFFSET(mp);
- } else {
- prealloced = 0;
- fixlen = ip->i_d.di_size;
- }
- } else {
- prealloced = 0;
- fixlen = 1LL << 32;
- }
-
- if (bmv->bmv_length == -1) {
- fixlen = XFS_FSB_TO_BB(mp, XFS_B_TO_FSB(mp, fixlen));
- bmv->bmv_length = MAX( (__int64_t)(fixlen - bmv->bmv_offset),
- (__int64_t)0);
- } else if (bmv->bmv_length < 0)
- return XFS_ERROR(EINVAL);
- if (bmv->bmv_length == 0) {
- bmv->bmv_entries = 0;
- return 0;
- }
- nex = bmv->bmv_count - 1;
- if (nex <= 0)
- return XFS_ERROR(EINVAL);
- bmvend = bmv->bmv_offset + bmv->bmv_length;
-
- xfs_ilock(ip, XFS_IOLOCK_SHARED);
-
- if (whichfork == XFS_DATA_FORK && ip->i_delayed_blks) {
- /* xfs_fsize_t last_byte = xfs_file_last_byte(ip); */
- XVOP_FLUSH_PAGES(vp, (xfs_off_t)0, -1, 0, FI_REMAPF, error);
- }
-
- ASSERT(whichfork == XFS_ATTR_FORK || ip->i_delayed_blks == 0);
-
- lock = xfs_ilock_map_shared(ip);
-
- /*
- * Don't let nex be bigger than the number of extents
- * we can have assuming alternating holes and real extents.
- */
- if (nex > XFS_IFORK_NEXTENTS(ip, whichfork) * 2 + 1)
- nex = XFS_IFORK_NEXTENTS(ip, whichfork) * 2 + 1;
-
- bmapi_flags = XFS_BMAPI_AFLAG(whichfork) |
- ((sh_unwritten) ? 0 : XFS_BMAPI_IGSTATE);
-
- /*
- * Allocate enough space to handle "subnex" maps at a time.
- */
- subnex = 16;
- map = kmem_alloc(subnex * sizeof(*map), KM_SLEEP);
-
- bmv->bmv_entries = 0;
-
- if (XFS_IFORK_NEXTENTS(ip, whichfork) == 0) {
- error = 0;
- goto unlock_and_return;
- }
-
- nexleft = nex;
-
- do {
- nmap = (nexleft > subnex) ? subnex : nexleft;
- error = xfs_bmapi(NULL, ip, XFS_BB_TO_FSBT(mp, bmv->bmv_offset),
- XFS_BB_TO_FSB(mp, bmv->bmv_length),
- bmapi_flags, NULL, 0, map, &nmap,
- NULL, NULL);
- if (error)
- goto unlock_and_return;
- ASSERT(nmap <= subnex);
-
- for (i = 0; i < nmap && nexleft && bmv->bmv_length; i++) {
- nexleft--;
- oflags = (map[i].br_state == XFS_EXT_UNWRITTEN) ?
- BMV_OF_PREALLOC : 0;
- out.bmv_offset = XFS_FSB_TO_BB(mp, map[i].br_startoff);
- out.bmv_length = XFS_FSB_TO_BB(mp, map[i].br_blockcount);
- ASSERT(map[i].br_startblock != DELAYSTARTBLOCK);
- if (map[i].br_startblock == HOLESTARTBLOCK &&
- ((prealloced && out.bmv_offset + out.bmv_length == bmvend) ||
- whichfork == XFS_ATTR_FORK )) {
- /*
- * came to hole at end of file or the end of
- attribute fork
- */
- goto unlock_and_return;
- } else {
- out.bmv_block =
- (map[i].br_startblock == HOLESTARTBLOCK) ?
- -1 :
- XFS_FSB_TO_DB(ip, map[i].br_startblock);
-
- /* return either getbmap/getbmapx structure. */
- if (interface & BMV_IF_EXTENDED) {
- struct getbmapx outx;
-
- GETBMAP_CONVERT(out,outx);
- outx.bmv_oflags = oflags;
- outx.bmv_unused1 = outx.bmv_unused2 = 0;
- if (copy_to_user(ap, &outx,
- sizeof(outx))) {
- error = XFS_ERROR(EFAULT);
- goto unlock_and_return;
- }
- } else {
- if (copy_to_user(ap, &out,
- sizeof(out))) {
- error = XFS_ERROR(EFAULT);
- goto unlock_and_return;
- }
- }
- bmv->bmv_offset =
- out.bmv_offset + out.bmv_length;
- bmv->bmv_length = MAX((__int64_t)0,
- (__int64_t)(bmvend - bmv->bmv_offset));
- bmv->bmv_entries++;
- ap = (interface & BMV_IF_EXTENDED) ?
- (void __user *)
- ((struct getbmapx __user *)ap + 1) :
- (void __user *)
- ((struct getbmap __user *)ap + 1);
- }
- }
- } while (nmap && nexleft && bmv->bmv_length);
-
-unlock_and_return:
- xfs_iunlock_map_shared(ip, lock);
- xfs_iunlock(ip, XFS_IOLOCK_SHARED);
-
- kmem_free(map, subnex * sizeof(*map));
-
- return error;
-}
-
-/*
- * Check the last inode extent to determine whether this allocation will result
- * in blocks being allocated at the end of the file. When we allocate new data
- * blocks at the end of the file which do not start at the previous data block,
- * we will try to align the new blocks at stripe unit boundaries.
- */
-STATIC int /* error */
-xfs_bmap_isaeof(
- xfs_inode_t *ip, /* incore inode pointer */
- xfs_fileoff_t off, /* file offset in fsblocks */
- int whichfork, /* data or attribute fork */
- char *aeof) /* return value */
-{
- int error; /* error return value */
- xfs_ifork_t *ifp; /* inode fork pointer */
- xfs_bmbt_rec_t *lastrec; /* extent record pointer */
- xfs_extnum_t nextents; /* number of file extents */
- xfs_bmbt_irec_t s; /* expanded extent record */
-
- ASSERT(whichfork == XFS_DATA_FORK);
- ifp = XFS_IFORK_PTR(ip, whichfork);
- if (!(ifp->if_flags & XFS_IFEXTENTS) &&
- (error = xfs_iread_extents(NULL, ip, whichfork)))
- return error;
- nextents = ifp->if_bytes / (uint)sizeof(xfs_bmbt_rec_t);
- if (nextents == 0) {
- *aeof = 1;
- return 0;
- }
- /*
- * Go to the last extent
- */
- lastrec = xfs_iext_get_ext(ifp, nextents - 1);
- xfs_bmbt_get_all(lastrec, &s);
- /*
- * Check we are allocating in the last extent (for delayed allocations)
- * or past the last extent for non-delayed allocations.
- */
- *aeof = (off >= s.br_startoff &&
- off < s.br_startoff + s.br_blockcount &&
- ISNULLSTARTBLOCK(s.br_startblock)) ||
- off >= s.br_startoff + s.br_blockcount;
- return 0;
-}
-
-/*
- * Check if the endoff is outside the last extent. If so the caller will grow
- * the allocation to a stripe unit boundary.
- */
-int /* error */
-xfs_bmap_eof(
- xfs_inode_t *ip, /* incore inode pointer */
- xfs_fileoff_t endoff, /* file offset in fsblocks */
- int whichfork, /* data or attribute fork */
- int *eof) /* result value */
-{
- xfs_fsblock_t blockcount; /* extent block count */
- int error; /* error return value */
- xfs_ifork_t *ifp; /* inode fork pointer */
- xfs_bmbt_rec_t *lastrec; /* extent record pointer */
- xfs_extnum_t nextents; /* number of file extents */
- xfs_fileoff_t startoff; /* extent starting file offset */
-
- ASSERT(whichfork == XFS_DATA_FORK);
- ifp = XFS_IFORK_PTR(ip, whichfork);
- if (!(ifp->if_flags & XFS_IFEXTENTS) &&
- (error = xfs_iread_extents(NULL, ip, whichfork)))
- return error;
- nextents = ifp->if_bytes / (uint)sizeof(xfs_bmbt_rec_t);
- if (nextents == 0) {
- *eof = 1;
- return 0;
- }
- /*
- * Go to the last extent
- */
- lastrec = xfs_iext_get_ext(ifp, nextents - 1);
- startoff = xfs_bmbt_get_startoff(lastrec);
- blockcount = xfs_bmbt_get_blockcount(lastrec);
- *eof = endoff >= startoff + blockcount;
- return 0;
-}
-
-#ifdef DEBUG
-#if 0
-/*
- * Check that the extents list for the inode ip is in the right order.
- */
-STATIC void
-xfs_bmap_check_extents(
- xfs_inode_t *ip, /* incore inode pointer */
- int whichfork) /* data or attr fork */
-{
- xfs_bmbt_rec_t *ep; /* current extent entry */
- xfs_extnum_t idx; /* extent record index */
- xfs_ifork_t *ifp; /* inode fork pointer */
- xfs_extnum_t nextents; /* number of extents in list */
- xfs_bmbt_rec_t *nextp; /* next extent entry */
-
- ifp = XFS_IFORK_PTR(ip, whichfork);
- ASSERT(ifp->if_flags & XFS_IFEXTENTS);
- nextents = ifp->if_bytes / (uint)sizeof(xfs_bmbt_rec_t);
- ep = xfs_iext_get_ext(ifp, 0);
- for (idx = 0; idx < nextents - 1; idx++) {
- nextp = xfs_iext_get_ext(ifp, idx + 1);
- xfs_btree_check_rec(XFS_BTNUM_BMAP, (void *)ep,
- (void *)(nextp));
- ep = nextp;
- }
-}
-#endif
-
-STATIC
-xfs_buf_t *
-xfs_bmap_get_bp(
- xfs_btree_cur_t *cur,
- xfs_fsblock_t bno)
-{
- int i;
- xfs_buf_t *bp;
-
- if (!cur)
- return(NULL);
-
- bp = NULL;
- for(i = 0; i < XFS_BTREE_MAXLEVELS; i++) {
- bp = cur->bc_bufs[i];
- if (!bp) break;
- if (XFS_BUF_ADDR(bp) == bno)
- break; /* Found it */
- }
- if (i == XFS_BTREE_MAXLEVELS)
- bp = NULL;
-
- if (!bp) { /* Chase down all the log items to see if the bp is there */
- xfs_log_item_chunk_t *licp;
- xfs_trans_t *tp;
-
- tp = cur->bc_tp;
- licp = &tp->t_items;
- while (!bp && licp != NULL) {
- if (XFS_LIC_ARE_ALL_FREE(licp)) {
- licp = licp->lic_next;
- continue;
- }
- for (i = 0; i < licp->lic_unused; i++) {
- xfs_log_item_desc_t *lidp;
- xfs_log_item_t *lip;
- xfs_buf_log_item_t *bip;
- xfs_buf_t *lbp;
-
- if (XFS_LIC_ISFREE(licp, i)) {
- continue;
- }
-
- lidp = XFS_LIC_SLOT(licp, i);
- lip = lidp->lid_item;
- if (lip->li_type != XFS_LI_BUF)
- continue;
-
- bip = (xfs_buf_log_item_t *)lip;
- lbp = bip->bli_buf;
-
- if (XFS_BUF_ADDR(lbp) == bno) {
- bp = lbp;
- break; /* Found it */
- }
- }
- licp = licp->lic_next;
- }
- }
- return(bp);
-}
-
-STATIC void
-xfs_check_block(
- xfs_bmbt_block_t *block,
- xfs_mount_t *mp,
- int root,
- short sz)
-{
- int i, j, dmxr;
- xfs_bmbt_ptr_t *pp, *thispa; /* pointer to block address */
- xfs_bmbt_key_t *prevp, *keyp;
-
- ASSERT(be16_to_cpu(block->bb_level) > 0);
-
- prevp = NULL;
- for( i = 1; i <= be16_to_cpu(block->bb_numrecs); i++) {
- dmxr = mp->m_bmap_dmxr[0];
-
- if (root) {
- keyp = XFS_BMAP_BROOT_KEY_ADDR(block, i, sz);
- } else {
- keyp = XFS_BTREE_KEY_ADDR(mp->m_sb.sb_blocksize,
- xfs_bmbt, block, i, dmxr);
- }
-
- if (prevp) {
- xfs_btree_check_key(XFS_BTNUM_BMAP, prevp, keyp);
- }
- prevp = keyp;
-
- /*
- * Compare the block numbers to see if there are dups.
- */
-
- if (root) {
- pp = XFS_BMAP_BROOT_PTR_ADDR(block, i, sz);
- } else {
- pp = XFS_BTREE_PTR_ADDR(mp->m_sb.sb_blocksize,
- xfs_bmbt, block, i, dmxr);
- }
- for (j = i+1; j <= be16_to_cpu(block->bb_numrecs); j++) {
- if (root) {
- thispa = XFS_BMAP_BROOT_PTR_ADDR(block, j, sz);
- } else {
- thispa = XFS_BTREE_PTR_ADDR(mp->m_sb.sb_blocksize,
- xfs_bmbt, block, j, dmxr);
- }
- if (INT_GET(*thispa, ARCH_CONVERT) ==
- INT_GET(*pp, ARCH_CONVERT)) {
- cmn_err(CE_WARN, "%s: thispa(%d) == pp(%d) %Ld",
- __FUNCTION__, j, i,
- INT_GET(*thispa, ARCH_CONVERT));
- panic("%s: ptrs are equal in node\n",
- __FUNCTION__);
- }
- }
- }
-}
-
-/*
- * Check that the extents for the inode ip are in the right order in all
- * btree leaves.
- */
-
-STATIC void
-xfs_bmap_check_leaf_extents(
- xfs_btree_cur_t *cur, /* btree cursor or null */
- xfs_inode_t *ip, /* incore inode pointer */
- int whichfork) /* data or attr fork */
-{
- xfs_bmbt_block_t *block; /* current btree block */
- xfs_fsblock_t bno; /* block # of "block" */
- xfs_buf_t *bp; /* buffer for "block" */
- int error; /* error return value */
- xfs_extnum_t i=0, j; /* index into the extents list */
- xfs_ifork_t *ifp; /* fork structure */
- int level; /* btree level, for checking */
- xfs_mount_t *mp; /* file system mount structure */
- xfs_bmbt_ptr_t *pp; /* pointer to block address */
- xfs_bmbt_rec_t *ep; /* pointer to current extent */
- xfs_bmbt_rec_t *lastp; /* pointer to previous extent */
- xfs_bmbt_rec_t *nextp; /* pointer to next extent */
- int bp_release = 0;
-
- if (XFS_IFORK_FORMAT(ip, whichfork) != XFS_DINODE_FMT_BTREE) {
- return;
- }
-
- bno = NULLFSBLOCK;
- mp = ip->i_mount;
- ifp = XFS_IFORK_PTR(ip, whichfork);
- block = ifp->if_broot;
- /*
- * Root level must use BMAP_BROOT_PTR_ADDR macro to get ptr out.
- */
- level = be16_to_cpu(block->bb_level);
- ASSERT(level > 0);
- xfs_check_block(block, mp, 1, ifp->if_broot_bytes);
- pp = XFS_BMAP_BROOT_PTR_ADDR(block, 1, ifp->if_broot_bytes);
- ASSERT(INT_GET(*pp, ARCH_CONVERT) != NULLDFSBNO);
- ASSERT(XFS_FSB_TO_AGNO(mp, INT_GET(*pp, ARCH_CONVERT)) < mp->m_sb.sb_agcount);
- ASSERT(XFS_FSB_TO_AGBNO(mp, INT_GET(*pp, ARCH_CONVERT)) < mp->m_sb.sb_agblocks);
- bno = INT_GET(*pp, ARCH_CONVERT);
- /*
- * Go down the tree until leaf level is reached, following the first
- * pointer (leftmost) at each level.
- */
- while (level-- > 0) {
- /* See if buf is in cur first */
- bp = xfs_bmap_get_bp(cur, XFS_FSB_TO_DADDR(mp, bno));
- if (bp) {
- bp_release = 0;
- } else {
- bp_release = 1;
- }
- if (!bp && (error = xfs_btree_read_bufl(mp, NULL, bno, 0, &bp,
- XFS_BMAP_BTREE_REF)))
- goto error_norelse;
- block = XFS_BUF_TO_BMBT_BLOCK(bp);
- XFS_WANT_CORRUPTED_GOTO(
- XFS_BMAP_SANITY_CHECK(mp, block, level),
- error0);
- if (level == 0)
- break;
-
- /*
- * Check this block for basic sanity (increasing keys and
- * no duplicate blocks).
- */
-
- xfs_check_block(block, mp, 0, 0);
- pp = XFS_BTREE_PTR_ADDR(mp->m_sb.sb_blocksize, xfs_bmbt, block,
- 1, mp->m_bmap_dmxr[1]);
- XFS_WANT_CORRUPTED_GOTO(XFS_FSB_SANITY_CHECK(mp, INT_GET(*pp, ARCH_CONVERT)), error0);
- bno = INT_GET(*pp, ARCH_CONVERT);
- if (bp_release) {
- bp_release = 0;
- xfs_trans_brelse(NULL, bp);
- }
- }
-
- /*
- * Here with bp and block set to the leftmost leaf node in the tree.
- */
- i = 0;
-
- /*
- * Loop over all leaf nodes checking that all extents are in the right order.
- */
- lastp = NULL;
- for (;;) {
- xfs_fsblock_t nextbno;
- xfs_extnum_t num_recs;
-
-
- num_recs = be16_to_cpu(block->bb_numrecs);
-
- /*
- * Read-ahead the next leaf block, if any.
- */
-
- nextbno = be64_to_cpu(block->bb_rightsib);
-
- /*
- * Check all the extents to make sure they are OK.
- * If we had a previous block, the last entry should
- * conform with the first entry in this one.
- */
-
- ep = XFS_BTREE_REC_ADDR(mp->m_sb.sb_blocksize, xfs_bmbt,
- block, 1, mp->m_bmap_dmxr[0]);
- for (j = 1; j < num_recs; j++) {
- nextp = XFS_BTREE_REC_ADDR(mp->m_sb.sb_blocksize, xfs_bmbt,
- block, j + 1, mp->m_bmap_dmxr[0]);
- if (lastp) {
- xfs_btree_check_rec(XFS_BTNUM_BMAP,
- (void *)lastp, (void *)ep);
- }
- xfs_btree_check_rec(XFS_BTNUM_BMAP, (void *)ep,
- (void *)(nextp));
- lastp = ep;
- ep = nextp;
- }
-
- i += num_recs;
- if (bp_release) {
- bp_release = 0;
- xfs_trans_brelse(NULL, bp);
- }
- bno = nextbno;
- /*
- * If we've reached the end, stop.
- */
- if (bno == NULLFSBLOCK)
- break;
-
- bp = xfs_bmap_get_bp(cur, XFS_FSB_TO_DADDR(mp, bno));
- if (bp) {
- bp_release = 0;
- } else {
- bp_release = 1;
- }
- if (!bp && (error = xfs_btree_read_bufl(mp, NULL, bno, 0, &bp,
- XFS_BMAP_BTREE_REF)))
- goto error_norelse;
- block = XFS_BUF_TO_BMBT_BLOCK(bp);
- }
- if (bp_release) {
- bp_release = 0;
- xfs_trans_brelse(NULL, bp);
- }
- return;
-
-error0:
- cmn_err(CE_WARN, "%s: at error0", __FUNCTION__);
- if (bp_release)
- xfs_trans_brelse(NULL, bp);
-error_norelse:
- cmn_err(CE_WARN, "%s: BAD after btree leaves for %d extents",
- __FUNCTION__, i);
- panic("%s: CORRUPTED BTREE OR SOMETHING", __FUNCTION__);
- return;
-}
-#endif
-
-/*
- * Count fsblocks of the given fork.
- */
-int /* error */
-xfs_bmap_count_blocks(
- xfs_trans_t *tp, /* transaction pointer */
- xfs_inode_t *ip, /* incore inode */
- int whichfork, /* data or attr fork */
- int *count) /* out: count of blocks */
-{
- xfs_bmbt_block_t *block; /* current btree block */
- xfs_fsblock_t bno; /* block # of "block" */
- xfs_ifork_t *ifp; /* fork structure */
- int level; /* btree level, for checking */
- xfs_mount_t *mp; /* file system mount structure */
- xfs_bmbt_ptr_t *pp; /* pointer to block address */
-
- bno = NULLFSBLOCK;
- mp = ip->i_mount;
- ifp = XFS_IFORK_PTR(ip, whichfork);
- if ( XFS_IFORK_FORMAT(ip, whichfork) == XFS_DINODE_FMT_EXTENTS ) {
- if (unlikely(xfs_bmap_count_leaves(ifp, 0,
- ifp->if_bytes / (uint)sizeof(xfs_bmbt_rec_t),
- count) < 0)) {
- XFS_ERROR_REPORT("xfs_bmap_count_blocks(1)",
- XFS_ERRLEVEL_LOW, mp);
- return XFS_ERROR(EFSCORRUPTED);
- }
- return 0;
- }
-
- /*
- * Root level must use BMAP_BROOT_PTR_ADDR macro to get ptr out.
- */
- block = ifp->if_broot;
- level = be16_to_cpu(block->bb_level);
- ASSERT(level > 0);
- pp = XFS_BMAP_BROOT_PTR_ADDR(block, 1, ifp->if_broot_bytes);
- ASSERT(INT_GET(*pp, ARCH_CONVERT) != NULLDFSBNO);
- ASSERT(XFS_FSB_TO_AGNO(mp, INT_GET(*pp, ARCH_CONVERT)) < mp->m_sb.sb_agcount);
- ASSERT(XFS_FSB_TO_AGBNO(mp, INT_GET(*pp, ARCH_CONVERT)) < mp->m_sb.sb_agblocks);
- bno = INT_GET(*pp, ARCH_CONVERT);
-
- if (unlikely(xfs_bmap_count_tree(mp, tp, ifp, bno, level, count) < 0)) {
- XFS_ERROR_REPORT("xfs_bmap_count_blocks(2)", XFS_ERRLEVEL_LOW,
- mp);
- return XFS_ERROR(EFSCORRUPTED);
- }
-
- return 0;
-}
-
-/*
- * Recursively walks each level of a btree
- * to count total fsblocks is use.
- */
-int /* error */
-xfs_bmap_count_tree(
- xfs_mount_t *mp, /* file system mount point */
- xfs_trans_t *tp, /* transaction pointer */
- xfs_ifork_t *ifp, /* inode fork pointer */
- xfs_fsblock_t blockno, /* file system block number */
- int levelin, /* level in btree */
- int *count) /* Count of blocks */
-{
- int error;
- xfs_buf_t *bp, *nbp;
- int level = levelin;
- xfs_bmbt_ptr_t *pp;
- xfs_fsblock_t bno = blockno;
- xfs_fsblock_t nextbno;
- xfs_bmbt_block_t *block, *nextblock;
- int numrecs;
-
- if ((error = xfs_btree_read_bufl(mp, tp, bno, 0, &bp, XFS_BMAP_BTREE_REF)))
- return error;
- *count += 1;
- block = XFS_BUF_TO_BMBT_BLOCK(bp);
-
- if (--level) {
- /* Not at node above leafs, count this level of nodes */
- nextbno = be64_to_cpu(block->bb_rightsib);
- while (nextbno != NULLFSBLOCK) {
- if ((error = xfs_btree_read_bufl(mp, tp, nextbno,
- 0, &nbp, XFS_BMAP_BTREE_REF)))
- return error;
- *count += 1;
- nextblock = XFS_BUF_TO_BMBT_BLOCK(nbp);
- nextbno = be64_to_cpu(nextblock->bb_rightsib);
- xfs_trans_brelse(tp, nbp);
- }
-
- /* Dive to the next level */
- pp = XFS_BTREE_PTR_ADDR(mp->m_sb.sb_blocksize,
- xfs_bmbt, block, 1, mp->m_bmap_dmxr[1]);
- bno = INT_GET(*pp, ARCH_CONVERT);
- if (unlikely((error =
- xfs_bmap_count_tree(mp, tp, ifp, bno, level, count)) < 0)) {
- xfs_trans_brelse(tp, bp);
- XFS_ERROR_REPORT("xfs_bmap_count_tree(1)",
- XFS_ERRLEVEL_LOW, mp);
- return XFS_ERROR(EFSCORRUPTED);
- }
- xfs_trans_brelse(tp, bp);
- } else {
- /* count all level 1 nodes and their leaves */
- for (;;) {
- nextbno = be64_to_cpu(block->bb_rightsib);
- numrecs = be16_to_cpu(block->bb_numrecs);
- if (unlikely(xfs_bmap_disk_count_leaves(ifp, mp,
- 0, block, numrecs, count) < 0)) {
- xfs_trans_brelse(tp, bp);
- XFS_ERROR_REPORT("xfs_bmap_count_tree(2)",
- XFS_ERRLEVEL_LOW, mp);
- return XFS_ERROR(EFSCORRUPTED);
- }
- xfs_trans_brelse(tp, bp);
- if (nextbno == NULLFSBLOCK)
- break;
- bno = nextbno;
- if ((error = xfs_btree_read_bufl(mp, tp, bno, 0, &bp,
- XFS_BMAP_BTREE_REF)))
- return error;
- *count += 1;
- block = XFS_BUF_TO_BMBT_BLOCK(bp);
- }
- }
- return 0;
-}
-
-/*
- * Count leaf blocks given a range of extent records.
- */
-int
-xfs_bmap_count_leaves(
- xfs_ifork_t *ifp,
- xfs_extnum_t idx,
- int numrecs,
- int *count)
-{
- int b;
- xfs_bmbt_rec_t *frp;
-
- for (b = 0; b < numrecs; b++) {
- frp = xfs_iext_get_ext(ifp, idx + b);
- *count += xfs_bmbt_get_blockcount(frp);
- }
- return 0;
-}
-
-/*
- * Count leaf blocks given a range of extent records originally
- * in btree format.
- */
-int
-xfs_bmap_disk_count_leaves(
- xfs_ifork_t *ifp,
- xfs_mount_t *mp,
- xfs_extnum_t idx,
- xfs_bmbt_block_t *block,
- int numrecs,
- int *count)
-{
- int b;
- xfs_bmbt_rec_t *frp;
-
- for (b = 1; b <= numrecs; b++) {
- frp = XFS_BTREE_REC_ADDR(mp->m_sb.sb_blocksize,
- xfs_bmbt, block, idx + b, mp->m_bmap_dmxr[0]);
- *count += xfs_bmbt_disk_get_blockcount(frp);
- }
- return 0;
-}
-
-
diff --git a/sys/gnu/fs/xfs/xfs_bmap.h b/sys/gnu/fs/xfs/xfs_bmap.h
deleted file mode 100644
index 80e9340..0000000
--- a/sys/gnu/fs/xfs/xfs_bmap.h
+++ /dev/null
@@ -1,386 +0,0 @@
-/*
- * Copyright (c) 2000-2006 Silicon Graphics, Inc.
- * All Rights Reserved.
- *
- * 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.
- *
- * This program is distributed in the hope that it would 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 the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- */
-#ifndef __XFS_BMAP_H__
-#define __XFS_BMAP_H__
-
-struct getbmap;
-struct xfs_bmbt_irec;
-struct xfs_ifork;
-struct xfs_inode;
-struct xfs_mount;
-struct xfs_trans;
-
-/*
- * DELTA: describe a change to the in-core extent list.
- *
- * Internally the use of xed_blockount is somewhat funky.
- * xed_blockcount contains an offset much of the time because this
- * makes merging changes easier. (xfs_fileoff_t and xfs_filblks_t are
- * the same underlying type).
- */
-typedef struct xfs_extdelta
-{
- xfs_fileoff_t xed_startoff; /* offset of range */
- xfs_filblks_t xed_blockcount; /* blocks in range */
-} xfs_extdelta_t;
-
-/*
- * List of extents to be free "later".
- * The list is kept sorted on xbf_startblock.
- */
-typedef struct xfs_bmap_free_item
-{
- xfs_fsblock_t xbfi_startblock;/* starting fs block number */
- xfs_extlen_t xbfi_blockcount;/* number of blocks in extent */
- struct xfs_bmap_free_item *xbfi_next; /* link to next entry */
-} xfs_bmap_free_item_t;
-
-/*
- * Header for free extent list.
- */
-typedef struct xfs_bmap_free
-{
- xfs_bmap_free_item_t *xbf_first; /* list of to-be-free extents */
- int xbf_count; /* count of items on list */
- int xbf_low; /* kludge: alloc in low mode */
-} xfs_bmap_free_t;
-
-#define XFS_BMAP_MAX_NMAP 4
-
-/*
- * Flags for xfs_bmapi
- */
-#define XFS_BMAPI_WRITE 0x001 /* write operation: allocate space */
-#define XFS_BMAPI_DELAY 0x002 /* delayed write operation */
-#define XFS_BMAPI_ENTIRE 0x004 /* return entire extent, not trimmed */
-#define XFS_BMAPI_METADATA 0x008 /* mapping metadata not user data */
-#define XFS_BMAPI_EXACT 0x010 /* allocate only to spec'd bounds */
-#define XFS_BMAPI_ATTRFORK 0x020 /* use attribute fork not data */
-#define XFS_BMAPI_ASYNC 0x040 /* bunmapi xactions can be async */
-#define XFS_BMAPI_RSVBLOCKS 0x080 /* OK to alloc. reserved data blocks */
-#define XFS_BMAPI_PREALLOC 0x100 /* preallocation op: unwritten space */
-#define XFS_BMAPI_IGSTATE 0x200 /* Ignore state - */
- /* combine contig. space */
-#define XFS_BMAPI_CONTIG 0x400 /* must allocate only one extent */
-/* XFS_BMAPI_DIRECT_IO 0x800 */
-#define XFS_BMAPI_CONVERT 0x1000 /* unwritten extent conversion - */
- /* need write cache flushing and no */
- /* additional allocation alignments */
-
-#define XFS_BMAPI_AFLAG(w) xfs_bmapi_aflag(w)
-static inline int xfs_bmapi_aflag(int w)
-{
- return (w == XFS_ATTR_FORK ? XFS_BMAPI_ATTRFORK : 0);
-}
-
-/*
- * Special values for xfs_bmbt_irec_t br_startblock field.
- */
-#define DELAYSTARTBLOCK ((xfs_fsblock_t)-1LL)
-#define HOLESTARTBLOCK ((xfs_fsblock_t)-2LL)
-
-#define XFS_BMAP_INIT(flp,fbp) xfs_bmap_init(flp,fbp)
-static inline void xfs_bmap_init(xfs_bmap_free_t *flp, xfs_fsblock_t *fbp)
-{
- ((flp)->xbf_first = NULL, (flp)->xbf_count = 0, \
- (flp)->xbf_low = 0, *(fbp) = NULLFSBLOCK);
-}
-
-/*
- * Argument structure for xfs_bmap_alloc.
- */
-typedef struct xfs_bmalloca {
- xfs_fsblock_t firstblock; /* i/o first block allocated */
- xfs_fsblock_t rval; /* starting block of new extent */
- xfs_fileoff_t off; /* offset in file filling in */
- struct xfs_trans *tp; /* transaction pointer */
- struct xfs_inode *ip; /* incore inode pointer */
- struct xfs_bmbt_irec *prevp; /* extent before the new one */
- struct xfs_bmbt_irec *gotp; /* extent after, or delayed */
- xfs_extlen_t alen; /* i/o length asked/allocated */
- xfs_extlen_t total; /* total blocks needed for xaction */
- xfs_extlen_t minlen; /* mininum allocation size (blocks) */
- xfs_extlen_t minleft; /* amount must be left after alloc */
- char eof; /* set if allocating past last extent */
- char wasdel; /* replacing a delayed allocation */
- char userdata;/* set if is user data */
- char low; /* low on space, using seq'l ags */
- char aeof; /* allocated space at eof */
- char conv; /* overwriting unwritten extents */
-} xfs_bmalloca_t;
-
-#ifdef __KERNEL__
-
-#if defined(XFS_BMAP_TRACE)
-/*
- * Trace operations for bmap extent tracing
- */
-#define XFS_BMAP_KTRACE_DELETE 1
-#define XFS_BMAP_KTRACE_INSERT 2
-#define XFS_BMAP_KTRACE_PRE_UP 3
-#define XFS_BMAP_KTRACE_POST_UP 4
-
-#define XFS_BMAP_TRACE_SIZE 4096 /* size of global trace buffer */
-#define XFS_BMAP_KTRACE_SIZE 32 /* size of per-inode trace buffer */
-extern ktrace_t *xfs_bmap_trace_buf;
-
-/*
- * Add bmap trace insert entries for all the contents of the extent list.
- */
-void
-xfs_bmap_trace_exlist(
- char *fname, /* function name */
- struct xfs_inode *ip, /* incore inode pointer */
- xfs_extnum_t cnt, /* count of entries in list */
- int whichfork); /* data or attr fork */
-#else
-#define xfs_bmap_trace_exlist(f,ip,c,w)
-#endif
-
-/*
- * Convert inode from non-attributed to attributed.
- * Must not be in a transaction, ip must not be locked.
- */
-int /* error code */
-xfs_bmap_add_attrfork(
- struct xfs_inode *ip, /* incore inode pointer */
- int size, /* space needed for new attribute */
- int rsvd); /* flag for reserved block allocation */
-
-/*
- * Add the extent to the list of extents to be free at transaction end.
- * The list is maintained sorted (by block number).
- */
-void
-xfs_bmap_add_free(
- xfs_fsblock_t bno, /* fs block number of extent */
- xfs_filblks_t len, /* length of extent */
- xfs_bmap_free_t *flist, /* list of extents */
- struct xfs_mount *mp); /* mount point structure */
-
-/*
- * Routine to clean up the free list data structure when
- * an error occurs during a transaction.
- */
-void
-xfs_bmap_cancel(
- xfs_bmap_free_t *flist); /* free list to clean up */
-
-/*
- * Compute and fill in the value of the maximum depth of a bmap btree
- * in this filesystem. Done once, during mount.
- */
-void
-xfs_bmap_compute_maxlevels(
- struct xfs_mount *mp, /* file system mount structure */
- int whichfork); /* data or attr fork */
-
-/*
- * Routine to be called at transaction's end by xfs_bmapi, xfs_bunmapi
- * caller. Frees all the extents that need freeing, which must be done
- * last due to locking considerations.
- *
- * Return 1 if the given transaction was committed and a new one allocated,
- * and 0 otherwise.
- */
-int /* error */
-xfs_bmap_finish(
- struct xfs_trans **tp, /* transaction pointer addr */
- xfs_bmap_free_t *flist, /* i/o: list extents to free */
- xfs_fsblock_t firstblock, /* controlled a.g. for allocs */
- int *committed); /* xact committed or not */
-
-/*
- * Returns the file-relative block number of the first unused block in the file.
- * This is the lowest-address hole if the file has holes, else the first block
- * past the end of file.
- */
-int /* error */
-xfs_bmap_first_unused(
- struct xfs_trans *tp, /* transaction pointer */
- struct xfs_inode *ip, /* incore inode */
- xfs_extlen_t len, /* size of hole to find */
- xfs_fileoff_t *unused, /* unused block num */
- int whichfork); /* data or attr fork */
-
-/*
- * Returns the file-relative block number of the last block + 1 before
- * last_block (input value) in the file.
- * This is not based on i_size, it is based on the extent list.
- * Returns 0 for local files, as they do not have an extent list.
- */
-int /* error */
-xfs_bmap_last_before(
- struct xfs_trans *tp, /* transaction pointer */
- struct xfs_inode *ip, /* incore inode */
- xfs_fileoff_t *last_block, /* last block */
- int whichfork); /* data or attr fork */
-
-/*
- * Returns the file-relative block number of the first block past eof in
- * the file. This is not based on i_size, it is based on the extent list.
- * Returns 0 for local files, as they do not have an extent list.
- */
-int /* error */
-xfs_bmap_last_offset(
- struct xfs_trans *tp, /* transaction pointer */
- struct xfs_inode *ip, /* incore inode */
- xfs_fileoff_t *unused, /* last block num */
- int whichfork); /* data or attr fork */
-
-/*
- * Returns whether the selected fork of the inode has exactly one
- * block or not. For the data fork we check this matches di_size,
- * implying the file's range is 0..bsize-1.
- */
-int
-xfs_bmap_one_block(
- struct xfs_inode *ip, /* incore inode */
- int whichfork); /* data or attr fork */
-
-/*
- * Read in the extents to iu_extents.
- * All inode fields are set up by caller, we just traverse the btree
- * and copy the records in.
- */
-int /* error */
-xfs_bmap_read_extents(
- struct xfs_trans *tp, /* transaction pointer */
- struct xfs_inode *ip, /* incore inode */
- int whichfork); /* data or attr fork */
-
-/*
- * Map file blocks to filesystem blocks.
- * File range is given by the bno/len pair.
- * Adds blocks to file if a write ("flags & XFS_BMAPI_WRITE" set)
- * into a hole or past eof.
- * Only allocates blocks from a single allocation group,
- * to avoid locking problems.
- * The returned value in "firstblock" from the first call in a transaction
- * must be remembered and presented to subsequent calls in "firstblock".
- * An upper bound for the number of blocks to be allocated is supplied to
- * the first call in "total"; if no allocation group has that many free
- * blocks then the call will fail (return NULLFSBLOCK in "firstblock").
- */
-int /* error */
-xfs_bmapi(
- struct xfs_trans *tp, /* transaction pointer */
- struct xfs_inode *ip, /* incore inode */
- xfs_fileoff_t bno, /* starting file offs. mapped */
- xfs_filblks_t len, /* length to map in file */
- int flags, /* XFS_BMAPI_... */
- xfs_fsblock_t *firstblock, /* first allocated block
- controls a.g. for allocs */
- xfs_extlen_t total, /* total blocks needed */
- struct xfs_bmbt_irec *mval, /* output: map values */
- int *nmap, /* i/o: mval size/count */
- xfs_bmap_free_t *flist, /* i/o: list extents to free */
- xfs_extdelta_t *delta); /* o: change made to incore
- extents */
-
-/*
- * Map file blocks to filesystem blocks, simple version.
- * One block only, read-only.
- * For flags, only the XFS_BMAPI_ATTRFORK flag is examined.
- * For the other flag values, the effect is as if XFS_BMAPI_METADATA
- * was set and all the others were clear.
- */
-int /* error */
-xfs_bmapi_single(
- struct xfs_trans *tp, /* transaction pointer */
- struct xfs_inode *ip, /* incore inode */
- int whichfork, /* data or attr fork */
- xfs_fsblock_t *fsb, /* output: mapped block */
- xfs_fileoff_t bno); /* starting file offs. mapped */
-
-/*
- * Unmap (remove) blocks from a file.
- * If nexts is nonzero then the number of extents to remove is limited to
- * that value. If not all extents in the block range can be removed then
- * *done is set.
- */
-int /* error */
-xfs_bunmapi(
- struct xfs_trans *tp, /* transaction pointer */
- struct xfs_inode *ip, /* incore inode */
- xfs_fileoff_t bno, /* starting offset to unmap */
- xfs_filblks_t len, /* length to unmap in file */
- int flags, /* XFS_BMAPI_... */
- xfs_extnum_t nexts, /* number of extents max */
- xfs_fsblock_t *firstblock, /* first allocated block
- controls a.g. for allocs */
- xfs_bmap_free_t *flist, /* i/o: list extents to free */
- xfs_extdelta_t *delta, /* o: change made to incore
- extents */
- int *done); /* set if not done yet */
-
-/*
- * Fcntl interface to xfs_bmapi.
- */
-int /* error code */
-xfs_getbmap(
- bhv_desc_t *bdp, /* XFS behavior descriptor*/
- struct getbmap *bmv, /* user bmap structure */
- void __user *ap, /* pointer to user's array */
- int iflags); /* interface flags */
-
-/*
- * Check if the endoff is outside the last extent. If so the caller will grow
- * the allocation to a stripe unit boundary
- */
-int
-xfs_bmap_eof(
- struct xfs_inode *ip,
- xfs_fileoff_t endoff,
- int whichfork,
- int *eof);
-
-/*
- * Count fsblocks of the given fork.
- */
-int
-xfs_bmap_count_blocks(
- xfs_trans_t *tp,
- struct xfs_inode *ip,
- int whichfork,
- int *count);
-
-/*
- * Check an extent list, which has just been read, for
- * any bit in the extent flag field.
- */
-int
-xfs_check_nostate_extents(
- struct xfs_ifork *ifp,
- xfs_extnum_t idx,
- xfs_extnum_t num);
-
-/*
- * Search the extent records for the entry containing block bno.
- * If bno lies in a hole, point to the next entry. If bno lies
- * past eof, *eofp will be set, and *prevp will contain the last
- * entry (null if none). Else, *lastxp will be set to the index
- * of the found entry; *gotp will contain the entry.
- */
-xfs_bmbt_rec_t *
-xfs_bmap_search_multi_extents(struct xfs_ifork *, xfs_fileoff_t, int *,
- xfs_extnum_t *, xfs_bmbt_irec_t *, xfs_bmbt_irec_t *);
-
-#endif /* __KERNEL__ */
-
-#endif /* __XFS_BMAP_H__ */
diff --git a/sys/gnu/fs/xfs/xfs_bmap_btree.c b/sys/gnu/fs/xfs/xfs_bmap_btree.c
deleted file mode 100644
index 725123f..0000000
--- a/sys/gnu/fs/xfs/xfs_bmap_btree.c
+++ /dev/null
@@ -1,2782 +0,0 @@
-/*
- * Copyright (c) 2000-2003,2005 Silicon Graphics, Inc.
- * All Rights Reserved.
- *
- * 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.
- *
- * This program is distributed in the hope that it would 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 the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- */
-#include "xfs.h"
-#include "xfs_fs.h"
-#include "xfs_types.h"
-#include "xfs_bit.h"
-#include "xfs_log.h"
-#include "xfs_inum.h"
-#include "xfs_trans.h"
-#include "xfs_sb.h"
-#include "xfs_ag.h"
-#include "xfs_dir.h"
-#include "xfs_dir2.h"
-#include "xfs_dmapi.h"
-#include "xfs_mount.h"
-#include "xfs_bmap_btree.h"
-#include "xfs_alloc_btree.h"
-#include "xfs_ialloc_btree.h"
-#include "xfs_dir_sf.h"
-#include "xfs_dir2_sf.h"
-#include "xfs_attr_sf.h"
-#include "xfs_dinode.h"
-#include "xfs_inode.h"
-#include "xfs_inode_item.h"
-#include "xfs_alloc.h"
-#include "xfs_btree.h"
-#include "xfs_ialloc.h"
-#include "xfs_itable.h"
-#include "xfs_bmap.h"
-#include "xfs_error.h"
-#include "xfs_quota.h"
-
-#if defined(XFS_BMBT_TRACE)
-ktrace_t *xfs_bmbt_trace_buf;
-#endif
-
-/*
- * Prototypes for internal btree functions.
- */
-
-
-STATIC int xfs_bmbt_killroot(xfs_btree_cur_t *);
-STATIC void xfs_bmbt_log_keys(xfs_btree_cur_t *, xfs_buf_t *, int, int);
-STATIC void xfs_bmbt_log_ptrs(xfs_btree_cur_t *, xfs_buf_t *, int, int);
-STATIC int xfs_bmbt_lshift(xfs_btree_cur_t *, int, int *);
-STATIC int xfs_bmbt_rshift(xfs_btree_cur_t *, int, int *);
-STATIC int xfs_bmbt_split(xfs_btree_cur_t *, int, xfs_fsblock_t *,
- xfs_bmbt_key_t *, xfs_btree_cur_t **, int *);
-STATIC int xfs_bmbt_updkey(xfs_btree_cur_t *, xfs_bmbt_key_t *, int);
-
-
-#if defined(XFS_BMBT_TRACE)
-
-static char ARGS[] = "args";
-static char ENTRY[] = "entry";
-static char ERROR[] = "error";
-#undef EXIT
-static char EXIT[] = "exit";
-
-/*
- * Add a trace buffer entry for the arguments given to the routine,
- * generic form.
- */
-STATIC void
-xfs_bmbt_trace_enter(
- char *func,
- xfs_btree_cur_t *cur,
- char *s,
- int type,
- int line,
- __psunsigned_t a0,
- __psunsigned_t a1,
- __psunsigned_t a2,
- __psunsigned_t a3,
- __psunsigned_t a4,
- __psunsigned_t a5,
- __psunsigned_t a6,
- __psunsigned_t a7,
- __psunsigned_t a8,
- __psunsigned_t a9,
- __psunsigned_t a10)
-{
- xfs_inode_t *ip;
- int whichfork;
-
- ip = cur->bc_private.b.ip;
- whichfork = cur->bc_private.b.whichfork;
- ktrace_enter(xfs_bmbt_trace_buf,
- (void *)((__psint_t)type | (whichfork << 8) | (line << 16)),
- (void *)func, (void *)s, (void *)ip, (void *)cur,
- (void *)a0, (void *)a1, (void *)a2, (void *)a3,
- (void *)a4, (void *)a5, (void *)a6, (void *)a7,
- (void *)a8, (void *)a9, (void *)a10);
- ASSERT(ip->i_btrace);
- ktrace_enter(ip->i_btrace,
- (void *)((__psint_t)type | (whichfork << 8) | (line << 16)),
- (void *)func, (void *)s, (void *)ip, (void *)cur,
- (void *)a0, (void *)a1, (void *)a2, (void *)a3,
- (void *)a4, (void *)a5, (void *)a6, (void *)a7,
- (void *)a8, (void *)a9, (void *)a10);
-}
-/*
- * Add a trace buffer entry for arguments, for a buffer & 1 integer arg.
- */
-STATIC void
-xfs_bmbt_trace_argbi(
- char *func,
- xfs_btree_cur_t *cur,
- xfs_buf_t *b,
- int i,
- int line)
-{
- xfs_bmbt_trace_enter(func, cur, ARGS, XFS_BMBT_KTRACE_ARGBI, line,
- (__psunsigned_t)b, i, 0, 0,
- 0, 0, 0, 0,
- 0, 0, 0);
-}
-
-/*
- * Add a trace buffer entry for arguments, for a buffer & 2 integer args.
- */
-STATIC void
-xfs_bmbt_trace_argbii(
- char *func,
- xfs_btree_cur_t *cur,
- xfs_buf_t *b,
- int i0,
- int i1,
- int line)
-{
- xfs_bmbt_trace_enter(func, cur, ARGS, XFS_BMBT_KTRACE_ARGBII, line,
- (__psunsigned_t)b, i0, i1, 0,
- 0, 0, 0, 0,
- 0, 0, 0);
-}
-
-/*
- * Add a trace buffer entry for arguments, for 3 block-length args
- * and an integer arg.
- */
-STATIC void
-xfs_bmbt_trace_argfffi(
- char *func,
- xfs_btree_cur_t *cur,
- xfs_dfiloff_t o,
- xfs_dfsbno_t b,
- xfs_dfilblks_t i,
- int j,
- int line)
-{
- xfs_bmbt_trace_enter(func, cur, ARGS, XFS_BMBT_KTRACE_ARGFFFI, line,
- o >> 32, (int)o, b >> 32, (int)b,
- i >> 32, (int)i, (int)j, 0,
- 0, 0, 0);
-}
-
-/*
- * Add a trace buffer entry for arguments, for one integer arg.
- */
-STATIC void
-xfs_bmbt_trace_argi(
- char *func,
- xfs_btree_cur_t *cur,
- int i,
- int line)
-{
- xfs_bmbt_trace_enter(func, cur, ARGS, XFS_BMBT_KTRACE_ARGI, line,
- i, 0, 0, 0,
- 0, 0, 0, 0,
- 0, 0, 0);
-}
-
-/*
- * Add a trace buffer entry for arguments, for int, fsblock, key.
- */
-STATIC void
-xfs_bmbt_trace_argifk(
- char *func,
- xfs_btree_cur_t *cur,
- int i,
- xfs_fsblock_t f,
- xfs_bmbt_key_t *k,
- int line)
-{
- xfs_dfsbno_t d;
- xfs_dfiloff_t o;
-
- d = (xfs_dfsbno_t)f;
- o = INT_GET(k->br_startoff, ARCH_CONVERT);
- xfs_bmbt_trace_enter(func, cur, ARGS, XFS_BMBT_KTRACE_ARGIFK, line,
- i, d >> 32, (int)d, o >> 32,
- (int)o, 0, 0, 0,
- 0, 0, 0);
-}
-
-/*
- * Add a trace buffer entry for arguments, for int, fsblock, rec.
- */
-STATIC void
-xfs_bmbt_trace_argifr(
- char *func,
- xfs_btree_cur_t *cur,
- int i,
- xfs_fsblock_t f,
- xfs_bmbt_rec_t *r,
- int line)
-{
- xfs_dfsbno_t b;
- xfs_dfilblks_t c;
- xfs_dfsbno_t d;
- xfs_dfiloff_t o;
- xfs_bmbt_irec_t s;
-
- d = (xfs_dfsbno_t)f;
- xfs_bmbt_disk_get_all(r, &s);
- o = (xfs_dfiloff_t)s.br_startoff;
- b = (xfs_dfsbno_t)s.br_startblock;
- c = s.br_blockcount;
- xfs_bmbt_trace_enter(func, cur, ARGS, XFS_BMBT_KTRACE_ARGIFR, line,
- i, d >> 32, (int)d, o >> 32,
- (int)o, b >> 32, (int)b, c >> 32,
- (int)c, 0, 0);
-}
-
-/*
- * Add a trace buffer entry for arguments, for int, key.
- */
-STATIC void
-xfs_bmbt_trace_argik(
- char *func,
- xfs_btree_cur_t *cur,
- int i,
- xfs_bmbt_key_t *k,
- int line)
-{
- xfs_dfiloff_t o;
-
- o = INT_GET(k->br_startoff, ARCH_CONVERT);
- xfs_bmbt_trace_enter(func, cur, ARGS, XFS_BMBT_KTRACE_ARGIFK, line,
- i, o >> 32, (int)o, 0,
- 0, 0, 0, 0,
- 0, 0, 0);
-}
-
-/*
- * Add a trace buffer entry for the cursor/operation.
- */
-STATIC void
-xfs_bmbt_trace_cursor(
- char *func,
- xfs_btree_cur_t *cur,
- char *s,
- int line)
-{
- xfs_bmbt_rec_t r;
-
- xfs_bmbt_set_all(&r, &cur->bc_rec.b);
- xfs_bmbt_trace_enter(func, cur, s, XFS_BMBT_KTRACE_CUR, line,
- (cur->bc_nlevels << 24) | (cur->bc_private.b.flags << 16) |
- cur->bc_private.b.allocated,
- INT_GET(r.l0, ARCH_CONVERT) >> 32, (int)INT_GET(r.l0, ARCH_CONVERT), INT_GET(r.l1, ARCH_CONVERT) >> 32, (int)INT_GET(r.l1, ARCH_CONVERT),
- (unsigned long)cur->bc_bufs[0], (unsigned long)cur->bc_bufs[1],
- (unsigned long)cur->bc_bufs[2], (unsigned long)cur->bc_bufs[3],
- (cur->bc_ptrs[0] << 16) | cur->bc_ptrs[1],
- (cur->bc_ptrs[2] << 16) | cur->bc_ptrs[3]);
-}
-
-#define XFS_BMBT_TRACE_ARGBI(c,b,i) \
- xfs_bmbt_trace_argbi(fname, c, b, i, __LINE__)
-#define XFS_BMBT_TRACE_ARGBII(c,b,i,j) \
- xfs_bmbt_trace_argbii(fname, c, b, i, j, __LINE__)
-#define XFS_BMBT_TRACE_ARGFFFI(c,o,b,i,j) \
- xfs_bmbt_trace_argfffi(fname, c, o, b, i, j, __LINE__)
-#define XFS_BMBT_TRACE_ARGI(c,i) \
- xfs_bmbt_trace_argi(fname, c, i, __LINE__)
-#define XFS_BMBT_TRACE_ARGIFK(c,i,f,k) \
- xfs_bmbt_trace_argifk(fname, c, i, f, k, __LINE__)
-#define XFS_BMBT_TRACE_ARGIFR(c,i,f,r) \
- xfs_bmbt_trace_argifr(fname, c, i, f, r, __LINE__)
-#define XFS_BMBT_TRACE_ARGIK(c,i,k) \
- xfs_bmbt_trace_argik(fname, c, i, k, __LINE__)
-#define XFS_BMBT_TRACE_CURSOR(c,s) \
- xfs_bmbt_trace_cursor(fname, c, s, __LINE__)
-#else
-#define XFS_BMBT_TRACE_ARGBI(c,b,i)
-#define XFS_BMBT_TRACE_ARGBII(c,b,i,j)
-#define XFS_BMBT_TRACE_ARGFFFI(c,o,b,i,j)
-#define XFS_BMBT_TRACE_ARGI(c,i)
-#define XFS_BMBT_TRACE_ARGIFK(c,i,f,k)
-#define XFS_BMBT_TRACE_ARGIFR(c,i,f,r)
-#define XFS_BMBT_TRACE_ARGIK(c,i,k)
-#define XFS_BMBT_TRACE_CURSOR(c,s)
-#endif /* XFS_BMBT_TRACE */
-
-
-/*
- * Internal functions.
- */
-
-/*
- * Delete record pointed to by cur/level.
- */
-STATIC int /* error */
-xfs_bmbt_delrec(
- xfs_btree_cur_t *cur,
- int level,
- int *stat) /* success/failure */
-{
- xfs_bmbt_block_t *block; /* bmap btree block */
- xfs_fsblock_t bno; /* fs-relative block number */
- xfs_buf_t *bp; /* buffer for block */
- int error; /* error return value */
-#ifdef XFS_BMBT_TRACE
- static char fname[] = "xfs_bmbt_delrec";
-#endif
- int i; /* loop counter */
- int j; /* temp state */
- xfs_bmbt_key_t key; /* bmap btree key */
- xfs_bmbt_key_t *kp=NULL; /* pointer to bmap btree key */
- xfs_fsblock_t lbno; /* left sibling block number */
- xfs_buf_t *lbp; /* left buffer pointer */
- xfs_bmbt_block_t *left; /* left btree block */
- xfs_bmbt_key_t *lkp; /* left btree key */
- xfs_bmbt_ptr_t *lpp; /* left address pointer */
- int lrecs=0; /* left record count */
- xfs_bmbt_rec_t *lrp; /* left record pointer */
- xfs_mount_t *mp; /* file system mount point */
- xfs_bmbt_ptr_t *pp; /* pointer to bmap block addr */
- int ptr; /* key/record index */
- xfs_fsblock_t rbno; /* right sibling block number */
- xfs_buf_t *rbp; /* right buffer pointer */
- xfs_bmbt_block_t *right; /* right btree block */
- xfs_bmbt_key_t *rkp; /* right btree key */
- xfs_bmbt_rec_t *rp; /* pointer to bmap btree rec */
- xfs_bmbt_ptr_t *rpp; /* right address pointer */
- xfs_bmbt_block_t *rrblock; /* right-right btree block */
- xfs_buf_t *rrbp; /* right-right buffer pointer */
- int rrecs=0; /* right record count */
- xfs_bmbt_rec_t *rrp; /* right record pointer */
- xfs_btree_cur_t *tcur; /* temporary btree cursor */
- int numrecs; /* temporary numrec count */
- int numlrecs, numrrecs;
-
- XFS_BMBT_TRACE_CURSOR(cur, ENTRY);
- XFS_BMBT_TRACE_ARGI(cur, level);
- ptr = cur->bc_ptrs[level];
- tcur = (xfs_btree_cur_t *)0;
- if (ptr == 0) {
- XFS_BMBT_TRACE_CURSOR(cur, EXIT);
- *stat = 0;
- return 0;
- }
- block = xfs_bmbt_get_block(cur, level, &bp);
- numrecs = be16_to_cpu(block->bb_numrecs);
-#ifdef DEBUG
- if ((error = xfs_btree_check_lblock(cur, block, level, bp))) {
- XFS_BMBT_TRACE_CURSOR(cur, ERROR);
- goto error0;
- }
-#endif
- if (ptr > numrecs) {
- XFS_BMBT_TRACE_CURSOR(cur, EXIT);
- *stat = 0;
- return 0;
- }
- XFS_STATS_INC(xs_bmbt_delrec);
- if (level > 0) {
- kp = XFS_BMAP_KEY_IADDR(block, 1, cur);
- pp = XFS_BMAP_PTR_IADDR(block, 1, cur);
-#ifdef DEBUG
- for (i = ptr; i < numrecs; i++) {
- if ((error = xfs_btree_check_lptr(cur, INT_GET(pp[i], ARCH_CONVERT), level))) {
- XFS_BMBT_TRACE_CURSOR(cur, ERROR);
- goto error0;
- }
- }
-#endif
- if (ptr < numrecs) {
- memmove(&kp[ptr - 1], &kp[ptr],
- (numrecs - ptr) * sizeof(*kp));
- memmove(&pp[ptr - 1], &pp[ptr], /* INT_: direct copy */
- (numrecs - ptr) * sizeof(*pp));
- xfs_bmbt_log_ptrs(cur, bp, ptr, numrecs - 1);
- xfs_bmbt_log_keys(cur, bp, ptr, numrecs - 1);
- }
- } else {
- rp = XFS_BMAP_REC_IADDR(block, 1, cur);
- if (ptr < numrecs) {
- memmove(&rp[ptr - 1], &rp[ptr],
- (numrecs - ptr) * sizeof(*rp));
- xfs_bmbt_log_recs(cur, bp, ptr, numrecs - 1);
- }
- if (ptr == 1) {
- INT_SET(key.br_startoff, ARCH_CONVERT, xfs_bmbt_disk_get_startoff(rp));
- kp = &key;
- }
- }
- numrecs--;
- block->bb_numrecs = cpu_to_be16(numrecs);
- xfs_bmbt_log_block(cur, bp, XFS_BB_NUMRECS);
- /*
- * We're at the root level.
- * First, shrink the root block in-memory.
- * Try to get rid of the next level down.
- * If we can't then there's nothing left to do.
- */
- if (level == cur->bc_nlevels - 1) {
- xfs_iroot_realloc(cur->bc_private.b.ip, -1,
- cur->bc_private.b.whichfork);
- if ((error = xfs_bmbt_killroot(cur))) {
- XFS_BMBT_TRACE_CURSOR(cur, ERROR);
- goto error0;
- }
- if (level > 0 && (error = xfs_bmbt_decrement(cur, level, &j))) {
- XFS_BMBT_TRACE_CURSOR(cur, ERROR);
- goto error0;
- }
- XFS_BMBT_TRACE_CURSOR(cur, EXIT);
- *stat = 1;
- return 0;
- }
- if (ptr == 1 && (error = xfs_bmbt_updkey(cur, kp, level + 1))) {
- XFS_BMBT_TRACE_CURSOR(cur, ERROR);
- goto error0;
- }
- if (numrecs >= XFS_BMAP_BLOCK_IMINRECS(level, cur)) {
- if (level > 0 && (error = xfs_bmbt_decrement(cur, level, &j))) {
- XFS_BMBT_TRACE_CURSOR(cur, ERROR);
- goto error0;
- }
- XFS_BMBT_TRACE_CURSOR(cur, EXIT);
- *stat = 1;
- return 0;
- }
- rbno = be64_to_cpu(block->bb_rightsib);
- lbno = be64_to_cpu(block->bb_leftsib);
- /*
- * One child of root, need to get a chance to copy its contents
- * into the root and delete it. Can't go up to next level,
- * there's nothing to delete there.
- */
- if (lbno == NULLFSBLOCK && rbno == NULLFSBLOCK &&
- level == cur->bc_nlevels - 2) {
- if ((error = xfs_bmbt_killroot(cur))) {
- XFS_BMBT_TRACE_CURSOR(cur, ERROR);
- goto error0;
- }
- if (level > 0 && (error = xfs_bmbt_decrement(cur, level, &i))) {
- XFS_BMBT_TRACE_CURSOR(cur, ERROR);
- goto error0;
- }
- XFS_BMBT_TRACE_CURSOR(cur, EXIT);
- *stat = 1;
- return 0;
- }
- ASSERT(rbno != NULLFSBLOCK || lbno != NULLFSBLOCK);
- if ((error = xfs_btree_dup_cursor(cur, &tcur))) {
- XFS_BMBT_TRACE_CURSOR(cur, ERROR);
- goto error0;
- }
- bno = NULLFSBLOCK;
- if (rbno != NULLFSBLOCK) {
- i = xfs_btree_lastrec(tcur, level);
- XFS_WANT_CORRUPTED_GOTO(i == 1, error0);
- if ((error = xfs_bmbt_increment(tcur, level, &i))) {
- XFS_BMBT_TRACE_CURSOR(cur, ERROR);
- goto error0;
- }
- XFS_WANT_CORRUPTED_GOTO(i == 1, error0);
- i = xfs_btree_lastrec(tcur, level);
- XFS_WANT_CORRUPTED_GOTO(i == 1, error0);
- rbp = tcur->bc_bufs[level];
- right = XFS_BUF_TO_BMBT_BLOCK(rbp);
-#ifdef DEBUG
- if ((error = xfs_btree_check_lblock(cur, right, level, rbp))) {
- XFS_BMBT_TRACE_CURSOR(cur, ERROR);
- goto error0;
- }
-#endif
- bno = be64_to_cpu(right->bb_leftsib);
- if (be16_to_cpu(right->bb_numrecs) - 1 >=
- XFS_BMAP_BLOCK_IMINRECS(level, cur)) {
- if ((error = xfs_bmbt_lshift(tcur, level, &i))) {
- XFS_BMBT_TRACE_CURSOR(cur, ERROR);
- goto error0;
- }
- if (i) {
- ASSERT(be16_to_cpu(block->bb_numrecs) >=
- XFS_BMAP_BLOCK_IMINRECS(level, tcur));
- xfs_btree_del_cursor(tcur, XFS_BTREE_NOERROR);
- tcur = NULL;
- if (level > 0) {
- if ((error = xfs_bmbt_decrement(cur,
- level, &i))) {
- XFS_BMBT_TRACE_CURSOR(cur,
- ERROR);
- goto error0;
- }
- }
- XFS_BMBT_TRACE_CURSOR(cur, EXIT);
- *stat = 1;
- return 0;
- }
- }
- rrecs = be16_to_cpu(right->bb_numrecs);
- if (lbno != NULLFSBLOCK) {
- i = xfs_btree_firstrec(tcur, level);
- XFS_WANT_CORRUPTED_GOTO(i == 1, error0);
- if ((error = xfs_bmbt_decrement(tcur, level, &i))) {
- XFS_BMBT_TRACE_CURSOR(cur, ERROR);
- goto error0;
- }
- XFS_WANT_CORRUPTED_GOTO(i == 1, error0);
- }
- }
- if (lbno != NULLFSBLOCK) {
- i = xfs_btree_firstrec(tcur, level);
- XFS_WANT_CORRUPTED_GOTO(i == 1, error0);
- /*
- * decrement to last in block
- */
- if ((error = xfs_bmbt_decrement(tcur, level, &i))) {
- XFS_BMBT_TRACE_CURSOR(cur, ERROR);
- goto error0;
- }
- i = xfs_btree_firstrec(tcur, level);
- XFS_WANT_CORRUPTED_GOTO(i == 1, error0);
- lbp = tcur->bc_bufs[level];
- left = XFS_BUF_TO_BMBT_BLOCK(lbp);
-#ifdef DEBUG
- if ((error = xfs_btree_check_lblock(cur, left, level, lbp))) {
- XFS_BMBT_TRACE_CURSOR(cur, ERROR);
- goto error0;
- }
-#endif
- bno = be64_to_cpu(left->bb_rightsib);
- if (be16_to_cpu(left->bb_numrecs) - 1 >=
- XFS_BMAP_BLOCK_IMINRECS(level, cur)) {
- if ((error = xfs_bmbt_rshift(tcur, level, &i))) {
- XFS_BMBT_TRACE_CURSOR(cur, ERROR);
- goto error0;
- }
- if (i) {
- ASSERT(be16_to_cpu(block->bb_numrecs) >=
- XFS_BMAP_BLOCK_IMINRECS(level, tcur));
- xfs_btree_del_cursor(tcur, XFS_BTREE_NOERROR);
- tcur = NULL;
- if (level == 0)
- cur->bc_ptrs[0]++;
- XFS_BMBT_TRACE_CURSOR(cur, EXIT);
- *stat = 1;
- return 0;
- }
- }
- lrecs = be16_to_cpu(left->bb_numrecs);
- }
- xfs_btree_del_cursor(tcur, XFS_BTREE_NOERROR);
- tcur = NULL;
- mp = cur->bc_mp;
- ASSERT(bno != NULLFSBLOCK);
- if (lbno != NULLFSBLOCK &&
- lrecs + be16_to_cpu(block->bb_numrecs) <= XFS_BMAP_BLOCK_IMAXRECS(level, cur)) {
- rbno = bno;
- right = block;
- rbp = bp;
- if ((error = xfs_btree_read_bufl(mp, cur->bc_tp, lbno, 0, &lbp,
- XFS_BMAP_BTREE_REF))) {
- XFS_BMBT_TRACE_CURSOR(cur, ERROR);
- goto error0;
- }
- left = XFS_BUF_TO_BMBT_BLOCK(lbp);
- if ((error = xfs_btree_check_lblock(cur, left, level, lbp))) {
- XFS_BMBT_TRACE_CURSOR(cur, ERROR);
- goto error0;
- }
- } else if (rbno != NULLFSBLOCK &&
- rrecs + be16_to_cpu(block->bb_numrecs) <=
- XFS_BMAP_BLOCK_IMAXRECS(level, cur)) {
- lbno = bno;
- left = block;
- lbp = bp;
- if ((error = xfs_btree_read_bufl(mp, cur->bc_tp, rbno, 0, &rbp,
- XFS_BMAP_BTREE_REF))) {
- XFS_BMBT_TRACE_CURSOR(cur, ERROR);
- goto error0;
- }
- right = XFS_BUF_TO_BMBT_BLOCK(rbp);
- if ((error = xfs_btree_check_lblock(cur, right, level, rbp))) {
- XFS_BMBT_TRACE_CURSOR(cur, ERROR);
- goto error0;
- }
- lrecs = be16_to_cpu(left->bb_numrecs);
- } else {
- if (level > 0 && (error = xfs_bmbt_decrement(cur, level, &i))) {
- XFS_BMBT_TRACE_CURSOR(cur, ERROR);
- goto error0;
- }
- XFS_BMBT_TRACE_CURSOR(cur, EXIT);
- *stat = 1;
- return 0;
- }
- numlrecs = be16_to_cpu(left->bb_numrecs);
- numrrecs = be16_to_cpu(right->bb_numrecs);
- if (level > 0) {
- lkp = XFS_BMAP_KEY_IADDR(left, numlrecs + 1, cur);
- lpp = XFS_BMAP_PTR_IADDR(left, numlrecs + 1, cur);
- rkp = XFS_BMAP_KEY_IADDR(right, 1, cur);
- rpp = XFS_BMAP_PTR_IADDR(right, 1, cur);
-#ifdef DEBUG
- for (i = 0; i < numrrecs; i++) {
- if ((error = xfs_btree_check_lptr(cur, INT_GET(rpp[i], ARCH_CONVERT), level))) {
- XFS_BMBT_TRACE_CURSOR(cur, ERROR);
- goto error0;
- }
- }
-#endif
- memcpy(lkp, rkp, numrrecs * sizeof(*lkp));
- memcpy(lpp, rpp, numrrecs * sizeof(*lpp));
- xfs_bmbt_log_keys(cur, lbp, numlrecs + 1, numlrecs + numrrecs);
- xfs_bmbt_log_ptrs(cur, lbp, numlrecs + 1, numlrecs + numrrecs);
- } else {
- lrp = XFS_BMAP_REC_IADDR(left, numlrecs + 1, cur);
- rrp = XFS_BMAP_REC_IADDR(right, 1, cur);
- memcpy(lrp, rrp, numrrecs * sizeof(*lrp));
- xfs_bmbt_log_recs(cur, lbp, numlrecs + 1, numlrecs + numrrecs);
- }
- be16_add(&left->bb_numrecs, numrrecs);
- left->bb_rightsib = right->bb_rightsib;
- xfs_bmbt_log_block(cur, lbp, XFS_BB_RIGHTSIB | XFS_BB_NUMRECS);
- if (be64_to_cpu(left->bb_rightsib) != NULLDFSBNO) {
- if ((error = xfs_btree_read_bufl(mp, cur->bc_tp,
- be64_to_cpu(left->bb_rightsib),
- 0, &rrbp, XFS_BMAP_BTREE_REF))) {
- XFS_BMBT_TRACE_CURSOR(cur, ERROR);
- goto error0;
- }
- rrblock = XFS_BUF_TO_BMBT_BLOCK(rrbp);
- if ((error = xfs_btree_check_lblock(cur, rrblock, level, rrbp))) {
- XFS_BMBT_TRACE_CURSOR(cur, ERROR);
- goto error0;
- }
- rrblock->bb_leftsib = cpu_to_be64(lbno);
- xfs_bmbt_log_block(cur, rrbp, XFS_BB_LEFTSIB);
- }
- xfs_bmap_add_free(XFS_DADDR_TO_FSB(mp, XFS_BUF_ADDR(rbp)), 1,
- cur->bc_private.b.flist, mp);
- cur->bc_private.b.ip->i_d.di_nblocks--;
- xfs_trans_log_inode(cur->bc_tp, cur->bc_private.b.ip, XFS_ILOG_CORE);
- XFS_TRANS_MOD_DQUOT_BYINO(mp, cur->bc_tp, cur->bc_private.b.ip,
- XFS_TRANS_DQ_BCOUNT, -1L);
- xfs_trans_binval(cur->bc_tp, rbp);
- if (bp != lbp) {
- cur->bc_bufs[level] = lbp;
- cur->bc_ptrs[level] += lrecs;
- cur->bc_ra[level] = 0;
- } else if ((error = xfs_bmbt_increment(cur, level + 1, &i))) {
- XFS_BMBT_TRACE_CURSOR(cur, ERROR);
- goto error0;
- }
- if (level > 0)
- cur->bc_ptrs[level]--;
- XFS_BMBT_TRACE_CURSOR(cur, EXIT);
- *stat = 2;
- return 0;
-
-error0:
- if (tcur)
- xfs_btree_del_cursor(tcur, XFS_BTREE_ERROR);
- return error;
-}
-
-#ifdef DEBUG
-/*
- * Get the data from the pointed-to record.
- */
-int
-xfs_bmbt_get_rec(
- xfs_btree_cur_t *cur,
- xfs_fileoff_t *off,
- xfs_fsblock_t *bno,
- xfs_filblks_t *len,
- xfs_exntst_t *state,
- int *stat)
-{
- xfs_bmbt_block_t *block;
- xfs_buf_t *bp;
-#ifdef DEBUG
- int error;
-#endif
- int ptr;
- xfs_bmbt_rec_t *rp;
-
- block = xfs_bmbt_get_block(cur, 0, &bp);
- ptr = cur->bc_ptrs[0];
-#ifdef DEBUG
- if ((error = xfs_btree_check_lblock(cur, block, 0, bp)))
- return error;
-#endif
- if (ptr > be16_to_cpu(block->bb_numrecs) || ptr <= 0) {
- *stat = 0;
- return 0;
- }
- rp = XFS_BMAP_REC_IADDR(block, ptr, cur);
- *off = xfs_bmbt_disk_get_startoff(rp);
- *bno = xfs_bmbt_disk_get_startblock(rp);
- *len = xfs_bmbt_disk_get_blockcount(rp);
- *state = xfs_bmbt_disk_get_state(rp);
- *stat = 1;
- return 0;
-}
-#endif
-
-/*
- * Insert one record/level. Return information to the caller
- * allowing the next level up to proceed if necessary.
- */
-STATIC int /* error */
-xfs_bmbt_insrec(
- xfs_btree_cur_t *cur,
- int level,
- xfs_fsblock_t *bnop,
- xfs_bmbt_rec_t *recp,
- xfs_btree_cur_t **curp,
- int *stat) /* no-go/done/continue */
-{
- xfs_bmbt_block_t *block; /* bmap btree block */
- xfs_buf_t *bp; /* buffer for block */
- int error; /* error return value */
-#ifdef XFS_BMBT_TRACE
- static char fname[] = "xfs_bmbt_insrec";
-#endif
- int i; /* loop index */
- xfs_bmbt_key_t key; /* bmap btree key */
- xfs_bmbt_key_t *kp=NULL; /* pointer to bmap btree key */
- int logflags; /* inode logging flags */
- xfs_fsblock_t nbno; /* new block number */
- struct xfs_btree_cur *ncur; /* new btree cursor */
- xfs_bmbt_key_t nkey; /* new btree key value */
- xfs_bmbt_rec_t nrec; /* new record count */
- int optr; /* old key/record index */
- xfs_bmbt_ptr_t *pp; /* pointer to bmap block addr */
- int ptr; /* key/record index */
- xfs_bmbt_rec_t *rp=NULL; /* pointer to bmap btree rec */
- int numrecs;
-
- ASSERT(level < cur->bc_nlevels);
- XFS_BMBT_TRACE_CURSOR(cur, ENTRY);
- XFS_BMBT_TRACE_ARGIFR(cur, level, *bnop, recp);
- ncur = (xfs_btree_cur_t *)0;
- INT_SET(key.br_startoff, ARCH_CONVERT,
- xfs_bmbt_disk_get_startoff(recp));
- optr = ptr = cur->bc_ptrs[level];
- if (ptr == 0) {
- XFS_BMBT_TRACE_CURSOR(cur, EXIT);
- *stat = 0;
- return 0;
- }
- XFS_STATS_INC(xs_bmbt_insrec);
- block = xfs_bmbt_get_block(cur, level, &bp);
- numrecs = be16_to_cpu(block->bb_numrecs);
- nkey.br_startoff = 0;
-#ifdef DEBUG
- if ((error = xfs_btree_check_lblock(cur, block, level, bp))) {
- XFS_BMBT_TRACE_CURSOR(cur, ERROR);
- return error;
- }
- if (ptr <= numrecs) {
- if (level == 0) {
- rp = XFS_BMAP_REC_IADDR(block, ptr, cur);
- xfs_btree_check_rec(XFS_BTNUM_BMAP, recp, rp);
- } else {
- kp = XFS_BMAP_KEY_IADDR(block, ptr, cur);
- xfs_btree_check_key(XFS_BTNUM_BMAP, &key, kp);
- }
- }
-#endif
- nbno = NULLFSBLOCK;
- if (numrecs == XFS_BMAP_BLOCK_IMAXRECS(level, cur)) {
- if (numrecs < XFS_BMAP_BLOCK_DMAXRECS(level, cur)) {
- /*
- * A root block, that can be made bigger.
- */
- xfs_iroot_realloc(cur->bc_private.b.ip, 1,
- cur->bc_private.b.whichfork);
- block = xfs_bmbt_get_block(cur, level, &bp);
- } else if (level == cur->bc_nlevels - 1) {
- if ((error = xfs_bmbt_newroot(cur, &logflags, stat)) ||
- *stat == 0) {
- XFS_BMBT_TRACE_CURSOR(cur, ERROR);
- return error;
- }
- xfs_trans_log_inode(cur->bc_tp, cur->bc_private.b.ip,
- logflags);
- block = xfs_bmbt_get_block(cur, level, &bp);
- } else {
- if ((error = xfs_bmbt_rshift(cur, level, &i))) {
- XFS_BMBT_TRACE_CURSOR(cur, ERROR);
- return error;
- }
- if (i) {
- /* nothing */
- } else {
- if ((error = xfs_bmbt_lshift(cur, level, &i))) {
- XFS_BMBT_TRACE_CURSOR(cur, ERROR);
- return error;
- }
- if (i) {
- optr = ptr = cur->bc_ptrs[level];
- } else {
- if ((error = xfs_bmbt_split(cur, level,
- &nbno, &nkey, &ncur,
- &i))) {
- XFS_BMBT_TRACE_CURSOR(cur,
- ERROR);
- return error;
- }
- if (i) {
- block = xfs_bmbt_get_block(
- cur, level, &bp);
-#ifdef DEBUG
- if ((error =
- xfs_btree_check_lblock(cur,
- block, level, bp))) {
- XFS_BMBT_TRACE_CURSOR(
- cur, ERROR);
- return error;
- }
-#endif
- ptr = cur->bc_ptrs[level];
- xfs_bmbt_disk_set_allf(&nrec,
- nkey.br_startoff, 0, 0,
- XFS_EXT_NORM);
- } else {
- XFS_BMBT_TRACE_CURSOR(cur,
- EXIT);
- *stat = 0;
- return 0;
- }
- }
- }
- }
- }
- numrecs = be16_to_cpu(block->bb_numrecs);
- if (level > 0) {
- kp = XFS_BMAP_KEY_IADDR(block, 1, cur);
- pp = XFS_BMAP_PTR_IADDR(block, 1, cur);
-#ifdef DEBUG
- for (i = numrecs; i >= ptr; i--) {
- if ((error = xfs_btree_check_lptr(cur, INT_GET(pp[i - 1], ARCH_CONVERT),
- level))) {
- XFS_BMBT_TRACE_CURSOR(cur, ERROR);
- return error;
- }
- }
-#endif
- memmove(&kp[ptr], &kp[ptr - 1],
- (numrecs - ptr + 1) * sizeof(*kp));
- memmove(&pp[ptr], &pp[ptr - 1], /* INT_: direct copy */
- (numrecs - ptr + 1) * sizeof(*pp));
-#ifdef DEBUG
- if ((error = xfs_btree_check_lptr(cur, (xfs_bmbt_ptr_t)*bnop,
- level))) {
- XFS_BMBT_TRACE_CURSOR(cur, ERROR);
- return error;
- }
-#endif
- kp[ptr - 1] = key;
- INT_SET(pp[ptr - 1], ARCH_CONVERT, *bnop);
- numrecs++;
- block->bb_numrecs = cpu_to_be16(numrecs);
- xfs_bmbt_log_keys(cur, bp, ptr, numrecs);
- xfs_bmbt_log_ptrs(cur, bp, ptr, numrecs);
- } else {
- rp = XFS_BMAP_REC_IADDR(block, 1, cur);
- memmove(&rp[ptr], &rp[ptr - 1],
- (numrecs - ptr + 1) * sizeof(*rp));
- rp[ptr - 1] = *recp;
- numrecs++;
- block->bb_numrecs = cpu_to_be16(numrecs);
- xfs_bmbt_log_recs(cur, bp, ptr, numrecs);
- }
- xfs_bmbt_log_block(cur, bp, XFS_BB_NUMRECS);
-#ifdef DEBUG
- if (ptr < numrecs) {
- if (level == 0)
- xfs_btree_check_rec(XFS_BTNUM_BMAP, rp + ptr - 1,
- rp + ptr);
- else
- xfs_btree_check_key(XFS_BTNUM_BMAP, kp + ptr - 1,
- kp + ptr);
- }
-#endif
- if (optr == 1 && (error = xfs_bmbt_updkey(cur, &key, level + 1))) {
- XFS_BMBT_TRACE_CURSOR(cur, ERROR);
- return error;
- }
- *bnop = nbno;
- if (nbno != NULLFSBLOCK) {
- *recp = nrec;
- *curp = ncur;
- }
- XFS_BMBT_TRACE_CURSOR(cur, EXIT);
- *stat = 1;
- return 0;
-}
-
-STATIC int
-xfs_bmbt_killroot(
- xfs_btree_cur_t *cur)
-{
- xfs_bmbt_block_t *block;
- xfs_bmbt_block_t *cblock;
- xfs_buf_t *cbp;
- xfs_bmbt_key_t *ckp;
- xfs_bmbt_ptr_t *cpp;
-#ifdef DEBUG
- int error;
-#endif
-#ifdef XFS_BMBT_TRACE
- static char fname[] = "xfs_bmbt_killroot";
-#endif
- int i;
- xfs_bmbt_key_t *kp;
- xfs_inode_t *ip;
- xfs_ifork_t *ifp;
- int level;
- xfs_bmbt_ptr_t *pp;
-
- XFS_BMBT_TRACE_CURSOR(cur, ENTRY);
- level = cur->bc_nlevels - 1;
- ASSERT(level >= 1);
- /*
- * Don't deal with the root block needs to be a leaf case.
- * We're just going to turn the thing back into extents anyway.
- */
- if (level == 1) {
- XFS_BMBT_TRACE_CURSOR(cur, EXIT);
- return 0;
- }
- block = xfs_bmbt_get_block(cur, level, &cbp);
- /*
- * Give up if the root has multiple children.
- */
- if (be16_to_cpu(block->bb_numrecs) != 1) {
- XFS_BMBT_TRACE_CURSOR(cur, EXIT);
- return 0;
- }
- /*
- * Only do this if the next level will fit.
- * Then the data must be copied up to the inode,
- * instead of freeing the root you free the next level.
- */
- cbp = cur->bc_bufs[level - 1];
- cblock = XFS_BUF_TO_BMBT_BLOCK(cbp);
- if (be16_to_cpu(cblock->bb_numrecs) > XFS_BMAP_BLOCK_DMAXRECS(level, cur)) {
- XFS_BMBT_TRACE_CURSOR(cur, EXIT);
- return 0;
- }
- ASSERT(be64_to_cpu(cblock->bb_leftsib) == NULLDFSBNO);
- ASSERT(be64_to_cpu(cblock->bb_rightsib) == NULLDFSBNO);
- ip = cur->bc_private.b.ip;
- ifp = XFS_IFORK_PTR(ip, cur->bc_private.b.whichfork);
- ASSERT(XFS_BMAP_BLOCK_IMAXRECS(level, cur) ==
- XFS_BMAP_BROOT_MAXRECS(ifp->if_broot_bytes));
- i = (int)(be16_to_cpu(cblock->bb_numrecs) - XFS_BMAP_BLOCK_IMAXRECS(level, cur));
- if (i) {
- xfs_iroot_realloc(ip, i, cur->bc_private.b.whichfork);
- block = ifp->if_broot;
- }
- be16_add(&block->bb_numrecs, i);
- ASSERT(block->bb_numrecs == cblock->bb_numrecs);
- kp = XFS_BMAP_KEY_IADDR(block, 1, cur);
- ckp = XFS_BMAP_KEY_IADDR(cblock, 1, cur);
- memcpy(kp, ckp, be16_to_cpu(block->bb_numrecs) * sizeof(*kp));
- pp = XFS_BMAP_PTR_IADDR(block, 1, cur);
- cpp = XFS_BMAP_PTR_IADDR(cblock, 1, cur);
-#ifdef DEBUG
- for (i = 0; i < be16_to_cpu(cblock->bb_numrecs); i++) {
- if ((error = xfs_btree_check_lptr(cur, INT_GET(cpp[i], ARCH_CONVERT), level - 1))) {
- XFS_BMBT_TRACE_CURSOR(cur, ERROR);
- return error;
- }
- }
-#endif
- memcpy(pp, cpp, be16_to_cpu(block->bb_numrecs) * sizeof(*pp));
- xfs_bmap_add_free(XFS_DADDR_TO_FSB(cur->bc_mp, XFS_BUF_ADDR(cbp)), 1,
- cur->bc_private.b.flist, cur->bc_mp);
- ip->i_d.di_nblocks--;
- XFS_TRANS_MOD_DQUOT_BYINO(cur->bc_mp, cur->bc_tp, ip,
- XFS_TRANS_DQ_BCOUNT, -1L);
- xfs_trans_binval(cur->bc_tp, cbp);
- cur->bc_bufs[level - 1] = NULL;
- be16_add(&block->bb_level, -1);
- xfs_trans_log_inode(cur->bc_tp, ip,
- XFS_ILOG_CORE | XFS_ILOG_FBROOT(cur->bc_private.b.whichfork));
- cur->bc_nlevels--;
- XFS_BMBT_TRACE_CURSOR(cur, EXIT);
- return 0;
-}
-
-/*
- * Log key values from the btree block.
- */
-STATIC void
-xfs_bmbt_log_keys(
- xfs_btree_cur_t *cur,
- xfs_buf_t *bp,
- int kfirst,
- int klast)
-{
-#ifdef XFS_BMBT_TRACE
- static char fname[] = "xfs_bmbt_log_keys";
-#endif
- xfs_trans_t *tp;
-
- XFS_BMBT_TRACE_CURSOR(cur, ENTRY);
- XFS_BMBT_TRACE_ARGBII(cur, bp, kfirst, klast);
- tp = cur->bc_tp;
- if (bp) {
- xfs_bmbt_block_t *block;
- int first;
- xfs_bmbt_key_t *kp;
- int last;
-
- block = XFS_BUF_TO_BMBT_BLOCK(bp);
- kp = XFS_BMAP_KEY_DADDR(block, 1, cur);
- first = (int)((xfs_caddr_t)&kp[kfirst - 1] - (xfs_caddr_t)block);
- last = (int)(((xfs_caddr_t)&kp[klast] - 1) - (xfs_caddr_t)block);
- xfs_trans_log_buf(tp, bp, first, last);
- } else {
- xfs_inode_t *ip;
-
- ip = cur->bc_private.b.ip;
- xfs_trans_log_inode(tp, ip,
- XFS_ILOG_FBROOT(cur->bc_private.b.whichfork));
- }
- XFS_BMBT_TRACE_CURSOR(cur, EXIT);
-}
-
-/*
- * Log pointer values from the btree block.
- */
-STATIC void
-xfs_bmbt_log_ptrs(
- xfs_btree_cur_t *cur,
- xfs_buf_t *bp,
- int pfirst,
- int plast)
-{
-#ifdef XFS_BMBT_TRACE
- static char fname[] = "xfs_bmbt_log_ptrs";
-#endif
- xfs_trans_t *tp;
-
- XFS_BMBT_TRACE_CURSOR(cur, ENTRY);
- XFS_BMBT_TRACE_ARGBII(cur, bp, pfirst, plast);
- tp = cur->bc_tp;
- if (bp) {
- xfs_bmbt_block_t *block;
- int first;
- int last;
- xfs_bmbt_ptr_t *pp;
-
- block = XFS_BUF_TO_BMBT_BLOCK(bp);
- pp = XFS_BMAP_PTR_DADDR(block, 1, cur);
- first = (int)((xfs_caddr_t)&pp[pfirst - 1] - (xfs_caddr_t)block);
- last = (int)(((xfs_caddr_t)&pp[plast] - 1) - (xfs_caddr_t)block);
- xfs_trans_log_buf(tp, bp, first, last);
- } else {
- xfs_inode_t *ip;
-
- ip = cur->bc_private.b.ip;
- xfs_trans_log_inode(tp, ip,
- XFS_ILOG_FBROOT(cur->bc_private.b.whichfork));
- }
- XFS_BMBT_TRACE_CURSOR(cur, EXIT);
-}
-
-/*
- * Lookup the record. The cursor is made to point to it, based on dir.
- */
-STATIC int /* error */
-xfs_bmbt_lookup(
- xfs_btree_cur_t *cur,
- xfs_lookup_t dir,
- int *stat) /* success/failure */
-{
- xfs_bmbt_block_t *block=NULL;
- xfs_buf_t *bp;
- xfs_daddr_t d;
- xfs_sfiloff_t diff;
- int error; /* error return value */
-#ifdef XFS_BMBT_TRACE
- static char fname[] = "xfs_bmbt_lookup";
-#endif
- xfs_fsblock_t fsbno=0;
- int high;
- int i;
- int keyno=0;
- xfs_bmbt_key_t *kkbase=NULL;
- xfs_bmbt_key_t *kkp;
- xfs_bmbt_rec_t *krbase=NULL;
- xfs_bmbt_rec_t *krp;
- int level;
- int low;
- xfs_mount_t *mp;
- xfs_bmbt_ptr_t *pp;
- xfs_bmbt_irec_t *rp;
- xfs_fileoff_t startoff;
- xfs_trans_t *tp;
-
- XFS_STATS_INC(xs_bmbt_lookup);
- XFS_BMBT_TRACE_CURSOR(cur, ENTRY);
- XFS_BMBT_TRACE_ARGI(cur, (int)dir);
- tp = cur->bc_tp;
- mp = cur->bc_mp;
- rp = &cur->bc_rec.b;
- for (level = cur->bc_nlevels - 1, diff = 1; level >= 0; level--) {
- if (level < cur->bc_nlevels - 1) {
- d = XFS_FSB_TO_DADDR(mp, fsbno);
- bp = cur->bc_bufs[level];
- if (bp && XFS_BUF_ADDR(bp) != d)
- bp = (xfs_buf_t *)0;
- if (!bp) {
- if ((error = xfs_btree_read_bufl(mp, tp, fsbno,
- 0, &bp, XFS_BMAP_BTREE_REF))) {
- XFS_BMBT_TRACE_CURSOR(cur, ERROR);
- return error;
- }
- xfs_btree_setbuf(cur, level, bp);
- block = XFS_BUF_TO_BMBT_BLOCK(bp);
- if ((error = xfs_btree_check_lblock(cur, block,
- level, bp))) {
- XFS_BMBT_TRACE_CURSOR(cur, ERROR);
- return error;
- }
- } else
- block = XFS_BUF_TO_BMBT_BLOCK(bp);
- } else
- block = xfs_bmbt_get_block(cur, level, &bp);
- if (diff == 0)
- keyno = 1;
- else {
- if (level > 0)
- kkbase = XFS_BMAP_KEY_IADDR(block, 1, cur);
- else
- krbase = XFS_BMAP_REC_IADDR(block, 1, cur);
- low = 1;
- if (!(high = be16_to_cpu(block->bb_numrecs))) {
- ASSERT(level == 0);
- cur->bc_ptrs[0] = dir != XFS_LOOKUP_LE;
- XFS_BMBT_TRACE_CURSOR(cur, EXIT);
- *stat = 0;
- return 0;
- }
- while (low <= high) {
- XFS_STATS_INC(xs_bmbt_compare);
- keyno = (low + high) >> 1;
- if (level > 0) {
- kkp = kkbase + keyno - 1;
- startoff = INT_GET(kkp->br_startoff, ARCH_CONVERT);
- } else {
- krp = krbase + keyno - 1;
- startoff = xfs_bmbt_disk_get_startoff(krp);
- }
- diff = (xfs_sfiloff_t)
- (startoff - rp->br_startoff);
- if (diff < 0)
- low = keyno + 1;
- else if (diff > 0)
- high = keyno - 1;
- else
- break;
- }
- }
- if (level > 0) {
- if (diff > 0 && --keyno < 1)
- keyno = 1;
- pp = XFS_BMAP_PTR_IADDR(block, keyno, cur);
-#ifdef DEBUG
- if ((error = xfs_btree_check_lptr(cur, INT_GET(*pp, ARCH_CONVERT), level))) {
- XFS_BMBT_TRACE_CURSOR(cur, ERROR);
- return error;
- }
-#endif
- fsbno = INT_GET(*pp, ARCH_CONVERT);
- cur->bc_ptrs[level] = keyno;
- }
- }
- if (dir != XFS_LOOKUP_LE && diff < 0) {
- keyno++;
- /*
- * If ge search and we went off the end of the block, but it's
- * not the last block, we're in the wrong block.
- */
- if (dir == XFS_LOOKUP_GE && keyno > be16_to_cpu(block->bb_numrecs) &&
- be64_to_cpu(block->bb_rightsib) != NULLDFSBNO) {
- cur->bc_ptrs[0] = keyno;
- if ((error = xfs_bmbt_increment(cur, 0, &i))) {
- XFS_BMBT_TRACE_CURSOR(cur, ERROR);
- return error;
- }
- XFS_WANT_CORRUPTED_RETURN(i == 1);
- XFS_BMBT_TRACE_CURSOR(cur, EXIT);
- *stat = 1;
- return 0;
- }
- }
- else if (dir == XFS_LOOKUP_LE && diff > 0)
- keyno--;
- cur->bc_ptrs[0] = keyno;
- if (keyno == 0 || keyno > be16_to_cpu(block->bb_numrecs)) {
- XFS_BMBT_TRACE_CURSOR(cur, EXIT);
- *stat = 0;
- } else {
- XFS_BMBT_TRACE_CURSOR(cur, EXIT);
- *stat = ((dir != XFS_LOOKUP_EQ) || (diff == 0));
- }
- return 0;
-}
-
-/*
- * Move 1 record left from cur/level if possible.
- * Update cur to reflect the new path.
- */
-STATIC int /* error */
-xfs_bmbt_lshift(
- xfs_btree_cur_t *cur,
- int level,
- int *stat) /* success/failure */
-{
- int error; /* error return value */
-#ifdef XFS_BMBT_TRACE
- static char fname[] = "xfs_bmbt_lshift";
-#endif
-#ifdef DEBUG
- int i; /* loop counter */
-#endif
- xfs_bmbt_key_t key; /* bmap btree key */
- xfs_buf_t *lbp; /* left buffer pointer */
- xfs_bmbt_block_t *left; /* left btree block */
- xfs_bmbt_key_t *lkp=NULL; /* left btree key */
- xfs_bmbt_ptr_t *lpp; /* left address pointer */
- int lrecs; /* left record count */
- xfs_bmbt_rec_t *lrp=NULL; /* left record pointer */
- xfs_mount_t *mp; /* file system mount point */
- xfs_buf_t *rbp; /* right buffer pointer */
- xfs_bmbt_block_t *right; /* right btree block */
- xfs_bmbt_key_t *rkp=NULL; /* right btree key */
- xfs_bmbt_ptr_t *rpp=NULL; /* right address pointer */
- xfs_bmbt_rec_t *rrp=NULL; /* right record pointer */
- int rrecs; /* right record count */
-
- XFS_BMBT_TRACE_CURSOR(cur, ENTRY);
- XFS_BMBT_TRACE_ARGI(cur, level);
- if (level == cur->bc_nlevels - 1) {
- XFS_BMBT_TRACE_CURSOR(cur, EXIT);
- *stat = 0;
- return 0;
- }
- rbp = cur->bc_bufs[level];
- right = XFS_BUF_TO_BMBT_BLOCK(rbp);
-#ifdef DEBUG
- if ((error = xfs_btree_check_lblock(cur, right, level, rbp))) {
- XFS_BMBT_TRACE_CURSOR(cur, ERROR);
- return error;
- }
-#endif
- if (be64_to_cpu(right->bb_leftsib) == NULLDFSBNO) {
- XFS_BMBT_TRACE_CURSOR(cur, EXIT);
- *stat = 0;
- return 0;
- }
- if (cur->bc_ptrs[level] <= 1) {
- XFS_BMBT_TRACE_CURSOR(cur, EXIT);
- *stat = 0;
- return 0;
- }
- mp = cur->bc_mp;
- if ((error = xfs_btree_read_bufl(mp, cur->bc_tp, be64_to_cpu(right->bb_leftsib), 0,
- &lbp, XFS_BMAP_BTREE_REF))) {
- XFS_BMBT_TRACE_CURSOR(cur, ERROR);
- return error;
- }
- left = XFS_BUF_TO_BMBT_BLOCK(lbp);
- if ((error = xfs_btree_check_lblock(cur, left, level, lbp))) {
- XFS_BMBT_TRACE_CURSOR(cur, ERROR);
- return error;
- }
- if (be16_to_cpu(left->bb_numrecs) == XFS_BMAP_BLOCK_IMAXRECS(level, cur)) {
- XFS_BMBT_TRACE_CURSOR(cur, EXIT);
- *stat = 0;
- return 0;
- }
- lrecs = be16_to_cpu(left->bb_numrecs) + 1;
- if (level > 0) {
- lkp = XFS_BMAP_KEY_IADDR(left, lrecs, cur);
- rkp = XFS_BMAP_KEY_IADDR(right, 1, cur);
- *lkp = *rkp;
- xfs_bmbt_log_keys(cur, lbp, lrecs, lrecs);
- lpp = XFS_BMAP_PTR_IADDR(left, lrecs, cur);
- rpp = XFS_BMAP_PTR_IADDR(right, 1, cur);
-#ifdef DEBUG
- if ((error = xfs_btree_check_lptr(cur, INT_GET(*rpp, ARCH_CONVERT), level))) {
- XFS_BMBT_TRACE_CURSOR(cur, ERROR);
- return error;
- }
-#endif
- *lpp = *rpp; /* INT_: direct copy */
- xfs_bmbt_log_ptrs(cur, lbp, lrecs, lrecs);
- } else {
- lrp = XFS_BMAP_REC_IADDR(left, lrecs, cur);
- rrp = XFS_BMAP_REC_IADDR(right, 1, cur);
- *lrp = *rrp;
- xfs_bmbt_log_recs(cur, lbp, lrecs, lrecs);
- }
- left->bb_numrecs = cpu_to_be16(lrecs);
- xfs_bmbt_log_block(cur, lbp, XFS_BB_NUMRECS);
-#ifdef DEBUG
- if (level > 0)
- xfs_btree_check_key(XFS_BTNUM_BMAP, lkp - 1, lkp);
- else
- xfs_btree_check_rec(XFS_BTNUM_BMAP, lrp - 1, lrp);
-#endif
- rrecs = be16_to_cpu(right->bb_numrecs) - 1;
- right->bb_numrecs = cpu_to_be16(rrecs);
- xfs_bmbt_log_block(cur, rbp, XFS_BB_NUMRECS);
- if (level > 0) {
-#ifdef DEBUG
- for (i = 0; i < rrecs; i++) {
- if ((error = xfs_btree_check_lptr(cur, INT_GET(rpp[i + 1], ARCH_CONVERT),
- level))) {
- XFS_BMBT_TRACE_CURSOR(cur, ERROR);
- return error;
- }
- }
-#endif
- memmove(rkp, rkp + 1, rrecs * sizeof(*rkp));
- memmove(rpp, rpp + 1, rrecs * sizeof(*rpp));
- xfs_bmbt_log_keys(cur, rbp, 1, rrecs);
- xfs_bmbt_log_ptrs(cur, rbp, 1, rrecs);
- } else {
- memmove(rrp, rrp + 1, rrecs * sizeof(*rrp));
- xfs_bmbt_log_recs(cur, rbp, 1, rrecs);
- INT_SET(key.br_startoff, ARCH_CONVERT,
- xfs_bmbt_disk_get_startoff(rrp));
- rkp = &key;
- }
- if ((error = xfs_bmbt_updkey(cur, rkp, level + 1))) {
- XFS_BMBT_TRACE_CURSOR(cur, ERROR);
- return error;
- }
- cur->bc_ptrs[level]--;
- XFS_BMBT_TRACE_CURSOR(cur, EXIT);
- *stat = 1;
- return 0;
-}
-
-/*
- * Move 1 record right from cur/level if possible.
- * Update cur to reflect the new path.
- */
-STATIC int /* error */
-xfs_bmbt_rshift(
- xfs_btree_cur_t *cur,
- int level,
- int *stat) /* success/failure */
-{
- int error; /* error return value */
-#ifdef XFS_BMBT_TRACE
- static char fname[] = "xfs_bmbt_rshift";
-#endif
- int i; /* loop counter */
- xfs_bmbt_key_t key; /* bmap btree key */
- xfs_buf_t *lbp; /* left buffer pointer */
- xfs_bmbt_block_t *left; /* left btree block */
- xfs_bmbt_key_t *lkp; /* left btree key */
- xfs_bmbt_ptr_t *lpp; /* left address pointer */
- xfs_bmbt_rec_t *lrp; /* left record pointer */
- xfs_mount_t *mp; /* file system mount point */
- xfs_buf_t *rbp; /* right buffer pointer */
- xfs_bmbt_block_t *right; /* right btree block */
- xfs_bmbt_key_t *rkp; /* right btree key */
- xfs_bmbt_ptr_t *rpp; /* right address pointer */
- xfs_bmbt_rec_t *rrp=NULL; /* right record pointer */
- struct xfs_btree_cur *tcur; /* temporary btree cursor */
-
- XFS_BMBT_TRACE_CURSOR(cur, ENTRY);
- XFS_BMBT_TRACE_ARGI(cur, level);
- if (level == cur->bc_nlevels - 1) {
- XFS_BMBT_TRACE_CURSOR(cur, EXIT);
- *stat = 0;
- return 0;
- }
- lbp = cur->bc_bufs[level];
- left = XFS_BUF_TO_BMBT_BLOCK(lbp);
-#ifdef DEBUG
- if ((error = xfs_btree_check_lblock(cur, left, level, lbp))) {
- XFS_BMBT_TRACE_CURSOR(cur, ERROR);
- return error;
- }
-#endif
- if (be64_to_cpu(left->bb_rightsib) == NULLDFSBNO) {
- XFS_BMBT_TRACE_CURSOR(cur, EXIT);
- *stat = 0;
- return 0;
- }
- if (cur->bc_ptrs[level] >= be16_to_cpu(left->bb_numrecs)) {
- XFS_BMBT_TRACE_CURSOR(cur, EXIT);
- *stat = 0;
- return 0;
- }
- mp = cur->bc_mp;
- if ((error = xfs_btree_read_bufl(mp, cur->bc_tp, be64_to_cpu(left->bb_rightsib), 0,
- &rbp, XFS_BMAP_BTREE_REF))) {
- XFS_BMBT_TRACE_CURSOR(cur, ERROR);
- return error;
- }
- right = XFS_BUF_TO_BMBT_BLOCK(rbp);
- if ((error = xfs_btree_check_lblock(cur, right, level, rbp))) {
- XFS_BMBT_TRACE_CURSOR(cur, ERROR);
- return error;
- }
- if (be16_to_cpu(right->bb_numrecs) == XFS_BMAP_BLOCK_IMAXRECS(level, cur)) {
- XFS_BMBT_TRACE_CURSOR(cur, EXIT);
- *stat = 0;
- return 0;
- }
- if (level > 0) {
- lkp = XFS_BMAP_KEY_IADDR(left, be16_to_cpu(left->bb_numrecs), cur);
- lpp = XFS_BMAP_PTR_IADDR(left, be16_to_cpu(left->bb_numrecs), cur);
- rkp = XFS_BMAP_KEY_IADDR(right, 1, cur);
- rpp = XFS_BMAP_PTR_IADDR(right, 1, cur);
-#ifdef DEBUG
- for (i = be16_to_cpu(right->bb_numrecs) - 1; i >= 0; i--) {
- if ((error = xfs_btree_check_lptr(cur, INT_GET(rpp[i], ARCH_CONVERT), level))) {
- XFS_BMBT_TRACE_CURSOR(cur, ERROR);
- return error;
- }
- }
-#endif
- memmove(rkp + 1, rkp, be16_to_cpu(right->bb_numrecs) * sizeof(*rkp));
- memmove(rpp + 1, rpp, be16_to_cpu(right->bb_numrecs) * sizeof(*rpp));
-#ifdef DEBUG
- if ((error = xfs_btree_check_lptr(cur, INT_GET(*lpp, ARCH_CONVERT), level))) {
- XFS_BMBT_TRACE_CURSOR(cur, ERROR);
- return error;
- }
-#endif
- *rkp = *lkp;
- *rpp = *lpp; /* INT_: direct copy */
- xfs_bmbt_log_keys(cur, rbp, 1, be16_to_cpu(right->bb_numrecs) + 1);
- xfs_bmbt_log_ptrs(cur, rbp, 1, be16_to_cpu(right->bb_numrecs) + 1);
- } else {
- lrp = XFS_BMAP_REC_IADDR(left, be16_to_cpu(left->bb_numrecs), cur);
- rrp = XFS_BMAP_REC_IADDR(right, 1, cur);
- memmove(rrp + 1, rrp, be16_to_cpu(right->bb_numrecs) * sizeof(*rrp));
- *rrp = *lrp;
- xfs_bmbt_log_recs(cur, rbp, 1, be16_to_cpu(right->bb_numrecs) + 1);
- INT_SET(key.br_startoff, ARCH_CONVERT,
- xfs_bmbt_disk_get_startoff(rrp));
- rkp = &key;
- }
- be16_add(&left->bb_numrecs, -1);
- xfs_bmbt_log_block(cur, lbp, XFS_BB_NUMRECS);
- be16_add(&right->bb_numrecs, 1);
-#ifdef DEBUG
- if (level > 0)
- xfs_btree_check_key(XFS_BTNUM_BMAP, rkp, rkp + 1);
- else
- xfs_btree_check_rec(XFS_BTNUM_BMAP, rrp, rrp + 1);
-#endif
- xfs_bmbt_log_block(cur, rbp, XFS_BB_NUMRECS);
- if ((error = xfs_btree_dup_cursor(cur, &tcur))) {
- XFS_BMBT_TRACE_CURSOR(cur, ERROR);
- return error;
- }
- i = xfs_btree_lastrec(tcur, level);
- XFS_WANT_CORRUPTED_GOTO(i == 1, error0);
- if ((error = xfs_bmbt_increment(tcur, level, &i))) {
- XFS_BMBT_TRACE_CURSOR(tcur, ERROR);
- goto error1;
- }
- XFS_WANT_CORRUPTED_GOTO(i == 1, error0);
- if ((error = xfs_bmbt_updkey(tcur, rkp, level + 1))) {
- XFS_BMBT_TRACE_CURSOR(tcur, ERROR);
- goto error1;
- }
- xfs_btree_del_cursor(tcur, XFS_BTREE_NOERROR);
- XFS_BMBT_TRACE_CURSOR(cur, EXIT);
- *stat = 1;
- return 0;
-error0:
- XFS_BMBT_TRACE_CURSOR(cur, ERROR);
-error1:
- xfs_btree_del_cursor(tcur, XFS_BTREE_ERROR);
- return error;
-}
-
-/*
- * Determine the extent state.
- */
-/* ARGSUSED */
-STATIC xfs_exntst_t
-xfs_extent_state(
- xfs_filblks_t blks,
- int extent_flag)
-{
- if (extent_flag) {
- ASSERT(blks != 0); /* saved for DMIG */
- return XFS_EXT_UNWRITTEN;
- }
- return XFS_EXT_NORM;
-}
-
-
-/*
- * Split cur/level block in half.
- * Return new block number and its first record (to be inserted into parent).
- */
-STATIC int /* error */
-xfs_bmbt_split(
- xfs_btree_cur_t *cur,
- int level,
- xfs_fsblock_t *bnop,
- xfs_bmbt_key_t *keyp,
- xfs_btree_cur_t **curp,
- int *stat) /* success/failure */
-{
- xfs_alloc_arg_t args; /* block allocation args */
- int error; /* error return value */
-#ifdef XFS_BMBT_TRACE
- static char fname[] = "xfs_bmbt_split";
-#endif
- int i; /* loop counter */
- xfs_fsblock_t lbno; /* left sibling block number */
- xfs_buf_t *lbp; /* left buffer pointer */
- xfs_bmbt_block_t *left; /* left btree block */
- xfs_bmbt_key_t *lkp; /* left btree key */
- xfs_bmbt_ptr_t *lpp; /* left address pointer */
- xfs_bmbt_rec_t *lrp; /* left record pointer */
- xfs_buf_t *rbp; /* right buffer pointer */
- xfs_bmbt_block_t *right; /* right btree block */
- xfs_bmbt_key_t *rkp; /* right btree key */
- xfs_bmbt_ptr_t *rpp; /* right address pointer */
- xfs_bmbt_block_t *rrblock; /* right-right btree block */
- xfs_buf_t *rrbp; /* right-right buffer pointer */
- xfs_bmbt_rec_t *rrp; /* right record pointer */
-
- XFS_BMBT_TRACE_CURSOR(cur, ENTRY);
- XFS_BMBT_TRACE_ARGIFK(cur, level, *bnop, keyp);
- args.tp = cur->bc_tp;
- args.mp = cur->bc_mp;
- lbp = cur->bc_bufs[level];
- lbno = XFS_DADDR_TO_FSB(args.mp, XFS_BUF_ADDR(lbp));
- left = XFS_BUF_TO_BMBT_BLOCK(lbp);
- args.fsbno = cur->bc_private.b.firstblock;
- if (args.fsbno == NULLFSBLOCK) {
- args.fsbno = lbno;
- args.type = XFS_ALLOCTYPE_START_BNO;
- } else if (cur->bc_private.b.flist->xbf_low)
- args.type = XFS_ALLOCTYPE_FIRST_AG;
- else
- args.type = XFS_ALLOCTYPE_NEAR_BNO;
- args.mod = args.minleft = args.alignment = args.total = args.isfl =
- args.userdata = args.minalignslop = 0;
- args.minlen = args.maxlen = args.prod = 1;
- args.wasdel = cur->bc_private.b.flags & XFS_BTCUR_BPRV_WASDEL;
- if (!args.wasdel && xfs_trans_get_block_res(args.tp) == 0) {
- XFS_BMBT_TRACE_CURSOR(cur, ERROR);
- return XFS_ERROR(ENOSPC);
- }
- if ((error = xfs_alloc_vextent(&args))) {
- XFS_BMBT_TRACE_CURSOR(cur, ERROR);
- return error;
- }
- if (args.fsbno == NULLFSBLOCK) {
- XFS_BMBT_TRACE_CURSOR(cur, EXIT);
- *stat = 0;
- return 0;
- }
- ASSERT(args.len == 1);
- cur->bc_private.b.firstblock = args.fsbno;
- cur->bc_private.b.allocated++;
- cur->bc_private.b.ip->i_d.di_nblocks++;
- xfs_trans_log_inode(args.tp, cur->bc_private.b.ip, XFS_ILOG_CORE);
- XFS_TRANS_MOD_DQUOT_BYINO(args.mp, args.tp, cur->bc_private.b.ip,
- XFS_TRANS_DQ_BCOUNT, 1L);
- rbp = xfs_btree_get_bufl(args.mp, args.tp, args.fsbno, 0);
- right = XFS_BUF_TO_BMBT_BLOCK(rbp);
-#ifdef DEBUG
- if ((error = xfs_btree_check_lblock(cur, left, level, rbp))) {
- XFS_BMBT_TRACE_CURSOR(cur, ERROR);
- return error;
- }
-#endif
- right->bb_magic = cpu_to_be32(XFS_BMAP_MAGIC);
- right->bb_level = left->bb_level;
- right->bb_numrecs = cpu_to_be16(be16_to_cpu(left->bb_numrecs) / 2);
- if ((be16_to_cpu(left->bb_numrecs) & 1) &&
- cur->bc_ptrs[level] <= be16_to_cpu(right->bb_numrecs) + 1)
- be16_add(&right->bb_numrecs, 1);
- i = be16_to_cpu(left->bb_numrecs) - be16_to_cpu(right->bb_numrecs) + 1;
- if (level > 0) {
- lkp = XFS_BMAP_KEY_IADDR(left, i, cur);
- lpp = XFS_BMAP_PTR_IADDR(left, i, cur);
- rkp = XFS_BMAP_KEY_IADDR(right, 1, cur);
- rpp = XFS_BMAP_PTR_IADDR(right, 1, cur);
-#ifdef DEBUG
- for (i = 0; i < be16_to_cpu(right->bb_numrecs); i++) {
- if ((error = xfs_btree_check_lptr(cur, INT_GET(lpp[i], ARCH_CONVERT), level))) {
- XFS_BMBT_TRACE_CURSOR(cur, ERROR);
- return error;
- }
- }
-#endif
- memcpy(rkp, lkp, be16_to_cpu(right->bb_numrecs) * sizeof(*rkp));
- memcpy(rpp, lpp, be16_to_cpu(right->bb_numrecs) * sizeof(*rpp));
- xfs_bmbt_log_keys(cur, rbp, 1, be16_to_cpu(right->bb_numrecs));
- xfs_bmbt_log_ptrs(cur, rbp, 1, be16_to_cpu(right->bb_numrecs));
- keyp->br_startoff = INT_GET(rkp->br_startoff, ARCH_CONVERT);
- } else {
- lrp = XFS_BMAP_REC_IADDR(left, i, cur);
- rrp = XFS_BMAP_REC_IADDR(right, 1, cur);
- memcpy(rrp, lrp, be16_to_cpu(right->bb_numrecs) * sizeof(*rrp));
- xfs_bmbt_log_recs(cur, rbp, 1, be16_to_cpu(right->bb_numrecs));
- keyp->br_startoff = xfs_bmbt_disk_get_startoff(rrp);
- }
- be16_add(&left->bb_numrecs, -(be16_to_cpu(right->bb_numrecs)));
- right->bb_rightsib = left->bb_rightsib;
- left->bb_rightsib = cpu_to_be64(args.fsbno);
- right->bb_leftsib = cpu_to_be64(lbno);
- xfs_bmbt_log_block(cur, rbp, XFS_BB_ALL_BITS);
- xfs_bmbt_log_block(cur, lbp, XFS_BB_NUMRECS | XFS_BB_RIGHTSIB);
- if (be64_to_cpu(right->bb_rightsib) != NULLDFSBNO) {
- if ((error = xfs_btree_read_bufl(args.mp, args.tp,
- be64_to_cpu(right->bb_rightsib), 0, &rrbp,
- XFS_BMAP_BTREE_REF))) {
- XFS_BMBT_TRACE_CURSOR(cur, ERROR);
- return error;
- }
- rrblock = XFS_BUF_TO_BMBT_BLOCK(rrbp);
- if ((error = xfs_btree_check_lblock(cur, rrblock, level, rrbp))) {
- XFS_BMBT_TRACE_CURSOR(cur, ERROR);
- return error;
- }
- rrblock->bb_leftsib = cpu_to_be64(args.fsbno);
- xfs_bmbt_log_block(cur, rrbp, XFS_BB_LEFTSIB);
- }
- if (cur->bc_ptrs[level] > be16_to_cpu(left->bb_numrecs) + 1) {
- xfs_btree_setbuf(cur, level, rbp);
- cur->bc_ptrs[level] -= be16_to_cpu(left->bb_numrecs);
- }
- if (level + 1 < cur->bc_nlevels) {
- if ((error = xfs_btree_dup_cursor(cur, curp))) {
- XFS_BMBT_TRACE_CURSOR(cur, ERROR);
- return error;
- }
- (*curp)->bc_ptrs[level + 1]++;
- }
- *bnop = args.fsbno;
- XFS_BMBT_TRACE_CURSOR(cur, EXIT);
- *stat = 1;
- return 0;
-}
-
-
-/*
- * Update keys for the record.
- */
-STATIC int
-xfs_bmbt_updkey(
- xfs_btree_cur_t *cur,
- xfs_bmbt_key_t *keyp, /* on-disk format */
- int level)
-{
- xfs_bmbt_block_t *block;
- xfs_buf_t *bp;
-#ifdef DEBUG
- int error;
-#endif
-#ifdef XFS_BMBT_TRACE
- static char fname[] = "xfs_bmbt_updkey";
-#endif
- xfs_bmbt_key_t *kp;
- int ptr;
-
- ASSERT(level >= 1);
- XFS_BMBT_TRACE_CURSOR(cur, ENTRY);
- XFS_BMBT_TRACE_ARGIK(cur, level, keyp);
- for (ptr = 1; ptr == 1 && level < cur->bc_nlevels; level++) {
- block = xfs_bmbt_get_block(cur, level, &bp);
-#ifdef DEBUG
- if ((error = xfs_btree_check_lblock(cur, block, level, bp))) {
- XFS_BMBT_TRACE_CURSOR(cur, ERROR);
- return error;
- }
-#endif
- ptr = cur->bc_ptrs[level];
- kp = XFS_BMAP_KEY_IADDR(block, ptr, cur);
- *kp = *keyp;
- xfs_bmbt_log_keys(cur, bp, ptr, ptr);
- }
- XFS_BMBT_TRACE_CURSOR(cur, EXIT);
- return 0;
-}
-
-/*
- * Convert on-disk form of btree root to in-memory form.
- */
-void
-xfs_bmdr_to_bmbt(
- xfs_bmdr_block_t *dblock,
- int dblocklen,
- xfs_bmbt_block_t *rblock,
- int rblocklen)
-{
- int dmxr;
- xfs_bmbt_key_t *fkp;
- xfs_bmbt_ptr_t *fpp;
- xfs_bmbt_key_t *tkp;
- xfs_bmbt_ptr_t *tpp;
-
- rblock->bb_magic = cpu_to_be32(XFS_BMAP_MAGIC);
- rblock->bb_level = dblock->bb_level;
- ASSERT(be16_to_cpu(rblock->bb_level) > 0);
- rblock->bb_numrecs = dblock->bb_numrecs;
- rblock->bb_leftsib = cpu_to_be64(NULLDFSBNO);
- rblock->bb_rightsib = cpu_to_be64(NULLDFSBNO);
- dmxr = (int)XFS_BTREE_BLOCK_MAXRECS(dblocklen, xfs_bmdr, 0);
- fkp = XFS_BTREE_KEY_ADDR(dblocklen, xfs_bmdr, dblock, 1, dmxr);
- tkp = XFS_BMAP_BROOT_KEY_ADDR(rblock, 1, rblocklen);
- fpp = XFS_BTREE_PTR_ADDR(dblocklen, xfs_bmdr, dblock, 1, dmxr);
- tpp = XFS_BMAP_BROOT_PTR_ADDR(rblock, 1, rblocklen);
- dmxr = be16_to_cpu(dblock->bb_numrecs);
- memcpy(tkp, fkp, sizeof(*fkp) * dmxr);
- memcpy(tpp, fpp, sizeof(*fpp) * dmxr); /* INT_: direct copy */
-}
-
-/*
- * Decrement cursor by one record at the level.
- * For nonzero levels the leaf-ward information is untouched.
- */
-int /* error */
-xfs_bmbt_decrement(
- xfs_btree_cur_t *cur,
- int level,
- int *stat) /* success/failure */
-{
- xfs_bmbt_block_t *block;
- xfs_buf_t *bp;
- int error; /* error return value */
-#ifdef XFS_BMBT_TRACE
- static char fname[] = "xfs_bmbt_decrement";
-#endif
- xfs_fsblock_t fsbno;
- int lev;
- xfs_mount_t *mp;
- xfs_trans_t *tp;
-
- XFS_BMBT_TRACE_CURSOR(cur, ENTRY);
- XFS_BMBT_TRACE_ARGI(cur, level);
- ASSERT(level < cur->bc_nlevels);
- if (level < cur->bc_nlevels - 1)
- xfs_btree_readahead(cur, level, XFS_BTCUR_LEFTRA);
- if (--cur->bc_ptrs[level] > 0) {
- XFS_BMBT_TRACE_CURSOR(cur, EXIT);
- *stat = 1;
- return 0;
- }
- block = xfs_bmbt_get_block(cur, level, &bp);
-#ifdef DEBUG
- if ((error = xfs_btree_check_lblock(cur, block, level, bp))) {
- XFS_BMBT_TRACE_CURSOR(cur, ERROR);
- return error;
- }
-#endif
- if (be64_to_cpu(block->bb_leftsib) == NULLDFSBNO) {
- XFS_BMBT_TRACE_CURSOR(cur, EXIT);
- *stat = 0;
- return 0;
- }
- for (lev = level + 1; lev < cur->bc_nlevels; lev++) {
- if (--cur->bc_ptrs[lev] > 0)
- break;
- if (lev < cur->bc_nlevels - 1)
- xfs_btree_readahead(cur, lev, XFS_BTCUR_LEFTRA);
- }
- if (lev == cur->bc_nlevels) {
- XFS_BMBT_TRACE_CURSOR(cur, EXIT);
- *stat = 0;
- return 0;
- }
- tp = cur->bc_tp;
- mp = cur->bc_mp;
- for (block = xfs_bmbt_get_block(cur, lev, &bp); lev > level; ) {
- fsbno = INT_GET(*XFS_BMAP_PTR_IADDR(block, cur->bc_ptrs[lev], cur), ARCH_CONVERT);
- if ((error = xfs_btree_read_bufl(mp, tp, fsbno, 0, &bp,
- XFS_BMAP_BTREE_REF))) {
- XFS_BMBT_TRACE_CURSOR(cur, ERROR);
- return error;
- }
- lev--;
- xfs_btree_setbuf(cur, lev, bp);
- block = XFS_BUF_TO_BMBT_BLOCK(bp);
- if ((error = xfs_btree_check_lblock(cur, block, lev, bp))) {
- XFS_BMBT_TRACE_CURSOR(cur, ERROR);
- return error;
- }
- cur->bc_ptrs[lev] = be16_to_cpu(block->bb_numrecs);
- }
- XFS_BMBT_TRACE_CURSOR(cur, EXIT);
- *stat = 1;
- return 0;
-}
-
-/*
- * Delete the record pointed to by cur.
- */
-int /* error */
-xfs_bmbt_delete(
- xfs_btree_cur_t *cur,
- int *stat) /* success/failure */
-{
- int error; /* error return value */
-#ifdef XFS_BMBT_TRACE
- static char fname[] = "xfs_bmbt_delete";
-#endif
- int i;
- int level;
-
- XFS_BMBT_TRACE_CURSOR(cur, ENTRY);
- for (level = 0, i = 2; i == 2; level++) {
- if ((error = xfs_bmbt_delrec(cur, level, &i))) {
- XFS_BMBT_TRACE_CURSOR(cur, ERROR);
- return error;
- }
- }
- if (i == 0) {
- for (level = 1; level < cur->bc_nlevels; level++) {
- if (cur->bc_ptrs[level] == 0) {
- if ((error = xfs_bmbt_decrement(cur, level,
- &i))) {
- XFS_BMBT_TRACE_CURSOR(cur, ERROR);
- return error;
- }
- break;
- }
- }
- }
- XFS_BMBT_TRACE_CURSOR(cur, EXIT);
- *stat = i;
- return 0;
-}
-
-/*
- * Convert a compressed bmap extent record to an uncompressed form.
- * This code must be in sync with the routines xfs_bmbt_get_startoff,
- * xfs_bmbt_get_startblock, xfs_bmbt_get_blockcount and xfs_bmbt_get_state.
- */
-
-STATIC __inline__ void
-__xfs_bmbt_get_all(
- __uint64_t l0,
- __uint64_t l1,
- xfs_bmbt_irec_t *s)
-{
- int ext_flag;
- xfs_exntst_t st;
-
- ext_flag = (int)(l0 >> (64 - BMBT_EXNTFLAG_BITLEN));
- s->br_startoff = ((xfs_fileoff_t)l0 &
- XFS_MASK64LO(64 - BMBT_EXNTFLAG_BITLEN)) >> 9;
-#if XFS_BIG_BLKNOS
- s->br_startblock = (((xfs_fsblock_t)l0 & XFS_MASK64LO(9)) << 43) |
- (((xfs_fsblock_t)l1) >> 21);
-#else
-#ifdef DEBUG
- {
- xfs_dfsbno_t b;
-
- b = (((xfs_dfsbno_t)l0 & XFS_MASK64LO(9)) << 43) |
- (((xfs_dfsbno_t)l1) >> 21);
- ASSERT((b >> 32) == 0 || ISNULLDSTARTBLOCK(b));
- s->br_startblock = (xfs_fsblock_t)b;
- }
-#else /* !DEBUG */
- s->br_startblock = (xfs_fsblock_t)(((xfs_dfsbno_t)l1) >> 21);
-#endif /* DEBUG */
-#endif /* XFS_BIG_BLKNOS */
- s->br_blockcount = (xfs_filblks_t)(l1 & XFS_MASK64LO(21));
- /* This is xfs_extent_state() in-line */
- if (ext_flag) {
- ASSERT(s->br_blockcount != 0); /* saved for DMIG */
- st = XFS_EXT_UNWRITTEN;
- } else
- st = XFS_EXT_NORM;
- s->br_state = st;
-}
-
-void
-xfs_bmbt_get_all(
- xfs_bmbt_rec_t *r,
- xfs_bmbt_irec_t *s)
-{
- __xfs_bmbt_get_all(r->l0, r->l1, s);
-}
-
-/*
- * Get the block pointer for the given level of the cursor.
- * Fill in the buffer pointer, if applicable.
- */
-xfs_bmbt_block_t *
-xfs_bmbt_get_block(
- xfs_btree_cur_t *cur,
- int level,
- xfs_buf_t **bpp)
-{
- xfs_ifork_t *ifp;
- xfs_bmbt_block_t *rval;
-
- if (level < cur->bc_nlevels - 1) {
- *bpp = cur->bc_bufs[level];
- rval = XFS_BUF_TO_BMBT_BLOCK(*bpp);
- } else {
- *bpp = NULL;
- ifp = XFS_IFORK_PTR(cur->bc_private.b.ip,
- cur->bc_private.b.whichfork);
- rval = ifp->if_broot;
- }
- return rval;
-}
-
-/*
- * Extract the blockcount field from an in memory bmap extent record.
- */
-xfs_filblks_t
-xfs_bmbt_get_blockcount(
- xfs_bmbt_rec_t *r)
-{
- return (xfs_filblks_t)(r->l1 & XFS_MASK64LO(21));
-}
-
-/*
- * Extract the startblock field from an in memory bmap extent record.
- */
-xfs_fsblock_t
-xfs_bmbt_get_startblock(
- xfs_bmbt_rec_t *r)
-{
-#if XFS_BIG_BLKNOS
- return (((xfs_fsblock_t)r->l0 & XFS_MASK64LO(9)) << 43) |
- (((xfs_fsblock_t)r->l1) >> 21);
-#else
-#ifdef DEBUG
- xfs_dfsbno_t b;
-
- b = (((xfs_dfsbno_t)r->l0 & XFS_MASK64LO(9)) << 43) |
- (((xfs_dfsbno_t)r->l1) >> 21);
- ASSERT((b >> 32) == 0 || ISNULLDSTARTBLOCK(b));
- return (xfs_fsblock_t)b;
-#else /* !DEBUG */
- return (xfs_fsblock_t)(((xfs_dfsbno_t)r->l1) >> 21);
-#endif /* DEBUG */
-#endif /* XFS_BIG_BLKNOS */
-}
-
-/*
- * Extract the startoff field from an in memory bmap extent record.
- */
-xfs_fileoff_t
-xfs_bmbt_get_startoff(
- xfs_bmbt_rec_t *r)
-{
- return ((xfs_fileoff_t)r->l0 &
- XFS_MASK64LO(64 - BMBT_EXNTFLAG_BITLEN)) >> 9;
-}
-
-xfs_exntst_t
-xfs_bmbt_get_state(
- xfs_bmbt_rec_t *r)
-{
- int ext_flag;
-
- ext_flag = (int)((r->l0) >> (64 - BMBT_EXNTFLAG_BITLEN));
- return xfs_extent_state(xfs_bmbt_get_blockcount(r),
- ext_flag);
-}
-
-#ifndef XFS_NATIVE_HOST
-/* Endian flipping versions of the bmbt extraction functions */
-void
-xfs_bmbt_disk_get_all(
- xfs_bmbt_rec_t *r,
- xfs_bmbt_irec_t *s)
-{
- __uint64_t l0, l1;
-
- l0 = INT_GET(r->l0, ARCH_CONVERT);
- l1 = INT_GET(r->l1, ARCH_CONVERT);
-
- __xfs_bmbt_get_all(l0, l1, s);
-}
-
-/*
- * Extract the blockcount field from an on disk bmap extent record.
- */
-xfs_filblks_t
-xfs_bmbt_disk_get_blockcount(
- xfs_bmbt_rec_t *r)
-{
- return (xfs_filblks_t)(INT_GET(r->l1, ARCH_CONVERT) & XFS_MASK64LO(21));
-}
-
-/*
- * Extract the startblock field from an on disk bmap extent record.
- */
-xfs_fsblock_t
-xfs_bmbt_disk_get_startblock(
- xfs_bmbt_rec_t *r)
-{
-#if XFS_BIG_BLKNOS
- return (((xfs_fsblock_t)INT_GET(r->l0, ARCH_CONVERT) & XFS_MASK64LO(9)) << 43) |
- (((xfs_fsblock_t)INT_GET(r->l1, ARCH_CONVERT)) >> 21);
-#else
-#ifdef DEBUG
- xfs_dfsbno_t b;
-
- b = (((xfs_dfsbno_t)INT_GET(r->l0, ARCH_CONVERT) & XFS_MASK64LO(9)) << 43) |
- (((xfs_dfsbno_t)INT_GET(r->l1, ARCH_CONVERT)) >> 21);
- ASSERT((b >> 32) == 0 || ISNULLDSTARTBLOCK(b));
- return (xfs_fsblock_t)b;
-#else /* !DEBUG */
- return (xfs_fsblock_t)(((xfs_dfsbno_t)INT_GET(r->l1, ARCH_CONVERT)) >> 21);
-#endif /* DEBUG */
-#endif /* XFS_BIG_BLKNOS */
-}
-
-/*
- * Extract the startoff field from a disk format bmap extent record.
- */
-xfs_fileoff_t
-xfs_bmbt_disk_get_startoff(
- xfs_bmbt_rec_t *r)
-{
- return ((xfs_fileoff_t)INT_GET(r->l0, ARCH_CONVERT) &
- XFS_MASK64LO(64 - BMBT_EXNTFLAG_BITLEN)) >> 9;
-}
-
-xfs_exntst_t
-xfs_bmbt_disk_get_state(
- xfs_bmbt_rec_t *r)
-{
- int ext_flag;
-
- ext_flag = (int)((INT_GET(r->l0, ARCH_CONVERT)) >> (64 - BMBT_EXNTFLAG_BITLEN));
- return xfs_extent_state(xfs_bmbt_disk_get_blockcount(r),
- ext_flag);
-}
-#endif /* XFS_NATIVE_HOST */
-
-
-/*
- * Increment cursor by one record at the level.
- * For nonzero levels the leaf-ward information is untouched.
- */
-int /* error */
-xfs_bmbt_increment(
- xfs_btree_cur_t *cur,
- int level,
- int *stat) /* success/failure */
-{
- xfs_bmbt_block_t *block;
- xfs_buf_t *bp;
- int error; /* error return value */
-#ifdef XFS_BMBT_TRACE
- static char fname[] = "xfs_bmbt_increment";
-#endif
- xfs_fsblock_t fsbno;
- int lev;
- xfs_mount_t *mp;
- xfs_trans_t *tp;
-
- XFS_BMBT_TRACE_CURSOR(cur, ENTRY);
- XFS_BMBT_TRACE_ARGI(cur, level);
- ASSERT(level < cur->bc_nlevels);
- if (level < cur->bc_nlevels - 1)
- xfs_btree_readahead(cur, level, XFS_BTCUR_RIGHTRA);
- block = xfs_bmbt_get_block(cur, level, &bp);
-#ifdef DEBUG
- if ((error = xfs_btree_check_lblock(cur, block, level, bp))) {
- XFS_BMBT_TRACE_CURSOR(cur, ERROR);
- return error;
- }
-#endif
- if (++cur->bc_ptrs[level] <= be16_to_cpu(block->bb_numrecs)) {
- XFS_BMBT_TRACE_CURSOR(cur, EXIT);
- *stat = 1;
- return 0;
- }
- if (be64_to_cpu(block->bb_rightsib) == NULLDFSBNO) {
- XFS_BMBT_TRACE_CURSOR(cur, EXIT);
- *stat = 0;
- return 0;
- }
- for (lev = level + 1; lev < cur->bc_nlevels; lev++) {
- block = xfs_bmbt_get_block(cur, lev, &bp);
-#ifdef DEBUG
- if ((error = xfs_btree_check_lblock(cur, block, lev, bp))) {
- XFS_BMBT_TRACE_CURSOR(cur, ERROR);
- return error;
- }
-#endif
- if (++cur->bc_ptrs[lev] <= be16_to_cpu(block->bb_numrecs))
- break;
- if (lev < cur->bc_nlevels - 1)
- xfs_btree_readahead(cur, lev, XFS_BTCUR_RIGHTRA);
- }
- if (lev == cur->bc_nlevels) {
- XFS_BMBT_TRACE_CURSOR(cur, EXIT);
- *stat = 0;
- return 0;
- }
- tp = cur->bc_tp;
- mp = cur->bc_mp;
- for (block = xfs_bmbt_get_block(cur, lev, &bp); lev > level; ) {
- fsbno = INT_GET(*XFS_BMAP_PTR_IADDR(block, cur->bc_ptrs[lev], cur), ARCH_CONVERT);
- if ((error = xfs_btree_read_bufl(mp, tp, fsbno, 0, &bp,
- XFS_BMAP_BTREE_REF))) {
- XFS_BMBT_TRACE_CURSOR(cur, ERROR);
- return error;
- }
- lev--;
- xfs_btree_setbuf(cur, lev, bp);
- block = XFS_BUF_TO_BMBT_BLOCK(bp);
- if ((error = xfs_btree_check_lblock(cur, block, lev, bp))) {
- XFS_BMBT_TRACE_CURSOR(cur, ERROR);
- return error;
- }
- cur->bc_ptrs[lev] = 1;
- }
- XFS_BMBT_TRACE_CURSOR(cur, EXIT);
- *stat = 1;
- return 0;
-}
-
-/*
- * Insert the current record at the point referenced by cur.
- */
-int /* error */
-xfs_bmbt_insert(
- xfs_btree_cur_t *cur,
- int *stat) /* success/failure */
-{
- int error; /* error return value */
-#ifdef XFS_BMBT_TRACE
- static char fname[] = "xfs_bmbt_insert";
-#endif
- int i;
- int level;
- xfs_fsblock_t nbno;
- xfs_btree_cur_t *ncur;
- xfs_bmbt_rec_t nrec;
- xfs_btree_cur_t *pcur;
-
- XFS_BMBT_TRACE_CURSOR(cur, ENTRY);
- level = 0;
- nbno = NULLFSBLOCK;
- xfs_bmbt_disk_set_all(&nrec, &cur->bc_rec.b);
- ncur = (xfs_btree_cur_t *)0;
- pcur = cur;
- do {
- if ((error = xfs_bmbt_insrec(pcur, level++, &nbno, &nrec, &ncur,
- &i))) {
- if (pcur != cur)
- xfs_btree_del_cursor(pcur, XFS_BTREE_ERROR);
- XFS_BMBT_TRACE_CURSOR(cur, ERROR);
- return error;
- }
- XFS_WANT_CORRUPTED_GOTO(i == 1, error0);
- if (pcur != cur && (ncur || nbno == NULLFSBLOCK)) {
- cur->bc_nlevels = pcur->bc_nlevels;
- cur->bc_private.b.allocated +=
- pcur->bc_private.b.allocated;
- pcur->bc_private.b.allocated = 0;
- ASSERT((cur->bc_private.b.firstblock != NULLFSBLOCK) ||
- (cur->bc_private.b.ip->i_d.di_flags &
- XFS_DIFLAG_REALTIME));
- cur->bc_private.b.firstblock =
- pcur->bc_private.b.firstblock;
- ASSERT(cur->bc_private.b.flist ==
- pcur->bc_private.b.flist);
- xfs_btree_del_cursor(pcur, XFS_BTREE_NOERROR);
- }
- if (ncur) {
- pcur = ncur;
- ncur = (xfs_btree_cur_t *)0;
- }
- } while (nbno != NULLFSBLOCK);
- XFS_BMBT_TRACE_CURSOR(cur, EXIT);
- *stat = i;
- return 0;
-error0:
- XFS_BMBT_TRACE_CURSOR(cur, ERROR);
- return error;
-}
-
-/*
- * Log fields from the btree block header.
- */
-void
-xfs_bmbt_log_block(
- xfs_btree_cur_t *cur,
- xfs_buf_t *bp,
- int fields)
-{
- int first;
-#ifdef XFS_BMBT_TRACE
- static char fname[] = "xfs_bmbt_log_block";
-#endif
- int last;
- xfs_trans_t *tp;
- static const short offsets[] = {
- offsetof(xfs_bmbt_block_t, bb_magic),
- offsetof(xfs_bmbt_block_t, bb_level),
- offsetof(xfs_bmbt_block_t, bb_numrecs),
- offsetof(xfs_bmbt_block_t, bb_leftsib),
- offsetof(xfs_bmbt_block_t, bb_rightsib),
- sizeof(xfs_bmbt_block_t)
- };
-
- XFS_BMBT_TRACE_CURSOR(cur, ENTRY);
- XFS_BMBT_TRACE_ARGBI(cur, bp, fields);
- tp = cur->bc_tp;
- if (bp) {
- xfs_btree_offsets(fields, offsets, XFS_BB_NUM_BITS, &first,
- &last);
- xfs_trans_log_buf(tp, bp, first, last);
- } else
- xfs_trans_log_inode(tp, cur->bc_private.b.ip,
- XFS_ILOG_FBROOT(cur->bc_private.b.whichfork));
- XFS_BMBT_TRACE_CURSOR(cur, EXIT);
-}
-
-/*
- * Log record values from the btree block.
- */
-void
-xfs_bmbt_log_recs(
- xfs_btree_cur_t *cur,
- xfs_buf_t *bp,
- int rfirst,
- int rlast)
-{
- xfs_bmbt_block_t *block;
- int first;
-#ifdef XFS_BMBT_TRACE
- static char fname[] = "xfs_bmbt_log_recs";
-#endif
- int last;
- xfs_bmbt_rec_t *rp;
- xfs_trans_t *tp;
-
- XFS_BMBT_TRACE_CURSOR(cur, ENTRY);
- XFS_BMBT_TRACE_ARGBII(cur, bp, rfirst, rlast);
- ASSERT(bp);
- tp = cur->bc_tp;
- block = XFS_BUF_TO_BMBT_BLOCK(bp);
- rp = XFS_BMAP_REC_DADDR(block, 1, cur);
- first = (int)((xfs_caddr_t)&rp[rfirst - 1] - (xfs_caddr_t)block);
- last = (int)(((xfs_caddr_t)&rp[rlast] - 1) - (xfs_caddr_t)block);
- xfs_trans_log_buf(tp, bp, first, last);
- XFS_BMBT_TRACE_CURSOR(cur, EXIT);
-}
-
-int /* error */
-xfs_bmbt_lookup_eq(
- xfs_btree_cur_t *cur,
- xfs_fileoff_t off,
- xfs_fsblock_t bno,
- xfs_filblks_t len,
- int *stat) /* success/failure */
-{
- cur->bc_rec.b.br_startoff = off;
- cur->bc_rec.b.br_startblock = bno;
- cur->bc_rec.b.br_blockcount = len;
- return xfs_bmbt_lookup(cur, XFS_LOOKUP_EQ, stat);
-}
-
-int /* error */
-xfs_bmbt_lookup_ge(
- xfs_btree_cur_t *cur,
- xfs_fileoff_t off,
- xfs_fsblock_t bno,
- xfs_filblks_t len,
- int *stat) /* success/failure */
-{
- cur->bc_rec.b.br_startoff = off;
- cur->bc_rec.b.br_startblock = bno;
- cur->bc_rec.b.br_blockcount = len;
- return xfs_bmbt_lookup(cur, XFS_LOOKUP_GE, stat);
-}
-
-/*
- * Give the bmap btree a new root block. Copy the old broot contents
- * down into a real block and make the broot point to it.
- */
-int /* error */
-xfs_bmbt_newroot(
- xfs_btree_cur_t *cur, /* btree cursor */
- int *logflags, /* logging flags for inode */
- int *stat) /* return status - 0 fail */
-{
- xfs_alloc_arg_t args; /* allocation arguments */
- xfs_bmbt_block_t *block; /* bmap btree block */
- xfs_buf_t *bp; /* buffer for block */
- xfs_bmbt_block_t *cblock; /* child btree block */
- xfs_bmbt_key_t *ckp; /* child key pointer */
- xfs_bmbt_ptr_t *cpp; /* child ptr pointer */
- int error; /* error return code */
-#ifdef XFS_BMBT_TRACE
- static char fname[] = "xfs_bmbt_newroot";
-#endif
-#ifdef DEBUG
- int i; /* loop counter */
-#endif
- xfs_bmbt_key_t *kp; /* pointer to bmap btree key */
- int level; /* btree level */
- xfs_bmbt_ptr_t *pp; /* pointer to bmap block addr */
-
- XFS_BMBT_TRACE_CURSOR(cur, ENTRY);
- level = cur->bc_nlevels - 1;
- block = xfs_bmbt_get_block(cur, level, &bp);
- /*
- * Copy the root into a real block.
- */
- args.mp = cur->bc_mp;
- pp = XFS_BMAP_PTR_IADDR(block, 1, cur);
- args.tp = cur->bc_tp;
- args.fsbno = cur->bc_private.b.firstblock;
- args.mod = args.minleft = args.alignment = args.total = args.isfl =
- args.userdata = args.minalignslop = 0;
- args.minlen = args.maxlen = args.prod = 1;
- args.wasdel = cur->bc_private.b.flags & XFS_BTCUR_BPRV_WASDEL;
- if (args.fsbno == NULLFSBLOCK) {
-#ifdef DEBUG
- if ((error = xfs_btree_check_lptr(cur, INT_GET(*pp, ARCH_CONVERT), level))) {
- XFS_BMBT_TRACE_CURSOR(cur, ERROR);
- return error;
- }
-#endif
- args.fsbno = INT_GET(*pp, ARCH_CONVERT);
- args.type = XFS_ALLOCTYPE_START_BNO;
- } else if (args.wasdel)
- args.type = XFS_ALLOCTYPE_FIRST_AG;
- else
- args.type = XFS_ALLOCTYPE_NEAR_BNO;
- if ((error = xfs_alloc_vextent(&args))) {
- XFS_BMBT_TRACE_CURSOR(cur, ERROR);
- return error;
- }
- if (args.fsbno == NULLFSBLOCK) {
- XFS_BMBT_TRACE_CURSOR(cur, EXIT);
- *stat = 0;
- return 0;
- }
- ASSERT(args.len == 1);
- cur->bc_private.b.firstblock = args.fsbno;
- cur->bc_private.b.allocated++;
- cur->bc_private.b.ip->i_d.di_nblocks++;
- XFS_TRANS_MOD_DQUOT_BYINO(args.mp, args.tp, cur->bc_private.b.ip,
- XFS_TRANS_DQ_BCOUNT, 1L);
- bp = xfs_btree_get_bufl(args.mp, cur->bc_tp, args.fsbno, 0);
- cblock = XFS_BUF_TO_BMBT_BLOCK(bp);
- *cblock = *block;
- be16_add(&block->bb_level, 1);
- block->bb_numrecs = cpu_to_be16(1);
- cur->bc_nlevels++;
- cur->bc_ptrs[level + 1] = 1;
- kp = XFS_BMAP_KEY_IADDR(block, 1, cur);
- ckp = XFS_BMAP_KEY_IADDR(cblock, 1, cur);
- memcpy(ckp, kp, be16_to_cpu(cblock->bb_numrecs) * sizeof(*kp));
- cpp = XFS_BMAP_PTR_IADDR(cblock, 1, cur);
-#ifdef DEBUG
- for (i = 0; i < be16_to_cpu(cblock->bb_numrecs); i++) {
- if ((error = xfs_btree_check_lptr(cur, INT_GET(pp[i], ARCH_CONVERT), level))) {
- XFS_BMBT_TRACE_CURSOR(cur, ERROR);
- return error;
- }
- }
-#endif
- memcpy(cpp, pp, be16_to_cpu(cblock->bb_numrecs) * sizeof(*pp));
-#ifdef DEBUG
- if ((error = xfs_btree_check_lptr(cur, (xfs_bmbt_ptr_t)args.fsbno,
- level))) {
- XFS_BMBT_TRACE_CURSOR(cur, ERROR);
- return error;
- }
-#endif
- INT_SET(*pp, ARCH_CONVERT, args.fsbno);
- xfs_iroot_realloc(cur->bc_private.b.ip, 1 - be16_to_cpu(cblock->bb_numrecs),
- cur->bc_private.b.whichfork);
- xfs_btree_setbuf(cur, level, bp);
- /*
- * Do all this logging at the end so that
- * the root is at the right level.
- */
- xfs_bmbt_log_block(cur, bp, XFS_BB_ALL_BITS);
- xfs_bmbt_log_keys(cur, bp, 1, be16_to_cpu(cblock->bb_numrecs));
- xfs_bmbt_log_ptrs(cur, bp, 1, be16_to_cpu(cblock->bb_numrecs));
- XFS_BMBT_TRACE_CURSOR(cur, EXIT);
- *logflags |=
- XFS_ILOG_CORE | XFS_ILOG_FBROOT(cur->bc_private.b.whichfork);
- *stat = 1;
- return 0;
-}
-
-/*
- * Set all the fields in a bmap extent record from the uncompressed form.
- */
-void
-xfs_bmbt_set_all(
- xfs_bmbt_rec_t *r,
- xfs_bmbt_irec_t *s)
-{
- int extent_flag;
-
- ASSERT((s->br_state == XFS_EXT_NORM) ||
- (s->br_state == XFS_EXT_UNWRITTEN));
- extent_flag = (s->br_state == XFS_EXT_NORM) ? 0 : 1;
- ASSERT((s->br_startoff & XFS_MASK64HI(9)) == 0);
- ASSERT((s->br_blockcount & XFS_MASK64HI(43)) == 0);
-#if XFS_BIG_BLKNOS
- ASSERT((s->br_startblock & XFS_MASK64HI(12)) == 0);
- r->l0 = ((xfs_bmbt_rec_base_t)extent_flag << 63) |
- ((xfs_bmbt_rec_base_t)s->br_startoff << 9) |
- ((xfs_bmbt_rec_base_t)s->br_startblock >> 43);
- r->l1 = ((xfs_bmbt_rec_base_t)s->br_startblock << 21) |
- ((xfs_bmbt_rec_base_t)s->br_blockcount &
- (xfs_bmbt_rec_base_t)XFS_MASK64LO(21));
-#else /* !XFS_BIG_BLKNOS */
- if (ISNULLSTARTBLOCK(s->br_startblock)) {
- r->l0 = ((xfs_bmbt_rec_base_t)extent_flag << 63) |
- ((xfs_bmbt_rec_base_t)s->br_startoff << 9) |
- (xfs_bmbt_rec_base_t)XFS_MASK64LO(9);
- r->l1 = XFS_MASK64HI(11) |
- ((xfs_bmbt_rec_base_t)s->br_startblock << 21) |
- ((xfs_bmbt_rec_base_t)s->br_blockcount &
- (xfs_bmbt_rec_base_t)XFS_MASK64LO(21));
- } else {
- r->l0 = ((xfs_bmbt_rec_base_t)extent_flag << 63) |
- ((xfs_bmbt_rec_base_t)s->br_startoff << 9);
- r->l1 = ((xfs_bmbt_rec_base_t)s->br_startblock << 21) |
- ((xfs_bmbt_rec_base_t)s->br_blockcount &
- (xfs_bmbt_rec_base_t)XFS_MASK64LO(21));
- }
-#endif /* XFS_BIG_BLKNOS */
-}
-
-/*
- * Set all the fields in a bmap extent record from the arguments.
- */
-void
-xfs_bmbt_set_allf(
- xfs_bmbt_rec_t *r,
- xfs_fileoff_t o,
- xfs_fsblock_t b,
- xfs_filblks_t c,
- xfs_exntst_t v)
-{
- int extent_flag;
-
- ASSERT((v == XFS_EXT_NORM) || (v == XFS_EXT_UNWRITTEN));
- extent_flag = (v == XFS_EXT_NORM) ? 0 : 1;
- ASSERT((o & XFS_MASK64HI(64-BMBT_STARTOFF_BITLEN)) == 0);
- ASSERT((c & XFS_MASK64HI(64-BMBT_BLOCKCOUNT_BITLEN)) == 0);
-#if XFS_BIG_BLKNOS
- ASSERT((b & XFS_MASK64HI(64-BMBT_STARTBLOCK_BITLEN)) == 0);
- r->l0 = ((xfs_bmbt_rec_base_t)extent_flag << 63) |
- ((xfs_bmbt_rec_base_t)o << 9) |
- ((xfs_bmbt_rec_base_t)b >> 43);
- r->l1 = ((xfs_bmbt_rec_base_t)b << 21) |
- ((xfs_bmbt_rec_base_t)c &
- (xfs_bmbt_rec_base_t)XFS_MASK64LO(21));
-#else /* !XFS_BIG_BLKNOS */
- if (ISNULLSTARTBLOCK(b)) {
- r->l0 = ((xfs_bmbt_rec_base_t)extent_flag << 63) |
- ((xfs_bmbt_rec_base_t)o << 9) |
- (xfs_bmbt_rec_base_t)XFS_MASK64LO(9);
- r->l1 = XFS_MASK64HI(11) |
- ((xfs_bmbt_rec_base_t)b << 21) |
- ((xfs_bmbt_rec_base_t)c &
- (xfs_bmbt_rec_base_t)XFS_MASK64LO(21));
- } else {
- r->l0 = ((xfs_bmbt_rec_base_t)extent_flag << 63) |
- ((xfs_bmbt_rec_base_t)o << 9);
- r->l1 = ((xfs_bmbt_rec_base_t)b << 21) |
- ((xfs_bmbt_rec_base_t)c &
- (xfs_bmbt_rec_base_t)XFS_MASK64LO(21));
- }
-#endif /* XFS_BIG_BLKNOS */
-}
-
-#ifndef XFS_NATIVE_HOST
-/*
- * Set all the fields in a bmap extent record from the uncompressed form.
- */
-void
-xfs_bmbt_disk_set_all(
- xfs_bmbt_rec_t *r,
- xfs_bmbt_irec_t *s)
-{
- int extent_flag;
-
- ASSERT((s->br_state == XFS_EXT_NORM) ||
- (s->br_state == XFS_EXT_UNWRITTEN));
- extent_flag = (s->br_state == XFS_EXT_NORM) ? 0 : 1;
- ASSERT((s->br_startoff & XFS_MASK64HI(9)) == 0);
- ASSERT((s->br_blockcount & XFS_MASK64HI(43)) == 0);
-#if XFS_BIG_BLKNOS
- ASSERT((s->br_startblock & XFS_MASK64HI(12)) == 0);
- INT_SET(r->l0, ARCH_CONVERT, ((xfs_bmbt_rec_base_t)extent_flag << 63) |
- ((xfs_bmbt_rec_base_t)s->br_startoff << 9) |
- ((xfs_bmbt_rec_base_t)s->br_startblock >> 43));
- INT_SET(r->l1, ARCH_CONVERT, ((xfs_bmbt_rec_base_t)s->br_startblock << 21) |
- ((xfs_bmbt_rec_base_t)s->br_blockcount &
- (xfs_bmbt_rec_base_t)XFS_MASK64LO(21)));
-#else /* !XFS_BIG_BLKNOS */
- if (ISNULLSTARTBLOCK(s->br_startblock)) {
- INT_SET(r->l0, ARCH_CONVERT, ((xfs_bmbt_rec_base_t)extent_flag << 63) |
- ((xfs_bmbt_rec_base_t)s->br_startoff << 9) |
- (xfs_bmbt_rec_base_t)XFS_MASK64LO(9));
- INT_SET(r->l1, ARCH_CONVERT, XFS_MASK64HI(11) |
- ((xfs_bmbt_rec_base_t)s->br_startblock << 21) |
- ((xfs_bmbt_rec_base_t)s->br_blockcount &
- (xfs_bmbt_rec_base_t)XFS_MASK64LO(21)));
- } else {
- INT_SET(r->l0, ARCH_CONVERT, ((xfs_bmbt_rec_base_t)extent_flag << 63) |
- ((xfs_bmbt_rec_base_t)s->br_startoff << 9));
- INT_SET(r->l1, ARCH_CONVERT, ((xfs_bmbt_rec_base_t)s->br_startblock << 21) |
- ((xfs_bmbt_rec_base_t)s->br_blockcount &
- (xfs_bmbt_rec_base_t)XFS_MASK64LO(21)));
- }
-#endif /* XFS_BIG_BLKNOS */
-}
-
-/*
- * Set all the fields in a disk format bmap extent record from the arguments.
- */
-void
-xfs_bmbt_disk_set_allf(
- xfs_bmbt_rec_t *r,
- xfs_fileoff_t o,
- xfs_fsblock_t b,
- xfs_filblks_t c,
- xfs_exntst_t v)
-{
- int extent_flag;
-
- ASSERT((v == XFS_EXT_NORM) || (v == XFS_EXT_UNWRITTEN));
- extent_flag = (v == XFS_EXT_NORM) ? 0 : 1;
- ASSERT((o & XFS_MASK64HI(64-BMBT_STARTOFF_BITLEN)) == 0);
- ASSERT((c & XFS_MASK64HI(64-BMBT_BLOCKCOUNT_BITLEN)) == 0);
-#if XFS_BIG_BLKNOS
- ASSERT((b & XFS_MASK64HI(64-BMBT_STARTBLOCK_BITLEN)) == 0);
- INT_SET(r->l0, ARCH_CONVERT, ((xfs_bmbt_rec_base_t)extent_flag << 63) |
- ((xfs_bmbt_rec_base_t)o << 9) |
- ((xfs_bmbt_rec_base_t)b >> 43));
- INT_SET(r->l1, ARCH_CONVERT, ((xfs_bmbt_rec_base_t)b << 21) |
- ((xfs_bmbt_rec_base_t)c &
- (xfs_bmbt_rec_base_t)XFS_MASK64LO(21)));
-#else /* !XFS_BIG_BLKNOS */
- if (ISNULLSTARTBLOCK(b)) {
- INT_SET(r->l0, ARCH_CONVERT, ((xfs_bmbt_rec_base_t)extent_flag << 63) |
- ((xfs_bmbt_rec_base_t)o << 9) |
- (xfs_bmbt_rec_base_t)XFS_MASK64LO(9));
- INT_SET(r->l1, ARCH_CONVERT, XFS_MASK64HI(11) |
- ((xfs_bmbt_rec_base_t)b << 21) |
- ((xfs_bmbt_rec_base_t)c &
- (xfs_bmbt_rec_base_t)XFS_MASK64LO(21)));
- } else {
- INT_SET(r->l0, ARCH_CONVERT, ((xfs_bmbt_rec_base_t)extent_flag << 63) |
- ((xfs_bmbt_rec_base_t)o << 9));
- INT_SET(r->l1, ARCH_CONVERT, ((xfs_bmbt_rec_base_t)b << 21) |
- ((xfs_bmbt_rec_base_t)c &
- (xfs_bmbt_rec_base_t)XFS_MASK64LO(21)));
- }
-#endif /* XFS_BIG_BLKNOS */
-}
-#endif /* XFS_NATIVE_HOST */
-
-/*
- * Set the blockcount field in a bmap extent record.
- */
-void
-xfs_bmbt_set_blockcount(
- xfs_bmbt_rec_t *r,
- xfs_filblks_t v)
-{
- ASSERT((v & XFS_MASK64HI(43)) == 0);
- r->l1 = (r->l1 & (xfs_bmbt_rec_base_t)XFS_MASK64HI(43)) |
- (xfs_bmbt_rec_base_t)(v & XFS_MASK64LO(21));
-}
-
-/*
- * Set the startblock field in a bmap extent record.
- */
-void
-xfs_bmbt_set_startblock(
- xfs_bmbt_rec_t *r,
- xfs_fsblock_t v)
-{
-#if XFS_BIG_BLKNOS
- ASSERT((v & XFS_MASK64HI(12)) == 0);
- r->l0 = (r->l0 & (xfs_bmbt_rec_base_t)XFS_MASK64HI(55)) |
- (xfs_bmbt_rec_base_t)(v >> 43);
- r->l1 = (r->l1 & (xfs_bmbt_rec_base_t)XFS_MASK64LO(21)) |
- (xfs_bmbt_rec_base_t)(v << 21);
-#else /* !XFS_BIG_BLKNOS */
- if (ISNULLSTARTBLOCK(v)) {
- r->l0 |= (xfs_bmbt_rec_base_t)XFS_MASK64LO(9);
- r->l1 = (xfs_bmbt_rec_base_t)XFS_MASK64HI(11) |
- ((xfs_bmbt_rec_base_t)v << 21) |
- (r->l1 & (xfs_bmbt_rec_base_t)XFS_MASK64LO(21));
- } else {
- r->l0 &= ~(xfs_bmbt_rec_base_t)XFS_MASK64LO(9);
- r->l1 = ((xfs_bmbt_rec_base_t)v << 21) |
- (r->l1 & (xfs_bmbt_rec_base_t)XFS_MASK64LO(21));
- }
-#endif /* XFS_BIG_BLKNOS */
-}
-
-/*
- * Set the startoff field in a bmap extent record.
- */
-void
-xfs_bmbt_set_startoff(
- xfs_bmbt_rec_t *r,
- xfs_fileoff_t v)
-{
- ASSERT((v & XFS_MASK64HI(9)) == 0);
- r->l0 = (r->l0 & (xfs_bmbt_rec_base_t) XFS_MASK64HI(1)) |
- ((xfs_bmbt_rec_base_t)v << 9) |
- (r->l0 & (xfs_bmbt_rec_base_t)XFS_MASK64LO(9));
-}
-
-/*
- * Set the extent state field in a bmap extent record.
- */
-void
-xfs_bmbt_set_state(
- xfs_bmbt_rec_t *r,
- xfs_exntst_t v)
-{
- ASSERT(v == XFS_EXT_NORM || v == XFS_EXT_UNWRITTEN);
- if (v == XFS_EXT_NORM)
- r->l0 &= XFS_MASK64LO(64 - BMBT_EXNTFLAG_BITLEN);
- else
- r->l0 |= XFS_MASK64HI(BMBT_EXNTFLAG_BITLEN);
-}
-
-/*
- * Convert in-memory form of btree root to on-disk form.
- */
-void
-xfs_bmbt_to_bmdr(
- xfs_bmbt_block_t *rblock,
- int rblocklen,
- xfs_bmdr_block_t *dblock,
- int dblocklen)
-{
- int dmxr;
- xfs_bmbt_key_t *fkp;
- xfs_bmbt_ptr_t *fpp;
- xfs_bmbt_key_t *tkp;
- xfs_bmbt_ptr_t *tpp;
-
- ASSERT(be32_to_cpu(rblock->bb_magic) == XFS_BMAP_MAGIC);
- ASSERT(be64_to_cpu(rblock->bb_leftsib) == NULLDFSBNO);
- ASSERT(be64_to_cpu(rblock->bb_rightsib) == NULLDFSBNO);
- ASSERT(be16_to_cpu(rblock->bb_level) > 0);
- dblock->bb_level = rblock->bb_level;
- dblock->bb_numrecs = rblock->bb_numrecs;
- dmxr = (int)XFS_BTREE_BLOCK_MAXRECS(dblocklen, xfs_bmdr, 0);
- fkp = XFS_BMAP_BROOT_KEY_ADDR(rblock, 1, rblocklen);
- tkp = XFS_BTREE_KEY_ADDR(dblocklen, xfs_bmdr, dblock, 1, dmxr);
- fpp = XFS_BMAP_BROOT_PTR_ADDR(rblock, 1, rblocklen);
- tpp = XFS_BTREE_PTR_ADDR(dblocklen, xfs_bmdr, dblock, 1, dmxr);
- dmxr = be16_to_cpu(dblock->bb_numrecs);
- memcpy(tkp, fkp, sizeof(*fkp) * dmxr);
- memcpy(tpp, fpp, sizeof(*fpp) * dmxr); /* INT_: direct copy */
-}
-
-/*
- * Update the record to the passed values.
- */
-int
-xfs_bmbt_update(
- xfs_btree_cur_t *cur,
- xfs_fileoff_t off,
- xfs_fsblock_t bno,
- xfs_filblks_t len,
- xfs_exntst_t state)
-{
- xfs_bmbt_block_t *block;
- xfs_buf_t *bp;
- int error;
-#ifdef XFS_BMBT_TRACE
- static char fname[] = "xfs_bmbt_update";
-#endif
- xfs_bmbt_key_t key;
- int ptr;
- xfs_bmbt_rec_t *rp;
-
- XFS_BMBT_TRACE_CURSOR(cur, ENTRY);
- XFS_BMBT_TRACE_ARGFFFI(cur, (xfs_dfiloff_t)off, (xfs_dfsbno_t)bno,
- (xfs_dfilblks_t)len, (int)state);
- block = xfs_bmbt_get_block(cur, 0, &bp);
-#ifdef DEBUG
- if ((error = xfs_btree_check_lblock(cur, block, 0, bp))) {
- XFS_BMBT_TRACE_CURSOR(cur, ERROR);
- return error;
- }
-#endif
- ptr = cur->bc_ptrs[0];
- rp = XFS_BMAP_REC_IADDR(block, ptr, cur);
- xfs_bmbt_disk_set_allf(rp, off, bno, len, state);
- xfs_bmbt_log_recs(cur, bp, ptr, ptr);
- if (ptr > 1) {
- XFS_BMBT_TRACE_CURSOR(cur, EXIT);
- return 0;
- }
- INT_SET(key.br_startoff, ARCH_CONVERT, off);
- if ((error = xfs_bmbt_updkey(cur, &key, 1))) {
- XFS_BMBT_TRACE_CURSOR(cur, ERROR);
- return error;
- }
- XFS_BMBT_TRACE_CURSOR(cur, EXIT);
- return 0;
-}
-
-/*
- * Check extent records, which have just been read, for
- * any bit in the extent flag field. ASSERT on debug
- * kernels, as this condition should not occur.
- * Return an error condition (1) if any flags found,
- * otherwise return 0.
- */
-
-int
-xfs_check_nostate_extents(
- xfs_ifork_t *ifp,
- xfs_extnum_t idx,
- xfs_extnum_t num)
-{
- xfs_bmbt_rec_t *ep;
-
- for (; num > 0; num--, idx++) {
- ep = xfs_iext_get_ext(ifp, idx);
- if ((ep->l0 >>
- (64 - BMBT_EXNTFLAG_BITLEN)) != 0) {
- ASSERT(0);
- return 1;
- }
- }
- return 0;
-}
diff --git a/sys/gnu/fs/xfs/xfs_bmap_btree.h b/sys/gnu/fs/xfs/xfs_bmap_btree.h
deleted file mode 100644
index 6478cfa..0000000
--- a/sys/gnu/fs/xfs/xfs_bmap_btree.h
+++ /dev/null
@@ -1,377 +0,0 @@
-/*
- * Copyright (c) 2000,2002-2005 Silicon Graphics, Inc.
- * All Rights Reserved.
- *
- * 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.
- *
- * This program is distributed in the hope that it would 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 the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- */
-#ifndef __XFS_BMAP_BTREE_H__
-#define __XFS_BMAP_BTREE_H__
-
-#define XFS_BMAP_MAGIC 0x424d4150 /* 'BMAP' */
-
-struct xfs_btree_cur;
-struct xfs_btree_lblock;
-struct xfs_mount;
-struct xfs_inode;
-
-/*
- * Bmap root header, on-disk form only.
- */
-typedef struct xfs_bmdr_block {
- __be16 bb_level; /* 0 is a leaf */
- __be16 bb_numrecs; /* current # of data records */
-} xfs_bmdr_block_t;
-
-/*
- * Bmap btree record and extent descriptor.
- * For 32-bit kernels,
- * l0:31 is an extent flag (value 1 indicates non-normal).
- * l0:0-30 and l1:9-31 are startoff.
- * l1:0-8, l2:0-31, and l3:21-31 are startblock.
- * l3:0-20 are blockcount.
- * For 64-bit kernels,
- * l0:63 is an extent flag (value 1 indicates non-normal).
- * l0:9-62 are startoff.
- * l0:0-8 and l1:21-63 are startblock.
- * l1:0-20 are blockcount.
- */
-
-#ifndef XFS_NATIVE_HOST
-
-#define BMBT_TOTAL_BITLEN 128 /* 128 bits, 16 bytes */
-#define BMBT_EXNTFLAG_BITOFF 0
-#define BMBT_EXNTFLAG_BITLEN 1
-#define BMBT_STARTOFF_BITOFF (BMBT_EXNTFLAG_BITOFF + BMBT_EXNTFLAG_BITLEN)
-#define BMBT_STARTOFF_BITLEN 54
-#define BMBT_STARTBLOCK_BITOFF (BMBT_STARTOFF_BITOFF + BMBT_STARTOFF_BITLEN)
-#define BMBT_STARTBLOCK_BITLEN 52
-#define BMBT_BLOCKCOUNT_BITOFF \
- (BMBT_STARTBLOCK_BITOFF + BMBT_STARTBLOCK_BITLEN)
-#define BMBT_BLOCKCOUNT_BITLEN (BMBT_TOTAL_BITLEN - BMBT_BLOCKCOUNT_BITOFF)
-
-#else
-
-#define BMBT_TOTAL_BITLEN 128 /* 128 bits, 16 bytes */
-#define BMBT_EXNTFLAG_BITOFF 63
-#define BMBT_EXNTFLAG_BITLEN 1
-#define BMBT_STARTOFF_BITOFF (BMBT_EXNTFLAG_BITOFF - BMBT_STARTOFF_BITLEN)
-#define BMBT_STARTOFF_BITLEN 54
-#define BMBT_STARTBLOCK_BITOFF 85 /* 128 - 43 (other 9 is in first word) */
-#define BMBT_STARTBLOCK_BITLEN 52
-#define BMBT_BLOCKCOUNT_BITOFF 64 /* Start of second 64 bit container */
-#define BMBT_BLOCKCOUNT_BITLEN 21
-
-#endif /* XFS_NATIVE_HOST */
-
-
-#define BMBT_USE_64 1
-
-typedef struct xfs_bmbt_rec_32
-{
- __uint32_t l0, l1, l2, l3;
-} xfs_bmbt_rec_32_t;
-typedef struct xfs_bmbt_rec_64
-{
- __uint64_t l0, l1;
-} xfs_bmbt_rec_64_t;
-
-typedef __uint64_t xfs_bmbt_rec_base_t; /* use this for casts */
-typedef xfs_bmbt_rec_64_t xfs_bmbt_rec_t, xfs_bmdr_rec_t;
-
-/*
- * Values and macros for delayed-allocation startblock fields.
- */
-#define STARTBLOCKVALBITS 17
-#define STARTBLOCKMASKBITS (15 + XFS_BIG_BLKNOS * 20)
-#define DSTARTBLOCKMASKBITS (15 + 20)
-#define STARTBLOCKMASK \
- (((((xfs_fsblock_t)1) << STARTBLOCKMASKBITS) - 1) << STARTBLOCKVALBITS)
-#define DSTARTBLOCKMASK \
- (((((xfs_dfsbno_t)1) << DSTARTBLOCKMASKBITS) - 1) << STARTBLOCKVALBITS)
-
-#define ISNULLSTARTBLOCK(x) isnullstartblock(x)
-static inline int isnullstartblock(xfs_fsblock_t x)
-{
- return ((x) & STARTBLOCKMASK) == STARTBLOCKMASK;
-}
-
-#define ISNULLDSTARTBLOCK(x) isnulldstartblock(x)
-static inline int isnulldstartblock(xfs_dfsbno_t x)
-{
- return ((x) & DSTARTBLOCKMASK) == DSTARTBLOCKMASK;
-}
-
-#define NULLSTARTBLOCK(k) nullstartblock(k)
-static inline xfs_fsblock_t nullstartblock(int k)
-{
- ASSERT(k < (1 << STARTBLOCKVALBITS));
- return STARTBLOCKMASK | (k);
-}
-
-#define STARTBLOCKVAL(x) startblockval(x)
-static inline xfs_filblks_t startblockval(xfs_fsblock_t x)
-{
- return (xfs_filblks_t)((x) & ~STARTBLOCKMASK);
-}
-
-/*
- * Possible extent formats.
- */
-typedef enum {
- XFS_EXTFMT_NOSTATE = 0,
- XFS_EXTFMT_HASSTATE
-} xfs_exntfmt_t;
-
-/*
- * Possible extent states.
- */
-typedef enum {
- XFS_EXT_NORM, XFS_EXT_UNWRITTEN,
- XFS_EXT_DMAPI_OFFLINE, XFS_EXT_INVALID
-} xfs_exntst_t;
-
-/*
- * Extent state and extent format macros.
- */
-#define XFS_EXTFMT_INODE(x) \
- (XFS_SB_VERSION_HASEXTFLGBIT(&((x)->i_mount->m_sb)) ? \
- XFS_EXTFMT_HASSTATE : XFS_EXTFMT_NOSTATE)
-#define ISUNWRITTEN(x) ((x)->br_state == XFS_EXT_UNWRITTEN)
-
-/*
- * Incore version of above.
- */
-typedef struct xfs_bmbt_irec
-{
- xfs_fileoff_t br_startoff; /* starting file offset */
- xfs_fsblock_t br_startblock; /* starting block number */
- xfs_filblks_t br_blockcount; /* number of blocks */
- xfs_exntst_t br_state; /* extent state */
-} xfs_bmbt_irec_t;
-
-/*
- * Key structure for non-leaf levels of the tree.
- */
-typedef struct xfs_bmbt_key
-{
- xfs_dfiloff_t br_startoff; /* starting file offset */
-} xfs_bmbt_key_t, xfs_bmdr_key_t;
-
-typedef xfs_dfsbno_t xfs_bmbt_ptr_t, xfs_bmdr_ptr_t; /* btree pointer type */
- /* btree block header type */
-typedef struct xfs_btree_lblock xfs_bmbt_block_t;
-
-#define XFS_BUF_TO_BMBT_BLOCK(bp) ((xfs_bmbt_block_t *)XFS_BUF_PTR(bp))
-
-#define XFS_BMAP_IBLOCK_SIZE(lev,cur) (1 << (cur)->bc_blocklog)
-#define XFS_BMAP_RBLOCK_DSIZE(lev,cur) ((cur)->bc_private.b.forksize)
-#define XFS_BMAP_RBLOCK_ISIZE(lev,cur) \
- ((int)XFS_IFORK_PTR((cur)->bc_private.b.ip, \
- (cur)->bc_private.b.whichfork)->if_broot_bytes)
-
-#define XFS_BMAP_BLOCK_DSIZE(lev,cur) \
- (((lev) == (cur)->bc_nlevels - 1 ? \
- XFS_BMAP_RBLOCK_DSIZE(lev,cur) : XFS_BMAP_IBLOCK_SIZE(lev,cur)))
-#define XFS_BMAP_BLOCK_ISIZE(lev,cur) \
- (((lev) == (cur)->bc_nlevels - 1 ? \
- XFS_BMAP_RBLOCK_ISIZE(lev,cur) : XFS_BMAP_IBLOCK_SIZE(lev,cur)))
-
-#define XFS_BMAP_BLOCK_DMAXRECS(lev,cur) \
- (((lev) == (cur)->bc_nlevels - 1 ? \
- XFS_BTREE_BLOCK_MAXRECS(XFS_BMAP_RBLOCK_DSIZE(lev,cur), \
- xfs_bmdr, (lev) == 0) : \
- ((cur)->bc_mp->m_bmap_dmxr[(lev) != 0])))
-#define XFS_BMAP_BLOCK_IMAXRECS(lev,cur) \
- (((lev) == (cur)->bc_nlevels - 1 ? \
- XFS_BTREE_BLOCK_MAXRECS(XFS_BMAP_RBLOCK_ISIZE(lev,cur),\
- xfs_bmbt, (lev) == 0) : \
- ((cur)->bc_mp->m_bmap_dmxr[(lev) != 0])))
-
-#define XFS_BMAP_BLOCK_DMINRECS(lev,cur) \
- (((lev) == (cur)->bc_nlevels - 1 ? \
- XFS_BTREE_BLOCK_MINRECS(XFS_BMAP_RBLOCK_DSIZE(lev,cur),\
- xfs_bmdr, (lev) == 0) : \
- ((cur)->bc_mp->m_bmap_dmnr[(lev) != 0])))
-#define XFS_BMAP_BLOCK_IMINRECS(lev,cur) \
- (((lev) == (cur)->bc_nlevels - 1 ? \
- XFS_BTREE_BLOCK_MINRECS(XFS_BMAP_RBLOCK_ISIZE(lev,cur),\
- xfs_bmbt, (lev) == 0) : \
- ((cur)->bc_mp->m_bmap_dmnr[(lev) != 0])))
-
-#define XFS_BMAP_REC_DADDR(bb,i,cur) \
- (XFS_BTREE_REC_ADDR(XFS_BMAP_BLOCK_DSIZE( \
- be16_to_cpu((bb)->bb_level), cur), \
- xfs_bmbt, bb, i, XFS_BMAP_BLOCK_DMAXRECS( \
- be16_to_cpu((bb)->bb_level), cur)))
-#define XFS_BMAP_REC_IADDR(bb,i,cur) \
- (XFS_BTREE_REC_ADDR(XFS_BMAP_BLOCK_ISIZE( \
- be16_to_cpu((bb)->bb_level), cur), \
- xfs_bmbt, bb, i, XFS_BMAP_BLOCK_IMAXRECS( \
- be16_to_cpu((bb)->bb_level), cur)))
-
-#define XFS_BMAP_KEY_DADDR(bb,i,cur) \
- (XFS_BTREE_KEY_ADDR(XFS_BMAP_BLOCK_DSIZE( \
- be16_to_cpu((bb)->bb_level), cur), \
- xfs_bmbt, bb, i, XFS_BMAP_BLOCK_DMAXRECS( \
- be16_to_cpu((bb)->bb_level), cur)))
-#define XFS_BMAP_KEY_IADDR(bb,i,cur) \
- (XFS_BTREE_KEY_ADDR(XFS_BMAP_BLOCK_ISIZE( \
- be16_to_cpu((bb)->bb_level), cur), \
- xfs_bmbt, bb, i, XFS_BMAP_BLOCK_IMAXRECS( \
- be16_to_cpu((bb)->bb_level), cur)))
-
-#define XFS_BMAP_PTR_DADDR(bb,i,cur) \
- (XFS_BTREE_PTR_ADDR(XFS_BMAP_BLOCK_DSIZE( \
- be16_to_cpu((bb)->bb_level), cur), \
- xfs_bmbt, bb, i, XFS_BMAP_BLOCK_DMAXRECS( \
- be16_to_cpu((bb)->bb_level), cur)))
-#define XFS_BMAP_PTR_IADDR(bb,i,cur) \
- (XFS_BTREE_PTR_ADDR(XFS_BMAP_BLOCK_ISIZE( \
- be16_to_cpu((bb)->bb_level), cur), \
- xfs_bmbt, bb, i, XFS_BMAP_BLOCK_IMAXRECS( \
- be16_to_cpu((bb)->bb_level), cur)))
-
-/*
- * These are to be used when we know the size of the block and
- * we don't have a cursor.
- */
-#define XFS_BMAP_BROOT_REC_ADDR(bb,i,sz) \
- (XFS_BTREE_REC_ADDR(sz,xfs_bmbt,bb,i,XFS_BMAP_BROOT_MAXRECS(sz)))
-#define XFS_BMAP_BROOT_KEY_ADDR(bb,i,sz) \
- (XFS_BTREE_KEY_ADDR(sz,xfs_bmbt,bb,i,XFS_BMAP_BROOT_MAXRECS(sz)))
-#define XFS_BMAP_BROOT_PTR_ADDR(bb,i,sz) \
- (XFS_BTREE_PTR_ADDR(sz,xfs_bmbt,bb,i,XFS_BMAP_BROOT_MAXRECS(sz)))
-
-#define XFS_BMAP_BROOT_NUMRECS(bb) be16_to_cpu((bb)->bb_numrecs)
-#define XFS_BMAP_BROOT_MAXRECS(sz) XFS_BTREE_BLOCK_MAXRECS(sz,xfs_bmbt,0)
-
-#define XFS_BMAP_BROOT_SPACE_CALC(nrecs) \
- (int)(sizeof(xfs_bmbt_block_t) + \
- ((nrecs) * (sizeof(xfs_bmbt_key_t) + sizeof(xfs_bmbt_ptr_t))))
-
-#define XFS_BMAP_BROOT_SPACE(bb) \
- (XFS_BMAP_BROOT_SPACE_CALC(be16_to_cpu((bb)->bb_numrecs)))
-#define XFS_BMDR_SPACE_CALC(nrecs) \
- (int)(sizeof(xfs_bmdr_block_t) + \
- ((nrecs) * (sizeof(xfs_bmbt_key_t) + sizeof(xfs_bmbt_ptr_t))))
-
-/*
- * Maximum number of bmap btree levels.
- */
-#define XFS_BM_MAXLEVELS(mp,w) ((mp)->m_bm_maxlevels[(w)])
-
-#define XFS_BMAP_SANITY_CHECK(mp,bb,level) \
- (be32_to_cpu((bb)->bb_magic) == XFS_BMAP_MAGIC && \
- be16_to_cpu((bb)->bb_level) == level && \
- be16_to_cpu((bb)->bb_numrecs) > 0 && \
- be16_to_cpu((bb)->bb_numrecs) <= (mp)->m_bmap_dmxr[(level) != 0])
-
-
-#ifdef __KERNEL__
-
-#if defined(XFS_BMBT_TRACE)
-/*
- * Trace buffer entry types.
- */
-#define XFS_BMBT_KTRACE_ARGBI 1
-#define XFS_BMBT_KTRACE_ARGBII 2
-#define XFS_BMBT_KTRACE_ARGFFFI 3
-#define XFS_BMBT_KTRACE_ARGI 4
-#define XFS_BMBT_KTRACE_ARGIFK 5
-#define XFS_BMBT_KTRACE_ARGIFR 6
-#define XFS_BMBT_KTRACE_ARGIK 7
-#define XFS_BMBT_KTRACE_CUR 8
-
-#define XFS_BMBT_TRACE_SIZE 4096 /* size of global trace buffer */
-#define XFS_BMBT_KTRACE_SIZE 32 /* size of per-inode trace buffer */
-extern ktrace_t *xfs_bmbt_trace_buf;
-#endif
-
-/*
- * Prototypes for xfs_bmap.c to call.
- */
-extern void xfs_bmdr_to_bmbt(xfs_bmdr_block_t *, int, xfs_bmbt_block_t *, int);
-extern int xfs_bmbt_decrement(struct xfs_btree_cur *, int, int *);
-extern int xfs_bmbt_delete(struct xfs_btree_cur *, int *);
-extern void xfs_bmbt_get_all(xfs_bmbt_rec_t *r, xfs_bmbt_irec_t *s);
-extern xfs_bmbt_block_t *xfs_bmbt_get_block(struct xfs_btree_cur *cur,
- int, struct xfs_buf **bpp);
-extern xfs_filblks_t xfs_bmbt_get_blockcount(xfs_bmbt_rec_t *r);
-extern xfs_fsblock_t xfs_bmbt_get_startblock(xfs_bmbt_rec_t *r);
-extern xfs_fileoff_t xfs_bmbt_get_startoff(xfs_bmbt_rec_t *r);
-extern xfs_exntst_t xfs_bmbt_get_state(xfs_bmbt_rec_t *r);
-
-#ifndef XFS_NATIVE_HOST
-extern void xfs_bmbt_disk_get_all(xfs_bmbt_rec_t *r, xfs_bmbt_irec_t *s);
-extern xfs_exntst_t xfs_bmbt_disk_get_state(xfs_bmbt_rec_t *r);
-extern xfs_filblks_t xfs_bmbt_disk_get_blockcount(xfs_bmbt_rec_t *r);
-extern xfs_fsblock_t xfs_bmbt_disk_get_startblock(xfs_bmbt_rec_t *r);
-extern xfs_fileoff_t xfs_bmbt_disk_get_startoff(xfs_bmbt_rec_t *r);
-#else
-#define xfs_bmbt_disk_get_all(r, s) xfs_bmbt_get_all(r, s)
-#define xfs_bmbt_disk_get_state(r) xfs_bmbt_get_state(r)
-#define xfs_bmbt_disk_get_blockcount(r) xfs_bmbt_get_blockcount(r)
-#define xfs_bmbt_disk_get_startblock(r) xfs_bmbt_get_blockcount(r)
-#define xfs_bmbt_disk_get_startoff(r) xfs_bmbt_get_startoff(r)
-#endif /* XFS_NATIVE_HOST */
-
-extern int xfs_bmbt_increment(struct xfs_btree_cur *, int, int *);
-extern int xfs_bmbt_insert(struct xfs_btree_cur *, int *);
-extern void xfs_bmbt_log_block(struct xfs_btree_cur *, struct xfs_buf *, int);
-extern void xfs_bmbt_log_recs(struct xfs_btree_cur *, struct xfs_buf *, int,
- int);
-extern int xfs_bmbt_lookup_eq(struct xfs_btree_cur *, xfs_fileoff_t,
- xfs_fsblock_t, xfs_filblks_t, int *);
-extern int xfs_bmbt_lookup_ge(struct xfs_btree_cur *, xfs_fileoff_t,
- xfs_fsblock_t, xfs_filblks_t, int *);
-
-/*
- * Give the bmap btree a new root block. Copy the old broot contents
- * down into a real block and make the broot point to it.
- */
-extern int xfs_bmbt_newroot(struct xfs_btree_cur *cur, int *lflags, int *stat);
-
-extern void xfs_bmbt_set_all(xfs_bmbt_rec_t *r, xfs_bmbt_irec_t *s);
-extern void xfs_bmbt_set_allf(xfs_bmbt_rec_t *r, xfs_fileoff_t o,
- xfs_fsblock_t b, xfs_filblks_t c, xfs_exntst_t v);
-extern void xfs_bmbt_set_blockcount(xfs_bmbt_rec_t *r, xfs_filblks_t v);
-extern void xfs_bmbt_set_startblock(xfs_bmbt_rec_t *r, xfs_fsblock_t v);
-extern void xfs_bmbt_set_startoff(xfs_bmbt_rec_t *r, xfs_fileoff_t v);
-extern void xfs_bmbt_set_state(xfs_bmbt_rec_t *r, xfs_exntst_t v);
-
-#ifndef XFS_NATIVE_HOST
-extern void xfs_bmbt_disk_set_all(xfs_bmbt_rec_t *r, xfs_bmbt_irec_t *s);
-extern void xfs_bmbt_disk_set_allf(xfs_bmbt_rec_t *r, xfs_fileoff_t o,
- xfs_fsblock_t b, xfs_filblks_t c, xfs_exntst_t v);
-#else
-#define xfs_bmbt_disk_set_all(r, s) xfs_bmbt_set_all(r, s)
-#define xfs_bmbt_disk_set_allf(r, o, b, c, v) xfs_bmbt_set_allf(r, o, b, c, v)
-#endif /* XFS_NATIVE_HOST */
-
-extern void xfs_bmbt_to_bmdr(xfs_bmbt_block_t *, int, xfs_bmdr_block_t *, int);
-extern int xfs_bmbt_update(struct xfs_btree_cur *, xfs_fileoff_t,
- xfs_fsblock_t, xfs_filblks_t, xfs_exntst_t);
-
-#ifdef DEBUG
-/*
- * Get the data from the pointed-to record.
- */
-extern int xfs_bmbt_get_rec(struct xfs_btree_cur *, xfs_fileoff_t *,
- xfs_fsblock_t *, xfs_filblks_t *,
- xfs_exntst_t *, int *);
-#endif
-
-#endif /* __KERNEL__ */
-
-#endif /* __XFS_BMAP_BTREE_H__ */
diff --git a/sys/gnu/fs/xfs/xfs_btree.c b/sys/gnu/fs/xfs/xfs_btree.c
deleted file mode 100644
index 52d5d09..0000000
--- a/sys/gnu/fs/xfs/xfs_btree.c
+++ /dev/null
@@ -1,943 +0,0 @@
-/*
- * Copyright (c) 2000-2002,2005 Silicon Graphics, Inc.
- * All Rights Reserved.
- *
- * 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.
- *
- * This program is distributed in the hope that it would 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 the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- */
-#include "xfs.h"
-#include "xfs_fs.h"
-#include "xfs_types.h"
-#include "xfs_bit.h"
-#include "xfs_log.h"
-#include "xfs_inum.h"
-#include "xfs_trans.h"
-#include "xfs_sb.h"
-#include "xfs_ag.h"
-#include "xfs_dir.h"
-#include "xfs_dir2.h"
-#include "xfs_dmapi.h"
-#include "xfs_mount.h"
-#include "xfs_bmap_btree.h"
-#include "xfs_alloc_btree.h"
-#include "xfs_ialloc_btree.h"
-#include "xfs_dir_sf.h"
-#include "xfs_dir2_sf.h"
-#include "xfs_attr_sf.h"
-#include "xfs_dinode.h"
-#include "xfs_inode.h"
-#include "xfs_btree.h"
-#include "xfs_ialloc.h"
-#include "xfs_error.h"
-
-/*
- * Cursor allocation zone.
- */
-kmem_zone_t *xfs_btree_cur_zone;
-
-/*
- * Btree magic numbers.
- */
-const __uint32_t xfs_magics[XFS_BTNUM_MAX] =
-{
- XFS_ABTB_MAGIC, XFS_ABTC_MAGIC, XFS_BMAP_MAGIC, XFS_IBT_MAGIC
-};
-
-/*
- * Prototypes for internal routines.
- */
-
-/*
- * Checking routine: return maxrecs for the block.
- */
-STATIC int /* number of records fitting in block */
-xfs_btree_maxrecs(
- xfs_btree_cur_t *cur, /* btree cursor */
- xfs_btree_block_t *block);/* generic btree block pointer */
-
-/*
- * Internal routines.
- */
-
-/*
- * Retrieve the block pointer from the cursor at the given level.
- * This may be a bmap btree root or from a buffer.
- */
-STATIC xfs_btree_block_t * /* generic btree block pointer */
-xfs_btree_get_block(
- xfs_btree_cur_t *cur, /* btree cursor */
- int level, /* level in btree */
- struct xfs_buf **bpp); /* buffer containing the block */
-
-/*
- * Checking routine: return maxrecs for the block.
- */
-STATIC int /* number of records fitting in block */
-xfs_btree_maxrecs(
- xfs_btree_cur_t *cur, /* btree cursor */
- xfs_btree_block_t *block) /* generic btree block pointer */
-{
- switch (cur->bc_btnum) {
- case XFS_BTNUM_BNO:
- case XFS_BTNUM_CNT:
- return (int)XFS_ALLOC_BLOCK_MAXRECS(
- be16_to_cpu(block->bb_h.bb_level), cur);
- case XFS_BTNUM_BMAP:
- return (int)XFS_BMAP_BLOCK_IMAXRECS(
- be16_to_cpu(block->bb_h.bb_level), cur);
- case XFS_BTNUM_INO:
- return (int)XFS_INOBT_BLOCK_MAXRECS(
- be16_to_cpu(block->bb_h.bb_level), cur);
- default:
- ASSERT(0);
- return 0;
- }
-}
-
-/*
- * External routines.
- */
-
-#ifdef DEBUG
-/*
- * Debug routine: check that block header is ok.
- */
-void
-xfs_btree_check_block(
- xfs_btree_cur_t *cur, /* btree cursor */
- xfs_btree_block_t *block, /* generic btree block pointer */
- int level, /* level of the btree block */
- xfs_buf_t *bp) /* buffer containing block, if any */
-{
- if (XFS_BTREE_LONG_PTRS(cur->bc_btnum))
- xfs_btree_check_lblock(cur, (xfs_btree_lblock_t *)block, level,
- bp);
- else
- xfs_btree_check_sblock(cur, (xfs_btree_sblock_t *)block, level,
- bp);
-}
-
-/*
- * Debug routine: check that keys are in the right order.
- */
-void
-xfs_btree_check_key(
- xfs_btnum_t btnum, /* btree identifier */
- void *ak1, /* pointer to left (lower) key */
- void *ak2) /* pointer to right (higher) key */
-{
- switch (btnum) {
- case XFS_BTNUM_BNO: {
- xfs_alloc_key_t *k1;
- xfs_alloc_key_t *k2;
-
- k1 = ak1;
- k2 = ak2;
- ASSERT(be32_to_cpu(k1->ar_startblock) < be32_to_cpu(k2->ar_startblock));
- break;
- }
- case XFS_BTNUM_CNT: {
- xfs_alloc_key_t *k1;
- xfs_alloc_key_t *k2;
-
- k1 = ak1;
- k2 = ak2;
- ASSERT(be32_to_cpu(k1->ar_blockcount) < be32_to_cpu(k2->ar_blockcount) ||
- (k1->ar_blockcount == k2->ar_blockcount &&
- be32_to_cpu(k1->ar_startblock) < be32_to_cpu(k2->ar_startblock)));
- break;
- }
- case XFS_BTNUM_BMAP: {
- xfs_bmbt_key_t *k1;
- xfs_bmbt_key_t *k2;
-
- k1 = ak1;
- k2 = ak2;
- ASSERT(INT_GET(k1->br_startoff, ARCH_CONVERT) < INT_GET(k2->br_startoff, ARCH_CONVERT));
- break;
- }
- case XFS_BTNUM_INO: {
- xfs_inobt_key_t *k1;
- xfs_inobt_key_t *k2;
-
- k1 = ak1;
- k2 = ak2;
- ASSERT(INT_GET(k1->ir_startino, ARCH_CONVERT) < INT_GET(k2->ir_startino, ARCH_CONVERT));
- break;
- }
- default:
- ASSERT(0);
- }
-}
-#endif /* DEBUG */
-
-/*
- * Checking routine: check that long form block header is ok.
- */
-/* ARGSUSED */
-int /* error (0 or EFSCORRUPTED) */
-xfs_btree_check_lblock(
- xfs_btree_cur_t *cur, /* btree cursor */
- xfs_btree_lblock_t *block, /* btree long form block pointer */
- int level, /* level of the btree block */
- xfs_buf_t *bp) /* buffer for block, if any */
-{
- int lblock_ok; /* block passes checks */
- xfs_mount_t *mp; /* file system mount point */
-
- mp = cur->bc_mp;
- lblock_ok =
- be32_to_cpu(block->bb_magic) == xfs_magics[cur->bc_btnum] &&
- be16_to_cpu(block->bb_level) == level &&
- be16_to_cpu(block->bb_numrecs) <=
- xfs_btree_maxrecs(cur, (xfs_btree_block_t *)block) &&
- block->bb_leftsib &&
- (be64_to_cpu(block->bb_leftsib) == NULLDFSBNO ||
- XFS_FSB_SANITY_CHECK(mp, be64_to_cpu(block->bb_leftsib))) &&
- block->bb_rightsib &&
- (be64_to_cpu(block->bb_rightsib) == NULLDFSBNO ||
- XFS_FSB_SANITY_CHECK(mp, be64_to_cpu(block->bb_rightsib)));
- if (unlikely(XFS_TEST_ERROR(!lblock_ok, mp, XFS_ERRTAG_BTREE_CHECK_LBLOCK,
- XFS_RANDOM_BTREE_CHECK_LBLOCK))) {
- if (bp)
- xfs_buftrace("LBTREE ERROR", bp);
- XFS_ERROR_REPORT("xfs_btree_check_lblock", XFS_ERRLEVEL_LOW,
- mp);
- return XFS_ERROR(EFSCORRUPTED);
- }
- return 0;
-}
-
-/*
- * Checking routine: check that (long) pointer is ok.
- */
-int /* error (0 or EFSCORRUPTED) */
-xfs_btree_check_lptr(
- xfs_btree_cur_t *cur, /* btree cursor */
- xfs_dfsbno_t ptr, /* btree block disk address */
- int level) /* btree block level */
-{
- xfs_mount_t *mp; /* file system mount point */
-
- mp = cur->bc_mp;
- XFS_WANT_CORRUPTED_RETURN(
- level > 0 &&
- ptr != NULLDFSBNO &&
- XFS_FSB_SANITY_CHECK(mp, ptr));
- return 0;
-}
-
-#ifdef DEBUG
-/*
- * Debug routine: check that records are in the right order.
- */
-void
-xfs_btree_check_rec(
- xfs_btnum_t btnum, /* btree identifier */
- void *ar1, /* pointer to left (lower) record */
- void *ar2) /* pointer to right (higher) record */
-{
- switch (btnum) {
- case XFS_BTNUM_BNO: {
- xfs_alloc_rec_t *r1;
- xfs_alloc_rec_t *r2;
-
- r1 = ar1;
- r2 = ar2;
- ASSERT(be32_to_cpu(r1->ar_startblock) +
- be32_to_cpu(r1->ar_blockcount) <=
- be32_to_cpu(r2->ar_startblock));
- break;
- }
- case XFS_BTNUM_CNT: {
- xfs_alloc_rec_t *r1;
- xfs_alloc_rec_t *r2;
-
- r1 = ar1;
- r2 = ar2;
- ASSERT(be32_to_cpu(r1->ar_blockcount) < be32_to_cpu(r2->ar_blockcount) ||
- (r1->ar_blockcount == r2->ar_blockcount &&
- be32_to_cpu(r1->ar_startblock) < be32_to_cpu(r2->ar_startblock)));
- break;
- }
- case XFS_BTNUM_BMAP: {
- xfs_bmbt_rec_t *r1;
- xfs_bmbt_rec_t *r2;
-
- r1 = ar1;
- r2 = ar2;
- ASSERT(xfs_bmbt_disk_get_startoff(r1) +
- xfs_bmbt_disk_get_blockcount(r1) <=
- xfs_bmbt_disk_get_startoff(r2));
- break;
- }
- case XFS_BTNUM_INO: {
- xfs_inobt_rec_t *r1;
- xfs_inobt_rec_t *r2;
-
- r1 = ar1;
- r2 = ar2;
- ASSERT(INT_GET(r1->ir_startino, ARCH_CONVERT) + XFS_INODES_PER_CHUNK <=
- INT_GET(r2->ir_startino, ARCH_CONVERT));
- break;
- }
- default:
- ASSERT(0);
- }
-}
-#endif /* DEBUG */
-
-/*
- * Checking routine: check that block header is ok.
- */
-/* ARGSUSED */
-int /* error (0 or EFSCORRUPTED) */
-xfs_btree_check_sblock(
- xfs_btree_cur_t *cur, /* btree cursor */
- xfs_btree_sblock_t *block, /* btree short form block pointer */
- int level, /* level of the btree block */
- xfs_buf_t *bp) /* buffer containing block */
-{
- xfs_buf_t *agbp; /* buffer for ag. freespace struct */
- xfs_agf_t *agf; /* ag. freespace structure */
- xfs_agblock_t agflen; /* native ag. freespace length */
- int sblock_ok; /* block passes checks */
-
- agbp = cur->bc_private.a.agbp;
- agf = XFS_BUF_TO_AGF(agbp);
- agflen = be32_to_cpu(agf->agf_length);
- sblock_ok =
- be32_to_cpu(block->bb_magic) == xfs_magics[cur->bc_btnum] &&
- be16_to_cpu(block->bb_level) == level &&
- be16_to_cpu(block->bb_numrecs) <=
- xfs_btree_maxrecs(cur, (xfs_btree_block_t *)block) &&
- (be32_to_cpu(block->bb_leftsib) == NULLAGBLOCK ||
- be32_to_cpu(block->bb_leftsib) < agflen) &&
- block->bb_leftsib &&
- (be32_to_cpu(block->bb_rightsib) == NULLAGBLOCK ||
- be32_to_cpu(block->bb_rightsib) < agflen) &&
- block->bb_rightsib;
- if (unlikely(XFS_TEST_ERROR(!sblock_ok, cur->bc_mp,
- XFS_ERRTAG_BTREE_CHECK_SBLOCK,
- XFS_RANDOM_BTREE_CHECK_SBLOCK))) {
- if (bp)
- xfs_buftrace("SBTREE ERROR", bp);
- XFS_ERROR_REPORT("xfs_btree_check_sblock", XFS_ERRLEVEL_LOW,
- cur->bc_mp);
- return XFS_ERROR(EFSCORRUPTED);
- }
- return 0;
-}
-
-/*
- * Checking routine: check that (short) pointer is ok.
- */
-int /* error (0 or EFSCORRUPTED) */
-xfs_btree_check_sptr(
- xfs_btree_cur_t *cur, /* btree cursor */
- xfs_agblock_t ptr, /* btree block disk address */
- int level) /* btree block level */
-{
- xfs_buf_t *agbp; /* buffer for ag. freespace struct */
- xfs_agf_t *agf; /* ag. freespace structure */
-
- agbp = cur->bc_private.a.agbp;
- agf = XFS_BUF_TO_AGF(agbp);
- XFS_WANT_CORRUPTED_RETURN(
- level > 0 &&
- ptr != NULLAGBLOCK && ptr != 0 &&
- ptr < be32_to_cpu(agf->agf_length));
- return 0;
-}
-
-/*
- * Delete the btree cursor.
- */
-void
-xfs_btree_del_cursor(
- xfs_btree_cur_t *cur, /* btree cursor */
- int error) /* del because of error */
-{
- int i; /* btree level */
-
- /*
- * Clear the buffer pointers, and release the buffers.
- * If we're doing this in the face of an error, we
- * need to make sure to inspect all of the entries
- * in the bc_bufs array for buffers to be unlocked.
- * This is because some of the btree code works from
- * level n down to 0, and if we get an error along
- * the way we won't have initialized all the entries
- * down to 0.
- */
- for (i = 0; i < cur->bc_nlevels; i++) {
- if (cur->bc_bufs[i])
- xfs_btree_setbuf(cur, i, NULL);
- else if (!error)
- break;
- }
- /*
- * Can't free a bmap cursor without having dealt with the
- * allocated indirect blocks' accounting.
- */
- ASSERT(cur->bc_btnum != XFS_BTNUM_BMAP ||
- cur->bc_private.b.allocated == 0);
- /*
- * Free the cursor.
- */
- kmem_zone_free(xfs_btree_cur_zone, cur);
-}
-
-/*
- * Duplicate the btree cursor.
- * Allocate a new one, copy the record, re-get the buffers.
- */
-int /* error */
-xfs_btree_dup_cursor(
- xfs_btree_cur_t *cur, /* input cursor */
- xfs_btree_cur_t **ncur) /* output cursor */
-{
- xfs_buf_t *bp; /* btree block's buffer pointer */
- int error; /* error return value */
- int i; /* level number of btree block */
- xfs_mount_t *mp; /* mount structure for filesystem */
- xfs_btree_cur_t *new; /* new cursor value */
- xfs_trans_t *tp; /* transaction pointer, can be NULL */
-
- tp = cur->bc_tp;
- mp = cur->bc_mp;
- /*
- * Allocate a new cursor like the old one.
- */
- new = xfs_btree_init_cursor(mp, tp, cur->bc_private.a.agbp,
- cur->bc_private.a.agno, cur->bc_btnum, cur->bc_private.b.ip,
- cur->bc_private.b.whichfork);
- /*
- * Copy the record currently in the cursor.
- */
- new->bc_rec = cur->bc_rec;
- /*
- * For each level current, re-get the buffer and copy the ptr value.
- */
- for (i = 0; i < new->bc_nlevels; i++) {
- new->bc_ptrs[i] = cur->bc_ptrs[i];
- new->bc_ra[i] = cur->bc_ra[i];
- if ((bp = cur->bc_bufs[i])) {
- if ((error = xfs_trans_read_buf(mp, tp, mp->m_ddev_targp,
- XFS_BUF_ADDR(bp), mp->m_bsize, 0, &bp))) {
- xfs_btree_del_cursor(new, error);
- *ncur = NULL;
- return error;
- }
- new->bc_bufs[i] = bp;
- ASSERT(bp);
- ASSERT(!XFS_BUF_GETERROR(bp));
- } else
- new->bc_bufs[i] = NULL;
- }
- /*
- * For bmap btrees, copy the firstblock, flist, and flags values,
- * since init cursor doesn't get them.
- */
- if (new->bc_btnum == XFS_BTNUM_BMAP) {
- new->bc_private.b.firstblock = cur->bc_private.b.firstblock;
- new->bc_private.b.flist = cur->bc_private.b.flist;
- new->bc_private.b.flags = cur->bc_private.b.flags;
- }
- *ncur = new;
- return 0;
-}
-
-/*
- * Change the cursor to point to the first record at the given level.
- * Other levels are unaffected.
- */
-int /* success=1, failure=0 */
-xfs_btree_firstrec(
- xfs_btree_cur_t *cur, /* btree cursor */
- int level) /* level to change */
-{
- xfs_btree_block_t *block; /* generic btree block pointer */
- xfs_buf_t *bp; /* buffer containing block */
-
- /*
- * Get the block pointer for this level.
- */
- block = xfs_btree_get_block(cur, level, &bp);
- xfs_btree_check_block(cur, block, level, bp);
- /*
- * It's empty, there is no such record.
- */
- if (!block->bb_h.bb_numrecs)
- return 0;
- /*
- * Set the ptr value to 1, that's the first record/key.
- */
- cur->bc_ptrs[level] = 1;
- return 1;
-}
-
-/*
- * Retrieve the block pointer from the cursor at the given level.
- * This may be a bmap btree root or from a buffer.
- */
-STATIC xfs_btree_block_t * /* generic btree block pointer */
-xfs_btree_get_block(
- xfs_btree_cur_t *cur, /* btree cursor */
- int level, /* level in btree */
- xfs_buf_t **bpp) /* buffer containing the block */
-{
- xfs_btree_block_t *block; /* return value */
- xfs_buf_t *bp; /* return buffer */
- xfs_ifork_t *ifp; /* inode fork pointer */
- int whichfork; /* data or attr fork */
-
- if (cur->bc_btnum == XFS_BTNUM_BMAP && level == cur->bc_nlevels - 1) {
- whichfork = cur->bc_private.b.whichfork;
- ifp = XFS_IFORK_PTR(cur->bc_private.b.ip, whichfork);
- block = (xfs_btree_block_t *)ifp->if_broot;
- bp = NULL;
- } else {
- bp = cur->bc_bufs[level];
- block = XFS_BUF_TO_BLOCK(bp);
- }
- ASSERT(block != NULL);
- *bpp = bp;
- return block;
-}
-
-/*
- * Get a buffer for the block, return it with no data read.
- * Long-form addressing.
- */
-xfs_buf_t * /* buffer for fsbno */
-xfs_btree_get_bufl(
- xfs_mount_t *mp, /* file system mount point */
- xfs_trans_t *tp, /* transaction pointer */
- xfs_fsblock_t fsbno, /* file system block number */
- uint lock) /* lock flags for get_buf */
-{
- xfs_buf_t *bp; /* buffer pointer (return value) */
- xfs_daddr_t d; /* real disk block address */
-
- ASSERT(fsbno != NULLFSBLOCK);
- d = XFS_FSB_TO_DADDR(mp, fsbno);
- bp = xfs_trans_get_buf(tp, mp->m_ddev_targp, d, mp->m_bsize, lock);
- ASSERT(bp);
- ASSERT(!XFS_BUF_GETERROR(bp));
- return bp;
-}
-
-/*
- * Get a buffer for the block, return it with no data read.
- * Short-form addressing.
- */
-xfs_buf_t * /* buffer for agno/agbno */
-xfs_btree_get_bufs(
- xfs_mount_t *mp, /* file system mount point */
- xfs_trans_t *tp, /* transaction pointer */
- xfs_agnumber_t agno, /* allocation group number */
- xfs_agblock_t agbno, /* allocation group block number */
- uint lock) /* lock flags for get_buf */
-{
- xfs_buf_t *bp; /* buffer pointer (return value) */
- xfs_daddr_t d; /* real disk block address */
-
- ASSERT(agno != NULLAGNUMBER);
- ASSERT(agbno != NULLAGBLOCK);
- d = XFS_AGB_TO_DADDR(mp, agno, agbno);
- bp = xfs_trans_get_buf(tp, mp->m_ddev_targp, d, mp->m_bsize, lock);
- ASSERT(bp);
- ASSERT(!XFS_BUF_GETERROR(bp));
- return bp;
-}
-
-/*
- * Allocate a new btree cursor.
- * The cursor is either for allocation (A) or bmap (B) or inodes (I).
- */
-xfs_btree_cur_t * /* new btree cursor */
-xfs_btree_init_cursor(
- xfs_mount_t *mp, /* file system mount point */
- xfs_trans_t *tp, /* transaction pointer */
- xfs_buf_t *agbp, /* (A only) buffer for agf structure */
- /* (I only) buffer for agi structure */
- xfs_agnumber_t agno, /* (AI only) allocation group number */
- xfs_btnum_t btnum, /* btree identifier */
- xfs_inode_t *ip, /* (B only) inode owning the btree */
- int whichfork) /* (B only) data or attr fork */
-{
- xfs_agf_t *agf; /* (A) allocation group freespace */
- xfs_agi_t *agi; /* (I) allocation group inodespace */
- xfs_btree_cur_t *cur; /* return value */
- xfs_ifork_t *ifp; /* (I) inode fork pointer */
- int nlevels=0; /* number of levels in the btree */
-
- ASSERT(xfs_btree_cur_zone != NULL);
- /*
- * Allocate a new cursor.
- */
- cur = kmem_zone_zalloc(xfs_btree_cur_zone, KM_SLEEP);
- /*
- * Deduce the number of btree levels from the arguments.
- */
- switch (btnum) {
- case XFS_BTNUM_BNO:
- case XFS_BTNUM_CNT:
- agf = XFS_BUF_TO_AGF(agbp);
- nlevels = be32_to_cpu(agf->agf_levels[btnum]);
- break;
- case XFS_BTNUM_BMAP:
- ifp = XFS_IFORK_PTR(ip, whichfork);
- nlevels = be16_to_cpu(ifp->if_broot->bb_level) + 1;
- break;
- case XFS_BTNUM_INO:
- agi = XFS_BUF_TO_AGI(agbp);
- nlevels = be32_to_cpu(agi->agi_level);
- break;
- default:
- ASSERT(0);
- }
- /*
- * Fill in the common fields.
- */
- cur->bc_tp = tp;
- cur->bc_mp = mp;
- cur->bc_nlevels = nlevels;
- cur->bc_btnum = btnum;
- cur->bc_blocklog = mp->m_sb.sb_blocklog;
- /*
- * Fill in private fields.
- */
- switch (btnum) {
- case XFS_BTNUM_BNO:
- case XFS_BTNUM_CNT:
- /*
- * Allocation btree fields.
- */
- cur->bc_private.a.agbp = agbp;
- cur->bc_private.a.agno = agno;
- break;
- case XFS_BTNUM_BMAP:
- /*
- * Bmap btree fields.
- */
- cur->bc_private.b.forksize = XFS_IFORK_SIZE(ip, whichfork);
- cur->bc_private.b.ip = ip;
- cur->bc_private.b.firstblock = NULLFSBLOCK;
- cur->bc_private.b.flist = NULL;
- cur->bc_private.b.allocated = 0;
- cur->bc_private.b.flags = 0;
- cur->bc_private.b.whichfork = whichfork;
- break;
- case XFS_BTNUM_INO:
- /*
- * Inode allocation btree fields.
- */
- cur->bc_private.i.agbp = agbp;
- cur->bc_private.i.agno = agno;
- break;
- default:
- ASSERT(0);
- }
- return cur;
-}
-
-/*
- * Check for the cursor referring to the last block at the given level.
- */
-int /* 1=is last block, 0=not last block */
-xfs_btree_islastblock(
- xfs_btree_cur_t *cur, /* btree cursor */
- int level) /* level to check */
-{
- xfs_btree_block_t *block; /* generic btree block pointer */
- xfs_buf_t *bp; /* buffer containing block */
-
- block = xfs_btree_get_block(cur, level, &bp);
- xfs_btree_check_block(cur, block, level, bp);
- if (XFS_BTREE_LONG_PTRS(cur->bc_btnum))
- return be64_to_cpu(block->bb_u.l.bb_rightsib) == NULLDFSBNO;
- else
- return be32_to_cpu(block->bb_u.s.bb_rightsib) == NULLAGBLOCK;
-}
-
-/*
- * Change the cursor to point to the last record in the current block
- * at the given level. Other levels are unaffected.
- */
-int /* success=1, failure=0 */
-xfs_btree_lastrec(
- xfs_btree_cur_t *cur, /* btree cursor */
- int level) /* level to change */
-{
- xfs_btree_block_t *block; /* generic btree block pointer */
- xfs_buf_t *bp; /* buffer containing block */
-
- /*
- * Get the block pointer for this level.
- */
- block = xfs_btree_get_block(cur, level, &bp);
- xfs_btree_check_block(cur, block, level, bp);
- /*
- * It's empty, there is no such record.
- */
- if (!block->bb_h.bb_numrecs)
- return 0;
- /*
- * Set the ptr value to numrecs, that's the last record/key.
- */
- cur->bc_ptrs[level] = be16_to_cpu(block->bb_h.bb_numrecs);
- return 1;
-}
-
-/*
- * Compute first and last byte offsets for the fields given.
- * Interprets the offsets table, which contains struct field offsets.
- */
-void
-xfs_btree_offsets(
- __int64_t fields, /* bitmask of fields */
- const short *offsets, /* table of field offsets */
- int nbits, /* number of bits to inspect */
- int *first, /* output: first byte offset */
- int *last) /* output: last byte offset */
-{
- int i; /* current bit number */
- __int64_t imask; /* mask for current bit number */
-
- ASSERT(fields != 0);
- /*
- * Find the lowest bit, so the first byte offset.
- */
- for (i = 0, imask = 1LL; ; i++, imask <<= 1) {
- if (imask & fields) {
- *first = offsets[i];
- break;
- }
- }
- /*
- * Find the highest bit, so the last byte offset.
- */
- for (i = nbits - 1, imask = 1LL << i; ; i--, imask >>= 1) {
- if (imask & fields) {
- *last = offsets[i + 1] - 1;
- break;
- }
- }
-}
-
-/*
- * Get a buffer for the block, return it read in.
- * Long-form addressing.
- */
-int /* error */
-xfs_btree_read_bufl(
- xfs_mount_t *mp, /* file system mount point */
- xfs_trans_t *tp, /* transaction pointer */
- xfs_fsblock_t fsbno, /* file system block number */
- uint lock, /* lock flags for read_buf */
- xfs_buf_t **bpp, /* buffer for fsbno */
- int refval) /* ref count value for buffer */
-{
- xfs_buf_t *bp; /* return value */
- xfs_daddr_t d; /* real disk block address */
- int error;
-
- ASSERT(fsbno != NULLFSBLOCK);
- d = XFS_FSB_TO_DADDR(mp, fsbno);
- if ((error = xfs_trans_read_buf(mp, tp, mp->m_ddev_targp, d,
- mp->m_bsize, lock, &bp))) {
- return error;
- }
- ASSERT(!bp || !XFS_BUF_GETERROR(bp));
- if (bp != NULL) {
- XFS_BUF_SET_VTYPE_REF(bp, B_FS_MAP, refval);
- }
- *bpp = bp;
- return 0;
-}
-
-/*
- * Get a buffer for the block, return it read in.
- * Short-form addressing.
- */
-int /* error */
-xfs_btree_read_bufs(
- xfs_mount_t *mp, /* file system mount point */
- xfs_trans_t *tp, /* transaction pointer */
- xfs_agnumber_t agno, /* allocation group number */
- xfs_agblock_t agbno, /* allocation group block number */
- uint lock, /* lock flags for read_buf */
- xfs_buf_t **bpp, /* buffer for agno/agbno */
- int refval) /* ref count value for buffer */
-{
- xfs_buf_t *bp; /* return value */
- xfs_daddr_t d; /* real disk block address */
- int error;
-
- ASSERT(agno != NULLAGNUMBER);
- ASSERT(agbno != NULLAGBLOCK);
- d = XFS_AGB_TO_DADDR(mp, agno, agbno);
- if ((error = xfs_trans_read_buf(mp, tp, mp->m_ddev_targp, d,
- mp->m_bsize, lock, &bp))) {
- return error;
- }
- ASSERT(!bp || !XFS_BUF_GETERROR(bp));
- if (bp != NULL) {
- switch (refval) {
- case XFS_ALLOC_BTREE_REF:
- XFS_BUF_SET_VTYPE_REF(bp, B_FS_MAP, refval);
- break;
- case XFS_INO_BTREE_REF:
- XFS_BUF_SET_VTYPE_REF(bp, B_FS_INOMAP, refval);
- break;
- }
- }
- *bpp = bp;
- return 0;
-}
-
-/*
- * Read-ahead the block, don't wait for it, don't return a buffer.
- * Long-form addressing.
- */
-/* ARGSUSED */
-void
-xfs_btree_reada_bufl(
- xfs_mount_t *mp, /* file system mount point */
- xfs_fsblock_t fsbno, /* file system block number */
- xfs_extlen_t count) /* count of filesystem blocks */
-{
- xfs_daddr_t d;
-
- ASSERT(fsbno != NULLFSBLOCK);
- d = XFS_FSB_TO_DADDR(mp, fsbno);
- xfs_baread(mp->m_ddev_targp, d, mp->m_bsize * count);
-}
-
-/*
- * Read-ahead the block, don't wait for it, don't return a buffer.
- * Short-form addressing.
- */
-/* ARGSUSED */
-void
-xfs_btree_reada_bufs(
- xfs_mount_t *mp, /* file system mount point */
- xfs_agnumber_t agno, /* allocation group number */
- xfs_agblock_t agbno, /* allocation group block number */
- xfs_extlen_t count) /* count of filesystem blocks */
-{
- xfs_daddr_t d;
-
- ASSERT(agno != NULLAGNUMBER);
- ASSERT(agbno != NULLAGBLOCK);
- d = XFS_AGB_TO_DADDR(mp, agno, agbno);
- xfs_baread(mp->m_ddev_targp, d, mp->m_bsize * count);
-}
-
-/*
- * Read-ahead btree blocks, at the given level.
- * Bits in lr are set from XFS_BTCUR_{LEFT,RIGHT}RA.
- */
-int
-xfs_btree_readahead_core(
- xfs_btree_cur_t *cur, /* btree cursor */
- int lev, /* level in btree */
- int lr) /* left/right bits */
-{
- xfs_alloc_block_t *a;
- xfs_bmbt_block_t *b;
- xfs_inobt_block_t *i;
- int rval = 0;
-
- ASSERT(cur->bc_bufs[lev] != NULL);
- cur->bc_ra[lev] |= lr;
- switch (cur->bc_btnum) {
- case XFS_BTNUM_BNO:
- case XFS_BTNUM_CNT:
- a = XFS_BUF_TO_ALLOC_BLOCK(cur->bc_bufs[lev]);
- if ((lr & XFS_BTCUR_LEFTRA) && be32_to_cpu(a->bb_leftsib) != NULLAGBLOCK) {
- xfs_btree_reada_bufs(cur->bc_mp, cur->bc_private.a.agno,
- be32_to_cpu(a->bb_leftsib), 1);
- rval++;
- }
- if ((lr & XFS_BTCUR_RIGHTRA) && be32_to_cpu(a->bb_rightsib) != NULLAGBLOCK) {
- xfs_btree_reada_bufs(cur->bc_mp, cur->bc_private.a.agno,
- be32_to_cpu(a->bb_rightsib), 1);
- rval++;
- }
- break;
- case XFS_BTNUM_BMAP:
- b = XFS_BUF_TO_BMBT_BLOCK(cur->bc_bufs[lev]);
- if ((lr & XFS_BTCUR_LEFTRA) && be64_to_cpu(b->bb_leftsib) != NULLDFSBNO) {
- xfs_btree_reada_bufl(cur->bc_mp, be64_to_cpu(b->bb_leftsib), 1);
- rval++;
- }
- if ((lr & XFS_BTCUR_RIGHTRA) && be64_to_cpu(b->bb_rightsib) != NULLDFSBNO) {
- xfs_btree_reada_bufl(cur->bc_mp, be64_to_cpu(b->bb_rightsib), 1);
- rval++;
- }
- break;
- case XFS_BTNUM_INO:
- i = XFS_BUF_TO_INOBT_BLOCK(cur->bc_bufs[lev]);
- if ((lr & XFS_BTCUR_LEFTRA) && be32_to_cpu(i->bb_leftsib) != NULLAGBLOCK) {
- xfs_btree_reada_bufs(cur->bc_mp, cur->bc_private.i.agno,
- be32_to_cpu(i->bb_leftsib), 1);
- rval++;
- }
- if ((lr & XFS_BTCUR_RIGHTRA) && be32_to_cpu(i->bb_rightsib) != NULLAGBLOCK) {
- xfs_btree_reada_bufs(cur->bc_mp, cur->bc_private.i.agno,
- be32_to_cpu(i->bb_rightsib), 1);
- rval++;
- }
- break;
- default:
- ASSERT(0);
- }
- return rval;
-}
-
-/*
- * Set the buffer for level "lev" in the cursor to bp, releasing
- * any previous buffer.
- */
-void
-xfs_btree_setbuf(
- xfs_btree_cur_t *cur, /* btree cursor */
- int lev, /* level in btree */
- xfs_buf_t *bp) /* new buffer to set */
-{
- xfs_btree_block_t *b; /* btree block */
- xfs_buf_t *obp; /* old buffer pointer */
-
- obp = cur->bc_bufs[lev];
- if (obp)
- xfs_trans_brelse(cur->bc_tp, obp);
- cur->bc_bufs[lev] = bp;
- cur->bc_ra[lev] = 0;
- if (!bp)
- return;
- b = XFS_BUF_TO_BLOCK(bp);
- if (XFS_BTREE_LONG_PTRS(cur->bc_btnum)) {
- if (be64_to_cpu(b->bb_u.l.bb_leftsib) == NULLDFSBNO)
- cur->bc_ra[lev] |= XFS_BTCUR_LEFTRA;
- if (be64_to_cpu(b->bb_u.l.bb_rightsib) == NULLDFSBNO)
- cur->bc_ra[lev] |= XFS_BTCUR_RIGHTRA;
- } else {
- if (be32_to_cpu(b->bb_u.s.bb_leftsib) == NULLAGBLOCK)
- cur->bc_ra[lev] |= XFS_BTCUR_LEFTRA;
- if (be32_to_cpu(b->bb_u.s.bb_rightsib) == NULLAGBLOCK)
- cur->bc_ra[lev] |= XFS_BTCUR_RIGHTRA;
- }
-}
diff --git a/sys/gnu/fs/xfs/xfs_btree.h b/sys/gnu/fs/xfs/xfs_btree.h
deleted file mode 100644
index 44f1bd9..0000000
--- a/sys/gnu/fs/xfs/xfs_btree.h
+++ /dev/null
@@ -1,473 +0,0 @@
-/*
- * Copyright (c) 2000-2001,2005 Silicon Graphics, Inc.
- * All Rights Reserved.
- *
- * 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.
- *
- * This program is distributed in the hope that it would 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 the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- */
-#ifndef __XFS_BTREE_H__
-#define __XFS_BTREE_H__
-
-struct xfs_buf;
-struct xfs_bmap_free;
-struct xfs_inode;
-struct xfs_mount;
-struct xfs_trans;
-
-/*
- * This nonsense is to make -wlint happy.
- */
-#define XFS_LOOKUP_EQ ((xfs_lookup_t)XFS_LOOKUP_EQi)
-#define XFS_LOOKUP_LE ((xfs_lookup_t)XFS_LOOKUP_LEi)
-#define XFS_LOOKUP_GE ((xfs_lookup_t)XFS_LOOKUP_GEi)
-
-#define XFS_BTNUM_BNO ((xfs_btnum_t)XFS_BTNUM_BNOi)
-#define XFS_BTNUM_CNT ((xfs_btnum_t)XFS_BTNUM_CNTi)
-#define XFS_BTNUM_BMAP ((xfs_btnum_t)XFS_BTNUM_BMAPi)
-#define XFS_BTNUM_INO ((xfs_btnum_t)XFS_BTNUM_INOi)
-
-/*
- * Short form header: space allocation btrees.
- */
-typedef struct xfs_btree_sblock {
- __be32 bb_magic; /* magic number for block type */
- __be16 bb_level; /* 0 is a leaf */
- __be16 bb_numrecs; /* current # of data records */
- __be32 bb_leftsib; /* left sibling block or NULLAGBLOCK */
- __be32 bb_rightsib; /* right sibling block or NULLAGBLOCK */
-} xfs_btree_sblock_t;
-
-/*
- * Long form header: bmap btrees.
- */
-typedef struct xfs_btree_lblock {
- __be32 bb_magic; /* magic number for block type */
- __be16 bb_level; /* 0 is a leaf */
- __be16 bb_numrecs; /* current # of data records */
- __be64 bb_leftsib; /* left sibling block or NULLDFSBNO */
- __be64 bb_rightsib; /* right sibling block or NULLDFSBNO */
-} xfs_btree_lblock_t;
-
-/*
- * Combined header and structure, used by common code.
- */
-typedef struct xfs_btree_hdr
-{
- __be32 bb_magic; /* magic number for block type */
- __be16 bb_level; /* 0 is a leaf */
- __be16 bb_numrecs; /* current # of data records */
-} xfs_btree_hdr_t;
-
-typedef struct xfs_btree_block {
- xfs_btree_hdr_t bb_h; /* header */
- union {
- struct {
- __be32 bb_leftsib;
- __be32 bb_rightsib;
- } s; /* short form pointers */
- struct {
- __be64 bb_leftsib;
- __be64 bb_rightsib;
- } l; /* long form pointers */
- } bb_u; /* rest */
-} xfs_btree_block_t;
-
-/*
- * For logging record fields.
- */
-#define XFS_BB_MAGIC 0x01
-#define XFS_BB_LEVEL 0x02
-#define XFS_BB_NUMRECS 0x04
-#define XFS_BB_LEFTSIB 0x08
-#define XFS_BB_RIGHTSIB 0x10
-#define XFS_BB_NUM_BITS 5
-#define XFS_BB_ALL_BITS ((1 << XFS_BB_NUM_BITS) - 1)
-
-/*
- * Boolean to select which form of xfs_btree_block_t.bb_u to use.
- */
-#define XFS_BTREE_LONG_PTRS(btnum) ((btnum) == XFS_BTNUM_BMAP)
-
-/*
- * Magic numbers for btree blocks.
- */
-extern const __uint32_t xfs_magics[];
-
-/*
- * Maximum and minimum records in a btree block.
- * Given block size, type prefix, and leaf flag (0 or 1).
- * The divisor below is equivalent to lf ? (e1) : (e2) but that produces
- * compiler warnings.
- */
-#define XFS_BTREE_BLOCK_MAXRECS(bsz,t,lf) \
- ((int)(((bsz) - (uint)sizeof(t ## _block_t)) / \
- (((lf) * (uint)sizeof(t ## _rec_t)) + \
- ((1 - (lf)) * \
- ((uint)sizeof(t ## _key_t) + (uint)sizeof(t ## _ptr_t))))))
-#define XFS_BTREE_BLOCK_MINRECS(bsz,t,lf) \
- (XFS_BTREE_BLOCK_MAXRECS(bsz,t,lf) / 2)
-
-/*
- * Record, key, and pointer address calculation macros.
- * Given block size, type prefix, block pointer, and index of requested entry
- * (first entry numbered 1).
- */
-#define XFS_BTREE_REC_ADDR(bsz,t,bb,i,mxr) \
- ((t ## _rec_t *)((char *)(bb) + sizeof(t ## _block_t) + \
- ((i) - 1) * sizeof(t ## _rec_t)))
-#define XFS_BTREE_KEY_ADDR(bsz,t,bb,i,mxr) \
- ((t ## _key_t *)((char *)(bb) + sizeof(t ## _block_t) + \
- ((i) - 1) * sizeof(t ## _key_t)))
-#define XFS_BTREE_PTR_ADDR(bsz,t,bb,i,mxr) \
- ((t ## _ptr_t *)((char *)(bb) + sizeof(t ## _block_t) + \
- (mxr) * sizeof(t ## _key_t) + ((i) - 1) * sizeof(t ## _ptr_t)))
-
-#define XFS_BTREE_MAXLEVELS 8 /* max of all btrees */
-
-/*
- * Btree cursor structure.
- * This collects all information needed by the btree code in one place.
- */
-typedef struct xfs_btree_cur
-{
- struct xfs_trans *bc_tp; /* transaction we're in, if any */
- struct xfs_mount *bc_mp; /* file system mount struct */
- union {
- xfs_alloc_rec_incore_t a;
- xfs_bmbt_irec_t b;
- xfs_inobt_rec_t i;
- } bc_rec; /* current insert/search record value */
- struct xfs_buf *bc_bufs[XFS_BTREE_MAXLEVELS]; /* buf ptr per level */
- int bc_ptrs[XFS_BTREE_MAXLEVELS]; /* key/record # */
- __uint8_t bc_ra[XFS_BTREE_MAXLEVELS]; /* readahead bits */
-#define XFS_BTCUR_LEFTRA 1 /* left sibling has been read-ahead */
-#define XFS_BTCUR_RIGHTRA 2 /* right sibling has been read-ahead */
- __uint8_t bc_nlevels; /* number of levels in the tree */
- __uint8_t bc_blocklog; /* log2(blocksize) of btree blocks */
- xfs_btnum_t bc_btnum; /* identifies which btree type */
- union {
- struct { /* needed for BNO, CNT */
- struct xfs_buf *agbp; /* agf buffer pointer */
- xfs_agnumber_t agno; /* ag number */
- } a;
- struct { /* needed for BMAP */
- struct xfs_inode *ip; /* pointer to our inode */
- struct xfs_bmap_free *flist; /* list to free after */
- xfs_fsblock_t firstblock; /* 1st blk allocated */
- int allocated; /* count of alloced */
- short forksize; /* fork's inode space */
- char whichfork; /* data or attr fork */
- char flags; /* flags */
-#define XFS_BTCUR_BPRV_WASDEL 1 /* was delayed */
- } b;
- struct { /* needed for INO */
- struct xfs_buf *agbp; /* agi buffer pointer */
- xfs_agnumber_t agno; /* ag number */
- } i;
- } bc_private; /* per-btree type data */
-} xfs_btree_cur_t;
-
-#define XFS_BTREE_NOERROR 0
-#define XFS_BTREE_ERROR 1
-
-/*
- * Convert from buffer to btree block header.
- */
-#define XFS_BUF_TO_BLOCK(bp) ((xfs_btree_block_t *)XFS_BUF_PTR(bp))
-#define XFS_BUF_TO_LBLOCK(bp) ((xfs_btree_lblock_t *)XFS_BUF_PTR(bp))
-#define XFS_BUF_TO_SBLOCK(bp) ((xfs_btree_sblock_t *)XFS_BUF_PTR(bp))
-
-
-#ifdef __KERNEL__
-
-#ifdef DEBUG
-/*
- * Debug routine: check that block header is ok.
- */
-void
-xfs_btree_check_block(
- xfs_btree_cur_t *cur, /* btree cursor */
- xfs_btree_block_t *block, /* generic btree block pointer */
- int level, /* level of the btree block */
- struct xfs_buf *bp); /* buffer containing block, if any */
-
-/*
- * Debug routine: check that keys are in the right order.
- */
-void
-xfs_btree_check_key(
- xfs_btnum_t btnum, /* btree identifier */
- void *ak1, /* pointer to left (lower) key */
- void *ak2); /* pointer to right (higher) key */
-
-/*
- * Debug routine: check that records are in the right order.
- */
-void
-xfs_btree_check_rec(
- xfs_btnum_t btnum, /* btree identifier */
- void *ar1, /* pointer to left (lower) record */
- void *ar2); /* pointer to right (higher) record */
-#else
-#define xfs_btree_check_block(a,b,c,d)
-#define xfs_btree_check_key(a,b,c)
-#define xfs_btree_check_rec(a,b,c)
-#endif /* DEBUG */
-
-/*
- * Checking routine: check that long form block header is ok.
- */
-int /* error (0 or EFSCORRUPTED) */
-xfs_btree_check_lblock(
- xfs_btree_cur_t *cur, /* btree cursor */
- xfs_btree_lblock_t *block, /* btree long form block pointer */
- int level, /* level of the btree block */
- struct xfs_buf *bp); /* buffer containing block, if any */
-
-/*
- * Checking routine: check that (long) pointer is ok.
- */
-int /* error (0 or EFSCORRUPTED) */
-xfs_btree_check_lptr(
- xfs_btree_cur_t *cur, /* btree cursor */
- xfs_dfsbno_t ptr, /* btree block disk address */
- int level); /* btree block level */
-
-/*
- * Checking routine: check that short form block header is ok.
- */
-int /* error (0 or EFSCORRUPTED) */
-xfs_btree_check_sblock(
- xfs_btree_cur_t *cur, /* btree cursor */
- xfs_btree_sblock_t *block, /* btree short form block pointer */
- int level, /* level of the btree block */
- struct xfs_buf *bp); /* buffer containing block */
-
-/*
- * Checking routine: check that (short) pointer is ok.
- */
-int /* error (0 or EFSCORRUPTED) */
-xfs_btree_check_sptr(
- xfs_btree_cur_t *cur, /* btree cursor */
- xfs_agblock_t ptr, /* btree block disk address */
- int level); /* btree block level */
-
-/*
- * Delete the btree cursor.
- */
-void
-xfs_btree_del_cursor(
- xfs_btree_cur_t *cur, /* btree cursor */
- int error); /* del because of error */
-
-/*
- * Duplicate the btree cursor.
- * Allocate a new one, copy the record, re-get the buffers.
- */
-int /* error */
-xfs_btree_dup_cursor(
- xfs_btree_cur_t *cur, /* input cursor */
- xfs_btree_cur_t **ncur);/* output cursor */
-
-/*
- * Change the cursor to point to the first record in the current block
- * at the given level. Other levels are unaffected.
- */
-int /* success=1, failure=0 */
-xfs_btree_firstrec(
- xfs_btree_cur_t *cur, /* btree cursor */
- int level); /* level to change */
-
-/*
- * Get a buffer for the block, return it with no data read.
- * Long-form addressing.
- */
-struct xfs_buf * /* buffer for fsbno */
-xfs_btree_get_bufl(
- struct xfs_mount *mp, /* file system mount point */
- struct xfs_trans *tp, /* transaction pointer */
- xfs_fsblock_t fsbno, /* file system block number */
- uint lock); /* lock flags for get_buf */
-
-/*
- * Get a buffer for the block, return it with no data read.
- * Short-form addressing.
- */
-struct xfs_buf * /* buffer for agno/agbno */
-xfs_btree_get_bufs(
- struct xfs_mount *mp, /* file system mount point */
- struct xfs_trans *tp, /* transaction pointer */
- xfs_agnumber_t agno, /* allocation group number */
- xfs_agblock_t agbno, /* allocation group block number */
- uint lock); /* lock flags for get_buf */
-
-/*
- * Allocate a new btree cursor.
- * The cursor is either for allocation (A) or bmap (B).
- */
-xfs_btree_cur_t * /* new btree cursor */
-xfs_btree_init_cursor(
- struct xfs_mount *mp, /* file system mount point */
- struct xfs_trans *tp, /* transaction pointer */
- struct xfs_buf *agbp, /* (A only) buffer for agf structure */
- xfs_agnumber_t agno, /* (A only) allocation group number */
- xfs_btnum_t btnum, /* btree identifier */
- struct xfs_inode *ip, /* (B only) inode owning the btree */
- int whichfork); /* (B only) data/attr fork */
-
-/*
- * Check for the cursor referring to the last block at the given level.
- */
-int /* 1=is last block, 0=not last block */
-xfs_btree_islastblock(
- xfs_btree_cur_t *cur, /* btree cursor */
- int level); /* level to check */
-
-/*
- * Change the cursor to point to the last record in the current block
- * at the given level. Other levels are unaffected.
- */
-int /* success=1, failure=0 */
-xfs_btree_lastrec(
- xfs_btree_cur_t *cur, /* btree cursor */
- int level); /* level to change */
-
-/*
- * Compute first and last byte offsets for the fields given.
- * Interprets the offsets table, which contains struct field offsets.
- */
-void
-xfs_btree_offsets(
- __int64_t fields, /* bitmask of fields */
- const short *offsets,/* table of field offsets */
- int nbits, /* number of bits to inspect */
- int *first, /* output: first byte offset */
- int *last); /* output: last byte offset */
-
-/*
- * Get a buffer for the block, return it read in.
- * Long-form addressing.
- */
-int /* error */
-xfs_btree_read_bufl(
- struct xfs_mount *mp, /* file system mount point */
- struct xfs_trans *tp, /* transaction pointer */
- xfs_fsblock_t fsbno, /* file system block number */
- uint lock, /* lock flags for read_buf */
- struct xfs_buf **bpp, /* buffer for fsbno */
- int refval);/* ref count value for buffer */
-
-/*
- * Get a buffer for the block, return it read in.
- * Short-form addressing.
- */
-int /* error */
-xfs_btree_read_bufs(
- struct xfs_mount *mp, /* file system mount point */
- struct xfs_trans *tp, /* transaction pointer */
- xfs_agnumber_t agno, /* allocation group number */
- xfs_agblock_t agbno, /* allocation group block number */
- uint lock, /* lock flags for read_buf */
- struct xfs_buf **bpp, /* buffer for agno/agbno */
- int refval);/* ref count value for buffer */
-
-/*
- * Read-ahead the block, don't wait for it, don't return a buffer.
- * Long-form addressing.
- */
-void /* error */
-xfs_btree_reada_bufl(
- struct xfs_mount *mp, /* file system mount point */
- xfs_fsblock_t fsbno, /* file system block number */
- xfs_extlen_t count); /* count of filesystem blocks */
-
-/*
- * Read-ahead the block, don't wait for it, don't return a buffer.
- * Short-form addressing.
- */
-void /* error */
-xfs_btree_reada_bufs(
- struct xfs_mount *mp, /* file system mount point */
- xfs_agnumber_t agno, /* allocation group number */
- xfs_agblock_t agbno, /* allocation group block number */
- xfs_extlen_t count); /* count of filesystem blocks */
-
-/*
- * Read-ahead btree blocks, at the given level.
- * Bits in lr are set from XFS_BTCUR_{LEFT,RIGHT}RA.
- */
-int /* readahead block count */
-xfs_btree_readahead_core(
- xfs_btree_cur_t *cur, /* btree cursor */
- int lev, /* level in btree */
- int lr); /* left/right bits */
-
-static inline int /* readahead block count */
-xfs_btree_readahead(
- xfs_btree_cur_t *cur, /* btree cursor */
- int lev, /* level in btree */
- int lr) /* left/right bits */
-{
- if ((cur->bc_ra[lev] | lr) == cur->bc_ra[lev])
- return 0;
-
- return xfs_btree_readahead_core(cur, lev, lr);
-}
-
-
-/*
- * Set the buffer for level "lev" in the cursor to bp, releasing
- * any previous buffer.
- */
-void
-xfs_btree_setbuf(
- xfs_btree_cur_t *cur, /* btree cursor */
- int lev, /* level in btree */
- struct xfs_buf *bp); /* new buffer to set */
-
-#endif /* __KERNEL__ */
-
-
-/*
- * Min and max functions for extlen, agblock, fileoff, and filblks types.
- */
-#define XFS_EXTLEN_MIN(a,b) \
- ((xfs_extlen_t)(a) < (xfs_extlen_t)(b) ? \
- (xfs_extlen_t)(a) : (xfs_extlen_t)(b))
-#define XFS_EXTLEN_MAX(a,b) \
- ((xfs_extlen_t)(a) > (xfs_extlen_t)(b) ? \
- (xfs_extlen_t)(a) : (xfs_extlen_t)(b))
-#define XFS_AGBLOCK_MIN(a,b) \
- ((xfs_agblock_t)(a) < (xfs_agblock_t)(b) ? \
- (xfs_agblock_t)(a) : (xfs_agblock_t)(b))
-#define XFS_AGBLOCK_MAX(a,b) \
- ((xfs_agblock_t)(a) > (xfs_agblock_t)(b) ? \
- (xfs_agblock_t)(a) : (xfs_agblock_t)(b))
-#define XFS_FILEOFF_MIN(a,b) \
- ((xfs_fileoff_t)(a) < (xfs_fileoff_t)(b) ? \
- (xfs_fileoff_t)(a) : (xfs_fileoff_t)(b))
-#define XFS_FILEOFF_MAX(a,b) \
- ((xfs_fileoff_t)(a) > (xfs_fileoff_t)(b) ? \
- (xfs_fileoff_t)(a) : (xfs_fileoff_t)(b))
-#define XFS_FILBLKS_MIN(a,b) \
- ((xfs_filblks_t)(a) < (xfs_filblks_t)(b) ? \
- (xfs_filblks_t)(a) : (xfs_filblks_t)(b))
-#define XFS_FILBLKS_MAX(a,b) \
- ((xfs_filblks_t)(a) > (xfs_filblks_t)(b) ? \
- (xfs_filblks_t)(a) : (xfs_filblks_t)(b))
-
-#define XFS_FSB_SANITY_CHECK(mp,fsb) \
- (XFS_FSB_TO_AGNO(mp, fsb) < mp->m_sb.sb_agcount && \
- XFS_FSB_TO_AGBNO(mp, fsb) < mp->m_sb.sb_agblocks)
-
-#endif /* __XFS_BTREE_H__ */
diff --git a/sys/gnu/fs/xfs/xfs_buf_item.c b/sys/gnu/fs/xfs/xfs_buf_item.c
deleted file mode 100644
index 725057f..0000000
--- a/sys/gnu/fs/xfs/xfs_buf_item.c
+++ /dev/null
@@ -1,1203 +0,0 @@
-/*
- * Copyright (c) 2000-2005 Silicon Graphics, Inc.
- * All Rights Reserved.
- *
- * 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.
- *
- * This program is distributed in the hope that it would 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 the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- */
-#include "xfs.h"
-#include "xfs_fs.h"
-#include "xfs_types.h"
-#include "xfs_bit.h"
-#include "xfs_log.h"
-#include "xfs_inum.h"
-#include "xfs_trans.h"
-#include "xfs_sb.h"
-#include "xfs_dir.h"
-#include "xfs_dmapi.h"
-#include "xfs_mount.h"
-#include "xfs_buf_item.h"
-#include "xfs_trans_priv.h"
-#include "xfs_error.h"
-
-
-kmem_zone_t *xfs_buf_item_zone;
-
-#ifdef XFS_TRANS_DEBUG
-/*
- * This function uses an alternate strategy for tracking the bytes
- * that the user requests to be logged. This can then be used
- * in conjunction with the bli_orig array in the buf log item to
- * catch bugs in our callers' code.
- *
- * We also double check the bits set in xfs_buf_item_log using a
- * simple algorithm to check that every byte is accounted for.
- */
-STATIC void
-xfs_buf_item_log_debug(
- xfs_buf_log_item_t *bip,
- uint first,
- uint last)
-{
- uint x;
- uint byte;
- uint nbytes;
- uint chunk_num;
- uint word_num;
- uint bit_num;
- uint bit_set;
- uint *wordp;
-
- ASSERT(bip->bli_logged != NULL);
- byte = first;
- nbytes = last - first + 1;
- bfset(bip->bli_logged, first, nbytes);
- for (x = 0; x < nbytes; x++) {
- chunk_num = byte >> XFS_BLI_SHIFT;
- word_num = chunk_num >> BIT_TO_WORD_SHIFT;
- bit_num = chunk_num & (NBWORD - 1);
- wordp = &(bip->bli_format.blf_data_map[word_num]);
- bit_set = *wordp & (1 << bit_num);
- ASSERT(bit_set);
- byte++;
- }
-}
-
-/*
- * This function is called when we flush something into a buffer without
- * logging it. This happens for things like inodes which are logged
- * separately from the buffer.
- */
-void
-xfs_buf_item_flush_log_debug(
- xfs_buf_t *bp,
- uint first,
- uint last)
-{
- xfs_buf_log_item_t *bip;
- uint nbytes;
-
- bip = XFS_BUF_FSPRIVATE(bp, xfs_buf_log_item_t*);
- if ((bip == NULL) || (bip->bli_item.li_type != XFS_LI_BUF)) {
- return;
- }
-
- ASSERT(bip->bli_logged != NULL);
- nbytes = last - first + 1;
- bfset(bip->bli_logged, first, nbytes);
-}
-
-/*
- * This function is called to verify that our callers have logged
- * all the bytes that they changed.
- *
- * It does this by comparing the original copy of the buffer stored in
- * the buf log item's bli_orig array to the current copy of the buffer
- * and ensuring that all bytes which mismatch are set in the bli_logged
- * array of the buf log item.
- */
-STATIC void
-xfs_buf_item_log_check(
- xfs_buf_log_item_t *bip)
-{
- char *orig;
- char *buffer;
- int x;
- xfs_buf_t *bp;
-
- ASSERT(bip->bli_orig != NULL);
- ASSERT(bip->bli_logged != NULL);
-
- bp = bip->bli_buf;
- ASSERT(XFS_BUF_COUNT(bp) > 0);
- ASSERT(XFS_BUF_PTR(bp) != NULL);
- orig = bip->bli_orig;
- buffer = XFS_BUF_PTR(bp);
- for (x = 0; x < XFS_BUF_COUNT(bp); x++) {
- if (orig[x] != buffer[x] && !btst(bip->bli_logged, x))
- cmn_err(CE_PANIC,
- "xfs_buf_item_log_check bip %x buffer %x orig %x index %d",
- bip, bp, orig, x);
- }
-}
-#else
-#define xfs_buf_item_log_debug(x,y,z)
-#define xfs_buf_item_log_check(x)
-#endif
-
-STATIC void xfs_buf_error_relse(xfs_buf_t *bp);
-STATIC void xfs_buf_do_callbacks(xfs_buf_t *bp, xfs_log_item_t *lip);
-
-/*
- * This returns the number of log iovecs needed to log the
- * given buf log item.
- *
- * It calculates this as 1 iovec for the buf log format structure
- * and 1 for each stretch of non-contiguous chunks to be logged.
- * Contiguous chunks are logged in a single iovec.
- *
- * If the XFS_BLI_STALE flag has been set, then log nothing.
- */
-STATIC uint
-xfs_buf_item_size(
- xfs_buf_log_item_t *bip)
-{
- uint nvecs;
- int next_bit;
- int last_bit;
- xfs_buf_t *bp;
-
- ASSERT(atomic_read(&bip->bli_refcount) > 0);
- if (bip->bli_flags & XFS_BLI_STALE) {
- /*
- * The buffer is stale, so all we need to log
- * is the buf log format structure with the
- * cancel flag in it.
- */
- xfs_buf_item_trace("SIZE STALE", bip);
- ASSERT(bip->bli_format.blf_flags & XFS_BLI_CANCEL);
- return 1;
- }
-
- bp = bip->bli_buf;
- ASSERT(bip->bli_flags & XFS_BLI_LOGGED);
- nvecs = 1;
- last_bit = xfs_next_bit(bip->bli_format.blf_data_map,
- bip->bli_format.blf_map_size, 0);
- ASSERT(last_bit != -1);
- nvecs++;
- while (last_bit != -1) {
- /*
- * This takes the bit number to start looking from and
- * returns the next set bit from there. It returns -1
- * if there are no more bits set or the start bit is
- * beyond the end of the bitmap.
- */
- next_bit = xfs_next_bit(bip->bli_format.blf_data_map,
- bip->bli_format.blf_map_size,
- last_bit + 1);
- /*
- * If we run out of bits, leave the loop,
- * else if we find a new set of bits bump the number of vecs,
- * else keep scanning the current set of bits.
- */
- if (next_bit == -1) {
- last_bit = -1;
- } else if (next_bit != last_bit + 1) {
- last_bit = next_bit;
- nvecs++;
- } else if (xfs_buf_offset(bp, next_bit * XFS_BLI_CHUNK) !=
- (xfs_buf_offset(bp, last_bit * XFS_BLI_CHUNK) +
- XFS_BLI_CHUNK)) {
- last_bit = next_bit;
- nvecs++;
- } else {
- last_bit++;
- }
- }
-
- xfs_buf_item_trace("SIZE NORM", bip);
- return nvecs;
-}
-
-/*
- * This is called to fill in the vector of log iovecs for the
- * given log buf item. It fills the first entry with a buf log
- * format structure, and the rest point to contiguous chunks
- * within the buffer.
- */
-STATIC void
-xfs_buf_item_format(
- xfs_buf_log_item_t *bip,
- xfs_log_iovec_t *log_vector)
-{
- uint base_size;
- uint nvecs;
- xfs_log_iovec_t *vecp;
- xfs_buf_t *bp;
- int first_bit;
- int last_bit;
- int next_bit;
- uint nbits;
- uint buffer_offset;
-
- ASSERT(atomic_read(&bip->bli_refcount) > 0);
- ASSERT((bip->bli_flags & XFS_BLI_LOGGED) ||
- (bip->bli_flags & XFS_BLI_STALE));
- bp = bip->bli_buf;
- ASSERT(XFS_BUF_BP_ISMAPPED(bp));
- vecp = log_vector;
-
- /*
- * The size of the base structure is the size of the
- * declared structure plus the space for the extra words
- * of the bitmap. We subtract one from the map size, because
- * the first element of the bitmap is accounted for in the
- * size of the base structure.
- */
- base_size =
- (uint)(sizeof(xfs_buf_log_format_t) +
- ((bip->bli_format.blf_map_size - 1) * sizeof(uint)));
- vecp->i_addr = (xfs_caddr_t)&bip->bli_format;
- vecp->i_len = base_size;
- XLOG_VEC_SET_TYPE(vecp, XLOG_REG_TYPE_BFORMAT);
- vecp++;
- nvecs = 1;
-
- if (bip->bli_flags & XFS_BLI_STALE) {
- /*
- * The buffer is stale, so all we need to log
- * is the buf log format structure with the
- * cancel flag in it.
- */
- xfs_buf_item_trace("FORMAT STALE", bip);
- ASSERT(bip->bli_format.blf_flags & XFS_BLI_CANCEL);
- bip->bli_format.blf_size = nvecs;
- return;
- }
-
- /*
- * Fill in an iovec for each set of contiguous chunks.
- */
- first_bit = xfs_next_bit(bip->bli_format.blf_data_map,
- bip->bli_format.blf_map_size, 0);
- ASSERT(first_bit != -1);
- last_bit = first_bit;
- nbits = 1;
- for (;;) {
- /*
- * This takes the bit number to start looking from and
- * returns the next set bit from there. It returns -1
- * if there are no more bits set or the start bit is
- * beyond the end of the bitmap.
- */
- next_bit = xfs_next_bit(bip->bli_format.blf_data_map,
- bip->bli_format.blf_map_size,
- (uint)last_bit + 1);
- /*
- * If we run out of bits fill in the last iovec and get
- * out of the loop.
- * Else if we start a new set of bits then fill in the
- * iovec for the series we were looking at and start
- * counting the bits in the new one.
- * Else we're still in the same set of bits so just
- * keep counting and scanning.
- */
- if (next_bit == -1) {
- buffer_offset = first_bit * XFS_BLI_CHUNK;
- vecp->i_addr = xfs_buf_offset(bp, buffer_offset);
- vecp->i_len = nbits * XFS_BLI_CHUNK;
- XLOG_VEC_SET_TYPE(vecp, XLOG_REG_TYPE_BCHUNK);
- nvecs++;
- break;
- } else if (next_bit != last_bit + 1) {
- buffer_offset = first_bit * XFS_BLI_CHUNK;
- vecp->i_addr = xfs_buf_offset(bp, buffer_offset);
- vecp->i_len = nbits * XFS_BLI_CHUNK;
- XLOG_VEC_SET_TYPE(vecp, XLOG_REG_TYPE_BCHUNK);
- nvecs++;
- vecp++;
- first_bit = next_bit;
- last_bit = next_bit;
- nbits = 1;
- } else if (xfs_buf_offset(bp, next_bit << XFS_BLI_SHIFT) !=
- (xfs_buf_offset(bp, last_bit << XFS_BLI_SHIFT) +
- XFS_BLI_CHUNK)) {
- buffer_offset = first_bit * XFS_BLI_CHUNK;
- vecp->i_addr = xfs_buf_offset(bp, buffer_offset);
- vecp->i_len = nbits * XFS_BLI_CHUNK;
- XLOG_VEC_SET_TYPE(vecp, XLOG_REG_TYPE_BCHUNK);
-/* You would think we need to bump the nvecs here too, but we do not
- * this number is used by recovery, and it gets confused by the boundary
- * split here
- * nvecs++;
- */
- vecp++;
- first_bit = next_bit;
- last_bit = next_bit;
- nbits = 1;
- } else {
- last_bit++;
- nbits++;
- }
- }
- bip->bli_format.blf_size = nvecs;
-
- /*
- * Check to make sure everything is consistent.
- */
- xfs_buf_item_trace("FORMAT NORM", bip);
- xfs_buf_item_log_check(bip);
-}
-
-/*
- * This is called to pin the buffer associated with the buf log
- * item in memory so it cannot be written out. Simply call bpin()
- * on the buffer to do this.
- */
-STATIC void
-xfs_buf_item_pin(
- xfs_buf_log_item_t *bip)
-{
- xfs_buf_t *bp;
-
- bp = bip->bli_buf;
- ASSERT(XFS_BUF_ISBUSY(bp));
- ASSERT(atomic_read(&bip->bli_refcount) > 0);
- ASSERT((bip->bli_flags & XFS_BLI_LOGGED) ||
- (bip->bli_flags & XFS_BLI_STALE));
- xfs_buf_item_trace("PIN", bip);
- xfs_buftrace("XFS_PIN", bp);
- xfs_bpin(bp);
-}
-
-
-/*
- * This is called to unpin the buffer associated with the buf log
- * item which was previously pinned with a call to xfs_buf_item_pin().
- * Just call bunpin() on the buffer to do this.
- *
- * Also drop the reference to the buf item for the current transaction.
- * If the XFS_BLI_STALE flag is set and we are the last reference,
- * then free up the buf log item and unlock the buffer.
- */
-STATIC void
-xfs_buf_item_unpin(
- xfs_buf_log_item_t *bip,
- int stale)
-{
- xfs_mount_t *mp;
- xfs_buf_t *bp;
- int freed;
- SPLDECL(s);
-
- bp = bip->bli_buf;
- ASSERT(bp != NULL);
- ASSERT(XFS_BUF_FSPRIVATE(bp, xfs_buf_log_item_t *) == bip);
- ASSERT(atomic_read(&bip->bli_refcount) > 0);
- xfs_buf_item_trace("UNPIN", bip);
- xfs_buftrace("XFS_UNPIN", bp);
-
- freed = atomic_dec_and_test(&bip->bli_refcount);
- mp = bip->bli_item.li_mountp;
- xfs_bunpin(bp);
- if (freed && stale) {
- ASSERT(bip->bli_flags & XFS_BLI_STALE);
- ASSERT(XFS_BUF_VALUSEMA(bp) <= 0);
- ASSERT(!(XFS_BUF_ISDELAYWRITE(bp)));
- ASSERT(XFS_BUF_ISSTALE(bp));
- ASSERT(bip->bli_format.blf_flags & XFS_BLI_CANCEL);
- xfs_buf_item_trace("UNPIN STALE", bip);
- xfs_buftrace("XFS_UNPIN STALE", bp);
- /*
- * If we get called here because of an IO error, we may
- * or may not have the item on the AIL. xfs_trans_delete_ail()
- * will take care of that situation.
- * xfs_trans_delete_ail() drops the AIL lock.
- */
- if (bip->bli_flags & XFS_BLI_STALE_INODE) {
- xfs_buf_do_callbacks(bp, (xfs_log_item_t *)bip);
- XFS_BUF_SET_FSPRIVATE(bp, NULL);
- XFS_BUF_CLR_IODONE_FUNC(bp);
- } else {
- AIL_LOCK(mp,s);
- xfs_trans_delete_ail(mp, (xfs_log_item_t *)bip, s);
- xfs_buf_item_relse(bp);
- ASSERT(XFS_BUF_FSPRIVATE(bp, void *) == NULL);
- }
- xfs_buf_relse(bp);
- }
-}
-
-/*
- * this is called from uncommit in the forced-shutdown path.
- * we need to check to see if the reference count on the log item
- * is going to drop to zero. If so, unpin will free the log item
- * so we need to free the item's descriptor (that points to the item)
- * in the transaction.
- */
-STATIC void
-xfs_buf_item_unpin_remove(
- xfs_buf_log_item_t *bip,
- xfs_trans_t *tp)
-{
- xfs_buf_t *bp;
- xfs_log_item_desc_t *lidp;
- int stale = 0;
-
- bp = bip->bli_buf;
- /*
- * will xfs_buf_item_unpin() call xfs_buf_item_relse()?
- */
- if ((atomic_read(&bip->bli_refcount) == 1) &&
- (bip->bli_flags & XFS_BLI_STALE)) {
- ASSERT(XFS_BUF_VALUSEMA(bip->bli_buf) <= 0);
- xfs_buf_item_trace("UNPIN REMOVE", bip);
- xfs_buftrace("XFS_UNPIN_REMOVE", bp);
- /*
- * yes -- clear the xaction descriptor in-use flag
- * and free the chunk if required. We can safely
- * do some work here and then call buf_item_unpin
- * to do the rest because if the if is true, then
- * we are holding the buffer locked so no one else
- * will be able to bump up the refcount.
- */
- lidp = xfs_trans_find_item(tp, (xfs_log_item_t *) bip);
- stale = lidp->lid_flags & XFS_LID_BUF_STALE;
- xfs_trans_free_item(tp, lidp);
- /*
- * Since the transaction no longer refers to the buffer,
- * the buffer should no longer refer to the transaction.
- */
- XFS_BUF_SET_FSPRIVATE2(bp, NULL);
- }
-
- xfs_buf_item_unpin(bip, stale);
-
- return;
-}
-
-/*
- * This is called to attempt to lock the buffer associated with this
- * buf log item. Don't sleep on the buffer lock. If we can't get
- * the lock right away, return 0. If we can get the lock, pull the
- * buffer from the free list, mark it busy, and return 1.
- */
-STATIC uint
-xfs_buf_item_trylock(
- xfs_buf_log_item_t *bip)
-{
- xfs_buf_t *bp;
-
- bp = bip->bli_buf;
-
- if (XFS_BUF_ISPINNED(bp)) {
- return XFS_ITEM_PINNED;
- }
-
- if (!XFS_BUF_CPSEMA(bp)) {
- return XFS_ITEM_LOCKED;
- }
-
- /*
- * Remove the buffer from the free list. Only do this
- * if it's on the free list. Private buffers like the
- * superblock buffer are not.
- */
- XFS_BUF_HOLD(bp);
-
- ASSERT(!(bip->bli_flags & XFS_BLI_STALE));
- xfs_buf_item_trace("TRYLOCK SUCCESS", bip);
- return XFS_ITEM_SUCCESS;
-}
-
-/*
- * Release the buffer associated with the buf log item.
- * If there is no dirty logged data associated with the
- * buffer recorded in the buf log item, then free the
- * buf log item and remove the reference to it in the
- * buffer.
- *
- * This call ignores the recursion count. It is only called
- * when the buffer should REALLY be unlocked, regardless
- * of the recursion count.
- *
- * If the XFS_BLI_HOLD flag is set in the buf log item, then
- * free the log item if necessary but do not unlock the buffer.
- * This is for support of xfs_trans_bhold(). Make sure the
- * XFS_BLI_HOLD field is cleared if we don't free the item.
- */
-STATIC void
-xfs_buf_item_unlock(
- xfs_buf_log_item_t *bip)
-{
- int aborted;
- xfs_buf_t *bp;
- uint hold;
-
- bp = bip->bli_buf;
- xfs_buftrace("XFS_UNLOCK", bp);
-
- /*
- * Clear the buffer's association with this transaction.
- */
- XFS_BUF_SET_FSPRIVATE2(bp, NULL);
-
- /*
- * If this is a transaction abort, don't return early.
- * Instead, allow the brelse to happen.
- * Normally it would be done for stale (cancelled) buffers
- * at unpin time, but we'll never go through the pin/unpin
- * cycle if we abort inside commit.
- */
- aborted = (bip->bli_item.li_flags & XFS_LI_ABORTED) != 0;
-
- /*
- * If the buf item is marked stale, then don't do anything.
- * We'll unlock the buffer and free the buf item when the
- * buffer is unpinned for the last time.
- */
- if (bip->bli_flags & XFS_BLI_STALE) {
- bip->bli_flags &= ~XFS_BLI_LOGGED;
- xfs_buf_item_trace("UNLOCK STALE", bip);
- ASSERT(bip->bli_format.blf_flags & XFS_BLI_CANCEL);
- if (!aborted)
- return;
- }
-
- /*
- * Drop the transaction's reference to the log item if
- * it was not logged as part of the transaction. Otherwise
- * we'll drop the reference in xfs_buf_item_unpin() when
- * the transaction is really through with the buffer.
- */
- if (!(bip->bli_flags & XFS_BLI_LOGGED)) {
- atomic_dec(&bip->bli_refcount);
- } else {
- /*
- * Clear the logged flag since this is per
- * transaction state.
- */
- bip->bli_flags &= ~XFS_BLI_LOGGED;
- }
-
- /*
- * Before possibly freeing the buf item, determine if we should
- * release the buffer at the end of this routine.
- */
- hold = bip->bli_flags & XFS_BLI_HOLD;
- xfs_buf_item_trace("UNLOCK", bip);
-
- /*
- * If the buf item isn't tracking any data, free it.
- * Otherwise, if XFS_BLI_HOLD is set clear it.
- */
- if (xfs_count_bits(bip->bli_format.blf_data_map,
- bip->bli_format.blf_map_size, 0) == 0) {
- xfs_buf_item_relse(bp);
- } else if (hold) {
- bip->bli_flags &= ~XFS_BLI_HOLD;
- }
-
- /*
- * Release the buffer if XFS_BLI_HOLD was not set.
- */
- if (!hold) {
- xfs_buf_relse(bp);
- }
-}
-
-/*
- * This is called to find out where the oldest active copy of the
- * buf log item in the on disk log resides now that the last log
- * write of it completed at the given lsn.
- * We always re-log all the dirty data in a buffer, so usually the
- * latest copy in the on disk log is the only one that matters. For
- * those cases we simply return the given lsn.
- *
- * The one exception to this is for buffers full of newly allocated
- * inodes. These buffers are only relogged with the XFS_BLI_INODE_BUF
- * flag set, indicating that only the di_next_unlinked fields from the
- * inodes in the buffers will be replayed during recovery. If the
- * original newly allocated inode images have not yet been flushed
- * when the buffer is so relogged, then we need to make sure that we
- * keep the old images in the 'active' portion of the log. We do this
- * by returning the original lsn of that transaction here rather than
- * the current one.
- */
-STATIC xfs_lsn_t
-xfs_buf_item_committed(
- xfs_buf_log_item_t *bip,
- xfs_lsn_t lsn)
-{
- xfs_buf_item_trace("COMMITTED", bip);
- if ((bip->bli_flags & XFS_BLI_INODE_ALLOC_BUF) &&
- (bip->bli_item.li_lsn != 0)) {
- return bip->bli_item.li_lsn;
- }
- return (lsn);
-}
-
-/*
- * This is called when the transaction holding the buffer is aborted.
- * Just behave as if the transaction had been cancelled. If we're shutting down
- * and have aborted this transaction, we'll trap this buffer when it tries to
- * get written out.
- */
-STATIC void
-xfs_buf_item_abort(
- xfs_buf_log_item_t *bip)
-{
- xfs_buf_t *bp;
-
- bp = bip->bli_buf;
- xfs_buftrace("XFS_ABORT", bp);
- XFS_BUF_SUPER_STALE(bp);
- xfs_buf_item_unlock(bip);
- return;
-}
-
-/*
- * This is called to asynchronously write the buffer associated with this
- * buf log item out to disk. The buffer will already have been locked by
- * a successful call to xfs_buf_item_trylock(). If the buffer still has
- * B_DELWRI set, then get it going out to disk with a call to bawrite().
- * If not, then just release the buffer.
- */
-STATIC void
-xfs_buf_item_push(
- xfs_buf_log_item_t *bip)
-{
- xfs_buf_t *bp;
-
- ASSERT(!(bip->bli_flags & XFS_BLI_STALE));
- xfs_buf_item_trace("PUSH", bip);
-
- bp = bip->bli_buf;
-
- if (XFS_BUF_ISDELAYWRITE(bp)) {
- xfs_bawrite(bip->bli_item.li_mountp, bp);
- } else {
- xfs_buf_relse(bp);
- }
-}
-
-/* ARGSUSED */
-STATIC void
-xfs_buf_item_committing(xfs_buf_log_item_t *bip, xfs_lsn_t commit_lsn)
-{
-}
-
-/*
- * This is the ops vector shared by all buf log items.
- */
-STATIC struct xfs_item_ops xfs_buf_item_ops = {
- .iop_size = (uint(*)(xfs_log_item_t*))xfs_buf_item_size,
- .iop_format = (void(*)(xfs_log_item_t*, xfs_log_iovec_t*))
- xfs_buf_item_format,
- .iop_pin = (void(*)(xfs_log_item_t*))xfs_buf_item_pin,
- .iop_unpin = (void(*)(xfs_log_item_t*, int))xfs_buf_item_unpin,
- .iop_unpin_remove = (void(*)(xfs_log_item_t*, xfs_trans_t *))
- xfs_buf_item_unpin_remove,
- .iop_trylock = (uint(*)(xfs_log_item_t*))xfs_buf_item_trylock,
- .iop_unlock = (void(*)(xfs_log_item_t*))xfs_buf_item_unlock,
- .iop_committed = (xfs_lsn_t(*)(xfs_log_item_t*, xfs_lsn_t))
- xfs_buf_item_committed,
- .iop_push = (void(*)(xfs_log_item_t*))xfs_buf_item_push,
- .iop_abort = (void(*)(xfs_log_item_t*))xfs_buf_item_abort,
- .iop_pushbuf = NULL,
- .iop_committing = (void(*)(xfs_log_item_t*, xfs_lsn_t))
- xfs_buf_item_committing
-};
-
-
-/*
- * Allocate a new buf log item to go with the given buffer.
- * Set the buffer's b_fsprivate field to point to the new
- * buf log item. If there are other item's attached to the
- * buffer (see xfs_buf_attach_iodone() below), then put the
- * buf log item at the front.
- */
-void
-xfs_buf_item_init(
- xfs_buf_t *bp,
- xfs_mount_t *mp)
-{
- xfs_log_item_t *lip;
- xfs_buf_log_item_t *bip;
- int chunks;
- int map_size;
-
- /*
- * Check to see if there is already a buf log item for
- * this buffer. If there is, it is guaranteed to be
- * the first. If we do already have one, there is
- * nothing to do here so return.
- */
- if (XFS_BUF_FSPRIVATE3(bp, xfs_mount_t *) != mp)
- XFS_BUF_SET_FSPRIVATE3(bp, mp);
- XFS_BUF_SET_BDSTRAT_FUNC(bp, xfs_bdstrat_cb);
- if (XFS_BUF_FSPRIVATE(bp, void *) != NULL) {
- lip = XFS_BUF_FSPRIVATE(bp, xfs_log_item_t *);
- if (lip->li_type == XFS_LI_BUF) {
- return;
- }
- }
-
- /*
- * chunks is the number of XFS_BLI_CHUNK size pieces
- * the buffer can be divided into. Make sure not to
- * truncate any pieces. map_size is the size of the
- * bitmap needed to describe the chunks of the buffer.
- */
- chunks = (int)((XFS_BUF_COUNT(bp) + (XFS_BLI_CHUNK - 1)) >> XFS_BLI_SHIFT);
- map_size = (int)((chunks + NBWORD) >> BIT_TO_WORD_SHIFT);
-
- bip = (xfs_buf_log_item_t*)kmem_zone_zalloc(xfs_buf_item_zone,
- KM_SLEEP);
- bip->bli_item.li_type = XFS_LI_BUF;
- bip->bli_item.li_ops = &xfs_buf_item_ops;
- bip->bli_item.li_mountp = mp;
- bip->bli_buf = bp;
- bip->bli_format.blf_type = XFS_LI_BUF;
- bip->bli_format.blf_blkno = (__int64_t)XFS_BUF_ADDR(bp);
- bip->bli_format.blf_len = (ushort)BTOBB(XFS_BUF_COUNT(bp));
- bip->bli_format.blf_map_size = map_size;
-#ifdef XFS_BLI_TRACE
- bip->bli_trace = ktrace_alloc(XFS_BLI_TRACE_SIZE, KM_SLEEP);
-#endif
-
-#ifdef XFS_TRANS_DEBUG
- /*
- * Allocate the arrays for tracking what needs to be logged
- * and what our callers request to be logged. bli_orig
- * holds a copy of the original, clean buffer for comparison
- * against, and bli_logged keeps a 1 bit flag per byte in
- * the buffer to indicate which bytes the callers have asked
- * to have logged.
- */
- bip->bli_orig = (char *)kmem_alloc(XFS_BUF_COUNT(bp), KM_SLEEP);
- memcpy(bip->bli_orig, XFS_BUF_PTR(bp), XFS_BUF_COUNT(bp));
- bip->bli_logged = (char *)kmem_zalloc(XFS_BUF_COUNT(bp) / NBBY, KM_SLEEP);
-#endif
-
- /*
- * Put the buf item into the list of items attached to the
- * buffer at the front.
- */
- if (XFS_BUF_FSPRIVATE(bp, void *) != NULL) {
- bip->bli_item.li_bio_list =
- XFS_BUF_FSPRIVATE(bp, xfs_log_item_t *);
- }
- XFS_BUF_SET_FSPRIVATE(bp, bip);
-}
-
-
-/*
- * Mark bytes first through last inclusive as dirty in the buf
- * item's bitmap.
- */
-void
-xfs_buf_item_log(
- xfs_buf_log_item_t *bip,
- uint first,
- uint last)
-{
- uint first_bit;
- uint last_bit;
- uint bits_to_set;
- uint bits_set;
- uint word_num;
- uint *wordp;
- uint bit;
- uint end_bit;
- uint mask;
-
- /*
- * Mark the item as having some dirty data for
- * quick reference in xfs_buf_item_dirty.
- */
- bip->bli_flags |= XFS_BLI_DIRTY;
-
- /*
- * Convert byte offsets to bit numbers.
- */
- first_bit = first >> XFS_BLI_SHIFT;
- last_bit = last >> XFS_BLI_SHIFT;
-
- /*
- * Calculate the total number of bits to be set.
- */
- bits_to_set = last_bit - first_bit + 1;
-
- /*
- * Get a pointer to the first word in the bitmap
- * to set a bit in.
- */
- word_num = first_bit >> BIT_TO_WORD_SHIFT;
- wordp = &(bip->bli_format.blf_data_map[word_num]);
-
- /*
- * Calculate the starting bit in the first word.
- */
- bit = first_bit & (uint)(NBWORD - 1);
-
- /*
- * First set any bits in the first word of our range.
- * If it starts at bit 0 of the word, it will be
- * set below rather than here. That is what the variable
- * bit tells us. The variable bits_set tracks the number
- * of bits that have been set so far. End_bit is the number
- * of the last bit to be set in this word plus one.
- */
- if (bit) {
- end_bit = MIN(bit + bits_to_set, (uint)NBWORD);
- mask = ((1 << (end_bit - bit)) - 1) << bit;
- *wordp |= mask;
- wordp++;
- bits_set = end_bit - bit;
- } else {
- bits_set = 0;
- }
-
- /*
- * Now set bits a whole word at a time that are between
- * first_bit and last_bit.
- */
- while ((bits_to_set - bits_set) >= NBWORD) {
- *wordp |= 0xffffffff;
- bits_set += NBWORD;
- wordp++;
- }
-
- /*
- * Finally, set any bits left to be set in one last partial word.
- */
- end_bit = bits_to_set - bits_set;
- if (end_bit) {
- mask = (1 << end_bit) - 1;
- *wordp |= mask;
- }
-
- xfs_buf_item_log_debug(bip, first, last);
-}
-
-
-/*
- * Return 1 if the buffer has some data that has been logged (at any
- * point, not just the current transaction) and 0 if not.
- */
-uint
-xfs_buf_item_dirty(
- xfs_buf_log_item_t *bip)
-{
- return (bip->bli_flags & XFS_BLI_DIRTY);
-}
-
-/*
- * This is called when the buf log item is no longer needed. It should
- * free the buf log item associated with the given buffer and clear
- * the buffer's pointer to the buf log item. If there are no more
- * items in the list, clear the b_iodone field of the buffer (see
- * xfs_buf_attach_iodone() below).
- */
-void
-xfs_buf_item_relse(
- xfs_buf_t *bp)
-{
- xfs_buf_log_item_t *bip;
-
- xfs_buftrace("XFS_RELSE", bp);
- bip = XFS_BUF_FSPRIVATE(bp, xfs_buf_log_item_t*);
- XFS_BUF_SET_FSPRIVATE(bp, bip->bli_item.li_bio_list);
- if ((XFS_BUF_FSPRIVATE(bp, void *) == NULL) &&
- (XFS_BUF_IODONE_FUNC(bp) != NULL)) {
- ASSERT((XFS_BUF_ISUNINITIAL(bp)) == 0);
- XFS_BUF_CLR_IODONE_FUNC(bp);
- }
-
-#ifdef XFS_TRANS_DEBUG
- kmem_free(bip->bli_orig, XFS_BUF_COUNT(bp));
- bip->bli_orig = NULL;
- kmem_free(bip->bli_logged, XFS_BUF_COUNT(bp) / NBBY);
- bip->bli_logged = NULL;
-#endif /* XFS_TRANS_DEBUG */
-
-#ifdef XFS_BLI_TRACE
- ktrace_free(bip->bli_trace);
-#endif
- kmem_zone_free(xfs_buf_item_zone, bip);
-}
-
-
-/*
- * Add the given log item with its callback to the list of callbacks
- * to be called when the buffer's I/O completes. If it is not set
- * already, set the buffer's b_iodone() routine to be
- * xfs_buf_iodone_callbacks() and link the log item into the list of
- * items rooted at b_fsprivate. Items are always added as the second
- * entry in the list if there is a first, because the buf item code
- * assumes that the buf log item is first.
- */
-void
-xfs_buf_attach_iodone(
- xfs_buf_t *bp,
- void (*cb)(xfs_buf_t *, xfs_log_item_t *),
- xfs_log_item_t *lip)
-{
- xfs_log_item_t *head_lip;
-
- ASSERT(XFS_BUF_ISBUSY(bp));
- ASSERT(XFS_BUF_VALUSEMA(bp) <= 0);
-
- lip->li_cb = cb;
- if (XFS_BUF_FSPRIVATE(bp, void *) != NULL) {
- head_lip = XFS_BUF_FSPRIVATE(bp, xfs_log_item_t *);
- lip->li_bio_list = head_lip->li_bio_list;
- head_lip->li_bio_list = lip;
- } else {
- XFS_BUF_SET_FSPRIVATE(bp, lip);
- }
-
- ASSERT((XFS_BUF_IODONE_FUNC(bp) == xfs_buf_iodone_callbacks) ||
- (XFS_BUF_IODONE_FUNC(bp) == NULL));
- XFS_BUF_SET_IODONE_FUNC(bp, xfs_buf_iodone_callbacks);
-}
-
-STATIC void
-xfs_buf_do_callbacks(
- xfs_buf_t *bp,
- xfs_log_item_t *lip)
-{
- xfs_log_item_t *nlip;
-
- while (lip != NULL) {
- nlip = lip->li_bio_list;
- ASSERT(lip->li_cb != NULL);
- /*
- * Clear the next pointer so we don't have any
- * confusion if the item is added to another buf.
- * Don't touch the log item after calling its
- * callback, because it could have freed itself.
- */
- lip->li_bio_list = NULL;
- lip->li_cb(bp, lip);
- lip = nlip;
- }
-}
-
-/*
- * This is the iodone() function for buffers which have had callbacks
- * attached to them by xfs_buf_attach_iodone(). It should remove each
- * log item from the buffer's list and call the callback of each in turn.
- * When done, the buffer's fsprivate field is set to NULL and the buffer
- * is unlocked with a call to iodone().
- */
-void
-xfs_buf_iodone_callbacks(
- xfs_buf_t *bp)
-{
- xfs_log_item_t *lip;
- static ulong lasttime;
- static xfs_buftarg_t *lasttarg;
- xfs_mount_t *mp;
-
- ASSERT(XFS_BUF_FSPRIVATE(bp, void *) != NULL);
- lip = XFS_BUF_FSPRIVATE(bp, xfs_log_item_t *);
-
- if (XFS_BUF_GETERROR(bp) != 0) {
- /*
- * If we've already decided to shutdown the filesystem
- * because of IO errors, there's no point in giving this
- * a retry.
- */
- mp = lip->li_mountp;
- if (XFS_FORCED_SHUTDOWN(mp)) {
- ASSERT(XFS_BUF_TARGET(bp) == mp->m_ddev_targp);
- XFS_BUF_SUPER_STALE(bp);
- xfs_buftrace("BUF_IODONE_CB", bp);
- xfs_buf_do_callbacks(bp, lip);
- XFS_BUF_SET_FSPRIVATE(bp, NULL);
- XFS_BUF_CLR_IODONE_FUNC(bp);
-
- /*
- * XFS_SHUT flag gets set when we go thru the
- * entire buffer cache and deliberately start
- * throwing away delayed write buffers.
- * Since there's no biowait done on those,
- * we should just brelse them.
- */
- if (XFS_BUF_ISSHUT(bp)) {
- XFS_BUF_UNSHUT(bp);
- xfs_buf_relse(bp);
- } else {
- xfs_biodone(bp);
- }
-
- return;
- }
-
- if ((XFS_BUF_TARGET(bp) != lasttarg) ||
- (ticks > (lasttime + 5*HZ))) {
- lasttime = ticks;
- prdev("XFS write error in file system meta-data "
- "block 0x%jx in %s",
- XFS_BUF_TARGET(bp),
- (uintmax_t)XFS_BUF_ADDR(bp), mp->m_fsname);
- }
- lasttarg = XFS_BUF_TARGET(bp);
-
- if (XFS_BUF_ISASYNC(bp)) {
- /*
- * If the write was asynchronous then noone will be
- * looking for the error. Clear the error state
- * and write the buffer out again delayed write.
- *
- * XXXsup This is OK, so long as we catch these
- * before we start the umount; we don't want these
- * DELWRI metadata bufs to be hanging around.
- */
- XFS_BUF_ERROR(bp,0); /* errno of 0 unsets the flag */
-
- if (!(XFS_BUF_ISSTALE(bp))) {
- XFS_BUF_DELAYWRITE(bp);
- XFS_BUF_DONE(bp);
- XFS_BUF_SET_START(bp);
- }
- ASSERT(XFS_BUF_IODONE_FUNC(bp));
- xfs_buftrace("BUF_IODONE ASYNC", bp);
- xfs_buf_relse(bp);
- } else {
- /*
- * If the write of the buffer was not asynchronous,
- * then we want to make sure to return the error
- * to the caller of bwrite(). Because of this we
- * cannot clear the B_ERROR state at this point.
- * Instead we install a callback function that
- * will be called when the buffer is released, and
- * that routine will clear the error state and
- * set the buffer to be written out again after
- * some delay.
- */
- /* We actually overwrite the existing b-relse
- function at times, but we're gonna be shutting down
- anyway. */
- XFS_BUF_SET_BRELSE_FUNC(bp,xfs_buf_error_relse);
- XFS_BUF_DONE(bp);
- XFS_BUF_V_IODONESEMA(bp);
- }
- return;
- }
-#ifdef XFSERRORDEBUG
- xfs_buftrace("XFS BUFCB NOERR", bp);
-#endif
- xfs_buf_do_callbacks(bp, lip);
- XFS_BUF_SET_FSPRIVATE(bp, NULL);
- XFS_BUF_CLR_IODONE_FUNC(bp);
- xfs_biodone(bp);
-}
-
-/*
- * This is a callback routine attached to a buffer which gets an error
- * when being written out synchronously.
- */
-STATIC void
-xfs_buf_error_relse(
- xfs_buf_t *bp)
-{
- xfs_log_item_t *lip;
- xfs_mount_t *mp;
-
- lip = XFS_BUF_FSPRIVATE(bp, xfs_log_item_t *);
- mp = (xfs_mount_t *)lip->li_mountp;
- ASSERT(XFS_BUF_TARGET(bp) == mp->m_ddev_targp);
-
- XFS_BUF_STALE(bp);
- XFS_BUF_DONE(bp);
- XFS_BUF_UNDELAYWRITE(bp);
- XFS_BUF_ERROR(bp,0);
- xfs_buftrace("BUF_ERROR_RELSE", bp);
- if (! XFS_FORCED_SHUTDOWN(mp))
- xfs_force_shutdown(mp, XFS_METADATA_IO_ERROR);
- /*
- * We have to unpin the pinned buffers so do the
- * callbacks.
- */
- xfs_buf_do_callbacks(bp, lip);
- XFS_BUF_SET_FSPRIVATE(bp, NULL);
- XFS_BUF_CLR_IODONE_FUNC(bp);
- XFS_BUF_SET_BRELSE_FUNC(bp,NULL);
- xfs_buf_relse(bp);
-}
-
-
-/*
- * This is the iodone() function for buffers which have been
- * logged. It is called when they are eventually flushed out.
- * It should remove the buf item from the AIL, and free the buf item.
- * It is called by xfs_buf_iodone_callbacks() above which will take
- * care of cleaning up the buffer itself.
- */
-/* ARGSUSED */
-void
-xfs_buf_iodone(
- xfs_buf_t *bp,
- xfs_buf_log_item_t *bip)
-{
- struct xfs_mount *mp;
- SPLDECL(s);
-
- ASSERT(bip->bli_buf == bp);
-
- mp = bip->bli_item.li_mountp;
-
- /*
- * If we are forcibly shutting down, this may well be
- * off the AIL already. That's because we simulate the
- * log-committed callbacks to unpin these buffers. Or we may never
- * have put this item on AIL because of the transaction was
- * aborted forcibly. xfs_trans_delete_ail() takes care of these.
- *
- * Either way, AIL is useless if we're forcing a shutdown.
- */
- AIL_LOCK(mp,s);
- /*
- * xfs_trans_delete_ail() drops the AIL lock.
- */
- xfs_trans_delete_ail(mp, (xfs_log_item_t *)bip, s);
-
-#ifdef XFS_TRANS_DEBUG
- kmem_free(bip->bli_orig, XFS_BUF_COUNT(bp));
- bip->bli_orig = NULL;
- kmem_free(bip->bli_logged, XFS_BUF_COUNT(bp) / NBBY);
- bip->bli_logged = NULL;
-#endif /* XFS_TRANS_DEBUG */
-
-#ifdef XFS_BLI_TRACE
- ktrace_free(bip->bli_trace);
-#endif
- kmem_zone_free(xfs_buf_item_zone, bip);
-}
-
-#if defined(XFS_BLI_TRACE)
-void
-xfs_buf_item_trace(
- char *id,
- xfs_buf_log_item_t *bip)
-{
- xfs_buf_t *bp;
- ASSERT(bip->bli_trace != NULL);
-
- bp = bip->bli_buf;
- ktrace_enter(bip->bli_trace,
- (void *)id,
- (void *)bip->bli_buf,
- (void *)((unsigned long)bip->bli_flags),
- (void *)((unsigned long)bip->bli_recur),
- (void *)((unsigned long)atomic_read(&bip->bli_refcount)),
- (void *)((unsigned long)
- (0xFFFFFFFF & XFS_BUF_ADDR(bp) >> 32)),
- (void *)((unsigned long)(0xFFFFFFFF & XFS_BUF_ADDR(bp))),
- (void *)((unsigned long)XFS_BUF_COUNT(bp)),
- (void *)((unsigned long)XFS_BUF_BFLAGS(bp)),
- XFS_BUF_FSPRIVATE(bp, void *),
- XFS_BUF_FSPRIVATE2(bp, void *),
- (void *)(unsigned long)XFS_BUF_ISPINNED(bp),
- (void *)XFS_BUF_IODONE_FUNC(bp),
- (void *)((unsigned long)(XFS_BUF_VALUSEMA(bp))),
- (void *)bip->bli_item.li_desc,
- (void *)((unsigned long)bip->bli_item.li_flags));
-}
-#endif /* XFS_BLI_TRACE */
-
-
diff --git a/sys/gnu/fs/xfs/xfs_buf_item.h b/sys/gnu/fs/xfs/xfs_buf_item.h
deleted file mode 100644
index 07c708c..0000000
--- a/sys/gnu/fs/xfs/xfs_buf_item.h
+++ /dev/null
@@ -1,157 +0,0 @@
-/*
- * Copyright (c) 2000-2001,2005 Silicon Graphics, Inc.
- * All Rights Reserved.
- *
- * 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.
- *
- * This program is distributed in the hope that it would 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 the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- */
-#ifndef __XFS_BUF_ITEM_H__
-#define __XFS_BUF_ITEM_H__
-
-/*
- * This is the structure used to lay out a buf log item in the
- * log. The data map describes which 128 byte chunks of the buffer
- * have been logged. This structure works only on buffers that
- * reside up to the first TB in the filesystem. These buffers are
- * generated only by pre-6.2 systems and are known as XFS_LI_6_1_BUF.
- */
-typedef struct xfs_buf_log_format_v1 {
- unsigned short blf_type; /* buf log item type indicator */
- unsigned short blf_size; /* size of this item */
- __int32_t blf_blkno; /* starting blkno of this buf */
- ushort blf_flags; /* misc state */
- ushort blf_len; /* number of blocks in this buf */
- unsigned int blf_map_size; /* size of data bitmap in words */
- unsigned int blf_data_map[1];/* variable size bitmap of */
- /* regions of buffer in this item */
-} xfs_buf_log_format_v1_t;
-
-/*
- * This is a form of the above structure with a 64 bit blkno field.
- * For 6.2 and beyond, this is XFS_LI_BUF. We use this to log everything.
- */
-typedef struct xfs_buf_log_format_t {
- unsigned short blf_type; /* buf log item type indicator */
- unsigned short blf_size; /* size of this item */
- ushort blf_flags; /* misc state */
- ushort blf_len; /* number of blocks in this buf */
- __int64_t blf_blkno; /* starting blkno of this buf */
- unsigned int blf_map_size; /* size of data bitmap in words */
- unsigned int blf_data_map[1];/* variable size bitmap of */
- /* regions of buffer in this item */
-} xfs_buf_log_format_t;
-
-/*
- * This flag indicates that the buffer contains on disk inodes
- * and requires special recovery handling.
- */
-#define XFS_BLI_INODE_BUF 0x1
-/*
- * This flag indicates that the buffer should not be replayed
- * during recovery because its blocks are being freed.
- */
-#define XFS_BLI_CANCEL 0x2
-/*
- * This flag indicates that the buffer contains on disk
- * user or group dquots and may require special recovery handling.
- */
-#define XFS_BLI_UDQUOT_BUF 0x4
-#define XFS_BLI_PDQUOT_BUF 0x8
-#define XFS_BLI_GDQUOT_BUF 0x10
-
-#define XFS_BLI_CHUNK 128
-#define XFS_BLI_SHIFT 7
-#define BIT_TO_WORD_SHIFT 5
-#define NBWORD (NBBY * sizeof(unsigned int))
-
-/*
- * buf log item flags
- */
-#define XFS_BLI_HOLD 0x01
-#define XFS_BLI_DIRTY 0x02
-#define XFS_BLI_STALE 0x04
-#define XFS_BLI_LOGGED 0x08
-#define XFS_BLI_INODE_ALLOC_BUF 0x10
-#define XFS_BLI_STALE_INODE 0x20
-
-
-#ifdef __KERNEL__
-
-struct xfs_buf;
-struct ktrace;
-struct xfs_mount;
-struct xfs_buf_log_item;
-
-#if defined(XFS_BLI_TRACE)
-#define XFS_BLI_TRACE_SIZE 32
-
-void xfs_buf_item_trace(char *, struct xfs_buf_log_item *);
-#else
-#define xfs_buf_item_trace(id, bip)
-#endif
-
-/*
- * This is the in core log item structure used to track information
- * needed to log buffers. It tracks how many times the lock has been
- * locked, and which 128 byte chunks of the buffer are dirty.
- */
-typedef struct xfs_buf_log_item {
- xfs_log_item_t bli_item; /* common item structure */
- struct xfs_buf *bli_buf; /* real buffer pointer */
- unsigned int bli_flags; /* misc flags */
- unsigned int bli_recur; /* lock recursion count */
- atomic_t bli_refcount; /* cnt of tp refs */
-#ifdef XFS_BLI_TRACE
- struct ktrace *bli_trace; /* event trace buf */
-#endif
-#ifdef XFS_TRANS_DEBUG
- char *bli_orig; /* original buffer copy */
- char *bli_logged; /* bytes logged (bitmap) */
-#endif
- xfs_buf_log_format_t bli_format; /* in-log header */
-} xfs_buf_log_item_t;
-
-/*
- * This structure is used during recovery to record the buf log
- * items which have been canceled and should not be replayed.
- */
-typedef struct xfs_buf_cancel {
- xfs_daddr_t bc_blkno;
- uint bc_len;
- int bc_refcount;
- struct xfs_buf_cancel *bc_next;
-} xfs_buf_cancel_t;
-
-void xfs_buf_item_init(struct xfs_buf *, struct xfs_mount *);
-void xfs_buf_item_relse(struct xfs_buf *);
-void xfs_buf_item_log(xfs_buf_log_item_t *, uint, uint);
-uint xfs_buf_item_dirty(xfs_buf_log_item_t *);
-void xfs_buf_attach_iodone(struct xfs_buf *,
- void(*)(struct xfs_buf *, xfs_log_item_t *),
- xfs_log_item_t *);
-void xfs_buf_iodone_callbacks(struct xfs_buf *);
-void xfs_buf_iodone(struct xfs_buf *, xfs_buf_log_item_t *);
-
-#ifdef XFS_TRANS_DEBUG
-void
-xfs_buf_item_flush_log_debug(
- struct xfs_buf *bp,
- uint first,
- uint last);
-#else
-#define xfs_buf_item_flush_log_debug(bp, first, last)
-#endif
-
-#endif /* __KERNEL__ */
-
-#endif /* __XFS_BUF_ITEM_H__ */
diff --git a/sys/gnu/fs/xfs/xfs_cap.c b/sys/gnu/fs/xfs/xfs_cap.c
deleted file mode 100644
index 7f8e038..0000000
--- a/sys/gnu/fs/xfs/xfs_cap.c
+++ /dev/null
@@ -1,207 +0,0 @@
-/*
- * Copyright (c) 2002 Silicon Graphics, Inc. All Rights Reserved.
- *
- * This program 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.
- *
- * This program is distributed in the hope that it would be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
- *
- * Further, this software is distributed without any warranty that it is
- * free of the rightful claim of any third person regarding infringement
- * or the like. Any license provided herein, whether implied or
- * otherwise, applies only to this software file. Patent licenses, if
- * any, provided herein do not apply to combinations of this program with
- * other software, or any other product whatsoever.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write the Free Software Foundation, Inc., 59
- * Temple Place - Suite 330, Boston MA 02111-1307, USA.
- *
- * Contact information: Silicon Graphics, Inc., 1600 Amphitheatre Pkwy,
- * Mountain View, CA 94043, or:
- *
- * http://www.sgi.com
- *
- * For further information regarding this notice, see:
- *
- * http://oss.sgi.com/projects/GenInfo/SGIGPLNoticeExplan/
- */
-
-#include "xfs.h"
-
-STATIC int xfs_cap_allow_set(xfs_vnode_t *);
-
-
-/*
- * Test for existence of capability attribute as efficiently as possible.
- */
-int
-xfs_cap_vhascap(
- xfs_vnode_t *vp)
-{
- int error;
- int len = sizeof(xfs_cap_set_t);
- int flags = ATTR_KERNOVAL|ATTR_ROOT;
-
- XVOP_ATTR_GET(vp, SGI_CAP_LINUX, NULL, &len, flags, sys_cred, error);
- return (error == 0);
-}
-
-/*
- * Convert from extended attribute representation to in-memory for XFS.
- */
-STATIC int
-posix_cap_xattr_to_xfs(
- posix_cap_xattr *src,
- size_t size,
- xfs_cap_set_t *dest)
-{
- if (!src || !dest)
- return EINVAL;
-
- if (src->c_version != cpu_to_le32(POSIX_CAP_XATTR_VERSION))
- return EINVAL;
- if (src->c_abiversion != cpu_to_le32(_LINUX_CAPABILITY_VERSION))
- return EINVAL;
-
- if (size < sizeof(posix_cap_xattr))
- return EINVAL;
-
- ASSERT(sizeof(dest->cap_effective) == sizeof(src->c_effective));
-
- dest->cap_effective = src->c_effective;
- dest->cap_permitted = src->c_permitted;
- dest->cap_inheritable = src->c_inheritable;
-
- return 0;
-}
-
-/*
- * Convert from in-memory XFS to extended attribute representation.
- */
-STATIC int
-posix_cap_xfs_to_xattr(
- xfs_cap_set_t *src,
- posix_cap_xattr *xattr_cap,
- size_t size)
-{
- size_t new_size = posix_cap_xattr_size();
-
- if (size < new_size)
- return -ERANGE;
-
- ASSERT(sizeof(xattr_cap->c_effective) == sizeof(src->cap_effective));
-
- xattr_cap->c_version = cpu_to_le32(POSIX_CAP_XATTR_VERSION);
- xattr_cap->c_abiversion = cpu_to_le32(_LINUX_CAPABILITY_VERSION);
- xattr_cap->c_effective = src->cap_effective;
- xattr_cap->c_permitted = src->cap_permitted;
- xattr_cap->c_inheritable= src->cap_inheritable;
-
- return new_size;
-}
-
-int
-xfs_cap_vget(
- xfs_vnode_t *vp,
- void *cap,
- size_t size)
-{
- int error;
- int len = sizeof(xfs_cap_set_t);
- int flags = ATTR_ROOT;
- xfs_cap_set_t xfs_cap = { 0 };
- posix_cap_xattr *xattr_cap = cap;
- char *data = (char *)&xfs_cap;
-
- VN_HOLD(vp);
- if ((error = _MAC_VACCESS(vp, NULL, VREAD)))
- goto out;
-
- if (!size) {
- flags |= ATTR_KERNOVAL;
- data = NULL;
- }
- XVOP_ATTR_GET(vp, SGI_CAP_LINUX, data, &len, flags, sys_cred, error);
- if (error)
- goto out;
- ASSERT(len == sizeof(xfs_cap_set_t));
-
- error = (size)? -posix_cap_xattr_size() :
- -posix_cap_xfs_to_xattr(&xfs_cap, xattr_cap, size);
-out:
- VN_RELE(vp);
- return -error;
-}
-
-int
-xfs_cap_vremove(
- xfs_vnode_t *vp)
-{
- int error;
-
- VN_HOLD(vp);
- error = xfs_cap_allow_set(vp);
- if (!error) {
- XVOP_ATTR_REMOVE(vp, SGI_CAP_LINUX, ATTR_ROOT, sys_cred, error);
- if (error == ENOATTR)
- error = 0; /* 'scool */
- }
- VN_RELE(vp);
- return -error;
-}
-
-int
-xfs_cap_vset(
- xfs_vnode_t *vp,
- void *cap,
- size_t size)
-{
- posix_cap_xattr *xattr_cap = cap;
- xfs_cap_set_t xfs_cap;
- int error;
-
- if (!cap)
- return -EINVAL;
-
- error = posix_cap_xattr_to_xfs(xattr_cap, size, &xfs_cap);
- if (error)
- return -error;
-
- VN_HOLD(vp);
- error = xfs_cap_allow_set(vp);
- if (error)
- goto out;
-
- XVOP_ATTR_SET(vp, SGI_CAP_LINUX, (char *)&xfs_cap,
- sizeof(xfs_cap_set_t), ATTR_ROOT, sys_cred, error);
-out:
- VN_RELE(vp);
- return -error;
-}
-
-STATIC int
-xfs_cap_allow_set(
- xfs_vnode_t *vp)
-{
- vattr_t va;
- int error;
-
- if (vp->v_vfsp->vfs_flag & VFS_RDONLY)
- return EROFS;
- if (vp->v_inode.i_flags & (S_IMMUTABLE|S_APPEND))
- return EPERM;
- if ((error = _MAC_VACCESS(vp, NULL, VWRITE)))
- return error;
- va.va_mask = XFS_AT_UID;
- XVOP_GETATTR(vp, &va, 0, NULL, error);
- if (error)
- return error;
- if (va.va_uid != current->fsuid && !capable(CAP_FOWNER))
- return EPERM;
- return error;
-}
-
diff --git a/sys/gnu/fs/xfs/xfs_cap.h b/sys/gnu/fs/xfs/xfs_cap.h
deleted file mode 100644
index 8bff4d4..0000000
--- a/sys/gnu/fs/xfs/xfs_cap.h
+++ /dev/null
@@ -1,70 +0,0 @@
-/*
- * Copyright (c) 2000-2002,2005 Silicon Graphics, Inc.
- * All Rights Reserved.
- *
- * 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.
- *
- * This program is distributed in the hope that it would 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 the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- */
-#ifndef __XFS_CAP_H__
-#define __XFS_CAP_H__
-
-/*
- * Capabilities
- */
-typedef __uint64_t xfs_cap_value_t;
-
-typedef struct xfs_cap_set {
- xfs_cap_value_t cap_effective; /* use in capability checks */
- xfs_cap_value_t cap_permitted; /* combined with file attrs */
- xfs_cap_value_t cap_inheritable;/* pass through exec */
-} xfs_cap_set_t;
-
-/* On-disk XFS extended attribute names */
-#define SGI_CAP_FILE "SGI_CAP_FILE"
-#define SGI_CAP_FILE_SIZE (sizeof(SGI_CAP_FILE)-1)
-#define SGI_CAP_LINUX "SGI_CAP_LINUX"
-#define SGI_CAP_LINUX_SIZE (sizeof(SGI_CAP_LINUX)-1)
-
-/*
- * For Linux, we take the bitfields directly from capability.h
- * and no longer attempt to keep this attribute ondisk compatible
- * with IRIX. Since this attribute is only set on executables,
- * it just doesn't make much sense to try. We do use a different
- * named attribute though, to avoid confusion.
- */
-
-#ifdef __KERNEL__
-
-#ifdef CONFIG_FS_POSIX_CAP
-
-#include <linux/posix_cap_xattr.h>
-
-struct xfs_vnode;
-
-extern int xfs_cap_vhascap(struct xfs_vnode *);
-extern int xfs_cap_vset(struct xfs_vnode *, void *, size_t);
-extern int xfs_cap_vget(struct xfs_vnode *, void *, size_t);
-extern int xfs_cap_vremove(struct xfs_vnode *vp);
-
-#define _CAP_EXISTS xfs_cap_vhascap
-
-#else
-#define xfs_cap_vset(v,p,sz) (-EOPNOTSUPP)
-#define xfs_cap_vget(v,p,sz) (-EOPNOTSUPP)
-#define xfs_cap_vremove(v) (-EOPNOTSUPP)
-#define _CAP_EXISTS (NULL)
-#endif
-
-#endif /* __KERNEL__ */
-
-#endif /* __XFS_CAP_H__ */
diff --git a/sys/gnu/fs/xfs/xfs_clnt.h b/sys/gnu/fs/xfs/xfs_clnt.h
deleted file mode 100644
index 5b7eb81..0000000
--- a/sys/gnu/fs/xfs/xfs_clnt.h
+++ /dev/null
@@ -1,103 +0,0 @@
-/*
- * Copyright (c) 2000-2005 Silicon Graphics, Inc.
- * All Rights Reserved.
- *
- * 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.
- *
- * This program is distributed in the hope that it would 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 the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- */
-#ifndef __XFS_CLNT_H__
-#define __XFS_CLNT_H__
-
-/*
- * XFS arguments structure, constructed from the arguments we
- * are passed via the mount system call.
- *
- * NOTE: The mount system call is handled differently between
- * Linux and IRIX. In IRIX we worked work with a binary data
- * structure coming in across the syscall interface from user
- * space (the mount userspace knows about each filesystem type
- * and the set of valid options for it, and converts the users
- * argument string into a binary structure _before_ making the
- * system call), and the ABI issues that this implies.
- *
- * In Linux, we are passed a comma separated set of options;
- * ie. a NULL terminated string of characters. Userspace mount
- * code does not have any knowledge of mount options expected by
- * each filesystem type and so each filesystem parses its mount
- * options in kernel space.
- *
- * For the Linux port, we kept this structure pretty much intact
- * and use it internally (because the existing code groks it).
- */
-struct xfs_mount_args {
- int flags; /* flags -> see XFSMNT_... macros below */
- int flags2; /* flags -> see XFSMNT2_... macros below */
- int logbufs; /* Number of log buffers, -1 to default */
- int logbufsize; /* Size of log buffers, -1 to default */
- char fsname[MAXNAMELEN+1]; /* data device name */
- char rtname[MAXNAMELEN+1]; /* realtime device filename */
- char logname[MAXNAMELEN+1]; /* journal device filename */
- char mtpt[MAXNAMELEN+1]; /* filesystem mount point */
- int sunit; /* stripe unit (BBs) */
- int swidth; /* stripe width (BBs), multiple of sunit */
- uchar_t iosizelog; /* log2 of the preferred I/O size */
- int ihashsize; /* inode hash table size (buckets) */
-};
-
-/*
- * XFS mount option flags -- args->flags1
- */
-#define XFSMNT_ATTR2 0x00000001 /* allow ATTR2 EA format */
-#define XFSMNT_WSYNC 0x00000002 /* safe mode nfs mount
- * compatible */
-#define XFSMNT_INO64 0x00000004 /* move inode numbers up
- * past 2^32 */
-#define XFSMNT_UQUOTA 0x00000008 /* user quota accounting */
-#define XFSMNT_PQUOTA 0x00000010 /* IRIX prj quota accounting */
-#define XFSMNT_UQUOTAENF 0x00000020 /* user quota limit
- * enforcement */
-#define XFSMNT_PQUOTAENF 0x00000040 /* IRIX project quota limit
- * enforcement */
-#define XFSMNT_QUIET 0x00000080 /* don't report mount errors */
-#define XFSMNT_NOALIGN 0x00000200 /* don't allocate at
- * stripe boundaries*/
-#define XFSMNT_RETERR 0x00000400 /* return error to user */
-#define XFSMNT_NORECOVERY 0x00000800 /* no recovery, implies
- * read-only mount */
-#define XFSMNT_SHARED 0x00001000 /* shared XFS mount */
-#define XFSMNT_IOSIZE 0x00002000 /* optimize for I/O size */
-#define XFSMNT_OSYNCISOSYNC 0x00004000 /* o_sync is REALLY o_sync */
- /* (osyncisdsync is default) */
-#define XFSMNT_32BITINODES 0x00200000 /* restrict inodes to 32
- * bits of address space */
-#define XFSMNT_GQUOTA 0x00400000 /* group quota accounting */
-#define XFSMNT_GQUOTAENF 0x00800000 /* group quota limit
- * enforcement */
-#define XFSMNT_NOUUID 0x01000000 /* Ignore fs uuid */
-#define XFSMNT_DMAPI 0x02000000 /* enable dmapi/xdsm */
-#define XFSMNT_BARRIER 0x04000000 /* use write barriers */
-#define XFSMNT_IDELETE 0x08000000 /* inode cluster delete */
-#define XFSMNT_SWALLOC 0x10000000 /* turn on stripe width
- * allocation */
-#define XFSMNT_IHASHSIZE 0x20000000 /* inode hash table size */
-#define XFSMNT_DIRSYNC 0x40000000 /* sync creat,link,unlink,rename
- * symlink,mkdir,rmdir,mknod */
-#define XFSMNT_FLAGS2 0x80000000 /* more flags set in flags2 */
-
-/*
- * XFS mount option flags -- args->flags2
- */
-#define XFSMNT2_COMPAT_IOSIZE 0x00000001 /* don't report large preferred
- * I/O size in stat(2) */
-
-#endif /* __XFS_CLNT_H__ */
diff --git a/sys/gnu/fs/xfs/xfs_da_btree.c b/sys/gnu/fs/xfs/xfs_da_btree.c
deleted file mode 100644
index 47b86f9..0000000
--- a/sys/gnu/fs/xfs/xfs_da_btree.c
+++ /dev/null
@@ -1,2590 +0,0 @@
-/*
- * Copyright (c) 2000-2005 Silicon Graphics, Inc.
- * All Rights Reserved.
- *
- * 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.
- *
- * This program is distributed in the hope that it would 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 the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- */
-#include "xfs.h"
-#include "xfs_fs.h"
-#include "xfs_types.h"
-#include "xfs_bit.h"
-#include "xfs_log.h"
-#include "xfs_inum.h"
-#include "xfs_trans.h"
-#include "xfs_sb.h"
-#include "xfs_ag.h"
-#include "xfs_dir.h"
-#include "xfs_dir2.h"
-#include "xfs_dmapi.h"
-#include "xfs_mount.h"
-#include "xfs_da_btree.h"
-#include "xfs_bmap_btree.h"
-#include "xfs_alloc_btree.h"
-#include "xfs_ialloc_btree.h"
-#include "xfs_dir_sf.h"
-#include "xfs_dir2_sf.h"
-#include "xfs_attr_sf.h"
-#include "xfs_dinode.h"
-#include "xfs_inode.h"
-#include "xfs_inode_item.h"
-#include "xfs_alloc.h"
-#include "xfs_btree.h"
-#include "xfs_bmap.h"
-#include "xfs_attr.h"
-#include "xfs_attr_leaf.h"
-#include "xfs_dir_leaf.h"
-#include "xfs_dir2_data.h"
-#include "xfs_dir2_leaf.h"
-#include "xfs_dir2_block.h"
-#include "xfs_dir2_node.h"
-#include "xfs_error.h"
-
-/*
- * xfs_da_btree.c
- *
- * Routines to implement directories as Btrees of hashed names.
- */
-
-/*========================================================================
- * Function prototypes for the kernel.
- *========================================================================*/
-
-/*
- * Routines used for growing the Btree.
- */
-STATIC int xfs_da_root_split(xfs_da_state_t *state,
- xfs_da_state_blk_t *existing_root,
- xfs_da_state_blk_t *new_child);
-STATIC int xfs_da_node_split(xfs_da_state_t *state,
- xfs_da_state_blk_t *existing_blk,
- xfs_da_state_blk_t *split_blk,
- xfs_da_state_blk_t *blk_to_add,
- int treelevel,
- int *result);
-STATIC void xfs_da_node_rebalance(xfs_da_state_t *state,
- xfs_da_state_blk_t *node_blk_1,
- xfs_da_state_blk_t *node_blk_2);
-STATIC void xfs_da_node_add(xfs_da_state_t *state,
- xfs_da_state_blk_t *old_node_blk,
- xfs_da_state_blk_t *new_node_blk);
-
-/*
- * Routines used for shrinking the Btree.
- */
-STATIC int xfs_da_root_join(xfs_da_state_t *state,
- xfs_da_state_blk_t *root_blk);
-STATIC int xfs_da_node_toosmall(xfs_da_state_t *state, int *retval);
-STATIC void xfs_da_node_remove(xfs_da_state_t *state,
- xfs_da_state_blk_t *drop_blk);
-STATIC void xfs_da_node_unbalance(xfs_da_state_t *state,
- xfs_da_state_blk_t *src_node_blk,
- xfs_da_state_blk_t *dst_node_blk);
-
-/*
- * Utility routines.
- */
-STATIC uint xfs_da_node_lasthash(xfs_dabuf_t *bp, int *count);
-STATIC int xfs_da_node_order(xfs_dabuf_t *node1_bp, xfs_dabuf_t *node2_bp);
-STATIC xfs_dabuf_t *xfs_da_buf_make(int nbuf, xfs_buf_t **bps, inst_t *ra);
-STATIC int xfs_da_blk_unlink(xfs_da_state_t *state,
- xfs_da_state_blk_t *drop_blk,
- xfs_da_state_blk_t *save_blk);
-STATIC void xfs_da_state_kill_altpath(xfs_da_state_t *state);
-
-/*========================================================================
- * Routines used for growing the Btree.
- *========================================================================*/
-
-/*
- * Create the initial contents of an intermediate node.
- */
-int
-xfs_da_node_create(xfs_da_args_t *args, xfs_dablk_t blkno, int level,
- xfs_dabuf_t **bpp, int whichfork)
-{
- xfs_da_intnode_t *node;
- xfs_dabuf_t *bp;
- int error;
- xfs_trans_t *tp;
-
- tp = args->trans;
- error = xfs_da_get_buf(tp, args->dp, blkno, -1, &bp, whichfork);
- if (error)
- return(error);
- ASSERT(bp != NULL);
- node = bp->data;
- node->hdr.info.forw = 0;
- node->hdr.info.back = 0;
- node->hdr.info.magic = cpu_to_be16(XFS_DA_NODE_MAGIC);
- node->hdr.info.pad = 0;
- node->hdr.count = 0;
- node->hdr.level = cpu_to_be16(level);
-
- xfs_da_log_buf(tp, bp,
- XFS_DA_LOGRANGE(node, &node->hdr, sizeof(node->hdr)));
-
- *bpp = bp;
- return(0);
-}
-
-/*
- * Split a leaf node, rebalance, then possibly split
- * intermediate nodes, rebalance, etc.
- */
-int /* error */
-xfs_da_split(xfs_da_state_t *state)
-{
- xfs_da_state_blk_t *oldblk, *newblk, *addblk;
- xfs_da_intnode_t *node;
- xfs_dabuf_t *bp;
- int max, action, error, i;
-
- /*
- * Walk back up the tree splitting/inserting/adjusting as necessary.
- * If we need to insert and there isn't room, split the node, then
- * decide which fragment to insert the new block from below into.
- * Note that we may split the root this way, but we need more fixup.
- */
- max = state->path.active - 1;
- ASSERT((max >= 0) && (max < XFS_DA_NODE_MAXDEPTH));
- ASSERT(state->path.blk[max].magic == XFS_ATTR_LEAF_MAGIC ||
- state->path.blk[max].magic == XFS_DIRX_LEAF_MAGIC(state->mp));
-
- addblk = &state->path.blk[max]; /* initial dummy value */
- for (i = max; (i >= 0) && addblk; state->path.active--, i--) {
- oldblk = &state->path.blk[i];
- newblk = &state->altpath.blk[i];
-
- /*
- * If a leaf node then
- * Allocate a new leaf node, then rebalance across them.
- * else if an intermediate node then
- * We split on the last layer, must we split the node?
- */
- switch (oldblk->magic) {
- case XFS_ATTR_LEAF_MAGIC:
- error = xfs_attr_leaf_split(state, oldblk, newblk);
- if ((error != 0) && (error != ENOSPC)) {
- return(error); /* GROT: attr is inconsistent */
- }
- if (!error) {
- addblk = newblk;
- break;
- }
- /*
- * Entry wouldn't fit, split the leaf again.
- */
- state->extravalid = 1;
- if (state->inleaf) {
- state->extraafter = 0; /* before newblk */
- error = xfs_attr_leaf_split(state, oldblk,
- &state->extrablk);
- } else {
- state->extraafter = 1; /* after newblk */
- error = xfs_attr_leaf_split(state, newblk,
- &state->extrablk);
- }
- if (error)
- return(error); /* GROT: attr inconsistent */
- addblk = newblk;
- break;
- case XFS_DIR_LEAF_MAGIC:
- ASSERT(XFS_DIR_IS_V1(state->mp));
- error = xfs_dir_leaf_split(state, oldblk, newblk);
- if ((error != 0) && (error != ENOSPC)) {
- return(error); /* GROT: dir is inconsistent */
- }
- if (!error) {
- addblk = newblk;
- break;
- }
- /*
- * Entry wouldn't fit, split the leaf again.
- */
- state->extravalid = 1;
- if (state->inleaf) {
- state->extraafter = 0; /* before newblk */
- error = xfs_dir_leaf_split(state, oldblk,
- &state->extrablk);
- if (error)
- return(error); /* GROT: dir incon. */
- addblk = newblk;
- } else {
- state->extraafter = 1; /* after newblk */
- error = xfs_dir_leaf_split(state, newblk,
- &state->extrablk);
- if (error)
- return(error); /* GROT: dir incon. */
- addblk = newblk;
- }
- break;
- case XFS_DIR2_LEAFN_MAGIC:
- ASSERT(XFS_DIR_IS_V2(state->mp));
- error = xfs_dir2_leafn_split(state, oldblk, newblk);
- if (error)
- return error;
- addblk = newblk;
- break;
- case XFS_DA_NODE_MAGIC:
- error = xfs_da_node_split(state, oldblk, newblk, addblk,
- max - i, &action);
- xfs_da_buf_done(addblk->bp);
- addblk->bp = NULL;
- if (error)
- return(error); /* GROT: dir is inconsistent */
- /*
- * Record the newly split block for the next time thru?
- */
- if (action)
- addblk = newblk;
- else
- addblk = NULL;
- break;
- }
-
- /*
- * Update the btree to show the new hashval for this child.
- */
- xfs_da_fixhashpath(state, &state->path);
- /*
- * If we won't need this block again, it's getting dropped
- * from the active path by the loop control, so we need
- * to mark it done now.
- */
- if (i > 0 || !addblk)
- xfs_da_buf_done(oldblk->bp);
- }
- if (!addblk)
- return(0);
-
- /*
- * Split the root node.
- */
- ASSERT(state->path.active == 0);
- oldblk = &state->path.blk[0];
- error = xfs_da_root_split(state, oldblk, addblk);
- if (error) {
- xfs_da_buf_done(oldblk->bp);
- xfs_da_buf_done(addblk->bp);
- addblk->bp = NULL;
- return(error); /* GROT: dir is inconsistent */
- }
-
- /*
- * Update pointers to the node which used to be block 0 and
- * just got bumped because of the addition of a new root node.
- * There might be three blocks involved if a double split occurred,
- * and the original block 0 could be at any position in the list.
- */
-
- node = oldblk->bp->data;
- if (node->hdr.info.forw) {
- if (be32_to_cpu(node->hdr.info.forw) == addblk->blkno) {
- bp = addblk->bp;
- } else {
- ASSERT(state->extravalid);
- bp = state->extrablk.bp;
- }
- node = bp->data;
- node->hdr.info.back = cpu_to_be32(oldblk->blkno);
- xfs_da_log_buf(state->args->trans, bp,
- XFS_DA_LOGRANGE(node, &node->hdr.info,
- sizeof(node->hdr.info)));
- }
- node = oldblk->bp->data;
- if (node->hdr.info.back) {
- if (be32_to_cpu(node->hdr.info.back) == addblk->blkno) {
- bp = addblk->bp;
- } else {
- ASSERT(state->extravalid);
- bp = state->extrablk.bp;
- }
- node = bp->data;
- node->hdr.info.forw = cpu_to_be32(oldblk->blkno);
- xfs_da_log_buf(state->args->trans, bp,
- XFS_DA_LOGRANGE(node, &node->hdr.info,
- sizeof(node->hdr.info)));
- }
- xfs_da_buf_done(oldblk->bp);
- xfs_da_buf_done(addblk->bp);
- addblk->bp = NULL;
- return(0);
-}
-
-/*
- * Split the root. We have to create a new root and point to the two
- * parts (the split old root) that we just created. Copy block zero to
- * the EOF, extending the inode in process.
- */
-STATIC int /* error */
-xfs_da_root_split(xfs_da_state_t *state, xfs_da_state_blk_t *blk1,
- xfs_da_state_blk_t *blk2)
-{
- xfs_da_intnode_t *node, *oldroot;
- xfs_da_args_t *args;
- xfs_dablk_t blkno;
- xfs_dabuf_t *bp;
- int error, size;
- xfs_inode_t *dp;
- xfs_trans_t *tp;
- xfs_mount_t *mp;
- xfs_dir2_leaf_t *leaf;
-
- /*
- * Copy the existing (incorrect) block from the root node position
- * to a free space somewhere.
- */
- args = state->args;
- ASSERT(args != NULL);
- error = xfs_da_grow_inode(args, &blkno);
- if (error)
- return(error);
- dp = args->dp;
- tp = args->trans;
- mp = state->mp;
- error = xfs_da_get_buf(tp, dp, blkno, -1, &bp, args->whichfork);
- if (error)
- return(error);
- ASSERT(bp != NULL);
- node = bp->data;
- oldroot = blk1->bp->data;
- if (be16_to_cpu(oldroot->hdr.info.magic) == XFS_DA_NODE_MAGIC) {
- size = (int)((char *)&oldroot->btree[be16_to_cpu(oldroot->hdr.count)] -
- (char *)oldroot);
- } else {
- ASSERT(XFS_DIR_IS_V2(mp));
- ASSERT(be16_to_cpu(oldroot->hdr.info.magic) == XFS_DIR2_LEAFN_MAGIC);
- leaf = (xfs_dir2_leaf_t *)oldroot;
- size = (int)((char *)&leaf->ents[be16_to_cpu(leaf->hdr.count)] -
- (char *)leaf);
- }
- memcpy(node, oldroot, size);
- xfs_da_log_buf(tp, bp, 0, size - 1);
- xfs_da_buf_done(blk1->bp);
- blk1->bp = bp;
- blk1->blkno = blkno;
-
- /*
- * Set up the new root node.
- */
- error = xfs_da_node_create(args,
- args->whichfork == XFS_DATA_FORK &&
- XFS_DIR_IS_V2(mp) ? mp->m_dirleafblk : 0,
- be16_to_cpu(node->hdr.level) + 1, &bp, args->whichfork);
- if (error)
- return(error);
- node = bp->data;
- node->btree[0].hashval = cpu_to_be32(blk1->hashval);
- node->btree[0].before = cpu_to_be32(blk1->blkno);
- node->btree[1].hashval = cpu_to_be32(blk2->hashval);
- node->btree[1].before = cpu_to_be32(blk2->blkno);
- node->hdr.count = cpu_to_be16(2);
-
-#ifdef DEBUG
- if (be16_to_cpu(oldroot->hdr.info.magic) == XFS_DIR2_LEAFN_MAGIC) {
- ASSERT(blk1->blkno >= mp->m_dirleafblk &&
- blk1->blkno < mp->m_dirfreeblk);
- ASSERT(blk2->blkno >= mp->m_dirleafblk &&
- blk2->blkno < mp->m_dirfreeblk);
- }
-#endif
-
- /* Header is already logged by xfs_da_node_create */
- xfs_da_log_buf(tp, bp,
- XFS_DA_LOGRANGE(node, node->btree,
- sizeof(xfs_da_node_entry_t) * 2));
- xfs_da_buf_done(bp);
-
- return(0);
-}
-
-/*
- * Split the node, rebalance, then add the new entry.
- */
-STATIC int /* error */
-xfs_da_node_split(xfs_da_state_t *state, xfs_da_state_blk_t *oldblk,
- xfs_da_state_blk_t *newblk,
- xfs_da_state_blk_t *addblk,
- int treelevel, int *result)
-{
- xfs_da_intnode_t *node;
- xfs_dablk_t blkno;
- int newcount, error;
- int useextra;
-
- node = oldblk->bp->data;
- ASSERT(be16_to_cpu(node->hdr.info.magic) == XFS_DA_NODE_MAGIC);
-
- /*
- * With V2 the extra block is data or freespace.
- */
- useextra = state->extravalid && (XFS_DIR_IS_V1(state->mp) ||
- state->args->whichfork == XFS_ATTR_FORK);
- newcount = 1 + useextra;
- /*
- * Do we have to split the node?
- */
- if ((be16_to_cpu(node->hdr.count) + newcount) > state->node_ents) {
- /*
- * Allocate a new node, add to the doubly linked chain of
- * nodes, then move some of our excess entries into it.
- */
- error = xfs_da_grow_inode(state->args, &blkno);
- if (error)
- return(error); /* GROT: dir is inconsistent */
-
- error = xfs_da_node_create(state->args, blkno, treelevel,
- &newblk->bp, state->args->whichfork);
- if (error)
- return(error); /* GROT: dir is inconsistent */
- newblk->blkno = blkno;
- newblk->magic = XFS_DA_NODE_MAGIC;
- xfs_da_node_rebalance(state, oldblk, newblk);
- error = xfs_da_blk_link(state, oldblk, newblk);
- if (error)
- return(error);
- *result = 1;
- } else {
- *result = 0;
- }
-
- /*
- * Insert the new entry(s) into the correct block
- * (updating last hashval in the process).
- *
- * xfs_da_node_add() inserts BEFORE the given index,
- * and as a result of using node_lookup_int() we always
- * point to a valid entry (not after one), but a split
- * operation always results in a new block whose hashvals
- * FOLLOW the current block.
- *
- * If we had double-split op below us, then add the extra block too.
- */
- node = oldblk->bp->data;
- if (oldblk->index <= be16_to_cpu(node->hdr.count)) {
- oldblk->index++;
- xfs_da_node_add(state, oldblk, addblk);
- if (useextra) {
- if (state->extraafter)
- oldblk->index++;
- xfs_da_node_add(state, oldblk, &state->extrablk);
- state->extravalid = 0;
- }
- } else {
- newblk->index++;
- xfs_da_node_add(state, newblk, addblk);
- if (useextra) {
- if (state->extraafter)
- newblk->index++;
- xfs_da_node_add(state, newblk, &state->extrablk);
- state->extravalid = 0;
- }
- }
-
- return(0);
-}
-
-/*
- * Balance the btree elements between two intermediate nodes,
- * usually one full and one empty.
- *
- * NOTE: if blk2 is empty, then it will get the upper half of blk1.
- */
-STATIC void
-xfs_da_node_rebalance(xfs_da_state_t *state, xfs_da_state_blk_t *blk1,
- xfs_da_state_blk_t *blk2)
-{
- xfs_da_intnode_t *node1, *node2, *tmpnode;
- xfs_da_node_entry_t *btree_s, *btree_d;
- int count, tmp;
- xfs_trans_t *tp;
-
- node1 = blk1->bp->data;
- node2 = blk2->bp->data;
- /*
- * Figure out how many entries need to move, and in which direction.
- * Swap the nodes around if that makes it simpler.
- */
- if ((be16_to_cpu(node1->hdr.count) > 0) && (be16_to_cpu(node2->hdr.count) > 0) &&
- ((be32_to_cpu(node2->btree[0].hashval) < be32_to_cpu(node1->btree[0].hashval)) ||
- (be32_to_cpu(node2->btree[be16_to_cpu(node2->hdr.count)-1].hashval) <
- be32_to_cpu(node1->btree[be16_to_cpu(node1->hdr.count)-1].hashval)))) {
- tmpnode = node1;
- node1 = node2;
- node2 = tmpnode;
- }
- ASSERT(be16_to_cpu(node1->hdr.info.magic) == XFS_DA_NODE_MAGIC);
- ASSERT(be16_to_cpu(node2->hdr.info.magic) == XFS_DA_NODE_MAGIC);
- count = (be16_to_cpu(node1->hdr.count) - be16_to_cpu(node2->hdr.count)) / 2;
- if (count == 0)
- return;
- tp = state->args->trans;
- /*
- * Two cases: high-to-low and low-to-high.
- */
- if (count > 0) {
- /*
- * Move elements in node2 up to make a hole.
- */
- if ((tmp = be16_to_cpu(node2->hdr.count)) > 0) {
- tmp *= (uint)sizeof(xfs_da_node_entry_t);
- btree_s = &node2->btree[0];
- btree_d = &node2->btree[count];
- memmove(btree_d, btree_s, tmp);
- }
-
- /*
- * Move the req'd B-tree elements from high in node1 to
- * low in node2.
- */
- be16_add(&node2->hdr.count, count);
- tmp = count * (uint)sizeof(xfs_da_node_entry_t);
- btree_s = &node1->btree[be16_to_cpu(node1->hdr.count) - count];
- btree_d = &node2->btree[0];
- memcpy(btree_d, btree_s, tmp);
- be16_add(&node1->hdr.count, -count);
- } else {
- /*
- * Move the req'd B-tree elements from low in node2 to
- * high in node1.
- */
- count = -count;
- tmp = count * (uint)sizeof(xfs_da_node_entry_t);
- btree_s = &node2->btree[0];
- btree_d = &node1->btree[be16_to_cpu(node1->hdr.count)];
- memcpy(btree_d, btree_s, tmp);
- be16_add(&node1->hdr.count, count);
- xfs_da_log_buf(tp, blk1->bp,
- XFS_DA_LOGRANGE(node1, btree_d, tmp));
-
- /*
- * Move elements in node2 down to fill the hole.
- */
- tmp = be16_to_cpu(node2->hdr.count) - count;
- tmp *= (uint)sizeof(xfs_da_node_entry_t);
- btree_s = &node2->btree[count];
- btree_d = &node2->btree[0];
- memmove(btree_d, btree_s, tmp);
- be16_add(&node2->hdr.count, -count);
- }
-
- /*
- * Log header of node 1 and all current bits of node 2.
- */
- xfs_da_log_buf(tp, blk1->bp,
- XFS_DA_LOGRANGE(node1, &node1->hdr, sizeof(node1->hdr)));
- xfs_da_log_buf(tp, blk2->bp,
- XFS_DA_LOGRANGE(node2, &node2->hdr,
- sizeof(node2->hdr) +
- sizeof(node2->btree[0]) * be16_to_cpu(node2->hdr.count)));
-
- /*
- * Record the last hashval from each block for upward propagation.
- * (note: don't use the swapped node pointers)
- */
- node1 = blk1->bp->data;
- node2 = blk2->bp->data;
- blk1->hashval = be32_to_cpu(node1->btree[be16_to_cpu(node1->hdr.count)-1].hashval);
- blk2->hashval = be32_to_cpu(node2->btree[be16_to_cpu(node2->hdr.count)-1].hashval);
-
- /*
- * Adjust the expected index for insertion.
- */
- if (blk1->index >= be16_to_cpu(node1->hdr.count)) {
- blk2->index = blk1->index - be16_to_cpu(node1->hdr.count);
- blk1->index = be16_to_cpu(node1->hdr.count) + 1; /* make it invalid */
- }
-}
-
-/*
- * Add a new entry to an intermediate node.
- */
-STATIC void
-xfs_da_node_add(xfs_da_state_t *state, xfs_da_state_blk_t *oldblk,
- xfs_da_state_blk_t *newblk)
-{
- xfs_da_intnode_t *node;
- xfs_da_node_entry_t *btree;
- int tmp;
- xfs_mount_t *mp;
-
- node = oldblk->bp->data;
- mp = state->mp;
- ASSERT(be16_to_cpu(node->hdr.info.magic) == XFS_DA_NODE_MAGIC);
- ASSERT((oldblk->index >= 0) && (oldblk->index <= be16_to_cpu(node->hdr.count)));
- ASSERT(newblk->blkno != 0);
- if (state->args->whichfork == XFS_DATA_FORK && XFS_DIR_IS_V2(mp))
- ASSERT(newblk->blkno >= mp->m_dirleafblk &&
- newblk->blkno < mp->m_dirfreeblk);
-
- /*
- * We may need to make some room before we insert the new node.
- */
- tmp = 0;
- btree = &node->btree[ oldblk->index ];
- if (oldblk->index < be16_to_cpu(node->hdr.count)) {
- tmp = (be16_to_cpu(node->hdr.count) - oldblk->index) * (uint)sizeof(*btree);
- memmove(btree + 1, btree, tmp);
- }
- btree->hashval = cpu_to_be32(newblk->hashval);
- btree->before = cpu_to_be32(newblk->blkno);
- xfs_da_log_buf(state->args->trans, oldblk->bp,
- XFS_DA_LOGRANGE(node, btree, tmp + sizeof(*btree)));
- be16_add(&node->hdr.count, 1);
- xfs_da_log_buf(state->args->trans, oldblk->bp,
- XFS_DA_LOGRANGE(node, &node->hdr, sizeof(node->hdr)));
-
- /*
- * Copy the last hash value from the oldblk to propagate upwards.
- */
- oldblk->hashval = be32_to_cpu(node->btree[be16_to_cpu(node->hdr.count)-1 ].hashval);
-}
-
-/*========================================================================
- * Routines used for shrinking the Btree.
- *========================================================================*/
-
-/*
- * Deallocate an empty leaf node, remove it from its parent,
- * possibly deallocating that block, etc...
- */
-int
-xfs_da_join(xfs_da_state_t *state)
-{
- xfs_da_state_blk_t *drop_blk, *save_blk;
- int action, error;
-
- action = 0;
- drop_blk = &state->path.blk[ state->path.active-1 ];
- save_blk = &state->altpath.blk[ state->path.active-1 ];
- ASSERT(state->path.blk[0].magic == XFS_DA_NODE_MAGIC);
- ASSERT(drop_blk->magic == XFS_ATTR_LEAF_MAGIC ||
- drop_blk->magic == XFS_DIRX_LEAF_MAGIC(state->mp));
-
- /*
- * Walk back up the tree joining/deallocating as necessary.
- * When we stop dropping blocks, break out.
- */
- for ( ; state->path.active >= 2; drop_blk--, save_blk--,
- state->path.active--) {
- /*
- * See if we can combine the block with a neighbor.
- * (action == 0) => no options, just leave
- * (action == 1) => coalesce, then unlink
- * (action == 2) => block empty, unlink it
- */
- switch (drop_blk->magic) {
- case XFS_ATTR_LEAF_MAGIC:
- error = xfs_attr_leaf_toosmall(state, &action);
- if (error)
- return(error);
- if (action == 0)
- return(0);
- xfs_attr_leaf_unbalance(state, drop_blk, save_blk);
- break;
- case XFS_DIR_LEAF_MAGIC:
- ASSERT(XFS_DIR_IS_V1(state->mp));
- error = xfs_dir_leaf_toosmall(state, &action);
- if (error)
- return(error);
- if (action == 0)
- return(0);
- xfs_dir_leaf_unbalance(state, drop_blk, save_blk);
- break;
- case XFS_DIR2_LEAFN_MAGIC:
- ASSERT(XFS_DIR_IS_V2(state->mp));
- error = xfs_dir2_leafn_toosmall(state, &action);
- if (error)
- return error;
- if (action == 0)
- return 0;
- xfs_dir2_leafn_unbalance(state, drop_blk, save_blk);
- break;
- case XFS_DA_NODE_MAGIC:
- /*
- * Remove the offending node, fixup hashvals,
- * check for a toosmall neighbor.
- */
- xfs_da_node_remove(state, drop_blk);
- xfs_da_fixhashpath(state, &state->path);
- error = xfs_da_node_toosmall(state, &action);
- if (error)
- return(error);
- if (action == 0)
- return 0;
- xfs_da_node_unbalance(state, drop_blk, save_blk);
- break;
- }
- xfs_da_fixhashpath(state, &state->altpath);
- error = xfs_da_blk_unlink(state, drop_blk, save_blk);
- xfs_da_state_kill_altpath(state);
- if (error)
- return(error);
- error = xfs_da_shrink_inode(state->args, drop_blk->blkno,
- drop_blk->bp);
- drop_blk->bp = NULL;
- if (error)
- return(error);
- }
- /*
- * We joined all the way to the top. If it turns out that
- * we only have one entry in the root, make the child block
- * the new root.
- */
- xfs_da_node_remove(state, drop_blk);
- xfs_da_fixhashpath(state, &state->path);
- error = xfs_da_root_join(state, &state->path.blk[0]);
- return(error);
-}
-
-/*
- * We have only one entry in the root. Copy the only remaining child of
- * the old root to block 0 as the new root node.
- */
-STATIC int
-xfs_da_root_join(xfs_da_state_t *state, xfs_da_state_blk_t *root_blk)
-{
- xfs_da_intnode_t *oldroot;
- /* REFERENCED */
- xfs_da_blkinfo_t *blkinfo;
- xfs_da_args_t *args;
- xfs_dablk_t child;
- xfs_dabuf_t *bp;
- int error;
-
- args = state->args;
- ASSERT(args != NULL);
- ASSERT(root_blk->magic == XFS_DA_NODE_MAGIC);
- oldroot = root_blk->bp->data;
- ASSERT(be16_to_cpu(oldroot->hdr.info.magic) == XFS_DA_NODE_MAGIC);
- ASSERT(!oldroot->hdr.info.forw);
- ASSERT(!oldroot->hdr.info.back);
-
- /*
- * If the root has more than one child, then don't do anything.
- */
- if (be16_to_cpu(oldroot->hdr.count) > 1)
- return(0);
-
- /*
- * Read in the (only) child block, then copy those bytes into
- * the root block's buffer and free the original child block.
- */
- child = be32_to_cpu(oldroot->btree[0].before);
- ASSERT(child != 0);
- error = xfs_da_read_buf(args->trans, args->dp, child, -1, &bp,
- args->whichfork);
- if (error)
- return(error);
- ASSERT(bp != NULL);
- blkinfo = bp->data;
- if (be16_to_cpu(oldroot->hdr.level) == 1) {
- ASSERT(be16_to_cpu(blkinfo->magic) == XFS_DIRX_LEAF_MAGIC(state->mp) ||
- be16_to_cpu(blkinfo->magic) == XFS_ATTR_LEAF_MAGIC);
- } else {
- ASSERT(be16_to_cpu(blkinfo->magic) == XFS_DA_NODE_MAGIC);
- }
- ASSERT(!blkinfo->forw);
- ASSERT(!blkinfo->back);
- memcpy(root_blk->bp->data, bp->data, state->blocksize);
- xfs_da_log_buf(args->trans, root_blk->bp, 0, state->blocksize - 1);
- error = xfs_da_shrink_inode(args, child, bp);
- return(error);
-}
-
-/*
- * Check a node block and its neighbors to see if the block should be
- * collapsed into one or the other neighbor. Always keep the block
- * with the smaller block number.
- * If the current block is over 50% full, don't try to join it, return 0.
- * If the block is empty, fill in the state structure and return 2.
- * If it can be collapsed, fill in the state structure and return 1.
- * If nothing can be done, return 0.
- */
-STATIC int
-xfs_da_node_toosmall(xfs_da_state_t *state, int *action)
-{
- xfs_da_intnode_t *node;
- xfs_da_state_blk_t *blk;
- xfs_da_blkinfo_t *info;
- int count, forward, error, retval, i;
- xfs_dablk_t blkno;
- xfs_dabuf_t *bp;
-
- /*
- * Check for the degenerate case of the block being over 50% full.
- * If so, it's not worth even looking to see if we might be able
- * to coalesce with a sibling.
- */
- blk = &state->path.blk[ state->path.active-1 ];
- info = blk->bp->data;
- ASSERT(be16_to_cpu(info->magic) == XFS_DA_NODE_MAGIC);
- node = (xfs_da_intnode_t *)info;
- count = be16_to_cpu(node->hdr.count);
- if (count > (state->node_ents >> 1)) {
- *action = 0; /* blk over 50%, don't try to join */
- return(0); /* blk over 50%, don't try to join */
- }
-
- /*
- * Check for the degenerate case of the block being empty.
- * If the block is empty, we'll simply delete it, no need to
- * coalesce it with a sibling block. We choose (arbitrarily)
- * to merge with the forward block unless it is NULL.
- */
- if (count == 0) {
- /*
- * Make altpath point to the block we want to keep and
- * path point to the block we want to drop (this one).
- */
- forward = (info->forw != 0);
- memcpy(&state->altpath, &state->path, sizeof(state->path));
- error = xfs_da_path_shift(state, &state->altpath, forward,
- 0, &retval);
- if (error)
- return(error);
- if (retval) {
- *action = 0;
- } else {
- *action = 2;
- }
- return(0);
- }
-
- /*
- * Examine each sibling block to see if we can coalesce with
- * at least 25% free space to spare. We need to figure out
- * whether to merge with the forward or the backward block.
- * We prefer coalescing with the lower numbered sibling so as
- * to shrink a directory over time.
- */
- /* start with smaller blk num */
- forward = (be32_to_cpu(info->forw) < be32_to_cpu(info->back));
- for (i = 0; i < 2; forward = !forward, i++) {
- if (forward)
- blkno = be32_to_cpu(info->forw);
- else
- blkno = be32_to_cpu(info->back);
- if (blkno == 0)
- continue;
- error = xfs_da_read_buf(state->args->trans, state->args->dp,
- blkno, -1, &bp, state->args->whichfork);
- if (error)
- return(error);
- ASSERT(bp != NULL);
-
- node = (xfs_da_intnode_t *)info;
- count = state->node_ents;
- count -= state->node_ents >> 2;
- count -= be16_to_cpu(node->hdr.count);
- node = bp->data;
- ASSERT(be16_to_cpu(node->hdr.info.magic) == XFS_DA_NODE_MAGIC);
- count -= be16_to_cpu(node->hdr.count);
- xfs_da_brelse(state->args->trans, bp);
- if (count >= 0)
- break; /* fits with at least 25% to spare */
- }
- if (i >= 2) {
- *action = 0;
- return(0);
- }
-
- /*
- * Make altpath point to the block we want to keep (the lower
- * numbered block) and path point to the block we want to drop.
- */
- memcpy(&state->altpath, &state->path, sizeof(state->path));
- if (blkno < blk->blkno) {
- error = xfs_da_path_shift(state, &state->altpath, forward,
- 0, &retval);
- if (error) {
- return(error);
- }
- if (retval) {
- *action = 0;
- return(0);
- }
- } else {
- error = xfs_da_path_shift(state, &state->path, forward,
- 0, &retval);
- if (error) {
- return(error);
- }
- if (retval) {
- *action = 0;
- return(0);
- }
- }
- *action = 1;
- return(0);
-}
-
-/*
- * Walk back up the tree adjusting hash values as necessary,
- * when we stop making changes, return.
- */
-void
-xfs_da_fixhashpath(xfs_da_state_t *state, xfs_da_state_path_t *path)
-{
- xfs_da_state_blk_t *blk;
- xfs_da_intnode_t *node;
- xfs_da_node_entry_t *btree;
- xfs_dahash_t lasthash=0;
- int level, count;
-
- level = path->active-1;
- blk = &path->blk[ level ];
- switch (blk->magic) {
- case XFS_ATTR_LEAF_MAGIC:
- lasthash = xfs_attr_leaf_lasthash(blk->bp, &count);
- if (count == 0)
- return;
- break;
- case XFS_DIR_LEAF_MAGIC:
- ASSERT(XFS_DIR_IS_V1(state->mp));
- lasthash = xfs_dir_leaf_lasthash(blk->bp, &count);
- if (count == 0)
- return;
- break;
- case XFS_DIR2_LEAFN_MAGIC:
- ASSERT(XFS_DIR_IS_V2(state->mp));
- lasthash = xfs_dir2_leafn_lasthash(blk->bp, &count);
- if (count == 0)
- return;
- break;
- case XFS_DA_NODE_MAGIC:
- lasthash = xfs_da_node_lasthash(blk->bp, &count);
- if (count == 0)
- return;
- break;
- }
- for (blk--, level--; level >= 0; blk--, level--) {
- node = blk->bp->data;
- ASSERT(be16_to_cpu(node->hdr.info.magic) == XFS_DA_NODE_MAGIC);
- btree = &node->btree[ blk->index ];
- if (be32_to_cpu(btree->hashval) == lasthash)
- break;
- blk->hashval = lasthash;
- btree->hashval = cpu_to_be32(lasthash);
- xfs_da_log_buf(state->args->trans, blk->bp,
- XFS_DA_LOGRANGE(node, btree, sizeof(*btree)));
-
- lasthash = be32_to_cpu(node->btree[be16_to_cpu(node->hdr.count)-1].hashval);
- }
-}
-
-/*
- * Remove an entry from an intermediate node.
- */
-STATIC void
-xfs_da_node_remove(xfs_da_state_t *state, xfs_da_state_blk_t *drop_blk)
-{
- xfs_da_intnode_t *node;
- xfs_da_node_entry_t *btree;
- int tmp;
-
- node = drop_blk->bp->data;
- ASSERT(drop_blk->index < be16_to_cpu(node->hdr.count));
- ASSERT(drop_blk->index >= 0);
-
- /*
- * Copy over the offending entry, or just zero it out.
- */
- btree = &node->btree[drop_blk->index];
- if (drop_blk->index < (be16_to_cpu(node->hdr.count)-1)) {
- tmp = be16_to_cpu(node->hdr.count) - drop_blk->index - 1;
- tmp *= (uint)sizeof(xfs_da_node_entry_t);
- memmove(btree, btree + 1, tmp);
- xfs_da_log_buf(state->args->trans, drop_blk->bp,
- XFS_DA_LOGRANGE(node, btree, tmp));
- btree = &node->btree[be16_to_cpu(node->hdr.count)-1];
- }
- memset((char *)btree, 0, sizeof(xfs_da_node_entry_t));
- xfs_da_log_buf(state->args->trans, drop_blk->bp,
- XFS_DA_LOGRANGE(node, btree, sizeof(*btree)));
- be16_add(&node->hdr.count, -1);
- xfs_da_log_buf(state->args->trans, drop_blk->bp,
- XFS_DA_LOGRANGE(node, &node->hdr, sizeof(node->hdr)));
-
- /*
- * Copy the last hash value from the block to propagate upwards.
- */
- btree--;
- drop_blk->hashval = be32_to_cpu(btree->hashval);
-}
-
-/*
- * Unbalance the btree elements between two intermediate nodes,
- * move all Btree elements from one node into another.
- */
-STATIC void
-xfs_da_node_unbalance(xfs_da_state_t *state, xfs_da_state_blk_t *drop_blk,
- xfs_da_state_blk_t *save_blk)
-{
- xfs_da_intnode_t *drop_node, *save_node;
- xfs_da_node_entry_t *btree;
- int tmp;
- xfs_trans_t *tp;
-
- drop_node = drop_blk->bp->data;
- save_node = save_blk->bp->data;
- ASSERT(be16_to_cpu(drop_node->hdr.info.magic) == XFS_DA_NODE_MAGIC);
- ASSERT(be16_to_cpu(save_node->hdr.info.magic) == XFS_DA_NODE_MAGIC);
- tp = state->args->trans;
-
- /*
- * If the dying block has lower hashvals, then move all the
- * elements in the remaining block up to make a hole.
- */
- if ((be32_to_cpu(drop_node->btree[0].hashval) < be32_to_cpu(save_node->btree[ 0 ].hashval)) ||
- (be32_to_cpu(drop_node->btree[be16_to_cpu(drop_node->hdr.count)-1].hashval) <
- be32_to_cpu(save_node->btree[be16_to_cpu(save_node->hdr.count)-1].hashval)))
- {
- btree = &save_node->btree[be16_to_cpu(drop_node->hdr.count)];
- tmp = be16_to_cpu(save_node->hdr.count) * (uint)sizeof(xfs_da_node_entry_t);
- memmove(btree, &save_node->btree[0], tmp);
- btree = &save_node->btree[0];
- xfs_da_log_buf(tp, save_blk->bp,
- XFS_DA_LOGRANGE(save_node, btree,
- (be16_to_cpu(save_node->hdr.count) + be16_to_cpu(drop_node->hdr.count)) *
- sizeof(xfs_da_node_entry_t)));
- } else {
- btree = &save_node->btree[be16_to_cpu(save_node->hdr.count)];
- xfs_da_log_buf(tp, save_blk->bp,
- XFS_DA_LOGRANGE(save_node, btree,
- be16_to_cpu(drop_node->hdr.count) *
- sizeof(xfs_da_node_entry_t)));
- }
-
- /*
- * Move all the B-tree elements from drop_blk to save_blk.
- */
- tmp = be16_to_cpu(drop_node->hdr.count) * (uint)sizeof(xfs_da_node_entry_t);
- memcpy(btree, &drop_node->btree[0], tmp);
- be16_add(&save_node->hdr.count, be16_to_cpu(drop_node->hdr.count));
-
- xfs_da_log_buf(tp, save_blk->bp,
- XFS_DA_LOGRANGE(save_node, &save_node->hdr,
- sizeof(save_node->hdr)));
-
- /*
- * Save the last hashval in the remaining block for upward propagation.
- */
- save_blk->hashval = be32_to_cpu(save_node->btree[be16_to_cpu(save_node->hdr.count)-1].hashval);
-}
-
-/*========================================================================
- * Routines used for finding things in the Btree.
- *========================================================================*/
-
-/*
- * Walk down the Btree looking for a particular filename, filling
- * in the state structure as we go.
- *
- * We will set the state structure to point to each of the elements
- * in each of the nodes where either the hashval is or should be.
- *
- * We support duplicate hashval's so for each entry in the current
- * node that could contain the desired hashval, descend. This is a
- * pruned depth-first tree search.
- */
-int /* error */
-xfs_da_node_lookup_int(xfs_da_state_t *state, int *result)
-{
- xfs_da_state_blk_t *blk;
- xfs_da_blkinfo_t *curr;
- xfs_da_intnode_t *node;
- xfs_da_node_entry_t *btree;
- xfs_dablk_t blkno;
- int probe, span, max, error, retval;
- xfs_dahash_t hashval;
- xfs_da_args_t *args;
-
- args = state->args;
-
- /*
- * Descend thru the B-tree searching each level for the right
- * node to use, until the right hashval is found.
- */
- if (args->whichfork == XFS_DATA_FORK && XFS_DIR_IS_V2(state->mp))
- blkno = state->mp->m_dirleafblk;
- else
- blkno = 0;
- for (blk = &state->path.blk[0], state->path.active = 1;
- state->path.active <= XFS_DA_NODE_MAXDEPTH;
- blk++, state->path.active++) {
- /*
- * Read the next node down in the tree.
- */
- blk->blkno = blkno;
- error = xfs_da_read_buf(args->trans, args->dp, blkno,
- -1, &blk->bp, args->whichfork);
- if (error) {
- blk->blkno = 0;
- state->path.active--;
- return(error);
- }
- curr = blk->bp->data;
- ASSERT(be16_to_cpu(curr->magic) == XFS_DA_NODE_MAGIC ||
- be16_to_cpu(curr->magic) == XFS_DIRX_LEAF_MAGIC(state->mp) ||
- be16_to_cpu(curr->magic) == XFS_ATTR_LEAF_MAGIC);
-
- /*
- * Search an intermediate node for a match.
- */
- blk->magic = be16_to_cpu(curr->magic);
- if (blk->magic == XFS_DA_NODE_MAGIC) {
- node = blk->bp->data;
- blk->hashval = be32_to_cpu(node->btree[be16_to_cpu(node->hdr.count)-1].hashval);
-
- /*
- * Binary search. (note: small blocks will skip loop)
- */
- max = be16_to_cpu(node->hdr.count);
- probe = span = max / 2;
- hashval = args->hashval;
- for (btree = &node->btree[probe]; span > 4;
- btree = &node->btree[probe]) {
- span /= 2;
- if (be32_to_cpu(btree->hashval) < hashval)
- probe += span;
- else if (be32_to_cpu(btree->hashval) > hashval)
- probe -= span;
- else
- break;
- }
- ASSERT((probe >= 0) && (probe < max));
- ASSERT((span <= 4) || (be32_to_cpu(btree->hashval) == hashval));
-
- /*
- * Since we may have duplicate hashval's, find the first
- * matching hashval in the node.
- */
- while ((probe > 0) && (be32_to_cpu(btree->hashval) >= hashval)) {
- btree--;
- probe--;
- }
- while ((probe < max) && (be32_to_cpu(btree->hashval) < hashval)) {
- btree++;
- probe++;
- }
-
- /*
- * Pick the right block to descend on.
- */
- if (probe == max) {
- blk->index = max-1;
- blkno = be32_to_cpu(node->btree[max-1].before);
- } else {
- blk->index = probe;
- blkno = be32_to_cpu(btree->before);
- }
- }
- else if (be16_to_cpu(curr->magic) == XFS_ATTR_LEAF_MAGIC) {
- blk->hashval = xfs_attr_leaf_lasthash(blk->bp, NULL);
- break;
- }
- else if (be16_to_cpu(curr->magic) == XFS_DIR_LEAF_MAGIC) {
- blk->hashval = xfs_dir_leaf_lasthash(blk->bp, NULL);
- break;
- }
- else if (be16_to_cpu(curr->magic) == XFS_DIR2_LEAFN_MAGIC) {
- blk->hashval = xfs_dir2_leafn_lasthash(blk->bp, NULL);
- break;
- }
- }
-
- /*
- * A leaf block that ends in the hashval that we are interested in
- * (final hashval == search hashval) means that the next block may
- * contain more entries with the same hashval, shift upward to the
- * next leaf and keep searching.
- */
- for (;;) {
- if (blk->magic == XFS_DIR_LEAF_MAGIC) {
- ASSERT(XFS_DIR_IS_V1(state->mp));
- retval = xfs_dir_leaf_lookup_int(blk->bp, args,
- &blk->index);
- } else if (blk->magic == XFS_DIR2_LEAFN_MAGIC) {
- ASSERT(XFS_DIR_IS_V2(state->mp));
- retval = xfs_dir2_leafn_lookup_int(blk->bp, args,
- &blk->index, state);
- }
- else if (blk->magic == XFS_ATTR_LEAF_MAGIC) {
- retval = xfs_attr_leaf_lookup_int(blk->bp, args);
- blk->index = args->index;
- args->blkno = blk->blkno;
- }
- if (((retval == ENOENT) || (retval == ENOATTR)) &&
- (blk->hashval == args->hashval)) {
- error = xfs_da_path_shift(state, &state->path, 1, 1,
- &retval);
- if (error)
- return(error);
- if (retval == 0) {
- continue;
- }
- else if (blk->magic == XFS_ATTR_LEAF_MAGIC) {
- /* path_shift() gives ENOENT */
- retval = XFS_ERROR(ENOATTR);
- }
- }
- break;
- }
- *result = retval;
- return(0);
-}
-
-/*========================================================================
- * Utility routines.
- *========================================================================*/
-
-/*
- * Link a new block into a doubly linked list of blocks (of whatever type).
- */
-int /* error */
-xfs_da_blk_link(xfs_da_state_t *state, xfs_da_state_blk_t *old_blk,
- xfs_da_state_blk_t *new_blk)
-{
- xfs_da_blkinfo_t *old_info, *new_info, *tmp_info;
- xfs_da_args_t *args;
- int before=0, error;
- xfs_dabuf_t *bp;
-
- /*
- * Set up environment.
- */
- args = state->args;
- ASSERT(args != NULL);
- old_info = old_blk->bp->data;
- new_info = new_blk->bp->data;
- ASSERT(old_blk->magic == XFS_DA_NODE_MAGIC ||
- old_blk->magic == XFS_DIRX_LEAF_MAGIC(state->mp) ||
- old_blk->magic == XFS_ATTR_LEAF_MAGIC);
- ASSERT(old_blk->magic == be16_to_cpu(old_info->magic));
- ASSERT(new_blk->magic == be16_to_cpu(new_info->magic));
- ASSERT(old_blk->magic == new_blk->magic);
-
- switch (old_blk->magic) {
- case XFS_ATTR_LEAF_MAGIC:
- before = xfs_attr_leaf_order(old_blk->bp, new_blk->bp);
- break;
- case XFS_DIR_LEAF_MAGIC:
- ASSERT(XFS_DIR_IS_V1(state->mp));
- before = xfs_dir_leaf_order(old_blk->bp, new_blk->bp);
- break;
- case XFS_DIR2_LEAFN_MAGIC:
- ASSERT(XFS_DIR_IS_V2(state->mp));
- before = xfs_dir2_leafn_order(old_blk->bp, new_blk->bp);
- break;
- case XFS_DA_NODE_MAGIC:
- before = xfs_da_node_order(old_blk->bp, new_blk->bp);
- break;
- }
-
- /*
- * Link blocks in appropriate order.
- */
- if (before) {
- /*
- * Link new block in before existing block.
- */
- new_info->forw = cpu_to_be32(old_blk->blkno);
- new_info->back = old_info->back;
- if (old_info->back) {
- error = xfs_da_read_buf(args->trans, args->dp,
- be32_to_cpu(old_info->back),
- -1, &bp, args->whichfork);
- if (error)
- return(error);
- ASSERT(bp != NULL);
- tmp_info = bp->data;
- ASSERT(be16_to_cpu(tmp_info->magic) == be16_to_cpu(old_info->magic));
- ASSERT(be32_to_cpu(tmp_info->forw) == old_blk->blkno);
- tmp_info->forw = cpu_to_be32(new_blk->blkno);
- xfs_da_log_buf(args->trans, bp, 0, sizeof(*tmp_info)-1);
- xfs_da_buf_done(bp);
- }
- old_info->back = cpu_to_be32(new_blk->blkno);
- } else {
- /*
- * Link new block in after existing block.
- */
- new_info->forw = old_info->forw;
- new_info->back = cpu_to_be32(old_blk->blkno);
- if (old_info->forw) {
- error = xfs_da_read_buf(args->trans, args->dp,
- be32_to_cpu(old_info->forw),
- -1, &bp, args->whichfork);
- if (error)
- return(error);
- ASSERT(bp != NULL);
- tmp_info = bp->data;
- ASSERT(tmp_info->magic == old_info->magic);
- ASSERT(be32_to_cpu(tmp_info->back) == old_blk->blkno);
- tmp_info->back = cpu_to_be32(new_blk->blkno);
- xfs_da_log_buf(args->trans, bp, 0, sizeof(*tmp_info)-1);
- xfs_da_buf_done(bp);
- }
- old_info->forw = cpu_to_be32(new_blk->blkno);
- }
-
- xfs_da_log_buf(args->trans, old_blk->bp, 0, sizeof(*tmp_info) - 1);
- xfs_da_log_buf(args->trans, new_blk->bp, 0, sizeof(*tmp_info) - 1);
- return(0);
-}
-
-/*
- * Compare two intermediate nodes for "order".
- */
-STATIC int
-xfs_da_node_order(xfs_dabuf_t *node1_bp, xfs_dabuf_t *node2_bp)
-{
- xfs_da_intnode_t *node1, *node2;
-
- node1 = node1_bp->data;
- node2 = node2_bp->data;
- ASSERT((be16_to_cpu(node1->hdr.info.magic) == XFS_DA_NODE_MAGIC) &&
- (be16_to_cpu(node2->hdr.info.magic) == XFS_DA_NODE_MAGIC));
- if ((be16_to_cpu(node1->hdr.count) > 0) && (be16_to_cpu(node2->hdr.count) > 0) &&
- ((be32_to_cpu(node2->btree[0].hashval) <
- be32_to_cpu(node1->btree[0].hashval)) ||
- (be32_to_cpu(node2->btree[be16_to_cpu(node2->hdr.count)-1].hashval) <
- be32_to_cpu(node1->btree[be16_to_cpu(node1->hdr.count)-1].hashval)))) {
- return(1);
- }
- return(0);
-}
-
-/*
- * Pick up the last hashvalue from an intermediate node.
- */
-STATIC uint
-xfs_da_node_lasthash(xfs_dabuf_t *bp, int *count)
-{
- xfs_da_intnode_t *node;
-
- node = bp->data;
- ASSERT(be16_to_cpu(node->hdr.info.magic) == XFS_DA_NODE_MAGIC);
- if (count)
- *count = be16_to_cpu(node->hdr.count);
- if (!node->hdr.count)
- return(0);
- return be32_to_cpu(node->btree[be16_to_cpu(node->hdr.count)-1].hashval);
-}
-
-/*
- * Unlink a block from a doubly linked list of blocks.
- */
-STATIC int /* error */
-xfs_da_blk_unlink(xfs_da_state_t *state, xfs_da_state_blk_t *drop_blk,
- xfs_da_state_blk_t *save_blk)
-{
- xfs_da_blkinfo_t *drop_info, *save_info, *tmp_info;
- xfs_da_args_t *args;
- xfs_dabuf_t *bp;
- int error;
-
- /*
- * Set up environment.
- */
- args = state->args;
- ASSERT(args != NULL);
- save_info = save_blk->bp->data;
- drop_info = drop_blk->bp->data;
- ASSERT(save_blk->magic == XFS_DA_NODE_MAGIC ||
- save_blk->magic == XFS_DIRX_LEAF_MAGIC(state->mp) ||
- save_blk->magic == XFS_ATTR_LEAF_MAGIC);
- ASSERT(save_blk->magic == be16_to_cpu(save_info->magic));
- ASSERT(drop_blk->magic == be16_to_cpu(drop_info->magic));
- ASSERT(save_blk->magic == drop_blk->magic);
- ASSERT((be32_to_cpu(save_info->forw) == drop_blk->blkno) ||
- (be32_to_cpu(save_info->back) == drop_blk->blkno));
- ASSERT((be32_to_cpu(drop_info->forw) == save_blk->blkno) ||
- (be32_to_cpu(drop_info->back) == save_blk->blkno));
-
- /*
- * Unlink the leaf block from the doubly linked chain of leaves.
- */
- if (be32_to_cpu(save_info->back) == drop_blk->blkno) {
- save_info->back = drop_info->back;
- if (drop_info->back) {
- error = xfs_da_read_buf(args->trans, args->dp,
- be32_to_cpu(drop_info->back),
- -1, &bp, args->whichfork);
- if (error)
- return(error);
- ASSERT(bp != NULL);
- tmp_info = bp->data;
- ASSERT(tmp_info->magic == save_info->magic);
- ASSERT(be32_to_cpu(tmp_info->forw) == drop_blk->blkno);
- tmp_info->forw = cpu_to_be32(save_blk->blkno);
- xfs_da_log_buf(args->trans, bp, 0,
- sizeof(*tmp_info) - 1);
- xfs_da_buf_done(bp);
- }
- } else {
- save_info->forw = drop_info->forw;
- if (drop_info->forw) {
- error = xfs_da_read_buf(args->trans, args->dp,
- be32_to_cpu(drop_info->forw),
- -1, &bp, args->whichfork);
- if (error)
- return(error);
- ASSERT(bp != NULL);
- tmp_info = bp->data;
- ASSERT(tmp_info->magic == save_info->magic);
- ASSERT(be32_to_cpu(tmp_info->back) == drop_blk->blkno);
- tmp_info->back = cpu_to_be32(save_blk->blkno);
- xfs_da_log_buf(args->trans, bp, 0,
- sizeof(*tmp_info) - 1);
- xfs_da_buf_done(bp);
- }
- }
-
- xfs_da_log_buf(args->trans, save_blk->bp, 0, sizeof(*save_info) - 1);
- return(0);
-}
-
-/*
- * Move a path "forward" or "!forward" one block at the current level.
- *
- * This routine will adjust a "path" to point to the next block
- * "forward" (higher hashvalues) or "!forward" (lower hashvals) in the
- * Btree, including updating pointers to the intermediate nodes between
- * the new bottom and the root.
- */
-int /* error */
-xfs_da_path_shift(xfs_da_state_t *state, xfs_da_state_path_t *path,
- int forward, int release, int *result)
-{
- xfs_da_state_blk_t *blk;
- xfs_da_blkinfo_t *info;
- xfs_da_intnode_t *node;
- xfs_da_args_t *args;
- xfs_dablk_t blkno=0;
- int level, error;
-
- /*
- * Roll up the Btree looking for the first block where our
- * current index is not at the edge of the block. Note that
- * we skip the bottom layer because we want the sibling block.
- */
- args = state->args;
- ASSERT(args != NULL);
- ASSERT(path != NULL);
- ASSERT((path->active > 0) && (path->active < XFS_DA_NODE_MAXDEPTH));
- level = (path->active-1) - 1; /* skip bottom layer in path */
- for (blk = &path->blk[level]; level >= 0; blk--, level--) {
- ASSERT(blk->bp != NULL);
- node = blk->bp->data;
- ASSERT(be16_to_cpu(node->hdr.info.magic) == XFS_DA_NODE_MAGIC);
- if (forward && (blk->index < be16_to_cpu(node->hdr.count)-1)) {
- blk->index++;
- blkno = be32_to_cpu(node->btree[blk->index].before);
- break;
- } else if (!forward && (blk->index > 0)) {
- blk->index--;
- blkno = be32_to_cpu(node->btree[blk->index].before);
- break;
- }
- }
- if (level < 0) {
- *result = XFS_ERROR(ENOENT); /* we're out of our tree */
- ASSERT(args->oknoent);
- return(0);
- }
-
- /*
- * Roll down the edge of the subtree until we reach the
- * same depth we were at originally.
- */
- for (blk++, level++; level < path->active; blk++, level++) {
- /*
- * Release the old block.
- * (if it's dirty, trans won't actually let go)
- */
- if (release)
- xfs_da_brelse(args->trans, blk->bp);
-
- /*
- * Read the next child block.
- */
- blk->blkno = blkno;
- error = xfs_da_read_buf(args->trans, args->dp, blkno, -1,
- &blk->bp, args->whichfork);
- if (error)
- return(error);
- ASSERT(blk->bp != NULL);
- info = blk->bp->data;
- ASSERT(be16_to_cpu(info->magic) == XFS_DA_NODE_MAGIC ||
- be16_to_cpu(info->magic) == XFS_DIRX_LEAF_MAGIC(state->mp) ||
- be16_to_cpu(info->magic) == XFS_ATTR_LEAF_MAGIC);
- blk->magic = be16_to_cpu(info->magic);
- if (blk->magic == XFS_DA_NODE_MAGIC) {
- node = (xfs_da_intnode_t *)info;
- blk->hashval = be32_to_cpu(node->btree[be16_to_cpu(node->hdr.count)-1].hashval);
- if (forward)
- blk->index = 0;
- else
- blk->index = be16_to_cpu(node->hdr.count)-1;
- blkno = be32_to_cpu(node->btree[blk->index].before);
- } else {
- ASSERT(level == path->active-1);
- blk->index = 0;
- switch(blk->magic) {
- case XFS_ATTR_LEAF_MAGIC:
- blk->hashval = xfs_attr_leaf_lasthash(blk->bp,
- NULL);
- break;
- case XFS_DIR_LEAF_MAGIC:
- ASSERT(XFS_DIR_IS_V1(state->mp));
- blk->hashval = xfs_dir_leaf_lasthash(blk->bp,
- NULL);
- break;
- case XFS_DIR2_LEAFN_MAGIC:
- ASSERT(XFS_DIR_IS_V2(state->mp));
- blk->hashval = xfs_dir2_leafn_lasthash(blk->bp,
- NULL);
- break;
- default:
- ASSERT(blk->magic == XFS_ATTR_LEAF_MAGIC ||
- blk->magic ==
- XFS_DIRX_LEAF_MAGIC(state->mp));
- break;
- }
- }
- }
- *result = 0;
- return(0);
-}
-
-
-/*========================================================================
- * Utility routines.
- *========================================================================*/
-
-/*
- * Implement a simple hash on a character string.
- * Rotate the hash value by 7 bits, then XOR each character in.
- * This is implemented with some source-level loop unrolling.
- */
-xfs_dahash_t
-xfs_da_hashname(const uchar_t *name, int namelen)
-{
- xfs_dahash_t hash;
-
- /*
- * Do four characters at a time as long as we can.
- */
- for (hash = 0; namelen >= 4; namelen -= 4, name += 4)
- hash = (name[0] << 21) ^ (name[1] << 14) ^ (name[2] << 7) ^
- (name[3] << 0) ^ rol32(hash, 7 * 4);
-
- /*
- * Now do the rest of the characters.
- */
- switch (namelen) {
- case 3:
- return (name[0] << 14) ^ (name[1] << 7) ^ (name[2] << 0) ^
- rol32(hash, 7 * 3);
- case 2:
- return (name[0] << 7) ^ (name[1] << 0) ^ rol32(hash, 7 * 2);
- case 1:
- return (name[0] << 0) ^ rol32(hash, 7 * 1);
- default: /* case 0: */
- return hash;
- }
-}
-
-/*
- * Add a block to the btree ahead of the file.
- * Return the new block number to the caller.
- */
-int
-xfs_da_grow_inode(xfs_da_args_t *args, xfs_dablk_t *new_blkno)
-{
- xfs_fileoff_t bno, b;
- xfs_bmbt_irec_t map;
- xfs_bmbt_irec_t *mapp;
- xfs_inode_t *dp;
- int nmap, error, w, count, c, got, i, mapi;
- xfs_fsize_t size;
- xfs_trans_t *tp;
- xfs_mount_t *mp;
-
- dp = args->dp;
- mp = dp->i_mount;
- w = args->whichfork;
- tp = args->trans;
- /*
- * For new directories adjust the file offset and block count.
- */
- if (w == XFS_DATA_FORK && XFS_DIR_IS_V2(mp)) {
- bno = mp->m_dirleafblk;
- count = mp->m_dirblkfsbs;
- } else {
- bno = 0;
- count = 1;
- }
- /*
- * Find a spot in the file space to put the new block.
- */
- if ((error = xfs_bmap_first_unused(tp, dp, count, &bno, w))) {
- return error;
- }
- if (w == XFS_DATA_FORK && XFS_DIR_IS_V2(mp))
- ASSERT(bno >= mp->m_dirleafblk && bno < mp->m_dirfreeblk);
- /*
- * Try mapping it in one filesystem block.
- */
- nmap = 1;
- ASSERT(args->firstblock != NULL);
- if ((error = xfs_bmapi(tp, dp, bno, count,
- XFS_BMAPI_AFLAG(w)|XFS_BMAPI_WRITE|XFS_BMAPI_METADATA|
- XFS_BMAPI_CONTIG,
- args->firstblock, args->total, &map, &nmap,
- args->flist, NULL))) {
- return error;
- }
- ASSERT(nmap <= 1);
- if (nmap == 1) {
- mapp = &map;
- mapi = 1;
- }
- /*
- * If we didn't get it and the block might work if fragmented,
- * try without the CONTIG flag. Loop until we get it all.
- */
- else if (nmap == 0 && count > 1) {
- mapp = kmem_alloc(sizeof(*mapp) * count, KM_SLEEP);
- for (b = bno, mapi = 0; b < bno + count; ) {
- nmap = MIN(XFS_BMAP_MAX_NMAP, count);
- c = (int)(bno + count - b);
- if ((error = xfs_bmapi(tp, dp, b, c,
- XFS_BMAPI_AFLAG(w)|XFS_BMAPI_WRITE|
- XFS_BMAPI_METADATA,
- args->firstblock, args->total,
- &mapp[mapi], &nmap, args->flist,
- NULL))) {
- kmem_free(mapp, sizeof(*mapp) * count);
- return error;
- }
- if (nmap < 1)
- break;
- mapi += nmap;
- b = mapp[mapi - 1].br_startoff +
- mapp[mapi - 1].br_blockcount;
- }
- } else {
- mapi = 0;
- mapp = NULL;
- }
- /*
- * Count the blocks we got, make sure it matches the total.
- */
- for (i = 0, got = 0; i < mapi; i++)
- got += mapp[i].br_blockcount;
- if (got != count || mapp[0].br_startoff != bno ||
- mapp[mapi - 1].br_startoff + mapp[mapi - 1].br_blockcount !=
- bno + count) {
- if (mapp != &map)
- kmem_free(mapp, sizeof(*mapp) * count);
- return XFS_ERROR(ENOSPC);
- }
- if (mapp != &map)
- kmem_free(mapp, sizeof(*mapp) * count);
- *new_blkno = (xfs_dablk_t)bno;
- /*
- * For version 1 directories, adjust the file size if it changed.
- */
- if (w == XFS_DATA_FORK && XFS_DIR_IS_V1(mp)) {
- ASSERT(mapi == 1);
- if ((error = xfs_bmap_last_offset(tp, dp, &bno, w)))
- return error;
- size = XFS_FSB_TO_B(mp, bno);
- if (size != dp->i_d.di_size) {
- dp->i_d.di_size = size;
- xfs_trans_log_inode(tp, dp, XFS_ILOG_CORE);
- }
- }
- return 0;
-}
-
-/*
- * Ick. We need to always be able to remove a btree block, even
- * if there's no space reservation because the filesystem is full.
- * This is called if xfs_bunmapi on a btree block fails due to ENOSPC.
- * It swaps the target block with the last block in the file. The
- * last block in the file can always be removed since it can't cause
- * a bmap btree split to do that.
- */
-STATIC int
-xfs_da_swap_lastblock(xfs_da_args_t *args, xfs_dablk_t *dead_blknop,
- xfs_dabuf_t **dead_bufp)
-{
- xfs_dablk_t dead_blkno, last_blkno, sib_blkno, par_blkno;
- xfs_dabuf_t *dead_buf, *last_buf, *sib_buf, *par_buf;
- xfs_fileoff_t lastoff;
- xfs_inode_t *ip;
- xfs_trans_t *tp;
- xfs_mount_t *mp;
- int error, w, entno, level, dead_level;
- xfs_da_blkinfo_t *dead_info, *sib_info;
- xfs_da_intnode_t *par_node, *dead_node;
- xfs_dir_leafblock_t *dead_leaf;
- xfs_dir2_leaf_t *dead_leaf2;
- xfs_dahash_t dead_hash;
-
- dead_buf = *dead_bufp;
- dead_blkno = *dead_blknop;
- tp = args->trans;
- ip = args->dp;
- w = args->whichfork;
- ASSERT(w == XFS_DATA_FORK);
- mp = ip->i_mount;
- if (XFS_DIR_IS_V2(mp)) {
- lastoff = mp->m_dirfreeblk;
- error = xfs_bmap_last_before(tp, ip, &lastoff, w);
- } else
- error = xfs_bmap_last_offset(tp, ip, &lastoff, w);
- if (error)
- return error;
- if (unlikely(lastoff == 0)) {
- XFS_ERROR_REPORT("xfs_da_swap_lastblock(1)", XFS_ERRLEVEL_LOW,
- mp);
- return XFS_ERROR(EFSCORRUPTED);
- }
- /*
- * Read the last block in the btree space.
- */
- last_blkno = (xfs_dablk_t)lastoff - mp->m_dirblkfsbs;
- if ((error = xfs_da_read_buf(tp, ip, last_blkno, -1, &last_buf, w)))
- return error;
- /*
- * Copy the last block into the dead buffer and log it.
- */
- memcpy(dead_buf->data, last_buf->data, mp->m_dirblksize);
- xfs_da_log_buf(tp, dead_buf, 0, mp->m_dirblksize - 1);
- dead_info = dead_buf->data;
- /*
- * Get values from the moved block.
- */
- if (be16_to_cpu(dead_info->magic) == XFS_DIR_LEAF_MAGIC) {
- ASSERT(XFS_DIR_IS_V1(mp));
- dead_leaf = (xfs_dir_leafblock_t *)dead_info;
- dead_level = 0;
- dead_hash =
- INT_GET(dead_leaf->entries[INT_GET(dead_leaf->hdr.count, ARCH_CONVERT) - 1].hashval, ARCH_CONVERT);
- } else if (be16_to_cpu(dead_info->magic) == XFS_DIR2_LEAFN_MAGIC) {
- ASSERT(XFS_DIR_IS_V2(mp));
- dead_leaf2 = (xfs_dir2_leaf_t *)dead_info;
- dead_level = 0;
- dead_hash = be32_to_cpu(dead_leaf2->ents[be16_to_cpu(dead_leaf2->hdr.count) - 1].hashval);
- } else {
- ASSERT(be16_to_cpu(dead_info->magic) == XFS_DA_NODE_MAGIC);
- dead_node = (xfs_da_intnode_t *)dead_info;
- dead_level = be16_to_cpu(dead_node->hdr.level);
- dead_hash = be32_to_cpu(dead_node->btree[be16_to_cpu(dead_node->hdr.count) - 1].hashval);
- }
- sib_buf = par_buf = NULL;
- /*
- * If the moved block has a left sibling, fix up the pointers.
- */
- if ((sib_blkno = be32_to_cpu(dead_info->back))) {
- if ((error = xfs_da_read_buf(tp, ip, sib_blkno, -1, &sib_buf, w)))
- goto done;
- sib_info = sib_buf->data;
- if (unlikely(
- be32_to_cpu(sib_info->forw) != last_blkno ||
- sib_info->magic != dead_info->magic)) {
- XFS_ERROR_REPORT("xfs_da_swap_lastblock(2)",
- XFS_ERRLEVEL_LOW, mp);
- error = XFS_ERROR(EFSCORRUPTED);
- goto done;
- }
- sib_info->forw = cpu_to_be32(dead_blkno);
- xfs_da_log_buf(tp, sib_buf,
- XFS_DA_LOGRANGE(sib_info, &sib_info->forw,
- sizeof(sib_info->forw)));
- xfs_da_buf_done(sib_buf);
- sib_buf = NULL;
- }
- /*
- * If the moved block has a right sibling, fix up the pointers.
- */
- if ((sib_blkno = be32_to_cpu(dead_info->forw))) {
- if ((error = xfs_da_read_buf(tp, ip, sib_blkno, -1, &sib_buf, w)))
- goto done;
- sib_info = sib_buf->data;
- if (unlikely(
- be32_to_cpu(sib_info->back) != last_blkno ||
- sib_info->magic != dead_info->magic)) {
- XFS_ERROR_REPORT("xfs_da_swap_lastblock(3)",
- XFS_ERRLEVEL_LOW, mp);
- error = XFS_ERROR(EFSCORRUPTED);
- goto done;
- }
- sib_info->back = cpu_to_be32(dead_blkno);
- xfs_da_log_buf(tp, sib_buf,
- XFS_DA_LOGRANGE(sib_info, &sib_info->back,
- sizeof(sib_info->back)));
- xfs_da_buf_done(sib_buf);
- sib_buf = NULL;
- }
- par_blkno = XFS_DIR_IS_V1(mp) ? 0 : mp->m_dirleafblk;
- level = -1;
- /*
- * Walk down the tree looking for the parent of the moved block.
- */
- for (;;) {
- if ((error = xfs_da_read_buf(tp, ip, par_blkno, -1, &par_buf, w)))
- goto done;
- par_node = par_buf->data;
- if (unlikely(
- be16_to_cpu(par_node->hdr.info.magic) != XFS_DA_NODE_MAGIC ||
- (level >= 0 && level != be16_to_cpu(par_node->hdr.level) + 1))) {
- XFS_ERROR_REPORT("xfs_da_swap_lastblock(4)",
- XFS_ERRLEVEL_LOW, mp);
- error = XFS_ERROR(EFSCORRUPTED);
- goto done;
- }
- level = be16_to_cpu(par_node->hdr.level);
- for (entno = 0;
- entno < be16_to_cpu(par_node->hdr.count) &&
- be32_to_cpu(par_node->btree[entno].hashval) < dead_hash;
- entno++)
- continue;
- if (unlikely(entno == be16_to_cpu(par_node->hdr.count))) {
- XFS_ERROR_REPORT("xfs_da_swap_lastblock(5)",
- XFS_ERRLEVEL_LOW, mp);
- error = XFS_ERROR(EFSCORRUPTED);
- goto done;
- }
- par_blkno = be32_to_cpu(par_node->btree[entno].before);
- if (level == dead_level + 1)
- break;
- xfs_da_brelse(tp, par_buf);
- par_buf = NULL;
- }
- /*
- * We're in the right parent block.
- * Look for the right entry.
- */
- for (;;) {
- for (;
- entno < be16_to_cpu(par_node->hdr.count) &&
- be32_to_cpu(par_node->btree[entno].before) != last_blkno;
- entno++)
- continue;
- if (entno < be16_to_cpu(par_node->hdr.count))
- break;
- par_blkno = be32_to_cpu(par_node->hdr.info.forw);
- xfs_da_brelse(tp, par_buf);
- par_buf = NULL;
- if (unlikely(par_blkno == 0)) {
- XFS_ERROR_REPORT("xfs_da_swap_lastblock(6)",
- XFS_ERRLEVEL_LOW, mp);
- error = XFS_ERROR(EFSCORRUPTED);
- goto done;
- }
- if ((error = xfs_da_read_buf(tp, ip, par_blkno, -1, &par_buf, w)))
- goto done;
- par_node = par_buf->data;
- if (unlikely(
- be16_to_cpu(par_node->hdr.level) != level ||
- be16_to_cpu(par_node->hdr.info.magic) != XFS_DA_NODE_MAGIC)) {
- XFS_ERROR_REPORT("xfs_da_swap_lastblock(7)",
- XFS_ERRLEVEL_LOW, mp);
- error = XFS_ERROR(EFSCORRUPTED);
- goto done;
- }
- entno = 0;
- }
- /*
- * Update the parent entry pointing to the moved block.
- */
- par_node->btree[entno].before = cpu_to_be32(dead_blkno);
- xfs_da_log_buf(tp, par_buf,
- XFS_DA_LOGRANGE(par_node, &par_node->btree[entno].before,
- sizeof(par_node->btree[entno].before)));
- xfs_da_buf_done(par_buf);
- xfs_da_buf_done(dead_buf);
- *dead_blknop = last_blkno;
- *dead_bufp = last_buf;
- return 0;
-done:
- if (par_buf)
- xfs_da_brelse(tp, par_buf);
- if (sib_buf)
- xfs_da_brelse(tp, sib_buf);
- xfs_da_brelse(tp, last_buf);
- return error;
-}
-
-/*
- * Remove a btree block from a directory or attribute.
- */
-int
-xfs_da_shrink_inode(xfs_da_args_t *args, xfs_dablk_t dead_blkno,
- xfs_dabuf_t *dead_buf)
-{
- xfs_inode_t *dp;
- int done, error, w, count;
- xfs_fileoff_t bno;
- xfs_fsize_t size;
- xfs_trans_t *tp;
- xfs_mount_t *mp;
-
- dp = args->dp;
- w = args->whichfork;
- tp = args->trans;
- mp = dp->i_mount;
- if (w == XFS_DATA_FORK && XFS_DIR_IS_V2(mp))
- count = mp->m_dirblkfsbs;
- else
- count = 1;
- for (;;) {
- /*
- * Remove extents. If we get ENOSPC for a dir we have to move
- * the last block to the place we want to kill.
- */
- if ((error = xfs_bunmapi(tp, dp, dead_blkno, count,
- XFS_BMAPI_AFLAG(w)|XFS_BMAPI_METADATA,
- 0, args->firstblock, args->flist, NULL,
- &done)) == ENOSPC) {
- if (w != XFS_DATA_FORK)
- goto done;
- if ((error = xfs_da_swap_lastblock(args, &dead_blkno,
- &dead_buf)))
- goto done;
- } else if (error)
- goto done;
- else
- break;
- }
- ASSERT(done);
- xfs_da_binval(tp, dead_buf);
- /*
- * Adjust the directory size for version 1.
- */
- if (w == XFS_DATA_FORK && XFS_DIR_IS_V1(mp)) {
- if ((error = xfs_bmap_last_offset(tp, dp, &bno, w)))
- return error;
- size = XFS_FSB_TO_B(dp->i_mount, bno);
- if (size != dp->i_d.di_size) {
- dp->i_d.di_size = size;
- xfs_trans_log_inode(tp, dp, XFS_ILOG_CORE);
- }
- }
- return 0;
-done:
- xfs_da_binval(tp, dead_buf);
- return error;
-}
-
-/*
- * See if the mapping(s) for this btree block are valid, i.e.
- * don't contain holes, are logically contiguous, and cover the whole range.
- */
-STATIC int
-xfs_da_map_covers_blocks(
- int nmap,
- xfs_bmbt_irec_t *mapp,
- xfs_dablk_t bno,
- int count)
-{
- int i;
- xfs_fileoff_t off;
-
- for (i = 0, off = bno; i < nmap; i++) {
- if (mapp[i].br_startblock == HOLESTARTBLOCK ||
- mapp[i].br_startblock == DELAYSTARTBLOCK) {
- return 0;
- }
- if (off != mapp[i].br_startoff) {
- return 0;
- }
- off += mapp[i].br_blockcount;
- }
- return off == bno + count;
-}
-
-/*
- * Make a dabuf.
- * Used for get_buf, read_buf, read_bufr, and reada_buf.
- */
-STATIC int
-xfs_da_do_buf(
- xfs_trans_t *trans,
- xfs_inode_t *dp,
- xfs_dablk_t bno,
- xfs_daddr_t *mappedbnop,
- xfs_dabuf_t **bpp,
- int whichfork,
- int caller,
- inst_t *ra)
-{
- xfs_buf_t *bp = NULL;
- xfs_buf_t **bplist;
- int error=0;
- int i;
- xfs_bmbt_irec_t map;
- xfs_bmbt_irec_t *mapp;
- xfs_daddr_t mappedbno;
- xfs_mount_t *mp;
- int nbplist=0;
- int nfsb;
- int nmap;
- xfs_dabuf_t *rbp;
-
- mp = dp->i_mount;
- if (whichfork == XFS_DATA_FORK && XFS_DIR_IS_V2(mp))
- nfsb = mp->m_dirblkfsbs;
- else
- nfsb = 1;
- mappedbno = *mappedbnop;
- /*
- * Caller doesn't have a mapping. -2 means don't complain
- * if we land in a hole.
- */
- if (mappedbno == -1 || mappedbno == -2) {
- /*
- * Optimize the one-block case.
- */
- if (nfsb == 1) {
- xfs_fsblock_t fsb;
-
- if ((error =
- xfs_bmapi_single(trans, dp, whichfork, &fsb,
- (xfs_fileoff_t)bno))) {
- return error;
- }
- mapp = &map;
- if (fsb == NULLFSBLOCK) {
- nmap = 0;
- } else {
- map.br_startblock = fsb;
- map.br_startoff = (xfs_fileoff_t)bno;
- map.br_blockcount = 1;
- nmap = 1;
- }
- } else {
- mapp = kmem_alloc(sizeof(*mapp) * nfsb, KM_SLEEP);
- nmap = nfsb;
- if ((error = xfs_bmapi(trans, dp, (xfs_fileoff_t)bno,
- nfsb,
- XFS_BMAPI_METADATA |
- XFS_BMAPI_AFLAG(whichfork),
- NULL, 0, mapp, &nmap, NULL, NULL)))
- goto exit0;
- }
- } else {
- map.br_startblock = XFS_DADDR_TO_FSB(mp, mappedbno);
- map.br_startoff = (xfs_fileoff_t)bno;
- map.br_blockcount = nfsb;
- mapp = &map;
- nmap = 1;
- }
- if (!xfs_da_map_covers_blocks(nmap, mapp, bno, nfsb)) {
- error = mappedbno == -2 ? 0 : XFS_ERROR(EFSCORRUPTED);
- if (unlikely(error == EFSCORRUPTED)) {
- if (xfs_error_level >= XFS_ERRLEVEL_LOW) {
- int i;
- cmn_err(CE_ALERT, "xfs_da_do_buf: bno %lld\n",
- (long long)bno);
- cmn_err(CE_ALERT, "dir: inode %lld\n",
- (long long)dp->i_ino);
- for (i = 0; i < nmap; i++) {
- cmn_err(CE_ALERT,
- "[%02d] br_startoff %lld br_startblock %lld br_blockcount %lld br_state %d\n",
- i,
- (long long)mapp[i].br_startoff,
- (long long)mapp[i].br_startblock,
- (long long)mapp[i].br_blockcount,
- mapp[i].br_state);
- }
- }
- XFS_ERROR_REPORT("xfs_da_do_buf(1)",
- XFS_ERRLEVEL_LOW, mp);
- }
- goto exit0;
- }
- if (caller != 3 && nmap > 1) {
- bplist = kmem_alloc(sizeof(*bplist) * nmap, KM_SLEEP);
- nbplist = 0;
- } else
- bplist = NULL;
- /*
- * Turn the mapping(s) into buffer(s).
- */
- for (i = 0; i < nmap; i++) {
- int nmapped;
-
- mappedbno = XFS_FSB_TO_DADDR(mp, mapp[i].br_startblock);
- if (i == 0)
- *mappedbnop = mappedbno;
- nmapped = (int)XFS_FSB_TO_BB(mp, mapp[i].br_blockcount);
- switch (caller) {
- case 0:
- bp = xfs_trans_get_buf(trans, mp->m_ddev_targp,
- mappedbno, nmapped, 0);
- error = bp ? XFS_BUF_GETERROR(bp) : XFS_ERROR(EIO);
- break;
- case 1:
- case 2:
- bp = NULL;
- error = xfs_trans_read_buf(mp, trans, mp->m_ddev_targp,
- mappedbno, nmapped, 0, &bp);
- break;
- case 3:
- xfs_baread(mp->m_ddev_targp, mappedbno, nmapped);
- error = 0;
- bp = NULL;
- break;
- }
- if (error) {
- if (bp)
- xfs_trans_brelse(trans, bp);
- goto exit1;
- }
- if (!bp)
- continue;
- if (caller == 1) {
- if (whichfork == XFS_ATTR_FORK) {
- XFS_BUF_SET_VTYPE_REF(bp, B_FS_ATTR_BTREE,
- XFS_ATTR_BTREE_REF);
- } else {
- XFS_BUF_SET_VTYPE_REF(bp, B_FS_DIR_BTREE,
- XFS_DIR_BTREE_REF);
- }
- }
- if (bplist) {
- bplist[nbplist++] = bp;
- }
- }
- /*
- * Build a dabuf structure.
- */
- if (bplist) {
- rbp = xfs_da_buf_make(nbplist, bplist, ra);
- } else if (bp)
- rbp = xfs_da_buf_make(1, &bp, ra);
- else
- rbp = NULL;
- /*
- * For read_buf, check the magic number.
- */
- if (caller == 1) {
- xfs_dir2_data_t *data;
- xfs_dir2_free_t *free;
- xfs_da_blkinfo_t *info;
- uint magic, magic1;
-
- info = rbp->data;
- data = rbp->data;
- free = rbp->data;
- magic = be16_to_cpu(info->magic);
- magic1 = be32_to_cpu(data->hdr.magic);
- if (unlikely(
- XFS_TEST_ERROR((magic != XFS_DA_NODE_MAGIC) &&
- (magic != XFS_DIR_LEAF_MAGIC) &&
- (magic != XFS_ATTR_LEAF_MAGIC) &&
- (magic != XFS_DIR2_LEAF1_MAGIC) &&
- (magic != XFS_DIR2_LEAFN_MAGIC) &&
- (magic1 != XFS_DIR2_BLOCK_MAGIC) &&
- (magic1 != XFS_DIR2_DATA_MAGIC) &&
- (be32_to_cpu(free->hdr.magic) != XFS_DIR2_FREE_MAGIC),
- mp, XFS_ERRTAG_DA_READ_BUF,
- XFS_RANDOM_DA_READ_BUF))) {
- xfs_buftrace("DA READ ERROR", rbp->bps[0]);
- XFS_CORRUPTION_ERROR("xfs_da_do_buf(2)",
- XFS_ERRLEVEL_LOW, mp, info);
- error = XFS_ERROR(EFSCORRUPTED);
- xfs_da_brelse(trans, rbp);
- nbplist = 0;
- goto exit1;
- }
- }
- if (bplist) {
- kmem_free(bplist, sizeof(*bplist) * nmap);
- }
- if (mapp != &map) {
- kmem_free(mapp, sizeof(*mapp) * nfsb);
- }
- if (bpp)
- *bpp = rbp;
- return 0;
-exit1:
- if (bplist) {
- for (i = 0; i < nbplist; i++)
- xfs_trans_brelse(trans, bplist[i]);
- kmem_free(bplist, sizeof(*bplist) * nmap);
- }
-exit0:
- if (mapp != &map)
- kmem_free(mapp, sizeof(*mapp) * nfsb);
- if (bpp)
- *bpp = NULL;
- return error;
-}
-
-/*
- * Get a buffer for the dir/attr block.
- */
-int
-xfs_da_get_buf(
- xfs_trans_t *trans,
- xfs_inode_t *dp,
- xfs_dablk_t bno,
- xfs_daddr_t mappedbno,
- xfs_dabuf_t **bpp,
- int whichfork)
-{
- return xfs_da_do_buf(trans, dp, bno, &mappedbno, bpp, whichfork, 0,
- (inst_t *)__return_address);
-}
-
-/*
- * Get a buffer for the dir/attr block, fill in the contents.
- */
-int
-xfs_da_read_buf(
- xfs_trans_t *trans,
- xfs_inode_t *dp,
- xfs_dablk_t bno,
- xfs_daddr_t mappedbno,
- xfs_dabuf_t **bpp,
- int whichfork)
-{
- return xfs_da_do_buf(trans, dp, bno, &mappedbno, bpp, whichfork, 1,
- (inst_t *)__return_address);
-}
-
-/*
- * Readahead the dir/attr block.
- */
-xfs_daddr_t
-xfs_da_reada_buf(
- xfs_trans_t *trans,
- xfs_inode_t *dp,
- xfs_dablk_t bno,
- int whichfork)
-{
- xfs_daddr_t rval;
-
- rval = -1;
- if (xfs_da_do_buf(trans, dp, bno, &rval, NULL, whichfork, 3,
- (inst_t *)__return_address))
- return -1;
- else
- return rval;
-}
-
-/*
- * Calculate the number of bits needed to hold i different values.
- */
-uint
-xfs_da_log2_roundup(uint i)
-{
- uint rval;
-
- for (rval = 0; rval < NBBY * sizeof(i); rval++) {
- if ((1 << rval) >= i)
- break;
- }
- return(rval);
-}
-
-kmem_zone_t *xfs_da_state_zone; /* anchor for state struct zone */
-kmem_zone_t *xfs_dabuf_zone; /* dabuf zone */
-
-/*
- * Allocate a dir-state structure.
- * We don't put them on the stack since they're large.
- */
-xfs_da_state_t *
-xfs_da_state_alloc(void)
-{
- return kmem_zone_zalloc(xfs_da_state_zone, KM_SLEEP);
-}
-
-/*
- * Kill the altpath contents of a da-state structure.
- */
-STATIC void
-xfs_da_state_kill_altpath(xfs_da_state_t *state)
-{
- int i;
-
- for (i = 0; i < state->altpath.active; i++) {
- if (state->altpath.blk[i].bp) {
- if (state->altpath.blk[i].bp != state->path.blk[i].bp)
- xfs_da_buf_done(state->altpath.blk[i].bp);
- state->altpath.blk[i].bp = NULL;
- }
- }
- state->altpath.active = 0;
-}
-
-/*
- * Free a da-state structure.
- */
-void
-xfs_da_state_free(xfs_da_state_t *state)
-{
- int i;
-
- xfs_da_state_kill_altpath(state);
- for (i = 0; i < state->path.active; i++) {
- if (state->path.blk[i].bp)
- xfs_da_buf_done(state->path.blk[i].bp);
- }
- if (state->extravalid && state->extrablk.bp)
- xfs_da_buf_done(state->extrablk.bp);
-#ifdef DEBUG
- memset((char *)state, 0, sizeof(*state));
-#endif /* DEBUG */
- kmem_zone_free(xfs_da_state_zone, state);
-}
-
-#ifdef XFS_DABUF_DEBUG
-xfs_dabuf_t *xfs_dabuf_global_list;
-lock_t xfs_dabuf_global_lock;
-#endif
-
-/*
- * Create a dabuf.
- */
-/* ARGSUSED */
-STATIC xfs_dabuf_t *
-xfs_da_buf_make(int nbuf, xfs_buf_t **bps, inst_t *ra)
-{
- xfs_buf_t *bp;
- xfs_dabuf_t *dabuf;
- int i;
- int off;
-
- if (nbuf == 1)
- dabuf = kmem_zone_alloc(xfs_dabuf_zone, KM_SLEEP);
- else
- dabuf = kmem_alloc(XFS_DA_BUF_SIZE(nbuf), KM_SLEEP);
- dabuf->dirty = 0;
-#ifdef XFS_DABUF_DEBUG
- dabuf->ra = ra;
- dabuf->target = XFS_BUF_TARGET(bps[0]);
- dabuf->blkno = XFS_BUF_ADDR(bps[0]);
-#endif
- if (nbuf == 1) {
- dabuf->nbuf = 1;
- bp = bps[0];
- dabuf->bbcount = (short)BTOBB(XFS_BUF_COUNT(bp));
- dabuf->data = XFS_BUF_PTR(bp);
- dabuf->bps[0] = bp;
- } else {
- dabuf->nbuf = nbuf;
- for (i = 0, dabuf->bbcount = 0; i < nbuf; i++) {
- dabuf->bps[i] = bp = bps[i];
- dabuf->bbcount += BTOBB(XFS_BUF_COUNT(bp));
- }
- dabuf->data = kmem_alloc(BBTOB(dabuf->bbcount), KM_SLEEP);
- for (i = off = 0; i < nbuf; i++, off += XFS_BUF_COUNT(bp)) {
- bp = bps[i];
- memcpy((char *)dabuf->data + off, XFS_BUF_PTR(bp),
- XFS_BUF_COUNT(bp));
- }
- }
-#ifdef XFS_DABUF_DEBUG
- {
- SPLDECL(s);
- xfs_dabuf_t *p;
-
- s = mutex_spinlock(&xfs_dabuf_global_lock);
- for (p = xfs_dabuf_global_list; p; p = p->next) {
- ASSERT(p->blkno != dabuf->blkno ||
- p->target != dabuf->target);
- }
- dabuf->prev = NULL;
- if (xfs_dabuf_global_list)
- xfs_dabuf_global_list->prev = dabuf;
- dabuf->next = xfs_dabuf_global_list;
- xfs_dabuf_global_list = dabuf;
- mutex_spinunlock(&xfs_dabuf_global_lock, s);
- }
-#endif
- return dabuf;
-}
-
-/*
- * Un-dirty a dabuf.
- */
-STATIC void
-xfs_da_buf_clean(xfs_dabuf_t *dabuf)
-{
- xfs_buf_t *bp;
- int i;
- int off;
-
- if (dabuf->dirty) {
- ASSERT(dabuf->nbuf > 1);
- dabuf->dirty = 0;
- for (i = off = 0; i < dabuf->nbuf;
- i++, off += XFS_BUF_COUNT(bp)) {
- bp = dabuf->bps[i];
- memcpy(XFS_BUF_PTR(bp), (char *)dabuf->data + off,
- XFS_BUF_COUNT(bp));
- }
- }
-}
-
-/*
- * Release a dabuf.
- */
-void
-xfs_da_buf_done(xfs_dabuf_t *dabuf)
-{
- ASSERT(dabuf);
- ASSERT(dabuf->nbuf && dabuf->data && dabuf->bbcount && dabuf->bps[0]);
- if (dabuf->dirty)
- xfs_da_buf_clean(dabuf);
- if (dabuf->nbuf > 1)
- kmem_free(dabuf->data, BBTOB(dabuf->bbcount));
-#ifdef XFS_DABUF_DEBUG
- {
- SPLDECL(s);
-
- s = mutex_spinlock(&xfs_dabuf_global_lock);
- if (dabuf->prev)
- dabuf->prev->next = dabuf->next;
- else
- xfs_dabuf_global_list = dabuf->next;
- if (dabuf->next)
- dabuf->next->prev = dabuf->prev;
- mutex_spinunlock(&xfs_dabuf_global_lock, s);
- }
- memset(dabuf, 0, XFS_DA_BUF_SIZE(dabuf->nbuf));
-#endif
- if (dabuf->nbuf == 1)
- kmem_zone_free(xfs_dabuf_zone, dabuf);
- else
- kmem_free(dabuf, XFS_DA_BUF_SIZE(dabuf->nbuf));
-}
-
-/*
- * Log transaction from a dabuf.
- */
-void
-xfs_da_log_buf(xfs_trans_t *tp, xfs_dabuf_t *dabuf, uint first, uint last)
-{
- xfs_buf_t *bp;
- uint f;
- int i;
- uint l;
- int off;
-
- ASSERT(dabuf->nbuf && dabuf->data && dabuf->bbcount && dabuf->bps[0]);
- if (dabuf->nbuf == 1) {
- ASSERT(dabuf->data == (void *)XFS_BUF_PTR(dabuf->bps[0]));
- xfs_trans_log_buf(tp, dabuf->bps[0], first, last);
- return;
- }
- dabuf->dirty = 1;
- ASSERT(first <= last);
- for (i = off = 0; i < dabuf->nbuf; i++, off += XFS_BUF_COUNT(bp)) {
- bp = dabuf->bps[i];
- f = off;
- l = f + XFS_BUF_COUNT(bp) - 1;
- if (f < first)
- f = first;
- if (l > last)
- l = last;
- if (f <= l)
- xfs_trans_log_buf(tp, bp, f - off, l - off);
- /*
- * B_DONE is set by xfs_trans_log buf.
- * If we don't set it on a new buffer (get not read)
- * then if we don't put anything in the buffer it won't
- * be set, and at commit it it released into the cache,
- * and then a read will fail.
- */
- else if (!(XFS_BUF_ISDONE(bp)))
- XFS_BUF_DONE(bp);
- }
- ASSERT(last < off);
-}
-
-/*
- * Release dabuf from a transaction.
- * Have to free up the dabuf before the buffers are released,
- * since the synchronization on the dabuf is really the lock on the buffer.
- */
-void
-xfs_da_brelse(xfs_trans_t *tp, xfs_dabuf_t *dabuf)
-{
- xfs_buf_t *bp;
- xfs_buf_t **bplist;
- int i;
- int nbuf;
-
- ASSERT(dabuf->nbuf && dabuf->data && dabuf->bbcount && dabuf->bps[0]);
- if ((nbuf = dabuf->nbuf) == 1) {
- bplist = &bp;
- bp = dabuf->bps[0];
- } else {
- bplist = kmem_alloc(nbuf * sizeof(*bplist), KM_SLEEP);
- memcpy(bplist, dabuf->bps, nbuf * sizeof(*bplist));
- }
- xfs_da_buf_done(dabuf);
- for (i = 0; i < nbuf; i++)
- xfs_trans_brelse(tp, bplist[i]);
- if (bplist != &bp)
- kmem_free(bplist, nbuf * sizeof(*bplist));
-}
-
-/*
- * Invalidate dabuf from a transaction.
- */
-void
-xfs_da_binval(xfs_trans_t *tp, xfs_dabuf_t *dabuf)
-{
- xfs_buf_t *bp;
- xfs_buf_t **bplist;
- int i;
- int nbuf;
-
- ASSERT(dabuf->nbuf && dabuf->data && dabuf->bbcount && dabuf->bps[0]);
- if ((nbuf = dabuf->nbuf) == 1) {
- bplist = &bp;
- bp = dabuf->bps[0];
- } else {
- bplist = kmem_alloc(nbuf * sizeof(*bplist), KM_SLEEP);
- memcpy(bplist, dabuf->bps, nbuf * sizeof(*bplist));
- }
- xfs_da_buf_done(dabuf);
- for (i = 0; i < nbuf; i++)
- xfs_trans_binval(tp, bplist[i]);
- if (bplist != &bp)
- kmem_free(bplist, nbuf * sizeof(*bplist));
-}
-
-/*
- * Get the first daddr from a dabuf.
- */
-xfs_daddr_t
-xfs_da_blkno(xfs_dabuf_t *dabuf)
-{
- ASSERT(dabuf->nbuf);
- ASSERT(dabuf->data);
- return XFS_BUF_ADDR(dabuf->bps[0]);
-}
diff --git a/sys/gnu/fs/xfs/xfs_da_btree.h b/sys/gnu/fs/xfs/xfs_da_btree.h
deleted file mode 100644
index 243a730..0000000
--- a/sys/gnu/fs/xfs/xfs_da_btree.h
+++ /dev/null
@@ -1,270 +0,0 @@
-/*
- * Copyright (c) 2000,2002,2005 Silicon Graphics, Inc.
- * All Rights Reserved.
- *
- * 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.
- *
- * This program is distributed in the hope that it would 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 the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- */
-#ifndef __XFS_DA_BTREE_H__
-#define __XFS_DA_BTREE_H__
-
-struct xfs_buf;
-struct xfs_bmap_free;
-struct xfs_inode;
-struct xfs_mount;
-struct xfs_trans;
-struct zone;
-
-/*========================================================================
- * Directory Structure when greater than XFS_LBSIZE(mp) bytes.
- *========================================================================*/
-
-/*
- * This structure is common to both leaf nodes and non-leaf nodes in the Btree.
- *
- * Is is used to manage a doubly linked list of all blocks at the same
- * level in the Btree, and to identify which type of block this is.
- */
-#define XFS_DA_NODE_MAGIC 0xfebe /* magic number: non-leaf blocks */
-#define XFS_DIR_LEAF_MAGIC 0xfeeb /* magic number: directory leaf blks */
-#define XFS_ATTR_LEAF_MAGIC 0xfbee /* magic number: attribute leaf blks */
-#define XFS_DIR2_LEAF1_MAGIC 0xd2f1 /* magic number: v2 dirlf single blks */
-#define XFS_DIR2_LEAFN_MAGIC 0xd2ff /* magic number: v2 dirlf multi blks */
-
-#define XFS_DIRX_LEAF_MAGIC(mp) \
- (XFS_DIR_IS_V1(mp) ? XFS_DIR_LEAF_MAGIC : XFS_DIR2_LEAFN_MAGIC)
-
-typedef struct xfs_da_blkinfo {
- __be32 forw; /* previous block in list */
- __be32 back; /* following block in list */
- __be16 magic; /* validity check on block */
- __be16 pad; /* unused */
-} xfs_da_blkinfo_t;
-
-/*
- * This is the structure of the root and intermediate nodes in the Btree.
- * The leaf nodes are defined above.
- *
- * Entries are not packed.
- *
- * Since we have duplicate keys, use a binary search but always follow
- * all match in the block, not just the first match found.
- */
-#define XFS_DA_NODE_MAXDEPTH 5 /* max depth of Btree */
-
-typedef struct xfs_da_intnode {
- struct xfs_da_node_hdr { /* constant-structure header block */
- xfs_da_blkinfo_t info; /* block type, links, etc. */
- __be16 count; /* count of active entries */
- __be16 level; /* level above leaves (leaf == 0) */
- } hdr;
- struct xfs_da_node_entry {
- __be32 hashval; /* hash value for this descendant */
- __be32 before; /* Btree block before this key */
- } btree[1]; /* variable sized array of keys */
-} xfs_da_intnode_t;
-typedef struct xfs_da_node_hdr xfs_da_node_hdr_t;
-typedef struct xfs_da_node_entry xfs_da_node_entry_t;
-
-#define XFS_DA_MAXHASH ((xfs_dahash_t)-1) /* largest valid hash value */
-
-#define XFS_LBSIZE(mp) (mp)->m_sb.sb_blocksize
-#define XFS_LBLOG(mp) (mp)->m_sb.sb_blocklog
-
-#define XFS_DA_MAKE_BNOENTRY(mp,bno,entry) \
- (((bno) << (mp)->m_dircook_elog) | (entry))
-#define XFS_DA_MAKE_COOKIE(mp,bno,entry,hash) \
- (((xfs_off_t)XFS_DA_MAKE_BNOENTRY(mp, bno, entry) << 32) | (hash))
-#define XFS_DA_COOKIE_HASH(mp,cookie) ((xfs_dahash_t)cookie)
-#define XFS_DA_COOKIE_BNO(mp,cookie) \
- ((((xfs_off_t)(cookie) >> 31) == -1LL ? \
- (xfs_dablk_t)0 : \
- (xfs_dablk_t)((xfs_off_t)(cookie) >> \
- ((mp)->m_dircook_elog + 32))))
-#define XFS_DA_COOKIE_ENTRY(mp,cookie) \
- ((((xfs_off_t)(cookie) >> 31) == -1LL ? \
- (xfs_dablk_t)0 : \
- (xfs_dablk_t)(((xfs_off_t)(cookie) >> 32) & \
- ((1 << (mp)->m_dircook_elog) - 1))))
-
-
-/*========================================================================
- * Btree searching and modification structure definitions.
- *========================================================================*/
-
-/*
- * Structure to ease passing around component names.
- */
-typedef struct xfs_da_args {
- const uchar_t *name; /* string (maybe not NULL terminated) */
- int namelen; /* length of string (maybe no NULL) */
- uchar_t *value; /* set of bytes (maybe contain NULLs) */
- int valuelen; /* length of value */
- int flags; /* argument flags (eg: ATTR_NOCREATE) */
- xfs_dahash_t hashval; /* hash value of name */
- xfs_ino_t inumber; /* input/output inode number */
- struct xfs_inode *dp; /* directory inode to manipulate */
- xfs_fsblock_t *firstblock; /* ptr to firstblock for bmap calls */
- struct xfs_bmap_free *flist; /* ptr to freelist for bmap_finish */
- struct xfs_trans *trans; /* current trans (changes over time) */
- xfs_extlen_t total; /* total blocks needed, for 1st bmap */
- int whichfork; /* data or attribute fork */
- xfs_dablk_t blkno; /* blkno of attr leaf of interest */
- int index; /* index of attr of interest in blk */
- xfs_dablk_t rmtblkno; /* remote attr value starting blkno */
- int rmtblkcnt; /* remote attr value block count */
- xfs_dablk_t blkno2; /* blkno of 2nd attr leaf of interest */
- int index2; /* index of 2nd attr in blk */
- xfs_dablk_t rmtblkno2; /* remote attr value starting blkno */
- int rmtblkcnt2; /* remote attr value block count */
- unsigned char justcheck; /* T/F: check for ok with no space */
- unsigned char rename; /* T/F: this is an atomic rename op */
- unsigned char addname; /* T/F: this is an add operation */
- unsigned char oknoent; /* T/F: ok to return ENOENT, else die */
-} xfs_da_args_t;
-
-/*
- * Structure to describe buffer(s) for a block.
- * This is needed in the directory version 2 format case, when
- * multiple non-contiguous fsblocks might be needed to cover one
- * logical directory block.
- * If the buffer count is 1 then the data pointer points to the
- * same place as the b_addr field for the buffer, else to kmem_alloced memory.
- */
-typedef struct xfs_dabuf {
- int nbuf; /* number of buffer pointers present */
- short dirty; /* data needs to be copied back */
- short bbcount; /* how large is data in bbs */
- void *data; /* pointer for buffers' data */
-#ifdef XFS_DABUF_DEBUG
- inst_t *ra; /* return address of caller to make */
- struct xfs_dabuf *next; /* next in global chain */
- struct xfs_dabuf *prev; /* previous in global chain */
- struct xfs_buftarg *target; /* device for buffer */
- xfs_daddr_t blkno; /* daddr first in bps[0] */
-#endif
- struct xfs_buf *bps[1]; /* actually nbuf of these */
-} xfs_dabuf_t;
-#define XFS_DA_BUF_SIZE(n) \
- (sizeof(xfs_dabuf_t) + sizeof(struct xfs_buf *) * ((n) - 1))
-
-#ifdef XFS_DABUF_DEBUG
-extern xfs_dabuf_t *xfs_dabuf_global_list;
-#endif
-
-/*
- * Storage for holding state during Btree searches and split/join ops.
- *
- * Only need space for 5 intermediate nodes. With a minimum of 62-way
- * fanout to the Btree, we can support over 900 million directory blocks,
- * which is slightly more than enough.
- */
-typedef struct xfs_da_state_blk {
- xfs_dabuf_t *bp; /* buffer containing block */
- xfs_dablk_t blkno; /* filesystem blkno of buffer */
- xfs_daddr_t disk_blkno; /* on-disk blkno (in BBs) of buffer */
- int index; /* relevant index into block */
- xfs_dahash_t hashval; /* last hash value in block */
- int magic; /* blk's magic number, ie: blk type */
-} xfs_da_state_blk_t;
-
-typedef struct xfs_da_state_path {
- int active; /* number of active levels */
- xfs_da_state_blk_t blk[XFS_DA_NODE_MAXDEPTH];
-} xfs_da_state_path_t;
-
-typedef struct xfs_da_state {
- xfs_da_args_t *args; /* filename arguments */
- struct xfs_mount *mp; /* filesystem mount point */
- unsigned int blocksize; /* logical block size */
- unsigned int node_ents; /* how many entries in danode */
- xfs_da_state_path_t path; /* search/split paths */
- xfs_da_state_path_t altpath; /* alternate path for join */
- unsigned char inleaf; /* insert into 1->lf, 0->splf */
- unsigned char extravalid; /* T/F: extrablk is in use */
- unsigned char extraafter; /* T/F: extrablk is after new */
- xfs_da_state_blk_t extrablk; /* for double-splits on leafs */
- /* for dirv2 extrablk is data */
-} xfs_da_state_t;
-
-/*
- * Utility macros to aid in logging changed structure fields.
- */
-#define XFS_DA_LOGOFF(BASE, ADDR) ((char *)(ADDR) - (char *)(BASE))
-#define XFS_DA_LOGRANGE(BASE, ADDR, SIZE) \
- (uint)(XFS_DA_LOGOFF(BASE, ADDR)), \
- (uint)(XFS_DA_LOGOFF(BASE, ADDR)+(SIZE)-1)
-
-
-#ifdef __KERNEL__
-/*========================================================================
- * Function prototypes for the kernel.
- *========================================================================*/
-
-/*
- * Routines used for growing the Btree.
- */
-int xfs_da_node_create(xfs_da_args_t *args, xfs_dablk_t blkno, int level,
- xfs_dabuf_t **bpp, int whichfork);
-int xfs_da_split(xfs_da_state_t *state);
-
-/*
- * Routines used for shrinking the Btree.
- */
-int xfs_da_join(xfs_da_state_t *state);
-void xfs_da_fixhashpath(xfs_da_state_t *state,
- xfs_da_state_path_t *path_to_to_fix);
-
-/*
- * Routines used for finding things in the Btree.
- */
-int xfs_da_node_lookup_int(xfs_da_state_t *state, int *result);
-int xfs_da_path_shift(xfs_da_state_t *state, xfs_da_state_path_t *path,
- int forward, int release, int *result);
-/*
- * Utility routines.
- */
-int xfs_da_blk_link(xfs_da_state_t *state, xfs_da_state_blk_t *old_blk,
- xfs_da_state_blk_t *new_blk);
-
-/*
- * Utility routines.
- */
-int xfs_da_grow_inode(xfs_da_args_t *args, xfs_dablk_t *new_blkno);
-int xfs_da_get_buf(struct xfs_trans *trans, struct xfs_inode *dp,
- xfs_dablk_t bno, xfs_daddr_t mappedbno,
- xfs_dabuf_t **bp, int whichfork);
-int xfs_da_read_buf(struct xfs_trans *trans, struct xfs_inode *dp,
- xfs_dablk_t bno, xfs_daddr_t mappedbno,
- xfs_dabuf_t **bpp, int whichfork);
-xfs_daddr_t xfs_da_reada_buf(struct xfs_trans *trans, struct xfs_inode *dp,
- xfs_dablk_t bno, int whichfork);
-int xfs_da_shrink_inode(xfs_da_args_t *args, xfs_dablk_t dead_blkno,
- xfs_dabuf_t *dead_buf);
-
-uint xfs_da_hashname(const uchar_t *name_string, int name_length);
-uint xfs_da_log2_roundup(uint i);
-xfs_da_state_t *xfs_da_state_alloc(void);
-void xfs_da_state_free(xfs_da_state_t *state);
-
-void xfs_da_buf_done(xfs_dabuf_t *dabuf);
-void xfs_da_log_buf(struct xfs_trans *tp, xfs_dabuf_t *dabuf, uint first,
- uint last);
-void xfs_da_brelse(struct xfs_trans *tp, xfs_dabuf_t *dabuf);
-void xfs_da_binval(struct xfs_trans *tp, xfs_dabuf_t *dabuf);
-xfs_daddr_t xfs_da_blkno(xfs_dabuf_t *dabuf);
-
-extern struct kmem_zone *xfs_da_state_zone;
-#endif /* __KERNEL__ */
-
-#endif /* __XFS_DA_BTREE_H__ */
diff --git a/sys/gnu/fs/xfs/xfs_dfrag.c b/sys/gnu/fs/xfs/xfs_dfrag.c
deleted file mode 100644
index 7b6b04e..0000000
--- a/sys/gnu/fs/xfs/xfs_dfrag.c
+++ /dev/null
@@ -1,413 +0,0 @@
-/*
- * Copyright (c) 2000-2006 Silicon Graphics, Inc.
- * All Rights Reserved.
- *
- * 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.
- *
- * This program is distributed in the hope that it would 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 the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- */
-#include "xfs.h"
-#include "xfs_fs.h"
-#include "xfs_types.h"
-#include "xfs_bit.h"
-#include "xfs_log.h"
-#include "xfs_inum.h"
-#include "xfs_trans.h"
-#include "xfs_sb.h"
-#include "xfs_ag.h"
-#include "xfs_dir.h"
-#include "xfs_dir2.h"
-#include "xfs_dmapi.h"
-#include "xfs_mount.h"
-#include "xfs_bmap_btree.h"
-#include "xfs_alloc_btree.h"
-#include "xfs_ialloc_btree.h"
-#include "xfs_dir_sf.h"
-#include "xfs_dir2_sf.h"
-#include "xfs_attr_sf.h"
-#include "xfs_dinode.h"
-#include "xfs_inode.h"
-#include "xfs_inode_item.h"
-#include "xfs_bmap.h"
-#include "xfs_btree.h"
-#include "xfs_ialloc.h"
-#include "xfs_itable.h"
-#include "xfs_dfrag.h"
-#include "xfs_error.h"
-#include "xfs_mac.h"
-#include "xfs_rw.h"
-
-#include <sys/capability.h>
-#include <sys/file.h>
-
-/*
- * Syssgi interface for swapext
- */
-int
-xfs_swapext(
- xfs_swapext_t __user *sxu)
-{
- xfs_swapext_t *sxp;
- xfs_inode_t *ip=NULL, *tip=NULL;
- xfs_mount_t *mp;
- xfs_vnode_t *vp = NULL, *tvp = NULL;
- struct vnode *bvp, *btvp;
- int error = 0;
-
- sxp = kmem_alloc(sizeof(xfs_swapext_t), KM_MAYFAIL);
- if (!sxp) {
- error = XFS_ERROR(ENOMEM);
- goto error0;
- }
- struct thread *td;
- struct cred *cred;
-
- td = curthread;
- cred = td->td_ucred;
-
- if (copy_from_user(sxp, sxu, sizeof(xfs_swapext_t))) {
- error = XFS_ERROR(EFAULT);
- goto error0;
- }
-
- /* Pull information for the target fd */
- if (fgetvp(td, (int)sxp->sx_fdtarget, CAP_READ | CAP_WRITE, &bvp)
- != 0) {
- error = XFS_ERROR(EINVAL);
- goto error0;
- }
-
- vp = VPTOXFSVP(bvp);
- ip = xfs_vtoi(vp);
- if (ip == NULL) {
- error = XFS_ERROR(EBADF);
- goto error0;
- }
-
- if (fgetvp(td, (int)sxp->sx_fdtmp, CAP_READ | CAP_WRITE, &btvp) != 0) {
- error = XFS_ERROR(EINVAL);
- goto error0;
- }
-
- tvp = VPTOXFSVP(btvp);
- tip = xfs_vtoi(tvp);
- if (tip == NULL) {
- error = XFS_ERROR(EBADF);
- goto error0;
- }
-
- if (ip->i_mount != tip->i_mount) {
- error = XFS_ERROR(EINVAL);
- goto error0;
- }
-
- if (ip->i_ino == tip->i_ino) {
- error = XFS_ERROR(EINVAL);
- goto error0;
- }
-
- mp = ip->i_mount;
-
- if (XFS_FORCED_SHUTDOWN(mp)) {
- error = XFS_ERROR(EIO);
- goto error0;
- }
-
- error = XFS_SWAP_EXTENTS(mp, &ip->i_iocore, &tip->i_iocore, sxp);
-
- error0:
-#ifdef RMC
- if (fp != NULL)
- fput(fp);
- if (tfp != NULL)
- fput(tfp);
-#endif
-
- if (sxp != NULL)
- kmem_free(sxp, sizeof(xfs_swapext_t));
-
- return error;
-}
-
-int
-xfs_swap_extents(
- xfs_inode_t *ip,
- xfs_inode_t *tip,
- xfs_swapext_t *sxp)
-{
- xfs_mount_t *mp;
- xfs_inode_t *ips[2];
- xfs_trans_t *tp;
- xfs_bstat_t *sbp = &sxp->sx_stat;
- xfs_vnode_t *vp, *tvp;
- xfs_ifork_t *tempifp, *ifp, *tifp;
- int ilf_fields, tilf_fields;
- static uint lock_flags = XFS_ILOCK_EXCL | XFS_IOLOCK_EXCL;
- int error = 0;
- int aforkblks = 0;
- int taforkblks = 0;
- __uint64_t tmp;
- char locked = 0;
-
- mp = ip->i_mount;
-
- tempifp = kmem_alloc(sizeof(xfs_ifork_t), KM_MAYFAIL);
- if (!tempifp) {
- error = XFS_ERROR(ENOMEM);
- goto error0;
- }
-
- sbp = &sxp->sx_stat;
- vp = XFS_ITOV(ip);
- tvp = XFS_ITOV(tip);
-
- /* Lock in i_ino order */
- if (ip->i_ino < tip->i_ino) {
- ips[0] = ip;
- ips[1] = tip;
- } else {
- ips[0] = tip;
- ips[1] = ip;
- }
-
- xfs_lock_inodes(ips, 2, 0, lock_flags);
- locked = 1;
-
- /* Check permissions */
- error = xfs_iaccess(ip, VWRITE, NULL);
- if (error)
- goto error0;
-
- error = xfs_iaccess(tip, VWRITE, NULL);
- if (error)
- goto error0;
-
- /* Verify that both files have the same format */
- if ((ip->i_d.di_mode & S_IFMT) != (tip->i_d.di_mode & S_IFMT)) {
- error = XFS_ERROR(EINVAL);
- goto error0;
- }
-
- /* Verify both files are either real-time or non-realtime */
- if ((ip->i_d.di_flags & XFS_DIFLAG_REALTIME) !=
- (tip->i_d.di_flags & XFS_DIFLAG_REALTIME)) {
- error = XFS_ERROR(EINVAL);
- goto error0;
- }
-
- /* Should never get a local format */
- if (ip->i_d.di_format == XFS_DINODE_FMT_LOCAL ||
- tip->i_d.di_format == XFS_DINODE_FMT_LOCAL) {
- error = XFS_ERROR(EINVAL);
- goto error0;
- }
-
- if (VN_CACHED(tvp) != 0) {
- xfs_inval_cached_trace(&tip->i_iocore, 0, -1, 0, -1);
- XVOP_FLUSHINVAL_PAGES(tvp, 0, -1, FI_REMAPF_LOCKED);
- }
-
- /* Verify O_DIRECT for ftmp */
- if (VN_CACHED(tvp) != 0) {
- error = XFS_ERROR(EINVAL);
- goto error0;
- }
-
- /* Verify all data are being swapped */
- if (sxp->sx_offset != 0 ||
- sxp->sx_length != ip->i_d.di_size ||
- sxp->sx_length != tip->i_d.di_size) {
- error = XFS_ERROR(EFAULT);
- goto error0;
- }
-
- /*
- * If the target has extended attributes, the tmp file
- * must also in order to ensure the correct data fork
- * format.
- */
- if ( XFS_IFORK_Q(ip) != XFS_IFORK_Q(tip) ) {
- error = XFS_ERROR(EINVAL);
- goto error0;
- }
-
- /*
- * Compare the current change & modify times with that
- * passed in. If they differ, we abort this swap.
- * This is the mechanism used to ensure the calling
- * process that the file was not changed out from
- * under it.
- */
- if ((sbp->bs_ctime.tv_sec != ip->i_d.di_ctime.t_sec) ||
- (sbp->bs_ctime.tv_nsec != ip->i_d.di_ctime.t_nsec) ||
- (sbp->bs_mtime.tv_sec != ip->i_d.di_mtime.t_sec) ||
- (sbp->bs_mtime.tv_nsec != ip->i_d.di_mtime.t_nsec)) {
- error = XFS_ERROR(EBUSY);
- goto error0;
- }
-
- /* We need to fail if the file is memory mapped. Once we have tossed
- * all existing pages, the page fault will have no option
- * but to go to the filesystem for pages. By making the page fault call
- * VOP_READ (or write in the case of autogrow) they block on the iolock
- * until we have switched the extents.
- */
- if (VN_MAPPED(vp)) {
- error = XFS_ERROR(EBUSY);
- goto error0;
- }
-
- xfs_iunlock(ip, XFS_ILOCK_EXCL);
- xfs_iunlock(tip, XFS_ILOCK_EXCL);
-
- /*
- * There is a race condition here since we gave up the
- * ilock. However, the data fork will not change since
- * we have the iolock (locked for truncation too) so we
- * are safe. We don't really care if non-io related
- * fields change.
- */
-
- XVOP_TOSS_PAGES(vp, 0, -1, FI_REMAPF);
-
- tp = xfs_trans_alloc(mp, XFS_TRANS_SWAPEXT);
- if ((error = xfs_trans_reserve(tp, 0,
- XFS_ICHANGE_LOG_RES(mp), 0,
- 0, 0))) {
- xfs_iunlock(ip, XFS_IOLOCK_EXCL);
- xfs_iunlock(tip, XFS_IOLOCK_EXCL);
- xfs_trans_cancel(tp, 0);
- locked = 0;
- goto error0;
- }
- xfs_lock_inodes(ips, 2, 0, XFS_ILOCK_EXCL);
-
- /*
- * Count the number of extended attribute blocks
- */
- if ( ((XFS_IFORK_Q(ip) != 0) && (ip->i_d.di_anextents > 0)) &&
- (ip->i_d.di_aformat != XFS_DINODE_FMT_LOCAL)) {
- error = xfs_bmap_count_blocks(tp, ip, XFS_ATTR_FORK, &aforkblks);
- if (error) {
- xfs_trans_cancel(tp, 0);
- goto error0;
- }
- }
- if ( ((XFS_IFORK_Q(tip) != 0) && (tip->i_d.di_anextents > 0)) &&
- (tip->i_d.di_aformat != XFS_DINODE_FMT_LOCAL)) {
- error = xfs_bmap_count_blocks(tp, tip, XFS_ATTR_FORK,
- &taforkblks);
- if (error) {
- xfs_trans_cancel(tp, 0);
- goto error0;
- }
- }
-
- /*
- * Swap the data forks of the inodes
- */
- ifp = &ip->i_df;
- tifp = &tip->i_df;
- *tempifp = *ifp; /* struct copy */
- *ifp = *tifp; /* struct copy */
- *tifp = *tempifp; /* struct copy */
-
- /*
- * Fix the on-disk inode values
- */
- tmp = (__uint64_t)ip->i_d.di_nblocks;
- ip->i_d.di_nblocks = tip->i_d.di_nblocks - taforkblks + aforkblks;
- tip->i_d.di_nblocks = tmp + taforkblks - aforkblks;
-
- tmp = (__uint64_t) ip->i_d.di_nextents;
- ip->i_d.di_nextents = tip->i_d.di_nextents;
- tip->i_d.di_nextents = tmp;
-
- tmp = (__uint64_t) ip->i_d.di_format;
- ip->i_d.di_format = tip->i_d.di_format;
- tip->i_d.di_format = tmp;
-
- ilf_fields = XFS_ILOG_CORE;
-
- switch(ip->i_d.di_format) {
- case XFS_DINODE_FMT_EXTENTS:
- /* If the extents fit in the inode, fix the
- * pointer. Otherwise it's already NULL or
- * pointing to the extent.
- */
- if (ip->i_d.di_nextents <= XFS_INLINE_EXTS) {
- ifp->if_u1.if_extents =
- ifp->if_u2.if_inline_ext;
- }
- ilf_fields |= XFS_ILOG_DEXT;
- break;
- case XFS_DINODE_FMT_BTREE:
- ilf_fields |= XFS_ILOG_DBROOT;
- break;
- }
-
- tilf_fields = XFS_ILOG_CORE;
-
- switch(tip->i_d.di_format) {
- case XFS_DINODE_FMT_EXTENTS:
- /* If the extents fit in the inode, fix the
- * pointer. Otherwise it's already NULL or
- * pointing to the extent.
- */
- if (tip->i_d.di_nextents <= XFS_INLINE_EXTS) {
- tifp->if_u1.if_extents =
- tifp->if_u2.if_inline_ext;
- }
- tilf_fields |= XFS_ILOG_DEXT;
- break;
- case XFS_DINODE_FMT_BTREE:
- tilf_fields |= XFS_ILOG_DBROOT;
- break;
- }
-
-#ifdef XXXKAN /* Not necessary, vnodes are vrefed already by fgetvp */
- /*
- * Increment vnode ref counts since xfs_trans_commit &
- * xfs_trans_cancel will both unlock the inodes and
- * decrement the associated ref counts.
- */
- VN_HOLD(vp);
- VN_HOLD(tvp);
-#endif
-
- xfs_trans_ijoin(tp, ip, lock_flags);
- xfs_trans_ijoin(tp, tip, lock_flags);
-
- xfs_trans_log_inode(tp, ip, ilf_fields);
- xfs_trans_log_inode(tp, tip, tilf_fields);
-
- /*
- * If this is a synchronous mount, make sure that the
- * transaction goes to disk before returning to the user.
- */
- if (mp->m_flags & XFS_MOUNT_WSYNC) {
- xfs_trans_set_sync(tp);
- }
-
- error = xfs_trans_commit(tp, XFS_TRANS_SWAPEXT, NULL);
-
- locked = 0;
-
- error0:
- if (locked) {
- xfs_iunlock(ip, lock_flags);
- xfs_iunlock(tip, lock_flags);
- }
- if (tempifp != NULL)
- kmem_free(tempifp, sizeof(xfs_ifork_t));
- return error;
-}
diff --git a/sys/gnu/fs/xfs/xfs_dfrag.h b/sys/gnu/fs/xfs/xfs_dfrag.h
deleted file mode 100644
index da17820..0000000
--- a/sys/gnu/fs/xfs/xfs_dfrag.h
+++ /dev/null
@@ -1,56 +0,0 @@
-/*
- * Copyright (c) 2000,2005 Silicon Graphics, Inc.
- * All Rights Reserved.
- *
- * 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.
- *
- * This program is distributed in the hope that it would 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 the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- */
-#ifndef __XFS_DFRAG_H__
-#define __XFS_DFRAG_H__
-
-/*
- * Structure passed to xfs_swapext
- */
-
-typedef struct xfs_swapext
-{
- __int64_t sx_version; /* version */
- __int64_t sx_fdtarget; /* fd of target file */
- __int64_t sx_fdtmp; /* fd of tmp file */
- xfs_off_t sx_offset; /* offset into file */
- xfs_off_t sx_length; /* leng from offset */
- char sx_pad[16]; /* pad space, unused */
- xfs_bstat_t sx_stat; /* stat of target b4 copy */
-} xfs_swapext_t;
-
-/*
- * Version flag
- */
-#define XFS_SX_VERSION 0
-
-#ifdef __KERNEL__
-/*
- * Prototypes for visible xfs_dfrag.c routines.
- */
-
-/*
- * Syscall interface for xfs_swapext
- */
-int xfs_swapext(struct xfs_swapext __user *sx);
-
-int xfs_swap_extents(struct xfs_inode *ip, struct xfs_inode *tip,
- struct xfs_swapext *sxp);
-
-#endif /* __KERNEL__ */
-
-#endif /* __XFS_DFRAG_H__ */
diff --git a/sys/gnu/fs/xfs/xfs_dinode.h b/sys/gnu/fs/xfs/xfs_dinode.h
deleted file mode 100644
index 79d0d9e..0000000
--- a/sys/gnu/fs/xfs/xfs_dinode.h
+++ /dev/null
@@ -1,281 +0,0 @@
-/*
- * Copyright (c) 2000,2002,2005 Silicon Graphics, Inc.
- * All Rights Reserved.
- *
- * 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.
- *
- * This program is distributed in the hope that it would 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 the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- */
-#ifndef __XFS_DINODE_H__
-#define __XFS_DINODE_H__
-
-struct xfs_buf;
-struct xfs_mount;
-
-#define XFS_DINODE_VERSION_1 1
-#define XFS_DINODE_VERSION_2 2
-#define XFS_DINODE_GOOD_VERSION(v) \
- (((v) == XFS_DINODE_VERSION_1 || (v) == XFS_DINODE_VERSION_2))
-#define XFS_DINODE_MAGIC 0x494e /* 'IN' */
-
-/*
- * Disk inode structure.
- * This is just the header; the inode is expanded to fill a variable size
- * with the last field expanding. It is split into the core and "other"
- * because we only need the core part in the in-core inode.
- */
-typedef struct xfs_timestamp {
- __int32_t t_sec; /* timestamp seconds */
- __int32_t t_nsec; /* timestamp nanoseconds */
-} xfs_timestamp_t;
-
-/*
- * Note: Coordinate changes to this structure with the XFS_DI_* #defines
- * below and the offsets table in xfs_ialloc_log_di().
- */
-typedef struct xfs_dinode_core
-{
- __uint16_t di_magic; /* inode magic # = XFS_DINODE_MAGIC */
- __uint16_t di_mode; /* mode and type of file */
- __int8_t di_version; /* inode version */
- __int8_t di_format; /* format of di_c data */
- __uint16_t di_onlink; /* old number of links to file */
- __uint32_t di_uid; /* owner's user id */
- __uint32_t di_gid; /* owner's group id */
- __uint32_t di_nlink; /* number of links to file */
- __uint16_t di_projid; /* owner's project id */
- __uint8_t di_pad[8]; /* unused, zeroed space */
- __uint16_t di_flushiter; /* incremented on flush */
- xfs_timestamp_t di_atime; /* time last accessed */
- xfs_timestamp_t di_mtime; /* time last modified */
- xfs_timestamp_t di_ctime; /* time created/inode modified */
- xfs_fsize_t di_size; /* number of bytes in file */
- xfs_drfsbno_t di_nblocks; /* # of direct & btree blocks used */
- xfs_extlen_t di_extsize; /* basic/minimum extent size for file */
- xfs_extnum_t di_nextents; /* number of extents in data fork */
- xfs_aextnum_t di_anextents; /* number of extents in attribute fork*/
- __uint8_t di_forkoff; /* attr fork offs, <<3 for 64b align */
- __int8_t di_aformat; /* format of attr fork's data */
- __uint32_t di_dmevmask; /* DMIG event mask */
- __uint16_t di_dmstate; /* DMIG state info */
- __uint16_t di_flags; /* random flags, XFS_DIFLAG_... */
- __uint32_t di_gen; /* generation number */
-} xfs_dinode_core_t;
-
-#define DI_MAX_FLUSH 0xffff
-
-typedef struct xfs_dinode
-{
- xfs_dinode_core_t di_core;
- /*
- * In adding anything between the core and the union, be
- * sure to update the macros like XFS_LITINO below and
- * XFS_BMAP_RBLOCK_DSIZE in xfs_bmap_btree.h.
- */
- xfs_agino_t di_next_unlinked;/* agi unlinked list ptr */
- union {
- xfs_bmdr_block_t di_bmbt; /* btree root block */
- xfs_bmbt_rec_32_t di_bmx[1]; /* extent list */
- xfs_dir_shortform_t di_dirsf; /* shortform directory */
- xfs_dir2_sf_t di_dir2sf; /* shortform directory v2 */
- char di_c[1]; /* local contents */
- xfs_dev_t di_dev; /* device for S_IFCHR/S_IFBLK */
- uuid_t di_muuid; /* mount point value */
- char di_symlink[1]; /* local symbolic link */
- } di_u;
- union {
- xfs_bmdr_block_t di_abmbt; /* btree root block */
- xfs_bmbt_rec_32_t di_abmx[1]; /* extent list */
- xfs_attr_shortform_t di_attrsf; /* shortform attribute list */
- } di_a;
-} xfs_dinode_t;
-
-/*
- * The 32 bit link count in the inode theoretically maxes out at UINT_MAX.
- * Since the pathconf interface is signed, we use 2^31 - 1 instead.
- * The old inode format had a 16 bit link count, so its maximum is USHRT_MAX.
- */
-#define XFS_MAXLINK ((1U << 31) - 1U)
-#define XFS_MAXLINK_1 65535U
-
-/*
- * Bit names for logging disk inodes only
- */
-#define XFS_DI_MAGIC 0x0000001
-#define XFS_DI_MODE 0x0000002
-#define XFS_DI_VERSION 0x0000004
-#define XFS_DI_FORMAT 0x0000008
-#define XFS_DI_ONLINK 0x0000010
-#define XFS_DI_UID 0x0000020
-#define XFS_DI_GID 0x0000040
-#define XFS_DI_NLINK 0x0000080
-#define XFS_DI_PROJID 0x0000100
-#define XFS_DI_PAD 0x0000200
-#define XFS_DI_ATIME 0x0000400
-#define XFS_DI_MTIME 0x0000800
-#define XFS_DI_CTIME 0x0001000
-#define XFS_DI_SIZE 0x0002000
-#define XFS_DI_NBLOCKS 0x0004000
-#define XFS_DI_EXTSIZE 0x0008000
-#define XFS_DI_NEXTENTS 0x0010000
-#define XFS_DI_NAEXTENTS 0x0020000
-#define XFS_DI_FORKOFF 0x0040000
-#define XFS_DI_AFORMAT 0x0080000
-#define XFS_DI_DMEVMASK 0x0100000
-#define XFS_DI_DMSTATE 0x0200000
-#define XFS_DI_FLAGS 0x0400000
-#define XFS_DI_GEN 0x0800000
-#define XFS_DI_NEXT_UNLINKED 0x1000000
-#define XFS_DI_U 0x2000000
-#define XFS_DI_A 0x4000000
-#define XFS_DI_NUM_BITS 27
-#define XFS_DI_ALL_BITS ((1 << XFS_DI_NUM_BITS) - 1)
-#define XFS_DI_CORE_BITS (XFS_DI_ALL_BITS & ~(XFS_DI_U|XFS_DI_A))
-
-/*
- * Values for di_format
- */
-typedef enum xfs_dinode_fmt
-{
- XFS_DINODE_FMT_DEV, /* CHR, BLK: di_dev */
- XFS_DINODE_FMT_LOCAL, /* DIR, REG: di_c */
- /* LNK: di_symlink */
- XFS_DINODE_FMT_EXTENTS, /* DIR, REG, LNK: di_bmx */
- XFS_DINODE_FMT_BTREE, /* DIR, REG, LNK: di_bmbt */
- XFS_DINODE_FMT_UUID /* MNT: di_uuid */
-} xfs_dinode_fmt_t;
-
-/*
- * Inode minimum and maximum sizes.
- */
-#define XFS_DINODE_MIN_LOG 8
-#define XFS_DINODE_MAX_LOG 11
-#define XFS_DINODE_MIN_SIZE (1 << XFS_DINODE_MIN_LOG)
-#define XFS_DINODE_MAX_SIZE (1 << XFS_DINODE_MAX_LOG)
-
-/*
- * Inode size for given fs.
- */
-#define XFS_LITINO(mp) ((mp)->m_litino)
-#define XFS_BROOT_SIZE_ADJ \
- (sizeof(xfs_bmbt_block_t) - sizeof(xfs_bmdr_block_t))
-
-/*
- * Inode data & attribute fork sizes, per inode.
- */
-#define XFS_CFORK_Q(dcp) ((dcp)->di_forkoff != 0)
-#define XFS_CFORK_Q_DISK(dcp) ((dcp)->di_forkoff != 0)
-
-#define XFS_CFORK_BOFF(dcp) ((int)((dcp)->di_forkoff << 3))
-#define XFS_CFORK_BOFF_DISK(dcp) \
- ((int)(INT_GET((dcp)->di_forkoff, ARCH_CONVERT) << 3))
-
-#define XFS_CFORK_DSIZE_DISK(dcp,mp) \
- (XFS_CFORK_Q_DISK(dcp) ? XFS_CFORK_BOFF_DISK(dcp) : XFS_LITINO(mp))
-#define XFS_CFORK_DSIZE(dcp,mp) \
- (XFS_CFORK_Q(dcp) ? XFS_CFORK_BOFF(dcp) : XFS_LITINO(mp))
-
-#define XFS_CFORK_ASIZE_DISK(dcp,mp) \
- (XFS_CFORK_Q_DISK(dcp) ? XFS_LITINO(mp) - XFS_CFORK_BOFF_DISK(dcp) : 0)
-#define XFS_CFORK_ASIZE(dcp,mp) \
- (XFS_CFORK_Q(dcp) ? XFS_LITINO(mp) - XFS_CFORK_BOFF(dcp) : 0)
-
-#define XFS_CFORK_SIZE_DISK(dcp,mp,w) \
- ((w) == XFS_DATA_FORK ? \
- XFS_CFORK_DSIZE_DISK(dcp, mp) : \
- XFS_CFORK_ASIZE_DISK(dcp, mp))
-#define XFS_CFORK_SIZE(dcp,mp,w) \
- ((w) == XFS_DATA_FORK ? \
- XFS_CFORK_DSIZE(dcp, mp) : XFS_CFORK_ASIZE(dcp, mp))
-
-#define XFS_DFORK_DSIZE(dip,mp) \
- XFS_CFORK_DSIZE_DISK(&(dip)->di_core, mp)
-#define XFS_DFORK_DSIZE_HOST(dip,mp) \
- XFS_CFORK_DSIZE(&(dip)->di_core, mp)
-#define XFS_DFORK_ASIZE(dip,mp) \
- XFS_CFORK_ASIZE_DISK(&(dip)->di_core, mp)
-#define XFS_DFORK_ASIZE_HOST(dip,mp) \
- XFS_CFORK_ASIZE(&(dip)->di_core, mp)
-#define XFS_DFORK_SIZE(dip,mp,w) \
- XFS_CFORK_SIZE_DISK(&(dip)->di_core, mp, w)
-#define XFS_DFORK_SIZE_HOST(dip,mp,w) \
- XFS_CFORK_SIZE(&(dip)->di_core, mp, w)
-
-#define XFS_DFORK_Q(dip) XFS_CFORK_Q_DISK(&(dip)->di_core)
-#define XFS_DFORK_BOFF(dip) XFS_CFORK_BOFF_DISK(&(dip)->di_core)
-#define XFS_DFORK_DPTR(dip) ((dip)->di_u.di_c)
-#define XFS_DFORK_APTR(dip) \
- ((dip)->di_u.di_c + XFS_DFORK_BOFF(dip))
-#define XFS_DFORK_PTR(dip,w) \
- ((w) == XFS_DATA_FORK ? XFS_DFORK_DPTR(dip) : XFS_DFORK_APTR(dip))
-#define XFS_CFORK_FORMAT(dcp,w) \
- ((w) == XFS_DATA_FORK ? (dcp)->di_format : (dcp)->di_aformat)
-#define XFS_CFORK_FMT_SET(dcp,w,n) \
- ((w) == XFS_DATA_FORK ? \
- ((dcp)->di_format = (n)) : ((dcp)->di_aformat = (n)))
-#define XFS_DFORK_FORMAT(dip,w) XFS_CFORK_FORMAT(&(dip)->di_core, w)
-
-#define XFS_CFORK_NEXTENTS_DISK(dcp,w) \
- ((w) == XFS_DATA_FORK ? \
- INT_GET((dcp)->di_nextents, ARCH_CONVERT) : \
- INT_GET((dcp)->di_anextents, ARCH_CONVERT))
-#define XFS_CFORK_NEXTENTS(dcp,w) \
- ((w) == XFS_DATA_FORK ? (dcp)->di_nextents : (dcp)->di_anextents)
-#define XFS_DFORK_NEXTENTS(dip,w) XFS_CFORK_NEXTENTS_DISK(&(dip)->di_core, w)
-#define XFS_DFORK_NEXTENTS_HOST(dip,w) XFS_CFORK_NEXTENTS(&(dip)->di_core, w)
-
-#define XFS_CFORK_NEXT_SET(dcp,w,n) \
- ((w) == XFS_DATA_FORK ? \
- ((dcp)->di_nextents = (n)) : ((dcp)->di_anextents = (n)))
-
-#define XFS_BUF_TO_DINODE(bp) ((xfs_dinode_t *)XFS_BUF_PTR(bp))
-
-/*
- * Values for di_flags
- * There should be a one-to-one correspondence between these flags and the
- * XFS_XFLAG_s.
- */
-#define XFS_DIFLAG_REALTIME_BIT 0 /* file's blocks come from rt area */
-#define XFS_DIFLAG_PREALLOC_BIT 1 /* file space has been preallocated */
-#define XFS_DIFLAG_NEWRTBM_BIT 2 /* for rtbitmap inode, new format */
-#define XFS_DIFLAG_IMMUTABLE_BIT 3 /* inode is immutable */
-#define XFS_DIFLAG_APPEND_BIT 4 /* inode is append-only */
-#define XFS_DIFLAG_SYNC_BIT 5 /* inode is written synchronously */
-#define XFS_DIFLAG_NOATIME_BIT 6 /* do not update atime */
-#define XFS_DIFLAG_NODUMP_BIT 7 /* do not dump */
-#define XFS_DIFLAG_RTINHERIT_BIT 8 /* create with realtime bit set */
-#define XFS_DIFLAG_PROJINHERIT_BIT 9 /* create with parents projid */
-#define XFS_DIFLAG_NOSYMLINKS_BIT 10 /* disallow symlink creation */
-#define XFS_DIFLAG_EXTSIZE_BIT 11 /* inode extent size allocator hint */
-#define XFS_DIFLAG_EXTSZINHERIT_BIT 12 /* inherit inode extent size */
-#define XFS_DIFLAG_REALTIME (1 << XFS_DIFLAG_REALTIME_BIT)
-#define XFS_DIFLAG_PREALLOC (1 << XFS_DIFLAG_PREALLOC_BIT)
-#define XFS_DIFLAG_NEWRTBM (1 << XFS_DIFLAG_NEWRTBM_BIT)
-#define XFS_DIFLAG_IMMUTABLE (1 << XFS_DIFLAG_IMMUTABLE_BIT)
-#define XFS_DIFLAG_APPEND (1 << XFS_DIFLAG_APPEND_BIT)
-#define XFS_DIFLAG_SYNC (1 << XFS_DIFLAG_SYNC_BIT)
-#define XFS_DIFLAG_NOATIME (1 << XFS_DIFLAG_NOATIME_BIT)
-#define XFS_DIFLAG_NODUMP (1 << XFS_DIFLAG_NODUMP_BIT)
-#define XFS_DIFLAG_RTINHERIT (1 << XFS_DIFLAG_RTINHERIT_BIT)
-#define XFS_DIFLAG_PROJINHERIT (1 << XFS_DIFLAG_PROJINHERIT_BIT)
-#define XFS_DIFLAG_NOSYMLINKS (1 << XFS_DIFLAG_NOSYMLINKS_BIT)
-#define XFS_DIFLAG_EXTSIZE (1 << XFS_DIFLAG_EXTSIZE_BIT)
-#define XFS_DIFLAG_EXTSZINHERIT (1 << XFS_DIFLAG_EXTSZINHERIT_BIT)
-
-#define XFS_DIFLAG_ANY \
- (XFS_DIFLAG_REALTIME | XFS_DIFLAG_PREALLOC | XFS_DIFLAG_NEWRTBM | \
- XFS_DIFLAG_IMMUTABLE | XFS_DIFLAG_APPEND | XFS_DIFLAG_SYNC | \
- XFS_DIFLAG_NOATIME | XFS_DIFLAG_NODUMP | XFS_DIFLAG_RTINHERIT | \
- XFS_DIFLAG_PROJINHERIT | XFS_DIFLAG_NOSYMLINKS | XFS_DIFLAG_EXTSIZE | \
- XFS_DIFLAG_EXTSZINHERIT)
-
-#endif /* __XFS_DINODE_H__ */
diff --git a/sys/gnu/fs/xfs/xfs_dir.c b/sys/gnu/fs/xfs/xfs_dir.c
deleted file mode 100644
index 7df722e..0000000
--- a/sys/gnu/fs/xfs/xfs_dir.c
+++ /dev/null
@@ -1,1218 +0,0 @@
-/*
- * Copyright (c) 2000-2001,2005 Silicon Graphics, Inc.
- * All Rights Reserved.
- *
- * 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.
- *
- * This program is distributed in the hope that it would 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 the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- */
-#include "xfs.h"
-#include "xfs_fs.h"
-#include "xfs_types.h"
-#include "xfs_log.h"
-#include "xfs_inum.h"
-#include "xfs_trans.h"
-#include "xfs_sb.h"
-#include "xfs_dir.h"
-#include "xfs_dir2.h"
-#include "xfs_dmapi.h"
-#include "xfs_mount.h"
-#include "xfs_da_btree.h"
-#include "xfs_bmap_btree.h"
-#include "xfs_alloc_btree.h"
-#include "xfs_ialloc_btree.h"
-#include "xfs_alloc.h"
-#include "xfs_btree.h"
-#include "xfs_dir_sf.h"
-#include "xfs_dir2_sf.h"
-#include "xfs_attr_sf.h"
-#include "xfs_dinode.h"
-#include "xfs_inode.h"
-#include "xfs_bmap.h"
-#include "xfs_dir_leaf.h"
-#include "xfs_error.h"
-
-/*
- * xfs_dir.c
- *
- * Provide the external interfaces to manage directories.
- */
-
-/*========================================================================
- * Function prototypes for the kernel.
- *========================================================================*/
-
-/*
- * Functions for the dirops interfaces.
- */
-static void xfs_dir_mount(struct xfs_mount *mp);
-
-static int xfs_dir_isempty(struct xfs_inode *dp);
-
-static int xfs_dir_init(struct xfs_trans *trans,
- struct xfs_inode *dir,
- struct xfs_inode *parent_dir);
-
-static int xfs_dir_createname(struct xfs_trans *trans,
- struct xfs_inode *dp,
- char *name_string,
- int name_len,
- xfs_ino_t inode_number,
- xfs_fsblock_t *firstblock,
- xfs_bmap_free_t *flist,
- xfs_extlen_t total);
-
-static int xfs_dir_lookup(struct xfs_trans *tp,
- struct xfs_inode *dp,
- char *name_string,
- int name_length,
- xfs_ino_t *inode_number);
-
-static int xfs_dir_removename(struct xfs_trans *trans,
- struct xfs_inode *dp,
- char *name_string,
- int name_length,
- xfs_ino_t ino,
- xfs_fsblock_t *firstblock,
- xfs_bmap_free_t *flist,
- xfs_extlen_t total);
-
-static int xfs_dir_getdents(struct xfs_trans *tp,
- struct xfs_inode *dp,
- struct uio *uiop,
- int *eofp);
-
-static int xfs_dir_replace(struct xfs_trans *tp,
- struct xfs_inode *dp,
- char *name_string,
- int name_length,
- xfs_ino_t inode_number,
- xfs_fsblock_t *firstblock,
- xfs_bmap_free_t *flist,
- xfs_extlen_t total);
-
-static int xfs_dir_canenter(struct xfs_trans *tp,
- struct xfs_inode *dp,
- char *name_string,
- int name_length);
-
-static int xfs_dir_shortform_validate_ondisk(xfs_mount_t *mp,
- xfs_dinode_t *dip);
-
-xfs_dirops_t xfsv1_dirops = {
- .xd_mount = xfs_dir_mount,
- .xd_isempty = xfs_dir_isempty,
- .xd_init = xfs_dir_init,
- .xd_createname = xfs_dir_createname,
- .xd_lookup = xfs_dir_lookup,
- .xd_removename = xfs_dir_removename,
- .xd_getdents = xfs_dir_getdents,
- .xd_replace = xfs_dir_replace,
- .xd_canenter = xfs_dir_canenter,
- .xd_shortform_validate_ondisk = xfs_dir_shortform_validate_ondisk,
- .xd_shortform_to_single = xfs_dir_shortform_to_leaf,
-};
-
-/*
- * Internal routines when dirsize == XFS_LBSIZE(mp).
- */
-STATIC int xfs_dir_leaf_lookup(xfs_da_args_t *args);
-STATIC int xfs_dir_leaf_removename(xfs_da_args_t *args, int *number_entries,
- int *total_namebytes);
-STATIC int xfs_dir_leaf_getdents(xfs_trans_t *trans, xfs_inode_t *dp,
- uio_t *uio, int *eofp,
- xfs_dirent_t *dbp,
- xfs_dir_put_t put);
-STATIC int xfs_dir_leaf_replace(xfs_da_args_t *args);
-
-/*
- * Internal routines when dirsize > XFS_LBSIZE(mp).
- */
-STATIC int xfs_dir_node_addname(xfs_da_args_t *args);
-STATIC int xfs_dir_node_lookup(xfs_da_args_t *args);
-STATIC int xfs_dir_node_removename(xfs_da_args_t *args);
-STATIC int xfs_dir_node_getdents(xfs_trans_t *trans, xfs_inode_t *dp,
- uio_t *uio, int *eofp,
- xfs_dirent_t *dbp,
- xfs_dir_put_t put);
-STATIC int xfs_dir_node_replace(xfs_da_args_t *args);
-
-#if defined(XFS_DIR_TRACE)
-ktrace_t *xfs_dir_trace_buf;
-#endif
-
-
-/*========================================================================
- * Overall external interface routines.
- *========================================================================*/
-
-xfs_dahash_t xfs_dir_hash_dot, xfs_dir_hash_dotdot;
-
-/*
- * One-time startup routine called from xfs_init().
- */
-void
-xfs_dir_startup(void)
-{
- xfs_dir_hash_dot = xfs_da_hashname(".", 1);
- xfs_dir_hash_dotdot = xfs_da_hashname("..", 2);
-}
-
-/*
- * Initialize directory-related fields in the mount structure.
- */
-static void
-xfs_dir_mount(xfs_mount_t *mp)
-{
- uint shortcount, leafcount, count;
-
- mp->m_dirversion = 1;
- if (!(mp->m_flags & XFS_MOUNT_ATTR2)) {
- shortcount = (mp->m_attroffset -
- (uint)sizeof(xfs_dir_sf_hdr_t)) /
- (uint)sizeof(xfs_dir_sf_entry_t);
- leafcount = (XFS_LBSIZE(mp) -
- (uint)sizeof(xfs_dir_leaf_hdr_t)) /
- ((uint)sizeof(xfs_dir_leaf_entry_t) +
- (uint)sizeof(xfs_dir_leaf_name_t));
- } else {
- shortcount = (XFS_BMDR_SPACE_CALC(MINABTPTRS) -
- (uint)sizeof(xfs_dir_sf_hdr_t)) /
- (uint)sizeof(xfs_dir_sf_entry_t);
- leafcount = (XFS_LBSIZE(mp) -
- (uint)sizeof(xfs_dir_leaf_hdr_t)) /
- ((uint)sizeof(xfs_dir_leaf_entry_t) +
- (uint)sizeof(xfs_dir_leaf_name_t));
- }
- count = shortcount > leafcount ? shortcount : leafcount;
- mp->m_dircook_elog = xfs_da_log2_roundup(count + 1);
- ASSERT(mp->m_dircook_elog <= mp->m_sb.sb_blocklog);
- mp->m_dir_node_ents = mp->m_attr_node_ents =
- (XFS_LBSIZE(mp) - (uint)sizeof(xfs_da_node_hdr_t)) /
- (uint)sizeof(xfs_da_node_entry_t);
- mp->m_dir_magicpct = (XFS_LBSIZE(mp) * 37) / 100;
- mp->m_dirblksize = mp->m_sb.sb_blocksize;
- mp->m_dirblkfsbs = 1;
-}
-
-/*
- * Return 1 if directory contains only "." and "..".
- */
-static int
-xfs_dir_isempty(xfs_inode_t *dp)
-{
- xfs_dir_sf_hdr_t *hdr;
-
- ASSERT((dp->i_d.di_mode & S_IFMT) == S_IFDIR);
- if (dp->i_d.di_size == 0)
- return(1);
- if (dp->i_d.di_size > XFS_IFORK_DSIZE(dp))
- return(0);
- hdr = (xfs_dir_sf_hdr_t *)dp->i_df.if_u1.if_data;
- return(hdr->count == 0);
-}
-
-/*
- * Initialize a directory with its "." and ".." entries.
- */
-static int
-xfs_dir_init(xfs_trans_t *trans, xfs_inode_t *dir, xfs_inode_t *parent_dir)
-{
- xfs_da_args_t args;
- int error;
-
- memset((char *)&args, 0, sizeof(args));
- args.dp = dir;
- args.trans = trans;
-
- ASSERT((dir->i_d.di_mode & S_IFMT) == S_IFDIR);
- if ((error = xfs_dir_ino_validate(trans->t_mountp, parent_dir->i_ino)))
- return error;
-
- return(xfs_dir_shortform_create(&args, parent_dir->i_ino));
-}
-
-/*
- * Generic handler routine to add a name to a directory.
- * Transitions directory from shortform to Btree as necessary.
- */
-static int /* error */
-xfs_dir_createname(xfs_trans_t *trans, xfs_inode_t *dp, char *name,
- int namelen, xfs_ino_t inum, xfs_fsblock_t *firstblock,
- xfs_bmap_free_t *flist, xfs_extlen_t total)
-{
- xfs_da_args_t args;
- int retval, newsize, done;
-
- ASSERT((dp->i_d.di_mode & S_IFMT) == S_IFDIR);
-
- if ((retval = xfs_dir_ino_validate(trans->t_mountp, inum)))
- return (retval);
-
- XFS_STATS_INC(xs_dir_create);
- /*
- * Fill in the arg structure for this request.
- */
- args.name = name;
- args.namelen = namelen;
- args.hashval = xfs_da_hashname(name, namelen);
- args.inumber = inum;
- args.dp = dp;
- args.firstblock = firstblock;
- args.flist = flist;
- args.total = total;
- args.whichfork = XFS_DATA_FORK;
- args.trans = trans;
- args.justcheck = 0;
- args.addname = args.oknoent = 1;
-
- /*
- * Decide on what work routines to call based on the inode size.
- */
- done = 0;
- if (dp->i_d.di_format == XFS_DINODE_FMT_LOCAL) {
- newsize = XFS_DIR_SF_ENTSIZE_BYNAME(args.namelen);
- if ((dp->i_d.di_size + newsize) <= XFS_IFORK_DSIZE(dp)) {
- retval = xfs_dir_shortform_addname(&args);
- done = 1;
- } else {
- if (total == 0)
- return XFS_ERROR(ENOSPC);
- retval = xfs_dir_shortform_to_leaf(&args);
- done = retval != 0;
- }
- }
- if (!done && xfs_bmap_one_block(dp, XFS_DATA_FORK)) {
- retval = xfs_dir_leaf_addname(&args);
- done = retval != ENOSPC;
- if (!done) {
- if (total == 0)
- return XFS_ERROR(ENOSPC);
- retval = xfs_dir_leaf_to_node(&args);
- done = retval != 0;
- }
- }
- if (!done) {
- retval = xfs_dir_node_addname(&args);
- }
- return(retval);
-}
-
-/*
- * Generic handler routine to check if a name can be added to a directory,
- * without adding any blocks to the directory.
- */
-static int /* error */
-xfs_dir_canenter(xfs_trans_t *trans, xfs_inode_t *dp, char *name, int namelen)
-{
- xfs_da_args_t args;
- int retval, newsize;
-
- ASSERT((dp->i_d.di_mode & S_IFMT) == S_IFDIR);
- /*
- * Fill in the arg structure for this request.
- */
- args.name = name;
- args.namelen = namelen;
- args.hashval = xfs_da_hashname(name, namelen);
- args.inumber = 0;
- args.dp = dp;
- args.firstblock = NULL;
- args.flist = NULL;
- args.total = 0;
- args.whichfork = XFS_DATA_FORK;
- args.trans = trans;
- args.justcheck = args.addname = args.oknoent = 1;
-
- /*
- * Decide on what work routines to call based on the inode size.
- */
- if (dp->i_d.di_format == XFS_DINODE_FMT_LOCAL) {
- newsize = XFS_DIR_SF_ENTSIZE_BYNAME(args.namelen);
- if ((dp->i_d.di_size + newsize) <= XFS_IFORK_DSIZE(dp))
- retval = 0;
- else
- retval = XFS_ERROR(ENOSPC);
- } else if (xfs_bmap_one_block(dp, XFS_DATA_FORK)) {
- retval = xfs_dir_leaf_addname(&args);
- } else {
- retval = xfs_dir_node_addname(&args);
- }
- return(retval);
-}
-
-/*
- * Generic handler routine to remove a name from a directory.
- * Transitions directory from Btree to shortform as necessary.
- */
-static int /* error */
-xfs_dir_removename(xfs_trans_t *trans, xfs_inode_t *dp, char *name,
- int namelen, xfs_ino_t ino, xfs_fsblock_t *firstblock,
- xfs_bmap_free_t *flist, xfs_extlen_t total)
-{
- xfs_da_args_t args;
- int count, totallen, newsize, retval;
-
- ASSERT((dp->i_d.di_mode & S_IFMT) == S_IFDIR);
- XFS_STATS_INC(xs_dir_remove);
- /*
- * Fill in the arg structure for this request.
- */
- args.name = name;
- args.namelen = namelen;
- args.hashval = xfs_da_hashname(name, namelen);
- args.inumber = ino;
- args.dp = dp;
- args.firstblock = firstblock;
- args.flist = flist;
- args.total = total;
- args.whichfork = XFS_DATA_FORK;
- args.trans = trans;
- args.justcheck = args.addname = args.oknoent = 0;
-
- /*
- * Decide on what work routines to call based on the inode size.
- */
- if (dp->i_d.di_format == XFS_DINODE_FMT_LOCAL) {
- retval = xfs_dir_shortform_removename(&args);
- } else if (xfs_bmap_one_block(dp, XFS_DATA_FORK)) {
- count = totallen = 0;
- retval = xfs_dir_leaf_removename(&args, &count, &totallen);
- if (retval == 0) {
- newsize = XFS_DIR_SF_ALLFIT(count, totallen);
- if (newsize <= XFS_IFORK_DSIZE(dp)) {
- retval = xfs_dir_leaf_to_shortform(&args);
- }
- }
- } else {
- retval = xfs_dir_node_removename(&args);
- }
- return(retval);
-}
-
-static int /* error */
-xfs_dir_lookup(xfs_trans_t *trans, xfs_inode_t *dp, char *name, int namelen,
- xfs_ino_t *inum)
-{
- xfs_da_args_t args;
- int retval;
-
- ASSERT((dp->i_d.di_mode & S_IFMT) == S_IFDIR);
-
- XFS_STATS_INC(xs_dir_lookup);
- /*
- * Fill in the arg structure for this request.
- */
- args.name = name;
- args.namelen = namelen;
- args.hashval = xfs_da_hashname(name, namelen);
- args.inumber = 0;
- args.dp = dp;
- args.firstblock = NULL;
- args.flist = NULL;
- args.total = 0;
- args.whichfork = XFS_DATA_FORK;
- args.trans = trans;
- args.justcheck = args.addname = 0;
- args.oknoent = 1;
-
- /*
- * Decide on what work routines to call based on the inode size.
- */
- if (dp->i_d.di_format == XFS_DINODE_FMT_LOCAL) {
- retval = xfs_dir_shortform_lookup(&args);
- } else if (xfs_bmap_one_block(dp, XFS_DATA_FORK)) {
- retval = xfs_dir_leaf_lookup(&args);
- } else {
- retval = xfs_dir_node_lookup(&args);
- }
- if (retval == EEXIST)
- retval = 0;
- *inum = args.inumber;
- return(retval);
-}
-
-/*
- * Implement readdir.
- */
-static int /* error */
-xfs_dir_getdents(xfs_trans_t *trans, xfs_inode_t *dp, uio_t *uio, int *eofp)
-{
- xfs_dirent_t *dbp;
- int alignment, retval;
- xfs_dir_put_t put;
-
- XFS_STATS_INC(xs_dir_getdents);
- ASSERT((dp->i_d.di_mode & S_IFMT) == S_IFDIR);
-
- /*
- * If our caller has given us a single contiguous memory buffer,
- * just work directly within that buffer. If it's in user memory,
- * lock it down first.
- */
- alignment = sizeof(xfs_off_t) - 1;
- if ((uio->uio_iovcnt == 1) &&
- (((__psint_t)uio->uio_iov[0].iov_base & alignment) == 0) &&
- ((uio->uio_iov[0].iov_len & alignment) == 0)) {
- dbp = NULL;
- put = xfs_dir_put_dirent64_direct;
- } else {
- dbp = kmem_alloc(sizeof(*dbp) + MAXNAMELEN, KM_SLEEP);
- put = xfs_dir_put_dirent64_uio;
- }
-
- /*
- * Decide on what work routines to call based on the inode size.
- */
- *eofp = 0;
-
- if (dp->i_d.di_format == XFS_DINODE_FMT_LOCAL) {
- retval = xfs_dir_shortform_getdents(dp, uio, eofp, dbp, put);
- } else if (xfs_bmap_one_block(dp, XFS_DATA_FORK)) {
- retval = xfs_dir_leaf_getdents(trans, dp, uio, eofp, dbp, put);
- } else {
- retval = xfs_dir_node_getdents(trans, dp, uio, eofp, dbp, put);
- }
- if (dbp != NULL)
- kmem_free(dbp, sizeof(*dbp) + MAXNAMELEN);
-
- return(retval);
-}
-
-static int /* error */
-xfs_dir_replace(xfs_trans_t *trans, xfs_inode_t *dp, char *name, int namelen,
- xfs_ino_t inum, xfs_fsblock_t *firstblock,
- xfs_bmap_free_t *flist, xfs_extlen_t total)
-{
- xfs_da_args_t args;
- int retval;
-
- ASSERT((dp->i_d.di_mode & S_IFMT) == S_IFDIR);
-
- if ((retval = xfs_dir_ino_validate(trans->t_mountp, inum)))
- return retval;
-
- /*
- * Fill in the arg structure for this request.
- */
- args.name = name;
- args.namelen = namelen;
- args.hashval = xfs_da_hashname(name, namelen);
- args.inumber = inum;
- args.dp = dp;
- args.firstblock = firstblock;
- args.flist = flist;
- args.total = total;
- args.whichfork = XFS_DATA_FORK;
- args.trans = trans;
- args.justcheck = args.addname = args.oknoent = 0;
-
- /*
- * Decide on what work routines to call based on the inode size.
- */
- if (dp->i_d.di_format == XFS_DINODE_FMT_LOCAL) {
- retval = xfs_dir_shortform_replace(&args);
- } else if (xfs_bmap_one_block(dp, XFS_DATA_FORK)) {
- retval = xfs_dir_leaf_replace(&args);
- } else {
- retval = xfs_dir_node_replace(&args);
- }
-
- return(retval);
-}
-
-static int
-xfs_dir_shortform_validate_ondisk(xfs_mount_t *mp, xfs_dinode_t *dp)
-{
- xfs_ino_t ino;
- int namelen_sum;
- int count;
- xfs_dir_shortform_t *sf;
- xfs_dir_sf_entry_t *sfe;
- int i;
-
-
-
- if ((INT_GET(dp->di_core.di_mode, ARCH_CONVERT) & S_IFMT) != S_IFDIR) {
- return 0;
- }
- if (INT_GET(dp->di_core.di_format, ARCH_CONVERT) != XFS_DINODE_FMT_LOCAL) {
- return 0;
- }
- if (INT_GET(dp->di_core.di_size, ARCH_CONVERT) < sizeof(sf->hdr)) {
- xfs_fs_cmn_err(CE_WARN, mp, "Invalid shortform size: dp 0x%p",
- dp);
- return 1;
- }
- sf = (xfs_dir_shortform_t *)(&dp->di_u.di_dirsf);
- ino = XFS_GET_DIR_INO8(sf->hdr.parent);
- if (xfs_dir_ino_validate(mp, ino))
- return 1;
-
- count = sf->hdr.count;
- if ((count < 0) || ((count * 10) > XFS_LITINO(mp))) {
- xfs_fs_cmn_err(CE_WARN, mp,
- "Invalid shortform count: dp 0x%p", dp);
- return(1);
- }
-
- if (count == 0) {
- return 0;
- }
-
- namelen_sum = 0;
- sfe = &sf->list[0];
- for (i = sf->hdr.count - 1; i >= 0; i--) {
- ino = XFS_GET_DIR_INO8(sfe->inumber);
- xfs_dir_ino_validate(mp, ino);
- if (sfe->namelen >= XFS_LITINO(mp)) {
- xfs_fs_cmn_err(CE_WARN, mp,
- "Invalid shortform namelen: dp 0x%p", dp);
- return 1;
- }
- namelen_sum += sfe->namelen;
- sfe = XFS_DIR_SF_NEXTENTRY(sfe);
- }
- if (namelen_sum >= XFS_LITINO(mp)) {
- xfs_fs_cmn_err(CE_WARN, mp,
- "Invalid shortform namelen: dp 0x%p", dp);
- return 1;
- }
-
- return 0;
-}
-
-/*========================================================================
- * External routines when dirsize == XFS_LBSIZE(dp->i_mount).
- *========================================================================*/
-
-/*
- * Add a name to the leaf directory structure
- * This is the external routine.
- */
-int
-xfs_dir_leaf_addname(xfs_da_args_t *args)
-{
- int index, retval;
- xfs_dabuf_t *bp;
-
- retval = xfs_da_read_buf(args->trans, args->dp, 0, -1, &bp,
- XFS_DATA_FORK);
- if (retval)
- return(retval);
- ASSERT(bp != NULL);
-
- retval = xfs_dir_leaf_lookup_int(bp, args, &index);
- if (retval == ENOENT)
- retval = xfs_dir_leaf_add(bp, args, index);
- xfs_da_buf_done(bp);
- return(retval);
-}
-
-/*
- * Remove a name from the leaf directory structure
- * This is the external routine.
- */
-STATIC int
-xfs_dir_leaf_removename(xfs_da_args_t *args, int *count, int *totallen)
-{
- xfs_dir_leafblock_t *leaf;
- int index, retval;
- xfs_dabuf_t *bp;
-
- retval = xfs_da_read_buf(args->trans, args->dp, 0, -1, &bp,
- XFS_DATA_FORK);
- if (retval)
- return(retval);
- ASSERT(bp != NULL);
- leaf = bp->data;
- ASSERT(be16_to_cpu(leaf->hdr.info.magic) == XFS_DIR_LEAF_MAGIC);
- retval = xfs_dir_leaf_lookup_int(bp, args, &index);
- if (retval == EEXIST) {
- (void)xfs_dir_leaf_remove(args->trans, bp, index);
- *count = INT_GET(leaf->hdr.count, ARCH_CONVERT);
- *totallen = INT_GET(leaf->hdr.namebytes, ARCH_CONVERT);
- retval = 0;
- }
- xfs_da_buf_done(bp);
- return(retval);
-}
-
-/*
- * Look up a name in a leaf directory structure.
- * This is the external routine.
- */
-STATIC int
-xfs_dir_leaf_lookup(xfs_da_args_t *args)
-{
- int index, retval;
- xfs_dabuf_t *bp;
-
- retval = xfs_da_read_buf(args->trans, args->dp, 0, -1, &bp,
- XFS_DATA_FORK);
- if (retval)
- return(retval);
- ASSERT(bp != NULL);
- retval = xfs_dir_leaf_lookup_int(bp, args, &index);
- xfs_da_brelse(args->trans, bp);
- return(retval);
-}
-
-/*
- * Copy out directory entries for getdents(), for leaf directories.
- */
-STATIC int
-xfs_dir_leaf_getdents(xfs_trans_t *trans, xfs_inode_t *dp, uio_t *uio,
- int *eofp, xfs_dirent_t *dbp, xfs_dir_put_t put)
-{
- xfs_dabuf_t *bp;
- int retval, eob;
-
- retval = xfs_da_read_buf(dp->i_transp, dp, 0, -1, &bp, XFS_DATA_FORK);
- if (retval)
- return(retval);
- ASSERT(bp != NULL);
- retval = xfs_dir_leaf_getdents_int(bp, dp, 0, uio, &eob, dbp, put, -1);
- xfs_da_brelse(trans, bp);
- *eofp = (eob == 0);
- return(retval);
-}
-
-/*
- * Look up a name in a leaf directory structure, replace the inode number.
- * This is the external routine.
- */
-STATIC int
-xfs_dir_leaf_replace(xfs_da_args_t *args)
-{
- int index, retval;
- xfs_dabuf_t *bp;
- xfs_ino_t inum;
- xfs_dir_leafblock_t *leaf;
- xfs_dir_leaf_entry_t *entry;
- xfs_dir_leaf_name_t *namest;
-
- inum = args->inumber;
- retval = xfs_da_read_buf(args->trans, args->dp, 0, -1, &bp,
- XFS_DATA_FORK);
- if (retval)
- return(retval);
- ASSERT(bp != NULL);
- retval = xfs_dir_leaf_lookup_int(bp, args, &index);
- if (retval == EEXIST) {
- leaf = bp->data;
- entry = &leaf->entries[index];
- namest = XFS_DIR_LEAF_NAMESTRUCT(leaf, INT_GET(entry->nameidx, ARCH_CONVERT));
- /* XXX - replace assert? */
- XFS_DIR_SF_PUT_DIRINO(&inum, &namest->inumber);
- xfs_da_log_buf(args->trans, bp,
- XFS_DA_LOGRANGE(leaf, namest, sizeof(namest->inumber)));
- xfs_da_buf_done(bp);
- retval = 0;
- } else
- xfs_da_brelse(args->trans, bp);
- return(retval);
-}
-
-
-/*========================================================================
- * External routines when dirsize > XFS_LBSIZE(mp).
- *========================================================================*/
-
-/*
- * Add a name to a Btree-format directory.
- *
- * This will involve walking down the Btree, and may involve splitting
- * leaf nodes and even splitting intermediate nodes up to and including
- * the root node (a special case of an intermediate node).
- */
-STATIC int
-xfs_dir_node_addname(xfs_da_args_t *args)
-{
- xfs_da_state_t *state;
- xfs_da_state_blk_t *blk;
- int retval, error;
-
- /*
- * Fill in bucket of arguments/results/context to carry around.
- */
- state = xfs_da_state_alloc();
- state->args = args;
- state->mp = args->dp->i_mount;
- state->blocksize = state->mp->m_sb.sb_blocksize;
- state->node_ents = state->mp->m_dir_node_ents;
-
- /*
- * Search to see if name already exists, and get back a pointer
- * to where it should go.
- */
- error = xfs_da_node_lookup_int(state, &retval);
- if (error)
- retval = error;
- if (retval != ENOENT)
- goto error;
- blk = &state->path.blk[ state->path.active-1 ];
- ASSERT(blk->magic == XFS_DIR_LEAF_MAGIC);
- retval = xfs_dir_leaf_add(blk->bp, args, blk->index);
- if (retval == 0) {
- /*
- * Addition succeeded, update Btree hashvals.
- */
- if (!args->justcheck)
- xfs_da_fixhashpath(state, &state->path);
- } else {
- /*
- * Addition failed, split as many Btree elements as required.
- */
- if (args->total == 0) {
- ASSERT(retval == ENOSPC);
- goto error;
- }
- retval = xfs_da_split(state);
- }
-error:
- xfs_da_state_free(state);
-
- return(retval);
-}
-
-/*
- * Remove a name from a B-tree directory.
- *
- * This will involve walking down the Btree, and may involve joining
- * leaf nodes and even joining intermediate nodes up to and including
- * the root node (a special case of an intermediate node).
- */
-STATIC int
-xfs_dir_node_removename(xfs_da_args_t *args)
-{
- xfs_da_state_t *state;
- xfs_da_state_blk_t *blk;
- int retval, error;
-
- state = xfs_da_state_alloc();
- state->args = args;
- state->mp = args->dp->i_mount;
- state->blocksize = state->mp->m_sb.sb_blocksize;
- state->node_ents = state->mp->m_dir_node_ents;
-
- /*
- * Search to see if name exists, and get back a pointer to it.
- */
- error = xfs_da_node_lookup_int(state, &retval);
- if (error)
- retval = error;
- if (retval != EEXIST) {
- xfs_da_state_free(state);
- return(retval);
- }
-
- /*
- * Remove the name and update the hashvals in the tree.
- */
- blk = &state->path.blk[ state->path.active-1 ];
- ASSERT(blk->magic == XFS_DIR_LEAF_MAGIC);
- retval = xfs_dir_leaf_remove(args->trans, blk->bp, blk->index);
- xfs_da_fixhashpath(state, &state->path);
-
- /*
- * Check to see if the tree needs to be collapsed.
- */
- error = 0;
- if (retval) {
- error = xfs_da_join(state);
- }
-
- xfs_da_state_free(state);
- if (error)
- return(error);
- return(0);
-}
-
-/*
- * Look up a filename in a int directory.
- * Use an internal routine to actually do all the work.
- */
-STATIC int
-xfs_dir_node_lookup(xfs_da_args_t *args)
-{
- xfs_da_state_t *state;
- int retval, error, i;
-
- state = xfs_da_state_alloc();
- state->args = args;
- state->mp = args->dp->i_mount;
- state->blocksize = state->mp->m_sb.sb_blocksize;
- state->node_ents = state->mp->m_dir_node_ents;
-
- /*
- * Search to see if name exists,
- * and get back a pointer to it.
- */
- error = xfs_da_node_lookup_int(state, &retval);
- if (error) {
- retval = error;
- }
-
- /*
- * If not in a transaction, we have to release all the buffers.
- */
- for (i = 0; i < state->path.active; i++) {
- xfs_da_brelse(args->trans, state->path.blk[i].bp);
- state->path.blk[i].bp = NULL;
- }
-
- xfs_da_state_free(state);
- return(retval);
-}
-
-STATIC int
-xfs_dir_node_getdents(xfs_trans_t *trans, xfs_inode_t *dp, uio_t *uio,
- int *eofp, xfs_dirent_t *dbp, xfs_dir_put_t put)
-{
- xfs_da_intnode_t *node;
- xfs_da_node_entry_t *btree;
- xfs_dir_leafblock_t *leaf = NULL;
- xfs_dablk_t bno, nextbno;
- xfs_dahash_t cookhash;
- xfs_mount_t *mp;
- int error, eob, i;
- xfs_dabuf_t *bp;
- xfs_daddr_t nextda;
-
- /*
- * Pick up our context.
- */
- mp = dp->i_mount;
- bp = NULL;
- bno = XFS_DA_COOKIE_BNO(mp, uio->uio_offset);
- cookhash = XFS_DA_COOKIE_HASH(mp, uio->uio_offset);
-
- xfs_dir_trace_g_du("node: start", dp, uio);
-
- /*
- * Re-find our place, even if we're confused about what our place is.
- *
- * First we check the block number from the magic cookie, it is a
- * cache of where we ended last time. If we find a leaf block, and
- * the starting hashval in that block is less than our desired
- * hashval, then we run with it.
- */
- if (bno > 0) {
- error = xfs_da_read_buf(trans, dp, bno, -2, &bp, XFS_DATA_FORK);
- if ((error != 0) && (error != EFSCORRUPTED))
- return(error);
- if (bp)
- leaf = bp->data;
- if (bp && be16_to_cpu(leaf->hdr.info.magic) != XFS_DIR_LEAF_MAGIC) {
- xfs_dir_trace_g_dub("node: block not a leaf",
- dp, uio, bno);
- xfs_da_brelse(trans, bp);
- bp = NULL;
- }
- if (bp && INT_GET(leaf->entries[0].hashval, ARCH_CONVERT) > cookhash) {
- xfs_dir_trace_g_dub("node: leaf hash too large",
- dp, uio, bno);
- xfs_da_brelse(trans, bp);
- bp = NULL;
- }
- if (bp &&
- cookhash > INT_GET(leaf->entries[INT_GET(leaf->hdr.count, ARCH_CONVERT) - 1].hashval, ARCH_CONVERT)) {
- xfs_dir_trace_g_dub("node: leaf hash too small",
- dp, uio, bno);
- xfs_da_brelse(trans, bp);
- bp = NULL;
- }
- }
-
- /*
- * If we did not find a leaf block from the blockno in the cookie,
- * or we there was no blockno in the cookie (eg: first time thru),
- * the we start at the top of the Btree and re-find our hashval.
- */
- if (bp == NULL) {
- xfs_dir_trace_g_du("node: start at root" , dp, uio);
- bno = 0;
- for (;;) {
- error = xfs_da_read_buf(trans, dp, bno, -1, &bp,
- XFS_DATA_FORK);
- if (error)
- return(error);
- if (bp == NULL)
- return(XFS_ERROR(EFSCORRUPTED));
- node = bp->data;
- if (be16_to_cpu(node->hdr.info.magic) != XFS_DA_NODE_MAGIC)
- break;
- btree = &node->btree[0];
- xfs_dir_trace_g_dun("node: node detail", dp, uio, node);
- for (i = 0; i < be16_to_cpu(node->hdr.count); btree++, i++) {
- if (be32_to_cpu(btree->hashval) >= cookhash) {
- bno = be32_to_cpu(btree->before);
- break;
- }
- }
- if (i == be16_to_cpu(node->hdr.count)) {
- xfs_da_brelse(trans, bp);
- xfs_dir_trace_g_du("node: hash beyond EOF",
- dp, uio);
- uio->uio_offset = XFS_DA_MAKE_COOKIE(mp, 0, 0,
- XFS_DA_MAXHASH);
- *eofp = 1;
- return(0);
- }
- xfs_dir_trace_g_dub("node: going to block",
- dp, uio, bno);
- xfs_da_brelse(trans, bp);
- }
- }
- ASSERT(cookhash != XFS_DA_MAXHASH);
-
- /*
- * We've dropped down to the (first) leaf block that contains the
- * hashval we are interested in. Continue rolling upward thru the
- * leaf blocks until we fill up our buffer.
- */
- for (;;) {
- leaf = bp->data;
- if (unlikely(be16_to_cpu(leaf->hdr.info.magic) != XFS_DIR_LEAF_MAGIC)) {
- xfs_dir_trace_g_dul("node: not a leaf", dp, uio, leaf);
- xfs_da_brelse(trans, bp);
- XFS_CORRUPTION_ERROR("xfs_dir_node_getdents(1)",
- XFS_ERRLEVEL_LOW, mp, leaf);
- return XFS_ERROR(EFSCORRUPTED);
- }
- xfs_dir_trace_g_dul("node: leaf detail", dp, uio, leaf);
- if ((nextbno = be32_to_cpu(leaf->hdr.info.forw))) {
- nextda = xfs_da_reada_buf(trans, dp, nextbno,
- XFS_DATA_FORK);
- } else
- nextda = -1;
- error = xfs_dir_leaf_getdents_int(bp, dp, bno, uio, &eob, dbp,
- put, nextda);
- xfs_da_brelse(trans, bp);
- bno = nextbno;
- if (eob) {
- xfs_dir_trace_g_dub("node: E-O-B", dp, uio, bno);
- *eofp = 0;
- return(error);
- }
- if (bno == 0)
- break;
- error = xfs_da_read_buf(trans, dp, bno, nextda, &bp,
- XFS_DATA_FORK);
- if (error)
- return(error);
- if (unlikely(bp == NULL)) {
- XFS_ERROR_REPORT("xfs_dir_node_getdents(2)",
- XFS_ERRLEVEL_LOW, mp);
- return(XFS_ERROR(EFSCORRUPTED));
- }
- }
- *eofp = 1;
- xfs_dir_trace_g_du("node: E-O-F", dp, uio);
- return(0);
-}
-
-/*
- * Look up a filename in an int directory, replace the inode number.
- * Use an internal routine to actually do the lookup.
- */
-STATIC int
-xfs_dir_node_replace(xfs_da_args_t *args)
-{
- xfs_da_state_t *state;
- xfs_da_state_blk_t *blk;
- xfs_dir_leafblock_t *leaf;
- xfs_dir_leaf_entry_t *entry;
- xfs_dir_leaf_name_t *namest;
- xfs_ino_t inum;
- int retval, error, i;
- xfs_dabuf_t *bp;
-
- state = xfs_da_state_alloc();
- state->args = args;
- state->mp = args->dp->i_mount;
- state->blocksize = state->mp->m_sb.sb_blocksize;
- state->node_ents = state->mp->m_dir_node_ents;
- inum = args->inumber;
-
- /*
- * Search to see if name exists,
- * and get back a pointer to it.
- */
- error = xfs_da_node_lookup_int(state, &retval);
- if (error) {
- retval = error;
- }
-
- if (retval == EEXIST) {
- blk = &state->path.blk[state->path.active - 1];
- ASSERT(blk->magic == XFS_DIR_LEAF_MAGIC);
- bp = blk->bp;
- leaf = bp->data;
- entry = &leaf->entries[blk->index];
- namest = XFS_DIR_LEAF_NAMESTRUCT(leaf, INT_GET(entry->nameidx, ARCH_CONVERT));
- /* XXX - replace assert ? */
- XFS_DIR_SF_PUT_DIRINO(&inum, &namest->inumber);
- xfs_da_log_buf(args->trans, bp,
- XFS_DA_LOGRANGE(leaf, namest, sizeof(namest->inumber)));
- xfs_da_buf_done(bp);
- blk->bp = NULL;
- retval = 0;
- } else {
- i = state->path.active - 1;
- xfs_da_brelse(args->trans, state->path.blk[i].bp);
- state->path.blk[i].bp = NULL;
- }
- for (i = 0; i < state->path.active - 1; i++) {
- xfs_da_brelse(args->trans, state->path.blk[i].bp);
- state->path.blk[i].bp = NULL;
- }
-
- xfs_da_state_free(state);
- return(retval);
-}
-
-#if defined(XFS_DIR_TRACE)
-/*
- * Add a trace buffer entry for an inode and a uio.
- */
-void
-xfs_dir_trace_g_du(char *where, xfs_inode_t *dp, uio_t *uio)
-{
- xfs_dir_trace_enter(XFS_DIR_KTRACE_G_DU, where,
- (void *)dp, (void *)dp->i_mount,
- (void *)((unsigned long)(uio->uio_offset >> 32)),
- (void *)((unsigned long)(uio->uio_offset & 0xFFFFFFFF)),
- (void *)(unsigned long)uio->uio_resid,
- NULL, NULL, NULL, NULL, NULL, NULL, NULL);
-}
-
-/*
- * Add a trace buffer entry for an inode and a uio.
- */
-void
-xfs_dir_trace_g_dub(char *where, xfs_inode_t *dp, uio_t *uio, xfs_dablk_t bno)
-{
- xfs_dir_trace_enter(XFS_DIR_KTRACE_G_DUB, where,
- (void *)dp, (void *)dp->i_mount,
- (void *)((unsigned long)(uio->uio_offset >> 32)),
- (void *)((unsigned long)(uio->uio_offset & 0xFFFFFFFF)),
- (void *)(unsigned long)uio->uio_resid,
- (void *)(unsigned long)bno,
- NULL, NULL, NULL, NULL, NULL, NULL);
-}
-
-/*
- * Add a trace buffer entry for an inode and a uio.
- */
-void
-xfs_dir_trace_g_dun(char *where, xfs_inode_t *dp, uio_t *uio,
- xfs_da_intnode_t *node)
-{
- int last = be16_to_cpu(node->hdr.count) - 1;
-
- xfs_dir_trace_enter(XFS_DIR_KTRACE_G_DUN, where,
- (void *)dp, (void *)dp->i_mount,
- (void *)((unsigned long)(uio->uio_offset >> 32)),
- (void *)((unsigned long)(uio->uio_offset & 0xFFFFFFFF)),
- (void *)(unsigned long)uio->uio_resid,
- (void *)(unsigned long)be32_to_cpu(node->hdr.info.forw),
- (void *)(unsigned long)
- be16_to_cpu(node->hdr.count),
- (void *)(unsigned long)
- be32_to_cpu(node->btree[0].hashval),
- (void *)(unsigned long)
- be32_to_cpu(node->btree[last].hashval),
- NULL, NULL, NULL);
-}
-
-/*
- * Add a trace buffer entry for an inode and a uio.
- */
-void
-xfs_dir_trace_g_dul(char *where, xfs_inode_t *dp, uio_t *uio,
- xfs_dir_leafblock_t *leaf)
-{
- int last = INT_GET(leaf->hdr.count, ARCH_CONVERT) - 1;
-
- xfs_dir_trace_enter(XFS_DIR_KTRACE_G_DUL, where,
- (void *)dp, (void *)dp->i_mount,
- (void *)((unsigned long)(uio->uio_offset >> 32)),
- (void *)((unsigned long)(uio->uio_offset & 0xFFFFFFFF)),
- (void *)(unsigned long)uio->uio_resid,
- (void *)(unsigned long)be32_to_cpu(leaf->hdr.info.forw),
- (void *)(unsigned long)
- INT_GET(leaf->hdr.count, ARCH_CONVERT),
- (void *)(unsigned long)
- INT_GET(leaf->entries[0].hashval, ARCH_CONVERT),
- (void *)(unsigned long)
- INT_GET(leaf->entries[last].hashval, ARCH_CONVERT),
- NULL, NULL, NULL);
-}
-
-/*
- * Add a trace buffer entry for an inode and a uio.
- */
-void
-xfs_dir_trace_g_due(char *where, xfs_inode_t *dp, uio_t *uio,
- xfs_dir_leaf_entry_t *entry)
-{
- xfs_dir_trace_enter(XFS_DIR_KTRACE_G_DUE, where,
- (void *)dp, (void *)dp->i_mount,
- (void *)((unsigned long)(uio->uio_offset >> 32)),
- (void *)((unsigned long)(uio->uio_offset & 0xFFFFFFFF)),
- (void *)(unsigned long)uio->uio_resid,
- (void *)(unsigned long)
- INT_GET(entry->hashval, ARCH_CONVERT),
- NULL, NULL, NULL, NULL, NULL, NULL);
-}
-
-/*
- * Add a trace buffer entry for an inode and a uio.
- */
-void
-xfs_dir_trace_g_duc(char *where, xfs_inode_t *dp, uio_t *uio, xfs_off_t cookie)
-{
- xfs_dir_trace_enter(XFS_DIR_KTRACE_G_DUC, where,
- (void *)dp, (void *)dp->i_mount,
- (void *)((unsigned long)(uio->uio_offset >> 32)),
- (void *)((unsigned long)(uio->uio_offset & 0xFFFFFFFF)),
- (void *)(unsigned long)uio->uio_resid,
- (void *)((unsigned long)(cookie >> 32)),
- (void *)((unsigned long)(cookie & 0xFFFFFFFF)),
- NULL, NULL, NULL, NULL, NULL);
-}
-
-/*
- * Add a trace buffer entry for the arguments given to the routine,
- * generic form.
- */
-void
-xfs_dir_trace_enter(int type, char *where,
- void * a0, void * a1,
- void * a2, void * a3,
- void * a4, void * a5,
- void * a6, void * a7,
- void * a8, void * a9,
- void * a10, void * a11)
-{
- ASSERT(xfs_dir_trace_buf);
- ktrace_enter(xfs_dir_trace_buf, (void *)(unsigned long)type,
- (void *)where,
- (void *)a0, (void *)a1, (void *)a2,
- (void *)a3, (void *)a4, (void *)a5,
- (void *)a6, (void *)a7, (void *)a8,
- (void *)a9, (void *)a10, (void *)a11,
- NULL, NULL);
-}
-#endif /* XFS_DIR_TRACE */
diff --git a/sys/gnu/fs/xfs/xfs_dir.h b/sys/gnu/fs/xfs/xfs_dir.h
deleted file mode 100644
index 8cc8afb..0000000
--- a/sys/gnu/fs/xfs/xfs_dir.h
+++ /dev/null
@@ -1,142 +0,0 @@
-/*
- * Copyright (c) 2000,2005 Silicon Graphics, Inc.
- * All Rights Reserved.
- *
- * 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.
- *
- * This program is distributed in the hope that it would 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 the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- */
-#ifndef __XFS_DIR_H__
-#define __XFS_DIR_H__
-
-/*
- * Large directories are structured around Btrees where all the data
- * elements are in the leaf nodes. Filenames are hashed into an int,
- * then that int is used as the index into the Btree. Since the hashval
- * of a filename may not be unique, we may have duplicate keys. The
- * internal links in the Btree are logical block offsets into the file.
- *
- * Small directories use a different format and are packed as tightly
- * as possible so as to fit into the literal area of the inode.
- */
-
-/*========================================================================
- * Function prototypes for the kernel.
- *========================================================================*/
-
-struct uio;
-struct xfs_bmap_free;
-struct xfs_da_args;
-struct xfs_dinode;
-struct xfs_inode;
-struct xfs_mount;
-struct xfs_trans;
-
-/*
- * Directory function types.
- * Put in structures (xfs_dirops_t) for v1 and v2 directories.
- */
-typedef void (*xfs_dir_mount_t)(struct xfs_mount *mp);
-typedef int (*xfs_dir_isempty_t)(struct xfs_inode *dp);
-typedef int (*xfs_dir_init_t)(struct xfs_trans *tp,
- struct xfs_inode *dp,
- struct xfs_inode *pdp);
-typedef int (*xfs_dir_createname_t)(struct xfs_trans *tp,
- struct xfs_inode *dp,
- char *name,
- int namelen,
- xfs_ino_t inum,
- xfs_fsblock_t *first,
- struct xfs_bmap_free *flist,
- xfs_extlen_t total);
-typedef int (*xfs_dir_lookup_t)(struct xfs_trans *tp,
- struct xfs_inode *dp,
- char *name,
- int namelen,
- xfs_ino_t *inum);
-typedef int (*xfs_dir_removename_t)(struct xfs_trans *tp,
- struct xfs_inode *dp,
- char *name,
- int namelen,
- xfs_ino_t ino,
- xfs_fsblock_t *first,
- struct xfs_bmap_free *flist,
- xfs_extlen_t total);
-typedef int (*xfs_dir_getdents_t)(struct xfs_trans *tp,
- struct xfs_inode *dp,
- struct uio *uio,
- int *eofp);
-typedef int (*xfs_dir_replace_t)(struct xfs_trans *tp,
- struct xfs_inode *dp,
- char *name,
- int namelen,
- xfs_ino_t inum,
- xfs_fsblock_t *first,
- struct xfs_bmap_free *flist,
- xfs_extlen_t total);
-typedef int (*xfs_dir_canenter_t)(struct xfs_trans *tp,
- struct xfs_inode *dp,
- char *name,
- int namelen);
-typedef int (*xfs_dir_shortform_validate_ondisk_t)(struct xfs_mount *mp,
- struct xfs_dinode *dip);
-typedef int (*xfs_dir_shortform_to_single_t)(struct xfs_da_args *args);
-
-typedef struct xfs_dirops {
- xfs_dir_mount_t xd_mount;
- xfs_dir_isempty_t xd_isempty;
- xfs_dir_init_t xd_init;
- xfs_dir_createname_t xd_createname;
- xfs_dir_lookup_t xd_lookup;
- xfs_dir_removename_t xd_removename;
- xfs_dir_getdents_t xd_getdents;
- xfs_dir_replace_t xd_replace;
- xfs_dir_canenter_t xd_canenter;
- xfs_dir_shortform_validate_ondisk_t xd_shortform_validate_ondisk;
- xfs_dir_shortform_to_single_t xd_shortform_to_single;
-} xfs_dirops_t;
-
-/*
- * Overall external interface routines.
- */
-void xfs_dir_startup(void); /* called exactly once */
-
-#define XFS_DIR_MOUNT(mp) \
- ((mp)->m_dirops.xd_mount(mp))
-#define XFS_DIR_ISEMPTY(mp,dp) \
- ((mp)->m_dirops.xd_isempty(dp))
-#define XFS_DIR_INIT(mp,tp,dp,pdp) \
- ((mp)->m_dirops.xd_init(tp,dp,pdp))
-#define XFS_DIR_CREATENAME(mp,tp,dp,name,namelen,inum,first,flist,total) \
- ((mp)->m_dirops.xd_createname(tp,dp,name,namelen,inum,first,flist,\
- total))
-#define XFS_DIR_LOOKUP(mp,tp,dp,name,namelen,inum) \
- ((mp)->m_dirops.xd_lookup(tp,dp,name,namelen,inum))
-#define XFS_DIR_REMOVENAME(mp,tp,dp,name,namelen,ino,first,flist,total) \
- ((mp)->m_dirops.xd_removename(tp,dp,name,namelen,ino,first,flist,total))
-#define XFS_DIR_GETDENTS(mp,tp,dp,uio,eofp) \
- ((mp)->m_dirops.xd_getdents(tp,dp,uio,eofp))
-#define XFS_DIR_REPLACE(mp,tp,dp,name,namelen,inum,first,flist,total) \
- ((mp)->m_dirops.xd_replace(tp,dp,name,namelen,inum,first,flist,total))
-#define XFS_DIR_CANENTER(mp,tp,dp,name,namelen) \
- ((mp)->m_dirops.xd_canenter(tp,dp,name,namelen))
-#define XFS_DIR_SHORTFORM_VALIDATE_ONDISK(mp,dip) \
- ((mp)->m_dirops.xd_shortform_validate_ondisk(mp,dip))
-#define XFS_DIR_SHORTFORM_TO_SINGLE(mp,args) \
- ((mp)->m_dirops.xd_shortform_to_single(args))
-
-#define XFS_DIR_IS_V1(mp) ((mp)->m_dirversion == 1)
-#define XFS_DIR_IS_V2(mp) ((mp)->m_dirversion == 2)
-extern xfs_dirops_t xfsv1_dirops;
-extern xfs_dirops_t xfsv2_dirops;
-
-#endif /* __XFS_DIR_H__ */
diff --git a/sys/gnu/fs/xfs/xfs_dir2.c b/sys/gnu/fs/xfs/xfs_dir2.c
deleted file mode 100644
index 12ee653..0000000
--- a/sys/gnu/fs/xfs/xfs_dir2.c
+++ /dev/null
@@ -1,851 +0,0 @@
-/*
- * Copyright (c) 2000-2001,2005 Silicon Graphics, Inc.
- * All Rights Reserved.
- *
- * 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.
- *
- * This program is distributed in the hope that it would 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 the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- */
-#include "xfs.h"
-#include "xfs_fs.h"
-#include "xfs_types.h"
-#include "xfs_bit.h"
-#include "xfs_log.h"
-#include "xfs_inum.h"
-#include "xfs_trans.h"
-#include "xfs_sb.h"
-#include "xfs_ag.h"
-#include "xfs_dir.h"
-#include "xfs_dir2.h"
-#include "xfs_dmapi.h"
-#include "xfs_mount.h"
-#include "xfs_da_btree.h"
-#include "xfs_bmap_btree.h"
-#include "xfs_alloc_btree.h"
-#include "xfs_dir_sf.h"
-#include "xfs_dir2_sf.h"
-#include "xfs_attr_sf.h"
-#include "xfs_dinode.h"
-#include "xfs_inode.h"
-#include "xfs_inode_item.h"
-#include "xfs_bmap.h"
-#include "xfs_dir_leaf.h"
-#include "xfs_dir2_data.h"
-#include "xfs_dir2_leaf.h"
-#include "xfs_dir2_block.h"
-#include "xfs_dir2_node.h"
-#include "xfs_dir2_trace.h"
-#include "xfs_error.h"
-
-/*
- * Declarations for interface routines.
- */
-static void xfs_dir2_mount(xfs_mount_t *mp);
-static int xfs_dir2_isempty(xfs_inode_t *dp);
-static int xfs_dir2_init(xfs_trans_t *tp, xfs_inode_t *dp,
- xfs_inode_t *pdp);
-static int xfs_dir2_createname(xfs_trans_t *tp, xfs_inode_t *dp,
- char *name, int namelen, xfs_ino_t inum,
- xfs_fsblock_t *first,
- xfs_bmap_free_t *flist, xfs_extlen_t total);
-static int xfs_dir2_lookup(xfs_trans_t *tp, xfs_inode_t *dp, char *name,
- int namelen, xfs_ino_t *inum);
-static int xfs_dir2_removename(xfs_trans_t *tp, xfs_inode_t *dp,
- char *name, int namelen, xfs_ino_t ino,
- xfs_fsblock_t *first,
- xfs_bmap_free_t *flist, xfs_extlen_t total);
-static int xfs_dir2_getdents(xfs_trans_t *tp, xfs_inode_t *dp, uio_t *uio,
- int *eofp);
-static int xfs_dir2_replace(xfs_trans_t *tp, xfs_inode_t *dp, char *name,
- int namelen, xfs_ino_t inum,
- xfs_fsblock_t *first, xfs_bmap_free_t *flist,
- xfs_extlen_t total);
-static int xfs_dir2_canenter(xfs_trans_t *tp, xfs_inode_t *dp, char *name,
- int namelen);
-static int xfs_dir2_shortform_validate_ondisk(xfs_mount_t *mp,
- xfs_dinode_t *dip);
-
-/*
- * Utility routine declarations.
- */
-static int xfs_dir2_put_dirent64_direct(xfs_dir2_put_args_t *pa);
-static int xfs_dir2_put_dirent64_uio(xfs_dir2_put_args_t *pa);
-
-/*
- * Directory operations vector.
- */
-xfs_dirops_t xfsv2_dirops = {
- .xd_mount = xfs_dir2_mount,
- .xd_isempty = xfs_dir2_isempty,
- .xd_init = xfs_dir2_init,
- .xd_createname = xfs_dir2_createname,
- .xd_lookup = xfs_dir2_lookup,
- .xd_removename = xfs_dir2_removename,
- .xd_getdents = xfs_dir2_getdents,
- .xd_replace = xfs_dir2_replace,
- .xd_canenter = xfs_dir2_canenter,
- .xd_shortform_validate_ondisk = xfs_dir2_shortform_validate_ondisk,
- .xd_shortform_to_single = xfs_dir2_sf_to_block,
-};
-
-/*
- * Interface routines.
- */
-
-/*
- * Initialize directory-related fields in the mount structure.
- */
-static void
-xfs_dir2_mount(
- xfs_mount_t *mp) /* filesystem mount point */
-{
- mp->m_dirversion = 2;
- ASSERT((1 << (mp->m_sb.sb_blocklog + mp->m_sb.sb_dirblklog)) <=
- XFS_MAX_BLOCKSIZE);
- mp->m_dirblksize = 1 << (mp->m_sb.sb_blocklog + mp->m_sb.sb_dirblklog);
- mp->m_dirblkfsbs = 1 << mp->m_sb.sb_dirblklog;
- mp->m_dirdatablk = XFS_DIR2_DB_TO_DA(mp, XFS_DIR2_DATA_FIRSTDB(mp));
- mp->m_dirleafblk = XFS_DIR2_DB_TO_DA(mp, XFS_DIR2_LEAF_FIRSTDB(mp));
- mp->m_dirfreeblk = XFS_DIR2_DB_TO_DA(mp, XFS_DIR2_FREE_FIRSTDB(mp));
- mp->m_attr_node_ents =
- (mp->m_sb.sb_blocksize - (uint)sizeof(xfs_da_node_hdr_t)) /
- (uint)sizeof(xfs_da_node_entry_t);
- mp->m_dir_node_ents =
- (mp->m_dirblksize - (uint)sizeof(xfs_da_node_hdr_t)) /
- (uint)sizeof(xfs_da_node_entry_t);
- mp->m_dir_magicpct = (mp->m_dirblksize * 37) / 100;
-}
-
-/*
- * Return 1 if directory contains only "." and "..".
- */
-static int /* return code */
-xfs_dir2_isempty(
- xfs_inode_t *dp) /* incore inode structure */
-{
- xfs_dir2_sf_t *sfp; /* shortform directory structure */
-
- ASSERT((dp->i_d.di_mode & S_IFMT) == S_IFDIR);
- /*
- * Might happen during shutdown.
- */
- if (dp->i_d.di_size == 0) {
- return 1;
- }
- if (dp->i_d.di_size > XFS_IFORK_DSIZE(dp))
- return 0;
- sfp = (xfs_dir2_sf_t *)dp->i_df.if_u1.if_data;
- return !sfp->hdr.count;
-}
-
-/*
- * Initialize a directory with its "." and ".." entries.
- */
-static int /* error */
-xfs_dir2_init(
- xfs_trans_t *tp, /* transaction pointer */
- xfs_inode_t *dp, /* incore directory inode */
- xfs_inode_t *pdp) /* incore parent directory inode */
-{
- xfs_da_args_t args; /* operation arguments */
- int error; /* error return value */
-
- memset((char *)&args, 0, sizeof(args));
- args.dp = dp;
- args.trans = tp;
- ASSERT((dp->i_d.di_mode & S_IFMT) == S_IFDIR);
- if ((error = xfs_dir_ino_validate(tp->t_mountp, pdp->i_ino))) {
- return error;
- }
- return xfs_dir2_sf_create(&args, pdp->i_ino);
-}
-
-/*
- Enter a name in a directory.
- */
-static int /* error */
-xfs_dir2_createname(
- xfs_trans_t *tp, /* transaction pointer */
- xfs_inode_t *dp, /* incore directory inode */
- char *name, /* new entry name */
- int namelen, /* new entry name length */
- xfs_ino_t inum, /* new entry inode number */
- xfs_fsblock_t *first, /* bmap's firstblock */
- xfs_bmap_free_t *flist, /* bmap's freeblock list */
- xfs_extlen_t total) /* bmap's total block count */
-{
- xfs_da_args_t args; /* operation arguments */
- int rval; /* return value */
- int v; /* type-checking value */
-
- ASSERT((dp->i_d.di_mode & S_IFMT) == S_IFDIR);
- if ((rval = xfs_dir_ino_validate(tp->t_mountp, inum))) {
- return rval;
- }
- XFS_STATS_INC(xs_dir_create);
- /*
- * Fill in the arg structure for this request.
- */
- args.name = name;
- args.namelen = namelen;
- args.hashval = xfs_da_hashname(name, namelen);
- args.inumber = inum;
- args.dp = dp;
- args.firstblock = first;
- args.flist = flist;
- args.total = total;
- args.whichfork = XFS_DATA_FORK;
- args.trans = tp;
- args.justcheck = 0;
- args.addname = args.oknoent = 1;
- /*
- * Decide on what work routines to call based on the inode size.
- */
- if (dp->i_d.di_format == XFS_DINODE_FMT_LOCAL)
- rval = xfs_dir2_sf_addname(&args);
- else if ((rval = xfs_dir2_isblock(tp, dp, &v))) {
- return rval;
- } else if (v)
- rval = xfs_dir2_block_addname(&args);
- else if ((rval = xfs_dir2_isleaf(tp, dp, &v))) {
- return rval;
- } else if (v)
- rval = xfs_dir2_leaf_addname(&args);
- else
- rval = xfs_dir2_node_addname(&args);
- return rval;
-}
-
-/*
- * Lookup a name in a directory, give back the inode number.
- */
-static int /* error */
-xfs_dir2_lookup(
- xfs_trans_t *tp, /* transaction pointer */
- xfs_inode_t *dp, /* incore directory inode */
- char *name, /* lookup name */
- int namelen, /* lookup name length */
- xfs_ino_t *inum) /* out: inode number */
-{
- xfs_da_args_t args; /* operation arguments */
- int rval; /* return value */
- int v; /* type-checking value */
-
- ASSERT((dp->i_d.di_mode & S_IFMT) == S_IFDIR);
- XFS_STATS_INC(xs_dir_lookup);
-
- /*
- * Fill in the arg structure for this request.
- */
- args.name = name;
- args.namelen = namelen;
- args.hashval = xfs_da_hashname(name, namelen);
- args.inumber = 0;
- args.dp = dp;
- args.firstblock = NULL;
- args.flist = NULL;
- args.total = 0;
- args.whichfork = XFS_DATA_FORK;
- args.trans = tp;
- args.justcheck = args.addname = 0;
- args.oknoent = 1;
- /*
- * Decide on what work routines to call based on the inode size.
- */
- if (dp->i_d.di_format == XFS_DINODE_FMT_LOCAL)
- rval = xfs_dir2_sf_lookup(&args);
- else if ((rval = xfs_dir2_isblock(tp, dp, &v))) {
- return rval;
- } else if (v)
- rval = xfs_dir2_block_lookup(&args);
- else if ((rval = xfs_dir2_isleaf(tp, dp, &v))) {
- return rval;
- } else if (v)
- rval = xfs_dir2_leaf_lookup(&args);
- else
- rval = xfs_dir2_node_lookup(&args);
- if (rval == EEXIST)
- rval = 0;
- if (rval == 0)
- *inum = args.inumber;
- return rval;
-}
-
-/*
- * Remove an entry from a directory.
- */
-static int /* error */
-xfs_dir2_removename(
- xfs_trans_t *tp, /* transaction pointer */
- xfs_inode_t *dp, /* incore directory inode */
- char *name, /* name of entry to remove */
- int namelen, /* name length of entry to remove */
- xfs_ino_t ino, /* inode number of entry to remove */
- xfs_fsblock_t *first, /* bmap's firstblock */
- xfs_bmap_free_t *flist, /* bmap's freeblock list */
- xfs_extlen_t total) /* bmap's total block count */
-{
- xfs_da_args_t args; /* operation arguments */
- int rval; /* return value */
- int v; /* type-checking value */
-
- ASSERT((dp->i_d.di_mode & S_IFMT) == S_IFDIR);
- XFS_STATS_INC(xs_dir_remove);
- /*
- * Fill in the arg structure for this request.
- */
- args.name = name;
- args.namelen = namelen;
- args.hashval = xfs_da_hashname(name, namelen);
- args.inumber = ino;
- args.dp = dp;
- args.firstblock = first;
- args.flist = flist;
- args.total = total;
- args.whichfork = XFS_DATA_FORK;
- args.trans = tp;
- args.justcheck = args.addname = args.oknoent = 0;
- /*
- * Decide on what work routines to call based on the inode size.
- */
- if (dp->i_d.di_format == XFS_DINODE_FMT_LOCAL)
- rval = xfs_dir2_sf_removename(&args);
- else if ((rval = xfs_dir2_isblock(tp, dp, &v))) {
- return rval;
- } else if (v)
- rval = xfs_dir2_block_removename(&args);
- else if ((rval = xfs_dir2_isleaf(tp, dp, &v))) {
- return rval;
- } else if (v)
- rval = xfs_dir2_leaf_removename(&args);
- else
- rval = xfs_dir2_node_removename(&args);
- return rval;
-}
-
-/*
- * Read a directory.
- */
-static int /* error */
-xfs_dir2_getdents(
- xfs_trans_t *tp, /* transaction pointer */
- xfs_inode_t *dp, /* incore directory inode */
- uio_t *uio, /* caller's buffer control */
- int *eofp) /* out: eof reached */
-{
- int alignment; /* alignment required for ABI */
- xfs_dirent_t *dbp; /* malloc'ed buffer */
- xfs_dir2_put_t put; /* entry formatting routine */
- int rval; /* return value */
- int v; /* type-checking value */
-
- ASSERT((dp->i_d.di_mode & S_IFMT) == S_IFDIR);
- XFS_STATS_INC(xs_dir_getdents);
- /*
- * If our caller has given us a single contiguous aligned memory buffer,
- * just work directly within that buffer. If it's in user memory,
- * lock it down first.
- */
- alignment = sizeof(xfs_off_t) - 1;
- if ((uio->uio_iovcnt == 1) &&
- (((__psint_t)uio->uio_iov[0].iov_base & alignment) == 0) &&
- ((uio->uio_iov[0].iov_len & alignment) == 0)) {
- dbp = NULL;
- put = xfs_dir2_put_dirent64_direct;
- } else {
- dbp = kmem_alloc(sizeof(*dbp) + MAXNAMELEN, KM_SLEEP);
- put = xfs_dir2_put_dirent64_uio;
- }
-
- *eofp = 0;
- /*
- * Decide on what work routines to call based on the inode size.
- */
- if (dp->i_d.di_format == XFS_DINODE_FMT_LOCAL)
- rval = xfs_dir2_sf_getdents(dp, uio, eofp, dbp, put);
- else if ((rval = xfs_dir2_isblock(tp, dp, &v))) {
- ;
- } else if (v)
- rval = xfs_dir2_block_getdents(tp, dp, uio, eofp, dbp, put);
- else
- rval = xfs_dir2_leaf_getdents(tp, dp, uio, eofp, dbp, put);
- if (dbp != NULL)
- kmem_free(dbp, sizeof(*dbp) + MAXNAMELEN);
- return rval;
-}
-
-/*
- * Replace the inode number of a directory entry.
- */
-static int /* error */
-xfs_dir2_replace(
- xfs_trans_t *tp, /* transaction pointer */
- xfs_inode_t *dp, /* incore directory inode */
- char *name, /* name of entry to replace */
- int namelen, /* name length of entry to replace */
- xfs_ino_t inum, /* new inode number */
- xfs_fsblock_t *first, /* bmap's firstblock */
- xfs_bmap_free_t *flist, /* bmap's freeblock list */
- xfs_extlen_t total) /* bmap's total block count */
-{
- xfs_da_args_t args; /* operation arguments */
- int rval; /* return value */
- int v; /* type-checking value */
-
- ASSERT((dp->i_d.di_mode & S_IFMT) == S_IFDIR);
-
- if ((rval = xfs_dir_ino_validate(tp->t_mountp, inum))) {
- return rval;
- }
- /*
- * Fill in the arg structure for this request.
- */
- args.name = name;
- args.namelen = namelen;
- args.hashval = xfs_da_hashname(name, namelen);
- args.inumber = inum;
- args.dp = dp;
- args.firstblock = first;
- args.flist = flist;
- args.total = total;
- args.whichfork = XFS_DATA_FORK;
- args.trans = tp;
- args.justcheck = args.addname = args.oknoent = 0;
- /*
- * Decide on what work routines to call based on the inode size.
- */
- if (dp->i_d.di_format == XFS_DINODE_FMT_LOCAL)
- rval = xfs_dir2_sf_replace(&args);
- else if ((rval = xfs_dir2_isblock(tp, dp, &v))) {
- return rval;
- } else if (v)
- rval = xfs_dir2_block_replace(&args);
- else if ((rval = xfs_dir2_isleaf(tp, dp, &v))) {
- return rval;
- } else if (v)
- rval = xfs_dir2_leaf_replace(&args);
- else
- rval = xfs_dir2_node_replace(&args);
- return rval;
-}
-
-/*
- * See if this entry can be added to the directory without allocating space.
- */
-static int /* error */
-xfs_dir2_canenter(
- xfs_trans_t *tp, /* transaction pointer */
- xfs_inode_t *dp, /* incore directory inode */
- char *name, /* name of entry to add */
- int namelen) /* name length of entry to add */
-{
- xfs_da_args_t args; /* operation arguments */
- int rval; /* return value */
- int v; /* type-checking value */
-
- ASSERT((dp->i_d.di_mode & S_IFMT) == S_IFDIR);
- /*
- * Fill in the arg structure for this request.
- */
- args.name = name;
- args.namelen = namelen;
- args.hashval = xfs_da_hashname(name, namelen);
- args.inumber = 0;
- args.dp = dp;
- args.firstblock = NULL;
- args.flist = NULL;
- args.total = 0;
- args.whichfork = XFS_DATA_FORK;
- args.trans = tp;
- args.justcheck = args.addname = args.oknoent = 1;
- /*
- * Decide on what work routines to call based on the inode size.
- */
- if (dp->i_d.di_format == XFS_DINODE_FMT_LOCAL)
- rval = xfs_dir2_sf_addname(&args);
- else if ((rval = xfs_dir2_isblock(tp, dp, &v))) {
- return rval;
- } else if (v)
- rval = xfs_dir2_block_addname(&args);
- else if ((rval = xfs_dir2_isleaf(tp, dp, &v))) {
- return rval;
- } else if (v)
- rval = xfs_dir2_leaf_addname(&args);
- else
- rval = xfs_dir2_node_addname(&args);
- return rval;
-}
-
-/*
- * Dummy routine for shortform inode validation.
- * Can't really do this.
- */
-/* ARGSUSED */
-static int /* error */
-xfs_dir2_shortform_validate_ondisk(
- xfs_mount_t *mp, /* filesystem mount point */
- xfs_dinode_t *dip) /* ondisk inode */
-{
- return 0;
-}
-
-/*
- * Utility routines.
- */
-
-/*
- * Add a block to the directory.
- * This routine is for data and free blocks, not leaf/node blocks
- * which are handled by xfs_da_grow_inode.
- */
-int /* error */
-xfs_dir2_grow_inode(
- xfs_da_args_t *args, /* operation arguments */
- int space, /* v2 dir's space XFS_DIR2_xxx_SPACE */
- xfs_dir2_db_t *dbp) /* out: block number added */
-{
- xfs_fileoff_t bno; /* directory offset of new block */
- int count; /* count of filesystem blocks */
- xfs_inode_t *dp; /* incore directory inode */
- int error; /* error return value */
- int got; /* blocks actually mapped */
- int i; /* temp mapping index */
- xfs_bmbt_irec_t map; /* single structure for bmap */
- int mapi; /* mapping index */
- xfs_bmbt_irec_t *mapp; /* bmap mapping structure(s) */
- xfs_mount_t *mp; /* filesystem mount point */
- int nmap; /* number of bmap entries */
- xfs_trans_t *tp; /* transaction pointer */
-
- xfs_dir2_trace_args_s("grow_inode", args, space);
- dp = args->dp;
- tp = args->trans;
- mp = dp->i_mount;
- /*
- * Set lowest possible block in the space requested.
- */
- bno = XFS_B_TO_FSBT(mp, space * XFS_DIR2_SPACE_SIZE);
- count = mp->m_dirblkfsbs;
- /*
- * Find the first hole for our block.
- */
- if ((error = xfs_bmap_first_unused(tp, dp, count, &bno, XFS_DATA_FORK))) {
- return error;
- }
- nmap = 1;
- ASSERT(args->firstblock != NULL);
- /*
- * Try mapping the new block contiguously (one extent).
- */
- if ((error = xfs_bmapi(tp, dp, bno, count,
- XFS_BMAPI_WRITE|XFS_BMAPI_METADATA|XFS_BMAPI_CONTIG,
- args->firstblock, args->total, &map, &nmap,
- args->flist, NULL))) {
- return error;
- }
- ASSERT(nmap <= 1);
- /*
- * Got it in 1.
- */
- if (nmap == 1) {
- mapp = &map;
- mapi = 1;
- }
- /*
- * Didn't work and this is a multiple-fsb directory block.
- * Try again with contiguous flag turned on.
- */
- else if (nmap == 0 && count > 1) {
- xfs_fileoff_t b; /* current file offset */
-
- /*
- * Space for maximum number of mappings.
- */
- mapp = kmem_alloc(sizeof(*mapp) * count, KM_SLEEP);
- /*
- * Iterate until we get to the end of our block.
- */
- for (b = bno, mapi = 0; b < bno + count; ) {
- int c; /* current fsb count */
-
- /*
- * Can't map more than MAX_NMAP at once.
- */
- nmap = MIN(XFS_BMAP_MAX_NMAP, count);
- c = (int)(bno + count - b);
- if ((error = xfs_bmapi(tp, dp, b, c,
- XFS_BMAPI_WRITE|XFS_BMAPI_METADATA,
- args->firstblock, args->total,
- &mapp[mapi], &nmap, args->flist,
- NULL))) {
- kmem_free(mapp, sizeof(*mapp) * count);
- return error;
- }
- if (nmap < 1)
- break;
- /*
- * Add this bunch into our table, go to the next offset.
- */
- mapi += nmap;
- b = mapp[mapi - 1].br_startoff +
- mapp[mapi - 1].br_blockcount;
- }
- }
- /*
- * Didn't work.
- */
- else {
- mapi = 0;
- mapp = NULL;
- }
- /*
- * See how many fsb's we got.
- */
- for (i = 0, got = 0; i < mapi; i++)
- got += mapp[i].br_blockcount;
- /*
- * Didn't get enough fsb's, or the first/last block's are wrong.
- */
- if (got != count || mapp[0].br_startoff != bno ||
- mapp[mapi - 1].br_startoff + mapp[mapi - 1].br_blockcount !=
- bno + count) {
- if (mapp != &map)
- kmem_free(mapp, sizeof(*mapp) * count);
- return XFS_ERROR(ENOSPC);
- }
- /*
- * Done with the temporary mapping table.
- */
- if (mapp != &map)
- kmem_free(mapp, sizeof(*mapp) * count);
- *dbp = XFS_DIR2_DA_TO_DB(mp, (xfs_dablk_t)bno);
- /*
- * Update file's size if this is the data space and it grew.
- */
- if (space == XFS_DIR2_DATA_SPACE) {
- xfs_fsize_t size; /* directory file (data) size */
-
- size = XFS_FSB_TO_B(mp, bno + count);
- if (size > dp->i_d.di_size) {
- dp->i_d.di_size = size;
- xfs_trans_log_inode(tp, dp, XFS_ILOG_CORE);
- }
- }
- return 0;
-}
-
-/*
- * See if the directory is a single-block form directory.
- */
-int /* error */
-xfs_dir2_isblock(
- xfs_trans_t *tp, /* transaction pointer */
- xfs_inode_t *dp, /* incore directory inode */
- int *vp) /* out: 1 is block, 0 is not block */
-{
- xfs_fileoff_t last; /* last file offset */
- xfs_mount_t *mp; /* filesystem mount point */
- int rval; /* return value */
-
- mp = dp->i_mount;
- if ((rval = xfs_bmap_last_offset(tp, dp, &last, XFS_DATA_FORK))) {
- return rval;
- }
- rval = XFS_FSB_TO_B(mp, last) == mp->m_dirblksize;
- ASSERT(rval == 0 || dp->i_d.di_size == mp->m_dirblksize);
- *vp = rval;
- return 0;
-}
-
-/*
- * See if the directory is a single-leaf form directory.
- */
-int /* error */
-xfs_dir2_isleaf(
- xfs_trans_t *tp, /* transaction pointer */
- xfs_inode_t *dp, /* incore directory inode */
- int *vp) /* out: 1 is leaf, 0 is not leaf */
-{
- xfs_fileoff_t last; /* last file offset */
- xfs_mount_t *mp; /* filesystem mount point */
- int rval; /* return value */
-
- mp = dp->i_mount;
- if ((rval = xfs_bmap_last_offset(tp, dp, &last, XFS_DATA_FORK))) {
- return rval;
- }
- *vp = last == mp->m_dirleafblk + (1 << mp->m_sb.sb_dirblklog);
- return 0;
-}
-
-/*
- * Getdents put routine for 64-bit ABI, direct form.
- */
-static int /* error */
-xfs_dir2_put_dirent64_direct(
- xfs_dir2_put_args_t *pa) /* argument bundle */
-{
- struct dirent *idbp, dtmp; /* dirent pointer */
- iovec_t *iovp; /* io vector */
- int namelen; /* entry name length */
- int reclen; /* entry total length */
- uio_t *uio; /* I/O control */
-
- namelen = pa->namelen;
-
- dtmp.d_namlen = namelen;
- dtmp.d_reclen = GENERIC_DIRSIZ(&dtmp);
- reclen = dtmp.d_reclen;
-
- uio = pa->uio;
- /*
- * Won't fit in the remaining space.
- */
- if (reclen > uio->uio_resid) {
- pa->done = 0;
- return 0;
- }
- iovp = uio->uio_iov;
- idbp = (struct dirent *)iovp->iov_base;
- iovp->iov_base = (char *)idbp + reclen;
- iovp->iov_len -= reclen;
- uio->uio_resid -= reclen;
- idbp->d_reclen = reclen;
- idbp->d_fileno = pa->ino;
- idbp->d_type = DT_UNKNOWN;
- idbp->d_namlen = namelen;
- memcpy(idbp->d_name, pa->name, namelen);
- idbp->d_name[namelen] = '\0';
- pa->done = 1;
- return 0;
-}
-
-/*
- * Getdents put routine for 64-bit ABI, uio form.
- */
-static int /* error */
-xfs_dir2_put_dirent64_uio(
- xfs_dir2_put_args_t *pa) /* argument bundle */
-{
- struct dirent *idbp, dtmp; /* dirent pointer */
- int namelen; /* entry name length */
- int reclen; /* entry total length */
- int rval; /* return value */
- uio_t *uio; /* I/O control */
-
- namelen = pa->namelen;
-
- dtmp.d_namlen = namelen;
- dtmp.d_reclen = GENERIC_DIRSIZ(&dtmp);
- reclen = dtmp.d_reclen;
-
- uio = pa->uio;
- /*
- * Won't fit in the remaining space.
- */
- if (reclen > uio->uio_resid) {
- pa->done = 0;
- return 0;
- }
- idbp = &dtmp;
- idbp->d_reclen = reclen;
- idbp->d_fileno = pa->ino;
- idbp->d_type = DT_UNKNOWN;
- idbp->d_namlen = namelen;
- memcpy(idbp->d_name, pa->name, namelen);
- idbp->d_name[namelen] = '\0';
- rval = uio_read((caddr_t)idbp, reclen, uio);
- pa->done = (rval == 0);
- return rval;
-}
-
-/*
- * Remove the given block from the directory.
- * This routine is used for data and free blocks, leaf/node are done
- * by xfs_da_shrink_inode.
- */
-int
-xfs_dir2_shrink_inode(
- xfs_da_args_t *args, /* operation arguments */
- xfs_dir2_db_t db, /* directory block number */
- xfs_dabuf_t *bp) /* block's buffer */
-{
- xfs_fileoff_t bno; /* directory file offset */
- xfs_dablk_t da; /* directory file offset */
- int done; /* bunmap is finished */
- xfs_inode_t *dp; /* incore directory inode */
- int error; /* error return value */
- xfs_mount_t *mp; /* filesystem mount point */
- xfs_trans_t *tp; /* transaction pointer */
-
- xfs_dir2_trace_args_db("shrink_inode", args, db, bp);
- dp = args->dp;
- mp = dp->i_mount;
- tp = args->trans;
- da = XFS_DIR2_DB_TO_DA(mp, db);
- /*
- * Unmap the fsblock(s).
- */
- if ((error = xfs_bunmapi(tp, dp, da, mp->m_dirblkfsbs,
- XFS_BMAPI_METADATA, 0, args->firstblock, args->flist,
- NULL, &done))) {
- /*
- * ENOSPC actually can happen if we're in a removename with
- * no space reservation, and the resulting block removal
- * would cause a bmap btree split or conversion from extents
- * to btree. This can only happen for un-fragmented
- * directory blocks, since you need to be punching out
- * the middle of an extent.
- * In this case we need to leave the block in the file,
- * and not binval it.
- * So the block has to be in a consistent empty state
- * and appropriately logged.
- * We don't free up the buffer, the caller can tell it
- * hasn't happened since it got an error back.
- */
- return error;
- }
- ASSERT(done);
- /*
- * Invalidate the buffer from the transaction.
- */
- xfs_da_binval(tp, bp);
- /*
- * If it's not a data block, we're done.
- */
- if (db >= XFS_DIR2_LEAF_FIRSTDB(mp))
- return 0;
- /*
- * If the block isn't the last one in the directory, we're done.
- */
- if (dp->i_d.di_size > XFS_DIR2_DB_OFF_TO_BYTE(mp, db + 1, 0))
- return 0;
- bno = da;
- if ((error = xfs_bmap_last_before(tp, dp, &bno, XFS_DATA_FORK))) {
- /*
- * This can't really happen unless there's kernel corruption.
- */
- return error;
- }
- if (db == mp->m_dirdatablk)
- ASSERT(bno == 0);
- else
- ASSERT(bno > 0);
- /*
- * Set the size to the new last block.
- */
- dp->i_d.di_size = XFS_FSB_TO_B(mp, bno);
- xfs_trans_log_inode(tp, dp, XFS_ILOG_CORE);
- return 0;
-}
-
-
diff --git a/sys/gnu/fs/xfs/xfs_dir2.h b/sys/gnu/fs/xfs/xfs_dir2.h
deleted file mode 100644
index 7dd364b..0000000
--- a/sys/gnu/fs/xfs/xfs_dir2.h
+++ /dev/null
@@ -1,87 +0,0 @@
-/*
- * Copyright (c) 2000-2001,2005 Silicon Graphics, Inc.
- * All Rights Reserved.
- *
- * 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.
- *
- * This program is distributed in the hope that it would 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 the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- */
-#ifndef __XFS_DIR2_H__
-#define __XFS_DIR2_H__
-
-struct uio;
-struct xfs_dabuf;
-struct xfs_da_args;
-struct xfs_dir2_put_args;
-struct xfs_inode;
-struct xfs_trans;
-
-/*
- * Directory version 2.
- * There are 4 possible formats:
- * shortform
- * single block - data with embedded leaf at the end
- * multiple data blocks, single leaf+freeindex block
- * data blocks, node&leaf blocks (btree), freeindex blocks
- *
- * The shortform format is in xfs_dir2_sf.h.
- * The single block format is in xfs_dir2_block.h.
- * The data block format is in xfs_dir2_data.h.
- * The leaf and freeindex block formats are in xfs_dir2_leaf.h.
- * Node blocks are the same as the other version, in xfs_da_btree.h.
- */
-
-/*
- * Byte offset in data block and shortform entry.
- */
-typedef __uint16_t xfs_dir2_data_off_t;
-#define NULLDATAOFF 0xffffU
-typedef uint xfs_dir2_data_aoff_t; /* argument form */
-
-/*
- * Directory block number (logical dirblk in file)
- */
-typedef __uint32_t xfs_dir2_db_t;
-
-/*
- * Byte offset in a directory.
- */
-typedef xfs_off_t xfs_dir2_off_t;
-
-/*
- * For getdents, argument struct for put routines.
- */
-typedef int (*xfs_dir2_put_t)(struct xfs_dir2_put_args *pa);
-typedef struct xfs_dir2_put_args {
- xfs_off_t cook; /* cookie of (next) entry */
- xfs_intino_t ino; /* inode number */
- xfs_dirent_t *dbp; /* buffer pointer */
- char *name; /* directory entry name */
- int namelen; /* length of name */
- int done; /* output: set if value was stored */
- xfs_dir2_put_t put; /* put function ptr (i/o) */
- struct uio *uio; /* uio control structure */
-} xfs_dir2_put_args_t;
-
-/*
- * Other interfaces used by the rest of the dir v2 code.
- */
-extern int xfs_dir2_grow_inode(struct xfs_da_args *args, int space,
- xfs_dir2_db_t *dbp);
-extern int xfs_dir2_isblock(struct xfs_trans *tp, struct xfs_inode *dp,
- int *vp);
-extern int xfs_dir2_isleaf(struct xfs_trans *tp, struct xfs_inode *dp,
- int *vp);
-extern int xfs_dir2_shrink_inode(struct xfs_da_args *args, xfs_dir2_db_t db,
- struct xfs_dabuf *bp);
-
-#endif /* __XFS_DIR2_H__ */
diff --git a/sys/gnu/fs/xfs/xfs_dir2_block.c b/sys/gnu/fs/xfs/xfs_dir2_block.c
deleted file mode 100644
index 972ded5..0000000
--- a/sys/gnu/fs/xfs/xfs_dir2_block.c
+++ /dev/null
@@ -1,1229 +0,0 @@
-/*
- * Copyright (c) 2000-2003,2005 Silicon Graphics, Inc.
- * All Rights Reserved.
- *
- * 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.
- *
- * This program is distributed in the hope that it would 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 the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- */
-#include "xfs.h"
-#include "xfs_fs.h"
-#include "xfs_types.h"
-#include "xfs_log.h"
-#include "xfs_inum.h"
-#include "xfs_trans.h"
-#include "xfs_sb.h"
-#include "xfs_dir.h"
-#include "xfs_dir2.h"
-#include "xfs_dmapi.h"
-#include "xfs_mount.h"
-#include "xfs_da_btree.h"
-#include "xfs_bmap_btree.h"
-#include "xfs_dir_sf.h"
-#include "xfs_dir2_sf.h"
-#include "xfs_attr_sf.h"
-#include "xfs_dinode.h"
-#include "xfs_inode.h"
-#include "xfs_inode_item.h"
-#include "xfs_dir_leaf.h"
-#include "xfs_dir2_data.h"
-#include "xfs_dir2_leaf.h"
-#include "xfs_dir2_block.h"
-#include "xfs_dir2_trace.h"
-#include "xfs_error.h"
-
-/*
- * Local function prototypes.
- */
-static void xfs_dir2_block_log_leaf(xfs_trans_t *tp, xfs_dabuf_t *bp, int first,
- int last);
-static void xfs_dir2_block_log_tail(xfs_trans_t *tp, xfs_dabuf_t *bp);
-static int xfs_dir2_block_lookup_int(xfs_da_args_t *args, xfs_dabuf_t **bpp,
- int *entno);
-static int xfs_dir2_block_sort(const void *a, const void *b);
-
-/*
- * Add an entry to a block directory.
- */
-int /* error */
-xfs_dir2_block_addname(
- xfs_da_args_t *args) /* directory op arguments */
-{
- xfs_dir2_data_free_t *bf; /* bestfree table in block */
- xfs_dir2_block_t *block; /* directory block structure */
- xfs_dir2_leaf_entry_t *blp; /* block leaf entries */
- xfs_dabuf_t *bp; /* buffer for block */
- xfs_dir2_block_tail_t *btp; /* block tail */
- int compact; /* need to compact leaf ents */
- xfs_dir2_data_entry_t *dep; /* block data entry */
- xfs_inode_t *dp; /* directory inode */
- xfs_dir2_data_unused_t *dup; /* block unused entry */
- int error; /* error return value */
- xfs_dir2_data_unused_t *enddup=NULL; /* unused at end of data */
- xfs_dahash_t hash; /* hash value of found entry */
- int high; /* high index for binary srch */
- int highstale; /* high stale index */
- int lfloghigh=0; /* last final leaf to log */
- int lfloglow=0; /* first final leaf to log */
- int len; /* length of the new entry */
- int low; /* low index for binary srch */
- int lowstale; /* low stale index */
- int mid=0; /* midpoint for binary srch */
- xfs_mount_t *mp; /* filesystem mount point */
- int needlog; /* need to log header */
- int needscan; /* need to rescan freespace */
- __be16 *tagp; /* pointer to tag value */
- xfs_trans_t *tp; /* transaction structure */
-
- xfs_dir2_trace_args("block_addname", args);
- dp = args->dp;
- tp = args->trans;
- mp = dp->i_mount;
- /*
- * Read the (one and only) directory block into dabuf bp.
- */
- if ((error =
- xfs_da_read_buf(tp, dp, mp->m_dirdatablk, -1, &bp, XFS_DATA_FORK))) {
- return error;
- }
- ASSERT(bp != NULL);
- block = bp->data;
- /*
- * Check the magic number, corrupted if wrong.
- */
- if (unlikely(be32_to_cpu(block->hdr.magic) != XFS_DIR2_BLOCK_MAGIC)) {
- XFS_CORRUPTION_ERROR("xfs_dir2_block_addname",
- XFS_ERRLEVEL_LOW, mp, block);
- xfs_da_brelse(tp, bp);
- return XFS_ERROR(EFSCORRUPTED);
- }
- len = XFS_DIR2_DATA_ENTSIZE(args->namelen);
- /*
- * Set up pointers to parts of the block.
- */
- bf = block->hdr.bestfree;
- btp = XFS_DIR2_BLOCK_TAIL_P(mp, block);
- blp = XFS_DIR2_BLOCK_LEAF_P(btp);
- /*
- * No stale entries? Need space for entry and new leaf.
- */
- if (!btp->stale) {
- /*
- * Tag just before the first leaf entry.
- */
- tagp = (__be16 *)blp - 1;
- /*
- * Data object just before the first leaf entry.
- */
- enddup = (xfs_dir2_data_unused_t *)((char *)block + be16_to_cpu(*tagp));
- /*
- * If it's not free then can't do this add without cleaning up:
- * the space before the first leaf entry needs to be free so it
- * can be expanded to hold the pointer to the new entry.
- */
- if (be16_to_cpu(enddup->freetag) != XFS_DIR2_DATA_FREE_TAG)
- dup = enddup = NULL;
- /*
- * Check out the biggest freespace and see if it's the same one.
- */
- else {
- dup = (xfs_dir2_data_unused_t *)
- ((char *)block + be16_to_cpu(bf[0].offset));
- if (dup == enddup) {
- /*
- * It is the biggest freespace, is it too small
- * to hold the new leaf too?
- */
- if (be16_to_cpu(dup->length) < len + (uint)sizeof(*blp)) {
- /*
- * Yes, we use the second-largest
- * entry instead if it works.
- */
- if (be16_to_cpu(bf[1].length) >= len)
- dup = (xfs_dir2_data_unused_t *)
- ((char *)block +
- be16_to_cpu(bf[1].offset));
- else
- dup = NULL;
- }
- } else {
- /*
- * Not the same free entry,
- * just check its length.
- */
- if (be16_to_cpu(dup->length) < len) {
- dup = NULL;
- }
- }
- }
- compact = 0;
- }
- /*
- * If there are stale entries we'll use one for the leaf.
- * Is the biggest entry enough to avoid compaction?
- */
- else if (be16_to_cpu(bf[0].length) >= len) {
- dup = (xfs_dir2_data_unused_t *)
- ((char *)block + be16_to_cpu(bf[0].offset));
- compact = 0;
- }
- /*
- * Will need to compact to make this work.
- */
- else {
- /*
- * Tag just before the first leaf entry.
- */
- tagp = (__be16 *)blp - 1;
- /*
- * Data object just before the first leaf entry.
- */
- dup = (xfs_dir2_data_unused_t *)((char *)block + be16_to_cpu(*tagp));
- /*
- * If it's not free then the data will go where the
- * leaf data starts now, if it works at all.
- */
- if (be16_to_cpu(dup->freetag) == XFS_DIR2_DATA_FREE_TAG) {
- if (be16_to_cpu(dup->length) + (be32_to_cpu(btp->stale) - 1) *
- (uint)sizeof(*blp) < len)
- dup = NULL;
- } else if ((be32_to_cpu(btp->stale) - 1) * (uint)sizeof(*blp) < len)
- dup = NULL;
- else
- dup = (xfs_dir2_data_unused_t *)blp;
- compact = 1;
- }
- /*
- * If this isn't a real add, we're done with the buffer.
- */
- if (args->justcheck)
- xfs_da_brelse(tp, bp);
- /*
- * If we don't have space for the new entry & leaf ...
- */
- if (!dup) {
- /*
- * Not trying to actually do anything, or don't have
- * a space reservation: return no-space.
- */
- if (args->justcheck || args->total == 0)
- return XFS_ERROR(ENOSPC);
- /*
- * Convert to the next larger format.
- * Then add the new entry in that format.
- */
- error = xfs_dir2_block_to_leaf(args, bp);
- xfs_da_buf_done(bp);
- if (error)
- return error;
- return xfs_dir2_leaf_addname(args);
- }
- /*
- * Just checking, and it would work, so say so.
- */
- if (args->justcheck)
- return 0;
- needlog = needscan = 0;
- /*
- * If need to compact the leaf entries, do it now.
- * Leave the highest-numbered stale entry stale.
- * XXX should be the one closest to mid but mid is not yet computed.
- */
- if (compact) {
- int fromidx; /* source leaf index */
- int toidx; /* target leaf index */
-
- for (fromidx = toidx = be32_to_cpu(btp->count) - 1,
- highstale = lfloghigh = -1;
- fromidx >= 0;
- fromidx--) {
- if (be32_to_cpu(blp[fromidx].address) == XFS_DIR2_NULL_DATAPTR) {
- if (highstale == -1)
- highstale = toidx;
- else {
- if (lfloghigh == -1)
- lfloghigh = toidx;
- continue;
- }
- }
- if (fromidx < toidx)
- blp[toidx] = blp[fromidx];
- toidx--;
- }
- lfloglow = toidx + 1 - (be32_to_cpu(btp->stale) - 1);
- lfloghigh -= be32_to_cpu(btp->stale) - 1;
- be32_add(&btp->count, -(be32_to_cpu(btp->stale) - 1));
- xfs_dir2_data_make_free(tp, bp,
- (xfs_dir2_data_aoff_t)((char *)blp - (char *)block),
- (xfs_dir2_data_aoff_t)((be32_to_cpu(btp->stale) - 1) * sizeof(*blp)),
- &needlog, &needscan);
- blp += be32_to_cpu(btp->stale) - 1;
- btp->stale = cpu_to_be32(1);
- /*
- * If we now need to rebuild the bestfree map, do so.
- * This needs to happen before the next call to use_free.
- */
- if (needscan) {
- xfs_dir2_data_freescan(mp, (xfs_dir2_data_t *)block,
- &needlog, NULL);
- needscan = 0;
- }
- }
- /*
- * Set leaf logging boundaries to impossible state.
- * For the no-stale case they're set explicitly.
- */
- else if (btp->stale) {
- lfloglow = be32_to_cpu(btp->count);
- lfloghigh = -1;
- }
- /*
- * Find the slot that's first lower than our hash value, -1 if none.
- */
- for (low = 0, high = be32_to_cpu(btp->count) - 1; low <= high; ) {
- mid = (low + high) >> 1;
- if ((hash = be32_to_cpu(blp[mid].hashval)) == args->hashval)
- break;
- if (hash < args->hashval)
- low = mid + 1;
- else
- high = mid - 1;
- }
- while (mid >= 0 && be32_to_cpu(blp[mid].hashval) >= args->hashval) {
- mid--;
- }
- /*
- * No stale entries, will use enddup space to hold new leaf.
- */
- if (!btp->stale) {
- /*
- * Mark the space needed for the new leaf entry, now in use.
- */
- xfs_dir2_data_use_free(tp, bp, enddup,
- (xfs_dir2_data_aoff_t)
- ((char *)enddup - (char *)block + be16_to_cpu(enddup->length) -
- sizeof(*blp)),
- (xfs_dir2_data_aoff_t)sizeof(*blp),
- &needlog, &needscan);
- /*
- * Update the tail (entry count).
- */
- be32_add(&btp->count, 1);
- /*
- * If we now need to rebuild the bestfree map, do so.
- * This needs to happen before the next call to use_free.
- */
- if (needscan) {
- xfs_dir2_data_freescan(mp, (xfs_dir2_data_t *)block,
- &needlog, NULL);
- needscan = 0;
- }
- /*
- * Adjust pointer to the first leaf entry, we're about to move
- * the table up one to open up space for the new leaf entry.
- * Then adjust our index to match.
- */
- blp--;
- mid++;
- if (mid)
- memmove(blp, &blp[1], mid * sizeof(*blp));
- lfloglow = 0;
- lfloghigh = mid;
- }
- /*
- * Use a stale leaf for our new entry.
- */
- else {
- for (lowstale = mid;
- lowstale >= 0 &&
- be32_to_cpu(blp[lowstale].address) != XFS_DIR2_NULL_DATAPTR;
- lowstale--)
- continue;
- for (highstale = mid + 1;
- highstale < be32_to_cpu(btp->count) &&
- be32_to_cpu(blp[highstale].address) != XFS_DIR2_NULL_DATAPTR &&
- (lowstale < 0 || mid - lowstale > highstale - mid);
- highstale++)
- continue;
- /*
- * Move entries toward the low-numbered stale entry.
- */
- if (lowstale >= 0 &&
- (highstale == be32_to_cpu(btp->count) ||
- mid - lowstale <= highstale - mid)) {
- if (mid - lowstale)
- memmove(&blp[lowstale], &blp[lowstale + 1],
- (mid - lowstale) * sizeof(*blp));
- lfloglow = MIN(lowstale, lfloglow);
- lfloghigh = MAX(mid, lfloghigh);
- }
- /*
- * Move entries toward the high-numbered stale entry.
- */
- else {
- ASSERT(highstale < be32_to_cpu(btp->count));
- mid++;
- if (highstale - mid)
- memmove(&blp[mid + 1], &blp[mid],
- (highstale - mid) * sizeof(*blp));
- lfloglow = MIN(mid, lfloglow);
- lfloghigh = MAX(highstale, lfloghigh);
- }
- be32_add(&btp->stale, -1);
- }
- /*
- * Point to the new data entry.
- */
- dep = (xfs_dir2_data_entry_t *)dup;
- /*
- * Fill in the leaf entry.
- */
- blp[mid].hashval = cpu_to_be32(args->hashval);
- blp[mid].address = cpu_to_be32(XFS_DIR2_BYTE_TO_DATAPTR(mp,
- (char *)dep - (char *)block));
- xfs_dir2_block_log_leaf(tp, bp, lfloglow, lfloghigh);
- /*
- * Mark space for the data entry used.
- */
- xfs_dir2_data_use_free(tp, bp, dup,
- (xfs_dir2_data_aoff_t)((char *)dup - (char *)block),
- (xfs_dir2_data_aoff_t)len, &needlog, &needscan);
- /*
- * Create the new data entry.
- */
- INT_SET(dep->inumber, ARCH_CONVERT, args->inumber);
- dep->namelen = args->namelen;
- memcpy(dep->name, args->name, args->namelen);
- tagp = XFS_DIR2_DATA_ENTRY_TAG_P(dep);
- *tagp = cpu_to_be16((char *)dep - (char *)block);
- /*
- * Clean up the bestfree array and log the header, tail, and entry.
- */
- if (needscan)
- xfs_dir2_data_freescan(mp, (xfs_dir2_data_t *)block, &needlog,
- NULL);
- if (needlog)
- xfs_dir2_data_log_header(tp, bp);
- xfs_dir2_block_log_tail(tp, bp);
- xfs_dir2_data_log_entry(tp, bp, dep);
- xfs_dir2_data_check(dp, bp);
- xfs_da_buf_done(bp);
- return 0;
-}
-
-/*
- * Readdir for block directories.
- */
-int /* error */
-xfs_dir2_block_getdents(
- xfs_trans_t *tp, /* transaction (NULL) */
- xfs_inode_t *dp, /* incore inode */
- uio_t *uio, /* caller's buffer control */
- int *eofp, /* eof reached? (out) */
- xfs_dirent_t *dbp, /* caller's buffer */
- xfs_dir2_put_t put) /* abi's formatting function */
-{
- xfs_dir2_block_t *block; /* directory block structure */
- xfs_dabuf_t *bp; /* buffer for block */
- xfs_dir2_block_tail_t *btp; /* block tail */
- xfs_dir2_data_entry_t *dep; /* block data entry */
- xfs_dir2_data_unused_t *dup; /* block unused entry */
- char *endptr; /* end of the data entries */
- int error; /* error return value */
- xfs_mount_t *mp; /* filesystem mount point */
- xfs_dir2_put_args_t p; /* arg package for put rtn */
- char *ptr; /* current data entry */
- int wantoff; /* starting block offset */
-
- mp = dp->i_mount;
- /*
- * If the block number in the offset is out of range, we're done.
- */
- if (XFS_DIR2_DATAPTR_TO_DB(mp, uio->uio_offset) > mp->m_dirdatablk) {
- *eofp = 1;
- return 0;
- }
- /*
- * Can't read the block, give up, else get dabuf in bp.
- */
- if ((error =
- xfs_da_read_buf(tp, dp, mp->m_dirdatablk, -1, &bp, XFS_DATA_FORK))) {
- return error;
- }
- ASSERT(bp != NULL);
- /*
- * Extract the byte offset we start at from the seek pointer.
- * We'll skip entries before this.
- */
- wantoff = XFS_DIR2_DATAPTR_TO_OFF(mp, uio->uio_offset);
- block = bp->data;
- xfs_dir2_data_check(dp, bp);
- /*
- * Set up values for the loop.
- */
- btp = XFS_DIR2_BLOCK_TAIL_P(mp, block);
- ptr = (char *)block->u;
- endptr = (char *)XFS_DIR2_BLOCK_LEAF_P(btp);
- p.dbp = dbp;
- p.put = put;
- p.uio = uio;
- /*
- * Loop over the data portion of the block.
- * Each object is a real entry (dep) or an unused one (dup).
- */
- while (ptr < endptr) {
- dup = (xfs_dir2_data_unused_t *)ptr;
- /*
- * Unused, skip it.
- */
- if (be16_to_cpu(dup->freetag) == XFS_DIR2_DATA_FREE_TAG) {
- ptr += be16_to_cpu(dup->length);
- continue;
- }
-
- dep = (xfs_dir2_data_entry_t *)ptr;
-
- /*
- * Bump pointer for the next iteration.
- */
- ptr += XFS_DIR2_DATA_ENTSIZE(dep->namelen);
- /*
- * The entry is before the desired starting point, skip it.
- */
- if ((char *)dep - (char *)block < wantoff)
- continue;
- /*
- * Set up argument structure for put routine.
- */
- p.namelen = dep->namelen;
-
- p.cook = XFS_DIR2_DB_OFF_TO_DATAPTR(mp, mp->m_dirdatablk,
- ptr - (char *)block);
- p.ino = INT_GET(dep->inumber, ARCH_CONVERT);
-#if XFS_BIG_INUMS
- p.ino += mp->m_inoadd;
-#endif
- p.name = (char *)dep->name;
-
- /*
- * Put the entry in the caller's buffer.
- */
- error = p.put(&p);
-
- /*
- * If it didn't fit, set the final offset to here & return.
- */
- if (!p.done) {
- uio->uio_offset =
- XFS_DIR2_DB_OFF_TO_DATAPTR(mp, mp->m_dirdatablk,
- (char *)dep - (char *)block);
- xfs_da_brelse(tp, bp);
- return error;
- }
- }
-
- /*
- * Reached the end of the block.
- * Set the offset to a non-existent block 1 and return.
- */
- *eofp = 1;
-
- uio->uio_offset =
- XFS_DIR2_DB_OFF_TO_DATAPTR(mp, mp->m_dirdatablk + 1, 0);
-
- xfs_da_brelse(tp, bp);
-
- return 0;
-}
-
-/*
- * Log leaf entries from the block.
- */
-static void
-xfs_dir2_block_log_leaf(
- xfs_trans_t *tp, /* transaction structure */
- xfs_dabuf_t *bp, /* block buffer */
- int first, /* index of first logged leaf */
- int last) /* index of last logged leaf */
-{
- xfs_dir2_block_t *block; /* directory block structure */
- xfs_dir2_leaf_entry_t *blp; /* block leaf entries */
- xfs_dir2_block_tail_t *btp; /* block tail */
- xfs_mount_t *mp; /* filesystem mount point */
-
- mp = tp->t_mountp;
- block = bp->data;
- btp = XFS_DIR2_BLOCK_TAIL_P(mp, block);
- blp = XFS_DIR2_BLOCK_LEAF_P(btp);
- xfs_da_log_buf(tp, bp, (uint)((char *)&blp[first] - (char *)block),
- (uint)((char *)&blp[last + 1] - (char *)block - 1));
-}
-
-/*
- * Log the block tail.
- */
-static void
-xfs_dir2_block_log_tail(
- xfs_trans_t *tp, /* transaction structure */
- xfs_dabuf_t *bp) /* block buffer */
-{
- xfs_dir2_block_t *block; /* directory block structure */
- xfs_dir2_block_tail_t *btp; /* block tail */
- xfs_mount_t *mp; /* filesystem mount point */
-
- mp = tp->t_mountp;
- block = bp->data;
- btp = XFS_DIR2_BLOCK_TAIL_P(mp, block);
- xfs_da_log_buf(tp, bp, (uint)((char *)btp - (char *)block),
- (uint)((char *)(btp + 1) - (char *)block - 1));
-}
-
-/*
- * Look up an entry in the block. This is the external routine,
- * xfs_dir2_block_lookup_int does the real work.
- */
-int /* error */
-xfs_dir2_block_lookup(
- xfs_da_args_t *args) /* dir lookup arguments */
-{
- xfs_dir2_block_t *block; /* block structure */
- xfs_dir2_leaf_entry_t *blp; /* block leaf entries */
- xfs_dabuf_t *bp; /* block buffer */
- xfs_dir2_block_tail_t *btp; /* block tail */
- xfs_dir2_data_entry_t *dep; /* block data entry */
- xfs_inode_t *dp; /* incore inode */
- int ent; /* entry index */
- int error; /* error return value */
- xfs_mount_t *mp; /* filesystem mount point */
-
- xfs_dir2_trace_args("block_lookup", args);
- /*
- * Get the buffer, look up the entry.
- * If not found (ENOENT) then return, have no buffer.
- */
- if ((error = xfs_dir2_block_lookup_int(args, &bp, &ent)))
- return error;
- dp = args->dp;
- mp = dp->i_mount;
- block = bp->data;
- xfs_dir2_data_check(dp, bp);
- btp = XFS_DIR2_BLOCK_TAIL_P(mp, block);
- blp = XFS_DIR2_BLOCK_LEAF_P(btp);
- /*
- * Get the offset from the leaf entry, to point to the data.
- */
- dep = (xfs_dir2_data_entry_t *)
- ((char *)block + XFS_DIR2_DATAPTR_TO_OFF(mp, be32_to_cpu(blp[ent].address)));
- /*
- * Fill in inode number, release the block.
- */
- args->inumber = INT_GET(dep->inumber, ARCH_CONVERT);
- xfs_da_brelse(args->trans, bp);
- return XFS_ERROR(EEXIST);
-}
-
-/*
- * Internal block lookup routine.
- */
-static int /* error */
-xfs_dir2_block_lookup_int(
- xfs_da_args_t *args, /* dir lookup arguments */
- xfs_dabuf_t **bpp, /* returned block buffer */
- int *entno) /* returned entry number */
-{
- xfs_dir2_dataptr_t addr; /* data entry address */
- xfs_dir2_block_t *block; /* block structure */
- xfs_dir2_leaf_entry_t *blp; /* block leaf entries */
- xfs_dabuf_t *bp; /* block buffer */
- xfs_dir2_block_tail_t *btp; /* block tail */
- xfs_dir2_data_entry_t *dep; /* block data entry */
- xfs_inode_t *dp; /* incore inode */
- int error; /* error return value */
- xfs_dahash_t hash; /* found hash value */
- int high; /* binary search high index */
- int low; /* binary search low index */
- int mid; /* binary search current idx */
- xfs_mount_t *mp; /* filesystem mount point */
- xfs_trans_t *tp; /* transaction pointer */
-
- dp = args->dp;
- tp = args->trans;
- mp = dp->i_mount;
- /*
- * Read the buffer, return error if we can't get it.
- */
- if ((error =
- xfs_da_read_buf(tp, dp, mp->m_dirdatablk, -1, &bp, XFS_DATA_FORK))) {
- return error;
- }
- ASSERT(bp != NULL);
- block = bp->data;
- xfs_dir2_data_check(dp, bp);
- btp = XFS_DIR2_BLOCK_TAIL_P(mp, block);
- blp = XFS_DIR2_BLOCK_LEAF_P(btp);
- /*
- * Loop doing a binary search for our hash value.
- * Find our entry, ENOENT if it's not there.
- */
- for (low = 0, high = be32_to_cpu(btp->count) - 1; ; ) {
- ASSERT(low <= high);
- mid = (low + high) >> 1;
- if ((hash = be32_to_cpu(blp[mid].hashval)) == args->hashval)
- break;
- if (hash < args->hashval)
- low = mid + 1;
- else
- high = mid - 1;
- if (low > high) {
- ASSERT(args->oknoent);
- xfs_da_brelse(tp, bp);
- return XFS_ERROR(ENOENT);
- }
- }
- /*
- * Back up to the first one with the right hash value.
- */
- while (mid > 0 && be32_to_cpu(blp[mid - 1].hashval) == args->hashval) {
- mid--;
- }
- /*
- * Now loop forward through all the entries with the
- * right hash value looking for our name.
- */
- do {
- if ((addr = be32_to_cpu(blp[mid].address)) == XFS_DIR2_NULL_DATAPTR)
- continue;
- /*
- * Get pointer to the entry from the leaf.
- */
- dep = (xfs_dir2_data_entry_t *)
- ((char *)block + XFS_DIR2_DATAPTR_TO_OFF(mp, addr));
- /*
- * Compare, if it's right give back buffer & entry number.
- */
- if (dep->namelen == args->namelen &&
- dep->name[0] == args->name[0] &&
- memcmp(dep->name, args->name, args->namelen) == 0) {
- *bpp = bp;
- *entno = mid;
- return 0;
- }
- } while (++mid < be32_to_cpu(btp->count) && be32_to_cpu(blp[mid].hashval) == hash);
- /*
- * No match, release the buffer and return ENOENT.
- */
- ASSERT(args->oknoent);
- xfs_da_brelse(tp, bp);
- return XFS_ERROR(ENOENT);
-}
-
-/*
- * Remove an entry from a block format directory.
- * If that makes the block small enough to fit in shortform, transform it.
- */
-int /* error */
-xfs_dir2_block_removename(
- xfs_da_args_t *args) /* directory operation args */
-{
- xfs_dir2_block_t *block; /* block structure */
- xfs_dir2_leaf_entry_t *blp; /* block leaf pointer */
- xfs_dabuf_t *bp; /* block buffer */
- xfs_dir2_block_tail_t *btp; /* block tail */
- xfs_dir2_data_entry_t *dep; /* block data entry */
- xfs_inode_t *dp; /* incore inode */
- int ent; /* block leaf entry index */
- int error; /* error return value */
- xfs_mount_t *mp; /* filesystem mount point */
- int needlog; /* need to log block header */
- int needscan; /* need to fixup bestfree */
- xfs_dir2_sf_hdr_t sfh; /* shortform header */
- int size; /* shortform size */
- xfs_trans_t *tp; /* transaction pointer */
-
- xfs_dir2_trace_args("block_removename", args);
- /*
- * Look up the entry in the block. Gets the buffer and entry index.
- * It will always be there, the vnodeops level does a lookup first.
- */
- if ((error = xfs_dir2_block_lookup_int(args, &bp, &ent))) {
- return error;
- }
- dp = args->dp;
- tp = args->trans;
- mp = dp->i_mount;
- block = bp->data;
- btp = XFS_DIR2_BLOCK_TAIL_P(mp, block);
- blp = XFS_DIR2_BLOCK_LEAF_P(btp);
- /*
- * Point to the data entry using the leaf entry.
- */
- dep = (xfs_dir2_data_entry_t *)
- ((char *)block + XFS_DIR2_DATAPTR_TO_OFF(mp, be32_to_cpu(blp[ent].address)));
- /*
- * Mark the data entry's space free.
- */
- needlog = needscan = 0;
- xfs_dir2_data_make_free(tp, bp,
- (xfs_dir2_data_aoff_t)((char *)dep - (char *)block),
- XFS_DIR2_DATA_ENTSIZE(dep->namelen), &needlog, &needscan);
- /*
- * Fix up the block tail.
- */
- be32_add(&btp->stale, 1);
- xfs_dir2_block_log_tail(tp, bp);
- /*
- * Remove the leaf entry by marking it stale.
- */
- blp[ent].address = cpu_to_be32(XFS_DIR2_NULL_DATAPTR);
- xfs_dir2_block_log_leaf(tp, bp, ent, ent);
- /*
- * Fix up bestfree, log the header if necessary.
- */
- if (needscan)
- xfs_dir2_data_freescan(mp, (xfs_dir2_data_t *)block, &needlog,
- NULL);
- if (needlog)
- xfs_dir2_data_log_header(tp, bp);
- xfs_dir2_data_check(dp, bp);
- /*
- * See if the size as a shortform is good enough.
- */
- if ((size = xfs_dir2_block_sfsize(dp, block, &sfh)) >
- XFS_IFORK_DSIZE(dp)) {
- xfs_da_buf_done(bp);
- return 0;
- }
- /*
- * If it works, do the conversion.
- */
- return xfs_dir2_block_to_sf(args, bp, size, &sfh);
-}
-
-/*
- * Replace an entry in a V2 block directory.
- * Change the inode number to the new value.
- */
-int /* error */
-xfs_dir2_block_replace(
- xfs_da_args_t *args) /* directory operation args */
-{
- xfs_dir2_block_t *block; /* block structure */
- xfs_dir2_leaf_entry_t *blp; /* block leaf entries */
- xfs_dabuf_t *bp; /* block buffer */
- xfs_dir2_block_tail_t *btp; /* block tail */
- xfs_dir2_data_entry_t *dep; /* block data entry */
- xfs_inode_t *dp; /* incore inode */
- int ent; /* leaf entry index */
- int error; /* error return value */
- xfs_mount_t *mp; /* filesystem mount point */
-
- xfs_dir2_trace_args("block_replace", args);
- /*
- * Lookup the entry in the directory. Get buffer and entry index.
- * This will always succeed since the caller has already done a lookup.
- */
- if ((error = xfs_dir2_block_lookup_int(args, &bp, &ent))) {
- return error;
- }
- dp = args->dp;
- mp = dp->i_mount;
- block = bp->data;
- btp = XFS_DIR2_BLOCK_TAIL_P(mp, block);
- blp = XFS_DIR2_BLOCK_LEAF_P(btp);
- /*
- * Point to the data entry we need to change.
- */
- dep = (xfs_dir2_data_entry_t *)
- ((char *)block + XFS_DIR2_DATAPTR_TO_OFF(mp, be32_to_cpu(blp[ent].address)));
- ASSERT(INT_GET(dep->inumber, ARCH_CONVERT) != args->inumber);
- /*
- * Change the inode number to the new value.
- */
- INT_SET(dep->inumber, ARCH_CONVERT, args->inumber);
- xfs_dir2_data_log_entry(args->trans, bp, dep);
- xfs_dir2_data_check(dp, bp);
- xfs_da_buf_done(bp);
- return 0;
-}
-
-/*
- * Qsort comparison routine for the block leaf entries.
- */
-static int /* sort order */
-xfs_dir2_block_sort(
- const void *a, /* first leaf entry */
- const void *b) /* second leaf entry */
-{
- const xfs_dir2_leaf_entry_t *la; /* first leaf entry */
- const xfs_dir2_leaf_entry_t *lb; /* second leaf entry */
-
- la = a;
- lb = b;
- return be32_to_cpu(la->hashval) < be32_to_cpu(lb->hashval) ? -1 :
- (be32_to_cpu(la->hashval) > be32_to_cpu(lb->hashval) ? 1 : 0);
-}
-
-/*
- * Convert a V2 leaf directory to a V2 block directory if possible.
- */
-int /* error */
-xfs_dir2_leaf_to_block(
- xfs_da_args_t *args, /* operation arguments */
- xfs_dabuf_t *lbp, /* leaf buffer */
- xfs_dabuf_t *dbp) /* data buffer */
-{
- __be16 *bestsp; /* leaf bests table */
- xfs_dir2_block_t *block; /* block structure */
- xfs_dir2_block_tail_t *btp; /* block tail */
- xfs_inode_t *dp; /* incore directory inode */
- xfs_dir2_data_unused_t *dup; /* unused data entry */
- int error; /* error return value */
- int from; /* leaf from index */
- xfs_dir2_leaf_t *leaf; /* leaf structure */
- xfs_dir2_leaf_entry_t *lep; /* leaf entry */
- xfs_dir2_leaf_tail_t *ltp; /* leaf tail structure */
- xfs_mount_t *mp; /* file system mount point */
- int needlog; /* need to log data header */
- int needscan; /* need to scan for bestfree */
- xfs_dir2_sf_hdr_t sfh; /* shortform header */
- int size; /* bytes used */
- __be16 *tagp; /* end of entry (tag) */
- int to; /* block/leaf to index */
- xfs_trans_t *tp; /* transaction pointer */
-
- xfs_dir2_trace_args_bb("leaf_to_block", args, lbp, dbp);
- dp = args->dp;
- tp = args->trans;
- mp = dp->i_mount;
- leaf = lbp->data;
- ASSERT(be16_to_cpu(leaf->hdr.info.magic) == XFS_DIR2_LEAF1_MAGIC);
- ltp = XFS_DIR2_LEAF_TAIL_P(mp, leaf);
- /*
- * If there are data blocks other than the first one, take this
- * opportunity to remove trailing empty data blocks that may have
- * been left behind during no-space-reservation operations.
- * These will show up in the leaf bests table.
- */
- while (dp->i_d.di_size > mp->m_dirblksize) {
- bestsp = XFS_DIR2_LEAF_BESTS_P(ltp);
- if (be16_to_cpu(bestsp[be32_to_cpu(ltp->bestcount) - 1]) ==
- mp->m_dirblksize - (uint)sizeof(block->hdr)) {
- if ((error =
- xfs_dir2_leaf_trim_data(args, lbp,
- (xfs_dir2_db_t)(be32_to_cpu(ltp->bestcount) - 1))))
- goto out;
- } else {
- error = 0;
- goto out;
- }
- }
- /*
- * Read the data block if we don't already have it, give up if it fails.
- */
- if (dbp == NULL &&
- (error = xfs_da_read_buf(tp, dp, mp->m_dirdatablk, -1, &dbp,
- XFS_DATA_FORK))) {
- goto out;
- }
- block = dbp->data;
- ASSERT(be32_to_cpu(block->hdr.magic) == XFS_DIR2_DATA_MAGIC);
- /*
- * Size of the "leaf" area in the block.
- */
- size = (uint)sizeof(block->tail) +
- (uint)sizeof(*lep) * (be16_to_cpu(leaf->hdr.count) - be16_to_cpu(leaf->hdr.stale));
- /*
- * Look at the last data entry.
- */
- tagp = (__be16 *)((char *)block + mp->m_dirblksize) - 1;
- dup = (xfs_dir2_data_unused_t *)((char *)block + be16_to_cpu(*tagp));
- /*
- * If it's not free or is too short we can't do it.
- */
- if (be16_to_cpu(dup->freetag) != XFS_DIR2_DATA_FREE_TAG ||
- be16_to_cpu(dup->length) < size) {
- error = 0;
- goto out;
- }
- /*
- * Start converting it to block form.
- */
- block->hdr.magic = cpu_to_be32(XFS_DIR2_BLOCK_MAGIC);
- needlog = 1;
- needscan = 0;
- /*
- * Use up the space at the end of the block (blp/btp).
- */
- xfs_dir2_data_use_free(tp, dbp, dup, mp->m_dirblksize - size, size,
- &needlog, &needscan);
- /*
- * Initialize the block tail.
- */
- btp = XFS_DIR2_BLOCK_TAIL_P(mp, block);
- btp->count = cpu_to_be32(be16_to_cpu(leaf->hdr.count) - be16_to_cpu(leaf->hdr.stale));
- btp->stale = 0;
- xfs_dir2_block_log_tail(tp, dbp);
- /*
- * Initialize the block leaf area. We compact out stale entries.
- */
- lep = XFS_DIR2_BLOCK_LEAF_P(btp);
- for (from = to = 0; from < be16_to_cpu(leaf->hdr.count); from++) {
- if (be32_to_cpu(leaf->ents[from].address) == XFS_DIR2_NULL_DATAPTR)
- continue;
- lep[to++] = leaf->ents[from];
- }
- ASSERT(to == be32_to_cpu(btp->count));
- xfs_dir2_block_log_leaf(tp, dbp, 0, be32_to_cpu(btp->count) - 1);
- /*
- * Scan the bestfree if we need it and log the data block header.
- */
- if (needscan)
- xfs_dir2_data_freescan(mp, (xfs_dir2_data_t *)block, &needlog,
- NULL);
- if (needlog)
- xfs_dir2_data_log_header(tp, dbp);
- /*
- * Pitch the old leaf block.
- */
- error = xfs_da_shrink_inode(args, mp->m_dirleafblk, lbp);
- lbp = NULL;
- if (error) {
- goto out;
- }
- /*
- * Now see if the resulting block can be shrunken to shortform.
- */
- if ((size = xfs_dir2_block_sfsize(dp, block, &sfh)) >
- XFS_IFORK_DSIZE(dp)) {
- error = 0;
- goto out;
- }
- return xfs_dir2_block_to_sf(args, dbp, size, &sfh);
-out:
- if (lbp)
- xfs_da_buf_done(lbp);
- if (dbp)
- xfs_da_buf_done(dbp);
- return error;
-}
-
-/*
- * Convert the shortform directory to block form.
- */
-int /* error */
-xfs_dir2_sf_to_block(
- xfs_da_args_t *args) /* operation arguments */
-{
- xfs_dir2_db_t blkno; /* dir-relative block # (0) */
- xfs_dir2_block_t *block; /* block structure */
- xfs_dir2_leaf_entry_t *blp; /* block leaf entries */
- xfs_dabuf_t *bp; /* block buffer */
- xfs_dir2_block_tail_t *btp; /* block tail pointer */
- char *buf; /* sf buffer */
- int buf_len;
- xfs_dir2_data_entry_t *dep; /* data entry pointer */
- xfs_inode_t *dp; /* incore directory inode */
- int dummy; /* trash */
- xfs_dir2_data_unused_t *dup; /* unused entry pointer */
- int endoffset; /* end of data objects */
- int error; /* error return value */
- int i; /* index */
- xfs_mount_t *mp; /* filesystem mount point */
- int needlog; /* need to log block header */
- int needscan; /* need to scan block freespc */
- int newoffset; /* offset from current entry */
- int offset; /* target block offset */
- xfs_dir2_sf_entry_t *sfep; /* sf entry pointer */
- xfs_dir2_sf_t *sfp; /* shortform structure */
- __be16 *tagp; /* end of data entry */
- xfs_trans_t *tp; /* transaction pointer */
-
- xfs_dir2_trace_args("sf_to_block", args);
- dp = args->dp;
- tp = args->trans;
- mp = dp->i_mount;
- ASSERT(dp->i_df.if_flags & XFS_IFINLINE);
- /*
- * Bomb out if the shortform directory is way too short.
- */
- if (dp->i_d.di_size < offsetof(xfs_dir2_sf_hdr_t, parent)) {
- ASSERT(XFS_FORCED_SHUTDOWN(mp));
- return XFS_ERROR(EIO);
- }
- ASSERT(dp->i_df.if_bytes == dp->i_d.di_size);
- ASSERT(dp->i_df.if_u1.if_data != NULL);
- sfp = (xfs_dir2_sf_t *)dp->i_df.if_u1.if_data;
- ASSERT(dp->i_d.di_size >= XFS_DIR2_SF_HDR_SIZE(sfp->hdr.i8count));
- /*
- * Copy the directory into the stack buffer.
- * Then pitch the incore inode data so we can make extents.
- */
-
- buf_len = dp->i_df.if_bytes;
- buf = kmem_alloc(dp->i_df.if_bytes, KM_SLEEP);
-
- memcpy(buf, sfp, dp->i_df.if_bytes);
- xfs_idata_realloc(dp, -dp->i_df.if_bytes, XFS_DATA_FORK);
- dp->i_d.di_size = 0;
- xfs_trans_log_inode(tp, dp, XFS_ILOG_CORE);
- /*
- * Reset pointer - old sfp is gone.
- */
- sfp = (xfs_dir2_sf_t *)buf;
- /*
- * Add block 0 to the inode.
- */
- error = xfs_dir2_grow_inode(args, XFS_DIR2_DATA_SPACE, &blkno);
- if (error) {
- kmem_free(buf, buf_len);
- return error;
- }
- /*
- * Initialize the data block.
- */
- error = xfs_dir2_data_init(args, blkno, &bp);
- if (error) {
- kmem_free(buf, buf_len);
- return error;
- }
- block = bp->data;
- block->hdr.magic = cpu_to_be32(XFS_DIR2_BLOCK_MAGIC);
- /*
- * Compute size of block "tail" area.
- */
- i = (uint)sizeof(*btp) +
- (sfp->hdr.count + 2) * (uint)sizeof(xfs_dir2_leaf_entry_t);
- /*
- * The whole thing is initialized to free by the init routine.
- * Say we're using the leaf and tail area.
- */
- dup = (xfs_dir2_data_unused_t *)block->u;
- needlog = needscan = 0;
- xfs_dir2_data_use_free(tp, bp, dup, mp->m_dirblksize - i, i, &needlog,
- &needscan);
- ASSERT(needscan == 0);
- /*
- * Fill in the tail.
- */
- btp = XFS_DIR2_BLOCK_TAIL_P(mp, block);
- btp->count = cpu_to_be32(sfp->hdr.count + 2); /* ., .. */
- btp->stale = 0;
- blp = XFS_DIR2_BLOCK_LEAF_P(btp);
- endoffset = (uint)((char *)blp - (char *)block);
- /*
- * Remove the freespace, we'll manage it.
- */
- xfs_dir2_data_use_free(tp, bp, dup,
- (xfs_dir2_data_aoff_t)((char *)dup - (char *)block),
- be16_to_cpu(dup->length), &needlog, &needscan);
- /*
- * Create entry for .
- */
- dep = (xfs_dir2_data_entry_t *)
- ((char *)block + XFS_DIR2_DATA_DOT_OFFSET);
- INT_SET(dep->inumber, ARCH_CONVERT, dp->i_ino);
- dep->namelen = 1;
- dep->name[0] = '.';
- tagp = XFS_DIR2_DATA_ENTRY_TAG_P(dep);
- *tagp = cpu_to_be16((char *)dep - (char *)block);
- xfs_dir2_data_log_entry(tp, bp, dep);
- blp[0].hashval = cpu_to_be32(xfs_dir_hash_dot);
- blp[0].address = cpu_to_be32(XFS_DIR2_BYTE_TO_DATAPTR(mp,
- (char *)dep - (char *)block));
- /*
- * Create entry for ..
- */
- dep = (xfs_dir2_data_entry_t *)
- ((char *)block + XFS_DIR2_DATA_DOTDOT_OFFSET);
- INT_SET(dep->inumber, ARCH_CONVERT, XFS_DIR2_SF_GET_INUMBER(sfp, &sfp->hdr.parent));
- dep->namelen = 2;
- dep->name[0] = dep->name[1] = '.';
- tagp = XFS_DIR2_DATA_ENTRY_TAG_P(dep);
- *tagp = cpu_to_be16((char *)dep - (char *)block);
- xfs_dir2_data_log_entry(tp, bp, dep);
- blp[1].hashval = cpu_to_be32(xfs_dir_hash_dotdot);
- blp[1].address = cpu_to_be32(XFS_DIR2_BYTE_TO_DATAPTR(mp,
- (char *)dep - (char *)block));
- offset = XFS_DIR2_DATA_FIRST_OFFSET;
- /*
- * Loop over existing entries, stuff them in.
- */
- if ((i = 0) == sfp->hdr.count)
- sfep = NULL;
- else
- sfep = XFS_DIR2_SF_FIRSTENTRY(sfp);
- /*
- * Need to preserve the existing offset values in the sf directory.
- * Insert holes (unused entries) where necessary.
- */
- while (offset < endoffset) {
- /*
- * sfep is null when we reach the end of the list.
- */
- if (sfep == NULL)
- newoffset = endoffset;
- else
- newoffset = XFS_DIR2_SF_GET_OFFSET(sfep);
- /*
- * There should be a hole here, make one.
- */
- if (offset < newoffset) {
- dup = (xfs_dir2_data_unused_t *)
- ((char *)block + offset);
- dup->freetag = cpu_to_be16(XFS_DIR2_DATA_FREE_TAG);
- dup->length = cpu_to_be16(newoffset - offset);
- *XFS_DIR2_DATA_UNUSED_TAG_P(dup) = cpu_to_be16(
- ((char *)dup - (char *)block));
- xfs_dir2_data_log_unused(tp, bp, dup);
- (void)xfs_dir2_data_freeinsert((xfs_dir2_data_t *)block,
- dup, &dummy);
- offset += be16_to_cpu(dup->length);
- continue;
- }
- /*
- * Copy a real entry.
- */
- dep = (xfs_dir2_data_entry_t *)((char *)block + newoffset);
- INT_SET(dep->inumber, ARCH_CONVERT, XFS_DIR2_SF_GET_INUMBER(sfp,
- XFS_DIR2_SF_INUMBERP(sfep)));
- dep->namelen = sfep->namelen;
- memcpy(dep->name, sfep->name, dep->namelen);
- tagp = XFS_DIR2_DATA_ENTRY_TAG_P(dep);
- *tagp = cpu_to_be16((char *)dep - (char *)block);
- xfs_dir2_data_log_entry(tp, bp, dep);
- blp[2 + i].hashval = cpu_to_be32(xfs_da_hashname(
- (char *)sfep->name, sfep->namelen));
- blp[2 + i].address = cpu_to_be32(XFS_DIR2_BYTE_TO_DATAPTR(mp,
- (char *)dep - (char *)block));
- offset = (int)((char *)(tagp + 1) - (char *)block);
- if (++i == sfp->hdr.count)
- sfep = NULL;
- else
- sfep = XFS_DIR2_SF_NEXTENTRY(sfp, sfep);
- }
- /* Done with the temporary buffer */
- kmem_free(buf, buf_len);
- /*
- * Sort the leaf entries by hash value.
- */
- xfs_sort(blp, be32_to_cpu(btp->count), sizeof(*blp), xfs_dir2_block_sort);
- /*
- * Log the leaf entry area and tail.
- * Already logged the header in data_init, ignore needlog.
- */
- ASSERT(needscan == 0);
- xfs_dir2_block_log_leaf(tp, bp, 0, be32_to_cpu(btp->count) - 1);
- xfs_dir2_block_log_tail(tp, bp);
- xfs_dir2_data_check(dp, bp);
- xfs_da_buf_done(bp);
- return 0;
-}
diff --git a/sys/gnu/fs/xfs/xfs_dir2_block.h b/sys/gnu/fs/xfs/xfs_dir2_block.h
deleted file mode 100644
index 6722eff..0000000
--- a/sys/gnu/fs/xfs/xfs_dir2_block.h
+++ /dev/null
@@ -1,95 +0,0 @@
-/*
- * Copyright (c) 2000-2001,2005 Silicon Graphics, Inc.
- * All Rights Reserved.
- *
- * 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.
- *
- * This program is distributed in the hope that it would 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 the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- */
-#ifndef __XFS_DIR2_BLOCK_H__
-#define __XFS_DIR2_BLOCK_H__
-
-/*
- * xfs_dir2_block.h
- * Directory version 2, single block format structures
- */
-
-struct uio;
-struct xfs_dabuf;
-struct xfs_da_args;
-struct xfs_dir2_data_hdr;
-struct xfs_dir2_leaf_entry;
-struct xfs_inode;
-struct xfs_mount;
-struct xfs_trans;
-
-/*
- * The single block format is as follows:
- * xfs_dir2_data_hdr_t structure
- * xfs_dir2_data_entry_t and xfs_dir2_data_unused_t structures
- * xfs_dir2_leaf_entry_t structures
- * xfs_dir2_block_tail_t structure
- */
-
-#define XFS_DIR2_BLOCK_MAGIC 0x58443242 /* XD2B: for one block dirs */
-
-typedef struct xfs_dir2_block_tail {
- __be32 count; /* count of leaf entries */
- __be32 stale; /* count of stale lf entries */
-} xfs_dir2_block_tail_t;
-
-/*
- * Generic single-block structure, for xfs_db.
- */
-typedef struct xfs_dir2_block {
- xfs_dir2_data_hdr_t hdr; /* magic XFS_DIR2_BLOCK_MAGIC */
- xfs_dir2_data_union_t u[1];
- xfs_dir2_leaf_entry_t leaf[1];
- xfs_dir2_block_tail_t tail;
-} xfs_dir2_block_t;
-
-/*
- * Pointer to the leaf header embedded in a data block (1-block format)
- */
-#define XFS_DIR2_BLOCK_TAIL_P(mp,block) xfs_dir2_block_tail_p(mp,block)
-static inline xfs_dir2_block_tail_t *
-xfs_dir2_block_tail_p(struct xfs_mount *mp, xfs_dir2_block_t *block)
-{
- return (((xfs_dir2_block_tail_t *)
- ((char *)(block) + (mp)->m_dirblksize)) - 1);
-}
-
-/*
- * Pointer to the leaf entries embedded in a data block (1-block format)
- */
-#define XFS_DIR2_BLOCK_LEAF_P(btp) xfs_dir2_block_leaf_p(btp)
-static inline struct xfs_dir2_leaf_entry *
-xfs_dir2_block_leaf_p(xfs_dir2_block_tail_t *btp)
-{
- return ((struct xfs_dir2_leaf_entry *)btp) - be32_to_cpu(btp->count);
-}
-
-/*
- * Function declarations.
- */
-extern int xfs_dir2_block_addname(struct xfs_da_args *args);
-extern int xfs_dir2_block_getdents(struct xfs_trans *tp, struct xfs_inode *dp,
- struct uio *uio, int *eofp,
- struct xfs_dirent *dbp, xfs_dir2_put_t put);
-extern int xfs_dir2_block_lookup(struct xfs_da_args *args);
-extern int xfs_dir2_block_removename(struct xfs_da_args *args);
-extern int xfs_dir2_block_replace(struct xfs_da_args *args);
-extern int xfs_dir2_leaf_to_block(struct xfs_da_args *args,
- struct xfs_dabuf *lbp, struct xfs_dabuf *dbp);
-extern int xfs_dir2_sf_to_block(struct xfs_da_args *args);
-
-#endif /* __XFS_DIR2_BLOCK_H__ */
diff --git a/sys/gnu/fs/xfs/xfs_dir2_data.c b/sys/gnu/fs/xfs/xfs_dir2_data.c
deleted file mode 100644
index bb3d03f..0000000
--- a/sys/gnu/fs/xfs/xfs_dir2_data.c
+++ /dev/null
@@ -1,837 +0,0 @@
-/*
- * Copyright (c) 2000-2002,2005 Silicon Graphics, Inc.
- * All Rights Reserved.
- *
- * 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.
- *
- * This program is distributed in the hope that it would 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 the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- */
-#include "xfs.h"
-#include "xfs_fs.h"
-#include "xfs_types.h"
-#include "xfs_log.h"
-#include "xfs_inum.h"
-#include "xfs_trans.h"
-#include "xfs_sb.h"
-#include "xfs_dir.h"
-#include "xfs_dir2.h"
-#include "xfs_dmapi.h"
-#include "xfs_mount.h"
-#include "xfs_da_btree.h"
-#include "xfs_bmap_btree.h"
-#include "xfs_dir_sf.h"
-#include "xfs_dir2_sf.h"
-#include "xfs_attr_sf.h"
-#include "xfs_dinode.h"
-#include "xfs_inode.h"
-#include "xfs_dir_leaf.h"
-#include "xfs_dir2_data.h"
-#include "xfs_dir2_leaf.h"
-#include "xfs_dir2_block.h"
-#include "xfs_error.h"
-
-#ifdef DEBUG
-/*
- * Check the consistency of the data block.
- * The input can also be a block-format directory.
- * Pop an assert if we find anything bad.
- */
-void
-xfs_dir2_data_check(
- xfs_inode_t *dp, /* incore inode pointer */
- xfs_dabuf_t *bp) /* data block's buffer */
-{
- xfs_dir2_dataptr_t addr; /* addr for leaf lookup */
- xfs_dir2_data_free_t *bf; /* bestfree table */
- xfs_dir2_block_tail_t *btp=NULL; /* block tail */
- int count; /* count of entries found */
- xfs_dir2_data_t *d; /* data block pointer */
- xfs_dir2_data_entry_t *dep; /* data entry */
- xfs_dir2_data_free_t *dfp; /* bestfree entry */
- xfs_dir2_data_unused_t *dup; /* unused entry */
- char *endp; /* end of useful data */
- int freeseen; /* mask of bestfrees seen */
- xfs_dahash_t hash; /* hash of current name */
- int i; /* leaf index */
- int lastfree; /* last entry was unused */
- xfs_dir2_leaf_entry_t *lep=NULL; /* block leaf entries */
- xfs_mount_t *mp; /* filesystem mount point */
- char *p; /* current data position */
- int stale; /* count of stale leaves */
-
- mp = dp->i_mount;
- d = bp->data;
- ASSERT(be32_to_cpu(d->hdr.magic) == XFS_DIR2_DATA_MAGIC ||
- be32_to_cpu(d->hdr.magic) == XFS_DIR2_BLOCK_MAGIC);
- bf = d->hdr.bestfree;
- p = (char *)d->u;
- if (be32_to_cpu(d->hdr.magic) == XFS_DIR2_BLOCK_MAGIC) {
- btp = XFS_DIR2_BLOCK_TAIL_P(mp, (xfs_dir2_block_t *)d);
- lep = XFS_DIR2_BLOCK_LEAF_P(btp);
- endp = (char *)lep;
- } else
- endp = (char *)d + mp->m_dirblksize;
- count = lastfree = freeseen = 0;
- /*
- * Account for zero bestfree entries.
- */
- if (!bf[0].length) {
- ASSERT(!bf[0].offset);
- freeseen |= 1 << 0;
- }
- if (!bf[1].length) {
- ASSERT(!bf[1].offset);
- freeseen |= 1 << 1;
- }
- if (!bf[2].length) {
- ASSERT(!bf[2].offset);
- freeseen |= 1 << 2;
- }
- ASSERT(be16_to_cpu(bf[0].length) >= be16_to_cpu(bf[1].length));
- ASSERT(be16_to_cpu(bf[1].length) >= be16_to_cpu(bf[2].length));
- /*
- * Loop over the data/unused entries.
- */
- while (p < endp) {
- dup = (xfs_dir2_data_unused_t *)p;
- /*
- * If it's unused, look for the space in the bestfree table.
- * If we find it, account for that, else make sure it
- * doesn't need to be there.
- */
- if (be16_to_cpu(dup->freetag) == XFS_DIR2_DATA_FREE_TAG) {
- ASSERT(lastfree == 0);
- ASSERT(be16_to_cpu(*XFS_DIR2_DATA_UNUSED_TAG_P(dup)) ==
- (char *)dup - (char *)d);
- dfp = xfs_dir2_data_freefind(d, dup);
- if (dfp) {
- i = (int)(dfp - bf);
- ASSERT((freeseen & (1 << i)) == 0);
- freeseen |= 1 << i;
- } else {
- ASSERT(be16_to_cpu(dup->length) <=
- be16_to_cpu(bf[2].length));
- }
- p += be16_to_cpu(dup->length);
- lastfree = 1;
- continue;
- }
- /*
- * It's a real entry. Validate the fields.
- * If this is a block directory then make sure it's
- * in the leaf section of the block.
- * The linear search is crude but this is DEBUG code.
- */
- dep = (xfs_dir2_data_entry_t *)p;
- ASSERT(dep->namelen != 0);
- ASSERT(xfs_dir_ino_validate(mp, INT_GET(dep->inumber, ARCH_CONVERT)) == 0);
- ASSERT(be16_to_cpu(*XFS_DIR2_DATA_ENTRY_TAG_P(dep)) ==
- (char *)dep - (char *)d);
- count++;
- lastfree = 0;
- if (be32_to_cpu(d->hdr.magic) == XFS_DIR2_BLOCK_MAGIC) {
- addr = XFS_DIR2_DB_OFF_TO_DATAPTR(mp, mp->m_dirdatablk,
- (xfs_dir2_data_aoff_t)
- ((char *)dep - (char *)d));
- hash = xfs_da_hashname((char *)dep->name, dep->namelen);
- for (i = 0; i < be32_to_cpu(btp->count); i++) {
- if (be32_to_cpu(lep[i].address) == addr &&
- be32_to_cpu(lep[i].hashval) == hash)
- break;
- }
- ASSERT(i < be32_to_cpu(btp->count));
- }
- p += XFS_DIR2_DATA_ENTSIZE(dep->namelen);
- }
- /*
- * Need to have seen all the entries and all the bestfree slots.
- */
- ASSERT(freeseen == 7);
- if (be32_to_cpu(d->hdr.magic) == XFS_DIR2_BLOCK_MAGIC) {
- for (i = stale = 0; i < be32_to_cpu(btp->count); i++) {
- if (be32_to_cpu(lep[i].address) == XFS_DIR2_NULL_DATAPTR)
- stale++;
- if (i > 0)
- ASSERT(be32_to_cpu(lep[i].hashval) >= be32_to_cpu(lep[i - 1].hashval));
- }
- ASSERT(count == be32_to_cpu(btp->count) - be32_to_cpu(btp->stale));
- ASSERT(stale == be32_to_cpu(btp->stale));
- }
-}
-#endif
-
-/*
- * Given a data block and an unused entry from that block,
- * return the bestfree entry if any that corresponds to it.
- */
-xfs_dir2_data_free_t *
-xfs_dir2_data_freefind(
- xfs_dir2_data_t *d, /* data block */
- xfs_dir2_data_unused_t *dup) /* data unused entry */
-{
- xfs_dir2_data_free_t *dfp; /* bestfree entry */
- xfs_dir2_data_aoff_t off; /* offset value needed */
-#if defined(DEBUG) && defined(__KERNEL__)
- int matched; /* matched the value */
- int seenzero; /* saw a 0 bestfree entry */
-#endif
-
- off = (xfs_dir2_data_aoff_t)((char *)dup - (char *)d);
-#if defined(DEBUG) && defined(__KERNEL__)
- /*
- * Validate some consistency in the bestfree table.
- * Check order, non-overlapping entries, and if we find the
- * one we're looking for it has to be exact.
- */
- ASSERT(be32_to_cpu(d->hdr.magic) == XFS_DIR2_DATA_MAGIC ||
- be32_to_cpu(d->hdr.magic) == XFS_DIR2_BLOCK_MAGIC);
- for (dfp = &d->hdr.bestfree[0], seenzero = matched = 0;
- dfp < &d->hdr.bestfree[XFS_DIR2_DATA_FD_COUNT];
- dfp++) {
- if (!dfp->offset) {
- ASSERT(!dfp->length);
- seenzero = 1;
- continue;
- }
- ASSERT(seenzero == 0);
- if (be16_to_cpu(dfp->offset) == off) {
- matched = 1;
- ASSERT(dfp->length == dup->length);
- } else if (off < be16_to_cpu(dfp->offset))
- ASSERT(off + be16_to_cpu(dup->length) <= be16_to_cpu(dfp->offset));
- else
- ASSERT(be16_to_cpu(dfp->offset) + be16_to_cpu(dfp->length) <= off);
- ASSERT(matched || be16_to_cpu(dfp->length) >= be16_to_cpu(dup->length));
- if (dfp > &d->hdr.bestfree[0])
- ASSERT(be16_to_cpu(dfp[-1].length) >= be16_to_cpu(dfp[0].length));
- }
-#endif
- /*
- * If this is smaller than the smallest bestfree entry,
- * it can't be there since they're sorted.
- */
- if (be16_to_cpu(dup->length) <
- be16_to_cpu(d->hdr.bestfree[XFS_DIR2_DATA_FD_COUNT - 1].length))
- return NULL;
- /*
- * Look at the three bestfree entries for our guy.
- */
- for (dfp = &d->hdr.bestfree[0];
- dfp < &d->hdr.bestfree[XFS_DIR2_DATA_FD_COUNT];
- dfp++) {
- if (!dfp->offset)
- return NULL;
- if (be16_to_cpu(dfp->offset) == off)
- return dfp;
- }
- /*
- * Didn't find it. This only happens if there are duplicate lengths.
- */
- return NULL;
-}
-
-/*
- * Insert an unused-space entry into the bestfree table.
- */
-xfs_dir2_data_free_t * /* entry inserted */
-xfs_dir2_data_freeinsert(
- xfs_dir2_data_t *d, /* data block pointer */
- xfs_dir2_data_unused_t *dup, /* unused space */
- int *loghead) /* log the data header (out) */
-{
- xfs_dir2_data_free_t *dfp; /* bestfree table pointer */
- xfs_dir2_data_free_t new; /* new bestfree entry */
-
-#ifdef __KERNEL__
- ASSERT(be32_to_cpu(d->hdr.magic) == XFS_DIR2_DATA_MAGIC ||
- be32_to_cpu(d->hdr.magic) == XFS_DIR2_BLOCK_MAGIC);
-#endif
- dfp = d->hdr.bestfree;
- new.length = dup->length;
- new.offset = cpu_to_be16((char *)dup - (char *)d);
- /*
- * Insert at position 0, 1, or 2; or not at all.
- */
- if (be16_to_cpu(new.length) > be16_to_cpu(dfp[0].length)) {
- dfp[2] = dfp[1];
- dfp[1] = dfp[0];
- dfp[0] = new;
- *loghead = 1;
- return &dfp[0];
- }
- if (be16_to_cpu(new.length) > be16_to_cpu(dfp[1].length)) {
- dfp[2] = dfp[1];
- dfp[1] = new;
- *loghead = 1;
- return &dfp[1];
- }
- if (be16_to_cpu(new.length) > be16_to_cpu(dfp[2].length)) {
- dfp[2] = new;
- *loghead = 1;
- return &dfp[2];
- }
- return NULL;
-}
-
-/*
- * Remove a bestfree entry from the table.
- */
-STATIC void
-xfs_dir2_data_freeremove(
- xfs_dir2_data_t *d, /* data block pointer */
- xfs_dir2_data_free_t *dfp, /* bestfree entry pointer */
- int *loghead) /* out: log data header */
-{
-#ifdef __KERNEL__
- ASSERT(be32_to_cpu(d->hdr.magic) == XFS_DIR2_DATA_MAGIC ||
- be32_to_cpu(d->hdr.magic) == XFS_DIR2_BLOCK_MAGIC);
-#endif
- /*
- * It's the first entry, slide the next 2 up.
- */
- if (dfp == &d->hdr.bestfree[0]) {
- d->hdr.bestfree[0] = d->hdr.bestfree[1];
- d->hdr.bestfree[1] = d->hdr.bestfree[2];
- }
- /*
- * It's the second entry, slide the 3rd entry up.
- */
- else if (dfp == &d->hdr.bestfree[1])
- d->hdr.bestfree[1] = d->hdr.bestfree[2];
- /*
- * Must be the last entry.
- */
- else
- ASSERT(dfp == &d->hdr.bestfree[2]);
- /*
- * Clear the 3rd entry, must be zero now.
- */
- d->hdr.bestfree[2].length = 0;
- d->hdr.bestfree[2].offset = 0;
- *loghead = 1;
-}
-
-/*
- * Given a data block, reconstruct its bestfree map.
- */
-void
-xfs_dir2_data_freescan(
- xfs_mount_t *mp, /* filesystem mount point */
- xfs_dir2_data_t *d, /* data block pointer */
- int *loghead, /* out: log data header */
- char *aendp) /* in: caller's endp */
-{
- xfs_dir2_block_tail_t *btp; /* block tail */
- xfs_dir2_data_entry_t *dep; /* active data entry */
- xfs_dir2_data_unused_t *dup; /* unused data entry */
- char *endp; /* end of block's data */
- char *p; /* current entry pointer */
-
-#ifdef __KERNEL__
- ASSERT(be32_to_cpu(d->hdr.magic) == XFS_DIR2_DATA_MAGIC ||
- be32_to_cpu(d->hdr.magic) == XFS_DIR2_BLOCK_MAGIC);
-#endif
- /*
- * Start by clearing the table.
- */
- memset(d->hdr.bestfree, 0, sizeof(d->hdr.bestfree));
- *loghead = 1;
- /*
- * Set up pointers.
- */
- p = (char *)d->u;
- if (aendp)
- endp = aendp;
- else if (be32_to_cpu(d->hdr.magic) == XFS_DIR2_BLOCK_MAGIC) {
- btp = XFS_DIR2_BLOCK_TAIL_P(mp, (xfs_dir2_block_t *)d);
- endp = (char *)XFS_DIR2_BLOCK_LEAF_P(btp);
- } else
- endp = (char *)d + mp->m_dirblksize;
- /*
- * Loop over the block's entries.
- */
- while (p < endp) {
- dup = (xfs_dir2_data_unused_t *)p;
- /*
- * If it's a free entry, insert it.
- */
- if (be16_to_cpu(dup->freetag) == XFS_DIR2_DATA_FREE_TAG) {
- ASSERT((char *)dup - (char *)d ==
- be16_to_cpu(*XFS_DIR2_DATA_UNUSED_TAG_P(dup)));
- xfs_dir2_data_freeinsert(d, dup, loghead);
- p += be16_to_cpu(dup->length);
- }
- /*
- * For active entries, check their tags and skip them.
- */
- else {
- dep = (xfs_dir2_data_entry_t *)p;
- ASSERT((char *)dep - (char *)d ==
- be16_to_cpu(*XFS_DIR2_DATA_ENTRY_TAG_P(dep)));
- p += XFS_DIR2_DATA_ENTSIZE(dep->namelen);
- }
- }
-}
-
-/*
- * Initialize a data block at the given block number in the directory.
- * Give back the buffer for the created block.
- */
-int /* error */
-xfs_dir2_data_init(
- xfs_da_args_t *args, /* directory operation args */
- xfs_dir2_db_t blkno, /* logical dir block number */
- xfs_dabuf_t **bpp) /* output block buffer */
-{
- xfs_dabuf_t *bp; /* block buffer */
- xfs_dir2_data_t *d; /* pointer to block */
- xfs_inode_t *dp; /* incore directory inode */
- xfs_dir2_data_unused_t *dup; /* unused entry pointer */
- int error; /* error return value */
- int i; /* bestfree index */
- xfs_mount_t *mp; /* filesystem mount point */
- xfs_trans_t *tp; /* transaction pointer */
- int t; /* temp */
-
- dp = args->dp;
- mp = dp->i_mount;
- tp = args->trans;
- /*
- * Get the buffer set up for the block.
- */
- error = xfs_da_get_buf(tp, dp, XFS_DIR2_DB_TO_DA(mp, blkno), -1, &bp,
- XFS_DATA_FORK);
- if (error) {
- return error;
- }
- ASSERT(bp != NULL);
- /*
- * Initialize the header.
- */
- d = bp->data;
- d->hdr.magic = cpu_to_be32(XFS_DIR2_DATA_MAGIC);
- d->hdr.bestfree[0].offset = cpu_to_be16(sizeof(d->hdr));
- for (i = 1; i < XFS_DIR2_DATA_FD_COUNT; i++) {
- d->hdr.bestfree[i].length = 0;
- d->hdr.bestfree[i].offset = 0;
- }
- /*
- * Set up an unused entry for the block's body.
- */
- dup = &d->u[0].unused;
- dup->freetag = cpu_to_be16(XFS_DIR2_DATA_FREE_TAG);
-
- t=mp->m_dirblksize - (uint)sizeof(d->hdr);
- d->hdr.bestfree[0].length = cpu_to_be16(t);
- dup->length = cpu_to_be16(t);
- *XFS_DIR2_DATA_UNUSED_TAG_P(dup) = cpu_to_be16((char *)dup - (char *)d);
- /*
- * Log it and return it.
- */
- xfs_dir2_data_log_header(tp, bp);
- xfs_dir2_data_log_unused(tp, bp, dup);
- *bpp = bp;
- return 0;
-}
-
-/*
- * Log an active data entry from the block.
- */
-void
-xfs_dir2_data_log_entry(
- xfs_trans_t *tp, /* transaction pointer */
- xfs_dabuf_t *bp, /* block buffer */
- xfs_dir2_data_entry_t *dep) /* data entry pointer */
-{
- xfs_dir2_data_t *d; /* data block pointer */
-
- d = bp->data;
- ASSERT(be32_to_cpu(d->hdr.magic) == XFS_DIR2_DATA_MAGIC ||
- be32_to_cpu(d->hdr.magic) == XFS_DIR2_BLOCK_MAGIC);
- xfs_da_log_buf(tp, bp, (uint)((char *)dep - (char *)d),
- (uint)((char *)(XFS_DIR2_DATA_ENTRY_TAG_P(dep) + 1) -
- (char *)d - 1));
-}
-
-/*
- * Log a data block header.
- */
-void
-xfs_dir2_data_log_header(
- xfs_trans_t *tp, /* transaction pointer */
- xfs_dabuf_t *bp) /* block buffer */
-{
- xfs_dir2_data_t *d; /* data block pointer */
-
- d = bp->data;
- ASSERT(be32_to_cpu(d->hdr.magic) == XFS_DIR2_DATA_MAGIC ||
- be32_to_cpu(d->hdr.magic) == XFS_DIR2_BLOCK_MAGIC);
- xfs_da_log_buf(tp, bp, (uint)((char *)&d->hdr - (char *)d),
- (uint)(sizeof(d->hdr) - 1));
-}
-
-/*
- * Log a data unused entry.
- */
-void
-xfs_dir2_data_log_unused(
- xfs_trans_t *tp, /* transaction pointer */
- xfs_dabuf_t *bp, /* block buffer */
- xfs_dir2_data_unused_t *dup) /* data unused pointer */
-{
- xfs_dir2_data_t *d; /* data block pointer */
-
- d = bp->data;
- ASSERT(be32_to_cpu(d->hdr.magic) == XFS_DIR2_DATA_MAGIC ||
- be32_to_cpu(d->hdr.magic) == XFS_DIR2_BLOCK_MAGIC);
- /*
- * Log the first part of the unused entry.
- */
- xfs_da_log_buf(tp, bp, (uint)((char *)dup - (char *)d),
- (uint)((char *)&dup->length + sizeof(dup->length) -
- 1 - (char *)d));
- /*
- * Log the end (tag) of the unused entry.
- */
- xfs_da_log_buf(tp, bp,
- (uint)((char *)XFS_DIR2_DATA_UNUSED_TAG_P(dup) - (char *)d),
- (uint)((char *)XFS_DIR2_DATA_UNUSED_TAG_P(dup) - (char *)d +
- sizeof(xfs_dir2_data_off_t) - 1));
-}
-
-/*
- * Make a byte range in the data block unused.
- * Its current contents are unimportant.
- */
-void
-xfs_dir2_data_make_free(
- xfs_trans_t *tp, /* transaction pointer */
- xfs_dabuf_t *bp, /* block buffer */
- xfs_dir2_data_aoff_t offset, /* starting byte offset */
- xfs_dir2_data_aoff_t len, /* length in bytes */
- int *needlogp, /* out: log header */
- int *needscanp) /* out: regen bestfree */
-{
- xfs_dir2_data_t *d; /* data block pointer */
- xfs_dir2_data_free_t *dfp; /* bestfree pointer */
- char *endptr; /* end of data area */
- xfs_mount_t *mp; /* filesystem mount point */
- int needscan; /* need to regen bestfree */
- xfs_dir2_data_unused_t *newdup; /* new unused entry */
- xfs_dir2_data_unused_t *postdup; /* unused entry after us */
- xfs_dir2_data_unused_t *prevdup; /* unused entry before us */
-
- mp = tp->t_mountp;
- d = bp->data;
- /*
- * Figure out where the end of the data area is.
- */
- if (be32_to_cpu(d->hdr.magic) == XFS_DIR2_DATA_MAGIC)
- endptr = (char *)d + mp->m_dirblksize;
- else {
- xfs_dir2_block_tail_t *btp; /* block tail */
-
- ASSERT(be32_to_cpu(d->hdr.magic) == XFS_DIR2_BLOCK_MAGIC);
- btp = XFS_DIR2_BLOCK_TAIL_P(mp, (xfs_dir2_block_t *)d);
- endptr = (char *)XFS_DIR2_BLOCK_LEAF_P(btp);
- }
- /*
- * If this isn't the start of the block, then back up to
- * the previous entry and see if it's free.
- */
- if (offset > sizeof(d->hdr)) {
- __be16 *tagp; /* tag just before us */
-
- tagp = (__be16 *)((char *)d + offset) - 1;
- prevdup = (xfs_dir2_data_unused_t *)((char *)d + be16_to_cpu(*tagp));
- if (be16_to_cpu(prevdup->freetag) != XFS_DIR2_DATA_FREE_TAG)
- prevdup = NULL;
- } else
- prevdup = NULL;
- /*
- * If this isn't the end of the block, see if the entry after
- * us is free.
- */
- if ((char *)d + offset + len < endptr) {
- postdup =
- (xfs_dir2_data_unused_t *)((char *)d + offset + len);
- if (be16_to_cpu(postdup->freetag) != XFS_DIR2_DATA_FREE_TAG)
- postdup = NULL;
- } else
- postdup = NULL;
- ASSERT(*needscanp == 0);
- needscan = 0;
- /*
- * Previous and following entries are both free,
- * merge everything into a single free entry.
- */
- if (prevdup && postdup) {
- xfs_dir2_data_free_t *dfp2; /* another bestfree pointer */
-
- /*
- * See if prevdup and/or postdup are in bestfree table.
- */
- dfp = xfs_dir2_data_freefind(d, prevdup);
- dfp2 = xfs_dir2_data_freefind(d, postdup);
- /*
- * We need a rescan unless there are exactly 2 free entries
- * namely our two. Then we know what's happening, otherwise
- * since the third bestfree is there, there might be more
- * entries.
- */
- needscan = (d->hdr.bestfree[2].length != 0);
- /*
- * Fix up the new big freespace.
- */
- be16_add(&prevdup->length, len + be16_to_cpu(postdup->length));
- *XFS_DIR2_DATA_UNUSED_TAG_P(prevdup) =
- cpu_to_be16((char *)prevdup - (char *)d);
- xfs_dir2_data_log_unused(tp, bp, prevdup);
- if (!needscan) {
- /*
- * Has to be the case that entries 0 and 1 are
- * dfp and dfp2 (don't know which is which), and
- * entry 2 is empty.
- * Remove entry 1 first then entry 0.
- */
- ASSERT(dfp && dfp2);
- if (dfp == &d->hdr.bestfree[1]) {
- dfp = &d->hdr.bestfree[0];
- ASSERT(dfp2 == dfp);
- dfp2 = &d->hdr.bestfree[1];
- }
- xfs_dir2_data_freeremove(d, dfp2, needlogp);
- xfs_dir2_data_freeremove(d, dfp, needlogp);
- /*
- * Now insert the new entry.
- */
- dfp = xfs_dir2_data_freeinsert(d, prevdup, needlogp);
- ASSERT(dfp == &d->hdr.bestfree[0]);
- ASSERT(dfp->length == prevdup->length);
- ASSERT(!dfp[1].length);
- ASSERT(!dfp[2].length);
- }
- }
- /*
- * The entry before us is free, merge with it.
- */
- else if (prevdup) {
- dfp = xfs_dir2_data_freefind(d, prevdup);
- be16_add(&prevdup->length, len);
- *XFS_DIR2_DATA_UNUSED_TAG_P(prevdup) =
- cpu_to_be16((char *)prevdup - (char *)d);
- xfs_dir2_data_log_unused(tp, bp, prevdup);
- /*
- * If the previous entry was in the table, the new entry
- * is longer, so it will be in the table too. Remove
- * the old one and add the new one.
- */
- if (dfp) {
- xfs_dir2_data_freeremove(d, dfp, needlogp);
- (void)xfs_dir2_data_freeinsert(d, prevdup, needlogp);
- }
- /*
- * Otherwise we need a scan if the new entry is big enough.
- */
- else {
- needscan = be16_to_cpu(prevdup->length) >
- be16_to_cpu(d->hdr.bestfree[2].length);
- }
- }
- /*
- * The following entry is free, merge with it.
- */
- else if (postdup) {
- dfp = xfs_dir2_data_freefind(d, postdup);
- newdup = (xfs_dir2_data_unused_t *)((char *)d + offset);
- newdup->freetag = cpu_to_be16(XFS_DIR2_DATA_FREE_TAG);
- newdup->length = cpu_to_be16(len + be16_to_cpu(postdup->length));
- *XFS_DIR2_DATA_UNUSED_TAG_P(newdup) =
- cpu_to_be16((char *)newdup - (char *)d);
- xfs_dir2_data_log_unused(tp, bp, newdup);
- /*
- * If the following entry was in the table, the new entry
- * is longer, so it will be in the table too. Remove
- * the old one and add the new one.
- */
- if (dfp) {
- xfs_dir2_data_freeremove(d, dfp, needlogp);
- (void)xfs_dir2_data_freeinsert(d, newdup, needlogp);
- }
- /*
- * Otherwise we need a scan if the new entry is big enough.
- */
- else {
- needscan = be16_to_cpu(newdup->length) >
- be16_to_cpu(d->hdr.bestfree[2].length);
- }
- }
- /*
- * Neither neighbor is free. Make a new entry.
- */
- else {
- newdup = (xfs_dir2_data_unused_t *)((char *)d + offset);
- newdup->freetag = cpu_to_be16(XFS_DIR2_DATA_FREE_TAG);
- newdup->length = cpu_to_be16(len);
- *XFS_DIR2_DATA_UNUSED_TAG_P(newdup) =
- cpu_to_be16((char *)newdup - (char *)d);
- xfs_dir2_data_log_unused(tp, bp, newdup);
- (void)xfs_dir2_data_freeinsert(d, newdup, needlogp);
- }
- *needscanp = needscan;
-}
-
-/*
- * Take a byte range out of an existing unused space and make it un-free.
- */
-void
-xfs_dir2_data_use_free(
- xfs_trans_t *tp, /* transaction pointer */
- xfs_dabuf_t *bp, /* data block buffer */
- xfs_dir2_data_unused_t *dup, /* unused entry */
- xfs_dir2_data_aoff_t offset, /* starting offset to use */
- xfs_dir2_data_aoff_t len, /* length to use */
- int *needlogp, /* out: need to log header */
- int *needscanp) /* out: need regen bestfree */
-{
- xfs_dir2_data_t *d; /* data block */
- xfs_dir2_data_free_t *dfp; /* bestfree pointer */
- int matchback; /* matches end of freespace */
- int matchfront; /* matches start of freespace */
- int needscan; /* need to regen bestfree */
- xfs_dir2_data_unused_t *newdup; /* new unused entry */
- xfs_dir2_data_unused_t *newdup2; /* another new unused entry */
- int oldlen; /* old unused entry's length */
-
- d = bp->data;
- ASSERT(be32_to_cpu(d->hdr.magic) == XFS_DIR2_DATA_MAGIC ||
- be32_to_cpu(d->hdr.magic) == XFS_DIR2_BLOCK_MAGIC);
- ASSERT(be16_to_cpu(dup->freetag) == XFS_DIR2_DATA_FREE_TAG);
- ASSERT(offset >= (char *)dup - (char *)d);
- ASSERT(offset + len <= (char *)dup + be16_to_cpu(dup->length) - (char *)d);
- ASSERT((char *)dup - (char *)d == be16_to_cpu(*XFS_DIR2_DATA_UNUSED_TAG_P(dup)));
- /*
- * Look up the entry in the bestfree table.
- */
- dfp = xfs_dir2_data_freefind(d, dup);
- oldlen = be16_to_cpu(dup->length);
- ASSERT(dfp || oldlen <= be16_to_cpu(d->hdr.bestfree[2].length));
- /*
- * Check for alignment with front and back of the entry.
- */
- matchfront = (char *)dup - (char *)d == offset;
- matchback = (char *)dup + oldlen - (char *)d == offset + len;
- ASSERT(*needscanp == 0);
- needscan = 0;
- /*
- * If we matched it exactly we just need to get rid of it from
- * the bestfree table.
- */
- if (matchfront && matchback) {
- if (dfp) {
- needscan = (d->hdr.bestfree[2].offset != 0);
- if (!needscan)
- xfs_dir2_data_freeremove(d, dfp, needlogp);
- }
- }
- /*
- * We match the first part of the entry.
- * Make a new entry with the remaining freespace.
- */
- else if (matchfront) {
- newdup = (xfs_dir2_data_unused_t *)((char *)d + offset + len);
- newdup->freetag = cpu_to_be16(XFS_DIR2_DATA_FREE_TAG);
- newdup->length = cpu_to_be16(oldlen - len);
- *XFS_DIR2_DATA_UNUSED_TAG_P(newdup) =
- cpu_to_be16((char *)newdup - (char *)d);
- xfs_dir2_data_log_unused(tp, bp, newdup);
- /*
- * If it was in the table, remove it and add the new one.
- */
- if (dfp) {
- xfs_dir2_data_freeremove(d, dfp, needlogp);
- dfp = xfs_dir2_data_freeinsert(d, newdup, needlogp);
- ASSERT(dfp != NULL);
- ASSERT(dfp->length == newdup->length);
- ASSERT(be16_to_cpu(dfp->offset) == (char *)newdup - (char *)d);
- /*
- * If we got inserted at the last slot,
- * that means we don't know if there was a better
- * choice for the last slot, or not. Rescan.
- */
- needscan = dfp == &d->hdr.bestfree[2];
- }
- }
- /*
- * We match the last part of the entry.
- * Trim the allocated space off the tail of the entry.
- */
- else if (matchback) {
- newdup = dup;
- newdup->length = cpu_to_be16(((char *)d + offset) - (char *)newdup);
- *XFS_DIR2_DATA_UNUSED_TAG_P(newdup) =
- cpu_to_be16((char *)newdup - (char *)d);
- xfs_dir2_data_log_unused(tp, bp, newdup);
- /*
- * If it was in the table, remove it and add the new one.
- */
- if (dfp) {
- xfs_dir2_data_freeremove(d, dfp, needlogp);
- dfp = xfs_dir2_data_freeinsert(d, newdup, needlogp);
- ASSERT(dfp != NULL);
- ASSERT(dfp->length == newdup->length);
- ASSERT(be16_to_cpu(dfp->offset) == (char *)newdup - (char *)d);
- /*
- * If we got inserted at the last slot,
- * that means we don't know if there was a better
- * choice for the last slot, or not. Rescan.
- */
- needscan = dfp == &d->hdr.bestfree[2];
- }
- }
- /*
- * Poking out the middle of an entry.
- * Make two new entries.
- */
- else {
- newdup = dup;
- newdup->length = cpu_to_be16(((char *)d + offset) - (char *)newdup);
- *XFS_DIR2_DATA_UNUSED_TAG_P(newdup) =
- cpu_to_be16((char *)newdup - (char *)d);
- xfs_dir2_data_log_unused(tp, bp, newdup);
- newdup2 = (xfs_dir2_data_unused_t *)((char *)d + offset + len);
- newdup2->freetag = cpu_to_be16(XFS_DIR2_DATA_FREE_TAG);
- newdup2->length = cpu_to_be16(oldlen - len - be16_to_cpu(newdup->length));
- *XFS_DIR2_DATA_UNUSED_TAG_P(newdup2) =
- cpu_to_be16((char *)newdup2 - (char *)d);
- xfs_dir2_data_log_unused(tp, bp, newdup2);
- /*
- * If the old entry was in the table, we need to scan
- * if the 3rd entry was valid, since these entries
- * are smaller than the old one.
- * If we don't need to scan that means there were 1 or 2
- * entries in the table, and removing the old and adding
- * the 2 new will work.
- */
- if (dfp) {
- needscan = (d->hdr.bestfree[2].length != 0);
- if (!needscan) {
- xfs_dir2_data_freeremove(d, dfp, needlogp);
- (void)xfs_dir2_data_freeinsert(d, newdup,
- needlogp);
- (void)xfs_dir2_data_freeinsert(d, newdup2,
- needlogp);
- }
- }
- }
- *needscanp = needscan;
-}
diff --git a/sys/gnu/fs/xfs/xfs_dir2_data.h b/sys/gnu/fs/xfs/xfs_dir2_data.h
deleted file mode 100644
index 0847cbb..0000000
--- a/sys/gnu/fs/xfs/xfs_dir2_data.h
+++ /dev/null
@@ -1,188 +0,0 @@
-/*
- * Copyright (c) 2000,2005 Silicon Graphics, Inc.
- * All Rights Reserved.
- *
- * 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.
- *
- * This program is distributed in the hope that it would 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 the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- */
-#ifndef __XFS_DIR2_DATA_H__
-#define __XFS_DIR2_DATA_H__
-
-/*
- * Directory format 2, data block structures.
- */
-
-struct xfs_dabuf;
-struct xfs_da_args;
-struct xfs_inode;
-struct xfs_trans;
-
-/*
- * Constants.
- */
-#define XFS_DIR2_DATA_MAGIC 0x58443244 /* XD2D: for multiblock dirs */
-#define XFS_DIR2_DATA_ALIGN_LOG 3 /* i.e., 8 bytes */
-#define XFS_DIR2_DATA_ALIGN (1 << XFS_DIR2_DATA_ALIGN_LOG)
-#define XFS_DIR2_DATA_FREE_TAG 0xffff
-#define XFS_DIR2_DATA_FD_COUNT 3
-
-/*
- * Directory address space divided into sections,
- * spaces separated by 32gb.
- */
-#define XFS_DIR2_SPACE_SIZE (1ULL << (32 + XFS_DIR2_DATA_ALIGN_LOG))
-#define XFS_DIR2_DATA_SPACE 0
-#define XFS_DIR2_DATA_OFFSET (XFS_DIR2_DATA_SPACE * XFS_DIR2_SPACE_SIZE)
-#define XFS_DIR2_DATA_FIRSTDB(mp) \
- XFS_DIR2_BYTE_TO_DB(mp, XFS_DIR2_DATA_OFFSET)
-
-/*
- * Offsets of . and .. in data space (always block 0)
- */
-#define XFS_DIR2_DATA_DOT_OFFSET \
- ((xfs_dir2_data_aoff_t)sizeof(xfs_dir2_data_hdr_t))
-#define XFS_DIR2_DATA_DOTDOT_OFFSET \
- (XFS_DIR2_DATA_DOT_OFFSET + XFS_DIR2_DATA_ENTSIZE(1))
-#define XFS_DIR2_DATA_FIRST_OFFSET \
- (XFS_DIR2_DATA_DOTDOT_OFFSET + XFS_DIR2_DATA_ENTSIZE(2))
-
-/*
- * Structures.
- */
-
-/*
- * Describe a free area in the data block.
- * The freespace will be formatted as a xfs_dir2_data_unused_t.
- */
-typedef struct xfs_dir2_data_free {
- __be16 offset; /* start of freespace */
- __be16 length; /* length of freespace */
-} xfs_dir2_data_free_t;
-
-/*
- * Header for the data blocks.
- * Always at the beginning of a directory-sized block.
- * The code knows that XFS_DIR2_DATA_FD_COUNT is 3.
- */
-typedef struct xfs_dir2_data_hdr {
- __be32 magic; /* XFS_DIR2_DATA_MAGIC */
- /* or XFS_DIR2_BLOCK_MAGIC */
- xfs_dir2_data_free_t bestfree[XFS_DIR2_DATA_FD_COUNT];
-} xfs_dir2_data_hdr_t;
-
-/*
- * Active entry in a data block. Aligned to 8 bytes.
- * Tag appears as the last 2 bytes.
- */
-typedef struct xfs_dir2_data_entry {
- xfs_ino_t inumber; /* inode number */
- __uint8_t namelen; /* name length */
- __uint8_t name[1]; /* name bytes, no null */
- /* variable offset */
- xfs_dir2_data_off_t tag; /* starting offset of us */
-} xfs_dir2_data_entry_t;
-
-/*
- * Unused entry in a data block. Aligned to 8 bytes.
- * Tag appears as the last 2 bytes.
- */
-typedef struct xfs_dir2_data_unused {
- __be16 freetag; /* XFS_DIR2_DATA_FREE_TAG */
- __be16 length; /* total free length */
- /* variable offset */
- __be16 tag; /* starting offset of us */
-} xfs_dir2_data_unused_t;
-
-typedef union {
- xfs_dir2_data_entry_t entry;
- xfs_dir2_data_unused_t unused;
-} xfs_dir2_data_union_t;
-
-/*
- * Generic data block structure, for xfs_db.
- */
-typedef struct xfs_dir2_data {
- xfs_dir2_data_hdr_t hdr; /* magic XFS_DIR2_DATA_MAGIC */
- xfs_dir2_data_union_t u[1];
-} xfs_dir2_data_t;
-
-/*
- * Macros.
- */
-
-/*
- * Size of a data entry.
- */
-#define XFS_DIR2_DATA_ENTSIZE(n) xfs_dir2_data_entsize(n)
-static inline int xfs_dir2_data_entsize(int n)
-{
- return (int)roundup(offsetof(xfs_dir2_data_entry_t, name[0]) + (n) + \
- (uint)sizeof(xfs_dir2_data_off_t), XFS_DIR2_DATA_ALIGN);
-}
-
-/*
- * Pointer to an entry's tag word.
- */
-#define XFS_DIR2_DATA_ENTRY_TAG_P(dep) xfs_dir2_data_entry_tag_p(dep)
-static inline __be16 *
-xfs_dir2_data_entry_tag_p(xfs_dir2_data_entry_t *dep)
-{
- return (__be16 *)((char *)dep +
- XFS_DIR2_DATA_ENTSIZE(dep->namelen) - sizeof(__be16));
-}
-
-/*
- * Pointer to a freespace's tag word.
- */
-#define XFS_DIR2_DATA_UNUSED_TAG_P(dup) \
- xfs_dir2_data_unused_tag_p(dup)
-static inline __be16 *
-xfs_dir2_data_unused_tag_p(xfs_dir2_data_unused_t *dup)
-{
- return (__be16 *)((char *)dup +
- be16_to_cpu(dup->length) - sizeof(__be16));
-}
-
-/*
- * Function declarations.
- */
-#ifdef DEBUG
-extern void xfs_dir2_data_check(struct xfs_inode *dp, struct xfs_dabuf *bp);
-#else
-#define xfs_dir2_data_check(dp,bp)
-#endif
-extern xfs_dir2_data_free_t *xfs_dir2_data_freefind(xfs_dir2_data_t *d,
- xfs_dir2_data_unused_t *dup);
-extern xfs_dir2_data_free_t *xfs_dir2_data_freeinsert(xfs_dir2_data_t *d,
- xfs_dir2_data_unused_t *dup, int *loghead);
-extern void xfs_dir2_data_freescan(struct xfs_mount *mp, xfs_dir2_data_t *d,
- int *loghead, char *aendp);
-extern int xfs_dir2_data_init(struct xfs_da_args *args, xfs_dir2_db_t blkno,
- struct xfs_dabuf **bpp);
-extern void xfs_dir2_data_log_entry(struct xfs_trans *tp, struct xfs_dabuf *bp,
- xfs_dir2_data_entry_t *dep);
-extern void xfs_dir2_data_log_header(struct xfs_trans *tp,
- struct xfs_dabuf *bp);
-extern void xfs_dir2_data_log_unused(struct xfs_trans *tp, struct xfs_dabuf *bp,
- xfs_dir2_data_unused_t *dup);
-extern void xfs_dir2_data_make_free(struct xfs_trans *tp, struct xfs_dabuf *bp,
- xfs_dir2_data_aoff_t offset,
- xfs_dir2_data_aoff_t len, int *needlogp,
- int *needscanp);
-extern void xfs_dir2_data_use_free(struct xfs_trans *tp, struct xfs_dabuf *bp,
- xfs_dir2_data_unused_t *dup,
- xfs_dir2_data_aoff_t offset,
- xfs_dir2_data_aoff_t len, int *needlogp,
- int *needscanp);
-
-#endif /* __XFS_DIR2_DATA_H__ */
diff --git a/sys/gnu/fs/xfs/xfs_dir2_leaf.c b/sys/gnu/fs/xfs/xfs_dir2_leaf.c
deleted file mode 100644
index 5fe88d5..0000000
--- a/sys/gnu/fs/xfs/xfs_dir2_leaf.c
+++ /dev/null
@@ -1,1877 +0,0 @@
-/*
- * Copyright (c) 2000-2003,2005 Silicon Graphics, Inc.
- * All Rights Reserved.
- *
- * 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.
- *
- * This program is distributed in the hope that it would 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 the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- */
-#include "xfs.h"
-#include "xfs_fs.h"
-#include "xfs_types.h"
-#include "xfs_bit.h"
-#include "xfs_log.h"
-#include "xfs_inum.h"
-#include "xfs_trans.h"
-#include "xfs_sb.h"
-#include "xfs_ag.h"
-#include "xfs_dir.h"
-#include "xfs_dir2.h"
-#include "xfs_dmapi.h"
-#include "xfs_mount.h"
-#include "xfs_da_btree.h"
-#include "xfs_bmap_btree.h"
-#include "xfs_attr_sf.h"
-#include "xfs_dir_sf.h"
-#include "xfs_dir2_sf.h"
-#include "xfs_dinode.h"
-#include "xfs_inode.h"
-#include "xfs_bmap.h"
-#include "xfs_dir2_data.h"
-#include "xfs_dir2_leaf.h"
-#include "xfs_dir2_block.h"
-#include "xfs_dir2_node.h"
-#include "xfs_dir2_trace.h"
-#include "xfs_error.h"
-
-/*
- * Local function declarations.
- */
-#ifdef DEBUG
-static void xfs_dir2_leaf_check(xfs_inode_t *dp, xfs_dabuf_t *bp);
-#else
-#define xfs_dir2_leaf_check(dp, bp)
-#endif
-static int xfs_dir2_leaf_lookup_int(xfs_da_args_t *args, xfs_dabuf_t **lbpp,
- int *indexp, xfs_dabuf_t **dbpp);
-static void xfs_dir2_leaf_log_bests(struct xfs_trans *tp, struct xfs_dabuf *bp,
- int first, int last);
-static void xfs_dir2_leaf_log_tail(struct xfs_trans *tp, struct xfs_dabuf *bp);
-
-
-/*
- * Convert a block form directory to a leaf form directory.
- */
-int /* error */
-xfs_dir2_block_to_leaf(
- xfs_da_args_t *args, /* operation arguments */
- xfs_dabuf_t *dbp) /* input block's buffer */
-{
- __be16 *bestsp; /* leaf's bestsp entries */
- xfs_dablk_t blkno; /* leaf block's bno */
- xfs_dir2_block_t *block; /* block structure */
- xfs_dir2_leaf_entry_t *blp; /* block's leaf entries */
- xfs_dir2_block_tail_t *btp; /* block's tail */
- xfs_inode_t *dp; /* incore directory inode */
- int error; /* error return code */
- xfs_dabuf_t *lbp; /* leaf block's buffer */
- xfs_dir2_db_t ldb; /* leaf block's bno */
- xfs_dir2_leaf_t *leaf; /* leaf structure */
- xfs_dir2_leaf_tail_t *ltp; /* leaf's tail */
- xfs_mount_t *mp; /* filesystem mount point */
- int needlog; /* need to log block header */
- int needscan; /* need to rescan bestfree */
- xfs_trans_t *tp; /* transaction pointer */
-
- xfs_dir2_trace_args_b("block_to_leaf", args, dbp);
- dp = args->dp;
- mp = dp->i_mount;
- tp = args->trans;
- /*
- * Add the leaf block to the inode.
- * This interface will only put blocks in the leaf/node range.
- * Since that's empty now, we'll get the root (block 0 in range).
- */
- if ((error = xfs_da_grow_inode(args, &blkno))) {
- return error;
- }
- ldb = XFS_DIR2_DA_TO_DB(mp, blkno);
- ASSERT(ldb == XFS_DIR2_LEAF_FIRSTDB(mp));
- /*
- * Initialize the leaf block, get a buffer for it.
- */
- if ((error = xfs_dir2_leaf_init(args, ldb, &lbp, XFS_DIR2_LEAF1_MAGIC))) {
- return error;
- }
- ASSERT(lbp != NULL);
- leaf = lbp->data;
- block = dbp->data;
- xfs_dir2_data_check(dp, dbp);
- btp = XFS_DIR2_BLOCK_TAIL_P(mp, block);
- blp = XFS_DIR2_BLOCK_LEAF_P(btp);
- /*
- * Set the counts in the leaf header.
- */
- leaf->hdr.count = cpu_to_be16(be32_to_cpu(btp->count));
- leaf->hdr.stale = cpu_to_be16(be32_to_cpu(btp->stale));
- /*
- * Could compact these but I think we always do the conversion
- * after squeezing out stale entries.
- */
- memcpy(leaf->ents, blp, be32_to_cpu(btp->count) * sizeof(xfs_dir2_leaf_entry_t));
- xfs_dir2_leaf_log_ents(tp, lbp, 0, be16_to_cpu(leaf->hdr.count) - 1);
- needscan = 0;
- needlog = 1;
- /*
- * Make the space formerly occupied by the leaf entries and block
- * tail be free.
- */
- xfs_dir2_data_make_free(tp, dbp,
- (xfs_dir2_data_aoff_t)((char *)blp - (char *)block),
- (xfs_dir2_data_aoff_t)((char *)block + mp->m_dirblksize -
- (char *)blp),
- &needlog, &needscan);
- /*
- * Fix up the block header, make it a data block.
- */
- block->hdr.magic = cpu_to_be32(XFS_DIR2_DATA_MAGIC);
- if (needscan)
- xfs_dir2_data_freescan(mp, (xfs_dir2_data_t *)block, &needlog,
- NULL);
- /*
- * Set up leaf tail and bests table.
- */
- ltp = XFS_DIR2_LEAF_TAIL_P(mp, leaf);
- ltp->bestcount = cpu_to_be32(1);
- bestsp = XFS_DIR2_LEAF_BESTS_P(ltp);
- bestsp[0] = block->hdr.bestfree[0].length;
- /*
- * Log the data header and leaf bests table.
- */
- if (needlog)
- xfs_dir2_data_log_header(tp, dbp);
- xfs_dir2_leaf_check(dp, lbp);
- xfs_dir2_data_check(dp, dbp);
- xfs_dir2_leaf_log_bests(tp, lbp, 0, 0);
- xfs_da_buf_done(lbp);
- return 0;
-}
-
-/*
- * Add an entry to a leaf form directory.
- */
-int /* error */
-xfs_dir2_leaf_addname(
- xfs_da_args_t *args) /* operation arguments */
-{
- __be16 *bestsp; /* freespace table in leaf */
- int compact; /* need to compact leaves */
- xfs_dir2_data_t *data; /* data block structure */
- xfs_dabuf_t *dbp; /* data block buffer */
- xfs_dir2_data_entry_t *dep; /* data block entry */
- xfs_inode_t *dp; /* incore directory inode */
- xfs_dir2_data_unused_t *dup; /* data unused entry */
- int error; /* error return value */
- int grown; /* allocated new data block */
- int highstale; /* index of next stale leaf */
- int i; /* temporary, index */
- int index; /* leaf table position */
- xfs_dabuf_t *lbp; /* leaf's buffer */
- xfs_dir2_leaf_t *leaf; /* leaf structure */
- int length; /* length of new entry */
- xfs_dir2_leaf_entry_t *lep; /* leaf entry table pointer */
- int lfloglow; /* low leaf logging index */
- int lfloghigh; /* high leaf logging index */
- int lowstale; /* index of prev stale leaf */
- xfs_dir2_leaf_tail_t *ltp; /* leaf tail pointer */
- xfs_mount_t *mp; /* filesystem mount point */
- int needbytes; /* leaf block bytes needed */
- int needlog; /* need to log data header */
- int needscan; /* need to rescan data free */
- __be16 *tagp; /* end of data entry */
- xfs_trans_t *tp; /* transaction pointer */
- xfs_dir2_db_t use_block; /* data block number */
-
- xfs_dir2_trace_args("leaf_addname", args);
- dp = args->dp;
- tp = args->trans;
- mp = dp->i_mount;
- /*
- * Read the leaf block.
- */
- error = xfs_da_read_buf(tp, dp, mp->m_dirleafblk, -1, &lbp,
- XFS_DATA_FORK);
- if (error) {
- return error;
- }
- ASSERT(lbp != NULL);
- /*
- * Look up the entry by hash value and name.
- * We know it's not there, our caller has already done a lookup.
- * So the index is of the entry to insert in front of.
- * But if there are dup hash values the index is of the first of those.
- */
- index = xfs_dir2_leaf_search_hash(args, lbp);
- leaf = lbp->data;
- ltp = XFS_DIR2_LEAF_TAIL_P(mp, leaf);
- bestsp = XFS_DIR2_LEAF_BESTS_P(ltp);
- length = XFS_DIR2_DATA_ENTSIZE(args->namelen);
- /*
- * See if there are any entries with the same hash value
- * and space in their block for the new entry.
- * This is good because it puts multiple same-hash value entries
- * in a data block, improving the lookup of those entries.
- */
- for (use_block = -1, lep = &leaf->ents[index];
- index < be16_to_cpu(leaf->hdr.count) && be32_to_cpu(lep->hashval) == args->hashval;
- index++, lep++) {
- if (be32_to_cpu(lep->address) == XFS_DIR2_NULL_DATAPTR)
- continue;
- i = XFS_DIR2_DATAPTR_TO_DB(mp, be32_to_cpu(lep->address));
- ASSERT(i < be32_to_cpu(ltp->bestcount));
- ASSERT(be16_to_cpu(bestsp[i]) != NULLDATAOFF);
- if (be16_to_cpu(bestsp[i]) >= length) {
- use_block = i;
- break;
- }
- }
- /*
- * Didn't find a block yet, linear search all the data blocks.
- */
- if (use_block == -1) {
- for (i = 0; i < be32_to_cpu(ltp->bestcount); i++) {
- /*
- * Remember a block we see that's missing.
- */
- if (be16_to_cpu(bestsp[i]) == NULLDATAOFF && use_block == -1)
- use_block = i;
- else if (be16_to_cpu(bestsp[i]) >= length) {
- use_block = i;
- break;
- }
- }
- }
- /*
- * How many bytes do we need in the leaf block?
- */
- needbytes =
- (leaf->hdr.stale ? 0 : (uint)sizeof(leaf->ents[0])) +
- (use_block != -1 ? 0 : (uint)sizeof(leaf->bests[0]));
- /*
- * Now kill use_block if it refers to a missing block, so we
- * can use it as an indication of allocation needed.
- */
- if (use_block != -1 && be16_to_cpu(bestsp[use_block]) == NULLDATAOFF)
- use_block = -1;
- /*
- * If we don't have enough free bytes but we can make enough
- * by compacting out stale entries, we'll do that.
- */
- if ((char *)bestsp - (char *)&leaf->ents[be16_to_cpu(leaf->hdr.count)] < needbytes &&
- be16_to_cpu(leaf->hdr.stale) > 1) {
- compact = 1;
- }
- /*
- * Otherwise if we don't have enough free bytes we need to
- * convert to node form.
- */
- else if ((char *)bestsp - (char *)&leaf->ents[be16_to_cpu(leaf->hdr.count)] <
- needbytes) {
- /*
- * Just checking or no space reservation, give up.
- */
- if (args->justcheck || args->total == 0) {
- xfs_da_brelse(tp, lbp);
- return XFS_ERROR(ENOSPC);
- }
- /*
- * Convert to node form.
- */
- error = xfs_dir2_leaf_to_node(args, lbp);
- xfs_da_buf_done(lbp);
- if (error)
- return error;
- /*
- * Then add the new entry.
- */
- return xfs_dir2_node_addname(args);
- }
- /*
- * Otherwise it will fit without compaction.
- */
- else
- compact = 0;
- /*
- * If just checking, then it will fit unless we needed to allocate
- * a new data block.
- */
- if (args->justcheck) {
- xfs_da_brelse(tp, lbp);
- return use_block == -1 ? XFS_ERROR(ENOSPC) : 0;
- }
- /*
- * If no allocations are allowed, return now before we've
- * changed anything.
- */
- if (args->total == 0 && use_block == -1) {
- xfs_da_brelse(tp, lbp);
- return XFS_ERROR(ENOSPC);
- }
- /*
- * Need to compact the leaf entries, removing stale ones.
- * Leave one stale entry behind - the one closest to our
- * insertion index - and we'll shift that one to our insertion
- * point later.
- */
- if (compact) {
- xfs_dir2_leaf_compact_x1(lbp, &index, &lowstale, &highstale,
- &lfloglow, &lfloghigh);
- }
- /*
- * There are stale entries, so we'll need log-low and log-high
- * impossibly bad values later.
- */
- else if (be16_to_cpu(leaf->hdr.stale)) {
- lfloglow = be16_to_cpu(leaf->hdr.count);
- lfloghigh = -1;
- }
- /*
- * If there was no data block space found, we need to allocate
- * a new one.
- */
- if (use_block == -1) {
- /*
- * Add the new data block.
- */
- if ((error = xfs_dir2_grow_inode(args, XFS_DIR2_DATA_SPACE,
- &use_block))) {
- xfs_da_brelse(tp, lbp);
- return error;
- }
- /*
- * Initialize the block.
- */
- if ((error = xfs_dir2_data_init(args, use_block, &dbp))) {
- xfs_da_brelse(tp, lbp);
- return error;
- }
- /*
- * If we're adding a new data block on the end we need to
- * extend the bests table. Copy it up one entry.
- */
- if (use_block >= be32_to_cpu(ltp->bestcount)) {
- bestsp--;
- memmove(&bestsp[0], &bestsp[1],
- be32_to_cpu(ltp->bestcount) * sizeof(bestsp[0]));
- be32_add(&ltp->bestcount, 1);
- xfs_dir2_leaf_log_tail(tp, lbp);
- xfs_dir2_leaf_log_bests(tp, lbp, 0, be32_to_cpu(ltp->bestcount) - 1);
- }
- /*
- * If we're filling in a previously empty block just log it.
- */
- else
- xfs_dir2_leaf_log_bests(tp, lbp, use_block, use_block);
- data = dbp->data;
- bestsp[use_block] = data->hdr.bestfree[0].length;
- grown = 1;
- }
- /*
- * Already had space in some data block.
- * Just read that one in.
- */
- else {
- if ((error =
- xfs_da_read_buf(tp, dp, XFS_DIR2_DB_TO_DA(mp, use_block),
- -1, &dbp, XFS_DATA_FORK))) {
- xfs_da_brelse(tp, lbp);
- return error;
- }
- data = dbp->data;
- grown = 0;
- }
- xfs_dir2_data_check(dp, dbp);
- /*
- * Point to the biggest freespace in our data block.
- */
- dup = (xfs_dir2_data_unused_t *)
- ((char *)data + be16_to_cpu(data->hdr.bestfree[0].offset));
- ASSERT(be16_to_cpu(dup->length) >= length);
- needscan = needlog = 0;
- /*
- * Mark the initial part of our freespace in use for the new entry.
- */
- xfs_dir2_data_use_free(tp, dbp, dup,
- (xfs_dir2_data_aoff_t)((char *)dup - (char *)data), length,
- &needlog, &needscan);
- /*
- * Initialize our new entry (at last).
- */
- dep = (xfs_dir2_data_entry_t *)dup;
- INT_SET(dep->inumber, ARCH_CONVERT, args->inumber);
- dep->namelen = args->namelen;
- memcpy(dep->name, args->name, dep->namelen);
- tagp = XFS_DIR2_DATA_ENTRY_TAG_P(dep);
- *tagp = cpu_to_be16((char *)dep - (char *)data);
- /*
- * Need to scan fix up the bestfree table.
- */
- if (needscan)
- xfs_dir2_data_freescan(mp, data, &needlog, NULL);
- /*
- * Need to log the data block's header.
- */
- if (needlog)
- xfs_dir2_data_log_header(tp, dbp);
- xfs_dir2_data_log_entry(tp, dbp, dep);
- /*
- * If the bests table needs to be changed, do it.
- * Log the change unless we've already done that.
- */
- if (be16_to_cpu(bestsp[use_block]) != be16_to_cpu(data->hdr.bestfree[0].length)) {
- bestsp[use_block] = data->hdr.bestfree[0].length;
- if (!grown)
- xfs_dir2_leaf_log_bests(tp, lbp, use_block, use_block);
- }
- /*
- * Now we need to make room to insert the leaf entry.
- * If there are no stale entries, we just insert a hole at index.
- */
- if (!leaf->hdr.stale) {
- /*
- * lep is still good as the index leaf entry.
- */
- if (index < be16_to_cpu(leaf->hdr.count))
- memmove(lep + 1, lep,
- (be16_to_cpu(leaf->hdr.count) - index) * sizeof(*lep));
- /*
- * Record low and high logging indices for the leaf.
- */
- lfloglow = index;
- lfloghigh = be16_to_cpu(leaf->hdr.count);
- be16_add(&leaf->hdr.count, 1);
- }
- /*
- * There are stale entries.
- * We will use one of them for the new entry.
- * It's probably not at the right location, so we'll have to
- * shift some up or down first.
- */
- else {
- /*
- * If we didn't compact before, we need to find the nearest
- * stale entries before and after our insertion point.
- */
- if (compact == 0) {
- /*
- * Find the first stale entry before the insertion
- * point, if any.
- */
- for (lowstale = index - 1;
- lowstale >= 0 &&
- be32_to_cpu(leaf->ents[lowstale].address) !=
- XFS_DIR2_NULL_DATAPTR;
- lowstale--)
- continue;
- /*
- * Find the next stale entry at or after the insertion
- * point, if any. Stop if we go so far that the
- * lowstale entry would be better.
- */
- for (highstale = index;
- highstale < be16_to_cpu(leaf->hdr.count) &&
- be32_to_cpu(leaf->ents[highstale].address) !=
- XFS_DIR2_NULL_DATAPTR &&
- (lowstale < 0 ||
- index - lowstale - 1 >= highstale - index);
- highstale++)
- continue;
- }
- /*
- * If the low one is better, use it.
- */
- if (lowstale >= 0 &&
- (highstale == be16_to_cpu(leaf->hdr.count) ||
- index - lowstale - 1 < highstale - index)) {
- ASSERT(index - lowstale - 1 >= 0);
- ASSERT(be32_to_cpu(leaf->ents[lowstale].address) ==
- XFS_DIR2_NULL_DATAPTR);
- /*
- * Copy entries up to cover the stale entry
- * and make room for the new entry.
- */
- if (index - lowstale - 1 > 0)
- memmove(&leaf->ents[lowstale],
- &leaf->ents[lowstale + 1],
- (index - lowstale - 1) * sizeof(*lep));
- lep = &leaf->ents[index - 1];
- lfloglow = MIN(lowstale, lfloglow);
- lfloghigh = MAX(index - 1, lfloghigh);
- }
- /*
- * The high one is better, so use that one.
- */
- else {
- ASSERT(highstale - index >= 0);
- ASSERT(be32_to_cpu(leaf->ents[highstale].address) ==
- XFS_DIR2_NULL_DATAPTR);
- /*
- * Copy entries down to cover the stale entry
- * and make room for the new entry.
- */
- if (highstale - index > 0)
- memmove(&leaf->ents[index + 1],
- &leaf->ents[index],
- (highstale - index) * sizeof(*lep));
- lep = &leaf->ents[index];
- lfloglow = MIN(index, lfloglow);
- lfloghigh = MAX(highstale, lfloghigh);
- }
- be16_add(&leaf->hdr.stale, -1);
- }
- /*
- * Fill in the new leaf entry.
- */
- lep->hashval = cpu_to_be32(args->hashval);
- lep->address = cpu_to_be32(XFS_DIR2_DB_OFF_TO_DATAPTR(mp, use_block,
- be16_to_cpu(*tagp)));
- /*
- * Log the leaf fields and give up the buffers.
- */
- xfs_dir2_leaf_log_header(tp, lbp);
- xfs_dir2_leaf_log_ents(tp, lbp, lfloglow, lfloghigh);
- xfs_dir2_leaf_check(dp, lbp);
- xfs_da_buf_done(lbp);
- xfs_dir2_data_check(dp, dbp);
- xfs_da_buf_done(dbp);
- return 0;
-}
-
-#ifdef DEBUG
-/*
- * Check the internal consistency of a leaf1 block.
- * Pop an assert if something is wrong.
- */
-void
-xfs_dir2_leaf_check(
- xfs_inode_t *dp, /* incore directory inode */
- xfs_dabuf_t *bp) /* leaf's buffer */
-{
- int i; /* leaf index */
- xfs_dir2_leaf_t *leaf; /* leaf structure */
- xfs_dir2_leaf_tail_t *ltp; /* leaf tail pointer */
- xfs_mount_t *mp; /* filesystem mount point */
- int stale; /* count of stale leaves */
-
- leaf = bp->data;
- mp = dp->i_mount;
- ASSERT(be16_to_cpu(leaf->hdr.info.magic) == XFS_DIR2_LEAF1_MAGIC);
- /*
- * This value is not restrictive enough.
- * Should factor in the size of the bests table as well.
- * We can deduce a value for that from di_size.
- */
- ASSERT(be16_to_cpu(leaf->hdr.count) <= XFS_DIR2_MAX_LEAF_ENTS(mp));
- ltp = XFS_DIR2_LEAF_TAIL_P(mp, leaf);
- /*
- * Leaves and bests don't overlap.
- */
- ASSERT((char *)&leaf->ents[be16_to_cpu(leaf->hdr.count)] <=
- (char *)XFS_DIR2_LEAF_BESTS_P(ltp));
- /*
- * Check hash value order, count stale entries.
- */
- for (i = stale = 0; i < be16_to_cpu(leaf->hdr.count); i++) {
- if (i + 1 < be16_to_cpu(leaf->hdr.count))
- ASSERT(be32_to_cpu(leaf->ents[i].hashval) <=
- be32_to_cpu(leaf->ents[i + 1].hashval));
- if (be32_to_cpu(leaf->ents[i].address) == XFS_DIR2_NULL_DATAPTR)
- stale++;
- }
- ASSERT(be16_to_cpu(leaf->hdr.stale) == stale);
-}
-#endif /* DEBUG */
-
-/*
- * Compact out any stale entries in the leaf.
- * Log the header and changed leaf entries, if any.
- */
-void
-xfs_dir2_leaf_compact(
- xfs_da_args_t *args, /* operation arguments */
- xfs_dabuf_t *bp) /* leaf buffer */
-{
- int from; /* source leaf index */
- xfs_dir2_leaf_t *leaf; /* leaf structure */
- int loglow; /* first leaf entry to log */
- int to; /* target leaf index */
-
- leaf = bp->data;
- if (!leaf->hdr.stale) {
- return;
- }
- /*
- * Compress out the stale entries in place.
- */
- for (from = to = 0, loglow = -1; from < be16_to_cpu(leaf->hdr.count); from++) {
- if (be32_to_cpu(leaf->ents[from].address) == XFS_DIR2_NULL_DATAPTR)
- continue;
- /*
- * Only actually copy the entries that are different.
- */
- if (from > to) {
- if (loglow == -1)
- loglow = to;
- leaf->ents[to] = leaf->ents[from];
- }
- to++;
- }
- /*
- * Update and log the header, log the leaf entries.
- */
- ASSERT(be16_to_cpu(leaf->hdr.stale) == from - to);
- be16_add(&leaf->hdr.count, -(be16_to_cpu(leaf->hdr.stale)));
- leaf->hdr.stale = 0;
- xfs_dir2_leaf_log_header(args->trans, bp);
- if (loglow != -1)
- xfs_dir2_leaf_log_ents(args->trans, bp, loglow, to - 1);
-}
-
-/*
- * Compact the leaf entries, removing stale ones.
- * Leave one stale entry behind - the one closest to our
- * insertion index - and the caller will shift that one to our insertion
- * point later.
- * Return new insertion index, where the remaining stale entry is,
- * and leaf logging indices.
- */
-void
-xfs_dir2_leaf_compact_x1(
- xfs_dabuf_t *bp, /* leaf buffer */
- int *indexp, /* insertion index */
- int *lowstalep, /* out: stale entry before us */
- int *highstalep, /* out: stale entry after us */
- int *lowlogp, /* out: low log index */
- int *highlogp) /* out: high log index */
-{
- int from; /* source copy index */
- int highstale; /* stale entry at/after index */
- int index; /* insertion index */
- int keepstale; /* source index of kept stale */
- xfs_dir2_leaf_t *leaf; /* leaf structure */
- int lowstale; /* stale entry before index */
- int newindex=0; /* new insertion index */
- int to; /* destination copy index */
-
- leaf = bp->data;
- ASSERT(be16_to_cpu(leaf->hdr.stale) > 1);
- index = *indexp;
- /*
- * Find the first stale entry before our index, if any.
- */
- for (lowstale = index - 1;
- lowstale >= 0 &&
- be32_to_cpu(leaf->ents[lowstale].address) != XFS_DIR2_NULL_DATAPTR;
- lowstale--)
- continue;
- /*
- * Find the first stale entry at or after our index, if any.
- * Stop if the answer would be worse than lowstale.
- */
- for (highstale = index;
- highstale < be16_to_cpu(leaf->hdr.count) &&
- be32_to_cpu(leaf->ents[highstale].address) != XFS_DIR2_NULL_DATAPTR &&
- (lowstale < 0 || index - lowstale > highstale - index);
- highstale++)
- continue;
- /*
- * Pick the better of lowstale and highstale.
- */
- if (lowstale >= 0 &&
- (highstale == be16_to_cpu(leaf->hdr.count) ||
- index - lowstale <= highstale - index))
- keepstale = lowstale;
- else
- keepstale = highstale;
- /*
- * Copy the entries in place, removing all the stale entries
- * except keepstale.
- */
- for (from = to = 0; from < be16_to_cpu(leaf->hdr.count); from++) {
- /*
- * Notice the new value of index.
- */
- if (index == from)
- newindex = to;
- if (from != keepstale &&
- be32_to_cpu(leaf->ents[from].address) == XFS_DIR2_NULL_DATAPTR) {
- if (from == to)
- *lowlogp = to;
- continue;
- }
- /*
- * Record the new keepstale value for the insertion.
- */
- if (from == keepstale)
- lowstale = highstale = to;
- /*
- * Copy only the entries that have moved.
- */
- if (from > to)
- leaf->ents[to] = leaf->ents[from];
- to++;
- }
- ASSERT(from > to);
- /*
- * If the insertion point was past the last entry,
- * set the new insertion point accordingly.
- */
- if (index == from)
- newindex = to;
- *indexp = newindex;
- /*
- * Adjust the leaf header values.
- */
- be16_add(&leaf->hdr.count, -(from - to));
- leaf->hdr.stale = cpu_to_be16(1);
- /*
- * Remember the low/high stale value only in the "right"
- * direction.
- */
- if (lowstale >= newindex)
- lowstale = -1;
- else
- highstale = be16_to_cpu(leaf->hdr.count);
- *highlogp = be16_to_cpu(leaf->hdr.count) - 1;
- *lowstalep = lowstale;
- *highstalep = highstale;
-}
-
-/*
- * Getdents (readdir) for leaf and node directories.
- * This reads the data blocks only, so is the same for both forms.
- */
-int /* error */
-xfs_dir2_leaf_getdents(
- xfs_trans_t *tp, /* transaction pointer */
- xfs_inode_t *dp, /* incore directory inode */
- uio_t *uio, /* I/O control & vectors */
- int *eofp, /* out: reached end of dir */
- xfs_dirent_t *dbp, /* caller's buffer */
- xfs_dir2_put_t put) /* ABI formatting routine */
-{
- xfs_dabuf_t *bp; /* data block buffer */
- int byteoff; /* offset in current block */
- xfs_dir2_db_t curdb; /* db for current block */
- xfs_dir2_off_t curoff; /* current overall offset */
- xfs_dir2_data_t *data; /* data block structure */
- xfs_dir2_data_entry_t *dep; /* data entry */
- xfs_dir2_data_unused_t *dup; /* unused entry */
- int eof; /* reached end of directory */
- int error = 0; /* error return value */
- int i; /* temporary loop index */
- int j; /* temporary loop index */
- int length; /* temporary length value */
- xfs_bmbt_irec_t *map; /* map vector for blocks */
- xfs_extlen_t map_blocks; /* number of fsbs in map */
- xfs_dablk_t map_off; /* last mapped file offset */
- int map_size; /* total entries in *map */
- int map_valid; /* valid entries in *map */
- xfs_mount_t *mp; /* filesystem mount point */
- xfs_dir2_off_t newoff; /* new curoff after new blk */
- int nmap; /* mappings to ask xfs_bmapi */
- xfs_dir2_put_args_t *p; /* formatting arg bundle */
- char *ptr = NULL; /* pointer to current data */
- int ra_current; /* number of read-ahead blks */
- int ra_index; /* *map index for read-ahead */
- int ra_offset; /* map entry offset for ra */
- int ra_want; /* readahead count wanted */
-
- /*
- * If the offset is at or past the largest allowed value,
- * give up right away, return eof.
- */
- if (uio->uio_offset >= XFS_DIR2_MAX_DATAPTR) {
- *eofp = 1;
- return 0;
- }
- mp = dp->i_mount;
- /*
- * Setup formatting arguments.
- */
- p = kmem_alloc(sizeof(*p), KM_SLEEP);
- p->dbp = dbp;
- p->put = put;
- p->uio = uio;
- /*
- * Set up to bmap a number of blocks based on the caller's
- * buffer size, the directory block size, and the filesystem
- * block size.
- */
- map_size =
- howmany(uio->uio_resid + mp->m_dirblksize,
- mp->m_sb.sb_blocksize);
- map = kmem_alloc(map_size * sizeof(*map), KM_SLEEP);
- map_valid = ra_index = ra_offset = ra_current = map_blocks = 0;
- bp = NULL;
- eof = 1;
- /*
- * Inside the loop we keep the main offset value as a byte offset
- * in the directory file.
- */
- curoff = XFS_DIR2_DATAPTR_TO_BYTE(mp, uio->uio_offset);
- /*
- * Force this conversion through db so we truncate the offset
- * down to get the start of the data block.
- */
- map_off = XFS_DIR2_DB_TO_DA(mp, XFS_DIR2_BYTE_TO_DB(mp, curoff));
- /*
- * Loop over directory entries until we reach the end offset.
- * Get more blocks and readahead as necessary.
- */
- while (curoff < XFS_DIR2_LEAF_OFFSET) {
- /*
- * If we have no buffer, or we're off the end of the
- * current buffer, need to get another one.
- */
- if (!bp || ptr >= (char *)bp->data + mp->m_dirblksize) {
- /*
- * If we have a buffer, we need to release it and
- * take it out of the mapping.
- */
- if (bp) {
- xfs_da_brelse(tp, bp);
- bp = NULL;
- map_blocks -= mp->m_dirblkfsbs;
- /*
- * Loop to get rid of the extents for the
- * directory block.
- */
- for (i = mp->m_dirblkfsbs; i > 0; ) {
- j = MIN((int)map->br_blockcount, i);
- map->br_blockcount -= j;
- map->br_startblock += j;
- map->br_startoff += j;
- /*
- * If mapping is done, pitch it from
- * the table.
- */
- if (!map->br_blockcount && --map_valid)
- memmove(&map[0], &map[1],
- sizeof(map[0]) *
- map_valid);
- i -= j;
- }
- }
- /*
- * Recalculate the readahead blocks wanted.
- */
- ra_want = howmany(uio->uio_resid + mp->m_dirblksize,
- mp->m_sb.sb_blocksize) - 1;
- /*
- * If we don't have as many as we want, and we haven't
- * run out of data blocks, get some more mappings.
- */
- if (1 + ra_want > map_blocks &&
- map_off <
- XFS_DIR2_BYTE_TO_DA(mp, XFS_DIR2_LEAF_OFFSET)) {
- /*
- * Get more bmaps, fill in after the ones
- * we already have in the table.
- */
- nmap = map_size - map_valid;
- error = xfs_bmapi(tp, dp,
- map_off,
- XFS_DIR2_BYTE_TO_DA(mp,
- XFS_DIR2_LEAF_OFFSET) - map_off,
- XFS_BMAPI_METADATA, NULL, 0,
- &map[map_valid], &nmap, NULL, NULL);
- /*
- * Don't know if we should ignore this or
- * try to return an error.
- * The trouble with returning errors
- * is that readdir will just stop without
- * actually passing the error through.
- */
- if (error)
- break; /* XXX */
- /*
- * If we got all the mappings we asked for,
- * set the final map offset based on the
- * last bmap value received.
- * Otherwise, we've reached the end.
- */
- if (nmap == map_size - map_valid)
- map_off =
- map[map_valid + nmap - 1].br_startoff +
- map[map_valid + nmap - 1].br_blockcount;
- else
- map_off =
- XFS_DIR2_BYTE_TO_DA(mp,
- XFS_DIR2_LEAF_OFFSET);
- /*
- * Look for holes in the mapping, and
- * eliminate them. Count up the valid blocks.
- */
- for (i = map_valid; i < map_valid + nmap; ) {
- if (map[i].br_startblock ==
- HOLESTARTBLOCK) {
- nmap--;
- length = map_valid + nmap - i;
- if (length)
- memmove(&map[i],
- &map[i + 1],
- sizeof(map[i]) *
- length);
- } else {
- map_blocks +=
- map[i].br_blockcount;
- i++;
- }
- }
- map_valid += nmap;
- }
- /*
- * No valid mappings, so no more data blocks.
- */
- if (!map_valid) {
- curoff = XFS_DIR2_DA_TO_BYTE(mp, map_off);
- break;
- }
- /*
- * Read the directory block starting at the first
- * mapping.
- */
- curdb = XFS_DIR2_DA_TO_DB(mp, map->br_startoff);
- error = xfs_da_read_buf(tp, dp, map->br_startoff,
- map->br_blockcount >= mp->m_dirblkfsbs ?
- XFS_FSB_TO_DADDR(mp, map->br_startblock) :
- -1,
- &bp, XFS_DATA_FORK);
- /*
- * Should just skip over the data block instead
- * of giving up.
- */
- if (error)
- break; /* XXX */
- /*
- * Adjust the current amount of read-ahead: we just
- * read a block that was previously ra.
- */
- if (ra_current)
- ra_current -= mp->m_dirblkfsbs;
- /*
- * Do we need more readahead?
- */
- for (ra_index = ra_offset = i = 0;
- ra_want > ra_current && i < map_blocks;
- i += mp->m_dirblkfsbs) {
- ASSERT(ra_index < map_valid);
- /*
- * Read-ahead a contiguous directory block.
- */
- if (i > ra_current &&
- map[ra_index].br_blockcount >=
- mp->m_dirblkfsbs) {
- xfs_baread(mp->m_ddev_targp,
- XFS_FSB_TO_DADDR(mp,
- map[ra_index].br_startblock +
- ra_offset),
- (int)BTOBB(mp->m_dirblksize));
- ra_current = i;
- }
- /*
- * Read-ahead a non-contiguous directory block.
- * This doesn't use our mapping, but this
- * is a very rare case.
- */
- else if (i > ra_current) {
- (void)xfs_da_reada_buf(tp, dp,
- map[ra_index].br_startoff +
- ra_offset, XFS_DATA_FORK);
- ra_current = i;
- }
- /*
- * Advance offset through the mapping table.
- */
- for (j = 0; j < mp->m_dirblkfsbs; j++) {
- /*
- * The rest of this extent but not
- * more than a dir block.
- */
- length = MIN(mp->m_dirblkfsbs,
- (int)(map[ra_index].br_blockcount -
- ra_offset));
- j += length;
- ra_offset += length;
- /*
- * Advance to the next mapping if
- * this one is used up.
- */
- if (ra_offset ==
- map[ra_index].br_blockcount) {
- ra_offset = 0;
- ra_index++;
- }
- }
- }
- /*
- * Having done a read, we need to set a new offset.
- */
- newoff = XFS_DIR2_DB_OFF_TO_BYTE(mp, curdb, 0);
- /*
- * Start of the current block.
- */
- if (curoff < newoff)
- curoff = newoff;
- /*
- * Make sure we're in the right block.
- */
- else if (curoff > newoff)
- ASSERT(XFS_DIR2_BYTE_TO_DB(mp, curoff) ==
- curdb);
- data = bp->data;
- xfs_dir2_data_check(dp, bp);
- /*
- * Find our position in the block.
- */
- ptr = (char *)&data->u;
- byteoff = XFS_DIR2_BYTE_TO_OFF(mp, curoff);
- /*
- * Skip past the header.
- */
- if (byteoff == 0)
- curoff += (uint)sizeof(data->hdr);
- /*
- * Skip past entries until we reach our offset.
- */
- else {
- while ((char *)ptr - (char *)data < byteoff) {
- dup = (xfs_dir2_data_unused_t *)ptr;
-
- if (be16_to_cpu(dup->freetag)
- == XFS_DIR2_DATA_FREE_TAG) {
-
- length = be16_to_cpu(dup->length);
- ptr += length;
- continue;
- }
- dep = (xfs_dir2_data_entry_t *)ptr;
- length =
- XFS_DIR2_DATA_ENTSIZE(dep->namelen);
- ptr += length;
- }
- /*
- * Now set our real offset.
- */
- curoff =
- XFS_DIR2_DB_OFF_TO_BYTE(mp,
- XFS_DIR2_BYTE_TO_DB(mp, curoff),
- (char *)ptr - (char *)data);
- if (ptr >= (char *)data + mp->m_dirblksize) {
- continue;
- }
- }
- }
- /*
- * We have a pointer to an entry.
- * Is it a live one?
- */
- dup = (xfs_dir2_data_unused_t *)ptr;
- /*
- * No, it's unused, skip over it.
- */
- if (be16_to_cpu(dup->freetag) == XFS_DIR2_DATA_FREE_TAG) {
- length = be16_to_cpu(dup->length);
- ptr += length;
- curoff += length;
- continue;
- }
-
- /*
- * Copy the entry into the putargs, and try formatting it.
- */
- dep = (xfs_dir2_data_entry_t *)ptr;
-
- p->namelen = dep->namelen;
-
- length = XFS_DIR2_DATA_ENTSIZE(p->namelen);
-
- p->cook = XFS_DIR2_BYTE_TO_DATAPTR(mp, curoff + length);
-
- p->ino = INT_GET(dep->inumber, ARCH_CONVERT);
-#if XFS_BIG_INUMS
- p->ino += mp->m_inoadd;
-#endif
- p->name = (char *)dep->name;
-
- error = p->put(p);
-
- /*
- * Won't fit. Return to caller.
- */
- if (!p->done) {
- eof = 0;
- break;
- }
- /*
- * Advance to next entry in the block.
- */
- ptr += length;
- curoff += length;
- }
-
- /*
- * All done. Set output offset value to current offset.
- */
- *eofp = eof;
- if (curoff > XFS_DIR2_DATAPTR_TO_BYTE(mp, XFS_DIR2_MAX_DATAPTR))
- uio->uio_offset = XFS_DIR2_MAX_DATAPTR;
- else
- uio->uio_offset = XFS_DIR2_BYTE_TO_DATAPTR(mp, curoff);
- kmem_free(map, map_size * sizeof(*map));
- kmem_free(p, sizeof(*p));
- if (bp)
- xfs_da_brelse(tp, bp);
- return error;
-}
-
-/*
- * Initialize a new leaf block, leaf1 or leafn magic accepted.
- */
-int
-xfs_dir2_leaf_init(
- xfs_da_args_t *args, /* operation arguments */
- xfs_dir2_db_t bno, /* directory block number */
- xfs_dabuf_t **bpp, /* out: leaf buffer */
- int magic) /* magic number for block */
-{
- xfs_dabuf_t *bp; /* leaf buffer */
- xfs_inode_t *dp; /* incore directory inode */
- int error; /* error return code */
- xfs_dir2_leaf_t *leaf; /* leaf structure */
- xfs_dir2_leaf_tail_t *ltp; /* leaf tail structure */
- xfs_mount_t *mp; /* filesystem mount point */
- xfs_trans_t *tp; /* transaction pointer */
-
- dp = args->dp;
- ASSERT(dp != NULL);
- tp = args->trans;
- mp = dp->i_mount;
- ASSERT(bno >= XFS_DIR2_LEAF_FIRSTDB(mp) &&
- bno < XFS_DIR2_FREE_FIRSTDB(mp));
- /*
- * Get the buffer for the block.
- */
- error = xfs_da_get_buf(tp, dp, XFS_DIR2_DB_TO_DA(mp, bno), -1, &bp,
- XFS_DATA_FORK);
- if (error) {
- return error;
- }
- ASSERT(bp != NULL);
- leaf = bp->data;
- /*
- * Initialize the header.
- */
- leaf->hdr.info.magic = cpu_to_be16(magic);
- leaf->hdr.info.forw = 0;
- leaf->hdr.info.back = 0;
- leaf->hdr.count = 0;
- leaf->hdr.stale = 0;
- xfs_dir2_leaf_log_header(tp, bp);
- /*
- * If it's a leaf-format directory initialize the tail.
- * In this case our caller has the real bests table to copy into
- * the block.
- */
- if (magic == XFS_DIR2_LEAF1_MAGIC) {
- ltp = XFS_DIR2_LEAF_TAIL_P(mp, leaf);
- ltp->bestcount = 0;
- xfs_dir2_leaf_log_tail(tp, bp);
- }
- *bpp = bp;
- return 0;
-}
-
-/*
- * Log the bests entries indicated from a leaf1 block.
- */
-static void
-xfs_dir2_leaf_log_bests(
- xfs_trans_t *tp, /* transaction pointer */
- xfs_dabuf_t *bp, /* leaf buffer */
- int first, /* first entry to log */
- int last) /* last entry to log */
-{
- __be16 *firstb; /* pointer to first entry */
- __be16 *lastb; /* pointer to last entry */
- xfs_dir2_leaf_t *leaf; /* leaf structure */
- xfs_dir2_leaf_tail_t *ltp; /* leaf tail structure */
-
- leaf = bp->data;
- ASSERT(be16_to_cpu(leaf->hdr.info.magic) == XFS_DIR2_LEAF1_MAGIC);
- ltp = XFS_DIR2_LEAF_TAIL_P(tp->t_mountp, leaf);
- firstb = XFS_DIR2_LEAF_BESTS_P(ltp) + first;
- lastb = XFS_DIR2_LEAF_BESTS_P(ltp) + last;
- xfs_da_log_buf(tp, bp, (uint)((char *)firstb - (char *)leaf),
- (uint)((char *)lastb - (char *)leaf + sizeof(*lastb) - 1));
-}
-
-/*
- * Log the leaf entries indicated from a leaf1 or leafn block.
- */
-void
-xfs_dir2_leaf_log_ents(
- xfs_trans_t *tp, /* transaction pointer */
- xfs_dabuf_t *bp, /* leaf buffer */
- int first, /* first entry to log */
- int last) /* last entry to log */
-{
- xfs_dir2_leaf_entry_t *firstlep; /* pointer to first entry */
- xfs_dir2_leaf_entry_t *lastlep; /* pointer to last entry */
- xfs_dir2_leaf_t *leaf; /* leaf structure */
-
- leaf = bp->data;
- ASSERT(be16_to_cpu(leaf->hdr.info.magic) == XFS_DIR2_LEAF1_MAGIC ||
- be16_to_cpu(leaf->hdr.info.magic) == XFS_DIR2_LEAFN_MAGIC);
- firstlep = &leaf->ents[first];
- lastlep = &leaf->ents[last];
- xfs_da_log_buf(tp, bp, (uint)((char *)firstlep - (char *)leaf),
- (uint)((char *)lastlep - (char *)leaf + sizeof(*lastlep) - 1));
-}
-
-/*
- * Log the header of the leaf1 or leafn block.
- */
-void
-xfs_dir2_leaf_log_header(
- xfs_trans_t *tp, /* transaction pointer */
- xfs_dabuf_t *bp) /* leaf buffer */
-{
- xfs_dir2_leaf_t *leaf; /* leaf structure */
-
- leaf = bp->data;
- ASSERT(be16_to_cpu(leaf->hdr.info.magic) == XFS_DIR2_LEAF1_MAGIC ||
- be16_to_cpu(leaf->hdr.info.magic) == XFS_DIR2_LEAFN_MAGIC);
- xfs_da_log_buf(tp, bp, (uint)((char *)&leaf->hdr - (char *)leaf),
- (uint)(sizeof(leaf->hdr) - 1));
-}
-
-/*
- * Log the tail of the leaf1 block.
- */
-STATIC void
-xfs_dir2_leaf_log_tail(
- xfs_trans_t *tp, /* transaction pointer */
- xfs_dabuf_t *bp) /* leaf buffer */
-{
- xfs_dir2_leaf_t *leaf; /* leaf structure */
- xfs_dir2_leaf_tail_t *ltp; /* leaf tail structure */
- xfs_mount_t *mp; /* filesystem mount point */
-
- mp = tp->t_mountp;
- leaf = bp->data;
- ASSERT(be16_to_cpu(leaf->hdr.info.magic) == XFS_DIR2_LEAF1_MAGIC);
- ltp = XFS_DIR2_LEAF_TAIL_P(mp, leaf);
- xfs_da_log_buf(tp, bp, (uint)((char *)ltp - (char *)leaf),
- (uint)(mp->m_dirblksize - 1));
-}
-
-/*
- * Look up the entry referred to by args in the leaf format directory.
- * Most of the work is done by the xfs_dir2_leaf_lookup_int routine which
- * is also used by the node-format code.
- */
-int
-xfs_dir2_leaf_lookup(
- xfs_da_args_t *args) /* operation arguments */
-{
- xfs_dabuf_t *dbp; /* data block buffer */
- xfs_dir2_data_entry_t *dep; /* data block entry */
- xfs_inode_t *dp; /* incore directory inode */
- int error; /* error return code */
- int index; /* found entry index */
- xfs_dabuf_t *lbp; /* leaf buffer */
- xfs_dir2_leaf_t *leaf; /* leaf structure */
- xfs_dir2_leaf_entry_t *lep; /* leaf entry */
- xfs_trans_t *tp; /* transaction pointer */
-
- xfs_dir2_trace_args("leaf_lookup", args);
- /*
- * Look up name in the leaf block, returning both buffers and index.
- */
- if ((error = xfs_dir2_leaf_lookup_int(args, &lbp, &index, &dbp))) {
- return error;
- }
- tp = args->trans;
- dp = args->dp;
- xfs_dir2_leaf_check(dp, lbp);
- leaf = lbp->data;
- /*
- * Get to the leaf entry and contained data entry address.
- */
- lep = &leaf->ents[index];
- /*
- * Point to the data entry.
- */
- dep = (xfs_dir2_data_entry_t *)
- ((char *)dbp->data +
- XFS_DIR2_DATAPTR_TO_OFF(dp->i_mount, be32_to_cpu(lep->address)));
- /*
- * Return the found inode number.
- */
- args->inumber = INT_GET(dep->inumber, ARCH_CONVERT);
- xfs_da_brelse(tp, dbp);
- xfs_da_brelse(tp, lbp);
- return XFS_ERROR(EEXIST);
-}
-
-/*
- * Look up name/hash in the leaf block.
- * Fill in indexp with the found index, and dbpp with the data buffer.
- * If not found dbpp will be NULL, and ENOENT comes back.
- * lbpp will always be filled in with the leaf buffer unless there's an error.
- */
-static int /* error */
-xfs_dir2_leaf_lookup_int(
- xfs_da_args_t *args, /* operation arguments */
- xfs_dabuf_t **lbpp, /* out: leaf buffer */
- int *indexp, /* out: index in leaf block */
- xfs_dabuf_t **dbpp) /* out: data buffer */
-{
- xfs_dir2_db_t curdb; /* current data block number */
- xfs_dabuf_t *dbp; /* data buffer */
- xfs_dir2_data_entry_t *dep; /* data entry */
- xfs_inode_t *dp; /* incore directory inode */
- int error; /* error return code */
- int index; /* index in leaf block */
- xfs_dabuf_t *lbp; /* leaf buffer */
- xfs_dir2_leaf_entry_t *lep; /* leaf entry */
- xfs_dir2_leaf_t *leaf; /* leaf structure */
- xfs_mount_t *mp; /* filesystem mount point */
- xfs_dir2_db_t newdb; /* new data block number */
- xfs_trans_t *tp; /* transaction pointer */
-
- dp = args->dp;
- tp = args->trans;
- mp = dp->i_mount;
- /*
- * Read the leaf block into the buffer.
- */
- if ((error =
- xfs_da_read_buf(tp, dp, mp->m_dirleafblk, -1, &lbp,
- XFS_DATA_FORK))) {
- return error;
- }
- *lbpp = lbp;
- leaf = lbp->data;
- xfs_dir2_leaf_check(dp, lbp);
- /*
- * Look for the first leaf entry with our hash value.
- */
- index = xfs_dir2_leaf_search_hash(args, lbp);
- /*
- * Loop over all the entries with the right hash value
- * looking to match the name.
- */
- for (lep = &leaf->ents[index], dbp = NULL, curdb = -1;
- index < be16_to_cpu(leaf->hdr.count) && be32_to_cpu(lep->hashval) == args->hashval;
- lep++, index++) {
- /*
- * Skip over stale leaf entries.
- */
- if (be32_to_cpu(lep->address) == XFS_DIR2_NULL_DATAPTR)
- continue;
- /*
- * Get the new data block number.
- */
- newdb = XFS_DIR2_DATAPTR_TO_DB(mp, be32_to_cpu(lep->address));
- /*
- * If it's not the same as the old data block number,
- * need to pitch the old one and read the new one.
- */
- if (newdb != curdb) {
- if (dbp)
- xfs_da_brelse(tp, dbp);
- if ((error =
- xfs_da_read_buf(tp, dp,
- XFS_DIR2_DB_TO_DA(mp, newdb), -1, &dbp,
- XFS_DATA_FORK))) {
- xfs_da_brelse(tp, lbp);
- return error;
- }
- xfs_dir2_data_check(dp, dbp);
- curdb = newdb;
- }
- /*
- * Point to the data entry.
- */
- dep = (xfs_dir2_data_entry_t *)
- ((char *)dbp->data +
- XFS_DIR2_DATAPTR_TO_OFF(mp, be32_to_cpu(lep->address)));
- /*
- * If it matches then return it.
- */
- if (dep->namelen == args->namelen &&
- dep->name[0] == args->name[0] &&
- memcmp(dep->name, args->name, args->namelen) == 0) {
- *dbpp = dbp;
- *indexp = index;
- return 0;
- }
- }
- /*
- * No match found, return ENOENT.
- */
- ASSERT(args->oknoent);
- if (dbp)
- xfs_da_brelse(tp, dbp);
- xfs_da_brelse(tp, lbp);
- return XFS_ERROR(ENOENT);
-}
-
-/*
- * Remove an entry from a leaf format directory.
- */
-int /* error */
-xfs_dir2_leaf_removename(
- xfs_da_args_t *args) /* operation arguments */
-{
- __be16 *bestsp; /* leaf block best freespace */
- xfs_dir2_data_t *data; /* data block structure */
- xfs_dir2_db_t db; /* data block number */
- xfs_dabuf_t *dbp; /* data block buffer */
- xfs_dir2_data_entry_t *dep; /* data entry structure */
- xfs_inode_t *dp; /* incore directory inode */
- int error; /* error return code */
- xfs_dir2_db_t i; /* temporary data block # */
- int index; /* index into leaf entries */
- xfs_dabuf_t *lbp; /* leaf buffer */
- xfs_dir2_leaf_t *leaf; /* leaf structure */
- xfs_dir2_leaf_entry_t *lep; /* leaf entry */
- xfs_dir2_leaf_tail_t *ltp; /* leaf tail structure */
- xfs_mount_t *mp; /* filesystem mount point */
- int needlog; /* need to log data header */
- int needscan; /* need to rescan data frees */
- xfs_dir2_data_off_t oldbest; /* old value of best free */
- xfs_trans_t *tp; /* transaction pointer */
-
- xfs_dir2_trace_args("leaf_removename", args);
- /*
- * Lookup the leaf entry, get the leaf and data blocks read in.
- */
- if ((error = xfs_dir2_leaf_lookup_int(args, &lbp, &index, &dbp))) {
- return error;
- }
- dp = args->dp;
- tp = args->trans;
- mp = dp->i_mount;
- leaf = lbp->data;
- data = dbp->data;
- xfs_dir2_data_check(dp, dbp);
- /*
- * Point to the leaf entry, use that to point to the data entry.
- */
- lep = &leaf->ents[index];
- db = XFS_DIR2_DATAPTR_TO_DB(mp, be32_to_cpu(lep->address));
- dep = (xfs_dir2_data_entry_t *)
- ((char *)data + XFS_DIR2_DATAPTR_TO_OFF(mp, be32_to_cpu(lep->address)));
- needscan = needlog = 0;
- oldbest = be16_to_cpu(data->hdr.bestfree[0].length);
- ltp = XFS_DIR2_LEAF_TAIL_P(mp, leaf);
- bestsp = XFS_DIR2_LEAF_BESTS_P(ltp);
- ASSERT(be16_to_cpu(bestsp[db]) == oldbest);
- /*
- * Mark the former data entry unused.
- */
- xfs_dir2_data_make_free(tp, dbp,
- (xfs_dir2_data_aoff_t)((char *)dep - (char *)data),
- XFS_DIR2_DATA_ENTSIZE(dep->namelen), &needlog, &needscan);
- /*
- * We just mark the leaf entry stale by putting a null in it.
- */
- be16_add(&leaf->hdr.stale, 1);
- xfs_dir2_leaf_log_header(tp, lbp);
- lep->address = cpu_to_be32(XFS_DIR2_NULL_DATAPTR);
- xfs_dir2_leaf_log_ents(tp, lbp, index, index);
- /*
- * Scan the freespace in the data block again if necessary,
- * log the data block header if necessary.
- */
- if (needscan)
- xfs_dir2_data_freescan(mp, data, &needlog, NULL);
- if (needlog)
- xfs_dir2_data_log_header(tp, dbp);
- /*
- * If the longest freespace in the data block has changed,
- * put the new value in the bests table and log that.
- */
- if (be16_to_cpu(data->hdr.bestfree[0].length) != oldbest) {
- bestsp[db] = data->hdr.bestfree[0].length;
- xfs_dir2_leaf_log_bests(tp, lbp, db, db);
- }
- xfs_dir2_data_check(dp, dbp);
- /*
- * If the data block is now empty then get rid of the data block.
- */
- if (be16_to_cpu(data->hdr.bestfree[0].length) ==
- mp->m_dirblksize - (uint)sizeof(data->hdr)) {
- ASSERT(db != mp->m_dirdatablk);
- if ((error = xfs_dir2_shrink_inode(args, db, dbp))) {
- /*
- * Nope, can't get rid of it because it caused
- * allocation of a bmap btree block to do so.
- * Just go on, returning success, leaving the
- * empty block in place.
- */
- if (error == ENOSPC && args->total == 0) {
- xfs_da_buf_done(dbp);
- error = 0;
- }
- xfs_dir2_leaf_check(dp, lbp);
- xfs_da_buf_done(lbp);
- return error;
- }
- dbp = NULL;
- /*
- * If this is the last data block then compact the
- * bests table by getting rid of entries.
- */
- if (db == be32_to_cpu(ltp->bestcount) - 1) {
- /*
- * Look for the last active entry (i).
- */
- for (i = db - 1; i > 0; i--) {
- if (be16_to_cpu(bestsp[i]) != NULLDATAOFF)
- break;
- }
- /*
- * Copy the table down so inactive entries at the
- * end are removed.
- */
- memmove(&bestsp[db - i], bestsp,
- (be32_to_cpu(ltp->bestcount) - (db - i)) * sizeof(*bestsp));
- be32_add(&ltp->bestcount, -(db - i));
- xfs_dir2_leaf_log_tail(tp, lbp);
- xfs_dir2_leaf_log_bests(tp, lbp, 0, be32_to_cpu(ltp->bestcount) - 1);
- } else
- bestsp[db] = cpu_to_be16(NULLDATAOFF);
- }
- /*
- * If the data block was not the first one, drop it.
- */
- else if (db != mp->m_dirdatablk && dbp != NULL) {
- xfs_da_buf_done(dbp);
- dbp = NULL;
- }
- xfs_dir2_leaf_check(dp, lbp);
- /*
- * See if we can convert to block form.
- */
- return xfs_dir2_leaf_to_block(args, lbp, dbp);
-}
-
-/*
- * Replace the inode number in a leaf format directory entry.
- */
-int /* error */
-xfs_dir2_leaf_replace(
- xfs_da_args_t *args) /* operation arguments */
-{
- xfs_dabuf_t *dbp; /* data block buffer */
- xfs_dir2_data_entry_t *dep; /* data block entry */
- xfs_inode_t *dp; /* incore directory inode */
- int error; /* error return code */
- int index; /* index of leaf entry */
- xfs_dabuf_t *lbp; /* leaf buffer */
- xfs_dir2_leaf_t *leaf; /* leaf structure */
- xfs_dir2_leaf_entry_t *lep; /* leaf entry */
- xfs_trans_t *tp; /* transaction pointer */
-
- xfs_dir2_trace_args("leaf_replace", args);
- /*
- * Look up the entry.
- */
- if ((error = xfs_dir2_leaf_lookup_int(args, &lbp, &index, &dbp))) {
- return error;
- }
- dp = args->dp;
- leaf = lbp->data;
- /*
- * Point to the leaf entry, get data address from it.
- */
- lep = &leaf->ents[index];
- /*
- * Point to the data entry.
- */
- dep = (xfs_dir2_data_entry_t *)
- ((char *)dbp->data +
- XFS_DIR2_DATAPTR_TO_OFF(dp->i_mount, be32_to_cpu(lep->address)));
- ASSERT(args->inumber != INT_GET(dep->inumber, ARCH_CONVERT));
- /*
- * Put the new inode number in, log it.
- */
- INT_SET(dep->inumber, ARCH_CONVERT, args->inumber);
- tp = args->trans;
- xfs_dir2_data_log_entry(tp, dbp, dep);
- xfs_da_buf_done(dbp);
- xfs_dir2_leaf_check(dp, lbp);
- xfs_da_brelse(tp, lbp);
- return 0;
-}
-
-/*
- * Return index in the leaf block (lbp) which is either the first
- * one with this hash value, or if there are none, the insert point
- * for that hash value.
- */
-int /* index value */
-xfs_dir2_leaf_search_hash(
- xfs_da_args_t *args, /* operation arguments */
- xfs_dabuf_t *lbp) /* leaf buffer */
-{
- xfs_dahash_t hash=0; /* hash from this entry */
- xfs_dahash_t hashwant; /* hash value looking for */
- int high; /* high leaf index */
- int low; /* low leaf index */
- xfs_dir2_leaf_t *leaf; /* leaf structure */
- xfs_dir2_leaf_entry_t *lep; /* leaf entry */
- int mid=0; /* current leaf index */
-
- leaf = lbp->data;
-#ifndef __KERNEL__
- if (!leaf->hdr.count)
- return 0;
-#endif
- /*
- * Note, the table cannot be empty, so we have to go through the loop.
- * Binary search the leaf entries looking for our hash value.
- */
- for (lep = leaf->ents, low = 0, high = be16_to_cpu(leaf->hdr.count) - 1,
- hashwant = args->hashval;
- low <= high; ) {
- mid = (low + high) >> 1;
- if ((hash = be32_to_cpu(lep[mid].hashval)) == hashwant)
- break;
- if (hash < hashwant)
- low = mid + 1;
- else
- high = mid - 1;
- }
- /*
- * Found one, back up through all the equal hash values.
- */
- if (hash == hashwant) {
- while (mid > 0 && be32_to_cpu(lep[mid - 1].hashval) == hashwant) {
- mid--;
- }
- }
- /*
- * Need to point to an entry higher than ours.
- */
- else if (hash < hashwant)
- mid++;
- return mid;
-}
-
-/*
- * Trim off a trailing data block. We know it's empty since the leaf
- * freespace table says so.
- */
-int /* error */
-xfs_dir2_leaf_trim_data(
- xfs_da_args_t *args, /* operation arguments */
- xfs_dabuf_t *lbp, /* leaf buffer */
- xfs_dir2_db_t db) /* data block number */
-{
- __be16 *bestsp; /* leaf bests table */
-#ifdef DEBUG
- xfs_dir2_data_t *data; /* data block structure */
-#endif
- xfs_dabuf_t *dbp; /* data block buffer */
- xfs_inode_t *dp; /* incore directory inode */
- int error; /* error return value */
- xfs_dir2_leaf_t *leaf; /* leaf structure */
- xfs_dir2_leaf_tail_t *ltp; /* leaf tail structure */
- xfs_mount_t *mp; /* filesystem mount point */
- xfs_trans_t *tp; /* transaction pointer */
-
- dp = args->dp;
- mp = dp->i_mount;
- tp = args->trans;
- /*
- * Read the offending data block. We need its buffer.
- */
- if ((error = xfs_da_read_buf(tp, dp, XFS_DIR2_DB_TO_DA(mp, db), -1, &dbp,
- XFS_DATA_FORK))) {
- return error;
- }
-#ifdef DEBUG
- data = dbp->data;
- ASSERT(be32_to_cpu(data->hdr.magic) == XFS_DIR2_DATA_MAGIC);
-#endif
- /* this seems to be an error
- * data is only valid if DEBUG is defined?
- * RMC 09/08/1999
- */
-
- leaf = lbp->data;
- ltp = XFS_DIR2_LEAF_TAIL_P(mp, leaf);
- ASSERT(be16_to_cpu(data->hdr.bestfree[0].length) ==
- mp->m_dirblksize - (uint)sizeof(data->hdr));
- ASSERT(db == be32_to_cpu(ltp->bestcount) - 1);
- /*
- * Get rid of the data block.
- */
- if ((error = xfs_dir2_shrink_inode(args, db, dbp))) {
- ASSERT(error != ENOSPC);
- xfs_da_brelse(tp, dbp);
- return error;
- }
- /*
- * Eliminate the last bests entry from the table.
- */
- bestsp = XFS_DIR2_LEAF_BESTS_P(ltp);
- be32_add(&ltp->bestcount, -1);
- memmove(&bestsp[1], &bestsp[0], be32_to_cpu(ltp->bestcount) * sizeof(*bestsp));
- xfs_dir2_leaf_log_tail(tp, lbp);
- xfs_dir2_leaf_log_bests(tp, lbp, 0, be32_to_cpu(ltp->bestcount) - 1);
- return 0;
-}
-
-/*
- * Convert node form directory to leaf form directory.
- * The root of the node form dir needs to already be a LEAFN block.
- * Just return if we can't do anything.
- */
-int /* error */
-xfs_dir2_node_to_leaf(
- xfs_da_state_t *state) /* directory operation state */
-{
- xfs_da_args_t *args; /* operation arguments */
- xfs_inode_t *dp; /* incore directory inode */
- int error; /* error return code */
- xfs_dabuf_t *fbp; /* buffer for freespace block */
- xfs_fileoff_t fo; /* freespace file offset */
- xfs_dir2_free_t *free; /* freespace structure */
- xfs_dabuf_t *lbp; /* buffer for leaf block */
- xfs_dir2_leaf_tail_t *ltp; /* tail of leaf structure */
- xfs_dir2_leaf_t *leaf; /* leaf structure */
- xfs_mount_t *mp; /* filesystem mount point */
- int rval; /* successful free trim? */
- xfs_trans_t *tp; /* transaction pointer */
-
- /*
- * There's more than a leaf level in the btree, so there must
- * be multiple leafn blocks. Give up.
- */
- if (state->path.active > 1)
- return 0;
- args = state->args;
- xfs_dir2_trace_args("node_to_leaf", args);
- mp = state->mp;
- dp = args->dp;
- tp = args->trans;
- /*
- * Get the last offset in the file.
- */
- if ((error = xfs_bmap_last_offset(tp, dp, &fo, XFS_DATA_FORK))) {
- return error;
- }
- fo -= mp->m_dirblkfsbs;
- /*
- * If there are freespace blocks other than the first one,
- * take this opportunity to remove trailing empty freespace blocks
- * that may have been left behind during no-space-reservation
- * operations.
- */
- while (fo > mp->m_dirfreeblk) {
- if ((error = xfs_dir2_node_trim_free(args, fo, &rval))) {
- return error;
- }
- if (rval)
- fo -= mp->m_dirblkfsbs;
- else
- return 0;
- }
- /*
- * Now find the block just before the freespace block.
- */
- if ((error = xfs_bmap_last_before(tp, dp, &fo, XFS_DATA_FORK))) {
- return error;
- }
- /*
- * If it's not the single leaf block, give up.
- */
- if (XFS_FSB_TO_B(mp, fo) > XFS_DIR2_LEAF_OFFSET + mp->m_dirblksize)
- return 0;
- lbp = state->path.blk[0].bp;
- leaf = lbp->data;
- ASSERT(be16_to_cpu(leaf->hdr.info.magic) == XFS_DIR2_LEAFN_MAGIC);
- /*
- * Read the freespace block.
- */
- if ((error = xfs_da_read_buf(tp, dp, mp->m_dirfreeblk, -1, &fbp,
- XFS_DATA_FORK))) {
- return error;
- }
- free = fbp->data;
- ASSERT(be32_to_cpu(free->hdr.magic) == XFS_DIR2_FREE_MAGIC);
- ASSERT(!free->hdr.firstdb);
- /*
- * Now see if the leafn and free data will fit in a leaf1.
- * If not, release the buffer and give up.
- */
- if ((uint)sizeof(leaf->hdr) +
- (be16_to_cpu(leaf->hdr.count) - be16_to_cpu(leaf->hdr.stale)) * (uint)sizeof(leaf->ents[0]) +
- be32_to_cpu(free->hdr.nvalid) * (uint)sizeof(leaf->bests[0]) +
- (uint)sizeof(leaf->tail) >
- mp->m_dirblksize) {
- xfs_da_brelse(tp, fbp);
- return 0;
- }
- /*
- * If the leaf has any stale entries in it, compress them out.
- * The compact routine will log the header.
- */
- if (be16_to_cpu(leaf->hdr.stale))
- xfs_dir2_leaf_compact(args, lbp);
- else
- xfs_dir2_leaf_log_header(tp, lbp);
- leaf->hdr.info.magic = cpu_to_be16(XFS_DIR2_LEAF1_MAGIC);
- /*
- * Set up the leaf tail from the freespace block.
- */
- ltp = XFS_DIR2_LEAF_TAIL_P(mp, leaf);
- ltp->bestcount = free->hdr.nvalid;
- /*
- * Set up the leaf bests table.
- */
- memcpy(XFS_DIR2_LEAF_BESTS_P(ltp), free->bests,
- be32_to_cpu(ltp->bestcount) * sizeof(leaf->bests[0]));
- xfs_dir2_leaf_log_bests(tp, lbp, 0, be32_to_cpu(ltp->bestcount) - 1);
- xfs_dir2_leaf_log_tail(tp, lbp);
- xfs_dir2_leaf_check(dp, lbp);
- /*
- * Get rid of the freespace block.
- */
- error = xfs_dir2_shrink_inode(args, XFS_DIR2_FREE_FIRSTDB(mp), fbp);
- if (error) {
- /*
- * This can't fail here because it can only happen when
- * punching out the middle of an extent, and this is an
- * isolated block.
- */
- ASSERT(error != ENOSPC);
- return error;
- }
- fbp = NULL;
- /*
- * Now see if we can convert the single-leaf directory
- * down to a block form directory.
- * This routine always kills the dabuf for the leaf, so
- * eliminate it from the path.
- */
- error = xfs_dir2_leaf_to_block(args, lbp, NULL);
- state->path.blk[0].bp = NULL;
- return error;
-}
diff --git a/sys/gnu/fs/xfs/xfs_dir2_leaf.h b/sys/gnu/fs/xfs/xfs_dir2_leaf.h
deleted file mode 100644
index f57ca11..0000000
--- a/sys/gnu/fs/xfs/xfs_dir2_leaf.h
+++ /dev/null
@@ -1,270 +0,0 @@
-/*
- * Copyright (c) 2000-2001,2005 Silicon Graphics, Inc.
- * All Rights Reserved.
- *
- * 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.
- *
- * This program is distributed in the hope that it would 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 the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- */
-#ifndef __XFS_DIR2_LEAF_H__
-#define __XFS_DIR2_LEAF_H__
-
-struct uio;
-struct xfs_dabuf;
-struct xfs_da_args;
-struct xfs_inode;
-struct xfs_mount;
-struct xfs_trans;
-
-/*
- * Offset of the leaf/node space. First block in this space
- * is the btree root.
- */
-#define XFS_DIR2_LEAF_SPACE 1
-#define XFS_DIR2_LEAF_OFFSET (XFS_DIR2_LEAF_SPACE * XFS_DIR2_SPACE_SIZE)
-#define XFS_DIR2_LEAF_FIRSTDB(mp) \
- XFS_DIR2_BYTE_TO_DB(mp, XFS_DIR2_LEAF_OFFSET)
-
-/*
- * Offset in data space of a data entry.
- */
-typedef __uint32_t xfs_dir2_dataptr_t;
-#define XFS_DIR2_MAX_DATAPTR ((xfs_dir2_dataptr_t)0xffffffff)
-#define XFS_DIR2_NULL_DATAPTR ((xfs_dir2_dataptr_t)0)
-
-/*
- * Leaf block header.
- */
-typedef struct xfs_dir2_leaf_hdr {
- xfs_da_blkinfo_t info; /* header for da routines */
- __be16 count; /* count of entries */
- __be16 stale; /* count of stale entries */
-} xfs_dir2_leaf_hdr_t;
-
-/*
- * Leaf block entry.
- */
-typedef struct xfs_dir2_leaf_entry {
- __be32 hashval; /* hash value of name */
- __be32 address; /* address of data entry */
-} xfs_dir2_leaf_entry_t;
-
-/*
- * Leaf block tail.
- */
-typedef struct xfs_dir2_leaf_tail {
- __be32 bestcount;
-} xfs_dir2_leaf_tail_t;
-
-/*
- * Leaf block.
- * bests and tail are at the end of the block for single-leaf only
- * (magic = XFS_DIR2_LEAF1_MAGIC not XFS_DIR2_LEAFN_MAGIC).
- */
-typedef struct xfs_dir2_leaf {
- xfs_dir2_leaf_hdr_t hdr; /* leaf header */
- xfs_dir2_leaf_entry_t ents[1]; /* entries */
- /* ... */
- xfs_dir2_data_off_t bests[1]; /* best free counts */
- xfs_dir2_leaf_tail_t tail; /* leaf tail */
-} xfs_dir2_leaf_t;
-
-/*
- * DB blocks here are logical directory block numbers, not filesystem blocks.
- */
-
-#define XFS_DIR2_MAX_LEAF_ENTS(mp) xfs_dir2_max_leaf_ents(mp)
-static inline int xfs_dir2_max_leaf_ents(struct xfs_mount *mp)
-{
- return (int)(((mp)->m_dirblksize - (uint)sizeof(xfs_dir2_leaf_hdr_t)) /
- (uint)sizeof(xfs_dir2_leaf_entry_t));
-}
-
-/*
- * Get address of the bestcount field in the single-leaf block.
- */
-#define XFS_DIR2_LEAF_TAIL_P(mp,lp) xfs_dir2_leaf_tail_p(mp, lp)
-static inline xfs_dir2_leaf_tail_t *
-xfs_dir2_leaf_tail_p(struct xfs_mount *mp, xfs_dir2_leaf_t *lp)
-{
- return (xfs_dir2_leaf_tail_t *)
- ((char *)(lp) + (mp)->m_dirblksize -
- (uint)sizeof(xfs_dir2_leaf_tail_t));
-}
-
-/*
- * Get address of the bests array in the single-leaf block.
- */
-#define XFS_DIR2_LEAF_BESTS_P(ltp) xfs_dir2_leaf_bests_p(ltp)
-static inline __be16 *
-xfs_dir2_leaf_bests_p(xfs_dir2_leaf_tail_t *ltp)
-{
- return (__be16 *)ltp - be32_to_cpu(ltp->bestcount);
-}
-
-/*
- * Convert dataptr to byte in file space
- */
-#define XFS_DIR2_DATAPTR_TO_BYTE(mp,dp) xfs_dir2_dataptr_to_byte(mp, dp)
-static inline xfs_dir2_off_t
-xfs_dir2_dataptr_to_byte(struct xfs_mount *mp, xfs_dir2_dataptr_t dp)
-{
- return (xfs_dir2_off_t)(dp) << XFS_DIR2_DATA_ALIGN_LOG;
-}
-
-/*
- * Convert byte in file space to dataptr. It had better be aligned.
- */
-#define XFS_DIR2_BYTE_TO_DATAPTR(mp,by) xfs_dir2_byte_to_dataptr(mp,by)
-static inline xfs_dir2_dataptr_t
-xfs_dir2_byte_to_dataptr(struct xfs_mount *mp, xfs_dir2_off_t by)
-{
- return (xfs_dir2_dataptr_t)((by) >> XFS_DIR2_DATA_ALIGN_LOG);
-}
-
-/*
- * Convert byte in space to (DB) block
- */
-#define XFS_DIR2_BYTE_TO_DB(mp,by) xfs_dir2_byte_to_db(mp, by)
-static inline xfs_dir2_db_t
-xfs_dir2_byte_to_db(struct xfs_mount *mp, xfs_dir2_off_t by)
-{
- return (xfs_dir2_db_t)((by) >> \
- ((mp)->m_sb.sb_blocklog + (mp)->m_sb.sb_dirblklog));
-}
-
-/*
- * Convert dataptr to a block number
- */
-#define XFS_DIR2_DATAPTR_TO_DB(mp,dp) xfs_dir2_dataptr_to_db(mp, dp)
-static inline xfs_dir2_db_t
-xfs_dir2_dataptr_to_db(struct xfs_mount *mp, xfs_dir2_dataptr_t dp)
-{
- return XFS_DIR2_BYTE_TO_DB(mp, XFS_DIR2_DATAPTR_TO_BYTE(mp, dp));
-}
-
-/*
- * Convert byte in space to offset in a block
- */
-#define XFS_DIR2_BYTE_TO_OFF(mp,by) xfs_dir2_byte_to_off(mp, by)
-static inline xfs_dir2_data_aoff_t
-xfs_dir2_byte_to_off(struct xfs_mount *mp, xfs_dir2_off_t by)
-{
- return (xfs_dir2_data_aoff_t)((by) & \
- ((1 << ((mp)->m_sb.sb_blocklog + (mp)->m_sb.sb_dirblklog)) - 1));
-}
-
-/*
- * Convert dataptr to a byte offset in a block
- */
-#define XFS_DIR2_DATAPTR_TO_OFF(mp,dp) xfs_dir2_dataptr_to_off(mp, dp)
-static inline xfs_dir2_data_aoff_t
-xfs_dir2_dataptr_to_off(struct xfs_mount *mp, xfs_dir2_dataptr_t dp)
-{
- return XFS_DIR2_BYTE_TO_OFF(mp, XFS_DIR2_DATAPTR_TO_BYTE(mp, dp));
-}
-
-/*
- * Convert block and offset to byte in space
- */
-#define XFS_DIR2_DB_OFF_TO_BYTE(mp,db,o) \
- xfs_dir2_db_off_to_byte(mp, db, o)
-static inline xfs_dir2_off_t
-xfs_dir2_db_off_to_byte(struct xfs_mount *mp, xfs_dir2_db_t db,
- xfs_dir2_data_aoff_t o)
-{
- return ((xfs_dir2_off_t)(db) << \
- ((mp)->m_sb.sb_blocklog + (mp)->m_sb.sb_dirblklog)) + (o);
-}
-
-/*
- * Convert block (DB) to block (dablk)
- */
-#define XFS_DIR2_DB_TO_DA(mp,db) xfs_dir2_db_to_da(mp, db)
-static inline xfs_dablk_t
-xfs_dir2_db_to_da(struct xfs_mount *mp, xfs_dir2_db_t db)
-{
- return (xfs_dablk_t)((db) << (mp)->m_sb.sb_dirblklog);
-}
-
-/*
- * Convert byte in space to (DA) block
- */
-#define XFS_DIR2_BYTE_TO_DA(mp,by) xfs_dir2_byte_to_da(mp, by)
-static inline xfs_dablk_t
-xfs_dir2_byte_to_da(struct xfs_mount *mp, xfs_dir2_off_t by)
-{
- return XFS_DIR2_DB_TO_DA(mp, XFS_DIR2_BYTE_TO_DB(mp, by));
-}
-
-/*
- * Convert block and offset to dataptr
- */
-#define XFS_DIR2_DB_OFF_TO_DATAPTR(mp,db,o) \
- xfs_dir2_db_off_to_dataptr(mp, db, o)
-static inline xfs_dir2_dataptr_t
-xfs_dir2_db_off_to_dataptr(struct xfs_mount *mp, xfs_dir2_db_t db,
- xfs_dir2_data_aoff_t o)
-{
- return XFS_DIR2_BYTE_TO_DATAPTR(mp, XFS_DIR2_DB_OFF_TO_BYTE(mp, db, o));
-}
-
-/*
- * Convert block (dablk) to block (DB)
- */
-#define XFS_DIR2_DA_TO_DB(mp,da) xfs_dir2_da_to_db(mp, da)
-static inline xfs_dir2_db_t
-xfs_dir2_da_to_db(struct xfs_mount *mp, xfs_dablk_t da)
-{
- return (xfs_dir2_db_t)((da) >> (mp)->m_sb.sb_dirblklog);
-}
-
-/*
- * Convert block (dablk) to byte offset in space
- */
-#define XFS_DIR2_DA_TO_BYTE(mp,da) xfs_dir2_da_to_byte(mp, da)
-static inline xfs_dir2_off_t
-xfs_dir2_da_to_byte(struct xfs_mount *mp, xfs_dablk_t da)
-{
- return XFS_DIR2_DB_OFF_TO_BYTE(mp, XFS_DIR2_DA_TO_DB(mp, da), 0);
-}
-
-/*
- * Function declarations.
- */
-extern int xfs_dir2_block_to_leaf(struct xfs_da_args *args,
- struct xfs_dabuf *dbp);
-extern int xfs_dir2_leaf_addname(struct xfs_da_args *args);
-extern void xfs_dir2_leaf_compact(struct xfs_da_args *args,
- struct xfs_dabuf *bp);
-extern void xfs_dir2_leaf_compact_x1(struct xfs_dabuf *bp, int *indexp,
- int *lowstalep, int *highstalep,
- int *lowlogp, int *highlogp);
-extern int xfs_dir2_leaf_getdents(struct xfs_trans *tp, struct xfs_inode *dp,
- struct uio *uio, int *eofp,
- struct xfs_dirent *dbp, xfs_dir2_put_t put);
-extern int xfs_dir2_leaf_init(struct xfs_da_args *args, xfs_dir2_db_t bno,
- struct xfs_dabuf **bpp, int magic);
-extern void xfs_dir2_leaf_log_ents(struct xfs_trans *tp, struct xfs_dabuf *bp,
- int first, int last);
-extern void xfs_dir2_leaf_log_header(struct xfs_trans *tp,
- struct xfs_dabuf *bp);
-extern int xfs_dir2_leaf_lookup(struct xfs_da_args *args);
-extern int xfs_dir2_leaf_removename(struct xfs_da_args *args);
-extern int xfs_dir2_leaf_replace(struct xfs_da_args *args);
-extern int xfs_dir2_leaf_search_hash(struct xfs_da_args *args,
- struct xfs_dabuf *lbp);
-extern int xfs_dir2_leaf_trim_data(struct xfs_da_args *args,
- struct xfs_dabuf *lbp, xfs_dir2_db_t db);
-extern int xfs_dir2_node_to_leaf(struct xfs_da_state *state);
-
-#endif /* __XFS_DIR2_LEAF_H__ */
diff --git a/sys/gnu/fs/xfs/xfs_dir2_node.c b/sys/gnu/fs/xfs/xfs_dir2_node.c
deleted file mode 100644
index ac511ab..0000000
--- a/sys/gnu/fs/xfs/xfs_dir2_node.c
+++ /dev/null
@@ -1,1999 +0,0 @@
-/*
- * Copyright (c) 2000-2005 Silicon Graphics, Inc.
- * All Rights Reserved.
- *
- * 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.
- *
- * This program is distributed in the hope that it would 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 the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- */
-#include "xfs.h"
-#include "xfs_fs.h"
-#include "xfs_types.h"
-#include "xfs_log.h"
-#include "xfs_inum.h"
-#include "xfs_trans.h"
-#include "xfs_sb.h"
-#include "xfs_dir.h"
-#include "xfs_dir2.h"
-#include "xfs_dmapi.h"
-#include "xfs_mount.h"
-#include "xfs_da_btree.h"
-#include "xfs_bmap_btree.h"
-#include "xfs_dir_sf.h"
-#include "xfs_dir2_sf.h"
-#include "xfs_attr_sf.h"
-#include "xfs_dinode.h"
-#include "xfs_inode.h"
-#include "xfs_bmap.h"
-#include "xfs_dir2_data.h"
-#include "xfs_dir2_leaf.h"
-#include "xfs_dir2_block.h"
-#include "xfs_dir2_node.h"
-#include "xfs_dir2_trace.h"
-#include "xfs_error.h"
-
-/*
- * Function declarations.
- */
-static void xfs_dir2_free_log_header(xfs_trans_t *tp, xfs_dabuf_t *bp);
-static int xfs_dir2_leafn_add(xfs_dabuf_t *bp, xfs_da_args_t *args, int index);
-#ifdef DEBUG
-static void xfs_dir2_leafn_check(xfs_inode_t *dp, xfs_dabuf_t *bp);
-#else
-#define xfs_dir2_leafn_check(dp, bp)
-#endif
-static void xfs_dir2_leafn_moveents(xfs_da_args_t *args, xfs_dabuf_t *bp_s,
- int start_s, xfs_dabuf_t *bp_d, int start_d,
- int count);
-static void xfs_dir2_leafn_rebalance(xfs_da_state_t *state,
- xfs_da_state_blk_t *blk1,
- xfs_da_state_blk_t *blk2);
-static int xfs_dir2_leafn_remove(xfs_da_args_t *args, xfs_dabuf_t *bp,
- int index, xfs_da_state_blk_t *dblk,
- int *rval);
-static int xfs_dir2_node_addname_int(xfs_da_args_t *args,
- xfs_da_state_blk_t *fblk);
-
-/*
- * Log entries from a freespace block.
- */
-void
-xfs_dir2_free_log_bests(
- xfs_trans_t *tp, /* transaction pointer */
- xfs_dabuf_t *bp, /* freespace buffer */
- int first, /* first entry to log */
- int last) /* last entry to log */
-{
- xfs_dir2_free_t *free; /* freespace structure */
-
- free = bp->data;
- ASSERT(be32_to_cpu(free->hdr.magic) == XFS_DIR2_FREE_MAGIC);
- xfs_da_log_buf(tp, bp,
- (uint)((char *)&free->bests[first] - (char *)free),
- (uint)((char *)&free->bests[last] - (char *)free +
- sizeof(free->bests[0]) - 1));
-}
-
-/*
- * Log header from a freespace block.
- */
-static void
-xfs_dir2_free_log_header(
- xfs_trans_t *tp, /* transaction pointer */
- xfs_dabuf_t *bp) /* freespace buffer */
-{
- xfs_dir2_free_t *free; /* freespace structure */
-
- free = bp->data;
- ASSERT(be32_to_cpu(free->hdr.magic) == XFS_DIR2_FREE_MAGIC);
- xfs_da_log_buf(tp, bp, (uint)((char *)&free->hdr - (char *)free),
- (uint)(sizeof(xfs_dir2_free_hdr_t) - 1));
-}
-
-/*
- * Convert a leaf-format directory to a node-format directory.
- * We need to change the magic number of the leaf block, and copy
- * the freespace table out of the leaf block into its own block.
- */
-int /* error */
-xfs_dir2_leaf_to_node(
- xfs_da_args_t *args, /* operation arguments */
- xfs_dabuf_t *lbp) /* leaf buffer */
-{
- xfs_inode_t *dp; /* incore directory inode */
- int error; /* error return value */
- xfs_dabuf_t *fbp; /* freespace buffer */
- xfs_dir2_db_t fdb; /* freespace block number */
- xfs_dir2_free_t *free; /* freespace structure */
- __be16 *from; /* pointer to freespace entry */
- int i; /* leaf freespace index */
- xfs_dir2_leaf_t *leaf; /* leaf structure */
- xfs_dir2_leaf_tail_t *ltp; /* leaf tail structure */
- xfs_mount_t *mp; /* filesystem mount point */
- int n; /* count of live freespc ents */
- xfs_dir2_data_off_t off; /* freespace entry value */
- __be16 *to; /* pointer to freespace entry */
- xfs_trans_t *tp; /* transaction pointer */
-
- xfs_dir2_trace_args_b("leaf_to_node", args, lbp);
- dp = args->dp;
- mp = dp->i_mount;
- tp = args->trans;
- /*
- * Add a freespace block to the directory.
- */
- if ((error = xfs_dir2_grow_inode(args, XFS_DIR2_FREE_SPACE, &fdb))) {
- return error;
- }
- ASSERT(fdb == XFS_DIR2_FREE_FIRSTDB(mp));
- /*
- * Get the buffer for the new freespace block.
- */
- if ((error = xfs_da_get_buf(tp, dp, XFS_DIR2_DB_TO_DA(mp, fdb), -1, &fbp,
- XFS_DATA_FORK))) {
- return error;
- }
- ASSERT(fbp != NULL);
- free = fbp->data;
- leaf = lbp->data;
- ltp = XFS_DIR2_LEAF_TAIL_P(mp, leaf);
- /*
- * Initialize the freespace block header.
- */
- free->hdr.magic = cpu_to_be32(XFS_DIR2_FREE_MAGIC);
- free->hdr.firstdb = 0;
- ASSERT(be32_to_cpu(ltp->bestcount) <= (uint)dp->i_d.di_size / mp->m_dirblksize);
- free->hdr.nvalid = ltp->bestcount;
- /*
- * Copy freespace entries from the leaf block to the new block.
- * Count active entries.
- */
- for (i = n = 0, from = XFS_DIR2_LEAF_BESTS_P(ltp), to = free->bests;
- i < be32_to_cpu(ltp->bestcount); i++, from++, to++) {
- if ((off = be16_to_cpu(*from)) != NULLDATAOFF)
- n++;
- *to = cpu_to_be16(off);
- }
- free->hdr.nused = cpu_to_be32(n);
- leaf->hdr.info.magic = cpu_to_be16(XFS_DIR2_LEAFN_MAGIC);
- /*
- * Log everything.
- */
- xfs_dir2_leaf_log_header(tp, lbp);
- xfs_dir2_free_log_header(tp, fbp);
- xfs_dir2_free_log_bests(tp, fbp, 0, be32_to_cpu(free->hdr.nvalid) - 1);
- xfs_da_buf_done(fbp);
- xfs_dir2_leafn_check(dp, lbp);
- return 0;
-}
-
-/*
- * Add a leaf entry to a leaf block in a node-form directory.
- * The other work necessary is done from the caller.
- */
-static int /* error */
-xfs_dir2_leafn_add(
- xfs_dabuf_t *bp, /* leaf buffer */
- xfs_da_args_t *args, /* operation arguments */
- int index) /* insertion pt for new entry */
-{
- int compact; /* compacting stale leaves */
- xfs_inode_t *dp; /* incore directory inode */
- int highstale; /* next stale entry */
- xfs_dir2_leaf_t *leaf; /* leaf structure */
- xfs_dir2_leaf_entry_t *lep; /* leaf entry */
- int lfloghigh; /* high leaf entry logging */
- int lfloglow; /* low leaf entry logging */
- int lowstale; /* previous stale entry */
- xfs_mount_t *mp; /* filesystem mount point */
- xfs_trans_t *tp; /* transaction pointer */
-
- xfs_dir2_trace_args_sb("leafn_add", args, index, bp);
- dp = args->dp;
- mp = dp->i_mount;
- tp = args->trans;
- leaf = bp->data;
-
- /*
- * Quick check just to make sure we are not going to index
- * into other peoples memory
- */
- if (index < 0)
- return XFS_ERROR(EFSCORRUPTED);
-
- /*
- * If there are already the maximum number of leaf entries in
- * the block, if there are no stale entries it won't fit.
- * Caller will do a split. If there are stale entries we'll do
- * a compact.
- */
-
- if (be16_to_cpu(leaf->hdr.count) == XFS_DIR2_MAX_LEAF_ENTS(mp)) {
- if (!leaf->hdr.stale)
- return XFS_ERROR(ENOSPC);
- compact = be16_to_cpu(leaf->hdr.stale) > 1;
- } else
- compact = 0;
- ASSERT(index == 0 || be32_to_cpu(leaf->ents[index - 1].hashval) <= args->hashval);
- ASSERT(index == be16_to_cpu(leaf->hdr.count) ||
- be32_to_cpu(leaf->ents[index].hashval) >= args->hashval);
-
- if (args->justcheck)
- return 0;
-
- /*
- * Compact out all but one stale leaf entry. Leaves behind
- * the entry closest to index.
- */
- if (compact) {
- xfs_dir2_leaf_compact_x1(bp, &index, &lowstale, &highstale,
- &lfloglow, &lfloghigh);
- }
- /*
- * Set impossible logging indices for this case.
- */
- else if (leaf->hdr.stale) {
- lfloglow = be16_to_cpu(leaf->hdr.count);
- lfloghigh = -1;
- }
- /*
- * No stale entries, just insert a space for the new entry.
- */
- if (!leaf->hdr.stale) {
- lep = &leaf->ents[index];
- if (index < be16_to_cpu(leaf->hdr.count))
- memmove(lep + 1, lep,
- (be16_to_cpu(leaf->hdr.count) - index) * sizeof(*lep));
- lfloglow = index;
- lfloghigh = be16_to_cpu(leaf->hdr.count);
- be16_add(&leaf->hdr.count, 1);
- }
- /*
- * There are stale entries. We'll use one for the new entry.
- */
- else {
- /*
- * If we didn't do a compact then we need to figure out
- * which stale entry will be used.
- */
- if (compact == 0) {
- /*
- * Find first stale entry before our insertion point.
- */
- for (lowstale = index - 1;
- lowstale >= 0 &&
- be32_to_cpu(leaf->ents[lowstale].address) !=
- XFS_DIR2_NULL_DATAPTR;
- lowstale--)
- continue;
- /*
- * Find next stale entry after insertion point.
- * Stop looking if the answer would be worse than
- * lowstale already found.
- */
- for (highstale = index;
- highstale < be16_to_cpu(leaf->hdr.count) &&
- be32_to_cpu(leaf->ents[highstale].address) !=
- XFS_DIR2_NULL_DATAPTR &&
- (lowstale < 0 ||
- index - lowstale - 1 >= highstale - index);
- highstale++)
- continue;
- }
- /*
- * Using the low stale entry.
- * Shift entries up toward the stale slot.
- */
- if (lowstale >= 0 &&
- (highstale == be16_to_cpu(leaf->hdr.count) ||
- index - lowstale - 1 < highstale - index)) {
- ASSERT(be32_to_cpu(leaf->ents[lowstale].address) ==
- XFS_DIR2_NULL_DATAPTR);
- ASSERT(index - lowstale - 1 >= 0);
- if (index - lowstale - 1 > 0)
- memmove(&leaf->ents[lowstale],
- &leaf->ents[lowstale + 1],
- (index - lowstale - 1) * sizeof(*lep));
- lep = &leaf->ents[index - 1];
- lfloglow = MIN(lowstale, lfloglow);
- lfloghigh = MAX(index - 1, lfloghigh);
- }
- /*
- * Using the high stale entry.
- * Shift entries down toward the stale slot.
- */
- else {
- ASSERT(be32_to_cpu(leaf->ents[highstale].address) ==
- XFS_DIR2_NULL_DATAPTR);
- ASSERT(highstale - index >= 0);
- if (highstale - index > 0)
- memmove(&leaf->ents[index + 1],
- &leaf->ents[index],
- (highstale - index) * sizeof(*lep));
- lep = &leaf->ents[index];
- lfloglow = MIN(index, lfloglow);
- lfloghigh = MAX(highstale, lfloghigh);
- }
- be16_add(&leaf->hdr.stale, -1);
- }
- /*
- * Insert the new entry, log everything.
- */
- lep->hashval = cpu_to_be32(args->hashval);
- lep->address = cpu_to_be32(XFS_DIR2_DB_OFF_TO_DATAPTR(mp,
- args->blkno, args->index));
- xfs_dir2_leaf_log_header(tp, bp);
- xfs_dir2_leaf_log_ents(tp, bp, lfloglow, lfloghigh);
- xfs_dir2_leafn_check(dp, bp);
- return 0;
-}
-
-#ifdef DEBUG
-/*
- * Check internal consistency of a leafn block.
- */
-void
-xfs_dir2_leafn_check(
- xfs_inode_t *dp, /* incore directory inode */
- xfs_dabuf_t *bp) /* leaf buffer */
-{
- int i; /* leaf index */
- xfs_dir2_leaf_t *leaf; /* leaf structure */
- xfs_mount_t *mp; /* filesystem mount point */
- int stale; /* count of stale leaves */
-
- leaf = bp->data;
- mp = dp->i_mount;
- ASSERT(be16_to_cpu(leaf->hdr.info.magic) == XFS_DIR2_LEAFN_MAGIC);
- ASSERT(be16_to_cpu(leaf->hdr.count) <= XFS_DIR2_MAX_LEAF_ENTS(mp));
- for (i = stale = 0; i < be16_to_cpu(leaf->hdr.count); i++) {
- if (i + 1 < be16_to_cpu(leaf->hdr.count)) {
- ASSERT(be32_to_cpu(leaf->ents[i].hashval) <=
- be32_to_cpu(leaf->ents[i + 1].hashval));
- }
- if (be32_to_cpu(leaf->ents[i].address) == XFS_DIR2_NULL_DATAPTR)
- stale++;
- }
- ASSERT(be16_to_cpu(leaf->hdr.stale) == stale);
-}
-#endif /* DEBUG */
-
-/*
- * Return the last hash value in the leaf.
- * Stale entries are ok.
- */
-xfs_dahash_t /* hash value */
-xfs_dir2_leafn_lasthash(
- xfs_dabuf_t *bp, /* leaf buffer */
- int *count) /* count of entries in leaf */
-{
- xfs_dir2_leaf_t *leaf; /* leaf structure */
-
- leaf = bp->data;
- ASSERT(be16_to_cpu(leaf->hdr.info.magic) == XFS_DIR2_LEAFN_MAGIC);
- if (count)
- *count = be16_to_cpu(leaf->hdr.count);
- if (!leaf->hdr.count)
- return 0;
- return be32_to_cpu(leaf->ents[be16_to_cpu(leaf->hdr.count) - 1].hashval);
-}
-
-/*
- * Look up a leaf entry in a node-format leaf block.
- * If this is an addname then the extrablk in state is a freespace block,
- * otherwise it's a data block.
- */
-int
-xfs_dir2_leafn_lookup_int(
- xfs_dabuf_t *bp, /* leaf buffer */
- xfs_da_args_t *args, /* operation arguments */
- int *indexp, /* out: leaf entry index */
- xfs_da_state_t *state) /* state to fill in */
-{
- xfs_dabuf_t *curbp; /* current data/free buffer */
- xfs_dir2_db_t curdb; /* current data block number */
- xfs_dir2_db_t curfdb; /* current free block number */
- xfs_dir2_data_entry_t *dep; /* data block entry */
- xfs_inode_t *dp; /* incore directory inode */
- int error; /* error return value */
- int fi; /* free entry index */
- xfs_dir2_free_t *free=NULL; /* free block structure */
- int index; /* leaf entry index */
- xfs_dir2_leaf_t *leaf; /* leaf structure */
- int length=0; /* length of new data entry */
- xfs_dir2_leaf_entry_t *lep; /* leaf entry */
- xfs_mount_t *mp; /* filesystem mount point */
- xfs_dir2_db_t newdb; /* new data block number */
- xfs_dir2_db_t newfdb; /* new free block number */
- xfs_trans_t *tp; /* transaction pointer */
-
- dp = args->dp;
- tp = args->trans;
- mp = dp->i_mount;
- leaf = bp->data;
- ASSERT(be16_to_cpu(leaf->hdr.info.magic) == XFS_DIR2_LEAFN_MAGIC);
-#ifdef __KERNEL__
- ASSERT(be16_to_cpu(leaf->hdr.count) > 0);
-#endif
- xfs_dir2_leafn_check(dp, bp);
- /*
- * Look up the hash value in the leaf entries.
- */
- index = xfs_dir2_leaf_search_hash(args, bp);
- /*
- * Do we have a buffer coming in?
- */
- if (state->extravalid)
- curbp = state->extrablk.bp;
- else
- curbp = NULL;
- /*
- * For addname, it's a free block buffer, get the block number.
- */
- if (args->addname) {
- curfdb = curbp ? state->extrablk.blkno : -1;
- curdb = -1;
- length = XFS_DIR2_DATA_ENTSIZE(args->namelen);
- if ((free = (curbp ? curbp->data : NULL)))
- ASSERT(be32_to_cpu(free->hdr.magic) == XFS_DIR2_FREE_MAGIC);
- }
- /*
- * For others, it's a data block buffer, get the block number.
- */
- else {
- curfdb = -1;
- curdb = curbp ? state->extrablk.blkno : -1;
- }
- /*
- * Loop over leaf entries with the right hash value.
- */
- for (lep = &leaf->ents[index];
- index < be16_to_cpu(leaf->hdr.count) && be32_to_cpu(lep->hashval) == args->hashval;
- lep++, index++) {
- /*
- * Skip stale leaf entries.
- */
- if (be32_to_cpu(lep->address) == XFS_DIR2_NULL_DATAPTR)
- continue;
- /*
- * Pull the data block number from the entry.
- */
- newdb = XFS_DIR2_DATAPTR_TO_DB(mp, be32_to_cpu(lep->address));
- /*
- * For addname, we're looking for a place to put the new entry.
- * We want to use a data block with an entry of equal
- * hash value to ours if there is one with room.
- */
- if (args->addname) {
- /*
- * If this block isn't the data block we already have
- * in hand, take a look at it.
- */
- if (newdb != curdb) {
- curdb = newdb;
- /*
- * Convert the data block to the free block
- * holding its freespace information.
- */
- newfdb = XFS_DIR2_DB_TO_FDB(mp, newdb);
- /*
- * If it's not the one we have in hand,
- * read it in.
- */
- if (newfdb != curfdb) {
- /*
- * If we had one before, drop it.
- */
- if (curbp)
- xfs_da_brelse(tp, curbp);
- /*
- * Read the free block.
- */
- if ((error = xfs_da_read_buf(tp, dp,
- XFS_DIR2_DB_TO_DA(mp,
- newfdb),
- -1, &curbp,
- XFS_DATA_FORK))) {
- return error;
- }
- curfdb = newfdb;
- free = curbp->data;
- ASSERT(be32_to_cpu(free->hdr.magic) ==
- XFS_DIR2_FREE_MAGIC);
- ASSERT((be32_to_cpu(free->hdr.firstdb) %
- XFS_DIR2_MAX_FREE_BESTS(mp)) ==
- 0);
- ASSERT(be32_to_cpu(free->hdr.firstdb) <= curdb);
- ASSERT(curdb <
- be32_to_cpu(free->hdr.firstdb) +
- be32_to_cpu(free->hdr.nvalid));
- }
- /*
- * Get the index for our entry.
- */
- fi = XFS_DIR2_DB_TO_FDINDEX(mp, curdb);
- /*
- * If it has room, return it.
- */
- if (unlikely(be16_to_cpu(free->bests[fi]) == NULLDATAOFF)) {
- XFS_ERROR_REPORT("xfs_dir2_leafn_lookup_int",
- XFS_ERRLEVEL_LOW, mp);
- return XFS_ERROR(EFSCORRUPTED);
- }
- if (be16_to_cpu(free->bests[fi]) >= length) {
- *indexp = index;
- state->extravalid = 1;
- state->extrablk.bp = curbp;
- state->extrablk.blkno = curfdb;
- state->extrablk.index = fi;
- state->extrablk.magic =
- XFS_DIR2_FREE_MAGIC;
- ASSERT(args->oknoent);
- return XFS_ERROR(ENOENT);
- }
- }
- }
- /*
- * Not adding a new entry, so we really want to find
- * the name given to us.
- */
- else {
- /*
- * If it's a different data block, go get it.
- */
- if (newdb != curdb) {
- /*
- * If we had a block before, drop it.
- */
- if (curbp)
- xfs_da_brelse(tp, curbp);
- /*
- * Read the data block.
- */
- if ((error =
- xfs_da_read_buf(tp, dp,
- XFS_DIR2_DB_TO_DA(mp, newdb), -1,
- &curbp, XFS_DATA_FORK))) {
- return error;
- }
- xfs_dir2_data_check(dp, curbp);
- curdb = newdb;
- }
- /*
- * Point to the data entry.
- */
- dep = (xfs_dir2_data_entry_t *)
- ((char *)curbp->data +
- XFS_DIR2_DATAPTR_TO_OFF(mp, be32_to_cpu(lep->address)));
- /*
- * Compare the entry, return it if it matches.
- */
- if (dep->namelen == args->namelen &&
- dep->name[0] == args->name[0] &&
- memcmp(dep->name, args->name, args->namelen) == 0) {
- args->inumber = INT_GET(dep->inumber, ARCH_CONVERT);
- *indexp = index;
- state->extravalid = 1;
- state->extrablk.bp = curbp;
- state->extrablk.blkno = curdb;
- state->extrablk.index =
- (int)((char *)dep -
- (char *)curbp->data);
- state->extrablk.magic = XFS_DIR2_DATA_MAGIC;
- return XFS_ERROR(EEXIST);
- }
- }
- }
- /*
- * Didn't find a match.
- * If we are holding a buffer, give it back in case our caller
- * finds it useful.
- */
- if ((state->extravalid = (curbp != NULL))) {
- state->extrablk.bp = curbp;
- state->extrablk.index = -1;
- /*
- * For addname, giving back a free block.
- */
- if (args->addname) {
- state->extrablk.blkno = curfdb;
- state->extrablk.magic = XFS_DIR2_FREE_MAGIC;
- }
- /*
- * For other callers, giving back a data block.
- */
- else {
- state->extrablk.blkno = curdb;
- state->extrablk.magic = XFS_DIR2_DATA_MAGIC;
- }
- }
- /*
- * Return the final index, that will be the insertion point.
- */
- *indexp = index;
- ASSERT(index == be16_to_cpu(leaf->hdr.count) || args->oknoent);
- return XFS_ERROR(ENOENT);
-}
-
-/*
- * Move count leaf entries from source to destination leaf.
- * Log entries and headers. Stale entries are preserved.
- */
-static void
-xfs_dir2_leafn_moveents(
- xfs_da_args_t *args, /* operation arguments */
- xfs_dabuf_t *bp_s, /* source leaf buffer */
- int start_s, /* source leaf index */
- xfs_dabuf_t *bp_d, /* destination leaf buffer */
- int start_d, /* destination leaf index */
- int count) /* count of leaves to copy */
-{
- xfs_dir2_leaf_t *leaf_d; /* destination leaf structure */
- xfs_dir2_leaf_t *leaf_s; /* source leaf structure */
- int stale; /* count stale leaves copied */
- xfs_trans_t *tp; /* transaction pointer */
-
- xfs_dir2_trace_args_bibii("leafn_moveents", args, bp_s, start_s, bp_d,
- start_d, count);
- /*
- * Silently return if nothing to do.
- */
- if (count == 0) {
- return;
- }
- tp = args->trans;
- leaf_s = bp_s->data;
- leaf_d = bp_d->data;
- /*
- * If the destination index is not the end of the current
- * destination leaf entries, open up a hole in the destination
- * to hold the new entries.
- */
- if (start_d < be16_to_cpu(leaf_d->hdr.count)) {
- memmove(&leaf_d->ents[start_d + count], &leaf_d->ents[start_d],
- (be16_to_cpu(leaf_d->hdr.count) - start_d) *
- sizeof(xfs_dir2_leaf_entry_t));
- xfs_dir2_leaf_log_ents(tp, bp_d, start_d + count,
- count + be16_to_cpu(leaf_d->hdr.count) - 1);
- }
- /*
- * If the source has stale leaves, count the ones in the copy range
- * so we can update the header correctly.
- */
- if (leaf_s->hdr.stale) {
- int i; /* temp leaf index */
-
- for (i = start_s, stale = 0; i < start_s + count; i++) {
- if (be32_to_cpu(leaf_s->ents[i].address) == XFS_DIR2_NULL_DATAPTR)
- stale++;
- }
- } else
- stale = 0;
- /*
- * Copy the leaf entries from source to destination.
- */
- memcpy(&leaf_d->ents[start_d], &leaf_s->ents[start_s],
- count * sizeof(xfs_dir2_leaf_entry_t));
- xfs_dir2_leaf_log_ents(tp, bp_d, start_d, start_d + count - 1);
- /*
- * If there are source entries after the ones we copied,
- * delete the ones we copied by sliding the next ones down.
- */
- if (start_s + count < be16_to_cpu(leaf_s->hdr.count)) {
- memmove(&leaf_s->ents[start_s], &leaf_s->ents[start_s + count],
- count * sizeof(xfs_dir2_leaf_entry_t));
- xfs_dir2_leaf_log_ents(tp, bp_s, start_s, start_s + count - 1);
- }
- /*
- * Update the headers and log them.
- */
- be16_add(&leaf_s->hdr.count, -(count));
- be16_add(&leaf_s->hdr.stale, -(stale));
- be16_add(&leaf_d->hdr.count, count);
- be16_add(&leaf_d->hdr.stale, stale);
- xfs_dir2_leaf_log_header(tp, bp_s);
- xfs_dir2_leaf_log_header(tp, bp_d);
- xfs_dir2_leafn_check(args->dp, bp_s);
- xfs_dir2_leafn_check(args->dp, bp_d);
-}
-
-/*
- * Determine the sort order of two leaf blocks.
- * Returns 1 if both are valid and leaf2 should be before leaf1, else 0.
- */
-int /* sort order */
-xfs_dir2_leafn_order(
- xfs_dabuf_t *leaf1_bp, /* leaf1 buffer */
- xfs_dabuf_t *leaf2_bp) /* leaf2 buffer */
-{
- xfs_dir2_leaf_t *leaf1; /* leaf1 structure */
- xfs_dir2_leaf_t *leaf2; /* leaf2 structure */
-
- leaf1 = leaf1_bp->data;
- leaf2 = leaf2_bp->data;
- ASSERT(be16_to_cpu(leaf1->hdr.info.magic) == XFS_DIR2_LEAFN_MAGIC);
- ASSERT(be16_to_cpu(leaf2->hdr.info.magic) == XFS_DIR2_LEAFN_MAGIC);
- if (be16_to_cpu(leaf1->hdr.count) > 0 &&
- be16_to_cpu(leaf2->hdr.count) > 0 &&
- (be32_to_cpu(leaf2->ents[0].hashval) < be32_to_cpu(leaf1->ents[0].hashval) ||
- be32_to_cpu(leaf2->ents[be16_to_cpu(leaf2->hdr.count) - 1].hashval) <
- be32_to_cpu(leaf1->ents[be16_to_cpu(leaf1->hdr.count) - 1].hashval)))
- return 1;
- return 0;
-}
-
-/*
- * Rebalance leaf entries between two leaf blocks.
- * This is actually only called when the second block is new,
- * though the code deals with the general case.
- * A new entry will be inserted in one of the blocks, and that
- * entry is taken into account when balancing.
- */
-static void
-xfs_dir2_leafn_rebalance(
- xfs_da_state_t *state, /* btree cursor */
- xfs_da_state_blk_t *blk1, /* first btree block */
- xfs_da_state_blk_t *blk2) /* second btree block */
-{
- xfs_da_args_t *args; /* operation arguments */
- int count; /* count (& direction) leaves */
- int isleft; /* new goes in left leaf */
- xfs_dir2_leaf_t *leaf1; /* first leaf structure */
- xfs_dir2_leaf_t *leaf2; /* second leaf structure */
- int mid; /* midpoint leaf index */
-#ifdef DEBUG
- int oldstale; /* old count of stale leaves */
-#endif
- int oldsum; /* old total leaf count */
- int swap; /* swapped leaf blocks */
-
- args = state->args;
- /*
- * If the block order is wrong, swap the arguments.
- */
- if ((swap = xfs_dir2_leafn_order(blk1->bp, blk2->bp))) {
- xfs_da_state_blk_t *tmp; /* temp for block swap */
-
- tmp = blk1;
- blk1 = blk2;
- blk2 = tmp;
- }
- leaf1 = blk1->bp->data;
- leaf2 = blk2->bp->data;
- oldsum = be16_to_cpu(leaf1->hdr.count) + be16_to_cpu(leaf2->hdr.count);
-#ifdef DEBUG
- oldstale = be16_to_cpu(leaf1->hdr.stale) + be16_to_cpu(leaf2->hdr.stale);
-#endif
- mid = oldsum >> 1;
- /*
- * If the old leaf count was odd then the new one will be even,
- * so we need to divide the new count evenly.
- */
- if (oldsum & 1) {
- xfs_dahash_t midhash; /* middle entry hash value */
-
- if (mid >= be16_to_cpu(leaf1->hdr.count))
- midhash = be32_to_cpu(leaf2->ents[mid - be16_to_cpu(leaf1->hdr.count)].hashval);
- else
- midhash = be32_to_cpu(leaf1->ents[mid].hashval);
- isleft = args->hashval <= midhash;
- }
- /*
- * If the old count is even then the new count is odd, so there's
- * no preferred side for the new entry.
- * Pick the left one.
- */
- else
- isleft = 1;
- /*
- * Calculate moved entry count. Positive means left-to-right,
- * negative means right-to-left. Then move the entries.
- */
- count = be16_to_cpu(leaf1->hdr.count) - mid + (isleft == 0);
- if (count > 0)
- xfs_dir2_leafn_moveents(args, blk1->bp,
- be16_to_cpu(leaf1->hdr.count) - count, blk2->bp, 0, count);
- else if (count < 0)
- xfs_dir2_leafn_moveents(args, blk2->bp, 0, blk1->bp,
- be16_to_cpu(leaf1->hdr.count), count);
- ASSERT(be16_to_cpu(leaf1->hdr.count) + be16_to_cpu(leaf2->hdr.count) == oldsum);
- ASSERT(be16_to_cpu(leaf1->hdr.stale) + be16_to_cpu(leaf2->hdr.stale) == oldstale);
- /*
- * Mark whether we're inserting into the old or new leaf.
- */
- if (be16_to_cpu(leaf1->hdr.count) < be16_to_cpu(leaf2->hdr.count))
- state->inleaf = swap;
- else if (be16_to_cpu(leaf1->hdr.count) > be16_to_cpu(leaf2->hdr.count))
- state->inleaf = !swap;
- else
- state->inleaf =
- swap ^ (blk1->index <= be16_to_cpu(leaf1->hdr.count));
- /*
- * Adjust the expected index for insertion.
- */
- if (!state->inleaf)
- blk2->index = blk1->index - be16_to_cpu(leaf1->hdr.count);
-
- /*
- * Finally sanity check just to make sure we are not returning a negative index
- */
- if(blk2->index < 0) {
- state->inleaf = 1;
- blk2->index = 0;
- cmn_err(CE_ALERT,
- "xfs_dir2_leafn_rebalance: picked the wrong leaf? reverting original leaf: "
- "blk1->index %d\n",
- blk1->index);
- }
-}
-
-/*
- * Remove an entry from a node directory.
- * This removes the leaf entry and the data entry,
- * and updates the free block if necessary.
- */
-static int /* error */
-xfs_dir2_leafn_remove(
- xfs_da_args_t *args, /* operation arguments */
- xfs_dabuf_t *bp, /* leaf buffer */
- int index, /* leaf entry index */
- xfs_da_state_blk_t *dblk, /* data block */
- int *rval) /* resulting block needs join */
-{
- xfs_dir2_data_t *data; /* data block structure */
- xfs_dir2_db_t db; /* data block number */
- xfs_dabuf_t *dbp; /* data block buffer */
- xfs_dir2_data_entry_t *dep; /* data block entry */
- xfs_inode_t *dp; /* incore directory inode */
- xfs_dir2_leaf_t *leaf; /* leaf structure */
- xfs_dir2_leaf_entry_t *lep; /* leaf entry */
- int longest; /* longest data free entry */
- int off; /* data block entry offset */
- xfs_mount_t *mp; /* filesystem mount point */
- int needlog; /* need to log data header */
- int needscan; /* need to rescan data frees */
- xfs_trans_t *tp; /* transaction pointer */
-
- xfs_dir2_trace_args_sb("leafn_remove", args, index, bp);
- dp = args->dp;
- tp = args->trans;
- mp = dp->i_mount;
- leaf = bp->data;
- ASSERT(be16_to_cpu(leaf->hdr.info.magic) == XFS_DIR2_LEAFN_MAGIC);
- /*
- * Point to the entry we're removing.
- */
- lep = &leaf->ents[index];
- /*
- * Extract the data block and offset from the entry.
- */
- db = XFS_DIR2_DATAPTR_TO_DB(mp, be32_to_cpu(lep->address));
- ASSERT(dblk->blkno == db);
- off = XFS_DIR2_DATAPTR_TO_OFF(mp, be32_to_cpu(lep->address));
- ASSERT(dblk->index == off);
- /*
- * Kill the leaf entry by marking it stale.
- * Log the leaf block changes.
- */
- be16_add(&leaf->hdr.stale, 1);
- xfs_dir2_leaf_log_header(tp, bp);
- lep->address = cpu_to_be32(XFS_DIR2_NULL_DATAPTR);
- xfs_dir2_leaf_log_ents(tp, bp, index, index);
- /*
- * Make the data entry free. Keep track of the longest freespace
- * in the data block in case it changes.
- */
- dbp = dblk->bp;
- data = dbp->data;
- dep = (xfs_dir2_data_entry_t *)((char *)data + off);
- longest = be16_to_cpu(data->hdr.bestfree[0].length);
- needlog = needscan = 0;
- xfs_dir2_data_make_free(tp, dbp, off,
- XFS_DIR2_DATA_ENTSIZE(dep->namelen), &needlog, &needscan);
- /*
- * Rescan the data block freespaces for bestfree.
- * Log the data block header if needed.
- */
- if (needscan)
- xfs_dir2_data_freescan(mp, data, &needlog, NULL);
- if (needlog)
- xfs_dir2_data_log_header(tp, dbp);
- xfs_dir2_data_check(dp, dbp);
- /*
- * If the longest data block freespace changes, need to update
- * the corresponding freeblock entry.
- */
- if (longest < be16_to_cpu(data->hdr.bestfree[0].length)) {
- int error; /* error return value */
- xfs_dabuf_t *fbp; /* freeblock buffer */
- xfs_dir2_db_t fdb; /* freeblock block number */
- int findex; /* index in freeblock entries */
- xfs_dir2_free_t *free; /* freeblock structure */
- int logfree; /* need to log free entry */
-
- /*
- * Convert the data block number to a free block,
- * read in the free block.
- */
- fdb = XFS_DIR2_DB_TO_FDB(mp, db);
- if ((error = xfs_da_read_buf(tp, dp, XFS_DIR2_DB_TO_DA(mp, fdb),
- -1, &fbp, XFS_DATA_FORK))) {
- return error;
- }
- free = fbp->data;
- ASSERT(be32_to_cpu(free->hdr.magic) == XFS_DIR2_FREE_MAGIC);
- ASSERT(be32_to_cpu(free->hdr.firstdb) ==
- XFS_DIR2_MAX_FREE_BESTS(mp) *
- (fdb - XFS_DIR2_FREE_FIRSTDB(mp)));
- /*
- * Calculate which entry we need to fix.
- */
- findex = XFS_DIR2_DB_TO_FDINDEX(mp, db);
- longest = be16_to_cpu(data->hdr.bestfree[0].length);
- /*
- * If the data block is now empty we can get rid of it
- * (usually).
- */
- if (longest == mp->m_dirblksize - (uint)sizeof(data->hdr)) {
- /*
- * Try to punch out the data block.
- */
- error = xfs_dir2_shrink_inode(args, db, dbp);
- if (error == 0) {
- dblk->bp = NULL;
- data = NULL;
- }
- /*
- * We can get ENOSPC if there's no space reservation.
- * In this case just drop the buffer and some one else
- * will eventually get rid of the empty block.
- */
- else if (error == ENOSPC && args->total == 0)
- xfs_da_buf_done(dbp);
- else
- return error;
- }
- /*
- * If we got rid of the data block, we can eliminate that entry
- * in the free block.
- */
- if (data == NULL) {
- /*
- * One less used entry in the free table.
- */
- free->hdr.nused = cpu_to_be32(-1);
- xfs_dir2_free_log_header(tp, fbp);
- /*
- * If this was the last entry in the table, we can
- * trim the table size back. There might be other
- * entries at the end referring to non-existent
- * data blocks, get those too.
- */
- if (findex == be32_to_cpu(free->hdr.nvalid) - 1) {
- int i; /* free entry index */
-
- for (i = findex - 1;
- i >= 0 && be16_to_cpu(free->bests[i]) == NULLDATAOFF;
- i--)
- continue;
- free->hdr.nvalid = cpu_to_be32(i + 1);
- logfree = 0;
- }
- /*
- * Not the last entry, just punch it out.
- */
- else {
- free->bests[findex] = cpu_to_be16(NULLDATAOFF);
- logfree = 1;
- }
- /*
- * If there are no useful entries left in the block,
- * get rid of the block if we can.
- */
- if (!free->hdr.nused) {
- error = xfs_dir2_shrink_inode(args, fdb, fbp);
- if (error == 0) {
- fbp = NULL;
- logfree = 0;
- } else if (error != ENOSPC || args->total != 0)
- return error;
- /*
- * It's possible to get ENOSPC if there is no
- * space reservation. In this case some one
- * else will eventually get rid of this block.
- */
- }
- }
- /*
- * Data block is not empty, just set the free entry to
- * the new value.
- */
- else {
- free->bests[findex] = cpu_to_be16(longest);
- logfree = 1;
- }
- /*
- * Log the free entry that changed, unless we got rid of it.
- */
- if (logfree)
- xfs_dir2_free_log_bests(tp, fbp, findex, findex);
- /*
- * Drop the buffer if we still have it.
- */
- if (fbp)
- xfs_da_buf_done(fbp);
- }
- xfs_dir2_leafn_check(dp, bp);
- /*
- * Return indication of whether this leaf block is emtpy enough
- * to justify trying to join it with a neighbor.
- */
- *rval =
- ((uint)sizeof(leaf->hdr) +
- (uint)sizeof(leaf->ents[0]) *
- (be16_to_cpu(leaf->hdr.count) - be16_to_cpu(leaf->hdr.stale))) <
- mp->m_dir_magicpct;
- return 0;
-}
-
-/*
- * Split the leaf entries in the old block into old and new blocks.
- */
-int /* error */
-xfs_dir2_leafn_split(
- xfs_da_state_t *state, /* btree cursor */
- xfs_da_state_blk_t *oldblk, /* original block */
- xfs_da_state_blk_t *newblk) /* newly created block */
-{
- xfs_da_args_t *args; /* operation arguments */
- xfs_dablk_t blkno; /* new leaf block number */
- int error; /* error return value */
- xfs_mount_t *mp; /* filesystem mount point */
-
- /*
- * Allocate space for a new leaf node.
- */
- args = state->args;
- mp = args->dp->i_mount;
- ASSERT(args != NULL);
- ASSERT(oldblk->magic == XFS_DIR2_LEAFN_MAGIC);
- error = xfs_da_grow_inode(args, &blkno);
- if (error) {
- return error;
- }
- /*
- * Initialize the new leaf block.
- */
- error = xfs_dir2_leaf_init(args, XFS_DIR2_DA_TO_DB(mp, blkno),
- &newblk->bp, XFS_DIR2_LEAFN_MAGIC);
- if (error) {
- return error;
- }
- newblk->blkno = blkno;
- newblk->magic = XFS_DIR2_LEAFN_MAGIC;
- /*
- * Rebalance the entries across the two leaves, link the new
- * block into the leaves.
- */
- xfs_dir2_leafn_rebalance(state, oldblk, newblk);
- error = xfs_da_blk_link(state, oldblk, newblk);
- if (error) {
- return error;
- }
- /*
- * Insert the new entry in the correct block.
- */
- if (state->inleaf)
- error = xfs_dir2_leafn_add(oldblk->bp, args, oldblk->index);
- else
- error = xfs_dir2_leafn_add(newblk->bp, args, newblk->index);
- /*
- * Update last hashval in each block since we added the name.
- */
- oldblk->hashval = xfs_dir2_leafn_lasthash(oldblk->bp, NULL);
- newblk->hashval = xfs_dir2_leafn_lasthash(newblk->bp, NULL);
- xfs_dir2_leafn_check(args->dp, oldblk->bp);
- xfs_dir2_leafn_check(args->dp, newblk->bp);
- return error;
-}
-
-/*
- * Check a leaf block and its neighbors to see if the block should be
- * collapsed into one or the other neighbor. Always keep the block
- * with the smaller block number.
- * If the current block is over 50% full, don't try to join it, return 0.
- * If the block is empty, fill in the state structure and return 2.
- * If it can be collapsed, fill in the state structure and return 1.
- * If nothing can be done, return 0.
- */
-int /* error */
-xfs_dir2_leafn_toosmall(
- xfs_da_state_t *state, /* btree cursor */
- int *action) /* resulting action to take */
-{
- xfs_da_state_blk_t *blk; /* leaf block */
- xfs_dablk_t blkno; /* leaf block number */
- xfs_dabuf_t *bp; /* leaf buffer */
- int bytes; /* bytes in use */
- int count; /* leaf live entry count */
- int error; /* error return value */
- int forward; /* sibling block direction */
- int i; /* sibling counter */
- xfs_da_blkinfo_t *info; /* leaf block header */
- xfs_dir2_leaf_t *leaf; /* leaf structure */
- int rval; /* result from path_shift */
-
- /*
- * Check for the degenerate case of the block being over 50% full.
- * If so, it's not worth even looking to see if we might be able
- * to coalesce with a sibling.
- */
- blk = &state->path.blk[state->path.active - 1];
- info = blk->bp->data;
- ASSERT(be16_to_cpu(info->magic) == XFS_DIR2_LEAFN_MAGIC);
- leaf = (xfs_dir2_leaf_t *)info;
- count = be16_to_cpu(leaf->hdr.count) - be16_to_cpu(leaf->hdr.stale);
- bytes = (uint)sizeof(leaf->hdr) + count * (uint)sizeof(leaf->ents[0]);
- if (bytes > (state->blocksize >> 1)) {
- /*
- * Blk over 50%, don't try to join.
- */
- *action = 0;
- return 0;
- }
- /*
- * Check for the degenerate case of the block being empty.
- * If the block is empty, we'll simply delete it, no need to
- * coalesce it with a sibling block. We choose (arbitrarily)
- * to merge with the forward block unless it is NULL.
- */
- if (count == 0) {
- /*
- * Make altpath point to the block we want to keep and
- * path point to the block we want to drop (this one).
- */
- forward = (info->forw != 0);
- memcpy(&state->altpath, &state->path, sizeof(state->path));
- error = xfs_da_path_shift(state, &state->altpath, forward, 0,
- &rval);
- if (error)
- return error;
- *action = rval ? 2 : 0;
- return 0;
- }
- /*
- * Examine each sibling block to see if we can coalesce with
- * at least 25% free space to spare. We need to figure out
- * whether to merge with the forward or the backward block.
- * We prefer coalescing with the lower numbered sibling so as
- * to shrink a directory over time.
- */
- forward = be32_to_cpu(info->forw) < be32_to_cpu(info->back);
- for (i = 0, bp = NULL; i < 2; forward = !forward, i++) {
- blkno = forward ? be32_to_cpu(info->forw) : be32_to_cpu(info->back);
- if (blkno == 0)
- continue;
- /*
- * Read the sibling leaf block.
- */
- if ((error =
- xfs_da_read_buf(state->args->trans, state->args->dp, blkno,
- -1, &bp, XFS_DATA_FORK))) {
- return error;
- }
- ASSERT(bp != NULL);
- /*
- * Count bytes in the two blocks combined.
- */
- leaf = (xfs_dir2_leaf_t *)info;
- count = be16_to_cpu(leaf->hdr.count) - be16_to_cpu(leaf->hdr.stale);
- bytes = state->blocksize - (state->blocksize >> 2);
- leaf = bp->data;
- ASSERT(be16_to_cpu(leaf->hdr.info.magic) == XFS_DIR2_LEAFN_MAGIC);
- count += be16_to_cpu(leaf->hdr.count) - be16_to_cpu(leaf->hdr.stale);
- bytes -= count * (uint)sizeof(leaf->ents[0]);
- /*
- * Fits with at least 25% to spare.
- */
- if (bytes >= 0)
- break;
- xfs_da_brelse(state->args->trans, bp);
- }
- /*
- * Didn't like either block, give up.
- */
- if (i >= 2) {
- *action = 0;
- return 0;
- }
- /*
- * Done with the sibling leaf block here, drop the dabuf
- * so path_shift can get it.
- */
- xfs_da_buf_done(bp);
- /*
- * Make altpath point to the block we want to keep (the lower
- * numbered block) and path point to the block we want to drop.
- */
- memcpy(&state->altpath, &state->path, sizeof(state->path));
- if (blkno < blk->blkno)
- error = xfs_da_path_shift(state, &state->altpath, forward, 0,
- &rval);
- else
- error = xfs_da_path_shift(state, &state->path, forward, 0,
- &rval);
- if (error) {
- return error;
- }
- *action = rval ? 0 : 1;
- return 0;
-}
-
-/*
- * Move all the leaf entries from drop_blk to save_blk.
- * This is done as part of a join operation.
- */
-void
-xfs_dir2_leafn_unbalance(
- xfs_da_state_t *state, /* cursor */
- xfs_da_state_blk_t *drop_blk, /* dead block */
- xfs_da_state_blk_t *save_blk) /* surviving block */
-{
- xfs_da_args_t *args; /* operation arguments */
- xfs_dir2_leaf_t *drop_leaf; /* dead leaf structure */
- xfs_dir2_leaf_t *save_leaf; /* surviving leaf structure */
-
- args = state->args;
- ASSERT(drop_blk->magic == XFS_DIR2_LEAFN_MAGIC);
- ASSERT(save_blk->magic == XFS_DIR2_LEAFN_MAGIC);
- drop_leaf = drop_blk->bp->data;
- save_leaf = save_blk->bp->data;
- ASSERT(be16_to_cpu(drop_leaf->hdr.info.magic) == XFS_DIR2_LEAFN_MAGIC);
- ASSERT(be16_to_cpu(save_leaf->hdr.info.magic) == XFS_DIR2_LEAFN_MAGIC);
- /*
- * If there are any stale leaf entries, take this opportunity
- * to purge them.
- */
- if (drop_leaf->hdr.stale)
- xfs_dir2_leaf_compact(args, drop_blk->bp);
- if (save_leaf->hdr.stale)
- xfs_dir2_leaf_compact(args, save_blk->bp);
- /*
- * Move the entries from drop to the appropriate end of save.
- */
- drop_blk->hashval = be32_to_cpu(drop_leaf->ents[be16_to_cpu(drop_leaf->hdr.count) - 1].hashval);
- if (xfs_dir2_leafn_order(save_blk->bp, drop_blk->bp))
- xfs_dir2_leafn_moveents(args, drop_blk->bp, 0, save_blk->bp, 0,
- be16_to_cpu(drop_leaf->hdr.count));
- else
- xfs_dir2_leafn_moveents(args, drop_blk->bp, 0, save_blk->bp,
- be16_to_cpu(save_leaf->hdr.count), be16_to_cpu(drop_leaf->hdr.count));
- save_blk->hashval = be32_to_cpu(save_leaf->ents[be16_to_cpu(save_leaf->hdr.count) - 1].hashval);
- xfs_dir2_leafn_check(args->dp, save_blk->bp);
-}
-
-/*
- * Top-level node form directory addname routine.
- */
-int /* error */
-xfs_dir2_node_addname(
- xfs_da_args_t *args) /* operation arguments */
-{
- xfs_da_state_blk_t *blk; /* leaf block for insert */
- int error; /* error return value */
- int rval; /* sub-return value */
- xfs_da_state_t *state; /* btree cursor */
-
- xfs_dir2_trace_args("node_addname", args);
- /*
- * Allocate and initialize the state (btree cursor).
- */
- state = xfs_da_state_alloc();
- state->args = args;
- state->mp = args->dp->i_mount;
- state->blocksize = state->mp->m_dirblksize;
- state->node_ents = state->mp->m_dir_node_ents;
- /*
- * Look up the name. We're not supposed to find it, but
- * this gives us the insertion point.
- */
- error = xfs_da_node_lookup_int(state, &rval);
- if (error)
- rval = error;
- if (rval != ENOENT) {
- goto done;
- }
- /*
- * Add the data entry to a data block.
- * Extravalid is set to a freeblock found by lookup.
- */
- rval = xfs_dir2_node_addname_int(args,
- state->extravalid ? &state->extrablk : NULL);
- if (rval) {
- goto done;
- }
- blk = &state->path.blk[state->path.active - 1];
- ASSERT(blk->magic == XFS_DIR2_LEAFN_MAGIC);
- /*
- * Add the new leaf entry.
- */
- rval = xfs_dir2_leafn_add(blk->bp, args, blk->index);
- if (rval == 0) {
- /*
- * It worked, fix the hash values up the btree.
- */
- if (!args->justcheck)
- xfs_da_fixhashpath(state, &state->path);
- } else {
- /*
- * It didn't work, we need to split the leaf block.
- */
- if (args->total == 0) {
- ASSERT(rval == ENOSPC);
- goto done;
- }
- /*
- * Split the leaf block and insert the new entry.
- */
- rval = xfs_da_split(state);
- }
-done:
- xfs_da_state_free(state);
- return rval;
-}
-
-/*
- * Add the data entry for a node-format directory name addition.
- * The leaf entry is added in xfs_dir2_leafn_add.
- * We may enter with a freespace block that the lookup found.
- */
-static int /* error */
-xfs_dir2_node_addname_int(
- xfs_da_args_t *args, /* operation arguments */
- xfs_da_state_blk_t *fblk) /* optional freespace block */
-{
- xfs_dir2_data_t *data; /* data block structure */
- xfs_dir2_db_t dbno; /* data block number */
- xfs_dabuf_t *dbp; /* data block buffer */
- xfs_dir2_data_entry_t *dep; /* data entry pointer */
- xfs_inode_t *dp; /* incore directory inode */
- xfs_dir2_data_unused_t *dup; /* data unused entry pointer */
- int error; /* error return value */
- xfs_dir2_db_t fbno; /* freespace block number */
- xfs_dabuf_t *fbp; /* freespace buffer */
- int findex; /* freespace entry index */
- xfs_dir2_free_t *free=NULL; /* freespace block structure */
- xfs_dir2_db_t ifbno; /* initial freespace block no */
- xfs_dir2_db_t lastfbno=0; /* highest freespace block no */
- int length; /* length of the new entry */
- int logfree; /* need to log free entry */
- xfs_mount_t *mp; /* filesystem mount point */
- int needlog; /* need to log data header */
- int needscan; /* need to rescan data frees */
- __be16 *tagp; /* data entry tag pointer */
- xfs_trans_t *tp; /* transaction pointer */
-
- dp = args->dp;
- mp = dp->i_mount;
- tp = args->trans;
- length = XFS_DIR2_DATA_ENTSIZE(args->namelen);
- /*
- * If we came in with a freespace block that means that lookup
- * found an entry with our hash value. This is the freespace
- * block for that data entry.
- */
- if (fblk) {
- fbp = fblk->bp;
- /*
- * Remember initial freespace block number.
- */
- ifbno = fblk->blkno;
- free = fbp->data;
- ASSERT(be32_to_cpu(free->hdr.magic) == XFS_DIR2_FREE_MAGIC);
- findex = fblk->index;
- /*
- * This means the free entry showed that the data block had
- * space for our entry, so we remembered it.
- * Use that data block.
- */
- if (findex >= 0) {
- ASSERT(findex < be32_to_cpu(free->hdr.nvalid));
- ASSERT(be16_to_cpu(free->bests[findex]) != NULLDATAOFF);
- ASSERT(be16_to_cpu(free->bests[findex]) >= length);
- dbno = be32_to_cpu(free->hdr.firstdb) + findex;
- }
- /*
- * The data block looked at didn't have enough room.
- * We'll start at the beginning of the freespace entries.
- */
- else {
- dbno = -1;
- findex = 0;
- }
- }
- /*
- * Didn't come in with a freespace block, so don't have a data block.
- */
- else {
- ifbno = dbno = -1;
- fbp = NULL;
- findex = 0;
- }
- /*
- * If we don't have a data block yet, we're going to scan the
- * freespace blocks looking for one. Figure out what the
- * highest freespace block number is.
- */
- if (dbno == -1) {
- xfs_fileoff_t fo; /* freespace block number */
-
- if ((error = xfs_bmap_last_offset(tp, dp, &fo, XFS_DATA_FORK)))
- return error;
- lastfbno = XFS_DIR2_DA_TO_DB(mp, (xfs_dablk_t)fo);
- fbno = ifbno;
- }
- /*
- * While we haven't identified a data block, search the freeblock
- * data for a good data block. If we find a null freeblock entry,
- * indicating a hole in the data blocks, remember that.
- */
- while (dbno == -1) {
- /*
- * If we don't have a freeblock in hand, get the next one.
- */
- if (fbp == NULL) {
- /*
- * Happens the first time through unless lookup gave
- * us a freespace block to start with.
- */
- if (++fbno == 0)
- fbno = XFS_DIR2_FREE_FIRSTDB(mp);
- /*
- * If it's ifbno we already looked at it.
- */
- if (fbno == ifbno)
- fbno++;
- /*
- * If it's off the end we're done.
- */
- if (fbno >= lastfbno)
- break;
- /*
- * Read the block. There can be holes in the
- * freespace blocks, so this might not succeed.
- * This should be really rare, so there's no reason
- * to avoid it.
- */
- if ((error = xfs_da_read_buf(tp, dp,
- XFS_DIR2_DB_TO_DA(mp, fbno), -2, &fbp,
- XFS_DATA_FORK))) {
- return error;
- }
- if (unlikely(fbp == NULL)) {
- continue;
- }
- free = fbp->data;
- ASSERT(be32_to_cpu(free->hdr.magic) == XFS_DIR2_FREE_MAGIC);
- findex = 0;
- }
- /*
- * Look at the current free entry. Is it good enough?
- */
- if (be16_to_cpu(free->bests[findex]) != NULLDATAOFF &&
- be16_to_cpu(free->bests[findex]) >= length)
- dbno = be32_to_cpu(free->hdr.firstdb) + findex;
- else {
- /*
- * Are we done with the freeblock?
- */
- if (++findex == be32_to_cpu(free->hdr.nvalid)) {
- /*
- * Drop the block.
- */
- xfs_da_brelse(tp, fbp);
- fbp = NULL;
- if (fblk && fblk->bp)
- fblk->bp = NULL;
- }
- }
- }
- /*
- * If we don't have a data block, we need to allocate one and make
- * the freespace entries refer to it.
- */
- if (unlikely(dbno == -1)) {
- /*
- * Not allowed to allocate, return failure.
- */
- if (args->justcheck || args->total == 0) {
- /*
- * Drop the freespace buffer unless it came from our
- * caller.
- */
- if ((fblk == NULL || fblk->bp == NULL) && fbp != NULL)
- xfs_da_buf_done(fbp);
- return XFS_ERROR(ENOSPC);
- }
- /*
- * Allocate and initialize the new data block.
- */
- if (unlikely((error = xfs_dir2_grow_inode(args,
- XFS_DIR2_DATA_SPACE,
- &dbno)) ||
- (error = xfs_dir2_data_init(args, dbno, &dbp)))) {
- /*
- * Drop the freespace buffer unless it came from our
- * caller.
- */
- if ((fblk == NULL || fblk->bp == NULL) && fbp != NULL)
- xfs_da_buf_done(fbp);
- return error;
- }
- /*
- * If (somehow) we have a freespace block, get rid of it.
- */
- if (fbp)
- xfs_da_brelse(tp, fbp);
- if (fblk && fblk->bp)
- fblk->bp = NULL;
-
- /*
- * Get the freespace block corresponding to the data block
- * that was just allocated.
- */
- fbno = XFS_DIR2_DB_TO_FDB(mp, dbno);
- if (unlikely(error = xfs_da_read_buf(tp, dp,
- XFS_DIR2_DB_TO_DA(mp, fbno), -2, &fbp,
- XFS_DATA_FORK))) {
- xfs_da_buf_done(dbp);
- return error;
- }
- /*
- * If there wasn't a freespace block, the read will
- * return a NULL fbp. Allocate and initialize a new one.
- */
- if( fbp == NULL ) {
- if ((error = xfs_dir2_grow_inode(args, XFS_DIR2_FREE_SPACE,
- &fbno))) {
- return error;
- }
-
- if (unlikely(XFS_DIR2_DB_TO_FDB(mp, dbno) != fbno)) {
- cmn_err(CE_ALERT,
- "xfs_dir2_node_addname_int: dir ino "
- "%llu needed freesp block %lld for\n"
- " data block %lld, got %lld\n"
- " ifbno %llu lastfbno %d\n",
- (unsigned long long)dp->i_ino,
- (long long)XFS_DIR2_DB_TO_FDB(mp, dbno),
- (long long)dbno, (long long)fbno,
- (unsigned long long)ifbno, lastfbno);
- if (fblk) {
- cmn_err(CE_ALERT,
- " fblk 0x%p blkno %llu "
- "index %d magic 0x%x\n",
- fblk,
- (unsigned long long)fblk->blkno,
- fblk->index,
- fblk->magic);
- } else {
- cmn_err(CE_ALERT,
- " ... fblk is NULL\n");
- }
- XFS_ERROR_REPORT("xfs_dir2_node_addname_int",
- XFS_ERRLEVEL_LOW, mp);
- return XFS_ERROR(EFSCORRUPTED);
- }
-
- /*
- * Get a buffer for the new block.
- */
- if ((error = xfs_da_get_buf(tp, dp,
- XFS_DIR2_DB_TO_DA(mp, fbno),
- -1, &fbp, XFS_DATA_FORK))) {
- return error;
- }
- ASSERT(fbp != NULL);
-
- /*
- * Initialize the new block to be empty, and remember
- * its first slot as our empty slot.
- */
- free = fbp->data;
- free->hdr.magic = cpu_to_be32(XFS_DIR2_FREE_MAGIC);
- free->hdr.firstdb = cpu_to_be32(
- (fbno - XFS_DIR2_FREE_FIRSTDB(mp)) *
- XFS_DIR2_MAX_FREE_BESTS(mp));
- free->hdr.nvalid = 0;
- free->hdr.nused = 0;
- } else {
- free = fbp->data;
- ASSERT(be32_to_cpu(free->hdr.magic) == XFS_DIR2_FREE_MAGIC);
- }
-
- /*
- * Set the freespace block index from the data block number.
- */
- findex = XFS_DIR2_DB_TO_FDINDEX(mp, dbno);
- /*
- * If it's after the end of the current entries in the
- * freespace block, extend that table.
- */
- if (findex >= be32_to_cpu(free->hdr.nvalid)) {
- ASSERT(findex < XFS_DIR2_MAX_FREE_BESTS(mp));
- free->hdr.nvalid = cpu_to_be32(findex + 1);
- /*
- * Tag new entry so nused will go up.
- */
- free->bests[findex] = cpu_to_be16(NULLDATAOFF);
- }
- /*
- * If this entry was for an empty data block
- * (this should always be true) then update the header.
- */
- if (be16_to_cpu(free->bests[findex]) == NULLDATAOFF) {
- be32_add(&free->hdr.nused, 1);
- xfs_dir2_free_log_header(tp, fbp);
- }
- /*
- * Update the real value in the table.
- * We haven't allocated the data entry yet so this will
- * change again.
- */
- data = dbp->data;
- free->bests[findex] = data->hdr.bestfree[0].length;
- logfree = 1;
- }
- /*
- * We had a data block so we don't have to make a new one.
- */
- else {
- /*
- * If just checking, we succeeded.
- */
- if (args->justcheck) {
- if ((fblk == NULL || fblk->bp == NULL) && fbp != NULL)
- xfs_da_buf_done(fbp);
- return 0;
- }
- /*
- * Read the data block in.
- */
- if (unlikely(
- error = xfs_da_read_buf(tp, dp, XFS_DIR2_DB_TO_DA(mp, dbno),
- -1, &dbp, XFS_DATA_FORK))) {
- if ((fblk == NULL || fblk->bp == NULL) && fbp != NULL)
- xfs_da_buf_done(fbp);
- return error;
- }
- data = dbp->data;
- logfree = 0;
- }
- ASSERT(be16_to_cpu(data->hdr.bestfree[0].length) >= length);
- /*
- * Point to the existing unused space.
- */
- dup = (xfs_dir2_data_unused_t *)
- ((char *)data + be16_to_cpu(data->hdr.bestfree[0].offset));
- needscan = needlog = 0;
- /*
- * Mark the first part of the unused space, inuse for us.
- */
- xfs_dir2_data_use_free(tp, dbp, dup,
- (xfs_dir2_data_aoff_t)((char *)dup - (char *)data), length,
- &needlog, &needscan);
- /*
- * Fill in the new entry and log it.
- */
- dep = (xfs_dir2_data_entry_t *)dup;
- INT_SET(dep->inumber, ARCH_CONVERT, args->inumber);
- dep->namelen = args->namelen;
- memcpy(dep->name, args->name, dep->namelen);
- tagp = XFS_DIR2_DATA_ENTRY_TAG_P(dep);
- *tagp = cpu_to_be16((char *)dep - (char *)data);
- xfs_dir2_data_log_entry(tp, dbp, dep);
- /*
- * Rescan the block for bestfree if needed.
- */
- if (needscan)
- xfs_dir2_data_freescan(mp, data, &needlog, NULL);
- /*
- * Log the data block header if needed.
- */
- if (needlog)
- xfs_dir2_data_log_header(tp, dbp);
- /*
- * If the freespace entry is now wrong, update it.
- */
- if (be16_to_cpu(free->bests[findex]) != be16_to_cpu(data->hdr.bestfree[0].length)) {
- free->bests[findex] = data->hdr.bestfree[0].length;
- logfree = 1;
- }
- /*
- * Log the freespace entry if needed.
- */
- if (logfree)
- xfs_dir2_free_log_bests(tp, fbp, findex, findex);
- /*
- * If the caller didn't hand us the freespace block, drop it.
- */
- if ((fblk == NULL || fblk->bp == NULL) && fbp != NULL)
- xfs_da_buf_done(fbp);
- /*
- * Return the data block and offset in args, then drop the data block.
- */
- args->blkno = (xfs_dablk_t)dbno;
- args->index = be16_to_cpu(*tagp);
- xfs_da_buf_done(dbp);
- return 0;
-}
-
-/*
- * Lookup an entry in a node-format directory.
- * All the real work happens in xfs_da_node_lookup_int.
- * The only real output is the inode number of the entry.
- */
-int /* error */
-xfs_dir2_node_lookup(
- xfs_da_args_t *args) /* operation arguments */
-{
- int error; /* error return value */
- int i; /* btree level */
- int rval; /* operation return value */
- xfs_da_state_t *state; /* btree cursor */
-
- xfs_dir2_trace_args("node_lookup", args);
- /*
- * Allocate and initialize the btree cursor.
- */
- state = xfs_da_state_alloc();
- state->args = args;
- state->mp = args->dp->i_mount;
- state->blocksize = state->mp->m_dirblksize;
- state->node_ents = state->mp->m_dir_node_ents;
- /*
- * Fill in the path to the entry in the cursor.
- */
- error = xfs_da_node_lookup_int(state, &rval);
- if (error)
- rval = error;
- /*
- * Release the btree blocks and leaf block.
- */
- for (i = 0; i < state->path.active; i++) {
- xfs_da_brelse(args->trans, state->path.blk[i].bp);
- state->path.blk[i].bp = NULL;
- }
- /*
- * Release the data block if we have it.
- */
- if (state->extravalid && state->extrablk.bp) {
- xfs_da_brelse(args->trans, state->extrablk.bp);
- state->extrablk.bp = NULL;
- }
- xfs_da_state_free(state);
- return rval;
-}
-
-/*
- * Remove an entry from a node-format directory.
- */
-int /* error */
-xfs_dir2_node_removename(
- xfs_da_args_t *args) /* operation arguments */
-{
- xfs_da_state_blk_t *blk; /* leaf block */
- int error; /* error return value */
- int rval; /* operation return value */
- xfs_da_state_t *state; /* btree cursor */
-
- xfs_dir2_trace_args("node_removename", args);
- /*
- * Allocate and initialize the btree cursor.
- */
- state = xfs_da_state_alloc();
- state->args = args;
- state->mp = args->dp->i_mount;
- state->blocksize = state->mp->m_dirblksize;
- state->node_ents = state->mp->m_dir_node_ents;
- /*
- * Look up the entry we're deleting, set up the cursor.
- */
- error = xfs_da_node_lookup_int(state, &rval);
- if (error) {
- rval = error;
- }
- /*
- * Didn't find it, upper layer screwed up.
- */
- if (rval != EEXIST) {
- xfs_da_state_free(state);
- return rval;
- }
- blk = &state->path.blk[state->path.active - 1];
- ASSERT(blk->magic == XFS_DIR2_LEAFN_MAGIC);
- ASSERT(state->extravalid);
- /*
- * Remove the leaf and data entries.
- * Extrablk refers to the data block.
- */
- error = xfs_dir2_leafn_remove(args, blk->bp, blk->index,
- &state->extrablk, &rval);
- if (error) {
- return error;
- }
- /*
- * Fix the hash values up the btree.
- */
- xfs_da_fixhashpath(state, &state->path);
- /*
- * If we need to join leaf blocks, do it.
- */
- if (rval && state->path.active > 1)
- error = xfs_da_join(state);
- /*
- * If no errors so far, try conversion to leaf format.
- */
- if (!error)
- error = xfs_dir2_node_to_leaf(state);
- xfs_da_state_free(state);
- return error;
-}
-
-/*
- * Replace an entry's inode number in a node-format directory.
- */
-int /* error */
-xfs_dir2_node_replace(
- xfs_da_args_t *args) /* operation arguments */
-{
- xfs_da_state_blk_t *blk; /* leaf block */
- xfs_dir2_data_t *data; /* data block structure */
- xfs_dir2_data_entry_t *dep; /* data entry changed */
- int error; /* error return value */
- int i; /* btree level */
- xfs_ino_t inum; /* new inode number */
- xfs_dir2_leaf_t *leaf; /* leaf structure */
- xfs_dir2_leaf_entry_t *lep; /* leaf entry being changed */
- int rval; /* internal return value */
- xfs_da_state_t *state; /* btree cursor */
-
- xfs_dir2_trace_args("node_replace", args);
- /*
- * Allocate and initialize the btree cursor.
- */
- state = xfs_da_state_alloc();
- state->args = args;
- state->mp = args->dp->i_mount;
- state->blocksize = state->mp->m_dirblksize;
- state->node_ents = state->mp->m_dir_node_ents;
- inum = args->inumber;
- /*
- * Lookup the entry to change in the btree.
- */
- error = xfs_da_node_lookup_int(state, &rval);
- if (error) {
- rval = error;
- }
- /*
- * It should be found, since the vnodeops layer has looked it up
- * and locked it. But paranoia is good.
- */
- if (rval == EEXIST) {
- /*
- * Find the leaf entry.
- */
- blk = &state->path.blk[state->path.active - 1];
- ASSERT(blk->magic == XFS_DIR2_LEAFN_MAGIC);
- leaf = blk->bp->data;
- lep = &leaf->ents[blk->index];
- ASSERT(state->extravalid);
- /*
- * Point to the data entry.
- */
- data = state->extrablk.bp->data;
- ASSERT(be32_to_cpu(data->hdr.magic) == XFS_DIR2_DATA_MAGIC);
- dep = (xfs_dir2_data_entry_t *)
- ((char *)data +
- XFS_DIR2_DATAPTR_TO_OFF(state->mp, be32_to_cpu(lep->address)));
- ASSERT(inum != INT_GET(dep->inumber, ARCH_CONVERT));
- /*
- * Fill in the new inode number and log the entry.
- */
- INT_SET(dep->inumber, ARCH_CONVERT, inum);
- xfs_dir2_data_log_entry(args->trans, state->extrablk.bp, dep);
- rval = 0;
- }
- /*
- * Didn't find it, and we're holding a data block. Drop it.
- */
- else if (state->extravalid) {
- xfs_da_brelse(args->trans, state->extrablk.bp);
- state->extrablk.bp = NULL;
- }
- /*
- * Release all the buffers in the cursor.
- */
- for (i = 0; i < state->path.active; i++) {
- xfs_da_brelse(args->trans, state->path.blk[i].bp);
- state->path.blk[i].bp = NULL;
- }
- xfs_da_state_free(state);
- return rval;
-}
-
-/*
- * Trim off a trailing empty freespace block.
- * Return (in rvalp) 1 if we did it, 0 if not.
- */
-int /* error */
-xfs_dir2_node_trim_free(
- xfs_da_args_t *args, /* operation arguments */
- xfs_fileoff_t fo, /* free block number */
- int *rvalp) /* out: did something */
-{
- xfs_dabuf_t *bp; /* freespace buffer */
- xfs_inode_t *dp; /* incore directory inode */
- int error; /* error return code */
- xfs_dir2_free_t *free; /* freespace structure */
- xfs_mount_t *mp; /* filesystem mount point */
- xfs_trans_t *tp; /* transaction pointer */
-
- dp = args->dp;
- mp = dp->i_mount;
- tp = args->trans;
- /*
- * Read the freespace block.
- */
- if (unlikely(error = xfs_da_read_buf(tp, dp, (xfs_dablk_t)fo, -2, &bp,
- XFS_DATA_FORK))) {
- return error;
- }
-
- /*
- * There can be holes in freespace. If fo is a hole, there's
- * nothing to do.
- */
- if (bp == NULL) {
- return 0;
- }
- free = bp->data;
- ASSERT(be32_to_cpu(free->hdr.magic) == XFS_DIR2_FREE_MAGIC);
- /*
- * If there are used entries, there's nothing to do.
- */
- if (be32_to_cpu(free->hdr.nused) > 0) {
- xfs_da_brelse(tp, bp);
- *rvalp = 0;
- return 0;
- }
- /*
- * Blow the block away.
- */
- if ((error =
- xfs_dir2_shrink_inode(args, XFS_DIR2_DA_TO_DB(mp, (xfs_dablk_t)fo),
- bp))) {
- /*
- * Can't fail with ENOSPC since that only happens with no
- * space reservation, when breaking up an extent into two
- * pieces. This is the last block of an extent.
- */
- ASSERT(error != ENOSPC);
- xfs_da_brelse(tp, bp);
- return error;
- }
- /*
- * Return that we succeeded.
- */
- *rvalp = 1;
- return 0;
-}
diff --git a/sys/gnu/fs/xfs/xfs_dir2_node.h b/sys/gnu/fs/xfs/xfs_dir2_node.h
deleted file mode 100644
index c7c870e..0000000
--- a/sys/gnu/fs/xfs/xfs_dir2_node.h
+++ /dev/null
@@ -1,104 +0,0 @@
-/*
- * Copyright (c) 2000,2005 Silicon Graphics, Inc.
- * All Rights Reserved.
- *
- * 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.
- *
- * This program is distributed in the hope that it would 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 the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- */
-#ifndef __XFS_DIR2_NODE_H__
-#define __XFS_DIR2_NODE_H__
-
-/*
- * Directory version 2, btree node format structures
- */
-
-struct uio;
-struct xfs_dabuf;
-struct xfs_da_args;
-struct xfs_da_state;
-struct xfs_da_state_blk;
-struct xfs_inode;
-struct xfs_trans;
-
-/*
- * Offset of the freespace index.
- */
-#define XFS_DIR2_FREE_SPACE 2
-#define XFS_DIR2_FREE_OFFSET (XFS_DIR2_FREE_SPACE * XFS_DIR2_SPACE_SIZE)
-#define XFS_DIR2_FREE_FIRSTDB(mp) \
- XFS_DIR2_BYTE_TO_DB(mp, XFS_DIR2_FREE_OFFSET)
-
-#define XFS_DIR2_FREE_MAGIC 0x58443246 /* XD2F */
-
-typedef struct xfs_dir2_free_hdr {
- __be32 magic; /* XFS_DIR2_FREE_MAGIC */
- __be32 firstdb; /* db of first entry */
- __be32 nvalid; /* count of valid entries */
- __be32 nused; /* count of used entries */
-} xfs_dir2_free_hdr_t;
-
-typedef struct xfs_dir2_free {
- xfs_dir2_free_hdr_t hdr; /* block header */
- __be16 bests[1]; /* best free counts */
- /* unused entries are -1 */
-} xfs_dir2_free_t;
-
-#define XFS_DIR2_MAX_FREE_BESTS(mp) \
- (((mp)->m_dirblksize - (uint)sizeof(xfs_dir2_free_hdr_t)) / \
- (uint)sizeof(xfs_dir2_data_off_t))
-
-/*
- * Convert data space db to the corresponding free db.
- */
-#define XFS_DIR2_DB_TO_FDB(mp,db) xfs_dir2_db_to_fdb(mp, db)
-static inline xfs_dir2_db_t
-xfs_dir2_db_to_fdb(struct xfs_mount *mp, xfs_dir2_db_t db)
-{
- return (XFS_DIR2_FREE_FIRSTDB(mp) + (db) / XFS_DIR2_MAX_FREE_BESTS(mp));
-}
-
-/*
- * Convert data space db to the corresponding index in a free db.
- */
-#define XFS_DIR2_DB_TO_FDINDEX(mp,db) xfs_dir2_db_to_fdindex(mp, db)
-static inline int
-xfs_dir2_db_to_fdindex(struct xfs_mount *mp, xfs_dir2_db_t db)
-{
- return ((db) % XFS_DIR2_MAX_FREE_BESTS(mp));
-}
-
-extern void xfs_dir2_free_log_bests(struct xfs_trans *tp, struct xfs_dabuf *bp,
- int first, int last);
-extern int xfs_dir2_leaf_to_node(struct xfs_da_args *args,
- struct xfs_dabuf *lbp);
-extern xfs_dahash_t xfs_dir2_leafn_lasthash(struct xfs_dabuf *bp, int *count);
-extern int xfs_dir2_leafn_lookup_int(struct xfs_dabuf *bp,
- struct xfs_da_args *args, int *indexp,
- struct xfs_da_state *state);
-extern int xfs_dir2_leafn_order(struct xfs_dabuf *leaf1_bp,
- struct xfs_dabuf *leaf2_bp);
-extern int xfs_dir2_leafn_split(struct xfs_da_state *state,
- struct xfs_da_state_blk *oldblk,
- struct xfs_da_state_blk *newblk);
-extern int xfs_dir2_leafn_toosmall(struct xfs_da_state *state, int *action);
-extern void xfs_dir2_leafn_unbalance(struct xfs_da_state *state,
- struct xfs_da_state_blk *drop_blk,
- struct xfs_da_state_blk *save_blk);
-extern int xfs_dir2_node_addname(struct xfs_da_args *args);
-extern int xfs_dir2_node_lookup(struct xfs_da_args *args);
-extern int xfs_dir2_node_removename(struct xfs_da_args *args);
-extern int xfs_dir2_node_replace(struct xfs_da_args *args);
-extern int xfs_dir2_node_trim_free(struct xfs_da_args *args, xfs_fileoff_t fo,
- int *rvalp);
-
-#endif /* __XFS_DIR2_NODE_H__ */
diff --git a/sys/gnu/fs/xfs/xfs_dir2_sf.c b/sys/gnu/fs/xfs/xfs_dir2_sf.c
deleted file mode 100644
index d98a41d..0000000
--- a/sys/gnu/fs/xfs/xfs_dir2_sf.c
+++ /dev/null
@@ -1,1296 +0,0 @@
-/*
- * Copyright (c) 2000-2003,2005 Silicon Graphics, Inc.
- * All Rights Reserved.
- *
- * 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.
- *
- * This program is distributed in the hope that it would 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 the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- */
-#include "xfs.h"
-#include "xfs_fs.h"
-#include "xfs_types.h"
-#include "xfs_log.h"
-#include "xfs_inum.h"
-#include "xfs_trans.h"
-#include "xfs_sb.h"
-#include "xfs_dir.h"
-#include "xfs_dir2.h"
-#include "xfs_dmapi.h"
-#include "xfs_mount.h"
-#include "xfs_da_btree.h"
-#include "xfs_bmap_btree.h"
-#include "xfs_dir_sf.h"
-#include "xfs_dir2_sf.h"
-#include "xfs_attr_sf.h"
-#include "xfs_dinode.h"
-#include "xfs_inode.h"
-#include "xfs_inode_item.h"
-#include "xfs_dir_leaf.h"
-#include "xfs_error.h"
-#include "xfs_dir2_data.h"
-#include "xfs_dir2_leaf.h"
-#include "xfs_dir2_block.h"
-#include "xfs_dir2_trace.h"
-
-/*
- * Prototypes for internal functions.
- */
-static void xfs_dir2_sf_addname_easy(xfs_da_args_t *args,
- xfs_dir2_sf_entry_t *sfep,
- xfs_dir2_data_aoff_t offset,
- int new_isize);
-static void xfs_dir2_sf_addname_hard(xfs_da_args_t *args, int objchange,
- int new_isize);
-static int xfs_dir2_sf_addname_pick(xfs_da_args_t *args, int objchange,
- xfs_dir2_sf_entry_t **sfepp,
- xfs_dir2_data_aoff_t *offsetp);
-#ifdef DEBUG
-static void xfs_dir2_sf_check(xfs_da_args_t *args);
-#else
-#define xfs_dir2_sf_check(args)
-#endif /* DEBUG */
-#if XFS_BIG_INUMS
-static void xfs_dir2_sf_toino4(xfs_da_args_t *args);
-static void xfs_dir2_sf_toino8(xfs_da_args_t *args);
-#endif /* XFS_BIG_INUMS */
-
-/*
- * Given a block directory (dp/block), calculate its size as a shortform (sf)
- * directory and a header for the sf directory, if it will fit it the
- * space currently present in the inode. If it won't fit, the output
- * size is too big (but not accurate).
- */
-int /* size for sf form */
-xfs_dir2_block_sfsize(
- xfs_inode_t *dp, /* incore inode pointer */
- xfs_dir2_block_t *block, /* block directory data */
- xfs_dir2_sf_hdr_t *sfhp) /* output: header for sf form */
-{
- xfs_dir2_dataptr_t addr; /* data entry address */
- xfs_dir2_leaf_entry_t *blp; /* leaf area of the block */
- xfs_dir2_block_tail_t *btp; /* tail area of the block */
- int count; /* shortform entry count */
- xfs_dir2_data_entry_t *dep; /* data entry in the block */
- int i; /* block entry index */
- int i8count; /* count of big-inode entries */
- int isdot; /* entry is "." */
- int isdotdot; /* entry is ".." */
- xfs_mount_t *mp; /* mount structure pointer */
- int namelen; /* total name bytes */
- xfs_ino_t parent = 0; /* parent inode number */
- int size=0; /* total computed size */
-
- mp = dp->i_mount;
-
- count = i8count = namelen = 0;
- btp = XFS_DIR2_BLOCK_TAIL_P(mp, block);
- blp = XFS_DIR2_BLOCK_LEAF_P(btp);
-
- /*
- * Iterate over the block's data entries by using the leaf pointers.
- */
- for (i = 0; i < be32_to_cpu(btp->count); i++) {
- if ((addr = be32_to_cpu(blp[i].address)) == XFS_DIR2_NULL_DATAPTR)
- continue;
- /*
- * Calculate the pointer to the entry at hand.
- */
- dep = (xfs_dir2_data_entry_t *)
- ((char *)block + XFS_DIR2_DATAPTR_TO_OFF(mp, addr));
- /*
- * Detect . and .., so we can special-case them.
- * . is not included in sf directories.
- * .. is included by just the parent inode number.
- */
- isdot = dep->namelen == 1 && dep->name[0] == '.';
- isdotdot =
- dep->namelen == 2 &&
- dep->name[0] == '.' && dep->name[1] == '.';
-#if XFS_BIG_INUMS
- if (!isdot)
- i8count += INT_GET(dep->inumber, ARCH_CONVERT) > XFS_DIR2_MAX_SHORT_INUM;
-#endif
- if (!isdot && !isdotdot) {
- count++;
- namelen += dep->namelen;
- } else if (isdotdot)
- parent = INT_GET(dep->inumber, ARCH_CONVERT);
- /*
- * Calculate the new size, see if we should give up yet.
- */
- size = XFS_DIR2_SF_HDR_SIZE(i8count) + /* header */
- count + /* namelen */
- count * (uint)sizeof(xfs_dir2_sf_off_t) + /* offset */
- namelen + /* name */
- (i8count ? /* inumber */
- (uint)sizeof(xfs_dir2_ino8_t) * count :
- (uint)sizeof(xfs_dir2_ino4_t) * count);
- if (size > XFS_IFORK_DSIZE(dp))
- return size; /* size value is a failure */
- }
- /*
- * Create the output header, if it worked.
- */
- sfhp->count = count;
- sfhp->i8count = i8count;
- XFS_DIR2_SF_PUT_INUMBER((xfs_dir2_sf_t *)sfhp, &parent, &sfhp->parent);
- return size;
-}
-
-/*
- * Convert a block format directory to shortform.
- * Caller has already checked that it will fit, and built us a header.
- */
-int /* error */
-xfs_dir2_block_to_sf(
- xfs_da_args_t *args, /* operation arguments */
- xfs_dabuf_t *bp, /* block buffer */
- int size, /* shortform directory size */
- xfs_dir2_sf_hdr_t *sfhp) /* shortform directory hdr */
-{
- xfs_dir2_block_t *block; /* block structure */
- xfs_dir2_block_tail_t *btp; /* block tail pointer */
- xfs_dir2_data_entry_t *dep; /* data entry pointer */
- xfs_inode_t *dp; /* incore directory inode */
- xfs_dir2_data_unused_t *dup; /* unused data pointer */
- char *endptr; /* end of data entries */
- int error; /* error return value */
- int logflags; /* inode logging flags */
- xfs_mount_t *mp; /* filesystem mount point */
- char *ptr; /* current data pointer */
- xfs_dir2_sf_entry_t *sfep; /* shortform entry */
- xfs_dir2_sf_t *sfp; /* shortform structure */
- xfs_ino_t temp;
-
- xfs_dir2_trace_args_sb("block_to_sf", args, size, bp);
- dp = args->dp;
- mp = dp->i_mount;
-
- /*
- * Make a copy of the block data, so we can shrink the inode
- * and add local data.
- */
- block = kmem_alloc(mp->m_dirblksize, KM_SLEEP);
- memcpy(block, bp->data, mp->m_dirblksize);
- logflags = XFS_ILOG_CORE;
- if ((error = xfs_dir2_shrink_inode(args, mp->m_dirdatablk, bp))) {
- ASSERT(error != ENOSPC);
- goto out;
- }
- /*
- * The buffer is now unconditionally gone, whether
- * xfs_dir2_shrink_inode worked or not.
- *
- * Convert the inode to local format.
- */
- dp->i_df.if_flags &= ~XFS_IFEXTENTS;
- dp->i_df.if_flags |= XFS_IFINLINE;
- dp->i_d.di_format = XFS_DINODE_FMT_LOCAL;
- ASSERT(dp->i_df.if_bytes == 0);
- xfs_idata_realloc(dp, size, XFS_DATA_FORK);
- logflags |= XFS_ILOG_DDATA;
- /*
- * Copy the header into the newly allocate local space.
- */
- sfp = (xfs_dir2_sf_t *)dp->i_df.if_u1.if_data;
- memcpy(sfp, sfhp, XFS_DIR2_SF_HDR_SIZE(sfhp->i8count));
- dp->i_d.di_size = size;
- /*
- * Set up to loop over the block's entries.
- */
- btp = XFS_DIR2_BLOCK_TAIL_P(mp, block);
- ptr = (char *)block->u;
- endptr = (char *)XFS_DIR2_BLOCK_LEAF_P(btp);
- sfep = XFS_DIR2_SF_FIRSTENTRY(sfp);
- /*
- * Loop over the active and unused entries.
- * Stop when we reach the leaf/tail portion of the block.
- */
- while (ptr < endptr) {
- /*
- * If it's unused, just skip over it.
- */
- dup = (xfs_dir2_data_unused_t *)ptr;
- if (be16_to_cpu(dup->freetag) == XFS_DIR2_DATA_FREE_TAG) {
- ptr += be16_to_cpu(dup->length);
- continue;
- }
- dep = (xfs_dir2_data_entry_t *)ptr;
- /*
- * Skip .
- */
- if (dep->namelen == 1 && dep->name[0] == '.')
- ASSERT(INT_GET(dep->inumber, ARCH_CONVERT) == dp->i_ino);
- /*
- * Skip .., but make sure the inode number is right.
- */
- else if (dep->namelen == 2 &&
- dep->name[0] == '.' && dep->name[1] == '.')
- ASSERT(INT_GET(dep->inumber, ARCH_CONVERT) ==
- XFS_DIR2_SF_GET_INUMBER(sfp, &sfp->hdr.parent));
- /*
- * Normal entry, copy it into shortform.
- */
- else {
- sfep->namelen = dep->namelen;
- XFS_DIR2_SF_PUT_OFFSET(sfep,
- (xfs_dir2_data_aoff_t)
- ((char *)dep - (char *)block));
- memcpy(sfep->name, dep->name, dep->namelen);
- temp=INT_GET(dep->inumber, ARCH_CONVERT);
- XFS_DIR2_SF_PUT_INUMBER(sfp, &temp,
- XFS_DIR2_SF_INUMBERP(sfep));
- sfep = XFS_DIR2_SF_NEXTENTRY(sfp, sfep);
- }
- ptr += XFS_DIR2_DATA_ENTSIZE(dep->namelen);
- }
- ASSERT((char *)sfep - (char *)sfp == size);
- xfs_dir2_sf_check(args);
-out:
- xfs_trans_log_inode(args->trans, dp, logflags);
- kmem_free(block, mp->m_dirblksize);
- return error;
-}
-
-/*
- * Add a name to a shortform directory.
- * There are two algorithms, "easy" and "hard" which we decide on
- * before changing anything.
- * Convert to block form if necessary, if the new entry won't fit.
- */
-int /* error */
-xfs_dir2_sf_addname(
- xfs_da_args_t *args) /* operation arguments */
-{
- int add_entsize; /* size of the new entry */
- xfs_inode_t *dp; /* incore directory inode */
- int error; /* error return value */
- int incr_isize; /* total change in size */
- int new_isize; /* di_size after adding name */
- int objchange; /* changing to 8-byte inodes */
- xfs_dir2_data_aoff_t offset = 0; /* offset for new entry */
- int old_isize; /* di_size before adding name */
- int pick; /* which algorithm to use */
- xfs_dir2_sf_t *sfp; /* shortform structure */
- xfs_dir2_sf_entry_t *sfep = NULL; /* shortform entry */
-
- xfs_dir2_trace_args("sf_addname", args);
- ASSERT(xfs_dir2_sf_lookup(args) == ENOENT);
- dp = args->dp;
- ASSERT(dp->i_df.if_flags & XFS_IFINLINE);
- /*
- * Make sure the shortform value has some of its header.
- */
- if (dp->i_d.di_size < offsetof(xfs_dir2_sf_hdr_t, parent)) {
- ASSERT(XFS_FORCED_SHUTDOWN(dp->i_mount));
- return XFS_ERROR(EIO);
- }
- ASSERT(dp->i_df.if_bytes == dp->i_d.di_size);
- ASSERT(dp->i_df.if_u1.if_data != NULL);
- sfp = (xfs_dir2_sf_t *)dp->i_df.if_u1.if_data;
- ASSERT(dp->i_d.di_size >= XFS_DIR2_SF_HDR_SIZE(sfp->hdr.i8count));
- /*
- * Compute entry (and change in) size.
- */
- add_entsize = XFS_DIR2_SF_ENTSIZE_BYNAME(sfp, args->namelen);
- incr_isize = add_entsize;
- objchange = 0;
-#if XFS_BIG_INUMS
- /*
- * Do we have to change to 8 byte inodes?
- */
- if (args->inumber > XFS_DIR2_MAX_SHORT_INUM && sfp->hdr.i8count == 0) {
- /*
- * Yes, adjust the entry size and the total size.
- */
- add_entsize +=
- (uint)sizeof(xfs_dir2_ino8_t) -
- (uint)sizeof(xfs_dir2_ino4_t);
- incr_isize +=
- (sfp->hdr.count + 2) *
- ((uint)sizeof(xfs_dir2_ino8_t) -
- (uint)sizeof(xfs_dir2_ino4_t));
- objchange = 1;
- }
-#endif
- old_isize = (int)dp->i_d.di_size;
- new_isize = old_isize + incr_isize;
- /*
- * Won't fit as shortform any more (due to size),
- * or the pick routine says it won't (due to offset values).
- */
- if (new_isize > XFS_IFORK_DSIZE(dp) ||
- (pick =
- xfs_dir2_sf_addname_pick(args, objchange, &sfep, &offset)) == 0) {
- /*
- * Just checking or no space reservation, it doesn't fit.
- */
- if (args->justcheck || args->total == 0)
- return XFS_ERROR(ENOSPC);
- /*
- * Convert to block form then add the name.
- */
- error = xfs_dir2_sf_to_block(args);
- if (error)
- return error;
- return xfs_dir2_block_addname(args);
- }
- /*
- * Just checking, it fits.
- */
- if (args->justcheck)
- return 0;
- /*
- * Do it the easy way - just add it at the end.
- */
- if (pick == 1)
- xfs_dir2_sf_addname_easy(args, sfep, offset, new_isize);
- /*
- * Do it the hard way - look for a place to insert the new entry.
- * Convert to 8 byte inode numbers first if necessary.
- */
- else {
- ASSERT(pick == 2);
-#if XFS_BIG_INUMS
- if (objchange)
- xfs_dir2_sf_toino8(args);
-#endif
- xfs_dir2_sf_addname_hard(args, objchange, new_isize);
- }
- xfs_trans_log_inode(args->trans, dp, XFS_ILOG_CORE | XFS_ILOG_DDATA);
- return 0;
-}
-
-/*
- * Add the new entry the "easy" way.
- * This is copying the old directory and adding the new entry at the end.
- * Since it's sorted by "offset" we need room after the last offset
- * that's already there, and then room to convert to a block directory.
- * This is already checked by the pick routine.
- */
-static void
-xfs_dir2_sf_addname_easy(
- xfs_da_args_t *args, /* operation arguments */
- xfs_dir2_sf_entry_t *sfep, /* pointer to new entry */
- xfs_dir2_data_aoff_t offset, /* offset to use for new ent */
- int new_isize) /* new directory size */
-{
- int byteoff; /* byte offset in sf dir */
- xfs_inode_t *dp; /* incore directory inode */
- xfs_dir2_sf_t *sfp; /* shortform structure */
-
- dp = args->dp;
-
- sfp = (xfs_dir2_sf_t *)dp->i_df.if_u1.if_data;
- byteoff = (int)((char *)sfep - (char *)sfp);
- /*
- * Grow the in-inode space.
- */
- xfs_idata_realloc(dp, XFS_DIR2_SF_ENTSIZE_BYNAME(sfp, args->namelen),
- XFS_DATA_FORK);
- /*
- * Need to set up again due to realloc of the inode data.
- */
- sfp = (xfs_dir2_sf_t *)dp->i_df.if_u1.if_data;
- sfep = (xfs_dir2_sf_entry_t *)((char *)sfp + byteoff);
- /*
- * Fill in the new entry.
- */
- sfep->namelen = args->namelen;
- XFS_DIR2_SF_PUT_OFFSET(sfep, offset);
- memcpy(sfep->name, args->name, sfep->namelen);
- XFS_DIR2_SF_PUT_INUMBER(sfp, &args->inumber,
- XFS_DIR2_SF_INUMBERP(sfep));
- /*
- * Update the header and inode.
- */
- sfp->hdr.count++;
-#if XFS_BIG_INUMS
- if (args->inumber > XFS_DIR2_MAX_SHORT_INUM)
- sfp->hdr.i8count++;
-#endif
- dp->i_d.di_size = new_isize;
- xfs_dir2_sf_check(args);
-}
-
-/*
- * Add the new entry the "hard" way.
- * The caller has already converted to 8 byte inode numbers if necessary,
- * in which case we need to leave the i8count at 1.
- * Find a hole that the new entry will fit into, and copy
- * the first part of the entries, the new entry, and the last part of
- * the entries.
- */
-/* ARGSUSED */
-static void
-xfs_dir2_sf_addname_hard(
- xfs_da_args_t *args, /* operation arguments */
- int objchange, /* changing inode number size */
- int new_isize) /* new directory size */
-{
- int add_datasize; /* data size need for new ent */
- char *buf; /* buffer for old */
- xfs_inode_t *dp; /* incore directory inode */
- int eof; /* reached end of old dir */
- int nbytes; /* temp for byte copies */
- xfs_dir2_data_aoff_t new_offset; /* next offset value */
- xfs_dir2_data_aoff_t offset; /* current offset value */
- int old_isize; /* previous di_size */
- xfs_dir2_sf_entry_t *oldsfep; /* entry in original dir */
- xfs_dir2_sf_t *oldsfp; /* original shortform dir */
- xfs_dir2_sf_entry_t *sfep; /* entry in new dir */
- xfs_dir2_sf_t *sfp; /* new shortform dir */
-
- /*
- * Copy the old directory to the stack buffer.
- */
- dp = args->dp;
-
- sfp = (xfs_dir2_sf_t *)dp->i_df.if_u1.if_data;
- old_isize = (int)dp->i_d.di_size;
- buf = kmem_alloc(old_isize, KM_SLEEP);
- oldsfp = (xfs_dir2_sf_t *)buf;
- memcpy(oldsfp, sfp, old_isize);
- /*
- * Loop over the old directory finding the place we're going
- * to insert the new entry.
- * If it's going to end up at the end then oldsfep will point there.
- */
- for (offset = XFS_DIR2_DATA_FIRST_OFFSET,
- oldsfep = XFS_DIR2_SF_FIRSTENTRY(oldsfp),
- add_datasize = XFS_DIR2_DATA_ENTSIZE(args->namelen),
- eof = (char *)oldsfep == &buf[old_isize];
- !eof;
- offset = new_offset + XFS_DIR2_DATA_ENTSIZE(oldsfep->namelen),
- oldsfep = XFS_DIR2_SF_NEXTENTRY(oldsfp, oldsfep),
- eof = (char *)oldsfep == &buf[old_isize]) {
- new_offset = XFS_DIR2_SF_GET_OFFSET(oldsfep);
- if (offset + add_datasize <= new_offset)
- break;
- }
- /*
- * Get rid of the old directory, then allocate space for
- * the new one. We do this so xfs_idata_realloc won't copy
- * the data.
- */
- xfs_idata_realloc(dp, -old_isize, XFS_DATA_FORK);
- xfs_idata_realloc(dp, new_isize, XFS_DATA_FORK);
- /*
- * Reset the pointer since the buffer was reallocated.
- */
- sfp = (xfs_dir2_sf_t *)dp->i_df.if_u1.if_data;
- /*
- * Copy the first part of the directory, including the header.
- */
- nbytes = (int)((char *)oldsfep - (char *)oldsfp);
- memcpy(sfp, oldsfp, nbytes);
- sfep = (xfs_dir2_sf_entry_t *)((char *)sfp + nbytes);
- /*
- * Fill in the new entry, and update the header counts.
- */
- sfep->namelen = args->namelen;
- XFS_DIR2_SF_PUT_OFFSET(sfep, offset);
- memcpy(sfep->name, args->name, sfep->namelen);
- XFS_DIR2_SF_PUT_INUMBER(sfp, &args->inumber,
- XFS_DIR2_SF_INUMBERP(sfep));
- sfp->hdr.count++;
-#if XFS_BIG_INUMS
- if (args->inumber > XFS_DIR2_MAX_SHORT_INUM && !objchange)
- sfp->hdr.i8count++;
-#endif
- /*
- * If there's more left to copy, do that.
- */
- if (!eof) {
- sfep = XFS_DIR2_SF_NEXTENTRY(sfp, sfep);
- memcpy(sfep, oldsfep, old_isize - nbytes);
- }
- kmem_free(buf, old_isize);
- dp->i_d.di_size = new_isize;
- xfs_dir2_sf_check(args);
-}
-
-/*
- * Decide if the new entry will fit at all.
- * If it will fit, pick between adding the new entry to the end (easy)
- * or somewhere else (hard).
- * Return 0 (won't fit), 1 (easy), 2 (hard).
- */
-/*ARGSUSED*/
-static int /* pick result */
-xfs_dir2_sf_addname_pick(
- xfs_da_args_t *args, /* operation arguments */
- int objchange, /* inode # size changes */
- xfs_dir2_sf_entry_t **sfepp, /* out(1): new entry ptr */
- xfs_dir2_data_aoff_t *offsetp) /* out(1): new offset */
-{
- xfs_inode_t *dp; /* incore directory inode */
- int holefit; /* found hole it will fit in */
- int i; /* entry number */
- xfs_mount_t *mp; /* filesystem mount point */
- xfs_dir2_data_aoff_t offset; /* data block offset */
- xfs_dir2_sf_entry_t *sfep; /* shortform entry */
- xfs_dir2_sf_t *sfp; /* shortform structure */
- int size; /* entry's data size */
- int used; /* data bytes used */
-
- dp = args->dp;
- mp = dp->i_mount;
-
- sfp = (xfs_dir2_sf_t *)dp->i_df.if_u1.if_data;
- size = XFS_DIR2_DATA_ENTSIZE(args->namelen);
- offset = XFS_DIR2_DATA_FIRST_OFFSET;
- sfep = XFS_DIR2_SF_FIRSTENTRY(sfp);
- holefit = 0;
- /*
- * Loop over sf entries.
- * Keep track of data offset and whether we've seen a place
- * to insert the new entry.
- */
- for (i = 0; i < sfp->hdr.count; i++) {
- if (!holefit)
- holefit = offset + size <= XFS_DIR2_SF_GET_OFFSET(sfep);
- offset = XFS_DIR2_SF_GET_OFFSET(sfep) +
- XFS_DIR2_DATA_ENTSIZE(sfep->namelen);
- sfep = XFS_DIR2_SF_NEXTENTRY(sfp, sfep);
- }
- /*
- * Calculate data bytes used excluding the new entry, if this
- * was a data block (block form directory).
- */
- used = offset +
- (sfp->hdr.count + 3) * (uint)sizeof(xfs_dir2_leaf_entry_t) +
- (uint)sizeof(xfs_dir2_block_tail_t);
- /*
- * If it won't fit in a block form then we can't insert it,
- * we'll go back, convert to block, then try the insert and convert
- * to leaf.
- */
- if (used + (holefit ? 0 : size) > mp->m_dirblksize)
- return 0;
- /*
- * If changing the inode number size, do it the hard way.
- */
-#if XFS_BIG_INUMS
- if (objchange) {
- return 2;
- }
-#else
- ASSERT(objchange == 0);
-#endif
- /*
- * If it won't fit at the end then do it the hard way (use the hole).
- */
- if (used + size > mp->m_dirblksize)
- return 2;
- /*
- * Do it the easy way.
- */
- *sfepp = sfep;
- *offsetp = offset;
- return 1;
-}
-
-#ifdef DEBUG
-/*
- * Check consistency of shortform directory, assert if bad.
- */
-static void
-xfs_dir2_sf_check(
- xfs_da_args_t *args) /* operation arguments */
-{
- xfs_inode_t *dp; /* incore directory inode */
- int i; /* entry number */
- int i8count; /* number of big inode#s */
- xfs_ino_t ino; /* entry inode number */
- int offset; /* data offset */
- xfs_dir2_sf_entry_t *sfep; /* shortform dir entry */
- xfs_dir2_sf_t *sfp; /* shortform structure */
-
- dp = args->dp;
-
- sfp = (xfs_dir2_sf_t *)dp->i_df.if_u1.if_data;
- offset = XFS_DIR2_DATA_FIRST_OFFSET;
- ino = XFS_DIR2_SF_GET_INUMBER(sfp, &sfp->hdr.parent);
- i8count = ino > XFS_DIR2_MAX_SHORT_INUM;
-
- for (i = 0, sfep = XFS_DIR2_SF_FIRSTENTRY(sfp);
- i < sfp->hdr.count;
- i++, sfep = XFS_DIR2_SF_NEXTENTRY(sfp, sfep)) {
- ASSERT(XFS_DIR2_SF_GET_OFFSET(sfep) >= offset);
- ino = XFS_DIR2_SF_GET_INUMBER(sfp, XFS_DIR2_SF_INUMBERP(sfep));
- i8count += ino > XFS_DIR2_MAX_SHORT_INUM;
- offset =
- XFS_DIR2_SF_GET_OFFSET(sfep) +
- XFS_DIR2_DATA_ENTSIZE(sfep->namelen);
- }
- ASSERT(i8count == sfp->hdr.i8count);
- ASSERT(XFS_BIG_INUMS || i8count == 0);
- ASSERT((char *)sfep - (char *)sfp == dp->i_d.di_size);
- ASSERT(offset +
- (sfp->hdr.count + 2) * (uint)sizeof(xfs_dir2_leaf_entry_t) +
- (uint)sizeof(xfs_dir2_block_tail_t) <=
- dp->i_mount->m_dirblksize);
-}
-#endif /* DEBUG */
-
-/*
- * Create a new (shortform) directory.
- */
-int /* error, always 0 */
-xfs_dir2_sf_create(
- xfs_da_args_t *args, /* operation arguments */
- xfs_ino_t pino) /* parent inode number */
-{
- xfs_inode_t *dp; /* incore directory inode */
- int i8count; /* parent inode is an 8-byte number */
- xfs_dir2_sf_t *sfp; /* shortform structure */
- int size; /* directory size */
-
- xfs_dir2_trace_args_i("sf_create", args, pino);
- dp = args->dp;
-
- ASSERT(dp != NULL);
- ASSERT(dp->i_d.di_size == 0);
- /*
- * If it's currently a zero-length extent file,
- * convert it to local format.
- */
- if (dp->i_d.di_format == XFS_DINODE_FMT_EXTENTS) {
- dp->i_df.if_flags &= ~XFS_IFEXTENTS; /* just in case */
- dp->i_d.di_format = XFS_DINODE_FMT_LOCAL;
- xfs_trans_log_inode(args->trans, dp, XFS_ILOG_CORE);
- dp->i_df.if_flags |= XFS_IFINLINE;
- }
- ASSERT(dp->i_df.if_flags & XFS_IFINLINE);
- ASSERT(dp->i_df.if_bytes == 0);
- i8count = pino > XFS_DIR2_MAX_SHORT_INUM;
- size = XFS_DIR2_SF_HDR_SIZE(i8count);
- /*
- * Make a buffer for the data.
- */
- xfs_idata_realloc(dp, size, XFS_DATA_FORK);
- /*
- * Fill in the header,
- */
- sfp = (xfs_dir2_sf_t *)dp->i_df.if_u1.if_data;
- sfp->hdr.i8count = i8count;
- /*
- * Now can put in the inode number, since i8count is set.
- */
- XFS_DIR2_SF_PUT_INUMBER(sfp, &pino, &sfp->hdr.parent);
- sfp->hdr.count = 0;
- dp->i_d.di_size = size;
- xfs_dir2_sf_check(args);
- xfs_trans_log_inode(args->trans, dp, XFS_ILOG_CORE | XFS_ILOG_DDATA);
- return 0;
-}
-
-int /* error */
-xfs_dir2_sf_getdents(
- xfs_inode_t *dp, /* incore directory inode */
- uio_t *uio, /* caller's buffer control */
- int *eofp, /* eof reached? (out) */
- xfs_dirent_t *dbp, /* caller's buffer */
- xfs_dir2_put_t put) /* abi's formatting function */
-{
- int error; /* error return value */
- int i; /* shortform entry number */
- xfs_mount_t *mp; /* filesystem mount point */
- xfs_dir2_dataptr_t off; /* current entry's offset */
- xfs_dir2_put_args_t p; /* arg package for put rtn */
- xfs_dir2_sf_entry_t *sfep; /* shortform directory entry */
- xfs_dir2_sf_t *sfp; /* shortform structure */
- xfs_off_t dir_offset;
-
- mp = dp->i_mount;
-
- ASSERT(dp->i_df.if_flags & XFS_IFINLINE);
- /*
- * Give up if the directory is way too short.
- */
- if (dp->i_d.di_size < offsetof(xfs_dir2_sf_hdr_t, parent)) {
- ASSERT(XFS_FORCED_SHUTDOWN(mp));
- return XFS_ERROR(EIO);
- }
-
- dir_offset = uio->uio_offset;
-
- ASSERT(dp->i_df.if_bytes == dp->i_d.di_size);
- ASSERT(dp->i_df.if_u1.if_data != NULL);
-
- sfp = (xfs_dir2_sf_t *)dp->i_df.if_u1.if_data;
-
- ASSERT(dp->i_d.di_size >= XFS_DIR2_SF_HDR_SIZE(sfp->hdr.i8count));
-
- /*
- * If the block number in the offset is out of range, we're done.
- */
- if (XFS_DIR2_DATAPTR_TO_DB(mp, dir_offset) > mp->m_dirdatablk) {
- *eofp = 1;
- return 0;
- }
-
- /*
- * Set up putargs structure.
- */
- p.dbp = dbp;
- p.put = put;
- p.uio = uio;
- /*
- * Put . entry unless we're starting past it.
- */
- if (dir_offset <=
- XFS_DIR2_DB_OFF_TO_DATAPTR(mp, mp->m_dirdatablk,
- XFS_DIR2_DATA_DOT_OFFSET)) {
- p.cook = XFS_DIR2_DB_OFF_TO_DATAPTR(mp, 0,
- XFS_DIR2_DATA_DOTDOT_OFFSET);
- p.ino = dp->i_ino;
-#if XFS_BIG_INUMS
- p.ino += mp->m_inoadd;
-#endif
- p.name = ".";
- p.namelen = 1;
-
- error = p.put(&p);
-
- if (!p.done) {
- uio->uio_offset =
- XFS_DIR2_DB_OFF_TO_DATAPTR(mp, mp->m_dirdatablk,
- XFS_DIR2_DATA_DOT_OFFSET);
- return error;
- }
- }
-
- /*
- * Put .. entry unless we're starting past it.
- */
- if (dir_offset <=
- XFS_DIR2_DB_OFF_TO_DATAPTR(mp, mp->m_dirdatablk,
- XFS_DIR2_DATA_DOTDOT_OFFSET)) {
- p.cook = XFS_DIR2_DB_OFF_TO_DATAPTR(mp, mp->m_dirdatablk,
- XFS_DIR2_DATA_FIRST_OFFSET);
- p.ino = XFS_DIR2_SF_GET_INUMBER(sfp, &sfp->hdr.parent);
-#if XFS_BIG_INUMS
- p.ino += mp->m_inoadd;
-#endif
- p.name = "..";
- p.namelen = 2;
-
- error = p.put(&p);
-
- if (!p.done) {
- uio->uio_offset =
- XFS_DIR2_DB_OFF_TO_DATAPTR(mp, mp->m_dirdatablk,
- XFS_DIR2_DATA_DOTDOT_OFFSET);
- return error;
- }
- }
-
- /*
- * Loop while there are more entries and put'ing works.
- */
- for (i = 0, sfep = XFS_DIR2_SF_FIRSTENTRY(sfp);
- i < sfp->hdr.count;
- i++, sfep = XFS_DIR2_SF_NEXTENTRY(sfp, sfep)) {
-
- off = XFS_DIR2_DB_OFF_TO_DATAPTR(mp, mp->m_dirdatablk,
- XFS_DIR2_SF_GET_OFFSET(sfep));
-
- if (dir_offset > off)
- continue;
-
- p.namelen = sfep->namelen;
-
- p.cook = XFS_DIR2_DB_OFF_TO_DATAPTR(mp, mp->m_dirdatablk,
- XFS_DIR2_SF_GET_OFFSET(sfep) +
- XFS_DIR2_DATA_ENTSIZE(p.namelen));
-
- p.ino = XFS_DIR2_SF_GET_INUMBER(sfp, XFS_DIR2_SF_INUMBERP(sfep));
-#if XFS_BIG_INUMS
- p.ino += mp->m_inoadd;
-#endif
- p.name = (char *)sfep->name;
-
- error = p.put(&p);
-
- if (!p.done) {
- uio->uio_offset = off;
- return error;
- }
- }
-
- /*
- * They all fit.
- */
- *eofp = 1;
-
- uio->uio_offset =
- XFS_DIR2_DB_OFF_TO_DATAPTR(mp, mp->m_dirdatablk + 1, 0);
-
- return 0;
-}
-
-/*
- * Lookup an entry in a shortform directory.
- * Returns EEXIST if found, ENOENT if not found.
- */
-int /* error */
-xfs_dir2_sf_lookup(
- xfs_da_args_t *args) /* operation arguments */
-{
- xfs_inode_t *dp; /* incore directory inode */
- int i; /* entry index */
- xfs_dir2_sf_entry_t *sfep; /* shortform directory entry */
- xfs_dir2_sf_t *sfp; /* shortform structure */
-
- xfs_dir2_trace_args("sf_lookup", args);
- xfs_dir2_sf_check(args);
- dp = args->dp;
-
- ASSERT(dp->i_df.if_flags & XFS_IFINLINE);
- /*
- * Bail out if the directory is way too short.
- */
- if (dp->i_d.di_size < offsetof(xfs_dir2_sf_hdr_t, parent)) {
- ASSERT(XFS_FORCED_SHUTDOWN(dp->i_mount));
- return XFS_ERROR(EIO);
- }
- ASSERT(dp->i_df.if_bytes == dp->i_d.di_size);
- ASSERT(dp->i_df.if_u1.if_data != NULL);
- sfp = (xfs_dir2_sf_t *)dp->i_df.if_u1.if_data;
- ASSERT(dp->i_d.di_size >= XFS_DIR2_SF_HDR_SIZE(sfp->hdr.i8count));
- /*
- * Special case for .
- */
- if (args->namelen == 1 && args->name[0] == '.') {
- args->inumber = dp->i_ino;
- return XFS_ERROR(EEXIST);
- }
- /*
- * Special case for ..
- */
- if (args->namelen == 2 &&
- args->name[0] == '.' && args->name[1] == '.') {
- args->inumber = XFS_DIR2_SF_GET_INUMBER(sfp, &sfp->hdr.parent);
- return XFS_ERROR(EEXIST);
- }
- /*
- * Loop over all the entries trying to match ours.
- */
- for (i = 0, sfep = XFS_DIR2_SF_FIRSTENTRY(sfp);
- i < sfp->hdr.count;
- i++, sfep = XFS_DIR2_SF_NEXTENTRY(sfp, sfep)) {
- if (sfep->namelen == args->namelen &&
- sfep->name[0] == args->name[0] &&
- memcmp(args->name, sfep->name, args->namelen) == 0) {
- args->inumber =
- XFS_DIR2_SF_GET_INUMBER(sfp,
- XFS_DIR2_SF_INUMBERP(sfep));
- return XFS_ERROR(EEXIST);
- }
- }
- /*
- * Didn't find it.
- */
- ASSERT(args->oknoent);
- return XFS_ERROR(ENOENT);
-}
-
-/*
- * Remove an entry from a shortform directory.
- */
-int /* error */
-xfs_dir2_sf_removename(
- xfs_da_args_t *args)
-{
- int byteoff; /* offset of removed entry */
- xfs_inode_t *dp; /* incore directory inode */
- int entsize; /* this entry's size */
- int i; /* shortform entry index */
- int newsize; /* new inode size */
- int oldsize; /* old inode size */
- xfs_dir2_sf_entry_t *sfep; /* shortform directory entry */
- xfs_dir2_sf_t *sfp; /* shortform structure */
-
- xfs_dir2_trace_args("sf_removename", args);
- dp = args->dp;
-
- ASSERT(dp->i_df.if_flags & XFS_IFINLINE);
- oldsize = (int)dp->i_d.di_size;
- /*
- * Bail out if the directory is way too short.
- */
- if (oldsize < offsetof(xfs_dir2_sf_hdr_t, parent)) {
- ASSERT(XFS_FORCED_SHUTDOWN(dp->i_mount));
- return XFS_ERROR(EIO);
- }
- ASSERT(dp->i_df.if_bytes == oldsize);
- ASSERT(dp->i_df.if_u1.if_data != NULL);
- sfp = (xfs_dir2_sf_t *)dp->i_df.if_u1.if_data;
- ASSERT(oldsize >= XFS_DIR2_SF_HDR_SIZE(sfp->hdr.i8count));
- /*
- * Loop over the old directory entries.
- * Find the one we're deleting.
- */
- for (i = 0, sfep = XFS_DIR2_SF_FIRSTENTRY(sfp);
- i < sfp->hdr.count;
- i++, sfep = XFS_DIR2_SF_NEXTENTRY(sfp, sfep)) {
- if (sfep->namelen == args->namelen &&
- sfep->name[0] == args->name[0] &&
- memcmp(sfep->name, args->name, args->namelen) == 0) {
- ASSERT(XFS_DIR2_SF_GET_INUMBER(sfp,
- XFS_DIR2_SF_INUMBERP(sfep)) ==
- args->inumber);
- break;
- }
- }
- /*
- * Didn't find it.
- */
- if (i == sfp->hdr.count) {
- return XFS_ERROR(ENOENT);
- }
- /*
- * Calculate sizes.
- */
- byteoff = (int)((char *)sfep - (char *)sfp);
- entsize = XFS_DIR2_SF_ENTSIZE_BYNAME(sfp, args->namelen);
- newsize = oldsize - entsize;
- /*
- * Copy the part if any after the removed entry, sliding it down.
- */
- if (byteoff + entsize < oldsize)
- memmove((char *)sfp + byteoff, (char *)sfp + byteoff + entsize,
- oldsize - (byteoff + entsize));
- /*
- * Fix up the header and file size.
- */
- sfp->hdr.count--;
- dp->i_d.di_size = newsize;
- /*
- * Reallocate, making it smaller.
- */
- xfs_idata_realloc(dp, newsize - oldsize, XFS_DATA_FORK);
- sfp = (xfs_dir2_sf_t *)dp->i_df.if_u1.if_data;
-#if XFS_BIG_INUMS
- /*
- * Are we changing inode number size?
- */
- if (args->inumber > XFS_DIR2_MAX_SHORT_INUM) {
- if (sfp->hdr.i8count == 1)
- xfs_dir2_sf_toino4(args);
- else
- sfp->hdr.i8count--;
- }
-#endif
- xfs_dir2_sf_check(args);
- xfs_trans_log_inode(args->trans, dp, XFS_ILOG_CORE | XFS_ILOG_DDATA);
- return 0;
-}
-
-/*
- * Replace the inode number of an entry in a shortform directory.
- */
-int /* error */
-xfs_dir2_sf_replace(
- xfs_da_args_t *args) /* operation arguments */
-{
- xfs_inode_t *dp; /* incore directory inode */
- int i; /* entry index */
-#if XFS_BIG_INUMS || defined(DEBUG)
- xfs_ino_t ino=0; /* entry old inode number */
-#endif
-#if XFS_BIG_INUMS
- int i8elevated; /* sf_toino8 set i8count=1 */
-#endif
- xfs_dir2_sf_entry_t *sfep; /* shortform directory entry */
- xfs_dir2_sf_t *sfp; /* shortform structure */
-
- xfs_dir2_trace_args("sf_replace", args);
- dp = args->dp;
-
- ASSERT(dp->i_df.if_flags & XFS_IFINLINE);
- /*
- * Bail out if the shortform directory is way too small.
- */
- if (dp->i_d.di_size < offsetof(xfs_dir2_sf_hdr_t, parent)) {
- ASSERT(XFS_FORCED_SHUTDOWN(dp->i_mount));
- return XFS_ERROR(EIO);
- }
- ASSERT(dp->i_df.if_bytes == dp->i_d.di_size);
- ASSERT(dp->i_df.if_u1.if_data != NULL);
- sfp = (xfs_dir2_sf_t *)dp->i_df.if_u1.if_data;
- ASSERT(dp->i_d.di_size >= XFS_DIR2_SF_HDR_SIZE(sfp->hdr.i8count));
-#if XFS_BIG_INUMS
- /*
- * New inode number is large, and need to convert to 8-byte inodes.
- */
- if (args->inumber > XFS_DIR2_MAX_SHORT_INUM && sfp->hdr.i8count == 0) {
- int error; /* error return value */
- int newsize; /* new inode size */
-
- newsize =
- dp->i_df.if_bytes +
- (sfp->hdr.count + 1) *
- ((uint)sizeof(xfs_dir2_ino8_t) -
- (uint)sizeof(xfs_dir2_ino4_t));
- /*
- * Won't fit as shortform, convert to block then do replace.
- */
- if (newsize > XFS_IFORK_DSIZE(dp)) {
- error = xfs_dir2_sf_to_block(args);
- if (error) {
- return error;
- }
- return xfs_dir2_block_replace(args);
- }
- /*
- * Still fits, convert to 8-byte now.
- */
- xfs_dir2_sf_toino8(args);
- i8elevated = 1;
- sfp = (xfs_dir2_sf_t *)dp->i_df.if_u1.if_data;
- } else
- i8elevated = 0;
-#endif
- ASSERT(args->namelen != 1 || args->name[0] != '.');
- /*
- * Replace ..'s entry.
- */
- if (args->namelen == 2 &&
- args->name[0] == '.' && args->name[1] == '.') {
-#if XFS_BIG_INUMS || defined(DEBUG)
- ino = XFS_DIR2_SF_GET_INUMBER(sfp, &sfp->hdr.parent);
- ASSERT(args->inumber != ino);
-#endif
- XFS_DIR2_SF_PUT_INUMBER(sfp, &args->inumber, &sfp->hdr.parent);
- }
- /*
- * Normal entry, look for the name.
- */
- else {
- for (i = 0, sfep = XFS_DIR2_SF_FIRSTENTRY(sfp);
- i < sfp->hdr.count;
- i++, sfep = XFS_DIR2_SF_NEXTENTRY(sfp, sfep)) {
- if (sfep->namelen == args->namelen &&
- sfep->name[0] == args->name[0] &&
- memcmp(args->name, sfep->name, args->namelen) == 0) {
-#if XFS_BIG_INUMS || defined(DEBUG)
- ino = XFS_DIR2_SF_GET_INUMBER(sfp,
- XFS_DIR2_SF_INUMBERP(sfep));
- ASSERT(args->inumber != ino);
-#endif
- XFS_DIR2_SF_PUT_INUMBER(sfp, &args->inumber,
- XFS_DIR2_SF_INUMBERP(sfep));
- break;
- }
- }
- /*
- * Didn't find it.
- */
- if (i == sfp->hdr.count) {
- ASSERT(args->oknoent);
-#if XFS_BIG_INUMS
- if (i8elevated)
- xfs_dir2_sf_toino4(args);
-#endif
- return XFS_ERROR(ENOENT);
- }
- }
-#if XFS_BIG_INUMS
- /*
- * See if the old number was large, the new number is small.
- */
- if (ino > XFS_DIR2_MAX_SHORT_INUM &&
- args->inumber <= XFS_DIR2_MAX_SHORT_INUM) {
- /*
- * And the old count was one, so need to convert to small.
- */
- if (sfp->hdr.i8count == 1)
- xfs_dir2_sf_toino4(args);
- else
- sfp->hdr.i8count--;
- }
- /*
- * See if the old number was small, the new number is large.
- */
- if (ino <= XFS_DIR2_MAX_SHORT_INUM &&
- args->inumber > XFS_DIR2_MAX_SHORT_INUM) {
- /*
- * add to the i8count unless we just converted to 8-byte
- * inodes (which does an implied i8count = 1)
- */
- ASSERT(sfp->hdr.i8count != 0);
- if (!i8elevated)
- sfp->hdr.i8count++;
- }
-#endif
- xfs_dir2_sf_check(args);
- xfs_trans_log_inode(args->trans, dp, XFS_ILOG_DDATA);
- return 0;
-}
-
-#if XFS_BIG_INUMS
-/*
- * Convert from 8-byte inode numbers to 4-byte inode numbers.
- * The last 8-byte inode number is gone, but the count is still 1.
- */
-static void
-xfs_dir2_sf_toino4(
- xfs_da_args_t *args) /* operation arguments */
-{
- char *buf; /* old dir's buffer */
- xfs_inode_t *dp; /* incore directory inode */
- int i; /* entry index */
- xfs_ino_t ino; /* entry inode number */
- int newsize; /* new inode size */
- xfs_dir2_sf_entry_t *oldsfep; /* old sf entry */
- xfs_dir2_sf_t *oldsfp; /* old sf directory */
- int oldsize; /* old inode size */
- xfs_dir2_sf_entry_t *sfep; /* new sf entry */
- xfs_dir2_sf_t *sfp; /* new sf directory */
-
- xfs_dir2_trace_args("sf_toino4", args);
- dp = args->dp;
-
- /*
- * Copy the old directory to the buffer.
- * Then nuke it from the inode, and add the new buffer to the inode.
- * Don't want xfs_idata_realloc copying the data here.
- */
- oldsize = dp->i_df.if_bytes;
- buf = kmem_alloc(oldsize, KM_SLEEP);
- oldsfp = (xfs_dir2_sf_t *)dp->i_df.if_u1.if_data;
- ASSERT(oldsfp->hdr.i8count == 1);
- memcpy(buf, oldsfp, oldsize);
- /*
- * Compute the new inode size.
- */
- newsize =
- oldsize -
- (oldsfp->hdr.count + 1) *
- ((uint)sizeof(xfs_dir2_ino8_t) - (uint)sizeof(xfs_dir2_ino4_t));
- xfs_idata_realloc(dp, -oldsize, XFS_DATA_FORK);
- xfs_idata_realloc(dp, newsize, XFS_DATA_FORK);
- /*
- * Reset our pointers, the data has moved.
- */
- oldsfp = (xfs_dir2_sf_t *)buf;
- sfp = (xfs_dir2_sf_t *)dp->i_df.if_u1.if_data;
- /*
- * Fill in the new header.
- */
- sfp->hdr.count = oldsfp->hdr.count;
- sfp->hdr.i8count = 0;
- ino = XFS_DIR2_SF_GET_INUMBER(oldsfp, &oldsfp->hdr.parent);
- XFS_DIR2_SF_PUT_INUMBER(sfp, &ino, &sfp->hdr.parent);
- /*
- * Copy the entries field by field.
- */
- for (i = 0, sfep = XFS_DIR2_SF_FIRSTENTRY(sfp),
- oldsfep = XFS_DIR2_SF_FIRSTENTRY(oldsfp);
- i < sfp->hdr.count;
- i++, sfep = XFS_DIR2_SF_NEXTENTRY(sfp, sfep),
- oldsfep = XFS_DIR2_SF_NEXTENTRY(oldsfp, oldsfep)) {
- sfep->namelen = oldsfep->namelen;
- sfep->offset = oldsfep->offset;
- memcpy(sfep->name, oldsfep->name, sfep->namelen);
- ino = XFS_DIR2_SF_GET_INUMBER(oldsfp,
- XFS_DIR2_SF_INUMBERP(oldsfep));
- XFS_DIR2_SF_PUT_INUMBER(sfp, &ino, XFS_DIR2_SF_INUMBERP(sfep));
- }
- /*
- * Clean up the inode.
- */
- kmem_free(buf, oldsize);
- dp->i_d.di_size = newsize;
- xfs_trans_log_inode(args->trans, dp, XFS_ILOG_CORE | XFS_ILOG_DDATA);
-}
-
-/*
- * Convert from 4-byte inode numbers to 8-byte inode numbers.
- * The new 8-byte inode number is not there yet, we leave with the
- * count 1 but no corresponding entry.
- */
-static void
-xfs_dir2_sf_toino8(
- xfs_da_args_t *args) /* operation arguments */
-{
- char *buf; /* old dir's buffer */
- xfs_inode_t *dp; /* incore directory inode */
- int i; /* entry index */
- xfs_ino_t ino; /* entry inode number */
- int newsize; /* new inode size */
- xfs_dir2_sf_entry_t *oldsfep; /* old sf entry */
- xfs_dir2_sf_t *oldsfp; /* old sf directory */
- int oldsize; /* old inode size */
- xfs_dir2_sf_entry_t *sfep; /* new sf entry */
- xfs_dir2_sf_t *sfp; /* new sf directory */
-
- xfs_dir2_trace_args("sf_toino8", args);
- dp = args->dp;
-
- /*
- * Copy the old directory to the buffer.
- * Then nuke it from the inode, and add the new buffer to the inode.
- * Don't want xfs_idata_realloc copying the data here.
- */
- oldsize = dp->i_df.if_bytes;
- buf = kmem_alloc(oldsize, KM_SLEEP);
- oldsfp = (xfs_dir2_sf_t *)dp->i_df.if_u1.if_data;
- ASSERT(oldsfp->hdr.i8count == 0);
- memcpy(buf, oldsfp, oldsize);
- /*
- * Compute the new inode size.
- */
- newsize =
- oldsize +
- (oldsfp->hdr.count + 1) *
- ((uint)sizeof(xfs_dir2_ino8_t) - (uint)sizeof(xfs_dir2_ino4_t));
- xfs_idata_realloc(dp, -oldsize, XFS_DATA_FORK);
- xfs_idata_realloc(dp, newsize, XFS_DATA_FORK);
- /*
- * Reset our pointers, the data has moved.
- */
- oldsfp = (xfs_dir2_sf_t *)buf;
- sfp = (xfs_dir2_sf_t *)dp->i_df.if_u1.if_data;
- /*
- * Fill in the new header.
- */
- sfp->hdr.count = oldsfp->hdr.count;
- sfp->hdr.i8count = 1;
- ino = XFS_DIR2_SF_GET_INUMBER(oldsfp, &oldsfp->hdr.parent);
- XFS_DIR2_SF_PUT_INUMBER(sfp, &ino, &sfp->hdr.parent);
- /*
- * Copy the entries field by field.
- */
- for (i = 0, sfep = XFS_DIR2_SF_FIRSTENTRY(sfp),
- oldsfep = XFS_DIR2_SF_FIRSTENTRY(oldsfp);
- i < sfp->hdr.count;
- i++, sfep = XFS_DIR2_SF_NEXTENTRY(sfp, sfep),
- oldsfep = XFS_DIR2_SF_NEXTENTRY(oldsfp, oldsfep)) {
- sfep->namelen = oldsfep->namelen;
- sfep->offset = oldsfep->offset;
- memcpy(sfep->name, oldsfep->name, sfep->namelen);
- ino = XFS_DIR2_SF_GET_INUMBER(oldsfp,
- XFS_DIR2_SF_INUMBERP(oldsfep));
- XFS_DIR2_SF_PUT_INUMBER(sfp, &ino, XFS_DIR2_SF_INUMBERP(sfep));
- }
- /*
- * Clean up the inode.
- */
- kmem_free(buf, oldsize);
- dp->i_d.di_size = newsize;
- xfs_trans_log_inode(args->trans, dp, XFS_ILOG_CORE | XFS_ILOG_DDATA);
-}
-#endif /* XFS_BIG_INUMS */
diff --git a/sys/gnu/fs/xfs/xfs_dir2_sf.h b/sys/gnu/fs/xfs/xfs_dir2_sf.h
deleted file mode 100644
index 42f015b..0000000
--- a/sys/gnu/fs/xfs/xfs_dir2_sf.h
+++ /dev/null
@@ -1,195 +0,0 @@
-/*
- * Copyright (c) 2000-2001,2005 Silicon Graphics, Inc.
- * All Rights Reserved.
- *
- * 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.
- *
- * This program is distributed in the hope that it would 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 the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- */
-#ifndef __XFS_DIR2_SF_H__
-#define __XFS_DIR2_SF_H__
-
-/*
- * Directory layout when stored internal to an inode.
- *
- * Small directories are packed as tightly as possible so as to
- * fit into the literal area of the inode.
- */
-
-struct uio;
-struct xfs_dabuf;
-struct xfs_da_args;
-struct xfs_dir2_block;
-struct xfs_inode;
-struct xfs_mount;
-struct xfs_trans;
-
-/*
- * Maximum size of a shortform directory.
- */
-#define XFS_DIR2_SF_MAX_SIZE \
- (XFS_DINODE_MAX_SIZE - (uint)sizeof(xfs_dinode_core_t) - \
- (uint)sizeof(xfs_agino_t))
-
-/*
- * Inode number stored as 8 8-bit values.
- */
-typedef struct { __uint8_t i[8]; } xfs_dir2_ino8_t;
-
-/*
- * Inode number stored as 4 8-bit values.
- * Works a lot of the time, when all the inode numbers in a directory
- * fit in 32 bits.
- */
-typedef struct { __uint8_t i[4]; } xfs_dir2_ino4_t;
-
-typedef union {
- xfs_dir2_ino8_t i8;
- xfs_dir2_ino4_t i4;
-} xfs_dir2_inou_t;
-#define XFS_DIR2_MAX_SHORT_INUM ((xfs_ino_t)0xffffffffULL)
-
-/*
- * Normalized offset (in a data block) of the entry, really xfs_dir2_data_off_t.
- * Only need 16 bits, this is the byte offset into the single block form.
- */
-typedef struct { __uint8_t i[2]; } xfs_dir2_sf_off_t;
-
-/*
- * The parent directory has a dedicated field, and the self-pointer must
- * be calculated on the fly.
- *
- * Entries are packed toward the top as tightly as possible. The header
- * and the elements must be memcpy'd out into a work area to get correct
- * alignment for the inode number fields.
- */
-typedef struct xfs_dir2_sf_hdr {
- __uint8_t count; /* count of entries */
- __uint8_t i8count; /* count of 8-byte inode #s */
- xfs_dir2_inou_t parent; /* parent dir inode number */
-} xfs_dir2_sf_hdr_t;
-
-typedef struct xfs_dir2_sf_entry {
- __uint8_t namelen; /* actual name length */
- xfs_dir2_sf_off_t offset; /* saved offset */
- __uint8_t name[1]; /* name, variable size */
- xfs_dir2_inou_t inumber; /* inode number, var. offset */
-} xfs_dir2_sf_entry_t;
-
-typedef struct xfs_dir2_sf {
- xfs_dir2_sf_hdr_t hdr; /* shortform header */
- xfs_dir2_sf_entry_t list[1]; /* shortform entries */
-} xfs_dir2_sf_t;
-
-#define XFS_DIR2_SF_HDR_SIZE(i8count) xfs_dir2_sf_hdr_size(i8count)
-static inline int xfs_dir2_sf_hdr_size(int i8count)
-{
- return ((uint)sizeof(xfs_dir2_sf_hdr_t) - \
- ((i8count) == 0) * \
- ((uint)sizeof(xfs_dir2_ino8_t) - (uint)sizeof(xfs_dir2_ino4_t)));
-}
-
-#define XFS_DIR2_SF_INUMBERP(sfep) xfs_dir2_sf_inumberp(sfep)
-static inline xfs_dir2_inou_t *xfs_dir2_sf_inumberp(xfs_dir2_sf_entry_t *sfep)
-{
- return (xfs_dir2_inou_t *)&(sfep)->name[(sfep)->namelen];
-}
-
-#define XFS_DIR2_SF_GET_INUMBER(sfp, from) \
- xfs_dir2_sf_get_inumber(sfp, from)
-static inline xfs_intino_t
-xfs_dir2_sf_get_inumber(xfs_dir2_sf_t *sfp, xfs_dir2_inou_t *from)
-{
- return ((sfp)->hdr.i8count == 0 ? \
- (xfs_intino_t)XFS_GET_DIR_INO4((from)->i4) : \
- (xfs_intino_t)XFS_GET_DIR_INO8((from)->i8));
-}
-
-#define XFS_DIR2_SF_PUT_INUMBER(sfp,from,to) \
- xfs_dir2_sf_put_inumber(sfp,from,to)
-static inline void xfs_dir2_sf_put_inumber(xfs_dir2_sf_t *sfp, xfs_ino_t *from,
- xfs_dir2_inou_t *to)
-{
- if ((sfp)->hdr.i8count == 0)
- XFS_PUT_DIR_INO4(*(from), (to)->i4);
- else
- XFS_PUT_DIR_INO8(*(from), (to)->i8);
-}
-
-#define XFS_DIR2_SF_GET_OFFSET(sfep) \
- xfs_dir2_sf_get_offset(sfep)
-static inline xfs_dir2_data_aoff_t
-xfs_dir2_sf_get_offset(xfs_dir2_sf_entry_t *sfep)
-{
- return INT_GET_UNALIGNED_16_BE(&(sfep)->offset.i);
-}
-
-#define XFS_DIR2_SF_PUT_OFFSET(sfep,off) \
- xfs_dir2_sf_put_offset(sfep,off)
-static inline void
-xfs_dir2_sf_put_offset(xfs_dir2_sf_entry_t *sfep, xfs_dir2_data_aoff_t off)
-{
- INT_SET_UNALIGNED_16_BE(&(sfep)->offset.i, off);
-}
-
-#define XFS_DIR2_SF_ENTSIZE_BYNAME(sfp,len) \
- xfs_dir2_sf_entsize_byname(sfp,len)
-static inline int xfs_dir2_sf_entsize_byname(xfs_dir2_sf_t *sfp, int len)
-{
- return ((uint)sizeof(xfs_dir2_sf_entry_t) - 1 + (len) - \
- ((sfp)->hdr.i8count == 0) * \
- ((uint)sizeof(xfs_dir2_ino8_t) - (uint)sizeof(xfs_dir2_ino4_t)));
-}
-
-#define XFS_DIR2_SF_ENTSIZE_BYENTRY(sfp,sfep) \
- xfs_dir2_sf_entsize_byentry(sfp,sfep)
-static inline int
-xfs_dir2_sf_entsize_byentry(xfs_dir2_sf_t *sfp, xfs_dir2_sf_entry_t *sfep)
-{
- return ((uint)sizeof(xfs_dir2_sf_entry_t) - 1 + (sfep)->namelen - \
- ((sfp)->hdr.i8count == 0) * \
- ((uint)sizeof(xfs_dir2_ino8_t) - (uint)sizeof(xfs_dir2_ino4_t)));
-}
-
-#define XFS_DIR2_SF_FIRSTENTRY(sfp) xfs_dir2_sf_firstentry(sfp)
-static inline xfs_dir2_sf_entry_t *xfs_dir2_sf_firstentry(xfs_dir2_sf_t *sfp)
-{
- return ((xfs_dir2_sf_entry_t *) \
- ((char *)(sfp) + XFS_DIR2_SF_HDR_SIZE(sfp->hdr.i8count)));
-}
-
-#define XFS_DIR2_SF_NEXTENTRY(sfp,sfep) xfs_dir2_sf_nextentry(sfp,sfep)
-static inline xfs_dir2_sf_entry_t *
-xfs_dir2_sf_nextentry(xfs_dir2_sf_t *sfp, xfs_dir2_sf_entry_t *sfep)
-{
- return ((xfs_dir2_sf_entry_t *) \
- ((char *)(sfep) + XFS_DIR2_SF_ENTSIZE_BYENTRY(sfp,sfep)));
-}
-
-/*
- * Functions.
- */
-extern int xfs_dir2_block_sfsize(struct xfs_inode *dp,
- struct xfs_dir2_block *block,
- xfs_dir2_sf_hdr_t *sfhp);
-extern int xfs_dir2_block_to_sf(struct xfs_da_args *args, struct xfs_dabuf *bp,
- int size, xfs_dir2_sf_hdr_t *sfhp);
-extern int xfs_dir2_sf_addname(struct xfs_da_args *args);
-extern int xfs_dir2_sf_create(struct xfs_da_args *args, xfs_ino_t pino);
-extern int xfs_dir2_sf_getdents(struct xfs_inode *dp, struct uio *uio,
- int *eofp, struct xfs_dirent *dbp,
- xfs_dir2_put_t put);
-extern int xfs_dir2_sf_lookup(struct xfs_da_args *args);
-extern int xfs_dir2_sf_removename(struct xfs_da_args *args);
-extern int xfs_dir2_sf_replace(struct xfs_da_args *args);
-
-#endif /* __XFS_DIR2_SF_H__ */
diff --git a/sys/gnu/fs/xfs/xfs_dir2_trace.c b/sys/gnu/fs/xfs/xfs_dir2_trace.c
deleted file mode 100644
index c626943..0000000
--- a/sys/gnu/fs/xfs/xfs_dir2_trace.c
+++ /dev/null
@@ -1,216 +0,0 @@
-/*
- * Copyright (c) 2000-2003,2005 Silicon Graphics, Inc.
- * All Rights Reserved.
- *
- * 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.
- *
- * This program is distributed in the hope that it would 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 the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- */
-#include "xfs.h"
-#include "xfs_fs.h"
-#include "xfs_types.h"
-#include "xfs_inum.h"
-#include "xfs_dir.h"
-#include "xfs_dir2.h"
-#include "xfs_da_btree.h"
-#include "xfs_bmap_btree.h"
-#include "xfs_dir_sf.h"
-#include "xfs_dir2_sf.h"
-#include "xfs_attr_sf.h"
-#include "xfs_dinode.h"
-#include "xfs_inode.h"
-#include "xfs_dir2_trace.h"
-
-#ifdef XFS_DIR2_TRACE
-ktrace_t *xfs_dir2_trace_buf;
-
-/*
- * Enter something in the trace buffers.
- */
-static void
-xfs_dir2_trace_enter(
- xfs_inode_t *dp,
- int type,
- char *where,
- char *name,
- int namelen,
- void *a0,
- void *a1,
- void *a2,
- void *a3,
- void *a4,
- void *a5,
- void *a6,
- void *a7)
-{
- void *n[5];
-
- ASSERT(xfs_dir2_trace_buf);
- ASSERT(dp->i_dir_trace);
- if (name)
- memcpy(n, name, min((int)sizeof(n), namelen));
- else
- memset((char *)n, 0, sizeof(n));
- ktrace_enter(xfs_dir2_trace_buf,
- (void *)(long)type, (void *)where,
- (void *)a0, (void *)a1, (void *)a2, (void *)a3,
- (void *)a4, (void *)a5, (void *)a6, (void *)a7,
- (void *)(long)namelen,
- (void *)n[0], (void *)n[1], (void *)n[2],
- (void *)n[3], (void *)n[4]);
- ktrace_enter(dp->i_dir_trace,
- (void *)(long)type, (void *)where,
- (void *)a0, (void *)a1, (void *)a2, (void *)a3,
- (void *)a4, (void *)a5, (void *)a6, (void *)a7,
- (void *)(long)namelen,
- (void *)n[0], (void *)n[1], (void *)n[2],
- (void *)n[3], (void *)n[4]);
-}
-
-void
-xfs_dir2_trace_args(
- char *where,
- xfs_da_args_t *args)
-{
- xfs_dir2_trace_enter(args->dp, XFS_DIR2_KTRACE_ARGS, where,
- (char *)args->name, (int)args->namelen,
- (void *)(unsigned long)args->hashval,
- (void *)((unsigned long)(args->inumber >> 32)),
- (void *)((unsigned long)(args->inumber & 0xFFFFFFFF)),
- (void *)args->dp, (void *)args->trans,
- (void *)(unsigned long)args->justcheck, NULL, NULL);
-}
-
-void
-xfs_dir2_trace_args_b(
- char *where,
- xfs_da_args_t *args,
- xfs_dabuf_t *bp)
-{
- xfs_dir2_trace_enter(args->dp, XFS_DIR2_KTRACE_ARGS_B, where,
- (char *)args->name, (int)args->namelen,
- (void *)(unsigned long)args->hashval,
- (void *)((unsigned long)(args->inumber >> 32)),
- (void *)((unsigned long)(args->inumber & 0xFFFFFFFF)),
- (void *)args->dp, (void *)args->trans,
- (void *)(unsigned long)args->justcheck,
- (void *)(bp ? bp->bps[0] : NULL), NULL);
-}
-
-void
-xfs_dir2_trace_args_bb(
- char *where,
- xfs_da_args_t *args,
- xfs_dabuf_t *lbp,
- xfs_dabuf_t *dbp)
-{
- xfs_dir2_trace_enter(args->dp, XFS_DIR2_KTRACE_ARGS_BB, where,
- (char *)args->name, (int)args->namelen,
- (void *)(unsigned long)args->hashval,
- (void *)((unsigned long)(args->inumber >> 32)),
- (void *)((unsigned long)(args->inumber & 0xFFFFFFFF)),
- (void *)args->dp, (void *)args->trans,
- (void *)(unsigned long)args->justcheck,
- (void *)(lbp ? lbp->bps[0] : NULL),
- (void *)(dbp ? dbp->bps[0] : NULL));
-}
-
-void
-xfs_dir2_trace_args_bibii(
- char *where,
- xfs_da_args_t *args,
- xfs_dabuf_t *bs,
- int ss,
- xfs_dabuf_t *bd,
- int sd,
- int c)
-{
- xfs_buf_t *bpbs = bs ? bs->bps[0] : NULL;
- xfs_buf_t *bpbd = bd ? bd->bps[0] : NULL;
-
- xfs_dir2_trace_enter(args->dp, XFS_DIR2_KTRACE_ARGS_BIBII, where,
- (char *)args->name, (int)args->namelen,
- (void *)args->dp, (void *)args->trans,
- (void *)bpbs, (void *)(long)ss, (void *)bpbd, (void *)(long)sd,
- (void *)(long)c, NULL);
-}
-
-void
-xfs_dir2_trace_args_db(
- char *where,
- xfs_da_args_t *args,
- xfs_dir2_db_t db,
- xfs_dabuf_t *bp)
-{
- xfs_buf_t *dbp = bp ? bp->bps[0] : NULL;
-
- xfs_dir2_trace_enter(args->dp, XFS_DIR2_KTRACE_ARGS_DB, where,
- (char *)args->name, (int)args->namelen,
- (void *)(unsigned long)args->hashval,
- (void *)((unsigned long)(args->inumber >> 32)),
- (void *)((unsigned long)(args->inumber & 0xFFFFFFFF)),
- (void *)args->dp, (void *)args->trans,
- (void *)(unsigned long)args->justcheck, (void *)(long)db,
- (void *)dbp);
-}
-
-void
-xfs_dir2_trace_args_i(
- char *where,
- xfs_da_args_t *args,
- xfs_ino_t i)
-{
- xfs_dir2_trace_enter(args->dp, XFS_DIR2_KTRACE_ARGS_I, where,
- (char *)args->name, (int)args->namelen,
- (void *)(unsigned long)args->hashval,
- (void *)((unsigned long)(args->inumber >> 32)),
- (void *)((unsigned long)(args->inumber & 0xFFFFFFFF)),
- (void *)args->dp, (void *)args->trans,
- (void *)(unsigned long)args->justcheck,
- (void *)((unsigned long)(i >> 32)),
- (void *)((unsigned long)(i & 0xFFFFFFFF)));
-}
-
-void
-xfs_dir2_trace_args_s(
- char *where,
- xfs_da_args_t *args,
- int s)
-{
- xfs_dir2_trace_enter(args->dp, XFS_DIR2_KTRACE_ARGS_S, where,
- (char *)args->name, (int)args->namelen,
- (void *)(unsigned long)args->hashval,
- (void *)((unsigned long)(args->inumber >> 32)),
- (void *)((unsigned long)(args->inumber & 0xFFFFFFFF)),
- (void *)args->dp, (void *)args->trans,
- (void *)(unsigned long)args->justcheck, (void *)(long)s, NULL);
-}
-
-void
-xfs_dir2_trace_args_sb(
- char *where,
- xfs_da_args_t *args,
- int s,
- xfs_dabuf_t *bp)
-{
- xfs_buf_t *dbp = bp ? bp->bps[0] : NULL;
-
- xfs_dir2_trace_enter(args->dp, XFS_DIR2_KTRACE_ARGS_SB, where,
- (char *)args->name, (int)args->namelen,
- (void *)(unsigned long)args->hashval,
- (void *)((unsigned long)(args->inumber >> 32)),
- (void *)((unsigned long)(args->inumber & 0xFFFFFFFF)),
- (void *)args->dp, (void *)args->trans,
- (void *)(unsigned long)args->justcheck, (void *)(long)s,
- (void *)dbp);
-}
-#endif /* XFS_DIR2_TRACE */
diff --git a/sys/gnu/fs/xfs/xfs_dir2_trace.h b/sys/gnu/fs/xfs/xfs_dir2_trace.h
deleted file mode 100644
index ca3c754..0000000
--- a/sys/gnu/fs/xfs/xfs_dir2_trace.h
+++ /dev/null
@@ -1,72 +0,0 @@
-/*
- * Copyright (c) 2000,2005 Silicon Graphics, Inc.
- * All Rights Reserved.
- *
- * 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.
- *
- * This program is distributed in the hope that it would 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 the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- */
-#ifndef __XFS_DIR2_TRACE_H__
-#define __XFS_DIR2_TRACE_H__
-
-/*
- * Tracing for xfs v2 directories.
- */
-
-#if defined(XFS_DIR2_TRACE)
-
-struct ktrace;
-struct xfs_dabuf;
-struct xfs_da_args;
-
-#define XFS_DIR2_GTRACE_SIZE 4096 /* global buffer */
-#define XFS_DIR2_KTRACE_SIZE 32 /* per-inode buffer */
-extern struct ktrace *xfs_dir2_trace_buf;
-
-#define XFS_DIR2_KTRACE_ARGS 1 /* args only */
-#define XFS_DIR2_KTRACE_ARGS_B 2 /* args + buffer */
-#define XFS_DIR2_KTRACE_ARGS_BB 3 /* args + 2 buffers */
-#define XFS_DIR2_KTRACE_ARGS_DB 4 /* args, db, buffer */
-#define XFS_DIR2_KTRACE_ARGS_I 5 /* args, inum */
-#define XFS_DIR2_KTRACE_ARGS_S 6 /* args, int */
-#define XFS_DIR2_KTRACE_ARGS_SB 7 /* args, int, buffer */
-#define XFS_DIR2_KTRACE_ARGS_BIBII 8 /* args, buf/int/buf/int/int */
-
-void xfs_dir2_trace_args(char *where, struct xfs_da_args *args);
-void xfs_dir2_trace_args_b(char *where, struct xfs_da_args *args,
- struct xfs_dabuf *bp);
-void xfs_dir2_trace_args_bb(char *where, struct xfs_da_args *args,
- struct xfs_dabuf *lbp, struct xfs_dabuf *dbp);
-void xfs_dir2_trace_args_bibii(char *where, struct xfs_da_args *args,
- struct xfs_dabuf *bs, int ss,
- struct xfs_dabuf *bd, int sd, int c);
-void xfs_dir2_trace_args_db(char *where, struct xfs_da_args *args,
- xfs_dir2_db_t db, struct xfs_dabuf *bp);
-void xfs_dir2_trace_args_i(char *where, struct xfs_da_args *args, xfs_ino_t i);
-void xfs_dir2_trace_args_s(char *where, struct xfs_da_args *args, int s);
-void xfs_dir2_trace_args_sb(char *where, struct xfs_da_args *args, int s,
- struct xfs_dabuf *bp);
-
-#else /* XFS_DIR2_TRACE */
-
-#define xfs_dir2_trace_args(where, args)
-#define xfs_dir2_trace_args_b(where, args, bp)
-#define xfs_dir2_trace_args_bb(where, args, lbp, dbp)
-#define xfs_dir2_trace_args_bibii(where, args, bs, ss, bd, sd, c)
-#define xfs_dir2_trace_args_db(where, args, db, bp)
-#define xfs_dir2_trace_args_i(where, args, i)
-#define xfs_dir2_trace_args_s(where, args, s)
-#define xfs_dir2_trace_args_sb(where, args, s, bp)
-
-#endif /* XFS_DIR2_TRACE */
-
-#endif /* __XFS_DIR2_TRACE_H__ */
diff --git a/sys/gnu/fs/xfs/xfs_dir_leaf.c b/sys/gnu/fs/xfs/xfs_dir_leaf.c
deleted file mode 100644
index f89cde1..0000000
--- a/sys/gnu/fs/xfs/xfs_dir_leaf.c
+++ /dev/null
@@ -1,2215 +0,0 @@
-/*
- * Copyright (c) 2000-2003,2005 Silicon Graphics, Inc.
- * All Rights Reserved.
- *
- * 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.
- *
- * This program is distributed in the hope that it would 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 the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- */
-#include "xfs.h"
-#include "xfs_fs.h"
-#include "xfs_types.h"
-#include "xfs_log.h"
-#include "xfs_inum.h"
-#include "xfs_trans.h"
-#include "xfs_sb.h"
-#include "xfs_dir.h"
-#include "xfs_dir2.h"
-#include "xfs_dmapi.h"
-#include "xfs_mount.h"
-#include "xfs_da_btree.h"
-#include "xfs_bmap_btree.h"
-#include "xfs_alloc_btree.h"
-#include "xfs_ialloc_btree.h"
-#include "xfs_dir_sf.h"
-#include "xfs_dir2_sf.h"
-#include "xfs_attr_sf.h"
-#include "xfs_dinode.h"
-#include "xfs_inode.h"
-#include "xfs_inode_item.h"
-#include "xfs_alloc.h"
-#include "xfs_btree.h"
-#include "xfs_bmap.h"
-#include "xfs_dir_leaf.h"
-#include "xfs_error.h"
-
-/*
- * xfs_dir_leaf.c
- *
- * Routines to implement leaf blocks of directories as Btrees of hashed names.
- */
-
-/*========================================================================
- * Function prototypes for the kernel.
- *========================================================================*/
-
-/*
- * Routines used for growing the Btree.
- */
-STATIC void xfs_dir_leaf_add_work(xfs_dabuf_t *leaf_buffer, xfs_da_args_t *args,
- int insertion_index,
- int freemap_index);
-STATIC int xfs_dir_leaf_compact(xfs_trans_t *trans, xfs_dabuf_t *leaf_buffer,
- int musthave, int justcheck);
-STATIC void xfs_dir_leaf_rebalance(xfs_da_state_t *state,
- xfs_da_state_blk_t *blk1,
- xfs_da_state_blk_t *blk2);
-STATIC int xfs_dir_leaf_figure_balance(xfs_da_state_t *state,
- xfs_da_state_blk_t *leaf_blk_1,
- xfs_da_state_blk_t *leaf_blk_2,
- int *number_entries_in_blk1,
- int *number_namebytes_in_blk1);
-
-STATIC int xfs_dir_leaf_create(struct xfs_da_args *args,
- xfs_dablk_t which_block,
- struct xfs_dabuf **bpp);
-
-/*
- * Utility routines.
- */
-STATIC void xfs_dir_leaf_moveents(xfs_dir_leafblock_t *src_leaf,
- int src_start,
- xfs_dir_leafblock_t *dst_leaf,
- int dst_start, int move_count,
- xfs_mount_t *mp);
-
-
-/*========================================================================
- * External routines when dirsize < XFS_IFORK_DSIZE(dp).
- *========================================================================*/
-
-
-/*
- * Validate a given inode number.
- */
-int
-xfs_dir_ino_validate(xfs_mount_t *mp, xfs_ino_t ino)
-{
- xfs_agblock_t agblkno;
- xfs_agino_t agino;
- xfs_agnumber_t agno;
- int ino_ok;
- int ioff;
-
- agno = XFS_INO_TO_AGNO(mp, ino);
- agblkno = XFS_INO_TO_AGBNO(mp, ino);
- ioff = XFS_INO_TO_OFFSET(mp, ino);
- agino = XFS_OFFBNO_TO_AGINO(mp, agblkno, ioff);
- ino_ok =
- agno < mp->m_sb.sb_agcount &&
- agblkno < mp->m_sb.sb_agblocks &&
- agblkno != 0 &&
- ioff < (1 << mp->m_sb.sb_inopblog) &&
- XFS_AGINO_TO_INO(mp, agno, agino) == ino;
- if (unlikely(XFS_TEST_ERROR(!ino_ok, mp, XFS_ERRTAG_DIR_INO_VALIDATE,
- XFS_RANDOM_DIR_INO_VALIDATE))) {
- xfs_fs_cmn_err(CE_WARN, mp, "Invalid inode number 0x%Lx",
- (unsigned long long) ino);
- XFS_ERROR_REPORT("xfs_dir_ino_validate", XFS_ERRLEVEL_LOW, mp);
- return XFS_ERROR(EFSCORRUPTED);
- }
- return 0;
-}
-
-/*
- * Create the initial contents of a shortform directory.
- */
-int
-xfs_dir_shortform_create(xfs_da_args_t *args, xfs_ino_t parent)
-{
- xfs_dir_sf_hdr_t *hdr;
- xfs_inode_t *dp;
-
- dp = args->dp;
- ASSERT(dp != NULL);
- ASSERT(dp->i_d.di_size == 0);
- if (dp->i_d.di_format == XFS_DINODE_FMT_EXTENTS) {
- dp->i_df.if_flags &= ~XFS_IFEXTENTS; /* just in case */
- dp->i_d.di_format = XFS_DINODE_FMT_LOCAL;
- xfs_trans_log_inode(args->trans, dp, XFS_ILOG_CORE);
- dp->i_df.if_flags |= XFS_IFINLINE;
- }
- ASSERT(dp->i_df.if_flags & XFS_IFINLINE);
- ASSERT(dp->i_df.if_bytes == 0);
- xfs_idata_realloc(dp, sizeof(*hdr), XFS_DATA_FORK);
- hdr = (xfs_dir_sf_hdr_t *)dp->i_df.if_u1.if_data;
- XFS_DIR_SF_PUT_DIRINO(&parent, &hdr->parent);
-
- hdr->count = 0;
- dp->i_d.di_size = sizeof(*hdr);
- xfs_trans_log_inode(args->trans, dp, XFS_ILOG_CORE | XFS_ILOG_DDATA);
- return 0;
-}
-
-/*
- * Add a name to the shortform directory structure.
- * Overflow from the inode has already been checked for.
- */
-int
-xfs_dir_shortform_addname(xfs_da_args_t *args)
-{
- xfs_dir_shortform_t *sf;
- xfs_dir_sf_entry_t *sfe;
- int i, offset, size;
- xfs_inode_t *dp;
-
- dp = args->dp;
- ASSERT(dp->i_df.if_flags & XFS_IFINLINE);
- /*
- * Catch the case where the conversion from shortform to leaf
- * failed part way through.
- */
- if (dp->i_d.di_size < sizeof(xfs_dir_sf_hdr_t)) {
- ASSERT(XFS_FORCED_SHUTDOWN(dp->i_mount));
- return XFS_ERROR(EIO);
- }
- ASSERT(dp->i_df.if_bytes == dp->i_d.di_size);
- ASSERT(dp->i_df.if_u1.if_data != NULL);
- sf = (xfs_dir_shortform_t *)dp->i_df.if_u1.if_data;
- sfe = &sf->list[0];
- for (i = sf->hdr.count-1; i >= 0; i--) {
- if (sfe->namelen == args->namelen &&
- args->name[0] == sfe->name[0] &&
- memcmp(args->name, sfe->name, args->namelen) == 0)
- return XFS_ERROR(EEXIST);
- sfe = XFS_DIR_SF_NEXTENTRY(sfe);
- }
-
- offset = (int)((char *)sfe - (char *)sf);
- size = XFS_DIR_SF_ENTSIZE_BYNAME(args->namelen);
- xfs_idata_realloc(dp, size, XFS_DATA_FORK);
- sf = (xfs_dir_shortform_t *)dp->i_df.if_u1.if_data;
- sfe = (xfs_dir_sf_entry_t *)((char *)sf + offset);
-
- XFS_DIR_SF_PUT_DIRINO(&args->inumber, &sfe->inumber);
- sfe->namelen = args->namelen;
- memcpy(sfe->name, args->name, sfe->namelen);
- sf->hdr.count++;
-
- dp->i_d.di_size += size;
- xfs_trans_log_inode(args->trans, dp, XFS_ILOG_CORE | XFS_ILOG_DDATA);
-
- return 0;
-}
-
-/*
- * Remove a name from the shortform directory structure.
- */
-int
-xfs_dir_shortform_removename(xfs_da_args_t *args)
-{
- xfs_dir_shortform_t *sf;
- xfs_dir_sf_entry_t *sfe;
- int base, size = 0, i;
- xfs_inode_t *dp;
-
- dp = args->dp;
- ASSERT(dp->i_df.if_flags & XFS_IFINLINE);
- /*
- * Catch the case where the conversion from shortform to leaf
- * failed part way through.
- */
- if (dp->i_d.di_size < sizeof(xfs_dir_sf_hdr_t)) {
- ASSERT(XFS_FORCED_SHUTDOWN(dp->i_mount));
- return XFS_ERROR(EIO);
- }
- ASSERT(dp->i_df.if_bytes == dp->i_d.di_size);
- ASSERT(dp->i_df.if_u1.if_data != NULL);
- base = sizeof(xfs_dir_sf_hdr_t);
- sf = (xfs_dir_shortform_t *)dp->i_df.if_u1.if_data;
- sfe = &sf->list[0];
- for (i = sf->hdr.count-1; i >= 0; i--) {
- size = XFS_DIR_SF_ENTSIZE_BYENTRY(sfe);
- if (sfe->namelen == args->namelen &&
- sfe->name[0] == args->name[0] &&
- memcmp(sfe->name, args->name, args->namelen) == 0)
- break;
- base += size;
- sfe = XFS_DIR_SF_NEXTENTRY(sfe);
- }
- if (i < 0) {
- ASSERT(args->oknoent);
- return XFS_ERROR(ENOENT);
- }
-
- if ((base + size) != dp->i_d.di_size) {
- memmove(&((char *)sf)[base], &((char *)sf)[base+size],
- dp->i_d.di_size - (base+size));
- }
- sf->hdr.count--;
-
- xfs_idata_realloc(dp, -size, XFS_DATA_FORK);
- dp->i_d.di_size -= size;
- xfs_trans_log_inode(args->trans, dp, XFS_ILOG_CORE | XFS_ILOG_DDATA);
-
- return 0;
-}
-
-/*
- * Look up a name in a shortform directory structure.
- */
-int
-xfs_dir_shortform_lookup(xfs_da_args_t *args)
-{
- xfs_dir_shortform_t *sf;
- xfs_dir_sf_entry_t *sfe;
- int i;
- xfs_inode_t *dp;
-
- dp = args->dp;
- ASSERT(dp->i_df.if_flags & XFS_IFINLINE);
- /*
- * Catch the case where the conversion from shortform to leaf
- * failed part way through.
- */
- if (dp->i_d.di_size < sizeof(xfs_dir_sf_hdr_t)) {
- ASSERT(XFS_FORCED_SHUTDOWN(dp->i_mount));
- return XFS_ERROR(EIO);
- }
- ASSERT(dp->i_df.if_bytes == dp->i_d.di_size);
- ASSERT(dp->i_df.if_u1.if_data != NULL);
- sf = (xfs_dir_shortform_t *)dp->i_df.if_u1.if_data;
- if (args->namelen == 2 &&
- args->name[0] == '.' && args->name[1] == '.') {
- XFS_DIR_SF_GET_DIRINO(&sf->hdr.parent, &args->inumber);
- return(XFS_ERROR(EEXIST));
- }
- if (args->namelen == 1 && args->name[0] == '.') {
- args->inumber = dp->i_ino;
- return(XFS_ERROR(EEXIST));
- }
- sfe = &sf->list[0];
- for (i = sf->hdr.count-1; i >= 0; i--) {
- if (sfe->namelen == args->namelen &&
- sfe->name[0] == args->name[0] &&
- memcmp(args->name, sfe->name, args->namelen) == 0) {
- XFS_DIR_SF_GET_DIRINO(&sfe->inumber, &args->inumber);
- return(XFS_ERROR(EEXIST));
- }
- sfe = XFS_DIR_SF_NEXTENTRY(sfe);
- }
- ASSERT(args->oknoent);
- return(XFS_ERROR(ENOENT));
-}
-
-/*
- * Convert from using the shortform to the leaf.
- */
-int
-xfs_dir_shortform_to_leaf(xfs_da_args_t *iargs)
-{
- xfs_inode_t *dp;
- xfs_dir_shortform_t *sf;
- xfs_dir_sf_entry_t *sfe;
- xfs_da_args_t args;
- xfs_ino_t inumber;
- char *tmpbuffer;
- int retval, i, size;
- xfs_dablk_t blkno;
- xfs_dabuf_t *bp;
-
- dp = iargs->dp;
- /*
- * Catch the case where the conversion from shortform to leaf
- * failed part way through.
- */
- if (dp->i_d.di_size < sizeof(xfs_dir_sf_hdr_t)) {
- ASSERT(XFS_FORCED_SHUTDOWN(dp->i_mount));
- return XFS_ERROR(EIO);
- }
- ASSERT(dp->i_df.if_bytes == dp->i_d.di_size);
- ASSERT(dp->i_df.if_u1.if_data != NULL);
- size = dp->i_df.if_bytes;
- tmpbuffer = kmem_alloc(size, KM_SLEEP);
- ASSERT(tmpbuffer != NULL);
-
- memcpy(tmpbuffer, dp->i_df.if_u1.if_data, size);
-
- sf = (xfs_dir_shortform_t *)tmpbuffer;
- XFS_DIR_SF_GET_DIRINO(&sf->hdr.parent, &inumber);
-
- xfs_idata_realloc(dp, -size, XFS_DATA_FORK);
- dp->i_d.di_size = 0;
- xfs_trans_log_inode(iargs->trans, dp, XFS_ILOG_CORE);
- retval = xfs_da_grow_inode(iargs, &blkno);
- if (retval)
- goto out;
-
- ASSERT(blkno == 0);
- retval = xfs_dir_leaf_create(iargs, blkno, &bp);
- if (retval)
- goto out;
- xfs_da_buf_done(bp);
-
- args.name = ".";
- args.namelen = 1;
- args.hashval = xfs_dir_hash_dot;
- args.inumber = dp->i_ino;
- args.dp = dp;
- args.firstblock = iargs->firstblock;
- args.flist = iargs->flist;
- args.total = iargs->total;
- args.whichfork = XFS_DATA_FORK;
- args.trans = iargs->trans;
- args.justcheck = 0;
- args.addname = args.oknoent = 1;
- retval = xfs_dir_leaf_addname(&args);
- if (retval)
- goto out;
-
- args.name = "..";
- args.namelen = 2;
- args.hashval = xfs_dir_hash_dotdot;
- args.inumber = inumber;
- retval = xfs_dir_leaf_addname(&args);
- if (retval)
- goto out;
-
- sfe = &sf->list[0];
- for (i = 0; i < sf->hdr.count; i++) {
- args.name = (char *)(sfe->name);
- args.namelen = sfe->namelen;
- args.hashval = xfs_da_hashname((char *)(sfe->name),
- sfe->namelen);
- XFS_DIR_SF_GET_DIRINO(&sfe->inumber, &args.inumber);
- retval = xfs_dir_leaf_addname(&args);
- if (retval)
- goto out;
- sfe = XFS_DIR_SF_NEXTENTRY(sfe);
- }
- retval = 0;
-
-out:
- kmem_free(tmpbuffer, size);
- return retval;
-}
-
-STATIC int
-xfs_dir_shortform_compare(const void *a, const void *b)
-{
- const xfs_dir_sf_sort_t *sa, *sb;
-
- sa = (const xfs_dir_sf_sort_t *)a;
- sb = (const xfs_dir_sf_sort_t *)b;
- if (sa->hash < sb->hash)
- return -1;
- else if (sa->hash > sb->hash)
- return 1;
- else
- return sa->entno - sb->entno;
-}
-
-/*
- * Copy out directory entries for getdents(), for shortform directories.
- */
-/*ARGSUSED*/
-int
-xfs_dir_shortform_getdents(xfs_inode_t *dp, uio_t *uio, int *eofp,
- xfs_dirent_t *dbp, xfs_dir_put_t put)
-{
- xfs_dir_shortform_t *sf;
- xfs_dir_sf_entry_t *sfe;
- int retval, i, sbsize, nsbuf, lastresid=0, want_entno;
- xfs_mount_t *mp;
- xfs_dahash_t cookhash, hash;
- xfs_dir_put_args_t p;
- xfs_dir_sf_sort_t *sbuf, *sbp;
-
- mp = dp->i_mount;
- sf = (xfs_dir_shortform_t *)dp->i_df.if_u1.if_data;
- cookhash = XFS_DA_COOKIE_HASH(mp, uio->uio_offset);
- want_entno = XFS_DA_COOKIE_ENTRY(mp, uio->uio_offset);
- nsbuf = sf->hdr.count + 2;
- sbsize = (nsbuf + 1) * sizeof(*sbuf);
- sbp = sbuf = kmem_alloc(sbsize, KM_SLEEP);
-
- xfs_dir_trace_g_du("sf: start", dp, uio);
-
- /*
- * Collect all the entries into the buffer.
- * Entry 0 is .
- */
- sbp->entno = 0;
- sbp->seqno = 0;
- sbp->hash = xfs_dir_hash_dot;
- sbp->ino = dp->i_ino;
- sbp->name = ".";
- sbp->namelen = 1;
- sbp++;
-
- /*
- * Entry 1 is ..
- */
- sbp->entno = 1;
- sbp->seqno = 0;
- sbp->hash = xfs_dir_hash_dotdot;
- sbp->ino = XFS_GET_DIR_INO8(sf->hdr.parent);
- sbp->name = "..";
- sbp->namelen = 2;
- sbp++;
-
- /*
- * Scan the directory data for the rest of the entries.
- */
- for (i = 0, sfe = &sf->list[0]; i < sf->hdr.count; i++) {
-
- if (unlikely(
- ((char *)sfe < (char *)sf) ||
- ((char *)sfe >= ((char *)sf + dp->i_df.if_bytes)))) {
- xfs_dir_trace_g_du("sf: corrupted", dp, uio);
- XFS_CORRUPTION_ERROR("xfs_dir_shortform_getdents",
- XFS_ERRLEVEL_LOW, mp, sfe);
- kmem_free(sbuf, sbsize);
- return XFS_ERROR(EFSCORRUPTED);
- }
-
- sbp->entno = i + 2;
- sbp->seqno = 0;
- sbp->hash = xfs_da_hashname((char *)sfe->name, sfe->namelen);
- sbp->ino = XFS_GET_DIR_INO8(sfe->inumber);
- sbp->name = (char *)sfe->name;
- sbp->namelen = sfe->namelen;
- sfe = XFS_DIR_SF_NEXTENTRY(sfe);
- sbp++;
- }
-
- /*
- * Sort the entries on hash then entno.
- */
- xfs_sort(sbuf, nsbuf, sizeof(*sbuf), xfs_dir_shortform_compare);
- /*
- * Stuff in last entry.
- */
- sbp->entno = nsbuf;
- sbp->hash = XFS_DA_MAXHASH;
- sbp->seqno = 0;
- /*
- * Figure out the sequence numbers in case there's a hash duplicate.
- */
- for (hash = sbuf->hash, sbp = sbuf + 1;
- sbp < &sbuf[nsbuf + 1]; sbp++) {
- if (sbp->hash == hash)
- sbp->seqno = sbp[-1].seqno + 1;
- else
- hash = sbp->hash;
- }
-
- /*
- * Set up put routine.
- */
- p.dbp = dbp;
- p.put = put;
- p.uio = uio;
-
- /*
- * Find our place.
- */
- for (sbp = sbuf; sbp < &sbuf[nsbuf + 1]; sbp++) {
- if (sbp->hash > cookhash ||
- (sbp->hash == cookhash && sbp->seqno >= want_entno))
- break;
- }
-
- /*
- * Did we fail to find anything? We stop at the last entry,
- * the one we put maxhash into.
- */
- if (sbp == &sbuf[nsbuf]) {
- kmem_free(sbuf, sbsize);
- xfs_dir_trace_g_du("sf: hash beyond end", dp, uio);
- uio->uio_offset = XFS_DA_MAKE_COOKIE(mp, 0, 0, XFS_DA_MAXHASH);
- *eofp = 1;
- return 0;
- }
-
- /*
- * Loop putting entries into the user buffer.
- */
- while (sbp < &sbuf[nsbuf]) {
- /*
- * Save the first resid in a run of equal-hashval entries
- * so that we can back them out if they don't all fit.
- */
- if (sbp->seqno == 0 || sbp == sbuf)
- lastresid = uio->uio_resid;
- XFS_PUT_COOKIE(p.cook, mp, 0, sbp[1].seqno, sbp[1].hash);
- p.ino = sbp->ino;
-#if XFS_BIG_INUMS
- p.ino += mp->m_inoadd;
-#endif
- p.name = sbp->name;
- p.namelen = sbp->namelen;
- retval = p.put(&p);
- if (!p.done) {
- uio->uio_offset =
- XFS_DA_MAKE_COOKIE(mp, 0, 0, sbp->hash);
- kmem_free(sbuf, sbsize);
- uio->uio_resid = lastresid;
- xfs_dir_trace_g_du("sf: E-O-B", dp, uio);
- return retval;
- }
- sbp++;
- }
- kmem_free(sbuf, sbsize);
- uio->uio_offset = p.cook.o;
- *eofp = 1;
- xfs_dir_trace_g_du("sf: E-O-F", dp, uio);
- return 0;
-}
-
-/*
- * Look up a name in a shortform directory structure, replace the inode number.
- */
-int
-xfs_dir_shortform_replace(xfs_da_args_t *args)
-{
- xfs_dir_shortform_t *sf;
- xfs_dir_sf_entry_t *sfe;
- xfs_inode_t *dp;
- int i;
-
- dp = args->dp;
- ASSERT(dp->i_df.if_flags & XFS_IFINLINE);
- /*
- * Catch the case where the conversion from shortform to leaf
- * failed part way through.
- */
- if (dp->i_d.di_size < sizeof(xfs_dir_sf_hdr_t)) {
- ASSERT(XFS_FORCED_SHUTDOWN(dp->i_mount));
- return XFS_ERROR(EIO);
- }
- ASSERT(dp->i_df.if_bytes == dp->i_d.di_size);
- ASSERT(dp->i_df.if_u1.if_data != NULL);
- sf = (xfs_dir_shortform_t *)dp->i_df.if_u1.if_data;
- if (args->namelen == 2 &&
- args->name[0] == '.' && args->name[1] == '.') {
- /* XXX - replace assert? */
- XFS_DIR_SF_PUT_DIRINO(&args->inumber, &sf->hdr.parent);
- xfs_trans_log_inode(args->trans, dp, XFS_ILOG_DDATA);
- return 0;
- }
- ASSERT(args->namelen != 1 || args->name[0] != '.');
- sfe = &sf->list[0];
- for (i = sf->hdr.count-1; i >= 0; i--) {
- if (sfe->namelen == args->namelen &&
- sfe->name[0] == args->name[0] &&
- memcmp(args->name, sfe->name, args->namelen) == 0) {
- ASSERT(memcmp((char *)&args->inumber,
- (char *)&sfe->inumber, sizeof(xfs_ino_t)));
- XFS_DIR_SF_PUT_DIRINO(&args->inumber, &sfe->inumber);
- xfs_trans_log_inode(args->trans, dp, XFS_ILOG_DDATA);
- return 0;
- }
- sfe = XFS_DIR_SF_NEXTENTRY(sfe);
- }
- ASSERT(args->oknoent);
- return XFS_ERROR(ENOENT);
-}
-
-/*
- * Convert a leaf directory to shortform structure
- */
-int
-xfs_dir_leaf_to_shortform(xfs_da_args_t *iargs)
-{
- xfs_dir_leafblock_t *leaf;
- xfs_dir_leaf_hdr_t *hdr;
- xfs_dir_leaf_entry_t *entry;
- xfs_dir_leaf_name_t *namest;
- xfs_da_args_t args;
- xfs_inode_t *dp;
- xfs_ino_t parent = 0;
- char *tmpbuffer;
- int retval, i;
- xfs_dabuf_t *bp;
-
- dp = iargs->dp;
- tmpbuffer = kmem_alloc(XFS_LBSIZE(dp->i_mount), KM_SLEEP);
- ASSERT(tmpbuffer != NULL);
-
- retval = xfs_da_read_buf(iargs->trans, iargs->dp, 0, -1, &bp,
- XFS_DATA_FORK);
- if (retval)
- goto out;
- ASSERT(bp != NULL);
- memcpy(tmpbuffer, bp->data, XFS_LBSIZE(dp->i_mount));
- leaf = (xfs_dir_leafblock_t *)tmpbuffer;
- ASSERT(be16_to_cpu(leaf->hdr.info.magic) == XFS_DIR_LEAF_MAGIC);
- memset(bp->data, 0, XFS_LBSIZE(dp->i_mount));
-
- /*
- * Find and special case the parent inode number
- */
- hdr = &leaf->hdr;
- entry = &leaf->entries[0];
- for (i = INT_GET(hdr->count, ARCH_CONVERT)-1; i >= 0; entry++, i--) {
- namest = XFS_DIR_LEAF_NAMESTRUCT(leaf, INT_GET(entry->nameidx, ARCH_CONVERT));
- if ((entry->namelen == 2) &&
- (namest->name[0] == '.') &&
- (namest->name[1] == '.')) {
- XFS_DIR_SF_GET_DIRINO(&namest->inumber, &parent);
- entry->nameidx = 0;
- } else if ((entry->namelen == 1) && (namest->name[0] == '.')) {
- entry->nameidx = 0;
- }
- }
- retval = xfs_da_shrink_inode(iargs, 0, bp);
- if (retval)
- goto out;
- retval = xfs_dir_shortform_create(iargs, parent);
- if (retval)
- goto out;
-
- /*
- * Copy the rest of the filenames
- */
- entry = &leaf->entries[0];
- args.dp = dp;
- args.firstblock = iargs->firstblock;
- args.flist = iargs->flist;
- args.total = iargs->total;
- args.whichfork = XFS_DATA_FORK;
- args.trans = iargs->trans;
- args.justcheck = 0;
- args.addname = args.oknoent = 1;
- for (i = 0; i < INT_GET(hdr->count, ARCH_CONVERT); entry++, i++) {
- if (!entry->nameidx)
- continue;
- namest = XFS_DIR_LEAF_NAMESTRUCT(leaf, INT_GET(entry->nameidx, ARCH_CONVERT));
- args.name = (char *)(namest->name);
- args.namelen = entry->namelen;
- args.hashval = INT_GET(entry->hashval, ARCH_CONVERT);
- XFS_DIR_SF_GET_DIRINO(&namest->inumber, &args.inumber);
- xfs_dir_shortform_addname(&args);
- }
-
-out:
- kmem_free(tmpbuffer, XFS_LBSIZE(dp->i_mount));
- return retval;
-}
-
-/*
- * Convert from using a single leaf to a root node and a leaf.
- */
-int
-xfs_dir_leaf_to_node(xfs_da_args_t *args)
-{
- xfs_dir_leafblock_t *leaf;
- xfs_da_intnode_t *node;
- xfs_inode_t *dp;
- xfs_dabuf_t *bp1, *bp2;
- xfs_dablk_t blkno;
- int retval;
-
- dp = args->dp;
- retval = xfs_da_grow_inode(args, &blkno);
- ASSERT(blkno == 1);
- if (retval)
- return retval;
- retval = xfs_da_read_buf(args->trans, args->dp, 0, -1, &bp1,
- XFS_DATA_FORK);
- if (retval)
- return retval;
- ASSERT(bp1 != NULL);
- retval = xfs_da_get_buf(args->trans, args->dp, 1, -1, &bp2,
- XFS_DATA_FORK);
- if (retval) {
- xfs_da_buf_done(bp1);
- return retval;
- }
- ASSERT(bp2 != NULL);
- memcpy(bp2->data, bp1->data, XFS_LBSIZE(dp->i_mount));
- xfs_da_buf_done(bp1);
- xfs_da_log_buf(args->trans, bp2, 0, XFS_LBSIZE(dp->i_mount) - 1);
-
- /*
- * Set up the new root node.
- */
- retval = xfs_da_node_create(args, 0, 1, &bp1, XFS_DATA_FORK);
- if (retval) {
- xfs_da_buf_done(bp2);
- return retval;
- }
- node = bp1->data;
- leaf = bp2->data;
- ASSERT(be16_to_cpu(leaf->hdr.info.magic) == XFS_DIR_LEAF_MAGIC);
- node->btree[0].hashval = cpu_to_be32(
- INT_GET(leaf->entries[
- INT_GET(leaf->hdr.count, ARCH_CONVERT)-1].hashval, ARCH_CONVERT));
- xfs_da_buf_done(bp2);
- node->btree[0].before = cpu_to_be32(blkno);
- node->hdr.count = cpu_to_be16(1);
- xfs_da_log_buf(args->trans, bp1,
- XFS_DA_LOGRANGE(node, &node->btree[0], sizeof(node->btree[0])));
- xfs_da_buf_done(bp1);
-
- return retval;
-}
-
-
-/*========================================================================
- * Routines used for growing the Btree.
- *========================================================================*/
-
-/*
- * Create the initial contents of a leaf directory
- * or a leaf in a node directory.
- */
-STATIC int
-xfs_dir_leaf_create(xfs_da_args_t *args, xfs_dablk_t blkno, xfs_dabuf_t **bpp)
-{
- xfs_dir_leafblock_t *leaf;
- xfs_dir_leaf_hdr_t *hdr;
- xfs_inode_t *dp;
- xfs_dabuf_t *bp;
- int retval;
-
- dp = args->dp;
- ASSERT(dp != NULL);
- retval = xfs_da_get_buf(args->trans, dp, blkno, -1, &bp, XFS_DATA_FORK);
- if (retval)
- return retval;
- ASSERT(bp != NULL);
- leaf = bp->data;
- memset((char *)leaf, 0, XFS_LBSIZE(dp->i_mount));
- hdr = &leaf->hdr;
- hdr->info.magic = cpu_to_be16(XFS_DIR_LEAF_MAGIC);
- INT_SET(hdr->firstused, ARCH_CONVERT, XFS_LBSIZE(dp->i_mount));
- if (!hdr->firstused)
- INT_SET(hdr->firstused, ARCH_CONVERT, XFS_LBSIZE(dp->i_mount) - 1);
- INT_SET(hdr->freemap[0].base, ARCH_CONVERT, sizeof(xfs_dir_leaf_hdr_t));
- INT_SET(hdr->freemap[0].size, ARCH_CONVERT, INT_GET(hdr->firstused, ARCH_CONVERT) - INT_GET(hdr->freemap[0].base, ARCH_CONVERT));
-
- xfs_da_log_buf(args->trans, bp, 0, XFS_LBSIZE(dp->i_mount) - 1);
-
- *bpp = bp;
- return 0;
-}
-
-/*
- * Split the leaf node, rebalance, then add the new entry.
- */
-int
-xfs_dir_leaf_split(xfs_da_state_t *state, xfs_da_state_blk_t *oldblk,
- xfs_da_state_blk_t *newblk)
-{
- xfs_dablk_t blkno;
- xfs_da_args_t *args;
- int error;
-
- /*
- * Allocate space for a new leaf node.
- */
- args = state->args;
- ASSERT(args != NULL);
- ASSERT(oldblk->magic == XFS_DIR_LEAF_MAGIC);
- error = xfs_da_grow_inode(args, &blkno);
- if (error)
- return error;
- error = xfs_dir_leaf_create(args, blkno, &newblk->bp);
- if (error)
- return error;
- newblk->blkno = blkno;
- newblk->magic = XFS_DIR_LEAF_MAGIC;
-
- /*
- * Rebalance the entries across the two leaves.
- */
- xfs_dir_leaf_rebalance(state, oldblk, newblk);
- error = xfs_da_blk_link(state, oldblk, newblk);
- if (error)
- return error;
-
- /*
- * Insert the new entry in the correct block.
- */
- if (state->inleaf) {
- error = xfs_dir_leaf_add(oldblk->bp, args, oldblk->index);
- } else {
- error = xfs_dir_leaf_add(newblk->bp, args, newblk->index);
- }
-
- /*
- * Update last hashval in each block since we added the name.
- */
- oldblk->hashval = xfs_dir_leaf_lasthash(oldblk->bp, NULL);
- newblk->hashval = xfs_dir_leaf_lasthash(newblk->bp, NULL);
- return error;
-}
-
-/*
- * Add a name to the leaf directory structure.
- *
- * Must take into account fragmented leaves and leaves where spacemap has
- * lost some freespace information (ie: holes).
- */
-int
-xfs_dir_leaf_add(xfs_dabuf_t *bp, xfs_da_args_t *args, int index)
-{
- xfs_dir_leafblock_t *leaf;
- xfs_dir_leaf_hdr_t *hdr;
- xfs_dir_leaf_map_t *map;
- int tablesize, entsize, sum, i, tmp, error;
-
- leaf = bp->data;
- ASSERT(be16_to_cpu(leaf->hdr.info.magic) == XFS_DIR_LEAF_MAGIC);
- ASSERT((index >= 0) && (index <= INT_GET(leaf->hdr.count, ARCH_CONVERT)));
- hdr = &leaf->hdr;
- entsize = XFS_DIR_LEAF_ENTSIZE_BYNAME(args->namelen);
-
- /*
- * Search through freemap for first-fit on new name length.
- * (may need to figure in size of entry struct too)
- */
- tablesize = (INT_GET(hdr->count, ARCH_CONVERT) + 1) * (uint)sizeof(xfs_dir_leaf_entry_t)
- + (uint)sizeof(xfs_dir_leaf_hdr_t);
- map = &hdr->freemap[XFS_DIR_LEAF_MAPSIZE-1];
- for (sum = 0, i = XFS_DIR_LEAF_MAPSIZE-1; i >= 0; map--, i--) {
- if (tablesize > INT_GET(hdr->firstused, ARCH_CONVERT)) {
- sum += INT_GET(map->size, ARCH_CONVERT);
- continue;
- }
- if (!map->size)
- continue; /* no space in this map */
- tmp = entsize;
- if (INT_GET(map->base, ARCH_CONVERT) < INT_GET(hdr->firstused, ARCH_CONVERT))
- tmp += (uint)sizeof(xfs_dir_leaf_entry_t);
- if (INT_GET(map->size, ARCH_CONVERT) >= tmp) {
- if (!args->justcheck)
- xfs_dir_leaf_add_work(bp, args, index, i);
- return 0;
- }
- sum += INT_GET(map->size, ARCH_CONVERT);
- }
-
- /*
- * If there are no holes in the address space of the block,
- * and we don't have enough freespace, then compaction will do us
- * no good and we should just give up.
- */
- if (!hdr->holes && (sum < entsize))
- return XFS_ERROR(ENOSPC);
-
- /*
- * Compact the entries to coalesce free space.
- * Pass the justcheck flag so the checking pass can return
- * an error, without changing anything, if it won't fit.
- */
- error = xfs_dir_leaf_compact(args->trans, bp,
- args->total == 0 ?
- entsize +
- (uint)sizeof(xfs_dir_leaf_entry_t) : 0,
- args->justcheck);
- if (error)
- return error;
- /*
- * After compaction, the block is guaranteed to have only one
- * free region, in freemap[0]. If it is not big enough, give up.
- */
- if (INT_GET(hdr->freemap[0].size, ARCH_CONVERT) <
- (entsize + (uint)sizeof(xfs_dir_leaf_entry_t)))
- return XFS_ERROR(ENOSPC);
-
- if (!args->justcheck)
- xfs_dir_leaf_add_work(bp, args, index, 0);
- return 0;
-}
-
-/*
- * Add a name to a leaf directory structure.
- */
-STATIC void
-xfs_dir_leaf_add_work(xfs_dabuf_t *bp, xfs_da_args_t *args, int index,
- int mapindex)
-{
- xfs_dir_leafblock_t *leaf;
- xfs_dir_leaf_hdr_t *hdr;
- xfs_dir_leaf_entry_t *entry;
- xfs_dir_leaf_name_t *namest;
- xfs_dir_leaf_map_t *map;
- /* REFERENCED */
- xfs_mount_t *mp;
- int tmp, i;
-
- leaf = bp->data;
- ASSERT(be16_to_cpu(leaf->hdr.info.magic) == XFS_DIR_LEAF_MAGIC);
- hdr = &leaf->hdr;
- ASSERT((mapindex >= 0) && (mapindex < XFS_DIR_LEAF_MAPSIZE));
- ASSERT((index >= 0) && (index <= INT_GET(hdr->count, ARCH_CONVERT)));
-
- /*
- * Force open some space in the entry array and fill it in.
- */
- entry = &leaf->entries[index];
- if (index < INT_GET(hdr->count, ARCH_CONVERT)) {
- tmp = INT_GET(hdr->count, ARCH_CONVERT) - index;
- tmp *= (uint)sizeof(xfs_dir_leaf_entry_t);
- memmove(entry + 1, entry, tmp);
- xfs_da_log_buf(args->trans, bp,
- XFS_DA_LOGRANGE(leaf, entry, tmp + (uint)sizeof(*entry)));
- }
- INT_MOD(hdr->count, ARCH_CONVERT, +1);
-
- /*
- * Allocate space for the new string (at the end of the run).
- */
- map = &hdr->freemap[mapindex];
- mp = args->trans->t_mountp;
- ASSERT(INT_GET(map->base, ARCH_CONVERT) < XFS_LBSIZE(mp));
- ASSERT(INT_GET(map->size, ARCH_CONVERT) >= XFS_DIR_LEAF_ENTSIZE_BYNAME(args->namelen));
- ASSERT(INT_GET(map->size, ARCH_CONVERT) < XFS_LBSIZE(mp));
- INT_MOD(map->size, ARCH_CONVERT, -(XFS_DIR_LEAF_ENTSIZE_BYNAME(args->namelen)));
- INT_SET(entry->nameidx, ARCH_CONVERT, INT_GET(map->base, ARCH_CONVERT) + INT_GET(map->size, ARCH_CONVERT));
- INT_SET(entry->hashval, ARCH_CONVERT, args->hashval);
- entry->namelen = args->namelen;
- xfs_da_log_buf(args->trans, bp,
- XFS_DA_LOGRANGE(leaf, entry, sizeof(*entry)));
-
- /*
- * Copy the string and inode number into the new space.
- */
- namest = XFS_DIR_LEAF_NAMESTRUCT(leaf, INT_GET(entry->nameidx, ARCH_CONVERT));
- XFS_DIR_SF_PUT_DIRINO(&args->inumber, &namest->inumber);
- memcpy(namest->name, args->name, args->namelen);
- xfs_da_log_buf(args->trans, bp,
- XFS_DA_LOGRANGE(leaf, namest, XFS_DIR_LEAF_ENTSIZE_BYENTRY(entry)));
-
- /*
- * Update the control info for this leaf node
- */
- if (INT_GET(entry->nameidx, ARCH_CONVERT) < INT_GET(hdr->firstused, ARCH_CONVERT))
- INT_COPY(hdr->firstused, entry->nameidx, ARCH_CONVERT);
- ASSERT(INT_GET(hdr->firstused, ARCH_CONVERT) >= ((INT_GET(hdr->count, ARCH_CONVERT)*sizeof(*entry))+sizeof(*hdr)));
- tmp = (INT_GET(hdr->count, ARCH_CONVERT)-1) * (uint)sizeof(xfs_dir_leaf_entry_t)
- + (uint)sizeof(xfs_dir_leaf_hdr_t);
- map = &hdr->freemap[0];
- for (i = 0; i < XFS_DIR_LEAF_MAPSIZE; map++, i++) {
- if (INT_GET(map->base, ARCH_CONVERT) == tmp) {
- INT_MOD(map->base, ARCH_CONVERT, (uint)sizeof(xfs_dir_leaf_entry_t));
- INT_MOD(map->size, ARCH_CONVERT, -((uint)sizeof(xfs_dir_leaf_entry_t)));
- }
- }
- INT_MOD(hdr->namebytes, ARCH_CONVERT, args->namelen);
- xfs_da_log_buf(args->trans, bp,
- XFS_DA_LOGRANGE(leaf, hdr, sizeof(*hdr)));
-}
-
-/*
- * Garbage collect a leaf directory block by copying it to a new buffer.
- */
-STATIC int
-xfs_dir_leaf_compact(xfs_trans_t *trans, xfs_dabuf_t *bp, int musthave,
- int justcheck)
-{
- xfs_dir_leafblock_t *leaf_s, *leaf_d;
- xfs_dir_leaf_hdr_t *hdr_s, *hdr_d;
- xfs_mount_t *mp;
- char *tmpbuffer;
- char *tmpbuffer2=NULL;
- int rval;
- int lbsize;
-
- mp = trans->t_mountp;
- lbsize = XFS_LBSIZE(mp);
- tmpbuffer = kmem_alloc(lbsize, KM_SLEEP);
- ASSERT(tmpbuffer != NULL);
- memcpy(tmpbuffer, bp->data, lbsize);
-
- /*
- * Make a second copy in case xfs_dir_leaf_moveents()
- * below destroys the original.
- */
- if (musthave || justcheck) {
- tmpbuffer2 = kmem_alloc(lbsize, KM_SLEEP);
- memcpy(tmpbuffer2, bp->data, lbsize);
- }
- memset(bp->data, 0, lbsize);
-
- /*
- * Copy basic information
- */
- leaf_s = (xfs_dir_leafblock_t *)tmpbuffer;
- leaf_d = bp->data;
- hdr_s = &leaf_s->hdr;
- hdr_d = &leaf_d->hdr;
- hdr_d->info = hdr_s->info; /* struct copy */
- INT_SET(hdr_d->firstused, ARCH_CONVERT, lbsize);
- if (!hdr_d->firstused)
- INT_SET(hdr_d->firstused, ARCH_CONVERT, lbsize - 1);
- hdr_d->namebytes = 0;
- hdr_d->count = 0;
- hdr_d->holes = 0;
- INT_SET(hdr_d->freemap[0].base, ARCH_CONVERT, sizeof(xfs_dir_leaf_hdr_t));
- INT_SET(hdr_d->freemap[0].size, ARCH_CONVERT, INT_GET(hdr_d->firstused, ARCH_CONVERT) - INT_GET(hdr_d->freemap[0].base, ARCH_CONVERT));
-
- /*
- * Copy all entry's in the same (sorted) order,
- * but allocate filenames packed and in sequence.
- * This changes the source (leaf_s) as well.
- */
- xfs_dir_leaf_moveents(leaf_s, 0, leaf_d, 0, (int)INT_GET(hdr_s->count, ARCH_CONVERT), mp);
-
- if (musthave && INT_GET(hdr_d->freemap[0].size, ARCH_CONVERT) < musthave)
- rval = XFS_ERROR(ENOSPC);
- else
- rval = 0;
-
- if (justcheck || rval == ENOSPC) {
- ASSERT(tmpbuffer2);
- memcpy(bp->data, tmpbuffer2, lbsize);
- } else {
- xfs_da_log_buf(trans, bp, 0, lbsize - 1);
- }
-
- kmem_free(tmpbuffer, lbsize);
- if (musthave || justcheck)
- kmem_free(tmpbuffer2, lbsize);
- return rval;
-}
-
-/*
- * Redistribute the directory entries between two leaf nodes,
- * taking into account the size of the new entry.
- *
- * NOTE: if new block is empty, then it will get the upper half of old block.
- */
-STATIC void
-xfs_dir_leaf_rebalance(xfs_da_state_t *state, xfs_da_state_blk_t *blk1,
- xfs_da_state_blk_t *blk2)
-{
- xfs_da_state_blk_t *tmp_blk;
- xfs_dir_leafblock_t *leaf1, *leaf2;
- xfs_dir_leaf_hdr_t *hdr1, *hdr2;
- int count, totallen, max, space, swap;
-
- /*
- * Set up environment.
- */
- ASSERT(blk1->magic == XFS_DIR_LEAF_MAGIC);
- ASSERT(blk2->magic == XFS_DIR_LEAF_MAGIC);
- leaf1 = blk1->bp->data;
- leaf2 = blk2->bp->data;
- ASSERT(be16_to_cpu(leaf1->hdr.info.magic) == XFS_DIR_LEAF_MAGIC);
- ASSERT(be16_to_cpu(leaf2->hdr.info.magic) == XFS_DIR_LEAF_MAGIC);
-
- /*
- * Check ordering of blocks, reverse if it makes things simpler.
- */
- swap = 0;
- if (xfs_dir_leaf_order(blk1->bp, blk2->bp)) {
- tmp_blk = blk1;
- blk1 = blk2;
- blk2 = tmp_blk;
- leaf1 = blk1->bp->data;
- leaf2 = blk2->bp->data;
- swap = 1;
- }
- hdr1 = &leaf1->hdr;
- hdr2 = &leaf2->hdr;
-
- /*
- * Examine entries until we reduce the absolute difference in
- * byte usage between the two blocks to a minimum. Then get
- * the direction to copy and the number of elements to move.
- */
- state->inleaf = xfs_dir_leaf_figure_balance(state, blk1, blk2,
- &count, &totallen);
- if (swap)
- state->inleaf = !state->inleaf;
-
- /*
- * Move any entries required from leaf to leaf:
- */
- if (count < INT_GET(hdr1->count, ARCH_CONVERT)) {
- /*
- * Figure the total bytes to be added to the destination leaf.
- */
- count = INT_GET(hdr1->count, ARCH_CONVERT) - count; /* number entries being moved */
- space = INT_GET(hdr1->namebytes, ARCH_CONVERT) - totallen;
- space += count * ((uint)sizeof(xfs_dir_leaf_name_t)-1);
- space += count * (uint)sizeof(xfs_dir_leaf_entry_t);
-
- /*
- * leaf2 is the destination, compact it if it looks tight.
- */
- max = INT_GET(hdr2->firstused, ARCH_CONVERT) - (uint)sizeof(xfs_dir_leaf_hdr_t);
- max -= INT_GET(hdr2->count, ARCH_CONVERT) * (uint)sizeof(xfs_dir_leaf_entry_t);
- if (space > max) {
- xfs_dir_leaf_compact(state->args->trans, blk2->bp,
- 0, 0);
- }
-
- /*
- * Move high entries from leaf1 to low end of leaf2.
- */
- xfs_dir_leaf_moveents(leaf1, INT_GET(hdr1->count, ARCH_CONVERT) - count,
- leaf2, 0, count, state->mp);
-
- xfs_da_log_buf(state->args->trans, blk1->bp, 0,
- state->blocksize-1);
- xfs_da_log_buf(state->args->trans, blk2->bp, 0,
- state->blocksize-1);
-
- } else if (count > INT_GET(hdr1->count, ARCH_CONVERT)) {
- /*
- * Figure the total bytes to be added to the destination leaf.
- */
- count -= INT_GET(hdr1->count, ARCH_CONVERT); /* number entries being moved */
- space = totallen - INT_GET(hdr1->namebytes, ARCH_CONVERT);
- space += count * ((uint)sizeof(xfs_dir_leaf_name_t)-1);
- space += count * (uint)sizeof(xfs_dir_leaf_entry_t);
-
- /*
- * leaf1 is the destination, compact it if it looks tight.
- */
- max = INT_GET(hdr1->firstused, ARCH_CONVERT) - (uint)sizeof(xfs_dir_leaf_hdr_t);
- max -= INT_GET(hdr1->count, ARCH_CONVERT) * (uint)sizeof(xfs_dir_leaf_entry_t);
- if (space > max) {
- xfs_dir_leaf_compact(state->args->trans, blk1->bp,
- 0, 0);
- }
-
- /*
- * Move low entries from leaf2 to high end of leaf1.
- */
- xfs_dir_leaf_moveents(leaf2, 0, leaf1, (int)INT_GET(hdr1->count, ARCH_CONVERT),
- count, state->mp);
-
- xfs_da_log_buf(state->args->trans, blk1->bp, 0,
- state->blocksize-1);
- xfs_da_log_buf(state->args->trans, blk2->bp, 0,
- state->blocksize-1);
- }
-
- /*
- * Copy out last hashval in each block for B-tree code.
- */
- blk1->hashval = INT_GET(leaf1->entries[ INT_GET(leaf1->hdr.count, ARCH_CONVERT)-1 ].hashval, ARCH_CONVERT);
- blk2->hashval = INT_GET(leaf2->entries[ INT_GET(leaf2->hdr.count, ARCH_CONVERT)-1 ].hashval, ARCH_CONVERT);
-
- /*
- * Adjust the expected index for insertion.
- * GROT: this doesn't work unless blk2 was originally empty.
- */
- if (!state->inleaf) {
- blk2->index = blk1->index - INT_GET(leaf1->hdr.count, ARCH_CONVERT);
- }
-}
-
-/*
- * Examine entries until we reduce the absolute difference in
- * byte usage between the two blocks to a minimum.
- * GROT: Is this really necessary? With other than a 512 byte blocksize,
- * GROT: there will always be enough room in either block for a new entry.
- * GROT: Do a double-split for this case?
- */
-STATIC int
-xfs_dir_leaf_figure_balance(xfs_da_state_t *state,
- xfs_da_state_blk_t *blk1,
- xfs_da_state_blk_t *blk2,
- int *countarg, int *namebytesarg)
-{
- xfs_dir_leafblock_t *leaf1, *leaf2;
- xfs_dir_leaf_hdr_t *hdr1, *hdr2;
- xfs_dir_leaf_entry_t *entry;
- int count, max, totallen, half;
- int lastdelta, foundit, tmp;
-
- /*
- * Set up environment.
- */
- leaf1 = blk1->bp->data;
- leaf2 = blk2->bp->data;
- hdr1 = &leaf1->hdr;
- hdr2 = &leaf2->hdr;
- foundit = 0;
- totallen = 0;
-
- /*
- * Examine entries until we reduce the absolute difference in
- * byte usage between the two blocks to a minimum.
- */
- max = INT_GET(hdr1->count, ARCH_CONVERT) + INT_GET(hdr2->count, ARCH_CONVERT);
- half = (max+1) * (uint)(sizeof(*entry)+sizeof(xfs_dir_leaf_entry_t)-1);
- half += INT_GET(hdr1->namebytes, ARCH_CONVERT) + INT_GET(hdr2->namebytes, ARCH_CONVERT) + state->args->namelen;
- half /= 2;
- lastdelta = state->blocksize;
- entry = &leaf1->entries[0];
- for (count = 0; count < max; entry++, count++) {
-
-#define XFS_DIR_ABS(A) (((A) < 0) ? -(A) : (A))
- /*
- * The new entry is in the first block, account for it.
- */
- if (count == blk1->index) {
- tmp = totallen + (uint)sizeof(*entry)
- + XFS_DIR_LEAF_ENTSIZE_BYNAME(state->args->namelen);
- if (XFS_DIR_ABS(half - tmp) > lastdelta)
- break;
- lastdelta = XFS_DIR_ABS(half - tmp);
- totallen = tmp;
- foundit = 1;
- }
-
- /*
- * Wrap around into the second block if necessary.
- */
- if (count == INT_GET(hdr1->count, ARCH_CONVERT)) {
- leaf1 = leaf2;
- entry = &leaf1->entries[0];
- }
-
- /*
- * Figure out if next leaf entry would be too much.
- */
- tmp = totallen + (uint)sizeof(*entry)
- + XFS_DIR_LEAF_ENTSIZE_BYENTRY(entry);
- if (XFS_DIR_ABS(half - tmp) > lastdelta)
- break;
- lastdelta = XFS_DIR_ABS(half - tmp);
- totallen = tmp;
-#undef XFS_DIR_ABS
- }
-
- /*
- * Calculate the number of namebytes that will end up in lower block.
- * If new entry not in lower block, fix up the count.
- */
- totallen -=
- count * (uint)(sizeof(*entry)+sizeof(xfs_dir_leaf_entry_t)-1);
- if (foundit) {
- totallen -= (sizeof(*entry)+sizeof(xfs_dir_leaf_entry_t)-1) +
- state->args->namelen;
- }
-
- *countarg = count;
- *namebytesarg = totallen;
- return foundit;
-}
-
-/*========================================================================
- * Routines used for shrinking the Btree.
- *========================================================================*/
-
-/*
- * Check a leaf block and its neighbors to see if the block should be
- * collapsed into one or the other neighbor. Always keep the block
- * with the smaller block number.
- * If the current block is over 50% full, don't try to join it, return 0.
- * If the block is empty, fill in the state structure and return 2.
- * If it can be collapsed, fill in the state structure and return 1.
- * If nothing can be done, return 0.
- */
-int
-xfs_dir_leaf_toosmall(xfs_da_state_t *state, int *action)
-{
- xfs_dir_leafblock_t *leaf;
- xfs_da_state_blk_t *blk;
- xfs_da_blkinfo_t *info;
- int count, bytes, forward, error, retval, i;
- xfs_dablk_t blkno;
- xfs_dabuf_t *bp;
-
- /*
- * Check for the degenerate case of the block being over 50% full.
- * If so, it's not worth even looking to see if we might be able
- * to coalesce with a sibling.
- */
- blk = &state->path.blk[ state->path.active-1 ];
- info = blk->bp->data;
- ASSERT(be16_to_cpu(info->magic) == XFS_DIR_LEAF_MAGIC);
- leaf = (xfs_dir_leafblock_t *)info;
- count = INT_GET(leaf->hdr.count, ARCH_CONVERT);
- bytes = (uint)sizeof(xfs_dir_leaf_hdr_t) +
- count * (uint)sizeof(xfs_dir_leaf_entry_t) +
- count * ((uint)sizeof(xfs_dir_leaf_name_t)-1) +
- INT_GET(leaf->hdr.namebytes, ARCH_CONVERT);
- if (bytes > (state->blocksize >> 1)) {
- *action = 0; /* blk over 50%, don't try to join */
- return 0;
- }
-
- /*
- * Check for the degenerate case of the block being empty.
- * If the block is empty, we'll simply delete it, no need to
- * coalesce it with a sibling block. We choose (arbitrarily)
- * to merge with the forward block unless it is NULL.
- */
- if (count == 0) {
- /*
- * Make altpath point to the block we want to keep and
- * path point to the block we want to drop (this one).
- */
- forward = (info->forw != 0);
- memcpy(&state->altpath, &state->path, sizeof(state->path));
- error = xfs_da_path_shift(state, &state->altpath, forward,
- 0, &retval);
- if (error)
- return error;
- if (retval) {
- *action = 0;
- } else {
- *action = 2;
- }
- return 0;
- }
-
- /*
- * Examine each sibling block to see if we can coalesce with
- * at least 25% free space to spare. We need to figure out
- * whether to merge with the forward or the backward block.
- * We prefer coalescing with the lower numbered sibling so as
- * to shrink a directory over time.
- */
- forward = (be32_to_cpu(info->forw) < be32_to_cpu(info->back)); /* start with smaller blk num */
- for (i = 0; i < 2; forward = !forward, i++) {
- if (forward)
- blkno = be32_to_cpu(info->forw);
- else
- blkno = be32_to_cpu(info->back);
- if (blkno == 0)
- continue;
- error = xfs_da_read_buf(state->args->trans, state->args->dp,
- blkno, -1, &bp,
- XFS_DATA_FORK);
- if (error)
- return error;
- ASSERT(bp != NULL);
-
- leaf = (xfs_dir_leafblock_t *)info;
- count = INT_GET(leaf->hdr.count, ARCH_CONVERT);
- bytes = state->blocksize - (state->blocksize>>2);
- bytes -= INT_GET(leaf->hdr.namebytes, ARCH_CONVERT);
- leaf = bp->data;
- ASSERT(be16_to_cpu(leaf->hdr.info.magic) == XFS_DIR_LEAF_MAGIC);
- count += INT_GET(leaf->hdr.count, ARCH_CONVERT);
- bytes -= INT_GET(leaf->hdr.namebytes, ARCH_CONVERT);
- bytes -= count * ((uint)sizeof(xfs_dir_leaf_name_t) - 1);
- bytes -= count * (uint)sizeof(xfs_dir_leaf_entry_t);
- bytes -= (uint)sizeof(xfs_dir_leaf_hdr_t);
- if (bytes >= 0)
- break; /* fits with at least 25% to spare */
-
- xfs_da_brelse(state->args->trans, bp);
- }
- if (i >= 2) {
- *action = 0;
- return 0;
- }
- xfs_da_buf_done(bp);
-
- /*
- * Make altpath point to the block we want to keep (the lower
- * numbered block) and path point to the block we want to drop.
- */
- memcpy(&state->altpath, &state->path, sizeof(state->path));
- if (blkno < blk->blkno) {
- error = xfs_da_path_shift(state, &state->altpath, forward,
- 0, &retval);
- } else {
- error = xfs_da_path_shift(state, &state->path, forward,
- 0, &retval);
- }
- if (error)
- return error;
- if (retval) {
- *action = 0;
- } else {
- *action = 1;
- }
- return 0;
-}
-
-/*
- * Remove a name from the leaf directory structure.
- *
- * Return 1 if leaf is less than 37% full, 0 if >= 37% full.
- * If two leaves are 37% full, when combined they will leave 25% free.
- */
-int
-xfs_dir_leaf_remove(xfs_trans_t *trans, xfs_dabuf_t *bp, int index)
-{
- xfs_dir_leafblock_t *leaf;
- xfs_dir_leaf_hdr_t *hdr;
- xfs_dir_leaf_map_t *map;
- xfs_dir_leaf_entry_t *entry;
- xfs_dir_leaf_name_t *namest;
- int before, after, smallest, entsize;
- int tablesize, tmp, i;
- xfs_mount_t *mp;
-
- leaf = bp->data;
- ASSERT(be16_to_cpu(leaf->hdr.info.magic) == XFS_DIR_LEAF_MAGIC);
- hdr = &leaf->hdr;
- mp = trans->t_mountp;
- ASSERT((INT_GET(hdr->count, ARCH_CONVERT) > 0) && (INT_GET(hdr->count, ARCH_CONVERT) < (XFS_LBSIZE(mp)/8)));
- ASSERT((index >= 0) && (index < INT_GET(hdr->count, ARCH_CONVERT)));
- ASSERT(INT_GET(hdr->firstused, ARCH_CONVERT) >= ((INT_GET(hdr->count, ARCH_CONVERT)*sizeof(*entry))+sizeof(*hdr)));
- entry = &leaf->entries[index];
- ASSERT(INT_GET(entry->nameidx, ARCH_CONVERT) >= INT_GET(hdr->firstused, ARCH_CONVERT));
- ASSERT(INT_GET(entry->nameidx, ARCH_CONVERT) < XFS_LBSIZE(mp));
-
- /*
- * Scan through free region table:
- * check for adjacency of free'd entry with an existing one,
- * find smallest free region in case we need to replace it,
- * adjust any map that borders the entry table,
- */
- tablesize = INT_GET(hdr->count, ARCH_CONVERT) * (uint)sizeof(xfs_dir_leaf_entry_t)
- + (uint)sizeof(xfs_dir_leaf_hdr_t);
- map = &hdr->freemap[0];
- tmp = INT_GET(map->size, ARCH_CONVERT);
- before = after = -1;
- smallest = XFS_DIR_LEAF_MAPSIZE - 1;
- entsize = XFS_DIR_LEAF_ENTSIZE_BYENTRY(entry);
- for (i = 0; i < XFS_DIR_LEAF_MAPSIZE; map++, i++) {
- ASSERT(INT_GET(map->base, ARCH_CONVERT) < XFS_LBSIZE(mp));
- ASSERT(INT_GET(map->size, ARCH_CONVERT) < XFS_LBSIZE(mp));
- if (INT_GET(map->base, ARCH_CONVERT) == tablesize) {
- INT_MOD(map->base, ARCH_CONVERT, -((uint)sizeof(xfs_dir_leaf_entry_t)));
- INT_MOD(map->size, ARCH_CONVERT, (uint)sizeof(xfs_dir_leaf_entry_t));
- }
-
- if ((INT_GET(map->base, ARCH_CONVERT) + INT_GET(map->size, ARCH_CONVERT)) == INT_GET(entry->nameidx, ARCH_CONVERT)) {
- before = i;
- } else if (INT_GET(map->base, ARCH_CONVERT) == (INT_GET(entry->nameidx, ARCH_CONVERT) + entsize)) {
- after = i;
- } else if (INT_GET(map->size, ARCH_CONVERT) < tmp) {
- tmp = INT_GET(map->size, ARCH_CONVERT);
- smallest = i;
- }
- }
-
- /*
- * Coalesce adjacent freemap regions,
- * or replace the smallest region.
- */
- if ((before >= 0) || (after >= 0)) {
- if ((before >= 0) && (after >= 0)) {
- map = &hdr->freemap[before];
- INT_MOD(map->size, ARCH_CONVERT, entsize);
- INT_MOD(map->size, ARCH_CONVERT, INT_GET(hdr->freemap[after].size, ARCH_CONVERT));
- hdr->freemap[after].base = 0;
- hdr->freemap[after].size = 0;
- } else if (before >= 0) {
- map = &hdr->freemap[before];
- INT_MOD(map->size, ARCH_CONVERT, entsize);
- } else {
- map = &hdr->freemap[after];
- INT_COPY(map->base, entry->nameidx, ARCH_CONVERT);
- INT_MOD(map->size, ARCH_CONVERT, entsize);
- }
- } else {
- /*
- * Replace smallest region (if it is smaller than free'd entry)
- */
- map = &hdr->freemap[smallest];
- if (INT_GET(map->size, ARCH_CONVERT) < entsize) {
- INT_COPY(map->base, entry->nameidx, ARCH_CONVERT);
- INT_SET(map->size, ARCH_CONVERT, entsize);
- }
- }
-
- /*
- * Did we remove the first entry?
- */
- if (INT_GET(entry->nameidx, ARCH_CONVERT) == INT_GET(hdr->firstused, ARCH_CONVERT))
- smallest = 1;
- else
- smallest = 0;
-
- /*
- * Compress the remaining entries and zero out the removed stuff.
- */
- namest = XFS_DIR_LEAF_NAMESTRUCT(leaf, INT_GET(entry->nameidx, ARCH_CONVERT));
- memset((char *)namest, 0, entsize);
- xfs_da_log_buf(trans, bp, XFS_DA_LOGRANGE(leaf, namest, entsize));
-
- INT_MOD(hdr->namebytes, ARCH_CONVERT, -(entry->namelen));
- tmp = (INT_GET(hdr->count, ARCH_CONVERT) - index) * (uint)sizeof(xfs_dir_leaf_entry_t);
- memmove(entry, entry + 1, tmp);
- INT_MOD(hdr->count, ARCH_CONVERT, -1);
- xfs_da_log_buf(trans, bp,
- XFS_DA_LOGRANGE(leaf, entry, tmp + (uint)sizeof(*entry)));
- entry = &leaf->entries[INT_GET(hdr->count, ARCH_CONVERT)];
- memset((char *)entry, 0, sizeof(xfs_dir_leaf_entry_t));
-
- /*
- * If we removed the first entry, re-find the first used byte
- * in the name area. Note that if the entry was the "firstused",
- * then we don't have a "hole" in our block resulting from
- * removing the name.
- */
- if (smallest) {
- tmp = XFS_LBSIZE(mp);
- entry = &leaf->entries[0];
- for (i = INT_GET(hdr->count, ARCH_CONVERT)-1; i >= 0; entry++, i--) {
- ASSERT(INT_GET(entry->nameidx, ARCH_CONVERT) >= INT_GET(hdr->firstused, ARCH_CONVERT));
- ASSERT(INT_GET(entry->nameidx, ARCH_CONVERT) < XFS_LBSIZE(mp));
- if (INT_GET(entry->nameidx, ARCH_CONVERT) < tmp)
- tmp = INT_GET(entry->nameidx, ARCH_CONVERT);
- }
- INT_SET(hdr->firstused, ARCH_CONVERT, tmp);
- if (!hdr->firstused)
- INT_SET(hdr->firstused, ARCH_CONVERT, tmp - 1);
- } else {
- hdr->holes = 1; /* mark as needing compaction */
- }
-
- xfs_da_log_buf(trans, bp, XFS_DA_LOGRANGE(leaf, hdr, sizeof(*hdr)));
-
- /*
- * Check if leaf is less than 50% full, caller may want to
- * "join" the leaf with a sibling if so.
- */
- tmp = (uint)sizeof(xfs_dir_leaf_hdr_t);
- tmp += INT_GET(leaf->hdr.count, ARCH_CONVERT) * (uint)sizeof(xfs_dir_leaf_entry_t);
- tmp += INT_GET(leaf->hdr.count, ARCH_CONVERT) * ((uint)sizeof(xfs_dir_leaf_name_t) - 1);
- tmp += INT_GET(leaf->hdr.namebytes, ARCH_CONVERT);
- if (tmp < mp->m_dir_magicpct)
- return 1; /* leaf is < 37% full */
- return 0;
-}
-
-/*
- * Move all the directory entries from drop_leaf into save_leaf.
- */
-void
-xfs_dir_leaf_unbalance(xfs_da_state_t *state, xfs_da_state_blk_t *drop_blk,
- xfs_da_state_blk_t *save_blk)
-{
- xfs_dir_leafblock_t *drop_leaf, *save_leaf, *tmp_leaf;
- xfs_dir_leaf_hdr_t *drop_hdr, *save_hdr, *tmp_hdr;
- xfs_mount_t *mp;
- char *tmpbuffer;
-
- /*
- * Set up environment.
- */
- mp = state->mp;
- ASSERT(drop_blk->magic == XFS_DIR_LEAF_MAGIC);
- ASSERT(save_blk->magic == XFS_DIR_LEAF_MAGIC);
- drop_leaf = drop_blk->bp->data;
- save_leaf = save_blk->bp->data;
- ASSERT(be16_to_cpu(drop_leaf->hdr.info.magic) == XFS_DIR_LEAF_MAGIC);
- ASSERT(be16_to_cpu(save_leaf->hdr.info.magic) == XFS_DIR_LEAF_MAGIC);
- drop_hdr = &drop_leaf->hdr;
- save_hdr = &save_leaf->hdr;
-
- /*
- * Save last hashval from dying block for later Btree fixup.
- */
- drop_blk->hashval = INT_GET(drop_leaf->entries[ drop_leaf->hdr.count-1 ].hashval, ARCH_CONVERT);
-
- /*
- * Check if we need a temp buffer, or can we do it in place.
- * Note that we don't check "leaf" for holes because we will
- * always be dropping it, toosmall() decided that for us already.
- */
- if (save_hdr->holes == 0) {
- /*
- * dest leaf has no holes, so we add there. May need
- * to make some room in the entry array.
- */
- if (xfs_dir_leaf_order(save_blk->bp, drop_blk->bp)) {
- xfs_dir_leaf_moveents(drop_leaf, 0, save_leaf, 0,
- (int)INT_GET(drop_hdr->count, ARCH_CONVERT), mp);
- } else {
- xfs_dir_leaf_moveents(drop_leaf, 0,
- save_leaf, INT_GET(save_hdr->count, ARCH_CONVERT),
- (int)INT_GET(drop_hdr->count, ARCH_CONVERT), mp);
- }
- } else {
- /*
- * Destination has holes, so we make a temporary copy
- * of the leaf and add them both to that.
- */
- tmpbuffer = kmem_alloc(state->blocksize, KM_SLEEP);
- ASSERT(tmpbuffer != NULL);
- memset(tmpbuffer, 0, state->blocksize);
- tmp_leaf = (xfs_dir_leafblock_t *)tmpbuffer;
- tmp_hdr = &tmp_leaf->hdr;
- tmp_hdr->info = save_hdr->info; /* struct copy */
- tmp_hdr->count = 0;
- INT_SET(tmp_hdr->firstused, ARCH_CONVERT, state->blocksize);
- if (!tmp_hdr->firstused)
- INT_SET(tmp_hdr->firstused, ARCH_CONVERT, state->blocksize - 1);
- tmp_hdr->namebytes = 0;
- if (xfs_dir_leaf_order(save_blk->bp, drop_blk->bp)) {
- xfs_dir_leaf_moveents(drop_leaf, 0, tmp_leaf, 0,
- (int)INT_GET(drop_hdr->count, ARCH_CONVERT), mp);
- xfs_dir_leaf_moveents(save_leaf, 0,
- tmp_leaf, INT_GET(tmp_leaf->hdr.count, ARCH_CONVERT),
- (int)INT_GET(save_hdr->count, ARCH_CONVERT), mp);
- } else {
- xfs_dir_leaf_moveents(save_leaf, 0, tmp_leaf, 0,
- (int)INT_GET(save_hdr->count, ARCH_CONVERT), mp);
- xfs_dir_leaf_moveents(drop_leaf, 0,
- tmp_leaf, INT_GET(tmp_leaf->hdr.count, ARCH_CONVERT),
- (int)INT_GET(drop_hdr->count, ARCH_CONVERT), mp);
- }
- memcpy(save_leaf, tmp_leaf, state->blocksize);
- kmem_free(tmpbuffer, state->blocksize);
- }
-
- xfs_da_log_buf(state->args->trans, save_blk->bp, 0,
- state->blocksize - 1);
-
- /*
- * Copy out last hashval in each block for B-tree code.
- */
- save_blk->hashval = INT_GET(save_leaf->entries[ INT_GET(save_leaf->hdr.count, ARCH_CONVERT)-1 ].hashval, ARCH_CONVERT);
-}
-
-/*========================================================================
- * Routines used for finding things in the Btree.
- *========================================================================*/
-
-/*
- * Look up a name in a leaf directory structure.
- * This is the internal routine, it uses the caller's buffer.
- *
- * Note that duplicate keys are allowed, but only check within the
- * current leaf node. The Btree code must check in adjacent leaf nodes.
- *
- * Return in *index the index into the entry[] array of either the found
- * entry, or where the entry should have been (insert before that entry).
- *
- * Don't change the args->inumber unless we find the filename.
- */
-int
-xfs_dir_leaf_lookup_int(xfs_dabuf_t *bp, xfs_da_args_t *args, int *index)
-{
- xfs_dir_leafblock_t *leaf;
- xfs_dir_leaf_entry_t *entry;
- xfs_dir_leaf_name_t *namest;
- int probe, span;
- xfs_dahash_t hashval;
-
- leaf = bp->data;
- ASSERT(be16_to_cpu(leaf->hdr.info.magic) == XFS_DIR_LEAF_MAGIC);
- ASSERT(INT_GET(leaf->hdr.count, ARCH_CONVERT) < (XFS_LBSIZE(args->dp->i_mount)/8));
-
- /*
- * Binary search. (note: small blocks will skip this loop)
- */
- hashval = args->hashval;
- probe = span = INT_GET(leaf->hdr.count, ARCH_CONVERT) / 2;
- for (entry = &leaf->entries[probe]; span > 4;
- entry = &leaf->entries[probe]) {
- span /= 2;
- if (INT_GET(entry->hashval, ARCH_CONVERT) < hashval)
- probe += span;
- else if (INT_GET(entry->hashval, ARCH_CONVERT) > hashval)
- probe -= span;
- else
- break;
- }
- ASSERT((probe >= 0) && \
- ((!leaf->hdr.count) || (probe < INT_GET(leaf->hdr.count, ARCH_CONVERT))));
- ASSERT((span <= 4) || (INT_GET(entry->hashval, ARCH_CONVERT) == hashval));
-
- /*
- * Since we may have duplicate hashval's, find the first matching
- * hashval in the leaf.
- */
- while ((probe > 0) && (INT_GET(entry->hashval, ARCH_CONVERT) >= hashval)) {
- entry--;
- probe--;
- }
- while ((probe < INT_GET(leaf->hdr.count, ARCH_CONVERT)) && (INT_GET(entry->hashval, ARCH_CONVERT) < hashval)) {
- entry++;
- probe++;
- }
- if ((probe == INT_GET(leaf->hdr.count, ARCH_CONVERT)) || (INT_GET(entry->hashval, ARCH_CONVERT) != hashval)) {
- *index = probe;
- ASSERT(args->oknoent);
- return XFS_ERROR(ENOENT);
- }
-
- /*
- * Duplicate keys may be present, so search all of them for a match.
- */
- while ((probe < INT_GET(leaf->hdr.count, ARCH_CONVERT)) && (INT_GET(entry->hashval, ARCH_CONVERT) == hashval)) {
- namest = XFS_DIR_LEAF_NAMESTRUCT(leaf, INT_GET(entry->nameidx, ARCH_CONVERT));
- if (entry->namelen == args->namelen &&
- namest->name[0] == args->name[0] &&
- memcmp(args->name, namest->name, args->namelen) == 0) {
- XFS_DIR_SF_GET_DIRINO(&namest->inumber, &args->inumber);
- *index = probe;
- return XFS_ERROR(EEXIST);
- }
- entry++;
- probe++;
- }
- *index = probe;
- ASSERT(probe == INT_GET(leaf->hdr.count, ARCH_CONVERT) || args->oknoent);
- return XFS_ERROR(ENOENT);
-}
-
-/*========================================================================
- * Utility routines.
- *========================================================================*/
-
-/*
- * Move the indicated entries from one leaf to another.
- * NOTE: this routine modifies both source and destination leaves.
- */
-/* ARGSUSED */
-STATIC void
-xfs_dir_leaf_moveents(xfs_dir_leafblock_t *leaf_s, int start_s,
- xfs_dir_leafblock_t *leaf_d, int start_d,
- int count, xfs_mount_t *mp)
-{
- xfs_dir_leaf_hdr_t *hdr_s, *hdr_d;
- xfs_dir_leaf_entry_t *entry_s, *entry_d;
- int tmp, i;
-
- /*
- * Check for nothing to do.
- */
- if (count == 0)
- return;
-
- /*
- * Set up environment.
- */
- ASSERT(be16_to_cpu(leaf_s->hdr.info.magic) == XFS_DIR_LEAF_MAGIC);
- ASSERT(be16_to_cpu(leaf_d->hdr.info.magic) == XFS_DIR_LEAF_MAGIC);
- hdr_s = &leaf_s->hdr;
- hdr_d = &leaf_d->hdr;
- ASSERT((INT_GET(hdr_s->count, ARCH_CONVERT) > 0) && (INT_GET(hdr_s->count, ARCH_CONVERT) < (XFS_LBSIZE(mp)/8)));
- ASSERT(INT_GET(hdr_s->firstused, ARCH_CONVERT) >=
- ((INT_GET(hdr_s->count, ARCH_CONVERT)*sizeof(*entry_s))+sizeof(*hdr_s)));
- ASSERT(INT_GET(hdr_d->count, ARCH_CONVERT) < (XFS_LBSIZE(mp)/8));
- ASSERT(INT_GET(hdr_d->firstused, ARCH_CONVERT) >=
- ((INT_GET(hdr_d->count, ARCH_CONVERT)*sizeof(*entry_d))+sizeof(*hdr_d)));
-
- ASSERT(start_s < INT_GET(hdr_s->count, ARCH_CONVERT));
- ASSERT(start_d <= INT_GET(hdr_d->count, ARCH_CONVERT));
- ASSERT(count <= INT_GET(hdr_s->count, ARCH_CONVERT));
-
- /*
- * Move the entries in the destination leaf up to make a hole?
- */
- if (start_d < INT_GET(hdr_d->count, ARCH_CONVERT)) {
- tmp = INT_GET(hdr_d->count, ARCH_CONVERT) - start_d;
- tmp *= (uint)sizeof(xfs_dir_leaf_entry_t);
- entry_s = &leaf_d->entries[start_d];
- entry_d = &leaf_d->entries[start_d + count];
- memcpy(entry_d, entry_s, tmp);
- }
-
- /*
- * Copy all entry's in the same (sorted) order,
- * but allocate filenames packed and in sequence.
- */
- entry_s = &leaf_s->entries[start_s];
- entry_d = &leaf_d->entries[start_d];
- for (i = 0; i < count; entry_s++, entry_d++, i++) {
- ASSERT(INT_GET(entry_s->nameidx, ARCH_CONVERT) >= INT_GET(hdr_s->firstused, ARCH_CONVERT));
- tmp = XFS_DIR_LEAF_ENTSIZE_BYENTRY(entry_s);
- INT_MOD(hdr_d->firstused, ARCH_CONVERT, -(tmp));
- entry_d->hashval = entry_s->hashval; /* INT_: direct copy */
- INT_COPY(entry_d->nameidx, hdr_d->firstused, ARCH_CONVERT);
- entry_d->namelen = entry_s->namelen;
- ASSERT(INT_GET(entry_d->nameidx, ARCH_CONVERT) + tmp <= XFS_LBSIZE(mp));
- memcpy(XFS_DIR_LEAF_NAMESTRUCT(leaf_d, INT_GET(entry_d->nameidx, ARCH_CONVERT)),
- XFS_DIR_LEAF_NAMESTRUCT(leaf_s, INT_GET(entry_s->nameidx, ARCH_CONVERT)), tmp);
- ASSERT(INT_GET(entry_s->nameidx, ARCH_CONVERT) + tmp <= XFS_LBSIZE(mp));
- memset((char *)XFS_DIR_LEAF_NAMESTRUCT(leaf_s, INT_GET(entry_s->nameidx, ARCH_CONVERT)),
- 0, tmp);
- INT_MOD(hdr_s->namebytes, ARCH_CONVERT, -(entry_d->namelen));
- INT_MOD(hdr_d->namebytes, ARCH_CONVERT, entry_d->namelen);
- INT_MOD(hdr_s->count, ARCH_CONVERT, -1);
- INT_MOD(hdr_d->count, ARCH_CONVERT, +1);
- tmp = INT_GET(hdr_d->count, ARCH_CONVERT) * (uint)sizeof(xfs_dir_leaf_entry_t)
- + (uint)sizeof(xfs_dir_leaf_hdr_t);
- ASSERT(INT_GET(hdr_d->firstused, ARCH_CONVERT) >= tmp);
-
- }
-
- /*
- * Zero out the entries we just copied.
- */
- if (start_s == INT_GET(hdr_s->count, ARCH_CONVERT)) {
- tmp = count * (uint)sizeof(xfs_dir_leaf_entry_t);
- entry_s = &leaf_s->entries[start_s];
- ASSERT((char *)entry_s + tmp <= (char *)leaf_s + XFS_LBSIZE(mp));
- memset((char *)entry_s, 0, tmp);
- } else {
- /*
- * Move the remaining entries down to fill the hole,
- * then zero the entries at the top.
- */
- tmp = INT_GET(hdr_s->count, ARCH_CONVERT) - count;
- tmp *= (uint)sizeof(xfs_dir_leaf_entry_t);
- entry_s = &leaf_s->entries[start_s + count];
- entry_d = &leaf_s->entries[start_s];
- memcpy(entry_d, entry_s, tmp);
-
- tmp = count * (uint)sizeof(xfs_dir_leaf_entry_t);
- entry_s = &leaf_s->entries[INT_GET(hdr_s->count, ARCH_CONVERT)];
- ASSERT((char *)entry_s + tmp <= (char *)leaf_s + XFS_LBSIZE(mp));
- memset((char *)entry_s, 0, tmp);
- }
-
- /*
- * Fill in the freemap information
- */
- INT_SET(hdr_d->freemap[0].base, ARCH_CONVERT, (uint)sizeof(xfs_dir_leaf_hdr_t));
- INT_MOD(hdr_d->freemap[0].base, ARCH_CONVERT, INT_GET(hdr_d->count, ARCH_CONVERT) * (uint)sizeof(xfs_dir_leaf_entry_t));
- INT_SET(hdr_d->freemap[0].size, ARCH_CONVERT, INT_GET(hdr_d->firstused, ARCH_CONVERT) - INT_GET(hdr_d->freemap[0].base, ARCH_CONVERT));
- INT_SET(hdr_d->freemap[1].base, ARCH_CONVERT, (hdr_d->freemap[2].base = 0));
- INT_SET(hdr_d->freemap[1].size, ARCH_CONVERT, (hdr_d->freemap[2].size = 0));
- hdr_s->holes = 1; /* leaf may not be compact */
-}
-
-/*
- * Compare two leaf blocks "order".
- */
-int
-xfs_dir_leaf_order(xfs_dabuf_t *leaf1_bp, xfs_dabuf_t *leaf2_bp)
-{
- xfs_dir_leafblock_t *leaf1, *leaf2;
-
- leaf1 = leaf1_bp->data;
- leaf2 = leaf2_bp->data;
- ASSERT((be16_to_cpu(leaf1->hdr.info.magic) == XFS_DIR_LEAF_MAGIC) &&
- (be16_to_cpu(leaf2->hdr.info.magic) == XFS_DIR_LEAF_MAGIC));
- if ((INT_GET(leaf1->hdr.count, ARCH_CONVERT) > 0) && (INT_GET(leaf2->hdr.count, ARCH_CONVERT) > 0) &&
- ((INT_GET(leaf2->entries[ 0 ].hashval, ARCH_CONVERT) <
- INT_GET(leaf1->entries[ 0 ].hashval, ARCH_CONVERT)) ||
- (INT_GET(leaf2->entries[ INT_GET(leaf2->hdr.count, ARCH_CONVERT)-1 ].hashval, ARCH_CONVERT) <
- INT_GET(leaf1->entries[ INT_GET(leaf1->hdr.count, ARCH_CONVERT)-1 ].hashval, ARCH_CONVERT)))) {
- return 1;
- }
- return 0;
-}
-
-/*
- * Pick up the last hashvalue from a leaf block.
- */
-xfs_dahash_t
-xfs_dir_leaf_lasthash(xfs_dabuf_t *bp, int *count)
-{
- xfs_dir_leafblock_t *leaf;
-
- leaf = bp->data;
- ASSERT(be16_to_cpu(leaf->hdr.info.magic) == XFS_DIR_LEAF_MAGIC);
- if (count)
- *count = INT_GET(leaf->hdr.count, ARCH_CONVERT);
- if (!leaf->hdr.count)
- return(0);
- return(INT_GET(leaf->entries[ INT_GET(leaf->hdr.count, ARCH_CONVERT)-1 ].hashval, ARCH_CONVERT));
-}
-
-/*
- * Copy out directory entries for getdents(), for leaf directories.
- */
-int
-xfs_dir_leaf_getdents_int(
- xfs_dabuf_t *bp,
- xfs_inode_t *dp,
- xfs_dablk_t bno,
- uio_t *uio,
- int *eobp,
- xfs_dirent_t *dbp,
- xfs_dir_put_t put,
- xfs_daddr_t nextda)
-{
- xfs_dir_leafblock_t *leaf;
- xfs_dir_leaf_entry_t *entry;
- xfs_dir_leaf_name_t *namest;
- int entno, want_entno, i, nextentno;
- xfs_mount_t *mp;
- xfs_dahash_t cookhash;
- xfs_dahash_t nexthash = 0;
-#if (BITS_PER_LONG == 32)
- xfs_dahash_t lasthash = XFS_DA_MAXHASH;
-#endif
- xfs_dir_put_args_t p;
-
- mp = dp->i_mount;
- leaf = bp->data;
- if (be16_to_cpu(leaf->hdr.info.magic) != XFS_DIR_LEAF_MAGIC) {
- *eobp = 1;
- return XFS_ERROR(ENOENT); /* XXX wrong code */
- }
-
- want_entno = XFS_DA_COOKIE_ENTRY(mp, uio->uio_offset);
-
- cookhash = XFS_DA_COOKIE_HASH(mp, uio->uio_offset);
-
- xfs_dir_trace_g_dul("leaf: start", dp, uio, leaf);
-
- /*
- * Re-find our place.
- */
- for (i = entno = 0, entry = &leaf->entries[0];
- i < INT_GET(leaf->hdr.count, ARCH_CONVERT);
- entry++, i++) {
-
- namest = XFS_DIR_LEAF_NAMESTRUCT(leaf,
- INT_GET(entry->nameidx, ARCH_CONVERT));
-
- if (unlikely(
- ((char *)namest < (char *)leaf) ||
- ((char *)namest >= (char *)leaf + XFS_LBSIZE(mp)))) {
- XFS_CORRUPTION_ERROR("xfs_dir_leaf_getdents_int(1)",
- XFS_ERRLEVEL_LOW, mp, leaf);
- xfs_dir_trace_g_du("leaf: corrupted", dp, uio);
- return XFS_ERROR(EFSCORRUPTED);
- }
- if (INT_GET(entry->hashval, ARCH_CONVERT) >= cookhash) {
- if ( entno < want_entno
- && INT_GET(entry->hashval, ARCH_CONVERT)
- == cookhash) {
- /*
- * Trying to get to a particular offset in a
- * run of equal-hashval entries.
- */
- entno++;
- } else if ( want_entno > 0
- && entno == want_entno
- && INT_GET(entry->hashval, ARCH_CONVERT)
- == cookhash) {
- break;
- } else {
- entno = 0;
- break;
- }
- }
- }
-
- if (i == INT_GET(leaf->hdr.count, ARCH_CONVERT)) {
- xfs_dir_trace_g_du("leaf: hash not found", dp, uio);
- if (!leaf->hdr.info.forw)
- uio->uio_offset =
- XFS_DA_MAKE_COOKIE(mp, 0, 0, XFS_DA_MAXHASH);
- /*
- * Don't set uio_offset if there's another block:
- * the node code will be setting uio_offset anyway.
- */
- *eobp = 0;
- return 0;
- }
- xfs_dir_trace_g_due("leaf: hash found", dp, uio, entry);
-
- p.dbp = dbp;
- p.put = put;
- p.uio = uio;
-
- /*
- * We're synchronized, start copying entries out to the user.
- */
- for (; entno >= 0 && i < INT_GET(leaf->hdr.count, ARCH_CONVERT);
- entry++, i++, (entno = nextentno)) {
- int lastresid=0, retval;
- xfs_dircook_t lastoffset;
- xfs_dahash_t thishash;
-
- /*
- * Check for a damaged directory leaf block and pick up
- * the inode number from this entry.
- */
- namest = XFS_DIR_LEAF_NAMESTRUCT(leaf,
- INT_GET(entry->nameidx, ARCH_CONVERT));
-
- if (unlikely(
- ((char *)namest < (char *)leaf) ||
- ((char *)namest >= (char *)leaf + XFS_LBSIZE(mp)))) {
- XFS_CORRUPTION_ERROR("xfs_dir_leaf_getdents_int(2)",
- XFS_ERRLEVEL_LOW, mp, leaf);
- xfs_dir_trace_g_du("leaf: corrupted", dp, uio);
- return XFS_ERROR(EFSCORRUPTED);
- }
-
- xfs_dir_trace_g_duc("leaf: middle cookie ",
- dp, uio, p.cook.o);
-
- if (i < (INT_GET(leaf->hdr.count, ARCH_CONVERT) - 1)) {
- nexthash = INT_GET(entry[1].hashval, ARCH_CONVERT);
-
- if (nexthash == INT_GET(entry->hashval, ARCH_CONVERT))
- nextentno = entno + 1;
- else
- nextentno = 0;
- XFS_PUT_COOKIE(p.cook, mp, bno, nextentno, nexthash);
- xfs_dir_trace_g_duc("leaf: middle cookie ",
- dp, uio, p.cook.o);
-
- } else if ((thishash = be32_to_cpu(leaf->hdr.info.forw))) {
- xfs_dabuf_t *bp2;
- xfs_dir_leafblock_t *leaf2;
-
- ASSERT(nextda != -1);
-
- retval = xfs_da_read_buf(dp->i_transp, dp, thishash,
- nextda, &bp2, XFS_DATA_FORK);
- if (retval)
- return retval;
-
- ASSERT(bp2 != NULL);
-
- leaf2 = bp2->data;
-
- if (unlikely(
- (be16_to_cpu(leaf2->hdr.info.magic)
- != XFS_DIR_LEAF_MAGIC)
- || (be32_to_cpu(leaf2->hdr.info.back)
- != bno))) { /* GROT */
- XFS_CORRUPTION_ERROR("xfs_dir_leaf_getdents_int(3)",
- XFS_ERRLEVEL_LOW, mp,
- leaf2);
- xfs_da_brelse(dp->i_transp, bp2);
-
- return XFS_ERROR(EFSCORRUPTED);
- }
-
- nexthash = INT_GET(leaf2->entries[0].hashval,
- ARCH_CONVERT);
- nextentno = -1;
- XFS_PUT_COOKIE(p.cook, mp, thishash, 0, nexthash);
- xfs_da_brelse(dp->i_transp, bp2);
- xfs_dir_trace_g_duc("leaf: next blk cookie",
- dp, uio, p.cook.o);
- } else {
- nextentno = -1;
- XFS_PUT_COOKIE(p.cook, mp, 0, 0, XFS_DA_MAXHASH);
- }
-
- /*
- * Save off the cookie so we can fall back should the
- * 'put' into the outgoing buffer fails. To handle a run
- * of equal-hashvals, the off_t structure on 64bit
- * builds has entno built into the cookie to ID the
- * entry. On 32bit builds, we only have space for the
- * hashval so we can't ID specific entries within a group
- * of same hashval entries. For this, lastoffset is set
- * to the first in the run of equal hashvals so we don't
- * include any entries unless we can include all entries
- * that share the same hashval. Hopefully the buffer
- * provided is big enough to handle it (see pv763517).
- */
-#if (BITS_PER_LONG == 32)
- if ((thishash = INT_GET(entry->hashval, ARCH_CONVERT))
- != lasthash) {
- XFS_PUT_COOKIE(lastoffset, mp, bno, entno, thishash);
- lastresid = uio->uio_resid;
- lasthash = thishash;
- } else {
- xfs_dir_trace_g_duc("leaf: DUP COOKIES, skipped",
- dp, uio, p.cook.o);
- }
-#else
- thishash = INT_GET(entry->hashval, ARCH_CONVERT);
- XFS_PUT_COOKIE(lastoffset, mp, bno, entno, thishash);
- lastresid = uio->uio_resid;
-#endif /* BITS_PER_LONG == 32 */
-
- /*
- * Put the current entry into the outgoing buffer. If we fail
- * then restore the UIO to the first entry in the current
- * run of equal-hashval entries (probably one 1 entry long).
- */
- p.ino = XFS_GET_DIR_INO8(namest->inumber);
-#if XFS_BIG_INUMS
- p.ino += mp->m_inoadd;
-#endif
- p.name = (char *)namest->name;
- p.namelen = entry->namelen;
-
- retval = p.put(&p);
-
- if (!p.done) {
- uio->uio_offset = lastoffset.o;
- uio->uio_resid = lastresid;
-
- *eobp = 1;
-
- xfs_dir_trace_g_du("leaf: E-O-B", dp, uio);
-
- return retval;
- }
- }
-
- uio->uio_offset = p.cook.o;
-
- *eobp = 0;
-
- xfs_dir_trace_g_du("leaf: E-O-F", dp, uio);
-
- return 0;
-}
-
-/*
- * Format a dirent64 structure and copy it out the user's buffer.
- */
-int
-xfs_dir_put_dirent64_direct(xfs_dir_put_args_t *pa)
-{
- iovec_t *iovp;
- int reclen, namelen;
- xfs_dirent_t *idbp;
- uio_t *uio;
-
- namelen = pa->namelen;
- reclen = DIRENTSIZE(namelen);
- uio = pa->uio;
- if (reclen > uio->uio_resid) {
- pa->done = 0;
- return 0;
- }
- iovp = uio->uio_iov;
- idbp = (xfs_dirent_t *)iovp->iov_base;
- iovp->iov_base = (char *)idbp + reclen;
- iovp->iov_len -= reclen;
- uio->uio_resid -= reclen;
- idbp->d_reclen = reclen;
- idbp->d_ino = pa->ino;
- idbp->d_off = pa->cook.o;
- idbp->d_name[namelen] = '\0';
- pa->done = 1;
- memcpy(idbp->d_name, pa->name, namelen);
- return 0;
-}
-
-/*
- * Format a dirent64 structure and copy it out the user's buffer.
- */
-int
-xfs_dir_put_dirent64_uio(xfs_dir_put_args_t *pa)
-{
- int retval, reclen, namelen;
- xfs_dirent_t *idbp;
- uio_t *uio;
-
- namelen = pa->namelen;
- reclen = DIRENTSIZE(namelen);
- uio = pa->uio;
- if (reclen > uio->uio_resid) {
- pa->done = 0;
- return 0;
- }
- idbp = pa->dbp;
- idbp->d_reclen = reclen;
- idbp->d_ino = pa->ino;
- idbp->d_off = pa->cook.o;
- idbp->d_name[namelen] = '\0';
- memcpy(idbp->d_name, pa->name, namelen);
- retval = uio_read((caddr_t)idbp, reclen, uio);
- pa->done = (retval == 0);
- return retval;
-}
-
-
diff --git a/sys/gnu/fs/xfs/xfs_dir_leaf.h b/sys/gnu/fs/xfs/xfs_dir_leaf.h
deleted file mode 100644
index eb8cd9a..0000000
--- a/sys/gnu/fs/xfs/xfs_dir_leaf.h
+++ /dev/null
@@ -1,231 +0,0 @@
-/*
- * Copyright (c) 2000-2001,2005 Silicon Graphics, Inc.
- * All Rights Reserved.
- *
- * 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.
- *
- * This program is distributed in the hope that it would 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 the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- */
-#ifndef __XFS_DIR_LEAF_H__
-#define __XFS_DIR_LEAF_H__
-
-/*
- * Directory layout, internal structure, access macros, etc.
- *
- * Large directories are structured around Btrees where all the data
- * elements are in the leaf nodes. Filenames are hashed into an int,
- * then that int is used as the index into the Btree. Since the hashval
- * of a filename may not be unique, we may have duplicate keys. The
- * internal links in the Btree are logical block offsets into the file.
- */
-
-struct uio;
-struct xfs_bmap_free;
-struct xfs_dabuf;
-struct xfs_da_args;
-struct xfs_da_state;
-struct xfs_da_state_blk;
-struct xfs_dir_put_args;
-struct xfs_inode;
-struct xfs_mount;
-struct xfs_trans;
-
-/*========================================================================
- * Directory Structure when equal to XFS_LBSIZE(mp) bytes.
- *========================================================================*/
-
-/*
- * This is the structure of the leaf nodes in the Btree.
- *
- * Struct leaf_entry's are packed from the top. Names grow from the bottom
- * but are not packed. The freemap contains run-length-encoded entries
- * for the free bytes after the leaf_entry's, but only the N largest such,
- * smaller runs are dropped. When the freemap doesn't show enough space
- * for an allocation, we compact the namelist area and try again. If we
- * still don't have enough space, then we have to split the block.
- *
- * Since we have duplicate hash keys, for each key that matches, compare
- * the actual string. The root and intermediate node search always takes
- * the first-in-the-block key match found, so we should only have to work
- * "forw"ard. If none matches, continue with the "forw"ard leaf nodes
- * until the hash key changes or the filename is found.
- *
- * The parent directory and the self-pointer are explicitly represented
- * (ie: there are entries for "." and "..").
- *
- * Note that the count being a __uint16_t limits us to something like a
- * blocksize of 1.3MB in the face of worst case (short) filenames.
- */
-#define XFS_DIR_LEAF_MAPSIZE 3 /* how many freespace slots */
-
-typedef struct xfs_dir_leaf_map { /* RLE map of free bytes */
- __uint16_t base; /* base of free region */
- __uint16_t size; /* run length of free region */
-} xfs_dir_leaf_map_t;
-
-typedef struct xfs_dir_leaf_hdr { /* constant-structure header block */
- xfs_da_blkinfo_t info; /* block type, links, etc. */
- __uint16_t count; /* count of active leaf_entry's */
- __uint16_t namebytes; /* num bytes of name strings stored */
- __uint16_t firstused; /* first used byte in name area */
- __uint8_t holes; /* != 0 if blk needs compaction */
- __uint8_t pad1;
- xfs_dir_leaf_map_t freemap[XFS_DIR_LEAF_MAPSIZE];
-} xfs_dir_leaf_hdr_t;
-
-typedef struct xfs_dir_leaf_entry { /* sorted on key, not name */
- xfs_dahash_t hashval; /* hash value of name */
- __uint16_t nameidx; /* index into buffer of name */
- __uint8_t namelen; /* length of name string */
- __uint8_t pad2;
-} xfs_dir_leaf_entry_t;
-
-typedef struct xfs_dir_leaf_name {
- xfs_dir_ino_t inumber; /* inode number for this key */
- __uint8_t name[1]; /* name string itself */
-} xfs_dir_leaf_name_t;
-
-typedef struct xfs_dir_leafblock {
- xfs_dir_leaf_hdr_t hdr; /* constant-structure header block */
- xfs_dir_leaf_entry_t entries[1]; /* var sized array */
- xfs_dir_leaf_name_t namelist[1]; /* grows from bottom of buf */
-} xfs_dir_leafblock_t;
-
-/*
- * Length of name for which a 512-byte block filesystem
- * can get a double split.
- */
-#define XFS_DIR_LEAF_CAN_DOUBLE_SPLIT_LEN \
- (512 - (uint)sizeof(xfs_dir_leaf_hdr_t) - \
- (uint)sizeof(xfs_dir_leaf_entry_t) * 2 - \
- (uint)sizeof(xfs_dir_leaf_name_t) * 2 - (MAXNAMELEN - 2) + 1 + 1)
-
-typedef int (*xfs_dir_put_t)(struct xfs_dir_put_args *pa);
-
-typedef union {
- xfs_off_t o; /* offset (cookie) */
- /*
- * Watch the order here (endian-ness dependent).
- */
- struct {
-#ifndef XFS_NATIVE_HOST
- xfs_dahash_t h; /* hash value */
- __uint32_t be; /* block and entry */
-#else
- __uint32_t be; /* block and entry */
- xfs_dahash_t h; /* hash value */
-#endif /* XFS_NATIVE_HOST */
- } s;
-} xfs_dircook_t;
-
-#define XFS_PUT_COOKIE(c,mp,bno,entry,hash) \
- ((c).s.be = XFS_DA_MAKE_BNOENTRY(mp, bno, entry), (c).s.h = (hash))
-
-typedef struct xfs_dir_put_args {
- xfs_dircook_t cook; /* cookie of (next) entry */
- xfs_intino_t ino; /* inode number */
- struct xfs_dirent *dbp; /* buffer pointer */
- char *name; /* directory entry name */
- int namelen; /* length of name */
- int done; /* output: set if value was stored */
- xfs_dir_put_t put; /* put function ptr (i/o) */
- struct uio *uio; /* uio control structure */
-} xfs_dir_put_args_t;
-
-#define XFS_DIR_LEAF_ENTSIZE_BYNAME(len) \
- xfs_dir_leaf_entsize_byname(len)
-static inline int xfs_dir_leaf_entsize_byname(int len)
-{
- return (uint)sizeof(xfs_dir_leaf_name_t)-1 + len;
-}
-
-#define XFS_DIR_LEAF_ENTSIZE_BYENTRY(entry) \
- xfs_dir_leaf_entsize_byentry(entry)
-static inline int xfs_dir_leaf_entsize_byentry(xfs_dir_leaf_entry_t *entry)
-{
- return (uint)sizeof(xfs_dir_leaf_name_t)-1 + (entry)->namelen;
-}
-
-#define XFS_DIR_LEAF_NAMESTRUCT(leafp,offset) \
- xfs_dir_leaf_namestruct(leafp,offset)
-static inline xfs_dir_leaf_name_t *
-xfs_dir_leaf_namestruct(xfs_dir_leafblock_t *leafp, int offset)
-{
- return (xfs_dir_leaf_name_t *)&((char *)(leafp))[offset];
-}
-
-/*========================================================================
- * Function prototypes for the kernel.
- *========================================================================*/
-
-/*
- * Internal routines when dirsize < XFS_LITINO(mp).
- */
-int xfs_dir_shortform_create(struct xfs_da_args *args, xfs_ino_t parent);
-int xfs_dir_shortform_addname(struct xfs_da_args *args);
-int xfs_dir_shortform_lookup(struct xfs_da_args *args);
-int xfs_dir_shortform_to_leaf(struct xfs_da_args *args);
-int xfs_dir_shortform_removename(struct xfs_da_args *args);
-int xfs_dir_shortform_getdents(struct xfs_inode *dp, struct uio *uio, int *eofp,
- struct xfs_dirent *dbp, xfs_dir_put_t put);
-int xfs_dir_shortform_replace(struct xfs_da_args *args);
-
-/*
- * Internal routines when dirsize == XFS_LBSIZE(mp).
- */
-int xfs_dir_leaf_to_node(struct xfs_da_args *args);
-int xfs_dir_leaf_to_shortform(struct xfs_da_args *args);
-
-/*
- * Routines used for growing the Btree.
- */
-int xfs_dir_leaf_split(struct xfs_da_state *state,
- struct xfs_da_state_blk *oldblk,
- struct xfs_da_state_blk *newblk);
-int xfs_dir_leaf_add(struct xfs_dabuf *leaf_buffer,
- struct xfs_da_args *args, int insertion_index);
-int xfs_dir_leaf_addname(struct xfs_da_args *args);
-int xfs_dir_leaf_lookup_int(struct xfs_dabuf *leaf_buffer,
- struct xfs_da_args *args,
- int *index_found_at);
-int xfs_dir_leaf_remove(struct xfs_trans *trans,
- struct xfs_dabuf *leaf_buffer,
- int index_to_remove);
-int xfs_dir_leaf_getdents_int(struct xfs_dabuf *bp, struct xfs_inode *dp,
- xfs_dablk_t bno, struct uio *uio,
- int *eobp, struct xfs_dirent *dbp,
- xfs_dir_put_t put, xfs_daddr_t nextda);
-
-/*
- * Routines used for shrinking the Btree.
- */
-int xfs_dir_leaf_toosmall(struct xfs_da_state *state, int *retval);
-void xfs_dir_leaf_unbalance(struct xfs_da_state *state,
- struct xfs_da_state_blk *drop_blk,
- struct xfs_da_state_blk *save_blk);
-
-/*
- * Utility routines.
- */
-uint xfs_dir_leaf_lasthash(struct xfs_dabuf *bp, int *count);
-int xfs_dir_leaf_order(struct xfs_dabuf *leaf1_bp,
- struct xfs_dabuf *leaf2_bp);
-int xfs_dir_put_dirent64_direct(xfs_dir_put_args_t *pa);
-int xfs_dir_put_dirent64_uio(xfs_dir_put_args_t *pa);
-int xfs_dir_ino_validate(struct xfs_mount *mp, xfs_ino_t ino);
-
-/*
- * Global data.
- */
-extern xfs_dahash_t xfs_dir_hash_dot, xfs_dir_hash_dotdot;
-
-#endif /* __XFS_DIR_LEAF_H__ */
diff --git a/sys/gnu/fs/xfs/xfs_dir_sf.h b/sys/gnu/fs/xfs/xfs_dir_sf.h
deleted file mode 100644
index 5b20b4d..0000000
--- a/sys/gnu/fs/xfs/xfs_dir_sf.h
+++ /dev/null
@@ -1,155 +0,0 @@
-/*
- * Copyright (c) 2000,2005 Silicon Graphics, Inc.
- * All Rights Reserved.
- *
- * 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.
- *
- * This program is distributed in the hope that it would 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 the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- */
-#ifndef __XFS_DIR_SF_H__
-#define __XFS_DIR_SF_H__
-
-/*
- * Directory layout when stored internal to an inode.
- *
- * Small directories are packed as tightly as possible so as to
- * fit into the literal area of the inode.
- */
-
-typedef struct { __uint8_t i[sizeof(xfs_ino_t)]; } xfs_dir_ino_t;
-
-/*
- * The parent directory has a dedicated field, and the self-pointer must
- * be calculated on the fly.
- *
- * Entries are packed toward the top as tight as possible. The header
- * and the elements much be memcpy'd out into a work area to get correct
- * alignment for the inode number fields.
- */
-typedef struct xfs_dir_sf_hdr { /* constant-structure header block */
- xfs_dir_ino_t parent; /* parent dir inode number */
- __uint8_t count; /* count of active entries */
-} xfs_dir_sf_hdr_t;
-
-typedef struct xfs_dir_sf_entry {
- xfs_dir_ino_t inumber; /* referenced inode number */
- __uint8_t namelen; /* actual length of name (no NULL) */
- __uint8_t name[1]; /* name */
-} xfs_dir_sf_entry_t;
-
-typedef struct xfs_dir_shortform {
- xfs_dir_sf_hdr_t hdr;
- xfs_dir_sf_entry_t list[1]; /* variable sized array */
-} xfs_dir_shortform_t;
-
-/*
- * We generate this then sort it, so that readdirs are returned in
- * hash-order. Else seekdir won't work.
- */
-typedef struct xfs_dir_sf_sort {
- __uint8_t entno; /* .=0, ..=1, else entry# + 2 */
- __uint8_t seqno; /* sequence # with same hash value */
- __uint8_t namelen; /* length of name value (no null) */
- xfs_dahash_t hash; /* this entry's hash value */
- xfs_intino_t ino; /* this entry's inode number */
- char *name; /* name value, pointer into buffer */
-} xfs_dir_sf_sort_t;
-
-#define XFS_DIR_SF_GET_DIRINO(from,to) xfs_dir_sf_get_dirino(from, to)
-static inline void xfs_dir_sf_get_dirino(xfs_dir_ino_t *from, xfs_ino_t *to)
-{
- *(to) = XFS_GET_DIR_INO8(*from);
-}
-
-#define XFS_DIR_SF_PUT_DIRINO(from,to) xfs_dir_sf_put_dirino(from, to)
-static inline void xfs_dir_sf_put_dirino(xfs_ino_t *from, xfs_dir_ino_t *to)
-{
- XFS_PUT_DIR_INO8(*(from), *(to));
-}
-
-#define XFS_DIR_SF_ENTSIZE_BYNAME(len) xfs_dir_sf_entsize_byname(len)
-static inline int xfs_dir_sf_entsize_byname(int len)
-{
- return (uint)sizeof(xfs_dir_sf_entry_t)-1 + (len);
-}
-
-#define XFS_DIR_SF_ENTSIZE_BYENTRY(sfep) xfs_dir_sf_entsize_byentry(sfep)
-static inline int xfs_dir_sf_entsize_byentry(xfs_dir_sf_entry_t *sfep)
-{
- return (uint)sizeof(xfs_dir_sf_entry_t)-1 + (sfep)->namelen;
-}
-
-#define XFS_DIR_SF_NEXTENTRY(sfep) xfs_dir_sf_nextentry(sfep)
-static inline xfs_dir_sf_entry_t *xfs_dir_sf_nextentry(xfs_dir_sf_entry_t *sfep)
-{
- return (xfs_dir_sf_entry_t *) \
- ((char *)(sfep) + XFS_DIR_SF_ENTSIZE_BYENTRY(sfep));
-}
-
-#define XFS_DIR_SF_ALLFIT(count,totallen) \
- xfs_dir_sf_allfit(count,totallen)
-static inline int xfs_dir_sf_allfit(int count, int totallen)
-{
- return ((uint)sizeof(xfs_dir_sf_hdr_t) + \
- ((uint)sizeof(xfs_dir_sf_entry_t)-1)*(count) + (totallen));
-}
-
-#if defined(XFS_DIR_TRACE)
-
-/*
- * Kernel tracing support for directories.
- */
-struct uio;
-struct xfs_inode;
-struct xfs_da_intnode;
-struct xfs_dinode;
-struct xfs_dir_leafblock;
-struct xfs_dir_leaf_entry;
-
-#define XFS_DIR_TRACE_SIZE 4096 /* size of global trace buffer */
-extern ktrace_t *xfs_dir_trace_buf;
-
-/*
- * Trace record types.
- */
-#define XFS_DIR_KTRACE_G_DU 1 /* dp, uio */
-#define XFS_DIR_KTRACE_G_DUB 2 /* dp, uio, bno */
-#define XFS_DIR_KTRACE_G_DUN 3 /* dp, uio, node */
-#define XFS_DIR_KTRACE_G_DUL 4 /* dp, uio, leaf */
-#define XFS_DIR_KTRACE_G_DUE 5 /* dp, uio, leaf entry */
-#define XFS_DIR_KTRACE_G_DUC 6 /* dp, uio, cookie */
-
-void xfs_dir_trace_g_du(char *where, struct xfs_inode *dp, struct uio *uio);
-void xfs_dir_trace_g_dub(char *where, struct xfs_inode *dp, struct uio *uio,
- xfs_dablk_t bno);
-void xfs_dir_trace_g_dun(char *where, struct xfs_inode *dp, struct uio *uio,
- struct xfs_da_intnode *node);
-void xfs_dir_trace_g_dul(char *where, struct xfs_inode *dp, struct uio *uio,
- struct xfs_dir_leafblock *leaf);
-void xfs_dir_trace_g_due(char *where, struct xfs_inode *dp, struct uio *uio,
- struct xfs_dir_leaf_entry *entry);
-void xfs_dir_trace_g_duc(char *where, struct xfs_inode *dp, struct uio *uio,
- xfs_off_t cookie);
-void xfs_dir_trace_enter(int type, char *where,
- void *a0, void *a1, void *a2, void *a3,
- void *a4, void *a5, void *a6, void *a7,
- void *a8, void *a9, void *a10, void *a11);
-#else
-#define xfs_dir_trace_g_du(w,d,u)
-#define xfs_dir_trace_g_dub(w,d,u,b)
-#define xfs_dir_trace_g_dun(w,d,u,n)
-#define xfs_dir_trace_g_dul(w,d,u,l)
-#define xfs_dir_trace_g_due(w,d,u,e)
-#define xfs_dir_trace_g_duc(w,d,u,c)
-#endif /* DEBUG */
-
-#endif /* __XFS_DIR_SF_H__ */
diff --git a/sys/gnu/fs/xfs/xfs_dmapi.h b/sys/gnu/fs/xfs/xfs_dmapi.h
deleted file mode 100644
index 8ddd9a5..0000000
--- a/sys/gnu/fs/xfs/xfs_dmapi.h
+++ /dev/null
@@ -1,198 +0,0 @@
-/*
- * Copyright (c) 2000-2005 Silicon Graphics, Inc.
- * All Rights Reserved.
- *
- * 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.
- *
- * This program is distributed in the hope that it would 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 the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- */
-#ifndef __XFS_DMAPI_H__
-#define __XFS_DMAPI_H__
-
-//#include <linux/version.h>
-/* Values used to define the on-disk version of dm_attrname_t. All
- * on-disk attribute names start with the 8-byte string "SGI_DMI_".
- *
- * In the on-disk inode, DMAPI attribute names consist of the user-provided
- * name with the DMATTR_PREFIXSTRING pre-pended. This string must NEVER be
- * changed.
- */
-
-#define DMATTR_PREFIXLEN 8
-#define DMATTR_PREFIXSTRING "SGI_DMI_"
-
-typedef enum {
- DM_EVENT_INVALID = -1,
- DM_EVENT_CANCEL = 0, /* not supported */
- DM_EVENT_MOUNT = 1,
- DM_EVENT_PREUNMOUNT = 2,
- DM_EVENT_UNMOUNT = 3,
- DM_EVENT_DEBUT = 4, /* not supported */
- DM_EVENT_CREATE = 5,
- DM_EVENT_CLOSE = 6, /* not supported */
- DM_EVENT_POSTCREATE = 7,
- DM_EVENT_REMOVE = 8,
- DM_EVENT_POSTREMOVE = 9,
- DM_EVENT_RENAME = 10,
- DM_EVENT_POSTRENAME = 11,
- DM_EVENT_LINK = 12,
- DM_EVENT_POSTLINK = 13,
- DM_EVENT_SYMLINK = 14,
- DM_EVENT_POSTSYMLINK = 15,
- DM_EVENT_READ = 16,
- DM_EVENT_WRITE = 17,
- DM_EVENT_TRUNCATE = 18,
- DM_EVENT_ATTRIBUTE = 19,
- DM_EVENT_DESTROY = 20,
- DM_EVENT_NOSPACE = 21,
- DM_EVENT_USER = 22,
- DM_EVENT_MAX = 23
-} dm_eventtype_t;
-#define HAVE_DM_EVENTTYPE_T
-
-typedef enum {
- DM_RIGHT_NULL,
- DM_RIGHT_SHARED,
- DM_RIGHT_EXCL
-} dm_right_t;
-#define HAVE_DM_RIGHT_T
-
-/* Defines for determining if an event message should be sent. */
-#define DM_EVENT_ENABLED(vfsp, ip, event) ( \
- unlikely ((vfsp)->vfs_flag & VFS_DMI) && \
- ( ((ip)->i_d.di_dmevmask & (1 << event)) || \
- ((ip)->i_mount->m_dmevmask & (1 << event)) ) \
- )
-
-#define DM_EVENT_ENABLED_IO(vfsp, io, event) ( \
- unlikely ((vfsp)->vfs_flag & VFS_DMI) && \
- ( ((io)->io_dmevmask & (1 << event)) || \
- ((io)->io_mount->m_dmevmask & (1 << event)) ) \
- )
-
-#define DM_XFS_VALID_FS_EVENTS ( \
- (1 << DM_EVENT_PREUNMOUNT) | \
- (1 << DM_EVENT_UNMOUNT) | \
- (1 << DM_EVENT_NOSPACE) | \
- (1 << DM_EVENT_DEBUT) | \
- (1 << DM_EVENT_CREATE) | \
- (1 << DM_EVENT_POSTCREATE) | \
- (1 << DM_EVENT_REMOVE) | \
- (1 << DM_EVENT_POSTREMOVE) | \
- (1 << DM_EVENT_RENAME) | \
- (1 << DM_EVENT_POSTRENAME) | \
- (1 << DM_EVENT_LINK) | \
- (1 << DM_EVENT_POSTLINK) | \
- (1 << DM_EVENT_SYMLINK) | \
- (1 << DM_EVENT_POSTSYMLINK) | \
- (1 << DM_EVENT_ATTRIBUTE) | \
- (1 << DM_EVENT_DESTROY) )
-
-/* Events valid in dm_set_eventlist() when called with a file handle for
- a regular file or a symlink. These events are persistent.
-*/
-
-#define DM_XFS_VALID_FILE_EVENTS ( \
- (1 << DM_EVENT_ATTRIBUTE) | \
- (1 << DM_EVENT_DESTROY) )
-
-/* Events valid in dm_set_eventlist() when called with a file handle for
- a directory. These events are persistent.
-*/
-
-#define DM_XFS_VALID_DIRECTORY_EVENTS ( \
- (1 << DM_EVENT_CREATE) | \
- (1 << DM_EVENT_POSTCREATE) | \
- (1 << DM_EVENT_REMOVE) | \
- (1 << DM_EVENT_POSTREMOVE) | \
- (1 << DM_EVENT_RENAME) | \
- (1 << DM_EVENT_POSTRENAME) | \
- (1 << DM_EVENT_LINK) | \
- (1 << DM_EVENT_POSTLINK) | \
- (1 << DM_EVENT_SYMLINK) | \
- (1 << DM_EVENT_POSTSYMLINK) | \
- (1 << DM_EVENT_ATTRIBUTE) | \
- (1 << DM_EVENT_DESTROY) )
-
-/* Events supported by the XFS filesystem. */
-#define DM_XFS_SUPPORTED_EVENTS ( \
- (1 << DM_EVENT_MOUNT) | \
- (1 << DM_EVENT_PREUNMOUNT) | \
- (1 << DM_EVENT_UNMOUNT) | \
- (1 << DM_EVENT_NOSPACE) | \
- (1 << DM_EVENT_CREATE) | \
- (1 << DM_EVENT_POSTCREATE) | \
- (1 << DM_EVENT_REMOVE) | \
- (1 << DM_EVENT_POSTREMOVE) | \
- (1 << DM_EVENT_RENAME) | \
- (1 << DM_EVENT_POSTRENAME) | \
- (1 << DM_EVENT_LINK) | \
- (1 << DM_EVENT_POSTLINK) | \
- (1 << DM_EVENT_SYMLINK) | \
- (1 << DM_EVENT_POSTSYMLINK) | \
- (1 << DM_EVENT_READ) | \
- (1 << DM_EVENT_WRITE) | \
- (1 << DM_EVENT_TRUNCATE) | \
- (1 << DM_EVENT_ATTRIBUTE) | \
- (1 << DM_EVENT_DESTROY) )
-
-
-/*
- * Definitions used for the flags field on dm_send_*_event().
- */
-
-#define DM_FLAGS_NDELAY 0x001 /* return EAGAIN after dm_pending() */
-#define DM_FLAGS_UNWANTED 0x002 /* event not in fsys dm_eventset_t */
-#define DM_FLAGS_IMUX 0x004 /* thread holds i_mutex */
-#define DM_FLAGS_IALLOCSEM_RD 0x010 /* thread holds i_alloc_sem rd */
-#define DM_FLAGS_IALLOCSEM_WR 0x020 /* thread holds i_alloc_sem wr */
-
-/*
- * Based on IO_ISDIRECT, decide which i_ flag is set.
- */
-#if 0
-#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,0)
-#define DM_SEM_FLAG_RD(ioflags) (((ioflags) & IO_ISDIRECT) ? \
- DM_FLAGS_IMUX : 0)
-#define DM_SEM_FLAG_WR (DM_FLAGS_IALLOCSEM_WR | DM_FLAGS_IMUX)
-#endif
-
-#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0)) && \
- (LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,22))
-#define DM_SEM_FLAG_RD(ioflags) (((ioflags) & IO_ISDIRECT) ? \
- DM_FLAGS_IALLOCSEM_RD : DM_FLAGS_IMUX)
-#define DM_SEM_FLAG_WR (DM_FLAGS_IALLOCSEM_WR | DM_FLAGS_IMUX)
-#endif
-
-#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,4,21)
-#define DM_SEM_FLAG_RD(ioflags) (((ioflags) & IO_ISDIRECT) ? \
- 0 : DM_FLAGS_IMUX)
-#define DM_SEM_FLAG_WR (DM_FLAGS_IMUX)
-#endif
-
-#endif
-
-#define DM_SEM_FLAG_WR 0 /* RMC */
-
-/*
- * Macros to turn caller specified delay/block flags into
- * dm_send_xxxx_event flag DM_FLAGS_NDELAY.
- */
-
-#define FILP_DELAY_FLAG(filp) ((filp->f_flags&(O_NDELAY|O_NONBLOCK)) ? \
- DM_FLAGS_NDELAY : 0)
-#define AT_DELAY_FLAG(f) ((f&ATTR_NONBLOCK) ? DM_FLAGS_NDELAY : 0)
-
-
-extern struct bhv_vfsops xfs_dmops;
-
-#endif /* __XFS_DMAPI_H__ */
diff --git a/sys/gnu/fs/xfs/xfs_dmops.c b/sys/gnu/fs/xfs/xfs_dmops.c
deleted file mode 100644
index 629795b..0000000
--- a/sys/gnu/fs/xfs/xfs_dmops.c
+++ /dev/null
@@ -1,37 +0,0 @@
-/*
- * Copyright (c) 2000-2003,2005 Silicon Graphics, Inc.
- * All Rights Reserved.
- *
- * 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.
- *
- * This program is distributed in the hope that it would 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 the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- */
-#include "xfs.h"
-#include "xfs_fs.h"
-#include "xfs_types.h"
-#include "xfs_log.h"
-#include "xfs_inum.h"
-#include "xfs_trans.h"
-#include "xfs_sb.h"
-#include "xfs_ag.h"
-#include "xfs_dir.h"
-#include "xfs_dir2.h"
-#include "xfs_dmapi.h"
-#include "xfs_mount.h"
-
-xfs_dmops_t xfs_dmcore_stub = {
- .xfs_send_data = (xfs_send_data_t)fs_nosys,
- .xfs_send_mmap = (xfs_send_mmap_t)fs_noerr,
- .xfs_send_destroy = (xfs_send_destroy_t)fs_nosys,
- .xfs_send_namesp = (xfs_send_namesp_t)fs_nosys,
- .xfs_send_unmount = (xfs_send_unmount_t)fs_noval,
-};
diff --git a/sys/gnu/fs/xfs/xfs_error.c b/sys/gnu/fs/xfs/xfs_error.c
deleted file mode 100644
index 409d8d8..0000000
--- a/sys/gnu/fs/xfs/xfs_error.c
+++ /dev/null
@@ -1,311 +0,0 @@
-/*
- * Copyright (c) 2000-2001,2005 Silicon Graphics, Inc.
- * All Rights Reserved.
- *
- * 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.
- *
- * This program is distributed in the hope that it would 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 the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- */
-#include "xfs.h"
-#include "xfs_fs.h"
-#include "xfs_types.h"
-#include "xfs_log.h"
-#include "xfs_inum.h"
-#include "xfs_trans.h"
-#include "xfs_sb.h"
-#include "xfs_dir.h"
-#include "xfs_dir2.h"
-#include "xfs_dmapi.h"
-#include "xfs_mount.h"
-#include "xfs_bmap_btree.h"
-#include "xfs_dir_sf.h"
-#include "xfs_dir2_sf.h"
-#include "xfs_attr_sf.h"
-#include "xfs_dinode.h"
-#include "xfs_inode.h"
-#include "xfs_utils.h"
-#include "xfs_error.h"
-
-#ifdef DEBUG
-
-int xfs_etrap[XFS_ERROR_NTRAP] = {
- 0,
-};
-
-int
-xfs_error_trap(int e)
-{
- int i;
-
- if (!e)
- return 0;
- for (i = 0; i < XFS_ERROR_NTRAP; i++) {
- if (xfs_etrap[i] == 0)
- break;
- if (e != xfs_etrap[i])
- continue;
- cmn_err(CE_NOTE, "xfs_error_trap: error %d", e);
- panic("xfs_error_trap");
- break;
- }
- return e;
-}
-#endif
-
-#if (defined(DEBUG) || defined(INDUCE_IO_ERROR))
-
-int xfs_etest[XFS_NUM_INJECT_ERROR];
-int64_t xfs_etest_fsid[XFS_NUM_INJECT_ERROR];
-char * xfs_etest_fsname[XFS_NUM_INJECT_ERROR];
-
-void
-xfs_error_test_init(void)
-{
- memset(xfs_etest, 0, sizeof(xfs_etest));
- memset(xfs_etest_fsid, 0, sizeof(xfs_etest_fsid));
- memset(xfs_etest_fsname, 0, sizeof(xfs_etest_fsname));
-}
-
-int
-xfs_error_test(int error_tag, int *fsidp, char *expression,
- int line, char *file, unsigned long randfactor)
-{
- int i;
- int64_t fsid;
-
- if (random() % randfactor)
- return 0;
-
- memcpy(&fsid, fsidp, sizeof(xfs_fsid_t));
-
- for (i = 0; i < XFS_NUM_INJECT_ERROR; i++) {
- if (xfs_etest[i] == error_tag && xfs_etest_fsid[i] == fsid) {
- cmn_err(CE_WARN,
- "Injecting error (%s) at file %s, line %d, on filesystem \"%s\"",
- expression, file, line, xfs_etest_fsname[i]);
- return 1;
- }
- }
-
- return 0;
-}
-
-int
-xfs_errortag_add(int error_tag, xfs_mount_t *mp)
-{
- int i;
- int len;
- int64_t fsid;
-
- memcpy(&fsid, mp->m_fixedfsid, sizeof(xfs_fsid_t));
-
- for (i = 0; i < XFS_NUM_INJECT_ERROR; i++) {
- if (xfs_etest_fsid[i] == fsid && xfs_etest[i] == error_tag) {
- cmn_err(CE_WARN, "XFS error tag #%d on", error_tag);
- return 0;
- }
- }
-
- for (i = 0; i < XFS_NUM_INJECT_ERROR; i++) {
- if (xfs_etest[i] == 0) {
- cmn_err(CE_WARN, "Turned on XFS error tag #%d",
- error_tag);
- xfs_etest[i] = error_tag;
- xfs_etest_fsid[i] = fsid;
- len = strlen(mp->m_fsname);
- xfs_etest_fsname[i] = kmem_alloc(len + 1, KM_SLEEP);
- strcpy(xfs_etest_fsname[i], mp->m_fsname);
- return 0;
- }
- }
-
- cmn_err(CE_WARN, "error tag overflow, too many turned on");
-
- return 1;
-}
-
-int
-xfs_errortag_clear(int error_tag, xfs_mount_t *mp)
-{
- int i;
- int64_t fsid;
-
- memcpy(&fsid, mp->m_fixedfsid, sizeof(xfs_fsid_t));
-
- for (i = 0; i < XFS_NUM_INJECT_ERROR; i++) {
- if (xfs_etest_fsid[i] == fsid && xfs_etest[i] == error_tag) {
- xfs_etest[i] = 0;
- xfs_etest_fsid[i] = 0LL;
- kmem_free(xfs_etest_fsname[i],
- strlen(xfs_etest_fsname[i]) + 1);
- xfs_etest_fsname[i] = NULL;
- cmn_err(CE_WARN, "Cleared XFS error tag #%d",
- error_tag);
- return 0;
- }
- }
-
- cmn_err(CE_WARN, "XFS error tag %d not on", error_tag);
-
- return 1;
-}
-
-int
-xfs_errortag_clearall_umount(int64_t fsid, char *fsname, int loud)
-{
- int i;
- int cleared = 0;
-
- for (i = 0; i < XFS_NUM_INJECT_ERROR; i++) {
- if ((fsid == 0LL || xfs_etest_fsid[i] == fsid) &&
- xfs_etest[i] != 0) {
- cleared = 1;
- cmn_err(CE_WARN, "Clearing XFS error tag #%d",
- xfs_etest[i]);
- xfs_etest[i] = 0;
- xfs_etest_fsid[i] = 0LL;
- kmem_free(xfs_etest_fsname[i],
- strlen(xfs_etest_fsname[i]) + 1);
- xfs_etest_fsname[i] = NULL;
- }
- }
-
- if (loud || cleared)
- cmn_err(CE_WARN,
- "Cleared all XFS error tags for filesystem \"%s\"",
- fsname);
-
- return 0;
-}
-
-int
-xfs_errortag_clearall(xfs_mount_t *mp)
-{
- int64_t fsid;
-
- memcpy(&fsid, mp->m_fixedfsid, sizeof(xfs_fsid_t));
-
- return xfs_errortag_clearall_umount(fsid, mp->m_fsname, 1);
-}
-#endif /* DEBUG || INDUCE_IO_ERROR */
-
-static void
-xfs_fs_vcmn_err(int level, xfs_mount_t *mp, char *fmt, va_list ap)
-{
- if (mp != NULL) {
- char *newfmt;
- int len = 16 + mp->m_fsname_len + strlen(fmt);
-
- newfmt = kmem_alloc(len, KM_SLEEP);
- sprintf(newfmt, "Filesystem \"%s\": %s", mp->m_fsname, fmt);
- icmn_err(level, newfmt, ap);
- kmem_free(newfmt, len);
- } else {
- icmn_err(level, fmt, ap);
- }
-}
-
-void
-xfs_fs_cmn_err(int level, xfs_mount_t *mp, char *fmt, ...)
-{
- va_list ap;
-
- va_start(ap, fmt);
- xfs_fs_vcmn_err(level, mp, fmt, ap);
- va_end(ap);
-}
-
-void
-xfs_cmn_err(int panic_tag, int level, xfs_mount_t *mp, char *fmt, ...)
-{
- va_list ap;
-
-#ifdef DEBUG
- xfs_panic_mask |= XFS_PTAG_SHUTDOWN_CORRUPT;
-#endif
-
- if (xfs_panic_mask && (xfs_panic_mask & panic_tag)
- && (level & CE_ALERT)) {
- level &= ~CE_ALERT;
- level |= CE_PANIC;
- cmn_err(CE_ALERT, "XFS: Transforming an alert into a BUG.");
- }
- va_start(ap, fmt);
- xfs_fs_vcmn_err(level, mp, fmt, ap);
- va_end(ap);
-}
-
-void
-xfs_error_report(
- char *tag,
- int level,
- xfs_mount_t *mp,
- char *fname,
- int linenum,
- inst_t *ra)
-{
- if (level <= xfs_error_level) {
- xfs_cmn_err(XFS_PTAG_ERROR_REPORT,
- CE_ALERT, mp,
- "XFS internal error %s at line %d of file %s. Caller 0x%p\n",
- tag, linenum, fname, ra);
-
- xfs_stack_trace();
- }
-}
-
-STATIC void
-xfs_hex_dump(void *p, int length)
-{
- __uint8_t *uip = (__uint8_t*)p;
- int i;
- char sbuf[128], *s;
-
- s = sbuf;
- *s = '\0';
- for (i=0; i<length; i++, uip++) {
- if ((i % 16) == 0) {
- if (*s != '\0')
- cmn_err(CE_ALERT, "%s\n", sbuf);
- s = sbuf;
- sprintf(s, "0x%x: ", i);
- while( *s != '\0')
- s++;
- }
- sprintf(s, "%02x ", *uip);
-
- /*
- * the kernel sprintf is a void; user sprintf returns
- * the sprintf'ed string's length. Find the new end-
- * of-string
- */
- while( *s != '\0')
- s++;
- }
- cmn_err(CE_ALERT, "%s\n", sbuf);
-}
-
-void
-xfs_corruption_error(
- char *tag,
- int level,
- xfs_mount_t *mp,
- void *p,
- char *fname,
- int linenum,
- inst_t *ra)
-{
- if (level <= xfs_error_level)
- xfs_hex_dump(p, 16);
- xfs_error_report(tag, level, mp, fname, linenum, ra);
-}
-
diff --git a/sys/gnu/fs/xfs/xfs_error.h b/sys/gnu/fs/xfs/xfs_error.h
deleted file mode 100644
index 9357ba4..0000000
--- a/sys/gnu/fs/xfs/xfs_error.h
+++ /dev/null
@@ -1,193 +0,0 @@
-/*
- * Copyright (c) 2000-2002,2005 Silicon Graphics, Inc.
- * All Rights Reserved.
- *
- * 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.
- *
- * This program is distributed in the hope that it would 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 the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- */
-#ifndef __XFS_ERROR_H__
-#define __XFS_ERROR_H__
-
-#define XFS_ERECOVER 1 /* Failure to recover log */
-#define XFS_ELOGSTAT 2 /* Failure to stat log in user space */
-#define XFS_ENOLOGSPACE 3 /* Reservation too large */
-#define XFS_ENOTSUP 4 /* Operation not supported */
-#define XFS_ENOLSN 5 /* Can't find the lsn you asked for */
-#define XFS_ENOTFOUND 6
-#define XFS_ENOTXFS 7 /* Not XFS filesystem */
-
-#ifdef DEBUG
-#define XFS_ERROR_NTRAP 10
-extern int xfs_etrap[XFS_ERROR_NTRAP];
-extern int xfs_error_trap(int);
-#define XFS_ERROR(e) xfs_error_trap(e)
-#else
-#define XFS_ERROR(e) (e)
-#endif
-
-struct xfs_mount;
-
-extern void xfs_error_report(char *tag, int level, struct xfs_mount *mp,
- char *fname, int linenum, inst_t *ra);
-extern void xfs_corruption_error(char *tag, int level, struct xfs_mount *mp,
- void *p, char *fname, int linenum, inst_t *ra);
-
-#define XFS_ERROR_REPORT(e, lvl, mp) \
- xfs_error_report(e, lvl, mp, __FILE__, __LINE__, __return_address)
-#define XFS_CORRUPTION_ERROR(e, lvl, mp, mem) \
- xfs_corruption_error(e, lvl, mp, mem, \
- __FILE__, __LINE__, __return_address)
-
-#define XFS_ERRLEVEL_OFF 0
-#define XFS_ERRLEVEL_LOW 1
-#define XFS_ERRLEVEL_HIGH 5
-
-/*
- * Macros to set EFSCORRUPTED & return/branch.
- */
-#define XFS_WANT_CORRUPTED_GOTO(x,l) \
- { \
- int fs_is_ok = (x); \
- ASSERT(fs_is_ok); \
- if (unlikely(!fs_is_ok)) { \
- XFS_ERROR_REPORT("XFS_WANT_CORRUPTED_GOTO", \
- XFS_ERRLEVEL_LOW, NULL); \
- error = XFS_ERROR(EFSCORRUPTED); \
- goto l; \
- } \
- }
-
-#define XFS_WANT_CORRUPTED_RETURN(x) \
- { \
- int fs_is_ok = (x); \
- ASSERT(fs_is_ok); \
- if (unlikely(!fs_is_ok)) { \
- XFS_ERROR_REPORT("XFS_WANT_CORRUPTED_RETURN", \
- XFS_ERRLEVEL_LOW, NULL); \
- return XFS_ERROR(EFSCORRUPTED); \
- } \
- }
-
-/*
- * error injection tags - the labels can be anything you want
- * but each tag should have its own unique number
- */
-
-#define XFS_ERRTAG_NOERROR 0
-#define XFS_ERRTAG_IFLUSH_1 1
-#define XFS_ERRTAG_IFLUSH_2 2
-#define XFS_ERRTAG_IFLUSH_3 3
-#define XFS_ERRTAG_IFLUSH_4 4
-#define XFS_ERRTAG_IFLUSH_5 5
-#define XFS_ERRTAG_IFLUSH_6 6
-#define XFS_ERRTAG_DA_READ_BUF 7
-#define XFS_ERRTAG_BTREE_CHECK_LBLOCK 8
-#define XFS_ERRTAG_BTREE_CHECK_SBLOCK 9
-#define XFS_ERRTAG_ALLOC_READ_AGF 10
-#define XFS_ERRTAG_IALLOC_READ_AGI 11
-#define XFS_ERRTAG_ITOBP_INOTOBP 12
-#define XFS_ERRTAG_IUNLINK 13
-#define XFS_ERRTAG_IUNLINK_REMOVE 14
-#define XFS_ERRTAG_DIR_INO_VALIDATE 15
-#define XFS_ERRTAG_BULKSTAT_READ_CHUNK 16
-#define XFS_ERRTAG_IODONE_IOERR 17
-#define XFS_ERRTAG_STRATREAD_IOERR 18
-#define XFS_ERRTAG_STRATCMPL_IOERR 19
-#define XFS_ERRTAG_DIOWRITE_IOERR 20
-#define XFS_ERRTAG_BMAPIFORMAT 21
-#define XFS_ERRTAG_MAX 22
-
-/*
- * Random factors for above tags, 1 means always, 2 means 1/2 time, etc.
- */
-#define XFS_RANDOM_DEFAULT 100
-#define XFS_RANDOM_IFLUSH_1 XFS_RANDOM_DEFAULT
-#define XFS_RANDOM_IFLUSH_2 XFS_RANDOM_DEFAULT
-#define XFS_RANDOM_IFLUSH_3 XFS_RANDOM_DEFAULT
-#define XFS_RANDOM_IFLUSH_4 XFS_RANDOM_DEFAULT
-#define XFS_RANDOM_IFLUSH_5 XFS_RANDOM_DEFAULT
-#define XFS_RANDOM_IFLUSH_6 XFS_RANDOM_DEFAULT
-#define XFS_RANDOM_DA_READ_BUF XFS_RANDOM_DEFAULT
-#define XFS_RANDOM_BTREE_CHECK_LBLOCK (XFS_RANDOM_DEFAULT/4)
-#define XFS_RANDOM_BTREE_CHECK_SBLOCK XFS_RANDOM_DEFAULT
-#define XFS_RANDOM_ALLOC_READ_AGF XFS_RANDOM_DEFAULT
-#define XFS_RANDOM_IALLOC_READ_AGI XFS_RANDOM_DEFAULT
-#define XFS_RANDOM_ITOBP_INOTOBP XFS_RANDOM_DEFAULT
-#define XFS_RANDOM_IUNLINK XFS_RANDOM_DEFAULT
-#define XFS_RANDOM_IUNLINK_REMOVE XFS_RANDOM_DEFAULT
-#define XFS_RANDOM_DIR_INO_VALIDATE XFS_RANDOM_DEFAULT
-#define XFS_RANDOM_BULKSTAT_READ_CHUNK XFS_RANDOM_DEFAULT
-#define XFS_RANDOM_IODONE_IOERR (XFS_RANDOM_DEFAULT/10)
-#define XFS_RANDOM_STRATREAD_IOERR (XFS_RANDOM_DEFAULT/10)
-#define XFS_RANDOM_STRATCMPL_IOERR (XFS_RANDOM_DEFAULT/10)
-#define XFS_RANDOM_DIOWRITE_IOERR (XFS_RANDOM_DEFAULT/10)
-#define XFS_RANDOM_BMAPIFORMAT XFS_RANDOM_DEFAULT
-
-#if (defined(DEBUG) || defined(INDUCE_IO_ERROR))
-extern int xfs_error_test(int, int *, char *, int, char *, unsigned long);
-extern void xfs_error_test_init(void);
-
-#define XFS_NUM_INJECT_ERROR 10
-
-#ifdef __ANSI_CPP__
-#define XFS_TEST_ERROR(expr, mp, tag, rf) \
- ((expr) || \
- xfs_error_test((tag), (mp)->m_fixedfsid, #expr, __LINE__, __FILE__, \
- (rf)))
-#else
-#define XFS_TEST_ERROR(expr, mp, tag, rf) \
- ((expr) || \
- xfs_error_test((tag), (mp)->m_fixedfsid, "expr", __LINE__, __FILE__, \
- (rf)))
-#endif /* __ANSI_CPP__ */
-
-extern int xfs_errortag_add(int error_tag, xfs_mount_t *mp);
-extern int xfs_errortag_clear(int error_tag, xfs_mount_t *mp);
-extern int xfs_errortag_clearall(xfs_mount_t *mp);
-extern int xfs_errortag_clearall_umount(int64_t fsid, char *fsname, int loud);
-#else
-#define XFS_TEST_ERROR(expr, mp, tag, rf) (expr)
-#define xfs_errortag_add(tag, mp) (ENOSYS)
-#define xfs_errortag_clearall(mp) (ENOSYS)
-#endif /* (DEBUG || INDUCE_IO_ERROR) */
-
-/*
- * XFS panic tags -- allow a call to xfs_cmn_err() be turned into
- * a panic by setting xfs_panic_mask in a
- * sysctl. update xfs_max[XFS_PARAM] if
- * more are added.
- */
-#define XFS_NO_PTAG 0
-#define XFS_PTAG_IFLUSH 0x00000001
-#define XFS_PTAG_LOGRES 0x00000002
-#define XFS_PTAG_AILDELETE 0x00000004
-#define XFS_PTAG_ERROR_REPORT 0x00000008
-#define XFS_PTAG_SHUTDOWN_CORRUPT 0x00000010
-#define XFS_PTAG_SHUTDOWN_IOERROR 0x00000020
-#define XFS_PTAG_SHUTDOWN_LOGERROR 0x00000040
-
-struct xfs_mount;
-/* PRINTFLIKE4 */
-extern void xfs_cmn_err(int panic_tag, int level, struct xfs_mount *mp,
- char *fmt, ...);
-/* PRINTFLIKE3 */
-extern void xfs_fs_cmn_err(int level, struct xfs_mount *mp, char *fmt, ...);
-
-#define xfs_fs_repair_cmn_err(level, mp, fmt, args...) \
- xfs_fs_cmn_err(level, mp, fmt " Unmount and run xfs_repair.", ## args)
-
-#define xfs_fs_mount_cmn_err(f, fmt, args...) \
- ((f & XFS_MFSI_QUIET)? cmn_err(CE_WARN, "XFS: " fmt, ## args) : (void)0)
-
-#endif /* __XFS_ERROR_H__ */
-
diff --git a/sys/gnu/fs/xfs/xfs_extfree_item.c b/sys/gnu/fs/xfs/xfs_extfree_item.c
deleted file mode 100644
index f19282e..0000000
--- a/sys/gnu/fs/xfs/xfs_extfree_item.c
+++ /dev/null
@@ -1,587 +0,0 @@
-/*
- * Copyright (c) 2000-2001,2005 Silicon Graphics, Inc.
- * All Rights Reserved.
- *
- * 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.
- *
- * This program is distributed in the hope that it would 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 the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- */
-#include "xfs.h"
-#include "xfs_fs.h"
-#include "xfs_types.h"
-#include "xfs_log.h"
-#include "xfs_inum.h"
-#include "xfs_trans.h"
-#include "xfs_buf_item.h"
-#include "xfs_sb.h"
-#include "xfs_dir.h"
-#include "xfs_dmapi.h"
-#include "xfs_mount.h"
-#include "xfs_trans_priv.h"
-#include "xfs_extfree_item.h"
-
-
-kmem_zone_t *xfs_efi_zone;
-kmem_zone_t *xfs_efd_zone;
-
-STATIC void xfs_efi_item_unlock(xfs_efi_log_item_t *);
-STATIC void xfs_efi_item_abort(xfs_efi_log_item_t *);
-STATIC void xfs_efd_item_abort(xfs_efd_log_item_t *);
-
-
-void
-xfs_efi_item_free(xfs_efi_log_item_t *efip)
-{
- int nexts = efip->efi_format.efi_nextents;
-
- if (nexts > XFS_EFI_MAX_FAST_EXTENTS) {
- kmem_free(efip, sizeof(xfs_efi_log_item_t) +
- (nexts - 1) * sizeof(xfs_extent_t));
- } else {
- kmem_zone_free(xfs_efi_zone, efip);
- }
-}
-
-/*
- * This returns the number of iovecs needed to log the given efi item.
- * We only need 1 iovec for an efi item. It just logs the efi_log_format
- * structure.
- */
-/*ARGSUSED*/
-STATIC uint
-xfs_efi_item_size(xfs_efi_log_item_t *efip)
-{
- return 1;
-}
-
-/*
- * This is called to fill in the vector of log iovecs for the
- * given efi log item. We use only 1 iovec, and we point that
- * at the efi_log_format structure embedded in the efi item.
- * It is at this point that we assert that all of the extent
- * slots in the efi item have been filled.
- */
-STATIC void
-xfs_efi_item_format(xfs_efi_log_item_t *efip,
- xfs_log_iovec_t *log_vector)
-{
- uint size;
-
- ASSERT(efip->efi_next_extent == efip->efi_format.efi_nextents);
-
- efip->efi_format.efi_type = XFS_LI_EFI;
-
- size = sizeof(xfs_efi_log_format_t);
- size += (efip->efi_format.efi_nextents - 1) * sizeof(xfs_extent_t);
- efip->efi_format.efi_size = 1;
-
- log_vector->i_addr = (xfs_caddr_t)&(efip->efi_format);
- log_vector->i_len = size;
- XLOG_VEC_SET_TYPE(log_vector, XLOG_REG_TYPE_EFI_FORMAT);
- ASSERT(size >= sizeof(xfs_efi_log_format_t));
-}
-
-
-/*
- * Pinning has no meaning for an efi item, so just return.
- */
-/*ARGSUSED*/
-STATIC void
-xfs_efi_item_pin(xfs_efi_log_item_t *efip)
-{
- return;
-}
-
-
-/*
- * While EFIs cannot really be pinned, the unpin operation is the
- * last place at which the EFI is manipulated during a transaction.
- * Here we coordinate with xfs_efi_cancel() to determine who gets to
- * free the EFI.
- */
-/*ARGSUSED*/
-STATIC void
-xfs_efi_item_unpin(xfs_efi_log_item_t *efip, int stale)
-{
- xfs_mount_t *mp;
- SPLDECL(s);
-
- mp = efip->efi_item.li_mountp;
- AIL_LOCK(mp, s);
- if (efip->efi_flags & XFS_EFI_CANCELED) {
- /*
- * xfs_trans_delete_ail() drops the AIL lock.
- */
- xfs_trans_delete_ail(mp, (xfs_log_item_t *)efip, s);
- xfs_efi_item_free(efip);
- } else {
- efip->efi_flags |= XFS_EFI_COMMITTED;
- AIL_UNLOCK(mp, s);
- }
-}
-
-/*
- * like unpin only we have to also clear the xaction descriptor
- * pointing the log item if we free the item. This routine duplicates
- * unpin because efi_flags is protected by the AIL lock. Freeing
- * the descriptor and then calling unpin would force us to drop the AIL
- * lock which would open up a race condition.
- */
-STATIC void
-xfs_efi_item_unpin_remove(xfs_efi_log_item_t *efip, xfs_trans_t *tp)
-{
- xfs_mount_t *mp;
- xfs_log_item_desc_t *lidp;
- SPLDECL(s);
-
- mp = efip->efi_item.li_mountp;
- AIL_LOCK(mp, s);
- if (efip->efi_flags & XFS_EFI_CANCELED) {
- /*
- * free the xaction descriptor pointing to this item
- */
- lidp = xfs_trans_find_item(tp, (xfs_log_item_t *) efip);
- xfs_trans_free_item(tp, lidp);
- /*
- * pull the item off the AIL.
- * xfs_trans_delete_ail() drops the AIL lock.
- */
- xfs_trans_delete_ail(mp, (xfs_log_item_t *)efip, s);
- xfs_efi_item_free(efip);
- } else {
- efip->efi_flags |= XFS_EFI_COMMITTED;
- AIL_UNLOCK(mp, s);
- }
-}
-
-/*
- * Efi items have no locking or pushing. However, since EFIs are
- * pulled from the AIL when their corresponding EFDs are committed
- * to disk, their situation is very similar to being pinned. Return
- * XFS_ITEM_PINNED so that the caller will eventually flush the log.
- * This should help in getting the EFI out of the AIL.
- */
-/*ARGSUSED*/
-STATIC uint
-xfs_efi_item_trylock(xfs_efi_log_item_t *efip)
-{
- return XFS_ITEM_PINNED;
-}
-
-/*
- * Efi items have no locking, so just return.
- */
-/*ARGSUSED*/
-STATIC void
-xfs_efi_item_unlock(xfs_efi_log_item_t *efip)
-{
- if (efip->efi_item.li_flags & XFS_LI_ABORTED)
- xfs_efi_item_abort(efip);
- return;
-}
-
-/*
- * The EFI is logged only once and cannot be moved in the log, so
- * simply return the lsn at which it's been logged. The canceled
- * flag is not paid any attention here. Checking for that is delayed
- * until the EFI is unpinned.
- */
-/*ARGSUSED*/
-STATIC xfs_lsn_t
-xfs_efi_item_committed(xfs_efi_log_item_t *efip, xfs_lsn_t lsn)
-{
- return lsn;
-}
-
-/*
- * This is called when the transaction logging the EFI is aborted.
- * Free up the EFI and return. No need to clean up the slot for
- * the item in the transaction. That was done by the unpin code
- * which is called prior to this routine in the abort/fs-shutdown path.
- */
-STATIC void
-xfs_efi_item_abort(xfs_efi_log_item_t *efip)
-{
- xfs_efi_item_free(efip);
-}
-
-/*
- * There isn't much you can do to push on an efi item. It is simply
- * stuck waiting for all of its corresponding efd items to be
- * committed to disk.
- */
-/*ARGSUSED*/
-STATIC void
-xfs_efi_item_push(xfs_efi_log_item_t *efip)
-{
- return;
-}
-
-/*
- * The EFI dependency tracking op doesn't do squat. It can't because
- * it doesn't know where the free extent is coming from. The dependency
- * tracking has to be handled by the "enclosing" metadata object. For
- * example, for inodes, the inode is locked throughout the extent freeing
- * so the dependency should be recorded there.
- */
-/*ARGSUSED*/
-STATIC void
-xfs_efi_item_committing(xfs_efi_log_item_t *efip, xfs_lsn_t lsn)
-{
- return;
-}
-
-/*
- * This is the ops vector shared by all efi log items.
- */
-STATIC struct xfs_item_ops xfs_efi_item_ops = {
- .iop_size = (uint(*)(xfs_log_item_t*))xfs_efi_item_size,
- .iop_format = (void(*)(xfs_log_item_t*, xfs_log_iovec_t*))
- xfs_efi_item_format,
- .iop_pin = (void(*)(xfs_log_item_t*))xfs_efi_item_pin,
- .iop_unpin = (void(*)(xfs_log_item_t*, int))xfs_efi_item_unpin,
- .iop_unpin_remove = (void(*)(xfs_log_item_t*, xfs_trans_t *))
- xfs_efi_item_unpin_remove,
- .iop_trylock = (uint(*)(xfs_log_item_t*))xfs_efi_item_trylock,
- .iop_unlock = (void(*)(xfs_log_item_t*))xfs_efi_item_unlock,
- .iop_committed = (xfs_lsn_t(*)(xfs_log_item_t*, xfs_lsn_t))
- xfs_efi_item_committed,
- .iop_push = (void(*)(xfs_log_item_t*))xfs_efi_item_push,
- .iop_abort = (void(*)(xfs_log_item_t*))xfs_efi_item_abort,
- .iop_pushbuf = NULL,
- .iop_committing = (void(*)(xfs_log_item_t*, xfs_lsn_t))
- xfs_efi_item_committing
-};
-
-
-/*
- * Allocate and initialize an efi item with the given number of extents.
- */
-xfs_efi_log_item_t *
-xfs_efi_init(xfs_mount_t *mp,
- uint nextents)
-
-{
- xfs_efi_log_item_t *efip;
- uint size;
-
- ASSERT(nextents > 0);
- if (nextents > XFS_EFI_MAX_FAST_EXTENTS) {
- size = (uint)(sizeof(xfs_efi_log_item_t) +
- ((nextents - 1) * sizeof(xfs_extent_t)));
- efip = (xfs_efi_log_item_t*)kmem_zalloc(size, KM_SLEEP);
- } else {
- efip = (xfs_efi_log_item_t*)kmem_zone_zalloc(xfs_efi_zone,
- KM_SLEEP);
- }
-
- efip->efi_item.li_type = XFS_LI_EFI;
- efip->efi_item.li_ops = &xfs_efi_item_ops;
- efip->efi_item.li_mountp = mp;
- efip->efi_format.efi_nextents = nextents;
- efip->efi_format.efi_id = (__psint_t)(void*)efip;
-
- return (efip);
-}
-
-/*
- * This is called by the efd item code below to release references to
- * the given efi item. Each efd calls this with the number of
- * extents that it has logged, and when the sum of these reaches
- * the total number of extents logged by this efi item we can free
- * the efi item.
- *
- * Freeing the efi item requires that we remove it from the AIL.
- * We'll use the AIL lock to protect our counters as well as
- * the removal from the AIL.
- */
-void
-xfs_efi_release(xfs_efi_log_item_t *efip,
- uint nextents)
-{
- xfs_mount_t *mp;
- int extents_left;
- SPLDECL(s);
-
- mp = efip->efi_item.li_mountp;
- ASSERT(efip->efi_next_extent > 0);
- ASSERT(efip->efi_flags & XFS_EFI_COMMITTED);
-
- AIL_LOCK(mp, s);
- ASSERT(efip->efi_next_extent >= nextents);
- efip->efi_next_extent -= nextents;
- extents_left = efip->efi_next_extent;
- if (extents_left == 0) {
- /*
- * xfs_trans_delete_ail() drops the AIL lock.
- */
- xfs_trans_delete_ail(mp, (xfs_log_item_t *)efip, s);
- xfs_efi_item_free(efip);
- } else {
- AIL_UNLOCK(mp, s);
- }
-}
-
-/*
- * This is called when the transaction that should be committing the
- * EFD corresponding to the given EFI is aborted. The committed and
- * canceled flags are used to coordinate the freeing of the EFI and
- * the references by the transaction that committed it.
- */
-STATIC void
-xfs_efi_cancel(
- xfs_efi_log_item_t *efip)
-{
- xfs_mount_t *mp;
- SPLDECL(s);
-
- mp = efip->efi_item.li_mountp;
- AIL_LOCK(mp, s);
- if (efip->efi_flags & XFS_EFI_COMMITTED) {
- /*
- * xfs_trans_delete_ail() drops the AIL lock.
- */
- xfs_trans_delete_ail(mp, (xfs_log_item_t *)efip, s);
- xfs_efi_item_free(efip);
- } else {
- efip->efi_flags |= XFS_EFI_CANCELED;
- AIL_UNLOCK(mp, s);
- }
-}
-
-STATIC void
-xfs_efd_item_free(xfs_efd_log_item_t *efdp)
-{
- int nexts = efdp->efd_format.efd_nextents;
-
- if (nexts > XFS_EFD_MAX_FAST_EXTENTS) {
- kmem_free(efdp, sizeof(xfs_efd_log_item_t) +
- (nexts - 1) * sizeof(xfs_extent_t));
- } else {
- kmem_zone_free(xfs_efd_zone, efdp);
- }
-}
-
-/*
- * This returns the number of iovecs needed to log the given efd item.
- * We only need 1 iovec for an efd item. It just logs the efd_log_format
- * structure.
- */
-/*ARGSUSED*/
-STATIC uint
-xfs_efd_item_size(xfs_efd_log_item_t *efdp)
-{
- return 1;
-}
-
-/*
- * This is called to fill in the vector of log iovecs for the
- * given efd log item. We use only 1 iovec, and we point that
- * at the efd_log_format structure embedded in the efd item.
- * It is at this point that we assert that all of the extent
- * slots in the efd item have been filled.
- */
-STATIC void
-xfs_efd_item_format(xfs_efd_log_item_t *efdp,
- xfs_log_iovec_t *log_vector)
-{
- uint size;
-
- ASSERT(efdp->efd_next_extent == efdp->efd_format.efd_nextents);
-
- efdp->efd_format.efd_type = XFS_LI_EFD;
-
- size = sizeof(xfs_efd_log_format_t);
- size += (efdp->efd_format.efd_nextents - 1) * sizeof(xfs_extent_t);
- efdp->efd_format.efd_size = 1;
-
- log_vector->i_addr = (xfs_caddr_t)&(efdp->efd_format);
- log_vector->i_len = size;
- XLOG_VEC_SET_TYPE(log_vector, XLOG_REG_TYPE_EFD_FORMAT);
- ASSERT(size >= sizeof(xfs_efd_log_format_t));
-}
-
-
-/*
- * Pinning has no meaning for an efd item, so just return.
- */
-/*ARGSUSED*/
-STATIC void
-xfs_efd_item_pin(xfs_efd_log_item_t *efdp)
-{
- return;
-}
-
-
-/*
- * Since pinning has no meaning for an efd item, unpinning does
- * not either.
- */
-/*ARGSUSED*/
-STATIC void
-xfs_efd_item_unpin(xfs_efd_log_item_t *efdp, int stale)
-{
- return;
-}
-
-/*ARGSUSED*/
-STATIC void
-xfs_efd_item_unpin_remove(xfs_efd_log_item_t *efdp, xfs_trans_t *tp)
-{
- return;
-}
-
-/*
- * Efd items have no locking, so just return success.
- */
-/*ARGSUSED*/
-STATIC uint
-xfs_efd_item_trylock(xfs_efd_log_item_t *efdp)
-{
- return XFS_ITEM_LOCKED;
-}
-
-/*
- * Efd items have no locking or pushing, so return failure
- * so that the caller doesn't bother with us.
- */
-/*ARGSUSED*/
-STATIC void
-xfs_efd_item_unlock(xfs_efd_log_item_t *efdp)
-{
- if (efdp->efd_item.li_flags & XFS_LI_ABORTED)
- xfs_efd_item_abort(efdp);
- return;
-}
-
-/*
- * When the efd item is committed to disk, all we need to do
- * is delete our reference to our partner efi item and then
- * free ourselves. Since we're freeing ourselves we must
- * return -1 to keep the transaction code from further referencing
- * this item.
- */
-/*ARGSUSED*/
-STATIC xfs_lsn_t
-xfs_efd_item_committed(xfs_efd_log_item_t *efdp, xfs_lsn_t lsn)
-{
- /*
- * If we got a log I/O error, it's always the case that the LR with the
- * EFI got unpinned and freed before the EFD got aborted.
- */
- if ((efdp->efd_item.li_flags & XFS_LI_ABORTED) == 0)
- xfs_efi_release(efdp->efd_efip, efdp->efd_format.efd_nextents);
-
- xfs_efd_item_free(efdp);
- return (xfs_lsn_t)-1;
-}
-
-/*
- * The transaction of which this EFD is a part has been aborted.
- * Inform its companion EFI of this fact and then clean up after
- * ourselves. No need to clean up the slot for the item in the
- * transaction. That was done by the unpin code which is called
- * prior to this routine in the abort/fs-shutdown path.
- */
-STATIC void
-xfs_efd_item_abort(xfs_efd_log_item_t *efdp)
-{
- /*
- * If we got a log I/O error, it's always the case that the LR with the
- * EFI got unpinned and freed before the EFD got aborted. So don't
- * reference the EFI at all in that case.
- */
- if ((efdp->efd_item.li_flags & XFS_LI_ABORTED) == 0)
- xfs_efi_cancel(efdp->efd_efip);
-
- xfs_efd_item_free(efdp);
-}
-
-/*
- * There isn't much you can do to push on an efd item. It is simply
- * stuck waiting for the log to be flushed to disk.
- */
-/*ARGSUSED*/
-STATIC void
-xfs_efd_item_push(xfs_efd_log_item_t *efdp)
-{
- return;
-}
-
-/*
- * The EFD dependency tracking op doesn't do squat. It can't because
- * it doesn't know where the free extent is coming from. The dependency
- * tracking has to be handled by the "enclosing" metadata object. For
- * example, for inodes, the inode is locked throughout the extent freeing
- * so the dependency should be recorded there.
- */
-/*ARGSUSED*/
-STATIC void
-xfs_efd_item_committing(xfs_efd_log_item_t *efip, xfs_lsn_t lsn)
-{
- return;
-}
-
-/*
- * This is the ops vector shared by all efd log items.
- */
-STATIC struct xfs_item_ops xfs_efd_item_ops = {
- .iop_size = (uint(*)(xfs_log_item_t*))xfs_efd_item_size,
- .iop_format = (void(*)(xfs_log_item_t*, xfs_log_iovec_t*))
- xfs_efd_item_format,
- .iop_pin = (void(*)(xfs_log_item_t*))xfs_efd_item_pin,
- .iop_unpin = (void(*)(xfs_log_item_t*, int))xfs_efd_item_unpin,
- .iop_unpin_remove = (void(*)(xfs_log_item_t*, xfs_trans_t*))
- xfs_efd_item_unpin_remove,
- .iop_trylock = (uint(*)(xfs_log_item_t*))xfs_efd_item_trylock,
- .iop_unlock = (void(*)(xfs_log_item_t*))xfs_efd_item_unlock,
- .iop_committed = (xfs_lsn_t(*)(xfs_log_item_t*, xfs_lsn_t))
- xfs_efd_item_committed,
- .iop_push = (void(*)(xfs_log_item_t*))xfs_efd_item_push,
- .iop_abort = (void(*)(xfs_log_item_t*))xfs_efd_item_abort,
- .iop_pushbuf = NULL,
- .iop_committing = (void(*)(xfs_log_item_t*, xfs_lsn_t))
- xfs_efd_item_committing
-};
-
-
-/*
- * Allocate and initialize an efd item with the given number of extents.
- */
-xfs_efd_log_item_t *
-xfs_efd_init(xfs_mount_t *mp,
- xfs_efi_log_item_t *efip,
- uint nextents)
-
-{
- xfs_efd_log_item_t *efdp;
- uint size;
-
- ASSERT(nextents > 0);
- if (nextents > XFS_EFD_MAX_FAST_EXTENTS) {
- size = (uint)(sizeof(xfs_efd_log_item_t) +
- ((nextents - 1) * sizeof(xfs_extent_t)));
- efdp = (xfs_efd_log_item_t*)kmem_zalloc(size, KM_SLEEP);
- } else {
- efdp = (xfs_efd_log_item_t*)kmem_zone_zalloc(xfs_efd_zone,
- KM_SLEEP);
- }
-
- efdp->efd_item.li_type = XFS_LI_EFD;
- efdp->efd_item.li_ops = &xfs_efd_item_ops;
- efdp->efd_item.li_mountp = mp;
- efdp->efd_efip = efip;
- efdp->efd_format.efd_nextents = nextents;
- efdp->efd_format.efd_efi_id = efip->efi_format.efi_id;
-
- return (efdp);
-}
diff --git a/sys/gnu/fs/xfs/xfs_extfree_item.h b/sys/gnu/fs/xfs/xfs_extfree_item.h
deleted file mode 100644
index 5bf6817..0000000
--- a/sys/gnu/fs/xfs/xfs_extfree_item.h
+++ /dev/null
@@ -1,111 +0,0 @@
-/*
- * Copyright (c) 2000,2005 Silicon Graphics, Inc.
- * All Rights Reserved.
- *
- * 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.
- *
- * This program is distributed in the hope that it would 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 the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- */
-#ifndef __XFS_EXTFREE_ITEM_H__
-#define __XFS_EXTFREE_ITEM_H__
-
-struct xfs_mount;
-struct kmem_zone;
-
-typedef struct xfs_extent {
- xfs_dfsbno_t ext_start;
- xfs_extlen_t ext_len;
-} xfs_extent_t;
-
-/*
- * This is the structure used to lay out an efi log item in the
- * log. The efi_extents field is a variable size array whose
- * size is given by efi_nextents.
- */
-typedef struct xfs_efi_log_format {
- unsigned short efi_type; /* efi log item type */
- unsigned short efi_size; /* size of this item */
- uint efi_nextents; /* # extents to free */
- __uint64_t efi_id; /* efi identifier */
- xfs_extent_t efi_extents[1]; /* array of extents to free */
-} xfs_efi_log_format_t;
-
-/*
- * This is the structure used to lay out an efd log item in the
- * log. The efd_extents array is a variable size array whose
- * size is given by efd_nextents;
- */
-typedef struct xfs_efd_log_format {
- unsigned short efd_type; /* efd log item type */
- unsigned short efd_size; /* size of this item */
- uint efd_nextents; /* # of extents freed */
- __uint64_t efd_efi_id; /* id of corresponding efi */
- xfs_extent_t efd_extents[1]; /* array of extents freed */
-} xfs_efd_log_format_t;
-
-
-#ifdef __KERNEL__
-
-/*
- * Max number of extents in fast allocation path.
- */
-#define XFS_EFI_MAX_FAST_EXTENTS 16
-
-/*
- * Define EFI flags.
- */
-#define XFS_EFI_RECOVERED 0x1
-#define XFS_EFI_COMMITTED 0x2
-#define XFS_EFI_CANCELED 0x4
-
-/*
- * This is the "extent free intention" log item. It is used
- * to log the fact that some extents need to be free. It is
- * used in conjunction with the "extent free done" log item
- * described below.
- */
-typedef struct xfs_efi_log_item {
- xfs_log_item_t efi_item;
- uint efi_flags; /* misc flags */
- uint efi_next_extent;
- xfs_efi_log_format_t efi_format;
-} xfs_efi_log_item_t;
-
-/*
- * This is the "extent free done" log item. It is used to log
- * the fact that some extents earlier mentioned in an efi item
- * have been freed.
- */
-typedef struct xfs_efd_log_item {
- xfs_log_item_t efd_item;
- xfs_efi_log_item_t *efd_efip;
- uint efd_next_extent;
- xfs_efd_log_format_t efd_format;
-} xfs_efd_log_item_t;
-
-/*
- * Max number of extents in fast allocation path.
- */
-#define XFS_EFD_MAX_FAST_EXTENTS 16
-
-extern struct kmem_zone *xfs_efi_zone;
-extern struct kmem_zone *xfs_efd_zone;
-
-xfs_efi_log_item_t *xfs_efi_init(struct xfs_mount *, uint);
-xfs_efd_log_item_t *xfs_efd_init(struct xfs_mount *, xfs_efi_log_item_t *,
- uint);
-
-void xfs_efi_item_free(xfs_efi_log_item_t *);
-
-#endif /* __KERNEL__ */
-
-#endif /* __XFS_EXTFREE_ITEM_H__ */
diff --git a/sys/gnu/fs/xfs/xfs_fs.h b/sys/gnu/fs/xfs/xfs_fs.h
deleted file mode 100644
index e9736a8..0000000
--- a/sys/gnu/fs/xfs/xfs_fs.h
+++ /dev/null
@@ -1,527 +0,0 @@
-/*
- * Copyright (c) 1995-2005 Silicon Graphics, Inc.
- * All Rights Reserved.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public License
- * as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it would 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 this program; if not, write the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- */
-#ifndef __XFS_FS_H__
-#define __XFS_FS_H__
-
-/*
- * SGI's XFS filesystem's major stuff (constants, structures)
- */
-
-#define XFS_NAME "xfs"
-
-/*
- * Direct I/O attribute record used with XFS_IOC_DIOINFO
- * d_miniosz is the min xfer size, xfer size multiple and file seek offset
- * alignment.
- */
-#ifndef HAVE_DIOATTR
-struct dioattr {
- __u32 d_mem; /* data buffer memory alignment */
- __u32 d_miniosz; /* min xfer size */
- __u32 d_maxiosz; /* max xfer size */
-};
-#endif
-
-/*
- * Structure for XFS_IOC_FSGETXATTR[A] and XFS_IOC_FSSETXATTR.
- */
-#ifndef HAVE_FSXATTR
-struct fsxattr {
- __u32 fsx_xflags; /* xflags field value (get/set) */
- __u32 fsx_extsize; /* extsize field value (get/set)*/
- __u32 fsx_nextents; /* nextents field value (get) */
- __u32 fsx_projid; /* project identifier (get/set) */
- unsigned char fsx_pad[12];
-};
-#endif
-
-/*
- * Flags for the bs_xflags/fsx_xflags field
- * There should be a one-to-one correspondence between these flags and the
- * XFS_DIFLAG_s.
- */
-#define XFS_XFLAG_REALTIME 0x00000001 /* data in realtime volume */
-#define XFS_XFLAG_PREALLOC 0x00000002 /* preallocated file extents */
-#define XFS_XFLAG_IMMUTABLE 0x00000008 /* file cannot be modified */
-#define XFS_XFLAG_APPEND 0x00000010 /* all writes append */
-#define XFS_XFLAG_SYNC 0x00000020 /* all writes synchronous */
-#define XFS_XFLAG_NOATIME 0x00000040 /* do not update access time */
-#define XFS_XFLAG_NODUMP 0x00000080 /* do not include in backups */
-#define XFS_XFLAG_RTINHERIT 0x00000100 /* create with rt bit set */
-#define XFS_XFLAG_PROJINHERIT 0x00000200 /* create with parents projid */
-#define XFS_XFLAG_NOSYMLINKS 0x00000400 /* disallow symlink creation */
-#define XFS_XFLAG_EXTSIZE 0x00000800 /* extent size allocator hint */
-#define XFS_XFLAG_EXTSZINHERIT 0x00001000 /* inherit inode extent size */
-#define XFS_XFLAG_HASATTR 0x80000000 /* no DIFLAG for this */
-
-/*
- * Structure for XFS_IOC_GETBMAP.
- * On input, fill in bmv_offset and bmv_length of the first structure
- * to indicate the area of interest in the file, and bmv_entry with the
- * number of array elements given. The first structure is updated on
- * return to give the offset and length for the next call.
- */
-#ifndef HAVE_GETBMAP
-struct getbmap {
- __s64 bmv_offset; /* file offset of segment in blocks */
- __s64 bmv_block; /* starting block (64-bit daddr_t) */
- __s64 bmv_length; /* length of segment, blocks */
- __s32 bmv_count; /* # of entries in array incl. 1st */
- __s32 bmv_entries; /* # of entries filled in (output) */
-};
-#endif
-
-/*
- * Structure for XFS_IOC_GETBMAPX. Fields bmv_offset through bmv_entries
- * are used exactly as in the getbmap structure. The getbmapx structure
- * has additional bmv_iflags and bmv_oflags fields. The bmv_iflags field
- * is only used for the first structure. It contains input flags
- * specifying XFS_IOC_GETBMAPX actions. The bmv_oflags field is filled
- * in by the XFS_IOC_GETBMAPX command for each returned structure after
- * the first.
- */
-#ifndef HAVE_GETBMAPX
-struct getbmapx {
- __s64 bmv_offset; /* file offset of segment in blocks */
- __s64 bmv_block; /* starting block (64-bit daddr_t) */
- __s64 bmv_length; /* length of segment, blocks */
- __s32 bmv_count; /* # of entries in array incl. 1st */
- __s32 bmv_entries; /* # of entries filled in (output). */
- __s32 bmv_iflags; /* input flags (1st structure) */
- __s32 bmv_oflags; /* output flags (after 1st structure)*/
- __s32 bmv_unused1; /* future use */
- __s32 bmv_unused2; /* future use */
-};
-#endif
-
-/* bmv_iflags values - set by XFS_IOC_GETBMAPX caller. */
-#define BMV_IF_ATTRFORK 0x1 /* return attr fork rather than data */
-#define BMV_IF_NO_DMAPI_READ 0x2 /* Do not generate DMAPI read event */
-#define BMV_IF_PREALLOC 0x4 /* rtn status BMV_OF_PREALLOC if req */
-#define BMV_IF_VALID (BMV_IF_ATTRFORK|BMV_IF_NO_DMAPI_READ|BMV_IF_PREALLOC)
-#ifdef __KERNEL__
-#define BMV_IF_EXTENDED 0x40000000 /* getpmapx if set */
-#endif
-
-/* bmv_oflags values - returned for for each non-header segment */
-#define BMV_OF_PREALLOC 0x1 /* segment = unwritten pre-allocation */
-
-/* Convert getbmap <-> getbmapx - move fields from p1 to p2. */
-#define GETBMAP_CONVERT(p1,p2) { \
- p2.bmv_offset = p1.bmv_offset; \
- p2.bmv_block = p1.bmv_block; \
- p2.bmv_length = p1.bmv_length; \
- p2.bmv_count = p1.bmv_count; \
- p2.bmv_entries = p1.bmv_entries; \
- \
-printf("offset 0x%jx block 0x%jx length 0x%jx count 0x%jx entries %d\n", \
- (uint64_t)p2.bmv_offset, \
- (uint64_t)p2.bmv_block, \
- (uint64_t)p2.bmv_length, \
- (uint64_t)p2.bmv_count, \
- p2.bmv_entries); \
- }
-
-
-/*
- * Structure for XFS_IOC_FSSETDM.
- * For use by backup and restore programs to set the XFS on-disk inode
- * fields di_dmevmask and di_dmstate. These must be set to exactly and
- * only values previously obtained via xfs_bulkstat! (Specifically the
- * xfs_bstat_t fields bs_dmevmask and bs_dmstate.)
- */
-#ifndef HAVE_FSDMIDATA
-struct fsdmidata {
- __u32 fsd_dmevmask; /* corresponds to di_dmevmask */
- __u16 fsd_padding;
- __u16 fsd_dmstate; /* corresponds to di_dmstate */
-};
-#endif
-
-/*
- * File segment locking set data type for 64 bit access.
- * Also used for all the RESV/FREE interfaces.
- */
-typedef struct xfs_flock64 {
- __s16 l_type;
- __s16 l_whence;
- __s64 l_start;
- __s64 l_len; /* len == 0 means until end of file */
- __s32 l_sysid;
- __u32 l_pid;
- __s32 l_pad[4]; /* reserve area */
-} xfs_flock64_t;
-
-/*
- * Output for XFS_IOC_FSGEOMETRY_V1
- */
-typedef struct xfs_fsop_geom_v1 {
- __u32 blocksize; /* filesystem (data) block size */
- __u32 rtextsize; /* realtime extent size */
- __u32 agblocks; /* fsblocks in an AG */
- __u32 agcount; /* number of allocation groups */
- __u32 logblocks; /* fsblocks in the log */
- __u32 sectsize; /* (data) sector size, bytes */
- __u32 inodesize; /* inode size in bytes */
- __u32 imaxpct; /* max allowed inode space(%) */
- __u64 datablocks; /* fsblocks in data subvolume */
- __u64 rtblocks; /* fsblocks in realtime subvol */
- __u64 rtextents; /* rt extents in realtime subvol*/
- __u64 logstart; /* starting fsblock of the log */
- unsigned char uuid[16]; /* unique id of the filesystem */
- __u32 sunit; /* stripe unit, fsblocks */
- __u32 swidth; /* stripe width, fsblocks */
- __s32 version; /* structure version */
- __u32 flags; /* superblock version flags */
- __u32 logsectsize; /* log sector size, bytes */
- __u32 rtsectsize; /* realtime sector size, bytes */
- __u32 dirblocksize; /* directory block size, bytes */
-} xfs_fsop_geom_v1_t;
-
-/*
- * Output for XFS_IOC_FSGEOMETRY
- */
-typedef struct xfs_fsop_geom {
- __u32 blocksize; /* filesystem (data) block size */
- __u32 rtextsize; /* realtime extent size */
- __u32 agblocks; /* fsblocks in an AG */
- __u32 agcount; /* number of allocation groups */
- __u32 logblocks; /* fsblocks in the log */
- __u32 sectsize; /* (data) sector size, bytes */
- __u32 inodesize; /* inode size in bytes */
- __u32 imaxpct; /* max allowed inode space(%) */
- __u64 datablocks; /* fsblocks in data subvolume */
- __u64 rtblocks; /* fsblocks in realtime subvol */
- __u64 rtextents; /* rt extents in realtime subvol*/
- __u64 logstart; /* starting fsblock of the log */
- unsigned char uuid[16]; /* unique id of the filesystem */
- __u32 sunit; /* stripe unit, fsblocks */
- __u32 swidth; /* stripe width, fsblocks */
- __s32 version; /* structure version */
- __u32 flags; /* superblock version flags */
- __u32 logsectsize; /* log sector size, bytes */
- __u32 rtsectsize; /* realtime sector size, bytes */
- __u32 dirblocksize; /* directory block size, bytes */
- __u32 logsunit; /* log stripe unit, bytes */
-} xfs_fsop_geom_t;
-
-/* Output for XFS_FS_COUNTS */
-typedef struct xfs_fsop_counts {
- __u64 freedata; /* free data section blocks */
- __u64 freertx; /* free rt extents */
- __u64 freeino; /* free inodes */
- __u64 allocino; /* total allocated inodes */
-} xfs_fsop_counts_t;
-
-/* Input/Output for XFS_GET_RESBLKS and XFS_SET_RESBLKS */
-typedef struct xfs_fsop_resblks {
- __u64 resblks;
- __u64 resblks_avail;
-} xfs_fsop_resblks_t;
-
-#define XFS_FSOP_GEOM_VERSION 0
-
-#define XFS_FSOP_GEOM_FLAGS_ATTR 0x0001 /* attributes in use */
-#define XFS_FSOP_GEOM_FLAGS_NLINK 0x0002 /* 32-bit nlink values */
-#define XFS_FSOP_GEOM_FLAGS_QUOTA 0x0004 /* quotas enabled */
-#define XFS_FSOP_GEOM_FLAGS_IALIGN 0x0008 /* inode alignment */
-#define XFS_FSOP_GEOM_FLAGS_DALIGN 0x0010 /* large data alignment */
-#define XFS_FSOP_GEOM_FLAGS_SHARED 0x0020 /* read-only shared */
-#define XFS_FSOP_GEOM_FLAGS_EXTFLG 0x0040 /* special extent flag */
-#define XFS_FSOP_GEOM_FLAGS_DIRV2 0x0080 /* directory version 2 */
-#define XFS_FSOP_GEOM_FLAGS_LOGV2 0x0100 /* log format version 2 */
-#define XFS_FSOP_GEOM_FLAGS_SECTOR 0x0200 /* sector sizes >1BB */
-#define XFS_FSOP_GEOM_FLAGS_ATTR2 0x0400 /* inline attributes rework */
-
-
-/*
- * Minimum and maximum sizes need for growth checks
- */
-#define XFS_MIN_AG_BLOCKS 64
-#define XFS_MIN_LOG_BLOCKS 512
-#define XFS_MAX_LOG_BLOCKS (64 * 1024)
-#define XFS_MIN_LOG_BYTES (256 * 1024)
-#define XFS_MAX_LOG_BYTES (128 * 1024 * 1024)
-
-/*
- * Structures for XFS_IOC_FSGROWFSDATA, XFS_IOC_FSGROWFSLOG & XFS_IOC_FSGROWFSRT
- */
-typedef struct xfs_growfs_data {
- __u64 newblocks; /* new data subvol size, fsblocks */
- __u32 imaxpct; /* new inode space percentage limit */
-} xfs_growfs_data_t;
-
-typedef struct xfs_growfs_log {
- __u32 newblocks; /* new log size, fsblocks */
- __u32 isint; /* 1 if new log is internal */
-} xfs_growfs_log_t;
-
-typedef struct xfs_growfs_rt {
- __u64 newblocks; /* new realtime size, fsblocks */
- __u32 extsize; /* new realtime extent size, fsblocks */
-} xfs_growfs_rt_t;
-
-
-/*
- * Structures returned from ioctl XFS_IOC_FSBULKSTAT & XFS_IOC_FSBULKSTAT_SINGLE
- */
-typedef struct xfs_bstime {
- time_t tv_sec; /* seconds */
- __s32 tv_nsec; /* and nanoseconds */
-} xfs_bstime_t;
-
-typedef struct xfs_bstat {
- __u64 bs_ino; /* inode number */
- __u16 bs_mode; /* type and mode */
- __u16 bs_nlink; /* number of links */
- __u32 bs_uid; /* user id */
- __u32 bs_gid; /* group id */
- __u32 bs_rdev; /* device value */
- __s32 bs_blksize; /* block size */
- __s64 bs_size; /* file size */
- xfs_bstime_t bs_atime; /* access time */
- xfs_bstime_t bs_mtime; /* modify time */
- xfs_bstime_t bs_ctime; /* inode change time */
- int64_t bs_blocks; /* number of blocks */
- __u32 bs_xflags; /* extended flags */
- __s32 bs_extsize; /* extent size */
- __s32 bs_extents; /* number of extents */
- __u32 bs_gen; /* generation count */
- __u16 bs_projid; /* project id */
- unsigned char bs_pad[14]; /* pad space, unused */
- __u32 bs_dmevmask; /* DMIG event mask */
- __u16 bs_dmstate; /* DMIG state info */
- __u16 bs_aextents; /* attribute number of extents */
-} xfs_bstat_t;
-
-/*
- * The user-level BulkStat Request interface structure.
- */
-typedef struct xfs_fsop_bulkreq {
- __u64 __user *lastip; /* last inode # pointer */
- __s32 icount; /* count of entries in buffer */
- void __user *ubuffer;/* user buffer for inode desc. */
- __s32 __user *ocount; /* output count pointer */
-} xfs_fsop_bulkreq_t;
-
-
-/*
- * Structures returned from xfs_inumbers routine (XFS_IOC_FSINUMBERS).
- */
-typedef struct xfs_inogrp {
- __u64 xi_startino; /* starting inode number */
- __s32 xi_alloccount; /* # bits set in allocmask */
- __u64 xi_allocmask; /* mask of allocated inodes */
-} xfs_inogrp_t;
-
-
-/*
- * Error injection.
- */
-typedef struct xfs_error_injection {
- __s32 fd;
- __s32 errtag;
-} xfs_error_injection_t;
-
-
-/*
- * The user-level Handle Request interface structure.
- */
-typedef struct xfs_fsop_handlereq {
- __u32 fd; /* fd for FD_TO_HANDLE */
- void __user *path; /* user pathname */
- __u32 oflags; /* open flags */
- void __user *ihandle;/* user supplied handle */
- __u32 ihandlen; /* user supplied length */
- void __user *ohandle;/* user buffer for handle */
- __u32 __user *ohandlen;/* user buffer length */
-} xfs_fsop_handlereq_t;
-
-/*
- * Compound structures for passing args through Handle Request interfaces
- * xfs_fssetdm_by_handle, xfs_attrlist_by_handle, xfs_attrmulti_by_handle
- * - ioctls: XFS_IOC_FSSETDM_BY_HANDLE, XFS_IOC_ATTRLIST_BY_HANDLE, and
- * XFS_IOC_ATTRMULTI_BY_HANDLE
- */
-
-typedef struct xfs_fsop_setdm_handlereq {
- struct xfs_fsop_handlereq hreq; /* handle information */
- struct fsdmidata __user *data; /* DMAPI data */
-} xfs_fsop_setdm_handlereq_t;
-
-typedef struct xfs_attrlist_cursor {
- __u32 opaque[4];
-} xfs_attrlist_cursor_t;
-
-typedef struct xfs_fsop_attrlist_handlereq {
- struct xfs_fsop_handlereq hreq; /* handle interface structure */
- struct xfs_attrlist_cursor pos; /* opaque cookie, list offset */
- __u32 flags; /* which namespace to use */
- __u32 buflen; /* length of buffer supplied */
- void __user *buffer; /* returned names */
-} xfs_fsop_attrlist_handlereq_t;
-
-typedef struct xfs_attr_multiop {
- __u32 am_opcode;
- __s32 am_error;
- void __user *am_attrname;
- void __user *am_attrvalue;
- __u32 am_length;
- __u32 am_flags;
-} xfs_attr_multiop_t;
-
-typedef struct xfs_fsop_attrmulti_handlereq {
- struct xfs_fsop_handlereq hreq; /* handle interface structure */
- __u32 opcount;/* count of following multiop */
- struct xfs_attr_multiop __user *ops; /* attr_multi data */
-} xfs_fsop_attrmulti_handlereq_t;
-
-/*
- * per machine unique filesystem identifier types.
- */
-typedef struct { __u32 val[2]; } xfs_fsid_t; /* file system id type */
-
-
-#ifndef HAVE_FID
-#define MAXFIDSZ 46
-
-typedef struct fid {
- __u16 fid_len; /* length of data in bytes */
- unsigned char fid_data[MAXFIDSZ]; /* data (fid_len worth) */
-} fid_t;
-#endif
-
-typedef struct xfs_fid {
- __u16 xfs_fid_len; /* length of remainder */
- __u16 xfs_fid_pad;
- __u32 xfs_fid_gen; /* generation number */
- __u64 xfs_fid_ino; /* 64 bits inode number */
-} xfs_fid_t;
-
-typedef struct xfs_fid2 {
- __u16 fid_len; /* length of remainder */
- __u16 fid_pad; /* padding, must be zero */
- __u32 fid_gen; /* generation number */
- __u64 fid_ino; /* inode number */
-} xfs_fid2_t;
-
-typedef struct xfs_handle {
- union {
- __s64 align; /* force alignment of ha_fid */
- xfs_fsid_t _ha_fsid; /* unique file system identifier */
- } ha_u;
- xfs_fid_t ha_fid; /* file system specific file ID */
-} xfs_handle_t;
-#define ha_fsid ha_u._ha_fsid
-
-#define XFS_HSIZE(handle) (((char *) &(handle).ha_fid.xfs_fid_pad \
- - (char *) &(handle)) \
- + (handle).ha_fid.xfs_fid_len)
-
-#define XFS_HANDLE_CMP(h1, h2) memcmp(h1, h2, sizeof(xfs_handle_t))
-
-#define FSHSIZE sizeof(fsid_t)
-
-/*
- * Flags for going down operation
- */
-#define XFS_FSOP_GOING_FLAGS_DEFAULT 0x0 /* going down */
-#define XFS_FSOP_GOING_FLAGS_LOGFLUSH 0x1 /* flush log but not data */
-#define XFS_FSOP_GOING_FLAGS_NOLOGFLUSH 0x2 /* don't flush log nor data */
-
-/*
- * ioctl commands that are used by Linux filesystems
- */
-#define XFS_IOC_GETXFLAGS _IOR('f', 1, long)
-#define XFS_IOC_SETXFLAGS _IOW('f', 2, long)
-#define XFS_IOC_GETVERSION _IOR('v', 1, long)
-
-/*
- * ioctl commands that replace IRIX fcntl()'s
- * For 'documentation' purposed more than anything else,
- * the "cmd #" field reflects the IRIX fcntl number.
- */
-#define XFS_IOC_ALLOCSP _IOW ('X', 10, struct xfs_flock64)
-#define XFS_IOC_FREESP _IOW ('X', 11, struct xfs_flock64)
-#define XFS_IOC_DIOINFO _IOR ('X', 30, struct dioattr)
-#define XFS_IOC_FSGETXATTR _IOR ('X', 31, struct fsxattr)
-#define XFS_IOC_FSSETXATTR _IOW ('X', 32, struct fsxattr)
-#define XFS_IOC_ALLOCSP64 _IOW ('X', 36, struct xfs_flock64)
-#define XFS_IOC_FREESP64 _IOW ('X', 37, struct xfs_flock64)
-#define XFS_IOC_GETBMAP _IOWR('X', 38, struct getbmap)
-#define XFS_IOC_FSSETDM _IOW ('X', 39, struct fsdmidata)
-#define XFS_IOC_RESVSP _IOW ('X', 40, struct xfs_flock64)
-#define XFS_IOC_UNRESVSP _IOW ('X', 41, struct xfs_flock64)
-#define XFS_IOC_RESVSP64 _IOW ('X', 42, struct xfs_flock64)
-#define XFS_IOC_UNRESVSP64 _IOW ('X', 43, struct xfs_flock64)
-#define XFS_IOC_GETBMAPA _IOWR('X', 44, struct getbmap)
-#define XFS_IOC_FSGETXATTRA _IOR ('X', 45, struct fsxattr)
-/* XFS_IOC_SETBIOSIZE ---- deprecated 46 */
-/* XFS_IOC_GETBIOSIZE ---- deprecated 47 */
-//#define XFS_IOC_GETBMAPX _IOWR('X', 56, struct getbmapx)
-#define XFS_IOC_GETBMAPX _IOC(IOC_INOUT, 'X', 56, (256 * sizeof(struct getbmapx)))
-
-
-/*
- * ioctl commands that replace IRIX syssgi()'s
- */
-#define XFS_IOC_FSGEOMETRY_V1 _IOR ('X', 100, struct xfs_fsop_geom_v1)
-#define XFS_IOC_FSBULKSTAT _IOWR('X', 101, struct xfs_fsop_bulkreq)
-#define XFS_IOC_FSBULKSTAT_SINGLE _IOWR('X', 102, struct xfs_fsop_bulkreq)
-#define XFS_IOC_FSINUMBERS _IOWR('X', 103, struct xfs_fsop_bulkreq)
-#define XFS_IOC_PATH_TO_FSHANDLE _IOWR('X', 104, struct xfs_fsop_handlereq)
-#define XFS_IOC_PATH_TO_HANDLE _IOWR('X', 105, struct xfs_fsop_handlereq)
-#define XFS_IOC_FD_TO_HANDLE _IOWR('X', 106, struct xfs_fsop_handlereq)
-#define XFS_IOC_OPEN_BY_HANDLE _IOWR('X', 107, struct xfs_fsop_handlereq)
-#define XFS_IOC_READLINK_BY_HANDLE _IOWR('X', 108, struct xfs_fsop_handlereq)
-#define XFS_IOC_SWAPEXT _IOWR('X', 109, struct xfs_swapext)
-#define XFS_IOC_FSGROWFSDATA _IOW ('X', 110, struct xfs_growfs_data)
-#define XFS_IOC_FSGROWFSLOG _IOW ('X', 111, struct xfs_growfs_log)
-#define XFS_IOC_FSGROWFSRT _IOW ('X', 112, struct xfs_growfs_rt)
-#define XFS_IOC_FSCOUNTS _IOR ('X', 113, struct xfs_fsop_counts)
-#define XFS_IOC_SET_RESBLKS _IOWR('X', 114, struct xfs_fsop_resblks)
-#define XFS_IOC_GET_RESBLKS _IOR ('X', 115, struct xfs_fsop_resblks)
-#define XFS_IOC_ERROR_INJECTION _IOW ('X', 116, struct xfs_error_injection)
-#define XFS_IOC_ERROR_CLEARALL _IOW ('X', 117, struct xfs_error_injection)
-/* XFS_IOC_ATTRCTL_BY_HANDLE -- deprecated 118 */
-#define XFS_IOC_FREEZE _IOWR('X', 119, int)
-#define XFS_IOC_THAW _IOWR('X', 120, int)
-#define XFS_IOC_FSSETDM_BY_HANDLE _IOW ('X', 121, struct xfs_fsop_setdm_handlereq)
-#define XFS_IOC_ATTRLIST_BY_HANDLE _IOW ('X', 122, struct xfs_fsop_attrlist_handlereq)
-#define XFS_IOC_ATTRMULTI_BY_HANDLE _IOW ('X', 123, struct xfs_fsop_attrmulti_handlereq)
-#define XFS_IOC_FSGEOMETRY _IOR ('X', 124, struct xfs_fsop_geom)
-#define XFS_IOC_GOINGDOWN _IOR ('X', 125, __uint32_t)
-/* XFS_IOC_GETFSUUID ---------- deprecated 140 */
-
-
-#ifndef HAVE_BBMACROS
-/*
- * Block I/O parameterization. A basic block (BB) is the lowest size of
- * filesystem allocation, and must equal 512. Length units given to bio
- * routines are in BB's.
- */
-#define BBSHIFT 9
-#define BBSIZE (1<<BBSHIFT)
-#define BBMASK (BBSIZE-1)
-#define BTOBB(bytes) (((__u64)(bytes) + BBSIZE - 1) >> BBSHIFT)
-#define BTOBBT(bytes) ((__u64)(bytes) >> BBSHIFT)
-#define BBTOB(bbs) ((bbs) << BBSHIFT)
-#endif
-
-#endif /* __XFS_FS_H__ */
-
diff --git a/sys/gnu/fs/xfs/xfs_fsops.c b/sys/gnu/fs/xfs/xfs_fsops.c
deleted file mode 100644
index 87341a5..0000000
--- a/sys/gnu/fs/xfs/xfs_fsops.c
+++ /dev/null
@@ -1,599 +0,0 @@
-/*
- * Copyright (c) 2000-2005 Silicon Graphics, Inc.
- * All Rights Reserved.
- *
- * 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.
- *
- * This program is distributed in the hope that it would 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 the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- */
-#include "xfs.h"
-#include "xfs_fs.h"
-#include "xfs_types.h"
-#include "xfs_bit.h"
-#include "xfs_inum.h"
-#include "xfs_log.h"
-#include "xfs_trans.h"
-#include "xfs_sb.h"
-#include "xfs_ag.h"
-#include "xfs_dir.h"
-#include "xfs_dir2.h"
-#include "xfs_dmapi.h"
-#include "xfs_mount.h"
-#include "xfs_bmap_btree.h"
-#include "xfs_alloc_btree.h"
-#include "xfs_ialloc_btree.h"
-#include "xfs_dir_sf.h"
-#include "xfs_dir2_sf.h"
-#include "xfs_attr_sf.h"
-#include "xfs_dinode.h"
-#include "xfs_inode.h"
-#include "xfs_inode_item.h"
-#include "xfs_btree.h"
-#include "xfs_error.h"
-#include "xfs_alloc.h"
-#include "xfs_ialloc.h"
-#include "xfs_fsops.h"
-#include "xfs_itable.h"
-#include "xfs_trans_space.h"
-#include "xfs_rtalloc.h"
-#include "xfs_rw.h"
-
-/*
- * File system operations
- */
-
-int
-xfs_fs_geometry(
- xfs_mount_t *mp,
- xfs_fsop_geom_t *geo,
- int new_version)
-{
- geo->blocksize = mp->m_sb.sb_blocksize;
- geo->rtextsize = mp->m_sb.sb_rextsize;
- geo->agblocks = mp->m_sb.sb_agblocks;
- geo->agcount = mp->m_sb.sb_agcount;
- geo->logblocks = mp->m_sb.sb_logblocks;
- geo->sectsize = mp->m_sb.sb_sectsize;
- geo->inodesize = mp->m_sb.sb_inodesize;
- geo->imaxpct = mp->m_sb.sb_imax_pct;
- geo->datablocks = mp->m_sb.sb_dblocks;
- geo->rtblocks = mp->m_sb.sb_rblocks;
- geo->rtextents = mp->m_sb.sb_rextents;
- geo->logstart = mp->m_sb.sb_logstart;
- ASSERT(sizeof(geo->uuid)==sizeof(mp->m_sb.sb_uuid));
- memcpy(geo->uuid, &mp->m_sb.sb_uuid, sizeof(mp->m_sb.sb_uuid));
- if (new_version >= 2) {
- geo->sunit = mp->m_sb.sb_unit;
- geo->swidth = mp->m_sb.sb_width;
- }
- if (new_version >= 3) {
- geo->version = XFS_FSOP_GEOM_VERSION;
- geo->flags =
- (XFS_SB_VERSION_HASATTR(&mp->m_sb) ?
- XFS_FSOP_GEOM_FLAGS_ATTR : 0) |
- (XFS_SB_VERSION_HASNLINK(&mp->m_sb) ?
- XFS_FSOP_GEOM_FLAGS_NLINK : 0) |
- (XFS_SB_VERSION_HASQUOTA(&mp->m_sb) ?
- XFS_FSOP_GEOM_FLAGS_QUOTA : 0) |
- (XFS_SB_VERSION_HASALIGN(&mp->m_sb) ?
- XFS_FSOP_GEOM_FLAGS_IALIGN : 0) |
- (XFS_SB_VERSION_HASDALIGN(&mp->m_sb) ?
- XFS_FSOP_GEOM_FLAGS_DALIGN : 0) |
- (XFS_SB_VERSION_HASSHARED(&mp->m_sb) ?
- XFS_FSOP_GEOM_FLAGS_SHARED : 0) |
- (XFS_SB_VERSION_HASEXTFLGBIT(&mp->m_sb) ?
- XFS_FSOP_GEOM_FLAGS_EXTFLG : 0) |
- (XFS_SB_VERSION_HASDIRV2(&mp->m_sb) ?
- XFS_FSOP_GEOM_FLAGS_DIRV2 : 0) |
- (XFS_SB_VERSION_HASSECTOR(&mp->m_sb) ?
- XFS_FSOP_GEOM_FLAGS_SECTOR : 0) |
- (XFS_SB_VERSION_HASATTR2(&mp->m_sb) ?
- XFS_FSOP_GEOM_FLAGS_ATTR2 : 0);
- geo->logsectsize = XFS_SB_VERSION_HASSECTOR(&mp->m_sb) ?
- mp->m_sb.sb_logsectsize : BBSIZE;
- geo->rtsectsize = mp->m_sb.sb_blocksize;
- geo->dirblocksize = mp->m_dirblksize;
- }
- if (new_version >= 4) {
- geo->flags |=
- (XFS_SB_VERSION_HASLOGV2(&mp->m_sb) ?
- XFS_FSOP_GEOM_FLAGS_LOGV2 : 0);
- geo->logsunit = mp->m_sb.sb_logsunit;
- }
- return 0;
-}
-
-static int
-xfs_growfs_data_private(
- xfs_mount_t *mp, /* mount point for filesystem */
- xfs_growfs_data_t *in) /* growfs data input struct */
-{
- xfs_agf_t *agf;
- xfs_agi_t *agi;
- xfs_agnumber_t agno;
- xfs_extlen_t agsize;
- xfs_extlen_t tmpsize;
- xfs_alloc_rec_t *arec;
- xfs_btree_sblock_t *block;
- xfs_buf_t *bp;
- int bucket;
- int dpct;
- int error;
- xfs_agnumber_t nagcount;
- xfs_agnumber_t nagimax = 0;
- xfs_rfsblock_t nb, nb_mod;
- xfs_rfsblock_t new;
- xfs_rfsblock_t nfree;
- xfs_agnumber_t oagcount;
- int pct;
- xfs_sb_t *sbp;
- xfs_trans_t *tp;
-
- nb = in->newblocks;
- pct = in->imaxpct;
- if (nb < mp->m_sb.sb_dblocks || pct < 0 || pct > 100)
- return XFS_ERROR(EINVAL);
- dpct = pct - mp->m_sb.sb_imax_pct;
- error = xfs_read_buf(mp, mp->m_ddev_targp,
- XFS_FSB_TO_BB(mp, nb) - XFS_FSS_TO_BB(mp, 1),
- XFS_FSS_TO_BB(mp, 1), 0, &bp);
- if (error)
- return error;
- ASSERT(bp);
- xfs_buf_relse(bp);
-
- new = nb; /* use new as a temporary here */
- nb_mod = do_div(new, mp->m_sb.sb_agblocks);
- nagcount = new + (nb_mod != 0);
- if (nb_mod && nb_mod < XFS_MIN_AG_BLOCKS) {
- nagcount--;
- nb = nagcount * mp->m_sb.sb_agblocks;
- if (nb < mp->m_sb.sb_dblocks)
- return XFS_ERROR(EINVAL);
- }
- new = nb - mp->m_sb.sb_dblocks;
- oagcount = mp->m_sb.sb_agcount;
- if (nagcount > oagcount) {
- down_write(&mp->m_peraglock);
- mp->m_perag = kmem_realloc(mp->m_perag,
- sizeof(xfs_perag_t) * nagcount,
- sizeof(xfs_perag_t) * oagcount,
- KM_SLEEP);
- memset(&mp->m_perag[oagcount], 0,
- (nagcount - oagcount) * sizeof(xfs_perag_t));
- mp->m_flags |= XFS_MOUNT_32BITINODES;
- nagimax = xfs_initialize_perag(XFS_MTOVFS(mp), mp, nagcount);
- up_write(&mp->m_peraglock);
- }
- tp = xfs_trans_alloc(mp, XFS_TRANS_GROWFS);
- if ((error = xfs_trans_reserve(tp, XFS_GROWFS_SPACE_RES(mp),
- XFS_GROWDATA_LOG_RES(mp), 0, 0, 0))) {
- xfs_trans_cancel(tp, 0);
- return error;
- }
-
- nfree = 0;
- for (agno = nagcount - 1; agno >= oagcount; agno--, new -= agsize) {
- /*
- * AG freelist header block
- */
- bp = xfs_buf_get(mp->m_ddev_targp,
- XFS_AG_DADDR(mp, agno, XFS_AGF_DADDR(mp)),
- XFS_FSS_TO_BB(mp, 1), 0);
- agf = XFS_BUF_TO_AGF(bp);
- memset(agf, 0, mp->m_sb.sb_sectsize);
- agf->agf_magicnum = cpu_to_be32(XFS_AGF_MAGIC);
- agf->agf_versionnum = cpu_to_be32(XFS_AGF_VERSION);
- agf->agf_seqno = cpu_to_be32(agno);
- if (agno == nagcount - 1)
- agsize =
- nb -
- (agno * (xfs_rfsblock_t)mp->m_sb.sb_agblocks);
- else
- agsize = mp->m_sb.sb_agblocks;
- agf->agf_length = cpu_to_be32(agsize);
- agf->agf_roots[XFS_BTNUM_BNOi] = cpu_to_be32(XFS_BNO_BLOCK(mp));
- agf->agf_roots[XFS_BTNUM_CNTi] = cpu_to_be32(XFS_CNT_BLOCK(mp));
- agf->agf_levels[XFS_BTNUM_BNOi] = cpu_to_be32(1);
- agf->agf_levels[XFS_BTNUM_CNTi] = cpu_to_be32(1);
- agf->agf_flfirst = 0;
- agf->agf_fllast = cpu_to_be32(XFS_AGFL_SIZE(mp) - 1);
- agf->agf_flcount = 0;
- tmpsize = agsize - XFS_PREALLOC_BLOCKS(mp);
- agf->agf_freeblks = cpu_to_be32(tmpsize);
- agf->agf_longest = cpu_to_be32(tmpsize);
- error = xfs_bwrite(mp, bp);
- if (error) {
- goto error0;
- }
- /*
- * AG inode header block
- */
- bp = xfs_buf_get(mp->m_ddev_targp,
- XFS_AG_DADDR(mp, agno, XFS_AGI_DADDR(mp)),
- XFS_FSS_TO_BB(mp, 1), 0);
- agi = XFS_BUF_TO_AGI(bp);
- memset(agi, 0, mp->m_sb.sb_sectsize);
- agi->agi_magicnum = cpu_to_be32(XFS_AGI_MAGIC);
- agi->agi_versionnum = cpu_to_be32(XFS_AGI_VERSION);
- agi->agi_seqno = cpu_to_be32(agno);
- agi->agi_length = cpu_to_be32(agsize);
- agi->agi_count = 0;
- agi->agi_root = cpu_to_be32(XFS_IBT_BLOCK(mp));
- agi->agi_level = cpu_to_be32(1);
- agi->agi_freecount = 0;
- agi->agi_newino = cpu_to_be32(NULLAGINO);
- agi->agi_dirino = cpu_to_be32(NULLAGINO);
- for (bucket = 0; bucket < XFS_AGI_UNLINKED_BUCKETS; bucket++)
- agi->agi_unlinked[bucket] = cpu_to_be32(NULLAGINO);
- error = xfs_bwrite(mp, bp);
- if (error) {
- goto error0;
- }
- /*
- * BNO btree root block
- */
- bp = xfs_buf_get(mp->m_ddev_targp,
- XFS_AGB_TO_DADDR(mp, agno, XFS_BNO_BLOCK(mp)),
- BTOBB(mp->m_sb.sb_blocksize), 0);
- block = XFS_BUF_TO_SBLOCK(bp);
- memset(block, 0, mp->m_sb.sb_blocksize);
- block->bb_magic = cpu_to_be32(XFS_ABTB_MAGIC);
- block->bb_level = 0;
- block->bb_numrecs = cpu_to_be16(1);
- block->bb_leftsib = cpu_to_be32(NULLAGBLOCK);
- block->bb_rightsib = cpu_to_be32(NULLAGBLOCK);
- arec = XFS_BTREE_REC_ADDR(mp->m_sb.sb_blocksize, xfs_alloc,
- block, 1, mp->m_alloc_mxr[0]);
- arec->ar_startblock = cpu_to_be32(XFS_PREALLOC_BLOCKS(mp));
- arec->ar_blockcount = cpu_to_be32(
- agsize - be32_to_cpu(arec->ar_startblock));
- error = xfs_bwrite(mp, bp);
- if (error) {
- goto error0;
- }
- /*
- * CNT btree root block
- */
- bp = xfs_buf_get(mp->m_ddev_targp,
- XFS_AGB_TO_DADDR(mp, agno, XFS_CNT_BLOCK(mp)),
- BTOBB(mp->m_sb.sb_blocksize), 0);
- block = XFS_BUF_TO_SBLOCK(bp);
- memset(block, 0, mp->m_sb.sb_blocksize);
- block->bb_magic = cpu_to_be32(XFS_ABTC_MAGIC);
- block->bb_level = 0;
- block->bb_numrecs = cpu_to_be16(1);
- block->bb_leftsib = cpu_to_be32(NULLAGBLOCK);
- block->bb_rightsib = cpu_to_be32(NULLAGBLOCK);
- arec = XFS_BTREE_REC_ADDR(mp->m_sb.sb_blocksize, xfs_alloc,
- block, 1, mp->m_alloc_mxr[0]);
- arec->ar_startblock = cpu_to_be32(XFS_PREALLOC_BLOCKS(mp));
- arec->ar_blockcount = cpu_to_be32(
- agsize - be32_to_cpu(arec->ar_startblock));
- nfree += be32_to_cpu(arec->ar_blockcount);
- error = xfs_bwrite(mp, bp);
- if (error) {
- goto error0;
- }
- /*
- * INO btree root block
- */
- bp = xfs_buf_get(mp->m_ddev_targp,
- XFS_AGB_TO_DADDR(mp, agno, XFS_IBT_BLOCK(mp)),
- BTOBB(mp->m_sb.sb_blocksize), 0);
- block = XFS_BUF_TO_SBLOCK(bp);
- memset(block, 0, mp->m_sb.sb_blocksize);
- block->bb_magic = cpu_to_be32(XFS_IBT_MAGIC);
- block->bb_level = 0;
- block->bb_numrecs = 0;
- block->bb_leftsib = cpu_to_be32(NULLAGBLOCK);
- block->bb_rightsib = cpu_to_be32(NULLAGBLOCK);
- error = xfs_bwrite(mp, bp);
- if (error) {
- goto error0;
- }
- }
- xfs_trans_agblocks_delta(tp, nfree);
- /*
- * There are new blocks in the old last a.g.
- */
- if (new) {
- /*
- * Change the agi length.
- */
- error = xfs_ialloc_read_agi(mp, tp, agno, &bp);
- if (error) {
- goto error0;
- }
- ASSERT(bp);
- agi = XFS_BUF_TO_AGI(bp);
- be32_add(&agi->agi_length, new);
- ASSERT(nagcount == oagcount ||
- be32_to_cpu(agi->agi_length) == mp->m_sb.sb_agblocks);
- xfs_ialloc_log_agi(tp, bp, XFS_AGI_LENGTH);
- /*
- * Change agf length.
- */
- error = xfs_alloc_read_agf(mp, tp, agno, 0, &bp);
- if (error) {
- goto error0;
- }
- ASSERT(bp);
- agf = XFS_BUF_TO_AGF(bp);
- be32_add(&agf->agf_length, new);
- ASSERT(be32_to_cpu(agf->agf_length) ==
- be32_to_cpu(agi->agi_length));
- /*
- * Free the new space.
- */
- error = xfs_free_extent(tp, XFS_AGB_TO_FSB(mp, agno,
- be32_to_cpu(agf->agf_length) - new), new);
- if (error) {
- goto error0;
- }
- }
- if (nagcount > oagcount)
- xfs_trans_mod_sb(tp, XFS_TRANS_SB_AGCOUNT, nagcount - oagcount);
- if (nb > mp->m_sb.sb_dblocks)
- xfs_trans_mod_sb(tp, XFS_TRANS_SB_DBLOCKS,
- nb - mp->m_sb.sb_dblocks);
- if (nfree)
- xfs_trans_mod_sb(tp, XFS_TRANS_SB_FDBLOCKS, nfree);
- if (dpct)
- xfs_trans_mod_sb(tp, XFS_TRANS_SB_IMAXPCT, dpct);
- error = xfs_trans_commit(tp, 0, NULL);
- if (error) {
- return error;
- }
- /* New allocation groups fully initialized, so update mount struct */
- if (nagimax)
- mp->m_maxagi = nagimax;
- if (mp->m_sb.sb_imax_pct) {
- __uint64_t icount = mp->m_sb.sb_dblocks * mp->m_sb.sb_imax_pct;
- do_div(icount, 100);
- mp->m_maxicount = icount << mp->m_sb.sb_inopblog;
- } else
- mp->m_maxicount = 0;
- for (agno = 1; agno < nagcount; agno++) {
- error = xfs_read_buf(mp, mp->m_ddev_targp,
- XFS_AGB_TO_DADDR(mp, agno, XFS_SB_BLOCK(mp)),
- XFS_FSS_TO_BB(mp, 1), 0, &bp);
- if (error) {
- xfs_fs_cmn_err(CE_WARN, mp,
- "error %d reading secondary superblock for ag %d",
- error, agno);
- break;
- }
- sbp = XFS_BUF_TO_SBP(bp);
- xfs_xlatesb(sbp, &mp->m_sb, -1, XFS_SB_ALL_BITS);
- /*
- * If we get an error writing out the alternate superblocks,
- * just issue a warning and continue. The real work is
- * already done and committed.
- */
- if (!(error = xfs_bwrite(mp, bp))) {
- continue;
- } else {
- xfs_fs_cmn_err(CE_WARN, mp,
- "write error %d updating secondary superblock for ag %d",
- error, agno);
- break; /* no point in continuing */
- }
- }
- return 0;
-
- error0:
- xfs_trans_cancel(tp, XFS_TRANS_ABORT);
- return error;
-}
-
-static int
-xfs_growfs_log_private(
- xfs_mount_t *mp, /* mount point for filesystem */
- xfs_growfs_log_t *in) /* growfs log input struct */
-{
- xfs_extlen_t nb;
-
- nb = in->newblocks;
- if (nb < XFS_MIN_LOG_BLOCKS || nb < XFS_B_TO_FSB(mp, XFS_MIN_LOG_BYTES))
- return XFS_ERROR(EINVAL);
- if (nb == mp->m_sb.sb_logblocks &&
- in->isint == (mp->m_sb.sb_logstart != 0))
- return XFS_ERROR(EINVAL);
- /*
- * Moving the log is hard, need new interfaces to sync
- * the log first, hold off all activity while moving it.
- * Can have shorter or longer log in the same space,
- * or transform internal to external log or vice versa.
- */
- return XFS_ERROR(ENOSYS);
-}
-
-/*
- * protected versions of growfs function acquire and release locks on the mount
- * point - exported through ioctls: XFS_IOC_FSGROWFSDATA, XFS_IOC_FSGROWFSLOG,
- * XFS_IOC_FSGROWFSRT
- */
-
-
-int
-xfs_growfs_data(
- xfs_mount_t *mp,
- xfs_growfs_data_t *in)
-{
- int error;
- if (!cpsema(&mp->m_growlock))
- return XFS_ERROR(EWOULDBLOCK);
- error = xfs_growfs_data_private(mp, in);
- vsema(&mp->m_growlock);
- return error;
-}
-
-int
-xfs_growfs_log(
- xfs_mount_t *mp,
- xfs_growfs_log_t *in)
-{
- int error;
- if (!cpsema(&mp->m_growlock))
- return XFS_ERROR(EWOULDBLOCK);
- error = xfs_growfs_log_private(mp, in);
- vsema(&mp->m_growlock);
- return error;
-}
-
-/*
- * exported through ioctl XFS_IOC_FSCOUNTS
- */
-
-int
-xfs_fs_counts(
- xfs_mount_t *mp,
- xfs_fsop_counts_t *cnt)
-{
- unsigned long s;
-
- xfs_icsb_sync_counters_lazy(mp);
- s = XFS_SB_LOCK(mp);
- cnt->freedata = mp->m_sb.sb_fdblocks;
- cnt->freertx = mp->m_sb.sb_frextents;
- cnt->freeino = mp->m_sb.sb_ifree;
- cnt->allocino = mp->m_sb.sb_icount;
- XFS_SB_UNLOCK(mp, s);
- return 0;
-}
-
-/*
- * exported through ioctl XFS_IOC_SET_RESBLKS & XFS_IOC_GET_RESBLKS
- *
- * xfs_reserve_blocks is called to set m_resblks
- * in the in-core mount table. The number of unused reserved blocks
- * is kept in m_resblks_avail.
- *
- * Reserve the requested number of blocks if available. Otherwise return
- * as many as possible to satisfy the request. The actual number
- * reserved are returned in outval
- *
- * A null inval pointer indicates that only the current reserved blocks
- * available should be returned no settings are changed.
- */
-
-int
-xfs_reserve_blocks(
- xfs_mount_t *mp,
- __uint64_t *inval,
- xfs_fsop_resblks_t *outval)
-{
- __int64_t lcounter, delta;
- __uint64_t request;
- unsigned long s;
-
- /* If inval is null, report current values and return */
-
- if (inval == (__uint64_t *)NULL) {
- outval->resblks = mp->m_resblks;
- outval->resblks_avail = mp->m_resblks_avail;
- return 0;
- }
-
- request = *inval;
- s = XFS_SB_LOCK(mp);
-
- /*
- * If our previous reservation was larger than the current value,
- * then move any unused blocks back to the free pool.
- */
-
- if (mp->m_resblks > request) {
- lcounter = mp->m_resblks_avail - request;
- if (lcounter > 0) { /* release unused blocks */
- mp->m_sb.sb_fdblocks += lcounter;
- mp->m_resblks_avail -= lcounter;
- }
- mp->m_resblks = request;
- } else {
- delta = request - mp->m_resblks;
- lcounter = mp->m_sb.sb_fdblocks - delta;
- if (lcounter < 0) {
- /* We can't satisfy the request, just get what we can */
- mp->m_resblks += mp->m_sb.sb_fdblocks;
- mp->m_resblks_avail += mp->m_sb.sb_fdblocks;
- mp->m_sb.sb_fdblocks = 0;
- } else {
- mp->m_sb.sb_fdblocks = lcounter;
- mp->m_resblks = request;
- mp->m_resblks_avail += delta;
- }
- }
-
- outval->resblks = mp->m_resblks;
- outval->resblks_avail = mp->m_resblks_avail;
- XFS_SB_UNLOCK(mp, s);
- return 0;
-}
-
-void
-xfs_fs_log_dummy(xfs_mount_t *mp)
-{
- xfs_trans_t *tp;
- xfs_inode_t *ip;
-
-
- tp = _xfs_trans_alloc(mp, XFS_TRANS_DUMMY1);
- atomic_inc(&mp->m_active_trans);
- if (xfs_trans_reserve(tp, 0, XFS_ICHANGE_LOG_RES(mp), 0, 0, 0)) {
- xfs_trans_cancel(tp, 0);
- return;
- }
-
- ip = mp->m_rootip;
- xfs_ilock(ip, XFS_ILOCK_EXCL);
-
- xfs_trans_ijoin(tp, ip, XFS_ILOCK_EXCL);
- xfs_trans_ihold(tp, ip);
- xfs_trans_log_inode(tp, ip, XFS_ILOG_CORE);
- xfs_trans_set_sync(tp);
- xfs_trans_commit(tp, 0, NULL);
-
- xfs_iunlock(ip, XFS_ILOCK_EXCL);
-}
-
-int
-xfs_fs_goingdown(
- xfs_mount_t *mp,
- __uint32_t inflags)
-{
- switch (inflags) {
- case XFS_FSOP_GOING_FLAGS_DEFAULT: {
-#ifdef RMC
- struct xfs_vfs *vfsp = XFS_MTOVFS(mp);
- struct super_block *sb = freeze_bdev(vfsp->vfs_super->s_bdev);
-
- if (sb && !IS_ERR(sb)) {
- xfs_force_shutdown(mp, XFS_FORCE_UMOUNT);
- thaw_bdev(sb->s_bdev, sb);
- }
-#endif
- break;
- }
- case XFS_FSOP_GOING_FLAGS_LOGFLUSH:
- xfs_force_shutdown(mp, XFS_FORCE_UMOUNT);
- break;
- case XFS_FSOP_GOING_FLAGS_NOLOGFLUSH:
- xfs_force_shutdown(mp, XFS_FORCE_UMOUNT|XFS_LOG_IO_ERROR);
- break;
- default:
- return XFS_ERROR(EINVAL);
- }
-
- return 0;
-}
diff --git a/sys/gnu/fs/xfs/xfs_fsops.h b/sys/gnu/fs/xfs/xfs_fsops.h
deleted file mode 100644
index 300d0c9..0000000
--- a/sys/gnu/fs/xfs/xfs_fsops.h
+++ /dev/null
@@ -1,30 +0,0 @@
-/*
- * Copyright (c) 2000-2001,2005 Silicon Graphics, Inc.
- * All Rights Reserved.
- *
- * 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.
- *
- * This program is distributed in the hope that it would 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 the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- */
-#ifndef __XFS_FSOPS_H__
-#define __XFS_FSOPS_H__
-
-extern int xfs_fs_geometry(xfs_mount_t *mp, xfs_fsop_geom_t *geo, int nversion);
-extern int xfs_growfs_data(xfs_mount_t *mp, xfs_growfs_data_t *in);
-extern int xfs_growfs_log(xfs_mount_t *mp, xfs_growfs_log_t *in);
-extern int xfs_fs_counts(xfs_mount_t *mp, xfs_fsop_counts_t *cnt);
-extern int xfs_reserve_blocks(xfs_mount_t *mp, __uint64_t *inval,
- xfs_fsop_resblks_t *outval);
-extern int xfs_fs_goingdown(xfs_mount_t *mp, __uint32_t inflags);
-extern void xfs_fs_log_dummy(xfs_mount_t *mp);
-
-#endif /* __XFS_FSOPS_H__ */
diff --git a/sys/gnu/fs/xfs/xfs_ialloc.c b/sys/gnu/fs/xfs/xfs_ialloc.c
deleted file mode 100644
index af1a240..0000000
--- a/sys/gnu/fs/xfs/xfs_ialloc.c
+++ /dev/null
@@ -1,1411 +0,0 @@
-/*
- * Copyright (c) 2000-2002,2005 Silicon Graphics, Inc.
- * All Rights Reserved.
- *
- * 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.
- *
- * This program is distributed in the hope that it would 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 the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- */
-#include "xfs.h"
-#include "xfs_fs.h"
-#include "xfs_types.h"
-#include "xfs_bit.h"
-#include "xfs_log.h"
-#include "xfs_inum.h"
-#include "xfs_trans.h"
-#include "xfs_sb.h"
-#include "xfs_ag.h"
-#include "xfs_dir.h"
-#include "xfs_dir2.h"
-#include "xfs_dmapi.h"
-#include "xfs_mount.h"
-#include "xfs_bmap_btree.h"
-#include "xfs_alloc_btree.h"
-#include "xfs_ialloc_btree.h"
-#include "xfs_dir_sf.h"
-#include "xfs_dir2_sf.h"
-#include "xfs_attr_sf.h"
-#include "xfs_dinode.h"
-#include "xfs_inode.h"
-#include "xfs_btree.h"
-#include "xfs_ialloc.h"
-#include "xfs_alloc.h"
-#include "xfs_rtalloc.h"
-#include "xfs_error.h"
-#include "xfs_bmap.h"
-
-/*
- * Log specified fields for the inode given by bp and off.
- */
-STATIC void
-xfs_ialloc_log_di(
- xfs_trans_t *tp, /* transaction pointer */
- xfs_buf_t *bp, /* inode buffer */
- int off, /* index of inode in buffer */
- int fields) /* bitmask of fields to log */
-{
- int first; /* first byte number */
- int ioffset; /* off in bytes */
- int last; /* last byte number */
- xfs_mount_t *mp; /* mount point structure */
- static const short offsets[] = { /* field offsets */
- /* keep in sync with bits */
- offsetof(xfs_dinode_core_t, di_magic),
- offsetof(xfs_dinode_core_t, di_mode),
- offsetof(xfs_dinode_core_t, di_version),
- offsetof(xfs_dinode_core_t, di_format),
- offsetof(xfs_dinode_core_t, di_onlink),
- offsetof(xfs_dinode_core_t, di_uid),
- offsetof(xfs_dinode_core_t, di_gid),
- offsetof(xfs_dinode_core_t, di_nlink),
- offsetof(xfs_dinode_core_t, di_projid),
- offsetof(xfs_dinode_core_t, di_pad),
- offsetof(xfs_dinode_core_t, di_atime),
- offsetof(xfs_dinode_core_t, di_mtime),
- offsetof(xfs_dinode_core_t, di_ctime),
- offsetof(xfs_dinode_core_t, di_size),
- offsetof(xfs_dinode_core_t, di_nblocks),
- offsetof(xfs_dinode_core_t, di_extsize),
- offsetof(xfs_dinode_core_t, di_nextents),
- offsetof(xfs_dinode_core_t, di_anextents),
- offsetof(xfs_dinode_core_t, di_forkoff),
- offsetof(xfs_dinode_core_t, di_aformat),
- offsetof(xfs_dinode_core_t, di_dmevmask),
- offsetof(xfs_dinode_core_t, di_dmstate),
- offsetof(xfs_dinode_core_t, di_flags),
- offsetof(xfs_dinode_core_t, di_gen),
- offsetof(xfs_dinode_t, di_next_unlinked),
- offsetof(xfs_dinode_t, di_u),
- offsetof(xfs_dinode_t, di_a),
- sizeof(xfs_dinode_t)
- };
-
-
- ASSERT(offsetof(xfs_dinode_t, di_core) == 0);
- ASSERT((fields & (XFS_DI_U|XFS_DI_A)) == 0);
- mp = tp->t_mountp;
- /*
- * Get the inode-relative first and last bytes for these fields
- */
- xfs_btree_offsets(fields, offsets, XFS_DI_NUM_BITS, &first, &last);
- /*
- * Convert to buffer offsets and log it.
- */
- ioffset = off << mp->m_sb.sb_inodelog;
- first += ioffset;
- last += ioffset;
- xfs_trans_log_buf(tp, bp, first, last);
-}
-
-/*
- * Allocation group level functions.
- */
-
-/*
- * Allocate new inodes in the allocation group specified by agbp.
- * Return 0 for success, else error code.
- */
-STATIC int /* error code or 0 */
-xfs_ialloc_ag_alloc(
- xfs_trans_t *tp, /* transaction pointer */
- xfs_buf_t *agbp, /* alloc group buffer */
- int *alloc)
-{
- xfs_agi_t *agi; /* allocation group header */
- xfs_alloc_arg_t args; /* allocation argument structure */
- int blks_per_cluster; /* fs blocks per inode cluster */
- xfs_btree_cur_t *cur; /* inode btree cursor */
- xfs_daddr_t d; /* disk addr of buffer */
- int error;
- xfs_buf_t *fbuf; /* new free inodes' buffer */
- xfs_dinode_t *free; /* new free inode structure */
- int i; /* inode counter */
- int j; /* block counter */
- int nbufs; /* num bufs of new inodes */
- xfs_agino_t newino; /* new first inode's number */
- xfs_agino_t newlen; /* new number of inodes */
- int ninodes; /* num inodes per buf */
- xfs_agino_t thisino; /* current inode number, for loop */
- int version; /* inode version number to use */
- int isaligned = 0; /* inode allocation at stripe unit */
- /* boundary */
-
- args.tp = tp;
- args.mp = tp->t_mountp;
-
- /*
- * Locking will ensure that we don't have two callers in here
- * at one time.
- */
- newlen = XFS_IALLOC_INODES(args.mp);
- if (args.mp->m_maxicount &&
- args.mp->m_sb.sb_icount + newlen > args.mp->m_maxicount)
- return XFS_ERROR(ENOSPC);
- args.minlen = args.maxlen = XFS_IALLOC_BLOCKS(args.mp);
- /*
- * First try to allocate inodes contiguous with the last-allocated
- * chunk of inodes. If the filesystem is striped, this will fill
- * an entire stripe unit with inodes.
- */
- agi = XFS_BUF_TO_AGI(agbp);
- newino = be32_to_cpu(agi->agi_newino);
- args.agbno = XFS_AGINO_TO_AGBNO(args.mp, newino) +
- XFS_IALLOC_BLOCKS(args.mp);
- if (likely(newino != NULLAGINO &&
- (args.agbno < be32_to_cpu(agi->agi_length)))) {
- args.fsbno = XFS_AGB_TO_FSB(args.mp,
- be32_to_cpu(agi->agi_seqno), args.agbno);
- args.type = XFS_ALLOCTYPE_THIS_BNO;
- args.mod = args.total = args.wasdel = args.isfl =
- args.userdata = args.minalignslop = 0;
- args.prod = 1;
- args.alignment = 1;
- /*
- * Allow space for the inode btree to split.
- */
- args.minleft = XFS_IN_MAXLEVELS(args.mp) - 1;
- if ((error = xfs_alloc_vextent(&args)))
- return error;
- } else
- args.fsbno = NULLFSBLOCK;
-
- if (unlikely(args.fsbno == NULLFSBLOCK)) {
- /*
- * Set the alignment for the allocation.
- * If stripe alignment is turned on then align at stripe unit
- * boundary.
- * If the cluster size is smaller than a filesystem block
- * then we're doing I/O for inodes in filesystem block size
- * pieces, so don't need alignment anyway.
- */
- isaligned = 0;
- if (args.mp->m_sinoalign) {
- ASSERT(!(args.mp->m_flags & XFS_MOUNT_NOALIGN));
- args.alignment = args.mp->m_dalign;
- isaligned = 1;
- } else if (XFS_SB_VERSION_HASALIGN(&args.mp->m_sb) &&
- args.mp->m_sb.sb_inoalignmt >=
- XFS_B_TO_FSBT(args.mp,
- XFS_INODE_CLUSTER_SIZE(args.mp)))
- args.alignment = args.mp->m_sb.sb_inoalignmt;
- else
- args.alignment = 1;
- /*
- * Need to figure out where to allocate the inode blocks.
- * Ideally they should be spaced out through the a.g.
- * For now, just allocate blocks up front.
- */
- args.agbno = be32_to_cpu(agi->agi_root);
- args.fsbno = XFS_AGB_TO_FSB(args.mp,
- be32_to_cpu(agi->agi_seqno), args.agbno);
- /*
- * Allocate a fixed-size extent of inodes.
- */
- args.type = XFS_ALLOCTYPE_NEAR_BNO;
- args.mod = args.total = args.wasdel = args.isfl =
- args.userdata = args.minalignslop = 0;
- args.prod = 1;
- /*
- * Allow space for the inode btree to split.
- */
- args.minleft = XFS_IN_MAXLEVELS(args.mp) - 1;
- if ((error = xfs_alloc_vextent(&args)))
- return error;
- }
-
- /*
- * If stripe alignment is turned on, then try again with cluster
- * alignment.
- */
- if (isaligned && args.fsbno == NULLFSBLOCK) {
- args.type = XFS_ALLOCTYPE_NEAR_BNO;
- args.agbno = be32_to_cpu(agi->agi_root);
- args.fsbno = XFS_AGB_TO_FSB(args.mp,
- be32_to_cpu(agi->agi_seqno), args.agbno);
- if (XFS_SB_VERSION_HASALIGN(&args.mp->m_sb) &&
- args.mp->m_sb.sb_inoalignmt >=
- XFS_B_TO_FSBT(args.mp, XFS_INODE_CLUSTER_SIZE(args.mp)))
- args.alignment = args.mp->m_sb.sb_inoalignmt;
- else
- args.alignment = 1;
- if ((error = xfs_alloc_vextent(&args)))
- return error;
- }
-
- if (args.fsbno == NULLFSBLOCK) {
- *alloc = 0;
- return 0;
- }
- ASSERT(args.len == args.minlen);
- /*
- * Convert the results.
- */
- newino = XFS_OFFBNO_TO_AGINO(args.mp, args.agbno, 0);
- /*
- * Loop over the new block(s), filling in the inodes.
- * For small block sizes, manipulate the inodes in buffers
- * which are multiples of the blocks size.
- */
- if (args.mp->m_sb.sb_blocksize >= XFS_INODE_CLUSTER_SIZE(args.mp)) {
- blks_per_cluster = 1;
- nbufs = (int)args.len;
- ninodes = args.mp->m_sb.sb_inopblock;
- } else {
- blks_per_cluster = XFS_INODE_CLUSTER_SIZE(args.mp) /
- args.mp->m_sb.sb_blocksize;
- nbufs = (int)args.len / blks_per_cluster;
- ninodes = blks_per_cluster * args.mp->m_sb.sb_inopblock;
- }
- /*
- * Figure out what version number to use in the inodes we create.
- * If the superblock version has caught up to the one that supports
- * the new inode format, then use the new inode version. Otherwise
- * use the old version so that old kernels will continue to be
- * able to use the file system.
- */
- if (XFS_SB_VERSION_HASNLINK(&args.mp->m_sb))
- version = XFS_DINODE_VERSION_2;
- else
- version = XFS_DINODE_VERSION_1;
-
- for (j = 0; j < nbufs; j++) {
- /*
- * Get the block.
- */
- d = XFS_AGB_TO_DADDR(args.mp, be32_to_cpu(agi->agi_seqno),
- args.agbno + (j * blks_per_cluster));
- fbuf = xfs_trans_get_buf(tp, args.mp->m_ddev_targp, d,
- args.mp->m_bsize * blks_per_cluster,
- XFS_BUF_LOCK);
- ASSERT(fbuf);
- ASSERT(!XFS_BUF_GETERROR(fbuf));
- /*
- * Set initial values for the inodes in this buffer.
- */
- xfs_biozero(fbuf, 0, ninodes << args.mp->m_sb.sb_inodelog);
- for (i = 0; i < ninodes; i++) {
- free = XFS_MAKE_IPTR(args.mp, fbuf, i);
- INT_SET(free->di_core.di_magic, ARCH_CONVERT, XFS_DINODE_MAGIC);
- INT_SET(free->di_core.di_version, ARCH_CONVERT, version);
- INT_SET(free->di_next_unlinked, ARCH_CONVERT, NULLAGINO);
- xfs_ialloc_log_di(tp, fbuf, i,
- XFS_DI_CORE_BITS | XFS_DI_NEXT_UNLINKED);
- }
- xfs_trans_inode_alloc_buf(tp, fbuf);
- }
- be32_add(&agi->agi_count, newlen);
- be32_add(&agi->agi_freecount, newlen);
- down_read(&args.mp->m_peraglock);
- args.mp->m_perag[be32_to_cpu(agi->agi_seqno)].pagi_freecount += newlen;
- up_read(&args.mp->m_peraglock);
- agi->agi_newino = cpu_to_be32(newino);
- /*
- * Insert records describing the new inode chunk into the btree.
- */
- cur = xfs_btree_init_cursor(args.mp, tp, agbp,
- be32_to_cpu(agi->agi_seqno),
- XFS_BTNUM_INO, (xfs_inode_t *)0, 0);
- for (thisino = newino;
- thisino < newino + newlen;
- thisino += XFS_INODES_PER_CHUNK) {
- if ((error = xfs_inobt_lookup_eq(cur, thisino,
- XFS_INODES_PER_CHUNK, XFS_INOBT_ALL_FREE, &i))) {
- xfs_btree_del_cursor(cur, XFS_BTREE_ERROR);
- return error;
- }
- ASSERT(i == 0);
- if ((error = xfs_inobt_insert(cur, &i))) {
- xfs_btree_del_cursor(cur, XFS_BTREE_ERROR);
- return error;
- }
- ASSERT(i == 1);
- }
- xfs_btree_del_cursor(cur, XFS_BTREE_NOERROR);
- /*
- * Log allocation group header fields
- */
- xfs_ialloc_log_agi(tp, agbp,
- XFS_AGI_COUNT | XFS_AGI_FREECOUNT | XFS_AGI_NEWINO);
- /*
- * Modify/log superblock values for inode count and inode free count.
- */
- xfs_trans_mod_sb(tp, XFS_TRANS_SB_ICOUNT, (long)newlen);
- xfs_trans_mod_sb(tp, XFS_TRANS_SB_IFREE, (long)newlen);
- *alloc = 1;
- return 0;
-}
-
-STATIC __inline xfs_agnumber_t
-xfs_ialloc_next_ag(
- xfs_mount_t *mp)
-{
- xfs_agnumber_t agno;
-
- spin_lock(&mp->m_agirotor_lock);
- agno = mp->m_agirotor;
- if (++mp->m_agirotor == mp->m_maxagi)
- mp->m_agirotor = 0;
- spin_unlock(&mp->m_agirotor_lock);
-
- return agno;
-}
-
-/*
- * Select an allocation group to look for a free inode in, based on the parent
- * inode and then mode. Return the allocation group buffer.
- */
-STATIC xfs_buf_t * /* allocation group buffer */
-xfs_ialloc_ag_select(
- xfs_trans_t *tp, /* transaction pointer */
- xfs_ino_t parent, /* parent directory inode number */
- mode_t mode, /* bits set to indicate file type */
- int okalloc) /* ok to allocate more space */
-{
- xfs_buf_t *agbp; /* allocation group header buffer */
- xfs_agnumber_t agcount; /* number of ag's in the filesystem */
- xfs_agnumber_t agno; /* current ag number */
- int flags; /* alloc buffer locking flags */
- xfs_extlen_t ineed; /* blocks needed for inode allocation */
- xfs_extlen_t longest = 0; /* longest extent available */
- xfs_mount_t *mp; /* mount point structure */
- int needspace; /* file mode implies space allocated */
- xfs_perag_t *pag; /* per allocation group data */
- xfs_agnumber_t pagno; /* parent (starting) ag number */
-
- /*
- * Files of these types need at least one block if length > 0
- * (and they won't fit in the inode, but that's hard to figure out).
- */
- needspace = S_ISDIR(mode) || S_ISREG(mode) || S_ISLNK(mode);
- mp = tp->t_mountp;
- agcount = mp->m_maxagi;
- if (S_ISDIR(mode))
- pagno = xfs_ialloc_next_ag(mp);
- else {
- pagno = XFS_INO_TO_AGNO(mp, parent);
- if (pagno >= agcount)
- pagno = 0;
- }
- ASSERT(pagno < agcount);
- /*
- * Loop through allocation groups, looking for one with a little
- * free space in it. Note we don't look for free inodes, exactly.
- * Instead, we include whether there is a need to allocate inodes
- * to mean that blocks must be allocated for them,
- * if none are currently free.
- */
- agno = pagno;
- flags = XFS_ALLOC_FLAG_TRYLOCK;
- down_read(&mp->m_peraglock);
- for (;;) {
- pag = &mp->m_perag[agno];
- if (!pag->pagi_init) {
- if (xfs_ialloc_read_agi(mp, tp, agno, &agbp)) {
- agbp = NULL;
- goto nextag;
- }
- } else
- agbp = NULL;
-
- if (!pag->pagi_inodeok) {
- xfs_ialloc_next_ag(mp);
- goto unlock_nextag;
- }
-
- /*
- * Is there enough free space for the file plus a block
- * of inodes (if we need to allocate some)?
- */
- ineed = pag->pagi_freecount ? 0 : XFS_IALLOC_BLOCKS(mp);
- if (ineed && !pag->pagf_init) {
- if (agbp == NULL &&
- xfs_ialloc_read_agi(mp, tp, agno, &agbp)) {
- agbp = NULL;
- goto nextag;
- }
- (void)xfs_alloc_pagf_init(mp, tp, agno, flags);
- }
- if (!ineed || pag->pagf_init) {
- if (ineed && !(longest = pag->pagf_longest))
- longest = pag->pagf_flcount > 0;
- if (!ineed ||
- (pag->pagf_freeblks >= needspace + ineed &&
- longest >= ineed &&
- okalloc)) {
- if (agbp == NULL &&
- xfs_ialloc_read_agi(mp, tp, agno, &agbp)) {
- agbp = NULL;
- goto nextag;
- }
- up_read(&mp->m_peraglock);
- return agbp;
- }
- }
-unlock_nextag:
- if (agbp)
- xfs_trans_brelse(tp, agbp);
-nextag:
- /*
- * No point in iterating over the rest, if we're shutting
- * down.
- */
- if (XFS_FORCED_SHUTDOWN(mp)) {
- up_read(&mp->m_peraglock);
- return (xfs_buf_t *)0;
- }
- agno++;
- if (agno >= agcount)
- agno = 0;
- if (agno == pagno) {
- if (flags == 0) {
- up_read(&mp->m_peraglock);
- return (xfs_buf_t *)0;
- }
- flags = 0;
- }
- }
-}
-
-/*
- * Visible inode allocation functions.
- */
-
-/*
- * Allocate an inode on disk.
- * Mode is used to tell whether the new inode will need space, and whether
- * it is a directory.
- *
- * The arguments IO_agbp and alloc_done are defined to work within
- * the constraint of one allocation per transaction.
- * xfs_dialloc() is designed to be called twice if it has to do an
- * allocation to make more free inodes. On the first call,
- * IO_agbp should be set to NULL. If an inode is available,
- * i.e., xfs_dialloc() did not need to do an allocation, an inode
- * number is returned. In this case, IO_agbp would be set to the
- * current ag_buf and alloc_done set to false.
- * If an allocation needed to be done, xfs_dialloc would return
- * the current ag_buf in IO_agbp and set alloc_done to true.
- * The caller should then commit the current transaction, allocate a new
- * transaction, and call xfs_dialloc() again, passing in the previous
- * value of IO_agbp. IO_agbp should be held across the transactions.
- * Since the agbp is locked across the two calls, the second call is
- * guaranteed to have a free inode available.
- *
- * Once we successfully pick an inode its number is returned and the
- * on-disk data structures are updated. The inode itself is not read
- * in, since doing so would break ordering constraints with xfs_reclaim.
- */
-int
-xfs_dialloc(
- xfs_trans_t *tp, /* transaction pointer */
- xfs_ino_t parent, /* parent inode (directory) */
- mode_t mode, /* mode bits for new inode */
- int okalloc, /* ok to allocate more space */
- xfs_buf_t **IO_agbp, /* in/out ag header's buffer */
- boolean_t *alloc_done, /* true if we needed to replenish
- inode freelist */
- xfs_ino_t *inop) /* inode number allocated */
-{
- xfs_agnumber_t agcount; /* number of allocation groups */
- xfs_buf_t *agbp; /* allocation group header's buffer */
- xfs_agnumber_t agno; /* allocation group number */
- xfs_agi_t *agi; /* allocation group header structure */
- xfs_btree_cur_t *cur; /* inode allocation btree cursor */
- int error; /* error return value */
- int i; /* result code */
- int ialloced = 0; /* inode allocation status */
- int noroom = 0; /* no space for inode blk allocation */
- xfs_ino_t ino; /* fs-relative inode to be returned */
- /* REFERENCED */
- int j; /* result code */
- xfs_mount_t *mp; /* file system mount structure */
- int offset; /* index of inode in chunk */
- xfs_agino_t pagino; /* parent's a.g. relative inode # */
- xfs_agnumber_t pagno; /* parent's allocation group number */
- xfs_inobt_rec_t rec; /* inode allocation record */
- xfs_agnumber_t tagno; /* testing allocation group number */
- xfs_btree_cur_t *tcur; /* temp cursor */
- xfs_inobt_rec_t trec; /* temp inode allocation record */
-
-
- if (*IO_agbp == NULL) {
- /*
- * We do not have an agbp, so select an initial allocation
- * group for inode allocation.
- */
- agbp = xfs_ialloc_ag_select(tp, parent, mode, okalloc);
- /*
- * Couldn't find an allocation group satisfying the
- * criteria, give up.
- */
- if (!agbp) {
- *inop = NULLFSINO;
- return 0;
- }
- agi = XFS_BUF_TO_AGI(agbp);
- ASSERT(be32_to_cpu(agi->agi_magicnum) == XFS_AGI_MAGIC);
- } else {
- /*
- * Continue where we left off before. In this case, we
- * know that the allocation group has free inodes.
- */
- agbp = *IO_agbp;
- agi = XFS_BUF_TO_AGI(agbp);
- ASSERT(be32_to_cpu(agi->agi_magicnum) == XFS_AGI_MAGIC);
- ASSERT(be32_to_cpu(agi->agi_freecount) > 0);
- }
- mp = tp->t_mountp;
- agcount = mp->m_sb.sb_agcount;
- agno = be32_to_cpu(agi->agi_seqno);
- tagno = agno;
- pagno = XFS_INO_TO_AGNO(mp, parent);
- pagino = XFS_INO_TO_AGINO(mp, parent);
-
- /*
- * If we have already hit the ceiling of inode blocks then clear
- * okalloc so we scan all available agi structures for a free
- * inode.
- */
-
- if (mp->m_maxicount &&
- mp->m_sb.sb_icount + XFS_IALLOC_INODES(mp) > mp->m_maxicount) {
- noroom = 1;
- okalloc = 0;
- }
-
- /*
- * Loop until we find an allocation group that either has free inodes
- * or in which we can allocate some inodes. Iterate through the
- * allocation groups upward, wrapping at the end.
- */
- *alloc_done = B_FALSE;
- while (!agi->agi_freecount) {
- /*
- * Don't do anything if we're not supposed to allocate
- * any blocks, just go on to the next ag.
- */
- if (okalloc) {
- /*
- * Try to allocate some new inodes in the allocation
- * group.
- */
- if ((error = xfs_ialloc_ag_alloc(tp, agbp, &ialloced))) {
- xfs_trans_brelse(tp, agbp);
- if (error == ENOSPC) {
- *inop = NULLFSINO;
- return 0;
- } else
- return error;
- }
- if (ialloced) {
- /*
- * We successfully allocated some inodes, return
- * the current context to the caller so that it
- * can commit the current transaction and call
- * us again where we left off.
- */
- ASSERT(be32_to_cpu(agi->agi_freecount) > 0);
- *alloc_done = B_TRUE;
- *IO_agbp = agbp;
- *inop = NULLFSINO;
- return 0;
- }
- }
- /*
- * If it failed, give up on this ag.
- */
- xfs_trans_brelse(tp, agbp);
- /*
- * Go on to the next ag: get its ag header.
- */
-nextag:
- if (++tagno == agcount)
- tagno = 0;
- if (tagno == agno) {
- *inop = NULLFSINO;
- return noroom ? ENOSPC : 0;
- }
- down_read(&mp->m_peraglock);
- if (mp->m_perag[tagno].pagi_inodeok == 0) {
- up_read(&mp->m_peraglock);
- goto nextag;
- }
- error = xfs_ialloc_read_agi(mp, tp, tagno, &agbp);
- up_read(&mp->m_peraglock);
- if (error)
- goto nextag;
- agi = XFS_BUF_TO_AGI(agbp);
- ASSERT(be32_to_cpu(agi->agi_magicnum) == XFS_AGI_MAGIC);
- }
- /*
- * Here with an allocation group that has a free inode.
- * Reset agno since we may have chosen a new ag in the
- * loop above.
- */
- agno = tagno;
- *IO_agbp = NULL;
- cur = xfs_btree_init_cursor(mp, tp, agbp, be32_to_cpu(agi->agi_seqno),
- XFS_BTNUM_INO, (xfs_inode_t *)0, 0);
- /*
- * If pagino is 0 (this is the root inode allocation) use newino.
- * This must work because we've just allocated some.
- */
- if (!pagino)
- pagino = be32_to_cpu(agi->agi_newino);
-#ifdef DEBUG
- if (cur->bc_nlevels == 1) {
- int freecount = 0;
-
- if ((error = xfs_inobt_lookup_ge(cur, 0, 0, 0, &i)))
- goto error0;
- XFS_WANT_CORRUPTED_GOTO(i == 1, error0);
- do {
- if ((error = xfs_inobt_get_rec(cur, &rec.ir_startino,
- &rec.ir_freecount, &rec.ir_free, &i)))
- goto error0;
- XFS_WANT_CORRUPTED_GOTO(i == 1, error0);
- freecount += rec.ir_freecount;
- if ((error = xfs_inobt_increment(cur, 0, &i)))
- goto error0;
- } while (i == 1);
-
- ASSERT(freecount == be32_to_cpu(agi->agi_freecount) ||
- XFS_FORCED_SHUTDOWN(mp));
- }
-#endif
- /*
- * If in the same a.g. as the parent, try to get near the parent.
- */
- if (pagno == agno) {
- if ((error = xfs_inobt_lookup_le(cur, pagino, 0, 0, &i)))
- goto error0;
- if (i != 0 &&
- (error = xfs_inobt_get_rec(cur, &rec.ir_startino,
- &rec.ir_freecount, &rec.ir_free, &j)) == 0 &&
- j == 1 &&
- rec.ir_freecount > 0) {
- /*
- * Found a free inode in the same chunk
- * as parent, done.
- */
- }
- /*
- * In the same a.g. as parent, but parent's chunk is full.
- */
- else {
- int doneleft; /* done, to the left */
- int doneright; /* done, to the right */
-
- if (error)
- goto error0;
- ASSERT(i == 1);
- ASSERT(j == 1);
- /*
- * Duplicate the cursor, search left & right
- * simultaneously.
- */
- if ((error = xfs_btree_dup_cursor(cur, &tcur)))
- goto error0;
- /*
- * Search left with tcur, back up 1 record.
- */
- if ((error = xfs_inobt_decrement(tcur, 0, &i)))
- goto error1;
- doneleft = !i;
- if (!doneleft) {
- if ((error = xfs_inobt_get_rec(tcur,
- &trec.ir_startino,
- &trec.ir_freecount,
- &trec.ir_free, &i)))
- goto error1;
- XFS_WANT_CORRUPTED_GOTO(i == 1, error1);
- }
- /*
- * Search right with cur, go forward 1 record.
- */
- if ((error = xfs_inobt_increment(cur, 0, &i)))
- goto error1;
- doneright = !i;
- if (!doneright) {
- if ((error = xfs_inobt_get_rec(cur,
- &rec.ir_startino,
- &rec.ir_freecount,
- &rec.ir_free, &i)))
- goto error1;
- XFS_WANT_CORRUPTED_GOTO(i == 1, error1);
- }
- /*
- * Loop until we find the closest inode chunk
- * with a free one.
- */
- while (!doneleft || !doneright) {
- int useleft; /* using left inode
- chunk this time */
-
- /*
- * Figure out which block is closer,
- * if both are valid.
- */
- if (!doneleft && !doneright)
- useleft =
- pagino -
- (trec.ir_startino +
- XFS_INODES_PER_CHUNK - 1) <
- rec.ir_startino - pagino;
- else
- useleft = !doneleft;
- /*
- * If checking the left, does it have
- * free inodes?
- */
- if (useleft && trec.ir_freecount) {
- /*
- * Yes, set it up as the chunk to use.
- */
- rec = trec;
- xfs_btree_del_cursor(cur,
- XFS_BTREE_NOERROR);
- cur = tcur;
- break;
- }
- /*
- * If checking the right, does it have
- * free inodes?
- */
- if (!useleft && rec.ir_freecount) {
- /*
- * Yes, it's already set up.
- */
- xfs_btree_del_cursor(tcur,
- XFS_BTREE_NOERROR);
- break;
- }
- /*
- * If used the left, get another one
- * further left.
- */
- if (useleft) {
- if ((error = xfs_inobt_decrement(tcur, 0,
- &i)))
- goto error1;
- doneleft = !i;
- if (!doneleft) {
- if ((error = xfs_inobt_get_rec(
- tcur,
- &trec.ir_startino,
- &trec.ir_freecount,
- &trec.ir_free, &i)))
- goto error1;
- XFS_WANT_CORRUPTED_GOTO(i == 1,
- error1);
- }
- }
- /*
- * If used the right, get another one
- * further right.
- */
- else {
- if ((error = xfs_inobt_increment(cur, 0,
- &i)))
- goto error1;
- doneright = !i;
- if (!doneright) {
- if ((error = xfs_inobt_get_rec(
- cur,
- &rec.ir_startino,
- &rec.ir_freecount,
- &rec.ir_free, &i)))
- goto error1;
- XFS_WANT_CORRUPTED_GOTO(i == 1,
- error1);
- }
- }
- }
- ASSERT(!doneleft || !doneright);
- }
- }
- /*
- * In a different a.g. from the parent.
- * See if the most recently allocated block has any free.
- */
- else if (be32_to_cpu(agi->agi_newino) != NULLAGINO) {
- if ((error = xfs_inobt_lookup_eq(cur,
- be32_to_cpu(agi->agi_newino), 0, 0, &i)))
- goto error0;
- if (i == 1 &&
- (error = xfs_inobt_get_rec(cur, &rec.ir_startino,
- &rec.ir_freecount, &rec.ir_free, &j)) == 0 &&
- j == 1 &&
- rec.ir_freecount > 0) {
- /*
- * The last chunk allocated in the group still has
- * a free inode.
- */
- }
- /*
- * None left in the last group, search the whole a.g.
- */
- else {
- if (error)
- goto error0;
- if ((error = xfs_inobt_lookup_ge(cur, 0, 0, 0, &i)))
- goto error0;
- ASSERT(i == 1);
- for (;;) {
- if ((error = xfs_inobt_get_rec(cur,
- &rec.ir_startino,
- &rec.ir_freecount, &rec.ir_free,
- &i)))
- goto error0;
- XFS_WANT_CORRUPTED_GOTO(i == 1, error0);
- if (rec.ir_freecount > 0)
- break;
- if ((error = xfs_inobt_increment(cur, 0, &i)))
- goto error0;
- XFS_WANT_CORRUPTED_GOTO(i == 1, error0);
- }
- }
- }
- offset = XFS_IALLOC_FIND_FREE(&rec.ir_free);
- ASSERT(offset >= 0);
- ASSERT(offset < XFS_INODES_PER_CHUNK);
- ASSERT((XFS_AGINO_TO_OFFSET(mp, rec.ir_startino) %
- XFS_INODES_PER_CHUNK) == 0);
- ino = XFS_AGINO_TO_INO(mp, agno, rec.ir_startino + offset);
- XFS_INOBT_CLR_FREE(&rec, offset);
- rec.ir_freecount--;
- if ((error = xfs_inobt_update(cur, rec.ir_startino, rec.ir_freecount,
- rec.ir_free)))
- goto error0;
- be32_add(&agi->agi_freecount, -1);
- xfs_ialloc_log_agi(tp, agbp, XFS_AGI_FREECOUNT);
- down_read(&mp->m_peraglock);
- mp->m_perag[tagno].pagi_freecount--;
- up_read(&mp->m_peraglock);
-#ifdef DEBUG
- if (cur->bc_nlevels == 1) {
- int freecount = 0;
-
- if ((error = xfs_inobt_lookup_ge(cur, 0, 0, 0, &i)))
- goto error0;
- do {
- if ((error = xfs_inobt_get_rec(cur, &rec.ir_startino,
- &rec.ir_freecount, &rec.ir_free, &i)))
- goto error0;
- XFS_WANT_CORRUPTED_GOTO(i == 1, error0);
- freecount += rec.ir_freecount;
- if ((error = xfs_inobt_increment(cur, 0, &i)))
- goto error0;
- } while (i == 1);
- ASSERT(freecount == be32_to_cpu(agi->agi_freecount) ||
- XFS_FORCED_SHUTDOWN(mp));
- }
-#endif
- xfs_btree_del_cursor(cur, XFS_BTREE_NOERROR);
- xfs_trans_mod_sb(tp, XFS_TRANS_SB_IFREE, -1);
- *inop = ino;
- return 0;
-error1:
- xfs_btree_del_cursor(tcur, XFS_BTREE_ERROR);
-error0:
- xfs_btree_del_cursor(cur, XFS_BTREE_ERROR);
- return error;
-}
-
-/*
- * Free disk inode. Carefully avoids touching the incore inode, all
- * manipulations incore are the caller's responsibility.
- * The on-disk inode is not changed by this operation, only the
- * btree (free inode mask) is changed.
- */
-int
-xfs_difree(
- xfs_trans_t *tp, /* transaction pointer */
- xfs_ino_t inode, /* inode to be freed */
- xfs_bmap_free_t *flist, /* extents to free */
- int *delete, /* set if inode cluster was deleted */
- xfs_ino_t *first_ino) /* first inode in deleted cluster */
-{
- /* REFERENCED */
- xfs_agblock_t agbno; /* block number containing inode */
- xfs_buf_t *agbp; /* buffer containing allocation group header */
- xfs_agino_t agino; /* inode number relative to allocation group */
- xfs_agnumber_t agno; /* allocation group number */
- xfs_agi_t *agi; /* allocation group header */
- xfs_btree_cur_t *cur; /* inode btree cursor */
- int error; /* error return value */
- int i; /* result code */
- int ilen; /* inodes in an inode cluster */
- xfs_mount_t *mp; /* mount structure for filesystem */
- int off; /* offset of inode in inode chunk */
- xfs_inobt_rec_t rec; /* btree record */
-
- mp = tp->t_mountp;
-
- /*
- * Break up inode number into its components.
- */
- agno = XFS_INO_TO_AGNO(mp, inode);
- if (agno >= mp->m_sb.sb_agcount) {
- cmn_err(CE_WARN,
- "xfs_difree: agno >= mp->m_sb.sb_agcount (%d >= %d) on %s. Returning EINVAL.",
- agno, mp->m_sb.sb_agcount, mp->m_fsname);
- ASSERT(0);
- return XFS_ERROR(EINVAL);
- }
- agino = XFS_INO_TO_AGINO(mp, inode);
- if (inode != XFS_AGINO_TO_INO(mp, agno, agino)) {
- cmn_err(CE_WARN,
- "xfs_difree: inode != XFS_AGINO_TO_INO() "
- "(%llu != %llu) on %s. Returning EINVAL.",
- (unsigned long long)inode,
- (unsigned long long)XFS_AGINO_TO_INO(mp, agno, agino),
- mp->m_fsname);
- ASSERT(0);
- return XFS_ERROR(EINVAL);
- }
- agbno = XFS_AGINO_TO_AGBNO(mp, agino);
- if (agbno >= mp->m_sb.sb_agblocks) {
- cmn_err(CE_WARN,
- "xfs_difree: agbno >= mp->m_sb.sb_agblocks (%d >= %d) on %s. Returning EINVAL.",
- agbno, mp->m_sb.sb_agblocks, mp->m_fsname);
- ASSERT(0);
- return XFS_ERROR(EINVAL);
- }
- /*
- * Get the allocation group header.
- */
- down_read(&mp->m_peraglock);
- error = xfs_ialloc_read_agi(mp, tp, agno, &agbp);
- up_read(&mp->m_peraglock);
- if (error) {
- cmn_err(CE_WARN,
- "xfs_difree: xfs_ialloc_read_agi() returned an error %d on %s. Returning error.",
- error, mp->m_fsname);
- return error;
- }
- agi = XFS_BUF_TO_AGI(agbp);
- ASSERT(be32_to_cpu(agi->agi_magicnum) == XFS_AGI_MAGIC);
- ASSERT(agbno < be32_to_cpu(agi->agi_length));
- /*
- * Initialize the cursor.
- */
- cur = xfs_btree_init_cursor(mp, tp, agbp, agno, XFS_BTNUM_INO,
- (xfs_inode_t *)0, 0);
-#ifdef DEBUG
- if (cur->bc_nlevels == 1) {
- int freecount = 0;
-
- if ((error = xfs_inobt_lookup_ge(cur, 0, 0, 0, &i)))
- goto error0;
- do {
- if ((error = xfs_inobt_get_rec(cur, &rec.ir_startino,
- &rec.ir_freecount, &rec.ir_free, &i)))
- goto error0;
- if (i) {
- freecount += rec.ir_freecount;
- if ((error = xfs_inobt_increment(cur, 0, &i)))
- goto error0;
- }
- } while (i == 1);
- ASSERT(freecount == be32_to_cpu(agi->agi_freecount) ||
- XFS_FORCED_SHUTDOWN(mp));
- }
-#endif
- /*
- * Look for the entry describing this inode.
- */
- if ((error = xfs_inobt_lookup_le(cur, agino, 0, 0, &i))) {
- cmn_err(CE_WARN,
- "xfs_difree: xfs_inobt_lookup_le returned() an error %d on %s. Returning error.",
- error, mp->m_fsname);
- goto error0;
- }
- XFS_WANT_CORRUPTED_GOTO(i == 1, error0);
- if ((error = xfs_inobt_get_rec(cur, &rec.ir_startino, &rec.ir_freecount,
- &rec.ir_free, &i))) {
- cmn_err(CE_WARN,
- "xfs_difree: xfs_inobt_get_rec() returned an error %d on %s. Returning error.",
- error, mp->m_fsname);
- goto error0;
- }
- XFS_WANT_CORRUPTED_GOTO(i == 1, error0);
- /*
- * Get the offset in the inode chunk.
- */
- off = agino - rec.ir_startino;
- ASSERT(off >= 0 && off < XFS_INODES_PER_CHUNK);
- ASSERT(!XFS_INOBT_IS_FREE(&rec, off));
- /*
- * Mark the inode free & increment the count.
- */
- XFS_INOBT_SET_FREE(&rec, off);
- rec.ir_freecount++;
-
- /*
- * When an inode cluster is free, it becomes eligible for removal
- */
- if ((mp->m_flags & XFS_MOUNT_IDELETE) &&
- (rec.ir_freecount == XFS_IALLOC_INODES(mp))) {
-
- *delete = 1;
- *first_ino = XFS_AGINO_TO_INO(mp, agno, rec.ir_startino);
-
- /*
- * Remove the inode cluster from the AGI B+Tree, adjust the
- * AGI and Superblock inode counts, and mark the disk space
- * to be freed when the transaction is committed.
- */
- ilen = XFS_IALLOC_INODES(mp);
- be32_add(&agi->agi_count, -ilen);
- be32_add(&agi->agi_freecount, -(ilen - 1));
- xfs_ialloc_log_agi(tp, agbp, XFS_AGI_COUNT | XFS_AGI_FREECOUNT);
- down_read(&mp->m_peraglock);
- mp->m_perag[agno].pagi_freecount -= ilen - 1;
- up_read(&mp->m_peraglock);
- xfs_trans_mod_sb(tp, XFS_TRANS_SB_ICOUNT, -ilen);
- xfs_trans_mod_sb(tp, XFS_TRANS_SB_IFREE, -(ilen - 1));
-
- if ((error = xfs_inobt_delete(cur, &i))) {
- cmn_err(CE_WARN, "xfs_difree: xfs_inobt_delete returned an error %d on %s.\n",
- error, mp->m_fsname);
- goto error0;
- }
-
- xfs_bmap_add_free(XFS_AGB_TO_FSB(mp,
- agno, XFS_INO_TO_AGBNO(mp,rec.ir_startino)),
- XFS_IALLOC_BLOCKS(mp), flist, mp);
- } else {
- *delete = 0;
-
- if ((error = xfs_inobt_update(cur, rec.ir_startino, rec.ir_freecount, rec.ir_free))) {
- cmn_err(CE_WARN,
- "xfs_difree: xfs_inobt_update() returned an error %d on %s. Returning error.",
- error, mp->m_fsname);
- goto error0;
- }
- /*
- * Change the inode free counts and log the ag/sb changes.
- */
- be32_add(&agi->agi_freecount, 1);
- xfs_ialloc_log_agi(tp, agbp, XFS_AGI_FREECOUNT);
- down_read(&mp->m_peraglock);
- mp->m_perag[agno].pagi_freecount++;
- up_read(&mp->m_peraglock);
- xfs_trans_mod_sb(tp, XFS_TRANS_SB_IFREE, 1);
- }
-
-#ifdef DEBUG
- if (cur->bc_nlevels == 1) {
- int freecount = 0;
-
- if ((error = xfs_inobt_lookup_ge(cur, 0, 0, 0, &i)))
- goto error0;
- do {
- if ((error = xfs_inobt_get_rec(cur,
- &rec.ir_startino,
- &rec.ir_freecount,
- &rec.ir_free, &i)))
- goto error0;
- if (i) {
- freecount += rec.ir_freecount;
- if ((error = xfs_inobt_increment(cur, 0, &i)))
- goto error0;
- }
- } while (i == 1);
- ASSERT(freecount == be32_to_cpu(agi->agi_freecount) ||
- XFS_FORCED_SHUTDOWN(mp));
- }
-#endif
- xfs_btree_del_cursor(cur, XFS_BTREE_NOERROR);
- return 0;
-
-error0:
- xfs_btree_del_cursor(cur, XFS_BTREE_ERROR);
- return error;
-}
-
-/*
- * Return the location of the inode in bno/off, for mapping it into a buffer.
- */
-/*ARGSUSED*/
-int
-xfs_dilocate(
- xfs_mount_t *mp, /* file system mount structure */
- xfs_trans_t *tp, /* transaction pointer */
- xfs_ino_t ino, /* inode to locate */
- xfs_fsblock_t *bno, /* output: block containing inode */
- int *len, /* output: num blocks in inode cluster */
- int *off, /* output: index in block of inode */
- uint flags) /* flags concerning inode lookup */
-{
- xfs_agblock_t agbno; /* block number of inode in the alloc group */
- xfs_buf_t *agbp; /* agi buffer */
- xfs_agino_t agino; /* inode number within alloc group */
- xfs_agnumber_t agno; /* allocation group number */
- int blks_per_cluster; /* num blocks per inode cluster */
- xfs_agblock_t chunk_agbno; /* first block in inode chunk */
- xfs_agino_t chunk_agino; /* first agino in inode chunk */
- __int32_t chunk_cnt; /* count of free inodes in chunk */
- xfs_inofree_t chunk_free; /* mask of free inodes in chunk */
- xfs_agblock_t cluster_agbno; /* first block in inode cluster */
- xfs_btree_cur_t *cur; /* inode btree cursor */
- int error; /* error code */
- int i; /* temp state */
- int offset; /* index of inode in its buffer */
- int offset_agbno; /* blks from chunk start to inode */
-
- ASSERT(ino != NULLFSINO);
- /*
- * Split up the inode number into its parts.
- */
- agno = XFS_INO_TO_AGNO(mp, ino);
- agino = XFS_INO_TO_AGINO(mp, ino);
- agbno = XFS_AGINO_TO_AGBNO(mp, agino);
- if (agno >= mp->m_sb.sb_agcount || agbno >= mp->m_sb.sb_agblocks ||
- ino != XFS_AGINO_TO_INO(mp, agno, agino)) {
-#ifdef DEBUG
- if (agno >= mp->m_sb.sb_agcount) {
- xfs_fs_cmn_err(CE_ALERT, mp,
- "xfs_dilocate: ino (0x%llx) agno (%d) >= "
- "mp->m_sb.sb_agcount (%d)",
- ino,
- agno, mp->m_sb.sb_agcount);
- }
- if (agbno >= mp->m_sb.sb_agblocks) {
- xfs_fs_cmn_err(CE_ALERT, mp,
- "xfs_dilocate: agbno (0x%llx) >= "
- "mp->m_sb.sb_agblocks (0x%lx)",
- (unsigned long long) agbno,
- (unsigned long) mp->m_sb.sb_agblocks);
- }
- if (ino != XFS_AGINO_TO_INO(mp, agno, agino)) {
- xfs_fs_cmn_err(CE_ALERT, mp,
- "xfs_dilocate: ino (0x%llx) != "
- "XFS_AGINO_TO_INO(mp, agno, agino) "
- "(0x%llx)",
- ino, XFS_AGINO_TO_INO(mp, agno, agino));
- }
-#endif /* DEBUG */
- return XFS_ERROR(EINVAL);
- }
- if ((mp->m_sb.sb_blocksize >= XFS_INODE_CLUSTER_SIZE(mp)) ||
- !(flags & XFS_IMAP_LOOKUP)) {
- offset = XFS_INO_TO_OFFSET(mp, ino);
- ASSERT(offset < mp->m_sb.sb_inopblock);
- *bno = XFS_AGB_TO_FSB(mp, agno, agbno);
- *off = offset;
- *len = 1;
- return 0;
- }
- blks_per_cluster = XFS_INODE_CLUSTER_SIZE(mp) >> mp->m_sb.sb_blocklog;
- if (*bno != NULLFSBLOCK) {
- offset = XFS_INO_TO_OFFSET(mp, ino);
- ASSERT(offset < mp->m_sb.sb_inopblock);
- cluster_agbno = XFS_FSB_TO_AGBNO(mp, *bno);
- *off = ((agbno - cluster_agbno) * mp->m_sb.sb_inopblock) +
- offset;
- *len = blks_per_cluster;
- return 0;
- }
- if (mp->m_inoalign_mask) {
- offset_agbno = agbno & mp->m_inoalign_mask;
- chunk_agbno = agbno - offset_agbno;
- } else {
- down_read(&mp->m_peraglock);
- error = xfs_ialloc_read_agi(mp, tp, agno, &agbp);
- up_read(&mp->m_peraglock);
- if (error) {
-#ifdef DEBUG
- xfs_fs_cmn_err(CE_ALERT, mp, "xfs_dilocate: "
- "xfs_ialloc_read_agi() returned "
- "error %d, agno %d",
- error, agno);
-#endif /* DEBUG */
- return error;
- }
- cur = xfs_btree_init_cursor(mp, tp, agbp, agno, XFS_BTNUM_INO,
- (xfs_inode_t *)0, 0);
- if ((error = xfs_inobt_lookup_le(cur, agino, 0, 0, &i))) {
-#ifdef DEBUG
- xfs_fs_cmn_err(CE_ALERT, mp, "xfs_dilocate: "
- "xfs_inobt_lookup_le() failed");
-#endif /* DEBUG */
- goto error0;
- }
- if ((error = xfs_inobt_get_rec(cur, &chunk_agino, &chunk_cnt,
- &chunk_free, &i))) {
-#ifdef DEBUG
- xfs_fs_cmn_err(CE_ALERT, mp, "xfs_dilocate: "
- "xfs_inobt_get_rec() failed");
-#endif /* DEBUG */
- goto error0;
- }
- if (i == 0) {
-#ifdef DEBUG
- xfs_fs_cmn_err(CE_ALERT, mp, "xfs_dilocate: "
- "xfs_inobt_get_rec() failed");
-#endif /* DEBUG */
- error = XFS_ERROR(EINVAL);
- }
- xfs_trans_brelse(tp, agbp);
- xfs_btree_del_cursor(cur, XFS_BTREE_NOERROR);
- if (error)
- return error;
- chunk_agbno = XFS_AGINO_TO_AGBNO(mp, chunk_agino);
- offset_agbno = agbno - chunk_agbno;
- }
- ASSERT(agbno >= chunk_agbno);
- cluster_agbno = chunk_agbno +
- ((offset_agbno / blks_per_cluster) * blks_per_cluster);
- offset = ((agbno - cluster_agbno) * mp->m_sb.sb_inopblock) +
- XFS_INO_TO_OFFSET(mp, ino);
- *bno = XFS_AGB_TO_FSB(mp, agno, cluster_agbno);
- *off = offset;
- *len = blks_per_cluster;
- return 0;
-error0:
- xfs_trans_brelse(tp, agbp);
- xfs_btree_del_cursor(cur, XFS_BTREE_ERROR);
- return error;
-}
-
-/*
- * Compute and fill in value of m_in_maxlevels.
- */
-void
-xfs_ialloc_compute_maxlevels(
- xfs_mount_t *mp) /* file system mount structure */
-{
- int level;
- uint maxblocks;
- uint maxleafents;
- int minleafrecs;
- int minnoderecs;
-
- maxleafents = (1LL << XFS_INO_AGINO_BITS(mp)) >>
- XFS_INODES_PER_CHUNK_LOG;
- minleafrecs = mp->m_alloc_mnr[0];
- minnoderecs = mp->m_alloc_mnr[1];
- maxblocks = (maxleafents + minleafrecs - 1) / minleafrecs;
- for (level = 1; maxblocks > 1; level++)
- maxblocks = (maxblocks + minnoderecs - 1) / minnoderecs;
- mp->m_in_maxlevels = level;
-}
-
-/*
- * Log specified fields for the ag hdr (inode section)
- */
-void
-xfs_ialloc_log_agi(
- xfs_trans_t *tp, /* transaction pointer */
- xfs_buf_t *bp, /* allocation group header buffer */
- int fields) /* bitmask of fields to log */
-{
- int first; /* first byte number */
- int last; /* last byte number */
- static const short offsets[] = { /* field starting offsets */
- /* keep in sync with bit definitions */
- offsetof(xfs_agi_t, agi_magicnum),
- offsetof(xfs_agi_t, agi_versionnum),
- offsetof(xfs_agi_t, agi_seqno),
- offsetof(xfs_agi_t, agi_length),
- offsetof(xfs_agi_t, agi_count),
- offsetof(xfs_agi_t, agi_root),
- offsetof(xfs_agi_t, agi_level),
- offsetof(xfs_agi_t, agi_freecount),
- offsetof(xfs_agi_t, agi_newino),
- offsetof(xfs_agi_t, agi_dirino),
- offsetof(xfs_agi_t, agi_unlinked),
- sizeof(xfs_agi_t)
- };
-#ifdef DEBUG
- xfs_agi_t *agi; /* allocation group header */
-
- agi = XFS_BUF_TO_AGI(bp);
- ASSERT(be32_to_cpu(agi->agi_magicnum) == XFS_AGI_MAGIC);
-#endif
- /*
- * Compute byte offsets for the first and last fields.
- */
- xfs_btree_offsets(fields, offsets, XFS_AGI_NUM_BITS, &first, &last);
- /*
- * Log the allocation group inode header buffer.
- */
- xfs_trans_log_buf(tp, bp, first, last);
-}
-
-/*
- * Read in the allocation group header (inode allocation section)
- */
-int
-xfs_ialloc_read_agi(
- xfs_mount_t *mp, /* file system mount structure */
- xfs_trans_t *tp, /* transaction pointer */
- xfs_agnumber_t agno, /* allocation group number */
- xfs_buf_t **bpp) /* allocation group hdr buf */
-{
- xfs_agi_t *agi; /* allocation group header */
- int agi_ok; /* agi is consistent */
- xfs_buf_t *bp; /* allocation group hdr buf */
- xfs_perag_t *pag; /* per allocation group data */
- int error;
-
- ASSERT(agno != NULLAGNUMBER);
- error = xfs_trans_read_buf(
- mp, tp, mp->m_ddev_targp,
- XFS_AG_DADDR(mp, agno, XFS_AGI_DADDR(mp)),
- XFS_FSS_TO_BB(mp, 1), 0, &bp);
- if (error)
- return error;
- ASSERT(bp && !XFS_BUF_GETERROR(bp));
-
- /*
- * Validate the magic number of the agi block.
- */
- agi = XFS_BUF_TO_AGI(bp);
- agi_ok =
- be32_to_cpu(agi->agi_magicnum) == XFS_AGI_MAGIC &&
- XFS_AGI_GOOD_VERSION(be32_to_cpu(agi->agi_versionnum));
- if (unlikely(XFS_TEST_ERROR(!agi_ok, mp, XFS_ERRTAG_IALLOC_READ_AGI,
- XFS_RANDOM_IALLOC_READ_AGI))) {
- XFS_CORRUPTION_ERROR("xfs_ialloc_read_agi", XFS_ERRLEVEL_LOW,
- mp, agi);
- xfs_trans_brelse(tp, bp);
- return XFS_ERROR(EFSCORRUPTED);
- }
- pag = &mp->m_perag[agno];
- if (!pag->pagi_init) {
- pag->pagi_freecount = be32_to_cpu(agi->agi_freecount);
- pag->pagi_init = 1;
- } else {
- /*
- * It's possible for these to be out of sync if
- * we are in the middle of a forced shutdown.
- */
- ASSERT(pag->pagi_freecount == be32_to_cpu(agi->agi_freecount) ||
- XFS_FORCED_SHUTDOWN(mp));
- }
-
-#ifdef DEBUG
- {
- int i;
-
- for (i = 0; i < XFS_AGI_UNLINKED_BUCKETS; i++)
- ASSERT(agi->agi_unlinked[i]);
- }
-#endif
-
- XFS_BUF_SET_VTYPE_REF(bp, B_FS_AGI, XFS_AGI_REF);
- *bpp = bp;
- return 0;
-}
diff --git a/sys/gnu/fs/xfs/xfs_ialloc.h b/sys/gnu/fs/xfs/xfs_ialloc.h
deleted file mode 100644
index 7f5debe..0000000
--- a/sys/gnu/fs/xfs/xfs_ialloc.h
+++ /dev/null
@@ -1,154 +0,0 @@
-/*
- * Copyright (c) 2000,2005 Silicon Graphics, Inc.
- * All Rights Reserved.
- *
- * 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.
- *
- * This program is distributed in the hope that it would 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 the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- */
-#ifndef __XFS_IALLOC_H__
-#define __XFS_IALLOC_H__
-
-struct xfs_buf;
-struct xfs_dinode;
-struct xfs_mount;
-struct xfs_trans;
-
-/*
- * Allocation parameters for inode allocation.
- */
-#define XFS_IALLOC_INODES(mp) (mp)->m_ialloc_inos
-#define XFS_IALLOC_BLOCKS(mp) (mp)->m_ialloc_blks
-
-/*
- * For small block file systems, move inodes in clusters of this size.
- * When we don't have a lot of memory, however, we go a bit smaller
- * to reduce the number of AGI and ialloc btree blocks we need to keep
- * around for xfs_dilocate(). We choose which one to use in
- * xfs_mount_int().
- */
-#define XFS_INODE_BIG_CLUSTER_SIZE 8192
-#define XFS_INODE_SMALL_CLUSTER_SIZE 4096
-#define XFS_INODE_CLUSTER_SIZE(mp) (mp)->m_inode_cluster_size
-
-/*
- * Make an inode pointer out of the buffer/offset.
- */
-#define XFS_MAKE_IPTR(mp,b,o) xfs_make_iptr(mp,b,o)
-static inline struct xfs_dinode *
-xfs_make_iptr(struct xfs_mount *mp, struct xfs_buf *b, int o)
-{
- return (xfs_dinode_t *)
- (xfs_buf_offset(b, o << (mp)->m_sb.sb_inodelog));
-}
-
-/*
- * Find a free (set) bit in the inode bitmask.
- */
-#define XFS_IALLOC_FIND_FREE(fp) xfs_ialloc_find_free(fp)
-static inline int xfs_ialloc_find_free(xfs_inofree_t *fp)
-{
- return xfs_lowbit64(*fp);
-}
-
-
-#ifdef __KERNEL__
-/*
- * Allocate an inode on disk.
- * Mode is used to tell whether the new inode will need space, and whether
- * it is a directory.
- *
- * To work within the constraint of one allocation per transaction,
- * xfs_dialloc() is designed to be called twice if it has to do an
- * allocation to make more free inodes. If an inode is
- * available without an allocation, agbp would be set to the current
- * agbp and alloc_done set to false.
- * If an allocation needed to be done, agbp would be set to the
- * inode header of the allocation group and alloc_done set to true.
- * The caller should then commit the current transaction and allocate a new
- * transaction. xfs_dialloc() should then be called again with
- * the agbp value returned from the previous call.
- *
- * Once we successfully pick an inode its number is returned and the
- * on-disk data structures are updated. The inode itself is not read
- * in, since doing so would break ordering constraints with xfs_reclaim.
- *
- * *agbp should be set to NULL on the first call, *alloc_done set to FALSE.
- */
-int /* error */
-xfs_dialloc(
- struct xfs_trans *tp, /* transaction pointer */
- xfs_ino_t parent, /* parent inode (directory) */
- mode_t mode, /* mode bits for new inode */
- int okalloc, /* ok to allocate more space */
- struct xfs_buf **agbp, /* buf for a.g. inode header */
- boolean_t *alloc_done, /* an allocation was done to replenish
- the free inodes */
- xfs_ino_t *inop); /* inode number allocated */
-
-/*
- * Free disk inode. Carefully avoids touching the incore inode, all
- * manipulations incore are the caller's responsibility.
- * The on-disk inode is not changed by this operation, only the
- * btree (free inode mask) is changed.
- */
-int /* error */
-xfs_difree(
- struct xfs_trans *tp, /* transaction pointer */
- xfs_ino_t inode, /* inode to be freed */
- struct xfs_bmap_free *flist, /* extents to free */
- int *delete, /* set if inode cluster was deleted */
- xfs_ino_t *first_ino); /* first inode in deleted cluster */
-
-/*
- * Return the location of the inode in bno/len/off,
- * for mapping it into a buffer.
- */
-int
-xfs_dilocate(
- struct xfs_mount *mp, /* file system mount structure */
- struct xfs_trans *tp, /* transaction pointer */
- xfs_ino_t ino, /* inode to locate */
- xfs_fsblock_t *bno, /* output: block containing inode */
- int *len, /* output: num blocks in cluster*/
- int *off, /* output: index in block of inode */
- uint flags); /* flags for inode btree lookup */
-
-/*
- * Compute and fill in value of m_in_maxlevels.
- */
-void
-xfs_ialloc_compute_maxlevels(
- struct xfs_mount *mp); /* file system mount structure */
-
-/*
- * Log specified fields for the ag hdr (inode section)
- */
-void
-xfs_ialloc_log_agi(
- struct xfs_trans *tp, /* transaction pointer */
- struct xfs_buf *bp, /* allocation group header buffer */
- int fields); /* bitmask of fields to log */
-
-/*
- * Read in the allocation group header (inode allocation section)
- */
-int /* error */
-xfs_ialloc_read_agi(
- struct xfs_mount *mp, /* file system mount structure */
- struct xfs_trans *tp, /* transaction pointer */
- xfs_agnumber_t agno, /* allocation group number */
- struct xfs_buf **bpp); /* allocation group hdr buf */
-
-#endif /* __KERNEL__ */
-
-#endif /* __XFS_IALLOC_H__ */
diff --git a/sys/gnu/fs/xfs/xfs_ialloc_btree.c b/sys/gnu/fs/xfs/xfs_ialloc_btree.c
deleted file mode 100644
index 60c6568..0000000
--- a/sys/gnu/fs/xfs/xfs_ialloc_btree.c
+++ /dev/null
@@ -1,2080 +0,0 @@
-/*
- * Copyright (c) 2000-2001,2005 Silicon Graphics, Inc.
- * All Rights Reserved.
- *
- * 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.
- *
- * This program is distributed in the hope that it would 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 the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- */
-#include "xfs.h"
-#include "xfs_fs.h"
-#include "xfs_types.h"
-#include "xfs_bit.h"
-#include "xfs_log.h"
-#include "xfs_inum.h"
-#include "xfs_trans.h"
-#include "xfs_sb.h"
-#include "xfs_ag.h"
-#include "xfs_dir.h"
-#include "xfs_dir2.h"
-#include "xfs_dmapi.h"
-#include "xfs_mount.h"
-#include "xfs_bmap_btree.h"
-#include "xfs_alloc_btree.h"
-#include "xfs_ialloc_btree.h"
-#include "xfs_dir_sf.h"
-#include "xfs_dir2_sf.h"
-#include "xfs_attr_sf.h"
-#include "xfs_dinode.h"
-#include "xfs_inode.h"
-#include "xfs_btree.h"
-#include "xfs_ialloc.h"
-#include "xfs_alloc.h"
-#include "xfs_error.h"
-
-STATIC void xfs_inobt_log_block(xfs_trans_t *, xfs_buf_t *, int);
-STATIC void xfs_inobt_log_keys(xfs_btree_cur_t *, xfs_buf_t *, int, int);
-STATIC void xfs_inobt_log_ptrs(xfs_btree_cur_t *, xfs_buf_t *, int, int);
-STATIC void xfs_inobt_log_recs(xfs_btree_cur_t *, xfs_buf_t *, int, int);
-STATIC int xfs_inobt_lshift(xfs_btree_cur_t *, int, int *);
-STATIC int xfs_inobt_newroot(xfs_btree_cur_t *, int *);
-STATIC int xfs_inobt_rshift(xfs_btree_cur_t *, int, int *);
-STATIC int xfs_inobt_split(xfs_btree_cur_t *, int, xfs_agblock_t *,
- xfs_inobt_key_t *, xfs_btree_cur_t **, int *);
-STATIC int xfs_inobt_updkey(xfs_btree_cur_t *, xfs_inobt_key_t *, int);
-
-/*
- * Single level of the xfs_inobt_delete record deletion routine.
- * Delete record pointed to by cur/level.
- * Remove the record from its block then rebalance the tree.
- * Return 0 for error, 1 for done, 2 to go on to the next level.
- */
-STATIC int /* error */
-xfs_inobt_delrec(
- xfs_btree_cur_t *cur, /* btree cursor */
- int level, /* level removing record from */
- int *stat) /* fail/done/go-on */
-{
- xfs_buf_t *agbp; /* buffer for a.g. inode header */
- xfs_mount_t *mp; /* mount structure */
- xfs_agi_t *agi; /* allocation group inode header */
- xfs_inobt_block_t *block; /* btree block record/key lives in */
- xfs_agblock_t bno; /* btree block number */
- xfs_buf_t *bp; /* buffer for block */
- int error; /* error return value */
- int i; /* loop index */
- xfs_inobt_key_t key; /* kp points here if block is level 0 */
- xfs_inobt_key_t *kp = NULL; /* pointer to btree keys */
- xfs_agblock_t lbno; /* left block's block number */
- xfs_buf_t *lbp; /* left block's buffer pointer */
- xfs_inobt_block_t *left; /* left btree block */
- xfs_inobt_key_t *lkp; /* left block key pointer */
- xfs_inobt_ptr_t *lpp; /* left block address pointer */
- int lrecs = 0; /* number of records in left block */
- xfs_inobt_rec_t *lrp; /* left block record pointer */
- xfs_inobt_ptr_t *pp = NULL; /* pointer to btree addresses */
- int ptr; /* index in btree block for this rec */
- xfs_agblock_t rbno; /* right block's block number */
- xfs_buf_t *rbp; /* right block's buffer pointer */
- xfs_inobt_block_t *right; /* right btree block */
- xfs_inobt_key_t *rkp; /* right block key pointer */
- xfs_inobt_rec_t *rp; /* pointer to btree records */
- xfs_inobt_ptr_t *rpp; /* right block address pointer */
- int rrecs = 0; /* number of records in right block */
- int numrecs;
- xfs_inobt_rec_t *rrp; /* right block record pointer */
- xfs_btree_cur_t *tcur; /* temporary btree cursor */
-
- mp = cur->bc_mp;
-
- /*
- * Get the index of the entry being deleted, check for nothing there.
- */
- ptr = cur->bc_ptrs[level];
- if (ptr == 0) {
- *stat = 0;
- return 0;
- }
-
- /*
- * Get the buffer & block containing the record or key/ptr.
- */
- bp = cur->bc_bufs[level];
- block = XFS_BUF_TO_INOBT_BLOCK(bp);
-#ifdef DEBUG
- if ((error = xfs_btree_check_sblock(cur, block, level, bp)))
- return error;
-#endif
- /*
- * Fail if we're off the end of the block.
- */
-
- numrecs = be16_to_cpu(block->bb_numrecs);
- if (ptr > numrecs) {
- *stat = 0;
- return 0;
- }
- /*
- * It's a nonleaf. Excise the key and ptr being deleted, by
- * sliding the entries past them down one.
- * Log the changed areas of the block.
- */
- if (level > 0) {
- kp = XFS_INOBT_KEY_ADDR(block, 1, cur);
- pp = XFS_INOBT_PTR_ADDR(block, 1, cur);
-#ifdef DEBUG
- for (i = ptr; i < numrecs; i++) {
- if ((error = xfs_btree_check_sptr(cur, be32_to_cpu(pp[i]), level)))
- return error;
- }
-#endif
- if (ptr < numrecs) {
- memmove(&kp[ptr - 1], &kp[ptr],
- (numrecs - ptr) * sizeof(*kp));
- memmove(&pp[ptr - 1], &pp[ptr],
- (numrecs - ptr) * sizeof(*kp));
- xfs_inobt_log_keys(cur, bp, ptr, numrecs - 1);
- xfs_inobt_log_ptrs(cur, bp, ptr, numrecs - 1);
- }
- }
- /*
- * It's a leaf. Excise the record being deleted, by sliding the
- * entries past it down one. Log the changed areas of the block.
- */
- else {
- rp = XFS_INOBT_REC_ADDR(block, 1, cur);
- if (ptr < numrecs) {
- memmove(&rp[ptr - 1], &rp[ptr],
- (numrecs - ptr) * sizeof(*rp));
- xfs_inobt_log_recs(cur, bp, ptr, numrecs - 1);
- }
- /*
- * If it's the first record in the block, we'll need a key
- * structure to pass up to the next level (updkey).
- */
- if (ptr == 1) {
- key.ir_startino = rp->ir_startino;
- kp = &key;
- }
- }
- /*
- * Decrement and log the number of entries in the block.
- */
- numrecs--;
- block->bb_numrecs = cpu_to_be16(numrecs);
- xfs_inobt_log_block(cur->bc_tp, bp, XFS_BB_NUMRECS);
- /*
- * Is this the root level? If so, we're almost done.
- */
- if (level == cur->bc_nlevels - 1) {
- /*
- * If this is the root level,
- * and there's only one entry left,
- * and it's NOT the leaf level,
- * then we can get rid of this level.
- */
- if (numrecs == 1 && level > 0) {
- agbp = cur->bc_private.i.agbp;
- agi = XFS_BUF_TO_AGI(agbp);
- /*
- * pp is still set to the first pointer in the block.
- * Make it the new root of the btree.
- */
- bno = be32_to_cpu(agi->agi_root);
- agi->agi_root = *pp;
- be32_add(&agi->agi_level, -1);
- /*
- * Free the block.
- */
- if ((error = xfs_free_extent(cur->bc_tp,
- XFS_AGB_TO_FSB(mp, cur->bc_private.i.agno, bno), 1)))
- return error;
- xfs_trans_binval(cur->bc_tp, bp);
- xfs_ialloc_log_agi(cur->bc_tp, agbp,
- XFS_AGI_ROOT | XFS_AGI_LEVEL);
- /*
- * Update the cursor so there's one fewer level.
- */
- cur->bc_bufs[level] = NULL;
- cur->bc_nlevels--;
- } else if (level > 0 &&
- (error = xfs_inobt_decrement(cur, level, &i)))
- return error;
- *stat = 1;
- return 0;
- }
- /*
- * If we deleted the leftmost entry in the block, update the
- * key values above us in the tree.
- */
- if (ptr == 1 && (error = xfs_inobt_updkey(cur, kp, level + 1)))
- return error;
- /*
- * If the number of records remaining in the block is at least
- * the minimum, we're done.
- */
- if (numrecs >= XFS_INOBT_BLOCK_MINRECS(level, cur)) {
- if (level > 0 &&
- (error = xfs_inobt_decrement(cur, level, &i)))
- return error;
- *stat = 1;
- return 0;
- }
- /*
- * Otherwise, we have to move some records around to keep the
- * tree balanced. Look at the left and right sibling blocks to
- * see if we can re-balance by moving only one record.
- */
- rbno = be32_to_cpu(block->bb_rightsib);
- lbno = be32_to_cpu(block->bb_leftsib);
- bno = NULLAGBLOCK;
- ASSERT(rbno != NULLAGBLOCK || lbno != NULLAGBLOCK);
- /*
- * Duplicate the cursor so our btree manipulations here won't
- * disrupt the next level up.
- */
- if ((error = xfs_btree_dup_cursor(cur, &tcur)))
- return error;
- /*
- * If there's a right sibling, see if it's ok to shift an entry
- * out of it.
- */
- if (rbno != NULLAGBLOCK) {
- /*
- * Move the temp cursor to the last entry in the next block.
- * Actually any entry but the first would suffice.
- */
- i = xfs_btree_lastrec(tcur, level);
- XFS_WANT_CORRUPTED_GOTO(i == 1, error0);
- if ((error = xfs_inobt_increment(tcur, level, &i)))
- goto error0;
- XFS_WANT_CORRUPTED_GOTO(i == 1, error0);
- i = xfs_btree_lastrec(tcur, level);
- XFS_WANT_CORRUPTED_GOTO(i == 1, error0);
- /*
- * Grab a pointer to the block.
- */
- rbp = tcur->bc_bufs[level];
- right = XFS_BUF_TO_INOBT_BLOCK(rbp);
-#ifdef DEBUG
- if ((error = xfs_btree_check_sblock(cur, right, level, rbp)))
- goto error0;
-#endif
- /*
- * Grab the current block number, for future use.
- */
- bno = be32_to_cpu(right->bb_leftsib);
- /*
- * If right block is full enough so that removing one entry
- * won't make it too empty, and left-shifting an entry out
- * of right to us works, we're done.
- */
- if (be16_to_cpu(right->bb_numrecs) - 1 >=
- XFS_INOBT_BLOCK_MINRECS(level, cur)) {
- if ((error = xfs_inobt_lshift(tcur, level, &i)))
- goto error0;
- if (i) {
- ASSERT(be16_to_cpu(block->bb_numrecs) >=
- XFS_INOBT_BLOCK_MINRECS(level, cur));
- xfs_btree_del_cursor(tcur,
- XFS_BTREE_NOERROR);
- if (level > 0 &&
- (error = xfs_inobt_decrement(cur, level,
- &i)))
- return error;
- *stat = 1;
- return 0;
- }
- }
- /*
- * Otherwise, grab the number of records in right for
- * future reference, and fix up the temp cursor to point
- * to our block again (last record).
- */
- rrecs = be16_to_cpu(right->bb_numrecs);
- if (lbno != NULLAGBLOCK) {
- xfs_btree_firstrec(tcur, level);
- if ((error = xfs_inobt_decrement(tcur, level, &i)))
- goto error0;
- }
- }
- /*
- * If there's a left sibling, see if it's ok to shift an entry
- * out of it.
- */
- if (lbno != NULLAGBLOCK) {
- /*
- * Move the temp cursor to the first entry in the
- * previous block.
- */
- xfs_btree_firstrec(tcur, level);
- if ((error = xfs_inobt_decrement(tcur, level, &i)))
- goto error0;
- xfs_btree_firstrec(tcur, level);
- /*
- * Grab a pointer to the block.
- */
- lbp = tcur->bc_bufs[level];
- left = XFS_BUF_TO_INOBT_BLOCK(lbp);
-#ifdef DEBUG
- if ((error = xfs_btree_check_sblock(cur, left, level, lbp)))
- goto error0;
-#endif
- /*
- * Grab the current block number, for future use.
- */
- bno = be32_to_cpu(left->bb_rightsib);
- /*
- * If left block is full enough so that removing one entry
- * won't make it too empty, and right-shifting an entry out
- * of left to us works, we're done.
- */
- if (be16_to_cpu(left->bb_numrecs) - 1 >=
- XFS_INOBT_BLOCK_MINRECS(level, cur)) {
- if ((error = xfs_inobt_rshift(tcur, level, &i)))
- goto error0;
- if (i) {
- ASSERT(be16_to_cpu(block->bb_numrecs) >=
- XFS_INOBT_BLOCK_MINRECS(level, cur));
- xfs_btree_del_cursor(tcur,
- XFS_BTREE_NOERROR);
- if (level == 0)
- cur->bc_ptrs[0]++;
- *stat = 1;
- return 0;
- }
- }
- /*
- * Otherwise, grab the number of records in right for
- * future reference.
- */
- lrecs = be16_to_cpu(left->bb_numrecs);
- }
- /*
- * Delete the temp cursor, we're done with it.
- */
- xfs_btree_del_cursor(tcur, XFS_BTREE_NOERROR);
- /*
- * If here, we need to do a join to keep the tree balanced.
- */
- ASSERT(bno != NULLAGBLOCK);
- /*
- * See if we can join with the left neighbor block.
- */
- if (lbno != NULLAGBLOCK &&
- lrecs + numrecs <= XFS_INOBT_BLOCK_MAXRECS(level, cur)) {
- /*
- * Set "right" to be the starting block,
- * "left" to be the left neighbor.
- */
- rbno = bno;
- right = block;
- rrecs = be16_to_cpu(right->bb_numrecs);
- rbp = bp;
- if ((error = xfs_btree_read_bufs(mp, cur->bc_tp,
- cur->bc_private.i.agno, lbno, 0, &lbp,
- XFS_INO_BTREE_REF)))
- return error;
- left = XFS_BUF_TO_INOBT_BLOCK(lbp);
- lrecs = be16_to_cpu(left->bb_numrecs);
- if ((error = xfs_btree_check_sblock(cur, left, level, lbp)))
- return error;
- }
- /*
- * If that won't work, see if we can join with the right neighbor block.
- */
- else if (rbno != NULLAGBLOCK &&
- rrecs + numrecs <= XFS_INOBT_BLOCK_MAXRECS(level, cur)) {
- /*
- * Set "left" to be the starting block,
- * "right" to be the right neighbor.
- */
- lbno = bno;
- left = block;
- lrecs = be16_to_cpu(left->bb_numrecs);
- lbp = bp;
- if ((error = xfs_btree_read_bufs(mp, cur->bc_tp,
- cur->bc_private.i.agno, rbno, 0, &rbp,
- XFS_INO_BTREE_REF)))
- return error;
- right = XFS_BUF_TO_INOBT_BLOCK(rbp);
- rrecs = be16_to_cpu(right->bb_numrecs);
- if ((error = xfs_btree_check_sblock(cur, right, level, rbp)))
- return error;
- }
- /*
- * Otherwise, we can't fix the imbalance.
- * Just return. This is probably a logic error, but it's not fatal.
- */
- else {
- if (level > 0 && (error = xfs_inobt_decrement(cur, level, &i)))
- return error;
- *stat = 1;
- return 0;
- }
- /*
- * We're now going to join "left" and "right" by moving all the stuff
- * in "right" to "left" and deleting "right".
- */
- if (level > 0) {
- /*
- * It's a non-leaf. Move keys and pointers.
- */
- lkp = XFS_INOBT_KEY_ADDR(left, lrecs + 1, cur);
- lpp = XFS_INOBT_PTR_ADDR(left, lrecs + 1, cur);
- rkp = XFS_INOBT_KEY_ADDR(right, 1, cur);
- rpp = XFS_INOBT_PTR_ADDR(right, 1, cur);
-#ifdef DEBUG
- for (i = 0; i < rrecs; i++) {
- if ((error = xfs_btree_check_sptr(cur, be32_to_cpu(rpp[i]), level)))
- return error;
- }
-#endif
- memcpy(lkp, rkp, rrecs * sizeof(*lkp));
- memcpy(lpp, rpp, rrecs * sizeof(*lpp));
- xfs_inobt_log_keys(cur, lbp, lrecs + 1, lrecs + rrecs);
- xfs_inobt_log_ptrs(cur, lbp, lrecs + 1, lrecs + rrecs);
- } else {
- /*
- * It's a leaf. Move records.
- */
- lrp = XFS_INOBT_REC_ADDR(left, lrecs + 1, cur);
- rrp = XFS_INOBT_REC_ADDR(right, 1, cur);
- memcpy(lrp, rrp, rrecs * sizeof(*lrp));
- xfs_inobt_log_recs(cur, lbp, lrecs + 1, lrecs + rrecs);
- }
- /*
- * If we joined with the left neighbor, set the buffer in the
- * cursor to the left block, and fix up the index.
- */
- if (bp != lbp) {
- xfs_btree_setbuf(cur, level, lbp);
- cur->bc_ptrs[level] += lrecs;
- }
- /*
- * If we joined with the right neighbor and there's a level above
- * us, increment the cursor at that level.
- */
- else if (level + 1 < cur->bc_nlevels &&
- (error = xfs_alloc_increment(cur, level + 1, &i)))
- return error;
- /*
- * Fix up the number of records in the surviving block.
- */
- lrecs += rrecs;
- left->bb_numrecs = cpu_to_be16(lrecs);
- /*
- * Fix up the right block pointer in the surviving block, and log it.
- */
- left->bb_rightsib = right->bb_rightsib;
- xfs_inobt_log_block(cur->bc_tp, lbp, XFS_BB_NUMRECS | XFS_BB_RIGHTSIB);
- /*
- * If there is a right sibling now, make it point to the
- * remaining block.
- */
- if (be32_to_cpu(left->bb_rightsib) != NULLAGBLOCK) {
- xfs_inobt_block_t *rrblock;
- xfs_buf_t *rrbp;
-
- if ((error = xfs_btree_read_bufs(mp, cur->bc_tp,
- cur->bc_private.i.agno, be32_to_cpu(left->bb_rightsib), 0,
- &rrbp, XFS_INO_BTREE_REF)))
- return error;
- rrblock = XFS_BUF_TO_INOBT_BLOCK(rrbp);
- if ((error = xfs_btree_check_sblock(cur, rrblock, level, rrbp)))
- return error;
- rrblock->bb_leftsib = cpu_to_be32(lbno);
- xfs_inobt_log_block(cur->bc_tp, rrbp, XFS_BB_LEFTSIB);
- }
- /*
- * Free the deleting block.
- */
- if ((error = xfs_free_extent(cur->bc_tp, XFS_AGB_TO_FSB(mp,
- cur->bc_private.i.agno, rbno), 1)))
- return error;
- xfs_trans_binval(cur->bc_tp, rbp);
- /*
- * Readjust the ptr at this level if it's not a leaf, since it's
- * still pointing at the deletion point, which makes the cursor
- * inconsistent. If this makes the ptr 0, the caller fixes it up.
- * We can't use decrement because it would change the next level up.
- */
- if (level > 0)
- cur->bc_ptrs[level]--;
- /*
- * Return value means the next level up has something to do.
- */
- *stat = 2;
- return 0;
-
-error0:
- xfs_btree_del_cursor(tcur, XFS_BTREE_ERROR);
- return error;
-}
-
-/*
- * Insert one record/level. Return information to the caller
- * allowing the next level up to proceed if necessary.
- */
-STATIC int /* error */
-xfs_inobt_insrec(
- xfs_btree_cur_t *cur, /* btree cursor */
- int level, /* level to insert record at */
- xfs_agblock_t *bnop, /* i/o: block number inserted */
- xfs_inobt_rec_t *recp, /* i/o: record data inserted */
- xfs_btree_cur_t **curp, /* output: new cursor replacing cur */
- int *stat) /* success/failure */
-{
- xfs_inobt_block_t *block; /* btree block record/key lives in */
- xfs_buf_t *bp; /* buffer for block */
- int error; /* error return value */
- int i; /* loop index */
- xfs_inobt_key_t key; /* key value being inserted */
- xfs_inobt_key_t *kp=NULL; /* pointer to btree keys */
- xfs_agblock_t nbno; /* block number of allocated block */
- xfs_btree_cur_t *ncur; /* new cursor to be used at next lvl */
- xfs_inobt_key_t nkey; /* new key value, from split */
- xfs_inobt_rec_t nrec; /* new record value, for caller */
- int numrecs;
- int optr; /* old ptr value */
- xfs_inobt_ptr_t *pp; /* pointer to btree addresses */
- int ptr; /* index in btree block for this rec */
- xfs_inobt_rec_t *rp=NULL; /* pointer to btree records */
-
- /*
- * GCC doesn't understand the (arguably complex) control flow in
- * this function and complains about uninitialized structure fields
- * without this.
- */
- memset(&nrec, 0, sizeof(nrec));
-
- /*
- * If we made it to the root level, allocate a new root block
- * and we're done.
- */
- if (level >= cur->bc_nlevels) {
- error = xfs_inobt_newroot(cur, &i);
- *bnop = NULLAGBLOCK;
- *stat = i;
- return error;
- }
- /*
- * Make a key out of the record data to be inserted, and save it.
- */
- key.ir_startino = recp->ir_startino; /* INT_: direct copy */
- optr = ptr = cur->bc_ptrs[level];
- /*
- * If we're off the left edge, return failure.
- */
- if (ptr == 0) {
- *stat = 0;
- return 0;
- }
- /*
- * Get pointers to the btree buffer and block.
- */
- bp = cur->bc_bufs[level];
- block = XFS_BUF_TO_INOBT_BLOCK(bp);
- numrecs = be16_to_cpu(block->bb_numrecs);
-#ifdef DEBUG
- if ((error = xfs_btree_check_sblock(cur, block, level, bp)))
- return error;
- /*
- * Check that the new entry is being inserted in the right place.
- */
- if (ptr <= numrecs) {
- if (level == 0) {
- rp = XFS_INOBT_REC_ADDR(block, ptr, cur);
- xfs_btree_check_rec(cur->bc_btnum, recp, rp);
- } else {
- kp = XFS_INOBT_KEY_ADDR(block, ptr, cur);
- xfs_btree_check_key(cur->bc_btnum, &key, kp);
- }
- }
-#endif
- nbno = NULLAGBLOCK;
- ncur = (xfs_btree_cur_t *)0;
- /*
- * If the block is full, we can't insert the new entry until we
- * make the block un-full.
- */
- if (numrecs == XFS_INOBT_BLOCK_MAXRECS(level, cur)) {
- /*
- * First, try shifting an entry to the right neighbor.
- */
- if ((error = xfs_inobt_rshift(cur, level, &i)))
- return error;
- if (i) {
- /* nothing */
- }
- /*
- * Next, try shifting an entry to the left neighbor.
- */
- else {
- if ((error = xfs_inobt_lshift(cur, level, &i)))
- return error;
- if (i) {
- optr = ptr = cur->bc_ptrs[level];
- } else {
- /*
- * Next, try splitting the current block
- * in half. If this works we have to
- * re-set our variables because
- * we could be in a different block now.
- */
- if ((error = xfs_inobt_split(cur, level, &nbno,
- &nkey, &ncur, &i)))
- return error;
- if (i) {
- bp = cur->bc_bufs[level];
- block = XFS_BUF_TO_INOBT_BLOCK(bp);
-#ifdef DEBUG
- if ((error = xfs_btree_check_sblock(cur,
- block, level, bp)))
- return error;
-#endif
- ptr = cur->bc_ptrs[level];
- nrec.ir_startino = nkey.ir_startino; /* INT_: direct copy */
- } else {
- /*
- * Otherwise the insert fails.
- */
- *stat = 0;
- return 0;
- }
- }
- }
- }
- /*
- * At this point we know there's room for our new entry in the block
- * we're pointing at.
- */
- numrecs = be16_to_cpu(block->bb_numrecs);
- if (level > 0) {
- /*
- * It's a non-leaf entry. Make a hole for the new data
- * in the key and ptr regions of the block.
- */
- kp = XFS_INOBT_KEY_ADDR(block, 1, cur);
- pp = XFS_INOBT_PTR_ADDR(block, 1, cur);
-#ifdef DEBUG
- for (i = numrecs; i >= ptr; i--) {
- if ((error = xfs_btree_check_sptr(cur, be32_to_cpu(pp[i - 1]), level)))
- return error;
- }
-#endif
- memmove(&kp[ptr], &kp[ptr - 1],
- (numrecs - ptr + 1) * sizeof(*kp));
- memmove(&pp[ptr], &pp[ptr - 1],
- (numrecs - ptr + 1) * sizeof(*pp));
- /*
- * Now stuff the new data in, bump numrecs and log the new data.
- */
-#ifdef DEBUG
- if ((error = xfs_btree_check_sptr(cur, *bnop, level)))
- return error;
-#endif
- kp[ptr - 1] = key; /* INT_: struct copy */
- pp[ptr - 1] = cpu_to_be32(*bnop);
- numrecs++;
- block->bb_numrecs = cpu_to_be16(numrecs);
- xfs_inobt_log_keys(cur, bp, ptr, numrecs);
- xfs_inobt_log_ptrs(cur, bp, ptr, numrecs);
- } else {
- /*
- * It's a leaf entry. Make a hole for the new record.
- */
- rp = XFS_INOBT_REC_ADDR(block, 1, cur);
- memmove(&rp[ptr], &rp[ptr - 1],
- (numrecs - ptr + 1) * sizeof(*rp));
- /*
- * Now stuff the new record in, bump numrecs
- * and log the new data.
- */
- rp[ptr - 1] = *recp; /* INT_: struct copy */
- numrecs++;
- block->bb_numrecs = cpu_to_be16(numrecs);
- xfs_inobt_log_recs(cur, bp, ptr, numrecs);
- }
- /*
- * Log the new number of records in the btree header.
- */
- xfs_inobt_log_block(cur->bc_tp, bp, XFS_BB_NUMRECS);
-#ifdef DEBUG
- /*
- * Check that the key/record is in the right place, now.
- */
- if (ptr < numrecs) {
- if (level == 0)
- xfs_btree_check_rec(cur->bc_btnum, rp + ptr - 1,
- rp + ptr);
- else
- xfs_btree_check_key(cur->bc_btnum, kp + ptr - 1,
- kp + ptr);
- }
-#endif
- /*
- * If we inserted at the start of a block, update the parents' keys.
- */
- if (optr == 1 && (error = xfs_inobt_updkey(cur, &key, level + 1)))
- return error;
- /*
- * Return the new block number, if any.
- * If there is one, give back a record value and a cursor too.
- */
- *bnop = nbno;
- if (nbno != NULLAGBLOCK) {
- *recp = nrec; /* INT_: struct copy */
- *curp = ncur;
- }
- *stat = 1;
- return 0;
-}
-
-/*
- * Log header fields from a btree block.
- */
-STATIC void
-xfs_inobt_log_block(
- xfs_trans_t *tp, /* transaction pointer */
- xfs_buf_t *bp, /* buffer containing btree block */
- int fields) /* mask of fields: XFS_BB_... */
-{
- int first; /* first byte offset logged */
- int last; /* last byte offset logged */
- static const short offsets[] = { /* table of offsets */
- offsetof(xfs_inobt_block_t, bb_magic),
- offsetof(xfs_inobt_block_t, bb_level),
- offsetof(xfs_inobt_block_t, bb_numrecs),
- offsetof(xfs_inobt_block_t, bb_leftsib),
- offsetof(xfs_inobt_block_t, bb_rightsib),
- sizeof(xfs_inobt_block_t)
- };
-
- xfs_btree_offsets(fields, offsets, XFS_BB_NUM_BITS, &first, &last);
- xfs_trans_log_buf(tp, bp, first, last);
-}
-
-/*
- * Log keys from a btree block (nonleaf).
- */
-STATIC void
-xfs_inobt_log_keys(
- xfs_btree_cur_t *cur, /* btree cursor */
- xfs_buf_t *bp, /* buffer containing btree block */
- int kfirst, /* index of first key to log */
- int klast) /* index of last key to log */
-{
- xfs_inobt_block_t *block; /* btree block to log from */
- int first; /* first byte offset logged */
- xfs_inobt_key_t *kp; /* key pointer in btree block */
- int last; /* last byte offset logged */
-
- block = XFS_BUF_TO_INOBT_BLOCK(bp);
- kp = XFS_INOBT_KEY_ADDR(block, 1, cur);
- first = (int)((xfs_caddr_t)&kp[kfirst - 1] - (xfs_caddr_t)block);
- last = (int)(((xfs_caddr_t)&kp[klast] - 1) - (xfs_caddr_t)block);
- xfs_trans_log_buf(cur->bc_tp, bp, first, last);
-}
-
-/*
- * Log block pointer fields from a btree block (nonleaf).
- */
-STATIC void
-xfs_inobt_log_ptrs(
- xfs_btree_cur_t *cur, /* btree cursor */
- xfs_buf_t *bp, /* buffer containing btree block */
- int pfirst, /* index of first pointer to log */
- int plast) /* index of last pointer to log */
-{
- xfs_inobt_block_t *block; /* btree block to log from */
- int first; /* first byte offset logged */
- int last; /* last byte offset logged */
- xfs_inobt_ptr_t *pp; /* block-pointer pointer in btree blk */
-
- block = XFS_BUF_TO_INOBT_BLOCK(bp);
- pp = XFS_INOBT_PTR_ADDR(block, 1, cur);
- first = (int)((xfs_caddr_t)&pp[pfirst - 1] - (xfs_caddr_t)block);
- last = (int)(((xfs_caddr_t)&pp[plast] - 1) - (xfs_caddr_t)block);
- xfs_trans_log_buf(cur->bc_tp, bp, first, last);
-}
-
-/*
- * Log records from a btree block (leaf).
- */
-STATIC void
-xfs_inobt_log_recs(
- xfs_btree_cur_t *cur, /* btree cursor */
- xfs_buf_t *bp, /* buffer containing btree block */
- int rfirst, /* index of first record to log */
- int rlast) /* index of last record to log */
-{
- xfs_inobt_block_t *block; /* btree block to log from */
- int first; /* first byte offset logged */
- int last; /* last byte offset logged */
- xfs_inobt_rec_t *rp; /* record pointer for btree block */
-
- block = XFS_BUF_TO_INOBT_BLOCK(bp);
- rp = XFS_INOBT_REC_ADDR(block, 1, cur);
- first = (int)((xfs_caddr_t)&rp[rfirst - 1] - (xfs_caddr_t)block);
- last = (int)(((xfs_caddr_t)&rp[rlast] - 1) - (xfs_caddr_t)block);
- xfs_trans_log_buf(cur->bc_tp, bp, first, last);
-}
-
-/*
- * Lookup the record. The cursor is made to point to it, based on dir.
- * Return 0 if can't find any such record, 1 for success.
- */
-STATIC int /* error */
-xfs_inobt_lookup(
- xfs_btree_cur_t *cur, /* btree cursor */
- xfs_lookup_t dir, /* <=, ==, or >= */
- int *stat) /* success/failure */
-{
- xfs_agblock_t agbno; /* a.g. relative btree block number */
- xfs_agnumber_t agno; /* allocation group number */
- xfs_inobt_block_t *block=NULL; /* current btree block */
- __int64_t diff; /* difference for the current key */
- int error; /* error return value */
- int keyno=0; /* current key number */
- int level; /* level in the btree */
- xfs_mount_t *mp; /* file system mount point */
-
- /*
- * Get the allocation group header, and the root block number.
- */
- mp = cur->bc_mp;
- {
- xfs_agi_t *agi; /* a.g. inode header */
-
- agi = XFS_BUF_TO_AGI(cur->bc_private.i.agbp);
- agno = be32_to_cpu(agi->agi_seqno);
- agbno = be32_to_cpu(agi->agi_root);
- }
- /*
- * Iterate over each level in the btree, starting at the root.
- * For each level above the leaves, find the key we need, based
- * on the lookup record, then follow the corresponding block
- * pointer down to the next level.
- */
- for (level = cur->bc_nlevels - 1, diff = 1; level >= 0; level--) {
- xfs_buf_t *bp; /* buffer pointer for btree block */
- xfs_daddr_t d; /* disk address of btree block */
-
- /*
- * Get the disk address we're looking for.
- */
- d = XFS_AGB_TO_DADDR(mp, agno, agbno);
- /*
- * If the old buffer at this level is for a different block,
- * throw it away, otherwise just use it.
- */
- bp = cur->bc_bufs[level];
- if (bp && XFS_BUF_ADDR(bp) != d)
- bp = (xfs_buf_t *)0;
- if (!bp) {
- /*
- * Need to get a new buffer. Read it, then
- * set it in the cursor, releasing the old one.
- */
- if ((error = xfs_btree_read_bufs(mp, cur->bc_tp,
- agno, agbno, 0, &bp, XFS_INO_BTREE_REF)))
- return error;
- xfs_btree_setbuf(cur, level, bp);
- /*
- * Point to the btree block, now that we have the buffer
- */
- block = XFS_BUF_TO_INOBT_BLOCK(bp);
- if ((error = xfs_btree_check_sblock(cur, block, level,
- bp)))
- return error;
- } else
- block = XFS_BUF_TO_INOBT_BLOCK(bp);
- /*
- * If we already had a key match at a higher level, we know
- * we need to use the first entry in this block.
- */
- if (diff == 0)
- keyno = 1;
- /*
- * Otherwise we need to search this block. Do a binary search.
- */
- else {
- int high; /* high entry number */
- xfs_inobt_key_t *kkbase=NULL;/* base of keys in block */
- xfs_inobt_rec_t *krbase=NULL;/* base of records in block */
- int low; /* low entry number */
-
- /*
- * Get a pointer to keys or records.
- */
- if (level > 0)
- kkbase = XFS_INOBT_KEY_ADDR(block, 1, cur);
- else
- krbase = XFS_INOBT_REC_ADDR(block, 1, cur);
- /*
- * Set low and high entry numbers, 1-based.
- */
- low = 1;
- if (!(high = be16_to_cpu(block->bb_numrecs))) {
- /*
- * If the block is empty, the tree must
- * be an empty leaf.
- */
- ASSERT(level == 0 && cur->bc_nlevels == 1);
- cur->bc_ptrs[0] = dir != XFS_LOOKUP_LE;
- *stat = 0;
- return 0;
- }
- /*
- * Binary search the block.
- */
- while (low <= high) {
- xfs_agino_t startino; /* key value */
-
- /*
- * keyno is average of low and high.
- */
- keyno = (low + high) >> 1;
- /*
- * Get startino.
- */
- if (level > 0) {
- xfs_inobt_key_t *kkp;
-
- kkp = kkbase + keyno - 1;
- startino = INT_GET(kkp->ir_startino, ARCH_CONVERT);
- } else {
- xfs_inobt_rec_t *krp;
-
- krp = krbase + keyno - 1;
- startino = INT_GET(krp->ir_startino, ARCH_CONVERT);
- }
- /*
- * Compute difference to get next direction.
- */
- diff = (__int64_t)
- startino - cur->bc_rec.i.ir_startino;
- /*
- * Less than, move right.
- */
- if (diff < 0)
- low = keyno + 1;
- /*
- * Greater than, move left.
- */
- else if (diff > 0)
- high = keyno - 1;
- /*
- * Equal, we're done.
- */
- else
- break;
- }
- }
- /*
- * If there are more levels, set up for the next level
- * by getting the block number and filling in the cursor.
- */
- if (level > 0) {
- /*
- * If we moved left, need the previous key number,
- * unless there isn't one.
- */
- if (diff > 0 && --keyno < 1)
- keyno = 1;
- agbno = be32_to_cpu(*XFS_INOBT_PTR_ADDR(block, keyno, cur));
-#ifdef DEBUG
- if ((error = xfs_btree_check_sptr(cur, agbno, level)))
- return error;
-#endif
- cur->bc_ptrs[level] = keyno;
- }
- }
- /*
- * Done with the search.
- * See if we need to adjust the results.
- */
- if (dir != XFS_LOOKUP_LE && diff < 0) {
- keyno++;
- /*
- * If ge search and we went off the end of the block, but it's
- * not the last block, we're in the wrong block.
- */
- if (dir == XFS_LOOKUP_GE &&
- keyno > be16_to_cpu(block->bb_numrecs) &&
- be32_to_cpu(block->bb_rightsib) != NULLAGBLOCK) {
- int i;
-
- cur->bc_ptrs[0] = keyno;
- if ((error = xfs_inobt_increment(cur, 0, &i)))
- return error;
- ASSERT(i == 1);
- *stat = 1;
- return 0;
- }
- }
- else if (dir == XFS_LOOKUP_LE && diff > 0)
- keyno--;
- cur->bc_ptrs[0] = keyno;
- /*
- * Return if we succeeded or not.
- */
- if (keyno == 0 || keyno > be16_to_cpu(block->bb_numrecs))
- *stat = 0;
- else
- *stat = ((dir != XFS_LOOKUP_EQ) || (diff == 0));
- return 0;
-}
-
-/*
- * Move 1 record left from cur/level if possible.
- * Update cur to reflect the new path.
- */
-STATIC int /* error */
-xfs_inobt_lshift(
- xfs_btree_cur_t *cur, /* btree cursor */
- int level, /* level to shift record on */
- int *stat) /* success/failure */
-{
- int error; /* error return value */
-#ifdef DEBUG
- int i; /* loop index */
-#endif
- xfs_inobt_key_t key; /* key value for leaf level upward */
- xfs_buf_t *lbp; /* buffer for left neighbor block */
- xfs_inobt_block_t *left; /* left neighbor btree block */
- xfs_inobt_key_t *lkp=NULL; /* key pointer for left block */
- xfs_inobt_ptr_t *lpp; /* address pointer for left block */
- xfs_inobt_rec_t *lrp=NULL; /* record pointer for left block */
- int nrec; /* new number of left block entries */
- xfs_buf_t *rbp; /* buffer for right (current) block */
- xfs_inobt_block_t *right; /* right (current) btree block */
- xfs_inobt_key_t *rkp=NULL; /* key pointer for right block */
- xfs_inobt_ptr_t *rpp=NULL; /* address pointer for right block */
- xfs_inobt_rec_t *rrp=NULL; /* record pointer for right block */
-
- /*
- * Set up variables for this block as "right".
- */
- rbp = cur->bc_bufs[level];
- right = XFS_BUF_TO_INOBT_BLOCK(rbp);
-#ifdef DEBUG
- if ((error = xfs_btree_check_sblock(cur, right, level, rbp)))
- return error;
-#endif
- /*
- * If we've got no left sibling then we can't shift an entry left.
- */
- if (be32_to_cpu(right->bb_leftsib) == NULLAGBLOCK) {
- *stat = 0;
- return 0;
- }
- /*
- * If the cursor entry is the one that would be moved, don't
- * do it... it's too complicated.
- */
- if (cur->bc_ptrs[level] <= 1) {
- *stat = 0;
- return 0;
- }
- /*
- * Set up the left neighbor as "left".
- */
- if ((error = xfs_btree_read_bufs(cur->bc_mp, cur->bc_tp,
- cur->bc_private.i.agno, be32_to_cpu(right->bb_leftsib),
- 0, &lbp, XFS_INO_BTREE_REF)))
- return error;
- left = XFS_BUF_TO_INOBT_BLOCK(lbp);
- if ((error = xfs_btree_check_sblock(cur, left, level, lbp)))
- return error;
- /*
- * If it's full, it can't take another entry.
- */
- if (be16_to_cpu(left->bb_numrecs) == XFS_INOBT_BLOCK_MAXRECS(level, cur)) {
- *stat = 0;
- return 0;
- }
- nrec = be16_to_cpu(left->bb_numrecs) + 1;
- /*
- * If non-leaf, copy a key and a ptr to the left block.
- */
- if (level > 0) {
- lkp = XFS_INOBT_KEY_ADDR(left, nrec, cur);
- rkp = XFS_INOBT_KEY_ADDR(right, 1, cur);
- *lkp = *rkp;
- xfs_inobt_log_keys(cur, lbp, nrec, nrec);
- lpp = XFS_INOBT_PTR_ADDR(left, nrec, cur);
- rpp = XFS_INOBT_PTR_ADDR(right, 1, cur);
-#ifdef DEBUG
- if ((error = xfs_btree_check_sptr(cur, be32_to_cpu(*rpp), level)))
- return error;
-#endif
- *lpp = *rpp; /* INT_: no-change copy */
- xfs_inobt_log_ptrs(cur, lbp, nrec, nrec);
- }
- /*
- * If leaf, copy a record to the left block.
- */
- else {
- lrp = XFS_INOBT_REC_ADDR(left, nrec, cur);
- rrp = XFS_INOBT_REC_ADDR(right, 1, cur);
- *lrp = *rrp;
- xfs_inobt_log_recs(cur, lbp, nrec, nrec);
- }
- /*
- * Bump and log left's numrecs, decrement and log right's numrecs.
- */
- be16_add(&left->bb_numrecs, 1);
- xfs_inobt_log_block(cur->bc_tp, lbp, XFS_BB_NUMRECS);
-#ifdef DEBUG
- if (level > 0)
- xfs_btree_check_key(cur->bc_btnum, lkp - 1, lkp);
- else
- xfs_btree_check_rec(cur->bc_btnum, lrp - 1, lrp);
-#endif
- be16_add(&right->bb_numrecs, -1);
- xfs_inobt_log_block(cur->bc_tp, rbp, XFS_BB_NUMRECS);
- /*
- * Slide the contents of right down one entry.
- */
- if (level > 0) {
-#ifdef DEBUG
- for (i = 0; i < be16_to_cpu(right->bb_numrecs); i++) {
- if ((error = xfs_btree_check_sptr(cur, be32_to_cpu(rpp[i + 1]),
- level)))
- return error;
- }
-#endif
- memmove(rkp, rkp + 1, be16_to_cpu(right->bb_numrecs) * sizeof(*rkp));
- memmove(rpp, rpp + 1, be16_to_cpu(right->bb_numrecs) * sizeof(*rpp));
- xfs_inobt_log_keys(cur, rbp, 1, be16_to_cpu(right->bb_numrecs));
- xfs_inobt_log_ptrs(cur, rbp, 1, be16_to_cpu(right->bb_numrecs));
- } else {
- memmove(rrp, rrp + 1, be16_to_cpu(right->bb_numrecs) * sizeof(*rrp));
- xfs_inobt_log_recs(cur, rbp, 1, be16_to_cpu(right->bb_numrecs));
- key.ir_startino = rrp->ir_startino; /* INT_: direct copy */
- rkp = &key;
- }
- /*
- * Update the parent key values of right.
- */
- if ((error = xfs_inobt_updkey(cur, rkp, level + 1)))
- return error;
- /*
- * Slide the cursor value left one.
- */
- cur->bc_ptrs[level]--;
- *stat = 1;
- return 0;
-}
-
-/*
- * Allocate a new root block, fill it in.
- */
-STATIC int /* error */
-xfs_inobt_newroot(
- xfs_btree_cur_t *cur, /* btree cursor */
- int *stat) /* success/failure */
-{
- xfs_agi_t *agi; /* a.g. inode header */
- xfs_alloc_arg_t args; /* allocation argument structure */
- xfs_inobt_block_t *block; /* one half of the old root block */
- xfs_buf_t *bp; /* buffer containing block */
- int error; /* error return value */
- xfs_inobt_key_t *kp; /* btree key pointer */
- xfs_agblock_t lbno; /* left block number */
- xfs_buf_t *lbp; /* left buffer pointer */
- xfs_inobt_block_t *left; /* left btree block */
- xfs_buf_t *nbp; /* new (root) buffer */
- xfs_inobt_block_t *new; /* new (root) btree block */
- int nptr; /* new value for key index, 1 or 2 */
- xfs_inobt_ptr_t *pp; /* btree address pointer */
- xfs_agblock_t rbno; /* right block number */
- xfs_buf_t *rbp; /* right buffer pointer */
- xfs_inobt_block_t *right; /* right btree block */
- xfs_inobt_rec_t *rp; /* btree record pointer */
-
- ASSERT(cur->bc_nlevels < XFS_IN_MAXLEVELS(cur->bc_mp));
-
- /*
- * Get a block & a buffer.
- */
- agi = XFS_BUF_TO_AGI(cur->bc_private.i.agbp);
- args.tp = cur->bc_tp;
- args.mp = cur->bc_mp;
- args.fsbno = XFS_AGB_TO_FSB(args.mp, cur->bc_private.i.agno,
- be32_to_cpu(agi->agi_root));
- args.mod = args.minleft = args.alignment = args.total = args.wasdel =
- args.isfl = args.userdata = args.minalignslop = 0;
- args.minlen = args.maxlen = args.prod = 1;
- args.type = XFS_ALLOCTYPE_NEAR_BNO;
- if ((error = xfs_alloc_vextent(&args)))
- return error;
- /*
- * None available, we fail.
- */
- if (args.fsbno == NULLFSBLOCK) {
- *stat = 0;
- return 0;
- }
- ASSERT(args.len == 1);
- nbp = xfs_btree_get_bufs(args.mp, args.tp, args.agno, args.agbno, 0);
- new = XFS_BUF_TO_INOBT_BLOCK(nbp);
- /*
- * Set the root data in the a.g. inode structure.
- */
- agi->agi_root = cpu_to_be32(args.agbno);
- be32_add(&agi->agi_level, 1);
- xfs_ialloc_log_agi(args.tp, cur->bc_private.i.agbp,
- XFS_AGI_ROOT | XFS_AGI_LEVEL);
- /*
- * At the previous root level there are now two blocks: the old
- * root, and the new block generated when it was split.
- * We don't know which one the cursor is pointing at, so we
- * set up variables "left" and "right" for each case.
- */
- bp = cur->bc_bufs[cur->bc_nlevels - 1];
- block = XFS_BUF_TO_INOBT_BLOCK(bp);
-#ifdef DEBUG
- if ((error = xfs_btree_check_sblock(cur, block, cur->bc_nlevels - 1, bp)))
- return error;
-#endif
- if (be32_to_cpu(block->bb_rightsib) != NULLAGBLOCK) {
- /*
- * Our block is left, pick up the right block.
- */
- lbp = bp;
- lbno = XFS_DADDR_TO_AGBNO(args.mp, XFS_BUF_ADDR(lbp));
- left = block;
- rbno = be32_to_cpu(left->bb_rightsib);
- if ((error = xfs_btree_read_bufs(args.mp, args.tp, args.agno,
- rbno, 0, &rbp, XFS_INO_BTREE_REF)))
- return error;
- bp = rbp;
- right = XFS_BUF_TO_INOBT_BLOCK(rbp);
- if ((error = xfs_btree_check_sblock(cur, right,
- cur->bc_nlevels - 1, rbp)))
- return error;
- nptr = 1;
- } else {
- /*
- * Our block is right, pick up the left block.
- */
- rbp = bp;
- rbno = XFS_DADDR_TO_AGBNO(args.mp, XFS_BUF_ADDR(rbp));
- right = block;
- lbno = be32_to_cpu(right->bb_leftsib);
- if ((error = xfs_btree_read_bufs(args.mp, args.tp, args.agno,
- lbno, 0, &lbp, XFS_INO_BTREE_REF)))
- return error;
- bp = lbp;
- left = XFS_BUF_TO_INOBT_BLOCK(lbp);
- if ((error = xfs_btree_check_sblock(cur, left,
- cur->bc_nlevels - 1, lbp)))
- return error;
- nptr = 2;
- }
- /*
- * Fill in the new block's btree header and log it.
- */
- new->bb_magic = cpu_to_be32(xfs_magics[cur->bc_btnum]);
- new->bb_level = cpu_to_be16(cur->bc_nlevels);
- new->bb_numrecs = cpu_to_be16(2);
- new->bb_leftsib = cpu_to_be32(NULLAGBLOCK);
- new->bb_rightsib = cpu_to_be32(NULLAGBLOCK);
- xfs_inobt_log_block(args.tp, nbp, XFS_BB_ALL_BITS);
- ASSERT(lbno != NULLAGBLOCK && rbno != NULLAGBLOCK);
- /*
- * Fill in the key data in the new root.
- */
- kp = XFS_INOBT_KEY_ADDR(new, 1, cur);
- if (be16_to_cpu(left->bb_level) > 0) {
- kp[0] = *XFS_INOBT_KEY_ADDR(left, 1, cur); /* INT_: struct copy */
- kp[1] = *XFS_INOBT_KEY_ADDR(right, 1, cur); /* INT_: struct copy */
- } else {
- rp = XFS_INOBT_REC_ADDR(left, 1, cur);
- INT_COPY(kp[0].ir_startino, rp->ir_startino, ARCH_CONVERT);
- rp = XFS_INOBT_REC_ADDR(right, 1, cur);
- INT_COPY(kp[1].ir_startino, rp->ir_startino, ARCH_CONVERT);
- }
- xfs_inobt_log_keys(cur, nbp, 1, 2);
- /*
- * Fill in the pointer data in the new root.
- */
- pp = XFS_INOBT_PTR_ADDR(new, 1, cur);
- pp[0] = cpu_to_be32(lbno);
- pp[1] = cpu_to_be32(rbno);
- xfs_inobt_log_ptrs(cur, nbp, 1, 2);
- /*
- * Fix up the cursor.
- */
- xfs_btree_setbuf(cur, cur->bc_nlevels, nbp);
- cur->bc_ptrs[cur->bc_nlevels] = nptr;
- cur->bc_nlevels++;
- *stat = 1;
- return 0;
-}
-
-/*
- * Move 1 record right from cur/level if possible.
- * Update cur to reflect the new path.
- */
-STATIC int /* error */
-xfs_inobt_rshift(
- xfs_btree_cur_t *cur, /* btree cursor */
- int level, /* level to shift record on */
- int *stat) /* success/failure */
-{
- int error; /* error return value */
- int i; /* loop index */
- xfs_inobt_key_t key; /* key value for leaf level upward */
- xfs_buf_t *lbp; /* buffer for left (current) block */
- xfs_inobt_block_t *left; /* left (current) btree block */
- xfs_inobt_key_t *lkp; /* key pointer for left block */
- xfs_inobt_ptr_t *lpp; /* address pointer for left block */
- xfs_inobt_rec_t *lrp; /* record pointer for left block */
- xfs_buf_t *rbp; /* buffer for right neighbor block */
- xfs_inobt_block_t *right; /* right neighbor btree block */
- xfs_inobt_key_t *rkp; /* key pointer for right block */
- xfs_inobt_ptr_t *rpp; /* address pointer for right block */
- xfs_inobt_rec_t *rrp=NULL; /* record pointer for right block */
- xfs_btree_cur_t *tcur; /* temporary cursor */
-
- /*
- * Set up variables for this block as "left".
- */
- lbp = cur->bc_bufs[level];
- left = XFS_BUF_TO_INOBT_BLOCK(lbp);
-#ifdef DEBUG
- if ((error = xfs_btree_check_sblock(cur, left, level, lbp)))
- return error;
-#endif
- /*
- * If we've got no right sibling then we can't shift an entry right.
- */
- if (be32_to_cpu(left->bb_rightsib) == NULLAGBLOCK) {
- *stat = 0;
- return 0;
- }
- /*
- * If the cursor entry is the one that would be moved, don't
- * do it... it's too complicated.
- */
- if (cur->bc_ptrs[level] >= be16_to_cpu(left->bb_numrecs)) {
- *stat = 0;
- return 0;
- }
- /*
- * Set up the right neighbor as "right".
- */
- if ((error = xfs_btree_read_bufs(cur->bc_mp, cur->bc_tp,
- cur->bc_private.i.agno, be32_to_cpu(left->bb_rightsib),
- 0, &rbp, XFS_INO_BTREE_REF)))
- return error;
- right = XFS_BUF_TO_INOBT_BLOCK(rbp);
- if ((error = xfs_btree_check_sblock(cur, right, level, rbp)))
- return error;
- /*
- * If it's full, it can't take another entry.
- */
- if (be16_to_cpu(right->bb_numrecs) == XFS_INOBT_BLOCK_MAXRECS(level, cur)) {
- *stat = 0;
- return 0;
- }
- /*
- * Make a hole at the start of the right neighbor block, then
- * copy the last left block entry to the hole.
- */
- if (level > 0) {
- lkp = XFS_INOBT_KEY_ADDR(left, be16_to_cpu(left->bb_numrecs), cur);
- lpp = XFS_INOBT_PTR_ADDR(left, be16_to_cpu(left->bb_numrecs), cur);
- rkp = XFS_INOBT_KEY_ADDR(right, 1, cur);
- rpp = XFS_INOBT_PTR_ADDR(right, 1, cur);
-#ifdef DEBUG
- for (i = be16_to_cpu(right->bb_numrecs) - 1; i >= 0; i--) {
- if ((error = xfs_btree_check_sptr(cur, be32_to_cpu(rpp[i]), level)))
- return error;
- }
-#endif
- memmove(rkp + 1, rkp, be16_to_cpu(right->bb_numrecs) * sizeof(*rkp));
- memmove(rpp + 1, rpp, be16_to_cpu(right->bb_numrecs) * sizeof(*rpp));
-#ifdef DEBUG
- if ((error = xfs_btree_check_sptr(cur, be32_to_cpu(*lpp), level)))
- return error;
-#endif
- *rkp = *lkp; /* INT_: no change copy */
- *rpp = *lpp; /* INT_: no change copy */
- xfs_inobt_log_keys(cur, rbp, 1, be16_to_cpu(right->bb_numrecs) + 1);
- xfs_inobt_log_ptrs(cur, rbp, 1, be16_to_cpu(right->bb_numrecs) + 1);
- } else {
- lrp = XFS_INOBT_REC_ADDR(left, be16_to_cpu(left->bb_numrecs), cur);
- rrp = XFS_INOBT_REC_ADDR(right, 1, cur);
- memmove(rrp + 1, rrp, be16_to_cpu(right->bb_numrecs) * sizeof(*rrp));
- *rrp = *lrp;
- xfs_inobt_log_recs(cur, rbp, 1, be16_to_cpu(right->bb_numrecs) + 1);
- key.ir_startino = rrp->ir_startino; /* INT_: direct copy */
- rkp = &key;
- }
- /*
- * Decrement and log left's numrecs, bump and log right's numrecs.
- */
- be16_add(&left->bb_numrecs, -1);
- xfs_inobt_log_block(cur->bc_tp, lbp, XFS_BB_NUMRECS);
- be16_add(&right->bb_numrecs, 1);
-#ifdef DEBUG
- if (level > 0)
- xfs_btree_check_key(cur->bc_btnum, rkp, rkp + 1);
- else
- xfs_btree_check_rec(cur->bc_btnum, rrp, rrp + 1);
-#endif
- xfs_inobt_log_block(cur->bc_tp, rbp, XFS_BB_NUMRECS);
- /*
- * Using a temporary cursor, update the parent key values of the
- * block on the right.
- */
- if ((error = xfs_btree_dup_cursor(cur, &tcur)))
- return error;
- xfs_btree_lastrec(tcur, level);
- if ((error = xfs_inobt_increment(tcur, level, &i)) ||
- (error = xfs_inobt_updkey(tcur, rkp, level + 1))) {
- xfs_btree_del_cursor(tcur, XFS_BTREE_ERROR);
- return error;
- }
- xfs_btree_del_cursor(tcur, XFS_BTREE_NOERROR);
- *stat = 1;
- return 0;
-}
-
-/*
- * Split cur/level block in half.
- * Return new block number and its first record (to be inserted into parent).
- */
-STATIC int /* error */
-xfs_inobt_split(
- xfs_btree_cur_t *cur, /* btree cursor */
- int level, /* level to split */
- xfs_agblock_t *bnop, /* output: block number allocated */
- xfs_inobt_key_t *keyp, /* output: first key of new block */
- xfs_btree_cur_t **curp, /* output: new cursor */
- int *stat) /* success/failure */
-{
- xfs_alloc_arg_t args; /* allocation argument structure */
- int error; /* error return value */
- int i; /* loop index/record number */
- xfs_agblock_t lbno; /* left (current) block number */
- xfs_buf_t *lbp; /* buffer for left block */
- xfs_inobt_block_t *left; /* left (current) btree block */
- xfs_inobt_key_t *lkp; /* left btree key pointer */
- xfs_inobt_ptr_t *lpp; /* left btree address pointer */
- xfs_inobt_rec_t *lrp; /* left btree record pointer */
- xfs_buf_t *rbp; /* buffer for right block */
- xfs_inobt_block_t *right; /* right (new) btree block */
- xfs_inobt_key_t *rkp; /* right btree key pointer */
- xfs_inobt_ptr_t *rpp; /* right btree address pointer */
- xfs_inobt_rec_t *rrp; /* right btree record pointer */
-
- /*
- * Set up left block (current one).
- */
- lbp = cur->bc_bufs[level];
- args.tp = cur->bc_tp;
- args.mp = cur->bc_mp;
- lbno = XFS_DADDR_TO_AGBNO(args.mp, XFS_BUF_ADDR(lbp));
- /*
- * Allocate the new block.
- * If we can't do it, we're toast. Give up.
- */
- args.fsbno = XFS_AGB_TO_FSB(args.mp, cur->bc_private.i.agno, lbno);
- args.mod = args.minleft = args.alignment = args.total = args.wasdel =
- args.isfl = args.userdata = args.minalignslop = 0;
- args.minlen = args.maxlen = args.prod = 1;
- args.type = XFS_ALLOCTYPE_NEAR_BNO;
- if ((error = xfs_alloc_vextent(&args)))
- return error;
- if (args.fsbno == NULLFSBLOCK) {
- *stat = 0;
- return 0;
- }
- ASSERT(args.len == 1);
- rbp = xfs_btree_get_bufs(args.mp, args.tp, args.agno, args.agbno, 0);
- /*
- * Set up the new block as "right".
- */
- right = XFS_BUF_TO_INOBT_BLOCK(rbp);
- /*
- * "Left" is the current (according to the cursor) block.
- */
- left = XFS_BUF_TO_INOBT_BLOCK(lbp);
-#ifdef DEBUG
- if ((error = xfs_btree_check_sblock(cur, left, level, lbp)))
- return error;
-#endif
- /*
- * Fill in the btree header for the new block.
- */
- right->bb_magic = cpu_to_be32(xfs_magics[cur->bc_btnum]);
- right->bb_level = left->bb_level;
- right->bb_numrecs = cpu_to_be16(be16_to_cpu(left->bb_numrecs) / 2);
- /*
- * Make sure that if there's an odd number of entries now, that
- * each new block will have the same number of entries.
- */
- if ((be16_to_cpu(left->bb_numrecs) & 1) &&
- cur->bc_ptrs[level] <= be16_to_cpu(right->bb_numrecs) + 1)
- be16_add(&right->bb_numrecs, 1);
- i = be16_to_cpu(left->bb_numrecs) - be16_to_cpu(right->bb_numrecs) + 1;
- /*
- * For non-leaf blocks, copy keys and addresses over to the new block.
- */
- if (level > 0) {
- lkp = XFS_INOBT_KEY_ADDR(left, i, cur);
- lpp = XFS_INOBT_PTR_ADDR(left, i, cur);
- rkp = XFS_INOBT_KEY_ADDR(right, 1, cur);
- rpp = XFS_INOBT_PTR_ADDR(right, 1, cur);
-#ifdef DEBUG
- for (i = 0; i < be16_to_cpu(right->bb_numrecs); i++) {
- if ((error = xfs_btree_check_sptr(cur, be32_to_cpu(lpp[i]), level)))
- return error;
- }
-#endif
- memcpy(rkp, lkp, be16_to_cpu(right->bb_numrecs) * sizeof(*rkp));
- memcpy(rpp, lpp, be16_to_cpu(right->bb_numrecs) * sizeof(*rpp));
- xfs_inobt_log_keys(cur, rbp, 1, be16_to_cpu(right->bb_numrecs));
- xfs_inobt_log_ptrs(cur, rbp, 1, be16_to_cpu(right->bb_numrecs));
- *keyp = *rkp;
- }
- /*
- * For leaf blocks, copy records over to the new block.
- */
- else {
- lrp = XFS_INOBT_REC_ADDR(left, i, cur);
- rrp = XFS_INOBT_REC_ADDR(right, 1, cur);
- memcpy(rrp, lrp, be16_to_cpu(right->bb_numrecs) * sizeof(*rrp));
- xfs_inobt_log_recs(cur, rbp, 1, be16_to_cpu(right->bb_numrecs));
- keyp->ir_startino = rrp->ir_startino; /* INT_: direct copy */
- }
- /*
- * Find the left block number by looking in the buffer.
- * Adjust numrecs, sibling pointers.
- */
- be16_add(&left->bb_numrecs, -(be16_to_cpu(right->bb_numrecs)));
- right->bb_rightsib = left->bb_rightsib;
- left->bb_rightsib = cpu_to_be32(args.agbno);
- right->bb_leftsib = cpu_to_be32(lbno);
- xfs_inobt_log_block(args.tp, rbp, XFS_BB_ALL_BITS);
- xfs_inobt_log_block(args.tp, lbp, XFS_BB_NUMRECS | XFS_BB_RIGHTSIB);
- /*
- * If there's a block to the new block's right, make that block
- * point back to right instead of to left.
- */
- if (be32_to_cpu(right->bb_rightsib) != NULLAGBLOCK) {
- xfs_inobt_block_t *rrblock; /* rr btree block */
- xfs_buf_t *rrbp; /* buffer for rrblock */
-
- if ((error = xfs_btree_read_bufs(args.mp, args.tp, args.agno,
- be32_to_cpu(right->bb_rightsib), 0, &rrbp,
- XFS_INO_BTREE_REF)))
- return error;
- rrblock = XFS_BUF_TO_INOBT_BLOCK(rrbp);
- if ((error = xfs_btree_check_sblock(cur, rrblock, level, rrbp)))
- return error;
- rrblock->bb_leftsib = cpu_to_be32(args.agbno);
- xfs_inobt_log_block(args.tp, rrbp, XFS_BB_LEFTSIB);
- }
- /*
- * If the cursor is really in the right block, move it there.
- * If it's just pointing past the last entry in left, then we'll
- * insert there, so don't change anything in that case.
- */
- if (cur->bc_ptrs[level] > be16_to_cpu(left->bb_numrecs) + 1) {
- xfs_btree_setbuf(cur, level, rbp);
- cur->bc_ptrs[level] -= be16_to_cpu(left->bb_numrecs);
- }
- /*
- * If there are more levels, we'll need another cursor which refers
- * the right block, no matter where this cursor was.
- */
- if (level + 1 < cur->bc_nlevels) {
- if ((error = xfs_btree_dup_cursor(cur, curp)))
- return error;
- (*curp)->bc_ptrs[level + 1]++;
- }
- *bnop = args.agbno;
- *stat = 1;
- return 0;
-}
-
-/*
- * Update keys at all levels from here to the root along the cursor's path.
- */
-STATIC int /* error */
-xfs_inobt_updkey(
- xfs_btree_cur_t *cur, /* btree cursor */
- xfs_inobt_key_t *keyp, /* new key value to update to */
- int level) /* starting level for update */
-{
- int ptr; /* index of key in block */
-
- /*
- * Go up the tree from this level toward the root.
- * At each level, update the key value to the value input.
- * Stop when we reach a level where the cursor isn't pointing
- * at the first entry in the block.
- */
- for (ptr = 1; ptr == 1 && level < cur->bc_nlevels; level++) {
- xfs_buf_t *bp; /* buffer for block */
- xfs_inobt_block_t *block; /* btree block */
-#ifdef DEBUG
- int error; /* error return value */
-#endif
- xfs_inobt_key_t *kp; /* ptr to btree block keys */
-
- bp = cur->bc_bufs[level];
- block = XFS_BUF_TO_INOBT_BLOCK(bp);
-#ifdef DEBUG
- if ((error = xfs_btree_check_sblock(cur, block, level, bp)))
- return error;
-#endif
- ptr = cur->bc_ptrs[level];
- kp = XFS_INOBT_KEY_ADDR(block, ptr, cur);
- *kp = *keyp;
- xfs_inobt_log_keys(cur, bp, ptr, ptr);
- }
- return 0;
-}
-
-/*
- * Externally visible routines.
- */
-
-/*
- * Decrement cursor by one record at the level.
- * For nonzero levels the leaf-ward information is untouched.
- */
-int /* error */
-xfs_inobt_decrement(
- xfs_btree_cur_t *cur, /* btree cursor */
- int level, /* level in btree, 0 is leaf */
- int *stat) /* success/failure */
-{
- xfs_inobt_block_t *block; /* btree block */
- int error;
- int lev; /* btree level */
-
- ASSERT(level < cur->bc_nlevels);
- /*
- * Read-ahead to the left at this level.
- */
- xfs_btree_readahead(cur, level, XFS_BTCUR_LEFTRA);
- /*
- * Decrement the ptr at this level. If we're still in the block
- * then we're done.
- */
- if (--cur->bc_ptrs[level] > 0) {
- *stat = 1;
- return 0;
- }
- /*
- * Get a pointer to the btree block.
- */
- block = XFS_BUF_TO_INOBT_BLOCK(cur->bc_bufs[level]);
-#ifdef DEBUG
- if ((error = xfs_btree_check_sblock(cur, block, level,
- cur->bc_bufs[level])))
- return error;
-#endif
- /*
- * If we just went off the left edge of the tree, return failure.
- */
- if (be32_to_cpu(block->bb_leftsib) == NULLAGBLOCK) {
- *stat = 0;
- return 0;
- }
- /*
- * March up the tree decrementing pointers.
- * Stop when we don't go off the left edge of a block.
- */
- for (lev = level + 1; lev < cur->bc_nlevels; lev++) {
- if (--cur->bc_ptrs[lev] > 0)
- break;
- /*
- * Read-ahead the left block, we're going to read it
- * in the next loop.
- */
- xfs_btree_readahead(cur, lev, XFS_BTCUR_LEFTRA);
- }
- /*
- * If we went off the root then we are seriously confused.
- */
- ASSERT(lev < cur->bc_nlevels);
- /*
- * Now walk back down the tree, fixing up the cursor's buffer
- * pointers and key numbers.
- */
- for (block = XFS_BUF_TO_INOBT_BLOCK(cur->bc_bufs[lev]); lev > level; ) {
- xfs_agblock_t agbno; /* block number of btree block */
- xfs_buf_t *bp; /* buffer containing btree block */
-
- agbno = be32_to_cpu(*XFS_INOBT_PTR_ADDR(block, cur->bc_ptrs[lev], cur));
- if ((error = xfs_btree_read_bufs(cur->bc_mp, cur->bc_tp,
- cur->bc_private.i.agno, agbno, 0, &bp,
- XFS_INO_BTREE_REF)))
- return error;
- lev--;
- xfs_btree_setbuf(cur, lev, bp);
- block = XFS_BUF_TO_INOBT_BLOCK(bp);
- if ((error = xfs_btree_check_sblock(cur, block, lev, bp)))
- return error;
- cur->bc_ptrs[lev] = be16_to_cpu(block->bb_numrecs);
- }
- *stat = 1;
- return 0;
-}
-
-/*
- * Delete the record pointed to by cur.
- * The cursor refers to the place where the record was (could be inserted)
- * when the operation returns.
- */
-int /* error */
-xfs_inobt_delete(
- xfs_btree_cur_t *cur, /* btree cursor */
- int *stat) /* success/failure */
-{
- int error;
- int i; /* result code */
- int level; /* btree level */
-
- /*
- * Go up the tree, starting at leaf level.
- * If 2 is returned then a join was done; go to the next level.
- * Otherwise we are done.
- */
- for (level = 0, i = 2; i == 2; level++) {
- if ((error = xfs_inobt_delrec(cur, level, &i)))
- return error;
- }
- if (i == 0) {
- for (level = 1; level < cur->bc_nlevels; level++) {
- if (cur->bc_ptrs[level] == 0) {
- if ((error = xfs_inobt_decrement(cur, level, &i)))
- return error;
- break;
- }
- }
- }
- *stat = i;
- return 0;
-}
-
-
-/*
- * Get the data from the pointed-to record.
- */
-int /* error */
-xfs_inobt_get_rec(
- xfs_btree_cur_t *cur, /* btree cursor */
- xfs_agino_t *ino, /* output: starting inode of chunk */
- __int32_t *fcnt, /* output: number of free inodes */
- xfs_inofree_t *free, /* output: free inode mask */
- int *stat) /* output: success/failure */
-{
- xfs_inobt_block_t *block; /* btree block */
- xfs_buf_t *bp; /* buffer containing btree block */
-#ifdef DEBUG
- int error; /* error return value */
-#endif
- int ptr; /* record number */
- xfs_inobt_rec_t *rec; /* record data */
-
- bp = cur->bc_bufs[0];
- ptr = cur->bc_ptrs[0];
- block = XFS_BUF_TO_INOBT_BLOCK(bp);
-#ifdef DEBUG
- if ((error = xfs_btree_check_sblock(cur, block, 0, bp)))
- return error;
-#endif
- /*
- * Off the right end or left end, return failure.
- */
- if (ptr > be16_to_cpu(block->bb_numrecs) || ptr <= 0) {
- *stat = 0;
- return 0;
- }
- /*
- * Point to the record and extract its data.
- */
- rec = XFS_INOBT_REC_ADDR(block, ptr, cur);
- *ino = INT_GET(rec->ir_startino, ARCH_CONVERT);
- *fcnt = INT_GET(rec->ir_freecount, ARCH_CONVERT);
- *free = INT_GET(rec->ir_free, ARCH_CONVERT);
- *stat = 1;
- return 0;
-}
-
-/*
- * Increment cursor by one record at the level.
- * For nonzero levels the leaf-ward information is untouched.
- */
-int /* error */
-xfs_inobt_increment(
- xfs_btree_cur_t *cur, /* btree cursor */
- int level, /* level in btree, 0 is leaf */
- int *stat) /* success/failure */
-{
- xfs_inobt_block_t *block; /* btree block */
- xfs_buf_t *bp; /* buffer containing btree block */
- int error; /* error return value */
- int lev; /* btree level */
-
- ASSERT(level < cur->bc_nlevels);
- /*
- * Read-ahead to the right at this level.
- */
- xfs_btree_readahead(cur, level, XFS_BTCUR_RIGHTRA);
- /*
- * Get a pointer to the btree block.
- */
- bp = cur->bc_bufs[level];
- block = XFS_BUF_TO_INOBT_BLOCK(bp);
-#ifdef DEBUG
- if ((error = xfs_btree_check_sblock(cur, block, level, bp)))
- return error;
-#endif
- /*
- * Increment the ptr at this level. If we're still in the block
- * then we're done.
- */
- if (++cur->bc_ptrs[level] <= be16_to_cpu(block->bb_numrecs)) {
- *stat = 1;
- return 0;
- }
- /*
- * If we just went off the right edge of the tree, return failure.
- */
- if (be32_to_cpu(block->bb_rightsib) == NULLAGBLOCK) {
- *stat = 0;
- return 0;
- }
- /*
- * March up the tree incrementing pointers.
- * Stop when we don't go off the right edge of a block.
- */
- for (lev = level + 1; lev < cur->bc_nlevels; lev++) {
- bp = cur->bc_bufs[lev];
- block = XFS_BUF_TO_INOBT_BLOCK(bp);
-#ifdef DEBUG
- if ((error = xfs_btree_check_sblock(cur, block, lev, bp)))
- return error;
-#endif
- if (++cur->bc_ptrs[lev] <= be16_to_cpu(block->bb_numrecs))
- break;
- /*
- * Read-ahead the right block, we're going to read it
- * in the next loop.
- */
- xfs_btree_readahead(cur, lev, XFS_BTCUR_RIGHTRA);
- }
- /*
- * If we went off the root then we are seriously confused.
- */
- ASSERT(lev < cur->bc_nlevels);
- /*
- * Now walk back down the tree, fixing up the cursor's buffer
- * pointers and key numbers.
- */
- for (bp = cur->bc_bufs[lev], block = XFS_BUF_TO_INOBT_BLOCK(bp);
- lev > level; ) {
- xfs_agblock_t agbno; /* block number of btree block */
-
- agbno = be32_to_cpu(*XFS_INOBT_PTR_ADDR(block, cur->bc_ptrs[lev], cur));
- if ((error = xfs_btree_read_bufs(cur->bc_mp, cur->bc_tp,
- cur->bc_private.i.agno, agbno, 0, &bp,
- XFS_INO_BTREE_REF)))
- return error;
- lev--;
- xfs_btree_setbuf(cur, lev, bp);
- block = XFS_BUF_TO_INOBT_BLOCK(bp);
- if ((error = xfs_btree_check_sblock(cur, block, lev, bp)))
- return error;
- cur->bc_ptrs[lev] = 1;
- }
- *stat = 1;
- return 0;
-}
-
-/*
- * Insert the current record at the point referenced by cur.
- * The cursor may be inconsistent on return if splits have been done.
- */
-int /* error */
-xfs_inobt_insert(
- xfs_btree_cur_t *cur, /* btree cursor */
- int *stat) /* success/failure */
-{
- int error; /* error return value */
- int i; /* result value, 0 for failure */
- int level; /* current level number in btree */
- xfs_agblock_t nbno; /* new block number (split result) */
- xfs_btree_cur_t *ncur; /* new cursor (split result) */
- xfs_inobt_rec_t nrec; /* record being inserted this level */
- xfs_btree_cur_t *pcur; /* previous level's cursor */
-
- level = 0;
- nbno = NULLAGBLOCK;
- INT_SET(nrec.ir_startino, ARCH_CONVERT, cur->bc_rec.i.ir_startino);
- INT_SET(nrec.ir_freecount, ARCH_CONVERT, cur->bc_rec.i.ir_freecount);
- INT_SET(nrec.ir_free, ARCH_CONVERT, cur->bc_rec.i.ir_free);
- ncur = (xfs_btree_cur_t *)0;
- pcur = cur;
- /*
- * Loop going up the tree, starting at the leaf level.
- * Stop when we don't get a split block, that must mean that
- * the insert is finished with this level.
- */
- do {
- /*
- * Insert nrec/nbno into this level of the tree.
- * Note if we fail, nbno will be null.
- */
- if ((error = xfs_inobt_insrec(pcur, level++, &nbno, &nrec, &ncur,
- &i))) {
- if (pcur != cur)
- xfs_btree_del_cursor(pcur, XFS_BTREE_ERROR);
- return error;
- }
- /*
- * See if the cursor we just used is trash.
- * Can't trash the caller's cursor, but otherwise we should
- * if ncur is a new cursor or we're about to be done.
- */
- if (pcur != cur && (ncur || nbno == NULLAGBLOCK)) {
- cur->bc_nlevels = pcur->bc_nlevels;
- xfs_btree_del_cursor(pcur, XFS_BTREE_NOERROR);
- }
- /*
- * If we got a new cursor, switch to it.
- */
- if (ncur) {
- pcur = ncur;
- ncur = (xfs_btree_cur_t *)0;
- }
- } while (nbno != NULLAGBLOCK);
- *stat = i;
- return 0;
-}
-
-/*
- * Lookup the record equal to ino in the btree given by cur.
- */
-int /* error */
-xfs_inobt_lookup_eq(
- xfs_btree_cur_t *cur, /* btree cursor */
- xfs_agino_t ino, /* starting inode of chunk */
- __int32_t fcnt, /* free inode count */
- xfs_inofree_t free, /* free inode mask */
- int *stat) /* success/failure */
-{
- cur->bc_rec.i.ir_startino = ino;
- cur->bc_rec.i.ir_freecount = fcnt;
- cur->bc_rec.i.ir_free = free;
- return xfs_inobt_lookup(cur, XFS_LOOKUP_EQ, stat);
-}
-
-/*
- * Lookup the first record greater than or equal to ino
- * in the btree given by cur.
- */
-int /* error */
-xfs_inobt_lookup_ge(
- xfs_btree_cur_t *cur, /* btree cursor */
- xfs_agino_t ino, /* starting inode of chunk */
- __int32_t fcnt, /* free inode count */
- xfs_inofree_t free, /* free inode mask */
- int *stat) /* success/failure */
-{
- cur->bc_rec.i.ir_startino = ino;
- cur->bc_rec.i.ir_freecount = fcnt;
- cur->bc_rec.i.ir_free = free;
- return xfs_inobt_lookup(cur, XFS_LOOKUP_GE, stat);
-}
-
-/*
- * Lookup the first record less than or equal to ino
- * in the btree given by cur.
- */
-int /* error */
-xfs_inobt_lookup_le(
- xfs_btree_cur_t *cur, /* btree cursor */
- xfs_agino_t ino, /* starting inode of chunk */
- __int32_t fcnt, /* free inode count */
- xfs_inofree_t free, /* free inode mask */
- int *stat) /* success/failure */
-{
- cur->bc_rec.i.ir_startino = ino;
- cur->bc_rec.i.ir_freecount = fcnt;
- cur->bc_rec.i.ir_free = free;
- return xfs_inobt_lookup(cur, XFS_LOOKUP_LE, stat);
-}
-
-/*
- * Update the record referred to by cur, to the value given
- * by [ino, fcnt, free].
- * This either works (return 0) or gets an EFSCORRUPTED error.
- */
-int /* error */
-xfs_inobt_update(
- xfs_btree_cur_t *cur, /* btree cursor */
- xfs_agino_t ino, /* starting inode of chunk */
- __int32_t fcnt, /* free inode count */
- xfs_inofree_t free) /* free inode mask */
-{
- xfs_inobt_block_t *block; /* btree block to update */
- xfs_buf_t *bp; /* buffer containing btree block */
- int error; /* error return value */
- int ptr; /* current record number (updating) */
- xfs_inobt_rec_t *rp; /* pointer to updated record */
-
- /*
- * Pick up the current block.
- */
- bp = cur->bc_bufs[0];
- block = XFS_BUF_TO_INOBT_BLOCK(bp);
-#ifdef DEBUG
- if ((error = xfs_btree_check_sblock(cur, block, 0, bp)))
- return error;
-#endif
- /*
- * Get the address of the rec to be updated.
- */
- ptr = cur->bc_ptrs[0];
- rp = XFS_INOBT_REC_ADDR(block, ptr, cur);
- /*
- * Fill in the new contents and log them.
- */
- INT_SET(rp->ir_startino, ARCH_CONVERT, ino);
- INT_SET(rp->ir_freecount, ARCH_CONVERT, fcnt);
- INT_SET(rp->ir_free, ARCH_CONVERT, free);
- xfs_inobt_log_recs(cur, bp, ptr, ptr);
- /*
- * Updating first record in leaf. Pass new key value up to our parent.
- */
- if (ptr == 1) {
- xfs_inobt_key_t key; /* key containing [ino] */
-
- INT_SET(key.ir_startino, ARCH_CONVERT, ino);
- if ((error = xfs_inobt_updkey(cur, &key, 1)))
- return error;
- }
- return 0;
-}
diff --git a/sys/gnu/fs/xfs/xfs_ialloc_btree.h b/sys/gnu/fs/xfs/xfs_ialloc_btree.h
deleted file mode 100644
index ae3904c..0000000
--- a/sys/gnu/fs/xfs/xfs_ialloc_btree.h
+++ /dev/null
@@ -1,177 +0,0 @@
-/*
- * Copyright (c) 2000,2005 Silicon Graphics, Inc.
- * All Rights Reserved.
- *
- * 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.
- *
- * This program is distributed in the hope that it would 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 the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- */
-#ifndef __XFS_IALLOC_BTREE_H__
-#define __XFS_IALLOC_BTREE_H__
-
-/*
- * Inode map on-disk structures
- */
-
-struct xfs_buf;
-struct xfs_btree_cur;
-struct xfs_btree_sblock;
-struct xfs_mount;
-
-/*
- * There is a btree for the inode map per allocation group.
- */
-#define XFS_IBT_MAGIC 0x49414254 /* 'IABT' */
-
-typedef __uint64_t xfs_inofree_t;
-#define XFS_INODES_PER_CHUNK (NBBY * sizeof(xfs_inofree_t))
-#define XFS_INODES_PER_CHUNK_LOG (XFS_NBBYLOG + 3)
-#define XFS_INOBT_ALL_FREE ((xfs_inofree_t)-1)
-
-#define XFS_INOBT_MASKN(i,n) xfs_inobt_maskn(i,n)
-static inline xfs_inofree_t xfs_inobt_maskn(int i, int n)
-{
- return (((n) >= XFS_INODES_PER_CHUNK ? \
- (xfs_inofree_t)0 : ((xfs_inofree_t)1 << (n))) - 1) << (i);
-}
-
-/*
- * Data record structure
- */
-typedef struct xfs_inobt_rec
-{
- xfs_agino_t ir_startino; /* starting inode number */
- __int32_t ir_freecount; /* count of free inodes (set bits) */
- xfs_inofree_t ir_free; /* free inode mask */
-} xfs_inobt_rec_t;
-
-/*
- * Key structure
- */
-typedef struct xfs_inobt_key
-{
- xfs_agino_t ir_startino; /* starting inode number */
-} xfs_inobt_key_t;
-
-/* btree pointer type */
-typedef __be32 xfs_inobt_ptr_t;
-
-/* btree block header type */
-typedef struct xfs_btree_sblock xfs_inobt_block_t;
-
-#define XFS_BUF_TO_INOBT_BLOCK(bp) ((xfs_inobt_block_t *)XFS_BUF_PTR(bp))
-
-/*
- * Bit manipulations for ir_free.
- */
-#define XFS_INOBT_MASK(i) ((xfs_inofree_t)1 << (i))
-#define XFS_INOBT_IS_FREE(rp,i) \
- (((rp)->ir_free & XFS_INOBT_MASK(i)) != 0)
-#define XFS_INOBT_IS_FREE_DISK(rp,i) \
- ((INT_GET((rp)->ir_free,ARCH_CONVERT) & XFS_INOBT_MASK(i)) != 0)
-#define XFS_INOBT_SET_FREE(rp,i) ((rp)->ir_free |= XFS_INOBT_MASK(i))
-#define XFS_INOBT_CLR_FREE(rp,i) ((rp)->ir_free &= ~XFS_INOBT_MASK(i))
-
-/*
- * Real block structures have a size equal to the disk block size.
- */
-#define XFS_INOBT_BLOCK_SIZE(lev,cur) (1 << (cur)->bc_blocklog)
-#define XFS_INOBT_BLOCK_MAXRECS(lev,cur) ((cur)->bc_mp->m_inobt_mxr[lev != 0])
-#define XFS_INOBT_BLOCK_MINRECS(lev,cur) ((cur)->bc_mp->m_inobt_mnr[lev != 0])
-#define XFS_INOBT_IS_LAST_REC(cur) \
- ((cur)->bc_ptrs[0] == be16_to_cpu(XFS_BUF_TO_INOBT_BLOCK((cur)->bc_bufs[0])->bb_numrecs))
-
-/*
- * Maximum number of inode btree levels.
- */
-#define XFS_IN_MAXLEVELS(mp) ((mp)->m_in_maxlevels)
-
-/*
- * block numbers in the AG.
- */
-#define XFS_IBT_BLOCK(mp) ((xfs_agblock_t)(XFS_CNT_BLOCK(mp) + 1))
-#define XFS_PREALLOC_BLOCKS(mp) ((xfs_agblock_t)(XFS_IBT_BLOCK(mp) + 1))
-
-/*
- * Record, key, and pointer address macros for btree blocks.
- */
-#define XFS_INOBT_REC_ADDR(bb,i,cur) \
- (XFS_BTREE_REC_ADDR(XFS_INOBT_BLOCK_SIZE(0,cur), xfs_inobt, bb, \
- i, XFS_INOBT_BLOCK_MAXRECS(0, cur)))
-#define XFS_INOBT_KEY_ADDR(bb,i,cur) \
- (XFS_BTREE_KEY_ADDR(XFS_INOBT_BLOCK_SIZE(1,cur), xfs_inobt, bb, \
- i, XFS_INOBT_BLOCK_MAXRECS(1, cur)))
-
-#define XFS_INOBT_PTR_ADDR(bb,i,cur) \
- (XFS_BTREE_PTR_ADDR(XFS_INOBT_BLOCK_SIZE(1,cur), xfs_inobt, bb, \
- i, XFS_INOBT_BLOCK_MAXRECS(1, cur)))
-
-/*
- * Decrement cursor by one record at the level.
- * For nonzero levels the leaf-ward information is untouched.
- */
-extern int xfs_inobt_decrement(struct xfs_btree_cur *cur, int level, int *stat);
-
-/*
- * Delete the record pointed to by cur.
- * The cursor refers to the place where the record was (could be inserted)
- * when the operation returns.
- */
-extern int xfs_inobt_delete(struct xfs_btree_cur *cur, int *stat);
-
-/*
- * Get the data from the pointed-to record.
- */
-extern int xfs_inobt_get_rec(struct xfs_btree_cur *cur, xfs_agino_t *ino,
- __int32_t *fcnt, xfs_inofree_t *free, int *stat);
-
-/*
- * Increment cursor by one record at the level.
- * For nonzero levels the leaf-ward information is untouched.
- */
-extern int xfs_inobt_increment(struct xfs_btree_cur *cur, int level, int *stat);
-
-/*
- * Insert the current record at the point referenced by cur.
- * The cursor may be inconsistent on return if splits have been done.
- */
-extern int xfs_inobt_insert(struct xfs_btree_cur *cur, int *stat);
-
-/*
- * Lookup the record equal to ino in the btree given by cur.
- */
-extern int xfs_inobt_lookup_eq(struct xfs_btree_cur *cur, xfs_agino_t ino,
- __int32_t fcnt, xfs_inofree_t free, int *stat);
-
-/*
- * Lookup the first record greater than or equal to ino
- * in the btree given by cur.
- */
-extern int xfs_inobt_lookup_ge(struct xfs_btree_cur *cur, xfs_agino_t ino,
- __int32_t fcnt, xfs_inofree_t free, int *stat);
-
-/*
- * Lookup the first record less than or equal to ino
- * in the btree given by cur.
- */
-extern int xfs_inobt_lookup_le(struct xfs_btree_cur *cur, xfs_agino_t ino,
- __int32_t fcnt, xfs_inofree_t free, int *stat);
-
-/*
- * Update the record referred to by cur, to the value given
- * by [ino, fcnt, free].
- * This either works (return 0) or gets an EFSCORRUPTED error.
- */
-extern int xfs_inobt_update(struct xfs_btree_cur *cur, xfs_agino_t ino,
- __int32_t fcnt, xfs_inofree_t free);
-
-#endif /* __XFS_IALLOC_BTREE_H__ */
diff --git a/sys/gnu/fs/xfs/xfs_iget.c b/sys/gnu/fs/xfs/xfs_iget.c
deleted file mode 100644
index 7b5803c..0000000
--- a/sys/gnu/fs/xfs/xfs_iget.c
+++ /dev/null
@@ -1,1052 +0,0 @@
-/*
- * Copyright (c) 2000-2005 Silicon Graphics, Inc.
- * All Rights Reserved.
- *
- * 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.
- *
- * This program is distributed in the hope that it would 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 the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- */
-#include "xfs.h"
-#include "xfs_fs.h"
-#include "xfs_types.h"
-#include "xfs_bit.h"
-#include "xfs_log.h"
-#include "xfs_inum.h"
-#include "xfs_trans.h"
-#include "xfs_sb.h"
-#include "xfs_ag.h"
-#include "xfs_dir.h"
-#include "xfs_dir2.h"
-#include "xfs_dmapi.h"
-#include "xfs_mount.h"
-#include "xfs_bmap_btree.h"
-#include "xfs_alloc_btree.h"
-#include "xfs_ialloc_btree.h"
-#include "xfs_dir_sf.h"
-#include "xfs_dir2_sf.h"
-#include "xfs_attr_sf.h"
-#include "xfs_dinode.h"
-#include "xfs_inode.h"
-#include "xfs_btree.h"
-#include "xfs_ialloc.h"
-#include "xfs_quota.h"
-#include "xfs_utils.h"
-
-/*
- * Initialize the inode hash table for the newly mounted file system.
- * Choose an initial table size based on user specified value, else
- * use a simple algorithm using the maximum number of inodes as an
- * indicator for table size, and clamp it between one and some large
- * number of pages.
- */
-void
-xfs_ihash_init(xfs_mount_t *mp)
-{
- __uint64_t icount;
- uint i, flags = KM_SLEEP | KM_MAYFAIL;
-
- if (!mp->m_ihsize) {
- icount = mp->m_maxicount ? mp->m_maxicount :
- (mp->m_sb.sb_dblocks << mp->m_sb.sb_inopblog);
- mp->m_ihsize = 1 << max_t(uint, 8,
- (xfs_highbit64(icount) + 1) / 2);
- mp->m_ihsize = min_t(uint, mp->m_ihsize,
- (64 * NBPP) / sizeof(xfs_ihash_t));
- }
-
- while (!(mp->m_ihash = (xfs_ihash_t *)kmem_zalloc(mp->m_ihsize *
- sizeof(xfs_ihash_t), flags))) {
- if ((mp->m_ihsize >>= 1) <= NBPP)
- flags = KM_SLEEP;
- }
- for (i = 0; i < mp->m_ihsize; i++) {
- rwlock_init(&(mp->m_ihash[i].ih_lock));
- }
-}
-
-/*
- * Free up structures allocated by xfs_ihash_init, at unmount time.
- */
-void
-xfs_ihash_free(xfs_mount_t *mp)
-{
- kmem_free(mp->m_ihash, mp->m_ihsize*sizeof(xfs_ihash_t));
- mp->m_ihash = NULL;
-}
-
-/*
- * Initialize the inode cluster hash table for the newly mounted file system.
- * Its size is derived from the ihash table size.
- */
-void
-xfs_chash_init(xfs_mount_t *mp)
-{
- uint i;
-
- mp->m_chsize = max_t(uint, 1, mp->m_ihsize /
- (XFS_INODE_CLUSTER_SIZE(mp) >> mp->m_sb.sb_inodelog));
- mp->m_chsize = min_t(uint, mp->m_chsize, mp->m_ihsize);
- mp->m_chash = (xfs_chash_t *)kmem_zalloc(mp->m_chsize
- * sizeof(xfs_chash_t),
- KM_SLEEP);
- for (i = 0; i < mp->m_chsize; i++) {
- spinlock_init(&mp->m_chash[i].ch_lock,"xfshash");
- }
-}
-
-/*
- * Free up structures allocated by xfs_chash_init, at unmount time.
- */
-void
-xfs_chash_free(xfs_mount_t *mp)
-{
- int i;
-
- for (i = 0; i < mp->m_chsize; i++) {
- spinlock_destroy(&mp->m_chash[i].ch_lock);
- }
-
- kmem_free(mp->m_chash, mp->m_chsize*sizeof(xfs_chash_t));
- mp->m_chash = NULL;
-}
-
-/*
- * Try to move an inode to the front of its hash list if possible
- * (and if its not there already). Called right after obtaining
- * the list version number and then dropping the read_lock on the
- * hash list in question (which is done right after looking up the
- * inode in question...).
- */
-STATIC void
-xfs_ihash_promote(
- xfs_ihash_t *ih,
- xfs_inode_t *ip,
- ulong version)
-{
- xfs_inode_t *iq;
-
- if ((ip->i_prevp != &ih->ih_next) && write_trylock(&ih->ih_lock)) {
- if (likely(version == ih->ih_version)) {
- /* remove from list */
- if ((iq = ip->i_next)) {
- iq->i_prevp = ip->i_prevp;
- }
- *ip->i_prevp = iq;
-
- /* insert at list head */
- iq = ih->ih_next;
- iq->i_prevp = &ip->i_next;
- ip->i_next = iq;
- ip->i_prevp = &ih->ih_next;
- ih->ih_next = ip;
- }
- write_unlock(&ih->ih_lock);
- }
-}
-
-/*
- * Look up an inode by number in the given file system.
- * The inode is looked up in the hash table for the file system
- * represented by the mount point parameter mp. Each bucket of
- * the hash table is guarded by an individual semaphore.
- *
- * If the inode is found in the hash table, its corresponding vnode
- * is obtained with a call to vn_get(). This call takes care of
- * coordination with the reclamation of the inode and vnode. Note
- * that the vmap structure is filled in while holding the hash lock.
- * This gives us the state of the inode/vnode when we found it and
- * is used for coordination in vn_get().
- *
- * If it is not in core, read it in from the file system's device and
- * add the inode into the hash table.
- *
- * The inode is locked according to the value of the lock_flags parameter.
- * This flag parameter indicates how and if the inode's IO lock and inode lock
- * should be taken.
- *
- * mp -- the mount point structure for the current file system. It points
- * to the inode hash table.
- * tp -- a pointer to the current transaction if there is one. This is
- * simply passed through to the xfs_iread() call.
- * ino -- the number of the inode desired. This is the unique identifier
- * within the file system for the inode being requested.
- * lock_flags -- flags indicating how to lock the inode. See the comment
- * for xfs_ilock() for a list of valid values.
- * bno -- the block number starting the buffer containing the inode,
- * if known (as by bulkstat), else 0.
- */
-#ifdef RMC
-STATIC int
-xfs_iget_core(
- xfs_vnode_t *vp,
- xfs_mount_t *mp,
- xfs_trans_t *tp,
- xfs_ino_t ino,
- uint flags,
- uint lock_flags,
- xfs_inode_t **ipp,
- xfs_daddr_t bno)
-{
- xfs_ihash_t *ih;
- xfs_inode_t *ip;
- xfs_inode_t *iq;
- xfs_vnode_t *inode_vp;
- ulong version;
- int error;
- /* REFERENCED */
- xfs_chash_t *ch;
- xfs_chashlist_t *chl, *chlnew;
- SPLDECL(s);
-
-
- ih = XFS_IHASH(mp, ino);
-
-again:
- read_lock(&ih->ih_lock);
-
- for (ip = ih->ih_next; ip != NULL; ip = ip->i_next) {
- if (ip->i_ino == ino) {
- /*
- * If INEW is set this inode is being set up
- * we need to pause and try again.
- */
- if (ip->i_flags & XFS_INEW) {
- read_unlock(&ih->ih_lock);
- delay(1);
- XFS_STATS_INC(xs_ig_frecycle);
-
- goto again;
- }
-
- inode_vp = XFS_ITOV_NULL(ip);
- if (inode_vp == NULL) {
- /*
- * If IRECLAIM is set this inode is
- * on its way out of the system,
- * we need to pause and try again.
- */
- if (ip->i_flags & XFS_IRECLAIM) {
- read_unlock(&ih->ih_lock);
- delay(1);
- XFS_STATS_INC(xs_ig_frecycle);
-
- goto again;
- }
-
- vn_trace_exit(vp, "xfs_iget.alloc",
- (inst_t *)__return_address);
-
- XFS_STATS_INC(xs_ig_found);
-
- ip->i_flags &= ~XFS_IRECLAIMABLE;
- version = ih->ih_version;
- read_unlock(&ih->ih_lock);
- xfs_ihash_promote(ih, ip, version);
-
-#ifdef RMC
- XFS_MOUNT_ILOCK(mp);
- list_del_init(&ip->i_reclaim);
- XFS_MOUNT_IUNLOCK(mp);
-#endif
-
- goto finish_inode;
-
- } else if (vp != inode_vp) {
-#ifdef RMC
- struct inode *inode = vn_to_inode(inode_vp);
-
- /* The inode is being torn down, pause and
- * try again.
- */
- if (inode->i_state & (I_FREEING | I_CLEAR)) {
- read_unlock(&ih->ih_lock);
- delay(1);
- XFS_STATS_INC(xs_ig_frecycle);
-
- goto again;
- }
-#endif
-/* Chances are the other vnode (the one in the inode) is being torn
- * down right now, and we landed on top of it. Question is, what do
- * we do? Unhook the old inode and hook up the new one?
- */
- cmn_err(CE_PANIC,
- "xfs_iget_core: ambiguous vns: vp/0x%p, invp/0x%p",
- inode_vp, vp);
- }
-
- /*
- * Inode cache hit: if ip is not at the front of
- * its hash chain, move it there now.
- * Do this with the lock held for update, but
- * do statistics after releasing the lock.
- */
- version = ih->ih_version;
- read_unlock(&ih->ih_lock);
- xfs_ihash_promote(ih, ip, version);
- XFS_STATS_INC(xs_ig_found);
-
-finish_inode:
- if (ip->i_d.di_mode == 0) {
- if (!(flags & IGET_CREATE))
- return ENOENT;
- xfs_iocore_inode_reinit(ip);
- }
-
- if (lock_flags != 0)
- xfs_ilock(ip, lock_flags);
-
- ip->i_flags &= ~XFS_ISTALE;
-
- vn_trace_exit(vp, "xfs_iget.found",
- (inst_t *)__return_address);
- goto return_ip;
- }
- }
-
- /*
- * Inode cache miss: save the hash chain version stamp and unlock
- * the chain, so we don't deadlock in vn_alloc.
- */
- XFS_STATS_INC(xs_ig_missed);
-
- version = ih->ih_version;
-
- read_unlock(&ih->ih_lock);
-
- /*
- * Read the disk inode attributes into a new inode structure and get
- * a new vnode for it. This should also initialize i_ino and i_mount.
- */
- error = xfs_iread(mp, tp, ino, &ip, bno);
- if (error) {
- return error;
- }
-
- vn_trace_exit(vp, "xfs_iget.alloc", (inst_t *)__return_address);
-
- xfs_inode_lock_init(ip, vp);
- xfs_iocore_inode_init(ip);
-
- if (lock_flags != 0) {
- xfs_ilock(ip, lock_flags);
- }
-
- if ((ip->i_d.di_mode == 0) && !(flags & IGET_CREATE)) {
- xfs_idestroy(ip);
- return ENOENT;
- }
-
- /*
- * Put ip on its hash chain, unless someone else hashed a duplicate
- * after we released the hash lock.
- */
- write_lock(&ih->ih_lock);
-
- if (ih->ih_version != version) {
- for (iq = ih->ih_next; iq != NULL; iq = iq->i_next) {
- if (iq->i_ino == ino) {
- write_unlock(&ih->ih_lock);
- xfs_idestroy(ip);
-
- XFS_STATS_INC(xs_ig_dup);
- goto again;
- }
- }
- }
-
- /*
- * These values _must_ be set before releasing ihlock!
- */
- ip->i_hash = ih;
- if ((iq = ih->ih_next)) {
- iq->i_prevp = &ip->i_next;
- }
- ip->i_next = iq;
- ip->i_prevp = &ih->ih_next;
- ih->ih_next = ip;
- ip->i_udquot = ip->i_gdquot = NULL;
- ih->ih_version++;
- ip->i_flags |= XFS_INEW;
-
- write_unlock(&ih->ih_lock);
-
- /*
- * put ip on its cluster's hash chain
- */
- ASSERT(ip->i_chash == NULL && ip->i_cprev == NULL &&
- ip->i_cnext == NULL);
-
- chlnew = NULL;
- ch = XFS_CHASH(mp, ip->i_blkno);
- chlredo:
- s = mutex_spinlock(&ch->ch_lock);
- for (chl = ch->ch_list; chl != NULL; chl = chl->chl_next) {
- if (chl->chl_blkno == ip->i_blkno) {
-
- /* insert this inode into the doubly-linked list
- * where chl points */
- if ((iq = chl->chl_ip)) {
- ip->i_cprev = iq->i_cprev;
- iq->i_cprev->i_cnext = ip;
- iq->i_cprev = ip;
- ip->i_cnext = iq;
- } else {
- ip->i_cnext = ip;
- ip->i_cprev = ip;
- }
- chl->chl_ip = ip;
- ip->i_chash = chl;
- break;
- }
- }
-
- /* no hash list found for this block; add a new hash list */
- if (chl == NULL) {
- if (chlnew == NULL) {
- mutex_spinunlock(&ch->ch_lock, s);
- ASSERT(xfs_chashlist_zone != NULL);
- chlnew = (xfs_chashlist_t *)
- kmem_zone_alloc(xfs_chashlist_zone,
- KM_SLEEP);
- ASSERT(chlnew != NULL);
- goto chlredo;
- } else {
- ip->i_cnext = ip;
- ip->i_cprev = ip;
- ip->i_chash = chlnew;
- chlnew->chl_ip = ip;
- chlnew->chl_blkno = ip->i_blkno;
- if (ch->ch_list)
- ch->ch_list->chl_prev = chlnew;
- chlnew->chl_next = ch->ch_list;
- chlnew->chl_prev = NULL;
- ch->ch_list = chlnew;
- chlnew = NULL;
- }
- } else {
- if (chlnew != NULL) {
- kmem_zone_free(xfs_chashlist_zone, chlnew);
- }
- }
-
- mutex_spinunlock(&ch->ch_lock, s);
-
-
- /*
- * Link ip to its mount and thread it on the mount's inode list.
- */
- XFS_MOUNT_ILOCK(mp);
- if ((iq = mp->m_inodes)) {
- ASSERT(iq->i_mprev->i_mnext == iq);
- ip->i_mprev = iq->i_mprev;
- iq->i_mprev->i_mnext = ip;
- iq->i_mprev = ip;
- ip->i_mnext = iq;
- } else {
- ip->i_mnext = ip;
- ip->i_mprev = ip;
- }
- mp->m_inodes = ip;
-
- XFS_MOUNT_IUNLOCK(mp);
-
- return_ip:
- ASSERT(ip->i_df.if_ext_max ==
- XFS_IFORK_DSIZE(ip) / sizeof(xfs_bmbt_rec_t));
-
- ASSERT(((ip->i_d.di_flags & XFS_DIFLAG_REALTIME) != 0) ==
- ((ip->i_iocore.io_flags & XFS_IOCORE_RT) != 0));
-
- *ipp = ip;
-
- /*
- * If we have a real type for an on-disk inode, we can set ops(&unlock)
- * now. If it's a new inode being created, xfs_ialloc will handle it.
- */
- XVFS_INIT_VNODE(XFS_MTOVFS(mp), vp, XFS_ITOBHV(ip), 1);
-
- return 0;
-}
-#endif
-
-#ifdef RMC
-/*
- * The 'normal' internal xfs_iget, if needed it will
- * 'allocate', or 'get', the vnode.
- */
-int
-xfs_iget(
- xfs_mount_t *mp,
- xfs_trans_t *tp,
- xfs_ino_t ino,
- uint flags,
- uint lock_flags,
- xfs_inode_t **ipp,
- xfs_daddr_t bno)
-{
- int error;
- struct inode *inode;
- xfs_vnode_t *vp = NULL;
-
- XFS_STATS_INC(xs_ig_attempts);
-
-retry:
- if ((inode = VFS_GET_INODE(XFS_MTOVFS(mp), ino, 0))) {
- xfs_inode_t *ip;
-
- vp = vn_from_inode(inode);
- if (inode->i_state & I_NEW) {
- vn_initialize(inode);
- error = xfs_iget_core(vp, mp, tp, ino, flags,
- lock_flags, ipp, bno);
- if (error) {
- vn_mark_bad(vp);
- if (inode->i_state & I_NEW)
- unlock_new_inode(inode);
- iput(inode);
- }
- } else {
- /*
- * If the inode is not fully constructed due to
- * filehandle mismatches wait for the inode to go
- * away and try again.
- *
- * iget_locked will call __wait_on_freeing_inode
- * to wait for the inode to go away.
- */
- if (is_bad_inode(inode) ||
- ((ip = xfs_vtoi(vp)) == NULL)) {
- iput(inode);
- delay(1);
- goto retry;
- }
-
- if (lock_flags != 0)
- xfs_ilock(ip, lock_flags);
- XFS_STATS_INC(xs_ig_found);
- *ipp = ip;
- error = 0;
- }
- } else
- error = ENOMEM; /* If we got no inode we are out of memory */
-
- return error;
-}
-#endif
-
-/*
- * Do the setup for the various locks within the incore inode.
- */
-void
-xfs_inode_lock_init(
- xfs_inode_t *ip,
- xfs_vnode_t *vp)
-{
- mrlock_init(&ip->i_lock, MRLOCK_ALLOW_EQUAL_PRI|MRLOCK_BARRIER,
- "xfsino", (long)vp->v_number);
- mrlock_init(&ip->i_iolock, MRLOCK_BARRIER, "xfsio", vp->v_number);
-#ifdef RMC
- init_waitqueue_head(&ip->i_ipin_wait);
-#endif
- atomic_set(&ip->i_pincount, 0);
- init_sema(&ip->i_flock, 1, "xfsfino", vp->v_number);
-}
-
-/*
- * Look for the inode corresponding to the given ino in the hash table.
- * If it is there and its i_transp pointer matches tp, return it.
- * Otherwise, return NULL.
- */
-xfs_inode_t *
-xfs_inode_incore(xfs_mount_t *mp,
- xfs_ino_t ino,
- xfs_trans_t *tp)
-{
- xfs_ihash_t *ih;
- xfs_inode_t *ip;
- ulong version;
-
- ih = XFS_IHASH(mp, ino);
- read_lock(&ih->ih_lock);
- for (ip = ih->ih_next; ip != NULL; ip = ip->i_next) {
- if (ip->i_ino == ino) {
- /*
- * If we find it and tp matches, return it.
- * Also move it to the front of the hash list
- * if we find it and it is not already there.
- * Otherwise break from the loop and return
- * NULL.
- */
- if (ip->i_transp == tp) {
- version = ih->ih_version;
- read_unlock(&ih->ih_lock);
- xfs_ihash_promote(ih, ip, version);
- return (ip);
- }
- break;
- }
- }
- read_unlock(&ih->ih_lock);
- return (NULL);
-}
-
-/*
- * Decrement reference count of an inode structure and unlock it.
- *
- * ip -- the inode being released
- * lock_flags -- this parameter indicates the inode's locks to be
- * to be released. See the comment on xfs_iunlock() for a list
- * of valid values.
- */
-void
-xfs_iput(xfs_inode_t *ip,
- uint lock_flags)
-{
- xfs_vnode_t *vp = XFS_ITOV(ip);
-
- vn_trace_entry(vp, "xfs_iput", (inst_t *)__return_address);
-
- xfs_iunlock(ip, lock_flags);
-
- VN_RELE(vp);
-}
-
-#ifdef RMC
-/* in xfs_freebsd_iget.c
- * Special iput for brand-new inodes that are still locked
- */
-void
-xfs_iput_new(xfs_inode_t *ip,
- uint lock_flags)
-{
- xfs_vnode_t *vp = XFS_ITOV(ip);
- struct inode *inode = vn_to_inode(vp);
-
- vn_trace_entry(vp, "xfs_iput_new", (inst_t *)__return_address);
-
- if ((ip->i_d.di_mode == 0)) {
- ASSERT(!(ip->i_flags & XFS_IRECLAIMABLE));
- vn_mark_bad(vp);
- }
- if (inode->i_state & I_NEW)
- unlock_new_inode(inode);
- if (lock_flags)
- xfs_iunlock(ip, lock_flags);
- VN_RELE(vp);
-}
-#endif
-
-
-/*
- * This routine embodies the part of the reclaim code that pulls
- * the inode from the inode hash table and the mount structure's
- * inode list.
- * This should only be called from xfs_reclaim().
- */
-void
-xfs_ireclaim(
- xfs_inode_t *ip)
-{
- xfs_vnode_t *vp;
-
- /*
- * Remove from old hash list and mount list.
- */
- XFS_STATS_INC(xs_ig_reclaims);
-
- xfs_iextract(ip);
-
- /*
- * Here we do a spurious inode lock in order to coordinate with
- * xfs_sync(). This is because xfs_sync() references the inodes
- * in the mount list without taking references on the corresponding
- * vnodes. We make that OK here by ensuring that we wait until
- * the inode is unlocked in xfs_sync() before we go ahead and
- * free it. We get both the regular lock and the io lock because
- * the xfs_sync() code may need to drop the regular one but will
- * still hold the io lock.
- */
- xfs_ilock(ip, XFS_ILOCK_EXCL | XFS_IOLOCK_EXCL);
-
- /*
- * Release dquots (and their references) if any. An inode may escape
- * xfs_inactive and get here via vn_alloc->vn_reclaim path.
- */
- XFS_QM_DQDETACH(ip->i_mount, ip);
-
- /*
- * Pull our behavior descriptor from the vnode chain.
- */
- vp = XFS_ITOV_NULL(ip);
- if (vp) {
- vn_bhv_remove(VN_BHV_HEAD(vp), XFS_ITOBHV(ip));
- }
-
- /*
- * Free all memory associated with the inode.
- */
- xfs_idestroy(ip);
-}
-
-/*
- * This routine removes an about-to-be-destroyed inode from
- * all of the lists in which it is located with the exception
- * of the behavior chain.
- */
-void
-xfs_iextract(
- xfs_inode_t *ip)
-{
- xfs_ihash_t *ih;
- xfs_inode_t *iq;
- xfs_mount_t *mp;
- xfs_chash_t *ch;
- xfs_chashlist_t *chl, *chm;
- SPLDECL(s);
-
- ih = ip->i_hash;
- write_lock(&ih->ih_lock);
- if ((iq = ip->i_next)) {
- iq->i_prevp = ip->i_prevp;
- }
- *ip->i_prevp = iq;
- ih->ih_version++;
- write_unlock(&ih->ih_lock);
-
- /*
- * Remove from cluster hash list
- * 1) delete the chashlist if this is the last inode on the chashlist
- * 2) unchain from list of inodes
- * 3) point chashlist->chl_ip to 'chl_next' if to this inode.
- */
- mp = ip->i_mount;
- ch = XFS_CHASH(mp, ip->i_blkno);
- s = mutex_spinlock(&ch->ch_lock);
-
- if (ip->i_cnext == ip) {
- /* Last inode on chashlist */
- ASSERT(ip->i_cnext == ip && ip->i_cprev == ip);
- ASSERT(ip->i_chash != NULL);
- chm=NULL;
- chl = ip->i_chash;
- if (chl->chl_prev)
- chl->chl_prev->chl_next = chl->chl_next;
- else
- ch->ch_list = chl->chl_next;
- if (chl->chl_next)
- chl->chl_next->chl_prev = chl->chl_prev;
- kmem_zone_free(xfs_chashlist_zone, chl);
- } else {
- /* delete one inode from a non-empty list */
- iq = ip->i_cnext;
- iq->i_cprev = ip->i_cprev;
- ip->i_cprev->i_cnext = iq;
- if (ip->i_chash->chl_ip == ip) {
- ip->i_chash->chl_ip = iq;
- }
- ip->i_chash = __return_address;
- ip->i_cprev = __return_address;
- ip->i_cnext = __return_address;
- }
- mutex_spinunlock(&ch->ch_lock, s);
-
- /*
- * Remove from mount's inode list.
- */
- XFS_MOUNT_ILOCK(mp);
- ASSERT((ip->i_mnext != NULL) && (ip->i_mprev != NULL));
- iq = ip->i_mnext;
- iq->i_mprev = ip->i_mprev;
- ip->i_mprev->i_mnext = iq;
-
- /*
- * Fix up the head pointer if it points to the inode being deleted.
- */
- if (mp->m_inodes == ip) {
- if (ip == iq) {
- mp->m_inodes = NULL;
- } else {
- mp->m_inodes = iq;
- }
- }
-
- /* Deal with the deleted inodes list */
-#ifdef RMC
- list_del_init(&ip->i_reclaim);
-#endif
-
- mp->m_ireclaims++;
- XFS_MOUNT_IUNLOCK(mp);
-}
-
-/*
- * This is a wrapper routine around the xfs_ilock() routine
- * used to centralize some grungy code. It is used in places
- * that wish to lock the inode solely for reading the extents.
- * The reason these places can't just call xfs_ilock(SHARED)
- * is that the inode lock also guards to bringing in of the
- * extents from disk for a file in b-tree format. If the inode
- * is in b-tree format, then we need to lock the inode exclusively
- * until the extents are read in. Locking it exclusively all
- * the time would limit our parallelism unnecessarily, though.
- * What we do instead is check to see if the extents have been
- * read in yet, and only lock the inode exclusively if they
- * have not.
- *
- * The function returns a value which should be given to the
- * corresponding xfs_iunlock_map_shared(). This value is
- * the mode in which the lock was actually taken.
- */
-uint
-xfs_ilock_map_shared(
- xfs_inode_t *ip)
-{
- uint lock_mode;
-
- if ((ip->i_d.di_format == XFS_DINODE_FMT_BTREE) &&
- ((ip->i_df.if_flags & XFS_IFEXTENTS) == 0)) {
- lock_mode = XFS_ILOCK_EXCL;
- } else {
- lock_mode = XFS_ILOCK_SHARED;
- }
-
- xfs_ilock(ip, lock_mode);
-
- return lock_mode;
-}
-
-/*
- * This is simply the unlock routine to go with xfs_ilock_map_shared().
- * All it does is call xfs_iunlock() with the given lock_mode.
- */
-void
-xfs_iunlock_map_shared(
- xfs_inode_t *ip,
- unsigned int lock_mode)
-{
- xfs_iunlock(ip, lock_mode);
-}
-
-/*
- * The xfs inode contains 2 locks: a multi-reader lock called the
- * i_iolock and a multi-reader lock called the i_lock. This routine
- * allows either or both of the locks to be obtained.
- *
- * The 2 locks should always be ordered so that the IO lock is
- * obtained first in order to prevent deadlock.
- *
- * ip -- the inode being locked
- * lock_flags -- this parameter indicates the inode's locks
- * to be locked. It can be:
- * XFS_IOLOCK_SHARED,
- * XFS_IOLOCK_EXCL,
- * XFS_ILOCK_SHARED,
- * XFS_ILOCK_EXCL,
- * XFS_IOLOCK_SHARED | XFS_ILOCK_SHARED,
- * XFS_IOLOCK_SHARED | XFS_ILOCK_EXCL,
- * XFS_IOLOCK_EXCL | XFS_ILOCK_SHARED,
- * XFS_IOLOCK_EXCL | XFS_ILOCK_EXCL
- */
-void
-xfs_ilock(xfs_inode_t *ip,
- uint lock_flags)
-{
- /*
- * You can't set both SHARED and EXCL for the same lock,
- * and only XFS_IOLOCK_SHARED, XFS_IOLOCK_EXCL, XFS_ILOCK_SHARED,
- * and XFS_ILOCK_EXCL are valid values to set in lock_flags.
- */
- ASSERT((lock_flags & (XFS_IOLOCK_SHARED | XFS_IOLOCK_EXCL)) !=
- (XFS_IOLOCK_SHARED | XFS_IOLOCK_EXCL));
- ASSERT((lock_flags & (XFS_ILOCK_SHARED | XFS_ILOCK_EXCL)) !=
- (XFS_ILOCK_SHARED | XFS_ILOCK_EXCL));
- ASSERT((lock_flags & ~XFS_LOCK_MASK) == 0);
-
- if (lock_flags & XFS_IOLOCK_EXCL) {
- mrupdate(&ip->i_iolock);
- } else if (lock_flags & XFS_IOLOCK_SHARED) {
- mraccess(&ip->i_iolock);
- }
- if (lock_flags & XFS_ILOCK_EXCL) {
- mrupdate(&ip->i_lock);
- } else if (lock_flags & XFS_ILOCK_SHARED) {
- mraccess(&ip->i_lock);
- }
- xfs_ilock_trace(ip, 1, lock_flags, (inst_t *)__return_address);
-}
-
-/*
- * This is just like xfs_ilock(), except that the caller
- * is guaranteed not to sleep. It returns 1 if it gets
- * the requested locks and 0 otherwise. If the IO lock is
- * obtained but the inode lock cannot be, then the IO lock
- * is dropped before returning.
- *
- * ip -- the inode being locked
- * lock_flags -- this parameter indicates the inode's locks to be
- * to be locked. See the comment for xfs_ilock() for a list
- * of valid values.
- *
- */
-int
-xfs_ilock_nowait(xfs_inode_t *ip,
- uint lock_flags)
-{
- int iolocked;
- int ilocked;
-
- /*
- * You can't set both SHARED and EXCL for the same lock,
- * and only XFS_IOLOCK_SHARED, XFS_IOLOCK_EXCL, XFS_ILOCK_SHARED,
- * and XFS_ILOCK_EXCL are valid values to set in lock_flags.
- */
- ASSERT((lock_flags & (XFS_IOLOCK_SHARED | XFS_IOLOCK_EXCL)) !=
- (XFS_IOLOCK_SHARED | XFS_IOLOCK_EXCL));
- ASSERT((lock_flags & (XFS_ILOCK_SHARED | XFS_ILOCK_EXCL)) !=
- (XFS_ILOCK_SHARED | XFS_ILOCK_EXCL));
- ASSERT((lock_flags & ~XFS_LOCK_MASK) == 0);
-
- iolocked = 0;
- if (lock_flags & XFS_IOLOCK_EXCL) {
- iolocked = mrtryupdate(&ip->i_iolock);
- if (!iolocked) {
- return 0;
- }
- } else if (lock_flags & XFS_IOLOCK_SHARED) {
- iolocked = mrtryaccess(&ip->i_iolock);
- if (!iolocked) {
- return 0;
- }
- }
- if (lock_flags & XFS_ILOCK_EXCL) {
- ilocked = mrtryupdate(&ip->i_lock);
- if (!ilocked) {
- if (iolocked) {
- mrunlock(&ip->i_iolock);
- }
- return 0;
- }
- } else if (lock_flags & XFS_ILOCK_SHARED) {
- ilocked = mrtryaccess(&ip->i_lock);
- if (!ilocked) {
- if (iolocked) {
- mrunlock(&ip->i_iolock);
- }
- return 0;
- }
- }
- xfs_ilock_trace(ip, 2, lock_flags, (inst_t *)__return_address);
- return 1;
-}
-
-/*
- * xfs_iunlock() is used to drop the inode locks acquired with
- * xfs_ilock() and xfs_ilock_nowait(). The caller must pass
- * in the flags given to xfs_ilock() or xfs_ilock_nowait() so
- * that we know which locks to drop.
- *
- * ip -- the inode being unlocked
- * lock_flags -- this parameter indicates the inode's locks to be
- * to be unlocked. See the comment for xfs_ilock() for a list
- * of valid values for this parameter.
- *
- */
-void
-xfs_iunlock(xfs_inode_t *ip,
- uint lock_flags)
-{
- /*
- * You can't set both SHARED and EXCL for the same lock,
- * and only XFS_IOLOCK_SHARED, XFS_IOLOCK_EXCL, XFS_ILOCK_SHARED,
- * and XFS_ILOCK_EXCL are valid values to set in lock_flags.
- */
- ASSERT((lock_flags & (XFS_IOLOCK_SHARED | XFS_IOLOCK_EXCL)) !=
- (XFS_IOLOCK_SHARED | XFS_IOLOCK_EXCL));
- ASSERT((lock_flags & (XFS_ILOCK_SHARED | XFS_ILOCK_EXCL)) !=
- (XFS_ILOCK_SHARED | XFS_ILOCK_EXCL));
- ASSERT((lock_flags & ~(XFS_LOCK_MASK | XFS_IUNLOCK_NONOTIFY)) == 0);
- ASSERT(lock_flags != 0);
-
- if (lock_flags & (XFS_IOLOCK_SHARED | XFS_IOLOCK_EXCL)) {
- ASSERT(!(lock_flags & XFS_IOLOCK_SHARED) ||
- (ismrlocked(&ip->i_iolock, MR_ACCESS)));
- ASSERT(!(lock_flags & XFS_IOLOCK_EXCL) ||
- (ismrlocked(&ip->i_iolock, MR_UPDATE)));
- mrunlock(&ip->i_iolock);
- }
-
- if (lock_flags & (XFS_ILOCK_SHARED | XFS_ILOCK_EXCL)) {
- ASSERT(!(lock_flags & XFS_ILOCK_SHARED) ||
- (ismrlocked(&ip->i_lock, MR_ACCESS)));
- ASSERT(!(lock_flags & XFS_ILOCK_EXCL) ||
- (ismrlocked(&ip->i_lock, MR_UPDATE)));
- mrunlock(&ip->i_lock);
-
- /*
- * Let the AIL know that this item has been unlocked in case
- * it is in the AIL and anyone is waiting on it. Don't do
- * this if the caller has asked us not to.
- */
- if (!(lock_flags & XFS_IUNLOCK_NONOTIFY) &&
- ip->i_itemp != NULL) {
- xfs_trans_unlocked_item(ip->i_mount,
- (xfs_log_item_t*)(ip->i_itemp));
- }
- }
- xfs_ilock_trace(ip, 3, lock_flags, (inst_t *)__return_address);
-}
-
-/*
- * give up write locks. the i/o lock cannot be held nested
- * if it is being demoted.
- */
-void
-xfs_ilock_demote(xfs_inode_t *ip,
- uint lock_flags)
-{
- ASSERT(lock_flags & (XFS_IOLOCK_EXCL|XFS_ILOCK_EXCL));
- ASSERT((lock_flags & ~(XFS_IOLOCK_EXCL|XFS_ILOCK_EXCL)) == 0);
-
- if (lock_flags & XFS_ILOCK_EXCL) {
- ASSERT(ismrlocked(&ip->i_lock, MR_UPDATE));
- mrdemote(&ip->i_lock);
- }
- if (lock_flags & XFS_IOLOCK_EXCL) {
- ASSERT(ismrlocked(&ip->i_iolock, MR_UPDATE));
- mrdemote(&ip->i_iolock);
- }
-}
-
-/*
- * The following three routines simply manage the i_flock
- * semaphore embedded in the inode. This semaphore synchronizes
- * processes attempting to flush the in-core inode back to disk.
- */
-void
-xfs_iflock(xfs_inode_t *ip)
-{
- psema(&(ip->i_flock), PINOD|PLTWAIT);
-}
-
-int
-xfs_iflock_nowait(xfs_inode_t *ip)
-{
- return (cpsema(&(ip->i_flock)));
-}
-
-void
-xfs_ifunlock(xfs_inode_t *ip)
-{
- ASSERT(valusema(&(ip->i_flock)) <= 0);
- vsema(&(ip->i_flock));
-}
diff --git a/sys/gnu/fs/xfs/xfs_imap.h b/sys/gnu/fs/xfs/xfs_imap.h
deleted file mode 100644
index d364500..0000000
--- a/sys/gnu/fs/xfs/xfs_imap.h
+++ /dev/null
@@ -1,40 +0,0 @@
-/*
- * Copyright (c) 2000,2005 Silicon Graphics, Inc.
- * All Rights Reserved.
- *
- * 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.
- *
- * This program is distributed in the hope that it would 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 the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- */
-#ifndef __XFS_IMAP_H__
-#define __XFS_IMAP_H__
-
-/*
- * This is the structure passed to xfs_imap() to map
- * an inode number to its on disk location.
- */
-typedef struct xfs_imap {
- xfs_daddr_t im_blkno; /* starting BB of inode chunk */
- uint im_len; /* length in BBs of inode chunk */
- xfs_agblock_t im_agblkno; /* logical block of inode chunk in ag */
- ushort im_ioffset; /* inode offset in block in "inodes" */
- ushort im_boffset; /* inode offset in block in bytes */
-} xfs_imap_t;
-
-#ifdef __KERNEL__
-struct xfs_mount;
-struct xfs_trans;
-int xfs_imap(struct xfs_mount *, struct xfs_trans *, xfs_ino_t,
- xfs_imap_t *, uint);
-#endif
-
-#endif /* __XFS_IMAP_H__ */
diff --git a/sys/gnu/fs/xfs/xfs_inode.c b/sys/gnu/fs/xfs/xfs_inode.c
deleted file mode 100644
index 53d46f0..0000000
--- a/sys/gnu/fs/xfs/xfs_inode.c
+++ /dev/null
@@ -1,4796 +0,0 @@
-/*
- * Copyright (c) 2000-2006 Silicon Graphics, Inc.
- * All Rights Reserved.
- *
- * 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.
- *
- * This program is distributed in the hope that it would 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 the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- */
-#include "xfs.h"
-#include "xfs_fs.h"
-#include "xfs_types.h"
-#include "xfs_bit.h"
-#include "xfs_log.h"
-#include "xfs_inum.h"
-#include "xfs_imap.h"
-#include "xfs_trans.h"
-#include "xfs_trans_priv.h"
-#include "xfs_sb.h"
-#include "xfs_ag.h"
-#include "xfs_dir.h"
-#include "xfs_dir2.h"
-#include "xfs_dmapi.h"
-#include "xfs_mount.h"
-#include "xfs_bmap_btree.h"
-#include "xfs_alloc_btree.h"
-#include "xfs_ialloc_btree.h"
-#include "xfs_dir_sf.h"
-#include "xfs_dir2_sf.h"
-#include "xfs_attr_sf.h"
-#include "xfs_dinode.h"
-#include "xfs_inode.h"
-#include "xfs_buf_item.h"
-#include "xfs_inode_item.h"
-#include "xfs_btree.h"
-#include "xfs_alloc.h"
-#include "xfs_ialloc.h"
-#include "xfs_bmap.h"
-#include "xfs_rw.h"
-#include "xfs_error.h"
-#include "xfs_utils.h"
-#include "xfs_dir2_trace.h"
-#include "xfs_quota.h"
-#include "xfs_mac.h"
-#include "xfs_acl.h"
-
-
-kmem_zone_t *xfs_ifork_zone;
-kmem_zone_t *xfs_inode_zone;
-kmem_zone_t *xfs_chashlist_zone;
-
-/*
- * Used in xfs_itruncate(). This is the maximum number of extents
- * freed from a file in a single transaction.
- */
-#define XFS_ITRUNC_MAX_EXTENTS 2
-
-STATIC int xfs_iflush_int(xfs_inode_t *, xfs_buf_t *);
-STATIC int xfs_iformat_local(xfs_inode_t *, xfs_dinode_t *, int, int);
-STATIC int xfs_iformat_extents(xfs_inode_t *, xfs_dinode_t *, int);
-STATIC int xfs_iformat_btree(xfs_inode_t *, xfs_dinode_t *, int);
-
-#ifdef DEBUG
-/*
- * Make sure that the extents in the given memory buffer
- * are valid.
- */
-STATIC void
-xfs_validate_extents(
- xfs_ifork_t *ifp,
- int nrecs,
- int disk,
- xfs_exntfmt_t fmt)
-{
- xfs_bmbt_rec_t *ep;
- xfs_bmbt_irec_t irec;
- xfs_bmbt_rec_t rec;
- int i;
-
- for (i = 0; i < nrecs; i++) {
- ep = xfs_iext_get_ext(ifp, i);
- rec.l0 = get_unaligned((__uint64_t*)&ep->l0);
- rec.l1 = get_unaligned((__uint64_t*)&ep->l1);
- if (disk)
- xfs_bmbt_disk_get_all(&rec, &irec);
- else
- xfs_bmbt_get_all(&rec, &irec);
- if (fmt == XFS_EXTFMT_NOSTATE)
- ASSERT(irec.br_state == XFS_EXT_NORM);
- }
-}
-#else /* DEBUG */
-#define xfs_validate_extents(ifp, nrecs, disk, fmt)
-#endif /* DEBUG */
-
-/*
- * Check that none of the inode's in the buffer have a next
- * unlinked field of 0.
- */
-#if defined(DEBUG)
-void
-xfs_inobp_check(
- xfs_mount_t *mp,
- xfs_buf_t *bp)
-{
- int i;
- int j;
- xfs_dinode_t *dip;
-
- j = mp->m_inode_cluster_size >> mp->m_sb.sb_inodelog;
-
- for (i = 0; i < j; i++) {
- dip = (xfs_dinode_t *)xfs_buf_offset(bp,
- i * mp->m_sb.sb_inodesize);
- if (!dip->di_next_unlinked) {
- xfs_fs_cmn_err(CE_ALERT, mp,
- "Detected a bogus zero next_unlinked field in incore inode buffer 0x%p. About to pop an ASSERT.",
- bp);
- ASSERT(dip->di_next_unlinked);
- }
- }
-}
-#endif
-
-/*
- * This routine is called to map an inode number within a file
- * system to the buffer containing the on-disk version of the
- * inode. It returns a pointer to the buffer containing the
- * on-disk inode in the bpp parameter, and in the dip parameter
- * it returns a pointer to the on-disk inode within that buffer.
- *
- * If a non-zero error is returned, then the contents of bpp and
- * dipp are undefined.
- *
- * Use xfs_imap() to determine the size and location of the
- * buffer to read from disk.
- */
-STATIC int
-xfs_inotobp(
- xfs_mount_t *mp,
- xfs_trans_t *tp,
- xfs_ino_t ino,
- xfs_dinode_t **dipp,
- xfs_buf_t **bpp,
- int *offset)
-{
- int di_ok;
- xfs_imap_t imap;
- xfs_buf_t *bp;
- int error;
- xfs_dinode_t *dip;
-
- /*
- * Call the space management code to find the location of the
- * inode on disk.
- */
- imap.im_blkno = 0;
- error = xfs_imap(mp, tp, ino, &imap, XFS_IMAP_LOOKUP);
- if (error != 0) {
- cmn_err(CE_WARN,
- "xfs_inotobp: xfs_imap() returned an "
- "error %d on %s. Returning error.", error, mp->m_fsname);
- return error;
- }
-
- /*
- * If the inode number maps to a block outside the bounds of the
- * file system then return NULL rather than calling read_buf
- * and panicing when we get an error from the driver.
- */
- if ((imap.im_blkno + imap.im_len) >
- XFS_FSB_TO_BB(mp, mp->m_sb.sb_dblocks)) {
- cmn_err(CE_WARN,
- "xfs_inotobp: inode number (%llu + %d) maps to a block outside the bounds "
- "of the file system %s. Returning EINVAL.",
- (unsigned long long)imap.im_blkno,
- imap.im_len, mp->m_fsname);
- return XFS_ERROR(EINVAL);
- }
-
- /*
- * Read in the buffer. If tp is NULL, xfs_trans_read_buf() will
- * default to just a read_buf() call.
- */
- error = xfs_trans_read_buf(mp, tp, mp->m_ddev_targp, imap.im_blkno,
- (int)imap.im_len, XFS_BUF_LOCK, &bp);
-
- if (error) {
- cmn_err(CE_WARN,
- "xfs_inotobp: xfs_trans_read_buf() returned an "
- "error %d on %s. Returning error.", error, mp->m_fsname);
- return error;
- }
- dip = (xfs_dinode_t *)xfs_buf_offset(bp, 0);
- di_ok =
- INT_GET(dip->di_core.di_magic, ARCH_CONVERT) == XFS_DINODE_MAGIC &&
- XFS_DINODE_GOOD_VERSION(INT_GET(dip->di_core.di_version, ARCH_CONVERT));
- if (unlikely(XFS_TEST_ERROR(!di_ok, mp, XFS_ERRTAG_ITOBP_INOTOBP,
- XFS_RANDOM_ITOBP_INOTOBP))) {
- XFS_CORRUPTION_ERROR("xfs_inotobp", XFS_ERRLEVEL_LOW, mp, dip);
- xfs_trans_brelse(tp, bp);
- cmn_err(CE_WARN,
- "xfs_inotobp: XFS_TEST_ERROR() returned an "
- "error on %s. Returning EFSCORRUPTED.", mp->m_fsname);
- return XFS_ERROR(EFSCORRUPTED);
- }
-
- xfs_inobp_check(mp, bp);
-
- /*
- * Set *dipp to point to the on-disk inode in the buffer.
- */
- *dipp = (xfs_dinode_t *)xfs_buf_offset(bp, imap.im_boffset);
- *bpp = bp;
- *offset = imap.im_boffset;
- return 0;
-}
-
-
-/*
- * This routine is called to map an inode to the buffer containing
- * the on-disk version of the inode. It returns a pointer to the
- * buffer containing the on-disk inode in the bpp parameter, and in
- * the dip parameter it returns a pointer to the on-disk inode within
- * that buffer.
- *
- * If a non-zero error is returned, then the contents of bpp and
- * dipp are undefined.
- *
- * If the inode is new and has not yet been initialized, use xfs_imap()
- * to determine the size and location of the buffer to read from disk.
- * If the inode has already been mapped to its buffer and read in once,
- * then use the mapping information stored in the inode rather than
- * calling xfs_imap(). This allows us to avoid the overhead of looking
- * at the inode btree for small block file systems (see xfs_dilocate()).
- * We can tell whether the inode has been mapped in before by comparing
- * its disk block address to 0. Only uninitialized inodes will have
- * 0 for the disk block address.
- */
-int
-xfs_itobp(
- xfs_mount_t *mp,
- xfs_trans_t *tp,
- xfs_inode_t *ip,
- xfs_dinode_t **dipp,
- xfs_buf_t **bpp,
- xfs_daddr_t bno,
- uint imap_flags)
-{
- xfs_buf_t *bp;
- int error;
- xfs_imap_t imap;
-#ifdef __KERNEL__
- int i;
- int ni;
-#endif
-
- if (ip->i_blkno == (xfs_daddr_t)0) {
- /*
- * Call the space management code to find the location of the
- * inode on disk.
- */
- imap.im_blkno = bno;
- if ((error = xfs_imap(mp, tp, ip->i_ino, &imap,
- XFS_IMAP_LOOKUP | imap_flags)))
- return error;
-
- /*
- * If the inode number maps to a block outside the bounds
- * of the file system then return NULL rather than calling
- * read_buf and panicing when we get an error from the
- * driver.
- */
- if ((imap.im_blkno + imap.im_len) >
- XFS_FSB_TO_BB(mp, mp->m_sb.sb_dblocks)) {
-#ifdef DEBUG
- xfs_fs_cmn_err(CE_ALERT, mp, "xfs_itobp: "
- "(imap.im_blkno (0x%llx) "
- "+ imap.im_len (0x%llx)) > "
- " XFS_FSB_TO_BB(mp, "
- "mp->m_sb.sb_dblocks) (0x%llx)",
- (unsigned long long) imap.im_blkno,
- (unsigned long long) imap.im_len,
- XFS_FSB_TO_BB(mp, mp->m_sb.sb_dblocks));
-#endif /* DEBUG */
- return XFS_ERROR(EINVAL);
- }
-
- /*
- * Fill in the fields in the inode that will be used to
- * map the inode to its buffer from now on.
- */
- ip->i_blkno = imap.im_blkno;
- ip->i_len = imap.im_len;
- ip->i_boffset = imap.im_boffset;
- } else {
- /*
- * We've already mapped the inode once, so just use the
- * mapping that we saved the first time.
- */
- imap.im_blkno = ip->i_blkno;
- imap.im_len = ip->i_len;
- imap.im_boffset = ip->i_boffset;
- }
- ASSERT(bno == 0 || bno == imap.im_blkno);
-
- /*
- * Read in the buffer. If tp is NULL, xfs_trans_read_buf() will
- * default to just a read_buf() call.
- */
- error = xfs_trans_read_buf(mp, tp, mp->m_ddev_targp, imap.im_blkno,
- (int)imap.im_len, XFS_BUF_LOCK, &bp);
-
- if (error) {
-#ifdef DEBUG
- xfs_fs_cmn_err(CE_ALERT, mp, "xfs_itobp: "
- "xfs_trans_read_buf() returned error %d, "
- "imap.im_blkno 0x%llx, imap.im_len 0x%llx",
- error, (unsigned long long) imap.im_blkno,
- (unsigned long long) imap.im_len);
-#endif /* DEBUG */
- return error;
- }
-#ifdef __KERNEL__
- /*
- * Validate the magic number and version of every inode in the buffer
- * (if DEBUG kernel) or the first inode in the buffer, otherwise.
- */
-#ifdef DEBUG
- ni = (imap_flags & XFS_IMAP_BULKSTAT) ? 0 :
- (BBTOB(imap.im_len) >> mp->m_sb.sb_inodelog);
-#else
- ni = (imap_flags & XFS_IMAP_BULKSTAT) ? 0 : 1;
-#endif
- for (i = 0; i < ni; i++) {
- int di_ok;
- xfs_dinode_t *dip;
-
- dip = (xfs_dinode_t *)xfs_buf_offset(bp,
- (i << mp->m_sb.sb_inodelog));
- di_ok = INT_GET(dip->di_core.di_magic, ARCH_CONVERT) == XFS_DINODE_MAGIC &&
- XFS_DINODE_GOOD_VERSION(INT_GET(dip->di_core.di_version, ARCH_CONVERT));
- if (unlikely(XFS_TEST_ERROR(!di_ok, mp, XFS_ERRTAG_ITOBP_INOTOBP,
- XFS_RANDOM_ITOBP_INOTOBP))) {
-#ifdef DEBUG
- prdev("bad inode magic/vsn daddr %lld #%d (magic=%x)",
- mp->m_ddev_targp,
- (unsigned long long)imap.im_blkno, i,
- INT_GET(dip->di_core.di_magic, ARCH_CONVERT));
-#endif
- XFS_CORRUPTION_ERROR("xfs_itobp", XFS_ERRLEVEL_HIGH,
- mp, dip);
- xfs_trans_brelse(tp, bp);
- return XFS_ERROR(EFSCORRUPTED);
- }
- }
-#endif /* __KERNEL__ */
-
- xfs_inobp_check(mp, bp);
-
- /*
- * Mark the buffer as an inode buffer now that it looks good
- */
- XFS_BUF_SET_VTYPE(bp, B_FS_INO);
-
- /*
- * Set *dipp to point to the on-disk inode in the buffer.
- */
- *dipp = (xfs_dinode_t *)xfs_buf_offset(bp, imap.im_boffset);
- *bpp = bp;
- return 0;
-}
-
-/*
- * Move inode type and inode format specific information from the
- * on-disk inode to the in-core inode. For fifos, devs, and sockets
- * this means set if_rdev to the proper value. For files, directories,
- * and symlinks this means to bring in the in-line data or extent
- * pointers. For a file in B-tree format, only the root is immediately
- * brought in-core. The rest will be in-lined in if_extents when it
- * is first referenced (see xfs_iread_extents()).
- */
-STATIC int
-xfs_iformat(
- xfs_inode_t *ip,
- xfs_dinode_t *dip)
-{
- xfs_attr_shortform_t *atp;
- int size;
- int error;
- xfs_fsize_t di_size;
- ip->i_df.if_ext_max =
- XFS_IFORK_DSIZE(ip) / (uint)sizeof(xfs_bmbt_rec_t);
- error = 0;
-
- if (unlikely(
- INT_GET(dip->di_core.di_nextents, ARCH_CONVERT) +
- INT_GET(dip->di_core.di_anextents, ARCH_CONVERT) >
- INT_GET(dip->di_core.di_nblocks, ARCH_CONVERT))) {
- xfs_fs_repair_cmn_err(CE_WARN, ip->i_mount,
- "corrupt dinode %Lu, extent total = %d, nblocks = %Lu.",
- (unsigned long long)ip->i_ino,
- (int)(INT_GET(dip->di_core.di_nextents, ARCH_CONVERT)
- + INT_GET(dip->di_core.di_anextents, ARCH_CONVERT)),
- (unsigned long long)
- INT_GET(dip->di_core.di_nblocks, ARCH_CONVERT));
- XFS_CORRUPTION_ERROR("xfs_iformat(1)", XFS_ERRLEVEL_LOW,
- ip->i_mount, dip);
- return XFS_ERROR(EFSCORRUPTED);
- }
-
- if (unlikely(INT_GET(dip->di_core.di_forkoff, ARCH_CONVERT) > ip->i_mount->m_sb.sb_inodesize)) {
- xfs_fs_repair_cmn_err(CE_WARN, ip->i_mount,
- "corrupt dinode %Lu, forkoff = 0x%x.",
- (unsigned long long)ip->i_ino,
- (int)(INT_GET(dip->di_core.di_forkoff, ARCH_CONVERT)));
- XFS_CORRUPTION_ERROR("xfs_iformat(2)", XFS_ERRLEVEL_LOW,
- ip->i_mount, dip);
- return XFS_ERROR(EFSCORRUPTED);
- }
-
- switch (ip->i_d.di_mode & S_IFMT) {
- case S_IFIFO:
- case S_IFCHR:
- case S_IFBLK:
- case S_IFSOCK:
- if (unlikely(INT_GET(dip->di_core.di_format, ARCH_CONVERT) != XFS_DINODE_FMT_DEV)) {
- XFS_CORRUPTION_ERROR("xfs_iformat(3)", XFS_ERRLEVEL_LOW,
- ip->i_mount, dip);
- return XFS_ERROR(EFSCORRUPTED);
- }
- ip->i_d.di_size = 0;
- ip->i_df.if_u2.if_rdev = INT_GET(dip->di_u.di_dev, ARCH_CONVERT);
- break;
-
- case S_IFREG:
- case S_IFLNK:
- case S_IFDIR:
- switch (INT_GET(dip->di_core.di_format, ARCH_CONVERT)) {
- case XFS_DINODE_FMT_LOCAL:
- /*
- * no local regular files yet
- */
- if (unlikely((INT_GET(dip->di_core.di_mode, ARCH_CONVERT) & S_IFMT) == S_IFREG)) {
- xfs_fs_repair_cmn_err(CE_WARN, ip->i_mount,
- "corrupt inode %Lu "
- "(local format for regular file).",
- (unsigned long long) ip->i_ino);
- XFS_CORRUPTION_ERROR("xfs_iformat(4)",
- XFS_ERRLEVEL_LOW,
- ip->i_mount, dip);
- return XFS_ERROR(EFSCORRUPTED);
- }
-
- di_size = INT_GET(dip->di_core.di_size, ARCH_CONVERT);
- if (unlikely(di_size > XFS_DFORK_DSIZE(dip, ip->i_mount))) {
- xfs_fs_repair_cmn_err(CE_WARN, ip->i_mount,
- "corrupt inode %Lu "
- "(bad size %Ld for local inode).",
- (unsigned long long) ip->i_ino,
- (long long) di_size);
- XFS_CORRUPTION_ERROR("xfs_iformat(5)",
- XFS_ERRLEVEL_LOW,
- ip->i_mount, dip);
- return XFS_ERROR(EFSCORRUPTED);
- }
-
- size = (int)di_size;
- error = xfs_iformat_local(ip, dip, XFS_DATA_FORK, size);
- break;
- case XFS_DINODE_FMT_EXTENTS:
- error = xfs_iformat_extents(ip, dip, XFS_DATA_FORK);
- break;
- case XFS_DINODE_FMT_BTREE:
- error = xfs_iformat_btree(ip, dip, XFS_DATA_FORK);
- break;
- default:
- XFS_ERROR_REPORT("xfs_iformat(6)", XFS_ERRLEVEL_LOW,
- ip->i_mount);
- return XFS_ERROR(EFSCORRUPTED);
- }
- break;
-
- default:
- XFS_ERROR_REPORT("xfs_iformat(7)", XFS_ERRLEVEL_LOW, ip->i_mount);
- return XFS_ERROR(EFSCORRUPTED);
- }
- if (error) {
- return error;
- }
- if (!XFS_DFORK_Q(dip))
- return 0;
- ASSERT(ip->i_afp == NULL);
- ip->i_afp = kmem_zone_zalloc(xfs_ifork_zone, KM_SLEEP);
- ip->i_afp->if_ext_max =
- XFS_IFORK_ASIZE(ip) / (uint)sizeof(xfs_bmbt_rec_t);
- switch (INT_GET(dip->di_core.di_aformat, ARCH_CONVERT)) {
- case XFS_DINODE_FMT_LOCAL:
- atp = (xfs_attr_shortform_t *)XFS_DFORK_APTR(dip);
- size = be16_to_cpu(atp->hdr.totsize);
- error = xfs_iformat_local(ip, dip, XFS_ATTR_FORK, size);
- break;
- case XFS_DINODE_FMT_EXTENTS:
- error = xfs_iformat_extents(ip, dip, XFS_ATTR_FORK);
- break;
- case XFS_DINODE_FMT_BTREE:
- error = xfs_iformat_btree(ip, dip, XFS_ATTR_FORK);
- break;
- default:
- error = XFS_ERROR(EFSCORRUPTED);
- break;
- }
- if (error) {
- kmem_zone_free(xfs_ifork_zone, ip->i_afp);
- ip->i_afp = NULL;
- xfs_idestroy_fork(ip, XFS_DATA_FORK);
- }
- return error;
-}
-
-/*
- * The file is in-lined in the on-disk inode.
- * If it fits into if_inline_data, then copy
- * it there, otherwise allocate a buffer for it
- * and copy the data there. Either way, set
- * if_data to point at the data.
- * If we allocate a buffer for the data, make
- * sure that its size is a multiple of 4 and
- * record the real size in i_real_bytes.
- */
-STATIC int
-xfs_iformat_local(
- xfs_inode_t *ip,
- xfs_dinode_t *dip,
- int whichfork,
- int size)
-{
- xfs_ifork_t *ifp;
- int real_size;
-
- /*
- * If the size is unreasonable, then something
- * is wrong and we just bail out rather than crash in
- * kmem_alloc() or memcpy() below.
- */
- if (unlikely(size > XFS_DFORK_SIZE(dip, ip->i_mount, whichfork))) {
- xfs_fs_repair_cmn_err(CE_WARN, ip->i_mount,
- "corrupt inode %Lu "
- "(bad size %d for local fork, size = %d).",
- (unsigned long long) ip->i_ino, size,
- XFS_DFORK_SIZE(dip, ip->i_mount, whichfork));
- XFS_CORRUPTION_ERROR("xfs_iformat_local", XFS_ERRLEVEL_LOW,
- ip->i_mount, dip);
- return XFS_ERROR(EFSCORRUPTED);
- }
- ifp = XFS_IFORK_PTR(ip, whichfork);
- real_size = 0;
- if (size == 0)
- ifp->if_u1.if_data = NULL;
- else if (size <= sizeof(ifp->if_u2.if_inline_data))
- ifp->if_u1.if_data = ifp->if_u2.if_inline_data;
- else {
- real_size = roundup(size, 4);
- ifp->if_u1.if_data = kmem_alloc(real_size, KM_SLEEP);
- }
- ifp->if_bytes = size;
- ifp->if_real_bytes = real_size;
- if (size)
- memcpy(ifp->if_u1.if_data, XFS_DFORK_PTR(dip, whichfork), size);
- ifp->if_flags &= ~XFS_IFEXTENTS;
- ifp->if_flags |= XFS_IFINLINE;
- return 0;
-}
-
-/*
- * The file consists of a set of extents all
- * of which fit into the on-disk inode.
- * If there are few enough extents to fit into
- * the if_inline_ext, then copy them there.
- * Otherwise allocate a buffer for them and copy
- * them into it. Either way, set if_extents
- * to point at the extents.
- */
-STATIC int
-xfs_iformat_extents(
- xfs_inode_t *ip,
- xfs_dinode_t *dip,
- int whichfork)
-{
- xfs_bmbt_rec_t *ep, *dp;
- xfs_ifork_t *ifp;
- int nex;
- int size;
- int i;
-
- ifp = XFS_IFORK_PTR(ip, whichfork);
- nex = XFS_DFORK_NEXTENTS(dip, whichfork);
- size = nex * (uint)sizeof(xfs_bmbt_rec_t);
-
- /*
- * If the number of extents is unreasonable, then something
- * is wrong and we just bail out rather than crash in
- * kmem_alloc() or memcpy() below.
- */
- if (unlikely(size < 0 || size > XFS_DFORK_SIZE(dip, ip->i_mount, whichfork))) {
- xfs_fs_repair_cmn_err(CE_WARN, ip->i_mount,
- "corrupt inode %Lu ((a)extents = %d).",
- (unsigned long long) ip->i_ino, nex);
- XFS_CORRUPTION_ERROR("xfs_iformat_extents(1)", XFS_ERRLEVEL_LOW,
- ip->i_mount, dip);
- return XFS_ERROR(EFSCORRUPTED);
- }
-
- ifp->if_real_bytes = 0;
- if (nex == 0)
- ifp->if_u1.if_extents = NULL;
- else if (nex <= XFS_INLINE_EXTS)
- ifp->if_u1.if_extents = ifp->if_u2.if_inline_ext;
- else
- xfs_iext_add(ifp, 0, nex);
-
- ifp->if_bytes = size;
- if (size) {
- dp = (xfs_bmbt_rec_t *) XFS_DFORK_PTR(dip, whichfork);
- xfs_validate_extents(ifp, nex, 1, XFS_EXTFMT_INODE(ip));
- for (i = 0; i < nex; i++, dp++) {
- ep = xfs_iext_get_ext(ifp, i);
- ep->l0 = INT_GET(get_unaligned((__uint64_t*)&dp->l0),
- ARCH_CONVERT);
- ep->l1 = INT_GET(get_unaligned((__uint64_t*)&dp->l1),
- ARCH_CONVERT);
- }
- xfs_bmap_trace_exlist("xfs_iformat_extents", ip, nex,
- whichfork);
- if (whichfork != XFS_DATA_FORK ||
- XFS_EXTFMT_INODE(ip) == XFS_EXTFMT_NOSTATE)
- if (unlikely(xfs_check_nostate_extents(
- ifp, 0, nex))) {
- XFS_ERROR_REPORT("xfs_iformat_extents(2)",
- XFS_ERRLEVEL_LOW,
- ip->i_mount);
- return XFS_ERROR(EFSCORRUPTED);
- }
- }
- ifp->if_flags |= XFS_IFEXTENTS;
- return 0;
-}
-
-/*
- * The file has too many extents to fit into
- * the inode, so they are in B-tree format.
- * Allocate a buffer for the root of the B-tree
- * and copy the root into it. The i_extents
- * field will remain NULL until all of the
- * extents are read in (when they are needed).
- */
-STATIC int
-xfs_iformat_btree(
- xfs_inode_t *ip,
- xfs_dinode_t *dip,
- int whichfork)
-{
- xfs_bmdr_block_t *dfp;
- xfs_ifork_t *ifp;
- /* REFERENCED */
- int nrecs;
- int size;
-
- ifp = XFS_IFORK_PTR(ip, whichfork);
- dfp = (xfs_bmdr_block_t *)XFS_DFORK_PTR(dip, whichfork);
- size = XFS_BMAP_BROOT_SPACE(dfp);
- nrecs = XFS_BMAP_BROOT_NUMRECS(dfp);
-
- /*
- * blow out if -- fork has less extents than can fit in
- * fork (fork shouldn't be a btree format), root btree
- * block has more records than can fit into the fork,
- * or the number of extents is greater than the number of
- * blocks.
- */
- if (unlikely(XFS_IFORK_NEXTENTS(ip, whichfork) <= ifp->if_ext_max
- || XFS_BMDR_SPACE_CALC(nrecs) >
- XFS_DFORK_SIZE(dip, ip->i_mount, whichfork)
- || XFS_IFORK_NEXTENTS(ip, whichfork) > ip->i_d.di_nblocks)) {
- xfs_fs_repair_cmn_err(CE_WARN, ip->i_mount,
- "corrupt inode %Lu (btree).",
- (unsigned long long) ip->i_ino);
- XFS_ERROR_REPORT("xfs_iformat_btree", XFS_ERRLEVEL_LOW,
- ip->i_mount);
- return XFS_ERROR(EFSCORRUPTED);
- }
-
- ifp->if_broot_bytes = size;
- ifp->if_broot = kmem_alloc(size, KM_SLEEP);
- ASSERT(ifp->if_broot != NULL);
- /*
- * Copy and convert from the on-disk structure
- * to the in-memory structure.
- */
- xfs_bmdr_to_bmbt(dfp, XFS_DFORK_SIZE(dip, ip->i_mount, whichfork),
- ifp->if_broot, size);
- ifp->if_flags &= ~XFS_IFEXTENTS;
- ifp->if_flags |= XFS_IFBROOT;
-
- return 0;
-}
-
-/*
- * xfs_xlate_dinode_core - translate an xfs_inode_core_t between ondisk
- * and native format
- *
- * buf = on-disk representation
- * dip = native representation
- * dir = direction - +ve -> disk to native
- * -ve -> native to disk
- */
-void
-xfs_xlate_dinode_core(
- xfs_caddr_t buf,
- xfs_dinode_core_t *dip,
- int dir)
-{
- xfs_dinode_core_t *buf_core = (xfs_dinode_core_t *)buf;
- xfs_dinode_core_t *mem_core = (xfs_dinode_core_t *)dip;
- xfs_arch_t arch = ARCH_CONVERT;
-
- ASSERT(dir);
-
- INT_XLATE(buf_core->di_magic, mem_core->di_magic, dir, arch);
- INT_XLATE(buf_core->di_mode, mem_core->di_mode, dir, arch);
- INT_XLATE(buf_core->di_version, mem_core->di_version, dir, arch);
- INT_XLATE(buf_core->di_format, mem_core->di_format, dir, arch);
- INT_XLATE(buf_core->di_onlink, mem_core->di_onlink, dir, arch);
- INT_XLATE(buf_core->di_uid, mem_core->di_uid, dir, arch);
- INT_XLATE(buf_core->di_gid, mem_core->di_gid, dir, arch);
- INT_XLATE(buf_core->di_nlink, mem_core->di_nlink, dir, arch);
- INT_XLATE(buf_core->di_projid, mem_core->di_projid, dir, arch);
-
- if (dir > 0) {
- memcpy(mem_core->di_pad, buf_core->di_pad,
- sizeof(buf_core->di_pad));
- } else {
- memcpy(buf_core->di_pad, mem_core->di_pad,
- sizeof(buf_core->di_pad));
- }
-
- INT_XLATE(buf_core->di_flushiter, mem_core->di_flushiter, dir, arch);
-
- INT_XLATE(buf_core->di_atime.t_sec, mem_core->di_atime.t_sec,
- dir, arch);
- INT_XLATE(buf_core->di_atime.t_nsec, mem_core->di_atime.t_nsec,
- dir, arch);
- INT_XLATE(buf_core->di_mtime.t_sec, mem_core->di_mtime.t_sec,
- dir, arch);
- INT_XLATE(buf_core->di_mtime.t_nsec, mem_core->di_mtime.t_nsec,
- dir, arch);
- INT_XLATE(buf_core->di_ctime.t_sec, mem_core->di_ctime.t_sec,
- dir, arch);
- INT_XLATE(buf_core->di_ctime.t_nsec, mem_core->di_ctime.t_nsec,
- dir, arch);
- INT_XLATE(buf_core->di_size, mem_core->di_size, dir, arch);
- INT_XLATE(buf_core->di_nblocks, mem_core->di_nblocks, dir, arch);
- INT_XLATE(buf_core->di_extsize, mem_core->di_extsize, dir, arch);
- INT_XLATE(buf_core->di_nextents, mem_core->di_nextents, dir, arch);
- INT_XLATE(buf_core->di_anextents, mem_core->di_anextents, dir, arch);
- INT_XLATE(buf_core->di_forkoff, mem_core->di_forkoff, dir, arch);
- INT_XLATE(buf_core->di_aformat, mem_core->di_aformat, dir, arch);
- INT_XLATE(buf_core->di_dmevmask, mem_core->di_dmevmask, dir, arch);
- INT_XLATE(buf_core->di_dmstate, mem_core->di_dmstate, dir, arch);
- INT_XLATE(buf_core->di_flags, mem_core->di_flags, dir, arch);
- INT_XLATE(buf_core->di_gen, mem_core->di_gen, dir, arch);
-}
-
-STATIC uint
-_xfs_dic2xflags(
- xfs_dinode_core_t *dic,
- __uint16_t di_flags)
-{
- uint flags = 0;
-
- if (di_flags & XFS_DIFLAG_ANY) {
- if (di_flags & XFS_DIFLAG_REALTIME)
- flags |= XFS_XFLAG_REALTIME;
- if (di_flags & XFS_DIFLAG_PREALLOC)
- flags |= XFS_XFLAG_PREALLOC;
- if (di_flags & XFS_DIFLAG_IMMUTABLE)
- flags |= XFS_XFLAG_IMMUTABLE;
- if (di_flags & XFS_DIFLAG_APPEND)
- flags |= XFS_XFLAG_APPEND;
- if (di_flags & XFS_DIFLAG_SYNC)
- flags |= XFS_XFLAG_SYNC;
- if (di_flags & XFS_DIFLAG_NOATIME)
- flags |= XFS_XFLAG_NOATIME;
- if (di_flags & XFS_DIFLAG_NODUMP)
- flags |= XFS_XFLAG_NODUMP;
- if (di_flags & XFS_DIFLAG_RTINHERIT)
- flags |= XFS_XFLAG_RTINHERIT;
- if (di_flags & XFS_DIFLAG_PROJINHERIT)
- flags |= XFS_XFLAG_PROJINHERIT;
- if (di_flags & XFS_DIFLAG_NOSYMLINKS)
- flags |= XFS_XFLAG_NOSYMLINKS;
- if (di_flags & XFS_DIFLAG_EXTSIZE)
- flags |= XFS_XFLAG_EXTSIZE;
- if (di_flags & XFS_DIFLAG_EXTSZINHERIT)
- flags |= XFS_XFLAG_EXTSZINHERIT;
- }
-
- return flags;
-}
-
-uint
-xfs_ip2xflags(
- xfs_inode_t *ip)
-{
- xfs_dinode_core_t *dic = &ip->i_d;
-
- return _xfs_dic2xflags(dic, dic->di_flags) |
- (XFS_CFORK_Q(dic) ? XFS_XFLAG_HASATTR : 0);
-}
-
-uint
-xfs_dic2xflags(
- xfs_dinode_core_t *dic)
-{
- return _xfs_dic2xflags(dic, INT_GET(dic->di_flags, ARCH_CONVERT)) |
- (XFS_CFORK_Q_DISK(dic) ? XFS_XFLAG_HASATTR : 0);
-}
-
-/*
- * Given a mount structure and an inode number, return a pointer
- * to a newly allocated in-core inode corresponding to the given
- * inode number.
- *
- * Initialize the inode's attributes and extent pointers if it
- * already has them (it will not if the inode has no links).
- */
-int
-xfs_iread(
- xfs_mount_t *mp,
- xfs_trans_t *tp,
- xfs_ino_t ino,
- xfs_inode_t **ipp,
- xfs_daddr_t bno)
-{
- xfs_buf_t *bp;
- xfs_dinode_t *dip;
- xfs_inode_t *ip;
- int error;
-
- ASSERT(xfs_inode_zone != NULL);
-
- ip = kmem_zone_zalloc(xfs_inode_zone, KM_SLEEP);
- ip->i_ino = ino;
- ip->i_mount = mp;
-
- /*
- * Get pointer's to the on-disk inode and the buffer containing it.
- * If the inode number refers to a block outside the file system
- * then xfs_itobp() will return NULL. In this case we should
- * return NULL as well. Set i_blkno to 0 so that xfs_itobp() will
- * know that this is a new incore inode.
- */
- error = xfs_itobp(mp, tp, ip, &dip, &bp, bno, 0);
- if (error) {
- kmem_zone_free(xfs_inode_zone, ip);
- return error;
- }
-
- /*
- * Initialize inode's trace buffers.
- * Do this before xfs_iformat in case it adds entries.
- */
-#ifdef XFS_BMAP_TRACE
- ip->i_xtrace = ktrace_alloc(XFS_BMAP_KTRACE_SIZE, KM_SLEEP);
-#endif
-#ifdef XFS_BMBT_TRACE
- ip->i_btrace = ktrace_alloc(XFS_BMBT_KTRACE_SIZE, KM_SLEEP);
-#endif
-#ifdef XFS_RW_TRACE
- ip->i_rwtrace = ktrace_alloc(XFS_RW_KTRACE_SIZE, KM_SLEEP);
-#endif
-#ifdef XFS_ILOCK_TRACE
- ip->i_lock_trace = ktrace_alloc(XFS_ILOCK_KTRACE_SIZE, KM_SLEEP);
-#endif
-#ifdef XFS_DIR2_TRACE
- ip->i_dir_trace = ktrace_alloc(XFS_DIR2_KTRACE_SIZE, KM_SLEEP);
-#endif
-
- /*
- * If we got something that isn't an inode it means someone
- * (nfs or dmi) has a stale handle.
- */
- if (INT_GET(dip->di_core.di_magic, ARCH_CONVERT) != XFS_DINODE_MAGIC) {
- kmem_zone_free(xfs_inode_zone, ip);
- xfs_trans_brelse(tp, bp);
-#ifdef DEBUG
- xfs_fs_cmn_err(CE_ALERT, mp, "xfs_iread: "
- "dip->di_core.di_magic (0x%x) != "
- "XFS_DINODE_MAGIC (0x%x)",
- INT_GET(dip->di_core.di_magic, ARCH_CONVERT),
- XFS_DINODE_MAGIC);
-#endif /* DEBUG */
- return XFS_ERROR(EINVAL);
- }
-
- /*
- * If the on-disk inode is already linked to a directory
- * entry, copy all of the inode into the in-core inode.
- * xfs_iformat() handles copying in the inode format
- * specific information.
- * Otherwise, just get the truly permanent information.
- */
- if (dip->di_core.di_mode) {
- xfs_xlate_dinode_core((xfs_caddr_t)&dip->di_core,
- &(ip->i_d), 1);
- error = xfs_iformat(ip, dip);
- if (error) {
- kmem_zone_free(xfs_inode_zone, ip);
- xfs_trans_brelse(tp, bp);
-#ifdef DEBUG
- xfs_fs_cmn_err(CE_ALERT, mp, "xfs_iread: "
- "xfs_iformat() returned error %d",
- error);
-#endif /* DEBUG */
- return error;
- }
- } else {
- ip->i_d.di_magic = INT_GET(dip->di_core.di_magic, ARCH_CONVERT);
- ip->i_d.di_version = INT_GET(dip->di_core.di_version, ARCH_CONVERT);
- ip->i_d.di_gen = INT_GET(dip->di_core.di_gen, ARCH_CONVERT);
- ip->i_d.di_flushiter = INT_GET(dip->di_core.di_flushiter, ARCH_CONVERT);
- /*
- * Make sure to pull in the mode here as well in
- * case the inode is released without being used.
- * This ensures that xfs_inactive() will see that
- * the inode is already free and not try to mess
- * with the uninitialized part of it.
- */
- ip->i_d.di_mode = 0;
- /*
- * Initialize the per-fork minima and maxima for a new
- * inode here. xfs_iformat will do it for old inodes.
- */
- ip->i_df.if_ext_max =
- XFS_IFORK_DSIZE(ip) / (uint)sizeof(xfs_bmbt_rec_t);
- }
-
-#ifdef RMC
- INIT_LIST_HEAD(&ip->i_reclaim);
-#else
- bzero(&ip->i_reclaim,sizeof(ip->i_reclaim));
-#endif
-
-
- /*
- * The inode format changed when we moved the link count and
- * made it 32 bits long. If this is an old format inode,
- * convert it in memory to look like a new one. If it gets
- * flushed to disk we will convert back before flushing or
- * logging it. We zero out the new projid field and the old link
- * count field. We'll handle clearing the pad field (the remains
- * of the old uuid field) when we actually convert the inode to
- * the new format. We don't change the version number so that we
- * can distinguish this from a real new format inode.
- */
- if (ip->i_d.di_version == XFS_DINODE_VERSION_1) {
- ip->i_d.di_nlink = ip->i_d.di_onlink;
- ip->i_d.di_onlink = 0;
- ip->i_d.di_projid = 0;
- }
-
- ip->i_delayed_blks = 0;
-
- /*
- * Mark the buffer containing the inode as something to keep
- * around for a while. This helps to keep recently accessed
- * meta-data in-core longer.
- */
- XFS_BUF_SET_REF(bp, XFS_INO_REF);
-
- /*
- * Use xfs_trans_brelse() to release the buffer containing the
- * on-disk inode, because it was acquired with xfs_trans_read_buf()
- * in xfs_itobp() above. If tp is NULL, this is just a normal
- * brelse(). If we're within a transaction, then xfs_trans_brelse()
- * will only release the buffer if it is not dirty within the
- * transaction. It will be OK to release the buffer in this case,
- * because inodes on disk are never destroyed and we will be
- * locking the new in-core inode before putting it in the hash
- * table where other processes can find it. Thus we don't have
- * to worry about the inode being changed just because we released
- * the buffer.
- */
- xfs_trans_brelse(tp, bp);
- *ipp = ip;
- return 0;
-}
-
-/*
- * Read in extents from a btree-format inode.
- * Allocate and fill in if_extents. Real work is done in xfs_bmap.c.
- */
-int
-xfs_iread_extents(
- xfs_trans_t *tp,
- xfs_inode_t *ip,
- int whichfork)
-{
- int error;
- xfs_ifork_t *ifp;
- xfs_extnum_t nextents;
- size_t size;
-
- if (unlikely(XFS_IFORK_FORMAT(ip, whichfork) != XFS_DINODE_FMT_BTREE)) {
- XFS_ERROR_REPORT("xfs_iread_extents", XFS_ERRLEVEL_LOW,
- ip->i_mount);
- return XFS_ERROR(EFSCORRUPTED);
- }
- nextents = XFS_IFORK_NEXTENTS(ip, whichfork);
- size = nextents * sizeof(xfs_bmbt_rec_t);
- ifp = XFS_IFORK_PTR(ip, whichfork);
-
- /*
- * We know that the size is valid (it's checked in iformat_btree)
- */
- ifp->if_lastex = NULLEXTNUM;
- ifp->if_bytes = ifp->if_real_bytes = 0;
- ifp->if_flags |= XFS_IFEXTENTS;
- xfs_iext_add(ifp, 0, nextents);
- error = xfs_bmap_read_extents(tp, ip, whichfork);
- if (error) {
- xfs_iext_destroy(ifp);
- ifp->if_flags &= ~XFS_IFEXTENTS;
- return error;
- }
- xfs_validate_extents(ifp, nextents, 0, XFS_EXTFMT_INODE(ip));
- return 0;
-}
-
-/*
- * Allocate an inode on disk and return a copy of its in-core version.
- * The in-core inode is locked exclusively. Set mode, nlink, and rdev
- * appropriately within the inode. The uid and gid for the inode are
- * set according to the contents of the given cred structure.
- *
- * Use xfs_dialloc() to allocate the on-disk inode. If xfs_dialloc()
- * has a free inode available, call xfs_iget()
- * to obtain the in-core version of the allocated inode. Finally,
- * fill in the inode and log its initial contents. In this case,
- * ialloc_context would be set to NULL and call_again set to false.
- *
- * If xfs_dialloc() does not have an available inode,
- * it will replenish its supply by doing an allocation. Since we can
- * only do one allocation within a transaction without deadlocks, we
- * must commit the current transaction before returning the inode itself.
- * In this case, therefore, we will set call_again to true and return.
- * The caller should then commit the current transaction, start a new
- * transaction, and call xfs_ialloc() again to actually get the inode.
- *
- * To ensure that some other process does not grab the inode that
- * was allocated during the first call to xfs_ialloc(), this routine
- * also returns the [locked] bp pointing to the head of the freelist
- * as ialloc_context. The caller should hold this buffer across
- * the commit and pass it back into this routine on the second call.
- */
-int
-xfs_ialloc(
- xfs_trans_t *tp,
- xfs_inode_t *pip,
- mode_t mode,
- xfs_nlink_t nlink,
- xfs_dev_t rdev,
- cred_t *cr,
- xfs_prid_t prid,
- int okalloc,
- xfs_buf_t **ialloc_context,
- boolean_t *call_again,
- xfs_inode_t **ipp)
-{
- xfs_ino_t ino;
- xfs_inode_t *ip;
- xfs_vnode_t *vp;
- uint flags;
- int error;
-
- /*
- * Call the space management code to pick
- * the on-disk inode to be allocated.
- */
- error = xfs_dialloc(tp, pip->i_ino, mode, okalloc,
- ialloc_context, call_again, &ino);
- if (error != 0) {
- return error;
- }
- if (*call_again || ino == NULLFSINO) {
- *ipp = NULL;
- return 0;
- }
- ASSERT(*ialloc_context == NULL);
-
- /*
- * Get the in-core inode with the lock held exclusively.
- * This is because we're setting fields here we need
- * to prevent others from looking at until we're done.
- */
- error = xfs_trans_iget(tp->t_mountp, tp, ino,
- IGET_CREATE, XFS_ILOCK_EXCL, &ip);
- if (error != 0) {
- return error;
- }
- ASSERT(ip != NULL);
-
- vp = XFS_ITOV(ip);
- ip->i_d.di_mode = (__uint16_t)mode;
- ip->i_d.di_onlink = 0;
- ip->i_d.di_nlink = nlink;
- ASSERT(ip->i_d.di_nlink == nlink);
- ip->i_d.di_uid = curthread->td_ucred->cr_uid;
- ip->i_d.di_gid = curthread->td_ucred->cr_groups[0];
- ip->i_d.di_projid = prid;
- memset(&(ip->i_d.di_pad[0]), 0, sizeof(ip->i_d.di_pad));
-
- /*
- * If the superblock version is up to where we support new format
- * inodes and this is currently an old format inode, then change
- * the inode version number now. This way we only do the conversion
- * here rather than here and in the flush/logging code.
- */
- if (XFS_SB_VERSION_HASNLINK(&tp->t_mountp->m_sb) &&
- ip->i_d.di_version == XFS_DINODE_VERSION_1) {
- ip->i_d.di_version = XFS_DINODE_VERSION_2;
- /*
- * We've already zeroed the old link count, the projid field,
- * and the pad field.
- */
- }
-
- /*
- * Project ids won't be stored on disk if we are using a version 1 inode.
- */
- if ( (prid != 0) && (ip->i_d.di_version == XFS_DINODE_VERSION_1))
- xfs_bump_ino_vers2(tp, ip);
-
- if (XFS_INHERIT_GID(pip, vp->v_vfsp)) {
- ip->i_d.di_gid = pip->i_d.di_gid;
- if ((pip->i_d.di_mode & S_ISGID) && (mode & S_IFMT) == S_IFDIR) {
- ip->i_d.di_mode |= S_ISGID;
- }
- }
-
- /*
- * If the group ID of the new file does not match the effective group
- * ID or one of the supplementary group IDs, the S_ISGID bit is cleared
- * (and only if the irix_sgid_inherit compatibility variable is set).
- */
- if ((irix_sgid_inherit) &&
- (ip->i_d.di_mode & S_ISGID) &&
- (!groupmember((gid_t)ip->i_d.di_gid, curthread->td_ucred))) {
- ip->i_d.di_mode &= ~S_ISGID;
- }
-
- ip->i_d.di_size = 0;
- ip->i_d.di_nextents = 0;
- ASSERT(ip->i_d.di_nblocks == 0);
- xfs_ichgtime(ip, XFS_ICHGTIME_CHG|XFS_ICHGTIME_ACC|XFS_ICHGTIME_MOD);
- /*
- * di_gen will have been taken care of in xfs_iread.
- */
- ip->i_d.di_extsize = 0;
- ip->i_d.di_dmevmask = 0;
- ip->i_d.di_dmstate = 0;
- ip->i_d.di_flags = 0;
- flags = XFS_ILOG_CORE;
- switch (mode & S_IFMT) {
- case S_IFIFO:
- case S_IFCHR:
- case S_IFBLK:
- case S_IFSOCK:
- ip->i_d.di_format = XFS_DINODE_FMT_DEV;
- ip->i_df.if_u2.if_rdev = rdev;
- ip->i_df.if_flags = 0;
- flags |= XFS_ILOG_DEV;
- break;
- case S_IFREG:
- case S_IFDIR:
- if (unlikely(pip->i_d.di_flags & XFS_DIFLAG_ANY)) {
- uint di_flags = 0;
-
- if ((mode & S_IFMT) == S_IFDIR) {
- if (pip->i_d.di_flags & XFS_DIFLAG_RTINHERIT)
- di_flags |= XFS_DIFLAG_RTINHERIT;
- if (pip->i_d.di_flags & XFS_DIFLAG_EXTSZINHERIT) {
- di_flags |= XFS_DIFLAG_EXTSZINHERIT;
- ip->i_d.di_extsize = pip->i_d.di_extsize;
- }
- } else if ((mode & S_IFMT) == S_IFREG) {
- if (pip->i_d.di_flags & XFS_DIFLAG_RTINHERIT) {
- di_flags |= XFS_DIFLAG_REALTIME;
- ip->i_iocore.io_flags |= XFS_IOCORE_RT;
- }
- if (pip->i_d.di_flags & XFS_DIFLAG_EXTSZINHERIT) {
- di_flags |= XFS_DIFLAG_EXTSIZE;
- ip->i_d.di_extsize = pip->i_d.di_extsize;
- }
- }
- if ((pip->i_d.di_flags & XFS_DIFLAG_NOATIME) &&
- xfs_inherit_noatime)
- di_flags |= XFS_DIFLAG_NOATIME;
- if ((pip->i_d.di_flags & XFS_DIFLAG_NODUMP) &&
- xfs_inherit_nodump)
- di_flags |= XFS_DIFLAG_NODUMP;
- if ((pip->i_d.di_flags & XFS_DIFLAG_SYNC) &&
- xfs_inherit_sync)
- di_flags |= XFS_DIFLAG_SYNC;
- if ((pip->i_d.di_flags & XFS_DIFLAG_NOSYMLINKS) &&
- xfs_inherit_nosymlinks)
- di_flags |= XFS_DIFLAG_NOSYMLINKS;
- if (pip->i_d.di_flags & XFS_DIFLAG_PROJINHERIT)
- di_flags |= XFS_DIFLAG_PROJINHERIT;
- ip->i_d.di_flags |= di_flags;
- }
- /* FALLTHROUGH */
- case S_IFLNK:
- ip->i_d.di_format = XFS_DINODE_FMT_EXTENTS;
- ip->i_df.if_flags = XFS_IFEXTENTS;
- ip->i_df.if_bytes = ip->i_df.if_real_bytes = 0;
- ip->i_df.if_u1.if_extents = NULL;
- break;
- default:
- ASSERT(0);
- }
- /*
- * Attribute fork settings for new inode.
- */
- ip->i_d.di_aformat = XFS_DINODE_FMT_EXTENTS;
- ip->i_d.di_anextents = 0;
-
- /*
- * Log the new values stuffed into the inode.
- */
- xfs_trans_log_inode(tp, ip, flags);
-
- /* now that we have an i_mode we can set Linux inode ops (& unlock) */
- XVFS_INIT_VNODE(XFS_MTOVFS(tp->t_mountp), vp, XFS_ITOBHV(ip), 1);
-
- *ipp = ip;
- return 0;
-}
-
-/*
- * Check to make sure that there are no blocks allocated to the
- * file beyond the size of the file. We don't check this for
- * files with fixed size extents or real time extents, but we
- * at least do it for regular files.
- */
-#ifdef DEBUG
-void
-xfs_isize_check(
- xfs_mount_t *mp,
- xfs_inode_t *ip,
- xfs_fsize_t isize)
-{
- xfs_fileoff_t map_first;
- int nimaps;
- xfs_bmbt_irec_t imaps[2];
-
- if ((ip->i_d.di_mode & S_IFMT) != S_IFREG)
- return;
-
- if (ip->i_d.di_flags & (XFS_DIFLAG_REALTIME | XFS_DIFLAG_EXTSIZE))
- return;
-
- nimaps = 2;
- map_first = XFS_B_TO_FSB(mp, (xfs_ufsize_t)isize);
- /*
- * The filesystem could be shutting down, so bmapi may return
- * an error.
- */
- if (xfs_bmapi(NULL, ip, map_first,
- (XFS_B_TO_FSB(mp,
- (xfs_ufsize_t)XFS_MAXIOFFSET(mp)) -
- map_first),
- XFS_BMAPI_ENTIRE, NULL, 0, imaps, &nimaps,
- NULL, NULL))
- return;
- ASSERT(nimaps == 1);
- ASSERT(imaps[0].br_startblock == HOLESTARTBLOCK);
-}
-#endif /* DEBUG */
-
-/*
- * Calculate the last possible buffered byte in a file. This must
- * include data that was buffered beyond the EOF by the write code.
- * This also needs to deal with overflowing the xfs_fsize_t type
- * which can happen for sizes near the limit.
- *
- * We also need to take into account any blocks beyond the EOF. It
- * may be the case that they were buffered by a write which failed.
- * In that case the pages will still be in memory, but the inode size
- * will never have been updated.
- */
-xfs_fsize_t
-xfs_file_last_byte(
- xfs_inode_t *ip)
-{
- xfs_mount_t *mp;
- xfs_fsize_t last_byte;
- xfs_fileoff_t last_block;
- xfs_fileoff_t size_last_block;
- int error;
-
- ASSERT(ismrlocked(&(ip->i_iolock), MR_UPDATE | MR_ACCESS));
-
- mp = ip->i_mount;
- /*
- * Only check for blocks beyond the EOF if the extents have
- * been read in. This eliminates the need for the inode lock,
- * and it also saves us from looking when it really isn't
- * necessary.
- */
- if (ip->i_df.if_flags & XFS_IFEXTENTS) {
- error = xfs_bmap_last_offset(NULL, ip, &last_block,
- XFS_DATA_FORK);
- if (error) {
- last_block = 0;
- }
- } else {
- last_block = 0;
- }
- size_last_block = XFS_B_TO_FSB(mp, (xfs_ufsize_t)ip->i_d.di_size);
- last_block = XFS_FILEOFF_MAX(last_block, size_last_block);
-
- last_byte = XFS_FSB_TO_B(mp, last_block);
- if (last_byte < 0) {
- return XFS_MAXIOFFSET(mp);
- }
- last_byte += (1 << mp->m_writeio_log);
- if (last_byte < 0) {
- return XFS_MAXIOFFSET(mp);
- }
- return last_byte;
-}
-
-#if defined(XFS_RW_TRACE)
-STATIC void
-xfs_itrunc_trace(
- int tag,
- xfs_inode_t *ip,
- int flag,
- xfs_fsize_t new_size,
- xfs_off_t toss_start,
- xfs_off_t toss_finish)
-{
- if (ip->i_rwtrace == NULL) {
- return;
- }
-
- ktrace_enter(ip->i_rwtrace,
- (void*)((long)tag),
- (void*)ip,
- (void*)(unsigned long)((ip->i_d.di_size >> 32) & 0xffffffff),
- (void*)(unsigned long)(ip->i_d.di_size & 0xffffffff),
- (void*)((long)flag),
- (void*)(unsigned long)((new_size >> 32) & 0xffffffff),
- (void*)(unsigned long)(new_size & 0xffffffff),
- (void*)(unsigned long)((toss_start >> 32) & 0xffffffff),
- (void*)(unsigned long)(toss_start & 0xffffffff),
- (void*)(unsigned long)((toss_finish >> 32) & 0xffffffff),
- (void*)(unsigned long)(toss_finish & 0xffffffff),
- (void*)(unsigned long)current_cpu(),
- (void*)(unsigned long)current_pid(),
- (void*)NULL,
- (void*)NULL,
- (void*)NULL);
-}
-#else
-#define xfs_itrunc_trace(tag, ip, flag, new_size, toss_start, toss_finish)
-#endif
-
-/*
- * Start the truncation of the file to new_size. The new size
- * must be smaller than the current size. This routine will
- * clear the buffer and page caches of file data in the removed
- * range, and xfs_itruncate_finish() will remove the underlying
- * disk blocks.
- *
- * The inode must have its I/O lock locked EXCLUSIVELY, and it
- * must NOT have the inode lock held at all. This is because we're
- * calling into the buffer/page cache code and we can't hold the
- * inode lock when we do so.
- *
- * We need to wait for any direct I/Os in flight to complete before we
- * proceed with the truncate. This is needed to prevent the extents
- * being read or written by the direct I/Os from being removed while the
- * I/O is in flight as there is no other method of synchronising
- * direct I/O with the truncate operation. Also, because we hold
- * the IOLOCK in exclusive mode, we prevent new direct I/Os from being
- * started until the truncate completes and drops the lock. Essentially,
- * the vn_iowait() call forms an I/O barrier that provides strict ordering
- * between direct I/Os and the truncate operation.
- *
- * The flags parameter can have either the value XFS_ITRUNC_DEFINITE
- * or XFS_ITRUNC_MAYBE. The XFS_ITRUNC_MAYBE value should be used
- * in the case that the caller is locking things out of order and
- * may not be able to call xfs_itruncate_finish() with the inode lock
- * held without dropping the I/O lock. If the caller must drop the
- * I/O lock before calling xfs_itruncate_finish(), then xfs_itruncate_start()
- * must be called again with all the same restrictions as the initial
- * call.
- */
-void
-xfs_itruncate_start(
- xfs_inode_t *ip,
- uint flags,
- xfs_fsize_t new_size)
-{
- xfs_fsize_t last_byte;
- xfs_off_t toss_start;
- xfs_mount_t *mp;
- xfs_vnode_t *vp;
-
- ASSERT(ismrlocked(&ip->i_iolock, MR_UPDATE) != 0);
- ASSERT((new_size == 0) || (new_size <= ip->i_d.di_size));
- ASSERT((flags == XFS_ITRUNC_DEFINITE) ||
- (flags == XFS_ITRUNC_MAYBE));
-
- mp = ip->i_mount;
- vp = XFS_ITOV(ip);
-
- vn_iowait(vp); /* wait for the completion of any pending DIOs */
-
- /*
- * Call VOP_TOSS_PAGES() or VOP_FLUSHINVAL_PAGES() to get rid of pages and buffers
- * overlapping the region being removed. We have to use
- * the less efficient VOP_FLUSHINVAL_PAGES() in the case that the
- * caller may not be able to finish the truncate without
- * dropping the inode's I/O lock. Make sure
- * to catch any pages brought in by buffers overlapping
- * the EOF by searching out beyond the isize by our
- * block size. We round new_size up to a block boundary
- * so that we don't toss things on the same block as
- * new_size but before it.
- *
- * Before calling VOP_TOSS_PAGES() or VOP_FLUSHINVAL_PAGES(), make sure to
- * call remapf() over the same region if the file is mapped.
- * This frees up mapped file references to the pages in the
- * given range and for the VOP_FLUSHINVAL_PAGES() case it ensures
- * that we get the latest mapped changes flushed out.
- */
- toss_start = XFS_B_TO_FSB(mp, (xfs_ufsize_t)new_size);
- toss_start = XFS_FSB_TO_B(mp, toss_start);
- if (toss_start < 0) {
- /*
- * The place to start tossing is beyond our maximum
- * file size, so there is no way that the data extended
- * out there.
- */
- return;
- }
- last_byte = xfs_file_last_byte(ip);
- xfs_itrunc_trace(XFS_ITRUNC_START, ip, flags, new_size, toss_start,
- last_byte);
- if (last_byte > toss_start) {
- if (flags & XFS_ITRUNC_DEFINITE) {
- XVOP_TOSS_PAGES(vp, toss_start, -1, FI_REMAPF_LOCKED);
- } else {
- XVOP_FLUSHINVAL_PAGES(vp, toss_start, -1, FI_REMAPF_LOCKED);
- }
- }
-
-#ifdef DEBUG
- if (new_size == 0) {
- ASSERT(VN_CACHED(vp) == 0);
- }
-#endif
-}
-
-/*
- * Shrink the file to the given new_size. The new
- * size must be smaller than the current size.
- * This will free up the underlying blocks
- * in the removed range after a call to xfs_itruncate_start()
- * or xfs_atruncate_start().
- *
- * The transaction passed to this routine must have made
- * a permanent log reservation of at least XFS_ITRUNCATE_LOG_RES.
- * This routine may commit the given transaction and
- * start new ones, so make sure everything involved in
- * the transaction is tidy before calling here.
- * Some transaction will be returned to the caller to be
- * committed. The incoming transaction must already include
- * the inode, and both inode locks must be held exclusively.
- * The inode must also be "held" within the transaction. On
- * return the inode will be "held" within the returned transaction.
- * This routine does NOT require any disk space to be reserved
- * for it within the transaction.
- *
- * The fork parameter must be either xfs_attr_fork or xfs_data_fork,
- * and it indicates the fork which is to be truncated. For the
- * attribute fork we only support truncation to size 0.
- *
- * We use the sync parameter to indicate whether or not the first
- * transaction we perform might have to be synchronous. For the attr fork,
- * it needs to be so if the unlink of the inode is not yet known to be
- * permanent in the log. This keeps us from freeing and reusing the
- * blocks of the attribute fork before the unlink of the inode becomes
- * permanent.
- *
- * For the data fork, we normally have to run synchronously if we're
- * being called out of the inactive path or we're being called
- * out of the create path where we're truncating an existing file.
- * Either way, the truncate needs to be sync so blocks don't reappear
- * in the file with altered data in case of a crash. wsync filesystems
- * can run the first case async because anything that shrinks the inode
- * has to run sync so by the time we're called here from inactive, the
- * inode size is permanently set to 0.
- *
- * Calls from the truncate path always need to be sync unless we're
- * in a wsync filesystem and the file has already been unlinked.
- *
- * The caller is responsible for correctly setting the sync parameter.
- * It gets too hard for us to guess here which path we're being called
- * out of just based on inode state.
- */
-int
-xfs_itruncate_finish(
- xfs_trans_t **tp,
- xfs_inode_t *ip,
- xfs_fsize_t new_size,
- int fork,
- int sync)
-{
- xfs_fsblock_t first_block;
- xfs_fileoff_t first_unmap_block;
- xfs_fileoff_t last_block;
- xfs_filblks_t unmap_len=0;
- xfs_mount_t *mp;
- xfs_trans_t *ntp;
- int done;
- int committed;
- xfs_bmap_free_t free_list;
- int error;
-
- ASSERT(ismrlocked(&ip->i_iolock, MR_UPDATE) != 0);
- ASSERT(ismrlocked(&ip->i_lock, MR_UPDATE) != 0);
- ASSERT((new_size == 0) || (new_size <= ip->i_d.di_size));
- ASSERT(*tp != NULL);
- ASSERT((*tp)->t_flags & XFS_TRANS_PERM_LOG_RES);
- ASSERT(ip->i_transp == *tp);
- ASSERT(ip->i_itemp != NULL);
- ASSERT(ip->i_itemp->ili_flags & XFS_ILI_HOLD);
-
-
- ntp = *tp;
- mp = (ntp)->t_mountp;
- ASSERT(! XFS_NOT_DQATTACHED(mp, ip));
-
- /*
- * We only support truncating the entire attribute fork.
- */
- if (fork == XFS_ATTR_FORK) {
- new_size = 0LL;
- }
- first_unmap_block = XFS_B_TO_FSB(mp, (xfs_ufsize_t)new_size);
- xfs_itrunc_trace(XFS_ITRUNC_FINISH1, ip, 0, new_size, 0, 0);
- /*
- * The first thing we do is set the size to new_size permanently
- * on disk. This way we don't have to worry about anyone ever
- * being able to look at the data being freed even in the face
- * of a crash. What we're getting around here is the case where
- * we free a block, it is allocated to another file, it is written
- * to, and then we crash. If the new data gets written to the
- * file but the log buffers containing the free and reallocation
- * don't, then we'd end up with garbage in the blocks being freed.
- * As long as we make the new_size permanent before actually
- * freeing any blocks it doesn't matter if they get writtten to.
- *
- * The callers must signal into us whether or not the size
- * setting here must be synchronous. There are a few cases
- * where it doesn't have to be synchronous. Those cases
- * occur if the file is unlinked and we know the unlink is
- * permanent or if the blocks being truncated are guaranteed
- * to be beyond the inode eof (regardless of the link count)
- * and the eof value is permanent. Both of these cases occur
- * only on wsync-mounted filesystems. In those cases, we're
- * guaranteed that no user will ever see the data in the blocks
- * that are being truncated so the truncate can run async.
- * In the free beyond eof case, the file may wind up with
- * more blocks allocated to it than it needs if we crash
- * and that won't get fixed until the next time the file
- * is re-opened and closed but that's ok as that shouldn't
- * be too many blocks.
- *
- * However, we can't just make all wsync xactions run async
- * because there's one call out of the create path that needs
- * to run sync where it's truncating an existing file to size
- * 0 whose size is > 0.
- *
- * It's probably possible to come up with a test in this
- * routine that would correctly distinguish all the above
- * cases from the values of the function parameters and the
- * inode state but for sanity's sake, I've decided to let the
- * layers above just tell us. It's simpler to correctly figure
- * out in the layer above exactly under what conditions we
- * can run async and I think it's easier for others read and
- * follow the logic in case something has to be changed.
- * cscope is your friend -- rcc.
- *
- * The attribute fork is much simpler.
- *
- * For the attribute fork we allow the caller to tell us whether
- * the unlink of the inode that led to this call is yet permanent
- * in the on disk log. If it is not and we will be freeing extents
- * in this inode then we make the first transaction synchronous
- * to make sure that the unlink is permanent by the time we free
- * the blocks.
- */
- if (fork == XFS_DATA_FORK) {
- if (ip->i_d.di_nextents > 0) {
- ip->i_d.di_size = new_size;
- xfs_trans_log_inode(ntp, ip, XFS_ILOG_CORE);
- }
- } else if (sync) {
- ASSERT(!(mp->m_flags & XFS_MOUNT_WSYNC));
- if (ip->i_d.di_anextents > 0)
- xfs_trans_set_sync(ntp);
- }
- ASSERT(fork == XFS_DATA_FORK ||
- (fork == XFS_ATTR_FORK &&
- ((sync && !(mp->m_flags & XFS_MOUNT_WSYNC)) ||
- (sync == 0 && (mp->m_flags & XFS_MOUNT_WSYNC)))));
-
- /*
- * Since it is possible for space to become allocated beyond
- * the end of the file (in a crash where the space is allocated
- * but the inode size is not yet updated), simply remove any
- * blocks which show up between the new EOF and the maximum
- * possible file size. If the first block to be removed is
- * beyond the maximum file size (ie it is the same as last_block),
- * then there is nothing to do.
- */
- last_block = XFS_B_TO_FSB(mp, (xfs_ufsize_t)XFS_MAXIOFFSET(mp));
- ASSERT(first_unmap_block <= last_block);
- done = 0;
- if (last_block == first_unmap_block) {
- done = 1;
- } else {
- unmap_len = last_block - first_unmap_block + 1;
- }
- while (!done) {
- /*
- * Free up up to XFS_ITRUNC_MAX_EXTENTS. xfs_bunmapi()
- * will tell us whether it freed the entire range or
- * not. If this is a synchronous mount (wsync),
- * then we can tell bunmapi to keep all the
- * transactions asynchronous since the unlink
- * transaction that made this inode inactive has
- * already hit the disk. There's no danger of
- * the freed blocks being reused, there being a
- * crash, and the reused blocks suddenly reappearing
- * in this file with garbage in them once recovery
- * runs.
- */
- XFS_BMAP_INIT(&free_list, &first_block);
- error = XFS_BUNMAPI(mp, ntp, &ip->i_iocore,
- first_unmap_block, unmap_len,
- XFS_BMAPI_AFLAG(fork) |
- (sync ? 0 : XFS_BMAPI_ASYNC),
- XFS_ITRUNC_MAX_EXTENTS,
- &first_block, &free_list,
- NULL, &done);
- if (error) {
- /*
- * If the bunmapi call encounters an error,
- * return to the caller where the transaction
- * can be properly aborted. We just need to
- * make sure we're not holding any resources
- * that we were not when we came in.
- */
- xfs_bmap_cancel(&free_list);
- return error;
- }
-
- /*
- * Duplicate the transaction that has the permanent
- * reservation and commit the old transaction.
- */
- error = xfs_bmap_finish(tp, &free_list, first_block,
- &committed);
- ntp = *tp;
- if (error) {
- /*
- * If the bmap finish call encounters an error,
- * return to the caller where the transaction
- * can be properly aborted. We just need to
- * make sure we're not holding any resources
- * that we were not when we came in.
- *
- * Aborting from this point might lose some
- * blocks in the file system, but oh well.
- */
- xfs_bmap_cancel(&free_list);
- if (committed) {
- /*
- * If the passed in transaction committed
- * in xfs_bmap_finish(), then we want to
- * add the inode to this one before returning.
- * This keeps things simple for the higher
- * level code, because it always knows that
- * the inode is locked and held in the
- * transaction that returns to it whether
- * errors occur or not. We don't mark the
- * inode dirty so that this transaction can
- * be easily aborted if possible.
- */
- xfs_trans_ijoin(ntp, ip,
- XFS_ILOCK_EXCL | XFS_IOLOCK_EXCL);
- xfs_trans_ihold(ntp, ip);
- }
- return error;
- }
-
- if (committed) {
- /*
- * The first xact was committed,
- * so add the inode to the new one.
- * Mark it dirty so it will be logged
- * and moved forward in the log as
- * part of every commit.
- */
- xfs_trans_ijoin(ntp, ip,
- XFS_ILOCK_EXCL | XFS_IOLOCK_EXCL);
- xfs_trans_ihold(ntp, ip);
- xfs_trans_log_inode(ntp, ip, XFS_ILOG_CORE);
- }
- ntp = xfs_trans_dup(ntp);
- (void) xfs_trans_commit(*tp, 0, NULL);
- *tp = ntp;
- error = xfs_trans_reserve(ntp, 0, XFS_ITRUNCATE_LOG_RES(mp), 0,
- XFS_TRANS_PERM_LOG_RES,
- XFS_ITRUNCATE_LOG_COUNT);
- /*
- * Add the inode being truncated to the next chained
- * transaction.
- */
- xfs_trans_ijoin(ntp, ip, XFS_ILOCK_EXCL | XFS_IOLOCK_EXCL);
- xfs_trans_ihold(ntp, ip);
- if (error)
- return (error);
- }
- /*
- * Only update the size in the case of the data fork, but
- * always re-log the inode so that our permanent transaction
- * can keep on rolling it forward in the log.
- */
- if (fork == XFS_DATA_FORK) {
- xfs_isize_check(mp, ip, new_size);
- ip->i_d.di_size = new_size;
- }
- xfs_trans_log_inode(ntp, ip, XFS_ILOG_CORE);
- ASSERT((new_size != 0) ||
- (fork == XFS_ATTR_FORK) ||
- (ip->i_delayed_blks == 0));
- ASSERT((new_size != 0) ||
- (fork == XFS_ATTR_FORK) ||
- (ip->i_d.di_nextents == 0));
- xfs_itrunc_trace(XFS_ITRUNC_FINISH2, ip, 0, new_size, 0, 0);
- return 0;
-}
-
-
-/*
- * xfs_igrow_start
- *
- * Do the first part of growing a file: zero any data in the last
- * block that is beyond the old EOF. We need to do this before
- * the inode is joined to the transaction to modify the i_size.
- * That way we can drop the inode lock and call into the buffer
- * cache to get the buffer mapping the EOF.
- */
-int
-xfs_igrow_start(
- xfs_inode_t *ip,
- xfs_fsize_t new_size,
- cred_t *credp)
-{
- int error;
-
- ASSERT(ismrlocked(&(ip->i_lock), MR_UPDATE) != 0);
- ASSERT(ismrlocked(&(ip->i_iolock), MR_UPDATE) != 0);
- ASSERT(new_size > ip->i_d.di_size);
-
- /*
- * Zero any pages that may have been created by
- * xfs_write_file() beyond the end of the file
- * and any blocks between the old and new file sizes.
- */
- error = xfs_zero_eof(XFS_ITOV(ip), &ip->i_iocore, new_size,
- ip->i_d.di_size, new_size);
- return error;
-}
-
-/*
- * xfs_igrow_finish
- *
- * This routine is called to extend the size of a file.
- * The inode must have both the iolock and the ilock locked
- * for update and it must be a part of the current transaction.
- * The xfs_igrow_start() function must have been called previously.
- * If the change_flag is not zero, the inode change timestamp will
- * be updated.
- */
-void
-xfs_igrow_finish(
- xfs_trans_t *tp,
- xfs_inode_t *ip,
- xfs_fsize_t new_size,
- int change_flag)
-{
- ASSERT(ismrlocked(&(ip->i_lock), MR_UPDATE) != 0);
- ASSERT(ismrlocked(&(ip->i_iolock), MR_UPDATE) != 0);
- ASSERT(ip->i_transp == tp);
- ASSERT(new_size > ip->i_d.di_size);
-
- /*
- * Update the file size. Update the inode change timestamp
- * if change_flag set.
- */
- ip->i_d.di_size = new_size;
- if (change_flag)
- xfs_ichgtime(ip, XFS_ICHGTIME_CHG);
- xfs_trans_log_inode(tp, ip, XFS_ILOG_CORE);
-
-}
-
-
-/*
- * This is called when the inode's link count goes to 0.
- * We place the on-disk inode on a list in the AGI. It
- * will be pulled from this list when the inode is freed.
- */
-int
-xfs_iunlink(
- xfs_trans_t *tp,
- xfs_inode_t *ip)
-{
- xfs_mount_t *mp;
- xfs_agi_t *agi;
- xfs_dinode_t *dip;
- xfs_buf_t *agibp;
- xfs_buf_t *ibp;
- xfs_agnumber_t agno;
- xfs_daddr_t agdaddr;
- xfs_agino_t agino;
- short bucket_index;
- int offset;
- int error;
- int agi_ok;
-
- ASSERT(ip->i_d.di_nlink == 0);
- ASSERT(ip->i_d.di_mode != 0);
- ASSERT(ip->i_transp == tp);
-
- mp = tp->t_mountp;
-
- agno = XFS_INO_TO_AGNO(mp, ip->i_ino);
- agdaddr = XFS_AG_DADDR(mp, agno, XFS_AGI_DADDR(mp));
-
- /*
- * Get the agi buffer first. It ensures lock ordering
- * on the list.
- */
- error = xfs_trans_read_buf(mp, tp, mp->m_ddev_targp, agdaddr,
- XFS_FSS_TO_BB(mp, 1), 0, &agibp);
- if (error) {
- return error;
- }
- /*
- * Validate the magic number of the agi block.
- */
- agi = XFS_BUF_TO_AGI(agibp);
- agi_ok =
- be32_to_cpu(agi->agi_magicnum) == XFS_AGI_MAGIC &&
- XFS_AGI_GOOD_VERSION(be32_to_cpu(agi->agi_versionnum));
- if (unlikely(XFS_TEST_ERROR(!agi_ok, mp, XFS_ERRTAG_IUNLINK,
- XFS_RANDOM_IUNLINK))) {
- XFS_CORRUPTION_ERROR("xfs_iunlink", XFS_ERRLEVEL_LOW, mp, agi);
- xfs_trans_brelse(tp, agibp);
- return XFS_ERROR(EFSCORRUPTED);
- }
- /*
- * Get the index into the agi hash table for the
- * list this inode will go on.
- */
- agino = XFS_INO_TO_AGINO(mp, ip->i_ino);
- ASSERT(agino != 0);
- bucket_index = agino % XFS_AGI_UNLINKED_BUCKETS;
- ASSERT(agi->agi_unlinked[bucket_index]);
- ASSERT(be32_to_cpu(agi->agi_unlinked[bucket_index]) != agino);
-
- if (be32_to_cpu(agi->agi_unlinked[bucket_index]) != NULLAGINO) {
- /*
- * There is already another inode in the bucket we need
- * to add ourselves to. Add us at the front of the list.
- * Here we put the head pointer into our next pointer,
- * and then we fall through to point the head at us.
- */
- error = xfs_itobp(mp, tp, ip, &dip, &ibp, 0, 0);
- if (error) {
- return error;
- }
- ASSERT(INT_GET(dip->di_next_unlinked, ARCH_CONVERT) == NULLAGINO);
- ASSERT(dip->di_next_unlinked);
- /* both on-disk, don't endian flip twice */
- dip->di_next_unlinked = agi->agi_unlinked[bucket_index];
- offset = ip->i_boffset +
- offsetof(xfs_dinode_t, di_next_unlinked);
- xfs_trans_inode_buf(tp, ibp);
- xfs_trans_log_buf(tp, ibp, offset,
- (offset + sizeof(xfs_agino_t) - 1));
- xfs_inobp_check(mp, ibp);
- }
-
- /*
- * Point the bucket head pointer at the inode being inserted.
- */
- ASSERT(agino != 0);
- agi->agi_unlinked[bucket_index] = cpu_to_be32(agino);
- offset = offsetof(xfs_agi_t, agi_unlinked) +
- (sizeof(xfs_agino_t) * bucket_index);
- xfs_trans_log_buf(tp, agibp, offset,
- (offset + sizeof(xfs_agino_t) - 1));
- return 0;
-}
-
-/*
- * Pull the on-disk inode from the AGI unlinked list.
- */
-STATIC int
-xfs_iunlink_remove(
- xfs_trans_t *tp,
- xfs_inode_t *ip)
-{
- xfs_ino_t next_ino;
- xfs_mount_t *mp;
- xfs_agi_t *agi;
- xfs_dinode_t *dip;
- xfs_buf_t *agibp;
- xfs_buf_t *ibp;
- xfs_agnumber_t agno;
- xfs_daddr_t agdaddr;
- xfs_agino_t agino;
- xfs_agino_t next_agino;
- xfs_buf_t *last_ibp;
- xfs_dinode_t *last_dip = NULL;
- short bucket_index;
- int offset, last_offset = 0;
- int error;
- int agi_ok;
-
- /*
- * First pull the on-disk inode from the AGI unlinked list.
- */
- mp = tp->t_mountp;
-
- agno = XFS_INO_TO_AGNO(mp, ip->i_ino);
- agdaddr = XFS_AG_DADDR(mp, agno, XFS_AGI_DADDR(mp));
-
- /*
- * Get the agi buffer first. It ensures lock ordering
- * on the list.
- */
- error = xfs_trans_read_buf(mp, tp, mp->m_ddev_targp, agdaddr,
- XFS_FSS_TO_BB(mp, 1), 0, &agibp);
- if (error) {
- cmn_err(CE_WARN,
- "xfs_iunlink_remove: xfs_trans_read_buf() returned an error %d on %s. Returning error.",
- error, mp->m_fsname);
- return error;
- }
- /*
- * Validate the magic number of the agi block.
- */
- agi = XFS_BUF_TO_AGI(agibp);
- agi_ok =
- be32_to_cpu(agi->agi_magicnum) == XFS_AGI_MAGIC &&
- XFS_AGI_GOOD_VERSION(be32_to_cpu(agi->agi_versionnum));
- if (unlikely(XFS_TEST_ERROR(!agi_ok, mp, XFS_ERRTAG_IUNLINK_REMOVE,
- XFS_RANDOM_IUNLINK_REMOVE))) {
- XFS_CORRUPTION_ERROR("xfs_iunlink_remove", XFS_ERRLEVEL_LOW,
- mp, agi);
- xfs_trans_brelse(tp, agibp);
- cmn_err(CE_WARN,
- "xfs_iunlink_remove: XFS_TEST_ERROR() returned an error on %s. Returning EFSCORRUPTED.",
- mp->m_fsname);
- return XFS_ERROR(EFSCORRUPTED);
- }
- /*
- * Get the index into the agi hash table for the
- * list this inode will go on.
- */
- agino = XFS_INO_TO_AGINO(mp, ip->i_ino);
- ASSERT(agino != 0);
- bucket_index = agino % XFS_AGI_UNLINKED_BUCKETS;
- ASSERT(be32_to_cpu(agi->agi_unlinked[bucket_index]) != NULLAGINO);
- ASSERT(agi->agi_unlinked[bucket_index]);
-
- if (be32_to_cpu(agi->agi_unlinked[bucket_index]) == agino) {
- /*
- * We're at the head of the list. Get the inode's
- * on-disk buffer to see if there is anyone after us
- * on the list. Only modify our next pointer if it
- * is not already NULLAGINO. This saves us the overhead
- * of dealing with the buffer when there is no need to
- * change it.
- */
- error = xfs_itobp(mp, tp, ip, &dip, &ibp, 0, 0);
- if (error) {
- cmn_err(CE_WARN,
- "xfs_iunlink_remove: xfs_itobp() returned an error %d on %s. Returning error.",
- error, mp->m_fsname);
- return error;
- }
- next_agino = INT_GET(dip->di_next_unlinked, ARCH_CONVERT);
- ASSERT(next_agino != 0);
- if (next_agino != NULLAGINO) {
- INT_SET(dip->di_next_unlinked, ARCH_CONVERT, NULLAGINO);
- offset = ip->i_boffset +
- offsetof(xfs_dinode_t, di_next_unlinked);
- xfs_trans_inode_buf(tp, ibp);
- xfs_trans_log_buf(tp, ibp, offset,
- (offset + sizeof(xfs_agino_t) - 1));
- xfs_inobp_check(mp, ibp);
- } else {
- xfs_trans_brelse(tp, ibp);
- }
- /*
- * Point the bucket head pointer at the next inode.
- */
- ASSERT(next_agino != 0);
- ASSERT(next_agino != agino);
- agi->agi_unlinked[bucket_index] = cpu_to_be32(next_agino);
- offset = offsetof(xfs_agi_t, agi_unlinked) +
- (sizeof(xfs_agino_t) * bucket_index);
- xfs_trans_log_buf(tp, agibp, offset,
- (offset + sizeof(xfs_agino_t) - 1));
- } else {
- /*
- * We need to search the list for the inode being freed.
- */
- next_agino = be32_to_cpu(agi->agi_unlinked[bucket_index]);
- last_ibp = NULL;
- while (next_agino != agino) {
- /*
- * If the last inode wasn't the one pointing to
- * us, then release its buffer since we're not
- * going to do anything with it.
- */
- if (last_ibp != NULL) {
- xfs_trans_brelse(tp, last_ibp);
- }
- next_ino = XFS_AGINO_TO_INO(mp, agno, next_agino);
- error = xfs_inotobp(mp, tp, next_ino, &last_dip,
- &last_ibp, &last_offset);
- if (error) {
- cmn_err(CE_WARN,
- "xfs_iunlink_remove: xfs_inotobp() returned an error %d on %s. Returning error.",
- error, mp->m_fsname);
- return error;
- }
- next_agino = INT_GET(last_dip->di_next_unlinked, ARCH_CONVERT);
- ASSERT(next_agino != NULLAGINO);
- ASSERT(next_agino != 0);
- }
- /*
- * Now last_ibp points to the buffer previous to us on
- * the unlinked list. Pull us from the list.
- */
- error = xfs_itobp(mp, tp, ip, &dip, &ibp, 0, 0);
- if (error) {
- cmn_err(CE_WARN,
- "xfs_iunlink_remove: xfs_itobp() returned an error %d on %s. Returning error.",
- error, mp->m_fsname);
- return error;
- }
- next_agino = INT_GET(dip->di_next_unlinked, ARCH_CONVERT);
- ASSERT(next_agino != 0);
- ASSERT(next_agino != agino);
- if (next_agino != NULLAGINO) {
- INT_SET(dip->di_next_unlinked, ARCH_CONVERT, NULLAGINO);
- offset = ip->i_boffset +
- offsetof(xfs_dinode_t, di_next_unlinked);
- xfs_trans_inode_buf(tp, ibp);
- xfs_trans_log_buf(tp, ibp, offset,
- (offset + sizeof(xfs_agino_t) - 1));
- xfs_inobp_check(mp, ibp);
- } else {
- xfs_trans_brelse(tp, ibp);
- }
- /*
- * Point the previous inode on the list to the next inode.
- */
- INT_SET(last_dip->di_next_unlinked, ARCH_CONVERT, next_agino);
- ASSERT(next_agino != 0);
- offset = last_offset + offsetof(xfs_dinode_t, di_next_unlinked);
- xfs_trans_inode_buf(tp, last_ibp);
- xfs_trans_log_buf(tp, last_ibp, offset,
- (offset + sizeof(xfs_agino_t) - 1));
- xfs_inobp_check(mp, last_ibp);
- }
- return 0;
-}
-
-static __inline__ int xfs_inode_clean(xfs_inode_t *ip)
-{
- return (((ip->i_itemp == NULL) ||
- !(ip->i_itemp->ili_format.ilf_fields & XFS_ILOG_ALL)) &&
- (ip->i_update_core == 0));
-}
-
-STATIC void
-xfs_ifree_cluster(
- xfs_inode_t *free_ip,
- xfs_trans_t *tp,
- xfs_ino_t inum)
-{
- xfs_mount_t *mp = free_ip->i_mount;
- int blks_per_cluster;
- int nbufs;
- int ninodes;
- int i, j, found, pre_flushed;
- xfs_daddr_t blkno;
- xfs_buf_t *bp;
- xfs_ihash_t *ih;
- xfs_inode_t *ip, **ip_found;
- xfs_inode_log_item_t *iip;
- xfs_log_item_t *lip;
- SPLDECL(s);
-
- if (mp->m_sb.sb_blocksize >= XFS_INODE_CLUSTER_SIZE(mp)) {
- blks_per_cluster = 1;
- ninodes = mp->m_sb.sb_inopblock;
- nbufs = XFS_IALLOC_BLOCKS(mp);
- } else {
- blks_per_cluster = XFS_INODE_CLUSTER_SIZE(mp) /
- mp->m_sb.sb_blocksize;
- ninodes = blks_per_cluster * mp->m_sb.sb_inopblock;
- nbufs = XFS_IALLOC_BLOCKS(mp) / blks_per_cluster;
- }
-
- ip_found = kmem_alloc(ninodes * sizeof(xfs_inode_t *), KM_NOFS);
-
- for (j = 0; j < nbufs; j++, inum += ninodes) {
- blkno = XFS_AGB_TO_DADDR(mp, XFS_INO_TO_AGNO(mp, inum),
- XFS_INO_TO_AGBNO(mp, inum));
-
-
- /*
- * Look for each inode in memory and attempt to lock it,
- * we can be racing with flush and tail pushing here.
- * any inode we get the locks on, add to an array of
- * inode items to process later.
- *
- * The get the buffer lock, we could beat a flush
- * or tail pushing thread to the lock here, in which
- * case they will go looking for the inode buffer
- * and fail, we need some other form of interlock
- * here.
- */
- found = 0;
- for (i = 0; i < ninodes; i++) {
- ih = XFS_IHASH(mp, inum + i);
- read_lock(&ih->ih_lock);
- for (ip = ih->ih_next; ip != NULL; ip = ip->i_next) {
- if (ip->i_ino == inum + i)
- break;
- }
-
- /* Inode not in memory or we found it already,
- * nothing to do
- */
- if (!ip || (ip->i_flags & XFS_ISTALE)) {
- read_unlock(&ih->ih_lock);
- continue;
- }
-
- if (xfs_inode_clean(ip)) {
- read_unlock(&ih->ih_lock);
- continue;
- }
-
- /* If we can get the locks then add it to the
- * list, otherwise by the time we get the bp lock
- * below it will already be attached to the
- * inode buffer.
- */
-
- /* This inode will already be locked - by us, lets
- * keep it that way.
- */
-
- if (ip == free_ip) {
- if (xfs_iflock_nowait(ip)) {
- ip->i_flags |= XFS_ISTALE;
-
- if (xfs_inode_clean(ip)) {
- xfs_ifunlock(ip);
- } else {
- ip_found[found++] = ip;
- }
- }
- read_unlock(&ih->ih_lock);
- continue;
- }
-
- if (xfs_ilock_nowait(ip, XFS_ILOCK_EXCL)) {
- if (xfs_iflock_nowait(ip)) {
- ip->i_flags |= XFS_ISTALE;
-
- if (xfs_inode_clean(ip)) {
- xfs_ifunlock(ip);
- xfs_iunlock(ip, XFS_ILOCK_EXCL);
- } else {
- ip_found[found++] = ip;
- }
- } else {
- xfs_iunlock(ip, XFS_ILOCK_EXCL);
- }
- }
-
- read_unlock(&ih->ih_lock);
- }
-
- bp = xfs_trans_get_buf(tp, mp->m_ddev_targp, blkno,
- mp->m_bsize * blks_per_cluster,
- XFS_BUF_LOCK);
-
- pre_flushed = 0;
- lip = XFS_BUF_FSPRIVATE(bp, xfs_log_item_t *);
- while (lip) {
- if (lip->li_type == XFS_LI_INODE) {
- iip = (xfs_inode_log_item_t *)lip;
- ASSERT(iip->ili_logged == 1);
- lip->li_cb = (void(*)(xfs_buf_t*,xfs_log_item_t*)) xfs_istale_done;
- AIL_LOCK(mp,s);
- iip->ili_flush_lsn = iip->ili_item.li_lsn;
- AIL_UNLOCK(mp, s);
- iip->ili_inode->i_flags |= XFS_ISTALE;
- pre_flushed++;
- }
- lip = lip->li_bio_list;
- }
-
- for (i = 0; i < found; i++) {
- ip = ip_found[i];
- iip = ip->i_itemp;
-
- if (!iip) {
- ip->i_update_core = 0;
- xfs_ifunlock(ip);
- xfs_iunlock(ip, XFS_ILOCK_EXCL);
- continue;
- }
-
- iip->ili_last_fields = iip->ili_format.ilf_fields;
- iip->ili_format.ilf_fields = 0;
- iip->ili_logged = 1;
- AIL_LOCK(mp,s);
- iip->ili_flush_lsn = iip->ili_item.li_lsn;
- AIL_UNLOCK(mp, s);
-
- xfs_buf_attach_iodone(bp,
- (void(*)(xfs_buf_t*,xfs_log_item_t*))
- xfs_istale_done, (xfs_log_item_t *)iip);
- if (ip != free_ip) {
- xfs_iunlock(ip, XFS_ILOCK_EXCL);
- }
- }
-
- if (found || pre_flushed)
- xfs_trans_stale_inode_buf(tp, bp);
- xfs_trans_binval(tp, bp);
- }
-
- kmem_free(ip_found, ninodes * sizeof(xfs_inode_t *));
-}
-
-/*
- * This is called to return an inode to the inode free list.
- * The inode should already be truncated to 0 length and have
- * no pages associated with it. This routine also assumes that
- * the inode is already a part of the transaction.
- *
- * The on-disk copy of the inode will have been added to the list
- * of unlinked inodes in the AGI. We need to remove the inode from
- * that list atomically with respect to freeing it here.
- */
-int
-xfs_ifree(
- xfs_trans_t *tp,
- xfs_inode_t *ip,
- xfs_bmap_free_t *flist)
-{
- int error;
- int delete;
- xfs_ino_t first_ino;
-
- ASSERT(ismrlocked(&ip->i_lock, MR_UPDATE));
- ASSERT(ip->i_transp == tp);
- ASSERT(ip->i_d.di_nlink == 0);
- ASSERT(ip->i_d.di_nextents == 0);
- ASSERT(ip->i_d.di_anextents == 0);
- ASSERT((ip->i_d.di_size == 0) ||
- ((ip->i_d.di_mode & S_IFMT) != S_IFREG));
- ASSERT(ip->i_d.di_nblocks == 0);
-
- /*
- * Pull the on-disk inode from the AGI unlinked list.
- */
- error = xfs_iunlink_remove(tp, ip);
- if (error != 0) {
- return error;
- }
-
- error = xfs_difree(tp, ip->i_ino, flist, &delete, &first_ino);
- if (error != 0) {
- return error;
- }
- ip->i_d.di_mode = 0; /* mark incore inode as free */
- ip->i_d.di_flags = 0;
- ip->i_d.di_dmevmask = 0;
- ip->i_d.di_forkoff = 0; /* mark the attr fork not in use */
- ip->i_df.if_ext_max =
- XFS_IFORK_DSIZE(ip) / (uint)sizeof(xfs_bmbt_rec_t);
- ip->i_d.di_format = XFS_DINODE_FMT_EXTENTS;
- ip->i_d.di_aformat = XFS_DINODE_FMT_EXTENTS;
- /*
- * Bump the generation count so no one will be confused
- * by reincarnations of this inode.
- */
- ip->i_d.di_gen++;
- xfs_trans_log_inode(tp, ip, XFS_ILOG_CORE);
-
- if (delete) {
- xfs_ifree_cluster(ip, tp, first_ino);
- }
-
- return 0;
-}
-
-/*
- * Reallocate the space for if_broot based on the number of records
- * being added or deleted as indicated in rec_diff. Move the records
- * and pointers in if_broot to fit the new size. When shrinking this
- * will eliminate holes between the records and pointers created by
- * the caller. When growing this will create holes to be filled in
- * by the caller.
- *
- * The caller must not request to add more records than would fit in
- * the on-disk inode root. If the if_broot is currently NULL, then
- * if we adding records one will be allocated. The caller must also
- * not request that the number of records go below zero, although
- * it can go to zero.
- *
- * ip -- the inode whose if_broot area is changing
- * ext_diff -- the change in the number of records, positive or negative,
- * requested for the if_broot array.
- */
-void
-xfs_iroot_realloc(
- xfs_inode_t *ip,
- int rec_diff,
- int whichfork)
-{
- int cur_max;
- xfs_ifork_t *ifp;
- xfs_bmbt_block_t *new_broot;
- int new_max;
- size_t new_size;
- char *np;
- char *op;
-
- /*
- * Handle the degenerate case quietly.
- */
- if (rec_diff == 0) {
- return;
- }
-
- ifp = XFS_IFORK_PTR(ip, whichfork);
- if (rec_diff > 0) {
- /*
- * If there wasn't any memory allocated before, just
- * allocate it now and get out.
- */
- if (ifp->if_broot_bytes == 0) {
- new_size = (size_t)XFS_BMAP_BROOT_SPACE_CALC(rec_diff);
- ifp->if_broot = (xfs_bmbt_block_t*)kmem_alloc(new_size,
- KM_SLEEP);
- ifp->if_broot_bytes = (int)new_size;
- return;
- }
-
- /*
- * If there is already an existing if_broot, then we need
- * to realloc() it and shift the pointers to their new
- * location. The records don't change location because
- * they are kept butted up against the btree block header.
- */
- cur_max = XFS_BMAP_BROOT_MAXRECS(ifp->if_broot_bytes);
- new_max = cur_max + rec_diff;
- new_size = (size_t)XFS_BMAP_BROOT_SPACE_CALC(new_max);
- ifp->if_broot = (xfs_bmbt_block_t *)
- kmem_realloc(ifp->if_broot,
- new_size,
- (size_t)XFS_BMAP_BROOT_SPACE_CALC(cur_max), /* old size */
- KM_SLEEP);
- op = (char *)XFS_BMAP_BROOT_PTR_ADDR(ifp->if_broot, 1,
- ifp->if_broot_bytes);
- np = (char *)XFS_BMAP_BROOT_PTR_ADDR(ifp->if_broot, 1,
- (int)new_size);
- ifp->if_broot_bytes = (int)new_size;
- ASSERT(ifp->if_broot_bytes <=
- XFS_IFORK_SIZE(ip, whichfork) + XFS_BROOT_SIZE_ADJ);
- memmove(np, op, cur_max * (uint)sizeof(xfs_dfsbno_t));
- return;
- }
-
- /*
- * rec_diff is less than 0. In this case, we are shrinking the
- * if_broot buffer. It must already exist. If we go to zero
- * records, just get rid of the root and clear the status bit.
- */
- ASSERT((ifp->if_broot != NULL) && (ifp->if_broot_bytes > 0));
- cur_max = XFS_BMAP_BROOT_MAXRECS(ifp->if_broot_bytes);
- new_max = cur_max + rec_diff;
- ASSERT(new_max >= 0);
- if (new_max > 0)
- new_size = (size_t)XFS_BMAP_BROOT_SPACE_CALC(new_max);
- else
- new_size = 0;
- if (new_size > 0) {
- new_broot = (xfs_bmbt_block_t *)kmem_alloc(new_size, KM_SLEEP);
- /*
- * First copy over the btree block header.
- */
- memcpy(new_broot, ifp->if_broot, sizeof(xfs_bmbt_block_t));
- } else {
- new_broot = NULL;
- ifp->if_flags &= ~XFS_IFBROOT;
- }
-
- /*
- * Only copy the records and pointers if there are any.
- */
- if (new_max > 0) {
- /*
- * First copy the records.
- */
- op = (char *)XFS_BMAP_BROOT_REC_ADDR(ifp->if_broot, 1,
- ifp->if_broot_bytes);
- np = (char *)XFS_BMAP_BROOT_REC_ADDR(new_broot, 1,
- (int)new_size);
- memcpy(np, op, new_max * (uint)sizeof(xfs_bmbt_rec_t));
-
- /*
- * Then copy the pointers.
- */
- op = (char *)XFS_BMAP_BROOT_PTR_ADDR(ifp->if_broot, 1,
- ifp->if_broot_bytes);
- np = (char *)XFS_BMAP_BROOT_PTR_ADDR(new_broot, 1,
- (int)new_size);
- memcpy(np, op, new_max * (uint)sizeof(xfs_dfsbno_t));
- }
- kmem_free(ifp->if_broot, ifp->if_broot_bytes);
- ifp->if_broot = new_broot;
- ifp->if_broot_bytes = (int)new_size;
- ASSERT(ifp->if_broot_bytes <=
- XFS_IFORK_SIZE(ip, whichfork) + XFS_BROOT_SIZE_ADJ);
- return;
-}
-
-
-/*
- * This is called when the amount of space needed for if_data
- * is increased or decreased. The change in size is indicated by
- * the number of bytes that need to be added or deleted in the
- * byte_diff parameter.
- *
- * If the amount of space needed has decreased below the size of the
- * inline buffer, then switch to using the inline buffer. Otherwise,
- * use kmem_realloc() or kmem_alloc() to adjust the size of the buffer
- * to what is needed.
- *
- * ip -- the inode whose if_data area is changing
- * byte_diff -- the change in the number of bytes, positive or negative,
- * requested for the if_data array.
- */
-void
-xfs_idata_realloc(
- xfs_inode_t *ip,
- int byte_diff,
- int whichfork)
-{
- xfs_ifork_t *ifp;
- int new_size;
- int real_size;
-
- if (byte_diff == 0) {
- return;
- }
-
- ifp = XFS_IFORK_PTR(ip, whichfork);
- new_size = (int)ifp->if_bytes + byte_diff;
- ASSERT(new_size >= 0);
-
- if (new_size == 0) {
- if (ifp->if_u1.if_data != ifp->if_u2.if_inline_data) {
- kmem_free(ifp->if_u1.if_data, ifp->if_real_bytes);
- }
- ifp->if_u1.if_data = NULL;
- real_size = 0;
- } else if (new_size <= sizeof(ifp->if_u2.if_inline_data)) {
- /*
- * If the valid extents/data can fit in if_inline_ext/data,
- * copy them from the malloc'd vector and free it.
- */
- if (ifp->if_u1.if_data == NULL) {
- ifp->if_u1.if_data = ifp->if_u2.if_inline_data;
- } else if (ifp->if_u1.if_data != ifp->if_u2.if_inline_data) {
- ASSERT(ifp->if_real_bytes != 0);
- memcpy(ifp->if_u2.if_inline_data, ifp->if_u1.if_data,
- new_size);
- kmem_free(ifp->if_u1.if_data, ifp->if_real_bytes);
- ifp->if_u1.if_data = ifp->if_u2.if_inline_data;
- }
- real_size = 0;
- } else {
- /*
- * Stuck with malloc/realloc.
- * For inline data, the underlying buffer must be
- * a multiple of 4 bytes in size so that it can be
- * logged and stay on word boundaries. We enforce
- * that here.
- */
- real_size = roundup(new_size, 4);
- if (ifp->if_u1.if_data == NULL) {
- ASSERT(ifp->if_real_bytes == 0);
- ifp->if_u1.if_data = kmem_alloc(real_size, KM_SLEEP);
- } else if (ifp->if_u1.if_data != ifp->if_u2.if_inline_data) {
- /*
- * Only do the realloc if the underlying size
- * is really changing.
- */
- if (ifp->if_real_bytes != real_size) {
- ifp->if_u1.if_data =
- kmem_realloc(ifp->if_u1.if_data,
- real_size,
- ifp->if_real_bytes,
- KM_SLEEP);
- }
- } else {
- ASSERT(ifp->if_real_bytes == 0);
- ifp->if_u1.if_data = kmem_alloc(real_size, KM_SLEEP);
- memcpy(ifp->if_u1.if_data, ifp->if_u2.if_inline_data,
- ifp->if_bytes);
- }
- }
- ifp->if_real_bytes = real_size;
- ifp->if_bytes = new_size;
- ASSERT(ifp->if_bytes <= XFS_IFORK_SIZE(ip, whichfork));
-}
-
-
-
-
-/*
- * Map inode to disk block and offset.
- *
- * mp -- the mount point structure for the current file system
- * tp -- the current transaction
- * ino -- the inode number of the inode to be located
- * imap -- this structure is filled in with the information necessary
- * to retrieve the given inode from disk
- * flags -- flags to pass to xfs_dilocate indicating whether or not
- * lookups in the inode btree were OK or not
- */
-int
-xfs_imap(
- xfs_mount_t *mp,
- xfs_trans_t *tp,
- xfs_ino_t ino,
- xfs_imap_t *imap,
- uint flags)
-{
- xfs_fsblock_t fsbno;
- int len;
- int off;
- int error;
-
- fsbno = imap->im_blkno ?
- XFS_DADDR_TO_FSB(mp, imap->im_blkno) : NULLFSBLOCK;
- error = xfs_dilocate(mp, tp, ino, &fsbno, &len, &off, flags);
- if (error != 0) {
- return error;
- }
- imap->im_blkno = XFS_FSB_TO_DADDR(mp, fsbno);
- imap->im_len = XFS_FSB_TO_BB(mp, len);
- imap->im_agblkno = XFS_FSB_TO_AGBNO(mp, fsbno);
- imap->im_ioffset = (ushort)off;
- imap->im_boffset = (ushort)(off << mp->m_sb.sb_inodelog);
- return 0;
-}
-
-void
-xfs_idestroy_fork(
- xfs_inode_t *ip,
- int whichfork)
-{
- xfs_ifork_t *ifp;
-
- ifp = XFS_IFORK_PTR(ip, whichfork);
- if (ifp->if_broot != NULL) {
- kmem_free(ifp->if_broot, ifp->if_broot_bytes);
- ifp->if_broot = NULL;
- }
-
- /*
- * If the format is local, then we can't have an extents
- * array so just look for an inline data array. If we're
- * not local then we may or may not have an extents list,
- * so check and free it up if we do.
- */
- if (XFS_IFORK_FORMAT(ip, whichfork) == XFS_DINODE_FMT_LOCAL) {
- if ((ifp->if_u1.if_data != ifp->if_u2.if_inline_data) &&
- (ifp->if_u1.if_data != NULL)) {
- ASSERT(ifp->if_real_bytes != 0);
- kmem_free(ifp->if_u1.if_data, ifp->if_real_bytes);
- ifp->if_u1.if_data = NULL;
- ifp->if_real_bytes = 0;
- }
- } else if ((ifp->if_flags & XFS_IFEXTENTS) &&
- ((ifp->if_flags & XFS_IFEXTIREC) ||
- ((ifp->if_u1.if_extents != NULL) &&
- (ifp->if_u1.if_extents != ifp->if_u2.if_inline_ext)))) {
- ASSERT(ifp->if_real_bytes != 0);
- xfs_iext_destroy(ifp);
- }
- ASSERT(ifp->if_u1.if_extents == NULL ||
- ifp->if_u1.if_extents == ifp->if_u2.if_inline_ext);
- ASSERT(ifp->if_real_bytes == 0);
- if (whichfork == XFS_ATTR_FORK) {
- kmem_zone_free(xfs_ifork_zone, ip->i_afp);
- ip->i_afp = NULL;
- }
-}
-
-/*
- * This is called free all the memory associated with an inode.
- * It must free the inode itself and any buffers allocated for
- * if_extents/if_data and if_broot. It must also free the lock
- * associated with the inode.
- */
-void
-xfs_idestroy(
- xfs_inode_t *ip)
-{
-
- switch (ip->i_d.di_mode & S_IFMT) {
- case S_IFREG:
- case S_IFDIR:
- case S_IFLNK:
- xfs_idestroy_fork(ip, XFS_DATA_FORK);
- break;
- }
- if (ip->i_afp)
- xfs_idestroy_fork(ip, XFS_ATTR_FORK);
- mrfree(&ip->i_lock);
- mrfree(&ip->i_iolock);
- freesema(&ip->i_flock);
-#ifdef XFS_BMAP_TRACE
- ktrace_free(ip->i_xtrace);
-#endif
-#ifdef XFS_BMBT_TRACE
- ktrace_free(ip->i_btrace);
-#endif
-#ifdef XFS_RW_TRACE
- ktrace_free(ip->i_rwtrace);
-#endif
-#ifdef XFS_ILOCK_TRACE
- ktrace_free(ip->i_lock_trace);
-#endif
-#ifdef XFS_DIR2_TRACE
- ktrace_free(ip->i_dir_trace);
-#endif
- if (ip->i_itemp) {
- /* XXXdpd should be able to assert this but shutdown
- * is leaving the AIL behind. */
- ASSERT(((ip->i_itemp->ili_item.li_flags & XFS_LI_IN_AIL) == 0) ||
- XFS_FORCED_SHUTDOWN(ip->i_mount));
- xfs_inode_item_destroy(ip);
- }
- kmem_zone_free(xfs_inode_zone, ip);
-}
-
-
-/*
- * Increment the pin count of the given buffer.
- * This value is protected by ipinlock spinlock in the mount structure.
- */
-void
-xfs_ipin(
- xfs_inode_t *ip)
-{
- ASSERT(ismrlocked(&ip->i_lock, MR_UPDATE));
-
- atomic_inc(&ip->i_pincount);
-}
-
-/*
- * Decrement the pin count of the given inode, and wake up
- * anyone in xfs_iwait_unpin() if the count goes to 0. The
- * inode must have been previously pinned with a call to xfs_ipin().
- */
-void
-xfs_iunpin(
- xfs_inode_t *ip)
-{
- ASSERT(atomic_read(&ip->i_pincount) > 0);
-
- if (atomic_dec_and_test(&ip->i_pincount)) {
- /*
- * If the inode is currently being reclaimed, the
- * linux inode _and_ the xfs vnode may have been
- * freed so we cannot reference either of them safely.
- * Hence we should not try to do anything to them
- * if the xfs inode is currently in the reclaim
- * path.
- *
- * However, we still need to issue the unpin wakeup
- * call as the inode reclaim may be blocked waiting for
- * the inode to become unpinned.
- */
- if (!(ip->i_flags & (XFS_IRECLAIM|XFS_IRECLAIMABLE))) {
- /*
- * Should I mark FreeBSD vnode as dirty here?
- */
- printf("xfs_iunpin: REC RECABLE ip %p\n",ip);
-#ifdef RMC
- xfs_vnode_t *vp = XFS_ITOV_NULL(ip);
-
- /* make sync come back and flush this inode */
- if (vp) {
- struct inode *inode = vn_to_inode(vp);
-
- if (!(inode->i_state & I_NEW))
- mark_inode_dirty_sync(inode);
- }
-#endif
- }
- wakeup(&ip->i_ipin_wait);
- }
-}
-
-/*
- * This is called to wait for the given inode to be unpinned.
- * It will sleep until this happens. The caller must have the
- * inode locked in at least shared mode so that the buffer cannot
- * be subsequently pinned once someone is waiting for it to be
- * unpinned.
- */
-STATIC void
-xfs_iunpin_wait(
- xfs_inode_t *ip)
-{
- xfs_inode_log_item_t *iip;
- xfs_lsn_t lsn;
-
- ASSERT(ismrlocked(&ip->i_lock, MR_UPDATE | MR_ACCESS));
-
- if (atomic_read(&ip->i_pincount) == 0) {
- return;
- }
-
- iip = ip->i_itemp;
- if (iip && iip->ili_last_lsn) {
- lsn = iip->ili_last_lsn;
- } else {
- lsn = (xfs_lsn_t)0;
- }
-
- /*
- * Give the log a push so we don't wait here too long.
- */
- xfs_log_force(ip->i_mount, lsn, XFS_LOG_FORCE);
-
- /*
- * XXXKAN: xfs_iunpin is not locking inode
- * at all?
- */
- while(atomic_read(&ip->i_pincount) != 0)
- tsleep(&ip->i_ipin_wait, PRIBIO, "iunpin", 0);
-}
-
-
-/*
- * xfs_iextents_copy()
- *
- * This is called to copy the REAL extents (as opposed to the delayed
- * allocation extents) from the inode into the given buffer. It
- * returns the number of bytes copied into the buffer.
- *
- * If there are no delayed allocation extents, then we can just
- * memcpy() the extents into the buffer. Otherwise, we need to
- * examine each extent in turn and skip those which are delayed.
- */
-int
-xfs_iextents_copy(
- xfs_inode_t *ip,
- xfs_bmbt_rec_t *buffer,
- int whichfork)
-{
- int copied;
- xfs_bmbt_rec_t *dest_ep;
- xfs_bmbt_rec_t *ep;
-#ifdef XFS_BMAP_TRACE
- static char fname[] = "xfs_iextents_copy";
-#endif
- int i;
- xfs_ifork_t *ifp;
- int nrecs;
- xfs_fsblock_t start_block;
-
- ifp = XFS_IFORK_PTR(ip, whichfork);
- ASSERT(ismrlocked(&ip->i_lock, MR_UPDATE|MR_ACCESS));
- ASSERT(ifp->if_bytes > 0);
-
- nrecs = ifp->if_bytes / (uint)sizeof(xfs_bmbt_rec_t);
- xfs_bmap_trace_exlist(fname, ip, nrecs, whichfork);
- ASSERT(nrecs > 0);
-
- /*
- * There are some delayed allocation extents in the
- * inode, so copy the extents one at a time and skip
- * the delayed ones. There must be at least one
- * non-delayed extent.
- */
- dest_ep = buffer;
- copied = 0;
- for (i = 0; i < nrecs; i++) {
- ep = xfs_iext_get_ext(ifp, i);
- start_block = xfs_bmbt_get_startblock(ep);
- if (ISNULLSTARTBLOCK(start_block)) {
- /*
- * It's a delayed allocation extent, so skip it.
- */
- continue;
- }
-
- /* Translate to on disk format */
- put_unaligned(INT_GET(ep->l0, ARCH_CONVERT),
- (__uint64_t*)&dest_ep->l0);
- put_unaligned(INT_GET(ep->l1, ARCH_CONVERT),
- (__uint64_t*)&dest_ep->l1);
- dest_ep++;
- copied++;
- }
- ASSERT(copied != 0);
- xfs_validate_extents(ifp, copied, 1, XFS_EXTFMT_INODE(ip));
-
- return (copied * (uint)sizeof(xfs_bmbt_rec_t));
-}
-
-/*
- * Each of the following cases stores data into the same region
- * of the on-disk inode, so only one of them can be valid at
- * any given time. While it is possible to have conflicting formats
- * and log flags, e.g. having XFS_ILOG_?DATA set when the fork is
- * in EXTENTS format, this can only happen when the fork has
- * changed formats after being modified but before being flushed.
- * In these cases, the format always takes precedence, because the
- * format indicates the current state of the fork.
- */
-/*ARGSUSED*/
-STATIC int
-xfs_iflush_fork(
- xfs_inode_t *ip,
- xfs_dinode_t *dip,
- xfs_inode_log_item_t *iip,
- int whichfork,
- xfs_buf_t *bp)
-{
- char *cp;
- xfs_ifork_t *ifp;
- xfs_mount_t *mp;
-#ifdef XFS_TRANS_DEBUG
- int first;
-#endif
- static const short brootflag[2] =
- { XFS_ILOG_DBROOT, XFS_ILOG_ABROOT };
- static const short dataflag[2] =
- { XFS_ILOG_DDATA, XFS_ILOG_ADATA };
- static const short extflag[2] =
- { XFS_ILOG_DEXT, XFS_ILOG_AEXT };
-
- if (iip == NULL)
- return 0;
- ifp = XFS_IFORK_PTR(ip, whichfork);
- /*
- * This can happen if we gave up in iformat in an error path,
- * for the attribute fork.
- */
- if (ifp == NULL) {
- ASSERT(whichfork == XFS_ATTR_FORK);
- return 0;
- }
- cp = XFS_DFORK_PTR(dip, whichfork);
- mp = ip->i_mount;
- switch (XFS_IFORK_FORMAT(ip, whichfork)) {
- case XFS_DINODE_FMT_LOCAL:
- if ((iip->ili_format.ilf_fields & dataflag[whichfork]) &&
- (ifp->if_bytes > 0)) {
- ASSERT(ifp->if_u1.if_data != NULL);
- ASSERT(ifp->if_bytes <= XFS_IFORK_SIZE(ip, whichfork));
- memcpy(cp, ifp->if_u1.if_data, ifp->if_bytes);
- }
- if (whichfork == XFS_DATA_FORK) {
- if (unlikely(XFS_DIR_SHORTFORM_VALIDATE_ONDISK(mp, dip))) {
- XFS_ERROR_REPORT("xfs_iflush_fork",
- XFS_ERRLEVEL_LOW, mp);
- return XFS_ERROR(EFSCORRUPTED);
- }
- }
- break;
-
- case XFS_DINODE_FMT_EXTENTS:
- ASSERT((ifp->if_flags & XFS_IFEXTENTS) ||
- !(iip->ili_format.ilf_fields & extflag[whichfork]));
- ASSERT((xfs_iext_get_ext(ifp, 0) != NULL) ||
- (ifp->if_bytes == 0));
- ASSERT((xfs_iext_get_ext(ifp, 0) == NULL) ||
- (ifp->if_bytes > 0));
- if ((iip->ili_format.ilf_fields & extflag[whichfork]) &&
- (ifp->if_bytes > 0)) {
- ASSERT(XFS_IFORK_NEXTENTS(ip, whichfork) > 0);
- (void)xfs_iextents_copy(ip, (xfs_bmbt_rec_t *)cp,
- whichfork);
- }
- break;
-
- case XFS_DINODE_FMT_BTREE:
- if ((iip->ili_format.ilf_fields & brootflag[whichfork]) &&
- (ifp->if_broot_bytes > 0)) {
- ASSERT(ifp->if_broot != NULL);
- ASSERT(ifp->if_broot_bytes <=
- (XFS_IFORK_SIZE(ip, whichfork) +
- XFS_BROOT_SIZE_ADJ));
- xfs_bmbt_to_bmdr(ifp->if_broot, ifp->if_broot_bytes,
- (xfs_bmdr_block_t *)cp,
- XFS_DFORK_SIZE(dip, mp, whichfork));
- }
- break;
-
- case XFS_DINODE_FMT_DEV:
- if (iip->ili_format.ilf_fields & XFS_ILOG_DEV) {
- ASSERT(whichfork == XFS_DATA_FORK);
- INT_SET(dip->di_u.di_dev, ARCH_CONVERT, ip->i_df.if_u2.if_rdev);
- }
- break;
-
- case XFS_DINODE_FMT_UUID:
- if (iip->ili_format.ilf_fields & XFS_ILOG_UUID) {
- ASSERT(whichfork == XFS_DATA_FORK);
- memcpy(&dip->di_u.di_muuid, &ip->i_df.if_u2.if_uuid,
- sizeof(uuid_t));
- }
- break;
-
- default:
- ASSERT(0);
- break;
- }
-
- return 0;
-}
-
-/*
- * xfs_iflush() will write a modified inode's changes out to the
- * inode's on disk home. The caller must have the inode lock held
- * in at least shared mode and the inode flush semaphore must be
- * held as well. The inode lock will still be held upon return from
- * the call and the caller is free to unlock it.
- * The inode flush lock will be unlocked when the inode reaches the disk.
- * The flags indicate how the inode's buffer should be written out.
- */
-int
-xfs_iflush(
- xfs_inode_t *ip,
- uint flags)
-{
- xfs_inode_log_item_t *iip;
- xfs_buf_t *bp;
- xfs_dinode_t *dip;
- xfs_mount_t *mp;
- int error;
- /* REFERENCED */
- xfs_chash_t *ch;
- xfs_inode_t *iq;
- int clcount; /* count of inodes clustered */
- int bufwasdelwri;
- enum { INT_DELWRI = (1 << 0), INT_ASYNC = (1 << 1) };
- SPLDECL(s);
-
- XFS_STATS_INC(xs_iflush_count);
-
-
- printf("xfs_iflush: ip %p i_ino %lld\n",ip,ip->i_ino);
- ASSERT(ismrlocked(&ip->i_lock, MR_UPDATE|MR_ACCESS));
- ASSERT(valusema(&ip->i_flock) <= 0);
- ASSERT(ip->i_d.di_format != XFS_DINODE_FMT_BTREE ||
- ip->i_d.di_nextents > ip->i_df.if_ext_max);
-
- iip = ip->i_itemp;
- mp = ip->i_mount;
-
- /*
- * If the inode isn't dirty, then just release the inode
- * flush lock and do nothing.
- */
- if ((ip->i_update_core == 0) &&
- ((iip == NULL) || !(iip->ili_format.ilf_fields & XFS_ILOG_ALL))) {
- ASSERT((iip != NULL) ?
- !(iip->ili_item.li_flags & XFS_LI_IN_AIL) : 1);
- xfs_ifunlock(ip);
- return 0;
- }
-
- /*
- * We can't flush the inode until it is unpinned, so
- * wait for it. We know noone new can pin it, because
- * we are holding the inode lock shared and you need
- * to hold it exclusively to pin the inode.
- */
- xfs_iunpin_wait(ip);
-
- /*
- * This may have been unpinned because the filesystem is shutting
- * down forcibly. If that's the case we must not write this inode
- * to disk, because the log record didn't make it to disk!
- */
- if (XFS_FORCED_SHUTDOWN(mp)) {
- ip->i_update_core = 0;
- if (iip)
- iip->ili_format.ilf_fields = 0;
- xfs_ifunlock(ip);
- return XFS_ERROR(EIO);
- }
-
- /*
- * Get the buffer containing the on-disk inode.
- */
- error = xfs_itobp(mp, NULL, ip, &dip, &bp, 0, 0);
- if (error) {
- xfs_ifunlock(ip);
- return error;
- }
-
- /*
- * Decide how buffer will be flushed out. This is done before
- * the call to xfs_iflush_int because this field is zeroed by it.
- */
- if (iip != NULL && iip->ili_format.ilf_fields != 0) {
- /*
- * Flush out the inode buffer according to the directions
- * of the caller. In the cases where the caller has given
- * us a choice choose the non-delwri case. This is because
- * the inode is in the AIL and we need to get it out soon.
- */
- switch (flags) {
- case XFS_IFLUSH_SYNC:
- case XFS_IFLUSH_DELWRI_ELSE_SYNC:
- flags = 0;
- break;
- case XFS_IFLUSH_ASYNC:
- case XFS_IFLUSH_DELWRI_ELSE_ASYNC:
- flags = INT_ASYNC;
- break;
- case XFS_IFLUSH_DELWRI:
- flags = INT_DELWRI;
- break;
- default:
- ASSERT(0);
- flags = 0;
- break;
- }
- } else {
- switch (flags) {
- case XFS_IFLUSH_DELWRI_ELSE_SYNC:
- case XFS_IFLUSH_DELWRI_ELSE_ASYNC:
- case XFS_IFLUSH_DELWRI:
- flags = INT_DELWRI;
- break;
- case XFS_IFLUSH_ASYNC:
- flags = INT_ASYNC;
- break;
- case XFS_IFLUSH_SYNC:
- flags = 0;
- break;
- default:
- ASSERT(0);
- flags = 0;
- break;
- }
- }
-
- /*
- * First flush out the inode that xfs_iflush was called with.
- */
- error = xfs_iflush_int(ip, bp);
- if (error) {
- goto corrupt_out;
- }
-
- /*
- * inode clustering:
- * see if other inodes can be gathered into this write
- */
-
- ip->i_chash->chl_buf = bp;
-
- ch = XFS_CHASH(mp, ip->i_blkno);
- s = mutex_spinlock(&ch->ch_lock);
-
- clcount = 0;
- for (iq = ip->i_cnext; iq != ip; iq = iq->i_cnext) {
- /*
- * Do an un-protected check to see if the inode is dirty and
- * is a candidate for flushing. These checks will be repeated
- * later after the appropriate locks are acquired.
- */
- iip = iq->i_itemp;
- if ((iq->i_update_core == 0) &&
- ((iip == NULL) ||
- !(iip->ili_format.ilf_fields & XFS_ILOG_ALL)) &&
- xfs_ipincount(iq) == 0) {
- continue;
- }
-
- /*
- * Try to get locks. If any are unavailable,
- * then this inode cannot be flushed and is skipped.
- */
-
- /* get inode locks (just i_lock) */
- if (xfs_ilock_nowait(iq, XFS_ILOCK_SHARED)) {
- /* get inode flush lock */
- if (xfs_iflock_nowait(iq)) {
- /* check if pinned */
- if (xfs_ipincount(iq) == 0) {
- /* arriving here means that
- * this inode can be flushed.
- * first re-check that it's
- * dirty
- */
- iip = iq->i_itemp;
- if ((iq->i_update_core != 0)||
- ((iip != NULL) &&
- (iip->ili_format.ilf_fields & XFS_ILOG_ALL))) {
- clcount++;
- error = xfs_iflush_int(iq, bp);
- if (error) {
- xfs_iunlock(iq,
- XFS_ILOCK_SHARED);
- goto cluster_corrupt_out;
- }
- } else {
- xfs_ifunlock(iq);
- }
- } else {
- xfs_ifunlock(iq);
- }
- }
- xfs_iunlock(iq, XFS_ILOCK_SHARED);
- }
- }
- mutex_spinunlock(&ch->ch_lock, s);
-
- if (clcount) {
- XFS_STATS_INC(xs_icluster_flushcnt);
- XFS_STATS_ADD(xs_icluster_flushinode, clcount);
- }
-
- /*
- * If the buffer is pinned then push on the log so we won't
- * get stuck waiting in the write for too long.
- */
- if (XFS_BUF_ISPINNED(bp)){
- xfs_log_force(mp, (xfs_lsn_t)0, XFS_LOG_FORCE);
- }
-
- if (flags & INT_DELWRI) {
- xfs_bdwrite(mp, bp);
- } else if (flags & INT_ASYNC) {
- xfs_bawrite(mp, bp);
- } else {
- error = xfs_bwrite(mp, bp);
- }
- return error;
-
-corrupt_out:
- xfs_buf_relse(bp);
- xfs_force_shutdown(mp, XFS_CORRUPT_INCORE);
- xfs_iflush_abort(ip);
- /*
- * Unlocks the flush lock
- */
- return XFS_ERROR(EFSCORRUPTED);
-
-cluster_corrupt_out:
- /* Corruption detected in the clustering loop. Invalidate the
- * inode buffer and shut down the filesystem.
- */
- mutex_spinunlock(&ch->ch_lock, s);
-
- /*
- * Clean up the buffer. If it was B_DELWRI, just release it --
- * brelse can handle it with no problems. If not, shut down the
- * filesystem before releasing the buffer.
- */
- if ((bufwasdelwri= XFS_BUF_ISDELAYWRITE(bp))) {
- xfs_buf_relse(bp);
- }
-
- xfs_force_shutdown(mp, XFS_CORRUPT_INCORE);
-
- if(!bufwasdelwri) {
- /*
- * Just like incore_relse: if we have b_iodone functions,
- * mark the buffer as an error and call them. Otherwise
- * mark it as stale and brelse.
- */
- if (XFS_BUF_IODONE_FUNC(bp)) {
- XFS_BUF_CLR_BDSTRAT_FUNC(bp);
- XFS_BUF_UNDONE(bp);
- XFS_BUF_STALE(bp);
- XFS_BUF_SHUT(bp);
- XFS_BUF_ERROR(bp,EIO);
- xfs_biodone(bp);
- } else {
- XFS_BUF_STALE(bp);
- xfs_buf_relse(bp);
- }
- }
-
- xfs_iflush_abort(iq);
- /*
- * Unlocks the flush lock
- */
- return XFS_ERROR(EFSCORRUPTED);
-}
-
-
-STATIC int
-xfs_iflush_int(
- xfs_inode_t *ip,
- xfs_buf_t *bp)
-{
- xfs_inode_log_item_t *iip;
- xfs_dinode_t *dip;
- xfs_mount_t *mp;
-#ifdef XFS_TRANS_DEBUG
- // int first;
-#endif
- SPLDECL(s);
-
- ASSERT(ismrlocked(&ip->i_lock, MR_UPDATE|MR_ACCESS));
- ASSERT(valusema(&ip->i_flock) <= 0);
- ASSERT(ip->i_d.di_format != XFS_DINODE_FMT_BTREE ||
- ip->i_d.di_nextents > ip->i_df.if_ext_max);
-
- iip = ip->i_itemp;
- mp = ip->i_mount;
-
-
- /*
- * If the inode isn't dirty, then just release the inode
- * flush lock and do nothing.
- */
- if ((ip->i_update_core == 0) &&
- ((iip == NULL) || !(iip->ili_format.ilf_fields & XFS_ILOG_ALL))) {
- xfs_ifunlock(ip);
- return 0;
- }
-
- /* set *dip = inode's place in the buffer */
- dip = (xfs_dinode_t *)xfs_buf_offset(bp, ip->i_boffset);
-
- /*
- * Clear i_update_core before copying out the data.
- * This is for coordination with our timestamp updates
- * that don't hold the inode lock. They will always
- * update the timestamps BEFORE setting i_update_core,
- * so if we clear i_update_core after they set it we
- * are guaranteed to see their updates to the timestamps.
- * I believe that this depends on strongly ordered memory
- * semantics, but we have that. We use the SYNCHRONIZE
- * macro to make sure that the compiler does not reorder
- * the i_update_core access below the data copy below.
- */
- ip->i_update_core = 0;
- SYNCHRONIZE();
-
- /*
- * Make sure to get the latest atime from the Linux inode.
- */
- xfs_synchronize_atime(ip);
-
- if (XFS_TEST_ERROR(INT_GET(dip->di_core.di_magic,ARCH_CONVERT) != XFS_DINODE_MAGIC,
- mp, XFS_ERRTAG_IFLUSH_1, XFS_RANDOM_IFLUSH_1)) {
- xfs_cmn_err(XFS_PTAG_IFLUSH, CE_ALERT, mp,
- "xfs_iflush: Bad inode %Lu magic number 0x%x, ptr 0x%p",
- ip->i_ino, (int) INT_GET(dip->di_core.di_magic, ARCH_CONVERT), dip);
- goto corrupt_out;
- }
- if (XFS_TEST_ERROR(ip->i_d.di_magic != XFS_DINODE_MAGIC,
- mp, XFS_ERRTAG_IFLUSH_2, XFS_RANDOM_IFLUSH_2)) {
- xfs_cmn_err(XFS_PTAG_IFLUSH, CE_ALERT, mp,
- "xfs_iflush: Bad inode %Lu, ptr 0x%p, magic number 0x%x",
- ip->i_ino, ip, ip->i_d.di_magic);
- goto corrupt_out;
- }
- if ((ip->i_d.di_mode & S_IFMT) == S_IFREG) {
- if (XFS_TEST_ERROR(
- (ip->i_d.di_format != XFS_DINODE_FMT_EXTENTS) &&
- (ip->i_d.di_format != XFS_DINODE_FMT_BTREE),
- mp, XFS_ERRTAG_IFLUSH_3, XFS_RANDOM_IFLUSH_3)) {
- xfs_cmn_err(XFS_PTAG_IFLUSH, CE_ALERT, mp,
- "xfs_iflush: Bad regular inode %Lu, ptr 0x%p",
- ip->i_ino, ip);
- goto corrupt_out;
- }
- } else if ((ip->i_d.di_mode & S_IFMT) == S_IFDIR) {
- if (XFS_TEST_ERROR(
- (ip->i_d.di_format != XFS_DINODE_FMT_EXTENTS) &&
- (ip->i_d.di_format != XFS_DINODE_FMT_BTREE) &&
- (ip->i_d.di_format != XFS_DINODE_FMT_LOCAL),
- mp, XFS_ERRTAG_IFLUSH_4, XFS_RANDOM_IFLUSH_4)) {
- xfs_cmn_err(XFS_PTAG_IFLUSH, CE_ALERT, mp,
- "xfs_iflush: Bad directory inode %Lu, ptr 0x%p",
- ip->i_ino, ip);
- goto corrupt_out;
- }
- }
- if (XFS_TEST_ERROR(ip->i_d.di_nextents + ip->i_d.di_anextents >
- ip->i_d.di_nblocks, mp, XFS_ERRTAG_IFLUSH_5,
- XFS_RANDOM_IFLUSH_5)) {
- xfs_cmn_err(XFS_PTAG_IFLUSH, CE_ALERT, mp,
- "xfs_iflush: detected corrupt incore inode %Lu, total extents = %d, nblocks = %Ld, ptr 0x%p",
- ip->i_ino,
- ip->i_d.di_nextents + ip->i_d.di_anextents,
- ip->i_d.di_nblocks,
- ip);
- goto corrupt_out;
- }
- if (XFS_TEST_ERROR(ip->i_d.di_forkoff > mp->m_sb.sb_inodesize,
- mp, XFS_ERRTAG_IFLUSH_6, XFS_RANDOM_IFLUSH_6)) {
- xfs_cmn_err(XFS_PTAG_IFLUSH, CE_ALERT, mp,
- "xfs_iflush: bad inode %Lu, forkoff 0x%x, ptr 0x%p",
- ip->i_ino, ip->i_d.di_forkoff, ip);
- goto corrupt_out;
- }
- /*
- * bump the flush iteration count, used to detect flushes which
- * postdate a log record during recovery.
- */
-
- ip->i_d.di_flushiter++;
-
- /*
- * Copy the dirty parts of the inode into the on-disk
- * inode. We always copy out the core of the inode,
- * because if the inode is dirty at all the core must
- * be.
- */
- xfs_xlate_dinode_core((xfs_caddr_t)&(dip->di_core), &(ip->i_d), -1);
-
- /* Wrap, we never let the log put out DI_MAX_FLUSH */
- if (ip->i_d.di_flushiter == DI_MAX_FLUSH)
- ip->i_d.di_flushiter = 0;
-
- /*
- * If this is really an old format inode and the superblock version
- * has not been updated to support only new format inodes, then
- * convert back to the old inode format. If the superblock version
- * has been updated, then make the conversion permanent.
- */
- ASSERT(ip->i_d.di_version == XFS_DINODE_VERSION_1 ||
- XFS_SB_VERSION_HASNLINK(&mp->m_sb));
- if (ip->i_d.di_version == XFS_DINODE_VERSION_1) {
- if (!XFS_SB_VERSION_HASNLINK(&mp->m_sb)) {
- /*
- * Convert it back.
- */
- ASSERT(ip->i_d.di_nlink <= XFS_MAXLINK_1);
- INT_SET(dip->di_core.di_onlink, ARCH_CONVERT, ip->i_d.di_nlink);
- } else {
- /*
- * The superblock version has already been bumped,
- * so just make the conversion to the new inode
- * format permanent.
- */
- ip->i_d.di_version = XFS_DINODE_VERSION_2;
- INT_SET(dip->di_core.di_version, ARCH_CONVERT, XFS_DINODE_VERSION_2);
- ip->i_d.di_onlink = 0;
- dip->di_core.di_onlink = 0;
- memset(&(ip->i_d.di_pad[0]), 0, sizeof(ip->i_d.di_pad));
- memset(&(dip->di_core.di_pad[0]), 0,
- sizeof(dip->di_core.di_pad));
- ASSERT(ip->i_d.di_projid == 0);
- }
- }
-
- if (xfs_iflush_fork(ip, dip, iip, XFS_DATA_FORK, bp) == EFSCORRUPTED) {
- goto corrupt_out;
- }
-
- if (XFS_IFORK_Q(ip)) {
- /*
- * The only error from xfs_iflush_fork is on the data fork.
- */
- (void) xfs_iflush_fork(ip, dip, iip, XFS_ATTR_FORK, bp);
- }
- xfs_inobp_check(mp, bp);
-
- /*
- * We've recorded everything logged in the inode, so we'd
- * like to clear the ilf_fields bits so we don't log and
- * flush things unnecessarily. However, we can't stop
- * logging all this information until the data we've copied
- * into the disk buffer is written to disk. If we did we might
- * overwrite the copy of the inode in the log with all the
- * data after re-logging only part of it, and in the face of
- * a crash we wouldn't have all the data we need to recover.
- *
- * What we do is move the bits to the ili_last_fields field.
- * When logging the inode, these bits are moved back to the
- * ilf_fields field. In the xfs_iflush_done() routine we
- * clear ili_last_fields, since we know that the information
- * those bits represent is permanently on disk. As long as
- * the flush completes before the inode is logged again, then
- * both ilf_fields and ili_last_fields will be cleared.
- *
- * We can play with the ilf_fields bits here, because the inode
- * lock must be held exclusively in order to set bits there
- * and the flush lock protects the ili_last_fields bits.
- * Set ili_logged so the flush done
- * routine can tell whether or not to look in the AIL.
- * Also, store the current LSN of the inode so that we can tell
- * whether the item has moved in the AIL from xfs_iflush_done().
- * In order to read the lsn we need the AIL lock, because
- * it is a 64 bit value that cannot be read atomically.
- */
- if (iip != NULL && iip->ili_format.ilf_fields != 0) {
- iip->ili_last_fields = iip->ili_format.ilf_fields;
- iip->ili_format.ilf_fields = 0;
- iip->ili_logged = 1;
-
- ASSERT(sizeof(xfs_lsn_t) == 8); /* don't lock if it shrinks */
- AIL_LOCK(mp,s);
- iip->ili_flush_lsn = iip->ili_item.li_lsn;
- AIL_UNLOCK(mp, s);
-
- /*
- * Attach the function xfs_iflush_done to the inode's
- * buffer. This will remove the inode from the AIL
- * and unlock the inode's flush lock when the inode is
- * completely written to disk.
- */
- xfs_buf_attach_iodone(bp, (void(*)(xfs_buf_t*,xfs_log_item_t*))
- xfs_iflush_done, (xfs_log_item_t *)iip);
-
- ASSERT(XFS_BUF_FSPRIVATE(bp, void *) != NULL);
- ASSERT(XFS_BUF_IODONE_FUNC(bp) != NULL);
- } else {
- /*
- * We're flushing an inode which is not in the AIL and has
- * not been logged but has i_update_core set. For this
- * case we can use a B_DELWRI flush and immediately drop
- * the inode flush lock because we can avoid the whole
- * AIL state thing. It's OK to drop the flush lock now,
- * because we've already locked the buffer and to do anything
- * you really need both.
- */
- if (iip != NULL) {
- ASSERT(iip->ili_logged == 0);
- ASSERT(iip->ili_last_fields == 0);
- ASSERT((iip->ili_item.li_flags & XFS_LI_IN_AIL) == 0);
- }
- xfs_ifunlock(ip);
- }
-
- return 0;
-
-corrupt_out:
- return XFS_ERROR(EFSCORRUPTED);
-}
-
-
-/*
- * Flush all inactive inodes in mp.
- */
-void
-xfs_iflush_all(
- xfs_mount_t *mp)
-{
- int done;
- int purged;
- xfs_inode_t *ip;
- xfs_vnode_t *vp;
-
- done = 0;
- while (!done) {
- purged = 0;
- XFS_MOUNT_ILOCK(mp);
- ip = mp->m_inodes;
- if (ip == NULL) {
- break;
- }
- do {
- /* Make sure we skip markers inserted by sync */
- if (ip->i_mount == NULL) {
- ip = ip->i_mnext;
- continue;
- }
-
- /*
- * It's up to our caller to purge the root
- * and quota vnodes later.
- */
- vp = XFS_ITOV_NULL(ip);
-
- if (!vp) {
- XFS_MOUNT_IUNLOCK(mp);
- xfs_finish_reclaim(ip, 0, XFS_IFLUSH_ASYNC);
- purged = 1;
- break;
- }
-
- if (vn_count(vp) != 0) {
- if (vn_count(vp) == 1 &&
- (ip == mp->m_rootip ||
- (mp->m_quotainfo &&
- (ip->i_ino == mp->m_sb.sb_uquotino ||
- ip->i_ino == mp->m_sb.sb_gquotino)))) {
- ip = ip->i_mnext;
- continue;
- }
- /*
- * Ignore busy inodes but continue flushing
- * others.
- */
- ip = ip->i_mnext;
- continue;
- }
- /*
- * Sample vp mapping while holding mp locked on MP
- * systems, so we don't purge a reclaimed or
- * nonexistent vnode. We break from the loop
- * since we know that we modify
- * it by pulling ourselves from it in xfs_reclaim()
- * called via vn_purge() below. Set ip to the next
- * entry in the list anyway so we'll know below
- * whether we reached the end or not.
- */
-
- XFS_MOUNT_IUNLOCK(mp);
- vn_purge(vp);
- purged = 1;
- break;
- } while (ip != mp->m_inodes);
- /*
- * We need to distinguish between when we exit the loop
- * after a purge and when we simply hit the end of the
- * list. We can't use the (ip == mp->m_inodes) test,
- * because when we purge an inode at the start of the list
- * the next inode on the list becomes mp->m_inodes. That
- * would cause such a test to bail out early. The purged
- * variable tells us how we got out of the loop.
- */
- if (!purged) {
- done = 1;
- }
- }
- XFS_MOUNT_IUNLOCK(mp);
-}
-
-/*
- * xfs_iaccess: check accessibility of inode for mode.
- * This function is quite linuxy now
- * probably should be move to a os specfic location
- */
-int
-xfs_iaccess(
- xfs_inode_t *ip,
- accmode_t accmode,
- cred_t *cr)
-{
- xfs_vnode_t *vp;
- int error;
-
- mode_t imode;
-
- vp = XFS_ITOV(ip);
- /* FreeBSD local change here */
- imode = (ip->i_d.di_mode & MODEMASK) | VTTOIF(vp->v_vnode->v_type);
- /*
- * Verify that the MAC policy allows the requested access.
- */
- if ((error = _MAC_XFS_IACCESS(ip, accmode, cr)))
- return XFS_ERROR(error);
-
- if (accmode & VWRITE) {
- xfs_mount_t *mp = ip->i_mount;
-
- if ((XVFSTOMNT(XFS_MTOVFS(mp))->mnt_flag & MNT_RDONLY) &&
- (S_ISREG(imode) || S_ISDIR(imode) || S_ISLNK(imode)))
- return XFS_ERROR(EROFS);
-
-#ifdef XXXKAN
- if (IS_IMMUTABLE(inode))
- return XFS_ERROR(EACCES);
-#endif
- }
-
- /*
- * If there's an Access Control List it's used instead of
- * the mode bits.
- */
- if ((error = _ACL_XFS_IACCESS(ip, accmode, cr)) != -1)
- return error ? XFS_ERROR(error) : 0;
-
-
- /* FreeBSD local change here */
- error = vaccess(vp->v_vnode->v_type, imode, ip->i_d.di_uid, ip->i_d.di_gid,
- accmode, cr, NULL);
-
- return (error);
-}
-
-/*
- * xfs_iroundup: round up argument to next power of two
- */
-uint
-xfs_iroundup(
- uint v)
-{
- int i;
- uint m;
-
- if ((v & (v - 1)) == 0)
- return v;
- ASSERT((v & 0x80000000) == 0);
- if ((v & (v + 1)) == 0)
- return v + 1;
- for (i = 0, m = 1; i < 31; i++, m <<= 1) {
- if (v & m)
- continue;
- v |= m;
- if ((v & (v + 1)) == 0)
- return v + 1;
- }
- ASSERT(0);
- return( 0 );
-}
-
-#ifdef XFS_ILOCK_TRACE
-ktrace_t *xfs_ilock_trace_buf;
-
-void
-xfs_ilock_trace(xfs_inode_t *ip, int lock, unsigned int lockflags, inst_t *ra)
-{
- ktrace_enter(ip->i_lock_trace,
- (void *)ip,
- (void *)(unsigned long)lock, /* 1 = LOCK, 3=UNLOCK, etc */
- (void *)(unsigned long)lockflags, /* XFS_ILOCK_EXCL etc */
- (void *)ra, /* caller of ilock */
- (void *)(unsigned long)current_cpu(),
- (void *)(unsigned long)current_pid(),
- NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL);
-}
-#endif
-
-/*
- * Return a pointer to the extent record at file index idx.
- */
-xfs_bmbt_rec_t *
-xfs_iext_get_ext(
- xfs_ifork_t *ifp, /* inode fork pointer */
- xfs_extnum_t idx) /* index of target extent */
-{
- ASSERT(idx >= 0);
- if ((ifp->if_flags & XFS_IFEXTIREC) && (idx == 0)) {
- return ifp->if_u1.if_ext_irec->er_extbuf;
- } else if (ifp->if_flags & XFS_IFEXTIREC) {
- xfs_ext_irec_t *erp; /* irec pointer */
- int erp_idx = 0; /* irec index */
- xfs_extnum_t page_idx = idx; /* ext index in target list */
-
- erp = xfs_iext_idx_to_irec(ifp, &page_idx, &erp_idx, 0);
- return &erp->er_extbuf[page_idx];
- } else if (ifp->if_bytes) {
- return &ifp->if_u1.if_extents[idx];
- } else {
- return NULL;
- }
-}
-
-/*
- * Insert new item(s) into the extent records for incore inode
- * fork 'ifp'. 'count' new items are inserted at index 'idx'.
- */
-void
-xfs_iext_insert(
- xfs_ifork_t *ifp, /* inode fork pointer */
- xfs_extnum_t idx, /* starting index of new items */
- xfs_extnum_t count, /* number of inserted items */
- xfs_bmbt_irec_t *new) /* items to insert */
-{
- xfs_bmbt_rec_t *ep; /* extent record pointer */
- xfs_extnum_t i; /* extent record index */
-
- ASSERT(ifp->if_flags & XFS_IFEXTENTS);
- xfs_iext_add(ifp, idx, count);
- for (i = idx; i < idx + count; i++, new++) {
- ep = xfs_iext_get_ext(ifp, i);
- xfs_bmbt_set_all(ep, new);
- }
-}
-
-/*
- * This is called when the amount of space required for incore file
- * extents needs to be increased. The ext_diff parameter stores the
- * number of new extents being added and the idx parameter contains
- * the extent index where the new extents will be added. If the new
- * extents are being appended, then we just need to (re)allocate and
- * initialize the space. Otherwise, if the new extents are being
- * inserted into the middle of the existing entries, a bit more work
- * is required to make room for the new extents to be inserted. The
- * caller is responsible for filling in the new extent entries upon
- * return.
- */
-void
-xfs_iext_add(
- xfs_ifork_t *ifp, /* inode fork pointer */
- xfs_extnum_t idx, /* index to begin adding exts */
- int ext_diff) /* number of extents to add */
-{
- int byte_diff; /* new bytes being added */
- int new_size; /* size of extents after adding */
- xfs_extnum_t nextents; /* number of extents in file */
-
- nextents = ifp->if_bytes / (uint)sizeof(xfs_bmbt_rec_t);
- ASSERT((idx >= 0) && (idx <= nextents));
- byte_diff = ext_diff * sizeof(xfs_bmbt_rec_t);
- new_size = ifp->if_bytes + byte_diff;
- /*
- * If the new number of extents (nextents + ext_diff)
- * fits inside the inode, then continue to use the inline
- * extent buffer.
- */
- if (nextents + ext_diff <= XFS_INLINE_EXTS) {
- if (idx < nextents) {
- memmove(&ifp->if_u2.if_inline_ext[idx + ext_diff],
- &ifp->if_u2.if_inline_ext[idx],
- (nextents - idx) * sizeof(xfs_bmbt_rec_t));
- memset(&ifp->if_u2.if_inline_ext[idx], 0, byte_diff);
- }
- ifp->if_u1.if_extents = ifp->if_u2.if_inline_ext;
- ifp->if_real_bytes = 0;
- ifp->if_lastex = nextents + ext_diff;
- }
- /*
- * Otherwise use a linear (direct) extent list.
- * If the extents are currently inside the inode,
- * xfs_iext_realloc_direct will switch us from
- * inline to direct extent allocation mode.
- */
- else if (nextents + ext_diff <= XFS_LINEAR_EXTS) {
- xfs_iext_realloc_direct(ifp, new_size);
- if (idx < nextents) {
- memmove(&ifp->if_u1.if_extents[idx + ext_diff],
- &ifp->if_u1.if_extents[idx],
- (nextents - idx) * sizeof(xfs_bmbt_rec_t));
- memset(&ifp->if_u1.if_extents[idx], 0, byte_diff);
- }
- }
- /* Indirection array */
- else {
- xfs_ext_irec_t *erp;
- int erp_idx = 0;
- int page_idx = idx;
-
- ASSERT(nextents + ext_diff > XFS_LINEAR_EXTS);
- if (ifp->if_flags & XFS_IFEXTIREC) {
- erp = xfs_iext_idx_to_irec(ifp, &page_idx, &erp_idx, 1);
- } else {
- xfs_iext_irec_init(ifp);
- ASSERT(ifp->if_flags & XFS_IFEXTIREC);
- erp = ifp->if_u1.if_ext_irec;
- }
- /* Extents fit in target extent page */
- if (erp && erp->er_extcount + ext_diff <= XFS_LINEAR_EXTS) {
- if (page_idx < erp->er_extcount) {
- memmove(&erp->er_extbuf[page_idx + ext_diff],
- &erp->er_extbuf[page_idx],
- (erp->er_extcount - page_idx) *
- sizeof(xfs_bmbt_rec_t));
- memset(&erp->er_extbuf[page_idx], 0, byte_diff);
- }
- erp->er_extcount += ext_diff;
- xfs_iext_irec_update_extoffs(ifp, erp_idx + 1, ext_diff);
- }
- /* Insert a new extent page */
- else if (erp) {
- xfs_iext_add_indirect_multi(ifp,
- erp_idx, page_idx, ext_diff);
- }
- /*
- * If extent(s) are being appended to the last page in
- * the indirection array and the new extent(s) don't fit
- * in the page, then erp is NULL and erp_idx is set to
- * the next index needed in the indirection array.
- */
- else {
- int count = ext_diff;
-
- while (count) {
- erp = xfs_iext_irec_new(ifp, erp_idx);
- erp->er_extcount = count;
- count -= MIN(count, (int)XFS_LINEAR_EXTS);
- if (count) {
- erp_idx++;
- }
- }
- }
- }
- ifp->if_bytes = new_size;
-}
-
-/*
- * This is called when incore extents are being added to the indirection
- * array and the new extents do not fit in the target extent list. The
- * erp_idx parameter contains the irec index for the target extent list
- * in the indirection array, and the idx parameter contains the extent
- * index within the list. The number of extents being added is stored
- * in the count parameter.
- *
- * |-------| |-------|
- * | | | | idx - number of extents before idx
- * | idx | | count |
- * | | | | count - number of extents being inserted at idx
- * |-------| |-------|
- * | count | | nex2 | nex2 - number of extents after idx + count
- * |-------| |-------|
- */
-void
-xfs_iext_add_indirect_multi(
- xfs_ifork_t *ifp, /* inode fork pointer */
- int erp_idx, /* target extent irec index */
- xfs_extnum_t idx, /* index within target list */
- int count) /* new extents being added */
-{
- int byte_diff; /* new bytes being added */
- xfs_ext_irec_t *erp; /* pointer to irec entry */
- xfs_extnum_t ext_diff; /* number of extents to add */
- xfs_extnum_t ext_cnt; /* new extents still needed */
- xfs_extnum_t nex2; /* extents after idx + count */
- xfs_bmbt_rec_t *nex2_ep = NULL; /* temp list for nex2 extents */
- int nlists; /* number of irec's (lists) */
-
- ASSERT(ifp->if_flags & XFS_IFEXTIREC);
- erp = &ifp->if_u1.if_ext_irec[erp_idx];
- nex2 = erp->er_extcount - idx;
- nlists = ifp->if_real_bytes / XFS_IEXT_BUFSZ;
-
- /*
- * Save second part of target extent list
- * (all extents past */
- if (nex2) {
- byte_diff = nex2 * sizeof(xfs_bmbt_rec_t);
- nex2_ep = (xfs_bmbt_rec_t *) kmem_alloc(byte_diff, KM_SLEEP);
- memmove(nex2_ep, &erp->er_extbuf[idx], byte_diff);
- erp->er_extcount -= nex2;
- xfs_iext_irec_update_extoffs(ifp, erp_idx + 1, -nex2);
- memset(&erp->er_extbuf[idx], 0, byte_diff);
- }
-
- /*
- * Add the new extents to the end of the target
- * list, then allocate new irec record(s) and
- * extent buffer(s) as needed to store the rest
- * of the new extents.
- */
- ext_cnt = count;
- ext_diff = MIN(ext_cnt, (int)XFS_LINEAR_EXTS - erp->er_extcount);
- if (ext_diff) {
- erp->er_extcount += ext_diff;
- xfs_iext_irec_update_extoffs(ifp, erp_idx + 1, ext_diff);
- ext_cnt -= ext_diff;
- }
- while (ext_cnt) {
- erp_idx++;
- erp = xfs_iext_irec_new(ifp, erp_idx);
- ext_diff = MIN(ext_cnt, (int)XFS_LINEAR_EXTS);
- erp->er_extcount = ext_diff;
- xfs_iext_irec_update_extoffs(ifp, erp_idx + 1, ext_diff);
- ext_cnt -= ext_diff;
- }
-
- /* Add nex2 extents back to indirection array */
- if (nex2) {
- xfs_extnum_t ext_avail;
- int i;
-
- byte_diff = nex2 * sizeof(xfs_bmbt_rec_t);
- ext_avail = XFS_LINEAR_EXTS - erp->er_extcount;
- i = 0;
- /*
- * If nex2 extents fit in the current page, append
- * nex2_ep after the new extents.
- */
- if (nex2 <= ext_avail) {
- i = erp->er_extcount;
- }
- /*
- * Otherwise, check if space is available in the
- * next page.
- */
- else if ((erp_idx < nlists - 1) &&
- (nex2 <= (ext_avail = XFS_LINEAR_EXTS -
- ifp->if_u1.if_ext_irec[erp_idx+1].er_extcount))) {
- erp_idx++;
- erp++;
- /* Create a hole for nex2 extents */
- memmove(&erp->er_extbuf[nex2], erp->er_extbuf,
- erp->er_extcount * sizeof(xfs_bmbt_rec_t));
- }
- /*
- * Final choice, create a new extent page for
- * nex2 extents.
- */
- else {
- erp_idx++;
- erp = xfs_iext_irec_new(ifp, erp_idx);
- }
- memmove(&erp->er_extbuf[i], nex2_ep, byte_diff);
- kmem_free(nex2_ep, byte_diff);
- erp->er_extcount += nex2;
- xfs_iext_irec_update_extoffs(ifp, erp_idx + 1, nex2);
- }
-}
-
-/*
- * This is called when the amount of space required for incore file
- * extents needs to be decreased. The ext_diff parameter stores the
- * number of extents to be removed and the idx parameter contains
- * the extent index where the extents will be removed from.
- *
- * If the amount of space needed has decreased below the linear
- * limit, XFS_IEXT_BUFSZ, then switch to using the contiguous
- * extent array. Otherwise, use kmem_realloc() to adjust the
- * size to what is needed.
- */
-void
-xfs_iext_remove(
- xfs_ifork_t *ifp, /* inode fork pointer */
- xfs_extnum_t idx, /* index to begin removing exts */
- int ext_diff) /* number of extents to remove */
-{
- xfs_extnum_t nextents; /* number of extents in file */
- int new_size; /* size of extents after removal */
-
- ASSERT(ext_diff > 0);
- nextents = ifp->if_bytes / (uint)sizeof(xfs_bmbt_rec_t);
- new_size = (nextents - ext_diff) * sizeof(xfs_bmbt_rec_t);
-
- if (new_size == 0) {
- xfs_iext_destroy(ifp);
- } else if (ifp->if_flags & XFS_IFEXTIREC) {
- xfs_iext_remove_indirect(ifp, idx, ext_diff);
- } else if (ifp->if_real_bytes) {
- xfs_iext_remove_direct(ifp, idx, ext_diff);
- } else {
- xfs_iext_remove_inline(ifp, idx, ext_diff);
- }
- ifp->if_bytes = new_size;
-}
-
-/*
- * This removes ext_diff extents from the inline buffer, beginning
- * at extent index idx.
- */
-void
-xfs_iext_remove_inline(
- xfs_ifork_t *ifp, /* inode fork pointer */
- xfs_extnum_t idx, /* index to begin removing exts */
- int ext_diff) /* number of extents to remove */
-{
- int nextents; /* number of extents in file */
-
- ASSERT(!(ifp->if_flags & XFS_IFEXTIREC));
- ASSERT(idx < XFS_INLINE_EXTS);
- nextents = ifp->if_bytes / (uint)sizeof(xfs_bmbt_rec_t);
- ASSERT(((nextents - ext_diff) > 0) &&
- (nextents - ext_diff) < XFS_INLINE_EXTS);
-
- if (idx + ext_diff < nextents) {
- memmove(&ifp->if_u2.if_inline_ext[idx],
- &ifp->if_u2.if_inline_ext[idx + ext_diff],
- (nextents - (idx + ext_diff)) *
- sizeof(xfs_bmbt_rec_t));
- memset(&ifp->if_u2.if_inline_ext[nextents - ext_diff],
- 0, ext_diff * sizeof(xfs_bmbt_rec_t));
- } else {
- memset(&ifp->if_u2.if_inline_ext[idx], 0,
- ext_diff * sizeof(xfs_bmbt_rec_t));
- }
-}
-
-/*
- * This removes ext_diff extents from a linear (direct) extent list,
- * beginning at extent index idx. If the extents are being removed
- * from the end of the list (ie. truncate) then we just need to re-
- * allocate the list to remove the extra space. Otherwise, if the
- * extents are being removed from the middle of the existing extent
- * entries, then we first need to move the extent records beginning
- * at idx + ext_diff up in the list to overwrite the records being
- * removed, then remove the extra space via kmem_realloc.
- */
-void
-xfs_iext_remove_direct(
- xfs_ifork_t *ifp, /* inode fork pointer */
- xfs_extnum_t idx, /* index to begin removing exts */
- int ext_diff) /* number of extents to remove */
-{
- xfs_extnum_t nextents; /* number of extents in file */
- int new_size; /* size of extents after removal */
-
- ASSERT(!(ifp->if_flags & XFS_IFEXTIREC));
- new_size = ifp->if_bytes -
- (ext_diff * sizeof(xfs_bmbt_rec_t));
- nextents = ifp->if_bytes / (uint)sizeof(xfs_bmbt_rec_t);
-
- if (new_size == 0) {
- xfs_iext_destroy(ifp);
- return;
- }
- /* Move extents up in the list (if needed) */
- if (idx + ext_diff < nextents) {
- memmove(&ifp->if_u1.if_extents[idx],
- &ifp->if_u1.if_extents[idx + ext_diff],
- (nextents - (idx + ext_diff)) *
- sizeof(xfs_bmbt_rec_t));
- }
- memset(&ifp->if_u1.if_extents[nextents - ext_diff],
- 0, ext_diff * sizeof(xfs_bmbt_rec_t));
- /*
- * Reallocate the direct extent list. If the extents
- * will fit inside the inode then xfs_iext_realloc_direct
- * will switch from direct to inline extent allocation
- * mode for us.
- */
- xfs_iext_realloc_direct(ifp, new_size);
- ifp->if_bytes = new_size;
-}
-
-/*
- * This is called when incore extents are being removed from the
- * indirection array and the extents being removed span multiple extent
- * buffers. The idx parameter contains the file extent index where we
- * want to begin removing extents, and the count parameter contains
- * how many extents need to be removed.
- *
- * |-------| |-------|
- * | nex1 | | | nex1 - number of extents before idx
- * |-------| | count |
- * | | | | count - number of extents being removed at idx
- * | count | |-------|
- * | | | nex2 | nex2 - number of extents after idx + count
- * |-------| |-------|
- */
-void
-xfs_iext_remove_indirect(
- xfs_ifork_t *ifp, /* inode fork pointer */
- xfs_extnum_t idx, /* index to begin removing extents */
- int count) /* number of extents to remove */
-{
- xfs_ext_irec_t *erp; /* indirection array pointer */
- int erp_idx = 0; /* indirection array index */
- xfs_extnum_t ext_cnt; /* extents left to remove */
- xfs_extnum_t ext_diff; /* extents to remove in current list */
- xfs_extnum_t nex1; /* number of extents before idx */
- xfs_extnum_t nex2; /* extents after idx + count */
- int nlists; /* entries in indirection array */
- int page_idx = idx; /* index in target extent list */
-
- ASSERT(ifp->if_flags & XFS_IFEXTIREC);
- erp = xfs_iext_idx_to_irec(ifp, &page_idx, &erp_idx, 0);
- ASSERT(erp != NULL);
- nlists = ifp->if_real_bytes / XFS_IEXT_BUFSZ;
- nex1 = page_idx;
- ext_cnt = count;
- while (ext_cnt) {
- nex2 = MAX((erp->er_extcount - (nex1 + ext_cnt)), 0);
- ext_diff = MIN(ext_cnt, (erp->er_extcount - nex1));
- /*
- * Check for deletion of entire list;
- * xfs_iext_irec_remove() updates extent offsets.
- */
- if (ext_diff == erp->er_extcount) {
- xfs_iext_irec_remove(ifp, erp_idx);
- ext_cnt -= ext_diff;
- nex1 = 0;
- if (ext_cnt) {
- ASSERT(erp_idx < ifp->if_real_bytes /
- XFS_IEXT_BUFSZ);
- erp = &ifp->if_u1.if_ext_irec[erp_idx];
- nex1 = 0;
- continue;
- } else {
- break;
- }
- }
- /* Move extents up (if needed) */
- if (nex2) {
- memmove(&erp->er_extbuf[nex1],
- &erp->er_extbuf[nex1 + ext_diff],
- nex2 * sizeof(xfs_bmbt_rec_t));
- }
- /* Zero out rest of page */
- memset(&erp->er_extbuf[nex1 + nex2], 0, (XFS_IEXT_BUFSZ -
- ((nex1 + nex2) * sizeof(xfs_bmbt_rec_t))));
- /* Update remaining counters */
- erp->er_extcount -= ext_diff;
- xfs_iext_irec_update_extoffs(ifp, erp_idx + 1, -ext_diff);
- ext_cnt -= ext_diff;
- nex1 = 0;
- erp_idx++;
- erp++;
- }
- ifp->if_bytes -= count * sizeof(xfs_bmbt_rec_t);
- xfs_iext_irec_compact(ifp);
-}
-
-/*
- * Create, destroy, or resize a linear (direct) block of extents.
- */
-void
-xfs_iext_realloc_direct(
- xfs_ifork_t *ifp, /* inode fork pointer */
- int new_size) /* new size of extents */
-{
- int rnew_size; /* real new size of extents */
-
- rnew_size = new_size;
-
- ASSERT(!(ifp->if_flags & XFS_IFEXTIREC) ||
- ((new_size >= 0) && (new_size <= XFS_IEXT_BUFSZ) &&
- (new_size != ifp->if_real_bytes)));
-
- /* Free extent records */
- if (new_size == 0) {
- xfs_iext_destroy(ifp);
- }
- /* Resize direct extent list and zero any new bytes */
- else if (ifp->if_real_bytes) {
- /* Check if extents will fit inside the inode */
- if (new_size <= XFS_INLINE_EXTS * sizeof(xfs_bmbt_rec_t)) {
- xfs_iext_direct_to_inline(ifp, new_size /
- (uint)sizeof(xfs_bmbt_rec_t));
- ifp->if_bytes = new_size;
- return;
- }
- if ((new_size & (new_size - 1)) != 0) {
- rnew_size = xfs_iroundup(new_size);
- }
- if (rnew_size != ifp->if_real_bytes) {
- ifp->if_u1.if_extents = (xfs_bmbt_rec_t *)
- kmem_realloc(ifp->if_u1.if_extents,
- rnew_size,
- ifp->if_real_bytes,
- KM_SLEEP);
- }
- if (rnew_size > ifp->if_real_bytes) {
- memset(&ifp->if_u1.if_extents[ifp->if_bytes /
- (uint)sizeof(xfs_bmbt_rec_t)], 0,
- rnew_size - ifp->if_real_bytes);
- }
- }
- /*
- * Switch from the inline extent buffer to a direct
- * extent list. Be sure to include the inline extent
- * bytes in new_size.
- */
- else {
- new_size += ifp->if_bytes;
- if ((new_size & (new_size - 1)) != 0) {
- rnew_size = xfs_iroundup(new_size);
- }
- xfs_iext_inline_to_direct(ifp, rnew_size);
- }
- ifp->if_real_bytes = rnew_size;
- ifp->if_bytes = new_size;
-}
-
-/*
- * Switch from linear (direct) extent records to inline buffer.
- */
-void
-xfs_iext_direct_to_inline(
- xfs_ifork_t *ifp, /* inode fork pointer */
- xfs_extnum_t nextents) /* number of extents in file */
-{
- ASSERT(ifp->if_flags & XFS_IFEXTENTS);
- ASSERT(nextents <= XFS_INLINE_EXTS);
- /*
- * The inline buffer was zeroed when we switched
- * from inline to direct extent allocation mode,
- * so we don't need to clear it here.
- */
- memcpy(ifp->if_u2.if_inline_ext, ifp->if_u1.if_extents,
- nextents * sizeof(xfs_bmbt_rec_t));
- kmem_free(ifp->if_u1.if_extents, KM_SLEEP);
- ifp->if_u1.if_extents = ifp->if_u2.if_inline_ext;
- ifp->if_real_bytes = 0;
-}
-
-/*
- * Switch from inline buffer to linear (direct) extent records.
- * new_size should already be rounded up to the next power of 2
- * by the caller (when appropriate), so use new_size as it is.
- * However, since new_size may be rounded up, we can't update
- * if_bytes here. It is the caller's responsibility to update
- * if_bytes upon return.
- */
-void
-xfs_iext_inline_to_direct(
- xfs_ifork_t *ifp, /* inode fork pointer */
- int new_size) /* number of extents in file */
-{
- ifp->if_u1.if_extents = (xfs_bmbt_rec_t *)
- kmem_alloc(new_size, KM_SLEEP);
- memset(ifp->if_u1.if_extents, 0, new_size);
- if (ifp->if_bytes) {
- memcpy(ifp->if_u1.if_extents, ifp->if_u2.if_inline_ext,
- ifp->if_bytes);
- memset(ifp->if_u2.if_inline_ext, 0, XFS_INLINE_EXTS *
- sizeof(xfs_bmbt_rec_t));
- }
- ifp->if_real_bytes = new_size;
-}
-
-/*
- * Resize an extent indirection array to new_size bytes.
- */
-void
-xfs_iext_realloc_indirect(
- xfs_ifork_t *ifp, /* inode fork pointer */
- int new_size) /* new indirection array size */
-{
- int nlists; /* number of irec's (ex lists) */
- int size; /* current indirection array size */
-
- ASSERT(ifp->if_flags & XFS_IFEXTIREC);
- nlists = ifp->if_real_bytes / XFS_IEXT_BUFSZ;
- size = nlists * sizeof(xfs_ext_irec_t);
- ASSERT(ifp->if_real_bytes);
- ASSERT((new_size >= 0) && (new_size != size));
- if (new_size == 0) {
- xfs_iext_destroy(ifp);
- } else {
- ifp->if_u1.if_ext_irec = (xfs_ext_irec_t *)
- kmem_realloc(ifp->if_u1.if_ext_irec,
- new_size, size, KM_SLEEP);
- }
-}
-
-/*
- * Switch from indirection array to linear (direct) extent allocations.
- */
-void
-xfs_iext_indirect_to_direct(
- xfs_ifork_t *ifp) /* inode fork pointer */
-{
- xfs_bmbt_rec_t *ep; /* extent record pointer */
- xfs_extnum_t nextents; /* number of extents in file */
- int size; /* size of file extents */
-
- ASSERT(ifp->if_flags & XFS_IFEXTIREC);
- nextents = ifp->if_bytes / (uint)sizeof(xfs_bmbt_rec_t);
- ASSERT(nextents <= XFS_LINEAR_EXTS);
- size = nextents * sizeof(xfs_bmbt_rec_t);
-
- xfs_iext_irec_compact_full(ifp);
- ASSERT(ifp->if_real_bytes == XFS_IEXT_BUFSZ);
-
- ep = ifp->if_u1.if_ext_irec->er_extbuf;
- kmem_free(ifp->if_u1.if_ext_irec, sizeof(xfs_ext_irec_t));
- ifp->if_flags &= ~XFS_IFEXTIREC;
- ifp->if_u1.if_extents = ep;
- ifp->if_bytes = size;
- if (nextents < XFS_LINEAR_EXTS) {
- xfs_iext_realloc_direct(ifp, size);
- }
-}
-
-/*
- * Free incore file extents.
- */
-void
-xfs_iext_destroy(
- xfs_ifork_t *ifp) /* inode fork pointer */
-{
- if (ifp->if_flags & XFS_IFEXTIREC) {
- int erp_idx;
- int nlists;
-
- nlists = ifp->if_real_bytes / XFS_IEXT_BUFSZ;
- for (erp_idx = nlists - 1; erp_idx >= 0 ; erp_idx--) {
- xfs_iext_irec_remove(ifp, erp_idx);
- }
- ifp->if_flags &= ~XFS_IFEXTIREC;
- } else if (ifp->if_real_bytes) {
- kmem_free(ifp->if_u1.if_extents, ifp->if_real_bytes);
- } else if (ifp->if_bytes) {
- memset(ifp->if_u2.if_inline_ext, 0, XFS_INLINE_EXTS *
- sizeof(xfs_bmbt_rec_t));
- }
- ifp->if_u1.if_extents = NULL;
- ifp->if_real_bytes = 0;
- ifp->if_bytes = 0;
-}
-
-/*
- * Return a pointer to the extent record for file system block bno.
- */
-xfs_bmbt_rec_t * /* pointer to found extent record */
-xfs_iext_bno_to_ext(
- xfs_ifork_t *ifp, /* inode fork pointer */
- xfs_fileoff_t bno, /* block number to search for */
- xfs_extnum_t *idxp) /* index of target extent */
-{
- xfs_bmbt_rec_t *base; /* pointer to first extent */
- xfs_filblks_t blockcount = 0; /* number of blocks in extent */
- xfs_bmbt_rec_t *ep = NULL; /* pointer to target extent */
- xfs_ext_irec_t *erp = NULL; /* indirection array pointer */
- int high; /* upper boundary in search */
- xfs_extnum_t idx = 0; /* index of target extent */
- int low; /* lower boundary in search */
- xfs_extnum_t nextents; /* number of file extents */
- xfs_fileoff_t startoff = 0; /* start offset of extent */
-
- nextents = ifp->if_bytes / (uint)sizeof(xfs_bmbt_rec_t);
- if (nextents == 0) {
- *idxp = 0;
- return NULL;
- }
- low = 0;
- if (ifp->if_flags & XFS_IFEXTIREC) {
- /* Find target extent list */
- int erp_idx = 0;
- erp = xfs_iext_bno_to_irec(ifp, bno, &erp_idx);
- base = erp->er_extbuf;
- high = erp->er_extcount - 1;
- } else {
- base = ifp->if_u1.if_extents;
- high = nextents - 1;
- }
- /* Binary search extent records */
- while (low <= high) {
- idx = (low + high) >> 1;
- ep = base + idx;
- startoff = xfs_bmbt_get_startoff(ep);
- blockcount = xfs_bmbt_get_blockcount(ep);
- if (bno < startoff) {
- high = idx - 1;
- } else if (bno >= startoff + blockcount) {
- low = idx + 1;
- } else {
- /* Convert back to file-based extent index */
- if (ifp->if_flags & XFS_IFEXTIREC) {
- idx += erp->er_extoff;
- }
- *idxp = idx;
- return ep;
- }
- }
- /* Convert back to file-based extent index */
- if (ifp->if_flags & XFS_IFEXTIREC) {
- idx += erp->er_extoff;
- }
- if (bno >= startoff + blockcount) {
- if (++idx == nextents) {
- ep = NULL;
- } else {
- ep = xfs_iext_get_ext(ifp, idx);
- }
- }
- *idxp = idx;
- return ep;
-}
-
-/*
- * Return a pointer to the indirection array entry containing the
- * extent record for filesystem block bno. Store the index of the
- * target irec in *erp_idxp.
- */
-xfs_ext_irec_t * /* pointer to found extent record */
-xfs_iext_bno_to_irec(
- xfs_ifork_t *ifp, /* inode fork pointer */
- xfs_fileoff_t bno, /* block number to search for */
- int *erp_idxp) /* irec index of target ext list */
-{
- xfs_ext_irec_t *erp = NULL; /* indirection array pointer */
- xfs_ext_irec_t *erp_next; /* next indirection array entry */
- int erp_idx; /* indirection array index */
- int nlists; /* number of extent irec's (lists) */
- int high; /* binary search upper limit */
- int low; /* binary search lower limit */
-
- ASSERT(ifp->if_flags & XFS_IFEXTIREC);
- nlists = ifp->if_real_bytes / XFS_IEXT_BUFSZ;
- erp_idx = 0;
- low = 0;
- high = nlists - 1;
- while (low <= high) {
- erp_idx = (low + high) >> 1;
- erp = &ifp->if_u1.if_ext_irec[erp_idx];
- erp_next = erp_idx < nlists - 1 ? erp + 1 : NULL;
- if (bno < xfs_bmbt_get_startoff(erp->er_extbuf)) {
- high = erp_idx - 1;
- } else if (erp_next && bno >=
- xfs_bmbt_get_startoff(erp_next->er_extbuf)) {
- low = erp_idx + 1;
- } else {
- break;
- }
- }
- *erp_idxp = erp_idx;
- return erp;
-}
-
-/*
- * Return a pointer to the indirection array entry containing the
- * extent record at file extent index *idxp. Store the index of the
- * target irec in *erp_idxp and store the page index of the target
- * extent record in *idxp.
- */
-xfs_ext_irec_t *
-xfs_iext_idx_to_irec(
- xfs_ifork_t *ifp, /* inode fork pointer */
- xfs_extnum_t *idxp, /* extent index (file -> page) */
- int *erp_idxp, /* pointer to target irec */
- int realloc) /* new bytes were just added */
-{
- xfs_ext_irec_t *prev; /* pointer to previous irec */
- xfs_ext_irec_t *erp = NULL; /* pointer to current irec */
- int erp_idx; /* indirection array index */
- int nlists; /* number of irec's (ex lists) */
- int high; /* binary search upper limit */
- int low; /* binary search lower limit */
- xfs_extnum_t page_idx = *idxp; /* extent index in target list */
-
- ASSERT(ifp->if_flags & XFS_IFEXTIREC);
- ASSERT(page_idx >= 0 && page_idx <=
- ifp->if_bytes / (uint)sizeof(xfs_bmbt_rec_t));
- nlists = ifp->if_real_bytes / XFS_IEXT_BUFSZ;
- erp_idx = 0;
- low = 0;
- high = nlists - 1;
-
- /* Binary search extent irec's */
- while (low <= high) {
- erp_idx = (low + high) >> 1;
- erp = &ifp->if_u1.if_ext_irec[erp_idx];
- prev = erp_idx > 0 ? erp - 1 : NULL;
- if (page_idx < erp->er_extoff || (page_idx == erp->er_extoff &&
- realloc && prev && prev->er_extcount < XFS_LINEAR_EXTS)) {
- high = erp_idx - 1;
- } else if (page_idx > erp->er_extoff + erp->er_extcount ||
- (page_idx == erp->er_extoff + erp->er_extcount &&
- !realloc)) {
- low = erp_idx + 1;
- } else if (page_idx == erp->er_extoff + erp->er_extcount &&
- erp->er_extcount == XFS_LINEAR_EXTS) {
- ASSERT(realloc);
- page_idx = 0;
- erp_idx++;
- erp = erp_idx < nlists ? erp + 1 : NULL;
- break;
- } else {
- page_idx -= erp->er_extoff;
- break;
- }
- }
- *idxp = page_idx;
- *erp_idxp = erp_idx;
- return(erp);
-}
-
-/*
- * Allocate and initialize an indirection array once the space needed
- * for incore extents increases above XFS_IEXT_BUFSZ.
- */
-void
-xfs_iext_irec_init(
- xfs_ifork_t *ifp) /* inode fork pointer */
-{
- xfs_ext_irec_t *erp; /* indirection array pointer */
- xfs_extnum_t nextents; /* number of extents in file */
-
- ASSERT(!(ifp->if_flags & XFS_IFEXTIREC));
- nextents = ifp->if_bytes / (uint)sizeof(xfs_bmbt_rec_t);
- ASSERT(nextents <= XFS_LINEAR_EXTS);
-
- erp = (xfs_ext_irec_t *)
- kmem_alloc(sizeof(xfs_ext_irec_t), KM_SLEEP);
-
- if (nextents == 0) {
- ifp->if_u1.if_extents = (xfs_bmbt_rec_t *)
- kmem_alloc(XFS_IEXT_BUFSZ, KM_SLEEP);
- } else if (!ifp->if_real_bytes) {
- xfs_iext_inline_to_direct(ifp, XFS_IEXT_BUFSZ);
- } else if (ifp->if_real_bytes < XFS_IEXT_BUFSZ) {
- xfs_iext_realloc_direct(ifp, XFS_IEXT_BUFSZ);
- }
- erp->er_extbuf = ifp->if_u1.if_extents;
- erp->er_extcount = nextents;
- erp->er_extoff = 0;
-
- ifp->if_flags |= XFS_IFEXTIREC;
- ifp->if_real_bytes = XFS_IEXT_BUFSZ;
- ifp->if_bytes = nextents * sizeof(xfs_bmbt_rec_t);
- ifp->if_u1.if_ext_irec = erp;
-
- return;
-}
-
-/*
- * Allocate and initialize a new entry in the indirection array.
- */
-xfs_ext_irec_t *
-xfs_iext_irec_new(
- xfs_ifork_t *ifp, /* inode fork pointer */
- int erp_idx) /* index for new irec */
-{
- xfs_ext_irec_t *erp; /* indirection array pointer */
- int i; /* loop counter */
- int nlists; /* number of irec's (ex lists) */
-
- ASSERT(ifp->if_flags & XFS_IFEXTIREC);
- nlists = ifp->if_real_bytes / XFS_IEXT_BUFSZ;
-
- /* Resize indirection array */
- xfs_iext_realloc_indirect(ifp, ++nlists *
- sizeof(xfs_ext_irec_t));
- /*
- * Move records down in the array so the
- * new page can use erp_idx.
- */
- erp = ifp->if_u1.if_ext_irec;
- for (i = nlists - 1; i > erp_idx; i--) {
- memmove(&erp[i], &erp[i-1], sizeof(xfs_ext_irec_t));
- }
- ASSERT(i == erp_idx);
-
- /* Initialize new extent record */
- erp = ifp->if_u1.if_ext_irec;
- erp[erp_idx].er_extbuf = (xfs_bmbt_rec_t *)
- kmem_alloc(XFS_IEXT_BUFSZ, KM_SLEEP);
- ifp->if_real_bytes = nlists * XFS_IEXT_BUFSZ;
- memset(erp[erp_idx].er_extbuf, 0, XFS_IEXT_BUFSZ);
- erp[erp_idx].er_extcount = 0;
- erp[erp_idx].er_extoff = erp_idx > 0 ?
- erp[erp_idx-1].er_extoff + erp[erp_idx-1].er_extcount : 0;
- return (&erp[erp_idx]);
-}
-
-/*
- * Remove a record from the indirection array.
- */
-void
-xfs_iext_irec_remove(
- xfs_ifork_t *ifp, /* inode fork pointer */
- int erp_idx) /* irec index to remove */
-{
- xfs_ext_irec_t *erp; /* indirection array pointer */
- int i; /* loop counter */
- int nlists; /* number of irec's (ex lists) */
-
- ASSERT(ifp->if_flags & XFS_IFEXTIREC);
- nlists = ifp->if_real_bytes / XFS_IEXT_BUFSZ;
- erp = &ifp->if_u1.if_ext_irec[erp_idx];
- if (erp->er_extbuf) {
- xfs_iext_irec_update_extoffs(ifp, erp_idx + 1,
- -erp->er_extcount);
- kmem_free(erp->er_extbuf, XFS_IEXT_BUFSZ);
- }
- /* Compact extent records */
- erp = ifp->if_u1.if_ext_irec;
- for (i = erp_idx; i < nlists - 1; i++) {
- memmove(&erp[i], &erp[i+1], sizeof(xfs_ext_irec_t));
- }
- /*
- * Manually free the last extent record from the indirection
- * array. A call to xfs_iext_realloc_indirect() with a size
- * of zero would result in a call to xfs_iext_destroy() which
- * would in turn call this function again, creating a nasty
- * infinite loop.
- */
- if (--nlists) {
- xfs_iext_realloc_indirect(ifp,
- nlists * sizeof(xfs_ext_irec_t));
- } else {
- kmem_free(ifp->if_u1.if_ext_irec,
- sizeof(xfs_ext_irec_t));
- }
- ifp->if_real_bytes = nlists * XFS_IEXT_BUFSZ;
-}
-
-/*
- * This is called to clean up large amounts of unused memory allocated
- * by the indirection array. Before compacting anything though, verify
- * that the indirection array is still needed and switch back to the
- * linear extent list (or even the inline buffer) if possible. The
- * compaction policy is as follows:
- *
- * Full Compaction: Extents fit into a single page (or inline buffer)
- * Full Compaction: Extents occupy less than 10% of allocated space
- * Partial Compaction: Extents occupy > 10% and < 50% of allocated space
- * No Compaction: Extents occupy at least 50% of allocated space
- */
-void
-xfs_iext_irec_compact(
- xfs_ifork_t *ifp) /* inode fork pointer */
-{
- xfs_extnum_t nextents; /* number of extents in file */
- int nlists; /* number of irec's (ex lists) */
-
- ASSERT(ifp->if_flags & XFS_IFEXTIREC);
- nlists = ifp->if_real_bytes / XFS_IEXT_BUFSZ;
- nextents = ifp->if_bytes / (uint)sizeof(xfs_bmbt_rec_t);
-
- if (nextents == 0) {
- xfs_iext_destroy(ifp);
- } else if (nextents <= XFS_INLINE_EXTS) {
- xfs_iext_indirect_to_direct(ifp);
- xfs_iext_direct_to_inline(ifp, nextents);
- } else if (nextents <= XFS_LINEAR_EXTS) {
- xfs_iext_indirect_to_direct(ifp);
- } else if (nextents < (nlists * XFS_LINEAR_EXTS) >> 3) {
- xfs_iext_irec_compact_full(ifp);
- } else if (nextents < (nlists * XFS_LINEAR_EXTS) >> 1) {
- xfs_iext_irec_compact_pages(ifp);
- }
-}
-
-/*
- * Combine extents from neighboring extent pages.
- */
-void
-xfs_iext_irec_compact_pages(
- xfs_ifork_t *ifp) /* inode fork pointer */
-{
- xfs_ext_irec_t *erp, *erp_next;/* pointers to irec entries */
- int erp_idx = 0; /* indirection array index */
- int nlists; /* number of irec's (ex lists) */
-
- ASSERT(ifp->if_flags & XFS_IFEXTIREC);
- nlists = ifp->if_real_bytes / XFS_IEXT_BUFSZ;
- while (erp_idx < nlists - 1) {
- erp = &ifp->if_u1.if_ext_irec[erp_idx];
- erp_next = erp + 1;
- if (erp_next->er_extcount <=
- (XFS_LINEAR_EXTS - erp->er_extcount)) {
- memmove(&erp->er_extbuf[erp->er_extcount],
- erp_next->er_extbuf, erp_next->er_extcount *
- sizeof(xfs_bmbt_rec_t));
- erp->er_extcount += erp_next->er_extcount;
- /*
- * Free page before removing extent record
- * so er_extoffs don't get modified in
- * xfs_iext_irec_remove.
- */
- kmem_free(erp_next->er_extbuf, XFS_IEXT_BUFSZ);
- erp_next->er_extbuf = NULL;
- xfs_iext_irec_remove(ifp, erp_idx + 1);
- nlists = ifp->if_real_bytes / XFS_IEXT_BUFSZ;
- } else {
- erp_idx++;
- }
- }
-}
-
-/*
- * Fully compact the extent records managed by the indirection array.
- */
-void
-xfs_iext_irec_compact_full(
- xfs_ifork_t *ifp) /* inode fork pointer */
-{
- xfs_bmbt_rec_t *ep, *ep_next; /* extent record pointers */
- xfs_ext_irec_t *erp, *erp_next; /* extent irec pointers */
- int erp_idx = 0; /* extent irec index */
- int ext_avail; /* empty entries in ex list */
- int ext_diff; /* number of exts to add */
- int nlists; /* number of irec's (ex lists) */
-
- ASSERT(ifp->if_flags & XFS_IFEXTIREC);
- nlists = ifp->if_real_bytes / XFS_IEXT_BUFSZ;
- erp = ifp->if_u1.if_ext_irec;
- ep = &erp->er_extbuf[erp->er_extcount];
- erp_next = erp + 1;
- ep_next = erp_next->er_extbuf;
- while (erp_idx < nlists - 1) {
- ext_avail = XFS_LINEAR_EXTS - erp->er_extcount;
- ext_diff = MIN(ext_avail, erp_next->er_extcount);
- memcpy(ep, ep_next, ext_diff * sizeof(xfs_bmbt_rec_t));
- erp->er_extcount += ext_diff;
- erp_next->er_extcount -= ext_diff;
- /* Remove next page */
- if (erp_next->er_extcount == 0) {
- /*
- * Free page before removing extent record
- * so er_extoffs don't get modified in
- * xfs_iext_irec_remove.
- */
- kmem_free(erp_next->er_extbuf,
- erp_next->er_extcount * sizeof(xfs_bmbt_rec_t));
- erp_next->er_extbuf = NULL;
- xfs_iext_irec_remove(ifp, erp_idx + 1);
- erp = &ifp->if_u1.if_ext_irec[erp_idx];
- nlists = ifp->if_real_bytes / XFS_IEXT_BUFSZ;
- /* Update next page */
- } else {
- /* Move rest of page up to become next new page */
- memmove(erp_next->er_extbuf, ep_next,
- erp_next->er_extcount * sizeof(xfs_bmbt_rec_t));
- ep_next = erp_next->er_extbuf;
- memset(&ep_next[erp_next->er_extcount], 0,
- (XFS_LINEAR_EXTS - erp_next->er_extcount) *
- sizeof(xfs_bmbt_rec_t));
- }
- if (erp->er_extcount == XFS_LINEAR_EXTS) {
- erp_idx++;
- if (erp_idx < nlists)
- erp = &ifp->if_u1.if_ext_irec[erp_idx];
- else
- break;
- }
- ep = &erp->er_extbuf[erp->er_extcount];
- erp_next = erp + 1;
- ep_next = erp_next->er_extbuf;
- }
-}
-
-/*
- * This is called to update the er_extoff field in the indirection
- * array when extents have been added or removed from one of the
- * extent lists. erp_idx contains the irec index to begin updating
- * at and ext_diff contains the number of extents that were added
- * or removed.
- */
-void
-xfs_iext_irec_update_extoffs(
- xfs_ifork_t *ifp, /* inode fork pointer */
- int erp_idx, /* irec index to update */
- int ext_diff) /* number of new extents */
-{
- int i; /* loop counter */
- int nlists; /* number of irec's (ex lists */
-
- ASSERT(ifp->if_flags & XFS_IFEXTIREC);
- nlists = ifp->if_real_bytes / XFS_IEXT_BUFSZ;
- for (i = erp_idx; i < nlists; i++) {
- ifp->if_u1.if_ext_irec[i].er_extoff += ext_diff;
- }
-}
diff --git a/sys/gnu/fs/xfs/xfs_inode.h b/sys/gnu/fs/xfs/xfs_inode.h
deleted file mode 100644
index 3b77381..0000000
--- a/sys/gnu/fs/xfs/xfs_inode.h
+++ /dev/null
@@ -1,516 +0,0 @@
-/*
- * Copyright (c) 2000-2003,2005 Silicon Graphics, Inc.
- * All Rights Reserved.
- *
- * 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.
- *
- * This program is distributed in the hope that it would 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 the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- */
-#ifndef __XFS_INODE_H__
-#define __XFS_INODE_H__
-
-/*
- * Fork identifiers.
- */
-#define XFS_DATA_FORK 0
-#define XFS_ATTR_FORK 1
-
-/*
- * The following xfs_ext_irec_t struct introduces a second (top) level
- * to the in-core extent allocation scheme. These structs are allocated
- * in a contiguous block, creating an indirection array where each entry
- * (irec) contains a pointer to a buffer of in-core extent records which
- * it manages. Each extent buffer is 4k in size, since 4k is the system
- * page size on Linux i386 and systems with larger page sizes don't seem
- * to gain much, if anything, by using their native page size as the
- * extent buffer size. Also, using 4k extent buffers everywhere provides
- * a consistent interface for CXFS across different platforms.
- *
- * There is currently no limit on the number of irec's (extent lists)
- * allowed, so heavily fragmented files may require an indirection array
- * which spans multiple system pages of memory. The number of extents
- * which would require this amount of contiguous memory is very large
- * and should not cause problems in the foreseeable future. However,
- * if the memory needed for the contiguous array ever becomes a problem,
- * it is possible that a third level of indirection may be required.
- */
-typedef struct xfs_ext_irec {
- xfs_bmbt_rec_t *er_extbuf; /* block of extent records */
- xfs_extnum_t er_extoff; /* extent offset in file */
- xfs_extnum_t er_extcount; /* number of extents in page/block */
-} xfs_ext_irec_t;
-
-/*
- * File incore extent information, present for each of data & attr forks.
- */
-#define XFS_IEXT_BUFSZ 4096
-#define XFS_LINEAR_EXTS (XFS_IEXT_BUFSZ / (uint)sizeof(xfs_bmbt_rec_t))
-#define XFS_INLINE_EXTS 2
-#define XFS_INLINE_DATA 32
-typedef struct xfs_ifork {
- int if_bytes; /* bytes in if_u1 */
- int if_real_bytes; /* bytes allocated in if_u1 */
- xfs_bmbt_block_t *if_broot; /* file's incore btree root */
- short if_broot_bytes; /* bytes allocated for root */
- unsigned char if_flags; /* per-fork flags */
- unsigned char if_ext_max; /* max # of extent records */
- xfs_extnum_t if_lastex; /* last if_extents used */
- union {
- xfs_bmbt_rec_t *if_extents; /* linear map file exts */
- xfs_ext_irec_t *if_ext_irec; /* irec map file exts */
- char *if_data; /* inline file data */
- } if_u1;
- union {
- xfs_bmbt_rec_t if_inline_ext[XFS_INLINE_EXTS];
- /* very small file extents */
- char if_inline_data[XFS_INLINE_DATA];
- /* very small file data */
- xfs_dev_t if_rdev; /* dev number if special */
- uuid_t if_uuid; /* mount point value */
- } if_u2;
-} xfs_ifork_t;
-
-/*
- * Flags for xfs_ichgtime().
- */
-#define XFS_ICHGTIME_MOD 0x1 /* data fork modification timestamp */
-#define XFS_ICHGTIME_ACC 0x2 /* data fork access timestamp */
-#define XFS_ICHGTIME_CHG 0x4 /* inode field change timestamp */
-
-/*
- * Per-fork incore inode flags.
- */
-#define XFS_IFINLINE 0x01 /* Inline data is read in */
-#define XFS_IFEXTENTS 0x02 /* All extent pointers are read in */
-#define XFS_IFBROOT 0x04 /* i_broot points to the bmap b-tree root */
-#define XFS_IFEXTIREC 0x08 /* Indirection array of extent blocks */
-
-/*
- * Flags for xfs_itobp(), xfs_imap() and xfs_dilocate().
- */
-#define XFS_IMAP_LOOKUP 0x1
-#define XFS_IMAP_BULKSTAT 0x2
-
-#ifdef __KERNEL__
-struct bhv_desc;
-struct cred;
-struct ktrace;
-struct xfs_vnode;
-struct xfs_buf;
-struct xfs_bmap_free;
-struct xfs_bmbt_irec;
-struct xfs_bmbt_block;
-struct xfs_inode;
-struct xfs_inode_log_item;
-struct xfs_mount;
-struct xfs_trans;
-struct xfs_dquot;
-
-#if defined(XFS_ILOCK_TRACE)
-#define XFS_ILOCK_KTRACE_SIZE 32
-extern ktrace_t *xfs_ilock_trace_buf;
-extern void xfs_ilock_trace(struct xfs_inode *, int, unsigned int, inst_t *);
-#else
-#define xfs_ilock_trace(i,n,f,ra)
-#endif
-
-typedef struct dm_attrs_s {
- __uint32_t da_dmevmask; /* DMIG event mask */
- __uint16_t da_dmstate; /* DMIG state info */
- __uint16_t da_pad; /* DMIG extra padding */
-} dm_attrs_t;
-
-typedef struct xfs_iocore {
- void *io_obj; /* pointer to container
- * inode or dcxvn structure */
- struct xfs_mount *io_mount; /* fs mount struct ptr */
-#ifdef DEBUG
- mrlock_t *io_lock; /* inode IO lock */
- mrlock_t *io_iolock; /* inode IO lock */
-#endif
-
- /* I/O state */
- xfs_fsize_t io_new_size; /* sz when write completes */
-
- /* Miscellaneous state. */
- unsigned int io_flags; /* IO related flags */
-
- /* DMAPI state */
- dm_attrs_t io_dmattrs;
-
-} xfs_iocore_t;
-
-#define io_dmevmask io_dmattrs.da_dmevmask
-#define io_dmstate io_dmattrs.da_dmstate
-
-#define XFS_IO_INODE(io) ((xfs_inode_t *) ((io)->io_obj))
-#define XFS_IO_DCXVN(io) ((dcxvn_t *) ((io)->io_obj))
-
-/*
- * Flags in the flags field
- */
-
-#define XFS_IOCORE_RT 0x1
-
-/*
- * xfs_iocore prototypes
- */
-
-extern void xfs_iocore_inode_init(struct xfs_inode *);
-extern void xfs_iocore_inode_reinit(struct xfs_inode *);
-
-
-/*
- * This is the type used in the xfs inode hash table.
- * An array of these is allocated for each mounted
- * file system to hash the inodes for that file system.
- */
-typedef struct xfs_ihash {
- struct xfs_inode *ih_next;
- rwlock_t ih_lock;
- uint ih_version;
-} xfs_ihash_t;
-
-#define XFS_IHASH(mp,ino) ((mp)->m_ihash + (((uint)(ino)) % (mp)->m_ihsize))
-
-/*
- * This is the xfs inode cluster hash. This hash is used by xfs_iflush to
- * find inodes that share a cluster and can be flushed to disk at the same
- * time.
- */
-typedef struct xfs_chashlist {
- struct xfs_chashlist *chl_next;
- struct xfs_chashlist *chl_prev;
- struct xfs_inode *chl_ip;
- xfs_daddr_t chl_blkno; /* starting block number of
- * the cluster */
- struct xfs_buf *chl_buf; /* the inode buffer */
-} xfs_chashlist_t;
-
-typedef struct xfs_chash {
- xfs_chashlist_t *ch_list;
- lock_t ch_lock;
-} xfs_chash_t;
-
-#define XFS_CHASH(mp,blk) ((mp)->m_chash + (((uint)blk) % (mp)->m_chsize))
-
-
-/*
- * This is the xfs in-core inode structure.
- * Most of the on-disk inode is embedded in the i_d field.
- *
- * The extent pointers/inline file space, however, are managed
- * separately. The memory for this information is pointed to by
- * the if_u1 unions depending on the type of the data.
- * This is used to linearize the array of extents for fast in-core
- * access. This is used until the file's number of extents
- * surpasses XFS_MAX_INCORE_EXTENTS, at which point all extent pointers
- * are accessed through the buffer cache.
- *
- * Other state kept in the in-core inode is used for identification,
- * locking, transactional updating, etc of the inode.
- *
- * Generally, we do not want to hold the i_rlock while holding the
- * i_ilock. Hierarchy is i_iolock followed by i_rlock.
- *
- * xfs_iptr_t contains all the inode fields upto and including the
- * i_mnext and i_mprev fields, it is used as a marker in the inode
- * chain off the mount structure by xfs_sync calls.
- */
-
-typedef struct {
- struct xfs_ihash *ip_hash; /* pointer to hash header */
- struct xfs_inode *ip_next; /* inode hash link forw */
- struct xfs_inode *ip_mnext; /* next inode in mount list */
- struct xfs_inode *ip_mprev; /* ptr to prev inode */
- struct xfs_inode **ip_prevp; /* ptr to prev i_next */
- struct xfs_mount *ip_mount; /* fs mount struct ptr */
-} xfs_iptr_t;
-
-typedef struct xfs_inode {
- /* Inode linking and identification information. */
- struct xfs_ihash *i_hash; /* pointer to hash header */
- struct xfs_inode *i_next; /* inode hash link forw */
- struct xfs_inode *i_mnext; /* next inode in mount list */
- struct xfs_inode *i_mprev; /* ptr to prev inode */
- struct xfs_inode **i_prevp; /* ptr to prev i_next */
- struct xfs_mount *i_mount; /* fs mount struct ptr */
- TAILQ_ENTRY(xfs_inode) i_reclaim; /* reclaim list */
- struct bhv_desc i_bhv_desc; /* inode behavior descriptor*/
- struct xfs_dquot *i_udquot; /* user dquot */
- struct xfs_dquot *i_gdquot; /* group dquot */
-
- /* Inode location stuff */
- xfs_ino_t i_ino; /* inode number (agno/agino)*/
- xfs_daddr_t i_blkno; /* blkno of inode buffer */
- ushort i_len; /* len of inode buffer */
- ushort i_boffset; /* off of inode in buffer */
-
- /* Extent information. */
- xfs_ifork_t *i_afp; /* attribute fork pointer */
- xfs_ifork_t i_df; /* data fork */
-
- /* Transaction and locking information. */
- struct xfs_trans *i_transp; /* ptr to owning transaction*/
- struct xfs_inode_log_item *i_itemp; /* logging information */
- mrlock_t i_lock; /* inode lock */
- mrlock_t i_iolock; /* inode IO lock */
- sema_t i_flock; /* inode flush lock */
- atomic_t i_pincount; /* inode pin count */
- wait_queue_head_t i_ipin_wait; /* inode pinning wait queue */
-#ifdef HAVE_REFCACHE
- struct xfs_inode **i_refcache; /* ptr to entry in ref cache */
- struct xfs_inode *i_release; /* inode to unref */
-#endif
- /* I/O state */
- xfs_iocore_t i_iocore; /* I/O core */
-
- /* Miscellaneous state. */
- unsigned short i_flags; /* see defined flags below */
- unsigned char i_update_core; /* timestamps/size is dirty */
- unsigned char i_update_size; /* di_size field is dirty */
- unsigned int i_gen; /* generation count */
- unsigned int i_delayed_blks; /* count of delay alloc blks */
-
- xfs_dinode_core_t i_d; /* most of ondisk inode */
- xfs_chashlist_t *i_chash; /* cluster hash list header */
- struct xfs_inode *i_cnext; /* cluster hash link forward */
- struct xfs_inode *i_cprev; /* cluster hash link backward */
-
- /* Trace buffers per inode. */
-#ifdef XFS_BMAP_TRACE
- struct ktrace *i_xtrace; /* inode extent list trace */
-#endif
-#ifdef XFS_BMBT_TRACE
- struct ktrace *i_btrace; /* inode bmap btree trace */
-#endif
-#ifdef XFS_RW_TRACE
- struct ktrace *i_rwtrace; /* inode read/write trace */
-#endif
-#ifdef XFS_ILOCK_TRACE
- struct ktrace *i_lock_trace; /* inode lock/unlock trace */
-#endif
-#ifdef XFS_DIR2_TRACE
- struct ktrace *i_dir_trace; /* inode directory trace */
-#endif
-} xfs_inode_t;
-
-#endif /* __KERNEL__ */
-
-
-/*
- * Fork handling.
- */
-#define XFS_IFORK_PTR(ip,w) \
- ((w) == XFS_DATA_FORK ? &(ip)->i_df : (ip)->i_afp)
-#define XFS_IFORK_Q(ip) XFS_CFORK_Q(&(ip)->i_d)
-#define XFS_IFORK_DSIZE(ip) XFS_CFORK_DSIZE(&ip->i_d, ip->i_mount)
-#define XFS_IFORK_ASIZE(ip) XFS_CFORK_ASIZE(&ip->i_d, ip->i_mount)
-#define XFS_IFORK_SIZE(ip,w) XFS_CFORK_SIZE(&ip->i_d, ip->i_mount, w)
-#define XFS_IFORK_FORMAT(ip,w) XFS_CFORK_FORMAT(&ip->i_d, w)
-#define XFS_IFORK_FMT_SET(ip,w,n) XFS_CFORK_FMT_SET(&ip->i_d, w, n)
-#define XFS_IFORK_NEXTENTS(ip,w) XFS_CFORK_NEXTENTS(&ip->i_d, w)
-#define XFS_IFORK_NEXT_SET(ip,w,n) XFS_CFORK_NEXT_SET(&ip->i_d, w, n)
-
-
-#ifdef __KERNEL__
-
-/*
- * In-core inode flags.
- */
-#define XFS_IGRIO 0x0001 /* inode used for guaranteed rate i/o */
-#define XFS_IUIOSZ 0x0002 /* inode i/o sizes have been explicitly set */
-#define XFS_IQUIESCE 0x0004 /* we have started quiescing for this inode */
-#define XFS_IRECLAIM 0x0008 /* we have started reclaiming this inode */
-#define XFS_ISTALE 0x0010 /* inode has been staled */
-#define XFS_IRECLAIMABLE 0x0020 /* inode can be reclaimed */
-#define XFS_INEW 0x0040
-
-/*
- * Flags for inode locking.
- */
-#define XFS_IOLOCK_EXCL 0x001
-#define XFS_IOLOCK_SHARED 0x002
-#define XFS_ILOCK_EXCL 0x004
-#define XFS_ILOCK_SHARED 0x008
-#define XFS_IUNLOCK_NONOTIFY 0x010
-/* XFS_IOLOCK_NESTED 0x020 */
-#define XFS_EXTENT_TOKEN_RD 0x040
-#define XFS_SIZE_TOKEN_RD 0x080
-#define XFS_EXTSIZE_RD (XFS_EXTENT_TOKEN_RD|XFS_SIZE_TOKEN_RD)
-#define XFS_WILLLEND 0x100 /* Always acquire tokens for lending */
-#define XFS_EXTENT_TOKEN_WR (XFS_EXTENT_TOKEN_RD | XFS_WILLLEND)
-#define XFS_SIZE_TOKEN_WR (XFS_SIZE_TOKEN_RD | XFS_WILLLEND)
-#define XFS_EXTSIZE_WR (XFS_EXTSIZE_RD | XFS_WILLLEND)
-/* XFS_SIZE_TOKEN_WANT 0x200 */
-
-#define XFS_LOCK_MASK \
- (XFS_IOLOCK_EXCL | XFS_IOLOCK_SHARED | XFS_ILOCK_EXCL | \
- XFS_ILOCK_SHARED | XFS_EXTENT_TOKEN_RD | XFS_SIZE_TOKEN_RD | \
- XFS_WILLLEND)
-
-/*
- * Flags for xfs_iflush()
- */
-#define XFS_IFLUSH_DELWRI_ELSE_SYNC 1
-#define XFS_IFLUSH_DELWRI_ELSE_ASYNC 2
-#define XFS_IFLUSH_SYNC 3
-#define XFS_IFLUSH_ASYNC 4
-#define XFS_IFLUSH_DELWRI 5
-
-/*
- * Flags for xfs_itruncate_start().
- */
-#define XFS_ITRUNC_DEFINITE 0x1
-#define XFS_ITRUNC_MAYBE 0x2
-
-#define XFS_ITOV(ip) BHV_TO_VNODE(XFS_ITOBHV(ip))
-#define XFS_ITOV_NULL(ip) BHV_TO_VNODE_NULL(XFS_ITOBHV(ip))
-#define XFS_ITOBHV(ip) ((struct bhv_desc *)(&((ip)->i_bhv_desc)))
-#define XFS_BHVTOI(bhvp) ((xfs_inode_t *)((char *)(bhvp) - \
- (char *)&(((xfs_inode_t *)0)->i_bhv_desc)))
-#define BHV_IS_XFS(bdp) (BHV_OPS(bdp) == &xfs_vnodeops)
-
-/*
- * For multiple groups support: if S_ISGID bit is set in the parent
- * directory, group of new file is set to that of the parent, and
- * new subdirectory gets S_ISGID bit from parent.
- */
-#define XFS_INHERIT_GID(pip, vfsp) \
- (((vfsp)->vfs_flag & VFS_GRPID) || ((pip)->i_d.di_mode & S_ISGID))
-
-/*
- * xfs_iget.c prototypes.
- */
-
-#define IGET_CREATE 1
-
-void xfs_ihash_init(struct xfs_mount *);
-void xfs_ihash_free(struct xfs_mount *);
-void xfs_chash_init(struct xfs_mount *);
-void xfs_chash_free(struct xfs_mount *);
-xfs_inode_t *xfs_inode_incore(struct xfs_mount *, xfs_ino_t,
- struct xfs_trans *);
-void xfs_inode_lock_init(xfs_inode_t *, struct xfs_vnode *);
-int xfs_iget(struct xfs_mount *, struct xfs_trans *, xfs_ino_t,
- uint, uint, xfs_inode_t **, xfs_daddr_t);
-void xfs_iput(xfs_inode_t *, uint);
-void xfs_iput_new(xfs_inode_t *, uint);
-void xfs_ilock(xfs_inode_t *, uint);
-int xfs_ilock_nowait(xfs_inode_t *, uint);
-void xfs_iunlock(xfs_inode_t *, uint);
-void xfs_ilock_demote(xfs_inode_t *, uint);
-void xfs_iflock(xfs_inode_t *);
-int xfs_iflock_nowait(xfs_inode_t *);
-uint xfs_ilock_map_shared(xfs_inode_t *);
-void xfs_iunlock_map_shared(xfs_inode_t *, uint);
-void xfs_ifunlock(xfs_inode_t *);
-void xfs_ireclaim(xfs_inode_t *);
-int xfs_finish_reclaim(xfs_inode_t *, int, int);
-int xfs_finish_reclaim_all(struct xfs_mount *, int);
-
-/*
- * xfs_inode.c prototypes.
- */
-int xfs_itobp(struct xfs_mount *, struct xfs_trans *,
- xfs_inode_t *, xfs_dinode_t **, struct xfs_buf **,
- xfs_daddr_t, uint);
-int xfs_iread(struct xfs_mount *, struct xfs_trans *, xfs_ino_t,
- xfs_inode_t **, xfs_daddr_t);
-int xfs_iread_extents(struct xfs_trans *, xfs_inode_t *, int);
-int xfs_ialloc(struct xfs_trans *, xfs_inode_t *, mode_t,
- xfs_nlink_t, xfs_dev_t, struct cred *, xfs_prid_t,
- int, struct xfs_buf **, boolean_t *, xfs_inode_t **);
-void xfs_xlate_dinode_core(xfs_caddr_t, struct xfs_dinode_core *,
- int);
-uint xfs_ip2xflags(struct xfs_inode *);
-uint xfs_dic2xflags(struct xfs_dinode_core *);
-int xfs_ifree(struct xfs_trans *, xfs_inode_t *,
- struct xfs_bmap_free *);
-void xfs_itruncate_start(xfs_inode_t *, uint, xfs_fsize_t);
-int xfs_itruncate_finish(struct xfs_trans **, xfs_inode_t *,
- xfs_fsize_t, int, int);
-int xfs_iunlink(struct xfs_trans *, xfs_inode_t *);
-int xfs_igrow_start(xfs_inode_t *, xfs_fsize_t, struct cred *);
-void xfs_igrow_finish(struct xfs_trans *, xfs_inode_t *,
- xfs_fsize_t, int);
-
-void xfs_idestroy_fork(xfs_inode_t *, int);
-void xfs_idestroy(xfs_inode_t *);
-void xfs_idata_realloc(xfs_inode_t *, int, int);
-void xfs_iextract(xfs_inode_t *);
-void xfs_iext_realloc(xfs_inode_t *, int, int);
-void xfs_iroot_realloc(xfs_inode_t *, int, int);
-void xfs_ipin(xfs_inode_t *);
-void xfs_iunpin(xfs_inode_t *);
-int xfs_iextents_copy(xfs_inode_t *, xfs_bmbt_rec_t *, int);
-int xfs_iflush(xfs_inode_t *, uint);
-void xfs_iflush_all(struct xfs_mount *);
-int xfs_iaccess(xfs_inode_t *, accmode_t, cred_t *);
-uint xfs_iroundup(uint);
-void xfs_ichgtime(xfs_inode_t *, int);
-xfs_fsize_t xfs_file_last_byte(xfs_inode_t *);
-void xfs_lock_inodes(xfs_inode_t **, int, int, uint);
-
-xfs_inode_t *xfs_vtoi(struct xfs_vnode *vp);
-
-void xfs_synchronize_atime(xfs_inode_t *);
-
-xfs_bmbt_rec_t *xfs_iext_get_ext(xfs_ifork_t *, xfs_extnum_t);
-void xfs_iext_insert(xfs_ifork_t *, xfs_extnum_t, xfs_extnum_t,
- xfs_bmbt_irec_t *);
-void xfs_iext_add(xfs_ifork_t *, xfs_extnum_t, int);
-void xfs_iext_add_indirect_multi(xfs_ifork_t *, int, xfs_extnum_t, int);
-void xfs_iext_remove(xfs_ifork_t *, xfs_extnum_t, int);
-void xfs_iext_remove_inline(xfs_ifork_t *, xfs_extnum_t, int);
-void xfs_iext_remove_direct(xfs_ifork_t *, xfs_extnum_t, int);
-void xfs_iext_remove_indirect(xfs_ifork_t *, xfs_extnum_t, int);
-void xfs_iext_realloc_direct(xfs_ifork_t *, int);
-void xfs_iext_realloc_indirect(xfs_ifork_t *, int);
-void xfs_iext_indirect_to_direct(xfs_ifork_t *);
-void xfs_iext_direct_to_inline(xfs_ifork_t *, xfs_extnum_t);
-void xfs_iext_inline_to_direct(xfs_ifork_t *, int);
-void xfs_iext_destroy(xfs_ifork_t *);
-xfs_bmbt_rec_t *xfs_iext_bno_to_ext(xfs_ifork_t *, xfs_fileoff_t, int *);
-xfs_ext_irec_t *xfs_iext_bno_to_irec(xfs_ifork_t *, xfs_fileoff_t, int *);
-xfs_ext_irec_t *xfs_iext_idx_to_irec(xfs_ifork_t *, xfs_extnum_t *, int *, int);
-void xfs_iext_irec_init(xfs_ifork_t *);
-xfs_ext_irec_t *xfs_iext_irec_new(xfs_ifork_t *, int);
-void xfs_iext_irec_remove(xfs_ifork_t *, int);
-void xfs_iext_irec_compact(xfs_ifork_t *);
-void xfs_iext_irec_compact_pages(xfs_ifork_t *);
-void xfs_iext_irec_compact_full(xfs_ifork_t *);
-void xfs_iext_irec_update_extoffs(xfs_ifork_t *, int, int);
-
-#define xfs_ipincount(ip) ((unsigned int) atomic_read(&ip->i_pincount))
-
-#ifdef DEBUG
-void xfs_isize_check(struct xfs_mount *, xfs_inode_t *, xfs_fsize_t);
-#else /* DEBUG */
-#define xfs_isize_check(mp, ip, isize)
-#endif /* DEBUG */
-
-#if defined(DEBUG)
-void xfs_inobp_check(struct xfs_mount *, struct xfs_buf *);
-#else
-#define xfs_inobp_check(mp, bp)
-#endif /* DEBUG */
-
-extern struct kmem_zone *xfs_chashlist_zone;
-extern struct kmem_zone *xfs_ifork_zone;
-extern struct kmem_zone *xfs_inode_zone;
-extern struct kmem_zone *xfs_ili_zone;
-
-#endif /* __KERNEL__ */
-
-#endif /* __XFS_INODE_H__ */
-
diff --git a/sys/gnu/fs/xfs/xfs_inode_item.c b/sys/gnu/fs/xfs/xfs_inode_item.c
deleted file mode 100644
index 7497a48..0000000
--- a/sys/gnu/fs/xfs/xfs_inode_item.c
+++ /dev/null
@@ -1,1086 +0,0 @@
-/*
- * Copyright (c) 2000-2002,2005 Silicon Graphics, Inc.
- * All Rights Reserved.
- *
- * 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.
- *
- * This program is distributed in the hope that it would 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 the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- */
-#include "xfs.h"
-#include "xfs_fs.h"
-#include "xfs_types.h"
-#include "xfs_bit.h"
-#include "xfs_log.h"
-#include "xfs_inum.h"
-#include "xfs_trans.h"
-#include "xfs_buf_item.h"
-#include "xfs_sb.h"
-#include "xfs_ag.h"
-#include "xfs_dir.h"
-#include "xfs_dir2.h"
-#include "xfs_dmapi.h"
-#include "xfs_mount.h"
-#include "xfs_trans_priv.h"
-#include "xfs_bmap_btree.h"
-#include "xfs_alloc_btree.h"
-#include "xfs_ialloc_btree.h"
-#include "xfs_dir_sf.h"
-#include "xfs_dir2_sf.h"
-#include "xfs_attr_sf.h"
-#include "xfs_dinode.h"
-#include "xfs_inode.h"
-#include "xfs_inode_item.h"
-#include "xfs_btree.h"
-#include "xfs_ialloc.h"
-#include "xfs_rw.h"
-
-
-kmem_zone_t *xfs_ili_zone; /* inode log item zone */
-
-/*
- * This returns the number of iovecs needed to log the given inode item.
- *
- * We need one iovec for the inode log format structure, one for the
- * inode core, and possibly one for the inode data/extents/b-tree root
- * and one for the inode attribute data/extents/b-tree root.
- */
-STATIC uint
-xfs_inode_item_size(
- xfs_inode_log_item_t *iip)
-{
- uint nvecs;
- xfs_inode_t *ip;
-
- ip = iip->ili_inode;
- nvecs = 2;
-
- /*
- * Only log the data/extents/b-tree root if there is something
- * left to log.
- */
- iip->ili_format.ilf_fields |= XFS_ILOG_CORE;
-
- switch (ip->i_d.di_format) {
- case XFS_DINODE_FMT_EXTENTS:
- iip->ili_format.ilf_fields &=
- ~(XFS_ILOG_DDATA | XFS_ILOG_DBROOT |
- XFS_ILOG_DEV | XFS_ILOG_UUID);
- if ((iip->ili_format.ilf_fields & XFS_ILOG_DEXT) &&
- (ip->i_d.di_nextents > 0) &&
- (ip->i_df.if_bytes > 0)) {
- ASSERT(ip->i_df.if_u1.if_extents != NULL);
- nvecs++;
- } else {
- iip->ili_format.ilf_fields &= ~XFS_ILOG_DEXT;
- }
- break;
-
- case XFS_DINODE_FMT_BTREE:
- ASSERT(ip->i_df.if_ext_max ==
- XFS_IFORK_DSIZE(ip) / (uint)sizeof(xfs_bmbt_rec_t));
- iip->ili_format.ilf_fields &=
- ~(XFS_ILOG_DDATA | XFS_ILOG_DEXT |
- XFS_ILOG_DEV | XFS_ILOG_UUID);
- if ((iip->ili_format.ilf_fields & XFS_ILOG_DBROOT) &&
- (ip->i_df.if_broot_bytes > 0)) {
- ASSERT(ip->i_df.if_broot != NULL);
- nvecs++;
- } else {
- ASSERT(!(iip->ili_format.ilf_fields &
- XFS_ILOG_DBROOT));
-#ifdef XFS_TRANS_DEBUG
- if (iip->ili_root_size > 0) {
- ASSERT(iip->ili_root_size ==
- ip->i_df.if_broot_bytes);
- ASSERT(memcmp(iip->ili_orig_root,
- ip->i_df.if_broot,
- iip->ili_root_size) == 0);
- } else {
- ASSERT(ip->i_df.if_broot_bytes == 0);
- }
-#endif
- iip->ili_format.ilf_fields &= ~XFS_ILOG_DBROOT;
- }
- break;
-
- case XFS_DINODE_FMT_LOCAL:
- iip->ili_format.ilf_fields &=
- ~(XFS_ILOG_DEXT | XFS_ILOG_DBROOT |
- XFS_ILOG_DEV | XFS_ILOG_UUID);
- if ((iip->ili_format.ilf_fields & XFS_ILOG_DDATA) &&
- (ip->i_df.if_bytes > 0)) {
- ASSERT(ip->i_df.if_u1.if_data != NULL);
- ASSERT(ip->i_d.di_size > 0);
- nvecs++;
- } else {
- iip->ili_format.ilf_fields &= ~XFS_ILOG_DDATA;
- }
- break;
-
- case XFS_DINODE_FMT_DEV:
- iip->ili_format.ilf_fields &=
- ~(XFS_ILOG_DDATA | XFS_ILOG_DBROOT |
- XFS_ILOG_DEXT | XFS_ILOG_UUID);
- break;
-
- case XFS_DINODE_FMT_UUID:
- iip->ili_format.ilf_fields &=
- ~(XFS_ILOG_DDATA | XFS_ILOG_DBROOT |
- XFS_ILOG_DEXT | XFS_ILOG_DEV);
- break;
-
- default:
- ASSERT(0);
- break;
- }
-
- /*
- * If there are no attributes associated with this file,
- * then there cannot be anything more to log.
- * Clear all attribute-related log flags.
- */
- if (!XFS_IFORK_Q(ip)) {
- iip->ili_format.ilf_fields &=
- ~(XFS_ILOG_ADATA | XFS_ILOG_ABROOT | XFS_ILOG_AEXT);
- return nvecs;
- }
-
- /*
- * Log any necessary attribute data.
- */
- switch (ip->i_d.di_aformat) {
- case XFS_DINODE_FMT_EXTENTS:
- iip->ili_format.ilf_fields &=
- ~(XFS_ILOG_ADATA | XFS_ILOG_ABROOT);
- if ((iip->ili_format.ilf_fields & XFS_ILOG_AEXT) &&
- (ip->i_d.di_anextents > 0) &&
- (ip->i_afp->if_bytes > 0)) {
- ASSERT(ip->i_afp->if_u1.if_extents != NULL);
- nvecs++;
- } else {
- iip->ili_format.ilf_fields &= ~XFS_ILOG_AEXT;
- }
- break;
-
- case XFS_DINODE_FMT_BTREE:
- iip->ili_format.ilf_fields &=
- ~(XFS_ILOG_ADATA | XFS_ILOG_AEXT);
- if ((iip->ili_format.ilf_fields & XFS_ILOG_ABROOT) &&
- (ip->i_afp->if_broot_bytes > 0)) {
- ASSERT(ip->i_afp->if_broot != NULL);
- nvecs++;
- } else {
- iip->ili_format.ilf_fields &= ~XFS_ILOG_ABROOT;
- }
- break;
-
- case XFS_DINODE_FMT_LOCAL:
- iip->ili_format.ilf_fields &=
- ~(XFS_ILOG_AEXT | XFS_ILOG_ABROOT);
- if ((iip->ili_format.ilf_fields & XFS_ILOG_ADATA) &&
- (ip->i_afp->if_bytes > 0)) {
- ASSERT(ip->i_afp->if_u1.if_data != NULL);
- nvecs++;
- } else {
- iip->ili_format.ilf_fields &= ~XFS_ILOG_ADATA;
- }
- break;
-
- default:
- ASSERT(0);
- break;
- }
-
- return nvecs;
-}
-
-/*
- * This is called to fill in the vector of log iovecs for the
- * given inode log item. It fills the first item with an inode
- * log format structure, the second with the on-disk inode structure,
- * and a possible third and/or fourth with the inode data/extents/b-tree
- * root and inode attributes data/extents/b-tree root.
- */
-STATIC void
-xfs_inode_item_format(
- xfs_inode_log_item_t *iip,
- xfs_log_iovec_t *log_vector)
-{
- uint nvecs;
- xfs_log_iovec_t *vecp;
- xfs_inode_t *ip;
- size_t data_bytes;
- xfs_bmbt_rec_t *ext_buffer;
- int nrecs;
- xfs_mount_t *mp;
-
- ip = iip->ili_inode;
- vecp = log_vector;
-
- vecp->i_addr = (xfs_caddr_t)&iip->ili_format;
- vecp->i_len = sizeof(xfs_inode_log_format_t);
- XLOG_VEC_SET_TYPE(vecp, XLOG_REG_TYPE_IFORMAT);
- vecp++;
- nvecs = 1;
-
- /*
- * Clear i_update_core if the timestamps (or any other
- * non-transactional modification) need flushing/logging
- * and we're about to log them with the rest of the core.
- *
- * This is the same logic as xfs_iflush() but this code can't
- * run at the same time as xfs_iflush because we're in commit
- * processing here and so we have the inode lock held in
- * exclusive mode. Although it doesn't really matter
- * for the timestamps if both routines were to grab the
- * timestamps or not. That would be ok.
- *
- * We clear i_update_core before copying out the data.
- * This is for coordination with our timestamp updates
- * that don't hold the inode lock. They will always
- * update the timestamps BEFORE setting i_update_core,
- * so if we clear i_update_core after they set it we
- * are guaranteed to see their updates to the timestamps
- * either here. Likewise, if they set it after we clear it
- * here, we'll see it either on the next commit of this
- * inode or the next time the inode gets flushed via
- * xfs_iflush(). This depends on strongly ordered memory
- * semantics, but we have that. We use the SYNCHRONIZE
- * macro to make sure that the compiler does not reorder
- * the i_update_core access below the data copy below.
- */
- if (ip->i_update_core) {
- ip->i_update_core = 0;
- SYNCHRONIZE();
- }
-
- /*
- * We don't have to worry about re-ordering here because
- * the update_size field is protected by the inode lock
- * and we have that held in exclusive mode.
- */
- if (ip->i_update_size)
- ip->i_update_size = 0;
-
- /*
- * Make sure to get the latest atime from the Linux inode.
- */
- xfs_synchronize_atime(ip);
-
- vecp->i_addr = (xfs_caddr_t)&ip->i_d;
- vecp->i_len = sizeof(xfs_dinode_core_t);
- XLOG_VEC_SET_TYPE(vecp, XLOG_REG_TYPE_ICORE);
- vecp++;
- nvecs++;
- iip->ili_format.ilf_fields |= XFS_ILOG_CORE;
-
- /*
- * If this is really an old format inode, then we need to
- * log it as such. This means that we have to copy the link
- * count from the new field to the old. We don't have to worry
- * about the new fields, because nothing trusts them as long as
- * the old inode version number is there. If the superblock already
- * has a new version number, then we don't bother converting back.
- */
- mp = ip->i_mount;
- ASSERT(ip->i_d.di_version == XFS_DINODE_VERSION_1 ||
- XFS_SB_VERSION_HASNLINK(&mp->m_sb));
- if (ip->i_d.di_version == XFS_DINODE_VERSION_1) {
- if (!XFS_SB_VERSION_HASNLINK(&mp->m_sb)) {
- /*
- * Convert it back.
- */
- ASSERT(ip->i_d.di_nlink <= XFS_MAXLINK_1);
- ip->i_d.di_onlink = ip->i_d.di_nlink;
- } else {
- /*
- * The superblock version has already been bumped,
- * so just make the conversion to the new inode
- * format permanent.
- */
- ip->i_d.di_version = XFS_DINODE_VERSION_2;
- ip->i_d.di_onlink = 0;
- memset(&(ip->i_d.di_pad[0]), 0, sizeof(ip->i_d.di_pad));
- }
- }
-
- switch (ip->i_d.di_format) {
- case XFS_DINODE_FMT_EXTENTS:
- ASSERT(!(iip->ili_format.ilf_fields &
- (XFS_ILOG_DDATA | XFS_ILOG_DBROOT |
- XFS_ILOG_DEV | XFS_ILOG_UUID)));
- if (iip->ili_format.ilf_fields & XFS_ILOG_DEXT) {
- ASSERT(ip->i_df.if_bytes > 0);
- ASSERT(ip->i_df.if_u1.if_extents != NULL);
- ASSERT(ip->i_d.di_nextents > 0);
- ASSERT(iip->ili_extents_buf == NULL);
- nrecs = ip->i_df.if_bytes /
- (uint)sizeof(xfs_bmbt_rec_t);
- ASSERT(nrecs > 0);
-#ifdef XFS_NATIVE_HOST
- if (nrecs == ip->i_d.di_nextents) {
- /*
- * There are no delayed allocation
- * extents, so just point to the
- * real extents array.
- */
- vecp->i_addr =
- (char *)(ip->i_df.if_u1.if_extents);
- vecp->i_len = ip->i_df.if_bytes;
- XLOG_VEC_SET_TYPE(vecp, XLOG_REG_TYPE_IEXT);
- } else
-#endif
- {
- /*
- * There are delayed allocation extents
- * in the inode, or we need to convert
- * the extents to on disk format.
- * Use xfs_iextents_copy()
- * to copy only the real extents into
- * a separate buffer. We'll free the
- * buffer in the unlock routine.
- */
- ext_buffer = kmem_alloc(ip->i_df.if_bytes,
- KM_SLEEP);
- iip->ili_extents_buf = ext_buffer;
- vecp->i_addr = (xfs_caddr_t)ext_buffer;
- vecp->i_len = xfs_iextents_copy(ip, ext_buffer,
- XFS_DATA_FORK);
- XLOG_VEC_SET_TYPE(vecp, XLOG_REG_TYPE_IEXT);
- }
- ASSERT(vecp->i_len <= ip->i_df.if_bytes);
- iip->ili_format.ilf_dsize = vecp->i_len;
- vecp++;
- nvecs++;
- }
- break;
-
- case XFS_DINODE_FMT_BTREE:
- ASSERT(!(iip->ili_format.ilf_fields &
- (XFS_ILOG_DDATA | XFS_ILOG_DEXT |
- XFS_ILOG_DEV | XFS_ILOG_UUID)));
- if (iip->ili_format.ilf_fields & XFS_ILOG_DBROOT) {
- ASSERT(ip->i_df.if_broot_bytes > 0);
- ASSERT(ip->i_df.if_broot != NULL);
- vecp->i_addr = (xfs_caddr_t)ip->i_df.if_broot;
- vecp->i_len = ip->i_df.if_broot_bytes;
- XLOG_VEC_SET_TYPE(vecp, XLOG_REG_TYPE_IBROOT);
- vecp++;
- nvecs++;
- iip->ili_format.ilf_dsize = ip->i_df.if_broot_bytes;
- }
- break;
-
- case XFS_DINODE_FMT_LOCAL:
- ASSERT(!(iip->ili_format.ilf_fields &
- (XFS_ILOG_DBROOT | XFS_ILOG_DEXT |
- XFS_ILOG_DEV | XFS_ILOG_UUID)));
- if (iip->ili_format.ilf_fields & XFS_ILOG_DDATA) {
- ASSERT(ip->i_df.if_bytes > 0);
- ASSERT(ip->i_df.if_u1.if_data != NULL);
- ASSERT(ip->i_d.di_size > 0);
-
- vecp->i_addr = (xfs_caddr_t)ip->i_df.if_u1.if_data;
- /*
- * Round i_bytes up to a word boundary.
- * The underlying memory is guaranteed to
- * to be there by xfs_idata_realloc().
- */
- data_bytes = roundup(ip->i_df.if_bytes, 4);
- ASSERT((ip->i_df.if_real_bytes == 0) ||
- (ip->i_df.if_real_bytes == data_bytes));
- vecp->i_len = (int)data_bytes;
- XLOG_VEC_SET_TYPE(vecp, XLOG_REG_TYPE_ILOCAL);
- vecp++;
- nvecs++;
- iip->ili_format.ilf_dsize = (unsigned)data_bytes;
- }
- break;
-
- case XFS_DINODE_FMT_DEV:
- ASSERT(!(iip->ili_format.ilf_fields &
- (XFS_ILOG_DBROOT | XFS_ILOG_DEXT |
- XFS_ILOG_DDATA | XFS_ILOG_UUID)));
- if (iip->ili_format.ilf_fields & XFS_ILOG_DEV) {
- iip->ili_format.ilf_u.ilfu_rdev =
- ip->i_df.if_u2.if_rdev;
- }
- break;
-
- case XFS_DINODE_FMT_UUID:
- ASSERT(!(iip->ili_format.ilf_fields &
- (XFS_ILOG_DBROOT | XFS_ILOG_DEXT |
- XFS_ILOG_DDATA | XFS_ILOG_DEV)));
- if (iip->ili_format.ilf_fields & XFS_ILOG_UUID) {
- iip->ili_format.ilf_u.ilfu_uuid =
- ip->i_df.if_u2.if_uuid;
- }
- break;
-
- default:
- ASSERT(0);
- break;
- }
-
- /*
- * If there are no attributes associated with the file,
- * then we're done.
- * Assert that no attribute-related log flags are set.
- */
- if (!XFS_IFORK_Q(ip)) {
- ASSERT(nvecs == iip->ili_item.li_desc->lid_size);
- iip->ili_format.ilf_size = nvecs;
- ASSERT(!(iip->ili_format.ilf_fields &
- (XFS_ILOG_ADATA | XFS_ILOG_ABROOT | XFS_ILOG_AEXT)));
- return;
- }
-
- switch (ip->i_d.di_aformat) {
- case XFS_DINODE_FMT_EXTENTS:
- ASSERT(!(iip->ili_format.ilf_fields &
- (XFS_ILOG_ADATA | XFS_ILOG_ABROOT)));
- if (iip->ili_format.ilf_fields & XFS_ILOG_AEXT) {
- ASSERT(ip->i_afp->if_bytes > 0);
- ASSERT(ip->i_afp->if_u1.if_extents != NULL);
- ASSERT(ip->i_d.di_anextents > 0);
-#ifdef DEBUG
- nrecs = ip->i_afp->if_bytes /
- (uint)sizeof(xfs_bmbt_rec_t);
-#endif
- ASSERT(nrecs > 0);
- ASSERT(nrecs == ip->i_d.di_anextents);
-#ifdef XFS_NATIVE_HOST
- /*
- * There are not delayed allocation extents
- * for attributes, so just point at the array.
- */
- vecp->i_addr = (char *)(ip->i_afp->if_u1.if_extents);
- vecp->i_len = ip->i_afp->if_bytes;
-#else
- ASSERT(iip->ili_aextents_buf == NULL);
- /*
- * Need to endian flip before logging
- */
- ext_buffer = kmem_alloc(ip->i_afp->if_bytes,
- KM_SLEEP);
- iip->ili_aextents_buf = ext_buffer;
- vecp->i_addr = (xfs_caddr_t)ext_buffer;
- vecp->i_len = xfs_iextents_copy(ip, ext_buffer,
- XFS_ATTR_FORK);
-#endif
- XLOG_VEC_SET_TYPE(vecp, XLOG_REG_TYPE_IATTR_EXT);
- iip->ili_format.ilf_asize = vecp->i_len;
- vecp++;
- nvecs++;
- }
- break;
-
- case XFS_DINODE_FMT_BTREE:
- ASSERT(!(iip->ili_format.ilf_fields &
- (XFS_ILOG_ADATA | XFS_ILOG_AEXT)));
- if (iip->ili_format.ilf_fields & XFS_ILOG_ABROOT) {
- ASSERT(ip->i_afp->if_broot_bytes > 0);
- ASSERT(ip->i_afp->if_broot != NULL);
- vecp->i_addr = (xfs_caddr_t)ip->i_afp->if_broot;
- vecp->i_len = ip->i_afp->if_broot_bytes;
- XLOG_VEC_SET_TYPE(vecp, XLOG_REG_TYPE_IATTR_BROOT);
- vecp++;
- nvecs++;
- iip->ili_format.ilf_asize = ip->i_afp->if_broot_bytes;
- }
- break;
-
- case XFS_DINODE_FMT_LOCAL:
- ASSERT(!(iip->ili_format.ilf_fields &
- (XFS_ILOG_ABROOT | XFS_ILOG_AEXT)));
- if (iip->ili_format.ilf_fields & XFS_ILOG_ADATA) {
- ASSERT(ip->i_afp->if_bytes > 0);
- ASSERT(ip->i_afp->if_u1.if_data != NULL);
-
- vecp->i_addr = (xfs_caddr_t)ip->i_afp->if_u1.if_data;
- /*
- * Round i_bytes up to a word boundary.
- * The underlying memory is guaranteed to
- * to be there by xfs_idata_realloc().
- */
- data_bytes = roundup(ip->i_afp->if_bytes, 4);
- ASSERT((ip->i_afp->if_real_bytes == 0) ||
- (ip->i_afp->if_real_bytes == data_bytes));
- vecp->i_len = (int)data_bytes;
- XLOG_VEC_SET_TYPE(vecp, XLOG_REG_TYPE_IATTR_LOCAL);
- vecp++;
- nvecs++;
- iip->ili_format.ilf_asize = (unsigned)data_bytes;
- }
- break;
-
- default:
- ASSERT(0);
- break;
- }
-
- ASSERT(nvecs == iip->ili_item.li_desc->lid_size);
- iip->ili_format.ilf_size = nvecs;
-}
-
-
-/*
- * This is called to pin the inode associated with the inode log
- * item in memory so it cannot be written out. Do this by calling
- * xfs_ipin() to bump the pin count in the inode while holding the
- * inode pin lock.
- */
-STATIC void
-xfs_inode_item_pin(
- xfs_inode_log_item_t *iip)
-{
- ASSERT(ismrlocked(&(iip->ili_inode->i_lock), MR_UPDATE));
- xfs_ipin(iip->ili_inode);
-}
-
-
-/*
- * This is called to unpin the inode associated with the inode log
- * item which was previously pinned with a call to xfs_inode_item_pin().
- * Just call xfs_iunpin() on the inode to do this.
- */
-/* ARGSUSED */
-STATIC void
-xfs_inode_item_unpin(
- xfs_inode_log_item_t *iip,
- int stale)
-{
- xfs_iunpin(iip->ili_inode);
-}
-
-/* ARGSUSED */
-STATIC void
-xfs_inode_item_unpin_remove(
- xfs_inode_log_item_t *iip,
- xfs_trans_t *tp)
-{
- xfs_iunpin(iip->ili_inode);
-}
-
-/*
- * This is called to attempt to lock the inode associated with this
- * inode log item, in preparation for the push routine which does the actual
- * iflush. Don't sleep on the inode lock or the flush lock.
- *
- * If the flush lock is already held, indicating that the inode has
- * been or is in the process of being flushed, then (ideally) we'd like to
- * see if the inode's buffer is still incore, and if so give it a nudge.
- * We delay doing so until the pushbuf routine, though, to avoid holding
- * the AIL lock across a call to the blackhole which is the buffer cache.
- * Also we don't want to sleep in any device strategy routines, which can happen
- * if we do the subsequent bawrite in here.
- */
-STATIC uint
-xfs_inode_item_trylock(
- xfs_inode_log_item_t *iip)
-{
- register xfs_inode_t *ip;
-
- ip = iip->ili_inode;
-
- if (xfs_ipincount(ip) > 0) {
- return XFS_ITEM_PINNED;
- }
-
- if (!xfs_ilock_nowait(ip, XFS_ILOCK_SHARED)) {
- return XFS_ITEM_LOCKED;
- }
-
- if (!xfs_iflock_nowait(ip)) {
- /*
- * If someone else isn't already trying to push the inode
- * buffer, we get to do it.
- */
- if (iip->ili_pushbuf_flag == 0) {
- iip->ili_pushbuf_flag = 1;
-#ifdef DEBUG
- iip->ili_push_owner = current_pid();
-#endif
- /*
- * Inode is left locked in shared mode.
- * Pushbuf routine gets to unlock it.
- */
- return XFS_ITEM_PUSHBUF;
- } else {
- /*
- * We hold the AIL_LOCK, so we must specify the
- * NONOTIFY flag so that we won't double trip.
- */
- xfs_iunlock(ip, XFS_ILOCK_SHARED|XFS_IUNLOCK_NONOTIFY);
- return XFS_ITEM_FLUSHING;
- }
- /* NOTREACHED */
- }
-
- /* Stale items should force out the iclog */
- if (ip->i_flags & XFS_ISTALE) {
- xfs_ifunlock(ip);
- xfs_iunlock(ip, XFS_ILOCK_SHARED|XFS_IUNLOCK_NONOTIFY);
- return XFS_ITEM_PINNED;
- }
-
-#ifdef DEBUG
- if (!XFS_FORCED_SHUTDOWN(ip->i_mount)) {
- ASSERT(iip->ili_format.ilf_fields != 0);
- ASSERT(iip->ili_logged == 0);
- ASSERT(iip->ili_item.li_flags & XFS_LI_IN_AIL);
- }
-#endif
- return XFS_ITEM_SUCCESS;
-}
-
-/*
- * Unlock the inode associated with the inode log item.
- * Clear the fields of the inode and inode log item that
- * are specific to the current transaction. If the
- * hold flags is set, do not unlock the inode.
- */
-STATIC void
-xfs_inode_item_unlock(
- xfs_inode_log_item_t *iip)
-{
- uint hold;
- uint iolocked;
- uint lock_flags;
- xfs_inode_t *ip;
-
- ASSERT(iip != NULL);
- ASSERT(iip->ili_inode->i_itemp != NULL);
- ASSERT(ismrlocked(&(iip->ili_inode->i_lock), MR_UPDATE));
- ASSERT((!(iip->ili_inode->i_itemp->ili_flags &
- XFS_ILI_IOLOCKED_EXCL)) ||
- ismrlocked(&(iip->ili_inode->i_iolock), MR_UPDATE));
- ASSERT((!(iip->ili_inode->i_itemp->ili_flags &
- XFS_ILI_IOLOCKED_SHARED)) ||
- ismrlocked(&(iip->ili_inode->i_iolock), MR_ACCESS));
- /*
- * Clear the transaction pointer in the inode.
- */
- ip = iip->ili_inode;
- ip->i_transp = NULL;
-
- /*
- * If the inode needed a separate buffer with which to log
- * its extents, then free it now.
- */
- if (iip->ili_extents_buf != NULL) {
- ASSERT(ip->i_d.di_format == XFS_DINODE_FMT_EXTENTS);
- ASSERT(ip->i_d.di_nextents > 0);
- ASSERT(iip->ili_format.ilf_fields & XFS_ILOG_DEXT);
- ASSERT(ip->i_df.if_bytes > 0);
- kmem_free(iip->ili_extents_buf, ip->i_df.if_bytes);
- iip->ili_extents_buf = NULL;
- }
- if (iip->ili_aextents_buf != NULL) {
- ASSERT(ip->i_d.di_aformat == XFS_DINODE_FMT_EXTENTS);
- ASSERT(ip->i_d.di_anextents > 0);
- ASSERT(iip->ili_format.ilf_fields & XFS_ILOG_AEXT);
- ASSERT(ip->i_afp->if_bytes > 0);
- kmem_free(iip->ili_aextents_buf, ip->i_afp->if_bytes);
- iip->ili_aextents_buf = NULL;
- }
-
- /*
- * Figure out if we should unlock the inode or not.
- */
- hold = iip->ili_flags & XFS_ILI_HOLD;
-
- /*
- * Before clearing out the flags, remember whether we
- * are holding the inode's IO lock.
- */
- iolocked = iip->ili_flags & XFS_ILI_IOLOCKED_ANY;
-
- /*
- * Clear out the fields of the inode log item particular
- * to the current transaction.
- */
- iip->ili_ilock_recur = 0;
- iip->ili_iolock_recur = 0;
- iip->ili_flags = 0;
-
- /*
- * Unlock the inode if XFS_ILI_HOLD was not set.
- */
- if (!hold) {
- lock_flags = XFS_ILOCK_EXCL;
- if (iolocked & XFS_ILI_IOLOCKED_EXCL) {
- lock_flags |= XFS_IOLOCK_EXCL;
- } else if (iolocked & XFS_ILI_IOLOCKED_SHARED) {
- lock_flags |= XFS_IOLOCK_SHARED;
- }
- xfs_iput(iip->ili_inode, lock_flags);
- }
-}
-
-/*
- * This is called to find out where the oldest active copy of the
- * inode log item in the on disk log resides now that the last log
- * write of it completed at the given lsn. Since we always re-log
- * all dirty data in an inode, the latest copy in the on disk log
- * is the only one that matters. Therefore, simply return the
- * given lsn.
- */
-/*ARGSUSED*/
-STATIC xfs_lsn_t
-xfs_inode_item_committed(
- xfs_inode_log_item_t *iip,
- xfs_lsn_t lsn)
-{
- return (lsn);
-}
-
-/*
- * The transaction with the inode locked has aborted. The inode
- * must not be dirty within the transaction (unless we're forcibly
- * shutting down). We simply unlock just as if the transaction
- * had been cancelled.
- */
-STATIC void
-xfs_inode_item_abort(
- xfs_inode_log_item_t *iip)
-{
- xfs_inode_item_unlock(iip);
- return;
-}
-
-
-/*
- * This gets called by xfs_trans_push_ail(), when IOP_TRYLOCK
- * failed to get the inode flush lock but did get the inode locked SHARED.
- * Here we're trying to see if the inode buffer is incore, and if so whether it's
- * marked delayed write. If that's the case, we'll initiate a bawrite on that
- * buffer to expedite the process.
- *
- * We aren't holding the AIL_LOCK (or the flush lock) when this gets called,
- * so it is inherently race-y.
- */
-STATIC void
-xfs_inode_item_pushbuf(
- xfs_inode_log_item_t *iip)
-{
- xfs_inode_t *ip;
- xfs_mount_t *mp;
- xfs_buf_t *bp;
- uint dopush;
-
- ip = iip->ili_inode;
-
- ASSERT(ismrlocked(&(ip->i_lock), MR_ACCESS));
-
- /*
- * The ili_pushbuf_flag keeps others from
- * trying to duplicate our effort.
- */
- ASSERT(iip->ili_pushbuf_flag != 0);
- ASSERT(iip->ili_push_owner == current_pid());
-
- /*
- * If flushlock isn't locked anymore, chances are that the
- * inode flush completed and the inode was taken off the AIL.
- * So, just get out.
- */
- if ((valusema(&(ip->i_flock)) > 0) ||
- ((iip->ili_item.li_flags & XFS_LI_IN_AIL) == 0)) {
- iip->ili_pushbuf_flag = 0;
- xfs_iunlock(ip, XFS_ILOCK_SHARED);
- return;
- }
-
- mp = ip->i_mount;
- bp = xfs_incore(mp->m_ddev_targp, iip->ili_format.ilf_blkno,
- iip->ili_format.ilf_len, XFS_INCORE_TRYLOCK);
-
- if (bp != NULL) {
- if (XFS_BUF_ISDELAYWRITE(bp)) {
- /*
- * We were racing with iflush because we don't hold
- * the AIL_LOCK or the flush lock. However, at this point,
- * we have the buffer, and we know that it's dirty.
- * So, it's possible that iflush raced with us, and
- * this item is already taken off the AIL.
- * If not, we can flush it async.
- */
- dopush = ((iip->ili_item.li_flags & XFS_LI_IN_AIL) &&
- (valusema(&(ip->i_flock)) <= 0));
- iip->ili_pushbuf_flag = 0;
- xfs_iunlock(ip, XFS_ILOCK_SHARED);
- xfs_buftrace("INODE ITEM PUSH", bp);
- if (XFS_BUF_ISPINNED(bp)) {
- xfs_log_force(mp, (xfs_lsn_t)0,
- XFS_LOG_FORCE);
- }
- if (dopush) {
- xfs_bawrite(mp, bp);
- } else {
- xfs_buf_relse(bp);
- }
- } else {
- iip->ili_pushbuf_flag = 0;
- xfs_iunlock(ip, XFS_ILOCK_SHARED);
- xfs_buf_relse(bp);
- }
- return;
- }
- /*
- * We have to be careful about resetting pushbuf flag too early (above).
- * Even though in theory we can do it as soon as we have the buflock,
- * we don't want others to be doing work needlessly. They'll come to
- * this function thinking that pushing the buffer is their
- * responsibility only to find that the buffer is still locked by
- * another doing the same thing
- */
- iip->ili_pushbuf_flag = 0;
- xfs_iunlock(ip, XFS_ILOCK_SHARED);
- return;
-}
-
-
-/*
- * This is called to asynchronously write the inode associated with this
- * inode log item out to disk. The inode will already have been locked by
- * a successful call to xfs_inode_item_trylock().
- */
-STATIC void
-xfs_inode_item_push(
- xfs_inode_log_item_t *iip)
-{
- xfs_inode_t *ip;
-
- ip = iip->ili_inode;
-
- ASSERT(ismrlocked(&(ip->i_lock), MR_ACCESS));
- ASSERT(valusema(&(ip->i_flock)) <= 0);
- /*
- * Since we were able to lock the inode's flush lock and
- * we found it on the AIL, the inode must be dirty. This
- * is because the inode is removed from the AIL while still
- * holding the flush lock in xfs_iflush_done(). Thus, if
- * we found it in the AIL and were able to obtain the flush
- * lock without sleeping, then there must not have been
- * anyone in the process of flushing the inode.
- */
- ASSERT(XFS_FORCED_SHUTDOWN(ip->i_mount) ||
- iip->ili_format.ilf_fields != 0);
-
- /*
- * Write out the inode. The completion routine ('iflush_done') will
- * pull it from the AIL, mark it clean, unlock the flush lock.
- */
- (void) xfs_iflush(ip, XFS_IFLUSH_ASYNC);
- xfs_iunlock(ip, XFS_ILOCK_SHARED);
-
- return;
-}
-
-/*
- * XXX rcc - this one really has to do something. Probably needs
- * to stamp in a new field in the incore inode.
- */
-/* ARGSUSED */
-STATIC void
-xfs_inode_item_committing(
- xfs_inode_log_item_t *iip,
- xfs_lsn_t lsn)
-{
- iip->ili_last_lsn = lsn;
- return;
-}
-
-/*
- * This is the ops vector shared by all buf log items.
- */
-STATIC struct xfs_item_ops xfs_inode_item_ops = {
- .iop_size = (uint(*)(xfs_log_item_t*))xfs_inode_item_size,
- .iop_format = (void(*)(xfs_log_item_t*, xfs_log_iovec_t*))
- xfs_inode_item_format,
- .iop_pin = (void(*)(xfs_log_item_t*))xfs_inode_item_pin,
- .iop_unpin = (void(*)(xfs_log_item_t*, int))xfs_inode_item_unpin,
- .iop_unpin_remove = (void(*)(xfs_log_item_t*, xfs_trans_t*))
- xfs_inode_item_unpin_remove,
- .iop_trylock = (uint(*)(xfs_log_item_t*))xfs_inode_item_trylock,
- .iop_unlock = (void(*)(xfs_log_item_t*))xfs_inode_item_unlock,
- .iop_committed = (xfs_lsn_t(*)(xfs_log_item_t*, xfs_lsn_t))
- xfs_inode_item_committed,
- .iop_push = (void(*)(xfs_log_item_t*))xfs_inode_item_push,
- .iop_abort = (void(*)(xfs_log_item_t*))xfs_inode_item_abort,
- .iop_pushbuf = (void(*)(xfs_log_item_t*))xfs_inode_item_pushbuf,
- .iop_committing = (void(*)(xfs_log_item_t*, xfs_lsn_t))
- xfs_inode_item_committing
-};
-
-
-/*
- * Initialize the inode log item for a newly allocated (in-core) inode.
- */
-void
-xfs_inode_item_init(
- xfs_inode_t *ip,
- xfs_mount_t *mp)
-{
- xfs_inode_log_item_t *iip;
-
- ASSERT(ip->i_itemp == NULL);
- iip = ip->i_itemp = kmem_zone_zalloc(xfs_ili_zone, KM_SLEEP);
-
- iip->ili_item.li_type = XFS_LI_INODE;
- iip->ili_item.li_ops = &xfs_inode_item_ops;
- iip->ili_item.li_mountp = mp;
- iip->ili_inode = ip;
-
- /*
- We have zeroed memory. No need ...
- iip->ili_extents_buf = NULL;
- iip->ili_pushbuf_flag = 0;
- */
-
- iip->ili_format.ilf_type = XFS_LI_INODE;
- iip->ili_format.ilf_ino = ip->i_ino;
- iip->ili_format.ilf_blkno = ip->i_blkno;
- iip->ili_format.ilf_len = ip->i_len;
- iip->ili_format.ilf_boffset = ip->i_boffset;
-}
-
-/*
- * Free the inode log item and any memory hanging off of it.
- */
-void
-xfs_inode_item_destroy(
- xfs_inode_t *ip)
-{
-#ifdef XFS_TRANS_DEBUG
- if (ip->i_itemp->ili_root_size != 0) {
- kmem_free(ip->i_itemp->ili_orig_root,
- ip->i_itemp->ili_root_size);
- }
-#endif
- kmem_zone_free(xfs_ili_zone, ip->i_itemp);
-}
-
-
-/*
- * This is the inode flushing I/O completion routine. It is called
- * from interrupt level when the buffer containing the inode is
- * flushed to disk. It is responsible for removing the inode item
- * from the AIL if it has not been re-logged, and unlocking the inode's
- * flush lock.
- */
-/*ARGSUSED*/
-void
-xfs_iflush_done(
- xfs_buf_t *bp,
- xfs_inode_log_item_t *iip)
-{
- xfs_inode_t *ip;
- SPLDECL(s);
-
- ip = iip->ili_inode;
-
- /*
- * We only want to pull the item from the AIL if it is
- * actually there and its location in the log has not
- * changed since we started the flush. Thus, we only bother
- * if the ili_logged flag is set and the inode's lsn has not
- * changed. First we check the lsn outside
- * the lock since it's cheaper, and then we recheck while
- * holding the lock before removing the inode from the AIL.
- */
- if (iip->ili_logged &&
- (iip->ili_item.li_lsn == iip->ili_flush_lsn)) {
- AIL_LOCK(ip->i_mount, s);
- if (iip->ili_item.li_lsn == iip->ili_flush_lsn) {
- /*
- * xfs_trans_delete_ail() drops the AIL lock.
- */
- xfs_trans_delete_ail(ip->i_mount,
- (xfs_log_item_t*)iip, s);
- } else {
- AIL_UNLOCK(ip->i_mount, s);
- }
- }
-
- iip->ili_logged = 0;
-
- /*
- * Clear the ili_last_fields bits now that we know that the
- * data corresponding to them is safely on disk.
- */
- iip->ili_last_fields = 0;
-
- /*
- * Release the inode's flush lock since we're done with it.
- */
- xfs_ifunlock(ip);
-
- return;
-}
-
-/*
- * This is the inode flushing abort routine. It is called
- * from xfs_iflush when the filesystem is shutting down to clean
- * up the inode state.
- * It is responsible for removing the inode item
- * from the AIL if it has not been re-logged, and unlocking the inode's
- * flush lock.
- */
-void
-xfs_iflush_abort(
- xfs_inode_t *ip)
-{
- xfs_inode_log_item_t *iip;
- xfs_mount_t *mp;
- SPLDECL(s);
-
- iip = ip->i_itemp;
- mp = ip->i_mount;
- if (iip) {
- if (iip->ili_item.li_flags & XFS_LI_IN_AIL) {
- AIL_LOCK(mp, s);
- if (iip->ili_item.li_flags & XFS_LI_IN_AIL) {
- /*
- * xfs_trans_delete_ail() drops the AIL lock.
- */
- xfs_trans_delete_ail(mp, (xfs_log_item_t *)iip,
- s);
- } else
- AIL_UNLOCK(mp, s);
- }
- iip->ili_logged = 0;
- /*
- * Clear the ili_last_fields bits now that we know that the
- * data corresponding to them is safely on disk.
- */
- iip->ili_last_fields = 0;
- /*
- * Clear the inode logging fields so no more flushes are
- * attempted.
- */
- iip->ili_format.ilf_fields = 0;
- }
- /*
- * Release the inode's flush lock since we're done with it.
- */
- xfs_ifunlock(ip);
-}
-
-void
-xfs_istale_done(
- xfs_buf_t *bp,
- xfs_inode_log_item_t *iip)
-{
- xfs_iflush_abort(iip->ili_inode);
-}
diff --git a/sys/gnu/fs/xfs/xfs_inode_item.h b/sys/gnu/fs/xfs/xfs_inode_item.h
deleted file mode 100644
index c5dbf93..0000000
--- a/sys/gnu/fs/xfs/xfs_inode_item.h
+++ /dev/null
@@ -1,178 +0,0 @@
-/*
- * Copyright (c) 2000,2005 Silicon Graphics, Inc.
- * All Rights Reserved.
- *
- * 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.
- *
- * This program is distributed in the hope that it would 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 the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- */
-#ifndef __XFS_INODE_ITEM_H__
-#define __XFS_INODE_ITEM_H__
-
-/*
- * This is the structure used to lay out an inode log item in the
- * log. The size of the inline data/extents/b-tree root to be logged
- * (if any) is indicated in the ilf_dsize field. Changes to this structure
- * must be added on to the end.
- *
- * Convention for naming inode log item versions : The current version
- * is always named XFS_LI_INODE. When an inode log item gets superseded,
- * add the latest version of IRIX that will generate logs with that item
- * to the version name.
- *
- * -Version 1 of this structure (XFS_LI_5_3_INODE) included up to the first
- * union (ilf_u) field. This was released with IRIX 5.3-XFS.
- * -Version 2 of this structure (XFS_LI_6_1_INODE) is currently the entire
- * structure. This was released with IRIX 6.0.1-XFS and IRIX 6.1.
- * -Version 3 of this structure (XFS_LI_INODE) is the same as version 2
- * so a new structure definition wasn't necessary. However, we had
- * to add a new type because the inode cluster size changed from 4K
- * to 8K and the version number had to be rev'ved to keep older kernels
- * from trying to recover logs with the 8K buffers in them. The logging
- * code can handle recovery on different-sized clusters now so hopefully
- * this'll be the last time we need to change the inode log item just
- * for a change in the inode cluster size. This new version was
- * released with IRIX 6.2.
- */
-typedef struct xfs_inode_log_format {
- unsigned short ilf_type; /* inode log item type */
- unsigned short ilf_size; /* size of this item */
- uint ilf_fields; /* flags for fields logged */
- ushort ilf_asize; /* size of attr d/ext/root */
- ushort ilf_dsize; /* size of data/ext/root */
- xfs_ino_t ilf_ino; /* inode number */
- union {
- xfs_dev_t ilfu_rdev; /* rdev value for dev inode*/
- uuid_t ilfu_uuid; /* mount point value */
- } ilf_u;
- __int64_t ilf_blkno; /* blkno of inode buffer */
- int ilf_len; /* len of inode buffer */
- int ilf_boffset; /* off of inode in buffer */
-} xfs_inode_log_format_t;
-
-/* Initial version shipped with IRIX 5.3-XFS */
-typedef struct xfs_inode_log_format_v1 {
- unsigned short ilf_type; /* inode log item type */
- unsigned short ilf_size; /* size of this item */
- uint ilf_fields; /* flags for fields logged */
- uint ilf_dsize; /* size of data/ext/root */
- xfs_ino_t ilf_ino; /* inode number */
- union {
- xfs_dev_t ilfu_rdev; /* rdev value for dev inode*/
- uuid_t ilfu_uuid; /* mount point value */
- } ilf_u;
-} xfs_inode_log_format_t_v1;
-
-/*
- * Flags for xfs_trans_log_inode flags field.
- */
-#define XFS_ILOG_CORE 0x001 /* log standard inode fields */
-#define XFS_ILOG_DDATA 0x002 /* log i_df.if_data */
-#define XFS_ILOG_DEXT 0x004 /* log i_df.if_extents */
-#define XFS_ILOG_DBROOT 0x008 /* log i_df.i_broot */
-#define XFS_ILOG_DEV 0x010 /* log the dev field */
-#define XFS_ILOG_UUID 0x020 /* log the uuid field */
-#define XFS_ILOG_ADATA 0x040 /* log i_af.if_data */
-#define XFS_ILOG_AEXT 0x080 /* log i_af.if_extents */
-#define XFS_ILOG_ABROOT 0x100 /* log i_af.i_broot */
-
-#define XFS_ILOG_NONCORE (XFS_ILOG_DDATA | XFS_ILOG_DEXT | \
- XFS_ILOG_DBROOT | XFS_ILOG_DEV | \
- XFS_ILOG_UUID | XFS_ILOG_ADATA | \
- XFS_ILOG_AEXT | XFS_ILOG_ABROOT)
-
-#define XFS_ILOG_DFORK (XFS_ILOG_DDATA | XFS_ILOG_DEXT | \
- XFS_ILOG_DBROOT)
-
-#define XFS_ILOG_AFORK (XFS_ILOG_ADATA | XFS_ILOG_AEXT | \
- XFS_ILOG_ABROOT)
-
-#define XFS_ILOG_ALL (XFS_ILOG_CORE | XFS_ILOG_DDATA | \
- XFS_ILOG_DEXT | XFS_ILOG_DBROOT | \
- XFS_ILOG_DEV | XFS_ILOG_UUID | \
- XFS_ILOG_ADATA | XFS_ILOG_AEXT | \
- XFS_ILOG_ABROOT)
-
-#define XFS_ILI_HOLD 0x1
-#define XFS_ILI_IOLOCKED_EXCL 0x2
-#define XFS_ILI_IOLOCKED_SHARED 0x4
-
-#define XFS_ILI_IOLOCKED_ANY (XFS_ILI_IOLOCKED_EXCL | XFS_ILI_IOLOCKED_SHARED)
-
-
-#ifdef __KERNEL__
-
-struct xfs_buf;
-struct xfs_bmbt_rec_64;
-struct xfs_inode;
-struct xfs_mount;
-
-
-typedef struct xfs_inode_log_item {
- xfs_log_item_t ili_item; /* common portion */
- struct xfs_inode *ili_inode; /* inode ptr */
- xfs_lsn_t ili_flush_lsn; /* lsn at last flush */
- xfs_lsn_t ili_last_lsn; /* lsn at last transaction */
- unsigned short ili_ilock_recur; /* lock recursion count */
- unsigned short ili_iolock_recur; /* lock recursion count */
- unsigned short ili_flags; /* misc flags */
- unsigned short ili_logged; /* flushed logged data */
- unsigned int ili_last_fields; /* fields when flushed */
- struct xfs_bmbt_rec_64 *ili_extents_buf; /* array of logged
- data exts */
- struct xfs_bmbt_rec_64 *ili_aextents_buf; /* array of logged
- attr exts */
- unsigned int ili_pushbuf_flag; /* one bit used in push_ail */
-
-#ifdef DEBUG
- uint64_t ili_push_owner; /* one who sets pushbuf_flag
- above gets to push the buf */
-#endif
-#ifdef XFS_TRANS_DEBUG
- int ili_root_size;
- char *ili_orig_root;
-#endif
- xfs_inode_log_format_t ili_format; /* logged structure */
-} xfs_inode_log_item_t;
-
-
-#define XFS_ILOG_FDATA(w) xfs_ilog_fdata(w)
-static inline int xfs_ilog_fdata(int w)
-{
- return (w == XFS_DATA_FORK ? XFS_ILOG_DDATA : XFS_ILOG_ADATA);
-}
-
-#endif /* __KERNEL__ */
-
-#define XFS_ILOG_FBROOT(w) xfs_ilog_fbroot(w)
-static inline int xfs_ilog_fbroot(int w)
-{
- return (w == XFS_DATA_FORK ? XFS_ILOG_DBROOT : XFS_ILOG_ABROOT);
-}
-
-#define XFS_ILOG_FEXT(w) xfs_ilog_fext(w)
-static inline int xfs_ilog_fext(int w)
-{
- return (w == XFS_DATA_FORK ? XFS_ILOG_DEXT : XFS_ILOG_AEXT);
-}
-
-#ifdef __KERNEL__
-
-extern void xfs_inode_item_init(struct xfs_inode *, struct xfs_mount *);
-extern void xfs_inode_item_destroy(struct xfs_inode *);
-extern void xfs_iflush_done(struct xfs_buf *, xfs_inode_log_item_t *);
-extern void xfs_istale_done(struct xfs_buf *, xfs_inode_log_item_t *);
-extern void xfs_iflush_abort(struct xfs_inode *);
-
-#endif /* __KERNEL__ */
-
-#endif /* __XFS_INODE_ITEM_H__ */
diff --git a/sys/gnu/fs/xfs/xfs_inum.h b/sys/gnu/fs/xfs/xfs_inum.h
deleted file mode 100644
index 7a28191..0000000
--- a/sys/gnu/fs/xfs/xfs_inum.h
+++ /dev/null
@@ -1,81 +0,0 @@
-/*
- * Copyright (c) 2000-2003,2005 Silicon Graphics, Inc.
- * All Rights Reserved.
- *
- * 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.
- *
- * This program is distributed in the hope that it would 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 the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- */
-#ifndef __XFS_INUM_H__
-#define __XFS_INUM_H__
-
-/*
- * Inode number format:
- * low inopblog bits - offset in block
- * next agblklog bits - block number in ag
- * next agno_log bits - ag number
- * high agno_log-agblklog-inopblog bits - 0
- */
-
-typedef __uint32_t xfs_agino_t; /* within allocation grp inode number */
-
-/*
- * Useful inode bits for this kernel.
- * Used in some places where having 64-bits in the 32-bit kernels
- * costs too much.
- */
-#if XFS_BIG_INUMS
-typedef xfs_ino_t xfs_intino_t;
-#else
-typedef __uint32_t xfs_intino_t;
-#endif
-
-#define NULLFSINO ((xfs_ino_t)-1)
-#define NULLAGINO ((xfs_agino_t)-1)
-
-struct xfs_mount;
-
-#define XFS_INO_MASK(k) (__uint32_t)((1ULL << (k)) - 1)
-#define XFS_INO_OFFSET_BITS(mp) (mp)->m_sb.sb_inopblog
-#define XFS_INO_AGBNO_BITS(mp) (mp)->m_sb.sb_agblklog
-#define XFS_INO_AGINO_BITS(mp) (mp)->m_agino_log
-#define XFS_INO_AGNO_BITS(mp) (mp)->m_agno_log
-#define XFS_INO_BITS(mp) \
- XFS_INO_AGNO_BITS(mp) + XFS_INO_AGINO_BITS(mp)
-#define XFS_INO_TO_AGNO(mp,i) \
- ((xfs_agnumber_t)((i) >> XFS_INO_AGINO_BITS(mp)))
-#define XFS_INO_TO_AGINO(mp,i) \
- ((xfs_agino_t)(i) & XFS_INO_MASK(XFS_INO_AGINO_BITS(mp)))
-#define XFS_INO_TO_AGBNO(mp,i) \
- (((xfs_agblock_t)(i) >> XFS_INO_OFFSET_BITS(mp)) & \
- XFS_INO_MASK(XFS_INO_AGBNO_BITS(mp)))
-#define XFS_INO_TO_OFFSET(mp,i) \
- ((int)(i) & XFS_INO_MASK(XFS_INO_OFFSET_BITS(mp)))
-#define XFS_INO_TO_FSB(mp,i) \
- XFS_AGB_TO_FSB(mp, XFS_INO_TO_AGNO(mp,i), XFS_INO_TO_AGBNO(mp,i))
-#define XFS_AGINO_TO_INO(mp,a,i) \
- (((xfs_ino_t)(a) << XFS_INO_AGINO_BITS(mp)) | (i))
-#define XFS_AGINO_TO_AGBNO(mp,i) ((i) >> XFS_INO_OFFSET_BITS(mp))
-#define XFS_AGINO_TO_OFFSET(mp,i) \
- ((i) & XFS_INO_MASK(XFS_INO_OFFSET_BITS(mp)))
-#define XFS_OFFBNO_TO_AGINO(mp,b,o) \
- ((xfs_agino_t)(((b) << XFS_INO_OFFSET_BITS(mp)) | (o)))
-
-#if XFS_BIG_INUMS
-#define XFS_MAXINUMBER ((xfs_ino_t)((1ULL << 56) - 1ULL))
-#define XFS_INO64_OFFSET ((xfs_ino_t)(1ULL << 32))
-#else
-#define XFS_MAXINUMBER ((xfs_ino_t)((1ULL << 32) - 1ULL))
-#endif
-#define XFS_MAXINUMBER_32 ((xfs_ino_t)((1ULL << 32) - 1ULL))
-
-#endif /* __XFS_INUM_H__ */
diff --git a/sys/gnu/fs/xfs/xfs_iocore.c b/sys/gnu/fs/xfs/xfs_iocore.c
deleted file mode 100644
index 19e4f78..0000000
--- a/sys/gnu/fs/xfs/xfs_iocore.c
+++ /dev/null
@@ -1,123 +0,0 @@
-/*
- * Copyright (c) 2000-2003,2005 Silicon Graphics, Inc.
- * All Rights Reserved.
- *
- * 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.
- *
- * This program is distributed in the hope that it would 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 the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- */
-#include "xfs.h"
-#include "xfs_fs.h"
-#include "xfs_types.h"
-#include "xfs_bit.h"
-#include "xfs_log.h"
-#include "xfs_inum.h"
-#include "xfs_trans.h"
-#include "xfs_sb.h"
-#include "xfs_ag.h"
-#include "xfs_dir.h"
-#include "xfs_dir2.h"
-#include "xfs_dfrag.h"
-#include "xfs_dmapi.h"
-#include "xfs_mount.h"
-#include "xfs_bmap_btree.h"
-#include "xfs_alloc_btree.h"
-#include "xfs_ialloc_btree.h"
-#include "xfs_dir_sf.h"
-#include "xfs_dir2_sf.h"
-#include "xfs_attr_sf.h"
-#include "xfs_dinode.h"
-#include "xfs_inode.h"
-#include "xfs_inode_item.h"
-#include "xfs_itable.h"
-#include "xfs_btree.h"
-#include "xfs_alloc.h"
-#include "xfs_ialloc.h"
-#include "xfs_bmap.h"
-#include "xfs_error.h"
-#include "xfs_rw.h"
-#include "xfs_quota.h"
-#include "xfs_trans_space.h"
-#include "xfs_iomap.h"
-
-
-
-STATIC xfs_fsize_t
-xfs_size_fn(
- xfs_inode_t *ip)
-{
- return (ip->i_d.di_size);
-}
-
-STATIC int
-xfs_ioinit(
- struct xfs_vfs *vfsp,
- struct xfs_mount_args *mntargs,
- int flags)
-{
- return xfs_mountfs(vfsp, XFS_VFSTOM(vfsp), flags);
-}
-
-xfs_ioops_t xfs_iocore_xfs = {
- .xfs_ioinit = (xfs_ioinit_t) xfs_ioinit,
- .xfs_bmapi_func = (xfs_bmapi_t) xfs_bmapi,
- .xfs_bunmapi_func = (xfs_bunmapi_t) xfs_bunmapi,
- .xfs_bmap_eof_func = (xfs_bmap_eof_t) xfs_bmap_eof,
- .xfs_iomap_write_direct =
- (xfs_iomap_write_direct_t) xfs_iomap_write_direct,
- .xfs_iomap_write_delay =
- (xfs_iomap_write_delay_t) xfs_iomap_write_delay,
- .xfs_iomap_write_allocate =
- (xfs_iomap_write_allocate_t) xfs_iomap_write_allocate,
- .xfs_iomap_write_unwritten =
- (xfs_iomap_write_unwritten_t) xfs_iomap_write_unwritten,
- .xfs_ilock = (xfs_lock_t) xfs_ilock,
- .xfs_lck_map_shared = (xfs_lck_map_shared_t) xfs_ilock_map_shared,
- .xfs_ilock_demote = (xfs_lock_demote_t) xfs_ilock_demote,
- .xfs_ilock_nowait = (xfs_lock_nowait_t) xfs_ilock_nowait,
- .xfs_unlock = (xfs_unlk_t) xfs_iunlock,
- .xfs_size_func = (xfs_size_t) xfs_size_fn,
- .xfs_iodone = (xfs_iodone_t) fs_noerr,
- .xfs_swap_extents_func = (xfs_swap_extents_t) xfs_swap_extents,
-};
-
-void
-xfs_iocore_inode_reinit(
- xfs_inode_t *ip)
-{
- xfs_iocore_t *io = &ip->i_iocore;
-
- io->io_flags = 0;
- if (ip->i_d.di_flags & XFS_DIFLAG_REALTIME)
- io->io_flags |= XFS_IOCORE_RT;
- io->io_dmevmask = ip->i_d.di_dmevmask;
- io->io_dmstate = ip->i_d.di_dmstate;
-}
-
-void
-xfs_iocore_inode_init(
- xfs_inode_t *ip)
-{
- xfs_iocore_t *io = &ip->i_iocore;
- xfs_mount_t *mp = ip->i_mount;
-
- io->io_mount = mp;
-#ifdef DEBUG
- io->io_lock = &ip->i_lock;
- io->io_iolock = &ip->i_iolock;
-#endif
-
- io->io_obj = (void *)ip;
-
- xfs_iocore_inode_reinit(ip);
-}
-
diff --git a/sys/gnu/fs/xfs/xfs_iomap.c b/sys/gnu/fs/xfs/xfs_iomap.c
deleted file mode 100644
index 2727e63..0000000
--- a/sys/gnu/fs/xfs/xfs_iomap.c
+++ /dev/null
@@ -1,1006 +0,0 @@
-/*
- * Copyright (c) 2000-2006 Silicon Graphics, Inc.
- * All Rights Reserved.
- *
- * 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.
- *
- * This program is distributed in the hope that it would 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 the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- */
-#include "xfs.h"
-#include "xfs_fs.h"
-#include "xfs_bit.h"
-#include "xfs_log.h"
-#include "xfs_inum.h"
-#include "xfs_trans.h"
-#include "xfs_sb.h"
-#include "xfs_ag.h"
-#include "xfs_dir.h"
-#include "xfs_dir2.h"
-#include "xfs_alloc.h"
-#include "xfs_dmapi.h"
-#include "xfs_quota.h"
-#include "xfs_mount.h"
-#include "xfs_bmap_btree.h"
-#include "xfs_alloc_btree.h"
-#include "xfs_ialloc_btree.h"
-#include "xfs_dir_sf.h"
-#include "xfs_dir2_sf.h"
-#include "xfs_attr_sf.h"
-#include "xfs_dinode.h"
-#include "xfs_inode.h"
-#include "xfs_ialloc.h"
-#include "xfs_btree.h"
-#include "xfs_bmap.h"
-#include "xfs_rtalloc.h"
-#include "xfs_error.h"
-#include "xfs_itable.h"
-#include "xfs_rw.h"
-#include "xfs_acl.h"
-#include "xfs_cap.h"
-#include "xfs_mac.h"
-#include "xfs_attr.h"
-#include "xfs_buf_item.h"
-#include "xfs_trans_space.h"
-#include "xfs_utils.h"
-#include "xfs_iomap.h"
-
-#if defined(XFS_RW_TRACE)
-void
-xfs_iomap_enter_trace(
- int tag,
- xfs_iocore_t *io,
- xfs_off_t offset,
- ssize_t count)
-{
- xfs_inode_t *ip = XFS_IO_INODE(io);
-
- if (!ip->i_rwtrace)
- return;
-
- ktrace_enter(ip->i_rwtrace,
- (void *)((unsigned long)tag),
- (void *)ip,
- (void *)((unsigned long)((ip->i_d.di_size >> 32) & 0xffffffff)),
- (void *)((unsigned long)(ip->i_d.di_size & 0xffffffff)),
- (void *)((unsigned long)((offset >> 32) & 0xffffffff)),
- (void *)((unsigned long)(offset & 0xffffffff)),
- (void *)((unsigned long)count),
- (void *)((unsigned long)((io->io_new_size >> 32) & 0xffffffff)),
- (void *)((unsigned long)(io->io_new_size & 0xffffffff)),
- (void *)((unsigned long)current_pid()),
- (void *)NULL,
- (void *)NULL,
- (void *)NULL,
- (void *)NULL,
- (void *)NULL,
- (void *)NULL);
-}
-
-void
-xfs_iomap_map_trace(
- int tag,
- xfs_iocore_t *io,
- xfs_off_t offset,
- ssize_t count,
- xfs_iomap_t *iomapp,
- xfs_bmbt_irec_t *imapp,
- int flags)
-{
- xfs_inode_t *ip = XFS_IO_INODE(io);
-
- if (!ip->i_rwtrace)
- return;
-
- ktrace_enter(ip->i_rwtrace,
- (void *)((unsigned long)tag),
- (void *)ip,
- (void *)((unsigned long)((ip->i_d.di_size >> 32) & 0xffffffff)),
- (void *)((unsigned long)(ip->i_d.di_size & 0xffffffff)),
- (void *)((unsigned long)((offset >> 32) & 0xffffffff)),
- (void *)((unsigned long)(offset & 0xffffffff)),
- (void *)((unsigned long)count),
- (void *)((unsigned long)flags),
- (void *)((unsigned long)((iomapp->iomap_offset >> 32) & 0xffffffff)),
- (void *)((unsigned long)(iomapp->iomap_offset & 0xffffffff)),
- (void *)((unsigned long)(iomapp->iomap_delta)),
- (void *)((unsigned long)(iomapp->iomap_bsize)),
- (void *)((unsigned long)(iomapp->iomap_bn)),
- (void *)(__psint_t)(imapp->br_startoff),
- (void *)((unsigned long)(imapp->br_blockcount)),
- (void *)(__psint_t)(imapp->br_startblock));
-}
-#else
-#define xfs_iomap_enter_trace(tag, io, offset, count)
-#define xfs_iomap_map_trace(tag, io, offset, count, iomapp, imapp, flags)
-#endif
-
-#define XFS_WRITEIO_ALIGN(mp,off) (((off) >> mp->m_writeio_log) \
- << mp->m_writeio_log)
-#define XFS_STRAT_WRITE_IMAPS 2
-#define XFS_WRITE_IMAPS XFS_BMAP_MAX_NMAP
-
-STATIC int
-xfs_imap_to_bmap(
- xfs_iocore_t *io,
- xfs_off_t offset,
- xfs_bmbt_irec_t *imap,
- xfs_iomap_t *iomapp,
- int imaps, /* Number of imap entries */
- int iomaps, /* Number of iomap entries */
- int flags)
-{
- xfs_mount_t *mp;
- xfs_fsize_t nisize;
- int pbm;
- xfs_fsblock_t start_block;
-
- mp = io->io_mount;
- nisize = XFS_SIZE(mp, io);
- if (io->io_new_size > nisize)
- nisize = io->io_new_size;
-
- for (pbm = 0; imaps && pbm < iomaps; imaps--, iomapp++, imap++, pbm++) {
- iomapp->iomap_offset = XFS_FSB_TO_B(mp, imap->br_startoff);
- iomapp->iomap_delta = offset - iomapp->iomap_offset;
- iomapp->iomap_bsize = XFS_FSB_TO_B(mp, imap->br_blockcount);
- iomapp->iomap_flags = flags;
-
- if (io->io_flags & XFS_IOCORE_RT) {
- iomapp->iomap_flags |= IOMAP_REALTIME;
- iomapp->iomap_target = mp->m_rtdev_targp;
- } else {
- iomapp->iomap_target = mp->m_ddev_targp;
- }
- start_block = imap->br_startblock;
- if (start_block == HOLESTARTBLOCK) {
- iomapp->iomap_bn = IOMAP_DADDR_NULL;
- iomapp->iomap_flags |= IOMAP_HOLE;
- } else if (start_block == DELAYSTARTBLOCK) {
- iomapp->iomap_bn = IOMAP_DADDR_NULL;
- iomapp->iomap_flags |= IOMAP_DELAY;
- } else {
- iomapp->iomap_bn = XFS_FSB_TO_DB_IO(io, start_block);
- if (ISUNWRITTEN(imap))
- iomapp->iomap_flags |= IOMAP_UNWRITTEN;
- }
-
- if ((iomapp->iomap_offset + iomapp->iomap_bsize) >= nisize) {
- iomapp->iomap_flags |= IOMAP_EOF;
- }
-
- offset += iomapp->iomap_bsize - iomapp->iomap_delta;
- }
- return pbm; /* Return the number filled */
-}
-
-int
-xfs_iomap(
- xfs_iocore_t *io,
- xfs_off_t offset,
- ssize_t count,
- int flags,
- xfs_iomap_t *iomapp,
- int *niomaps)
-{
- xfs_mount_t *mp = io->io_mount;
- xfs_fileoff_t offset_fsb, end_fsb;
- int error = 0;
- int lockmode = 0;
- xfs_bmbt_irec_t imap;
- int nimaps = 1;
- int bmapi_flags = 0;
- int iomap_flags = 0;
-
- if (XFS_FORCED_SHUTDOWN(mp))
- return XFS_ERROR(EIO);
-
- switch (flags &
- (BMAPI_READ | BMAPI_WRITE | BMAPI_ALLOCATE |
- BMAPI_UNWRITTEN | BMAPI_DEVICE)) {
- case BMAPI_READ:
- xfs_iomap_enter_trace(XFS_IOMAP_READ_ENTER, io, offset, count);
- lockmode = XFS_LCK_MAP_SHARED(mp, io);
- bmapi_flags = XFS_BMAPI_ENTIRE;
- break;
- case BMAPI_WRITE:
- xfs_iomap_enter_trace(XFS_IOMAP_WRITE_ENTER, io, offset, count);
- lockmode = XFS_ILOCK_EXCL|XFS_EXTSIZE_WR;
- if (flags & BMAPI_IGNSTATE)
- bmapi_flags |= XFS_BMAPI_IGSTATE|XFS_BMAPI_ENTIRE;
- XFS_ILOCK(mp, io, lockmode);
- break;
- case BMAPI_ALLOCATE:
- xfs_iomap_enter_trace(XFS_IOMAP_ALLOC_ENTER, io, offset, count);
- lockmode = XFS_ILOCK_SHARED|XFS_EXTSIZE_RD;
- bmapi_flags = XFS_BMAPI_ENTIRE;
- /* Attempt non-blocking lock */
- if (flags & BMAPI_TRYLOCK) {
- if (!XFS_ILOCK_NOWAIT(mp, io, lockmode))
- return XFS_ERROR(EAGAIN);
- } else {
- XFS_ILOCK(mp, io, lockmode);
- }
- break;
- case BMAPI_UNWRITTEN:
- goto phase2;
- case BMAPI_DEVICE:
- lockmode = XFS_LCK_MAP_SHARED(mp, io);
- iomapp->iomap_target = io->io_flags & XFS_IOCORE_RT ?
- mp->m_rtdev_targp : mp->m_ddev_targp;
- error = 0;
- *niomaps = 1;
- goto out;
- default:
- panic("unrecognized bmapi flags");
- }
-
- ASSERT(offset <= mp->m_maxioffset);
- if ((xfs_fsize_t)offset + count > mp->m_maxioffset)
- count = mp->m_maxioffset - offset;
- end_fsb = XFS_B_TO_FSB(mp, (xfs_ufsize_t)offset + count);
- offset_fsb = XFS_B_TO_FSBT(mp, offset);
-
- error = XFS_BMAPI(mp, NULL, io, offset_fsb,
- (xfs_filblks_t)(end_fsb - offset_fsb),
- bmapi_flags, NULL, 0, &imap,
- &nimaps, NULL, NULL);
-
- if (error)
- goto out;
-
-phase2:
- switch (flags & (BMAPI_WRITE|BMAPI_ALLOCATE|BMAPI_UNWRITTEN)) {
- case BMAPI_WRITE:
- /* If we found an extent, return it */
- if (nimaps &&
- (imap.br_startblock != HOLESTARTBLOCK) &&
- (imap.br_startblock != DELAYSTARTBLOCK)) {
- xfs_iomap_map_trace(XFS_IOMAP_WRITE_MAP, io,
- offset, count, iomapp, &imap, flags);
- break;
- }
-
- if (flags & (BMAPI_DIRECT|BMAPI_MMAP)) {
- error = XFS_IOMAP_WRITE_DIRECT(mp, io, offset,
- count, flags, &imap, &nimaps, nimaps);
- } else {
- error = XFS_IOMAP_WRITE_DELAY(mp, io, offset, count,
- flags, &imap, &nimaps);
- }
- if (!error) {
- xfs_iomap_map_trace(XFS_IOMAP_ALLOC_MAP, io,
- offset, count, iomapp, &imap, flags);
- }
- iomap_flags = IOMAP_NEW;
- break;
- case BMAPI_ALLOCATE:
- /* If we found an extent, return it */
- XFS_IUNLOCK(mp, io, lockmode);
- lockmode = 0;
-
- if (nimaps && !ISNULLSTARTBLOCK(imap.br_startblock)) {
- xfs_iomap_map_trace(XFS_IOMAP_WRITE_MAP, io,
- offset, count, iomapp, &imap, flags);
- break;
- }
-
- error = XFS_IOMAP_WRITE_ALLOCATE(mp, io, offset, count,
- &imap, &nimaps);
- break;
- case BMAPI_UNWRITTEN:
- lockmode = 0;
- error = XFS_IOMAP_WRITE_UNWRITTEN(mp, io, offset, count);
- nimaps = 0;
- break;
- }
-
- if (nimaps) {
- *niomaps = xfs_imap_to_bmap(io, offset, &imap,
- iomapp, nimaps, *niomaps, iomap_flags);
- } else if (niomaps) {
- *niomaps = 0;
- }
-
-out:
- if (lockmode)
- XFS_IUNLOCK(mp, io, lockmode);
- return XFS_ERROR(error);
-}
-
-STATIC int
-xfs_iomap_eof_align_last_fsb(
- xfs_mount_t *mp,
- xfs_iocore_t *io,
- xfs_fsize_t isize,
- xfs_extlen_t extsize,
- xfs_fileoff_t *last_fsb)
-{
- xfs_fileoff_t new_last_fsb = 0;
- xfs_extlen_t align;
- int eof, error;
-
- if (io->io_flags & XFS_IOCORE_RT)
- ;
- /*
- * If mounted with the "-o swalloc" option, roundup the allocation
- * request to a stripe width boundary if the file size is >=
- * stripe width and we are allocating past the allocation eof.
- */
- else if (mp->m_swidth && (mp->m_flags & XFS_MOUNT_SWALLOC) &&
- (isize >= XFS_FSB_TO_B(mp, mp->m_swidth)))
- new_last_fsb = roundup_64(*last_fsb, mp->m_swidth);
- /*
- * Roundup the allocation request to a stripe unit (m_dalign) boundary
- * if the file size is >= stripe unit size, and we are allocating past
- * the allocation eof.
- */
- else if (mp->m_dalign && (isize >= XFS_FSB_TO_B(mp, mp->m_dalign)))
- new_last_fsb = roundup_64(*last_fsb, mp->m_dalign);
-
- /*
- * Always round up the allocation request to an extent boundary
- * (when file on a real-time subvolume or has di_extsize hint).
- */
- if (extsize) {
- if (new_last_fsb)
- align = roundup_64(new_last_fsb, extsize);
- else
- align = extsize;
- new_last_fsb = roundup_64(*last_fsb, align);
- }
-
- if (new_last_fsb) {
- error = XFS_BMAP_EOF(mp, io, new_last_fsb, XFS_DATA_FORK, &eof);
- if (error)
- return error;
- if (eof)
- *last_fsb = new_last_fsb;
- }
- return 0;
-}
-
-STATIC int
-xfs_flush_space(
- xfs_inode_t *ip,
- int *fsynced,
- int *ioflags)
-{
- switch (*fsynced) {
- case 0:
- if (ip->i_delayed_blks) {
- xfs_iunlock(ip, XFS_ILOCK_EXCL);
- xfs_flush_inode(ip);
- xfs_ilock(ip, XFS_ILOCK_EXCL);
- *fsynced = 1;
- } else {
- *ioflags |= BMAPI_SYNC;
- *fsynced = 2;
- }
- return 0;
- case 1:
- *fsynced = 2;
- *ioflags |= BMAPI_SYNC;
- return 0;
- case 2:
- xfs_iunlock(ip, XFS_ILOCK_EXCL);
- xfs_flush_device(ip);
- xfs_ilock(ip, XFS_ILOCK_EXCL);
- *fsynced = 3;
- return 0;
- }
- return 1;
-}
-
-int
-xfs_iomap_write_direct(
- xfs_inode_t *ip,
- xfs_off_t offset,
- size_t count,
- int flags,
- xfs_bmbt_irec_t *ret_imap,
- int *nmaps,
- int found)
-{
- xfs_mount_t *mp = ip->i_mount;
- xfs_iocore_t *io = &ip->i_iocore;
- xfs_fileoff_t offset_fsb;
- xfs_fileoff_t last_fsb;
- xfs_filblks_t count_fsb, resaligned;
- xfs_fsblock_t firstfsb;
- xfs_extlen_t extsz, temp;
- xfs_fsize_t isize;
- int nimaps;
- int bmapi_flag;
- int quota_flag;
- int rt;
- xfs_trans_t *tp;
- xfs_bmbt_irec_t imap;
- xfs_bmap_free_t free_list;
- uint qblocks, resblks, resrtextents;
- int committed;
- int error;
-
- /*
- * Make sure that the dquots are there. This doesn't hold
- * the ilock across a disk read.
- */
- error = XFS_QM_DQATTACH(ip->i_mount, ip, XFS_QMOPT_ILOCKED);
- if (error)
- return XFS_ERROR(error);
-
- rt = XFS_IS_REALTIME_INODE(ip);
- if (unlikely(rt)) {
- if (!(extsz = ip->i_d.di_extsize))
- extsz = mp->m_sb.sb_rextsize;
- } else {
- extsz = ip->i_d.di_extsize;
- }
-
- isize = ip->i_d.di_size;
- if (io->io_new_size > isize)
- isize = io->io_new_size;
-
- offset_fsb = XFS_B_TO_FSBT(mp, offset);
- last_fsb = XFS_B_TO_FSB(mp, ((xfs_ufsize_t)(offset + count)));
- if ((offset + count) > isize) {
- error = xfs_iomap_eof_align_last_fsb(mp, io, isize, extsz,
- &last_fsb);
- if (error)
- goto error_out;
- } else {
- if (found && (ret_imap->br_startblock == HOLESTARTBLOCK))
- last_fsb = MIN(last_fsb, (xfs_fileoff_t)
- ret_imap->br_blockcount +
- ret_imap->br_startoff);
- }
- count_fsb = last_fsb - offset_fsb;
- ASSERT(count_fsb > 0);
-
- resaligned = count_fsb;
- if (unlikely(extsz)) {
- if ((temp = do_mod(offset_fsb, extsz)))
- resaligned += temp;
- if ((temp = do_mod(resaligned, extsz)))
- resaligned += extsz - temp;
- }
-
- if (unlikely(rt)) {
- resrtextents = qblocks = resaligned;
- resrtextents /= mp->m_sb.sb_rextsize;
- resblks = XFS_DIOSTRAT_SPACE_RES(mp, 0);
- quota_flag = XFS_QMOPT_RES_RTBLKS;
- } else {
- resrtextents = 0;
- resblks = qblocks = XFS_DIOSTRAT_SPACE_RES(mp, resaligned);
- quota_flag = XFS_QMOPT_RES_REGBLKS;
- }
-
- /*
- * Allocate and setup the transaction
- */
- xfs_iunlock(ip, XFS_ILOCK_EXCL);
- tp = xfs_trans_alloc(mp, XFS_TRANS_DIOSTRAT);
- error = xfs_trans_reserve(tp, resblks,
- XFS_WRITE_LOG_RES(mp), resrtextents,
- XFS_TRANS_PERM_LOG_RES,
- XFS_WRITE_LOG_COUNT);
- /*
- * Check for running out of space, note: need lock to return
- */
- if (error)
- xfs_trans_cancel(tp, 0);
- xfs_ilock(ip, XFS_ILOCK_EXCL);
- if (error)
- goto error_out;
-
- error = XFS_TRANS_RESERVE_QUOTA_NBLKS(mp, tp, ip,
- qblocks, 0, quota_flag);
- if (error)
- goto error1;
-
- xfs_trans_ijoin(tp, ip, XFS_ILOCK_EXCL);
- xfs_trans_ihold(tp, ip);
-
- bmapi_flag = XFS_BMAPI_WRITE;
- if ((flags & BMAPI_DIRECT) && (offset < ip->i_d.di_size || extsz))
- bmapi_flag |= XFS_BMAPI_PREALLOC;
-
- /*
- * Issue the xfs_bmapi() call to allocate the blocks
- */
- XFS_BMAP_INIT(&free_list, &firstfsb);
- nimaps = 1;
- error = XFS_BMAPI(mp, tp, io, offset_fsb, count_fsb, bmapi_flag,
- &firstfsb, 0, &imap, &nimaps, &free_list, NULL);
- if (error)
- goto error0;
-
- /*
- * Complete the transaction
- */
- error = xfs_bmap_finish(&tp, &free_list, firstfsb, &committed);
- if (error)
- goto error0;
- error = xfs_trans_commit(tp, XFS_TRANS_RELEASE_LOG_RES, NULL);
- if (error)
- goto error_out;
-
- /*
- * Copy any maps to caller's array and return any error.
- */
- if (nimaps == 0) {
- error = (ENOSPC);
- goto error_out;
- }
-
- *ret_imap = imap;
- *nmaps = 1;
- if ( !(io->io_flags & XFS_IOCORE_RT) && !ret_imap->br_startblock) {
- cmn_err(CE_PANIC,"Access to block zero: fs <%s> inode: %lld "
- "start_block : %llx start_off : %llx blkcnt : %llx "
- "extent-state : %x \n",
- (ip->i_mount)->m_fsname,
- (long long)ip->i_ino,
- (unsigned long long)ret_imap->br_startblock,
- (unsigned long long)ret_imap->br_startoff,
- (unsigned long long)ret_imap->br_blockcount,
- ret_imap->br_state);
- }
- return 0;
-
-error0: /* Cancel bmap, unlock inode, unreserve quota blocks, cancel trans */
- xfs_bmap_cancel(&free_list);
- XFS_TRANS_UNRESERVE_QUOTA_NBLKS(mp, tp, ip, qblocks, 0, quota_flag);
-
-error1: /* Just cancel transaction */
- xfs_trans_cancel(tp, XFS_TRANS_RELEASE_LOG_RES | XFS_TRANS_ABORT);
- *nmaps = 0; /* nothing set-up here */
-
-error_out:
- return XFS_ERROR(error);
-}
-
-/*
- * If the caller is doing a write at the end of the file,
- * then extend the allocation out to the file system's write
- * iosize. We clean up any extra space left over when the
- * file is closed in xfs_inactive().
- *
- * For sync writes, we are flushing delayed allocate space to
- * try to make additional space available for allocation near
- * the filesystem full boundary - preallocation hurts in that
- * situation, of course.
- */
-STATIC int
-xfs_iomap_eof_want_preallocate(
- xfs_mount_t *mp,
- xfs_iocore_t *io,
- xfs_fsize_t isize,
- xfs_off_t offset,
- size_t count,
- int ioflag,
- xfs_bmbt_irec_t *imap,
- int nimaps,
- int *prealloc)
-{
- xfs_fileoff_t start_fsb;
- xfs_filblks_t count_fsb;
- xfs_fsblock_t firstblock;
- int n, error, imaps;
-
- *prealloc = 0;
- if ((ioflag & BMAPI_SYNC) || (offset + count) <= isize)
- return 0;
-
- /*
- * If there are any real blocks past eof, then don't
- * do any speculative allocation.
- */
- start_fsb = XFS_B_TO_FSBT(mp, ((xfs_ufsize_t)(offset + count - 1)));
- count_fsb = XFS_B_TO_FSB(mp, (xfs_ufsize_t)XFS_MAXIOFFSET(mp));
- while (count_fsb > 0) {
- imaps = nimaps;
- firstblock = NULLFSBLOCK;
- error = XFS_BMAPI(mp, NULL, io, start_fsb, count_fsb, 0,
- &firstblock, 0, imap, &imaps, NULL, NULL);
- if (error)
- return error;
- for (n = 0; n < imaps; n++) {
- if ((imap[n].br_startblock != HOLESTARTBLOCK) &&
- (imap[n].br_startblock != DELAYSTARTBLOCK))
- return 0;
- start_fsb += imap[n].br_blockcount;
- count_fsb -= imap[n].br_blockcount;
- }
- }
- *prealloc = 1;
- return 0;
-}
-
-int
-xfs_iomap_write_delay(
- xfs_inode_t *ip,
- xfs_off_t offset,
- size_t count,
- int ioflag,
- xfs_bmbt_irec_t *ret_imap,
- int *nmaps)
-{
- xfs_mount_t *mp = ip->i_mount;
- xfs_iocore_t *io = &ip->i_iocore;
- xfs_fileoff_t offset_fsb;
- xfs_fileoff_t last_fsb;
- xfs_off_t aligned_offset;
- xfs_fileoff_t ioalign;
- xfs_fsblock_t firstblock;
- xfs_extlen_t extsz;
- xfs_fsize_t isize;
- int nimaps;
- xfs_bmbt_irec_t imap[XFS_WRITE_IMAPS];
- int prealloc, fsynced = 0;
- int error;
-
- ASSERT(ismrlocked(&ip->i_lock, MR_UPDATE) != 0);
-
- /*
- * Make sure that the dquots are there. This doesn't hold
- * the ilock across a disk read.
- */
- error = XFS_QM_DQATTACH(mp, ip, XFS_QMOPT_ILOCKED);
- if (error)
- return XFS_ERROR(error);
-
- if (XFS_IS_REALTIME_INODE(ip)) {
- if (!(extsz = ip->i_d.di_extsize))
- extsz = mp->m_sb.sb_rextsize;
- } else {
- extsz = ip->i_d.di_extsize;
- }
-
- offset_fsb = XFS_B_TO_FSBT(mp, offset);
-
-retry:
- isize = ip->i_d.di_size;
- if (io->io_new_size > isize)
- isize = io->io_new_size;
-
- error = xfs_iomap_eof_want_preallocate(mp, io, isize, offset, count,
- ioflag, imap, XFS_WRITE_IMAPS, &prealloc);
- if (error)
- return error;
-
- if (prealloc) {
- aligned_offset = XFS_WRITEIO_ALIGN(mp, (offset + count - 1));
- ioalign = XFS_B_TO_FSBT(mp, aligned_offset);
- last_fsb = ioalign + mp->m_writeio_blocks;
- } else {
- last_fsb = XFS_B_TO_FSB(mp, ((xfs_ufsize_t)(offset + count)));
- }
-
- if (prealloc || extsz) {
- error = xfs_iomap_eof_align_last_fsb(mp, io, isize, extsz,
- &last_fsb);
- if (error)
- return error;
- }
-
- nimaps = XFS_WRITE_IMAPS;
- firstblock = NULLFSBLOCK;
- error = XFS_BMAPI(mp, NULL, io, offset_fsb,
- (xfs_filblks_t)(last_fsb - offset_fsb),
- XFS_BMAPI_DELAY | XFS_BMAPI_WRITE |
- XFS_BMAPI_ENTIRE, &firstblock, 1, imap,
- &nimaps, NULL, NULL);
- if (error && (error != ENOSPC))
- return XFS_ERROR(error);
-
- /*
- * If bmapi returned us nothing, and if we didn't get back EDQUOT,
- * then we must have run out of space - flush delalloc, and retry..
- */
- if (nimaps == 0) {
- xfs_iomap_enter_trace(XFS_IOMAP_WRITE_NOSPACE,
- io, offset, count);
- if (xfs_flush_space(ip, &fsynced, &ioflag))
- return XFS_ERROR(ENOSPC);
-
- error = 0;
- goto retry;
- }
-
- if (!(io->io_flags & XFS_IOCORE_RT) && !ret_imap->br_startblock) {
- cmn_err(CE_PANIC,"Access to block zero: fs <%s> inode: %lld "
- "start_block : %llx start_off : %llx blkcnt : %llx "
- "extent-state : %x \n",
- (ip->i_mount)->m_fsname,
- (long long)ip->i_ino,
- (unsigned long long)ret_imap->br_startblock,
- (unsigned long long)ret_imap->br_startoff,
- (unsigned long long)ret_imap->br_blockcount,
- ret_imap->br_state);
- }
-
- *ret_imap = imap[0];
- *nmaps = 1;
-
- return 0;
-}
-
-/*
- * Pass in a delayed allocate extent, convert it to real extents;
- * return to the caller the extent we create which maps on top of
- * the originating callers request.
- *
- * Called without a lock on the inode.
- */
-int
-xfs_iomap_write_allocate(
- xfs_inode_t *ip,
- xfs_off_t offset,
- size_t count,
- xfs_bmbt_irec_t *map,
- int *retmap)
-{
- xfs_mount_t *mp = ip->i_mount;
- xfs_iocore_t *io = &ip->i_iocore;
- xfs_fileoff_t offset_fsb, last_block;
- xfs_fileoff_t end_fsb, map_start_fsb;
- xfs_fsblock_t first_block;
- xfs_bmap_free_t free_list;
- xfs_filblks_t count_fsb;
- xfs_bmbt_irec_t imap[XFS_STRAT_WRITE_IMAPS];
- xfs_trans_t *tp;
- int i, nimaps, committed;
- int error = 0;
- int nres;
-
- *retmap = 0;
-
- /*
- * Make sure that the dquots are there.
- */
- if ((error = XFS_QM_DQATTACH(mp, ip, 0)))
- return XFS_ERROR(error);
-
- offset_fsb = XFS_B_TO_FSBT(mp, offset);
- count_fsb = map->br_blockcount;
- map_start_fsb = map->br_startoff;
-
- XFS_STATS_ADD(xs_xstrat_bytes, XFS_FSB_TO_B(mp, count_fsb));
-
- while (count_fsb != 0) {
- /*
- * Set up a transaction with which to allocate the
- * backing store for the file. Do allocations in a
- * loop until we get some space in the range we are
- * interested in. The other space that might be allocated
- * is in the delayed allocation extent on which we sit
- * but before our buffer starts.
- */
-
- nimaps = 0;
- while (nimaps == 0) {
- tp = xfs_trans_alloc(mp, XFS_TRANS_STRAT_WRITE);
- nres = XFS_EXTENTADD_SPACE_RES(mp, XFS_DATA_FORK);
- error = xfs_trans_reserve(tp, nres,
- XFS_WRITE_LOG_RES(mp),
- 0, XFS_TRANS_PERM_LOG_RES,
- XFS_WRITE_LOG_COUNT);
- if (error == ENOSPC) {
- error = xfs_trans_reserve(tp, 0,
- XFS_WRITE_LOG_RES(mp),
- 0,
- XFS_TRANS_PERM_LOG_RES,
- XFS_WRITE_LOG_COUNT);
- }
- if (error) {
- xfs_trans_cancel(tp, 0);
- return XFS_ERROR(error);
- }
- xfs_ilock(ip, XFS_ILOCK_EXCL);
- xfs_trans_ijoin(tp, ip, XFS_ILOCK_EXCL);
- xfs_trans_ihold(tp, ip);
-
- XFS_BMAP_INIT(&free_list, &first_block);
-
- nimaps = XFS_STRAT_WRITE_IMAPS;
- /*
- * Ensure we don't go beyond eof - it is possible
- * the extents changed since we did the read call,
- * we dropped the ilock in the interim.
- */
-
- end_fsb = XFS_B_TO_FSB(mp, ip->i_d.di_size);
- xfs_bmap_last_offset(NULL, ip, &last_block,
- XFS_DATA_FORK);
- last_block = XFS_FILEOFF_MAX(last_block, end_fsb);
- if ((map_start_fsb + count_fsb) > last_block) {
- count_fsb = last_block - map_start_fsb;
- if (count_fsb == 0) {
- error = EAGAIN;
- goto trans_cancel;
- }
- }
-
- /* Go get the actual blocks */
- error = XFS_BMAPI(mp, tp, io, map_start_fsb, count_fsb,
- XFS_BMAPI_WRITE, &first_block, 1,
- imap, &nimaps, &free_list, NULL);
- if (error)
- goto trans_cancel;
-
- error = xfs_bmap_finish(&tp, &free_list,
- first_block, &committed);
- if (error)
- goto trans_cancel;
-
- error = xfs_trans_commit(tp,
- XFS_TRANS_RELEASE_LOG_RES, NULL);
- if (error)
- goto error0;
-
- xfs_iunlock(ip, XFS_ILOCK_EXCL);
- }
-
- /*
- * See if we were able to allocate an extent that
- * covers at least part of the callers request
- */
-
- for (i = 0; i < nimaps; i++) {
- if (!(io->io_flags & XFS_IOCORE_RT) &&
- !imap[i].br_startblock) {
- cmn_err(CE_PANIC,"Access to block zero: "
- "fs <%s> inode: %lld "
- "start_block : %llx start_off : %llx "
- "blkcnt : %llx extent-state : %x \n",
- (ip->i_mount)->m_fsname,
- (long long)ip->i_ino,
- (unsigned long long)
- imap[i].br_startblock,
- (unsigned long long)
- imap[i].br_startoff,
- (unsigned long long)
- imap[i].br_blockcount,
- imap[i].br_state);
- }
- if ((offset_fsb >= imap[i].br_startoff) &&
- (offset_fsb < (imap[i].br_startoff +
- imap[i].br_blockcount))) {
- *map = imap[i];
- *retmap = 1;
- XFS_STATS_INC(xs_xstrat_quick);
- return 0;
- }
- count_fsb -= imap[i].br_blockcount;
- }
-
- /* So far we have not mapped the requested part of the
- * file, just surrounding data, try again.
- */
- nimaps--;
- map_start_fsb = imap[nimaps].br_startoff +
- imap[nimaps].br_blockcount;
- }
-
-trans_cancel:
- xfs_bmap_cancel(&free_list);
- xfs_trans_cancel(tp, XFS_TRANS_RELEASE_LOG_RES | XFS_TRANS_ABORT);
-error0:
- xfs_iunlock(ip, XFS_ILOCK_EXCL);
- return XFS_ERROR(error);
-}
-
-int
-xfs_iomap_write_unwritten(
- xfs_inode_t *ip,
- xfs_off_t offset,
- size_t count)
-{
- xfs_mount_t *mp = ip->i_mount;
- xfs_iocore_t *io = &ip->i_iocore;
- xfs_fileoff_t offset_fsb;
- xfs_filblks_t count_fsb;
- xfs_filblks_t numblks_fsb;
- xfs_fsblock_t firstfsb;
- int nimaps;
- xfs_trans_t *tp;
- xfs_bmbt_irec_t imap;
- xfs_bmap_free_t free_list;
- uint resblks;
- int committed;
- int error;
-
- xfs_iomap_enter_trace(XFS_IOMAP_UNWRITTEN,
- &ip->i_iocore, offset, count);
-
- offset_fsb = XFS_B_TO_FSBT(mp, offset);
- count_fsb = XFS_B_TO_FSB(mp, (xfs_ufsize_t)offset + count);
- count_fsb = (xfs_filblks_t)(count_fsb - offset_fsb);
-
- resblks = XFS_DIOSTRAT_SPACE_RES(mp, 0) << 1;
-
- do {
- /*
- * set up a transaction to convert the range of extents
- * from unwritten to real. Do allocations in a loop until
- * we have covered the range passed in.
- */
-
- tp = xfs_trans_alloc(mp, XFS_TRANS_STRAT_WRITE);
- error = xfs_trans_reserve(tp, resblks,
- XFS_WRITE_LOG_RES(mp), 0,
- XFS_TRANS_PERM_LOG_RES,
- XFS_WRITE_LOG_COUNT);
- if (error) {
- xfs_trans_cancel(tp, 0);
- goto error0;
- }
-
- xfs_ilock(ip, XFS_ILOCK_EXCL);
- xfs_trans_ijoin(tp, ip, XFS_ILOCK_EXCL);
- xfs_trans_ihold(tp, ip);
-
- /*
- * Modify the unwritten extent state of the buffer.
- */
- XFS_BMAP_INIT(&free_list, &firstfsb);
- nimaps = 1;
- error = XFS_BMAPI(mp, tp, io, offset_fsb, count_fsb,
- XFS_BMAPI_WRITE|XFS_BMAPI_CONVERT, &firstfsb,
- 1, &imap, &nimaps, &free_list, NULL);
- if (error)
- goto error_on_bmapi_transaction;
-
- error = xfs_bmap_finish(&(tp), &(free_list),
- firstfsb, &committed);
- if (error)
- goto error_on_bmapi_transaction;
-
- error = xfs_trans_commit(tp, XFS_TRANS_RELEASE_LOG_RES, NULL);
- xfs_iunlock(ip, XFS_ILOCK_EXCL);
- if (error)
- goto error0;
-
- if ( !(io->io_flags & XFS_IOCORE_RT) && !imap.br_startblock) {
- cmn_err(CE_PANIC,"Access to block zero: fs <%s> "
- "inode: %lld start_block : %llx start_off : "
- "%llx blkcnt : %llx extent-state : %x \n",
- (ip->i_mount)->m_fsname,
- (long long)ip->i_ino,
- (unsigned long long)imap.br_startblock,
- (unsigned long long)imap.br_startoff,
- (unsigned long long)imap.br_blockcount,
- imap.br_state);
- }
-
- if ((numblks_fsb = imap.br_blockcount) == 0) {
- /*
- * The numblks_fsb value should always get
- * smaller, otherwise the loop is stuck.
- */
- ASSERT(imap.br_blockcount);
- break;
- }
- offset_fsb += numblks_fsb;
- count_fsb -= numblks_fsb;
- } while (count_fsb > 0);
-
- return 0;
-
-error_on_bmapi_transaction:
- xfs_bmap_cancel(&free_list);
- xfs_trans_cancel(tp, (XFS_TRANS_RELEASE_LOG_RES | XFS_TRANS_ABORT));
- xfs_iunlock(ip, XFS_ILOCK_EXCL);
-error0:
- return XFS_ERROR(error);
-}
diff --git a/sys/gnu/fs/xfs/xfs_iomap.h b/sys/gnu/fs/xfs/xfs_iomap.h
deleted file mode 100644
index 3ce204a..0000000
--- a/sys/gnu/fs/xfs/xfs_iomap.h
+++ /dev/null
@@ -1,90 +0,0 @@
-/*
- * Copyright (c) 2003-2005 Silicon Graphics, Inc.
- * All Rights Reserved.
- *
- * 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.
- *
- * This program is distributed in the hope that it would 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 the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- */
-#ifndef __XFS_IOMAP_H__
-#define __XFS_IOMAP_H__
-
-#define IOMAP_DADDR_NULL ((xfs_daddr_t) (-1LL))
-
-
-typedef enum { /* iomap_flags values */
- IOMAP_EOF = 0x01, /* mapping contains EOF */
- IOMAP_HOLE = 0x02, /* mapping covers a hole */
- IOMAP_DELAY = 0x04, /* mapping covers delalloc region */
- IOMAP_REALTIME = 0x10, /* mapping on the realtime device */
- IOMAP_UNWRITTEN = 0x20, /* mapping covers allocated */
- /* but uninitialized file data */
- IOMAP_NEW = 0x40 /* just allocate */
-} iomap_flags_t;
-
-typedef enum {
- /* base extent manipulation calls */
- BMAPI_READ = (1 << 0), /* read extents */
- BMAPI_WRITE = (1 << 1), /* create extents */
- BMAPI_ALLOCATE = (1 << 2), /* delayed allocate to real extents */
- BMAPI_UNWRITTEN = (1 << 3), /* unwritten extents to real extents */
- /* modifiers */
- BMAPI_IGNSTATE = (1 << 4), /* ignore unwritten state on read */
- BMAPI_DIRECT = (1 << 5), /* direct instead of buffered write */
- BMAPI_MMAP = (1 << 6), /* allocate for mmap write */
- BMAPI_SYNC = (1 << 7), /* sync write to flush delalloc space */
- BMAPI_TRYLOCK = (1 << 8), /* non-blocking request */
- BMAPI_DEVICE = (1 << 9), /* we only want to know the device */
-} bmapi_flags_t;
-
-
-/*
- * xfs_iomap_t: File system I/O map
- *
- * The iomap_bn field is expressed in 512-byte blocks, and is where the
- * mapping starts on disk.
- *
- * The iomap_offset, iomap_bsize and iomap_delta fields are in bytes.
- * iomap_offset is the offset of the mapping in the file itself.
- * iomap_bsize is the size of the mapping, iomap_delta is the
- * desired data's offset into the mapping, given the offset supplied
- * to the file I/O map routine.
- *
- * When a request is made to read beyond the logical end of the object,
- * iomap_size may be set to 0, but iomap_offset and iomap_length should be set
- * to the actual amount of underlying storage that has been allocated, if any.
- */
-
-typedef struct xfs_iomap {
- xfs_daddr_t iomap_bn; /* first 512b blk of mapping */
- xfs_buftarg_t *iomap_target;
- xfs_off_t iomap_offset; /* offset of mapping, bytes */
- xfs_off_t iomap_bsize; /* size of mapping, bytes */
- xfs_off_t iomap_delta; /* offset into mapping, bytes */
- iomap_flags_t iomap_flags;
-} xfs_iomap_t;
-
-struct xfs_iocore;
-struct xfs_inode;
-struct xfs_bmbt_irec;
-
-extern int xfs_iomap(struct xfs_iocore *, xfs_off_t, ssize_t, int,
- struct xfs_iomap *, int *);
-extern int xfs_iomap_write_direct(struct xfs_inode *, xfs_off_t, size_t,
- int, struct xfs_bmbt_irec *, int *, int);
-extern int xfs_iomap_write_delay(struct xfs_inode *, xfs_off_t, size_t, int,
- struct xfs_bmbt_irec *, int *);
-extern int xfs_iomap_write_allocate(struct xfs_inode *, xfs_off_t, size_t,
- struct xfs_bmbt_irec *, int *);
-extern int xfs_iomap_write_unwritten(struct xfs_inode *, xfs_off_t, size_t);
-
-#endif /* __XFS_IOMAP_H__*/
diff --git a/sys/gnu/fs/xfs/xfs_itable.c b/sys/gnu/fs/xfs/xfs_itable.c
deleted file mode 100644
index b8f9f6f..0000000
--- a/sys/gnu/fs/xfs/xfs_itable.c
+++ /dev/null
@@ -1,848 +0,0 @@
-/*
- * Copyright (c) 2000-2002,2005 Silicon Graphics, Inc.
- * All Rights Reserved.
- *
- * 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.
- *
- * This program is distributed in the hope that it would 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 the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- */
-#include "xfs.h"
-#include "xfs_fs.h"
-#include "xfs_types.h"
-#include "xfs_bit.h"
-#include "xfs_log.h"
-#include "xfs_inum.h"
-#include "xfs_trans.h"
-#include "xfs_sb.h"
-#include "xfs_ag.h"
-#include "xfs_dir.h"
-#include "xfs_dir2.h"
-#include "xfs_dmapi.h"
-#include "xfs_mount.h"
-#include "xfs_bmap_btree.h"
-#include "xfs_alloc_btree.h"
-#include "xfs_ialloc_btree.h"
-#include "xfs_dir_sf.h"
-#include "xfs_dir2_sf.h"
-#include "xfs_attr_sf.h"
-#include "xfs_dinode.h"
-#include "xfs_inode.h"
-#include "xfs_ialloc.h"
-#include "xfs_itable.h"
-#include "xfs_error.h"
-#include "xfs_btree.h"
-
-#ifndef HAVE_USERACC
-#define useracc(ubuffer, size, flags, foo) (0)
-#define unuseracc(ubuffer, size, flags)
-#endif
-
-STATIC int
-xfs_bulkstat_one_iget(
- xfs_mount_t *mp, /* mount point for filesystem */
- xfs_ino_t ino, /* inode number to get data for */
- xfs_daddr_t bno, /* starting bno of inode cluster */
- xfs_bstat_t *buf, /* return buffer */
- int *stat) /* BULKSTAT_RV_... */
-{
- xfs_dinode_core_t *dic; /* dinode core info pointer */
- xfs_inode_t *ip; /* incore inode pointer */
- xfs_vnode_t *vp;
- int error;
-
- error = xfs_iget(mp, NULL, ino, 0, XFS_ILOCK_SHARED, &ip, bno);
- if (error) {
- *stat = BULKSTAT_RV_NOTHING;
- return error;
- }
-
- ASSERT(ip != NULL);
- ASSERT(ip->i_blkno != (xfs_daddr_t)0);
- if (ip->i_d.di_mode == 0) {
- *stat = BULKSTAT_RV_NOTHING;
- error = XFS_ERROR(ENOENT);
- goto out_iput;
- }
-
- vp = XFS_ITOV(ip);
- dic = &ip->i_d;
-
- /* xfs_iget returns the following without needing
- * further change.
- */
- buf->bs_nlink = dic->di_nlink;
- buf->bs_projid = dic->di_projid;
- buf->bs_ino = ino;
- buf->bs_mode = dic->di_mode;
- buf->bs_uid = dic->di_uid;
- buf->bs_gid = dic->di_gid;
- buf->bs_size = dic->di_size;
- vn_atime_to_bstime(vp, &buf->bs_atime);
- buf->bs_mtime.tv_sec = dic->di_mtime.t_sec;
- buf->bs_mtime.tv_nsec = dic->di_mtime.t_nsec;
- buf->bs_ctime.tv_sec = dic->di_ctime.t_sec;
- buf->bs_ctime.tv_nsec = dic->di_ctime.t_nsec;
- buf->bs_xflags = xfs_ip2xflags(ip);
- buf->bs_extsize = dic->di_extsize << mp->m_sb.sb_blocklog;
- buf->bs_extents = dic->di_nextents;
- buf->bs_gen = dic->di_gen;
- memset(buf->bs_pad, 0, sizeof(buf->bs_pad));
- buf->bs_dmevmask = dic->di_dmevmask;
- buf->bs_dmstate = dic->di_dmstate;
- buf->bs_aextents = dic->di_anextents;
-
- switch (dic->di_format) {
- case XFS_DINODE_FMT_DEV:
- buf->bs_rdev = ip->i_df.if_u2.if_rdev;
- buf->bs_blksize = BLKDEV_IOSIZE;
- buf->bs_blocks = 0;
- break;
- case XFS_DINODE_FMT_LOCAL:
- case XFS_DINODE_FMT_UUID:
- buf->bs_rdev = 0;
- buf->bs_blksize = mp->m_sb.sb_blocksize;
- buf->bs_blocks = 0;
- break;
- case XFS_DINODE_FMT_EXTENTS:
- case XFS_DINODE_FMT_BTREE:
- buf->bs_rdev = 0;
- buf->bs_blksize = mp->m_sb.sb_blocksize;
- buf->bs_blocks = dic->di_nblocks + ip->i_delayed_blks;
- break;
- }
-
- out_iput:
- xfs_iput(ip, XFS_ILOCK_SHARED);
- return error;
-}
-
-STATIC int
-xfs_bulkstat_one_dinode(
- xfs_mount_t *mp, /* mount point for filesystem */
- xfs_ino_t ino, /* inode number to get data for */
- xfs_dinode_t *dip, /* dinode inode pointer */
- xfs_bstat_t *buf) /* return buffer */
-{
- xfs_dinode_core_t *dic; /* dinode core info pointer */
-
- dic = &dip->di_core;
-
- /*
- * The inode format changed when we moved the link count and
- * made it 32 bits long. If this is an old format inode,
- * convert it in memory to look like a new one. If it gets
- * flushed to disk we will convert back before flushing or
- * logging it. We zero out the new projid field and the old link
- * count field. We'll handle clearing the pad field (the remains
- * of the old uuid field) when we actually convert the inode to
- * the new format. We don't change the version number so that we
- * can distinguish this from a real new format inode.
- */
- if (INT_GET(dic->di_version, ARCH_CONVERT) == XFS_DINODE_VERSION_1) {
- buf->bs_nlink = INT_GET(dic->di_onlink, ARCH_CONVERT);
- buf->bs_projid = 0;
- } else {
- buf->bs_nlink = INT_GET(dic->di_nlink, ARCH_CONVERT);
- buf->bs_projid = INT_GET(dic->di_projid, ARCH_CONVERT);
- }
-
- buf->bs_ino = ino;
- buf->bs_mode = INT_GET(dic->di_mode, ARCH_CONVERT);
- buf->bs_uid = INT_GET(dic->di_uid, ARCH_CONVERT);
- buf->bs_gid = INT_GET(dic->di_gid, ARCH_CONVERT);
- buf->bs_size = INT_GET(dic->di_size, ARCH_CONVERT);
- buf->bs_atime.tv_sec = INT_GET(dic->di_atime.t_sec, ARCH_CONVERT);
- buf->bs_atime.tv_nsec = INT_GET(dic->di_atime.t_nsec, ARCH_CONVERT);
- buf->bs_mtime.tv_sec = INT_GET(dic->di_mtime.t_sec, ARCH_CONVERT);
- buf->bs_mtime.tv_nsec = INT_GET(dic->di_mtime.t_nsec, ARCH_CONVERT);
- buf->bs_ctime.tv_sec = INT_GET(dic->di_ctime.t_sec, ARCH_CONVERT);
- buf->bs_ctime.tv_nsec = INT_GET(dic->di_ctime.t_nsec, ARCH_CONVERT);
- buf->bs_xflags = xfs_dic2xflags(dic);
- buf->bs_extsize = INT_GET(dic->di_extsize, ARCH_CONVERT) << mp->m_sb.sb_blocklog;
- buf->bs_extents = INT_GET(dic->di_nextents, ARCH_CONVERT);
- buf->bs_gen = INT_GET(dic->di_gen, ARCH_CONVERT);
- memset(buf->bs_pad, 0, sizeof(buf->bs_pad));
- buf->bs_dmevmask = INT_GET(dic->di_dmevmask, ARCH_CONVERT);
- buf->bs_dmstate = INT_GET(dic->di_dmstate, ARCH_CONVERT);
- buf->bs_aextents = INT_GET(dic->di_anextents, ARCH_CONVERT);
-
- switch (INT_GET(dic->di_format, ARCH_CONVERT)) {
- case XFS_DINODE_FMT_DEV:
- buf->bs_rdev = INT_GET(dip->di_u.di_dev, ARCH_CONVERT);
- buf->bs_blksize = BLKDEV_IOSIZE;
- buf->bs_blocks = 0;
- break;
- case XFS_DINODE_FMT_LOCAL:
- case XFS_DINODE_FMT_UUID:
- buf->bs_rdev = 0;
- buf->bs_blksize = mp->m_sb.sb_blocksize;
- buf->bs_blocks = 0;
- break;
- case XFS_DINODE_FMT_EXTENTS:
- case XFS_DINODE_FMT_BTREE:
- buf->bs_rdev = 0;
- buf->bs_blksize = mp->m_sb.sb_blocksize;
- buf->bs_blocks = INT_GET(dic->di_nblocks, ARCH_CONVERT);
- break;
- }
-
- return 0;
-}
-
-/*
- * Return stat information for one inode.
- * Return 0 if ok, else errno.
- */
-int /* error status */
-xfs_bulkstat_one(
- xfs_mount_t *mp, /* mount point for filesystem */
- xfs_ino_t ino, /* inode number to get data for */
- void __user *buffer, /* buffer to place output in */
- int ubsize, /* size of buffer */
- void *private_data, /* my private data */
- xfs_daddr_t bno, /* starting bno of inode cluster */
- int *ubused, /* bytes used by me */
- void *dibuff, /* on-disk inode buffer */
- int *stat) /* BULKSTAT_RV_... */
-{
- xfs_bstat_t *buf; /* return buffer */
- int error = 0; /* error value */
- xfs_dinode_t *dip; /* dinode inode pointer */
-
- dip = (xfs_dinode_t *)dibuff;
-
- if (!buffer || ino == mp->m_sb.sb_rbmino || ino == mp->m_sb.sb_rsumino ||
- (XFS_SB_VERSION_HASQUOTA(&mp->m_sb) &&
- (ino == mp->m_sb.sb_uquotino || ino == mp->m_sb.sb_gquotino))) {
- *stat = BULKSTAT_RV_NOTHING;
- return XFS_ERROR(EINVAL);
- }
- if (ubsize < sizeof(*buf)) {
- *stat = BULKSTAT_RV_NOTHING;
- return XFS_ERROR(ENOMEM);
- }
-
- buf = kmem_alloc(sizeof(*buf), KM_SLEEP);
-
- if (dip == NULL) {
- /* We're not being passed a pointer to a dinode. This happens
- * if BULKSTAT_FG_IGET is selected. Do the iget.
- */
- error = xfs_bulkstat_one_iget(mp, ino, bno, buf, stat);
- if (error)
- goto out_free;
- } else {
- xfs_bulkstat_one_dinode(mp, ino, dip, buf);
- }
-
- if (copy_to_user(buffer, buf, sizeof(*buf))) {
- *stat = BULKSTAT_RV_NOTHING;
- error = EFAULT;
- goto out_free;
- }
-
- *stat = BULKSTAT_RV_DIDONE;
- if (ubused)
- *ubused = sizeof(*buf);
-
- out_free:
- kmem_free(buf, sizeof(*buf));
- return error;
-}
-
-/*
- * Return stat information in bulk (by-inode) for the filesystem.
- */
-int /* error status */
-xfs_bulkstat(
- xfs_mount_t *mp, /* mount point for filesystem */
- xfs_ino_t *lastinop, /* last inode returned */
- int *ubcountp, /* size of buffer/count returned */
- bulkstat_one_pf formatter, /* func that'd fill a single buf */
- void *private_data,/* private data for formatter */
- size_t statstruct_size, /* sizeof struct filling */
- char __user *ubuffer, /* buffer with inode stats */
- int flags, /* defined in xfs_itable.h */
- int *done) /* 1 if there are more stats to get */
-{
- xfs_agblock_t agbno=0;/* allocation group block number */
- xfs_buf_t *agbp; /* agi header buffer */
- xfs_agi_t *agi; /* agi header data */
- xfs_agino_t agino; /* inode # in allocation group */
- xfs_agnumber_t agno; /* allocation group number */
- xfs_daddr_t bno; /* inode cluster start daddr */
- int chunkidx; /* current index into inode chunk */
- int clustidx; /* current index into inode cluster */
- xfs_btree_cur_t *cur; /* btree cursor for ialloc btree */
- int end_of_ag; /* set if we've seen the ag end */
- int error; /* error code */
- int fmterror;/* bulkstat formatter result */
- __int32_t gcnt; /* current btree rec's count */
- xfs_inofree_t gfree; /* current btree rec's free mask */
- xfs_agino_t gino; /* current btree rec's start inode */
- int i; /* loop index */
- int icount; /* count of inodes good in irbuf */
- xfs_ino_t ino; /* inode number (filesystem) */
- xfs_inobt_rec_t *irbp; /* current irec buffer pointer */
- xfs_inobt_rec_t *irbuf; /* start of irec buffer */
- xfs_inobt_rec_t *irbufend; /* end of good irec buffer entries */
- xfs_ino_t lastino=0; /* last inode number returned */
- int nbcluster; /* # of blocks in a cluster */
- int nicluster; /* # of inodes in a cluster */
- int nimask; /* mask for inode clusters */
- int nirbuf; /* size of irbuf */
- int rval; /* return value error code */
- int tmp; /* result value from btree calls */
- int ubcount; /* size of user's buffer */
- int ubleft; /* bytes left in user's buffer */
- char __user *ubufp; /* pointer into user's buffer */
- int ubelem; /* spaces used in user's buffer */
- int ubused; /* bytes used by formatter */
- xfs_buf_t *bp; /* ptr to on-disk inode cluster buf */
- xfs_dinode_t *dip; /* ptr into bp for specific inode */
- xfs_inode_t *ip; /* ptr to in-core inode struct */
-
- /*
- * Get the last inode value, see if there's nothing to do.
- */
- ino = (xfs_ino_t)*lastinop;
- dip = NULL;
- agno = XFS_INO_TO_AGNO(mp, ino);
- agino = XFS_INO_TO_AGINO(mp, ino);
- if (agno >= mp->m_sb.sb_agcount ||
- ino != XFS_AGINO_TO_INO(mp, agno, agino)) {
- *done = 1;
- *ubcountp = 0;
- return 0;
- }
- ubcount = *ubcountp; /* statstruct's */
- ubleft = ubcount * statstruct_size; /* bytes */
- *ubcountp = ubelem = 0;
- *done = 0;
- fmterror = 0;
- ubufp = ubuffer;
- nicluster = mp->m_sb.sb_blocksize >= XFS_INODE_CLUSTER_SIZE(mp) ?
- mp->m_sb.sb_inopblock :
- (XFS_INODE_CLUSTER_SIZE(mp) >> mp->m_sb.sb_inodelog);
- nimask = ~(nicluster - 1);
- nbcluster = nicluster >> mp->m_sb.sb_inopblog;
- /*
- * Lock down the user's buffer. If a buffer was not sent, as in the case
- * disk quota code calls here, we skip this.
- */
- if (ubuffer &&
- (error = useracc(ubuffer, ubcount * statstruct_size,
- (B_READ|B_PHYS), NULL))) {
- return error;
- }
- /*
- * Allocate a page-sized buffer for inode btree records.
- * We could try allocating something smaller, but for normal
- * calls we'll always (potentially) need the whole page.
- */
- irbuf = kmem_alloc(NBPC, KM_SLEEP);
- nirbuf = NBPC / sizeof(*irbuf);
- /*
- * Loop over the allocation groups, starting from the last
- * inode returned; 0 means start of the allocation group.
- */
- rval = 0;
- while (ubleft >= statstruct_size && agno < mp->m_sb.sb_agcount) {
- bp = NULL;
- down_read(&mp->m_peraglock);
- error = xfs_ialloc_read_agi(mp, NULL, agno, &agbp);
- up_read(&mp->m_peraglock);
- if (error) {
- /*
- * Skip this allocation group and go to the next one.
- */
- agno++;
- agino = 0;
- continue;
- }
- agi = XFS_BUF_TO_AGI(agbp);
- /*
- * Allocate and initialize a btree cursor for ialloc btree.
- */
- cur = xfs_btree_init_cursor(mp, NULL, agbp, agno, XFS_BTNUM_INO,
- (xfs_inode_t *)0, 0);
- irbp = irbuf;
- irbufend = irbuf + nirbuf;
- end_of_ag = 0;
- /*
- * If we're returning in the middle of an allocation group,
- * we need to get the remainder of the chunk we're in.
- */
- if (agino > 0) {
- /*
- * Lookup the inode chunk that this inode lives in.
- */
- error = xfs_inobt_lookup_le(cur, agino, 0, 0, &tmp);
- if (!error && /* no I/O error */
- tmp && /* lookup succeeded */
- /* got the record, should always work */
- !(error = xfs_inobt_get_rec(cur, &gino, &gcnt,
- &gfree, &i)) &&
- i == 1 &&
- /* this is the right chunk */
- agino < gino + XFS_INODES_PER_CHUNK &&
- /* lastino was not last in chunk */
- (chunkidx = agino - gino + 1) <
- XFS_INODES_PER_CHUNK &&
- /* there are some left allocated */
- XFS_INOBT_MASKN(chunkidx,
- XFS_INODES_PER_CHUNK - chunkidx) & ~gfree) {
- /*
- * Grab the chunk record. Mark all the
- * uninteresting inodes (because they're
- * before our start point) free.
- */
- for (i = 0; i < chunkidx; i++) {
- if (XFS_INOBT_MASK(i) & ~gfree)
- gcnt++;
- }
- gfree |= XFS_INOBT_MASKN(0, chunkidx);
- INT_SET(irbp->ir_startino, ARCH_CONVERT, gino);
- INT_SET(irbp->ir_freecount, ARCH_CONVERT, gcnt);
- INT_SET(irbp->ir_free, ARCH_CONVERT, gfree);
- irbp++;
- agino = gino + XFS_INODES_PER_CHUNK;
- icount = XFS_INODES_PER_CHUNK - gcnt;
- } else {
- /*
- * If any of those tests failed, bump the
- * inode number (just in case).
- */
- agino++;
- icount = 0;
- }
- /*
- * In any case, increment to the next record.
- */
- if (!error)
- error = xfs_inobt_increment(cur, 0, &tmp);
- } else {
- /*
- * Start of ag. Lookup the first inode chunk.
- */
- error = xfs_inobt_lookup_ge(cur, 0, 0, 0, &tmp);
- icount = 0;
- }
- /*
- * Loop through inode btree records in this ag,
- * until we run out of inodes or space in the buffer.
- */
- while (irbp < irbufend && icount < ubcount) {
- /*
- * Loop as long as we're unable to read the
- * inode btree.
- */
- while (error) {
- agino += XFS_INODES_PER_CHUNK;
- if (XFS_AGINO_TO_AGBNO(mp, agino) >=
- be32_to_cpu(agi->agi_length))
- break;
- error = xfs_inobt_lookup_ge(cur, agino, 0, 0,
- &tmp);
- }
- /*
- * If ran off the end of the ag either with an error,
- * or the normal way, set end and stop collecting.
- */
- if (error ||
- (error = xfs_inobt_get_rec(cur, &gino, &gcnt,
- &gfree, &i)) ||
- i == 0) {
- end_of_ag = 1;
- break;
- }
- /*
- * If this chunk has any allocated inodes, save it.
- */
- if (gcnt < XFS_INODES_PER_CHUNK) {
- INT_SET(irbp->ir_startino, ARCH_CONVERT, gino);
- INT_SET(irbp->ir_freecount, ARCH_CONVERT, gcnt);
- INT_SET(irbp->ir_free, ARCH_CONVERT, gfree);
- irbp++;
- icount += XFS_INODES_PER_CHUNK - gcnt;
- }
- /*
- * Set agino to after this chunk and bump the cursor.
- */
- agino = gino + XFS_INODES_PER_CHUNK;
- error = xfs_inobt_increment(cur, 0, &tmp);
- }
- /*
- * Drop the btree buffers and the agi buffer.
- * We can't hold any of the locks these represent
- * when calling iget.
- */
- xfs_btree_del_cursor(cur, XFS_BTREE_NOERROR);
- xfs_buf_relse(agbp);
- /*
- * Now format all the good inodes into the user's buffer.
- */
- irbufend = irbp;
- for (irbp = irbuf;
- irbp < irbufend && ubleft >= statstruct_size; irbp++) {
- /*
- * Read-ahead the next chunk's worth of inodes.
- */
- if (&irbp[1] < irbufend) {
- /*
- * Loop over all clusters in the next chunk.
- * Do a readahead if there are any allocated
- * inodes in that cluster.
- */
- for (agbno = XFS_AGINO_TO_AGBNO(mp,
- INT_GET(irbp[1].ir_startino, ARCH_CONVERT)),
- chunkidx = 0;
- chunkidx < XFS_INODES_PER_CHUNK;
- chunkidx += nicluster,
- agbno += nbcluster) {
- if (XFS_INOBT_MASKN(chunkidx,
- nicluster) &
- ~(INT_GET(irbp[1].ir_free, ARCH_CONVERT)))
- xfs_btree_reada_bufs(mp, agno,
- agbno, nbcluster);
- }
- }
- /*
- * Now process this chunk of inodes.
- */
- for (agino = INT_GET(irbp->ir_startino, ARCH_CONVERT), chunkidx = 0, clustidx = 0;
- ubleft > 0 &&
- INT_GET(irbp->ir_freecount, ARCH_CONVERT) < XFS_INODES_PER_CHUNK;
- chunkidx++, clustidx++, agino++) {
- ASSERT(chunkidx < XFS_INODES_PER_CHUNK);
- /*
- * Recompute agbno if this is the
- * first inode of the cluster.
- *
- * Careful with clustidx. There can be
- * multple clusters per chunk, a single
- * cluster per chunk or a cluster that has
- * inodes represented from several different
- * chunks (if blocksize is large).
- *
- * Because of this, the starting clustidx is
- * initialized to zero in this loop but must
- * later be reset after reading in the cluster
- * buffer.
- */
- if ((chunkidx & (nicluster - 1)) == 0) {
- agbno = XFS_AGINO_TO_AGBNO(mp,
- INT_GET(irbp->ir_startino, ARCH_CONVERT)) +
- ((chunkidx & nimask) >>
- mp->m_sb.sb_inopblog);
-
- if (flags & BULKSTAT_FG_QUICK) {
- ino = XFS_AGINO_TO_INO(mp, agno,
- agino);
- bno = XFS_AGB_TO_DADDR(mp, agno,
- agbno);
-
- /*
- * Get the inode cluster buffer
- */
- ASSERT(xfs_inode_zone != NULL);
- ip = kmem_zone_zalloc(xfs_inode_zone,
- KM_SLEEP);
- ip->i_ino = ino;
- ip->i_mount = mp;
- if (bp)
- xfs_buf_relse(bp);
- error = xfs_itobp(mp, NULL, ip,
- &dip, &bp, bno,
- XFS_IMAP_BULKSTAT);
- if (!error)
- clustidx = ip->i_boffset / mp->m_sb.sb_inodesize;
- kmem_zone_free(xfs_inode_zone, ip);
- if (XFS_TEST_ERROR(error != 0,
- mp, XFS_ERRTAG_BULKSTAT_READ_CHUNK,
- XFS_RANDOM_BULKSTAT_READ_CHUNK)) {
- bp = NULL;
- ubleft = 0;
- rval = error;
- break;
- }
- }
- }
- /*
- * Skip if this inode is free.
- */
- if (XFS_INOBT_MASK(chunkidx) & INT_GET(irbp->ir_free, ARCH_CONVERT))
- continue;
- /*
- * Count used inodes as free so we can tell
- * when the chunk is used up.
- */
- INT_MOD(irbp->ir_freecount, ARCH_CONVERT, +1);
- ino = XFS_AGINO_TO_INO(mp, agno, agino);
- bno = XFS_AGB_TO_DADDR(mp, agno, agbno);
- if (flags & BULKSTAT_FG_QUICK) {
- dip = (xfs_dinode_t *)xfs_buf_offset(bp,
- (clustidx << mp->m_sb.sb_inodelog));
-
- if (INT_GET(dip->di_core.di_magic, ARCH_CONVERT)
- != XFS_DINODE_MAGIC
- || !XFS_DINODE_GOOD_VERSION(
- INT_GET(dip->di_core.di_version, ARCH_CONVERT)))
- continue;
- }
-
- /*
- * Get the inode and fill in a single buffer.
- * BULKSTAT_FG_QUICK uses dip to fill it in.
- * BULKSTAT_FG_IGET uses igets.
- * See: xfs_bulkstat_one & xfs_dm_bulkstat_one.
- * This is also used to count inodes/blks, etc
- * in xfs_qm_quotacheck.
- */
- ubused = statstruct_size;
- error = formatter(mp, ino, ubufp,
- ubleft, private_data,
- bno, &ubused, dip, &fmterror);
- if (fmterror == BULKSTAT_RV_NOTHING) {
- if (error == ENOMEM)
- ubleft = 0;
- continue;
- }
- if (fmterror == BULKSTAT_RV_GIVEUP) {
- ubleft = 0;
- ASSERT(error);
- rval = error;
- break;
- }
- if (ubufp)
- ubufp += ubused;
- ubleft -= ubused;
- ubelem++;
- lastino = ino;
- }
- }
-
- if (bp)
- xfs_buf_relse(bp);
-
- /*
- * Set up for the next loop iteration.
- */
- if (ubleft > 0) {
- if (end_of_ag) {
- agno++;
- agino = 0;
- } else
- agino = XFS_INO_TO_AGINO(mp, lastino);
- } else
- break;
- }
- /*
- * Done, we're either out of filesystem or space to put the data.
- */
- kmem_free(irbuf, NBPC);
- if (ubuffer)
- unuseracc(ubuffer, ubcount * statstruct_size, (B_READ|B_PHYS));
- *ubcountp = ubelem;
- if (agno >= mp->m_sb.sb_agcount) {
- /*
- * If we ran out of filesystem, mark lastino as off
- * the end of the filesystem, so the next call
- * will return immediately.
- */
- *lastinop = (xfs_ino_t)XFS_AGINO_TO_INO(mp, agno, 0);
- *done = 1;
- } else
- *lastinop = (xfs_ino_t)lastino;
-
- return rval;
-}
-
-/*
- * Return stat information in bulk (by-inode) for the filesystem.
- * Special case for non-sequential one inode bulkstat.
- */
-int /* error status */
-xfs_bulkstat_single(
- xfs_mount_t *mp, /* mount point for filesystem */
- xfs_ino_t *lastinop, /* inode to return */
- char __user *buffer, /* buffer with inode stats */
- int *done) /* 1 if there are more stats to get */
-{
- int count; /* count value for bulkstat call */
- int error; /* return value */
- xfs_ino_t ino; /* filesystem inode number */
- int res; /* result from bs1 */
-
- /*
- * note that requesting valid inode numbers which are not allocated
- * to inodes will most likely cause xfs_itobp to generate warning
- * messages about bad magic numbers. This is ok. The fact that
- * the inode isn't actually an inode is handled by the
- * error check below. Done this way to make the usual case faster
- * at the expense of the error case.
- */
-
- ino = (xfs_ino_t)*lastinop;
- error = xfs_bulkstat_one(mp, ino, buffer, sizeof(xfs_bstat_t),
- NULL, 0, NULL, NULL, &res);
- if (error) {
- /*
- * Special case way failed, do it the "long" way
- * to see if that works.
- */
- (*lastinop)--;
- count = 1;
- if (xfs_bulkstat(mp, lastinop, &count, xfs_bulkstat_one,
- NULL, sizeof(xfs_bstat_t), buffer,
- BULKSTAT_FG_IGET, done))
- return error;
- if (count == 0 || (xfs_ino_t)*lastinop != ino)
- return error == EFSCORRUPTED ?
- XFS_ERROR(EINVAL) : error;
- else
- return 0;
- }
- *done = 0;
- return 0;
-}
-
-/*
- * Return inode number table for the filesystem.
- */
-int /* error status */
-xfs_inumbers(
- xfs_mount_t *mp, /* mount point for filesystem */
- xfs_ino_t *lastino, /* last inode returned */
- int *count, /* size of buffer/count returned */
- xfs_inogrp_t __user *ubuffer)/* buffer with inode descriptions */
-{
- xfs_buf_t *agbp;
- xfs_agino_t agino;
- xfs_agnumber_t agno;
- int bcount;
- xfs_inogrp_t *buffer;
- int bufidx;
- xfs_btree_cur_t *cur;
- int error;
- __int32_t gcnt;
- xfs_inofree_t gfree;
- xfs_agino_t gino;
- int i;
- xfs_ino_t ino;
- int left;
- int tmp;
-
- ino = (xfs_ino_t)*lastino;
- agno = XFS_INO_TO_AGNO(mp, ino);
- agino = XFS_INO_TO_AGINO(mp, ino);
- left = *count;
- *count = 0;
- bcount = MIN(left, (int)(NBPP / sizeof(*buffer)));
- buffer = kmem_alloc(bcount * sizeof(*buffer), KM_SLEEP);
- error = bufidx = 0;
- cur = NULL;
- agbp = NULL;
- while (left > 0 && agno < mp->m_sb.sb_agcount) {
- if (agbp == NULL) {
- down_read(&mp->m_peraglock);
- error = xfs_ialloc_read_agi(mp, NULL, agno, &agbp);
- up_read(&mp->m_peraglock);
- if (error) {
- /*
- * If we can't read the AGI of this ag,
- * then just skip to the next one.
- */
- ASSERT(cur == NULL);
- agbp = NULL;
- agno++;
- agino = 0;
- continue;
- }
- cur = xfs_btree_init_cursor(mp, NULL, agbp, agno,
- XFS_BTNUM_INO, (xfs_inode_t *)0, 0);
- error = xfs_inobt_lookup_ge(cur, agino, 0, 0, &tmp);
- if (error) {
- xfs_btree_del_cursor(cur, XFS_BTREE_ERROR);
- cur = NULL;
- xfs_buf_relse(agbp);
- agbp = NULL;
- /*
- * Move up the last inode in the current
- * chunk. The lookup_ge will always get
- * us the first inode in the next chunk.
- */
- agino += XFS_INODES_PER_CHUNK - 1;
- continue;
- }
- }
- if ((error = xfs_inobt_get_rec(cur, &gino, &gcnt, &gfree,
- &i)) ||
- i == 0) {
- xfs_buf_relse(agbp);
- agbp = NULL;
- xfs_btree_del_cursor(cur, XFS_BTREE_NOERROR);
- cur = NULL;
- agno++;
- agino = 0;
- continue;
- }
- agino = gino + XFS_INODES_PER_CHUNK - 1;
- buffer[bufidx].xi_startino = XFS_AGINO_TO_INO(mp, agno, gino);
- buffer[bufidx].xi_alloccount = XFS_INODES_PER_CHUNK - gcnt;
- buffer[bufidx].xi_allocmask = ~gfree;
- bufidx++;
- left--;
- if (bufidx == bcount) {
- if (copy_to_user(ubuffer, buffer,
- bufidx * sizeof(*buffer))) {
- error = XFS_ERROR(EFAULT);
- break;
- }
- ubuffer += bufidx;
- *count += bufidx;
- bufidx = 0;
- }
- if (left) {
- error = xfs_inobt_increment(cur, 0, &tmp);
- if (error) {
- xfs_btree_del_cursor(cur, XFS_BTREE_ERROR);
- cur = NULL;
- xfs_buf_relse(agbp);
- agbp = NULL;
- /*
- * The agino value has already been bumped.
- * Just try to skip up to it.
- */
- agino += XFS_INODES_PER_CHUNK;
- continue;
- }
- }
- }
- if (!error) {
- if (bufidx) {
- if (copy_to_user(ubuffer, buffer,
- bufidx * sizeof(*buffer)))
- error = XFS_ERROR(EFAULT);
- else
- *count += bufidx;
- }
- *lastino = XFS_AGINO_TO_INO(mp, agno, agino);
- }
- kmem_free(buffer, bcount * sizeof(*buffer));
- if (cur)
- xfs_btree_del_cursor(cur, (error ? XFS_BTREE_ERROR :
- XFS_BTREE_NOERROR));
- if (agbp)
- xfs_buf_relse(agbp);
- return error;
-}
diff --git a/sys/gnu/fs/xfs/xfs_itable.h b/sys/gnu/fs/xfs/xfs_itable.h
deleted file mode 100644
index 11eb4e1..0000000
--- a/sys/gnu/fs/xfs/xfs_itable.h
+++ /dev/null
@@ -1,91 +0,0 @@
-/*
- * Copyright (c) 2000-2001 Silicon Graphics, Inc. All Rights Reserved.
- *
- * 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.
- *
- * This program is distributed in the hope that it would 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 the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- */
-#ifndef __XFS_ITABLE_H__
-#define __XFS_ITABLE_H__
-
-/*
- * xfs_bulkstat() is used to fill in xfs_bstat structures as well as dm_stat
- * structures (by the dmi library). This is a pointer to a formatter function
- * that will iget the inode and fill in the appropriate structure.
- * see xfs_bulkstat_one() and xfs_dm_bulkstat_one() in dmapi_xfs.c
- */
-typedef int (*bulkstat_one_pf)(struct xfs_mount *mp,
- xfs_ino_t ino,
- void __user *buffer,
- int ubsize,
- void *private_data,
- xfs_daddr_t bno,
- int *ubused,
- void *dip,
- int *stat);
-
-/*
- * Values for stat return value.
- */
-#define BULKSTAT_RV_NOTHING 0
-#define BULKSTAT_RV_DIDONE 1
-#define BULKSTAT_RV_GIVEUP 2
-
-/*
- * Values for bulkstat flag argument.
- */
-#define BULKSTAT_FG_IGET 0x1 /* Go through the buffer cache */
-#define BULKSTAT_FG_QUICK 0x2 /* No iget, walk the dinode cluster */
-#define BULKSTAT_FG_VFSLOCKED 0x4 /* Already have vfs lock */
-
-/*
- * Return stat information in bulk (by-inode) for the filesystem.
- */
-int /* error status */
-xfs_bulkstat(
- xfs_mount_t *mp, /* mount point for filesystem */
- xfs_ino_t *lastino, /* last inode returned */
- int *count, /* size of buffer/count returned */
- bulkstat_one_pf formatter, /* func that'd fill a single buf */
- void *private_data, /* private data for formatter */
- size_t statstruct_size,/* sizeof struct that we're filling */
- char __user *ubuffer,/* buffer with inode stats */
- int flags, /* flag to control access method */
- int *done); /* 1 if there are more stats to get */
-
-int
-xfs_bulkstat_single(
- xfs_mount_t *mp,
- xfs_ino_t *lastinop,
- char __user *buffer,
- int *done);
-
-int
-xfs_bulkstat_one(
- xfs_mount_t *mp,
- xfs_ino_t ino,
- void __user *buffer,
- int ubsize,
- void *private_data,
- xfs_daddr_t bno,
- int *ubused,
- void *dibuff,
- int *stat);
-
-int /* error status */
-xfs_inumbers(
- xfs_mount_t *mp, /* mount point for filesystem */
- xfs_ino_t *last, /* last inode returned */
- int *count, /* size of buffer/count returned */
- xfs_inogrp_t __user *buffer);/* buffer with inode info */
-
-#endif /* __XFS_ITABLE_H__ */
diff --git a/sys/gnu/fs/xfs/xfs_log.c b/sys/gnu/fs/xfs/xfs_log.c
deleted file mode 100644
index 46c0d3d..0000000
--- a/sys/gnu/fs/xfs/xfs_log.c
+++ /dev/null
@@ -1,3708 +0,0 @@
-/*
- * Copyright (c) 2000-2005 Silicon Graphics, Inc.
- * All Rights Reserved.
- *
- * 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.
- *
- * This program is distributed in the hope that it would 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 the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- */
-#include "xfs.h"
-#include "xfs_fs.h"
-#include "xfs_types.h"
-#include "xfs_bit.h"
-#include "xfs_log.h"
-#include "xfs_inum.h"
-#include "xfs_trans.h"
-#include "xfs_sb.h"
-#include "xfs_ag.h"
-#include "xfs_dir.h"
-#include "xfs_dir2.h"
-#include "xfs_dmapi.h"
-#include "xfs_mount.h"
-#include "xfs_error.h"
-#include "xfs_log_priv.h"
-#include "xfs_buf_item.h"
-#include "xfs_bmap_btree.h"
-#include "xfs_alloc_btree.h"
-#include "xfs_ialloc_btree.h"
-#include "xfs_log_recover.h"
-#include "xfs_trans_priv.h"
-#include "xfs_dir_sf.h"
-#include "xfs_dir2_sf.h"
-#include "xfs_attr_sf.h"
-#include "xfs_dinode.h"
-#include "xfs_inode.h"
-#include "xfs_rw.h"
-
-
-#define xlog_write_adv_cnt(ptr, len, off, bytes) \
- { (ptr) += (bytes); \
- (len) -= (bytes); \
- (off) += (bytes);}
-
-/* Local miscellaneous function prototypes */
-STATIC int xlog_bdstrat_cb(struct xfs_buf *);
-STATIC int xlog_commit_record(xfs_mount_t *mp, xlog_ticket_t *ticket,
- xlog_in_core_t **, xfs_lsn_t *);
-STATIC xlog_t * xlog_alloc_log(xfs_mount_t *mp,
- xfs_buftarg_t *log_target,
- xfs_daddr_t blk_offset,
- int num_bblks);
-STATIC int xlog_space_left(xlog_t *log, int cycle, int bytes);
-STATIC int xlog_sync(xlog_t *log, xlog_in_core_t *iclog);
-STATIC void xlog_dealloc_log(xlog_t *log);
-STATIC int xlog_write(xfs_mount_t *mp, xfs_log_iovec_t region[],
- int nentries, xfs_log_ticket_t tic,
- xfs_lsn_t *start_lsn,
- xlog_in_core_t **commit_iclog,
- uint flags);
-
-/* local state machine functions */
-STATIC void xlog_state_done_syncing(xlog_in_core_t *iclog, int);
-STATIC void xlog_state_do_callback(xlog_t *log,int aborted, xlog_in_core_t *iclog);
-STATIC int xlog_state_get_iclog_space(xlog_t *log,
- int len,
- xlog_in_core_t **iclog,
- xlog_ticket_t *ticket,
- int *continued_write,
- int *logoffsetp);
-STATIC void xlog_state_put_ticket(xlog_t *log,
- xlog_ticket_t *tic);
-STATIC int xlog_state_release_iclog(xlog_t *log,
- xlog_in_core_t *iclog);
-STATIC void xlog_state_switch_iclogs(xlog_t *log,
- xlog_in_core_t *iclog,
- int eventual_size);
-STATIC int xlog_state_sync(xlog_t *log,
- xfs_lsn_t lsn,
- uint flags,
- int *log_flushed);
-STATIC int xlog_state_sync_all(xlog_t *log, uint flags, int *log_flushed);
-STATIC void xlog_state_want_sync(xlog_t *log, xlog_in_core_t *iclog);
-
-/* local functions to manipulate grant head */
-STATIC int xlog_grant_log_space(xlog_t *log,
- xlog_ticket_t *xtic);
-STATIC void xlog_grant_push_ail(xfs_mount_t *mp,
- int need_bytes);
-STATIC void xlog_regrant_reserve_log_space(xlog_t *log,
- xlog_ticket_t *ticket);
-STATIC int xlog_regrant_write_log_space(xlog_t *log,
- xlog_ticket_t *ticket);
-STATIC void xlog_ungrant_log_space(xlog_t *log,
- xlog_ticket_t *ticket);
-
-
-/* local ticket functions */
-STATIC void xlog_state_ticket_alloc(xlog_t *log);
-STATIC xlog_ticket_t *xlog_ticket_get(xlog_t *log,
- int unit_bytes,
- int count,
- char clientid,
- uint flags);
-STATIC void xlog_ticket_put(xlog_t *log, xlog_ticket_t *ticket);
-
-#if defined(DEBUG)
-STATIC void xlog_verify_dest_ptr(xlog_t *log, __psint_t ptr);
-STATIC void xlog_verify_grant_head(xlog_t *log, int equals);
-STATIC void xlog_verify_iclog(xlog_t *log, xlog_in_core_t *iclog,
- int count, boolean_t syncing);
-STATIC void xlog_verify_tail_lsn(xlog_t *log, xlog_in_core_t *iclog,
- xfs_lsn_t tail_lsn);
-#else
-#define xlog_verify_dest_ptr(a,b)
-#define xlog_verify_grant_head(a,b)
-#define xlog_verify_iclog(a,b,c,d)
-#define xlog_verify_tail_lsn(a,b,c)
-#endif
-
-STATIC int xlog_iclogs_empty(xlog_t *log);
-
-#if defined(XFS_LOG_TRACE)
-void
-xlog_trace_loggrant(xlog_t *log, xlog_ticket_t *tic, xfs_caddr_t string)
-{
- unsigned long cnts;
-
- if (!log->l_grant_trace) {
- log->l_grant_trace = ktrace_alloc(2048, KM_NOSLEEP);
- if (!log->l_grant_trace)
- return;
- }
- /* ticket counts are 1 byte each */
- cnts = ((unsigned long)tic->t_ocnt) | ((unsigned long)tic->t_cnt) << 8;
-
- ktrace_enter(log->l_grant_trace,
- (void *)tic,
- (void *)log->l_reserve_headq,
- (void *)log->l_write_headq,
- (void *)((unsigned long)log->l_grant_reserve_cycle),
- (void *)((unsigned long)log->l_grant_reserve_bytes),
- (void *)((unsigned long)log->l_grant_write_cycle),
- (void *)((unsigned long)log->l_grant_write_bytes),
- (void *)((unsigned long)log->l_curr_cycle),
- (void *)((unsigned long)log->l_curr_block),
- (void *)((unsigned long)CYCLE_LSN(log->l_tail_lsn)),
- (void *)((unsigned long)BLOCK_LSN(log->l_tail_lsn)),
- (void *)string,
- (void *)((unsigned long)tic->t_trans_type),
- (void *)cnts,
- (void *)((unsigned long)tic->t_curr_res),
- (void *)((unsigned long)tic->t_unit_res));
-}
-
-void
-xlog_trace_iclog(xlog_in_core_t *iclog, uint state)
-{
- if (!iclog->ic_trace)
- iclog->ic_trace = ktrace_alloc(256, KM_SLEEP);
- ktrace_enter(iclog->ic_trace,
- (void *)((unsigned long)state),
- (void *)((unsigned long)current_pid()),
- (void *)NULL, (void *)NULL, (void *)NULL, (void *)NULL,
- (void *)NULL, (void *)NULL, (void *)NULL, (void *)NULL,
- (void *)NULL, (void *)NULL, (void *)NULL, (void *)NULL,
- (void *)NULL, (void *)NULL);
-}
-#else
-#define xlog_trace_loggrant(log,tic,string)
-#define xlog_trace_iclog(iclog,state)
-#endif /* XFS_LOG_TRACE */
-
-
-static void
-xlog_ins_ticketq(struct xlog_ticket **qp, struct xlog_ticket *tic)
-{
- if (*qp) {
- tic->t_next = (*qp);
- tic->t_prev = (*qp)->t_prev;
- (*qp)->t_prev->t_next = tic;
- (*qp)->t_prev = tic;
- } else {
- tic->t_prev = tic->t_next = tic;
- *qp = tic;
- }
-
- tic->t_flags |= XLOG_TIC_IN_Q;
-}
-
-static void
-xlog_del_ticketq(struct xlog_ticket **qp, struct xlog_ticket *tic)
-{
- if (tic == tic->t_next) {
- *qp = NULL;
- } else {
- *qp = tic->t_next;
- tic->t_next->t_prev = tic->t_prev;
- tic->t_prev->t_next = tic->t_next;
- }
-
- tic->t_next = tic->t_prev = NULL;
- tic->t_flags &= ~XLOG_TIC_IN_Q;
-}
-
-static void
-xlog_grant_sub_space(struct log *log, int bytes)
-{
- log->l_grant_write_bytes -= bytes;
- if (log->l_grant_write_bytes < 0) {
- log->l_grant_write_bytes += log->l_logsize;
- log->l_grant_write_cycle--;
- }
-
- log->l_grant_reserve_bytes -= bytes;
- if ((log)->l_grant_reserve_bytes < 0) {
- log->l_grant_reserve_bytes += log->l_logsize;
- log->l_grant_reserve_cycle--;
- }
-
-}
-
-static void
-xlog_grant_add_space_write(struct log *log, int bytes)
-{
- log->l_grant_write_bytes += bytes;
- if (log->l_grant_write_bytes > log->l_logsize) {
- log->l_grant_write_bytes -= log->l_logsize;
- log->l_grant_write_cycle++;
- }
-}
-
-static void
-xlog_grant_add_space_reserve(struct log *log, int bytes)
-{
- log->l_grant_reserve_bytes += bytes;
- if (log->l_grant_reserve_bytes > log->l_logsize) {
- log->l_grant_reserve_bytes -= log->l_logsize;
- log->l_grant_reserve_cycle++;
- }
-}
-
-static inline void
-xlog_grant_add_space(struct log *log, int bytes)
-{
- xlog_grant_add_space_write(log, bytes);
- xlog_grant_add_space_reserve(log, bytes);
-}
-
-
-/*
- * NOTES:
- *
- * 1. currblock field gets updated at startup and after in-core logs
- * marked as with WANT_SYNC.
- */
-
-/*
- * This routine is called when a user of a log manager ticket is done with
- * the reservation. If the ticket was ever used, then a commit record for
- * the associated transaction is written out as a log operation header with
- * no data. The flag XLOG_TIC_INITED is set when the first write occurs with
- * a given ticket. If the ticket was one with a permanent reservation, then
- * a few operations are done differently. Permanent reservation tickets by
- * default don't release the reservation. They just commit the current
- * transaction with the belief that the reservation is still needed. A flag
- * must be passed in before permanent reservations are actually released.
- * When these type of tickets are not released, they need to be set into
- * the inited state again. By doing this, a start record will be written
- * out when the next write occurs.
- */
-xfs_lsn_t
-xfs_log_done(xfs_mount_t *mp,
- xfs_log_ticket_t xtic,
- void **iclog,
- uint flags)
-{
- xlog_t *log = mp->m_log;
- xlog_ticket_t *ticket = (xfs_log_ticket_t) xtic;
- xfs_lsn_t lsn = 0;
-
- if (XLOG_FORCED_SHUTDOWN(log) ||
- /*
- * If nothing was ever written, don't write out commit record.
- * If we get an error, just continue and give back the log ticket.
- */
- (((ticket->t_flags & XLOG_TIC_INITED) == 0) &&
- (xlog_commit_record(mp, ticket,
- (xlog_in_core_t **)iclog, &lsn)))) {
- lsn = (xfs_lsn_t) -1;
- if (ticket->t_flags & XLOG_TIC_PERM_RESERV) {
- flags |= XFS_LOG_REL_PERM_RESERV;
- }
- }
-
-
- if ((ticket->t_flags & XLOG_TIC_PERM_RESERV) == 0 ||
- (flags & XFS_LOG_REL_PERM_RESERV)) {
- /*
- * Release ticket if not permanent reservation or a specific
- * request has been made to release a permanent reservation.
- */
- xlog_trace_loggrant(log, ticket, "xfs_log_done: (non-permanent)");
- xlog_ungrant_log_space(log, ticket);
- xlog_state_put_ticket(log, ticket);
- } else {
- xlog_trace_loggrant(log, ticket, "xfs_log_done: (permanent)");
- xlog_regrant_reserve_log_space(log, ticket);
- }
-
- /* If this ticket was a permanent reservation and we aren't
- * trying to release it, reset the inited flags; so next time
- * we write, a start record will be written out.
- */
- if ((ticket->t_flags & XLOG_TIC_PERM_RESERV) &&
- (flags & XFS_LOG_REL_PERM_RESERV) == 0)
- ticket->t_flags |= XLOG_TIC_INITED;
-
- return lsn;
-} /* xfs_log_done */
-
-
-/*
- * Force the in-core log to disk. If flags == XFS_LOG_SYNC,
- * the force is done synchronously.
- *
- * Asynchronous forces are implemented by setting the WANT_SYNC
- * bit in the appropriate in-core log and then returning.
- *
- * Synchronous forces are implemented with a semaphore. All callers
- * to force a given lsn to disk will wait on a semaphore attached to the
- * specific in-core log. When given in-core log finally completes its
- * write to disk, that thread will wake up all threads waiting on the
- * semaphore.
- */
-int
-_xfs_log_force(
- xfs_mount_t *mp,
- xfs_lsn_t lsn,
- uint flags,
- int *log_flushed)
-{
- xlog_t *log = mp->m_log;
- int dummy;
-
- if (!log_flushed)
- log_flushed = &dummy;
-
- ASSERT(flags & XFS_LOG_FORCE);
-
- XFS_STATS_INC(xs_log_force);
-
- if (log->l_flags & XLOG_IO_ERROR)
- return XFS_ERROR(EIO);
- if (lsn == 0)
- return xlog_state_sync_all(log, flags, log_flushed);
- else
- return xlog_state_sync(log, lsn, flags, log_flushed);
-} /* xfs_log_force */
-
-/*
- * Attaches a new iclog I/O completion callback routine during
- * transaction commit. If the log is in error state, a non-zero
- * return code is handed back and the caller is responsible for
- * executing the callback at an appropriate time.
- */
-int
-xfs_log_notify(xfs_mount_t *mp, /* mount of partition */
- void *iclog_hndl, /* iclog to hang callback off */
- xfs_log_callback_t *cb)
-{
- xlog_t *log = mp->m_log;
- xlog_in_core_t *iclog = (xlog_in_core_t *)iclog_hndl;
- int abortflg, spl;
-
- cb->cb_next = NULL;
- spl = LOG_LOCK(log);
- abortflg = (iclog->ic_state & XLOG_STATE_IOERROR);
- if (!abortflg) {
- ASSERT_ALWAYS((iclog->ic_state == XLOG_STATE_ACTIVE) ||
- (iclog->ic_state == XLOG_STATE_WANT_SYNC));
- cb->cb_next = NULL;
- *(iclog->ic_callback_tail) = cb;
- iclog->ic_callback_tail = &(cb->cb_next);
- }
- LOG_UNLOCK(log, spl);
- return abortflg;
-} /* xfs_log_notify */
-
-int
-xfs_log_release_iclog(xfs_mount_t *mp,
- void *iclog_hndl)
-{
- xlog_t *log = mp->m_log;
- xlog_in_core_t *iclog = (xlog_in_core_t *)iclog_hndl;
-
- if (xlog_state_release_iclog(log, iclog)) {
- xfs_force_shutdown(mp, XFS_LOG_IO_ERROR);
- return EIO;
- }
-
- return 0;
-}
-
-/*
- * 1. Reserve an amount of on-disk log space and return a ticket corresponding
- * to the reservation.
- * 2. Potentially, push buffers at tail of log to disk.
- *
- * Each reservation is going to reserve extra space for a log record header.
- * When writes happen to the on-disk log, we don't subtract the length of the
- * log record header from any reservation. By wasting space in each
- * reservation, we prevent over allocation problems.
- */
-int
-xfs_log_reserve(xfs_mount_t *mp,
- int unit_bytes,
- int cnt,
- xfs_log_ticket_t *ticket,
- __uint8_t client,
- uint flags,
- uint t_type)
-{
- xlog_t *log = mp->m_log;
- xlog_ticket_t *internal_ticket;
- int retval = 0;
-
- ASSERT(client == XFS_TRANSACTION || client == XFS_LOG);
- ASSERT((flags & XFS_LOG_NOSLEEP) == 0);
-
- if (XLOG_FORCED_SHUTDOWN(log))
- return XFS_ERROR(EIO);
-
- XFS_STATS_INC(xs_try_logspace);
-
- if (*ticket != NULL) {
- ASSERT(flags & XFS_LOG_PERM_RESERV);
- internal_ticket = (xlog_ticket_t *)*ticket;
- xlog_trace_loggrant(log, internal_ticket, "xfs_log_reserve: existing ticket (permanent trans)");
- xlog_grant_push_ail(mp, internal_ticket->t_unit_res);
- retval = xlog_regrant_write_log_space(log, internal_ticket);
- } else {
- /* may sleep if need to allocate more tickets */
- internal_ticket = xlog_ticket_get(log, unit_bytes, cnt,
- client, flags);
- internal_ticket->t_trans_type = t_type;
- *ticket = internal_ticket;
- xlog_trace_loggrant(log, internal_ticket,
- (internal_ticket->t_flags & XLOG_TIC_PERM_RESERV) ?
- "xfs_log_reserve: create new ticket (permanent trans)" :
- "xfs_log_reserve: create new ticket");
- xlog_grant_push_ail(mp,
- (internal_ticket->t_unit_res *
- internal_ticket->t_cnt));
- retval = xlog_grant_log_space(log, internal_ticket);
- }
-
- return retval;
-} /* xfs_log_reserve */
-
-
-/*
- * Mount a log filesystem
- *
- * mp - ubiquitous xfs mount point structure
- * log_target - buftarg of on-disk log device
- * blk_offset - Start block # where block size is 512 bytes (BBSIZE)
- * num_bblocks - Number of BBSIZE blocks in on-disk log
- *
- * Return error or zero.
- */
-int
-xfs_log_mount(xfs_mount_t *mp,
- xfs_buftarg_t *log_target,
- xfs_daddr_t blk_offset,
- int num_bblks)
-{
- if (!(mp->m_flags & XFS_MOUNT_NORECOVERY))
- cmn_err(CE_NOTE, "XFS mounting filesystem %s", mp->m_fsname);
- else {
- cmn_err(CE_NOTE,
- "!Mounting filesystem \"%s\" in no-recovery mode. Filesystem will be inconsistent.",
- mp->m_fsname);
- ASSERT(XFS_MTOVFS(mp)->vfs_flag & VFS_RDONLY);
- }
-
- mp->m_log = xlog_alloc_log(mp, log_target, blk_offset, num_bblks);
-
- /*
- * skip log recovery on a norecovery mount. pretend it all
- * just worked.
- */
- if (!(mp->m_flags & XFS_MOUNT_NORECOVERY)) {
- int error;
- xfs_vfs_t *vfsp = XFS_MTOVFS(mp);
- int readonly = (vfsp->vfs_flag & VFS_RDONLY);
-
- if (readonly)
- vfsp->vfs_flag &= ~VFS_RDONLY;
-
- error = xlog_recover(mp->m_log);
-
- if (readonly)
- vfsp->vfs_flag |= VFS_RDONLY;
- if (error) {
- cmn_err(CE_WARN, "XFS: log mount/recovery failed: error %d", error);
- xlog_dealloc_log(mp->m_log);
- return error;
- }
- }
-
- /* Normal transactions can now occur */
- mp->m_log->l_flags &= ~XLOG_ACTIVE_RECOVERY;
-
- /* End mounting message in xfs_log_mount_finish */
- return 0;
-} /* xfs_log_mount */
-
-/*
- * Finish the recovery of the file system. This is separate from
- * the xfs_log_mount() call, because it depends on the code in
- * xfs_mountfs() to read in the root and real-time bitmap inodes
- * between calling xfs_log_mount() and here.
- *
- * mp - ubiquitous xfs mount point structure
- */
-int
-xfs_log_mount_finish(xfs_mount_t *mp, int mfsi_flags)
-{
- int error;
-
- if (!(mp->m_flags & XFS_MOUNT_NORECOVERY))
- error = xlog_recover_finish(mp->m_log, mfsi_flags);
- else {
- error = 0;
- ASSERT(XFS_MTOVFS(mp)->vfs_flag & VFS_RDONLY);
- }
-
- return error;
-}
-
-/*
- * Unmount processing for the log.
- */
-int
-xfs_log_unmount(xfs_mount_t *mp)
-{
- int error;
-
- error = xfs_log_unmount_write(mp);
- xfs_log_unmount_dealloc(mp);
- return error;
-}
-
-/*
- * Final log writes as part of unmount.
- *
- * Mark the filesystem clean as unmount happens. Note that during relocation
- * this routine needs to be executed as part of source-bag while the
- * deallocation must not be done until source-end.
- */
-
-/*
- * Unmount record used to have a string "Unmount filesystem--" in the
- * data section where the "Un" was really a magic number (XLOG_UNMOUNT_TYPE).
- * We just write the magic number now since that particular field isn't
- * currently architecture converted and "nUmount" is a bit foo.
- * As far as I know, there weren't any dependencies on the old behaviour.
- */
-
-int
-xfs_log_unmount_write(xfs_mount_t *mp)
-{
- xlog_t *log = mp->m_log;
- xlog_in_core_t *iclog;
-#ifdef DEBUG
- xlog_in_core_t *first_iclog;
-#endif
- xfs_log_iovec_t reg[1];
- xfs_log_ticket_t tic = NULL;
- xfs_lsn_t lsn;
- int error;
- SPLDECL(s);
-
- /* the data section must be 32 bit size aligned */
- struct {
- __uint16_t magic;
- __uint16_t pad1;
- __uint32_t pad2; /* may as well make it 64 bits */
- } magic = { XLOG_UNMOUNT_TYPE, 0, 0 };
-
- /*
- * Don't write out unmount record on read-only mounts.
- * Or, if we are doing a forced umount (typically because of IO errors).
- */
- if (XFS_MTOVFS(mp)->vfs_flag & VFS_RDONLY)
- return 0;
-
- xfs_log_force(mp, 0, XFS_LOG_FORCE|XFS_LOG_SYNC);
-
-#ifdef DEBUG
- first_iclog = iclog = log->l_iclog;
- do {
- if (!(iclog->ic_state & XLOG_STATE_IOERROR)) {
- ASSERT(iclog->ic_state & XLOG_STATE_ACTIVE);
- ASSERT(iclog->ic_offset == 0);
- }
- iclog = iclog->ic_next;
- } while (iclog != first_iclog);
-#endif
- if (! (XLOG_FORCED_SHUTDOWN(log))) {
- reg[0].i_addr = (void*)&magic;
- reg[0].i_len = sizeof(magic);
- XLOG_VEC_SET_TYPE(&reg[0], XLOG_REG_TYPE_UNMOUNT);
-
- error = xfs_log_reserve(mp, 600, 1, &tic, XFS_LOG, 0, 0);
- if (!error) {
- /* remove inited flag */
- ((xlog_ticket_t *)tic)->t_flags = 0;
- error = xlog_write(mp, reg, 1, tic, &lsn,
- NULL, XLOG_UNMOUNT_TRANS);
- /*
- * At this point, we're umounting anyway,
- * so there's no point in transitioning log state
- * to IOERROR. Just continue...
- */
- }
-
- if (error) {
- xfs_fs_cmn_err(CE_ALERT, mp,
- "xfs_log_unmount: unmount record failed");
- }
-
-
- s = LOG_LOCK(log);
- iclog = log->l_iclog;
- iclog->ic_refcnt++;
- LOG_UNLOCK(log, s);
- xlog_state_want_sync(log, iclog);
- (void) xlog_state_release_iclog(log, iclog);
-
- s = LOG_LOCK(log);
- if (!(iclog->ic_state == XLOG_STATE_ACTIVE ||
- iclog->ic_state == XLOG_STATE_DIRTY)) {
- if (!XLOG_FORCED_SHUTDOWN(log)) {
- sv_wait(&iclog->ic_forcesema, PMEM,
- &log->l_icloglock, s);
- } else {
- LOG_UNLOCK(log, s);
- }
- } else {
- LOG_UNLOCK(log, s);
- }
- if (tic)
- xlog_state_put_ticket(log, tic);
- } else {
- /*
- * We're already in forced_shutdown mode, couldn't
- * even attempt to write out the unmount transaction.
- *
- * Go through the motions of sync'ing and releasing
- * the iclog, even though no I/O will actually happen,
- * we need to wait for other log I/Os that may already
- * be in progress. Do this as a separate section of
- * code so we'll know if we ever get stuck here that
- * we're in this odd situation of trying to unmount
- * a file system that went into forced_shutdown as
- * the result of an unmount..
- */
- s = LOG_LOCK(log);
- iclog = log->l_iclog;
- iclog->ic_refcnt++;
- LOG_UNLOCK(log, s);
-
- xlog_state_want_sync(log, iclog);
- (void) xlog_state_release_iclog(log, iclog);
-
- s = LOG_LOCK(log);
-
- if ( ! ( iclog->ic_state == XLOG_STATE_ACTIVE
- || iclog->ic_state == XLOG_STATE_DIRTY
- || iclog->ic_state == XLOG_STATE_IOERROR) ) {
-
- sv_wait(&iclog->ic_forcesema, PMEM,
- &log->l_icloglock, s);
- } else {
- LOG_UNLOCK(log, s);
- }
- }
-
- return 0;
-} /* xfs_log_unmount_write */
-
-/*
- * Deallocate log structures for unmount/relocation.
- */
-void
-xfs_log_unmount_dealloc(xfs_mount_t *mp)
-{
- xlog_dealloc_log(mp->m_log);
-}
-
-/*
- * Write region vectors to log. The write happens using the space reservation
- * of the ticket (tic). It is not a requirement that all writes for a given
- * transaction occur with one call to xfs_log_write().
- */
-int
-xfs_log_write(xfs_mount_t * mp,
- xfs_log_iovec_t reg[],
- int nentries,
- xfs_log_ticket_t tic,
- xfs_lsn_t *start_lsn)
-{
- int error;
- xlog_t *log = mp->m_log;
-
- if (XLOG_FORCED_SHUTDOWN(log))
- return XFS_ERROR(EIO);
-
- if ((error = xlog_write(mp, reg, nentries, tic, start_lsn, NULL, 0))) {
- xfs_force_shutdown(mp, XFS_LOG_IO_ERROR);
- }
- return error;
-} /* xfs_log_write */
-
-
-void
-xfs_log_move_tail(xfs_mount_t *mp,
- xfs_lsn_t tail_lsn)
-{
- xlog_ticket_t *tic;
- xlog_t *log = mp->m_log;
- int need_bytes, free_bytes, cycle, bytes;
- SPLDECL(s);
-
- if (XLOG_FORCED_SHUTDOWN(log))
- return;
- ASSERT(!XFS_FORCED_SHUTDOWN(mp));
-
- if (tail_lsn == 0) {
- /* needed since sync_lsn is 64 bits */
- s = LOG_LOCK(log);
- tail_lsn = log->l_last_sync_lsn;
- LOG_UNLOCK(log, s);
- }
-
- s = GRANT_LOCK(log);
-
- /* Also an invalid lsn. 1 implies that we aren't passing in a valid
- * tail_lsn.
- */
- if (tail_lsn != 1) {
- log->l_tail_lsn = tail_lsn;
- }
-
- if ((tic = log->l_write_headq)) {
-#ifdef DEBUG
- if (log->l_flags & XLOG_ACTIVE_RECOVERY)
- panic("Recovery problem");
-#endif
- cycle = log->l_grant_write_cycle;
- bytes = log->l_grant_write_bytes;
- free_bytes = xlog_space_left(log, cycle, bytes);
- do {
- ASSERT(tic->t_flags & XLOG_TIC_PERM_RESERV);
-
- if (free_bytes < tic->t_unit_res && tail_lsn != 1)
- break;
- tail_lsn = 0;
- free_bytes -= tic->t_unit_res;
- sv_signal(&tic->t_sema);
- tic = tic->t_next;
- } while (tic != log->l_write_headq);
- }
- if ((tic = log->l_reserve_headq)) {
-#ifdef DEBUG
- if (log->l_flags & XLOG_ACTIVE_RECOVERY)
- panic("Recovery problem");
-#endif
- cycle = log->l_grant_reserve_cycle;
- bytes = log->l_grant_reserve_bytes;
- free_bytes = xlog_space_left(log, cycle, bytes);
- do {
- if (tic->t_flags & XLOG_TIC_PERM_RESERV)
- need_bytes = tic->t_unit_res*tic->t_cnt;
- else
- need_bytes = tic->t_unit_res;
- if (free_bytes < need_bytes && tail_lsn != 1)
- break;
- tail_lsn = 0;
- free_bytes -= need_bytes;
- sv_signal(&tic->t_sema);
- tic = tic->t_next;
- } while (tic != log->l_reserve_headq);
- }
- GRANT_UNLOCK(log, s);
-} /* xfs_log_move_tail */
-
-/*
- * Determine if we have a transaction that has gone to disk
- * that needs to be covered. Log activity needs to be idle (no AIL and
- * nothing in the iclogs). And, we need to be in the right state indicating
- * something has gone out.
- */
-int
-xfs_log_need_covered(xfs_mount_t *mp)
-{
- SPLDECL(s);
- int needed = 0, gen;
- xlog_t *log = mp->m_log;
- xfs_vfs_t *vfsp = XFS_MTOVFS(mp);
-
- if (/* fs_frozen(vfsp) RMC */ 0 || XFS_FORCED_SHUTDOWN(mp) ||
- (vfsp->vfs_flag & VFS_RDONLY))
- return 0;
-
- s = LOG_LOCK(log);
- if (((log->l_covered_state == XLOG_STATE_COVER_NEED) ||
- (log->l_covered_state == XLOG_STATE_COVER_NEED2))
- && !xfs_trans_first_ail(mp, &gen)
- && xlog_iclogs_empty(log)) {
- if (log->l_covered_state == XLOG_STATE_COVER_NEED)
- log->l_covered_state = XLOG_STATE_COVER_DONE;
- else {
- ASSERT(log->l_covered_state == XLOG_STATE_COVER_NEED2);
- log->l_covered_state = XLOG_STATE_COVER_DONE2;
- }
- needed = 1;
- }
- LOG_UNLOCK(log, s);
- return needed;
-}
-
-/******************************************************************************
- *
- * local routines
- *
- ******************************************************************************
- */
-
-/* xfs_trans_tail_ail returns 0 when there is nothing in the list.
- * The log manager must keep track of the last LR which was committed
- * to disk. The lsn of this LR will become the new tail_lsn whenever
- * xfs_trans_tail_ail returns 0. If we don't do this, we run into
- * the situation where stuff could be written into the log but nothing
- * was ever in the AIL when asked. Eventually, we panic since the
- * tail hits the head.
- *
- * We may be holding the log iclog lock upon entering this routine.
- */
-xfs_lsn_t
-xlog_assign_tail_lsn(xfs_mount_t *mp)
-{
- xfs_lsn_t tail_lsn;
- SPLDECL(s);
- xlog_t *log = mp->m_log;
-
- tail_lsn = xfs_trans_tail_ail(mp);
- s = GRANT_LOCK(log);
- if (tail_lsn != 0) {
- log->l_tail_lsn = tail_lsn;
- } else {
- tail_lsn = log->l_tail_lsn = log->l_last_sync_lsn;
- }
- GRANT_UNLOCK(log, s);
-
- return tail_lsn;
-} /* xlog_assign_tail_lsn */
-
-
-/*
- * Return the space in the log between the tail and the head. The head
- * is passed in the cycle/bytes formal parms. In the special case where
- * the reserve head has wrapped passed the tail, this calculation is no
- * longer valid. In this case, just return 0 which means there is no space
- * in the log. This works for all places where this function is called
- * with the reserve head. Of course, if the write head were to ever
- * wrap the tail, we should blow up. Rather than catch this case here,
- * we depend on other ASSERTions in other parts of the code. XXXmiken
- *
- * This code also handles the case where the reservation head is behind
- * the tail. The details of this case are described below, but the end
- * result is that we return the size of the log as the amount of space left.
- */
-int
-xlog_space_left(xlog_t *log, int cycle, int bytes)
-{
- int free_bytes;
- int tail_bytes;
- int tail_cycle;
-
- tail_bytes = BBTOB(BLOCK_LSN(log->l_tail_lsn));
- tail_cycle = CYCLE_LSN(log->l_tail_lsn);
- if ((tail_cycle == cycle) && (bytes >= tail_bytes)) {
- free_bytes = log->l_logsize - (bytes - tail_bytes);
- } else if ((tail_cycle + 1) < cycle) {
- return 0;
- } else if (tail_cycle < cycle) {
- ASSERT(tail_cycle == (cycle - 1));
- free_bytes = tail_bytes - bytes;
- } else {
- /*
- * The reservation head is behind the tail.
- * In this case we just want to return the size of the
- * log as the amount of space left.
- */
- xfs_fs_cmn_err(CE_ALERT, log->l_mp,
- "xlog_space_left: head behind tail\n"
- " tail_cycle = %d, tail_bytes = %d\n"
- " GH cycle = %d, GH bytes = %d",
- tail_cycle, tail_bytes, cycle, bytes);
- ASSERT(0);
- free_bytes = log->l_logsize;
- }
- return free_bytes;
-} /* xlog_space_left */
-
-
-/*
- * Log function which is called when an io completes.
- *
- * The log manager needs its own routine, in order to control what
- * happens with the buffer after the write completes.
- */
-void
-xlog_iodone(xfs_buf_t *bp)
-{
- xlog_in_core_t *iclog;
- xlog_t *l;
- int aborted;
-
- iclog = XFS_BUF_FSPRIVATE(bp, xlog_in_core_t *);
- ASSERT(XFS_BUF_FSPRIVATE2(bp, unsigned long) == (unsigned long) 2);
- XFS_BUF_SET_FSPRIVATE2(bp, (unsigned long)1);
- aborted = 0;
-
- /*
- * Some versions of cpp barf on the recursive definition of
- * ic_log -> hic_fields.ic_log and expand ic_log twice when
- * it is passed through two macros. Workaround broken cpp.
- */
- l = iclog->ic_log;
-
- /*
- * Race to shutdown the filesystem if we see an error.
- */
- if (XFS_TEST_ERROR((XFS_BUF_GETERROR(bp)), l->l_mp,
- XFS_ERRTAG_IODONE_IOERR, XFS_RANDOM_IODONE_IOERR)) {
- xfs_ioerror_alert("xlog_iodone", l->l_mp, bp, XFS_BUF_ADDR(bp));
- XFS_BUF_STALE(bp);
- xfs_force_shutdown(l->l_mp, XFS_LOG_IO_ERROR);
- /*
- * This flag will be propagated to the trans-committed
- * callback routines to let them know that the log-commit
- * didn't succeed.
- */
- aborted = XFS_LI_ABORTED;
- } else if (iclog->ic_state & XLOG_STATE_IOERROR) {
- aborted = XFS_LI_ABORTED;
- }
- xlog_state_done_syncing(iclog, aborted);
- if (!(XFS_BUF_ISASYNC(bp))) {
- /*
- * Corresponding psema() will be done in bwrite(). If we don't
- * vsema() here, panic.
- */
- XFS_BUF_V_IODONESEMA(bp);
- } else
- XFS_BUF_VSEMA(bp);
-} /* xlog_iodone */
-
-/*
- * The bdstrat callback function for log bufs. This gives us a central
- * place to trap bufs in case we get hit by a log I/O error and need to
- * shutdown. Actually, in practice, even when we didn't get a log error,
- * we transition the iclogs to IOERROR state *after* flushing all existing
- * iclogs to disk. This is because we don't want anymore new transactions to be
- * started or completed afterwards.
- */
-STATIC int
-xlog_bdstrat_cb(struct xfs_buf *bp)
-{
- xlog_in_core_t *iclog;
-
- iclog = XFS_BUF_FSPRIVATE(bp, xlog_in_core_t *);
-
- if ((iclog->ic_state & XLOG_STATE_IOERROR) == 0) {
- /* note for irix bstrat will need struct bdevsw passed
- * Fix the following macro if the code ever is merged
- */
- XFS_bdstrat(bp);
- return 0;
- }
-
- xfs_buftrace("XLOG__BDSTRAT IOERROR", bp);
- XFS_BUF_ERROR(bp, EIO);
- XFS_BUF_STALE(bp);
- xfs_biodone(bp);
- return XFS_ERROR(EIO);
-
-
-}
-
-/*
- * Return size of each in-core log record buffer.
- *
- * Low memory machines only get 2 16KB buffers. We don't want to waste
- * memory here. However, all other machines get at least 2 32KB buffers.
- * The number is hard coded because we don't care about the minimum
- * memory size, just 32MB systems.
- *
- * If the filesystem blocksize is too large, we may need to choose a
- * larger size since the directory code currently logs entire blocks.
- */
-
-STATIC void
-xlog_get_iclog_buffer_size(xfs_mount_t *mp,
- xlog_t *log)
-{
- int size;
- int xhdrs;
-
- if (mp->m_logbufs <= 0) {
- if (xfs_physmem <= btoc(128*1024*1024)) {
- log->l_iclog_bufs = XLOG_MIN_ICLOGS;
- } else if (xfs_physmem <= btoc(400*1024*1024)) {
- log->l_iclog_bufs = XLOG_MED_ICLOGS;
- } else { /* 256K with 32K bufs */
- log->l_iclog_bufs = XLOG_MAX_ICLOGS;
- }
- } else {
- log->l_iclog_bufs = mp->m_logbufs;
- }
-
- /*
- * Buffer size passed in from mount system call.
- */
- if (mp->m_logbsize > 0) {
- size = log->l_iclog_size = mp->m_logbsize;
- log->l_iclog_size_log = 0;
- while (size != 1) {
- log->l_iclog_size_log++;
- size >>= 1;
- }
-
- if (XFS_SB_VERSION_HASLOGV2(&mp->m_sb)) {
- /* # headers = size / 32K
- * one header holds cycles from 32K of data
- */
-
- xhdrs = mp->m_logbsize / XLOG_HEADER_CYCLE_SIZE;
- if (mp->m_logbsize % XLOG_HEADER_CYCLE_SIZE)
- xhdrs++;
- log->l_iclog_hsize = xhdrs << BBSHIFT;
- log->l_iclog_heads = xhdrs;
- } else {
- ASSERT(mp->m_logbsize <= XLOG_BIG_RECORD_BSIZE);
- log->l_iclog_hsize = BBSIZE;
- log->l_iclog_heads = 1;
- }
- goto done;
- }
-
- /*
- * Special case machines that have less than 32MB of memory.
- * All machines with more memory use 32KB buffers.
- */
- if (xfs_physmem <= btoc(32*1024*1024)) {
- /* Don't change; min configuration */
- log->l_iclog_size = XLOG_RECORD_BSIZE; /* 16k */
- log->l_iclog_size_log = XLOG_RECORD_BSHIFT;
- } else {
- log->l_iclog_size = XLOG_BIG_RECORD_BSIZE; /* 32k */
- log->l_iclog_size_log = XLOG_BIG_RECORD_BSHIFT;
- }
-
- /* the default log size is 16k or 32k which is one header sector */
- log->l_iclog_hsize = BBSIZE;
- log->l_iclog_heads = 1;
-
- /*
- * For 16KB, we use 3 32KB buffers. For 32KB block sizes, we use
- * 4 32KB buffers. For 64KB block sizes, we use 8 32KB buffers.
- */
- if (mp->m_sb.sb_blocksize >= 16*1024) {
- log->l_iclog_size = XLOG_BIG_RECORD_BSIZE;
- log->l_iclog_size_log = XLOG_BIG_RECORD_BSHIFT;
- if (mp->m_logbufs <= 0) {
- switch (mp->m_sb.sb_blocksize) {
- case 16*1024: /* 16 KB */
- log->l_iclog_bufs = 3;
- break;
- case 32*1024: /* 32 KB */
- log->l_iclog_bufs = 4;
- break;
- case 64*1024: /* 64 KB */
- log->l_iclog_bufs = 8;
- break;
- default:
- xlog_panic("XFS: Invalid blocksize");
- break;
- }
- }
- }
-
-done: /* are we being asked to make the sizes selected above visible? */
- if (mp->m_logbufs == 0)
- mp->m_logbufs = log->l_iclog_bufs;
- if (mp->m_logbsize == 0)
- mp->m_logbsize = log->l_iclog_size;
-} /* xlog_get_iclog_buffer_size */
-
-
-/*
- * This routine initializes some of the log structure for a given mount point.
- * Its primary purpose is to fill in enough, so recovery can occur. However,
- * some other stuff may be filled in too.
- */
-STATIC xlog_t *
-xlog_alloc_log(xfs_mount_t *mp,
- xfs_buftarg_t *log_target,
- xfs_daddr_t blk_offset,
- int num_bblks)
-{
- xlog_t *log;
- xlog_rec_header_t *head;
- xlog_in_core_t **iclogp;
- xlog_in_core_t *iclog, *prev_iclog=NULL;
- xfs_buf_t *bp;
- int i;
- int iclogsize;
-
- log = (xlog_t *)kmem_zalloc(sizeof(xlog_t), KM_SLEEP);
-
- log->l_mp = mp;
- log->l_targ = log_target;
- log->l_logsize = BBTOB(num_bblks);
- log->l_logBBstart = blk_offset;
- log->l_logBBsize = num_bblks;
- log->l_covered_state = XLOG_STATE_COVER_IDLE;
- log->l_flags |= XLOG_ACTIVE_RECOVERY;
-
- log->l_prev_block = -1;
- ASSIGN_ANY_LSN_HOST(log->l_tail_lsn, 1, 0);
- /* log->l_tail_lsn = 0x100000000LL; cycle = 1; current block = 0 */
- log->l_last_sync_lsn = log->l_tail_lsn;
- log->l_curr_cycle = 1; /* 0 is bad since this is initial value */
- log->l_grant_reserve_cycle = 1;
- log->l_grant_write_cycle = 1;
-
- if (XFS_SB_VERSION_HASSECTOR(&mp->m_sb)) {
- log->l_sectbb_log = mp->m_sb.sb_logsectlog - BBSHIFT;
- ASSERT(log->l_sectbb_log <= mp->m_sectbb_log);
- /* for larger sector sizes, must have v2 or external log */
- ASSERT(log->l_sectbb_log == 0 ||
- log->l_logBBstart == 0 ||
- XFS_SB_VERSION_HASLOGV2(&mp->m_sb));
- ASSERT(mp->m_sb.sb_logsectlog >= BBSHIFT);
- }
- log->l_sectbb_mask = (1 << log->l_sectbb_log) - 1;
-
- xlog_get_iclog_buffer_size(mp, log);
-
- bp = xfs_buf_get_empty(log->l_iclog_size, mp->m_logdev_targp);
- XFS_BUF_SET_IODONE_FUNC(bp, xlog_iodone);
- XFS_BUF_SET_BDSTRAT_FUNC(bp, xlog_bdstrat_cb);
- XFS_BUF_SET_FSPRIVATE2(bp, (unsigned long)1);
- ASSERT(XFS_BUF_ISBUSY(bp));
- ASSERT(XFS_BUF_VALUSEMA(bp) <= 0);
- XFS_BUF_VSEMA(bp);
- log->l_xbuf = bp;
-
- spinlock_init(&log->l_icloglock, "iclog");
- spinlock_init(&log->l_grant_lock, "grhead_iclog");
- initnsema(&log->l_flushsema, 0, "ic-flush");
- xlog_state_ticket_alloc(log); /* wait until after icloglock inited */
-
- /* log record size must be multiple of BBSIZE; see xlog_rec_header_t */
- ASSERT((XFS_BUF_SIZE(bp) & BBMASK) == 0);
-
- iclogp = &log->l_iclog;
- /*
- * The amount of memory to allocate for the iclog structure is
- * rather funky due to the way the structure is defined. It is
- * done this way so that we can use different sizes for machines
- * with different amounts of memory. See the definition of
- * xlog_in_core_t in xfs_log_priv.h for details.
- */
- iclogsize = log->l_iclog_size;
- ASSERT(log->l_iclog_size >= 4096);
- for (i=0; i < log->l_iclog_bufs; i++) {
- *iclogp = (xlog_in_core_t *)
- kmem_zalloc(sizeof(xlog_in_core_t), KM_SLEEP);
- iclog = *iclogp;
- iclog->hic_data = (xlog_in_core_2_t *)
- kmem_zalloc(iclogsize, KM_SLEEP);
-
- iclog->ic_prev = prev_iclog;
- prev_iclog = iclog;
- log->l_iclog_bak[i] = (xfs_caddr_t)&(iclog->ic_header);
-
- head = &iclog->ic_header;
- memset(head, 0, sizeof(xlog_rec_header_t));
- INT_SET(head->h_magicno, ARCH_CONVERT, XLOG_HEADER_MAGIC_NUM);
- INT_SET(head->h_version, ARCH_CONVERT,
- XFS_SB_VERSION_HASLOGV2(&log->l_mp->m_sb) ? 2 : 1);
- INT_SET(head->h_size, ARCH_CONVERT, log->l_iclog_size);
- /* new fields */
- INT_SET(head->h_fmt, ARCH_CONVERT, XLOG_FMT);
- memcpy(&head->h_fs_uuid, &mp->m_sb.sb_uuid, sizeof(uuid_t));
-
- bp = xfs_buf_get_empty(log->l_iclog_size, mp->m_logdev_targp);
- XFS_BUF_SET_IODONE_FUNC(bp, xlog_iodone);
- XFS_BUF_SET_BDSTRAT_FUNC(bp, xlog_bdstrat_cb);
- XFS_BUF_SET_FSPRIVATE2(bp, (unsigned long)1);
- iclog->ic_bp = bp;
-
- iclog->ic_size = XFS_BUF_SIZE(bp) - log->l_iclog_hsize;
- iclog->ic_state = XLOG_STATE_ACTIVE;
- iclog->ic_log = log;
- iclog->ic_callback_tail = &(iclog->ic_callback);
- iclog->ic_datap = (char *)iclog->hic_data + log->l_iclog_hsize;
-
- ASSERT(XFS_BUF_ISBUSY(iclog->ic_bp));
- ASSERT(XFS_BUF_VALUSEMA(iclog->ic_bp) <= 0);
- XFS_BUF_VSEMA(iclog->ic_bp);
- sv_init(&iclog->ic_forcesema, SV_DEFAULT, "iclog-force");
- sv_init(&iclog->ic_writesema, SV_DEFAULT, "iclog-write");
-
- iclogp = &iclog->ic_next;
- }
- *iclogp = log->l_iclog; /* complete ring */
- log->l_iclog->ic_prev = prev_iclog; /* re-write 1st prev ptr */
-
- return log;
-} /* xlog_alloc_log */
-
-
-/*
- * Write out the commit record of a transaction associated with the given
- * ticket. Return the lsn of the commit record.
- */
-STATIC int
-xlog_commit_record(xfs_mount_t *mp,
- xlog_ticket_t *ticket,
- xlog_in_core_t **iclog,
- xfs_lsn_t *commitlsnp)
-{
- int error;
- xfs_log_iovec_t reg[1];
-
- reg[0].i_addr = NULL;
- reg[0].i_len = 0;
- XLOG_VEC_SET_TYPE(&reg[0], XLOG_REG_TYPE_COMMIT);
-
- ASSERT_ALWAYS(iclog);
- if ((error = xlog_write(mp, reg, 1, ticket, commitlsnp,
- iclog, XLOG_COMMIT_TRANS))) {
- xfs_force_shutdown(mp, XFS_LOG_IO_ERROR);
- }
- return error;
-} /* xlog_commit_record */
-
-
-/*
- * Push on the buffer cache code if we ever use more than 75% of the on-disk
- * log space. This code pushes on the lsn which would supposedly free up
- * the 25% which we want to leave free. We may need to adopt a policy which
- * pushes on an lsn which is further along in the log once we reach the high
- * water mark. In this manner, we would be creating a low water mark.
- */
-void
-xlog_grant_push_ail(xfs_mount_t *mp,
- int need_bytes)
-{
- xlog_t *log = mp->m_log; /* pointer to the log */
- xfs_lsn_t tail_lsn; /* lsn of the log tail */
- xfs_lsn_t threshold_lsn = 0; /* lsn we'd like to be at */
- int free_blocks; /* free blocks left to write to */
- int free_bytes; /* free bytes left to write to */
- int threshold_block; /* block in lsn we'd like to be at */
- int threshold_cycle; /* lsn cycle we'd like to be at */
- int free_threshold;
- SPLDECL(s);
-
- ASSERT(BTOBB(need_bytes) < log->l_logBBsize);
-
- s = GRANT_LOCK(log);
- free_bytes = xlog_space_left(log,
- log->l_grant_reserve_cycle,
- log->l_grant_reserve_bytes);
- tail_lsn = log->l_tail_lsn;
- free_blocks = BTOBBT(free_bytes);
-
- /*
- * Set the threshold for the minimum number of free blocks in the
- * log to the maximum of what the caller needs, one quarter of the
- * log, and 256 blocks.
- */
- free_threshold = BTOBB(need_bytes);
- free_threshold = MAX(free_threshold, (log->l_logBBsize >> 2));
- free_threshold = MAX(free_threshold, 256);
- if (free_blocks < free_threshold) {
- threshold_block = BLOCK_LSN(tail_lsn) + free_threshold;
- threshold_cycle = CYCLE_LSN(tail_lsn);
- if (threshold_block >= log->l_logBBsize) {
- threshold_block -= log->l_logBBsize;
- threshold_cycle += 1;
- }
- ASSIGN_ANY_LSN_HOST(threshold_lsn, threshold_cycle,
- threshold_block);
-
- /* Don't pass in an lsn greater than the lsn of the last
- * log record known to be on disk.
- */
- if (XFS_LSN_CMP(threshold_lsn, log->l_last_sync_lsn) > 0)
- threshold_lsn = log->l_last_sync_lsn;
- }
- GRANT_UNLOCK(log, s);
-
- /*
- * Get the transaction layer to kick the dirty buffers out to
- * disk asynchronously. No point in trying to do this if
- * the filesystem is shutting down.
- */
- if (threshold_lsn &&
- !XLOG_FORCED_SHUTDOWN(log))
- xfs_trans_push_ail(mp, threshold_lsn);
-} /* xlog_grant_push_ail */
-
-
-/*
- * Flush out the in-core log (iclog) to the on-disk log in an asynchronous
- * fashion. Previously, we should have moved the current iclog
- * ptr in the log to point to the next available iclog. This allows further
- * write to continue while this code syncs out an iclog ready to go.
- * Before an in-core log can be written out, the data section must be scanned
- * to save away the 1st word of each BBSIZE block into the header. We replace
- * it with the current cycle count. Each BBSIZE block is tagged with the
- * cycle count because there in an implicit assumption that drives will
- * guarantee that entire 512 byte blocks get written at once. In other words,
- * we can't have part of a 512 byte block written and part not written. By
- * tagging each block, we will know which blocks are valid when recovering
- * after an unclean shutdown.
- *
- * This routine is single threaded on the iclog. No other thread can be in
- * this routine with the same iclog. Changing contents of iclog can there-
- * fore be done without grabbing the state machine lock. Updating the global
- * log will require grabbing the lock though.
- *
- * The entire log manager uses a logical block numbering scheme. Only
- * log_sync (and then only bwrite()) know about the fact that the log may
- * not start with block zero on a given device. The log block start offset
- * is added immediately before calling bwrite().
- */
-
-int
-xlog_sync(xlog_t *log,
- xlog_in_core_t *iclog)
-{
- xfs_caddr_t dptr; /* pointer to byte sized element */
- xfs_buf_t *bp;
- int i, ops;
- uint count; /* byte count of bwrite */
- uint count_init; /* initial count before roundup */
- int roundoff; /* roundoff to BB or stripe */
- int split = 0; /* split write into two regions */
- int error;
- SPLDECL(s);
- int v2 = XFS_SB_VERSION_HASLOGV2(&log->l_mp->m_sb);
-
- XFS_STATS_INC(xs_log_writes);
- ASSERT(iclog->ic_refcnt == 0);
-
- /* Add for LR header */
- count_init = log->l_iclog_hsize + iclog->ic_offset;
-
- /* Round out the log write size */
- if (v2 && log->l_mp->m_sb.sb_logsunit > 1) {
- /* we have a v2 stripe unit to use */
- count = XLOG_LSUNITTOB(log, XLOG_BTOLSUNIT(log, count_init));
- } else {
- count = BBTOB(BTOBB(count_init));
- }
- roundoff = count - count_init;
- ASSERT(roundoff >= 0);
- ASSERT((v2 && log->l_mp->m_sb.sb_logsunit > 1 &&
- roundoff < log->l_mp->m_sb.sb_logsunit)
- ||
- (log->l_mp->m_sb.sb_logsunit <= 1 &&
- roundoff < BBTOB(1)));
-
- /* move grant heads by roundoff in sync */
- s = GRANT_LOCK(log);
- xlog_grant_add_space(log, roundoff);
- GRANT_UNLOCK(log, s);
-
- /* put cycle number in every block */
- xlog_pack_data(log, iclog, roundoff);
-
- /* real byte length */
- if (v2) {
- INT_SET(iclog->ic_header.h_len,
- ARCH_CONVERT,
- iclog->ic_offset + roundoff);
- } else {
- INT_SET(iclog->ic_header.h_len, ARCH_CONVERT, iclog->ic_offset);
- }
-
- /* put ops count in correct order */
- ops = iclog->ic_header.h_num_logops;
- INT_SET(iclog->ic_header.h_num_logops, ARCH_CONVERT, ops);
-
- bp = iclog->ic_bp;
- XFS_BUF_PSEMA(bp, PRIBIO);
- ASSERT(XFS_BUF_FSPRIVATE2(bp, unsigned long) == (unsigned long)1);
- XFS_BUF_SET_FSPRIVATE2(bp, (unsigned long)2);
- XFS_BUF_SET_ADDR(bp, BLOCK_LSN(INT_GET(iclog->ic_header.h_lsn, ARCH_CONVERT)));
-
- XFS_STATS_ADD(xs_log_blocks, BTOBB(count));
-
- /* Do we need to split this write into 2 parts? */
- if (XFS_BUF_ADDR(bp) + BTOBB(count) > log->l_logBBsize) {
- split = count - (BBTOB(log->l_logBBsize - XFS_BUF_ADDR(bp)));
- count = BBTOB(log->l_logBBsize - XFS_BUF_ADDR(bp));
- iclog->ic_bwritecnt = 2; /* split into 2 writes */
- } else {
- iclog->ic_bwritecnt = 1;
- }
- XFS_BUF_SET_PTR(bp, (xfs_caddr_t) &(iclog->ic_header), count);
- XFS_BUF_SET_FSPRIVATE(bp, iclog); /* save for later */
- XFS_BUF_BUSY(bp);
- XFS_BUF_ASYNC(bp);
- XFS_BUF_SET_IODONE_FUNC(bp, xlog_iodone);
- /*
- * Do an ordered write for the log block.
- *
- * It may not be needed to flush the first split block in the log wrap
- * case, but do it anyways to be safe -AK
- */
- if (log->l_mp->m_flags & XFS_MOUNT_BARRIER)
- XFS_BUF_ORDERED(bp);
-
- ASSERT(XFS_BUF_ADDR(bp) <= log->l_logBBsize-1);
- ASSERT(XFS_BUF_ADDR(bp) + BTOBB(count) <= log->l_logBBsize);
-
- xlog_verify_iclog(log, iclog, count, B_TRUE);
-
- /* account for log which doesn't start at block #0 */
- XFS_BUF_SET_ADDR(bp, XFS_BUF_ADDR(bp) + log->l_logBBstart);
- /*
- * Don't call xfs_bwrite here. We do log-syncs even when the filesystem
- * is shutting down.
- */
- XFS_BUF_WRITE(bp);
-
- if ((error = XFS_bwrite(bp))) {
- xfs_ioerror_alert("xlog_sync", log->l_mp, bp,
- XFS_BUF_ADDR(bp));
- return error;
- }
- if (split) {
- bp = iclog->ic_log->l_xbuf;
- ASSERT(XFS_BUF_FSPRIVATE2(bp, unsigned long) ==
- (unsigned long)1);
- XFS_BUF_SET_FSPRIVATE2(bp, (unsigned long)2);
- XFS_BUF_SET_ADDR(bp, 0); /* logical 0 */
- XFS_BUF_SET_PTR(bp, (xfs_caddr_t)((__psint_t)&(iclog->ic_header)+
- (__psint_t)count), split);
- XFS_BUF_SET_FSPRIVATE(bp, iclog);
- XFS_BUF_BUSY(bp);
- XFS_BUF_ASYNC(bp);
- XFS_BUF_SET_IODONE_FUNC(bp, xlog_iodone);
- if (log->l_mp->m_flags & XFS_MOUNT_BARRIER)
- XFS_BUF_ORDERED(bp);
- dptr = XFS_BUF_PTR(bp);
- /*
- * Bump the cycle numbers at the start of each block
- * since this part of the buffer is at the start of
- * a new cycle. Watch out for the header magic number
- * case, though.
- */
- for (i=0; i<split; i += BBSIZE) {
- INT_MOD(*(uint *)dptr, ARCH_CONVERT, +1);
- if (INT_GET(*(uint *)dptr, ARCH_CONVERT) == XLOG_HEADER_MAGIC_NUM)
- INT_MOD(*(uint *)dptr, ARCH_CONVERT, +1);
- dptr += BBSIZE;
- }
-
- ASSERT(XFS_BUF_ADDR(bp) <= log->l_logBBsize-1);
- ASSERT(XFS_BUF_ADDR(bp) + BTOBB(count) <= log->l_logBBsize);
-
- /* account for internal log which doesn't start at block #0 */
- XFS_BUF_SET_ADDR(bp, XFS_BUF_ADDR(bp) + log->l_logBBstart);
- XFS_BUF_WRITE(bp);
- if ((error = XFS_bwrite(bp))) {
- xfs_ioerror_alert("xlog_sync (split)", log->l_mp,
- bp, XFS_BUF_ADDR(bp));
- return error;
- }
- }
- return 0;
-} /* xlog_sync */
-
-
-/*
- * Deallocate a log structure
- */
-void
-xlog_dealloc_log(xlog_t *log)
-{
- xlog_in_core_t *iclog, *next_iclog;
- xlog_ticket_t *tic, *next_tic;
- int i;
-
-
- iclog = log->l_iclog;
- for (i=0; i<log->l_iclog_bufs; i++) {
- sv_destroy(&iclog->ic_forcesema);
- sv_destroy(&iclog->ic_writesema);
- XFS_BUF_PSEMA(iclog->ic_bp, PRIBIO);
- xfs_buf_free(iclog->ic_bp);
-#ifdef XFS_LOG_TRACE
- if (iclog->ic_trace != NULL) {
- ktrace_free(iclog->ic_trace);
- }
-#endif
- next_iclog = iclog->ic_next;
- kmem_free(iclog->hic_data, log->l_iclog_size);
- kmem_free(iclog, sizeof(xlog_in_core_t));
- iclog = next_iclog;
- }
- freesema(&log->l_flushsema);
- spinlock_destroy(&log->l_icloglock);
- spinlock_destroy(&log->l_grant_lock);
-
- /* XXXsup take a look at this again. */
- if ((log->l_ticket_cnt != log->l_ticket_tcnt) &&
- !XLOG_FORCED_SHUTDOWN(log)) {
- xfs_fs_cmn_err(CE_WARN, log->l_mp,
- "xlog_dealloc_log: (cnt: %d, total: %d)",
- log->l_ticket_cnt, log->l_ticket_tcnt);
- /* ASSERT(log->l_ticket_cnt == log->l_ticket_tcnt); */
-
- } else {
- tic = log->l_unmount_free;
- while (tic) {
- next_tic = tic->t_next;
- kmem_free(tic, NBPP);
- tic = next_tic;
- }
- }
- XFS_BUF_PSEMA(log->l_xbuf, PRIBIO);
- xfs_buf_free(log->l_xbuf);
-#ifdef XFS_LOG_TRACE
- if (log->l_trace != NULL) {
- ktrace_free(log->l_trace);
- }
- if (log->l_grant_trace != NULL) {
- ktrace_free(log->l_grant_trace);
- }
-#endif
- log->l_mp->m_log = NULL;
- kmem_free(log, sizeof(xlog_t));
-} /* xlog_dealloc_log */
-
-/*
- * Update counters atomically now that memcpy is done.
- */
-/* ARGSUSED */
-static inline void
-xlog_state_finish_copy(xlog_t *log,
- xlog_in_core_t *iclog,
- int record_cnt,
- int copy_bytes)
-{
- SPLDECL(s);
-
- s = LOG_LOCK(log);
-
- iclog->ic_header.h_num_logops += record_cnt;
- iclog->ic_offset += copy_bytes;
-
- LOG_UNLOCK(log, s);
-} /* xlog_state_finish_copy */
-
-
-
-
-/*
- * print out info relating to regions written which consume
- * the reservation
- */
-STATIC void
-xlog_print_tic_res(xfs_mount_t *mp, xlog_ticket_t *ticket)
-{
- uint i;
- uint ophdr_spc = ticket->t_res_num_ophdrs * (uint)sizeof(xlog_op_header_t);
-
- /* match with XLOG_REG_TYPE_* in xfs_log.h */
- static char *res_type_str[XLOG_REG_TYPE_MAX] = {
- "bformat",
- "bchunk",
- "efi_format",
- "efd_format",
- "iformat",
- "icore",
- "iext",
- "ibroot",
- "ilocal",
- "iattr_ext",
- "iattr_broot",
- "iattr_local",
- "qformat",
- "dquot",
- "quotaoff",
- "LR header",
- "unmount",
- "commit",
- "trans header"
- };
- static char *trans_type_str[XFS_TRANS_TYPE_MAX] = {
- "SETATTR_NOT_SIZE",
- "SETATTR_SIZE",
- "INACTIVE",
- "CREATE",
- "CREATE_TRUNC",
- "TRUNCATE_FILE",
- "REMOVE",
- "LINK",
- "RENAME",
- "MKDIR",
- "RMDIR",
- "SYMLINK",
- "SET_DMATTRS",
- "GROWFS",
- "STRAT_WRITE",
- "DIOSTRAT",
- "WRITE_SYNC",
- "WRITEID",
- "ADDAFORK",
- "ATTRINVAL",
- "ATRUNCATE",
- "ATTR_SET",
- "ATTR_RM",
- "ATTR_FLAG",
- "CLEAR_AGI_BUCKET",
- "QM_SBCHANGE",
- "DUMMY1",
- "DUMMY2",
- "QM_QUOTAOFF",
- "QM_DQALLOC",
- "QM_SETQLIM",
- "QM_DQCLUSTER",
- "QM_QINOCREATE",
- "QM_QUOTAOFF_END",
- "SB_UNIT",
- "FSYNC_TS",
- "GROWFSRT_ALLOC",
- "GROWFSRT_ZERO",
- "GROWFSRT_FREE",
- "SWAPEXT"
- };
-
- xfs_fs_cmn_err(CE_WARN, mp,
- "xfs_log_write: reservation summary:\n"
- " trans type = %s (%u)\n"
- " unit res = %d bytes\n"
- " current res = %d bytes\n"
- " total reg = %u bytes (o/flow = %u bytes)\n"
- " ophdrs = %u (ophdr space = %u bytes)\n"
- " ophdr + reg = %u bytes\n"
- " num regions = %u\n",
- ((ticket->t_trans_type <= 0 ||
- ticket->t_trans_type > XFS_TRANS_TYPE_MAX) ?
- "bad-trans-type" : trans_type_str[ticket->t_trans_type-1]),
- ticket->t_trans_type,
- ticket->t_unit_res,
- ticket->t_curr_res,
- ticket->t_res_arr_sum, ticket->t_res_o_flow,
- ticket->t_res_num_ophdrs, ophdr_spc,
- ticket->t_res_arr_sum +
- ticket->t_res_o_flow + ophdr_spc,
- ticket->t_res_num);
-
- for (i = 0; i < ticket->t_res_num; i++) {
- uint r_type = ticket->t_res_arr[i].r_type;
- cmn_err(CE_WARN,
- "region[%u]: %s - %u bytes\n",
- i,
- ((r_type <= 0 || r_type > XLOG_REG_TYPE_MAX) ?
- "bad-rtype" : res_type_str[r_type-1]),
- ticket->t_res_arr[i].r_len);
- }
-}
-
-/*
- * Write some region out to in-core log
- *
- * This will be called when writing externally provided regions or when
- * writing out a commit record for a given transaction.
- *
- * General algorithm:
- * 1. Find total length of this write. This may include adding to the
- * lengths passed in.
- * 2. Check whether we violate the tickets reservation.
- * 3. While writing to this iclog
- * A. Reserve as much space in this iclog as can get
- * B. If this is first write, save away start lsn
- * C. While writing this region:
- * 1. If first write of transaction, write start record
- * 2. Write log operation header (header per region)
- * 3. Find out if we can fit entire region into this iclog
- * 4. Potentially, verify destination memcpy ptr
- * 5. Memcpy (partial) region
- * 6. If partial copy, release iclog; otherwise, continue
- * copying more regions into current iclog
- * 4. Mark want sync bit (in simulation mode)
- * 5. Release iclog for potential flush to on-disk log.
- *
- * ERRORS:
- * 1. Panic if reservation is overrun. This should never happen since
- * reservation amounts are generated internal to the filesystem.
- * NOTES:
- * 1. Tickets are single threaded data structures.
- * 2. The XLOG_END_TRANS & XLOG_CONTINUE_TRANS flags are passed down to the
- * syncing routine. When a single log_write region needs to span
- * multiple in-core logs, the XLOG_CONTINUE_TRANS bit should be set
- * on all log operation writes which don't contain the end of the
- * region. The XLOG_END_TRANS bit is used for the in-core log
- * operation which contains the end of the continued log_write region.
- * 3. When xlog_state_get_iclog_space() grabs the rest of the current iclog,
- * we don't really know exactly how much space will be used. As a result,
- * we don't update ic_offset until the end when we know exactly how many
- * bytes have been written out.
- */
-int
-xlog_write(xfs_mount_t * mp,
- xfs_log_iovec_t reg[],
- int nentries,
- xfs_log_ticket_t tic,
- xfs_lsn_t *start_lsn,
- xlog_in_core_t **commit_iclog,
- uint flags)
-{
- xlog_t *log = mp->m_log;
- xlog_ticket_t *ticket = (xlog_ticket_t *)tic;
- xlog_op_header_t *logop_head; /* ptr to log operation header */
- xlog_in_core_t *iclog = NULL; /* ptr to current in-core log */
- __psint_t ptr; /* copy address into data region */
- int len; /* # xlog_write() bytes 2 still copy */
- int index; /* region index currently copying */
- int log_offset = 0; /* offset (from 0) into data region */
- int start_rec_copy; /* # bytes to copy for start record */
- int partial_copy; /* did we split a region? */
- int partial_copy_len;/* # bytes copied if split region */
- int need_copy; /* # bytes need to memcpy this region */
- int copy_len; /* # bytes actually memcpy'ing */
- int copy_off; /* # bytes from entry start */
- int contwr; /* continued write of in-core log? */
- int error;
- int record_cnt = 0, data_cnt = 0;
-
- partial_copy_len = partial_copy = 0;
-
- /* Calculate potential maximum space. Each region gets its own
- * xlog_op_header_t and may need to be double word aligned.
- */
- len = 0;
- if (ticket->t_flags & XLOG_TIC_INITED) { /* acct for start rec of xact */
- len += sizeof(xlog_op_header_t);
- XLOG_TIC_ADD_OPHDR(ticket);
- }
-
- for (index = 0; index < nentries; index++) {
- len += sizeof(xlog_op_header_t); /* each region gets >= 1 */
- XLOG_TIC_ADD_OPHDR(ticket);
- len += reg[index].i_len;
- XLOG_TIC_ADD_REGION(ticket, reg[index].i_len, reg[index].i_type);
- }
- contwr = *start_lsn = 0;
-
- if (ticket->t_curr_res < len) {
- xlog_print_tic_res(mp, ticket);
-#ifdef DEBUG
- xlog_panic(
- "xfs_log_write: reservation ran out. Need to up reservation");
-#else
- /* Customer configurable panic */
- xfs_cmn_err(XFS_PTAG_LOGRES, CE_ALERT, mp,
- "xfs_log_write: reservation ran out. Need to up reservation");
- /* If we did not panic, shutdown the filesystem */
- xfs_force_shutdown(mp, XFS_CORRUPT_INCORE);
-#endif
- } else
- ticket->t_curr_res -= len;
-
- for (index = 0; index < nentries; ) {
- if ((error = xlog_state_get_iclog_space(log, len, &iclog, ticket,
- &contwr, &log_offset)))
- return error;
-
- ASSERT(log_offset <= iclog->ic_size - 1);
- ptr = (__psint_t) ((char *)iclog->ic_datap+log_offset);
-
- /* start_lsn is the first lsn written to. That's all we need. */
- if (! *start_lsn)
- *start_lsn = INT_GET(iclog->ic_header.h_lsn, ARCH_CONVERT);
-
- /* This loop writes out as many regions as can fit in the amount
- * of space which was allocated by xlog_state_get_iclog_space().
- */
- while (index < nentries) {
- ASSERT(reg[index].i_len % sizeof(__int32_t) == 0);
- ASSERT((__psint_t)ptr % sizeof(__int32_t) == 0);
- start_rec_copy = 0;
-
- /* If first write for transaction, insert start record.
- * We can't be trying to commit if we are inited. We can't
- * have any "partial_copy" if we are inited.
- */
- if (ticket->t_flags & XLOG_TIC_INITED) {
- logop_head = (xlog_op_header_t *)ptr;
- INT_SET(logop_head->oh_tid, ARCH_CONVERT, ticket->t_tid);
- logop_head->oh_clientid = ticket->t_clientid;
- logop_head->oh_len = 0;
- logop_head->oh_flags = XLOG_START_TRANS;
- logop_head->oh_res2 = 0;
- ticket->t_flags &= ~XLOG_TIC_INITED; /* clear bit */
- record_cnt++;
-
- start_rec_copy = sizeof(xlog_op_header_t);
- xlog_write_adv_cnt(ptr, len, log_offset, start_rec_copy);
- }
-
- /* Copy log operation header directly into data section */
- logop_head = (xlog_op_header_t *)ptr;
- INT_SET(logop_head->oh_tid, ARCH_CONVERT, ticket->t_tid);
- logop_head->oh_clientid = ticket->t_clientid;
- logop_head->oh_res2 = 0;
-
- /* header copied directly */
- xlog_write_adv_cnt(ptr, len, log_offset, sizeof(xlog_op_header_t));
-
- /* are we copying a commit or unmount record? */
- logop_head->oh_flags = flags;
-
- /*
- * We've seen logs corrupted with bad transaction client
- * ids. This makes sure that XFS doesn't generate them on.
- * Turn this into an EIO and shut down the filesystem.
- */
- switch (logop_head->oh_clientid) {
- case XFS_TRANSACTION:
- case XFS_VOLUME:
- case XFS_LOG:
- break;
- default:
- xfs_fs_cmn_err(CE_WARN, mp,
- "Bad XFS transaction clientid 0x%x in ticket 0x%p",
- logop_head->oh_clientid, tic);
- return XFS_ERROR(EIO);
- }
-
- /* Partial write last time? => (partial_copy != 0)
- * need_copy is the amount we'd like to copy if everything could
- * fit in the current memcpy.
- */
- need_copy = reg[index].i_len - partial_copy_len;
-
- copy_off = partial_copy_len;
- if (need_copy <= iclog->ic_size - log_offset) { /*complete write */
- INT_SET(logop_head->oh_len, ARCH_CONVERT, copy_len = need_copy);
- if (partial_copy)
- logop_head->oh_flags|= (XLOG_END_TRANS|XLOG_WAS_CONT_TRANS);
- partial_copy_len = partial_copy = 0;
- } else { /* partial write */
- copy_len = iclog->ic_size - log_offset;
- INT_SET(logop_head->oh_len, ARCH_CONVERT, copy_len);
- logop_head->oh_flags |= XLOG_CONTINUE_TRANS;
- if (partial_copy)
- logop_head->oh_flags |= XLOG_WAS_CONT_TRANS;
- partial_copy_len += copy_len;
- partial_copy++;
- len += sizeof(xlog_op_header_t); /* from splitting of region */
- /* account for new log op header */
- ticket->t_curr_res -= sizeof(xlog_op_header_t);
- XLOG_TIC_ADD_OPHDR(ticket);
- }
- xlog_verify_dest_ptr(log, ptr);
-
- /* copy region */
- ASSERT(copy_len >= 0);
- memcpy((xfs_caddr_t)ptr, reg[index].i_addr + copy_off, copy_len);
- xlog_write_adv_cnt(ptr, len, log_offset, copy_len);
-
- /* make copy_len total bytes copied, including headers */
- copy_len += start_rec_copy + sizeof(xlog_op_header_t);
- record_cnt++;
- data_cnt += contwr ? copy_len : 0;
- if (partial_copy) { /* copied partial region */
- /* already marked WANT_SYNC by xlog_state_get_iclog_space */
- xlog_state_finish_copy(log, iclog, record_cnt, data_cnt);
- record_cnt = data_cnt = 0;
- if ((error = xlog_state_release_iclog(log, iclog)))
- return error;
- break; /* don't increment index */
- } else { /* copied entire region */
- index++;
- partial_copy_len = partial_copy = 0;
-
- if (iclog->ic_size - log_offset <= sizeof(xlog_op_header_t)) {
- xlog_state_finish_copy(log, iclog, record_cnt, data_cnt);
- record_cnt = data_cnt = 0;
- xlog_state_want_sync(log, iclog);
- if (commit_iclog) {
- ASSERT(flags & XLOG_COMMIT_TRANS);
- *commit_iclog = iclog;
- } else if ((error = xlog_state_release_iclog(log, iclog)))
- return error;
- if (index == nentries)
- return 0; /* we are done */
- else
- break;
- }
- } /* if (partial_copy) */
- } /* while (index < nentries) */
- } /* for (index = 0; index < nentries; ) */
- ASSERT(len == 0);
-
- xlog_state_finish_copy(log, iclog, record_cnt, data_cnt);
- if (commit_iclog) {
- ASSERT(flags & XLOG_COMMIT_TRANS);
- *commit_iclog = iclog;
- return 0;
- }
- return xlog_state_release_iclog(log, iclog);
-} /* xlog_write */
-
-
-/*****************************************************************************
- *
- * State Machine functions
- *
- *****************************************************************************
- */
-
-/* Clean iclogs starting from the head. This ordering must be
- * maintained, so an iclog doesn't become ACTIVE beyond one that
- * is SYNCING. This is also required to maintain the notion that we use
- * a counting semaphore to hold off would be writers to the log when every
- * iclog is trying to sync to disk.
- *
- * State Change: DIRTY -> ACTIVE
- */
-STATIC void
-xlog_state_clean_log(xlog_t *log)
-{
- xlog_in_core_t *iclog;
- int changed = 0;
-
- iclog = log->l_iclog;
- do {
- if (iclog->ic_state == XLOG_STATE_DIRTY) {
- iclog->ic_state = XLOG_STATE_ACTIVE;
- iclog->ic_offset = 0;
- iclog->ic_callback = NULL; /* don't need to free */
- /*
- * If the number of ops in this iclog indicate it just
- * contains the dummy transaction, we can
- * change state into IDLE (the second time around).
- * Otherwise we should change the state into
- * NEED a dummy.
- * We don't need to cover the dummy.
- */
- if (!changed &&
- (INT_GET(iclog->ic_header.h_num_logops, ARCH_CONVERT) == XLOG_COVER_OPS)) {
- changed = 1;
- } else {
- /*
- * We have two dirty iclogs so start over
- * This could also be num of ops indicates
- * this is not the dummy going out.
- */
- changed = 2;
- }
- iclog->ic_header.h_num_logops = 0;
- memset(iclog->ic_header.h_cycle_data, 0,
- sizeof(iclog->ic_header.h_cycle_data));
- iclog->ic_header.h_lsn = 0;
- } else if (iclog->ic_state == XLOG_STATE_ACTIVE)
- /* do nothing */;
- else
- break; /* stop cleaning */
- iclog = iclog->ic_next;
- } while (iclog != log->l_iclog);
-
- /* log is locked when we are called */
- /*
- * Change state for the dummy log recording.
- * We usually go to NEED. But we go to NEED2 if the changed indicates
- * we are done writing the dummy record.
- * If we are done with the second dummy recored (DONE2), then
- * we go to IDLE.
- */
- if (changed) {
- switch (log->l_covered_state) {
- case XLOG_STATE_COVER_IDLE:
- case XLOG_STATE_COVER_NEED:
- case XLOG_STATE_COVER_NEED2:
- log->l_covered_state = XLOG_STATE_COVER_NEED;
- break;
-
- case XLOG_STATE_COVER_DONE:
- if (changed == 1)
- log->l_covered_state = XLOG_STATE_COVER_NEED2;
- else
- log->l_covered_state = XLOG_STATE_COVER_NEED;
- break;
-
- case XLOG_STATE_COVER_DONE2:
- if (changed == 1)
- log->l_covered_state = XLOG_STATE_COVER_IDLE;
- else
- log->l_covered_state = XLOG_STATE_COVER_NEED;
- break;
-
- default:
- ASSERT(0);
- }
- }
-} /* xlog_state_clean_log */
-
-STATIC xfs_lsn_t
-xlog_get_lowest_lsn(
- xlog_t *log)
-{
- xlog_in_core_t *lsn_log;
- xfs_lsn_t lowest_lsn, lsn;
-
- lsn_log = log->l_iclog;
- lowest_lsn = 0;
- do {
- if (!(lsn_log->ic_state & (XLOG_STATE_ACTIVE|XLOG_STATE_DIRTY))) {
- lsn = INT_GET(lsn_log->ic_header.h_lsn, ARCH_CONVERT);
- if ((lsn && !lowest_lsn) ||
- (XFS_LSN_CMP(lsn, lowest_lsn) < 0)) {
- lowest_lsn = lsn;
- }
- }
- lsn_log = lsn_log->ic_next;
- } while (lsn_log != log->l_iclog);
- return lowest_lsn;
-}
-
-
-STATIC void
-xlog_state_do_callback(
- xlog_t *log,
- int aborted,
- xlog_in_core_t *ciclog)
-{
- xlog_in_core_t *iclog;
- xlog_in_core_t *first_iclog; /* used to know when we've
- * processed all iclogs once */
- xfs_log_callback_t *cb, *cb_next;
- int flushcnt = 0;
- xfs_lsn_t lowest_lsn;
- int ioerrors; /* counter: iclogs with errors */
- int loopdidcallbacks; /* flag: inner loop did callbacks*/
- int funcdidcallbacks; /* flag: function did callbacks */
- int repeats; /* for issuing console warnings if
- * looping too many times */
- SPLDECL(s);
-
- s = LOG_LOCK(log);
- first_iclog = iclog = log->l_iclog;
- ioerrors = 0;
- funcdidcallbacks = 0;
- repeats = 0;
-
- do {
- /*
- * Scan all iclogs starting with the one pointed to by the
- * log. Reset this starting point each time the log is
- * unlocked (during callbacks).
- *
- * Keep looping through iclogs until one full pass is made
- * without running any callbacks.
- */
- first_iclog = log->l_iclog;
- iclog = log->l_iclog;
- loopdidcallbacks = 0;
- repeats++;
-
- do {
-
- /* skip all iclogs in the ACTIVE & DIRTY states */
- if (iclog->ic_state &
- (XLOG_STATE_ACTIVE|XLOG_STATE_DIRTY)) {
- iclog = iclog->ic_next;
- continue;
- }
-
- /*
- * Between marking a filesystem SHUTDOWN and stopping
- * the log, we do flush all iclogs to disk (if there
- * wasn't a log I/O error). So, we do want things to
- * go smoothly in case of just a SHUTDOWN w/o a
- * LOG_IO_ERROR.
- */
- if (!(iclog->ic_state & XLOG_STATE_IOERROR)) {
- /*
- * Can only perform callbacks in order. Since
- * this iclog is not in the DONE_SYNC/
- * DO_CALLBACK state, we skip the rest and
- * just try to clean up. If we set our iclog
- * to DO_CALLBACK, we will not process it when
- * we retry since a previous iclog is in the
- * CALLBACK and the state cannot change since
- * we are holding the LOG_LOCK.
- */
- if (!(iclog->ic_state &
- (XLOG_STATE_DONE_SYNC |
- XLOG_STATE_DO_CALLBACK))) {
- if (ciclog && (ciclog->ic_state ==
- XLOG_STATE_DONE_SYNC)) {
- ciclog->ic_state = XLOG_STATE_DO_CALLBACK;
- }
- break;
- }
- /*
- * We now have an iclog that is in either the
- * DO_CALLBACK or DONE_SYNC states. The other
- * states (WANT_SYNC, SYNCING, or CALLBACK were
- * caught by the above if and are going to
- * clean (i.e. we aren't doing their callbacks)
- * see the above if.
- */
-
- /*
- * We will do one more check here to see if we
- * have chased our tail around.
- */
-
- lowest_lsn = xlog_get_lowest_lsn(log);
- if (lowest_lsn && (
- XFS_LSN_CMP(
- lowest_lsn,
- INT_GET(iclog->ic_header.h_lsn, ARCH_CONVERT)
- )<0)) {
- iclog = iclog->ic_next;
- continue; /* Leave this iclog for
- * another thread */
- }
-
- iclog->ic_state = XLOG_STATE_CALLBACK;
-
- LOG_UNLOCK(log, s);
-
- /* l_last_sync_lsn field protected by
- * GRANT_LOCK. Don't worry about iclog's lsn.
- * No one else can be here except us.
- */
- s = GRANT_LOCK(log);
- ASSERT(XFS_LSN_CMP(
- log->l_last_sync_lsn,
- INT_GET(iclog->ic_header.h_lsn, ARCH_CONVERT)
- )<=0);
- log->l_last_sync_lsn = INT_GET(iclog->ic_header.h_lsn, ARCH_CONVERT);
- GRANT_UNLOCK(log, s);
-
- /*
- * Keep processing entries in the callback list
- * until we come around and it is empty. We
- * need to atomically see that the list is
- * empty and change the state to DIRTY so that
- * we don't miss any more callbacks being added.
- */
- s = LOG_LOCK(log);
- } else {
- ioerrors++;
- }
- cb = iclog->ic_callback;
-
- while (cb != 0) {
- iclog->ic_callback_tail = &(iclog->ic_callback);
- iclog->ic_callback = NULL;
- LOG_UNLOCK(log, s);
-
- /* perform callbacks in the order given */
- for (; cb != 0; cb = cb_next) {
- cb_next = cb->cb_next;
- cb->cb_func(cb->cb_arg, aborted);
- }
- s = LOG_LOCK(log);
- cb = iclog->ic_callback;
- }
-
- loopdidcallbacks++;
- funcdidcallbacks++;
-
- ASSERT(iclog->ic_callback == 0);
- if (!(iclog->ic_state & XLOG_STATE_IOERROR))
- iclog->ic_state = XLOG_STATE_DIRTY;
-
- /*
- * Transition from DIRTY to ACTIVE if applicable.
- * NOP if STATE_IOERROR.
- */
- xlog_state_clean_log(log);
-
- /* wake up threads waiting in xfs_log_force() */
- sv_broadcast(&iclog->ic_forcesema);
-
- iclog = iclog->ic_next;
- } while (first_iclog != iclog);
- if (repeats && (repeats % 10) == 0) {
- xfs_fs_cmn_err(CE_WARN, log->l_mp,
- "xlog_state_do_callback: looping %d", repeats);
- }
- } while (!ioerrors && loopdidcallbacks);
-
- /*
- * make one last gasp attempt to see if iclogs are being left in
- * limbo..
- */
-#ifdef DEBUG
- if (funcdidcallbacks) {
- first_iclog = iclog = log->l_iclog;
- do {
- ASSERT(iclog->ic_state != XLOG_STATE_DO_CALLBACK);
- /*
- * Terminate the loop if iclogs are found in states
- * which will cause other threads to clean up iclogs.
- *
- * SYNCING - i/o completion will go through logs
- * DONE_SYNC - interrupt thread should be waiting for
- * LOG_LOCK
- * IOERROR - give up hope all ye who enter here
- */
- if (iclog->ic_state == XLOG_STATE_WANT_SYNC ||
- iclog->ic_state == XLOG_STATE_SYNCING ||
- iclog->ic_state == XLOG_STATE_DONE_SYNC ||
- iclog->ic_state == XLOG_STATE_IOERROR )
- break;
- iclog = iclog->ic_next;
- } while (first_iclog != iclog);
- }
-#endif
-
- if (log->l_iclog->ic_state & (XLOG_STATE_ACTIVE|XLOG_STATE_IOERROR)) {
- flushcnt = log->l_flushcnt;
- log->l_flushcnt = 0;
- }
- LOG_UNLOCK(log, s);
- while (flushcnt--)
- vsema(&log->l_flushsema);
-} /* xlog_state_do_callback */
-
-
-/*
- * Finish transitioning this iclog to the dirty state.
- *
- * Make sure that we completely execute this routine only when this is
- * the last call to the iclog. There is a good chance that iclog flushes,
- * when we reach the end of the physical log, get turned into 2 separate
- * calls to bwrite. Hence, one iclog flush could generate two calls to this
- * routine. By using the reference count bwritecnt, we guarantee that only
- * the second completion goes through.
- *
- * Callbacks could take time, so they are done outside the scope of the
- * global state machine log lock. Assume that the calls to cvsema won't
- * take a long time. At least we know it won't sleep.
- */
-void
-xlog_state_done_syncing(
- xlog_in_core_t *iclog,
- int aborted)
-{
- xlog_t *log = iclog->ic_log;
- SPLDECL(s);
-
- s = LOG_LOCK(log);
-
- ASSERT(iclog->ic_state == XLOG_STATE_SYNCING ||
- iclog->ic_state == XLOG_STATE_IOERROR);
- ASSERT(iclog->ic_refcnt == 0);
- ASSERT(iclog->ic_bwritecnt == 1 || iclog->ic_bwritecnt == 2);
-
-
- /*
- * If we got an error, either on the first buffer, or in the case of
- * split log writes, on the second, we mark ALL iclogs STATE_IOERROR,
- * and none should ever be attempted to be written to disk
- * again.
- */
- if (iclog->ic_state != XLOG_STATE_IOERROR) {
- if (--iclog->ic_bwritecnt == 1) {
- LOG_UNLOCK(log, s);
- return;
- }
- iclog->ic_state = XLOG_STATE_DONE_SYNC;
- }
-
- /*
- * Someone could be sleeping prior to writing out the next
- * iclog buffer, we wake them all, one will get to do the
- * I/O, the others get to wait for the result.
- */
- sv_broadcast(&iclog->ic_writesema);
- LOG_UNLOCK(log, s);
- xlog_state_do_callback(log, aborted, iclog); /* also cleans log */
-} /* xlog_state_done_syncing */
-
-
-/*
- * If the head of the in-core log ring is not (ACTIVE or DIRTY), then we must
- * sleep. The flush semaphore is set to the number of in-core buffers and
- * decremented around disk syncing. Therefore, if all buffers are syncing,
- * this semaphore will cause new writes to sleep until a sync completes.
- * Otherwise, this code just does p() followed by v(). This approximates
- * a sleep/wakeup except we can't race.
- *
- * The in-core logs are used in a circular fashion. They are not used
- * out-of-order even when an iclog past the head is free.
- *
- * return:
- * * log_offset where xlog_write() can start writing into the in-core
- * log's data space.
- * * in-core log pointer to which xlog_write() should write.
- * * boolean indicating this is a continued write to an in-core log.
- * If this is the last write, then the in-core log's offset field
- * needs to be incremented, depending on the amount of data which
- * is copied.
- */
-int
-xlog_state_get_iclog_space(xlog_t *log,
- int len,
- xlog_in_core_t **iclogp,
- xlog_ticket_t *ticket,
- int *continued_write,
- int *logoffsetp)
-{
- SPLDECL(s);
- int log_offset;
- xlog_rec_header_t *head;
- xlog_in_core_t *iclog;
- int error;
-
-restart:
- s = LOG_LOCK(log);
- if (XLOG_FORCED_SHUTDOWN(log)) {
- LOG_UNLOCK(log, s);
- return XFS_ERROR(EIO);
- }
-
- iclog = log->l_iclog;
- if (! (iclog->ic_state == XLOG_STATE_ACTIVE)) {
- log->l_flushcnt++;
- LOG_UNLOCK(log, s);
- xlog_trace_iclog(iclog, XLOG_TRACE_SLEEP_FLUSH);
- XFS_STATS_INC(xs_log_noiclogs);
- /* Ensure that log writes happen */
- psema(&log->l_flushsema, PINOD);
- goto restart;
- }
- ASSERT(iclog->ic_state == XLOG_STATE_ACTIVE);
- head = &iclog->ic_header;
-
- iclog->ic_refcnt++; /* prevents sync */
- log_offset = iclog->ic_offset;
-
- /* On the 1st write to an iclog, figure out lsn. This works
- * if iclogs marked XLOG_STATE_WANT_SYNC always write out what they are
- * committing to. If the offset is set, that's how many blocks
- * must be written.
- */
- if (log_offset == 0) {
- ticket->t_curr_res -= log->l_iclog_hsize;
- XLOG_TIC_ADD_REGION(ticket,
- log->l_iclog_hsize,
- XLOG_REG_TYPE_LRHEADER);
- INT_SET(head->h_cycle, ARCH_CONVERT, log->l_curr_cycle);
- ASSIGN_LSN(head->h_lsn, log);
- ASSERT(log->l_curr_block >= 0);
- }
-
- /* If there is enough room to write everything, then do it. Otherwise,
- * claim the rest of the region and make sure the XLOG_STATE_WANT_SYNC
- * bit is on, so this will get flushed out. Don't update ic_offset
- * until you know exactly how many bytes get copied. Therefore, wait
- * until later to update ic_offset.
- *
- * xlog_write() algorithm assumes that at least 2 xlog_op_header_t's
- * can fit into remaining data section.
- */
- if (iclog->ic_size - iclog->ic_offset < 2*sizeof(xlog_op_header_t)) {
- xlog_state_switch_iclogs(log, iclog, iclog->ic_size);
-
- /* If I'm the only one writing to this iclog, sync it to disk */
- if (iclog->ic_refcnt == 1) {
- LOG_UNLOCK(log, s);
- if ((error = xlog_state_release_iclog(log, iclog)))
- return error;
- } else {
- iclog->ic_refcnt--;
- LOG_UNLOCK(log, s);
- }
- goto restart;
- }
-
- /* Do we have enough room to write the full amount in the remainder
- * of this iclog? Or must we continue a write on the next iclog and
- * mark this iclog as completely taken? In the case where we switch
- * iclogs (to mark it taken), this particular iclog will release/sync
- * to disk in xlog_write().
- */
- if (len <= iclog->ic_size - iclog->ic_offset) {
- *continued_write = 0;
- iclog->ic_offset += len;
- } else {
- *continued_write = 1;
- xlog_state_switch_iclogs(log, iclog, iclog->ic_size);
- }
- *iclogp = iclog;
-
- ASSERT(iclog->ic_offset <= iclog->ic_size);
- LOG_UNLOCK(log, s);
-
- *logoffsetp = log_offset;
- return 0;
-} /* xlog_state_get_iclog_space */
-
-/*
- * Atomically get the log space required for a log ticket.
- *
- * Once a ticket gets put onto the reserveq, it will only return after
- * the needed reservation is satisfied.
- */
-STATIC int
-xlog_grant_log_space(xlog_t *log,
- xlog_ticket_t *tic)
-{
- int free_bytes;
- int need_bytes;
- SPLDECL(s);
-#ifdef DEBUG
- xfs_lsn_t tail_lsn;
-#endif
-
-
-#ifdef DEBUG
- if (log->l_flags & XLOG_ACTIVE_RECOVERY)
- panic("grant Recovery problem");
-#endif
-
- /* Is there space or do we need to sleep? */
- s = GRANT_LOCK(log);
- xlog_trace_loggrant(log, tic, "xlog_grant_log_space: enter");
-
- /* something is already sleeping; insert new transaction at end */
- if (log->l_reserve_headq) {
- xlog_ins_ticketq(&log->l_reserve_headq, tic);
- xlog_trace_loggrant(log, tic,
- "xlog_grant_log_space: sleep 1");
- /*
- * Gotta check this before going to sleep, while we're
- * holding the grant lock.
- */
- if (XLOG_FORCED_SHUTDOWN(log))
- goto error_return;
-
- XFS_STATS_INC(xs_sleep_logspace);
- sv_wait(&tic->t_sema, PINOD|PLTWAIT, &log->l_grant_lock, s);
- /*
- * If we got an error, and the filesystem is shutting down,
- * we'll catch it down below. So just continue...
- */
- xlog_trace_loggrant(log, tic,
- "xlog_grant_log_space: wake 1");
- s = GRANT_LOCK(log);
- }
- if (tic->t_flags & XFS_LOG_PERM_RESERV)
- need_bytes = tic->t_unit_res*tic->t_ocnt;
- else
- need_bytes = tic->t_unit_res;
-
-redo:
- if (XLOG_FORCED_SHUTDOWN(log))
- goto error_return;
-
- free_bytes = xlog_space_left(log, log->l_grant_reserve_cycle,
- log->l_grant_reserve_bytes);
- if (free_bytes < need_bytes) {
- if ((tic->t_flags & XLOG_TIC_IN_Q) == 0)
- xlog_ins_ticketq(&log->l_reserve_headq, tic);
- xlog_trace_loggrant(log, tic,
- "xlog_grant_log_space: sleep 2");
- XFS_STATS_INC(xs_sleep_logspace);
- sv_wait(&tic->t_sema, PINOD|PLTWAIT, &log->l_grant_lock, s);
-
- if (XLOG_FORCED_SHUTDOWN(log)) {
- s = GRANT_LOCK(log);
- goto error_return;
- }
-
- xlog_trace_loggrant(log, tic,
- "xlog_grant_log_space: wake 2");
- xlog_grant_push_ail(log->l_mp, need_bytes);
- s = GRANT_LOCK(log);
- goto redo;
- } else if (tic->t_flags & XLOG_TIC_IN_Q)
- xlog_del_ticketq(&log->l_reserve_headq, tic);
-
- /* we've got enough space */
- xlog_grant_add_space(log, need_bytes);
-#ifdef DEBUG
- tail_lsn = log->l_tail_lsn;
- /*
- * Check to make sure the grant write head didn't just over lap the
- * tail. If the cycles are the same, we can't be overlapping.
- * Otherwise, make sure that the cycles differ by exactly one and
- * check the byte count.
- */
- if (CYCLE_LSN(tail_lsn) != log->l_grant_write_cycle) {
- ASSERT(log->l_grant_write_cycle-1 == CYCLE_LSN(tail_lsn));
- ASSERT(log->l_grant_write_bytes <= BBTOB(BLOCK_LSN(tail_lsn)));
- }
-#endif
- xlog_trace_loggrant(log, tic, "xlog_grant_log_space: exit");
- xlog_verify_grant_head(log, 1);
- GRANT_UNLOCK(log, s);
- return 0;
-
- error_return:
- if (tic->t_flags & XLOG_TIC_IN_Q)
- xlog_del_ticketq(&log->l_reserve_headq, tic);
- xlog_trace_loggrant(log, tic, "xlog_grant_log_space: err_ret");
- /*
- * If we are failing, make sure the ticket doesn't have any
- * current reservations. We don't want to add this back when
- * the ticket/transaction gets cancelled.
- */
- tic->t_curr_res = 0;
- tic->t_cnt = 0; /* ungrant will give back unit_res * t_cnt. */
- GRANT_UNLOCK(log, s);
- return XFS_ERROR(EIO);
-} /* xlog_grant_log_space */
-
-
-/*
- * Replenish the byte reservation required by moving the grant write head.
- *
- *
- */
-STATIC int
-xlog_regrant_write_log_space(xlog_t *log,
- xlog_ticket_t *tic)
-{
- SPLDECL(s);
- int free_bytes, need_bytes;
- xlog_ticket_t *ntic;
-#ifdef DEBUG
- xfs_lsn_t tail_lsn;
-#endif
-
- tic->t_curr_res = tic->t_unit_res;
- XLOG_TIC_RESET_RES(tic);
-
- if (tic->t_cnt > 0)
- return 0;
-
-#ifdef DEBUG
- if (log->l_flags & XLOG_ACTIVE_RECOVERY)
- panic("regrant Recovery problem");
-#endif
-
- s = GRANT_LOCK(log);
- xlog_trace_loggrant(log, tic, "xlog_regrant_write_log_space: enter");
-
- if (XLOG_FORCED_SHUTDOWN(log))
- goto error_return;
-
- /* If there are other waiters on the queue then give them a
- * chance at logspace before us. Wake up the first waiters,
- * if we do not wake up all the waiters then go to sleep waiting
- * for more free space, otherwise try to get some space for
- * this transaction.
- */
-
- if ((ntic = log->l_write_headq)) {
- free_bytes = xlog_space_left(log, log->l_grant_write_cycle,
- log->l_grant_write_bytes);
- do {
- ASSERT(ntic->t_flags & XLOG_TIC_PERM_RESERV);
-
- if (free_bytes < ntic->t_unit_res)
- break;
- free_bytes -= ntic->t_unit_res;
- sv_signal(&ntic->t_sema);
- ntic = ntic->t_next;
- } while (ntic != log->l_write_headq);
-
- if (ntic != log->l_write_headq) {
- if ((tic->t_flags & XLOG_TIC_IN_Q) == 0)
- xlog_ins_ticketq(&log->l_write_headq, tic);
-
- xlog_trace_loggrant(log, tic,
- "xlog_regrant_write_log_space: sleep 1");
- XFS_STATS_INC(xs_sleep_logspace);
- sv_wait(&tic->t_sema, PINOD|PLTWAIT,
- &log->l_grant_lock, s);
-
- /* If we're shutting down, this tic is already
- * off the queue */
- if (XLOG_FORCED_SHUTDOWN(log)) {
- s = GRANT_LOCK(log);
- goto error_return;
- }
-
- xlog_trace_loggrant(log, tic,
- "xlog_regrant_write_log_space: wake 1");
- xlog_grant_push_ail(log->l_mp, tic->t_unit_res);
- s = GRANT_LOCK(log);
- }
- }
-
- need_bytes = tic->t_unit_res;
-
-redo:
- if (XLOG_FORCED_SHUTDOWN(log))
- goto error_return;
-
- free_bytes = xlog_space_left(log, log->l_grant_write_cycle,
- log->l_grant_write_bytes);
- if (free_bytes < need_bytes) {
- if ((tic->t_flags & XLOG_TIC_IN_Q) == 0)
- xlog_ins_ticketq(&log->l_write_headq, tic);
- XFS_STATS_INC(xs_sleep_logspace);
- sv_wait(&tic->t_sema, PINOD|PLTWAIT, &log->l_grant_lock, s);
-
- /* If we're shutting down, this tic is already off the queue */
- if (XLOG_FORCED_SHUTDOWN(log)) {
- s = GRANT_LOCK(log);
- goto error_return;
- }
-
- xlog_trace_loggrant(log, tic,
- "xlog_regrant_write_log_space: wake 2");
- xlog_grant_push_ail(log->l_mp, need_bytes);
- s = GRANT_LOCK(log);
- goto redo;
- } else if (tic->t_flags & XLOG_TIC_IN_Q)
- xlog_del_ticketq(&log->l_write_headq, tic);
-
- /* we've got enough space */
- xlog_grant_add_space_write(log, need_bytes);
-#ifdef DEBUG
- tail_lsn = log->l_tail_lsn;
- if (CYCLE_LSN(tail_lsn) != log->l_grant_write_cycle) {
- ASSERT(log->l_grant_write_cycle-1 == CYCLE_LSN(tail_lsn));
- ASSERT(log->l_grant_write_bytes <= BBTOB(BLOCK_LSN(tail_lsn)));
- }
-#endif
-
- xlog_trace_loggrant(log, tic, "xlog_regrant_write_log_space: exit");
- xlog_verify_grant_head(log, 1);
- GRANT_UNLOCK(log, s);
- return 0;
-
-
- error_return:
- if (tic->t_flags & XLOG_TIC_IN_Q)
- xlog_del_ticketq(&log->l_reserve_headq, tic);
- xlog_trace_loggrant(log, tic, "xlog_regrant_write_log_space: err_ret");
- /*
- * If we are failing, make sure the ticket doesn't have any
- * current reservations. We don't want to add this back when
- * the ticket/transaction gets cancelled.
- */
- tic->t_curr_res = 0;
- tic->t_cnt = 0; /* ungrant will give back unit_res * t_cnt. */
- GRANT_UNLOCK(log, s);
- return XFS_ERROR(EIO);
-} /* xlog_regrant_write_log_space */
-
-
-/* The first cnt-1 times through here we don't need to
- * move the grant write head because the permanent
- * reservation has reserved cnt times the unit amount.
- * Release part of current permanent unit reservation and
- * reset current reservation to be one units worth. Also
- * move grant reservation head forward.
- */
-STATIC void
-xlog_regrant_reserve_log_space(xlog_t *log,
- xlog_ticket_t *ticket)
-{
- SPLDECL(s);
-
- xlog_trace_loggrant(log, ticket,
- "xlog_regrant_reserve_log_space: enter");
- if (ticket->t_cnt > 0)
- ticket->t_cnt--;
-
- s = GRANT_LOCK(log);
- xlog_grant_sub_space(log, ticket->t_curr_res);
- ticket->t_curr_res = ticket->t_unit_res;
- XLOG_TIC_RESET_RES(ticket);
- xlog_trace_loggrant(log, ticket,
- "xlog_regrant_reserve_log_space: sub current res");
- xlog_verify_grant_head(log, 1);
-
- /* just return if we still have some of the pre-reserved space */
- if (ticket->t_cnt > 0) {
- GRANT_UNLOCK(log, s);
- return;
- }
-
- xlog_grant_add_space_reserve(log, ticket->t_unit_res);
- xlog_trace_loggrant(log, ticket,
- "xlog_regrant_reserve_log_space: exit");
- xlog_verify_grant_head(log, 0);
- GRANT_UNLOCK(log, s);
- ticket->t_curr_res = ticket->t_unit_res;
- XLOG_TIC_RESET_RES(ticket);
-} /* xlog_regrant_reserve_log_space */
-
-
-/*
- * Give back the space left from a reservation.
- *
- * All the information we need to make a correct determination of space left
- * is present. For non-permanent reservations, things are quite easy. The
- * count should have been decremented to zero. We only need to deal with the
- * space remaining in the current reservation part of the ticket. If the
- * ticket contains a permanent reservation, there may be left over space which
- * needs to be released. A count of N means that N-1 refills of the current
- * reservation can be done before we need to ask for more space. The first
- * one goes to fill up the first current reservation. Once we run out of
- * space, the count will stay at zero and the only space remaining will be
- * in the current reservation field.
- */
-STATIC void
-xlog_ungrant_log_space(xlog_t *log,
- xlog_ticket_t *ticket)
-{
- SPLDECL(s);
-
- if (ticket->t_cnt > 0)
- ticket->t_cnt--;
-
- s = GRANT_LOCK(log);
- xlog_trace_loggrant(log, ticket, "xlog_ungrant_log_space: enter");
-
- xlog_grant_sub_space(log, ticket->t_curr_res);
-
- xlog_trace_loggrant(log, ticket, "xlog_ungrant_log_space: sub current");
-
- /* If this is a permanent reservation ticket, we may be able to free
- * up more space based on the remaining count.
- */
- if (ticket->t_cnt > 0) {
- ASSERT(ticket->t_flags & XLOG_TIC_PERM_RESERV);
- xlog_grant_sub_space(log, ticket->t_unit_res*ticket->t_cnt);
- }
-
- xlog_trace_loggrant(log, ticket, "xlog_ungrant_log_space: exit");
- xlog_verify_grant_head(log, 1);
- GRANT_UNLOCK(log, s);
- xfs_log_move_tail(log->l_mp, 1);
-} /* xlog_ungrant_log_space */
-
-
-/*
- * Atomically put back used ticket.
- */
-void
-xlog_state_put_ticket(xlog_t *log,
- xlog_ticket_t *tic)
-{
- unsigned long s;
-
- s = LOG_LOCK(log);
- xlog_ticket_put(log, tic);
- LOG_UNLOCK(log, s);
-} /* xlog_state_put_ticket */
-
-/*
- * Flush iclog to disk if this is the last reference to the given iclog and
- * the WANT_SYNC bit is set.
- *
- * When this function is entered, the iclog is not necessarily in the
- * WANT_SYNC state. It may be sitting around waiting to get filled.
- *
- *
- */
-int
-xlog_state_release_iclog(xlog_t *log,
- xlog_in_core_t *iclog)
-{
- SPLDECL(s);
- int sync = 0; /* do we sync? */
-
- xlog_assign_tail_lsn(log->l_mp);
-
- s = LOG_LOCK(log);
-
- if (iclog->ic_state & XLOG_STATE_IOERROR) {
- LOG_UNLOCK(log, s);
- return XFS_ERROR(EIO);
- }
-
- ASSERT(iclog->ic_refcnt > 0);
- ASSERT(iclog->ic_state == XLOG_STATE_ACTIVE ||
- iclog->ic_state == XLOG_STATE_WANT_SYNC);
-
- if (--iclog->ic_refcnt == 0 &&
- iclog->ic_state == XLOG_STATE_WANT_SYNC) {
- sync++;
- iclog->ic_state = XLOG_STATE_SYNCING;
- INT_SET(iclog->ic_header.h_tail_lsn, ARCH_CONVERT, log->l_tail_lsn);
- xlog_verify_tail_lsn(log, iclog, log->l_tail_lsn);
- /* cycle incremented when incrementing curr_block */
- }
-
- LOG_UNLOCK(log, s);
-
- /*
- * We let the log lock go, so it's possible that we hit a log I/O
- * error or some other SHUTDOWN condition that marks the iclog
- * as XLOG_STATE_IOERROR before the bwrite. However, we know that
- * this iclog has consistent data, so we ignore IOERROR
- * flags after this point.
- */
- if (sync) {
- return xlog_sync(log, iclog);
- }
- return 0;
-
-} /* xlog_state_release_iclog */
-
-
-/*
- * This routine will mark the current iclog in the ring as WANT_SYNC
- * and move the current iclog pointer to the next iclog in the ring.
- * When this routine is called from xlog_state_get_iclog_space(), the
- * exact size of the iclog has not yet been determined. All we know is
- * that every data block. We have run out of space in this log record.
- */
-STATIC void
-xlog_state_switch_iclogs(xlog_t *log,
- xlog_in_core_t *iclog,
- int eventual_size)
-{
- ASSERT(iclog->ic_state == XLOG_STATE_ACTIVE);
- if (!eventual_size)
- eventual_size = iclog->ic_offset;
- iclog->ic_state = XLOG_STATE_WANT_SYNC;
- INT_SET(iclog->ic_header.h_prev_block, ARCH_CONVERT, log->l_prev_block);
- log->l_prev_block = log->l_curr_block;
- log->l_prev_cycle = log->l_curr_cycle;
-
- /* roll log?: ic_offset changed later */
- log->l_curr_block += BTOBB(eventual_size)+BTOBB(log->l_iclog_hsize);
-
- /* Round up to next log-sunit */
- if (XFS_SB_VERSION_HASLOGV2(&log->l_mp->m_sb) &&
- log->l_mp->m_sb.sb_logsunit > 1) {
- __uint32_t sunit_bb = BTOBB(log->l_mp->m_sb.sb_logsunit);
- log->l_curr_block = roundup(log->l_curr_block, sunit_bb);
- }
-
- if (log->l_curr_block >= log->l_logBBsize) {
- log->l_curr_cycle++;
- if (log->l_curr_cycle == XLOG_HEADER_MAGIC_NUM)
- log->l_curr_cycle++;
- log->l_curr_block -= log->l_logBBsize;
- ASSERT(log->l_curr_block >= 0);
- }
- ASSERT(iclog == log->l_iclog);
- log->l_iclog = iclog->ic_next;
-} /* xlog_state_switch_iclogs */
-
-
-/*
- * Write out all data in the in-core log as of this exact moment in time.
- *
- * Data may be written to the in-core log during this call. However,
- * we don't guarantee this data will be written out. A change from past
- * implementation means this routine will *not* write out zero length LRs.
- *
- * Basically, we try and perform an intelligent scan of the in-core logs.
- * If we determine there is no flushable data, we just return. There is no
- * flushable data if:
- *
- * 1. the current iclog is active and has no data; the previous iclog
- * is in the active or dirty state.
- * 2. the current iclog is drity, and the previous iclog is in the
- * active or dirty state.
- *
- * We may sleep (call psema) if:
- *
- * 1. the current iclog is not in the active nor dirty state.
- * 2. the current iclog dirty, and the previous iclog is not in the
- * active nor dirty state.
- * 3. the current iclog is active, and there is another thread writing
- * to this particular iclog.
- * 4. a) the current iclog is active and has no other writers
- * b) when we return from flushing out this iclog, it is still
- * not in the active nor dirty state.
- */
-STATIC int
-xlog_state_sync_all(xlog_t *log, uint flags, int *log_flushed)
-{
- xlog_in_core_t *iclog;
- xfs_lsn_t lsn;
- SPLDECL(s);
-
- s = LOG_LOCK(log);
-
- iclog = log->l_iclog;
- if (iclog->ic_state & XLOG_STATE_IOERROR) {
- LOG_UNLOCK(log, s);
- return XFS_ERROR(EIO);
- }
-
- /* If the head iclog is not active nor dirty, we just attach
- * ourselves to the head and go to sleep.
- */
- if (iclog->ic_state == XLOG_STATE_ACTIVE ||
- iclog->ic_state == XLOG_STATE_DIRTY) {
- /*
- * If the head is dirty or (active and empty), then
- * we need to look at the previous iclog. If the previous
- * iclog is active or dirty we are done. There is nothing
- * to sync out. Otherwise, we attach ourselves to the
- * previous iclog and go to sleep.
- */
- if (iclog->ic_state == XLOG_STATE_DIRTY ||
- (iclog->ic_refcnt == 0 && iclog->ic_offset == 0)) {
- iclog = iclog->ic_prev;
- if (iclog->ic_state == XLOG_STATE_ACTIVE ||
- iclog->ic_state == XLOG_STATE_DIRTY)
- goto no_sleep;
- else
- goto maybe_sleep;
- } else {
- if (iclog->ic_refcnt == 0) {
- /* We are the only one with access to this
- * iclog. Flush it out now. There should
- * be a roundoff of zero to show that someone
- * has already taken care of the roundoff from
- * the previous sync.
- */
- iclog->ic_refcnt++;
- lsn = INT_GET(iclog->ic_header.h_lsn, ARCH_CONVERT);
- xlog_state_switch_iclogs(log, iclog, 0);
- LOG_UNLOCK(log, s);
-
- if (xlog_state_release_iclog(log, iclog))
- return XFS_ERROR(EIO);
- *log_flushed = 1;
- s = LOG_LOCK(log);
- if (INT_GET(iclog->ic_header.h_lsn, ARCH_CONVERT) == lsn &&
- iclog->ic_state != XLOG_STATE_DIRTY)
- goto maybe_sleep;
- else
- goto no_sleep;
- } else {
- /* Someone else is writing to this iclog.
- * Use its call to flush out the data. However,
- * the other thread may not force out this LR,
- * so we mark it WANT_SYNC.
- */
- xlog_state_switch_iclogs(log, iclog, 0);
- goto maybe_sleep;
- }
- }
- }
-
- /* By the time we come around again, the iclog could've been filled
- * which would give it another lsn. If we have a new lsn, just
- * return because the relevant data has been flushed.
- */
-maybe_sleep:
- if (flags & XFS_LOG_SYNC) {
- /*
- * We must check if we're shutting down here, before
- * we wait, while we're holding the LOG_LOCK.
- * Then we check again after waking up, in case our
- * sleep was disturbed by a bad news.
- */
- if (iclog->ic_state & XLOG_STATE_IOERROR) {
- LOG_UNLOCK(log, s);
- return XFS_ERROR(EIO);
- }
- XFS_STATS_INC(xs_log_force_sleep);
- sv_wait(&iclog->ic_forcesema, PINOD, &log->l_icloglock, s);
- /*
- * No need to grab the log lock here since we're
- * only deciding whether or not to return EIO
- * and the memory read should be atomic.
- */
- if (iclog->ic_state & XLOG_STATE_IOERROR)
- return XFS_ERROR(EIO);
- *log_flushed = 1;
-
- } else {
-
-no_sleep:
- LOG_UNLOCK(log, s);
- }
- return 0;
-} /* xlog_state_sync_all */
-
-
-/*
- * Used by code which implements synchronous log forces.
- *
- * Find in-core log with lsn.
- * If it is in the DIRTY state, just return.
- * If it is in the ACTIVE state, move the in-core log into the WANT_SYNC
- * state and go to sleep or return.
- * If it is in any other state, go to sleep or return.
- *
- * If filesystem activity goes to zero, the iclog will get flushed only by
- * bdflush().
- */
-int
-xlog_state_sync(xlog_t *log,
- xfs_lsn_t lsn,
- uint flags,
- int *log_flushed)
-{
- xlog_in_core_t *iclog;
- int already_slept = 0;
- SPLDECL(s);
-
-
-try_again:
- s = LOG_LOCK(log);
- iclog = log->l_iclog;
-
- if (iclog->ic_state & XLOG_STATE_IOERROR) {
- LOG_UNLOCK(log, s);
- return XFS_ERROR(EIO);
- }
-
- do {
- if (INT_GET(iclog->ic_header.h_lsn, ARCH_CONVERT) != lsn) {
- iclog = iclog->ic_next;
- continue;
- }
-
- if (iclog->ic_state == XLOG_STATE_DIRTY) {
- LOG_UNLOCK(log, s);
- return 0;
- }
-
- if (iclog->ic_state == XLOG_STATE_ACTIVE) {
- /*
- * We sleep here if we haven't already slept (e.g.
- * this is the first time we've looked at the correct
- * iclog buf) and the buffer before us is going to
- * be sync'ed. The reason for this is that if we
- * are doing sync transactions here, by waiting for
- * the previous I/O to complete, we can allow a few
- * more transactions into this iclog before we close
- * it down.
- *
- * Otherwise, we mark the buffer WANT_SYNC, and bump
- * up the refcnt so we can release the log (which drops
- * the ref count). The state switch keeps new transaction
- * commits from using this buffer. When the current commits
- * finish writing into the buffer, the refcount will drop to
- * zero and the buffer will go out then.
- */
- if (!already_slept &&
- (iclog->ic_prev->ic_state & (XLOG_STATE_WANT_SYNC |
- XLOG_STATE_SYNCING))) {
- ASSERT(!(iclog->ic_state & XLOG_STATE_IOERROR));
- XFS_STATS_INC(xs_log_force_sleep);
- sv_wait(&iclog->ic_prev->ic_writesema, PSWP,
- &log->l_icloglock, s);
- *log_flushed = 1;
- already_slept = 1;
- goto try_again;
- } else {
- iclog->ic_refcnt++;
- xlog_state_switch_iclogs(log, iclog, 0);
- LOG_UNLOCK(log, s);
- if (xlog_state_release_iclog(log, iclog))
- return XFS_ERROR(EIO);
- *log_flushed = 1;
- s = LOG_LOCK(log);
- }
- }
-
- if ((flags & XFS_LOG_SYNC) && /* sleep */
- !(iclog->ic_state & (XLOG_STATE_ACTIVE | XLOG_STATE_DIRTY))) {
-
- /*
- * Don't wait on the forcesema if we know that we've
- * gotten a log write error.
- */
- if (iclog->ic_state & XLOG_STATE_IOERROR) {
- LOG_UNLOCK(log, s);
- return XFS_ERROR(EIO);
- }
- XFS_STATS_INC(xs_log_force_sleep);
- sv_wait(&iclog->ic_forcesema, PSWP, &log->l_icloglock, s);
- /*
- * No need to grab the log lock here since we're
- * only deciding whether or not to return EIO
- * and the memory read should be atomic.
- */
- if (iclog->ic_state & XLOG_STATE_IOERROR)
- return XFS_ERROR(EIO);
- *log_flushed = 1;
- } else { /* just return */
- LOG_UNLOCK(log, s);
- }
- return 0;
-
- } while (iclog != log->l_iclog);
-
- LOG_UNLOCK(log, s);
- return 0;
-} /* xlog_state_sync */
-
-
-/*
- * Called when we want to mark the current iclog as being ready to sync to
- * disk.
- */
-void
-xlog_state_want_sync(xlog_t *log, xlog_in_core_t *iclog)
-{
- SPLDECL(s);
-
- s = LOG_LOCK(log);
-
- if (iclog->ic_state == XLOG_STATE_ACTIVE) {
- xlog_state_switch_iclogs(log, iclog, 0);
- } else {
- ASSERT(iclog->ic_state &
- (XLOG_STATE_WANT_SYNC|XLOG_STATE_IOERROR));
- }
-
- LOG_UNLOCK(log, s);
-} /* xlog_state_want_sync */
-
-
-
-/*****************************************************************************
- *
- * TICKET functions
- *
- *****************************************************************************
- */
-
-/*
- * Algorithm doesn't take into account page size. ;-(
- */
-STATIC void
-xlog_state_ticket_alloc(xlog_t *log)
-{
- xlog_ticket_t *t_list;
- xlog_ticket_t *next;
- xfs_caddr_t buf;
- uint i = (NBPP / sizeof(xlog_ticket_t)) - 2;
- SPLDECL(s);
-
- /*
- * The kmem_zalloc may sleep, so we shouldn't be holding the
- * global lock. XXXmiken: may want to use zone allocator.
- */
- buf = (xfs_caddr_t) kmem_zalloc(NBPP, KM_SLEEP);
-
- s = LOG_LOCK(log);
-
- /* Attach 1st ticket to Q, so we can keep track of allocated memory */
- t_list = (xlog_ticket_t *)buf;
- t_list->t_next = log->l_unmount_free;
- log->l_unmount_free = t_list++;
- log->l_ticket_cnt++;
- log->l_ticket_tcnt++;
-
- /* Next ticket becomes first ticket attached to ticket free list */
- if (log->l_freelist != NULL) {
- ASSERT(log->l_tail != NULL);
- log->l_tail->t_next = t_list;
- } else {
- log->l_freelist = t_list;
- }
- log->l_ticket_cnt++;
- log->l_ticket_tcnt++;
-
- /* Cycle through rest of alloc'ed memory, building up free Q */
- for ( ; i > 0; i--) {
- next = t_list + 1;
- t_list->t_next = next;
- t_list = next;
- log->l_ticket_cnt++;
- log->l_ticket_tcnt++;
- }
- t_list->t_next = NULL;
- log->l_tail = t_list;
- LOG_UNLOCK(log, s);
-} /* xlog_state_ticket_alloc */
-
-
-/*
- * Put ticket into free list
- *
- * Assumption: log lock is held around this call.
- */
-STATIC void
-xlog_ticket_put(xlog_t *log,
- xlog_ticket_t *ticket)
-{
- sv_destroy(&ticket->t_sema);
-
- /*
- * Don't think caching will make that much difference. It's
- * more important to make debug easier.
- */
-#if 0
- /* real code will want to use LIFO for caching */
- ticket->t_next = log->l_freelist;
- log->l_freelist = ticket;
- /* no need to clear fields */
-#else
- /* When we debug, it is easier if tickets are cycled */
- ticket->t_next = NULL;
- if (log->l_tail != 0) {
- log->l_tail->t_next = ticket;
- } else {
- ASSERT(log->l_freelist == 0);
- log->l_freelist = ticket;
- }
- log->l_tail = ticket;
-#endif /* DEBUG */
- log->l_ticket_cnt++;
-} /* xlog_ticket_put */
-
-
-/*
- * Grab ticket off freelist or allocation some more
- */
-xlog_ticket_t *
-xlog_ticket_get(xlog_t *log,
- int unit_bytes,
- int cnt,
- char client,
- uint xflags)
-{
- xlog_ticket_t *tic;
- uint num_headers;
- SPLDECL(s);
-
- alloc:
- if (log->l_freelist == NULL)
- xlog_state_ticket_alloc(log); /* potentially sleep */
-
- s = LOG_LOCK(log);
- if (log->l_freelist == NULL) {
- LOG_UNLOCK(log, s);
- goto alloc;
- }
- tic = log->l_freelist;
- log->l_freelist = tic->t_next;
- if (log->l_freelist == NULL)
- log->l_tail = NULL;
- log->l_ticket_cnt--;
- LOG_UNLOCK(log, s);
-
- /*
- * Permanent reservations have up to 'cnt'-1 active log operations
- * in the log. A unit in this case is the amount of space for one
- * of these log operations. Normal reservations have a cnt of 1
- * and their unit amount is the total amount of space required.
- *
- * The following lines of code account for non-transaction data
- * which occupy space in the on-disk log.
- *
- * Normal form of a transaction is:
- * <oph><trans-hdr><start-oph><reg1-oph><reg1><reg2-oph>...<commit-oph>
- * and then there are LR hdrs, split-recs and roundoff at end of syncs.
- *
- * We need to account for all the leadup data and trailer data
- * around the transaction data.
- * And then we need to account for the worst case in terms of using
- * more space.
- * The worst case will happen if:
- * - the placement of the transaction happens to be such that the
- * roundoff is at its maximum
- * - the transaction data is synced before the commit record is synced
- * i.e. <transaction-data><roundoff> | <commit-rec><roundoff>
- * Therefore the commit record is in its own Log Record.
- * This can happen as the commit record is called with its
- * own region to xlog_write().
- * This then means that in the worst case, roundoff can happen for
- * the commit-rec as well.
- * The commit-rec is smaller than padding in this scenario and so it is
- * not added separately.
- */
-
- /* for trans header */
- unit_bytes += sizeof(xlog_op_header_t);
- unit_bytes += sizeof(xfs_trans_header_t);
-
- /* for start-rec */
- unit_bytes += sizeof(xlog_op_header_t);
-
- /* for LR headers */
- num_headers = ((unit_bytes + log->l_iclog_size-1) >> log->l_iclog_size_log);
- unit_bytes += log->l_iclog_hsize * num_headers;
-
- /* for commit-rec LR header - note: padding will subsume the ophdr */
- unit_bytes += log->l_iclog_hsize;
-
- /* for split-recs - ophdrs added when data split over LRs */
- unit_bytes += sizeof(xlog_op_header_t) * num_headers;
-
- /* for roundoff padding for transaction data and one for commit record */
- if (XFS_SB_VERSION_HASLOGV2(&log->l_mp->m_sb) &&
- log->l_mp->m_sb.sb_logsunit > 1) {
- /* log su roundoff */
- unit_bytes += 2*log->l_mp->m_sb.sb_logsunit;
- } else {
- /* BB roundoff */
- unit_bytes += 2*BBSIZE;
- }
-
- tic->t_unit_res = unit_bytes;
- tic->t_curr_res = unit_bytes;
- tic->t_cnt = cnt;
- tic->t_ocnt = cnt;
- tic->t_tid = (xlog_tid_t)((__psint_t)tic & 0xffffffff);
- tic->t_clientid = client;
- tic->t_flags = XLOG_TIC_INITED;
- tic->t_trans_type = 0;
- if (xflags & XFS_LOG_PERM_RESERV)
- tic->t_flags |= XLOG_TIC_PERM_RESERV;
- sv_init(&(tic->t_sema), SV_DEFAULT, "logtick");
-
- XLOG_TIC_RESET_RES(tic);
-
- return tic;
-} /* xlog_ticket_get */
-
-
-/******************************************************************************
- *
- * Log debug routines
- *
- ******************************************************************************
- */
-#if defined(DEBUG)
-/*
- * Make sure that the destination ptr is within the valid data region of
- * one of the iclogs. This uses backup pointers stored in a different
- * part of the log in case we trash the log structure.
- */
-void
-xlog_verify_dest_ptr(xlog_t *log,
- __psint_t ptr)
-{
- int i;
- int good_ptr = 0;
-
- for (i=0; i < log->l_iclog_bufs; i++) {
- if (ptr >= (__psint_t)log->l_iclog_bak[i] &&
- ptr <= (__psint_t)log->l_iclog_bak[i]+log->l_iclog_size)
- good_ptr++;
- }
- if (! good_ptr)
- xlog_panic("xlog_verify_dest_ptr: invalid ptr");
-} /* xlog_verify_dest_ptr */
-
-STATIC void
-xlog_verify_grant_head(xlog_t *log, int equals)
-{
- if (log->l_grant_reserve_cycle == log->l_grant_write_cycle) {
- if (equals)
- ASSERT(log->l_grant_reserve_bytes >= log->l_grant_write_bytes);
- else
- ASSERT(log->l_grant_reserve_bytes > log->l_grant_write_bytes);
- } else {
- ASSERT(log->l_grant_reserve_cycle-1 == log->l_grant_write_cycle);
- ASSERT(log->l_grant_write_bytes >= log->l_grant_reserve_bytes);
- }
-} /* xlog_verify_grant_head */
-
-/* check if it will fit */
-STATIC void
-xlog_verify_tail_lsn(xlog_t *log,
- xlog_in_core_t *iclog,
- xfs_lsn_t tail_lsn)
-{
- int blocks;
-
- if (CYCLE_LSN(tail_lsn) == log->l_prev_cycle) {
- blocks =
- log->l_logBBsize - (log->l_prev_block - BLOCK_LSN(tail_lsn));
- if (blocks < BTOBB(iclog->ic_offset)+BTOBB(log->l_iclog_hsize))
- xlog_panic("xlog_verify_tail_lsn: ran out of log space");
- } else {
- ASSERT(CYCLE_LSN(tail_lsn)+1 == log->l_prev_cycle);
-
- if (BLOCK_LSN(tail_lsn) == log->l_prev_block)
- xlog_panic("xlog_verify_tail_lsn: tail wrapped");
-
- blocks = BLOCK_LSN(tail_lsn) - log->l_prev_block;
- if (blocks < BTOBB(iclog->ic_offset) + 1)
- xlog_panic("xlog_verify_tail_lsn: ran out of log space");
- }
-} /* xlog_verify_tail_lsn */
-
-/*
- * Perform a number of checks on the iclog before writing to disk.
- *
- * 1. Make sure the iclogs are still circular
- * 2. Make sure we have a good magic number
- * 3. Make sure we don't have magic numbers in the data
- * 4. Check fields of each log operation header for:
- * A. Valid client identifier
- * B. tid ptr value falls in valid ptr space (user space code)
- * C. Length in log record header is correct according to the
- * individual operation headers within record.
- * 5. When a bwrite will occur within 5 blocks of the front of the physical
- * log, check the preceding blocks of the physical log to make sure all
- * the cycle numbers agree with the current cycle number.
- */
-STATIC void
-xlog_verify_iclog(xlog_t *log,
- xlog_in_core_t *iclog,
- int count,
- boolean_t syncing)
-{
- xlog_op_header_t *ophead;
- xlog_in_core_t *icptr;
- xlog_in_core_2_t *xhdr;
- xfs_caddr_t ptr;
- xfs_caddr_t base_ptr;
- __psint_t field_offset;
- __uint8_t clientid;
- int len, i, j, k, op_len;
- int idx;
- SPLDECL(s);
-
- /* check validity of iclog pointers */
- s = LOG_LOCK(log);
- icptr = log->l_iclog;
- for (i=0; i < log->l_iclog_bufs; i++) {
- if (icptr == 0)
- xlog_panic("xlog_verify_iclog: invalid ptr");
- icptr = icptr->ic_next;
- }
- if (icptr != log->l_iclog)
- xlog_panic("xlog_verify_iclog: corrupt iclog ring");
- LOG_UNLOCK(log, s);
-
- /* check log magic numbers */
- ptr = (xfs_caddr_t) &(iclog->ic_header);
- if (INT_GET(*(uint *)ptr, ARCH_CONVERT) != XLOG_HEADER_MAGIC_NUM)
- xlog_panic("xlog_verify_iclog: invalid magic num");
-
- for (ptr += BBSIZE; ptr < ((xfs_caddr_t)&(iclog->ic_header))+count;
- ptr += BBSIZE) {
- if (INT_GET(*(uint *)ptr, ARCH_CONVERT) == XLOG_HEADER_MAGIC_NUM)
- xlog_panic("xlog_verify_iclog: unexpected magic num");
- }
-
- /* check fields */
- len = INT_GET(iclog->ic_header.h_num_logops, ARCH_CONVERT);
- ptr = iclog->ic_datap;
- base_ptr = ptr;
- ophead = (xlog_op_header_t *)ptr;
- xhdr = (xlog_in_core_2_t *)&iclog->ic_header;
- for (i = 0; i < len; i++) {
- ophead = (xlog_op_header_t *)ptr;
-
- /* clientid is only 1 byte */
- field_offset = (__psint_t)
- ((xfs_caddr_t)&(ophead->oh_clientid) - base_ptr);
- if (syncing == B_FALSE || (field_offset & 0x1ff)) {
- clientid = ophead->oh_clientid;
- } else {
- idx = BTOBBT((xfs_caddr_t)&(ophead->oh_clientid) - iclog->ic_datap);
- if (idx >= (XLOG_HEADER_CYCLE_SIZE / BBSIZE)) {
- j = idx / (XLOG_HEADER_CYCLE_SIZE / BBSIZE);
- k = idx % (XLOG_HEADER_CYCLE_SIZE / BBSIZE);
- clientid = GET_CLIENT_ID(xhdr[j].hic_xheader.xh_cycle_data[k], ARCH_CONVERT);
- } else {
- clientid = GET_CLIENT_ID(iclog->ic_header.h_cycle_data[idx], ARCH_CONVERT);
- }
- }
- if (clientid != XFS_TRANSACTION && clientid != XFS_LOG)
- cmn_err(CE_WARN, "xlog_verify_iclog: "
- "invalid clientid %d op 0x%p offset 0x%lx",
- clientid, ophead, (unsigned long)field_offset);
-
- /* check length */
- field_offset = (__psint_t)
- ((xfs_caddr_t)&(ophead->oh_len) - base_ptr);
- if (syncing == B_FALSE || (field_offset & 0x1ff)) {
- op_len = INT_GET(ophead->oh_len, ARCH_CONVERT);
- } else {
- idx = BTOBBT((__psint_t)&ophead->oh_len -
- (__psint_t)iclog->ic_datap);
- if (idx >= (XLOG_HEADER_CYCLE_SIZE / BBSIZE)) {
- j = idx / (XLOG_HEADER_CYCLE_SIZE / BBSIZE);
- k = idx % (XLOG_HEADER_CYCLE_SIZE / BBSIZE);
- op_len = INT_GET(xhdr[j].hic_xheader.xh_cycle_data[k], ARCH_CONVERT);
- } else {
- op_len = INT_GET(iclog->ic_header.h_cycle_data[idx], ARCH_CONVERT);
- }
- }
- ptr += sizeof(xlog_op_header_t) + op_len;
- }
-} /* xlog_verify_iclog */
-#endif
-
-/*
- * Mark all iclogs IOERROR. LOG_LOCK is held by the caller.
- */
-STATIC int
-xlog_state_ioerror(
- xlog_t *log)
-{
- xlog_in_core_t *iclog, *ic;
-
- iclog = log->l_iclog;
- if (! (iclog->ic_state & XLOG_STATE_IOERROR)) {
- /*
- * Mark all the incore logs IOERROR.
- * From now on, no log flushes will result.
- */
- ic = iclog;
- do {
- ic->ic_state = XLOG_STATE_IOERROR;
- ic = ic->ic_next;
- } while (ic != iclog);
- return 0;
- }
- /*
- * Return non-zero, if state transition has already happened.
- */
- return 1;
-}
-
-/*
- * This is called from xfs_force_shutdown, when we're forcibly
- * shutting down the filesystem, typically because of an IO error.
- * Our main objectives here are to make sure that:
- * a. the filesystem gets marked 'SHUTDOWN' for all interested
- * parties to find out, 'atomically'.
- * b. those who're sleeping on log reservations, pinned objects and
- * other resources get woken up, and be told the bad news.
- * c. nothing new gets queued up after (a) and (b) are done.
- * d. if !logerror, flush the iclogs to disk, then seal them off
- * for business.
- */
-int
-xfs_log_force_umount(
- struct xfs_mount *mp,
- int logerror)
-{
- xlog_ticket_t *tic;
- xlog_t *log;
- int retval;
- int dummy;
- SPLDECL(s);
- SPLDECL(s2);
-
- log = mp->m_log;
-
- /*
- * If this happens during log recovery, don't worry about
- * locking; the log isn't open for business yet.
- */
- if (!log ||
- log->l_flags & XLOG_ACTIVE_RECOVERY) {
- mp->m_flags |= XFS_MOUNT_FS_SHUTDOWN;
- XFS_BUF_DONE(mp->m_sb_bp);
- return 0;
- }
-
- /*
- * Somebody could've already done the hard work for us.
- * No need to get locks for this.
- */
- if (logerror && log->l_iclog->ic_state & XLOG_STATE_IOERROR) {
- ASSERT(XLOG_FORCED_SHUTDOWN(log));
- return 1;
- }
- retval = 0;
- /*
- * We must hold both the GRANT lock and the LOG lock,
- * before we mark the filesystem SHUTDOWN and wake
- * everybody up to tell the bad news.
- */
- s = GRANT_LOCK(log);
- s2 = LOG_LOCK(log);
- mp->m_flags |= XFS_MOUNT_FS_SHUTDOWN;
- XFS_BUF_DONE(mp->m_sb_bp);
- /*
- * This flag is sort of redundant because of the mount flag, but
- * it's good to maintain the separation between the log and the rest
- * of XFS.
- */
- log->l_flags |= XLOG_IO_ERROR;
-
- /*
- * If we hit a log error, we want to mark all the iclogs IOERROR
- * while we're still holding the loglock.
- */
- if (logerror)
- retval = xlog_state_ioerror(log);
- LOG_UNLOCK(log, s2);
-
- /*
- * We don't want anybody waiting for log reservations
- * after this. That means we have to wake up everybody
- * queued up on reserve_headq as well as write_headq.
- * In addition, we make sure in xlog_{re}grant_log_space
- * that we don't enqueue anything once the SHUTDOWN flag
- * is set, and this action is protected by the GRANTLOCK.
- */
- if ((tic = log->l_reserve_headq)) {
- do {
- sv_signal(&tic->t_sema);
- tic = tic->t_next;
- } while (tic != log->l_reserve_headq);
- }
-
- if ((tic = log->l_write_headq)) {
- do {
- sv_signal(&tic->t_sema);
- tic = tic->t_next;
- } while (tic != log->l_write_headq);
- }
- GRANT_UNLOCK(log, s);
-
- if (! (log->l_iclog->ic_state & XLOG_STATE_IOERROR)) {
- ASSERT(!logerror);
- /*
- * Force the incore logs to disk before shutting the
- * log down completely.
- */
- xlog_state_sync_all(log, XFS_LOG_FORCE|XFS_LOG_SYNC, &dummy);
- s2 = LOG_LOCK(log);
- retval = xlog_state_ioerror(log);
- LOG_UNLOCK(log, s2);
- }
- /*
- * Wake up everybody waiting on xfs_log_force.
- * Callback all log item committed functions as if the
- * log writes were completed.
- */
- xlog_state_do_callback(log, XFS_LI_ABORTED, NULL);
-
-#ifdef XFSERRORDEBUG
- {
- xlog_in_core_t *iclog;
-
- s = LOG_LOCK(log);
- iclog = log->l_iclog;
- do {
- ASSERT(iclog->ic_callback == 0);
- iclog = iclog->ic_next;
- } while (iclog != log->l_iclog);
- LOG_UNLOCK(log, s);
- }
-#endif
- /* return non-zero if log IOERROR transition had already happened */
- return retval;
-}
-
-STATIC int
-xlog_iclogs_empty(xlog_t *log)
-{
- xlog_in_core_t *iclog;
-
- iclog = log->l_iclog;
- do {
- /* endianness does not matter here, zero is zero in
- * any language.
- */
- if (iclog->ic_header.h_num_logops)
- return 0;
- iclog = iclog->ic_next;
- } while (iclog != log->l_iclog);
- return 1;
-}
-
diff --git a/sys/gnu/fs/xfs/xfs_log.h b/sys/gnu/fs/xfs/xfs_log.h
deleted file mode 100644
index eacb3d4..0000000
--- a/sys/gnu/fs/xfs/xfs_log.h
+++ /dev/null
@@ -1,192 +0,0 @@
-/*
- * Copyright (c) 2000-2003,2005 Silicon Graphics, Inc.
- * All Rights Reserved.
- *
- * 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.
- *
- * This program is distributed in the hope that it would 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 the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- */
-#ifndef __XFS_LOG_H__
-#define __XFS_LOG_H__
-
-/* get lsn fields */
-
-#define CYCLE_LSN(lsn) ((uint)((lsn)>>32))
-#define BLOCK_LSN(lsn) ((uint)(lsn))
-/* this is used in a spot where we might otherwise double-endian-flip */
-#define CYCLE_LSN_DISK(lsn) (((uint *)&(lsn))[0])
-
-#ifdef __KERNEL__
-/*
- * By comparing each component, we don't have to worry about extra
- * endian issues in treating two 32 bit numbers as one 64 bit number
- */
-static inline xfs_lsn_t _lsn_cmp(xfs_lsn_t lsn1, xfs_lsn_t lsn2)
-{
- if (CYCLE_LSN(lsn1) != CYCLE_LSN(lsn2))
- return (CYCLE_LSN(lsn1)<CYCLE_LSN(lsn2))? -999 : 999;
-
- if (BLOCK_LSN(lsn1) != BLOCK_LSN(lsn2))
- return (BLOCK_LSN(lsn1)<BLOCK_LSN(lsn2))? -999 : 999;
-
- return 0;
-}
-
-#define XFS_LSN_CMP(x,y) _lsn_cmp(x,y)
-
-/*
- * Macros, structures, prototypes for interface to the log manager.
- */
-
-/*
- * Flags to xfs_log_mount
- */
-#define XFS_LOG_RECOVER 0x1
-
-/*
- * Flags to xfs_log_done()
- */
-#define XFS_LOG_REL_PERM_RESERV 0x1
-
-
-/*
- * Flags to xfs_log_reserve()
- *
- * XFS_LOG_SLEEP: If space is not available, sleep (default)
- * XFS_LOG_NOSLEEP: If space is not available, return error
- * XFS_LOG_PERM_RESERV: Permanent reservation. When writes are
- * performed against this type of reservation, the reservation
- * is not decreased. Long running transactions should use this.
- */
-#define XFS_LOG_SLEEP 0x0
-#define XFS_LOG_NOSLEEP 0x1
-#define XFS_LOG_PERM_RESERV 0x2
-#define XFS_LOG_RESV_ALL (XFS_LOG_NOSLEEP|XFS_LOG_PERM_RESERV)
-
-
-/*
- * Flags to xfs_log_force()
- *
- * XFS_LOG_SYNC: Synchronous force in-core log to disk
- * XFS_LOG_FORCE: Start in-core log write now.
- * XFS_LOG_URGE: Start write within some window of time.
- *
- * Note: Either XFS_LOG_FORCE or XFS_LOG_URGE must be set.
- */
-#define XFS_LOG_SYNC 0x1
-#define XFS_LOG_FORCE 0x2
-#define XFS_LOG_URGE 0x4
-
-#endif /* __KERNEL__ */
-
-
-/* Log Clients */
-#define XFS_TRANSACTION 0x69
-#define XFS_VOLUME 0x2
-#define XFS_LOG 0xaa
-
-
-/* Region types for iovec's i_type */
-#define XLOG_REG_TYPE_BFORMAT 1
-#define XLOG_REG_TYPE_BCHUNK 2
-#define XLOG_REG_TYPE_EFI_FORMAT 3
-#define XLOG_REG_TYPE_EFD_FORMAT 4
-#define XLOG_REG_TYPE_IFORMAT 5
-#define XLOG_REG_TYPE_ICORE 6
-#define XLOG_REG_TYPE_IEXT 7
-#define XLOG_REG_TYPE_IBROOT 8
-#define XLOG_REG_TYPE_ILOCAL 9
-#define XLOG_REG_TYPE_IATTR_EXT 10
-#define XLOG_REG_TYPE_IATTR_BROOT 11
-#define XLOG_REG_TYPE_IATTR_LOCAL 12
-#define XLOG_REG_TYPE_QFORMAT 13
-#define XLOG_REG_TYPE_DQUOT 14
-#define XLOG_REG_TYPE_QUOTAOFF 15
-#define XLOG_REG_TYPE_LRHEADER 16
-#define XLOG_REG_TYPE_UNMOUNT 17
-#define XLOG_REG_TYPE_COMMIT 18
-#define XLOG_REG_TYPE_TRANSHDR 19
-#define XLOG_REG_TYPE_MAX 19
-
-#define XLOG_VEC_SET_TYPE(vecp, t) ((vecp)->i_type = (t))
-
-typedef struct xfs_log_iovec {
- xfs_caddr_t i_addr; /* beginning address of region */
- int i_len; /* length in bytes of region */
- uint i_type; /* type of region */
-} xfs_log_iovec_t;
-
-typedef void* xfs_log_ticket_t;
-
-/*
- * Structure used to pass callback function and the function's argument
- * to the log manager.
- */
-typedef struct xfs_log_callback {
- struct xfs_log_callback *cb_next;
- void (*cb_func)(void *, int);
- void *cb_arg;
-} xfs_log_callback_t;
-
-
-#ifdef __KERNEL__
-/* Log manager interfaces */
-struct xfs_mount;
-xfs_lsn_t xfs_log_done(struct xfs_mount *mp,
- xfs_log_ticket_t ticket,
- void **iclog,
- uint flags);
-int _xfs_log_force(struct xfs_mount *mp,
- xfs_lsn_t lsn,
- uint flags,
- int *log_forced);
-#define xfs_log_force(mp, lsn, flags) \
- _xfs_log_force(mp, lsn, flags, NULL);
-int xfs_log_mount(struct xfs_mount *mp,
- struct xfs_buftarg *log_target,
- xfs_daddr_t start_block,
- int num_bblocks);
-int xfs_log_mount_finish(struct xfs_mount *mp, int);
-void xfs_log_move_tail(struct xfs_mount *mp,
- xfs_lsn_t tail_lsn);
-int xfs_log_notify(struct xfs_mount *mp,
- void *iclog,
- xfs_log_callback_t *callback_entry);
-int xfs_log_release_iclog(struct xfs_mount *mp,
- void *iclog_hndl);
-int xfs_log_reserve(struct xfs_mount *mp,
- int length,
- int count,
- xfs_log_ticket_t *ticket,
- __uint8_t clientid,
- uint flags,
- uint t_type);
-int xfs_log_write(struct xfs_mount *mp,
- xfs_log_iovec_t region[],
- int nentries,
- xfs_log_ticket_t ticket,
- xfs_lsn_t *start_lsn);
-int xfs_log_unmount(struct xfs_mount *mp);
-int xfs_log_unmount_write(struct xfs_mount *mp);
-void xfs_log_unmount_dealloc(struct xfs_mount *mp);
-int xfs_log_force_umount(struct xfs_mount *mp, int logerror);
-int xfs_log_need_covered(struct xfs_mount *mp);
-
-void xlog_iodone(struct xfs_buf *);
-
-#endif
-
-
-extern int xlog_debug; /* set to 1 to enable real log */
-
-
-#endif /* __XFS_LOG_H__ */
diff --git a/sys/gnu/fs/xfs/xfs_log_priv.h b/sys/gnu/fs/xfs/xfs_log_priv.h
deleted file mode 100644
index 34bcbf5..0000000
--- a/sys/gnu/fs/xfs/xfs_log_priv.h
+++ /dev/null
@@ -1,511 +0,0 @@
-/*
- * Copyright (c) 2000-2003,2005 Silicon Graphics, Inc.
- * All Rights Reserved.
- *
- * 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.
- *
- * This program is distributed in the hope that it would 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 the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- */
-#ifndef __XFS_LOG_PRIV_H__
-#define __XFS_LOG_PRIV_H__
-
-struct xfs_buf;
-struct ktrace;
-struct log;
-struct xlog_ticket;
-struct xfs_buf_cancel;
-struct xfs_mount;
-
-/*
- * Macros, structures, prototypes for internal log manager use.
- */
-
-#define XLOG_MIN_ICLOGS 2
-#define XLOG_MED_ICLOGS 4
-#define XLOG_MAX_ICLOGS 8
-#define XLOG_CALLBACK_SIZE 10
-#define XLOG_HEADER_MAGIC_NUM 0xFEEDbabe /* Invalid cycle number */
-#define XLOG_VERSION_1 1
-#define XLOG_VERSION_2 2 /* Large IClogs, Log sunit */
-#define XLOG_VERSION_OKBITS (XLOG_VERSION_1 | XLOG_VERSION_2)
-#define XLOG_RECORD_BSIZE (16*1024) /* eventually 32k */
-#define XLOG_BIG_RECORD_BSIZE (32*1024) /* 32k buffers */
-#define XLOG_MAX_RECORD_BSIZE (256*1024)
-#define XLOG_HEADER_CYCLE_SIZE (32*1024) /* cycle data in header */
-#define XLOG_RECORD_BSHIFT 14 /* 16384 == 1 << 14 */
-#define XLOG_BIG_RECORD_BSHIFT 15 /* 32k == 1 << 15 */
-#define XLOG_MAX_RECORD_BSHIFT 18 /* 256k == 1 << 18 */
-#define XLOG_BTOLSUNIT(log, b) (((b)+(log)->l_mp->m_sb.sb_logsunit-1) / \
- (log)->l_mp->m_sb.sb_logsunit)
-#define XLOG_LSUNITTOB(log, su) ((su) * (log)->l_mp->m_sb.sb_logsunit)
-
-#define XLOG_HEADER_SIZE 512
-
-#define XLOG_REC_SHIFT(log) \
- BTOBB(1 << (XFS_SB_VERSION_HASLOGV2(&log->l_mp->m_sb) ? \
- XLOG_MAX_RECORD_BSHIFT : XLOG_BIG_RECORD_BSHIFT))
-#define XLOG_TOTAL_REC_SHIFT(log) \
- BTOBB(XLOG_MAX_ICLOGS << (XFS_SB_VERSION_HASLOGV2(&log->l_mp->m_sb) ? \
- XLOG_MAX_RECORD_BSHIFT : XLOG_BIG_RECORD_BSHIFT))
-
-/*
- * set lsns
- */
-
-#define ASSIGN_ANY_LSN_HOST(lsn,cycle,block) \
- { \
- (lsn) = ((xfs_lsn_t)(cycle)<<32)|(block); \
- }
-#define ASSIGN_ANY_LSN_DISK(lsn,cycle,block) \
- { \
- INT_SET(((uint *)&(lsn))[0], ARCH_CONVERT, (cycle)); \
- INT_SET(((uint *)&(lsn))[1], ARCH_CONVERT, (block)); \
- }
-#define ASSIGN_LSN(lsn,log) \
- ASSIGN_ANY_LSN_DISK(lsn,(log)->l_curr_cycle,(log)->l_curr_block);
-
-#define XLOG_SET(f,b) (((f) & (b)) == (b))
-
-#define GET_CYCLE(ptr, arch) \
- (INT_GET(*(uint *)(ptr), arch) == XLOG_HEADER_MAGIC_NUM ? \
- INT_GET(*((uint *)(ptr)+1), arch) : \
- INT_GET(*(uint *)(ptr), arch) \
- )
-
-#define BLK_AVG(blk1, blk2) ((blk1+blk2) >> 1)
-
-
-#ifdef __KERNEL__
-
-/*
- * get client id from packed copy.
- *
- * this hack is here because the xlog_pack code copies four bytes
- * of xlog_op_header containing the fields oh_clientid, oh_flags
- * and oh_res2 into the packed copy.
- *
- * later on this four byte chunk is treated as an int and the
- * client id is pulled out.
- *
- * this has endian issues, of course.
- */
-
-#ifndef XFS_NATIVE_HOST
-#define GET_CLIENT_ID(i,arch) \
- ((i) & 0xff)
-#else
-#define GET_CLIENT_ID(i,arch) \
- ((i) >> 24)
-#endif
-
-#define GRANT_LOCK(log) mutex_spinlock(&(log)->l_grant_lock)
-#define GRANT_UNLOCK(log, s) mutex_spinunlock(&(log)->l_grant_lock, s)
-#define LOG_LOCK(log) mutex_spinlock(&(log)->l_icloglock)
-#define LOG_UNLOCK(log, s) mutex_spinunlock(&(log)->l_icloglock, s)
-
-#define xlog_panic(args...) cmn_err(CE_PANIC, ## args)
-#define xlog_exit(args...) cmn_err(CE_PANIC, ## args)
-#define xlog_warn(args...) cmn_err(CE_WARN, ## args)
-
-/*
- * In core log state
- */
-#define XLOG_STATE_ACTIVE 0x0001 /* Current IC log being written to */
-#define XLOG_STATE_WANT_SYNC 0x0002 /* Want to sync this iclog; no more writes */
-#define XLOG_STATE_SYNCING 0x0004 /* This IC log is syncing */
-#define XLOG_STATE_DONE_SYNC 0x0008 /* Done syncing to disk */
-#define XLOG_STATE_DO_CALLBACK \
- 0x0010 /* Process callback functions */
-#define XLOG_STATE_CALLBACK 0x0020 /* Callback functions now */
-#define XLOG_STATE_DIRTY 0x0040 /* Dirty IC log, not ready for ACTIVE status*/
-#define XLOG_STATE_IOERROR 0x0080 /* IO error happened in sync'ing log */
-#define XLOG_STATE_ALL 0x7FFF /* All possible valid flags */
-#define XLOG_STATE_NOTUSED 0x8000 /* This IC log not being used */
-#endif /* __KERNEL__ */
-
-/*
- * Flags to log operation header
- *
- * The first write of a new transaction will be preceded with a start
- * record, XLOG_START_TRANS. Once a transaction is committed, a commit
- * record is written, XLOG_COMMIT_TRANS. If a single region can not fit into
- * the remainder of the current active in-core log, it is split up into
- * multiple regions. Each partial region will be marked with a
- * XLOG_CONTINUE_TRANS until the last one, which gets marked with XLOG_END_TRANS.
- *
- */
-#define XLOG_START_TRANS 0x01 /* Start a new transaction */
-#define XLOG_COMMIT_TRANS 0x02 /* Commit this transaction */
-#define XLOG_CONTINUE_TRANS 0x04 /* Cont this trans into new region */
-#define XLOG_WAS_CONT_TRANS 0x08 /* Cont this trans into new region */
-#define XLOG_END_TRANS 0x10 /* End a continued transaction */
-#define XLOG_UNMOUNT_TRANS 0x20 /* Unmount a filesystem transaction */
-#define XLOG_SKIP_TRANS (XLOG_COMMIT_TRANS | XLOG_CONTINUE_TRANS | \
- XLOG_WAS_CONT_TRANS | XLOG_END_TRANS | \
- XLOG_UNMOUNT_TRANS)
-
-#ifdef __KERNEL__
-/*
- * Flags to log ticket
- */
-#define XLOG_TIC_INITED 0x1 /* has been initialized */
-#define XLOG_TIC_PERM_RESERV 0x2 /* permanent reservation */
-#define XLOG_TIC_IN_Q 0x4
-#endif /* __KERNEL__ */
-
-#define XLOG_UNMOUNT_TYPE 0x556e /* Un for Unmount */
-
-/*
- * Flags for log structure
- */
-#define XLOG_CHKSUM_MISMATCH 0x1 /* used only during recovery */
-#define XLOG_ACTIVE_RECOVERY 0x2 /* in the middle of recovery */
-#define XLOG_RECOVERY_NEEDED 0x4 /* log was recovered */
-#define XLOG_IO_ERROR 0x8 /* log hit an I/O error, and being
- shutdown */
-typedef __uint32_t xlog_tid_t;
-
-
-#ifdef __KERNEL__
-/*
- * Below are states for covering allocation transactions.
- * By covering, we mean changing the h_tail_lsn in the last on-disk
- * log write such that no allocation transactions will be re-done during
- * recovery after a system crash. Recovery starts at the last on-disk
- * log write.
- *
- * These states are used to insert dummy log entries to cover
- * space allocation transactions which can undo non-transactional changes
- * after a crash. Writes to a file with space
- * already allocated do not result in any transactions. Allocations
- * might include space beyond the EOF. So if we just push the EOF a
- * little, the last transaction for the file could contain the wrong
- * size. If there is no file system activity, after an allocation
- * transaction, and the system crashes, the allocation transaction
- * will get replayed and the file will be truncated. This could
- * be hours/days/... after the allocation occurred.
- *
- * The fix for this is to do two dummy transactions when the
- * system is idle. We need two dummy transaction because the h_tail_lsn
- * in the log record header needs to point beyond the last possible
- * non-dummy transaction. The first dummy changes the h_tail_lsn to
- * the first transaction before the dummy. The second dummy causes
- * h_tail_lsn to point to the first dummy. Recovery starts at h_tail_lsn.
- *
- * These dummy transactions get committed when everything
- * is idle (after there has been some activity).
- *
- * There are 5 states used to control this.
- *
- * IDLE -- no logging has been done on the file system or
- * we are done covering previous transactions.
- * NEED -- logging has occurred and we need a dummy transaction
- * when the log becomes idle.
- * DONE -- we were in the NEED state and have committed a dummy
- * transaction.
- * NEED2 -- we detected that a dummy transaction has gone to the
- * on disk log with no other transactions.
- * DONE2 -- we committed a dummy transaction when in the NEED2 state.
- *
- * There are two places where we switch states:
- *
- * 1.) In xfs_sync, when we detect an idle log and are in NEED or NEED2.
- * We commit the dummy transaction and switch to DONE or DONE2,
- * respectively. In all other states, we don't do anything.
- *
- * 2.) When we finish writing the on-disk log (xlog_state_clean_log).
- *
- * No matter what state we are in, if this isn't the dummy
- * transaction going out, the next state is NEED.
- * So, if we aren't in the DONE or DONE2 states, the next state
- * is NEED. We can't be finishing a write of the dummy record
- * unless it was committed and the state switched to DONE or DONE2.
- *
- * If we are in the DONE state and this was a write of the
- * dummy transaction, we move to NEED2.
- *
- * If we are in the DONE2 state and this was a write of the
- * dummy transaction, we move to IDLE.
- *
- *
- * Writing only one dummy transaction can get appended to
- * one file space allocation. When this happens, the log recovery
- * code replays the space allocation and a file could be truncated.
- * This is why we have the NEED2 and DONE2 states before going idle.
- */
-
-#define XLOG_STATE_COVER_IDLE 0
-#define XLOG_STATE_COVER_NEED 1
-#define XLOG_STATE_COVER_DONE 2
-#define XLOG_STATE_COVER_NEED2 3
-#define XLOG_STATE_COVER_DONE2 4
-
-#define XLOG_COVER_OPS 5
-
-
-/* Ticket reservation region accounting */
-#define XLOG_TIC_LEN_MAX 15
-#define XLOG_TIC_RESET_RES(t) ((t)->t_res_num = \
- (t)->t_res_arr_sum = (t)->t_res_num_ophdrs = 0)
-#define XLOG_TIC_ADD_OPHDR(t) ((t)->t_res_num_ophdrs++)
-#define XLOG_TIC_ADD_REGION(t, len, type) \
- do { \
- if ((t)->t_res_num == XLOG_TIC_LEN_MAX) { \
- /* add to overflow and start again */ \
- (t)->t_res_o_flow += (t)->t_res_arr_sum; \
- (t)->t_res_num = 0; \
- (t)->t_res_arr_sum = 0; \
- } \
- (t)->t_res_arr[(t)->t_res_num].r_len = (len); \
- (t)->t_res_arr[(t)->t_res_num].r_type = (type); \
- (t)->t_res_arr_sum += (len); \
- (t)->t_res_num++; \
- } while (0)
-
-/*
- * Reservation region
- * As would be stored in xfs_log_iovec but without the i_addr which
- * we don't care about.
- */
-typedef struct xlog_res {
- uint r_len; /* region length :4 */
- uint r_type; /* region's transaction type :4 */
-} xlog_res_t;
-
-typedef struct xlog_ticket {
- sv_t t_sema; /* sleep on this semaphore : 20 */
- struct xlog_ticket *t_next; /* :4|8 */
- struct xlog_ticket *t_prev; /* :4|8 */
- xlog_tid_t t_tid; /* transaction identifier : 4 */
- int t_curr_res; /* current reservation in bytes : 4 */
- int t_unit_res; /* unit reservation in bytes : 4 */
- char t_ocnt; /* original count : 1 */
- char t_cnt; /* current count : 1 */
- char t_clientid; /* who does this belong to; : 1 */
- char t_flags; /* properties of reservation : 1 */
- uint t_trans_type; /* transaction type : 4 */
-
- /* reservation array fields */
- uint t_res_num; /* num in array : 4 */
- uint t_res_num_ophdrs; /* num op hdrs : 4 */
- uint t_res_arr_sum; /* array sum : 4 */
- uint t_res_o_flow; /* sum overflow : 4 */
- xlog_res_t t_res_arr[XLOG_TIC_LEN_MAX]; /* array of res : 8 * 15 */
-} xlog_ticket_t;
-
-#endif
-
-
-typedef struct xlog_op_header {
- xlog_tid_t oh_tid; /* transaction id of operation : 4 b */
- int oh_len; /* bytes in data region : 4 b */
- __uint8_t oh_clientid; /* who sent me this : 1 b */
- __uint8_t oh_flags; /* : 1 b */
- ushort oh_res2; /* 32 bit align : 2 b */
-} xlog_op_header_t;
-
-
-/* valid values for h_fmt */
-#define XLOG_FMT_UNKNOWN 0
-#define XLOG_FMT_LINUX_LE 1
-#define XLOG_FMT_LINUX_BE 2
-#define XLOG_FMT_IRIX_BE 3
-
-/* our fmt */
-#ifdef XFS_NATIVE_HOST
-#define XLOG_FMT XLOG_FMT_LINUX_BE
-#else
-#define XLOG_FMT XLOG_FMT_LINUX_LE
-#endif
-
-typedef struct xlog_rec_header {
- uint h_magicno; /* log record (LR) identifier : 4 */
- uint h_cycle; /* write cycle of log : 4 */
- int h_version; /* LR version : 4 */
- int h_len; /* len in bytes; should be 64-bit aligned: 4 */
- xfs_lsn_t h_lsn; /* lsn of this LR : 8 */
- xfs_lsn_t h_tail_lsn; /* lsn of 1st LR w/ buffers not committed: 8 */
- uint h_chksum; /* may not be used; non-zero if used : 4 */
- int h_prev_block; /* block number to previous LR : 4 */
- int h_num_logops; /* number of log operations in this LR : 4 */
- uint h_cycle_data[XLOG_HEADER_CYCLE_SIZE / BBSIZE];
- /* new fields */
- int h_fmt; /* format of log record : 4 */
- uuid_t h_fs_uuid; /* uuid of FS : 16 */
- int h_size; /* iclog size : 4 */
-} xlog_rec_header_t;
-
-typedef struct xlog_rec_ext_header {
- uint xh_cycle; /* write cycle of log : 4 */
- uint xh_cycle_data[XLOG_HEADER_CYCLE_SIZE / BBSIZE]; /* : 256 */
-} xlog_rec_ext_header_t;
-
-#ifdef __KERNEL__
-/*
- * - A log record header is 512 bytes. There is plenty of room to grow the
- * xlog_rec_header_t into the reserved space.
- * - ic_data follows, so a write to disk can start at the beginning of
- * the iclog.
- * - ic_forcesema is used to implement synchronous forcing of the iclog to disk.
- * - ic_next is the pointer to the next iclog in the ring.
- * - ic_bp is a pointer to the buffer used to write this incore log to disk.
- * - ic_log is a pointer back to the global log structure.
- * - ic_callback is a linked list of callback function/argument pairs to be
- * called after an iclog finishes writing.
- * - ic_size is the full size of the header plus data.
- * - ic_offset is the current number of bytes written to in this iclog.
- * - ic_refcnt is bumped when someone is writing to the log.
- * - ic_state is the state of the iclog.
- */
-typedef struct xlog_iclog_fields {
- sv_t ic_forcesema;
- sv_t ic_writesema;
- struct xlog_in_core *ic_next;
- struct xlog_in_core *ic_prev;
- struct xfs_buf *ic_bp;
- struct log *ic_log;
- xfs_log_callback_t *ic_callback;
- xfs_log_callback_t **ic_callback_tail;
-#ifdef XFS_LOG_TRACE
- struct ktrace *ic_trace;
-#endif
- int ic_size;
- int ic_offset;
- int ic_refcnt;
- int ic_bwritecnt;
- ushort_t ic_state;
- char *ic_datap; /* pointer to iclog data */
-} xlog_iclog_fields_t;
-
-typedef union xlog_in_core2 {
- xlog_rec_header_t hic_header;
- xlog_rec_ext_header_t hic_xheader;
- char hic_sector[XLOG_HEADER_SIZE];
-} xlog_in_core_2_t;
-
-typedef struct xlog_in_core {
- xlog_iclog_fields_t hic_fields;
- xlog_in_core_2_t *hic_data;
-} xlog_in_core_t;
-
-/*
- * Defines to save our code from this glop.
- */
-#define ic_forcesema hic_fields.ic_forcesema
-#define ic_writesema hic_fields.ic_writesema
-#define ic_next hic_fields.ic_next
-#define ic_prev hic_fields.ic_prev
-#define ic_bp hic_fields.ic_bp
-#define ic_log hic_fields.ic_log
-#define ic_callback hic_fields.ic_callback
-#define ic_callback_tail hic_fields.ic_callback_tail
-#define ic_trace hic_fields.ic_trace
-#define ic_size hic_fields.ic_size
-#define ic_offset hic_fields.ic_offset
-#define ic_refcnt hic_fields.ic_refcnt
-#define ic_bwritecnt hic_fields.ic_bwritecnt
-#define ic_state hic_fields.ic_state
-#define ic_datap hic_fields.ic_datap
-#define ic_header hic_data->hic_header
-
-/*
- * The reservation head lsn is not made up of a cycle number and block number.
- * Instead, it uses a cycle number and byte number. Logs don't expect to
- * overflow 31 bits worth of byte offset, so using a byte number will mean
- * that round off problems won't occur when releasing partial reservations.
- */
-typedef struct log {
- /* The following block of fields are changed while holding icloglock */
- sema_t l_flushsema; /* iclog flushing semaphore */
- int l_flushcnt; /* # of procs waiting on this
- * sema */
- int l_ticket_cnt; /* free ticket count */
- int l_ticket_tcnt; /* total ticket count */
- int l_covered_state;/* state of "covering disk
- * log entries" */
- xlog_ticket_t *l_freelist; /* free list of tickets */
- xlog_ticket_t *l_unmount_free;/* kmem_free these addresses */
- xlog_ticket_t *l_tail; /* free list of tickets */
- xlog_in_core_t *l_iclog; /* head log queue */
- lock_t l_icloglock; /* grab to change iclog state */
- xfs_lsn_t l_tail_lsn; /* lsn of 1st LR with unflushed
- * buffers */
- xfs_lsn_t l_last_sync_lsn;/* lsn of last LR on disk */
- struct xfs_mount *l_mp; /* mount point */
- struct xfs_buf *l_xbuf; /* extra buffer for log
- * wrapping */
- struct xfs_buftarg *l_targ; /* buftarg of log */
- xfs_daddr_t l_logBBstart; /* start block of log */
- int l_logsize; /* size of log in bytes */
- int l_logBBsize; /* size of log in BB chunks */
- int l_curr_cycle; /* Cycle number of log writes */
- int l_prev_cycle; /* Cycle number before last
- * block increment */
- int l_curr_block; /* current logical log block */
- int l_prev_block; /* previous logical log block */
- int l_iclog_size; /* size of log in bytes */
- int l_iclog_size_log; /* log power size of log */
- int l_iclog_bufs; /* number of iclog buffers */
-
- /* The following field are used for debugging; need to hold icloglock */
- char *l_iclog_bak[XLOG_MAX_ICLOGS];
-
- /* The following block of fields are changed while holding grant_lock */
- lock_t l_grant_lock;
- xlog_ticket_t *l_reserve_headq;
- xlog_ticket_t *l_write_headq;
- int l_grant_reserve_cycle;
- int l_grant_reserve_bytes;
- int l_grant_write_cycle;
- int l_grant_write_bytes;
-
- /* The following fields don't need locking */
-#ifdef XFS_LOG_TRACE
- struct ktrace *l_trace;
- struct ktrace *l_grant_trace;
-#endif
- uint l_flags;
- uint l_quotaoffs_flag; /* XFS_DQ_*, for QUOTAOFFs */
- struct xfs_buf_cancel **l_buf_cancel_table;
- int l_iclog_hsize; /* size of iclog header */
- int l_iclog_heads; /* # of iclog header sectors */
- uint l_sectbb_log; /* log2 of sector size in BBs */
- uint l_sectbb_mask; /* sector size (in BBs)
- * alignment mask */
-} xlog_t;
-
-#define XLOG_FORCED_SHUTDOWN(log) ((log)->l_flags & XLOG_IO_ERROR)
-
-
-/* common routines */
-extern xfs_lsn_t xlog_assign_tail_lsn(struct xfs_mount *mp);
-extern int xlog_find_tail(xlog_t *log,
- xfs_daddr_t *head_blk,
- xfs_daddr_t *tail_blk);
-extern int xlog_recover(xlog_t *log);
-extern int xlog_recover_finish(xlog_t *log, int mfsi_flags);
-extern void xlog_pack_data(xlog_t *log, xlog_in_core_t *iclog, int);
-extern void xlog_recover_process_iunlinks(xlog_t *log);
-
-extern struct xfs_buf *xlog_get_bp(xlog_t *, int);
-extern void xlog_put_bp(struct xfs_buf *);
-extern int xlog_bread(xlog_t *, xfs_daddr_t, int, struct xfs_buf *);
-
-/* iclog tracing */
-#define XLOG_TRACE_GRAB_FLUSH 1
-#define XLOG_TRACE_REL_FLUSH 2
-#define XLOG_TRACE_SLEEP_FLUSH 3
-#define XLOG_TRACE_WAKE_FLUSH 4
-
-#endif /* __KERNEL__ */
-
-#endif /* __XFS_LOG_PRIV_H__ */
diff --git a/sys/gnu/fs/xfs/xfs_log_recover.c b/sys/gnu/fs/xfs/xfs_log_recover.c
deleted file mode 100644
index c0e035b..0000000
--- a/sys/gnu/fs/xfs/xfs_log_recover.c
+++ /dev/null
@@ -1,4078 +0,0 @@
-/*
- * Copyright (c) 2000-2003,2005 Silicon Graphics, Inc.
- * All Rights Reserved.
- *
- * 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.
- *
- * This program is distributed in the hope that it would 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 the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- */
-#include "xfs.h"
-#include "xfs_fs.h"
-#include "xfs_types.h"
-#include "xfs_bit.h"
-#include "xfs_log.h"
-#include "xfs_inum.h"
-#include "xfs_trans.h"
-#include "xfs_sb.h"
-#include "xfs_ag.h"
-#include "xfs_dir.h"
-#include "xfs_dir2.h"
-#include "xfs_dmapi.h"
-#include "xfs_mount.h"
-#include "xfs_error.h"
-#include "xfs_bmap_btree.h"
-#include "xfs_alloc_btree.h"
-#include "xfs_ialloc_btree.h"
-#include "xfs_dir_sf.h"
-#include "xfs_dir2_sf.h"
-#include "xfs_attr_sf.h"
-#include "xfs_dinode.h"
-#include "xfs_inode.h"
-#include "xfs_inode_item.h"
-#include "xfs_imap.h"
-#include "xfs_alloc.h"
-#include "xfs_ialloc.h"
-#include "xfs_log_priv.h"
-#include "xfs_buf_item.h"
-#include "xfs_log_recover.h"
-#include "xfs_extfree_item.h"
-#include "xfs_trans_priv.h"
-#include "xfs_quota.h"
-#include "xfs_rw.h"
-
-STATIC int xlog_find_zeroed(xlog_t *, xfs_daddr_t *);
-STATIC int xlog_clear_stale_blocks(xlog_t *, xfs_lsn_t);
-STATIC void xlog_recover_insert_item_backq(xlog_recover_item_t **q,
- xlog_recover_item_t *item);
-#if defined(DEBUG)
-STATIC void xlog_recover_check_summary(xlog_t *);
-STATIC void xlog_recover_check_ail(xfs_mount_t *, xfs_log_item_t *, int);
-#else
-#define xlog_recover_check_summary(log)
-#define xlog_recover_check_ail(mp, lip, gen)
-#endif
-
-
-/*
- * Sector aligned buffer routines for buffer create/read/write/access
- */
-
-#define XLOG_SECTOR_ROUNDUP_BBCOUNT(log, bbs) \
- ( ((log)->l_sectbb_mask && (bbs & (log)->l_sectbb_mask)) ? \
- ((bbs + (log)->l_sectbb_mask + 1) & ~(log)->l_sectbb_mask) : (bbs) )
-#define XLOG_SECTOR_ROUNDDOWN_BLKNO(log, bno) ((bno) & ~(log)->l_sectbb_mask)
-
-xfs_buf_t *
-xlog_get_bp(
- xlog_t *log,
- int num_bblks)
-{
- ASSERT(num_bblks > 0);
-
- if (log->l_sectbb_log) {
- if (num_bblks > 1)
- num_bblks += XLOG_SECTOR_ROUNDUP_BBCOUNT(log, 1);
- num_bblks = XLOG_SECTOR_ROUNDUP_BBCOUNT(log, num_bblks);
- }
- return xfs_buf_get_noaddr(BBTOB(num_bblks), log->l_mp->m_logdev_targp);
-}
-
-void
-xlog_put_bp(
- xfs_buf_t *bp)
-{
- xfs_buf_free(bp);
-}
-
-
-/*
- * nbblks should be uint, but oh well. Just want to catch that 32-bit length.
- */
-int
-xlog_bread(
- xlog_t *log,
- xfs_daddr_t blk_no,
- int nbblks,
- xfs_buf_t *bp)
-{
- int error;
-
- if (log->l_sectbb_log) {
- blk_no = XLOG_SECTOR_ROUNDDOWN_BLKNO(log, blk_no);
- nbblks = XLOG_SECTOR_ROUNDUP_BBCOUNT(log, nbblks);
- }
-
- ASSERT(nbblks > 0);
- ASSERT(BBTOB(nbblks) <= XFS_BUF_SIZE(bp));
- ASSERT(bp);
-
- XFS_BUF_SET_ADDR(bp, log->l_logBBstart + blk_no);
- XFS_BUF_READ(bp);
- XFS_BUF_BUSY(bp);
- XFS_BUF_SET_COUNT(bp, BBTOB(nbblks));
- XFS_BUF_SET_TARGET(bp, log->l_mp->m_logdev_targp);
-
- xfsbdstrat(log->l_mp, bp);
- if ((error = xfs_iowait(bp)))
- xfs_ioerror_alert("xlog_bread", log->l_mp,
- bp, XFS_BUF_ADDR(bp));
- return error;
-}
-
-/*
- * Write out the buffer at the given block for the given number of blocks.
- * The buffer is kept locked across the write and is returned locked.
- * This can only be used for synchronous log writes.
- */
-STATIC int
-xlog_bwrite(
- xlog_t *log,
- xfs_daddr_t blk_no,
- int nbblks,
- xfs_buf_t *bp)
-{
- int error;
-
- if (log->l_sectbb_log) {
- blk_no = XLOG_SECTOR_ROUNDDOWN_BLKNO(log, blk_no);
- nbblks = XLOG_SECTOR_ROUNDUP_BBCOUNT(log, nbblks);
- }
-
- ASSERT(nbblks > 0);
- ASSERT(BBTOB(nbblks) <= XFS_BUF_SIZE(bp));
-
- XFS_BUF_SET_ADDR(bp, log->l_logBBstart + blk_no);
- XFS_BUF_ZEROFLAGS(bp);
- XFS_BUF_BUSY(bp);
- XFS_BUF_HOLD(bp);
- XFS_BUF_PSEMA(bp, PRIBIO);
- XFS_BUF_SET_COUNT(bp, BBTOB(nbblks));
- XFS_BUF_SET_TARGET(bp, log->l_mp->m_logdev_targp);
-
- if ((error = xfs_bwrite(log->l_mp, bp)))
- xfs_ioerror_alert("xlog_bwrite", log->l_mp,
- bp, XFS_BUF_ADDR(bp));
- return error;
-}
-
-STATIC xfs_caddr_t
-xlog_align(
- xlog_t *log,
- xfs_daddr_t blk_no,
- int nbblks,
- xfs_buf_t *bp)
-{
- xfs_caddr_t ptr;
-
- if (!log->l_sectbb_log)
- return XFS_BUF_PTR(bp);
-
- ptr = XFS_BUF_PTR(bp) + BBTOB((int)blk_no & log->l_sectbb_mask);
- ASSERT(XFS_BUF_SIZE(bp) >=
- BBTOB(nbblks + (blk_no & log->l_sectbb_mask)));
- return ptr;
-}
-
-#ifdef DEBUG
-/*
- * dump debug superblock and log record information
- */
-STATIC void
-xlog_header_check_dump(
- xfs_mount_t *mp,
- xlog_rec_header_t *head)
-{
- int b;
-
- printk("%s: SB : uuid = ", __FUNCTION__);
- for (b = 0; b < 16; b++)
- printk("%02x",((unsigned char *)&mp->m_sb.sb_uuid)[b]);
- printk(", fmt = %d\n", XLOG_FMT);
- printk(" log : uuid = ");
- for (b = 0; b < 16; b++)
- printk("%02x",((unsigned char *)&head->h_fs_uuid)[b]);
- printk(", fmt = %d\n", INT_GET(head->h_fmt, ARCH_CONVERT));
-}
-#else
-#define xlog_header_check_dump(mp, head)
-#endif
-
-/*
- * check log record header for recovery
- */
-STATIC int
-xlog_header_check_recover(
- xfs_mount_t *mp,
- xlog_rec_header_t *head)
-{
- ASSERT(INT_GET(head->h_magicno, ARCH_CONVERT) == XLOG_HEADER_MAGIC_NUM);
-
- /*
- * IRIX doesn't write the h_fmt field and leaves it zeroed
- * (XLOG_FMT_UNKNOWN). This stops us from trying to recover
- * a dirty log created in IRIX.
- */
- if (unlikely(INT_GET(head->h_fmt, ARCH_CONVERT) != XLOG_FMT)) {
- xlog_warn(
- "XFS: dirty log written in incompatible format - can't recover");
- xlog_header_check_dump(mp, head);
- XFS_ERROR_REPORT("xlog_header_check_recover(1)",
- XFS_ERRLEVEL_HIGH, mp);
- return XFS_ERROR(EFSCORRUPTED);
- } else if (unlikely(!uuid_equal(&mp->m_sb.sb_uuid, &head->h_fs_uuid))) {
- xlog_warn(
- "XFS: dirty log entry has mismatched uuid - can't recover");
- xlog_header_check_dump(mp, head);
- XFS_ERROR_REPORT("xlog_header_check_recover(2)",
- XFS_ERRLEVEL_HIGH, mp);
- return XFS_ERROR(EFSCORRUPTED);
- }
- return 0;
-}
-
-/*
- * read the head block of the log and check the header
- */
-STATIC int
-xlog_header_check_mount(
- xfs_mount_t *mp,
- xlog_rec_header_t *head)
-{
- ASSERT(INT_GET(head->h_magicno, ARCH_CONVERT) == XLOG_HEADER_MAGIC_NUM);
-
- if (uuid_is_nil(&head->h_fs_uuid)) {
- /*
- * IRIX doesn't write the h_fs_uuid or h_fmt fields. If
- * h_fs_uuid is nil, we assume this log was last mounted
- * by IRIX and continue.
- */
- xlog_warn("XFS: nil uuid in log - IRIX style log");
- } else if (unlikely(!uuid_equal(&mp->m_sb.sb_uuid, &head->h_fs_uuid))) {
- xlog_warn("XFS: log has mismatched uuid - can't recover");
- xlog_header_check_dump(mp, head);
- XFS_ERROR_REPORT("xlog_header_check_mount",
- XFS_ERRLEVEL_HIGH, mp);
- return XFS_ERROR(EFSCORRUPTED);
- }
- return 0;
-}
-
-STATIC void
-xlog_recover_iodone(
- struct xfs_buf *bp)
-{
- xfs_mount_t *mp;
-
- ASSERT(XFS_BUF_FSPRIVATE(bp, void *));
-
- if (XFS_BUF_GETERROR(bp)) {
- /*
- * We're not going to bother about retrying
- * this during recovery. One strike!
- */
- mp = XFS_BUF_FSPRIVATE(bp, xfs_mount_t *);
- xfs_ioerror_alert("xlog_recover_iodone",
- mp, bp, XFS_BUF_ADDR(bp));
- xfs_force_shutdown(mp, XFS_METADATA_IO_ERROR);
- }
- XFS_BUF_SET_FSPRIVATE(bp, NULL);
- XFS_BUF_CLR_IODONE_FUNC(bp);
- xfs_biodone(bp);
-}
-
-/*
- * This routine finds (to an approximation) the first block in the physical
- * log which contains the given cycle. It uses a binary search algorithm.
- * Note that the algorithm can not be perfect because the disk will not
- * necessarily be perfect.
- */
-STATIC int
-xlog_find_cycle_start(
- xlog_t *log,
- xfs_buf_t *bp,
- xfs_daddr_t first_blk,
- xfs_daddr_t *last_blk,
- uint cycle)
-{
- xfs_caddr_t offset;
- xfs_daddr_t mid_blk;
- uint mid_cycle;
- int error;
-
- mid_blk = BLK_AVG(first_blk, *last_blk);
- while (mid_blk != first_blk && mid_blk != *last_blk) {
- if ((error = xlog_bread(log, mid_blk, 1, bp)))
- return error;
- offset = xlog_align(log, mid_blk, 1, bp);
- mid_cycle = GET_CYCLE(offset, ARCH_CONVERT);
- if (mid_cycle == cycle) {
- *last_blk = mid_blk;
- /* last_half_cycle == mid_cycle */
- } else {
- first_blk = mid_blk;
- /* first_half_cycle == mid_cycle */
- }
- mid_blk = BLK_AVG(first_blk, *last_blk);
- }
- ASSERT((mid_blk == first_blk && mid_blk+1 == *last_blk) ||
- (mid_blk == *last_blk && mid_blk-1 == first_blk));
-
- return 0;
-}
-
-/*
- * Check that the range of blocks does not contain the cycle number
- * given. The scan needs to occur from front to back and the ptr into the
- * region must be updated since a later routine will need to perform another
- * test. If the region is completely good, we end up returning the same
- * last block number.
- *
- * Set blkno to -1 if we encounter no errors. This is an invalid block number
- * since we don't ever expect logs to get this large.
- */
-STATIC int
-xlog_find_verify_cycle(
- xlog_t *log,
- xfs_daddr_t start_blk,
- int nbblks,
- uint stop_on_cycle_no,
- xfs_daddr_t *new_blk)
-{
- xfs_daddr_t i, j;
- uint cycle;
- xfs_buf_t *bp;
- xfs_daddr_t bufblks;
- xfs_caddr_t buf = NULL;
- int error = 0;
-
- bufblks = 1 << ffs(nbblks);
-
- while (!(bp = xlog_get_bp(log, bufblks))) {
- /* can't get enough memory to do everything in one big buffer */
- bufblks >>= 1;
- if (bufblks <= log->l_sectbb_log)
- return ENOMEM;
- }
-
- for (i = start_blk; i < start_blk + nbblks; i += bufblks) {
- int bcount;
-
- bcount = min(bufblks, (start_blk + nbblks - i));
-
- if ((error = xlog_bread(log, i, bcount, bp)))
- goto out;
-
- buf = xlog_align(log, i, bcount, bp);
- for (j = 0; j < bcount; j++) {
- cycle = GET_CYCLE(buf, ARCH_CONVERT);
- if (cycle == stop_on_cycle_no) {
- *new_blk = i+j;
- goto out;
- }
-
- buf += BBSIZE;
- }
- }
-
- *new_blk = -1;
-
-out:
- xlog_put_bp(bp);
- return error;
-}
-
-/*
- * Potentially backup over partial log record write.
- *
- * In the typical case, last_blk is the number of the block directly after
- * a good log record. Therefore, we subtract one to get the block number
- * of the last block in the given buffer. extra_bblks contains the number
- * of blocks we would have read on a previous read. This happens when the
- * last log record is split over the end of the physical log.
- *
- * extra_bblks is the number of blocks potentially verified on a previous
- * call to this routine.
- */
-STATIC int
-xlog_find_verify_log_record(
- xlog_t *log,
- xfs_daddr_t start_blk,
- xfs_daddr_t *last_blk,
- int extra_bblks)
-{
- xfs_daddr_t i;
- xfs_buf_t *bp;
- xfs_caddr_t offset = NULL;
- xlog_rec_header_t *head = NULL;
- int error = 0;
- int smallmem = 0;
- int num_blks = *last_blk - start_blk;
- int xhdrs;
-
- ASSERT(start_blk != 0 || *last_blk != start_blk);
-
- if (!(bp = xlog_get_bp(log, num_blks))) {
- if (!(bp = xlog_get_bp(log, 1)))
- return ENOMEM;
- smallmem = 1;
- } else {
- if ((error = xlog_bread(log, start_blk, num_blks, bp)))
- goto out;
- offset = xlog_align(log, start_blk, num_blks, bp);
- offset += ((num_blks - 1) << BBSHIFT);
- }
-
- for (i = (*last_blk) - 1; i >= 0; i--) {
- if (i < start_blk) {
- /* valid log record not found */
- xlog_warn(
- "XFS: Log inconsistent (didn't find previous header)");
- ASSERT(0);
- error = XFS_ERROR(EIO);
- goto out;
- }
-
- if (smallmem) {
- if ((error = xlog_bread(log, i, 1, bp)))
- goto out;
- offset = xlog_align(log, i, 1, bp);
- }
-
- head = (xlog_rec_header_t *)offset;
-
- if (XLOG_HEADER_MAGIC_NUM ==
- INT_GET(head->h_magicno, ARCH_CONVERT))
- break;
-
- if (!smallmem)
- offset -= BBSIZE;
- }
-
- /*
- * We hit the beginning of the physical log & still no header. Return
- * to caller. If caller can handle a return of -1, then this routine
- * will be called again for the end of the physical log.
- */
- if (i == -1) {
- error = -1;
- goto out;
- }
-
- /*
- * We have the final block of the good log (the first block
- * of the log record _before_ the head. So we check the uuid.
- */
- if ((error = xlog_header_check_mount(log->l_mp, head)))
- goto out;
-
- /*
- * We may have found a log record header before we expected one.
- * last_blk will be the 1st block # with a given cycle #. We may end
- * up reading an entire log record. In this case, we don't want to
- * reset last_blk. Only when last_blk points in the middle of a log
- * record do we update last_blk.
- */
- if (XFS_SB_VERSION_HASLOGV2(&log->l_mp->m_sb)) {
- uint h_size = INT_GET(head->h_size, ARCH_CONVERT);
-
- xhdrs = h_size / XLOG_HEADER_CYCLE_SIZE;
- if (h_size % XLOG_HEADER_CYCLE_SIZE)
- xhdrs++;
- } else {
- xhdrs = 1;
- }
-
- if (*last_blk - i + extra_bblks
- != BTOBB(INT_GET(head->h_len, ARCH_CONVERT)) + xhdrs)
- *last_blk = i;
-
-out:
- xlog_put_bp(bp);
- return error;
-}
-
-/*
- * Head is defined to be the point of the log where the next log write
- * write could go. This means that incomplete LR writes at the end are
- * eliminated when calculating the head. We aren't guaranteed that previous
- * LR have complete transactions. We only know that a cycle number of
- * current cycle number -1 won't be present in the log if we start writing
- * from our current block number.
- *
- * last_blk contains the block number of the first block with a given
- * cycle number.
- *
- * Return: zero if normal, non-zero if error.
- */
-STATIC int
-xlog_find_head(
- xlog_t *log,
- xfs_daddr_t *return_head_blk)
-{
- xfs_buf_t *bp;
- xfs_caddr_t offset;
- xfs_daddr_t new_blk, first_blk = 0, start_blk, last_blk, head_blk;
- int num_scan_bblks;
- uint first_half_cycle, last_half_cycle;
- uint stop_on_cycle;
- int error, log_bbnum = log->l_logBBsize;
-
- /* Is the end of the log device zeroed? */
- if ((error = xlog_find_zeroed(log, &first_blk)) == -1) {
- *return_head_blk = first_blk;
-
- /* Is the whole lot zeroed? */
- if (!first_blk) {
- /* Linux XFS shouldn't generate totally zeroed logs -
- * mkfs etc write a dummy unmount record to a fresh
- * log so we can store the uuid in there
- */
- xlog_warn("XFS: totally zeroed log");
- }
-
- return 0;
- } else if (error) {
- xlog_warn("XFS: empty log check failed");
- return error;
- }
-
- first_blk = 0; /* get cycle # of 1st block */
- bp = xlog_get_bp(log, 1);
- if (!bp)
- return ENOMEM;
- if ((error = xlog_bread(log, 0, 1, bp)))
- goto bp_err;
- offset = xlog_align(log, 0, 1, bp);
- first_half_cycle = GET_CYCLE(offset, ARCH_CONVERT);
-
- last_blk = head_blk = log_bbnum - 1; /* get cycle # of last block */
- if ((error = xlog_bread(log, last_blk, 1, bp)))
- goto bp_err;
- offset = xlog_align(log, last_blk, 1, bp);
- last_half_cycle = GET_CYCLE(offset, ARCH_CONVERT);
- ASSERT(last_half_cycle != 0);
-
- /*
- * If the 1st half cycle number is equal to the last half cycle number,
- * then the entire log is stamped with the same cycle number. In this
- * case, head_blk can't be set to zero (which makes sense). The below
- * math doesn't work out properly with head_blk equal to zero. Instead,
- * we set it to log_bbnum which is an invalid block number, but this
- * value makes the math correct. If head_blk doesn't changed through
- * all the tests below, *head_blk is set to zero at the very end rather
- * than log_bbnum. In a sense, log_bbnum and zero are the same block
- * in a circular file.
- */
- if (first_half_cycle == last_half_cycle) {
- /*
- * In this case we believe that the entire log should have
- * cycle number last_half_cycle. We need to scan backwards
- * from the end verifying that there are no holes still
- * containing last_half_cycle - 1. If we find such a hole,
- * then the start of that hole will be the new head. The
- * simple case looks like
- * x | x ... | x - 1 | x
- * Another case that fits this picture would be
- * x | x + 1 | x ... | x
- * In this case the head really is somewhere at the end of the
- * log, as one of the latest writes at the beginning was
- * incomplete.
- * One more case is
- * x | x + 1 | x ... | x - 1 | x
- * This is really the combination of the above two cases, and
- * the head has to end up at the start of the x-1 hole at the
- * end of the log.
- *
- * In the 256k log case, we will read from the beginning to the
- * end of the log and search for cycle numbers equal to x-1.
- * We don't worry about the x+1 blocks that we encounter,
- * because we know that they cannot be the head since the log
- * started with x.
- */
- head_blk = log_bbnum;
- stop_on_cycle = last_half_cycle - 1;
- } else {
- /*
- * In this case we want to find the first block with cycle
- * number matching last_half_cycle. We expect the log to be
- * some variation on
- * x + 1 ... | x ...
- * The first block with cycle number x (last_half_cycle) will
- * be where the new head belongs. First we do a binary search
- * for the first occurrence of last_half_cycle. The binary
- * search may not be totally accurate, so then we scan back
- * from there looking for occurrences of last_half_cycle before
- * us. If that backwards scan wraps around the beginning of
- * the log, then we look for occurrences of last_half_cycle - 1
- * at the end of the log. The cases we're looking for look
- * like
- * x + 1 ... | x | x + 1 | x ...
- * ^ binary search stopped here
- * or
- * x + 1 ... | x ... | x - 1 | x
- * <---------> less than scan distance
- */
- stop_on_cycle = last_half_cycle;
- if ((error = xlog_find_cycle_start(log, bp, first_blk,
- &head_blk, last_half_cycle)))
- goto bp_err;
- }
-
- /*
- * Now validate the answer. Scan back some number of maximum possible
- * blocks and make sure each one has the expected cycle number. The
- * maximum is determined by the total possible amount of buffering
- * in the in-core log. The following number can be made tighter if
- * we actually look at the block size of the filesystem.
- */
- num_scan_bblks = XLOG_TOTAL_REC_SHIFT(log);
- if (head_blk >= num_scan_bblks) {
- /*
- * We are guaranteed that the entire check can be performed
- * in one buffer.
- */
- start_blk = head_blk - num_scan_bblks;
- if ((error = xlog_find_verify_cycle(log,
- start_blk, num_scan_bblks,
- stop_on_cycle, &new_blk)))
- goto bp_err;
- if (new_blk != -1)
- head_blk = new_blk;
- } else { /* need to read 2 parts of log */
- /*
- * We are going to scan backwards in the log in two parts.
- * First we scan the physical end of the log. In this part
- * of the log, we are looking for blocks with cycle number
- * last_half_cycle - 1.
- * If we find one, then we know that the log starts there, as
- * we've found a hole that didn't get written in going around
- * the end of the physical log. The simple case for this is
- * x + 1 ... | x ... | x - 1 | x
- * <---------> less than scan distance
- * If all of the blocks at the end of the log have cycle number
- * last_half_cycle, then we check the blocks at the start of
- * the log looking for occurrences of last_half_cycle. If we
- * find one, then our current estimate for the location of the
- * first occurrence of last_half_cycle is wrong and we move
- * back to the hole we've found. This case looks like
- * x + 1 ... | x | x + 1 | x ...
- * ^ binary search stopped here
- * Another case we need to handle that only occurs in 256k
- * logs is
- * x + 1 ... | x ... | x+1 | x ...
- * ^ binary search stops here
- * In a 256k log, the scan at the end of the log will see the
- * x + 1 blocks. We need to skip past those since that is
- * certainly not the head of the log. By searching for
- * last_half_cycle-1 we accomplish that.
- */
- start_blk = log_bbnum - num_scan_bblks + head_blk;
- ASSERT(head_blk <= INT_MAX &&
- (xfs_daddr_t) num_scan_bblks - head_blk >= 0);
- if ((error = xlog_find_verify_cycle(log, start_blk,
- num_scan_bblks - (int)head_blk,
- (stop_on_cycle - 1), &new_blk)))
- goto bp_err;
- if (new_blk != -1) {
- head_blk = new_blk;
- goto bad_blk;
- }
-
- /*
- * Scan beginning of log now. The last part of the physical
- * log is good. This scan needs to verify that it doesn't find
- * the last_half_cycle.
- */
- start_blk = 0;
- ASSERT(head_blk <= INT_MAX);
- if ((error = xlog_find_verify_cycle(log,
- start_blk, (int)head_blk,
- stop_on_cycle, &new_blk)))
- goto bp_err;
- if (new_blk != -1)
- head_blk = new_blk;
- }
-
- bad_blk:
- /*
- * Now we need to make sure head_blk is not pointing to a block in
- * the middle of a log record.
- */
- num_scan_bblks = XLOG_REC_SHIFT(log);
- if (head_blk >= num_scan_bblks) {
- start_blk = head_blk - num_scan_bblks; /* don't read head_blk */
-
- /* start ptr at last block ptr before head_blk */
- if ((error = xlog_find_verify_log_record(log, start_blk,
- &head_blk, 0)) == -1) {
- error = XFS_ERROR(EIO);
- goto bp_err;
- } else if (error)
- goto bp_err;
- } else {
- start_blk = 0;
- ASSERT(head_blk <= INT_MAX);
- if ((error = xlog_find_verify_log_record(log, start_blk,
- &head_blk, 0)) == -1) {
- /* We hit the beginning of the log during our search */
- start_blk = log_bbnum - num_scan_bblks + head_blk;
- new_blk = log_bbnum;
- ASSERT(start_blk <= INT_MAX &&
- (xfs_daddr_t) log_bbnum-start_blk >= 0);
- ASSERT(head_blk <= INT_MAX);
- if ((error = xlog_find_verify_log_record(log,
- start_blk, &new_blk,
- (int)head_blk)) == -1) {
- error = XFS_ERROR(EIO);
- goto bp_err;
- } else if (error)
- goto bp_err;
- if (new_blk != log_bbnum)
- head_blk = new_blk;
- } else if (error)
- goto bp_err;
- }
-
- xlog_put_bp(bp);
- if (head_blk == log_bbnum)
- *return_head_blk = 0;
- else
- *return_head_blk = head_blk;
- /*
- * When returning here, we have a good block number. Bad block
- * means that during a previous crash, we didn't have a clean break
- * from cycle number N to cycle number N-1. In this case, we need
- * to find the first block with cycle number N-1.
- */
- return 0;
-
- bp_err:
- xlog_put_bp(bp);
-
- if (error)
- xlog_warn("XFS: failed to find log head");
- return error;
-}
-
-/*
- * Find the sync block number or the tail of the log.
- *
- * This will be the block number of the last record to have its
- * associated buffers synced to disk. Every log record header has
- * a sync lsn embedded in it. LSNs hold block numbers, so it is easy
- * to get a sync block number. The only concern is to figure out which
- * log record header to believe.
- *
- * The following algorithm uses the log record header with the largest
- * lsn. The entire log record does not need to be valid. We only care
- * that the header is valid.
- *
- * We could speed up search by using current head_blk buffer, but it is not
- * available.
- */
-int
-xlog_find_tail(
- xlog_t *log,
- xfs_daddr_t *head_blk,
- xfs_daddr_t *tail_blk)
-{
- xlog_rec_header_t *rhead;
- xlog_op_header_t *op_head;
- xfs_caddr_t offset = NULL;
- xfs_buf_t *bp;
- int error, i, found;
- xfs_daddr_t umount_data_blk;
- xfs_daddr_t after_umount_blk;
- xfs_lsn_t tail_lsn;
- int hblks;
-
- found = 0;
-
- /*
- * Find previous log record
- */
- if ((error = xlog_find_head(log, head_blk)))
- return error;
-
- bp = xlog_get_bp(log, 1);
- if (!bp)
- return ENOMEM;
- if (*head_blk == 0) { /* special case */
- if ((error = xlog_bread(log, 0, 1, bp)))
- goto bread_err;
- offset = xlog_align(log, 0, 1, bp);
- if (GET_CYCLE(offset, ARCH_CONVERT) == 0) {
- *tail_blk = 0;
- /* leave all other log inited values alone */
- goto exit;
- }
- }
-
- /*
- * Search backwards looking for log record header block
- */
- ASSERT(*head_blk < INT_MAX);
- for (i = (int)(*head_blk) - 1; i >= 0; i--) {
- if ((error = xlog_bread(log, i, 1, bp)))
- goto bread_err;
- offset = xlog_align(log, i, 1, bp);
- if (XLOG_HEADER_MAGIC_NUM ==
- INT_GET(*(uint *)offset, ARCH_CONVERT)) {
- found = 1;
- break;
- }
- }
- /*
- * If we haven't found the log record header block, start looking
- * again from the end of the physical log. XXXmiken: There should be
- * a check here to make sure we didn't search more than N blocks in
- * the previous code.
- */
- if (!found) {
- for (i = log->l_logBBsize - 1; i >= (int)(*head_blk); i--) {
- if ((error = xlog_bread(log, i, 1, bp)))
- goto bread_err;
- offset = xlog_align(log, i, 1, bp);
- if (XLOG_HEADER_MAGIC_NUM ==
- INT_GET(*(uint*)offset, ARCH_CONVERT)) {
- found = 2;
- break;
- }
- }
- }
- if (!found) {
- xlog_warn("XFS: xlog_find_tail: couldn't find sync record");
- ASSERT(0);
- return XFS_ERROR(EIO);
- }
-
- /* find blk_no of tail of log */
- rhead = (xlog_rec_header_t *)offset;
- *tail_blk = BLOCK_LSN(INT_GET(rhead->h_tail_lsn, ARCH_CONVERT));
-
- /*
- * Reset log values according to the state of the log when we
- * crashed. In the case where head_blk == 0, we bump curr_cycle
- * one because the next write starts a new cycle rather than
- * continuing the cycle of the last good log record. At this
- * point we have guaranteed that all partial log records have been
- * accounted for. Therefore, we know that the last good log record
- * written was complete and ended exactly on the end boundary
- * of the physical log.
- */
- log->l_prev_block = i;
- log->l_curr_block = (int)*head_blk;
- log->l_curr_cycle = INT_GET(rhead->h_cycle, ARCH_CONVERT);
- if (found == 2)
- log->l_curr_cycle++;
- log->l_tail_lsn = INT_GET(rhead->h_tail_lsn, ARCH_CONVERT);
- log->l_last_sync_lsn = INT_GET(rhead->h_lsn, ARCH_CONVERT);
- log->l_grant_reserve_cycle = log->l_curr_cycle;
- log->l_grant_reserve_bytes = BBTOB(log->l_curr_block);
- log->l_grant_write_cycle = log->l_curr_cycle;
- log->l_grant_write_bytes = BBTOB(log->l_curr_block);
-
- /*
- * Look for unmount record. If we find it, then we know there
- * was a clean unmount. Since 'i' could be the last block in
- * the physical log, we convert to a log block before comparing
- * to the head_blk.
- *
- * Save the current tail lsn to use to pass to
- * xlog_clear_stale_blocks() below. We won't want to clear the
- * unmount record if there is one, so we pass the lsn of the
- * unmount record rather than the block after it.
- */
- if (XFS_SB_VERSION_HASLOGV2(&log->l_mp->m_sb)) {
- int h_size = INT_GET(rhead->h_size, ARCH_CONVERT);
- int h_version = INT_GET(rhead->h_version, ARCH_CONVERT);
-
- if ((h_version & XLOG_VERSION_2) &&
- (h_size > XLOG_HEADER_CYCLE_SIZE)) {
- hblks = h_size / XLOG_HEADER_CYCLE_SIZE;
- if (h_size % XLOG_HEADER_CYCLE_SIZE)
- hblks++;
- } else {
- hblks = 1;
- }
- } else {
- hblks = 1;
- }
- after_umount_blk = (i + hblks + (int)
- BTOBB(INT_GET(rhead->h_len, ARCH_CONVERT))) % log->l_logBBsize;
- tail_lsn = log->l_tail_lsn;
- if (*head_blk == after_umount_blk &&
- INT_GET(rhead->h_num_logops, ARCH_CONVERT) == 1) {
- umount_data_blk = (i + hblks) % log->l_logBBsize;
- if ((error = xlog_bread(log, umount_data_blk, 1, bp))) {
- goto bread_err;
- }
- offset = xlog_align(log, umount_data_blk, 1, bp);
- op_head = (xlog_op_header_t *)offset;
- if (op_head->oh_flags & XLOG_UNMOUNT_TRANS) {
- /*
- * Set tail and last sync so that newly written
- * log records will point recovery to after the
- * current unmount record.
- */
- ASSIGN_ANY_LSN_HOST(log->l_tail_lsn, log->l_curr_cycle,
- after_umount_blk);
- ASSIGN_ANY_LSN_HOST(log->l_last_sync_lsn, log->l_curr_cycle,
- after_umount_blk);
- *tail_blk = after_umount_blk;
- }
- }
-
- /*
- * Make sure that there are no blocks in front of the head
- * with the same cycle number as the head. This can happen
- * because we allow multiple outstanding log writes concurrently,
- * and the later writes might make it out before earlier ones.
- *
- * We use the lsn from before modifying it so that we'll never
- * overwrite the unmount record after a clean unmount.
- *
- * Do this only if we are going to recover the filesystem
- *
- * NOTE: This used to say "if (!readonly)"
- * However on Linux, we can & do recover a read-only filesystem.
- * We only skip recovery if NORECOVERY is specified on mount,
- * in which case we would not be here.
- *
- * But... if the -device- itself is readonly, just skip this.
- * We can't recover this device anyway, so it won't matter.
- */
- if (!xfs_readonly_buftarg(log->l_mp->m_logdev_targp)) {
- error = xlog_clear_stale_blocks(log, tail_lsn);
- }
-
-bread_err:
-exit:
- xlog_put_bp(bp);
-
- if (error)
- xlog_warn("XFS: failed to locate log tail");
- return error;
-}
-
-/*
- * Is the log zeroed at all?
- *
- * The last binary search should be changed to perform an X block read
- * once X becomes small enough. You can then search linearly through
- * the X blocks. This will cut down on the number of reads we need to do.
- *
- * If the log is partially zeroed, this routine will pass back the blkno
- * of the first block with cycle number 0. It won't have a complete LR
- * preceding it.
- *
- * Return:
- * 0 => the log is completely written to
- * -1 => use *blk_no as the first block of the log
- * >0 => error has occurred
- */
-int
-xlog_find_zeroed(
- xlog_t *log,
- xfs_daddr_t *blk_no)
-{
- xfs_buf_t *bp;
- xfs_caddr_t offset;
- uint first_cycle, last_cycle;
- xfs_daddr_t new_blk, last_blk, start_blk;
- xfs_daddr_t num_scan_bblks;
- int error, log_bbnum = log->l_logBBsize;
-
- /* check totally zeroed log */
- bp = xlog_get_bp(log, 1);
- if (!bp)
- return ENOMEM;
- if ((error = xlog_bread(log, 0, 1, bp)))
- goto bp_err;
- offset = xlog_align(log, 0, 1, bp);
- first_cycle = GET_CYCLE(offset, ARCH_CONVERT);
- if (first_cycle == 0) { /* completely zeroed log */
- *blk_no = 0;
- xlog_put_bp(bp);
- return -1;
- }
-
- /* check partially zeroed log */
- if ((error = xlog_bread(log, log_bbnum-1, 1, bp)))
- goto bp_err;
- offset = xlog_align(log, log_bbnum-1, 1, bp);
- last_cycle = GET_CYCLE(offset, ARCH_CONVERT);
- if (last_cycle != 0) { /* log completely written to */
- xlog_put_bp(bp);
- return 0;
- } else if (first_cycle != 1) {
- /*
- * If the cycle of the last block is zero, the cycle of
- * the first block must be 1. If it's not, maybe we're
- * not looking at a log... Bail out.
- */
- xlog_warn("XFS: Log inconsistent or not a log (last==0, first!=1)");
- return XFS_ERROR(EINVAL);
- }
-
- /* we have a partially zeroed log */
- last_blk = log_bbnum-1;
- if ((error = xlog_find_cycle_start(log, bp, 0, &last_blk, 0)))
- goto bp_err;
-
- /*
- * Validate the answer. Because there is no way to guarantee that
- * the entire log is made up of log records which are the same size,
- * we scan over the defined maximum blocks. At this point, the maximum
- * is not chosen to mean anything special. XXXmiken
- */
- num_scan_bblks = XLOG_TOTAL_REC_SHIFT(log);
- ASSERT(num_scan_bblks <= INT_MAX);
-
- if (last_blk < num_scan_bblks)
- num_scan_bblks = last_blk;
- start_blk = last_blk - num_scan_bblks;
-
- /*
- * We search for any instances of cycle number 0 that occur before
- * our current estimate of the head. What we're trying to detect is
- * 1 ... | 0 | 1 | 0...
- * ^ binary search ends here
- */
- if ((error = xlog_find_verify_cycle(log, start_blk,
- (int)num_scan_bblks, 0, &new_blk)))
- goto bp_err;
- if (new_blk != -1)
- last_blk = new_blk;
-
- /*
- * Potentially backup over partial log record write. We don't need
- * to search the end of the log because we know it is zero.
- */
- if ((error = xlog_find_verify_log_record(log, start_blk,
- &last_blk, 0)) == -1) {
- error = XFS_ERROR(EIO);
- goto bp_err;
- } else if (error)
- goto bp_err;
-
- *blk_no = last_blk;
-bp_err:
- xlog_put_bp(bp);
- if (error)
- return error;
- return -1;
-}
-
-/*
- * These are simple subroutines used by xlog_clear_stale_blocks() below
- * to initialize a buffer full of empty log record headers and write
- * them into the log.
- */
-STATIC void
-xlog_add_record(
- xlog_t *log,
- xfs_caddr_t buf,
- int cycle,
- int block,
- int tail_cycle,
- int tail_block)
-{
- xlog_rec_header_t *recp = (xlog_rec_header_t *)buf;
-
- memset(buf, 0, BBSIZE);
- INT_SET(recp->h_magicno, ARCH_CONVERT, XLOG_HEADER_MAGIC_NUM);
- INT_SET(recp->h_cycle, ARCH_CONVERT, cycle);
- INT_SET(recp->h_version, ARCH_CONVERT,
- XFS_SB_VERSION_HASLOGV2(&log->l_mp->m_sb) ? 2 : 1);
- ASSIGN_ANY_LSN_DISK(recp->h_lsn, cycle, block);
- ASSIGN_ANY_LSN_DISK(recp->h_tail_lsn, tail_cycle, tail_block);
- INT_SET(recp->h_fmt, ARCH_CONVERT, XLOG_FMT);
- memcpy(&recp->h_fs_uuid, &log->l_mp->m_sb.sb_uuid, sizeof(uuid_t));
-}
-
-STATIC int
-xlog_write_log_records(
- xlog_t *log,
- int cycle,
- int start_block,
- int blocks,
- int tail_cycle,
- int tail_block)
-{
- xfs_caddr_t offset;
- xfs_buf_t *bp;
- int balign, ealign;
- int sectbb = XLOG_SECTOR_ROUNDUP_BBCOUNT(log, 1);
- int end_block = start_block + blocks;
- int bufblks;
- int error = 0;
- int i, j = 0;
-
- bufblks = 1 << ffs(blocks);
- while (!(bp = xlog_get_bp(log, bufblks))) {
- bufblks >>= 1;
- if (bufblks <= log->l_sectbb_log)
- return ENOMEM;
- }
-
- /* We may need to do a read at the start to fill in part of
- * the buffer in the starting sector not covered by the first
- * write below.
- */
- balign = XLOG_SECTOR_ROUNDDOWN_BLKNO(log, start_block);
- if (balign != start_block) {
- if ((error = xlog_bread(log, start_block, 1, bp))) {
- xlog_put_bp(bp);
- return error;
- }
- j = start_block - balign;
- }
-
- for (i = start_block; i < end_block; i += bufblks) {
- int bcount, endcount;
-
- bcount = min(bufblks, end_block - start_block);
- endcount = bcount - j;
-
- /* We may need to do a read at the end to fill in part of
- * the buffer in the final sector not covered by the write.
- * If this is the same sector as the above read, skip it.
- */
- ealign = XLOG_SECTOR_ROUNDDOWN_BLKNO(log, end_block);
- if (j == 0 && (start_block + endcount > ealign)) {
- offset = XFS_BUF_PTR(bp);
- balign = BBTOB(ealign - start_block);
- XFS_BUF_SET_PTR(bp, offset + balign, BBTOB(sectbb));
- if ((error = xlog_bread(log, ealign, sectbb, bp)))
- break;
- XFS_BUF_SET_PTR(bp, offset, bufblks);
- }
-
- offset = xlog_align(log, start_block, endcount, bp);
- for (; j < endcount; j++) {
- xlog_add_record(log, offset, cycle, i+j,
- tail_cycle, tail_block);
- offset += BBSIZE;
- }
- error = xlog_bwrite(log, start_block, endcount, bp);
- if (error)
- break;
- start_block += endcount;
- j = 0;
- }
- xlog_put_bp(bp);
- return error;
-}
-
-/*
- * This routine is called to blow away any incomplete log writes out
- * in front of the log head. We do this so that we won't become confused
- * if we come up, write only a little bit more, and then crash again.
- * If we leave the partial log records out there, this situation could
- * cause us to think those partial writes are valid blocks since they
- * have the current cycle number. We get rid of them by overwriting them
- * with empty log records with the old cycle number rather than the
- * current one.
- *
- * The tail lsn is passed in rather than taken from
- * the log so that we will not write over the unmount record after a
- * clean unmount in a 512 block log. Doing so would leave the log without
- * any valid log records in it until a new one was written. If we crashed
- * during that time we would not be able to recover.
- */
-STATIC int
-xlog_clear_stale_blocks(
- xlog_t *log,
- xfs_lsn_t tail_lsn)
-{
- int tail_cycle, head_cycle;
- int tail_block, head_block;
- int tail_distance, max_distance;
- int distance;
- int error;
-
- tail_cycle = CYCLE_LSN(tail_lsn);
- tail_block = BLOCK_LSN(tail_lsn);
- head_cycle = log->l_curr_cycle;
- head_block = log->l_curr_block;
-
- /*
- * Figure out the distance between the new head of the log
- * and the tail. We want to write over any blocks beyond the
- * head that we may have written just before the crash, but
- * we don't want to overwrite the tail of the log.
- */
- if (head_cycle == tail_cycle) {
- /*
- * The tail is behind the head in the physical log,
- * so the distance from the head to the tail is the
- * distance from the head to the end of the log plus
- * the distance from the beginning of the log to the
- * tail.
- */
- if (unlikely(head_block < tail_block || head_block >= log->l_logBBsize)) {
- XFS_ERROR_REPORT("xlog_clear_stale_blocks(1)",
- XFS_ERRLEVEL_LOW, log->l_mp);
- return XFS_ERROR(EFSCORRUPTED);
- }
- tail_distance = tail_block + (log->l_logBBsize - head_block);
- } else {
- /*
- * The head is behind the tail in the physical log,
- * so the distance from the head to the tail is just
- * the tail block minus the head block.
- */
- if (unlikely(head_block >= tail_block || head_cycle != (tail_cycle + 1))){
- XFS_ERROR_REPORT("xlog_clear_stale_blocks(2)",
- XFS_ERRLEVEL_LOW, log->l_mp);
- return XFS_ERROR(EFSCORRUPTED);
- }
- tail_distance = tail_block - head_block;
- }
-
- /*
- * If the head is right up against the tail, we can't clear
- * anything.
- */
- if (tail_distance <= 0) {
- ASSERT(tail_distance == 0);
- return 0;
- }
-
- max_distance = XLOG_TOTAL_REC_SHIFT(log);
- /*
- * Take the smaller of the maximum amount of outstanding I/O
- * we could have and the distance to the tail to clear out.
- * We take the smaller so that we don't overwrite the tail and
- * we don't waste all day writing from the head to the tail
- * for no reason.
- */
- max_distance = MIN(max_distance, tail_distance);
-
- if ((head_block + max_distance) <= log->l_logBBsize) {
- /*
- * We can stomp all the blocks we need to without
- * wrapping around the end of the log. Just do it
- * in a single write. Use the cycle number of the
- * current cycle minus one so that the log will look like:
- * n ... | n - 1 ...
- */
- error = xlog_write_log_records(log, (head_cycle - 1),
- head_block, max_distance, tail_cycle,
- tail_block);
- if (error)
- return error;
- } else {
- /*
- * We need to wrap around the end of the physical log in
- * order to clear all the blocks. Do it in two separate
- * I/Os. The first write should be from the head to the
- * end of the physical log, and it should use the current
- * cycle number minus one just like above.
- */
- distance = log->l_logBBsize - head_block;
- error = xlog_write_log_records(log, (head_cycle - 1),
- head_block, distance, tail_cycle,
- tail_block);
-
- if (error)
- return error;
-
- /*
- * Now write the blocks at the start of the physical log.
- * This writes the remainder of the blocks we want to clear.
- * It uses the current cycle number since we're now on the
- * same cycle as the head so that we get:
- * n ... n ... | n - 1 ...
- * ^^^^^ blocks we're writing
- */
- distance = max_distance - (log->l_logBBsize - head_block);
- error = xlog_write_log_records(log, head_cycle, 0, distance,
- tail_cycle, tail_block);
- if (error)
- return error;
- }
-
- return 0;
-}
-
-/******************************************************************************
- *
- * Log recover routines
- *
- ******************************************************************************
- */
-
-STATIC xlog_recover_t *
-xlog_recover_find_tid(
- xlog_recover_t *q,
- xlog_tid_t tid)
-{
- xlog_recover_t *p = q;
-
- while (p != NULL) {
- if (p->r_log_tid == tid)
- break;
- p = p->r_next;
- }
- return p;
-}
-
-STATIC void
-xlog_recover_put_hashq(
- xlog_recover_t **q,
- xlog_recover_t *trans)
-{
- trans->r_next = *q;
- *q = trans;
-}
-
-STATIC void
-xlog_recover_add_item(
- xlog_recover_item_t **itemq)
-{
- xlog_recover_item_t *item;
-
- item = kmem_zalloc(sizeof(xlog_recover_item_t), KM_SLEEP);
- xlog_recover_insert_item_backq(itemq, item);
-}
-
-STATIC int
-xlog_recover_add_to_cont_trans(
- xlog_recover_t *trans,
- xfs_caddr_t dp,
- int len)
-{
- xlog_recover_item_t *item;
- xfs_caddr_t ptr, old_ptr;
- int old_len;
-
- item = trans->r_itemq;
- if (item == 0) {
- /* finish copying rest of trans header */
- xlog_recover_add_item(&trans->r_itemq);
- ptr = (xfs_caddr_t) &trans->r_theader +
- sizeof(xfs_trans_header_t) - len;
- memcpy(ptr, dp, len); /* d, s, l */
- return 0;
- }
- item = item->ri_prev;
-
- old_ptr = item->ri_buf[item->ri_cnt-1].i_addr;
- old_len = item->ri_buf[item->ri_cnt-1].i_len;
-
- ptr = kmem_realloc(old_ptr, len+old_len, old_len, 0u);
- memcpy(&ptr[old_len], dp, len); /* d, s, l */
- item->ri_buf[item->ri_cnt-1].i_len += len;
- item->ri_buf[item->ri_cnt-1].i_addr = ptr;
- return 0;
-}
-
-/*
- * The next region to add is the start of a new region. It could be
- * a whole region or it could be the first part of a new region. Because
- * of this, the assumption here is that the type and size fields of all
- * format structures fit into the first 32 bits of the structure.
- *
- * This works because all regions must be 32 bit aligned. Therefore, we
- * either have both fields or we have neither field. In the case we have
- * neither field, the data part of the region is zero length. We only have
- * a log_op_header and can throw away the header since a new one will appear
- * later. If we have at least 4 bytes, then we can determine how many regions
- * will appear in the current log item.
- */
-STATIC int
-xlog_recover_add_to_trans(
- xlog_recover_t *trans,
- xfs_caddr_t dp,
- int len)
-{
- xfs_inode_log_format_t *in_f; /* any will do */
- xlog_recover_item_t *item;
- xfs_caddr_t ptr;
-
- if (!len)
- return 0;
- item = trans->r_itemq;
- if (item == 0) {
- ASSERT(*(uint *)dp == XFS_TRANS_HEADER_MAGIC);
- if (len == sizeof(xfs_trans_header_t))
- xlog_recover_add_item(&trans->r_itemq);
- memcpy(&trans->r_theader, dp, len); /* d, s, l */
- return 0;
- }
-
- ptr = kmem_alloc(len, KM_SLEEP);
- memcpy(ptr, dp, len);
- in_f = (xfs_inode_log_format_t *)ptr;
-
- if (item->ri_prev->ri_total != 0 &&
- item->ri_prev->ri_total == item->ri_prev->ri_cnt) {
- xlog_recover_add_item(&trans->r_itemq);
- }
- item = trans->r_itemq;
- item = item->ri_prev;
-
- if (item->ri_total == 0) { /* first region to be added */
- item->ri_total = in_f->ilf_size;
- ASSERT(item->ri_total <= XLOG_MAX_REGIONS_IN_ITEM);
- item->ri_buf = kmem_zalloc((item->ri_total *
- sizeof(xfs_log_iovec_t)), KM_SLEEP);
- }
- ASSERT(item->ri_total > item->ri_cnt);
- /* Description region is ri_buf[0] */
- item->ri_buf[item->ri_cnt].i_addr = ptr;
- item->ri_buf[item->ri_cnt].i_len = len;
- item->ri_cnt++;
- return 0;
-}
-
-STATIC void
-xlog_recover_new_tid(
- xlog_recover_t **q,
- xlog_tid_t tid,
- xfs_lsn_t lsn)
-{
- xlog_recover_t *trans;
-
- trans = kmem_zalloc(sizeof(xlog_recover_t), KM_SLEEP);
- trans->r_log_tid = tid;
- trans->r_lsn = lsn;
- xlog_recover_put_hashq(q, trans);
-}
-
-STATIC int
-xlog_recover_unlink_tid(
- xlog_recover_t **q,
- xlog_recover_t *trans)
-{
- xlog_recover_t *tp;
- int found = 0;
-
- ASSERT(trans != 0);
- if (trans == *q) {
- *q = (*q)->r_next;
- } else {
- tp = *q;
- while (tp != 0) {
- if (tp->r_next == trans) {
- found = 1;
- break;
- }
- tp = tp->r_next;
- }
- if (!found) {
- xlog_warn(
- "XFS: xlog_recover_unlink_tid: trans not found");
- ASSERT(0);
- return XFS_ERROR(EIO);
- }
- tp->r_next = tp->r_next->r_next;
- }
- return 0;
-}
-
-STATIC void
-xlog_recover_insert_item_backq(
- xlog_recover_item_t **q,
- xlog_recover_item_t *item)
-{
- if (*q == 0) {
- item->ri_prev = item->ri_next = item;
- *q = item;
- } else {
- item->ri_next = *q;
- item->ri_prev = (*q)->ri_prev;
- (*q)->ri_prev = item;
- item->ri_prev->ri_next = item;
- }
-}
-
-STATIC void
-xlog_recover_insert_item_frontq(
- xlog_recover_item_t **q,
- xlog_recover_item_t *item)
-{
- xlog_recover_insert_item_backq(q, item);
- *q = item;
-}
-
-STATIC int
-xlog_recover_reorder_trans(
- xlog_t *log,
- xlog_recover_t *trans)
-{
- xlog_recover_item_t *first_item, *itemq, *itemq_next;
- xfs_buf_log_format_t *buf_f;
- xfs_buf_log_format_v1_t *obuf_f;
- ushort flags = 0;
-
- first_item = itemq = trans->r_itemq;
- trans->r_itemq = NULL;
- do {
- itemq_next = itemq->ri_next;
- buf_f = (xfs_buf_log_format_t *)itemq->ri_buf[0].i_addr;
- switch (ITEM_TYPE(itemq)) {
- case XFS_LI_BUF:
- flags = buf_f->blf_flags;
- break;
- case XFS_LI_6_1_BUF:
- case XFS_LI_5_3_BUF:
- obuf_f = (xfs_buf_log_format_v1_t*)buf_f;
- flags = obuf_f->blf_flags;
- break;
- }
-
- switch (ITEM_TYPE(itemq)) {
- case XFS_LI_BUF:
- case XFS_LI_6_1_BUF:
- case XFS_LI_5_3_BUF:
- if (!(flags & XFS_BLI_CANCEL)) {
- xlog_recover_insert_item_frontq(&trans->r_itemq,
- itemq);
- break;
- }
- case XFS_LI_INODE:
- case XFS_LI_6_1_INODE:
- case XFS_LI_5_3_INODE:
- case XFS_LI_DQUOT:
- case XFS_LI_QUOTAOFF:
- case XFS_LI_EFD:
- case XFS_LI_EFI:
- xlog_recover_insert_item_backq(&trans->r_itemq, itemq);
- break;
- default:
- xlog_warn(
- "XFS: xlog_recover_reorder_trans: unrecognized type of log operation");
- ASSERT(0);
- return XFS_ERROR(EIO);
- }
- itemq = itemq_next;
- } while (first_item != itemq);
- return 0;
-}
-
-/*
- * Build up the table of buf cancel records so that we don't replay
- * cancelled data in the second pass. For buffer records that are
- * not cancel records, there is nothing to do here so we just return.
- *
- * If we get a cancel record which is already in the table, this indicates
- * that the buffer was cancelled multiple times. In order to ensure
- * that during pass 2 we keep the record in the table until we reach its
- * last occurrence in the log, we keep a reference count in the cancel
- * record in the table to tell us how many times we expect to see this
- * record during the second pass.
- */
-STATIC void
-xlog_recover_do_buffer_pass1(
- xlog_t *log,
- xfs_buf_log_format_t *buf_f)
-{
- xfs_buf_cancel_t *bcp;
- xfs_buf_cancel_t *nextp;
- xfs_buf_cancel_t *prevp;
- xfs_buf_cancel_t **bucket;
- xfs_buf_log_format_v1_t *obuf_f;
- xfs_daddr_t blkno = 0;
- uint len = 0;
- ushort flags = 0;
-
- switch (buf_f->blf_type) {
- case XFS_LI_BUF:
- blkno = buf_f->blf_blkno;
- len = buf_f->blf_len;
- flags = buf_f->blf_flags;
- break;
- case XFS_LI_6_1_BUF:
- case XFS_LI_5_3_BUF:
- obuf_f = (xfs_buf_log_format_v1_t*)buf_f;
- blkno = (xfs_daddr_t) obuf_f->blf_blkno;
- len = obuf_f->blf_len;
- flags = obuf_f->blf_flags;
- break;
- }
-
- /*
- * If this isn't a cancel buffer item, then just return.
- */
- if (!(flags & XFS_BLI_CANCEL))
- return;
-
- /*
- * Insert an xfs_buf_cancel record into the hash table of
- * them. If there is already an identical record, bump
- * its reference count.
- */
- bucket = &log->l_buf_cancel_table[(__uint64_t)blkno %
- XLOG_BC_TABLE_SIZE];
- /*
- * If the hash bucket is empty then just insert a new record into
- * the bucket.
- */
- if (*bucket == NULL) {
- bcp = (xfs_buf_cancel_t *)kmem_alloc(sizeof(xfs_buf_cancel_t),
- KM_SLEEP);
- bcp->bc_blkno = blkno;
- bcp->bc_len = len;
- bcp->bc_refcount = 1;
- bcp->bc_next = NULL;
- *bucket = bcp;
- return;
- }
-
- /*
- * The hash bucket is not empty, so search for duplicates of our
- * record. If we find one them just bump its refcount. If not
- * then add us at the end of the list.
- */
- prevp = NULL;
- nextp = *bucket;
- while (nextp != NULL) {
- if (nextp->bc_blkno == blkno && nextp->bc_len == len) {
- nextp->bc_refcount++;
- return;
- }
- prevp = nextp;
- nextp = nextp->bc_next;
- }
- ASSERT(prevp != NULL);
- bcp = (xfs_buf_cancel_t *)kmem_alloc(sizeof(xfs_buf_cancel_t),
- KM_SLEEP);
- bcp->bc_blkno = blkno;
- bcp->bc_len = len;
- bcp->bc_refcount = 1;
- bcp->bc_next = NULL;
- prevp->bc_next = bcp;
-}
-
-/*
- * Check to see whether the buffer being recovered has a corresponding
- * entry in the buffer cancel record table. If it does then return 1
- * so that it will be cancelled, otherwise return 0. If the buffer is
- * actually a buffer cancel item (XFS_BLI_CANCEL is set), then decrement
- * the refcount on the entry in the table and remove it from the table
- * if this is the last reference.
- *
- * We remove the cancel record from the table when we encounter its
- * last occurrence in the log so that if the same buffer is re-used
- * again after its last cancellation we actually replay the changes
- * made at that point.
- */
-STATIC int
-xlog_check_buffer_cancelled(
- xlog_t *log,
- xfs_daddr_t blkno,
- uint len,
- ushort flags)
-{
- xfs_buf_cancel_t *bcp;
- xfs_buf_cancel_t *prevp;
- xfs_buf_cancel_t **bucket;
-
- if (log->l_buf_cancel_table == NULL) {
- /*
- * There is nothing in the table built in pass one,
- * so this buffer must not be cancelled.
- */
- ASSERT(!(flags & XFS_BLI_CANCEL));
- return 0;
- }
-
- bucket = &log->l_buf_cancel_table[(__uint64_t)blkno %
- XLOG_BC_TABLE_SIZE];
- bcp = *bucket;
- if (bcp == NULL) {
- /*
- * There is no corresponding entry in the table built
- * in pass one, so this buffer has not been cancelled.
- */
- ASSERT(!(flags & XFS_BLI_CANCEL));
- return 0;
- }
-
- /*
- * Search for an entry in the buffer cancel table that
- * matches our buffer.
- */
- prevp = NULL;
- while (bcp != NULL) {
- if (bcp->bc_blkno == blkno && bcp->bc_len == len) {
- /*
- * We've go a match, so return 1 so that the
- * recovery of this buffer is cancelled.
- * If this buffer is actually a buffer cancel
- * log item, then decrement the refcount on the
- * one in the table and remove it if this is the
- * last reference.
- */
- if (flags & XFS_BLI_CANCEL) {
- bcp->bc_refcount--;
- if (bcp->bc_refcount == 0) {
- if (prevp == NULL) {
- *bucket = bcp->bc_next;
- } else {
- prevp->bc_next = bcp->bc_next;
- }
- kmem_free(bcp,
- sizeof(xfs_buf_cancel_t));
- }
- }
- return 1;
- }
- prevp = bcp;
- bcp = bcp->bc_next;
- }
- /*
- * We didn't find a corresponding entry in the table, so
- * return 0 so that the buffer is NOT cancelled.
- */
- ASSERT(!(flags & XFS_BLI_CANCEL));
- return 0;
-}
-
-STATIC int
-xlog_recover_do_buffer_pass2(
- xlog_t *log,
- xfs_buf_log_format_t *buf_f)
-{
- xfs_buf_log_format_v1_t *obuf_f;
- xfs_daddr_t blkno = 0;
- ushort flags = 0;
- uint len = 0;
-
- switch (buf_f->blf_type) {
- case XFS_LI_BUF:
- blkno = buf_f->blf_blkno;
- flags = buf_f->blf_flags;
- len = buf_f->blf_len;
- break;
- case XFS_LI_6_1_BUF:
- case XFS_LI_5_3_BUF:
- obuf_f = (xfs_buf_log_format_v1_t*)buf_f;
- blkno = (xfs_daddr_t) obuf_f->blf_blkno;
- flags = obuf_f->blf_flags;
- len = (xfs_daddr_t) obuf_f->blf_len;
- break;
- }
-
- return xlog_check_buffer_cancelled(log, blkno, len, flags);
-}
-
-/*
- * Perform recovery for a buffer full of inodes. In these buffers,
- * the only data which should be recovered is that which corresponds
- * to the di_next_unlinked pointers in the on disk inode structures.
- * The rest of the data for the inodes is always logged through the
- * inodes themselves rather than the inode buffer and is recovered
- * in xlog_recover_do_inode_trans().
- *
- * The only time when buffers full of inodes are fully recovered is
- * when the buffer is full of newly allocated inodes. In this case
- * the buffer will not be marked as an inode buffer and so will be
- * sent to xlog_recover_do_reg_buffer() below during recovery.
- */
-STATIC int
-xlog_recover_do_inode_buffer(
- xfs_mount_t *mp,
- xlog_recover_item_t *item,
- xfs_buf_t *bp,
- xfs_buf_log_format_t *buf_f)
-{
- int i;
- int item_index;
- int bit;
- int nbits;
- int reg_buf_offset;
- int reg_buf_bytes;
- int next_unlinked_offset;
- int inodes_per_buf;
- xfs_agino_t *logged_nextp;
- xfs_agino_t *buffer_nextp;
- xfs_buf_log_format_v1_t *obuf_f;
- unsigned int *data_map = NULL;
- unsigned int map_size = 0;
-
- switch (buf_f->blf_type) {
- case XFS_LI_BUF:
- data_map = buf_f->blf_data_map;
- map_size = buf_f->blf_map_size;
- break;
- case XFS_LI_6_1_BUF:
- case XFS_LI_5_3_BUF:
- obuf_f = (xfs_buf_log_format_v1_t*)buf_f;
- data_map = obuf_f->blf_data_map;
- map_size = obuf_f->blf_map_size;
- break;
- }
- /*
- * Set the variables corresponding to the current region to
- * 0 so that we'll initialize them on the first pass through
- * the loop.
- */
- reg_buf_offset = 0;
- reg_buf_bytes = 0;
- bit = 0;
- nbits = 0;
- item_index = 0;
- inodes_per_buf = XFS_BUF_COUNT(bp) >> mp->m_sb.sb_inodelog;
- for (i = 0; i < inodes_per_buf; i++) {
- next_unlinked_offset = (i * mp->m_sb.sb_inodesize) +
- offsetof(xfs_dinode_t, di_next_unlinked);
-
- while (next_unlinked_offset >=
- (reg_buf_offset + reg_buf_bytes)) {
- /*
- * The next di_next_unlinked field is beyond
- * the current logged region. Find the next
- * logged region that contains or is beyond
- * the current di_next_unlinked field.
- */
- bit += nbits;
- bit = xfs_next_bit(data_map, map_size, bit);
-
- /*
- * If there are no more logged regions in the
- * buffer, then we're done.
- */
- if (bit == -1) {
- return 0;
- }
-
- nbits = xfs_contig_bits(data_map, map_size,
- bit);
- ASSERT(nbits > 0);
- reg_buf_offset = bit << XFS_BLI_SHIFT;
- reg_buf_bytes = nbits << XFS_BLI_SHIFT;
- item_index++;
- }
-
- /*
- * If the current logged region starts after the current
- * di_next_unlinked field, then move on to the next
- * di_next_unlinked field.
- */
- if (next_unlinked_offset < reg_buf_offset) {
- continue;
- }
-
- ASSERT(item->ri_buf[item_index].i_addr != NULL);
- ASSERT((item->ri_buf[item_index].i_len % XFS_BLI_CHUNK) == 0);
- ASSERT((reg_buf_offset + reg_buf_bytes) <= XFS_BUF_COUNT(bp));
-
- /*
- * The current logged region contains a copy of the
- * current di_next_unlinked field. Extract its value
- * and copy it to the buffer copy.
- */
- logged_nextp = (xfs_agino_t *)
- ((char *)(item->ri_buf[item_index].i_addr) +
- (next_unlinked_offset - reg_buf_offset));
- if (unlikely(*logged_nextp == 0)) {
- xfs_fs_cmn_err(CE_ALERT, mp,
- "bad inode buffer log record (ptr = 0x%p, bp = 0x%p). XFS trying to replay bad (0) inode di_next_unlinked field",
- item, bp);
- XFS_ERROR_REPORT("xlog_recover_do_inode_buf",
- XFS_ERRLEVEL_LOW, mp);
- return XFS_ERROR(EFSCORRUPTED);
- }
-
- buffer_nextp = (xfs_agino_t *)xfs_buf_offset(bp,
- next_unlinked_offset);
- INT_SET(*buffer_nextp, ARCH_CONVERT, *logged_nextp);
- }
-
- return 0;
-}
-
-/*
- * Perform a 'normal' buffer recovery. Each logged region of the
- * buffer should be copied over the corresponding region in the
- * given buffer. The bitmap in the buf log format structure indicates
- * where to place the logged data.
- */
-/*ARGSUSED*/
-STATIC void
-xlog_recover_do_reg_buffer(
- xfs_mount_t *mp,
- xlog_recover_item_t *item,
- xfs_buf_t *bp,
- xfs_buf_log_format_t *buf_f)
-{
- int i;
- int bit;
- int nbits;
- xfs_buf_log_format_v1_t *obuf_f;
- unsigned int *data_map = NULL;
- unsigned int map_size = 0;
- int error;
-
- switch (buf_f->blf_type) {
- case XFS_LI_BUF:
- data_map = buf_f->blf_data_map;
- map_size = buf_f->blf_map_size;
- break;
- case XFS_LI_6_1_BUF:
- case XFS_LI_5_3_BUF:
- obuf_f = (xfs_buf_log_format_v1_t*)buf_f;
- data_map = obuf_f->blf_data_map;
- map_size = obuf_f->blf_map_size;
- break;
- }
- bit = 0;
- i = 1; /* 0 is the buf format structure */
- while (1) {
- bit = xfs_next_bit(data_map, map_size, bit);
- if (bit == -1)
- break;
- nbits = xfs_contig_bits(data_map, map_size, bit);
- ASSERT(nbits > 0);
- ASSERT(item->ri_buf[i].i_addr != 0);
- ASSERT(item->ri_buf[i].i_len % XFS_BLI_CHUNK == 0);
- ASSERT(XFS_BUF_COUNT(bp) >=
- ((uint)bit << XFS_BLI_SHIFT)+(nbits<<XFS_BLI_SHIFT));
-
- /*
- * Do a sanity check if this is a dquot buffer. Just checking
- * the first dquot in the buffer should do. XXXThis is
- * probably a good thing to do for other buf types also.
- */
- error = 0;
- if (buf_f->blf_flags &
- (XFS_BLI_UDQUOT_BUF|XFS_BLI_PDQUOT_BUF|XFS_BLI_GDQUOT_BUF)) {
- error = xfs_qm_dqcheck((xfs_disk_dquot_t *)
- item->ri_buf[i].i_addr,
- -1, 0, XFS_QMOPT_DOWARN,
- "dquot_buf_recover");
- }
- if (!error)
- memcpy(xfs_buf_offset(bp,
- (uint)bit << XFS_BLI_SHIFT), /* dest */
- item->ri_buf[i].i_addr, /* source */
- nbits<<XFS_BLI_SHIFT); /* length */
- i++;
- bit += nbits;
- }
-
- /* Shouldn't be any more regions */
- ASSERT(i == item->ri_total);
-}
-
-/*
- * Do some primitive error checking on ondisk dquot data structures.
- */
-int
-xfs_qm_dqcheck(
- xfs_disk_dquot_t *ddq,
- xfs_dqid_t id,
- uint type, /* used only when IO_dorepair is true */
- uint flags,
- char *str)
-{
- xfs_dqblk_t *d = (xfs_dqblk_t *)ddq;
- int errs = 0;
-
- /*
- * We can encounter an uninitialized dquot buffer for 2 reasons:
- * 1. If we crash while deleting the quotainode(s), and those blks got
- * used for user data. This is because we take the path of regular
- * file deletion; however, the size field of quotainodes is never
- * updated, so all the tricks that we play in itruncate_finish
- * don't quite matter.
- *
- * 2. We don't play the quota buffers when there's a quotaoff logitem.
- * But the allocation will be replayed so we'll end up with an
- * uninitialized quota block.
- *
- * This is all fine; things are still consistent, and we haven't lost
- * any quota information. Just don't complain about bad dquot blks.
- */
- if (be16_to_cpu(ddq->d_magic) != XFS_DQUOT_MAGIC) {
- if (flags & XFS_QMOPT_DOWARN)
- cmn_err(CE_ALERT,
- "%s : XFS dquot ID 0x%x, magic 0x%x != 0x%x",
- str, id, be16_to_cpu(ddq->d_magic), XFS_DQUOT_MAGIC);
- errs++;
- }
- if (ddq->d_version != XFS_DQUOT_VERSION) {
- if (flags & XFS_QMOPT_DOWARN)
- cmn_err(CE_ALERT,
- "%s : XFS dquot ID 0x%x, version 0x%x != 0x%x",
- str, id, ddq->d_version, XFS_DQUOT_VERSION);
- errs++;
- }
-
- if (ddq->d_flags != XFS_DQ_USER &&
- ddq->d_flags != XFS_DQ_PROJ &&
- ddq->d_flags != XFS_DQ_GROUP) {
- if (flags & XFS_QMOPT_DOWARN)
- cmn_err(CE_ALERT,
- "%s : XFS dquot ID 0x%x, unknown flags 0x%x",
- str, id, ddq->d_flags);
- errs++;
- }
-
- if (id != -1 && id != be32_to_cpu(ddq->d_id)) {
- if (flags & XFS_QMOPT_DOWARN)
- cmn_err(CE_ALERT,
- "%s : ondisk-dquot 0x%p, ID mismatch: "
- "0x%x expected, found id 0x%x",
- str, ddq, id, be32_to_cpu(ddq->d_id));
- errs++;
- }
-
- if (!errs && ddq->d_id) {
- if (ddq->d_blk_softlimit &&
- be64_to_cpu(ddq->d_bcount) >=
- be64_to_cpu(ddq->d_blk_softlimit)) {
- if (!ddq->d_btimer) {
- if (flags & XFS_QMOPT_DOWARN)
- cmn_err(CE_ALERT,
- "%s : Dquot ID 0x%x (0x%p) "
- "BLK TIMER NOT STARTED",
- str, (int)be32_to_cpu(ddq->d_id), ddq);
- errs++;
- }
- }
- if (ddq->d_ino_softlimit &&
- be64_to_cpu(ddq->d_icount) >=
- be64_to_cpu(ddq->d_ino_softlimit)) {
- if (!ddq->d_itimer) {
- if (flags & XFS_QMOPT_DOWARN)
- cmn_err(CE_ALERT,
- "%s : Dquot ID 0x%x (0x%p) "
- "INODE TIMER NOT STARTED",
- str, (int)be32_to_cpu(ddq->d_id), ddq);
- errs++;
- }
- }
- if (ddq->d_rtb_softlimit &&
- be64_to_cpu(ddq->d_rtbcount) >=
- be64_to_cpu(ddq->d_rtb_softlimit)) {
- if (!ddq->d_rtbtimer) {
- if (flags & XFS_QMOPT_DOWARN)
- cmn_err(CE_ALERT,
- "%s : Dquot ID 0x%x (0x%p) "
- "RTBLK TIMER NOT STARTED",
- str, (int)be32_to_cpu(ddq->d_id), ddq);
- errs++;
- }
- }
- }
-
- if (!errs || !(flags & XFS_QMOPT_DQREPAIR))
- return errs;
-
- if (flags & XFS_QMOPT_DOWARN)
- cmn_err(CE_NOTE, "Re-initializing dquot ID 0x%x", id);
-
- /*
- * Typically, a repair is only requested by quotacheck.
- */
- ASSERT(id != -1);
- ASSERT(flags & XFS_QMOPT_DQREPAIR);
- memset(d, 0, sizeof(xfs_dqblk_t));
-
- d->dd_diskdq.d_magic = cpu_to_be16(XFS_DQUOT_MAGIC);
- d->dd_diskdq.d_version = XFS_DQUOT_VERSION;
- d->dd_diskdq.d_flags = type;
- d->dd_diskdq.d_id = cpu_to_be32(id);
-
- return errs;
-}
-
-/*
- * Perform a dquot buffer recovery.
- * Simple algorithm: if we have found a QUOTAOFF logitem of the same type
- * (ie. USR or GRP), then just toss this buffer away; don't recover it.
- * Else, treat it as a regular buffer and do recovery.
- */
-STATIC void
-xlog_recover_do_dquot_buffer(
- xfs_mount_t *mp,
- xlog_t *log,
- xlog_recover_item_t *item,
- xfs_buf_t *bp,
- xfs_buf_log_format_t *buf_f)
-{
- uint type;
-
- /*
- * Filesystems are required to send in quota flags at mount time.
- */
- if (mp->m_qflags == 0) {
- return;
- }
-
- type = 0;
- if (buf_f->blf_flags & XFS_BLI_UDQUOT_BUF)
- type |= XFS_DQ_USER;
- if (buf_f->blf_flags & XFS_BLI_PDQUOT_BUF)
- type |= XFS_DQ_PROJ;
- if (buf_f->blf_flags & XFS_BLI_GDQUOT_BUF)
- type |= XFS_DQ_GROUP;
- /*
- * This type of quotas was turned off, so ignore this buffer
- */
- if (log->l_quotaoffs_flag & type)
- return;
-
- xlog_recover_do_reg_buffer(mp, item, bp, buf_f);
-}
-
-/*
- * This routine replays a modification made to a buffer at runtime.
- * There are actually two types of buffer, regular and inode, which
- * are handled differently. Inode buffers are handled differently
- * in that we only recover a specific set of data from them, namely
- * the inode di_next_unlinked fields. This is because all other inode
- * data is actually logged via inode records and any data we replay
- * here which overlaps that may be stale.
- *
- * When meta-data buffers are freed at run time we log a buffer item
- * with the XFS_BLI_CANCEL bit set to indicate that previous copies
- * of the buffer in the log should not be replayed at recovery time.
- * This is so that if the blocks covered by the buffer are reused for
- * file data before we crash we don't end up replaying old, freed
- * meta-data into a user's file.
- *
- * To handle the cancellation of buffer log items, we make two passes
- * over the log during recovery. During the first we build a table of
- * those buffers which have been cancelled, and during the second we
- * only replay those buffers which do not have corresponding cancel
- * records in the table. See xlog_recover_do_buffer_pass[1,2] above
- * for more details on the implementation of the table of cancel records.
- */
-STATIC int
-xlog_recover_do_buffer_trans(
- xlog_t *log,
- xlog_recover_item_t *item,
- int pass)
-{
- xfs_buf_log_format_t *buf_f;
- xfs_buf_log_format_v1_t *obuf_f;
- xfs_mount_t *mp;
- xfs_buf_t *bp;
- int error;
- int cancel;
- xfs_daddr_t blkno;
- int len;
- ushort flags;
-
- buf_f = (xfs_buf_log_format_t *)item->ri_buf[0].i_addr;
-
- if (pass == XLOG_RECOVER_PASS1) {
- /*
- * In this pass we're only looking for buf items
- * with the XFS_BLI_CANCEL bit set.
- */
- xlog_recover_do_buffer_pass1(log, buf_f);
- return 0;
- } else {
- /*
- * In this pass we want to recover all the buffers
- * which have not been cancelled and are not
- * cancellation buffers themselves. The routine
- * we call here will tell us whether or not to
- * continue with the replay of this buffer.
- */
- cancel = xlog_recover_do_buffer_pass2(log, buf_f);
- if (cancel) {
- return 0;
- }
- }
- switch (buf_f->blf_type) {
- case XFS_LI_BUF:
- blkno = buf_f->blf_blkno;
- len = buf_f->blf_len;
- flags = buf_f->blf_flags;
- break;
- case XFS_LI_6_1_BUF:
- case XFS_LI_5_3_BUF:
- obuf_f = (xfs_buf_log_format_v1_t*)buf_f;
- blkno = obuf_f->blf_blkno;
- len = obuf_f->blf_len;
- flags = obuf_f->blf_flags;
- break;
- default:
- xfs_fs_cmn_err(CE_ALERT, log->l_mp,
- "xfs_log_recover: unknown buffer type 0x%x, logdev %s",
- buf_f->blf_type, log->l_mp->m_logname ?
- log->l_mp->m_logname : "internal");
- XFS_ERROR_REPORT("xlog_recover_do_buffer_trans",
- XFS_ERRLEVEL_LOW, log->l_mp);
- return XFS_ERROR(EFSCORRUPTED);
- }
-
- mp = log->l_mp;
- if (flags & XFS_BLI_INODE_BUF) {
- bp = xfs_buf_read_flags(mp->m_ddev_targp, blkno, len,
- XFS_BUF_LOCK);
- } else {
- bp = xfs_buf_read(mp->m_ddev_targp, blkno, len, 0);
- }
- if (XFS_BUF_ISERROR(bp)) {
- xfs_ioerror_alert("xlog_recover_do..(read#1)", log->l_mp,
- bp, blkno);
- error = XFS_BUF_GETERROR(bp);
- xfs_buf_relse(bp);
- return error;
- }
-
- error = 0;
- if (flags & XFS_BLI_INODE_BUF) {
- error = xlog_recover_do_inode_buffer(mp, item, bp, buf_f);
- } else if (flags &
- (XFS_BLI_UDQUOT_BUF|XFS_BLI_PDQUOT_BUF|XFS_BLI_GDQUOT_BUF)) {
- xlog_recover_do_dquot_buffer(mp, log, item, bp, buf_f);
- } else {
- xlog_recover_do_reg_buffer(mp, item, bp, buf_f);
- }
- if (error)
- return XFS_ERROR(error);
-
- /*
- * Perform delayed write on the buffer. Asynchronous writes will be
- * slower when taking into account all the buffers to be flushed.
- *
- * Also make sure that only inode buffers with good sizes stay in
- * the buffer cache. The kernel moves inodes in buffers of 1 block
- * or XFS_INODE_CLUSTER_SIZE bytes, whichever is bigger. The inode
- * buffers in the log can be a different size if the log was generated
- * by an older kernel using unclustered inode buffers or a newer kernel
- * running with a different inode cluster size. Regardless, if the
- * the inode buffer size isn't MAX(blocksize, XFS_INODE_CLUSTER_SIZE)
- * for *our* value of XFS_INODE_CLUSTER_SIZE, then we need to keep
- * the buffer out of the buffer cache so that the buffer won't
- * overlap with future reads of those inodes.
- */
- if (XFS_DINODE_MAGIC ==
- INT_GET(*((__uint16_t *)(xfs_buf_offset(bp, 0))), ARCH_CONVERT) &&
- (XFS_BUF_COUNT(bp) != MAX(log->l_mp->m_sb.sb_blocksize,
- (__uint32_t)XFS_INODE_CLUSTER_SIZE(log->l_mp)))) {
- XFS_BUF_STALE(bp);
- error = xfs_bwrite(mp, bp);
- } else {
- ASSERT(XFS_BUF_FSPRIVATE(bp, void *) == NULL ||
- XFS_BUF_FSPRIVATE(bp, xfs_mount_t *) == mp);
- XFS_BUF_SET_FSPRIVATE(bp, mp);
- XFS_BUF_SET_IODONE_FUNC(bp, xlog_recover_iodone);
- xfs_bdwrite(mp, bp);
- }
-
- return (error);
-}
-
-STATIC int
-xlog_recover_do_inode_trans(
- xlog_t *log,
- xlog_recover_item_t *item,
- int pass)
-{
- xfs_inode_log_format_t *in_f;
- xfs_mount_t *mp;
- xfs_buf_t *bp;
- xfs_imap_t imap;
- xfs_dinode_t *dip;
- xfs_ino_t ino;
- int len;
- xfs_caddr_t src;
- xfs_caddr_t dest;
- int error;
- int attr_index;
- uint fields;
- xfs_dinode_core_t *dicp;
-
- if (pass == XLOG_RECOVER_PASS1) {
- return 0;
- }
-
- in_f = (xfs_inode_log_format_t *)item->ri_buf[0].i_addr;
- ino = in_f->ilf_ino;
- mp = log->l_mp;
- if (ITEM_TYPE(item) == XFS_LI_INODE) {
- imap.im_blkno = (xfs_daddr_t)in_f->ilf_blkno;
- imap.im_len = in_f->ilf_len;
- imap.im_boffset = in_f->ilf_boffset;
- } else {
- /*
- * It's an old inode format record. We don't know where
- * its cluster is located on disk, and we can't allow
- * xfs_imap() to figure it out because the inode btrees
- * are not ready to be used. Therefore do not pass the
- * XFS_IMAP_LOOKUP flag to xfs_imap(). This will give
- * us only the single block in which the inode lives
- * rather than its cluster, so we must make sure to
- * invalidate the buffer when we write it out below.
- */
- imap.im_blkno = 0;
- xfs_imap(log->l_mp, NULL, ino, &imap, 0);
- }
-
- /*
- * Inode buffers can be freed, look out for it,
- * and do not replay the inode.
- */
- if (xlog_check_buffer_cancelled(log, imap.im_blkno, imap.im_len, 0))
- return 0;
-
- bp = xfs_buf_read_flags(mp->m_ddev_targp, imap.im_blkno, imap.im_len,
- XFS_BUF_LOCK);
- if (XFS_BUF_ISERROR(bp)) {
- xfs_ioerror_alert("xlog_recover_do..(read#2)", mp,
- bp, imap.im_blkno);
- error = XFS_BUF_GETERROR(bp);
- xfs_buf_relse(bp);
- return error;
- }
- error = 0;
- ASSERT(in_f->ilf_fields & XFS_ILOG_CORE);
- dip = (xfs_dinode_t *)xfs_buf_offset(bp, imap.im_boffset);
-
- /*
- * Make sure the place we're flushing out to really looks
- * like an inode!
- */
- if (unlikely(INT_GET(dip->di_core.di_magic, ARCH_CONVERT) != XFS_DINODE_MAGIC)) {
- xfs_buf_relse(bp);
- xfs_fs_cmn_err(CE_ALERT, mp,
- "xfs_inode_recover: Bad inode magic number, dino ptr = 0x%p, dino bp = 0x%p, ino = %Ld",
- dip, bp, ino);
- XFS_ERROR_REPORT("xlog_recover_do_inode_trans(1)",
- XFS_ERRLEVEL_LOW, mp);
- return XFS_ERROR(EFSCORRUPTED);
- }
- dicp = (xfs_dinode_core_t*)(item->ri_buf[1].i_addr);
- if (unlikely(dicp->di_magic != XFS_DINODE_MAGIC)) {
- xfs_buf_relse(bp);
- xfs_fs_cmn_err(CE_ALERT, mp,
- "xfs_inode_recover: Bad inode log record, rec ptr 0x%p, ino %Ld",
- item, ino);
- XFS_ERROR_REPORT("xlog_recover_do_inode_trans(2)",
- XFS_ERRLEVEL_LOW, mp);
- return XFS_ERROR(EFSCORRUPTED);
- }
-
- /* Skip replay when the on disk inode is newer than the log one */
- if (dicp->di_flushiter <
- INT_GET(dip->di_core.di_flushiter, ARCH_CONVERT)) {
- /*
- * Deal with the wrap case, DI_MAX_FLUSH is less
- * than smaller numbers
- */
- if ((INT_GET(dip->di_core.di_flushiter, ARCH_CONVERT)
- == DI_MAX_FLUSH) &&
- (dicp->di_flushiter < (DI_MAX_FLUSH>>1))) {
- /* do nothing */
- } else {
- xfs_buf_relse(bp);
- return 0;
- }
- }
- /* Take the opportunity to reset the flush iteration count */
- dicp->di_flushiter = 0;
-
- if (unlikely((dicp->di_mode & S_IFMT) == S_IFREG)) {
- if ((dicp->di_format != XFS_DINODE_FMT_EXTENTS) &&
- (dicp->di_format != XFS_DINODE_FMT_BTREE)) {
- XFS_CORRUPTION_ERROR("xlog_recover_do_inode_trans(3)",
- XFS_ERRLEVEL_LOW, mp, dicp);
- xfs_buf_relse(bp);
- xfs_fs_cmn_err(CE_ALERT, mp,
- "xfs_inode_recover: Bad regular inode log record, rec ptr 0x%p, ino ptr = 0x%p, ino bp = 0x%p, ino %Ld",
- item, dip, bp, ino);
- return XFS_ERROR(EFSCORRUPTED);
- }
- } else if (unlikely((dicp->di_mode & S_IFMT) == S_IFDIR)) {
- if ((dicp->di_format != XFS_DINODE_FMT_EXTENTS) &&
- (dicp->di_format != XFS_DINODE_FMT_BTREE) &&
- (dicp->di_format != XFS_DINODE_FMT_LOCAL)) {
- XFS_CORRUPTION_ERROR("xlog_recover_do_inode_trans(4)",
- XFS_ERRLEVEL_LOW, mp, dicp);
- xfs_buf_relse(bp);
- xfs_fs_cmn_err(CE_ALERT, mp,
- "xfs_inode_recover: Bad dir inode log record, rec ptr 0x%p, ino ptr = 0x%p, ino bp = 0x%p, ino %Ld",
- item, dip, bp, ino);
- return XFS_ERROR(EFSCORRUPTED);
- }
- }
- if (unlikely(dicp->di_nextents + dicp->di_anextents > dicp->di_nblocks)){
- XFS_CORRUPTION_ERROR("xlog_recover_do_inode_trans(5)",
- XFS_ERRLEVEL_LOW, mp, dicp);
- xfs_buf_relse(bp);
- xfs_fs_cmn_err(CE_ALERT, mp,
- "xfs_inode_recover: Bad inode log record, rec ptr 0x%p, dino ptr 0x%p, dino bp 0x%p, ino %Ld, total extents = %d, nblocks = %Ld",
- item, dip, bp, ino,
- dicp->di_nextents + dicp->di_anextents,
- dicp->di_nblocks);
- return XFS_ERROR(EFSCORRUPTED);
- }
- if (unlikely(dicp->di_forkoff > mp->m_sb.sb_inodesize)) {
- XFS_CORRUPTION_ERROR("xlog_recover_do_inode_trans(6)",
- XFS_ERRLEVEL_LOW, mp, dicp);
- xfs_buf_relse(bp);
- xfs_fs_cmn_err(CE_ALERT, mp,
- "xfs_inode_recover: Bad inode log rec ptr 0x%p, dino ptr 0x%p, dino bp 0x%p, ino %Ld, forkoff 0x%x",
- item, dip, bp, ino, dicp->di_forkoff);
- return XFS_ERROR(EFSCORRUPTED);
- }
- if (unlikely(item->ri_buf[1].i_len > sizeof(xfs_dinode_core_t))) {
- XFS_CORRUPTION_ERROR("xlog_recover_do_inode_trans(7)",
- XFS_ERRLEVEL_LOW, mp, dicp);
- xfs_buf_relse(bp);
- xfs_fs_cmn_err(CE_ALERT, mp,
- "xfs_inode_recover: Bad inode log record length %d, rec ptr 0x%p",
- item->ri_buf[1].i_len, item);
- return XFS_ERROR(EFSCORRUPTED);
- }
-
- /* The core is in in-core format */
- xfs_xlate_dinode_core((xfs_caddr_t)&dip->di_core,
- (xfs_dinode_core_t*)item->ri_buf[1].i_addr, -1);
-
- /* the rest is in on-disk format */
- if (item->ri_buf[1].i_len > sizeof(xfs_dinode_core_t)) {
- memcpy((xfs_caddr_t) dip + sizeof(xfs_dinode_core_t),
- item->ri_buf[1].i_addr + sizeof(xfs_dinode_core_t),
- item->ri_buf[1].i_len - sizeof(xfs_dinode_core_t));
- }
-
- fields = in_f->ilf_fields;
- switch (fields & (XFS_ILOG_DEV | XFS_ILOG_UUID)) {
- case XFS_ILOG_DEV:
- INT_SET(dip->di_u.di_dev, ARCH_CONVERT, in_f->ilf_u.ilfu_rdev);
-
- break;
- case XFS_ILOG_UUID:
- dip->di_u.di_muuid = in_f->ilf_u.ilfu_uuid;
- break;
- }
-
- if (in_f->ilf_size == 2)
- goto write_inode_buffer;
- len = item->ri_buf[2].i_len;
- src = item->ri_buf[2].i_addr;
- ASSERT(in_f->ilf_size <= 4);
- ASSERT((in_f->ilf_size == 3) || (fields & XFS_ILOG_AFORK));
- ASSERT(!(fields & XFS_ILOG_DFORK) ||
- (len == in_f->ilf_dsize));
-
- switch (fields & XFS_ILOG_DFORK) {
- case XFS_ILOG_DDATA:
- case XFS_ILOG_DEXT:
- memcpy(&dip->di_u, src, len);
- break;
-
- case XFS_ILOG_DBROOT:
- xfs_bmbt_to_bmdr((xfs_bmbt_block_t *)src, len,
- &(dip->di_u.di_bmbt),
- XFS_DFORK_DSIZE(dip, mp));
- break;
-
- default:
- /*
- * There are no data fork flags set.
- */
- ASSERT((fields & XFS_ILOG_DFORK) == 0);
- break;
- }
-
- /*
- * If we logged any attribute data, recover it. There may or
- * may not have been any other non-core data logged in this
- * transaction.
- */
- if (in_f->ilf_fields & XFS_ILOG_AFORK) {
- if (in_f->ilf_fields & XFS_ILOG_DFORK) {
- attr_index = 3;
- } else {
- attr_index = 2;
- }
- len = item->ri_buf[attr_index].i_len;
- src = item->ri_buf[attr_index].i_addr;
- ASSERT(len == in_f->ilf_asize);
-
- switch (in_f->ilf_fields & XFS_ILOG_AFORK) {
- case XFS_ILOG_ADATA:
- case XFS_ILOG_AEXT:
- dest = XFS_DFORK_APTR(dip);
- ASSERT(len <= XFS_DFORK_ASIZE(dip, mp));
- memcpy(dest, src, len);
- break;
-
- case XFS_ILOG_ABROOT:
- dest = XFS_DFORK_APTR(dip);
- xfs_bmbt_to_bmdr((xfs_bmbt_block_t *)src, len,
- (xfs_bmdr_block_t*)dest,
- XFS_DFORK_ASIZE(dip, mp));
- break;
-
- default:
- xlog_warn("XFS: xlog_recover_do_inode_trans: Invalid flag");
- ASSERT(0);
- xfs_buf_relse(bp);
- return XFS_ERROR(EIO);
- }
- }
-
-write_inode_buffer:
- if (ITEM_TYPE(item) == XFS_LI_INODE) {
- ASSERT(XFS_BUF_FSPRIVATE(bp, void *) == NULL ||
- XFS_BUF_FSPRIVATE(bp, xfs_mount_t *) == mp);
- XFS_BUF_SET_FSPRIVATE(bp, mp);
- XFS_BUF_SET_IODONE_FUNC(bp, xlog_recover_iodone);
- xfs_bdwrite(mp, bp);
- } else {
- XFS_BUF_STALE(bp);
- error = xfs_bwrite(mp, bp);
- }
-
- return (error);
-}
-
-/*
- * Recover QUOTAOFF records. We simply make a note of it in the xlog_t
- * structure, so that we know not to do any dquot item or dquot buffer recovery,
- * of that type.
- */
-STATIC int
-xlog_recover_do_quotaoff_trans(
- xlog_t *log,
- xlog_recover_item_t *item,
- int pass)
-{
- xfs_qoff_logformat_t *qoff_f;
-
- if (pass == XLOG_RECOVER_PASS2) {
- return (0);
- }
-
- qoff_f = (xfs_qoff_logformat_t *)item->ri_buf[0].i_addr;
- ASSERT(qoff_f);
-
- /*
- * The logitem format's flag tells us if this was user quotaoff,
- * group/project quotaoff or both.
- */
- if (qoff_f->qf_flags & XFS_UQUOTA_ACCT)
- log->l_quotaoffs_flag |= XFS_DQ_USER;
- if (qoff_f->qf_flags & XFS_PQUOTA_ACCT)
- log->l_quotaoffs_flag |= XFS_DQ_PROJ;
- if (qoff_f->qf_flags & XFS_GQUOTA_ACCT)
- log->l_quotaoffs_flag |= XFS_DQ_GROUP;
-
- return (0);
-}
-
-/*
- * Recover a dquot record
- */
-STATIC int
-xlog_recover_do_dquot_trans(
- xlog_t *log,
- xlog_recover_item_t *item,
- int pass)
-{
- xfs_mount_t *mp;
- xfs_buf_t *bp;
- struct xfs_disk_dquot *ddq, *recddq;
- int error;
- xfs_dq_logformat_t *dq_f;
- uint type;
-
- if (pass == XLOG_RECOVER_PASS1) {
- return 0;
- }
- mp = log->l_mp;
-
- /*
- * Filesystems are required to send in quota flags at mount time.
- */
- if (mp->m_qflags == 0)
- return (0);
-
- recddq = (xfs_disk_dquot_t *)item->ri_buf[1].i_addr;
- ASSERT(recddq);
- /*
- * This type of quotas was turned off, so ignore this record.
- */
- type = INT_GET(recddq->d_flags, ARCH_CONVERT) &
- (XFS_DQ_USER | XFS_DQ_PROJ | XFS_DQ_GROUP);
- ASSERT(type);
- if (log->l_quotaoffs_flag & type)
- return (0);
-
- /*
- * At this point we know that quota was _not_ turned off.
- * Since the mount flags are not indicating to us otherwise, this
- * must mean that quota is on, and the dquot needs to be replayed.
- * Remember that we may not have fully recovered the superblock yet,
- * so we can't do the usual trick of looking at the SB quota bits.
- *
- * The other possibility, of course, is that the quota subsystem was
- * removed since the last mount - ENOSYS.
- */
- dq_f = (xfs_dq_logformat_t *)item->ri_buf[0].i_addr;
- ASSERT(dq_f);
- if ((error = xfs_qm_dqcheck(recddq,
- dq_f->qlf_id,
- 0, XFS_QMOPT_DOWARN,
- "xlog_recover_do_dquot_trans (log copy)"))) {
- return XFS_ERROR(EIO);
- }
- ASSERT(dq_f->qlf_len == 1);
-
- error = xfs_read_buf(mp, mp->m_ddev_targp,
- dq_f->qlf_blkno,
- XFS_FSB_TO_BB(mp, dq_f->qlf_len),
- 0, &bp);
- if (error) {
- xfs_ioerror_alert("xlog_recover_do..(read#3)", mp,
- bp, dq_f->qlf_blkno);
- return error;
- }
- ASSERT(bp);
- ddq = (xfs_disk_dquot_t *)xfs_buf_offset(bp, dq_f->qlf_boffset);
-
- /*
- * At least the magic num portion should be on disk because this
- * was among a chunk of dquots created earlier, and we did some
- * minimal initialization then.
- */
- if (xfs_qm_dqcheck(ddq, dq_f->qlf_id, 0, XFS_QMOPT_DOWARN,
- "xlog_recover_do_dquot_trans")) {
- xfs_buf_relse(bp);
- return XFS_ERROR(EIO);
- }
-
- memcpy(ddq, recddq, item->ri_buf[1].i_len);
-
- ASSERT(dq_f->qlf_size == 2);
- ASSERT(XFS_BUF_FSPRIVATE(bp, void *) == NULL ||
- XFS_BUF_FSPRIVATE(bp, xfs_mount_t *) == mp);
- XFS_BUF_SET_FSPRIVATE(bp, mp);
- XFS_BUF_SET_IODONE_FUNC(bp, xlog_recover_iodone);
- xfs_bdwrite(mp, bp);
-
- return (0);
-}
-
-/*
- * This routine is called to create an in-core extent free intent
- * item from the efi format structure which was logged on disk.
- * It allocates an in-core efi, copies the extents from the format
- * structure into it, and adds the efi to the AIL with the given
- * LSN.
- */
-STATIC void
-xlog_recover_do_efi_trans(
- xlog_t *log,
- xlog_recover_item_t *item,
- xfs_lsn_t lsn,
- int pass)
-{
- xfs_mount_t *mp;
- xfs_efi_log_item_t *efip;
- xfs_efi_log_format_t *efi_formatp;
- SPLDECL(s);
-
- if (pass == XLOG_RECOVER_PASS1) {
- return;
- }
-
- efi_formatp = (xfs_efi_log_format_t *)item->ri_buf[0].i_addr;
- ASSERT(item->ri_buf[0].i_len ==
- (sizeof(xfs_efi_log_format_t) +
- ((efi_formatp->efi_nextents - 1) * sizeof(xfs_extent_t))));
-
- mp = log->l_mp;
- efip = xfs_efi_init(mp, efi_formatp->efi_nextents);
- memcpy((char *)&(efip->efi_format), (char *)efi_formatp,
- sizeof(xfs_efi_log_format_t) +
- ((efi_formatp->efi_nextents - 1) * sizeof(xfs_extent_t)));
- efip->efi_next_extent = efi_formatp->efi_nextents;
- efip->efi_flags |= XFS_EFI_COMMITTED;
-
- AIL_LOCK(mp,s);
- /*
- * xfs_trans_update_ail() drops the AIL lock.
- */
- xfs_trans_update_ail(mp, (xfs_log_item_t *)efip, lsn, s);
-}
-
-
-/*
- * This routine is called when an efd format structure is found in
- * a committed transaction in the log. It's purpose is to cancel
- * the corresponding efi if it was still in the log. To do this
- * it searches the AIL for the efi with an id equal to that in the
- * efd format structure. If we find it, we remove the efi from the
- * AIL and free it.
- */
-STATIC void
-xlog_recover_do_efd_trans(
- xlog_t *log,
- xlog_recover_item_t *item,
- int pass)
-{
- xfs_mount_t *mp;
- xfs_efd_log_format_t *efd_formatp;
- xfs_efi_log_item_t *efip = NULL;
- xfs_log_item_t *lip;
- int gen;
- __uint64_t efi_id;
- SPLDECL(s);
-
- if (pass == XLOG_RECOVER_PASS1) {
- return;
- }
-
- efd_formatp = (xfs_efd_log_format_t *)item->ri_buf[0].i_addr;
- ASSERT(item->ri_buf[0].i_len ==
- (sizeof(xfs_efd_log_format_t) +
- ((efd_formatp->efd_nextents - 1) * sizeof(xfs_extent_t))));
- efi_id = efd_formatp->efd_efi_id;
-
- /*
- * Search for the efi with the id in the efd format structure
- * in the AIL.
- */
- mp = log->l_mp;
- AIL_LOCK(mp,s);
- lip = xfs_trans_first_ail(mp, &gen);
- while (lip != NULL) {
- if (lip->li_type == XFS_LI_EFI) {
- efip = (xfs_efi_log_item_t *)lip;
- if (efip->efi_format.efi_id == efi_id) {
- /*
- * xfs_trans_delete_ail() drops the
- * AIL lock.
- */
- xfs_trans_delete_ail(mp, lip, s);
- break;
- }
- }
- lip = xfs_trans_next_ail(mp, lip, &gen, NULL);
- }
-
- /*
- * If we found it, then free it up. If it wasn't there, it
- * must have been overwritten in the log. Oh well.
- */
- if (lip != NULL) {
- xfs_efi_item_free(efip);
- } else {
- AIL_UNLOCK(mp, s);
- }
-}
-
-/*
- * Perform the transaction
- *
- * If the transaction modifies a buffer or inode, do it now. Otherwise,
- * EFIs and EFDs get queued up by adding entries into the AIL for them.
- */
-STATIC int
-xlog_recover_do_trans(
- xlog_t *log,
- xlog_recover_t *trans,
- int pass)
-{
- int error = 0;
- xlog_recover_item_t *item, *first_item;
-
- if ((error = xlog_recover_reorder_trans(log, trans)))
- return error;
- first_item = item = trans->r_itemq;
- do {
- /*
- * we don't need to worry about the block number being
- * truncated in > 1 TB buffers because in user-land,
- * we're now n32 or 64-bit so xfs_daddr_t is 64-bits so
- * the blknos will get through the user-mode buffer
- * cache properly. The only bad case is o32 kernels
- * where xfs_daddr_t is 32-bits but mount will warn us
- * off a > 1 TB filesystem before we get here.
- */
- if ((ITEM_TYPE(item) == XFS_LI_BUF) ||
- (ITEM_TYPE(item) == XFS_LI_6_1_BUF) ||
- (ITEM_TYPE(item) == XFS_LI_5_3_BUF)) {
- if ((error = xlog_recover_do_buffer_trans(log, item,
- pass)))
- break;
- } else if ((ITEM_TYPE(item) == XFS_LI_INODE) ||
- (ITEM_TYPE(item) == XFS_LI_6_1_INODE) ||
- (ITEM_TYPE(item) == XFS_LI_5_3_INODE)) {
- if ((error = xlog_recover_do_inode_trans(log, item,
- pass)))
- break;
- } else if (ITEM_TYPE(item) == XFS_LI_EFI) {
- xlog_recover_do_efi_trans(log, item, trans->r_lsn,
- pass);
- } else if (ITEM_TYPE(item) == XFS_LI_EFD) {
- xlog_recover_do_efd_trans(log, item, pass);
- } else if (ITEM_TYPE(item) == XFS_LI_DQUOT) {
- if ((error = xlog_recover_do_dquot_trans(log, item,
- pass)))
- break;
- } else if ((ITEM_TYPE(item) == XFS_LI_QUOTAOFF)) {
- if ((error = xlog_recover_do_quotaoff_trans(log, item,
- pass)))
- break;
- } else {
- xlog_warn("XFS: xlog_recover_do_trans");
- ASSERT(0);
- error = XFS_ERROR(EIO);
- break;
- }
- item = item->ri_next;
- } while (first_item != item);
-
- return error;
-}
-
-/*
- * Free up any resources allocated by the transaction
- *
- * Remember that EFIs, EFDs, and IUNLINKs are handled later.
- */
-STATIC void
-xlog_recover_free_trans(
- xlog_recover_t *trans)
-{
- xlog_recover_item_t *first_item, *item, *free_item;
- int i;
-
- item = first_item = trans->r_itemq;
- do {
- free_item = item;
- item = item->ri_next;
- /* Free the regions in the item. */
- for (i = 0; i < free_item->ri_cnt; i++) {
- kmem_free(free_item->ri_buf[i].i_addr,
- free_item->ri_buf[i].i_len);
- }
- /* Free the item itself */
- kmem_free(free_item->ri_buf,
- (free_item->ri_total * sizeof(xfs_log_iovec_t)));
- kmem_free(free_item, sizeof(xlog_recover_item_t));
- } while (first_item != item);
- /* Free the transaction recover structure */
- kmem_free(trans, sizeof(xlog_recover_t));
-}
-
-STATIC int
-xlog_recover_commit_trans(
- xlog_t *log,
- xlog_recover_t **q,
- xlog_recover_t *trans,
- int pass)
-{
- int error;
-
- if ((error = xlog_recover_unlink_tid(q, trans)))
- return error;
- if ((error = xlog_recover_do_trans(log, trans, pass)))
- return error;
- xlog_recover_free_trans(trans); /* no error */
- return 0;
-}
-
-STATIC int
-xlog_recover_unmount_trans(
- xlog_recover_t *trans)
-{
- /* Do nothing now */
- xlog_warn("XFS: xlog_recover_unmount_trans: Unmount LR");
- return 0;
-}
-
-/*
- * There are two valid states of the r_state field. 0 indicates that the
- * transaction structure is in a normal state. We have either seen the
- * start of the transaction or the last operation we added was not a partial
- * operation. If the last operation we added to the transaction was a
- * partial operation, we need to mark r_state with XLOG_WAS_CONT_TRANS.
- *
- * NOTE: skip LRs with 0 data length.
- */
-STATIC int
-xlog_recover_process_data(
- xlog_t *log,
- xlog_recover_t *rhash[],
- xlog_rec_header_t *rhead,
- xfs_caddr_t dp,
- int pass)
-{
- xfs_caddr_t lp;
- int num_logops;
- xlog_op_header_t *ohead;
- xlog_recover_t *trans;
- xlog_tid_t tid;
- int error;
- unsigned long hash;
- uint flags;
-
- lp = dp + INT_GET(rhead->h_len, ARCH_CONVERT);
- num_logops = INT_GET(rhead->h_num_logops, ARCH_CONVERT);
-
- /* check the log format matches our own - else we can't recover */
- if (xlog_header_check_recover(log->l_mp, rhead))
- return (XFS_ERROR(EIO));
-
- while ((dp < lp) && num_logops) {
- ASSERT(dp + sizeof(xlog_op_header_t) <= lp);
- ohead = (xlog_op_header_t *)dp;
- dp += sizeof(xlog_op_header_t);
- if (ohead->oh_clientid != XFS_TRANSACTION &&
- ohead->oh_clientid != XFS_LOG) {
- xlog_warn(
- "XFS: xlog_recover_process_data: bad clientid");
- ASSERT(0);
- return (XFS_ERROR(EIO));
- }
- tid = INT_GET(ohead->oh_tid, ARCH_CONVERT);
- hash = XLOG_RHASH(tid);
- trans = xlog_recover_find_tid(rhash[hash], tid);
- if (trans == NULL) { /* not found; add new tid */
- if (ohead->oh_flags & XLOG_START_TRANS)
- xlog_recover_new_tid(&rhash[hash], tid,
- INT_GET(rhead->h_lsn, ARCH_CONVERT));
- } else {
- ASSERT(dp+INT_GET(ohead->oh_len, ARCH_CONVERT) <= lp);
- flags = ohead->oh_flags & ~XLOG_END_TRANS;
- if (flags & XLOG_WAS_CONT_TRANS)
- flags &= ~XLOG_CONTINUE_TRANS;
- switch (flags) {
- case XLOG_COMMIT_TRANS:
- error = xlog_recover_commit_trans(log,
- &rhash[hash], trans, pass);
- break;
- case XLOG_UNMOUNT_TRANS:
- error = xlog_recover_unmount_trans(trans);
- break;
- case XLOG_WAS_CONT_TRANS:
- error = xlog_recover_add_to_cont_trans(trans,
- dp, INT_GET(ohead->oh_len,
- ARCH_CONVERT));
- break;
- case XLOG_START_TRANS:
- xlog_warn(
- "XFS: xlog_recover_process_data: bad transaction");
- ASSERT(0);
- error = XFS_ERROR(EIO);
- break;
- case 0:
- case XLOG_CONTINUE_TRANS:
- error = xlog_recover_add_to_trans(trans,
- dp, INT_GET(ohead->oh_len,
- ARCH_CONVERT));
- break;
- default:
- xlog_warn(
- "XFS: xlog_recover_process_data: bad flag");
- ASSERT(0);
- error = XFS_ERROR(EIO);
- break;
- }
- if (error)
- return error;
- }
- dp += INT_GET(ohead->oh_len, ARCH_CONVERT);
- num_logops--;
- }
- return 0;
-}
-
-/*
- * Process an extent free intent item that was recovered from
- * the log. We need to free the extents that it describes.
- */
-STATIC void
-xlog_recover_process_efi(
- xfs_mount_t *mp,
- xfs_efi_log_item_t *efip)
-{
- xfs_efd_log_item_t *efdp;
- xfs_trans_t *tp;
- int i;
- xfs_extent_t *extp;
- xfs_fsblock_t startblock_fsb;
-
- ASSERT(!(efip->efi_flags & XFS_EFI_RECOVERED));
-
- /*
- * First check the validity of the extents described by the
- * EFI. If any are bad, then assume that all are bad and
- * just toss the EFI.
- */
- for (i = 0; i < efip->efi_format.efi_nextents; i++) {
- extp = &(efip->efi_format.efi_extents[i]);
- startblock_fsb = XFS_BB_TO_FSB(mp,
- XFS_FSB_TO_DADDR(mp, extp->ext_start));
- if ((startblock_fsb == 0) ||
- (extp->ext_len == 0) ||
- (startblock_fsb >= mp->m_sb.sb_dblocks) ||
- (extp->ext_len >= mp->m_sb.sb_agblocks)) {
- /*
- * This will pull the EFI from the AIL and
- * free the memory associated with it.
- */
- xfs_efi_release(efip, efip->efi_format.efi_nextents);
- return;
- }
- }
-
- tp = xfs_trans_alloc(mp, 0);
- xfs_trans_reserve(tp, 0, XFS_ITRUNCATE_LOG_RES(mp), 0, 0, 0);
- efdp = xfs_trans_get_efd(tp, efip, efip->efi_format.efi_nextents);
-
- for (i = 0; i < efip->efi_format.efi_nextents; i++) {
- extp = &(efip->efi_format.efi_extents[i]);
- xfs_free_extent(tp, extp->ext_start, extp->ext_len);
- xfs_trans_log_efd_extent(tp, efdp, extp->ext_start,
- extp->ext_len);
- }
-
- efip->efi_flags |= XFS_EFI_RECOVERED;
- xfs_trans_commit(tp, 0, NULL);
-}
-
-/*
- * Verify that once we've encountered something other than an EFI
- * in the AIL that there are no more EFIs in the AIL.
- */
-#if defined(DEBUG)
-STATIC void
-xlog_recover_check_ail(
- xfs_mount_t *mp,
- xfs_log_item_t *lip,
- int gen)
-{
- int orig_gen = gen;
-
- do {
- ASSERT(lip->li_type != XFS_LI_EFI);
- lip = xfs_trans_next_ail(mp, lip, &gen, NULL);
- /*
- * The check will be bogus if we restart from the
- * beginning of the AIL, so ASSERT that we don't.
- * We never should since we're holding the AIL lock
- * the entire time.
- */
- ASSERT(gen == orig_gen);
- } while (lip != NULL);
-}
-#endif /* DEBUG */
-
-/*
- * When this is called, all of the EFIs which did not have
- * corresponding EFDs should be in the AIL. What we do now
- * is free the extents associated with each one.
- *
- * Since we process the EFIs in normal transactions, they
- * will be removed at some point after the commit. This prevents
- * us from just walking down the list processing each one.
- * We'll use a flag in the EFI to skip those that we've already
- * processed and use the AIL iteration mechanism's generation
- * count to try to speed this up at least a bit.
- *
- * When we start, we know that the EFIs are the only things in
- * the AIL. As we process them, however, other items are added
- * to the AIL. Since everything added to the AIL must come after
- * everything already in the AIL, we stop processing as soon as
- * we see something other than an EFI in the AIL.
- */
-STATIC void
-xlog_recover_process_efis(
- xlog_t *log)
-{
- xfs_log_item_t *lip;
- xfs_efi_log_item_t *efip;
- int gen;
- xfs_mount_t *mp;
- SPLDECL(s);
-
- mp = log->l_mp;
- AIL_LOCK(mp,s);
-
- lip = xfs_trans_first_ail(mp, &gen);
- while (lip != NULL) {
- /*
- * We're done when we see something other than an EFI.
- */
- if (lip->li_type != XFS_LI_EFI) {
- xlog_recover_check_ail(mp, lip, gen);
- break;
- }
-
- /*
- * Skip EFIs that we've already processed.
- */
- efip = (xfs_efi_log_item_t *)lip;
- if (efip->efi_flags & XFS_EFI_RECOVERED) {
- lip = xfs_trans_next_ail(mp, lip, &gen, NULL);
- continue;
- }
-
- AIL_UNLOCK(mp, s);
- xlog_recover_process_efi(mp, efip);
- AIL_LOCK(mp,s);
- lip = xfs_trans_next_ail(mp, lip, &gen, NULL);
- }
- AIL_UNLOCK(mp, s);
-}
-
-/*
- * This routine performs a transaction to null out a bad inode pointer
- * in an agi unlinked inode hash bucket.
- */
-STATIC void
-xlog_recover_clear_agi_bucket(
- xfs_mount_t *mp,
- xfs_agnumber_t agno,
- int bucket)
-{
- xfs_trans_t *tp;
- xfs_agi_t *agi;
- xfs_buf_t *agibp;
- int offset;
- int error;
-
- tp = xfs_trans_alloc(mp, XFS_TRANS_CLEAR_AGI_BUCKET);
- xfs_trans_reserve(tp, 0, XFS_CLEAR_AGI_BUCKET_LOG_RES(mp), 0, 0, 0);
-
- error = xfs_trans_read_buf(mp, tp, mp->m_ddev_targp,
- XFS_AG_DADDR(mp, agno, XFS_AGI_DADDR(mp)),
- XFS_FSS_TO_BB(mp, 1), 0, &agibp);
- if (error) {
- xfs_trans_cancel(tp, XFS_TRANS_ABORT);
- return;
- }
-
- agi = XFS_BUF_TO_AGI(agibp);
- if (be32_to_cpu(agi->agi_magicnum) != XFS_AGI_MAGIC) {
- xfs_trans_cancel(tp, XFS_TRANS_ABORT);
- return;
- }
-
- agi->agi_unlinked[bucket] = cpu_to_be32(NULLAGINO);
- offset = offsetof(xfs_agi_t, agi_unlinked) +
- (sizeof(xfs_agino_t) * bucket);
- xfs_trans_log_buf(tp, agibp, offset,
- (offset + sizeof(xfs_agino_t) - 1));
-
- (void) xfs_trans_commit(tp, 0, NULL);
-}
-
-/*
- * xlog_iunlink_recover
- *
- * This is called during recovery to process any inodes which
- * we unlinked but not freed when the system crashed. These
- * inodes will be on the lists in the AGI blocks. What we do
- * here is scan all the AGIs and fully truncate and free any
- * inodes found on the lists. Each inode is removed from the
- * lists when it has been fully truncated and is freed. The
- * freeing of the inode and its removal from the list must be
- * atomic.
- */
-void
-xlog_recover_process_iunlinks(
- xlog_t *log)
-{
- xfs_mount_t *mp;
- xfs_agnumber_t agno;
- xfs_agi_t *agi;
- xfs_buf_t *agibp;
- xfs_buf_t *ibp;
- xfs_dinode_t *dip;
- xfs_inode_t *ip;
- xfs_agino_t agino;
- xfs_ino_t ino;
- int bucket;
- int error;
- uint mp_dmevmask;
-
- mp = log->l_mp;
-
- /*
- * Prevent any DMAPI event from being sent while in this function.
- */
- mp_dmevmask = mp->m_dmevmask;
- mp->m_dmevmask = 0;
-
- for (agno = 0; agno < mp->m_sb.sb_agcount; agno++) {
- /*
- * Find the agi for this ag.
- */
- agibp = xfs_buf_read(mp->m_ddev_targp,
- XFS_AG_DADDR(mp, agno, XFS_AGI_DADDR(mp)),
- XFS_FSS_TO_BB(mp, 1), 0);
- if (XFS_BUF_ISERROR(agibp)) {
- xfs_ioerror_alert("xlog_recover_process_iunlinks(#1)",
- log->l_mp, agibp,
- XFS_AG_DADDR(mp, agno, XFS_AGI_DADDR(mp)));
- }
- agi = XFS_BUF_TO_AGI(agibp);
- ASSERT(XFS_AGI_MAGIC == be32_to_cpu(agi->agi_magicnum));
-
- for (bucket = 0; bucket < XFS_AGI_UNLINKED_BUCKETS; bucket++) {
-
- agino = be32_to_cpu(agi->agi_unlinked[bucket]);
- while (agino != NULLAGINO) {
-
- /*
- * Release the agi buffer so that it can
- * be acquired in the normal course of the
- * transaction to truncate and free the inode.
- */
- xfs_buf_relse(agibp);
-
- ino = XFS_AGINO_TO_INO(mp, agno, agino);
- error = xfs_iget(mp, NULL, ino, 0, 0, &ip, 0);
- ASSERT(error || (ip != NULL));
-
- if (!error) {
- /*
- * Get the on disk inode to find the
- * next inode in the bucket.
- */
- error = xfs_itobp(mp, NULL, ip, &dip,
- &ibp, 0, 0);
- ASSERT(error || (dip != NULL));
- }
-
- if (!error) {
- ASSERT(ip->i_d.di_nlink == 0);
-
- /* setup for the next pass */
- agino = INT_GET(dip->di_next_unlinked,
- ARCH_CONVERT);
- xfs_buf_relse(ibp);
- /*
- * Prevent any DMAPI event from
- * being sent when the
- * reference on the inode is
- * dropped.
- */
- ip->i_d.di_dmevmask = 0;
-
- /*
- * If this is a new inode, handle
- * it specially. Otherwise,
- * just drop our reference to the
- * inode. If there are no
- * other references, this will
- * send the inode to
- * xfs_inactive() which will
- * truncate the file and free
- * the inode.
- */
- if (ip->i_d.di_mode == 0)
- xfs_iput_new(ip, 0);
- else
- VN_RELE(XFS_ITOV(ip));
- } else {
- /*
- * We can't read in the inode
- * this bucket points to, or
- * this inode is messed up. Just
- * ditch this bucket of inodes. We
- * will lose some inodes and space,
- * but at least we won't hang. Call
- * xlog_recover_clear_agi_bucket()
- * to perform a transaction to clear
- * the inode pointer in the bucket.
- */
- xlog_recover_clear_agi_bucket(mp, agno,
- bucket);
-
- agino = NULLAGINO;
- }
-
- /*
- * Reacquire the agibuffer and continue around
- * the loop.
- */
- agibp = xfs_buf_read(mp->m_ddev_targp,
- XFS_AG_DADDR(mp, agno,
- XFS_AGI_DADDR(mp)),
- XFS_FSS_TO_BB(mp, 1), 0);
- if (XFS_BUF_ISERROR(agibp)) {
- xfs_ioerror_alert(
- "xlog_recover_process_iunlinks(#2)",
- log->l_mp, agibp,
- XFS_AG_DADDR(mp, agno,
- XFS_AGI_DADDR(mp)));
- }
- agi = XFS_BUF_TO_AGI(agibp);
- ASSERT(XFS_AGI_MAGIC == be32_to_cpu(
- agi->agi_magicnum));
- }
- }
-
- /*
- * Release the buffer for the current agi so we can
- * go on to the next one.
- */
- xfs_buf_relse(agibp);
- }
-
- mp->m_dmevmask = mp_dmevmask;
-}
-
-
-#ifdef DEBUG
-STATIC void
-xlog_pack_data_checksum(
- xlog_t *log,
- xlog_in_core_t *iclog,
- int size)
-{
- int i;
- uint *up;
- uint chksum = 0;
-
- up = (uint *)iclog->ic_datap;
- /* divide length by 4 to get # words */
- for (i = 0; i < (size >> 2); i++) {
- chksum ^= INT_GET(*up, ARCH_CONVERT);
- up++;
- }
- INT_SET(iclog->ic_header.h_chksum, ARCH_CONVERT, chksum);
-}
-#else
-#define xlog_pack_data_checksum(log, iclog, size)
-#endif
-
-/*
- * Stamp cycle number in every block
- */
-void
-xlog_pack_data(
- xlog_t *log,
- xlog_in_core_t *iclog,
- int roundoff)
-{
- int i, j, k;
- int size = iclog->ic_offset + roundoff;
- uint cycle_lsn;
- xfs_caddr_t dp;
- xlog_in_core_2_t *xhdr;
-
- xlog_pack_data_checksum(log, iclog, size);
-
- cycle_lsn = CYCLE_LSN_DISK(iclog->ic_header.h_lsn);
-
- dp = iclog->ic_datap;
- for (i = 0; i < BTOBB(size) &&
- i < (XLOG_HEADER_CYCLE_SIZE / BBSIZE); i++) {
- iclog->ic_header.h_cycle_data[i] = *(uint *)dp;
- *(uint *)dp = cycle_lsn;
- dp += BBSIZE;
- }
-
- if (XFS_SB_VERSION_HASLOGV2(&log->l_mp->m_sb)) {
- xhdr = (xlog_in_core_2_t *)&iclog->ic_header;
- for ( ; i < BTOBB(size); i++) {
- j = i / (XLOG_HEADER_CYCLE_SIZE / BBSIZE);
- k = i % (XLOG_HEADER_CYCLE_SIZE / BBSIZE);
- xhdr[j].hic_xheader.xh_cycle_data[k] = *(uint *)dp;
- *(uint *)dp = cycle_lsn;
- dp += BBSIZE;
- }
-
- for (i = 1; i < log->l_iclog_heads; i++) {
- xhdr[i].hic_xheader.xh_cycle = cycle_lsn;
- }
- }
-}
-
-#if defined(DEBUG) && defined(XFS_LOUD_RECOVERY)
-STATIC void
-xlog_unpack_data_checksum(
- xlog_rec_header_t *rhead,
- xfs_caddr_t dp,
- xlog_t *log)
-{
- uint *up = (uint *)dp;
- uint chksum = 0;
- int i;
-
- /* divide length by 4 to get # words */
- for (i=0; i < INT_GET(rhead->h_len, ARCH_CONVERT) >> 2; i++) {
- chksum ^= INT_GET(*up, ARCH_CONVERT);
- up++;
- }
- if (chksum != INT_GET(rhead->h_chksum, ARCH_CONVERT)) {
- if (rhead->h_chksum ||
- ((log->l_flags & XLOG_CHKSUM_MISMATCH) == 0)) {
- cmn_err(CE_DEBUG,
- "XFS: LogR chksum mismatch: was (0x%x) is (0x%x)",
- INT_GET(rhead->h_chksum, ARCH_CONVERT), chksum);
- cmn_err(CE_DEBUG,
-"XFS: Disregard message if filesystem was created with non-DEBUG kernel");
- if (XFS_SB_VERSION_HASLOGV2(&log->l_mp->m_sb)) {
- cmn_err(CE_DEBUG,
- "XFS: LogR this is a LogV2 filesystem");
- }
- log->l_flags |= XLOG_CHKSUM_MISMATCH;
- }
- }
-}
-#else
-#define xlog_unpack_data_checksum(rhead, dp, log)
-#endif
-
-STATIC void
-xlog_unpack_data(
- xlog_rec_header_t *rhead,
- xfs_caddr_t dp,
- xlog_t *log)
-{
- int i, j, k;
- xlog_in_core_2_t *xhdr;
-
- for (i = 0; i < BTOBB(INT_GET(rhead->h_len, ARCH_CONVERT)) &&
- i < (XLOG_HEADER_CYCLE_SIZE / BBSIZE); i++) {
- *(uint *)dp = *(uint *)&rhead->h_cycle_data[i];
- dp += BBSIZE;
- }
-
- if (XFS_SB_VERSION_HASLOGV2(&log->l_mp->m_sb)) {
- xhdr = (xlog_in_core_2_t *)rhead;
- for ( ; i < BTOBB(INT_GET(rhead->h_len, ARCH_CONVERT)); i++) {
- j = i / (XLOG_HEADER_CYCLE_SIZE / BBSIZE);
- k = i % (XLOG_HEADER_CYCLE_SIZE / BBSIZE);
- *(uint *)dp = xhdr[j].hic_xheader.xh_cycle_data[k];
- dp += BBSIZE;
- }
- }
-
- xlog_unpack_data_checksum(rhead, dp, log);
-}
-
-STATIC int
-xlog_valid_rec_header(
- xlog_t *log,
- xlog_rec_header_t *rhead,
- xfs_daddr_t blkno)
-{
- int hlen;
-
- if (unlikely(
- (INT_GET(rhead->h_magicno, ARCH_CONVERT) !=
- XLOG_HEADER_MAGIC_NUM))) {
- XFS_ERROR_REPORT("xlog_valid_rec_header(1)",
- XFS_ERRLEVEL_LOW, log->l_mp);
- return XFS_ERROR(EFSCORRUPTED);
- }
- if (unlikely(
- (!rhead->h_version ||
- (INT_GET(rhead->h_version, ARCH_CONVERT) &
- (~XLOG_VERSION_OKBITS)) != 0))) {
- xlog_warn("XFS: %s: unrecognised log version (%d).",
- __FUNCTION__, INT_GET(rhead->h_version, ARCH_CONVERT));
- return XFS_ERROR(EIO);
- }
-
- /* LR body must have data or it wouldn't have been written */
- hlen = INT_GET(rhead->h_len, ARCH_CONVERT);
- if (unlikely( hlen <= 0 || hlen > INT_MAX )) {
- XFS_ERROR_REPORT("xlog_valid_rec_header(2)",
- XFS_ERRLEVEL_LOW, log->l_mp);
- return XFS_ERROR(EFSCORRUPTED);
- }
- if (unlikely( blkno > log->l_logBBsize || blkno > INT_MAX )) {
- XFS_ERROR_REPORT("xlog_valid_rec_header(3)",
- XFS_ERRLEVEL_LOW, log->l_mp);
- return XFS_ERROR(EFSCORRUPTED);
- }
- return 0;
-}
-
-/*
- * Read the log from tail to head and process the log records found.
- * Handle the two cases where the tail and head are in the same cycle
- * and where the active portion of the log wraps around the end of
- * the physical log separately. The pass parameter is passed through
- * to the routines called to process the data and is not looked at
- * here.
- */
-STATIC int
-xlog_do_recovery_pass(
- xlog_t *log,
- xfs_daddr_t head_blk,
- xfs_daddr_t tail_blk,
- int pass)
-{
- xlog_rec_header_t *rhead;
- xfs_daddr_t blk_no;
- xfs_caddr_t bufaddr, offset;
- xfs_buf_t *hbp, *dbp;
- int error = 0, h_size;
- int bblks, split_bblks;
- int hblks, split_hblks, wrapped_hblks;
- xlog_recover_t *rhash[XLOG_RHASH_SIZE];
-
- ASSERT(head_blk != tail_blk);
-
- /*
- * Read the header of the tail block and get the iclog buffer size from
- * h_size. Use this to tell how many sectors make up the log header.
- */
- if (XFS_SB_VERSION_HASLOGV2(&log->l_mp->m_sb)) {
- /*
- * When using variable length iclogs, read first sector of
- * iclog header and extract the header size from it. Get a
- * new hbp that is the correct size.
- */
- hbp = xlog_get_bp(log, 1);
- if (!hbp)
- return ENOMEM;
- if ((error = xlog_bread(log, tail_blk, 1, hbp)))
- goto bread_err1;
- offset = xlog_align(log, tail_blk, 1, hbp);
- rhead = (xlog_rec_header_t *)offset;
- error = xlog_valid_rec_header(log, rhead, tail_blk);
- if (error)
- goto bread_err1;
- h_size = INT_GET(rhead->h_size, ARCH_CONVERT);
- if ((INT_GET(rhead->h_version, ARCH_CONVERT)
- & XLOG_VERSION_2) &&
- (h_size > XLOG_HEADER_CYCLE_SIZE)) {
- hblks = h_size / XLOG_HEADER_CYCLE_SIZE;
- if (h_size % XLOG_HEADER_CYCLE_SIZE)
- hblks++;
- xlog_put_bp(hbp);
- hbp = xlog_get_bp(log, hblks);
- } else {
- hblks = 1;
- }
- } else {
- ASSERT(log->l_sectbb_log == 0);
- hblks = 1;
- hbp = xlog_get_bp(log, 1);
- h_size = XLOG_BIG_RECORD_BSIZE;
- }
-
- if (!hbp)
- return ENOMEM;
- dbp = xlog_get_bp(log, BTOBB(h_size));
- if (!dbp) {
- xlog_put_bp(hbp);
- return ENOMEM;
- }
-
- memset(rhash, 0, sizeof(rhash));
- if (tail_blk <= head_blk) {
- for (blk_no = tail_blk; blk_no < head_blk; ) {
- if ((error = xlog_bread(log, blk_no, hblks, hbp)))
- goto bread_err2;
- offset = xlog_align(log, blk_no, hblks, hbp);
- rhead = (xlog_rec_header_t *)offset;
- error = xlog_valid_rec_header(log, rhead, blk_no);
- if (error)
- goto bread_err2;
-
- /* blocks in data section */
- bblks = (int)BTOBB(INT_GET(rhead->h_len, ARCH_CONVERT));
- error = xlog_bread(log, blk_no + hblks, bblks, dbp);
- if (error)
- goto bread_err2;
- offset = xlog_align(log, blk_no + hblks, bblks, dbp);
- xlog_unpack_data(rhead, offset, log);
- if ((error = xlog_recover_process_data(log,
- rhash, rhead, offset, pass)))
- goto bread_err2;
- blk_no += bblks + hblks;
- }
- } else {
- /*
- * Perform recovery around the end of the physical log.
- * When the head is not on the same cycle number as the tail,
- * we can't do a sequential recovery as above.
- */
- blk_no = tail_blk;
- while (blk_no < log->l_logBBsize) {
- /*
- * Check for header wrapping around physical end-of-log
- */
- offset = NULL;
- split_hblks = 0;
- wrapped_hblks = 0;
- if (blk_no + hblks <= log->l_logBBsize) {
- /* Read header in one read */
- error = xlog_bread(log, blk_no, hblks, hbp);
- if (error)
- goto bread_err2;
- offset = xlog_align(log, blk_no, hblks, hbp);
- } else {
- /* This LR is split across physical log end */
- if (blk_no != log->l_logBBsize) {
- /* some data before physical log end */
- ASSERT(blk_no <= INT_MAX);
- split_hblks = log->l_logBBsize - (int)blk_no;
- ASSERT(split_hblks > 0);
- if ((error = xlog_bread(log, blk_no,
- split_hblks, hbp)))
- goto bread_err2;
- offset = xlog_align(log, blk_no,
- split_hblks, hbp);
- }
- /*
- * Note: this black magic still works with
- * large sector sizes (non-512) only because:
- * - we increased the buffer size originally
- * by 1 sector giving us enough extra space
- * for the second read;
- * - the log start is guaranteed to be sector
- * aligned;
- * - we read the log end (LR header start)
- * _first_, then the log start (LR header end)
- * - order is important.
- */
- bufaddr = XFS_BUF_PTR(hbp);
- XFS_BUF_SET_PTR(hbp,
- bufaddr + BBTOB(split_hblks),
- BBTOB(hblks - split_hblks));
- wrapped_hblks = hblks - split_hblks;
- error = xlog_bread(log, 0, wrapped_hblks, hbp);
- if (error)
- goto bread_err2;
- XFS_BUF_SET_PTR(hbp, bufaddr, BBTOB(hblks));
- if (!offset)
- offset = xlog_align(log, 0,
- wrapped_hblks, hbp);
- }
- rhead = (xlog_rec_header_t *)offset;
- error = xlog_valid_rec_header(log, rhead,
- split_hblks ? blk_no : 0);
- if (error)
- goto bread_err2;
-
- bblks = (int)BTOBB(INT_GET(rhead->h_len, ARCH_CONVERT));
- blk_no += hblks;
-
- /* Read in data for log record */
- if (blk_no + bblks <= log->l_logBBsize) {
- error = xlog_bread(log, blk_no, bblks, dbp);
- if (error)
- goto bread_err2;
- offset = xlog_align(log, blk_no, bblks, dbp);
- } else {
- /* This log record is split across the
- * physical end of log */
- offset = NULL;
- split_bblks = 0;
- if (blk_no != log->l_logBBsize) {
- /* some data is before the physical
- * end of log */
- ASSERT(!wrapped_hblks);
- ASSERT(blk_no <= INT_MAX);
- split_bblks =
- log->l_logBBsize - (int)blk_no;
- ASSERT(split_bblks > 0);
- if ((error = xlog_bread(log, blk_no,
- split_bblks, dbp)))
- goto bread_err2;
- offset = xlog_align(log, blk_no,
- split_bblks, dbp);
- }
- /*
- * Note: this black magic still works with
- * large sector sizes (non-512) only because:
- * - we increased the buffer size originally
- * by 1 sector giving us enough extra space
- * for the second read;
- * - the log start is guaranteed to be sector
- * aligned;
- * - we read the log end (LR header start)
- * _first_, then the log start (LR header end)
- * - order is important.
- */
- bufaddr = XFS_BUF_PTR(dbp);
- XFS_BUF_SET_PTR(dbp,
- bufaddr + BBTOB(split_bblks),
- BBTOB(bblks - split_bblks));
- if ((error = xlog_bread(log, wrapped_hblks,
- bblks - split_bblks, dbp)))
- goto bread_err2;
- XFS_BUF_SET_PTR(dbp, bufaddr, h_size);
- if (!offset)
- offset = xlog_align(log, wrapped_hblks,
- bblks - split_bblks, dbp);
- }
- xlog_unpack_data(rhead, offset, log);
- if ((error = xlog_recover_process_data(log, rhash,
- rhead, offset, pass)))
- goto bread_err2;
- blk_no += bblks;
- }
-
- ASSERT(blk_no >= log->l_logBBsize);
- blk_no -= log->l_logBBsize;
-
- /* read first part of physical log */
- while (blk_no < head_blk) {
- if ((error = xlog_bread(log, blk_no, hblks, hbp)))
- goto bread_err2;
- offset = xlog_align(log, blk_no, hblks, hbp);
- rhead = (xlog_rec_header_t *)offset;
- error = xlog_valid_rec_header(log, rhead, blk_no);
- if (error)
- goto bread_err2;
- bblks = (int)BTOBB(INT_GET(rhead->h_len, ARCH_CONVERT));
- if ((error = xlog_bread(log, blk_no+hblks, bblks, dbp)))
- goto bread_err2;
- offset = xlog_align(log, blk_no+hblks, bblks, dbp);
- xlog_unpack_data(rhead, offset, log);
- if ((error = xlog_recover_process_data(log, rhash,
- rhead, offset, pass)))
- goto bread_err2;
- blk_no += bblks + hblks;
- }
- }
-
- bread_err2:
- xlog_put_bp(dbp);
- bread_err1:
- xlog_put_bp(hbp);
- return error;
-}
-
-/*
- * Do the recovery of the log. We actually do this in two phases.
- * The two passes are necessary in order to implement the function
- * of cancelling a record written into the log. The first pass
- * determines those things which have been cancelled, and the
- * second pass replays log items normally except for those which
- * have been cancelled. The handling of the replay and cancellations
- * takes place in the log item type specific routines.
- *
- * The table of items which have cancel records in the log is allocated
- * and freed at this level, since only here do we know when all of
- * the log recovery has been completed.
- */
-STATIC int
-xlog_do_log_recovery(
- xlog_t *log,
- xfs_daddr_t head_blk,
- xfs_daddr_t tail_blk)
-{
- int error;
-
- ASSERT(head_blk != tail_blk);
-
- /*
- * First do a pass to find all of the cancelled buf log items.
- * Store them in the buf_cancel_table for use in the second pass.
- */
- log->l_buf_cancel_table =
- (xfs_buf_cancel_t **)kmem_zalloc(XLOG_BC_TABLE_SIZE *
- sizeof(xfs_buf_cancel_t*),
- KM_SLEEP);
- error = xlog_do_recovery_pass(log, head_blk, tail_blk,
- XLOG_RECOVER_PASS1);
- if (error != 0) {
- kmem_free(log->l_buf_cancel_table,
- XLOG_BC_TABLE_SIZE * sizeof(xfs_buf_cancel_t*));
- log->l_buf_cancel_table = NULL;
- return error;
- }
- /*
- * Then do a second pass to actually recover the items in the log.
- * When it is complete free the table of buf cancel items.
- */
- error = xlog_do_recovery_pass(log, head_blk, tail_blk,
- XLOG_RECOVER_PASS2);
-#ifdef DEBUG
- {
- int i;
-
- for (i = 0; i < XLOG_BC_TABLE_SIZE; i++)
- ASSERT(log->l_buf_cancel_table[i] == NULL);
- }
-#endif /* DEBUG */
-
- kmem_free(log->l_buf_cancel_table,
- XLOG_BC_TABLE_SIZE * sizeof(xfs_buf_cancel_t*));
- log->l_buf_cancel_table = NULL;
-
- return error;
-}
-
-/*
- * Do the actual recovery
- */
-STATIC int
-xlog_do_recover(
- xlog_t *log,
- xfs_daddr_t head_blk,
- xfs_daddr_t tail_blk)
-{
- int error;
- xfs_buf_t *bp;
- xfs_sb_t *sbp;
-
- /*
- * XXX: Disable log recovery for now, until we fix panics.
- */
- printf("XFS log recovery disabled.\n");
- return (EOPNOTSUPP);
- /*
- * First replay the images in the log.
- */
- error = xlog_do_log_recovery(log, head_blk, tail_blk);
- if (error) {
- return error;
- }
-
- XFS_bflush(log->l_mp->m_ddev_targp);
-
- /*
- * If IO errors happened during recovery, bail out.
- */
- if (XFS_FORCED_SHUTDOWN(log->l_mp)) {
- return (EIO);
- }
-
- /*
- * We now update the tail_lsn since much of the recovery has completed
- * and there may be space available to use. If there were no extent
- * or iunlinks, we can free up the entire log and set the tail_lsn to
- * be the last_sync_lsn. This was set in xlog_find_tail to be the
- * lsn of the last known good LR on disk. If there are extent frees
- * or iunlinks they will have some entries in the AIL; so we look at
- * the AIL to determine how to set the tail_lsn.
- */
- xlog_assign_tail_lsn(log->l_mp);
-
- /*
- * Now that we've finished replaying all buffer and inode
- * updates, re-read in the superblock.
- */
- bp = xfs_getsb(log->l_mp, 0);
- XFS_BUF_UNDONE(bp);
- XFS_BUF_READ(bp);
- xfsbdstrat(log->l_mp, bp);
- if ((error = xfs_iowait(bp))) {
- xfs_ioerror_alert("xlog_do_recover",
- log->l_mp, bp, XFS_BUF_ADDR(bp));
- ASSERT(0);
- xfs_buf_relse(bp);
- return error;
- }
-
- /* Convert superblock from on-disk format */
- sbp = &log->l_mp->m_sb;
- xfs_xlatesb(XFS_BUF_TO_SBP(bp), sbp, 1, XFS_SB_ALL_BITS);
- ASSERT(sbp->sb_magicnum == XFS_SB_MAGIC);
- ASSERT(XFS_SB_GOOD_VERSION(sbp));
- xfs_buf_relse(bp);
-
- xlog_recover_check_summary(log);
-
- /* Normal transactions can now occur */
- log->l_flags &= ~XLOG_ACTIVE_RECOVERY;
- return 0;
-}
-
-/*
- * Perform recovery and re-initialize some log variables in xlog_find_tail.
- *
- * Return error or zero.
- */
-int
-xlog_recover(
- xlog_t *log)
-{
- xfs_daddr_t head_blk, tail_blk;
- int error;
-
- /* find the tail of the log */
- if ((error = xlog_find_tail(log, &head_blk, &tail_blk)))
- return error;
-
- if (tail_blk != head_blk) {
- /* There used to be a comment here:
- *
- * disallow recovery on read-only mounts. note -- mount
- * checks for ENOSPC and turns it into an intelligent
- * error message.
- * ...but this is no longer true. Now, unless you specify
- * NORECOVERY (in which case this function would never be
- * called), we just go ahead and recover. We do this all
- * under the vfs layer, so we can get away with it unless
- * the device itself is read-only, in which case we fail.
- */
- if ((error = xfs_dev_is_read_only(log->l_mp,
- "recovery required"))) {
- return error;
- }
-
- cmn_err(CE_NOTE,
- "Starting XFS recovery on filesystem: %s (logdev: %s)",
- log->l_mp->m_fsname, log->l_mp->m_logname ?
- log->l_mp->m_logname : "internal");
-
- error = xlog_do_recover(log, head_blk, tail_blk);
- log->l_flags |= XLOG_RECOVERY_NEEDED;
- }
- return error;
-}
-
-/*
- * In the first part of recovery we replay inodes and buffers and build
- * up the list of extent free items which need to be processed. Here
- * we process the extent free items and clean up the on disk unlinked
- * inode lists. This is separated from the first part of recovery so
- * that the root and real-time bitmap inodes can be read in from disk in
- * between the two stages. This is necessary so that we can free space
- * in the real-time portion of the file system.
- */
-int
-xlog_recover_finish(
- xlog_t *log,
- int mfsi_flags)
-{
- /*
- * Now we're ready to do the transactions needed for the
- * rest of recovery. Start with completing all the extent
- * free intent records and then process the unlinked inode
- * lists. At this point, we essentially run in normal mode
- * except that we're still performing recovery actions
- * rather than accepting new requests.
- */
- if (log->l_flags & XLOG_RECOVERY_NEEDED) {
- xlog_recover_process_efis(log);
- /*
- * Sync the log to get all the EFIs out of the AIL.
- * This isn't absolutely necessary, but it helps in
- * case the unlink transactions would have problems
- * pushing the EFIs out of the way.
- */
- xfs_log_force(log->l_mp, (xfs_lsn_t)0,
- (XFS_LOG_FORCE | XFS_LOG_SYNC));
-
- if ( (mfsi_flags & XFS_MFSI_NOUNLINK) == 0 ) {
- xlog_recover_process_iunlinks(log);
- }
-
- xlog_recover_check_summary(log);
-
- cmn_err(CE_NOTE,
- "Ending XFS recovery on filesystem: %s (logdev: %s)",
- log->l_mp->m_fsname, log->l_mp->m_logname ?
- log->l_mp->m_logname : "internal");
- log->l_flags &= ~XLOG_RECOVERY_NEEDED;
- } else {
- cmn_err(CE_DEBUG,
- "!Ending clean XFS mount for filesystem: %s",
- log->l_mp->m_fsname);
- }
- return 0;
-}
-
-
-#if defined(DEBUG)
-/*
- * Read all of the agf and agi counters and check that they
- * are consistent with the superblock counters.
- */
-void
-xlog_recover_check_summary(
- xlog_t *log)
-{
- xfs_mount_t *mp;
- xfs_agf_t *agfp;
- xfs_agi_t *agip;
- xfs_buf_t *agfbp;
- xfs_buf_t *agibp;
- xfs_daddr_t agfdaddr;
- xfs_daddr_t agidaddr;
- xfs_buf_t *sbbp;
-#ifdef XFS_LOUD_RECOVERY
- xfs_sb_t *sbp;
-#endif
- xfs_agnumber_t agno;
- __uint64_t freeblks;
- __uint64_t itotal;
- __uint64_t ifree;
-
- mp = log->l_mp;
-
- freeblks = 0LL;
- itotal = 0LL;
- ifree = 0LL;
- for (agno = 0; agno < mp->m_sb.sb_agcount; agno++) {
- agfdaddr = XFS_AG_DADDR(mp, agno, XFS_AGF_DADDR(mp));
- agfbp = xfs_buf_read(mp->m_ddev_targp, agfdaddr,
- XFS_FSS_TO_BB(mp, 1), 0);
- if (XFS_BUF_ISERROR(agfbp)) {
- xfs_ioerror_alert("xlog_recover_check_summary(agf)",
- mp, agfbp, agfdaddr);
- }
- agfp = XFS_BUF_TO_AGF(agfbp);
- ASSERT(XFS_AGF_MAGIC == be32_to_cpu(agfp->agf_magicnum));
- ASSERT(XFS_AGF_GOOD_VERSION(be32_to_cpu(agfp->agf_versionnum)));
- ASSERT(be32_to_cpu(agfp->agf_seqno) == agno);
-
- freeblks += be32_to_cpu(agfp->agf_freeblks) +
- be32_to_cpu(agfp->agf_flcount);
- xfs_buf_relse(agfbp);
-
- agidaddr = XFS_AG_DADDR(mp, agno, XFS_AGI_DADDR(mp));
- agibp = xfs_buf_read(mp->m_ddev_targp, agidaddr,
- XFS_FSS_TO_BB(mp, 1), 0);
- if (XFS_BUF_ISERROR(agibp)) {
- xfs_ioerror_alert("xlog_recover_check_summary(agi)",
- mp, agibp, agidaddr);
- }
- agip = XFS_BUF_TO_AGI(agibp);
- ASSERT(XFS_AGI_MAGIC == be32_to_cpu(agip->agi_magicnum));
- ASSERT(XFS_AGI_GOOD_VERSION(be32_to_cpu(agip->agi_versionnum)));
- ASSERT(be32_to_cpu(agip->agi_seqno) == agno);
-
- itotal += be32_to_cpu(agip->agi_count);
- ifree += be32_to_cpu(agip->agi_freecount);
- xfs_buf_relse(agibp);
- }
-
- sbbp = xfs_getsb(mp, 0);
-#ifdef XFS_LOUD_RECOVERY
- sbp = &mp->m_sb;
- xfs_xlatesb(XFS_BUF_TO_SBP(sbbp), sbp, 1, XFS_SB_ALL_BITS);
- cmn_err(CE_NOTE,
- "xlog_recover_check_summary: sb_icount %Lu itotal %Lu",
- sbp->sb_icount, itotal);
- cmn_err(CE_NOTE,
- "xlog_recover_check_summary: sb_ifree %Lu itotal %Lu",
- sbp->sb_ifree, ifree);
- cmn_err(CE_NOTE,
- "xlog_recover_check_summary: sb_fdblocks %Lu freeblks %Lu",
- sbp->sb_fdblocks, freeblks);
-#if 0
- /*
- * This is turned off until I account for the allocation
- * btree blocks which live in free space.
- */
- ASSERT(sbp->sb_icount == itotal);
- ASSERT(sbp->sb_ifree == ifree);
- ASSERT(sbp->sb_fdblocks == freeblks);
-#endif
-#endif
- xfs_buf_relse(sbbp);
-}
-#endif /* DEBUG */
diff --git a/sys/gnu/fs/xfs/xfs_log_recover.h b/sys/gnu/fs/xfs/xfs_log_recover.h
deleted file mode 100644
index b225455..0000000
--- a/sys/gnu/fs/xfs/xfs_log_recover.h
+++ /dev/null
@@ -1,67 +0,0 @@
-/*
- * Copyright (c) 2000,2005 Silicon Graphics, Inc.
- * All Rights Reserved.
- *
- * 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.
- *
- * This program is distributed in the hope that it would 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 the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- */
-#ifndef __XFS_LOG_RECOVER_H__
-#define __XFS_LOG_RECOVER_H__
-
-/*
- * Macros, structures, prototypes for internal log manager use.
- */
-
-#define XLOG_RHASH_BITS 4
-#define XLOG_RHASH_SIZE 16
-#define XLOG_RHASH_SHIFT 2
-#define XLOG_RHASH(tid) \
- ((((__uint32_t)tid)>>XLOG_RHASH_SHIFT) & (XLOG_RHASH_SIZE-1))
-
-#define XLOG_MAX_REGIONS_IN_ITEM (XFS_MAX_BLOCKSIZE / XFS_BLI_CHUNK / 2 + 1)
-
-
-/*
- * item headers are in ri_buf[0]. Additional buffers follow.
- */
-typedef struct xlog_recover_item {
- struct xlog_recover_item *ri_next;
- struct xlog_recover_item *ri_prev;
- int ri_type;
- int ri_cnt; /* count of regions found */
- int ri_total; /* total regions */
- xfs_log_iovec_t *ri_buf; /* ptr to regions buffer */
-} xlog_recover_item_t;
-
-struct xlog_tid;
-typedef struct xlog_recover {
- struct xlog_recover *r_next;
- xlog_tid_t r_log_tid; /* log's transaction id */
- xfs_trans_header_t r_theader; /* trans header for partial */
- int r_state; /* not needed */
- xfs_lsn_t r_lsn; /* xact lsn */
- xlog_recover_item_t *r_itemq; /* q for items */
-} xlog_recover_t;
-
-#define ITEM_TYPE(i) (*(ushort *)(i)->ri_buf[0].i_addr)
-
-/*
- * This is the number of entries in the l_buf_cancel_table used during
- * recovery.
- */
-#define XLOG_BC_TABLE_SIZE 64
-
-#define XLOG_RECOVER_PASS1 1
-#define XLOG_RECOVER_PASS2 2
-
-#endif /* __XFS_LOG_RECOVER_H__ */
diff --git a/sys/gnu/fs/xfs/xfs_mac.c b/sys/gnu/fs/xfs/xfs_mac.c
deleted file mode 100644
index a31a524..0000000
--- a/sys/gnu/fs/xfs/xfs_mac.c
+++ /dev/null
@@ -1,72 +0,0 @@
-/*
- * Copyright (c) 2000-2002 Silicon Graphics, Inc. All Rights Reserved.
- *
- * This program 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.
- *
- * This program is distributed in the hope that it would be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
- *
- * Further, this software is distributed without any warranty that it is
- * free of the rightful claim of any third person regarding infringement
- * or the like. Any license provided herein, whether implied or
- * otherwise, applies only to this software file. Patent licenses, if
- * any, provided herein do not apply to combinations of this program with
- * other software, or any other product whatsoever.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write the Free Software Foundation, Inc., 59
- * Temple Place - Suite 330, Boston MA 02111-1307, USA.
- *
- * Contact information: Silicon Graphics, Inc., 1600 Amphitheatre Pkwy,
- * Mountain View, CA 94043, or:
- *
- * http://www.sgi.com
- *
- * For further information regarding this notice, see:
- *
- * http://oss.sgi.com/projects/GenInfo/SGIGPLNoticeExplan/
- */
-
-#include "xfs.h"
-
-static xfs_mac_label_t *mac_low_high_lp;
-static xfs_mac_label_t *mac_high_low_lp;
-static xfs_mac_label_t *mac_admin_high_lp;
-static xfs_mac_label_t *mac_equal_equal_lp;
-
-/*
- * Test for the existence of a MAC label as efficiently as possible.
- */
-int
-xfs_mac_vhaslabel(
- xfs_vnode_t *vp)
-{
- int error;
- int len = sizeof(xfs_mac_label_t);
- int flags = ATTR_KERNOVAL|ATTR_ROOT;
-
- XVOP_ATTR_GET(vp, SGI_MAC_FILE, NULL, &len, flags, sys_cred, error);
- return (error == 0);
-}
-
-int
-xfs_mac_iaccess(xfs_inode_t *ip, mode_t mode, struct cred *cr)
-{
- xfs_mac_label_t mac;
- xfs_mac_label_t *mp = mac_high_low_lp;
-
- if (cr == NULL || sys_cred == NULL ) {
- return EACCES;
- }
-
- if (xfs_attr_fetch(ip, SGI_MAC_FILE, (char *)&mac, sizeof(mac)) == 0) {
- if ((mp = mac_add_label(&mac)) == NULL) {
- return mac_access(mac_high_low_lp, cr, mode);
- }
- }
-
- return mac_access(mp, cr, mode);
-}
diff --git a/sys/gnu/fs/xfs/xfs_mac.h b/sys/gnu/fs/xfs/xfs_mac.h
deleted file mode 100644
index 18e0e98..0000000
--- a/sys/gnu/fs/xfs/xfs_mac.h
+++ /dev/null
@@ -1,106 +0,0 @@
-/*
- * Copyright (c) 2001-2002,2005 Silicon Graphics, Inc.
- * All Rights Reserved.
- *
- * 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.
- *
- * This program is distributed in the hope that it would 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 the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- */
-#ifndef __XFS_MAC_H__
-#define __XFS_MAC_H__
-
-/*
- * Mandatory Access Control
- *
- * Layout of a composite MAC label:
- * ml_list contains the list of categories (MSEN) followed by the list of
- * divisions (MINT). This is actually a header for the data structure which
- * will have an ml_list with more than one element.
- *
- * -------------------------------
- * | ml_msen_type | ml_mint_type |
- * -------------------------------
- * | ml_level | ml_grade |
- * -------------------------------
- * | ml_catcount |
- * -------------------------------
- * | ml_divcount |
- * -------------------------------
- * | category 1 |
- * | . . . |
- * | category N | (where N = ml_catcount)
- * -------------------------------
- * | division 1 |
- * | . . . |
- * | division M | (where M = ml_divcount)
- * -------------------------------
- */
-#define XFS_MAC_MAX_SETS 250
-typedef struct xfs_mac_label {
- __uint8_t ml_msen_type; /* MSEN label type */
- __uint8_t ml_mint_type; /* MINT label type */
- __uint8_t ml_level; /* Hierarchical level */
- __uint8_t ml_grade; /* Hierarchical grade */
- __uint16_t ml_catcount; /* Category count */
- __uint16_t ml_divcount; /* Division count */
- /* Category set, then Division set */
- __uint16_t ml_list[XFS_MAC_MAX_SETS];
-} xfs_mac_label_t;
-
-/* MSEN label type names. Choose an upper case ASCII character. */
-#define XFS_MSEN_ADMIN_LABEL 'A' /* Admin: low<admin != tcsec<high */
-#define XFS_MSEN_EQUAL_LABEL 'E' /* Wildcard - always equal */
-#define XFS_MSEN_HIGH_LABEL 'H' /* System High - always dominates */
-#define XFS_MSEN_MLD_HIGH_LABEL 'I' /* System High, multi-level dir */
-#define XFS_MSEN_LOW_LABEL 'L' /* System Low - always dominated */
-#define XFS_MSEN_MLD_LABEL 'M' /* TCSEC label on a multi-level dir */
-#define XFS_MSEN_MLD_LOW_LABEL 'N' /* System Low, multi-level dir */
-#define XFS_MSEN_TCSEC_LABEL 'T' /* TCSEC label */
-#define XFS_MSEN_UNKNOWN_LABEL 'U' /* unknown label */
-
-/* MINT label type names. Choose a lower case ASCII character. */
-#define XFS_MINT_BIBA_LABEL 'b' /* Dual of a TCSEC label */
-#define XFS_MINT_EQUAL_LABEL 'e' /* Wildcard - always equal */
-#define XFS_MINT_HIGH_LABEL 'h' /* High Grade - always dominates */
-#define XFS_MINT_LOW_LABEL 'l' /* Low Grade - always dominated */
-
-/* On-disk XFS extended attribute names */
-#define SGI_MAC_FILE "SGI_MAC_FILE"
-#define SGI_MAC_FILE_SIZE (sizeof(SGI_MAC_FILE)-1)
-
-
-#ifdef __KERNEL__
-
-#ifdef CONFIG_FS_POSIX_MAC
-
-/* NOT YET IMPLEMENTED */
-
-#define MACEXEC 00100
-#define MACWRITE 00200
-#define MACREAD 00400
-
-struct xfs_inode;
-extern int xfs_mac_iaccess(struct xfs_inode *, mode_t, cred_t *);
-
-#define _MAC_XFS_IACCESS(i,m,c) (xfs_mac_iaccess(i,m,c))
-#define _MAC_VACCESS(v,c,m) (xfs_mac_vaccess(v,c,m))
-#define _MAC_EXISTS xfs_mac_vhaslabel
-
-#else
-#define _MAC_XFS_IACCESS(i,m,c) (0)
-#define _MAC_VACCESS(v,c,m) (0)
-#define _MAC_EXISTS (NULL)
-#endif
-
-#endif /* __KERNEL__ */
-
-#endif /* __XFS_MAC_H__ */
diff --git a/sys/gnu/fs/xfs/xfs_mount.c b/sys/gnu/fs/xfs/xfs_mount.c
deleted file mode 100644
index 7c6e478..0000000
--- a/sys/gnu/fs/xfs/xfs_mount.c
+++ /dev/null
@@ -1,2207 +0,0 @@
-/*
- * Copyright (c) 2000-2005 Silicon Graphics, Inc.
- * All Rights Reserved.
- *
- * 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.
- *
- * This program is distributed in the hope that it would 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 the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- */
-#include "xfs.h"
-#include "xfs_fs.h"
-#include "xfs_types.h"
-#include "xfs_bit.h"
-#include "xfs_log.h"
-#include "xfs_inum.h"
-#include "xfs_trans.h"
-#include "xfs_sb.h"
-#include "xfs_ag.h"
-#include "xfs_dir.h"
-#include "xfs_dir2.h"
-#include "xfs_dmapi.h"
-#include "xfs_mount.h"
-#include "xfs_bmap_btree.h"
-#include "xfs_alloc_btree.h"
-#include "xfs_ialloc_btree.h"
-#include "xfs_dir_sf.h"
-#include "xfs_dir2_sf.h"
-#include "xfs_attr_sf.h"
-#include "xfs_dinode.h"
-#include "xfs_inode.h"
-#include "xfs_btree.h"
-#include "xfs_ialloc.h"
-#include "xfs_alloc.h"
-#include "xfs_rtalloc.h"
-#include "xfs_bmap.h"
-#include "xfs_error.h"
-#include "xfs_rw.h"
-#include "xfs_quota.h"
-#include "xfs_fsops.h"
-
-STATIC void xfs_mount_log_sbunit(xfs_mount_t *, __int64_t);
-STATIC int xfs_uuid_mount(xfs_mount_t *);
-STATIC void xfs_uuid_unmount(xfs_mount_t *mp);
-STATIC void xfs_unmountfs_wait(xfs_mount_t *);
-
-
-#ifdef HAVE_PERCPU_SB
-STATIC void xfs_icsb_destroy_counters(xfs_mount_t *);
-STATIC void xfs_icsb_balance_counter(xfs_mount_t *, xfs_sb_field_t, int);
-STATIC void xfs_icsb_sync_counters(xfs_mount_t *);
-STATIC int xfs_icsb_modify_counters(xfs_mount_t *, xfs_sb_field_t,
- int, int);
-STATIC int xfs_icsb_modify_counters_locked(xfs_mount_t *, xfs_sb_field_t,
- int, int);
-STATIC int xfs_icsb_disable_counter(xfs_mount_t *, xfs_sb_field_t);
-
-#else
-
-#define xfs_icsb_destroy_counters(mp) do { } while (0)
-#define xfs_icsb_balance_counter(mp, a, b) do { } while (0)
-#define xfs_icsb_sync_counters(mp) do { } while (0)
-#define xfs_icsb_modify_counters(mp, a, b, c) do { } while (0)
-#define xfs_icsb_modify_counters_locked(mp, a, b, c) do { } while (0)
-
-#endif
-
-static const struct {
- short offset;
- short type; /* 0 = integer
- * 1 = binary / string (no translation)
- */
-} xfs_sb_info[] = {
- { offsetof(xfs_sb_t, sb_magicnum), 0 },
- { offsetof(xfs_sb_t, sb_blocksize), 0 },
- { offsetof(xfs_sb_t, sb_dblocks), 0 },
- { offsetof(xfs_sb_t, sb_rblocks), 0 },
- { offsetof(xfs_sb_t, sb_rextents), 0 },
- { offsetof(xfs_sb_t, sb_uuid), 1 },
- { offsetof(xfs_sb_t, sb_logstart), 0 },
- { offsetof(xfs_sb_t, sb_rootino), 0 },
- { offsetof(xfs_sb_t, sb_rbmino), 0 },
- { offsetof(xfs_sb_t, sb_rsumino), 0 },
- { offsetof(xfs_sb_t, sb_rextsize), 0 },
- { offsetof(xfs_sb_t, sb_agblocks), 0 },
- { offsetof(xfs_sb_t, sb_agcount), 0 },
- { offsetof(xfs_sb_t, sb_rbmblocks), 0 },
- { offsetof(xfs_sb_t, sb_logblocks), 0 },
- { offsetof(xfs_sb_t, sb_versionnum), 0 },
- { offsetof(xfs_sb_t, sb_sectsize), 0 },
- { offsetof(xfs_sb_t, sb_inodesize), 0 },
- { offsetof(xfs_sb_t, sb_inopblock), 0 },
- { offsetof(xfs_sb_t, sb_fname[0]), 1 },
- { offsetof(xfs_sb_t, sb_blocklog), 0 },
- { offsetof(xfs_sb_t, sb_sectlog), 0 },
- { offsetof(xfs_sb_t, sb_inodelog), 0 },
- { offsetof(xfs_sb_t, sb_inopblog), 0 },
- { offsetof(xfs_sb_t, sb_agblklog), 0 },
- { offsetof(xfs_sb_t, sb_rextslog), 0 },
- { offsetof(xfs_sb_t, sb_inprogress), 0 },
- { offsetof(xfs_sb_t, sb_imax_pct), 0 },
- { offsetof(xfs_sb_t, sb_icount), 0 },
- { offsetof(xfs_sb_t, sb_ifree), 0 },
- { offsetof(xfs_sb_t, sb_fdblocks), 0 },
- { offsetof(xfs_sb_t, sb_frextents), 0 },
- { offsetof(xfs_sb_t, sb_uquotino), 0 },
- { offsetof(xfs_sb_t, sb_gquotino), 0 },
- { offsetof(xfs_sb_t, sb_qflags), 0 },
- { offsetof(xfs_sb_t, sb_flags), 0 },
- { offsetof(xfs_sb_t, sb_shared_vn), 0 },
- { offsetof(xfs_sb_t, sb_inoalignmt), 0 },
- { offsetof(xfs_sb_t, sb_unit), 0 },
- { offsetof(xfs_sb_t, sb_width), 0 },
- { offsetof(xfs_sb_t, sb_dirblklog), 0 },
- { offsetof(xfs_sb_t, sb_logsectlog), 0 },
- { offsetof(xfs_sb_t, sb_logsectsize),0 },
- { offsetof(xfs_sb_t, sb_logsunit), 0 },
- { offsetof(xfs_sb_t, sb_features2), 0 },
- { sizeof(xfs_sb_t), 0 }
-};
-
-/*
- * Return a pointer to an initialized xfs_mount structure.
- */
-xfs_mount_t *
-xfs_mount_init(void)
-{
- xfs_mount_t *mp;
-
- mp = kmem_zalloc(sizeof(xfs_mount_t), KM_SLEEP);
-
- if (xfs_icsb_init_counters(mp)) {
- mp->m_flags |= XFS_MOUNT_NO_PERCPU_SB;
- }
-
- AIL_LOCKINIT(&mp->m_ail_lock, "xfs_ail");
- spinlock_init(&mp->m_sb_lock, "xfs_sb");
- /* FreeBSD specfic */
- sx_init(&mp->m_ilock, "xfs_mnt");
- initnsema(&mp->m_growlock, 1, "xfs_grow");
- /*
- * Initialize the AIL.
- */
- xfs_trans_ail_init(mp);
-
- atomic_set(&mp->m_active_trans, 0);
-
- return mp;
-}
-
-/*
- * Free up the resources associated with a mount structure. Assume that
- * the structure was initially zeroed, so we can tell which fields got
- * initialized.
- */
-void
-xfs_mount_free(
- xfs_mount_t *mp,
- int remove_bhv)
-{
- if (mp->m_ihash)
- xfs_ihash_free(mp);
- if (mp->m_chash)
- xfs_chash_free(mp);
-
- if (mp->m_perag) {
- int agno;
-
- for (agno = 0; agno < mp->m_maxagi; agno++)
- if (mp->m_perag[agno].pagb_list)
- kmem_free(mp->m_perag[agno].pagb_list,
- sizeof(xfs_perag_busy_t) *
- XFS_PAGB_NUM_SLOTS);
- kmem_free(mp->m_perag,
- sizeof(xfs_perag_t) * mp->m_sb.sb_agcount);
- }
-
- AIL_LOCK_DESTROY(&mp->m_ail_lock);
- spinlock_destroy(&mp->m_sb_lock);
- /* FreeBSD specfic */
- sx_destroy(&mp->m_ilock);
- freesema(&mp->m_growlock);
- if (mp->m_quotainfo)
- XFS_QM_DONE(mp);
-
- if (mp->m_fsname != NULL)
- kmem_free(mp->m_fsname, mp->m_fsname_len);
- if (mp->m_rtname != NULL)
- kmem_free(mp->m_rtname, strlen(mp->m_rtname) + 1);
- if (mp->m_logname != NULL)
- kmem_free(mp->m_logname, strlen(mp->m_logname) + 1);
-
- if (remove_bhv) {
- xfs_vfs_t *vfsp = XFS_MTOVFS(mp);
-
- bhv_remove_all_vfsops(vfsp, 0);
- VFS_REMOVEBHV(vfsp, &mp->m_bhv);
- }
-
- xfs_icsb_destroy_counters(mp);
- kmem_free(mp, sizeof(xfs_mount_t));
-}
-
-
-/*
- * Check the validity of the SB found.
- */
-STATIC int
-xfs_mount_validate_sb(
- xfs_mount_t *mp,
- xfs_sb_t *sbp,
- int flags)
-{
- /*
- * If the log device and data device have the
- * same device number, the log is internal.
- * Consequently, the sb_logstart should be non-zero. If
- * we have a zero sb_logstart in this case, we may be trying to mount
- * a volume filesystem in a non-volume manner.
- */
- if (sbp->sb_magicnum != XFS_SB_MAGIC) {
- xfs_fs_mount_cmn_err(flags, "bad magic number");
- return XFS_ERROR(EWRONGFS);
- }
-
- if (!XFS_SB_GOOD_VERSION(sbp)) {
- xfs_fs_mount_cmn_err(flags, "bad version");
- return XFS_ERROR(EWRONGFS);
- }
-
- if (unlikely(
- sbp->sb_logstart == 0 && mp->m_logdev_targp == mp->m_ddev_targp)) {
- xfs_fs_mount_cmn_err(flags,
- "filesystem is marked as having an external log; "
- "specify logdev on the\nmount command line.");
- return XFS_ERROR(EINVAL);
- }
-
- if (unlikely(
- sbp->sb_logstart != 0 && mp->m_logdev_targp != mp->m_ddev_targp)) {
- xfs_fs_mount_cmn_err(flags,
- "filesystem is marked as having an internal log; "
- "do not specify logdev on\nthe mount command line.");
- return XFS_ERROR(EINVAL);
- }
-
- /*
- * More sanity checking. These were stolen directly from
- * xfs_repair.
- */
- if (unlikely(
- sbp->sb_agcount <= 0 ||
- sbp->sb_sectsize < XFS_MIN_SECTORSIZE ||
- sbp->sb_sectsize > XFS_MAX_SECTORSIZE ||
- sbp->sb_sectlog < XFS_MIN_SECTORSIZE_LOG ||
- sbp->sb_sectlog > XFS_MAX_SECTORSIZE_LOG ||
- sbp->sb_blocksize < XFS_MIN_BLOCKSIZE ||
- sbp->sb_blocksize > XFS_MAX_BLOCKSIZE ||
- sbp->sb_blocklog < XFS_MIN_BLOCKSIZE_LOG ||
- sbp->sb_blocklog > XFS_MAX_BLOCKSIZE_LOG ||
- sbp->sb_inodesize < XFS_DINODE_MIN_SIZE ||
- sbp->sb_inodesize > XFS_DINODE_MAX_SIZE ||
- sbp->sb_inodelog < XFS_DINODE_MIN_LOG ||
- sbp->sb_inodelog > XFS_DINODE_MAX_LOG ||
- (sbp->sb_blocklog - sbp->sb_inodelog != sbp->sb_inopblog) ||
- (sbp->sb_rextsize * sbp->sb_blocksize > XFS_MAX_RTEXTSIZE) ||
- (sbp->sb_rextsize * sbp->sb_blocksize < XFS_MIN_RTEXTSIZE) ||
- (sbp->sb_imax_pct > 100 /* zero sb_imax_pct is valid */))) {
- xfs_fs_mount_cmn_err(flags, "SB sanity check 1 failed");
- return XFS_ERROR(EFSCORRUPTED);
- }
-
- /*
- * Sanity check AG count, size fields against data size field
- */
- if (unlikely(
- sbp->sb_dblocks == 0 ||
- sbp->sb_dblocks >
- (xfs_drfsbno_t)sbp->sb_agcount * sbp->sb_agblocks ||
- sbp->sb_dblocks < (xfs_drfsbno_t)(sbp->sb_agcount - 1) *
- sbp->sb_agblocks + XFS_MIN_AG_BLOCKS)) {
- xfs_fs_mount_cmn_err(flags, "SB sanity check 2 failed");
- return XFS_ERROR(EFSCORRUPTED);
- }
-
- ASSERT(PAGE_SHIFT >= sbp->sb_blocklog);
- ASSERT(sbp->sb_blocklog >= BBSHIFT);
-
-#if XFS_BIG_BLKNOS /* Limited by ULONG_MAX of page cache index */
- if (unlikely(
- (sbp->sb_dblocks >> (PAGE_SHIFT - sbp->sb_blocklog)) > ULONG_MAX ||
- (sbp->sb_rblocks >> (PAGE_SHIFT - sbp->sb_blocklog)) > ULONG_MAX)) {
-#else /* Limited by UINT_MAX of sectors */
- if (unlikely(
- (sbp->sb_dblocks << (sbp->sb_blocklog - BBSHIFT)) > UINT_MAX ||
- (sbp->sb_rblocks << (sbp->sb_blocklog - BBSHIFT)) > UINT_MAX)) {
-#endif
- xfs_fs_mount_cmn_err(flags,
- "file system too large to be mounted on this system.");
- return XFS_ERROR(E2BIG);
- }
-
- if (unlikely(sbp->sb_inprogress)) {
- xfs_fs_mount_cmn_err(flags, "file system busy");
- return XFS_ERROR(EFSCORRUPTED);
- }
-
- /*
- * Version 1 directory format has never worked on Linux.
- */
- if (unlikely(!XFS_SB_VERSION_HASDIRV2(sbp))) {
- xfs_fs_mount_cmn_err(flags,
- "file system using version 1 directory format");
- return XFS_ERROR(ENOSYS);
- }
-
- /*
- * Until this is fixed only page-sized or smaller data blocks work.
- */
- if (unlikely(sbp->sb_blocksize > PAGE_SIZE)) {
- xfs_fs_mount_cmn_err(flags,
- "file system with blocksize %d bytes",
- sbp->sb_blocksize);
- xfs_fs_mount_cmn_err(flags,
- "only pagesize (%ld) or less will currently work.",
- PAGE_SIZE);
- return XFS_ERROR(ENOSYS);
- }
-
- return 0;
-}
-
-xfs_agnumber_t
-xfs_initialize_perag(
- struct xfs_vfs *vfs,
- xfs_mount_t *mp,
- xfs_agnumber_t agcount)
-{
- xfs_agnumber_t index, max_metadata;
- xfs_perag_t *pag;
- xfs_agino_t agino;
- xfs_ino_t ino;
- xfs_sb_t *sbp = &mp->m_sb;
- xfs_ino_t max_inum = XFS_MAXINUMBER_32;
-
- /* Check to see if the filesystem can overflow 32 bit inodes */
- agino = XFS_OFFBNO_TO_AGINO(mp, sbp->sb_agblocks - 1, 0);
- ino = XFS_AGINO_TO_INO(mp, agcount - 1, agino);
-
- /* Clear the mount flag if no inode can overflow 32 bits
- * on this filesystem, or if specifically requested..
- */
- if ((vfs->vfs_flag & VFS_32BITINODES) && ino > max_inum) {
- mp->m_flags |= XFS_MOUNT_32BITINODES;
- } else {
- mp->m_flags &= ~XFS_MOUNT_32BITINODES;
- }
-
- /* If we can overflow then setup the ag headers accordingly */
- if (mp->m_flags & XFS_MOUNT_32BITINODES) {
- /* Calculate how much should be reserved for inodes to
- * meet the max inode percentage.
- */
- if (mp->m_maxicount) {
- __uint64_t icount;
-
- icount = sbp->sb_dblocks * sbp->sb_imax_pct;
- do_div(icount, 100);
- icount += sbp->sb_agblocks - 1;
- do_div(icount, sbp->sb_agblocks);
- max_metadata = icount;
- } else {
- max_metadata = agcount;
- }
- for (index = 0; index < agcount; index++) {
- ino = XFS_AGINO_TO_INO(mp, index, agino);
- if (ino > max_inum) {
- index++;
- break;
- }
-
- /* This ag is preferred for inodes */
- pag = &mp->m_perag[index];
- pag->pagi_inodeok = 1;
- if (index < max_metadata)
- pag->pagf_metadata = 1;
- }
- } else {
- /* Setup default behavior for smaller filesystems */
- for (index = 0; index < agcount; index++) {
- pag = &mp->m_perag[index];
- pag->pagi_inodeok = 1;
- }
- }
- return index;
-}
-
-/*
- * xfs_xlatesb
- *
- * data - on disk version of sb
- * sb - a superblock
- * dir - conversion direction: <0 - convert sb to buf
- * >0 - convert buf to sb
- * fields - which fields to copy (bitmask)
- */
-void
-xfs_xlatesb(
- void *data,
- xfs_sb_t *sb,
- int dir,
- __int64_t fields)
-{
- xfs_caddr_t buf_ptr;
- xfs_caddr_t mem_ptr;
- xfs_sb_field_t f;
- int first;
- int size;
-
- ASSERT(dir);
- ASSERT(fields);
-
- if (!fields)
- return;
-
- buf_ptr = (xfs_caddr_t)data;
- mem_ptr = (xfs_caddr_t)sb;
-
- while (fields) {
- f = (xfs_sb_field_t)xfs_lowbit64((__uint64_t)fields);
- first = xfs_sb_info[f].offset;
- size = xfs_sb_info[f + 1].offset - first;
-
- ASSERT(xfs_sb_info[f].type == 0 || xfs_sb_info[f].type == 1);
-
- if (size == 1 || xfs_sb_info[f].type == 1) {
- if (dir > 0) {
- memcpy(mem_ptr + first, buf_ptr + first, size);
- } else {
- memcpy(buf_ptr + first, mem_ptr + first, size);
- }
- } else {
- switch (size) {
- case 2:
- INT_XLATE(*(__uint16_t*)(buf_ptr+first),
- *(__uint16_t*)(mem_ptr+first),
- dir, ARCH_CONVERT);
- break;
- case 4:
- INT_XLATE(*(__uint32_t*)(buf_ptr+first),
- *(__uint32_t*)(mem_ptr+first),
- dir, ARCH_CONVERT);
- break;
- case 8:
- INT_XLATE(*(__uint64_t*)(buf_ptr+first),
- *(__uint64_t*)(mem_ptr+first), dir, ARCH_CONVERT);
- break;
- default:
- ASSERT(0);
- }
- }
-
- fields &= ~(1LL << f);
- }
-}
-
-/*
- * xfs_readsb
- *
- * Does the initial read of the superblock.
- */
-int
-xfs_readsb(xfs_mount_t *mp, int flags)
-{
- unsigned int sector_size;
- unsigned int extra_flags;
- xfs_buf_t *bp;
- xfs_sb_t *sbp;
- int error;
-
- ASSERT(mp->m_sb_bp == NULL);
- ASSERT(mp->m_ddev_targp != NULL);
-
- /*
- * Allocate a (locked) buffer to hold the superblock.
- * This will be kept around at all times to optimize
- * access to the superblock.
- */
- sector_size = xfs_getsize_buftarg(mp->m_ddev_targp);
- extra_flags = XFS_BUF_LOCK | XFS_BUF_MANAGE | XFS_BUF_MAPPED;
-
- bp = xfs_getsb(mp,0);
-
- if (!bp || XFS_BUF_ISERROR(bp)) {
- xfs_fs_mount_cmn_err(flags, "SB read failed");
- error = bp ? XFS_BUF_GETERROR(bp) : ENOMEM;
- goto fail;
- }
- ASSERT(XFS_BUF_ISBUSY(bp));
- ASSERT(XFS_BUF_VALUSEMA(bp) <= 0);
-
- /*
- * Initialize the mount structure from the superblock.
- * But first do some basic consistency checking.
- */
- sbp = XFS_BUF_TO_SBP(bp);
- xfs_xlatesb(XFS_BUF_PTR(bp), &(mp->m_sb), 1, XFS_SB_ALL_BITS);
-
- error = xfs_mount_validate_sb(mp, &(mp->m_sb), flags);
- if (error) {
- xfs_fs_mount_cmn_err(flags, "SB validate failed");
- goto fail;
- }
-
- /*
- * We must be able to do sector-sized and sector-aligned IO.
- */
- if (sector_size > mp->m_sb.sb_sectsize) {
- xfs_fs_mount_cmn_err(flags,
- "device supports only %u byte sectors (not %u)",
- sector_size, mp->m_sb.sb_sectsize);
- error = ENOSYS;
- goto fail;
- }
-
- /*
- * If device sector size is smaller than the superblock size,
- * re-read the superblock so the buffer is correctly sized.
- */
- if (sector_size < mp->m_sb.sb_sectsize) {
- XFS_BUF_UNMANAGE(bp);
- xfs_buf_relse(bp);
- sector_size = mp->m_sb.sb_sectsize;
- bp = xfs_buf_read_flags(mp->m_ddev_targp, XFS_SB_DADDR,
- BTOBB(sector_size), extra_flags);
- if (!bp || XFS_BUF_ISERROR(bp)) {
- xfs_fs_mount_cmn_err(flags, "SB re-read failed");
- error = bp ? XFS_BUF_GETERROR(bp) : ENOMEM;
- goto fail;
- }
- ASSERT(XFS_BUF_ISBUSY(bp));
- ASSERT(XFS_BUF_VALUSEMA(bp) <= 0);
- }
-
- xfs_icsb_balance_counter(mp, XFS_SBS_ICOUNT, 0);
- xfs_icsb_balance_counter(mp, XFS_SBS_IFREE, 0);
- xfs_icsb_balance_counter(mp, XFS_SBS_FDBLOCKS, 0);
-
- mp->m_sb_bp = bp;
- xfs_buf_relse(bp);
- ASSERT(XFS_BUF_VALUSEMA(bp) > 0);
- return 0;
-
- fail:
- if (bp) {
- XFS_BUF_UNMANAGE(bp);
- xfs_buf_relse(bp);
- }
- return error;
-}
-
-
-/*
- * xfs_mount_common
- *
- * Mount initialization code establishing various mount
- * fields from the superblock associated with the given
- * mount structure
- */
-STATIC void
-xfs_mount_common(xfs_mount_t *mp, xfs_sb_t *sbp)
-{
- int i;
-
- mp->m_agfrotor = mp->m_agirotor = 0;
- spinlock_init(&mp->m_agirotor_lock, "m_agirotor_lock");
- mp->m_maxagi = mp->m_sb.sb_agcount;
- mp->m_blkbit_log = sbp->sb_blocklog + XFS_NBBYLOG;
- mp->m_blkbb_log = sbp->sb_blocklog - BBSHIFT;
- mp->m_sectbb_log = sbp->sb_sectlog - BBSHIFT;
- mp->m_agno_log = xfs_highbit32(sbp->sb_agcount - 1) + 1;
- mp->m_agino_log = sbp->sb_inopblog + sbp->sb_agblklog;
- mp->m_litino = sbp->sb_inodesize -
- ((uint)sizeof(xfs_dinode_core_t) + (uint)sizeof(xfs_agino_t));
- mp->m_blockmask = sbp->sb_blocksize - 1;
- mp->m_blockwsize = sbp->sb_blocksize >> XFS_WORDLOG;
- mp->m_blockwmask = mp->m_blockwsize - 1;
-#ifdef RMC
- INIT_LIST_HEAD(&mp->m_del_inodes);
-#endif
- TAILQ_INIT(&mp->m_del_inodes);
-
- /*
- * Setup for attributes, in case they get created.
- * This value is for inodes getting attributes for the first time,
- * the per-inode value is for old attribute values.
- */
- ASSERT(sbp->sb_inodesize >= 256 && sbp->sb_inodesize <= 2048);
- switch (sbp->sb_inodesize) {
- case 256:
- mp->m_attroffset = XFS_LITINO(mp) -
- XFS_BMDR_SPACE_CALC(MINABTPTRS);
- break;
- case 512:
- case 1024:
- case 2048:
- mp->m_attroffset = XFS_BMDR_SPACE_CALC(6 * MINABTPTRS);
- break;
- default:
- ASSERT(0);
- }
- ASSERT(mp->m_attroffset < XFS_LITINO(mp));
-
- for (i = 0; i < 2; i++) {
- mp->m_alloc_mxr[i] = XFS_BTREE_BLOCK_MAXRECS(sbp->sb_blocksize,
- xfs_alloc, i == 0);
- mp->m_alloc_mnr[i] = XFS_BTREE_BLOCK_MINRECS(sbp->sb_blocksize,
- xfs_alloc, i == 0);
- }
- for (i = 0; i < 2; i++) {
- mp->m_bmap_dmxr[i] = XFS_BTREE_BLOCK_MAXRECS(sbp->sb_blocksize,
- xfs_bmbt, i == 0);
- mp->m_bmap_dmnr[i] = XFS_BTREE_BLOCK_MINRECS(sbp->sb_blocksize,
- xfs_bmbt, i == 0);
- }
- for (i = 0; i < 2; i++) {
- mp->m_inobt_mxr[i] = XFS_BTREE_BLOCK_MAXRECS(sbp->sb_blocksize,
- xfs_inobt, i == 0);
- mp->m_inobt_mnr[i] = XFS_BTREE_BLOCK_MINRECS(sbp->sb_blocksize,
- xfs_inobt, i == 0);
- }
-
- mp->m_bsize = XFS_FSB_TO_BB(mp, 1);
- mp->m_ialloc_inos = (int)MAX((__uint16_t)XFS_INODES_PER_CHUNK,
- sbp->sb_inopblock);
- mp->m_ialloc_blks = mp->m_ialloc_inos >> sbp->sb_inopblog;
-}
-/*
- * xfs_mountfs
- *
- * This function does the following on an initial mount of a file system:
- * - reads the superblock from disk and init the mount struct
- * - if we're a 32-bit kernel, do a size check on the superblock
- * so we don't mount terabyte filesystems
- * - init mount struct realtime fields
- * - allocate inode hash table for fs
- * - init directory manager
- * - perform recovery and init the log manager
- */
-int
-xfs_mountfs(
- xfs_vfs_t *vfsp,
- xfs_mount_t *mp,
- int mfsi_flags)
-{
- xfs_buf_t *bp;
- xfs_sb_t *sbp = &(mp->m_sb);
- xfs_inode_t *rip;
- xfs_vnode_t *rvp = NULL;
- int readio_log, writeio_log;
- xfs_daddr_t d;
- __uint64_t ret64;
- __int64_t update_flags;
- uint quotamount, quotaflags;
- int agno;
- int uuid_mounted = 0;
- int error = 0;
-
- if (mp->m_sb_bp == NULL) {
- if ((error = xfs_readsb(mp, mfsi_flags))) {
- return error;
- }
- }
- xfs_mount_common(mp, sbp);
-
- /*
- * Check if sb_agblocks is aligned at stripe boundary
- * If sb_agblocks is NOT aligned turn off m_dalign since
- * allocator alignment is within an ag, therefore ag has
- * to be aligned at stripe boundary.
- */
- update_flags = 0LL;
- if (mp->m_dalign && !(mfsi_flags & XFS_MFSI_SECOND)) {
- /*
- * If stripe unit and stripe width are not multiples
- * of the fs blocksize turn off alignment.
- */
- if ((BBTOB(mp->m_dalign) & mp->m_blockmask) ||
- (BBTOB(mp->m_swidth) & mp->m_blockmask)) {
- if (mp->m_flags & XFS_MOUNT_RETERR) {
- cmn_err(CE_WARN,
- "XFS: alignment check 1 failed");
- error = XFS_ERROR(EINVAL);
- goto error1;
- }
- mp->m_dalign = mp->m_swidth = 0;
- } else {
- /*
- * Convert the stripe unit and width to FSBs.
- */
- mp->m_dalign = XFS_BB_TO_FSBT(mp, mp->m_dalign);
- if (mp->m_dalign && (sbp->sb_agblocks % mp->m_dalign)) {
- if (mp->m_flags & XFS_MOUNT_RETERR) {
- error = XFS_ERROR(EINVAL);
- goto error1;
- }
- xfs_fs_cmn_err(CE_WARN, mp,
-"stripe alignment turned off: sunit(%d)/swidth(%d) incompatible with agsize(%d)",
- mp->m_dalign, mp->m_swidth,
- sbp->sb_agblocks);
-
- mp->m_dalign = 0;
- mp->m_swidth = 0;
- } else if (mp->m_dalign) {
- mp->m_swidth = XFS_BB_TO_FSBT(mp, mp->m_swidth);
- } else {
- if (mp->m_flags & XFS_MOUNT_RETERR) {
- xfs_fs_cmn_err(CE_WARN, mp,
-"stripe alignment turned off: sunit(%d) less than bsize(%d)",
- mp->m_dalign,
- mp->m_blockmask +1);
- error = XFS_ERROR(EINVAL);
- goto error1;
- }
- mp->m_swidth = 0;
- }
- }
-
- /*
- * Update superblock with new values
- * and log changes
- */
- if (XFS_SB_VERSION_HASDALIGN(sbp)) {
- if (sbp->sb_unit != mp->m_dalign) {
- sbp->sb_unit = mp->m_dalign;
- update_flags |= XFS_SB_UNIT;
- }
- if (sbp->sb_width != mp->m_swidth) {
- sbp->sb_width = mp->m_swidth;
- update_flags |= XFS_SB_WIDTH;
- }
- }
- } else if ((mp->m_flags & XFS_MOUNT_NOALIGN) != XFS_MOUNT_NOALIGN &&
- XFS_SB_VERSION_HASDALIGN(&mp->m_sb)) {
- mp->m_dalign = sbp->sb_unit;
- mp->m_swidth = sbp->sb_width;
- }
-
- xfs_alloc_compute_maxlevels(mp);
- xfs_bmap_compute_maxlevels(mp, XFS_DATA_FORK);
- xfs_bmap_compute_maxlevels(mp, XFS_ATTR_FORK);
- xfs_ialloc_compute_maxlevels(mp);
-
- if (sbp->sb_imax_pct) {
- __uint64_t icount;
-
- /* Make sure the maximum inode count is a multiple of the
- * units we allocate inodes in.
- */
-
- icount = sbp->sb_dblocks * sbp->sb_imax_pct;
- do_div(icount, 100);
- do_div(icount, mp->m_ialloc_blks);
- mp->m_maxicount = (icount * mp->m_ialloc_blks) <<
- sbp->sb_inopblog;
- } else
- mp->m_maxicount = 0;
-
- mp->m_maxioffset = xfs_max_file_offset(sbp->sb_blocklog);
-
- /*
- * XFS uses the uuid from the superblock as the unique
- * identifier for fsid. We can not use the uuid from the volume
- * since a single partition filesystem is identical to a single
- * partition volume/filesystem.
- */
- if ((mfsi_flags & XFS_MFSI_SECOND) == 0 &&
- (mp->m_flags & XFS_MOUNT_NOUUID) == 0) {
- if (xfs_uuid_mount(mp)) {
- error = XFS_ERROR(EINVAL);
- goto error1;
- }
- uuid_mounted=1;
- ret64 = uuid_hash64(&sbp->sb_uuid);
- memcpy(&vfsp->vfs_fsid, &ret64, sizeof(ret64));
- }
-
- /*
- * Set the default minimum read and write sizes unless
- * already specified in a mount option.
- * We use smaller I/O sizes when the file system
- * is being used for NFS service (wsync mount option).
- */
- if (!(mp->m_flags & XFS_MOUNT_DFLT_IOSIZE)) {
- if (mp->m_flags & XFS_MOUNT_WSYNC) {
- readio_log = XFS_WSYNC_READIO_LOG;
- writeio_log = XFS_WSYNC_WRITEIO_LOG;
- } else {
- readio_log = XFS_READIO_LOG_LARGE;
- writeio_log = XFS_WRITEIO_LOG_LARGE;
- }
- } else {
- readio_log = mp->m_readio_log;
- writeio_log = mp->m_writeio_log;
- }
-
- /*
- * Set the number of readahead buffers to use based on
- * physical memory size.
- */
- if (xfs_physmem <= 4096) /* <= 16MB */
- mp->m_nreadaheads = XFS_RW_NREADAHEAD_16MB;
- else if (xfs_physmem <= 8192) /* <= 32MB */
- mp->m_nreadaheads = XFS_RW_NREADAHEAD_32MB;
- else
- mp->m_nreadaheads = XFS_RW_NREADAHEAD_K32;
- if (sbp->sb_blocklog > readio_log) {
- mp->m_readio_log = sbp->sb_blocklog;
- } else {
- mp->m_readio_log = readio_log;
- }
- mp->m_readio_blocks = 1 << (mp->m_readio_log - sbp->sb_blocklog);
- if (sbp->sb_blocklog > writeio_log) {
- mp->m_writeio_log = sbp->sb_blocklog;
- } else {
- mp->m_writeio_log = writeio_log;
- }
- mp->m_writeio_blocks = 1 << (mp->m_writeio_log - sbp->sb_blocklog);
-
- /*
- * Set the inode cluster size based on the physical memory
- * size. This may still be overridden by the file system
- * block size if it is larger than the chosen cluster size.
- */
- if (xfs_physmem <= btoc(32 * 1024 * 1024)) { /* <= 32 MB */
- mp->m_inode_cluster_size = XFS_INODE_SMALL_CLUSTER_SIZE;
- } else {
- mp->m_inode_cluster_size = XFS_INODE_BIG_CLUSTER_SIZE;
- }
- /*
- * Set whether we're using inode alignment.
- */
- if (XFS_SB_VERSION_HASALIGN(&mp->m_sb) &&
- mp->m_sb.sb_inoalignmt >=
- XFS_B_TO_FSBT(mp, mp->m_inode_cluster_size))
- mp->m_inoalign_mask = mp->m_sb.sb_inoalignmt - 1;
- else
- mp->m_inoalign_mask = 0;
- /*
- * If we are using stripe alignment, check whether
- * the stripe unit is a multiple of the inode alignment
- */
- if (mp->m_dalign && mp->m_inoalign_mask &&
- !(mp->m_dalign & mp->m_inoalign_mask))
- mp->m_sinoalign = mp->m_dalign;
- else
- mp->m_sinoalign = 0;
- /*
- * Check that the data (and log if separate) are an ok size.
- */
- d = (xfs_daddr_t)XFS_FSB_TO_BB(mp, mp->m_sb.sb_dblocks);
- if (XFS_BB_TO_FSB(mp, d) != mp->m_sb.sb_dblocks) {
- cmn_err(CE_WARN, "XFS: size check 1 failed");
- error = XFS_ERROR(E2BIG);
- goto error1;
- }
- error = xfs_read_buf(mp, mp->m_ddev_targp,
- d - XFS_FSS_TO_BB(mp, 1),
- XFS_FSS_TO_BB(mp, 1), 0, &bp);
- if (!error) {
- xfs_buf_relse(bp);
- } else {
- cmn_err(CE_WARN, "XFS: size check 2 failed");
- if (error == ENOSPC) {
- error = XFS_ERROR(E2BIG);
- }
- goto error1;
- }
-
- if (((mfsi_flags & XFS_MFSI_CLIENT) == 0) &&
- mp->m_logdev_targp != mp->m_ddev_targp) {
- d = (xfs_daddr_t)XFS_FSB_TO_BB(mp, mp->m_sb.sb_logblocks);
- if (XFS_BB_TO_FSB(mp, d) != mp->m_sb.sb_logblocks) {
- cmn_err(CE_WARN, "XFS: size check 3 failed");
- error = XFS_ERROR(E2BIG);
- goto error1;
- }
- error = xfs_read_buf(mp, mp->m_logdev_targp,
- d - XFS_FSB_TO_BB(mp, 1),
- XFS_FSB_TO_BB(mp, 1), 0, &bp);
- if (!error) {
- xfs_buf_relse(bp);
- } else {
- cmn_err(CE_WARN, "XFS: size check 3 failed");
- if (error == ENOSPC) {
- error = XFS_ERROR(E2BIG);
- }
- goto error1;
- }
- }
-
- /*
- * Initialize realtime fields in the mount structure
- */
- if ((error = xfs_rtmount_init(mp))) {
- cmn_err(CE_WARN, "XFS: RT mount failed");
- goto error1;
- }
-
- /*
- * For client case we are done now
- */
- if (mfsi_flags & XFS_MFSI_CLIENT) {
- return 0;
- }
-
- /*
- * Copies the low order bits of the timestamp and the randomly
- * set "sequence" number out of a UUID.
- */
- uuid_getnodeuniq(&sbp->sb_uuid, mp->m_fixedfsid);
-
- /*
- * The vfs structure needs to have a file system independent
- * way of checking for the invariant file system ID. Since it
- * can't look at mount structures it has a pointer to the data
- * in the mount structure.
- *
- * File systems that don't support user level file handles (i.e.
- * all of them except for XFS) will leave vfs_altfsid as NULL.
- */
- vfsp->vfs_altfsid = (xfs_fsid_t *)mp->m_fixedfsid;
- mp->m_dmevmask = 0; /* not persistent; set after each mount */
-
- /*
- * Select the right directory manager.
- */
- mp->m_dirops =
- XFS_SB_VERSION_HASDIRV2(&mp->m_sb) ?
- xfsv2_dirops :
- xfsv1_dirops;
-
- /*
- * Initialize directory manager's entries.
- */
- XFS_DIR_MOUNT(mp);
-
- /*
- * Initialize the attribute manager's entries.
- */
- mp->m_attr_magicpct = (mp->m_sb.sb_blocksize * 37) / 100;
-
- /*
- * Initialize the precomputed transaction reservations values.
- */
- xfs_trans_init(mp);
-
- /*
- * Allocate and initialize the inode hash table for this
- * file system.
- */
- xfs_ihash_init(mp);
- xfs_chash_init(mp);
-
- /*
- * Allocate and initialize the per-ag data.
- */
- init_rwsem(&mp->m_peraglock);
- mp->m_perag =
- kmem_zalloc(sbp->sb_agcount * sizeof(xfs_perag_t), KM_SLEEP);
-
- mp->m_maxagi = xfs_initialize_perag(vfsp, mp, sbp->sb_agcount);
-
- /*
- * log's mount-time initialization. Perform 1st part recovery if needed
- */
- if (likely(sbp->sb_logblocks > 0)) { /* check for volume case */
- error = xfs_log_mount(mp, mp->m_logdev_targp,
- XFS_FSB_TO_DADDR(mp, sbp->sb_logstart),
- XFS_FSB_TO_BB(mp, sbp->sb_logblocks));
- if (error) {
- cmn_err(CE_WARN, "XFS: log mount failed");
- goto error2;
- }
- } else { /* No log has been defined */
- cmn_err(CE_WARN, "XFS: no log defined");
- XFS_ERROR_REPORT("xfs_mountfs_int(1)", XFS_ERRLEVEL_LOW, mp);
- error = XFS_ERROR(EFSCORRUPTED);
- goto error2;
- }
-
- /*
- * Get and sanity-check the root inode.
- * Save the pointer to it in the mount structure.
- */
- error = xfs_iget(mp, NULL, sbp->sb_rootino, 0, XFS_ILOCK_EXCL, &rip, 0);
- if (error) {
- cmn_err(CE_WARN, "XFS: failed to read root inode");
- goto error3;
- }
-
- ASSERT(rip != NULL);
- rvp = XFS_ITOV(rip);
-
- if (unlikely((rip->i_d.di_mode & S_IFMT) != S_IFDIR)) {
- cmn_err(CE_WARN, "XFS: corrupted root inode");
- printf("Root inode %p is not a directory: %llu",
- mp->m_ddev_targp, (unsigned long long)rip->i_ino);
- xfs_iunlock(rip, XFS_ILOCK_EXCL);
- XFS_ERROR_REPORT("xfs_mountfs_int(2)", XFS_ERRLEVEL_LOW,
- mp);
- error = XFS_ERROR(EFSCORRUPTED);
- goto error4;
- }
- mp->m_rootip = rip; /* save it */
-
- xfs_iunlock(rip, XFS_ILOCK_EXCL);
-
- /*
- * Initialize realtime inode pointers in the mount structure
- */
- if ((error = xfs_rtmount_inodes(mp))) {
- /*
- * Free up the root inode.
- */
- cmn_err(CE_WARN, "XFS: failed to read RT inodes");
- goto error4;
- }
-
- /*
- * If fs is not mounted readonly, then update the superblock
- * unit and width changes.
- */
- if (update_flags && !(vfsp->vfs_flag & VFS_RDONLY))
- xfs_mount_log_sbunit(mp, update_flags);
-
- /*
- * Initialise the XFS quota management subsystem for this mount
- */
- if ((error = XFS_QM_INIT(mp, &quotamount, &quotaflags)))
- goto error4;
-
- /*
- * Finish recovering the file system. This part needed to be
- * delayed until after the root and real-time bitmap inodes
- * were consistently read in.
- */
- error = xfs_log_mount_finish(mp, mfsi_flags);
- if (error) {
- cmn_err(CE_WARN, "XFS: log mount finish failed");
- goto error4;
- }
-
- /*
- * Complete the quota initialisation, post-log-replay component.
- */
- if ((error = XFS_QM_MOUNT(mp, quotamount, quotaflags, mfsi_flags)))
- goto error4;
-
- return 0;
-
- error4:
- /*
- * Free up the root inode.
- */
- VN_RELE(rvp);
- error3:
- xfs_log_unmount_dealloc(mp);
- error2:
- xfs_ihash_free(mp);
- xfs_chash_free(mp);
- for (agno = 0; agno < sbp->sb_agcount; agno++)
- if (mp->m_perag[agno].pagb_list)
- kmem_free(mp->m_perag[agno].pagb_list,
- sizeof(xfs_perag_busy_t) * XFS_PAGB_NUM_SLOTS);
- kmem_free(mp->m_perag, sbp->sb_agcount * sizeof(xfs_perag_t));
- mp->m_perag = NULL;
- /* FALLTHROUGH */
- error1:
- if (uuid_mounted)
- xfs_uuid_unmount(mp);
- xfs_freesb(mp);
- return error;
-}
-
-/*
- * xfs_unmountfs
- *
- * This flushes out the inodes,dquots and the superblock, unmounts the
- * log and makes sure that incore structures are freed.
- */
-int
-xfs_unmountfs(xfs_mount_t *mp, struct cred *cr)
-{
- struct xfs_vfs *vfsp = XFS_MTOVFS(mp);
-#if defined(DEBUG) || defined(INDUCE_IO_ERROR)
- int64_t fsid;
-#endif
-
- xfs_iflush_all(mp);
-
- XFS_QM_DQPURGEALL(mp, XFS_QMOPT_QUOTALL | XFS_QMOPT_UMOUNTING);
-
- /*
- * Flush out the log synchronously so that we know for sure
- * that nothing is pinned. This is important because bflush()
- * will skip pinned buffers.
- */
- xfs_log_force(mp, (xfs_lsn_t)0, XFS_LOG_FORCE | XFS_LOG_SYNC);
-
- xfs_binval(mp->m_ddev_targp);
- if (mp->m_rtdev_targp) {
- xfs_binval(mp->m_rtdev_targp);
- }
-
- xfs_unmountfs_writesb(mp);
-
- xfs_unmountfs_wait(mp); /* wait for async bufs */
-
- xfs_log_unmount(mp); /* Done! No more fs ops. */
-
- xfs_freesb(mp);
-
- /*
- * All inodes from this mount point should be freed.
- */
- //ASSERT(mp->m_inodes == NULL);
- if (mp->m_inodes != NULL ) {
- printf("WRONG: mp->m_ireclaims: %d\n", mp->m_ireclaims);
- printf("WRONG: mp->m_inodes: %p\n", mp->m_inodes);
- }
-
- xfs_unmountfs_close(mp, cr);
- if ((mp->m_flags & XFS_MOUNT_NOUUID) == 0)
- xfs_uuid_unmount(mp);
-
-#if defined(DEBUG) || defined(INDUCE_IO_ERROR)
- /*
- * clear all error tags on this filesystem
- */
- memcpy(&fsid, &vfsp->vfs_fsid, sizeof(int64_t));
- xfs_errortag_clearall_umount(fsid, mp->m_fsname, 0);
-#endif
- XFS_IODONE(vfsp);
- xfs_mount_free(mp, 1);
- return 0;
-}
-
-void
-xfs_unmountfs_close(xfs_mount_t *mp, struct cred *cr)
-{
- if (mp->m_logdev_targp != mp->m_ddev_targp)
- xfs_free_buftarg(mp->m_logdev_targp, 1);
- if (mp->m_rtdev_targp)
- xfs_free_buftarg(mp->m_rtdev_targp, 1);
- xfs_free_buftarg(mp->m_ddev_targp, 0);
-}
-
-STATIC void
-xfs_unmountfs_wait(xfs_mount_t *mp)
-{
- if (mp->m_logdev_targp != mp->m_ddev_targp)
- xfs_wait_buftarg(mp->m_logdev_targp);
- if (mp->m_rtdev_targp)
- xfs_wait_buftarg(mp->m_rtdev_targp);
- xfs_wait_buftarg(mp->m_ddev_targp);
-}
-
-int
-xfs_unmountfs_writesb(xfs_mount_t *mp)
-{
- xfs_buf_t *sbp;
- xfs_sb_t *sb;
- int error = 0;
-
- /*
- * skip superblock write if fs is read-only, or
- * if we are doing a forced umount.
- */
- sbp = xfs_getsb(mp, 0);
- if (!(XFS_MTOVFS(mp)->vfs_flag & VFS_RDONLY ||
- XFS_FORCED_SHUTDOWN(mp))) {
-
- xfs_icsb_sync_counters(mp);
-
- /*
- * mark shared-readonly if desired
- */
- sb = XFS_BUF_TO_SBP(sbp);
- if (mp->m_mk_sharedro) {
- if (!(sb->sb_flags & XFS_SBF_READONLY))
- sb->sb_flags |= XFS_SBF_READONLY;
- if (!XFS_SB_VERSION_HASSHARED(sb))
- XFS_SB_VERSION_ADDSHARED(sb);
- xfs_fs_cmn_err(CE_NOTE, mp,
- "Unmounting, marking shared read-only");
- }
- XFS_BUF_UNDONE(sbp);
- XFS_BUF_UNREAD(sbp);
- XFS_BUF_UNDELAYWRITE(sbp);
- XFS_BUF_WRITE(sbp);
- XFS_BUF_UNASYNC(sbp);
- ASSERT(XFS_BUF_TARGET(sbp) == mp->m_ddev_targp);
- xfsbdstrat(mp, sbp);
- /* Nevermind errors we might get here. */
- error = xfs_iowait(sbp);
- if (error)
- xfs_ioerror_alert("xfs_unmountfs_writesb",
- mp, sbp, XFS_BUF_ADDR(sbp));
- if (error && mp->m_mk_sharedro)
- xfs_fs_cmn_err(CE_ALERT, mp, "Superblock write error detected while unmounting. Filesystem may not be marked shared readonly");
- }
- xfs_buf_relse(sbp);
- return error;
-}
-
-/*
- * xfs_mod_sb() can be used to copy arbitrary changes to the
- * in-core superblock into the superblock buffer to be logged.
- * It does not provide the higher level of locking that is
- * needed to protect the in-core superblock from concurrent
- * access.
- */
-void
-xfs_mod_sb(xfs_trans_t *tp, __int64_t fields)
-{
- xfs_buf_t *bp;
- int first;
- int last;
- xfs_mount_t *mp;
- xfs_sb_t *sbp;
- xfs_sb_field_t f;
-
- ASSERT(fields);
- if (!fields)
- return;
- mp = tp->t_mountp;
- bp = xfs_trans_getsb(tp, mp, 0);
- sbp = XFS_BUF_TO_SBP(bp);
- first = sizeof(xfs_sb_t);
- last = 0;
-
- /* translate/copy */
-
- xfs_xlatesb(XFS_BUF_PTR(bp), &(mp->m_sb), -1, fields);
-
- /* find modified range */
-
- f = (xfs_sb_field_t)xfs_lowbit64((__uint64_t)fields);
- ASSERT((1LL << f) & XFS_SB_MOD_BITS);
- first = xfs_sb_info[f].offset;
-
- f = (xfs_sb_field_t)xfs_highbit64((__uint64_t)fields);
- ASSERT((1LL << f) & XFS_SB_MOD_BITS);
- last = xfs_sb_info[f + 1].offset - 1;
-
- xfs_trans_log_buf(tp, bp, first, last);
-}
-/*
- * xfs_mod_incore_sb_unlocked() is a utility routine common used to apply
- * a delta to a specified field in the in-core superblock. Simply
- * switch on the field indicated and apply the delta to that field.
- * Fields are not allowed to dip below zero, so if the delta would
- * do this do not apply it and return EINVAL.
- *
- * The SB_LOCK must be held when this routine is called.
- */
-int
-xfs_mod_incore_sb_unlocked(xfs_mount_t *mp, xfs_sb_field_t field,
- int delta, int rsvd)
-{
- int scounter; /* short counter for 32 bit fields */
- long long lcounter; /* long counter for 64 bit fields */
- long long res_used, rem;
-
- /*
- * With the in-core superblock spin lock held, switch
- * on the indicated field. Apply the delta to the
- * proper field. If the fields value would dip below
- * 0, then do not apply the delta and return EINVAL.
- */
- switch (field) {
- case XFS_SBS_ICOUNT:
- lcounter = (long long)mp->m_sb.sb_icount;
- lcounter += delta;
- if (lcounter < 0) {
- ASSERT(0);
- return XFS_ERROR(EINVAL);
- }
- mp->m_sb.sb_icount = lcounter;
- return 0;
- case XFS_SBS_IFREE:
- lcounter = (long long)mp->m_sb.sb_ifree;
- lcounter += delta;
- if (lcounter < 0) {
- ASSERT(0);
- return XFS_ERROR(EINVAL);
- }
- mp->m_sb.sb_ifree = lcounter;
- return 0;
- case XFS_SBS_FDBLOCKS:
-
- lcounter = (long long)mp->m_sb.sb_fdblocks;
- res_used = (long long)(mp->m_resblks - mp->m_resblks_avail);
-
- if (delta > 0) { /* Putting blocks back */
- if (res_used > delta) {
- mp->m_resblks_avail += delta;
- } else {
- rem = delta - res_used;
- mp->m_resblks_avail = mp->m_resblks;
- lcounter += rem;
- }
- } else { /* Taking blocks away */
-
- lcounter += delta;
-
- /*
- * If were out of blocks, use any available reserved blocks if
- * were allowed to.
- */
-
- if (lcounter < 0) {
- if (rsvd) {
- lcounter = (long long)mp->m_resblks_avail + delta;
- if (lcounter < 0) {
- return XFS_ERROR(ENOSPC);
- }
- mp->m_resblks_avail = lcounter;
- return 0;
- } else { /* not reserved */
- return XFS_ERROR(ENOSPC);
- }
- }
- }
-
- mp->m_sb.sb_fdblocks = lcounter;
- return 0;
- case XFS_SBS_FREXTENTS:
- lcounter = (long long)mp->m_sb.sb_frextents;
- lcounter += delta;
- if (lcounter < 0) {
- return XFS_ERROR(ENOSPC);
- }
- mp->m_sb.sb_frextents = lcounter;
- return 0;
- case XFS_SBS_DBLOCKS:
- lcounter = (long long)mp->m_sb.sb_dblocks;
- lcounter += delta;
- if (lcounter < 0) {
- ASSERT(0);
- return XFS_ERROR(EINVAL);
- }
- mp->m_sb.sb_dblocks = lcounter;
- return 0;
- case XFS_SBS_AGCOUNT:
- scounter = mp->m_sb.sb_agcount;
- scounter += delta;
- if (scounter < 0) {
- ASSERT(0);
- return XFS_ERROR(EINVAL);
- }
- mp->m_sb.sb_agcount = scounter;
- return 0;
- case XFS_SBS_IMAX_PCT:
- scounter = mp->m_sb.sb_imax_pct;
- scounter += delta;
- if (scounter < 0) {
- ASSERT(0);
- return XFS_ERROR(EINVAL);
- }
- mp->m_sb.sb_imax_pct = scounter;
- return 0;
- case XFS_SBS_REXTSIZE:
- scounter = mp->m_sb.sb_rextsize;
- scounter += delta;
- if (scounter < 0) {
- ASSERT(0);
- return XFS_ERROR(EINVAL);
- }
- mp->m_sb.sb_rextsize = scounter;
- return 0;
- case XFS_SBS_RBMBLOCKS:
- scounter = mp->m_sb.sb_rbmblocks;
- scounter += delta;
- if (scounter < 0) {
- ASSERT(0);
- return XFS_ERROR(EINVAL);
- }
- mp->m_sb.sb_rbmblocks = scounter;
- return 0;
- case XFS_SBS_RBLOCKS:
- lcounter = (long long)mp->m_sb.sb_rblocks;
- lcounter += delta;
- if (lcounter < 0) {
- ASSERT(0);
- return XFS_ERROR(EINVAL);
- }
- mp->m_sb.sb_rblocks = lcounter;
- return 0;
- case XFS_SBS_REXTENTS:
- lcounter = (long long)mp->m_sb.sb_rextents;
- lcounter += delta;
- if (lcounter < 0) {
- ASSERT(0);
- return XFS_ERROR(EINVAL);
- }
- mp->m_sb.sb_rextents = lcounter;
- return 0;
- case XFS_SBS_REXTSLOG:
- scounter = mp->m_sb.sb_rextslog;
- scounter += delta;
- if (scounter < 0) {
- ASSERT(0);
- return XFS_ERROR(EINVAL);
- }
- mp->m_sb.sb_rextslog = scounter;
- return 0;
- default:
- ASSERT(0);
- return XFS_ERROR(EINVAL);
- }
-}
-
-/*
- * xfs_mod_incore_sb() is used to change a field in the in-core
- * superblock structure by the specified delta. This modification
- * is protected by the SB_LOCK. Just use the xfs_mod_incore_sb_unlocked()
- * routine to do the work.
- */
-int
-xfs_mod_incore_sb(xfs_mount_t *mp, xfs_sb_field_t field, int delta, int rsvd)
-{
- unsigned long s;
- int status;
-
- /* check for per-cpu counters */
- switch (field) {
-#ifdef HAVE_PERCPU_SB
- case XFS_SBS_ICOUNT:
- case XFS_SBS_IFREE:
- case XFS_SBS_FDBLOCKS:
- if (!(mp->m_flags & XFS_MOUNT_NO_PERCPU_SB)) {
- status = xfs_icsb_modify_counters(mp, field,
- delta, rsvd);
- break;
- }
- /* FALLTHROUGH */
-#endif
- default:
- s = XFS_SB_LOCK(mp);
- status = xfs_mod_incore_sb_unlocked(mp, field, delta, rsvd);
- XFS_SB_UNLOCK(mp, s);
- break;
- }
-
- return status;
-}
-
-/*
- * xfs_mod_incore_sb_batch() is used to change more than one field
- * in the in-core superblock structure at a time. This modification
- * is protected by a lock internal to this module. The fields and
- * changes to those fields are specified in the array of xfs_mod_sb
- * structures passed in.
- *
- * Either all of the specified deltas will be applied or none of
- * them will. If any modified field dips below 0, then all modifications
- * will be backed out and EINVAL will be returned.
- */
-int
-xfs_mod_incore_sb_batch(xfs_mount_t *mp, xfs_mod_sb_t *msb, uint nmsb, int rsvd)
-{
- unsigned long s;
- int status=0;
- xfs_mod_sb_t *msbp;
-
- /*
- * Loop through the array of mod structures and apply each
- * individually. If any fail, then back out all those
- * which have already been applied. Do all of this within
- * the scope of the SB_LOCK so that all of the changes will
- * be atomic.
- */
- s = XFS_SB_LOCK(mp);
- msbp = &msb[0];
- for (msbp = &msbp[0]; msbp < (msb + nmsb); msbp++) {
- /*
- * Apply the delta at index n. If it fails, break
- * from the loop so we'll fall into the undo loop
- * below.
- */
- switch (msbp->msb_field) {
-#ifdef HAVE_PERCPU_SB
- case XFS_SBS_ICOUNT:
- case XFS_SBS_IFREE:
- case XFS_SBS_FDBLOCKS:
- if (!(mp->m_flags & XFS_MOUNT_NO_PERCPU_SB)) {
- status = xfs_icsb_modify_counters_locked(mp,
- msbp->msb_field,
- msbp->msb_delta, rsvd);
- break;
- }
- /* FALLTHROUGH */
-#endif
- default:
- status = xfs_mod_incore_sb_unlocked(mp,
- msbp->msb_field,
- msbp->msb_delta, rsvd);
- break;
- }
-
- if (status != 0) {
- break;
- }
- }
-
- /*
- * If we didn't complete the loop above, then back out
- * any changes made to the superblock. If you add code
- * between the loop above and here, make sure that you
- * preserve the value of status. Loop back until
- * we step below the beginning of the array. Make sure
- * we don't touch anything back there.
- */
- if (status != 0) {
- msbp--;
- while (msbp >= msb) {
- switch (msbp->msb_field) {
-#ifdef HAVE_PERCPU_SB
- case XFS_SBS_ICOUNT:
- case XFS_SBS_IFREE:
- case XFS_SBS_FDBLOCKS:
- if (!(mp->m_flags & XFS_MOUNT_NO_PERCPU_SB)) {
- status =
- xfs_icsb_modify_counters_locked(mp,
- msbp->msb_field,
- -(msbp->msb_delta),
- rsvd);
- break;
- }
- /* FALLTHROUGH */
-#endif
- default:
- status = xfs_mod_incore_sb_unlocked(mp,
- msbp->msb_field,
- -(msbp->msb_delta),
- rsvd);
- break;
- }
- ASSERT(status == 0);
- msbp--;
- }
- }
- XFS_SB_UNLOCK(mp, s);
- return status;
-}
-
-/*
- * xfs_getsb() is called to obtain the buffer for the superblock.
- * The buffer is returned locked and read in from disk.
- * The buffer should be released with a call to xfs_brelse().
- *
- * If the flags parameter is BUF_TRYLOCK, then we'll only return
- * the superblock buffer if it can be locked without sleeping.
- * If it can't then we'll return NULL.
- */
-xfs_buf_t *
-xfs_getsb(
- xfs_mount_t *mp,
- int flags)
-{
- xfs_buf_t *bp;
- int extra_flags = 0;
- unsigned int sector_size;
-
-
- bp = mp->m_sb_bp;
- sector_size = xfs_getsize_buftarg(mp->m_ddev_targp);
-#ifdef NOT
- /* MANAGED buf's appear broken in FreeBSD
- * but it's unclear if we need a persistant superblock?
- * since we now translate the ondisk superblock to
- * a separate translated structure and then translate that
- * structure back when we want to write the superblock
- */
- extra_flags = XFS_BUF_LOCK | XFS_BUF_MANAGE | XFS_BUF_MAPPED;
- extra_flags = XFS_BUF_MANAGE;
-#endif
-
- mp->m_sb_bp = bp
- = xfs_buf_read_flags(mp->m_ddev_targp,
- XFS_SB_DADDR,
- BTOBB(sector_size),
- extra_flags);
-
- XFS_BUF_HOLD(bp);
- ASSERT(XFS_BUF_ISDONE(bp));
- if (!XFS_BUF_ISDONE(bp)){
- printf("xfs_getsb: %p bp flags 0x%x\n",bp,bp->b_flags);
- }
- return bp;
-}
-
-/*
- * Used to free the superblock along various error paths.
- */
-void
-xfs_freesb(
- xfs_mount_t *mp)
-{
- xfs_buf_t *bp;
-
- /*
- * Use xfs_getsb() so that the buffer will be locked
- * when we call xfs_buf_relse().
- */
- bp = xfs_getsb(mp, 0);
- XFS_BUF_UNMANAGE(bp);
- xfs_buf_relse(bp);
- mp->m_sb_bp = NULL;
-}
-
-/*
- * See if the UUID is unique among mounted XFS filesystems.
- * Mount fails if UUID is nil or a FS with the same UUID is already mounted.
- */
-STATIC int
-xfs_uuid_mount(
- xfs_mount_t *mp)
-{
- if (uuid_is_nil(&mp->m_sb.sb_uuid)) {
- cmn_err(CE_WARN,
- "XFS: Filesystem %s has nil UUID - can't mount",
- mp->m_fsname);
- return -1;
- }
- if (!uuid_table_insert(&mp->m_sb.sb_uuid)) {
- cmn_err(CE_WARN,
- "XFS: Filesystem %s has duplicate UUID - can't mount",
- mp->m_fsname);
- return -1;
- }
- return 0;
-}
-
-/*
- * Remove filesystem from the UUID table.
- */
-STATIC void
-xfs_uuid_unmount(
- xfs_mount_t *mp)
-{
- uuid_table_remove(&mp->m_sb.sb_uuid);
-}
-
-/*
- * Used to log changes to the superblock unit and width fields which could
- * be altered by the mount options. Only the first superblock is updated.
- */
-STATIC void
-xfs_mount_log_sbunit(
- xfs_mount_t *mp,
- __int64_t fields)
-{
- xfs_trans_t *tp;
-
- ASSERT(fields & (XFS_SB_UNIT|XFS_SB_WIDTH|XFS_SB_UUID));
-
- tp = xfs_trans_alloc(mp, XFS_TRANS_SB_UNIT);
- if (xfs_trans_reserve(tp, 0, mp->m_sb.sb_sectsize + 128, 0, 0,
- XFS_DEFAULT_LOG_COUNT)) {
- xfs_trans_cancel(tp, 0);
- return;
- }
- xfs_mod_sb(tp, fields);
- xfs_trans_commit(tp, 0, NULL);
-}
-
-
-#ifdef HAVE_PERCPU_SB
-/*
- * Per-cpu incore superblock counters
- *
- * Simple concept, difficult implementation
- *
- * Basically, replace the incore superblock counters with a distributed per cpu
- * counter for contended fields (e.g. free block count).
- *
- * Difficulties arise in that the incore sb is used for ENOSPC checking, and
- * hence needs to be accurately read when we are running low on space. Hence
- * there is a method to enable and disable the per-cpu counters based on how
- * much "stuff" is available in them.
- *
- * Basically, a counter is enabled if there is enough free resource to justify
- * running a per-cpu fast-path. If the per-cpu counter runs out (i.e. a local
- * ENOSPC), then we disable the counters to synchronise all callers and
- * re-distribute the available resources.
- *
- * If, once we redistributed the available resources, we still get a failure,
- * we disable the per-cpu counter and go through the slow path.
- *
- * The slow path is the current xfs_mod_incore_sb() function. This means that
- * when we disable a per-cpu counter, we need to drain it's resources back to
- * the global superblock. We do this after disabling the counter to prevent
- * more threads from queueing up on the counter.
- *
- * Essentially, this means that we still need a lock in the fast path to enable
- * synchronisation between the global counters and the per-cpu counters. This
- * is not a problem because the lock will be local to a CPU almost all the time
- * and have little contention except when we get to ENOSPC conditions.
- *
- * Basically, this lock becomes a barrier that enables us to lock out the fast
- * path while we do things like enabling and disabling counters and
- * synchronising the counters.
- *
- * Locking rules:
- *
- * 1. XFS_SB_LOCK() before picking up per-cpu locks
- * 2. per-cpu locks always picked up via for_each_online_cpu() order
- * 3. accurate counter sync requires XFS_SB_LOCK + per cpu locks
- * 4. modifying per-cpu counters requires holding per-cpu lock
- * 5. modifying global counters requires holding XFS_SB_LOCK
- * 6. enabling or disabling a counter requires holding the XFS_SB_LOCK
- * and _none_ of the per-cpu locks.
- *
- * Disabled counters are only ever re-enabled by a balance operation
- * that results in more free resources per CPU than a given threshold.
- * To ensure counters don't remain disabled, they are rebalanced when
- * the global resource goes above a higher threshold (i.e. some hysteresis
- * is present to prevent thrashing).
- */
-
-/*
- * hot-plug CPU notifier support.
- *
- * We cannot use the hotcpu_register() function because it does
- * not allow notifier instances. We need a notifier per filesystem
- * as we need to be able to identify the filesystem to balance
- * the counters out. This is achieved by having a notifier block
- * embedded in the xfs_mount_t and doing pointer magic to get the
- * mount pointer from the notifier block address.
- */
-STATIC int
-xfs_icsb_cpu_notify(
- struct notifier_block *nfb,
- unsigned long action,
- void *hcpu)
-{
- xfs_icsb_cnts_t *cntp;
- xfs_mount_t *mp;
- int s;
-
- mp = (xfs_mount_t *)container_of(nfb, xfs_mount_t, m_icsb_notifier);
- cntp = (xfs_icsb_cnts_t *)
- per_cpu_ptr(mp->m_sb_cnts, (unsigned long)hcpu);
- switch (action) {
- case CPU_UP_PREPARE:
- /* Easy Case - initialize the area and locks, and
- * then rebalance when online does everything else for us. */
- memset(cntp, 0, sizeof(xfs_icsb_cnts_t));
- break;
- case CPU_ONLINE:
- xfs_icsb_balance_counter(mp, XFS_SBS_ICOUNT, 0);
- xfs_icsb_balance_counter(mp, XFS_SBS_IFREE, 0);
- xfs_icsb_balance_counter(mp, XFS_SBS_FDBLOCKS, 0);
- break;
- case CPU_DEAD:
- /* Disable all the counters, then fold the dead cpu's
- * count into the total on the global superblock and
- * re-enable the counters. */
- s = XFS_SB_LOCK(mp);
- xfs_icsb_disable_counter(mp, XFS_SBS_ICOUNT);
- xfs_icsb_disable_counter(mp, XFS_SBS_IFREE);
- xfs_icsb_disable_counter(mp, XFS_SBS_FDBLOCKS);
-
- mp->m_sb.sb_icount += cntp->icsb_icount;
- mp->m_sb.sb_ifree += cntp->icsb_ifree;
- mp->m_sb.sb_fdblocks += cntp->icsb_fdblocks;
-
- memset(cntp, 0, sizeof(xfs_icsb_cnts_t));
-
- xfs_icsb_balance_counter(mp, XFS_SBS_ICOUNT, XFS_ICSB_SB_LOCKED);
- xfs_icsb_balance_counter(mp, XFS_SBS_IFREE, XFS_ICSB_SB_LOCKED);
- xfs_icsb_balance_counter(mp, XFS_SBS_FDBLOCKS, XFS_ICSB_SB_LOCKED);
- XFS_SB_UNLOCK(mp, s);
- break;
- }
-
- return NOTIFY_OK;
-}
-
-int
-xfs_icsb_init_counters(
- xfs_mount_t *mp)
-{
- xfs_icsb_cnts_t *cntp;
- int i;
-
- mp->m_sb_cnts = alloc_percpu(xfs_icsb_cnts_t);
- if (mp->m_sb_cnts == NULL)
- return -ENOMEM;
-
- mp->m_icsb_notifier.notifier_call = xfs_icsb_cpu_notify;
- mp->m_icsb_notifier.priority = 0;
- register_cpu_notifier(&mp->m_icsb_notifier);
-
- for_each_online_cpu(i) {
- cntp = (xfs_icsb_cnts_t *)per_cpu_ptr(mp->m_sb_cnts, i);
- memset(cntp, 0, sizeof(xfs_icsb_cnts_t));
- }
- /*
- * start with all counters disabled so that the
- * initial balance kicks us off correctly
- */
- mp->m_icsb_counters = -1;
- return 0;
-}
-
-STATIC void
-xfs_icsb_destroy_counters(
- xfs_mount_t *mp)
-{
- if (mp->m_sb_cnts) {
- unregister_cpu_notifier(&mp->m_icsb_notifier);
- free_percpu(mp->m_sb_cnts);
- }
-}
-
-STATIC inline void
-xfs_icsb_lock_cntr(
- xfs_icsb_cnts_t *icsbp)
-{
- while (test_and_set_bit(XFS_ICSB_FLAG_LOCK, &icsbp->icsb_flags)) {
- ndelay(1000);
- }
-}
-
-STATIC inline void
-xfs_icsb_unlock_cntr(
- xfs_icsb_cnts_t *icsbp)
-{
- clear_bit(XFS_ICSB_FLAG_LOCK, &icsbp->icsb_flags);
-}
-
-
-STATIC inline void
-xfs_icsb_lock_all_counters(
- xfs_mount_t *mp)
-{
- xfs_icsb_cnts_t *cntp;
- int i;
-
- for_each_online_cpu(i) {
- cntp = (xfs_icsb_cnts_t *)per_cpu_ptr(mp->m_sb_cnts, i);
- xfs_icsb_lock_cntr(cntp);
- }
-}
-
-STATIC inline void
-xfs_icsb_unlock_all_counters(
- xfs_mount_t *mp)
-{
- xfs_icsb_cnts_t *cntp;
- int i;
-
- for_each_online_cpu(i) {
- cntp = (xfs_icsb_cnts_t *)per_cpu_ptr(mp->m_sb_cnts, i);
- xfs_icsb_unlock_cntr(cntp);
- }
-}
-
-STATIC void
-xfs_icsb_count(
- xfs_mount_t *mp,
- xfs_icsb_cnts_t *cnt,
- int flags)
-{
- xfs_icsb_cnts_t *cntp;
- int i;
-
- memset(cnt, 0, sizeof(xfs_icsb_cnts_t));
-
- if (!(flags & XFS_ICSB_LAZY_COUNT))
- xfs_icsb_lock_all_counters(mp);
-
- for_each_online_cpu(i) {
- cntp = (xfs_icsb_cnts_t *)per_cpu_ptr(mp->m_sb_cnts, i);
- cnt->icsb_icount += cntp->icsb_icount;
- cnt->icsb_ifree += cntp->icsb_ifree;
- cnt->icsb_fdblocks += cntp->icsb_fdblocks;
- }
-
- if (!(flags & XFS_ICSB_LAZY_COUNT))
- xfs_icsb_unlock_all_counters(mp);
-}
-
-STATIC int
-xfs_icsb_counter_disabled(
- xfs_mount_t *mp,
- xfs_sb_field_t field)
-{
- ASSERT((field >= XFS_SBS_ICOUNT) && (field <= XFS_SBS_FDBLOCKS));
- return test_bit(field, &mp->m_icsb_counters);
-}
-
-STATIC int
-xfs_icsb_disable_counter(
- xfs_mount_t *mp,
- xfs_sb_field_t field)
-{
- xfs_icsb_cnts_t cnt;
-
- ASSERT((field >= XFS_SBS_ICOUNT) && (field <= XFS_SBS_FDBLOCKS));
-
- xfs_icsb_lock_all_counters(mp);
- if (!test_and_set_bit(field, &mp->m_icsb_counters)) {
- /* drain back to superblock */
-
- xfs_icsb_count(mp, &cnt, XFS_ICSB_SB_LOCKED|XFS_ICSB_LAZY_COUNT);
- switch(field) {
- case XFS_SBS_ICOUNT:
- mp->m_sb.sb_icount = cnt.icsb_icount;
- break;
- case XFS_SBS_IFREE:
- mp->m_sb.sb_ifree = cnt.icsb_ifree;
- break;
- case XFS_SBS_FDBLOCKS:
- mp->m_sb.sb_fdblocks = cnt.icsb_fdblocks;
- break;
- default:
- BUG();
- }
- }
-
- xfs_icsb_unlock_all_counters(mp);
-
- return 0;
-}
-
-STATIC void
-xfs_icsb_enable_counter(
- xfs_mount_t *mp,
- xfs_sb_field_t field,
- uint64_t count,
- uint64_t resid)
-{
- xfs_icsb_cnts_t *cntp;
- int i;
-
- ASSERT((field >= XFS_SBS_ICOUNT) && (field <= XFS_SBS_FDBLOCKS));
-
- xfs_icsb_lock_all_counters(mp);
- for_each_online_cpu(i) {
- cntp = per_cpu_ptr(mp->m_sb_cnts, i);
- switch (field) {
- case XFS_SBS_ICOUNT:
- cntp->icsb_icount = count + resid;
- break;
- case XFS_SBS_IFREE:
- cntp->icsb_ifree = count + resid;
- break;
- case XFS_SBS_FDBLOCKS:
- cntp->icsb_fdblocks = count + resid;
- break;
- default:
- BUG();
- break;
- }
- resid = 0;
- }
- clear_bit(field, &mp->m_icsb_counters);
- xfs_icsb_unlock_all_counters(mp);
-}
-
-STATIC void
-xfs_icsb_sync_counters_int(
- xfs_mount_t *mp,
- int flags)
-{
- xfs_icsb_cnts_t cnt;
- int s;
-
- /* Pass 1: lock all counters */
- if ((flags & XFS_ICSB_SB_LOCKED) == 0)
- s = XFS_SB_LOCK(mp);
-
- xfs_icsb_count(mp, &cnt, flags);
-
- /* Step 3: update mp->m_sb fields */
- if (!xfs_icsb_counter_disabled(mp, XFS_SBS_ICOUNT))
- mp->m_sb.sb_icount = cnt.icsb_icount;
- if (!xfs_icsb_counter_disabled(mp, XFS_SBS_IFREE))
- mp->m_sb.sb_ifree = cnt.icsb_ifree;
- if (!xfs_icsb_counter_disabled(mp, XFS_SBS_FDBLOCKS))
- mp->m_sb.sb_fdblocks = cnt.icsb_fdblocks;
-
- if ((flags & XFS_ICSB_SB_LOCKED) == 0)
- XFS_SB_UNLOCK(mp, s);
-}
-
-/*
- * Accurate update of per-cpu counters to incore superblock
- */
-STATIC void
-xfs_icsb_sync_counters(
- xfs_mount_t *mp)
-{
- xfs_icsb_sync_counters_int(mp, 0);
-}
-
-/*
- * lazy addition used for things like df, background sb syncs, etc
- */
-void
-xfs_icsb_sync_counters_lazy(
- xfs_mount_t *mp)
-{
- xfs_icsb_sync_counters_int(mp, XFS_ICSB_LAZY_COUNT);
-}
-
-/*
- * Balance and enable/disable counters as necessary.
- *
- * Thresholds for re-enabling counters are somewhat magic.
- * inode counts are chosen to be the same number as single
- * on disk allocation chunk per CPU, and free blocks is
- * something far enough zero that we aren't going thrash
- * when we get near ENOSPC.
- */
-#define XFS_ICSB_INO_CNTR_REENABLE 64
-#define XFS_ICSB_FDBLK_CNTR_REENABLE 512
-STATIC void
-xfs_icsb_balance_counter(
- xfs_mount_t *mp,
- xfs_sb_field_t field,
- int flags)
-{
- uint64_t count, resid = 0;
- int weight = num_online_cpus();
- int s;
-
- if (!(flags & XFS_ICSB_SB_LOCKED))
- s = XFS_SB_LOCK(mp);
-
- /* disable counter and sync counter */
- xfs_icsb_disable_counter(mp, field);
-
- /* update counters - first CPU gets residual*/
- switch (field) {
- case XFS_SBS_ICOUNT:
- count = mp->m_sb.sb_icount;
- resid = do_div(count, weight);
- if (count < XFS_ICSB_INO_CNTR_REENABLE)
- goto out;
- break;
- case XFS_SBS_IFREE:
- count = mp->m_sb.sb_ifree;
- resid = do_div(count, weight);
- if (count < XFS_ICSB_INO_CNTR_REENABLE)
- goto out;
- break;
- case XFS_SBS_FDBLOCKS:
- count = mp->m_sb.sb_fdblocks;
- resid = do_div(count, weight);
- if (count < XFS_ICSB_FDBLK_CNTR_REENABLE)
- goto out;
- break;
- default:
- BUG();
- break;
- }
-
- xfs_icsb_enable_counter(mp, field, count, resid);
-out:
- if (!(flags & XFS_ICSB_SB_LOCKED))
- XFS_SB_UNLOCK(mp, s);
-}
-
-STATIC int
-xfs_icsb_modify_counters_int(
- xfs_mount_t *mp,
- xfs_sb_field_t field,
- int delta,
- int rsvd,
- int flags)
-{
- xfs_icsb_cnts_t *icsbp;
- long long lcounter; /* long counter for 64 bit fields */
- int cpu, s, locked = 0;
- int ret = 0, balance_done = 0;
-
-again:
- cpu = get_cpu();
- icsbp = (xfs_icsb_cnts_t *)per_cpu_ptr(mp->m_sb_cnts, cpu),
- xfs_icsb_lock_cntr(icsbp);
- if (unlikely(xfs_icsb_counter_disabled(mp, field)))
- goto slow_path;
-
- switch (field) {
- case XFS_SBS_ICOUNT:
- lcounter = icsbp->icsb_icount;
- lcounter += delta;
- if (unlikely(lcounter < 0))
- goto slow_path;
- icsbp->icsb_icount = lcounter;
- break;
-
- case XFS_SBS_IFREE:
- lcounter = icsbp->icsb_ifree;
- lcounter += delta;
- if (unlikely(lcounter < 0))
- goto slow_path;
- icsbp->icsb_ifree = lcounter;
- break;
-
- case XFS_SBS_FDBLOCKS:
- BUG_ON((mp->m_resblks - mp->m_resblks_avail) != 0);
-
- lcounter = icsbp->icsb_fdblocks;
- lcounter += delta;
- if (unlikely(lcounter < 0))
- goto slow_path;
- icsbp->icsb_fdblocks = lcounter;
- break;
- default:
- BUG();
- break;
- }
- xfs_icsb_unlock_cntr(icsbp);
- put_cpu();
- if (locked)
- XFS_SB_UNLOCK(mp, s);
- return 0;
-
- /*
- * The slow path needs to be run with the SBLOCK
- * held so that we prevent other threads from
- * attempting to run this path at the same time.
- * this provides exclusion for the balancing code,
- * and exclusive fallback if the balance does not
- * provide enough resources to continue in an unlocked
- * manner.
- */
-slow_path:
- xfs_icsb_unlock_cntr(icsbp);
- put_cpu();
-
- /* need to hold superblock incase we need
- * to disable a counter */
- if (!(flags & XFS_ICSB_SB_LOCKED)) {
- s = XFS_SB_LOCK(mp);
- locked = 1;
- flags |= XFS_ICSB_SB_LOCKED;
- }
- if (!balance_done) {
- xfs_icsb_balance_counter(mp, field, flags);
- balance_done = 1;
- goto again;
- } else {
- /*
- * we might not have enough on this local
- * cpu to allocate for a bulk request.
- * We need to drain this field from all CPUs
- * and disable the counter fastpath
- */
- xfs_icsb_disable_counter(mp, field);
- }
-
- ret = xfs_mod_incore_sb_unlocked(mp, field, delta, rsvd);
-
- if (locked)
- XFS_SB_UNLOCK(mp, s);
- return ret;
-}
-
-STATIC int
-xfs_icsb_modify_counters(
- xfs_mount_t *mp,
- xfs_sb_field_t field,
- int delta,
- int rsvd)
-{
- return xfs_icsb_modify_counters_int(mp, field, delta, rsvd, 0);
-}
-
-/*
- * Called when superblock is already locked
- */
-STATIC int
-xfs_icsb_modify_counters_locked(
- xfs_mount_t *mp,
- xfs_sb_field_t field,
- int delta,
- int rsvd)
-{
- return xfs_icsb_modify_counters_int(mp, field, delta,
- rsvd, XFS_ICSB_SB_LOCKED);
-}
-#endif
diff --git a/sys/gnu/fs/xfs/xfs_mount.h b/sys/gnu/fs/xfs/xfs_mount.h
deleted file mode 100644
index 02ad298..0000000
--- a/sys/gnu/fs/xfs/xfs_mount.h
+++ /dev/null
@@ -1,626 +0,0 @@
-/*
- * Copyright (c) 2000-2005 Silicon Graphics, Inc.
- * All Rights Reserved.
- *
- * 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.
- *
- * This program is distributed in the hope that it would 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 the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- */
-#ifndef __XFS_MOUNT_H__
-#define __XFS_MOUNT_H__
-
-typedef struct xfs_trans_reservations {
- uint tr_write; /* extent alloc trans */
- uint tr_itruncate; /* truncate trans */
- uint tr_rename; /* rename trans */
- uint tr_link; /* link trans */
- uint tr_remove; /* unlink trans */
- uint tr_symlink; /* symlink trans */
- uint tr_create; /* create trans */
- uint tr_mkdir; /* mkdir trans */
- uint tr_ifree; /* inode free trans */
- uint tr_ichange; /* inode update trans */
- uint tr_growdata; /* fs data section grow trans */
- uint tr_swrite; /* sync write inode trans */
- uint tr_addafork; /* cvt inode to attributed trans */
- uint tr_writeid; /* write setuid/setgid file */
- uint tr_attrinval; /* attr fork buffer invalidation */
- uint tr_attrset; /* set/create an attribute */
- uint tr_attrrm; /* remove an attribute */
- uint tr_clearagi; /* clear bad agi unlinked ino bucket */
- uint tr_growrtalloc; /* grow realtime allocations */
- uint tr_growrtzero; /* grow realtime zeroing */
- uint tr_growrtfree; /* grow realtime freeing */
-} xfs_trans_reservations_t;
-
-#ifndef __KERNEL__
-/*
- * Moved here from xfs_ag.h to avoid reordering header files
- */
-#define XFS_DADDR_TO_AGNO(mp,d) \
- ((xfs_agnumber_t)(XFS_BB_TO_FSBT(mp, d) / (mp)->m_sb.sb_agblocks))
-#define XFS_DADDR_TO_AGBNO(mp,d) \
- ((xfs_agblock_t)(XFS_BB_TO_FSBT(mp, d) % (mp)->m_sb.sb_agblocks))
-#else
-struct cred;
-struct log;
-struct xfs_vfs;
-struct xfs_vnode;
-struct xfs_mount_args;
-struct xfs_ihash;
-struct xfs_chash;
-struct xfs_inode;
-struct xfs_perag;
-struct xfs_iocore;
-struct xfs_bmbt_irec;
-struct xfs_bmap_free;
-struct xfs_extdelta;
-struct xfs_swapext;
-
-extern struct xvfsops xfs_vfsops;
-//extern struct xvnodeops xfs_vnodeops;
-
-#define AIL_LOCK_T lock_t
-#define AIL_LOCKINIT(x,y) spinlock_init(x,y)
-#define AIL_LOCK_DESTROY(x) spinlock_destroy(x)
-#define AIL_LOCK(mp,s) s=mutex_spinlock(&(mp)->m_ail_lock)
-#define AIL_UNLOCK(mp,s) mutex_spinunlock(&(mp)->m_ail_lock, s)
-
-
-/*
- * Prototypes and functions for the Data Migration subsystem.
- */
-
-typedef int (*xfs_send_data_t)(int, struct xfs_vnode *,
- xfs_off_t, size_t, int, vrwlock_t *);
-typedef int (*xfs_send_mmap_t)(void*, uint);
-typedef int (*xfs_send_destroy_t)(struct xfs_vnode *, dm_right_t);
-typedef int (*xfs_send_namesp_t)(dm_eventtype_t, struct xfs_vfs *,
- struct xfs_vnode *,
- dm_right_t, struct xfs_vnode *, dm_right_t,
- char *, char *, mode_t, int, int);
-typedef void (*xfs_send_unmount_t)(struct xfs_vfs *, struct xfs_vnode *,
- dm_right_t, mode_t, int, int);
-
-typedef struct xfs_dmops {
- xfs_send_data_t xfs_send_data;
- xfs_send_mmap_t xfs_send_mmap;
- xfs_send_destroy_t xfs_send_destroy;
- xfs_send_namesp_t xfs_send_namesp;
- xfs_send_unmount_t xfs_send_unmount;
-} xfs_dmops_t;
-
-#define XFS_SEND_DATA(mp, ev,vp,off,len,fl,lock) \
- (*(mp)->m_dm_ops.xfs_send_data)(ev,vp,off,len,fl,lock)
-#define XFS_SEND_MMAP(mp, vma,fl) \
- (*(mp)->m_dm_ops.xfs_send_mmap)(vma,fl)
-#define XFS_SEND_DESTROY(mp, vp,right) \
- (*(mp)->m_dm_ops.xfs_send_destroy)(vp,right)
-#define XFS_SEND_NAMESP(mp, ev,b1,r1,b2,r2,n1,n2,mode,rval,fl) \
- (*(mp)->m_dm_ops.xfs_send_namesp)(ev,NULL,b1,r1,b2,r2,n1,n2,mode,rval,fl)
-#define XFS_SEND_PREUNMOUNT(mp, vfs,b1,r1,b2,r2,n1,n2,mode,rval,fl) \
- (*(mp)->m_dm_ops.xfs_send_namesp)(DM_EVENT_PREUNMOUNT,vfs,b1,r1,b2,r2,n1,n2,mode,rval,fl)
-#define XFS_SEND_UNMOUNT(mp, vfsp,vp,right,mode,rval,fl) \
- (*(mp)->m_dm_ops.xfs_send_unmount)(vfsp,vp,right,mode,rval,fl)
-
-
-/*
- * Prototypes and functions for the Quota Management subsystem.
- */
-
-struct xfs_dquot;
-struct xfs_dqtrxops;
-struct xfs_quotainfo;
-
-typedef int (*xfs_qminit_t)(struct xfs_mount *, uint *, uint *);
-typedef int (*xfs_qmmount_t)(struct xfs_mount *, uint, uint, int);
-typedef int (*xfs_qmunmount_t)(struct xfs_mount *);
-typedef void (*xfs_qmdone_t)(struct xfs_mount *);
-typedef void (*xfs_dqrele_t)(struct xfs_dquot *);
-typedef int (*xfs_dqattach_t)(struct xfs_inode *, uint);
-typedef void (*xfs_dqdetach_t)(struct xfs_inode *);
-typedef int (*xfs_dqpurgeall_t)(struct xfs_mount *, uint);
-typedef int (*xfs_dqvopalloc_t)(struct xfs_mount *,
- struct xfs_inode *, uid_t, gid_t, prid_t, uint,
- struct xfs_dquot **, struct xfs_dquot **);
-typedef void (*xfs_dqvopcreate_t)(struct xfs_trans *, struct xfs_inode *,
- struct xfs_dquot *, struct xfs_dquot *);
-typedef int (*xfs_dqvoprename_t)(struct xfs_inode **);
-typedef struct xfs_dquot * (*xfs_dqvopchown_t)(
- struct xfs_trans *, struct xfs_inode *,
- struct xfs_dquot **, struct xfs_dquot *);
-typedef int (*xfs_dqvopchownresv_t)(struct xfs_trans *, struct xfs_inode *,
- struct xfs_dquot *, struct xfs_dquot *, uint);
-
-typedef struct xfs_qmops {
- xfs_qminit_t xfs_qminit;
- xfs_qmdone_t xfs_qmdone;
- xfs_qmmount_t xfs_qmmount;
- xfs_qmunmount_t xfs_qmunmount;
- xfs_dqrele_t xfs_dqrele;
- xfs_dqattach_t xfs_dqattach;
- xfs_dqdetach_t xfs_dqdetach;
- xfs_dqpurgeall_t xfs_dqpurgeall;
- xfs_dqvopalloc_t xfs_dqvopalloc;
- xfs_dqvopcreate_t xfs_dqvopcreate;
- xfs_dqvoprename_t xfs_dqvoprename;
- xfs_dqvopchown_t xfs_dqvopchown;
- xfs_dqvopchownresv_t xfs_dqvopchownresv;
- struct xfs_dqtrxops *xfs_dqtrxops;
-} xfs_qmops_t;
-
-#define XFS_QM_INIT(mp, mnt, fl) \
- (*(mp)->m_qm_ops.xfs_qminit)(mp, mnt, fl)
-#define XFS_QM_MOUNT(mp, mnt, fl, mfsi_flags) \
- (*(mp)->m_qm_ops.xfs_qmmount)(mp, mnt, fl, mfsi_flags)
-#define XFS_QM_UNMOUNT(mp) \
- (*(mp)->m_qm_ops.xfs_qmunmount)(mp)
-#define XFS_QM_DONE(mp) \
- (*(mp)->m_qm_ops.xfs_qmdone)(mp)
-#define XFS_QM_DQRELE(mp, dq) \
- (*(mp)->m_qm_ops.xfs_dqrele)(dq)
-#define XFS_QM_DQATTACH(mp, ip, fl) \
- (*(mp)->m_qm_ops.xfs_dqattach)(ip, fl)
-#define XFS_QM_DQDETACH(mp, ip) \
- (*(mp)->m_qm_ops.xfs_dqdetach)(ip)
-#define XFS_QM_DQPURGEALL(mp, fl) \
- (*(mp)->m_qm_ops.xfs_dqpurgeall)(mp, fl)
-#define XFS_QM_DQVOPALLOC(mp, ip, uid, gid, prid, fl, dq1, dq2) \
- (*(mp)->m_qm_ops.xfs_dqvopalloc)(mp, ip, uid, gid, prid, fl, dq1, dq2)
-#define XFS_QM_DQVOPCREATE(mp, tp, ip, dq1, dq2) \
- (*(mp)->m_qm_ops.xfs_dqvopcreate)(tp, ip, dq1, dq2)
-#define XFS_QM_DQVOPRENAME(mp, ip) \
- (*(mp)->m_qm_ops.xfs_dqvoprename)(ip)
-#define XFS_QM_DQVOPCHOWN(mp, tp, ip, dqp, dq) \
- (*(mp)->m_qm_ops.xfs_dqvopchown)(tp, ip, dqp, dq)
-#define XFS_QM_DQVOPCHOWNRESV(mp, tp, ip, dq1, dq2, fl) \
- (*(mp)->m_qm_ops.xfs_dqvopchownresv)(tp, ip, dq1, dq2, fl)
-
-
-/*
- * Prototypes and functions for I/O core modularization.
- */
-
-typedef int (*xfs_ioinit_t)(struct xfs_vfs *,
- struct xfs_mount_args *, int);
-typedef int (*xfs_bmapi_t)(struct xfs_trans *, void *,
- xfs_fileoff_t, xfs_filblks_t, int,
- xfs_fsblock_t *, xfs_extlen_t,
- struct xfs_bmbt_irec *, int *,
- struct xfs_bmap_free *, struct xfs_extdelta *);
-typedef int (*xfs_bunmapi_t)(struct xfs_trans *,
- void *, xfs_fileoff_t,
- xfs_filblks_t, int, xfs_extnum_t,
- xfs_fsblock_t *, struct xfs_bmap_free *,
- struct xfs_extdelta *, int *);
-typedef int (*xfs_bmap_eof_t)(void *, xfs_fileoff_t, int, int *);
-typedef int (*xfs_iomap_write_direct_t)(
- void *, xfs_off_t, size_t, int,
- struct xfs_bmbt_irec *, int *, int);
-typedef int (*xfs_iomap_write_delay_t)(
- void *, xfs_off_t, size_t, int,
- struct xfs_bmbt_irec *, int *);
-typedef int (*xfs_iomap_write_allocate_t)(
- void *, xfs_off_t, size_t,
- struct xfs_bmbt_irec *, int *);
-typedef int (*xfs_iomap_write_unwritten_t)(
- void *, xfs_off_t, size_t);
-typedef uint (*xfs_lck_map_shared_t)(void *);
-typedef void (*xfs_lock_t)(void *, uint);
-typedef void (*xfs_lock_demote_t)(void *, uint);
-typedef int (*xfs_lock_nowait_t)(void *, uint);
-typedef void (*xfs_unlk_t)(void *, unsigned int);
-typedef xfs_fsize_t (*xfs_size_t)(void *);
-typedef xfs_fsize_t (*xfs_iodone_t)(struct xfs_vfs *);
-typedef int (*xfs_swap_extents_t)(void *, void *,
- struct xfs_swapext*);
-
-typedef struct xfs_ioops {
- xfs_ioinit_t xfs_ioinit;
- xfs_bmapi_t xfs_bmapi_func;
- xfs_bunmapi_t xfs_bunmapi_func;
- xfs_bmap_eof_t xfs_bmap_eof_func;
- xfs_iomap_write_direct_t xfs_iomap_write_direct;
- xfs_iomap_write_delay_t xfs_iomap_write_delay;
- xfs_iomap_write_allocate_t xfs_iomap_write_allocate;
- xfs_iomap_write_unwritten_t xfs_iomap_write_unwritten;
- xfs_lock_t xfs_ilock;
- xfs_lck_map_shared_t xfs_lck_map_shared;
- xfs_lock_demote_t xfs_ilock_demote;
- xfs_lock_nowait_t xfs_ilock_nowait;
- xfs_unlk_t xfs_unlock;
- xfs_size_t xfs_size_func;
- xfs_iodone_t xfs_iodone;
- xfs_swap_extents_t xfs_swap_extents_func;
-} xfs_ioops_t;
-
-#define XFS_IOINIT(vfsp, args, flags) \
- (*(mp)->m_io_ops.xfs_ioinit)(vfsp, args, flags)
-#define XFS_BMAPI(mp, trans,io,bno,len,f,first,tot,mval,nmap,flist,delta) \
- (*(mp)->m_io_ops.xfs_bmapi_func) \
- (trans,(io)->io_obj,bno,len,f,first,tot,mval,nmap,flist,delta)
-#define XFS_BUNMAPI(mp, trans,io,bno,len,f,nexts,first,flist,delta,done) \
- (*(mp)->m_io_ops.xfs_bunmapi_func) \
- (trans,(io)->io_obj,bno,len,f,nexts,first,flist,delta,done)
-#define XFS_BMAP_EOF(mp, io, endoff, whichfork, eof) \
- (*(mp)->m_io_ops.xfs_bmap_eof_func) \
- ((io)->io_obj, endoff, whichfork, eof)
-#define XFS_IOMAP_WRITE_DIRECT(mp, io, offset, count, flags, mval, nmap, found)\
- (*(mp)->m_io_ops.xfs_iomap_write_direct) \
- ((io)->io_obj, offset, count, flags, mval, nmap, found)
-#define XFS_IOMAP_WRITE_DELAY(mp, io, offset, count, flags, mval, nmap) \
- (*(mp)->m_io_ops.xfs_iomap_write_delay) \
- ((io)->io_obj, offset, count, flags, mval, nmap)
-#define XFS_IOMAP_WRITE_ALLOCATE(mp, io, offset, count, mval, nmap) \
- (*(mp)->m_io_ops.xfs_iomap_write_allocate) \
- ((io)->io_obj, offset, count, mval, nmap)
-#define XFS_IOMAP_WRITE_UNWRITTEN(mp, io, offset, count) \
- (*(mp)->m_io_ops.xfs_iomap_write_unwritten) \
- ((io)->io_obj, offset, count)
-#define XFS_LCK_MAP_SHARED(mp, io) \
- (*(mp)->m_io_ops.xfs_lck_map_shared)((io)->io_obj)
-#define XFS_ILOCK(mp, io, mode) \
- (*(mp)->m_io_ops.xfs_ilock)((io)->io_obj, mode)
-#define XFS_ILOCK_NOWAIT(mp, io, mode) \
- (*(mp)->m_io_ops.xfs_ilock_nowait)((io)->io_obj, mode)
-#define XFS_IUNLOCK(mp, io, mode) \
- (*(mp)->m_io_ops.xfs_unlock)((io)->io_obj, mode)
-#define XFS_ILOCK_DEMOTE(mp, io, mode) \
- (*(mp)->m_io_ops.xfs_ilock_demote)((io)->io_obj, mode)
-#define XFS_SIZE(mp, io) \
- (*(mp)->m_io_ops.xfs_size_func)((io)->io_obj)
-#define XFS_IODONE(vfsp) \
- (*(mp)->m_io_ops.xfs_iodone)(vfsp)
-#define XFS_SWAP_EXTENTS(mp, io, tio, sxp) \
- (*(mp)->m_io_ops.xfs_swap_extents_func) \
- ((io)->io_obj, (tio)->io_obj, sxp)
-
-#ifdef HAVE_PERCPU_SB
-
-/*
- * Valid per-cpu incore superblock counters. Note that if you add new counters,
- * you may need to define new counter disabled bit field descriptors as there
- * are more possible fields in the superblock that can fit in a bitfield on a
- * 32 bit platform. The XFS_SBS_* values for the current current counters just
- * fit.
- */
-typedef struct xfs_icsb_cnts {
- uint64_t icsb_fdblocks;
- uint64_t icsb_ifree;
- uint64_t icsb_icount;
- unsigned long icsb_flags;
-} xfs_icsb_cnts_t;
-
-#define XFS_ICSB_FLAG_LOCK (1 << 0) /* counter lock bit */
-
-#define XFS_ICSB_SB_LOCKED (1 << 0) /* sb already locked */
-#define XFS_ICSB_LAZY_COUNT (1 << 1) /* accuracy not needed */
-
-extern int xfs_icsb_init_counters(struct xfs_mount *);
-extern void xfs_icsb_sync_counters_lazy(struct xfs_mount *);
-
-#else
-#define xfs_icsb_init_counters(mp) (0)
-#define xfs_icsb_sync_counters_lazy(mp) do { } while (0)
-#endif
-
-typedef struct xfs_mount {
- bhv_desc_t m_bhv; /* vfs xfs behavior */
- xfs_tid_t m_tid; /* next unused tid for fs */
- AIL_LOCK_T m_ail_lock; /* fs AIL mutex */
- xfs_ail_entry_t m_ail; /* fs active log item list */
- uint m_ail_gen; /* fs AIL generation count */
- xfs_sb_t m_sb; /* copy of fs superblock */
- lock_t m_sb_lock; /* sb counter mutex */
- struct xfs_buf *m_sb_bp; /* buffer for superblock */
- char *m_fsname; /* filesystem name */
- int m_fsname_len; /* strlen of fs name */
- char *m_rtname; /* realtime device name */
- char *m_logname; /* external log device name */
- int m_bsize; /* fs logical block size */
- xfs_agnumber_t m_agfrotor; /* last ag where space found */
- xfs_agnumber_t m_agirotor; /* last ag dir inode alloced */
- lock_t m_agirotor_lock;/* .. and lock protecting it */
- xfs_agnumber_t m_maxagi; /* highest inode alloc group */
- uint m_ihsize; /* size of next field */
- struct xfs_ihash *m_ihash; /* fs private inode hash table*/
- struct xfs_inode *m_inodes; /* active inode list */
- TAILQ_HEAD(,xfs_inode) m_del_inodes; /* inodes to reclaim */
- // xfs_mutex_t m_ilock; /* inode list mutex */
- /* FreeBSD specfic */
- struct sx m_ilock; /* inode list mutex */
- uint m_ireclaims; /* count of calls to reclaim*/
- uint m_readio_log; /* min read size log bytes */
- uint m_readio_blocks; /* min read size blocks */
- uint m_writeio_log; /* min write size log bytes */
- uint m_writeio_blocks; /* min write size blocks */
- struct log *m_log; /* log specific stuff */
- int m_logbufs; /* number of log buffers */
- int m_logbsize; /* size of each log buffer */
- uint m_rsumlevels; /* rt summary levels */
- uint m_rsumsize; /* size of rt summary, bytes */
- struct xfs_inode *m_rbmip; /* pointer to bitmap inode */
- struct xfs_inode *m_rsumip; /* pointer to summary inode */
- struct xfs_inode *m_rootip; /* pointer to root directory */
- struct xfs_quotainfo *m_quotainfo; /* disk quota information */
- xfs_buftarg_t *m_ddev_targp; /* saves taking the address */
- xfs_buftarg_t *m_logdev_targp;/* ptr to log device */
- xfs_buftarg_t *m_rtdev_targp; /* ptr to rt device */
- __uint8_t m_dircook_elog; /* log d-cookie entry bits */
- __uint8_t m_blkbit_log; /* blocklog + NBBY */
- __uint8_t m_blkbb_log; /* blocklog - BBSHIFT */
- __uint8_t m_agno_log; /* log #ag's */
- __uint8_t m_agino_log; /* #bits for agino in inum */
- __uint8_t m_nreadaheads; /* #readahead buffers */
- __uint16_t m_inode_cluster_size;/* min inode buf size */
- uint m_blockmask; /* sb_blocksize-1 */
- uint m_blockwsize; /* sb_blocksize in words */
- uint m_blockwmask; /* blockwsize-1 */
- uint m_alloc_mxr[2]; /* XFS_ALLOC_BLOCK_MAXRECS */
- uint m_alloc_mnr[2]; /* XFS_ALLOC_BLOCK_MINRECS */
- uint m_bmap_dmxr[2]; /* XFS_BMAP_BLOCK_DMAXRECS */
- uint m_bmap_dmnr[2]; /* XFS_BMAP_BLOCK_DMINRECS */
- uint m_inobt_mxr[2]; /* XFS_INOBT_BLOCK_MAXRECS */
- uint m_inobt_mnr[2]; /* XFS_INOBT_BLOCK_MINRECS */
- uint m_ag_maxlevels; /* XFS_AG_MAXLEVELS */
- uint m_bm_maxlevels[2]; /* XFS_BM_MAXLEVELS */
- uint m_in_maxlevels; /* XFS_IN_MAXLEVELS */
- struct xfs_perag *m_perag; /* per-ag accounting info */
- struct rw_semaphore m_peraglock; /* lock for m_perag (pointer) */
- sema_t m_growlock; /* growfs mutex */
- int m_fixedfsid[2]; /* unchanged for life of FS */
- uint m_dmevmask; /* DMI events for this FS */
- __uint64_t m_flags; /* global mount flags */
- uint m_attroffset; /* inode attribute offset */
- uint m_dir_node_ents; /* #entries in a dir danode */
- uint m_attr_node_ents; /* #entries in attr danode */
- int m_ialloc_inos; /* inodes in inode allocation */
- int m_ialloc_blks; /* blocks in inode allocation */
- int m_litino; /* size of inode union area */
- int m_inoalign_mask;/* mask sb_inoalignmt if used */
- uint m_qflags; /* quota status flags */
- xfs_trans_reservations_t m_reservations;/* precomputed res values */
- __uint64_t m_maxicount; /* maximum inode count */
- __uint64_t m_maxioffset; /* maximum inode offset */
- __uint64_t m_resblks; /* total reserved blocks */
- __uint64_t m_resblks_avail;/* available reserved blocks */
-#if XFS_BIG_INUMS
- xfs_ino_t m_inoadd; /* add value for ino64_offset */
-#endif
- int m_dalign; /* stripe unit */
- int m_swidth; /* stripe width */
- int m_sinoalign; /* stripe unit inode alignment */
- int m_attr_magicpct;/* 37% of the blocksize */
- int m_dir_magicpct; /* 37% of the dir blocksize */
- __uint8_t m_mk_sharedro; /* mark shared ro on unmount */
- __uint8_t m_inode_quiesce;/* call quiesce on new inodes.
- field governed by m_ilock */
- __uint8_t m_sectbb_log; /* sectlog - BBSHIFT */
- __uint8_t m_dirversion; /* 1 or 2 */
- xfs_dirops_t m_dirops; /* table of dir funcs */
- int m_dirblksize; /* directory block sz--bytes */
- int m_dirblkfsbs; /* directory block sz--fsbs */
- xfs_dablk_t m_dirdatablk; /* blockno of dir data v2 */
- xfs_dablk_t m_dirleafblk; /* blockno of dir non-data v2 */
- xfs_dablk_t m_dirfreeblk; /* blockno of dirfreeindex v2 */
- uint m_chsize; /* size of next field */
- struct xfs_chash *m_chash; /* fs private inode per-cluster
- * hash table */
- struct xfs_dmops m_dm_ops; /* vector of DMI ops */
- struct xfs_qmops m_qm_ops; /* vector of XQM ops */
- struct xfs_ioops m_io_ops; /* vector of I/O ops */
- atomic_t m_active_trans; /* number trans frozen */
-#ifdef HAVE_PERCPU_SB
- xfs_icsb_cnts_t *m_sb_cnts; /* per-cpu superblock counters */
- unsigned long m_icsb_counters; /* disabled per-cpu counters */
- struct notifier_block m_icsb_notifier; /* hotplug cpu notifier */
-#endif
-} xfs_mount_t;
-
-/*
- * Flags for m_flags.
- */
-#define XFS_MOUNT_WSYNC (1ULL << 0) /* for nfs - all metadata ops
- must be synchronous except
- for space allocations */
-#define XFS_MOUNT_INO64 (1ULL << 1)
- /* (1ULL << 2) -- currently unused */
- /* (1ULL << 3) -- currently unused */
-#define XFS_MOUNT_FS_SHUTDOWN (1ULL << 4) /* atomic stop of all filesystem
- operations, typically for
- disk errors in metadata */
-#define XFS_MOUNT_RETERR (1ULL << 6) /* return alignment errors to
- user */
-#define XFS_MOUNT_NOALIGN (1ULL << 7) /* turn off stripe alignment
- allocations */
-#define XFS_MOUNT_ATTR2 (1ULL << 8) /* allow use of attr2 format */
- /* (1ULL << 9) -- currently unused */
-#define XFS_MOUNT_NORECOVERY (1ULL << 10) /* no recovery - dirty fs */
-#define XFS_MOUNT_SHARED (1ULL << 11) /* shared mount */
-#define XFS_MOUNT_DFLT_IOSIZE (1ULL << 12) /* set default i/o size */
-#define XFS_MOUNT_OSYNCISOSYNC (1ULL << 13) /* o_sync is REALLY o_sync */
- /* osyncisdsync is now default*/
-#define XFS_MOUNT_32BITINODES (1ULL << 14) /* do not create inodes above
- * 32 bits in size */
- /* (1ULL << 15) -- currently unused */
-#define XFS_MOUNT_NOUUID (1ULL << 16) /* ignore uuid during mount */
-#define XFS_MOUNT_BARRIER (1ULL << 17)
-#define XFS_MOUNT_IDELETE (1ULL << 18) /* delete empty inode clusters*/
-#define XFS_MOUNT_SWALLOC (1ULL << 19) /* turn on stripe width
- * allocation */
-#define XFS_MOUNT_IHASHSIZE (1ULL << 20) /* inode hash table size */
-#define XFS_MOUNT_DIRSYNC (1ULL << 21) /* synchronous directory ops */
-#define XFS_MOUNT_COMPAT_IOSIZE (1ULL << 22) /* don't report large preferred
- * I/O size in stat() */
-#define XFS_MOUNT_NO_PERCPU_SB (1ULL << 23) /* don't use per-cpu superblock
- counters */
-
-
-/*
- * Default minimum read and write sizes.
- */
-#define XFS_READIO_LOG_LARGE 16
-#define XFS_WRITEIO_LOG_LARGE 16
-
-/*
- * Max and min values for mount-option defined I/O
- * preallocation sizes.
- */
-#define XFS_MAX_IO_LOG 30 /* 1G */
-#define XFS_MIN_IO_LOG PAGE_SHIFT
-
-/*
- * Synchronous read and write sizes. This should be
- * better for NFSv2 wsync filesystems.
- */
-#define XFS_WSYNC_READIO_LOG 15 /* 32K */
-#define XFS_WSYNC_WRITEIO_LOG 14 /* 16K */
-
-/*
- * Allow large block sizes to be reported to userspace programs if the
- * "largeio" mount option is used.
- *
- * If compatibility mode is specified, simply return the basic unit of caching
- * so that we don't get inefficient read/modify/write I/O from user apps.
- * Otherwise....
- *
- * If the underlying volume is a stripe, then return the stripe width in bytes
- * as the recommended I/O size. It is not a stripe and we've set a default
- * buffered I/O size, return that, otherwise return the compat default.
- */
-static inline unsigned long
-xfs_preferred_iosize(xfs_mount_t *mp)
-{
- if (mp->m_flags & XFS_MOUNT_COMPAT_IOSIZE)
- return PAGE_CACHE_SIZE;
- return (mp->m_swidth ?
- (mp->m_swidth << mp->m_sb.sb_blocklog) :
- ((mp->m_flags & XFS_MOUNT_DFLT_IOSIZE) ?
- (1 << (int)MAX(mp->m_readio_log, mp->m_writeio_log)) :
- PAGE_CACHE_SIZE));
-}
-
-#define XFS_MAXIOFFSET(mp) ((mp)->m_maxioffset)
-
-#define XFS_FORCED_SHUTDOWN(mp) ((mp)->m_flags & XFS_MOUNT_FS_SHUTDOWN)
-#define xfs_force_shutdown(m,f) \
- XVFS_FORCE_SHUTDOWN((XFS_MTOVFS(m)), f, __FILE__, __LINE__)
-
-/*
- * Flags sent to xfs_force_shutdown.
- */
-#define XFS_METADATA_IO_ERROR 0x1
-#define XFS_LOG_IO_ERROR 0x2
-#define XFS_FORCE_UMOUNT 0x4
-#define XFS_CORRUPT_INCORE 0x8 /* Corrupt in-memory data structures */
-#define XFS_SHUTDOWN_REMOTE_REQ 0x10 /* Shutdown came from remote cell */
-
-/*
- * Flags for xfs_mountfs
- */
-#define XFS_MFSI_SECOND 0x01 /* Secondary mount -- skip stuff */
-#define XFS_MFSI_CLIENT 0x02 /* Is a client -- skip lots of stuff */
-/* XFS_MFSI_RRINODES */
-#define XFS_MFSI_NOUNLINK 0x08 /* Skip unlinked inode processing in */
- /* log recovery */
-#define XFS_MFSI_NO_QUOTACHECK 0x10 /* Skip quotacheck processing */
-/* XFS_MFSI_CONVERT_SUNIT */
-#define XFS_MFSI_QUIET 0x40 /* Be silent if mount errors found */
-
-/*
- * Macros for getting from mount to vfs and back.
- */
-#define XFS_MTOVFS(mp) xfs_mtovfs(mp)
-static inline xfs_vfs_t *xfs_mtovfs(xfs_mount_t *mp)
-{
- return bhvtovfs(&mp->m_bhv);
-}
-
-#define XFS_BHVTOM(bdp) xfs_bhvtom(bdp)
-static inline xfs_mount_t *xfs_bhvtom(bhv_desc_t *bdp)
-{
- return (xfs_mount_t *)BHV_PDATA(bdp);
-}
-
-#define XFS_VFSTOM(vfs) xfs_vfstom(vfs)
-static inline xfs_mount_t *xfs_vfstom(xfs_vfs_t *vfs)
-{
- return XFS_BHVTOM(bhv_lookup(VFS_BHVHEAD(vfs), &xfs_vfsops));
-}
-
-#define XFS_DADDR_TO_AGNO(mp,d) xfs_daddr_to_agno(mp,d)
-static inline xfs_agnumber_t
-xfs_daddr_to_agno(struct xfs_mount *mp, xfs_daddr_t d)
-{
- xfs_daddr_t ld = XFS_BB_TO_FSBT(mp, d);
- do_div(ld, mp->m_sb.sb_agblocks);
- return (xfs_agnumber_t) ld;
-}
-
-#define XFS_DADDR_TO_AGBNO(mp,d) xfs_daddr_to_agbno(mp,d)
-static inline xfs_agblock_t
-xfs_daddr_to_agbno(struct xfs_mount *mp, xfs_daddr_t d)
-{
- xfs_daddr_t ld = XFS_BB_TO_FSBT(mp, d);
- return (xfs_agblock_t) do_div(ld, mp->m_sb.sb_agblocks);
-}
-
-/*
- * This structure is for use by the xfs_mod_incore_sb_batch() routine.
- */
-typedef struct xfs_mod_sb {
- xfs_sb_field_t msb_field; /* Field to modify, see below */
- int msb_delta; /* Change to make to specified field */
-} xfs_mod_sb_t;
-
-/* FreeBSD specfic */
-#define XFS_MOUNT_ILOCK(mp) sx_xlock(&((mp)->m_ilock))
-#define XFS_MOUNT_IUNLOCK(mp) sx_xunlock(&((mp)->m_ilock))
-
-#define XFS_SB_LOCK(mp) mutex_spinlock(&(mp)->m_sb_lock)
-#define XFS_SB_UNLOCK(mp,s) mutex_spinunlock(&(mp)->m_sb_lock,(s))
-
-extern xfs_mount_t *xfs_mount_init(void);
-extern void xfs_mod_sb(xfs_trans_t *, __int64_t);
-extern void xfs_mount_free(xfs_mount_t *mp, int remove_bhv);
-extern int xfs_mountfs(struct xfs_vfs *, xfs_mount_t *mp, int);
-extern void xfs_mountfs_check_barriers(xfs_mount_t *mp);
-
-extern int xfs_unmountfs(xfs_mount_t *, struct cred *);
-extern void xfs_unmountfs_close(xfs_mount_t *, struct cred *);
-extern int xfs_unmountfs_writesb(xfs_mount_t *);
-extern int xfs_unmount_flush(xfs_mount_t *, int);
-extern int xfs_mod_incore_sb(xfs_mount_t *, xfs_sb_field_t, int, int);
-extern int xfs_mod_incore_sb_unlocked(xfs_mount_t *, xfs_sb_field_t,
- int, int);
-extern int xfs_mod_incore_sb_batch(xfs_mount_t *, xfs_mod_sb_t *,
- uint, int);
-extern struct xfs_buf *xfs_getsb(xfs_mount_t *, int);
-extern int xfs_readsb(xfs_mount_t *, int);
-extern void xfs_freesb(xfs_mount_t *);
-extern void xfs_do_force_shutdown(bhv_desc_t *, int, char *, int);
-extern int xfs_syncsub(xfs_mount_t *, int, int, int *);
-extern int xfs_sync_inodes(xfs_mount_t *, int, int, int *);
-extern xfs_agnumber_t xfs_initialize_perag(struct xfs_vfs *, xfs_mount_t *,
- xfs_agnumber_t);
-extern void xfs_xlatesb(void *, struct xfs_sb *, int, __int64_t);
-
-extern struct xfs_dmops xfs_dmcore_stub;
-extern struct xfs_qmops xfs_qmcore_stub;
-extern struct xfs_ioops xfs_iocore_xfs;
-
-extern int xfs_init(void);
-extern void xfs_cleanup(void);
-
-#endif /* __KERNEL__ */
-
-#endif /* __XFS_MOUNT_H__ */
diff --git a/sys/gnu/fs/xfs/xfs_qmops.c b/sys/gnu/fs/xfs/xfs_qmops.c
deleted file mode 100644
index 1408a32..0000000
--- a/sys/gnu/fs/xfs/xfs_qmops.c
+++ /dev/null
@@ -1,128 +0,0 @@
-/*
- * Copyright (c) 2000-2005 Silicon Graphics, Inc.
- * All Rights Reserved.
- *
- * 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.
- *
- * This program is distributed in the hope that it would 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 the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- */
-#include "xfs.h"
-#include "xfs_fs.h"
-#include "xfs_types.h"
-#include "xfs_log.h"
-#include "xfs_inum.h"
-#include "xfs_trans.h"
-#include "xfs_sb.h"
-#include "xfs_ag.h"
-#include "xfs_dir.h"
-#include "xfs_dir2.h"
-#include "xfs_dmapi.h"
-#include "xfs_mount.h"
-#include "xfs_quota.h"
-#include "xfs_error.h"
-
-STATIC struct xfs_dquot *
-xfs_dqvopchown_default(
- struct xfs_trans *tp,
- struct xfs_inode *ip,
- struct xfs_dquot **dqp,
- struct xfs_dquot *dq)
-{
- return NULL;
-}
-
-/*
- * Clear the quotaflags in memory and in the superblock.
- */
-int
-xfs_mount_reset_sbqflags(xfs_mount_t *mp)
-{
- int error;
- xfs_trans_t *tp;
- unsigned long s;
-
- mp->m_qflags = 0;
- /*
- * It is OK to look at sb_qflags here in mount path,
- * without SB_LOCK.
- */
- if (mp->m_sb.sb_qflags == 0)
- return 0;
- s = XFS_SB_LOCK(mp);
- mp->m_sb.sb_qflags = 0;
- XFS_SB_UNLOCK(mp, s);
-
- /*
- * if the fs is readonly, let the incore superblock run
- * with quotas off but don't flush the update out to disk
- */
- if (XFS_MTOVFS(mp)->vfs_flag & VFS_RDONLY)
- return 0;
-#ifdef QUOTADEBUG
- xfs_fs_cmn_err(CE_NOTE, mp, "Writing superblock quota changes");
-#endif
- tp = xfs_trans_alloc(mp, XFS_TRANS_QM_SBCHANGE);
- if ((error = xfs_trans_reserve(tp, 0, mp->m_sb.sb_sectsize + 128, 0, 0,
- XFS_DEFAULT_LOG_COUNT))) {
- xfs_trans_cancel(tp, 0);
- xfs_fs_cmn_err(CE_ALERT, mp,
- "xfs_mount_reset_sbqflags: Superblock update failed!");
- return error;
- }
- xfs_mod_sb(tp, XFS_SB_QFLAGS);
- error = xfs_trans_commit(tp, 0, NULL);
- return error;
-}
-
-STATIC int
-xfs_noquota_init(
- xfs_mount_t *mp,
- uint *needquotamount,
- uint *quotaflags)
-{
- int error = 0;
-
- *quotaflags = 0;
- *needquotamount = B_FALSE;
-
- ASSERT(!XFS_IS_QUOTA_ON(mp));
-
- /*
- * If a file system had quotas running earlier, but decided to
- * mount without -o uquota/pquota/gquota options, revoke the
- * quotachecked license.
- */
- if (mp->m_sb.sb_qflags & XFS_ALL_QUOTA_ACCT) {
- cmn_err(CE_NOTE,
- "XFS resetting qflags for filesystem %s",
- mp->m_fsname);
-
- error = xfs_mount_reset_sbqflags(mp);
- }
- return error;
-}
-
-xfs_qmops_t xfs_qmcore_stub = {
- .xfs_qminit = (xfs_qminit_t) xfs_noquota_init,
- .xfs_qmdone = (xfs_qmdone_t) fs_noerr,
- .xfs_qmmount = (xfs_qmmount_t) fs_noerr,
- .xfs_qmunmount = (xfs_qmunmount_t) fs_noerr,
- .xfs_dqrele = (xfs_dqrele_t) fs_noerr,
- .xfs_dqattach = (xfs_dqattach_t) fs_noerr,
- .xfs_dqdetach = (xfs_dqdetach_t) fs_noerr,
- .xfs_dqpurgeall = (xfs_dqpurgeall_t) fs_noerr,
- .xfs_dqvopalloc = (xfs_dqvopalloc_t) fs_noerr,
- .xfs_dqvopcreate = (xfs_dqvopcreate_t) fs_noerr,
- .xfs_dqvoprename = (xfs_dqvoprename_t) fs_noerr,
- .xfs_dqvopchown = xfs_dqvopchown_default,
- .xfs_dqvopchownresv = (xfs_dqvopchownresv_t) fs_noerr,
-};
diff --git a/sys/gnu/fs/xfs/xfs_quota.h b/sys/gnu/fs/xfs/xfs_quota.h
deleted file mode 100644
index 7fbef97..0000000
--- a/sys/gnu/fs/xfs/xfs_quota.h
+++ /dev/null
@@ -1,372 +0,0 @@
-/*
- * Copyright (c) 2000-2005 Silicon Graphics, Inc.
- * All Rights Reserved.
- *
- * 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.
- *
- * This program is distributed in the hope that it would 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 the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- */
-#ifndef __XFS_QUOTA_H__
-#define __XFS_QUOTA_H__
-
-/*
- * The ondisk form of a dquot structure.
- */
-#define XFS_DQUOT_MAGIC 0x4451 /* 'DQ' */
-#define XFS_DQUOT_VERSION (u_int8_t)0x01 /* latest version number */
-
-/*
- * uid_t and gid_t are hard-coded to 32 bits in the inode.
- * Hence, an 'id' in a dquot is 32 bits..
- */
-typedef __uint32_t xfs_dqid_t;
-
-/*
- * Even though users may not have quota limits occupying all 64-bits,
- * they may need 64-bit accounting. Hence, 64-bit quota-counters,
- * and quota-limits. This is a waste in the common case, but hey ...
- */
-typedef __uint64_t xfs_qcnt_t;
-typedef __uint16_t xfs_qwarncnt_t;
-
-/*
- * This is the main portion of the on-disk representation of quota
- * information for a user. This is the q_core of the xfs_dquot_t that
- * is kept in kernel memory. We pad this with some more expansion room
- * to construct the on disk structure.
- */
-typedef struct xfs_disk_dquot {
- __be16 d_magic; /* dquot magic = XFS_DQUOT_MAGIC */
- __u8 d_version; /* dquot version */
- __u8 d_flags; /* XFS_DQ_USER/PROJ/GROUP */
- __be32 d_id; /* user,project,group id */
- __be64 d_blk_hardlimit;/* absolute limit on disk blks */
- __be64 d_blk_softlimit;/* preferred limit on disk blks */
- __be64 d_ino_hardlimit;/* maximum # allocated inodes */
- __be64 d_ino_softlimit;/* preferred inode limit */
- __be64 d_bcount; /* disk blocks owned by the user */
- __be64 d_icount; /* inodes owned by the user */
- __be32 d_itimer; /* zero if within inode limits if not,
- this is when we refuse service */
- __be32 d_btimer; /* similar to above; for disk blocks */
- __be16 d_iwarns; /* warnings issued wrt num inodes */
- __be16 d_bwarns; /* warnings issued wrt disk blocks */
- __be32 d_pad0; /* 64 bit align */
- __be64 d_rtb_hardlimit;/* absolute limit on realtime blks */
- __be64 d_rtb_softlimit;/* preferred limit on RT disk blks */
- __be64 d_rtbcount; /* realtime blocks owned */
- __be32 d_rtbtimer; /* similar to above; for RT disk blocks */
- __be16 d_rtbwarns; /* warnings issued wrt RT disk blocks */
- __be16 d_pad;
-} xfs_disk_dquot_t;
-
-/*
- * This is what goes on disk. This is separated from the xfs_disk_dquot because
- * carrying the unnecessary padding would be a waste of memory.
- */
-typedef struct xfs_dqblk {
- xfs_disk_dquot_t dd_diskdq; /* portion that lives incore as well */
- char dd_fill[32]; /* filling for posterity */
-} xfs_dqblk_t;
-
-/*
- * flags for q_flags field in the dquot.
- */
-#define XFS_DQ_USER 0x0001 /* a user quota */
-#define XFS_DQ_PROJ 0x0002 /* project quota */
-#define XFS_DQ_GROUP 0x0004 /* a group quota */
-#define XFS_DQ_FLOCKED 0x0008 /* flush lock taken */
-#define XFS_DQ_DIRTY 0x0010 /* dquot is dirty */
-#define XFS_DQ_WANT 0x0020 /* for lookup/reclaim race */
-#define XFS_DQ_INACTIVE 0x0040 /* dq off mplist & hashlist */
-#define XFS_DQ_MARKER 0x0080 /* sentinel */
-
-#define XFS_DQ_ALLTYPES (XFS_DQ_USER|XFS_DQ_PROJ|XFS_DQ_GROUP)
-
-/*
- * In the worst case, when both user and group quotas are on,
- * we can have a max of three dquots changing in a single transaction.
- */
-#define XFS_DQUOT_LOGRES(mp) (sizeof(xfs_disk_dquot_t) * 3)
-
-
-/*
- * These are the structures used to lay out dquots and quotaoff
- * records on the log. Quite similar to those of inodes.
- */
-
-/*
- * log format struct for dquots.
- * The first two fields must be the type and size fitting into
- * 32 bits : log_recovery code assumes that.
- */
-typedef struct xfs_dq_logformat {
- __uint16_t qlf_type; /* dquot log item type */
- __uint16_t qlf_size; /* size of this item */
- xfs_dqid_t qlf_id; /* usr/grp/proj id : 32 bits */
- __int64_t qlf_blkno; /* blkno of dquot buffer */
- __int32_t qlf_len; /* len of dquot buffer */
- __uint32_t qlf_boffset; /* off of dquot in buffer */
-} xfs_dq_logformat_t;
-
-/*
- * log format struct for QUOTAOFF records.
- * The first two fields must be the type and size fitting into
- * 32 bits : log_recovery code assumes that.
- * We write two LI_QUOTAOFF logitems per quotaoff, the last one keeps a pointer
- * to the first and ensures that the first logitem is taken out of the AIL
- * only when the last one is securely committed.
- */
-typedef struct xfs_qoff_logformat {
- unsigned short qf_type; /* quotaoff log item type */
- unsigned short qf_size; /* size of this item */
- unsigned int qf_flags; /* USR and/or GRP */
- char qf_pad[12]; /* padding for future */
-} xfs_qoff_logformat_t;
-
-
-/*
- * Disk quotas status in m_qflags, and also sb_qflags. 16 bits.
- */
-#define XFS_UQUOTA_ACCT 0x0001 /* user quota accounting ON */
-#define XFS_UQUOTA_ENFD 0x0002 /* user quota limits enforced */
-#define XFS_UQUOTA_CHKD 0x0004 /* quotacheck run on usr quotas */
-#define XFS_PQUOTA_ACCT 0x0008 /* project quota accounting ON */
-#define XFS_OQUOTA_ENFD 0x0010 /* other (grp/prj) quota limits enforced */
-#define XFS_OQUOTA_CHKD 0x0020 /* quotacheck run on other (grp/prj) quotas */
-#define XFS_GQUOTA_ACCT 0x0040 /* group quota accounting ON */
-
-/*
- * Quota Accounting/Enforcement flags
- */
-#define XFS_ALL_QUOTA_ACCT \
- (XFS_UQUOTA_ACCT | XFS_GQUOTA_ACCT | XFS_PQUOTA_ACCT)
-#define XFS_ALL_QUOTA_ENFD (XFS_UQUOTA_ENFD | XFS_OQUOTA_ENFD)
-#define XFS_ALL_QUOTA_CHKD (XFS_UQUOTA_CHKD | XFS_OQUOTA_CHKD)
-
-#define XFS_IS_QUOTA_RUNNING(mp) ((mp)->m_qflags & XFS_ALL_QUOTA_ACCT)
-#define XFS_IS_QUOTA_ENFORCED(mp) ((mp)->m_qflags & XFS_ALL_QUOTA_ENFD)
-#define XFS_IS_UQUOTA_RUNNING(mp) ((mp)->m_qflags & XFS_UQUOTA_ACCT)
-#define XFS_IS_PQUOTA_RUNNING(mp) ((mp)->m_qflags & XFS_PQUOTA_ACCT)
-#define XFS_IS_GQUOTA_RUNNING(mp) ((mp)->m_qflags & XFS_GQUOTA_ACCT)
-
-/*
- * Incore only flags for quotaoff - these bits get cleared when quota(s)
- * are in the process of getting turned off. These flags are in m_qflags but
- * never in sb_qflags.
- */
-#define XFS_UQUOTA_ACTIVE 0x0100 /* uquotas are being turned off */
-#define XFS_PQUOTA_ACTIVE 0x0200 /* pquotas are being turned off */
-#define XFS_GQUOTA_ACTIVE 0x0400 /* gquotas are being turned off */
-
-/*
- * Checking XFS_IS_*QUOTA_ON() while holding any inode lock guarantees
- * quota will be not be switched off as long as that inode lock is held.
- */
-#define XFS_IS_QUOTA_ON(mp) ((mp)->m_qflags & (XFS_UQUOTA_ACTIVE | \
- XFS_GQUOTA_ACTIVE | \
- XFS_PQUOTA_ACTIVE))
-#define XFS_IS_OQUOTA_ON(mp) ((mp)->m_qflags & (XFS_GQUOTA_ACTIVE | \
- XFS_PQUOTA_ACTIVE))
-#define XFS_IS_UQUOTA_ON(mp) ((mp)->m_qflags & XFS_UQUOTA_ACTIVE)
-#define XFS_IS_GQUOTA_ON(mp) ((mp)->m_qflags & XFS_GQUOTA_ACTIVE)
-#define XFS_IS_PQUOTA_ON(mp) ((mp)->m_qflags & XFS_PQUOTA_ACTIVE)
-
-/*
- * Flags to tell various functions what to do. Not all of these are meaningful
- * to a single function. None of these XFS_QMOPT_* flags are meant to have
- * persistent values (ie. their values can and will change between versions)
- */
-#define XFS_QMOPT_DQLOCK 0x0000001 /* dqlock */
-#define XFS_QMOPT_DQALLOC 0x0000002 /* alloc dquot ondisk if needed */
-#define XFS_QMOPT_UQUOTA 0x0000004 /* user dquot requested */
-#define XFS_QMOPT_PQUOTA 0x0000008 /* project dquot requested */
-#define XFS_QMOPT_FORCE_RES 0x0000010 /* ignore quota limits */
-#define XFS_QMOPT_DQSUSER 0x0000020 /* don't cache super users dquot */
-#define XFS_QMOPT_SBVERSION 0x0000040 /* change superblock version num */
-#define XFS_QMOPT_QUOTAOFF 0x0000080 /* quotas are being turned off */
-#define XFS_QMOPT_UMOUNTING 0x0000100 /* filesys is being unmounted */
-#define XFS_QMOPT_DOLOG 0x0000200 /* log buf changes (in quotacheck) */
-#define XFS_QMOPT_DOWARN 0x0000400 /* increase warning cnt if needed */
-#define XFS_QMOPT_ILOCKED 0x0000800 /* inode is already locked (excl) */
-#define XFS_QMOPT_DQREPAIR 0x0001000 /* repair dquot if damaged */
-#define XFS_QMOPT_GQUOTA 0x0002000 /* group dquot requested */
-#define XFS_QMOPT_ENOSPC 0x0004000 /* enospc instead of edquot (prj) */
-
-/*
- * flags to xfs_trans_mod_dquot to indicate which field needs to be
- * modified.
- */
-#define XFS_QMOPT_RES_REGBLKS 0x0010000
-#define XFS_QMOPT_RES_RTBLKS 0x0020000
-#define XFS_QMOPT_BCOUNT 0x0040000
-#define XFS_QMOPT_ICOUNT 0x0080000
-#define XFS_QMOPT_RTBCOUNT 0x0100000
-#define XFS_QMOPT_DELBCOUNT 0x0200000
-#define XFS_QMOPT_DELRTBCOUNT 0x0400000
-#define XFS_QMOPT_RES_INOS 0x0800000
-
-/*
- * flags for dqflush and dqflush_all.
- */
-#define XFS_QMOPT_SYNC 0x1000000
-#define XFS_QMOPT_ASYNC 0x2000000
-#define XFS_QMOPT_DELWRI 0x4000000
-
-/*
- * flags for dqalloc.
- */
-#define XFS_QMOPT_INHERIT 0x8000000
-
-/*
- * flags to xfs_trans_mod_dquot.
- */
-#define XFS_TRANS_DQ_RES_BLKS XFS_QMOPT_RES_REGBLKS
-#define XFS_TRANS_DQ_RES_RTBLKS XFS_QMOPT_RES_RTBLKS
-#define XFS_TRANS_DQ_RES_INOS XFS_QMOPT_RES_INOS
-#define XFS_TRANS_DQ_BCOUNT XFS_QMOPT_BCOUNT
-#define XFS_TRANS_DQ_DELBCOUNT XFS_QMOPT_DELBCOUNT
-#define XFS_TRANS_DQ_ICOUNT XFS_QMOPT_ICOUNT
-#define XFS_TRANS_DQ_RTBCOUNT XFS_QMOPT_RTBCOUNT
-#define XFS_TRANS_DQ_DELRTBCOUNT XFS_QMOPT_DELRTBCOUNT
-
-
-#define XFS_QMOPT_QUOTALL \
- (XFS_QMOPT_UQUOTA | XFS_QMOPT_PQUOTA | XFS_QMOPT_GQUOTA)
-#define XFS_QMOPT_RESBLK_MASK (XFS_QMOPT_RES_REGBLKS | XFS_QMOPT_RES_RTBLKS)
-
-#ifdef __KERNEL__
-/*
- * This check is done typically without holding the inode lock;
- * that may seem racy, but it is harmless in the context that it is used.
- * The inode cannot go inactive as long a reference is kept, and
- * therefore if dquot(s) were attached, they'll stay consistent.
- * If, for example, the ownership of the inode changes while
- * we didn't have the inode locked, the appropriate dquot(s) will be
- * attached atomically.
- */
-#define XFS_NOT_DQATTACHED(mp, ip) ((XFS_IS_UQUOTA_ON(mp) &&\
- (ip)->i_udquot == NULL) || \
- (XFS_IS_OQUOTA_ON(mp) && \
- (ip)->i_gdquot == NULL))
-
-#define XFS_QM_NEED_QUOTACHECK(mp) \
- ((XFS_IS_UQUOTA_ON(mp) && \
- (mp->m_sb.sb_qflags & XFS_UQUOTA_CHKD) == 0) || \
- (XFS_IS_GQUOTA_ON(mp) && \
- ((mp->m_sb.sb_qflags & XFS_OQUOTA_CHKD) == 0 || \
- (mp->m_sb.sb_qflags & XFS_PQUOTA_ACCT))) || \
- (XFS_IS_PQUOTA_ON(mp) && \
- ((mp->m_sb.sb_qflags & XFS_OQUOTA_CHKD) == 0 || \
- (mp->m_sb.sb_qflags & XFS_GQUOTA_ACCT))))
-
-#define XFS_MOUNT_QUOTA_SET1 (XFS_UQUOTA_ACCT|XFS_UQUOTA_ENFD|\
- XFS_UQUOTA_CHKD|XFS_PQUOTA_ACCT|\
- XFS_OQUOTA_ENFD|XFS_OQUOTA_CHKD)
-
-#define XFS_MOUNT_QUOTA_SET2 (XFS_UQUOTA_ACCT|XFS_UQUOTA_ENFD|\
- XFS_UQUOTA_CHKD|XFS_GQUOTA_ACCT|\
- XFS_OQUOTA_ENFD|XFS_OQUOTA_CHKD)
-
-#define XFS_MOUNT_QUOTA_ALL (XFS_UQUOTA_ACCT|XFS_UQUOTA_ENFD|\
- XFS_UQUOTA_CHKD|XFS_PQUOTA_ACCT|\
- XFS_OQUOTA_ENFD|XFS_OQUOTA_CHKD|\
- XFS_GQUOTA_ACCT)
-#define XFS_MOUNT_QUOTA_MASK (XFS_MOUNT_QUOTA_ALL | XFS_UQUOTA_ACTIVE | \
- XFS_GQUOTA_ACTIVE | XFS_PQUOTA_ACTIVE)
-
-
-/*
- * The structure kept inside the xfs_trans_t keep track of dquot changes
- * within a transaction and apply them later.
- */
-typedef struct xfs_dqtrx {
- struct xfs_dquot *qt_dquot; /* the dquot this refers to */
- ulong qt_blk_res; /* blks reserved on a dquot */
- ulong qt_blk_res_used; /* blks used from the reservation */
- ulong qt_ino_res; /* inode reserved on a dquot */
- ulong qt_ino_res_used; /* inodes used from the reservation */
- long qt_bcount_delta; /* dquot blk count changes */
- long qt_delbcnt_delta; /* delayed dquot blk count changes */
- long qt_icount_delta; /* dquot inode count changes */
- ulong qt_rtblk_res; /* # blks reserved on a dquot */
- ulong qt_rtblk_res_used;/* # blks used from reservation */
- long qt_rtbcount_delta;/* dquot realtime blk changes */
- long qt_delrtb_delta; /* delayed RT blk count changes */
-} xfs_dqtrx_t;
-
-/*
- * Dquot transaction functions, used if quota is enabled.
- */
-typedef void (*qo_dup_dqinfo_t)(struct xfs_trans *, struct xfs_trans *);
-typedef void (*qo_mod_dquot_byino_t)(struct xfs_trans *,
- struct xfs_inode *, uint, long);
-typedef void (*qo_free_dqinfo_t)(struct xfs_trans *);
-typedef void (*qo_apply_dquot_deltas_t)(struct xfs_trans *);
-typedef void (*qo_unreserve_and_mod_dquots_t)(struct xfs_trans *);
-typedef int (*qo_reserve_quota_nblks_t)(
- struct xfs_trans *, struct xfs_mount *,
- struct xfs_inode *, long, long, uint);
-typedef int (*qo_reserve_quota_bydquots_t)(
- struct xfs_trans *, struct xfs_mount *,
- struct xfs_dquot *, struct xfs_dquot *,
- long, long, uint);
-typedef struct xfs_dqtrxops {
- qo_dup_dqinfo_t qo_dup_dqinfo;
- qo_free_dqinfo_t qo_free_dqinfo;
- qo_mod_dquot_byino_t qo_mod_dquot_byino;
- qo_apply_dquot_deltas_t qo_apply_dquot_deltas;
- qo_reserve_quota_nblks_t qo_reserve_quota_nblks;
- qo_reserve_quota_bydquots_t qo_reserve_quota_bydquots;
- qo_unreserve_and_mod_dquots_t qo_unreserve_and_mod_dquots;
-} xfs_dqtrxops_t;
-
-#define XFS_DQTRXOP(mp, tp, op, args...) \
- ((mp)->m_qm_ops.xfs_dqtrxops ? \
- ((mp)->m_qm_ops.xfs_dqtrxops->op)(tp, ## args) : 0)
-
-#define XFS_DQTRXOP_VOID(mp, tp, op, args...) \
- ((mp)->m_qm_ops.xfs_dqtrxops ? \
- ((mp)->m_qm_ops.xfs_dqtrxops->op)(tp, ## args) : (void)0)
-
-#define XFS_TRANS_DUP_DQINFO(mp, otp, ntp) \
- XFS_DQTRXOP_VOID(mp, otp, qo_dup_dqinfo, ntp)
-#define XFS_TRANS_FREE_DQINFO(mp, tp) \
- XFS_DQTRXOP_VOID(mp, tp, qo_free_dqinfo)
-#define XFS_TRANS_MOD_DQUOT_BYINO(mp, tp, ip, field, delta) \
- XFS_DQTRXOP_VOID(mp, tp, qo_mod_dquot_byino, ip, field, delta)
-#define XFS_TRANS_APPLY_DQUOT_DELTAS(mp, tp) \
- XFS_DQTRXOP_VOID(mp, tp, qo_apply_dquot_deltas)
-#define XFS_TRANS_RESERVE_QUOTA_NBLKS(mp, tp, ip, nblks, ninos, fl) \
- XFS_DQTRXOP(mp, tp, qo_reserve_quota_nblks, mp, ip, nblks, ninos, fl)
-#define XFS_TRANS_RESERVE_QUOTA_BYDQUOTS(mp, tp, ud, gd, nb, ni, fl) \
- XFS_DQTRXOP(mp, tp, qo_reserve_quota_bydquots, mp, ud, gd, nb, ni, fl)
-#define XFS_TRANS_UNRESERVE_AND_MOD_DQUOTS(mp, tp) \
- XFS_DQTRXOP_VOID(mp, tp, qo_unreserve_and_mod_dquots)
-
-#define XFS_TRANS_UNRESERVE_QUOTA_NBLKS(mp, tp, ip, nblks, ninos, flags) \
- XFS_TRANS_RESERVE_QUOTA_NBLKS(mp, tp, ip, -(nblks), -(ninos), flags)
-#define XFS_TRANS_RESERVE_QUOTA(mp, tp, ud, gd, nb, ni, f) \
- XFS_TRANS_RESERVE_QUOTA_BYDQUOTS(mp, tp, ud, gd, nb, ni, \
- f | XFS_QMOPT_RES_REGBLKS)
-#define XFS_TRANS_UNRESERVE_QUOTA(mp, tp, ud, gd, nb, ni, f) \
- XFS_TRANS_RESERVE_QUOTA_BYDQUOTS(mp, tp, ud, gd, -(nb), -(ni), \
- f | XFS_QMOPT_RES_REGBLKS)
-
-extern int xfs_qm_dqcheck(xfs_disk_dquot_t *, xfs_dqid_t, uint, uint, char *);
-extern int xfs_mount_reset_sbqflags(struct xfs_mount *);
-
-extern struct bhv_vfsops xfs_qmops;
-
-#endif /* __KERNEL__ */
-
-#endif /* __XFS_QUOTA_H__ */
diff --git a/sys/gnu/fs/xfs/xfs_refcache.c b/sys/gnu/fs/xfs/xfs_refcache.c
deleted file mode 100644
index 09918b5..0000000
--- a/sys/gnu/fs/xfs/xfs_refcache.c
+++ /dev/null
@@ -1,431 +0,0 @@
-/*
- * Copyright (c) 2000-2003,2005 Silicon Graphics, Inc.
- * All Rights Reserved.
- *
- * 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.
- *
- * This program is distributed in the hope that it would 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 the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- */
-#include "xfs.h"
-#include "xfs_fs.h"
-#include "xfs_types.h"
-#include "xfs_bit.h"
-#include "xfs_log.h"
-#include "xfs_inum.h"
-#include "xfs_trans.h"
-#include "xfs_sb.h"
-#include "xfs_ag.h"
-#include "xfs_dir.h"
-#include "xfs_dir2.h"
-#include "xfs_dmapi.h"
-#include "xfs_mount.h"
-#include "xfs_bmap_btree.h"
-#include "xfs_alloc_btree.h"
-#include "xfs_ialloc_btree.h"
-#include "xfs_dir_sf.h"
-#include "xfs_dir2_sf.h"
-#include "xfs_attr_sf.h"
-#include "xfs_dinode.h"
-#include "xfs_inode.h"
-#include "xfs_inode_item.h"
-#include "xfs_itable.h"
-#include "xfs_btree.h"
-#include "xfs_alloc.h"
-#include "xfs_ialloc.h"
-#include "xfs_bmap.h"
-#include "xfs_attr.h"
-#include "xfs_error.h"
-#include "xfs_buf_item.h"
-#include "xfs_refcache.h"
-
-STATIC lock_t xfs_refcache_lock;
-STATIC xfs_inode_t **xfs_refcache;
-STATIC int xfs_refcache_index;
-STATIC int xfs_refcache_busy;
-STATIC int xfs_refcache_count;
-
-void
-xfs_refcache_init(void)
-{
- spinlock_init(&xfs_refcache_lock, "xfs_refcache");
-}
-/*
- * Insert the given inode into the reference cache.
- */
-void
-xfs_refcache_insert(
- xfs_inode_t *ip)
-{
- vnode_t *vp;
- xfs_inode_t *release_ip;
- xfs_inode_t **refcache;
-
- ASSERT(ismrlocked(&(ip->i_iolock), MR_UPDATE));
-
- /*
- * If an unmount is busy blowing entries out of the cache,
- * then don't bother.
- */
- if (xfs_refcache_busy) {
- return;
- }
-
- /*
- * If we tuned the refcache down to zero, don't do anything.
- */
- if (!xfs_refcache_size) {
- return;
- }
-
- /*
- * The inode is already in the refcache, so don't bother
- * with it.
- */
- if (ip->i_refcache != NULL) {
- return;
- }
-
- vp = XFS_ITOV(ip);
- /* ASSERT(vp->v_count > 0); */
- VN_HOLD(vp);
-
- /*
- * We allocate the reference cache on use so that we don't
- * waste the memory on systems not being used as NFS servers.
- */
- if (xfs_refcache == NULL) {
- refcache = (xfs_inode_t **)kmem_zalloc(XFS_REFCACHE_SIZE_MAX *
- sizeof(xfs_inode_t *),
- KM_SLEEP);
- } else {
- refcache = NULL;
- }
-
- spin_lock(&xfs_refcache_lock);
-
- /*
- * If we allocated memory for the refcache above and it still
- * needs it, then use the memory we allocated. Otherwise we'll
- * free the memory below.
- */
- if (refcache != NULL) {
- if (xfs_refcache == NULL) {
- xfs_refcache = refcache;
- refcache = NULL;
- }
- }
-
- /*
- * If an unmount is busy clearing out the cache, don't add new
- * entries to it.
- */
- if (xfs_refcache_busy) {
- spin_unlock(&xfs_refcache_lock);
- VN_RELE(vp);
- /*
- * If we allocated memory for the refcache above but someone
- * else beat us to using it, then free the memory now.
- */
- if (refcache != NULL) {
- kmem_free(refcache,
- XFS_REFCACHE_SIZE_MAX * sizeof(xfs_inode_t *));
- }
- return;
- }
- release_ip = xfs_refcache[xfs_refcache_index];
- if (release_ip != NULL) {
- release_ip->i_refcache = NULL;
- xfs_refcache_count--;
- ASSERT(xfs_refcache_count >= 0);
- }
- xfs_refcache[xfs_refcache_index] = ip;
- ASSERT(ip->i_refcache == NULL);
- ip->i_refcache = &(xfs_refcache[xfs_refcache_index]);
- xfs_refcache_count++;
- ASSERT(xfs_refcache_count <= xfs_refcache_size);
- xfs_refcache_index++;
- if (xfs_refcache_index == xfs_refcache_size) {
- xfs_refcache_index = 0;
- }
- spin_unlock(&xfs_refcache_lock);
-
- /*
- * Save the pointer to the inode to be released so that we can
- * VN_RELE it once we've dropped our inode locks in xfs_rwunlock().
- * The pointer may be NULL, but that's OK.
- */
- ip->i_release = release_ip;
-
- /*
- * If we allocated memory for the refcache above but someone
- * else beat us to using it, then free the memory now.
- */
- if (refcache != NULL) {
- kmem_free(refcache,
- XFS_REFCACHE_SIZE_MAX * sizeof(xfs_inode_t *));
- }
-}
-
-
-/*
- * If the given inode is in the reference cache, purge its entry and
- * release the reference on the vnode.
- */
-void
-xfs_refcache_purge_ip(
- xfs_inode_t *ip)
-{
- vnode_t *vp;
- int error;
-
- /*
- * If we're not pointing to our entry in the cache, then
- * we must not be in the cache.
- */
- if (ip->i_refcache == NULL) {
- return;
- }
-
- spin_lock(&xfs_refcache_lock);
- if (ip->i_refcache == NULL) {
- spin_unlock(&xfs_refcache_lock);
- return;
- }
-
- /*
- * Clear both our pointer to the cache entry and its pointer
- * back to us.
- */
- ASSERT(*(ip->i_refcache) == ip);
- *(ip->i_refcache) = NULL;
- ip->i_refcache = NULL;
- xfs_refcache_count--;
- ASSERT(xfs_refcache_count >= 0);
- spin_unlock(&xfs_refcache_lock);
-
- vp = XFS_ITOV(ip);
- /* ASSERT(vp->v_count > 1); */
- VOP_RELEASE(vp, error);
- VN_RELE(vp);
-}
-
-
-/*
- * This is called from the XFS unmount code to purge all entries for the
- * given mount from the cache. It uses the refcache busy counter to
- * make sure that new entries are not added to the cache as we purge them.
- */
-void
-xfs_refcache_purge_mp(
- xfs_mount_t *mp)
-{
- vnode_t *vp;
- int error, i;
- xfs_inode_t *ip;
-
- if (xfs_refcache == NULL) {
- return;
- }
-
- spin_lock(&xfs_refcache_lock);
- /*
- * Bumping the busy counter keeps new entries from being added
- * to the cache. We use a counter since multiple unmounts could
- * be in here simultaneously.
- */
- xfs_refcache_busy++;
-
- for (i = 0; i < xfs_refcache_size; i++) {
- ip = xfs_refcache[i];
- if ((ip != NULL) && (ip->i_mount == mp)) {
- xfs_refcache[i] = NULL;
- ip->i_refcache = NULL;
- xfs_refcache_count--;
- ASSERT(xfs_refcache_count >= 0);
- spin_unlock(&xfs_refcache_lock);
- vp = XFS_ITOV(ip);
- VOP_RELEASE(vp, error);
- VN_RELE(vp);
- spin_lock(&xfs_refcache_lock);
- }
- }
-
- xfs_refcache_busy--;
- ASSERT(xfs_refcache_busy >= 0);
- spin_unlock(&xfs_refcache_lock);
-}
-
-
-/*
- * This is called from the XFS sync code to ensure that the refcache
- * is emptied out over time. We purge a small number of entries with
- * each call.
- */
-void
-xfs_refcache_purge_some(xfs_mount_t *mp)
-{
- int error, i;
- xfs_inode_t *ip;
- int iplist_index;
- xfs_inode_t **iplist;
-
- if ((xfs_refcache == NULL) || (xfs_refcache_count == 0)) {
- return;
- }
-
- iplist_index = 0;
- iplist = (xfs_inode_t **)kmem_zalloc(xfs_refcache_purge_count *
- sizeof(xfs_inode_t *), KM_SLEEP);
-
- spin_lock(&xfs_refcache_lock);
-
- /*
- * Store any inodes we find in the next several entries
- * into the iplist array to be released after dropping
- * the spinlock. We always start looking from the currently
- * oldest place in the cache. We move the refcache index
- * forward as we go so that we are sure to eventually clear
- * out the entire cache when the system goes idle.
- */
- for (i = 0; i < xfs_refcache_purge_count; i++) {
- ip = xfs_refcache[xfs_refcache_index];
- if (ip != NULL) {
- xfs_refcache[xfs_refcache_index] = NULL;
- ip->i_refcache = NULL;
- xfs_refcache_count--;
- ASSERT(xfs_refcache_count >= 0);
- iplist[iplist_index] = ip;
- iplist_index++;
- }
- xfs_refcache_index++;
- if (xfs_refcache_index == xfs_refcache_size) {
- xfs_refcache_index = 0;
- }
- }
-
- spin_unlock(&xfs_refcache_lock);
-
- /*
- * Now drop the inodes we collected.
- */
- for (i = 0; i < iplist_index; i++) {
- VOP_RELEASE(XFS_ITOV(iplist[i]), error);
- VN_RELE(XFS_ITOV(iplist[i]));
- }
-
- kmem_free(iplist, xfs_refcache_purge_count *
- sizeof(xfs_inode_t *));
-}
-
-/*
- * This is called when the refcache is dynamically resized
- * via a sysctl.
- *
- * If the new size is smaller than the old size, purge all
- * entries in slots greater than the new size, and move
- * the index if necessary.
- *
- * If the refcache hasn't even been allocated yet, or the
- * new size is larger than the old size, just set the value
- * of xfs_refcache_size.
- */
-
-void
-xfs_refcache_resize(int xfs_refcache_new_size)
-{
- int i;
- xfs_inode_t *ip;
- int iplist_index = 0;
- xfs_inode_t **iplist;
- int error;
-
- /*
- * If the new size is smaller than the current size,
- * purge entries to create smaller cache, and
- * reposition index if necessary.
- * Don't bother if no refcache yet.
- */
- if (xfs_refcache && (xfs_refcache_new_size < xfs_refcache_size)) {
-
- iplist = (xfs_inode_t **)kmem_zalloc(XFS_REFCACHE_SIZE_MAX *
- sizeof(xfs_inode_t *), KM_SLEEP);
-
- spin_lock(&xfs_refcache_lock);
-
- for (i = xfs_refcache_new_size; i < xfs_refcache_size; i++) {
- ip = xfs_refcache[i];
- if (ip != NULL) {
- xfs_refcache[i] = NULL;
- ip->i_refcache = NULL;
- xfs_refcache_count--;
- ASSERT(xfs_refcache_count >= 0);
- iplist[iplist_index] = ip;
- iplist_index++;
- }
- }
-
- xfs_refcache_size = xfs_refcache_new_size;
-
- /*
- * Move index to beginning of cache if it's now past the end
- */
- if (xfs_refcache_index >= xfs_refcache_new_size)
- xfs_refcache_index = 0;
-
- spin_unlock(&xfs_refcache_lock);
-
- /*
- * Now drop the inodes we collected.
- */
- for (i = 0; i < iplist_index; i++) {
- VOP_RELEASE(XFS_ITOV(iplist[i]), error);
- VN_RELE(XFS_ITOV(iplist[i]));
- }
-
- kmem_free(iplist, XFS_REFCACHE_SIZE_MAX *
- sizeof(xfs_inode_t *));
- } else {
- spin_lock(&xfs_refcache_lock);
- xfs_refcache_size = xfs_refcache_new_size;
- spin_unlock(&xfs_refcache_lock);
- }
-}
-
-void
-xfs_refcache_iunlock(
- xfs_inode_t *ip,
- uint lock_flags)
-{
- xfs_inode_t *release_ip;
- int error;
-
- release_ip = ip->i_release;
- ip->i_release = NULL;
-
- xfs_iunlock(ip, lock_flags);
-
- if (release_ip != NULL) {
- VOP_RELEASE(XFS_ITOV(release_ip), error);
- VN_RELE(XFS_ITOV(release_ip));
- }
-}
-
-void
-xfs_refcache_destroy(void)
-{
- if (xfs_refcache) {
- kmem_free(xfs_refcache,
- XFS_REFCACHE_SIZE_MAX * sizeof(xfs_inode_t *));
- xfs_refcache = NULL;
- }
- spinlock_destroy(&xfs_refcache_lock);
-}
diff --git a/sys/gnu/fs/xfs/xfs_refcache.h b/sys/gnu/fs/xfs/xfs_refcache.h
deleted file mode 100644
index a0a592f..0000000
--- a/sys/gnu/fs/xfs/xfs_refcache.h
+++ /dev/null
@@ -1,54 +0,0 @@
-/*
- * Copyright (c) 2000-2003,2005 Silicon Graphics, Inc.
- * All Rights Reserved.
- *
- * 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.
- *
- * This program is distributed in the hope that it would 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 the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- */
-#ifndef __XFS_REFCACHE_H__
-#define __XFS_REFCACHE_H__
-
-#ifdef HAVE_REFCACHE
-/*
- * Maximum size (in inodes) for the NFS reference cache
- */
-#define XFS_REFCACHE_SIZE_MAX 512
-
-struct xfs_inode;
-struct xfs_mount;
-
-extern void xfs_refcache_init(void);
-extern void xfs_refcache_insert(struct xfs_inode *);
-extern void xfs_refcache_purge_ip(struct xfs_inode *);
-extern void xfs_refcache_purge_mp(struct xfs_mount *);
-extern void xfs_refcache_purge_some(struct xfs_mount *);
-extern void xfs_refcache_resize(int);
-extern void xfs_refcache_destroy(void);
-
-extern void xfs_refcache_iunlock(struct xfs_inode *, uint);
-
-#else
-
-#define xfs_refcache_init() do { } while (0)
-#define xfs_refcache_insert(ip) do { } while (0)
-#define xfs_refcache_purge_ip(ip) do { } while (0)
-#define xfs_refcache_purge_mp(mp) do { } while (0)
-#define xfs_refcache_purge_some(mp) do { } while (0)
-#define xfs_refcache_resize(size) do { } while (0)
-#define xfs_refcache_destroy() do { } while (0)
-
-#define xfs_refcache_iunlock(ip, flags) xfs_iunlock(ip, flags)
-
-#endif
-
-#endif /* __XFS_REFCACHE_H__ */
diff --git a/sys/gnu/fs/xfs/xfs_rename.c b/sys/gnu/fs/xfs/xfs_rename.c
deleted file mode 100644
index 995a4ec..0000000
--- a/sys/gnu/fs/xfs/xfs_rename.c
+++ /dev/null
@@ -1,636 +0,0 @@
-/*
- * Copyright (c) 2000-2003,2005 Silicon Graphics, Inc.
- * All Rights Reserved.
- *
- * 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.
- *
- * This program is distributed in the hope that it would 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 the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- */
-#include "xfs.h"
-#include "xfs_fs.h"
-#include "xfs_types.h"
-#include "xfs_log.h"
-#include "xfs_inum.h"
-#include "xfs_trans.h"
-#include "xfs_sb.h"
-#include "xfs_dir.h"
-#include "xfs_dir2.h"
-#include "xfs_dmapi.h"
-#include "xfs_mount.h"
-#include "xfs_da_btree.h"
-#include "xfs_bmap_btree.h"
-#include "xfs_dir_sf.h"
-#include "xfs_dir2_sf.h"
-#include "xfs_attr_sf.h"
-#include "xfs_dinode.h"
-#include "xfs_inode.h"
-#include "xfs_inode_item.h"
-#include "xfs_bmap.h"
-#include "xfs_error.h"
-#include "xfs_quota.h"
-#include "xfs_refcache.h"
-#include "xfs_utils.h"
-#include "xfs_trans_space.h"
-#include "xfs_dir_leaf.h"
-
-
-/*
- * Given an array of up to 4 inode pointers, unlock the pointed to inodes.
- * If there are fewer than 4 entries in the array, the empty entries will
- * be at the end and will have NULL pointers in them.
- */
-STATIC void
-xfs_rename_unlock4(
- xfs_inode_t **i_tab,
- uint lock_mode)
-{
- int i;
-
- xfs_iunlock(i_tab[0], lock_mode);
- for (i = 1; i < 4; i++) {
- if (i_tab[i] == NULL) {
- break;
- }
- /*
- * Watch out for duplicate entries in the table.
- */
- if (i_tab[i] != i_tab[i-1]) {
- xfs_iunlock(i_tab[i], lock_mode);
- }
- }
-}
-
-#ifdef DEBUG
-int xfs_rename_skip, xfs_rename_nskip;
-#endif
-
-/*
- * The following routine will acquire the locks required for a rename
- * operation. The code understands the semantics of renames and will
- * validate that name1 exists under dp1 & that name2 may or may not
- * exist under dp2.
- *
- * We are renaming dp1/name1 to dp2/name2.
- *
- * Return ENOENT if dp1 does not exist, other lookup errors, or 0 for success.
- */
-STATIC int
-xfs_lock_for_rename(
- xfs_inode_t *dp1, /* old (source) directory inode */
- xfs_inode_t *dp2, /* new (target) directory inode */
- vname_t *vname1,/* old entry name */
- vname_t *vname2,/* new entry name */
- xfs_inode_t **ipp1, /* inode of old entry */
- xfs_inode_t **ipp2, /* inode of new entry, if it
- already exists, NULL otherwise. */
- xfs_inode_t **i_tab,/* array of inode returned, sorted */
- int *num_inodes) /* number of inodes in array */
-{
- xfs_inode_t *ip1, *ip2, *temp;
- xfs_ino_t inum1, inum2;
- int error;
- int i, j;
- uint lock_mode;
- int diff_dirs = (dp1 != dp2);
-
- ip2 = NULL;
-
- /*
- * First, find out the current inums of the entries so that we
- * can determine the initial locking order. We'll have to
- * sanity check stuff after all the locks have been acquired
- * to see if we still have the right inodes, directories, etc.
- */
- lock_mode = xfs_ilock_map_shared(dp1);
- error = xfs_get_dir_entry(vname1, &ip1);
- if (error) {
- xfs_iunlock_map_shared(dp1, lock_mode);
- return error;
- }
-
- inum1 = ip1->i_ino;
-
- ASSERT(ip1);
- ITRACE(ip1);
-
- /*
- * Unlock dp1 and lock dp2 if they are different.
- */
-
- if (diff_dirs) {
- xfs_iunlock_map_shared(dp1, lock_mode);
- lock_mode = xfs_ilock_map_shared(dp2);
- }
-
- error = xfs_dir_lookup_int(XFS_ITOBHV(dp2), lock_mode,
- vname2, &inum2, &ip2);
- if (error == ENOENT) { /* target does not need to exist. */
- inum2 = 0;
- } else if (error) {
- /*
- * If dp2 and dp1 are the same, the next line unlocks dp1.
- * Got it?
- */
- xfs_iunlock_map_shared(dp2, lock_mode);
- IRELE (ip1);
- return error;
- } else {
- ITRACE(ip2);
- }
-
- /*
- * i_tab contains a list of pointers to inodes. We initialize
- * the table here & we'll sort it. We will then use it to
- * order the acquisition of the inode locks.
- *
- * Note that the table may contain duplicates. e.g., dp1 == dp2.
- */
- i_tab[0] = dp1;
- i_tab[1] = dp2;
- i_tab[2] = ip1;
- if (inum2 == 0) {
- *num_inodes = 3;
- i_tab[3] = NULL;
- } else {
- *num_inodes = 4;
- i_tab[3] = ip2;
- }
-
- /*
- * Sort the elements via bubble sort. (Remember, there are at
- * most 4 elements to sort, so this is adequate.)
- */
- for (i=0; i < *num_inodes; i++) {
- for (j=1; j < *num_inodes; j++) {
- if (i_tab[j]->i_ino < i_tab[j-1]->i_ino) {
- temp = i_tab[j];
- i_tab[j] = i_tab[j-1];
- i_tab[j-1] = temp;
- }
- }
- }
-
- /*
- * We have dp2 locked. If it isn't first, unlock it.
- * If it is first, tell xfs_lock_inodes so it can skip it
- * when locking. if dp1 == dp2, xfs_lock_inodes will skip both
- * since they are equal. xfs_lock_inodes needs all these inodes
- * so that it can unlock and retry if there might be a dead-lock
- * potential with the log.
- */
-
- if (i_tab[0] == dp2 && lock_mode == XFS_ILOCK_SHARED) {
-#ifdef DEBUG
- xfs_rename_skip++;
-#endif
- xfs_lock_inodes(i_tab, *num_inodes, 1, XFS_ILOCK_SHARED);
- } else {
-#ifdef DEBUG
- xfs_rename_nskip++;
-#endif
- xfs_iunlock_map_shared(dp2, lock_mode);
- xfs_lock_inodes(i_tab, *num_inodes, 0, XFS_ILOCK_SHARED);
- }
-
- /*
- * Set the return value. Null out any unused entries in i_tab.
- */
- *ipp1 = *ipp2 = NULL;
- for (i=0; i < *num_inodes; i++) {
- if (i_tab[i]->i_ino == inum1) {
- *ipp1 = i_tab[i];
- }
- if (i_tab[i]->i_ino == inum2) {
- *ipp2 = i_tab[i];
- }
- }
- for (;i < 4; i++) {
- i_tab[i] = NULL;
- }
- return 0;
-}
-
-/*
- * xfs_rename
- */
-int
-xfs_rename(
- bhv_desc_t *src_dir_bdp,
- vname_t *src_vname,
- xfs_vnode_t *target_dir_vp,
- vname_t *target_vname,
- cred_t *credp)
-{
- xfs_trans_t *tp;
- xfs_inode_t *src_dp, *target_dp, *src_ip, *target_ip;
- xfs_mount_t *mp;
- int new_parent; /* moving to a new dir */
- int src_is_directory; /* src_name is a directory */
- int error;
- xfs_bmap_free_t free_list;
- xfs_fsblock_t first_block;
- int cancel_flags;
- int committed;
- xfs_inode_t *inodes[4];
- int target_ip_dropped = 0; /* dropped target_ip link? */
- xfs_vnode_t *src_dir_vp;
- int spaceres;
- int target_link_zero = 0;
- int num_inodes;
- char *src_name = VNAME(src_vname);
- char *target_name = VNAME(target_vname);
- int src_namelen = VNAMELEN(src_vname);
- int target_namelen = VNAMELEN(target_vname);
-
- src_dir_vp = BHV_TO_VNODE(src_dir_bdp);
- vn_trace_entry(src_dir_vp, "xfs_rename", (inst_t *)__return_address);
- vn_trace_entry(target_dir_vp, "xfs_rename", (inst_t *)__return_address);
-
- /*
- * Find the XFS behavior descriptor for the target directory
- * vnode since it was not handed to us.
- */
- target_dp = xfs_vtoi(target_dir_vp);
- if (target_dp == NULL) {
- return XFS_ERROR(EXDEV);
- }
-
- src_dp = XFS_BHVTOI(src_dir_bdp);
- mp = src_dp->i_mount;
-
- if (DM_EVENT_ENABLED(src_dir_vp->v_vfsp, src_dp, DM_EVENT_RENAME) ||
- DM_EVENT_ENABLED(target_dir_vp->v_vfsp,
- target_dp, DM_EVENT_RENAME)) {
- error = XFS_SEND_NAMESP(mp, DM_EVENT_RENAME,
- src_dir_vp, DM_RIGHT_NULL,
- target_dir_vp, DM_RIGHT_NULL,
- src_name, target_name,
- 0, 0, 0);
- if (error) {
- return error;
- }
- }
- /* Return through std_return after this point. */
-
- /*
- * Lock all the participating inodes. Depending upon whether
- * the target_name exists in the target directory, and
- * whether the target directory is the same as the source
- * directory, we can lock from 2 to 4 inodes.
- * xfs_lock_for_rename() will return ENOENT if src_name
- * does not exist in the source directory.
- */
- tp = NULL;
- error = xfs_lock_for_rename(src_dp, target_dp, src_vname,
- target_vname, &src_ip, &target_ip, inodes,
- &num_inodes);
-
- if (error) {
- /*
- * We have nothing locked, no inode references, and
- * no transaction, so just get out.
- */
- goto std_return;
- }
-
- ASSERT(src_ip != NULL);
-
- if ((src_ip->i_d.di_mode & S_IFMT) == S_IFDIR) {
- /*
- * Check for link count overflow on target_dp
- */
- if (target_ip == NULL && (src_dp != target_dp) &&
- target_dp->i_d.di_nlink >= XFS_MAXLINK) {
- error = XFS_ERROR(EMLINK);
- xfs_rename_unlock4(inodes, XFS_ILOCK_SHARED);
- goto rele_return;
- }
- }
-
- new_parent = (src_dp != target_dp);
- src_is_directory = ((src_ip->i_d.di_mode & S_IFMT) == S_IFDIR);
-
- /*
- * Drop the locks on our inodes so that we can start the transaction.
- */
- xfs_rename_unlock4(inodes, XFS_ILOCK_SHARED);
-
- XFS_BMAP_INIT(&free_list, &first_block);
- tp = xfs_trans_alloc(mp, XFS_TRANS_RENAME);
- cancel_flags = XFS_TRANS_RELEASE_LOG_RES;
- spaceres = XFS_RENAME_SPACE_RES(mp, target_namelen);
- error = xfs_trans_reserve(tp, spaceres, XFS_RENAME_LOG_RES(mp), 0,
- XFS_TRANS_PERM_LOG_RES, XFS_RENAME_LOG_COUNT);
- if (error == ENOSPC) {
- spaceres = 0;
- error = xfs_trans_reserve(tp, 0, XFS_RENAME_LOG_RES(mp), 0,
- XFS_TRANS_PERM_LOG_RES, XFS_RENAME_LOG_COUNT);
- }
- if (error) {
- xfs_trans_cancel(tp, 0);
- goto rele_return;
- }
-
- /*
- * Attach the dquots to the inodes
- */
- if ((error = XFS_QM_DQVOPRENAME(mp, inodes))) {
- xfs_trans_cancel(tp, cancel_flags);
- goto rele_return;
- }
-
- /*
- * Reacquire the inode locks we dropped above.
- */
- xfs_lock_inodes(inodes, num_inodes, 0, XFS_ILOCK_EXCL);
-
- /*
- * Join all the inodes to the transaction. From this point on,
- * we can rely on either trans_commit or trans_cancel to unlock
- * them. Note that we need to add a vnode reference to the
- * directories since trans_commit & trans_cancel will decrement
- * them when they unlock the inodes. Also, we need to be careful
- * not to add an inode to the transaction more than once.
- */
- VN_HOLD(src_dir_vp);
- xfs_trans_ijoin(tp, src_dp, XFS_ILOCK_EXCL);
- if (new_parent) {
- VN_HOLD(target_dir_vp);
- xfs_trans_ijoin(tp, target_dp, XFS_ILOCK_EXCL);
- }
- if ((src_ip != src_dp) && (src_ip != target_dp)) {
- xfs_trans_ijoin(tp, src_ip, XFS_ILOCK_EXCL);
- }
- if ((target_ip != NULL) &&
- (target_ip != src_ip) &&
- (target_ip != src_dp) &&
- (target_ip != target_dp)) {
- xfs_trans_ijoin(tp, target_ip, XFS_ILOCK_EXCL);
- }
-
- /*
- * Set up the target.
- */
- if (target_ip == NULL) {
- /*
- * If there's no space reservation, check the entry will
- * fit before actually inserting it.
- */
- if (spaceres == 0 &&
- (error = XFS_DIR_CANENTER(mp, tp, target_dp, target_name,
- target_namelen))) {
- goto error_return;
- }
- /*
- * If target does not exist and the rename crosses
- * directories, adjust the target directory link count
- * to account for the ".." reference from the new entry.
- */
- error = XFS_DIR_CREATENAME(mp, tp, target_dp, target_name,
- target_namelen, src_ip->i_ino,
- &first_block, &free_list, spaceres);
- if (error == ENOSPC) {
- goto error_return;
- }
- if (error) {
- goto abort_return;
- }
- xfs_ichgtime(target_dp, XFS_ICHGTIME_MOD | XFS_ICHGTIME_CHG);
-
- if (new_parent && src_is_directory) {
- error = xfs_bumplink(tp, target_dp);
- if (error) {
- goto abort_return;
- }
- }
- } else { /* target_ip != NULL */
-
- /*
- * If target exists and it's a directory, check that both
- * target and source are directories and that target can be
- * destroyed, or that neither is a directory.
- */
- if ((target_ip->i_d.di_mode & S_IFMT) == S_IFDIR) {
- /*
- * Make sure target dir is empty.
- */
- if (!(XFS_DIR_ISEMPTY(target_ip->i_mount, target_ip)) ||
- (target_ip->i_d.di_nlink > 2)) {
- error = XFS_ERROR(EEXIST);
- goto error_return;
- }
- }
-
- /*
- * Link the source inode under the target name.
- * If the source inode is a directory and we are moving
- * it across directories, its ".." entry will be
- * inconsistent until we replace that down below.
- *
- * In case there is already an entry with the same
- * name at the destination directory, remove it first.
- */
- error = XFS_DIR_REPLACE(mp, tp, target_dp, target_name,
- target_namelen, src_ip->i_ino, &first_block,
- &free_list, spaceres);
- if (error) {
- goto abort_return;
- }
- xfs_ichgtime(target_dp, XFS_ICHGTIME_MOD | XFS_ICHGTIME_CHG);
-
- /*
- * Decrement the link count on the target since the target
- * dir no longer points to it.
- */
- error = xfs_droplink(tp, target_ip);
- if (error) {
- goto abort_return;
- }
- target_ip_dropped = 1;
-
- if (src_is_directory) {
- /*
- * Drop the link from the old "." entry.
- */
- error = xfs_droplink(tp, target_ip);
- if (error) {
- goto abort_return;
- }
- }
-
- /* Do this test while we still hold the locks */
- target_link_zero = (target_ip)->i_d.di_nlink==0;
-
- } /* target_ip != NULL */
-
- /*
- * Remove the source.
- */
- if (new_parent && src_is_directory) {
-
- /*
- * Rewrite the ".." entry to point to the new
- * directory.
- */
- error = XFS_DIR_REPLACE(mp, tp, src_ip, "..", 2,
- target_dp->i_ino, &first_block,
- &free_list, spaceres);
- ASSERT(error != EEXIST);
- if (error) {
- goto abort_return;
- }
- xfs_ichgtime(src_ip, XFS_ICHGTIME_MOD | XFS_ICHGTIME_CHG);
-
- } else {
- /*
- * We always want to hit the ctime on the source inode.
- * We do it in the if clause above for the 'new_parent &&
- * src_is_directory' case, and here we get all the other
- * cases. This isn't strictly required by the standards
- * since the source inode isn't really being changed,
- * but old unix file systems did it and some incremental
- * backup programs won't work without it.
- */
- xfs_ichgtime(src_ip, XFS_ICHGTIME_CHG);
- }
-
- /*
- * Adjust the link count on src_dp. This is necessary when
- * renaming a directory, either within one parent when
- * the target existed, or across two parent directories.
- */
- if (src_is_directory && (new_parent || target_ip != NULL)) {
-
- /*
- * Decrement link count on src_directory since the
- * entry that's moved no longer points to it.
- */
- error = xfs_droplink(tp, src_dp);
- if (error) {
- goto abort_return;
- }
- }
-
- error = XFS_DIR_REMOVENAME(mp, tp, src_dp, src_name, src_namelen,
- src_ip->i_ino, &first_block, &free_list, spaceres);
- if (error) {
- goto abort_return;
- }
- xfs_ichgtime(src_dp, XFS_ICHGTIME_MOD | XFS_ICHGTIME_CHG);
-
- /*
- * Update the generation counts on all the directory inodes
- * that we're modifying.
- */
- src_dp->i_gen++;
- xfs_trans_log_inode(tp, src_dp, XFS_ILOG_CORE);
-
- if (new_parent) {
- target_dp->i_gen++;
- xfs_trans_log_inode(tp, target_dp, XFS_ILOG_CORE);
- }
-
- /*
- * If there was a target inode, take an extra reference on
- * it here so that it doesn't go to xfs_inactive() from
- * within the commit.
- */
- if (target_ip != NULL) {
- IHOLD(target_ip);
- }
-
- /*
- * If this is a synchronous mount, make sure that the
- * rename transaction goes to disk before returning to
- * the user.
- */
- if (mp->m_flags & (XFS_MOUNT_WSYNC|XFS_MOUNT_DIRSYNC)) {
- xfs_trans_set_sync(tp);
- }
-
- /*
- * Take refs. for vop_link_removed calls below. No need to worry
- * about directory refs. because the caller holds them.
- *
- * Do holds before the xfs_bmap_finish since it might rele them down
- * to zero.
- */
-
- if (target_ip_dropped)
- IHOLD(target_ip);
- IHOLD(src_ip);
-
- error = xfs_bmap_finish(&tp, &free_list, first_block, &committed);
- if (error) {
- xfs_bmap_cancel(&free_list);
- xfs_trans_cancel(tp, (XFS_TRANS_RELEASE_LOG_RES |
- XFS_TRANS_ABORT));
- if (target_ip != NULL) {
- IRELE(target_ip);
- }
- if (target_ip_dropped) {
- IRELE(target_ip);
- }
- IRELE(src_ip);
- goto std_return;
- }
-
- /*
- * trans_commit will unlock src_ip, target_ip & decrement
- * the vnode references.
- */
- error = xfs_trans_commit(tp, XFS_TRANS_RELEASE_LOG_RES, NULL);
- if (target_ip != NULL) {
- xfs_refcache_purge_ip(target_ip);
- IRELE(target_ip);
- }
- /*
- * Let interposed file systems know about removed links.
- */
- if (target_ip_dropped) {
- XVOP_LINK_REMOVED(XFS_ITOV(target_ip), target_dir_vp,
- target_link_zero);
- IRELE(target_ip);
- }
-
- IRELE(src_ip);
-
- /* Fall through to std_return with error = 0 or errno from
- * xfs_trans_commit */
-std_return:
- if (DM_EVENT_ENABLED(src_dir_vp->v_vfsp, src_dp, DM_EVENT_POSTRENAME) ||
- DM_EVENT_ENABLED(target_dir_vp->v_vfsp,
- target_dp, DM_EVENT_POSTRENAME)) {
- (void) XFS_SEND_NAMESP (mp, DM_EVENT_POSTRENAME,
- src_dir_vp, DM_RIGHT_NULL,
- target_dir_vp, DM_RIGHT_NULL,
- src_name, target_name,
- 0, error, 0);
- }
- return error;
-
- abort_return:
- cancel_flags |= XFS_TRANS_ABORT;
- /* FALLTHROUGH */
- error_return:
- xfs_bmap_cancel(&free_list);
- xfs_trans_cancel(tp, cancel_flags);
- goto std_return;
-
- rele_return:
- IRELE(src_ip);
- if (target_ip != NULL) {
- IRELE(target_ip);
- }
- goto std_return;
-}
-
diff --git a/sys/gnu/fs/xfs/xfs_rtalloc.c b/sys/gnu/fs/xfs/xfs_rtalloc.c
deleted file mode 100644
index f5944c8..0000000
--- a/sys/gnu/fs/xfs/xfs_rtalloc.c
+++ /dev/null
@@ -1,2449 +0,0 @@
-/*
- * Copyright (c) 2000-2005 Silicon Graphics, Inc.
- * All Rights Reserved.
- *
- * 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.
- *
- * This program is distributed in the hope that it would 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 the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- */
-#include "xfs.h"
-#include "xfs_fs.h"
-#include "xfs_types.h"
-#include "xfs_bit.h"
-#include "xfs_log.h"
-#include "xfs_inum.h"
-#include "xfs_trans.h"
-#include "xfs_sb.h"
-#include "xfs_ag.h"
-#include "xfs_dir.h"
-#include "xfs_dir2.h"
-#include "xfs_dmapi.h"
-#include "xfs_mount.h"
-#include "xfs_bmap_btree.h"
-#include "xfs_alloc_btree.h"
-#include "xfs_ialloc_btree.h"
-#include "xfs_dir_sf.h"
-#include "xfs_dir2_sf.h"
-#include "xfs_attr_sf.h"
-#include "xfs_dinode.h"
-#include "xfs_inode.h"
-#include "xfs_btree.h"
-#include "xfs_ialloc.h"
-#include "xfs_alloc.h"
-#include "xfs_bmap.h"
-#include "xfs_rtalloc.h"
-#include "xfs_fsops.h"
-#include "xfs_error.h"
-#include "xfs_rw.h"
-#include "xfs_inode_item.h"
-#include "xfs_trans_space.h"
-
-
-/*
- * Prototypes for internal functions.
- */
-
-
-STATIC int xfs_rtallocate_range(xfs_mount_t *, xfs_trans_t *, xfs_rtblock_t,
- xfs_extlen_t, xfs_buf_t **, xfs_fsblock_t *);
-STATIC int xfs_rtany_summary(xfs_mount_t *, xfs_trans_t *, int, int,
- xfs_rtblock_t, xfs_buf_t **, xfs_fsblock_t *, int *);
-STATIC int xfs_rtcheck_range(xfs_mount_t *, xfs_trans_t *, xfs_rtblock_t,
- xfs_extlen_t, int, xfs_rtblock_t *, int *);
-STATIC int xfs_rtfind_back(xfs_mount_t *, xfs_trans_t *, xfs_rtblock_t,
- xfs_rtblock_t, xfs_rtblock_t *);
-STATIC int xfs_rtfind_forw(xfs_mount_t *, xfs_trans_t *, xfs_rtblock_t,
- xfs_rtblock_t, xfs_rtblock_t *);
-STATIC int xfs_rtget_summary( xfs_mount_t *, xfs_trans_t *, int,
- xfs_rtblock_t, xfs_buf_t **, xfs_fsblock_t *, xfs_suminfo_t *);
-STATIC int xfs_rtmodify_range(xfs_mount_t *, xfs_trans_t *, xfs_rtblock_t,
- xfs_extlen_t, int);
-STATIC int xfs_rtmodify_summary(xfs_mount_t *, xfs_trans_t *, int,
- xfs_rtblock_t, int, xfs_buf_t **, xfs_fsblock_t *);
-
-/*
- * Internal functions.
- */
-
-/*
- * xfs_lowbit32: get low bit set out of 32-bit argument, -1 if none set.
- */
-STATIC int
-xfs_lowbit32(
- __uint32_t v)
-{
- if (v)
- return ffs(v) - 1;
- return -1;
-}
-
-/*
- * Allocate space to the bitmap or summary file, and zero it, for growfs.
- */
-STATIC int /* error */
-xfs_growfs_rt_alloc(
- xfs_mount_t *mp, /* file system mount point */
- xfs_extlen_t oblocks, /* old count of blocks */
- xfs_extlen_t nblocks, /* new count of blocks */
- xfs_ino_t ino) /* inode number (bitmap/summary) */
-{
- xfs_fileoff_t bno; /* block number in file */
- xfs_buf_t *bp; /* temporary buffer for zeroing */
- int cancelflags; /* flags for xfs_trans_cancel */
- int committed; /* transaction committed flag */
- xfs_daddr_t d; /* disk block address */
- int error; /* error return value */
- xfs_fsblock_t firstblock; /* first block allocated in xaction */
- xfs_bmap_free_t flist; /* list of freed blocks */
- xfs_fsblock_t fsbno; /* filesystem block for bno */
- xfs_inode_t *ip; /* pointer to incore inode */
- xfs_bmbt_irec_t map; /* block map output */
- int nmap; /* number of block maps */
- int resblks; /* space reservation */
- xfs_trans_t *tp; /* transaction pointer */
-
- /*
- * Allocate space to the file, as necessary.
- */
- while (oblocks < nblocks) {
- tp = xfs_trans_alloc(mp, XFS_TRANS_GROWFSRT_ALLOC);
- resblks = XFS_GROWFSRT_SPACE_RES(mp, nblocks - oblocks);
- cancelflags = 0;
- /*
- * Reserve space & log for one extent added to the file.
- */
- if ((error = xfs_trans_reserve(tp, resblks,
- XFS_GROWRTALLOC_LOG_RES(mp), 0,
- XFS_TRANS_PERM_LOG_RES,
- XFS_DEFAULT_PERM_LOG_COUNT)))
- goto error_exit;
- cancelflags = XFS_TRANS_RELEASE_LOG_RES;
- /*
- * Lock the inode.
- */
- if ((error = xfs_trans_iget(mp, tp, ino, 0,
- XFS_ILOCK_EXCL, &ip)))
- goto error_exit;
- XFS_BMAP_INIT(&flist, &firstblock);
- /*
- * Allocate blocks to the bitmap file.
- */
- nmap = 1;
- cancelflags |= XFS_TRANS_ABORT;
- error = xfs_bmapi(tp, ip, oblocks, nblocks - oblocks,
- XFS_BMAPI_WRITE | XFS_BMAPI_METADATA, &firstblock,
- resblks, &map, &nmap, &flist, NULL);
- if (!error && nmap < 1)
- error = XFS_ERROR(ENOSPC);
- if (error)
- goto error_exit;
- /*
- * Free any blocks freed up in the transaction, then commit.
- */
- error = xfs_bmap_finish(&tp, &flist, firstblock, &committed);
- if (error)
- goto error_exit;
- xfs_trans_commit(tp, XFS_TRANS_RELEASE_LOG_RES, NULL);
- /*
- * Now we need to clear the allocated blocks.
- * Do this one block per transaction, to keep it simple.
- */
- cancelflags = 0;
- for (bno = map.br_startoff, fsbno = map.br_startblock;
- bno < map.br_startoff + map.br_blockcount;
- bno++, fsbno++) {
- tp = xfs_trans_alloc(mp, XFS_TRANS_GROWFSRT_ZERO);
- /*
- * Reserve log for one block zeroing.
- */
- if ((error = xfs_trans_reserve(tp, 0,
- XFS_GROWRTZERO_LOG_RES(mp), 0, 0, 0)))
- goto error_exit;
- /*
- * Lock the bitmap inode.
- */
- if ((error = xfs_trans_iget(mp, tp, ino, 0,
- XFS_ILOCK_EXCL, &ip)))
- goto error_exit;
- /*
- * Get a buffer for the block.
- */
- d = XFS_FSB_TO_DADDR(mp, fsbno);
- bp = xfs_trans_get_buf(tp, mp->m_ddev_targp, d,
- mp->m_bsize, 0);
- if (bp == NULL) {
- error = XFS_ERROR(EIO);
- goto error_exit;
- }
- memset(XFS_BUF_PTR(bp), 0, mp->m_sb.sb_blocksize);
- xfs_trans_log_buf(tp, bp, 0, mp->m_sb.sb_blocksize - 1);
- /*
- * Commit the transaction.
- */
- xfs_trans_commit(tp, 0, NULL);
- }
- /*
- * Go on to the next extent, if any.
- */
- oblocks = map.br_startoff + map.br_blockcount;
- }
- return 0;
-error_exit:
- xfs_trans_cancel(tp, cancelflags);
- return error;
-}
-
-/*
- * Attempt to allocate an extent minlen<=len<=maxlen starting from
- * bitmap block bbno. If we don't get maxlen then use prod to trim
- * the length, if given. Returns error; returns starting block in *rtblock.
- * The lengths are all in rtextents.
- */
-STATIC int /* error */
-xfs_rtallocate_extent_block(
- xfs_mount_t *mp, /* file system mount point */
- xfs_trans_t *tp, /* transaction pointer */
- xfs_rtblock_t bbno, /* bitmap block number */
- xfs_extlen_t minlen, /* minimum length to allocate */
- xfs_extlen_t maxlen, /* maximum length to allocate */
- xfs_extlen_t *len, /* out: actual length allocated */
- xfs_rtblock_t *nextp, /* out: next block to try */
- xfs_buf_t **rbpp, /* in/out: summary block buffer */
- xfs_fsblock_t *rsb, /* in/out: summary block number */
- xfs_extlen_t prod, /* extent product factor */
- xfs_rtblock_t *rtblock) /* out: start block allocated */
-{
- xfs_rtblock_t besti; /* best rtblock found so far */
- xfs_rtblock_t bestlen; /* best length found so far */
- xfs_rtblock_t end; /* last rtblock in chunk */
- int error; /* error value */
- xfs_rtblock_t i; /* current rtblock trying */
- xfs_rtblock_t next; /* next rtblock to try */
- int stat; /* status from internal calls */
-
- /*
- * Loop over all the extents starting in this bitmap block,
- * looking for one that's long enough.
- */
- for (i = XFS_BLOCKTOBIT(mp, bbno), besti = -1, bestlen = 0,
- end = XFS_BLOCKTOBIT(mp, bbno + 1) - 1;
- i <= end;
- i++) {
- /*
- * See if there's a free extent of maxlen starting at i.
- * If it's not so then next will contain the first non-free.
- */
- error = xfs_rtcheck_range(mp, tp, i, maxlen, 1, &next, &stat);
- if (error) {
- return error;
- }
- if (stat) {
- /*
- * i for maxlen is all free, allocate and return that.
- */
- error = xfs_rtallocate_range(mp, tp, i, maxlen, rbpp,
- rsb);
- if (error) {
- return error;
- }
- *len = maxlen;
- *rtblock = i;
- return 0;
- }
- /*
- * In the case where we have a variable-sized allocation
- * request, figure out how big this free piece is,
- * and if it's big enough for the minimum, and the best
- * so far, remember it.
- */
- if (minlen < maxlen) {
- xfs_rtblock_t thislen; /* this extent size */
-
- thislen = next - i;
- if (thislen >= minlen && thislen > bestlen) {
- besti = i;
- bestlen = thislen;
- }
- }
- /*
- * If not done yet, find the start of the next free space.
- */
- if (next < end) {
- error = xfs_rtfind_forw(mp, tp, next, end, &i);
- if (error) {
- return error;
- }
- } else
- break;
- }
- /*
- * Searched the whole thing & didn't find a maxlen free extent.
- */
- if (minlen < maxlen && besti != -1) {
- xfs_extlen_t p; /* amount to trim length by */
-
- /*
- * If size should be a multiple of prod, make that so.
- */
- if (prod > 1 && (p = do_mod(bestlen, prod)))
- bestlen -= p;
- /*
- * Allocate besti for bestlen & return that.
- */
- error = xfs_rtallocate_range(mp, tp, besti, bestlen, rbpp, rsb);
- if (error) {
- return error;
- }
- *len = bestlen;
- *rtblock = besti;
- return 0;
- }
- /*
- * Allocation failed. Set *nextp to the next block to try.
- */
- *nextp = next;
- *rtblock = NULLRTBLOCK;
- return 0;
-}
-
-/*
- * Allocate an extent of length minlen<=len<=maxlen, starting at block
- * bno. If we don't get maxlen then use prod to trim the length, if given.
- * Returns error; returns starting block in *rtblock.
- * The lengths are all in rtextents.
- */
-STATIC int /* error */
-xfs_rtallocate_extent_exact(
- xfs_mount_t *mp, /* file system mount point */
- xfs_trans_t *tp, /* transaction pointer */
- xfs_rtblock_t bno, /* starting block number to allocate */
- xfs_extlen_t minlen, /* minimum length to allocate */
- xfs_extlen_t maxlen, /* maximum length to allocate */
- xfs_extlen_t *len, /* out: actual length allocated */
- xfs_buf_t **rbpp, /* in/out: summary block buffer */
- xfs_fsblock_t *rsb, /* in/out: summary block number */
- xfs_extlen_t prod, /* extent product factor */
- xfs_rtblock_t *rtblock) /* out: start block allocated */
-{
- int error; /* error value */
- xfs_extlen_t i; /* extent length trimmed due to prod */
- int isfree; /* extent is free */
- xfs_rtblock_t next; /* next block to try (dummy) */
-
- ASSERT(minlen % prod == 0 && maxlen % prod == 0);
- /*
- * Check if the range in question (for maxlen) is free.
- */
- error = xfs_rtcheck_range(mp, tp, bno, maxlen, 1, &next, &isfree);
- if (error) {
- return error;
- }
- if (isfree) {
- /*
- * If it is, allocate it and return success.
- */
- error = xfs_rtallocate_range(mp, tp, bno, maxlen, rbpp, rsb);
- if (error) {
- return error;
- }
- *len = maxlen;
- *rtblock = bno;
- return 0;
- }
- /*
- * If not, allocate what there is, if it's at least minlen.
- */
- maxlen = next - bno;
- if (maxlen < minlen) {
- /*
- * Failed, return failure status.
- */
- *rtblock = NULLRTBLOCK;
- return 0;
- }
- /*
- * Trim off tail of extent, if prod is specified.
- */
- if (prod > 1 && (i = maxlen % prod)) {
- maxlen -= i;
- if (maxlen < minlen) {
- /*
- * Now we can't do it, return failure status.
- */
- *rtblock = NULLRTBLOCK;
- return 0;
- }
- }
- /*
- * Allocate what we can and return it.
- */
- error = xfs_rtallocate_range(mp, tp, bno, maxlen, rbpp, rsb);
- if (error) {
- return error;
- }
- *len = maxlen;
- *rtblock = bno;
- return 0;
-}
-
-/*
- * Allocate an extent of length minlen<=len<=maxlen, starting as near
- * to bno as possible. If we don't get maxlen then use prod to trim
- * the length, if given. The lengths are all in rtextents.
- */
-STATIC int /* error */
-xfs_rtallocate_extent_near(
- xfs_mount_t *mp, /* file system mount point */
- xfs_trans_t *tp, /* transaction pointer */
- xfs_rtblock_t bno, /* starting block number to allocate */
- xfs_extlen_t minlen, /* minimum length to allocate */
- xfs_extlen_t maxlen, /* maximum length to allocate */
- xfs_extlen_t *len, /* out: actual length allocated */
- xfs_buf_t **rbpp, /* in/out: summary block buffer */
- xfs_fsblock_t *rsb, /* in/out: summary block number */
- xfs_extlen_t prod, /* extent product factor */
- xfs_rtblock_t *rtblock) /* out: start block allocated */
-{
- int any; /* any useful extents from summary */
- xfs_rtblock_t bbno; /* bitmap block number */
- int error; /* error value */
- int i; /* bitmap block offset (loop control) */
- int j; /* secondary loop control */
- int log2len; /* log2 of minlen */
- xfs_rtblock_t n; /* next block to try */
- xfs_rtblock_t r; /* result block */
-
- ASSERT(minlen % prod == 0 && maxlen % prod == 0);
- /*
- * If the block number given is off the end, silently set it to
- * the last block.
- */
- if (bno >= mp->m_sb.sb_rextents)
- bno = mp->m_sb.sb_rextents - 1;
- /*
- * Try the exact allocation first.
- */
- error = xfs_rtallocate_extent_exact(mp, tp, bno, minlen, maxlen, len,
- rbpp, rsb, prod, &r);
- if (error) {
- return error;
- }
- /*
- * If the exact allocation worked, return that.
- */
- if (r != NULLRTBLOCK) {
- *rtblock = r;
- return 0;
- }
- bbno = XFS_BITTOBLOCK(mp, bno);
- i = 0;
- log2len = xfs_highbit32(minlen);
- /*
- * Loop over all bitmap blocks (bbno + i is current block).
- */
- for (;;) {
- /*
- * Get summary information of extents of all useful levels
- * starting in this bitmap block.
- */
- error = xfs_rtany_summary(mp, tp, log2len, mp->m_rsumlevels - 1,
- bbno + i, rbpp, rsb, &any);
- if (error) {
- return error;
- }
- /*
- * If there are any useful extents starting here, try
- * allocating one.
- */
- if (any) {
- /*
- * On the positive side of the starting location.
- */
- if (i >= 0) {
- /*
- * Try to allocate an extent starting in
- * this block.
- */
- error = xfs_rtallocate_extent_block(mp, tp,
- bbno + i, minlen, maxlen, len, &n, rbpp,
- rsb, prod, &r);
- if (error) {
- return error;
- }
- /*
- * If it worked, return it.
- */
- if (r != NULLRTBLOCK) {
- *rtblock = r;
- return 0;
- }
- }
- /*
- * On the negative side of the starting location.
- */
- else { /* i < 0 */
- /*
- * Loop backwards through the bitmap blocks from
- * the starting point-1 up to where we are now.
- * There should be an extent which ends in this
- * bitmap block and is long enough.
- */
- for (j = -1; j > i; j--) {
- /*
- * Grab the summary information for
- * this bitmap block.
- */
- error = xfs_rtany_summary(mp, tp,
- log2len, mp->m_rsumlevels - 1,
- bbno + j, rbpp, rsb, &any);
- if (error) {
- return error;
- }
- /*
- * If there's no extent given in the
- * summary that means the extent we
- * found must carry over from an
- * earlier block. If there is an
- * extent given, we've already tried
- * that allocation, don't do it again.
- */
- if (any)
- continue;
- error = xfs_rtallocate_extent_block(mp,
- tp, bbno + j, minlen, maxlen,
- len, &n, rbpp, rsb, prod, &r);
- if (error) {
- return error;
- }
- /*
- * If it works, return the extent.
- */
- if (r != NULLRTBLOCK) {
- *rtblock = r;
- return 0;
- }
- }
- /*
- * There weren't intervening bitmap blocks
- * with a long enough extent, or the
- * allocation didn't work for some reason
- * (i.e. it's a little * too short).
- * Try to allocate from the summary block
- * that we found.
- */
- error = xfs_rtallocate_extent_block(mp, tp,
- bbno + i, minlen, maxlen, len, &n, rbpp,
- rsb, prod, &r);
- if (error) {
- return error;
- }
- /*
- * If it works, return the extent.
- */
- if (r != NULLRTBLOCK) {
- *rtblock = r;
- return 0;
- }
- }
- }
- /*
- * Loop control. If we were on the positive side, and there's
- * still more blocks on the negative side, go there.
- */
- if (i > 0 && (int)bbno - i >= 0)
- i = -i;
- /*
- * If positive, and no more negative, but there are more
- * positive, go there.
- */
- else if (i > 0 && (int)bbno + i < mp->m_sb.sb_rbmblocks - 1)
- i++;
- /*
- * If negative or 0 (just started), and there are positive
- * blocks to go, go there. The 0 case moves to block 1.
- */
- else if (i <= 0 && (int)bbno - i < mp->m_sb.sb_rbmblocks - 1)
- i = 1 - i;
- /*
- * If negative or 0 and there are more negative blocks,
- * go there.
- */
- else if (i <= 0 && (int)bbno + i > 0)
- i--;
- /*
- * Must be done. Return failure.
- */
- else
- break;
- }
- *rtblock = NULLRTBLOCK;
- return 0;
-}
-
-/*
- * Allocate an extent of length minlen<=len<=maxlen, with no position
- * specified. If we don't get maxlen then use prod to trim
- * the length, if given. The lengths are all in rtextents.
- */
-STATIC int /* error */
-xfs_rtallocate_extent_size(
- xfs_mount_t *mp, /* file system mount point */
- xfs_trans_t *tp, /* transaction pointer */
- xfs_extlen_t minlen, /* minimum length to allocate */
- xfs_extlen_t maxlen, /* maximum length to allocate */
- xfs_extlen_t *len, /* out: actual length allocated */
- xfs_buf_t **rbpp, /* in/out: summary block buffer */
- xfs_fsblock_t *rsb, /* in/out: summary block number */
- xfs_extlen_t prod, /* extent product factor */
- xfs_rtblock_t *rtblock) /* out: start block allocated */
-{
- int error; /* error value */
- int i; /* bitmap block number */
- int l; /* level number (loop control) */
- xfs_rtblock_t n; /* next block to be tried */
- xfs_rtblock_t r; /* result block number */
- xfs_suminfo_t sum; /* summary information for extents */
-
- ASSERT(minlen % prod == 0 && maxlen % prod == 0);
- /*
- * Loop over all the levels starting with maxlen.
- * At each level, look at all the bitmap blocks, to see if there
- * are extents starting there that are long enough (>= maxlen).
- * Note, only on the initial level can the allocation fail if
- * the summary says there's an extent.
- */
- for (l = xfs_highbit32(maxlen); l < mp->m_rsumlevels; l++) {
- /*
- * Loop over all the bitmap blocks.
- */
- for (i = 0; i < mp->m_sb.sb_rbmblocks; i++) {
- /*
- * Get the summary for this level/block.
- */
- error = xfs_rtget_summary(mp, tp, l, i, rbpp, rsb,
- &sum);
- if (error) {
- return error;
- }
- /*
- * Nothing there, on to the next block.
- */
- if (!sum)
- continue;
- /*
- * Try allocating the extent.
- */
- error = xfs_rtallocate_extent_block(mp, tp, i, maxlen,
- maxlen, len, &n, rbpp, rsb, prod, &r);
- if (error) {
- return error;
- }
- /*
- * If it worked, return that.
- */
- if (r != NULLRTBLOCK) {
- *rtblock = r;
- return 0;
- }
- /*
- * If the "next block to try" returned from the
- * allocator is beyond the next bitmap block,
- * skip to that bitmap block.
- */
- if (XFS_BITTOBLOCK(mp, n) > i + 1)
- i = XFS_BITTOBLOCK(mp, n) - 1;
- }
- }
- /*
- * Didn't find any maxlen blocks. Try smaller ones, unless
- * we're asking for a fixed size extent.
- */
- if (minlen > --maxlen) {
- *rtblock = NULLRTBLOCK;
- return 0;
- }
- /*
- * Loop over sizes, from maxlen down to minlen.
- * This time, when we do the allocations, allow smaller ones
- * to succeed.
- */
- for (l = xfs_highbit32(maxlen); l >= xfs_highbit32(minlen); l--) {
- /*
- * Loop over all the bitmap blocks, try an allocation
- * starting in that block.
- */
- for (i = 0; i < mp->m_sb.sb_rbmblocks; i++) {
- /*
- * Get the summary information for this level/block.
- */
- error = xfs_rtget_summary(mp, tp, l, i, rbpp, rsb,
- &sum);
- if (error) {
- return error;
- }
- /*
- * If nothing there, go on to next.
- */
- if (!sum)
- continue;
- /*
- * Try the allocation. Make sure the specified
- * minlen/maxlen are in the possible range for
- * this summary level.
- */
- error = xfs_rtallocate_extent_block(mp, tp, i,
- XFS_RTMAX(minlen, 1 << l),
- XFS_RTMIN(maxlen, (1 << (l + 1)) - 1),
- len, &n, rbpp, rsb, prod, &r);
- if (error) {
- return error;
- }
- /*
- * If it worked, return that extent.
- */
- if (r != NULLRTBLOCK) {
- *rtblock = r;
- return 0;
- }
- /*
- * If the "next block to try" returned from the
- * allocator is beyond the next bitmap block,
- * skip to that bitmap block.
- */
- if (XFS_BITTOBLOCK(mp, n) > i + 1)
- i = XFS_BITTOBLOCK(mp, n) - 1;
- }
- }
- /*
- * Got nothing, return failure.
- */
- *rtblock = NULLRTBLOCK;
- return 0;
-}
-
-/*
- * Mark an extent specified by start and len allocated.
- * Updates all the summary information as well as the bitmap.
- */
-STATIC int /* error */
-xfs_rtallocate_range(
- xfs_mount_t *mp, /* file system mount point */
- xfs_trans_t *tp, /* transaction pointer */
- xfs_rtblock_t start, /* start block to allocate */
- xfs_extlen_t len, /* length to allocate */
- xfs_buf_t **rbpp, /* in/out: summary block buffer */
- xfs_fsblock_t *rsb) /* in/out: summary block number */
-{
- xfs_rtblock_t end; /* end of the allocated extent */
- int error; /* error value */
- xfs_rtblock_t postblock; /* first block allocated > end */
- xfs_rtblock_t preblock; /* first block allocated < start */
-
- end = start + len - 1;
- /*
- * Assume we're allocating out of the middle of a free extent.
- * We need to find the beginning and end of the extent so we can
- * properly update the summary.
- */
- error = xfs_rtfind_back(mp, tp, start, 0, &preblock);
- if (error) {
- return error;
- }
- /*
- * Find the next allocated block (end of free extent).
- */
- error = xfs_rtfind_forw(mp, tp, end, mp->m_sb.sb_rextents - 1,
- &postblock);
- if (error) {
- return error;
- }
- /*
- * Decrement the summary information corresponding to the entire
- * (old) free extent.
- */
- error = xfs_rtmodify_summary(mp, tp,
- XFS_RTBLOCKLOG(postblock + 1 - preblock),
- XFS_BITTOBLOCK(mp, preblock), -1, rbpp, rsb);
- if (error) {
- return error;
- }
- /*
- * If there are blocks not being allocated at the front of the
- * old extent, add summary data for them to be free.
- */
- if (preblock < start) {
- error = xfs_rtmodify_summary(mp, tp,
- XFS_RTBLOCKLOG(start - preblock),
- XFS_BITTOBLOCK(mp, preblock), 1, rbpp, rsb);
- if (error) {
- return error;
- }
- }
- /*
- * If there are blocks not being allocated at the end of the
- * old extent, add summary data for them to be free.
- */
- if (postblock > end) {
- error = xfs_rtmodify_summary(mp, tp,
- XFS_RTBLOCKLOG(postblock - end),
- XFS_BITTOBLOCK(mp, end + 1), 1, rbpp, rsb);
- if (error) {
- return error;
- }
- }
- /*
- * Modify the bitmap to mark this extent allocated.
- */
- error = xfs_rtmodify_range(mp, tp, start, len, 0);
- return error;
-}
-
-/*
- * Return whether there are any free extents in the size range given
- * by low and high, for the bitmap block bbno.
- */
-STATIC int /* error */
-xfs_rtany_summary(
- xfs_mount_t *mp, /* file system mount structure */
- xfs_trans_t *tp, /* transaction pointer */
- int low, /* low log2 extent size */
- int high, /* high log2 extent size */
- xfs_rtblock_t bbno, /* bitmap block number */
- xfs_buf_t **rbpp, /* in/out: summary block buffer */
- xfs_fsblock_t *rsb, /* in/out: summary block number */
- int *stat) /* out: any good extents here? */
-{
- int error; /* error value */
- int log; /* loop counter, log2 of ext. size */
- xfs_suminfo_t sum; /* summary data */
-
- /*
- * Loop over logs of extent sizes. Order is irrelevant.
- */
- for (log = low; log <= high; log++) {
- /*
- * Get one summary datum.
- */
- error = xfs_rtget_summary(mp, tp, log, bbno, rbpp, rsb, &sum);
- if (error) {
- return error;
- }
- /*
- * If there are any, return success.
- */
- if (sum) {
- *stat = 1;
- return 0;
- }
- }
- /*
- * Found nothing, return failure.
- */
- *stat = 0;
- return 0;
-}
-
-/*
- * Get a buffer for the bitmap or summary file block specified.
- * The buffer is returned read and locked.
- */
-STATIC int /* error */
-xfs_rtbuf_get(
- xfs_mount_t *mp, /* file system mount structure */
- xfs_trans_t *tp, /* transaction pointer */
- xfs_rtblock_t block, /* block number in bitmap or summary */
- int issum, /* is summary not bitmap */
- xfs_buf_t **bpp) /* output: buffer for the block */
-{
- xfs_buf_t *bp; /* block buffer, result */
- xfs_daddr_t d; /* disk addr of block */
- int error; /* error value */
- xfs_fsblock_t fsb; /* fs block number for block */
- xfs_inode_t *ip; /* bitmap or summary inode */
-
- ip = issum ? mp->m_rsumip : mp->m_rbmip;
- /*
- * Map from the file offset (block) and inode number to the
- * file system block.
- */
- error = xfs_bmapi_single(tp, ip, XFS_DATA_FORK, &fsb, block);
- if (error) {
- return error;
- }
- ASSERT(fsb != NULLFSBLOCK);
- /*
- * Convert to disk address for buffer cache.
- */
- d = XFS_FSB_TO_DADDR(mp, fsb);
- /*
- * Read the buffer.
- */
- error = xfs_trans_read_buf(mp, tp, mp->m_ddev_targp, d,
- mp->m_bsize, 0, &bp);
- if (error) {
- return error;
- }
- ASSERT(bp && !XFS_BUF_GETERROR(bp));
- *bpp = bp;
- return 0;
-}
-
-#ifdef DEBUG
-/*
- * Check that the given extent (block range) is allocated already.
- */
-STATIC int /* error */
-xfs_rtcheck_alloc_range(
- xfs_mount_t *mp, /* file system mount point */
- xfs_trans_t *tp, /* transaction pointer */
- xfs_rtblock_t bno, /* starting block number of extent */
- xfs_extlen_t len, /* length of extent */
- int *stat) /* out: 1 for allocated, 0 for not */
-{
- xfs_rtblock_t new; /* dummy for xfs_rtcheck_range */
-
- return xfs_rtcheck_range(mp, tp, bno, len, 0, &new, stat);
-}
-#endif
-
-#ifdef DEBUG
-/*
- * Check whether the given block in the bitmap has the given value.
- */
-STATIC int /* 1 for matches, 0 for not */
-xfs_rtcheck_bit(
- xfs_mount_t *mp, /* file system mount structure */
- xfs_trans_t *tp, /* transaction pointer */
- xfs_rtblock_t start, /* bit (block) to check */
- int val) /* 1 for free, 0 for allocated */
-{
- int bit; /* bit number in the word */
- xfs_rtblock_t block; /* bitmap block number */
- xfs_buf_t *bp; /* buf for the block */
- xfs_rtword_t *bufp; /* pointer into the buffer */
- /* REFERENCED */
- int error; /* error value */
- xfs_rtword_t wdiff; /* difference between bit & expected */
- int word; /* word number in the buffer */
- xfs_rtword_t wval; /* word value from buffer */
-
- block = XFS_BITTOBLOCK(mp, start);
- error = xfs_rtbuf_get(mp, tp, block, 0, &bp);
- bufp = (xfs_rtword_t *)XFS_BUF_PTR(bp);
- word = XFS_BITTOWORD(mp, start);
- bit = (int)(start & (XFS_NBWORD - 1));
- wval = bufp[word];
- xfs_trans_brelse(tp, bp);
- wdiff = (wval ^ -val) & ((xfs_rtword_t)1 << bit);
- return !wdiff;
-}
-#endif /* DEBUG */
-
-#if 0
-/*
- * Check that the given extent (block range) is free already.
- */
-STATIC int /* error */
-xfs_rtcheck_free_range(
- xfs_mount_t *mp, /* file system mount point */
- xfs_trans_t *tp, /* transaction pointer */
- xfs_rtblock_t bno, /* starting block number of extent */
- xfs_extlen_t len, /* length of extent */
- int *stat) /* out: 1 for free, 0 for not */
-{
- xfs_rtblock_t new; /* dummy for xfs_rtcheck_range */
-
- return xfs_rtcheck_range(mp, tp, bno, len, 1, &new, stat);
-}
-#endif
-
-/*
- * Check that the given range is either all allocated (val = 0) or
- * all free (val = 1).
- */
-STATIC int /* error */
-xfs_rtcheck_range(
- xfs_mount_t *mp, /* file system mount point */
- xfs_trans_t *tp, /* transaction pointer */
- xfs_rtblock_t start, /* starting block number of extent */
- xfs_extlen_t len, /* length of extent */
- int val, /* 1 for free, 0 for allocated */
- xfs_rtblock_t *new, /* out: first block not matching */
- int *stat) /* out: 1 for matches, 0 for not */
-{
- xfs_rtword_t *b; /* current word in buffer */
- int bit; /* bit number in the word */
- xfs_rtblock_t block; /* bitmap block number */
- xfs_buf_t *bp; /* buf for the block */
- xfs_rtword_t *bufp; /* starting word in buffer */
- int error; /* error value */
- xfs_rtblock_t i; /* current bit number rel. to start */
- xfs_rtblock_t lastbit; /* last useful bit in word */
- xfs_rtword_t mask; /* mask of relevant bits for value */
- xfs_rtword_t wdiff; /* difference from wanted value */
- int word; /* word number in the buffer */
-
- /*
- * Compute starting bitmap block number
- */
- block = XFS_BITTOBLOCK(mp, start);
- /*
- * Read the bitmap block.
- */
- error = xfs_rtbuf_get(mp, tp, block, 0, &bp);
- if (error) {
- return error;
- }
- bufp = (xfs_rtword_t *)XFS_BUF_PTR(bp);
- /*
- * Compute the starting word's address, and starting bit.
- */
- word = XFS_BITTOWORD(mp, start);
- b = &bufp[word];
- bit = (int)(start & (XFS_NBWORD - 1));
- /*
- * 0 (allocated) => all zero's; 1 (free) => all one's.
- */
- val = -val;
- /*
- * If not starting on a word boundary, deal with the first
- * (partial) word.
- */
- if (bit) {
- /*
- * Compute first bit not examined.
- */
- lastbit = XFS_RTMIN(bit + len, XFS_NBWORD);
- /*
- * Mask of relevant bits.
- */
- mask = (((xfs_rtword_t)1 << (lastbit - bit)) - 1) << bit;
- /*
- * Compute difference between actual and desired value.
- */
- if ((wdiff = (*b ^ val) & mask)) {
- /*
- * Different, compute first wrong bit and return.
- */
- xfs_trans_brelse(tp, bp);
- i = XFS_RTLOBIT(wdiff) - bit;
- *new = start + i;
- *stat = 0;
- return 0;
- }
- i = lastbit - bit;
- /*
- * Go on to next block if that's where the next word is
- * and we need the next word.
- */
- if (++word == XFS_BLOCKWSIZE(mp) && i < len) {
- /*
- * If done with this block, get the next one.
- */
- xfs_trans_brelse(tp, bp);
- error = xfs_rtbuf_get(mp, tp, ++block, 0, &bp);
- if (error) {
- return error;
- }
- b = bufp = (xfs_rtword_t *)XFS_BUF_PTR(bp);
- word = 0;
- } else {
- /*
- * Go on to the next word in the buffer.
- */
- b++;
- }
- } else {
- /*
- * Starting on a word boundary, no partial word.
- */
- i = 0;
- }
- /*
- * Loop over whole words in buffers. When we use up one buffer
- * we move on to the next one.
- */
- while (len - i >= XFS_NBWORD) {
- /*
- * Compute difference between actual and desired value.
- */
- if ((wdiff = *b ^ val)) {
- /*
- * Different, compute first wrong bit and return.
- */
- xfs_trans_brelse(tp, bp);
- i += XFS_RTLOBIT(wdiff);
- *new = start + i;
- *stat = 0;
- return 0;
- }
- i += XFS_NBWORD;
- /*
- * Go on to next block if that's where the next word is
- * and we need the next word.
- */
- if (++word == XFS_BLOCKWSIZE(mp) && i < len) {
- /*
- * If done with this block, get the next one.
- */
- xfs_trans_brelse(tp, bp);
- error = xfs_rtbuf_get(mp, tp, ++block, 0, &bp);
- if (error) {
- return error;
- }
- b = bufp = (xfs_rtword_t *)XFS_BUF_PTR(bp);
- word = 0;
- } else {
- /*
- * Go on to the next word in the buffer.
- */
- b++;
- }
- }
- /*
- * If not ending on a word boundary, deal with the last
- * (partial) word.
- */
- if ((lastbit = len - i)) {
- /*
- * Mask of relevant bits.
- */
- mask = ((xfs_rtword_t)1 << lastbit) - 1;
- /*
- * Compute difference between actual and desired value.
- */
- if ((wdiff = (*b ^ val) & mask)) {
- /*
- * Different, compute first wrong bit and return.
- */
- xfs_trans_brelse(tp, bp);
- i += XFS_RTLOBIT(wdiff);
- *new = start + i;
- *stat = 0;
- return 0;
- } else
- i = len;
- }
- /*
- * Successful, return.
- */
- xfs_trans_brelse(tp, bp);
- *new = start + i;
- *stat = 1;
- return 0;
-}
-
-/*
- * Copy and transform the summary file, given the old and new
- * parameters in the mount structures.
- */
-STATIC int /* error */
-xfs_rtcopy_summary(
- xfs_mount_t *omp, /* old file system mount point */
- xfs_mount_t *nmp, /* new file system mount point */
- xfs_trans_t *tp) /* transaction pointer */
-{
- xfs_rtblock_t bbno; /* bitmap block number */
- xfs_buf_t *bp; /* summary buffer */
- int error; /* error return value */
- int log; /* summary level number (log length) */
- xfs_suminfo_t sum; /* summary data */
- xfs_fsblock_t sumbno; /* summary block number */
-
- bp = NULL;
- for (log = omp->m_rsumlevels - 1; log >= 0; log--) {
- for (bbno = omp->m_sb.sb_rbmblocks - 1;
- (xfs_srtblock_t)bbno >= 0;
- bbno--) {
- error = xfs_rtget_summary(omp, tp, log, bbno, &bp,
- &sumbno, &sum);
- if (error)
- return error;
- if (sum == 0)
- continue;
- error = xfs_rtmodify_summary(omp, tp, log, bbno, -sum,
- &bp, &sumbno);
- if (error)
- return error;
- error = xfs_rtmodify_summary(nmp, tp, log, bbno, sum,
- &bp, &sumbno);
- if (error)
- return error;
- ASSERT(sum > 0);
- }
- }
- return 0;
-}
-
-/*
- * Searching backward from start to limit, find the first block whose
- * allocated/free state is different from start's.
- */
-STATIC int /* error */
-xfs_rtfind_back(
- xfs_mount_t *mp, /* file system mount point */
- xfs_trans_t *tp, /* transaction pointer */
- xfs_rtblock_t start, /* starting block to look at */
- xfs_rtblock_t limit, /* last block to look at */
- xfs_rtblock_t *rtblock) /* out: start block found */
-{
- xfs_rtword_t *b; /* current word in buffer */
- int bit; /* bit number in the word */
- xfs_rtblock_t block; /* bitmap block number */
- xfs_buf_t *bp; /* buf for the block */
- xfs_rtword_t *bufp; /* starting word in buffer */
- int error; /* error value */
- xfs_rtblock_t firstbit; /* first useful bit in the word */
- xfs_rtblock_t i; /* current bit number rel. to start */
- xfs_rtblock_t len; /* length of inspected area */
- xfs_rtword_t mask; /* mask of relevant bits for value */
- xfs_rtword_t want; /* mask for "good" values */
- xfs_rtword_t wdiff; /* difference from wanted value */
- int word; /* word number in the buffer */
-
- /*
- * Compute and read in starting bitmap block for starting block.
- */
- block = XFS_BITTOBLOCK(mp, start);
- error = xfs_rtbuf_get(mp, tp, block, 0, &bp);
- if (error) {
- return error;
- }
- bufp = (xfs_rtword_t *)XFS_BUF_PTR(bp);
- /*
- * Get the first word's index & point to it.
- */
- word = XFS_BITTOWORD(mp, start);
- b = &bufp[word];
- bit = (int)(start & (XFS_NBWORD - 1));
- len = start - limit + 1;
- /*
- * Compute match value, based on the bit at start: if 1 (free)
- * then all-ones, else all-zeroes.
- */
- want = (*b & ((xfs_rtword_t)1 << bit)) ? -1 : 0;
- /*
- * If the starting position is not word-aligned, deal with the
- * partial word.
- */
- if (bit < XFS_NBWORD - 1) {
- /*
- * Calculate first (leftmost) bit number to look at,
- * and mask for all the relevant bits in this word.
- */
- firstbit = XFS_RTMAX((xfs_srtblock_t)(bit - len + 1), 0);
- mask = (((xfs_rtword_t)1 << (bit - firstbit + 1)) - 1) <<
- firstbit;
- /*
- * Calculate the difference between the value there
- * and what we're looking for.
- */
- if ((wdiff = (*b ^ want) & mask)) {
- /*
- * Different. Mark where we are and return.
- */
- xfs_trans_brelse(tp, bp);
- i = bit - XFS_RTHIBIT(wdiff);
- *rtblock = start - i + 1;
- return 0;
- }
- i = bit - firstbit + 1;
- /*
- * Go on to previous block if that's where the previous word is
- * and we need the previous word.
- */
- if (--word == -1 && i < len) {
- /*
- * If done with this block, get the previous one.
- */
- xfs_trans_brelse(tp, bp);
- error = xfs_rtbuf_get(mp, tp, --block, 0, &bp);
- if (error) {
- return error;
- }
- bufp = (xfs_rtword_t *)XFS_BUF_PTR(bp);
- word = XFS_BLOCKWMASK(mp);
- b = &bufp[word];
- } else {
- /*
- * Go on to the previous word in the buffer.
- */
- b--;
- }
- } else {
- /*
- * Starting on a word boundary, no partial word.
- */
- i = 0;
- }
- /*
- * Loop over whole words in buffers. When we use up one buffer
- * we move on to the previous one.
- */
- while (len - i >= XFS_NBWORD) {
- /*
- * Compute difference between actual and desired value.
- */
- if ((wdiff = *b ^ want)) {
- /*
- * Different, mark where we are and return.
- */
- xfs_trans_brelse(tp, bp);
- i += XFS_NBWORD - 1 - XFS_RTHIBIT(wdiff);
- *rtblock = start - i + 1;
- return 0;
- }
- i += XFS_NBWORD;
- /*
- * Go on to previous block if that's where the previous word is
- * and we need the previous word.
- */
- if (--word == -1 && i < len) {
- /*
- * If done with this block, get the previous one.
- */
- xfs_trans_brelse(tp, bp);
- error = xfs_rtbuf_get(mp, tp, --block, 0, &bp);
- if (error) {
- return error;
- }
- bufp = (xfs_rtword_t *)XFS_BUF_PTR(bp);
- word = XFS_BLOCKWMASK(mp);
- b = &bufp[word];
- } else {
- /*
- * Go on to the previous word in the buffer.
- */
- b--;
- }
- }
- /*
- * If not ending on a word boundary, deal with the last
- * (partial) word.
- */
- if (len - i) {
- /*
- * Calculate first (leftmost) bit number to look at,
- * and mask for all the relevant bits in this word.
- */
- firstbit = XFS_NBWORD - (len - i);
- mask = (((xfs_rtword_t)1 << (len - i)) - 1) << firstbit;
- /*
- * Compute difference between actual and desired value.
- */
- if ((wdiff = (*b ^ want) & mask)) {
- /*
- * Different, mark where we are and return.
- */
- xfs_trans_brelse(tp, bp);
- i += XFS_NBWORD - 1 - XFS_RTHIBIT(wdiff);
- *rtblock = start - i + 1;
- return 0;
- } else
- i = len;
- }
- /*
- * No match, return that we scanned the whole area.
- */
- xfs_trans_brelse(tp, bp);
- *rtblock = start - i + 1;
- return 0;
-}
-
-/*
- * Searching forward from start to limit, find the first block whose
- * allocated/free state is different from start's.
- */
-STATIC int /* error */
-xfs_rtfind_forw(
- xfs_mount_t *mp, /* file system mount point */
- xfs_trans_t *tp, /* transaction pointer */
- xfs_rtblock_t start, /* starting block to look at */
- xfs_rtblock_t limit, /* last block to look at */
- xfs_rtblock_t *rtblock) /* out: start block found */
-{
- xfs_rtword_t *b; /* current word in buffer */
- int bit; /* bit number in the word */
- xfs_rtblock_t block; /* bitmap block number */
- xfs_buf_t *bp; /* buf for the block */
- xfs_rtword_t *bufp; /* starting word in buffer */
- int error; /* error value */
- xfs_rtblock_t i; /* current bit number rel. to start */
- xfs_rtblock_t lastbit; /* last useful bit in the word */
- xfs_rtblock_t len; /* length of inspected area */
- xfs_rtword_t mask; /* mask of relevant bits for value */
- xfs_rtword_t want; /* mask for "good" values */
- xfs_rtword_t wdiff; /* difference from wanted value */
- int word; /* word number in the buffer */
-
- /*
- * Compute and read in starting bitmap block for starting block.
- */
- block = XFS_BITTOBLOCK(mp, start);
- error = xfs_rtbuf_get(mp, tp, block, 0, &bp);
- if (error) {
- return error;
- }
- bufp = (xfs_rtword_t *)XFS_BUF_PTR(bp);
- /*
- * Get the first word's index & point to it.
- */
- word = XFS_BITTOWORD(mp, start);
- b = &bufp[word];
- bit = (int)(start & (XFS_NBWORD - 1));
- len = limit - start + 1;
- /*
- * Compute match value, based on the bit at start: if 1 (free)
- * then all-ones, else all-zeroes.
- */
- want = (*b & ((xfs_rtword_t)1 << bit)) ? -1 : 0;
- /*
- * If the starting position is not word-aligned, deal with the
- * partial word.
- */
- if (bit) {
- /*
- * Calculate last (rightmost) bit number to look at,
- * and mask for all the relevant bits in this word.
- */
- lastbit = XFS_RTMIN(bit + len, XFS_NBWORD);
- mask = (((xfs_rtword_t)1 << (lastbit - bit)) - 1) << bit;
- /*
- * Calculate the difference between the value there
- * and what we're looking for.
- */
- if ((wdiff = (*b ^ want) & mask)) {
- /*
- * Different. Mark where we are and return.
- */
- xfs_trans_brelse(tp, bp);
- i = XFS_RTLOBIT(wdiff) - bit;
- *rtblock = start + i - 1;
- return 0;
- }
- i = lastbit - bit;
- /*
- * Go on to next block if that's where the next word is
- * and we need the next word.
- */
- if (++word == XFS_BLOCKWSIZE(mp) && i < len) {
- /*
- * If done with this block, get the previous one.
- */
- xfs_trans_brelse(tp, bp);
- error = xfs_rtbuf_get(mp, tp, ++block, 0, &bp);
- if (error) {
- return error;
- }
- b = bufp = (xfs_rtword_t *)XFS_BUF_PTR(bp);
- word = 0;
- } else {
- /*
- * Go on to the previous word in the buffer.
- */
- b++;
- }
- } else {
- /*
- * Starting on a word boundary, no partial word.
- */
- i = 0;
- }
- /*
- * Loop over whole words in buffers. When we use up one buffer
- * we move on to the next one.
- */
- while (len - i >= XFS_NBWORD) {
- /*
- * Compute difference between actual and desired value.
- */
- if ((wdiff = *b ^ want)) {
- /*
- * Different, mark where we are and return.
- */
- xfs_trans_brelse(tp, bp);
- i += XFS_RTLOBIT(wdiff);
- *rtblock = start + i - 1;
- return 0;
- }
- i += XFS_NBWORD;
- /*
- * Go on to next block if that's where the next word is
- * and we need the next word.
- */
- if (++word == XFS_BLOCKWSIZE(mp) && i < len) {
- /*
- * If done with this block, get the next one.
- */
- xfs_trans_brelse(tp, bp);
- error = xfs_rtbuf_get(mp, tp, ++block, 0, &bp);
- if (error) {
- return error;
- }
- b = bufp = (xfs_rtword_t *)XFS_BUF_PTR(bp);
- word = 0;
- } else {
- /*
- * Go on to the next word in the buffer.
- */
- b++;
- }
- }
- /*
- * If not ending on a word boundary, deal with the last
- * (partial) word.
- */
- if ((lastbit = len - i)) {
- /*
- * Calculate mask for all the relevant bits in this word.
- */
- mask = ((xfs_rtword_t)1 << lastbit) - 1;
- /*
- * Compute difference between actual and desired value.
- */
- if ((wdiff = (*b ^ want) & mask)) {
- /*
- * Different, mark where we are and return.
- */
- xfs_trans_brelse(tp, bp);
- i += XFS_RTLOBIT(wdiff);
- *rtblock = start + i - 1;
- return 0;
- } else
- i = len;
- }
- /*
- * No match, return that we scanned the whole area.
- */
- xfs_trans_brelse(tp, bp);
- *rtblock = start + i - 1;
- return 0;
-}
-
-/*
- * Mark an extent specified by start and len freed.
- * Updates all the summary information as well as the bitmap.
- */
-STATIC int /* error */
-xfs_rtfree_range(
- xfs_mount_t *mp, /* file system mount point */
- xfs_trans_t *tp, /* transaction pointer */
- xfs_rtblock_t start, /* starting block to free */
- xfs_extlen_t len, /* length to free */
- xfs_buf_t **rbpp, /* in/out: summary block buffer */
- xfs_fsblock_t *rsb) /* in/out: summary block number */
-{
- xfs_rtblock_t end; /* end of the freed extent */
- int error; /* error value */
- xfs_rtblock_t postblock; /* first block freed > end */
- xfs_rtblock_t preblock; /* first block freed < start */
-
- end = start + len - 1;
- /*
- * Modify the bitmap to mark this extent freed.
- */
- error = xfs_rtmodify_range(mp, tp, start, len, 1);
- if (error) {
- return error;
- }
- /*
- * Assume we're freeing out of the middle of an allocated extent.
- * We need to find the beginning and end of the extent so we can
- * properly update the summary.
- */
- error = xfs_rtfind_back(mp, tp, start, 0, &preblock);
- if (error) {
- return error;
- }
- /*
- * Find the next allocated block (end of allocated extent).
- */
- error = xfs_rtfind_forw(mp, tp, end, mp->m_sb.sb_rextents - 1,
- &postblock);
- /*
- * If there are blocks not being freed at the front of the
- * old extent, add summary data for them to be allocated.
- */
- if (preblock < start) {
- error = xfs_rtmodify_summary(mp, tp,
- XFS_RTBLOCKLOG(start - preblock),
- XFS_BITTOBLOCK(mp, preblock), -1, rbpp, rsb);
- if (error) {
- return error;
- }
- }
- /*
- * If there are blocks not being freed at the end of the
- * old extent, add summary data for them to be allocated.
- */
- if (postblock > end) {
- error = xfs_rtmodify_summary(mp, tp,
- XFS_RTBLOCKLOG(postblock - end),
- XFS_BITTOBLOCK(mp, end + 1), -1, rbpp, rsb);
- if (error) {
- return error;
- }
- }
- /*
- * Increment the summary information corresponding to the entire
- * (new) free extent.
- */
- error = xfs_rtmodify_summary(mp, tp,
- XFS_RTBLOCKLOG(postblock + 1 - preblock),
- XFS_BITTOBLOCK(mp, preblock), 1, rbpp, rsb);
- return error;
-}
-
-/*
- * Read and return the summary information for a given extent size,
- * bitmap block combination.
- * Keeps track of a current summary block, so we don't keep reading
- * it from the buffer cache.
- */
-STATIC int /* error */
-xfs_rtget_summary(
- xfs_mount_t *mp, /* file system mount structure */
- xfs_trans_t *tp, /* transaction pointer */
- int log, /* log2 of extent size */
- xfs_rtblock_t bbno, /* bitmap block number */
- xfs_buf_t **rbpp, /* in/out: summary block buffer */
- xfs_fsblock_t *rsb, /* in/out: summary block number */
- xfs_suminfo_t *sum) /* out: summary info for this block */
-{
- xfs_buf_t *bp; /* buffer for summary block */
- int error; /* error value */
- xfs_fsblock_t sb; /* summary fsblock */
- int so; /* index into the summary file */
- xfs_suminfo_t *sp; /* pointer to returned data */
-
- /*
- * Compute entry number in the summary file.
- */
- so = XFS_SUMOFFS(mp, log, bbno);
- /*
- * Compute the block number in the summary file.
- */
- sb = XFS_SUMOFFSTOBLOCK(mp, so);
- /*
- * If we have an old buffer, and the block number matches, use that.
- */
- if (rbpp && *rbpp && *rsb == sb)
- bp = *rbpp;
- /*
- * Otherwise we have to get the buffer.
- */
- else {
- /*
- * If there was an old one, get rid of it first.
- */
- if (rbpp && *rbpp)
- xfs_trans_brelse(tp, *rbpp);
- error = xfs_rtbuf_get(mp, tp, sb, 1, &bp);
- if (error) {
- return error;
- }
- /*
- * Remember this buffer and block for the next call.
- */
- if (rbpp) {
- *rbpp = bp;
- *rsb = sb;
- }
- }
- /*
- * Point to the summary information & copy it out.
- */
- sp = XFS_SUMPTR(mp, bp, so);
- *sum = *sp;
- /*
- * Drop the buffer if we're not asked to remember it.
- */
- if (!rbpp)
- xfs_trans_brelse(tp, bp);
- return 0;
-}
-
-/*
- * Set the given range of bitmap bits to the given value.
- * Do whatever I/O and logging is required.
- */
-STATIC int /* error */
-xfs_rtmodify_range(
- xfs_mount_t *mp, /* file system mount point */
- xfs_trans_t *tp, /* transaction pointer */
- xfs_rtblock_t start, /* starting block to modify */
- xfs_extlen_t len, /* length of extent to modify */
- int val) /* 1 for free, 0 for allocated */
-{
- xfs_rtword_t *b; /* current word in buffer */
- int bit; /* bit number in the word */
- xfs_rtblock_t block; /* bitmap block number */
- xfs_buf_t *bp; /* buf for the block */
- xfs_rtword_t *bufp; /* starting word in buffer */
- int error; /* error value */
- xfs_rtword_t *first; /* first used word in the buffer */
- int i; /* current bit number rel. to start */
- int lastbit; /* last useful bit in word */
- xfs_rtword_t mask; /* mask o frelevant bits for value */
- int word; /* word number in the buffer */
-
- /*
- * Compute starting bitmap block number.
- */
- block = XFS_BITTOBLOCK(mp, start);
- /*
- * Read the bitmap block, and point to its data.
- */
- error = xfs_rtbuf_get(mp, tp, block, 0, &bp);
- if (error) {
- return error;
- }
- bufp = (xfs_rtword_t *)XFS_BUF_PTR(bp);
- /*
- * Compute the starting word's address, and starting bit.
- */
- word = XFS_BITTOWORD(mp, start);
- first = b = &bufp[word];
- bit = (int)(start & (XFS_NBWORD - 1));
- /*
- * 0 (allocated) => all zeroes; 1 (free) => all ones.
- */
- val = -val;
- /*
- * If not starting on a word boundary, deal with the first
- * (partial) word.
- */
- if (bit) {
- /*
- * Compute first bit not changed and mask of relevant bits.
- */
- lastbit = XFS_RTMIN(bit + len, XFS_NBWORD);
- mask = (((xfs_rtword_t)1 << (lastbit - bit)) - 1) << bit;
- /*
- * Set/clear the active bits.
- */
- if (val)
- *b |= mask;
- else
- *b &= ~mask;
- i = lastbit - bit;
- /*
- * Go on to the next block if that's where the next word is
- * and we need the next word.
- */
- if (++word == XFS_BLOCKWSIZE(mp) && i < len) {
- /*
- * Log the changed part of this block.
- * Get the next one.
- */
- xfs_trans_log_buf(tp, bp,
- (uint)((char *)first - (char *)bufp),
- (uint)((char *)b - (char *)bufp));
- error = xfs_rtbuf_get(mp, tp, ++block, 0, &bp);
- if (error) {
- return error;
- }
- first = b = bufp = (xfs_rtword_t *)XFS_BUF_PTR(bp);
- word = 0;
- } else {
- /*
- * Go on to the next word in the buffer
- */
- b++;
- }
- } else {
- /*
- * Starting on a word boundary, no partial word.
- */
- i = 0;
- }
- /*
- * Loop over whole words in buffers. When we use up one buffer
- * we move on to the next one.
- */
- while (len - i >= XFS_NBWORD) {
- /*
- * Set the word value correctly.
- */
- *b = val;
- i += XFS_NBWORD;
- /*
- * Go on to the next block if that's where the next word is
- * and we need the next word.
- */
- if (++word == XFS_BLOCKWSIZE(mp) && i < len) {
- /*
- * Log the changed part of this block.
- * Get the next one.
- */
- xfs_trans_log_buf(tp, bp,
- (uint)((char *)first - (char *)bufp),
- (uint)((char *)b - (char *)bufp));
- error = xfs_rtbuf_get(mp, tp, ++block, 0, &bp);
- if (error) {
- return error;
- }
- first = b = bufp = (xfs_rtword_t *)XFS_BUF_PTR(bp);
- word = 0;
- } else {
- /*
- * Go on to the next word in the buffer
- */
- b++;
- }
- }
- /*
- * If not ending on a word boundary, deal with the last
- * (partial) word.
- */
- if ((lastbit = len - i)) {
- /*
- * Compute a mask of relevant bits.
- */
- bit = 0;
- mask = ((xfs_rtword_t)1 << lastbit) - 1;
- /*
- * Set/clear the active bits.
- */
- if (val)
- *b |= mask;
- else
- *b &= ~mask;
- b++;
- }
- /*
- * Log any remaining changed bytes.
- */
- if (b > first)
- xfs_trans_log_buf(tp, bp, (uint)((char *)first - (char *)bufp),
- (uint)((char *)b - (char *)bufp - 1));
- return 0;
-}
-
-/*
- * Read and modify the summary information for a given extent size,
- * bitmap block combination.
- * Keeps track of a current summary block, so we don't keep reading
- * it from the buffer cache.
- */
-STATIC int /* error */
-xfs_rtmodify_summary(
- xfs_mount_t *mp, /* file system mount point */
- xfs_trans_t *tp, /* transaction pointer */
- int log, /* log2 of extent size */
- xfs_rtblock_t bbno, /* bitmap block number */
- int delta, /* change to make to summary info */
- xfs_buf_t **rbpp, /* in/out: summary block buffer */
- xfs_fsblock_t *rsb) /* in/out: summary block number */
-{
- xfs_buf_t *bp; /* buffer for the summary block */
- int error; /* error value */
- xfs_fsblock_t sb; /* summary fsblock */
- int so; /* index into the summary file */
- xfs_suminfo_t *sp; /* pointer to returned data */
-
- /*
- * Compute entry number in the summary file.
- */
- so = XFS_SUMOFFS(mp, log, bbno);
- /*
- * Compute the block number in the summary file.
- */
- sb = XFS_SUMOFFSTOBLOCK(mp, so);
- /*
- * If we have an old buffer, and the block number matches, use that.
- */
- if (rbpp && *rbpp && *rsb == sb)
- bp = *rbpp;
- /*
- * Otherwise we have to get the buffer.
- */
- else {
- /*
- * If there was an old one, get rid of it first.
- */
- if (rbpp && *rbpp)
- xfs_trans_brelse(tp, *rbpp);
- error = xfs_rtbuf_get(mp, tp, sb, 1, &bp);
- if (error) {
- return error;
- }
- /*
- * Remember this buffer and block for the next call.
- */
- if (rbpp) {
- *rbpp = bp;
- *rsb = sb;
- }
- }
- /*
- * Point to the summary information, modify and log it.
- */
- sp = XFS_SUMPTR(mp, bp, so);
- *sp += delta;
- xfs_trans_log_buf(tp, bp, (uint)((char *)sp - (char *)XFS_BUF_PTR(bp)),
- (uint)((char *)sp - (char *)XFS_BUF_PTR(bp) + sizeof(*sp) - 1));
- return 0;
-}
-
-/*
- * Visible (exported) functions.
- */
-
-/*
- * Grow the realtime area of the filesystem.
- */
-int
-xfs_growfs_rt(
- xfs_mount_t *mp, /* mount point for filesystem */
- xfs_growfs_rt_t *in) /* growfs rt input struct */
-{
- xfs_rtblock_t bmbno; /* bitmap block number */
- xfs_buf_t *bp; /* temporary buffer */
- int cancelflags; /* flags for xfs_trans_cancel */
- int error; /* error return value */
- xfs_inode_t *ip; /* bitmap inode, used as lock */
- xfs_mount_t *nmp; /* new (fake) mount structure */
- xfs_drfsbno_t nrblocks; /* new number of realtime blocks */
- xfs_extlen_t nrbmblocks; /* new number of rt bitmap blocks */
- xfs_drtbno_t nrextents; /* new number of realtime extents */
- uint8_t nrextslog; /* new log2 of sb_rextents */
- xfs_extlen_t nrsumblocks; /* new number of summary blocks */
- uint nrsumlevels; /* new rt summary levels */
- uint nrsumsize; /* new size of rt summary, bytes */
- xfs_sb_t *nsbp; /* new superblock */
- xfs_extlen_t rbmblocks; /* current number of rt bitmap blocks */
- xfs_extlen_t rsumblocks; /* current number of rt summary blks */
- xfs_sb_t *sbp; /* old superblock */
- xfs_fsblock_t sumbno; /* summary block number */
- xfs_trans_t *tp; /* transaction pointer */
-
- sbp = &mp->m_sb;
- /*
- * Initial error checking.
- */
- if (mp->m_rtdev_targp || mp->m_rbmip == NULL ||
- (nrblocks = in->newblocks) <= sbp->sb_rblocks ||
- (sbp->sb_rblocks && (in->extsize != sbp->sb_rextsize)))
- return XFS_ERROR(EINVAL);
- /*
- * Read in the last block of the device, make sure it exists.
- */
- error = xfs_read_buf(mp, mp->m_rtdev_targp,
- XFS_FSB_TO_BB(mp, in->newblocks - 1),
- XFS_FSB_TO_BB(mp, 1), 0, &bp);
- if (error)
- return error;
- ASSERT(bp);
- xfs_buf_relse(bp);
- /*
- * Calculate new parameters. These are the final values to be reached.
- */
- nrextents = nrblocks;
- do_div(nrextents, in->extsize);
- nrbmblocks = roundup_64(nrextents, NBBY * sbp->sb_blocksize);
- nrextslog = xfs_highbit32(nrextents);
- nrsumlevels = nrextslog + 1;
- nrsumsize = (uint)sizeof(xfs_suminfo_t) * nrsumlevels * nrbmblocks;
- nrsumblocks = XFS_B_TO_FSB(mp, nrsumsize);
- nrsumsize = XFS_FSB_TO_B(mp, nrsumblocks);
- /*
- * New summary size can't be more than half the size of
- * the log. This prevents us from getting a log overflow,
- * since we'll log basically the whole summary file at once.
- */
- if (nrsumblocks > (mp->m_sb.sb_logblocks >> 1))
- return XFS_ERROR(EINVAL);
- /*
- * Get the old block counts for bitmap and summary inodes.
- * These can't change since other growfs callers are locked out.
- */
- rbmblocks = XFS_B_TO_FSB(mp, mp->m_rbmip->i_d.di_size);
- rsumblocks = XFS_B_TO_FSB(mp, mp->m_rsumip->i_d.di_size);
- /*
- * Allocate space to the bitmap and summary files, as necessary.
- */
- if ((error = xfs_growfs_rt_alloc(mp, rbmblocks, nrbmblocks,
- mp->m_sb.sb_rbmino)))
- return error;
- if ((error = xfs_growfs_rt_alloc(mp, rsumblocks, nrsumblocks,
- mp->m_sb.sb_rsumino)))
- return error;
- nmp = NULL;
- /*
- * Loop over the bitmap blocks.
- * We will do everything one bitmap block at a time.
- * Skip the current block if it is exactly full.
- * This also deals with the case where there were no rtextents before.
- */
- for (bmbno = sbp->sb_rbmblocks -
- ((sbp->sb_rextents & ((1 << mp->m_blkbit_log) - 1)) != 0);
- bmbno < nrbmblocks;
- bmbno++) {
- /*
- * Allocate a new (fake) mount/sb.
- */
- nmp = kmem_alloc(sizeof(*nmp), KM_SLEEP);
- *nmp = *mp;
- nsbp = &nmp->m_sb;
- /*
- * Calculate new sb and mount fields for this round.
- */
- nsbp->sb_rextsize = in->extsize;
- nsbp->sb_rbmblocks = bmbno + 1;
- nsbp->sb_rblocks =
- XFS_RTMIN(nrblocks,
- nsbp->sb_rbmblocks * NBBY *
- nsbp->sb_blocksize * nsbp->sb_rextsize);
- nsbp->sb_rextents = nsbp->sb_rblocks;
- do_div(nsbp->sb_rextents, nsbp->sb_rextsize);
- nsbp->sb_rextslog = xfs_highbit32(nsbp->sb_rextents);
- nrsumlevels = nmp->m_rsumlevels = nsbp->sb_rextslog + 1;
- nrsumsize =
- (uint)sizeof(xfs_suminfo_t) * nrsumlevels *
- nsbp->sb_rbmblocks;
- nrsumblocks = XFS_B_TO_FSB(mp, nrsumsize);
- nmp->m_rsumsize = nrsumsize = XFS_FSB_TO_B(mp, nrsumblocks);
- /*
- * Start a transaction, get the log reservation.
- */
- tp = xfs_trans_alloc(mp, XFS_TRANS_GROWFSRT_FREE);
- cancelflags = 0;
- if ((error = xfs_trans_reserve(tp, 0,
- XFS_GROWRTFREE_LOG_RES(nmp), 0, 0, 0)))
- goto error_exit;
- /*
- * Lock out other callers by grabbing the bitmap inode lock.
- */
- if ((error = xfs_trans_iget(mp, tp, mp->m_sb.sb_rbmino, 0,
- XFS_ILOCK_EXCL, &ip)))
- goto error_exit;
- ASSERT(ip == mp->m_rbmip);
- /*
- * Update the bitmap inode's size.
- */
- mp->m_rbmip->i_d.di_size =
- nsbp->sb_rbmblocks * nsbp->sb_blocksize;
- xfs_trans_log_inode(tp, mp->m_rbmip, XFS_ILOG_CORE);
- cancelflags |= XFS_TRANS_ABORT;
- /*
- * Get the summary inode into the transaction.
- */
- if ((error = xfs_trans_iget(mp, tp, mp->m_sb.sb_rsumino, 0,
- XFS_ILOCK_EXCL, &ip)))
- goto error_exit;
- ASSERT(ip == mp->m_rsumip);
- /*
- * Update the summary inode's size.
- */
- mp->m_rsumip->i_d.di_size = nmp->m_rsumsize;
- xfs_trans_log_inode(tp, mp->m_rsumip, XFS_ILOG_CORE);
- /*
- * Copy summary data from old to new sizes.
- * Do this when the real size (not block-aligned) changes.
- */
- if (sbp->sb_rbmblocks != nsbp->sb_rbmblocks ||
- mp->m_rsumlevels != nmp->m_rsumlevels) {
- error = xfs_rtcopy_summary(mp, nmp, tp);
- if (error)
- goto error_exit;
- }
- /*
- * Update superblock fields.
- */
- if (nsbp->sb_rextsize != sbp->sb_rextsize)
- xfs_trans_mod_sb(tp, XFS_TRANS_SB_REXTSIZE,
- nsbp->sb_rextsize - sbp->sb_rextsize);
- if (nsbp->sb_rbmblocks != sbp->sb_rbmblocks)
- xfs_trans_mod_sb(tp, XFS_TRANS_SB_RBMBLOCKS,
- nsbp->sb_rbmblocks - sbp->sb_rbmblocks);
- if (nsbp->sb_rblocks != sbp->sb_rblocks)
- xfs_trans_mod_sb(tp, XFS_TRANS_SB_RBLOCKS,
- nsbp->sb_rblocks - sbp->sb_rblocks);
- if (nsbp->sb_rextents != sbp->sb_rextents)
- xfs_trans_mod_sb(tp, XFS_TRANS_SB_REXTENTS,
- nsbp->sb_rextents - sbp->sb_rextents);
- if (nsbp->sb_rextslog != sbp->sb_rextslog)
- xfs_trans_mod_sb(tp, XFS_TRANS_SB_REXTSLOG,
- nsbp->sb_rextslog - sbp->sb_rextslog);
- /*
- * Free new extent.
- */
- bp = NULL;
- error = xfs_rtfree_range(nmp, tp, sbp->sb_rextents,
- nsbp->sb_rextents - sbp->sb_rextents, &bp, &sumbno);
- if (error)
- goto error_exit;
- /*
- * Mark more blocks free in the superblock.
- */
- xfs_trans_mod_sb(tp, XFS_TRANS_SB_FREXTENTS,
- nsbp->sb_rextents - sbp->sb_rextents);
- /*
- * Free the fake mp structure.
- */
- kmem_free(nmp, sizeof(*nmp));
- nmp = NULL;
- /*
- * Update mp values into the real mp structure.
- */
- mp->m_rsumlevels = nrsumlevels;
- mp->m_rsumsize = nrsumsize;
- /*
- * Commit the transaction.
- */
- xfs_trans_commit(tp, 0, NULL);
- }
- return 0;
-
- /*
- * Error paths come here.
- */
-error_exit:
- if (nmp)
- kmem_free(nmp, sizeof(*nmp));
- xfs_trans_cancel(tp, cancelflags);
- return error;
-}
-
-/*
- * Allocate an extent in the realtime subvolume, with the usual allocation
- * parameters. The length units are all in realtime extents, as is the
- * result block number.
- */
-int /* error */
-xfs_rtallocate_extent(
- xfs_trans_t *tp, /* transaction pointer */
- xfs_rtblock_t bno, /* starting block number to allocate */
- xfs_extlen_t minlen, /* minimum length to allocate */
- xfs_extlen_t maxlen, /* maximum length to allocate */
- xfs_extlen_t *len, /* out: actual length allocated */
- xfs_alloctype_t type, /* allocation type XFS_ALLOCTYPE... */
- int wasdel, /* was a delayed allocation extent */
- xfs_extlen_t prod, /* extent product factor */
- xfs_rtblock_t *rtblock) /* out: start block allocated */
-{
- int error; /* error value */
- xfs_inode_t *ip; /* inode for bitmap file */
- xfs_mount_t *mp; /* file system mount structure */
- xfs_rtblock_t r; /* result allocated block */
- xfs_fsblock_t sb; /* summary file block number */
- xfs_buf_t *sumbp; /* summary file block buffer */
-
- ASSERT(minlen > 0 && minlen <= maxlen);
- mp = tp->t_mountp;
- /*
- * If prod is set then figure out what to do to minlen and maxlen.
- */
- if (prod > 1) {
- xfs_extlen_t i;
-
- if ((i = maxlen % prod))
- maxlen -= i;
- if ((i = minlen % prod))
- minlen += prod - i;
- if (maxlen < minlen) {
- *rtblock = NULLRTBLOCK;
- return 0;
- }
- }
- /*
- * Lock out other callers by grabbing the bitmap inode lock.
- */
- if ((error = xfs_trans_iget(mp, tp, mp->m_sb.sb_rbmino, 0,
- XFS_ILOCK_EXCL, &ip)))
- return error;
- sumbp = NULL;
- /*
- * Allocate by size, or near another block, or exactly at some block.
- */
- switch (type) {
- case XFS_ALLOCTYPE_ANY_AG:
- error = xfs_rtallocate_extent_size(mp, tp, minlen, maxlen, len,
- &sumbp, &sb, prod, &r);
- break;
- case XFS_ALLOCTYPE_NEAR_BNO:
- error = xfs_rtallocate_extent_near(mp, tp, bno, minlen, maxlen,
- len, &sumbp, &sb, prod, &r);
- break;
- case XFS_ALLOCTYPE_THIS_BNO:
- error = xfs_rtallocate_extent_exact(mp, tp, bno, minlen, maxlen,
- len, &sumbp, &sb, prod, &r);
- break;
- default:
- ASSERT(0);
- }
- if (error) {
- return error;
- }
- /*
- * If it worked, update the superblock.
- */
- if (r != NULLRTBLOCK) {
- long slen = (long)*len;
-
- ASSERT(*len >= minlen && *len <= maxlen);
- if (wasdel)
- xfs_trans_mod_sb(tp, XFS_TRANS_SB_RES_FREXTENTS, -slen);
- else
- xfs_trans_mod_sb(tp, XFS_TRANS_SB_FREXTENTS, -slen);
- }
- *rtblock = r;
- return 0;
-}
-
-/*
- * Free an extent in the realtime subvolume. Length is expressed in
- * realtime extents, as is the block number.
- */
-int /* error */
-xfs_rtfree_extent(
- xfs_trans_t *tp, /* transaction pointer */
- xfs_rtblock_t bno, /* starting block number to free */
- xfs_extlen_t len) /* length of extent freed */
-{
- int error; /* error value */
- xfs_inode_t *ip; /* bitmap file inode */
- xfs_mount_t *mp; /* file system mount structure */
- xfs_fsblock_t sb; /* summary file block number */
- xfs_buf_t *sumbp; /* summary file block buffer */
-
- mp = tp->t_mountp;
- /*
- * Synchronize by locking the bitmap inode.
- */
- if ((error = xfs_trans_iget(mp, tp, mp->m_sb.sb_rbmino, 0,
- XFS_ILOCK_EXCL, &ip)))
- return error;
-#if defined(__KERNEL__) && defined(DEBUG)
- /*
- * Check to see that this whole range is currently allocated.
- */
- {
- int stat; /* result from checking range */
-
- error = xfs_rtcheck_alloc_range(mp, tp, bno, len, &stat);
- if (error) {
- return error;
- }
- ASSERT(stat);
- }
-#endif
- sumbp = NULL;
- /*
- * Free the range of realtime blocks.
- */
- error = xfs_rtfree_range(mp, tp, bno, len, &sumbp, &sb);
- if (error) {
- return error;
- }
- /*
- * Mark more blocks free in the superblock.
- */
- xfs_trans_mod_sb(tp, XFS_TRANS_SB_FREXTENTS, (long)len);
- /*
- * If we've now freed all the blocks, reset the file sequence
- * number to 0.
- */
- if (tp->t_frextents_delta + mp->m_sb.sb_frextents ==
- mp->m_sb.sb_rextents) {
- if (!(ip->i_d.di_flags & XFS_DIFLAG_NEWRTBM))
- ip->i_d.di_flags |= XFS_DIFLAG_NEWRTBM;
- *(__uint64_t *)&ip->i_d.di_atime = 0;
- xfs_trans_log_inode(tp, ip, XFS_ILOG_CORE);
- }
- return 0;
-}
-
-/*
- * Initialize realtime fields in the mount structure.
- */
-int /* error */
-xfs_rtmount_init(
- xfs_mount_t *mp) /* file system mount structure */
-{
- xfs_buf_t *bp; /* buffer for last block of subvolume */
- xfs_daddr_t d; /* address of last block of subvolume */
- int error; /* error return value */
- xfs_sb_t *sbp; /* filesystem superblock copy in mount */
-
- sbp = &mp->m_sb;
- if (sbp->sb_rblocks == 0)
- return 0;
- if (mp->m_rtdev_targp == NULL) {
- cmn_err(CE_WARN,
- "XFS: This filesystem has a realtime volume, use rtdev=device option");
- return XFS_ERROR(ENODEV);
- }
- mp->m_rsumlevels = sbp->sb_rextslog + 1;
- mp->m_rsumsize =
- (uint)sizeof(xfs_suminfo_t) * mp->m_rsumlevels *
- sbp->sb_rbmblocks;
- mp->m_rsumsize = roundup(mp->m_rsumsize, sbp->sb_blocksize);
- mp->m_rbmip = mp->m_rsumip = NULL;
- /*
- * Check that the realtime section is an ok size.
- */
- d = (xfs_daddr_t)XFS_FSB_TO_BB(mp, mp->m_sb.sb_rblocks);
- if (XFS_BB_TO_FSB(mp, d) != mp->m_sb.sb_rblocks) {
- cmn_err(CE_WARN, "XFS: realtime mount -- %llu != %llu",
- (unsigned long long) XFS_BB_TO_FSB(mp, d),
- (unsigned long long) mp->m_sb.sb_rblocks);
- return XFS_ERROR(E2BIG);
- }
- error = xfs_read_buf(mp, mp->m_rtdev_targp,
- d - XFS_FSB_TO_BB(mp, 1),
- XFS_FSB_TO_BB(mp, 1), 0, &bp);
- if (error) {
- cmn_err(CE_WARN,
- "XFS: realtime mount -- xfs_read_buf failed, returned %d", error);
- if (error == ENOSPC)
- return XFS_ERROR(E2BIG);
- return error;
- }
- xfs_buf_relse(bp);
- return 0;
-}
-
-/*
- * Get the bitmap and summary inodes into the mount structure
- * at mount time.
- */
-int /* error */
-xfs_rtmount_inodes(
- xfs_mount_t *mp) /* file system mount structure */
-{
- int error; /* error return value */
- xfs_sb_t *sbp;
-
- sbp = &mp->m_sb;
- if (sbp->sb_rbmino == NULLFSINO)
- return 0;
- error = xfs_iget(mp, NULL, sbp->sb_rbmino, 0, 0, &mp->m_rbmip, 0);
- if (error)
- return error;
- ASSERT(mp->m_rbmip != NULL);
- ASSERT(sbp->sb_rsumino != NULLFSINO);
- error = xfs_iget(mp, NULL, sbp->sb_rsumino, 0, 0, &mp->m_rsumip, 0);
- if (error) {
- VN_RELE(XFS_ITOV(mp->m_rbmip));
- return error;
- }
- ASSERT(mp->m_rsumip != NULL);
- return 0;
-}
-
-/*
- * Pick an extent for allocation at the start of a new realtime file.
- * Use the sequence number stored in the atime field of the bitmap inode.
- * Translate this to a fraction of the rtextents, and return the product
- * of rtextents and the fraction.
- * The fraction sequence is 0, 1/2, 1/4, 3/4, 1/8, ..., 7/8, 1/16, ...
- */
-int /* error */
-xfs_rtpick_extent(
- xfs_mount_t *mp, /* file system mount point */
- xfs_trans_t *tp, /* transaction pointer */
- xfs_extlen_t len, /* allocation length (rtextents) */
- xfs_rtblock_t *pick) /* result rt extent */
-{
- xfs_rtblock_t b; /* result block */
- int error; /* error return value */
- xfs_inode_t *ip; /* bitmap incore inode */
- int log2; /* log of sequence number */
- __uint64_t resid; /* residual after log removed */
- __uint64_t seq; /* sequence number of file creation */
- __uint64_t *seqp; /* pointer to seqno in inode */
-
- if ((error = xfs_trans_iget(mp, tp, mp->m_sb.sb_rbmino, 0,
- XFS_ILOCK_EXCL, &ip)))
- return error;
- ASSERT(ip == mp->m_rbmip);
- seqp = (__uint64_t *)&ip->i_d.di_atime;
- if (!(ip->i_d.di_flags & XFS_DIFLAG_NEWRTBM)) {
- ip->i_d.di_flags |= XFS_DIFLAG_NEWRTBM;
- *seqp = 0;
- }
- seq = *seqp;
- if ((log2 = xfs_highbit64(seq)) == -1)
- b = 0;
- else {
- resid = seq - (1ULL << log2);
- b = (mp->m_sb.sb_rextents * ((resid << 1) + 1ULL)) >>
- (log2 + 1);
- if (b >= mp->m_sb.sb_rextents)
- b = do_mod(b, mp->m_sb.sb_rextents);
- if (b + len > mp->m_sb.sb_rextents)
- b = mp->m_sb.sb_rextents - len;
- }
- *seqp = seq + 1;
- xfs_trans_log_inode(tp, ip, XFS_ILOG_CORE);
- *pick = b;
- return 0;
-}
-
-#ifdef DEBUG
-/*
- * Debug code: print out the value of a range in the bitmap.
- */
-void
-xfs_rtprint_range(
- xfs_mount_t *mp, /* file system mount structure */
- xfs_trans_t *tp, /* transaction pointer */
- xfs_rtblock_t start, /* starting block to print */
- xfs_extlen_t len) /* length to print */
-{
- xfs_extlen_t i; /* block number in the extent */
-
- printk("%Ld: ", (long long)start);
- for (i = 0; i < len; i++)
- printk("%d", xfs_rtcheck_bit(mp, tp, start + i, 1));
- printk("\n");
-}
-
-/*
- * Debug code: print the summary file.
- */
-void
-xfs_rtprint_summary(
- xfs_mount_t *mp, /* file system mount structure */
- xfs_trans_t *tp) /* transaction pointer */
-{
- xfs_suminfo_t c; /* summary data */
- xfs_rtblock_t i; /* bitmap block number */
- int l; /* summary information level */
- int p; /* flag for printed anything */
- xfs_fsblock_t sb; /* summary block number */
- xfs_buf_t *sumbp; /* summary block buffer */
-
- sumbp = NULL;
- for (l = 0; l < mp->m_rsumlevels; l++) {
- for (p = 0, i = 0; i < mp->m_sb.sb_rbmblocks; i++) {
- (void)xfs_rtget_summary(mp, tp, l, i, &sumbp, &sb, &c);
- if (c) {
- if (!p) {
- printk("%Ld-%Ld:", 1LL << l,
- XFS_RTMIN((1LL << l) +
- ((1LL << l) - 1LL),
- mp->m_sb.sb_rextents));
- p = 1;
- }
- printk(" %Ld:%d", (long long)i, c);
- }
- }
- if (p)
- printk("\n");
- }
- if (sumbp)
- xfs_trans_brelse(tp, sumbp);
-}
-#endif /* DEBUG */
diff --git a/sys/gnu/fs/xfs/xfs_rtalloc.h b/sys/gnu/fs/xfs/xfs_rtalloc.h
deleted file mode 100644
index 89297a0..0000000
--- a/sys/gnu/fs/xfs/xfs_rtalloc.h
+++ /dev/null
@@ -1,173 +0,0 @@
-/*
- * Copyright (c) 2000-2003,2005 Silicon Graphics, Inc.
- * All Rights Reserved.
- *
- * 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.
- *
- * This program is distributed in the hope that it would 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 the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- */
-#ifndef __XFS_RTALLOC_H__
-#define __XFS_RTALLOC_H__
-
-struct xfs_mount;
-struct xfs_trans;
-
-#define XFS_IS_REALTIME_INODE(ip) ((ip)->i_d.di_flags & XFS_DIFLAG_REALTIME)
-
-/* Min and max rt extent sizes, specified in bytes */
-#define XFS_MAX_RTEXTSIZE (1024 * 1024 * 1024) /* 1GB */
-#define XFS_DFL_RTEXTSIZE (64 * 1024) /* 64KB */
-#define XFS_MIN_RTEXTSIZE (4 * 1024) /* 4KB */
-
-/*
- * Constants for bit manipulations.
- */
-#define XFS_NBBYLOG 3 /* log2(NBBY) */
-#define XFS_WORDLOG 2 /* log2(sizeof(xfs_rtword_t)) */
-#define XFS_NBWORDLOG (XFS_NBBYLOG + XFS_WORDLOG)
-#define XFS_NBWORD (1 << XFS_NBWORDLOG)
-#define XFS_WORDMASK ((1 << XFS_WORDLOG) - 1)
-
-#define XFS_BLOCKSIZE(mp) ((mp)->m_sb.sb_blocksize)
-#define XFS_BLOCKMASK(mp) ((mp)->m_blockmask)
-#define XFS_BLOCKWSIZE(mp) ((mp)->m_blockwsize)
-#define XFS_BLOCKWMASK(mp) ((mp)->m_blockwmask)
-
-/*
- * Summary and bit manipulation macros.
- */
-#define XFS_SUMOFFS(mp,ls,bb) ((int)((ls) * (mp)->m_sb.sb_rbmblocks + (bb)))
-#define XFS_SUMOFFSTOBLOCK(mp,s) \
- (((s) * (uint)sizeof(xfs_suminfo_t)) >> (mp)->m_sb.sb_blocklog)
-#define XFS_SUMPTR(mp,bp,so) \
- ((xfs_suminfo_t *)((char *)XFS_BUF_PTR(bp) + \
- (((so) * (uint)sizeof(xfs_suminfo_t)) & XFS_BLOCKMASK(mp))))
-
-#define XFS_BITTOBLOCK(mp,bi) ((bi) >> (mp)->m_blkbit_log)
-#define XFS_BLOCKTOBIT(mp,bb) ((bb) << (mp)->m_blkbit_log)
-#define XFS_BITTOWORD(mp,bi) \
- ((int)(((bi) >> XFS_NBWORDLOG) & XFS_BLOCKWMASK(mp)))
-
-#define XFS_RTMIN(a,b) ((a) < (b) ? (a) : (b))
-#define XFS_RTMAX(a,b) ((a) > (b) ? (a) : (b))
-
-#define XFS_RTLOBIT(w) xfs_lowbit32(w)
-#define XFS_RTHIBIT(w) xfs_highbit32(w)
-
-#if XFS_BIG_BLKNOS
-#define XFS_RTBLOCKLOG(b) xfs_highbit64(b)
-#else
-#define XFS_RTBLOCKLOG(b) xfs_highbit32(b)
-#endif
-
-
-#ifdef __KERNEL__
-
-#ifdef CONFIG_XFS_RT
-/*
- * Function prototypes for exported functions.
- */
-
-/*
- * Allocate an extent in the realtime subvolume, with the usual allocation
- * parameters. The length units are all in realtime extents, as is the
- * result block number.
- */
-int /* error */
-xfs_rtallocate_extent(
- struct xfs_trans *tp, /* transaction pointer */
- xfs_rtblock_t bno, /* starting block number to allocate */
- xfs_extlen_t minlen, /* minimum length to allocate */
- xfs_extlen_t maxlen, /* maximum length to allocate */
- xfs_extlen_t *len, /* out: actual length allocated */
- xfs_alloctype_t type, /* allocation type XFS_ALLOCTYPE... */
- int wasdel, /* was a delayed allocation extent */
- xfs_extlen_t prod, /* extent product factor */
- xfs_rtblock_t *rtblock); /* out: start block allocated */
-
-/*
- * Free an extent in the realtime subvolume. Length is expressed in
- * realtime extents, as is the block number.
- */
-int /* error */
-xfs_rtfree_extent(
- struct xfs_trans *tp, /* transaction pointer */
- xfs_rtblock_t bno, /* starting block number to free */
- xfs_extlen_t len); /* length of extent freed */
-
-/*
- * Initialize realtime fields in the mount structure.
- */
-int /* error */
-xfs_rtmount_init(
- struct xfs_mount *mp); /* file system mount structure */
-
-/*
- * Get the bitmap and summary inodes into the mount structure
- * at mount time.
- */
-int /* error */
-xfs_rtmount_inodes(
- struct xfs_mount *mp); /* file system mount structure */
-
-/*
- * Pick an extent for allocation at the start of a new realtime file.
- * Use the sequence number stored in the atime field of the bitmap inode.
- * Translate this to a fraction of the rtextents, and return the product
- * of rtextents and the fraction.
- * The fraction sequence is 0, 1/2, 1/4, 3/4, 1/8, ..., 7/8, 1/16, ...
- */
-int /* error */
-xfs_rtpick_extent(
- struct xfs_mount *mp, /* file system mount point */
- struct xfs_trans *tp, /* transaction pointer */
- xfs_extlen_t len, /* allocation length (rtextents) */
- xfs_rtblock_t *pick); /* result rt extent */
-
-/*
- * Debug code: print out the value of a range in the bitmap.
- */
-void
-xfs_rtprint_range(
- struct xfs_mount *mp, /* file system mount structure */
- struct xfs_trans *tp, /* transaction pointer */
- xfs_rtblock_t start, /* starting block to print */
- xfs_extlen_t len); /* length to print */
-
-/*
- * Debug code: print the summary file.
- */
-void
-xfs_rtprint_summary(
- struct xfs_mount *mp, /* file system mount structure */
- struct xfs_trans *tp); /* transaction pointer */
-
-/*
- * Grow the realtime area of the filesystem.
- */
-int
-xfs_growfs_rt(
- struct xfs_mount *mp, /* file system mount structure */
- xfs_growfs_rt_t *in); /* user supplied growfs struct */
-
-#else
-# define xfs_rtallocate_extent(t,b,min,max,l,a,f,p,rb) (ENOSYS)
-# define xfs_rtfree_extent(t,b,l) (ENOSYS)
-# define xfs_rtpick_extent(m,t,l,rb) ((*rb = 0), ENOSYS)
-# define xfs_growfs_rt(mp,in) (ENOSYS)
-# define xfs_rtmount_init(m) (((mp)->m_sb.sb_rblocks == 0)? 0 : (ENOSYS))
-# define xfs_rtmount_inodes(m) (((mp)->m_sb.sb_rblocks == 0)? 0 : (ENOSYS))
-#endif /* CONFIG_XFS_RT */
-
-#endif /* __KERNEL__ */
-
-#endif /* __XFS_RTALLOC_H__ */
diff --git a/sys/gnu/fs/xfs/xfs_rw.c b/sys/gnu/fs/xfs/xfs_rw.c
deleted file mode 100644
index a59c102..0000000
--- a/sys/gnu/fs/xfs/xfs_rw.c
+++ /dev/null
@@ -1,341 +0,0 @@
-/*
- * Copyright (c) 2000-2003,2005 Silicon Graphics, Inc.
- * All Rights Reserved.
- *
- * 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.
- *
- * This program is distributed in the hope that it would 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 the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- */
-#include "xfs.h"
-#include "xfs_fs.h"
-#include "xfs_types.h"
-#include "xfs_bit.h"
-#include "xfs_log.h"
-#include "xfs_inum.h"
-#include "xfs_trans.h"
-#include "xfs_sb.h"
-#include "xfs_ag.h"
-#include "xfs_dir.h"
-#include "xfs_dir2.h"
-#include "xfs_dmapi.h"
-#include "xfs_mount.h"
-#include "xfs_bmap_btree.h"
-#include "xfs_alloc_btree.h"
-#include "xfs_ialloc_btree.h"
-#include "xfs_dir_sf.h"
-#include "xfs_dir2_sf.h"
-#include "xfs_attr_sf.h"
-#include "xfs_dinode.h"
-#include "xfs_inode.h"
-#include "xfs_inode_item.h"
-#include "xfs_itable.h"
-#include "xfs_btree.h"
-#include "xfs_alloc.h"
-#include "xfs_ialloc.h"
-#include "xfs_attr.h"
-#include "xfs_bmap.h"
-#include "xfs_acl.h"
-#include "xfs_mac.h"
-#include "xfs_error.h"
-#include "xfs_buf_item.h"
-#include "xfs_rw.h"
-
-/*
- * This is a subroutine for xfs_write() and other writers (xfs_ioctl)
- * which clears the setuid and setgid bits when a file is written.
- */
-int
-xfs_write_clear_setuid(
- xfs_inode_t *ip)
-{
- xfs_mount_t *mp;
- xfs_trans_t *tp;
- int error;
-
- mp = ip->i_mount;
- tp = xfs_trans_alloc(mp, XFS_TRANS_WRITEID);
- if ((error = xfs_trans_reserve(tp, 0,
- XFS_WRITEID_LOG_RES(mp),
- 0, 0, 0))) {
- xfs_trans_cancel(tp, 0);
- return error;
- }
- xfs_ilock(ip, XFS_ILOCK_EXCL);
- xfs_trans_ijoin(tp, ip, XFS_ILOCK_EXCL);
- xfs_trans_ihold(tp, ip);
- ip->i_d.di_mode &= ~S_ISUID;
-
- /*
- * Note that we don't have to worry about mandatory
- * file locking being disabled here because we only
- * clear the S_ISGID bit if the Group execute bit is
- * on, but if it was on then mandatory locking wouldn't
- * have been enabled.
- */
- if (ip->i_d.di_mode & S_IXGRP) {
- ip->i_d.di_mode &= ~S_ISGID;
- }
- xfs_trans_log_inode(tp, ip, XFS_ILOG_CORE);
- xfs_trans_set_sync(tp);
- error = xfs_trans_commit(tp, 0, NULL);
- xfs_iunlock(ip, XFS_ILOCK_EXCL);
- return 0;
-}
-
-/*
- * Force a shutdown of the filesystem instantly while keeping
- * the filesystem consistent. We don't do an unmount here; just shutdown
- * the shop, make sure that absolutely nothing persistent happens to
- * this filesystem after this point.
- */
-
-void
-xfs_do_force_shutdown(
- bhv_desc_t *bdp,
- int flags,
- char *fname,
- int lnnum)
-{
- int logerror;
- xfs_mount_t *mp;
-
- mp = XFS_BHVTOM(bdp);
- logerror = flags & XFS_LOG_IO_ERROR;
-
- if (!(flags & XFS_FORCE_UMOUNT)) {
- cmn_err(CE_NOTE,
- "xfs_force_shutdown(%s,0x%x) called from line %d of file %s. Return address = 0x%p",
- mp->m_fsname,flags,lnnum,fname,__return_address);
- }
- /*
- * No need to duplicate efforts.
- */
- if (XFS_FORCED_SHUTDOWN(mp) && !logerror)
- return;
-
- /*
- * This flags XFS_MOUNT_FS_SHUTDOWN, makes sure that we don't
- * queue up anybody new on the log reservations, and wakes up
- * everybody who's sleeping on log reservations and tells
- * them the bad news.
- */
- if (xfs_log_force_umount(mp, logerror))
- return;
-
- if (flags & XFS_CORRUPT_INCORE) {
- xfs_cmn_err(XFS_PTAG_SHUTDOWN_CORRUPT, CE_ALERT, mp,
- "Corruption of in-memory data detected. Shutting down filesystem: %s",
- mp->m_fsname);
- if (XFS_ERRLEVEL_HIGH <= xfs_error_level) {
- xfs_stack_trace();
- }
- } else if (!(flags & XFS_FORCE_UMOUNT)) {
- if (logerror) {
- xfs_cmn_err(XFS_PTAG_SHUTDOWN_LOGERROR, CE_ALERT, mp,
- "Log I/O Error Detected. Shutting down filesystem: %s",
- mp->m_fsname);
- } else if (!(flags & XFS_SHUTDOWN_REMOTE_REQ)) {
- xfs_cmn_err(XFS_PTAG_SHUTDOWN_IOERROR, CE_ALERT, mp,
- "I/O Error Detected. Shutting down filesystem: %s",
- mp->m_fsname);
- }
- }
- if (!(flags & XFS_FORCE_UMOUNT)) {
- cmn_err(CE_ALERT,
- "Please umount the filesystem, and rectify the problem(s)");
- }
-}
-
-
-/*
- * Called when we want to stop a buffer from getting written or read.
- * We attach the EIO error, muck with its flags, and call biodone
- * so that the proper iodone callbacks get called.
- */
-int
-xfs_bioerror(
- xfs_buf_t *bp)
-{
-
-#ifdef XFSERRORDEBUG
- ASSERT(XFS_BUF_ISREAD(bp) || bp->b_iodone);
-#endif
-
- /*
- * No need to wait until the buffer is unpinned.
- * We aren't flushing it.
- */
- xfs_buftrace("XFS IOERROR", bp);
- XFS_BUF_ERROR(bp, EIO);
- /*
- * We're calling biodone, so delete B_DONE flag. Either way
- * we have to call the iodone callback, and calling biodone
- * probably is the best way since it takes care of
- * GRIO as well.
- */
- XFS_BUF_UNREAD(bp);
- XFS_BUF_UNDELAYWRITE(bp);
- XFS_BUF_UNDONE(bp);
- XFS_BUF_STALE(bp);
-
- XFS_BUF_CLR_BDSTRAT_FUNC(bp);
- xfs_biodone(bp);
-
- return (EIO);
-}
-
-/*
- * Same as xfs_bioerror, except that we are releasing the buffer
- * here ourselves, and avoiding the biodone call.
- * This is meant for userdata errors; metadata bufs come with
- * iodone functions attached, so that we can track down errors.
- */
-int
-xfs_bioerror_relse(
- xfs_buf_t *bp)
-{
- int64_t fl;
-
- ASSERT(XFS_BUF_IODONE_FUNC(bp) != xfs_buf_iodone_callbacks);
- ASSERT(XFS_BUF_IODONE_FUNC(bp) != xlog_iodone);
-
- xfs_buftrace("XFS IOERRELSE", bp);
- fl = XFS_BUF_BFLAGS(bp);
- /*
- * No need to wait until the buffer is unpinned.
- * We aren't flushing it.
- *
- * chunkhold expects B_DONE to be set, whether
- * we actually finish the I/O or not. We don't want to
- * change that interface.
- */
- XFS_BUF_UNREAD(bp);
- XFS_BUF_UNDELAYWRITE(bp);
- XFS_BUF_DONE(bp);
- XFS_BUF_STALE(bp);
- XFS_BUF_CLR_IODONE_FUNC(bp);
- XFS_BUF_CLR_BDSTRAT_FUNC(bp);
- if (!(fl & XFS_B_ASYNC)) {
- /*
- * Mark b_error and B_ERROR _both_.
- * Lot's of chunkcache code assumes that.
- * There's no reason to mark error for
- * ASYNC buffers.
- */
- XFS_BUF_ERROR(bp, EIO);
- XFS_BUF_V_IODONESEMA(bp);
- } else {
- xfs_buf_relse(bp);
- }
- return (EIO);
-}
-
-/*
- * Prints out an ALERT message about I/O error.
- */
-void
-xfs_ioerror_alert(
- char *func,
- struct xfs_mount *mp,
- xfs_buf_t *bp,
- xfs_daddr_t blkno)
-{
- cmn_err(CE_ALERT,
- "I/O error in filesystem (\"%s\") meta-data dev %s block 0x%llx"
- " (\"%s\") error %d buf count %zd",
- (!mp || !mp->m_fsname) ? "(fs name not set)" : mp->m_fsname,
- XFS_BUFTARG_NAME(XFS_BUF_TARGET(bp)),
- (__uint64_t)blkno, func,
- XFS_BUF_GETERROR(bp), XFS_BUF_COUNT(bp));
-}
-
-/*
- * This isn't an absolute requirement, but it is
- * just a good idea to call xfs_read_buf instead of
- * directly doing a read_buf call. For one, we shouldn't
- * be doing this disk read if we are in SHUTDOWN state anyway,
- * so this stops that from happening. Secondly, this does all
- * the error checking stuff and the brelse if appropriate for
- * the caller, so the code can be a little leaner.
- */
-
-int
-xfs_read_buf(
- struct xfs_mount *mp,
- xfs_buftarg_t *target,
- xfs_daddr_t blkno,
- int len,
- uint flags,
- xfs_buf_t **bpp)
-{
- xfs_buf_t *bp;
- int error;
-
- if (flags)
- bp = xfs_buf_read_flags(target, blkno, len, flags);
- else
- bp = xfs_buf_read(target, blkno, len, flags);
- if (!bp)
- return XFS_ERROR(EIO);
- error = XFS_BUF_GETERROR(bp);
- if (bp && !error && !XFS_FORCED_SHUTDOWN(mp)) {
- *bpp = bp;
- } else {
- *bpp = NULL;
- if (error) {
- xfs_ioerror_alert("xfs_read_buf", mp, bp, XFS_BUF_ADDR(bp));
- } else {
- error = XFS_ERROR(EIO);
- }
- if (bp) {
- XFS_BUF_UNDONE(bp);
- XFS_BUF_UNDELAYWRITE(bp);
- XFS_BUF_STALE(bp);
- /*
- * brelse clears B_ERROR and b_error
- */
- xfs_buf_relse(bp);
- }
- }
- return (error);
-}
-
-/*
- * Wrapper around bwrite() so that we can trap
- * write errors, and act accordingly.
- */
-int
-xfs_bwrite(
- struct xfs_mount *mp,
- struct xfs_buf *bp)
-{
- int error;
-
- /*
- * XXXsup how does this work for quotas.
- */
- XFS_BUF_SET_BDSTRAT_FUNC(bp, xfs_bdstrat_cb);
- XFS_BUF_SET_FSPRIVATE3(bp, mp);
- XFS_BUF_WRITE(bp);
-
- if ((error = XFS_bwrite(bp))) {
- ASSERT(mp);
- /*
- * Cannot put a buftrace here since if the buffer is not
- * B_HOLD then we will brelse() the buffer before returning
- * from bwrite and we could be tracing a buffer that has
- * been reused.
- */
- xfs_force_shutdown(mp, XFS_METADATA_IO_ERROR);
- }
- return (error);
-}
diff --git a/sys/gnu/fs/xfs/xfs_rw.h b/sys/gnu/fs/xfs/xfs_rw.h
deleted file mode 100644
index 34994b9..0000000
--- a/sys/gnu/fs/xfs/xfs_rw.h
+++ /dev/null
@@ -1,98 +0,0 @@
-/*
- * Copyright (c) 2000-2003,2005 Silicon Graphics, Inc.
- * All Rights Reserved.
- *
- * 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.
- *
- * This program is distributed in the hope that it would 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 the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- */
-#ifndef __XFS_RW_H__
-#define __XFS_RW_H__
-
-struct xfs_buf;
-struct xfs_inode;
-struct xfs_mount;
-
-/*
- * Maximum count of bmaps used by read and write paths.
- */
-#define XFS_MAX_RW_NBMAPS 4
-
-/*
- * Counts of readahead buffers to use based on physical memory size.
- * None of these should be more than XFS_MAX_RW_NBMAPS.
- */
-#define XFS_RW_NREADAHEAD_16MB 2
-#define XFS_RW_NREADAHEAD_32MB 3
-#define XFS_RW_NREADAHEAD_K32 4
-#define XFS_RW_NREADAHEAD_K64 4
-
-/*
- * Maximum size of a buffer that we\'ll map. Making this
- * too big will degrade performance due to the number of
- * pages which need to be gathered. Making it too small
- * will prevent us from doing large I/O\'s to hardware that
- * needs it.
- *
- * This is currently set to 512 KB.
- */
-#define XFS_MAX_BMAP_LEN_BB 1024
-#define XFS_MAX_BMAP_LEN_BYTES 524288
-
-/*
- * Convert the given file system block to a disk block.
- * We have to treat it differently based on whether the
- * file is a real time file or not, because the bmap code
- * does.
- */
-#define XFS_FSB_TO_DB(ip,fsb) xfs_fsb_to_db(ip,fsb)
-static inline xfs_daddr_t
-xfs_fsb_to_db(struct xfs_inode *ip, xfs_fsblock_t fsb)
-{
- return (((ip)->i_d.di_flags & XFS_DIFLAG_REALTIME) ? \
- (xfs_daddr_t)XFS_FSB_TO_BB((ip)->i_mount, (fsb)) : \
- XFS_FSB_TO_DADDR((ip)->i_mount, (fsb)));
-}
-#define XFS_FSB_TO_DB_IO(io,fsb) xfs_fsb_to_db_io(io,fsb)
-static inline xfs_daddr_t
-xfs_fsb_to_db_io(struct xfs_iocore *io, xfs_fsblock_t fsb)
-{
- return (((io)->io_flags & XFS_IOCORE_RT) ? \
- XFS_FSB_TO_BB((io)->io_mount, (fsb)) : \
- XFS_FSB_TO_DADDR((io)->io_mount, (fsb)));
-}
-
-/*
- * Prototypes for functions in xfs_rw.c.
- */
-extern int xfs_write_clear_setuid(struct xfs_inode *ip);
-extern int xfs_bwrite(struct xfs_mount *mp, struct xfs_buf *bp);
-extern int xfs_bioerror(struct xfs_buf *bp);
-extern int xfs_bioerror_relse(struct xfs_buf *bp);
-extern int xfs_read_buf(struct xfs_mount *mp, xfs_buftarg_t *btp,
- xfs_daddr_t blkno, int len, uint flags,
- struct xfs_buf **bpp);
-extern void xfs_ioerror_alert(char *func, struct xfs_mount *mp,
- xfs_buf_t *bp, xfs_daddr_t blkno);
-
-/*
- * Prototypes for functions in xfs_vnodeops.c.
- */
-extern int xfs_rwlock(bhv_desc_t *bdp, vrwlock_t write_lock);
-extern void xfs_rwunlock(bhv_desc_t *bdp, vrwlock_t write_lock);
-extern int xfs_setattr(bhv_desc_t *bdp, xfs_vattr_t *vap, int flags, cred_t *credp);
-extern int xfs_change_file_space(bhv_desc_t *bdp, u_long cmd, xfs_flock64_t *bf,
- xfs_off_t offset, cred_t *credp, int flags);
-extern int xfs_set_dmattrs(bhv_desc_t *bdp, u_int evmask, u_int16_t state,
- cred_t *credp);
-
-#endif /* __XFS_RW_H__ */
diff --git a/sys/gnu/fs/xfs/xfs_sb.h b/sys/gnu/fs/xfs/xfs_sb.h
deleted file mode 100644
index bf168a9..0000000
--- a/sys/gnu/fs/xfs/xfs_sb.h
+++ /dev/null
@@ -1,492 +0,0 @@
-/*
- * Copyright (c) 2000-2005 Silicon Graphics, Inc.
- * All Rights Reserved.
- *
- * 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.
- *
- * This program is distributed in the hope that it would 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 the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- */
-#ifndef __XFS_SB_H__
-#define __XFS_SB_H__
-
-/*
- * Super block
- * Fits into a sector-sized buffer at address 0 of each allocation group.
- * Only the first of these is ever updated except during growfs.
- */
-
-struct xfs_buf;
-struct xfs_mount;
-
-#define XFS_SB_MAGIC 0x58465342 /* 'XFSB' */
-#define XFS_SB_VERSION_1 1 /* 5.3, 6.0.1, 6.1 */
-#define XFS_SB_VERSION_2 2 /* 6.2 - attributes */
-#define XFS_SB_VERSION_3 3 /* 6.2 - new inode version */
-#define XFS_SB_VERSION_4 4 /* 6.2+ - bitmask version */
-#define XFS_SB_VERSION_NUMBITS 0x000f
-#define XFS_SB_VERSION_ALLFBITS 0xfff0
-#define XFS_SB_VERSION_SASHFBITS 0xf000
-#define XFS_SB_VERSION_REALFBITS 0x0ff0
-#define XFS_SB_VERSION_ATTRBIT 0x0010
-#define XFS_SB_VERSION_NLINKBIT 0x0020
-#define XFS_SB_VERSION_QUOTABIT 0x0040
-#define XFS_SB_VERSION_ALIGNBIT 0x0080
-#define XFS_SB_VERSION_DALIGNBIT 0x0100
-#define XFS_SB_VERSION_SHAREDBIT 0x0200
-#define XFS_SB_VERSION_LOGV2BIT 0x0400
-#define XFS_SB_VERSION_SECTORBIT 0x0800
-#define XFS_SB_VERSION_EXTFLGBIT 0x1000
-#define XFS_SB_VERSION_DIRV2BIT 0x2000
-#define XFS_SB_VERSION_MOREBITSBIT 0x8000
-#define XFS_SB_VERSION_OKSASHFBITS \
- (XFS_SB_VERSION_EXTFLGBIT | \
- XFS_SB_VERSION_DIRV2BIT)
-#define XFS_SB_VERSION_OKREALFBITS \
- (XFS_SB_VERSION_ATTRBIT | \
- XFS_SB_VERSION_NLINKBIT | \
- XFS_SB_VERSION_QUOTABIT | \
- XFS_SB_VERSION_ALIGNBIT | \
- XFS_SB_VERSION_DALIGNBIT | \
- XFS_SB_VERSION_SHAREDBIT | \
- XFS_SB_VERSION_LOGV2BIT | \
- XFS_SB_VERSION_SECTORBIT | \
- XFS_SB_VERSION_MOREBITSBIT)
-#define XFS_SB_VERSION_OKSASHBITS \
- (XFS_SB_VERSION_NUMBITS | \
- XFS_SB_VERSION_REALFBITS | \
- XFS_SB_VERSION_OKSASHFBITS)
-#define XFS_SB_VERSION_OKREALBITS \
- (XFS_SB_VERSION_NUMBITS | \
- XFS_SB_VERSION_OKREALFBITS | \
- XFS_SB_VERSION_OKSASHFBITS)
-
-/*
- * There are two words to hold XFS "feature" bits: the original
- * word, sb_versionnum, and sb_features2. Whenever a bit is set in
- * sb_features2, the feature bit XFS_SB_VERSION_MOREBITSBIT must be set.
- *
- * These defines represent bits in sb_features2.
- */
-#define XFS_SB_VERSION2_REALFBITS 0x00ffffff /* Mask: features */
-#define XFS_SB_VERSION2_RESERVED1BIT 0x00000001
-#define XFS_SB_VERSION2_RESERVED2BIT 0x00000002
-#define XFS_SB_VERSION2_RESERVED4BIT 0x00000004
-#define XFS_SB_VERSION2_ATTR2BIT 0x00000008 /* Inline attr rework */
-#define XFS_SB_VERSION2_SASHFBITS 0xff000000 /* Mask: features that
- require changing
- PROM and SASH */
-
-#define XFS_SB_VERSION2_OKREALFBITS \
- (XFS_SB_VERSION2_ATTR2BIT)
-#define XFS_SB_VERSION2_OKSASHFBITS \
- (0)
-#define XFS_SB_VERSION2_OKREALBITS \
- (XFS_SB_VERSION2_OKREALFBITS | \
- XFS_SB_VERSION2_OKSASHFBITS )
-
-typedef struct xfs_sb
-{
- __uint32_t sb_magicnum; /* magic number == XFS_SB_MAGIC */
- __uint32_t sb_blocksize; /* logical block size, bytes */
- xfs_drfsbno_t sb_dblocks; /* number of data blocks */
- xfs_drfsbno_t sb_rblocks; /* number of realtime blocks */
- xfs_drtbno_t sb_rextents; /* number of realtime extents */
- uuid_t sb_uuid; /* file system unique id */
- xfs_dfsbno_t sb_logstart; /* starting block of log if internal */
- xfs_ino_t sb_rootino; /* root inode number */
- xfs_ino_t sb_rbmino; /* bitmap inode for realtime extents */
- xfs_ino_t sb_rsumino; /* summary inode for rt bitmap */
- xfs_agblock_t sb_rextsize; /* realtime extent size, blocks */
- xfs_agblock_t sb_agblocks; /* size of an allocation group */
- xfs_agnumber_t sb_agcount; /* number of allocation groups */
- xfs_extlen_t sb_rbmblocks; /* number of rt bitmap blocks */
- xfs_extlen_t sb_logblocks; /* number of log blocks */
- __uint16_t sb_versionnum; /* header version == XFS_SB_VERSION */
- __uint16_t sb_sectsize; /* volume sector size, bytes */
- __uint16_t sb_inodesize; /* inode size, bytes */
- __uint16_t sb_inopblock; /* inodes per block */
- char sb_fname[12]; /* file system name */
- __uint8_t sb_blocklog; /* log2 of sb_blocksize */
- __uint8_t sb_sectlog; /* log2 of sb_sectsize */
- __uint8_t sb_inodelog; /* log2 of sb_inodesize */
- __uint8_t sb_inopblog; /* log2 of sb_inopblock */
- __uint8_t sb_agblklog; /* log2 of sb_agblocks (rounded up) */
- __uint8_t sb_rextslog; /* log2 of sb_rextents */
- __uint8_t sb_inprogress; /* mkfs is in progress, don't mount */
- __uint8_t sb_imax_pct; /* max % of fs for inode space */
- /* statistics */
- /*
- * These fields must remain contiguous. If you really
- * want to change their layout, make sure you fix the
- * code in xfs_trans_apply_sb_deltas().
- */
- __uint64_t sb_icount; /* allocated inodes */
- __uint64_t sb_ifree; /* free inodes */
- __uint64_t sb_fdblocks; /* free data blocks */
- __uint64_t sb_frextents; /* free realtime extents */
- /*
- * End contiguous fields.
- */
- xfs_ino_t sb_uquotino; /* user quota inode */
- xfs_ino_t sb_gquotino; /* group quota inode */
- __uint16_t sb_qflags; /* quota flags */
- __uint8_t sb_flags; /* misc. flags */
- __uint8_t sb_shared_vn; /* shared version number */
- xfs_extlen_t sb_inoalignmt; /* inode chunk alignment, fsblocks */
- __uint32_t sb_unit; /* stripe or raid unit */
- __uint32_t sb_width; /* stripe or raid width */
- __uint8_t sb_dirblklog; /* log2 of dir block size (fsbs) */
- __uint8_t sb_logsectlog; /* log2 of the log sector size */
- __uint16_t sb_logsectsize; /* sector size for the log, bytes */
- __uint32_t sb_logsunit; /* stripe unit size for the log */
- __uint32_t sb_features2; /* additional feature bits */
-} xfs_sb_t;
-
-/*
- * Sequence number values for the fields.
- */
-typedef enum {
- XFS_SBS_MAGICNUM, XFS_SBS_BLOCKSIZE, XFS_SBS_DBLOCKS, XFS_SBS_RBLOCKS,
- XFS_SBS_REXTENTS, XFS_SBS_UUID, XFS_SBS_LOGSTART, XFS_SBS_ROOTINO,
- XFS_SBS_RBMINO, XFS_SBS_RSUMINO, XFS_SBS_REXTSIZE, XFS_SBS_AGBLOCKS,
- XFS_SBS_AGCOUNT, XFS_SBS_RBMBLOCKS, XFS_SBS_LOGBLOCKS,
- XFS_SBS_VERSIONNUM, XFS_SBS_SECTSIZE, XFS_SBS_INODESIZE,
- XFS_SBS_INOPBLOCK, XFS_SBS_FNAME, XFS_SBS_BLOCKLOG,
- XFS_SBS_SECTLOG, XFS_SBS_INODELOG, XFS_SBS_INOPBLOG, XFS_SBS_AGBLKLOG,
- XFS_SBS_REXTSLOG, XFS_SBS_INPROGRESS, XFS_SBS_IMAX_PCT, XFS_SBS_ICOUNT,
- XFS_SBS_IFREE, XFS_SBS_FDBLOCKS, XFS_SBS_FREXTENTS, XFS_SBS_UQUOTINO,
- XFS_SBS_GQUOTINO, XFS_SBS_QFLAGS, XFS_SBS_FLAGS, XFS_SBS_SHARED_VN,
- XFS_SBS_INOALIGNMT, XFS_SBS_UNIT, XFS_SBS_WIDTH, XFS_SBS_DIRBLKLOG,
- XFS_SBS_LOGSECTLOG, XFS_SBS_LOGSECTSIZE, XFS_SBS_LOGSUNIT,
- XFS_SBS_FEATURES2,
- XFS_SBS_FIELDCOUNT
-} xfs_sb_field_t;
-
-/*
- * Mask values, defined based on the xfs_sb_field_t values.
- * Only define the ones we're using.
- */
-#define XFS_SB_MVAL(x) (1LL << XFS_SBS_ ## x)
-#define XFS_SB_UUID XFS_SB_MVAL(UUID)
-#define XFS_SB_FNAME XFS_SB_MVAL(FNAME)
-#define XFS_SB_ROOTINO XFS_SB_MVAL(ROOTINO)
-#define XFS_SB_RBMINO XFS_SB_MVAL(RBMINO)
-#define XFS_SB_RSUMINO XFS_SB_MVAL(RSUMINO)
-#define XFS_SB_VERSIONNUM XFS_SB_MVAL(VERSIONNUM)
-#define XFS_SB_UQUOTINO XFS_SB_MVAL(UQUOTINO)
-#define XFS_SB_GQUOTINO XFS_SB_MVAL(GQUOTINO)
-#define XFS_SB_QFLAGS XFS_SB_MVAL(QFLAGS)
-#define XFS_SB_SHARED_VN XFS_SB_MVAL(SHARED_VN)
-#define XFS_SB_UNIT XFS_SB_MVAL(UNIT)
-#define XFS_SB_WIDTH XFS_SB_MVAL(WIDTH)
-#define XFS_SB_FEATURES2 XFS_SB_MVAL(FEATURES2)
-#define XFS_SB_NUM_BITS ((int)XFS_SBS_FIELDCOUNT)
-#define XFS_SB_ALL_BITS ((1LL << XFS_SB_NUM_BITS) - 1)
-#define XFS_SB_MOD_BITS \
- (XFS_SB_UUID | XFS_SB_ROOTINO | XFS_SB_RBMINO | XFS_SB_RSUMINO | \
- XFS_SB_VERSIONNUM | XFS_SB_UQUOTINO | XFS_SB_GQUOTINO | \
- XFS_SB_QFLAGS | XFS_SB_SHARED_VN | XFS_SB_UNIT | XFS_SB_WIDTH | \
- XFS_SB_FEATURES2)
-
-
-/*
- * Misc. Flags - warning - these will be cleared by xfs_repair unless
- * a feature bit is set when the flag is used.
- */
-#define XFS_SBF_NOFLAGS 0x00 /* no flags set */
-#define XFS_SBF_READONLY 0x01 /* only read-only mounts allowed */
-
-/*
- * define max. shared version we can interoperate with
- */
-#define XFS_SB_MAX_SHARED_VN 0
-
-#define XFS_SB_VERSION_NUM(sbp) ((sbp)->sb_versionnum & XFS_SB_VERSION_NUMBITS)
-
-#define XFS_SB_GOOD_VERSION(sbp) xfs_sb_good_version(sbp)
-#ifdef __KERNEL__
-static inline int xfs_sb_good_version(xfs_sb_t *sbp)
-{
- return (((sbp->sb_versionnum >= XFS_SB_VERSION_1) && \
- (sbp->sb_versionnum <= XFS_SB_VERSION_3)) || \
- ((XFS_SB_VERSION_NUM(sbp) == XFS_SB_VERSION_4) && \
- !((sbp->sb_versionnum & ~XFS_SB_VERSION_OKREALBITS) || \
- ((sbp->sb_versionnum & XFS_SB_VERSION_MOREBITSBIT) && \
- (sbp->sb_features2 & ~XFS_SB_VERSION2_OKREALBITS))) && \
- (sbp->sb_shared_vn <= XFS_SB_MAX_SHARED_VN)));
-}
-#else
-static inline int xfs_sb_good_version(xfs_sb_t *sbp)
-{
- return (((sbp->sb_versionnum >= XFS_SB_VERSION_1) && \
- (sbp->sb_versionnum <= XFS_SB_VERSION_3)) || \
- ((XFS_SB_VERSION_NUM(sbp) == XFS_SB_VERSION_4) && \
- !((sbp->sb_versionnum & ~XFS_SB_VERSION_OKREALBITS) || \
- ((sbp->sb_versionnum & XFS_SB_VERSION_MOREBITSBIT) && \
- (sbp->sb_features2 & ~XFS_SB_VERSION2_OKREALBITS))) && \
- (!(sbp->sb_versionnum & XFS_SB_VERSION_SHAREDBIT) || \
- (sbp->sb_shared_vn <= XFS_SB_MAX_SHARED_VN))));
-}
-#endif /* __KERNEL__ */
-
-#define XFS_SB_GOOD_SASH_VERSION(sbp) \
- ((((sbp)->sb_versionnum >= XFS_SB_VERSION_1) && \
- ((sbp)->sb_versionnum <= XFS_SB_VERSION_3)) || \
- ((XFS_SB_VERSION_NUM(sbp) == XFS_SB_VERSION_4) && \
- !((sbp)->sb_versionnum & ~XFS_SB_VERSION_OKSASHBITS)))
-
-#define XFS_SB_VERSION_TONEW(v) xfs_sb_version_tonew(v)
-static inline unsigned xfs_sb_version_tonew(unsigned v)
-{
- return ((((v) == XFS_SB_VERSION_1) ? \
- 0 : \
- (((v) == XFS_SB_VERSION_2) ? \
- XFS_SB_VERSION_ATTRBIT : \
- (XFS_SB_VERSION_ATTRBIT | XFS_SB_VERSION_NLINKBIT))) | \
- XFS_SB_VERSION_4);
-}
-
-#define XFS_SB_VERSION_TOOLD(v) xfs_sb_version_toold(v)
-static inline unsigned xfs_sb_version_toold(unsigned v)
-{
- return (((v) & (XFS_SB_VERSION_QUOTABIT | XFS_SB_VERSION_ALIGNBIT)) ? \
- 0 : \
- (((v) & XFS_SB_VERSION_NLINKBIT) ? \
- XFS_SB_VERSION_3 : \
- (((v) & XFS_SB_VERSION_ATTRBIT) ? \
- XFS_SB_VERSION_2 : \
- XFS_SB_VERSION_1)));
-}
-
-#define XFS_SB_VERSION_HASATTR(sbp) xfs_sb_version_hasattr(sbp)
-static inline int xfs_sb_version_hasattr(xfs_sb_t *sbp)
-{
- return ((sbp)->sb_versionnum == XFS_SB_VERSION_2) || \
- ((sbp)->sb_versionnum == XFS_SB_VERSION_3) || \
- ((XFS_SB_VERSION_NUM(sbp) == XFS_SB_VERSION_4) && \
- ((sbp)->sb_versionnum & XFS_SB_VERSION_ATTRBIT));
-}
-
-#define XFS_SB_VERSION_ADDATTR(sbp) xfs_sb_version_addattr(sbp)
-static inline void xfs_sb_version_addattr(xfs_sb_t *sbp)
-{
- (sbp)->sb_versionnum = (((sbp)->sb_versionnum == XFS_SB_VERSION_1) ? \
- XFS_SB_VERSION_2 : \
- ((XFS_SB_VERSION_NUM(sbp) == XFS_SB_VERSION_4) ? \
- ((sbp)->sb_versionnum | XFS_SB_VERSION_ATTRBIT) : \
- (XFS_SB_VERSION_4 | XFS_SB_VERSION_ATTRBIT)));
-}
-
-#define XFS_SB_VERSION_HASNLINK(sbp) xfs_sb_version_hasnlink(sbp)
-static inline int xfs_sb_version_hasnlink(xfs_sb_t *sbp)
-{
- return ((sbp)->sb_versionnum == XFS_SB_VERSION_3) || \
- ((XFS_SB_VERSION_NUM(sbp) == XFS_SB_VERSION_4) && \
- ((sbp)->sb_versionnum & XFS_SB_VERSION_NLINKBIT));
-}
-
-#define XFS_SB_VERSION_ADDNLINK(sbp) xfs_sb_version_addnlink(sbp)
-static inline void xfs_sb_version_addnlink(xfs_sb_t *sbp)
-{
- (sbp)->sb_versionnum = ((sbp)->sb_versionnum <= XFS_SB_VERSION_2 ? \
- XFS_SB_VERSION_3 : \
- ((sbp)->sb_versionnum | XFS_SB_VERSION_NLINKBIT));
-}
-
-#define XFS_SB_VERSION_HASQUOTA(sbp) xfs_sb_version_hasquota(sbp)
-static inline int xfs_sb_version_hasquota(xfs_sb_t *sbp)
-{
- return (XFS_SB_VERSION_NUM(sbp) == XFS_SB_VERSION_4) && \
- ((sbp)->sb_versionnum & XFS_SB_VERSION_QUOTABIT);
-}
-
-#define XFS_SB_VERSION_ADDQUOTA(sbp) xfs_sb_version_addquota(sbp)
-static inline void xfs_sb_version_addquota(xfs_sb_t *sbp)
-{
- (sbp)->sb_versionnum = \
- (XFS_SB_VERSION_NUM(sbp) == XFS_SB_VERSION_4 ? \
- ((sbp)->sb_versionnum | XFS_SB_VERSION_QUOTABIT) : \
- (XFS_SB_VERSION_TONEW((sbp)->sb_versionnum) | \
- XFS_SB_VERSION_QUOTABIT));
-}
-
-#define XFS_SB_VERSION_HASALIGN(sbp) xfs_sb_version_hasalign(sbp)
-static inline int xfs_sb_version_hasalign(xfs_sb_t *sbp)
-{
- return (XFS_SB_VERSION_NUM(sbp) == XFS_SB_VERSION_4) && \
- ((sbp)->sb_versionnum & XFS_SB_VERSION_ALIGNBIT);
-}
-
-#define XFS_SB_VERSION_SUBALIGN(sbp) xfs_sb_version_subalign(sbp)
-static inline void xfs_sb_version_subalign(xfs_sb_t *sbp)
-{
- (sbp)->sb_versionnum = \
- XFS_SB_VERSION_TOOLD((sbp)->sb_versionnum & ~XFS_SB_VERSION_ALIGNBIT);
-}
-
-#define XFS_SB_VERSION_HASDALIGN(sbp) xfs_sb_version_hasdalign(sbp)
-static inline int xfs_sb_version_hasdalign(xfs_sb_t *sbp)
-{
- return (XFS_SB_VERSION_NUM(sbp) == XFS_SB_VERSION_4) && \
- ((sbp)->sb_versionnum & XFS_SB_VERSION_DALIGNBIT);
-}
-
-#define XFS_SB_VERSION_ADDDALIGN(sbp) xfs_sb_version_adddalign(sbp)
-static inline int xfs_sb_version_adddalign(xfs_sb_t *sbp)
-{
- return (sbp)->sb_versionnum = \
- ((sbp)->sb_versionnum | XFS_SB_VERSION_DALIGNBIT);
-}
-
-#define XFS_SB_VERSION_HASSHARED(sbp) xfs_sb_version_hasshared(sbp)
-static inline int xfs_sb_version_hasshared(xfs_sb_t *sbp)
-{
- return (XFS_SB_VERSION_NUM(sbp) == XFS_SB_VERSION_4) && \
- ((sbp)->sb_versionnum & XFS_SB_VERSION_SHAREDBIT);
-}
-
-#define XFS_SB_VERSION_ADDSHARED(sbp) xfs_sb_version_addshared(sbp)
-static inline int xfs_sb_version_addshared(xfs_sb_t *sbp)
-{
- return (sbp)->sb_versionnum = \
- ((sbp)->sb_versionnum | XFS_SB_VERSION_SHAREDBIT);
-}
-
-#define XFS_SB_VERSION_SUBSHARED(sbp) xfs_sb_version_subshared(sbp)
-static inline int xfs_sb_version_subshared(xfs_sb_t *sbp)
-{
- return (sbp)->sb_versionnum = \
- ((sbp)->sb_versionnum & ~XFS_SB_VERSION_SHAREDBIT);
-}
-
-#define XFS_SB_VERSION_HASDIRV2(sbp) xfs_sb_version_hasdirv2(sbp)
-static inline int xfs_sb_version_hasdirv2(xfs_sb_t *sbp)
-{
- return (XFS_SB_VERSION_NUM(sbp) == XFS_SB_VERSION_4) && \
- ((sbp)->sb_versionnum & XFS_SB_VERSION_DIRV2BIT);
-}
-
-#define XFS_SB_VERSION_HASLOGV2(sbp) xfs_sb_version_haslogv2(sbp)
-static inline int xfs_sb_version_haslogv2(xfs_sb_t *sbp)
-{
- return (XFS_SB_VERSION_NUM(sbp) == XFS_SB_VERSION_4) && \
- ((sbp)->sb_versionnum & XFS_SB_VERSION_LOGV2BIT);
-}
-
-#define XFS_SB_VERSION_HASEXTFLGBIT(sbp) xfs_sb_version_hasextflgbit(sbp)
-static inline int xfs_sb_version_hasextflgbit(xfs_sb_t *sbp)
-{
- return (XFS_SB_VERSION_NUM(sbp) == XFS_SB_VERSION_4) && \
- ((sbp)->sb_versionnum & XFS_SB_VERSION_EXTFLGBIT);
-}
-
-#define XFS_SB_VERSION_ADDEXTFLGBIT(sbp) xfs_sb_version_addextflgbit(sbp)
-static inline int xfs_sb_version_addextflgbit(xfs_sb_t *sbp)
-{
- return (sbp)->sb_versionnum = \
- ((sbp)->sb_versionnum | XFS_SB_VERSION_EXTFLGBIT);
-}
-
-#define XFS_SB_VERSION_SUBEXTFLGBIT(sbp) xfs_sb_version_subextflgbit(sbp)
-static inline int xfs_sb_version_subextflgbit(xfs_sb_t *sbp)
-{
- return (sbp)->sb_versionnum = \
- ((sbp)->sb_versionnum & ~XFS_SB_VERSION_EXTFLGBIT);
-}
-
-#define XFS_SB_VERSION_HASSECTOR(sbp) xfs_sb_version_hassector(sbp)
-static inline int xfs_sb_version_hassector(xfs_sb_t *sbp)
-{
- return (XFS_SB_VERSION_NUM(sbp) == XFS_SB_VERSION_4) && \
- ((sbp)->sb_versionnum & XFS_SB_VERSION_SECTORBIT);
-}
-
-#define XFS_SB_VERSION_HASMOREBITS(sbp) xfs_sb_version_hasmorebits(sbp)
-static inline int xfs_sb_version_hasmorebits(xfs_sb_t *sbp)
-{
- return (XFS_SB_VERSION_NUM(sbp) == XFS_SB_VERSION_4) && \
- ((sbp)->sb_versionnum & XFS_SB_VERSION_MOREBITSBIT);
-}
-
-/*
- * sb_features2 bit version macros.
- *
- * For example, for a bit defined as XFS_SB_VERSION2_FUNBIT, has a macro:
- *
- * SB_VERSION_HASFUNBIT(xfs_sb_t *sbp)
- * ((XFS_SB_VERSION_HASMOREBITS(sbp) &&
- * ((sbp)->sb_features2 & XFS_SB_VERSION2_FUNBIT)
- */
-
-#define XFS_SB_VERSION_HASATTR2(sbp) xfs_sb_version_hasattr2(sbp)
-static inline int xfs_sb_version_hasattr2(xfs_sb_t *sbp)
-{
- return (XFS_SB_VERSION_HASMOREBITS(sbp)) && \
- ((sbp)->sb_features2 & XFS_SB_VERSION2_ATTR2BIT);
-}
-
-#define XFS_SB_VERSION_ADDATTR2(sbp) xfs_sb_version_addattr2(sbp)
-static inline void xfs_sb_version_addattr2(xfs_sb_t *sbp)
-{
- ((sbp)->sb_versionnum = \
- ((sbp)->sb_versionnum | XFS_SB_VERSION_MOREBITSBIT), \
- ((sbp)->sb_features2 = \
- ((sbp)->sb_features2 | XFS_SB_VERSION2_ATTR2BIT)));
-}
-
-/*
- * end of superblock version macros
- */
-
-#define XFS_SB_DADDR ((xfs_daddr_t)0) /* daddr in filesystem/ag */
-#define XFS_SB_BLOCK(mp) XFS_HDR_BLOCK(mp, XFS_SB_DADDR)
-#define XFS_BUF_TO_SBP(bp) ((xfs_sb_t *)XFS_BUF_PTR(bp))
-
-#define XFS_HDR_BLOCK(mp,d) ((xfs_agblock_t)XFS_BB_TO_FSBT(mp,d))
-#define XFS_DADDR_TO_FSB(mp,d) XFS_AGB_TO_FSB(mp, \
- XFS_DADDR_TO_AGNO(mp,d), XFS_DADDR_TO_AGBNO(mp,d))
-#define XFS_FSB_TO_DADDR(mp,fsbno) XFS_AGB_TO_DADDR(mp, \
- XFS_FSB_TO_AGNO(mp,fsbno), XFS_FSB_TO_AGBNO(mp,fsbno))
-
-/*
- * File system sector to basic block conversions.
- */
-#define XFS_FSS_TO_BB(mp,sec) ((sec) << (mp)->m_sectbb_log)
-#define XFS_BB_TO_FSS(mp,bb) \
- (((bb) + (XFS_FSS_TO_BB(mp,1) - 1)) >> (mp)->m_sectbb_log)
-#define XFS_BB_TO_FSST(mp,bb) ((bb) >> (mp)->m_sectbb_log)
-
-/*
- * File system sector to byte conversions.
- */
-#define XFS_FSS_TO_B(mp,sectno) ((xfs_fsize_t)(sectno) << (mp)->m_sb.sb_sectlog)
-#define XFS_B_TO_FSST(mp,b) (((__uint64_t)(b)) >> (mp)->m_sb.sb_sectlog)
-
-/*
- * File system block to basic block conversions.
- */
-#define XFS_FSB_TO_BB(mp,fsbno) ((fsbno) << (mp)->m_blkbb_log)
-#define XFS_BB_TO_FSB(mp,bb) \
- (((bb) + (XFS_FSB_TO_BB(mp,1) - 1)) >> (mp)->m_blkbb_log)
-#define XFS_BB_TO_FSBT(mp,bb) ((bb) >> (mp)->m_blkbb_log)
-#define XFS_BB_FSB_OFFSET(mp,bb) ((bb) & ((mp)->m_bsize - 1))
-
-/*
- * File system block to byte conversions.
- */
-#define XFS_FSB_TO_B(mp,fsbno) ((xfs_fsize_t)(fsbno) << (mp)->m_sb.sb_blocklog)
-#define XFS_B_TO_FSB(mp,b) \
- ((((__uint64_t)(b)) + (mp)->m_blockmask) >> (mp)->m_sb.sb_blocklog)
-#define XFS_B_TO_FSBT(mp,b) (((__uint64_t)(b)) >> (mp)->m_sb.sb_blocklog)
-#define XFS_B_FSB_OFFSET(mp,b) ((b) & (mp)->m_blockmask)
-
-#endif /* __XFS_SB_H__ */
diff --git a/sys/gnu/fs/xfs/xfs_trans.c b/sys/gnu/fs/xfs/xfs_trans.c
deleted file mode 100644
index 75cbade..0000000
--- a/sys/gnu/fs/xfs/xfs_trans.c
+++ /dev/null
@@ -1,1382 +0,0 @@
-/*
- * Copyright (c) 2000-2003,2005 Silicon Graphics, Inc.
- * All Rights Reserved.
- *
- * 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.
- *
- * This program is distributed in the hope that it would 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 the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- */
-#include "xfs.h"
-#include "xfs_fs.h"
-#include "xfs_types.h"
-#include "xfs_bit.h"
-#include "xfs_log.h"
-#include "xfs_inum.h"
-#include "xfs_trans.h"
-#include "xfs_sb.h"
-#include "xfs_ag.h"
-#include "xfs_dir.h"
-#include "xfs_dir2.h"
-#include "xfs_dmapi.h"
-#include "xfs_mount.h"
-#include "xfs_error.h"
-#include "xfs_da_btree.h"
-#include "xfs_bmap_btree.h"
-#include "xfs_alloc_btree.h"
-#include "xfs_ialloc_btree.h"
-#include "xfs_dir_sf.h"
-#include "xfs_dir2_sf.h"
-#include "xfs_attr_sf.h"
-#include "xfs_dinode.h"
-#include "xfs_inode.h"
-#include "xfs_btree.h"
-#include "xfs_ialloc.h"
-#include "xfs_alloc.h"
-#include "xfs_bmap.h"
-#include "xfs_quota.h"
-#include "xfs_trans_priv.h"
-#include "xfs_trans_space.h"
-
-
-STATIC void xfs_trans_apply_sb_deltas(xfs_trans_t *);
-STATIC uint xfs_trans_count_vecs(xfs_trans_t *);
-STATIC void xfs_trans_fill_vecs(xfs_trans_t *, xfs_log_iovec_t *);
-STATIC void xfs_trans_uncommit(xfs_trans_t *, uint);
-STATIC void xfs_trans_committed(xfs_trans_t *, int);
-STATIC void xfs_trans_chunk_committed(xfs_log_item_chunk_t *, xfs_lsn_t, int);
-STATIC void xfs_trans_free(xfs_trans_t *);
-
-kmem_zone_t *xfs_trans_zone;
-
-
-/*
- * Reservation functions here avoid a huge stack in xfs_trans_init
- * due to register overflow from temporaries in the calculations.
- */
-
-STATIC uint
-xfs_calc_write_reservation(xfs_mount_t *mp)
-{
- return XFS_CALC_WRITE_LOG_RES(mp) + XFS_DQUOT_LOGRES(mp);
-}
-
-STATIC uint
-xfs_calc_itruncate_reservation(xfs_mount_t *mp)
-{
- return XFS_CALC_ITRUNCATE_LOG_RES(mp) + XFS_DQUOT_LOGRES(mp);
-}
-
-STATIC uint
-xfs_calc_rename_reservation(xfs_mount_t *mp)
-{
- return XFS_CALC_RENAME_LOG_RES(mp) + XFS_DQUOT_LOGRES(mp);
-}
-
-STATIC uint
-xfs_calc_link_reservation(xfs_mount_t *mp)
-{
- return XFS_CALC_LINK_LOG_RES(mp) + XFS_DQUOT_LOGRES(mp);
-}
-
-STATIC uint
-xfs_calc_remove_reservation(xfs_mount_t *mp)
-{
- return XFS_CALC_REMOVE_LOG_RES(mp) + XFS_DQUOT_LOGRES(mp);
-}
-
-STATIC uint
-xfs_calc_symlink_reservation(xfs_mount_t *mp)
-{
- return XFS_CALC_SYMLINK_LOG_RES(mp) + XFS_DQUOT_LOGRES(mp);
-}
-
-STATIC uint
-xfs_calc_create_reservation(xfs_mount_t *mp)
-{
- return XFS_CALC_CREATE_LOG_RES(mp) + XFS_DQUOT_LOGRES(mp);
-}
-
-STATIC uint
-xfs_calc_mkdir_reservation(xfs_mount_t *mp)
-{
- return XFS_CALC_MKDIR_LOG_RES(mp) + XFS_DQUOT_LOGRES(mp);
-}
-
-STATIC uint
-xfs_calc_ifree_reservation(xfs_mount_t *mp)
-{
- return XFS_CALC_IFREE_LOG_RES(mp) + XFS_DQUOT_LOGRES(mp);
-}
-
-STATIC uint
-xfs_calc_ichange_reservation(xfs_mount_t *mp)
-{
- return XFS_CALC_ICHANGE_LOG_RES(mp) + XFS_DQUOT_LOGRES(mp);
-}
-
-STATIC uint
-xfs_calc_growdata_reservation(xfs_mount_t *mp)
-{
- return XFS_CALC_GROWDATA_LOG_RES(mp);
-}
-
-STATIC uint
-xfs_calc_growrtalloc_reservation(xfs_mount_t *mp)
-{
- return XFS_CALC_GROWRTALLOC_LOG_RES(mp);
-}
-
-STATIC uint
-xfs_calc_growrtzero_reservation(xfs_mount_t *mp)
-{
- return XFS_CALC_GROWRTZERO_LOG_RES(mp);
-}
-
-STATIC uint
-xfs_calc_growrtfree_reservation(xfs_mount_t *mp)
-{
- return XFS_CALC_GROWRTFREE_LOG_RES(mp);
-}
-
-STATIC uint
-xfs_calc_swrite_reservation(xfs_mount_t *mp)
-{
- return XFS_CALC_SWRITE_LOG_RES(mp);
-}
-
-STATIC uint
-xfs_calc_writeid_reservation(xfs_mount_t *mp)
-{
- return XFS_CALC_WRITEID_LOG_RES(mp);
-}
-
-STATIC uint
-xfs_calc_addafork_reservation(xfs_mount_t *mp)
-{
- return XFS_CALC_ADDAFORK_LOG_RES(mp) + XFS_DQUOT_LOGRES(mp);
-}
-
-STATIC uint
-xfs_calc_attrinval_reservation(xfs_mount_t *mp)
-{
- return XFS_CALC_ATTRINVAL_LOG_RES(mp);
-}
-
-STATIC uint
-xfs_calc_attrset_reservation(xfs_mount_t *mp)
-{
- return XFS_CALC_ATTRSET_LOG_RES(mp) + XFS_DQUOT_LOGRES(mp);
-}
-
-STATIC uint
-xfs_calc_attrrm_reservation(xfs_mount_t *mp)
-{
- return XFS_CALC_ATTRRM_LOG_RES(mp) + XFS_DQUOT_LOGRES(mp);
-}
-
-STATIC uint
-xfs_calc_clear_agi_bucket_reservation(xfs_mount_t *mp)
-{
- return XFS_CALC_CLEAR_AGI_BUCKET_LOG_RES(mp);
-}
-
-/*
- * Initialize the precomputed transaction reservation values
- * in the mount structure.
- */
-void
-xfs_trans_init(
- xfs_mount_t *mp)
-{
- xfs_trans_reservations_t *resp;
-
- resp = &(mp->m_reservations);
- resp->tr_write = xfs_calc_write_reservation(mp);
- resp->tr_itruncate = xfs_calc_itruncate_reservation(mp);
- resp->tr_rename = xfs_calc_rename_reservation(mp);
- resp->tr_link = xfs_calc_link_reservation(mp);
- resp->tr_remove = xfs_calc_remove_reservation(mp);
- resp->tr_symlink = xfs_calc_symlink_reservation(mp);
- resp->tr_create = xfs_calc_create_reservation(mp);
- resp->tr_mkdir = xfs_calc_mkdir_reservation(mp);
- resp->tr_ifree = xfs_calc_ifree_reservation(mp);
- resp->tr_ichange = xfs_calc_ichange_reservation(mp);
- resp->tr_growdata = xfs_calc_growdata_reservation(mp);
- resp->tr_swrite = xfs_calc_swrite_reservation(mp);
- resp->tr_writeid = xfs_calc_writeid_reservation(mp);
- resp->tr_addafork = xfs_calc_addafork_reservation(mp);
- resp->tr_attrinval = xfs_calc_attrinval_reservation(mp);
- resp->tr_attrset = xfs_calc_attrset_reservation(mp);
- resp->tr_attrrm = xfs_calc_attrrm_reservation(mp);
- resp->tr_clearagi = xfs_calc_clear_agi_bucket_reservation(mp);
- resp->tr_growrtalloc = xfs_calc_growrtalloc_reservation(mp);
- resp->tr_growrtzero = xfs_calc_growrtzero_reservation(mp);
- resp->tr_growrtfree = xfs_calc_growrtfree_reservation(mp);
-}
-
-/*
- * This routine is called to allocate a transaction structure.
- * The type parameter indicates the type of the transaction. These
- * are enumerated in xfs_trans.h.
- *
- * Dynamically allocate the transaction structure from the transaction
- * zone, initialize it, and return it to the caller.
- */
-xfs_trans_t *
-xfs_trans_alloc(
- xfs_mount_t *mp,
- uint type)
-{
-#ifdef RMC
- fs_check_frozen(XFS_MTOVFS(mp), SB_FREEZE_TRANS);
-#endif
- atomic_inc(&mp->m_active_trans);
-
- return (_xfs_trans_alloc(mp, type));
-
-}
-
-xfs_trans_t *
-_xfs_trans_alloc(
- xfs_mount_t *mp,
- uint type)
-{
- xfs_trans_t *tp;
-
- ASSERT(xfs_trans_zone != NULL);
- tp = kmem_zone_zalloc(xfs_trans_zone, KM_SLEEP);
-
- /*
- * Initialize the transaction structure.
- */
- tp->t_magic = XFS_TRANS_MAGIC;
- tp->t_type = type;
- tp->t_mountp = mp;
- tp->t_items_free = XFS_LIC_NUM_SLOTS;
- tp->t_busy_free = XFS_LBC_NUM_SLOTS;
- XFS_LIC_INIT(&(tp->t_items));
- XFS_LBC_INIT(&(tp->t_busy));
-
- return (tp);
-}
-
-/*
- * This is called to create a new transaction which will share the
- * permanent log reservation of the given transaction. The remaining
- * unused block and rt extent reservations are also inherited. This
- * implies that the original transaction is no longer allowed to allocate
- * blocks. Locks and log items, however, are no inherited. They must
- * be added to the new transaction explicitly.
- */
-xfs_trans_t *
-xfs_trans_dup(
- xfs_trans_t *tp)
-{
- xfs_trans_t *ntp;
-
- ntp = kmem_zone_zalloc(xfs_trans_zone, KM_SLEEP);
-
- /*
- * Initialize the new transaction structure.
- */
- ntp->t_magic = XFS_TRANS_MAGIC;
- ntp->t_type = tp->t_type;
- ntp->t_mountp = tp->t_mountp;
- ntp->t_items_free = XFS_LIC_NUM_SLOTS;
- ntp->t_busy_free = XFS_LBC_NUM_SLOTS;
- XFS_LIC_INIT(&(ntp->t_items));
- XFS_LBC_INIT(&(ntp->t_busy));
-
- ASSERT(tp->t_flags & XFS_TRANS_PERM_LOG_RES);
- ASSERT(tp->t_ticket != NULL);
-
- ntp->t_flags = XFS_TRANS_PERM_LOG_RES | (tp->t_flags & XFS_TRANS_RESERVE);
- ntp->t_ticket = tp->t_ticket;
- ntp->t_blk_res = tp->t_blk_res - tp->t_blk_res_used;
- tp->t_blk_res = tp->t_blk_res_used;
- ntp->t_rtx_res = tp->t_rtx_res - tp->t_rtx_res_used;
- tp->t_rtx_res = tp->t_rtx_res_used;
- PFLAGS_DUP(&tp->t_pflags, &ntp->t_pflags);
-
- XFS_TRANS_DUP_DQINFO(tp->t_mountp, tp, ntp);
-
- atomic_inc(&tp->t_mountp->m_active_trans);
- return ntp;
-}
-
-/*
- * This is called to reserve free disk blocks and log space for the
- * given transaction. This must be done before allocating any resources
- * within the transaction.
- *
- * This will return ENOSPC if there are not enough blocks available.
- * It will sleep waiting for available log space.
- * The only valid value for the flags parameter is XFS_RES_LOG_PERM, which
- * is used by long running transactions. If any one of the reservations
- * fails then they will all be backed out.
- *
- * This does not do quota reservations. That typically is done by the
- * caller afterwards.
- */
-int
-xfs_trans_reserve(
- xfs_trans_t *tp,
- uint blocks,
- uint logspace,
- uint rtextents,
- uint flags,
- uint logcount)
-{
- int log_flags;
- int error;
- int rsvd;
-
- error = 0;
- rsvd = (tp->t_flags & XFS_TRANS_RESERVE) != 0;
-
- /* Mark this thread as being in a transaction */
- PFLAGS_SET_FSTRANS(&tp->t_pflags);
-
-
- /*
- * Attempt to reserve the needed disk blocks by decrementing
- * the number needed from the number available. This will
- * fail if the count would go below zero.
- */
- if (blocks > 0) {
- error = xfs_mod_incore_sb(tp->t_mountp, XFS_SBS_FDBLOCKS,
- -blocks, rsvd);
- if (error != 0) {
- PFLAGS_RESTORE_FSTRANS(&tp->t_pflags);
- return (XFS_ERROR(ENOSPC));
- }
- tp->t_blk_res += blocks;
- }
-
- /*
- * Reserve the log space needed for this transaction.
- */
- if (logspace > 0) {
- ASSERT((tp->t_log_res == 0) || (tp->t_log_res == logspace));
- ASSERT((tp->t_log_count == 0) ||
- (tp->t_log_count == logcount));
- if (flags & XFS_TRANS_PERM_LOG_RES) {
- log_flags = XFS_LOG_PERM_RESERV;
- tp->t_flags |= XFS_TRANS_PERM_LOG_RES;
- } else {
- ASSERT(tp->t_ticket == NULL);
- ASSERT(!(tp->t_flags & XFS_TRANS_PERM_LOG_RES));
- log_flags = 0;
- }
-
- error = xfs_log_reserve(tp->t_mountp, logspace, logcount,
- &tp->t_ticket,
- XFS_TRANSACTION, log_flags, tp->t_type);
- if (error) {
- goto undo_blocks;
- }
- tp->t_log_res = logspace;
- tp->t_log_count = logcount;
- }
-
- /*
- * Attempt to reserve the needed realtime extents by decrementing
- * the number needed from the number available. This will
- * fail if the count would go below zero.
- */
- if (rtextents > 0) {
- error = xfs_mod_incore_sb(tp->t_mountp, XFS_SBS_FREXTENTS,
- -rtextents, rsvd);
- if (error) {
- error = XFS_ERROR(ENOSPC);
- goto undo_log;
- }
- tp->t_rtx_res += rtextents;
- }
-
- return 0;
-
- /*
- * Error cases jump to one of these labels to undo any
- * reservations which have already been performed.
- */
-undo_log:
- if (logspace > 0) {
- if (flags & XFS_TRANS_PERM_LOG_RES) {
- log_flags = XFS_LOG_REL_PERM_RESERV;
- } else {
- log_flags = 0;
- }
- xfs_log_done(tp->t_mountp, tp->t_ticket, NULL, log_flags);
- tp->t_ticket = NULL;
- tp->t_log_res = 0;
- tp->t_flags &= ~XFS_TRANS_PERM_LOG_RES;
- }
-
-undo_blocks:
- if (blocks > 0) {
- (void) xfs_mod_incore_sb(tp->t_mountp, XFS_SBS_FDBLOCKS,
- blocks, rsvd);
- tp->t_blk_res = 0;
- }
-
- PFLAGS_RESTORE_FSTRANS(&tp->t_pflags);
-
- return (error);
-}
-
-
-/*
- * Record the indicated change to the given field for application
- * to the file system's superblock when the transaction commits.
- * For now, just store the change in the transaction structure.
- *
- * Mark the transaction structure to indicate that the superblock
- * needs to be updated before committing.
- */
-void
-xfs_trans_mod_sb(
- xfs_trans_t *tp,
- uint field,
- long delta)
-{
-
- switch (field) {
- case XFS_TRANS_SB_ICOUNT:
- tp->t_icount_delta += delta;
- break;
- case XFS_TRANS_SB_IFREE:
- tp->t_ifree_delta += delta;
- break;
- case XFS_TRANS_SB_FDBLOCKS:
- /*
- * Track the number of blocks allocated in the
- * transaction. Make sure it does not exceed the
- * number reserved.
- */
- if (delta < 0) {
- tp->t_blk_res_used += (uint)-delta;
- ASSERT(tp->t_blk_res_used <= tp->t_blk_res);
- }
- tp->t_fdblocks_delta += delta;
- break;
- case XFS_TRANS_SB_RES_FDBLOCKS:
- /*
- * The allocation has already been applied to the
- * in-core superblock's counter. This should only
- * be applied to the on-disk superblock.
- */
- ASSERT(delta < 0);
- tp->t_res_fdblocks_delta += delta;
- break;
- case XFS_TRANS_SB_FREXTENTS:
- /*
- * Track the number of blocks allocated in the
- * transaction. Make sure it does not exceed the
- * number reserved.
- */
- if (delta < 0) {
- tp->t_rtx_res_used += (uint)-delta;
- ASSERT(tp->t_rtx_res_used <= tp->t_rtx_res);
- }
- tp->t_frextents_delta += delta;
- break;
- case XFS_TRANS_SB_RES_FREXTENTS:
- /*
- * The allocation has already been applied to the
- * in-core superblock's counter. This should only
- * be applied to the on-disk superblock.
- */
- ASSERT(delta < 0);
- tp->t_res_frextents_delta += delta;
- break;
- case XFS_TRANS_SB_DBLOCKS:
- ASSERT(delta > 0);
- tp->t_dblocks_delta += delta;
- break;
- case XFS_TRANS_SB_AGCOUNT:
- ASSERT(delta > 0);
- tp->t_agcount_delta += delta;
- break;
- case XFS_TRANS_SB_IMAXPCT:
- tp->t_imaxpct_delta += delta;
- break;
- case XFS_TRANS_SB_REXTSIZE:
- tp->t_rextsize_delta += delta;
- break;
- case XFS_TRANS_SB_RBMBLOCKS:
- tp->t_rbmblocks_delta += delta;
- break;
- case XFS_TRANS_SB_RBLOCKS:
- tp->t_rblocks_delta += delta;
- break;
- case XFS_TRANS_SB_REXTENTS:
- tp->t_rextents_delta += delta;
- break;
- case XFS_TRANS_SB_REXTSLOG:
- tp->t_rextslog_delta += delta;
- break;
- default:
- ASSERT(0);
- return;
- }
-
- tp->t_flags |= (XFS_TRANS_SB_DIRTY | XFS_TRANS_DIRTY);
-}
-
-/*
- * xfs_trans_apply_sb_deltas() is called from the commit code
- * to bring the superblock buffer into the current transaction
- * and modify it as requested by earlier calls to xfs_trans_mod_sb().
- *
- * For now we just look at each field allowed to change and change
- * it if necessary.
- */
-STATIC void
-xfs_trans_apply_sb_deltas(
- xfs_trans_t *tp)
-{
- xfs_sb_t *sbp;
- xfs_buf_t *bp;
- int whole = 0;
-
- bp = xfs_trans_getsb(tp, tp->t_mountp, 0);
- sbp = XFS_BUF_TO_SBP(bp);
-
- /*
- * Check that superblock mods match the mods made to AGF counters.
- */
- ASSERT((tp->t_fdblocks_delta + tp->t_res_fdblocks_delta) ==
- (tp->t_ag_freeblks_delta + tp->t_ag_flist_delta +
- tp->t_ag_btree_delta));
-
- if (tp->t_icount_delta != 0) {
- INT_MOD(sbp->sb_icount, ARCH_CONVERT, tp->t_icount_delta);
- }
- if (tp->t_ifree_delta != 0) {
- INT_MOD(sbp->sb_ifree, ARCH_CONVERT, tp->t_ifree_delta);
- }
-
- if (tp->t_fdblocks_delta != 0) {
- INT_MOD(sbp->sb_fdblocks, ARCH_CONVERT, tp->t_fdblocks_delta);
- }
- if (tp->t_res_fdblocks_delta != 0) {
- INT_MOD(sbp->sb_fdblocks, ARCH_CONVERT, tp->t_res_fdblocks_delta);
- }
-
- if (tp->t_frextents_delta != 0) {
- INT_MOD(sbp->sb_frextents, ARCH_CONVERT, tp->t_frextents_delta);
- }
- if (tp->t_res_frextents_delta != 0) {
- INT_MOD(sbp->sb_frextents, ARCH_CONVERT, tp->t_res_frextents_delta);
- }
- if (tp->t_dblocks_delta != 0) {
- INT_MOD(sbp->sb_dblocks, ARCH_CONVERT, tp->t_dblocks_delta);
- whole = 1;
- }
- if (tp->t_agcount_delta != 0) {
- INT_MOD(sbp->sb_agcount, ARCH_CONVERT, tp->t_agcount_delta);
- whole = 1;
- }
- if (tp->t_imaxpct_delta != 0) {
- INT_MOD(sbp->sb_imax_pct, ARCH_CONVERT, tp->t_imaxpct_delta);
- whole = 1;
- }
- if (tp->t_rextsize_delta != 0) {
- INT_MOD(sbp->sb_rextsize, ARCH_CONVERT, tp->t_rextsize_delta);
- whole = 1;
- }
- if (tp->t_rbmblocks_delta != 0) {
- INT_MOD(sbp->sb_rbmblocks, ARCH_CONVERT, tp->t_rbmblocks_delta);
- whole = 1;
- }
- if (tp->t_rblocks_delta != 0) {
- INT_MOD(sbp->sb_rblocks, ARCH_CONVERT, tp->t_rblocks_delta);
- whole = 1;
- }
- if (tp->t_rextents_delta != 0) {
- INT_MOD(sbp->sb_rextents, ARCH_CONVERT, tp->t_rextents_delta);
- whole = 1;
- }
- if (tp->t_rextslog_delta != 0) {
- INT_MOD(sbp->sb_rextslog, ARCH_CONVERT, tp->t_rextslog_delta);
- whole = 1;
- }
-
- if (whole)
- /*
- * Log the whole thing, the fields are noncontiguous.
- */
- xfs_trans_log_buf(tp, bp, 0, sizeof(xfs_sb_t) - 1);
- else
- /*
- * Since all the modifiable fields are contiguous, we
- * can get away with this.
- */
- xfs_trans_log_buf(tp, bp, offsetof(xfs_sb_t, sb_icount),
- offsetof(xfs_sb_t, sb_frextents) +
- sizeof(sbp->sb_frextents) - 1);
-
-#ifdef XXXKAN
- XFS_MTOVFS(tp->t_mountp)->vfs_super->s_dirt = 1;
-#endif
-}
-
-/*
- * xfs_trans_unreserve_and_mod_sb() is called to release unused
- * reservations and apply superblock counter changes to the in-core
- * superblock.
- *
- * This is done efficiently with a single call to xfs_mod_incore_sb_batch().
- */
-STATIC void
-xfs_trans_unreserve_and_mod_sb(
- xfs_trans_t *tp)
-{
- xfs_mod_sb_t msb[14]; /* If you add cases, add entries */
- xfs_mod_sb_t *msbp;
- /* REFERENCED */
- int error;
- int rsvd;
-
- msbp = msb;
- rsvd = (tp->t_flags & XFS_TRANS_RESERVE) != 0;
-
- /*
- * Release any reserved blocks. Any that were allocated
- * will be taken back again by fdblocks_delta below.
- */
- if (tp->t_blk_res > 0) {
- msbp->msb_field = XFS_SBS_FDBLOCKS;
- msbp->msb_delta = tp->t_blk_res;
- msbp++;
- }
-
- /*
- * Release any reserved real time extents . Any that were
- * allocated will be taken back again by frextents_delta below.
- */
- if (tp->t_rtx_res > 0) {
- msbp->msb_field = XFS_SBS_FREXTENTS;
- msbp->msb_delta = tp->t_rtx_res;
- msbp++;
- }
-
- /*
- * Apply any superblock modifications to the in-core version.
- * The t_res_fdblocks_delta and t_res_frextents_delta fields are
- * explicitly NOT applied to the in-core superblock.
- * The idea is that that has already been done.
- */
- if (tp->t_flags & XFS_TRANS_SB_DIRTY) {
- if (tp->t_icount_delta != 0) {
- msbp->msb_field = XFS_SBS_ICOUNT;
- msbp->msb_delta = (int)tp->t_icount_delta;
- msbp++;
- }
- if (tp->t_ifree_delta != 0) {
- msbp->msb_field = XFS_SBS_IFREE;
- msbp->msb_delta = (int)tp->t_ifree_delta;
- msbp++;
- }
- if (tp->t_fdblocks_delta != 0) {
- msbp->msb_field = XFS_SBS_FDBLOCKS;
- msbp->msb_delta = (int)tp->t_fdblocks_delta;
- msbp++;
- }
- if (tp->t_frextents_delta != 0) {
- msbp->msb_field = XFS_SBS_FREXTENTS;
- msbp->msb_delta = (int)tp->t_frextents_delta;
- msbp++;
- }
- if (tp->t_dblocks_delta != 0) {
- msbp->msb_field = XFS_SBS_DBLOCKS;
- msbp->msb_delta = (int)tp->t_dblocks_delta;
- msbp++;
- }
- if (tp->t_agcount_delta != 0) {
- msbp->msb_field = XFS_SBS_AGCOUNT;
- msbp->msb_delta = (int)tp->t_agcount_delta;
- msbp++;
- }
- if (tp->t_imaxpct_delta != 0) {
- msbp->msb_field = XFS_SBS_IMAX_PCT;
- msbp->msb_delta = (int)tp->t_imaxpct_delta;
- msbp++;
- }
- if (tp->t_rextsize_delta != 0) {
- msbp->msb_field = XFS_SBS_REXTSIZE;
- msbp->msb_delta = (int)tp->t_rextsize_delta;
- msbp++;
- }
- if (tp->t_rbmblocks_delta != 0) {
- msbp->msb_field = XFS_SBS_RBMBLOCKS;
- msbp->msb_delta = (int)tp->t_rbmblocks_delta;
- msbp++;
- }
- if (tp->t_rblocks_delta != 0) {
- msbp->msb_field = XFS_SBS_RBLOCKS;
- msbp->msb_delta = (int)tp->t_rblocks_delta;
- msbp++;
- }
- if (tp->t_rextents_delta != 0) {
- msbp->msb_field = XFS_SBS_REXTENTS;
- msbp->msb_delta = (int)tp->t_rextents_delta;
- msbp++;
- }
- if (tp->t_rextslog_delta != 0) {
- msbp->msb_field = XFS_SBS_REXTSLOG;
- msbp->msb_delta = (int)tp->t_rextslog_delta;
- msbp++;
- }
- }
-
- /*
- * If we need to change anything, do it.
- */
- if (msbp > msb) {
- error = xfs_mod_incore_sb_batch(tp->t_mountp, msb,
- (uint)(msbp - msb), rsvd);
- ASSERT(error == 0);
- }
-}
-
-
-/*
- * xfs_trans_commit
- *
- * Commit the given transaction to the log a/synchronously.
- *
- * XFS disk error handling mechanism is not based on a typical
- * transaction abort mechanism. Logically after the filesystem
- * gets marked 'SHUTDOWN', we can't let any new transactions
- * be durable - ie. committed to disk - because some metadata might
- * be inconsistent. In such cases, this returns an error, and the
- * caller may assume that all locked objects joined to the transaction
- * have already been unlocked as if the commit had succeeded.
- * Do not reference the transaction structure after this call.
- */
- /*ARGSUSED*/
-int
-_xfs_trans_commit(
- xfs_trans_t *tp,
- uint flags,
- xfs_lsn_t *commit_lsn_p,
- int *log_flushed)
-{
- xfs_log_iovec_t *log_vector;
- int nvec;
- xfs_mount_t *mp;
- xfs_lsn_t commit_lsn;
- /* REFERENCED */
- int error;
- int log_flags;
- int sync;
-#define XFS_TRANS_LOGVEC_COUNT 16
- xfs_log_iovec_t log_vector_fast[XFS_TRANS_LOGVEC_COUNT];
- void *commit_iclog;
- int shutdown;
-
- commit_lsn = -1;
-
- /*
- * Determine whether this commit is releasing a permanent
- * log reservation or not.
- */
- if (flags & XFS_TRANS_RELEASE_LOG_RES) {
- ASSERT(tp->t_flags & XFS_TRANS_PERM_LOG_RES);
- log_flags = XFS_LOG_REL_PERM_RESERV;
- } else {
- log_flags = 0;
- }
- mp = tp->t_mountp;
-
- /*
- * If there is nothing to be logged by the transaction,
- * then unlock all of the items associated with the
- * transaction and free the transaction structure.
- * Also make sure to return any reserved blocks to
- * the free pool.
- */
-shut_us_down:
- shutdown = XFS_FORCED_SHUTDOWN(mp) ? EIO : 0;
- if (!(tp->t_flags & XFS_TRANS_DIRTY) || shutdown) {
- xfs_trans_unreserve_and_mod_sb(tp);
- /*
- * It is indeed possible for the transaction to be
- * not dirty but the dqinfo portion to be. All that
- * means is that we have some (non-persistent) quota
- * reservations that need to be unreserved.
- */
- XFS_TRANS_UNRESERVE_AND_MOD_DQUOTS(mp, tp);
- if (tp->t_ticket) {
- commit_lsn = xfs_log_done(mp, tp->t_ticket,
- NULL, log_flags);
- if (commit_lsn == -1 && !shutdown)
- shutdown = XFS_ERROR(EIO);
- }
- PFLAGS_RESTORE_FSTRANS(&tp->t_pflags);
- xfs_trans_free_items(tp, shutdown? XFS_TRANS_ABORT : 0);
- xfs_trans_free_busy(tp);
- xfs_trans_free(tp);
- XFS_STATS_INC(xs_trans_empty);
- if (commit_lsn_p)
- *commit_lsn_p = commit_lsn;
- return (shutdown);
- }
- ASSERT(tp->t_ticket != NULL);
-
- /*
- * If we need to update the superblock, then do it now.
- */
- if (tp->t_flags & XFS_TRANS_SB_DIRTY) {
- xfs_trans_apply_sb_deltas(tp);
- }
- XFS_TRANS_APPLY_DQUOT_DELTAS(mp, tp);
-
- /*
- * Ask each log item how many log_vector entries it will
- * need so we can figure out how many to allocate.
- * Try to avoid the kmem_alloc() call in the common case
- * by using a vector from the stack when it fits.
- */
- nvec = xfs_trans_count_vecs(tp);
- if (nvec == 0) {
- xfs_force_shutdown(mp, XFS_LOG_IO_ERROR);
- goto shut_us_down;
- } else if (nvec <= XFS_TRANS_LOGVEC_COUNT) {
- log_vector = log_vector_fast;
- } else {
- log_vector = (xfs_log_iovec_t *)kmem_alloc(nvec *
- sizeof(xfs_log_iovec_t),
- KM_SLEEP);
- }
-
- /*
- * Fill in the log_vector and pin the logged items, and
- * then write the transaction to the log.
- */
- xfs_trans_fill_vecs(tp, log_vector);
-
- error = xfs_log_write(mp, log_vector, nvec, tp->t_ticket, &(tp->t_lsn));
-
- /*
- * The transaction is committed incore here, and can go out to disk
- * at any time after this call. However, all the items associated
- * with the transaction are still locked and pinned in memory.
- */
- commit_lsn = xfs_log_done(mp, tp->t_ticket, &commit_iclog, log_flags);
-
- tp->t_commit_lsn = commit_lsn;
- if (nvec > XFS_TRANS_LOGVEC_COUNT) {
- kmem_free(log_vector, nvec * sizeof(xfs_log_iovec_t));
- }
-
- if (commit_lsn_p)
- *commit_lsn_p = commit_lsn;
-
- /*
- * If we got a log write error. Unpin the logitems that we
- * had pinned, clean up, free trans structure, and return error.
- */
- if (error || commit_lsn == -1) {
- PFLAGS_RESTORE_FSTRANS(&tp->t_pflags);
- xfs_trans_uncommit(tp, flags|XFS_TRANS_ABORT);
- return XFS_ERROR(EIO);
- }
-
- /*
- * Once the transaction has committed, unused
- * reservations need to be released and changes to
- * the superblock need to be reflected in the in-core
- * version. Do that now.
- */
- xfs_trans_unreserve_and_mod_sb(tp);
-
- sync = tp->t_flags & XFS_TRANS_SYNC;
-
- /*
- * Tell the LM to call the transaction completion routine
- * when the log write with LSN commit_lsn completes (e.g.
- * when the transaction commit really hits the on-disk log).
- * After this call we cannot reference tp, because the call
- * can happen at any time and the call will free the transaction
- * structure pointed to by tp. The only case where we call
- * the completion routine (xfs_trans_committed) directly is
- * if the log is turned off on a debug kernel or we're
- * running in simulation mode (the log is explicitly turned
- * off).
- */
- tp->t_logcb.cb_func = (void(*)(void*, int))xfs_trans_committed;
- tp->t_logcb.cb_arg = tp;
-
- /*
- * We need to pass the iclog buffer which was used for the
- * transaction commit record into this function, and attach
- * the callback to it. The callback must be attached before
- * the items are unlocked to avoid racing with other threads
- * waiting for an item to unlock.
- */
- shutdown = xfs_log_notify(mp, commit_iclog, &(tp->t_logcb));
-
- /*
- * Mark this thread as no longer being in a transaction
- */
- PFLAGS_RESTORE_FSTRANS(&tp->t_pflags);
-
- /*
- * Once all the items of the transaction have been copied
- * to the in core log and the callback is attached, the
- * items can be unlocked.
- *
- * This will free descriptors pointing to items which were
- * not logged since there is nothing more to do with them.
- * For items which were logged, we will keep pointers to them
- * so they can be unpinned after the transaction commits to disk.
- * This will also stamp each modified meta-data item with
- * the commit lsn of this transaction for dependency tracking
- * purposes.
- */
- xfs_trans_unlock_items(tp, commit_lsn);
-
- /*
- * If we detected a log error earlier, finish committing
- * the transaction now (unpin log items, etc).
- *
- * Order is critical here, to avoid using the transaction
- * pointer after its been freed (by xfs_trans_committed
- * either here now, or as a callback). We cannot do this
- * step inside xfs_log_notify as was done earlier because
- * of this issue.
- */
- if (shutdown)
- xfs_trans_committed(tp, XFS_LI_ABORTED);
-
- /*
- * Now that the xfs_trans_committed callback has been attached,
- * and the items are released we can finally allow the iclog to
- * go to disk.
- */
- error = xfs_log_release_iclog(mp, commit_iclog);
-
- /*
- * If the transaction needs to be synchronous, then force the
- * log out now and wait for it.
- */
- if (sync) {
- if (!error) {
- error = _xfs_log_force(mp, commit_lsn,
- XFS_LOG_FORCE | XFS_LOG_SYNC,
- log_flushed);
- }
- XFS_STATS_INC(xs_trans_sync);
- } else {
- XFS_STATS_INC(xs_trans_async);
- }
-
- return (error);
-}
-
-
-/*
- * Total up the number of log iovecs needed to commit this
- * transaction. The transaction itself needs one for the
- * transaction header. Ask each dirty item in turn how many
- * it needs to get the total.
- */
-STATIC uint
-xfs_trans_count_vecs(
- xfs_trans_t *tp)
-{
- int nvecs;
- xfs_log_item_desc_t *lidp;
-
- nvecs = 1;
- lidp = xfs_trans_first_item(tp);
- ASSERT(lidp != NULL);
-
- /* In the non-debug case we need to start bailing out if we
- * didn't find a log_item here, return zero and let trans_commit
- * deal with it.
- */
- if (lidp == NULL)
- return 0;
-
- while (lidp != NULL) {
- /*
- * Skip items which aren't dirty in this transaction.
- */
- if (!(lidp->lid_flags & XFS_LID_DIRTY)) {
- lidp = xfs_trans_next_item(tp, lidp);
- continue;
- }
- lidp->lid_size = IOP_SIZE(lidp->lid_item);
- nvecs += lidp->lid_size;
- lidp = xfs_trans_next_item(tp, lidp);
- }
-
- return nvecs;
-}
-
-/*
- * Called from the trans_commit code when we notice that
- * the filesystem is in the middle of a forced shutdown.
- */
-STATIC void
-xfs_trans_uncommit(
- xfs_trans_t *tp,
- uint flags)
-{
- xfs_log_item_desc_t *lidp;
-
- for (lidp = xfs_trans_first_item(tp);
- lidp != NULL;
- lidp = xfs_trans_next_item(tp, lidp)) {
- /*
- * Unpin all but those that aren't dirty.
- */
- if (lidp->lid_flags & XFS_LID_DIRTY)
- IOP_UNPIN_REMOVE(lidp->lid_item, tp);
- }
-
- xfs_trans_unreserve_and_mod_sb(tp);
- XFS_TRANS_UNRESERVE_AND_MOD_DQUOTS(tp->t_mountp, tp);
-
- xfs_trans_free_items(tp, flags);
- xfs_trans_free_busy(tp);
- xfs_trans_free(tp);
-}
-
-/*
- * Fill in the vector with pointers to data to be logged
- * by this transaction. The transaction header takes
- * the first vector, and then each dirty item takes the
- * number of vectors it indicated it needed in xfs_trans_count_vecs().
- *
- * As each item fills in the entries it needs, also pin the item
- * so that it cannot be flushed out until the log write completes.
- */
-STATIC void
-xfs_trans_fill_vecs(
- xfs_trans_t *tp,
- xfs_log_iovec_t *log_vector)
-{
- xfs_log_item_desc_t *lidp;
- xfs_log_iovec_t *vecp;
- uint nitems;
-
- /*
- * Skip over the entry for the transaction header, we'll
- * fill that in at the end.
- */
- vecp = log_vector + 1; /* pointer arithmetic */
-
- nitems = 0;
- lidp = xfs_trans_first_item(tp);
- ASSERT(lidp != NULL);
- while (lidp != NULL) {
- /*
- * Skip items which aren't dirty in this transaction.
- */
- if (!(lidp->lid_flags & XFS_LID_DIRTY)) {
- lidp = xfs_trans_next_item(tp, lidp);
- continue;
- }
- /*
- * The item may be marked dirty but not log anything.
- * This can be used to get called when a transaction
- * is committed.
- */
- if (lidp->lid_size) {
- nitems++;
- }
- IOP_FORMAT(lidp->lid_item, vecp);
- vecp += lidp->lid_size; /* pointer arithmetic */
- IOP_PIN(lidp->lid_item);
- lidp = xfs_trans_next_item(tp, lidp);
- }
-
- /*
- * Now that we've counted the number of items in this
- * transaction, fill in the transaction header.
- */
- tp->t_header.th_magic = XFS_TRANS_HEADER_MAGIC;
- tp->t_header.th_type = tp->t_type;
- tp->t_header.th_num_items = nitems;
- log_vector->i_addr = (xfs_caddr_t)&tp->t_header;
- log_vector->i_len = sizeof(xfs_trans_header_t);
- XLOG_VEC_SET_TYPE(log_vector, XLOG_REG_TYPE_TRANSHDR);
-}
-
-
-/*
- * Unlock all of the transaction's items and free the transaction.
- * The transaction must not have modified any of its items, because
- * there is no way to restore them to their previous state.
- *
- * If the transaction has made a log reservation, make sure to release
- * it as well.
- */
-void
-xfs_trans_cancel(
- xfs_trans_t *tp,
- int flags)
-{
- int log_flags;
-#ifdef DEBUG
- xfs_log_item_chunk_t *licp;
- xfs_log_item_desc_t *lidp;
- xfs_log_item_t *lip;
- int i;
-#endif
- xfs_mount_t *mp = tp->t_mountp;
-
- /*
- * See if the caller is being too lazy to figure out if
- * the transaction really needs an abort.
- */
- if ((flags & XFS_TRANS_ABORT) && !(tp->t_flags & XFS_TRANS_DIRTY))
- flags &= ~XFS_TRANS_ABORT;
- /*
- * See if the caller is relying on us to shut down the
- * filesystem. This happens in paths where we detect
- * corruption and decide to give up.
- */
- if ((tp->t_flags & XFS_TRANS_DIRTY) && !XFS_FORCED_SHUTDOWN(mp)) {
- XFS_ERROR_REPORT("xfs_trans_cancel", XFS_ERRLEVEL_LOW, mp);
- xfs_force_shutdown(mp, XFS_CORRUPT_INCORE);
- }
-#ifdef DEBUG
- if (!(flags & XFS_TRANS_ABORT)) {
- licp = &(tp->t_items);
- while (licp != NULL) {
- lidp = licp->lic_descs;
- for (i = 0; i < licp->lic_unused; i++, lidp++) {
- if (XFS_LIC_ISFREE(licp, i)) {
- continue;
- }
-
- lip = lidp->lid_item;
- if (!XFS_FORCED_SHUTDOWN(mp))
- ASSERT(!(lip->li_type == XFS_LI_EFD));
- }
- licp = licp->lic_next;
- }
- }
-#endif
- xfs_trans_unreserve_and_mod_sb(tp);
- XFS_TRANS_UNRESERVE_AND_MOD_DQUOTS(mp, tp);
-
- if (tp->t_ticket) {
- if (flags & XFS_TRANS_RELEASE_LOG_RES) {
- ASSERT(tp->t_flags & XFS_TRANS_PERM_LOG_RES);
- log_flags = XFS_LOG_REL_PERM_RESERV;
- } else {
- log_flags = 0;
- }
- xfs_log_done(mp, tp->t_ticket, NULL, log_flags);
- }
-
- /* mark this thread as no longer being in a transaction */
- PFLAGS_RESTORE_FSTRANS(&tp->t_pflags);
-
- xfs_trans_free_items(tp, flags);
- xfs_trans_free_busy(tp);
- xfs_trans_free(tp);
-}
-
-
-/*
- * Free the transaction structure. If there is more clean up
- * to do when the structure is freed, add it here.
- */
-STATIC void
-xfs_trans_free(
- xfs_trans_t *tp)
-{
- atomic_dec(&tp->t_mountp->m_active_trans);
- XFS_TRANS_FREE_DQINFO(tp->t_mountp, tp);
- kmem_zone_free(xfs_trans_zone, tp);
-}
-
-
-/*
- * THIS SHOULD BE REWRITTEN TO USE xfs_trans_next_item().
- *
- * This is typically called by the LM when a transaction has been fully
- * committed to disk. It needs to unpin the items which have
- * been logged by the transaction and update their positions
- * in the AIL if necessary.
- * This also gets called when the transactions didn't get written out
- * because of an I/O error. Abortflag & XFS_LI_ABORTED is set then.
- *
- * Call xfs_trans_chunk_committed() to process the items in
- * each chunk.
- */
-STATIC void
-xfs_trans_committed(
- xfs_trans_t *tp,
- int abortflag)
-{
- xfs_log_item_chunk_t *licp;
- xfs_log_item_chunk_t *next_licp;
- xfs_log_busy_chunk_t *lbcp;
- xfs_log_busy_slot_t *lbsp;
- int i;
-
- /*
- * Call the transaction's completion callback if there
- * is one.
- */
- if (tp->t_callback != NULL) {
- tp->t_callback(tp, tp->t_callarg);
- }
-
- /*
- * Special case the chunk embedded in the transaction.
- */
- licp = &(tp->t_items);
- if (!(XFS_LIC_ARE_ALL_FREE(licp))) {
- xfs_trans_chunk_committed(licp, tp->t_lsn, abortflag);
- }
-
- /*
- * Process the items in each chunk in turn.
- */
- licp = licp->lic_next;
- while (licp != NULL) {
- ASSERT(!XFS_LIC_ARE_ALL_FREE(licp));
- xfs_trans_chunk_committed(licp, tp->t_lsn, abortflag);
- next_licp = licp->lic_next;
- kmem_free(licp, sizeof(xfs_log_item_chunk_t));
- licp = next_licp;
- }
-
- /*
- * Clear all the per-AG busy list items listed in this transaction
- */
- lbcp = &tp->t_busy;
- while (lbcp != NULL) {
- for (i = 0, lbsp = lbcp->lbc_busy; i < lbcp->lbc_unused; i++, lbsp++) {
- if (!XFS_LBC_ISFREE(lbcp, i)) {
- xfs_alloc_clear_busy(tp, lbsp->lbc_ag,
- lbsp->lbc_idx);
- }
- }
- lbcp = lbcp->lbc_next;
- }
- xfs_trans_free_busy(tp);
-
- /*
- * That's it for the transaction structure. Free it.
- */
- xfs_trans_free(tp);
-}
-
-/*
- * This is called to perform the commit processing for each
- * item described by the given chunk.
- *
- * The commit processing consists of unlocking items which were
- * held locked with the SYNC_UNLOCK attribute, calling the committed
- * routine of each logged item, updating the item's position in the AIL
- * if necessary, and unpinning each item. If the committed routine
- * returns -1, then do nothing further with the item because it
- * may have been freed.
- *
- * Since items are unlocked when they are copied to the incore
- * log, it is possible for two transactions to be completing
- * and manipulating the same item simultaneously. The AIL lock
- * will protect the lsn field of each item. The value of this
- * field can never go backwards.
- *
- * We unpin the items after repositioning them in the AIL, because
- * otherwise they could be immediately flushed and we'd have to race
- * with the flusher trying to pull the item from the AIL as we add it.
- */
-STATIC void
-xfs_trans_chunk_committed(
- xfs_log_item_chunk_t *licp,
- xfs_lsn_t lsn,
- int aborted)
-{
- xfs_log_item_desc_t *lidp;
- xfs_log_item_t *lip;
- xfs_lsn_t item_lsn;
- struct xfs_mount *mp;
- int i;
- SPLDECL(s);
-
- lidp = licp->lic_descs;
- for (i = 0; i < licp->lic_unused; i++, lidp++) {
- if (XFS_LIC_ISFREE(licp, i)) {
- continue;
- }
-
- lip = lidp->lid_item;
- if (aborted)
- lip->li_flags |= XFS_LI_ABORTED;
-
- /*
- * Send in the ABORTED flag to the COMMITTED routine
- * so that it knows whether the transaction was aborted
- * or not.
- */
- item_lsn = IOP_COMMITTED(lip, lsn);
-
- /*
- * If the committed routine returns -1, make
- * no more references to the item.
- */
- if (XFS_LSN_CMP(item_lsn, (xfs_lsn_t)-1) == 0) {
- continue;
- }
-
- /*
- * If the returned lsn is greater than what it
- * contained before, update the location of the
- * item in the AIL. If it is not, then do nothing.
- * Items can never move backwards in the AIL.
- *
- * While the new lsn should usually be greater, it
- * is possible that a later transaction completing
- * simultaneously with an earlier one using the
- * same item could complete first with a higher lsn.
- * This would cause the earlier transaction to fail
- * the test below.
- */
- mp = lip->li_mountp;
- AIL_LOCK(mp,s);
- if (XFS_LSN_CMP(item_lsn, lip->li_lsn) > 0) {
- /*
- * This will set the item's lsn to item_lsn
- * and update the position of the item in
- * the AIL.
- *
- * xfs_trans_update_ail() drops the AIL lock.
- */
- xfs_trans_update_ail(mp, lip, item_lsn, s);
- } else {
- AIL_UNLOCK(mp, s);
- }
-
- /*
- * Now that we've repositioned the item in the AIL,
- * unpin it so it can be flushed. Pass information
- * about buffer stale state down from the log item
- * flags, if anyone else stales the buffer we do not
- * want to pay any attention to it.
- */
- IOP_UNPIN(lip, lidp->lid_flags & XFS_LID_BUF_STALE);
- }
-}
-
diff --git a/sys/gnu/fs/xfs/xfs_trans.h b/sys/gnu/fs/xfs/xfs_trans.h
deleted file mode 100644
index 100d9a4..0000000
--- a/sys/gnu/fs/xfs/xfs_trans.h
+++ /dev/null
@@ -1,1016 +0,0 @@
-/*
- * Copyright (c) 2000-2002,2005 Silicon Graphics, Inc.
- * All Rights Reserved.
- *
- * 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.
- *
- * This program is distributed in the hope that it would 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 the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- */
-#ifndef __XFS_TRANS_H__
-#define __XFS_TRANS_H__
-
-/*
- * This is the structure written in the log at the head of
- * every transaction. It identifies the type and id of the
- * transaction, and contains the number of items logged by
- * the transaction so we know how many to expect during recovery.
- *
- * Do not change the below structure without redoing the code in
- * xlog_recover_add_to_trans() and xlog_recover_add_to_cont_trans().
- */
-typedef struct xfs_trans_header {
- uint th_magic; /* magic number */
- uint th_type; /* transaction type */
- __int32_t th_tid; /* transaction id (unused) */
- uint th_num_items; /* num items logged by trans */
-} xfs_trans_header_t;
-
-#define XFS_TRANS_HEADER_MAGIC 0x5452414e /* TRAN */
-
-/*
- * Log item types.
- */
-#define XFS_LI_5_3_BUF 0x1234 /* v1 bufs, 1-block inode buffers */
-#define XFS_LI_5_3_INODE 0x1235 /* 1-block inode buffers */
-#define XFS_LI_EFI 0x1236
-#define XFS_LI_EFD 0x1237
-#define XFS_LI_IUNLINK 0x1238
-#define XFS_LI_6_1_INODE 0x1239 /* 4K non-aligned inode bufs */
-#define XFS_LI_6_1_BUF 0x123a /* v1, 4K inode buffers */
-#define XFS_LI_INODE 0x123b /* aligned ino chunks, var-size ibufs */
-#define XFS_LI_BUF 0x123c /* v2 bufs, variable sized inode bufs */
-#define XFS_LI_DQUOT 0x123d
-#define XFS_LI_QUOTAOFF 0x123e
-
-/*
- * Transaction types. Used to distinguish types of buffers.
- */
-#define XFS_TRANS_SETATTR_NOT_SIZE 1
-#define XFS_TRANS_SETATTR_SIZE 2
-#define XFS_TRANS_INACTIVE 3
-#define XFS_TRANS_CREATE 4
-#define XFS_TRANS_CREATE_TRUNC 5
-#define XFS_TRANS_TRUNCATE_FILE 6
-#define XFS_TRANS_REMOVE 7
-#define XFS_TRANS_LINK 8
-#define XFS_TRANS_RENAME 9
-#define XFS_TRANS_MKDIR 10
-#define XFS_TRANS_RMDIR 11
-#define XFS_TRANS_SYMLINK 12
-#define XFS_TRANS_SET_DMATTRS 13
-#define XFS_TRANS_GROWFS 14
-#define XFS_TRANS_STRAT_WRITE 15
-#define XFS_TRANS_DIOSTRAT 16
-#define XFS_TRANS_WRITE_SYNC 17
-#define XFS_TRANS_WRITEID 18
-#define XFS_TRANS_ADDAFORK 19
-#define XFS_TRANS_ATTRINVAL 20
-#define XFS_TRANS_ATRUNCATE 21
-#define XFS_TRANS_ATTR_SET 22
-#define XFS_TRANS_ATTR_RM 23
-#define XFS_TRANS_ATTR_FLAG 24
-#define XFS_TRANS_CLEAR_AGI_BUCKET 25
-#define XFS_TRANS_QM_SBCHANGE 26
-/*
- * Dummy entries since we use the transaction type to index into the
- * trans_type[] in xlog_recover_print_trans_head()
- */
-#define XFS_TRANS_DUMMY1 27
-#define XFS_TRANS_DUMMY2 28
-#define XFS_TRANS_QM_QUOTAOFF 29
-#define XFS_TRANS_QM_DQALLOC 30
-#define XFS_TRANS_QM_SETQLIM 31
-#define XFS_TRANS_QM_DQCLUSTER 32
-#define XFS_TRANS_QM_QINOCREATE 33
-#define XFS_TRANS_QM_QUOTAOFF_END 34
-#define XFS_TRANS_SB_UNIT 35
-#define XFS_TRANS_FSYNC_TS 36
-#define XFS_TRANS_GROWFSRT_ALLOC 37
-#define XFS_TRANS_GROWFSRT_ZERO 38
-#define XFS_TRANS_GROWFSRT_FREE 39
-#define XFS_TRANS_SWAPEXT 40
-#define XFS_TRANS_TYPE_MAX 40
-/* new transaction types need to be reflected in xfs_logprint(8) */
-
-
-#ifdef __KERNEL__
-struct xfs_buf;
-struct xfs_buftarg;
-struct xfs_efd_log_item;
-struct xfs_efi_log_item;
-struct xfs_inode;
-struct xfs_item_ops;
-struct xfs_log_iovec;
-struct xfs_log_item;
-struct xfs_log_item_desc;
-struct xfs_mount;
-struct xfs_trans;
-struct xfs_dquot_acct;
-
-typedef struct xfs_ail_entry {
- struct xfs_log_item *ail_forw; /* AIL forw pointer */
- struct xfs_log_item *ail_back; /* AIL back pointer */
-} xfs_ail_entry_t;
-
-typedef struct xfs_log_item {
- xfs_ail_entry_t li_ail; /* AIL pointers */
- xfs_lsn_t li_lsn; /* last on-disk lsn */
- struct xfs_log_item_desc *li_desc; /* ptr to current desc*/
- struct xfs_mount *li_mountp; /* ptr to fs mount */
- uint li_type; /* item type */
- uint li_flags; /* misc flags */
- struct xfs_log_item *li_bio_list; /* buffer item list */
- void (*li_cb)(struct xfs_buf *,
- struct xfs_log_item *);
- /* buffer item iodone */
- /* callback func */
- struct xfs_item_ops *li_ops; /* function list */
-} xfs_log_item_t;
-
-#define XFS_LI_IN_AIL 0x1
-#define XFS_LI_ABORTED 0x2
-
-typedef struct xfs_item_ops {
- uint (*iop_size)(xfs_log_item_t *);
- void (*iop_format)(xfs_log_item_t *, struct xfs_log_iovec *);
- void (*iop_pin)(xfs_log_item_t *);
- void (*iop_unpin)(xfs_log_item_t *, int);
- void (*iop_unpin_remove)(xfs_log_item_t *, struct xfs_trans *);
- uint (*iop_trylock)(xfs_log_item_t *);
- void (*iop_unlock)(xfs_log_item_t *);
- xfs_lsn_t (*iop_committed)(xfs_log_item_t *, xfs_lsn_t);
- void (*iop_push)(xfs_log_item_t *);
- void (*iop_abort)(xfs_log_item_t *);
- void (*iop_pushbuf)(xfs_log_item_t *);
- void (*iop_committing)(xfs_log_item_t *, xfs_lsn_t);
-} xfs_item_ops_t;
-
-#define IOP_SIZE(ip) (*(ip)->li_ops->iop_size)(ip)
-#define IOP_FORMAT(ip,vp) (*(ip)->li_ops->iop_format)(ip, vp)
-#define IOP_PIN(ip) (*(ip)->li_ops->iop_pin)(ip)
-#define IOP_UNPIN(ip, flags) (*(ip)->li_ops->iop_unpin)(ip, flags)
-#define IOP_UNPIN_REMOVE(ip,tp) (*(ip)->li_ops->iop_unpin_remove)(ip, tp)
-#define IOP_TRYLOCK(ip) (*(ip)->li_ops->iop_trylock)(ip)
-#define IOP_UNLOCK(ip) (*(ip)->li_ops->iop_unlock)(ip)
-#define IOP_COMMITTED(ip, lsn) (*(ip)->li_ops->iop_committed)(ip, lsn)
-#define IOP_PUSH(ip) (*(ip)->li_ops->iop_push)(ip)
-#define IOP_ABORT(ip) (*(ip)->li_ops->iop_abort)(ip)
-#define IOP_PUSHBUF(ip) (*(ip)->li_ops->iop_pushbuf)(ip)
-#define IOP_COMMITTING(ip, lsn) (*(ip)->li_ops->iop_committing)(ip, lsn)
-
-/*
- * Return values for the IOP_TRYLOCK() routines.
- */
-#define XFS_ITEM_SUCCESS 0
-#define XFS_ITEM_PINNED 1
-#define XFS_ITEM_LOCKED 2
-#define XFS_ITEM_FLUSHING 3
-#define XFS_ITEM_PUSHBUF 4
-
-#endif /* __KERNEL__ */
-
-/*
- * This structure is used to track log items associated with
- * a transaction. It points to the log item and keeps some
- * flags to track the state of the log item. It also tracks
- * the amount of space needed to log the item it describes
- * once we get to commit processing (see xfs_trans_commit()).
- */
-typedef struct xfs_log_item_desc {
- xfs_log_item_t *lid_item;
- ushort lid_size;
- unsigned char lid_flags;
- unsigned char lid_index;
-} xfs_log_item_desc_t;
-
-#define XFS_LID_DIRTY 0x1
-#define XFS_LID_PINNED 0x2
-#define XFS_LID_BUF_STALE 0x8
-
-/*
- * This structure is used to maintain a chunk list of log_item_desc
- * structures. The free field is a bitmask indicating which descriptors
- * in this chunk's array are free. The unused field is the first value
- * not used since this chunk was allocated.
- */
-#define XFS_LIC_NUM_SLOTS 15
-typedef struct xfs_log_item_chunk {
- struct xfs_log_item_chunk *lic_next;
- ushort lic_free;
- ushort lic_unused;
- xfs_log_item_desc_t lic_descs[XFS_LIC_NUM_SLOTS];
-} xfs_log_item_chunk_t;
-
-#define XFS_LIC_MAX_SLOT (XFS_LIC_NUM_SLOTS - 1)
-#define XFS_LIC_FREEMASK ((1 << XFS_LIC_NUM_SLOTS) - 1)
-
-
-/*
- * Initialize the given chunk. Set the chunk's free descriptor mask
- * to indicate that all descriptors are free. The caller gets to set
- * lic_unused to the right value (0 matches all free). The
- * lic_descs.lid_index values are set up as each desc is allocated.
- */
-#define XFS_LIC_INIT(cp) xfs_lic_init(cp)
-static inline void xfs_lic_init(xfs_log_item_chunk_t *cp)
-{
- cp->lic_free = XFS_LIC_FREEMASK;
-}
-
-#define XFS_LIC_INIT_SLOT(cp,slot) xfs_lic_init_slot(cp, slot)
-static inline void xfs_lic_init_slot(xfs_log_item_chunk_t *cp, int slot)
-{
- cp->lic_descs[slot].lid_index = (unsigned char)(slot);
-}
-
-#define XFS_LIC_VACANCY(cp) xfs_lic_vacancy(cp)
-static inline int xfs_lic_vacancy(xfs_log_item_chunk_t *cp)
-{
- return cp->lic_free & XFS_LIC_FREEMASK;
-}
-
-#define XFS_LIC_ALL_FREE(cp) xfs_lic_all_free(cp)
-static inline void xfs_lic_all_free(xfs_log_item_chunk_t *cp)
-{
- cp->lic_free = XFS_LIC_FREEMASK;
-}
-
-#define XFS_LIC_ARE_ALL_FREE(cp) xfs_lic_are_all_free(cp)
-static inline int xfs_lic_are_all_free(xfs_log_item_chunk_t *cp)
-{
- return ((cp->lic_free & XFS_LIC_FREEMASK) == XFS_LIC_FREEMASK);
-}
-
-#define XFS_LIC_ISFREE(cp,slot) xfs_lic_isfree(cp,slot)
-static inline int xfs_lic_isfree(xfs_log_item_chunk_t *cp, int slot)
-{
- return (cp->lic_free & (1 << slot));
-}
-
-#define XFS_LIC_CLAIM(cp,slot) xfs_lic_claim(cp,slot)
-static inline void xfs_lic_claim(xfs_log_item_chunk_t *cp, int slot)
-{
- cp->lic_free &= ~(1 << slot);
-}
-
-#define XFS_LIC_RELSE(cp,slot) xfs_lic_relse(cp,slot)
-static inline void xfs_lic_relse(xfs_log_item_chunk_t *cp, int slot)
-{
- cp->lic_free |= 1 << slot;
-}
-
-#define XFS_LIC_SLOT(cp,slot) xfs_lic_slot(cp,slot)
-static inline xfs_log_item_desc_t *
-xfs_lic_slot(xfs_log_item_chunk_t *cp, int slot)
-{
- return &(cp->lic_descs[slot]);
-}
-
-#define XFS_LIC_DESC_TO_SLOT(dp) xfs_lic_desc_to_slot(dp)
-static inline int xfs_lic_desc_to_slot(xfs_log_item_desc_t *dp)
-{
- return (uint)dp->lid_index;
-}
-
-/*
- * Calculate the address of a chunk given a descriptor pointer:
- * dp - dp->lid_index give the address of the start of the lic_descs array.
- * From this we subtract the offset of the lic_descs field in a chunk.
- * All of this yields the address of the chunk, which is
- * cast to a chunk pointer.
- */
-#define XFS_LIC_DESC_TO_CHUNK(dp) xfs_lic_desc_to_chunk(dp)
-static inline xfs_log_item_chunk_t *
-xfs_lic_desc_to_chunk(xfs_log_item_desc_t *dp)
-{
- return (xfs_log_item_chunk_t*) \
- (((xfs_caddr_t)((dp) - (dp)->lid_index)) - \
- (xfs_caddr_t)(((xfs_log_item_chunk_t*)0)->lic_descs));
-}
-
-#ifdef __KERNEL__
-/*
- * This structure is used to maintain a list of block ranges that have been
- * freed in the transaction. The ranges are listed in the perag[] busy list
- * between when they're freed and the transaction is committed to disk.
- */
-
-typedef struct xfs_log_busy_slot {
- xfs_agnumber_t lbc_ag;
- ushort lbc_idx; /* index in perag.busy[] */
-} xfs_log_busy_slot_t;
-
-#define XFS_LBC_NUM_SLOTS 31
-typedef struct xfs_log_busy_chunk {
- struct xfs_log_busy_chunk *lbc_next;
- uint lbc_free; /* free slots bitmask */
- ushort lbc_unused; /* first unused */
- xfs_log_busy_slot_t lbc_busy[XFS_LBC_NUM_SLOTS];
-} xfs_log_busy_chunk_t;
-
-#define XFS_LBC_MAX_SLOT (XFS_LBC_NUM_SLOTS - 1)
-#define XFS_LBC_FREEMASK ((1U << XFS_LBC_NUM_SLOTS) - 1)
-
-#define XFS_LBC_INIT(cp) ((cp)->lbc_free = XFS_LBC_FREEMASK)
-#define XFS_LBC_CLAIM(cp, slot) ((cp)->lbc_free &= ~(1 << (slot)))
-#define XFS_LBC_SLOT(cp, slot) (&((cp)->lbc_busy[(slot)]))
-#define XFS_LBC_VACANCY(cp) (((cp)->lbc_free) & XFS_LBC_FREEMASK)
-#define XFS_LBC_ISFREE(cp, slot) ((cp)->lbc_free & (1 << (slot)))
-
-/*
- * This is the type of function which can be given to xfs_trans_callback()
- * to be called upon the transaction's commit to disk.
- */
-typedef void (*xfs_trans_callback_t)(struct xfs_trans *, void *);
-
-/*
- * This is the structure maintained for every active transaction.
- */
-typedef struct xfs_trans {
- unsigned int t_magic; /* magic number */
- xfs_log_callback_t t_logcb; /* log callback struct */
- struct xfs_trans *t_forw; /* async list pointers */
- struct xfs_trans *t_back; /* async list pointers */
- unsigned int t_type; /* transaction type */
- unsigned int t_log_res; /* amt of log space resvd */
- unsigned int t_log_count; /* count for perm log res */
- unsigned int t_blk_res; /* # of blocks resvd */
- unsigned int t_blk_res_used; /* # of resvd blocks used */
- unsigned int t_rtx_res; /* # of rt extents resvd */
- unsigned int t_rtx_res_used; /* # of resvd rt extents used */
- xfs_log_ticket_t t_ticket; /* log mgr ticket */
- sema_t t_sema; /* sema for commit completion */
- xfs_lsn_t t_lsn; /* log seq num of start of
- * transaction. */
- xfs_lsn_t t_commit_lsn; /* log seq num of end of
- * transaction. */
- struct xfs_mount *t_mountp; /* ptr to fs mount struct */
- struct xfs_dquot_acct *t_dqinfo; /* acctg info for dquots */
- xfs_trans_callback_t t_callback; /* transaction callback */
- void *t_callarg; /* callback arg */
- unsigned int t_flags; /* misc flags */
- long t_icount_delta; /* superblock icount change */
- long t_ifree_delta; /* superblock ifree change */
- long t_fdblocks_delta; /* superblock fdblocks chg */
- long t_res_fdblocks_delta; /* on-disk only chg */
- long t_frextents_delta;/* superblock freextents chg*/
- long t_res_frextents_delta; /* on-disk only chg */
- long t_ag_freeblks_delta; /* debugging counter */
- long t_ag_flist_delta; /* debugging counter */
- long t_ag_btree_delta; /* debugging counter */
- long t_dblocks_delta;/* superblock dblocks change */
- long t_agcount_delta;/* superblock agcount change */
- long t_imaxpct_delta;/* superblock imaxpct change */
- long t_rextsize_delta;/* superblock rextsize chg */
- long t_rbmblocks_delta;/* superblock rbmblocks chg */
- long t_rblocks_delta;/* superblock rblocks change */
- long t_rextents_delta;/* superblocks rextents chg */
- long t_rextslog_delta;/* superblocks rextslog chg */
- unsigned int t_items_free; /* log item descs free */
- xfs_log_item_chunk_t t_items; /* first log item desc chunk */
- xfs_trans_header_t t_header; /* header for in-log trans */
- unsigned int t_busy_free; /* busy descs free */
- xfs_log_busy_chunk_t t_busy; /* busy/async free blocks */
- unsigned long t_pflags; /* saved process flags state */
-} xfs_trans_t;
-
-#endif /* __KERNEL__ */
-
-
-#define XFS_TRANS_MAGIC 0x5452414E /* 'TRAN' */
-/*
- * Values for t_flags.
- */
-#define XFS_TRANS_DIRTY 0x01 /* something needs to be logged */
-#define XFS_TRANS_SB_DIRTY 0x02 /* superblock is modified */
-#define XFS_TRANS_PERM_LOG_RES 0x04 /* xact took a permanent log res */
-#define XFS_TRANS_SYNC 0x08 /* make commit synchronous */
-#define XFS_TRANS_DQ_DIRTY 0x10 /* at least one dquot in trx dirty */
-#define XFS_TRANS_RESERVE 0x20 /* OK to use reserved data blocks */
-
-/*
- * Values for call flags parameter.
- */
-#define XFS_TRANS_NOSLEEP 0x1
-#define XFS_TRANS_WAIT 0x2
-#define XFS_TRANS_RELEASE_LOG_RES 0x4
-#define XFS_TRANS_ABORT 0x8
-
-/*
- * Field values for xfs_trans_mod_sb.
- */
-#define XFS_TRANS_SB_ICOUNT 0x00000001
-#define XFS_TRANS_SB_IFREE 0x00000002
-#define XFS_TRANS_SB_FDBLOCKS 0x00000004
-#define XFS_TRANS_SB_RES_FDBLOCKS 0x00000008
-#define XFS_TRANS_SB_FREXTENTS 0x00000010
-#define XFS_TRANS_SB_RES_FREXTENTS 0x00000020
-#define XFS_TRANS_SB_DBLOCKS 0x00000040
-#define XFS_TRANS_SB_AGCOUNT 0x00000080
-#define XFS_TRANS_SB_IMAXPCT 0x00000100
-#define XFS_TRANS_SB_REXTSIZE 0x00000200
-#define XFS_TRANS_SB_RBMBLOCKS 0x00000400
-#define XFS_TRANS_SB_RBLOCKS 0x00000800
-#define XFS_TRANS_SB_REXTENTS 0x00001000
-#define XFS_TRANS_SB_REXTSLOG 0x00002000
-
-
-/*
- * Various log reservation values.
- * These are based on the size of the file system block
- * because that is what most transactions manipulate.
- * Each adds in an additional 128 bytes per item logged to
- * try to account for the overhead of the transaction mechanism.
- *
- * Note:
- * Most of the reservations underestimate the number of allocation
- * groups into which they could free extents in the xfs_bmap_finish()
- * call. This is because the number in the worst case is quite high
- * and quite unusual. In order to fix this we need to change
- * xfs_bmap_finish() to free extents in only a single AG at a time.
- * This will require changes to the EFI code as well, however, so that
- * the EFI for the extents not freed is logged again in each transaction.
- * See bug 261917.
- */
-
-/*
- * Per-extent log reservation for the allocation btree changes
- * involved in freeing or allocating an extent.
- * 2 trees * (2 blocks/level * max depth - 1) * block size
- */
-#define XFS_ALLOCFREE_LOG_RES(mp,nx) \
- ((nx) * (2 * XFS_FSB_TO_B((mp), 2 * XFS_AG_MAXLEVELS(mp) - 1)))
-#define XFS_ALLOCFREE_LOG_COUNT(mp,nx) \
- ((nx) * (2 * (2 * XFS_AG_MAXLEVELS(mp) - 1)))
-
-/*
- * Per-directory log reservation for any directory change.
- * dir blocks: (1 btree block per level + data block + free block) * dblock size
- * bmap btree: (levels + 2) * max depth * block size
- * v2 directory blocks can be fragmented below the dirblksize down to the fsb
- * size, so account for that in the DAENTER macros.
- */
-#define XFS_DIROP_LOG_RES(mp) \
- (XFS_FSB_TO_B(mp, XFS_DAENTER_BLOCKS(mp, XFS_DATA_FORK)) + \
- (XFS_FSB_TO_B(mp, XFS_DAENTER_BMAPS(mp, XFS_DATA_FORK) + 1)))
-#define XFS_DIROP_LOG_COUNT(mp) \
- (XFS_DAENTER_BLOCKS(mp, XFS_DATA_FORK) + \
- XFS_DAENTER_BMAPS(mp, XFS_DATA_FORK) + 1)
-
-/*
- * In a write transaction we can allocate a maximum of 2
- * extents. This gives:
- * the inode getting the new extents: inode size
- * the inode\'s bmap btree: max depth * block size
- * the agfs of the ags from which the extents are allocated: 2 * sector
- * the superblock free block counter: sector size
- * the allocation btrees: 2 exts * 2 trees * (2 * max depth - 1) * block size
- * And the bmap_finish transaction can free bmap blocks in a join:
- * the agfs of the ags containing the blocks: 2 * sector size
- * the agfls of the ags containing the blocks: 2 * sector size
- * the super block free block counter: sector size
- * the allocation btrees: 2 exts * 2 trees * (2 * max depth - 1) * block size
- */
-#define XFS_CALC_WRITE_LOG_RES(mp) \
- (MAX( \
- ((mp)->m_sb.sb_inodesize + \
- XFS_FSB_TO_B((mp), XFS_BM_MAXLEVELS(mp, XFS_DATA_FORK)) + \
- (2 * (mp)->m_sb.sb_sectsize) + \
- (mp)->m_sb.sb_sectsize + \
- XFS_ALLOCFREE_LOG_RES(mp, 2) + \
- (128 * (4 + XFS_BM_MAXLEVELS(mp, XFS_DATA_FORK) + XFS_ALLOCFREE_LOG_COUNT(mp, 2)))),\
- ((2 * (mp)->m_sb.sb_sectsize) + \
- (2 * (mp)->m_sb.sb_sectsize) + \
- (mp)->m_sb.sb_sectsize + \
- XFS_ALLOCFREE_LOG_RES(mp, 2) + \
- (128 * (5 + XFS_ALLOCFREE_LOG_COUNT(mp, 2))))))
-
-#define XFS_WRITE_LOG_RES(mp) ((mp)->m_reservations.tr_write)
-
-/*
- * In truncating a file we free up to two extents at once. We can modify:
- * the inode being truncated: inode size
- * the inode\'s bmap btree: (max depth + 1) * block size
- * And the bmap_finish transaction can free the blocks and bmap blocks:
- * the agf for each of the ags: 4 * sector size
- * the agfl for each of the ags: 4 * sector size
- * the super block to reflect the freed blocks: sector size
- * worst case split in allocation btrees per extent assuming 4 extents:
- * 4 exts * 2 trees * (2 * max depth - 1) * block size
- * the inode btree: max depth * blocksize
- * the allocation btrees: 2 trees * (max depth - 1) * block size
- */
-#define XFS_CALC_ITRUNCATE_LOG_RES(mp) \
- (MAX( \
- ((mp)->m_sb.sb_inodesize + \
- XFS_FSB_TO_B((mp), XFS_BM_MAXLEVELS(mp, XFS_DATA_FORK) + 1) + \
- (128 * (2 + XFS_BM_MAXLEVELS(mp, XFS_DATA_FORK)))), \
- ((4 * (mp)->m_sb.sb_sectsize) + \
- (4 * (mp)->m_sb.sb_sectsize) + \
- (mp)->m_sb.sb_sectsize + \
- XFS_ALLOCFREE_LOG_RES(mp, 4) + \
- (128 * (9 + XFS_ALLOCFREE_LOG_COUNT(mp, 4))) + \
- (128 * 5) + \
- XFS_ALLOCFREE_LOG_RES(mp, 1) + \
- (128 * (2 + XFS_IALLOC_BLOCKS(mp) + XFS_IN_MAXLEVELS(mp) + \
- XFS_ALLOCFREE_LOG_COUNT(mp, 1))))))
-
-#define XFS_ITRUNCATE_LOG_RES(mp) ((mp)->m_reservations.tr_itruncate)
-
-/*
- * In renaming a files we can modify:
- * the four inodes involved: 4 * inode size
- * the two directory btrees: 2 * (max depth + v2) * dir block size
- * the two directory bmap btrees: 2 * max depth * block size
- * And the bmap_finish transaction can free dir and bmap blocks (two sets
- * of bmap blocks) giving:
- * the agf for the ags in which the blocks live: 3 * sector size
- * the agfl for the ags in which the blocks live: 3 * sector size
- * the superblock for the free block count: sector size
- * the allocation btrees: 3 exts * 2 trees * (2 * max depth - 1) * block size
- */
-#define XFS_CALC_RENAME_LOG_RES(mp) \
- (MAX( \
- ((4 * (mp)->m_sb.sb_inodesize) + \
- (2 * XFS_DIROP_LOG_RES(mp)) + \
- (128 * (4 + 2 * XFS_DIROP_LOG_COUNT(mp)))), \
- ((3 * (mp)->m_sb.sb_sectsize) + \
- (3 * (mp)->m_sb.sb_sectsize) + \
- (mp)->m_sb.sb_sectsize + \
- XFS_ALLOCFREE_LOG_RES(mp, 3) + \
- (128 * (7 + XFS_ALLOCFREE_LOG_COUNT(mp, 3))))))
-
-#define XFS_RENAME_LOG_RES(mp) ((mp)->m_reservations.tr_rename)
-
-/*
- * For creating a link to an inode:
- * the parent directory inode: inode size
- * the linked inode: inode size
- * the directory btree could split: (max depth + v2) * dir block size
- * the directory bmap btree could join or split: (max depth + v2) * blocksize
- * And the bmap_finish transaction can free some bmap blocks giving:
- * the agf for the ag in which the blocks live: sector size
- * the agfl for the ag in which the blocks live: sector size
- * the superblock for the free block count: sector size
- * the allocation btrees: 2 trees * (2 * max depth - 1) * block size
- */
-#define XFS_CALC_LINK_LOG_RES(mp) \
- (MAX( \
- ((mp)->m_sb.sb_inodesize + \
- (mp)->m_sb.sb_inodesize + \
- XFS_DIROP_LOG_RES(mp) + \
- (128 * (2 + XFS_DIROP_LOG_COUNT(mp)))), \
- ((mp)->m_sb.sb_sectsize + \
- (mp)->m_sb.sb_sectsize + \
- (mp)->m_sb.sb_sectsize + \
- XFS_ALLOCFREE_LOG_RES(mp, 1) + \
- (128 * (3 + XFS_ALLOCFREE_LOG_COUNT(mp, 1))))))
-
-#define XFS_LINK_LOG_RES(mp) ((mp)->m_reservations.tr_link)
-
-/*
- * For removing a directory entry we can modify:
- * the parent directory inode: inode size
- * the removed inode: inode size
- * the directory btree could join: (max depth + v2) * dir block size
- * the directory bmap btree could join or split: (max depth + v2) * blocksize
- * And the bmap_finish transaction can free the dir and bmap blocks giving:
- * the agf for the ag in which the blocks live: 2 * sector size
- * the agfl for the ag in which the blocks live: 2 * sector size
- * the superblock for the free block count: sector size
- * the allocation btrees: 2 exts * 2 trees * (2 * max depth - 1) * block size
- */
-#define XFS_CALC_REMOVE_LOG_RES(mp) \
- (MAX( \
- ((mp)->m_sb.sb_inodesize + \
- (mp)->m_sb.sb_inodesize + \
- XFS_DIROP_LOG_RES(mp) + \
- (128 * (2 + XFS_DIROP_LOG_COUNT(mp)))), \
- ((2 * (mp)->m_sb.sb_sectsize) + \
- (2 * (mp)->m_sb.sb_sectsize) + \
- (mp)->m_sb.sb_sectsize + \
- XFS_ALLOCFREE_LOG_RES(mp, 2) + \
- (128 * (5 + XFS_ALLOCFREE_LOG_COUNT(mp, 2))))))
-
-#define XFS_REMOVE_LOG_RES(mp) ((mp)->m_reservations.tr_remove)
-
-/*
- * For symlink we can modify:
- * the parent directory inode: inode size
- * the new inode: inode size
- * the inode btree entry: 1 block
- * the directory btree: (max depth + v2) * dir block size
- * the directory inode\'s bmap btree: (max depth + v2) * block size
- * the blocks for the symlink: 1 KB
- * Or in the first xact we allocate some inodes giving:
- * the agi and agf of the ag getting the new inodes: 2 * sectorsize
- * the inode blocks allocated: XFS_IALLOC_BLOCKS * blocksize
- * the inode btree: max depth * blocksize
- * the allocation btrees: 2 trees * (2 * max depth - 1) * block size
- */
-#define XFS_CALC_SYMLINK_LOG_RES(mp) \
- (MAX( \
- ((mp)->m_sb.sb_inodesize + \
- (mp)->m_sb.sb_inodesize + \
- XFS_FSB_TO_B(mp, 1) + \
- XFS_DIROP_LOG_RES(mp) + \
- 1024 + \
- (128 * (4 + XFS_DIROP_LOG_COUNT(mp)))), \
- (2 * (mp)->m_sb.sb_sectsize + \
- XFS_FSB_TO_B((mp), XFS_IALLOC_BLOCKS((mp))) + \
- XFS_FSB_TO_B((mp), XFS_IN_MAXLEVELS(mp)) + \
- XFS_ALLOCFREE_LOG_RES(mp, 1) + \
- (128 * (2 + XFS_IALLOC_BLOCKS(mp) + XFS_IN_MAXLEVELS(mp) + \
- XFS_ALLOCFREE_LOG_COUNT(mp, 1))))))
-
-#define XFS_SYMLINK_LOG_RES(mp) ((mp)->m_reservations.tr_symlink)
-
-/*
- * For create we can modify:
- * the parent directory inode: inode size
- * the new inode: inode size
- * the inode btree entry: block size
- * the superblock for the nlink flag: sector size
- * the directory btree: (max depth + v2) * dir block size
- * the directory inode\'s bmap btree: (max depth + v2) * block size
- * Or in the first xact we allocate some inodes giving:
- * the agi and agf of the ag getting the new inodes: 2 * sectorsize
- * the superblock for the nlink flag: sector size
- * the inode blocks allocated: XFS_IALLOC_BLOCKS * blocksize
- * the inode btree: max depth * blocksize
- * the allocation btrees: 2 trees * (max depth - 1) * block size
- */
-#define XFS_CALC_CREATE_LOG_RES(mp) \
- (MAX( \
- ((mp)->m_sb.sb_inodesize + \
- (mp)->m_sb.sb_inodesize + \
- (mp)->m_sb.sb_sectsize + \
- XFS_FSB_TO_B(mp, 1) + \
- XFS_DIROP_LOG_RES(mp) + \
- (128 * (3 + XFS_DIROP_LOG_COUNT(mp)))), \
- (3 * (mp)->m_sb.sb_sectsize + \
- XFS_FSB_TO_B((mp), XFS_IALLOC_BLOCKS((mp))) + \
- XFS_FSB_TO_B((mp), XFS_IN_MAXLEVELS(mp)) + \
- XFS_ALLOCFREE_LOG_RES(mp, 1) + \
- (128 * (2 + XFS_IALLOC_BLOCKS(mp) + XFS_IN_MAXLEVELS(mp) + \
- XFS_ALLOCFREE_LOG_COUNT(mp, 1))))))
-
-#define XFS_CREATE_LOG_RES(mp) ((mp)->m_reservations.tr_create)
-
-/*
- * Making a new directory is the same as creating a new file.
- */
-#define XFS_CALC_MKDIR_LOG_RES(mp) XFS_CALC_CREATE_LOG_RES(mp)
-
-#define XFS_MKDIR_LOG_RES(mp) ((mp)->m_reservations.tr_mkdir)
-
-/*
- * In freeing an inode we can modify:
- * the inode being freed: inode size
- * the super block free inode counter: sector size
- * the agi hash list and counters: sector size
- * the inode btree entry: block size
- * the on disk inode before ours in the agi hash list: inode cluster size
- * the inode btree: max depth * blocksize
- * the allocation btrees: 2 trees * (max depth - 1) * block size
- */
-#define XFS_CALC_IFREE_LOG_RES(mp) \
- ((mp)->m_sb.sb_inodesize + \
- (mp)->m_sb.sb_sectsize + \
- (mp)->m_sb.sb_sectsize + \
- XFS_FSB_TO_B((mp), 1) + \
- MAX((__uint16_t)XFS_FSB_TO_B((mp), 1), XFS_INODE_CLUSTER_SIZE(mp)) + \
- (128 * 5) + \
- XFS_ALLOCFREE_LOG_RES(mp, 1) + \
- (128 * (2 + XFS_IALLOC_BLOCKS(mp) + XFS_IN_MAXLEVELS(mp) + \
- XFS_ALLOCFREE_LOG_COUNT(mp, 1))))
-
-
-#define XFS_IFREE_LOG_RES(mp) ((mp)->m_reservations.tr_ifree)
-
-/*
- * When only changing the inode we log the inode and possibly the superblock
- * We also add a bit of slop for the transaction stuff.
- */
-#define XFS_CALC_ICHANGE_LOG_RES(mp) ((mp)->m_sb.sb_inodesize + \
- (mp)->m_sb.sb_sectsize + 512)
-
-#define XFS_ICHANGE_LOG_RES(mp) ((mp)->m_reservations.tr_ichange)
-
-/*
- * Growing the data section of the filesystem.
- * superblock
- * agi and agf
- * allocation btrees
- */
-#define XFS_CALC_GROWDATA_LOG_RES(mp) \
- ((mp)->m_sb.sb_sectsize * 3 + \
- XFS_ALLOCFREE_LOG_RES(mp, 1) + \
- (128 * (3 + XFS_ALLOCFREE_LOG_COUNT(mp, 1))))
-
-#define XFS_GROWDATA_LOG_RES(mp) ((mp)->m_reservations.tr_growdata)
-
-/*
- * Growing the rt section of the filesystem.
- * In the first set of transactions (ALLOC) we allocate space to the
- * bitmap or summary files.
- * superblock: sector size
- * agf of the ag from which the extent is allocated: sector size
- * bmap btree for bitmap/summary inode: max depth * blocksize
- * bitmap/summary inode: inode size
- * allocation btrees for 1 block alloc: 2 * (2 * maxdepth - 1) * blocksize
- */
-#define XFS_CALC_GROWRTALLOC_LOG_RES(mp) \
- (2 * (mp)->m_sb.sb_sectsize + \
- XFS_FSB_TO_B((mp), XFS_BM_MAXLEVELS(mp, XFS_DATA_FORK)) + \
- (mp)->m_sb.sb_inodesize + \
- XFS_ALLOCFREE_LOG_RES(mp, 1) + \
- (128 * \
- (3 + XFS_BM_MAXLEVELS(mp, XFS_DATA_FORK) + \
- XFS_ALLOCFREE_LOG_COUNT(mp, 1))))
-
-#define XFS_GROWRTALLOC_LOG_RES(mp) ((mp)->m_reservations.tr_growrtalloc)
-
-/*
- * Growing the rt section of the filesystem.
- * In the second set of transactions (ZERO) we zero the new metadata blocks.
- * one bitmap/summary block: blocksize
- */
-#define XFS_CALC_GROWRTZERO_LOG_RES(mp) \
- ((mp)->m_sb.sb_blocksize + 128)
-
-#define XFS_GROWRTZERO_LOG_RES(mp) ((mp)->m_reservations.tr_growrtzero)
-
-/*
- * Growing the rt section of the filesystem.
- * In the third set of transactions (FREE) we update metadata without
- * allocating any new blocks.
- * superblock: sector size
- * bitmap inode: inode size
- * summary inode: inode size
- * one bitmap block: blocksize
- * summary blocks: new summary size
- */
-#define XFS_CALC_GROWRTFREE_LOG_RES(mp) \
- ((mp)->m_sb.sb_sectsize + \
- 2 * (mp)->m_sb.sb_inodesize + \
- (mp)->m_sb.sb_blocksize + \
- (mp)->m_rsumsize + \
- (128 * 5))
-
-#define XFS_GROWRTFREE_LOG_RES(mp) ((mp)->m_reservations.tr_growrtfree)
-
-/*
- * Logging the inode modification timestamp on a synchronous write.
- * inode
- */
-#define XFS_CALC_SWRITE_LOG_RES(mp) \
- ((mp)->m_sb.sb_inodesize + 128)
-
-#define XFS_SWRITE_LOG_RES(mp) ((mp)->m_reservations.tr_swrite)
-
-/*
- * Logging the inode timestamps on an fsync -- same as SWRITE
- * as long as SWRITE logs the entire inode core
- */
-#define XFS_FSYNC_TS_LOG_RES(mp) ((mp)->m_reservations.tr_swrite)
-
-/*
- * Logging the inode mode bits when writing a setuid/setgid file
- * inode
- */
-#define XFS_CALC_WRITEID_LOG_RES(mp) \
- ((mp)->m_sb.sb_inodesize + 128)
-
-#define XFS_WRITEID_LOG_RES(mp) ((mp)->m_reservations.tr_swrite)
-
-/*
- * Converting the inode from non-attributed to attributed.
- * the inode being converted: inode size
- * agf block and superblock (for block allocation)
- * the new block (directory sized)
- * bmap blocks for the new directory block
- * allocation btrees
- */
-#define XFS_CALC_ADDAFORK_LOG_RES(mp) \
- ((mp)->m_sb.sb_inodesize + \
- (mp)->m_sb.sb_sectsize * 2 + \
- (mp)->m_dirblksize + \
- (XFS_DIR_IS_V1(mp) ? 0 : \
- XFS_FSB_TO_B(mp, (XFS_DAENTER_BMAP1B(mp, XFS_DATA_FORK) + 1))) + \
- XFS_ALLOCFREE_LOG_RES(mp, 1) + \
- (128 * (4 + \
- (XFS_DIR_IS_V1(mp) ? 0 : \
- XFS_DAENTER_BMAP1B(mp, XFS_DATA_FORK) + 1) + \
- XFS_ALLOCFREE_LOG_COUNT(mp, 1))))
-
-#define XFS_ADDAFORK_LOG_RES(mp) ((mp)->m_reservations.tr_addafork)
-
-/*
- * Removing the attribute fork of a file
- * the inode being truncated: inode size
- * the inode\'s bmap btree: max depth * block size
- * And the bmap_finish transaction can free the blocks and bmap blocks:
- * the agf for each of the ags: 4 * sector size
- * the agfl for each of the ags: 4 * sector size
- * the super block to reflect the freed blocks: sector size
- * worst case split in allocation btrees per extent assuming 4 extents:
- * 4 exts * 2 trees * (2 * max depth - 1) * block size
- */
-#define XFS_CALC_ATTRINVAL_LOG_RES(mp) \
- (MAX( \
- ((mp)->m_sb.sb_inodesize + \
- XFS_FSB_TO_B((mp), XFS_BM_MAXLEVELS(mp, XFS_ATTR_FORK)) + \
- (128 * (1 + XFS_BM_MAXLEVELS(mp, XFS_ATTR_FORK)))), \
- ((4 * (mp)->m_sb.sb_sectsize) + \
- (4 * (mp)->m_sb.sb_sectsize) + \
- (mp)->m_sb.sb_sectsize + \
- XFS_ALLOCFREE_LOG_RES(mp, 4) + \
- (128 * (9 + XFS_ALLOCFREE_LOG_COUNT(mp, 4))))))
-
-#define XFS_ATTRINVAL_LOG_RES(mp) ((mp)->m_reservations.tr_attrinval)
-
-/*
- * Setting an attribute.
- * the inode getting the attribute
- * the superblock for allocations
- * the agfs extents are allocated from
- * the attribute btree * max depth
- * the inode allocation btree
- * Since attribute transaction space is dependent on the size of the attribute,
- * the calculation is done partially at mount time and partially at runtime.
- */
-#define XFS_CALC_ATTRSET_LOG_RES(mp) \
- ((mp)->m_sb.sb_inodesize + \
- (mp)->m_sb.sb_sectsize + \
- XFS_FSB_TO_B((mp), XFS_DA_NODE_MAXDEPTH) + \
- (128 * (2 + XFS_DA_NODE_MAXDEPTH)))
-
-#define XFS_ATTRSET_LOG_RES(mp, ext) \
- ((mp)->m_reservations.tr_attrset + \
- (ext * (mp)->m_sb.sb_sectsize) + \
- (ext * XFS_FSB_TO_B((mp), XFS_BM_MAXLEVELS(mp, XFS_ATTR_FORK))) + \
- (128 * (ext + (ext * XFS_BM_MAXLEVELS(mp, XFS_ATTR_FORK)))))
-
-/*
- * Removing an attribute.
- * the inode: inode size
- * the attribute btree could join: max depth * block size
- * the inode bmap btree could join or split: max depth * block size
- * And the bmap_finish transaction can free the attr blocks freed giving:
- * the agf for the ag in which the blocks live: 2 * sector size
- * the agfl for the ag in which the blocks live: 2 * sector size
- * the superblock for the free block count: sector size
- * the allocation btrees: 2 exts * 2 trees * (2 * max depth - 1) * block size
- */
-#define XFS_CALC_ATTRRM_LOG_RES(mp) \
- (MAX( \
- ((mp)->m_sb.sb_inodesize + \
- XFS_FSB_TO_B((mp), XFS_DA_NODE_MAXDEPTH) + \
- XFS_FSB_TO_B((mp), XFS_BM_MAXLEVELS(mp, XFS_ATTR_FORK)) + \
- (128 * (1 + XFS_DA_NODE_MAXDEPTH + XFS_BM_MAXLEVELS(mp, XFS_DATA_FORK)))), \
- ((2 * (mp)->m_sb.sb_sectsize) + \
- (2 * (mp)->m_sb.sb_sectsize) + \
- (mp)->m_sb.sb_sectsize + \
- XFS_ALLOCFREE_LOG_RES(mp, 2) + \
- (128 * (5 + XFS_ALLOCFREE_LOG_COUNT(mp, 2))))))
-
-#define XFS_ATTRRM_LOG_RES(mp) ((mp)->m_reservations.tr_attrrm)
-
-/*
- * Clearing a bad agino number in an agi hash bucket.
- */
-#define XFS_CALC_CLEAR_AGI_BUCKET_LOG_RES(mp) \
- ((mp)->m_sb.sb_sectsize + 128)
-
-#define XFS_CLEAR_AGI_BUCKET_LOG_RES(mp) ((mp)->m_reservations.tr_clearagi)
-
-
-/*
- * Various log count values.
- */
-#define XFS_DEFAULT_LOG_COUNT 1
-#define XFS_DEFAULT_PERM_LOG_COUNT 2
-#define XFS_ITRUNCATE_LOG_COUNT 2
-#define XFS_INACTIVE_LOG_COUNT 2
-#define XFS_CREATE_LOG_COUNT 2
-#define XFS_MKDIR_LOG_COUNT 3
-#define XFS_SYMLINK_LOG_COUNT 3
-#define XFS_REMOVE_LOG_COUNT 2
-#define XFS_LINK_LOG_COUNT 2
-#define XFS_RENAME_LOG_COUNT 2
-#define XFS_WRITE_LOG_COUNT 2
-#define XFS_ADDAFORK_LOG_COUNT 2
-#define XFS_ATTRINVAL_LOG_COUNT 1
-#define XFS_ATTRSET_LOG_COUNT 3
-#define XFS_ATTRRM_LOG_COUNT 3
-
-/*
- * Here we centralize the specification of XFS meta-data buffer
- * reference count values. This determine how hard the buffer
- * cache tries to hold onto the buffer.
- */
-#define XFS_AGF_REF 4
-#define XFS_AGI_REF 4
-#define XFS_AGFL_REF 3
-#define XFS_INO_BTREE_REF 3
-#define XFS_ALLOC_BTREE_REF 2
-#define XFS_BMAP_BTREE_REF 2
-#define XFS_DIR_BTREE_REF 2
-#define XFS_ATTR_BTREE_REF 1
-#define XFS_INO_REF 1
-#define XFS_DQUOT_REF 1
-
-#ifdef __KERNEL__
-/*
- * XFS transaction mechanism exported interfaces that are
- * actually macros.
- */
-#define xfs_trans_get_log_res(tp) ((tp)->t_log_res)
-#define xfs_trans_get_log_count(tp) ((tp)->t_log_count)
-#define xfs_trans_get_block_res(tp) ((tp)->t_blk_res)
-#define xfs_trans_set_sync(tp) ((tp)->t_flags |= XFS_TRANS_SYNC)
-
-#ifdef DEBUG
-#define xfs_trans_agblocks_delta(tp, d) ((tp)->t_ag_freeblks_delta += (long)d)
-#define xfs_trans_agflist_delta(tp, d) ((tp)->t_ag_flist_delta += (long)d)
-#define xfs_trans_agbtree_delta(tp, d) ((tp)->t_ag_btree_delta += (long)d)
-#else
-#define xfs_trans_agblocks_delta(tp, d)
-#define xfs_trans_agflist_delta(tp, d)
-#define xfs_trans_agbtree_delta(tp, d)
-#endif
-
-/*
- * XFS transaction mechanism exported interfaces.
- */
-void xfs_trans_init(struct xfs_mount *);
-xfs_trans_t *xfs_trans_alloc(struct xfs_mount *, uint);
-xfs_trans_t *_xfs_trans_alloc(struct xfs_mount *, uint);
-xfs_trans_t *xfs_trans_dup(xfs_trans_t *);
-int xfs_trans_reserve(xfs_trans_t *, uint, uint, uint,
- uint, uint);
-void xfs_trans_mod_sb(xfs_trans_t *, uint, long);
-struct xfs_buf *xfs_trans_get_buf(xfs_trans_t *, struct xfs_buftarg *, xfs_daddr_t,
- int, uint);
-int xfs_trans_read_buf(struct xfs_mount *, xfs_trans_t *,
- struct xfs_buftarg *, xfs_daddr_t, int, uint,
- struct xfs_buf **);
-struct xfs_buf *xfs_trans_getsb(xfs_trans_t *, struct xfs_mount *, int);
-
-void xfs_trans_brelse(xfs_trans_t *, struct xfs_buf *);
-void xfs_trans_bjoin(xfs_trans_t *, struct xfs_buf *);
-void xfs_trans_bhold(xfs_trans_t *, struct xfs_buf *);
-void xfs_trans_bhold_release(xfs_trans_t *, struct xfs_buf *);
-void xfs_trans_binval(xfs_trans_t *, struct xfs_buf *);
-void xfs_trans_inode_buf(xfs_trans_t *, struct xfs_buf *);
-void xfs_trans_stale_inode_buf(xfs_trans_t *, struct xfs_buf *);
-void xfs_trans_dquot_buf(xfs_trans_t *, struct xfs_buf *, uint);
-void xfs_trans_inode_alloc_buf(xfs_trans_t *, struct xfs_buf *);
-int xfs_trans_iget(struct xfs_mount *, xfs_trans_t *,
- xfs_ino_t , uint, uint, struct xfs_inode **);
-void xfs_trans_ijoin(xfs_trans_t *, struct xfs_inode *, uint);
-void xfs_trans_ihold(xfs_trans_t *, struct xfs_inode *);
-void xfs_trans_log_buf(xfs_trans_t *, struct xfs_buf *, uint, uint);
-void xfs_trans_log_inode(xfs_trans_t *, struct xfs_inode *, uint);
-struct xfs_efi_log_item *xfs_trans_get_efi(xfs_trans_t *, uint);
-void xfs_efi_release(struct xfs_efi_log_item *, uint);
-void xfs_trans_log_efi_extent(xfs_trans_t *,
- struct xfs_efi_log_item *,
- xfs_fsblock_t,
- xfs_extlen_t);
-struct xfs_efd_log_item *xfs_trans_get_efd(xfs_trans_t *,
- struct xfs_efi_log_item *,
- uint);
-void xfs_trans_log_efd_extent(xfs_trans_t *,
- struct xfs_efd_log_item *,
- xfs_fsblock_t,
- xfs_extlen_t);
-int _xfs_trans_commit(xfs_trans_t *,
- uint flags,
- xfs_lsn_t *,
- int *);
-#define xfs_trans_commit(tp, flags, lsn) \
- _xfs_trans_commit(tp, flags, lsn, NULL)
-void xfs_trans_cancel(xfs_trans_t *, int);
-void xfs_trans_ail_init(struct xfs_mount *);
-xfs_lsn_t xfs_trans_push_ail(struct xfs_mount *, xfs_lsn_t);
-xfs_lsn_t xfs_trans_tail_ail(struct xfs_mount *);
-void xfs_trans_unlocked_item(struct xfs_mount *,
- xfs_log_item_t *);
-xfs_log_busy_slot_t *xfs_trans_add_busy(xfs_trans_t *tp,
- xfs_agnumber_t ag,
- xfs_extlen_t idx);
-
-#endif /* __KERNEL__ */
-
-#endif /* __XFS_TRANS_H__ */
diff --git a/sys/gnu/fs/xfs/xfs_trans_ail.c b/sys/gnu/fs/xfs/xfs_trans_ail.c
deleted file mode 100644
index 19ab24a..0000000
--- a/sys/gnu/fs/xfs/xfs_trans_ail.c
+++ /dev/null
@@ -1,581 +0,0 @@
-/*
- * Copyright (c) 2000-2002,2005 Silicon Graphics, Inc.
- * All Rights Reserved.
- *
- * 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.
- *
- * This program is distributed in the hope that it would 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 the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- */
-#include "xfs.h"
-#include "xfs_fs.h"
-#include "xfs_types.h"
-#include "xfs_log.h"
-#include "xfs_inum.h"
-#include "xfs_trans.h"
-#include "xfs_sb.h"
-#include "xfs_dir.h"
-#include "xfs_dmapi.h"
-#include "xfs_mount.h"
-#include "xfs_trans_priv.h"
-#include "xfs_error.h"
-
-STATIC void xfs_ail_insert(xfs_ail_entry_t *, xfs_log_item_t *);
-STATIC xfs_log_item_t * xfs_ail_delete(xfs_ail_entry_t *, xfs_log_item_t *);
-STATIC xfs_log_item_t * xfs_ail_min(xfs_ail_entry_t *);
-STATIC xfs_log_item_t * xfs_ail_next(xfs_ail_entry_t *, xfs_log_item_t *);
-
-#ifdef DEBUG
-STATIC void xfs_ail_check(xfs_ail_entry_t *);
-#else
-#define xfs_ail_check(a)
-#endif /* DEBUG */
-
-
-/*
- * This is called by the log manager code to determine the LSN
- * of the tail of the log. This is exactly the LSN of the first
- * item in the AIL. If the AIL is empty, then this function
- * returns 0.
- *
- * We need the AIL lock in order to get a coherent read of the
- * lsn of the last item in the AIL.
- */
-xfs_lsn_t
-xfs_trans_tail_ail(
- xfs_mount_t *mp)
-{
- xfs_lsn_t lsn;
- xfs_log_item_t *lip;
- SPLDECL(s);
-
- AIL_LOCK(mp,s);
- lip = xfs_ail_min(&(mp->m_ail));
- if (lip == NULL) {
- lsn = (xfs_lsn_t)0;
- } else {
- lsn = lip->li_lsn;
- }
- AIL_UNLOCK(mp, s);
-
- return lsn;
-}
-
-/*
- * xfs_trans_push_ail
- *
- * This routine is called to move the tail of the AIL
- * forward. It does this by trying to flush items in the AIL
- * whose lsns are below the given threshold_lsn.
- *
- * The routine returns the lsn of the tail of the log.
- */
-xfs_lsn_t
-xfs_trans_push_ail(
- xfs_mount_t *mp,
- xfs_lsn_t threshold_lsn)
-{
- xfs_lsn_t lsn;
- xfs_log_item_t *lip;
- int gen;
- int restarts;
- int lock_result;
- int flush_log;
- SPLDECL(s);
-
-#define XFS_TRANS_PUSH_AIL_RESTARTS 10
-
- AIL_LOCK(mp,s);
- lip = xfs_trans_first_ail(mp, &gen);
- if (lip == NULL || XFS_FORCED_SHUTDOWN(mp)) {
- /*
- * Just return if the AIL is empty.
- */
- AIL_UNLOCK(mp, s);
- return (xfs_lsn_t)0;
- }
-
- XFS_STATS_INC(xs_push_ail);
-
- /*
- * While the item we are looking at is below the given threshold
- * try to flush it out. Make sure to limit the number of times
- * we allow xfs_trans_next_ail() to restart scanning from the
- * beginning of the list. We'd like not to stop until we've at least
- * tried to push on everything in the AIL with an LSN less than
- * the given threshold. However, we may give up before that if
- * we realize that we've been holding the AIL_LOCK for 'too long',
- * blocking interrupts. Currently, too long is < 500us roughly.
- */
- flush_log = 0;
- restarts = 0;
- while (((restarts < XFS_TRANS_PUSH_AIL_RESTARTS) &&
- (XFS_LSN_CMP(lip->li_lsn, threshold_lsn) < 0))) {
- /*
- * If we can lock the item without sleeping, unlock
- * the AIL lock and flush the item. Then re-grab the
- * AIL lock so we can look for the next item on the
- * AIL. Since we unlock the AIL while we flush the
- * item, the next routine may start over again at the
- * the beginning of the list if anything has changed.
- * That is what the generation count is for.
- *
- * If we can't lock the item, either its holder will flush
- * it or it is already being flushed or it is being relogged.
- * In any of these case it is being taken care of and we
- * can just skip to the next item in the list.
- */
- lock_result = IOP_TRYLOCK(lip);
- switch (lock_result) {
- case XFS_ITEM_SUCCESS:
- AIL_UNLOCK(mp, s);
- XFS_STATS_INC(xs_push_ail_success);
- IOP_PUSH(lip);
- AIL_LOCK(mp,s);
- break;
-
- case XFS_ITEM_PUSHBUF:
- AIL_UNLOCK(mp, s);
- XFS_STATS_INC(xs_push_ail_pushbuf);
-#ifdef XFSRACEDEBUG
- delay_for_intr();
- delay(300);
-#endif
- ASSERT(lip->li_ops->iop_pushbuf);
- ASSERT(lip);
- IOP_PUSHBUF(lip);
- AIL_LOCK(mp,s);
- break;
-
- case XFS_ITEM_PINNED:
- XFS_STATS_INC(xs_push_ail_pinned);
- flush_log = 1;
- break;
-
- case XFS_ITEM_LOCKED:
- XFS_STATS_INC(xs_push_ail_locked);
- break;
-
- case XFS_ITEM_FLUSHING:
- XFS_STATS_INC(xs_push_ail_flushing);
- break;
-
- default:
- ASSERT(0);
- break;
- }
-
- lip = xfs_trans_next_ail(mp, lip, &gen, &restarts);
- if (lip == NULL) {
- break;
- }
- if (XFS_FORCED_SHUTDOWN(mp)) {
- /*
- * Just return if we shut down during the last try.
- */
- AIL_UNLOCK(mp, s);
- return (xfs_lsn_t)0;
- }
-
- }
-
- if (flush_log) {
- /*
- * If something we need to push out was pinned, then
- * push out the log so it will become unpinned and
- * move forward in the AIL.
- */
- AIL_UNLOCK(mp, s);
- XFS_STATS_INC(xs_push_ail_flush);
- xfs_log_force(mp, (xfs_lsn_t)0, XFS_LOG_FORCE);
- AIL_LOCK(mp, s);
- }
-
- lip = xfs_ail_min(&(mp->m_ail));
- if (lip == NULL) {
- lsn = (xfs_lsn_t)0;
- } else {
- lsn = lip->li_lsn;
- }
-
- AIL_UNLOCK(mp, s);
- return lsn;
-} /* xfs_trans_push_ail */
-
-
-/*
- * This is to be called when an item is unlocked that may have
- * been in the AIL. It will wake up the first member of the AIL
- * wait list if this item's unlocking might allow it to progress.
- * If the item is in the AIL, then we need to get the AIL lock
- * while doing our checking so we don't race with someone going
- * to sleep waiting for this event in xfs_trans_push_ail().
- */
-void
-xfs_trans_unlocked_item(
- xfs_mount_t *mp,
- xfs_log_item_t *lip)
-{
- xfs_log_item_t *min_lip;
-
- /*
- * If we're forcibly shutting down, we may have
- * unlocked log items arbitrarily. The last thing
- * we want to do is to move the tail of the log
- * over some potentially valid data.
- */
- if (!(lip->li_flags & XFS_LI_IN_AIL) ||
- XFS_FORCED_SHUTDOWN(mp)) {
- return;
- }
-
- /*
- * This is the one case where we can call into xfs_ail_min()
- * without holding the AIL lock because we only care about the
- * case where we are at the tail of the AIL. If the object isn't
- * at the tail, it doesn't matter what result we get back. This
- * is slightly racy because since we were just unlocked, we could
- * go to sleep between the call to xfs_ail_min and the call to
- * xfs_log_move_tail, have someone else lock us, commit to us disk,
- * move us out of the tail of the AIL, and then we wake up. However,
- * the call to xfs_log_move_tail() doesn't do anything if there's
- * not enough free space to wake people up so we're safe calling it.
- */
- min_lip = xfs_ail_min(&mp->m_ail);
-
- if (min_lip == lip)
- xfs_log_move_tail(mp, 1);
-} /* xfs_trans_unlocked_item */
-
-
-/*
- * Update the position of the item in the AIL with the new
- * lsn. If it is not yet in the AIL, add it. Otherwise, move
- * it to its new position by removing it and re-adding it.
- *
- * Wakeup anyone with an lsn less than the item's lsn. If the item
- * we move in the AIL is the minimum one, update the tail lsn in the
- * log manager.
- *
- * Increment the AIL's generation count to indicate that the tree
- * has changed.
- *
- * This function must be called with the AIL lock held. The lock
- * is dropped before returning, so the caller must pass in the
- * cookie returned by AIL_LOCK.
- */
-void
-xfs_trans_update_ail(
- xfs_mount_t *mp,
- xfs_log_item_t *lip,
- xfs_lsn_t lsn,
- unsigned long s)
-{
- xfs_ail_entry_t *ailp;
- xfs_log_item_t *dlip=NULL;
- xfs_log_item_t *mlip; /* ptr to minimum lip */
-
- ailp = &(mp->m_ail);
- mlip = xfs_ail_min(ailp);
-
- if (lip->li_flags & XFS_LI_IN_AIL) {
- dlip = xfs_ail_delete(ailp, lip);
- ASSERT(dlip == lip);
- } else {
- lip->li_flags |= XFS_LI_IN_AIL;
- }
-
- lip->li_lsn = lsn;
-
- xfs_ail_insert(ailp, lip);
- mp->m_ail_gen++;
-
- if (mlip == dlip) {
- mlip = xfs_ail_min(&(mp->m_ail));
- AIL_UNLOCK(mp, s);
- xfs_log_move_tail(mp, mlip->li_lsn);
- } else {
- AIL_UNLOCK(mp, s);
- }
-
-
-} /* xfs_trans_update_ail */
-
-/*
- * Delete the given item from the AIL. It must already be in
- * the AIL.
- *
- * Wakeup anyone with an lsn less than item's lsn. If the item
- * we delete in the AIL is the minimum one, update the tail lsn in the
- * log manager.
- *
- * Clear the IN_AIL flag from the item, reset its lsn to 0, and
- * bump the AIL's generation count to indicate that the tree
- * has changed.
- *
- * This function must be called with the AIL lock held. The lock
- * is dropped before returning, so the caller must pass in the
- * cookie returned by AIL_LOCK.
- */
-void
-xfs_trans_delete_ail(
- xfs_mount_t *mp,
- xfs_log_item_t *lip,
- unsigned long s)
-{
- xfs_ail_entry_t *ailp;
- xfs_log_item_t *dlip;
- xfs_log_item_t *mlip;
-
- if (lip->li_flags & XFS_LI_IN_AIL) {
- ailp = &(mp->m_ail);
- mlip = xfs_ail_min(ailp);
- dlip = xfs_ail_delete(ailp, lip);
- ASSERT(dlip == lip);
-
-
- lip->li_flags &= ~XFS_LI_IN_AIL;
- lip->li_lsn = 0;
- mp->m_ail_gen++;
-
- if (mlip == dlip) {
- mlip = xfs_ail_min(&(mp->m_ail));
- AIL_UNLOCK(mp, s);
- xfs_log_move_tail(mp, (mlip ? mlip->li_lsn : 0));
- } else {
- AIL_UNLOCK(mp, s);
- }
- }
- else {
- /*
- * If the file system is not being shutdown, we are in
- * serious trouble if we get to this stage.
- */
- if (XFS_FORCED_SHUTDOWN(mp))
- AIL_UNLOCK(mp, s);
- else {
- xfs_cmn_err(XFS_PTAG_AILDELETE, CE_ALERT, mp,
- "xfs_trans_delete_ail: attempting to delete a log item that is not in the AIL");
- AIL_UNLOCK(mp, s);
- xfs_force_shutdown(mp, XFS_CORRUPT_INCORE);
- }
- }
-}
-
-
-
-/*
- * Return the item in the AIL with the smallest lsn.
- * Return the current tree generation number for use
- * in calls to xfs_trans_next_ail().
- */
-xfs_log_item_t *
-xfs_trans_first_ail(
- xfs_mount_t *mp,
- int *gen)
-{
- xfs_log_item_t *lip;
-
- lip = xfs_ail_min(&(mp->m_ail));
- *gen = (int)mp->m_ail_gen;
-
- return (lip);
-}
-
-/*
- * If the generation count of the tree has not changed since the
- * caller last took something from the AIL, then return the elmt
- * in the tree which follows the one given. If the count has changed,
- * then return the minimum elmt of the AIL and bump the restarts counter
- * if one is given.
- */
-xfs_log_item_t *
-xfs_trans_next_ail(
- xfs_mount_t *mp,
- xfs_log_item_t *lip,
- int *gen,
- int *restarts)
-{
- xfs_log_item_t *nlip;
-
- ASSERT(mp && lip && gen);
- if (mp->m_ail_gen == *gen) {
- nlip = xfs_ail_next(&(mp->m_ail), lip);
- } else {
- nlip = xfs_ail_min(&(mp->m_ail));
- *gen = (int)mp->m_ail_gen;
- if (restarts != NULL) {
- XFS_STATS_INC(xs_push_ail_restarts);
- (*restarts)++;
- }
- }
-
- return (nlip);
-}
-
-
-/*
- * The active item list (AIL) is a doubly linked list of log
- * items sorted by ascending lsn. The base of the list is
- * a forw/back pointer pair embedded in the xfs mount structure.
- * The base is initialized with both pointers pointing to the
- * base. This case always needs to be distinguished, because
- * the base has no lsn to look at. We almost always insert
- * at the end of the list, so on inserts we search from the
- * end of the list to find where the new item belongs.
- */
-
-/*
- * Initialize the doubly linked list to point only to itself.
- */
-void
-xfs_trans_ail_init(
- xfs_mount_t *mp)
-{
- mp->m_ail.ail_forw = (xfs_log_item_t*)&(mp->m_ail);
- mp->m_ail.ail_back = (xfs_log_item_t*)&(mp->m_ail);
-}
-
-/*
- * Insert the given log item into the AIL.
- * We almost always insert at the end of the list, so on inserts
- * we search from the end of the list to find where the
- * new item belongs.
- */
-STATIC void
-xfs_ail_insert(
- xfs_ail_entry_t *base,
- xfs_log_item_t *lip)
-/* ARGSUSED */
-{
- xfs_log_item_t *next_lip;
-
- /*
- * If the list is empty, just insert the item.
- */
- if (base->ail_back == (xfs_log_item_t*)base) {
- base->ail_forw = lip;
- base->ail_back = lip;
- lip->li_ail.ail_forw = (xfs_log_item_t*)base;
- lip->li_ail.ail_back = (xfs_log_item_t*)base;
- return;
- }
-
- next_lip = base->ail_back;
- while ((next_lip != (xfs_log_item_t*)base) &&
- (XFS_LSN_CMP(next_lip->li_lsn, lip->li_lsn) > 0)) {
- next_lip = next_lip->li_ail.ail_back;
- }
- ASSERT((next_lip == (xfs_log_item_t*)base) ||
- (XFS_LSN_CMP(next_lip->li_lsn, lip->li_lsn) <= 0));
- lip->li_ail.ail_forw = next_lip->li_ail.ail_forw;
- lip->li_ail.ail_back = next_lip;
- next_lip->li_ail.ail_forw = lip;
- lip->li_ail.ail_forw->li_ail.ail_back = lip;
-
- xfs_ail_check(base);
- return;
-}
-
-/*
- * Delete the given item from the AIL. Return a pointer to the item.
- */
-/*ARGSUSED*/
-STATIC xfs_log_item_t *
-xfs_ail_delete(
- xfs_ail_entry_t *base,
- xfs_log_item_t *lip)
-/* ARGSUSED */
-{
- lip->li_ail.ail_forw->li_ail.ail_back = lip->li_ail.ail_back;
- lip->li_ail.ail_back->li_ail.ail_forw = lip->li_ail.ail_forw;
- lip->li_ail.ail_forw = NULL;
- lip->li_ail.ail_back = NULL;
-
- xfs_ail_check(base);
- return lip;
-}
-
-/*
- * Return a pointer to the first item in the AIL.
- * If the AIL is empty, then return NULL.
- */
-STATIC xfs_log_item_t *
-xfs_ail_min(
- xfs_ail_entry_t *base)
-/* ARGSUSED */
-{
- register xfs_log_item_t *forw = base->ail_forw;
- if (forw == (xfs_log_item_t*)base) {
- return NULL;
- }
- return forw;
-}
-
-/*
- * Return a pointer to the item which follows
- * the given item in the AIL. If the given item
- * is the last item in the list, then return NULL.
- */
-STATIC xfs_log_item_t *
-xfs_ail_next(
- xfs_ail_entry_t *base,
- xfs_log_item_t *lip)
-/* ARGSUSED */
-{
- if (lip->li_ail.ail_forw == (xfs_log_item_t*)base) {
- return NULL;
- }
- return lip->li_ail.ail_forw;
-
-}
-
-#ifdef DEBUG
-/*
- * Check that the list is sorted as it should be.
- */
-STATIC void
-xfs_ail_check(
- xfs_ail_entry_t *base)
-{
- xfs_log_item_t *lip;
- xfs_log_item_t *prev_lip;
-
- lip = base->ail_forw;
- if (lip == (xfs_log_item_t*)base) {
- /*
- * Make sure the pointers are correct when the list
- * is empty.
- */
- ASSERT(base->ail_back == (xfs_log_item_t*)base);
- return;
- }
-
- /*
- * Walk the list checking forward and backward pointers,
- * lsn ordering, and that every entry has the XFS_LI_IN_AIL
- * flag set.
- */
- prev_lip = (xfs_log_item_t*)base;
- while (lip != (xfs_log_item_t*)base) {
- if (prev_lip != (xfs_log_item_t*)base) {
- ASSERT(prev_lip->li_ail.ail_forw == lip);
- ASSERT(XFS_LSN_CMP(prev_lip->li_lsn, lip->li_lsn) <= 0);
- }
- ASSERT(lip->li_ail.ail_back == prev_lip);
- ASSERT((lip->li_flags & XFS_LI_IN_AIL) != 0);
- prev_lip = lip;
- lip = lip->li_ail.ail_forw;
- }
- ASSERT(lip == (xfs_log_item_t*)base);
- ASSERT(base->ail_back == prev_lip);
-}
-#endif /* DEBUG */
diff --git a/sys/gnu/fs/xfs/xfs_trans_buf.c b/sys/gnu/fs/xfs/xfs_trans_buf.c
deleted file mode 100644
index 0ed8d3f..0000000
--- a/sys/gnu/fs/xfs/xfs_trans_buf.c
+++ /dev/null
@@ -1,1113 +0,0 @@
-/*
- * Copyright (c) 2000-2002,2005 Silicon Graphics, Inc.
- * All Rights Reserved.
- *
- * 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.
- *
- * This program is distributed in the hope that it would 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 the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- */
-#include "xfs.h"
-#include "xfs_fs.h"
-#include "xfs_types.h"
-#include "xfs_bit.h"
-#include "xfs_log.h"
-#include "xfs_inum.h"
-#include "xfs_trans.h"
-#include "xfs_sb.h"
-#include "xfs_ag.h"
-#include "xfs_dir.h"
-#include "xfs_dir2.h"
-#include "xfs_dmapi.h"
-#include "xfs_mount.h"
-#include "xfs_bmap_btree.h"
-#include "xfs_alloc_btree.h"
-#include "xfs_ialloc_btree.h"
-#include "xfs_dir_sf.h"
-#include "xfs_dir2_sf.h"
-#include "xfs_attr_sf.h"
-#include "xfs_dinode.h"
-#include "xfs_inode.h"
-#include "xfs_buf_item.h"
-#include "xfs_trans_priv.h"
-#include "xfs_error.h"
-#include "xfs_rw.h"
-
-
-STATIC xfs_buf_t *xfs_trans_buf_item_match(xfs_trans_t *, xfs_buftarg_t *,
- xfs_daddr_t, int);
-STATIC xfs_buf_t *xfs_trans_buf_item_match_all(xfs_trans_t *, xfs_buftarg_t *,
- xfs_daddr_t, int);
-
-
-/*
- * Get and lock the buffer for the caller if it is not already
- * locked within the given transaction. If it is already locked
- * within the transaction, just increment its lock recursion count
- * and return a pointer to it.
- *
- * Use the fast path function xfs_trans_buf_item_match() or the buffer
- * cache routine incore_match() to find the buffer
- * if it is already owned by this transaction.
- *
- * If we don't already own the buffer, use get_buf() to get it.
- * If it doesn't yet have an associated xfs_buf_log_item structure,
- * then allocate one and add the item to this transaction.
- *
- * If the transaction pointer is NULL, make this just a normal
- * get_buf() call.
- */
-xfs_buf_t *
-xfs_trans_get_buf(xfs_trans_t *tp,
- xfs_buftarg_t *target_dev,
- xfs_daddr_t blkno,
- int len,
- uint flags)
-{
- xfs_buf_t *bp;
- xfs_buf_log_item_t *bip;
-
- if (flags == 0)
- flags = XFS_BUF_LOCK | XFS_BUF_MAPPED;
-
- /*
- * Default to a normal get_buf() call if the tp is NULL.
- */
- if (tp == NULL) {
- bp = xfs_buf_get_flags(target_dev, blkno, len,
- flags | BUF_BUSY);
- return(bp);
- }
-
- /*
- * If we find the buffer in the cache with this transaction
- * pointer in its b_fsprivate2 field, then we know we already
- * have it locked. In this case we just increment the lock
- * recursion count and return the buffer to the caller.
- */
- if (tp->t_items.lic_next == NULL) {
- bp = xfs_trans_buf_item_match(tp, target_dev, blkno, len);
- } else {
- bp = xfs_trans_buf_item_match_all(tp, target_dev, blkno, len);
- }
- if (bp != NULL) {
- ASSERT(XFS_BUF_VALUSEMA(bp) <= 0);
- if (XFS_FORCED_SHUTDOWN(tp->t_mountp)) {
- xfs_buftrace("TRANS GET RECUR SHUT", bp);
- XFS_BUF_SUPER_STALE(bp);
- }
- /*
- * If the buffer is stale then it was binval'ed
- * since last read. This doesn't matter since the
- * caller isn't allowed to use the data anyway.
- */
- else if (XFS_BUF_ISSTALE(bp)) {
- xfs_buftrace("TRANS GET RECUR STALE", bp);
- ASSERT(!XFS_BUF_ISDELAYWRITE(bp));
- }
- ASSERT(XFS_BUF_FSPRIVATE2(bp, xfs_trans_t *) == tp);
- bip = XFS_BUF_FSPRIVATE(bp, xfs_buf_log_item_t *);
- ASSERT(bip != NULL);
- ASSERT(atomic_read(&bip->bli_refcount) > 0);
- bip->bli_recur++;
- xfs_buftrace("TRANS GET RECUR", bp);
- xfs_buf_item_trace("GET RECUR", bip);
- return (bp);
- }
-
- /*
- * We always specify the BUF_BUSY flag within a transaction so
- * that get_buf does not try to push out a delayed write buffer
- * which might cause another transaction to take place (if the
- * buffer was delayed alloc). Such recursive transactions can
- * easily deadlock with our current transaction as well as cause
- * us to run out of stack space.
- */
- bp = xfs_buf_get_flags(target_dev, blkno, len, flags | BUF_BUSY);
- if (bp == NULL) {
- return NULL;
- }
-
- ASSERT(!XFS_BUF_GETERROR(bp));
-
- /*
- * The xfs_buf_log_item pointer is stored in b_fsprivate. If
- * it doesn't have one yet, then allocate one and initialize it.
- * The checks to see if one is there are in xfs_buf_item_init().
- */
- xfs_buf_item_init(bp, tp->t_mountp);
-
- /*
- * Set the recursion count for the buffer within this transaction
- * to 0.
- */
- bip = XFS_BUF_FSPRIVATE(bp, xfs_buf_log_item_t*);
- ASSERT(!(bip->bli_flags & XFS_BLI_STALE));
- ASSERT(!(bip->bli_format.blf_flags & XFS_BLI_CANCEL));
- ASSERT(!(bip->bli_flags & XFS_BLI_LOGGED));
- bip->bli_recur = 0;
-
- /*
- * Take a reference for this transaction on the buf item.
- */
- atomic_inc(&bip->bli_refcount);
-
- /*
- * Get a log_item_desc to point at the new item.
- */
- (void) xfs_trans_add_item(tp, (xfs_log_item_t*)bip);
-
- /*
- * Initialize b_fsprivate2 so we can find it with incore_match()
- * above.
- */
- XFS_BUF_SET_FSPRIVATE2(bp, tp);
-
- xfs_buftrace("TRANS GET", bp);
- xfs_buf_item_trace("GET", bip);
- return (bp);
-}
-
-/*
- * Get and lock the superblock buffer of this file system for the
- * given transaction.
- *
- * We don't need to use incore_match() here, because the superblock
- * buffer is a private buffer which we keep a pointer to in the
- * mount structure.
- */
-xfs_buf_t *
-xfs_trans_getsb(xfs_trans_t *tp,
- struct xfs_mount *mp,
- int flags)
-{
- xfs_buf_t *bp;
- xfs_buf_log_item_t *bip;
-
- /*
- * Default to just trying to lock the superblock buffer
- * if tp is NULL.
- */
- if (tp == NULL) {
- return (xfs_getsb(mp, flags));
- }
-
- /*
- * If the superblock buffer already has this transaction
- * pointer in its b_fsprivate2 field, then we know we already
- * have it locked. In this case we just increment the lock
- * recursion count and return the buffer to the caller.
- */
- bp = mp->m_sb_bp;
- if (XFS_BUF_FSPRIVATE2(bp, xfs_trans_t *) == tp) {
- bip = XFS_BUF_FSPRIVATE(bp, xfs_buf_log_item_t*);
- ASSERT(bip != NULL);
- ASSERT(atomic_read(&bip->bli_refcount) > 0);
- bip->bli_recur++;
- xfs_buf_item_trace("GETSB RECUR", bip);
- return (bp);
- }
-
- bp = xfs_getsb(mp, flags);
- if (bp == NULL) {
- return NULL;
- }
-
- /*
- * The xfs_buf_log_item pointer is stored in b_fsprivate. If
- * it doesn't have one yet, then allocate one and initialize it.
- * The checks to see if one is there are in xfs_buf_item_init().
- */
- xfs_buf_item_init(bp, mp);
-
- /*
- * Set the recursion count for the buffer within this transaction
- * to 0.
- */
- bip = XFS_BUF_FSPRIVATE(bp, xfs_buf_log_item_t*);
- ASSERT(!(bip->bli_flags & XFS_BLI_STALE));
- ASSERT(!(bip->bli_format.blf_flags & XFS_BLI_CANCEL));
- ASSERT(!(bip->bli_flags & XFS_BLI_LOGGED));
- bip->bli_recur = 0;
-
- /*
- * Take a reference for this transaction on the buf item.
- */
- atomic_inc(&bip->bli_refcount);
-
- /*
- * Get a log_item_desc to point at the new item.
- */
- (void) xfs_trans_add_item(tp, (xfs_log_item_t*)bip);
-
- /*
- * Initialize b_fsprivate2 so we can find it with incore_match()
- * above.
- */
- XFS_BUF_SET_FSPRIVATE2(bp, tp);
-
- xfs_buf_item_trace("GETSB", bip);
- return (bp);
-}
-
-#ifdef DEBUG
-xfs_buftarg_t *xfs_error_target;
-int xfs_do_error;
-int xfs_req_num;
-int xfs_error_mod = 33;
-#endif
-
-/*
- * Get and lock the buffer for the caller if it is not already
- * locked within the given transaction. If it has not yet been
- * read in, read it from disk. If it is already locked
- * within the transaction and already read in, just increment its
- * lock recursion count and return a pointer to it.
- *
- * Use the fast path function xfs_trans_buf_item_match() or the buffer
- * cache routine incore_match() to find the buffer
- * if it is already owned by this transaction.
- *
- * If we don't already own the buffer, use read_buf() to get it.
- * If it doesn't yet have an associated xfs_buf_log_item structure,
- * then allocate one and add the item to this transaction.
- *
- * If the transaction pointer is NULL, make this just a normal
- * read_buf() call.
- */
-int
-xfs_trans_read_buf(
- xfs_mount_t *mp,
- xfs_trans_t *tp,
- xfs_buftarg_t *target,
- xfs_daddr_t blkno,
- int len,
- uint flags,
- xfs_buf_t **bpp)
-{
- xfs_buf_t *bp;
- xfs_buf_log_item_t *bip;
- int error;
-
- if (flags == 0)
- flags = XFS_BUF_LOCK | XFS_BUF_MAPPED;
-
- /*
- * Default to a normal get_buf() call if the tp is NULL.
- */
- if (tp == NULL) {
- bp = xfs_buf_read_flags(target, blkno, len, flags | BUF_BUSY);
- if (!bp)
- return XFS_ERROR(ENOMEM);
-
- if ((bp != NULL) && (XFS_BUF_GETERROR(bp) != 0)) {
- xfs_ioerror_alert("xfs_trans_read_buf", mp,
- bp, blkno);
- error = XFS_BUF_GETERROR(bp);
- xfs_buf_relse(bp);
- return error;
- }
-#ifdef DEBUG
- if (xfs_do_error && (bp != NULL)) {
- if (xfs_error_target == target) {
- if (((xfs_req_num++) % xfs_error_mod) == 0) {
- xfs_buf_relse(bp);
- printk("Returning error!\n");
- return XFS_ERROR(EIO);
- }
- }
- }
-#endif
- if (XFS_FORCED_SHUTDOWN(mp))
- goto shutdown_abort;
- *bpp = bp;
- return 0;
- }
-
- /*
- * If we find the buffer in the cache with this transaction
- * pointer in its b_fsprivate2 field, then we know we already
- * have it locked. If it is already read in we just increment
- * the lock recursion count and return the buffer to the caller.
- * If the buffer is not yet read in, then we read it in, increment
- * the lock recursion count, and return it to the caller.
- */
- if (tp->t_items.lic_next == NULL) {
- bp = xfs_trans_buf_item_match(tp, target, blkno, len);
- } else {
- bp = xfs_trans_buf_item_match_all(tp, target, blkno, len);
- }
- if (bp != NULL) {
- ASSERT(XFS_BUF_VALUSEMA(bp) <= 0);
- ASSERT(XFS_BUF_FSPRIVATE2(bp, xfs_trans_t *) == tp);
- ASSERT(XFS_BUF_FSPRIVATE(bp, void *) != NULL);
- ASSERT((XFS_BUF_ISERROR(bp)) == 0);
- if (!(XFS_BUF_ISDONE(bp))) {
- xfs_buftrace("READ_BUF_INCORE !DONE", bp);
- ASSERT(!XFS_BUF_ISASYNC(bp));
- XFS_BUF_READ(bp);
- xfsbdstrat(tp->t_mountp, bp);
- xfs_iowait(bp);
- if (XFS_BUF_GETERROR(bp) != 0) {
- xfs_ioerror_alert("xfs_trans_read_buf", mp,
- bp, blkno);
- error = XFS_BUF_GETERROR(bp);
- xfs_buf_relse(bp);
- /*
- * We can gracefully recover from most
- * read errors. Ones we can't are those
- * that happen after the transaction's
- * already dirty.
- */
- if (tp->t_flags & XFS_TRANS_DIRTY)
- xfs_force_shutdown(tp->t_mountp,
- XFS_METADATA_IO_ERROR);
- return error;
- }
- }
- /*
- * We never locked this buf ourselves, so we shouldn't
- * brelse it either. Just get out.
- */
- if (XFS_FORCED_SHUTDOWN(mp)) {
- xfs_buftrace("READ_BUF_INCORE XFSSHUTDN", bp);
- *bpp = NULL;
- return XFS_ERROR(EIO);
- }
-
-
- bip = XFS_BUF_FSPRIVATE(bp, xfs_buf_log_item_t*);
- bip->bli_recur++;
-
- ASSERT(atomic_read(&bip->bli_refcount) > 0);
- xfs_buf_item_trace("READ RECUR", bip);
- *bpp = bp;
- return 0;
- }
-
- /*
- * We always specify the BUF_BUSY flag within a transaction so
- * that get_buf does not try to push out a delayed write buffer
- * which might cause another transaction to take place (if the
- * buffer was delayed alloc). Such recursive transactions can
- * easily deadlock with our current transaction as well as cause
- * us to run out of stack space.
- */
- bp = xfs_buf_read_flags(target, blkno, len, flags | BUF_BUSY);
- if (bp == NULL) {
- *bpp = NULL;
- return 0;
- }
- if (XFS_BUF_GETERROR(bp) != 0) {
- XFS_BUF_SUPER_STALE(bp);
- xfs_buftrace("READ ERROR", bp);
- error = XFS_BUF_GETERROR(bp);
-
- xfs_ioerror_alert("xfs_trans_read_buf", mp,
- bp, blkno);
- if (tp->t_flags & XFS_TRANS_DIRTY)
- xfs_force_shutdown(tp->t_mountp, XFS_METADATA_IO_ERROR);
- xfs_buf_relse(bp);
- return error;
- }
-#ifdef DEBUG
- if (xfs_do_error && !(tp->t_flags & XFS_TRANS_DIRTY)) {
- if (xfs_error_target == target) {
- if (((xfs_req_num++) % xfs_error_mod) == 0) {
- xfs_force_shutdown(tp->t_mountp,
- XFS_METADATA_IO_ERROR);
- xfs_buf_relse(bp);
- printk("Returning error in trans!\n");
- return XFS_ERROR(EIO);
- }
- }
- }
-#endif
- if (XFS_FORCED_SHUTDOWN(mp))
- goto shutdown_abort;
-
- /*
- * The xfs_buf_log_item pointer is stored in b_fsprivate. If
- * it doesn't have one yet, then allocate one and initialize it.
- * The checks to see if one is there are in xfs_buf_item_init().
- */
- xfs_buf_item_init(bp, tp->t_mountp);
-
- /*
- * Set the recursion count for the buffer within this transaction
- * to 0.
- */
- bip = XFS_BUF_FSPRIVATE(bp, xfs_buf_log_item_t*);
- ASSERT(!(bip->bli_flags & XFS_BLI_STALE));
- ASSERT(!(bip->bli_format.blf_flags & XFS_BLI_CANCEL));
- ASSERT(!(bip->bli_flags & XFS_BLI_LOGGED));
- bip->bli_recur = 0;
-
- /*
- * Take a reference for this transaction on the buf item.
- */
- atomic_inc(&bip->bli_refcount);
-
- /*
- * Get a log_item_desc to point at the new item.
- */
- (void) xfs_trans_add_item(tp, (xfs_log_item_t*)bip);
-
- /*
- * Initialize b_fsprivate2 so we can find it with incore_match()
- * above.
- */
- XFS_BUF_SET_FSPRIVATE2(bp, tp);
-
- xfs_buftrace("TRANS READ", bp);
- xfs_buf_item_trace("READ", bip);
- *bpp = bp;
- return 0;
-
-shutdown_abort:
- /*
- * the theory here is that buffer is good but we're
- * bailing out because the filesystem is being forcibly
- * shut down. So we should leave the b_flags alone since
- * the buffer's not staled and just get out.
- */
-#if defined(DEBUG)
- if (XFS_BUF_ISSTALE(bp) && XFS_BUF_ISDELAYWRITE(bp))
- cmn_err(CE_NOTE, "about to pop assert, bp == 0x%p", bp);
-#endif
- ASSERT((XFS_BUF_BFLAGS(bp) & (XFS_B_STALE|XFS_B_DELWRI)) !=
- (XFS_B_STALE|XFS_B_DELWRI));
-
- xfs_buftrace("READ_BUF XFSSHUTDN", bp);
- xfs_buf_relse(bp);
- *bpp = NULL;
- return XFS_ERROR(EIO);
-}
-
-
-/*
- * Release the buffer bp which was previously acquired with one of the
- * xfs_trans_... buffer allocation routines if the buffer has not
- * been modified within this transaction. If the buffer is modified
- * within this transaction, do decrement the recursion count but do
- * not release the buffer even if the count goes to 0. If the buffer is not
- * modified within the transaction, decrement the recursion count and
- * release the buffer if the recursion count goes to 0.
- *
- * If the buffer is to be released and it was not modified before
- * this transaction began, then free the buf_log_item associated with it.
- *
- * If the transaction pointer is NULL, make this just a normal
- * brelse() call.
- */
-void
-xfs_trans_brelse(xfs_trans_t *tp,
- xfs_buf_t *bp)
-{
- xfs_buf_log_item_t *bip;
- xfs_log_item_t *lip;
- xfs_log_item_desc_t *lidp;
-
- /*
- * Default to a normal brelse() call if the tp is NULL.
- */
- if (tp == NULL) {
- ASSERT(XFS_BUF_FSPRIVATE2(bp, void *) == NULL);
- /*
- * If there's a buf log item attached to the buffer,
- * then let the AIL know that the buffer is being
- * unlocked.
- */
- if (XFS_BUF_FSPRIVATE(bp, void *) != NULL) {
- lip = XFS_BUF_FSPRIVATE(bp, xfs_log_item_t *);
- if (lip->li_type == XFS_LI_BUF) {
- bip = XFS_BUF_FSPRIVATE(bp,xfs_buf_log_item_t*);
- xfs_trans_unlocked_item(
- bip->bli_item.li_mountp,
- lip);
- }
- }
- xfs_buf_relse(bp);
- return;
- }
-
- ASSERT(XFS_BUF_FSPRIVATE2(bp, xfs_trans_t *) == tp);
- bip = XFS_BUF_FSPRIVATE(bp, xfs_buf_log_item_t *);
- ASSERT(bip->bli_item.li_type == XFS_LI_BUF);
- ASSERT(!(bip->bli_flags & XFS_BLI_STALE));
- ASSERT(!(bip->bli_format.blf_flags & XFS_BLI_CANCEL));
- ASSERT(atomic_read(&bip->bli_refcount) > 0);
-
- /*
- * Find the item descriptor pointing to this buffer's
- * log item. It must be there.
- */
- lidp = xfs_trans_find_item(tp, (xfs_log_item_t*)bip);
- ASSERT(lidp != NULL);
-
- /*
- * If the release is just for a recursive lock,
- * then decrement the count and return.
- */
- if (bip->bli_recur > 0) {
- bip->bli_recur--;
- xfs_buf_item_trace("RELSE RECUR", bip);
- return;
- }
-
- /*
- * If the buffer is dirty within this transaction, we can't
- * release it until we commit.
- */
- if (lidp->lid_flags & XFS_LID_DIRTY) {
- xfs_buf_item_trace("RELSE DIRTY", bip);
- return;
- }
-
- /*
- * If the buffer has been invalidated, then we can't release
- * it until the transaction commits to disk unless it is re-dirtied
- * as part of this transaction. This prevents us from pulling
- * the item from the AIL before we should.
- */
- if (bip->bli_flags & XFS_BLI_STALE) {
- xfs_buf_item_trace("RELSE STALE", bip);
- return;
- }
-
- ASSERT(!(bip->bli_flags & XFS_BLI_LOGGED));
- xfs_buf_item_trace("RELSE", bip);
-
- /*
- * Free up the log item descriptor tracking the released item.
- */
- xfs_trans_free_item(tp, lidp);
-
- /*
- * Clear the hold flag in the buf log item if it is set.
- * We wouldn't want the next user of the buffer to
- * get confused.
- */
- if (bip->bli_flags & XFS_BLI_HOLD) {
- bip->bli_flags &= ~XFS_BLI_HOLD;
- }
-
- /*
- * Drop our reference to the buf log item.
- */
- atomic_dec(&bip->bli_refcount);
-
- /*
- * If the buf item is not tracking data in the log, then
- * we must free it before releasing the buffer back to the
- * free pool. Before releasing the buffer to the free pool,
- * clear the transaction pointer in b_fsprivate2 to dissolve
- * its relation to this transaction.
- */
- if (!xfs_buf_item_dirty(bip)) {
-/***
- ASSERT(bp->b_pincount == 0);
-***/
- ASSERT(atomic_read(&bip->bli_refcount) == 0);
- ASSERT(!(bip->bli_item.li_flags & XFS_LI_IN_AIL));
- ASSERT(!(bip->bli_flags & XFS_BLI_INODE_ALLOC_BUF));
- xfs_buf_item_relse(bp);
- bip = NULL;
- }
- XFS_BUF_SET_FSPRIVATE2(bp, NULL);
-
- /*
- * If we've still got a buf log item on the buffer, then
- * tell the AIL that the buffer is being unlocked.
- */
- if (bip != NULL) {
- xfs_trans_unlocked_item(bip->bli_item.li_mountp,
- (xfs_log_item_t*)bip);
- }
-
- xfs_buf_relse(bp);
- return;
-}
-
-/*
- * Add the locked buffer to the transaction.
- * The buffer must be locked, and it cannot be associated with any
- * transaction.
- *
- * If the buffer does not yet have a buf log item associated with it,
- * then allocate one for it. Then add the buf item to the transaction.
- */
-void
-xfs_trans_bjoin(xfs_trans_t *tp,
- xfs_buf_t *bp)
-{
- xfs_buf_log_item_t *bip;
-
- ASSERT(XFS_BUF_ISBUSY(bp));
- ASSERT(XFS_BUF_FSPRIVATE2(bp, void *) == NULL);
-
- /*
- * The xfs_buf_log_item pointer is stored in b_fsprivate. If
- * it doesn't have one yet, then allocate one and initialize it.
- * The checks to see if one is there are in xfs_buf_item_init().
- */
- xfs_buf_item_init(bp, tp->t_mountp);
- bip = XFS_BUF_FSPRIVATE(bp, xfs_buf_log_item_t *);
- ASSERT(!(bip->bli_flags & XFS_BLI_STALE));
- ASSERT(!(bip->bli_format.blf_flags & XFS_BLI_CANCEL));
- ASSERT(!(bip->bli_flags & XFS_BLI_LOGGED));
-
- /*
- * Take a reference for this transaction on the buf item.
- */
- atomic_inc(&bip->bli_refcount);
-
- /*
- * Get a log_item_desc to point at the new item.
- */
- (void) xfs_trans_add_item(tp, (xfs_log_item_t *)bip);
-
- /*
- * Initialize b_fsprivate2 so we can find it with incore_match()
- * in xfs_trans_get_buf() and friends above.
- */
- XFS_BUF_SET_FSPRIVATE2(bp, tp);
-
- xfs_buf_item_trace("BJOIN", bip);
-}
-
-/*
- * Mark the buffer as not needing to be unlocked when the buf item's
- * IOP_UNLOCK() routine is called. The buffer must already be locked
- * and associated with the given transaction.
- */
-/* ARGSUSED */
-void
-xfs_trans_bhold(xfs_trans_t *tp,
- xfs_buf_t *bp)
-{
- xfs_buf_log_item_t *bip;
-
- ASSERT(XFS_BUF_ISBUSY(bp));
- ASSERT(XFS_BUF_FSPRIVATE2(bp, xfs_trans_t *) == tp);
- ASSERT(XFS_BUF_FSPRIVATE(bp, void *) != NULL);
-
- bip = XFS_BUF_FSPRIVATE(bp, xfs_buf_log_item_t *);
- ASSERT(!(bip->bli_flags & XFS_BLI_STALE));
- ASSERT(!(bip->bli_format.blf_flags & XFS_BLI_CANCEL));
- ASSERT(atomic_read(&bip->bli_refcount) > 0);
- bip->bli_flags |= XFS_BLI_HOLD;
- xfs_buf_item_trace("BHOLD", bip);
-}
-
-/*
- * Cancel the previous buffer hold request made on this buffer
- * for this transaction.
- */
-void
-xfs_trans_bhold_release(xfs_trans_t *tp,
- xfs_buf_t *bp)
-{
- xfs_buf_log_item_t *bip;
-
- ASSERT(XFS_BUF_ISBUSY(bp));
- ASSERT(XFS_BUF_FSPRIVATE2(bp, xfs_trans_t *) == tp);
- ASSERT(XFS_BUF_FSPRIVATE(bp, void *) != NULL);
-
- bip = XFS_BUF_FSPRIVATE(bp, xfs_buf_log_item_t *);
- ASSERT(!(bip->bli_flags & XFS_BLI_STALE));
- ASSERT(!(bip->bli_format.blf_flags & XFS_BLI_CANCEL));
- ASSERT(atomic_read(&bip->bli_refcount) > 0);
- ASSERT(bip->bli_flags & XFS_BLI_HOLD);
- bip->bli_flags &= ~XFS_BLI_HOLD;
- xfs_buf_item_trace("BHOLD RELEASE", bip);
-}
-
-/*
- * This is called to mark bytes first through last inclusive of the given
- * buffer as needing to be logged when the transaction is committed.
- * The buffer must already be associated with the given transaction.
- *
- * First and last are numbers relative to the beginning of this buffer,
- * so the first byte in the buffer is numbered 0 regardless of the
- * value of b_blkno.
- */
-void
-xfs_trans_log_buf(xfs_trans_t *tp,
- xfs_buf_t *bp,
- uint first,
- uint last)
-{
- xfs_buf_log_item_t *bip;
- xfs_log_item_desc_t *lidp;
-
- ASSERT(XFS_BUF_ISBUSY(bp));
- ASSERT(XFS_BUF_FSPRIVATE2(bp, xfs_trans_t *) == tp);
- ASSERT(XFS_BUF_FSPRIVATE(bp, void *) != NULL);
- ASSERT((first <= last) && (last < XFS_BUF_COUNT(bp)));
- ASSERT((XFS_BUF_IODONE_FUNC(bp) == NULL) ||
- (XFS_BUF_IODONE_FUNC(bp) == xfs_buf_iodone_callbacks));
-
- /*
- * Mark the buffer as needing to be written out eventually,
- * and set its iodone function to remove the buffer's buf log
- * item from the AIL and free it when the buffer is flushed
- * to disk. See xfs_buf_attach_iodone() for more details
- * on li_cb and xfs_buf_iodone_callbacks().
- * If we end up aborting this transaction, we trap this buffer
- * inside the b_bdstrat callback so that this won't get written to
- * disk.
- */
- XFS_BUF_DELAYWRITE(bp);
- XFS_BUF_DONE(bp);
-
- bip = XFS_BUF_FSPRIVATE(bp, xfs_buf_log_item_t *);
- ASSERT(atomic_read(&bip->bli_refcount) > 0);
- XFS_BUF_SET_IODONE_FUNC(bp, xfs_buf_iodone_callbacks);
- bip->bli_item.li_cb = (void(*)(xfs_buf_t*,xfs_log_item_t*))xfs_buf_iodone;
-
- /*
- * If we invalidated the buffer within this transaction, then
- * cancel the invalidation now that we're dirtying the buffer
- * again. There are no races with the code in xfs_buf_item_unpin(),
- * because we have a reference to the buffer this entire time.
- */
- if (bip->bli_flags & XFS_BLI_STALE) {
- xfs_buf_item_trace("BLOG UNSTALE", bip);
- bip->bli_flags &= ~XFS_BLI_STALE;
- ASSERT(XFS_BUF_ISSTALE(bp));
- XFS_BUF_UNSTALE(bp);
- bip->bli_format.blf_flags &= ~XFS_BLI_CANCEL;
- }
-
- lidp = xfs_trans_find_item(tp, (xfs_log_item_t*)bip);
- ASSERT(lidp != NULL);
-
- tp->t_flags |= XFS_TRANS_DIRTY;
- lidp->lid_flags |= XFS_LID_DIRTY;
- lidp->lid_flags &= ~XFS_LID_BUF_STALE;
- bip->bli_flags |= XFS_BLI_LOGGED;
- xfs_buf_item_log(bip, first, last);
- xfs_buf_item_trace("BLOG", bip);
-}
-
-
-/*
- * This called to invalidate a buffer that is being used within
- * a transaction. Typically this is because the blocks in the
- * buffer are being freed, so we need to prevent it from being
- * written out when we're done. Allowing it to be written again
- * might overwrite data in the free blocks if they are reallocated
- * to a file.
- *
- * We prevent the buffer from being written out by clearing the
- * B_DELWRI flag. We can't always
- * get rid of the buf log item at this point, though, because
- * the buffer may still be pinned by another transaction. If that
- * is the case, then we'll wait until the buffer is committed to
- * disk for the last time (we can tell by the ref count) and
- * free it in xfs_buf_item_unpin(). Until it is cleaned up we
- * will keep the buffer locked so that the buffer and buf log item
- * are not reused.
- */
-void
-xfs_trans_binval(
- xfs_trans_t *tp,
- xfs_buf_t *bp)
-{
- xfs_log_item_desc_t *lidp;
- xfs_buf_log_item_t *bip;
-
- ASSERT(XFS_BUF_ISBUSY(bp));
- ASSERT(XFS_BUF_FSPRIVATE2(bp, xfs_trans_t *) == tp);
- ASSERT(XFS_BUF_FSPRIVATE(bp, void *) != NULL);
-
- bip = XFS_BUF_FSPRIVATE(bp, xfs_buf_log_item_t *);
- lidp = xfs_trans_find_item(tp, (xfs_log_item_t*)bip);
- ASSERT(lidp != NULL);
- ASSERT(atomic_read(&bip->bli_refcount) > 0);
-
- if (bip->bli_flags & XFS_BLI_STALE) {
- /*
- * If the buffer is already invalidated, then
- * just return.
- */
- ASSERT(!(XFS_BUF_ISDELAYWRITE(bp)));
- ASSERT(XFS_BUF_ISSTALE(bp));
- ASSERT(!(bip->bli_flags & (XFS_BLI_LOGGED | XFS_BLI_DIRTY)));
- ASSERT(!(bip->bli_format.blf_flags & XFS_BLI_INODE_BUF));
- ASSERT(bip->bli_format.blf_flags & XFS_BLI_CANCEL);
- ASSERT(lidp->lid_flags & XFS_LID_DIRTY);
- ASSERT(tp->t_flags & XFS_TRANS_DIRTY);
- xfs_buftrace("XFS_BINVAL RECUR", bp);
- xfs_buf_item_trace("BINVAL RECUR", bip);
- return;
- }
-
- /*
- * Clear the dirty bit in the buffer and set the STALE flag
- * in the buf log item. The STALE flag will be used in
- * xfs_buf_item_unpin() to determine if it should clean up
- * when the last reference to the buf item is given up.
- * We set the XFS_BLI_CANCEL flag in the buf log format structure
- * and log the buf item. This will be used at recovery time
- * to determine that copies of the buffer in the log before
- * this should not be replayed.
- * We mark the item descriptor and the transaction dirty so
- * that we'll hold the buffer until after the commit.
- *
- * Since we're invalidating the buffer, we also clear the state
- * about which parts of the buffer have been logged. We also
- * clear the flag indicating that this is an inode buffer since
- * the data in the buffer will no longer be valid.
- *
- * We set the stale bit in the buffer as well since we're getting
- * rid of it.
- */
- XFS_BUF_UNDELAYWRITE(bp);
- XFS_BUF_STALE(bp);
- bip->bli_flags |= XFS_BLI_STALE;
- bip->bli_flags &= ~(XFS_BLI_LOGGED | XFS_BLI_DIRTY);
- bip->bli_format.blf_flags &= ~XFS_BLI_INODE_BUF;
- bip->bli_format.blf_flags |= XFS_BLI_CANCEL;
- memset((char *)(bip->bli_format.blf_data_map), 0,
- (bip->bli_format.blf_map_size * sizeof(uint)));
- lidp->lid_flags |= XFS_LID_DIRTY|XFS_LID_BUF_STALE;
- tp->t_flags |= XFS_TRANS_DIRTY;
- xfs_buftrace("XFS_BINVAL", bp);
- xfs_buf_item_trace("BINVAL", bip);
-}
-
-/*
- * This call is used to indicate that the buffer contains on-disk
- * inodes which must be handled specially during recovery. They
- * require special handling because only the di_next_unlinked from
- * the inodes in the buffer should be recovered. The rest of the
- * data in the buffer is logged via the inodes themselves.
- *
- * All we do is set the XFS_BLI_INODE_BUF flag in the buffer's log
- * format structure so that we'll know what to do at recovery time.
- */
-/* ARGSUSED */
-void
-xfs_trans_inode_buf(
- xfs_trans_t *tp,
- xfs_buf_t *bp)
-{
- xfs_buf_log_item_t *bip;
-
- ASSERT(XFS_BUF_ISBUSY(bp));
- ASSERT(XFS_BUF_FSPRIVATE2(bp, xfs_trans_t *) == tp);
- ASSERT(XFS_BUF_FSPRIVATE(bp, void *) != NULL);
-
- bip = XFS_BUF_FSPRIVATE(bp, xfs_buf_log_item_t *);
- ASSERT(atomic_read(&bip->bli_refcount) > 0);
-
- bip->bli_format.blf_flags |= XFS_BLI_INODE_BUF;
-}
-
-/*
- * This call is used to indicate that the buffer is going to
- * be staled and was an inode buffer. This means it gets
- * special processing during unpin - where any inodes
- * associated with the buffer should be removed from ail.
- * There is also special processing during recovery,
- * any replay of the inodes in the buffer needs to be
- * prevented as the buffer may have been reused.
- */
-void
-xfs_trans_stale_inode_buf(
- xfs_trans_t *tp,
- xfs_buf_t *bp)
-{
- xfs_buf_log_item_t *bip;
-
- ASSERT(XFS_BUF_ISBUSY(bp));
- ASSERT(XFS_BUF_FSPRIVATE2(bp, xfs_trans_t *) == tp);
- ASSERT(XFS_BUF_FSPRIVATE(bp, void *) != NULL);
-
- bip = XFS_BUF_FSPRIVATE(bp, xfs_buf_log_item_t *);
- ASSERT(atomic_read(&bip->bli_refcount) > 0);
-
- bip->bli_flags |= XFS_BLI_STALE_INODE;
- bip->bli_item.li_cb = (void(*)(xfs_buf_t*,xfs_log_item_t*))
- xfs_buf_iodone;
-}
-
-
-
-/*
- * Mark the buffer as being one which contains newly allocated
- * inodes. We need to make sure that even if this buffer is
- * relogged as an 'inode buf' we still recover all of the inode
- * images in the face of a crash. This works in coordination with
- * xfs_buf_item_committed() to ensure that the buffer remains in the
- * AIL at its original location even after it has been relogged.
- */
-/* ARGSUSED */
-void
-xfs_trans_inode_alloc_buf(
- xfs_trans_t *tp,
- xfs_buf_t *bp)
-{
- xfs_buf_log_item_t *bip;
-
- ASSERT(XFS_BUF_ISBUSY(bp));
- ASSERT(XFS_BUF_FSPRIVATE2(bp, xfs_trans_t *) == tp);
- ASSERT(XFS_BUF_FSPRIVATE(bp, void *) != NULL);
-
- bip = XFS_BUF_FSPRIVATE(bp, xfs_buf_log_item_t *);
- ASSERT(atomic_read(&bip->bli_refcount) > 0);
-
- bip->bli_flags |= XFS_BLI_INODE_ALLOC_BUF;
-}
-
-
-/*
- * Similar to xfs_trans_inode_buf(), this marks the buffer as a cluster of
- * dquots. However, unlike in inode buffer recovery, dquot buffers get
- * recovered in their entirety. (Hence, no XFS_BLI_DQUOT_ALLOC_BUF flag).
- * The only thing that makes dquot buffers different from regular
- * buffers is that we must not replay dquot bufs when recovering
- * if a _corresponding_ quotaoff has happened. We also have to distinguish
- * between usr dquot bufs and grp dquot bufs, because usr and grp quotas
- * can be turned off independently.
- */
-/* ARGSUSED */
-void
-xfs_trans_dquot_buf(
- xfs_trans_t *tp,
- xfs_buf_t *bp,
- uint type)
-{
- xfs_buf_log_item_t *bip;
-
- ASSERT(XFS_BUF_ISBUSY(bp));
- ASSERT(XFS_BUF_FSPRIVATE2(bp, xfs_trans_t *) == tp);
- ASSERT(XFS_BUF_FSPRIVATE(bp, void *) != NULL);
- ASSERT(type == XFS_BLI_UDQUOT_BUF ||
- type == XFS_BLI_PDQUOT_BUF ||
- type == XFS_BLI_GDQUOT_BUF);
-
- bip = XFS_BUF_FSPRIVATE(bp, xfs_buf_log_item_t *);
- ASSERT(atomic_read(&bip->bli_refcount) > 0);
-
- bip->bli_format.blf_flags |= type;
-}
-
-/*
- * Check to see if a buffer matching the given parameters is already
- * a part of the given transaction. Only check the first, embedded
- * chunk, since we don't want to spend all day scanning large transactions.
- */
-STATIC xfs_buf_t *
-xfs_trans_buf_item_match(
- xfs_trans_t *tp,
- xfs_buftarg_t *target,
- xfs_daddr_t blkno,
- int len)
-{
- xfs_log_item_chunk_t *licp;
- xfs_log_item_desc_t *lidp;
- xfs_buf_log_item_t *blip;
- xfs_buf_t *bp;
- int i;
-
- bp = NULL;
- len = BBTOB(len);
- licp = &tp->t_items;
- if (!XFS_LIC_ARE_ALL_FREE(licp)) {
- for (i = 0; i < licp->lic_unused; i++) {
- /*
- * Skip unoccupied slots.
- */
- if (XFS_LIC_ISFREE(licp, i)) {
- continue;
- }
-
- lidp = XFS_LIC_SLOT(licp, i);
- blip = (xfs_buf_log_item_t *)lidp->lid_item;
- if (blip->bli_item.li_type != XFS_LI_BUF) {
- continue;
- }
-
- bp = blip->bli_buf;
- if ((XFS_BUF_TARGET(bp) == target) &&
- (XFS_BUF_ADDR(bp) == blkno) &&
- (XFS_BUF_COUNT(bp) == len)) {
- /*
- * We found it. Break out and
- * return the pointer to the buffer.
- */
- break;
- } else {
- bp = NULL;
- }
- }
- }
- return bp;
-}
-
-/*
- * Check to see if a buffer matching the given parameters is already
- * a part of the given transaction. Check all the chunks, we
- * want to be thorough.
- */
-STATIC xfs_buf_t *
-xfs_trans_buf_item_match_all(
- xfs_trans_t *tp,
- xfs_buftarg_t *target,
- xfs_daddr_t blkno,
- int len)
-{
- xfs_log_item_chunk_t *licp;
- xfs_log_item_desc_t *lidp;
- xfs_buf_log_item_t *blip;
- xfs_buf_t *bp;
- int i;
-
- bp = NULL;
- len = BBTOB(len);
- for (licp = &tp->t_items; licp != NULL; licp = licp->lic_next) {
- if (XFS_LIC_ARE_ALL_FREE(licp)) {
- ASSERT(licp == &tp->t_items);
- ASSERT(licp->lic_next == NULL);
- return NULL;
- }
- for (i = 0; i < licp->lic_unused; i++) {
- /*
- * Skip unoccupied slots.
- */
- if (XFS_LIC_ISFREE(licp, i)) {
- continue;
- }
-
- lidp = XFS_LIC_SLOT(licp, i);
- blip = (xfs_buf_log_item_t *)lidp->lid_item;
- if (blip->bli_item.li_type != XFS_LI_BUF) {
- continue;
- }
-
- bp = blip->bli_buf;
- if ((XFS_BUF_TARGET(bp) == target) &&
- (XFS_BUF_ADDR(bp) == blkno) &&
- (XFS_BUF_COUNT(bp) == len)) {
- /*
- * We found it. Break out and
- * return the pointer to the buffer.
- */
- return bp;
- }
- }
- }
- return NULL;
-}
-
diff --git a/sys/gnu/fs/xfs/xfs_trans_extfree.c b/sys/gnu/fs/xfs/xfs_trans_extfree.c
deleted file mode 100644
index 7d7d627..0000000
--- a/sys/gnu/fs/xfs/xfs_trans_extfree.c
+++ /dev/null
@@ -1,141 +0,0 @@
-/*
- * Copyright (c) 2000,2005 Silicon Graphics, Inc.
- * All Rights Reserved.
- *
- * 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.
- *
- * This program is distributed in the hope that it would 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 the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- */
-#include "xfs.h"
-#include "xfs_fs.h"
-#include "xfs_types.h"
-#include "xfs_log.h"
-#include "xfs_inum.h"
-#include "xfs_trans.h"
-#include "xfs_sb.h"
-#include "xfs_dir.h"
-#include "xfs_dmapi.h"
-#include "xfs_mount.h"
-#include "xfs_trans_priv.h"
-#include "xfs_extfree_item.h"
-
-/*
- * This routine is called to allocate an "extent free intention"
- * log item that will hold nextents worth of extents. The
- * caller must use all nextents extents, because we are not
- * flexible about this at all.
- */
-xfs_efi_log_item_t *
-xfs_trans_get_efi(xfs_trans_t *tp,
- uint nextents)
-{
- xfs_efi_log_item_t *efip;
-
- ASSERT(tp != NULL);
- ASSERT(nextents > 0);
-
- efip = xfs_efi_init(tp->t_mountp, nextents);
- ASSERT(efip != NULL);
-
- /*
- * Get a log_item_desc to point at the new item.
- */
- (void) xfs_trans_add_item(tp, (xfs_log_item_t*)efip);
-
- return (efip);
-}
-
-/*
- * This routine is called to indicate that the described
- * extent is to be logged as needing to be freed. It should
- * be called once for each extent to be freed.
- */
-void
-xfs_trans_log_efi_extent(xfs_trans_t *tp,
- xfs_efi_log_item_t *efip,
- xfs_fsblock_t start_block,
- xfs_extlen_t ext_len)
-{
- xfs_log_item_desc_t *lidp;
- uint next_extent;
- xfs_extent_t *extp;
-
- lidp = xfs_trans_find_item(tp, (xfs_log_item_t*)efip);
- ASSERT(lidp != NULL);
-
- tp->t_flags |= XFS_TRANS_DIRTY;
- lidp->lid_flags |= XFS_LID_DIRTY;
-
- next_extent = efip->efi_next_extent;
- ASSERT(next_extent < efip->efi_format.efi_nextents);
- extp = &(efip->efi_format.efi_extents[next_extent]);
- extp->ext_start = start_block;
- extp->ext_len = ext_len;
- efip->efi_next_extent++;
-}
-
-
-/*
- * This routine is called to allocate an "extent free done"
- * log item that will hold nextents worth of extents. The
- * caller must use all nextents extents, because we are not
- * flexible about this at all.
- */
-xfs_efd_log_item_t *
-xfs_trans_get_efd(xfs_trans_t *tp,
- xfs_efi_log_item_t *efip,
- uint nextents)
-{
- xfs_efd_log_item_t *efdp;
-
- ASSERT(tp != NULL);
- ASSERT(nextents > 0);
-
- efdp = xfs_efd_init(tp->t_mountp, efip, nextents);
- ASSERT(efdp != NULL);
-
- /*
- * Get a log_item_desc to point at the new item.
- */
- (void) xfs_trans_add_item(tp, (xfs_log_item_t*)efdp);
-
- return (efdp);
-}
-
-/*
- * This routine is called to indicate that the described
- * extent is to be logged as having been freed. It should
- * be called once for each extent freed.
- */
-void
-xfs_trans_log_efd_extent(xfs_trans_t *tp,
- xfs_efd_log_item_t *efdp,
- xfs_fsblock_t start_block,
- xfs_extlen_t ext_len)
-{
- xfs_log_item_desc_t *lidp;
- uint next_extent;
- xfs_extent_t *extp;
-
- lidp = xfs_trans_find_item(tp, (xfs_log_item_t*)efdp);
- ASSERT(lidp != NULL);
-
- tp->t_flags |= XFS_TRANS_DIRTY;
- lidp->lid_flags |= XFS_LID_DIRTY;
-
- next_extent = efdp->efd_next_extent;
- ASSERT(next_extent < efdp->efd_format.efd_nextents);
- extp = &(efdp->efd_format.efd_extents[next_extent]);
- extp->ext_start = start_block;
- extp->ext_len = ext_len;
- efdp->efd_next_extent++;
-}
diff --git a/sys/gnu/fs/xfs/xfs_trans_inode.c b/sys/gnu/fs/xfs/xfs_trans_inode.c
deleted file mode 100644
index 7c5894d..0000000
--- a/sys/gnu/fs/xfs/xfs_trans_inode.c
+++ /dev/null
@@ -1,310 +0,0 @@
-/*
- * Copyright (c) 2000,2005 Silicon Graphics, Inc.
- * All Rights Reserved.
- *
- * 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.
- *
- * This program is distributed in the hope that it would 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 the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- */
-#include "xfs.h"
-#include "xfs_fs.h"
-#include "xfs_types.h"
-#include "xfs_bit.h"
-#include "xfs_log.h"
-#include "xfs_inum.h"
-#include "xfs_trans.h"
-#include "xfs_sb.h"
-#include "xfs_ag.h"
-#include "xfs_dir.h"
-#include "xfs_dir2.h"
-#include "xfs_dmapi.h"
-#include "xfs_mount.h"
-#include "xfs_bmap_btree.h"
-#include "xfs_alloc_btree.h"
-#include "xfs_ialloc_btree.h"
-#include "xfs_dir_sf.h"
-#include "xfs_dir2_sf.h"
-#include "xfs_attr_sf.h"
-#include "xfs_dinode.h"
-#include "xfs_inode.h"
-#include "xfs_btree.h"
-#include "xfs_ialloc.h"
-#include "xfs_trans_priv.h"
-#include "xfs_inode_item.h"
-
-#ifdef XFS_TRANS_DEBUG
-STATIC void
-xfs_trans_inode_broot_debug(
- xfs_inode_t *ip);
-#else
-#define xfs_trans_inode_broot_debug(ip)
-#endif
-
-
-/*
- * Get and lock the inode for the caller if it is not already
- * locked within the given transaction. If it is already locked
- * within the transaction, just increment its lock recursion count
- * and return a pointer to it.
- *
- * For an inode to be locked in a transaction, the inode lock, as
- * opposed to the io lock, must be taken exclusively. This ensures
- * that the inode can be involved in only 1 transaction at a time.
- * Lock recursion is handled on the io lock, but only for lock modes
- * of equal or lesser strength. That is, you can recur on the io lock
- * held EXCL with a SHARED request but not vice versa. Also, if
- * the inode is already a part of the transaction then you cannot
- * go from not holding the io lock to having it EXCL or SHARED.
- *
- * Use the inode cache routine xfs_inode_incore() to find the inode
- * if it is already owned by this transaction.
- *
- * If we don't already own the inode, use xfs_iget() to get it.
- * Since the inode log item structure is embedded in the incore
- * inode structure and is initialized when the inode is brought
- * into memory, there is nothing to do with it here.
- *
- * If the given transaction pointer is NULL, just call xfs_iget().
- * This simplifies code which must handle both cases.
- */
-int
-xfs_trans_iget(
- xfs_mount_t *mp,
- xfs_trans_t *tp,
- xfs_ino_t ino,
- uint flags,
- uint lock_flags,
- xfs_inode_t **ipp)
-{
- int error;
- xfs_inode_t *ip;
- xfs_inode_log_item_t *iip;
-
- /*
- * If the transaction pointer is NULL, just call the normal
- * xfs_iget().
- */
- if (tp == NULL)
- return xfs_iget(mp, NULL, ino, flags, lock_flags, ipp, 0);
-
- /*
- * If we find the inode in core with this transaction
- * pointer in its i_transp field, then we know we already
- * have it locked. In this case we just increment the lock
- * recursion count and return the inode to the caller.
- * Assert that the inode is already locked in the mode requested
- * by the caller. We cannot do lock promotions yet, so
- * die if someone gets this wrong.
- */
- if ((ip = xfs_inode_incore(tp->t_mountp, ino, tp)) != NULL) {
- /*
- * Make sure that the inode lock is held EXCL and
- * that the io lock is never upgraded when the inode
- * is already a part of the transaction.
- */
- ASSERT(ip->i_itemp != NULL);
- ASSERT(lock_flags & XFS_ILOCK_EXCL);
- ASSERT(ismrlocked(&ip->i_lock, MR_UPDATE));
- ASSERT((!(lock_flags & XFS_IOLOCK_EXCL)) ||
- ismrlocked(&ip->i_iolock, MR_UPDATE));
- ASSERT((!(lock_flags & XFS_IOLOCK_EXCL)) ||
- (ip->i_itemp->ili_flags & XFS_ILI_IOLOCKED_EXCL));
- ASSERT((!(lock_flags & XFS_IOLOCK_SHARED)) ||
- ismrlocked(&ip->i_iolock, (MR_UPDATE | MR_ACCESS)));
- ASSERT((!(lock_flags & XFS_IOLOCK_SHARED)) ||
- (ip->i_itemp->ili_flags & XFS_ILI_IOLOCKED_ANY));
-
- if (lock_flags & (XFS_IOLOCK_SHARED | XFS_IOLOCK_EXCL)) {
- ip->i_itemp->ili_iolock_recur++;
- }
- if (lock_flags & XFS_ILOCK_EXCL) {
- ip->i_itemp->ili_ilock_recur++;
- }
- *ipp = ip;
- return 0;
- }
-
- ASSERT(lock_flags & XFS_ILOCK_EXCL);
- error = xfs_iget(tp->t_mountp, tp, ino, flags, lock_flags, &ip, 0);
- if (error) {
- return error;
- }
- ASSERT(ip != NULL);
-
- /*
- * Get a log_item_desc to point at the new item.
- */
- if (ip->i_itemp == NULL)
- xfs_inode_item_init(ip, mp);
- iip = ip->i_itemp;
- (void) xfs_trans_add_item(tp, (xfs_log_item_t *)(iip));
-
- xfs_trans_inode_broot_debug(ip);
-
- /*
- * If the IO lock has been acquired, mark that in
- * the inode log item so we'll know to unlock it
- * when the transaction commits.
- */
- ASSERT(iip->ili_flags == 0);
- if (lock_flags & XFS_IOLOCK_EXCL) {
- iip->ili_flags |= XFS_ILI_IOLOCKED_EXCL;
- } else if (lock_flags & XFS_IOLOCK_SHARED) {
- iip->ili_flags |= XFS_ILI_IOLOCKED_SHARED;
- }
-
- /*
- * Initialize i_transp so we can find it with xfs_inode_incore()
- * above.
- */
- ip->i_transp = tp;
-
- *ipp = ip;
- return 0;
-}
-
-/*
- * Add the locked inode to the transaction.
- * The inode must be locked, and it cannot be associated with any
- * transaction. The caller must specify the locks already held
- * on the inode.
- */
-void
-xfs_trans_ijoin(
- xfs_trans_t *tp,
- xfs_inode_t *ip,
- uint lock_flags)
-{
- xfs_inode_log_item_t *iip;
-
- ASSERT(ip->i_transp == NULL);
- ASSERT(ismrlocked(&ip->i_lock, MR_UPDATE));
- ASSERT(lock_flags & XFS_ILOCK_EXCL);
- if (ip->i_itemp == NULL)
- xfs_inode_item_init(ip, ip->i_mount);
- iip = ip->i_itemp;
- ASSERT(iip->ili_flags == 0);
- ASSERT(iip->ili_ilock_recur == 0);
- ASSERT(iip->ili_iolock_recur == 0);
-
- /*
- * Get a log_item_desc to point at the new item.
- */
- (void) xfs_trans_add_item(tp, (xfs_log_item_t*)(iip));
-
- xfs_trans_inode_broot_debug(ip);
-
- /*
- * If the IO lock is already held, mark that in the inode log item.
- */
- if (lock_flags & XFS_IOLOCK_EXCL) {
- iip->ili_flags |= XFS_ILI_IOLOCKED_EXCL;
- } else if (lock_flags & XFS_IOLOCK_SHARED) {
- iip->ili_flags |= XFS_ILI_IOLOCKED_SHARED;
- }
-
- /*
- * Initialize i_transp so we can find it with xfs_inode_incore()
- * in xfs_trans_iget() above.
- */
- ip->i_transp = tp;
-}
-
-
-
-/*
- * Mark the inode as not needing to be unlocked when the inode item's
- * IOP_UNLOCK() routine is called. The inode must already be locked
- * and associated with the given transaction.
- */
-/*ARGSUSED*/
-void
-xfs_trans_ihold(
- xfs_trans_t *tp,
- xfs_inode_t *ip)
-{
- ASSERT(ip->i_transp == tp);
- ASSERT(ip->i_itemp != NULL);
- ASSERT(ismrlocked(&ip->i_lock, MR_UPDATE));
-
- ip->i_itemp->ili_flags |= XFS_ILI_HOLD;
-}
-
-
-/*
- * This is called to mark the fields indicated in fieldmask as needing
- * to be logged when the transaction is committed. The inode must
- * already be associated with the given transaction.
- *
- * The values for fieldmask are defined in xfs_inode_item.h. We always
- * log all of the core inode if any of it has changed, and we always log
- * all of the inline data/extents/b-tree root if any of them has changed.
- */
-void
-xfs_trans_log_inode(
- xfs_trans_t *tp,
- xfs_inode_t *ip,
- uint flags)
-{
- xfs_log_item_desc_t *lidp;
-
- ASSERT(ip->i_transp == tp);
- ASSERT(ip->i_itemp != NULL);
- ASSERT(ismrlocked(&ip->i_lock, MR_UPDATE));
-
- lidp = xfs_trans_find_item(tp, (xfs_log_item_t*)(ip->i_itemp));
- ASSERT(lidp != NULL);
-
- tp->t_flags |= XFS_TRANS_DIRTY;
- lidp->lid_flags |= XFS_LID_DIRTY;
-
- /*
- * Always OR in the bits from the ili_last_fields field.
- * This is to coordinate with the xfs_iflush() and xfs_iflush_done()
- * routines in the eventual clearing of the ilf_fields bits.
- * See the big comment in xfs_iflush() for an explanation of
- * this coordination mechanism.
- */
- flags |= ip->i_itemp->ili_last_fields;
- ip->i_itemp->ili_format.ilf_fields |= flags;
-}
-
-#ifdef XFS_TRANS_DEBUG
-/*
- * Keep track of the state of the inode btree root to make sure we
- * log it properly.
- */
-STATIC void
-xfs_trans_inode_broot_debug(
- xfs_inode_t *ip)
-{
- xfs_inode_log_item_t *iip;
-
- ASSERT(ip->i_itemp != NULL);
- iip = ip->i_itemp;
- if (iip->ili_root_size != 0) {
- ASSERT(iip->ili_orig_root != NULL);
- kmem_free(iip->ili_orig_root, iip->ili_root_size);
- iip->ili_root_size = 0;
- iip->ili_orig_root = NULL;
- }
- if (ip->i_d.di_format == XFS_DINODE_FMT_BTREE) {
- ASSERT((ip->i_df.if_broot != NULL) &&
- (ip->i_df.if_broot_bytes > 0));
- iip->ili_root_size = ip->i_df.if_broot_bytes;
- iip->ili_orig_root =
- (char*)kmem_alloc(iip->ili_root_size, KM_SLEEP);
- memcpy(iip->ili_orig_root, (char*)(ip->i_df.if_broot),
- iip->ili_root_size);
- }
-}
-#endif
diff --git a/sys/gnu/fs/xfs/xfs_trans_item.c b/sys/gnu/fs/xfs/xfs_trans_item.c
deleted file mode 100644
index 925fb3a..0000000
--- a/sys/gnu/fs/xfs/xfs_trans_item.c
+++ /dev/null
@@ -1,539 +0,0 @@
-/*
- * Copyright (c) 2000-2002,2005 Silicon Graphics, Inc.
- * All Rights Reserved.
- *
- * 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.
- *
- * This program is distributed in the hope that it would 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 the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- */
-#include "xfs.h"
-#include "xfs_fs.h"
-#include "xfs_types.h"
-#include "xfs_log.h"
-#include "xfs_inum.h"
-#include "xfs_trans.h"
-#include "xfs_trans_priv.h"
-
-STATIC int xfs_trans_unlock_chunk(xfs_log_item_chunk_t *,
- int, int, xfs_lsn_t);
-
-/*
- * This is called to add the given log item to the transaction's
- * list of log items. It must find a free log item descriptor
- * or allocate a new one and add the item to that descriptor.
- * The function returns a pointer to item descriptor used to point
- * to the new item. The log item will now point to its new descriptor
- * with its li_desc field.
- */
-xfs_log_item_desc_t *
-xfs_trans_add_item(xfs_trans_t *tp, xfs_log_item_t *lip)
-{
- xfs_log_item_desc_t *lidp;
- xfs_log_item_chunk_t *licp;
- int i=0;
-
- /*
- * If there are no free descriptors, allocate a new chunk
- * of them and put it at the front of the chunk list.
- */
- if (tp->t_items_free == 0) {
- licp = (xfs_log_item_chunk_t*)
- kmem_alloc(sizeof(xfs_log_item_chunk_t), KM_SLEEP);
- ASSERT(licp != NULL);
- /*
- * Initialize the chunk, and then
- * claim the first slot in the newly allocated chunk.
- */
- XFS_LIC_INIT(licp);
- XFS_LIC_CLAIM(licp, 0);
- licp->lic_unused = 1;
- XFS_LIC_INIT_SLOT(licp, 0);
- lidp = XFS_LIC_SLOT(licp, 0);
-
- /*
- * Link in the new chunk and update the free count.
- */
- licp->lic_next = tp->t_items.lic_next;
- tp->t_items.lic_next = licp;
- tp->t_items_free = XFS_LIC_NUM_SLOTS - 1;
-
- /*
- * Initialize the descriptor and the generic portion
- * of the log item.
- *
- * Point the new slot at this item and return it.
- * Also point the log item at its currently active
- * descriptor and set the item's mount pointer.
- */
- lidp->lid_item = lip;
- lidp->lid_flags = 0;
- lidp->lid_size = 0;
- lip->li_desc = lidp;
- lip->li_mountp = tp->t_mountp;
- return lidp;
- }
-
- /*
- * Find the free descriptor. It is somewhere in the chunklist
- * of descriptors.
- */
- licp = &tp->t_items;
- while (licp != NULL) {
- if (XFS_LIC_VACANCY(licp)) {
- if (licp->lic_unused <= XFS_LIC_MAX_SLOT) {
- i = licp->lic_unused;
- ASSERT(XFS_LIC_ISFREE(licp, i));
- break;
- }
- for (i = 0; i <= XFS_LIC_MAX_SLOT; i++) {
- if (XFS_LIC_ISFREE(licp, i))
- break;
- }
- ASSERT(i <= XFS_LIC_MAX_SLOT);
- break;
- }
- licp = licp->lic_next;
- }
- ASSERT(licp != NULL);
- /*
- * If we find a free descriptor, claim it,
- * initialize it, and return it.
- */
- XFS_LIC_CLAIM(licp, i);
- if (licp->lic_unused <= i) {
- licp->lic_unused = i + 1;
- XFS_LIC_INIT_SLOT(licp, i);
- }
- lidp = XFS_LIC_SLOT(licp, i);
- tp->t_items_free--;
- lidp->lid_item = lip;
- lidp->lid_flags = 0;
- lidp->lid_size = 0;
- lip->li_desc = lidp;
- lip->li_mountp = tp->t_mountp;
- return lidp;
-}
-
-/*
- * Free the given descriptor.
- *
- * This requires setting the bit in the chunk's free mask corresponding
- * to the given slot.
- */
-void
-xfs_trans_free_item(xfs_trans_t *tp, xfs_log_item_desc_t *lidp)
-{
- uint slot;
- xfs_log_item_chunk_t *licp;
- xfs_log_item_chunk_t **licpp;
-
- slot = XFS_LIC_DESC_TO_SLOT(lidp);
- licp = XFS_LIC_DESC_TO_CHUNK(lidp);
- XFS_LIC_RELSE(licp, slot);
- lidp->lid_item->li_desc = NULL;
- tp->t_items_free++;
-
- /*
- * If there are no more used items in the chunk and this is not
- * the chunk embedded in the transaction structure, then free
- * the chunk. First pull it from the chunk list and then
- * free it back to the heap. We didn't bother with a doubly
- * linked list here because the lists should be very short
- * and this is not a performance path. It's better to save
- * the memory of the extra pointer.
- *
- * Also decrement the transaction structure's count of free items
- * by the number in a chunk since we are freeing an empty chunk.
- */
- if (XFS_LIC_ARE_ALL_FREE(licp) && (licp != &(tp->t_items))) {
- licpp = &(tp->t_items.lic_next);
- while (*licpp != licp) {
- ASSERT(*licpp != NULL);
- licpp = &((*licpp)->lic_next);
- }
- *licpp = licp->lic_next;
- kmem_free(licp, sizeof(xfs_log_item_chunk_t));
- tp->t_items_free -= XFS_LIC_NUM_SLOTS;
- }
-}
-
-/*
- * This is called to find the descriptor corresponding to the given
- * log item. It returns a pointer to the descriptor.
- * The log item MUST have a corresponding descriptor in the given
- * transaction. This routine does not return NULL, it panics.
- *
- * The descriptor pointer is kept in the log item's li_desc field.
- * Just return it.
- */
-/*ARGSUSED*/
-xfs_log_item_desc_t *
-xfs_trans_find_item(xfs_trans_t *tp, xfs_log_item_t *lip)
-{
- ASSERT(lip->li_desc != NULL);
-
- return lip->li_desc;
-}
-
-
-/*
- * Return a pointer to the first descriptor in the chunk list.
- * This does not return NULL if there are none, it panics.
- *
- * The first descriptor must be in either the first or second chunk.
- * This is because the only chunk allowed to be empty is the first.
- * All others are freed when they become empty.
- *
- * At some point this and xfs_trans_next_item() should be optimized
- * to quickly look at the mask to determine if there is anything to
- * look at.
- */
-xfs_log_item_desc_t *
-xfs_trans_first_item(xfs_trans_t *tp)
-{
- xfs_log_item_chunk_t *licp;
- int i;
-
- licp = &tp->t_items;
- /*
- * If it's not in the first chunk, skip to the second.
- */
- if (XFS_LIC_ARE_ALL_FREE(licp)) {
- licp = licp->lic_next;
- }
-
- /*
- * Return the first non-free descriptor in the chunk.
- */
- ASSERT(!XFS_LIC_ARE_ALL_FREE(licp));
- for (i = 0; i < licp->lic_unused; i++) {
- if (XFS_LIC_ISFREE(licp, i)) {
- continue;
- }
-
- return XFS_LIC_SLOT(licp, i);
- }
- cmn_err(CE_WARN, "xfs_trans_first_item() -- no first item");
- return NULL;
-}
-
-
-/*
- * Given a descriptor, return the next descriptor in the chunk list.
- * This returns NULL if there are no more used descriptors in the list.
- *
- * We do this by first locating the chunk in which the descriptor resides,
- * and then scanning forward in the chunk and the list for the next
- * used descriptor.
- */
-/*ARGSUSED*/
-xfs_log_item_desc_t *
-xfs_trans_next_item(xfs_trans_t *tp, xfs_log_item_desc_t *lidp)
-{
- xfs_log_item_chunk_t *licp;
- int i;
-
- licp = XFS_LIC_DESC_TO_CHUNK(lidp);
-
- /*
- * First search the rest of the chunk. The for loop keeps us
- * from referencing things beyond the end of the chunk.
- */
- for (i = (int)XFS_LIC_DESC_TO_SLOT(lidp) + 1; i < licp->lic_unused; i++) {
- if (XFS_LIC_ISFREE(licp, i)) {
- continue;
- }
-
- return XFS_LIC_SLOT(licp, i);
- }
-
- /*
- * Now search the next chunk. It must be there, because the
- * next chunk would have been freed if it were empty.
- * If there is no next chunk, return NULL.
- */
- if (licp->lic_next == NULL) {
- return NULL;
- }
-
- licp = licp->lic_next;
- ASSERT(!XFS_LIC_ARE_ALL_FREE(licp));
- for (i = 0; i < licp->lic_unused; i++) {
- if (XFS_LIC_ISFREE(licp, i)) {
- continue;
- }
-
- return XFS_LIC_SLOT(licp, i);
- }
- ASSERT(0);
- /* NOTREACHED */
- return NULL; /* keep gcc quite */
-}
-
-/*
- * This is called to unlock all of the items of a transaction and to free
- * all the descriptors of that transaction.
- *
- * It walks the list of descriptors and unlocks each item. It frees
- * each chunk except that embedded in the transaction as it goes along.
- */
-void
-xfs_trans_free_items(
- xfs_trans_t *tp,
- int flags)
-{
- xfs_log_item_chunk_t *licp;
- xfs_log_item_chunk_t *next_licp;
- int abort;
-
- abort = flags & XFS_TRANS_ABORT;
- licp = &tp->t_items;
- /*
- * Special case the embedded chunk so we don't free it below.
- */
- if (!XFS_LIC_ARE_ALL_FREE(licp)) {
- (void) xfs_trans_unlock_chunk(licp, 1, abort, NULLCOMMITLSN);
- XFS_LIC_ALL_FREE(licp);
- licp->lic_unused = 0;
- }
- licp = licp->lic_next;
-
- /*
- * Unlock each item in each chunk and free the chunks.
- */
- while (licp != NULL) {
- ASSERT(!XFS_LIC_ARE_ALL_FREE(licp));
- (void) xfs_trans_unlock_chunk(licp, 1, abort, NULLCOMMITLSN);
- next_licp = licp->lic_next;
- kmem_free(licp, sizeof(xfs_log_item_chunk_t));
- licp = next_licp;
- }
-
- /*
- * Reset the transaction structure's free item count.
- */
- tp->t_items_free = XFS_LIC_NUM_SLOTS;
- tp->t_items.lic_next = NULL;
-}
-
-
-
-/*
- * This is called to unlock the items associated with a transaction.
- * Items which were not logged should be freed.
- * Those which were logged must still be tracked so they can be unpinned
- * when the transaction commits.
- */
-void
-xfs_trans_unlock_items(xfs_trans_t *tp, xfs_lsn_t commit_lsn)
-{
- xfs_log_item_chunk_t *licp;
- xfs_log_item_chunk_t *next_licp;
- xfs_log_item_chunk_t **licpp;
- int freed;
-
- freed = 0;
- licp = &tp->t_items;
-
- /*
- * Special case the embedded chunk so we don't free.
- */
- if (!XFS_LIC_ARE_ALL_FREE(licp)) {
- freed = xfs_trans_unlock_chunk(licp, 0, 0, commit_lsn);
- }
- licpp = &(tp->t_items.lic_next);
- licp = licp->lic_next;
-
- /*
- * Unlock each item in each chunk, free non-dirty descriptors,
- * and free empty chunks.
- */
- while (licp != NULL) {
- ASSERT(!XFS_LIC_ARE_ALL_FREE(licp));
- freed += xfs_trans_unlock_chunk(licp, 0, 0, commit_lsn);
- next_licp = licp->lic_next;
- if (XFS_LIC_ARE_ALL_FREE(licp)) {
- *licpp = next_licp;
- kmem_free(licp, sizeof(xfs_log_item_chunk_t));
- freed -= XFS_LIC_NUM_SLOTS;
- } else {
- licpp = &(licp->lic_next);
- }
- ASSERT(*licpp == next_licp);
- licp = next_licp;
- }
-
- /*
- * Fix the free descriptor count in the transaction.
- */
- tp->t_items_free += freed;
-}
-
-/*
- * Unlock each item pointed to by a descriptor in the given chunk.
- * Stamp the commit lsn into each item if necessary.
- * Free descriptors pointing to items which are not dirty if freeing_chunk
- * is zero. If freeing_chunk is non-zero, then we need to unlock all
- * items in the chunk.
- *
- * Return the number of descriptors freed.
- */
-STATIC int
-xfs_trans_unlock_chunk(
- xfs_log_item_chunk_t *licp,
- int freeing_chunk,
- int abort,
- xfs_lsn_t commit_lsn)
-{
- xfs_log_item_desc_t *lidp;
- xfs_log_item_t *lip;
- int i;
- int freed;
-
- freed = 0;
- lidp = licp->lic_descs;
- for (i = 0; i < licp->lic_unused; i++, lidp++) {
- if (XFS_LIC_ISFREE(licp, i)) {
- continue;
- }
- lip = lidp->lid_item;
- lip->li_desc = NULL;
-
- if (commit_lsn != NULLCOMMITLSN)
- IOP_COMMITTING(lip, commit_lsn);
- if (abort)
- lip->li_flags |= XFS_LI_ABORTED;
- IOP_UNLOCK(lip);
-
- /*
- * Free the descriptor if the item is not dirty
- * within this transaction and the caller is not
- * going to just free the entire thing regardless.
- */
- if (!(freeing_chunk) &&
- (!(lidp->lid_flags & XFS_LID_DIRTY) || abort)) {
- XFS_LIC_RELSE(licp, i);
- freed++;
- }
- }
-
- return freed;
-}
-
-
-/*
- * This is called to add the given busy item to the transaction's
- * list of busy items. It must find a free busy item descriptor
- * or allocate a new one and add the item to that descriptor.
- * The function returns a pointer to busy descriptor used to point
- * to the new busy entry. The log busy entry will now point to its new
- * descriptor with its ???? field.
- */
-xfs_log_busy_slot_t *
-xfs_trans_add_busy(xfs_trans_t *tp, xfs_agnumber_t ag, xfs_extlen_t idx)
-{
- xfs_log_busy_chunk_t *lbcp;
- xfs_log_busy_slot_t *lbsp;
- int i=0;
-
- /*
- * If there are no free descriptors, allocate a new chunk
- * of them and put it at the front of the chunk list.
- */
- if (tp->t_busy_free == 0) {
- lbcp = (xfs_log_busy_chunk_t*)
- kmem_alloc(sizeof(xfs_log_busy_chunk_t), KM_SLEEP);
- ASSERT(lbcp != NULL);
- /*
- * Initialize the chunk, and then
- * claim the first slot in the newly allocated chunk.
- */
- XFS_LBC_INIT(lbcp);
- XFS_LBC_CLAIM(lbcp, 0);
- lbcp->lbc_unused = 1;
- lbsp = XFS_LBC_SLOT(lbcp, 0);
-
- /*
- * Link in the new chunk and update the free count.
- */
- lbcp->lbc_next = tp->t_busy.lbc_next;
- tp->t_busy.lbc_next = lbcp;
- tp->t_busy_free = XFS_LIC_NUM_SLOTS - 1;
-
- /*
- * Initialize the descriptor and the generic portion
- * of the log item.
- *
- * Point the new slot at this item and return it.
- * Also point the log item at its currently active
- * descriptor and set the item's mount pointer.
- */
- lbsp->lbc_ag = ag;
- lbsp->lbc_idx = idx;
- return lbsp;
- }
-
- /*
- * Find the free descriptor. It is somewhere in the chunklist
- * of descriptors.
- */
- lbcp = &tp->t_busy;
- while (lbcp != NULL) {
- if (XFS_LBC_VACANCY(lbcp)) {
- if (lbcp->lbc_unused <= XFS_LBC_MAX_SLOT) {
- i = lbcp->lbc_unused;
- break;
- } else {
- /* out-of-order vacancy */
- printk("OOO vacancy lbcp 0x%p\n", lbcp);
- ASSERT(0);
- }
- }
- lbcp = lbcp->lbc_next;
- }
- ASSERT(lbcp != NULL);
- /*
- * If we find a free descriptor, claim it,
- * initialize it, and return it.
- */
- XFS_LBC_CLAIM(lbcp, i);
- if (lbcp->lbc_unused <= i) {
- lbcp->lbc_unused = i + 1;
- }
- lbsp = XFS_LBC_SLOT(lbcp, i);
- tp->t_busy_free--;
- lbsp->lbc_ag = ag;
- lbsp->lbc_idx = idx;
- return lbsp;
-}
-
-
-/*
- * xfs_trans_free_busy
- * Free all of the busy lists from a transaction
- */
-void
-xfs_trans_free_busy(xfs_trans_t *tp)
-{
- xfs_log_busy_chunk_t *lbcp;
- xfs_log_busy_chunk_t *lbcq;
-
- lbcp = tp->t_busy.lbc_next;
- while (lbcp != NULL) {
- lbcq = lbcp->lbc_next;
- kmem_free(lbcp, sizeof(xfs_log_busy_chunk_t));
- lbcp = lbcq;
- }
-
- XFS_LBC_INIT(&tp->t_busy);
- tp->t_busy.lbc_unused = 0;
-}
diff --git a/sys/gnu/fs/xfs/xfs_trans_priv.h b/sys/gnu/fs/xfs/xfs_trans_priv.h
deleted file mode 100644
index f68856a..0000000
--- a/sys/gnu/fs/xfs/xfs_trans_priv.h
+++ /dev/null
@@ -1,61 +0,0 @@
-/*
- * Copyright (c) 2000,2002,2005 Silicon Graphics, Inc.
- * All Rights Reserved.
- *
- * 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.
- *
- * This program is distributed in the hope that it would 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 the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- */
-#ifndef __XFS_TRANS_PRIV_H__
-#define __XFS_TRANS_PRIV_H__
-
-struct xfs_log_item;
-struct xfs_log_item_desc;
-struct xfs_mount;
-struct xfs_trans;
-
-/*
- * From xfs_trans_item.c
- */
-struct xfs_log_item_desc *xfs_trans_add_item(struct xfs_trans *,
- struct xfs_log_item *);
-void xfs_trans_free_item(struct xfs_trans *,
- struct xfs_log_item_desc *);
-struct xfs_log_item_desc *xfs_trans_find_item(struct xfs_trans *,
- struct xfs_log_item *);
-struct xfs_log_item_desc *xfs_trans_first_item(struct xfs_trans *);
-struct xfs_log_item_desc *xfs_trans_next_item(struct xfs_trans *,
- struct xfs_log_item_desc *);
-void xfs_trans_free_items(struct xfs_trans *, int);
-void xfs_trans_unlock_items(struct xfs_trans *,
- xfs_lsn_t);
-void xfs_trans_free_busy(xfs_trans_t *tp);
-#if 0
-xfs_log_busy_slot_t *xfs_trans_add_busy(xfs_trans_t *tp,
- xfs_agnumber_t ag,
- xfs_extlen_t idx);
-#endif
-
-/*
- * From xfs_trans_ail.c
- */
-void xfs_trans_update_ail(struct xfs_mount *,
- struct xfs_log_item *, xfs_lsn_t,
- unsigned long);
-void xfs_trans_delete_ail(struct xfs_mount *,
- struct xfs_log_item *, unsigned long);
-struct xfs_log_item *xfs_trans_first_ail(struct xfs_mount *, int *);
-struct xfs_log_item *xfs_trans_next_ail(struct xfs_mount *,
- struct xfs_log_item *, int *, int *);
-
-
-#endif /* __XFS_TRANS_PRIV_H__ */
diff --git a/sys/gnu/fs/xfs/xfs_trans_space.h b/sys/gnu/fs/xfs/xfs_trans_space.h
deleted file mode 100644
index 7fe3792..0000000
--- a/sys/gnu/fs/xfs/xfs_trans_space.h
+++ /dev/null
@@ -1,91 +0,0 @@
-/*
- * Copyright (c) 2000,2005 Silicon Graphics, Inc.
- * All Rights Reserved.
- *
- * 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.
- *
- * This program is distributed in the hope that it would 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 the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- */
-#ifndef __XFS_TRANS_SPACE_H__
-#define __XFS_TRANS_SPACE_H__
-
-/*
- * Components of space reservations.
- */
-#define XFS_MAX_CONTIG_EXTENTS_PER_BLOCK(mp) \
- (((mp)->m_alloc_mxr[0]) - ((mp)->m_alloc_mnr[0]))
-#define XFS_EXTENTADD_SPACE_RES(mp,w) (XFS_BM_MAXLEVELS(mp,w) - 1)
-#define XFS_NEXTENTADD_SPACE_RES(mp,b,w)\
- (((b + XFS_MAX_CONTIG_EXTENTS_PER_BLOCK(mp) - 1) / \
- XFS_MAX_CONTIG_EXTENTS_PER_BLOCK(mp)) * \
- XFS_EXTENTADD_SPACE_RES(mp,w))
-#define XFS_DAENTER_1B(mp,w) ((w) == XFS_DATA_FORK ? (mp)->m_dirblkfsbs : 1)
-#define XFS_DAENTER_DBS(mp,w) \
- (XFS_DA_NODE_MAXDEPTH + \
- ((XFS_DIR_IS_V2(mp) && (w) == XFS_DATA_FORK) ? 2 : 0))
-#define XFS_DAENTER_BLOCKS(mp,w) \
- (XFS_DAENTER_1B(mp,w) * XFS_DAENTER_DBS(mp,w))
-#define XFS_DAENTER_BMAP1B(mp,w) \
- XFS_NEXTENTADD_SPACE_RES(mp, XFS_DAENTER_1B(mp, w), w)
-#define XFS_DAENTER_BMAPS(mp,w) \
- (XFS_DAENTER_DBS(mp,w) * XFS_DAENTER_BMAP1B(mp,w))
-#define XFS_DAENTER_SPACE_RES(mp,w) \
- (XFS_DAENTER_BLOCKS(mp,w) + XFS_DAENTER_BMAPS(mp,w))
-#define XFS_DAREMOVE_SPACE_RES(mp,w) XFS_DAENTER_BMAPS(mp,w)
-#define XFS_DIRENTER_MAX_SPLIT(mp,nl) \
- (((mp)->m_sb.sb_blocksize == 512 && \
- XFS_DIR_IS_V1(mp) && \
- (nl) >= XFS_DIR_LEAF_CAN_DOUBLE_SPLIT_LEN) ? 2 : 1)
-#define XFS_DIRENTER_SPACE_RES(mp,nl) \
- (XFS_DAENTER_SPACE_RES(mp, XFS_DATA_FORK) * \
- XFS_DIRENTER_MAX_SPLIT(mp,nl))
-#define XFS_DIRREMOVE_SPACE_RES(mp) \
- XFS_DAREMOVE_SPACE_RES(mp, XFS_DATA_FORK)
-#define XFS_IALLOC_SPACE_RES(mp) \
- (XFS_IALLOC_BLOCKS(mp) + XFS_IN_MAXLEVELS(mp)-1)
-
-/*
- * Space reservation values for various transactions.
- */
-#define XFS_ADDAFORK_SPACE_RES(mp) \
- ((mp)->m_dirblkfsbs + \
- (XFS_DIR_IS_V1(mp) ? 0 : XFS_DAENTER_BMAP1B(mp, XFS_DATA_FORK)))
-#define XFS_ATTRRM_SPACE_RES(mp) \
- XFS_DAREMOVE_SPACE_RES(mp, XFS_ATTR_FORK)
-/* This macro is not used - see inline code in xfs_attr_set */
-#define XFS_ATTRSET_SPACE_RES(mp, v) \
- (XFS_DAENTER_SPACE_RES(mp, XFS_ATTR_FORK) + XFS_B_TO_FSB(mp, v))
-#define XFS_CREATE_SPACE_RES(mp,nl) \
- (XFS_IALLOC_SPACE_RES(mp) + XFS_DIRENTER_SPACE_RES(mp,nl))
-#define XFS_DIOSTRAT_SPACE_RES(mp, v) \
- (XFS_EXTENTADD_SPACE_RES(mp, XFS_DATA_FORK) + (v))
-#define XFS_GROWFS_SPACE_RES(mp) \
- (2 * XFS_AG_MAXLEVELS(mp))
-#define XFS_GROWFSRT_SPACE_RES(mp,b) \
- ((b) + XFS_EXTENTADD_SPACE_RES(mp, XFS_DATA_FORK))
-#define XFS_LINK_SPACE_RES(mp,nl) \
- XFS_DIRENTER_SPACE_RES(mp,nl)
-#define XFS_MKDIR_SPACE_RES(mp,nl) \
- (XFS_IALLOC_SPACE_RES(mp) + XFS_DIRENTER_SPACE_RES(mp,nl))
-#define XFS_QM_DQALLOC_SPACE_RES(mp) \
- (XFS_EXTENTADD_SPACE_RES(mp, XFS_DATA_FORK) + \
- XFS_DQUOT_CLUSTER_SIZE_FSB)
-#define XFS_QM_QINOCREATE_SPACE_RES(mp) \
- XFS_IALLOC_SPACE_RES(mp)
-#define XFS_REMOVE_SPACE_RES(mp) \
- XFS_DIRREMOVE_SPACE_RES(mp)
-#define XFS_RENAME_SPACE_RES(mp,nl) \
- (XFS_DIRREMOVE_SPACE_RES(mp) + XFS_DIRENTER_SPACE_RES(mp,nl))
-#define XFS_SYMLINK_SPACE_RES(mp,nl,b) \
- (XFS_IALLOC_SPACE_RES(mp) + XFS_DIRENTER_SPACE_RES(mp,nl) + (b))
-
-#endif /* __XFS_TRANS_SPACE_H__ */
diff --git a/sys/gnu/fs/xfs/xfs_types.h b/sys/gnu/fs/xfs/xfs_types.h
deleted file mode 100644
index cce9a5f..0000000
--- a/sys/gnu/fs/xfs/xfs_types.h
+++ /dev/null
@@ -1,179 +0,0 @@
-/*
- * Copyright (c) 2000-2005 Silicon Graphics, Inc.
- * All Rights Reserved.
- *
- * 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.
- *
- * This program is distributed in the hope that it would 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 the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- */
-#ifndef __XFS_TYPES_H__
-#define __XFS_TYPES_H__
-
-#ifdef __KERNEL__
-
-/*
- * POSIX Extensions
- */
-typedef unsigned char uchar_t;
-typedef unsigned short ushort_t;
-typedef unsigned int uint_t;
-typedef unsigned long ulong_t;
-
-/*
- * Additional type declarations for XFS
- */
-#ifndef __FreeBSD__
-typedef signed char __int8_t;
-typedef unsigned char __uint8_t;
-typedef signed short int __int16_t;
-typedef unsigned short int __uint16_t;
-typedef signed int __int32_t;
-typedef unsigned int __uint32_t;
-typedef signed long long int __int64_t;
-typedef unsigned long long int __uint64_t;
-
-typedef enum { B_FALSE,B_TRUE } boolean_t;
-#endif
-
-typedef __uint32_t prid_t; /* project ID */
-typedef __uint32_t inst_t; /* an instruction */
-
-typedef __s64 xfs_off_t; /* <file offset> type */
-typedef __u64 xfs_ino_t; /* <inode> type */
-typedef __s64 xfs_daddr_t; /* <disk address> type */
-typedef char * xfs_caddr_t; /* <core address> type */
-typedef __u32 xfs_dev_t;
-typedef __u32 xfs_nlink_t;
-
-/* __psint_t is the same size as a pointer */
-#if (BITS_PER_LONG == 32)
-typedef __int32_t __psint_t;
-typedef __uint32_t __psunsigned_t;
-#elif (BITS_PER_LONG == 64)
-typedef __int64_t __psint_t;
-typedef __uint64_t __psunsigned_t;
-#else
-#error BITS_PER_LONG must be 32 or 64
-#endif
-
-#endif /* __KERNEL__ */
-
-typedef __uint32_t xfs_agblock_t; /* blockno in alloc. group */
-typedef __uint32_t xfs_extlen_t; /* extent length in blocks */
-typedef __uint32_t xfs_agnumber_t; /* allocation group number */
-typedef __int32_t xfs_extnum_t; /* # of extents in a file */
-typedef __int16_t xfs_aextnum_t; /* # extents in an attribute fork */
-typedef __int64_t xfs_fsize_t; /* bytes in a file */
-typedef __uint64_t xfs_ufsize_t; /* unsigned bytes in a file */
-
-typedef __int32_t xfs_suminfo_t; /* type of bitmap summary info */
-typedef __int32_t xfs_rtword_t; /* word type for bitmap manipulations */
-
-typedef __int64_t xfs_lsn_t; /* log sequence number */
-typedef __int32_t xfs_tid_t; /* transaction identifier */
-
-typedef __uint32_t xfs_dablk_t; /* dir/attr block number (in file) */
-typedef __uint32_t xfs_dahash_t; /* dir/attr hash value */
-
-typedef __uint16_t xfs_prid_t; /* prid_t truncated to 16bits in XFS */
-
-/*
- * These types are 64 bits on disk but are either 32 or 64 bits in memory.
- * Disk based types:
- */
-typedef __uint64_t xfs_dfsbno_t; /* blockno in filesystem (agno|agbno) */
-typedef __uint64_t xfs_drfsbno_t; /* blockno in filesystem (raw) */
-typedef __uint64_t xfs_drtbno_t; /* extent (block) in realtime area */
-typedef __uint64_t xfs_dfiloff_t; /* block number in a file */
-typedef __uint64_t xfs_dfilblks_t; /* number of blocks in a file */
-
-/*
- * Memory based types are conditional.
- */
-#if XFS_BIG_BLKNOS
-typedef __uint64_t xfs_fsblock_t; /* blockno in filesystem (agno|agbno) */
-typedef __uint64_t xfs_rfsblock_t; /* blockno in filesystem (raw) */
-typedef __uint64_t xfs_rtblock_t; /* extent (block) in realtime area */
-typedef __int64_t xfs_srtblock_t; /* signed version of xfs_rtblock_t */
-#else
-typedef __uint32_t xfs_fsblock_t; /* blockno in filesystem (agno|agbno) */
-typedef __uint32_t xfs_rfsblock_t; /* blockno in filesystem (raw) */
-typedef __uint32_t xfs_rtblock_t; /* extent (block) in realtime area */
-typedef __int32_t xfs_srtblock_t; /* signed version of xfs_rtblock_t */
-#endif
-typedef __uint64_t xfs_fileoff_t; /* block number in a file */
-typedef __int64_t xfs_sfiloff_t; /* signed block number in a file */
-typedef __uint64_t xfs_filblks_t; /* number of blocks in a file */
-
-typedef __uint8_t xfs_arch_t; /* architecture of an xfs fs */
-
-/*
- * Null values for the types.
- */
-#define NULLDFSBNO ((xfs_dfsbno_t)-1)
-#define NULLDRFSBNO ((xfs_drfsbno_t)-1)
-#define NULLDRTBNO ((xfs_drtbno_t)-1)
-#define NULLDFILOFF ((xfs_dfiloff_t)-1)
-
-#define NULLFSBLOCK ((xfs_fsblock_t)-1)
-#define NULLRFSBLOCK ((xfs_rfsblock_t)-1)
-#define NULLRTBLOCK ((xfs_rtblock_t)-1)
-#define NULLFILEOFF ((xfs_fileoff_t)-1)
-
-#define NULLAGBLOCK ((xfs_agblock_t)-1)
-#define NULLAGNUMBER ((xfs_agnumber_t)-1)
-#define NULLEXTNUM ((xfs_extnum_t)-1)
-
-#define NULLCOMMITLSN ((xfs_lsn_t)-1)
-
-/*
- * Max values for extlen, extnum, aextnum.
- */
-#define MAXEXTLEN ((xfs_extlen_t)0x001fffff) /* 21 bits */
-#define MAXEXTNUM ((xfs_extnum_t)0x7fffffff) /* signed int */
-#define MAXAEXTNUM ((xfs_aextnum_t)0x7fff) /* signed short */
-
-/*
- * Min numbers of data/attr fork btree root pointers.
- */
-#define MINDBTPTRS 3
-#define MINABTPTRS 2
-
-/*
- * MAXNAMELEN is the length (including the terminating null) of
- * the longest permissible file (component) name.
- */
-#define MAXNAMELEN 256
-
-typedef struct xfs_dirent { /* data from readdir() */
- xfs_ino_t d_ino; /* inode number of entry */
- xfs_off_t d_off; /* offset of disk directory entry */
- unsigned short d_reclen; /* length of this record */
- char d_name[1]; /* name of file */
-} xfs_dirent_t;
-
-#define DIRENTBASESIZE (((xfs_dirent_t *)0)->d_name - (char *)0)
-#define DIRENTSIZE(namelen) \
- ((DIRENTBASESIZE + (namelen) + \
- sizeof(xfs_off_t)) & ~(sizeof(xfs_off_t) - 1))
-
-typedef enum {
- XFS_LOOKUP_EQi, XFS_LOOKUP_LEi, XFS_LOOKUP_GEi
-} xfs_lookup_t;
-
-typedef enum {
- XFS_BTNUM_BNOi, XFS_BTNUM_CNTi, XFS_BTNUM_BMAPi, XFS_BTNUM_INOi,
- XFS_BTNUM_MAX
-} xfs_btnum_t;
-
-#endif /* __XFS_TYPES_H__ */
-
diff --git a/sys/gnu/fs/xfs/xfs_utils.c b/sys/gnu/fs/xfs/xfs_utils.c
deleted file mode 100644
index 3feec78..0000000
--- a/sys/gnu/fs/xfs/xfs_utils.c
+++ /dev/null
@@ -1,472 +0,0 @@
-/*
- * Copyright (c) 2000-2002,2005 Silicon Graphics, Inc.
- * All Rights Reserved.
- *
- * 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.
- *
- * This program is distributed in the hope that it would 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 the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- */
-#include "xfs.h"
-#include "xfs_fs.h"
-#include "xfs_types.h"
-#include "xfs_bit.h"
-#include "xfs_log.h"
-#include "xfs_inum.h"
-#include "xfs_trans.h"
-#include "xfs_sb.h"
-#include "xfs_ag.h"
-#include "xfs_dir.h"
-#include "xfs_dir2.h"
-#include "xfs_dmapi.h"
-#include "xfs_mount.h"
-#include "xfs_bmap_btree.h"
-#include "xfs_dir_sf.h"
-#include "xfs_dir2_sf.h"
-#include "xfs_attr_sf.h"
-#include "xfs_dinode.h"
-#include "xfs_inode.h"
-#include "xfs_inode_item.h"
-#include "xfs_bmap.h"
-#include "xfs_error.h"
-#include "xfs_quota.h"
-#include "xfs_rw.h"
-#include "xfs_itable.h"
-#include "xfs_utils.h"
-
-/*
- * xfs_get_dir_entry is used to get a reference to an inode given
- * its parent directory inode and the name of the file. It does
- * not lock the child inode, and it unlocks the directory before
- * returning. The directory's generation number is returned for
- * use by a later call to xfs_lock_dir_and_entry.
- */
-int
-xfs_get_dir_entry(
- vname_t *dentry,
- xfs_inode_t **ipp)
-{
- xfs_vnode_t *vp;
-
- vp = VNAME_TO_VNODE(dentry);
-
- *ipp = xfs_vtoi(vp);
- if (!*ipp)
- return XFS_ERROR(ENOENT);
- VN_HOLD(vp);
- return 0;
-}
-
-int
-xfs_dir_lookup_int(
- bhv_desc_t *dir_bdp,
- uint lock_mode,
- vname_t *dentry,
- xfs_ino_t *inum,
- xfs_inode_t **ipp)
-{
- xfs_vnode_t *dir_vp;
- xfs_inode_t *dp;
- int error;
-
- dir_vp = BHV_TO_VNODE(dir_bdp);
- vn_trace_entry(dir_vp, __FUNCTION__, (inst_t *)__return_address);
-
- dp = XFS_BHVTOI(dir_bdp);
-
- error = XFS_DIR_LOOKUP(dp->i_mount, NULL, dp,
- VNAME(dentry), VNAMELEN(dentry), inum);
- if (!error) {
- /*
- * Unlock the directory. We do this because we can't
- * hold the directory lock while doing the vn_get()
- * in xfs_iget(). Doing so could cause us to hold
- * a lock while waiting for the inode to finish
- * being inactive while it's waiting for a log
- * reservation in the inactive routine.
- */
- xfs_iunlock(dp, lock_mode);
- error = xfs_iget(dp->i_mount, NULL, *inum, 0, 0, ipp, 0);
- xfs_ilock(dp, lock_mode);
-
- if (error) {
- *ipp = NULL;
- } else if ((*ipp)->i_d.di_mode == 0) {
- /*
- * The inode has been freed. Something is
- * wrong so just get out of here.
- */
- xfs_iunlock(dp, lock_mode);
- xfs_iput_new(*ipp, 0);
- *ipp = NULL;
- xfs_ilock(dp, lock_mode);
- error = XFS_ERROR(ENOENT);
- }
- }
- return error;
-}
-
-/*
- * Allocates a new inode from disk and return a pointer to the
- * incore copy. This routine will internally commit the current
- * transaction and allocate a new one if the Space Manager needed
- * to do an allocation to replenish the inode free-list.
- *
- * This routine is designed to be called from xfs_create and
- * xfs_create_dir.
- *
- */
-int
-xfs_dir_ialloc(
- xfs_trans_t **tpp, /* input: current transaction;
- output: may be a new transaction. */
- xfs_inode_t *dp, /* directory within whose allocate
- the inode. */
- mode_t mode,
- xfs_nlink_t nlink,
- xfs_dev_t rdev,
- cred_t *credp,
- prid_t prid, /* project id */
- int okalloc, /* ok to allocate new space */
- xfs_inode_t **ipp, /* pointer to inode; it will be
- locked. */
- int *committed)
-
-{
- xfs_trans_t *tp;
- xfs_trans_t *ntp;
- xfs_inode_t *ip;
- xfs_buf_t *ialloc_context = NULL;
- boolean_t call_again = B_FALSE;
- int code;
- uint log_res;
- uint log_count;
- void *dqinfo;
- uint tflags;
-
- tp = *tpp;
- ASSERT(tp->t_flags & XFS_TRANS_PERM_LOG_RES);
-
- /*
- * xfs_ialloc will return a pointer to an incore inode if
- * the Space Manager has an available inode on the free
- * list. Otherwise, it will do an allocation and replenish
- * the freelist. Since we can only do one allocation per
- * transaction without deadlocks, we will need to commit the
- * current transaction and start a new one. We will then
- * need to call xfs_ialloc again to get the inode.
- *
- * If xfs_ialloc did an allocation to replenish the freelist,
- * it returns the bp containing the head of the freelist as
- * ialloc_context. We will hold a lock on it across the
- * transaction commit so that no other process can steal
- * the inode(s) that we've just allocated.
- */
- code = xfs_ialloc(tp, dp, mode, nlink, rdev, credp, prid, okalloc,
- &ialloc_context, &call_again, &ip);
-
- /*
- * Return an error if we were unable to allocate a new inode.
- * This should only happen if we run out of space on disk or
- * encounter a disk error.
- */
- if (code) {
- *ipp = NULL;
- return code;
- }
- if (!call_again && (ip == NULL)) {
- *ipp = NULL;
- return XFS_ERROR(ENOSPC);
- }
-
- /*
- * If call_again is set, then we were unable to get an
- * inode in one operation. We need to commit the current
- * transaction and call xfs_ialloc() again. It is guaranteed
- * to succeed the second time.
- */
- if (call_again) {
-
- /*
- * Normally, xfs_trans_commit releases all the locks.
- * We call bhold to hang on to the ialloc_context across
- * the commit. Holding this buffer prevents any other
- * processes from doing any allocations in this
- * allocation group.
- */
- xfs_trans_bhold(tp, ialloc_context);
- /*
- * Save the log reservation so we can use
- * them in the next transaction.
- */
- log_res = xfs_trans_get_log_res(tp);
- log_count = xfs_trans_get_log_count(tp);
-
- /*
- * We want the quota changes to be associated with the next
- * transaction, NOT this one. So, detach the dqinfo from this
- * and attach it to the next transaction.
- */
- dqinfo = NULL;
- tflags = 0;
- if (tp->t_dqinfo) {
- dqinfo = (void *)tp->t_dqinfo;
- tp->t_dqinfo = NULL;
- tflags = tp->t_flags & XFS_TRANS_DQ_DIRTY;
- tp->t_flags &= ~(XFS_TRANS_DQ_DIRTY);
- }
-
- ntp = xfs_trans_dup(tp);
- code = xfs_trans_commit(tp, 0, NULL);
- tp = ntp;
- if (committed != NULL) {
- *committed = 1;
- }
- /*
- * If we get an error during the commit processing,
- * release the buffer that is still held and return
- * to the caller.
- */
- if (code) {
- xfs_buf_relse(ialloc_context);
- if (dqinfo) {
- tp->t_dqinfo = dqinfo;
- XFS_TRANS_FREE_DQINFO(tp->t_mountp, tp);
- }
- *tpp = ntp;
- *ipp = NULL;
- return code;
- }
- code = xfs_trans_reserve(tp, 0, log_res, 0,
- XFS_TRANS_PERM_LOG_RES, log_count);
- /*
- * Re-attach the quota info that we detached from prev trx.
- */
- if (dqinfo) {
- tp->t_dqinfo = dqinfo;
- tp->t_flags |= tflags;
- }
-
- if (code) {
- xfs_buf_relse(ialloc_context);
- *tpp = ntp;
- *ipp = NULL;
- return code;
- }
- xfs_trans_bjoin(tp, ialloc_context);
-
- /*
- * Call ialloc again. Since we've locked out all
- * other allocations in this allocation group,
- * this call should always succeed.
- */
- code = xfs_ialloc(tp, dp, mode, nlink, rdev, credp, prid,
- okalloc, &ialloc_context, &call_again, &ip);
-
- /*
- * If we get an error at this point, return to the caller
- * so that the current transaction can be aborted.
- */
- if (code) {
- *tpp = tp;
- *ipp = NULL;
- return code;
- }
- ASSERT ((!call_again) && (ip != NULL));
-
- } else {
- if (committed != NULL) {
- *committed = 0;
- }
- }
-
- *ipp = ip;
- *tpp = tp;
-
- return 0;
-}
-
-/*
- * Decrement the link count on an inode & log the change.
- * If this causes the link count to go to zero, initiate the
- * logging activity required to truncate a file.
- */
-int /* error */
-xfs_droplink(
- xfs_trans_t *tp,
- xfs_inode_t *ip)
-{
- int error;
-
- xfs_ichgtime(ip, XFS_ICHGTIME_CHG);
-
- ASSERT (ip->i_d.di_nlink > 0);
- ip->i_d.di_nlink--;
- xfs_trans_log_inode(tp, ip, XFS_ILOG_CORE);
-
- error = 0;
- if (ip->i_d.di_nlink == 0) {
- /*
- * We're dropping the last link to this file.
- * Move the on-disk inode to the AGI unlinked list.
- * From xfs_inactive() we will pull the inode from
- * the list and free it.
- */
- error = xfs_iunlink(tp, ip);
- }
- return error;
-}
-
-/*
- * This gets called when the inode's version needs to be changed from 1 to 2.
- * Currently this happens when the nlink field overflows the old 16-bit value
- * or when chproj is called to change the project for the first time.
- * As a side effect the superblock version will also get rev'd
- * to contain the NLINK bit.
- */
-void
-xfs_bump_ino_vers2(
- xfs_trans_t *tp,
- xfs_inode_t *ip)
-{
- xfs_mount_t *mp;
- unsigned long s;
-
- ASSERT(ismrlocked (&ip->i_lock, MR_UPDATE));
- ASSERT(ip->i_d.di_version == XFS_DINODE_VERSION_1);
-
- ip->i_d.di_version = XFS_DINODE_VERSION_2;
- ip->i_d.di_onlink = 0;
- memset(&(ip->i_d.di_pad[0]), 0, sizeof(ip->i_d.di_pad));
- mp = tp->t_mountp;
- if (!XFS_SB_VERSION_HASNLINK(&mp->m_sb)) {
- s = XFS_SB_LOCK(mp);
- if (!XFS_SB_VERSION_HASNLINK(&mp->m_sb)) {
- XFS_SB_VERSION_ADDNLINK(&mp->m_sb);
- XFS_SB_UNLOCK(mp, s);
- xfs_mod_sb(tp, XFS_SB_VERSIONNUM);
- } else {
- XFS_SB_UNLOCK(mp, s);
- }
- }
- /* Caller must log the inode */
-}
-
-/*
- * Increment the link count on an inode & log the change.
- */
-int
-xfs_bumplink(
- xfs_trans_t *tp,
- xfs_inode_t *ip)
-{
- if (ip->i_d.di_nlink >= XFS_MAXLINK)
- return XFS_ERROR(EMLINK);
- xfs_ichgtime(ip, XFS_ICHGTIME_CHG);
-
- ASSERT(ip->i_d.di_nlink > 0);
- ip->i_d.di_nlink++;
- if ((ip->i_d.di_version == XFS_DINODE_VERSION_1) &&
- (ip->i_d.di_nlink > XFS_MAXLINK_1)) {
- /*
- * The inode has increased its number of links beyond
- * what can fit in an old format inode. It now needs
- * to be converted to a version 2 inode with a 32 bit
- * link count. If this is the first inode in the file
- * system to do this, then we need to bump the superblock
- * version number as well.
- */
- xfs_bump_ino_vers2(tp, ip);
- }
-
- xfs_trans_log_inode(tp, ip, XFS_ILOG_CORE);
- return 0;
-}
-
-/*
- * Try to truncate the given file to 0 length. Currently called
- * only out of xfs_remove when it has to truncate a file to free
- * up space for the remove to proceed.
- */
-int
-xfs_truncate_file(
- xfs_mount_t *mp,
- xfs_inode_t *ip)
-{
- xfs_trans_t *tp;
- int error;
-
-#ifdef QUOTADEBUG
- /*
- * This is called to truncate the quotainodes too.
- */
- if (XFS_IS_UQUOTA_ON(mp)) {
- if (ip->i_ino != mp->m_sb.sb_uquotino)
- ASSERT(ip->i_udquot);
- }
- if (XFS_IS_OQUOTA_ON(mp)) {
- if (ip->i_ino != mp->m_sb.sb_gquotino)
- ASSERT(ip->i_gdquot);
- }
-#endif
- /*
- * Make the call to xfs_itruncate_start before starting the
- * transaction, because we cannot make the call while we're
- * in a transaction.
- */
- xfs_ilock(ip, XFS_IOLOCK_EXCL);
- xfs_itruncate_start(ip, XFS_ITRUNC_DEFINITE, (xfs_fsize_t)0);
-
- tp = xfs_trans_alloc(mp, XFS_TRANS_TRUNCATE_FILE);
- if ((error = xfs_trans_reserve(tp, 0, XFS_ITRUNCATE_LOG_RES(mp), 0,
- XFS_TRANS_PERM_LOG_RES,
- XFS_ITRUNCATE_LOG_COUNT))) {
- xfs_trans_cancel(tp, 0);
- xfs_iunlock(ip, XFS_IOLOCK_EXCL);
- return error;
- }
-
- /*
- * Follow the normal truncate locking protocol. Since we
- * hold the inode in the transaction, we know that it's number
- * of references will stay constant.
- */
- xfs_ilock(ip, XFS_ILOCK_EXCL);
- xfs_trans_ijoin(tp, ip, XFS_ILOCK_EXCL | XFS_IOLOCK_EXCL);
- xfs_trans_ihold(tp, ip);
- /*
- * Signal a sync xaction. The only case where that isn't
- * the case is if we're truncating an already unlinked file
- * on a wsync fs. In that case, we know the blocks can't
- * reappear in the file because the links to file are
- * permanently toast. Currently, we're always going to
- * want a sync transaction because this code is being
- * called from places where nlink is guaranteed to be 1
- * but I'm leaving the tests in to protect against future
- * changes -- rcc.
- */
- error = xfs_itruncate_finish(&tp, ip, (xfs_fsize_t)0,
- XFS_DATA_FORK,
- ((ip->i_d.di_nlink != 0 ||
- !(mp->m_flags & XFS_MOUNT_WSYNC))
- ? 1 : 0));
- if (error) {
- xfs_trans_cancel(tp, XFS_TRANS_RELEASE_LOG_RES |
- XFS_TRANS_ABORT);
- } else {
- xfs_ichgtime(ip, XFS_ICHGTIME_MOD | XFS_ICHGTIME_CHG);
- error = xfs_trans_commit(tp, XFS_TRANS_RELEASE_LOG_RES,
- NULL);
- }
- xfs_iunlock(ip, XFS_ILOCK_EXCL | XFS_IOLOCK_EXCL);
-
- return error;
-}
diff --git a/sys/gnu/fs/xfs/xfs_utils.h b/sys/gnu/fs/xfs/xfs_utils.h
deleted file mode 100644
index 2178ad1..0000000
--- a/sys/gnu/fs/xfs/xfs_utils.h
+++ /dev/null
@@ -1,38 +0,0 @@
-/*
- * Copyright (c) 2000-2002,2005 Silicon Graphics, Inc.
- * All Rights Reserved.
- *
- * 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.
- *
- * This program is distributed in the hope that it would 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 the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- */
-#ifndef __XFS_UTILS_H__
-#define __XFS_UTILS_H__
-
-#define IRELE(ip) VN_RELE(XFS_ITOV(ip))
-#define IHOLD(ip) VN_HOLD(XFS_ITOV(ip))
-#define ITRACE(ip) vn_trace_ref(XFS_ITOV(ip), __FILE__, __LINE__, \
- (inst_t *)__return_address)
-
-extern int xfs_rename (bhv_desc_t *, vname_t *, xfs_vnode_t *, vname_t *, cred_t *);
-extern int xfs_get_dir_entry (vname_t *, xfs_inode_t **);
-extern int xfs_dir_lookup_int (bhv_desc_t *, uint, vname_t *, xfs_ino_t *,
- xfs_inode_t **);
-extern int xfs_truncate_file (xfs_mount_t *, xfs_inode_t *);
-extern int xfs_dir_ialloc (xfs_trans_t **, xfs_inode_t *, mode_t, xfs_nlink_t,
- xfs_dev_t, cred_t *, prid_t, int,
- xfs_inode_t **, int *);
-extern int xfs_droplink (xfs_trans_t *, xfs_inode_t *);
-extern int xfs_bumplink (xfs_trans_t *, xfs_inode_t *);
-extern void xfs_bump_ino_vers2 (xfs_trans_t *, xfs_inode_t *);
-
-#endif /* __XFS_UTILS_H__ */
diff --git a/sys/gnu/fs/xfs/xfs_vfsops.c b/sys/gnu/fs/xfs/xfs_vfsops.c
deleted file mode 100644
index b073a8e..0000000
--- a/sys/gnu/fs/xfs/xfs_vfsops.c
+++ /dev/null
@@ -1,2030 +0,0 @@
-/*
- * Copyright (c) 2000-2005 Silicon Graphics, Inc.
- * All Rights Reserved.
- *
- * 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.
- *
- * This program is distributed in the hope that it would 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 the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- */
-#include "xfs.h"
-#include "xfs_fs.h"
-#include "xfs_types.h"
-#include "xfs_bit.h"
-#include "xfs_log.h"
-#include "xfs_inum.h"
-#include "xfs_trans.h"
-#include "xfs_sb.h"
-#include "xfs_ag.h"
-#include "xfs_dir.h"
-#include "xfs_dir2.h"
-#include "xfs_dmapi.h"
-#include "xfs_mount.h"
-#include "xfs_da_btree.h"
-#include "xfs_bmap_btree.h"
-#include "xfs_ialloc_btree.h"
-#include "xfs_alloc_btree.h"
-#include "xfs_dir_sf.h"
-#include "xfs_dir2_sf.h"
-#include "xfs_attr_sf.h"
-#include "xfs_dinode.h"
-#include "xfs_inode.h"
-#include "xfs_inode_item.h"
-#include "xfs_btree.h"
-#include "xfs_alloc.h"
-#include "xfs_ialloc.h"
-#include "xfs_quota.h"
-#include "xfs_error.h"
-#include "xfs_bmap.h"
-#include "xfs_rw.h"
-#include "xfs_refcache.h"
-#include "xfs_buf_item.h"
-#include "xfs_log_priv.h"
-#include "xfs_dir2_trace.h"
-#include "xfs_extfree_item.h"
-#include "xfs_acl.h"
-#include "xfs_attr.h"
-#include "xfs_clnt.h"
-#include "xfs_fsops.h"
-#include "xfs_vnode.h"
-
-STATIC int xfs_sync(bhv_desc_t *, int, cred_t *);
-
- extern kmem_zone_t *xfs_bmap_free_item_zone;
- extern kmem_zone_t *xfs_btree_cur_zone;
- extern kmem_zone_t *xfs_trans_zone;
- extern kmem_zone_t *xfs_dabuf_zone;
- extern kmem_zone_t *xfs_buf_item_zone;
-
-#ifdef XFS_DABUF_DEBUG
- extern lock_t xfs_dabuf_global_lock;
-#endif
-
-int
-xfs_init(void)
-{
-#if 0
- extern kmem_zone_t *xfs_bmap_free_item_zone;
- extern kmem_zone_t *xfs_btree_cur_zone;
- extern kmem_zone_t *xfs_trans_zone;
- extern kmem_zone_t *xfs_buf_item_zone;
- extern kmem_zone_t *xfs_dabuf_zone;
-#endif
-#ifdef XFS_DABUF_DEBUG
- spinlock_init(&xfs_dabuf_global_lock, "xfsda");
-#endif
- /*
- * Initialize all of the zone allocators we use.
- */
- xfs_bmap_free_item_zone = kmem_zone_init(sizeof(xfs_bmap_free_item_t),
- "xfs_bmap_free_item");
- xfs_btree_cur_zone = kmem_zone_init(sizeof(xfs_btree_cur_t),
- "xfs_btree_cur");
- xfs_trans_zone = kmem_zone_init(sizeof(xfs_trans_t), "xfs_trans");
- xfs_da_state_zone =
- kmem_zone_init(sizeof(xfs_da_state_t), "xfs_da_state");
- xfs_dabuf_zone = kmem_zone_init(sizeof(xfs_dabuf_t), "xfs_dabuf");
- xfs_ifork_zone = kmem_zone_init(sizeof(xfs_ifork_t), "xfs_ifork");
- xfs_acl_zone_init(xfs_acl_zone, "xfs_acl");
-
- /*
- * The size of the zone allocated buf log item is the maximum
- * size possible under XFS. This wastes a little bit of memory,
- * but it is much faster.
- */
- xfs_buf_item_zone =
- kmem_zone_init((sizeof(xfs_buf_log_item_t) +
- (((XFS_MAX_BLOCKSIZE / XFS_BLI_CHUNK) /
- NBWORD) * sizeof(int))),
- "xfs_buf_item");
- xfs_efd_zone =
- kmem_zone_init((sizeof(xfs_efd_log_item_t) +
- ((XFS_EFD_MAX_FAST_EXTENTS - 1) *
- sizeof(xfs_extent_t))),
- "xfs_efd_item");
- xfs_efi_zone =
- kmem_zone_init((sizeof(xfs_efi_log_item_t) +
- ((XFS_EFI_MAX_FAST_EXTENTS - 1) *
- sizeof(xfs_extent_t))),
- "xfs_efi_item");
-
- /*
- * These zones warrant special memory allocator hints
- */
- xfs_inode_zone =
- kmem_zone_init_flags(sizeof(xfs_inode_t), "xfs_inode",
- KM_ZONE_HWALIGN | KM_ZONE_RECLAIM |
- KM_ZONE_SPREAD, NULL);
- xfs_ili_zone =
- kmem_zone_init_flags(sizeof(xfs_inode_log_item_t), "xfs_ili",
- KM_ZONE_SPREAD, NULL);
- xfs_chashlist_zone =
- kmem_zone_init_flags(sizeof(xfs_chashlist_t), "xfs_chashlist",
- KM_ZONE_SPREAD, NULL);
-
- /*
- * Allocate global trace buffers.
- */
-#ifdef XFS_ALLOC_TRACE
- xfs_alloc_trace_buf = ktrace_alloc(XFS_ALLOC_TRACE_SIZE, KM_SLEEP);
-#endif
-#ifdef XFS_BMAP_TRACE
- xfs_bmap_trace_buf = ktrace_alloc(XFS_BMAP_TRACE_SIZE, KM_SLEEP);
-#endif
-#ifdef XFS_BMBT_TRACE
- xfs_bmbt_trace_buf = ktrace_alloc(XFS_BMBT_TRACE_SIZE, KM_SLEEP);
-#endif
-#ifdef XFS_DIR_TRACE
- xfs_dir_trace_buf = ktrace_alloc(XFS_DIR_TRACE_SIZE, KM_SLEEP);
-#endif
-#ifdef XFS_ATTR_TRACE
- xfs_attr_trace_buf = ktrace_alloc(XFS_ATTR_TRACE_SIZE, KM_SLEEP);
-#endif
-#ifdef XFS_DIR2_TRACE
- xfs_dir2_trace_buf = ktrace_alloc(XFS_DIR2_GTRACE_SIZE, KM_SLEEP);
-#endif
-
- xfs_dir_startup();
-
-#if (defined(DEBUG) || defined(INDUCE_IO_ERROR))
- xfs_error_test_init();
-#endif /* DEBUG || INDUCE_IO_ERROR */
-
- xfs_refcache_init();
- xfs_init_procfs();
- xfs_sysctl_register();
- return 0;
-}
-
-void
-xfs_cleanup(void)
-{
-#if 0
- extern kmem_zone_t *xfs_bmap_free_item_zone;
- extern kmem_zone_t *xfs_btree_cur_zone;
- extern kmem_zone_t *xfs_inode_zone;
- extern kmem_zone_t *xfs_trans_zone;
- extern kmem_zone_t *xfs_da_state_zone;
- extern kmem_zone_t *xfs_dabuf_zone;
- extern kmem_zone_t *xfs_efd_zone;
- extern kmem_zone_t *xfs_efi_zone;
- extern kmem_zone_t *xfs_buf_item_zone;
- extern kmem_zone_t *xfs_chashlist_zone;
-#endif
-
- xfs_cleanup_procfs();
- xfs_sysctl_unregister();
- xfs_refcache_destroy();
- xfs_acl_zone_destroy(xfs_acl_zone);
-
-#ifdef XFS_DIR2_TRACE
- ktrace_free(xfs_dir2_trace_buf);
-#endif
-#ifdef XFS_ATTR_TRACE
- ktrace_free(xfs_attr_trace_buf);
-#endif
-#ifdef XFS_DIR_TRACE
- ktrace_free(xfs_dir_trace_buf);
-#endif
-#ifdef XFS_BMBT_TRACE
- ktrace_free(xfs_bmbt_trace_buf);
-#endif
-#ifdef XFS_BMAP_TRACE
- ktrace_free(xfs_bmap_trace_buf);
-#endif
-#ifdef XFS_ALLOC_TRACE
- ktrace_free(xfs_alloc_trace_buf);
-#endif
-
- kmem_zone_destroy(xfs_bmap_free_item_zone);
- kmem_zone_destroy(xfs_btree_cur_zone);
- kmem_zone_destroy(xfs_inode_zone);
- kmem_zone_destroy(xfs_trans_zone);
- kmem_zone_destroy(xfs_da_state_zone);
- kmem_zone_destroy(xfs_dabuf_zone);
- kmem_zone_destroy(xfs_buf_item_zone);
- kmem_zone_destroy(xfs_efd_zone);
- kmem_zone_destroy(xfs_efi_zone);
- kmem_zone_destroy(xfs_ifork_zone);
- kmem_zone_destroy(xfs_ili_zone);
- kmem_zone_destroy(xfs_chashlist_zone);
-}
-
-/*
- * xfs_start_flags
- *
- * This function fills in xfs_mount_t fields based on mount args.
- * Note: the superblock has _not_ yet been read in.
- */
-STATIC int
-xfs_start_flags(
- struct xfs_vfs *vfs,
- struct xfs_mount_args *ap,
- struct xfs_mount *mp)
-{
- /* Values are in BBs */
- if ((ap->flags & XFSMNT_NOALIGN) != XFSMNT_NOALIGN) {
- /*
- * At this point the superblock has not been read
- * in, therefore we do not know the block size.
- * Before the mount call ends we will convert
- * these to FSBs.
- */
- mp->m_dalign = ap->sunit;
- mp->m_swidth = ap->swidth;
- }
-
- if (ap->logbufs != -1 &&
- ap->logbufs != 0 &&
- (ap->logbufs < XLOG_MIN_ICLOGS ||
- ap->logbufs > XLOG_MAX_ICLOGS)) {
- cmn_err(CE_WARN,
- "XFS: invalid logbufs value: %d [not %d-%d]",
- ap->logbufs, XLOG_MIN_ICLOGS, XLOG_MAX_ICLOGS);
- return XFS_ERROR(EINVAL);
- }
- mp->m_logbufs = ap->logbufs;
- if (ap->logbufsize != -1 &&
- ap->logbufsize != 0 &&
- ap->logbufsize != 16 * 1024 &&
- ap->logbufsize != 32 * 1024 &&
- ap->logbufsize != 64 * 1024 &&
- ap->logbufsize != 128 * 1024 &&
- ap->logbufsize != 256 * 1024) {
- cmn_err(CE_WARN,
- "XFS: invalid logbufsize: %d [not 16k,32k,64k,128k or 256k]",
- ap->logbufsize);
- return XFS_ERROR(EINVAL);
- }
- mp->m_ihsize = ap->ihashsize;
- mp->m_logbsize = ap->logbufsize;
- mp->m_fsname_len = strlen(ap->fsname) + 1;
- mp->m_fsname = kmem_alloc(mp->m_fsname_len, KM_SLEEP);
- strcpy(mp->m_fsname, ap->fsname);
- if (ap->rtname[0]) {
- mp->m_rtname = kmem_alloc(strlen(ap->rtname) + 1, KM_SLEEP);
- strcpy(mp->m_rtname, ap->rtname);
- }
- if (ap->logname[0]) {
- mp->m_logname = kmem_alloc(strlen(ap->logname) + 1, KM_SLEEP);
- strcpy(mp->m_logname, ap->logname);
- }
-
- if (ap->flags & XFSMNT_WSYNC)
- mp->m_flags |= XFS_MOUNT_WSYNC;
-#if XFS_BIG_INUMS
- if (ap->flags & XFSMNT_INO64) {
- mp->m_flags |= XFS_MOUNT_INO64;
- mp->m_inoadd = XFS_INO64_OFFSET;
- }
-#endif
- if (ap->flags & XFSMNT_RETERR)
- mp->m_flags |= XFS_MOUNT_RETERR;
- if (ap->flags & XFSMNT_NOALIGN)
- mp->m_flags |= XFS_MOUNT_NOALIGN;
- if (ap->flags & XFSMNT_SWALLOC)
- mp->m_flags |= XFS_MOUNT_SWALLOC;
- if (ap->flags & XFSMNT_OSYNCISOSYNC)
- mp->m_flags |= XFS_MOUNT_OSYNCISOSYNC;
- if (ap->flags & XFSMNT_32BITINODES)
- mp->m_flags |= XFS_MOUNT_32BITINODES;
-
- if (ap->flags & XFSMNT_IOSIZE) {
- if (ap->iosizelog > XFS_MAX_IO_LOG ||
- ap->iosizelog < XFS_MIN_IO_LOG) {
- cmn_err(CE_WARN,
- "XFS: invalid log iosize: %d [not %d-%d]",
- ap->iosizelog, XFS_MIN_IO_LOG,
- XFS_MAX_IO_LOG);
- return XFS_ERROR(EINVAL);
- }
-
- mp->m_flags |= XFS_MOUNT_DFLT_IOSIZE;
- mp->m_readio_log = mp->m_writeio_log = ap->iosizelog;
- }
-
- if (ap->flags & XFSMNT_IHASHSIZE)
- mp->m_flags |= XFS_MOUNT_IHASHSIZE;
- if (ap->flags & XFSMNT_IDELETE)
- mp->m_flags |= XFS_MOUNT_IDELETE;
- if (ap->flags & XFSMNT_DIRSYNC)
- mp->m_flags |= XFS_MOUNT_DIRSYNC;
- if (ap->flags & XFSMNT_ATTR2)
- mp->m_flags |= XFS_MOUNT_ATTR2;
-
- if (ap->flags2 & XFSMNT2_COMPAT_IOSIZE)
- mp->m_flags |= XFS_MOUNT_COMPAT_IOSIZE;
-
- /*
- * no recovery flag requires a read-only mount
- */
- if (ap->flags & XFSMNT_NORECOVERY) {
- if (!(vfs->vfs_flag & VFS_RDONLY)) {
- cmn_err(CE_WARN,
- "XFS: tried to mount a FS read-write without recovery!");
- return XFS_ERROR(EINVAL);
- }
- mp->m_flags |= XFS_MOUNT_NORECOVERY;
- }
-
- if (ap->flags & XFSMNT_NOUUID)
- mp->m_flags |= XFS_MOUNT_NOUUID;
- if (ap->flags & XFSMNT_BARRIER)
- mp->m_flags |= XFS_MOUNT_BARRIER;
- else
- mp->m_flags &= ~XFS_MOUNT_BARRIER;
-
- return 0;
-}
-
-/*
- * This function fills in xfs_mount_t fields based on mount args.
- * Note: the superblock _has_ now been read in.
- */
-STATIC int
-xfs_finish_flags(
- struct xfs_vfs *vfs,
- struct xfs_mount_args *ap,
- struct xfs_mount *mp)
-{
- int ronly = (vfs->vfs_flag & VFS_RDONLY);
-
- /* Fail a mount where the logbuf is smaller then the log stripe */
- if (XFS_SB_VERSION_HASLOGV2(&mp->m_sb)) {
- if ((ap->logbufsize <= 0) &&
- (mp->m_sb.sb_logsunit > XLOG_BIG_RECORD_BSIZE)) {
- mp->m_logbsize = mp->m_sb.sb_logsunit;
- } else if (ap->logbufsize > 0 &&
- ap->logbufsize < mp->m_sb.sb_logsunit) {
- cmn_err(CE_WARN,
- "XFS: logbuf size must be greater than or equal to log stripe size");
- return XFS_ERROR(EINVAL);
- }
- } else {
- /* Fail a mount if the logbuf is larger than 32K */
- if (ap->logbufsize > XLOG_BIG_RECORD_BSIZE) {
- cmn_err(CE_WARN,
- "XFS: logbuf size for version 1 logs must be 16K or 32K");
- return XFS_ERROR(EINVAL);
- }
- }
-
- if (XFS_SB_VERSION_HASATTR2(&mp->m_sb)) {
- mp->m_flags |= XFS_MOUNT_ATTR2;
- }
-
- /*
- * prohibit r/w mounts of read-only filesystems
- */
- if ((mp->m_sb.sb_flags & XFS_SBF_READONLY) && !ronly) {
- cmn_err(CE_WARN,
- "XFS: cannot mount a read-only filesystem as read-write");
- return XFS_ERROR(EROFS);
- }
-
- /*
- * check for shared mount.
- */
- if (ap->flags & XFSMNT_SHARED) {
- if (!XFS_SB_VERSION_HASSHARED(&mp->m_sb))
- return XFS_ERROR(EINVAL);
-
- /*
- * For IRIX 6.5, shared mounts must have the shared
- * version bit set, have the persistent readonly
- * field set, must be version 0 and can only be mounted
- * read-only.
- */
- if (!ronly || !(mp->m_sb.sb_flags & XFS_SBF_READONLY) ||
- (mp->m_sb.sb_shared_vn != 0))
- return XFS_ERROR(EINVAL);
-
- mp->m_flags |= XFS_MOUNT_SHARED;
-
- /*
- * Shared XFS V0 can't deal with DMI. Return EINVAL.
- */
- if (mp->m_sb.sb_shared_vn == 0 && (ap->flags & XFSMNT_DMAPI))
- return XFS_ERROR(EINVAL);
- }
-
- return 0;
-}
-
-/*
- * xfs_mount
- *
- * The file system configurations are:
- * (1) device (partition) with data and internal log
- * (2) logical volume with data and log subvolumes.
- * (3) logical volume with data, log, and realtime subvolumes.
- *
- * We only have to handle opening the log and realtime volumes here if
- * they are present. The data subvolume has already been opened by
- * get_sb_bdev() and is stored in vfsp->vfs_super->s_bdev.
- */
-STATIC int
-xfs_mount(
- struct bhv_desc *bhvp,
- struct xfs_mount_args *args,
- cred_t *credp)
-{
- struct xfs_vfs *vfsp = bhvtovfs(bhvp);
- struct bhv_desc *p;
- struct xfs_mount *mp = XFS_BHVTOM(bhvp);
- struct vnode *ddev, *logdev, *rtdev;
- int flags = 0, error;
-
- ddev = logdev = rtdev = NULL;
-
- error = xfs_blkdev_get(mp, args->fsname, &ddev);
- if (error)
- return error;
-
- /*
- * Setup xfs_mount function vectors from available behaviors
- */
- p = vfs_bhv_lookup(vfsp, VFS_POSITION_DM);
- mp->m_dm_ops = p ? *(xfs_dmops_t *) vfs_bhv_custom(p) : xfs_dmcore_stub;
- p = vfs_bhv_lookup(vfsp, VFS_POSITION_QM);
- mp->m_qm_ops = p ? *(xfs_qmops_t *) vfs_bhv_custom(p) : xfs_qmcore_stub;
- p = vfs_bhv_lookup(vfsp, VFS_POSITION_IO);
- mp->m_io_ops = p ? *(xfs_ioops_t *) vfs_bhv_custom(p) : xfs_iocore_xfs;
-
- if (args->flags & XFSMNT_QUIET)
- flags |= XFS_MFSI_QUIET;
-
- /*
- * Open real time and log devices - order is important.
- */
- if (args->logname[0]) {
- error = xfs_blkdev_get(mp, args->logname, &logdev);
- if (error) {
- xfs_blkdev_put(ddev);
- return error;
- }
- }
- if (args->rtname[0]) {
- error = xfs_blkdev_get(mp, args->rtname, &rtdev);
- if (error) {
- xfs_blkdev_put(logdev);
- xfs_blkdev_put(ddev);
- return error;
- }
-
- if (rtdev == ddev || rtdev == logdev) {
- cmn_err(CE_WARN,
- "XFS: Cannot mount filesystem with identical rtdev and ddev/logdev.");
- xfs_blkdev_put(logdev);
- xfs_blkdev_put(rtdev);
- xfs_blkdev_put(ddev);
- return EINVAL;
- }
- }
-
- /*
- * Setup xfs_mount buffer target pointers
- */
- error = ENOMEM;
- mp->m_ddev_targp = xfs_alloc_buftarg(ddev, 0);
- if (!mp->m_ddev_targp) {
- xfs_blkdev_put(logdev);
- xfs_blkdev_put(rtdev);
- return error;
- }
- if (rtdev) {
- mp->m_rtdev_targp = xfs_alloc_buftarg(rtdev, 1);
- if (!mp->m_rtdev_targp)
- goto error0;
- }
- mp->m_logdev_targp = (logdev && logdev != ddev) ?
- xfs_alloc_buftarg(logdev, 1) : mp->m_ddev_targp;
- if (!mp->m_logdev_targp)
- goto error0;
-
- /*
- * Setup flags based on mount(2) options and then the superblock
- */
- error = xfs_start_flags(vfsp, args, mp);
- if (error)
- goto error1;
- error = xfs_readsb(mp, flags);
- if (error)
- goto error1;
- error = xfs_finish_flags(vfsp, args, mp);
- if (error)
- goto error2;
-
- /*
- * Setup xfs_mount buffer target pointers based on superblock
- */
- error = xfs_setsize_buftarg(mp->m_ddev_targp, mp->m_sb.sb_blocksize,
- mp->m_sb.sb_sectsize);
- if (!error && logdev && logdev != ddev) {
- unsigned int log_sector_size = BBSIZE;
-
- if (XFS_SB_VERSION_HASSECTOR(&mp->m_sb))
- log_sector_size = mp->m_sb.sb_logsectsize;
- error = xfs_setsize_buftarg(mp->m_logdev_targp,
- mp->m_sb.sb_blocksize,
- log_sector_size);
- }
- if (!error && rtdev)
- error = xfs_setsize_buftarg(mp->m_rtdev_targp,
- mp->m_sb.sb_blocksize,
- mp->m_sb.sb_sectsize);
- if (error)
- goto error2;
-
- if ((mp->m_flags & XFS_MOUNT_BARRIER) && !(vfsp->vfs_flag & VFS_RDONLY))
- xfs_mountfs_check_barriers(mp);
-
- error = XFS_IOINIT(vfsp, args, flags);
- if (error)
- goto error2;
-
- return 0;
-
-error2:
- if (mp->m_sb_bp)
- xfs_freesb(mp);
-error1:
- xfs_binval(mp->m_ddev_targp);
- if (logdev && logdev != ddev)
- xfs_binval(mp->m_logdev_targp);
- if (rtdev)
- xfs_binval(mp->m_rtdev_targp);
-error0:
- xfs_unmountfs_close(mp, credp);
- return error;
-}
-
-STATIC int
-xfs_unmount(
- bhv_desc_t *bdp,
- int flags,
- cred_t *credp)
-{
- struct xfs_vfs *vfsp = bhvtovfs(bdp);
- xfs_mount_t *mp = XFS_BHVTOM(bdp);
- xfs_inode_t *rip;
- xfs_vnode_t *rvp;
- int unmount_event_wanted = 0;
- int unmount_event_flags = 0;
- int xfs_unmountfs_needed = 0;
- int error;
-
- rip = mp->m_rootip;
- rvp = XFS_ITOV(rip);
-
- if (vfsp->vfs_flag & VFS_DMI) {
- error = XFS_SEND_PREUNMOUNT(mp, vfsp,
- rvp, DM_RIGHT_NULL, rvp, DM_RIGHT_NULL,
- NULL, NULL, 0, 0,
- (mp->m_dmevmask & (1<<DM_EVENT_PREUNMOUNT))?
- 0:DM_FLAGS_UNWANTED);
- if (error)
- return XFS_ERROR(error);
- unmount_event_wanted = 1;
- unmount_event_flags = (mp->m_dmevmask & (1<<DM_EVENT_UNMOUNT))?
- 0 : DM_FLAGS_UNWANTED;
- }
-
- /*
- * Linux (& presumably Irix) do not reach this code if
- * any of this FS vnodes have active references. FreeBSD
- * relies on FS to clean after itself.
- */
- xfs_iflush_all(mp);
-
- /*
- * First blow any referenced inode from this file system
- * out of the reference cache, and delete the timer.
- */
- xfs_refcache_purge_mp(mp);
-
- XFS_bflush(mp->m_ddev_targp);
- error = xfs_unmount_flush(mp, 0);
- if (error)
- goto out;
-
- ASSERT(vn_count(rvp) == 1);
-
- /*
- * Drop the reference count
- */
- VN_RELE(rvp);
-
- /*
- * If we're forcing a shutdown, typically because of a media error,
- * we want to make sure we invalidate dirty pages that belong to
- * referenced vnodes as well.
- */
- if (XFS_FORCED_SHUTDOWN(mp)) {
- error = xfs_sync(&mp->m_bhv,
- (SYNC_WAIT | SYNC_CLOSE), credp);
- ASSERT(error != EFSCORRUPTED);
- }
- xfs_unmountfs_needed = 1;
-
-out:
- /* Send DMAPI event, if required.
- * Then do xfs_unmountfs() if needed.
- * Then return error (or zero).
- */
- if (unmount_event_wanted) {
- /* Note: mp structure must still exist for
- * XFS_SEND_UNMOUNT() call.
- */
- XFS_SEND_UNMOUNT(mp, vfsp, error == 0 ? rvp : NULL,
- DM_RIGHT_NULL, 0, error, unmount_event_flags);
- }
- if (xfs_unmountfs_needed) {
- /*
- * Call common unmount function to flush to disk
- * and free the super block buffer & mount structures.
- */
- xfs_unmountfs(mp, credp);
- }
-
- return XFS_ERROR(error);
-}
-
-STATIC int
-xfs_quiesce_fs(
- xfs_mount_t *mp)
-{
- int count = 0, pincount;
-
- xfs_refcache_purge_mp(mp);
- xfs_flush_buftarg(mp->m_ddev_targp, 0);
- xfs_finish_reclaim_all(mp, 0);
-
- /* This loop must run at least twice.
- * The first instance of the loop will flush
- * most meta data but that will generate more
- * meta data (typically directory updates).
- * Which then must be flushed and logged before
- * we can write the unmount record.
- */
- do {
- xfs_syncsub(mp, SYNC_REMOUNT|SYNC_ATTR|SYNC_WAIT, 0, NULL);
- pincount = xfs_flush_buftarg(mp->m_ddev_targp, 1);
- if (!pincount) {
- delay(50);
- count++;
- }
- } while (count < 2);
-
- return 0;
-}
-
-/* XXXKAN */
-#define pagebuf_delwri_flush(a,b,c) \
- do { \
- printf("pagebuf_delwri_flush NI\n"); \
- if (c) *((int *)(c)) = 0; \
- } while(0)
-
-STATIC int
-xfs_mntupdate(
- bhv_desc_t *bdp,
- int *flags,
- struct xfs_mount_args *args)
-{
- struct xfs_vfs *vfsp = bhvtovfs(bdp);
- xfs_mount_t *mp = XFS_BHVTOM(bdp);
- int error;
-
-#ifdef RMC
- if (!(*flags & MS_RDONLY)) { /* rw/ro -> rw */
-#endif
- if (!(*flags & VFS_RDONLY)) { /* rw/ro -> rw */
- if (vfsp->vfs_flag & VFS_RDONLY)
- vfsp->vfs_flag &= ~VFS_RDONLY;
- if (args->flags & XFSMNT_BARRIER) {
- mp->m_flags |= XFS_MOUNT_BARRIER;
- xfs_mountfs_check_barriers(mp);
- } else {
- mp->m_flags &= ~XFS_MOUNT_BARRIER;
- }
- } else if (!(vfsp->vfs_flag & VFS_RDONLY)) { /* rw -> ro */
- XVFS_SYNC(vfsp, SYNC_FSDATA|SYNC_BDFLUSH|SYNC_ATTR, NULL, error);
- xfs_quiesce_fs(mp);
- xfs_log_unmount_write(mp);
- xfs_unmountfs_writesb(mp);
- vfsp->vfs_flag |= VFS_RDONLY;
- }
- return 0;
-}
-
-/*
- * xfs_unmount_flush implements a set of flush operation on special
- * inodes, which are needed as a separate set of operations so that
- * they can be called as part of relocation process.
- */
-int
-xfs_unmount_flush(
- xfs_mount_t *mp, /* Mount structure we are getting
- rid of. */
- int relocation) /* Called from vfs relocation. */
-{
- xfs_inode_t *rip = mp->m_rootip;
- xfs_inode_t *rbmip;
- xfs_inode_t *rsumip = NULL;
- xfs_vnode_t *rvp = XFS_ITOV_NULL(rip);
- int error;
-
- if (rvp == NULL)
- return (0);
- xfs_ilock(rip, XFS_ILOCK_EXCL);
- xfs_iflock(rip);
-
- /*
- * Flush out the real time inodes.
- */
- if ((rbmip = mp->m_rbmip) != NULL) {
- xfs_ilock(rbmip, XFS_ILOCK_EXCL);
- xfs_iflock(rbmip);
- error = xfs_iflush(rbmip, XFS_IFLUSH_SYNC);
- xfs_iunlock(rbmip, XFS_ILOCK_EXCL);
-
- if (error == EFSCORRUPTED)
- goto fscorrupt_out;
-
- ASSERT(vn_count(XFS_ITOV(rbmip)) == 1);
-
- rsumip = mp->m_rsumip;
- xfs_ilock(rsumip, XFS_ILOCK_EXCL);
- xfs_iflock(rsumip);
- error = xfs_iflush(rsumip, XFS_IFLUSH_SYNC);
- xfs_iunlock(rsumip, XFS_ILOCK_EXCL);
-
- if (error == EFSCORRUPTED)
- goto fscorrupt_out;
-
- ASSERT(vn_count(XFS_ITOV(rsumip)) == 1);
- }
-
- /*
- * Synchronously flush root inode to disk
- */
- error = xfs_iflush(rip, XFS_IFLUSH_SYNC);
- if (error == EFSCORRUPTED)
- goto fscorrupt_out2;
-
- if (vn_count(rvp) != 1 && !relocation) {
- xfs_iunlock(rip, XFS_ILOCK_EXCL);
- return XFS_ERROR(EBUSY);
- }
-
- /*
- * Release dquot that rootinode, rbmino and rsumino might be holding,
- * flush and purge the quota inodes.
- */
- error = XFS_QM_UNMOUNT(mp);
- if (error == EFSCORRUPTED)
- goto fscorrupt_out2;
-
- if (rbmip) {
- VN_RELE(XFS_ITOV(rbmip));
- VN_RELE(XFS_ITOV(rsumip));
- }
-
- xfs_iunlock(rip, XFS_ILOCK_EXCL);
- return 0;
-
-fscorrupt_out:
- xfs_ifunlock(rip);
-
-fscorrupt_out2:
- xfs_iunlock(rip, XFS_ILOCK_EXCL);
-
- return XFS_ERROR(EFSCORRUPTED);
-}
-
-/*
- * xfs_root extracts the root vnode from a vfs.
- *
- * vfsp -- the vfs struct for the desired file system
- * vpp -- address of the caller's vnode pointer which should be
- * set to the desired fs root vnode
- */
-STATIC int
-xfs_root(
- bhv_desc_t *bdp,
- xfs_vnode_t **vpp)
-{
- xfs_vnode_t *vp;
-
- vp = XFS_ITOV((XFS_BHVTOM(bdp))->m_rootip);
- VN_HOLD(vp);
- *vpp = vp;
- return 0;
-}
-
-/*
- * xfs_statvfs
- *
- * Fill in the statvfs structure for the given file system. We use
- * the superblock lock in the mount structure to ensure a consistent
- * snapshot of the counters returned.
- */
-STATIC int
-xfs_statvfs(
- bhv_desc_t *bdp,
- xfs_statfs_t *statp,
- xfs_vnode_t *vp)
-{
- __uint64_t fakeinos;
- xfs_extlen_t lsize;
- xfs_mount_t *mp;
- xfs_sb_t *sbp;
- unsigned long s;
-
- mp = XFS_BHVTOM(bdp);
- sbp = &(mp->m_sb);
-
- statp->f_type = XFS_SB_MAGIC;
-
- xfs_icsb_sync_counters_lazy(mp);
- s = XFS_SB_LOCK(mp);
- statp->f_bsize = sbp->sb_blocksize;
- lsize = sbp->sb_logstart ? sbp->sb_logblocks : 0;
- statp->f_blocks = sbp->sb_dblocks - lsize;
- statp->f_bfree = statp->f_bavail = sbp->sb_fdblocks;
- fakeinos = statp->f_bfree << sbp->sb_inopblog;
-#if XFS_BIG_INUMS
- fakeinos += mp->m_inoadd;
-#endif
- statp->f_files =
- MIN(sbp->sb_icount + fakeinos, (__uint64_t)XFS_MAXINUMBER);
- if (mp->m_maxicount)
-#if XFS_BIG_INUMS
- if (!mp->m_inoadd)
-#endif
- statp->f_files = min_t(typeof(statp->f_files),
- statp->f_files,
- mp->m_maxicount);
- statp->f_ffree = statp->f_files - (sbp->sb_icount - sbp->sb_ifree);
- XFS_SB_UNLOCK(mp, s);
-
- xfs_statvfs_fsid(statp, mp);
- return 0;
-}
-
-
-/*
- * xfs_sync flushes any pending I/O to file system vfsp.
- *
- * This routine is called by vfs_sync() to make sure that things make it
- * out to disk eventually, on sync() system calls to flush out everything,
- * and when the file system is unmounted. For the vfs_sync() case, all
- * we really need to do is sync out the log to make all of our meta-data
- * updates permanent (except for timestamps). For calls from pflushd(),
- * dirty pages are kept moving by calling pdflush() on the inodes
- * containing them. We also flush the inodes that we can lock without
- * sleeping and the superblock if we can lock it without sleeping from
- * vfs_sync() so that items at the tail of the log are always moving out.
- *
- * Flags:
- * SYNC_BDFLUSH - We're being called from vfs_sync() so we don't want
- * to sleep if we can help it. All we really need
- * to do is ensure that the log is synced at least
- * periodically. We also push the inodes and
- * superblock if we can lock them without sleeping
- * and they are not pinned.
- * SYNC_ATTR - We need to flush the inodes. If SYNC_BDFLUSH is not
- * set, then we really want to lock each inode and flush
- * it.
- * SYNC_WAIT - All the flushes that take place in this call should
- * be synchronous.
- * SYNC_DELWRI - This tells us to push dirty pages associated with
- * inodes. SYNC_WAIT and SYNC_BDFLUSH are used to
- * determine if they should be flushed sync, async, or
- * delwri.
- * SYNC_CLOSE - This flag is passed when the system is being
- * unmounted. We should sync and invalidate everything.
- * SYNC_FSDATA - This indicates that the caller would like to make
- * sure the superblock is safe on disk. We can ensure
- * this by simply making sure the log gets flushed
- * if SYNC_BDFLUSH is set, and by actually writing it
- * out otherwise.
- *
- */
-/*ARGSUSED*/
-STATIC int
-xfs_sync(
- bhv_desc_t *bdp,
- int flags,
- cred_t *credp)
-{
- xfs_mount_t *mp = XFS_BHVTOM(bdp);
-
- if (unlikely(flags == SYNC_QUIESCE))
- return xfs_quiesce_fs(mp);
- else
- return xfs_syncsub(mp, flags, 0, NULL);
-}
-
-/*
- * xfs sync routine for internal use
- *
- * This routine supports all of the flags defined for the generic VFS_SYNC
- * interface as explained above under xfs_sync. In the interests of not
- * changing interfaces within the 6.5 family, additional internally-
- * required functions are specified within a separate xflags parameter,
- * only available by calling this routine.
- *
- */
-int
-xfs_sync_inodes(
- xfs_mount_t *mp,
- int flags,
- int xflags,
- int *bypassed)
-{
- xfs_inode_t *ip = NULL;
- xfs_inode_t *ip_next;
- xfs_buf_t *bp;
- xfs_vnode_t *vp = NULL;
- int error;
- int last_error;
- uint64_t fflag;
- uint lock_flags;
- uint base_lock_flags;
- boolean_t mount_locked;
- boolean_t vnode_refed;
- int preempt;
- xfs_dinode_t *dip;
- xfs_iptr_t *ipointer;
-#ifdef DEBUG
- boolean_t ipointer_in = B_FALSE;
-
-#define IPOINTER_SET ipointer_in = B_TRUE
-#define IPOINTER_CLR ipointer_in = B_FALSE
-#else
-#define IPOINTER_SET
-#define IPOINTER_CLR
-#endif
-
-
-/* Insert a marker record into the inode list after inode ip. The list
- * must be locked when this is called. After the call the list will no
- * longer be locked.
- */
-#define IPOINTER_INSERT(ip, mp) { \
- ASSERT(ipointer_in == B_FALSE); \
- ipointer->ip_mnext = ip->i_mnext; \
- ipointer->ip_mprev = ip; \
- ip->i_mnext = (xfs_inode_t *)ipointer; \
- ipointer->ip_mnext->i_mprev = (xfs_inode_t *)ipointer; \
- preempt = 0; \
- XFS_MOUNT_IUNLOCK(mp); \
- mount_locked = B_FALSE; \
- IPOINTER_SET; \
- }
-
-/* Remove the marker from the inode list. If the marker was the only item
- * in the list then there are no remaining inodes and we should zero out
- * the whole list. If we are the current head of the list then move the head
- * past us.
- */
-#define IPOINTER_REMOVE(ip, mp) { \
- ASSERT(ipointer_in == B_TRUE); \
- if (ipointer->ip_mnext != (xfs_inode_t *)ipointer) { \
- ip = ipointer->ip_mnext; \
- ip->i_mprev = ipointer->ip_mprev; \
- ipointer->ip_mprev->i_mnext = ip; \
- if (mp->m_inodes == (xfs_inode_t *)ipointer) { \
- mp->m_inodes = ip; \
- } \
- } else { \
- ASSERT(mp->m_inodes == (xfs_inode_t *)ipointer); \
- mp->m_inodes = NULL; \
- ip = NULL; \
- } \
- IPOINTER_CLR; \
- }
-
-#define XFS_PREEMPT_MASK 0x7f
-
- if (bypassed)
- *bypassed = 0;
- if (XFS_MTOVFS(mp)->vfs_flag & VFS_RDONLY)
- return 0;
- error = 0;
- last_error = 0;
- preempt = 0;
-
- /* Allocate a reference marker */
- ipointer = (xfs_iptr_t *)kmem_zalloc(sizeof(xfs_iptr_t), KM_SLEEP);
-
- fflag = XFS_B_ASYNC; /* default is don't wait */
- if (flags & (SYNC_BDFLUSH | SYNC_DELWRI))
- fflag = XFS_B_DELWRI;
- if (flags & SYNC_WAIT)
- fflag = 0; /* synchronous overrides all */
-
- base_lock_flags = XFS_ILOCK_SHARED;
- if (flags & (SYNC_DELWRI | SYNC_CLOSE)) {
- /*
- * We need the I/O lock if we're going to call any of
- * the flush/inval routines.
- */
- base_lock_flags |= XFS_IOLOCK_SHARED;
- }
-
- XFS_MOUNT_ILOCK(mp);
-
- ip = mp->m_inodes;
-
- mount_locked = B_TRUE;
- vnode_refed = B_FALSE;
-
- IPOINTER_CLR;
-
- do {
- ASSERT(ipointer_in == B_FALSE);
- ASSERT(vnode_refed == B_FALSE);
-
- lock_flags = base_lock_flags;
-
- /*
- * There were no inodes in the list, just break out
- * of the loop.
- */
- if (ip == NULL) {
- break;
- }
-
- /*
- * We found another sync thread marker - skip it
- */
- if (ip->i_mount == NULL) {
- ip = ip->i_mnext;
- continue;
- }
-
- vp = XFS_ITOV_NULL(ip);
-
- /*
- * If the vnode is gone then this is being torn down,
- * call reclaim if it is flushed, else let regular flush
- * code deal with it later in the loop.
- */
-
- if (vp == NULL) {
- /* Skip ones already in reclaim */
- if (ip->i_flags & XFS_IRECLAIM) {
- ip = ip->i_mnext;
- continue;
- }
- if (xfs_ilock_nowait(ip, XFS_ILOCK_EXCL) == 0) {
- ip = ip->i_mnext;
- } else if ((xfs_ipincount(ip) == 0) &&
- xfs_iflock_nowait(ip)) {
- IPOINTER_INSERT(ip, mp);
-
- xfs_finish_reclaim(ip, 1,
- XFS_IFLUSH_DELWRI_ELSE_ASYNC);
-
- XFS_MOUNT_ILOCK(mp);
- mount_locked = B_TRUE;
- IPOINTER_REMOVE(ip, mp);
- } else {
- xfs_iunlock(ip, XFS_ILOCK_EXCL);
- ip = ip->i_mnext;
- }
- continue;
- }
-
- if (VN_BAD(vp)) {
- ip = ip->i_mnext;
- continue;
- }
-
- if (XFS_FORCED_SHUTDOWN(mp) && !(flags & SYNC_CLOSE)) {
- XFS_MOUNT_IUNLOCK(mp);
- kmem_free(ipointer, sizeof(xfs_iptr_t));
- return 0;
- }
-
- /*
- * If this is just vfs_sync() or pflushd() calling
- * then we can skip inodes for which it looks like
- * there is nothing to do. Since we don't have the
- * inode locked this is racy, but these are periodic
- * calls so it doesn't matter. For the others we want
- * to know for sure, so we at least try to lock them.
- */
- if (flags & SYNC_BDFLUSH) {
- if (((ip->i_itemp == NULL) ||
- !(ip->i_itemp->ili_format.ilf_fields &
- XFS_ILOG_ALL)) &&
- (ip->i_update_core == 0)) {
- ip = ip->i_mnext;
- continue;
- }
- }
-
- /*
- * Try to lock without sleeping. We're out of order with
- * the inode list lock here, so if we fail we need to drop
- * the mount lock and try again. If we're called from
- * bdflush() here, then don't bother.
- *
- * The inode lock here actually coordinates with the
- * almost spurious inode lock in xfs_ireclaim() to prevent
- * the vnode we handle here without a reference from
- * being freed while we reference it. If we lock the inode
- * while it's on the mount list here, then the spurious inode
- * lock in xfs_ireclaim() after the inode is pulled from
- * the mount list will sleep until we release it here.
- * This keeps the vnode from being freed while we reference
- * it.
- */
- if (xfs_ilock_nowait(ip, lock_flags) == 0) {
- if ((flags & SYNC_BDFLUSH) || (vp == NULL)) {
- ip = ip->i_mnext;
- continue;
- }
-
- vp = vn_grab(vp);
- if (vp == NULL) {
- ip = ip->i_mnext;
- continue;
- }
-
- IPOINTER_INSERT(ip, mp);
- xfs_ilock(ip, lock_flags);
-
- ASSERT(vp == XFS_ITOV(ip));
- ASSERT(ip->i_mount == mp);
-
- vnode_refed = B_TRUE;
- }
-
- /* From here on in the loop we may have a marker record
- * in the inode list.
- */
-
- if ((flags & SYNC_CLOSE) && (vp != NULL)) {
- /*
- * This is the shutdown case. We just need to
- * flush and invalidate all the pages associated
- * with the inode. Drop the inode lock since
- * we can't hold it across calls to the buffer
- * cache.
- *
- * We don't set the VREMAPPING bit in the vnode
- * here, because we don't hold the vnode lock
- * exclusively. It doesn't really matter, though,
- * because we only come here when we're shutting
- * down anyway.
- */
- xfs_iunlock(ip, XFS_ILOCK_SHARED);
-
- if (XFS_FORCED_SHUTDOWN(mp)) {
- XVOP_TOSS_PAGES(vp, 0, -1, FI_REMAPF);
- } else {
- XVOP_FLUSHINVAL_PAGES(vp, 0, -1, FI_REMAPF);
- }
-
- xfs_ilock(ip, XFS_ILOCK_SHARED);
-
- } else if ((flags & SYNC_DELWRI) && (vp != NULL)) {
- if (VN_DIRTY(vp)) {
- /* We need to have dropped the lock here,
- * so insert a marker if we have not already
- * done so.
- */
- if (mount_locked) {
- IPOINTER_INSERT(ip, mp);
- }
-
- /*
- * Drop the inode lock since we can't hold it
- * across calls to the buffer cache.
- */
- xfs_iunlock(ip, XFS_ILOCK_SHARED);
- XVOP_FLUSH_PAGES(vp, (xfs_off_t)0, -1,
- fflag, FI_NONE, error);
- xfs_ilock(ip, XFS_ILOCK_SHARED);
- }
-
- }
-
- if (flags & SYNC_BDFLUSH) {
- if ((flags & SYNC_ATTR) &&
- ((ip->i_update_core) ||
- ((ip->i_itemp != NULL) &&
- (ip->i_itemp->ili_format.ilf_fields != 0)))) {
-
- /* Insert marker and drop lock if not already
- * done.
- */
- if (mount_locked) {
- IPOINTER_INSERT(ip, mp);
- }
-
- /*
- * We don't want the periodic flushing of the
- * inodes by vfs_sync() to interfere with
- * I/O to the file, especially read I/O
- * where it is only the access time stamp
- * that is being flushed out. To prevent
- * long periods where we have both inode
- * locks held shared here while reading the
- * inode's buffer in from disk, we drop the
- * inode lock while reading in the inode
- * buffer. We have to release the buffer
- * and reacquire the inode lock so that they
- * are acquired in the proper order (inode
- * locks first). The buffer will go at the
- * end of the lru chain, though, so we can
- * expect it to still be there when we go
- * for it again in xfs_iflush().
- */
- if ((xfs_ipincount(ip) == 0) &&
- xfs_iflock_nowait(ip)) {
-
- xfs_ifunlock(ip);
- xfs_iunlock(ip, XFS_ILOCK_SHARED);
-
- error = xfs_itobp(mp, NULL, ip,
- &dip, &bp, 0, 0);
- if (!error) {
- xfs_buf_relse(bp);
- } else {
- /* Bailing out, remove the
- * marker and free it.
- */
- XFS_MOUNT_ILOCK(mp);
-
- IPOINTER_REMOVE(ip, mp);
-
- XFS_MOUNT_IUNLOCK(mp);
-
- ASSERT(!(lock_flags &
- XFS_IOLOCK_SHARED));
-
- kmem_free(ipointer,
- sizeof(xfs_iptr_t));
- return (0);
- }
-
- /*
- * Since we dropped the inode lock,
- * the inode may have been reclaimed.
- * Therefore, we reacquire the mount
- * lock and check to see if we were the
- * inode reclaimed. If this happened
- * then the ipointer marker will no
- * longer point back at us. In this
- * case, move ip along to the inode
- * after the marker, remove the marker
- * and continue.
- */
- XFS_MOUNT_ILOCK(mp);
- mount_locked = B_TRUE;
-
- if (ip != ipointer->ip_mprev) {
- IPOINTER_REMOVE(ip, mp);
-
- ASSERT(!vnode_refed);
- ASSERT(!(lock_flags &
- XFS_IOLOCK_SHARED));
- continue;
- }
-
- ASSERT(ip->i_mount == mp);
-
- if (xfs_ilock_nowait(ip,
- XFS_ILOCK_SHARED) == 0) {
- ASSERT(ip->i_mount == mp);
- /*
- * We failed to reacquire
- * the inode lock without
- * sleeping, so just skip
- * the inode for now. We
- * clear the ILOCK bit from
- * the lock_flags so that we
- * won't try to drop a lock
- * we don't hold below.
- */
- lock_flags &= ~XFS_ILOCK_SHARED;
- IPOINTER_REMOVE(ip_next, mp);
- } else if ((xfs_ipincount(ip) == 0) &&
- xfs_iflock_nowait(ip)) {
- ASSERT(ip->i_mount == mp);
- /*
- * Since this is vfs_sync()
- * calling we only flush the
- * inode out if we can lock
- * it without sleeping and
- * it is not pinned. Drop
- * the mount lock here so
- * that we don't hold it for
- * too long. We already have
- * a marker in the list here.
- */
- XFS_MOUNT_IUNLOCK(mp);
- mount_locked = B_FALSE;
- error = xfs_iflush(ip,
- XFS_IFLUSH_DELWRI);
- } else {
- ASSERT(ip->i_mount == mp);
- IPOINTER_REMOVE(ip_next, mp);
- }
- }
-
- }
-
- } else {
- if ((flags & SYNC_ATTR) &&
- ((ip->i_update_core) ||
- ((ip->i_itemp != NULL) &&
- (ip->i_itemp->ili_format.ilf_fields != 0)))) {
- if (mount_locked) {
- IPOINTER_INSERT(ip, mp);
- }
-
- if (flags & SYNC_WAIT) {
- xfs_iflock(ip);
- error = xfs_iflush(ip,
- XFS_IFLUSH_SYNC);
- } else {
- /*
- * If we can't acquire the flush
- * lock, then the inode is already
- * being flushed so don't bother
- * waiting. If we can lock it then
- * do a delwri flush so we can
- * combine multiple inode flushes
- * in each disk write.
- */
- if (xfs_iflock_nowait(ip)) {
- error = xfs_iflush(ip,
- XFS_IFLUSH_DELWRI);
- }
- else if (bypassed)
- (*bypassed)++;
- }
- }
- }
-
- if (lock_flags != 0) {
- xfs_iunlock(ip, lock_flags);
- }
-
- if (vnode_refed) {
- /*
- * If we had to take a reference on the vnode
- * above, then wait until after we've unlocked
- * the inode to release the reference. This is
- * because we can be already holding the inode
- * lock when VN_RELE() calls xfs_inactive().
- *
- * Make sure to drop the mount lock before calling
- * VN_RELE() so that we don't trip over ourselves if
- * we have to go for the mount lock again in the
- * inactive code.
- */
- if (mount_locked) {
- IPOINTER_INSERT(ip, mp);
- }
-
- VN_RELE(vp);
-
- vnode_refed = B_FALSE;
- }
-
- if (error) {
- last_error = error;
- }
-
- /*
- * bail out if the filesystem is corrupted.
- */
- if (error == EFSCORRUPTED) {
- if (!mount_locked) {
- XFS_MOUNT_ILOCK(mp);
- IPOINTER_REMOVE(ip, mp);
- }
- XFS_MOUNT_IUNLOCK(mp);
- ASSERT(ipointer_in == B_FALSE);
- kmem_free(ipointer, sizeof(xfs_iptr_t));
- return XFS_ERROR(error);
- }
-
- /* Let other threads have a chance at the mount lock
- * if we have looped many times without dropping the
- * lock.
- */
- if ((++preempt & XFS_PREEMPT_MASK) == 0) {
- if (mount_locked) {
- IPOINTER_INSERT(ip, mp);
- }
- }
-
- if (mount_locked == B_FALSE) {
- XFS_MOUNT_ILOCK(mp);
- mount_locked = B_TRUE;
- IPOINTER_REMOVE(ip, mp);
- continue;
- }
-
- ASSERT(ipointer_in == B_FALSE);
- ip = ip->i_mnext;
-
- } while (ip != mp->m_inodes);
-
- XFS_MOUNT_IUNLOCK(mp);
-
- ASSERT(ipointer_in == B_FALSE);
-
- kmem_free(ipointer, sizeof(xfs_iptr_t));
- return XFS_ERROR(last_error);
-}
-
-/*
- * xfs sync routine for internal use
- *
- * This routine supports all of the flags defined for the generic VFS_SYNC
- * interface as explained above under xfs_sync. In the interests of not
- * changing interfaces within the 6.5 family, additional internally-
- * required functions are specified within a separate xflags parameter,
- * only available by calling this routine.
- *
- */
-int
-xfs_syncsub(
- xfs_mount_t *mp,
- int flags,
- int xflags,
- int *bypassed)
-{
- int error = 0;
- int last_error = 0;
- uint log_flags = XFS_LOG_FORCE;
- xfs_buf_t *bp;
- xfs_buf_log_item_t *bip;
-
- /*
- * Sync out the log. This ensures that the log is periodically
- * flushed even if there is not enough activity to fill it up.
- */
- if (flags & SYNC_WAIT)
- log_flags |= XFS_LOG_SYNC;
-
- xfs_log_force(mp, (xfs_lsn_t)0, log_flags);
-
- if (flags & (SYNC_ATTR|SYNC_DELWRI)) {
- if (flags & SYNC_BDFLUSH)
- xfs_finish_reclaim_all(mp, 1);
- else
- error = xfs_sync_inodes(mp, flags, xflags, bypassed);
- }
-
- /*
- * Flushing out dirty data above probably generated more
- * log activity, so if this isn't vfs_sync() then flush
- * the log again.
- */
- if (flags & SYNC_DELWRI) {
- xfs_log_force(mp, (xfs_lsn_t)0, log_flags);
- }
-
- if (flags & SYNC_FSDATA) {
- /*
- * If this is vfs_sync() then only sync the superblock
- * if we can lock it without sleeping and it is not pinned.
- */
- if (flags & SYNC_BDFLUSH) {
- bp = xfs_getsb(mp, XFS_BUF_TRYLOCK);
- if (bp != NULL) {
- bip = XFS_BUF_FSPRIVATE(bp,xfs_buf_log_item_t*);
- if ((bip != NULL) &&
- xfs_buf_item_dirty(bip)) {
- if (!(XFS_BUF_ISPINNED(bp))) {
- XFS_BUF_ASYNC(bp);
- error = xfs_bwrite(mp, bp);
- } else {
- xfs_buf_relse(bp);
- }
- } else {
- xfs_buf_relse(bp);
- }
- }
- } else {
- bp = xfs_getsb(mp, 0);
- /*
- * If the buffer is pinned then push on the log so
- * we won't get stuck waiting in the write for
- * someone, maybe ourselves, to flush the log.
- * Even though we just pushed the log above, we
- * did not have the superblock buffer locked at
- * that point so it can become pinned in between
- * there and here.
- */
- if (XFS_BUF_ISPINNED(bp))
- xfs_log_force(mp, (xfs_lsn_t)0, XFS_LOG_FORCE);
- if (flags & SYNC_WAIT)
- XFS_BUF_UNASYNC(bp);
- else
- XFS_BUF_ASYNC(bp);
- error = xfs_bwrite(mp, bp);
- }
- if (error) {
- last_error = error;
- }
- }
-
- /*
- * If this is the periodic sync, then kick some entries out of
- * the reference cache. This ensures that idle entries are
- * eventually kicked out of the cache.
- */
- if (flags & SYNC_REFCACHE) {
- if (flags & SYNC_WAIT)
- xfs_refcache_purge_mp(mp);
- else
- xfs_refcache_purge_some(mp);
- }
-
- /*
- * Now check to see if the log needs a "dummy" transaction.
- */
-
- if (!(flags & SYNC_REMOUNT) && xfs_log_need_covered(mp)) {
- xfs_trans_t *tp;
- xfs_inode_t *ip;
-
- /*
- * Put a dummy transaction in the log to tell
- * recovery that all others are OK.
- */
- tp = xfs_trans_alloc(mp, XFS_TRANS_DUMMY1);
- if ((error = xfs_trans_reserve(tp, 0,
- XFS_ICHANGE_LOG_RES(mp),
- 0, 0, 0))) {
- xfs_trans_cancel(tp, 0);
- return error;
- }
-
- ip = mp->m_rootip;
- xfs_ilock(ip, XFS_ILOCK_EXCL);
-
- xfs_trans_ijoin(tp, ip, XFS_ILOCK_EXCL);
- xfs_trans_ihold(tp, ip);
- xfs_trans_log_inode(tp, ip, XFS_ILOG_CORE);
- error = xfs_trans_commit(tp, 0, NULL);
- xfs_iunlock(ip, XFS_ILOCK_EXCL);
- xfs_log_force(mp, (xfs_lsn_t)0, log_flags);
- }
-
- /*
- * When shutting down, we need to insure that the AIL is pushed
- * to disk or the filesystem can appear corrupt from the PROM.
- */
- if ((flags & (SYNC_CLOSE|SYNC_WAIT)) == (SYNC_CLOSE|SYNC_WAIT)) {
- XFS_bflush(mp->m_ddev_targp);
- if (mp->m_rtdev_targp) {
- XFS_bflush(mp->m_rtdev_targp);
- }
- }
-
- return XFS_ERROR(last_error);
-}
-
-/*
- * xfs_vget - called by DMAPI and NFSD to get vnode from file handle
- */
-STATIC int
-xfs_vget(
- bhv_desc_t *bdp,
- xfs_vnode_t **vpp,
- fid_t *fidp)
-{
- xfs_mount_t *mp = XFS_BHVTOM(bdp);
- xfs_fid_t *xfid = (struct xfs_fid *)fidp;
- xfs_inode_t *ip;
- int error;
- xfs_ino_t ino;
- unsigned int igen;
-
- /*
- * Invalid. Since handles can be created in user space and passed in
- * via gethandle(), this is not cause for a panic.
- */
- if (xfid->xfs_fid_len != sizeof(*xfid) - sizeof(xfid->xfs_fid_len))
- return XFS_ERROR(EINVAL);
-
- ino = xfid->xfs_fid_ino;
- igen = xfid->xfs_fid_gen;
-
- /*
- * NFS can sometimes send requests for ino 0. Fail them gracefully.
- */
- if (ino == 0)
- return XFS_ERROR(ESTALE);
-
- error = xfs_iget(mp, NULL, ino, 0, XFS_ILOCK_SHARED, &ip, 0);
- if (error) {
- *vpp = NULL;
- return error;
- }
-
- if (ip == NULL) {
- *vpp = NULL;
- return XFS_ERROR(EIO);
- }
-
- if (ip->i_d.di_mode == 0 || ip->i_d.di_gen != igen) {
- xfs_iput_new(ip, XFS_ILOCK_SHARED);
- *vpp = NULL;
- return XFS_ERROR(ENOENT);
- }
-
- *vpp = XFS_ITOV(ip);
- xfs_iunlock(ip, XFS_ILOCK_SHARED);
- return 0;
-}
-
-
-#define MNTOPT_LOGBUFS "logbufs" /* number of XFS log buffers */
-#define MNTOPT_LOGBSIZE "logbsize" /* size of XFS log buffers */
-#define MNTOPT_LOGDEV "logdev" /* log device */
-#define MNTOPT_RTDEV "rtdev" /* realtime I/O device */
-#define MNTOPT_BIOSIZE "biosize" /* log2 of preferred buffered io size */
-#define MNTOPT_WSYNC "wsync" /* safe-mode nfs compatible mount */
-#define MNTOPT_INO64 "ino64" /* force inodes into 64-bit range */
-#define MNTOPT_NOALIGN "noalign" /* turn off stripe alignment */
-#define MNTOPT_SWALLOC "swalloc" /* turn on stripe width allocation */
-#define MNTOPT_SUNIT "sunit" /* data volume stripe unit */
-#define MNTOPT_SWIDTH "swidth" /* data volume stripe width */
-#define MNTOPT_NOUUID "nouuid" /* ignore filesystem UUID */
-#define MNTOPT_MTPT "mtpt" /* filesystem mount point */
-#define MNTOPT_GRPID "grpid" /* group-ID from parent directory */
-#define MNTOPT_NOGRPID "nogrpid" /* group-ID from current process */
-#define MNTOPT_BSDGROUPS "bsdgroups" /* group-ID from parent directory */
-#define MNTOPT_SYSVGROUPS "sysvgroups" /* group-ID from current process */
-#define MNTOPT_ALLOCSIZE "allocsize" /* preferred allocation size */
-#define MNTOPT_IHASHSIZE "ihashsize" /* size of inode hash table */
-#define MNTOPT_NORECOVERY "norecovery" /* don't run XFS recovery */
-#define MNTOPT_BARRIER "barrier" /* use writer barriers for log write and
- * unwritten extent conversion */
-#define MNTOPT_NOBARRIER "nobarrier" /* .. disable */
-#define MNTOPT_OSYNCISOSYNC "osyncisosync" /* o_sync is REALLY o_sync */
-#define MNTOPT_64BITINODE "inode64" /* inodes can be allocated anywhere */
-#define MNTOPT_IKEEP "ikeep" /* do not free empty inode clusters */
-#define MNTOPT_NOIKEEP "noikeep" /* free empty inode clusters */
-#define MNTOPT_LARGEIO "largeio" /* report large I/O sizes in stat() */
-#define MNTOPT_NOLARGEIO "nolargeio" /* do not report large I/O sizes
- * in stat(). */
-#define MNTOPT_ATTR2 "attr2" /* do use attr2 attribute format */
-#define MNTOPT_NOATTR2 "noattr2" /* do not use attr2 attribute format */
-#define simple_strtoul strtoul
-
-STATIC unsigned long
-suffix_strtoul(char *cp, char **endp, unsigned int base)
-{
- int last, shift_left_factor = 0;
- char *value = (char *)cp;
-
- last = strlen(value) - 1;
- if (value[last] == 'K' || value[last] == 'k') {
- shift_left_factor = 10;
- value[last] = '\0';
- }
- if (value[last] == 'M' || value[last] == 'm') {
- shift_left_factor = 20;
- value[last] = '\0';
- }
- if (value[last] == 'G' || value[last] == 'g') {
- shift_left_factor = 30;
- value[last] = '\0';
- }
-
- return simple_strtoul(cp, endp, base) << shift_left_factor;
-}
-
-
-STATIC int
-xfs_parseargs(
- struct bhv_desc *bhv,
- char *options,
- struct xfs_mount_args *args,
- int update)
-{
- struct xfs_vfs *vfsp = bhvtovfs(bhv);
- char *this_char, *value, *eov;
- int dsunit, dswidth, vol_dsunit, vol_dswidth;
- int iosize;
-
- args->flags |= XFSMNT_IDELETE;
- args->flags |= XFSMNT_BARRIER;
- args->flags2 |= XFSMNT2_COMPAT_IOSIZE;
-
- if (!options)
- goto done;
-
- iosize = dsunit = dswidth = vol_dsunit = vol_dswidth = 0;
-
- while ((this_char = strsep(&options, ",")) != NULL) {
- if (!*this_char)
- continue;
- if ((value = strchr(this_char, '=')) != NULL)
- *value++ = 0;
-
- if (!strcmp(this_char, MNTOPT_LOGBUFS)) {
- if (!value || !*value) {
- printf("XFS: %s option requires an argument\n",
- this_char);
- return EINVAL;
- }
- args->logbufs = simple_strtoul(value, &eov, 10);
- } else if (!strcmp(this_char, MNTOPT_LOGBSIZE)) {
- if (!value || !*value) {
- printf("XFS: %s option requires an argument\n",
- this_char);
- return EINVAL;
- }
- args->logbufsize = suffix_strtoul(value, &eov, 10);
- } else if (!strcmp(this_char, MNTOPT_LOGDEV)) {
- if (!value || !*value) {
- printf("XFS: %s option requires an argument\n",
- this_char);
- return EINVAL;
- }
- strncpy(args->logname, value, MAXNAMELEN);
- } else if (!strcmp(this_char, MNTOPT_MTPT)) {
- if (!value || !*value) {
- printf("XFS: %s option requires an argument\n",
- this_char);
- return EINVAL;
- }
- strncpy(args->mtpt, value, MAXNAMELEN);
- } else if (!strcmp(this_char, MNTOPT_RTDEV)) {
- if (!value || !*value) {
- printf("XFS: %s option requires an argument\n",
- this_char);
- return EINVAL;
- }
- strncpy(args->rtname, value, MAXNAMELEN);
- } else if (!strcmp(this_char, MNTOPT_BIOSIZE)) {
- if (!value || !*value) {
- printf("XFS: %s option requires an argument\n",
- this_char);
- return EINVAL;
- }
- iosize = simple_strtoul(value, &eov, 10);
- args->flags |= XFSMNT_IOSIZE;
- args->iosizelog = (uint8_t) iosize;
- } else if (!strcmp(this_char, MNTOPT_ALLOCSIZE)) {
- if (!value || !*value) {
- printk("XFS: %s option requires an argument\n",
- this_char);
- return EINVAL;
- }
- iosize = suffix_strtoul(value, &eov, 10);
- args->flags |= XFSMNT_IOSIZE;
- args->iosizelog = ffs(iosize) - 1;
- } else if (!strcmp(this_char, MNTOPT_IHASHSIZE)) {
- if (!value || !*value) {
- printk("XFS: %s option requires an argument\n",
- this_char);
- return EINVAL;
- }
- args->flags |= XFSMNT_IHASHSIZE;
- args->ihashsize = simple_strtoul(value, &eov, 10);
- } else if (!strcmp(this_char, MNTOPT_GRPID) ||
- !strcmp(this_char, MNTOPT_BSDGROUPS)) {
- vfsp->vfs_flag |= VFS_GRPID;
- } else if (!strcmp(this_char, MNTOPT_NOGRPID) ||
- !strcmp(this_char, MNTOPT_SYSVGROUPS)) {
- vfsp->vfs_flag &= ~VFS_GRPID;
- } else if (!strcmp(this_char, MNTOPT_WSYNC)) {
- args->flags |= XFSMNT_WSYNC;
- } else if (!strcmp(this_char, MNTOPT_OSYNCISOSYNC)) {
- args->flags |= XFSMNT_OSYNCISOSYNC;
- } else if (!strcmp(this_char, MNTOPT_NORECOVERY)) {
- args->flags |= XFSMNT_NORECOVERY;
- } else if (!strcmp(this_char, MNTOPT_INO64)) {
- args->flags |= XFSMNT_INO64;
-#if !XFS_BIG_INUMS
-
- printf("XFS: %s option not allowed on this system\n",
- this_char);
- return EINVAL;
-#endif
- } else if (!strcmp(this_char, MNTOPT_NOALIGN)) {
- args->flags |= XFSMNT_NOALIGN;
- } else if (!strcmp(this_char, MNTOPT_SWALLOC)) {
- args->flags |= XFSMNT_SWALLOC;
- } else if (!strcmp(this_char, MNTOPT_SUNIT)) {
- if (!value || !*value) {
- printf("XFS: %s option requires an argument\n",
- this_char);
- return EINVAL;
- }
- dsunit = simple_strtoul(value, &eov, 10);
- } else if (!strcmp(this_char, MNTOPT_SWIDTH)) {
- if (!value || !*value) {
- printf("XFS: %s option requires an argument\n",
- this_char);
- return EINVAL;
- }
- dswidth = simple_strtoul(value, &eov, 10);
- } else if (!strcmp(this_char, MNTOPT_64BITINODE)) {
- args->flags &= ~XFSMNT_32BITINODES;
-#if !XFS_BIG_INUMS
-
- printf("XFS: %s option not allowed on this system\n",
- this_char);
- return EINVAL;
-#endif
- } else if (!strcmp(this_char, MNTOPT_NOUUID)) {
- args->flags |= XFSMNT_NOUUID;
- } else if (!strcmp(this_char, MNTOPT_BARRIER)) {
- args->flags |= XFSMNT_BARRIER;
- } else if (!strcmp(this_char, MNTOPT_NOBARRIER)) {
- args->flags &= ~XFSMNT_BARRIER;
- } else if (!strcmp(this_char, MNTOPT_IKEEP)) {
- args->flags &= ~XFSMNT_IDELETE;
- } else if (!strcmp(this_char, MNTOPT_NOIKEEP)) {
- args->flags |= XFSMNT_IDELETE;
- } else if (!strcmp(this_char, MNTOPT_LARGEIO)) {
- args->flags2 &= ~XFSMNT2_COMPAT_IOSIZE;
- } else if (!strcmp(this_char, MNTOPT_NOLARGEIO)) {
- args->flags2 |= XFSMNT2_COMPAT_IOSIZE;
- } else if (!strcmp(this_char, MNTOPT_ATTR2)) {
- args->flags |= XFSMNT_ATTR2;
- } else if (!strcmp(this_char, MNTOPT_NOATTR2)) {
- args->flags &= ~XFSMNT_ATTR2;
- } else if (!strcmp(this_char, "osyncisdsync")) {
- /* no-op, this is now the default */
-printf("XFS: osyncisdsync is now the default, option is deprecated.\n");
- } else if (!strcmp(this_char, "irixsgid")) {
-printf("XFS: irixsgid is now a sysctl(2) variable, option is deprecated.\n");
- } else {
- printf("XFS: unknown mount option [%s].\n", this_char);
- return EINVAL;
- }
- }
-
- if (args->flags & XFSMNT_NORECOVERY) {
- if ((vfsp->vfs_flag & VFS_RDONLY) == 0) {
- printf("XFS: no-recovery mounts must be read-only.\n");
- return EINVAL;
- }
- }
-
- if ((args->flags & XFSMNT_NOALIGN) && (dsunit || dswidth)) {
- printf(
- "XFS: sunit and swidth options incompatible with the noalign option\n");
- return EINVAL;
- }
-
- if ((dsunit && !dswidth) || (!dsunit && dswidth)) {
- printf("XFS: sunit and swidth must be specified together\n");
- return EINVAL;
- }
-
- if (dsunit && (dswidth % dsunit != 0)) {
- printf(
- "XFS: stripe width (%d) must be a multiple of the stripe unit (%d)\n",
- dswidth, dsunit);
- return EINVAL;
- }
-
- if ((args->flags & XFSMNT_NOALIGN) != XFSMNT_NOALIGN) {
- if (dsunit) {
- args->sunit = dsunit;
- args->flags |= XFSMNT_RETERR;
- } else {
- args->sunit = vol_dsunit;
- }
- dswidth ? (args->swidth = dswidth) :
- (args->swidth = vol_dswidth);
- } else {
- args->sunit = args->swidth = 0;
- }
-
-done:
- if (args->flags & XFSMNT_32BITINODES)
- vfsp->vfs_flag |= VFS_32BITINODES;
- if (args->flags2)
- args->flags |= XFSMNT_FLAGS2;
- return 0;
-}
-
-#define seq_printf sbuf_printf
-STATIC int
-xfs_showargs(
- struct bhv_desc *bhv,
- struct sbuf *m)
-{
- static struct proc_xfs_info {
- int flag;
- char *str;
- } xfs_info[] = {
- /* the few simple ones we can get from the mount struct */
- { XFS_MOUNT_WSYNC, "," MNTOPT_WSYNC },
- { XFS_MOUNT_INO64, "," MNTOPT_INO64 },
- { XFS_MOUNT_NOALIGN, "," MNTOPT_NOALIGN },
- { XFS_MOUNT_SWALLOC, "," MNTOPT_SWALLOC },
- { XFS_MOUNT_NOUUID, "," MNTOPT_NOUUID },
- { XFS_MOUNT_NORECOVERY, "," MNTOPT_NORECOVERY },
- { XFS_MOUNT_OSYNCISOSYNC, "," MNTOPT_OSYNCISOSYNC },
- { 0, NULL }
- };
- struct proc_xfs_info *xfs_infop;
- struct xfs_mount *mp = XFS_BHVTOM(bhv);
- struct xfs_vfs *vfsp = XFS_MTOVFS(mp);
-
- for (xfs_infop = xfs_info; xfs_infop->flag; xfs_infop++) {
- if (mp->m_flags & xfs_infop->flag)
- sbuf_printf(m, "%s", xfs_infop->str);
- }
-
- if (mp->m_flags & XFS_MOUNT_IHASHSIZE)
- seq_printf(m, "," MNTOPT_IHASHSIZE "=%d", mp->m_ihsize);
-
- if (mp->m_flags & XFS_MOUNT_DFLT_IOSIZE)
- seq_printf(m, "," MNTOPT_ALLOCSIZE "=%dk",
- (int)(1 << mp->m_writeio_log) >> 10);
-
- if (mp->m_logbufs > 0)
- sbuf_printf(m, "," MNTOPT_LOGBUFS "=%d", mp->m_logbufs);
- if (mp->m_logbsize > 0)
- seq_printf(m, "," MNTOPT_LOGBSIZE "=%dk", mp->m_logbsize >> 10);
-
- if (mp->m_logname)
- seq_printf(m, "," MNTOPT_LOGDEV "=%s", mp->m_logname);
- if (mp->m_rtname)
- seq_printf(m, "," MNTOPT_RTDEV "=%s", mp->m_rtname);
-
- if (mp->m_dalign > 0)
- sbuf_printf(m, "," MNTOPT_SUNIT "=%d",
- (int)XFS_FSB_TO_BB(mp, mp->m_dalign));
- if (mp->m_swidth > 0)
- sbuf_printf(m, "," MNTOPT_SWIDTH "=%d",
- (int)XFS_FSB_TO_BB(mp, mp->m_swidth));
-
- if (!(mp->m_flags & XFS_MOUNT_IDELETE))
- seq_printf(m, "," MNTOPT_IKEEP);
- if (!(mp->m_flags & XFS_MOUNT_COMPAT_IOSIZE))
- seq_printf(m, "," MNTOPT_LARGEIO);
-
- if (!(vfsp->vfs_flag & VFS_32BITINODES))
- sbuf_printf(m, "," MNTOPT_64BITINODE);
- if (vfsp->vfs_flag & VFS_GRPID)
- seq_printf(m, "," MNTOPT_GRPID);
-
- return 0;
-}
-
-STATIC void
-xfs_freeze(
- bhv_desc_t *bdp)
-{
- xfs_mount_t *mp = XFS_BHVTOM(bdp);
-
- while (atomic_read(&mp->m_active_trans) > 0)
- delay(100);
-
- /* Push the superblock and write an unmount record */
- xfs_log_unmount_write(mp);
- xfs_unmountfs_writesb(mp);
- xfs_fs_log_dummy(mp);
-}
-
-
-xvfsops_t xfs_vfsops = {
- BHV_IDENTITY_INIT(VFS_BHV_XFS,VFS_POSITION_XFS),
- .xvfs_parseargs = xfs_parseargs,
- .xvfs_showargs = xfs_showargs,
- .xvfs_mount = xfs_mount,
- .xvfs_unmount = xfs_unmount,
- .xvfs_mntupdate = xfs_mntupdate,
- .xvfs_root = xfs_root,
- .xvfs_statvfs = xfs_statvfs,
- .xvfs_sync = xfs_sync,
- .xvfs_vget = xfs_vget,
- .xvfs_dmapiops = (xvfs_dmapiops_t)fs_nosys,
- .xvfs_quotactl = (xvfs_quotactl_t)fs_nosys,
- .xvfs_get_inode = (xvfs_get_inode_t)fs_nosys,
- .xvfs_init_vnode = xfs_initialize_vnode,
- .xvfs_force_shutdown = xfs_do_force_shutdown,
- .xvfs_freeze = xfs_freeze,
-};
diff --git a/sys/gnu/fs/xfs/xfs_vnodeops.c b/sys/gnu/fs/xfs/xfs_vnodeops.c
deleted file mode 100644
index 4743cc7..0000000
--- a/sys/gnu/fs/xfs/xfs_vnodeops.c
+++ /dev/null
@@ -1,4719 +0,0 @@
-/*
- * Copyright (c) 2000-2006 Silicon Graphics, Inc.
- * All Rights Reserved.
- *
- * 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.
- *
- * This program is distributed in the hope that it would 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 the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- */
-
-#include "xfs.h"
-#include "xfs_fs.h"
-#include "xfs_types.h"
-#include "xfs_bit.h"
-#include "xfs_log.h"
-#include "xfs_inum.h"
-#include "xfs_trans.h"
-#include "xfs_sb.h"
-#include "xfs_ag.h"
-#include "xfs_dir.h"
-#include "xfs_dir2.h"
-#include "xfs_dmapi.h"
-#include "xfs_mount.h"
-#include "xfs_da_btree.h"
-#include "xfs_bmap_btree.h"
-#include "xfs_alloc_btree.h"
-#include "xfs_ialloc_btree.h"
-#include "xfs_dir_sf.h"
-#include "xfs_dir2_sf.h"
-#include "xfs_attr_sf.h"
-#include "xfs_dinode.h"
-#include "xfs_inode.h"
-#include "xfs_inode_item.h"
-#include "xfs_dir_leaf.h"
-#include "xfs_itable.h"
-#include "xfs_btree.h"
-#include "xfs_ialloc.h"
-#include "xfs_alloc.h"
-#include "xfs_bmap.h"
-#include "xfs_attr.h"
-#include "xfs_rw.h"
-#include "xfs_error.h"
-#include "xfs_quota.h"
-#include "xfs_utils.h"
-#include "xfs_rtalloc.h"
-#include "xfs_refcache.h"
-#include "xfs_trans_space.h"
-#include "xfs_log_priv.h"
-#include "xfs_mac.h"
-
-#include "xfs_fs.h"
-
-/*
- * The maximum pathlen is 1024 bytes. Since the minimum file system
- * blocksize is 512 bytes, we can get a max of 2 extents back from
- * bmapi.
- */
-#define SYMLINK_MAPS 2
-
-/*
- * For xfs, we check that the file isn't too big to be opened by this kernel.
- * No other open action is required for regular files. Devices are handled
- * through the specfs file system, pipes through fifofs. Device and
- * fifo vnodes are "wrapped" by specfs and fifofs vnodes, respectively,
- * when a new vnode is first looked up or created.
- */
-STATIC int
-xfs_open(
- bhv_desc_t *bdp,
- cred_t *credp)
-{
- int mode;
- xfs_vnode_t *vp;
- xfs_inode_t *ip;
-
- vp = BHV_TO_VNODE(bdp);
- ip = XFS_BHVTOI(bdp);
-
- if (XFS_FORCED_SHUTDOWN(ip->i_mount))
- return XFS_ERROR(EIO);
-
- /*
- * If it's a directory with any blocks, read-ahead block 0
- * as we're almost certain to have the next operation be a read there.
- */
- if (VN_ISDIR(vp) && ip->i_d.di_nextents > 0) {
- mode = xfs_ilock_map_shared(ip);
- if (ip->i_d.di_nextents > 0)
- (void)xfs_da_reada_buf(NULL, ip, 0, XFS_DATA_FORK);
- xfs_iunlock(ip, mode);
- }
- return 0;
-}
-
-
-/*
- * xfs_getattr
- */
-STATIC int
-xfs_getattr(
- bhv_desc_t *bdp,
- xfs_vattr_t *vap,
- int flags,
- cred_t *credp)
-{
- xfs_inode_t *ip;
- xfs_mount_t *mp;
- xfs_vnode_t *vp;
-
- vp = BHV_TO_VNODE(bdp);
- vn_trace_entry(vp, __FUNCTION__, (inst_t *)__return_address);
-
- ip = XFS_BHVTOI(bdp);
- mp = ip->i_mount;
-
- if (XFS_FORCED_SHUTDOWN(mp))
- return XFS_ERROR(EIO);
-
- if (!(flags & ATTR_LAZY))
- xfs_ilock(ip, XFS_ILOCK_SHARED);
-
- vap->va_size = ip->i_d.di_size;
- if (vap->va_mask == XFS_AT_SIZE)
- goto all_done;
-
- vap->va_nblocks =
- XFS_FSB_TO_BB(mp, ip->i_d.di_nblocks + ip->i_delayed_blks);
- vap->va_nodeid = ip->i_ino;
-#if XFS_BIG_INUMS
- vap->va_nodeid += mp->m_inoadd;
-#endif
- vap->va_nlink = ip->i_d.di_nlink;
-
- /*
- * Quick exit for non-stat callers
- */
- if ((vap->va_mask &
- ~(XFS_AT_SIZE|XFS_AT_FSID|XFS_AT_NODEID|
- XFS_AT_NLINK|XFS_AT_BLKSIZE)) == 0)
- goto all_done;
-
- /*
- * Copy from in-core inode.
- */
- vap->va_mode = ip->i_d.di_mode;
- vap->va_uid = ip->i_d.di_uid;
- vap->va_gid = ip->i_d.di_gid;
- vap->va_projid = ip->i_d.di_projid;
-
- /*
- * Check vnode type block/char vs. everything else.
- */
- switch (ip->i_d.di_mode & S_IFMT) {
- case S_IFBLK:
- case S_IFCHR:
- vap->va_rdev = ip->i_df.if_u2.if_rdev;
- vap->va_blocksize = BLKDEV_IOSIZE;
- break;
- default:
- vap->va_rdev = 0;
-
- if (!(ip->i_d.di_flags & XFS_DIFLAG_REALTIME)) {
- vap->va_blocksize = xfs_preferred_iosize(mp);
- } else {
-
- /*
- * If the file blocks are being allocated from a
- * realtime partition, then return the inode's
- * realtime extent size or the realtime volume's
- * extent size.
- */
- vap->va_blocksize = ip->i_d.di_extsize ?
- (ip->i_d.di_extsize << mp->m_sb.sb_blocklog) :
- (mp->m_sb.sb_rextsize << mp->m_sb.sb_blocklog);
- }
- break;
- }
-
- vn_atime_to_timespec(vp, &vap->va_atime);
- vap->va_mtime.tv_sec = ip->i_d.di_mtime.t_sec;
- vap->va_mtime.tv_nsec = ip->i_d.di_mtime.t_nsec;
- vap->va_ctime.tv_sec = ip->i_d.di_ctime.t_sec;
- vap->va_ctime.tv_nsec = ip->i_d.di_ctime.t_nsec;
-
- /*
- * Exit for stat callers. See if any of the rest of the fields
- * to be filled in are needed.
- */
- if ((vap->va_mask &
- (XFS_AT_XFLAGS|XFS_AT_EXTSIZE|XFS_AT_NEXTENTS|XFS_AT_ANEXTENTS|
- XFS_AT_GENCOUNT|XFS_AT_VCODE)) == 0)
- goto all_done;
-
- /*
- * Convert di_flags to xflags.
- */
- vap->va_xflags = xfs_ip2xflags(ip);
-
- /*
- * Exit for inode revalidate. See if any of the rest of
- * the fields to be filled in are needed.
- */
- if ((vap->va_mask &
- (XFS_AT_EXTSIZE|XFS_AT_NEXTENTS|XFS_AT_ANEXTENTS|
- XFS_AT_GENCOUNT|XFS_AT_VCODE)) == 0)
- goto all_done;
-
- vap->va_extsize = ip->i_d.di_extsize << mp->m_sb.sb_blocklog;
- vap->va_nextents =
- (ip->i_df.if_flags & XFS_IFEXTENTS) ?
- ip->i_df.if_bytes / sizeof(xfs_bmbt_rec_t) :
- ip->i_d.di_nextents;
- if (ip->i_afp)
- vap->va_anextents =
- (ip->i_afp->if_flags & XFS_IFEXTENTS) ?
- ip->i_afp->if_bytes / sizeof(xfs_bmbt_rec_t) :
- ip->i_d.di_anextents;
- else
- vap->va_anextents = 0;
- vap->va_gen = ip->i_d.di_gen;
-
- all_done:
- if (!(flags & ATTR_LAZY))
- xfs_iunlock(ip, XFS_ILOCK_SHARED);
- return 0;
-}
-
-
-/*
- * xfs_setattr
- */
-int
-xfs_setattr(
- bhv_desc_t *bdp,
- xfs_vattr_t *vap,
- int flags,
- cred_t *credp)
-{
- xfs_inode_t *ip;
- xfs_trans_t *tp;
- xfs_mount_t *mp;
- int mask;
- int code;
- uint lock_flags;
- uint commit_flags=0;
- uid_t uid=0, iuid=0;
- gid_t gid=0, igid=0;
- int timeflags = 0;
- xfs_vnode_t *vp;
- xfs_prid_t projid=0, iprojid=0;
- int mandlock_before, mandlock_after;
- struct xfs_dquot *udqp, *gdqp, *olddquot1, *olddquot2;
- int file_owner;
- int need_iolock = 1;
-
- vp = BHV_TO_VNODE(bdp);
- vn_trace_entry(vp, __FUNCTION__, (inst_t *)__return_address);
-
- if (vp->v_vfsp->vfs_flag & VFS_RDONLY)
- return XFS_ERROR(EROFS);
-
- /*
- * Cannot set certain attributes.
- */
- mask = vap->va_mask;
- if (mask & XFS_AT_NOSET) {
- return XFS_ERROR(EINVAL);
- }
-
- ip = XFS_BHVTOI(bdp);
- mp = ip->i_mount;
-
- if (XFS_FORCED_SHUTDOWN(mp))
- return XFS_ERROR(EIO);
-
- /*
- * Timestamps do not need to be logged and hence do not
- * need to be done within a transaction.
- */
- if (mask & XFS_AT_UPDTIMES) {
- ASSERT((mask & ~XFS_AT_UPDTIMES) == 0);
- timeflags = ((mask & XFS_AT_UPDATIME) ? XFS_ICHGTIME_ACC : 0) |
- ((mask & XFS_AT_UPDCTIME) ? XFS_ICHGTIME_CHG : 0) |
- ((mask & XFS_AT_UPDMTIME) ? XFS_ICHGTIME_MOD : 0);
- xfs_ichgtime(ip, timeflags);
- return 0;
- }
-
- olddquot1 = olddquot2 = NULL;
- udqp = gdqp = NULL;
-
- /*
- * If disk quotas is on, we make sure that the dquots do exist on disk,
- * before we start any other transactions. Trying to do this later
- * is messy. We don't care to take a readlock to look at the ids
- * in inode here, because we can't hold it across the trans_reserve.
- * If the IDs do change before we take the ilock, we're covered
- * because the i_*dquot fields will get updated anyway.
- */
- if (XFS_IS_QUOTA_ON(mp) &&
- (mask & (XFS_AT_UID|XFS_AT_GID|XFS_AT_PROJID))) {
- uint qflags = 0;
-
- if ((mask & XFS_AT_UID) && XFS_IS_UQUOTA_ON(mp)) {
- uid = vap->va_uid;
- qflags |= XFS_QMOPT_UQUOTA;
- } else {
- uid = ip->i_d.di_uid;
- }
- if ((mask & XFS_AT_GID) && XFS_IS_GQUOTA_ON(mp)) {
- gid = vap->va_gid;
- qflags |= XFS_QMOPT_GQUOTA;
- } else {
- gid = ip->i_d.di_gid;
- }
- if ((mask & XFS_AT_PROJID) && XFS_IS_PQUOTA_ON(mp)) {
- projid = vap->va_projid;
- qflags |= XFS_QMOPT_PQUOTA;
- } else {
- projid = ip->i_d.di_projid;
- }
- /*
- * We take a reference when we initialize udqp and gdqp,
- * so it is important that we never blindly double trip on
- * the same variable. See xfs_create() for an example.
- */
- ASSERT(udqp == NULL);
- ASSERT(gdqp == NULL);
- code = XFS_QM_DQVOPALLOC(mp, ip, uid, gid, projid, qflags,
- &udqp, &gdqp);
- if (code)
- return code;
- }
-
- /*
- * For the other attributes, we acquire the inode lock and
- * first do an error checking pass.
- */
- tp = NULL;
- lock_flags = XFS_ILOCK_EXCL;
- ASSERT(flags & ATTR_NOLOCK ? flags & ATTR_DMI : 1);
- if (flags & ATTR_NOLOCK)
- need_iolock = 0;
- if (!(mask & XFS_AT_SIZE)) {
- if ((mask != (XFS_AT_CTIME|XFS_AT_ATIME|XFS_AT_MTIME)) ||
- (mp->m_flags & XFS_MOUNT_WSYNC)) {
- tp = xfs_trans_alloc(mp, XFS_TRANS_SETATTR_NOT_SIZE);
- commit_flags = 0;
- if ((code = xfs_trans_reserve(tp, 0,
- XFS_ICHANGE_LOG_RES(mp), 0,
- 0, 0))) {
- lock_flags = 0;
- goto error_return;
- }
- }
- } else {
- if (DM_EVENT_ENABLED (vp->v_vfsp, ip, DM_EVENT_TRUNCATE) &&
- !(flags & ATTR_DMI)) {
- int dmflags = AT_DELAY_FLAG(flags) | DM_SEM_FLAG_WR;
- code = XFS_SEND_DATA(mp, DM_EVENT_TRUNCATE, vp,
- vap->va_size, 0, dmflags, NULL);
- if (code) {
- lock_flags = 0;
- goto error_return;
- }
- }
- if (need_iolock)
- lock_flags |= XFS_IOLOCK_EXCL;
- }
-
- xfs_ilock(ip, lock_flags);
-
- /* boolean: are we the file owner? */
-#if 0
- file_owner = (current_fsuid(credp) == ip->i_d.di_uid);
-#else
- file_owner = (credp->cr_uid == ip->i_d.di_uid);
-#endif
-
- /*
- * Change various properties of a file.
- * Only the owner or users with CAP_FOWNER
- * capability may do these things.
- */
- if (mask &
- (XFS_AT_MODE|XFS_AT_XFLAGS|XFS_AT_EXTSIZE|XFS_AT_UID|
- XFS_AT_GID|XFS_AT_PROJID)) {
- /*
- * CAP_FOWNER overrides the following restrictions:
- *
- * The user ID of the calling process must be equal
- * to the file owner ID, except in cases where the
- * CAP_FSETID capability is applicable.
- */
- if (!file_owner && !capable(CAP_FOWNER)) {
- code = XFS_ERROR(EPERM);
- goto error_return;
- }
-
- /*
- * CAP_FSETID overrides the following restrictions:
- *
- * The effective user ID of the calling process shall match
- * the file owner when setting the set-user-ID and
- * set-group-ID bits on that file.
- *
- * The effective group ID or one of the supplementary group
- * IDs of the calling process shall match the group owner of
- * the file when setting the set-group-ID bit on that file
- */
- if (mask & XFS_AT_MODE) {
- mode_t m = 0;
-
- if ((vap->va_mode & S_ISUID) && !file_owner)
- m |= S_ISUID;
- if ((vap->va_mode & S_ISGID) &&
- !groupmember((gid_t)ip->i_d.di_gid, credp))
- m |= S_ISGID;
-#if 1
- /* Linux allows this, Irix doesn't. */
- if ((vap->va_mode & S_ISVTX) && !VN_ISDIR(vp))
- m |= S_ISVTX;
-#endif
- if (m && !capable(CAP_FSETID))
- vap->va_mode &= ~m;
- }
- }
-
- /*
- * Change file ownership. Must be the owner or privileged.
- * If the system was configured with the "restricted_chown"
- * option, the owner is not permitted to give away the file,
- * and can change the group id only to a group of which he
- * or she is a member.
- */
- if (mask & (XFS_AT_UID|XFS_AT_GID|XFS_AT_PROJID)) {
- /*
- * These IDs could have changed since we last looked at them.
- * But, we're assured that if the ownership did change
- * while we didn't have the inode locked, inode's dquot(s)
- * would have changed also.
- */
- iuid = ip->i_d.di_uid;
- iprojid = ip->i_d.di_projid;
- igid = ip->i_d.di_gid;
- gid = (mask & XFS_AT_GID) ? vap->va_gid : igid;
- uid = (mask & XFS_AT_UID) ? vap->va_uid : iuid;
-
- projid = (mask & XFS_AT_PROJID) ? (xfs_prid_t)vap->va_projid :
- iprojid;
-
- /*
- * CAP_CHOWN overrides the following restrictions:
- *
- * If _POSIX_CHOWN_RESTRICTED is defined, this capability
- * shall override the restriction that a process cannot
- * change the user ID of a file it owns and the restriction
- * that the group ID supplied to the chown() function
- * shall be equal to either the group ID or one of the
- * supplementary group IDs of the calling process.
- */
- if (restricted_chown &&
- (iuid != uid || (igid != gid &&
- !groupmember((gid_t)gid, credp))) &&
- !capable(CAP_CHOWN)) {
- code = XFS_ERROR(EPERM);
- goto error_return;
- }
- /*
- * Do a quota reservation only if uid/projid/gid is actually
- * going to change.
- */
- if ((XFS_IS_UQUOTA_ON(mp) && iuid != uid) ||
- (XFS_IS_PQUOTA_ON(mp) && iprojid != projid) ||
- (XFS_IS_GQUOTA_ON(mp) && igid != gid)) {
- ASSERT(tp);
- code = XFS_QM_DQVOPCHOWNRESV(mp, tp, ip, udqp, gdqp,
- capable(CAP_FOWNER) ?
- XFS_QMOPT_FORCE_RES : 0);
- if (code) /* out of quota */
- goto error_return;
- }
- }
-
- /*
- * Truncate file. Must have write permission and not be a directory.
- */
- if (mask & XFS_AT_SIZE) {
- /* Short circuit the truncate case for zero length files */
- if ((vap->va_size == 0) &&
- (ip->i_d.di_size == 0) && (ip->i_d.di_nextents == 0)) {
- xfs_iunlock(ip, XFS_ILOCK_EXCL);
- lock_flags &= ~XFS_ILOCK_EXCL;
- if (mask & XFS_AT_CTIME)
- xfs_ichgtime(ip, XFS_ICHGTIME_MOD | XFS_ICHGTIME_CHG);
- code = 0;
- goto error_return;
- }
-
- if (VN_ISDIR(vp)) {
- code = XFS_ERROR(EISDIR);
- goto error_return;
- } else if (!VN_ISREG(vp)) {
- code = XFS_ERROR(EINVAL);
- goto error_return;
- }
- /*
- * Make sure that the dquots are attached to the inode.
- */
- if ((code = XFS_QM_DQATTACH(mp, ip, XFS_QMOPT_ILOCKED)))
- goto error_return;
- }
-
- /*
- * Change file access or modified times.
- */
- if (mask & (XFS_AT_ATIME|XFS_AT_MTIME)) {
- if (!file_owner) {
- if ((flags & ATTR_UTIME) &&
- !capable(CAP_FOWNER)) {
- code = XFS_ERROR(EPERM);
- goto error_return;
- }
- }
- }
-
- /*
- * Change extent size or realtime flag.
- */
- if (mask & (XFS_AT_EXTSIZE|XFS_AT_XFLAGS)) {
- /*
- * Can't change extent size if any extents are allocated.
- */
- if (ip->i_d.di_nextents && (mask & XFS_AT_EXTSIZE) &&
- ((ip->i_d.di_extsize << mp->m_sb.sb_blocklog) !=
- vap->va_extsize) ) {
- code = XFS_ERROR(EINVAL); /* EFBIG? */
- goto error_return;
- }
- /*
- * Can't change realtime flag if any extents are allocated.
- */
- if ((ip->i_d.di_nextents || ip->i_delayed_blks) &&
- (mask & XFS_AT_XFLAGS) &&
- (ip->i_d.di_flags & XFS_DIFLAG_REALTIME) !=
- (vap->va_xflags & XFS_XFLAG_REALTIME)) {
- code = XFS_ERROR(EINVAL); /* EFBIG? */
- goto error_return;
- }
-
- /*
- * Extent size must be a multiple of the appropriate block
- * size, if set at all.
- */
- if ((mask & XFS_AT_EXTSIZE) && vap->va_extsize != 0) {
- xfs_extlen_t size;
-
- if ((ip->i_d.di_flags & XFS_DIFLAG_REALTIME) ||
- ((mask & XFS_AT_XFLAGS) &&
- (vap->va_xflags & XFS_XFLAG_REALTIME))) {
- size = mp->m_sb.sb_rextsize <<
- mp->m_sb.sb_blocklog;
- } else {
- size = mp->m_sb.sb_blocksize;
- }
- if (vap->va_extsize % size) {
- code = XFS_ERROR(EINVAL);
- goto error_return;
- }
- }
- /*
- * If realtime flag is set then must have realtime data.
- */
- if ((mask & XFS_AT_XFLAGS) &&
- (vap->va_xflags & XFS_XFLAG_REALTIME)) {
- if ((mp->m_sb.sb_rblocks == 0) ||
- (mp->m_sb.sb_rextsize == 0) ||
- (ip->i_d.di_extsize % mp->m_sb.sb_rextsize)) {
- code = XFS_ERROR(EINVAL);
- goto error_return;
- }
- }
-
- /*
- * Can't modify an immutable/append-only file unless
- * we have appropriate permission.
- */
- if ((mask & XFS_AT_XFLAGS) &&
- (ip->i_d.di_flags &
- (XFS_DIFLAG_IMMUTABLE|XFS_DIFLAG_APPEND) ||
- (vap->va_xflags &
- (XFS_XFLAG_IMMUTABLE | XFS_XFLAG_APPEND))) &&
- !capable(CAP_LINUX_IMMUTABLE)) {
- code = XFS_ERROR(EPERM);
- goto error_return;
- }
- }
-
- /*
- * Now we can make the changes. Before we join the inode
- * to the transaction, if XFS_AT_SIZE is set then take care of
- * the part of the truncation that must be done without the
- * inode lock. This needs to be done before joining the inode
- * to the transaction, because the inode cannot be unlocked
- * once it is a part of the transaction.
- */
- if (mask & XFS_AT_SIZE) {
- code = 0;
- if ((vap->va_size > ip->i_d.di_size) &&
- (flags & ATTR_NOSIZETOK) == 0) {
- code = xfs_igrow_start(ip, vap->va_size, credp);
- }
- xfs_iunlock(ip, XFS_ILOCK_EXCL);
- vn_iowait(vp); /* wait for the completion of any pending DIOs */
- if (!code)
- code = xfs_itruncate_data(ip, vap->va_size);
- if (code) {
- ASSERT(tp == NULL);
- lock_flags &= ~XFS_ILOCK_EXCL;
- ASSERT(lock_flags == XFS_IOLOCK_EXCL);
- goto error_return;
- }
- tp = xfs_trans_alloc(mp, XFS_TRANS_SETATTR_SIZE);
- if ((code = xfs_trans_reserve(tp, 0,
- XFS_ITRUNCATE_LOG_RES(mp), 0,
- XFS_TRANS_PERM_LOG_RES,
- XFS_ITRUNCATE_LOG_COUNT))) {
- xfs_trans_cancel(tp, 0);
- if (need_iolock)
- xfs_iunlock(ip, XFS_IOLOCK_EXCL);
- return code;
- }
- commit_flags = XFS_TRANS_RELEASE_LOG_RES;
- xfs_ilock(ip, XFS_ILOCK_EXCL);
- }
-
- if (tp) {
- xfs_trans_ijoin(tp, ip, lock_flags);
- xfs_trans_ihold(tp, ip);
- }
-
- /* determine whether mandatory locking mode changes */
- mandlock_before = MANDLOCK(vp, ip->i_d.di_mode);
-
- /*
- * Truncate file. Must have write permission and not be a directory.
- */
- if (mask & XFS_AT_SIZE) {
- if (vap->va_size > ip->i_d.di_size) {
- xfs_igrow_finish(tp, ip, vap->va_size,
- !(flags & ATTR_DMI));
- } else if ((vap->va_size <= ip->i_d.di_size) ||
- ((vap->va_size == 0) && ip->i_d.di_nextents)) {
- /*
- * signal a sync transaction unless
- * we're truncating an already unlinked
- * file on a wsync filesystem
- */
- code = xfs_itruncate_finish(&tp, ip,
- (xfs_fsize_t)vap->va_size,
- XFS_DATA_FORK,
- ((ip->i_d.di_nlink != 0 ||
- !(mp->m_flags & XFS_MOUNT_WSYNC))
- ? 1 : 0));
- if (code) {
- goto abort_return;
- }
- }
- /*
- * Have to do this even if the file's size doesn't change.
- */
- timeflags |= XFS_ICHGTIME_MOD | XFS_ICHGTIME_CHG;
- }
-
- /*
- * Change file access modes.
- */
- if (mask & XFS_AT_MODE) {
- ip->i_d.di_mode &= S_IFMT;
- ip->i_d.di_mode |= vap->va_mode & ~S_IFMT;
-
- xfs_trans_log_inode (tp, ip, XFS_ILOG_CORE);
- timeflags |= XFS_ICHGTIME_CHG;
- }
-
- /*
- * Change file ownership. Must be the owner or privileged.
- * If the system was configured with the "restricted_chown"
- * option, the owner is not permitted to give away the file,
- * and can change the group id only to a group of which he
- * or she is a member.
- */
- if (mask & (XFS_AT_UID|XFS_AT_GID|XFS_AT_PROJID)) {
- /*
- * CAP_FSETID overrides the following restrictions:
- *
- * The set-user-ID and set-group-ID bits of a file will be
- * cleared upon successful return from chown()
- */
- if ((ip->i_d.di_mode & (S_ISUID|S_ISGID)) &&
- !capable(CAP_FSETID)) {
- ip->i_d.di_mode &= ~(S_ISUID|S_ISGID);
- }
-
- /*
- * Change the ownerships and register quota modifications
- * in the transaction.
- */
- if (iuid != uid) {
- if (XFS_IS_UQUOTA_ON(mp)) {
- ASSERT(mask & XFS_AT_UID);
- ASSERT(udqp);
- olddquot1 = XFS_QM_DQVOPCHOWN(mp, tp, ip,
- &ip->i_udquot, udqp);
- }
- ip->i_d.di_uid = uid;
- }
- if (igid != gid) {
- if (XFS_IS_GQUOTA_ON(mp)) {
- ASSERT(!XFS_IS_PQUOTA_ON(mp));
- ASSERT(mask & XFS_AT_GID);
- ASSERT(gdqp);
- olddquot2 = XFS_QM_DQVOPCHOWN(mp, tp, ip,
- &ip->i_gdquot, gdqp);
- }
- ip->i_d.di_gid = gid;
- }
- if (iprojid != projid) {
- if (XFS_IS_PQUOTA_ON(mp)) {
- ASSERT(!XFS_IS_GQUOTA_ON(mp));
- ASSERT(mask & XFS_AT_PROJID);
- ASSERT(gdqp);
- olddquot2 = XFS_QM_DQVOPCHOWN(mp, tp, ip,
- &ip->i_gdquot, gdqp);
- }
- ip->i_d.di_projid = projid;
- /*
- * We may have to rev the inode as well as
- * the superblock version number since projids didn't
- * exist before DINODE_VERSION_2 and SB_VERSION_NLINK.
- */
- if (ip->i_d.di_version == XFS_DINODE_VERSION_1)
- xfs_bump_ino_vers2(tp, ip);
- }
-
- xfs_trans_log_inode (tp, ip, XFS_ILOG_CORE);
- timeflags |= XFS_ICHGTIME_CHG;
- }
-
-
- /*
- * Change file access or modified times.
- */
- if (mask & (XFS_AT_ATIME|XFS_AT_MTIME)) {
- if (mask & XFS_AT_ATIME) {
- ip->i_d.di_atime.t_sec = vap->va_atime.tv_sec;
- ip->i_d.di_atime.t_nsec = vap->va_atime.tv_nsec;
- ip->i_update_core = 1;
- //timeflags &= ~XFS_ICHGTIME_ACC;
- }
- if (mask & XFS_AT_MTIME) {
- ip->i_d.di_mtime.t_sec = vap->va_mtime.tv_sec;
- ip->i_d.di_mtime.t_nsec = vap->va_mtime.tv_nsec;
- timeflags &= ~XFS_ICHGTIME_MOD;
- timeflags |= XFS_ICHGTIME_CHG;
- }
- if (tp && (flags & ATTR_UTIME))
- xfs_trans_log_inode (tp, ip, XFS_ILOG_CORE);
- }
-
- /*
- * Change XFS-added attributes.
- */
- if (mask & (XFS_AT_EXTSIZE|XFS_AT_XFLAGS)) {
- if (mask & XFS_AT_EXTSIZE) {
- /*
- * Converting bytes to fs blocks.
- */
- ip->i_d.di_extsize = vap->va_extsize >>
- mp->m_sb.sb_blocklog;
- }
- if (mask & XFS_AT_XFLAGS) {
- uint di_flags;
-
- /* can't set PREALLOC this way, just preserve it */
- di_flags = (ip->i_d.di_flags & XFS_DIFLAG_PREALLOC);
- if (vap->va_xflags & XFS_XFLAG_IMMUTABLE)
- di_flags |= XFS_DIFLAG_IMMUTABLE;
- if (vap->va_xflags & XFS_XFLAG_APPEND)
- di_flags |= XFS_DIFLAG_APPEND;
- if (vap->va_xflags & XFS_XFLAG_SYNC)
- di_flags |= XFS_DIFLAG_SYNC;
- if (vap->va_xflags & XFS_XFLAG_NOATIME)
- di_flags |= XFS_DIFLAG_NOATIME;
- if (vap->va_xflags & XFS_XFLAG_NODUMP)
- di_flags |= XFS_DIFLAG_NODUMP;
- if (vap->va_xflags & XFS_XFLAG_PROJINHERIT)
- di_flags |= XFS_DIFLAG_PROJINHERIT;
- if ((ip->i_d.di_mode & S_IFMT) == S_IFDIR) {
- if (vap->va_xflags & XFS_XFLAG_RTINHERIT)
- di_flags |= XFS_DIFLAG_RTINHERIT;
- if (vap->va_xflags & XFS_XFLAG_NOSYMLINKS)
- di_flags |= XFS_DIFLAG_NOSYMLINKS;
- if (vap->va_xflags & XFS_XFLAG_EXTSZINHERIT)
- di_flags |= XFS_DIFLAG_EXTSZINHERIT;
- } else if ((ip->i_d.di_mode & S_IFMT) == S_IFREG) {
- if (vap->va_xflags & XFS_XFLAG_REALTIME) {
- di_flags |= XFS_DIFLAG_REALTIME;
- ip->i_iocore.io_flags |= XFS_IOCORE_RT;
- } else {
- ip->i_iocore.io_flags &= ~XFS_IOCORE_RT;
- }
- if (vap->va_xflags & XFS_XFLAG_EXTSIZE)
- di_flags |= XFS_DIFLAG_EXTSIZE;
- }
- ip->i_d.di_flags = di_flags;
- }
- xfs_trans_log_inode(tp, ip, XFS_ILOG_CORE);
- timeflags |= XFS_ICHGTIME_CHG;
- }
-
- /*
- * Change file inode change time only if XFS_AT_CTIME set
- * AND we have been called by a DMI function.
- */
-
- if ( (flags & ATTR_DMI) && (mask & XFS_AT_CTIME) ) {
- ip->i_d.di_ctime.t_sec = vap->va_ctime.tv_sec;
- ip->i_d.di_ctime.t_nsec = vap->va_ctime.tv_nsec;
- ip->i_update_core = 1;
- timeflags &= ~XFS_ICHGTIME_CHG;
- }
-
- /*
- * Send out timestamp changes that need to be set to the
- * current time. Not done when called by a DMI function.
- */
- if (timeflags && !(flags & ATTR_DMI))
- xfs_ichgtime(ip, timeflags);
-
- XFS_STATS_INC(xs_ig_attrchg);
-
- /*
- * If this is a synchronous mount, make sure that the
- * transaction goes to disk before returning to the user.
- * This is slightly sub-optimal in that truncates require
- * two sync transactions instead of one for wsync filesystems.
- * One for the truncate and one for the timestamps since we
- * don't want to change the timestamps unless we're sure the
- * truncate worked. Truncates are less than 1% of the laddis
- * mix so this probably isn't worth the trouble to optimize.
- */
- code = 0;
- if (tp) {
- if (mp->m_flags & XFS_MOUNT_WSYNC)
- xfs_trans_set_sync(tp);
-
- code = xfs_trans_commit(tp, commit_flags, NULL);
- }
-
- /*
- * If the (regular) file's mandatory locking mode changed, then
- * notify the vnode. We do this under the inode lock to prevent
- * racing calls to vop_vnode_change.
- */
- mandlock_after = MANDLOCK(vp, ip->i_d.di_mode);
- if (mandlock_before != mandlock_after) {
- XVOP_VNODE_CHANGE(vp, VCHANGE_FLAGS_ENF_LOCKING,
- mandlock_after);
- }
-
- xfs_iunlock(ip, lock_flags);
-
- /*
- * Release any dquot(s) the inode had kept before chown.
- */
- XFS_QM_DQRELE(mp, olddquot1);
- XFS_QM_DQRELE(mp, olddquot2);
- XFS_QM_DQRELE(mp, udqp);
- XFS_QM_DQRELE(mp, gdqp);
-
- if (code) {
- return code;
- }
-
- if (DM_EVENT_ENABLED(vp->v_vfsp, ip, DM_EVENT_ATTRIBUTE) &&
- !(flags & ATTR_DMI)) {
- (void) XFS_SEND_NAMESP(mp, DM_EVENT_ATTRIBUTE, vp, DM_RIGHT_NULL,
- NULL, DM_RIGHT_NULL, NULL, NULL,
- 0, 0, AT_DELAY_FLAG(flags));
- }
- return 0;
-
- abort_return:
- commit_flags |= XFS_TRANS_ABORT;
- /* FALLTHROUGH */
- error_return:
- XFS_QM_DQRELE(mp, udqp);
- XFS_QM_DQRELE(mp, gdqp);
- if (tp) {
- xfs_trans_cancel(tp, commit_flags);
- }
- if (lock_flags != 0) {
- xfs_iunlock(ip, lock_flags);
- }
- return code;
-}
-
-
-/*
- * xfs_access
- * Null conversion from vnode mode bits to inode mode bits, as in efs.
- */
-STATIC int
-xfs_access(
- bhv_desc_t *bdp,
- accmode_t accmode,
- cred_t *credp)
-{
- xfs_inode_t *ip;
- int error;
-
- vn_trace_entry(BHV_TO_VNODE(bdp), __FUNCTION__,
- (inst_t *)__return_address);
-
- ip = XFS_BHVTOI(bdp);
- xfs_ilock(ip, XFS_ILOCK_SHARED);
- error = xfs_iaccess(ip, accmode, credp);
- xfs_iunlock(ip, XFS_ILOCK_SHARED);
- return error;
-}
-
-
-/*
- * xfs_readlink
- *
- */
-STATIC int
-xfs_readlink(
- bhv_desc_t *bdp,
- uio_t *uiop,
- int ioflags,
- cred_t *credp)
-{
- xfs_inode_t *ip;
- int count;
- xfs_off_t offset;
- int pathlen;
- xfs_vnode_t *vp;
- int error = 0;
- xfs_mount_t *mp;
- int nmaps;
- xfs_bmbt_irec_t mval[SYMLINK_MAPS];
- xfs_daddr_t d;
- int byte_cnt;
- int n;
- xfs_buf_t *bp;
-
- vp = BHV_TO_VNODE(bdp);
- vn_trace_entry(vp, __FUNCTION__, (inst_t *)__return_address);
-
- ip = XFS_BHVTOI(bdp);
- mp = ip->i_mount;
-
- if (XFS_FORCED_SHUTDOWN(mp))
- return XFS_ERROR(EIO);
-
- xfs_ilock(ip, XFS_ILOCK_SHARED);
-
- ASSERT((ip->i_d.di_mode & S_IFMT) == S_IFLNK);
-
- offset = uiop->uio_offset;
- count = uiop->uio_resid;
-
- if (offset < 0) {
- error = XFS_ERROR(EINVAL);
- goto error_return;
- }
- if (count <= 0) {
- error = 0;
- goto error_return;
- }
-
- /*
- * See if the symlink is stored inline.
- */
- pathlen = (int)ip->i_d.di_size;
-
- if (ip->i_df.if_flags & XFS_IFINLINE) {
- error = uio_read(ip->i_df.if_u1.if_data, pathlen, uiop);
- }
- else {
- /*
- * Symlink not inline. Call bmap to get it in.
- */
- nmaps = SYMLINK_MAPS;
-
- error = xfs_bmapi(NULL, ip, 0, XFS_B_TO_FSB(mp, pathlen),
- 0, NULL, 0, mval, &nmaps, NULL, NULL);
-
- if (error) {
- goto error_return;
- }
-
- for (n = 0; n < nmaps; n++) {
- d = XFS_FSB_TO_DADDR(mp, mval[n].br_startblock);
- byte_cnt = XFS_FSB_TO_B(mp, mval[n].br_blockcount);
- bp = xfs_buf_read(mp->m_ddev_targp, d,
- BTOBB(byte_cnt), 0);
- error = XFS_BUF_GETERROR(bp);
- if (error) {
- xfs_ioerror_alert("xfs_readlink",
- ip->i_mount, bp, XFS_BUF_ADDR(bp));
- xfs_buf_relse(bp);
- goto error_return;
- }
- if (pathlen < byte_cnt)
- byte_cnt = pathlen;
- pathlen -= byte_cnt;
-
- error = uio_read(XFS_BUF_PTR(bp), byte_cnt, uiop);
- xfs_buf_relse (bp);
- }
-
- }
-
-error_return:
- xfs_iunlock(ip, XFS_ILOCK_SHARED);
- return error;
-}
-
-
-/*
- * xfs_fsync
- *
- * This is called to sync the inode and its data out to disk.
- * We need to hold the I/O lock while flushing the data, and
- * the inode lock while flushing the inode. The inode lock CANNOT
- * be held while flushing the data, so acquire after we're done
- * with that.
- */
-STATIC int
-xfs_fsync(
- bhv_desc_t *bdp,
- int flag,
- cred_t *credp,
- xfs_off_t start,
- xfs_off_t stop)
-{
- xfs_inode_t *ip;
- xfs_trans_t *tp;
- int error;
- int log_flushed = 0, changed = 1;
-
- vn_trace_entry(BHV_TO_VNODE(bdp),
- __FUNCTION__, (inst_t *)__return_address);
-
- ip = XFS_BHVTOI(bdp);
-
- ASSERT(start >= 0 && stop >= -1);
-
- if (XFS_FORCED_SHUTDOWN(ip->i_mount))
- return XFS_ERROR(EIO);
-
- /*
- * We always need to make sure that the required inode state
- * is safe on disk. The vnode might be clean but because
- * of committed transactions that haven't hit the disk yet.
- * Likewise, there could be unflushed non-transactional
- * changes to the inode core that have to go to disk.
- *
- * The following code depends on one assumption: that
- * any transaction that changes an inode logs the core
- * because it has to change some field in the inode core
- * (typically nextents or nblocks). That assumption
- * implies that any transactions against an inode will
- * catch any non-transactional updates. If inode-altering
- * transactions exist that violate this assumption, the
- * code breaks. Right now, it figures that if the involved
- * update_* field is clear and the inode is unpinned, the
- * inode is clean. Either it's been flushed or it's been
- * committed and the commit has hit the disk unpinning the inode.
- * (Note that xfs_inode_item_format() called at commit clears
- * the update_* fields.)
- */
- xfs_ilock(ip, XFS_ILOCK_SHARED);
-
- /* If we are flushing data then we care about update_size
- * being set, otherwise we care about update_core
- */
- if ((flag & FSYNC_DATA) ?
- (ip->i_update_size == 0) :
- (ip->i_update_core == 0)) {
- /*
- * Timestamps/size haven't changed since last inode
- * flush or inode transaction commit. That means
- * either nothing got written or a transaction
- * committed which caught the updates. If the
- * latter happened and the transaction hasn't
- * hit the disk yet, the inode will be still
- * be pinned. If it is, force the log.
- */
-
- xfs_iunlock(ip, XFS_ILOCK_SHARED);
-
- if (xfs_ipincount(ip)) {
- _xfs_log_force(ip->i_mount, (xfs_lsn_t)0,
- XFS_LOG_FORCE |
- ((flag & FSYNC_WAIT)
- ? XFS_LOG_SYNC : 0),
- &log_flushed);
- } else {
- /*
- * If the inode is not pinned and nothing
- * has changed we don't need to flush the
- * cache.
- */
- changed = 0;
- }
- error = 0;
- } else {
- /*
- * Kick off a transaction to log the inode
- * core to get the updates. Make it
- * sync if FSYNC_WAIT is passed in (which
- * is done by everybody but specfs). The
- * sync transaction will also force the log.
- */
- xfs_iunlock(ip, XFS_ILOCK_SHARED);
- tp = xfs_trans_alloc(ip->i_mount, XFS_TRANS_FSYNC_TS);
- if ((error = xfs_trans_reserve(tp, 0,
- XFS_FSYNC_TS_LOG_RES(ip->i_mount),
- 0, 0, 0))) {
- xfs_trans_cancel(tp, 0);
- return error;
- }
- xfs_ilock(ip, XFS_ILOCK_EXCL);
-
- /*
- * Note - it's possible that we might have pushed
- * ourselves out of the way during trans_reserve
- * which would flush the inode. But there's no
- * guarantee that the inode buffer has actually
- * gone out yet (it's delwri). Plus the buffer
- * could be pinned anyway if it's part of an
- * inode in another recent transaction. So we
- * play it safe and fire off the transaction anyway.
- */
- xfs_trans_ijoin(tp, ip, XFS_ILOCK_EXCL);
- xfs_trans_ihold(tp, ip);
- xfs_trans_log_inode(tp, ip, XFS_ILOG_CORE);
- if (flag & FSYNC_WAIT)
- xfs_trans_set_sync(tp);
- error = _xfs_trans_commit(tp, 0, NULL, &log_flushed);
-
- xfs_iunlock(ip, XFS_ILOCK_EXCL);
- }
-
- if ((ip->i_mount->m_flags & XFS_MOUNT_BARRIER) && changed) {
- /*
- * If the log write didn't issue an ordered tag we need
- * to flush the disk cache for the data device now.
- */
- if (!log_flushed)
- xfs_blkdev_issue_flush(ip->i_mount->m_ddev_targp);
-
- /*
- * If this inode is on the RT dev we need to flush that
- * cache as well.
- */
- if (ip->i_d.di_flags & XFS_DIFLAG_REALTIME)
- xfs_blkdev_issue_flush(ip->i_mount->m_rtdev_targp);
- }
-
- return error;
-}
-
-/*
- * This is called by xfs_inactive to free any blocks beyond eof,
- * when the link count isn't zero.
- */
-STATIC int
-xfs_inactive_free_eofblocks(
- xfs_mount_t *mp,
- xfs_inode_t *ip)
-{
- xfs_trans_t *tp;
- int error;
- xfs_fileoff_t end_fsb;
- xfs_fileoff_t last_fsb;
- xfs_filblks_t map_len;
- int nimaps;
- xfs_bmbt_irec_t imap;
-
- /*
- * Figure out if there are any blocks beyond the end
- * of the file. If not, then there is nothing to do.
- */
- end_fsb = XFS_B_TO_FSB(mp, ((xfs_ufsize_t)ip->i_d.di_size));
- last_fsb = XFS_B_TO_FSB(mp, (xfs_ufsize_t)XFS_MAXIOFFSET(mp));
- map_len = last_fsb - end_fsb;
- if (map_len <= 0)
- return 0;
-
- nimaps = 1;
- xfs_ilock(ip, XFS_ILOCK_SHARED);
- error = XFS_BMAPI(mp, NULL, &ip->i_iocore, end_fsb, map_len, 0,
- NULL, 0, &imap, &nimaps, NULL, NULL);
- xfs_iunlock(ip, XFS_ILOCK_SHARED);
-
- if (!error && (nimaps != 0) &&
- (imap.br_startblock != HOLESTARTBLOCK ||
- ip->i_delayed_blks)) {
- /*
- * Attach the dquots to the inode up front.
- */
- if ((error = XFS_QM_DQATTACH(mp, ip, 0)))
- return error;
-
- /*
- * There are blocks after the end of file.
- * Free them up now by truncating the file to
- * its current size.
- */
- tp = xfs_trans_alloc(mp, XFS_TRANS_INACTIVE);
-
- /*
- * Do the xfs_itruncate_start() call before
- * reserving any log space because
- * itruncate_start will call into the buffer
- * cache and we can't
- * do that within a transaction.
- */
- xfs_ilock(ip, XFS_IOLOCK_EXCL);
- xfs_itruncate_start(ip, XFS_ITRUNC_DEFINITE,
- ip->i_d.di_size);
-
- error = xfs_trans_reserve(tp, 0,
- XFS_ITRUNCATE_LOG_RES(mp),
- 0, XFS_TRANS_PERM_LOG_RES,
- XFS_ITRUNCATE_LOG_COUNT);
- if (error) {
- ASSERT(XFS_FORCED_SHUTDOWN(mp));
- xfs_trans_cancel(tp, 0);
- xfs_iunlock(ip, XFS_IOLOCK_EXCL);
- return error;
- }
-
- xfs_ilock(ip, XFS_ILOCK_EXCL);
- xfs_trans_ijoin(tp, ip,
- XFS_IOLOCK_EXCL |
- XFS_ILOCK_EXCL);
- xfs_trans_ihold(tp, ip);
-
- error = xfs_itruncate_finish(&tp, ip,
- ip->i_d.di_size,
- XFS_DATA_FORK,
- 0);
- /*
- * If we get an error at this point we
- * simply don't bother truncating the file.
- */
- if (error) {
- xfs_trans_cancel(tp,
- (XFS_TRANS_RELEASE_LOG_RES |
- XFS_TRANS_ABORT));
- } else {
- error = xfs_trans_commit(tp,
- XFS_TRANS_RELEASE_LOG_RES,
- NULL);
- }
- xfs_iunlock(ip, XFS_IOLOCK_EXCL | XFS_ILOCK_EXCL);
- }
- return error;
-}
-
-/*
- * Free a symlink that has blocks associated with it.
- */
-STATIC int
-xfs_inactive_symlink_rmt(
- xfs_inode_t *ip,
- xfs_trans_t **tpp)
-{
- xfs_buf_t *bp;
- int committed;
- int done;
- int error;
- xfs_fsblock_t first_block;
- xfs_bmap_free_t free_list;
- int i;
- xfs_mount_t *mp;
- xfs_bmbt_irec_t mval[SYMLINK_MAPS];
- int nmaps;
- xfs_trans_t *ntp;
- int size;
- xfs_trans_t *tp;
-
- tp = *tpp;
- mp = ip->i_mount;
- ASSERT(ip->i_d.di_size > XFS_IFORK_DSIZE(ip));
- /*
- * We're freeing a symlink that has some
- * blocks allocated to it. Free the
- * blocks here. We know that we've got
- * either 1 or 2 extents and that we can
- * free them all in one bunmapi call.
- */
- ASSERT(ip->i_d.di_nextents > 0 && ip->i_d.di_nextents <= 2);
- if ((error = xfs_trans_reserve(tp, 0, XFS_ITRUNCATE_LOG_RES(mp), 0,
- XFS_TRANS_PERM_LOG_RES, XFS_ITRUNCATE_LOG_COUNT))) {
- ASSERT(XFS_FORCED_SHUTDOWN(mp));
- xfs_trans_cancel(tp, 0);
- *tpp = NULL;
- return error;
- }
- /*
- * Lock the inode, fix the size, and join it to the transaction.
- * Hold it so in the normal path, we still have it locked for
- * the second transaction. In the error paths we need it
- * held so the cancel won't rele it, see below.
- */
- xfs_ilock(ip, XFS_IOLOCK_EXCL | XFS_ILOCK_EXCL);
- size = (int)ip->i_d.di_size;
- ip->i_d.di_size = 0;
- xfs_trans_ijoin(tp, ip, XFS_ILOCK_EXCL | XFS_IOLOCK_EXCL);
- xfs_trans_ihold(tp, ip);
- xfs_trans_log_inode(tp, ip, XFS_ILOG_CORE);
- /*
- * Find the block(s) so we can inval and unmap them.
- */
- done = 0;
- XFS_BMAP_INIT(&free_list, &first_block);
- nmaps = sizeof(mval) / sizeof(mval[0]);
- if ((error = xfs_bmapi(tp, ip, 0, XFS_B_TO_FSB(mp, size),
- XFS_BMAPI_METADATA, &first_block, 0, mval, &nmaps,
- &free_list, NULL)))
- goto error0;
- /*
- * Invalidate the block(s).
- */
- for (i = 0; i < nmaps; i++) {
- bp = xfs_trans_get_buf(tp, mp->m_ddev_targp,
- XFS_FSB_TO_DADDR(mp, mval[i].br_startblock),
- XFS_FSB_TO_BB(mp, mval[i].br_blockcount), 0);
- xfs_trans_binval(tp, bp);
- }
- /*
- * Unmap the dead block(s) to the free_list.
- */
- if ((error = xfs_bunmapi(tp, ip, 0, size, XFS_BMAPI_METADATA, nmaps,
- &first_block, &free_list, NULL, &done)))
- goto error1;
- ASSERT(done);
- /*
- * Commit the first transaction. This logs the EFI and the inode.
- */
- if ((error = xfs_bmap_finish(&tp, &free_list, first_block, &committed)))
- goto error1;
- /*
- * The transaction must have been committed, since there were
- * actually extents freed by xfs_bunmapi. See xfs_bmap_finish.
- * The new tp has the extent freeing and EFDs.
- */
- ASSERT(committed);
- /*
- * The first xact was committed, so add the inode to the new one.
- * Mark it dirty so it will be logged and moved forward in the log as
- * part of every commit.
- */
- xfs_trans_ijoin(tp, ip, XFS_ILOCK_EXCL | XFS_IOLOCK_EXCL);
- xfs_trans_ihold(tp, ip);
- xfs_trans_log_inode(tp, ip, XFS_ILOG_CORE);
- /*
- * Get a new, empty transaction to return to our caller.
- */
- ntp = xfs_trans_dup(tp);
- /*
- * Commit the transaction containing extent freeing and EFDs.
- * If we get an error on the commit here or on the reserve below,
- * we need to unlock the inode since the new transaction doesn't
- * have the inode attached.
- */
- error = xfs_trans_commit(tp, 0, NULL);
- tp = ntp;
- if (error) {
- ASSERT(XFS_FORCED_SHUTDOWN(mp));
- goto error0;
- }
- /*
- * Remove the memory for extent descriptions (just bookkeeping).
- */
- if (ip->i_df.if_bytes)
- xfs_idata_realloc(ip, -ip->i_df.if_bytes, XFS_DATA_FORK);
- ASSERT(ip->i_df.if_bytes == 0);
- /*
- * Put an itruncate log reservation in the new transaction
- * for our caller.
- */
- if ((error = xfs_trans_reserve(tp, 0, XFS_ITRUNCATE_LOG_RES(mp), 0,
- XFS_TRANS_PERM_LOG_RES, XFS_ITRUNCATE_LOG_COUNT))) {
- ASSERT(XFS_FORCED_SHUTDOWN(mp));
- goto error0;
- }
- /*
- * Return with the inode locked but not joined to the transaction.
- */
- *tpp = tp;
- return 0;
-
- error1:
- xfs_bmap_cancel(&free_list);
- error0:
- /*
- * Have to come here with the inode locked and either
- * (held and in the transaction) or (not in the transaction).
- * If the inode isn't held then cancel would iput it, but
- * that's wrong since this is inactive and the vnode ref
- * count is 0 already.
- * Cancel won't do anything to the inode if held, but it still
- * needs to be locked until the cancel is done, if it was
- * joined to the transaction.
- */
- xfs_trans_cancel(tp, XFS_TRANS_RELEASE_LOG_RES | XFS_TRANS_ABORT);
- xfs_iunlock(ip, XFS_IOLOCK_EXCL | XFS_ILOCK_EXCL);
- *tpp = NULL;
- return error;
-
-}
-
-STATIC int
-xfs_inactive_symlink_local(
- xfs_inode_t *ip,
- xfs_trans_t **tpp)
-{
- int error;
-
- ASSERT(ip->i_d.di_size <= XFS_IFORK_DSIZE(ip));
- /*
- * We're freeing a symlink which fit into
- * the inode. Just free the memory used
- * to hold the old symlink.
- */
- error = xfs_trans_reserve(*tpp, 0,
- XFS_ITRUNCATE_LOG_RES(ip->i_mount),
- 0, XFS_TRANS_PERM_LOG_RES,
- XFS_ITRUNCATE_LOG_COUNT);
-
- if (error) {
- xfs_trans_cancel(*tpp, 0);
- *tpp = NULL;
- return error;
- }
- xfs_ilock(ip, XFS_ILOCK_EXCL | XFS_IOLOCK_EXCL);
-
- /*
- * Zero length symlinks _can_ exist.
- */
- if (ip->i_df.if_bytes > 0) {
- xfs_idata_realloc(ip,
- -(ip->i_df.if_bytes),
- XFS_DATA_FORK);
- ASSERT(ip->i_df.if_bytes == 0);
- }
- return 0;
-}
-
-/*
- *
- */
-STATIC int
-xfs_inactive_attrs(
- xfs_inode_t *ip,
- xfs_trans_t **tpp)
-{
- xfs_trans_t *tp;
- int error;
- xfs_mount_t *mp;
-
- ASSERT(ismrlocked(&ip->i_iolock, MR_UPDATE));
- tp = *tpp;
- mp = ip->i_mount;
- ASSERT(ip->i_d.di_forkoff != 0);
- xfs_trans_commit(tp, XFS_TRANS_RELEASE_LOG_RES, NULL);
- xfs_iunlock(ip, XFS_ILOCK_EXCL);
-
- error = xfs_attr_inactive(ip);
- if (error) {
- *tpp = NULL;
- xfs_iunlock(ip, XFS_IOLOCK_EXCL);
- return error; /* goto out */
- }
-
- tp = xfs_trans_alloc(mp, XFS_TRANS_INACTIVE);
- error = xfs_trans_reserve(tp, 0,
- XFS_IFREE_LOG_RES(mp),
- 0, XFS_TRANS_PERM_LOG_RES,
- XFS_INACTIVE_LOG_COUNT);
- if (error) {
- ASSERT(XFS_FORCED_SHUTDOWN(mp));
- xfs_trans_cancel(tp, 0);
- *tpp = NULL;
- xfs_iunlock(ip, XFS_IOLOCK_EXCL);
- return error;
- }
-
- xfs_ilock(ip, XFS_ILOCK_EXCL);
- xfs_trans_ijoin(tp, ip, XFS_IOLOCK_EXCL | XFS_ILOCK_EXCL);
- xfs_trans_ihold(tp, ip);
- xfs_idestroy_fork(ip, XFS_ATTR_FORK);
-
- ASSERT(ip->i_d.di_anextents == 0);
-
- *tpp = tp;
- return 0;
-}
-
-STATIC int
-xfs_release(
- bhv_desc_t *bdp)
-{
- xfs_inode_t *ip;
- xfs_vnode_t *vp;
- xfs_mount_t *mp;
- int error;
-
- vp = BHV_TO_VNODE(bdp);
- ip = XFS_BHVTOI(bdp);
-
- if (!VN_ISREG(vp) || (ip->i_d.di_mode == 0)) {
- return 0;
- }
-
- /* If this is a read-only mount, don't do this (would generate I/O) */
- if (vp->v_vfsp->vfs_flag & VFS_RDONLY)
- return 0;
-
-#ifdef HAVE_REFCACHE
- /* If we are in the NFS reference cache then don't do this now */
- if (ip->i_refcache)
- return 0;
-#endif
-
- mp = ip->i_mount;
-
- if (ip->i_d.di_nlink != 0) {
- if ((((ip->i_d.di_mode & S_IFMT) == S_IFREG) &&
- ((ip->i_d.di_size > 0) || (VN_CACHED(vp) > 0 ||
- ip->i_delayed_blks > 0)) &&
- (ip->i_df.if_flags & XFS_IFEXTENTS)) &&
- (!(ip->i_d.di_flags &
- (XFS_DIFLAG_PREALLOC | XFS_DIFLAG_APPEND)))) {
- if ((error = xfs_inactive_free_eofblocks(mp, ip)))
- return error;
-
-#ifdef RMC /* Update linux inode block count after free above */
- vn_to_inode(vp)->i_blocks = XFS_FSB_TO_BB(mp,
- ip->i_d.di_nblocks + ip->i_delayed_blks);
-#endif
- }
- }
-
- return 0;
-}
-
-/*
- * xfs_inactive
- *
- * This is called when the vnode reference count for the vnode
- * goes to zero. If the file has been unlinked, then it must
- * now be truncated. Also, we clear all of the read-ahead state
- * kept for the inode here since the file is now closed.
- */
-STATIC int
-xfs_inactive(
- bhv_desc_t *bdp,
- cred_t *credp)
-{
- xfs_inode_t *ip;
- xfs_vnode_t *vp;
-
- xfs_bmap_free_t free_list;
- xfs_fsblock_t first_block;
- int committed;
- xfs_trans_t *tp;
- xfs_mount_t *mp;
- int error;
- int truncate;
-
- vp = BHV_TO_VNODE(bdp);
- vn_trace_entry(vp, __FUNCTION__, (inst_t *)__return_address);
-
- ip = XFS_BHVTOI(bdp);
-
- /*
- * If the inode is already free, then there can be nothing
- * to clean up here.
- */
- if (ip->i_d.di_mode == 0 || VN_BAD(vp)) {
- ASSERT(ip->i_df.if_real_bytes == 0);
- ASSERT(ip->i_df.if_broot_bytes == 0);
- return VN_INACTIVE_CACHE;
- }
-
- /*
- * Only do a truncate if it's a regular file with
- * some actual space in it. It's OK to look at the
- * inode's fields without the lock because we're the
- * only one with a reference to the inode.
- */
- truncate = ((ip->i_d.di_nlink == 0) &&
- ((ip->i_d.di_size != 0) || (ip->i_d.di_nextents > 0) ||
- (ip->i_delayed_blks > 0)) &&
- ((ip->i_d.di_mode & S_IFMT) == S_IFREG));
-
- mp = ip->i_mount;
-
- if (ip->i_d.di_nlink == 0 &&
- DM_EVENT_ENABLED(vp->v_vfsp, ip, DM_EVENT_DESTROY)) {
- (void) XFS_SEND_DESTROY(mp, vp, DM_RIGHT_NULL);
- }
-
- error = 0;
-
- /* If this is a read-only mount, don't do this (would generate I/O) */
- if (vp->v_vfsp->vfs_flag & VFS_RDONLY)
- goto out;
-
- if (ip->i_d.di_nlink != 0) {
- if ((((ip->i_d.di_mode & S_IFMT) == S_IFREG) &&
- ((ip->i_d.di_size > 0) || (VN_CACHED(vp) > 0 ||
- ip->i_delayed_blks > 0)) &&
- (ip->i_df.if_flags & XFS_IFEXTENTS) &&
- (!(ip->i_d.di_flags &
- (XFS_DIFLAG_PREALLOC | XFS_DIFLAG_APPEND)) ||
- (ip->i_delayed_blks != 0)))) {
- if ((error = xfs_inactive_free_eofblocks(mp, ip)))
- return VN_INACTIVE_CACHE;
-#ifdef RMC
- /* Update linux inode block count after free above */
- vn_to_inode(vp)->i_blocks = XFS_FSB_TO_BB(mp,
- ip->i_d.di_nblocks + ip->i_delayed_blks);
-#endif
- }
- goto out;
- }
-
- ASSERT(ip->i_d.di_nlink == 0);
-
- if ((error = XFS_QM_DQATTACH(mp, ip, 0)))
- return VN_INACTIVE_CACHE;
-
- tp = xfs_trans_alloc(mp, XFS_TRANS_INACTIVE);
- if (truncate) {
- /*
- * Do the xfs_itruncate_start() call before
- * reserving any log space because itruncate_start
- * will call into the buffer cache and we can't
- * do that within a transaction.
- */
- xfs_ilock(ip, XFS_IOLOCK_EXCL);
-
- xfs_itruncate_start(ip, XFS_ITRUNC_DEFINITE, 0);
-
- error = xfs_trans_reserve(tp, 0,
- XFS_ITRUNCATE_LOG_RES(mp),
- 0, XFS_TRANS_PERM_LOG_RES,
- XFS_ITRUNCATE_LOG_COUNT);
- if (error) {
- /* Don't call itruncate_cleanup */
- ASSERT(XFS_FORCED_SHUTDOWN(mp));
- xfs_trans_cancel(tp, 0);
- xfs_iunlock(ip, XFS_IOLOCK_EXCL);
- return VN_INACTIVE_CACHE;
- }
-
- xfs_ilock(ip, XFS_ILOCK_EXCL);
- xfs_trans_ijoin(tp, ip, XFS_IOLOCK_EXCL | XFS_ILOCK_EXCL);
- xfs_trans_ihold(tp, ip);
-
- /*
- * normally, we have to run xfs_itruncate_finish sync.
- * But if filesystem is wsync and we're in the inactive
- * path, then we know that nlink == 0, and that the
- * xaction that made nlink == 0 is permanently committed
- * since xfs_remove runs as a synchronous transaction.
- */
- error = xfs_itruncate_finish(&tp, ip, 0, XFS_DATA_FORK,
- (!(mp->m_flags & XFS_MOUNT_WSYNC) ? 1 : 0));
-
- if (error) {
- xfs_trans_cancel(tp,
- XFS_TRANS_RELEASE_LOG_RES | XFS_TRANS_ABORT);
- xfs_iunlock(ip, XFS_IOLOCK_EXCL | XFS_ILOCK_EXCL);
- return VN_INACTIVE_CACHE;
- }
- } else if ((ip->i_d.di_mode & S_IFMT) == S_IFLNK) {
-
- /*
- * If we get an error while cleaning up a
- * symlink we bail out.
- */
- error = (ip->i_d.di_size > XFS_IFORK_DSIZE(ip)) ?
- xfs_inactive_symlink_rmt(ip, &tp) :
- xfs_inactive_symlink_local(ip, &tp);
-
- if (error) {
- ASSERT(tp == NULL);
- return VN_INACTIVE_CACHE;
- }
-
- xfs_trans_ijoin(tp, ip, XFS_IOLOCK_EXCL | XFS_ILOCK_EXCL);
- xfs_trans_ihold(tp, ip);
- } else {
- error = xfs_trans_reserve(tp, 0,
- XFS_IFREE_LOG_RES(mp),
- 0, XFS_TRANS_PERM_LOG_RES,
- XFS_INACTIVE_LOG_COUNT);
- if (error) {
- ASSERT(XFS_FORCED_SHUTDOWN(mp));
- xfs_trans_cancel(tp, 0);
- return VN_INACTIVE_CACHE;
- }
-
- xfs_ilock(ip, XFS_ILOCK_EXCL | XFS_IOLOCK_EXCL);
- xfs_trans_ijoin(tp, ip, XFS_IOLOCK_EXCL | XFS_ILOCK_EXCL);
- xfs_trans_ihold(tp, ip);
- }
-
- /*
- * If there are attributes associated with the file
- * then blow them away now. The code calls a routine
- * that recursively deconstructs the attribute fork.
- * We need to just commit the current transaction
- * because we can't use it for xfs_attr_inactive().
- */
- if (ip->i_d.di_anextents > 0) {
- error = xfs_inactive_attrs(ip, &tp);
- /*
- * If we got an error, the transaction is already
- * cancelled, and the inode is unlocked. Just get out.
- */
- if (error)
- return VN_INACTIVE_CACHE;
- } else if (ip->i_afp) {
- xfs_idestroy_fork(ip, XFS_ATTR_FORK);
- }
-
- /*
- * Free the inode.
- */
- XFS_BMAP_INIT(&free_list, &first_block);
- error = xfs_ifree(tp, ip, &free_list);
- if (error) {
- /*
- * If we fail to free the inode, shut down. The cancel
- * might do that, we need to make sure. Otherwise the
- * inode might be lost for a long time or forever.
- */
- if (!XFS_FORCED_SHUTDOWN(mp)) {
- cmn_err(CE_NOTE,
- "xfs_inactive: xfs_ifree() returned an error = %d on %s",
- error, mp->m_fsname);
- xfs_force_shutdown(mp, XFS_METADATA_IO_ERROR);
- }
- xfs_trans_cancel(tp, XFS_TRANS_RELEASE_LOG_RES|XFS_TRANS_ABORT);
- } else {
- /*
- * Credit the quota account(s). The inode is gone.
- */
- XFS_TRANS_MOD_DQUOT_BYINO(mp, tp, ip, XFS_TRANS_DQ_ICOUNT, -1);
-
- /*
- * Just ignore errors at this point. There is
- * nothing we can do except to try to keep going.
- */
- (void) xfs_bmap_finish(&tp, &free_list, first_block,
- &committed);
- (void) xfs_trans_commit(tp, XFS_TRANS_RELEASE_LOG_RES, NULL);
- }
- /*
- * Release the dquots held by inode, if any.
- */
- XFS_QM_DQDETACH(mp, ip);
-
- xfs_iunlock(ip, XFS_IOLOCK_EXCL | XFS_ILOCK_EXCL);
-
- out:
- return VN_INACTIVE_CACHE;
-}
-
-
-/*
- * xfs_lookup
- */
-STATIC int
-xfs_lookup(
- bhv_desc_t *dir_bdp,
- vname_t *dentry,
- xfs_vnode_t **vpp,
- int flags,
- xfs_vnode_t *rdir,
- cred_t *credp)
-{
- xfs_inode_t *dp, *ip;
- xfs_ino_t e_inum;
- int error;
- uint lock_mode;
- xfs_vnode_t *dir_vp;
-
- dir_vp = BHV_TO_VNODE(dir_bdp);
- vn_trace_entry(dir_vp, __FUNCTION__, (inst_t *)__return_address);
-
- dp = XFS_BHVTOI(dir_bdp);
-
- if (XFS_FORCED_SHUTDOWN(dp->i_mount))
- return XFS_ERROR(EIO);
-
- lock_mode = xfs_ilock_map_shared(dp);
- error = xfs_dir_lookup_int(dir_bdp, lock_mode, dentry, &e_inum, &ip);
- if (!error) {
- *vpp = XFS_ITOV(ip);
- ITRACE(ip);
- }
- xfs_iunlock_map_shared(dp, lock_mode);
- return error;
-}
-
-
-/*
- * xfs_create (create a new file).
- */
-STATIC int
-xfs_create(
- bhv_desc_t *dir_bdp,
- vname_t *dentry,
- xfs_vattr_t *vap,
- xfs_vnode_t **vpp,
- cred_t *credp)
-{
- char *name = VNAME(dentry);
- xfs_vnode_t *dir_vp;
- xfs_inode_t *dp, *ip;
- xfs_vnode_t *vp=NULL;
- xfs_trans_t *tp;
- xfs_mount_t *mp;
- xfs_dev_t rdev;
- int error;
- xfs_bmap_free_t free_list;
- xfs_fsblock_t first_block;
- boolean_t dp_joined_to_trans;
- int dm_event_sent = 0;
- uint cancel_flags;
- int committed;
- xfs_prid_t prid;
- struct xfs_dquot *udqp, *gdqp;
- uint resblks;
- int dm_di_mode;
- int namelen;
-
- ASSERT(!*vpp);
- dir_vp = BHV_TO_VNODE(dir_bdp);
- vn_trace_entry(dir_vp, __FUNCTION__, (inst_t *)__return_address);
-
- dp = XFS_BHVTOI(dir_bdp);
- mp = dp->i_mount;
-
- dm_di_mode = vap->va_mode;
- namelen = VNAMELEN(dentry);
-
- if (DM_EVENT_ENABLED(dir_vp->v_vfsp, dp, DM_EVENT_CREATE)) {
- error = XFS_SEND_NAMESP(mp, DM_EVENT_CREATE,
- dir_vp, DM_RIGHT_NULL, NULL,
- DM_RIGHT_NULL, name, NULL,
- dm_di_mode, 0, 0);
-
- if (error)
- return error;
- dm_event_sent = 1;
- }
-
- if (XFS_FORCED_SHUTDOWN(mp))
- return XFS_ERROR(EIO);
-
- /* Return through std_return after this point. */
-
- udqp = gdqp = NULL;
-
- if (dp->i_d.di_flags & XFS_DIFLAG_PROJINHERIT)
- prid = dp->i_d.di_projid;
- else if (vap->va_mask & XFS_AT_PROJID)
- prid = (xfs_prid_t)vap->va_projid;
- else
- prid = (xfs_prid_t)dfltprid;
-
- /*
- * Make sure that we have allocated dquot(s) on disk.
- */
- error = XFS_QM_DQVOPALLOC(mp, dp,
- current_fsuid(credp), current_fsgid(credp), prid,
- XFS_QMOPT_QUOTALL|XFS_QMOPT_INHERIT, &udqp, &gdqp);
- if (error)
- goto std_return;
-
- ip = NULL;
- dp_joined_to_trans = B_FALSE;
-
- tp = xfs_trans_alloc(mp, XFS_TRANS_CREATE);
- cancel_flags = XFS_TRANS_RELEASE_LOG_RES;
- resblks = XFS_CREATE_SPACE_RES(mp, namelen);
- /*
- * Initially assume that the file does not exist and
- * reserve the resources for that case. If that is not
- * the case we'll drop the one we have and get a more
- * appropriate transaction later.
- */
- error = xfs_trans_reserve(tp, resblks, XFS_CREATE_LOG_RES(mp), 0,
- XFS_TRANS_PERM_LOG_RES, XFS_CREATE_LOG_COUNT);
- if (error == ENOSPC) {
- resblks = 0;
- error = xfs_trans_reserve(tp, 0, XFS_CREATE_LOG_RES(mp), 0,
- XFS_TRANS_PERM_LOG_RES, XFS_CREATE_LOG_COUNT);
- }
- if (error) {
- cancel_flags = 0;
- dp = NULL;
- goto error_return;
- }
-
- xfs_ilock(dp, XFS_ILOCK_EXCL);
-
- XFS_BMAP_INIT(&free_list, &first_block);
-
- ASSERT(ip == NULL);
-
- /*
- * Reserve disk quota and the inode.
- */
- error = XFS_TRANS_RESERVE_QUOTA(mp, tp, udqp, gdqp, resblks, 1, 0);
- if (error)
- goto error_return;
-
- if (resblks == 0 &&
- (error = XFS_DIR_CANENTER(mp, tp, dp, name, namelen)))
- goto error_return;
- rdev = (vap->va_mask & XFS_AT_RDEV) ? vap->va_rdev : 0;
- error = xfs_dir_ialloc(&tp, dp, vap->va_mode, 1,
- rdev, credp, prid, resblks > 0,
- &ip, &committed);
- if (error) {
- if (error == ENOSPC)
- goto error_return;
- goto abort_return;
- }
- ITRACE(ip);
-
- /*
- * At this point, we've gotten a newly allocated inode.
- * It is locked (and joined to the transaction).
- */
-
- ASSERT(ismrlocked (&ip->i_lock, MR_UPDATE));
-
- /*
- * Now we join the directory inode to the transaction.
- * We do not do it earlier because xfs_dir_ialloc
- * might commit the previous transaction (and release
- * all the locks).
- */
-
- VN_HOLD(dir_vp);
- xfs_trans_ijoin(tp, dp, XFS_ILOCK_EXCL);
- dp_joined_to_trans = B_TRUE;
-
- error = XFS_DIR_CREATENAME(mp, tp, dp, name, namelen, ip->i_ino,
- &first_block, &free_list,
- resblks ? resblks - XFS_IALLOC_SPACE_RES(mp) : 0);
- if (error) {
- ASSERT(error != ENOSPC);
- goto abort_return;
- }
- xfs_ichgtime(dp, XFS_ICHGTIME_MOD | XFS_ICHGTIME_CHG);
- xfs_trans_log_inode(tp, dp, XFS_ILOG_CORE);
-
- /*
- * If this is a synchronous mount, make sure that the
- * create transaction goes to disk before returning to
- * the user.
- */
- if (mp->m_flags & (XFS_MOUNT_WSYNC|XFS_MOUNT_DIRSYNC)) {
- xfs_trans_set_sync(tp);
- }
-
- dp->i_gen++;
-
- /*
- * Attach the dquot(s) to the inodes and modify them incore.
- * These ids of the inode couldn't have changed since the new
- * inode has been locked ever since it was created.
- */
- XFS_QM_DQVOPCREATE(mp, tp, ip, udqp, gdqp);
-
- /*
- * xfs_trans_commit normally decrements the vnode ref count
- * when it unlocks the inode. Since we want to return the
- * vnode to the caller, we bump the vnode ref count now.
- */
- IHOLD(ip);
- vp = XFS_ITOV(ip);
-
- error = xfs_bmap_finish(&tp, &free_list, first_block, &committed);
- if (error) {
- xfs_bmap_cancel(&free_list);
- goto abort_rele;
- }
-
- error = xfs_trans_commit(tp, XFS_TRANS_RELEASE_LOG_RES, NULL);
- if (error) {
- IRELE(ip);
- tp = NULL;
- goto error_return;
- }
-
- XFS_QM_DQRELE(mp, udqp);
- XFS_QM_DQRELE(mp, gdqp);
-
- /*
- * Propagate the fact that the vnode changed after the
- * xfs_inode locks have been released.
- */
- XVOP_VNODE_CHANGE(vp, VCHANGE_FLAGS_TRUNCATED, 3);
-
- *vpp = vp;
-
- /* Fallthrough to std_return with error = 0 */
-
-std_return:
- if ( (*vpp || (error != 0 && dm_event_sent != 0)) &&
- DM_EVENT_ENABLED(dir_vp->v_vfsp, XFS_BHVTOI(dir_bdp),
- DM_EVENT_POSTCREATE)) {
- (void) XFS_SEND_NAMESP(mp, DM_EVENT_POSTCREATE,
- dir_vp, DM_RIGHT_NULL,
- *vpp ? vp:NULL,
- DM_RIGHT_NULL, name, NULL,
- dm_di_mode, error, 0);
- }
- return error;
-
- abort_return:
- cancel_flags |= XFS_TRANS_ABORT;
- /* FALLTHROUGH */
-
- error_return:
- if (tp != NULL)
- xfs_trans_cancel(tp, cancel_flags);
-
- if (!dp_joined_to_trans && (dp != NULL))
- xfs_iunlock(dp, XFS_ILOCK_EXCL);
- XFS_QM_DQRELE(mp, udqp);
- XFS_QM_DQRELE(mp, gdqp);
-
- goto std_return;
-
- abort_rele:
- /*
- * Wait until after the current transaction is aborted to
- * release the inode. This prevents recursive transactions
- * and deadlocks from xfs_inactive.
- */
- cancel_flags |= XFS_TRANS_ABORT;
- xfs_trans_cancel(tp, cancel_flags);
- IRELE(ip);
-
- XFS_QM_DQRELE(mp, udqp);
- XFS_QM_DQRELE(mp, gdqp);
-
- goto std_return;
-}
-
-#ifdef DEBUG
-/*
- * Some counters to see if (and how often) we are hitting some deadlock
- * prevention code paths.
- */
-
-int xfs_rm_locks;
-int xfs_rm_lock_delays;
-int xfs_rm_attempts;
-#endif
-
-/*
- * The following routine will lock the inodes associated with the
- * directory and the named entry in the directory. The locks are
- * acquired in increasing inode number.
- *
- * If the entry is "..", then only the directory is locked. The
- * vnode ref count will still include that from the .. entry in
- * this case.
- *
- * There is a deadlock we need to worry about. If the locked directory is
- * in the AIL, it might be blocking up the log. The next inode we lock
- * could be already locked by another thread waiting for log space (e.g
- * a permanent log reservation with a long running transaction (see
- * xfs_itruncate_finish)). To solve this, we must check if the directory
- * is in the ail and use lock_nowait. If we can't lock, we need to
- * drop the inode lock on the directory and try again. xfs_iunlock will
- * potentially push the tail if we were holding up the log.
- */
-STATIC int
-xfs_lock_dir_and_entry(
- xfs_inode_t *dp,
- vname_t *dentry,
- xfs_inode_t *ip) /* inode of entry 'name' */
-{
- int attempts;
- xfs_ino_t e_inum;
- xfs_inode_t *ips[2];
- xfs_log_item_t *lp;
-
-#ifdef DEBUG
- xfs_rm_locks++;
-#endif
- attempts = 0;
-
-again:
- xfs_ilock(dp, XFS_ILOCK_EXCL);
-
- e_inum = ip->i_ino;
-
- ITRACE(ip);
-
- /*
- * We want to lock in increasing inum. Since we've already
- * acquired the lock on the directory, we may need to release
- * if if the inum of the entry turns out to be less.
- */
- if (e_inum > dp->i_ino) {
- /*
- * We are already in the right order, so just
- * lock on the inode of the entry.
- * We need to use nowait if dp is in the AIL.
- */
-
- lp = (xfs_log_item_t *)dp->i_itemp;
- if (lp && (lp->li_flags & XFS_LI_IN_AIL)) {
- if (!xfs_ilock_nowait(ip, XFS_ILOCK_EXCL)) {
- attempts++;
-#ifdef DEBUG
- xfs_rm_attempts++;
-#endif
-
- /*
- * Unlock dp and try again.
- * xfs_iunlock will try to push the tail
- * if the inode is in the AIL.
- */
-
- xfs_iunlock(dp, XFS_ILOCK_EXCL);
-
- if ((attempts % 5) == 0) {
- delay(1); /* Don't just spin the CPU */
-#ifdef DEBUG
- xfs_rm_lock_delays++;
-#endif
- }
- goto again;
- }
- } else {
- xfs_ilock(ip, XFS_ILOCK_EXCL);
- }
- } else if (e_inum < dp->i_ino) {
- xfs_iunlock(dp, XFS_ILOCK_EXCL);
-
- ips[0] = ip;
- ips[1] = dp;
- xfs_lock_inodes(ips, 2, 0, XFS_ILOCK_EXCL);
- }
- /* else e_inum == dp->i_ino */
- /* This can happen if we're asked to lock /x/..
- * the entry is "..", which is also the parent directory.
- */
-
- return 0;
-}
-
-#ifdef DEBUG
-int xfs_locked_n;
-int xfs_small_retries;
-int xfs_middle_retries;
-int xfs_lots_retries;
-int xfs_lock_delays;
-#endif
-
-/*
- * The following routine will lock n inodes in exclusive mode.
- * We assume the caller calls us with the inodes in i_ino order.
- *
- * We need to detect deadlock where an inode that we lock
- * is in the AIL and we start waiting for another inode that is locked
- * by a thread in a long running transaction (such as truncate). This can
- * result in deadlock since the long running trans might need to wait
- * for the inode we just locked in order to push the tail and free space
- * in the log.
- */
-void
-xfs_lock_inodes(
- xfs_inode_t **ips,
- int inodes,
- int first_locked,
- uint lock_mode)
-{
- int attempts = 0, i, j, try_lock;
- xfs_log_item_t *lp;
-
- ASSERT(ips && (inodes >= 2)); /* we need at least two */
-
- if (first_locked) {
- try_lock = 1;
- i = 1;
- } else {
- try_lock = 0;
- i = 0;
- }
-
-again:
- for (; i < inodes; i++) {
- ASSERT(ips[i]);
-
- if (i && (ips[i] == ips[i-1])) /* Already locked */
- continue;
-
- /*
- * If try_lock is not set yet, make sure all locked inodes
- * are not in the AIL.
- * If any are, set try_lock to be used later.
- */
-
- if (!try_lock) {
- for (j = (i - 1); j >= 0 && !try_lock; j--) {
- lp = (xfs_log_item_t *)ips[j]->i_itemp;
- if (lp && (lp->li_flags & XFS_LI_IN_AIL)) {
- try_lock++;
- }
- }
- }
-
- /*
- * If any of the previous locks we have locked is in the AIL,
- * we must TRY to get the second and subsequent locks. If
- * we can't get any, we must release all we have
- * and try again.
- */
-
- if (try_lock) {
- /* try_lock must be 0 if i is 0. */
- /*
- * try_lock means we have an inode locked
- * that is in the AIL.
- */
- ASSERT(i != 0);
- if (!xfs_ilock_nowait(ips[i], lock_mode)) {
- attempts++;
-
- /*
- * Unlock all previous guys and try again.
- * xfs_iunlock will try to push the tail
- * if the inode is in the AIL.
- */
-
- for(j = i - 1; j >= 0; j--) {
-
- /*
- * Check to see if we've already
- * unlocked this one.
- * Not the first one going back,
- * and the inode ptr is the same.
- */
- if ((j != (i - 1)) && ips[j] ==
- ips[j+1])
- continue;
-
- xfs_iunlock(ips[j], lock_mode);
- }
-
- if ((attempts % 5) == 0) {
- delay(1); /* Don't just spin the CPU */
-#ifdef DEBUG
- xfs_lock_delays++;
-#endif
- }
- i = 0;
- try_lock = 0;
- goto again;
- }
- } else {
- xfs_ilock(ips[i], lock_mode);
- }
- }
-
-#ifdef DEBUG
- if (attempts) {
- if (attempts < 5) xfs_small_retries++;
- else if (attempts < 100) xfs_middle_retries++;
- else xfs_lots_retries++;
- } else {
- xfs_locked_n++;
- }
-#endif
-}
-
-#ifdef DEBUG
-#define REMOVE_DEBUG_TRACE(x) {remove_which_error_return = (x);}
-int remove_which_error_return = 0;
-#else /* ! DEBUG */
-#define REMOVE_DEBUG_TRACE(x)
-#endif /* ! DEBUG */
-
-extern int xfs_remove(bhv_desc_t *, bhv_desc_t *, vname_t *, cred_t *);
-/*
- * xfs_remove
- *
- */
-int
-xfs_remove(
- bhv_desc_t *dir_bdp,
- bhv_desc_t *vp_bdp,
- vname_t *dentry,
- cred_t *credp)
-{
- xfs_vnode_t *dir_vp;
- xfs_vnode_t *xvp;
- char *name = VNAME(dentry);
- xfs_inode_t *dp, *ip;
- xfs_trans_t *tp = NULL;
- xfs_mount_t *mp;
- int error = 0;
- xfs_bmap_free_t free_list;
- xfs_fsblock_t first_block;
- int cancel_flags;
- int committed;
- int dm_di_mode = 0;
- int link_zero;
- uint resblks;
- int namelen;
-
- dir_vp = BHV_TO_VNODE(dir_bdp);
- xvp = BHV_TO_VNODE(vp_bdp);
-
- printf("xfs_remove: dvp %p vp %p\n",dir_vp,xvp);
- vn_trace_entry(dir_vp, __FUNCTION__, (inst_t *)__return_address);
-
- dp = XFS_BHVTOI(dir_bdp);
- mp = dp->i_mount;
-
- if (XFS_FORCED_SHUTDOWN(mp))
- return XFS_ERROR(EIO);
-
- namelen = VNAMELEN(dentry);
-
- if (DM_EVENT_ENABLED(dir_vp->v_vfsp, dp, DM_EVENT_REMOVE)) {
- error = XFS_SEND_NAMESP(mp, DM_EVENT_REMOVE, dir_vp,
- DM_RIGHT_NULL, NULL, DM_RIGHT_NULL,
- name, NULL, 0, 0, 0);
- if (error)
- return error;
- }
-
- /* From this point on, return through std_return */
- ip = NULL;
-
- /*
- * We need to get a reference to ip before we get our log
- * reservation. The reason for this is that we cannot call
- * xfs_iget for an inode for which we do not have a reference
- * once we've acquired a log reservation. This is because the
- * inode we are trying to get might be in xfs_inactive going
- * for a log reservation. Since we'll have to wait for the
- * inactive code to complete before returning from xfs_iget,
- * we need to make sure that we don't have log space reserved
- * when we call xfs_iget. Instead we get an unlocked reference
- * to the inode before getting our log reservation.
- */
-#ifdef RMC
- error = xfs_get_dir_entry(dentry, &ip);
-#endif
- /* FreeBSD has already done the lookup */
- ip = xvp->v_inode;
- VN_HOLD(xvp);
-
- if (error) {
- REMOVE_DEBUG_TRACE(__LINE__);
- goto std_return;
- }
-
- dm_di_mode = ip->i_d.di_mode;
-
- vn_trace_entry(XFS_ITOV(ip), __FUNCTION__, (inst_t *)__return_address);
-
- ITRACE(ip);
-
- error = XFS_QM_DQATTACH(mp, dp, 0);
- if (!error && dp != ip)
- error = XFS_QM_DQATTACH(mp, ip, 0);
- if (error) {
- REMOVE_DEBUG_TRACE(__LINE__);
- IRELE(ip);
- goto std_return;
- }
-
- tp = xfs_trans_alloc(mp, XFS_TRANS_REMOVE);
- cancel_flags = XFS_TRANS_RELEASE_LOG_RES;
- /*
- * We try to get the real space reservation first,
- * allowing for directory btree deletion(s) implying
- * possible bmap insert(s). If we can't get the space
- * reservation then we use 0 instead, and avoid the bmap
- * btree insert(s) in the directory code by, if the bmap
- * insert tries to happen, instead trimming the LAST
- * block from the directory.
- */
- resblks = XFS_REMOVE_SPACE_RES(mp);
- error = xfs_trans_reserve(tp, resblks, XFS_REMOVE_LOG_RES(mp), 0,
- XFS_TRANS_PERM_LOG_RES, XFS_REMOVE_LOG_COUNT);
- if (error == ENOSPC) {
- resblks = 0;
- error = xfs_trans_reserve(tp, 0, XFS_REMOVE_LOG_RES(mp), 0,
- XFS_TRANS_PERM_LOG_RES, XFS_REMOVE_LOG_COUNT);
- }
- if (error) {
- ASSERT(error != ENOSPC);
- REMOVE_DEBUG_TRACE(__LINE__);
- xfs_trans_cancel(tp, 0);
- IRELE(ip);
- return error;
- }
-
- error = xfs_lock_dir_and_entry(dp, dentry, ip);
- if (error) {
- REMOVE_DEBUG_TRACE(__LINE__);
- xfs_trans_cancel(tp, cancel_flags);
- IRELE(ip);
- goto std_return;
- }
-
- /*
- * At this point, we've gotten both the directory and the entry
- * inodes locked.
- */
- xfs_trans_ijoin(tp, dp, XFS_ILOCK_EXCL);
- if (dp != ip) {
- /*
- * Increment vnode ref count only in this case since
- * there's an extra vnode reference in the case where
- * dp == ip.
- */
- IHOLD(dp);
- xfs_trans_ijoin(tp, ip, XFS_ILOCK_EXCL);
- }
-
- /*
- * Entry must exist since we did a lookup in xfs_lock_dir_and_entry.
- */
- XFS_BMAP_INIT(&free_list, &first_block);
- error = XFS_DIR_REMOVENAME(mp, tp, dp, name, namelen, ip->i_ino,
- &first_block, &free_list, 0);
- if (error) {
- ASSERT(error != ENOENT);
- REMOVE_DEBUG_TRACE(__LINE__);
- goto error1;
- }
- xfs_ichgtime(dp, XFS_ICHGTIME_MOD | XFS_ICHGTIME_CHG);
-
- dp->i_gen++;
- xfs_trans_log_inode(tp, dp, XFS_ILOG_CORE);
-
- error = xfs_droplink(tp, ip);
- if (error) {
- REMOVE_DEBUG_TRACE(__LINE__);
- goto error1;
- }
-
- /* Determine if this is the last link while
- * we are in the transaction.
- */
- link_zero = (ip)->i_d.di_nlink==0;
-
- /*
- * Take an extra ref on the inode so that it doesn't
- * go to xfs_inactive() from within the commit.
- */
- IHOLD(ip);
-
- /*
- * If this is a synchronous mount, make sure that the
- * remove transaction goes to disk before returning to
- * the user.
- */
- if (mp->m_flags & (XFS_MOUNT_WSYNC|XFS_MOUNT_DIRSYNC)) {
- xfs_trans_set_sync(tp);
- }
-
- error = xfs_bmap_finish(&tp, &free_list, first_block, &committed);
- if (error) {
- REMOVE_DEBUG_TRACE(__LINE__);
- goto error_rele;
- }
-
- error = xfs_trans_commit(tp, XFS_TRANS_RELEASE_LOG_RES, NULL);
- if (error) {
- IRELE(ip);
- goto std_return;
- }
-
- /*
- * Before we drop our extra reference to the inode, purge it
- * from the refcache if it is there. By waiting until afterwards
- * to do the IRELE, we ensure that we won't go inactive in the
- * xfs_refcache_purge_ip routine (although that would be OK).
- */
- xfs_refcache_purge_ip(ip);
-
- vn_trace_exit(XFS_ITOV(ip), __FUNCTION__, (inst_t *)__return_address);
-
- /*
- * Let interposed file systems know about removed links.
- */
- XVOP_LINK_REMOVED(XFS_ITOV(ip), dir_vp, link_zero);
-
- IRELE(ip);
-
-/* Fall through to std_return with error = 0 */
- std_return:
- if (DM_EVENT_ENABLED(dir_vp->v_vfsp, dp,
- DM_EVENT_POSTREMOVE)) {
- (void) XFS_SEND_NAMESP(mp, DM_EVENT_POSTREMOVE,
- dir_vp, DM_RIGHT_NULL,
- NULL, DM_RIGHT_NULL,
- name, NULL, dm_di_mode, error, 0);
- }
- return error;
-
- error1:
- xfs_bmap_cancel(&free_list);
- cancel_flags |= XFS_TRANS_ABORT;
- xfs_trans_cancel(tp, cancel_flags);
- goto std_return;
-
- error_rele:
- /*
- * In this case make sure to not release the inode until after
- * the current transaction is aborted. Releasing it beforehand
- * can cause us to go to xfs_inactive and start a recursive
- * transaction which can easily deadlock with the current one.
- */
- xfs_bmap_cancel(&free_list);
- cancel_flags |= XFS_TRANS_ABORT;
- xfs_trans_cancel(tp, cancel_flags);
-
- /*
- * Before we drop our extra reference to the inode, purge it
- * from the refcache if it is there. By waiting until afterwards
- * to do the IRELE, we ensure that we won't go inactive in the
- * xfs_refcache_purge_ip routine (although that would be OK).
- */
- xfs_refcache_purge_ip(ip);
-
- IRELE(ip);
-
- goto std_return;
-}
-
-
-/*
- * xfs_link
- *
- */
-STATIC int
-xfs_link(
- bhv_desc_t *target_dir_bdp,
- xfs_vnode_t *src_vp,
- vname_t *dentry,
- cred_t *credp)
-{
- xfs_inode_t *tdp, *sip;
- xfs_trans_t *tp;
- xfs_mount_t *mp;
- xfs_inode_t *ips[2];
- int error;
- xfs_bmap_free_t free_list;
- xfs_fsblock_t first_block;
- int cancel_flags;
- int committed;
- xfs_vnode_t *target_dir_vp;
- int resblks;
- char *target_name = VNAME(dentry);
- int target_namelen;
-
- target_dir_vp = BHV_TO_VNODE(target_dir_bdp);
- vn_trace_entry(target_dir_vp, __FUNCTION__, (inst_t *)__return_address);
- vn_trace_entry(src_vp, __FUNCTION__, (inst_t *)__return_address);
-
- target_namelen = VNAMELEN(dentry);
- if (VN_ISDIR(src_vp))
- return XFS_ERROR(EPERM);
-
- sip = xfs_vtoi(src_vp);
- tdp = XFS_BHVTOI(target_dir_bdp);
- mp = tdp->i_mount;
- if (XFS_FORCED_SHUTDOWN(mp))
- return XFS_ERROR(EIO);
-
- if (DM_EVENT_ENABLED(src_vp->v_vfsp, tdp, DM_EVENT_LINK)) {
- error = XFS_SEND_NAMESP(mp, DM_EVENT_LINK,
- target_dir_vp, DM_RIGHT_NULL,
- src_vp, DM_RIGHT_NULL,
- target_name, NULL, 0, 0, 0);
- if (error)
- return error;
- }
-
- /* Return through std_return after this point. */
-
- error = XFS_QM_DQATTACH(mp, sip, 0);
- if (!error && sip != tdp)
- error = XFS_QM_DQATTACH(mp, tdp, 0);
- if (error)
- goto std_return;
-
- tp = xfs_trans_alloc(mp, XFS_TRANS_LINK);
- cancel_flags = XFS_TRANS_RELEASE_LOG_RES;
- resblks = XFS_LINK_SPACE_RES(mp, target_namelen);
- error = xfs_trans_reserve(tp, resblks, XFS_LINK_LOG_RES(mp), 0,
- XFS_TRANS_PERM_LOG_RES, XFS_LINK_LOG_COUNT);
- if (error == ENOSPC) {
- resblks = 0;
- error = xfs_trans_reserve(tp, 0, XFS_LINK_LOG_RES(mp), 0,
- XFS_TRANS_PERM_LOG_RES, XFS_LINK_LOG_COUNT);
- }
- if (error) {
- cancel_flags = 0;
- goto error_return;
- }
-
- if (sip->i_ino < tdp->i_ino) {
- ips[0] = sip;
- ips[1] = tdp;
- } else {
- ips[0] = tdp;
- ips[1] = sip;
- }
-
- xfs_lock_inodes(ips, 2, 0, XFS_ILOCK_EXCL);
-
- /*
- * Increment vnode ref counts since xfs_trans_commit &
- * xfs_trans_cancel will both unlock the inodes and
- * decrement the associated ref counts.
- */
- VN_HOLD(src_vp);
- VN_HOLD(target_dir_vp);
- xfs_trans_ijoin(tp, sip, XFS_ILOCK_EXCL);
- xfs_trans_ijoin(tp, tdp, XFS_ILOCK_EXCL);
-
- /*
- * If the source has too many links, we can't make any more to it.
- */
- if (sip->i_d.di_nlink >= XFS_MAXLINK) {
- error = XFS_ERROR(EMLINK);
- goto error_return;
- }
-
- /*
- * If we are using project inheritance, we only allow hard link
- * creation in our tree when the project IDs are the same; else
- * the tree quota mechanism could be circumvented.
- */
- if (unlikely((tdp->i_d.di_flags & XFS_DIFLAG_PROJINHERIT) &&
- (tdp->i_d.di_projid != sip->i_d.di_projid))) {
- error = XFS_ERROR(EPERM);
- goto error_return;
- }
-
- if (resblks == 0 &&
- (error = XFS_DIR_CANENTER(mp, tp, tdp, target_name,
- target_namelen)))
- goto error_return;
-
- XFS_BMAP_INIT(&free_list, &first_block);
-
- error = XFS_DIR_CREATENAME(mp, tp, tdp, target_name, target_namelen,
- sip->i_ino, &first_block, &free_list,
- resblks);
- if (error)
- goto abort_return;
- xfs_ichgtime(tdp, XFS_ICHGTIME_MOD | XFS_ICHGTIME_CHG);
- tdp->i_gen++;
- xfs_trans_log_inode(tp, tdp, XFS_ILOG_CORE);
-
- error = xfs_bumplink(tp, sip);
- if (error) {
- goto abort_return;
- }
-
- /*
- * If this is a synchronous mount, make sure that the
- * link transaction goes to disk before returning to
- * the user.
- */
- if (mp->m_flags & (XFS_MOUNT_WSYNC|XFS_MOUNT_DIRSYNC)) {
- xfs_trans_set_sync(tp);
- }
-
- error = xfs_bmap_finish (&tp, &free_list, first_block, &committed);
- if (error) {
- xfs_bmap_cancel(&free_list);
- goto abort_return;
- }
-
- error = xfs_trans_commit(tp, XFS_TRANS_RELEASE_LOG_RES, NULL);
- if (error) {
- goto std_return;
- }
-
- /* Fall through to std_return with error = 0. */
-std_return:
- if (DM_EVENT_ENABLED(src_vp->v_vfsp, sip,
- DM_EVENT_POSTLINK)) {
- (void) XFS_SEND_NAMESP(mp, DM_EVENT_POSTLINK,
- target_dir_vp, DM_RIGHT_NULL,
- src_vp, DM_RIGHT_NULL,
- target_name, NULL, 0, error, 0);
- }
- return error;
-
- abort_return:
- cancel_flags |= XFS_TRANS_ABORT;
- /* FALLTHROUGH */
-
- error_return:
- xfs_trans_cancel(tp, cancel_flags);
- goto std_return;
-}
-/*
- * xfs_mkdir
- *
- */
-STATIC int
-xfs_mkdir(
- bhv_desc_t *dir_bdp,
- vname_t *dentry,
- xfs_vattr_t *vap,
- xfs_vnode_t **vpp,
- cred_t *credp)
-{
- char *dir_name = VNAME(dentry);
- xfs_inode_t *dp;
- xfs_inode_t *cdp; /* inode of created dir */
- xfs_vnode_t *cvp; /* vnode of created dir */
- xfs_trans_t *tp;
- xfs_mount_t *mp;
- int cancel_flags;
- int error;
- int committed;
- xfs_bmap_free_t free_list;
- xfs_fsblock_t first_block;
- xfs_vnode_t *dir_vp;
- boolean_t dp_joined_to_trans;
- boolean_t created = B_FALSE;
- int dm_event_sent = 0;
- xfs_prid_t prid;
- struct xfs_dquot *udqp, *gdqp;
- uint resblks;
- int dm_di_mode;
- int dir_namelen;
-
- dir_vp = BHV_TO_VNODE(dir_bdp);
- dp = XFS_BHVTOI(dir_bdp);
- mp = dp->i_mount;
-
- if (XFS_FORCED_SHUTDOWN(mp))
- return XFS_ERROR(EIO);
-
- dir_namelen = VNAMELEN(dentry);
-
- tp = NULL;
- dp_joined_to_trans = B_FALSE;
- dm_di_mode = vap->va_mode;
-
- if (DM_EVENT_ENABLED(dir_vp->v_vfsp, dp, DM_EVENT_CREATE)) {
- error = XFS_SEND_NAMESP(mp, DM_EVENT_CREATE,
- dir_vp, DM_RIGHT_NULL, NULL,
- DM_RIGHT_NULL, dir_name, NULL,
- dm_di_mode, 0, 0);
- if (error)
- return error;
- dm_event_sent = 1;
- }
-
- /* Return through std_return after this point. */
-
- vn_trace_entry(dir_vp, __FUNCTION__, (inst_t *)__return_address);
-
- mp = dp->i_mount;
- udqp = gdqp = NULL;
-
- if (dp->i_d.di_flags & XFS_DIFLAG_PROJINHERIT)
- prid = dp->i_d.di_projid;
- else if (vap->va_mask & XFS_AT_PROJID)
- prid = (xfs_prid_t)vap->va_projid;
- else
- prid = (xfs_prid_t)dfltprid;
-
- /*
- * Make sure that we have allocated dquot(s) on disk.
- */
- error = XFS_QM_DQVOPALLOC(mp, dp,
- current_fsuid(credp), current_fsgid(credp), prid,
- XFS_QMOPT_QUOTALL | XFS_QMOPT_INHERIT, &udqp, &gdqp);
- if (error)
- goto std_return;
-
- tp = xfs_trans_alloc(mp, XFS_TRANS_MKDIR);
- cancel_flags = XFS_TRANS_RELEASE_LOG_RES;
- resblks = XFS_MKDIR_SPACE_RES(mp, dir_namelen);
- error = xfs_trans_reserve(tp, resblks, XFS_MKDIR_LOG_RES(mp), 0,
- XFS_TRANS_PERM_LOG_RES, XFS_MKDIR_LOG_COUNT);
- if (error == ENOSPC) {
- resblks = 0;
- error = xfs_trans_reserve(tp, 0, XFS_MKDIR_LOG_RES(mp), 0,
- XFS_TRANS_PERM_LOG_RES,
- XFS_MKDIR_LOG_COUNT);
- }
- if (error) {
- cancel_flags = 0;
- dp = NULL;
- goto error_return;
- }
-
- xfs_ilock(dp, XFS_ILOCK_EXCL);
-
- /*
- * Check for directory link count overflow.
- */
- if (dp->i_d.di_nlink >= XFS_MAXLINK) {
- error = XFS_ERROR(EMLINK);
- goto error_return;
- }
-
- /*
- * Reserve disk quota and the inode.
- */
- error = XFS_TRANS_RESERVE_QUOTA(mp, tp, udqp, gdqp, resblks, 1, 0);
- if (error)
- goto error_return;
-
- if (resblks == 0 &&
- (error = XFS_DIR_CANENTER(mp, tp, dp, dir_name, dir_namelen)))
- goto error_return;
- /*
- * create the directory inode.
- */
- error = xfs_dir_ialloc(&tp, dp, vap->va_mode, 2,
- 0, credp, prid, resblks > 0,
- &cdp, NULL);
- if (error) {
- if (error == ENOSPC)
- goto error_return;
- goto abort_return;
- }
- ITRACE(cdp);
-
- /*
- * Now we add the directory inode to the transaction.
- * We waited until now since xfs_dir_ialloc might start
- * a new transaction. Had we joined the transaction
- * earlier, the locks might have gotten released.
- */
- VN_HOLD(dir_vp);
- xfs_trans_ijoin(tp, dp, XFS_ILOCK_EXCL);
- dp_joined_to_trans = B_TRUE;
-
- XFS_BMAP_INIT(&free_list, &first_block);
-
- error = XFS_DIR_CREATENAME(mp, tp, dp, dir_name, dir_namelen,
- cdp->i_ino, &first_block, &free_list,
- resblks ? resblks - XFS_IALLOC_SPACE_RES(mp) : 0);
- if (error) {
- ASSERT(error != ENOSPC);
- goto error1;
- }
- xfs_ichgtime(dp, XFS_ICHGTIME_MOD | XFS_ICHGTIME_CHG);
-
- /*
- * Bump the in memory version number of the parent directory
- * so that other processes accessing it will recognize that
- * the directory has changed.
- */
- dp->i_gen++;
-
- error = XFS_DIR_INIT(mp, tp, cdp, dp);
- if (error) {
- goto error2;
- }
-
- cdp->i_gen = 1;
- error = xfs_bumplink(tp, dp);
- if (error) {
- goto error2;
- }
-
- cvp = XFS_ITOV(cdp);
-
- created = B_TRUE;
-
- *vpp = cvp;
- IHOLD(cdp);
-
- /*
- * Attach the dquots to the new inode and modify the icount incore.
- */
- XFS_QM_DQVOPCREATE(mp, tp, cdp, udqp, gdqp);
-
- /*
- * If this is a synchronous mount, make sure that the
- * mkdir transaction goes to disk before returning to
- * the user.
- */
- if (mp->m_flags & (XFS_MOUNT_WSYNC|XFS_MOUNT_DIRSYNC)) {
- xfs_trans_set_sync(tp);
- }
-
- error = xfs_bmap_finish(&tp, &free_list, first_block, &committed);
- if (error) {
- IRELE(cdp);
- goto error2;
- }
-
- error = xfs_trans_commit(tp, XFS_TRANS_RELEASE_LOG_RES, NULL);
- XFS_QM_DQRELE(mp, udqp);
- XFS_QM_DQRELE(mp, gdqp);
- if (error) {
- IRELE(cdp);
- }
-
- /* Fall through to std_return with error = 0 or errno from
- * xfs_trans_commit. */
-
-std_return:
- if ( (created || (error != 0 && dm_event_sent != 0)) &&
- DM_EVENT_ENABLED(dir_vp->v_vfsp, XFS_BHVTOI(dir_bdp),
- DM_EVENT_POSTCREATE)) {
- (void) XFS_SEND_NAMESP(mp, DM_EVENT_POSTCREATE,
- dir_vp, DM_RIGHT_NULL,
- created ? XFS_ITOV(cdp):NULL,
- DM_RIGHT_NULL,
- dir_name, NULL,
- dm_di_mode, error, 0);
- }
- return error;
-
- error2:
- error1:
- xfs_bmap_cancel(&free_list);
- abort_return:
- cancel_flags |= XFS_TRANS_ABORT;
- error_return:
- xfs_trans_cancel(tp, cancel_flags);
- XFS_QM_DQRELE(mp, udqp);
- XFS_QM_DQRELE(mp, gdqp);
-
- if (!dp_joined_to_trans && (dp != NULL)) {
- xfs_iunlock(dp, XFS_ILOCK_EXCL);
- }
-
- goto std_return;
-}
-
-
-/*
- * xfs_rmdir
- *
- */
-STATIC int
-xfs_rmdir(
- bhv_desc_t *dir_bdp,
- vname_t *dentry,
- cred_t *credp)
-{
- char *name = VNAME(dentry);
- xfs_inode_t *dp;
- xfs_inode_t *cdp; /* child directory */
- xfs_trans_t *tp;
- xfs_mount_t *mp;
- int error;
- xfs_bmap_free_t free_list;
- xfs_fsblock_t first_block;
- int cancel_flags;
- int committed;
- xfs_vnode_t *dir_vp;
- int dm_di_mode = 0;
- int last_cdp_link;
- int namelen;
- uint resblks;
-
- dir_vp = BHV_TO_VNODE(dir_bdp);
- dp = XFS_BHVTOI(dir_bdp);
- mp = dp->i_mount;
-
- vn_trace_entry(dir_vp, __FUNCTION__, (inst_t *)__return_address);
-
- if (XFS_FORCED_SHUTDOWN(XFS_BHVTOI(dir_bdp)->i_mount))
- return XFS_ERROR(EIO);
- namelen = VNAMELEN(dentry);
-
- if (DM_EVENT_ENABLED(dir_vp->v_vfsp, dp, DM_EVENT_REMOVE)) {
- error = XFS_SEND_NAMESP(mp, DM_EVENT_REMOVE,
- dir_vp, DM_RIGHT_NULL,
- NULL, DM_RIGHT_NULL,
- name, NULL, 0, 0, 0);
- if (error)
- return XFS_ERROR(error);
- }
-
- /* Return through std_return after this point. */
-
- cdp = NULL;
-
- /*
- * We need to get a reference to cdp before we get our log
- * reservation. The reason for this is that we cannot call
- * xfs_iget for an inode for which we do not have a reference
- * once we've acquired a log reservation. This is because the
- * inode we are trying to get might be in xfs_inactive going
- * for a log reservation. Since we'll have to wait for the
- * inactive code to complete before returning from xfs_iget,
- * we need to make sure that we don't have log space reserved
- * when we call xfs_iget. Instead we get an unlocked reference
- * to the inode before getting our log reservation.
- */
- error = xfs_get_dir_entry(dentry, &cdp);
- if (error) {
- REMOVE_DEBUG_TRACE(__LINE__);
- goto std_return;
- }
- mp = dp->i_mount;
- dm_di_mode = cdp->i_d.di_mode;
-
- /*
- * Get the dquots for the inodes.
- */
- error = XFS_QM_DQATTACH(mp, dp, 0);
- if (!error && dp != cdp)
- error = XFS_QM_DQATTACH(mp, cdp, 0);
- if (error) {
- IRELE(cdp);
- REMOVE_DEBUG_TRACE(__LINE__);
- goto std_return;
- }
-
- tp = xfs_trans_alloc(mp, XFS_TRANS_RMDIR);
- cancel_flags = XFS_TRANS_RELEASE_LOG_RES;
- /*
- * We try to get the real space reservation first,
- * allowing for directory btree deletion(s) implying
- * possible bmap insert(s). If we can't get the space
- * reservation then we use 0 instead, and avoid the bmap
- * btree insert(s) in the directory code by, if the bmap
- * insert tries to happen, instead trimming the LAST
- * block from the directory.
- */
- resblks = XFS_REMOVE_SPACE_RES(mp);
- error = xfs_trans_reserve(tp, resblks, XFS_REMOVE_LOG_RES(mp), 0,
- XFS_TRANS_PERM_LOG_RES, XFS_DEFAULT_LOG_COUNT);
- if (error == ENOSPC) {
- resblks = 0;
- error = xfs_trans_reserve(tp, 0, XFS_REMOVE_LOG_RES(mp), 0,
- XFS_TRANS_PERM_LOG_RES, XFS_DEFAULT_LOG_COUNT);
- }
- if (error) {
- ASSERT(error != ENOSPC);
- cancel_flags = 0;
- IRELE(cdp);
- goto error_return;
- }
- XFS_BMAP_INIT(&free_list, &first_block);
-
- /*
- * Now lock the child directory inode and the parent directory
- * inode in the proper order. This will take care of validating
- * that the directory entry for the child directory inode has
- * not changed while we were obtaining a log reservation.
- */
- error = xfs_lock_dir_and_entry(dp, dentry, cdp);
- if (error) {
- xfs_trans_cancel(tp, cancel_flags);
- IRELE(cdp);
- goto std_return;
- }
-
- xfs_trans_ijoin(tp, dp, XFS_ILOCK_EXCL);
- if (dp != cdp) {
- /*
- * Only increment the parent directory vnode count if
- * we didn't bump it in looking up cdp. The only time
- * we don't bump it is when we're looking up ".".
- */
- VN_HOLD(dir_vp);
- }
-
- ITRACE(cdp);
- xfs_trans_ijoin(tp, cdp, XFS_ILOCK_EXCL);
-
- ASSERT(cdp->i_d.di_nlink >= 2);
- if (cdp->i_d.di_nlink != 2) {
- error = XFS_ERROR(ENOTEMPTY);
- goto error_return;
- }
- if (!XFS_DIR_ISEMPTY(mp, cdp)) {
- error = XFS_ERROR(ENOTEMPTY);
- goto error_return;
- }
-
- error = XFS_DIR_REMOVENAME(mp, tp, dp, name, namelen, cdp->i_ino,
- &first_block, &free_list, resblks);
- if (error) {
- goto error1;
- }
-
- xfs_ichgtime(dp, XFS_ICHGTIME_MOD | XFS_ICHGTIME_CHG);
-
- /*
- * Bump the in memory generation count on the parent
- * directory so that other can know that it has changed.
- */
- dp->i_gen++;
-
- /*
- * Drop the link from cdp's "..".
- */
- error = xfs_droplink(tp, dp);
- if (error) {
- goto error1;
- }
-
- /*
- * Drop the link from dp to cdp.
- */
- error = xfs_droplink(tp, cdp);
- if (error) {
- goto error1;
- }
-
- /*
- * Drop the "." link from cdp to self.
- */
- error = xfs_droplink(tp, cdp);
- if (error) {
- goto error1;
- }
-
- /* Determine these before committing transaction */
- last_cdp_link = (cdp)->i_d.di_nlink==0;
-
- /*
- * Take an extra ref on the child vnode so that it
- * does not go to xfs_inactive() from within the commit.
- */
- IHOLD(cdp);
-
- /*
- * If this is a synchronous mount, make sure that the
- * rmdir transaction goes to disk before returning to
- * the user.
- */
- if (mp->m_flags & (XFS_MOUNT_WSYNC|XFS_MOUNT_DIRSYNC)) {
- xfs_trans_set_sync(tp);
- }
-
- error = xfs_bmap_finish (&tp, &free_list, first_block, &committed);
- if (error) {
- xfs_bmap_cancel(&free_list);
- xfs_trans_cancel(tp, (XFS_TRANS_RELEASE_LOG_RES |
- XFS_TRANS_ABORT));
- IRELE(cdp);
- goto std_return;
- }
-
- error = xfs_trans_commit(tp, XFS_TRANS_RELEASE_LOG_RES, NULL);
- if (error) {
- IRELE(cdp);
- goto std_return;
- }
-
-
- /*
- * Let interposed file systems know about removed links.
- */
- XVOP_LINK_REMOVED(XFS_ITOV(cdp), dir_vp, last_cdp_link);
-
- IRELE(cdp);
-
- /* Fall through to std_return with error = 0 or the errno
- * from xfs_trans_commit. */
- std_return:
- if (DM_EVENT_ENABLED(dir_vp->v_vfsp, dp, DM_EVENT_POSTREMOVE)) {
- (void) XFS_SEND_NAMESP(mp, DM_EVENT_POSTREMOVE,
- dir_vp, DM_RIGHT_NULL,
- NULL, DM_RIGHT_NULL,
- name, NULL, dm_di_mode,
- error, 0);
- }
- return error;
-
- error1:
- xfs_bmap_cancel(&free_list);
- cancel_flags |= XFS_TRANS_ABORT;
- /* FALLTHROUGH */
-
- error_return:
- xfs_trans_cancel(tp, cancel_flags);
- goto std_return;
-}
-
-
-/*
- * xfs_readdir
- *
- * Read dp's entries starting at uiop->uio_offset and translate them into
- * bufsize bytes worth of struct dirents starting at bufbase.
- */
-STATIC int
-xfs_readdir(
- bhv_desc_t *dir_bdp,
- uio_t *uiop,
- cred_t *credp,
- int *eofp)
-{
- xfs_inode_t *dp;
- xfs_trans_t *tp = NULL;
- int error = 0;
- uint lock_mode;
-
- vn_trace_entry(BHV_TO_VNODE(dir_bdp), __FUNCTION__,
- (inst_t *)__return_address);
- dp = XFS_BHVTOI(dir_bdp);
-
- if (XFS_FORCED_SHUTDOWN(dp->i_mount)) {
- return XFS_ERROR(EIO);
- }
-
- lock_mode = xfs_ilock_map_shared(dp);
- error = XFS_DIR_GETDENTS(dp->i_mount, tp, dp, uiop, eofp);
- xfs_iunlock_map_shared(dp, lock_mode);
- return error;
-}
-
-
-/*
- * xfs_symlink
- *
- */
-STATIC int
-xfs_symlink(
- bhv_desc_t *dir_bdp,
- vname_t *dentry,
- xfs_vattr_t *vap,
- char *target_path,
- xfs_vnode_t **vpp,
- cred_t *credp)
-{
- xfs_trans_t *tp;
- xfs_mount_t *mp;
- xfs_inode_t *dp;
- xfs_inode_t *ip;
- int error;
- int pathlen;
- xfs_bmap_free_t free_list;
- xfs_fsblock_t first_block;
- boolean_t dp_joined_to_trans;
- xfs_vnode_t *dir_vp;
- uint cancel_flags;
- int committed;
- xfs_fileoff_t first_fsb;
- xfs_filblks_t fs_blocks;
- int nmaps;
- xfs_bmbt_irec_t mval[SYMLINK_MAPS];
- xfs_daddr_t d;
- char *cur_chunk;
- int byte_cnt;
- int n;
- xfs_buf_t *bp;
- xfs_prid_t prid;
- struct xfs_dquot *udqp, *gdqp;
- uint resblks;
- char *link_name = VNAME(dentry);
- int link_namelen;
- struct thread *current = curthread;
-
- *vpp = NULL;
- dir_vp = BHV_TO_VNODE(dir_bdp);
- dp = XFS_BHVTOI(dir_bdp);
- dp_joined_to_trans = B_FALSE;
- error = 0;
- ip = NULL;
- tp = NULL;
-
- vn_trace_entry(dir_vp, __FUNCTION__, (inst_t *)__return_address);
-
- mp = dp->i_mount;
-
- if (XFS_FORCED_SHUTDOWN(mp))
- return XFS_ERROR(EIO);
-
- link_namelen = VNAMELEN(dentry);
-
- /*
- * Check component lengths of the target path name.
- */
- pathlen = strlen(target_path);
- if (pathlen >= MAXPATHLEN) /* total string too long */
- return XFS_ERROR(ENAMETOOLONG);
- if (pathlen >= MAXNAMELEN) { /* is any component too long? */
- int len, total;
- char *path;
-
- for(total = 0, path = target_path; total < pathlen;) {
- /*
- * Skip any slashes.
- */
- while(*path == '/') {
- total++;
- path++;
- }
-
- /*
- * Count up to the next slash or end of path.
- * Error out if the component is bigger than MAXNAMELEN.
- */
- for(len = 0; *path != '/' && total < pathlen;total++, path++) {
- if (++len >= MAXNAMELEN) {
- error = ENAMETOOLONG;
- return error;
- }
- }
- }
- }
-
- if (DM_EVENT_ENABLED(dir_vp->v_vfsp, dp, DM_EVENT_SYMLINK)) {
- error = XFS_SEND_NAMESP(mp, DM_EVENT_SYMLINK, dir_vp,
- DM_RIGHT_NULL, NULL, DM_RIGHT_NULL,
- link_name, target_path, 0, 0, 0);
- if (error)
- return error;
- }
-
- /* Return through std_return after this point. */
-
- udqp = gdqp = NULL;
-
-#ifdef XXXKAN
- if (dp->i_d.di_flags & XFS_DIFLAG_PROJINHERIT)
- prid = dp->i_d.di_projid;
- else if (vap->va_mask & XFS_AT_PROJID)
- prid = (xfs_prid_t)vap->va_projid;
- else
-#endif
- prid = (xfs_prid_t)dfltprid;
-
- /*
- * Make sure that we have allocated dquot(s) on disk.
- */
- error = XFS_QM_DQVOPALLOC(mp, dp,
- current->td_ucred->cr_uid,
- current->td_ucred->cr_groups[0],
- prid,
- XFS_QMOPT_QUOTALL | XFS_QMOPT_INHERIT, &udqp, &gdqp);
- if (error)
- goto std_return;
-
- tp = xfs_trans_alloc(mp, XFS_TRANS_SYMLINK);
- cancel_flags = XFS_TRANS_RELEASE_LOG_RES;
- /*
- * The symlink will fit into the inode data fork?
- * There can't be any attributes so we get the whole variable part.
- */
- if (pathlen <= XFS_LITINO(mp))
- fs_blocks = 0;
- else
- fs_blocks = XFS_B_TO_FSB(mp, pathlen);
- resblks = XFS_SYMLINK_SPACE_RES(mp, link_namelen, fs_blocks);
- error = xfs_trans_reserve(tp, resblks, XFS_SYMLINK_LOG_RES(mp), 0,
- XFS_TRANS_PERM_LOG_RES, XFS_SYMLINK_LOG_COUNT);
- if (error == ENOSPC && fs_blocks == 0) {
- resblks = 0;
- error = xfs_trans_reserve(tp, 0, XFS_SYMLINK_LOG_RES(mp), 0,
- XFS_TRANS_PERM_LOG_RES, XFS_SYMLINK_LOG_COUNT);
- }
- if (error) {
- cancel_flags = 0;
- dp = NULL;
- goto error_return;
- }
-
- xfs_ilock(dp, XFS_ILOCK_EXCL);
-
- /*
- * Check whether the directory allows new symlinks or not.
- */
- if (dp->i_d.di_flags & XFS_DIFLAG_NOSYMLINKS) {
- error = XFS_ERROR(EPERM);
- goto error_return;
- }
-
- /*
- * Reserve disk quota : blocks and inode.
- */
- error = XFS_TRANS_RESERVE_QUOTA(mp, tp, udqp, gdqp, resblks, 1, 0);
- if (error)
- goto error_return;
-
- /*
- * Check for ability to enter directory entry, if no space reserved.
- */
- if (resblks == 0 &&
- (error = XFS_DIR_CANENTER(mp, tp, dp, link_name, link_namelen)))
- goto error_return;
- /*
- * Initialize the bmap freelist prior to calling either
- * bmapi or the directory create code.
- */
- XFS_BMAP_INIT(&free_list, &first_block);
-
- /*
- * Allocate an inode for the symlink.
- */
- error = xfs_dir_ialloc(&tp, dp, S_IFLNK | (vap->va_mode&~S_IFMT),
- 1, 0, credp, prid, resblks > 0, &ip, NULL);
- if (error) {
- if (error == ENOSPC)
- goto error_return;
- goto error1;
- }
- ITRACE(ip);
-
- VN_HOLD(dir_vp);
- xfs_trans_ijoin(tp, dp, XFS_ILOCK_EXCL);
- dp_joined_to_trans = B_TRUE;
-
- /*
- * Also attach the dquot(s) to it, if applicable.
- */
- XFS_QM_DQVOPCREATE(mp, tp, ip, udqp, gdqp);
-
- if (resblks)
- resblks -= XFS_IALLOC_SPACE_RES(mp);
- /*
- * If the symlink will fit into the inode, write it inline.
- */
- if (pathlen <= XFS_IFORK_DSIZE(ip)) {
- xfs_idata_realloc(ip, pathlen, XFS_DATA_FORK);
- memcpy(ip->i_df.if_u1.if_data, target_path, pathlen);
- ip->i_d.di_size = pathlen;
-
- /*
- * The inode was initially created in extent format.
- */
- ip->i_df.if_flags &= ~(XFS_IFEXTENTS | XFS_IFBROOT);
- ip->i_df.if_flags |= XFS_IFINLINE;
-
- ip->i_d.di_format = XFS_DINODE_FMT_LOCAL;
- xfs_trans_log_inode(tp, ip, XFS_ILOG_DDATA | XFS_ILOG_CORE);
-
- } else {
- first_fsb = 0;
- nmaps = SYMLINK_MAPS;
-
- error = xfs_bmapi(tp, ip, first_fsb, fs_blocks,
- XFS_BMAPI_WRITE | XFS_BMAPI_METADATA,
- &first_block, resblks, mval, &nmaps,
- &free_list, NULL);
- if (error) {
- goto error1;
- }
-
- if (resblks)
- resblks -= fs_blocks;
- ip->i_d.di_size = pathlen;
- xfs_trans_log_inode(tp, ip, XFS_ILOG_CORE);
-
- cur_chunk = target_path;
- for (n = 0; n < nmaps; n++) {
- d = XFS_FSB_TO_DADDR(mp, mval[n].br_startblock);
- byte_cnt = XFS_FSB_TO_B(mp, mval[n].br_blockcount);
- bp = xfs_trans_get_buf(tp, mp->m_ddev_targp, d,
- BTOBB(byte_cnt), 0);
- ASSERT(bp && !XFS_BUF_GETERROR(bp));
- if (pathlen < byte_cnt) {
- byte_cnt = pathlen;
- }
- pathlen -= byte_cnt;
-
- memcpy(XFS_BUF_PTR(bp), cur_chunk, byte_cnt);
- cur_chunk += byte_cnt;
-
- xfs_trans_log_buf(tp, bp, 0, byte_cnt - 1);
- }
- }
-
- /*
- * Create the directory entry for the symlink.
- */
- error = XFS_DIR_CREATENAME(mp, tp, dp, link_name, link_namelen,
- ip->i_ino, &first_block, &free_list, resblks);
- if (error) {
- goto error1;
- }
- xfs_ichgtime(dp, XFS_ICHGTIME_MOD | XFS_ICHGTIME_CHG);
- xfs_trans_log_inode(tp, dp, XFS_ILOG_CORE);
-
- /*
- * Bump the in memory version number of the parent directory
- * so that other processes accessing it will recognize that
- * the directory has changed.
- */
- dp->i_gen++;
-
- /*
- * If this is a synchronous mount, make sure that the
- * symlink transaction goes to disk before returning to
- * the user.
- */
- if (mp->m_flags & (XFS_MOUNT_WSYNC|XFS_MOUNT_DIRSYNC)) {
- xfs_trans_set_sync(tp);
- }
-
- /*
- * xfs_trans_commit normally decrements the vnode ref count
- * when it unlocks the inode. Since we want to return the
- * vnode to the caller, we bump the vnode ref count now.
- */
- IHOLD(ip);
-
- error = xfs_bmap_finish(&tp, &free_list, first_block, &committed);
- if (error) {
- goto error2;
- }
- error = xfs_trans_commit(tp, XFS_TRANS_RELEASE_LOG_RES, NULL);
- XFS_QM_DQRELE(mp, udqp);
- XFS_QM_DQRELE(mp, gdqp);
-
- /* Fall through to std_return with error = 0 or errno from
- * xfs_trans_commit */
-std_return:
- if (DM_EVENT_ENABLED(dir_vp->v_vfsp, XFS_BHVTOI(dir_bdp),
- DM_EVENT_POSTSYMLINK)) {
- (void) XFS_SEND_NAMESP(mp, DM_EVENT_POSTSYMLINK,
- dir_vp, DM_RIGHT_NULL,
- error ? NULL : XFS_ITOV(ip),
- DM_RIGHT_NULL, link_name, target_path,
- 0, error, 0);
- }
-
- if (!error) {
- xfs_vnode_t *vp;
-
- ASSERT(ip);
- vp = XFS_ITOV(ip);
- *vpp = vp;
- }
- return error;
-
- error2:
- IRELE(ip);
- error1:
- xfs_bmap_cancel(&free_list);
- cancel_flags |= XFS_TRANS_ABORT;
- error_return:
- xfs_trans_cancel(tp, cancel_flags);
- XFS_QM_DQRELE(mp, udqp);
- XFS_QM_DQRELE(mp, gdqp);
-
- if (!dp_joined_to_trans && (dp != NULL)) {
- xfs_iunlock(dp, XFS_ILOCK_EXCL);
- }
-
- goto std_return;
-}
-
-
-/*
- * xfs_fid2
- *
- * A fid routine that takes a pointer to a previously allocated
- * fid structure (like xfs_fast_fid) but uses a 64 bit inode number.
- */
-STATIC int
-xfs_fid2(
- bhv_desc_t *bdp,
- fid_t *fidp)
-{
- xfs_inode_t *ip;
- xfs_fid2_t *xfid;
-
- vn_trace_entry(BHV_TO_VNODE(bdp), __FUNCTION__,
- (inst_t *)__return_address);
- ASSERT(sizeof(xfs_fid_t) >= sizeof(xfs_fid2_t));
-
- xfid = (xfs_fid2_t *)fidp;
- ip = XFS_BHVTOI(bdp);
- xfid->fid_len = sizeof(xfs_fid2_t) - sizeof(xfid->fid_len);
- xfid->fid_pad = 0;
- /*
- * use memcpy because the inode is a long long and there's no
- * assurance that xfid->fid_ino is properly aligned.
- */
- memcpy(&xfid->fid_ino, &ip->i_ino, sizeof(xfid->fid_ino));
- xfid->fid_gen = ip->i_d.di_gen;
-
- return 0;
-}
-
-
-/*
- * xfs_rwlock
- */
-int
-xfs_rwlock(
- bhv_desc_t *bdp,
- vrwlock_t locktype)
-{
- xfs_inode_t *ip;
- xfs_vnode_t *vp;
-
- vp = BHV_TO_VNODE(bdp);
- if (VN_ISDIR(vp))
- return 1;
- ip = XFS_BHVTOI(bdp);
- if (locktype == VRWLOCK_WRITE) {
- xfs_ilock(ip, XFS_IOLOCK_EXCL);
- } else if (locktype == VRWLOCK_TRY_READ) {
- return xfs_ilock_nowait(ip, XFS_IOLOCK_SHARED);
- } else if (locktype == VRWLOCK_TRY_WRITE) {
- return xfs_ilock_nowait(ip, XFS_IOLOCK_EXCL);
- } else {
- ASSERT((locktype == VRWLOCK_READ) ||
- (locktype == VRWLOCK_WRITE_DIRECT));
- xfs_ilock(ip, XFS_IOLOCK_SHARED);
- }
-
- return 1;
-}
-
-
-/*
- * xfs_rwunlock
- */
-void
-xfs_rwunlock(
- bhv_desc_t *bdp,
- vrwlock_t locktype)
-{
- xfs_inode_t *ip;
- xfs_vnode_t *vp;
-
- vp = BHV_TO_VNODE(bdp);
- if (VN_ISDIR(vp))
- return;
- ip = XFS_BHVTOI(bdp);
- if (locktype == VRWLOCK_WRITE) {
- /*
- * In the write case, we may have added a new entry to
- * the reference cache. This might store a pointer to
- * an inode to be released in this inode. If it is there,
- * clear the pointer and release the inode after unlocking
- * this one.
- */
- xfs_refcache_iunlock(ip, XFS_IOLOCK_EXCL);
- } else {
- ASSERT((locktype == VRWLOCK_READ) ||
- (locktype == VRWLOCK_WRITE_DIRECT));
- xfs_iunlock(ip, XFS_IOLOCK_SHARED);
- }
- return;
-}
-
-STATIC int
-xfs_inode_flush(
- bhv_desc_t *bdp,
- int flags)
-{
- xfs_inode_t *ip;
- xfs_mount_t *mp;
- xfs_inode_log_item_t *iip;
- int error = 0;
-
- ip = XFS_BHVTOI(bdp);
- mp = ip->i_mount;
- iip = ip->i_itemp;
-
- if (XFS_FORCED_SHUTDOWN(mp))
- return XFS_ERROR(EIO);
-
- /*
- * Bypass inodes which have already been cleaned by
- * the inode flush clustering code inside xfs_iflush
- */
- if ((ip->i_update_core == 0) &&
- ((iip == NULL) || !(iip->ili_format.ilf_fields & XFS_ILOG_ALL)))
- return 0;
-
- if (flags & FLUSH_LOG) {
- if (iip && iip->ili_last_lsn) {
- xlog_t *log = mp->m_log;
- xfs_lsn_t sync_lsn;
- int s, log_flags = XFS_LOG_FORCE;
-
- s = GRANT_LOCK(log);
- sync_lsn = log->l_last_sync_lsn;
- GRANT_UNLOCK(log, s);
-
- if ((XFS_LSN_CMP(iip->ili_last_lsn, sync_lsn) <= 0))
- return 0;
-
- if (flags & FLUSH_SYNC)
- log_flags |= XFS_LOG_SYNC;
- return xfs_log_force(mp, iip->ili_last_lsn, log_flags);
- }
- }
-
- /*
- * We make this non-blocking if the inode is contended,
- * return EAGAIN to indicate to the caller that they
- * did not succeed. This prevents the flush path from
- * blocking on inodes inside another operation right
- * now, they get caught later by xfs_sync.
- */
- if (flags & FLUSH_INODE) {
- int flush_flags;
-
- if (xfs_ipincount(ip))
- return EAGAIN;
-
- if (flags & FLUSH_SYNC) {
- xfs_ilock(ip, XFS_ILOCK_SHARED);
- xfs_iflock(ip);
- } else if (xfs_ilock_nowait(ip, XFS_ILOCK_SHARED)) {
- if (xfs_ipincount(ip) || !xfs_iflock_nowait(ip)) {
- xfs_iunlock(ip, XFS_ILOCK_SHARED);
- return EAGAIN;
- }
- } else {
- return EAGAIN;
- }
-
- if (flags & FLUSH_SYNC)
- flush_flags = XFS_IFLUSH_SYNC;
- else
- flush_flags = XFS_IFLUSH_ASYNC;
-
- error = xfs_iflush(ip, flush_flags);
- xfs_iunlock(ip, XFS_ILOCK_SHARED);
- }
-
- return error;
-}
-
-
-int
-xfs_set_dmattrs (
- bhv_desc_t *bdp,
- u_int evmask,
- u_int16_t state,
- cred_t *credp)
-{
- xfs_inode_t *ip;
- xfs_trans_t *tp;
- xfs_mount_t *mp;
- int error;
-
- if (!capable(CAP_SYS_ADMIN))
- return XFS_ERROR(EPERM);
-
- ip = XFS_BHVTOI(bdp);
- mp = ip->i_mount;
-
- if (XFS_FORCED_SHUTDOWN(mp))
- return XFS_ERROR(EIO);
-
- tp = xfs_trans_alloc(mp, XFS_TRANS_SET_DMATTRS);
- error = xfs_trans_reserve(tp, 0, XFS_ICHANGE_LOG_RES (mp), 0, 0, 0);
- if (error) {
- xfs_trans_cancel(tp, 0);
- return error;
- }
- xfs_ilock(ip, XFS_ILOCK_EXCL);
- xfs_trans_ijoin(tp, ip, XFS_ILOCK_EXCL);
-
- ip->i_iocore.io_dmevmask = ip->i_d.di_dmevmask = evmask;
- ip->i_iocore.io_dmstate = ip->i_d.di_dmstate = state;
-
- xfs_trans_log_inode(tp, ip, XFS_ILOG_CORE);
- IHOLD(ip);
- error = xfs_trans_commit(tp, 0, NULL);
-
- return error;
-}
-
-
-/*
- * xfs_reclaim
- */
-STATIC int
-xfs_reclaim(
- bhv_desc_t *bdp)
-{
- xfs_inode_t *ip;
- xfs_vnode_t *vp;
-
- vp = BHV_TO_VNODE(bdp);
- ip = XFS_BHVTOI(bdp);
-
- vn_trace_entry(vp, __FUNCTION__, (inst_t *)__return_address);
-
- ASSERT(!VN_MAPPED(vp));
-
- /* bad inode, get out here ASAP */
- if (VN_BAD(vp)) {
- xfs_ireclaim(ip);
- return 0;
- }
-
- vn_iowait(vp);
-
- ASSERT(XFS_FORCED_SHUTDOWN(ip->i_mount) || ip->i_delayed_blks == 0);
-
- /*
- * Make sure the atime in the XFS inode is correct before freeing the
- * Linux inode.
- */
- xfs_synchronize_atime(ip);
-
- vnode_destroy_vobject(vp->v_vnode);
-
- /* If we have nothing to flush with this inode then complete the
- * teardown now, otherwise break the link between the xfs inode
- * and the linux inode and clean up the xfs inode later. This
- * avoids flushing the inode to disk during the delete operation
- * itself.
- */
- if (!ip->i_update_core && (ip->i_itemp == NULL)) {
- xfs_ilock(ip, XFS_ILOCK_EXCL);
- xfs_iflock(ip);
- return xfs_finish_reclaim(ip, 1, XFS_IFLUSH_DELWRI_ELSE_SYNC);
- } else {
- xfs_mount_t *mp = ip->i_mount;
-
- /* Protect sync from us */
- XFS_MOUNT_ILOCK(mp);
- vn_bhv_remove(VN_BHV_HEAD(vp), XFS_ITOBHV(ip));
- TAILQ_INSERT_TAIL(&mp->m_del_inodes, ip, i_reclaim);
- ip->i_flags |= XFS_IRECLAIMABLE;
- XFS_MOUNT_IUNLOCK(mp);
- }
- return 0;
-}
-
-int
-xfs_finish_reclaim(
- xfs_inode_t *ip,
- int locked,
- int sync_mode)
-{
- xfs_ihash_t *ih = ip->i_hash;
- xfs_vnode_t *vp = XFS_ITOV_NULL(ip);
- int error;
-
- if (vp && VN_BAD(vp))
- goto reclaim;
-
- /* The hash lock here protects a thread in xfs_iget_core from
- * racing with us on linking the inode back with a vnode.
- * Once we have the XFS_IRECLAIM flag set it will not touch
- * us.
- */
- write_lock(&ih->ih_lock);
- if ((ip->i_flags & XFS_IRECLAIM) ||
- (!(ip->i_flags & XFS_IRECLAIMABLE) && vp == NULL)) {
- write_unlock(&ih->ih_lock);
- if (locked) {
- xfs_ifunlock(ip);
- xfs_iunlock(ip, XFS_ILOCK_EXCL);
- }
- return 1;
- }
- ip->i_flags |= XFS_IRECLAIM;
- write_unlock(&ih->ih_lock);
-
- /*
- * If the inode is still dirty, then flush it out. If the inode
- * is not in the AIL, then it will be OK to flush it delwri as
- * long as xfs_iflush() does not keep any references to the inode.
- * We leave that decision up to xfs_iflush() since it has the
- * knowledge of whether it's OK to simply do a delwri flush of
- * the inode or whether we need to wait until the inode is
- * pulled from the AIL.
- * We get the flush lock regardless, though, just to make sure
- * we don't free it while it is being flushed.
- */
- if (!XFS_FORCED_SHUTDOWN(ip->i_mount)) {
- if (!locked) {
- xfs_ilock(ip, XFS_ILOCK_EXCL);
- xfs_iflock(ip);
- }
-
- if (ip->i_update_core ||
- ((ip->i_itemp != NULL) &&
- (ip->i_itemp->ili_format.ilf_fields != 0))) {
- error = xfs_iflush(ip, sync_mode);
- /*
- * If we hit an error, typically because of filesystem
- * shutdown, we don't need to let vn_reclaim to know
- * because we're gonna reclaim the inode anyway.
- */
- if (error) {
- xfs_iunlock(ip, XFS_ILOCK_EXCL);
- goto reclaim;
- }
- xfs_iflock(ip); /* synchronize with xfs_iflush_done */
- }
-
- ASSERT(ip->i_update_core == 0);
- ASSERT(ip->i_itemp == NULL ||
- ip->i_itemp->ili_format.ilf_fields == 0);
- xfs_iunlock(ip, XFS_ILOCK_EXCL);
- } else if (locked) {
- /*
- * We are not interested in doing an iflush if we're
- * in the process of shutting down the filesystem forcibly.
- * So, just reclaim the inode.
- */
- xfs_ifunlock(ip);
- xfs_iunlock(ip, XFS_ILOCK_EXCL);
- }
-
- reclaim:
- xfs_ireclaim(ip);
- return 0;
-}
-
-int
-xfs_finish_reclaim_all(xfs_mount_t *mp, int noblock)
-{
-#ifdef RMC
- int purged;
- xfs_inode_t *ip, *n;
- int done = 0;
-
- while (!done) {
- purged = 0;
- XFS_MOUNT_ILOCK(mp);
- TAILQ_FOREACH_SAFE(curr, &mp->m_del_inodes, i_reclaim, next) {
- ip = curr;
- if (noblock) {
- if (xfs_ilock_nowait(ip, XFS_ILOCK_EXCL) == 0)
- continue;
- if (xfs_ipincount(ip) ||
- !xfs_iflock_nowait(ip)) {
- xfs_iunlock(ip, XFS_ILOCK_EXCL);
- continue;
- }
- }
- XFS_MOUNT_IUNLOCK(mp);
- if (xfs_finish_reclaim(ip, noblock,
- XFS_IFLUSH_DELWRI_ELSE_ASYNC))
- delay(1);
- purged = 1;
- break;
- }
-
- done = !purged;
- }
-
- XFS_MOUNT_IUNLOCK(mp);
-#endif
- return 0;
-}
-
-/*
- * xfs_alloc_file_space()
- * This routine allocates disk space for the given file.
- *
- * If alloc_type == 0, this request is for an ALLOCSP type
- * request which will change the file size. In this case, no
- * DMAPI event will be generated by the call. A TRUNCATE event
- * will be generated later by xfs_setattr.
- *
- * If alloc_type != 0, this request is for a RESVSP type
- * request, and a DMAPI DM_EVENT_WRITE will be generated if the
- * lower block boundary byte address is less than the file's
- * length.
- *
- * RETURNS:
- * 0 on success
- * errno on error
- *
- */
-STATIC int
-xfs_alloc_file_space(
- xfs_inode_t *ip,
- xfs_off_t offset,
- xfs_off_t len,
- int alloc_type,
- int attr_flags)
-{
- xfs_mount_t *mp = ip->i_mount;
- xfs_off_t count;
- xfs_filblks_t allocated_fsb;
- xfs_filblks_t allocatesize_fsb;
- xfs_extlen_t extsz, temp;
- xfs_fileoff_t startoffset_fsb;
- xfs_fsblock_t firstfsb;
- int nimaps;
- int bmapi_flag;
- int quota_flag;
- int rt;
- xfs_trans_t *tp;
- xfs_bmbt_irec_t imaps[1], *imapp;
- xfs_bmap_free_t free_list;
- uint qblocks, resblks, resrtextents;
- int committed;
- int error;
-
- vn_trace_entry(XFS_ITOV(ip), __FUNCTION__, (inst_t *)__return_address);
-
- if (XFS_FORCED_SHUTDOWN(mp))
- return XFS_ERROR(EIO);
-
- rt = XFS_IS_REALTIME_INODE(ip);
- if (unlikely(rt)) {
- if (!(extsz = ip->i_d.di_extsize))
- extsz = mp->m_sb.sb_rextsize;
- } else {
- extsz = ip->i_d.di_extsize;
- }
-
- if ((error = XFS_QM_DQATTACH(mp, ip, 0)))
- return error;
-
- if (len <= 0)
- return XFS_ERROR(EINVAL);
-
- count = len;
- error = 0;
- imapp = &imaps[0];
- nimaps = 1;
- bmapi_flag = XFS_BMAPI_WRITE | (alloc_type ? XFS_BMAPI_PREALLOC : 0);
- startoffset_fsb = XFS_B_TO_FSBT(mp, offset);
- allocatesize_fsb = XFS_B_TO_FSB(mp, count);
-
- /* Generate a DMAPI event if needed. */
- if (alloc_type != 0 && offset < ip->i_d.di_size &&
- (attr_flags&ATTR_DMI) == 0 &&
- DM_EVENT_ENABLED(XFS_MTOVFS(mp), ip, DM_EVENT_WRITE)) {
- xfs_off_t end_dmi_offset;
-
- end_dmi_offset = offset+len;
- if (end_dmi_offset > ip->i_d.di_size)
- end_dmi_offset = ip->i_d.di_size;
- error = XFS_SEND_DATA(mp, DM_EVENT_WRITE, XFS_ITOV(ip),
- offset, end_dmi_offset - offset,
- 0, NULL);
- if (error)
- return error;
- }
-
- /*
- * Allocate file space until done or until there is an error
- */
-retry:
- while (allocatesize_fsb && !error) {
- xfs_fileoff_t s, e;
-
- /*
- * Determine space reservations for data/realtime.
- */
- if (unlikely(extsz)) {
- s = startoffset_fsb;
- do_div(s, extsz);
- s *= extsz;
- e = startoffset_fsb + allocatesize_fsb;
- if ((temp = do_mod(startoffset_fsb, extsz)))
- e += temp;
- if ((temp = do_mod(e, extsz)))
- e += extsz - temp;
- } else {
- s = 0;
- e = allocatesize_fsb;
- }
-
- if (unlikely(rt)) {
- resrtextents = qblocks = (uint)(e - s);
- resrtextents /= mp->m_sb.sb_rextsize;
- resblks = XFS_DIOSTRAT_SPACE_RES(mp, 0);
- quota_flag = XFS_QMOPT_RES_RTBLKS;
- } else {
- resrtextents = 0;
- resblks = qblocks = \
- XFS_DIOSTRAT_SPACE_RES(mp, (uint)(e - s));
- quota_flag = XFS_QMOPT_RES_REGBLKS;
- }
-
- /*
- * Allocate and setup the transaction.
- */
- tp = xfs_trans_alloc(mp, XFS_TRANS_DIOSTRAT);
- error = xfs_trans_reserve(tp, resblks,
- XFS_WRITE_LOG_RES(mp), resrtextents,
- XFS_TRANS_PERM_LOG_RES,
- XFS_WRITE_LOG_COUNT);
- /*
- * Check for running out of space
- */
- if (error) {
- /*
- * Free the transaction structure.
- */
- ASSERT(error == ENOSPC || XFS_FORCED_SHUTDOWN(mp));
- xfs_trans_cancel(tp, 0);
- break;
- }
- xfs_ilock(ip, XFS_ILOCK_EXCL);
- error = XFS_TRANS_RESERVE_QUOTA_NBLKS(mp, tp, ip,
- qblocks, 0, quota_flag);
- if (error)
- goto error1;
-
- xfs_trans_ijoin(tp, ip, XFS_ILOCK_EXCL);
- xfs_trans_ihold(tp, ip);
-
- /*
- * Issue the xfs_bmapi() call to allocate the blocks
- */
- XFS_BMAP_INIT(&free_list, &firstfsb);
- error = XFS_BMAPI(mp, tp, &ip->i_iocore, startoffset_fsb,
- allocatesize_fsb, bmapi_flag,
- &firstfsb, 0, imapp, &nimaps,
- &free_list, NULL);
- if (error) {
- goto error0;
- }
-
- /*
- * Complete the transaction
- */
- error = xfs_bmap_finish(&tp, &free_list, firstfsb, &committed);
- if (error) {
- goto error0;
- }
-
- error = xfs_trans_commit(tp, XFS_TRANS_RELEASE_LOG_RES, NULL);
- xfs_iunlock(ip, XFS_ILOCK_EXCL);
- if (error) {
- break;
- }
-
- allocated_fsb = imapp->br_blockcount;
-
- if (nimaps == 0) {
- error = XFS_ERROR(ENOSPC);
- break;
- }
-
- startoffset_fsb += allocated_fsb;
- allocatesize_fsb -= allocated_fsb;
- }
-dmapi_enospc_check:
- if (error == ENOSPC && (attr_flags&ATTR_DMI) == 0 &&
- DM_EVENT_ENABLED(XFS_MTOVFS(mp), ip, DM_EVENT_NOSPACE)) {
-
- error = XFS_SEND_NAMESP(mp, DM_EVENT_NOSPACE,
- XFS_ITOV(ip), DM_RIGHT_NULL,
- XFS_ITOV(ip), DM_RIGHT_NULL,
- NULL, NULL, 0, 0, 0); /* Delay flag intentionally unused */
- if (error == 0)
- goto retry; /* Maybe DMAPI app. has made space */
- /* else fall through with error from XFS_SEND_DATA */
- }
-
- return error;
-
-error0: /* Cancel bmap, unlock inode, unreserve quota blocks, cancel trans */
- xfs_bmap_cancel(&free_list);
- XFS_TRANS_UNRESERVE_QUOTA_NBLKS(mp, tp, ip, qblocks, 0, quota_flag);
-
-error1: /* Just cancel transaction */
- xfs_trans_cancel(tp, XFS_TRANS_RELEASE_LOG_RES | XFS_TRANS_ABORT);
- xfs_iunlock(ip, XFS_ILOCK_EXCL);
- goto dmapi_enospc_check;
-}
-
-/*
- * Zero file bytes between startoff and endoff inclusive.
- * The iolock is held exclusive and no blocks are buffered.
- */
-STATIC int
-xfs_zero_remaining_bytes(
- xfs_inode_t *ip,
- xfs_off_t startoff,
- xfs_off_t endoff)
-{
- xfs_bmbt_irec_t imap;
- xfs_fileoff_t offset_fsb;
- xfs_off_t lastoffset;
- xfs_off_t offset;
- xfs_buf_t *bp;
- xfs_mount_t *mp = ip->i_mount;
- int nimap;
- int error = 0;
-
- bp = xfs_buf_get_noaddr(mp->m_sb.sb_blocksize,
- ip->i_d.di_flags & XFS_DIFLAG_REALTIME ?
- mp->m_rtdev_targp : mp->m_ddev_targp);
-
- for (offset = startoff; offset <= endoff; offset = lastoffset + 1) {
- offset_fsb = XFS_B_TO_FSBT(mp, offset);
- nimap = 1;
- error = XFS_BMAPI(mp, NULL, &ip->i_iocore, offset_fsb, 1, 0,
- NULL, 0, &imap, &nimap, NULL, NULL);
- if (error || nimap < 1)
- break;
- ASSERT(imap.br_blockcount >= 1);
- ASSERT(imap.br_startoff == offset_fsb);
- lastoffset = XFS_FSB_TO_B(mp, imap.br_startoff + 1) - 1;
- if (lastoffset > endoff)
- lastoffset = endoff;
- if (imap.br_startblock == HOLESTARTBLOCK)
- continue;
- ASSERT(imap.br_startblock != DELAYSTARTBLOCK);
- if (imap.br_state == XFS_EXT_UNWRITTEN)
- continue;
- XFS_BUF_UNDONE(bp);
- XFS_BUF_UNWRITE(bp);
- XFS_BUF_READ(bp);
- XFS_BUF_SET_ADDR(bp, XFS_FSB_TO_DB(ip, imap.br_startblock));
- xfsbdstrat(mp, bp);
- if ((error = xfs_iowait(bp))) {
- xfs_ioerror_alert("xfs_zero_remaining_bytes(read)",
- mp, bp, XFS_BUF_ADDR(bp));
- break;
- }
- memset(XFS_BUF_PTR(bp) +
- (offset - XFS_FSB_TO_B(mp, imap.br_startoff)),
- 0, lastoffset - offset + 1);
- XFS_BUF_UNDONE(bp);
- XFS_BUF_UNREAD(bp);
- XFS_BUF_WRITE(bp);
- xfsbdstrat(mp, bp);
- if ((error = xfs_iowait(bp))) {
- xfs_ioerror_alert("xfs_zero_remaining_bytes(write)",
- mp, bp, XFS_BUF_ADDR(bp));
- break;
- }
- }
- xfs_buf_free(bp);
- return error;
-}
-
-/*
- * xfs_free_file_space()
- * This routine frees disk space for the given file.
- *
- * This routine is only called by xfs_change_file_space
- * for an UNRESVSP type call.
- *
- * RETURNS:
- * 0 on success
- * errno on error
- *
- */
-STATIC int
-xfs_free_file_space(
- xfs_inode_t *ip,
- xfs_off_t offset,
- xfs_off_t len,
- int attr_flags)
-{
- xfs_vnode_t *vp;
- int committed;
- int done;
- xfs_off_t end_dmi_offset;
- xfs_fileoff_t endoffset_fsb;
- int error;
- xfs_fsblock_t firstfsb;
- xfs_bmap_free_t free_list;
- xfs_off_t ilen;
- xfs_bmbt_irec_t imap;
- xfs_off_t ioffset;
- xfs_extlen_t mod=0;
- xfs_mount_t *mp;
- int nimap;
- uint resblks;
- int rounding;
- int rt;
- xfs_fileoff_t startoffset_fsb;
- xfs_trans_t *tp;
- int need_iolock = 1;
-
- vp = XFS_ITOV(ip);
- mp = ip->i_mount;
-
- vn_trace_entry(vp, __FUNCTION__, (inst_t *)__return_address);
-
- if ((error = XFS_QM_DQATTACH(mp, ip, 0)))
- return error;
-
- error = 0;
- if (len <= 0) /* if nothing being freed */
- return error;
- rt = (ip->i_d.di_flags & XFS_DIFLAG_REALTIME);
- startoffset_fsb = XFS_B_TO_FSB(mp, offset);
- end_dmi_offset = offset + len;
- endoffset_fsb = XFS_B_TO_FSBT(mp, end_dmi_offset);
-
- if (offset < ip->i_d.di_size &&
- (attr_flags & ATTR_DMI) == 0 &&
- DM_EVENT_ENABLED(XFS_MTOVFS(mp), ip, DM_EVENT_WRITE)) {
- if (end_dmi_offset > ip->i_d.di_size)
- end_dmi_offset = ip->i_d.di_size;
- error = XFS_SEND_DATA(mp, DM_EVENT_WRITE, vp,
- offset, end_dmi_offset - offset,
- AT_DELAY_FLAG(attr_flags), NULL);
- if (error)
- return error;
- }
-
- ASSERT(attr_flags & ATTR_NOLOCK ? attr_flags & ATTR_DMI : 1);
- if (attr_flags & ATTR_NOLOCK)
- need_iolock = 0;
- if (need_iolock) {
- xfs_ilock(ip, XFS_IOLOCK_EXCL);
- vn_iowait(vp); /* wait for the completion of any pending DIOs */
- }
-
- rounding = MAX((__uint8_t)(1 << mp->m_sb.sb_blocklog),
- (__uint8_t)NBPP);
- ilen = len + (offset & (rounding - 1));
- ioffset = offset & ~(rounding - 1);
- if (ilen & (rounding - 1))
- ilen = (ilen + rounding) & ~(rounding - 1);
-
- if (VN_CACHED(vp) != 0) {
- xfs_inval_cached_trace(&ip->i_iocore, ioffset, -1,
- ctooff(offtoct(ioffset)), -1);
- XVOP_FLUSHINVAL_PAGES(vp, ctooff(offtoct(ioffset)),
- -1, FI_REMAPF_LOCKED);
- }
-
- /*
- * Need to zero the stuff we're not freeing, on disk.
- * If its a realtime file & can't use unwritten extents then we
- * actually need to zero the extent edges. Otherwise xfs_bunmapi
- * will take care of it for us.
- */
- if (rt && !XFS_SB_VERSION_HASEXTFLGBIT(&mp->m_sb)) {
- nimap = 1;
- error = XFS_BMAPI(mp, NULL, &ip->i_iocore, startoffset_fsb,
- 1, 0, NULL, 0, &imap, &nimap, NULL, NULL);
- if (error)
- goto out_unlock_iolock;
- ASSERT(nimap == 0 || nimap == 1);
- if (nimap && imap.br_startblock != HOLESTARTBLOCK) {
- xfs_daddr_t block;
-
- ASSERT(imap.br_startblock != DELAYSTARTBLOCK);
- block = imap.br_startblock;
- mod = do_div(block, mp->m_sb.sb_rextsize);
- if (mod)
- startoffset_fsb += mp->m_sb.sb_rextsize - mod;
- }
- nimap = 1;
- error = XFS_BMAPI(mp, NULL, &ip->i_iocore, endoffset_fsb - 1,
- 1, 0, NULL, 0, &imap, &nimap, NULL, NULL);
- if (error)
- goto out_unlock_iolock;
- ASSERT(nimap == 0 || nimap == 1);
- if (nimap && imap.br_startblock != HOLESTARTBLOCK) {
- ASSERT(imap.br_startblock != DELAYSTARTBLOCK);
- mod++;
- if (mod && (mod != mp->m_sb.sb_rextsize))
- endoffset_fsb -= mod;
- }
- }
- if ((done = (endoffset_fsb <= startoffset_fsb)))
- /*
- * One contiguous piece to clear
- */
- error = xfs_zero_remaining_bytes(ip, offset, offset + len - 1);
- else {
- /*
- * Some full blocks, possibly two pieces to clear
- */
- if (offset < XFS_FSB_TO_B(mp, startoffset_fsb))
- error = xfs_zero_remaining_bytes(ip, offset,
- XFS_FSB_TO_B(mp, startoffset_fsb) - 1);
- if (!error &&
- XFS_FSB_TO_B(mp, endoffset_fsb) < offset + len)
- error = xfs_zero_remaining_bytes(ip,
- XFS_FSB_TO_B(mp, endoffset_fsb),
- offset + len - 1);
- }
-
- /*
- * free file space until done or until there is an error
- */
- resblks = XFS_DIOSTRAT_SPACE_RES(mp, 0);
- while (!error && !done) {
-
- /*
- * allocate and setup the transaction
- */
- tp = xfs_trans_alloc(mp, XFS_TRANS_DIOSTRAT);
- error = xfs_trans_reserve(tp,
- resblks,
- XFS_WRITE_LOG_RES(mp),
- 0,
- XFS_TRANS_PERM_LOG_RES,
- XFS_WRITE_LOG_COUNT);
-
- /*
- * check for running out of space
- */
- if (error) {
- /*
- * Free the transaction structure.
- */
- ASSERT(error == ENOSPC || XFS_FORCED_SHUTDOWN(mp));
- xfs_trans_cancel(tp, 0);
- break;
- }
- xfs_ilock(ip, XFS_ILOCK_EXCL);
- error = XFS_TRANS_RESERVE_QUOTA(mp, tp,
- ip->i_udquot, ip->i_gdquot, resblks, 0,
- XFS_QMOPT_RES_REGBLKS);
- if (error)
- goto error1;
-
- xfs_trans_ijoin(tp, ip, XFS_ILOCK_EXCL);
- xfs_trans_ihold(tp, ip);
-
- /*
- * issue the bunmapi() call to free the blocks
- */
- XFS_BMAP_INIT(&free_list, &firstfsb);
- error = XFS_BUNMAPI(mp, tp, &ip->i_iocore, startoffset_fsb,
- endoffset_fsb - startoffset_fsb,
- 0, 2, &firstfsb, &free_list, NULL, &done);
- if (error) {
- goto error0;
- }
-
- /*
- * complete the transaction
- */
- error = xfs_bmap_finish(&tp, &free_list, firstfsb, &committed);
- if (error) {
- goto error0;
- }
-
- error = xfs_trans_commit(tp, XFS_TRANS_RELEASE_LOG_RES, NULL);
- xfs_iunlock(ip, XFS_ILOCK_EXCL);
- }
-
- out_unlock_iolock:
- if (need_iolock)
- xfs_iunlock(ip, XFS_IOLOCK_EXCL);
- return error;
-
- error0:
- xfs_bmap_cancel(&free_list);
- error1:
- xfs_trans_cancel(tp, XFS_TRANS_RELEASE_LOG_RES | XFS_TRANS_ABORT);
- xfs_iunlock(ip, need_iolock ? (XFS_ILOCK_EXCL | XFS_IOLOCK_EXCL) :
- XFS_ILOCK_EXCL);
- return error;
-}
-
-/*
- * xfs_change_file_space()
- * This routine allocates or frees disk space for the given file.
- * The user specified parameters are checked for alignment and size
- * limitations.
- *
- * RETURNS:
- * 0 on success
- * errno on error
- *
- */
-int
-xfs_change_file_space(
- bhv_desc_t *bdp,
- u_long cmd,
- xfs_flock64_t *bf,
- xfs_off_t offset,
- cred_t *credp,
- int attr_flags)
-{
- int clrprealloc;
- int error;
- xfs_fsize_t fsize;
- xfs_inode_t *ip;
- xfs_mount_t *mp;
- int setprealloc;
- xfs_off_t startoffset;
- xfs_off_t llen;
- xfs_trans_t *tp;
- xfs_vattr_t va;
- xfs_vnode_t *vp;
-
- vp = BHV_TO_VNODE(bdp);
- vn_trace_entry(vp, __FUNCTION__, (inst_t *)__return_address);
-
- ip = XFS_BHVTOI(bdp);
- mp = ip->i_mount;
-
- /*
- * must be a regular file and have write permission
- */
- if (!VN_ISREG(vp))
- return XFS_ERROR(EINVAL);
-
- xfs_ilock(ip, XFS_ILOCK_SHARED);
-
- if ((error = xfs_iaccess(ip, VWRITE, credp))) {
- xfs_iunlock(ip, XFS_ILOCK_SHARED);
- return error;
- }
-
- xfs_iunlock(ip, XFS_ILOCK_SHARED);
-
- switch (bf->l_whence) {
- case 0: /*SEEK_SET*/
- break;
- case 1: /*SEEK_CUR*/
- bf->l_start += offset;
- break;
- case 2: /*SEEK_END*/
- bf->l_start += ip->i_d.di_size;
- break;
- default:
- return XFS_ERROR(EINVAL);
- }
-
- llen = bf->l_len > 0 ? bf->l_len - 1 : bf->l_len;
-
- if ( (bf->l_start < 0)
- || (bf->l_start > XFS_MAXIOFFSET(mp))
- || (bf->l_start + llen < 0)
- || (bf->l_start + llen > XFS_MAXIOFFSET(mp)))
- return XFS_ERROR(EINVAL);
-
- bf->l_whence = 0;
-
- startoffset = bf->l_start;
- fsize = ip->i_d.di_size;
-
- /*
- * XFS_IOC_RESVSP and XFS_IOC_UNRESVSP will reserve or unreserve
- * file space.
- * These calls do NOT zero the data space allocated to the file,
- * nor do they change the file size.
- *
- * XFS_IOC_ALLOCSP and XFS_IOC_FREESP will allocate and free file
- * space.
- * These calls cause the new file data to be zeroed and the file
- * size to be changed.
- */
- setprealloc = clrprealloc = 0;
-
- switch (cmd) {
- case XFS_IOC_RESVSP:
- case XFS_IOC_RESVSP64:
- error = xfs_alloc_file_space(ip, startoffset, bf->l_len,
- 1, attr_flags);
- if (error)
- return error;
- setprealloc = 1;
- break;
-
- case XFS_IOC_UNRESVSP:
- case XFS_IOC_UNRESVSP64:
- if ((error = xfs_free_file_space(ip, startoffset, bf->l_len,
- attr_flags)))
- return error;
- break;
-
- case XFS_IOC_ALLOCSP:
- case XFS_IOC_ALLOCSP64:
- case XFS_IOC_FREESP:
- case XFS_IOC_FREESP64:
- if (startoffset > fsize) {
- error = xfs_alloc_file_space(ip, fsize,
- startoffset - fsize, 0, attr_flags);
- if (error)
- break;
- }
-
- va.va_mask = XFS_AT_SIZE;
- va.va_size = startoffset;
-
- error = xfs_setattr(bdp, &va, attr_flags, credp);
-
- if (error)
- return error;
-
- clrprealloc = 1;
- break;
-
- default:
- ASSERT(0);
- return XFS_ERROR(EINVAL);
- }
-
- /*
- * update the inode timestamp, mode, and prealloc flag bits
- */
- tp = xfs_trans_alloc(mp, XFS_TRANS_WRITEID);
-
- if ((error = xfs_trans_reserve(tp, 0, XFS_WRITEID_LOG_RES(mp),
- 0, 0, 0))) {
- /* ASSERT(0); */
- xfs_trans_cancel(tp, 0);
- return error;
- }
-
- xfs_ilock(ip, XFS_ILOCK_EXCL);
-
- xfs_trans_ijoin(tp, ip, XFS_ILOCK_EXCL);
- xfs_trans_ihold(tp, ip);
-
- if ((attr_flags & ATTR_DMI) == 0) {
- ip->i_d.di_mode &= ~S_ISUID;
-
- /*
- * Note that we don't have to worry about mandatory
- * file locking being disabled here because we only
- * clear the S_ISGID bit if the Group execute bit is
- * on, but if it was on then mandatory locking wouldn't
- * have been enabled.
- */
- if (ip->i_d.di_mode & S_IXGRP)
- ip->i_d.di_mode &= ~S_ISGID;
-
- xfs_ichgtime(ip, XFS_ICHGTIME_MOD | XFS_ICHGTIME_CHG);
- }
- if (setprealloc)
- ip->i_d.di_flags |= XFS_DIFLAG_PREALLOC;
- else if (clrprealloc)
- ip->i_d.di_flags &= ~XFS_DIFLAG_PREALLOC;
-
- xfs_trans_log_inode(tp, ip, XFS_ILOG_CORE);
- xfs_trans_set_sync(tp);
-
- error = xfs_trans_commit(tp, 0, NULL);
-
- xfs_iunlock(ip, XFS_ILOCK_EXCL);
-
- return error;
-}
-
-
-xfs_vnodeops_t xfs_vnodeops = {
- BHV_IDENTITY_INIT(VN_BHV_XFS,VNODE_POSITION_XFS),
- .vop_open = xfs_open,
- .vop_read = xfs_read,
-#ifdef HAVE_SENDFILE
- .vop_sendfile = xfs_sendfile,
-#endif
- .vop_write = xfs_write,
- .vop_ioctl = xfs_ioctl,
- .vop_getattr = xfs_getattr,
- .vop_setattr = xfs_setattr,
- .vop_access = xfs_access,
- .vop_lookup = xfs_lookup,
- .vop_create = xfs_create,
- .vop_remove = xfs_remove,
- .vop_link = xfs_link,
- .vop_rename = xfs_rename,
- .vop_mkdir = xfs_mkdir,
- .vop_rmdir = xfs_rmdir,
- .vop_readdir = xfs_readdir,
- .vop_symlink = xfs_symlink,
- .vop_readlink = xfs_readlink,
- .vop_fsync = xfs_fsync,
- .vop_inactive = xfs_inactive,
- .vop_fid2 = xfs_fid2,
- .vop_rwlock = xfs_rwlock,
- .vop_rwunlock = xfs_rwunlock,
- .vop_bmap = xfs_bmap,
- .vop_reclaim = xfs_reclaim,
- .vop_attr_get = xfs_attr_get,
- .vop_attr_set = xfs_attr_set,
- .vop_attr_remove = xfs_attr_remove,
- .vop_attr_list = xfs_attr_list,
- .vop_link_removed = (xfs_vop_link_removed_t)fs_noval,
- .vop_vnode_change = (xfs_vop_vnode_change_t)fs_noval,
- .vop_tosspages = fs_tosspages,
- .vop_flushinval_pages = fs_flushinval_pages,
- .vop_flush_pages = fs_flush_pages,
- .vop_release = xfs_release,
- .vop_iflush = xfs_inode_flush,
-};
diff --git a/sys/gnu/fs/xfs/xfsidbg.c b/sys/gnu/fs/xfs/xfsidbg.c
deleted file mode 100644
index e0fc2f6..0000000
--- a/sys/gnu/fs/xfs/xfsidbg.c
+++ /dev/null
@@ -1,7769 +0,0 @@
-/*
- * Copyright (c) 2000-2005 Silicon Graphics, Inc.
- * All Rights Reserved.
- *
- * 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.
- *
- * This program is distributed in the hope that it would 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 the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- */
-#include "xfs.h"
-
-#include "xfs_fs.h"
-#include "xfs_types.h"
-#include "xfs_bit.h"
-#include "xfs_log.h"
-#include "xfs_inum.h"
-#include "xfs_trans.h"
-#include "xfs_sb.h"
-#include "xfs_ag.h"
-#include "xfs_dir.h"
-#include "xfs_dir2.h"
-#include "xfs_dmapi.h"
-#include "xfs_mount.h"
-#include "xfs_alloc.h"
-#include "xfs_da_btree.h"
-#include "xfs_alloc_btree.h"
-#include "xfs_bmap_btree.h"
-#include "xfs_ialloc_btree.h"
-#include "xfs_dir_sf.h"
-#include "xfs_dir2_sf.h"
-#include "xfs_attr_sf.h"
-#include "xfs_dinode.h"
-#include "xfs_inode.h"
-#include "xfs_btree.h"
-#include "xfs_buf_item.h"
-#include "xfs_inode_item.h"
-#include "xfs_extfree_item.h"
-#include "xfs_rw.h"
-#include "xfs_bmap.h"
-#include "xfs_attr.h"
-#include "xfs_attr_leaf.h"
-#include "xfs_dir_leaf.h"
-#include "xfs_dir2_data.h"
-#include "xfs_dir2_leaf.h"
-#include "xfs_dir2_block.h"
-#include "xfs_dir2_node.h"
-#include "xfs_dir2_trace.h"
-#include "xfs_log_priv.h"
-#include "xfs_log_recover.h"
-#include "xfs_quota.h"
-#include "quota/xfs_qm.h"
-#include "xfs_iomap.h"
-
-#include <support/kdb.h>
-
-#define qprintf kdb_printf
-
-/*
- * Command table functions. (tracing)
- */
-#ifdef XFS_ALLOC_TRACE
-static void xfsidbg_xalatrace(int);
-static void xfsidbg_xalbtrace(xfs_agblock_t);
-static void xfsidbg_xalgtrace(xfs_agnumber_t);
-static void xfsidbg_xalmtrace(xfs_mount_t *);
-static void xfsidbg_xalttrace(int);
-#endif
-#ifdef XFS_ATTR_TRACE
-static void xfsidbg_xattrtrace(int);
-#endif
-#ifdef XFS_BLI_TRACE
-static void xfsidbg_xblitrace(xfs_buf_log_item_t *);
-#endif
-#ifdef XFS_BMAP_TRACE
-static void xfsidbg_xbmatrace(int);
-static void xfsidbg_xbmitrace(xfs_inode_t *);
-static void xfsidbg_xbmstrace(xfs_inode_t *);
-static void xfsidbg_xbxatrace(int);
-static void xfsidbg_xbxitrace(xfs_inode_t *);
-static void xfsidbg_xbxstrace(xfs_inode_t *);
-#endif
-#ifdef XFS_ILOCK_TRACE
-static void xfsidbg_xilock_trace(xfs_inode_t *);
-static void xfsidbg_xailock_trace(int);
-#endif
-#ifdef XFS_DIR_TRACE
-static void xfsidbg_xdirtrace(int);
-#endif
-#ifdef XFS_DIR2_TRACE
-static void xfsidbg_xdir2atrace(int);
-static void xfsidbg_xdir2itrace(xfs_inode_t *);
-#endif
-#ifdef XFS_LOG_TRACE
-static void xfsidbg_xiclogtrace(xlog_in_core_t *);
-static void xfsidbg_xlog_granttrace(xlog_t *);
-#endif
-#ifdef XFS_DQUOT_TRACE
-static void xfsidbg_xqm_dqtrace(xfs_dquot_t *);
-#endif
-
-
-/*
- * Command table functions.
- */
-static void xfsidbg_xagf(xfs_agf_t *);
-static void xfsidbg_xagi(xfs_agi_t *);
-static void xfsidbg_xaildump(xfs_mount_t *);
-static void xfsidbg_xalloc(xfs_alloc_arg_t *);
-static void xfsidbg_xattrcontext(xfs_attr_list_context_t *);
-static void xfsidbg_xattrleaf(xfs_attr_leafblock_t *);
-static void xfsidbg_xattrsf(xfs_attr_shortform_t *);
-static void xfsidbg_xbirec(xfs_bmbt_irec_t *r);
-static void xfsidbg_xbmalla(xfs_bmalloca_t *);
-static void xfsidbg_xbrec(xfs_bmbt_rec_64_t *);
-static void xfsidbg_xbroot(xfs_inode_t *);
-static void xfsidbg_xbroota(xfs_inode_t *);
-static void xfsidbg_xbtcur(xfs_btree_cur_t *);
-static void xfsidbg_xbuf(xfs_buf_t *);
-static void xfsidbg_xbuf_real(xfs_buf_t *, int);
-static void xfsidbg_xarg(int);
-static void xfsidbg_xchksum(uint *);
-static void xfsidbg_xchash(xfs_mount_t *mp);
-static void xfsidbg_xchashlist(xfs_chashlist_t *chl);
-static void xfsidbg_xdaargs(xfs_da_args_t *);
-static void xfsidbg_xdabuf(xfs_dabuf_t *);
-static void xfsidbg_xdanode(xfs_da_intnode_t *);
-static void xfsidbg_xdastate(xfs_da_state_t *);
-static void xfsidbg_xdirleaf(xfs_dir_leafblock_t *);
-static void xfsidbg_xdirsf(xfs_dir_shortform_t *);
-static void xfsidbg_xdir2free(xfs_dir2_free_t *);
-static void xfsidbg_xdir2sf(xfs_dir2_sf_t *);
-static void xfsidbg_xexlist(xfs_inode_t *);
-static void xfsidbg_xflist(xfs_bmap_free_t *);
-static void xfsidbg_xhelp(void);
-static void xfsidbg_xiclog(xlog_in_core_t *);
-static void xfsidbg_xiclogall(xlog_in_core_t *);
-static void xfsidbg_xiclogcb(xlog_in_core_t *);
-static void xfsidbg_xihash(xfs_mount_t *mp);
-static void xfsidbg_xinodes(xfs_mount_t *);
-static void xfsidbg_delayed_blocks(xfs_mount_t *);
-static void xfsidbg_xinodes_quiesce(xfs_mount_t *);
-static void xfsidbg_xlog(xlog_t *);
-static void xfsidbg_xlog_ritem(xlog_recover_item_t *);
-static void xfsidbg_xlog_rtrans(xlog_recover_t *);
-static void xfsidbg_xlog_rtrans_entire(xlog_recover_t *);
-static void xfsidbg_xlog_tic(xlog_ticket_t *);
-static void xfsidbg_xlogitem(xfs_log_item_t *);
-static void xfsidbg_xmount(xfs_mount_t *);
-static void xfsidbg_xnode(xfs_inode_t *ip);
-static void xfsidbg_xcore(xfs_iocore_t *io);
-static void xfsidbg_xperag(xfs_mount_t *);
-static void xfsidbg_xqm_diskdq(xfs_disk_dquot_t *);
-static void xfsidbg_xqm_dqattached_inos(xfs_mount_t *);
-static void xfsidbg_xqm_dquot(xfs_dquot_t *);
-static void xfsidbg_xqm_mplist(xfs_mount_t *);
-static void xfsidbg_xqm_qinfo(xfs_mount_t *mp);
-static void xfsidbg_xqm_tpdqinfo(xfs_trans_t *tp);
-static void xfsidbg_xsb(xfs_sb_t *);
-static void xfsidbg_xsb_convert(xfs_sb_t *);
-static void xfsidbg_xtp(xfs_trans_t *);
-static void xfsidbg_xtrans_res(xfs_mount_t *);
-#ifdef CONFIG_XFS_QUOTA
-static void xfsidbg_xqm(void);
-static void xfsidbg_xqm_htab(void);
-static void xfsidbg_xqm_freelist_print(xfs_frlist_t *qlist, char *title);
-static void xfsidbg_xqm_freelist(void);
-#endif
-
-#ifdef XFS_BMAP_TRACE
-static void xfs_convert_extent(xfs_bmbt_rec_32_t *, xfs_dfiloff_t *,
- xfs_dfsbno_t *, xfs_dfilblks_t *, int *);
-#endif
-
-/*
- * Prototypes for static functions.
- */
-#ifdef XFS_ALLOC_TRACE
-static int xfs_alloc_trace_entry(ktrace_entry_t *ktep);
-#endif
-#ifdef XFS_ATTR_TRACE
-static int xfs_attr_trace_entry(ktrace_entry_t *ktep);
-#endif
-#ifdef XFS_BMAP_TRACE
-static int xfs_bmap_trace_entry(ktrace_entry_t *ktep);
-#endif
-#ifdef XFS_BMAP_TRACE
-static int xfs_bmbt_trace_entry(ktrace_entry_t *ktep);
-#endif
-#ifdef XFS_DIR_TRACE
-static int xfs_dir_trace_entry(ktrace_entry_t *ktep);
-#endif
-#ifdef XFS_DIR2_TRACE
-static int xfs_dir2_trace_entry(ktrace_entry_t *ktep);
-#endif
-#ifdef XFS_RW_TRACE
-static void xfs_bunmap_trace_entry(ktrace_entry_t *ktep);
-static void xfs_rw_enter_trace_entry(ktrace_entry_t *ktep);
-static void xfs_page_trace_entry(ktrace_entry_t *ktep);
-static int xfs_rw_trace_entry(ktrace_entry_t *ktep);
-#endif
-static void xfs_broot(xfs_inode_t *ip, xfs_ifork_t *f);
-static void xfs_btalloc(xfs_alloc_block_t *bt, int bsz);
-static void xfs_btbmap(xfs_bmbt_block_t *bt, int bsz);
-static void xfs_btino(xfs_inobt_block_t *bt, int bsz);
-static void xfs_buf_item_print(xfs_buf_log_item_t *blip, int summary);
-static void xfs_dastate_path(xfs_da_state_path_t *p);
-static void xfs_dir2data(void *addr, int size);
-static void xfs_dir2leaf(xfs_dir2_leaf_t *leaf, int size);
-static void xfs_dquot_item_print(xfs_dq_logitem_t *lip, int summary);
-static void xfs_efd_item_print(xfs_efd_log_item_t *efdp, int summary);
-static void xfs_efi_item_print(xfs_efi_log_item_t *efip, int summary);
-static char * xfs_fmtformat(xfs_dinode_fmt_t f);
-char * xfs_fmtfsblock(xfs_fsblock_t bno, xfs_mount_t *mp);
-static char * xfs_fmtino(xfs_ino_t ino, xfs_mount_t *mp);
-static char * xfs_fmtlsn(xfs_lsn_t *lsnp);
-static char * xfs_fmtmode(int m);
-static char * xfs_fmtsize(size_t i);
-static char * xfs_fmtuuid(uuid_t *);
-static void xfs_inode_item_print(xfs_inode_log_item_t *ilip, int summary);
-static void xfs_inodebuf(xfs_buf_t *bp);
-static void xfs_prdinode_core(xfs_dinode_core_t *dip);
-static void xfs_qoff_item_print(xfs_qoff_logitem_t *lip, int summary);
-static void xfs_xexlist_fork(xfs_inode_t *ip, int whichfork);
-static void xfs_xnode_fork(char *name, xfs_ifork_t *f);
-
-
-/* kdb wrappers */
-
-static int kdbm_xfs_xagf(
- int argc,
- const char **argv,
- const char **envp,
- struct pt_regs *regs)
-{
- unsigned long addr;
- int nextarg = 1;
- long offset = 0;
- int diag;
-
- if (argc != 1)
- return KDB_ARGCOUNT;
- diag = kdbgetaddrarg(argc, argv, &nextarg, &addr, &offset, NULL, regs);
- if (diag)
- return diag;
-
- xfsidbg_xagf((xfs_agf_t *)addr);
- return 0;
-}
-
-static int kdbm_xfs_xagi(
- int argc,
- const char **argv,
- const char **envp,
- struct pt_regs *regs)
-{
- unsigned long addr;
- int nextarg = 1;
- long offset = 0;
- int diag;
-
- if (argc != 1)
- return KDB_ARGCOUNT;
- diag = kdbgetaddrarg(argc, argv, &nextarg, &addr, &offset, NULL, regs);
- if (diag)
- return diag;
-
- xfsidbg_xagi((xfs_agi_t *)addr);
- return 0;
-}
-
-static int kdbm_xfs_xaildump(
- int argc,
- const char **argv,
- const char **envp,
- struct pt_regs *regs)
-{
- unsigned long addr;
- int nextarg = 1;
- long offset = 0;
- int diag;
-
- if (argc != 1)
- return KDB_ARGCOUNT;
- diag = kdbgetaddrarg(argc, argv, &nextarg, &addr, &offset, NULL, regs);
- if (diag)
- return diag;
-
- xfsidbg_xaildump((xfs_mount_t *) addr);
- return 0;
-}
-
-#ifdef XFS_ALLOC_TRACE
-static int kdbm_xfs_xalatrace(
- int argc,
- const char **argv,
- const char **envp,
- struct pt_regs *regs)
-{
- unsigned long addr;
- int nextarg = 1;
- long offset = 0;
- int diag;
-
- if (argc != 1)
- return KDB_ARGCOUNT;
-
- diag = kdbgetaddrarg(argc, argv, &nextarg, &addr, &offset, NULL, regs);
- if (diag)
- return diag;
-
- xfsidbg_xalatrace((int) addr);
- return 0;
-}
-
-static int kdbm_xfs_xalbtrace(
- int argc,
- const char **argv,
- const char **envp,
- struct pt_regs *regs)
-{
- unsigned long addr;
- int nextarg = 1;
- long offset = 0;
- int diag;
-
- if (argc != 1)
- return KDB_ARGCOUNT;
-
- diag = kdbgetaddrarg(argc, argv, &nextarg, &addr, &offset, NULL, regs);
- if (diag)
- return diag;
-
- xfsidbg_xalbtrace((xfs_agblock_t) addr);
- return 0;
-}
-
-static int kdbm_xfs_xalgtrace(
- int argc,
- const char **argv,
- const char **envp,
- struct pt_regs *regs)
-{
- unsigned long addr;
- int nextarg = 1;
- long offset = 0;
- int diag;
-
- if (argc != 1)
- return KDB_ARGCOUNT;
-
- diag = kdbgetaddrarg(argc, argv, &nextarg, &addr, &offset, NULL, regs);
- if (diag)
- return diag;
-
- xfsidbg_xalgtrace((xfs_agnumber_t) addr);
- return 0;
-}
-#endif
-
-#ifdef XFS_ATTR_TRACE
-static int kdbm_xfs_xattrtrace(
- int argc,
- const char **argv,
- const char **envp,
- struct pt_regs *regs)
-{
- unsigned long addr;
- int nextarg = 1;
- long offset = 0;
- int diag;
-
- if (argc != 1)
- return KDB_ARGCOUNT;
-
- diag = kdbgetaddrarg(argc, argv, &nextarg, &addr, &offset, NULL, regs);
- if (diag)
- return diag;
-
- xfsidbg_xattrtrace((int) addr);
- return 0;
-}
-#endif
-
-#ifdef XFS_BLI_TRACE
-static int kdbm_xfs_xblitrace(
- int argc,
- const char **argv,
- const char **envp,
- struct pt_regs *regs)
-{
- unsigned long addr;
- int nextarg = 1;
- long offset = 0;
- int diag;
-
- if (argc != 1)
- return KDB_ARGCOUNT;
-
- diag = kdbgetaddrarg(argc, argv, &nextarg, &addr, &offset, NULL, regs);
- if (diag)
- return diag;
-
- xfsidbg_xblitrace((xfs_buf_log_item_t *) addr);
- return 0;
-}
-#endif
-
-#ifdef XFS_BMAP_TRACE
-static int kdbm_xfs_xbmatrace(
- int argc,
- const char **argv,
- const char **envp,
- struct pt_regs *regs)
-{
- unsigned long addr;
- int nextarg = 1;
- long offset = 0;
- int diag;
-
- if (argc != 1)
- return KDB_ARGCOUNT;
-
- diag = kdbgetaddrarg(argc, argv, &nextarg, &addr, &offset, NULL, regs);
- if (diag)
- return diag;
-
- xfsidbg_xbmatrace((int) addr);
- return 0;
-}
-
-static int kdbm_xfs_xbmitrace(
- int argc,
- const char **argv,
- const char **envp,
- struct pt_regs *regs)
-{
- unsigned long addr;
- int nextarg = 1;
- long offset = 0;
- int diag;
-
- if (argc != 1)
- return KDB_ARGCOUNT;
-
- diag = kdbgetaddrarg(argc, argv, &nextarg, &addr, &offset, NULL, regs);
- if (diag)
- return diag;
-
- xfsidbg_xbmitrace((xfs_inode_t *) addr);
- return 0;
-}
-
-static int kdbm_xfs_xbmstrace(
- int argc,
- const char **argv,
- const char **envp,
- struct pt_regs *regs)
-{
- unsigned long addr;
- int nextarg = 1;
- long offset = 0;
- int diag;
-
- if (argc != 1)
- return KDB_ARGCOUNT;
-
- diag = kdbgetaddrarg(argc, argv, &nextarg, &addr, &offset, NULL, regs);
- if (diag)
- return diag;
-
- xfsidbg_xbmstrace((xfs_inode_t *) addr);
- return 0;
-}
-
-static int kdbm_xfs_xbxatrace(
- int argc,
- const char **argv,
- const char **envp,
- struct pt_regs *regs)
-{
- unsigned long addr;
- int nextarg = 1;
- long offset = 0;
- int diag;
-
- if (argc != 1)
- return KDB_ARGCOUNT;
-
- diag = kdbgetaddrarg(argc, argv, &nextarg, &addr, &offset, NULL, regs);
- if (diag)
- return diag;
-
- xfsidbg_xbxatrace((int) addr);
- return 0;
-}
-
-static int kdbm_xfs_xbxitrace(
- int argc,
- const char **argv,
- const char **envp,
- struct pt_regs *regs)
-{
- unsigned long addr;
- int nextarg = 1;
- long offset = 0;
- int diag;
-
- if (argc != 1)
- return KDB_ARGCOUNT;
-
- diag = kdbgetaddrarg(argc, argv, &nextarg, &addr, &offset, NULL, regs);
- if (diag)
- return diag;
-
- xfsidbg_xbxitrace((xfs_inode_t *) addr);
- return 0;
-}
-
-static int kdbm_xfs_xbxstrace(
- int argc,
- const char **argv,
- const char **envp,
- struct pt_regs *regs)
-{
- unsigned long addr;
- int nextarg = 1;
- long offset = 0;
- int diag;
-
- if (argc != 1)
- return KDB_ARGCOUNT;
-
- diag = kdbgetaddrarg(argc, argv, &nextarg, &addr, &offset, NULL, regs);
- if (diag)
- return diag;
-
- xfsidbg_xbxstrace((xfs_inode_t *) addr);
- return 0;
-}
-#endif
-
-#ifdef XFS_DIR2_TRACE
-static int kdbm_xfs_xdir2atrace(
- int argc,
- const char **argv,
- const char **envp,
- struct pt_regs *regs)
-{
- unsigned long addr;
- int nextarg = 1;
- long offset = 0;
- int diag;
-
- if (argc != 1)
- return KDB_ARGCOUNT;
-
- diag = kdbgetaddrarg(argc, argv, &nextarg, &addr, &offset, NULL, regs);
- if (diag)
- return diag;
-
- xfsidbg_xdir2atrace((int) addr);
- return 0;
-}
-
-static int kdbm_xfs_xdir2itrace(
- int argc,
- const char **argv,
- const char **envp,
- struct pt_regs *regs)
-{
- unsigned long addr;
- int nextarg = 1;
- long offset = 0;
- int diag;
-
- if (argc != 1)
- return KDB_ARGCOUNT;
-
- diag = kdbgetaddrarg(argc, argv, &nextarg, &addr, &offset, NULL, regs);
- if (diag)
- return diag;
-
- xfsidbg_xdir2itrace((xfs_inode_t *) addr);
- return 0;
-}
-#endif
-
-#ifdef XFS_DIR_TRACE
-static int kdbm_xfs_xdirtrace(
- int argc,
- const char **argv,
- const char **envp,
- struct pt_regs *regs)
-{
- unsigned long addr;
- int nextarg = 1;
- long offset = 0;
- int diag;
-
- if (argc != 1)
- return KDB_ARGCOUNT;
-
- diag = kdbgetaddrarg(argc, argv, &nextarg, &addr, &offset, NULL, regs);
- if (diag)
- return diag;
-
- xfsidbg_xdirtrace((int) addr);
- return 0;
-}
-#endif
-
-#ifdef XFS_LOG_TRACE
-static int kdbm_xfs_xiclogtrace(
- int argc,
- const char **argv,
- const char **envp,
- struct pt_regs *regs)
-{
- unsigned long addr;
- int nextarg = 1;
- long offset = 0;
- int diag;
-
- if (argc != 1)
- return KDB_ARGCOUNT;
-
- diag = kdbgetaddrarg(argc, argv, &nextarg, &addr, &offset, NULL, regs);
- if (diag)
- return diag;
-
- xfsidbg_xiclogtrace((xlog_in_core_t *) addr);
- return 0;
-}
-#endif
-
-#ifdef XFS_ILOCK_TRACE
-static int kdbm_xfs_xilock_trace(
- int argc,
- const char **argv,
- const char **envp,
- struct pt_regs *regs)
-{
- unsigned long addr;
- int nextarg = 1;
- long offset = 0;
- int diag;
-
- if (argc != 1)
- return KDB_ARGCOUNT;
-
- diag = kdbgetaddrarg(argc, argv, &nextarg, &addr, &offset, NULL, regs);
- if (diag)
- return diag;
-
- xfsidbg_xilock_trace((xfs_inode_t *) addr);
- return 0;
-}
-
-static int kdbm_xfs_xailock_trace(
- int argc,
- const char **argv,
- const char **envp,
- struct pt_regs *regs)
-{
- unsigned long addr;
- int nextarg = 1;
- long offset = 0;
- int diag;
-
- if (argc != 1)
- return KDB_ARGCOUNT;
-
- diag = kdbgetaddrarg(argc, argv, &nextarg, &addr, &offset, NULL, regs);
- if (diag)
- return diag;
-
- xfsidbg_xailock_trace((int) addr);
- return 0;
-}
-#endif
-
-#ifdef XFS_LOG_TRACE
-static int kdbm_xfs_xlog_granttrace(
- int argc,
- const char **argv,
- const char **envp,
- struct pt_regs *regs)
-{
- unsigned long addr;
- int nextarg = 1;
- long offset = 0;
- int diag;
-
- if (argc != 1)
- return KDB_ARGCOUNT;
-
- diag = kdbgetaddrarg(argc, argv, &nextarg, &addr, &offset, NULL, regs);
- if (diag)
- return diag;
-
- xfsidbg_xlog_granttrace((xlog_t *) addr);
- return 0;
-}
-#endif
-
-#ifdef XFS_DQUOT_TRACE
-static int kdbm_xfs_xqm_dqtrace(
- int argc,
- const char **argv,
- const char **envp,
- struct pt_regs *regs)
-{
- unsigned long addr;
- int nextarg = 1;
- long offset = 0;
- int diag;
-
- if (argc != 1)
- return KDB_ARGCOUNT;
-
- diag = kdbgetaddrarg(argc, argv, &nextarg, &addr, &offset, NULL, regs);
- if (diag)
- return diag;
-
- xfsidbg_xqm_dqtrace((xfs_dquot_t *) addr);
- return 0;
-}
-#endif
-
-#ifdef XFS_RW_TRACE
-static int kdbm_xfs_xrwtrace(
- int argc,
- const char **argv,
- const char **envp,
- struct pt_regs *regs)
-{
- unsigned long addr;
- int nextarg = 1;
- long offset = 0;
- int diag;
- ktrace_entry_t *ktep;
- ktrace_snap_t kts;
- xfs_inode_t *ip;
-
- if (argc != 1)
- return KDB_ARGCOUNT;
-
- diag = kdbgetaddrarg(argc, argv, &nextarg, &addr, &offset, NULL, regs);
- if (diag)
- return diag;
-
- ip = (xfs_inode_t *) addr;
- if (ip->i_rwtrace == NULL) {
- qprintf("The inode trace buffer is not initialized\n");
- return 0;
- }
- qprintf("i_rwtrace = 0x%p\n", ip->i_rwtrace);
- ktep = ktrace_first(ip->i_rwtrace, &kts);
- while (ktep != NULL) {
- if (xfs_rw_trace_entry(ktep))
- qprintf("\n");
- ktep = ktrace_next(ip->i_rwtrace, &kts);
- }
- return 0;
-}
-#endif
-
-static int kdbm_xfs_xalloc(
- int argc,
- const char **argv,
- const char **envp,
- struct pt_regs *regs)
-{
- unsigned long addr;
- int nextarg = 1;
- long offset = 0;
- int diag;
-
- if (argc != 1)
- return KDB_ARGCOUNT;
- diag = kdbgetaddrarg(argc, argv, &nextarg, &addr, &offset, NULL, regs);
- if (diag)
- return diag;
-
- xfsidbg_xalloc((xfs_alloc_arg_t *) addr);
- return 0;
-}
-
-#ifdef XFS_ALLOC_TRACE
-static int kdbm_xfs_xalmtrace(
- int argc,
- const char **argv,
- const char **envp,
- struct pt_regs *regs)
-{
- unsigned long addr;
- int nextarg = 1;
- long offset = 0;
- int diag;
-
- if (argc != 1)
- return KDB_ARGCOUNT;
- diag = kdbgetaddrarg(argc, argv, &nextarg, &addr, &offset, NULL, regs);
- if (diag)
- return diag;
-
- xfsidbg_xalmtrace((xfs_mount_t *) addr);
- return 0;
-}
-
-static int kdbm_xfs_xalttrace(
- int argc,
- const char **argv,
- const char **envp,
- struct pt_regs *regs)
-{
- unsigned long addr;
- int nextarg = 1;
- long offset = 0;
- int diag;
-
- if (argc != 1)
- return KDB_ARGCOUNT;
- diag = kdbgetaddrarg(argc, argv, &nextarg, &addr, &offset, NULL, regs);
- if (diag)
- return diag;
-
- xfsidbg_xalttrace((int) addr);
- return 0;
-}
-#endif /* XFS_ALLOC_TRACE */
-
-static int kdbm_xfs_xattrcontext(
- int argc,
- const char **argv,
- const char **envp,
- struct pt_regs *regs)
-{
- unsigned long addr;
- int nextarg = 1;
- long offset = 0;
- int diag;
-
- if (argc != 1)
- return KDB_ARGCOUNT;
- diag = kdbgetaddrarg(argc, argv, &nextarg, &addr, &offset, NULL, regs);
- if (diag)
- return diag;
-
- xfsidbg_xattrcontext((xfs_attr_list_context_t *) addr);
- return 0;
-}
-
-static int kdbm_xfs_xattrleaf(
- int argc,
- const char **argv,
- const char **envp,
- struct pt_regs *regs)
-{
- unsigned long addr;
- int nextarg = 1;
- long offset = 0;
- int diag;
-
- if (argc != 1)
- return KDB_ARGCOUNT;
- diag = kdbgetaddrarg(argc, argv, &nextarg, &addr, &offset, NULL, regs);
- if (diag)
- return diag;
-
- xfsidbg_xattrleaf((xfs_attr_leafblock_t *) addr);
- return 0;
-}
-
-static int kdbm_xfs_xattrsf(
- int argc,
- const char **argv,
- const char **envp,
- struct pt_regs *regs)
-{
- unsigned long addr;
- int nextarg = 1;
- long offset = 0;
- int diag;
-
- if (argc != 1)
- return KDB_ARGCOUNT;
- diag = kdbgetaddrarg(argc, argv, &nextarg, &addr, &offset, NULL, regs);
- if (diag)
- return diag;
-
- xfsidbg_xattrsf((xfs_attr_shortform_t *) addr);
- return 0;
-}
-
-static int kdbm_xfs_xbirec(
- int argc,
- const char **argv,
- const char **envp,
- struct pt_regs *regs)
-{
- unsigned long addr;
- int nextarg = 1;
- long offset = 0;
- int diag;
-
- if (argc != 1)
- return KDB_ARGCOUNT;
- diag = kdbgetaddrarg(argc, argv, &nextarg, &addr, &offset, NULL, regs);
- if (diag)
- return diag;
-
- xfsidbg_xbirec((xfs_bmbt_irec_t *) addr);
- return 0;
-}
-
-static int kdbm_xfs_xbmalla(
- int argc,
- const char **argv,
- const char **envp,
- struct pt_regs *regs)
-{
- unsigned long addr;
- int nextarg = 1;
- long offset = 0;
- int diag;
-
- if (argc != 1)
- return KDB_ARGCOUNT;
- diag = kdbgetaddrarg(argc, argv, &nextarg, &addr, &offset, NULL, regs);
- if (diag)
- return diag;
-
- xfsidbg_xbmalla((xfs_bmalloca_t *)addr);
- return 0;
-}
-
-static int kdbm_xfs_xbrec(
- int argc,
- const char **argv,
- const char **envp,
- struct pt_regs *regs)
-{
- unsigned long addr;
- int nextarg = 1;
- long offset = 0;
- int diag;
-
- if (argc != 1)
- return KDB_ARGCOUNT;
- diag = kdbgetaddrarg(argc, argv, &nextarg, &addr, &offset, NULL, regs);
- if (diag)
- return diag;
-
- xfsidbg_xbrec((xfs_bmbt_rec_64_t *) addr);
- return 0;
-}
-
-static int kdbm_xfs_xbroot(
- int argc,
- const char **argv,
- const char **envp,
- struct pt_regs *regs)
-{
- unsigned long addr;
- int nextarg = 1;
- long offset = 0;
- int diag;
-
- if (argc != 1)
- return KDB_ARGCOUNT;
- diag = kdbgetaddrarg(argc, argv, &nextarg, &addr, &offset, NULL, regs);
- if (diag)
- return diag;
-
- xfsidbg_xbroot((xfs_inode_t *) addr);
- return 0;
-}
-
-static int kdbm_xfs_xbroota(
- int argc,
- const char **argv,
- const char **envp,
- struct pt_regs *regs)
-{
- unsigned long addr;
- int nextarg = 1;
- long offset = 0;
- int diag;
-
- if (argc != 1)
- return KDB_ARGCOUNT;
- diag = kdbgetaddrarg(argc, argv, &nextarg, &addr, &offset, NULL, regs);
- if (diag)
- return diag;
-
- xfsidbg_xbroota((xfs_inode_t *) addr);
- return 0;
-}
-
-static int kdbm_xfs_xbtcur(
- int argc,
- const char **argv,
- const char **envp,
- struct pt_regs *regs)
-{
- unsigned long addr;
- int nextarg = 1;
- long offset = 0;
- int diag;
-
- if (argc != 1)
- return KDB_ARGCOUNT;
- diag = kdbgetaddrarg(argc, argv, &nextarg, &addr, &offset, NULL, regs);
- if (diag)
- return diag;
-
- xfsidbg_xbtcur((xfs_btree_cur_t *) addr);
- return 0;
-}
-
-static int kdbm_xfs_xbuf(
- int argc,
- const char **argv,
- const char **envp,
- struct pt_regs *regs)
-{
- unsigned long addr;
- int nextarg = 1;
- long offset = 0;
- int diag;
-
- if (argc != 1)
- return KDB_ARGCOUNT;
- diag = kdbgetaddrarg(argc, argv, &nextarg, &addr, &offset, NULL, regs);
- if (diag)
- return diag;
-
- xfsidbg_xbuf((xfs_buf_t *) addr);
- return 0;
-}
-
-
-static int kdbm_xfs_xarg(
- int argc,
- const char **argv,
- const char **envp,
- struct pt_regs *regs)
-{
- unsigned long addr;
- int nextarg = 1;
- long offset = 0;
- int diag;
-
- if (argc != 1)
- return KDB_ARGCOUNT;
- diag = kdbgetaddrarg(argc, argv, &nextarg, &addr, &offset, NULL, regs);
- if (diag)
- return diag;
-
- xfsidbg_xarg((int) addr);
- return 0;
-}
-
-static int kdbm_xfs_xchksum(
- int argc,
- const char **argv,
- const char **envp,
- struct pt_regs *regs)
-{
- unsigned long addr;
- int nextarg = 1;
- long offset = 0;
- int diag;
-
- if (argc != 1)
- return KDB_ARGCOUNT;
- diag = kdbgetaddrarg(argc, argv, &nextarg, &addr, &offset, NULL, regs);
- if (diag)
- return diag;
-
- xfsidbg_xchksum((uint *) addr);
- return 0;
-}
-
-
-static int kdbm_xfs_xchash(
- int argc,
- const char **argv,
- const char **envp,
- struct pt_regs *regs)
-{
- unsigned long addr;
- int nextarg = 1;
- long offset = 0;
- int diag;
-
- if (argc != 1)
- return KDB_ARGCOUNT;
- diag = kdbgetaddrarg(argc, argv, &nextarg, &addr, &offset, NULL, regs);
- if (diag)
- return diag;
-
- xfsidbg_xchash((xfs_mount_t *) addr);
- return 0;
-}
-
-static int kdbm_xfs_xchashlist(
- int argc,
- const char **argv,
- const char **envp,
- struct pt_regs *regs)
-{
- unsigned long addr;
- int nextarg = 1;
- long offset = 0;
- int diag;
-
- if (argc != 1)
- return KDB_ARGCOUNT;
- diag = kdbgetaddrarg(argc, argv, &nextarg, &addr, &offset, NULL, regs);
- if (diag)
- return diag;
-
- xfsidbg_xchashlist((xfs_chashlist_t *) addr);
- return 0;
-}
-
-
-static int kdbm_xfs_xdaargs(
- int argc,
- const char **argv,
- const char **envp,
- struct pt_regs *regs)
-{
- unsigned long addr;
- int nextarg = 1;
- long offset = 0;
- int diag;
-
- if (argc != 1)
- return KDB_ARGCOUNT;
- diag = kdbgetaddrarg(argc, argv, &nextarg, &addr, &offset, NULL, regs);
- if (diag)
- return diag;
-
- xfsidbg_xdaargs((xfs_da_args_t *) addr);
- return 0;
-}
-
-static int kdbm_xfs_xdabuf(
- int argc,
- const char **argv,
- const char **envp,
- struct pt_regs *regs)
-{
- unsigned long addr;
- int nextarg = 1;
- long offset = 0;
- int diag;
-
- if (argc != 1)
- return KDB_ARGCOUNT;
- diag = kdbgetaddrarg(argc, argv, &nextarg, &addr, &offset, NULL, regs);
- if (diag)
- return diag;
-
- xfsidbg_xdabuf((xfs_dabuf_t *) addr);
- return 0;
-}
-
-static int kdbm_xfs_xdanode(
- int argc,
- const char **argv,
- const char **envp,
- struct pt_regs *regs)
-{
- unsigned long addr;
- int nextarg = 1;
- long offset = 0;
- int diag;
-
- if (argc != 1)
- return KDB_ARGCOUNT;
- diag = kdbgetaddrarg(argc, argv, &nextarg, &addr, &offset, NULL, regs);
- if (diag)
- return diag;
-
- xfsidbg_xdanode((xfs_da_intnode_t *) addr);
- return 0;
-}
-
-static int kdbm_xfs_xdastate(
- int argc,
- const char **argv,
- const char **envp,
- struct pt_regs *regs)
-{
- unsigned long addr;
- int nextarg = 1;
- long offset = 0;
- int diag;
-
- if (argc != 1)
- return KDB_ARGCOUNT;
- diag = kdbgetaddrarg(argc, argv, &nextarg, &addr, &offset, NULL, regs);
- if (diag)
- return diag;
-
- xfsidbg_xdastate((xfs_da_state_t *) addr);
- return 0;
-}
-
-static int kdbm_xfs_xdirleaf(
- int argc,
- const char **argv,
- const char **envp,
- struct pt_regs *regs)
-{
- unsigned long addr;
- int nextarg = 1;
- long offset = 0;
- int diag;
-
- if (argc != 1)
- return KDB_ARGCOUNT;
- diag = kdbgetaddrarg(argc, argv, &nextarg, &addr, &offset, NULL, regs);
- if (diag)
- return diag;
-
- xfsidbg_xdirleaf((xfs_dir_leafblock_t *) addr);
- return 0;
-}
-
-static int kdbm_xfs_xdirsf(
- int argc,
- const char **argv,
- const char **envp,
- struct pt_regs *regs)
-{
- unsigned long addr;
- int nextarg = 1;
- long offset = 0;
- int diag;
-
- if (argc != 1)
- return KDB_ARGCOUNT;
- diag = kdbgetaddrarg(argc, argv, &nextarg, &addr, &offset, NULL, regs);
- if (diag)
- return diag;
-
- xfsidbg_xdirsf((xfs_dir_shortform_t *) addr);
- return 0;
-}
-
-static int kdbm_xfs_xdir2free(
- int argc,
- const char **argv,
- const char **envp,
- struct pt_regs *regs)
-{
- unsigned long addr;
- int nextarg = 1;
- long offset = 0;
- int diag;
-
- if (argc != 1)
- return KDB_ARGCOUNT;
- diag = kdbgetaddrarg(argc, argv, &nextarg, &addr, &offset, NULL, regs);
- if (diag)
- return diag;
-
- xfsidbg_xdir2free((xfs_dir2_free_t *) addr);
- return 0;
-}
-
-static int kdbm_xfs_xdir2sf(
- int argc,
- const char **argv,
- const char **envp,
- struct pt_regs *regs)
-{
- unsigned long addr;
- int nextarg = 1;
- long offset = 0;
- int diag;
-
- if (argc != 1)
- return KDB_ARGCOUNT;
- diag = kdbgetaddrarg(argc, argv, &nextarg, &addr, &offset, NULL, regs);
- if (diag)
- return diag;
-
- xfsidbg_xdir2sf((xfs_dir2_sf_t *) addr);
- return 0;
-}
-
-static int kdbm_xfs_xexlist(
- int argc,
- const char **argv,
- const char **envp,
- struct pt_regs *regs)
-{
- unsigned long addr;
- int nextarg = 1;
- long offset = 0;
- int diag;
-
- if (argc != 1)
- return KDB_ARGCOUNT;
- diag = kdbgetaddrarg(argc, argv, &nextarg, &addr, &offset, NULL, regs);
- if (diag)
- return diag;
-
- xfsidbg_xexlist((xfs_inode_t *) addr);
- return 0;
-}
-
-static int kdbm_xfs_xflist(
- int argc,
- const char **argv,
- const char **envp,
- struct pt_regs *regs)
-{
- unsigned long addr;
- int nextarg = 1;
- long offset = 0;
- int diag;
-
- if (argc != 1)
- return KDB_ARGCOUNT;
- diag = kdbgetaddrarg(argc, argv, &nextarg, &addr, &offset, NULL, regs);
- if (diag)
- return diag;
-
- xfsidbg_xflist((xfs_bmap_free_t *) addr);
- return 0;
-}
-
-static int kdbm_xfs_xhelp(
- int argc,
- const char **argv,
- const char **envp,
- struct pt_regs *regs)
-{
- if (argc != 0)
- return KDB_ARGCOUNT;
-
- xfsidbg_xhelp();
- return 0;
-}
-
-static int kdbm_xfs_xiclog(
- int argc,
- const char **argv,
- const char **envp,
- struct pt_regs *regs)
-{
- unsigned long addr;
- int nextarg = 1;
- long offset = 0;
- int diag;
-
- if (argc != 1)
- return KDB_ARGCOUNT;
- diag = kdbgetaddrarg(argc, argv, &nextarg, &addr, &offset, NULL, regs);
- if (diag)
- return diag;
-
- xfsidbg_xiclog((xlog_in_core_t *) addr);
- return 0;
-}
-
-static int kdbm_xfs_xiclogall(
- int argc,
- const char **argv,
- const char **envp,
- struct pt_regs *regs)
-{
- unsigned long addr;
- int nextarg = 1;
- long offset = 0;
- int diag;
-
- if (argc != 1)
- return KDB_ARGCOUNT;
- diag = kdbgetaddrarg(argc, argv, &nextarg, &addr, &offset, NULL, regs);
- if (diag)
- return diag;
-
- xfsidbg_xiclogall((xlog_in_core_t *) addr);
- return 0;
-}
-
-static int kdbm_xfs_xiclogcb(
- int argc,
- const char **argv,
- const char **envp,
- struct pt_regs *regs)
-{
- unsigned long addr;
- int nextarg = 1;
- long offset = 0;
- int diag;
-
- if (argc != 1)
- return KDB_ARGCOUNT;
- diag = kdbgetaddrarg(argc, argv, &nextarg, &addr, &offset, NULL, regs);
- if (diag)
- return diag;
-
- xfsidbg_xiclogcb((xlog_in_core_t *) addr);
- return 0;
-}
-
-static int kdbm_xfs_xihash(
- int argc,
- const char **argv,
- const char **envp,
- struct pt_regs *regs)
-{
- unsigned long addr;
- int nextarg = 1;
- long offset = 0;
- int diag;
-
- if (argc != 1)
- return KDB_ARGCOUNT;
- diag = kdbgetaddrarg(argc, argv, &nextarg, &addr, &offset, NULL, regs);
- if (diag)
- return diag;
-
- xfsidbg_xihash((xfs_mount_t *) addr);
- return 0;
-}
-
-static int kdbm_xfs_xinodes(
- int argc,
- const char **argv,
- const char **envp,
- struct pt_regs *regs)
-{
- unsigned long addr;
- int nextarg = 1;
- long offset = 0;
- int diag;
-
- if (argc != 1)
- return KDB_ARGCOUNT;
- diag = kdbgetaddrarg(argc, argv, &nextarg, &addr, &offset, NULL, regs);
- if (diag)
- return diag;
-
- xfsidbg_xinodes((xfs_mount_t *) addr);
- return 0;
-}
-
-static int kdbm_xfs_delayed_blocks(
- int argc,
- const char **argv,
- const char **envp,
- struct pt_regs *regs)
-{
- unsigned long addr;
- int nextarg = 1;
- long offset = 0;
- int diag;
-
- if (argc != 1)
- return KDB_ARGCOUNT;
- diag = kdbgetaddrarg(argc, argv, &nextarg, &addr, &offset, NULL, regs);
- if (diag)
- return diag;
-
- xfsidbg_delayed_blocks((xfs_mount_t *) addr);
- return 0;
-}
-
-
-static int kdbm_xfs_xinodes_quiesce(
- int argc,
- const char **argv,
- const char **envp,
- struct pt_regs *regs)
-{
- unsigned long addr;
- int nextarg = 1;
- long offset = 0;
- int diag;
-
- if (argc != 1)
- return KDB_ARGCOUNT;
- diag = kdbgetaddrarg(argc, argv, &nextarg, &addr, &offset, NULL, regs);
- if (diag)
- return diag;
-
- xfsidbg_xinodes_quiesce((xfs_mount_t *) addr);
- return 0;
-}
-
-static int kdbm_xfs_xlog(
- int argc,
- const char **argv,
- const char **envp,
- struct pt_regs *regs)
-{
- unsigned long addr;
- int nextarg = 1;
- long offset = 0;
- int diag;
-
- if (argc != 1)
- return KDB_ARGCOUNT;
- diag = kdbgetaddrarg(argc, argv, &nextarg, &addr, &offset, NULL, regs);
- if (diag)
- return diag;
-
- xfsidbg_xlog((xlog_t *) addr);
- return 0;
-}
-
-static int kdbm_xfs_xlog_ritem(
- int argc,
- const char **argv,
- const char **envp,
- struct pt_regs *regs)
-{
- unsigned long addr;
- int nextarg = 1;
- long offset = 0;
- int diag;
-
- if (argc != 1)
- return KDB_ARGCOUNT;
- diag = kdbgetaddrarg(argc, argv, &nextarg, &addr, &offset, NULL, regs);
- if (diag)
- return diag;
-
- xfsidbg_xlog_ritem((xlog_recover_item_t *) addr);
- return 0;
-}
-
-static int kdbm_xfs_xlog_rtrans(
- int argc,
- const char **argv,
- const char **envp,
- struct pt_regs *regs)
-{
- unsigned long addr;
- int nextarg = 1;
- long offset = 0;
- int diag;
-
- if (argc != 1)
- return KDB_ARGCOUNT;
- diag = kdbgetaddrarg(argc, argv, &nextarg, &addr, &offset, NULL, regs);
- if (diag)
- return diag;
-
- xfsidbg_xlog_rtrans((xlog_recover_t *) addr);
- return 0;
-}
-
-static int kdbm_xfs_xlog_rtrans_entire(
- int argc,
- const char **argv,
- const char **envp,
- struct pt_regs *regs)
-{
- unsigned long addr;
- int nextarg = 1;
- long offset = 0;
- int diag;
-
- if (argc != 1)
- return KDB_ARGCOUNT;
- diag = kdbgetaddrarg(argc, argv, &nextarg, &addr, &offset, NULL, regs);
- if (diag)
- return diag;
-
- xfsidbg_xlog_rtrans_entire((xlog_recover_t *) addr);
- return 0;
-}
-
-static int kdbm_xfs_xlog_tic(
- int argc,
- const char **argv,
- const char **envp,
- struct pt_regs *regs)
-{
- unsigned long addr;
- int nextarg = 1;
- long offset = 0;
- int diag;
-
- if (argc != 1)
- return KDB_ARGCOUNT;
- diag = kdbgetaddrarg(argc, argv, &nextarg, &addr, &offset, NULL, regs);
- if (diag)
- return diag;
-
- xfsidbg_xlog_tic((xlog_ticket_t *) addr);
- return 0;
-}
-
-static int kdbm_xfs_xlogitem(
- int argc,
- const char **argv,
- const char **envp,
- struct pt_regs *regs)
-{
- unsigned long addr;
- int nextarg = 1;
- long offset = 0;
- int diag;
-
- if (argc != 1)
- return KDB_ARGCOUNT;
- diag = kdbgetaddrarg(argc, argv, &nextarg, &addr, &offset, NULL, regs);
- if (diag)
- return diag;
-
- xfsidbg_xlogitem((xfs_log_item_t *) addr);
- return 0;
-}
-
-static int kdbm_xfs_xmount(
- int argc,
- const char **argv,
- const char **envp,
- struct pt_regs *regs)
-{
- unsigned long addr;
- int nextarg = 1;
- long offset = 0;
- int diag;
-
- if (argc != 1)
- return KDB_ARGCOUNT;
- diag = kdbgetaddrarg(argc, argv, &nextarg, &addr, &offset, NULL, regs);
- if (diag)
- return diag;
-
- xfsidbg_xmount((xfs_mount_t *) addr);
- return 0;
-}
-
-static int kdbm_xfs_xnode(
- int argc,
- const char **argv,
- const char **envp,
- struct pt_regs *regs)
-{
- unsigned long addr;
- int nextarg = 1;
- long offset = 0;
- int diag;
-
- if (argc != 1)
- return KDB_ARGCOUNT;
- diag = kdbgetaddrarg(argc, argv, &nextarg, &addr, &offset, NULL, regs);
- if (diag)
- return diag;
-
- xfsidbg_xnode((xfs_inode_t *) addr);
- return 0;
-}
-
-static int kdbm_xfs_xcore(
- int argc,
- const char **argv,
- const char **envp,
- struct pt_regs *regs)
-{
- unsigned long addr;
- int nextarg = 1;
- long offset = 0;
- int diag;
-
- if (argc != 1)
- return KDB_ARGCOUNT;
- diag = kdbgetaddrarg(argc, argv, &nextarg, &addr, &offset, NULL, regs);
- if (diag)
- return diag;
-
- xfsidbg_xcore((xfs_iocore_t *) addr);
- return 0;
-}
-
-static int kdbm_xfs_xperag(
- int argc,
- const char **argv,
- const char **envp,
- struct pt_regs *regs)
-{
- unsigned long addr;
- int nextarg = 1;
- long offset = 0;
- int diag;
-
- if (argc != 1)
- return KDB_ARGCOUNT;
- diag = kdbgetaddrarg(argc, argv, &nextarg, &addr, &offset, NULL, regs);
- if (diag)
- return diag;
-
- xfsidbg_xperag((xfs_mount_t *) addr);
- return 0;
-}
-
-static int kdbm_xfs_xqm_diskdq(
- int argc,
- const char **argv,
- const char **envp,
- struct pt_regs *regs)
-{
- unsigned long addr;
- int nextarg = 1;
- long offset = 0;
- int diag;
-
- if (argc != 1)
- return KDB_ARGCOUNT;
- diag = kdbgetaddrarg(argc, argv, &nextarg, &addr, &offset, NULL, regs);
- if (diag)
- return diag;
-
- xfsidbg_xqm_diskdq((xfs_disk_dquot_t *) addr);
- return 0;
-}
-
-static int kdbm_xfs_xqm_dqattached_inos(
- int argc,
- const char **argv,
- const char **envp,
- struct pt_regs *regs)
-{
- unsigned long addr;
- int nextarg = 1;
- long offset = 0;
- int diag;
-
- if (argc != 1)
- return KDB_ARGCOUNT;
- diag = kdbgetaddrarg(argc, argv, &nextarg, &addr, &offset, NULL, regs);
- if (diag)
- return diag;
-
- xfsidbg_xqm_dqattached_inos((xfs_mount_t *) addr);
- return 0;
-}
-
-static int kdbm_xfs_xqm_dquot(
- int argc,
- const char **argv,
- const char **envp,
- struct pt_regs *regs)
-{
- unsigned long addr;
- int nextarg = 1;
- long offset = 0;
- int diag;
-
- if (argc != 1)
- return KDB_ARGCOUNT;
- diag = kdbgetaddrarg(argc, argv, &nextarg, &addr, &offset, NULL, regs);
- if (diag)
- return diag;
-
- xfsidbg_xqm_dquot((xfs_dquot_t *) addr);
- return 0;
-}
-
-#ifdef CONFIG_XFS_QUOTA
-static int kdbm_xfs_xqm(
- int argc,
- const char **argv,
- const char **envp,
- struct pt_regs *regs)
-{
- if (argc != 0)
- return KDB_ARGCOUNT;
-
- xfsidbg_xqm();
- return 0;
-}
-
-static int kdbm_xfs_xqm_freelist(
- int argc,
- const char **argv,
- const char **envp,
- struct pt_regs *regs)
-{
- if (argc != 0)
- return KDB_ARGCOUNT;
-
- xfsidbg_xqm_freelist();
- return 0;
-}
-
-static int kdbm_xfs_xqm_htab(
- int argc,
- const char **argv,
- const char **envp,
- struct pt_regs *regs)
-{
- if (argc != 0)
- return KDB_ARGCOUNT;
-
- xfsidbg_xqm_htab();
- return 0;
-}
-#endif
-
-static int kdbm_xfs_xqm_mplist(
- int argc,
- const char **argv,
- const char **envp,
- struct pt_regs *regs)
-{
- unsigned long addr;
- int nextarg = 1;
- long offset = 0;
- int diag;
-
- if (argc != 1)
- return KDB_ARGCOUNT;
- diag = kdbgetaddrarg(argc, argv, &nextarg, &addr, &offset, NULL, regs);
- if (diag)
- return diag;
-
- xfsidbg_xqm_mplist((xfs_mount_t *) addr);
- return 0;
-}
-
-static int kdbm_xfs_xqm_qinfo(
- int argc,
- const char **argv,
- const char **envp,
- struct pt_regs *regs)
-{
- unsigned long addr;
- int nextarg = 1;
- long offset = 0;
- int diag;
-
- if (argc != 1)
- return KDB_ARGCOUNT;
- diag = kdbgetaddrarg(argc, argv, &nextarg, &addr, &offset, NULL, regs);
- if (diag)
- return diag;
-
- xfsidbg_xqm_qinfo((xfs_mount_t *) addr);
- return 0;
-}
-
-static int kdbm_xfs_xqm_tpdqinfo(
- int argc,
- const char **argv,
- const char **envp,
- struct pt_regs *regs)
-{
- unsigned long addr;
- int nextarg = 1;
- long offset = 0;
- int diag;
-
- if (argc != 1)
- return KDB_ARGCOUNT;
- diag = kdbgetaddrarg(argc, argv, &nextarg, &addr, &offset, NULL, regs);
- if (diag)
- return diag;
-
- xfsidbg_xqm_tpdqinfo((xfs_trans_t *) addr);
- return 0;
-}
-
-static int kdbm_xfs_xsb(
- int argc,
- const char **argv,
- const char **envp,
- struct pt_regs *regs)
-{
- unsigned long addr;
- unsigned long convert=0;
- int nextarg = 1;
- long offset = 0;
- int diag;
-
- if (argc != 1 && argc!=2)
- return KDB_ARGCOUNT;
- diag = kdbgetaddrarg(argc, argv, &nextarg, &addr, &offset, NULL, regs);
- if (diag)
- return diag;
- if (argc==2) {
- /* extra argument - conversion flag */
- diag = kdbgetaddrarg(argc, argv, &nextarg, &convert, &offset, NULL, regs);
- if (diag)
- return diag;
- }
-
- if (convert)
- xfsidbg_xsb_convert((xfs_sb_t *) addr);
- else
- xfsidbg_xsb((xfs_sb_t *) addr);
- return 0;
-}
-
-static int kdbm_xfs_xtp(
- int argc,
- const char **argv,
- const char **envp,
- struct pt_regs *regs)
-{
- unsigned long addr;
- int nextarg = 1;
- long offset = 0;
- int diag;
-
- if (argc != 1)
- return KDB_ARGCOUNT;
- diag = kdbgetaddrarg(argc, argv, &nextarg, &addr, &offset, NULL, regs);
- if (diag)
- return diag;
-
- xfsidbg_xtp((xfs_trans_t *) addr);
- return 0;
-}
-
-static int kdbm_xfs_xtrans_res(
- int argc,
- const char **argv,
- const char **envp,
- struct pt_regs *regs)
-{
- unsigned long addr;
- int nextarg = 1;
- long offset = 0;
- int diag;
-
- if (argc != 1)
- return KDB_ARGCOUNT;
- diag = kdbgetaddrarg(argc, argv, &nextarg, &addr, &offset, NULL, regs);
- if (diag)
- return diag;
-
- xfsidbg_xtrans_res((xfs_mount_t *) addr);
- return 0;
-}
-
-/*
- * Vnode descriptor dump.
- * This table is a string version of all the flags defined in vnode.h.
- */
-char *tab_vflags[] = {
- /* local only flags */
- "VINACT", /* 0x01 */
- "VRECLM", /* 0x02 */
- "VWAIT", /* 0x04 */
- "VMODIFIED", /* 0x08 */
- "INVALID0x10", /* 0x10 */
- "INVALID0x20", /* 0x20 */
- "INVALID0x40", /* 0x40 */
- "INVALID0x80", /* 0x80 */
- "INVALID0x100", /* 0x100 */
- "INVALID0x200", /* 0x200 */
- "INVALID0x400", /* 0x400 */
- "INVALID0x800", /* 0x800 */
- "INVALID0x1000", /* 0x1000 */
- "INVALID0x2000", /* 0x2000 */
- "INVALID0x4000", /* 0x4000 */
- "INVALID0x8000", /* 0x8000 */
- "INVALID0x10000", /* 0x10000 */
- "INVALID0x20000", /* 0x20000 */
- "INVALID0x40000", /* 0x40000 */
- "INVALID0x80000", /* 0x80000 */
- "VROOT", /* 0x100000 */
- "INVALID0x200000", /* 0x200000 */
- "INVALID00x400000", /* 0x400000 */
- "INVALID0x800000", /* 0x800000 */
- "INVALID0x1000000", /* 0x1000000 */
- "INVALID0x2000000", /* 0x2000000 */
- "VSHARE", /* 0x4000000 */
- "INVALID0x8000000", /* 0x8000000 */
- "VENF_LOCKING", /* 0x10000000 */
- "VOPLOCK", /* 0x20000000 */
- "VPURGE", /* 0x40000000 */
- "INVALID0x80000000", /* 0x80000000 */
- NULL
-};
-
-static void
-printflags(register uint64_t flags,
- register char **strings,
- register char *name)
-{
- register uint64_t mask = 1;
-
- if (name)
- kdb_printf("%s 0x%llx <", name, (unsigned long long)flags);
-
- while (flags != 0 && *strings) {
- if (mask & flags) {
- kdb_printf("%s ", *strings);
- flags &= ~mask;
- }
- mask <<= 1;
- strings++;
- }
-
- if (name)
- kdb_printf("> ");
-
- return;
-}
-
-
-static void printbhv(bhv_desc_t *bdp)
-{
- int maxbhv = 20; /* if you get 20 bhvs you're in trouble already */
- kdb_symtab_t symtab;
-
- if (bdp == NULL) {
- kdb_printf("NULL bhv\n");
- return;
- }
-
- kdb_printf("bhv at 0x%p\n", bdp);
- while (bdp && maxbhv--) {
- if (kdbnearsym((unsigned long)bdp->bd_ops, &symtab))
- kdb_printf(" ops %s", symtab.sym_name);
- else
- kdb_printf(" ops %s/0x%p", "???", (void *)bdp->bd_ops);
-
- kdb_printf(" vobj 0x%p pdata 0x%p next 0x%p\n",
- bdp->bd_vobj, bdp->bd_pdata, bdp->bd_next);
-
- bdp = bdp->bd_next;
- }
-}
-
-
-static void printvnode(xfs_vnode_t *vp, unsigned long addr)
-{
- kdb_printf("vnode: 0x%lx\n", addr);
- kdb_printf(" v_bh 0x%p\n", &vp->v_bh);
-
- printbhv(vp->v_fbhv);
-
- printflags((__psunsigned_t)vp->v_flag, tab_vflags, "flag =");
- kdb_printf("\n");
-
-#ifdef XFS_VNODE_TRACE
- kdb_printf(" v_trace 0x%p\n", vp->v_trace);
-#endif /* XFS_VNODE_TRACE */
-
- kdb_printf(" v_vfsp 0x%p v_number 0x%llx\n",
- vp->v_vfsp, (unsigned long long)vp->v_number);
-}
-
-static int kdbm_vnode(
- int argc,
- const char **argv,
- const char **envp,
- struct pt_regs *regs)
-{
- unsigned long addr;
- int nextarg = 1;
- long offset = 0;
- int diag;
- xfs_vnode_t vp;
-
- if (argc != 1)
- return KDB_ARGCOUNT;
-
- diag = kdbgetaddrarg(argc, argv, &nextarg, &addr, &offset, NULL, regs);
-
- if (diag)
- return diag;
-
- if ((diag = kdb_getarea(vp, addr)))
- return diag;
-
- printvnode(&vp, addr);
-
- return 0;
-}
-
-static void
-print_vfs(xfs_vfs_t *vfs, unsigned long addr)
-{
- kdb_printf("vfsp at 0x%lx", addr);
- kdb_printf(" vfs_flag 0x%x\n", vfs->vfs_flag);
- kdb_printf(" vfs_mp 0x%p", vfs->vfs_mp);
- kdb_printf(" vfs_bh 0x%p\n", &vfs->vfs_bh);
-
- printbhv(vfs->vfs_fbhv);
-}
-
-static int kdbm_bhv(
- int argc,
- const char **argv,
- const char **envp,
- struct pt_regs *regs)
-{
- unsigned long addr;
- int nextarg = 1;
- long offset = 0;
- int diag;
- bhv_desc_t *bh;
-
- if (argc != 1)
- return KDB_ARGCOUNT;
-
- diag = kdbgetaddrarg(argc, argv, &nextarg, &addr, &offset, NULL, regs);
-
- if (diag)
- return diag;
-
- bh = (bhv_desc_t *)addr;
-
- printbhv(bh);
-
- return 0;
-}
-
-static int kdbm_vfs(
- int argc,
- const char **argv,
- const char **envp,
- struct pt_regs *regs)
-{
- unsigned long addr;
- int nextarg = 1;
- long offset = 0;
- int diag;
- xfs_vfs_t vfs;
-
- if (argc != 1)
- return KDB_ARGCOUNT;
-
- diag = kdbgetaddrarg(argc, argv, &nextarg, &addr, &offset, NULL, regs);
-
- if (diag)
- return diag;
-
- if ((diag = kdb_getarea(vfs, addr)))
- return diag;
-
- print_vfs(&vfs, addr);
-
- return 0;
-}
-
-
-#ifdef XFS_VNODE_TRACE
-/*
- * Print a vnode trace entry.
- */
-static int
-vn_trace_pr_entry(ktrace_entry_t *ktep)
-{
- char funcname[128];
- kdb_symtab_t symtab;
-
-
- if ((__psint_t)ktep->val[0] == 0)
- return 0;
-
- if (kdbnearsym((unsigned int)ktep->val[8], &symtab)) {
- unsigned long offval;
-
- offval = (unsigned int)ktep->val[8] - symtab.sym_start;
-
- if (offval)
- sprintf(funcname, "%s+0x%lx", symtab.sym_name, offval);
- else
- sprintf(funcname, "%s", symtab.sym_name);
- } else
- funcname[0] = '\0';
-
-
- switch ((__psint_t)ktep->val[0]) {
- case VNODE_KTRACE_ENTRY:
- kdb_printf("entry to %s i_count = %d",
- (char *)ktep->val[1],
- (__psint_t)ktep->val[3]);
- break;
-
- case VNODE_KTRACE_EXIT:
- kdb_printf("exit from %s i_count = %d",
- (char *)ktep->val[1],
- (__psint_t)ktep->val[3]);
- break;
-
- case VNODE_KTRACE_HOLD:
- if ((__psint_t)ktep->val[3] != 1)
- kdb_printf("hold @%s:%d(%s) i_count %d => %d ",
- (char *)ktep->val[1],
- (__psint_t)ktep->val[2],
- funcname,
- (__psint_t)ktep->val[3] - 1,
- (__psint_t)ktep->val[3]);
- else
- kdb_printf("get @%s:%d(%s) i_count = %d",
- (char *)ktep->val[1],
- (__psint_t)ktep->val[2],
- funcname,
- (__psint_t)ktep->val[3]);
- break;
-
- case VNODE_KTRACE_REF:
- kdb_printf("ref @%s:%d(%s) i_count = %d",
- (char *)ktep->val[1],
- (__psint_t)ktep->val[2],
- funcname,
- (__psint_t)ktep->val[3]);
- break;
-
- case VNODE_KTRACE_RELE:
- if ((__psint_t)ktep->val[3] != 1)
- kdb_printf("rele @%s:%d(%s) i_count %d => %d ",
- (char *)ktep->val[1],
- (__psint_t)ktep->val[2],
- funcname,
- (__psint_t)ktep->val[3],
- (__psint_t)ktep->val[3] - 1);
- else
- kdb_printf("free @%s:%d(%s) i_count = %d",
- (char *)ktep->val[1],
- (__psint_t)ktep->val[2],
- funcname,
- (__psint_t)ktep->val[3]);
- break;
-
- default:
- kdb_printf("unknown vntrace record\n");
- return 1;
- }
-
- kdb_printf("\n");
-
- kdb_printf(" cpu = %d pid = %d ",
- (__psint_t)ktep->val[6], (pid_t)ktep->val[7]);
-
- printflags((__psunsigned_t)ktep->val[5], tab_vflags, "flag =");
-
- if (kdbnearsym((unsigned int)ktep->val[4], &symtab)) {
- unsigned long offval;
-
- offval = (unsigned int)ktep->val[4] - symtab.sym_start;
-
- if (offval)
- kdb_printf(" ra = %s+0x%lx", symtab.sym_name, offval);
- else
- kdb_printf(" ra = %s", symtab.sym_name);
- } else
- kdb_printf(" ra = ?? 0x%p", (void *)ktep->val[4]);
-
- return 1;
-}
-
-
-/*
- * Print out the trace buffer attached to the given vnode.
- */
-static int kdbm_vntrace(
- int argc,
- const char **argv,
- const char **envp,
- struct pt_regs *regs)
-{
- int diag;
- int nextarg = 1;
- long offset = 0;
- unsigned long addr;
- xfs_vnode_t *vp;
- ktrace_entry_t *ktep;
- ktrace_snap_t kts;
-
-
- if (argc != 1)
- return KDB_ARGCOUNT;
-
- diag = kdbgetaddrarg(argc, argv, &nextarg, &addr, &offset, NULL, regs);
-
- if (diag)
- return diag;
-
- vp = (xfs_vnode_t *)addr;
-
- if (vp->v_trace == NULL) {
- kdb_printf("The vnode trace buffer is not initialized\n");
-
- return 0;
- }
-
- kdb_printf("vntrace vp 0x%p\n", vp);
-
- ktep = ktrace_first(vp->v_trace, &kts);
-
- while (ktep != NULL) {
- if (vn_trace_pr_entry(ktep))
- kdb_printf("\n");
-
- ktep = ktrace_next(vp->v_trace, &kts);
- }
-
- return 0;
-}
-/*
- * Print out the trace buffer attached to the given vnode.
- */
-static int kdbm_vntraceaddr(
- int argc,
- const char **argv,
- const char **envp,
- struct pt_regs *regs)
-{
- int diag;
- int nextarg = 1;
- long offset = 0;
- unsigned long addr;
- struct ktrace *kt;
- ktrace_entry_t *ktep;
- ktrace_snap_t kts;
-
-
- if (argc != 1)
- return KDB_ARGCOUNT;
-
- diag = kdbgetaddrarg(argc, argv, &nextarg, &addr, &offset, NULL, regs);
-
- if (diag)
- return diag;
-
- kt = (struct ktrace *)addr;
-
- kdb_printf("vntraceaddr kt 0x%p\n", kt);
-
- ktep = ktrace_first(kt, &kts);
-
- while (ktep != NULL) {
- if (vn_trace_pr_entry(ktep))
- kdb_printf("\n");
-
- ktep = ktrace_next(kt, &kts);
- }
-
- return 0;
-}
-#endif /* XFS_VNODE_TRACE */
-
-#ifdef __linux__
-static void printinode(struct inode *ip)
-{
- unsigned long addr;
-
-
- if (ip == NULL)
- return;
-
- kdb_printf(" i_ino = %lu i_count = %u i_size %Ld\n",
- ip->i_ino, atomic_read(&ip->i_count),
- ip->i_size);
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0)
- kdb_printf(
- " i_mode = 0x%x i_nlink = %d i_rdev = 0x%x i_state = 0x%lx\n",
- ip->i_mode, ip->i_nlink,
- kdev_t_to_nr(ip->i_rdev), ip->i_state);
- kdb_printf(" i_hash.nxt = 0x%p i_hash.pprv = 0x%p\n",
- ip->i_hash.next, ip->i_hash.prev);
-#else
- kdb_printf(
- " i_mode = 0x%x i_nlink = %d i_rdev = 0x%x i_state = 0x%lx\n",
- ip->i_mode, ip->i_nlink,
- ip->i_rdev, ip->i_state);
- kdb_printf(" i_hash.nxt = 0x%p i_hash.pprv = 0x%p\n",
- ip->i_hash.next, ip->i_hash.pprev);
-#endif
- kdb_printf(" i_list.nxt = 0x%p i_list.prv = 0x%p\n",
- ip->i_list.next, ip->i_list.prev);
- kdb_printf(" i_dentry.nxt = 0x%p i_dentry.prv = 0x%p\n",
- ip->i_dentry.next,
- ip->i_dentry.prev);
-
- addr = (unsigned long)ip;
-
- kdb_printf(" i_sb = 0x%p i_op = 0x%p i_data = 0x%lx nrpages = %lu\n",
- ip->i_sb, ip->i_op,
- addr + offsetof(struct inode, i_data),
- ip->i_data.nrpages);
-
- kdb_printf(" vnode ptr 0x%p\n", vn_from_inode(ip));
-}
-
-#endif
-
-
-static int kdbm_vn(
- int argc,
- const char **argv,
- const char **envp,
- struct pt_regs *regs)
-{
- int diag;
- int nextarg = 1;
- long offset = 0;
- unsigned long addr;
-#ifdef __linux__
- struct inode *ip;
-#endif
- xfs_vnode_t vp;
-#ifdef XFS_VNODE_TRACE
- ktrace_entry_t *ktep;
- ktrace_snap_t kts;
-#endif
-
- if (argc != 1)
- return KDB_ARGCOUNT;
-
- diag = kdbgetaddrarg(argc, argv, &nextarg, &addr, &offset, NULL, regs);
- if (diag)
- return diag;
-
- if ((diag = kdb_getarea(vp, addr)))
- return diag;
-
-#ifdef __linux__
- ip = vn_to_inode((vnode_t *)addr);
- kdb_printf("--> Inode @ 0x%p\n", ip);
- printinode(ip);
-#endif
-
- kdb_printf("--> Vnode @ 0x%lx\n", addr);
- printvnode(&vp, addr);
-
-#ifdef XFS_VNODE_TRACE
- kdb_printf("--> Vntrace @ 0x%lx/0x%p\n", addr, vp.v_trace);
- if (vp.v_trace == NULL)
- return 0;
- ktep = ktrace_first(vp.v_trace, &kts);
- while (ktep != NULL) {
- if (vn_trace_pr_entry(ktep))
- kdb_printf("\n");
-
- ktep = ktrace_next(vp.v_trace, &kts);
- }
-#endif /* XFS_VNODE_TRACE */
- return 0;
-}
-
-
-#ifdef __linux__
-
-static char *bp_flag_vals[] = {
-/* 0 */ "READ", "WRITE", "MAPPED", "PARTIAL", "ASYNC",
-/* 5 */ "NONE", "DELWRI", "STALE", "FS_MANAGED", "FS_DATAIOD",
-/* 10 */ "FORCEIO", "FLUSH", "READ_AHEAD", "DIRECTIO", "LOCK",
-/* 15 */ "TRYLOCK", "DONT_BLOCK", "PAGE_CACHE", "KMEM_ALLOC", "RUN_QUEUES",
-/* 20 */ "PRIVATE_BH", "DELWRI_Q",
- NULL };
-
-#endif
-
-static char *iomap_flag_vals[] = {
- "EOF", "HOLE", "DELAY", "INVALID0x08",
- "INVALID0x10", "UNWRITTEN", "NEW", "INVALID0x80",
- NULL };
-
-
-static char *map_flags(unsigned long flags, char *mapping[])
-{
- static char buffer[256];
- int index;
- int offset = 12;
-
- buffer[0] = '\0';
-
- for (index = 0; flags && mapping[index]; flags >>= 1, index++) {
- if (flags & 1) {
- if ((offset + strlen(mapping[index]) + 1) >= 80) {
- strcat(buffer, "\n ");
- offset = 12;
- } else if (offset > 12) {
- strcat(buffer, " ");
- offset++;
- }
- strcat(buffer, mapping[index]);
- offset += strlen(mapping[index]);
- }
- }
-
- return (buffer);
-}
-
-#ifdef __linux__
-
-static char *bp_flags(xfs_buf_flags_t bp_flag)
-{
- return(map_flags((unsigned long) bp_flag, bp_flag_vals));
-}
-
-static int
-kdbm_bp_flags(int argc, const char **argv, const char **envp, struct pt_regs *regs)
-{
- unsigned long flags;
- int diag;
-
- if (argc != 1)
- return KDB_ARGCOUNT;
-
- diag = kdbgetularg(argv[1], &flags);
- if (diag)
- return diag;
-
- kdb_printf("bp flags 0x%lx = %s\n", flags, bp_flags(flags));
-
- return 0;
-}
-
-static void
-print_xfs_buf(
- xfs_buf_t *bp,
- unsigned long addr)
-{
- unsigned long age = (xfs_buf_age_centisecs * HZ) / 100;
-
- kdb_printf("xfs_buf_t at 0x%lx\n", addr);
- kdb_printf(" b_flags %s\n", bp_flags(bp->b_flags));
- kdb_printf(" b_target 0x%p b_hold %d b_next 0x%p b_prev 0x%p\n",
- bp->b_target, bp->b_hold.counter,
- list_entry(bp->b_list.next, xfs_buf_t, b_list),
- list_entry(bp->b_list.prev, xfs_buf_t, b_list));
- kdb_printf(" b_hash 0x%p b_hash_next 0x%p b_hash_prev 0x%p\n",
- bp->b_hash,
- list_entry(bp->b_hash_list.next, xfs_buf_t, b_hash_list),
- list_entry(bp->b_hash_list.prev, xfs_buf_t, b_hash_list));
- kdb_printf(" b_file_offset 0x%llx b_buffer_length 0x%llx b_addr 0x%p\n",
- (unsigned long long) bp->b_file_offset,
- (unsigned long long) bp->b_buffer_length,
- bp->b_addr);
- kdb_printf(" b_bn 0x%llx b_count_desired 0x%lx b_locked %d\n",
- (unsigned long long)bp->b_bn,
- (unsigned long) bp->b_count_desired, (int)bp->b_locked);
- kdb_printf(" b_queuetime %ld (now=%ld/age=%ld) b_io_remaining %d\n",
- bp->b_queuetime, jiffies, bp->b_queuetime + age,
- bp->b_io_remaining.counter);
- kdb_printf(" b_page_count %u b_offset 0x%x b_pages 0x%p b_error %u\n",
- bp->b_page_count, bp->b_offset,
- bp->b_pages, bp->b_error);
- kdb_printf(" b_iodonesema (%d,%d) b_sema (%d,%d) b_pincount (%d)\n",
- bp->b_iodonesema.count.counter,
- bp->b_iodonesema.sleepers,
- bp->b_sema.count.counter, bp->b_sema.sleepers,
- bp->b_pin_count.counter);
-#ifdef XFS_BUF_LOCK_TRACKING
- kdb_printf(" last holder %d\n", bp->b_last_holder);
-#endif
- if (bp->b_fspriv || bp->b_fspriv2) {
- kdb_printf( " b_fspriv 0x%p b_fspriv2 0x%p\n",
- bp->b_fspriv, bp->b_fspriv2);
- }
-}
-
-static int
-kdbm_bp(int argc, const char **argv, const char **envp, struct pt_regs *regs)
-{
- xfs_buf_t bp;
- unsigned long addr;
- long offset=0;
- int nextarg;
- int diag;
-
- if (argc != 1)
- return KDB_ARGCOUNT;
-
- nextarg = 1;
- if ((diag = kdbgetaddrarg(argc, argv, &nextarg, &addr, &offset, NULL, regs)) ||
- (diag = kdb_getarea(bp, addr)))
- return diag;
-
- print_xfs_buf(&bp, addr);
-
- return 0;
-}
-
-static int
-kdbm_bpdelay(int argc, const char **argv, const char **envp,
- struct pt_regs *regs)
-{
-#ifdef DEBUG
- extern struct list_head xfs_buftarg_list;
- struct list_head *curr, *next;
- xfs_buftarg_t *tp, *n;
- xfs_buf_t bp;
- unsigned long addr, verbose = 0;
- int diag, count = 0;
-
- if (argc > 1)
- return KDB_ARGCOUNT;
-
- if (argc == 1) {
- if ((diag = kdbgetularg(argv[1], &verbose))) {
- return diag;
- }
- }
-
- if (!verbose) {
- kdb_printf("index bp pin queuetime\n");
- }
-
-
- list_for_each_entry_safe(tp, n, &xfs_buftarg_list, bt_list) {
- list_for_each_safe(curr, next, &tp->bt_delwrite_queue) {
- addr = (unsigned long)list_entry(curr, xfs_buf_t, b_list);
- if ((diag = kdb_getarea(bp, addr)))
- return diag;
-
- if (verbose) {
- print_xfs_buf(&bp, addr);
- } else {
- kdb_printf("%4d 0x%lx %d %ld\n",
- count++, addr,
- bp.b_pin_count.counter,
- bp.b_queuetime);
- }
- }
- }
-#else
- kdb_printf("bt_delwrite_queue inaccessible (non-debug)\n");
-#endif
- return 0;
-}
-#endif
-
-static int
-kdbm_iomap(int argc, const char **argv, const char **envp,
- struct pt_regs *regs)
-{
- xfs_iomap_t iomap;
- unsigned long addr;
- long offset=0;
- int nextarg;
- int diag;
-
- if (argc != 1)
- return KDB_ARGCOUNT;
-
- nextarg = 1;
- if ((diag = kdbgetaddrarg(argc, argv, &nextarg, &addr, &offset, NULL, regs)))
- return diag;
- if ((diag = kdb_getarea(iomap, addr)))
- return diag;
-
- kdb_printf("iomap_t at 0x%lx\n", addr);
- kdb_printf(" bn 0x%llx offset 0x%Lx delta 0x%lx bsize 0x%llx\n",
- (long long) iomap.iomap_bn, iomap.iomap_offset,
- (unsigned long)iomap.iomap_delta, (long long)iomap.iomap_bsize);
- kdb_printf(" iomap_flags %s\n",
- map_flags(iomap.iomap_flags, iomap_flag_vals));
-
- return 0;
-}
-
-static int
-kdbm_i2vnode(int argc, const char **argv, const char **envp,
- struct pt_regs *regs)
-{
- struct vnode vp;
- struct inode *ip;
- unsigned long addr;
- long offset=0;
- int nextarg;
- int diag;
-
- if (argc != 1)
- return KDB_ARGCOUNT;
-
- nextarg = 1;
- if ((diag = kdbgetaddrarg(argc, argv, &nextarg, &addr, &offset, NULL, regs)))
- return diag;
- ip = (struct inode *)addr;
- if ((diag = kdb_getarea(vp, (unsigned long)vn_from_inode(ip))))
- return diag;
-
- kdb_printf("--> Inode @ 0x%p\n", ip);
- printinode(ip);
-
- kdb_printf("--> Vnode @ 0x%p\n", vn_from_inode(ip));
- printvnode(&vp, (unsigned long)vn_from_inode(ip));
-
- return 0;
-}
-
-#ifdef XFS_BUF_TRACE
-static int xfs_buf_trace_entry(ktrace_entry_t *ktep)
-{
- unsigned long long daddr;
-
- daddr = ((unsigned long long)(unsigned long)ktep->val[8] << 32)
- | ((unsigned long long)(unsigned long)ktep->val[9]);
-
- kdb_printf("bp 0x%p [%s] (hold %lu lock %ld) data 0x%p",
- ktep->val[0],
- (char *)ktep->val[1],
- (unsigned long)ktep->val[3],
- (long)ktep->val[4],
- ktep->val[6]);
- kdb_symbol_print((unsigned long)ktep->val[7], NULL,
- KDB_SP_SPACEB|KDB_SP_PAREN|KDB_SP_NEWLINE);
- kdb_printf(" offset 0x%llx size 0x%lx task 0x%p\n",
- daddr, (long)ktep->val[10], ktep->val[5]);
- kdb_printf(" flags: %s\n", bp_flags((int)(long)ktep->val[2]));
- return 1;
-}
-
-static int
-kdbm_bptrace_offset(int argc, const char **argv, const char **envp,
- struct pt_regs *regs)
-{
- long mask = 0;
- unsigned long got_offset = 0, offset = 0;
- int diag;
- ktrace_entry_t *ktep;
- ktrace_snap_t kts;
-
- if (argc > 2)
- return KDB_ARGCOUNT;
-
- if (argc > 0) {
- diag = kdbgetularg(argv[1], &offset);
- if (diag)
- return diag;
- got_offset = 1; /* allows tracing offset zero */
- }
-
- if (argc > 1) {
- diag = kdbgetularg(argv[1], &mask); /* sign extent mask */
- if (diag)
- return diag;
- }
-
- ktep = ktrace_first(xfs_buf_trace_buf, &kts);
- do {
- unsigned long long daddr;
-
- if (ktep == NULL)
- break;
- daddr = ((unsigned long long)(unsigned long)ktep->val[8] << 32)
- | ((unsigned long long)(unsigned long)ktep->val[9]);
- if (got_offset && ((daddr & ~mask) != offset))
- continue;
- if (xfs_buf_trace_entry(ktep))
- kdb_printf("\n");
- } while ((ktep = ktrace_next(xfs_buf_trace_buf, &kts)) != NULL);
- return 0;
-}
-
-static int
-kdbm_bptrace(int argc, const char **argv, const char **envp,
- struct pt_regs *regs)
-{
- unsigned long addr = 0;
- int diag, nextarg;
- long offset = 0;
- char *event_match = NULL;
- ktrace_entry_t *ktep;
- ktrace_snap_t kts;
-
- if (argc > 1)
- return KDB_ARGCOUNT;
-
- if (argc == 1) {
- if (isupper(argv[1][0]) || islower(argv[1][0])) {
- event_match = (char *)argv[1];
- kdb_printf("event match on \"%s\"\n", event_match);
- argc = 0;
- } else {
- nextarg = 1;
- diag = kdbgetaddrarg(argc, argv,
- &nextarg, &addr, &offset, NULL, regs);
- if (diag) {
- kdb_printf("non-numeric arg: %s\n", argv[1]);
- return diag;
- }
- }
- }
-
- ktep = ktrace_first(xfs_buf_trace_buf, &kts);
- do {
- if (ktep == NULL)
- break;
- if (addr && (ktep->val[0] != (void *)addr))
- continue;
- if (event_match && strcmp((char *)ktep->val[1], event_match))
- continue;
- if (xfs_buf_trace_entry(ktep))
- qprintf("\n");
- } while ((ktep = ktrace_next(xfs_buf_trace_buf, &kts)) != NULL);
-
- return 0;
-}
-#endif
-
-struct xif {
- char *name;
- int (*func)(int, const char **, const char **, struct pt_regs *);
- char *args;
- char *help;
-};
-
-static struct xif xfsidbg_funcs[] = {
- { "bhv", kdbm_bhv, "<bhv>", "Dump bhv chain"},
- { "vn", kdbm_vn, "<vnode>", "Dump inode/vnode/trace"},
- { "vnode", kdbm_vnode, "<vnode>", "Dump vnode"},
- { "vfs", kdbm_vfs, "<vfs>", "Dump vfs"},
-#ifdef XFS_VNODE_TRACE
- { "vntrace", kdbm_vntrace, "<vntrace>", "Dump vnode Trace"},
- { "vntraceaddr", kdbm_vntraceaddr, "<vntrace>",
- "Dump vnode Trace by Address"},
-#endif
- { "xagf", kdbm_xfs_xagf, "<agf>",
- "Dump XFS allocation group freespace" },
- { "xagi", kdbm_xfs_xagi, "<agi>",
- "Dump XFS allocation group inode" },
- { "xail", kdbm_xfs_xaildump, "<xfs_mount_t>",
- "Dump XFS AIL for a mountpoint" },
-#ifdef XFS_ALLOC_TRACE
- { "xalatrc", kdbm_xfs_xalatrace, "<count>",
- "Dump XFS alloc count trace" },
- { "xalbtrc", kdbm_xfs_xalbtrace, "<xfs_agblock_t>",
- "Dump XFS alloc block trace" },
- { "xalgtrc", kdbm_xfs_xalgtrace, "<xfs_agnumber_t>",
- "Dump XFS alloc alloc-group trace" },
-#endif
-
- { "xalloc", kdbm_xfs_xalloc, "<xfs_alloc_arg_t>",
- "Dump XFS allocation args structure" },
-#ifdef XFS_ALLOC_TRACE
- { "xalmtrc", kdbm_xfs_xalmtrace, "<xfs_mount_t>",
- "Dump XFS alloc mount-point trace" },
- { "xalttrc", kdbm_xfs_xalttrace, "<tag>",
- "Dump XFS alloc trace by tag number" },
-#endif
- { "xarg", kdbm_xfs_xarg, "<value>",
- "Input XFS argument for next function" },
- { "xattrcx", kdbm_xfs_xattrcontext, "<xfs_attr_list_context_t>",
- "Dump XFS attr_list context struct"},
- { "xattrlf", kdbm_xfs_xattrleaf, "<xfs_attr_leafblock_t>",
- "Dump XFS attribute leaf block"},
- { "xattrsf", kdbm_xfs_xattrsf, "<xfs_attr_shortform_t>",
- "Dump XFS attribute shortform"},
-#ifdef XFS_ATTR_TRACE
- { "xattrtr", kdbm_xfs_xattrtrace, "<count>",
- "Dump XFS attribute attr_list() trace" },
-#endif
- { "xbirec", kdbm_xfs_xbirec, "<xfs_bmbt_irec_t",
- "Dump XFS bmap incore record"},
-#ifdef XFS_BLI_TRACE
- { "xblitrc", kdbm_xfs_xblitrace, "<xfs_buf_log_item_t>",
- "Dump XFS buf log item trace" },
-#endif
- { "xbmalla", kdbm_xfs_xbmalla, "<xfs_bmalloca_t>",
- "Dump XFS bmalloc args structure"},
-#ifdef XFS_BMAP_TRACE
- { "xbmatrc", kdbm_xfs_xbmatrace, "<count>",
- "Dump XFS bmap btree count trace" },
- { "xbmitrc", kdbm_xfs_xbmitrace, "<xfs_inode_t>",
- "Dump XFS bmap btree per-inode trace" },
- { "xbmstrc", kdbm_xfs_xbmstrace, "<xfs_inode_t>",
- "Dump XFS bmap btree inode trace" },
-#endif
- { "xbrec", kdbm_xfs_xbrec, "<xfs_bmbt_rec_64_t>",
- "Dump XFS bmap record"},
- { "xbroot", kdbm_xfs_xbroot, "<xfs_inode_t>",
- "Dump XFS bmap btree root (data)"},
- { "xbroota", kdbm_xfs_xbroota, "<xfs_inode_t>",
- "Dump XFS bmap btree root (attr)"},
- { "xbtcur", kdbm_xfs_xbtcur, "<xfs_btree_cur_t>",
- "Dump XFS btree cursor"},
- { "xbuf", kdbm_xfs_xbuf, "<xfs_buf_t>",
- "Dump XFS data from a buffer"},
-#ifdef XFS_BMAP_TRACE
- { "xbxatrc", kdbm_xfs_xbxatrace, "<count>",
- "Dump XFS bmap extent count trace" },
- { "xbxitrc", kdbm_xfs_xbxitrace, "<xfs_inode_t>",
- "Dump XFS bmap extent per-inode trace" },
- { "xbxstrc", kdbm_xfs_xbxstrace, "<xfs_inode_t>",
- "Dump XFS bmap extent inode trace" },
-#endif
- { "xchash", kdbm_xfs_xchash, "<xfs_mount_t>",
- "Dump XFS cluster hash"},
- { "xchlist", kdbm_xfs_xchashlist, "<xfs_chashlist_t>",
- "Dump XFS cluster hash list"},
- { "xchksum", kdbm_xfs_xchksum, "<addr>", "Dump chksum" },
-#ifdef XFS_DIR2_TRACE
- { "xd2atrc", kdbm_xfs_xdir2atrace, "<count>",
- "Dump XFS directory v2 count trace" },
-#endif
- { "xd2free", kdbm_xfs_xdir2free, "<xfs_dir2_free_t>",
- "Dump XFS directory v2 freemap"},
-#ifdef XFS_DIR2_TRACE
- { "xd2itrc", kdbm_xfs_xdir2itrace, "<xfs_inode_t>",
- "Dump XFS directory v2 per-inode trace" },
-#endif
- { "xdaargs", kdbm_xfs_xdaargs, "<xfs_da_args_t>",
- "Dump XFS dir/attr args structure"},
- { "xdabuf", kdbm_xfs_xdabuf, "<xfs_dabuf_t>",
- "Dump XFS dir/attr buf structure"},
- { "xdanode", kdbm_xfs_xdanode, "<xfs_da_intnode_t>",
- "Dump XFS dir/attr node block"},
- { "xdastat", kdbm_xfs_xdastate, "<xfs_da_state_t>",
- "Dump XFS dir/attr state_blk struct"},
- { "xdelay", kdbm_xfs_delayed_blocks, "<xfs_mount_t>",
- "Dump delayed block totals"},
- { "xdirlf", kdbm_xfs_xdirleaf, "<xfs_dir_leafblock_t>",
- "Dump XFS directory leaf block"},
- { "xdirsf", kdbm_xfs_xdirsf, "<xfs_dir_shortform_t>",
- "Dump XFS directory shortform"},
- { "xdir2sf", kdbm_xfs_xdir2sf, "<xfs_dir2_sf_t>",
- "Dump XFS directory v2 shortform"},
-#ifdef XFS_DIR_TRACE
- { "xdirtrc", kdbm_xfs_xdirtrace, "<count>",
- "Dump XFS directory getdents() trace" },
-#endif
- { "xdiskdq", kdbm_xfs_xqm_diskdq, "<xfs_disk_dquot_t>",
- "Dump XFS ondisk dquot (quota) struct"},
- { "xdqatt", kdbm_xfs_xqm_dqattached_inos, "<xfs_mount_t>",
- "All incore inodes with dquots"},
- { "xdqinfo", kdbm_xfs_xqm_tpdqinfo, "<xfs_trans_t>",
- "Dump dqinfo structure of a trans"},
-#ifdef XFS_DQUOT_TRACE
- { "xdqtrace",kdbm_xfs_xqm_dqtrace, "<xfs_dquot_t>",
- "Dump trace of a given dquot" },
-#endif
- { "xdquot", kdbm_xfs_xqm_dquot, "<xfs_dquot_t>",
- "Dump XFS dquot (quota) structure"},
- { "xexlist", kdbm_xfs_xexlist, "<xfs_inode_t>",
- "Dump XFS bmap extents in inode"},
- { "xflist", kdbm_xfs_xflist, "<xfs_bmap_free_t>",
- "Dump XFS to-be-freed extent records"},
- { "xhelp", kdbm_xfs_xhelp, "",
- "Print idbg-xfs help"},
- { "xicall", kdbm_xfs_xiclogall, "<xlog_in_core_t>",
- "Dump All XFS in-core logs"},
- { "xiclog", kdbm_xfs_xiclog, "<xlog_in_core_t>",
- "Dump XFS in-core log"},
-#ifdef XFS_LOG_TRACE
- { "xictrc", kdbm_xfs_xiclogtrace, "<xlog_in_core_t>",
- "Dump XFS in-core log trace" },
-#endif
- { "xihash", kdbm_xfs_xihash, "<xfs_mount_t>",
- "Dump XFS inode hash statistics"},
-#ifdef XFS_ILOCK_TRACE
- { "xilocktrc",kdbm_xfs_xilock_trace, "<xfs_inode_t>",
- "Dump XFS ilock trace" },
- { "xailcktrc",kdbm_xfs_xailock_trace,"<count>",
- "Dump XFS global ilock trace" },
-#endif
- { "xinodes", kdbm_xfs_xinodes, "<xfs_mount_t>",
- "Dump XFS inodes per mount"},
- { "xquiesce",kdbm_xfs_xinodes_quiesce, "<xfs_mount_t>",
- "Dump non-quiesced XFS inodes per mount"},
-#ifdef XFS_LOG_TRACE
- { "xl_grtr", kdbm_xfs_xlog_granttrace, "<xlog_t>",
- "Dump XFS log grant trace" },
-#endif
- { "xl_rcit", kdbm_xfs_xlog_ritem, "<xlog_recover_item_t>",
- "Dump XFS recovery item"},
- { "xl_rctr", kdbm_xfs_xlog_rtrans, "<xlog_recover_t>",
- "Dump XFS recovery transaction"},
- { "xl_rctr2",kdbm_xfs_xlog_rtrans_entire, "<xlog_recover_t>",
- "Dump entire recovery transaction"},
- { "xl_tic", kdbm_xfs_xlog_tic, "<xlog_ticket_t>",
- "Dump XFS log ticket"},
- { "xlog", kdbm_xfs_xlog, "<xlog_t>",
- "Dump XFS log"},
- { "xlogcb", kdbm_xfs_xiclogcb, "<xlog_in_core_t>",
- "Dump XFS in-core log callbacks"},
- { "xlogitm", kdbm_xfs_xlogitem, "<xfs_log_item_t>",
- "Dump XFS log item structure"},
- { "xmount", kdbm_xfs_xmount, "<xfs_mount_t>",
- "Dump XFS mount structure"},
- { "xnode", kdbm_xfs_xnode, "<xfs_inode_t>",
- "Dump XFS inode"},
- { "xiocore", kdbm_xfs_xcore, "<xfs_iocore_t>",
- "Dump XFS iocore"},
- { "xperag", kdbm_xfs_xperag, "<xfs_mount_t>",
- "Dump XFS per-allocation group data"},
- { "xqinfo", kdbm_xfs_xqm_qinfo, "<xfs_mount_t>",
- "Dump mount->m_quotainfo structure"},
-#ifdef CONFIG_XFS_QUOTA
- { "xqm", kdbm_xfs_xqm, "",
- "Dump XFS quota manager structure"},
- { "xqmfree", kdbm_xfs_xqm_freelist, "",
- "Dump XFS global freelist of dquots"},
- { "xqmhtab", kdbm_xfs_xqm_htab, "",
- "Dump XFS hashtable of dquots"},
-#endif /* CONFIG_XFS_QUOTA */
- { "xqmplist",kdbm_xfs_xqm_mplist, "<xfs_mount_t>",
- "Dump XFS all dquots of a f/s"},
-#ifdef XFS_RW_TRACE
- { "xrwtrc", kdbm_xfs_xrwtrace, "<xfs_inode_t>",
- "Dump XFS inode read/write trace" },
-#endif
- { "xsb", kdbm_xfs_xsb, "<xfs_sb_t> <cnv>",
- "Dump XFS superblock"},
- { "xtp", kdbm_xfs_xtp, "<xfs_trans_t>",
- "Dump XFS transaction structure"},
- { "xtrres", kdbm_xfs_xtrans_res, "<xfs_mount_t>",
- "Dump XFS reservation values"},
- { NULL, NULL, NULL }
-};
-
-static struct xif xfsbuf_funcs[] = {
- { "bp", kdbm_bp, "<vaddr>", "Display xfs_buf_t" },
- { "bpflags", kdbm_bp_flags, "<flags>", "Display xfs_buf flags" },
- { "xiomap", kdbm_iomap, "<xfs_iomap_t *>", "Display IOmap" },
- { "i2vnode", kdbm_i2vnode, "<inode *>", "Display Vnode" },
- { "bpdelay", kdbm_bpdelay, "0|1", "Display delwri buffers" },
-#ifdef XFS_BUF_TRACE
- { "bptrace", kdbm_bptrace, "<vaddr>|<count>", "xfs_buf_t trace" },
- { "bpoffset",kdbm_bptrace_offset, "<daddr> [<mask>]","xfs_buf_t trace" },
-#endif
- { NULL, NULL, NULL }
-};
-
-static int
-xfsidbg_init(void)
-{
- struct xif *p;
-
- for (p = xfsidbg_funcs; p->name; p++)
- kdb_register(p->name, p->func, p->args, p->help, 0);
- for (p = xfsbuf_funcs; p->name; p++)
- kdb_register(p->name, p->func, p->args, p->help, 0);
- return 0;
-}
-
-static void
-xfsidbg_exit(void)
-{
- struct xif *p;
-
- for (p = xfsidbg_funcs; p->name; p++)
- kdb_unregister(p->name);
- for (p = xfsbuf_funcs; p->name; p++)
- kdb_unregister(p->name);
-}
-
-/*
- * Argument to xfs_alloc routines, for allocation type.
- */
-static char *xfs_alloctype[] = {
- "any_ag", "first_ag", "start_ag", "this_ag",
- "start_bno", "near_bno", "this_bno"
-};
-
-/*
- * Static functions.
- */
-
-#ifdef XFS_ALLOC_TRACE
-/*
- * Print xfs alloc trace buffer entry.
- */
-static int
-xfs_alloc_trace_entry(ktrace_entry_t *ktep)
-{
- static char *modagf_flags[] = {
- "magicnum",
- "versionnum",
- "seqno",
- "length",
- "roots",
- "levels",
- "flfirst",
- "fllast",
- "flcount",
- "freeblks",
- "longest",
- NULL
- };
-
- if (((__psint_t)ktep->val[0] & 0xffff) == 0)
- return 0;
- switch ((long)ktep->val[0] & 0xffffL) {
- case XFS_ALLOC_KTRACE_ALLOC:
- kdb_printf("alloc %s[%s %ld] mp 0x%p\n",
- (char *)ktep->val[1],
- ktep->val[2] ? (char *)ktep->val[2] : "",
- (long)ktep->val[0] >> 16,
- (xfs_mount_t *)ktep->val[3]);
- kdb_printf(
- "agno %ld agbno %ld minlen %ld maxlen %ld mod %ld prod %ld minleft %ld\n",
- (long)ktep->val[4],
- (long)ktep->val[5],
- (long)ktep->val[6],
- (long)ktep->val[7],
- (long)ktep->val[8],
- (long)ktep->val[9],
- (long)ktep->val[10]);
- kdb_printf("total %ld alignment %ld len %ld type %s otype %s\n",
- (long)ktep->val[11],
- (long)ktep->val[12],
- (long)ktep->val[13],
- xfs_alloctype[((__psint_t)ktep->val[14]) >> 16],
- xfs_alloctype[((__psint_t)ktep->val[14]) & 0xffff]);
- kdb_printf("wasdel %d wasfromfl %d isfl %d userdata %d\n",
- ((__psint_t)ktep->val[15] & (1 << 3)) != 0,
- ((__psint_t)ktep->val[15] & (1 << 2)) != 0,
- ((__psint_t)ktep->val[15] & (1 << 1)) != 0,
- ((__psint_t)ktep->val[15] & (1 << 0)) != 0);
- break;
- case XFS_ALLOC_KTRACE_FREE:
- kdb_printf("free %s[%s %ld] mp 0x%p\n",
- (char *)ktep->val[1],
- ktep->val[2] ? (char *)ktep->val[2] : "",
- (long)ktep->val[0] >> 16,
- (xfs_mount_t *)ktep->val[3]);
- kdb_printf("agno %ld agbno %ld len %ld isfl %d\n",
- (long)ktep->val[4],
- (long)ktep->val[5],
- (long)ktep->val[6],
- (__psint_t)ktep->val[7] != 0);
- break;
- case XFS_ALLOC_KTRACE_MODAGF:
- kdb_printf("modagf %s[%s %ld] mp 0x%p\n",
- (char *)ktep->val[1],
- ktep->val[2] ? (char *)ktep->val[2] : "",
- (long)ktep->val[0] >> 16,
- (xfs_mount_t *)ktep->val[3]);
- printflags((__psint_t)ktep->val[4], modagf_flags, "modified");
- kdb_printf("seqno %lu length %lu roots b %lu c %lu\n",
- (unsigned long)ktep->val[5],
- (unsigned long)ktep->val[6],
- (unsigned long)ktep->val[7],
- (unsigned long)ktep->val[8]);
- kdb_printf("levels b %lu c %lu flfirst %lu fllast %lu flcount %lu\n",
- (unsigned long)ktep->val[9],
- (unsigned long)ktep->val[10],
- (unsigned long)ktep->val[11],
- (unsigned long)ktep->val[12],
- (unsigned long)ktep->val[13]);
- kdb_printf("freeblks %lu longest %lu\n",
- (unsigned long)ktep->val[14],
- (unsigned long)ktep->val[15]);
- break;
-
- case XFS_ALLOC_KTRACE_UNBUSY:
- kdb_printf("unbusy %s [%s %ld] mp 0x%p\n",
- (char *)ktep->val[1],
- ktep->val[2] ? (char *)ktep->val[2] : "",
- (long)ktep->val[0] >> 16,
- (xfs_mount_t *)ktep->val[3]);
- kdb_printf(" agno %lu slot %lu tp 0x%p\n",
- (unsigned long)ktep->val[4],
- (unsigned long)ktep->val[7],
- (xfs_trans_t *)ktep->val[8]);
- break;
- case XFS_ALLOC_KTRACE_BUSY:
- kdb_printf("busy %s [%s %ld] mp 0x%p\n",
- (char *)ktep->val[1],
- ktep->val[2] ? (char *)ktep->val[2] : "",
- (long)ktep->val[0] >> 16,
- (xfs_mount_t *)ktep->val[3]);
- kdb_printf(" agno %lu agbno %lu len %lu slot %lu tp 0x%p\n",
- (unsigned long)ktep->val[4],
- (unsigned long)ktep->val[5],
- (unsigned long)ktep->val[6],
- (unsigned long)ktep->val[7],
- (xfs_trans_t *)ktep->val[8]);
- break;
- case XFS_ALLOC_KTRACE_BUSYSEARCH:
- kdb_printf("busy-search %s [%s %ld] mp 0x%p\n",
- (char *)ktep->val[1],
- ktep->val[2] ? (char *)ktep->val[2] : "",
- (long)ktep->val[0] >> 16,
- (xfs_mount_t *)ktep->val[3]);
- kdb_printf(" agno %ld agbno %ld len %ld slot %ld tp 0x%p\n",
- (unsigned long)ktep->val[4],
- (unsigned long)ktep->val[5],
- (unsigned long)ktep->val[6],
- (unsigned long)ktep->val[7],
- (xfs_trans_t *)ktep->val[8]);
- break;
- default:
- kdb_printf("unknown alloc trace record\n");
- break;
- }
- return 1;
-}
-#endif /* XFS_ALLOC_TRACE */
-
-#ifdef XFS_ATTR_TRACE
-/*
- * Print an attribute trace buffer entry.
- */
-static int
-xfs_attr_trace_entry(ktrace_entry_t *ktep)
-{
- static char *attr_arg_flags[] = {
- "DONTFOLLOW", /* 0x0001 */
- "ROOT", /* 0x0002 */
- "TRUSTED", /* 0x0004 */
- "SECURE", /* 0x0008 */
- "CREATE", /* 0x0010 */
- "REPLACE", /* 0x0020 */
- "?", /* 0x0040 */
- "?", /* 0x0080 */
- "SYSTEM", /* 0x0100 */
- "?", /* 0x0200 */
- "?", /* 0x0400 */
- "?", /* 0x0800 */
- "KERNOTIME", /* 0x1000 */
- "KERNOVAL", /* 0x2000 */
- "KERNAMELS", /* 0x4000 */
- "KERNFULLS", /* 0x8000 */
- NULL
- };
-
- if (!ktep->val[0])
- return 0;
-
- qprintf("-- %s: cursor h/b/o 0x%lx/0x%lx/%lu, dupcnt %lu, dp 0x%p\n",
- (char *)ktep->val[1],
- (unsigned long)ktep->val[3],
- (unsigned long)ktep->val[4],
- (unsigned long)ktep->val[5],
- (unsigned long)ktep->val[11],
- (xfs_inode_t *)ktep->val[2]);
- qprintf(" alist 0x%p, size %lu, count %lu, firstu %lu, Llen %lu",
- (attrlist_t *)ktep->val[6],
- (unsigned long)ktep->val[7],
- (unsigned long)ktep->val[8],
- (unsigned long)ktep->val[9],
- (unsigned long)ktep->val[10]);
- printflags((__psunsigned_t)(ktep->val[12]), attr_arg_flags, ", flags");
- qprintf("\n");
-
- switch ((__psint_t)ktep->val[0]) {
- case XFS_ATTR_KTRACE_L_C:
- break;
- case XFS_ATTR_KTRACE_L_CN:
- qprintf(" node: count %lu, 1st hash 0x%lx, last hash 0x%lx\n",
- (unsigned long)ktep->val[13],
- (unsigned long)ktep->val[14],
- (unsigned long)ktep->val[15]);
- break;
- case XFS_ATTR_KTRACE_L_CB:
- qprintf(" btree: hash 0x%lx, blkno 0x%lx\n",
- (unsigned long)ktep->val[13],
- (unsigned long)ktep->val[14]);
- break;
- case XFS_ATTR_KTRACE_L_CL:
- qprintf(" leaf: count %ld, 1st hash 0x%lx, last hash 0x%lx\n",
- (unsigned long)ktep->val[13],
- (unsigned long)ktep->val[14],
- (unsigned long)ktep->val[15]);
- break;
- default:
- qprintf(" unknown attr trace record format\n");
- break;
- }
- return 1;
-}
-#endif /* XFS_ATTR_TRACE */
-
-#ifdef XFS_BMAP_TRACE
-/*
- * Print xfs bmap extent trace buffer entry.
- */
-static int
-xfs_bmap_trace_entry(ktrace_entry_t *ktep)
-{
- xfs_dfsbno_t b;
- xfs_dfilblks_t c;
- xfs_inode_t *ip;
- xfs_ino_t ino;
- xfs_dfiloff_t o;
- int flag;
- int opcode;
- static char *ops[] = { "del", "ins", "pre", "post" };
- xfs_bmbt_rec_32_t r;
- int whichfork;
-
- opcode = ((__psint_t)ktep->val[0]) & 0xffff;
- if (opcode == 0)
- return 0;
- whichfork = ((__psint_t)ktep->val[0]) >> 16;
- ip = (xfs_inode_t *)ktep->val[3];
- ino = ((xfs_ino_t)(unsigned long)ktep->val[6] << 32) |
- ((xfs_ino_t)(unsigned long)ktep->val[7]);
- qprintf("%s %s:%s ip %p ino %s %cf\n",
- ops[opcode - 1], (char *)ktep->val[1],
- (char *)ktep->val[2], ip, xfs_fmtino(ino, ip->i_mount),
- "da"[whichfork]);
- r.l0 = (xfs_bmbt_rec_base_t)(unsigned long)ktep->val[8];
- r.l1 = (xfs_bmbt_rec_base_t)(unsigned long)ktep->val[9];
- r.l2 = (xfs_bmbt_rec_base_t)(unsigned long)ktep->val[10];
- r.l3 = (xfs_bmbt_rec_base_t)(unsigned long)ktep->val[11];
- xfs_convert_extent(&r, &o, &b, &c, &flag);
- qprintf(" idx %ld offset %lld block %s",
- (long)ktep->val[4], o,
- xfs_fmtfsblock((xfs_fsblock_t)b, ip->i_mount));
- qprintf(" count %lld flag %d\n", c, flag);
- if ((__psint_t)ktep->val[5] != 2)
- return 1;
- r.l0 = (xfs_bmbt_rec_base_t)(unsigned long)ktep->val[12];
- r.l1 = (xfs_bmbt_rec_base_t)(unsigned long)ktep->val[13];
- r.l2 = (xfs_bmbt_rec_base_t)(unsigned long)ktep->val[14];
- r.l3 = (xfs_bmbt_rec_base_t)(unsigned long)ktep->val[15];
- xfs_convert_extent(&r, &o, &b, &c, &flag);
- qprintf(" offset %lld block %s", o,
- xfs_fmtfsblock((xfs_fsblock_t)b, ip->i_mount));
- qprintf(" count %lld flag %d\n", c, flag);
- return 1;
-}
-
-/*
- * Print xfs bmap btree trace buffer entry.
- */
-static int
-xfs_bmbt_trace_entry(
- ktrace_entry_t *ktep)
-{
- int line;
- xfs_bmbt_rec_32_t r;
- xfs_bmbt_irec_t s;
- int type;
- int whichfork;
-
- type = (__psint_t)ktep->val[0] & 0xff;
- if (type == 0)
- return 0;
- whichfork = ((__psint_t)ktep->val[0] >> 8) & 0xff;
- line = ((__psint_t)ktep->val[0] >> 16) & 0xffff;
- qprintf("%s[%s@%d] ip 0x%p %cf cur 0x%p\n",
- (char *)ktep->val[1],
- (char *)ktep->val[2],
- line,
- (xfs_inode_t *)ktep->val[3],
- "da"[whichfork],
- (xfs_btree_cur_t *)ktep->val[4]);
- switch (type) {
- case XFS_BMBT_KTRACE_ARGBI:
- qprintf(" buf 0x%p i %ld\n",
- (xfs_buf_t *)ktep->val[5],
- (long)ktep->val[6]);
- break;
- case XFS_BMBT_KTRACE_ARGBII:
- qprintf(" buf 0x%p i0 %ld i1 %ld\n",
- (xfs_buf_t *)ktep->val[5],
- (long)ktep->val[6],
- (long)ktep->val[7]);
- break;
- case XFS_BMBT_KTRACE_ARGFFFI:
- qprintf(" o 0x%x%08x b 0x%x%08x i 0x%x%08x j %ld\n",
- (unsigned int)(long)ktep->val[5],
- (unsigned int)(long)ktep->val[6],
- (unsigned int)(long)ktep->val[7],
- (unsigned int)(long)ktep->val[8],
- (unsigned int)(long)ktep->val[9],
- (unsigned int)(long)ktep->val[10],
- (long)ktep->val[11]);
- break;
- case XFS_BMBT_KTRACE_ARGI:
- qprintf(" i 0x%lx\n",
- (long)ktep->val[5]);
- break;
- case XFS_BMBT_KTRACE_ARGIFK:
- qprintf(" i 0x%lx f 0x%x%08x o 0x%x%08x\n",
- (long)ktep->val[5],
- (unsigned int)(long)ktep->val[6],
- (unsigned int)(long)ktep->val[7],
- (unsigned int)(long)ktep->val[8],
- (unsigned int)(long)ktep->val[9]);
- break;
- case XFS_BMBT_KTRACE_ARGIFR:
- qprintf(" i 0x%lx f 0x%x%08x ",
- (long)ktep->val[5],
- (unsigned int)(long)ktep->val[6],
- (unsigned int)(long)ktep->val[7]);
- s.br_startoff = (xfs_fileoff_t)
- (((xfs_dfiloff_t)(unsigned long)ktep->val[8] << 32) |
- (xfs_dfiloff_t)(unsigned long)ktep->val[9]);
- s.br_startblock = (xfs_fsblock_t)
- (((xfs_dfsbno_t)(unsigned long)ktep->val[10] << 32) |
- (xfs_dfsbno_t)(unsigned long)ktep->val[11]);
- s.br_blockcount = (xfs_filblks_t)
- (((xfs_dfilblks_t)(unsigned long)ktep->val[12] << 32) |
- (xfs_dfilblks_t)(unsigned long)ktep->val[13]);
- xfsidbg_xbirec(&s);
- break;
- case XFS_BMBT_KTRACE_ARGIK:
- qprintf(" i 0x%lx o 0x%x%08x\n",
- (long)ktep->val[5],
- (unsigned int)(long)ktep->val[6],
- (unsigned int)(long)ktep->val[7]);
- break;
- case XFS_BMBT_KTRACE_CUR:
- qprintf(" nlevels %ld flags %ld allocated %ld ",
- ((long)ktep->val[5] >> 24) & 0xff,
- ((long)ktep->val[5] >> 16) & 0xff,
- (long)ktep->val[5] & 0xffff);
- r.l0 = (xfs_bmbt_rec_base_t)(unsigned long)ktep->val[6];
- r.l1 = (xfs_bmbt_rec_base_t)(unsigned long)ktep->val[7];
- r.l2 = (xfs_bmbt_rec_base_t)(unsigned long)ktep->val[8];
- r.l3 = (xfs_bmbt_rec_base_t)(unsigned long)ktep->val[9];
- xfsidbg_xbrec((xfs_bmbt_rec_64_t *)&r);
- qprintf(" bufs 0x%p 0x%p 0x%p 0x%p ",
- (xfs_buf_t *)ktep->val[10],
- (xfs_buf_t *)ktep->val[11],
- (xfs_buf_t *)ktep->val[12],
- (xfs_buf_t *)ktep->val[13]);
- qprintf("ptrs %ld %ld %ld %ld\n",
- (long)ktep->val[14] >> 16,
- (long)ktep->val[14] & 0xffff,
- (long)ktep->val[15] >> 16,
- (long)ktep->val[15] & 0xffff);
- break;
- default:
- qprintf("unknown bmbt trace record\n");
- break;
- }
- return 1;
-}
-#endif
-
-/*
- * Print an xfs in-inode bmap btree root.
- */
-static void
-xfs_broot(xfs_inode_t *ip, xfs_ifork_t *f)
-{
- xfs_bmbt_block_t *broot;
- int format;
- int i;
- xfs_bmbt_key_t *kp;
- xfs_bmbt_ptr_t *pp;
-
- format = f == &ip->i_df ? ip->i_d.di_format : ip->i_d.di_aformat;
- if ((f->if_flags & XFS_IFBROOT) == 0 ||
- format != XFS_DINODE_FMT_BTREE) {
- kdb_printf("inode 0x%p not btree format\n", ip);
- return;
- }
- broot = f->if_broot;
- kdb_printf("block @0x%p magic %x level %d numrecs %d\n",
- broot,
- be32_to_cpu(broot->bb_magic),
- be16_to_cpu(broot->bb_level),
- be16_to_cpu(broot->bb_numrecs));
- kp = XFS_BMAP_BROOT_KEY_ADDR(broot, 1, f->if_broot_bytes);
- pp = XFS_BMAP_BROOT_PTR_ADDR(broot, 1, f->if_broot_bytes);
- for (i = 1; i <= be16_to_cpu(broot->bb_numrecs); i++)
- kdb_printf("\t%d: startoff %Ld ptr %Lx %s\n",
- i, INT_GET(kp[i - 1].br_startoff, ARCH_CONVERT), INT_GET(pp[i - 1], ARCH_CONVERT),
- xfs_fmtfsblock(INT_GET(pp[i - 1], ARCH_CONVERT), ip->i_mount));
-}
-
-/*
- * Print allocation btree block.
- */
-static void
-xfs_btalloc(xfs_alloc_block_t *bt, int bsz)
-{
- int i;
-
- kdb_printf("magic 0x%x level %d numrecs %d leftsib 0x%x rightsib 0x%x\n",
- be32_to_cpu(bt->bb_magic),
- be16_to_cpu(bt->bb_level),
- be16_to_cpu(bt->bb_numrecs),
- be32_to_cpu(bt->bb_leftsib),
- be32_to_cpu(bt->bb_rightsib));
- if (!bt->bb_level) {
- for (i = 1; i <= be16_to_cpu(bt->bb_numrecs); i++) {
- xfs_alloc_rec_t *r;
-
- r = XFS_BTREE_REC_ADDR(bsz, xfs_alloc, bt, i, 0);
- kdb_printf("rec %d startblock 0x%x blockcount %d\n",
- i,
- be32_to_cpu(r->ar_startblock),
- be32_to_cpu(r->ar_blockcount));
- }
- } else {
- int mxr;
-
- mxr = XFS_BTREE_BLOCK_MAXRECS(bsz, xfs_alloc, 0);
- for (i = 1; i <= be16_to_cpu(bt->bb_numrecs); i++) {
- xfs_alloc_key_t *k;
- xfs_alloc_ptr_t *p;
-
- k = XFS_BTREE_KEY_ADDR(bsz, xfs_alloc, bt, i, mxr);
- p = XFS_BTREE_PTR_ADDR(bsz, xfs_alloc, bt, i, mxr);
- kdb_printf("key %d startblock 0x%x blockcount %d ptr 0x%x\n",
- i,
- be32_to_cpu(k->ar_startblock),
- be32_to_cpu(k->ar_blockcount),
- be32_to_cpu(*p));
- }
- }
-}
-
-/*
- * Print a bmap btree block.
- */
-static void
-xfs_btbmap(xfs_bmbt_block_t *bt, int bsz)
-{
- int i;
-
- kdb_printf("magic 0x%x level %d numrecs %d leftsib %Lx rightsib %Lx\n",
- be32_to_cpu(bt->bb_magic),
- be16_to_cpu(bt->bb_level),
- be16_to_cpu(bt->bb_numrecs),
- be64_to_cpu(bt->bb_leftsib),
- be64_to_cpu(bt->bb_rightsib));
- if (!bt->bb_level) {
- for (i = 1; i <= be16_to_cpu(bt->bb_numrecs); i++) {
- xfs_bmbt_rec_t *r;
- xfs_bmbt_irec_t irec;
-
- r = (xfs_bmbt_rec_t *)XFS_BTREE_REC_ADDR(bsz,
- xfs_bmbt, bt, i, 0);
-
- xfs_bmbt_disk_get_all((xfs_bmbt_rec_t *)r, &irec);
- kdb_printf("rec %d startoff %Ld startblock %Lx blockcount %Ld flag %d\n",
- i, irec.br_startoff,
- (__uint64_t)irec.br_startblock,
- irec.br_blockcount, irec.br_state);
- }
- } else {
- int mxr;
-
- mxr = XFS_BTREE_BLOCK_MAXRECS(bsz, xfs_bmbt, 0);
- for (i = 1; i <= be16_to_cpu(bt->bb_numrecs); i++) {
- xfs_bmbt_key_t *k;
- xfs_bmbt_ptr_t *p;
-
- k = XFS_BTREE_KEY_ADDR(bsz, xfs_bmbt, bt, i, mxr);
- p = XFS_BTREE_PTR_ADDR(bsz, xfs_bmbt, bt, i, mxr);
- kdb_printf("key %d startoff %Ld ",
- i, INT_GET(k->br_startoff, ARCH_CONVERT));
- kdb_printf("ptr %Lx\n", INT_GET(*p, ARCH_CONVERT));
- }
- }
-}
-
-/*
- * Print an inode btree block.
- */
-static void
-xfs_btino(xfs_inobt_block_t *bt, int bsz)
-{
- int i;
-
- kdb_printf("magic 0x%x level %d numrecs %d leftsib 0x%x rightsib 0x%x\n",
- be32_to_cpu(bt->bb_magic),
- be16_to_cpu(bt->bb_level),
- be16_to_cpu(bt->bb_numrecs),
- be32_to_cpu(bt->bb_leftsib),
- be32_to_cpu(bt->bb_rightsib));
- if (!bt->bb_level) {
- for (i = 1; i <= be16_to_cpu(bt->bb_numrecs); i++) {
- xfs_inobt_rec_t *r;
-
- r = XFS_BTREE_REC_ADDR(bsz, xfs_inobt, bt, i, 0);
- kdb_printf("rec %d startino 0x%x freecount %d, free %Lx\n",
- i, INT_GET(r->ir_startino, ARCH_CONVERT),
- INT_GET(r->ir_freecount, ARCH_CONVERT),
- INT_GET(r->ir_free, ARCH_CONVERT));
- }
- } else {
- int mxr;
-
- mxr = XFS_BTREE_BLOCK_MAXRECS(bsz, xfs_inobt, 0);
- for (i = 1; i <= be16_to_cpu(bt->bb_numrecs); i++) {
- xfs_inobt_key_t *k;
- xfs_inobt_ptr_t *p;
-
- k = XFS_BTREE_KEY_ADDR(bsz, xfs_inobt, bt, i, mxr);
- p = XFS_BTREE_PTR_ADDR(bsz, xfs_inobt, bt, i, mxr);
- kdb_printf("key %d startino 0x%x ptr 0x%x\n",
- i, INT_GET(k->ir_startino, ARCH_CONVERT),
- be32_to_cpu(*p));
- }
- }
-}
-
-/*
- * Print a buf log item.
- */
-static void
-xfs_buf_item_print(xfs_buf_log_item_t *blip, int summary)
-{
- static char *bli_flags[] = {
- "hold", /* 0x1 */
- "dirty", /* 0x2 */
- "stale", /* 0x4 */
- "logged", /* 0x8 */
- "ialloc", /* 0x10 */
- "inode_stale", /* 0x20 */
- NULL
- };
- static char *blf_flags[] = {
- "inode", /* 0x1 */
- "cancel", /* 0x2 */
- NULL
- };
-
- if (summary) {
- kdb_printf("buf 0x%p blkno 0x%Lx ", blip->bli_buf,
- blip->bli_format.blf_blkno);
- printflags(blip->bli_flags, bli_flags, "flags:");
- kdb_printf("\n ");
- xfsidbg_xbuf_real(blip->bli_buf, 1);
- return;
- }
- kdb_printf("buf 0x%p recur %d refcount %d flags:",
- blip->bli_buf, blip->bli_recur,
- atomic_read(&blip->bli_refcount));
- printflags(blip->bli_flags, bli_flags, NULL);
- kdb_printf("\n");
- kdb_printf("size %d blkno 0x%Lx len 0x%x map size %d map 0x%p\n",
- blip->bli_format.blf_size, blip->bli_format.blf_blkno,
- (uint) blip->bli_format.blf_len, blip->bli_format.blf_map_size,
- &(blip->bli_format.blf_data_map[0]));
- kdb_printf("blf flags: ");
- printflags((uint)blip->bli_format.blf_flags, blf_flags, NULL);
-#ifdef XFS_TRANS_DEBUG
- kdb_printf("orig 0x%x logged 0x%x",
- blip->bli_orig, blip->bli_logged);
-#endif
- kdb_printf("\n");
-}
-
-#ifdef XFS_BMAP_TRACE
-/*
- * Convert an external extent descriptor to internal form.
- */
-static void
-xfs_convert_extent(xfs_bmbt_rec_32_t *rp, xfs_dfiloff_t *op, xfs_dfsbno_t *sp,
- xfs_dfilblks_t *cp, int *fp)
-{
- xfs_dfiloff_t o;
- xfs_dfsbno_t s;
- xfs_dfilblks_t c;
- int flag;
-
- flag = (((xfs_dfiloff_t)rp->l0) >> 31) & 1;
- o = ((((xfs_dfiloff_t)rp->l0) & 0x7fffffff) << 23) |
- (((xfs_dfiloff_t)rp->l1) >> 9);
- s = (((xfs_dfsbno_t)(rp->l1 & 0x000001ff)) << 43) |
- (((xfs_dfsbno_t)rp->l2) << 11) |
- (((xfs_dfsbno_t)rp->l3) >> 21);
- c = (xfs_dfilblks_t)(rp->l3 & 0x001fffff);
- *op = o;
- *sp = s;
- *cp = c;
- *fp = flag;
-}
-#endif
-
-#ifdef XFS_RW_TRACE
-/*
- * Print itrunc entry trace.
- */
-static void
-xfs_ctrunc_trace_entry(ktrace_entry_t *ktep)
-{
- qprintf("ip 0x%p cpu %ld\n",
- (xfs_inode_t *)(unsigned long)ktep->val[1], (long)ktep->val[2]);
-}
-#endif
-
-/*
- * Print an xfs_da_state_path structure.
- */
-static void
-xfs_dastate_path(xfs_da_state_path_t *p)
-{
- int i;
-
- kdb_printf("active %d\n", p->active);
- for (i = 0; i < XFS_DA_NODE_MAXDEPTH; i++) {
- kdb_printf(" blk %d bp 0x%p blkno 0x%x",
- i, p->blk[i].bp, p->blk[i].blkno);
- kdb_printf(" index %d hashval 0x%x ",
- p->blk[i].index, (uint_t)p->blk[i].hashval);
- switch(p->blk[i].magic) {
- case XFS_DA_NODE_MAGIC: kdb_printf("NODE\n"); break;
- case XFS_DIR_LEAF_MAGIC: kdb_printf("DIR\n"); break;
- case XFS_ATTR_LEAF_MAGIC: kdb_printf("ATTR\n"); break;
- case XFS_DIR2_LEAFN_MAGIC: kdb_printf("DIR2\n"); break;
- default: kdb_printf("type ?\n"); break;
- }
- }
-}
-
-#ifdef XFS_DIR_TRACE
-/*
- * Print a xfs directory trace buffer entry.
- */
-static int
-xfs_dir_trace_entry(ktrace_entry_t *ktep)
-{
- xfs_mount_t *mp;
- __uint32_t hash;
- xfs_off_t cookie;
-
- if (!ktep->val[0] || !ktep->val[1])
- return 0;
-
- mp = (xfs_mount_t *)ktep->val[3];
- cookie = (__psunsigned_t)ktep->val[4];
- cookie <<= 32;
- cookie |= (__psunsigned_t)ktep->val[5];
- qprintf("%s -- dp=0x%p b/e/h=%ld/%ld/0x%08lx resid=0x%lx ",
- (char *)ktep->val[1],
- (xfs_inode_t *)ktep->val[2],
- (long)XFS_DA_COOKIE_BNO(mp, cookie),
- (long)XFS_DA_COOKIE_ENTRY(mp, cookie),
- (unsigned long)XFS_DA_COOKIE_HASH(mp, cookie),
- (long)ktep->val[6]);
-
- switch ((__psint_t)ktep->val[0]) {
- case XFS_DIR_KTRACE_G_DU:
- break;
- case XFS_DIR_KTRACE_G_DUB:
- qprintf("bno=%ld", (long)ktep->val[7]);
- break;
- case XFS_DIR_KTRACE_G_DUN:
- qprintf("forw=%ld, cnt=%ld, 0x%08lx - 0x%08lx",
- (long)ktep->val[7],
- (long)ktep->val[8],
- (unsigned long)ktep->val[9],
- (unsigned long)ktep->val[10]);
- break;
- case XFS_DIR_KTRACE_G_DUL:
- qprintf("forw=%ld, cnt=%ld, 0x%08lx - 0x%08lx",
- (long)ktep->val[7],
- (long)ktep->val[8],
- (unsigned long)ktep->val[9],
- (unsigned long)ktep->val[10]);
- break;
- case XFS_DIR_KTRACE_G_DUE:
- qprintf("entry hashval 0x%08lx", (unsigned long)ktep->val[7]);
- break;
- case XFS_DIR_KTRACE_G_DUC:
- cookie = (__psunsigned_t)ktep->val[7];
- cookie <<= 32;
- cookie |= (__psunsigned_t)ktep->val[8];
- hash = XFS_DA_COOKIE_HASH(mp, cookie);
- qprintf("b/e/h=%ld/%ld/0x%08x",
- (long)XFS_DA_COOKIE_BNO(mp, cookie),
- (long)XFS_DA_COOKIE_ENTRY(mp, cookie),
- hash);
- break;
- default:
- qprintf("unknown dir trace record format");
- break;
- }
- return 1;
-}
-#endif
-
-#ifdef XFS_DIR2_TRACE
-/*
- * Print a xfs v2 directory trace buffer entry.
- */
-static int
-xfs_dir2_trace_entry(ktrace_entry_t *ktep)
-{
- char *cp;
- int i;
- int len;
-
- if (!ktep->val[0])
- return 0;
- cp = (char *)&ktep->val[10];
- qprintf("%s: '", (char *)ktep->val[1]);
- len = min((__psint_t)ktep->val[9], (__psint_t)sizeof(ktep->val[10])*6);
- for (i = 0; i < len; i++)
- qprintf("%c", cp[i]);
- qprintf("'(%ld)", (long)ktep->val[9]);
- if ((__psunsigned_t)ktep->val[0] != XFS_DIR2_KTRACE_ARGS_BIBII)
- qprintf(" hashval 0x%llx inumber %lld dp 0x%p tp 0x%p check %d",
- (__uint64_t)(unsigned long)ktep->val[2],
- (__int64_t)(unsigned long)ktep->val[3],
- ktep->val[4], ktep->val[5],
- (int)(__psint_t)ktep->val[6]);
- switch ((__psunsigned_t)ktep->val[0]) {
- case XFS_DIR2_KTRACE_ARGS:
- break;
- case XFS_DIR2_KTRACE_ARGS_B:
- qprintf(" bp 0x%p", ktep->val[7]);
- break;
- case XFS_DIR2_KTRACE_ARGS_BB:
- qprintf(" lbp 0x%p dbp 0x%p", ktep->val[7], ktep->val[8]);
- break;
- case XFS_DIR2_KTRACE_ARGS_BIBII:
- qprintf(" dp 0x%p tp 0x%p srcbp 0x%p srci %d dstbp 0x%p dsti %d count %d",
- ktep->val[2], ktep->val[3], ktep->val[4],
- (int)(__psint_t)ktep->val[5], ktep->val[6],
- (int)(__psint_t)ktep->val[7],
- (int)(__psint_t)ktep->val[8]);
- break;
- case XFS_DIR2_KTRACE_ARGS_DB:
- qprintf(" db 0x%x bp 0x%p",
- (xfs_dir2_db_t)(unsigned long)ktep->val[7],
- ktep->val[8]);
- break;
- case XFS_DIR2_KTRACE_ARGS_I:
- qprintf(" i 0x%lx", (unsigned long)ktep->val[7]);
- break;
- case XFS_DIR2_KTRACE_ARGS_S:
- qprintf(" s 0x%x", (int)(__psint_t)ktep->val[7]);
- break;
- case XFS_DIR2_KTRACE_ARGS_SB:
- qprintf(" s 0x%x bp 0x%p", (int)(__psint_t)ktep->val[7],
- ktep->val[8]);
- break;
- default:
- qprintf("unknown dirv2 trace record format");
- break;
- }
- return 1;
-}
-#endif
-
-/*
- * Print an efd log item.
- */
-static void
-xfs_efd_item_print(xfs_efd_log_item_t *efdp, int summary)
-{
- int i;
- xfs_extent_t *ep;
-
- if (summary) {
- kdb_printf("Extent Free Done: ID 0x%Lx nextents %d (at 0x%p)\n",
- efdp->efd_format.efd_efi_id,
- efdp->efd_format.efd_nextents, efdp);
- return;
- }
- kdb_printf("size %d nextents %d next extent %d efip 0x%p\n",
- efdp->efd_format.efd_size, efdp->efd_format.efd_nextents,
- efdp->efd_next_extent, efdp->efd_efip);
- kdb_printf("efi_id 0x%Lx\n", efdp->efd_format.efd_efi_id);
- kdb_printf("efd extents:\n");
- ep = &(efdp->efd_format.efd_extents[0]);
- for (i = 0; i < efdp->efd_next_extent; i++, ep++) {
- kdb_printf(" block %Lx len %d\n",
- ep->ext_start, ep->ext_len);
- }
-}
-
-/*
- * Print an efi log item.
- */
-static void
-xfs_efi_item_print(xfs_efi_log_item_t *efip, int summary)
-{
- int i;
- xfs_extent_t *ep;
- static char *efi_flags[] = {
- "recovered", /* 0x1 */
- "committed", /* 0x2 */
- "cancelled", /* 0x4 */
- NULL,
- };
-
- if (summary) {
- kdb_printf("Extent Free Intention: ID 0x%Lx nextents %d (at 0x%p)\n",
- efip->efi_format.efi_id,
- efip->efi_format.efi_nextents, efip);
- return;
- }
- kdb_printf("size %d nextents %d next extent %d\n",
- efip->efi_format.efi_size, efip->efi_format.efi_nextents,
- efip->efi_next_extent);
- kdb_printf("id %Lx", efip->efi_format.efi_id);
- printflags(efip->efi_flags, efi_flags, "flags :");
- kdb_printf("\n");
- kdb_printf("efi extents:\n");
- ep = &(efip->efi_format.efi_extents[0]);
- for (i = 0; i < efip->efi_next_extent; i++, ep++) {
- kdb_printf(" block %Lx len %d\n",
- ep->ext_start, ep->ext_len);
- }
-}
-
-/*
- * Format inode "format" into a static buffer & return it.
- */
-static char *
-xfs_fmtformat(xfs_dinode_fmt_t f)
-{
- static char *t[] = {
- "dev",
- "local",
- "extents",
- "btree",
- "uuid"
- };
-
- return t[f];
-}
-
-/*
- * Format fsblock number into a static buffer & return it.
- */
-char *
-xfs_fmtfsblock(xfs_fsblock_t bno, xfs_mount_t *mp)
-{
- static char rval[50];
-
- if (bno == NULLFSBLOCK)
- sprintf(rval, "NULLFSBLOCK");
- else if (ISNULLSTARTBLOCK(bno))
- sprintf(rval, "NULLSTARTBLOCK(%Ld)", STARTBLOCKVAL(bno));
- else if (mp)
- sprintf(rval, "%Ld[%x:%x]", (xfs_dfsbno_t)bno,
- XFS_FSB_TO_AGNO(mp, bno), XFS_FSB_TO_AGBNO(mp, bno));
- else
- sprintf(rval, "%Ld", (xfs_dfsbno_t)bno);
- return rval;
-}
-
-/*
- * Format inode number into a static buffer & return it.
- */
-static char *
-xfs_fmtino(xfs_ino_t ino, xfs_mount_t *mp)
-{
- static char rval[50];
-
- if (mp)
- sprintf(rval, "%llu[%x:%x:%x]",
- (unsigned long long) ino,
- XFS_INO_TO_AGNO(mp, ino),
- XFS_INO_TO_AGBNO(mp, ino),
- XFS_INO_TO_OFFSET(mp, ino));
- else
- sprintf(rval, "%llu", (unsigned long long) ino);
- return rval;
-}
-
-/*
- * Format an lsn for printing into a static buffer & return it.
- */
-static char *
-xfs_fmtlsn(xfs_lsn_t *lsnp)
-{
- uint *wordp;
- uint *word2p;
- static char buf[20];
-
- wordp = (uint *)lsnp;
- word2p = wordp++;
- sprintf(buf, "[%u:%u]", *wordp, *word2p);
-
- return buf;
-}
-
-/*
- * Format file mode into a static buffer & return it.
- */
-static char *
-xfs_fmtmode(int m)
-{
- static char rval[16];
-
- sprintf(rval, "%c%c%c%c%c%c%c%c%c%c%c%c%c",
- "?fc?dxb?r?l?S?m?"[(m & S_IFMT) >> 12],
- m & S_ISUID ? 'u' : '-',
- m & S_ISGID ? 'g' : '-',
- m & S_ISVTX ? 'v' : '-',
- m & S_IRUSR ? 'r' : '-',
- m & S_IWUSR ? 'w' : '-',
- m & S_IXUSR ? 'x' : '-',
- m & S_IRGRP ? 'r' : '-',
- m & S_IWGRP ? 'w' : '-',
- m & S_IXGRP ? 'x' : '-',
- m & S_IROTH ? 'r' : '-',
- m & S_IWOTH ? 'w' : '-',
- m & S_IXOTH ? 'x' : '-');
- return rval;
-}
-
-/*
- * Format a size into a static buffer & return it.
- */
-static char *
-xfs_fmtsize(size_t i)
-{
- static char rval[20];
-
- /* size_t is 32 bits in 32-bit kernel, 64 bits in 64-bit kernel */
- sprintf(rval, "0x%lx", (unsigned long) i);
- return rval;
-}
-
-/*
- * Format a uuid into a static buffer & return it.
- */
-static char *
-xfs_fmtuuid(uuid_t *uu)
-{
- static char rval[40];
- char *o = rval;
- char *i = (unsigned char*)uu;
- int b;
-
- for (b=0;b<16;b++) {
- o+=sprintf(o, "%02x", *i++);
- if (b==3||b==5||b==7||b==9) *o++='-';
- }
- *o='\0';
-
- return rval;
-}
-
-/*
- * Print an inode log item.
- */
-static void
-xfs_inode_item_print(xfs_inode_log_item_t *ilip, int summary)
-{
- static char *ili_flags[] = {
- "hold", /* 0x1 */
- "iolock excl", /* 0x2 */
- "iolock shrd", /* 0x4 */
- NULL
- };
- static char *ilf_fields[] = {
- "core", /* 0x001 */
- "ddata", /* 0x002 */
- "dexts", /* 0x004 */
- "dbroot", /* 0x008 */
- "dev", /* 0x010 */
- "uuid", /* 0x020 */
- "adata", /* 0x040 */
- "aext", /* 0x080 */
- "abroot", /* 0x100 */
- NULL
- };
-
- if (summary) {
- kdb_printf("inode 0x%p logged %d ",
- ilip->ili_inode, ilip->ili_logged);
- printflags(ilip->ili_flags, ili_flags, "flags:");
- printflags(ilip->ili_format.ilf_fields, ilf_fields, "format:");
- printflags(ilip->ili_last_fields, ilf_fields, "lastfield:");
- kdb_printf("\n");
- return;
- }
- kdb_printf("inode 0x%p ino 0x%llu pushbuf %d logged %d flags: ",
- ilip->ili_inode, (unsigned long long) ilip->ili_format.ilf_ino,
- ilip->ili_pushbuf_flag, ilip->ili_logged);
- printflags(ilip->ili_flags, ili_flags, NULL);
- kdb_printf("\n");
- kdb_printf("ilock recur %d iolock recur %d ext buf 0x%p\n",
- ilip->ili_ilock_recur, ilip->ili_iolock_recur,
- ilip->ili_extents_buf);
-#ifdef XFS_TRANS_DEBUG
- kdb_printf("root bytes %d root orig 0x%x\n",
- ilip->ili_root_size, ilip->ili_orig_root);
-#endif
- kdb_printf("size %d ", ilip->ili_format.ilf_size);
- printflags(ilip->ili_format.ilf_fields, ilf_fields, "fields:");
- printflags(ilip->ili_last_fields, ilf_fields, " last fields: ");
- kdb_printf("\n");
- kdb_printf(" flush lsn %s last lsn %s\n",
- xfs_fmtlsn(&(ilip->ili_flush_lsn)),
- xfs_fmtlsn(&(ilip->ili_last_lsn)));
- kdb_printf("dsize %d, asize %d, rdev 0x%x\n",
- ilip->ili_format.ilf_dsize,
- ilip->ili_format.ilf_asize,
- ilip->ili_format.ilf_u.ilfu_rdev);
- kdb_printf("blkno 0x%Lx len 0x%x boffset 0x%x\n",
- ilip->ili_format.ilf_blkno,
- ilip->ili_format.ilf_len,
- ilip->ili_format.ilf_boffset);
-}
-
-/*
- * Print a dquot log item.
- */
-/* ARGSUSED */
-static void
-xfs_dquot_item_print(xfs_dq_logitem_t *lip, int summary)
-{
- kdb_printf("dquot 0x%p\n",
- lip->qli_dquot);
-
-}
-
-/*
- * Print a quotaoff log item.
- */
-/* ARGSUSED */
-static void
-xfs_qoff_item_print(xfs_qoff_logitem_t *lip, int summary)
-{
- kdb_printf("start qoff item 0x%p flags 0x%x\n",
- lip->qql_start_lip, lip->qql_format.qf_flags);
-
-}
-
-/*
- * Print buffer full of inodes.
- */
-static void
-xfs_inodebuf(xfs_buf_t *bp)
-{
- xfs_dinode_t *di;
- xfs_dinode_core_t dic;
- int n, i;
-
- n = XFS_BUF_COUNT(bp) >> 8;
- for (i = 0; i < n; i++) {
- di = (xfs_dinode_t *)xfs_buf_offset(bp,
- i * 256);
-
- xfs_xlate_dinode_core((xfs_caddr_t)&di->di_core, &dic, 1);
- xfs_prdinode_core(&dic);
- kdb_printf("next_unlinked 0x%x u@0x%p\n",
- INT_GET(di->di_next_unlinked, ARCH_CONVERT),
- &di->di_u);
- }
-}
-
-#ifdef XFS_RW_TRACE
-/*
- * Print iomap entry trace.
- */
-static void
-xfs_iomap_enter_trace_entry(ktrace_entry_t *ktep)
-{
- qprintf("ip 0x%p size 0x%x%x offset 0x%x%x count 0x%x\n",
- ktep->val[1],
- (unsigned int)(long)ktep->val[2],
- (unsigned int)(long)ktep->val[3],
- (unsigned int)(long)ktep->val[4],
- (unsigned int)(long)ktep->val[5],
- (unsigned int)(long)ktep->val[6]);
- qprintf("io new size 0x%x%x pid=%d\n",
- (unsigned int)(long)ktep->val[7],
- (unsigned int)(long)ktep->val[8],
- (unsigned int)(long)ktep->val[9]);
-}
-
-/*
- * Print iomap map trace.
- */
-static void
-xfs_iomap_map_trace_entry(ktrace_entry_t *ktep)
-{
- static char *bmapi_flags[] = {
- "read", /* BMAPI_READ */
- "write", /* BMAPI_WRITE */
- "allocate", /* BMAPI_ALLOCATE */
- "unwritten", /* BMAPI_UNWRITTEN */
- "ignstate", /* BMAPI_IGNSTATE */
- "direct", /* BMAPI_DIRECT */
- "mmap", /* BMAPI_MMAP */
- "sync", /* BMAPI_SYNC */
- "trylock", /* BMAPI_TRYLOCK */
- "device", /* BMAPI_DEVICE */
- NULL
- };
-
- qprintf("ip 0x%p size 0x%x%x offset 0x%x%x count 0x%x\n",
- ktep->val[1],
- (unsigned int)(long)ktep->val[2],
- (unsigned int)(long)ktep->val[3],
- (unsigned int)(long)ktep->val[4],
- (unsigned int)(long)ktep->val[5],
- (unsigned int)(long)ktep->val[6]);
- printflags((__psint_t)ktep->val[7], bmapi_flags, "bmapi flags");
- qprintf("iomap off 0x%x%x delta 0x%x bsize 0x%x bno 0x%x\n",
- (unsigned int)(long)ktep->val[8],
- (unsigned int)(long)ktep->val[9],
- (unsigned int)(long)ktep->val[10],
- (unsigned int)(long)ktep->val[11],
- (unsigned int)(long)ktep->val[12]);
- qprintf("imap off 0x%x count 0x%x block 0x%x\n",
- (unsigned int)(long)ktep->val[13],
- (unsigned int)(long)ktep->val[14],
- (unsigned int)(long)ktep->val[15]);
-}
-
-/*
- * Print itrunc entry trace.
- */
-static void
-xfs_itrunc_trace_entry(ktrace_entry_t *ktep)
-{
- qprintf("ip 0x%p size 0x%x%x flag %ld new size 0x%x%x\n",
- ktep->val[1],
- (unsigned int)(long)ktep->val[2],
- (unsigned int)(long)ktep->val[3],
- (long)ktep->val[4],
- (unsigned int)(long)ktep->val[5],
- (unsigned int)(long)ktep->val[6]);
- qprintf("toss start 0x%x%x toss finish 0x%x%x cpu id %ld pid %d\n",
- (unsigned int)(long)ktep->val[7],
- (unsigned int)(long)ktep->val[8],
- (unsigned int)(long)ktep->val[9],
- (unsigned int)(long)ktep->val[10],
- (long)ktep->val[11],
- (unsigned int)(long)ktep->val[12]);
-}
-
-/*
- * Print bunmap entry trace.
- */
-static void
-xfs_bunmap_trace_entry(ktrace_entry_t *ktep)
-{
- static char *bunmapi_flags[] = {
- "write", /* 0x01 */
- "delay", /* 0x02 */
- "entire", /* 0x04 */
- "metadata", /* 0x08 */
- "exact", /* 0x10 */
- "attrfork", /* 0x20 */
- "async", /* 0x40 */
- "rsvblocks", /* 0x80 */
- NULL
- };
-
- qprintf("ip 0x%p size 0x%x%x bno 0x%x%x len 0x%x cpu id %ld\n",
- ktep->val[1],
- (unsigned int)(long)ktep->val[2],
- (unsigned int)(long)ktep->val[3],
- (unsigned int)(long)ktep->val[4],
- (unsigned int)(long)ktep->val[5],
- (unsigned int)(long)ktep->val[6],
- (long)ktep->val[8]);
- qprintf("ra 0x%p pid %d ", ktep->val[9], (int)(long)ktep->val[10]);
- printflags((__psint_t)ktep->val[7], bunmapi_flags, "flags");
-}
-
-/*
- * Print inval_cached_pages entry trace.
- */
-static void
-xfs_inval_cached_trace_entry(ktrace_entry_t *ktep)
-{
- qprintf("ip 0x%p offset 0x%x%x len 0x%x%x first 0x%x%x last 0x%x%x pid %d\n",
- ktep->val[1],
- (unsigned int)(long)ktep->val[2],
- (unsigned int)(long)ktep->val[3],
- (unsigned int)(long)ktep->val[4],
- (unsigned int)(long)ktep->val[5],
- (unsigned int)(long)ktep->val[6],
- (unsigned int)(long)ktep->val[7],
- (unsigned int)(long)ktep->val[8],
- (unsigned int)(long)ktep->val[9],
- (unsigned int)(long)ktep->val[10]);
-}
-#endif
-
-
-/*
- * Print disk inode core.
- */
-static void
-xfs_prdinode_core(xfs_dinode_core_t *dip)
-{
- static char *diflags[] = {
- "realtime", /* XFS_DIFLAG_REALTIME */
- "prealloc", /* XFS_DIFLAG_PREALLOC */
- "newrtbm", /* XFS_DIFLAG_NEWRTBM */
- "immutable", /* XFS_DIFLAG_IMMUTABLE */
- "append", /* XFS_DIFLAG_APPEND */
- "sync", /* XFS_DIFLAG_SYNC */
- "noatime", /* XFS_DIFLAG_NOATIME */
- "nodump", /* XFS_DIFLAG_NODUMP */
- "rtinherit", /* XFS_DIFLAG_RTINHERIT */
- "projinherit", /* XFS_DIFLAG_PROJINHERIT */
- "nosymlinks", /* XFS_DIFLAG_NOSYMLINKS */
- "extsize", /* XFS_DIFLAG_EXTSIZE */
- "extszinherit", /* XFS_DIFLAG_EXTSZINHERIT */
- NULL
- };
-
- kdb_printf("magic 0x%x mode 0%o (%s) version 0x%x format 0x%x (%s)\n",
- dip->di_magic, dip->di_mode,
- xfs_fmtmode(dip->di_mode),
- dip->di_version, dip->di_format,
- xfs_fmtformat((xfs_dinode_fmt_t)dip->di_format));
- kdb_printf("nlink %d uid %d gid %d projid %d flushiter %u\n",
- dip->di_nlink,
- dip->di_uid,
- dip->di_gid,
- (uint)dip->di_projid,
- (uint)dip->di_flushiter);
- kdb_printf("atime %u:%u mtime %ud:%u ctime %u:%u\n",
- dip->di_atime.t_sec, dip->di_atime.t_nsec,
- dip->di_mtime.t_sec, dip->di_mtime.t_nsec,
- dip->di_ctime.t_sec, dip->di_ctime.t_nsec);
- kdb_printf("size %Ld ", dip->di_size);
- kdb_printf("nblocks %Ld extsize 0x%x nextents 0x%x anextents 0x%x\n",
- dip->di_nblocks, dip->di_extsize, dip->di_nextents,
- dip->di_anextents);
- kdb_printf("forkoff %d aformat 0x%x (%s) dmevmask 0x%x dmstate 0x%x ",
- dip->di_forkoff, dip->di_aformat,
- xfs_fmtformat((xfs_dinode_fmt_t)dip->di_aformat),
- dip->di_dmevmask, dip->di_dmstate);
- printflags(dip->di_flags, diflags, "flags");
- kdb_printf("gen 0x%x\n", dip->di_gen);
-}
-
-#ifdef XFS_RW_TRACE
-/*
- * Print read/write entry trace.
- */
-static void
-xfs_rw_enter_trace_entry(ktrace_entry_t *ktep)
-{
- qprintf("ip 0x%p size 0x%x%x ptr 0x%p size %lu\n",
- ktep->val[1],
- (unsigned int)(long)ktep->val[2],
- (unsigned int)(long)ktep->val[3],
- ktep->val[4],
- (unsigned long)ktep->val[5]);
- qprintf("io offset 0x%x%x ioflags 0x%x new size 0x%x%x pid %d\n",
- (unsigned int)(long)ktep->val[6],
- (unsigned int)(long)ktep->val[7],
- (unsigned int)(long)ktep->val[8],
- (unsigned int)(long)ktep->val[9],
- (unsigned int)(long)ktep->val[10],
- (unsigned int)(long)ktep->val[11]);
-}
-
-/*
- * Print page write/release trace.
- */
-static void
-xfs_page_trace_entry(ktrace_entry_t *ktep)
-{
- qprintf("ip 0x%p inode 0x%p page 0x%p\n",
- ktep->val[1], ktep->val[2], ktep->val[3]);
- qprintf("mask 0x%x di_size 0x%x%x isize 0x%x%x offset 0x%x%x\n",
- (unsigned int)(long)ktep->val[4],
- (unsigned int)(long)ktep->val[5],
- (unsigned int)(long)ktep->val[6],
- (unsigned int)(long)ktep->val[7],
- (unsigned int)(long)ktep->val[8],
- (unsigned int)(long)ktep->val[9],
- (unsigned int)(long)ktep->val[10]);
- qprintf("delalloc %d unmapped %d unwritten %d pid %d\n",
- (unsigned int)(long)ktep->val[11],
- (unsigned int)(long)ktep->val[12],
- (unsigned int)(long)ktep->val[13],
- (unsigned int)(long)ktep->val[14]);
-}
-
-/*
- * Print read/write trace entry.
- */
-static int
-xfs_rw_trace_entry(ktrace_entry_t *ktep)
-{
- switch ( (long)ktep->val[0] ) {
- case XFS_READ_ENTER:
- qprintf("READ ENTER:\n");
- xfs_rw_enter_trace_entry(ktep);
- break;
- case XFS_WRITE_ENTER:
- qprintf("WRITE ENTER:\n");
- xfs_rw_enter_trace_entry(ktep);
- break;
- case XFS_SENDFILE_ENTER:
- qprintf("SENDFILE ENTER:\n");
- xfs_rw_enter_trace_entry(ktep);
- break;
- case XFS_IOMAP_READ_ENTER:
- qprintf("IOMAP READ ENTER:\n");
- xfs_iomap_enter_trace_entry(ktep);
- break;
- case XFS_IOMAP_WRITE_ENTER:
- qprintf("IOMAP WRITE ENTER:\n");
- xfs_iomap_enter_trace_entry(ktep);
- break;
- case XFS_IOMAP_WRITE_NOSPACE:
- qprintf("IOMAP WRITE NOSPACE:\n");
- xfs_iomap_enter_trace_entry(ktep);
- break;
- case XFS_IOMAP_READ_MAP:
- qprintf("IOMAP READ MAP:\n");
- xfs_iomap_map_trace_entry(ktep);
- break;
- case XFS_IOMAP_WRITE_MAP:
- qprintf("IOMAP WRITE MAP:\n");
- xfs_iomap_map_trace_entry(ktep);
- break;
- case XFS_ITRUNC_START:
- qprintf("ITRUNC START:\n");
- xfs_itrunc_trace_entry(ktep);
- break;
- case XFS_ITRUNC_FINISH1:
- qprintf("ITRUNC FINISH1:\n");
- xfs_itrunc_trace_entry(ktep);
- break;
- case XFS_ITRUNC_FINISH2:
- qprintf("ITRUNC FINISH2:\n");
- xfs_itrunc_trace_entry(ktep);
- break;
- case XFS_CTRUNC1:
- qprintf("CTRUNC1:\n");
- xfs_ctrunc_trace_entry(ktep);
- break;
- case XFS_CTRUNC2:
- qprintf("CTRUNC2:\n");
- xfs_ctrunc_trace_entry(ktep);
- break;
- case XFS_CTRUNC3:
- qprintf("CTRUNC3:\n");
- xfs_ctrunc_trace_entry(ktep);
- break;
- case XFS_CTRUNC4:
- qprintf("CTRUNC4:\n");
- xfs_ctrunc_trace_entry(ktep);
- break;
- case XFS_CTRUNC5:
- qprintf("CTRUNC5:\n");
- xfs_ctrunc_trace_entry(ktep);
- break;
- case XFS_CTRUNC6:
- qprintf("CTRUNC6:\n");
- xfs_ctrunc_trace_entry(ktep);
- break;
- case XFS_BUNMAP:
- qprintf("BUNMAP:\n");
- xfs_bunmap_trace_entry(ktep);
- break;
- case XFS_INVAL_CACHED:
- qprintf("INVAL CACHED:\n");
- xfs_inval_cached_trace_entry(ktep);
- break;
- case XFS_DIORD_ENTER:
- qprintf("DIORD ENTER:\n");
- xfs_rw_enter_trace_entry(ktep);
- break;
- case XFS_DIOWR_ENTER:
- qprintf("DIOWR ENTER:\n");
- xfs_rw_enter_trace_entry(ktep);
- break;
- case XFS_WRITEPAGE_ENTER:
- qprintf("PAGE WRITE:\n");
- xfs_page_trace_entry(ktep);
- break;
- case XFS_RELEASEPAGE_ENTER:
- qprintf("PAGE RELEASE:\n");
- xfs_page_trace_entry(ktep);
- break;
- case XFS_INVALIDPAGE_ENTER:
- qprintf("PAGE INVALIDATE:\n");
- xfs_page_trace_entry(ktep);
- break;
- case XFS_IOMAP_ALLOC_ENTER:
- qprintf("ALLOC ENTER:\n");
- xfs_iomap_enter_trace_entry(ktep);
- break;
- case XFS_IOMAP_ALLOC_MAP:
- qprintf("ALLOC MAP:\n");
- xfs_iomap_map_trace_entry(ktep);
- break;
- case XFS_IOMAP_UNWRITTEN:
- qprintf("UNWRITTEN:\n");
- xfs_iomap_enter_trace_entry(ktep);
- break;
-
- default:
- qprintf("UNKNOWN RW TRACE\n");
- return 0;
- }
-
- return 1;
-}
-#endif
-
-/*
- * Print xfs extent records for a fork.
- */
-static void
-xfs_xexlist_fork(xfs_inode_t *ip, int whichfork)
-{
- int nextents, i;
- xfs_ifork_t *ifp;
- xfs_bmbt_irec_t irec;
-
- ifp = XFS_IFORK_PTR(ip, whichfork);
- if (ifp->if_flags & XFS_IFEXTENTS) {
- nextents = ifp->if_bytes / (uint)sizeof(xfs_bmbt_rec_t);
- kdb_printf("inode 0x%p %cf extents 0x%p nextents 0x%x\n",
- ip, "da"[whichfork], xfs_iext_get_ext(ifp, 0),
- nextents);
- for (i = 0; i < nextents; i++) {
- xfs_bmbt_get_all(xfs_iext_get_ext(ifp, i), &irec);
- kdb_printf(
- "%d: startoff %Ld startblock %s blockcount %Ld flag %d\n",
- i, irec.br_startoff,
- xfs_fmtfsblock(irec.br_startblock, ip->i_mount),
- irec.br_blockcount, irec.br_state);
- }
- }
-}
-
-static void
-xfs_xnode_fork(char *name, xfs_ifork_t *f)
-{
- static char *tab_flags[] = {
- "inline", /* XFS_IFINLINE */
- "extents", /* XFS_IFEXTENTS */
- "broot", /* XFS_IFBROOT */
- NULL
- };
- int *p;
-
- kdb_printf("%s fork", name);
- if (f == NULL) {
- kdb_printf(" empty\n");
- return;
- } else
- kdb_printf("\n");
- kdb_printf(" bytes %s ", xfs_fmtsize(f->if_bytes));
- kdb_printf("real_bytes %s lastex 0x%x u1:%s 0x%p\n",
- xfs_fmtsize(f->if_real_bytes), f->if_lastex,
- f->if_flags & XFS_IFINLINE ? "data" : "extents",
- f->if_flags & XFS_IFINLINE ?
- f->if_u1.if_data :
- (char *)f->if_u1.if_extents);
- kdb_printf(" broot 0x%p broot_bytes %s ext_max %d ",
- f->if_broot, xfs_fmtsize(f->if_broot_bytes), f->if_ext_max);
- printflags(f->if_flags, tab_flags, "flags");
- kdb_printf("\n");
- kdb_printf(" u2");
- for (p = (int *)&f->if_u2;
- p < (int *)((char *)&f->if_u2 + XFS_INLINE_DATA);
- p++)
- kdb_printf(" 0x%x", *p);
- kdb_printf("\n");
-}
-
-/*
- * Command-level xfs-idbg functions.
- */
-
-/*
- * Print xfs allocation group freespace header.
- */
-static void
-xfsidbg_xagf(xfs_agf_t *agf)
-{
- kdb_printf("magicnum 0x%x versionnum 0x%x seqno 0x%x length 0x%x\n",
- be32_to_cpu(agf->agf_magicnum),
- be32_to_cpu(agf->agf_versionnum),
- be32_to_cpu(agf->agf_seqno),
- be32_to_cpu(agf->agf_length));
- kdb_printf("roots b 0x%x c 0x%x levels b %d c %d\n",
- be32_to_cpu(agf->agf_roots[XFS_BTNUM_BNO]),
- be32_to_cpu(agf->agf_roots[XFS_BTNUM_CNT]),
- be32_to_cpu(agf->agf_levels[XFS_BTNUM_BNO]),
- be32_to_cpu(agf->agf_levels[XFS_BTNUM_CNT]));
- kdb_printf("flfirst %d fllast %d flcount %d freeblks %d longest %d\n",
- be32_to_cpu(agf->agf_flfirst),
- be32_to_cpu(agf->agf_fllast),
- be32_to_cpu(agf->agf_flcount),
- be32_to_cpu(agf->agf_freeblks),
- be32_to_cpu(agf->agf_longest));
-}
-
-/*
- * Print xfs allocation group inode header.
- */
-static void
-xfsidbg_xagi(xfs_agi_t *agi)
-{
- int i;
- int j;
-
- kdb_printf("magicnum 0x%x versionnum 0x%x seqno 0x%x length 0x%x\n",
- be32_to_cpu(agi->agi_magicnum),
- be32_to_cpu(agi->agi_versionnum),
- be32_to_cpu(agi->agi_seqno),
- be32_to_cpu(agi->agi_length));
- kdb_printf("count 0x%x root 0x%x level 0x%x\n",
- be32_to_cpu(agi->agi_count),
- be32_to_cpu(agi->agi_root),
- be32_to_cpu(agi->agi_level));
- kdb_printf("freecount 0x%x newino 0x%x dirino 0x%x\n",
- be32_to_cpu(agi->agi_freecount),
- be32_to_cpu(agi->agi_newino),
- be32_to_cpu(agi->agi_dirino));
-
- kdb_printf("unlinked buckets\n");
- for (i = 0; i < XFS_AGI_UNLINKED_BUCKETS; i++) {
- for (j = 0; j < 4; j++, i++) {
- kdb_printf("0x%08x ",
- be32_to_cpu(agi->agi_unlinked[i]));
- }
- kdb_printf("\n");
- }
-}
-
-#ifdef XFS_ALLOC_TRACE
-/*
- * Print out the last "count" entries in the allocation trace buffer.
- */
-static void
-xfsidbg_xalatrace(int count)
-{
- ktrace_entry_t *ktep;
- ktrace_snap_t kts;
- int nentries;
- int skip_entries;
-
- if (xfs_alloc_trace_buf == NULL) {
- qprintf("The xfs alloc trace buffer is not initialized\n");
- return;
- }
- nentries = ktrace_nentries(xfs_alloc_trace_buf);
- if (count == -1) {
- count = nentries;
- }
- if ((count <= 0) || (count > nentries)) {
- qprintf("Invalid count. There are %d entries.\n", nentries);
- return;
- }
-
- ktep = ktrace_first(xfs_alloc_trace_buf, &kts);
- if (count != nentries) {
- /*
- * Skip the total minus the number to look at minus one
- * for the entry returned by ktrace_first().
- */
- skip_entries = nentries - count - 1;
- ktep = ktrace_skip(xfs_alloc_trace_buf, skip_entries, &kts);
- if (ktep == NULL) {
- qprintf("Skipped them all\n");
- return;
- }
- }
- while (ktep != NULL) {
- if (xfs_alloc_trace_entry(ktep))
- qprintf("\n");
- ktep = ktrace_next(xfs_alloc_trace_buf, &kts);
- }
-}
-
-/*
- * Print out all the entries in the alloc trace buf corresponding
- * to the given block number.
- */
-static void
-xfsidbg_xalbtrace(xfs_agblock_t bno)
-{
- ktrace_entry_t *ktep;
- ktrace_snap_t kts;
-
- if (xfs_alloc_trace_buf == NULL) {
- qprintf("The xfs alloc trace buffer is not initialized\n");
- return;
- }
-
- ktep = ktrace_first(xfs_alloc_trace_buf, &kts);
- while (ktep != NULL) {
- switch ((__psint_t)ktep->val[0]) {
- case XFS_ALLOC_KTRACE_ALLOC:
- case XFS_ALLOC_KTRACE_FREE:
- if (bno >= (xfs_agblock_t)((__psint_t)ktep->val[5]) &&
- bno < (xfs_agblock_t)((__psint_t)ktep->val[5]) +
- (xfs_extlen_t)((__psint_t)ktep->val[13])) {
- (void)xfs_alloc_trace_entry(ktep);
- qprintf("\n");
- }
- break;
- }
- ktep = ktrace_next(xfs_alloc_trace_buf, &kts);
- }
-}
-
-/*
- * Print out all the entries in the alloc trace buf corresponding
- * to the given allocation group.
- */
-static void
-xfsidbg_xalgtrace(xfs_agnumber_t agno)
-{
- ktrace_entry_t *ktep;
- ktrace_snap_t kts;
-
- if (xfs_alloc_trace_buf == NULL) {
- qprintf("The xfs alloc trace buffer is not initialized\n");
- return;
- }
-
- ktep = ktrace_first(xfs_alloc_trace_buf, &kts);
- while (ktep != NULL) {
- if ( (__psint_t)ktep->val[0] &&
- ((xfs_agnumber_t)((__psint_t)ktep->val[4])) == agno ) {
- (void)xfs_alloc_trace_entry(ktep);
- qprintf("\n");
- }
- ktep = ktrace_next(xfs_alloc_trace_buf, &kts);
- }
-}
-#endif
-
-/*
- * Print an allocation argument structure for XFS.
- */
-static void
-xfsidbg_xalloc(xfs_alloc_arg_t *args)
-{
- kdb_printf("tp 0x%p mp 0x%p agbp 0x%p pag 0x%p fsbno %s\n",
- args->tp, args->mp, args->agbp, args->pag,
- xfs_fmtfsblock(args->fsbno, args->mp));
- kdb_printf("agno 0x%x agbno 0x%x minlen 0x%x maxlen 0x%x mod 0x%x\n",
- args->agno, args->agbno, args->minlen, args->maxlen, args->mod);
- kdb_printf("prod 0x%x minleft 0x%x total 0x%x alignment 0x%x\n",
- args->prod, args->minleft, args->total, args->alignment);
- kdb_printf("minalignslop 0x%x len 0x%x type %s otype %s wasdel %d\n",
- args->minalignslop, args->len, xfs_alloctype[args->type],
- xfs_alloctype[args->otype], args->wasdel);
- kdb_printf("wasfromfl %d isfl %d userdata %d\n",
- args->wasfromfl, args->isfl, args->userdata);
-}
-
-#ifdef XFS_ALLOC_TRACE
-/*
- * Print out all the entries in the alloc trace buf corresponding
- * to the given mount point.
- */
-static void
-xfsidbg_xalmtrace(xfs_mount_t *mp)
-{
- ktrace_entry_t *ktep;
- ktrace_snap_t kts;
-
- if (xfs_alloc_trace_buf == NULL) {
- kdb_printf("The xfs alloc trace buffer is not initialized\n");
- return;
- }
-
- ktep = ktrace_first(xfs_alloc_trace_buf, &kts);
- while (ktep != NULL) {
- if ((__psint_t)ktep->val[0] &&
- (xfs_mount_t *)ktep->val[3] == mp) {
- (void)xfs_alloc_trace_entry(ktep);
- kdb_printf("\n");
- }
- ktep = ktrace_next(xfs_alloc_trace_buf, &kts);
- }
-}
-
-/*
- * Print out all the entries in the alloc trace buf corresponding
- * to the given entry type.
- */
-static void
-xfsidbg_xalttrace(int tag)
-{
- ktrace_entry_t *ktep;
- ktrace_snap_t kts;
-
- if (xfs_alloc_trace_buf == NULL) {
- qprintf("The xfs alloc trace buffer is not initialized\n");
- return;
- }
-
- ktep = ktrace_first(xfs_alloc_trace_buf, &kts);
- while (ktep != NULL) {
- if ((__psint_t)ktep->val[0] &&
- ((long)ktep->val[0] & 0xffffL) == (long)tag) {
- (void)xfs_alloc_trace_entry(ktep);
- qprintf("\n");
- }
- ktep = ktrace_next(xfs_alloc_trace_buf, &kts);
- }
-}
-#endif
-
-static int xargument = 0;
-
-/*
- * Set xtra argument, used by xchksum.
- */
-static void
-xfsidbg_xarg(int xarg)
-{
- if (xarg == -1)
- qprintf("xargument: %d\n", xargument);
- else
- xargument = xarg;
-} /* xfsidbg_xarg */
-
-/*
- * Print an attr_list() context structure.
- */
-static void
-xfsidbg_xattrcontext(xfs_attr_list_context_t *context)
-{
- static char *attr_arg_flags[] = {
- "DONTFOLLOW", /* 0x0001 */
- "?", /* 0x0002 */
- "?", /* 0x0004 */
- "?", /* 0x0008 */
- "CREATE", /* 0x0010 */
- "?", /* 0x0020 */
- "?", /* 0x0040 */
- "?", /* 0x0080 */
- "?", /* 0x0100 */
- "?", /* 0x0200 */
- "?", /* 0x0400 */
- "?", /* 0x0800 */
- "KERNOTIME", /* 0x1000 */
- NULL
- };
-
- kdb_printf("dp 0x%p, dupcnt %d, resynch %d",
- context->dp, context->dupcnt, context->resynch);
- printflags((__psunsigned_t)context->flags, attr_arg_flags, ", flags");
- kdb_printf("\ncursor h/b/o 0x%x/0x%x/%d -- p/p/i 0x%x/0x%x/0x%x\n",
- context->cursor->hashval, context->cursor->blkno,
- context->cursor->offset, context->cursor->pad1,
- context->cursor->pad2, context->cursor->initted);
- kdb_printf("alist 0x%p, bufsize 0x%x, count %d, firstu 0x%x\n",
- context->alist, context->bufsize, context->count,
- context->firstu);
-}
-
-/*
- * Print attribute leaf block.
- */
-static void
-xfsidbg_xattrleaf(xfs_attr_leafblock_t *leaf)
-{
- xfs_attr_leaf_hdr_t *h;
- xfs_da_blkinfo_t *i;
- xfs_attr_leaf_map_t *m;
- xfs_attr_leaf_entry_t *e;
- xfs_attr_leaf_name_local_t *l;
- xfs_attr_leaf_name_remote_t *r;
- int j, k;
-
- h = &leaf->hdr;
- i = &h->info;
- kdb_printf("hdr info forw 0x%x back 0x%x magic 0x%x\n",
- i->forw, i->back, i->magic);
- kdb_printf("hdr count %d usedbytes %d firstused %d holes %d\n",
- INT_GET(h->count, ARCH_CONVERT),
- INT_GET(h->usedbytes, ARCH_CONVERT),
- INT_GET(h->firstused, ARCH_CONVERT), h->holes);
- for (j = 0, m = h->freemap; j < XFS_ATTR_LEAF_MAPSIZE; j++, m++) {
- kdb_printf("hdr freemap %d base %d size %d\n",
- j, INT_GET(m->base, ARCH_CONVERT),
- INT_GET(m->size, ARCH_CONVERT));
- }
- for (j = 0, e = leaf->entries; j < INT_GET(h->count, ARCH_CONVERT); j++, e++) {
- kdb_printf("[%2d] hash 0x%x nameidx %d flags 0x%x",
- j, INT_GET(e->hashval, ARCH_CONVERT),
- INT_GET(e->nameidx, ARCH_CONVERT), e->flags);
- if (e->flags & XFS_ATTR_LOCAL)
- kdb_printf("LOCAL ");
- if (e->flags & XFS_ATTR_ROOT)
- kdb_printf("ROOT ");
- if (e->flags & XFS_ATTR_SECURE)
- kdb_printf("SECURE ");
- if (e->flags & XFS_ATTR_INCOMPLETE)
- kdb_printf("INCOMPLETE ");
- k = ~(XFS_ATTR_LOCAL | XFS_ATTR_ROOT |
- XFS_ATTR_SECURE | XFS_ATTR_INCOMPLETE);
- if ((e->flags & k) != 0)
- kdb_printf("0x%x", e->flags & k);
- kdb_printf(">\n name \"");
- if (e->flags & XFS_ATTR_LOCAL) {
- l = XFS_ATTR_LEAF_NAME_LOCAL(leaf, j);
- for (k = 0; k < l->namelen; k++)
- kdb_printf("%c", l->nameval[k]);
- kdb_printf("\"(%d) value \"", l->namelen);
- for (k = 0; (k < INT_GET(l->valuelen, ARCH_CONVERT)) && (k < 32); k++)
- kdb_printf("%c", l->nameval[l->namelen + k]);
- if (k == 32)
- kdb_printf("...");
- kdb_printf("\"(%d)\n",
- INT_GET(l->valuelen, ARCH_CONVERT));
- } else {
- r = XFS_ATTR_LEAF_NAME_REMOTE(leaf, j);
- for (k = 0; k < r->namelen; k++)
- kdb_printf("%c", r->name[k]);
- kdb_printf("\"(%d) value blk 0x%x len %d\n",
- r->namelen,
- INT_GET(r->valueblk, ARCH_CONVERT),
- INT_GET(r->valuelen, ARCH_CONVERT));
- }
- }
-}
-
-/*
- * Print a shortform attribute list.
- */
-static void
-xfsidbg_xattrsf(xfs_attr_shortform_t *s)
-{
- xfs_attr_sf_hdr_t *sfh;
- xfs_attr_sf_entry_t *sfe;
- int i, j;
-
- sfh = &s->hdr;
- kdb_printf("hdr count %d\n", INT_GET(sfh->count, ARCH_CONVERT));
- for (i = 0, sfe = s->list; i < INT_GET(sfh->count, ARCH_CONVERT); i++) {
- kdb_printf("entry %d namelen %d name \"", i, sfe->namelen);
- for (j = 0; j < sfe->namelen; j++)
- kdb_printf("%c", sfe->nameval[j]);
- kdb_printf("\" valuelen %d value \"", INT_GET(sfe->valuelen, ARCH_CONVERT));
- for (j = 0; (j < INT_GET(sfe->valuelen, ARCH_CONVERT)) && (j < 32); j++)
- kdb_printf("%c", sfe->nameval[sfe->namelen + j]);
- if (j == 32)
- kdb_printf("...");
- kdb_printf("\"\n");
- sfe = XFS_ATTR_SF_NEXTENTRY(sfe);
- }
-}
-
-#ifdef XFS_ATTR_TRACE
-/*
- * Print out the last "count" entries in the attribute trace buffer.
- */
-static void
-xfsidbg_xattrtrace(int count)
-{
- ktrace_entry_t *ktep;
- ktrace_snap_t kts;
- int nentries;
- int skip_entries;
-
- if (xfs_attr_trace_buf == NULL) {
- qprintf("The xfs attribute trace buffer is not initialized\n");
- return;
- }
- nentries = ktrace_nentries(xfs_attr_trace_buf);
- if (count == -1) {
- count = nentries;
- }
- if ((count <= 0) || (count > nentries)) {
- qprintf("Invalid count. There are %d entries.\n", nentries);
- return;
- }
-
- ktep = ktrace_first(xfs_attr_trace_buf, &kts);
- if (count != nentries) {
- /*
- * Skip the total minus the number to look at minus one
- * for the entry returned by ktrace_first().
- */
- skip_entries = nentries - count - 1;
- ktep = ktrace_skip(xfs_attr_trace_buf, skip_entries, &kts);
- if (ktep == NULL) {
- qprintf("Skipped them all\n");
- return;
- }
- }
- while (ktep != NULL) {
- xfs_attr_trace_entry(ktep);
- ktep = ktrace_next(xfs_attr_trace_buf, &kts);
- }
-}
-#endif
-
-/*
- * Print xfs bmap internal record
- */
-static void
-xfsidbg_xbirec(xfs_bmbt_irec_t *r)
-{
- kdb_printf(
- "startoff %Ld startblock %Lx blockcount %Ld state %Ld\n",
- (__uint64_t)r->br_startoff,
- (__uint64_t)r->br_startblock,
- (__uint64_t)r->br_blockcount,
- (__uint64_t)r->br_state);
-}
-
-#ifdef XFS_BLI_TRACE
-/*
- * Print out the buf log item trace for the given buf log item.
- */
-static void
-xfsidbg_xblitrace(xfs_buf_log_item_t *bip)
-{
- ktrace_entry_t *ktep;
- ktrace_snap_t kts;
- uint64_t flags;
- static char *xbli_flags[] = {
- "hold", /* 0x01 */
- "dirty", /* 0x02 */
- "stale", /* 0x04 */
- "logged", /* 0x08 */
- NULL
- };
- static char *xli_flags[] = {
- "in ail", /* 0x1 */
- NULL
- };
-
- if (bip->bli_trace == NULL) {
- qprintf("The bli trace buffer is not initialized\n");
- return;
- }
-
- ktep = ktrace_first(bip->bli_trace, &kts);
- while (ktep != NULL) {
- qprintf("%s bp 0x%p flags ",
- (char *)ktep->val[0], ktep->val[1]);
- printflags((__psint_t)(ktep->val[2]), xbli_flags, "xbli");
- qprintf("\n");
- qprintf("recur %ld refcount %ld blkno 0x%lx bcount 0x%lx\n",
- (long)ktep->val[3], (long)ktep->val[4],
- (unsigned long)ktep->val[5],
- (unsigned long)ktep->val[6]);
- flags = (((uint64_t)(unsigned long)ktep->val[7] << 32) &
- 0xFFFFFFFF00000000ULL) |
- (((uint64_t)(unsigned long)ktep->val[8]) &
- 0x00000000FFFFFFFFULL);
- qprintf("bp flags ");
- printflags(flags, bp_flag_vals, NULL);
- qprintf("\n");
- qprintf("fspriv 0x%p fspriv2 0x%p pincount %ld iodone 0x%p\n",
- ktep->val[9], ktep->val[10],
- (long)ktep->val[11], ktep->val[12]);
- qprintf("lockval %ld lid 0x%lx log item flags ",
- (long)ktep->val[13], (unsigned long)ktep->val[14]);
- printflags((__psint_t)(ktep->val[15]), xli_flags, "xli");
- qprintf("\n");
-
- ktep = ktrace_next(bip->bli_trace, &kts);
- }
-}
-#endif
-
-/*
- * Print a bmap alloc argument structure for XFS.
- */
-static void
-xfsidbg_xbmalla(xfs_bmalloca_t *a)
-{
- kdb_printf("tp 0x%p ip 0x%p eof %d prevp 0x%p\n",
- a->tp, a->ip, a->eof, a->prevp);
- kdb_printf("gotp 0x%p firstblock %s alen %d total %d\n",
- a->gotp, xfs_fmtfsblock(a->firstblock, a->ip->i_mount),
- a->alen, a->total);
- kdb_printf("off %s wasdel %d userdata %d minlen %d\n",
- xfs_fmtfsblock(a->off, a->ip->i_mount), a->wasdel,
- a->userdata, a->minlen);
- kdb_printf("minleft %d low %d rval %s aeof %d conv %d\n",
- a->minleft, a->low, xfs_fmtfsblock(a->rval, a->ip->i_mount),
- a->aeof, a->conv);
-}
-
-#ifdef XFS_BMAP_TRACE
-/*
- * Print out the last "count" entries in the bmap btree trace buffer.
- * The "a" is for "all" inodes.
- */
-static void
-xfsidbg_xbmatrace(int count)
-{
- ktrace_entry_t *ktep;
- ktrace_snap_t kts;
- int nentries;
- int skip_entries;
-
- if (xfs_bmbt_trace_buf == NULL) {
- qprintf("The xfs bmap btree trace buffer is not initialized\n"); return;
- }
- nentries = ktrace_nentries(xfs_bmbt_trace_buf);
- if (count == -1) {
- count = nentries;
- }
- if ((count <= 0) || (count > nentries)) {
- qprintf("Invalid count. There are %d entries.\n", nentries);
- return;
- }
-
- ktep = ktrace_first(xfs_bmbt_trace_buf, &kts);
- if (count != nentries) {
- /*
- * Skip the total minus the number to look at minus one
- * for the entry returned by ktrace_first().
- */
- skip_entries = nentries - count - 1;
- ktep = ktrace_skip(xfs_bmbt_trace_buf, skip_entries, &kts);
- if (ktep == NULL) {
- qprintf("Skipped them all\n");
- return;
- }
- }
- while (ktep != NULL) {
- if (xfs_bmbt_trace_entry(ktep))
- qprintf("\n");
- ktep = ktrace_next(xfs_bmbt_trace_buf, &kts);
- }
-}
-
-/*
- * Print out the bmap btree trace buffer attached to the given inode.
- */
-static void
-xfsidbg_xbmitrace(xfs_inode_t *ip)
-{
- ktrace_entry_t *ktep;
- ktrace_snap_t kts;
-
- if (ip->i_btrace == NULL) {
- qprintf("The inode trace buffer is not initialized\n");
- return;
- }
-
- ktep = ktrace_first(ip->i_btrace, &kts);
- while (ktep != NULL) {
- if (xfs_bmbt_trace_entry(ktep))
- qprintf("\n");
- ktep = ktrace_next(ip->i_btrace, &kts);
- }
-}
-
-/*
- * Print out all the entries in the bmap btree trace buf corresponding
- * to the given inode. The "s" is for "single" inode.
- */
-static void
-xfsidbg_xbmstrace(xfs_inode_t *ip)
-{
- ktrace_entry_t *ktep;
- ktrace_snap_t kts;
-
- if (xfs_bmbt_trace_buf == NULL) {
- qprintf("The xfs bmap btree trace buffer is not initialized\n"); return;
- }
-
- ktep = ktrace_first(xfs_bmbt_trace_buf, &kts);
- while (ktep != NULL) {
- if ((xfs_inode_t *)(ktep->val[2]) == ip) {
- if (xfs_bmbt_trace_entry(ktep))
- qprintf("\n");
- }
- ktep = ktrace_next(xfs_bmbt_trace_buf, &kts);
- }
-}
-#endif
-
-/*
- * Print xfs bmap record
- */
-static void
-xfsidbg_xbrec(xfs_bmbt_rec_64_t *r)
-{
- xfs_bmbt_irec_t irec;
-
- xfs_bmbt_get_all((xfs_bmbt_rec_t *)r, &irec);
- kdb_printf("startoff %Ld startblock %Lx blockcount %Ld flag %d\n",
- irec.br_startoff, (__uint64_t)irec.br_startblock,
- irec.br_blockcount, irec.br_state);
-}
-
-/*
- * Print an xfs in-inode bmap btree root (data fork).
- */
-static void
-xfsidbg_xbroot(xfs_inode_t *ip)
-{
- xfs_broot(ip, &ip->i_df);
-}
-
-/*
- * Print an xfs in-inode bmap btree root (attribute fork).
- */
-static void
-xfsidbg_xbroota(xfs_inode_t *ip)
-{
- if (ip->i_afp)
- xfs_broot(ip, ip->i_afp);
-}
-
-/*
- * Print xfs btree cursor.
- */
-static void
-xfsidbg_xbtcur(xfs_btree_cur_t *c)
-{
- int l;
-
- kdb_printf("tp 0x%p mp 0x%p\n",
- c->bc_tp,
- c->bc_mp);
- if (c->bc_btnum == XFS_BTNUM_BMAP) {
- kdb_printf("rec.b ");
- xfsidbg_xbirec(&c->bc_rec.b);
- } else if (c->bc_btnum == XFS_BTNUM_INO) {
- kdb_printf("rec.i startino 0x%x freecount 0x%x free %Lx\n",
- c->bc_rec.i.ir_startino, c->bc_rec.i.ir_freecount,
- c->bc_rec.i.ir_free);
- } else {
- kdb_printf("rec.a startblock 0x%x blockcount 0x%x\n",
- c->bc_rec.a.ar_startblock,
- c->bc_rec.a.ar_blockcount);
- }
- kdb_printf("bufs");
- for (l = 0; l < c->bc_nlevels; l++)
- kdb_printf(" 0x%p", c->bc_bufs[l]);
- kdb_printf("\n");
- kdb_printf("ptrs");
- for (l = 0; l < c->bc_nlevels; l++)
- kdb_printf(" 0x%x", c->bc_ptrs[l]);
- kdb_printf(" ra");
- for (l = 0; l < c->bc_nlevels; l++)
- kdb_printf(" %d", c->bc_ra[l]);
- kdb_printf("\n");
- kdb_printf("nlevels %d btnum %s blocklog %d\n",
- c->bc_nlevels,
- c->bc_btnum == XFS_BTNUM_BNO ? "bno" :
- (c->bc_btnum == XFS_BTNUM_CNT ? "cnt" :
- (c->bc_btnum == XFS_BTNUM_BMAP ? "bmap" : "ino")),
- c->bc_blocklog);
- if (c->bc_btnum == XFS_BTNUM_BMAP) {
- kdb_printf("private forksize 0x%x whichfork %d ip 0x%p flags %d\n",
- c->bc_private.b.forksize,
- c->bc_private.b.whichfork,
- c->bc_private.b.ip,
- c->bc_private.b.flags);
- kdb_printf("private firstblock %s flist 0x%p allocated 0x%x\n",
- xfs_fmtfsblock(c->bc_private.b.firstblock, c->bc_mp),
- c->bc_private.b.flist,
- c->bc_private.b.allocated);
- } else if (c->bc_btnum == XFS_BTNUM_INO) {
- kdb_printf("private agbp 0x%p agno 0x%x\n",
- c->bc_private.i.agbp,
- c->bc_private.i.agno);
- } else {
- kdb_printf("private agbp 0x%p agno 0x%x\n",
- c->bc_private.a.agbp,
- c->bc_private.a.agno);
- }
-}
-
-/*
- * Figure out what kind of xfs block the buffer contains,
- * and invoke a print routine.
- */
-static void
-xfsidbg_xbuf(xfs_buf_t *bp)
-{
- xfsidbg_xbuf_real(bp, 0);
-}
-
-/*
- * Figure out what kind of xfs block the buffer contains,
- * and invoke a print routine (if asked to).
- */
-static void
-xfsidbg_xbuf_real(xfs_buf_t *bp, int summary)
-{
- void *d;
- xfs_agf_t *agf;
- xfs_agi_t *agi;
- xfs_sb_t *sb;
- xfs_alloc_block_t *bta;
- xfs_bmbt_block_t *btb;
- xfs_inobt_block_t *bti;
- xfs_attr_leafblock_t *aleaf;
- xfs_dir_leafblock_t *dleaf;
- xfs_da_intnode_t *node;
- xfs_dinode_t *di;
- xfs_disk_dquot_t *dqb;
- xfs_dir2_block_t *d2block;
- xfs_dir2_data_t *d2data;
- xfs_dir2_leaf_t *d2leaf;
- xfs_dir2_free_t *d2free;
-
- d = XFS_BUF_PTR(bp);
- if (be32_to_cpu((agf = d)->agf_magicnum) == XFS_AGF_MAGIC) {
- if (summary) {
- kdb_printf("freespace hdr for AG %d (at 0x%p)\n",
- be32_to_cpu(agf->agf_seqno), agf);
- } else {
- kdb_printf("buf 0x%p agf 0x%p\n", bp, agf);
- xfsidbg_xagf(agf);
- }
- } else if (be32_to_cpu((agi = d)->agi_magicnum) == XFS_AGI_MAGIC) {
- if (summary) {
- kdb_printf("Inode hdr for AG %d (at 0x%p)\n",
- be32_to_cpu(agi->agi_seqno), agi);
- } else {
- kdb_printf("buf 0x%p agi 0x%p\n", bp, agi);
- xfsidbg_xagi(agi);
- }
- } else if (be32_to_cpu((bta = d)->bb_magic) == XFS_ABTB_MAGIC) {
- if (summary) {
- kdb_printf("Alloc BNO Btree blk, level %d (at 0x%p)\n",
- be16_to_cpu(bta->bb_level), bta);
- } else {
- kdb_printf("buf 0x%p abtbno 0x%p\n", bp, bta);
- xfs_btalloc(bta, XFS_BUF_COUNT(bp));
- }
- } else if (be32_to_cpu((bta = d)->bb_magic) == XFS_ABTC_MAGIC) {
- if (summary) {
- kdb_printf("Alloc COUNT Btree blk, level %d (at 0x%p)\n",
- be16_to_cpu(bta->bb_level), bta);
- } else {
- kdb_printf("buf 0x%p abtcnt 0x%p\n", bp, bta);
- xfs_btalloc(bta, XFS_BUF_COUNT(bp));
- }
- } else if (be32_to_cpu((btb = d)->bb_magic) == XFS_BMAP_MAGIC) {
- if (summary) {
- kdb_printf("Bmap Btree blk, level %d (at 0x%p)\n",
- be16_to_cpu(btb->bb_level), btb);
- } else {
- kdb_printf("buf 0x%p bmapbt 0x%p\n", bp, btb);
- xfs_btbmap(btb, XFS_BUF_COUNT(bp));
- }
- } else if (be32_to_cpu((bti = d)->bb_magic) == XFS_IBT_MAGIC) {
- if (summary) {
- kdb_printf("Inode Btree blk, level %d (at 0x%p)\n",
- be16_to_cpu(bti->bb_level), bti);
- } else {
- kdb_printf("buf 0x%p inobt 0x%p\n", bp, bti);
- xfs_btino(bti, XFS_BUF_COUNT(bp));
- }
- } else if (INT_GET((aleaf = d)->hdr.info.magic, ARCH_CONVERT) == XFS_ATTR_LEAF_MAGIC) {
- if (summary) {
- kdb_printf("Attr Leaf, 1st hash 0x%x (at 0x%p)\n",
- INT_GET(aleaf->entries[0].hashval, ARCH_CONVERT), aleaf);
- } else {
- kdb_printf("buf 0x%p attr leaf 0x%p\n", bp, aleaf);
- xfsidbg_xattrleaf(aleaf);
- }
- } else if (INT_GET((dleaf = d)->hdr.info.magic, ARCH_CONVERT) == XFS_DIR_LEAF_MAGIC) {
- if (summary) {
- kdb_printf("Dir Leaf, 1st hash 0x%x (at 0x%p)\n",
- dleaf->entries[0].hashval, dleaf);
- } else {
- kdb_printf("buf 0x%p dir leaf 0x%p\n", bp, dleaf);
- xfsidbg_xdirleaf(dleaf);
- }
- } else if (INT_GET((node = d)->hdr.info.magic, ARCH_CONVERT) == XFS_DA_NODE_MAGIC) {
- if (summary) {
- kdb_printf("Dir/Attr Node, level %d, 1st hash 0x%x (at 0x%p)\n",
- node->hdr.level, node->btree[0].hashval, node);
- } else {
- kdb_printf("buf 0x%p dir/attr node 0x%p\n", bp, node);
- xfsidbg_xdanode(node);
- }
- } else if (INT_GET((di = d)->di_core.di_magic, ARCH_CONVERT) == XFS_DINODE_MAGIC) {
- if (summary) {
- kdb_printf("Disk Inode (at 0x%p)\n", di);
- } else {
- kdb_printf("buf 0x%p dinode 0x%p\n", bp, di);
- xfs_inodebuf(bp);
- }
- } else if (INT_GET((sb = d)->sb_magicnum, ARCH_CONVERT) == XFS_SB_MAGIC) {
- if (summary) {
- kdb_printf("Superblock (at 0x%p)\n", sb);
- } else {
- kdb_printf("buf 0x%p sb 0x%p\n", bp, sb);
- /* SB in a buffer - we need to convert */
- xfsidbg_xsb_convert(sb);
- }
- } else if ((dqb = d)->d_magic == cpu_to_be16(XFS_DQUOT_MAGIC)) {
-#define XFSIDBG_DQTYPESTR(d) \
- (((d)->d_flags & XFS_DQ_USER) ? "USR" : \
- (((d)->d_flags & XFS_DQ_GROUP) ? "GRP" : \
- (((d)->d_flags & XFS_DQ_PROJ) ? "PRJ" : "???")))
- kdb_printf("Quota blk starting ID [%d], type %s at 0x%p\n",
- be32_to_cpu(dqb->d_id), XFSIDBG_DQTYPESTR(dqb), dqb);
-
- } else if (INT_GET((d2block = d)->hdr.magic, ARCH_CONVERT) == XFS_DIR2_BLOCK_MAGIC) {
- if (summary) {
- kdb_printf("Dir2 block (at 0x%p)\n", d2block);
- } else {
- kdb_printf("buf 0x%p dir2 block 0x%p\n", bp, d2block);
- xfs_dir2data((void *)d2block, XFS_BUF_COUNT(bp));
- }
- } else if (INT_GET((d2data = d)->hdr.magic, ARCH_CONVERT) == XFS_DIR2_DATA_MAGIC) {
- if (summary) {
- kdb_printf("Dir2 data (at 0x%p)\n", d2data);
- } else {
- kdb_printf("buf 0x%p dir2 data 0x%p\n", bp, d2data);
- xfs_dir2data((void *)d2data, XFS_BUF_COUNT(bp));
- }
- } else if (INT_GET((d2leaf = d)->hdr.info.magic, ARCH_CONVERT) == XFS_DIR2_LEAF1_MAGIC) {
- if (summary) {
- kdb_printf("Dir2 leaf(1) (at 0x%p)\n", d2leaf);
- } else {
- kdb_printf("buf 0x%p dir2 leaf 0x%p\n", bp, d2leaf);
- xfs_dir2leaf(d2leaf, XFS_BUF_COUNT(bp));
- }
- } else if (INT_GET(d2leaf->hdr.info.magic, ARCH_CONVERT) == XFS_DIR2_LEAFN_MAGIC) {
- if (summary) {
- kdb_printf("Dir2 leaf(n) (at 0x%p)\n", d2leaf);
- } else {
- kdb_printf("buf 0x%p dir2 leaf 0x%p\n", bp, d2leaf);
- xfs_dir2leaf(d2leaf, XFS_BUF_COUNT(bp));
- }
- } else if (INT_GET((d2free = d)->hdr.magic, ARCH_CONVERT) == XFS_DIR2_FREE_MAGIC) {
- if (summary) {
- kdb_printf("Dir2 free (at 0x%p)\n", d2free);
- } else {
- kdb_printf("buf 0x%p dir2 free 0x%p\n", bp, d2free);
- xfsidbg_xdir2free(d2free);
- }
- } else {
- kdb_printf("buf 0x%p unknown 0x%p\n", bp, d);
- }
-}
-
-#ifdef XFS_BMAP_TRACE
-/*
- * Print out the last "count" entries in the bmap extent trace buffer.
- * The "a" is for "all" inodes.
- */
-static void
-xfsidbg_xbxatrace(int count)
-{
- ktrace_entry_t *ktep;
- ktrace_snap_t kts;
- int nentries;
- int skip_entries;
-
- if (xfs_bmap_trace_buf == NULL) {
- qprintf("The xfs bmap extent trace buffer is not initialized\n");
- return;
- }
- nentries = ktrace_nentries(xfs_bmap_trace_buf);
- if (count == -1) {
- count = nentries;
- }
- if ((count <= 0) || (count > nentries)) {
- qprintf("Invalid count. There are %d entries.\n", nentries);
- return;
- }
-
- ktep = ktrace_first(xfs_bmap_trace_buf, &kts);
- if (count != nentries) {
- /*
- * Skip the total minus the number to look at minus one
- * for the entry returned by ktrace_first().
- */
- skip_entries = nentries - count - 1;
- ktep = ktrace_skip(xfs_bmap_trace_buf, skip_entries, &kts);
- if (ktep == NULL) {
- qprintf("Skipped them all\n");
- return;
- }
- }
- while (ktep != NULL) {
- if (xfs_bmap_trace_entry(ktep))
- qprintf("\n");
- ktep = ktrace_next(xfs_bmap_trace_buf, &kts);
- }
-}
-
-/*
- * Print out the bmap extent trace buffer attached to the given inode.
- */
-static void
-xfsidbg_xbxitrace(xfs_inode_t *ip)
-{
- ktrace_entry_t *ktep;
- ktrace_snap_t kts;
- if (ip->i_xtrace == NULL) {
- qprintf("The inode trace buffer is not initialized\n");
- return;
- }
-
- ktep = ktrace_first(ip->i_xtrace, &kts);
- while (ktep != NULL) {
- if (xfs_bmap_trace_entry(ktep))
- qprintf("\n");
- ktep = ktrace_next(ip->i_xtrace, &kts);
- }
-}
-
-/*
- * Print out all the entries in the bmap extent trace buf corresponding
- * to the given inode. The "s" is for "single" inode.
- */
-static void
-xfsidbg_xbxstrace(xfs_inode_t *ip)
-{
- ktrace_entry_t *ktep;
- ktrace_snap_t kts;
-
- if (xfs_bmap_trace_buf == NULL) {
- qprintf("The xfs bmap extent trace buffer is not initialized\n");
- return;
- }
-
- ktep = ktrace_first(xfs_bmap_trace_buf, &kts);
- while (ktep != NULL) {
- if ((xfs_inode_t *)(ktep->val[3]) == ip) {
- if (xfs_bmap_trace_entry(ktep))
- qprintf("\n");
- }
- ktep = ktrace_next(xfs_bmap_trace_buf, &kts);
- }
-}
-#endif
-
-#ifdef XFS_ILOCK_TRACE
-/*
- * Print out the ilock trace buffer attached to the given inode.
- */
-static void
-xfsidbg_xilock_trace_entry(ktrace_entry_t *ktep)
-{
- static char *xiflags[] = {
- "IOLOCK_EXCL",
- "IOLOCK_SHAR",
- "ILOCK_EXCL",
- "ILOCK_SHAR",
- "IUNLK_NONOT",
- NULL
- };
-
- if ((__psint_t)ktep->val[0] &&
- (__psint_t)ktep->val[7] == 0) {
- printflags((__psint_t)ktep->val[2], xiflags,"Flags ");
- if ((__psint_t)ktep->val[1] == 1)
- qprintf("LOCK\n");
- else if ((__psint_t)ktep->val[1] == 2)
- qprintf("LOCK SHARED\n");
- else if ((__psint_t)ktep->val[1] == 3)
- qprintf("UNLOCK\n");
- qprintf("ip 0x%p %llx %ld\n",
- ktep->val[0],
- (unsigned long long)((xfs_inode_t*)ktep->val[0])->i_ino,
- (long)ktep->val[6]);
- qprintf("raddr 0x%p\n", ktep->val[3]);
- qprintf(" Pid %ld, cpu %ld\n",
- (long)ktep->val[5],
- (long)ktep->val[4]);
- qprintf("-----------------------\n");
-
- } else if ((__psint_t)ktep->val[7] == 1) {
- if ((__psint_t)ktep->val[1] == 1)
- qprintf("FlushLOCK ");
- else if ((__psint_t)ktep->val[1] == 2)
- qprintf("FlushTRYLOCK %ld ",
- (long)ktep->val[2]);
- else if ((__psint_t)ktep->val[1] == 3)
- qprintf("FlushUNLOCK ");
- else if ((__psint_t)ktep->val[1] == 4)
- qprintf("FlushInode 0x%p",
- ktep->val[2]);
- else if ((__psint_t)ktep->val[1] == 5)
- qprintf("FlushInodeInt ");
- else qprintf("FlushUNKNOWN ");
- qprintf("ip 0x%p ino %llx @ %ld\n",
- ktep->val[0],
- (unsigned long long)((xfs_inode_t*)ktep->val[0])->i_ino,
- (long)ktep->val[6]);
- qprintf("raddr 0x%p\n", ktep->val[3]);
- qprintf(" Pid %ld, cpu %ld\n",
- (long)ktep->val[5],
- (long)ktep->val[4]);
- qprintf("-----------------------\n");
- }
-}
-
-static void
-xfsidbg_xilock_trace(xfs_inode_t *ip)
-{
- static char *xiflags[] = {
- "IOLOCK_EXCL",
- "IOLOCK_SHAR",
- "ILOCK_EXCL",
- "ILOCK_SHAR",
- "IUNLK_NONOT",
- NULL
- };
-
- ktrace_entry_t *ktep;
- ktrace_snap_t kts;
- if (ip->i_lock_trace == NULL) {
- qprintf("The inode ilock trace buffer is not initialized\n");
- return;
- }
-
- ktep = ktrace_first(ip->i_lock_trace, &kts);
- while (ktep != NULL) {
- if ((__psint_t)ktep->val[0] &&
- (__psint_t)ktep->val[7] == 0) {
- printflags((__psint_t)ktep->val[2], xiflags,"Flags ");
- if ((__psint_t)ktep->val[1] == 1)
- qprintf("LOCK\n");
- else if ((__psint_t)ktep->val[1] == 2)
- qprintf("LOCK SHARED\n");
- else if ((__psint_t)ktep->val[1] == 3)
- qprintf("UNLOCK\n");
- qprintf("ip 0x%p %lld %ld\n",
- ktep->val[0], (unsigned long long)
- ((xfs_inode_t*)ktep->val[0])->i_ino,
- (long)ktep->val[6]);
- qprintf("raddr 0x%p\n", ktep->val[3]);
- qprintf(" Pid %ld, cpu %ld\n",
- (long)ktep->val[5],
- (long)ktep->val[4]);
- qprintf("-----------------------\n");
- } else if ((__psint_t)ktep->val[7] == 1) {
- if ((__psint_t)ktep->val[1] == 1)
- qprintf("LOCK ");
- else if ((__psint_t)ktep->val[1] == 2)
- qprintf("TRYLOCK %ld ",
- (long)ktep->val[2]);
- else if ((__psint_t)ktep->val[1] == 3)
- qprintf("UNLOCK ");
- else qprintf("UNKNOWN ");
- qprintf("ip 0x%p %lld %ld\n",
- ktep->val[0], (unsigned long long)
- ((xfs_inode_t*)ktep->val[0])->i_ino,
- (long)ktep->val[6]);
- qprintf("raddr 0x%p\n", ktep->val[3]);
- qprintf(" Pid %ld, cpu %ld\n",
- (long)ktep->val[5],
- (long)ktep->val[4]);
- qprintf("-----------------------\n");
- }
-
- ktep = ktrace_next(ip->i_lock_trace, &kts);
- }
-}
-
-/*
- * Print out the last "count" entries in the inode lock trace buffer.
- * The "a" is for "all" entries.
- */
-static void
-xfsidbg_xailock_trace(int count)
-{
- ktrace_entry_t *ktep;
- ktrace_snap_t kts;
- int nentries;
- int skip_entries;
-
- if (xfs_ilock_trace_buf == NULL) {
- qprintf("The xfs inode lock trace buffer is not initialized\n"); return;
- }
- nentries = ktrace_nentries(xfs_ilock_trace_buf);
- if (count == -1) {
- count = nentries;
- }
- if ((count <= 0) || (count > nentries)) {
- qprintf("Invalid count. There are %d entries.\n", nentries);
- return;
- }
-
- ktep = ktrace_first(xfs_ilock_trace_buf, &kts);
- if (count != nentries) {
- /*
- * Skip the total minus the number to look at minus one
- * for the entry returned by ktrace_first().
- */
- skip_entries = nentries - count - 1;
- ktep = ktrace_skip(xfs_ilock_trace_buf, skip_entries, &kts);
- if (ktep == NULL) {
- qprintf("Skipped them all\n");
- return;
- }
- }
- while (ktep != NULL) {
- xfsidbg_xilock_trace_entry(ktep);
- ktep = ktrace_next(xfs_ilock_trace_buf, &kts);
- }
-}
-#endif
-
-/*
- * Compute & print buffer's checksum.
- */
-static void
-xfsidbg_xchksum(uint *addr)
-{
- uint i, chksum = 0;
-
- if (((__psint_t)addr) == ((__psint_t)-1)) {
- qprintf("USAGE xchksum <address>\n");
- qprintf(" length is set with xarg\n");
- } else {
- for (i=0; i<xargument; i++) {
- chksum ^= *addr;
- addr++;
- }
- qprintf("chksum (0x%x) length (%d)\n", chksum, xargument);
- }
-} /* xfsidbg_xchksum */
-
-/*
- * Print an xfs_da_args structure.
- */
-static void
-xfsidbg_xdaargs(xfs_da_args_t *n)
-{
- char *ch;
- int i;
-
- kdb_printf(" name \"");
- for (i = 0; i < n->namelen; i++) {
- kdb_printf("%c", n->name[i]);
- }
- kdb_printf("\"(%d) value ", n->namelen);
- if (n->value) {
- kdb_printf("\"");
- ch = n->value;
- for (i = 0; (i < n->valuelen) && (i < 32); ch++, i++) {
- switch(*ch) {
- case '\n': kdb_printf("\n"); break;
- case '\b': kdb_printf("\b"); break;
- case '\t': kdb_printf("\t"); break;
- default: kdb_printf("%c", *ch); break;
- }
- }
- if (i == 32)
- kdb_printf("...");
- kdb_printf("\"(%d)\n", n->valuelen);
- } else {
- kdb_printf("(NULL)(%d)\n", n->valuelen);
- }
- kdb_printf(" hashval 0x%x whichfork %d flags <",
- (uint_t)n->hashval, n->whichfork);
- if (n->flags & ATTR_ROOT)
- kdb_printf("ROOT ");
- if (n->flags & ATTR_SECURE)
- kdb_printf("SECURE ");
- if (n->flags & ATTR_CREATE)
- kdb_printf("CREATE ");
- if (n->flags & ATTR_REPLACE)
- kdb_printf("REPLACE ");
- if (n->flags & XFS_ATTR_INCOMPLETE)
- kdb_printf("INCOMPLETE ");
- i = ~(ATTR_ROOT | ATTR_SECURE |
- ATTR_CREATE | ATTR_REPLACE | XFS_ATTR_INCOMPLETE);
- if ((n->flags & i) != 0)
- kdb_printf("0x%x", n->flags & i);
- kdb_printf(">\n");
- kdb_printf(" rename %d justcheck %d addname %d oknoent %d\n",
- n->rename, n->justcheck, n->addname, n->oknoent);
- kdb_printf(" leaf: blkno %d index %d rmtblkno %d rmtblkcnt %d\n",
- n->blkno, n->index, n->rmtblkno, n->rmtblkcnt);
- kdb_printf(" leaf2: blkno %d index %d rmtblkno %d rmtblkcnt %d\n",
- n->blkno2, n->index2, n->rmtblkno2, n->rmtblkcnt2);
- kdb_printf(" inumber %llu dp 0x%p firstblock 0x%p flist 0x%p\n",
- (unsigned long long) n->inumber,
- n->dp, n->firstblock, n->flist);
- kdb_printf(" trans 0x%p total %d\n",
- n->trans, n->total);
-}
-
-/*
- * Print a da buffer structure.
- */
-static void
-xfsidbg_xdabuf(xfs_dabuf_t *dabuf)
-{
- int i;
-
- kdb_printf("nbuf %d dirty %d bbcount %d data 0x%p bps",
- dabuf->nbuf, dabuf->dirty, dabuf->bbcount, dabuf->data);
- for (i = 0; i < dabuf->nbuf; i++)
- kdb_printf(" %d:0x%p", i, dabuf->bps[i]);
- kdb_printf("\n");
-#ifdef XFS_DABUF_DEBUG
- kdb_printf(" ra 0x%x prev 0x%x next 0x%x dev 0x%x blkno 0x%x\n",
- dabuf->ra, dabuf->prev, dabuf->next, dabuf->dev, dabuf->blkno);
-#endif
-}
-
-/*
- * Print a directory/attribute internal node block.
- */
-static void
-xfsidbg_xdanode(xfs_da_intnode_t *node)
-{
- xfs_da_node_hdr_t *h;
- xfs_da_blkinfo_t *i;
- xfs_da_node_entry_t *e;
- int j;
-
- h = &node->hdr;
- i = &h->info;
- kdb_printf("hdr info forw 0x%x back 0x%x magic 0x%x\n",
- INT_GET(i->forw, ARCH_CONVERT), INT_GET(i->back, ARCH_CONVERT), INT_GET(i->magic, ARCH_CONVERT));
- kdb_printf("hdr count %d level %d\n",
- INT_GET(h->count, ARCH_CONVERT), INT_GET(h->level, ARCH_CONVERT));
- for (j = 0, e = node->btree; j < INT_GET(h->count, ARCH_CONVERT); j++, e++) {
- kdb_printf("btree %d hashval 0x%x before 0x%x\n",
- j, (uint_t)INT_GET(e->hashval, ARCH_CONVERT), INT_GET(e->before, ARCH_CONVERT));
- }
-}
-
-/*
- * Print an xfs_da_state_blk structure.
- */
-static void
-xfsidbg_xdastate(xfs_da_state_t *s)
-{
- xfs_da_state_blk_t *eblk;
-
- kdb_printf("args 0x%p mp 0x%p blocksize %u node_ents %u inleaf %u\n",
- s->args, s->mp, s->blocksize, s->node_ents, s->inleaf);
- if (s->args)
- xfsidbg_xdaargs(s->args);
-
- kdb_printf("path: ");
- xfs_dastate_path(&s->path);
-
- kdb_printf("altpath: ");
- xfs_dastate_path(&s->altpath);
-
- eblk = &s->extrablk;
- kdb_printf("extra: valid %d, after %d\n", s->extravalid, s->extraafter);
- kdb_printf(" bp 0x%p blkno 0x%x ", eblk->bp, eblk->blkno);
- kdb_printf("index %d hashval 0x%x\n", eblk->index, (uint_t)eblk->hashval);
-}
-
-/*
- * Print a directory leaf block.
- */
-static void
-xfsidbg_xdirleaf(xfs_dir_leafblock_t *leaf)
-{
- xfs_dir_leaf_hdr_t *h;
- xfs_da_blkinfo_t *i;
- xfs_dir_leaf_map_t *m;
- xfs_dir_leaf_entry_t *e;
- xfs_dir_leaf_name_t *n;
- int j, k;
- xfs_ino_t ino;
-
- h = &leaf->hdr;
- i = &h->info;
- kdb_printf("hdr info forw 0x%x back 0x%x magic 0x%x\n",
- INT_GET(i->forw, ARCH_CONVERT), INT_GET(i->back, ARCH_CONVERT), INT_GET(i->magic, ARCH_CONVERT));
- kdb_printf("hdr count %d namebytes %d firstused %d holes %d\n",
- INT_GET(h->count, ARCH_CONVERT), INT_GET(h->namebytes, ARCH_CONVERT), INT_GET(h->firstused, ARCH_CONVERT), h->holes);
- for (j = 0, m = h->freemap; j < XFS_DIR_LEAF_MAPSIZE; j++, m++) {
- kdb_printf("hdr freemap %d base %d size %d\n",
- j, INT_GET(m->base, ARCH_CONVERT), INT_GET(m->size, ARCH_CONVERT));
- }
- for (j = 0, e = leaf->entries; j < INT_GET(h->count, ARCH_CONVERT); j++, e++) {
- n = XFS_DIR_LEAF_NAMESTRUCT(leaf, INT_GET(e->nameidx, ARCH_CONVERT));
- XFS_DIR_SF_GET_DIRINO(&n->inumber, &ino);
- kdb_printf("leaf %d hashval 0x%x nameidx %d inumber %llu ",
- j, (uint_t)INT_GET(e->hashval, ARCH_CONVERT),
- INT_GET(e->nameidx, ARCH_CONVERT),
- (unsigned long long)ino);
- kdb_printf("namelen %d name \"", e->namelen);
- for (k = 0; k < e->namelen; k++)
- kdb_printf("%c", n->name[k]);
- kdb_printf("\"\n");
- }
-}
-
-/*
- * Print a directory v2 data block, single or multiple.
- */
-static void
-xfs_dir2data(void *addr, int size)
-{
- xfs_dir2_data_t *db;
- xfs_dir2_block_t *bb;
- xfs_dir2_data_hdr_t *h;
- xfs_dir2_data_free_t *m;
- xfs_dir2_data_entry_t *e;
- xfs_dir2_data_unused_t *u;
- xfs_dir2_leaf_entry_t *l=NULL;
- int j, k;
- char *p;
- char *t;
- xfs_dir2_block_tail_t *tail=NULL;
-
- db = (xfs_dir2_data_t *)addr;
- bb = (xfs_dir2_block_t *)addr;
- h = &db->hdr;
- kdb_printf("hdr magic 0x%x (%s)\nhdr bestfree", INT_GET(h->magic, ARCH_CONVERT),
- INT_GET(h->magic, ARCH_CONVERT) == XFS_DIR2_DATA_MAGIC ? "DATA" :
- (INT_GET(h->magic, ARCH_CONVERT) == XFS_DIR2_BLOCK_MAGIC ? "BLOCK" : ""));
- for (j = 0, m = h->bestfree; j < XFS_DIR2_DATA_FD_COUNT; j++, m++) {
- kdb_printf(" %d: 0x%x@0x%x", j, INT_GET(m->length, ARCH_CONVERT), INT_GET(m->offset, ARCH_CONVERT));
- }
- kdb_printf("\n");
- if (INT_GET(h->magic, ARCH_CONVERT) == XFS_DIR2_DATA_MAGIC)
- t = (char *)db + size;
- else {
- /* XFS_DIR2_BLOCK_TAIL_P */
- tail = (xfs_dir2_block_tail_t *)
- ((char *)bb + size - sizeof(xfs_dir2_block_tail_t));
- l = XFS_DIR2_BLOCK_LEAF_P(tail);
- t = (char *)l;
- }
- for (p = (char *)(h + 1); p < t; ) {
- u = (xfs_dir2_data_unused_t *)p;
- if (u->freetag == XFS_DIR2_DATA_FREE_TAG) {
- kdb_printf("0x%lx unused freetag 0x%x length 0x%x tag 0x%x\n",
- (unsigned long) (p - (char *)addr),
- INT_GET(u->freetag, ARCH_CONVERT),
- INT_GET(u->length, ARCH_CONVERT),
- INT_GET(*XFS_DIR2_DATA_UNUSED_TAG_P(u), ARCH_CONVERT));
- p += INT_GET(u->length, ARCH_CONVERT);
- continue;
- }
- e = (xfs_dir2_data_entry_t *)p;
- kdb_printf("0x%lx entry inumber %llu namelen %d name \"",
- (unsigned long) (p - (char *)addr),
- (unsigned long long) INT_GET(e->inumber, ARCH_CONVERT),
- e->namelen);
- for (k = 0; k < e->namelen; k++)
- kdb_printf("%c", e->name[k]);
- kdb_printf("\" tag 0x%x\n", INT_GET(*XFS_DIR2_DATA_ENTRY_TAG_P(e), ARCH_CONVERT));
- p += XFS_DIR2_DATA_ENTSIZE(e->namelen);
- }
- if (INT_GET(h->magic, ARCH_CONVERT) == XFS_DIR2_DATA_MAGIC)
- return;
- for (j = 0; j < INT_GET(tail->count, ARCH_CONVERT); j++, l++) {
- kdb_printf("0x%lx leaf %d hashval 0x%x address 0x%x (byte 0x%x)\n",
- (unsigned long) ((char *)l - (char *)addr), j,
- (uint_t)INT_GET(l->hashval, ARCH_CONVERT),
- INT_GET(l->address, ARCH_CONVERT),
- /* XFS_DIR2_DATAPTR_TO_BYTE */
- INT_GET(l->address, ARCH_CONVERT) << XFS_DIR2_DATA_ALIGN_LOG);
- }
- kdb_printf("0x%lx tail count %d\n",
- (unsigned long) ((char *)tail - (char *)addr),
- INT_GET(tail->count, ARCH_CONVERT));
-}
-
-static void
-xfs_dir2leaf(xfs_dir2_leaf_t *leaf, int size)
-{
- xfs_dir2_leaf_hdr_t *h;
- xfs_da_blkinfo_t *i;
- xfs_dir2_leaf_entry_t *e;
- xfs_dir2_data_off_t *b;
- xfs_dir2_leaf_tail_t *t;
- int j;
-
- h = &leaf->hdr;
- i = &h->info;
- e = leaf->ents;
- kdb_printf("hdr info forw 0x%x back 0x%x magic 0x%x\n",
- INT_GET(i->forw, ARCH_CONVERT), INT_GET(i->back, ARCH_CONVERT), INT_GET(i->magic, ARCH_CONVERT));
- kdb_printf("hdr count %d stale %d\n", INT_GET(h->count, ARCH_CONVERT), INT_GET(h->stale, ARCH_CONVERT));
- for (j = 0; j < INT_GET(h->count, ARCH_CONVERT); j++, e++) {
- kdb_printf("0x%lx ent %d hashval 0x%x address 0x%x (byte 0x%x)\n",
- (unsigned long) ((char *)e - (char *)leaf), j,
- (uint_t)INT_GET(e->hashval, ARCH_CONVERT),
- INT_GET(e->address, ARCH_CONVERT),
- /* XFS_DIR2_DATAPTR_TO_BYTE */
- INT_GET(e->address, ARCH_CONVERT) << XFS_DIR2_DATA_ALIGN_LOG);
- }
- if (INT_GET(i->magic, ARCH_CONVERT) == XFS_DIR2_LEAFN_MAGIC)
- return;
- /* XFS_DIR2_LEAF_TAIL_P */
- t = (xfs_dir2_leaf_tail_t *)((char *)leaf + size - sizeof(*t));
- b = XFS_DIR2_LEAF_BESTS_P(t);
- for (j = 0; j < INT_GET(t->bestcount, ARCH_CONVERT); j++, b++) {
- kdb_printf("0x%lx best %d 0x%x\n",
- (unsigned long) ((char *)b - (char *)leaf), j,
- INT_GET(*b, ARCH_CONVERT));
- }
- kdb_printf("tail bestcount %d\n", INT_GET(t->bestcount, ARCH_CONVERT));
-}
-
-/*
- * Print a shortform directory.
- */
-static void
-xfsidbg_xdirsf(xfs_dir_shortform_t *s)
-{
- xfs_dir_sf_hdr_t *sfh;
- xfs_dir_sf_entry_t *sfe;
- xfs_ino_t ino;
- int i, j;
-
- sfh = &s->hdr;
- XFS_DIR_SF_GET_DIRINO(&sfh->parent, &ino);
- kdb_printf("hdr parent %llu", (unsigned long long)ino);
- kdb_printf(" count %d\n", sfh->count);
- for (i = 0, sfe = s->list; i < sfh->count; i++) {
- XFS_DIR_SF_GET_DIRINO(&sfe->inumber, &ino);
- kdb_printf("entry %d inumber %llu", i, (unsigned long long)ino);
- kdb_printf(" namelen %d name \"", sfe->namelen);
- for (j = 0; j < sfe->namelen; j++)
- kdb_printf("%c", sfe->name[j]);
- kdb_printf("\"\n");
- sfe = XFS_DIR_SF_NEXTENTRY(sfe);
- }
-}
-
-/*
- * Print a shortform v2 directory.
- */
-static void
-xfsidbg_xdir2sf(xfs_dir2_sf_t *s)
-{
- xfs_dir2_sf_hdr_t *sfh;
- xfs_dir2_sf_entry_t *sfe;
- xfs_ino_t ino;
- int i, j;
-
- sfh = &s->hdr;
- ino = XFS_DIR2_SF_GET_INUMBER(s, &sfh->parent);
- kdb_printf("hdr count %d i8count %d parent %llu\n",
- sfh->count, sfh->i8count, (unsigned long long) ino);
- for (i = 0, sfe = XFS_DIR2_SF_FIRSTENTRY(s); i < sfh->count; i++) {
- ino = XFS_DIR2_SF_GET_INUMBER(s, XFS_DIR2_SF_INUMBERP(sfe));
- kdb_printf("entry %d inumber %llu offset 0x%x namelen %d name \"",
- i, (unsigned long long) ino,
- XFS_DIR2_SF_GET_OFFSET(sfe),
- sfe->namelen);
- for (j = 0; j < sfe->namelen; j++)
- kdb_printf("%c", sfe->name[j]);
- kdb_printf("\"\n");
- sfe = XFS_DIR2_SF_NEXTENTRY(s, sfe);
- }
-}
-
-/*
- * Print a node-form v2 directory freemap block.
- */
-static void
-xfsidbg_xdir2free(xfs_dir2_free_t *f)
-{
- int i;
-
- kdb_printf("hdr magic 0x%x firstdb %d nvalid %d nused %d\n",
- INT_GET(f->hdr.magic, ARCH_CONVERT), INT_GET(f->hdr.firstdb, ARCH_CONVERT), INT_GET(f->hdr.nvalid, ARCH_CONVERT), INT_GET(f->hdr.nused, ARCH_CONVERT));
- for (i = 0; i < INT_GET(f->hdr.nvalid, ARCH_CONVERT); i++) {
- kdb_printf("entry %d db %d count %d\n",
- i, i + INT_GET(f->hdr.firstdb, ARCH_CONVERT), INT_GET(f->bests[i], ARCH_CONVERT));
- }
-}
-
-#ifdef XFS_DIR_TRACE
-/*
- * Print out the last "count" entries in the directory trace buffer.
- */
-static void
-xfsidbg_xdirtrace(int count)
-{
- ktrace_entry_t *ktep;
- ktrace_snap_t kts;
- int nentries;
- int skip_entries;
-
- if (xfs_dir_trace_buf == NULL) {
- qprintf("The xfs directory trace buffer is not initialized\n");
- return;
- }
- nentries = ktrace_nentries(xfs_dir_trace_buf);
- if (count == -1) {
- count = nentries;
- }
- if ((count <= 0) || (count > nentries)) {
- qprintf("Invalid count. There are %d entries.\n", nentries);
- return;
- }
-
- ktep = ktrace_first(xfs_dir_trace_buf, &kts);
- if (count != nentries) {
- /*
- * Skip the total minus the number to look at minus one
- * for the entry returned by ktrace_first().
- */
- skip_entries = nentries - count - 1;
- ktep = ktrace_skip(xfs_dir_trace_buf, skip_entries, &kts);
- if (ktep == NULL) {
- qprintf("Skipped them all\n");
- return;
- }
- }
- while (ktep != NULL) {
- if (xfs_dir_trace_entry(ktep))
- qprintf("\n");
- ktep = ktrace_next(xfs_dir_trace_buf, &kts);
- }
-}
-#endif
-
-#ifdef XFS_DIR2_TRACE
-/*
- * Print out the last "count" entries in the directory v2 trace buffer.
- */
-static void
-xfsidbg_xdir2atrace(int count)
-{
- ktrace_entry_t *ktep;
- ktrace_snap_t kts;
- int nentries;
- int skip_entries;
-
- if (xfs_dir2_trace_buf == NULL) {
- qprintf("The xfs dirv2 trace buffer is not initialized\n");
- return;
- }
- nentries = ktrace_nentries(xfs_dir2_trace_buf);
- if (count == -1) {
- count = nentries;
- }
- if ((count <= 0) || (count > nentries)) {
- qprintf("Invalid count. There are %d entries.\n", nentries);
- return;
- }
-
- ktep = ktrace_first(xfs_dir2_trace_buf, &kts);
- if (count != nentries) {
- /*
- * Skip the total minus the number to look at minus one
- * for the entry returned by ktrace_first().
- */
- skip_entries = nentries - count - 1;
- ktep = ktrace_skip(xfs_dir2_trace_buf, skip_entries, &kts);
- if (ktep == NULL) {
- qprintf("Skipped them all\n");
- return;
- }
- }
- while (ktep != NULL) {
- if (xfs_dir2_trace_entry(ktep))
- qprintf("\n");
- ktep = ktrace_next(xfs_dir2_trace_buf, &kts);
- }
-}
-
-/*
- * Print out the directory v2 trace buffer attached to the given inode.
- */
-static void
-xfsidbg_xdir2itrace(xfs_inode_t *ip)
-{
- ktrace_entry_t *ktep;
- ktrace_snap_t kts;
-
- if (ip->i_dir_trace == NULL) {
- qprintf("The inode trace buffer is not initialized\n");
- return;
- }
-
- ktep = ktrace_first(ip->i_dir_trace, &kts);
- while (ktep != NULL) {
- if (xfs_dir2_trace_entry(ktep))
- qprintf("\n");
- ktep = ktrace_next(ip->i_dir_trace, &kts);
- }
-}
-#endif
-
-/*
- * Print xfs extent records.
- */
-static void
-xfsidbg_xexlist(xfs_inode_t *ip)
-{
- xfs_xexlist_fork(ip, XFS_DATA_FORK);
- if (XFS_IFORK_Q(ip))
- xfs_xexlist_fork(ip, XFS_ATTR_FORK);
-}
-
-/*
- * Print an xfs free-extent records.
- */
-static void
-xfsidbg_xflist(xfs_bmap_free_t *flist)
-{
- xfs_bmap_free_item_t *item;
-
- kdb_printf("flist@0x%p: first 0x%p count %d low %d\n", flist,
- flist->xbf_first, flist->xbf_count, flist->xbf_low);
- for (item = flist->xbf_first; item; item = item->xbfi_next) {
- kdb_printf("item@0x%p: startblock %Lx blockcount %d", item,
- (xfs_dfsbno_t)item->xbfi_startblock,
- item->xbfi_blockcount);
- }
-}
-
-/*
- * Print out the help messages for these functions.
- */
-static void
-xfsidbg_xhelp(void)
-{
- struct xif *p;
-
- for (p = xfsidbg_funcs; p->name; p++)
- kdb_printf("%-16s %s %s\n", p->name, p->args, p->help);
-}
-
-/*
- * Print out an XFS in-core log structure.
- */
-static void
-xfsidbg_xiclog(xlog_in_core_t *iclog)
-{
- int i;
- static char *ic_flags[] = {
- "ACTIVE", /* 0x0001 */
- "WANT_SYNC", /* 0x0002 */
- "SYNCING", /* 0X0004 */
- "DONE_SYNC", /* 0X0008 */
- "DO_CALLBACK", /* 0X0010 */
- "CALLBACK", /* 0X0020 */
- "DIRTY", /* 0X0040 */
- "IOERROR", /* 0X0080 */
- "NOTUSED", /* 0X8000 */
- NULL
- };
-
- kdb_printf("xlog_in_core/header at 0x%p/0x%p\n",
- iclog, iclog->hic_data);
- kdb_printf("magicno: %x cycle: %d version: %d lsn: 0x%Lx\n",
- INT_GET(iclog->ic_header.h_magicno, ARCH_CONVERT), INT_GET(iclog->ic_header.h_cycle, ARCH_CONVERT),
- INT_GET(iclog->ic_header.h_version, ARCH_CONVERT), INT_GET(iclog->ic_header.h_lsn, ARCH_CONVERT));
- kdb_printf("tail_lsn: 0x%Lx len: %d prev_block: %d num_ops: %d\n",
- INT_GET(iclog->ic_header.h_tail_lsn, ARCH_CONVERT), INT_GET(iclog->ic_header.h_len, ARCH_CONVERT),
- INT_GET(iclog->ic_header.h_prev_block, ARCH_CONVERT), INT_GET(iclog->ic_header.h_num_logops, ARCH_CONVERT));
- kdb_printf("cycle_data: ");
- for (i=0; i<(iclog->ic_size>>BBSHIFT); i++) {
- kdb_printf("%x ", INT_GET(iclog->ic_header.h_cycle_data[i], ARCH_CONVERT));
- }
- kdb_printf("\n");
- kdb_printf("size: %d\n", INT_GET(iclog->ic_header.h_size, ARCH_CONVERT));
- kdb_printf("\n");
- kdb_printf("--------------------------------------------------\n");
- kdb_printf("data: 0x%p &forcesema: 0x%p next: 0x%p bp: 0x%p\n",
- iclog->ic_datap, &iclog->ic_forcesema, iclog->ic_next,
- iclog->ic_bp);
- kdb_printf("log: 0x%p callb: 0x%p callb_tail: 0x%p\n",
- iclog->ic_log, iclog->ic_callback, iclog->ic_callback_tail);
- kdb_printf("size: %d (OFFSET: %d) trace: 0x%p refcnt: %d bwritecnt: %d",
- iclog->ic_size, iclog->ic_offset,
-#ifdef XFS_LOG_TRACE
- iclog->ic_trace,
-#else
- NULL,
-#endif
- iclog->ic_refcnt, iclog->ic_bwritecnt);
- if (iclog->ic_state & XLOG_STATE_ALL)
- printflags(iclog->ic_state, ic_flags, " state:");
- else
- kdb_printf(" state: INVALID 0x%x", iclog->ic_state);
- kdb_printf("\n");
-} /* xfsidbg_xiclog */
-
-
-/*
- * Print all incore logs.
- */
-static void
-xfsidbg_xiclogall(xlog_in_core_t *iclog)
-{
- xlog_in_core_t *first_iclog = iclog;
-
- do {
- xfsidbg_xiclog(iclog);
- kdb_printf("=================================================\n");
- iclog = iclog->ic_next;
- } while (iclog != first_iclog);
-} /* xfsidbg_xiclogall */
-
-/*
- * Print out the callback structures attached to an iclog.
- */
-static void
-xfsidbg_xiclogcb(xlog_in_core_t *iclog)
-{
- xfs_log_callback_t *cb;
- kdb_symtab_t symtab;
-
- for (cb = iclog->ic_callback; cb != NULL; cb = cb->cb_next) {
-
- if (kdbnearsym((unsigned long)cb->cb_func, &symtab)) {
- unsigned long offval;
-
- offval = (unsigned long)cb->cb_func - symtab.sym_start;
-
- if (offval)
- kdb_printf("func = %s+0x%lx",
- symtab.sym_name,
- offval);
- else
- kdb_printf("func = %s", symtab.sym_name);
- } else
- kdb_printf("func = ?? 0x%p", (void *)cb->cb_func);
-
- kdb_printf(" arg 0x%p next 0x%p\n", cb->cb_arg, cb->cb_next);
- }
-}
-
-#ifdef XFS_LOG_TRACE
-/*
- * Print trace from incore log.
- */
-static void
-xfsidbg_xiclogtrace(xlog_in_core_t *iclog)
-{
- ktrace_entry_t *ktep;
- ktrace_snap_t kts;
- ktrace_t *kt = iclog->ic_trace;
-
- qprintf("iclog->ic_trace 0x%p\n", kt);
- ktep = ktrace_first(kt, &kts);
- while (ktep != NULL) {
- switch ((__psint_t)ktep->val[0]) {
- case XLOG_TRACE_GRAB_FLUSH: {
- qprintf("grabbing semaphore\n");
- break;
- }
- case XLOG_TRACE_REL_FLUSH: {
- qprintf("releasing semaphore\n");
- break;
- }
- case XLOG_TRACE_SLEEP_FLUSH: {
- qprintf("sleeping on semaphore\n");
- break;
- }
- case XLOG_TRACE_WAKE_FLUSH: {
- qprintf("waking up on semaphore\n");
- break;
- }
- default: {
- }
- }
- ktep = ktrace_next(kt, &kts);
- }
-} /* xfsidbg_xiclogtrace */
-#endif
-
-/*
- * Print all of the inodes attached to the given mount structure.
- */
-static void
-xfsidbg_xinodes(xfs_mount_t *mp)
-{
- xfs_inode_t *ip;
-
- kdb_printf("xfs_mount at 0x%p\n", mp);
- ip = mp->m_inodes;
- if (ip != NULL) {
- do {
- if (ip->i_mount == NULL) {
- ip = ip->i_mnext;
- continue;
- }
- kdb_printf("\n");
- xfsidbg_xnode(ip);
- ip = ip->i_mnext;
- } while (ip != mp->m_inodes);
- }
- kdb_printf("\nEnd of Inodes\n");
-}
-
-static void
-xfsidbg_delayed_blocks(xfs_mount_t *mp)
-{
- xfs_inode_t *ip;
- unsigned int total = 0;
- unsigned int icount = 0;
-
- ip = mp->m_inodes;
- if (ip != NULL) {
- do {
- if (ip->i_mount == NULL) {
- ip = ip->i_mnext;
- continue;
- }
- if (ip->i_delayed_blks) {
- total += ip->i_delayed_blks;
- icount++;
- }
- ip = ip->i_mnext;
- } while (ip != mp->m_inodes);
- }
- kdb_printf("delayed blocks total: %d in %d inodes\n", total, icount);
-}
-
-static void
-xfsidbg_xinodes_quiesce(xfs_mount_t *mp)
-{
- xfs_inode_t *ip;
-
- kdb_printf("xfs_mount at 0x%p\n", mp);
- ip = mp->m_inodes;
- if (ip != NULL) {
- do {
- if (ip->i_mount == NULL) {
- ip = ip->i_mnext;
- continue;
- }
- if (!(ip->i_flags & XFS_IQUIESCE)) {
- kdb_printf("ip 0x%p not quiesced\n", ip);
- }
- ip = ip->i_mnext;
- } while (ip != mp->m_inodes);
- }
- kdb_printf("\nEnd of Inodes\n");
-}
-
-static char *
-xfsidbg_get_cstate(int state)
-{
- switch(state) {
- case XLOG_STATE_COVER_IDLE:
- return("idle");
- case XLOG_STATE_COVER_NEED:
- return("need");
- case XLOG_STATE_COVER_DONE:
- return("done");
- case XLOG_STATE_COVER_NEED2:
- return("need2");
- case XLOG_STATE_COVER_DONE2:
- return("done2");
- default:
- return("unknown");
- }
-}
-
-/*
- * Print out an XFS log structure.
- */
-static void
-xfsidbg_xlog(xlog_t *log)
-{
- static char *t_flags[] = {
- "CHKSUM_MISMATCH", /* 0x01 */
- "ACTIVE_RECOVERY", /* 0x02 */
- "RECOVERY_NEEDED", /* 0x04 */
- "IO_ERROR", /* 0x08 */
- NULL
- };
-
- kdb_printf("xlog at 0x%p\n", log);
- kdb_printf("&flushsm: 0x%p flushcnt: %d tic_cnt: %d tic_tcnt: %d \n",
- &log->l_flushsema, log->l_flushcnt,
- log->l_ticket_cnt, log->l_ticket_tcnt);
- kdb_printf("freelist: 0x%p tail: 0x%p ICLOG: 0x%p \n",
- log->l_freelist, log->l_tail, log->l_iclog);
- kdb_printf("&icloglock: 0x%p tail_lsn: %s last_sync_lsn: %s \n",
- &log->l_icloglock, xfs_fmtlsn(&log->l_tail_lsn),
- xfs_fmtlsn(&log->l_last_sync_lsn));
- kdb_printf("mp: 0x%p xbuf: 0x%p l_covered_state: %s \n",
- log->l_mp, log->l_xbuf,
- xfsidbg_get_cstate(log->l_covered_state));
- kdb_printf("flags: ");
- printflags(log->l_flags, t_flags,"log");
- kdb_printf(" logBBstart: %lld logsize: %d logBBsize: %d\n",
- (long long) log->l_logBBstart,
- log->l_logsize,log->l_logBBsize);
- kdb_printf("curr_cycle: %d prev_cycle: %d curr_block: %d prev_block: %d\n",
- log->l_curr_cycle, log->l_prev_cycle, log->l_curr_block,
- log->l_prev_block);
- kdb_printf("iclog_bak: 0x%p iclog_size: 0x%x (%d) num iclogs: %d\n",
- log->l_iclog_bak, log->l_iclog_size, log->l_iclog_size,
- log->l_iclog_bufs);
- kdb_printf("l_iclog_hsize %d l_iclog_heads %d\n",
- log->l_iclog_hsize, log->l_iclog_heads);
- kdb_printf("l_sectbb_log %u l_sectbb_mask %u\n",
- log->l_sectbb_log, log->l_sectbb_mask);
- kdb_printf("&grant_lock: 0x%p resHeadQ: 0x%p wrHeadQ: 0x%p\n",
- &log->l_grant_lock, log->l_reserve_headq, log->l_write_headq);
- kdb_printf("GResCycle: %d GResBytes: %d GWrCycle: %d GWrBytes: %d\n",
- log->l_grant_reserve_cycle, log->l_grant_reserve_bytes,
- log->l_grant_write_cycle, log->l_grant_write_bytes);
- qprintf("GResBlocks: %d GResRemain: %d GWrBlocks: %d GWrRemain: %d\n",
- (int)BTOBBT(log->l_grant_reserve_bytes),
- log->l_grant_reserve_bytes % BBSIZE,
- (int)BTOBBT(log->l_grant_write_bytes),
- log->l_grant_write_bytes % BBSIZE);
-#ifdef XFS_LOG_TRACE
- qprintf("trace: 0x%p grant_trace: use xlog value\n", log->l_trace);
-#endif
-} /* xfsidbg_xlog */
-
-static void
-xfsidbg_print_trans_type(unsigned int t_type)
-{
- switch (t_type) {
- case XFS_TRANS_SETATTR_NOT_SIZE: kdb_printf("SETATTR_NOT_SIZE");break;
- case XFS_TRANS_SETATTR_SIZE: kdb_printf("SETATTR_SIZE"); break;
- case XFS_TRANS_INACTIVE: kdb_printf("INACTIVE"); break;
- case XFS_TRANS_CREATE: kdb_printf("CREATE"); break;
- case XFS_TRANS_CREATE_TRUNC: kdb_printf("CREATE_TRUNC"); break;
- case XFS_TRANS_TRUNCATE_FILE: kdb_printf("TRUNCATE_FILE"); break;
- case XFS_TRANS_REMOVE: kdb_printf("REMOVE"); break;
- case XFS_TRANS_LINK: kdb_printf("LINK"); break;
- case XFS_TRANS_RENAME: kdb_printf("RENAME"); break;
- case XFS_TRANS_MKDIR: kdb_printf("MKDIR"); break;
- case XFS_TRANS_RMDIR: kdb_printf("RMDIR"); break;
- case XFS_TRANS_SYMLINK: kdb_printf("SYMLINK"); break;
- case XFS_TRANS_SET_DMATTRS: kdb_printf("SET_DMATTRS"); break;
- case XFS_TRANS_GROWFS: kdb_printf("GROWFS"); break;
- case XFS_TRANS_STRAT_WRITE: kdb_printf("STRAT_WRITE"); break;
- case XFS_TRANS_DIOSTRAT: kdb_printf("DIOSTRAT"); break;
- case XFS_TRANS_WRITE_SYNC: kdb_printf("WRITE_SYNC"); break;
- case XFS_TRANS_WRITEID: kdb_printf("WRITEID"); break;
- case XFS_TRANS_ADDAFORK: kdb_printf("ADDAFORK"); break;
- case XFS_TRANS_ATTRINVAL: kdb_printf("ATTRINVAL"); break;
- case XFS_TRANS_ATRUNCATE: kdb_printf("ATRUNCATE"); break;
- case XFS_TRANS_ATTR_SET: kdb_printf("ATTR_SET"); break;
- case XFS_TRANS_ATTR_RM: kdb_printf("ATTR_RM"); break;
- case XFS_TRANS_ATTR_FLAG: kdb_printf("ATTR_FLAG"); break;
- case XFS_TRANS_CLEAR_AGI_BUCKET:kdb_printf("CLEAR_AGI_BUCKET"); break;
- case XFS_TRANS_QM_SBCHANGE: kdb_printf("QM_SBCHANGE"); break;
- case XFS_TRANS_QM_QUOTAOFF: kdb_printf("QM_QUOTAOFF"); break;
- case XFS_TRANS_QM_DQALLOC: kdb_printf("QM_DQALLOC"); break;
- case XFS_TRANS_QM_SETQLIM: kdb_printf("QM_SETQLIM"); break;
- case XFS_TRANS_QM_DQCLUSTER: kdb_printf("QM_DQCLUSTER"); break;
- case XFS_TRANS_QM_QINOCREATE: kdb_printf("QM_QINOCREATE"); break;
- case XFS_TRANS_QM_QUOTAOFF_END: kdb_printf("QM_QOFF_END"); break;
- case XFS_TRANS_SB_UNIT: kdb_printf("SB_UNIT"); break;
- case XFS_TRANS_FSYNC_TS: kdb_printf("FSYNC_TS"); break;
- case XFS_TRANS_GROWFSRT_ALLOC: kdb_printf("GROWFSRT_ALLOC"); break;
- case XFS_TRANS_GROWFSRT_ZERO: kdb_printf("GROWFSRT_ZERO"); break;
- case XFS_TRANS_GROWFSRT_FREE: kdb_printf("GROWFSRT_FREE"); break;
- default: kdb_printf("unknown(0x%x)", t_type); break;
- }
-}
-
-#ifdef XFS_LOG_TRACE
-/*
- * Print grant trace for a log.
- */
-static void
-xfsidbg_xlog_granttrace(xlog_t *log)
-{
- ktrace_entry_t *ktep;
- ktrace_snap_t kts;
- ktrace_t *kt;
- int i = 0;
- unsigned long cnts,t_ocnt, t_cnt;
-
- if (((__psint_t)log) == ((__psint_t)-1)) {
- qprintf("Usage: xl_grtr <log>\n");
- return;
- }
- if ((kt = log->l_grant_trace))
- qprintf("log->l_grant_trace 0x%p\n", kt);
- else {
- qprintf("log->l_grant_trace is empty!\n");
- return;
- }
- ktep = ktrace_first(kt, &kts);
- while (ktep != NULL) {
- /* split cnts into two parts: cnt and ocnt */
- cnts = (unsigned long)ktep->val[13];
- t_ocnt = 0xff & cnts;
- t_cnt = cnts >> 8;
-
- qprintf("%d: %s [", i++, (char *)ktep->val[11]);
- xfsidbg_print_trans_type((unsigned long)ktep->val[12]);
- qprintf("]\n");
- qprintf(" t_ocnt = %lu, t_cnt = %lu, t_curr_res = %lu, "
- "t_unit_res = %lu\n",
- t_ocnt, t_cnt, (unsigned long)ktep->val[14],
- (unsigned long)ktep->val[15]);
- qprintf(" tic:0x%p resQ:0x%p wrQ:0x%p ",
- ktep->val[0], ktep->val[1], ktep->val[2]);
- qprintf(" GrResC:%ld GrResB:%ld GrWrC:%ld GrWrB:%ld \n",
- (long)ktep->val[3], (long)ktep->val[4],
- (long)ktep->val[5], (long)ktep->val[6]);
- qprintf(" HeadC:%ld HeadB:%ld TailC:%ld TailB:%ld\n",
- (long)ktep->val[7], (long)ktep->val[8],
- (long)ktep->val[9], (long)ktep->val[10]);
- ktep = ktrace_next(kt, &kts);
- }
-} /* xfsidbg_xlog_granttrace */
-#endif
-
-/*
- * Print out an XFS recovery transaction
- */
-static void
-xfsidbg_xlog_ritem(xlog_recover_item_t *item)
-{
- int i = XLOG_MAX_REGIONS_IN_ITEM;
-
- kdb_printf("(xlog_recover_item 0x%p) ", item);
- kdb_printf("next: 0x%p prev: 0x%p type: %d cnt: %d ttl: %d\n",
- item->ri_next, item->ri_prev, ITEM_TYPE(item), item->ri_cnt,
- item->ri_total);
- for ( ; i > 0; i--) {
- if (!item->ri_buf[XLOG_MAX_REGIONS_IN_ITEM-i].i_addr)
- break;
- kdb_printf("a: 0x%p l: %d ",
- item->ri_buf[XLOG_MAX_REGIONS_IN_ITEM-i].i_addr,
- item->ri_buf[XLOG_MAX_REGIONS_IN_ITEM-i].i_len);
- }
- kdb_printf("\n");
-} /* xfsidbg_xlog_ritem */
-
-/*
- * Print out an XFS recovery transaction
- */
-static void
-xfsidbg_xlog_rtrans(xlog_recover_t *trans)
-{
- xlog_recover_item_t *rip, *first_rip;
-
- kdb_printf("(xlog_recover 0x%p) ", trans);
- kdb_printf("tid: %x type: %d items: %d ttid: 0x%x ",
- trans->r_log_tid, trans->r_theader.th_type,
- trans->r_theader.th_num_items, trans->r_theader.th_tid);
- kdb_printf("itemq: 0x%p\n", trans->r_itemq);
- if (trans->r_itemq) {
- rip = first_rip = trans->r_itemq;
- do {
- kdb_printf("(recovery item: 0x%p) ", rip);
- kdb_printf("type: %d cnt: %d total: %d\n",
- ITEM_TYPE(rip), rip->ri_cnt, rip->ri_total);
- rip = rip->ri_next;
- } while (rip != first_rip);
- }
-} /* xfsidbg_xlog_rtrans */
-
-static void
-xfsidbg_xlog_buf_logitem(xlog_recover_item_t *item)
-{
- xfs_buf_log_format_t *buf_f;
- int i, j;
- int bit;
- int nbits;
- unsigned int *data_map;
- unsigned int map_size;
- int size;
-
- buf_f = (xfs_buf_log_format_t *)item->ri_buf[0].i_addr;
- if (buf_f->blf_flags & XFS_BLI_INODE_BUF) {
- kdb_printf("\tINODE BUF <blkno=0x%Lx, len=0x%x>\n",
- buf_f->blf_blkno, buf_f->blf_len);
- } else if (buf_f->blf_flags &
- (XFS_BLI_UDQUOT_BUF|XFS_BLI_PDQUOT_BUF|XFS_BLI_GDQUOT_BUF)) {
- kdb_printf("\tDQUOT BUF <blkno=0x%Lx, len=0x%x>\n",
- buf_f->blf_blkno, buf_f->blf_len);
- } else {
- data_map = buf_f->blf_data_map;
- map_size = buf_f->blf_map_size;
- kdb_printf("\tREG BUF <blkno=0x%Lx, len=0x%x map 0x%p size %d>\n",
- buf_f->blf_blkno, buf_f->blf_len, data_map, map_size);
- bit = 0;
- i = 0; /* 0 is the buf format structure */
- while (1) {
- bit = xfs_next_bit(data_map, map_size, bit);
- if (bit == -1)
- break;
- nbits = xfs_contig_bits(data_map, map_size, bit);
- size = ((uint)bit << XFS_BLI_SHIFT)+(nbits<<XFS_BLI_SHIFT);
- kdb_printf("\t\tlogbuf.i_addr 0x%p, size 0x%x\n",
- item->ri_buf[i].i_addr, size);
- kdb_printf("\t\t\t\"");
- for (j=0; j<8 && j<size; j++) {
- kdb_printf("%02x", ((char *)item->ri_buf[i].i_addr)[j]);
- }
- kdb_printf("...\"\n");
- i++;
- bit += nbits;
- }
-
- }
-}
-
-/*
- * Print out an ENTIRE XFS recovery transaction
- */
-static void
-xfsidbg_xlog_rtrans_entire(xlog_recover_t *trans)
-{
- xlog_recover_item_t *item, *first_rip;
-
- kdb_printf("(Recovering Xact 0x%p) ", trans);
- kdb_printf("tid: %x type: %d nitems: %d ttid: 0x%x ",
- trans->r_log_tid, trans->r_theader.th_type,
- trans->r_theader.th_num_items, trans->r_theader.th_tid);
- kdb_printf("itemq: 0x%p\n", trans->r_itemq);
- if (trans->r_itemq) {
- item = first_rip = trans->r_itemq;
- do {
- /*
- kdb_printf("(recovery item: 0x%x) ", item);
- kdb_printf("type: %d cnt: %d total: %d\n",
- item->ri_type, item->ri_cnt, item->ri_total);
- */
- if ((ITEM_TYPE(item) == XFS_LI_BUF) ||
- (ITEM_TYPE(item) == XFS_LI_6_1_BUF) ||
- (ITEM_TYPE(item) == XFS_LI_5_3_BUF)) {
- kdb_printf("BUF:");
- xfsidbg_xlog_buf_logitem(item);
- } else if ((ITEM_TYPE(item) == XFS_LI_INODE) ||
- (ITEM_TYPE(item) == XFS_LI_6_1_INODE) ||
- (ITEM_TYPE(item) == XFS_LI_5_3_INODE)) {
- kdb_printf("INODE:\n");
- } else if (ITEM_TYPE(item) == XFS_LI_EFI) {
- kdb_printf("EFI:\n");
- } else if (ITEM_TYPE(item) == XFS_LI_EFD) {
- kdb_printf("EFD:\n");
- } else if (ITEM_TYPE(item) == XFS_LI_DQUOT) {
- kdb_printf("DQUOT:\n");
- } else if ((ITEM_TYPE(item) == XFS_LI_QUOTAOFF)) {
- kdb_printf("QUOTAOFF:\n");
- } else {
- kdb_printf("UNKNOWN LOGITEM 0x%x\n", ITEM_TYPE(item));
- }
- item = item->ri_next;
- } while (item != first_rip);
- }
-} /* xfsidbg_xlog_rtrans */
-
-/*
- * Print out an XFS ticket structure.
- */
-static void
-xfsidbg_xlog_tic(xlog_ticket_t *tic)
-{
- static char *t_flags[] = {
- "INIT", /* 0x1 */
- "PERM_RES", /* 0x2 */
- "IN_Q", /* 0x4 */
- NULL
- };
-
- kdb_printf("xlog_ticket at 0x%p\n", tic);
- kdb_printf("next: 0x%p prev: 0x%p tid: 0x%x \n",
- tic->t_next, tic->t_prev, tic->t_tid);
- kdb_printf("curr_res: %d unit_res: %d ocnt: %d cnt: %d\n",
- tic->t_curr_res, tic->t_unit_res, (int)tic->t_ocnt,
- (int)tic->t_cnt);
- kdb_printf("clientid: %c \n", tic->t_clientid);
- printflags(tic->t_flags, t_flags,"ticket");
- kdb_printf("\n");
- qprintf("trans type: ");
- xfsidbg_print_trans_type(tic->t_trans_type);
- qprintf("\n");
-} /* xfsidbg_xlog_tic */
-
-/*
- * Print out a single log item.
- */
-static void
-xfsidbg_xlogitem(xfs_log_item_t *lip)
-{
- xfs_log_item_t *bio_lip;
- static char *lid_type[] = {
- "???", /* 0 */
- "5-3-buf", /* 1 */
- "5-3-inode", /* 2 */
- "efi", /* 3 */
- "efd", /* 4 */
- "iunlink", /* 5 */
- "6-1-inode", /* 6 */
- "6-1-buf", /* 7 */
- "inode", /* 8 */
- "buf", /* 9 */
- "dquot", /* 10 */
- NULL
- };
- static char *li_flags[] = {
- "in ail", /* 0x1 */
- NULL
- };
-
- kdb_printf("type %s mountp 0x%p flags ",
- lid_type[lip->li_type - XFS_LI_5_3_BUF + 1],
- lip->li_mountp);
- printflags((uint)(lip->li_flags), li_flags,"log");
- kdb_printf("\n");
- kdb_printf("ail forw 0x%p ail back 0x%p lsn %s\ndesc %p ops 0x%p",
- lip->li_ail.ail_forw, lip->li_ail.ail_back,
- xfs_fmtlsn(&(lip->li_lsn)), lip->li_desc, lip->li_ops);
- kdb_printf(" iodonefunc &0x%p\n", lip->li_cb);
- if (lip->li_type == XFS_LI_BUF) {
- bio_lip = lip->li_bio_list;
- if (bio_lip != NULL) {
- kdb_printf("iodone list:\n");
- }
- while (bio_lip != NULL) {
- kdb_printf("item 0x%p func 0x%p\n",
- bio_lip, bio_lip->li_cb);
- bio_lip = bio_lip->li_bio_list;
- }
- }
- switch (lip->li_type) {
- case XFS_LI_BUF:
- xfs_buf_item_print((xfs_buf_log_item_t *)lip, 0);
- break;
- case XFS_LI_INODE:
- xfs_inode_item_print((xfs_inode_log_item_t *)lip, 0);
- break;
- case XFS_LI_EFI:
- xfs_efi_item_print((xfs_efi_log_item_t *)lip, 0);
- break;
- case XFS_LI_EFD:
- xfs_efd_item_print((xfs_efd_log_item_t *)lip, 0);
- break;
- case XFS_LI_DQUOT:
- xfs_dquot_item_print((xfs_dq_logitem_t *)lip, 0);
- break;
- case XFS_LI_QUOTAOFF:
- xfs_qoff_item_print((xfs_qoff_logitem_t *)lip, 0);
- break;
-
- default:
- kdb_printf("Unknown item type %d\n", lip->li_type);
- break;
- }
-}
-
-/*
- * Print out a summary of the AIL hanging off of a mount struct.
- */
-static void
-xfsidbg_xaildump(xfs_mount_t *mp)
-{
- xfs_log_item_t *lip;
- static char *lid_type[] = {
- "???", /* 0 */
- "5-3-buf", /* 1 */
- "5-3-inode", /* 2 */
- "efi", /* 3 */
- "efd", /* 4 */
- "iunlink", /* 5 */
- "6-1-inode", /* 6 */
- "6-1-buf", /* 7 */
- "inode", /* 8 */
- "buf", /* 9 */
- "dquot", /* 10 */
- NULL
- };
- static char *li_flags[] = {
- "in ail", /* 0x1 */
- NULL
- };
- int count;
-
- if ((mp->m_ail.ail_forw == NULL) ||
- (mp->m_ail.ail_forw == (xfs_log_item_t *)&mp->m_ail)) {
- kdb_printf("AIL is empty\n");
- return;
- }
- kdb_printf("AIL for mp 0x%p, oldest first\n", mp);
- lip = (xfs_log_item_t*)mp->m_ail.ail_forw;
- for (count = 0; lip; count++) {
- kdb_printf("[%d] type %s ", count,
- lid_type[lip->li_type - XFS_LI_5_3_BUF + 1]);
- printflags((uint)(lip->li_flags), li_flags, "flags:");
- kdb_printf(" lsn %s\n ", xfs_fmtlsn(&(lip->li_lsn)));
- switch (lip->li_type) {
- case XFS_LI_BUF:
- xfs_buf_item_print((xfs_buf_log_item_t *)lip, 1);
- break;
- case XFS_LI_INODE:
- xfs_inode_item_print((xfs_inode_log_item_t *)lip, 1);
- break;
- case XFS_LI_EFI:
- xfs_efi_item_print((xfs_efi_log_item_t *)lip, 1);
- break;
- case XFS_LI_EFD:
- xfs_efd_item_print((xfs_efd_log_item_t *)lip, 1);
- break;
- case XFS_LI_DQUOT:
- xfs_dquot_item_print((xfs_dq_logitem_t *)lip, 1);
- break;
- case XFS_LI_QUOTAOFF:
- xfs_qoff_item_print((xfs_qoff_logitem_t *)lip, 1);
- break;
- default:
- kdb_printf("Unknown item type %d\n", lip->li_type);
- break;
- }
-
- if (lip->li_ail.ail_forw == (xfs_log_item_t*)&mp->m_ail) {
- lip = NULL;
- } else {
- lip = lip->li_ail.ail_forw;
- }
- }
-}
-
-/*
- * Print xfs mount structure.
- */
-static void
-xfsidbg_xmount(xfs_mount_t *mp)
-{
- static char *xmount_flags[] = {
- "WSYNC", /* 0x0001 */
- "INO64", /* 0x0002 */
- "UNUSED_4", /* 0x0004 */
- "UNUSED_8", /* 0x0008 */
- "FSSHUTDOWN", /* 0x0010 */
- "NOATIME", /* 0x0020 */
- "RETERR", /* 0x0040 */
- "NOALIGN", /* 0x0080 */
- "ATTR2", /* 0x0100 */
- "UNUSED_200", /* 0x0200 */
- "NORECOVERY", /* 0x0400 */
- "SHARED", /* 0x0800 */
- "DFLT_IOSIZE", /* 0x1000 */
- "OSYNCISOSYNC", /* 0x2000 */
- "32BITINODES", /* 0x4000 */
- "32BITINOOPT", /* 0x8000 */
- "NOUUID", /* 0x10000 */
- "BARRIER", /* 0x20000 */
- "IDELETE", /* 0x40000 */
- "SWALLOC", /* 0x80000 */
- "IHASHSIZE", /* 0x100000 */
- "DIRSYNC", /* 0x200000 */
- "COMPAT_IOSIZE",/* 0x400000 */
- NULL
- };
-
- static char *quota_flags[] = {
- "UQ", /* 0x0001 */
- "UQE", /* 0x0002 */
- "UQCHKD", /* 0x0004 */
- "PQ", /* 0x0008 */
- "GQE", /* 0x0010 */
- "GQCHKD", /* 0x0020 */
- "GQ", /* 0x0040 */
- "UQACTV", /* 0x0080 */
- "GQACTV", /* 0x0100 */
- "QMAYBE", /* 0x0200 */
- NULL
- };
-
- kdb_printf("xfs_mount at 0x%p\n", mp);
- kdb_printf("vfsp 0x%p tid 0x%x ail_lock 0x%p &ail 0x%p\n",
- XFS_MTOVFS(mp), mp->m_tid, &mp->m_ail_lock, &mp->m_ail);
- kdb_printf("ail_gen 0x%x &sb 0x%p\n",
- mp->m_ail_gen, &mp->m_sb);
- kdb_printf("sb_lock 0x%p sb_bp 0x%p dev 0x%s logdev 0x%s rtdev 0x%s\n",
- &mp->m_sb_lock, mp->m_sb_bp,
- mp->m_ddev_targp ? devtoname(mp->m_ddev_targp->dev) : 0,
- mp->m_logdev_targp ? devtoname(mp->m_logdev_targp->dev) : 0,
- mp->m_rtdev_targp ? devtoname(mp->m_rtdev_targp->dev) : 0);
- kdb_printf("bsize %d agfrotor %d xfs_rotorstep %d agirotor %d\n",
- mp->m_bsize, mp->m_agfrotor, xfs_rotorstep, mp->m_agirotor);
- kdb_printf("ihash 0x%p ihsize %d\n",
- mp->m_ihash, mp->m_ihsize);
- kdb_printf("inodes 0x%p ilock 0x%p ireclaims 0x%x\n",
- mp->m_inodes, &mp->m_ilock, mp->m_ireclaims);
- kdb_printf("readio_log 0x%x readio_blocks 0x%x ",
- mp->m_readio_log, mp->m_readio_blocks);
- kdb_printf("writeio_log 0x%x writeio_blocks 0x%x\n",
- mp->m_writeio_log, mp->m_writeio_blocks);
- kdb_printf("logbufs %d logbsize %d LOG 0x%p\n", mp->m_logbufs,
- mp->m_logbsize, mp->m_log);
- kdb_printf("rsumlevels 0x%x rsumsize 0x%x rbmip 0x%p rsumip 0x%p\n",
- mp->m_rsumlevels, mp->m_rsumsize, mp->m_rbmip, mp->m_rsumip);
- kdb_printf("rootip 0x%p\n", mp->m_rootip);
- kdb_printf("dircook_elog %d blkbit_log %d blkbb_log %d agno_log %d\n",
- mp->m_dircook_elog, mp->m_blkbit_log, mp->m_blkbb_log,
- mp->m_agno_log);
- kdb_printf("agino_log %d nreadaheads %d inode cluster size %d\n",
- mp->m_agino_log, mp->m_nreadaheads,
- mp->m_inode_cluster_size);
- kdb_printf("blockmask 0x%x blockwsize 0x%x blockwmask 0x%x\n",
- mp->m_blockmask, mp->m_blockwsize, mp->m_blockwmask);
- kdb_printf("alloc_mxr[lf,nd] %d %d alloc_mnr[lf,nd] %d %d\n",
- mp->m_alloc_mxr[0], mp->m_alloc_mxr[1],
- mp->m_alloc_mnr[0], mp->m_alloc_mnr[1]);
- kdb_printf("bmap_dmxr[lfnr,ndnr] %d %d bmap_dmnr[lfnr,ndnr] %d %d\n",
- mp->m_bmap_dmxr[0], mp->m_bmap_dmxr[1],
- mp->m_bmap_dmnr[0], mp->m_bmap_dmnr[1]);
- kdb_printf("inobt_mxr[lf,nd] %d %d inobt_mnr[lf,nd] %d %d\n",
- mp->m_inobt_mxr[0], mp->m_inobt_mxr[1],
- mp->m_inobt_mnr[0], mp->m_inobt_mnr[1]);
- kdb_printf("ag_maxlevels %d bm_maxlevels[d,a] %d %d in_maxlevels %d\n",
- mp->m_ag_maxlevels, mp->m_bm_maxlevels[0],
- mp->m_bm_maxlevels[1], mp->m_in_maxlevels);
- kdb_printf("perag 0x%p &peraglock 0x%p &growlock 0x%p\n",
- mp->m_perag, &mp->m_peraglock, &mp->m_growlock);
- printflags(mp->m_flags, xmount_flags,"flags");
- kdb_printf("ialloc_inos %d ialloc_blks %d litino %d\n",
- mp->m_ialloc_inos, mp->m_ialloc_blks, mp->m_litino);
- kdb_printf("dir_node_ents %u attr_node_ents %u\n",
- mp->m_dir_node_ents, mp->m_attr_node_ents);
- kdb_printf("attroffset %d maxicount %Ld inoalign_mask %d\n",
- mp->m_attroffset, mp->m_maxicount, mp->m_inoalign_mask);
- kdb_printf("resblks %Ld resblks_avail %Ld\n", mp->m_resblks,
- mp->m_resblks_avail);
-#if XFS_BIG_INUMS
- kdb_printf(" inoadd %llx\n", (unsigned long long) mp->m_inoadd);
-#else
- kdb_printf("\n");
-#endif
- if (mp->m_quotainfo)
- kdb_printf("quotainfo 0x%p (uqip = 0x%p, gqip = 0x%p)\n",
- mp->m_quotainfo,
- mp->m_quotainfo->qi_uquotaip,
- mp->m_quotainfo->qi_gquotaip);
- else
- kdb_printf("quotainfo NULL\n");
- printflags(mp->m_qflags, quota_flags,"quotaflags");
- kdb_printf("\n");
- kdb_printf("dalign %d swidth %d sinoalign %d attr_magicpct %d dir_magicpct %d\n",
- mp->m_dalign, mp->m_swidth, mp->m_sinoalign,
- mp->m_attr_magicpct, mp->m_dir_magicpct);
- kdb_printf("mk_sharedro %d inode_quiesce %d sectbb_log %d\n",
- mp->m_mk_sharedro, mp->m_inode_quiesce, mp->m_sectbb_log);
- kdb_printf("dirversion %d dirblkfsbs %d &dirops 0x%p\n",
- mp->m_dirversion, mp->m_dirblkfsbs, &mp->m_dirops);
- kdb_printf("dirblksize %d dirdatablk 0x%Lx dirleafblk 0x%Lx dirfreeblk 0x%Lx\n",
- mp->m_dirblksize,
- (xfs_dfiloff_t)mp->m_dirdatablk,
- (xfs_dfiloff_t)mp->m_dirleafblk,
- (xfs_dfiloff_t)mp->m_dirfreeblk);
- kdb_printf("chsize %d chash 0x%p\n",
- mp->m_chsize, mp->m_chash);
- if (mp->m_fsname != NULL)
- kdb_printf("mountpoint \"%s\"\n", mp->m_fsname);
- else
- kdb_printf("No name!!!\n");
-
-}
-
-static void
-xfsidbg_xihash(xfs_mount_t *mp)
-{
- xfs_ihash_t *ih;
- int i;
- int j;
- int total;
- int numzeros;
- xfs_inode_t *ip;
- int *hist;
- int hist_bytes = mp->m_ihsize * sizeof(int);
- int hist2[21];
-
- hist = (int *) kmem_alloc(hist_bytes, KM_SLEEP);
-
- if (hist == NULL) {
- kdb_printf("xfsidbg_xihash: kmalloc(%d) failed!\n",
- hist_bytes);
- return;
- }
-
- for (i = 0; i < mp->m_ihsize; i++) {
- ih = mp->m_ihash + i;
- j = 0;
- for (ip = ih->ih_next; ip != NULL; ip = ip->i_next)
- j++;
- hist[i] = j;
- }
-
- numzeros = total = 0;
-
- for (i = 0; i < 21; i++)
- hist2[i] = 0;
-
- for (i = 0; i < mp->m_ihsize; i++) {
- kdb_printf("%d ", hist[i]);
- total += hist[i];
- numzeros += hist[i] == 0 ? 1 : 0;
- if (hist[i] > 20)
- j = 20;
- else
- j = hist[i];
-
- if (! (j <= 20)) {
- kdb_printf("xfsidbg_xihash: (j > 20)/%d @ line # %d\n",
- j, __LINE__);
- return;
- }
-
- hist2[j]++;
- }
-
- kdb_printf("\n");
-
- kdb_printf("total inodes = %d, average length = %d, adjusted average = %d \n",
- total, total / mp->m_ihsize,
- total / (mp->m_ihsize - numzeros));
-
- for (i = 0; i < 21; i++) {
- kdb_printf("%d - %d , ", i, hist2[i]);
- }
- kdb_printf("\n");
- kmem_free(hist, hist_bytes);
-}
-
-/*
- * Command to print xfs inodes: kp xnode <addr>
- */
-static void
-xfsidbg_xnode(xfs_inode_t *ip)
-{
- static char *tab_flags[] = {
- "grio", /* XFS_IGRIO */
- "uiosize", /* XFS_IUIOSZ */
- "quiesce", /* XFS_IQUIESCE */
- "reclaim", /* XFS_IRECLAIM */
- "stale", /* XFS_ISTALE */
- NULL
- };
-
- kdb_printf("hash 0x%p next 0x%p prevp 0x%p mount 0x%p\n",
- ip->i_hash,
- ip->i_next,
- ip->i_prevp,
- ip->i_mount);
- kdb_printf("mnext 0x%p mprev 0x%p vnode 0x%p \n",
- ip->i_mnext,
- ip->i_mprev,
- XFS_ITOV_NULL(ip));
- kdb_printf("dev %s ino %s\n",
- devtoname(ip->i_mount->m_dev),
- xfs_fmtino(ip->i_ino, ip->i_mount));
- kdb_printf("blkno 0x%llx len 0x%x boffset 0x%x\n",
- (long long) ip->i_blkno,
- ip->i_len,
- ip->i_boffset);
- kdb_printf("transp 0x%p &itemp 0x%p\n",
- ip->i_transp,
- ip->i_itemp);
- kdb_printf("&lock 0x%p &iolock 0x%p ",
- &ip->i_lock,
- &ip->i_iolock);
- kdb_printf("&flock 0x%p (%d) pincount 0x%x\n",
- &ip->i_flock, valusema(&ip->i_flock),
- xfs_ipincount(ip));
- kdb_printf("udquotp 0x%p gdquotp 0x%p\n",
- ip->i_udquot, ip->i_gdquot);
- kdb_printf("new_size %Ld\n", ip->i_iocore.io_new_size);
- printflags((int)ip->i_flags, tab_flags, "flags");
- kdb_printf("\n");
- kdb_printf("update_core %d update size %d\n",
- (int)(ip->i_update_core), (int) ip->i_update_size);
- kdb_printf("gen 0x%x delayed blks %d",
- ip->i_gen,
- ip->i_delayed_blks);
-#ifdef XFS_BMAP_TRACE
- qprintf(" bmap_trace 0x%p\n", ip->i_xtrace);
-#endif
-#ifdef XFS_BMBT_TRACE
- qprintf(" bmbt trace 0x%p\n", ip->i_btrace);
-#endif
-#ifdef XFS_RW_TRACE
- qprintf(" rw trace 0x%p\n", ip->i_rwtrace);
-#endif
-#ifdef XFS_ILOCK_TRACE
- qprintf(" ilock trace 0x%p\n", ip->i_lock_trace);
-#endif
-#ifdef XFS_DIR2_TRACE
- qprintf(" dir trace 0x%p\n", ip->i_dir_trace);
-#endif
- kdb_printf("\n");
- kdb_printf("chash 0x%p cnext 0x%p cprev 0x%p\n",
- ip->i_chash,
- ip->i_cnext,
- ip->i_cprev);
- xfs_xnode_fork("data", &ip->i_df);
- xfs_xnode_fork("attr", ip->i_afp);
- kdb_printf("\n");
- xfs_prdinode_core(&ip->i_d);
-}
-
-static void
-xfsidbg_xcore(xfs_iocore_t *io)
-{
- kdb_printf("io_obj 0x%p io_flags 0x%x io_mount 0x%p\n",
- io->io_obj, io->io_flags, io->io_mount);
- kdb_printf("new_size %Lx\n", io->io_new_size);
-}
-
-/*
- * Command to print xfs inode cluster hash table: kp xchash <addr>
- */
-static void
-xfsidbg_xchash(xfs_mount_t *mp)
-{
- int i;
- xfs_chash_t *ch;
-
- kdb_printf("m_chash 0x%p size %d\n",
- mp->m_chash, mp->m_chsize);
- for (i = 0; i < mp->m_chsize; i++) {
- ch = mp->m_chash + i;
- kdb_printf("[%3d] ch 0x%p chashlist 0x%p\n", i, ch, ch->ch_list);
- xfsidbg_xchashlist(ch->ch_list);
- }
-}
-
-/*
- * Command to print xfs inode cluster hash list: kp xchashlist <addr>
- */
-static void
-xfsidbg_xchashlist(xfs_chashlist_t *chl)
-{
- xfs_inode_t *ip;
-
- while (chl != NULL) {
- kdb_printf("hashlist inode 0x%p blkno %lld buf 0x%p",
- chl->chl_ip, (long long) chl->chl_blkno, chl->chl_buf);
-
- kdb_printf("\n");
-
- /* print inodes on chashlist */
- ip = chl->chl_ip;
- do {
- kdb_printf("0x%p ", ip);
- ip = ip->i_cnext;
- } while (ip != chl->chl_ip);
- kdb_printf("\n");
-
- chl=chl->chl_next;
- }
-}
-
-/*
- * Print xfs per-ag data structures for filesystem.
- */
-static void
-xfsidbg_xperag(xfs_mount_t *mp)
-{
- xfs_agnumber_t agno;
- xfs_perag_t *pag;
- int busy;
-
- pag = mp->m_perag;
- for (agno = 0; agno < mp->m_sb.sb_agcount; agno++, pag++) {
- kdb_printf("ag %d f_init %d i_init %d\n",
- agno, pag->pagf_init, pag->pagi_init);
- if (pag->pagf_init)
- kdb_printf(
- " f_levels[b,c] %d,%d f_flcount %d f_freeblks %d f_longest %d\n"
- " f__metadata %d\n",
- pag->pagf_levels[XFS_BTNUM_BNOi],
- pag->pagf_levels[XFS_BTNUM_CNTi],
- pag->pagf_flcount, pag->pagf_freeblks,
- pag->pagf_longest, pag->pagf_metadata);
- if (pag->pagi_init)
- kdb_printf(" i_freecount %d i_inodeok %d\n",
- pag->pagi_freecount, pag->pagi_inodeok);
- if (pag->pagf_init) {
- for (busy = 0; busy < XFS_PAGB_NUM_SLOTS; busy++) {
- if (pag->pagb_list[busy].busy_length != 0) {
- kdb_printf(
- " %04d: start %d length %d tp 0x%p\n",
- busy,
- pag->pagb_list[busy].busy_start,
- pag->pagb_list[busy].busy_length,
- pag->pagb_list[busy].busy_tp);
- }
- }
- }
- }
-}
-
-#ifdef CONFIG_XFS_QUOTA
-static void
-xfsidbg_xqm(void)
-{
- if (xfs_Gqm == NULL) {
- kdb_printf("NULL XQM!!\n");
- return;
- }
-
- kdb_printf("usrhtab 0x%p grphtab 0x%p ndqfree 0x%x hashmask 0x%x\n",
- xfs_Gqm->qm_usr_dqhtable,
- xfs_Gqm->qm_grp_dqhtable,
- xfs_Gqm->qm_dqfreelist.qh_nelems,
- xfs_Gqm->qm_dqhashmask);
- kdb_printf("&freelist 0x%p, totaldquots 0x%x nrefs 0x%x\n",
- &xfs_Gqm->qm_dqfreelist,
- atomic_read(&xfs_Gqm->qm_totaldquots),
- xfs_Gqm->qm_nrefs);
-}
-#endif
-
-static void
-xfsidbg_xqm_diskdq(xfs_disk_dquot_t *d)
-{
- kdb_printf("magic 0x%x\tversion 0x%x\tID 0x%x (%d)\t\n",
- be16_to_cpu(d->d_magic), d->d_version,
- be32_to_cpu(d->d_id), be32_to_cpu(d->d_id));
- kdb_printf("bhard 0x%llx\tbsoft 0x%llx\tihard 0x%llx\tisoft 0x%llx\n",
- be64_to_cpu(d->d_blk_hardlimit),
- be64_to_cpu(d->d_blk_softlimit),
- be64_to_cpu(d->d_ino_hardlimit),
- be64_to_cpu(d->d_ino_softlimit));
- kdb_printf("bcount 0x%llx icount 0x%llx\n",
- be64_to_cpu(d->d_bcount),
- be64_to_cpu(d->d_icount));
- kdb_printf("btimer 0x%x itimer 0x%x \n",
- be32_to_cpu(d->d_btimer),
- be32_to_cpu(d->d_itimer));
-}
-
-static char *xdq_flags[] = {
- "USER", /* XFS_DQ_USER */
- "PROJ", /* XFS_DQ_PROJ */
- "GROUP", /* XFS_DQ_GROUP */
- "FLKD", /* XFS_DQ_FLOCKED */
- "DIRTY", /* XFS_DQ_DIRTY */
- "WANT", /* XFS_DQ_WANT */
- "INACT", /* XFS_DQ_INACTIVE */
- "MARKER", /* XFS_DQ_MARKER */
- NULL
-};
-
-static void
-xfsidbg_xqm_dquot(xfs_dquot_t *dqp)
-{
- kdb_printf("mount 0x%p hash 0x%p gdquotp 0x%p HL_next 0x%p HL_prevp 0x%p\n",
- dqp->q_mount,
- dqp->q_hash,
- dqp->q_gdquot,
- dqp->HL_NEXT,
- dqp->HL_PREVP);
- kdb_printf("MPL_next 0x%p MPL_prevp 0x%p FL_next 0x%p FL_prev 0x%p\n",
- dqp->MPL_NEXT,
- dqp->MPL_PREVP,
- dqp->dq_flnext,
- dqp->dq_flprev);
-
- kdb_printf("nrefs 0x%x blkno 0x%llx boffset 0x%x ", dqp->q_nrefs,
- (unsigned long long)dqp->q_blkno, dqp->q_bufoffset);
- printflags(dqp->dq_flags, xdq_flags, "flags:");
- kdb_printf("res_bcount %llu res_icount %llu res_rtbcount %llu\n",
- (unsigned long long)dqp->q_res_bcount,
- (unsigned long long)dqp->q_res_icount,
- (unsigned long long)dqp->q_res_rtbcount);
- kdb_printf("qlock 0x%p flock 0x%p (%s) pincount 0x%x\n",
- &dqp->q_qlock,
- &dqp->q_flock,
- (valusema(&dqp->q_flock) <= 0) ? "LCK" : "UNLKD",
- dqp->q_pincount);
-#ifdef XFS_DQUOT_TRACE
- qprintf("dqtrace 0x%p\n", dqp->q_trace);
-#endif
- kdb_printf("disk-dquot 0x%p\n", &dqp->q_core);
- xfsidbg_xqm_diskdq(&dqp->q_core);
-
-}
-
-
-#define XQMIDBG_LIST_PRINT(l, NXT) \
-{ \
- xfs_dquot_t *dqp;\
- int i = 0; \
- kdb_printf("[#%d dquots]\n", (int) (l)->qh_nelems); \
- for (dqp = (l)->qh_next; dqp != NULL; dqp = dqp->NXT) {\
- kdb_printf( \
- "\t%d. [0x%p] \"%d (%s)\"\t blks = %d, inos = %d refs = %d\n", \
- ++i, dqp, (int) be32_to_cpu(dqp->q_core.d_id), \
- DQFLAGTO_TYPESTR(dqp), \
- (int) be64_to_cpu(dqp->q_core.d_bcount), \
- (int) be64_to_cpu(dqp->q_core.d_icount), \
- (int) dqp->q_nrefs); }\
- kdb_printf("\n"); \
-}
-
-static void
-xfsidbg_xqm_dqattached_inos(xfs_mount_t *mp)
-{
- xfs_inode_t *ip;
- int n = 0;
-
- ip = mp->m_inodes;
- do {
- if (ip->i_mount == NULL) {
- ip = ip->i_mnext;
- continue;
- }
- if (ip->i_udquot || ip->i_gdquot) {
- n++;
- kdb_printf("inode = 0x%p, ino %d: udq 0x%p, gdq 0x%p\n",
- ip, (int)ip->i_ino, ip->i_udquot, ip->i_gdquot);
- }
- ip = ip->i_mnext;
- } while (ip != mp->m_inodes);
- kdb_printf("\nNumber of inodes with dquots attached: %d\n", n);
-}
-
-#ifdef CONFIG_XFS_QUOTA
-static void
-xfsidbg_xqm_freelist_print(xfs_frlist_t *qlist, char *title)
-{
- xfs_dquot_t *dq;
- int i = 0;
- kdb_printf("%s (#%d)\n", title, (int) qlist->qh_nelems);
- FOREACH_DQUOT_IN_FREELIST(dq, qlist) {
- kdb_printf("\t%d.\t\"%d (%s:0x%p)\"\t bcnt = %d, icnt = %d "
- "refs = %d\n",
- ++i, (int) be32_to_cpu(dq->q_core.d_id),
- DQFLAGTO_TYPESTR(dq), dq,
- (int) be64_to_cpu(dq->q_core.d_bcount),
- (int) be64_to_cpu(dq->q_core.d_icount),
- (int) dq->q_nrefs);
- }
-}
-
-static void
-xfsidbg_xqm_freelist(void)
-{
- if (xfs_Gqm) {
- xfsidbg_xqm_freelist_print(&(xfs_Gqm->qm_dqfreelist), "Freelist");
- } else
- kdb_printf("NULL XQM!!\n");
-}
-
-static void
-xfsidbg_xqm_htab(void)
-{
- int i;
- xfs_dqhash_t *h;
-
- if (xfs_Gqm == NULL) {
- kdb_printf("NULL XQM!!\n");
- return;
- }
- for (i = 0; i <= xfs_Gqm->qm_dqhashmask; i++) {
- h = &xfs_Gqm->qm_usr_dqhtable[i];
- if (h->qh_next) {
- kdb_printf("USR %d: ", i);
- XQMIDBG_LIST_PRINT(h, HL_NEXT);
- }
- }
- for (i = 0; i <= xfs_Gqm->qm_dqhashmask; i++) {
- h = &xfs_Gqm->qm_grp_dqhtable[i];
- if (h->qh_next) {
- kdb_printf("GRP/PRJ %d: ", i);
- XQMIDBG_LIST_PRINT(h, HL_NEXT);
- }
- }
-}
-#endif
-
-#ifdef XFS_DQUOT_TRACE
-static int
-xfsidbg_xqm_pr_dqentry(ktrace_entry_t *ktep)
-{
- if ((__psint_t)ktep->val[0] == 0)
- return 0;
- switch ((__psint_t)ktep->val[0]) {
- case DQUOT_KTRACE_ENTRY:
- qprintf("[%ld] %s\t",
- (long)ktep->val[12], /* pid */
- (char *)ktep->val[1]);
- printflags((__psint_t)ktep->val[3], xdq_flags,"flgs ");
- qprintf("\nnrefs = %u, "
- "flags = 0x%x, "
- "id = %d, "
- "res_bc = 0x%x\n"
- "bcnt = 0x%x [0x%x | 0x%x], "
- "icnt = 0x%x [0x%x | 0x%x]\n"
- "@ %ld\n",
- (unsigned int)(long)ktep->val[2], /* nrefs */
- (unsigned int)(long)ktep->val[3], /* flags */
- (unsigned int)(long)ktep->val[11], /* ID */
- (unsigned int)(long)ktep->val[4], /* res_bc */
- (unsigned int)(long)ktep->val[5], /* bcnt */
- (unsigned int)(long)ktep->val[8], /* bsoft */
- (unsigned int)(long)ktep->val[7], /* bhard */
- (unsigned int)(long)ktep->val[6], /* icnt */
- (unsigned int)(long)ktep->val[10], /* isoft */
- (unsigned int)(long)ktep->val[9], /* ihard */
- (long) ktep->val[13] /* time */
- );
- break;
-
- default:
- qprintf("unknown dqtrace record\n");
- break;
- }
- return (1);
-}
-
-void
-xfsidbg_xqm_dqtrace(xfs_dquot_t *dqp)
-{
- ktrace_entry_t *ktep;
- ktrace_snap_t kts;
-
- if (dqp->q_trace == NULL) {
- qprintf("The xfs dquot trace buffer is not initialized\n");
- return;
- }
- qprintf("xdqtrace dquot 0x%p\n", dqp);
-
- ktep = ktrace_first(dqp->q_trace, &kts);
- while (ktep != NULL) {
- if (xfsidbg_xqm_pr_dqentry(ktep))
- qprintf("---------------------------------\n");
- ktep = ktrace_next(dqp->q_trace, &kts);
- }
-}
-#endif
-
-static void
-xfsidbg_xqm_mplist(xfs_mount_t *mp)
-{
- if (mp->m_quotainfo == NULL) {
- kdb_printf("NULL quotainfo\n");
- return;
- }
-
- XQMIDBG_LIST_PRINT(&(mp->m_quotainfo->qi_dqlist), MPL_NEXT);
-
-}
-
-
-static void
-xfsidbg_xqm_qinfo(xfs_mount_t *mp)
-{
- if (mp == NULL || mp->m_quotainfo == NULL) {
- kdb_printf("NULL quotainfo\n");
- return;
- }
-
- kdb_printf("uqip 0x%p, gqip 0x%p, &pinlock 0x%p &dqlist 0x%p\n",
- mp->m_quotainfo->qi_uquotaip,
- mp->m_quotainfo->qi_gquotaip,
- &mp->m_quotainfo->qi_pinlock,
- &mp->m_quotainfo->qi_dqlist);
-
- kdb_printf("btmlimit 0x%x, itmlimit 0x%x, RTbtmlim 0x%x\n",
- (int)mp->m_quotainfo->qi_btimelimit,
- (int)mp->m_quotainfo->qi_itimelimit,
- (int)mp->m_quotainfo->qi_rtbtimelimit);
-
- kdb_printf("bwarnlim 0x%x, iwarnlim 0x%x, RTbwarnlim 0x%x\n",
- (int)mp->m_quotainfo->qi_bwarnlimit,
- (int)mp->m_quotainfo->qi_iwarnlimit,
- (int)mp->m_quotainfo->qi_rtbwarnlimit);
-
- kdb_printf("nreclaims %d, &qofflock 0x%p, chunklen 0x%x, dqperchunk 0x%x\n",
- (int)mp->m_quotainfo->qi_dqreclaims,
- &mp->m_quotainfo->qi_quotaofflock,
- (int)mp->m_quotainfo->qi_dqchunklen,
- (int)mp->m_quotainfo->qi_dqperchunk);
-}
-
-static void
-xfsidbg_xqm_tpdqinfo(xfs_trans_t *tp)
-{
- xfs_dqtrx_t *qa, *q;
- int i,j;
-
- kdb_printf("dqinfo 0x%p\n", tp->t_dqinfo);
- if (! tp->t_dqinfo)
- return;
- kdb_printf("USR: \n");
- qa = tp->t_dqinfo->dqa_usrdquots;
- for (j = 0; j < 2; j++) {
- for (i = 0; i < XFS_QM_TRANS_MAXDQS; i++) {
- if (qa[i].qt_dquot == NULL)
- break;
- q = &qa[i];
- kdb_printf(
- "\"%d\"[0x%p]: bres %d, bres-used %d, bdelta %d, del-delta %d, icnt-delta %d\n",
- (int) be32_to_cpu(q->qt_dquot->q_core.d_id),
- q->qt_dquot,
- (int) q->qt_blk_res,
- (int) q->qt_blk_res_used,
- (int) q->qt_bcount_delta,
- (int) q->qt_delbcnt_delta,
- (int) q->qt_icount_delta);
- }
- if (j == 0) {
- qa = tp->t_dqinfo->dqa_grpdquots;
- kdb_printf("GRP/PRJ: \n");
- }
- }
-}
-
-/*
- * Print xfs superblock.
- */
-static void
-xfsidbg_xsb(xfs_sb_t *sbp)
-{
- kdb_printf("magicnum 0x%x blocksize 0x%x dblocks %Ld rblocks %Ld\n",
- sbp->sb_magicnum, sbp->sb_blocksize,
- sbp->sb_dblocks, sbp->sb_rblocks);
- kdb_printf("rextents %Ld uuid %s logstart %s\n",
- sbp->sb_rextents, xfs_fmtuuid(&sbp->sb_uuid),
- xfs_fmtfsblock(sbp->sb_logstart, NULL));
- kdb_printf("rootino %s ", xfs_fmtino(sbp->sb_rootino, NULL));
- kdb_printf("rbmino %s ", xfs_fmtino(sbp->sb_rbmino, NULL));
- kdb_printf("rsumino %s\n", xfs_fmtino(sbp->sb_rsumino, NULL));
- kdb_printf("rextsize 0x%x agblocks 0x%x agcount 0x%x rbmblocks 0x%x\n",
- sbp->sb_rextsize, sbp->sb_agblocks, sbp->sb_agcount,
- sbp->sb_rbmblocks);
- kdb_printf("logblocks 0x%x versionnum 0x%x sectsize 0x%x inodesize 0x%x\n",
- sbp->sb_logblocks, sbp->sb_versionnum, sbp->sb_sectsize,
- sbp->sb_inodesize);
- kdb_printf("inopblock 0x%x blocklog 0x%x sectlog 0x%x inodelog 0x%x\n",
- sbp->sb_inopblock, sbp->sb_blocklog, sbp->sb_sectlog,
- sbp->sb_inodelog);
- kdb_printf("inopblog %d agblklog %d rextslog %d inprogress %d imax_pct %d\n",
- sbp->sb_inopblog, sbp->sb_agblklog, sbp->sb_rextslog,
- sbp->sb_inprogress, sbp->sb_imax_pct);
- kdb_printf("icount %Lx ifree %Lx fdblocks %Lx frextents %Lx\n",
- sbp->sb_icount, sbp->sb_ifree,
- sbp->sb_fdblocks, sbp->sb_frextents);
- kdb_printf("uquotino %s ", xfs_fmtino(sbp->sb_uquotino, NULL));
- kdb_printf("gquotino %s ", xfs_fmtino(sbp->sb_gquotino, NULL));
- kdb_printf("qflags 0x%x flags 0x%x shared_vn %d inoaligmt %d\n",
- sbp->sb_qflags, sbp->sb_flags, sbp->sb_shared_vn,
- sbp->sb_inoalignmt);
- kdb_printf("unit %d width %d dirblklog %d\n",
- sbp->sb_unit, sbp->sb_width, sbp->sb_dirblklog);
- kdb_printf("log sunit %d\n", sbp->sb_logsunit);
-}
-
-static void
-xfsidbg_xsb_convert(xfs_sb_t *sbp)
-{
- xfs_sb_t sb;
-
- xfs_xlatesb(sbp, &sb, 1, XFS_SB_ALL_BITS);
-
- kdb_printf("<converted>\n");
- xfsidbg_xsb(&sb);
-}
-
-/*
- * Print out an XFS transaction structure. Print summaries for
- * each of the items.
- */
-static void
-xfsidbg_xtp(xfs_trans_t *tp)
-{
- xfs_log_item_chunk_t *licp;
- xfs_log_item_desc_t *lidp;
- xfs_log_busy_chunk_t *lbcp;
- int i;
- int chunk;
- static char *xtp_flags[] = {
- "dirty", /* 0x1 */
- "sb_dirty", /* 0x2 */
- "perm_log_res", /* 0x4 */
- "sync", /* 0x08 */
- "dq_dirty", /* 0x10 */
- NULL
- };
- static char *lid_flags[] = {
- "dirty", /* 0x1 */
- "pinned", /* 0x2 */
- "sync unlock", /* 0x4 */
- "buf stale", /* 0x8 */
- NULL
- };
-
- kdb_printf("tp 0x%p type ", tp);
- xfsidbg_print_trans_type(tp->t_type);
- kdb_printf(" mount 0x%p\n", tp->t_mountp);
- kdb_printf("flags ");
- printflags(tp->t_flags, xtp_flags,"xtp");
- kdb_printf("\n");
- kdb_printf("callback 0x%p forw 0x%p back 0x%p\n",
- &tp->t_logcb, tp->t_forw, tp->t_back);
- kdb_printf("log res %d block res %d block res used %d\n",
- tp->t_log_res, tp->t_blk_res, tp->t_blk_res_used);
- kdb_printf("rt res %d rt res used %d\n", tp->t_rtx_res,
- tp->t_rtx_res_used);
- kdb_printf("ticket 0x%lx lsn %s commit_lsn %s\n",
- (unsigned long) tp->t_ticket,
- xfs_fmtlsn(&tp->t_lsn),
- xfs_fmtlsn(&tp->t_commit_lsn));
- kdb_printf("callback 0x%p callarg 0x%p\n",
- tp->t_callback, tp->t_callarg);
- kdb_printf("icount delta %ld ifree delta %ld\n",
- tp->t_icount_delta, tp->t_ifree_delta);
- kdb_printf("blocks delta %ld res blocks delta %ld\n",
- tp->t_fdblocks_delta, tp->t_res_fdblocks_delta);
- kdb_printf("rt delta %ld res rt delta %ld\n",
- tp->t_frextents_delta, tp->t_res_frextents_delta);
- kdb_printf("ag freeblks delta %ld ag flist delta %ld ag btree delta %ld\n",
- tp->t_ag_freeblks_delta, tp->t_ag_flist_delta,
- tp->t_ag_btree_delta);
- kdb_printf("dblocks delta %ld agcount delta %ld imaxpct delta %ld\n",
- tp->t_dblocks_delta, tp->t_agcount_delta, tp->t_imaxpct_delta);
- kdb_printf("rextsize delta %ld rbmblocks delta %ld\n",
- tp->t_rextsize_delta, tp->t_rbmblocks_delta);
- kdb_printf("rblocks delta %ld rextents delta %ld rextslog delta %ld\n",
- tp->t_rblocks_delta, tp->t_rextents_delta,
- tp->t_rextslog_delta);
- kdb_printf("dqinfo 0x%p\n", tp->t_dqinfo);
- kdb_printf("log items:\n");
- licp = &tp->t_items;
- chunk = 0;
- while (licp != NULL) {
- if (XFS_LIC_ARE_ALL_FREE(licp)) {
- licp = licp->lic_next;
- chunk++;
- continue;
- }
- for (i = 0; i < licp->lic_unused; i++) {
- if (XFS_LIC_ISFREE(licp, i)) {
- continue;
- }
-
- lidp = XFS_LIC_SLOT(licp, i);
- kdb_printf("\n");
- kdb_printf("chunk %d index %d item 0x%p size %d\n",
- chunk, i, lidp->lid_item, lidp->lid_size);
- kdb_printf("flags ");
- printflags(lidp->lid_flags, lid_flags,"lic");
- kdb_printf("\n");
- xfsidbg_xlogitem(lidp->lid_item);
- }
- chunk++;
- licp = licp->lic_next;
- }
-
- kdb_printf("log busy free %d, list:\n", tp->t_busy_free);
- lbcp = &tp->t_busy;
- chunk = 0;
- while (lbcp != NULL) {
- kdb_printf("Chunk %d at 0x%p next 0x%p free 0x%08x unused %d\n",
- chunk, lbcp, lbcp->lbc_next, lbcp->lbc_free,
- lbcp->lbc_unused);
- for (i = 0; i < XFS_LBC_NUM_SLOTS; i++) {
- kdb_printf(" %02d: ag %d idx %d\n",
- i,
- lbcp->lbc_busy[i].lbc_ag,
- lbcp->lbc_busy[i].lbc_idx);
- }
- lbcp = lbcp->lbc_next;
- }
-}
-
-static void
-xfsidbg_xtrans_res(
- xfs_mount_t *mp)
-{
- xfs_trans_reservations_t *xtrp;
-
- xtrp = &mp->m_reservations;
- kdb_printf("write: %d\ttruncate: %d\trename: %d\n",
- xtrp->tr_write, xtrp->tr_itruncate, xtrp->tr_rename);
- kdb_printf("link: %d\tremove: %d\tsymlink: %d\n",
- xtrp->tr_link, xtrp->tr_remove, xtrp->tr_symlink);
- kdb_printf("create: %d\tmkdir: %d\tifree: %d\n",
- xtrp->tr_create, xtrp->tr_mkdir, xtrp->tr_ifree);
- kdb_printf("ichange: %d\tgrowdata: %d\tswrite: %d\n",
- xtrp->tr_ichange, xtrp->tr_growdata, xtrp->tr_swrite);
- kdb_printf("addafork: %d\twriteid: %d\tattrinval: %d\n",
- xtrp->tr_addafork, xtrp->tr_writeid, xtrp->tr_attrinval);
- kdb_printf("attrset: %d\tattrrm: %d\tclearagi: %d\n",
- xtrp->tr_attrset, xtrp->tr_attrrm, xtrp->tr_clearagi);
- kdb_printf("growrtalloc: %d\tgrowrtzero: %d\tgrowrtfree: %d\n",
- xtrp->tr_growrtalloc, xtrp->tr_growrtzero, xtrp->tr_growrtfree);
-}
diff --git a/sys/i386/conf/GENERIC b/sys/i386/conf/GENERIC
index 3a98ded..d35a780 100644
--- a/sys/i386/conf/GENERIC
+++ b/sys/i386/conf/GENERIC
@@ -146,7 +146,10 @@ device sa # Sequential Access (tape etc)
device cd # CD
device pass # Passthrough device (direct ATA/SCSI access)
device ses # Enclosure Services (SES and SAF-TE)
-#device ctl # CAM Target Layer
+device ctl # CAM Target Layer
+options CTL_DISABLE # Disable CTL by default to save memory.
+ # Re-enable with kern.cam.ctl.disable=0 in
+ # /boot/loader.conf
# RAID controllers interfaced to the SCSI subsystem
device amr # AMI MegaRAID
diff --git a/sys/i386/conf/NOTES b/sys/i386/conf/NOTES
index 95ccd4e..f8f78cc 100644
--- a/sys/i386/conf/NOTES
+++ b/sys/i386/conf/NOTES
@@ -773,6 +773,13 @@ device glxsb # AMD Geode LX Security Block
#
# VirtIO support
+#
+# The virtio entry provides a generic bus for use by the device drivers.
+# It must be combined with an interface that communicates with the host.
+# Multiple such interfaces defined by the VirtIO specification. FreeBSD
+# only has support for PCI. Therefore, virtio_pci must be statically
+# compiled in or loaded as a module for the device drivers to function.
+#
device virtio # Generic VirtIO bus (required)
device virtio_pci # VirtIO PCI Interface
device vtnet # VirtIO Ethernet device
diff --git a/sys/i386/xen/pmap.c b/sys/i386/xen/pmap.c
index 9a5aec0..65e2e76 100644
--- a/sys/i386/xen/pmap.c
+++ b/sys/i386/xen/pmap.c
@@ -2038,7 +2038,7 @@ pmap_pv_reclaim(pmap_t locked_pmap)
vm_page_dirty(m);
if ((tpte & PG_A) != 0)
vm_page_aflag_set(m, PGA_REFERENCED);
- TAILQ_REMOVE(&m->md.pv_list, pv, pv_list);
+ TAILQ_REMOVE(&m->md.pv_list, pv, pv_next);
if (TAILQ_EMPTY(&m->md.pv_list))
vm_page_aflag_clear(m, PGA_WRITEABLE);
pc->pc_map[field] |= 1UL << bit;
@@ -2239,9 +2239,9 @@ pmap_pvh_remove(struct md_page *pvh, pmap_t pmap, vm_offset_t va)
pv_entry_t pv;
rw_assert(&pvh_global_lock, RA_WLOCKED);
- TAILQ_FOREACH(pv, &pvh->pv_list, pv_list) {
+ TAILQ_FOREACH(pv, &pvh->pv_list, pv_next) {
if (pmap == PV_PMAP(pv) && va == pv->pv_va) {
- TAILQ_REMOVE(&pvh->pv_list, pv, pv_list);
+ TAILQ_REMOVE(&pvh->pv_list, pv, pv_next);
break;
}
}
@@ -2281,7 +2281,7 @@ pmap_try_insert_pv_entry(pmap_t pmap, vm_offset_t va, vm_page_t m)
if (pv_entry_count < pv_entry_high_water &&
(pv = get_pv_entry(pmap, TRUE)) != NULL) {
pv->pv_va = va;
- TAILQ_INSERT_TAIL(&m->md.pv_list, pv, pv_list);
+ TAILQ_INSERT_TAIL(&m->md.pv_list, pv, pv_next);
return (TRUE);
} else
return (FALSE);
@@ -2503,7 +2503,7 @@ pmap_remove_all(vm_page_t m)
vm_page_dirty(m);
pmap_unuse_pt(pmap, pv->pv_va, &free);
pmap_invalidate_page(pmap, pv->pv_va);
- TAILQ_REMOVE(&m->md.pv_list, pv, pv_list);
+ TAILQ_REMOVE(&m->md.pv_list, pv, pv_next);
free_pv_entry(pmap, pv);
PMAP_UNLOCK(pmap);
}
@@ -2770,7 +2770,7 @@ pmap_enter(pmap_t pmap, vm_offset_t va, vm_prot_t access, vm_page_t m,
if (pv == NULL)
pv = get_pv_entry(pmap, FALSE);
pv->pv_va = va;
- TAILQ_INSERT_TAIL(&m->md.pv_list, pv, pv_list);
+ TAILQ_INSERT_TAIL(&m->md.pv_list, pv, pv_next);
pa |= PG_MANAGED;
} else if (pv != NULL)
free_pv_entry(pmap, pv);
@@ -3465,7 +3465,7 @@ pmap_page_exists_quick(pmap_t pmap, vm_page_t m)
("pmap_page_exists_quick: page %p is not managed", m));
rv = FALSE;
rw_wlock(&pvh_global_lock);
- TAILQ_FOREACH(pv, &m->md.pv_list, pv_list) {
+ TAILQ_FOREACH(pv, &m->md.pv_list, pv_next) {
if (PV_PMAP(pv) == pmap) {
rv = TRUE;
break;
@@ -3497,7 +3497,7 @@ pmap_page_wired_mappings(vm_page_t m)
return (count);
rw_wlock(&pvh_global_lock);
sched_pin();
- TAILQ_FOREACH(pv, &m->md.pv_list, pv_list) {
+ TAILQ_FOREACH(pv, &m->md.pv_list, pv_next) {
pmap = PV_PMAP(pv);
PMAP_LOCK(pmap);
pte = pmap_pte_quick(pmap, pv->pv_va);
@@ -3602,7 +3602,7 @@ pmap_remove_pages(pmap_t pmap)
if (tpte & PG_M)
vm_page_dirty(m);
- TAILQ_REMOVE(&m->md.pv_list, pv, pv_list);
+ TAILQ_REMOVE(&m->md.pv_list, pv, pv_next);
if (TAILQ_EMPTY(&m->md.pv_list))
vm_page_aflag_clear(m, PGA_WRITEABLE);
@@ -3662,7 +3662,7 @@ pmap_is_modified(vm_page_t m)
return (rv);
rw_wlock(&pvh_global_lock);
sched_pin();
- TAILQ_FOREACH(pv, &m->md.pv_list, pv_list) {
+ TAILQ_FOREACH(pv, &m->md.pv_list, pv_next) {
pmap = PV_PMAP(pv);
PMAP_LOCK(pmap);
pte = pmap_pte_quick(pmap, pv->pv_va);
@@ -3723,7 +3723,7 @@ pmap_is_referenced(vm_page_t m)
rv = FALSE;
rw_wlock(&pvh_global_lock);
sched_pin();
- TAILQ_FOREACH(pv, &m->md.pv_list, pv_list) {
+ TAILQ_FOREACH(pv, &m->md.pv_list, pv_next) {
pmap = PV_PMAP(pv);
PMAP_LOCK(pmap);
pte = pmap_pte_quick(pmap, pv->pv_va);
@@ -3793,7 +3793,7 @@ pmap_remove_write(vm_page_t m)
return;
rw_wlock(&pvh_global_lock);
sched_pin();
- TAILQ_FOREACH(pv, &m->md.pv_list, pv_list) {
+ TAILQ_FOREACH(pv, &m->md.pv_list, pv_next) {
pmap = PV_PMAP(pv);
PMAP_LOCK(pmap);
pte = pmap_pte_quick(pmap, pv->pv_va);
@@ -3852,9 +3852,9 @@ pmap_ts_referenced(vm_page_t m)
if ((pv = TAILQ_FIRST(&m->md.pv_list)) != NULL) {
pvf = pv;
do {
- pvn = TAILQ_NEXT(pv, pv_list);
- TAILQ_REMOVE(&m->md.pv_list, pv, pv_list);
- TAILQ_INSERT_TAIL(&m->md.pv_list, pv, pv_list);
+ pvn = TAILQ_NEXT(pv, pv_next);
+ TAILQ_REMOVE(&m->md.pv_list, pv, pv_next);
+ TAILQ_INSERT_TAIL(&m->md.pv_list, pv, pv_next);
pmap = PV_PMAP(pv);
PMAP_LOCK(pmap);
pte = pmap_pte_quick(pmap, pv->pv_va);
@@ -3901,7 +3901,7 @@ pmap_clear_modify(vm_page_t m)
return;
rw_wlock(&pvh_global_lock);
sched_pin();
- TAILQ_FOREACH(pv, &m->md.pv_list, pv_list) {
+ TAILQ_FOREACH(pv, &m->md.pv_list, pv_next) {
pmap = PV_PMAP(pv);
PMAP_LOCK(pmap);
pte = pmap_pte_quick(pmap, pv->pv_va);
@@ -3936,7 +3936,7 @@ pmap_clear_reference(vm_page_t m)
("pmap_clear_reference: page %p is not managed", m));
rw_wlock(&pvh_global_lock);
sched_pin();
- TAILQ_FOREACH(pv, &m->md.pv_list, pv_list) {
+ TAILQ_FOREACH(pv, &m->md.pv_list, pv_next) {
pmap = PV_PMAP(pv);
PMAP_LOCK(pmap);
pte = pmap_pte_quick(pmap, pv->pv_va);
@@ -4418,7 +4418,7 @@ pmap_pvdump(vm_paddr_t pa)
printf("pa %x", pa);
m = PHYS_TO_VM_PAGE(pa);
- TAILQ_FOREACH(pv, &m->md.pv_list, pv_list) {
+ TAILQ_FOREACH(pv, &m->md.pv_list, pv_next) {
pmap = PV_PMAP(pv);
printf(" -> pmap %p, va %x", (void *)pmap, pv->pv_va);
pads(pmap);
diff --git a/sys/kern/capabilities.conf b/sys/kern/capabilities.conf
index 3c08782..71c22bf 100644
--- a/sys/kern/capabilities.conf
+++ b/sys/kern/capabilities.conf
@@ -100,11 +100,9 @@ aio_write
#audit
##
-## Disllow bind(2) for now, even though we support CAP_BIND.
+## Allow bindat(2).
##
-## XXXRW: Revisit this.
-##
-#bind
+bindat
##
## Allow capability mode and capability system calls.
@@ -132,11 +130,9 @@ close
closefrom
##
-## Disallow connect(2) for now, despite CAP_CONNECT.
-##
-## XXXRW: Revisit this.
+## Allow connectat(2).
##
-#connect
+connectat
##
## cpuset(2) and related calls require scoping by process, but should
diff --git a/sys/kern/init_sysent.c b/sys/kern/init_sysent.c
index b5ed57b..e7041d2 100644
--- a/sys/kern/init_sysent.c
+++ b/sys/kern/init_sysent.c
@@ -3,7 +3,7 @@
*
* DO NOT EDIT-- this file is automatically generated.
* $FreeBSD$
- * created from FreeBSD: head/sys/kern/syscalls.master 247602 2013-03-02 00:53:12Z pjd
+ * created from FreeBSD: head/sys/kern/syscalls.master 247667 2013-03-02 21:11:30Z pjd
*/
#include "opt_compat.h"
@@ -572,4 +572,6 @@ struct sysent sysent[] = {
{ AS(cap_ioctls_get_args), (sy_call_t *)sys_cap_ioctls_get, AUE_CAP_IOCTLS_GET, NULL, 0, 0, SYF_CAPENABLED, SY_THR_STATIC }, /* 535 = cap_ioctls_get */
{ AS(cap_fcntls_limit_args), (sy_call_t *)sys_cap_fcntls_limit, AUE_CAP_FCNTLS_LIMIT, NULL, 0, 0, SYF_CAPENABLED, SY_THR_STATIC }, /* 536 = cap_fcntls_limit */
{ AS(cap_fcntls_get_args), (sy_call_t *)sys_cap_fcntls_get, AUE_CAP_FCNTLS_GET, NULL, 0, 0, SYF_CAPENABLED, SY_THR_STATIC }, /* 537 = cap_fcntls_get */
+ { AS(bindat_args), (sy_call_t *)sys_bindat, AUE_BINDAT, NULL, 0, 0, SYF_CAPENABLED, SY_THR_STATIC }, /* 538 = bindat */
+ { AS(connectat_args), (sy_call_t *)sys_connectat, AUE_CONNECTAT, NULL, 0, 0, SYF_CAPENABLED, SY_THR_STATIC }, /* 539 = connectat */
};
diff --git a/sys/kern/kern_clock.c b/sys/kern/kern_clock.c
index 55a2bff..2841f8c 100644
--- a/sys/kern/kern_clock.c
+++ b/sys/kern/kern_clock.c
@@ -78,7 +78,8 @@ __FBSDID("$FreeBSD$");
#include <sys/pmckern.h>
PMC_SOFT_DEFINE( , , clock, hard);
PMC_SOFT_DEFINE( , , clock, stat);
-PMC_SOFT_DEFINE( , , clock, prof);
+PMC_SOFT_DEFINE_EX( , , clock, prof, \
+ cpu_startprofclock, cpu_stopprofclock);
#endif
#ifdef DEVICE_POLLING
@@ -460,7 +461,7 @@ hardclock_cpu(int usermode)
if (td->td_intr_frame != NULL)
PMC_SOFT_CALL_TF( , , clock, hard, td->td_intr_frame);
#endif
- callout_tick();
+ callout_process(sbinuptime());
}
/*
@@ -550,7 +551,6 @@ hardclock_cnt(int cnt, int usermode)
if (td->td_intr_frame != NULL)
PMC_SOFT_CALL_TF( , , clock, hard, td->td_intr_frame);
#endif
- callout_tick();
/* We are in charge to handle this tick duty. */
if (newticks > 0) {
/* Dangerous and no need to call these things concurrently. */
diff --git a/sys/kern/kern_clocksource.c b/sys/kern/kern_clocksource.c
index 10732d9..c2bebbe 100644
--- a/sys/kern/kern_clocksource.c
+++ b/sys/kern/kern_clocksource.c
@@ -1,5 +1,5 @@
/*-
- * Copyright (c) 2010-2012 Alexander Motin <mav@FreeBSD.org>
+ * Copyright (c) 2010-2013 Alexander Motin <mav@FreeBSD.org>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -37,6 +37,7 @@ __FBSDID("$FreeBSD$");
#include <sys/param.h>
#include <sys/systm.h>
#include <sys/bus.h>
+#include <sys/limits.h>
#include <sys/lock.h>
#include <sys/kdb.h>
#include <sys/ktr.h>
@@ -63,17 +64,14 @@ int cpu_can_deep_sleep = 0; /* C3 state is available. */
int cpu_disable_deep_sleep = 0; /* Timer dies in C3. */
static void setuptimer(void);
-static void loadtimer(struct bintime *now, int first);
+static void loadtimer(sbintime_t now, int first);
static int doconfigtimer(void);
static void configtimer(int start);
static int round_freq(struct eventtimer *et, int freq);
-static void getnextcpuevent(struct bintime *event, int idle);
-static void getnextevent(struct bintime *event);
-static int handleevents(struct bintime *now, int fake);
-#ifdef SMP
-static void cpu_new_callout(int cpu, int ticks);
-#endif
+static sbintime_t getnextcpuevent(int idle);
+static sbintime_t getnextevent(void);
+static int handleevents(sbintime_t now, int fake);
static struct mtx et_hw_mtx;
@@ -94,13 +92,11 @@ static struct mtx et_hw_mtx;
}
static struct eventtimer *timer = NULL;
-static struct bintime timerperiod; /* Timer period for periodic mode. */
-static struct bintime hardperiod; /* hardclock() events period. */
-static struct bintime statperiod; /* statclock() events period. */
-static struct bintime profperiod; /* profclock() events period. */
-static struct bintime nexttick; /* Next global timer tick time. */
-static struct bintime nexthard; /* Next global hardlock() event. */
-static u_int busy = 0; /* Reconfiguration is in progress. */
+static sbintime_t timerperiod; /* Timer period for periodic mode. */
+static sbintime_t statperiod; /* statclock() events period. */
+static sbintime_t profperiod; /* profclock() events period. */
+static sbintime_t nexttick; /* Next global timer tick time. */
+static u_int busy = 1; /* Reconfiguration is in progress. */
static int profiling = 0; /* Profiling events enabled. */
static char timername[32]; /* Wanted timer. */
@@ -116,11 +112,6 @@ TUNABLE_INT("kern.eventtimer.idletick", &idletick);
SYSCTL_UINT(_kern_eventtimer, OID_AUTO, idletick, CTLFLAG_RW, &idletick,
0, "Run periodic events when idle");
-static u_int activetick = 1; /* Run all periodic events when active. */
-TUNABLE_INT("kern.eventtimer.activetick", &activetick);
-SYSCTL_UINT(_kern_eventtimer, OID_AUTO, activetick, CTLFLAG_RW, &activetick,
- 0, "Run all periodic events when active");
-
static int periodic = 0; /* Periodic or one-shot mode. */
static int want_periodic = 0; /* What mode to prefer. */
TUNABLE_INT("kern.eventtimer.periodic", &want_periodic);
@@ -129,31 +120,23 @@ struct pcpu_state {
struct mtx et_hw_mtx; /* Per-CPU timer mutex. */
u_int action; /* Reconfiguration requests. */
u_int handle; /* Immediate handle resuests. */
- struct bintime now; /* Last tick time. */
- struct bintime nextevent; /* Next scheduled event on this CPU. */
- struct bintime nexttick; /* Next timer tick time. */
- struct bintime nexthard; /* Next hardlock() event. */
- struct bintime nextstat; /* Next statclock() event. */
- struct bintime nextprof; /* Next profclock() event. */
+ sbintime_t now; /* Last tick time. */
+ sbintime_t nextevent; /* Next scheduled event on this CPU. */
+ sbintime_t nexttick; /* Next timer tick time. */
+ sbintime_t nexthard; /* Next hardlock() event. */
+ sbintime_t nextstat; /* Next statclock() event. */
+ sbintime_t nextprof; /* Next profclock() event. */
+ sbintime_t nextcall; /* Next callout event. */
+ sbintime_t nextcallopt; /* Next optional callout event. */
#ifdef KDTRACE_HOOKS
- struct bintime nextcyc; /* Next OpenSolaris cyclics event. */
+ sbintime_t nextcyc; /* Next OpenSolaris cyclics event. */
#endif
int ipi; /* This CPU needs IPI. */
int idle; /* This CPU is in idle mode. */
};
static DPCPU_DEFINE(struct pcpu_state, timerstate);
-
-#define FREQ2BT(freq, bt) \
-{ \
- (bt)->sec = 0; \
- (bt)->frac = ((uint64_t)0x8000000000000000 / (freq)) << 1; \
-}
-#define BT2FREQ(bt) \
- (((uint64_t)0x8000000000000000 + ((bt)->frac >> 2)) / \
- ((bt)->frac >> 1))
-
-#define SBT2FREQ(sbt) ((SBT_1S + ((sbt) >> 1)) / (sbt))
+DPCPU_DEFINE(sbintime_t, hardclocktime);
/*
* Timer broadcast IPI handler.
@@ -161,7 +144,7 @@ static DPCPU_DEFINE(struct pcpu_state, timerstate);
int
hardclockintr(void)
{
- struct bintime now;
+ sbintime_t now;
struct pcpu_state *state;
int done;
@@ -169,10 +152,9 @@ hardclockintr(void)
return (FILTER_HANDLED);
state = DPCPU_PTR(timerstate);
now = state->now;
- CTR4(KTR_SPARE2, "ipi at %d: now %d.%08x%08x",
- curcpu, now.sec, (u_int)(now.frac >> 32),
- (u_int)(now.frac & 0xffffffff));
- done = handleevents(&now, 0);
+ CTR3(KTR_SPARE2, "ipi at %d: now %d.%08x",
+ curcpu, (int)(now >> 32), (u_int)(now & 0xffffffff));
+ done = handleevents(now, 0);
return (done ? FILTER_HANDLED : FILTER_STRAY);
}
@@ -180,48 +162,43 @@ hardclockintr(void)
* Handle all events for specified time on this CPU
*/
static int
-handleevents(struct bintime *now, int fake)
+handleevents(sbintime_t now, int fake)
{
- struct bintime t;
+ sbintime_t t, *hct;
struct trapframe *frame;
struct pcpu_state *state;
- uintfptr_t pc;
int usermode;
int done, runs;
- CTR4(KTR_SPARE2, "handle at %d: now %d.%08x%08x",
- curcpu, now->sec, (u_int)(now->frac >> 32),
- (u_int)(now->frac & 0xffffffff));
+ CTR3(KTR_SPARE2, "handle at %d: now %d.%08x",
+ curcpu, (int)(now >> 32), (u_int)(now & 0xffffffff));
done = 0;
if (fake) {
frame = NULL;
usermode = 0;
- pc = 0;
} else {
frame = curthread->td_intr_frame;
usermode = TRAPF_USERMODE(frame);
- pc = TRAPF_PC(frame);
}
state = DPCPU_PTR(timerstate);
runs = 0;
- while (bintime_cmp(now, &state->nexthard, >=)) {
- bintime_addx(&state->nexthard, hardperiod.frac);
+ while (now >= state->nexthard) {
+ state->nexthard += tick_sbt;
runs++;
}
if (runs) {
- if ((timer->et_flags & ET_FLAGS_PERCPU) == 0 &&
- bintime_cmp(&state->nexthard, &nexthard, >))
- nexthard = state->nexthard;
+ hct = DPCPU_PTR(hardclocktime);
+ *hct = state->nexthard - tick_sbt;
if (fake < 2) {
hardclock_cnt(runs, usermode);
done = 1;
}
}
runs = 0;
- while (bintime_cmp(now, &state->nextstat, >=)) {
- bintime_addx(&state->nextstat, statperiod.frac);
+ while (now >= state->nextstat) {
+ state->nextstat += statperiod;
runs++;
}
if (runs && fake < 2) {
@@ -230,31 +207,29 @@ handleevents(struct bintime *now, int fake)
}
if (profiling) {
runs = 0;
- while (bintime_cmp(now, &state->nextprof, >=)) {
- bintime_addx(&state->nextprof, profperiod.frac);
+ while (now >= state->nextprof) {
+ state->nextprof += profperiod;
runs++;
}
if (runs && !fake) {
- profclock_cnt(runs, usermode, pc);
+ profclock_cnt(runs, usermode, TRAPF_PC(frame));
done = 1;
}
} else
state->nextprof = state->nextstat;
+ if (now >= state->nextcallopt) {
+ state->nextcall = state->nextcallopt = INT64_MAX;
+ callout_process(now);
+ }
#ifdef KDTRACE_HOOKS
- if (fake == 0 && cyclic_clock_func != NULL &&
- state->nextcyc.sec != -1 &&
- bintime_cmp(now, &state->nextcyc, >=)) {
- state->nextcyc.sec = -1;
+ if (fake == 0 && now >= state->nextcyc && cyclic_clock_func != NULL) {
+ state->nextcyc = INT64_MAX;
(*cyclic_clock_func)(frame);
}
#endif
- getnextcpuevent(&t, 0);
- if (fake == 2) {
- state->nextevent = t;
- return (done);
- }
+ t = getnextcpuevent(0);
ET_HW_LOCK(state);
if (!busy) {
state->idle = 0;
@@ -268,84 +243,81 @@ handleevents(struct bintime *now, int fake)
/*
* Schedule binuptime of the next event on current CPU.
*/
-static void
-getnextcpuevent(struct bintime *event, int idle)
+static sbintime_t
+getnextcpuevent(int idle)
{
- struct bintime tmp;
+ sbintime_t event;
struct pcpu_state *state;
- int skip;
+ u_int hardfreq;
state = DPCPU_PTR(timerstate);
- /* Handle hardclock() events. */
- *event = state->nexthard;
- if (idle || (!activetick && !profiling &&
- (timer->et_flags & ET_FLAGS_PERCPU) == 0)) {
- skip = idle ? 4 : (stathz / 2);
- if (curcpu == CPU_FIRST() && tc_min_ticktock_freq > skip)
- skip = tc_min_ticktock_freq;
- skip = callout_tickstofirst(hz / skip) - 1;
- CTR2(KTR_SPARE2, "skip at %d: %d", curcpu, skip);
- tmp = hardperiod;
- bintime_mul(&tmp, skip);
- bintime_add(event, &tmp);
- }
+ /* Handle hardclock() events, skipping some if CPU is idle. */
+ event = state->nexthard;
+ if (idle) {
+ hardfreq = (u_int)hz / 2;
+ if (tc_min_ticktock_freq > 2
+#ifdef SMP
+ && curcpu == CPU_FIRST()
+#endif
+ )
+ hardfreq = hz / tc_min_ticktock_freq;
+ if (hardfreq > 1)
+ event += tick_sbt * (hardfreq - 1);
+ }
+ /* Handle callout events. */
+ if (event > state->nextcall)
+ event = state->nextcall;
if (!idle) { /* If CPU is active - handle other types of events. */
- if (bintime_cmp(event, &state->nextstat, >))
- *event = state->nextstat;
- if (profiling && bintime_cmp(event, &state->nextprof, >))
- *event = state->nextprof;
+ if (event > state->nextstat)
+ event = state->nextstat;
+ if (profiling && event > state->nextprof)
+ event = state->nextprof;
}
#ifdef KDTRACE_HOOKS
- if (state->nextcyc.sec != -1 && bintime_cmp(event, &state->nextcyc, >))
- *event = state->nextcyc;
+ if (event > state->nextcyc)
+ event = state->nextcyc;
#endif
+ return (event);
}
/*
* Schedule binuptime of the next event on all CPUs.
*/
-static void
-getnextevent(struct bintime *event)
+static sbintime_t
+getnextevent(void)
{
struct pcpu_state *state;
+ sbintime_t event;
#ifdef SMP
int cpu;
#endif
- int c, nonidle;
+ int c;
state = DPCPU_PTR(timerstate);
- *event = state->nextevent;
- c = curcpu;
- nonidle = !state->idle;
- if ((timer->et_flags & ET_FLAGS_PERCPU) == 0) {
+ event = state->nextevent;
+ c = -1;
#ifdef SMP
- if (smp_started) {
- CPU_FOREACH(cpu) {
- if (curcpu == cpu)
- continue;
- state = DPCPU_ID_PTR(cpu, timerstate);
- nonidle += !state->idle;
- if (bintime_cmp(event, &state->nextevent, >)) {
- *event = state->nextevent;
- c = cpu;
- }
+ if ((timer->et_flags & ET_FLAGS_PERCPU) == 0) {
+ CPU_FOREACH(cpu) {
+ state = DPCPU_ID_PTR(cpu, timerstate);
+ if (event > state->nextevent) {
+ event = state->nextevent;
+ c = cpu;
}
}
-#endif
- if (nonidle != 0 && bintime_cmp(event, &nexthard, >))
- *event = nexthard;
}
- CTR5(KTR_SPARE2, "next at %d: next %d.%08x%08x by %d",
- curcpu, event->sec, (u_int)(event->frac >> 32),
- (u_int)(event->frac & 0xffffffff), c);
+#endif
+ CTR4(KTR_SPARE2, "next at %d: next %d.%08x by %d",
+ curcpu, (int)(event >> 32), (u_int)(event & 0xffffffff), c);
+ return (event);
}
/* Hardware timer callback function. */
static void
timercb(struct eventtimer *et, void *arg)
{
- struct bintime now;
- struct bintime *next;
+ sbintime_t now;
+ sbintime_t *next;
struct pcpu_state *state;
#ifdef SMP
int cpu, bcast;
@@ -360,16 +332,14 @@ timercb(struct eventtimer *et, void *arg)
next = &state->nexttick;
} else
next = &nexttick;
- binuptime(&now);
- if (periodic) {
- *next = now;
- bintime_addx(next, timerperiod.frac); /* Next tick in 1 period. */
- } else
- next->sec = -1; /* Next tick is not scheduled yet. */
+ now = sbinuptime();
+ if (periodic)
+ *next = now + timerperiod;
+ else
+ *next = -1; /* Next tick is not scheduled yet. */
state->now = now;
- CTR4(KTR_SPARE2, "intr at %d: now %d.%08x%08x",
- curcpu, (int)(now.sec), (u_int)(now.frac >> 32),
- (u_int)(now.frac & 0xffffffff));
+ CTR3(KTR_SPARE2, "intr at %d: now %d.%08x",
+ curcpu, (int)(now >> 32), (u_int)(now & 0xffffffff));
#ifdef SMP
/* Prepare broadcasting to other CPUs for non-per-CPU timers. */
@@ -379,8 +349,8 @@ timercb(struct eventtimer *et, void *arg)
state = DPCPU_ID_PTR(cpu, timerstate);
ET_HW_LOCK(state);
state->now = now;
- if (bintime_cmp(&now, &state->nextevent, >=)) {
- state->nextevent.sec++;
+ if (now >= state->nextevent) {
+ state->nextevent += SBT_1S;
if (curcpu != cpu) {
state->ipi = 1;
bcast = 1;
@@ -392,7 +362,7 @@ timercb(struct eventtimer *et, void *arg)
#endif
/* Handle events for this time on this CPU. */
- handleevents(&now, 0);
+ handleevents(now, 0);
#ifdef SMP
/* Broadcast interrupt to other CPUs for non-per-CPU timers. */
@@ -414,11 +384,11 @@ timercb(struct eventtimer *et, void *arg)
* Load new value into hardware timer.
*/
static void
-loadtimer(struct bintime *now, int start)
+loadtimer(sbintime_t now, int start)
{
struct pcpu_state *state;
- struct bintime new;
- struct bintime *next;
+ sbintime_t new;
+ sbintime_t *next;
uint64_t tmp;
int eq;
@@ -433,30 +403,24 @@ loadtimer(struct bintime *now, int start)
* Try to start all periodic timers aligned
* to period to make events synchronous.
*/
- tmp = ((uint64_t)now->sec << 36) + (now->frac >> 28);
- tmp = (tmp % (timerperiod.frac >> 28)) << 28;
- new.sec = 0;
- new.frac = timerperiod.frac - tmp;
- if (new.frac < tmp) /* Left less then passed. */
- bintime_addx(&new, timerperiod.frac);
+ tmp = now % timerperiod;
+ new = timerperiod - tmp;
+ if (new < tmp) /* Left less then passed. */
+ new += timerperiod;
CTR5(KTR_SPARE2, "load p at %d: now %d.%08x first in %d.%08x",
- curcpu, now->sec, (u_int)(now->frac >> 32),
- new.sec, (u_int)(new.frac >> 32));
- *next = new;
- bintime_add(next, now);
- et_start(timer, bttosbt(new), bttosbt(timerperiod));
+ curcpu, (int)(now >> 32), (u_int)(now & 0xffffffff),
+ (int)(new >> 32), (u_int)(new & 0xffffffff));
+ *next = new + now;
+ et_start(timer, new, timerperiod);
}
} else {
- getnextevent(&new);
- eq = bintime_cmp(&new, next, ==);
- CTR5(KTR_SPARE2, "load at %d: next %d.%08x%08x eq %d",
- curcpu, new.sec, (u_int)(new.frac >> 32),
- (u_int)(new.frac & 0xffffffff),
- eq);
+ new = getnextevent();
+ eq = (new == *next);
+ CTR4(KTR_SPARE2, "load at %d: next %d.%08x eq %d",
+ curcpu, (int)(new >> 32), (u_int)(new & 0xffffffff), eq);
if (!eq) {
*next = new;
- bintime_sub(&new, now);
- et_start(timer, bttosbt(new), 0);
+ et_start(timer, new - now, 0);
}
}
}
@@ -478,7 +442,7 @@ setuptimer(void)
while (freq < (profiling ? profhz : stathz))
freq += hz;
freq = round_freq(timer, freq);
- FREQ2BT(freq, &timerperiod);
+ timerperiod = SBT_1S / freq;
}
/*
@@ -487,15 +451,15 @@ setuptimer(void)
static int
doconfigtimer(void)
{
- struct bintime now;
+ sbintime_t now;
struct pcpu_state *state;
state = DPCPU_PTR(timerstate);
switch (atomic_load_acq_int(&state->action)) {
case 1:
- binuptime(&now);
+ now = sbinuptime();
ET_HW_LOCK(state);
- loadtimer(&now, 1);
+ loadtimer(now, 1);
ET_HW_UNLOCK(state);
state->handle = 0;
atomic_store_rel_int(&state->action, 0);
@@ -509,8 +473,8 @@ doconfigtimer(void)
return (1);
}
if (atomic_readandclear_int(&state->handle) && !busy) {
- binuptime(&now);
- handleevents(&now, 0);
+ now = sbinuptime();
+ handleevents(now, 0);
return (1);
}
return (0);
@@ -523,40 +487,45 @@ doconfigtimer(void)
static void
configtimer(int start)
{
- struct bintime now, next;
+ sbintime_t now, next;
struct pcpu_state *state;
int cpu;
if (start) {
setuptimer();
- binuptime(&now);
- }
+ now = sbinuptime();
+ } else
+ now = 0;
critical_enter();
ET_HW_LOCK(DPCPU_PTR(timerstate));
if (start) {
/* Initialize time machine parameters. */
- next = now;
- bintime_addx(&next, timerperiod.frac);
+ next = now + timerperiod;
if (periodic)
nexttick = next;
else
- nexttick.sec = -1;
+ nexttick = -1;
CPU_FOREACH(cpu) {
state = DPCPU_ID_PTR(cpu, timerstate);
state->now = now;
- state->nextevent = next;
+ if (!smp_started && cpu != CPU_FIRST())
+ state->nextevent = INT64_MAX;
+ else
+ state->nextevent = next;
if (periodic)
state->nexttick = next;
else
- state->nexttick.sec = -1;
+ state->nexttick = -1;
state->nexthard = next;
state->nextstat = next;
state->nextprof = next;
+ state->nextcall = next;
+ state->nextcallopt = next;
hardclock_sync(cpu);
}
busy = 0;
/* Start global timer or per-CPU timer of this CPU. */
- loadtimer(&now, 1);
+ loadtimer(now, 1);
} else {
busy = 1;
/* Stop global timer or per-CPU timer of this CPU. */
@@ -629,12 +598,11 @@ cpu_initclocks_bsp(void)
state = DPCPU_ID_PTR(cpu, timerstate);
mtx_init(&state->et_hw_mtx, "et_hw_mtx", NULL, MTX_SPIN);
#ifdef KDTRACE_HOOKS
- state->nextcyc.sec = -1;
+ state->nextcyc = INT64_MAX;
#endif
+ state->nextcall = INT64_MAX;
+ state->nextcallopt = INT64_MAX;
}
-#ifdef SMP
- callout_new_inserted = cpu_new_callout;
-#endif
periodic = want_periodic;
/* Grab requested timer or the best of present. */
if (timername[0])
@@ -698,9 +666,10 @@ cpu_initclocks_bsp(void)
profhz = round_freq(timer, stathz * 64);
}
tick = 1000000 / hz;
- FREQ2BT(hz, &hardperiod);
- FREQ2BT(stathz, &statperiod);
- FREQ2BT(profhz, &profperiod);
+ tick_sbt = SBT_1S / hz;
+ tick_bt = sbttobt(tick_sbt);
+ statperiod = SBT_1S / stathz;
+ profperiod = SBT_1S / profhz;
ET_LOCK();
configtimer(1);
ET_UNLOCK();
@@ -712,18 +681,22 @@ cpu_initclocks_bsp(void)
void
cpu_initclocks_ap(void)
{
- struct bintime now;
+ sbintime_t now;
struct pcpu_state *state;
+ struct thread *td;
state = DPCPU_PTR(timerstate);
- binuptime(&now);
+ now = sbinuptime();
ET_HW_LOCK(state);
state->now = now;
hardclock_sync(curcpu);
- handleevents(&state->now, 2);
- if (timer->et_flags & ET_FLAGS_PERCPU)
- loadtimer(&now, 1);
+ spinlock_enter();
ET_HW_UNLOCK(state);
+ td = curthread;
+ td->td_intr_nesting_level++;
+ handleevents(state->now, 2);
+ td->td_intr_nesting_level--;
+ spinlock_exit();
}
/*
@@ -772,7 +745,7 @@ cpu_stopprofclock(void)
sbintime_t
cpu_idleclock(void)
{
- struct bintime now, t;
+ sbintime_t now, t;
struct pcpu_state *state;
if (idletick || busy ||
@@ -786,19 +759,17 @@ cpu_idleclock(void)
if (periodic)
now = state->now;
else
- binuptime(&now);
- CTR4(KTR_SPARE2, "idle at %d: now %d.%08x%08x",
- curcpu, now.sec, (u_int)(now.frac >> 32),
- (u_int)(now.frac & 0xffffffff));
- getnextcpuevent(&t, 1);
+ now = sbinuptime();
+ CTR3(KTR_SPARE2, "idle at %d: now %d.%08x",
+ curcpu, (int)(now >> 32), (u_int)(now & 0xffffffff));
+ t = getnextcpuevent(1);
ET_HW_LOCK(state);
state->idle = 1;
state->nextevent = t;
if (!periodic)
- loadtimer(&now, 0);
+ loadtimer(now, 0);
ET_HW_UNLOCK(state);
- bintime_sub(&t, &now);
- return (MAX(bttosbt(t), 0));
+ return (MAX(t - now, 0));
}
/*
@@ -807,7 +778,7 @@ cpu_idleclock(void)
void
cpu_activeclock(void)
{
- struct bintime now;
+ sbintime_t now;
struct pcpu_state *state;
struct thread *td;
@@ -817,101 +788,98 @@ cpu_activeclock(void)
if (periodic)
now = state->now;
else
- binuptime(&now);
- CTR4(KTR_SPARE2, "active at %d: now %d.%08x%08x",
- curcpu, now.sec, (u_int)(now.frac >> 32),
- (u_int)(now.frac & 0xffffffff));
+ now = sbinuptime();
+ CTR3(KTR_SPARE2, "active at %d: now %d.%08x",
+ curcpu, (int)(now >> 32), (u_int)(now & 0xffffffff));
spinlock_enter();
td = curthread;
td->td_intr_nesting_level++;
- handleevents(&now, 1);
+ handleevents(now, 1);
td->td_intr_nesting_level--;
spinlock_exit();
}
#ifdef KDTRACE_HOOKS
void
-clocksource_cyc_set(const struct bintime *t)
+clocksource_cyc_set(const struct bintime *bt)
{
- struct bintime now;
+ sbintime_t now, t;
struct pcpu_state *state;
+ /* Do not touch anything if somebody reconfiguring timers. */
+ if (busy)
+ return;
+ t = bttosbt(*bt);
state = DPCPU_PTR(timerstate);
if (periodic)
now = state->now;
else
- binuptime(&now);
+ now = sbinuptime();
- CTR4(KTR_SPARE2, "set_cyc at %d: now %d.%08x%08x",
- curcpu, now.sec, (u_int)(now.frac >> 32),
- (u_int)(now.frac & 0xffffffff));
- CTR4(KTR_SPARE2, "set_cyc at %d: t %d.%08x%08x",
- curcpu, t->sec, (u_int)(t->frac >> 32),
- (u_int)(t->frac & 0xffffffff));
+ CTR5(KTR_SPARE2, "set_cyc at %d: now %d.%08x t %d.%08x",
+ curcpu, (int)(now >> 32), (u_int)(now & 0xffffffff),
+ (int)(t >> 32), (u_int)(t & 0xffffffff));
ET_HW_LOCK(state);
- if (bintime_cmp(t, &state->nextcyc, ==)) {
- ET_HW_UNLOCK(state);
- return;
- }
- state->nextcyc = *t;
- if (bintime_cmp(&state->nextcyc, &state->nextevent, >=)) {
- ET_HW_UNLOCK(state);
- return;
- }
- state->nextevent = state->nextcyc;
+ if (t == state->nextcyc)
+ goto done;
+ state->nextcyc = t;
+ if (t >= state->nextevent)
+ goto done;
+ state->nextevent = t;
if (!periodic)
- loadtimer(&now, 0);
+ loadtimer(now, 0);
+done:
ET_HW_UNLOCK(state);
}
#endif
-#ifdef SMP
-static void
-cpu_new_callout(int cpu, int ticks)
+void
+cpu_new_callout(int cpu, sbintime_t bt, sbintime_t bt_opt)
{
- struct bintime tmp;
struct pcpu_state *state;
- CTR3(KTR_SPARE2, "new co at %d: on %d in %d",
- curcpu, cpu, ticks);
+ /* Do not touch anything if somebody reconfiguring timers. */
+ if (busy)
+ return;
+ CTR6(KTR_SPARE2, "new co at %d: on %d at %d.%08x - %d.%08x",
+ curcpu, cpu, (int)(bt_opt >> 32), (u_int)(bt_opt & 0xffffffff),
+ (int)(bt >> 32), (u_int)(bt & 0xffffffff));
state = DPCPU_ID_PTR(cpu, timerstate);
ET_HW_LOCK(state);
- if (state->idle == 0 || busy) {
- ET_HW_UNLOCK(state);
- return;
- }
+
/*
- * If timer is periodic - just update next event time for target CPU.
- * If timer is global - there is chance it is already programmed.
+ * If there is callout time already set earlier -- do nothing.
+ * This check may appear redundant because we check already in
+ * callout_process() but this double check guarantees we're safe
+ * with respect to race conditions between interrupts execution
+ * and scheduling.
*/
- if (periodic || (timer->et_flags & ET_FLAGS_PERCPU) == 0) {
- tmp = hardperiod;
- bintime_mul(&tmp, ticks - 1);
- bintime_add(&tmp, &state->nexthard);
- if (bintime_cmp(&tmp, &state->nextevent, <))
- state->nextevent = tmp;
- if (periodic ||
- bintime_cmp(&state->nextevent, &nexttick, >=)) {
- ET_HW_UNLOCK(state);
- return;
- }
+ state->nextcallopt = bt_opt;
+ if (bt >= state->nextcall)
+ goto done;
+ state->nextcall = bt;
+ /* If there is some other event set earlier -- do nothing. */
+ if (bt >= state->nextevent)
+ goto done;
+ state->nextevent = bt;
+ /* If timer is periodic -- there is nothing to reprogram. */
+ if (periodic)
+ goto done;
+ /* If timer is global or of the current CPU -- reprogram it. */
+ if ((timer->et_flags & ET_FLAGS_PERCPU) == 0 || cpu == curcpu) {
+ loadtimer(sbinuptime(), 0);
+done:
+ ET_HW_UNLOCK(state);
+ return;
}
- /*
- * Otherwise we have to wake that CPU up, as we can't get present
- * bintime to reprogram global timer from here. If timer is per-CPU,
- * we by definition can't do it from here.
- */
+ /* Otherwise make other CPU to reprogram it. */
+ state->handle = 1;
ET_HW_UNLOCK(state);
- if (timer->et_flags & ET_FLAGS_PERCPU) {
- state->handle = 1;
- ipi_cpu(cpu, IPI_HARDCLOCK);
- } else {
- if (!cpu_idle_wakeup(cpu))
- ipi_cpu(cpu, IPI_AST);
- }
-}
+#ifdef SMP
+ ipi_cpu(cpu, IPI_HARDCLOCK);
#endif
+}
/*
* Report or change the active event timers hardware.
diff --git a/sys/kern/kern_condvar.c b/sys/kern/kern_condvar.c
index 82a997c..483ea2e 100644
--- a/sys/kern/kern_condvar.c
+++ b/sys/kern/kern_condvar.c
@@ -270,12 +270,13 @@ _cv_wait_sig(struct cv *cvp, struct lock_object *lock)
}
/*
- * Wait on a condition variable for at most timo/hz seconds. Returns 0 if the
- * process was resumed by cv_signal or cv_broadcast, EWOULDBLOCK if the timeout
- * expires.
+ * Wait on a condition variable for (at most) the value specified in sbt
+ * argument. Returns 0 if the process was resumed by cv_signal or cv_broadcast,
+ * EWOULDBLOCK if the timeout expires.
*/
int
-_cv_timedwait(struct cv *cvp, struct lock_object *lock, int timo)
+_cv_timedwait_sbt(struct cv *cvp, struct lock_object *lock, sbintime_t sbt,
+ sbintime_t pr, int flags)
{
WITNESS_SAVE_DECL(lock_witness);
struct lock_class *class;
@@ -311,7 +312,7 @@ _cv_timedwait(struct cv *cvp, struct lock_object *lock, int timo)
DROP_GIANT();
sleepq_add(cvp, lock, cvp->cv_description, SLEEPQ_CONDVAR, 0);
- sleepq_set_timeout(cvp, timo);
+ sleepq_set_timeout_sbt(cvp, sbt, pr, flags);
if (lock != &Giant.lock_object) {
if (class->lc_flags & LC_SLEEPABLE)
sleepq_release(cvp);
@@ -336,13 +337,15 @@ _cv_timedwait(struct cv *cvp, struct lock_object *lock, int timo)
}
/*
- * Wait on a condition variable for at most timo/hz seconds, allowing
- * interruption by signals. Returns 0 if the thread was resumed by cv_signal
- * or cv_broadcast, EWOULDBLOCK if the timeout expires, and EINTR or ERESTART if
- * a signal was caught.
+ * Wait on a condition variable for (at most) the value specified in sbt
+ * argument, allowing interruption by signals.
+ * Returns 0 if the thread was resumed by cv_signal or cv_broadcast,
+ * EWOULDBLOCK if the timeout expires, and EINTR or ERESTART if a signal
+ * was caught.
*/
int
-_cv_timedwait_sig(struct cv *cvp, struct lock_object *lock, int timo)
+_cv_timedwait_sig_sbt(struct cv *cvp, struct lock_object *lock,
+ sbintime_t sbt, sbintime_t pr, int flags)
{
WITNESS_SAVE_DECL(lock_witness);
struct lock_class *class;
@@ -379,7 +382,7 @@ _cv_timedwait_sig(struct cv *cvp, struct lock_object *lock, int timo)
sleepq_add(cvp, lock, cvp->cv_description, SLEEPQ_CONDVAR |
SLEEPQ_INTERRUPTIBLE, 0);
- sleepq_set_timeout(cvp, timo);
+ sleepq_set_timeout_sbt(cvp, sbt, pr, flags);
if (lock != &Giant.lock_object) {
if (class->lc_flags & LC_SLEEPABLE)
sleepq_release(cvp);
diff --git a/sys/kern/kern_descrip.c b/sys/kern/kern_descrip.c
index b146bab..1475ea3 100644
--- a/sys/kern/kern_descrip.c
+++ b/sys/kern/kern_descrip.c
@@ -104,6 +104,7 @@ static MALLOC_DEFINE(M_FILEDESC, "filedesc", "Open file descriptor table");
static MALLOC_DEFINE(M_FILEDESC_TO_LEADER, "filedesc_to_leader",
"file desc to leader structures");
static MALLOC_DEFINE(M_SIGIO, "sigio", "sigio structures");
+MALLOC_DEFINE(M_FILECAPS, "filecaps", "descriptor capabilities");
MALLOC_DECLARE(M_FADVISE);
@@ -1389,7 +1390,7 @@ filecaps_copy(const struct filecaps *src, struct filecaps *dst)
("fc_ioctls != NULL, but fc_nioctls=%hd", src->fc_nioctls));
size = sizeof(src->fc_ioctls[0]) * src->fc_nioctls;
- dst->fc_ioctls = malloc(size, M_TEMP, M_WAITOK);
+ dst->fc_ioctls = malloc(size, M_FILECAPS, M_WAITOK);
bcopy(src->fc_ioctls, dst->fc_ioctls, size);
}
}
@@ -1397,7 +1398,7 @@ filecaps_copy(const struct filecaps *src, struct filecaps *dst)
/*
* Move filecaps structure to the new place and clear the old place.
*/
-static void
+void
filecaps_move(struct filecaps *src, struct filecaps *dst)
{
@@ -1425,7 +1426,7 @@ void
filecaps_free(struct filecaps *fcaps)
{
- free(fcaps->fc_ioctls, M_TEMP);
+ free(fcaps->fc_ioctls, M_FILECAPS);
bzero(fcaps, sizeof(*fcaps));
}
diff --git a/sys/kern/kern_event.c b/sys/kern/kern_event.c
index 6a920ca..c3d1b86 100644
--- a/sys/kern/kern_event.c
+++ b/sys/kern/kern_event.c
@@ -517,39 +517,28 @@ knote_fork(struct knlist *list, int pid)
* XXX: EVFILT_TIMER should perhaps live in kern_time.c beside the
* interval timer support code.
*/
-static int
-timertoticks(intptr_t data)
+static __inline sbintime_t
+timer2sbintime(intptr_t data)
{
- struct timeval tv;
- int tticks;
-
- tv.tv_sec = data / 1000;
- tv.tv_usec = (data % 1000) * 1000;
- tticks = tvtohz(&tv);
- return tticks;
+ return (SBT_1MS * data);
}
static void
filt_timerexpire(void *knx)
{
- struct knote *kn = knx;
struct callout *calloutp;
+ struct knote *kn;
+ kn = knx;
kn->kn_data++;
KNOTE_ACTIVATE(kn, 0); /* XXX - handle locking */
- /*
- * timertoticks() uses tvtohz() which always adds 1 to allow
- * for the time until the next clock interrupt being strictly
- * less than 1 clock tick. We don't want that here since we
- * want to appear to be in sync with the clock interrupt even
- * when we're delayed.
- */
if ((kn->kn_flags & EV_ONESHOT) != EV_ONESHOT) {
calloutp = (struct callout *)kn->kn_hook;
- callout_reset_curcpu(calloutp, timertoticks(kn->kn_sdata) - 1,
- filt_timerexpire, kn);
+ callout_reset_sbt_on(calloutp,
+ timer2sbintime(kn->kn_sdata), 0 /* 1ms? */,
+ filt_timerexpire, kn, PCPU_GET(cpuid), 0);
}
}
@@ -573,8 +562,9 @@ filt_timerattach(struct knote *kn)
calloutp = malloc(sizeof(*calloutp), M_KQUEUE, M_WAITOK);
callout_init(calloutp, CALLOUT_MPSAFE);
kn->kn_hook = calloutp;
- callout_reset_curcpu(calloutp, timertoticks(kn->kn_sdata),
- filt_timerexpire, kn);
+ callout_reset_sbt_on(calloutp,
+ timer2sbintime(kn->kn_sdata), 0 /* 1ms? */,
+ filt_timerexpire, kn, PCPU_GET(cpuid), 0);
return (0);
}
@@ -1319,10 +1309,9 @@ kqueue_scan(struct kqueue *kq, int maxevents, struct kevent_copyops *k_ops,
const struct timespec *tsp, struct kevent *keva, struct thread *td)
{
struct kevent *kevp;
- struct timeval atv, rtv, ttv;
struct knote *kn, *marker;
- int count, timeout, nkev, error, influx;
- int haskqglobal, touch;
+ sbintime_t asbt, rsbt;
+ int count, error, haskqglobal, influx, nkev, touch;
count = maxevents;
nkev = 0;
@@ -1332,24 +1321,28 @@ kqueue_scan(struct kqueue *kq, int maxevents, struct kevent_copyops *k_ops,
if (maxevents == 0)
goto done_nl;
+ rsbt = 0;
if (tsp != NULL) {
- TIMESPEC_TO_TIMEVAL(&atv, tsp);
- if (itimerfix(&atv)) {
+ if (tsp->tv_sec < 0 || tsp->tv_nsec < 0 ||
+ tsp->tv_nsec >= 1000000000) {
error = EINVAL;
goto done_nl;
}
- if (tsp->tv_sec == 0 && tsp->tv_nsec == 0)
- timeout = -1;
- else
- timeout = atv.tv_sec > 24 * 60 * 60 ?
- 24 * 60 * 60 * hz : tvtohz(&atv);
- getmicrouptime(&rtv);
- timevaladd(&atv, &rtv);
- } else {
- atv.tv_sec = 0;
- atv.tv_usec = 0;
- timeout = 0;
- }
+ if (timespecisset(tsp)) {
+ if (tsp->tv_sec < INT32_MAX) {
+ rsbt = tstosbt(*tsp);
+ if (TIMESEL(&asbt, rsbt))
+ asbt += tc_tick_sbt;
+ asbt += rsbt;
+ if (asbt < rsbt)
+ asbt = 0;
+ rsbt >>= tc_precexp;
+ } else
+ asbt = 0;
+ } else
+ asbt = -1;
+ } else
+ asbt = 0;
marker = knote_alloc(1);
if (marker == NULL) {
error = ENOMEM;
@@ -1357,28 +1350,16 @@ kqueue_scan(struct kqueue *kq, int maxevents, struct kevent_copyops *k_ops,
}
marker->kn_status = KN_MARKER;
KQ_LOCK(kq);
- goto start;
retry:
- if (atv.tv_sec || atv.tv_usec) {
- getmicrouptime(&rtv);
- if (timevalcmp(&rtv, &atv, >=))
- goto done;
- ttv = atv;
- timevalsub(&ttv, &rtv);
- timeout = ttv.tv_sec > 24 * 60 * 60 ?
- 24 * 60 * 60 * hz : tvtohz(&ttv);
- }
-
-start:
kevp = keva;
if (kq->kq_count == 0) {
- if (timeout < 0) {
+ if (asbt == -1) {
error = EWOULDBLOCK;
} else {
kq->kq_state |= KQ_SLEEP;
- error = msleep(kq, &kq->kq_lock, PSOCK | PCATCH,
- "kqread", timeout);
+ error = msleep_sbt(kq, &kq->kq_lock, PSOCK | PCATCH,
+ "kqread", asbt, rsbt, C_ABSOLUTE);
}
if (error == 0)
goto retry;
diff --git a/sys/kern/kern_intr.c b/sys/kern/kern_intr.c
index d2c31fd..8351ab8 100644
--- a/sys/kern/kern_intr.c
+++ b/sys/kern/kern_intr.c
@@ -1103,7 +1103,6 @@ int
swi_add(struct intr_event **eventp, const char *name, driver_intr_t handler,
void *arg, int pri, enum intr_type flags, void **cookiep)
{
- struct thread *td;
struct intr_event *ie;
int error;
@@ -1125,15 +1124,7 @@ swi_add(struct intr_event **eventp, const char *name, driver_intr_t handler,
}
error = intr_event_add_handler(ie, name, NULL, handler, arg,
PI_SWI(pri), flags, cookiep);
- if (error)
- return (error);
- if (pri == SWI_CLOCK) {
- td = ie->ie_thread->it_thread;
- thread_lock(td);
- td->td_flags |= TDF_NOLOAD;
- thread_unlock(td);
- }
- return (0);
+ return (error);
}
/*
diff --git a/sys/kern/kern_resource.c b/sys/kern/kern_resource.c
index 590cfcb..57ee671 100644
--- a/sys/kern/kern_resource.c
+++ b/sys/kern/kern_resource.c
@@ -469,8 +469,7 @@ sys_rtprio(td, uap)
int
rtp_to_pri(struct rtprio *rtp, struct thread *td)
{
- u_char newpri;
- u_char oldpri;
+ u_char newpri, oldclass, oldpri;
switch (RTP_PRIO_BASE(rtp->type)) {
case RTP_PRIO_REALTIME:
@@ -493,11 +492,12 @@ rtp_to_pri(struct rtprio *rtp, struct thread *td)
}
thread_lock(td);
+ oldclass = td->td_pri_class;
sched_class(td, rtp->type); /* XXX fix */
oldpri = td->td_user_pri;
sched_user_prio(td, newpri);
- if (td->td_user_pri != oldpri && (td == curthread ||
- td->td_priority == oldpri || td->td_user_pri <= PRI_MAX_REALTIME))
+ if (td->td_user_pri != oldpri && (oldclass != RTP_PRIO_NORMAL ||
+ td->td_pri_class != RTP_PRIO_NORMAL))
sched_prio(td, td->td_user_pri);
if (TD_ON_UPILOCK(td) && oldpri != newpri) {
critical_enter();
@@ -645,7 +645,8 @@ lim_cb(void *arg)
}
}
if ((p->p_flag & P_WEXIT) == 0)
- callout_reset(&p->p_limco, hz, lim_cb, p);
+ callout_reset_sbt(&p->p_limco, SBT_1S, 0,
+ lim_cb, p, C_PREL(1));
}
int
@@ -697,7 +698,8 @@ kern_proc_setrlimit(struct thread *td, struct proc *p, u_int which,
case RLIMIT_CPU:
if (limp->rlim_cur != RLIM_INFINITY &&
p->p_cpulimit == RLIM_INFINITY)
- callout_reset(&p->p_limco, hz, lim_cb, p);
+ callout_reset_sbt(&p->p_limco, SBT_1S, 0,
+ lim_cb, p, C_PREL(1));
p->p_cpulimit = limp->rlim_cur;
break;
case RLIMIT_DATA:
@@ -1137,7 +1139,8 @@ lim_fork(struct proc *p1, struct proc *p2)
p2->p_limit = lim_hold(p1->p_limit);
callout_init_mtx(&p2->p_limco, &p2->p_mtx, 0);
if (p1->p_cpulimit != RLIM_INFINITY)
- callout_reset(&p2->p_limco, hz, lim_cb, p2);
+ callout_reset_sbt(&p2->p_limco, SBT_1S, 0,
+ lim_cb, p2, C_PREL(1));
}
void
diff --git a/sys/kern/kern_synch.c b/sys/kern/kern_synch.c
index 73dfd70..5aae8d8 100644
--- a/sys/kern/kern_synch.c
+++ b/sys/kern/kern_synch.c
@@ -146,12 +146,12 @@ sleepinit(void)
*/
int
_sleep(void *ident, struct lock_object *lock, int priority,
- const char *wmesg, int timo)
+ const char *wmesg, sbintime_t sbt, sbintime_t pr, int flags)
{
struct thread *td;
struct proc *p;
struct lock_class *class;
- int catch, flags, lock_state, pri, rval;
+ int catch, lock_state, pri, rval, sleepq_flags;
WITNESS_SAVE_DECL(lock_witness);
td = curthread;
@@ -162,7 +162,7 @@ _sleep(void *ident, struct lock_object *lock, int priority,
#endif
WITNESS_WARN(WARN_GIANTOK | WARN_SLEEPOK, lock,
"Sleeping on \"%s\"", wmesg);
- KASSERT(timo != 0 || mtx_owned(&Giant) || lock != NULL,
+ KASSERT(sbt != 0 || mtx_owned(&Giant) || lock != NULL,
("sleeping without a lock"));
KASSERT(p != NULL, ("msleep1"));
KASSERT(ident != NULL && TD_IS_RUNNING(td), ("msleep"));
@@ -199,13 +199,13 @@ _sleep(void *ident, struct lock_object *lock, int priority,
sleepq_remove(td, td->td_wchan);
if (ident == &pause_wchan)
- flags = SLEEPQ_PAUSE;
+ sleepq_flags = SLEEPQ_PAUSE;
else
- flags = SLEEPQ_SLEEP;
+ sleepq_flags = SLEEPQ_SLEEP;
if (catch)
- flags |= SLEEPQ_INTERRUPTIBLE;
+ sleepq_flags |= SLEEPQ_INTERRUPTIBLE;
if (priority & PBDRY)
- flags |= SLEEPQ_STOP_ON_BDRY;
+ sleepq_flags |= SLEEPQ_STOP_ON_BDRY;
sleepq_lock(ident);
CTR5(KTR_PROC, "sleep: thread %ld (pid %ld, %s) on %s (%p)",
@@ -231,18 +231,18 @@ _sleep(void *ident, struct lock_object *lock, int priority,
* stopped, then td will no longer be on a sleep queue upon
* return from cursig().
*/
- sleepq_add(ident, lock, wmesg, flags, 0);
- if (timo)
- sleepq_set_timeout(ident, timo);
+ sleepq_add(ident, lock, wmesg, sleepq_flags, 0);
+ if (sbt != 0)
+ sleepq_set_timeout_sbt(ident, sbt, pr, flags);
if (lock != NULL && class->lc_flags & LC_SLEEPABLE) {
sleepq_release(ident);
WITNESS_SAVE(lock, lock_witness);
lock_state = class->lc_unlock(lock);
sleepq_lock(ident);
}
- if (timo && catch)
+ if (sbt != 0 && catch)
rval = sleepq_timedwait_sig(ident, pri);
- else if (timo)
+ else if (sbt != 0)
rval = sleepq_timedwait(ident, pri);
else if (catch)
rval = sleepq_wait_sig(ident, pri);
@@ -263,7 +263,8 @@ _sleep(void *ident, struct lock_object *lock, int priority,
}
int
-msleep_spin(void *ident, struct mtx *mtx, const char *wmesg, int timo)
+msleep_spin_sbt(void *ident, struct mtx *mtx, const char *wmesg,
+ sbintime_t sbt, sbintime_t pr, int flags)
{
struct thread *td;
struct proc *p;
@@ -301,8 +302,8 @@ msleep_spin(void *ident, struct mtx *mtx, const char *wmesg, int timo)
* We put ourselves on the sleep queue and start our timeout.
*/
sleepq_add(ident, &mtx->lock_object, wmesg, SLEEPQ_SLEEP, 0);
- if (timo)
- sleepq_set_timeout(ident, timo);
+ if (sbt != 0)
+ sleepq_set_timeout_sbt(ident, sbt, pr, flags);
/*
* Can't call ktrace with any spin locks held so it can lock the
@@ -324,7 +325,7 @@ msleep_spin(void *ident, struct mtx *mtx, const char *wmesg, int timo)
wmesg);
sleepq_lock(ident);
#endif
- if (timo)
+ if (sbt != 0)
rval = sleepq_timedwait(ident, 0);
else {
sleepq_wait(ident, 0);
@@ -348,28 +349,30 @@ msleep_spin(void *ident, struct mtx *mtx, const char *wmesg, int timo)
* to a "timo" value of one.
*/
int
-pause(const char *wmesg, int timo)
+pause_sbt(const char *wmesg, sbintime_t sbt, sbintime_t pr, int flags)
{
- KASSERT(timo >= 0, ("pause: timo must be >= 0"));
+ int sbt_sec;
+
+ sbt_sec = sbintime_getsec(sbt);
+ KASSERT(sbt_sec >= 0, ("pause: timo must be >= 0"));
/* silently convert invalid timeouts */
- if (timo < 1)
- timo = 1;
+ if (sbt == 0)
+ sbt = tick_sbt;
if (cold) {
/*
- * We delay one HZ at a time to avoid overflowing the
+ * We delay one second at a time to avoid overflowing the
* system specific DELAY() function(s):
*/
- while (timo >= hz) {
+ while (sbt_sec > 0) {
DELAY(1000000);
- timo -= hz;
+ sbt_sec--;
}
- if (timo > 0)
- DELAY(timo * tick);
+ DELAY((sbt & 0xffffffff) / SBT_1US);
return (0);
}
- return (tsleep(&pause_wchan, 0, wmesg, timo));
+ return (_sleep(&pause_wchan, NULL, 0, wmesg, sbt, pr, flags));
}
/*
@@ -560,8 +563,9 @@ loadav(void *arg)
* random variation to avoid synchronisation with processes that
* run at regular intervals.
*/
- callout_reset(&loadav_callout, hz * 4 + (int)(random() % (hz * 2 + 1)),
- loadav, NULL);
+ callout_reset_sbt(&loadav_callout,
+ tick_sbt * (hz * 4 + (int)(random() % (hz * 2 + 1))), 0,
+ loadav, NULL, C_DIRECT_EXEC | C_HARDCLOCK);
}
/* ARGSUSED */
diff --git a/sys/kern/kern_tc.c b/sys/kern/kern_tc.c
index 6e1f486..9fe7ebe 100644
--- a/sys/kern/kern_tc.c
+++ b/sys/kern/kern_tc.c
@@ -22,6 +22,7 @@ __FBSDID("$FreeBSD$");
#include <sys/param.h>
#include <sys/kernel.h>
+#include <sys/limits.h>
#ifdef FFCLOCK
#include <sys/lock.h>
#include <sys/mutex.h>
@@ -119,6 +120,21 @@ static int timestepwarnings;
SYSCTL_INT(_kern_timecounter, OID_AUTO, stepwarnings, CTLFLAG_RW,
&timestepwarnings, 0, "Log time steps");
+struct bintime bt_timethreshold;
+struct bintime bt_tickthreshold;
+sbintime_t sbt_timethreshold;
+sbintime_t sbt_tickthreshold;
+struct bintime tc_tick_bt;
+sbintime_t tc_tick_sbt;
+int tc_precexp;
+int tc_timepercentage = TC_DEFAULTPERC;
+TUNABLE_INT("kern.timecounter.alloweddeviation", &tc_timepercentage);
+static int sysctl_kern_timecounter_adjprecision(SYSCTL_HANDLER_ARGS);
+SYSCTL_PROC(_kern_timecounter, OID_AUTO, alloweddeviation,
+ CTLTYPE_INT | CTLFLAG_RW | CTLFLAG_MPSAFE, 0, 0,
+ sysctl_kern_timecounter_adjprecision, "I",
+ "Allowed time interval deviation in percents");
+
static void tc_windup(void);
static void cpu_tick_calibrate(int);
@@ -1746,10 +1762,47 @@ tc_ticktock(int cnt)
tc_windup();
}
+static void __inline
+tc_adjprecision(void)
+{
+ int t;
+
+ if (tc_timepercentage > 0) {
+ t = (99 + tc_timepercentage) / tc_timepercentage;
+ tc_precexp = fls(t + (t >> 1)) - 1;
+ FREQ2BT(hz / tc_tick, &bt_timethreshold);
+ FREQ2BT(hz, &bt_tickthreshold);
+ bintime_shift(&bt_timethreshold, tc_precexp);
+ bintime_shift(&bt_tickthreshold, tc_precexp);
+ } else {
+ tc_precexp = 31;
+ bt_timethreshold.sec = INT_MAX;
+ bt_timethreshold.frac = ~(uint64_t)0;
+ bt_tickthreshold = bt_timethreshold;
+ }
+ sbt_timethreshold = bttosbt(bt_timethreshold);
+ sbt_tickthreshold = bttosbt(bt_tickthreshold);
+}
+
+static int
+sysctl_kern_timecounter_adjprecision(SYSCTL_HANDLER_ARGS)
+{
+ int error, val;
+
+ val = tc_timepercentage;
+ error = sysctl_handle_int(oidp, &val, 0, req);
+ if (error != 0 || req->newptr == NULL)
+ return (error);
+ tc_timepercentage = val;
+ tc_adjprecision();
+ return (0);
+}
+
static void
inittimecounter(void *dummy)
{
u_int p;
+ int tick_rate;
/*
* Set the initial timeout to
@@ -1763,6 +1816,12 @@ inittimecounter(void *dummy)
tc_tick = (hz + 500) / 1000;
else
tc_tick = 1;
+ tc_adjprecision();
+ FREQ2BT(hz, &tick_bt);
+ tick_sbt = bttosbt(tick_bt);
+ tick_rate = hz / tc_tick;
+ FREQ2BT(tick_rate, &tc_tick_bt);
+ tc_tick_sbt = bttosbt(tc_tick_bt);
p = (tc_tick * 1000000) / hz;
printf("Timecounters tick every %d.%03u msec\n", p / 1000, p % 1000);
diff --git a/sys/kern/kern_time.c b/sys/kern/kern_time.c
index 97c288d..4225928 100644
--- a/sys/kern/kern_time.c
+++ b/sys/kern/kern_time.c
@@ -43,6 +43,7 @@ __FBSDID("$FreeBSD$");
#include <sys/resourcevar.h>
#include <sys/signalvar.h>
#include <sys/kernel.h>
+#include <sys/sleepqueue.h>
#include <sys/syscallsubr.h>
#include <sys/sysctl.h>
#include <sys/sysent.h>
@@ -481,38 +482,45 @@ static int nanowait;
int
kern_nanosleep(struct thread *td, struct timespec *rqt, struct timespec *rmt)
{
- struct timespec ts, ts2, ts3;
- struct timeval tv;
+ struct timespec ts;
+ sbintime_t sbt, sbtt, prec, tmp;
+ time_t over;
int error;
if (rqt->tv_nsec < 0 || rqt->tv_nsec >= 1000000000)
return (EINVAL);
if (rqt->tv_sec < 0 || (rqt->tv_sec == 0 && rqt->tv_nsec == 0))
return (0);
- getnanouptime(&ts);
- timespecadd(&ts, rqt);
- TIMESPEC_TO_TIMEVAL(&tv, rqt);
- for (;;) {
- error = tsleep(&nanowait, PWAIT | PCATCH, "nanslp",
- tvtohz(&tv));
- getnanouptime(&ts2);
- if (error != EWOULDBLOCK) {
- if (error == ERESTART)
- error = EINTR;
- if (rmt != NULL) {
- timespecsub(&ts, &ts2);
- if (ts.tv_sec < 0)
- timespecclear(&ts);
- *rmt = ts;
- }
- return (error);
+ ts = *rqt;
+ if (ts.tv_sec > INT32_MAX / 2) {
+ over = ts.tv_sec - INT32_MAX / 2;
+ ts.tv_sec -= over;
+ } else
+ over = 0;
+ tmp = tstosbt(ts);
+ prec = tmp;
+ prec >>= tc_precexp;
+ if (TIMESEL(&sbt, tmp))
+ sbt += tc_tick_sbt;
+ sbt += tmp;
+ error = tsleep_sbt(&nanowait, PWAIT | PCATCH, "nanslp", sbt, prec,
+ C_ABSOLUTE);
+ if (error != EWOULDBLOCK) {
+ if (error == ERESTART)
+ error = EINTR;
+ TIMESEL(&sbtt, tmp);
+ if (rmt != NULL) {
+ ts = sbttots(sbt - sbtt);
+ ts.tv_sec += over;
+ if (ts.tv_sec < 0)
+ timespecclear(&ts);
+ *rmt = ts;
}
- if (timespeccmp(&ts2, &ts, >=))
+ if (sbtt >= sbt)
return (0);
- ts3 = ts;
- timespecsub(&ts3, &ts2);
- TIMESPEC_TO_TIMEVAL(&tv, &ts3);
+ return (error);
}
+ return (0);
}
#ifndef _SYS_SYSPROTO_H_
@@ -683,7 +691,7 @@ kern_getitimer(struct thread *td, u_int which, struct itimerval *aitv)
*aitv = p->p_realtimer;
PROC_UNLOCK(p);
if (timevalisset(&aitv->it_value)) {
- getmicrouptime(&ctv);
+ microuptime(&ctv);
if (timevalcmp(&aitv->it_value, &ctv, <))
timevalclear(&aitv->it_value);
else
@@ -728,28 +736,33 @@ kern_setitimer(struct thread *td, u_int which, struct itimerval *aitv,
{
struct proc *p = td->td_proc;
struct timeval ctv;
+ sbintime_t sbt, pr;
if (aitv == NULL)
return (kern_getitimer(td, which, oitv));
if (which > ITIMER_PROF)
return (EINVAL);
- if (itimerfix(&aitv->it_value))
+ if (itimerfix(&aitv->it_value) ||
+ aitv->it_value.tv_sec > INT32_MAX / 2)
return (EINVAL);
if (!timevalisset(&aitv->it_value))
timevalclear(&aitv->it_interval);
- else if (itimerfix(&aitv->it_interval))
+ else if (itimerfix(&aitv->it_interval) ||
+ aitv->it_interval.tv_sec > INT32_MAX / 2)
return (EINVAL);
if (which == ITIMER_REAL) {
PROC_LOCK(p);
if (timevalisset(&p->p_realtimer.it_value))
callout_stop(&p->p_itcallout);
- getmicrouptime(&ctv);
+ microuptime(&ctv);
if (timevalisset(&aitv->it_value)) {
- callout_reset(&p->p_itcallout, tvtohz(&aitv->it_value),
- realitexpire, p);
+ pr = tvtosbt(aitv->it_value) >> tc_precexp;
timevaladd(&aitv->it_value, &ctv);
+ sbt = tvtosbt(aitv->it_value);
+ callout_reset_sbt(&p->p_itcallout, sbt, pr,
+ realitexpire, p, C_ABSOLUTE);
}
*oitv = p->p_realtimer;
p->p_realtimer = *aitv;
@@ -785,7 +798,8 @@ void
realitexpire(void *arg)
{
struct proc *p;
- struct timeval ctv, ntv;
+ struct timeval ctv;
+ sbintime_t isbt;
p = (struct proc *)arg;
kern_psignal(p, SIGALRM);
@@ -795,19 +809,17 @@ realitexpire(void *arg)
wakeup(&p->p_itcallout);
return;
}
- for (;;) {
+ isbt = tvtosbt(p->p_realtimer.it_interval);
+ if (isbt >= sbt_timethreshold)
+ getmicrouptime(&ctv);
+ else
+ microuptime(&ctv);
+ do {
timevaladd(&p->p_realtimer.it_value,
&p->p_realtimer.it_interval);
- getmicrouptime(&ctv);
- if (timevalcmp(&p->p_realtimer.it_value, &ctv, >)) {
- ntv = p->p_realtimer.it_value;
- timevalsub(&ntv, &ctv);
- callout_reset(&p->p_itcallout, tvtohz(&ntv) - 1,
- realitexpire, p);
- return;
- }
- }
- /*NOTREACHED*/
+ } while (timevalcmp(&p->p_realtimer.it_value, &ctv, <=));
+ callout_reset_sbt(&p->p_itcallout, tvtosbt(p->p_realtimer.it_value),
+ isbt >> tc_precexp, realitexpire, p, C_ABSOLUTE);
}
/*
@@ -822,8 +834,9 @@ itimerfix(struct timeval *tv)
if (tv->tv_sec < 0 || tv->tv_usec < 0 || tv->tv_usec >= 1000000)
return (EINVAL);
- if (tv->tv_sec == 0 && tv->tv_usec != 0 && tv->tv_usec < tick)
- tv->tv_usec = tick;
+ if (tv->tv_sec == 0 && tv->tv_usec != 0 &&
+ tv->tv_usec < (u_int)tick / 16)
+ tv->tv_usec = (u_int)tick / 16;
return (0);
}
diff --git a/sys/kern/kern_timeout.c b/sys/kern/kern_timeout.c
index 9cdc39b..df459cd 100644
--- a/sys/kern/kern_timeout.c
+++ b/sys/kern/kern_timeout.c
@@ -37,13 +37,16 @@
#include <sys/cdefs.h>
__FBSDID("$FreeBSD$");
+#include "opt_callout_profiling.h"
#include "opt_kdtrace.h"
+#if defined(__arm__)
+#include "opt_timer.h"
+#endif
#include <sys/param.h>
#include <sys/systm.h>
#include <sys/bus.h>
#include <sys/callout.h>
-#include <sys/condvar.h>
#include <sys/interrupt.h>
#include <sys/kernel.h>
#include <sys/ktr.h>
@@ -60,6 +63,10 @@ __FBSDID("$FreeBSD$");
#include <machine/cpu.h>
#endif
+#ifndef NO_EVENTTIMERS
+DPCPU_DECLARE(sbintime_t, hardclocktime);
+#endif
+
SDT_PROVIDER_DEFINE(callout_execute);
SDT_PROBE_DEFINE(callout_execute, kernel, , callout_start, callout-start);
SDT_PROBE_ARGTYPE(callout_execute, kernel, , callout_start, 0,
@@ -68,6 +75,7 @@ SDT_PROBE_DEFINE(callout_execute, kernel, , callout_end, callout-end);
SDT_PROBE_ARGTYPE(callout_execute, kernel, , callout_end, 0,
"struct callout *");
+#ifdef CALLOUT_PROFILING
static int avg_depth;
SYSCTL_INT(_debug, OID_AUTO, to_avg_depth, CTLFLAG_RD, &avg_depth, 0,
"Average number of items examined per softclock call. Units = 1/1000");
@@ -80,65 +88,83 @@ SYSCTL_INT(_debug, OID_AUTO, to_avg_lockcalls, CTLFLAG_RD, &avg_lockcalls, 0,
static int avg_mpcalls;
SYSCTL_INT(_debug, OID_AUTO, to_avg_mpcalls, CTLFLAG_RD, &avg_mpcalls, 0,
"Average number of MP callouts made per softclock call. Units = 1/1000");
+static int avg_depth_dir;
+SYSCTL_INT(_debug, OID_AUTO, to_avg_depth_dir, CTLFLAG_RD, &avg_depth_dir, 0,
+ "Average number of direct callouts examined per callout_process call. "
+ "Units = 1/1000");
+static int avg_lockcalls_dir;
+SYSCTL_INT(_debug, OID_AUTO, to_avg_lockcalls_dir, CTLFLAG_RD,
+ &avg_lockcalls_dir, 0, "Average number of lock direct callouts made per "
+ "callout_process call. Units = 1/1000");
+static int avg_mpcalls_dir;
+SYSCTL_INT(_debug, OID_AUTO, to_avg_mpcalls_dir, CTLFLAG_RD, &avg_mpcalls_dir,
+ 0, "Average number of MP direct callouts made per callout_process call. "
+ "Units = 1/1000");
+#endif
/*
* TODO:
* allocate more timeout table slots when table overflows.
*/
-int callwheelsize, callwheelmask;
+u_int callwheelsize, callwheelmask;
/*
- * The callout cpu migration entity represents informations necessary for
- * describing the migrating callout to the new callout cpu.
+ * The callout cpu exec entities represent informations necessary for
+ * describing the state of callouts currently running on the CPU and the ones
+ * necessary for migrating callouts to the new callout cpu. In particular,
+ * the first entry of the array cc_exec_entity holds informations for callout
+ * running in SWI thread context, while the second one holds informations
+ * for callout running directly from hardware interrupt context.
* The cached informations are very important for deferring migration when
* the migrating callout is already running.
*/
-struct cc_mig_ent {
+struct cc_exec {
+ struct callout *cc_next;
+ struct callout *cc_curr;
#ifdef SMP
- void (*ce_migration_func)(void *);
- void *ce_migration_arg;
- int ce_migration_cpu;
- int ce_migration_ticks;
+ void (*ce_migration_func)(void *);
+ void *ce_migration_arg;
+ int ce_migration_cpu;
+ sbintime_t ce_migration_time;
#endif
+ bool cc_cancel;
+ bool cc_waiting;
};
/*
* There is one struct callout_cpu per cpu, holding all relevant
* state for the callout processing thread on the individual CPU.
- * In particular:
- * cc_ticks is incremented once per tick in callout_cpu().
- * It tracks the global 'ticks' but in a way that the individual
- * threads should not worry about races in the order in which
- * hardclock() and hardclock_cpu() run on the various CPUs.
- * cc_softclock is advanced in callout_cpu() to point to the
- * first entry in cc_callwheel that may need handling. In turn,
- * a softclock() is scheduled so it can serve the various entries i
- * such that cc_softclock <= i <= cc_ticks .
- * XXX maybe cc_softclock and cc_ticks should be volatile ?
- *
- * cc_ticks is also used in callout_reset_cpu() to determine
- * when the callout should be served.
*/
struct callout_cpu {
struct mtx_padalign cc_lock;
- struct cc_mig_ent cc_migrating_entity;
+ struct cc_exec cc_exec_entity[2];
struct callout *cc_callout;
- struct callout_tailq *cc_callwheel;
- struct callout_list cc_callfree;
- struct callout *cc_next;
- struct callout *cc_curr;
+ struct callout_list *cc_callwheel;
+ struct callout_tailq cc_expireq;
+ struct callout_slist cc_callfree;
+ sbintime_t cc_firstevent;
+ sbintime_t cc_lastscan;
void *cc_cookie;
- int cc_ticks;
- int cc_softticks;
- int cc_cancel;
- int cc_waiting;
- int cc_firsttick;
+ u_int cc_bucket;
};
+#define cc_exec_curr cc_exec_entity[0].cc_curr
+#define cc_exec_next cc_exec_entity[0].cc_next
+#define cc_exec_cancel cc_exec_entity[0].cc_cancel
+#define cc_exec_waiting cc_exec_entity[0].cc_waiting
+#define cc_exec_curr_dir cc_exec_entity[1].cc_curr
+#define cc_exec_next_dir cc_exec_entity[1].cc_next
+#define cc_exec_cancel_dir cc_exec_entity[1].cc_cancel
+#define cc_exec_waiting_dir cc_exec_entity[1].cc_waiting
+
#ifdef SMP
-#define cc_migration_func cc_migrating_entity.ce_migration_func
-#define cc_migration_arg cc_migrating_entity.ce_migration_arg
-#define cc_migration_cpu cc_migrating_entity.ce_migration_cpu
-#define cc_migration_ticks cc_migrating_entity.ce_migration_ticks
+#define cc_migration_func cc_exec_entity[0].ce_migration_func
+#define cc_migration_arg cc_exec_entity[0].ce_migration_arg
+#define cc_migration_cpu cc_exec_entity[0].ce_migration_cpu
+#define cc_migration_time cc_exec_entity[0].ce_migration_time
+#define cc_migration_func_dir cc_exec_entity[1].ce_migration_func
+#define cc_migration_arg_dir cc_exec_entity[1].ce_migration_arg
+#define cc_migration_cpu_dir cc_exec_entity[1].ce_migration_cpu
+#define cc_migration_time_dir cc_exec_entity[1].ce_migration_time
struct callout_cpu cc_cpu[MAXCPU];
#define CPUBLOCK MAXCPU
@@ -154,39 +180,48 @@ struct callout_cpu cc_cpu;
#define CC_LOCK_ASSERT(cc) mtx_assert(&(cc)->cc_lock, MA_OWNED)
static int timeout_cpu;
-void (*callout_new_inserted)(int cpu, int ticks) = NULL;
+
+static void softclock_call_cc(struct callout *c, struct callout_cpu *cc,
+#ifdef CALLOUT_PROFILING
+ int *mpcalls, int *lockcalls, int *gcalls,
+#endif
+ int direct);
static MALLOC_DEFINE(M_CALLOUT, "callout", "Callout datastructures");
/**
* Locked by cc_lock:
- * cc_curr - If a callout is in progress, it is curr_callout.
- * If curr_callout is non-NULL, threads waiting in
+ * cc_curr - If a callout is in progress, it is cc_curr.
+ * If cc_curr is non-NULL, threads waiting in
* callout_drain() will be woken up as soon as the
* relevant callout completes.
- * cc_cancel - Changing to 1 with both callout_lock and c_lock held
+ * cc_cancel - Changing to 1 with both callout_lock and cc_lock held
* guarantees that the current callout will not run.
* The softclock() function sets this to 0 before it
* drops callout_lock to acquire c_lock, and it calls
* the handler only if curr_cancelled is still 0 after
- * c_lock is successfully acquired.
+ * cc_lock is successfully acquired.
* cc_waiting - If a thread is waiting in callout_drain(), then
* callout_wait is nonzero. Set only when
- * curr_callout is non-NULL.
+ * cc_curr is non-NULL.
*/
/*
- * Resets the migration entity tied to a specific callout cpu.
+ * Resets the execution entity tied to a specific callout cpu.
*/
static void
-cc_cme_cleanup(struct callout_cpu *cc)
+cc_cce_cleanup(struct callout_cpu *cc, int direct)
{
+ cc->cc_exec_entity[direct].cc_curr = NULL;
+ cc->cc_exec_entity[direct].cc_next = NULL;
+ cc->cc_exec_entity[direct].cc_cancel = false;
+ cc->cc_exec_entity[direct].cc_waiting = false;
#ifdef SMP
- cc->cc_migration_cpu = CPUBLOCK;
- cc->cc_migration_ticks = 0;
- cc->cc_migration_func = NULL;
- cc->cc_migration_arg = NULL;
+ cc->cc_exec_entity[direct].ce_migration_cpu = CPUBLOCK;
+ cc->cc_exec_entity[direct].ce_migration_time = 0;
+ cc->cc_exec_entity[direct].ce_migration_func = NULL;
+ cc->cc_exec_entity[direct].ce_migration_arg = NULL;
#endif
}
@@ -194,18 +229,18 @@ cc_cme_cleanup(struct callout_cpu *cc)
* Checks if migration is requested by a specific callout cpu.
*/
static int
-cc_cme_migrating(struct callout_cpu *cc)
+cc_cce_migrating(struct callout_cpu *cc, int direct)
{
#ifdef SMP
- return (cc->cc_migration_cpu != CPUBLOCK);
+ return (cc->cc_exec_entity[direct].ce_migration_cpu != CPUBLOCK);
#else
return (0);
#endif
}
/*
- * kern_timeout_callwheel_alloc() - kernel low level callwheel initialization
+ * kern_timeout_callwheel_alloc() - kernel low level callwheel initialization
*
* This code is called very early in the kernel initialization sequence,
* and may be called more then once.
@@ -226,7 +261,7 @@ kern_timeout_callwheel_alloc(caddr_t v)
cc->cc_callout = (struct callout *)v;
v = (caddr_t)(cc->cc_callout + ncallout);
- cc->cc_callwheel = (struct callout_tailq *)v;
+ cc->cc_callwheel = (struct callout_list *)v;
v = (caddr_t)(cc->cc_callwheel + callwheelsize);
return(v);
}
@@ -239,10 +274,12 @@ callout_cpu_init(struct callout_cpu *cc)
mtx_init(&cc->cc_lock, "callout", NULL, MTX_SPIN | MTX_RECURSE);
SLIST_INIT(&cc->cc_callfree);
- for (i = 0; i < callwheelsize; i++) {
- TAILQ_INIT(&cc->cc_callwheel[i]);
- }
- cc_cme_cleanup(cc);
+ for (i = 0; i < callwheelsize; i++)
+ LIST_INIT(&cc->cc_callwheel[i]);
+ TAILQ_INIT(&cc->cc_expireq);
+ cc->cc_firstevent = INT64_MAX;
+ for (i = 0; i < 2; i++)
+ cc_cce_cleanup(cc, i);
if (cc->cc_callout == NULL)
return;
for (i = 0; i < ncallout; i++) {
@@ -321,7 +358,7 @@ start_softclock(void *dummy)
panic("died while creating standard software ithreads");
cc->cc_callout = NULL; /* Only cpu0 handles timeout(). */
cc->cc_callwheel = malloc(
- sizeof(struct callout_tailq) * callwheelsize, M_CALLOUT,
+ sizeof(struct callout_list) * callwheelsize, M_CALLOUT,
M_WAITOK);
callout_cpu_init(cc);
}
@@ -330,64 +367,148 @@ start_softclock(void *dummy)
SYSINIT(start_softclock, SI_SUB_SOFTINTR, SI_ORDER_FIRST, start_softclock, NULL);
+#define CC_HASH_SHIFT 8
+
+static inline u_int
+callout_hash(sbintime_t sbt)
+{
+
+ return (sbt >> (32 - CC_HASH_SHIFT));
+}
+
+static inline u_int
+callout_get_bucket(sbintime_t sbt)
+{
+
+ return (callout_hash(sbt) & callwheelmask);
+}
+
void
-callout_tick(void)
+callout_process(sbintime_t now)
{
+ struct callout *tmp, *tmpn;
struct callout_cpu *cc;
- int need_softclock;
- int bucket;
+ struct callout_list *sc;
+ sbintime_t first, last, max, tmp_max;
+ uint32_t lookahead;
+ u_int firstb, lastb, nowb;
+#ifdef CALLOUT_PROFILING
+ int depth_dir = 0, mpcalls_dir = 0, lockcalls_dir = 0;
+#endif
- /*
- * Process callouts at a very low cpu priority, so we don't keep the
- * relatively high clock interrupt priority any longer than necessary.
- */
- need_softclock = 0;
cc = CC_SELF();
mtx_lock_spin_flags(&cc->cc_lock, MTX_QUIET);
- cc->cc_firsttick = cc->cc_ticks = ticks;
- for (; (cc->cc_softticks - cc->cc_ticks) <= 0; cc->cc_softticks++) {
- bucket = cc->cc_softticks & callwheelmask;
- if (!TAILQ_EMPTY(&cc->cc_callwheel[bucket])) {
- need_softclock = 1;
- break;
- }
+
+ /* Compute the buckets of the last scan and present times. */
+ firstb = callout_hash(cc->cc_lastscan);
+ cc->cc_lastscan = now;
+ nowb = callout_hash(now);
+
+ /* Compute the last bucket and minimum time of the bucket after it. */
+ if (nowb == firstb)
+ lookahead = (SBT_1S / 16);
+ else if (nowb - firstb == 1)
+ lookahead = (SBT_1S / 8);
+ else
+ lookahead = (SBT_1S / 2);
+ first = last = now;
+ first += (lookahead / 2);
+ last += lookahead;
+ last &= (0xffffffffffffffffLLU << (32 - CC_HASH_SHIFT));
+ lastb = callout_hash(last) - 1;
+ max = last;
+
+ /*
+ * Check if we wrapped around the entire wheel from the last scan.
+ * In case, we need to scan entirely the wheel for pending callouts.
+ */
+ if (lastb - firstb >= callwheelsize) {
+ lastb = firstb + callwheelsize - 1;
+ if (nowb - firstb >= callwheelsize)
+ nowb = lastb;
}
+
+ /* Iterate callwheel from firstb to nowb and then up to lastb. */
+ do {
+ sc = &cc->cc_callwheel[firstb & callwheelmask];
+ tmp = LIST_FIRST(sc);
+ while (tmp != NULL) {
+ /* Run the callout if present time within allowed. */
+ if (tmp->c_time <= now) {
+ /*
+ * Consumer told us the callout may be run
+ * directly from hardware interrupt context.
+ */
+ if (tmp->c_flags & CALLOUT_DIRECT) {
+#ifdef CALLOUT_PROFILING
+ ++depth_dir;
+#endif
+ cc->cc_exec_next_dir =
+ LIST_NEXT(tmp, c_links.le);
+ cc->cc_bucket = firstb & callwheelmask;
+ LIST_REMOVE(tmp, c_links.le);
+ softclock_call_cc(tmp, cc,
+#ifdef CALLOUT_PROFILING
+ &mpcalls_dir, &lockcalls_dir, NULL,
+#endif
+ 1);
+ tmp = cc->cc_exec_next_dir;
+ } else {
+ tmpn = LIST_NEXT(tmp, c_links.le);
+ LIST_REMOVE(tmp, c_links.le);
+ TAILQ_INSERT_TAIL(&cc->cc_expireq,
+ tmp, c_links.tqe);
+ tmp->c_flags |= CALLOUT_PROCESSED;
+ tmp = tmpn;
+ }
+ continue;
+ }
+ /* Skip events from distant future. */
+ if (tmp->c_time >= max)
+ goto next;
+ /*
+ * Event minimal time is bigger than present maximal
+ * time, so it cannot be aggregated.
+ */
+ if (tmp->c_time > last) {
+ lastb = nowb;
+ goto next;
+ }
+ /* Update first and last time, respecting this event. */
+ if (tmp->c_time < first)
+ first = tmp->c_time;
+ tmp_max = tmp->c_time + tmp->c_precision;
+ if (tmp_max < last)
+ last = tmp_max;
+next:
+ tmp = LIST_NEXT(tmp, c_links.le);
+ }
+ /* Proceed with the next bucket. */
+ firstb++;
+ /*
+ * Stop if we looked after present time and found
+ * some event we can't execute at now.
+ * Stop if we looked far enough into the future.
+ */
+ } while (((int)(firstb - lastb)) <= 0);
+ cc->cc_firstevent = last;
+#ifndef NO_EVENTTIMERS
+ cpu_new_callout(curcpu, last, first);
+#endif
+#ifdef CALLOUT_PROFILING
+ avg_depth_dir += (depth_dir * 1000 - avg_depth_dir) >> 8;
+ avg_mpcalls_dir += (mpcalls_dir * 1000 - avg_mpcalls_dir) >> 8;
+ avg_lockcalls_dir += (lockcalls_dir * 1000 - avg_lockcalls_dir) >> 8;
+#endif
mtx_unlock_spin_flags(&cc->cc_lock, MTX_QUIET);
/*
* swi_sched acquires the thread lock, so we don't want to call it
* with cc_lock held; incorrect locking order.
*/
- if (need_softclock)
+ if (!TAILQ_EMPTY(&cc->cc_expireq))
swi_sched(cc->cc_cookie, 0);
}
-int
-callout_tickstofirst(int limit)
-{
- struct callout_cpu *cc;
- struct callout *c;
- struct callout_tailq *sc;
- int curticks;
- int skip = 1;
-
- cc = CC_SELF();
- mtx_lock_spin_flags(&cc->cc_lock, MTX_QUIET);
- curticks = cc->cc_ticks;
- while( skip < ncallout && skip < limit ) {
- sc = &cc->cc_callwheel[ (curticks+skip) & callwheelmask ];
- /* search scanning ticks */
- TAILQ_FOREACH( c, sc, c_links.tqe ){
- if (c->c_time - curticks <= ncallout)
- goto out;
- }
- skip++;
- }
-out:
- cc->cc_firsttick = curticks + skip;
- mtx_unlock_spin_flags(&cc->cc_lock, MTX_QUIET);
- return (skip);
-}
-
static struct callout_cpu *
callout_lock(struct callout *c)
{
@@ -413,26 +534,41 @@ callout_lock(struct callout *c)
}
static void
-callout_cc_add(struct callout *c, struct callout_cpu *cc, int to_ticks,
- void (*func)(void *), void *arg, int cpu)
+callout_cc_add(struct callout *c, struct callout_cpu *cc,
+ sbintime_t sbt, sbintime_t precision, void (*func)(void *),
+ void *arg, int cpu, int flags)
{
+ int bucket;
CC_LOCK_ASSERT(cc);
-
- if (to_ticks <= 0)
- to_ticks = 1;
+ if (sbt < cc->cc_lastscan)
+ sbt = cc->cc_lastscan;
c->c_arg = arg;
c->c_flags |= (CALLOUT_ACTIVE | CALLOUT_PENDING);
+ if (flags & C_DIRECT_EXEC)
+ c->c_flags |= CALLOUT_DIRECT;
+ c->c_flags &= ~CALLOUT_PROCESSED;
c->c_func = func;
- c->c_time = ticks + to_ticks;
- TAILQ_INSERT_TAIL(&cc->cc_callwheel[c->c_time & callwheelmask],
- c, c_links.tqe);
- if ((c->c_time - cc->cc_firsttick) < 0 &&
- callout_new_inserted != NULL) {
- cc->cc_firsttick = c->c_time;
- (*callout_new_inserted)(cpu,
- to_ticks + (ticks - cc->cc_ticks));
+ c->c_time = sbt;
+ c->c_precision = precision;
+ bucket = callout_get_bucket(c->c_time);
+ CTR3(KTR_CALLOUT, "precision set for %p: %d.%08x",
+ c, (int)(c->c_precision >> 32),
+ (u_int)(c->c_precision & 0xffffffff));
+ LIST_INSERT_HEAD(&cc->cc_callwheel[bucket], c, c_links.le);
+ if (cc->cc_bucket == bucket)
+ cc->cc_exec_next_dir = c;
+#ifndef NO_EVENTTIMERS
+ /*
+ * Inform the eventtimers(4) subsystem there's a new callout
+ * that has been inserted, but only if really required.
+ */
+ sbt = c->c_time + c->c_precision;
+ if (sbt < cc->cc_firstevent) {
+ cc->cc_firstevent = sbt;
+ cpu_new_callout(cpu, sbt, c->c_time);
}
+#endif
}
static void
@@ -446,8 +582,11 @@ callout_cc_del(struct callout *c, struct callout_cpu *cc)
}
static void
-softclock_call_cc(struct callout *c, struct callout_cpu *cc, int *mpcalls,
- int *lockcalls, int *gcalls)
+softclock_call_cc(struct callout *c, struct callout_cpu *cc,
+#ifdef CALLOUT_PROFILING
+ int *mpcalls, int *lockcalls, int *gcalls,
+#endif
+ int direct)
{
void (*c_func)(void *);
void *c_arg;
@@ -458,12 +597,13 @@ softclock_call_cc(struct callout *c, struct callout_cpu *cc, int *mpcalls,
struct callout_cpu *new_cc;
void (*new_func)(void *);
void *new_arg;
- int new_cpu, new_ticks;
+ int flags, new_cpu;
+ sbintime_t new_time;
#endif
-#ifdef DIAGNOSTIC
- struct bintime bt1, bt2;
+#if defined(DIAGNOSTIC) || defined(CALLOUT_PROFILING)
+ sbintime_t sbt1, sbt2;
struct timespec ts2;
- static uint64_t maxdt = 36893488147419102LL; /* 2 msec */
+ static sbintime_t maxdt = 2 * SBT_1MS; /* 2 msec */
static timeout_t *lastfunc;
#endif
@@ -480,8 +620,8 @@ softclock_call_cc(struct callout *c, struct callout_cpu *cc, int *mpcalls,
c->c_flags = CALLOUT_LOCAL_ALLOC;
else
c->c_flags &= ~CALLOUT_PENDING;
- cc->cc_curr = c;
- cc->cc_cancel = 0;
+ cc->cc_exec_entity[direct].cc_curr = c;
+ cc->cc_exec_entity[direct].cc_cancel = false;
CC_UNLOCK(cc);
if (c_lock != NULL) {
class->lc_lock(c_lock, sharedlock);
@@ -489,46 +629,51 @@ softclock_call_cc(struct callout *c, struct callout_cpu *cc, int *mpcalls,
* The callout may have been cancelled
* while we switched locks.
*/
- if (cc->cc_cancel) {
+ if (cc->cc_exec_entity[direct].cc_cancel) {
class->lc_unlock(c_lock);
goto skip;
}
/* The callout cannot be stopped now. */
- cc->cc_cancel = 1;
-
+ cc->cc_exec_entity[direct].cc_cancel = true;
if (c_lock == &Giant.lock_object) {
+#ifdef CALLOUT_PROFILING
(*gcalls)++;
- CTR3(KTR_CALLOUT, "callout %p func %p arg %p",
+#endif
+ CTR3(KTR_CALLOUT, "callout giant %p func %p arg %p",
c, c_func, c_arg);
} else {
+#ifdef CALLOUT_PROFILING
(*lockcalls)++;
+#endif
CTR3(KTR_CALLOUT, "callout lock %p func %p arg %p",
c, c_func, c_arg);
}
} else {
+#ifdef CALLOUT_PROFILING
(*mpcalls)++;
- CTR3(KTR_CALLOUT, "callout mpsafe %p func %p arg %p",
+#endif
+ CTR3(KTR_CALLOUT, "callout %p func %p arg %p",
c, c_func, c_arg);
}
-#ifdef DIAGNOSTIC
- binuptime(&bt1);
+#if defined(DIAGNOSTIC) || defined(CALLOUT_PROFILING)
+ sbt1 = sbinuptime();
#endif
THREAD_NO_SLEEPING();
SDT_PROBE(callout_execute, kernel, , callout_start, c, 0, 0, 0, 0);
c_func(c_arg);
SDT_PROBE(callout_execute, kernel, , callout_end, c, 0, 0, 0, 0);
THREAD_SLEEPING_OK();
-#ifdef DIAGNOSTIC
- binuptime(&bt2);
- bintime_sub(&bt2, &bt1);
- if (bt2.frac > maxdt) {
- if (lastfunc != c_func || bt2.frac > maxdt * 2) {
- bintime2timespec(&bt2, &ts2);
+#if defined(DIAGNOSTIC) || defined(CALLOUT_PROFILING)
+ sbt2 = sbinuptime();
+ sbt2 -= sbt1;
+ if (sbt2 > maxdt) {
+ if (lastfunc != c_func || sbt2 > maxdt * 2) {
+ ts2 = sbttots(sbt2);
printf(
"Expensive timeout(9) function: %p(%p) %jd.%09ld s\n",
c_func, c_arg, (intmax_t)ts2.tv_sec, ts2.tv_nsec);
}
- maxdt = bt2.frac;
+ maxdt = sbt2;
lastfunc = c_func;
}
#endif
@@ -537,17 +682,17 @@ softclock_call_cc(struct callout *c, struct callout_cpu *cc, int *mpcalls,
class->lc_unlock(c_lock);
skip:
CC_LOCK(cc);
- KASSERT(cc->cc_curr == c, ("mishandled cc_curr"));
- cc->cc_curr = NULL;
- if (cc->cc_waiting) {
+ KASSERT(cc->cc_exec_entity[direct].cc_curr == c, ("mishandled cc_curr"));
+ cc->cc_exec_entity[direct].cc_curr = NULL;
+ if (cc->cc_exec_entity[direct].cc_waiting) {
/*
* There is someone waiting for the
* callout to complete.
* If the callout was scheduled for
* migration just cancel it.
*/
- if (cc_cme_migrating(cc)) {
- cc_cme_cleanup(cc);
+ if (cc_cce_migrating(cc, direct)) {
+ cc_cce_cleanup(cc, direct);
/*
* It should be assert here that the callout is not
@@ -555,11 +700,11 @@ skip:
*/
c->c_flags &= ~CALLOUT_DFRMIGRATION;
}
- cc->cc_waiting = 0;
+ cc->cc_exec_entity[direct].cc_waiting = false;
CC_UNLOCK(cc);
- wakeup(&cc->cc_waiting);
+ wakeup(&cc->cc_exec_entity[direct].cc_waiting);
CC_LOCK(cc);
- } else if (cc_cme_migrating(cc)) {
+ } else if (cc_cce_migrating(cc, direct)) {
KASSERT((c_flags & CALLOUT_LOCAL_ALLOC) == 0,
("Migrating legacy callout %p", c));
#ifdef SMP
@@ -567,11 +712,11 @@ skip:
* If the callout was scheduled for
* migration just perform it now.
*/
- new_cpu = cc->cc_migration_cpu;
- new_ticks = cc->cc_migration_ticks;
- new_func = cc->cc_migration_func;
- new_arg = cc->cc_migration_arg;
- cc_cme_cleanup(cc);
+ new_cpu = cc->cc_exec_entity[direct].ce_migration_cpu;
+ new_time = cc->cc_exec_entity[direct].ce_migration_time;
+ new_func = cc->cc_exec_entity[direct].ce_migration_func;
+ new_arg = cc->cc_exec_entity[direct].ce_migration_arg;
+ cc_cce_cleanup(cc, direct);
/*
* It should be assert here that the callout is not destroyed
@@ -589,8 +734,9 @@ skip:
c->c_flags &= ~CALLOUT_DFRMIGRATION;
new_cc = callout_cpu_switch(c, cc, new_cpu);
- callout_cc_add(c, new_cc, new_ticks, new_func, new_arg,
- new_cpu);
+ flags = (direct) ? C_DIRECT_EXEC : 0;
+ callout_cc_add(c, new_cc, new_time, c->c_precision, new_func,
+ new_arg, new_cpu, flags);
CC_UNLOCK(new_cc);
CC_LOCK(cc);
#else
@@ -633,63 +779,29 @@ softclock(void *arg)
{
struct callout_cpu *cc;
struct callout *c;
- struct callout_tailq *bucket;
- int curticks;
- int steps; /* #steps since we last allowed interrupts */
- int depth;
- int mpcalls;
- int lockcalls;
- int gcalls;
-
-#ifndef MAX_SOFTCLOCK_STEPS
-#define MAX_SOFTCLOCK_STEPS 100 /* Maximum allowed value of steps. */
-#endif /* MAX_SOFTCLOCK_STEPS */
-
- mpcalls = 0;
- lockcalls = 0;
- gcalls = 0;
- depth = 0;
- steps = 0;
+#ifdef CALLOUT_PROFILING
+ int depth = 0, gcalls = 0, lockcalls = 0, mpcalls = 0;
+#endif
+
cc = (struct callout_cpu *)arg;
CC_LOCK(cc);
- while (cc->cc_softticks - 1 != cc->cc_ticks) {
- /*
- * cc_softticks may be modified by hard clock, so cache
- * it while we work on a given bucket.
- */
- curticks = cc->cc_softticks;
- cc->cc_softticks++;
- bucket = &cc->cc_callwheel[curticks & callwheelmask];
- c = TAILQ_FIRST(bucket);
- while (c != NULL) {
- depth++;
- if (c->c_time != curticks) {
- c = TAILQ_NEXT(c, c_links.tqe);
- ++steps;
- if (steps >= MAX_SOFTCLOCK_STEPS) {
- cc->cc_next = c;
- /* Give interrupts a chance. */
- CC_UNLOCK(cc);
- ; /* nothing */
- CC_LOCK(cc);
- c = cc->cc_next;
- steps = 0;
- }
- } else {
- cc->cc_next = TAILQ_NEXT(c, c_links.tqe);
- TAILQ_REMOVE(bucket, c, c_links.tqe);
- softclock_call_cc(c, cc, &mpcalls,
- &lockcalls, &gcalls);
- steps = 0;
- c = cc->cc_next;
- }
- }
+ while ((c = TAILQ_FIRST(&cc->cc_expireq)) != NULL) {
+ TAILQ_REMOVE(&cc->cc_expireq, c, c_links.tqe);
+ softclock_call_cc(c, cc,
+#ifdef CALLOUT_PROFILING
+ &mpcalls, &lockcalls, &gcalls,
+#endif
+ 0);
+#ifdef CALLOUT_PROFILING
+ ++depth;
+#endif
}
+#ifdef CALLOUT_PROFILING
avg_depth += (depth * 1000 - avg_depth) >> 8;
avg_mpcalls += (mpcalls * 1000 - avg_mpcalls) >> 8;
avg_lockcalls += (lockcalls * 1000 - avg_lockcalls) >> 8;
avg_gcalls += (gcalls * 1000 - avg_gcalls) >> 8;
- cc->cc_next = NULL;
+#endif
CC_UNLOCK(cc);
}
@@ -704,7 +816,7 @@ softclock(void *arg)
* Initialize a handle so that using it with untimeout is benign.
*
* See AT&T BCI Driver Reference Manual for specification. This
- * implementation differs from that one in that although an
+ * implementation differs from that one in that although an
* identification value is returned from timeout, the original
* arguments to timeout as well as the identifier are used to
* identify entries for untimeout.
@@ -779,28 +891,71 @@ callout_handle_init(struct callout_handle *handle)
* callout_deactivate() - marks the callout as having been serviced
*/
int
-callout_reset_on(struct callout *c, int to_ticks, void (*ftn)(void *),
- void *arg, int cpu)
+callout_reset_sbt_on(struct callout *c, sbintime_t sbt, sbintime_t precision,
+ void (*ftn)(void *), void *arg, int cpu, int flags)
{
+ sbintime_t to_sbt, pr;
struct callout_cpu *cc;
- int cancelled = 0;
+ int cancelled, direct;
+ cancelled = 0;
+ if (flags & C_ABSOLUTE) {
+ to_sbt = sbt;
+ } else {
+ if ((flags & C_HARDCLOCK) && (sbt < tick_sbt))
+ sbt = tick_sbt;
+ if ((flags & C_HARDCLOCK) ||
+#ifdef NO_EVENTTIMERS
+ sbt >= sbt_timethreshold) {
+ to_sbt = getsbinuptime();
+
+ /* Add safety belt for the case of hz > 1000. */
+ to_sbt += tc_tick_sbt - tick_sbt;
+#else
+ sbt >= sbt_tickthreshold) {
+ /*
+ * Obtain the time of the last hardclock() call on
+ * this CPU directly from the kern_clocksource.c.
+ * This value is per-CPU, but it is equal for all
+ * active ones.
+ */
+#ifdef __LP64__
+ to_sbt = DPCPU_GET(hardclocktime);
+#else
+ spinlock_enter();
+ to_sbt = DPCPU_GET(hardclocktime);
+ spinlock_exit();
+#endif
+#endif
+ if ((flags & C_HARDCLOCK) == 0)
+ to_sbt += tick_sbt;
+ } else
+ to_sbt = sbinuptime();
+ to_sbt += sbt;
+ pr = ((C_PRELGET(flags) < 0) ? sbt >> tc_precexp :
+ sbt >> C_PRELGET(flags));
+ if (pr > precision)
+ precision = pr;
+ }
/*
* Don't allow migration of pre-allocated callouts lest they
* become unbalanced.
*/
if (c->c_flags & CALLOUT_LOCAL_ALLOC)
cpu = c->c_cpu;
+ direct = (c->c_flags & CALLOUT_DIRECT) != 0;
+ KASSERT(!direct || c->c_lock == NULL,
+ ("%s: direct callout %p has lock", __func__, c));
cc = callout_lock(c);
- if (cc->cc_curr == c) {
+ if (cc->cc_exec_entity[direct].cc_curr == c) {
/*
* We're being asked to reschedule a callout which is
* currently in progress. If there is a lock then we
* can cancel the callout if it has not really started.
*/
- if (c->c_lock != NULL && !cc->cc_cancel)
- cancelled = cc->cc_cancel = 1;
- if (cc->cc_waiting) {
+ if (c->c_lock != NULL && !cc->cc_exec_entity[direct].cc_cancel)
+ cancelled = cc->cc_exec_entity[direct].cc_cancel = true;
+ if (cc->cc_exec_entity[direct].cc_waiting) {
/*
* Someone has called callout_drain to kill this
* callout. Don't reschedule.
@@ -813,12 +968,12 @@ callout_reset_on(struct callout *c, int to_ticks, void (*ftn)(void *),
}
}
if (c->c_flags & CALLOUT_PENDING) {
- if (cc->cc_next == c) {
- cc->cc_next = TAILQ_NEXT(c, c_links.tqe);
- }
- TAILQ_REMOVE(&cc->cc_callwheel[c->c_time & callwheelmask], c,
- c_links.tqe);
-
+ if ((c->c_flags & CALLOUT_PROCESSED) == 0) {
+ if (cc->cc_exec_next_dir == c)
+ cc->cc_exec_next_dir = LIST_NEXT(c, c_links.le);
+ LIST_REMOVE(c, c_links.le);
+ } else
+ TAILQ_REMOVE(&cc->cc_expireq, c, c_links.tqe);
cancelled = 1;
c->c_flags &= ~(CALLOUT_ACTIVE | CALLOUT_PENDING);
}
@@ -830,15 +985,17 @@ callout_reset_on(struct callout *c, int to_ticks, void (*ftn)(void *),
* to a more appropriate moment.
*/
if (c->c_cpu != cpu) {
- if (cc->cc_curr == c) {
- cc->cc_migration_cpu = cpu;
- cc->cc_migration_ticks = to_ticks;
- cc->cc_migration_func = ftn;
- cc->cc_migration_arg = arg;
+ if (cc->cc_exec_entity[direct].cc_curr == c) {
+ cc->cc_exec_entity[direct].ce_migration_cpu = cpu;
+ cc->cc_exec_entity[direct].ce_migration_time
+ = to_sbt;
+ cc->cc_exec_entity[direct].ce_migration_func = ftn;
+ cc->cc_exec_entity[direct].ce_migration_arg = arg;
c->c_flags |= CALLOUT_DFRMIGRATION;
- CTR5(KTR_CALLOUT,
- "migration of %p func %p arg %p in %d to %u deferred",
- c, c->c_func, c->c_arg, to_ticks, cpu);
+ CTR6(KTR_CALLOUT,
+ "migration of %p func %p arg %p in %d.%08x to %u deferred",
+ c, c->c_func, c->c_arg, (int)(to_sbt >> 32),
+ (u_int)(to_sbt & 0xffffffff), cpu);
CC_UNLOCK(cc);
return (cancelled);
}
@@ -846,9 +1003,10 @@ callout_reset_on(struct callout *c, int to_ticks, void (*ftn)(void *),
}
#endif
- callout_cc_add(c, cc, to_ticks, ftn, arg, cpu);
- CTR5(KTR_CALLOUT, "%sscheduled %p func %p arg %p in %d",
- cancelled ? "re" : "", c, c->c_func, c->c_arg, to_ticks);
+ callout_cc_add(c, cc, to_sbt, precision, ftn, arg, cpu, flags);
+ CTR6(KTR_CALLOUT, "%sscheduled %p func %p arg %p in %d.%08x",
+ cancelled ? "re" : "", c, c->c_func, c->c_arg, (int)(to_sbt >> 32),
+ (u_int)(to_sbt & 0xffffffff));
CC_UNLOCK(cc);
return (cancelled);
@@ -876,7 +1034,7 @@ _callout_stop_safe(c, safe)
{
struct callout_cpu *cc, *old_cc;
struct lock_class *class;
- int use_lock, sq_locked;
+ int direct, sq_locked, use_lock;
/*
* Some old subsystems don't hold Giant while running a callout_stop(),
@@ -892,7 +1050,7 @@ _callout_stop_safe(c, safe)
}
} else
use_lock = 0;
-
+ direct = (c->c_flags & CALLOUT_DIRECT) != 0;
sq_locked = 0;
old_cc = NULL;
again:
@@ -906,7 +1064,7 @@ again:
if (sq_locked != 0 && cc != old_cc) {
#ifdef SMP
CC_UNLOCK(cc);
- sleepq_release(&old_cc->cc_waiting);
+ sleepq_release(&old_cc->cc_exec_entity[direct].cc_waiting);
sq_locked = 0;
old_cc = NULL;
goto again;
@@ -927,12 +1085,13 @@ again:
* If it wasn't on the queue and it isn't the current
* callout, then we can't stop it, so just bail.
*/
- if (cc->cc_curr != c) {
+ if (cc->cc_exec_entity[direct].cc_curr != c) {
CTR3(KTR_CALLOUT, "failed to stop %p func %p arg %p",
c, c->c_func, c->c_arg);
CC_UNLOCK(cc);
if (sq_locked)
- sleepq_release(&cc->cc_waiting);
+ sleepq_release(
+ &cc->cc_exec_entity[direct].cc_waiting);
return (0);
}
@@ -943,8 +1102,7 @@ again:
* just wait for the current invocation to
* finish.
*/
- while (cc->cc_curr == c) {
-
+ while (cc->cc_exec_entity[direct].cc_curr == c) {
/*
* Use direct calls to sleepqueue interface
* instead of cv/msleep in order to avoid
@@ -964,7 +1122,8 @@ again:
*/
if (!sq_locked) {
CC_UNLOCK(cc);
- sleepq_lock(&cc->cc_waiting);
+ sleepq_lock(
+ &cc->cc_exec_entity[direct].cc_waiting);
sq_locked = 1;
old_cc = cc;
goto again;
@@ -976,13 +1135,16 @@ again:
* will be packed up, just let softclock()
* take care of it.
*/
- cc->cc_waiting = 1;
+ cc->cc_exec_entity[direct].cc_waiting = true;
DROP_GIANT();
CC_UNLOCK(cc);
- sleepq_add(&cc->cc_waiting,
+ sleepq_add(
+ &cc->cc_exec_entity[direct].cc_waiting,
&cc->cc_lock.lock_object, "codrain",
SLEEPQ_SLEEP, 0);
- sleepq_wait(&cc->cc_waiting, 0);
+ sleepq_wait(
+ &cc->cc_exec_entity[direct].cc_waiting,
+ 0);
sq_locked = 0;
old_cc = NULL;
@@ -990,7 +1152,8 @@ again:
PICKUP_GIANT();
CC_LOCK(cc);
}
- } else if (use_lock && !cc->cc_cancel) {
+ } else if (use_lock &&
+ !cc->cc_exec_entity[direct].cc_cancel) {
/*
* The current callout is waiting for its
* lock which we hold. Cancel the callout
@@ -998,10 +1161,10 @@ again:
* lock, the callout will be skipped in
* softclock().
*/
- cc->cc_cancel = 1;
+ cc->cc_exec_entity[direct].cc_cancel = true;
CTR3(KTR_CALLOUT, "cancelled %p func %p arg %p",
c, c->c_func, c->c_arg);
- KASSERT(!cc_cme_migrating(cc),
+ KASSERT(!cc_cce_migrating(cc, direct),
("callout wrongly scheduled for migration"));
CC_UNLOCK(cc);
KASSERT(!sq_locked, ("sleepqueue chain locked"));
@@ -1020,16 +1183,18 @@ again:
return (0);
}
if (sq_locked)
- sleepq_release(&cc->cc_waiting);
+ sleepq_release(&cc->cc_exec_entity[direct].cc_waiting);
c->c_flags &= ~(CALLOUT_ACTIVE | CALLOUT_PENDING);
CTR3(KTR_CALLOUT, "cancelled %p func %p arg %p",
c, c->c_func, c->c_arg);
- if (cc->cc_next == c)
- cc->cc_next = TAILQ_NEXT(c, c_links.tqe);
- TAILQ_REMOVE(&cc->cc_callwheel[c->c_time & callwheelmask], c,
- c_links.tqe);
+ if ((c->c_flags & CALLOUT_PROCESSED) == 0) {
+ if (cc->cc_exec_next_dir == c)
+ cc->cc_exec_next_dir = LIST_NEXT(c, c_links.le);
+ LIST_REMOVE(c, c_links.le);
+ } else
+ TAILQ_REMOVE(&cc->cc_expireq, c, c_links.tqe);
callout_cc_del(c, cc);
CC_UNLOCK(cc);
@@ -1136,3 +1301,121 @@ adjust_timeout_calltodo(time_change)
return;
}
#endif /* APM_FIXUP_CALLTODO */
+
+static int
+flssbt(sbintime_t sbt)
+{
+
+ sbt += (uint64_t)sbt >> 1;
+ if (sizeof(long) >= sizeof(sbintime_t))
+ return (flsl(sbt));
+ if (sbt >= SBT_1S)
+ return (flsl(((uint64_t)sbt) >> 32) + 32);
+ return (flsl(sbt));
+}
+
+/*
+ * Dump immediate statistic snapshot of the scheduled callouts.
+ */
+static int
+sysctl_kern_callout_stat(SYSCTL_HANDLER_ARGS)
+{
+ struct callout *tmp;
+ struct callout_cpu *cc;
+ struct callout_list *sc;
+ sbintime_t maxpr, maxt, medpr, medt, now, spr, st, t;
+ int ct[64], cpr[64], ccpbk[32];
+ int error, val, i, count, tcum, pcum, maxc, c, medc;
+#ifdef SMP
+ int cpu;
+#endif
+
+ val = 0;
+ error = sysctl_handle_int(oidp, &val, 0, req);
+ if (error != 0 || req->newptr == NULL)
+ return (error);
+ count = maxc = 0;
+ st = spr = maxt = maxpr = 0;
+ bzero(ccpbk, sizeof(ccpbk));
+ bzero(ct, sizeof(ct));
+ bzero(cpr, sizeof(cpr));
+ now = sbinuptime();
+#ifdef SMP
+ CPU_FOREACH(cpu) {
+ cc = CC_CPU(cpu);
+#else
+ cc = CC_CPU(timeout_cpu);
+#endif
+ CC_LOCK(cc);
+ for (i = 0; i < callwheelsize; i++) {
+ sc = &cc->cc_callwheel[i];
+ c = 0;
+ LIST_FOREACH(tmp, sc, c_links.le) {
+ c++;
+ t = tmp->c_time - now;
+ if (t < 0)
+ t = 0;
+ st += t / SBT_1US;
+ spr += tmp->c_precision / SBT_1US;
+ if (t > maxt)
+ maxt = t;
+ if (tmp->c_precision > maxpr)
+ maxpr = tmp->c_precision;
+ ct[flssbt(t)]++;
+ cpr[flssbt(tmp->c_precision)]++;
+ }
+ if (c > maxc)
+ maxc = c;
+ ccpbk[fls(c + c / 2)]++;
+ count += c;
+ }
+ CC_UNLOCK(cc);
+#ifdef SMP
+ }
+#endif
+
+ for (i = 0, tcum = 0; i < 64 && tcum < count / 2; i++)
+ tcum += ct[i];
+ medt = (i >= 2) ? (((sbintime_t)1) << (i - 2)) : 0;
+ for (i = 0, pcum = 0; i < 64 && pcum < count / 2; i++)
+ pcum += cpr[i];
+ medpr = (i >= 2) ? (((sbintime_t)1) << (i - 2)) : 0;
+ for (i = 0, c = 0; i < 32 && c < count / 2; i++)
+ c += ccpbk[i];
+ medc = (i >= 2) ? (1 << (i - 2)) : 0;
+
+ printf("Scheduled callouts statistic snapshot:\n");
+ printf(" Callouts: %6d Buckets: %6d*%-3d Bucket size: 0.%06ds\n",
+ count, callwheelsize, mp_ncpus, 1000000 >> CC_HASH_SHIFT);
+ printf(" C/Bk: med %5d avg %6d.%06jd max %6d\n",
+ medc,
+ count / callwheelsize / mp_ncpus,
+ (uint64_t)count * 1000000 / callwheelsize / mp_ncpus % 1000000,
+ maxc);
+ printf(" Time: med %5jd.%06jds avg %6jd.%06jds max %6jd.%06jds\n",
+ medt / SBT_1S, (medt & 0xffffffff) * 1000000 >> 32,
+ (st / count) / 1000000, (st / count) % 1000000,
+ maxt / SBT_1S, (maxt & 0xffffffff) * 1000000 >> 32);
+ printf(" Prec: med %5jd.%06jds avg %6jd.%06jds max %6jd.%06jds\n",
+ medpr / SBT_1S, (medpr & 0xffffffff) * 1000000 >> 32,
+ (spr / count) / 1000000, (spr / count) % 1000000,
+ maxpr / SBT_1S, (maxpr & 0xffffffff) * 1000000 >> 32);
+ printf(" Distribution: \tbuckets\t time\t tcum\t"
+ " prec\t pcum\n");
+ for (i = 0, tcum = pcum = 0; i < 64; i++) {
+ if (ct[i] == 0 && cpr[i] == 0)
+ continue;
+ t = (i != 0) ? (((sbintime_t)1) << (i - 1)) : 0;
+ tcum += ct[i];
+ pcum += cpr[i];
+ printf(" %10jd.%06jds\t 2**%d\t%7d\t%7d\t%7d\t%7d\n",
+ t / SBT_1S, (t & 0xffffffff) * 1000000 >> 32,
+ i - 1 - (32 - CC_HASH_SHIFT),
+ ct[i], tcum, cpr[i], pcum);
+ }
+ return (error);
+}
+SYSCTL_PROC(_kern, OID_AUTO, callout_stat,
+ CTLTYPE_INT | CTLFLAG_RW | CTLFLAG_MPSAFE,
+ 0, 0, sysctl_kern_callout_stat, "I",
+ "Dump immediate statistic snapshot of the scheduled callouts");
diff --git a/sys/kern/subr_log.c b/sys/kern/subr_log.c
index 8981358..1e61274 100644
--- a/sys/kern/subr_log.c
+++ b/sys/kern/subr_log.c
@@ -117,8 +117,8 @@ logopen(struct cdev *dev, int flags, int mode, struct thread *td)
return (EBUSY);
}
log_open = 1;
- callout_reset(&logsoftc.sc_callout, hz / log_wakeups_per_second,
- logtimeout, NULL);
+ callout_reset_sbt(&logsoftc.sc_callout,
+ SBT_1S / log_wakeups_per_second, 0, logtimeout, NULL, C_PREL(1));
mtx_unlock(&msgbuf_lock);
fsetown(td->td_proc->p_pid, &logsoftc.sc_sigio); /* signal process only */
@@ -233,22 +233,21 @@ logtimeout(void *arg)
if (!log_open)
return;
- if (log_wakeups_per_second < 1) {
- printf("syslog wakeup is less than one. Adjusting to 1.\n");
- log_wakeups_per_second = 1;
- }
- if (msgbuftrigger == 0) {
- callout_schedule(&logsoftc.sc_callout,
- hz / log_wakeups_per_second);
- return;
- }
+ if (msgbuftrigger == 0)
+ goto done;
msgbuftrigger = 0;
selwakeuppri(&logsoftc.sc_selp, LOG_RDPRI);
KNOTE_LOCKED(&logsoftc.sc_selp.si_note, 0);
if ((logsoftc.sc_state & LOG_ASYNC) && logsoftc.sc_sigio != NULL)
pgsigio(&logsoftc.sc_sigio, SIGIO, 0);
cv_broadcastpri(&log_wakeup, LOG_RDPRI);
- callout_schedule(&logsoftc.sc_callout, hz / log_wakeups_per_second);
+done:
+ if (log_wakeups_per_second < 1) {
+ printf("syslog wakeup is less than one. Adjusting to 1.\n");
+ log_wakeups_per_second = 1;
+ }
+ callout_reset_sbt(&logsoftc.sc_callout,
+ SBT_1S / log_wakeups_per_second, 0, logtimeout, NULL, C_PREL(1));
}
/*ARGSUSED*/
diff --git a/sys/kern/subr_param.c b/sys/kern/subr_param.c
index f36c769..0a3580b 100644
--- a/sys/kern/subr_param.c
+++ b/sys/kern/subr_param.c
@@ -81,8 +81,10 @@ __FBSDID("$FreeBSD$");
static int sysctl_kern_vm_guest(SYSCTL_HANDLER_ARGS);
-int hz;
-int tick;
+int hz; /* system clock's frequency */
+int tick; /* usec per tick (1000000 / hz) */
+struct bintime tick_bt; /* bintime per tick (1s / hz) */
+sbintime_t tick_sbt;
int maxusers; /* base tunable */
int maxproc; /* maximum # of processes */
int maxprocperuid; /* max # of procs per user */
@@ -221,6 +223,8 @@ init_param1(void)
if (hz == -1)
hz = vm_guest > VM_GUEST_NO ? HZ_VM : HZ;
tick = 1000000 / hz;
+ tick_sbt = SBT_1S / hz;
+ tick_bt = sbttobt(tick_sbt);
#ifdef VM_SWZONE_SIZE_MAX
maxswzone = VM_SWZONE_SIZE_MAX;
diff --git a/sys/kern/subr_sleepqueue.c b/sys/kern/subr_sleepqueue.c
index f187544..3e1c0c3 100644
--- a/sys/kern/subr_sleepqueue.c
+++ b/sys/kern/subr_sleepqueue.c
@@ -361,7 +361,8 @@ sleepq_add(void *wchan, struct lock_object *lock, const char *wmesg, int flags,
* sleep queue after timo ticks if the thread has not already been awakened.
*/
void
-sleepq_set_timeout(void *wchan, int timo)
+sleepq_set_timeout_sbt(void *wchan, sbintime_t sbt, sbintime_t pr,
+ int flags)
{
struct sleepqueue_chain *sc;
struct thread *td;
@@ -372,7 +373,8 @@ sleepq_set_timeout(void *wchan, int timo)
MPASS(TD_ON_SLEEPQ(td));
MPASS(td->td_sleepqueue == NULL);
MPASS(wchan != NULL);
- callout_reset_curcpu(&td->td_slpcallout, timo, sleepq_timeout, td);
+ callout_reset_sbt_on(&td->td_slpcallout, sbt, pr,
+ sleepq_timeout, td, PCPU_GET(cpuid), flags | C_DIRECT_EXEC);
}
/*
diff --git a/sys/kern/sys_generic.c b/sys/kern/sys_generic.c
index 39f33f3..2d149b5 100644
--- a/sys/kern/sys_generic.c
+++ b/sys/kern/sys_generic.c
@@ -103,7 +103,7 @@ static int dofilewrite(struct thread *, int, struct file *, struct uio *,
off_t, int);
static void doselwakeup(struct selinfo *, int);
static void seltdinit(struct thread *);
-static int seltdwait(struct thread *, int);
+static int seltdwait(struct thread *, sbintime_t, sbintime_t);
static void seltdclear(struct thread *);
/*
@@ -950,9 +950,10 @@ kern_select(struct thread *td, int nd, fd_set *fd_in, fd_set *fd_ou,
*/
fd_mask s_selbits[howmany(2048, NFDBITS)];
fd_mask *ibits[3], *obits[3], *selbits, *sbp;
- struct timeval atv, rtv, ttv;
- int error, lf, ndu, timo;
+ struct timeval rtv;
+ sbintime_t asbt, precision, rsbt;
u_int nbufbytes, ncpbytes, ncpubytes, nfdbits;
+ int error, lf, ndu;
if (nd < 0)
return (EINVAL);
@@ -1042,35 +1043,36 @@ kern_select(struct thread *td, int nd, fd_set *fd_in, fd_set *fd_ou,
if (nbufbytes != 0)
bzero(selbits, nbufbytes / 2);
+ precision = 0;
if (tvp != NULL) {
- atv = *tvp;
- if (itimerfix(&atv)) {
+ rtv = *tvp;
+ if (rtv.tv_sec < 0 || rtv.tv_usec < 0 ||
+ rtv.tv_usec >= 1000000) {
error = EINVAL;
goto done;
}
- getmicrouptime(&rtv);
- timevaladd(&atv, &rtv);
- } else {
- atv.tv_sec = 0;
- atv.tv_usec = 0;
- }
- timo = 0;
+ if (rtv.tv_sec == 0 && rtv.tv_usec == 0)
+ asbt = 0;
+ else if (rtv.tv_sec < INT32_MAX) {
+ rsbt = tvtosbt(rtv);
+ precision = rsbt;
+ precision >>= tc_precexp;
+ if (TIMESEL(&asbt, rsbt))
+ asbt += tc_tick_sbt;
+ asbt += rsbt;
+ if (asbt < rsbt)
+ asbt = -1;
+ } else
+ asbt = -1;
+ } else
+ asbt = -1;
seltdinit(td);
/* Iterate until the timeout expires or descriptors become ready. */
for (;;) {
error = selscan(td, ibits, obits, nd);
if (error || td->td_retval[0] != 0)
break;
- if (atv.tv_sec || atv.tv_usec) {
- getmicrouptime(&rtv);
- if (timevalcmp(&rtv, &atv, >=))
- break;
- ttv = atv;
- timevalsub(&ttv, &rtv);
- timo = ttv.tv_sec > 24 * 60 * 60 ?
- 24 * 60 * 60 * hz : tvtohz(&ttv);
- }
- error = seltdwait(td, timo);
+ error = seltdwait(td, asbt, precision);
if (error)
break;
error = selrescan(td, ibits, obits);
@@ -1278,9 +1280,9 @@ sys_poll(td, uap)
{
struct pollfd *bits;
struct pollfd smallbits[32];
- struct timeval atv, rtv, ttv;
- int error, timo;
+ sbintime_t asbt, precision, rsbt;
u_int nfds;
+ int error;
size_t ni;
nfds = uap->nfds;
@@ -1294,36 +1296,31 @@ sys_poll(td, uap)
error = copyin(uap->fds, bits, ni);
if (error)
goto done;
+ precision = 0;
if (uap->timeout != INFTIM) {
- atv.tv_sec = uap->timeout / 1000;
- atv.tv_usec = (uap->timeout % 1000) * 1000;
- if (itimerfix(&atv)) {
+ if (uap->timeout < 0) {
error = EINVAL;
goto done;
}
- getmicrouptime(&rtv);
- timevaladd(&atv, &rtv);
- } else {
- atv.tv_sec = 0;
- atv.tv_usec = 0;
- }
- timo = 0;
+ if (uap->timeout == 0)
+ asbt = 0;
+ else {
+ rsbt = SBT_1MS * uap->timeout;
+ precision = rsbt;
+ precision >>= tc_precexp;
+ if (TIMESEL(&asbt, rsbt))
+ asbt += tc_tick_sbt;
+ asbt += rsbt;
+ }
+ } else
+ asbt = -1;
seltdinit(td);
/* Iterate until the timeout expires or descriptors become ready. */
for (;;) {
error = pollscan(td, bits, nfds);
if (error || td->td_retval[0] != 0)
break;
- if (atv.tv_sec || atv.tv_usec) {
- getmicrouptime(&rtv);
- if (timevalcmp(&rtv, &atv, >=))
- break;
- ttv = atv;
- timevalsub(&ttv, &rtv);
- timo = ttv.tv_sec > 24 * 60 * 60 ?
- 24 * 60 * 60 * hz : tvtohz(&ttv);
- }
- error = seltdwait(td, timo);
+ error = seltdwait(td, asbt, precision);
if (error)
break;
error = pollrescan(td);
@@ -1667,7 +1664,7 @@ out:
}
static int
-seltdwait(struct thread *td, int timo)
+seltdwait(struct thread *td, sbintime_t sbt, sbintime_t precision)
{
struct seltd *stp;
int error;
@@ -1686,8 +1683,11 @@ seltdwait(struct thread *td, int timo)
mtx_unlock(&stp->st_mtx);
return (0);
}
- if (timo > 0)
- error = cv_timedwait_sig(&stp->st_wait, &stp->st_mtx, timo);
+ if (sbt == 0)
+ error = EWOULDBLOCK;
+ else if (sbt != -1)
+ error = cv_timedwait_sig_sbt(&stp->st_wait, &stp->st_mtx,
+ sbt, precision, C_ABSOLUTE);
else
error = cv_wait_sig(&stp->st_wait, &stp->st_mtx);
mtx_unlock(&stp->st_mtx);
diff --git a/sys/kern/syscalls.c b/sys/kern/syscalls.c
index e066014..3b6a111 100644
--- a/sys/kern/syscalls.c
+++ b/sys/kern/syscalls.c
@@ -3,7 +3,7 @@
*
* DO NOT EDIT-- this file is automatically generated.
* $FreeBSD$
- * created from FreeBSD: head/sys/kern/syscalls.master 247602 2013-03-02 00:53:12Z pjd
+ * created from FreeBSD: head/sys/kern/syscalls.master 247667 2013-03-02 21:11:30Z pjd
*/
const char *syscallnames[] = {
@@ -545,4 +545,6 @@ const char *syscallnames[] = {
"cap_ioctls_get", /* 535 = cap_ioctls_get */
"cap_fcntls_limit", /* 536 = cap_fcntls_limit */
"cap_fcntls_get", /* 537 = cap_fcntls_get */
+ "bindat", /* 538 = bindat */
+ "connectat", /* 539 = connectat */
};
diff --git a/sys/kern/syscalls.master b/sys/kern/syscalls.master
index 1a89010..9c22f2b 100644
--- a/sys/kern/syscalls.master
+++ b/sys/kern/syscalls.master
@@ -965,5 +965,9 @@
uint32_t fcntlrights); }
537 AUE_CAP_FCNTLS_GET STD { int cap_fcntls_get(int fd, \
uint32_t *fcntlrightsp); }
+538 AUE_BINDAT STD { int bindat(int fd, int s, caddr_t name, \
+ int namelen); }
+539 AUE_CONNECTAT STD { int connectat(int fd, int s, caddr_t name, \
+ int namelen); }
; Please copy any additions and changes to the following compatability tables:
; sys/compat/freebsd32/syscalls.master
diff --git a/sys/kern/systrace_args.c b/sys/kern/systrace_args.c
index d811da2..0ff91ef 100644
--- a/sys/kern/systrace_args.c
+++ b/sys/kern/systrace_args.c
@@ -3328,6 +3328,26 @@ systrace_args(int sysnum, void *params, uint64_t *uarg, int *n_args)
*n_args = 2;
break;
}
+ /* bindat */
+ case 538: {
+ struct bindat_args *p = params;
+ iarg[0] = p->fd; /* int */
+ iarg[1] = p->s; /* int */
+ uarg[2] = (intptr_t) p->name; /* caddr_t */
+ iarg[3] = p->namelen; /* int */
+ *n_args = 4;
+ break;
+ }
+ /* connectat */
+ case 539: {
+ struct connectat_args *p = params;
+ iarg[0] = p->fd; /* int */
+ iarg[1] = p->s; /* int */
+ uarg[2] = (intptr_t) p->name; /* caddr_t */
+ iarg[3] = p->namelen; /* int */
+ *n_args = 4;
+ break;
+ }
default:
*n_args = 0;
break;
@@ -8858,6 +8878,44 @@ systrace_entry_setargdesc(int sysnum, int ndx, char *desc, size_t descsz)
break;
};
break;
+ /* bindat */
+ case 538:
+ switch(ndx) {
+ case 0:
+ p = "int";
+ break;
+ case 1:
+ p = "int";
+ break;
+ case 2:
+ p = "caddr_t";
+ break;
+ case 3:
+ p = "int";
+ break;
+ default:
+ break;
+ };
+ break;
+ /* connectat */
+ case 539:
+ switch(ndx) {
+ case 0:
+ p = "int";
+ break;
+ case 1:
+ p = "int";
+ break;
+ case 2:
+ p = "caddr_t";
+ break;
+ case 3:
+ p = "int";
+ break;
+ default:
+ break;
+ };
+ break;
default:
break;
};
@@ -10776,6 +10834,16 @@ systrace_return_setargdesc(int sysnum, int ndx, char *desc, size_t descsz)
if (ndx == 0 || ndx == 1)
p = "int";
break;
+ /* bindat */
+ case 538:
+ if (ndx == 0 || ndx == 1)
+ p = "int";
+ break;
+ /* connectat */
+ case 539:
+ if (ndx == 0 || ndx == 1)
+ p = "int";
+ break;
default:
break;
};
diff --git a/sys/kern/uipc_domain.c b/sys/kern/uipc_domain.c
index c146232..709cc0e 100644
--- a/sys/kern/uipc_domain.c
+++ b/sys/kern/uipc_domain.c
@@ -136,8 +136,10 @@ protosw_init(struct protosw *pr)
#define DEFAULT(foo, bar) if ((foo) == NULL) (foo) = (bar)
DEFAULT(pu->pru_accept, pru_accept_notsupp);
DEFAULT(pu->pru_bind, pru_bind_notsupp);
+ DEFAULT(pu->pru_bindat, pru_bindat_notsupp);
DEFAULT(pu->pru_connect, pru_connect_notsupp);
DEFAULT(pu->pru_connect2, pru_connect2_notsupp);
+ DEFAULT(pu->pru_connectat, pru_connectat_notsupp);
DEFAULT(pu->pru_control, pru_control_notsupp);
DEFAULT(pu->pru_disconnect, pru_disconnect_notsupp);
DEFAULT(pu->pru_listen, pru_listen_notsupp);
diff --git a/sys/kern/uipc_socket.c b/sys/kern/uipc_socket.c
index de8ae5a..7fcac1c 100644
--- a/sys/kern/uipc_socket.c
+++ b/sys/kern/uipc_socket.c
@@ -615,7 +615,18 @@ sobind(struct socket *so, struct sockaddr *nam, struct thread *td)
CURVNET_SET(so->so_vnet);
error = (*so->so_proto->pr_usrreqs->pru_bind)(so, nam, td);
CURVNET_RESTORE();
- return error;
+ return (error);
+}
+
+int
+sobindat(int fd, struct socket *so, struct sockaddr *nam, struct thread *td)
+{
+ int error;
+
+ CURVNET_SET(so->so_vnet);
+ error = (*so->so_proto->pr_usrreqs->pru_bindat)(fd, so, nam, td);
+ CURVNET_RESTORE();
+ return (error);
}
/*
@@ -638,7 +649,7 @@ solisten(struct socket *so, int backlog, struct thread *td)
CURVNET_SET(so->so_vnet);
error = (*so->so_proto->pr_usrreqs->pru_listen)(so, backlog, td);
CURVNET_RESTORE();
- return error;
+ return (error);
}
int
@@ -896,6 +907,13 @@ soaccept(struct socket *so, struct sockaddr **nam)
int
soconnect(struct socket *so, struct sockaddr *nam, struct thread *td)
{
+
+ return (soconnectat(AT_FDCWD, so, nam, td));
+}
+
+int
+soconnectat(int fd, struct socket *so, struct sockaddr *nam, struct thread *td)
+{
int error;
if (so->so_options & SO_ACCEPTCONN)
@@ -917,7 +935,13 @@ soconnect(struct socket *so, struct sockaddr *nam, struct thread *td)
* biting us.
*/
so->so_error = 0;
- error = (*so->so_proto->pr_usrreqs->pru_connect)(so, nam, td);
+ if (fd == AT_FDCWD) {
+ error = (*so->so_proto->pr_usrreqs->pru_connect)(so,
+ nam, td);
+ } else {
+ error = (*so->so_proto->pr_usrreqs->pru_connectat)(fd,
+ so, nam, td);
+ }
}
CURVNET_RESTORE();
@@ -3141,6 +3165,14 @@ pru_bind_notsupp(struct socket *so, struct sockaddr *nam, struct thread *td)
}
int
+pru_bindat_notsupp(int fd, struct socket *so, struct sockaddr *nam,
+ struct thread *td)
+{
+
+ return EOPNOTSUPP;
+}
+
+int
pru_connect_notsupp(struct socket *so, struct sockaddr *nam, struct thread *td)
{
@@ -3148,6 +3180,14 @@ pru_connect_notsupp(struct socket *so, struct sockaddr *nam, struct thread *td)
}
int
+pru_connectat_notsupp(int fd, struct socket *so, struct sockaddr *nam,
+ struct thread *td)
+{
+
+ return EOPNOTSUPP;
+}
+
+int
pru_connect2_notsupp(struct socket *so1, struct socket *so2)
{
diff --git a/sys/kern/uipc_syscalls.c b/sys/kern/uipc_syscalls.c
index eca171c..894cffc 100644
--- a/sys/kern/uipc_syscalls.c
+++ b/sys/kern/uipc_syscalls.c
@@ -202,26 +202,23 @@ sys_bind(td, uap)
struct sockaddr *sa;
int error;
- if ((error = getsockaddr(&sa, uap->name, uap->namelen)) != 0)
- return (error);
-
- error = kern_bind(td, uap->s, sa);
- free(sa, M_SONAME);
+ error = getsockaddr(&sa, uap->name, uap->namelen);
+ if (error == 0) {
+ error = kern_bind(td, uap->s, sa);
+ free(sa, M_SONAME);
+ }
return (error);
}
-int
-kern_bind(td, fd, sa)
- struct thread *td;
- int fd;
- struct sockaddr *sa;
+static int
+kern_bindat(struct thread *td, int dirfd, int fd, struct sockaddr *sa)
{
struct socket *so;
struct file *fp;
int error;
AUDIT_ARG_FD(fd);
- AUDIT_ARG_SOCKADDR(td, sa);
+ AUDIT_ARG_SOCKADDR(td, dirfd, sa);
error = getsock_cap(td->td_proc->p_fd, fd, CAP_BIND, &fp, NULL);
if (error)
return (error);
@@ -232,13 +229,48 @@ kern_bind(td, fd, sa)
#endif
#ifdef MAC
error = mac_socket_check_bind(td->td_ucred, so, sa);
- if (error == 0)
+ if (error == 0) {
+#endif
+ if (dirfd == AT_FDCWD)
+ error = sobind(so, sa, td);
+ else
+ error = sobindat(dirfd, so, sa, td);
+#ifdef MAC
+ }
#endif
- error = sobind(so, sa, td);
fdrop(fp, td);
return (error);
}
+int
+kern_bind(struct thread *td, int fd, struct sockaddr *sa)
+{
+
+ return (kern_bindat(td, AT_FDCWD, fd, sa));
+}
+
+/* ARGSUSED */
+int
+sys_bindat(td, uap)
+ struct thread *td;
+ struct bindat_args /* {
+ int fd;
+ int s;
+ caddr_t name;
+ int namelen;
+ } */ *uap;
+{
+ struct sockaddr *sa;
+ int error;
+
+ error = getsockaddr(&sa, uap->name, uap->namelen);
+ if (error == 0) {
+ error = kern_bindat(td, uap->fd, uap->s, sa);
+ free(sa, M_SONAME);
+ }
+ return (error);
+}
+
/* ARGSUSED */
int
sys_listen(td, uap)
@@ -436,7 +468,7 @@ kern_accept(struct thread *td, int s, struct sockaddr **name,
*namelen = 0;
goto done;
}
- AUDIT_ARG_SOCKADDR(td, sa);
+ AUDIT_ARG_SOCKADDR(td, AT_FDCWD, sa);
if (name) {
/* check sa_len before it is destroyed */
if (*namelen > sa->sa_len)
@@ -511,20 +543,15 @@ sys_connect(td, uap)
int error;
error = getsockaddr(&sa, uap->name, uap->namelen);
- if (error)
- return (error);
-
- error = kern_connect(td, uap->s, sa);
- free(sa, M_SONAME);
+ if (error == 0) {
+ error = kern_connect(td, uap->s, sa);
+ free(sa, M_SONAME);
+ }
return (error);
}
-
-int
-kern_connect(td, fd, sa)
- struct thread *td;
- int fd;
- struct sockaddr *sa;
+static int
+kern_connectat(struct thread *td, int dirfd, int fd, struct sockaddr *sa)
{
struct socket *so;
struct file *fp;
@@ -532,7 +559,7 @@ kern_connect(td, fd, sa)
int interrupted = 0;
AUDIT_ARG_FD(fd);
- AUDIT_ARG_SOCKADDR(td, sa);
+ AUDIT_ARG_SOCKADDR(td, dirfd, sa);
error = getsock_cap(td->td_proc->p_fd, fd, CAP_CONNECT, &fp, NULL);
if (error)
return (error);
@@ -550,7 +577,10 @@ kern_connect(td, fd, sa)
if (error)
goto bad;
#endif
- error = soconnect(so, sa, td);
+ if (dirfd == AT_FDCWD)
+ error = soconnect(so, sa, td);
+ else
+ error = soconnectat(dirfd, so, sa, td);
if (error)
goto bad;
if ((so->so_state & SS_NBIO) && (so->so_state & SS_ISCONNECTING)) {
@@ -583,6 +613,35 @@ done1:
}
int
+kern_connect(struct thread *td, int fd, struct sockaddr *sa)
+{
+
+ return (kern_connectat(td, AT_FDCWD, fd, sa));
+}
+
+/* ARGSUSED */
+int
+sys_connectat(td, uap)
+ struct thread *td;
+ struct connectat_args /* {
+ int fd;
+ int s;
+ caddr_t name;
+ int namelen;
+ } */ *uap;
+{
+ struct sockaddr *sa;
+ int error;
+
+ error = getsockaddr(&sa, uap->name, uap->namelen);
+ if (error == 0) {
+ error = kern_connectat(td, uap->fd, uap->s, sa);
+ free(sa, M_SONAME);
+ }
+ return (error);
+}
+
+int
kern_socketpair(struct thread *td, int domain, int type, int protocol,
int *rsv)
{
@@ -750,7 +809,7 @@ kern_sendit(td, s, mp, flags, control, segflg)
AUDIT_ARG_FD(s);
rights = CAP_SEND;
if (mp->msg_name != NULL) {
- AUDIT_ARG_SOCKADDR(td, mp->msg_name);
+ AUDIT_ARG_SOCKADDR(td, AT_FDCWD, mp->msg_name);
rights |= CAP_CONNECT;
}
error = getsock_cap(td->td_proc->p_fd, s, rights, &fp, NULL);
@@ -998,7 +1057,7 @@ kern_recvit(td, s, mp, fromseg, controlp)
error = 0;
}
if (fromsa != NULL)
- AUDIT_ARG_SOCKADDR(td, fromsa);
+ AUDIT_ARG_SOCKADDR(td, AT_FDCWD, fromsa);
#ifdef KTRACE
if (ktruio != NULL) {
ktruio->uio_resid = len - auio.uio_resid;
diff --git a/sys/kern/uipc_usrreq.c b/sys/kern/uipc_usrreq.c
index dcfd009..dcd8c4e 100644
--- a/sys/kern/uipc_usrreq.c
+++ b/sys/kern/uipc_usrreq.c
@@ -62,6 +62,7 @@ __FBSDID("$FreeBSD$");
#include "opt_ddb.h"
#include <sys/param.h>
+#include <sys/capability.h>
#include <sys/domain.h>
#include <sys/fcntl.h>
#include <sys/malloc.h> /* XXX must be before <sys/file.h> */
@@ -101,6 +102,8 @@ __FBSDID("$FreeBSD$");
#include <vm/uma.h>
+MALLOC_DECLARE(M_FILECAPS);
+
/*
* Locking key:
* (l) Locked using list lock
@@ -271,6 +274,8 @@ static int uipc_connect2(struct socket *, struct socket *);
static int uipc_ctloutput(struct socket *, struct sockopt *);
static int unp_connect(struct socket *, struct sockaddr *,
struct thread *);
+static int unp_connectat(int, struct socket *, struct sockaddr *,
+ struct thread *);
static int unp_connect2(struct socket *so, struct socket *so2, int);
static void unp_disconnect(struct unpcb *unp, struct unpcb *unp2);
static void unp_dispose(struct mbuf *);
@@ -279,7 +284,7 @@ static void unp_drop(struct unpcb *, int);
static void unp_gc(__unused void *, int);
static void unp_scan(struct mbuf *, void (*)(struct file *));
static void unp_discard(struct file *);
-static void unp_freerights(struct filedescent *, int);
+static void unp_freerights(struct filedescent **, int);
static void unp_init(void);
static int unp_internalize(struct mbuf **, struct thread *);
static void unp_internalize_fp(struct file *);
@@ -450,7 +455,7 @@ uipc_attach(struct socket *so, int proto, struct thread *td)
}
static int
-uipc_bind(struct socket *so, struct sockaddr *nam, struct thread *td)
+uipc_bindat(int fd, struct socket *so, struct sockaddr *nam, struct thread *td)
{
struct sockaddr_un *soun = (struct sockaddr_un *)nam;
struct vattr vattr;
@@ -496,8 +501,8 @@ uipc_bind(struct socket *so, struct sockaddr *nam, struct thread *td)
buf[namelen] = 0;
restart:
- NDINIT(&nd, CREATE, NOFOLLOW | LOCKPARENT | SAVENAME,
- UIO_SYSSPACE, buf, td);
+ NDINIT_ATRIGHTS(&nd, CREATE, NOFOLLOW | LOCKPARENT | SAVENAME,
+ UIO_SYSSPACE, buf, fd, CAP_BINDAT, td);
/* SHOULD BE ABLE TO ADOPT EXISTING AND wakeup() ALA FIFO's */
error = namei(&nd);
if (error)
@@ -560,6 +565,13 @@ error:
}
static int
+uipc_bind(struct socket *so, struct sockaddr *nam, struct thread *td)
+{
+
+ return (uipc_bindat(AT_FDCWD, so, nam, td));
+}
+
+static int
uipc_connect(struct socket *so, struct sockaddr *nam, struct thread *td)
{
int error;
@@ -571,6 +583,19 @@ uipc_connect(struct socket *so, struct sockaddr *nam, struct thread *td)
return (error);
}
+static int
+uipc_connectat(int fd, struct socket *so, struct sockaddr *nam,
+ struct thread *td)
+{
+ int error;
+
+ KASSERT(td == curthread, ("uipc_connectat: td != curthread"));
+ UNP_LINK_WLOCK();
+ error = unp_connectat(fd, so, nam, td);
+ UNP_LINK_WUNLOCK();
+ return (error);
+}
+
static void
uipc_close(struct socket *so)
{
@@ -1081,7 +1106,9 @@ static struct pr_usrreqs uipc_usrreqs_dgram = {
.pru_accept = uipc_accept,
.pru_attach = uipc_attach,
.pru_bind = uipc_bind,
+ .pru_bindat = uipc_bindat,
.pru_connect = uipc_connect,
+ .pru_connectat = uipc_connectat,
.pru_connect2 = uipc_connect2,
.pru_detach = uipc_detach,
.pru_disconnect = uipc_disconnect,
@@ -1101,7 +1128,9 @@ static struct pr_usrreqs uipc_usrreqs_seqpacket = {
.pru_accept = uipc_accept,
.pru_attach = uipc_attach,
.pru_bind = uipc_bind,
+ .pru_bindat = uipc_bindat,
.pru_connect = uipc_connect,
+ .pru_connectat = uipc_connectat,
.pru_connect2 = uipc_connect2,
.pru_detach = uipc_detach,
.pru_disconnect = uipc_disconnect,
@@ -1121,7 +1150,9 @@ static struct pr_usrreqs uipc_usrreqs_stream = {
.pru_accept = uipc_accept,
.pru_attach = uipc_attach,
.pru_bind = uipc_bind,
+ .pru_bindat = uipc_bindat,
.pru_connect = uipc_connect,
+ .pru_connectat = uipc_connectat,
.pru_connect2 = uipc_connect2,
.pru_detach = uipc_detach,
.pru_disconnect = uipc_disconnect,
@@ -1233,6 +1264,14 @@ uipc_ctloutput(struct socket *so, struct sockopt *sopt)
static int
unp_connect(struct socket *so, struct sockaddr *nam, struct thread *td)
{
+
+ return (unp_connectat(AT_FDCWD, so, nam, td));
+}
+
+static int
+unp_connectat(int fd, struct socket *so, struct sockaddr *nam,
+ struct thread *td)
+{
struct sockaddr_un *soun = (struct sockaddr_un *)nam;
struct vnode *vp;
struct socket *so2, *so3;
@@ -1265,8 +1304,8 @@ unp_connect(struct socket *so, struct sockaddr *nam, struct thread *td)
UNP_PCB_UNLOCK(unp);
sa = malloc(sizeof(struct sockaddr_un), M_SONAME, M_WAITOK);
- NDINIT(&nd, LOOKUP, FOLLOW | LOCKSHARED | LOCKLEAF,
- UIO_SYSSPACE, buf, td);
+ NDINIT_ATRIGHTS(&nd, LOOKUP, FOLLOW | LOCKSHARED | LOCKLEAF,
+ UIO_SYSSPACE, buf, fd, CAP_CONNECTAT, td);
error = namei(&nd);
if (error)
vp = NULL;
@@ -1642,16 +1681,17 @@ unp_drop(struct unpcb *unp, int errno)
}
static void
-unp_freerights(struct filedescent *fde, int fdcount)
+unp_freerights(struct filedescent **fdep, int fdcount)
{
struct file *fp;
int i;
- for (i = 0; i < fdcount; i++, fde++) {
- fp = fde->fde_file;
- bzero(fde, sizeof(*fde));
+ for (i = 0; i < fdcount; i++) {
+ fp = fdep[i]->fde_file;
+ filecaps_free(&fdep[i]->fde_caps);
unp_discard(fp);
}
+ free(fdep[0], M_FILECAPS);
}
static int
@@ -1662,7 +1702,7 @@ unp_externalize(struct mbuf *control, struct mbuf **controlp)
int i;
int *fdp;
struct filedesc *fdesc = td->td_proc->p_fd;
- struct filedescent *fde, *fdep;
+ struct filedescent *fde, **fdep;
void *data;
socklen_t clen = control->m_len, datalen;
int error, newfds;
@@ -1718,16 +1758,18 @@ unp_externalize(struct mbuf *control, struct mbuf **controlp)
fdp = (int *)
CMSG_DATA(mtod(*controlp, struct cmsghdr *));
- for (i = 0; i < newfds; i++, fdep++, fdp++) {
+ for (i = 0; i < newfds; i++, fdp++) {
if (fdalloc(td, 0, &f))
panic("unp_externalize fdalloc failed");
fde = &fdesc->fd_ofiles[f];
- fde->fde_file = fdep->fde_file;
- filecaps_copy(&fdep->fde_caps, &fde->fde_caps);
+ fde->fde_file = fdep[0]->fde_file;
+ filecaps_move(&fdep[0]->fde_caps,
+ &fde->fde_caps);
unp_externalize_fp(fde->fde_file);
*fdp = f;
}
FILEDESC_XUNLOCK(fdesc);
+ free(fdep[0], M_FILECAPS);
} else {
/* We can just copy anything else across. */
if (error || controlp == NULL)
@@ -1802,7 +1844,7 @@ unp_internalize(struct mbuf **controlp, struct thread *td)
struct bintime *bt;
struct cmsghdr *cm = mtod(control, struct cmsghdr *);
struct cmsgcred *cmcred;
- struct filedescent *fde, *fdep;
+ struct filedescent *fde, **fdep, *fdev;
struct file *fp;
struct timeval *tv;
int i, fd, *fdp;
@@ -1876,7 +1918,7 @@ unp_internalize(struct mbuf **controlp, struct thread *td)
* Now replace the integer FDs with pointers to the
* file structure and capability rights.
*/
- newlen = oldfds * sizeof(*fdep);
+ newlen = oldfds * sizeof(fdep[0]);
*controlp = sbcreatecontrol(NULL, newlen,
SCM_RIGHTS, SOL_SOCKET);
if (*controlp == NULL) {
@@ -1885,13 +1927,17 @@ unp_internalize(struct mbuf **controlp, struct thread *td)
goto out;
}
fdp = data;
- fdep = (struct filedescent *)
+ fdep = (struct filedescent **)
CMSG_DATA(mtod(*controlp, struct cmsghdr *));
- for (i = 0; i < oldfds; i++, fdep++, fdp++) {
+ fdev = malloc(sizeof(*fdev) * oldfds, M_FILECAPS,
+ M_WAITOK);
+ for (i = 0; i < oldfds; i++, fdev++, fdp++) {
fde = &fdesc->fd_ofiles[*fdp];
- fdep->fde_file = fde->fde_file;
- filecaps_copy(&fde->fde_caps, &fdep->fde_caps);
- unp_internalize_fp(fdep->fde_file);
+ fdep[i] = fdev;
+ fdep[i]->fde_file = fde->fde_file;
+ filecaps_copy(&fde->fde_caps,
+ &fdep[i]->fde_caps);
+ unp_internalize_fp(fdep[i]->fde_file);
}
FILEDESC_SUNLOCK(fdesc);
break;
@@ -2253,7 +2299,7 @@ static void
unp_scan(struct mbuf *m0, void (*op)(struct file *))
{
struct mbuf *m;
- struct filedescent *fdep;
+ struct filedescent **fdep;
struct cmsghdr *cm;
void *data;
int i;
@@ -2280,8 +2326,8 @@ unp_scan(struct mbuf *m0, void (*op)(struct file *))
cm->cmsg_type == SCM_RIGHTS) {
qfds = datalen / sizeof(*fdep);
fdep = data;
- for (i = 0; i < qfds; i++, fdep++)
- (*op)(fdep->fde_file);
+ for (i = 0; i < qfds; i++)
+ (*op)(fdep[i]->fde_file);
}
if (CMSG_SPACE(datalen) < clen) {
diff --git a/sys/modules/coda/Makefile b/sys/modules/coda/Makefile
deleted file mode 100644
index ebcb39c..0000000
--- a/sys/modules/coda/Makefile
+++ /dev/null
@@ -1,10 +0,0 @@
-# $FreeBSD$
-
-.PATH: ${.CURDIR}/../../fs/coda
-
-KMOD= coda
-SRCS= vnode_if.h \
- coda_fbsd.c coda_psdev.c coda_subr.c coda_venus.c coda_vfsops.c \
- coda_vnops.c opt_coda.h
-
-.include <bsd.kmod.mk>
diff --git a/sys/modules/coda5/Makefile b/sys/modules/coda5/Makefile
deleted file mode 100644
index f9aea09..0000000
--- a/sys/modules/coda5/Makefile
+++ /dev/null
@@ -1,13 +0,0 @@
-# $FreeBSD$
-
-.PATH: ${.CURDIR}/../../fs/coda
-
-KMOD= coda5
-SRCS= vnode_if.h \
- coda_fbsd.c coda_psdev.c coda_subr.c \
- coda_venus.c coda_vfsops.c coda_vnops.c \
- opt_coda.h
-
-CFLAGS+= -DCODA5_MODULE
-
-.include <bsd.kmod.mk>
diff --git a/sys/modules/drm2/drm2/Makefile b/sys/modules/drm2/drm2/Makefile
index 1bc979d..215a0ed 100644
--- a/sys/modules/drm2/drm2/Makefile
+++ b/sys/modules/drm2/drm2/Makefile
@@ -1,6 +1,6 @@
# $FreeBSD$
-.PATH: ${.CURDIR}/../../../dev/drm2
+.PATH: ${.CURDIR}/../../../dev/drm2 ${.CURDIR}/../../../dev/drm2/ttm
KMOD = drm2
SRCS = \
drm_agpsupport.c \
@@ -18,6 +18,7 @@ SRCS = \
drm_fops.c \
drm_gem.c \
drm_gem_names.c \
+ drm_global.c \
drm_hashtab.c \
drm_ioctl.c \
drm_irq.c \
@@ -31,7 +32,19 @@ SRCS = \
drm_sman.c \
drm_stub.c \
drm_sysctl.c \
- drm_vm.c
+ drm_vm.c \
+ ttm_lock.c \
+ ttm_object.c \
+ ttm_tt.c \
+ ttm_bo_util.c \
+ ttm_bo.c \
+ ttm_bo_manager.c \
+ ttm_execbuf_util.c \
+ ttm_memory.c \
+ ttm_page_alloc.c \
+ ttm_bo_vm.c
+#ttm_agp_backend.c
+#ttm_page_alloc_dma.c
.if ${MACHINE_CPUARCH} == "amd64"
SRCS += drm_ioc32.c
diff --git a/sys/modules/hpfs/Makefile b/sys/modules/hpfs/Makefile
deleted file mode 100644
index 750fda0..0000000
--- a/sys/modules/hpfs/Makefile
+++ /dev/null
@@ -1,10 +0,0 @@
-# $FreeBSD$
-
-.PATH: ${.CURDIR}/../../fs/hpfs
-
-KMOD= hpfs
-SRCS= vnode_if.h \
- hpfs_vfsops.c hpfs_vnops.c hpfs_subr.c hpfs_lookup.c \
- hpfs_alsubr.c
-
-.include <bsd.kmod.mk>
diff --git a/sys/modules/mqueue/Makefile b/sys/modules/mqueue/Makefile
index 1a29556..f86c78b 100644
--- a/sys/modules/mqueue/Makefile
+++ b/sys/modules/mqueue/Makefile
@@ -5,6 +5,6 @@
KMOD= mqueuefs
SRCS= uipc_mqueue.c \
vnode_if.h \
- opt_posix.h opt_compat.h
+ opt_posix.h opt_compat.h opt_capsicum.h
.include <bsd.kmod.mk>
diff --git a/sys/modules/ntfs/Makefile b/sys/modules/ntfs/Makefile
deleted file mode 100644
index 367af98..0000000
--- a/sys/modules/ntfs/Makefile
+++ /dev/null
@@ -1,11 +0,0 @@
-# $FreeBSD$
-
-.PATH: ${.CURDIR}/../../fs/ntfs
-
-KMOD= ntfs
-SRCS= vnode_if.h \
- ntfs_vfsops.c ntfs_vnops.c ntfs_subr.c ntfs_ihash.c \
- ntfs_compr.c
-EXPORT_SYMS= ntfs_iconv
-
-.include <bsd.kmod.mk>
diff --git a/sys/modules/ntfs_iconv/Makefile b/sys/modules/ntfs_iconv/Makefile
deleted file mode 100644
index 33e6d42..0000000
--- a/sys/modules/ntfs_iconv/Makefile
+++ /dev/null
@@ -1,7 +0,0 @@
-# $FreeBSD$
-
-.PATH: ${.CURDIR}/../../fs/ntfs
-KMOD= ntfs_iconv
-SRCS= ntfs_iconv.c
-
-.include <bsd.kmod.mk>
diff --git a/sys/modules/portalfs/Makefile b/sys/modules/portalfs/Makefile
deleted file mode 100644
index dcd5966..0000000
--- a/sys/modules/portalfs/Makefile
+++ /dev/null
@@ -1,10 +0,0 @@
-# $FreeBSD$
-
-.PATH: ${.CURDIR}/../../fs/portalfs
-
-KMOD= portalfs
-SRCS= vnode_if.h \
- portal_vfsops.c portal_vnops.c \
- opt_capsicum.h
-
-.include <bsd.kmod.mk>
diff --git a/sys/modules/uart/Makefile b/sys/modules/uart/Makefile
index 61bcdec..d8a4869 100644
--- a/sys/modules/uart/Makefile
+++ b/sys/modules/uart/Makefile
@@ -26,6 +26,7 @@ SRCS= uart_bus_acpi.c ${uart_bus_ebus} uart_bus_isa.c uart_bus_pccard.c \
SRCS+= bus_if.h card_if.h device_if.h isa_if.h ${ofw_bus_if} pci_if.h \
power_if.h pccarddevs.h serdev_if.h
+SRCS+= opt_platform.h
MFILES= dev/pccard/card_if.m dev/pccard/power_if.m dev/pci/pci_if.m \
dev/ofw/ofw_bus_if.m dev/uart/uart_if.m isa/isa_if.m kern/bus_if.m \
diff --git a/sys/modules/xfs/Makefile b/sys/modules/xfs/Makefile
deleted file mode 100644
index 1aabcef..0000000
--- a/sys/modules/xfs/Makefile
+++ /dev/null
@@ -1,89 +0,0 @@
-# $FreeBSD$
-
-.PATH: ${.CURDIR}/../../gnu/fs/xfs \
- ${.CURDIR}/../../gnu/fs/xfs/FreeBSD \
- ${.CURDIR}/../../gnu/fs/xfs/FreeBSD/support
-
-KMOD= xfs
-
-SRCS = vnode_if.h \
- xfs_alloc.c \
- xfs_alloc_btree.c \
- xfs_bit.c \
- xfs_bmap.c \
- xfs_bmap_btree.c \
- xfs_btree.c \
- xfs_buf_item.c \
- xfs_da_btree.c \
- xfs_dir.c \
- xfs_dir2.c \
- xfs_dir2_block.c \
- xfs_dir2_data.c \
- xfs_dir2_leaf.c \
- xfs_dir2_node.c \
- xfs_dir2_sf.c \
- xfs_dir2_trace.c \
- xfs_dir_leaf.c \
- xfs_error.c \
- xfs_extfree_item.c \
- xfs_freebsd_iget.c \
- xfs_fsops.c \
- xfs_ialloc.c \
- xfs_ialloc_btree.c \
- xfs_inode.c \
- xfs_inode_item.c \
- xfs_iocore.c \
- xfs_itable.c \
- xfs_dfrag.c \
- xfs_log.c \
- xfs_log_recover.c \
- xfs_mount.c \
- xfs_rename.c \
- xfs_trans.c \
- xfs_trans_ail.c \
- xfs_trans_buf.c \
- xfs_trans_extfree.c \
- xfs_trans_inode.c \
- xfs_trans_item.c \
- xfs_utils.c \
- xfs_vfsops.c \
- xfs_vnodeops.c \
- xfs_rw.c \
- xfs_iget.c \
- xfs_attr_leaf.c \
- xfs_attr.c \
- xfs_dmops.c \
- xfs_qmops.c \
- xfs_mountops.c \
- xfs_vnops.c \
- xfs_frw.c \
- xfs_iomap.c \
- xfs_buf.c \
- xfs_globals.c \
- xfs_dmistubs.c \
- xfs_behavior.c \
- xfs_super.c \
- xfs_stats.c \
- xfs_sysctl.c \
- xfs_vfs.c \
- xfs_vnode.c \
- xfs_fs_subr.c \
- xfs_ioctl.c \
- debug.c \
- ktrace.c \
- mrlock.c \
- uuid.c \
- kmem.c \
- kdb.c
-
-SRCS+= opt_ddb.h
-
-.include <bsd.kmod.mk>
-
-CFLAGS+= -I${.CURDIR}/../../gnu/fs/xfs/FreeBSD \
- -I${.CURDIR}/../../gnu/fs/xfs/FreeBSD/support \
- -I${.CURDIR}/../../gnu/fs/xfs
-
-CWARNFLAGS.xfs_dir2_block.c= ${NO_WARRAY_BOUNDS}
-CWARNFLAGS.xfs_dir2_sf.c= ${NO_WARRAY_BOUNDS}
-CWARNFLAGS+= ${CWARNFLAGS.${.IMPSRC:T}}
diff --git a/sys/net/route.c b/sys/net/route.c
index e69ce48..c0f6526 100644
--- a/sys/net/route.c
+++ b/sys/net/route.c
@@ -1498,7 +1498,7 @@ rtinit1(struct ifaddr *ifa, int cmd, int flags, int fibnum)
if (rnh == NULL)
/* this table doesn't exist but others might */
continue;
- RADIX_NODE_HEAD_LOCK(rnh);
+ RADIX_NODE_HEAD_RLOCK(rnh);
#ifdef RADIX_MPATH
if (rn_mpath_capable(rnh)) {
@@ -1527,7 +1527,7 @@ rtinit1(struct ifaddr *ifa, int cmd, int flags, int fibnum)
(rn->rn_flags & RNF_ROOT) ||
RNTORT(rn)->rt_ifa != ifa ||
!sa_equal((struct sockaddr *)rn->rn_key, dst));
- RADIX_NODE_HEAD_UNLOCK(rnh);
+ RADIX_NODE_HEAD_RUNLOCK(rnh);
if (error) {
/* this is only an error if bad on ALL tables */
continue;
diff --git a/sys/netinet/siftr.c b/sys/netinet/siftr.c
index b0e111c..886be06 100644
--- a/sys/netinet/siftr.c
+++ b/sys/netinet/siftr.c
@@ -1314,7 +1314,7 @@ siftr_manage_ops(uint8_t action)
* flow seen and freeing any malloc'd memory.
* The hash consists of an array of LISTs (man 3 queue).
*/
- for (i = 0; i < siftr_hashmask; i++) {
+ for (i = 0; i <= siftr_hashmask; i++) {
LIST_FOREACH_SAFE(counter, counter_hash + i, nodes,
tmp_counter) {
key = counter->key;
diff --git a/sys/netinet/tcp_timer.c b/sys/netinet/tcp_timer.c
index 48444c1..bde7503 100644
--- a/sys/netinet/tcp_timer.c
+++ b/sys/netinet/tcp_timer.c
@@ -719,20 +719,24 @@ tcp_timer_active(struct tcpcb *tp, int timer_type)
#define ticks_to_msecs(t) (1000*(t) / hz)
void
-tcp_timer_to_xtimer(struct tcpcb *tp, struct tcp_timer *timer, struct xtcp_timer *xtimer)
+tcp_timer_to_xtimer(struct tcpcb *tp, struct tcp_timer *timer,
+ struct xtcp_timer *xtimer)
{
- bzero(xtimer, sizeof(struct xtcp_timer));
+ sbintime_t now;
+
+ bzero(xtimer, sizeof(*xtimer));
if (timer == NULL)
return;
+ now = getsbinuptime();
if (callout_active(&timer->tt_delack))
- xtimer->tt_delack = ticks_to_msecs(timer->tt_delack.c_time - ticks);
+ xtimer->tt_delack = (timer->tt_delack.c_time - now) / SBT_1MS;
if (callout_active(&timer->tt_rexmt))
- xtimer->tt_rexmt = ticks_to_msecs(timer->tt_rexmt.c_time - ticks);
+ xtimer->tt_rexmt = (timer->tt_rexmt.c_time - now) / SBT_1MS;
if (callout_active(&timer->tt_persist))
- xtimer->tt_persist = ticks_to_msecs(timer->tt_persist.c_time - ticks);
+ xtimer->tt_persist = (timer->tt_persist.c_time - now) / SBT_1MS;
if (callout_active(&timer->tt_keep))
- xtimer->tt_keep = ticks_to_msecs(timer->tt_keep.c_time - ticks);
+ xtimer->tt_keep = (timer->tt_keep.c_time - now) / SBT_1MS;
if (callout_active(&timer->tt_2msl))
- xtimer->tt_2msl = ticks_to_msecs(timer->tt_2msl.c_time - ticks);
+ xtimer->tt_2msl = (timer->tt_2msl.c_time - now) / SBT_1MS;
xtimer->t_rcvtime = ticks_to_msecs(ticks - tp->t_rcvtime);
}
diff --git a/sys/netpfil/ipfw/ip_fw_dynamic.c b/sys/netpfil/ipfw/ip_fw_dynamic.c
index 656e826..b0456d3 100644
--- a/sys/netpfil/ipfw/ip_fw_dynamic.c
+++ b/sys/netpfil/ipfw/ip_fw_dynamic.c
@@ -980,8 +980,8 @@ ipfw_dyn_tick(void * vnetx)
chain = &V_layer3_chain;
- /* Run keepalive checks every keepalive_interval iff ka is enabled */
- if ((V_dyn_keepalive_last + V_dyn_keepalive_interval >= time_uptime) &&
+ /* Run keepalive checks every keepalive_period iff ka is enabled */
+ if ((V_dyn_keepalive_last + V_dyn_keepalive_period <= time_uptime) &&
(V_dyn_keepalive != 0)) {
V_dyn_keepalive_last = time_uptime;
check_ka = 1;
@@ -1320,7 +1320,7 @@ ipfw_dyn_init(struct ip_fw_chain *chain)
V_dyn_keepalive_interval = 20;
V_dyn_keepalive_period = 5;
V_dyn_keepalive = 1; /* do send keepalives */
- V_dyn_keepalive = time_uptime;
+ V_dyn_keepalive_last = time_uptime;
V_dyn_max = 4096; /* max # of dynamic rules */
diff --git a/sys/ofed/include/linux/timer.h b/sys/ofed/include/linux/timer.h
index ed4ed4a..a497334 100644
--- a/sys/ofed/include/linux/timer.h
+++ b/sys/ofed/include/linux/timer.h
@@ -37,11 +37,10 @@
struct timer_list {
struct callout timer_callout;
void (*function)(unsigned long);
- unsigned long data;
+ unsigned long data;
+ unsigned long expires;
};
-#define expires timer_callout.c_time
-
static inline void
_timer_fn(void *context)
{
@@ -65,13 +64,16 @@ do { \
callout_init(&(timer)->timer_callout, CALLOUT_MPSAFE); \
} while (0)
-#define mod_timer(timer, expire) \
- callout_reset(&(timer)->timer_callout, (expire) - jiffies, \
- _timer_fn, (timer))
+#define mod_timer(timer, exp) \
+do { \
+ (timer)->expires = (exp); \
+ callout_reset(&(timer)->timer_callout, (exp) - jiffies, \
+ _timer_fn, (timer)); \
+} while (0)
#define add_timer(timer) \
callout_reset(&(timer)->timer_callout, \
- (timer)->timer_callout.c_time - jiffies, _timer_fn, (timer))
+ (timer)->expires - jiffies, _timer_fn, (timer))
#define del_timer(timer) callout_stop(&(timer)->timer_callout)
#define del_timer_sync(timer) callout_drain(&(timer)->timer_callout)
diff --git a/sys/security/audit/audit.h b/sys/security/audit/audit.h
index 733a3c7..dd55875 100644
--- a/sys/security/audit/audit.h
+++ b/sys/security/audit/audit.h
@@ -95,7 +95,7 @@ void audit_arg_pid(pid_t pid);
void audit_arg_process(struct proc *p);
void audit_arg_signum(u_int signum);
void audit_arg_socket(int sodomain, int sotype, int soprotocol);
-void audit_arg_sockaddr(struct thread *td, struct sockaddr *sa);
+void audit_arg_sockaddr(struct thread *td, int dirfd, struct sockaddr *sa);
void audit_arg_auid(uid_t auid);
void audit_arg_auditinfo(struct auditinfo *au_info);
void audit_arg_auditinfo_addr(struct auditinfo_addr *au_info);
@@ -267,9 +267,9 @@ void audit_thread_free(struct thread *td);
audit_arg_socket((sodomain), (sotype), (soprotocol)); \
} while (0)
-#define AUDIT_ARG_SOCKADDR(td, sa) do { \
+#define AUDIT_ARG_SOCKADDR(td, dirfd, sa) do { \
if (AUDITING_TD(curthread)) \
- audit_arg_sockaddr((td), (sa)); \
+ audit_arg_sockaddr((td), (dirfd), (sa)); \
} while (0)
#define AUDIT_ARG_SUID(suid) do { \
@@ -365,7 +365,7 @@ void audit_thread_free(struct thread *td);
#define AUDIT_ARG_SIGNUM(signum)
#define AUDIT_ARG_SGID(sgid)
#define AUDIT_ARG_SOCKET(sodomain, sotype, soprotocol)
-#define AUDIT_ARG_SOCKADDR(td, sa)
+#define AUDIT_ARG_SOCKADDR(td, dirfd, sa)
#define AUDIT_ARG_SUID(suid)
#define AUDIT_ARG_TEXT(text)
#define AUDIT_ARG_UID(uid)
diff --git a/sys/security/audit/audit_arg.c b/sys/security/audit/audit_arg.c
index ec04b8b..4927be0 100644
--- a/sys/security/audit/audit_arg.c
+++ b/sys/security/audit/audit_arg.c
@@ -441,7 +441,7 @@ audit_arg_socket(int sodomain, int sotype, int soprotocol)
}
void
-audit_arg_sockaddr(struct thread *td, struct sockaddr *sa)
+audit_arg_sockaddr(struct thread *td, int dirfd, struct sockaddr *sa)
{
struct kaudit_record *ar;
@@ -463,7 +463,9 @@ audit_arg_sockaddr(struct thread *td, struct sockaddr *sa)
break;
case AF_UNIX:
- audit_arg_upath1(td, AT_FDCWD,
+ if (dirfd != AT_FDCWD)
+ audit_arg_atfd1(dirfd);
+ audit_arg_upath1(td, dirfd,
((struct sockaddr_un *)sa)->sun_path);
ARG_SET_VALID(ar, ARG_SADDRUNIX);
break;
diff --git a/sys/security/audit/audit_bsm.c b/sys/security/audit/audit_bsm.c
index 9c69b1e..03b3c23 100644
--- a/sys/security/audit/audit_bsm.c
+++ b/sys/security/audit/audit_bsm.c
@@ -554,6 +554,21 @@ kaudit_to_bsm(struct kaudit_record *kar, struct au_record **pau)
/* XXX Need to handle ARG_SADDRINET6 */
break;
+ case AUE_BINDAT:
+ case AUE_CONNECTAT:
+ ATFD1_TOKENS(1);
+ if (ARG_IS_VALID(kar, ARG_FD)) {
+ tok = au_to_arg32(2, "fd", ar->ar_arg_fd);
+ kau_write(rec, tok);
+ }
+ if (ARG_IS_VALID(kar, ARG_SADDRUNIX)) {
+ tok = au_to_sock_unix((struct sockaddr_un *)
+ &ar->ar_arg_sockaddr);
+ kau_write(rec, tok);
+ UPATH1_TOKENS;
+ }
+ break;
+
case AUE_SOCKET:
case AUE_SOCKETPAIR:
if (ARG_IS_VALID(kar, ARG_SOCKINFO)) {
diff --git a/sys/sparc64/pci/psycho.c b/sys/sparc64/pci/psycho.c
index a6e1469..8717426 100644
--- a/sys/sparc64/pci/psycho.c
+++ b/sys/sparc64/pci/psycho.c
@@ -200,7 +200,7 @@ struct psycho_icarg {
* "Sabre" is the UltraSPARC IIi onboard UPA to PCI bridge. It manages a
* single PCI bus and does not have a streaming buffer. It often has an APB
* (advanced PCI bridge) connected to it, which was designed specifically for
- * the IIi. The APB let's the IIi handle two independednt PCI buses, and
+ * the IIi. The APB lets the IIi handle two independent PCI buses, and
* appears as two "Simba"'s underneath the Sabre.
*
* "Hummingbird" is the UltraSPARC IIe onboard UPA to PCI bridge. It's
diff --git a/sys/sys/_callout.h b/sys/sys/_callout.h
index b8c3ce9..e186aec 100644
--- a/sys/sys/_callout.h
+++ b/sys/sys/_callout.h
@@ -42,15 +42,18 @@
struct lock_object;
-SLIST_HEAD(callout_list, callout);
+LIST_HEAD(callout_list, callout);
+SLIST_HEAD(callout_slist, callout);
TAILQ_HEAD(callout_tailq, callout);
struct callout {
union {
+ LIST_ENTRY(callout) le;
SLIST_ENTRY(callout) sle;
TAILQ_ENTRY(callout) tqe;
} c_links;
- int c_time; /* ticks to the event */
+ sbintime_t c_time; /* ticks to the event */
+ sbintime_t c_precision; /* delta allowed wrt opt */
void *c_arg; /* function argument */
void (*c_func)(void *); /* function to call */
struct lock_object *c_lock; /* lock to handle */
diff --git a/sys/sys/callout.h b/sys/sys/callout.h
index 95b9a32..7a4dec9 100644
--- a/sys/sys/callout.h
+++ b/sys/sys/callout.h
@@ -47,6 +47,16 @@
#define CALLOUT_RETURNUNLOCKED 0x0010 /* handler returns with mtx unlocked */
#define CALLOUT_SHAREDLOCK 0x0020 /* callout lock held in shared mode */
#define CALLOUT_DFRMIGRATION 0x0040 /* callout in deferred migration mode */
+#define CALLOUT_PROCESSED 0x0080 /* callout in wheel or processing list? */
+#define CALLOUT_DIRECT 0x0100 /* allow exec from hw int context */
+
+#define C_DIRECT_EXEC 0x0001 /* direct execution of callout */
+#define C_PRELBITS 7
+#define C_PRELRANGE ((1 << C_PRELBITS) - 1)
+#define C_PREL(x) (((x) + 1) << 1)
+#define C_PRELGET(x) (int)((((x) >> 1) & C_PRELRANGE) - 1)
+#define C_HARDCLOCK 0x0100 /* align to hardclock() calls */
+#define C_ABSOLUTE 0x0200 /* event time is absolute. */
struct callout_handle {
struct callout *callout;
@@ -67,7 +77,15 @@ void _callout_init_lock(struct callout *, struct lock_object *, int);
_callout_init_lock((c), ((rw) != NULL) ? &(rw)->lock_object : \
NULL, (flags))
#define callout_pending(c) ((c)->c_flags & CALLOUT_PENDING)
-int callout_reset_on(struct callout *, int, void (*)(void *), void *, int);
+int callout_reset_sbt_on(struct callout *, sbintime_t, sbintime_t,
+ void (*)(void *), void *, int, int);
+#define callout_reset_sbt(c, sbt, pr, fn, arg, flags) \
+ callout_reset_sbt_on((c), (sbt), (pr), (fn), (arg), (c)->c_cpu, flags)
+#define callout_reset_sbt_curcpu(c, sbt, pr, fn, arg, flags) \
+ callout_reset_sbt_on((c), (sbt), (pr), (fn), (arg), PCPU_GET(cpuid), flags)
+#define callout_reset_on(c, to_ticks, fn, arg, cpu) \
+ callout_reset_sbt_on((c), (tick_sbt * (to_ticks)), 0, (fn), (arg), \
+ (cpu), C_HARDCLOCK)
#define callout_reset(c, on_tick, fn, arg) \
callout_reset_on((c), (on_tick), (fn), (arg), (c)->c_cpu)
#define callout_reset_curcpu(c, on_tick, fn, arg) \
@@ -78,9 +96,7 @@ int callout_schedule_on(struct callout *, int, int);
callout_schedule_on((c), (on_tick), PCPU_GET(cpuid))
#define callout_stop(c) _callout_stop_safe(c, 0)
int _callout_stop_safe(struct callout *, int);
-void callout_tick(void);
-int callout_tickstofirst(int limit);
-extern void (*callout_new_inserted)(int cpu, int ticks);
+void callout_process(sbintime_t now);
#endif
diff --git a/sys/sys/capability.h b/sys/sys/capability.h
index 27e56c2..0d1ea5c 100644
--- a/sys/sys/capability.h
+++ b/sys/sys/capability.h
@@ -182,13 +182,18 @@
#define CAP_PDWAIT 0x0020000000000000ULL
#define CAP_PDKILL 0x0040000000000000ULL
+/*
+ * Rights that allow to use bindat(2) and connectat(2) syscalls on a
+ * directory descriptor.
+ */
+#define CAP_BINDAT 0x0400000000000000ULL
+#define CAP_CONNECTAT 0x0800000000000000ULL
+
/* The mask of all valid method rights. */
-#define CAP_MASK_VALID 0x03ffffffffffffffULL
+#define CAP_MASK_VALID 0x0fffffffffffffffULL
#define CAP_ALL CAP_MASK_VALID
/* Available bits. */
-#define CAP_UNUSED5 0x0400000000000000ULL
-#define CAP_UNUSED4 0x0800000000000000ULL
#define CAP_UNUSED3 0x1000000000000000ULL
#define CAP_UNUSED2 0x2000000000000000ULL
#define CAP_UNUSED1 0x4000000000000000ULL
diff --git a/sys/sys/condvar.h b/sys/sys/condvar.h
index ac97b9c..f940a75 100644
--- a/sys/sys/condvar.h
+++ b/sys/sys/condvar.h
@@ -55,8 +55,10 @@ void cv_destroy(struct cv *cvp);
void _cv_wait(struct cv *cvp, struct lock_object *lock);
void _cv_wait_unlock(struct cv *cvp, struct lock_object *lock);
int _cv_wait_sig(struct cv *cvp, struct lock_object *lock);
-int _cv_timedwait(struct cv *cvp, struct lock_object *lock, int timo);
-int _cv_timedwait_sig(struct cv *cvp, struct lock_object *lock, int timo);
+int _cv_timedwait_sbt(struct cv *cvp, struct lock_object *lock,
+ sbintime_t sbt, sbintime_t pr, int flags);
+int _cv_timedwait_sig_sbt(struct cv *cvp, struct lock_object *lock,
+ sbintime_t sbt, sbintime_t pr, int flags);
void cv_signal(struct cv *cvp);
void cv_broadcastpri(struct cv *cvp, int pri);
@@ -68,9 +70,15 @@ void cv_broadcastpri(struct cv *cvp, int pri);
#define cv_wait_sig(cvp, lock) \
_cv_wait_sig((cvp), &(lock)->lock_object)
#define cv_timedwait(cvp, lock, timo) \
- _cv_timedwait((cvp), &(lock)->lock_object, (timo))
+ _cv_timedwait_sbt((cvp), &(lock)->lock_object, \
+ tick_sbt * (timo), 0, C_HARDCLOCK)
+#define cv_timedwait_sbt(cvp, lock, sbt, pr, flags) \
+ _cv_timedwait_sbt((cvp), &(lock)->lock_object, (sbt), (pr), (flags))
#define cv_timedwait_sig(cvp, lock, timo) \
- _cv_timedwait_sig((cvp), &(lock)->lock_object, (timo))
+ _cv_timedwait_sig_sbt((cvp), &(lock)->lock_object, \
+ tick_sbt * (timo), 0, C_HARDCLOCK)
+#define cv_timedwait_sig_sbt(cvp, lock, sbt, pr, flags) \
+ _cv_timedwait_sig_sbt((cvp), &(lock)->lock_object, (sbt), (pr), (flags))
#define cv_broadcast(cvp) cv_broadcastpri(cvp, 0)
diff --git a/sys/sys/diskmbr.h b/sys/sys/diskmbr.h
index 747f70b..c92364d 100644
--- a/sys/sys/diskmbr.h
+++ b/sys/sys/diskmbr.h
@@ -45,6 +45,7 @@
#define DOSMAGIC 0xAA55
#define DOSPTYP_EXT 0x05 /* DOS extended partition */
+#define DOSPTYP_FAT16 0x06 /* FAT16 partition */
#define DOSPTYP_NTFS 0x07 /* NTFS partition */
#define DOSPTYP_FAT32 0x0b /* FAT32 partition */
#define DOSPTYP_EXTLBA 0x0f /* DOS extended partition */
diff --git a/sys/sys/filedesc.h b/sys/sys/filedesc.h
index f3e3a09..d9fe0e0 100644
--- a/sys/sys/filedesc.h
+++ b/sys/sys/filedesc.h
@@ -136,6 +136,7 @@ struct thread;
void filecaps_init(struct filecaps *fcaps);
void filecaps_copy(const struct filecaps *src, struct filecaps *dst);
+void filecaps_move(struct filecaps *src, struct filecaps *dst);
void filecaps_free(struct filecaps *fcaps);
int closef(struct file *fp, struct thread *td);
diff --git a/sys/sys/mutex.h b/sys/sys/mutex.h
index 9a36b63..85d6996 100644
--- a/sys/sys/mutex.h
+++ b/sys/sys/mutex.h
@@ -376,7 +376,8 @@ extern struct mtx_pool *mtxpool_sleep;
mtx_assert_((m), (what), __FILE__, __LINE__)
#define mtx_sleep(chan, mtx, pri, wmesg, timo) \
- _sleep((chan), &(mtx)->lock_object, (pri), (wmesg), (timo))
+ _sleep((chan), &(mtx)->lock_object, (pri), (wmesg), \
+ tick_sbt * (timo), 0, C_HARDCLOCK)
#define mtx_initialized(m) lock_initalized(&(m)->lock_object)
diff --git a/sys/sys/param.h b/sys/sys/param.h
index 26db635..ce72863 100644
--- a/sys/sys/param.h
+++ b/sys/sys/param.h
@@ -58,7 +58,7 @@
* in the range 5 to 9.
*/
#undef __FreeBSD_version
-#define __FreeBSD_version 1000028 /* Master, propagated to newvers */
+#define __FreeBSD_version 1000029 /* Master, propagated to newvers */
/*
* __FreeBSD_kernel__ indicates that this system uses the kernel of FreeBSD,
diff --git a/sys/sys/pmckern.h b/sys/sys/pmckern.h
index c623648..e3e18a6 100644
--- a/sys/sys/pmckern.h
+++ b/sys/sys/pmckern.h
@@ -87,9 +87,9 @@ struct pmckern_soft {
* Soft PMC.
*/
-#define PMC_SOFT_DEFINE(prov, mod, func, name) \
+#define PMC_SOFT_DEFINE_EX(prov, mod, func, name, alloc, release) \
struct pmc_soft pmc_##prov##_##mod##_##func##_##name = \
- { 0, { #prov "_" #mod "_" #func "." #name, 0 } }; \
+ { 0, alloc, release, { #prov "_" #mod "_" #func "." #name, 0 } }; \
SYSINIT(pmc_##prov##_##mod##_##func##_##name##_init, SI_SUB_KDTRACE, \
SI_ORDER_SECOND + 1, pmc_soft_ev_register, \
&pmc_##prov##_##mod##_##func##_##name ); \
@@ -97,6 +97,9 @@ struct pmckern_soft {
SI_SUB_KDTRACE, SI_ORDER_SECOND + 1, pmc_soft_ev_deregister, \
&pmc_##prov##_##mod##_##func##_##name )
+#define PMC_SOFT_DEFINE(prov, mod, func, name) \
+ PMC_SOFT_DEFINE_EX(prov, mod, func, name, NULL, NULL)
+
#define PMC_SOFT_DECLARE(prov, mod, func, name) \
extern struct pmc_soft pmc_##prov##_##mod##_##func##_##name
@@ -147,6 +150,8 @@ do { \
struct pmc_soft {
int ps_running;
+ void (*ps_alloc)(void);
+ void (*ps_release)(void);
struct pmc_dyn_event_descr ps_ev;
};
diff --git a/sys/sys/protosw.h b/sys/sys/protosw.h
index 78d6e06..8553baf 100644
--- a/sys/sys/protosw.h
+++ b/sys/sys/protosw.h
@@ -223,6 +223,10 @@ struct pr_usrreqs {
struct ucred *cred, struct thread *td);
void (*pru_sosetlabel)(struct socket *so);
void (*pru_close)(struct socket *so);
+ int (*pru_bindat)(int fd, struct socket *so, struct sockaddr *nam,
+ struct thread *td);
+ int (*pru_connectat)(int fd, struct socket *so,
+ struct sockaddr *nam, struct thread *td);
};
/*
@@ -232,8 +236,12 @@ int pru_accept_notsupp(struct socket *so, struct sockaddr **nam);
int pru_attach_notsupp(struct socket *so, int proto, struct thread *td);
int pru_bind_notsupp(struct socket *so, struct sockaddr *nam,
struct thread *td);
+int pru_bindat_notsupp(int fd, struct socket *so, struct sockaddr *nam,
+ struct thread *td);
int pru_connect_notsupp(struct socket *so, struct sockaddr *nam,
struct thread *td);
+int pru_connectat_notsupp(int fd, struct socket *so, struct sockaddr *nam,
+ struct thread *td);
int pru_connect2_notsupp(struct socket *so1, struct socket *so2);
int pru_control_notsupp(struct socket *so, u_long cmd, caddr_t data,
struct ifnet *ifp, struct thread *td);
diff --git a/sys/sys/rwlock.h b/sys/sys/rwlock.h
index 8623c05..26e4ac7 100644
--- a/sys/sys/rwlock.h
+++ b/sys/sys/rwlock.h
@@ -211,7 +211,8 @@ void __rw_assert(const volatile uintptr_t *c, int what, const char *file,
rw_runlock(rw); \
} while (0)
#define rw_sleep(chan, rw, pri, wmesg, timo) \
- _sleep((chan), &(rw)->lock_object, (pri), (wmesg), (timo))
+ _sleep((chan), &(rw)->lock_object, (pri), (wmesg), \
+ tick_sbt * (timo), 0, C_HARDCLOCK)
#define rw_initialized(rw) lock_initalized(&(rw)->lock_object)
diff --git a/sys/sys/sleepqueue.h b/sys/sys/sleepqueue.h
index f2a5c75..1c34636 100644
--- a/sys/sys/sleepqueue.h
+++ b/sys/sys/sleepqueue.h
@@ -108,7 +108,10 @@ struct sleepqueue *sleepq_lookup(void *wchan);
void sleepq_release(void *wchan);
void sleepq_remove(struct thread *td, void *wchan);
int sleepq_signal(void *wchan, int flags, int pri, int queue);
-void sleepq_set_timeout(void *wchan, int timo);
+void sleepq_set_timeout_sbt(void *wchan, sbintime_t sbt,
+ sbintime_t pr, int flags);
+#define sleepq_set_timeout(wchan, timo) \
+ sleepq_set_timeout_sbt((wchan), tick_sbt * (timo), 0, C_HARDCLOCK)
u_int sleepq_sleepcnt(void *wchan, int queue);
int sleepq_timedwait(void *wchan, int pri);
int sleepq_timedwait_sig(void *wchan, int pri);
diff --git a/sys/sys/socket.h b/sys/sys/socket.h
index c29a689..632dae4 100644
--- a/sys/sys/socket.h
+++ b/sys/sys/socket.h
@@ -620,7 +620,9 @@ struct sf_hdtr {
__BEGIN_DECLS
int accept(int, struct sockaddr * __restrict, socklen_t * __restrict);
int bind(int, const struct sockaddr *, socklen_t);
+int bindat(int, int, const struct sockaddr *, socklen_t);
int connect(int, const struct sockaddr *, socklen_t);
+int connectat(int, int, const struct sockaddr *, socklen_t);
int getpeername(int, struct sockaddr * __restrict, socklen_t * __restrict);
int getsockname(int, struct sockaddr * __restrict, socklen_t * __restrict);
int getsockopt(int, int, int, void * __restrict, socklen_t * __restrict);
diff --git a/sys/sys/socketvar.h b/sys/sys/socketvar.h
index 9012f240..77f31df 100644
--- a/sys/sys/socketvar.h
+++ b/sys/sys/socketvar.h
@@ -318,8 +318,12 @@ void soabort(struct socket *so);
int soaccept(struct socket *so, struct sockaddr **nam);
int socheckuid(struct socket *so, uid_t uid);
int sobind(struct socket *so, struct sockaddr *nam, struct thread *td);
+int sobindat(int fd, struct socket *so, struct sockaddr *nam,
+ struct thread *td);
int soclose(struct socket *so);
int soconnect(struct socket *so, struct sockaddr *nam, struct thread *td);
+int soconnectat(int fd, struct socket *so, struct sockaddr *nam,
+ struct thread *td);
int soconnect2(struct socket *so1, struct socket *so2);
int socow_setup(struct mbuf *m0, struct uio *uio);
int socreate(int dom, struct socket **aso, int type, int proto,
diff --git a/sys/sys/sx.h b/sys/sys/sx.h
index 8c76a50..01d7112 100644
--- a/sys/sys/sx.h
+++ b/sys/sys/sx.h
@@ -275,7 +275,8 @@ __sx_sunlock(struct sx *sx, const char *file, int line)
#define sx_unlock(sx) sx_unlock_((sx), LOCK_FILE, LOCK_LINE)
#define sx_sleep(chan, sx, pri, wmesg, timo) \
- _sleep((chan), &(sx)->lock_object, (pri), (wmesg), (timo))
+ _sleep((chan), &(sx)->lock_object, (pri), (wmesg), \
+ tick_sbt * (timo), 0, C_HARDCLOCK)
/*
* Options passed to sx_init_flags().
diff --git a/sys/sys/syscall.h b/sys/sys/syscall.h
index 5a2a1f6..4537d88 100644
--- a/sys/sys/syscall.h
+++ b/sys/sys/syscall.h
@@ -3,7 +3,7 @@
*
* DO NOT EDIT-- this file is automatically generated.
* $FreeBSD$
- * created from FreeBSD: head/sys/kern/syscalls.master 247602 2013-03-02 00:53:12Z pjd
+ * created from FreeBSD: head/sys/kern/syscalls.master 247667 2013-03-02 21:11:30Z pjd
*/
#define SYS_syscall 0
@@ -457,4 +457,6 @@
#define SYS_cap_ioctls_get 535
#define SYS_cap_fcntls_limit 536
#define SYS_cap_fcntls_get 537
-#define SYS_MAXSYSCALL 538
+#define SYS_bindat 538
+#define SYS_connectat 539
+#define SYS_MAXSYSCALL 540
diff --git a/sys/sys/syscall.mk b/sys/sys/syscall.mk
index 3e2a3d4..6833450 100644
--- a/sys/sys/syscall.mk
+++ b/sys/sys/syscall.mk
@@ -1,7 +1,7 @@
# FreeBSD system call names.
# DO NOT EDIT-- this file is automatically generated.
# $FreeBSD$
-# created from FreeBSD: head/sys/kern/syscalls.master 247602 2013-03-02 00:53:12Z pjd
+# created from FreeBSD: head/sys/kern/syscalls.master 247667 2013-03-02 21:11:30Z pjd
MIASM = \
syscall.o \
exit.o \
@@ -405,4 +405,6 @@ MIASM = \
cap_ioctls_limit.o \
cap_ioctls_get.o \
cap_fcntls_limit.o \
- cap_fcntls_get.o
+ cap_fcntls_get.o \
+ bindat.o \
+ connectat.o
diff --git a/sys/sys/sysproto.h b/sys/sys/sysproto.h
index 8ef4080..ff94b35 100644
--- a/sys/sys/sysproto.h
+++ b/sys/sys/sysproto.h
@@ -3,7 +3,7 @@
*
* DO NOT EDIT-- this file is automatically generated.
* $FreeBSD$
- * created from FreeBSD: head/sys/kern/syscalls.master 247602 2013-03-02 00:53:12Z pjd
+ * created from FreeBSD: head/sys/kern/syscalls.master 247667 2013-03-02 21:11:30Z pjd
*/
#ifndef _SYS_SYSPROTO_H_
@@ -1784,6 +1784,18 @@ struct cap_fcntls_get_args {
char fd_l_[PADL_(int)]; int fd; char fd_r_[PADR_(int)];
char fcntlrightsp_l_[PADL_(uint32_t *)]; uint32_t * fcntlrightsp; char fcntlrightsp_r_[PADR_(uint32_t *)];
};
+struct bindat_args {
+ char fd_l_[PADL_(int)]; int fd; char fd_r_[PADR_(int)];
+ char s_l_[PADL_(int)]; int s; char s_r_[PADR_(int)];
+ char name_l_[PADL_(caddr_t)]; caddr_t name; char name_r_[PADR_(caddr_t)];
+ char namelen_l_[PADL_(int)]; int namelen; char namelen_r_[PADR_(int)];
+};
+struct connectat_args {
+ char fd_l_[PADL_(int)]; int fd; char fd_r_[PADR_(int)];
+ char s_l_[PADL_(int)]; int s; char s_r_[PADR_(int)];
+ char name_l_[PADL_(caddr_t)]; caddr_t name; char name_r_[PADR_(caddr_t)];
+ char namelen_l_[PADL_(int)]; int namelen; char namelen_r_[PADR_(int)];
+};
int nosys(struct thread *, struct nosys_args *);
void sys_sys_exit(struct thread *, struct sys_exit_args *);
int sys_fork(struct thread *, struct fork_args *);
@@ -2171,6 +2183,8 @@ int sys_cap_ioctls_limit(struct thread *, struct cap_ioctls_limit_args *);
int sys_cap_ioctls_get(struct thread *, struct cap_ioctls_get_args *);
int sys_cap_fcntls_limit(struct thread *, struct cap_fcntls_limit_args *);
int sys_cap_fcntls_get(struct thread *, struct cap_fcntls_get_args *);
+int sys_bindat(struct thread *, struct bindat_args *);
+int sys_connectat(struct thread *, struct connectat_args *);
#ifdef COMPAT_43
@@ -2872,6 +2886,8 @@ int freebsd7_shmctl(struct thread *, struct freebsd7_shmctl_args *);
#define SYS_AUE_cap_ioctls_get AUE_CAP_IOCTLS_GET
#define SYS_AUE_cap_fcntls_limit AUE_CAP_FCNTLS_LIMIT
#define SYS_AUE_cap_fcntls_get AUE_CAP_FCNTLS_GET
+#define SYS_AUE_bindat AUE_BINDAT
+#define SYS_AUE_connectat AUE_CONNECTAT
#undef PAD_
#undef PADL_
diff --git a/sys/sys/systm.h b/sys/sys/systm.h
index 2bf8056..f149e6c 100644
--- a/sys/sys/systm.h
+++ b/sys/sys/systm.h
@@ -44,7 +44,6 @@
#include <sys/cdefs.h>
#include <sys/queue.h>
#include <sys/stdint.h> /* for people using printf mainly */
-#include <sys/time.h>
extern int cold; /* nonzero if we are doing a cold boot */
extern int rebooting; /* kern_reboot() has been called. */
@@ -270,6 +269,7 @@ void cpu_startprofclock(void);
void cpu_stopprofclock(void);
sbintime_t cpu_idleclock(void);
void cpu_activeclock(void);
+void cpu_new_callout(int cpu, sbintime_t bt, sbintime_t bt_opt);
extern int cpu_can_deep_sleep;
extern int cpu_disable_deep_sleep;
@@ -340,14 +340,27 @@ static __inline void splx(intrmask_t ipl __unused) { return; }
* less often.
*/
int _sleep(void *chan, struct lock_object *lock, int pri, const char *wmesg,
- int timo) __nonnull(1);
+ sbintime_t sbt, sbintime_t pr, int flags) __nonnull(1);
#define msleep(chan, mtx, pri, wmesg, timo) \
- _sleep((chan), &(mtx)->lock_object, (pri), (wmesg), (timo))
-int msleep_spin(void *chan, struct mtx *mtx, const char *wmesg, int timo)
- __nonnull(1);
-int pause(const char *wmesg, int timo);
+ _sleep((chan), &(mtx)->lock_object, (pri), (wmesg), \
+ tick_sbt * (timo), 0, C_HARDCLOCK)
+#define msleep_sbt(chan, mtx, pri, wmesg, bt, pr, flags) \
+ _sleep((chan), &(mtx)->lock_object, (pri), (wmesg), (bt), (pr), \
+ (flags))
+int msleep_spin_sbt(void *chan, struct mtx *mtx, const char *wmesg,
+ sbintime_t sbt, sbintime_t pr, int flags) __nonnull(1);
+#define msleep_spin(chan, mtx, wmesg, timo) \
+ msleep_spin_sbt((chan), (mtx), (wmesg), tick_sbt * (timo), \
+ 0, C_HARDCLOCK)
+int pause_sbt(const char *wmesg, sbintime_t sbt, sbintime_t pr,
+ int flags);
+#define pause(wmesg, timo) \
+ pause_sbt((wmesg), tick_sbt * (timo), 0, C_HARDCLOCK)
#define tsleep(chan, pri, wmesg, timo) \
- _sleep((chan), NULL, (pri), (wmesg), (timo))
+ _sleep((chan), NULL, (pri), (wmesg), tick_sbt * (timo), \
+ 0, C_HARDCLOCK)
+#define tsleep_sbt(chan, pri, wmesg, bt, pr, flags) \
+ _sleep((chan), NULL, (pri), (wmesg), (bt), (pr), (flags))
void wakeup(void *chan) __nonnull(1);
void wakeup_one(void *chan) __nonnull(1);
diff --git a/sys/sys/time.h b/sys/sys/time.h
index 555c37e..761a123 100644
--- a/sys/sys/time.h
+++ b/sys/sys/time.h
@@ -102,6 +102,21 @@ bintime_mul(struct bintime *bt, u_int x)
bt->frac = (p2 << 32) | (p1 & 0xffffffffull);
}
+static __inline void
+bintime_shift(struct bintime *bt, int exp)
+{
+
+ if (exp > 0) {
+ bt->sec <<= exp;
+ bt->sec |= bt->frac >> (64 - exp);
+ bt->frac <<= exp;
+ } else if (exp < 0) {
+ bt->frac >>= -exp;
+ bt->frac |= (uint64_t)bt->sec << (64 + exp);
+ bt->sec >>= -exp;
+ }
+}
+
#define bintime_clear(a) ((a)->sec = (a)->frac = 0)
#define bintime_isset(a) ((a)->sec || (a)->frac)
#define bintime_cmp(a, b, cmp) \
@@ -113,7 +128,7 @@ bintime_mul(struct bintime *bt, u_int x)
#define SBT_1M (SBT_1S * 60)
#define SBT_1MS (SBT_1S / 1000)
#define SBT_1US (SBT_1S / 1000000)
-#define SBT_1NS (SBT_1S / 1000000000)
+#define SBT_1NS (SBT_1S / 1000000000)
static __inline int
sbintime_getsec(sbintime_t sbt)
@@ -133,7 +148,7 @@ static __inline struct bintime
sbttobt(sbintime_t sbt)
{
struct bintime bt;
-
+
bt.sec = sbt >> 32;
bt.frac = sbt << 32;
return (bt);
@@ -357,6 +372,16 @@ extern volatile time_t time_second;
extern volatile time_t time_uptime;
extern struct bintime boottimebin;
extern struct timeval boottime;
+extern struct bintime tc_tick_bt;
+extern sbintime_t tc_tick_sbt;
+extern struct bintime tick_bt;
+extern sbintime_t tick_sbt;
+extern int tc_precexp;
+extern int tc_timepercentage;
+extern struct bintime bt_timethreshold;
+extern struct bintime bt_tickthreshold;
+extern sbintime_t sbt_timethreshold;
+extern sbintime_t sbt_tickthreshold;
/*
* Functions for looking at our clock: [get]{bin,nano,micro}[up]time()
@@ -421,6 +446,25 @@ int ratecheck(struct timeval *, const struct timeval *);
void timevaladd(struct timeval *t1, const struct timeval *t2);
void timevalsub(struct timeval *t1, const struct timeval *t2);
int tvtohz(struct timeval *tv);
+
+#define TC_DEFAULTPERC 5
+
+#define BT2FREQ(bt) \
+ (((uint64_t)0x8000000000000000 + ((bt)->frac >> 2)) / \
+ ((bt)->frac >> 1))
+
+#define SBT2FREQ(sbt) ((SBT_1S + ((sbt) >> 1)) / (sbt))
+
+#define FREQ2BT(freq, bt) \
+{ \
+ (bt)->sec = 0; \
+ (bt)->frac = ((uint64_t)0x8000000000000000 / (freq)) << 1; \
+}
+
+#define TIMESEL(sbt, sbt2) \
+ (((sbt2) >= sbt_timethreshold) ? \
+ ((*(sbt) = getsbinuptime()), 1) : ((*(sbt) = sbinuptime()), 0))
+
#else /* !_KERNEL */
#include <time.h>
diff --git a/sys/vm/vm_object.c b/sys/vm/vm_object.c
index 73d93fc..38e0519 100644
--- a/sys/vm/vm_object.c
+++ b/sys/vm/vm_object.c
@@ -166,8 +166,9 @@ vm_object_zdtor(void *mem, int size, void *arg)
object = (vm_object_t)mem;
KASSERT(TAILQ_EMPTY(&object->memq),
- ("object %p has resident pages",
- object));
+ ("object %p has resident pages in its memq", object));
+ KASSERT(object->root == NULL,
+ ("object %p has resident pages in its tree", object));
#if VM_NRESERVLEVEL > 0
KASSERT(LIST_EMPTY(&object->rvq),
("object %p has reservations",
@@ -198,9 +199,11 @@ vm_object_zinit(void *mem, int size, int flags)
rw_init_flags(&object->lock, "vm object", RW_DUPOK);
/* These are true for any object that has been freed */
+ object->root = NULL;
object->paging_in_progress = 0;
object->resident_page_count = 0;
object->shadow_count = 0;
+ object->cache = NULL;
return (0);
}
@@ -211,7 +214,6 @@ _vm_object_allocate(objtype_t type, vm_pindex_t size, vm_object_t object)
TAILQ_INIT(&object->memq);
LIST_INIT(&object->shadow_head);
- object->root = NULL;
object->type = type;
switch (type) {
case OBJT_DEAD:
@@ -242,14 +244,12 @@ _vm_object_allocate(objtype_t type, vm_pindex_t size, vm_object_t object)
object->memattr = VM_MEMATTR_DEFAULT;
object->cred = NULL;
object->charge = 0;
- object->pg_color = 0;
object->handle = NULL;
object->backing_object = NULL;
object->backing_object_offset = (vm_ooffset_t) 0;
#if VM_NRESERVLEVEL > 0
LIST_INIT(&object->rvq);
#endif
- object->cache = NULL;
mtx_lock(&vm_object_list_mtx);
TAILQ_INSERT_TAIL(&vm_object_list, object, object_list);
diff --git a/tools/make_libdeps.sh b/tools/make_libdeps.sh
index 8d09ee6..3b59488 100644
--- a/tools/make_libdeps.sh
+++ b/tools/make_libdeps.sh
@@ -47,6 +47,7 @@ sed -E
-e's; ;! ;g'
-e's;$;!;'
-e's;-lbsdxml!;lib/libexpat;g'
+ -e's;-lbsdyml!;lib/libyaml;g'
-e's;-lpthread!;lib/libthr;g'
-e's;-lm!;lib/msun;g'
-e's;-l(ncurses|termcap)!;lib/ncurses/ncurses;g'
diff --git a/tools/regression/bin/sh/builtins/trap12.0 b/tools/regression/bin/sh/builtins/trap12.0
new file mode 100644
index 0000000..8c62ffd
--- /dev/null
+++ b/tools/regression/bin/sh/builtins/trap12.0
@@ -0,0 +1,10 @@
+# $FreeBSD$
+
+f() {
+ trap 'return 42' USR1
+ kill -USR1 $$
+ return 3
+}
+f
+r=$?
+[ "$r" = 42 ]
diff --git a/tools/regression/capsicum/syscalls/cap_ioctls_limit.c b/tools/regression/capsicum/syscalls/cap_ioctls_limit.c
index 3a08fac..753aa71 100644
--- a/tools/regression/capsicum/syscalls/cap_ioctls_limit.c
+++ b/tools/regression/capsicum/syscalls/cap_ioctls_limit.c
@@ -51,7 +51,7 @@ ioctl_tests_0(int fd)
{
unsigned long cmds[2];
- CHECK(cap_ioctls_get(fd, NULL, 0) == INT_MAX);
+ CHECK(cap_ioctls_get(fd, NULL, 0) == CAP_IOCTLS_ALL);
CHECK(fcntl(fd, F_GETFD) == 0);
CHECK(ioctl(fd, FIOCLEX) == 0);
@@ -241,7 +241,7 @@ ioctl_tests_recv_0(int sock)
CHECK(descriptor_recv(sock, &fd) == 0);
- CHECK(cap_ioctls_get(fd, NULL, 0) == INT_MAX);
+ CHECK(cap_ioctls_get(fd, NULL, 0) == CAP_IOCTLS_ALL);
CHECK(fcntl(fd, F_GETFD) == 0);
CHECK(ioctl(fd, FIOCLEX) == 0);
diff --git a/tools/regression/pjdfstest/Makefile b/tools/regression/pjdfstest/Makefile
index ca789fe..eec813a 100644
--- a/tools/regression/pjdfstest/Makefile
+++ b/tools/regression/pjdfstest/Makefile
@@ -6,7 +6,7 @@ ${PROG}: ${PROG}.c
@OSTYPE=`uname`; \
CFLAGS=-D__OS_$${OSTYPE}__; \
if [ $$OSTYPE = "FreeBSD" ]; then \
- CFLAGS="$$CFLAGS -DHAS_LCHMOD -DHAS_CHFLAGS -DHAS_FCHFLAGS -DHAS_LCHFLAGS -DHAS_FREEBSD_ACL"; \
+ CFLAGS="$$CFLAGS -DHAS_LCHMOD -DHAS_CHFLAGS -DHAS_FCHFLAGS -DHAS_LCHFLAGS -DHAS_FREEBSD_ACL -DHAS_BINDAT -DHAS_CONNECTAT"; \
elif [ $$OSTYPE = "SunOS" ]; then \
CFLAGS="$$CFLAGS -DHAS_TRUNCATE64 -DHAS_STAT64"; \
CFLAGS="$$CFLAGS -lsocket"; \
diff --git a/tools/regression/pjdfstest/pjdfstest.c b/tools/regression/pjdfstest/pjdfstest.c
index c08fafd..6eafc8c 100644
--- a/tools/regression/pjdfstest/pjdfstest.c
+++ b/tools/regression/pjdfstest/pjdfstest.c
@@ -82,7 +82,13 @@ enum action {
ACTION_MKNOD,
ACTION_MKNODAT,
ACTION_BIND,
+#ifdef HAS_BINDAT
+ ACTION_BINDAT,
+#endif
ACTION_CONNECT,
+#ifdef HAS_CONNECTAT
+ ACTION_CONNECTAT,
+#endif
ACTION_CHMOD,
ACTION_FCHMOD,
#ifdef HAS_LCHMOD
@@ -154,7 +160,13 @@ static struct syscall_desc syscalls[] = {
{ "mknod", ACTION_MKNOD, { TYPE_STRING, TYPE_STRING, TYPE_NUMBER, TYPE_NUMBER, TYPE_NUMBER, TYPE_NONE} },
{ "mknodat", ACTION_MKNODAT, { TYPE_DESCRIPTOR, TYPE_STRING, TYPE_STRING, TYPE_NUMBER, TYPE_NUMBER, TYPE_NUMBER, TYPE_NONE} },
{ "bind", ACTION_BIND, { TYPE_STRING, TYPE_NONE } },
+#ifdef HAS_BINDAT
+ { "bindat", ACTION_BINDAT, { TYPE_DESCRIPTOR, TYPE_STRING, TYPE_NONE } },
+#endif
{ "connect", ACTION_CONNECT, { TYPE_STRING, TYPE_NONE } },
+#ifdef HAS_CONNECTAT
+ { "connectat", ACTION_CONNECTAT, { TYPE_DESCRIPTOR, TYPE_STRING, TYPE_NONE } },
+#endif
{ "chmod", ACTION_CHMOD, { TYPE_STRING, TYPE_NUMBER, TYPE_NONE } },
{ "fchmod", ACTION_FCHMOD, { TYPE_DESCRIPTOR, TYPE_NUMBER, TYPE_NONE } },
#ifdef HAS_LCHMOD
@@ -732,6 +744,22 @@ call_syscall(struct syscall_desc *scall, char *argv[])
rval = bind(rval, (struct sockaddr *)&sunx, sizeof(sunx));
break;
}
+#ifdef HAS_BINDAT
+ case ACTION_BINDAT:
+ {
+ struct sockaddr_un sunx;
+
+ sunx.sun_family = AF_UNIX;
+ strncpy(sunx.sun_path, STR(1), sizeof(sunx.sun_path) - 1);
+ sunx.sun_path[sizeof(sunx.sun_path) - 1] = '\0';
+ rval = socket(AF_UNIX, SOCK_STREAM, 0);
+ if (rval < 0)
+ break;
+ rval = bindat(NUM(0), rval, (struct sockaddr *)&sunx,
+ sizeof(sunx));
+ break;
+ }
+#endif
case ACTION_CONNECT:
{
struct sockaddr_un sunx;
@@ -745,6 +773,22 @@ call_syscall(struct syscall_desc *scall, char *argv[])
rval = connect(rval, (struct sockaddr *)&sunx, sizeof(sunx));
break;
}
+#ifdef HAS_CONNECTAT
+ case ACTION_CONNECTAT:
+ {
+ struct sockaddr_un sunx;
+
+ sunx.sun_family = AF_UNIX;
+ strncpy(sunx.sun_path, STR(1), sizeof(sunx.sun_path) - 1);
+ sunx.sun_path[sizeof(sunx.sun_path) - 1] = '\0';
+ rval = socket(AF_UNIX, SOCK_STREAM, 0);
+ if (rval < 0)
+ break;
+ rval = connectat(NUM(0), rval, (struct sockaddr *)&sunx,
+ sizeof(sunx));
+ break;
+ }
+#endif
case ACTION_CHMOD:
rval = chmod(STR(0), (mode_t)NUM(1));
break;
diff --git a/tools/tools/cxgbetool/cxgbetool.c b/tools/tools/cxgbetool/cxgbetool.c
index 39e7376..32f6d26 100644
--- a/tools/tools/cxgbetool/cxgbetool.c
+++ b/tools/tools/cxgbetool/cxgbetool.c
@@ -31,6 +31,7 @@ __FBSDID("$FreeBSD$");
#include <stdint.h>
#include <stdlib.h>
#include <unistd.h>
+#include <ctype.h>
#include <errno.h>
#include <err.h>
#include <fcntl.h>
diff --git a/usr.bin/Makefile.arm b/usr.bin/Makefile.arm
index 3c4e7a5..b720e3d 100644
--- a/usr.bin/Makefile.arm
+++ b/usr.bin/Makefile.arm
@@ -1,3 +1,2 @@
# $FreeBSD$
-SUBDIR:= ${SUBDIR:Ntruss}
diff --git a/usr.bin/c89/c89.c b/usr.bin/c89/c89.c
index a1dc9b2..930153f 100644
--- a/usr.bin/c89/c89.c
+++ b/usr.bin/c89/c89.c
@@ -72,7 +72,7 @@ main(int argc, char **argv)
Argv.a = malloc((argc + 1 + N_ARGS_PREPENDED) * sizeof *Argv.a);
if (Argv.a == NULL)
err(1, "malloc");
- Argv.a[Argc++] = argv[0];
+ Argv.a[Argc++] = CC;
for (j = 0; j < N_ARGS_PREPENDED; ++j)
Argv.a[Argc++] = args_prepended[j];
while ((i = getopt(argc, argv, "cD:EgI:l:L:o:OsU:")) != -1) {
diff --git a/usr.bin/c99/c99.c b/usr.bin/c99/c99.c
index f5f273f..79cca89 100644
--- a/usr.bin/c99/c99.c
+++ b/usr.bin/c99/c99.c
@@ -70,7 +70,7 @@ main(int argc, char *argv[])
usage();
}
- addarg("cc");
+ addarg("/usr/bin/cc");
addarg("-std=iso9899:1999");
addarg("-pedantic");
for (i = 1; i < optind; i++)
diff --git a/usr.bin/calendar/calendars/calendar.birthday b/usr.bin/calendar/calendars/calendar.birthday
index ad78d8f..adf14a2 100644
--- a/usr.bin/calendar/calendars/calendar.birthday
+++ b/usr.bin/calendar/calendars/calendar.birthday
@@ -6,6 +6,7 @@
#ifndef _calendar_birthday_
#define _calendar_birthday_
+#undef unix
01/01 J.D. Salinger born, 1919
01/01 Paul Revere born in Boston, 1735
diff --git a/usr.bin/find/extern.h b/usr.bin/find/extern.h
index 6fa25d2..90b9b29 100644
--- a/usr.bin/find/extern.h
+++ b/usr.bin/find/extern.h
@@ -73,6 +73,7 @@ creat_f c_regex;
creat_f c_samefile;
creat_f c_simple;
creat_f c_size;
+creat_f c_sparse;
creat_f c_type;
creat_f c_user;
creat_f c_xdev;
@@ -109,6 +110,7 @@ exec_f f_prune;
exec_f f_quit;
exec_f f_regex;
exec_f f_size;
+exec_f f_sparse;
exec_f f_type;
exec_f f_user;
diff --git a/usr.bin/find/find.1 b/usr.bin/find/find.1
index 47c40d8..cffeacf 100644
--- a/usr.bin/find/find.1
+++ b/usr.bin/find/find.1
@@ -816,6 +816,10 @@ terabytes (1024 gigabytes)
.It Cm P
petabytes (1024 terabytes)
.El
+.It Ic -sparse
+True if the current file is sparse,
+i.e. has fewer blocks allocated than expected based on its size in bytes.
+This might also match files that have been compressed by the filesystem.
.It Ic -type Ar t
True if the file is of the specified type.
Possible file types are as follows:
@@ -997,7 +1001,7 @@ and
as well as
.Ic -amin , -anewer , -cmin , -cnewer , -delete , -empty , -fstype ,
.Ic -iname , -inum , -iregex , -ls , -maxdepth , -mindepth , -mmin ,
-.Ic -path , -print0 , -regex
+.Ic -path , -print0 , -regex, -sparse
and all of the
.Ic -B*
birthtime related primaries are extensions to
diff --git a/usr.bin/find/function.c b/usr.bin/find/function.c
index cad6eb1..61d61cb 100644
--- a/usr.bin/find/function.c
+++ b/usr.bin/find/function.c
@@ -1497,6 +1497,29 @@ c_size(OPTION *option, char ***argvp)
}
/*
+ * -sparse functions --
+ *
+ * Check if a file is sparse by finding if it occupies fewer blocks
+ * than we expect based on its size.
+ */
+int
+f_sparse(PLAN *plan __unused, FTSENT *entry)
+{
+ off_t expected_blocks;
+
+ expected_blocks = (entry->fts_statp->st_size + 511) / 512;
+ return entry->fts_statp->st_blocks < expected_blocks;
+}
+
+PLAN *
+c_sparse(OPTION *option, char ***argvp __unused)
+{
+ ftsoptions &= ~FTS_NOSTAT;
+
+ return palloc(option);
+}
+
+/*
* -type c functions --
*
* True if the type of the file is c, where c is b, c, d, p, f or w
diff --git a/usr.bin/find/option.c b/usr.bin/find/option.c
index b89420c..4fc63b6 100644
--- a/usr.bin/find/option.c
+++ b/usr.bin/find/option.c
@@ -145,6 +145,7 @@ static OPTION const options[] = {
{ "-regex", c_regex, f_regex, 0 },
{ "-samefile", c_samefile, f_inum, 0 },
{ "-size", c_size, f_size, 0 },
+ { "-sparse", c_sparse, f_sparse, 0 },
{ "-true", c_simple, f_always_true, 0 },
{ "-type", c_type, f_type, 0 },
{ "-uid", c_user, f_user, 0 },
diff --git a/usr.bin/hexdump/conv.c b/usr.bin/hexdump/conv.c
index 2253dff..8ba1311 100644
--- a/usr.bin/hexdump/conv.c
+++ b/usr.bin/hexdump/conv.c
@@ -151,7 +151,7 @@ conv_u(PR *pr, u_char *p)
static char const * list[] = {
"nul", "soh", "stx", "etx", "eot", "enq", "ack", "bel",
"bs", "ht", "lf", "vt", "ff", "cr", "so", "si",
- "dle", "dcl", "dc2", "dc3", "dc4", "nak", "syn", "etb",
+ "dle", "dc1", "dc2", "dc3", "dc4", "nak", "syn", "etb",
"can", "em", "sub", "esc", "fs", "gs", "rs", "us",
};
diff --git a/usr.bin/procstat/procstat_files.c b/usr.bin/procstat/procstat_files.c
index 030bba1..a3137db 100644
--- a/usr.bin/procstat/procstat_files.c
+++ b/usr.bin/procstat/procstat_files.c
@@ -215,6 +215,13 @@ static struct cap_desc {
{ CAP_PDWAIT, "pw" },
{ CAP_PDKILL, "pk" },
+ /*
+ * Rights that allow to use bindat(2) and connectat(2) syscalls on a
+ * directory descriptor.
+ */
+ { CAP_BINDAT, "ba" },
+ { CAP_CONNECTAT, "ca" },
+
/* Aliases and defines that combine multiple rights. */
{ CAP_PREAD, "prd" },
{ CAP_PWRITE, "pwr" },
diff --git a/usr.bin/truss/arm-fbsd.c b/usr.bin/truss/arm-fbsd.c
new file mode 100644
index 0000000..b717619
--- /dev/null
+++ b/usr.bin/truss/arm-fbsd.c
@@ -0,0 +1,369 @@
+/*
+ * Copyright 1997 Sean Eric Fagan
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by Sean Eric Fagan
+ * 4. Neither the name of the author may be used to endorse or promote
+ * products derived from this software without specific prior written
+ * permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+/*
+ * FreeBSD/arm-specific system call handling. This is probably the most
+ * complex part of the entire truss program, although I've got lots of
+ * it handled relatively cleanly now. The system call names are generated
+ * automatically, thanks to /usr/src/sys/kern/syscalls.master. The
+ * names used for the various structures are confusing, I sadly admit.
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+#include <sys/types.h>
+#include <sys/ptrace.h>
+#include <sys/syscall.h>
+
+#include <machine/reg.h>
+#include <machine/armreg.h>
+#include <machine/ucontext.h>
+
+#include <errno.h>
+#include <fcntl.h>
+#include <signal.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <time.h>
+#include <unistd.h>
+#include <err.h>
+
+#include "truss.h"
+#include "syscall.h"
+#include "extern.h"
+
+#include "syscalls.h"
+
+
+static int nsyscalls = sizeof(syscallnames) / sizeof(syscallnames[0]);
+
+/*
+ * This is what this particular file uses to keep track of a system call.
+ * It is probably not quite sufficient -- I can probably use the same
+ * structure for the various syscall personalities, and I also probably
+ * need to nest system calls (for signal handlers).
+ *
+ * 'struct syscall' describes the system call; it may be NULL, however,
+ * if we don't know about this particular system call yet.
+ */
+struct freebsd_syscall {
+ struct syscall *sc;
+ const char *name;
+ int number;
+ unsigned long *args;
+ int nargs; /* number of arguments -- *not* number of words! */
+ char **s_args; /* the printable arguments */
+};
+
+static struct freebsd_syscall *
+alloc_fsc(void)
+{
+
+ return (malloc(sizeof(struct freebsd_syscall)));
+}
+
+/* Clear up and free parts of the fsc structure. */
+static void
+free_fsc(struct freebsd_syscall *fsc)
+{
+ int i;
+
+ free(fsc->args);
+ if (fsc->s_args) {
+ for (i = 0; i < fsc->nargs; i++)
+ free(fsc->s_args[i]);
+ free(fsc->s_args);
+ }
+ free(fsc);
+}
+
+/*
+ * Called when a process has entered a system call. nargs is the
+ * number of words, not number of arguments (a necessary distinction
+ * in some cases). Note that if the STOPEVENT() code in i386/i386/trap.c
+ * is ever changed these functions need to keep up.
+ */
+
+void
+arm_syscall_entry(struct trussinfo *trussinfo, int nargs)
+{
+ struct ptrace_io_desc iorequest;
+ struct reg regs;
+ struct freebsd_syscall *fsc;
+ struct syscall *sc;
+ lwpid_t tid;
+ int i, syscall_num;
+ register_t *ap;
+
+ tid = trussinfo->curthread->tid;
+
+ if (ptrace(PT_GETREGS, tid, (caddr_t)&regs, 0) < 0) {
+ fprintf(trussinfo->outfile, "-- CANNOT READ REGISTERS --\n");
+ return;
+ }
+ ap = &regs.r[0];
+
+ /*
+ * FreeBSD has two special kinds of system call redirctions --
+ * SYS_syscall, and SYS___syscall. The former is the old syscall()
+ * routine, basically; the latter is for quad-aligned arguments.
+ */
+#ifdef __ARM_EABI__
+ syscall_num = regs.r[7];
+#else
+ if ((syscall_num = ptrace(PT_READ_I, tid,
+ (caddr_t)(regs.r[_REG_PC] - INSN_SIZE), 0)) == -1) {
+ fprintf(trussinfo->outfile, "-- CANNOT READ PC --\n");
+ return;
+ }
+ syscall_num = syscall_num & 0x000fffff;
+#endif
+ switch (syscall_num) {
+ case SYS_syscall:
+ syscall_num = *ap++;
+ nargs--;
+ break;
+ case SYS___syscall:
+ syscall_num = ap[_QUAD_LOWWORD];
+ ap += 2;
+ nargs -= 2;
+ break;
+ }
+
+ fsc = alloc_fsc();
+ if (fsc == NULL)
+ return;
+ fsc->number = syscall_num;
+ fsc->name = (syscall_num < 0 || syscall_num >= nsyscalls) ?
+ NULL : syscallnames[syscall_num];
+ if (!fsc->name) {
+ fprintf(trussinfo->outfile, "-- UNKNOWN SYSCALL %d --\n",
+ syscall_num);
+ }
+
+ if (fsc->name && (trussinfo->flags & FOLLOWFORKS) &&
+ (strcmp(fsc->name, "fork") == 0 ||
+ strcmp(fsc->name, "rfork") == 0 ||
+ strcmp(fsc->name, "vfork") == 0))
+ trussinfo->curthread->in_fork = 1;
+
+ if (nargs == 0)
+ return;
+
+ fsc->args = malloc((1 + nargs) * sizeof(unsigned long));
+ switch (nargs) {
+ default:
+ /*
+ * The OS doesn't seem to allow more than 10 words of
+ * parameters (yay!). So we shouldn't be here.
+ */
+ warn("More than 10 words (%d) of arguments!\n", nargs);
+ break;
+ case 10:
+ case 9:
+ case 8:
+ case 7:
+ case 6:
+ case 5:
+ /*
+ * If there are 7-10 words of arguments, they are placed
+ * on the stack, as is normal for other processors.
+ * The fall-through for all of these is deliberate!!!
+ */
+ // XXX BAD constant used here
+ iorequest.piod_op = PIOD_READ_D;
+ iorequest.piod_offs = (void *)(regs.r[_REG_SP] +
+ 4 * sizeof(uint32_t));
+ iorequest.piod_addr = &fsc->args[4];
+ iorequest.piod_len = (nargs - 4) * sizeof(fsc->args[0]);
+ ptrace(PT_IO, tid, (caddr_t)&iorequest, 0);
+ if (iorequest.piod_len == 0)
+ return;
+ case 4: fsc->args[3] = ap[3];
+ case 3: fsc->args[2] = ap[2];
+ case 2: fsc->args[1] = ap[1];
+ case 1: fsc->args[0] = ap[0];
+ case 0: break;
+ }
+
+ sc = NULL;
+ if (fsc->name)
+ sc = get_syscall(fsc->name);
+ if (sc)
+ fsc->nargs = sc->nargs;
+ else {
+#if DEBUG
+ fprintf(trussinfo->outfile, "unknown syscall %s -- setting "
+ "args to %d\n", fsc->name, nargs);
+#endif
+ fsc->nargs = nargs;
+ }
+
+ fsc->s_args = calloc(1, (1 + fsc->nargs) * sizeof(char *));
+ fsc->sc = sc;
+
+ /*
+ * At this point, we set up the system call arguments.
+ * We ignore any OUT ones, however -- those are arguments that
+ * are set by the system call, and so are probably meaningless
+ * now. This doesn't currently support arguments that are
+ * passed in *and* out, however.
+ */
+
+ if (fsc->name) {
+#if DEBUG
+ fprintf(stderr, "syscall %s(", fsc->name);
+#endif
+ for (i = 0; i < fsc->nargs; i++) {
+#if DEBUG
+ fprintf(stderr, "0x%x%s", sc ?
+ fsc->args[sc->args[i].offset] : fsc->args[i],
+ i < (fsc->nargs - 1) ? "," : "");
+#endif
+ if (sc && !(sc->args[i].type & OUT)) {
+ fsc->s_args[i] = print_arg(&sc->args[i],
+ fsc->args, 0, trussinfo);
+ }
+ }
+#if DEBUG
+ fprintf(stderr, ")\n");
+#endif
+ }
+
+#if DEBUG
+ fprintf(trussinfo->outfile, "\n");
+#endif
+
+ if (fsc->name != NULL && (strcmp(fsc->name, "execve") == 0 ||
+ strcmp(fsc->name, "exit") == 0)) {
+ /*
+ * XXX
+ * This could be done in a more general
+ * manner but it still wouldn't be very pretty.
+ */
+ if (strcmp(fsc->name, "execve") == 0) {
+ if ((trussinfo->flags & EXECVEARGS) == 0) {
+ if (fsc->s_args[1]) {
+ free(fsc->s_args[1]);
+ fsc->s_args[1] = NULL;
+ }
+ }
+ if ((trussinfo->flags & EXECVEENVS) == 0) {
+ if (fsc->s_args[2]) {
+ free(fsc->s_args[2]);
+ fsc->s_args[2] = NULL;
+ }
+ }
+ }
+ }
+ trussinfo->curthread->fsc = fsc;
+}
+
+/*
+ * And when the system call is done, we handle it here.
+ * Currently, no attempt is made to ensure that the system calls
+ * match -- this needs to be fixed (and is, in fact, why S_SCX includes
+ * the system call number instead of, say, an error status).
+ */
+
+long
+arm_syscall_exit(struct trussinfo *trussinfo, int syscall_num __unused)
+{
+ struct reg regs;
+ struct freebsd_syscall *fsc;
+ struct syscall *sc;
+ lwpid_t tid;
+ long retval;
+ int errorp, i;
+
+ if (trussinfo->curthread->fsc == NULL)
+ return (-1);
+
+ tid = trussinfo->curthread->tid;
+
+ if (ptrace(PT_GETREGS, tid, (caddr_t)&regs, 0) < 0) {
+ fprintf(trussinfo->outfile, "-- CANNOT READ REGISTERS --\n");
+ return (-1);
+ }
+
+ retval = regs.r[0];
+ errorp = !!(regs.r_cpsr & PSR_C_bit);
+
+ /*
+ * This code, while simpler than the initial versions I used, could
+ * stand some significant cleaning.
+ */
+
+ fsc = trussinfo->curthread->fsc;
+ sc = fsc->sc;
+ if (!sc) {
+ for (i = 0; i < fsc->nargs; i++)
+ asprintf(&fsc->s_args[i], "0x%lx", fsc->args[i]);
+ } else {
+ /*
+ * Here, we only look for arguments that have OUT masked in --
+ * otherwise, they were handled in the syscall_entry function.
+ */
+ for (i = 0; i < sc->nargs; i++) {
+ char *temp;
+ if (sc->args[i].type & OUT) {
+ /*
+ * If an error occurred, then don't bother
+ * getting the data; it may not be valid.
+ */
+ if (errorp) {
+ asprintf(&temp, "0x%lx",
+ fsc->args[sc->args[i].offset]);
+ } else {
+ temp = print_arg(&sc->args[i],
+ fsc->args, retval, trussinfo);
+ }
+ fsc->s_args[i] = temp;
+ }
+ }
+ }
+
+ if (fsc->name != NULL && (strcmp(fsc->name, "execve") == 0 ||
+ strcmp(fsc->name, "exit") == 0))
+ trussinfo->curthread->in_syscall = 1;
+
+ /*
+ * It would probably be a good idea to merge the error handling,
+ * but that complicates things considerably.
+ */
+
+ print_syscall_ret(trussinfo, fsc->name, fsc->nargs, fsc->s_args, errorp,
+ retval, fsc->sc);
+ free_fsc(fsc);
+
+ return (retval);
+}
diff --git a/usr.bin/truss/extern.h b/usr.bin/truss/extern.h
index f89582a..c60c6c7 100644
--- a/usr.bin/truss/extern.h
+++ b/usr.bin/truss/extern.h
@@ -37,6 +37,10 @@ extern void restore_proc(int);
extern void waitevent(struct trussinfo *);
extern const char *ioctlname(unsigned long val);
extern char *strsig(int sig);
+#ifdef __arm__
+extern void arm_syscall_entry(struct trussinfo *, int);
+extern long arm_syscall_exit(struct trussinfo *, int);
+#endif
#ifdef __amd64__
extern void amd64_syscall_entry(struct trussinfo *, int);
extern long amd64_syscall_exit(struct trussinfo *, int);
diff --git a/usr.bin/truss/main.c b/usr.bin/truss/main.c
index 4e9f74b..ecaa0db 100644
--- a/usr.bin/truss/main.c
+++ b/usr.bin/truss/main.c
@@ -79,6 +79,9 @@ static struct ex_types {
void (*enter_syscall)(struct trussinfo *, int);
long (*exit_syscall)(struct trussinfo *, int);
} ex_types[] = {
+#ifdef __arm__
+ { "FreeBSD ELF32", arm_syscall_entry, arm_syscall_exit },
+#endif
#ifdef __amd64__
{ "FreeBSD ELF64", amd64_syscall_entry, amd64_syscall_exit },
{ "FreeBSD ELF32", amd64_fbsd32_syscall_entry, amd64_fbsd32_syscall_exit },
diff --git a/usr.sbin/bhyve/acpi.c b/usr.sbin/bhyve/acpi.c
index cabe75e..f9504f8 100644
--- a/usr.sbin/bhyve/acpi.c
+++ b/usr.sbin/bhyve/acpi.c
@@ -687,12 +687,16 @@ basl_load(int fd, uint64_t off)
int err;
err = 0;
- gaddr = paddr_guest2host(basl_acpi_base + off, sb.st_size);
- if (gaddr != NULL) {
- if (fstat(fd, &sb) < 0 || read(fd, gaddr, sb.st_size) < 0)
- err = errno;
- } else
- err = EFAULT;
+ if (fstat(fd, &sb) < 0) {
+ err = errno;
+ } else {
+ gaddr = paddr_guest2host(basl_acpi_base + off, sb.st_size);
+ if (gaddr != NULL) {
+ if (read(fd, gaddr, sb.st_size) < 0)
+ err = errno;
+ } else
+ err = EFAULT;
+ }
return (err);
}
diff --git a/usr.sbin/bhyve/pci_virtio_block.c b/usr.sbin/bhyve/pci_virtio_block.c
index 31ff2e6..0c34666 100644
--- a/usr.sbin/bhyve/pci_virtio_block.c
+++ b/usr.sbin/bhyve/pci_virtio_block.c
@@ -164,14 +164,19 @@ pci_vtblk_iosize(struct pci_devinst *pi)
static int
hq_num_avail(struct vring_hqueue *hq)
{
- int ndesc;
+ uint16_t ndesc;
- if (*hq->hq_avail_idx >= hq->hq_cur_aidx)
- ndesc = *hq->hq_avail_idx - hq->hq_cur_aidx;
- else
- ndesc = UINT16_MAX - hq->hq_cur_aidx + *hq->hq_avail_idx + 1;
+ /*
+ * We're just computing (a-b) in GF(216).
+ *
+ * The only glitch here is that in standard C,
+ * uint16_t promotes to (signed) int when int has
+ * more than 16 bits (pretty much always now), so
+ * we have to force it back to unsigned.
+ */
+ ndesc = (unsigned)*hq->hq_avail_idx - (unsigned)hq->hq_cur_aidx;
- assert(ndesc >= 0 && ndesc <= hq->hq_size);
+ assert(ndesc <= hq->hq_size);
return (ndesc);
}
diff --git a/usr.sbin/bhyve/pci_virtio_net.c b/usr.sbin/bhyve/pci_virtio_net.c
index a5cf8b3..11647d6 100644
--- a/usr.sbin/bhyve/pci_virtio_net.c
+++ b/usr.sbin/bhyve/pci_virtio_net.c
@@ -172,12 +172,17 @@ hq_num_avail(struct vring_hqueue *hq)
{
int ndesc;
- if (*hq->hq_avail_idx >= hq->hq_cur_aidx)
- ndesc = *hq->hq_avail_idx - hq->hq_cur_aidx;
- else
- ndesc = UINT16_MAX - hq->hq_cur_aidx + *hq->hq_avail_idx + 1;
+ /*
+ * We're just computing (a-b) in GF(216).
+ *
+ * The only glitch here is that in standard C,
+ * uint16_t promotes to (signed) int when int has
+ * more than 16 bits (pretty much always now), so
+ * we have to force it back to unsigned.
+ */
+ ndesc = (unsigned)*hq->hq_avail_idx - (unsigned)hq->hq_cur_aidx;
- assert(ndesc >= 0 && ndesc <= hq->hq_size);
+ assert(ndesc <= hq->hq_size);
return (ndesc);
}
diff --git a/usr.sbin/mount_portalfs/Makefile b/usr.sbin/mount_portalfs/Makefile
deleted file mode 100644
index 991a36f..0000000
--- a/usr.sbin/mount_portalfs/Makefile
+++ /dev/null
@@ -1,15 +0,0 @@
-# From: @(#)Makefile 8.3 (Berkeley) 3/27/94
-# $FreeBSD$
-
-PROG= mount_portalfs
-SRCS= mount_portalfs.c activate.c conf.c cred.c getmntopts.c pt_conf.c \
- pt_exec.c pt_file.c pt_pipe.c pt_tcp.c pt_tcplisten.c
-MAN= mount_portalfs.8
-
-MOUNT= ${.CURDIR}/../../sbin/mount
-CFLAGS+=-I${MOUNT}
-WARNS?= 3
-
-.PATH: ${MOUNT}
-
-.include <bsd.prog.mk>
diff --git a/usr.sbin/mount_portalfs/activate.c b/usr.sbin/mount_portalfs/activate.c
deleted file mode 100644
index 7d35d48..0000000
--- a/usr.sbin/mount_portalfs/activate.c
+++ /dev/null
@@ -1,195 +0,0 @@
-/*
- * Copyright (c) 1992, 1993
- * The Regents of the University of California. All rights reserved.
- * All rights reserved.
- *
- * This code is derived from software donated to Berkeley by
- * Jan-Simon Pendry.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * @(#)activate.c 8.3 (Berkeley) 4/28/95
- */
-
-#include <sys/cdefs.h>
-__FBSDID("$FreeBSD$");
-
-#include <errno.h>
-#include <string.h>
-#include <unistd.h>
-#include <sys/types.h>
-#include <sys/param.h>
-#include <sys/socket.h>
-#include <sys/syslog.h>
-#include <sys/uio.h>
-
-#include "portald.h"
-
-/*
- * Scan the providers list and call the
- * appropriate function.
- */
-static int activate_argv(struct portal_cred *pcr, char *key, char **v, int so,
- int *fdp)
-{
- provider *pr;
-
- for (pr = providers; pr->pr_match; pr++)
- if (strcmp(v[0], pr->pr_match) == 0)
- return ((*pr->pr_func)(pcr, key, v, so, fdp));
-
- return (ENOENT);
-}
-
-static int get_request(int so, struct portal_cred *pcr, char *key, int klen)
-{
- struct iovec iov[2];
- struct msghdr msg;
- int n;
-
- iov[0].iov_base = (caddr_t) pcr;
- iov[0].iov_len = sizeof(*pcr);
- iov[1].iov_base = key;
- iov[1].iov_len = klen;
-
- memset(&msg, 0, sizeof(msg));
- msg.msg_iov = iov;
- msg.msg_iovlen = 2;
-
- n = recvmsg(so, &msg, 0);
- if (n < 0)
- return (errno);
-
- if (n <= (int)sizeof(*pcr))
- return (EINVAL);
-
- n -= sizeof(*pcr);
- key[n] = '\0';
-
- return (0);
-}
-
-static void send_reply(int so, int fd, int error)
-{
- int n;
- struct iovec iov;
- struct msghdr msg;
- union {
- struct cmsghdr cmsg;
- char control[CMSG_SPACE(sizeof(int))];
- } ctl;
-
- /*
- * Line up error code. Don't worry about byte ordering
- * because we must be sending to the local machine.
- */
- iov.iov_base = (caddr_t) &error;
- iov.iov_len = sizeof(error);
-
- /*
- * Build a msghdr
- */
- memset(&msg, 0, sizeof(msg));
- msg.msg_iov = &iov;
- msg.msg_iovlen = 1;
-
- /*
- * If there is a file descriptor to send then
- * construct a suitable rights control message.
- */
- if (fd >= 0) {
- ctl.cmsg.cmsg_len = CMSG_LEN(sizeof(int));
- ctl.cmsg.cmsg_level = SOL_SOCKET;
- ctl.cmsg.cmsg_type = SCM_RIGHTS;
- *((int *)CMSG_DATA(&ctl.cmsg)) = fd;
- msg.msg_control = (caddr_t) &ctl;
- msg.msg_controllen = ctl.cmsg.cmsg_len;
- }
-
- /*
- * Send to kernel...
- */
- if ((n = sendmsg(so, &msg, 0)) < 0)
- syslog(LOG_ERR, "send: %s", strerror(errno));
-#ifdef DEBUG
- fprintf(stderr, "sent %d bytes\n", n);
-#endif
- sleep(1); /*XXX*/
-#ifdef notdef
- if (shutdown(so, SHUT_RDWR) < 0)
- syslog(LOG_ERR, "shutdown: %s", strerror(errno));
-#endif
- /*
- * Throw away the open file descriptor
- */
- (void) close(fd);
-}
-
-void activate(qelem *q, int so)
-{
- struct portal_cred pcred;
- char key[MAXPATHLEN+1];
- int error;
- char **v;
- int fd = -1;
-
- /*
- * Read the key from the socket
- */
- error = get_request(so, &pcred, key, sizeof(key));
- if (error) {
- syslog(LOG_ERR, "activate: recvmsg: %s", strerror(error));
- goto drop;
- }
-
-#ifdef DEBUG
- fprintf(stderr, "lookup key %s\n", key);
-#endif
-
- /*
- * Find a match in the configuration file
- */
- v = conf_match(q, key);
-
- /*
- * If a match existed, then find an appropriate portal
- * otherwise simply return ENOENT.
- */
- if (v) {
- error = activate_argv(&pcred, key, v, so, &fd);
- if (error)
- fd = -1;
- else if (fd < 0)
- error = -1;
- } else {
- error = ENOENT;
- }
-
- if (error >= 0)
- send_reply(so, fd, error);
-
-drop:;
- close(so);
-}
diff --git a/usr.sbin/mount_portalfs/conf.c b/usr.sbin/mount_portalfs/conf.c
deleted file mode 100644
index f6b34bd..0000000
--- a/usr.sbin/mount_portalfs/conf.c
+++ /dev/null
@@ -1,318 +0,0 @@
-/*
- * Copyright (c) 1992, 1993
- * The Regents of the University of California. All rights reserved.
- * All rights reserved.
- *
- * This code is derived from software donated to Berkeley by
- * Jan-Simon Pendry.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * @(#)conf.c 8.2 (Berkeley) 3/27/94
- */
-
-#include <sys/cdefs.h>
-__FBSDID("$FreeBSD$");
-
-#include <errno.h>
-#include <limits.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <unistd.h>
-#include <regex.h>
-#include <sys/types.h>
-#include <sys/param.h>
-#include <sys/syslog.h>
-
-#include "portald.h"
-
-#define ALLOC(ty) (xmalloc(sizeof(ty)))
-
-typedef struct path path;
-struct path {
- qelem p_q; /* 2-way linked list */
- int p_lno; /* Line number of this record */
- char *p_args; /* copy of arg string (malloc) */
- char *p_key; /* Pathname to match (also p_argv[0]) */
- regex_t p_rx; /* RE to match against pathname () */
- int p_rxvalid; /* non-zero if valid regular expression */
- int p_argc; /* number of elements in arg string */
- char **p_argv; /* argv[] pointers into arg string (malloc) */
-};
-
-static char *conf_file; /* XXX for regerror */
-static path *curp; /* XXX for regerror */
-
-/*
- * Add an element to a 2-way list,
- * just after (pred)
- */
-static void ins_que(qelem *elem, qelem *pred)
-{
- qelem *p = pred->q_forw;
- elem->q_back = pred;
- elem->q_forw = p;
- pred->q_forw = elem;
- p->q_back = elem;
-}
-
-/*
- * Remove an element from a 2-way list
- */
-static void rem_que(qelem *elem)
-{
- qelem *p = elem->q_forw;
- qelem *p2 = elem->q_back;
- p2->q_forw = p;
- p->q_back = p2;
-}
-
-/*
- * Error checking malloc
- */
-static void *xmalloc(unsigned siz)
-{
- void *p = malloc(siz);
- if (p)
- return (p);
- syslog(LOG_ALERT, "malloc: failed to get %d bytes", siz);
- exit(1);
-}
-
-/*
- * Insert the path in the list.
- * If there is already an element with the same key then
- * the *second* one is ignored (return 0). If the key is
- * not found then the path is added to the end of the list
- * and 1 is returned.
- */
-static int pinsert(path *p0, qelem *q0)
-{
- qelem *q;
-
- if (p0->p_argc == 0)
- return (0);
-
- for (q = q0->q_forw; q != q0; q = q->q_forw) {
- path *p = (path *) q;
- if (strcmp(p->p_key, p0->p_key) == 0)
- return (0);
- }
- ins_que(&p0->p_q, q0->q_back);
- return (1);
-
-}
-
-static path *palloc(char *cline, int lno)
-{
- int c;
- char *s;
- char *key;
- path *p;
- char **ap;
-
- /*
- * Implement comment chars
- */
- s = strchr(cline, '#');
- if (s)
- *s = 0;
-
- /*
- * Do a pass through the string to count the number
- * of arguments
- */
- c = 0;
- key = strdup(cline);
- for (s = key; s != NULL; ) {
- char *val;
- while ((val = strsep(&s, " \t\n")) != NULL && *val == '\0')
- ;
- if (val)
- c++;
- }
- c++;
- free(key);
-
- if (c <= 1)
- return (0);
-
- /*
- * Now do another pass and generate a new path structure
- */
- p = ALLOC(path);
- p->p_argc = 0;
- p->p_argv = xmalloc(c * sizeof(char *));
- p->p_args = strdup(cline);
- ap = p->p_argv;
- for (s = p->p_args; s != NULL; ) {
- char *val;
- while ((val = strsep(&s, " \t\n")) != NULL && *val == '\0')
- ;
- if (val) {
- *ap++ = val;
- p->p_argc++;
- }
- }
- *ap = 0;
-
-#ifdef DEBUG
- for (c = 0; c < p->p_argc; c++)
- printf("%sv[%d] = %s\n", c?"\t":"", c, p->p_argv[c]);
-#endif
-
- p->p_key = p->p_argv[0];
- if (strpbrk(p->p_key, RE_CHARS)) {
- int val;
-
- curp = p; /* XXX */
- val = regcomp(&p->p_rx, p->p_key, REG_EXTENDED | REG_NOSUB);
- if (val) {
- char errbuf[_POSIX2_LINE_MAX];
- regerror(val, &p->p_rx, errbuf, sizeof errbuf);
- syslog(LOG_ERR, "%s:%d: regcomp %s: %s",
- conf_file, curp->p_lno, curp->p_key, errbuf);
- regfree(&p->p_rx);
- p->p_rxvalid = 0;
- } else {
- p->p_rxvalid = 1;
- }
- curp = 0; /* XXX */
- } else {
- p->p_rxvalid = 0;
- }
- p->p_lno = lno;
-
- return (p);
-}
-
-/*
- * Free a path structure
- */
-static void pfree(path *p)
-{
- free(p->p_args);
- if (p->p_rxvalid) {
- regfree(&p->p_rx);
- }
- free((char *) p->p_argv);
- free((char *) p);
-}
-
-/*
- * Discard all currently held path structures on q0.
- * and add all the ones on xq.
- */
-static void preplace(qelem *q0, qelem *xq)
-{
- /*
- * While the list is not empty,
- * take the first element off the list
- * and free it.
- */
- while (q0->q_forw != q0) {
- qelem *q = q0->q_forw;
- rem_que(q);
- pfree((path *) q);
- }
- while (xq->q_forw != xq) {
- qelem *q = xq->q_forw;
- rem_que(q);
- ins_que(q, q0);
- }
-}
-
-/*
- * Read the lines from the configuration file and
- * add them to the list of paths.
- */
-static void readfp(qelem *q0, FILE *fp)
-{
- char cline[LINE_MAX];
- int nread = 0;
- qelem q;
-
- /*
- * Make a new empty list.
- */
- q.q_forw = q.q_back = &q;
-
- /*
- * Read the lines from the configuration file.
- */
- while (fgets(cline, sizeof(cline), fp)) {
- path *p = palloc(cline, nread+1);
- if (p && !pinsert(p, &q))
- pfree(p);
- nread++;
- }
-
- /*
- * If some records were read, then throw
- * away the old list and replace with the
- * new one.
- */
- if (nread)
- preplace(q0, &q);
-}
-
-/*
- * Read the configuration file (conf) and replace
- * the existing path list with the new version.
- * If the file is not readable, then no changes take place
- */
-void conf_read(qelem *q, char *conf)
-{
- FILE *fp = fopen(conf, "r");
- if (fp) {
- conf_file = conf; /* XXX */
- readfp(q, fp);
- conf_file = 0; /* XXX */
- (void) fclose(fp);
- } else {
- syslog(LOG_ERR, "open config file \"%s\": %s", conf, strerror(errno));
- }
-}
-
-
-char **conf_match(qelem *q0, char *key)
-{
- qelem *q;
-
- for (q = q0->q_forw; q != q0; q = q->q_forw) {
- path *p = (path *) q;
- if (p->p_rxvalid) {
- if (!regexec(&p->p_rx, key, 0, 0, 0)) {
- return p->p_argv + 1;
- }
- } else {
- if (strncmp(p->p_key, key, strlen(p->p_key)) == 0)
- return (p->p_argv+1);
- }
- }
-
- return (0);
-}
diff --git a/usr.sbin/mount_portalfs/cred.c b/usr.sbin/mount_portalfs/cred.c
deleted file mode 100644
index 2bd3623..0000000
--- a/usr.sbin/mount_portalfs/cred.c
+++ /dev/null
@@ -1,75 +0,0 @@
-/*-
- * Copyright (C) 2005 Diomidis Spinellis. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY AUTHOR AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- */
-
-#include <sys/cdefs.h>
-__FBSDID("$FreeBSD$");
-
-#include <errno.h>
-#include <stdlib.h>
-#include <unistd.h>
-
-#include <sys/types.h>
-#include <sys/param.h>
-#include <sys/syslog.h>
-
-#include "portald.h"
-
-/*
- * Set the process's credentials to those specified in user,
- * saving the existing ones in save.
- * Return 0 on success, -1 (with errno set) on error.
- */
-int
-set_user_credentials(struct portal_cred *user, struct portal_cred *save)
-{
- save->pcr_uid = geteuid();
- if ((save->pcr_ngroups = getgroups(NGROUPS_MAX, save->pcr_groups)) < 0)
- return (-1);
- if (setgroups(user->pcr_ngroups, user->pcr_groups) < 0)
- return (-1);
- if (seteuid(user->pcr_uid) < 0)
- return (-1);
- return (0);
-}
-
-/*
- * Restore the process's credentials to the ones specified in save.
- * Log failures using LOG_ERR.
- * Return 0 on success, -1 (with errno set) on error.
- */
-int
-restore_credentials(struct portal_cred *save)
-{
- if (seteuid(save->pcr_uid) < 0) {
- syslog(LOG_ERR, "seteuid: %m");
- return (-1);
- }
- if (setgroups(save->pcr_ngroups, save->pcr_groups) < 0) {
- syslog(LOG_ERR, "setgroups: %m");
- return (-1);
- }
- return (0);
-}
diff --git a/usr.sbin/mount_portalfs/mount_portalfs.8 b/usr.sbin/mount_portalfs/mount_portalfs.8
deleted file mode 100644
index b6ca9cc..0000000
--- a/usr.sbin/mount_portalfs/mount_portalfs.8
+++ /dev/null
@@ -1,216 +0,0 @@
-.\"
-.\" Copyright (c) 1993, 1994
-.\" The Regents of the University of California. All rights reserved.
-.\" All rights reserved.
-.\"
-.\" This code is derived from software donated to Berkeley by
-.\" Jan-Simon Pendry.
-.\"
-.\" Redistribution and use in source and binary forms, with or without
-.\" modification, are permitted provided that the following conditions
-.\" are met:
-.\" 1. Redistributions of source code must retain the above copyright
-.\" notice, this list of conditions and the following disclaimer.
-.\" 2. Redistributions in binary form must reproduce the above copyright
-.\" notice, this list of conditions and the following disclaimer in the
-.\" documentation and/or other materials provided with the distribution.
-.\" 4. Neither the name of the University nor the names of its contributors
-.\" may be used to endorse or promote products derived from this software
-.\" without specific prior written permission.
-.\"
-.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
-.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
-.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
-.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
-.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
-.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
-.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
-.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
-.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
-.\" SUCH DAMAGE.
-.\"
-.\" @(#)mount_portal.8 8.3 (Berkeley) 3/27/94
-.\" $FreeBSD$
-.\"
-.Dd March 11, 2005
-.Dt MOUNT_PORTALFS 8
-.Os
-.Sh NAME
-.Nm mount_portalfs
-.Nd mount the portal daemon
-.Sh SYNOPSIS
-.Nm
-.Op Fl o Ar options
-.Ar /etc/portal.conf
-.Ar mount_point
-.Sh DESCRIPTION
-The
-.Nm
-utility attaches an instance of the portal daemon
-to the global file system namespace.
-The conventional mount point is
-.Pa /p .
-.\" .PA /dev .
-This command is normally executed by
-.Xr mount 8
-at boot time.
-.Pp
-The options are as follows:
-.Bl -tag -width indent
-.It Fl o
-Options are specified with a
-.Fl o
-flag followed by a comma separated string of options.
-See the
-.Xr mount 8
-man page for possible options and their meanings.
-.El
-.Pp
-The portal daemon provides an
-.Em open
-service.
-Objects opened under the portal mount point are
-dynamically created by the portal daemon according
-to rules specified in the named configuration file.
-Using this mechanism allows descriptors such as sockets
-to be made available in the file system namespace.
-.Pp
-The portal daemon works by being passed the full pathname
-of the object being opened.
-The daemon creates an appropriate descriptor according
-to the rules in the configuration file, and then passes the descriptor back
-to the calling process as the result of the open system call.
-.Sh NAMESPACE
-By convention, the portal daemon divides the namespace into sub-namespaces,
-each of which handles objects of a particular type.
-.Pp
-The following sub-namespaces are currently implemented:
-.Pa fs ,
-.Pa pipe ,
-.Pa tcp ,
-and
-.Pa tcplisten .
-.Pp
-The
-.Pa fs
-namespace opens the named file, starting back at the root directory.
-This can be used to provide a controlled escape path from
-a chrooted environment.
-.Pp
-The
-.Pa pipe
-namespace executes the named command, starting back at the root directory.
-The command's arguments can be provided after the command's name,
-by separating them with spaces or tabs.
-Files opened for reading in the
-.Pa pipe
-namespace will receive their input from the command's standard output;
-files opened for writing will send the data of write operations
-to the command's standard input.
-.Pp
-The
-.Pa tcp
-namespace takes a slash separated hostname and a port and
-creates an open TCP/IP connection.
-.Pp
-The
-.Pa tcplisten
-namespace takes a slash separated hostname and port and creates a TCP/IP
-socket bound to the given hostname-port pair.
-The hostname may be
-specified as "ANY" to allow any other host to connect to the socket.
-A
-port number of 0 will dynamically allocate a port, this can be
-discovered by calling
-.Xr getsockname 2
-with the returned file descriptor.
-Privileged ports can only be bound to
-by the super-user.
-.Sh "CONFIGURATION FILE"
-The configuration file contains a list of rules.
-Each rule takes one line and consists of two or more
-whitespace separated fields.
-A hash (``#'') character causes the remainder of a line to
-be ignored.
-Blank lines are ignored.
-.Pp
-The first field is a pathname prefix to match
-against the requested pathname.
-If a match is found, the second field
-tells the daemon what type of object to create.
-Subsequent fields are passed to the creation function.
-.Bd -literal
-# @(#)portal.conf 5.1 (Berkeley) 7/13/92
-tcplisten/ tcplisten tcplisten/
-tcp/ tcp tcp/
-fs/ file fs/
-pipe/ pipe pipe/
-.Ed
-.Sh FILES
-.Bl -tag -width /p/* -compact
-.It Pa /p/*
-.El
-.Sh EXAMPLES
-Display the greeting of the
-.Fx
-.Tn SMTP
-server.
-.Pp
-.Dl "head -1 /p/tcp/mx1.freebsd.org/smtp"
-.Pp
-Implement a (single-threaded) echo server:
-.Bd -literal -offset indent
-while :
-do
- (exec 3<>/p/tcplisten/ANY/echo && cat -u <&3 >&3)
-done
-.Ed
-.Pp
-Gather data from two sources.
-Verify that two remote files are identical:
-.Bd -literal -offset indent
-diff -q '/p/pipe/usr/bin/fetch -o - \\
- ftp://ftp1.freebsd.org/pub/FreeBSD/README.TXT' \\
- '/p/pipe/usr/bin/fetch -o - \\
- ftp://ftp2.freebsd.org/pub/FreeBSD/README.TXT'
-.Ed
-.Pp
-Scatter data to two sinks.
-Record a remote
-.Tn CD
-.Tn ISO
-image and calculate its checksum:
-.Bd -literal -offset indent
-fetch -o - ftp://ftp5.freebsd.org/.../disc.iso |
-tee '/p/pipe/usr/local/bin/cdrecord -' |
-md5
-.Ed
-.Pp
-Create an
-.Tn XML
-view of the password file:
-.Bd -literal -offset indent
-ln -s '/p/pipe/usr/local/bin/passwd2xml /etc/passwd' \\
- /etc/passwd.xml"
-.Ed
-.Sh SEE ALSO
-.Xr mount 2 ,
-.Xr unmount 2 ,
-.Xr fstab 5 ,
-.Xr mount 8
-.Rs
-.%A "W. Richard Stevens"
-.%A "Jan-Simon Pendry"
-.%T "Portals in 4.4BSD"
-.%B "USENIX 1995 Technical Conference Proceedings"
-.%O "Berkeley, CA"
-.%I "Peter Honeyman"
-.Re
-.Sh HISTORY
-The
-.Nm
-utility first appeared in
-.Bx 4.4 .
-.Sh CAVEATS
-This file system may not be NFS-exported.
diff --git a/usr.sbin/mount_portalfs/mount_portalfs.c b/usr.sbin/mount_portalfs/mount_portalfs.c
deleted file mode 100644
index 3bffbb1..0000000
--- a/usr.sbin/mount_portalfs/mount_portalfs.c
+++ /dev/null
@@ -1,281 +0,0 @@
-/*
- * Copyright (c) 1992, 1993, 1994
- * The Regents of the University of California. All rights reserved.
- *
- * This code is derived from software donated to Berkeley by
- * Jan-Simon Pendry.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-#ifndef lint
-static const char copyright[] =
-"@(#) Copyright (c) 1992, 1993, 1994\n\
- The Regents of the University of California. All rights reserved.\n";
-#endif /* not lint */
-
-#if 0
-static char sccsid[] = "@(#)mount_portal.c 8.6 (Berkeley) 4/26/95";
-#endif
-
-#include <sys/cdefs.h>
-__FBSDID("$FreeBSD$");
-
-#include <sys/param.h>
-#include <sys/wait.h>
-#include <sys/socket.h>
-#include <sys/un.h>
-#include <sys/stat.h>
-#include <sys/syslog.h>
-#include <sys/mount.h>
-
-#include <err.h>
-#include <errno.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <sysexits.h>
-#include <unistd.h>
-
-#include "mntopts.h"
-#include "pathnames.h"
-#include "portald.h"
-
-struct mntopt mopts[] = {
- MOPT_STDOPTS,
- MOPT_END
-};
-
-static void usage(void) __dead2;
-
-static volatile sig_atomic_t readcf; /* Set when SIGHUP received */
-
-static void sighup(int sig __unused)
-{
- readcf ++;
-}
-
-static void sigchld(int sig __unused)
-{
- pid_t pid;
-
- while ((pid = waitpid((pid_t) -1, (int *) 0, WNOHANG)) > 0)
- ;
- /* wrtp - waitpid _doesn't_ return 0 when no children! */
-#ifdef notdef
- if (pid < 0 && errno != ECHILD)
- syslog(LOG_WARNING, "waitpid: %s", strerror(errno));
-#endif
-}
-
-int
-main(int argc, char *argv[])
-{
- struct portal_args args;
- struct sockaddr_un un;
- char *conf;
- char mountpt[MAXPATHLEN];
- int mntflags = 0;
- char tag[32];
- mode_t um;
-
- qelem q;
- int rc;
- int so;
- int error = 0;
-
- /*
- * Crack command line args
- */
- int ch;
-
- while ((ch = getopt(argc, argv, "o:")) != -1) {
- switch (ch) {
- case 'o':
- getmntopts(optarg, mopts, &mntflags, 0);
- break;
- default:
- error = 1;
- break;
- }
- }
-
- if (optind != (argc - 2))
- error = 1;
-
- if (error)
- usage();
-
- /*
- * Get config file and mount point
- */
- conf = argv[optind];
- if (conf[0] != '/') {
- (void)fprintf(stderr,
- "The configuration file must be specified"
- "through an absolute file path.\n");
- exit(EX_USAGE);
- }
-
- /* resolve the mountpoint with realpath(3) */
- if (checkpath(argv[optind+1], mountpt) != 0)
- err(EX_USAGE, "%s", mountpt);
-
- /*
- * Construct the listening socket
- */
- un.sun_family = AF_UNIX;
- if (sizeof(_PATH_TMPPORTAL) >= sizeof(un.sun_path)) {
- errx(EX_SOFTWARE, "portal socket name too long");
- }
- strcpy(un.sun_path, _PATH_TMPPORTAL);
- mktemp(un.sun_path);
- un.sun_len = strlen(un.sun_path);
-
- so = socket(AF_UNIX, SOCK_STREAM, 0);
- if (so < 0) {
- err(EX_OSERR, "socket");
- }
- um = umask(077);
- (void) unlink(un.sun_path);
- if (bind(so, (struct sockaddr *) &un, sizeof(un)) < 0)
- err(1, NULL);
-
- (void) unlink(un.sun_path);
- (void) umask(um);
-
- (void) listen(so, 5);
-
- args.pa_socket = so;
- sprintf(tag, "portal:%d", getpid());
- args.pa_config = tag;
-
- rc = mount("portalfs", mountpt, mntflags, &args);
- if (rc < 0)
- err(1, NULL);
-
- /*
- * Everything is ready to go - now is a good time to fork
- */
-#ifndef DEBUG
- daemon(0, 0);
-#endif
-
- /*
- * Start logging (and change name)
- */
- openlog("portald", LOG_CONS|LOG_PID, LOG_DAEMON);
-
- q.q_forw = q.q_back = &q;
- readcf = 1;
-
- signal(SIGCHLD, sigchld);
- signal(SIGHUP, sighup);
-
- /*
- * Just loop waiting for new connections and activating them
- */
- for (;;) {
- struct sockaddr_un un2;
- int len2 = sizeof(un2);
- int so2;
- pid_t pid;
- fd_set fdset;
-
- /*
- * Check whether we need to re-read the configuration file
- */
- if (readcf) {
-#ifdef DEBUG
- printf ("re-reading configuration file\n");
-#endif
- readcf = 0;
- conf_read(&q, conf);
- continue;
- }
-
- /*
- * Accept a new connection
- * Will get EINTR if a signal has arrived, so just
- * ignore that error code
- */
- FD_ZERO(&fdset);
- FD_SET(so, &fdset);
- rc = select(so+1, &fdset, (fd_set *) 0, (fd_set *) 0, (struct timeval *) 0);
- if (rc < 0) {
- if (errno == EINTR)
- continue;
- syslog(LOG_ERR, "select: %s", strerror(errno));
- exit(EX_OSERR);
- }
- if (rc == 0)
- break;
- so2 = accept(so, (struct sockaddr *) &un2, &len2);
- if (so2 < 0) {
- /*
- * The unmount function does a shutdown on the socket
- * which will generated ECONNABORTED on the accept.
- */
- if (errno == ECONNABORTED)
- break;
- if (errno != EINTR) {
- syslog(LOG_ERR, "accept: %s", strerror(errno));
- exit(EX_OSERR);
- }
- continue;
- }
-
- /*
- * Now fork a new child to deal with the connection
- */
- eagain:;
- switch (pid = fork()) {
- case -1:
- if (errno == EAGAIN) {
- sleep(1);
- goto eagain;
- }
- syslog(LOG_ERR, "fork: %s", strerror(errno));
- break;
- case 0:
- (void) close(so);
- activate(&q, so2);
- exit(0);
- default:
- (void) close(so2);
- break;
- }
- }
- syslog(LOG_INFO, "%s unmounted", mountpt);
- exit(0);
-}
-
-static void
-usage(void)
-{
- (void)fprintf(stderr,
- "usage: mount_portalfs [-o options] config mount-point\n");
- exit(EX_USAGE);
-}
diff --git a/usr.sbin/mount_portalfs/pathnames.h b/usr.sbin/mount_portalfs/pathnames.h
deleted file mode 100644
index 9373c7d..0000000
--- a/usr.sbin/mount_portalfs/pathnames.h
+++ /dev/null
@@ -1,40 +0,0 @@
-/*
- * Copyright (c) 1992, 1993
- * The Regents of the University of California. All rights reserved.
- * All rights reserved.
- *
- * This code is derived from software donated to Berkeley by
- * Jan-Simon Pendry.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * @(#)pathnames.h 8.1 (Berkeley) 6/5/93
- *
- * $FreeBSD$
- */
-
-#include <paths.h>
-
-#define _PATH_TMPPORTAL "/tmp/portalXXXXXXXXXX" /* Scratch socket name */
diff --git a/usr.sbin/mount_portalfs/portal.conf b/usr.sbin/mount_portalfs/portal.conf
deleted file mode 100644
index 398cfb2..0000000
--- a/usr.sbin/mount_portalfs/portal.conf
+++ /dev/null
@@ -1,7 +0,0 @@
-# @(#)portal.conf 8.1 (Berkeley) 6/5/93
-# $FreeBSD$
-tcplisten/ tcplisten tcplisten/
-tcp/ tcp tcp/
-fs/ file fs/
-pipe/ pipe pipe/
-foo/ exec ./bar bar baz
diff --git a/usr.sbin/mount_portalfs/portald.h b/usr.sbin/mount_portalfs/portald.h
deleted file mode 100644
index 99cd5d7..0000000
--- a/usr.sbin/mount_portalfs/portald.h
+++ /dev/null
@@ -1,86 +0,0 @@
-/*
- * Copyright (c) 1992, 1993
- * The Regents of the University of California. All rights reserved.
- * All rights reserved.
- *
- * This code is derived from software donated to Berkeley by
- * Jan-Simon Pendry.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * @(#)portald.h 8.1 (Berkeley) 6/5/93
- *
- * $FreeBSD$
- */
-
-#include <sys/cdefs.h>
-#include <sys/ucred.h>
-#include <fs/portalfs/portal.h>
-
-/*
- * Meta-chars in an RE. Paths in the config file containing
- * any of these characters will be matched using regexec, other
- * paths will be prefix-matched.
- */
-#define RE_CHARS ".|()[]*+?\\^$"
-
-typedef struct qelem qelem;
-
-struct qelem {
- qelem *q_forw;
- qelem *q_back;
-};
-
-typedef struct provider provider;
-struct provider {
- const char *pr_match;
- int (*pr_func)(struct portal_cred *,
- char *key, char **v, int so, int *fdp);
-};
-extern provider providers[];
-
-/*
- * Portal providers
- */
-extern int portal_exec(struct portal_cred *,
- char *key, char **v, int so, int *fdp);
-extern int portal_file(struct portal_cred *,
- char *key, char **v, int so, int *fdp);
-extern int portal_pipe(struct portal_cred *,
- char *key, char **v, int so, int *fdp);
-extern int portal_tcp(struct portal_cred *,
- char *key, char **v, int so, int *fdp);
-extern int portal_tcplisten(struct portal_cred *,
- char *key, char **v, int so, int *fdp);
-
-/*
- * Global functions
- */
-extern void activate(qelem *q, int so);
-extern char **conf_match(qelem *q, char *key);
-extern void conf_read(qelem *q, char *conf);
-extern int set_user_credentials(struct portal_cred *user,
- struct portal_cred *save_area);
-extern int restore_credentials(struct portal_cred *save_area);
diff --git a/usr.sbin/mount_portalfs/pt_conf.c b/usr.sbin/mount_portalfs/pt_conf.c
deleted file mode 100644
index 7f1e817..0000000
--- a/usr.sbin/mount_portalfs/pt_conf.c
+++ /dev/null
@@ -1,50 +0,0 @@
-/*
- * Copyright (c) 1992, 1993
- * The Regents of the University of California. All rights reserved.
- * All rights reserved.
- *
- * This code is derived from software donated to Berkeley by
- * Jan-Simon Pendry.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * @(#)pt_conf.c 8.1 (Berkeley) 6/5/93
- */
-
-#include <sys/cdefs.h>
-__FBSDID("$FreeBSD$");
-
-#include <sys/types.h>
-#include <sys/param.h>
-#include "portald.h"
-
-provider providers[] = {
- { "exec", portal_exec },
- { "file", portal_file },
- { "pipe", portal_pipe },
- { "tcp", portal_tcp },
- { "tcplisten", portal_tcplisten },
- { 0, 0 }
-};
diff --git a/usr.sbin/mount_portalfs/pt_exec.c b/usr.sbin/mount_portalfs/pt_exec.c
deleted file mode 100644
index 86a47e9..0000000
--- a/usr.sbin/mount_portalfs/pt_exec.c
+++ /dev/null
@@ -1,50 +0,0 @@
-/*
- * Copyright (c) 1992, 1993
- * The Regents of the University of California. All rights reserved.
- * All rights reserved.
- *
- * This code is derived from software donated to Berkeley by
- * Jan-Simon Pendry.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * @(#)pt_exec.c 8.1 (Berkeley) 6/5/93
- */
-
-#include <sys/cdefs.h>
-__FBSDID("$FreeBSD$");
-
-#include <errno.h>
-#include <sys/types.h>
-#include <sys/param.h>
-
-#include "portald.h"
-
-int portal_exec(struct portal_cred *pcr __unused, char *key __unused,
- char **v __unused, int so __unused, int *fdp __unused)
-{
- return (ENOEXEC);
-}
-
diff --git a/usr.sbin/mount_portalfs/pt_file.c b/usr.sbin/mount_portalfs/pt_file.c
deleted file mode 100644
index 270f812..0000000
--- a/usr.sbin/mount_portalfs/pt_file.c
+++ /dev/null
@@ -1,91 +0,0 @@
-/*
- * Copyright (c) 1992, 1993
- * The Regents of the University of California. All rights reserved.
- * All rights reserved.
- *
- * This code is derived from software donated to Berkeley by
- * Jan-Simon Pendry.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * @(#)pt_file.c 8.3 (Berkeley) 7/3/94
- */
-
-#include <sys/cdefs.h>
-__FBSDID("$FreeBSD$");
-
-#include <errno.h>
-#include <fcntl.h>
-#include <string.h>
-#include <unistd.h>
-#include <sys/types.h>
-#include <sys/param.h>
-#include <sys/syslog.h>
-
-#include "portald.h"
-
-int portal_file(struct portal_cred *pcr,
- char *key, char **v, int so __unused, int *fdp)
-{
- int fd;
- char pbuf[MAXPATHLEN];
- int error;
- struct portal_cred save_area;
-
- pbuf[0] = '/';
- strcpy(pbuf+1, key + (v[1] ? strlen(v[1]) : 0));
-
-#ifdef DEBUG
- printf("path = %s, uid = %d, gid = %d\n", pbuf, pcr->pcr_uid, pcr->pcr_groups[0]);
- printf ("fflag = %x, oflag = %x\n", pcr->pcr_flag, (pcr->pcr_flag)-1);
-#endif
-
- if (set_user_credentials(pcr, &save_area) < 0)
- return (errno);
-
- /* dmb convert kernel flags to oflags, see <fcntl.h> */
- fd = open(pbuf, (pcr->pcr_flag)-1, 0777);
- if (fd < 0)
- error = errno;
- else
- error = 0;
-
- if (restore_credentials(&save_area) < 0) {
- error = errno;
- if (fd >= 0) {
- (void) close(fd);
- fd = -1;
- }
- }
-
- if (error == 0)
- *fdp = fd;
-
-#ifdef DEBUG
- fprintf(stderr, "pt_file returns *fdp = %d, error = %d\n", *fdp, error);
-#endif
-
- return (error);
-}
diff --git a/usr.sbin/mount_portalfs/pt_pipe.c b/usr.sbin/mount_portalfs/pt_pipe.c
deleted file mode 100644
index 84ee6e4..0000000
--- a/usr.sbin/mount_portalfs/pt_pipe.c
+++ /dev/null
@@ -1,229 +0,0 @@
-/*-
- * Copyright (C) 2005 Diomidis Spinellis. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY AUTHOR AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- */
-
-#include <sys/cdefs.h>
-__FBSDID("$FreeBSD$");
-
-#include <ctype.h>
-#include <errno.h>
-#include <fcntl.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <unistd.h>
-
-#include <sys/types.h>
-#include <sys/param.h>
-#include <sys/syslog.h>
-
-#include "portald.h"
-
-/* Usage conventions for the pipe's endpoints. */
-#define READ_END 0
-#define WRITE_END 1
-
-static int errlog(void);
-static int parse_argv(char *args, char **argv);
-
-int portal_pipe(struct portal_cred *pcr, char *key, char **v,
- int kso __unused, int *fdp)
-{
- int fd[2]; /* Pipe endpoints. */
- int caller_end; /* The pipe end we will use. */
- int process_end; /* The pipe end the spawned process will use. */
- int redirect_fd; /* The fd to redirect on the spawned process. */
- char pbuf[MAXPATHLEN];
- int error = 0;
- int i;
- char **argv;
- int argc;
- struct portal_cred save_area;
-
- /* Validate open mode, and assign roles. */
- if ((pcr->pcr_flag & FWRITE) && (pcr->pcr_flag & FREAD))
- /* Don't allow both on a single fd. */
- return (EINVAL);
- else if (pcr->pcr_flag & FREAD) {
- /*
- * The caller reads from the pipe,
- * the spawned process writes to it.
- */
- caller_end = READ_END;
- process_end = WRITE_END;
- redirect_fd = STDOUT_FILENO;
- } else if (pcr->pcr_flag & FWRITE) {
- /*
- * The caller writes to the pipe,
- * the spawned process reads from it.
- */
- caller_end = WRITE_END;
- process_end = READ_END;
- redirect_fd = STDIN_FILENO;
- } else
- return (EINVAL);
-
- /* Get and check command line. */
- pbuf[0] = '/';
- strcpy(pbuf+1, key + (v[1] ? strlen(v[1]) : 0));
- argc = parse_argv(pbuf, NULL);
- if (argc == 0)
- return (ENOENT);
-
- /* Swap privileges. */
- if (set_user_credentials(pcr, &save_area) < 0)
- return (errno);
-
- /* Redirect and spawn the specified process. */
- fd[READ_END] = fd[WRITE_END] = -1;
- if (pipe(fd) < 0) {
- error = errno;
- goto done;
- }
- switch (fork()) {
- case -1: /* Error */
- error = errno;
- break;
- default: /* Parent */
- (void)close(fd[process_end]);
- break;
- case 0: /* Child */
- argv = (char **)malloc((argc + 1) * sizeof(char *));
- if (argv == 0) {
- syslog(LOG_ALERT,
- "malloc: failed to get space for %d pointers",
- argc + 1);
- exit(EXIT_FAILURE);
- }
- parse_argv(pbuf, argv);
-
- if (dup2(fd[process_end], redirect_fd) < 0) {
- syslog(LOG_ERR, "dup2: %m");
- exit(EXIT_FAILURE);
- }
- (void)close(fd[caller_end]);
- (void)close(fd[process_end]);
- if (errlog() < 0) {
- syslog(LOG_ERR, "errlog: %m");
- exit(EXIT_FAILURE);
- }
- if (execv(argv[0], argv) < 0) {
- syslog(LOG_ERR, "execv(%s): %m", argv[0]);
- exit(EXIT_FAILURE);
- }
- /* NOTREACHED */
- }
-
-done:
- /* Re-establish our privileges. */
- if (restore_credentials(&save_area) < 0)
- error = errno;
-
- /* Set return fd value. */
- if (error == 0)
- *fdp = fd[caller_end];
- else {
- for (i = 0; i < 2; i++)
- if (fd[i] >= 0)
- (void)close(fd[i]);
- *fdp = -1;
- }
-
- return (error);
-}
-
-/*
- * Redirect stderr to the system log.
- * Return 0 if ok.
- * Return -1 with errno set on error.
- */
-static int
-errlog(void)
-{
- int fd[2];
- char buff[1024];
- FILE *f;
- int ret = 0;
-
- if (pipe(fd) < 0)
- return (-1);
- switch (fork()) {
- case -1: /* Error */
- return (-1);
- case 0: /* Child */
- if ((f = fdopen(fd[READ_END], "r")) == NULL) {
- syslog(LOG_ERR, "fdopen: %m");
- exit(EXIT_FAILURE);
- }
- (void)close(fd[WRITE_END]);
- while (fgets(buff, sizeof(buff), f) != NULL)
- syslog(LOG_ERR, "exec: %s", buff);
- exit(EXIT_SUCCESS);
- /* NOTREACHED */
- default: /* Parent */
- if (dup2(fd[WRITE_END], STDERR_FILENO) < 0)
- ret = -1;
- (void)close(fd[READ_END]);
- (void)close(fd[WRITE_END]);
- break;
- }
- return (ret);
-}
-
-/*
- * Parse the args string as a space-separated argument vector.
- * If argv is not NULL, split the string into its constituent
- * components, and set argv to point to the beginning of each
- * string component; NULL-terminating argv.
- * Return the number of string components.
- */
-static int
-parse_argv(char *args, char **argv)
-{
- int count = 0;
- char *p;
- enum {WORD, SPACE} state = SPACE;
-
- for (p = args; *p; p++)
- switch (state) {
- case WORD:
- if (isspace(*p)) {
- if (argv)
- *p = '\0';
- state = SPACE;
- }
- break;
- case SPACE:
- if (!isspace(*p)) {
- if (argv)
- argv[count] = p;
- count++;
- state = WORD;
- }
- }
- if (argv)
- argv[count] = NULL;
- return (count);
-}
diff --git a/usr.sbin/mount_portalfs/pt_tcp.c b/usr.sbin/mount_portalfs/pt_tcp.c
deleted file mode 100644
index d9a2a1e..0000000
--- a/usr.sbin/mount_portalfs/pt_tcp.c
+++ /dev/null
@@ -1,157 +0,0 @@
-/*
- * Copyright (c) 1992, 1993, 1994
- * The Regents of the University of California. All rights reserved.
- * All rights reserved.
- *
- * This code is derived from software donated to Berkeley by
- * Jan-Simon Pendry.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * @(#)pt_tcp.c 8.5 (Berkeley) 4/28/95
- */
-
-#include <sys/cdefs.h>
-__FBSDID("$FreeBSD$");
-
-#include <errno.h>
-#include <stdlib.h>
-#include <string.h>
-#include <unistd.h>
-#include <sys/types.h>
-#include <sys/param.h>
-#include <sys/syslog.h>
-#include <sys/socket.h>
-#include <netinet/in.h>
-#include <arpa/inet.h>
-#include <netdb.h>
-
-#include "portald.h"
-
-/*
- * Key will be tcp/host/port[/"priv"]
- * Create a TCP socket connected to the
- * requested host and port.
- * Some trailing suffix values have special meanings.
- * An unrecognized suffix is an error.
- */
-int portal_tcp(struct portal_cred *pcr, char *key, char **v,
- int kso __unused, int *fdp)
-{
- char host[MAXHOSTNAMELEN];
- char port[MAXHOSTNAMELEN];
- char *p = key + (v[1] ? strlen(v[1]) : 0);
- char *q;
- struct hostent *hp;
- struct servent *sp;
- struct in_addr **ipp;
- struct in_addr *ip[2];
- struct in_addr ina;
- u_short s_port;
- int priv = 0;
- struct sockaddr_in sain;
-
- q = strchr(p, '/');
- if (q == 0 || q - p >= (int)sizeof(host))
- return (EINVAL);
- *q = '\0';
- strcpy(host, p);
- p = q + 1;
-
- q = strchr(p, '/');
- if (q)
- *q = '\0';
- if (strlen(p) >= sizeof(port))
- return (EINVAL);
- strcpy(port, p);
- if (q) {
- p = q + 1;
- if (strcmp(p, "priv") == 0) {
- if (pcr->pcr_uid == 0)
- priv = 1;
- else
- return (EPERM);
- } else {
- return (EINVAL);
- }
- }
-
- hp = gethostbyname(host);
- if (hp != 0) {
- ipp = (struct in_addr **) hp->h_addr_list;
- } else {
- ina.s_addr = inet_addr(host);
- if (ina.s_addr == INADDR_NONE)
- return (EINVAL);
- ip[0] = &ina;
- ip[1] = 0;
- ipp = ip;
- }
-#ifdef DEBUG
- printf ("inet address for %s is %s\n", host, inet_ntoa(*ipp[0]));
-#endif
-
- sp = getservbyname(port, "tcp");
- if (sp != NULL) {
- s_port = (u_short)sp->s_port;
- } else {
- s_port = strtoul(port, &p, 0);
- if (s_port == 0 || *p != '\0')
- return (EINVAL);
- s_port = htons(s_port);
- }
-#ifdef DEBUG
- printf ("port number for %s is %d\n", port, (int)ntohs(s_port));
-#endif
-
- memset(&sain, 0, sizeof(sain));
- sain.sin_len = sizeof(sain);
- sain.sin_family = AF_INET;
- sain.sin_port = s_port;
-
- while (ipp[0]) {
- int so;
-
- if (priv)
- so = rresvport((int *) 0);
- else
- so = socket(AF_INET, SOCK_STREAM, 0);
- if (so < 0) {
- syslog(LOG_ERR, "socket: %m");
- return (errno);
- }
-
- sain.sin_addr = *ipp[0];
- if (connect(so, (struct sockaddr *) &sain, sizeof(sain)) == 0) {
- *fdp = so;
- return (0);
- }
- (void) close(so);
-
- ipp++;
- }
-
- return (errno);
-}
diff --git a/usr.sbin/mount_portalfs/pt_tcplisten.c b/usr.sbin/mount_portalfs/pt_tcplisten.c
deleted file mode 100644
index 3bd29c1..0000000
--- a/usr.sbin/mount_portalfs/pt_tcplisten.c
+++ /dev/null
@@ -1,201 +0,0 @@
-/*
- * Copyright (c) 1992, 1993
- * The Regents of the University of California. All rights reserved.
- * All rights reserved.
- *
- * This code is derived from software donated to Berkeley by
- * Jan-Simon Pendry.
- *
- * Modified by Duncan Barclay.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * @(#)pt_tcp.c 8.3 (Berkeley) 3/27/94
- *
- * pt_tcp.c,v 1.1.1.1 1994/05/26 06:34:34 rgrimes Exp
- */
-
-#include <sys/cdefs.h>
-__FBSDID("$FreeBSD$");
-
-#include <stdio.h>
-#include <unistd.h>
-#include <stdlib.h>
-#include <errno.h>
-#include <string.h>
-#include <sys/types.h>
-#include <sys/param.h>
-#include <sys/syslog.h>
-#include <sys/socket.h>
-#include <netinet/in.h>
-#include <arpa/inet.h>
-#include <netdb.h>
-
-#include "portald.h"
-
-/*
- * Key will be tcplisten/host/port
- *
- * Create a TCP socket bound to the requested host and port.
- * If the host is "ANY" the receiving address will be set to INADDR_ANY.
- * If the port is 0 the caller must find out the returned port number
- * using a call to getsockname.
- *
- * XXX! The owner of the socket will be root rather then the user. This
- * may cause remote auth (identd) to return unexpected results.
- *
- */
-int portal_tcplisten(struct portal_cred *pcr, char *key, char **v,
- int kso __unused, int *fdp)
-{
- char host[MAXHOSTNAMELEN];
- char port[MAXHOSTNAMELEN];
- char *p = key + (v[1] ? strlen(v[1]) : 0);
- char *q;
- struct hostent *hp;
- struct servent *sp;
- struct in_addr **ipp = NULL;
- struct in_addr *ip[2];
- struct in_addr ina;
- u_short s_port;
- int any = 0;
- struct sockaddr_in sain;
-
- q = strchr(p, '/');
- if (q == 0 || q - p >= (int)sizeof(host))
- return (EINVAL);
- *q = '\0';
- snprintf(host, sizeof(host), "%s", p);
- p = q + 1;
-
- q = strchr(p, '/');
- if (q)
- *q = '\0';
- if (strlen(p) >= sizeof(port))
- return (EINVAL);
- snprintf(port, sizeof(port), "%s", p);
-
- if (strcmp(host, "ANY") == 0) {
- any = 1;
- } else {
- hp = gethostbyname(host);
- if (hp != 0) {
- ipp = (struct in_addr **) hp->h_addr_list;
- } else {
- ina.s_addr = inet_addr(host);
- if (ina.s_addr == INADDR_NONE)
- return (EINVAL);
- ip[0] = &ina;
- ip[1] = 0;
- ipp = ip;
- }
- }
-#ifdef DEBUG
- if (any)
- printf("INADDR_ANY to be used for hostname\n");
- else
- printf("inet address for %s is %s\n", host, inet_ntoa(*ipp[0]));
-#endif
-
- sp = getservbyname(port, "tcp");
- if (sp != NULL) {
- s_port = (u_short) sp->s_port;
- } else {
- s_port = strtoul(port, &p, 0);
- if (*p != '\0')
- return (EINVAL);
- s_port = htons(s_port);
- }
- if ((ntohs(s_port) != 0) &&
- (ntohs(s_port) <= IPPORT_RESERVED) &&
- (pcr->pcr_uid != 0))
- return (EPERM);
-#ifdef DEBUG
- printf("port number for %s is %d\n", port, ntohs(s_port));
-#endif
-
- memset(&sain, 0, sizeof(sain));
- sain.sin_len = sizeof(sain);
- sain.sin_family = AF_INET;
- sain.sin_port = s_port;
-
- if (any) {
- int so;
- int sock;
-
- so = socket(AF_INET, SOCK_STREAM, 0);
- if (so < 0) {
- syslog(LOG_ERR, "socket: %m");
- return (errno);
- }
-
- sain.sin_addr.s_addr = INADDR_ANY;
- if (bind(so, (struct sockaddr *) &sain, sizeof(sain)) == 0) {
- listen(so, 1);
- if ((sock = accept(so, (struct sockaddr *)0, (int *)0)) == -1) {
- syslog(LOG_ERR, "accept: %m");
- (void) close(so);
- return (errno);
- }
- *fdp = sock;
- (void) close(so);
- return (0);
- }
- syslog(LOG_ERR, "bind: %m");
- (void) close(so);
- return (errno);
- }
-
- while (ipp[0]) {
- int so;
- int sock;
-
- so = socket(AF_INET, SOCK_STREAM, 0);
- if (so < 0) {
- syslog(LOG_ERR, "socket: %m");
- return (errno);
- }
-
- sain.sin_addr = *ipp[0];
- if (bind(so, (struct sockaddr *) &sain, sizeof(sain)) == 0) {
- listen(so, 1);
- if ((sock = accept(so, (struct sockaddr *)0, (int *)0)) == -1) {
- syslog(LOG_ERR, "accept: %m");
- (void) close(so);
- return (errno);
- }
- *fdp = sock;
- (void) close(so);
- return (0);
- }
- (void) close(so);
-
- ipp++;
- }
-
- syslog(LOG_ERR, "bind: %m");
- return (errno);
-
-}
diff --git a/usr.sbin/pc-sysinstall/backend/functions-bsdlabel.sh b/usr.sbin/pc-sysinstall/backend/functions-bsdlabel.sh
index 0eedfad..37353d7 100755
--- a/usr.sbin/pc-sysinstall/backend/functions-bsdlabel.sh
+++ b/usr.sbin/pc-sysinstall/backend/functions-bsdlabel.sh
@@ -62,7 +62,18 @@ get_fs_line_xvars()
echo $ZFSVARS | grep -qE "^(disk|file|mirror|raidz(1|2|3)?|spare|log|cache):" 2>/dev/null
if [ $? -eq 0 ] ; then
ZTYPE=`echo $ZFSVARS | cut -f1 -d:`
- ZFSVARS=`echo $ZFSVARS | sed "s|$ZTYPE: ||g" | sed "s|$ZTYPE:||g"`
+ tmpVars=`echo $ZFSVARS | sed "s|$ZTYPE: ||g" | sed "s|$ZTYPE:||g"`
+ ZFSVARS=""
+ # make sure we have a '/dev' in front of the extra devices
+ for i in $tmpVars
+ do
+ echo $i | grep -q '/dev/'
+ if [ $? -ne 0 ] ; then
+ ZFSVARS="$ZFSVARS /dev/${i}"
+ else
+ ZFSVARS="$ZFSVARS $i"
+ fi
+ done
fi
# Return the ZFS options
diff --git a/usr.sbin/pc-sysinstall/backend/functions-disk.sh b/usr.sbin/pc-sysinstall/backend/functions-disk.sh
index b1b815d..eac10d9 100755
--- a/usr.sbin/pc-sysinstall/backend/functions-disk.sh
+++ b/usr.sbin/pc-sysinstall/backend/functions-disk.sh
@@ -33,6 +33,7 @@ is_disk()
for _dsk in `sysctl -n kern.disks`
do
[ "$_dsk" = "${1}" ] && return 0
+ [ "/dev/$_dsk" = "${1}" ] && return 0
done
return 1
diff --git a/usr.sbin/pc-sysinstall/backend/functions-extractimage.sh b/usr.sbin/pc-sysinstall/backend/functions-extractimage.sh
index 5d32466..fd6556d 100755
--- a/usr.sbin/pc-sysinstall/backend/functions-extractimage.sh
+++ b/usr.sbin/pc-sysinstall/backend/functions-extractimage.sh
@@ -29,23 +29,60 @@
. ${BACKEND}/functions-mountoptical.sh
+# Performs the extraction of data to disk from FreeBSD dist files
+start_extract_dist()
+{
+ if [ -z "$1" ] ; then exit_err "Called dist extraction with no directory set!"; fi
+ if [ -z "$INSFILE" ]; then exit_err "Called extraction with no install file set!"; fi
+ local DDIR="$1"
+
+ # Check if we are doing an upgrade, and if so use our exclude list
+ if [ "${INSTALLMODE}" = "upgrade" ]; then
+ TAROPTS="-X ${PROGDIR}/conf/exclude-from-upgrade"
+ else
+ TAROPTS=""
+ fi
+
+ # Loop though and extract dist files
+ for di in $INSFILE
+ do
+ # Check the MANIFEST see if we have an archive size / count
+ if [ -e "${DDIR}/MANIFEST" ]; then
+ count=`grep "^${di}.txz" ${DDIR}/MANIFEST | awk '{print $3}'`
+ if [ ! -z "$count" ] ; then
+ echo "INSTALLCOUNT: $count"
+ fi
+ fi
+ echo_log "pc-sysinstall: Starting Extraction (${di})"
+ tar -xpv -C ${FSMNT} -f ${DDIR}/${di}.txz ${TAROPTS} >&1 2>&1
+ if [ $? -ne 0 ]; then
+ exit_err "ERROR: Failed extracting the dist file: $di"
+ fi
+ done
+
+ # Check if this was a FTP download and clean it up now
+ if [ "${INSTALLMEDIUM}" = "ftp" ]; then
+ echo_log "Cleaning up downloaded archives"
+ rm -rf ${DDIR}
+ fi
+
+ echo_log "pc-sysinstall: Extraction Finished"
+}
+
# Performs the extraction of data to disk from a uzip or tar archive
start_extract_uzip_tar()
{
- if [ -z "$INSFILE" ]
- then
+ if [ -z "$INSFILE" ]; then
exit_err "ERROR: Called extraction with no install file set!"
fi
# Check if we have a .count file, and echo it out for a front-end to use in progress bars
- if [ -e "${INSFILE}.count" ]
- then
+ if [ -e "${INSFILE}.count" ]; then
echo "INSTALLCOUNT: `cat ${INSFILE}.count`"
fi
# Check if we are doing an upgrade, and if so use our exclude list
- if [ "${INSTALLMODE}" = "upgrade" ]
- then
+ if [ "${INSTALLMODE}" = "upgrade" ]; then
TAROPTS="-X ${PROGDIR}/conf/exclude-from-upgrade"
else
TAROPTS=""
@@ -87,9 +124,8 @@ start_extract_uzip_tar()
mdconfig -d -u ${MDDEVICE}
;;
tar)
- tar -xpv -C ${FSMNT} -f ${INSFILE} ${TAROPTS} >&1 2>&1
- if [ $? -ne 0 ]
- then
+ tar -xpv -C ${FSMNT} -f ${INSFILE} ${TAROPTS} >&1 2>&1
+ if [ $? -ne 0 ]; then
exit_err "ERROR: Failed extracting the tar image"
fi
;;
@@ -176,6 +212,38 @@ start_extract_split()
echo_log "pc-sysinstall: Extraction Finished"
};
+# Function which will attempt to fetch the dist file(s) before we start
+fetch_dist_file()
+{
+ get_value_from_cfg ftpPath
+ if [ -z "$VAL" ]
+ then
+ exit_err "ERROR: Install medium was set to ftp, but no ftpPath was provided!"
+ fi
+
+ FTPPATH="${VAL}"
+
+ # Check if we have a /usr partition to save the download
+ if [ -d "${FSMNT}/usr" ]
+ then
+ DLDIR="${FSMNT}/usr/.fetch.$$"
+ else
+ DLDIR="${FSMNT}/.fetch.$$"
+ fi
+ mkdir -p ${DLDIR}
+
+ # Do the fetch of the dist archive(s) now
+ for di in $INSFILE
+ do
+ fetch_file "${FTPPATH}/${di}.txz" "${DLDIR}/${di}.txz" "1"
+ done
+
+ # Check to see if there is a MANIFEST file for this install
+ fetch_file "${FTPPATH}/MANIFEST" "${DLDIR}/MANIFEST" "0"
+
+ export DLDIR
+};
+
# Function which will attempt to fetch the install file before we start
# the install
fetch_install_file()
@@ -390,6 +458,13 @@ init_extraction()
case $PACKAGETYPE in
uzip) INSFILE="${FBSD_UZIP_FILE}" ;;
tar) INSFILE="${FBSD_TAR_FILE}" ;;
+ dist)
+ get_value_from_cfg_with_spaces distFiles
+ if [ -z "$VAL" ] ; then
+ exit_err "No dist files specified!"
+ fi
+ INSFILE="${VAL}"
+ ;;
split)
INSDIR="${FBSD_BRANCH_DIR}"
@@ -401,6 +476,13 @@ init_extraction()
case $PACKAGETYPE in
uzip) INSFILE="${UZIP_FILE}" ;;
tar) INSFILE="${TAR_FILE}" ;;
+ dist)
+ get_value_from_cfg_with_spaces distFiles
+ if [ -z "$VAL" ] ; then
+ exit_err "No dist files specified!"
+ fi
+ INSFILE="${VAL}"
+ ;;
esac
fi
export INSFILE
@@ -417,22 +499,32 @@ init_extraction()
start_extract_split
else
- INSFILE="${CDMNT}/${INSFILE}" ; export INSFILE
- start_extract_uzip_tar
+ if [ "$PACKAGETYPE" = "dist" ] ; then
+ start_extract_dist "${CDMNT}/usr/freebsd-dist"
+ else
+ INSFILE="${CDMNT}/${INSFILE}" ; export INSFILE
+ start_extract_uzip_tar
+ fi
fi
;;
ftp)
- if [ "$PACKAGETYPE" = "split" ]
- then
- fetch_split_files
-
- INSDIR="${INSFILE}" ; export INSDIR
- start_extract_split
- else
- fetch_install_file
- start_extract_uzip_tar
- fi
+ case $PACKAGETYPE in
+ split)
+ fetch_split_files
+
+ INSDIR="${INSFILE}" ; export INSDIR
+ start_extract_split
+ ;;
+ dist)
+ fetch_dist_file
+ start_extract_dist "$DLDIR"
+ ;;
+ *)
+ fetch_install_file
+ start_extract_uzip_tar
+ ;;
+ esac
;;
sftp) ;;
@@ -446,8 +538,13 @@ init_extraction()
exit_err "Install medium was set to local, but no localPath was provided!"
fi
LOCALPATH=$VAL
- INSFILE="${LOCALPATH}/${INSFILE}" ; export INSFILE
- start_extract_uzip_tar
+ if [ "$PACKAGETYPE" = "dist" ] ; then
+ INSFILE="${INSFILE}" ; export INSFILE
+ start_extract_dist "$LOCALPATH"
+ else
+ INSFILE="${LOCALPATH}/${INSFILE}" ; export INSFILE
+ start_extract_uzip_tar
+ fi
;;
*) exit_err "ERROR: Unknown install medium" ;;
esac
diff --git a/usr.sbin/pc-sysinstall/backend/functions-installpackages.sh b/usr.sbin/pc-sysinstall/backend/functions-installpackages.sh
index 7572efb..c1a879a 100755
--- a/usr.sbin/pc-sysinstall/backend/functions-installpackages.sh
+++ b/usr.sbin/pc-sysinstall/backend/functions-installpackages.sh
@@ -76,50 +76,113 @@ fetch_package_dependencies()
# Check for any packages specified, and begin loading them
install_packages()
{
+ echo "Checking for packages to install..."
+ sleep 2
+
# First, lets check and see if we even have any packages to install
get_value_from_cfg installPackages
- if [ -n "${VAL}" ]
- then
- HERE=`pwd`
- rc_nohalt "mkdir -p ${FSMNT}/${PKGTMPDIR}"
- rc_nohalt "cd ${FSMNT}/${PKGTMPDIR}"
- if [ ! -f "${CONFDIR}/INDEX" ]
+ # Nothing to do?
+ if [ -z "${VAL}" ]; then return; fi
+
+ echo "Installing packages..."
+ sleep 3
+
+ local PKGPTH
+
+ HERE=`pwd`
+ rc_halt "mkdir -p ${FSMNT}${PKGTMPDIR}"
+
+ # Determine the directory we will install packages from
+ get_package_location
+ rc_halt "cd ${PKGDLDIR}"
+
+ # Set the location of the INDEXFILE
+ INDEXFILE="${TMPDIR}/INDEX"
+
+ if [ ! -f "${INDEXFILE}" ]; then
+ get_package_index
+ fi
+
+ if [ ! -f "${TMPDIR}/INDEX.parsed" -a "$INSTALLMEDIUM" = "ftp" ]; then
+ parse_package_index
+ fi
+
+ # What extension are we using for pkgs?
+ PKGEXT="txz"
+ get_value_from_cfg pkgExt
+ if [ -n "${VAL}" ]; then
+ strip_white_space ${VAL}
+ PKGEXT="$VAL"
+ fi
+ export PKGEXT
+
+ # We dont want to be bothered with scripts asking questions
+ PACKAGE_BUILDING=yes
+ export PACKAGE_BUILDING
+
+ # Lets start by cleaning up the string and getting it ready to parse
+ get_value_from_cfg_with_spaces installPackages
+ PACKAGES="${VAL}"
+ echo_log "Packages to install: `echo $PACKAGES | wc -w | awk '{print $1}'`"
+ for i in $PACKAGES
+ do
+ if ! get_package_name "${i}"
then
- get_package_index
+ echo_log "Unable to locate package ${i}"
+ continue
fi
- if [ ! -f "${CONFDIR}/INDEX.parsed" ]
- then
- parse_package_index
+ PKGNAME="${VAL}"
+
+ # Fetch package + deps, but skip if installing from local media
+ if [ "${INSTALLMEDIUM}" = "ftp" ] ; then
+ DEPFILE="${FSMNT}/${PKGTMPDIR}/.${PKGNAME}.deps"
+ rc_nohalt "touch ${DEPFILE}"
+ determine_package_dependencies "${PKGNAME}" "${DEPFILE}"
+ fetch_package_dependencies "${DEPFILE}" "${FSMNT}/${PKGTMPDIR}"
fi
- # Lets start by cleaning up the string and getting it ready to parse
- strip_white_space ${VAL}
- PACKAGES=`echo ${VAL} | sed -e "s|,| |g"`
- for i in $PACKAGES
- do
- if get_package_name "${i}"
- then
- PKGNAME="${VAL}"
- DEPFILE="${FSMNT}/${PKGTMPDIR}/.${PKGNAME}.deps"
-
- rc_nohalt "touch ${DEPFILE}"
- determine_package_dependencies "${PKGNAME}" "${DEPFILE}"
- fetch_package_dependencies "${DEPFILE}" "${FSMNT}/${PKGTMPDIR}"
-
- # If the package is not already installed, install it!
- if ! run_chroot_cmd "pkg_info -e ${PKGNAME}"
- then
- rc_nohalt "pkg_add -C ${FSMNT} ${PKGTMPDIR}/${PKGNAME}.tbz"
- fi
-
- rc_nohalt "rm ${DEPFILE}"
+ # Set package location
+ case "${INSTALLMEDIUM}" in
+ usb|dvd|local) PKGPTH="${PKGTMPDIR}/All/${PKGNAME}" ;;
+ *) PKGPTH="${PKGTMPDIR}/${PKGNAME}" ;;
+ esac
+
+ # See if we need to determine the package format we are working with
+ if [ -z "${PKGINFO}" ] ; then
+ tar tqf "${FSMNT}${PKGPTH}" '+MANIFEST' >/dev/null 2>/dev/null
+ if [ $? -ne 0 ] ; then
+ PKGADD="pkg_add -C ${FSMNT}"
+ PKGINFO="pkg_info"
+ else
+ PKGADD="pkg -c ${FSMNT} add"
+ PKGINFO="pkg info"
+ bootstrap_pkgng
fi
+ fi
- rc_nohalt "cd ${HERE}"
- done
+ # If the package is not already installed, install it!
+ if ! run_chroot_cmd "${PKGINFO} -e ${PKGNAME}" >/dev/null 2>/dev/null
+ then
+ echo_log "Installing package: ${PKGNAME}"
+ rc_nohalt "${PKGADD} ${PKGPTH}"
+ fi
+
+ if [ "${INSTALLMEDIUM}" = "ftp" ] ; then
+ rc_nohalt "rm ${DEPFILE}"
+ fi
+
+ done
+
+ echo_log "Package installation complete!"
- rm -rf "${FSMNT}/${PKGTMPDIR}"
+ # Cleanup after ourselves
+ rc_halt "cd ${HERE}"
+ if [ "${INSTALLMEDIUM}" = "ftp" ] ; then
+ rc_halt "rm -rf ${FSMNT}${PKGTMPDIR}" >/dev/null 2>/dev/null
+ else
+ rc_halt "umount ${FSMNT}${PKGTMPDIR}" >/dev/null 2>/dev/null
+ rc_halt "rmdir ${FSMNT}${PKGTMPDIR}" >/dev/null 2>/dev/null
fi
};
diff --git a/usr.sbin/pc-sysinstall/backend/functions-mountdisk.sh b/usr.sbin/pc-sysinstall/backend/functions-mountdisk.sh
index c90c058..e9eb148 100755
--- a/usr.sbin/pc-sysinstall/backend/functions-mountdisk.sh
+++ b/usr.sbin/pc-sysinstall/backend/functions-mountdisk.sh
@@ -149,12 +149,12 @@ mount_all_filesystems()
for PART in `ls ${PARTDIR}`
do
PARTDEV=`echo $PART | sed 's|-|/|g'`
- if [ ! -e "${PARTDEV}" ]
+ PARTFS="`cat ${PARTDIR}/${PART} | cut -d '#' -f 1`"
+ if [ ! -e "${PARTDEV}" -a "${PARTFS}" != "ZFS" ]
then
exit_err "ERROR: The partition ${PARTDEV} does not exist. Failure in bsdlabel?"
fi
- PARTFS="`cat ${PARTDIR}/${PART} | cut -d '#' -f 1`"
PARTMNT="`cat ${PARTDIR}/${PART} | cut -d '#' -f 2`"
PARTENC="`cat ${PARTDIR}/${PART} | cut -d '#' -f 3`"
@@ -186,12 +186,12 @@ mount_all_filesystems()
for PART in `ls ${PARTDIR}`
do
PARTDEV=`echo $PART | sed 's|-|/|g'`
- if [ ! -e "${PARTDEV}" ]
+ PARTFS="`cat ${PARTDIR}/${PART} | cut -d '#' -f 1`"
+ if [ ! -e "${PARTDEV}" -a "${PARTFS}" != "ZFS" ]
then
exit_err "ERROR: The partition ${PARTDEV} does not exist. Failure in bsdlabel?"
fi
- PARTFS="`cat ${PARTDIR}/${PART} | cut -d '#' -f 1`"
PARTMNT="`cat ${PARTDIR}/${PART} | cut -d '#' -f 2`"
PARTENC="`cat ${PARTDIR}/${PART} | cut -d '#' -f 3`"
diff --git a/usr.sbin/pc-sysinstall/backend/functions-newfs.sh b/usr.sbin/pc-sysinstall/backend/functions-newfs.sh
index 2ab4a83..f8664f0 100755
--- a/usr.sbin/pc-sysinstall/backend/functions-newfs.sh
+++ b/usr.sbin/pc-sysinstall/backend/functions-newfs.sh
@@ -60,18 +60,56 @@ setup_zfs_filesystem()
fi
done
-
# Check if we have some custom zpool arguments and use them if so
if [ ! -z "${ZPOOLOPTS}" ] ; then
- rc_halt "zpool create -m none -f ${ZPOOLNAME} ${ZPOOLOPTS}"
+ # Sort through devices and run gnop on them
+ local gnopDev=""
+ local newOpts=""
+ for i in $ZPOOLOPTS
+ do
+ echo "$i" | grep -q '/dev/'
+ if [ $? -eq 0 ] ; then
+ rc_halt "gnop create -S 4096 ${i}"
+ gnopDev="$gnopDev $i"
+ newOpts="$newOpts ${i}.nop"
+ else
+ newOpts="$newOpts $i"
+ fi
+ done
+
+ echo_log "Creating zpool ${ZPOOLNAME} with $newOpts"
+ rc_halt "zpool create -m none -f ${ZPOOLNAME} ${newOpts}"
+
+ # Export the pool
+ rc_halt "zpool export ${ZPOOLNAME}"
+
+ # Destroy the gnop devices
+ for i in $gnopDev
+ do
+ rc_halt "gnop destroy ${i}.nop"
+ done
+
+ # And lastly re-import the pool
+ rc_halt "zpool import ${ZPOOLNAME}"
else
+ # Lets do our pseudo-4k drive
+ rc_halt "gnop create -S 4096 ${PART}${EXT}"
+
# No zpool options, create pool on single device
- rc_halt "zpool create -m none -f ${ZPOOLNAME} ${PART}${EXT}"
+ echo_log "Creating zpool ${ZPOOLNAME} on ${PART}${EXT}"
+ rc_halt "zpool create -m none -f ${ZPOOLNAME} ${PART}${EXT}.nop"
+
+ # Finish up the gnop 4k trickery
+ rc_halt "zpool export ${ZPOOLNAME}"
+ rc_halt "gnop destroy ${PART}${EXT}.nop"
+ rc_halt "zpool import ${ZPOOLNAME}"
fi
# Disable atime for this zfs partition, speed increase
rc_nohalt "zfs set atime=off ${ZPOOLNAME}"
+
+
};
# Runs newfs on all the partiions which we've setup with bsdlabel
diff --git a/usr.sbin/pc-sysinstall/backend/functions-packages.sh b/usr.sbin/pc-sysinstall/backend/functions-packages.sh
index c426778..ee41928 100755
--- a/usr.sbin/pc-sysinstall/backend/functions-packages.sh
+++ b/usr.sbin/pc-sysinstall/backend/functions-packages.sh
@@ -45,9 +45,11 @@ get_package_index_by_ftp()
then
INDEX_FILE="${INDEX_FILE}.bz2"
USE_BZIP2=1
+ INDEX_PATH="${INDEXFILE}.bz2"
+ else
+ INDEX_PATH="${INDEXFILE}"
fi
- INDEX_PATH="${CONFDIR}/${INDEX_FILE}"
fetch_file "${FTP_SERVER}/${INDEX_FILE}" "${INDEX_PATH}" "1"
if [ -f "${INDEX_PATH}" ] && [ "${USE_BZIP2}" -eq "1" ]
then
@@ -57,17 +59,18 @@ get_package_index_by_ftp()
get_package_index_by_fs()
{
- local INDEX_FILE
-
- INDEX_FILE="${CDMNT}/packages/INDEX"
- fetch_file "${INDEX_FILE}" "${CONFDIR}/" "0"
+ if [ "$INSTALLMEDIUM" = "local" ] ; then
+ INDEXFILE="${LOCALPATH}/packages/INDEX"
+ else
+ INDEXFILE="${CDMNT}/packages/INDEX"
+ fi
};
get_package_index_size()
{
- if [ -f "${CONFDIR}/INDEX" ]
+ if [ -f "${INDEXFILE}" ]
then
- SIZE=`ls -l ${CONFDIR}/INDEX | awk '{ print $5 }'`
+ SIZE=`ls -l ${INDEXFILE} | awk '{ print $5 }'`
else
get_ftp_mirror
FTPHOST="${VAL}"
@@ -94,28 +97,24 @@ get_package_index()
get_package_index_by_ftp "${FTPPATH}"
else
- get_value_from_cfg ftpHost
- if [ -z "$VAL" ]
- then
- exit_err "ERROR: Install medium was set to ftp, but no ftpHost was provided!"
- fi
-
- FTPHOST="${VAL}"
-
- get_value_from_cfg ftpDir
- if [ -z "$VAL" ]
- then
- exit_err "ERROR: Install medium was set to ftp, but no ftpDir was provided!"
- fi
-
- FTPDIR="${VAL}"
- FTPPATH="ftp://${FTPHOST}${FTPDIR}"
case "${INSTALLMEDIUM}" in
- usb|dvd) get_package_index_by_fs ;;
- ftp) get_package_index_by_ftp "${FTPPATH}" ;;
- sftp) ;;
- *) RES=1 ;;
+ usb|dvd|local) get_package_index_by_fs ;;
+ ftp) get_value_from_cfg ftpHost
+ if [ -z "$VAL" ]; then
+ exit_err "ERROR: Install medium was set to ftp, but no ftpHost was provided!"
+ fi
+ FTPHOST="${VAL}"
+
+ get_value_from_cfg ftpDir
+ if [ -z "$VAL" ]; then
+ exit_err "ERROR: Install medium was set to ftp, but no ftpDir was provided!"
+ fi
+ FTPDIR="${VAL}"
+ FTPPATH="ftp://${FTPHOST}${FTPDIR}"
+ get_package_index_by_ftp "${FTPPATH}" ;;
+ sftp) ;;
+ *) RES=1 ;;
esac
fi
@@ -125,10 +124,11 @@ get_package_index()
parse_package_index()
{
+ echo_log "Building package dep list.. Please wait.."
INDEX_FILE="${PKGDIR}/INDEX"
exec 3<&0
- exec 0<"${INDEX_FILE}"
+ exec 0<"${INDEXFILE}"
while read -r line
do
@@ -257,20 +257,38 @@ get_package_name()
{
PACKAGE="${1}"
RES=0
+ local PKGPTH
- INDEX_FILE="${PKGDIR}/INDEX.deps"
- REGEX="^${PACKAGE}|"
+ # If we are on a local medium, we can parse the Latest/ directory
+ if [ "${INSTALLMEDIUM}" != "ftp" ] ; then
+ case "${INSTALLMEDIUM}" in
+ usb|dvd) PKGPTH="${CDMNT}/packages" ;;
+ *) PKGPTH="${LOCALPATH}/packages" ;;
+ esac
+
+ # Check the /Latest dir for generic names, then look for specific version in All/
+ if [ -e "${PKGPTH}/Latest/${PACKAGE}.${PKGEXT}" ] ; then
+ NAME=`ls -al ${PKGPTH}/Latest/${PACKAGE}.${PKGEXT} 2>/dev/null | cut -d '>' -f 2 | rev | cut -f1 -d'/' | rev | tr -s ' '`
+ else
+ NAME=`ls -al ${PKGPTH}/All/${PACKAGE}.${PKGEXT} 2>/dev/null | cut -d '>' -f 2 | rev | cut -f1 -d'/' | rev | tr -s ' '`
+ fi
+ export VAL="${NAME}"
+ else
+ # Doing remote fetch, we we will look up, but some generic names like
+ # "perl" wont work, since we don't know the default version
+ INDEX_FILE="${PKGDIR}/INDEX.deps"
+ REGEX="^${PACKAGE}|"
- LINE=`grep "${REGEX}" "${INDEX_FILE}" 2>/dev/null`
- NAME=`echo "${LINE}"|cut -f2 -d'|'`
+ LINE=`grep "${REGEX}" "${INDEX_FILE}" 2>/dev/null`
+ NAME=`echo "${LINE}"|cut -f2 -d'|'`
- export VAL="${NAME}"
+ export VAL="${NAME}"
+ fi
if [ -z "${VAL}" ]
then
RES=1
fi
-
return ${RES}
};
@@ -334,7 +352,7 @@ fetch_package_by_ftp()
fi
FTPDIR="${VAL}"
- PACKAGE="${PACKAGE}.tbz"
+ PACKAGE="${PACKAGE}.${PKGEXT}"
FTP_SERVER="ftp://${FTPHOST}${FTPDIR}"
if [ ! -f "${SAVEDIR}/${PACKAGE}" ]
@@ -345,28 +363,49 @@ fetch_package_by_ftp()
fi
};
-fetch_package_by_fs()
-{
- CATEGORY="${1}"
- PACKAGE="${2}"
- SAVEDIR="${3}"
-
- PACKAGE="${PACKAGE}.tbz"
- if [ ! -f "${SAVEDIR}/${PACKAGE}" ]
- then
- fetch_file "${CDMNT}/packages/${CATEGORY}/${PACKAGE}" "${SAVEDIR}/" "0"
- fi
-};
-
fetch_package()
{
CATEGORY="${1}"
PACKAGE="${2}"
SAVEDIR="${3}"
+ # Fetch package, but skip if installing from local media
case "${INSTALLMEDIUM}" in
- usb|dvd) fetch_package_by_fs "${CATEGORY}" "${PACKAGE}" "${SAVEDIR}" ;;
+ usb|dvd|local) return ;;
ftp) fetch_package_by_ftp "${CATEGORY}" "${PACKAGE}" "${SAVEDIR}" ;;
sftp) ;;
esac
};
+
+bootstrap_pkgng()
+{
+ # Check if we need to boot-strap pkgng
+ if run_chroot_cmd "which pkg-static" >/dev/null 2>/dev/null
+ then
+ return
+ fi
+ local PKGPTH
+
+ # Ok, lets boot-strap this sucker
+ echo_log "Bootstraping pkgng.."
+ fetch_package "Latest" "pkg" "${PKGDLDIR}"
+
+ # Figure out real location of "pkg" package
+ case "${INSTALLMEDIUM}" in
+ usb|dvd|local) PKGPTH="${PKGTMPDIR}/Latest/pkg.${PKGEXT}" ;;
+ *) PKGPTH="${PKGTMPDIR}/pkg.${PKGEXT}" ;;
+ esac
+ rc_halt "pkg -c ${FSMNT} add ${PKGPTH}" ; run_chroot_cmd "pkg2ng"
+}
+
+get_package_location()
+{
+ case "${INSTALLMEDIUM}" in
+ usb|dvd) rc_halt "mount_nullfs ${CDMNT}/packages ${FSMNT}${PKGTMPDIR}"
+ PKGDLDIR="${FSMNT}${PKGTMPDIR}/All" ;;
+ local) rc_halt "mount_nullfs ${LOCALPATH}/packages ${FSMNT}${PKGTMPDIR}"
+ PKGDLDIR="${FSMNT}${PKGTMPDIR}/All" ;;
+ *) PKGDLDIR="${FSMNT}${PKGTMPDIR}" ;;
+ esac
+ export PKGDLDIR
+}
diff --git a/usr.sbin/pc-sysinstall/backend/functions-parse.sh b/usr.sbin/pc-sysinstall/backend/functions-parse.sh
index ed0a3e6..fb7cdd2 100755
--- a/usr.sbin/pc-sysinstall/backend/functions-parse.sh
+++ b/usr.sbin/pc-sysinstall/backend/functions-parse.sh
@@ -45,7 +45,7 @@ get_value_from_cfg_with_spaces()
{
if [ -n "${1}" ]
then
- export VAL=`grep "^${1}=" ${CFGF} | head -n 1 | cut -d '=' -f 2-`
+ export VAL="`grep ^${1}= ${CFGF} | head -n 1 | cut -d '=' -f 2-`"
else
exit_err "Error: Did we forgot to supply a setting to grab?"
fi
diff --git a/usr.sbin/pc-sysinstall/backend/functions.sh b/usr.sbin/pc-sysinstall/backend/functions.sh
index 33d0005..a2d039b 100755
--- a/usr.sbin/pc-sysinstall/backend/functions.sh
+++ b/usr.sbin/pc-sysinstall/backend/functions.sh
@@ -277,7 +277,11 @@ get_zpool_name()
while :
do
NEWNAME="${BASENAME}${NUM}"
- zpool import | grep -qw "${NEWNAME}" || break
+ zpool list | grep -qw "${NEWNAME}"
+ local chk1=$?
+ zpool import | grep -qw "${NEWNAME}"
+ local chk2=$?
+ if [ $chk1 -eq 1 -a $chk2 -eq 1 ] ; then break ; fi
NUM=$((NUM+1))
done
diff --git a/usr.sbin/pc-sysinstall/backend/parseconfig.sh b/usr.sbin/pc-sysinstall/backend/parseconfig.sh
index c852cea..f3d89fc 100755
--- a/usr.sbin/pc-sysinstall/backend/parseconfig.sh
+++ b/usr.sbin/pc-sysinstall/backend/parseconfig.sh
@@ -69,7 +69,7 @@ file_sanity_check "installMode installType installMedium packageType"
check_value installMode "fresh upgrade extract"
check_value installType "PCBSD FreeBSD"
check_value installMedium "dvd usb ftp rsync image local"
-check_value packageType "uzip tar rsync split"
+check_value packageType "uzip tar rsync split dist"
if_check_value_exists mirrorbal "load prefer round-robin split"
# We passed all sanity checks! Yay, lets start the install
diff --git a/usr.sbin/pc-sysinstall/conf/pc-sysinstall.conf b/usr.sbin/pc-sysinstall/conf/pc-sysinstall.conf
index 5d682dc..9c01e31 100644
--- a/usr.sbin/pc-sysinstall/conf/pc-sysinstall.conf
+++ b/usr.sbin/pc-sysinstall/conf/pc-sysinstall.conf
@@ -5,11 +5,9 @@
TMPDIR="/tmp/.pc-sysinstall"
export TMPDIR
-if [ ! -d "${TMPDIR}" ]
-then
- mkdir -p ${TMPDIR}
- chmod 777 ${TMPDIR}
-fi
+# Create a fresh TMPDIR
+if [ -d "${TMPDIR}" -a "$TMPDIR" != '/' ]; then rm -rf ${TMPDIR}; fi
+mkdir -p ${TMPDIR}
# Set our temp directory for storing partition information
PARTDIR="${TMPDIR}/part-info"
diff --git a/usr.sbin/pc-sysinstall/examples/README b/usr.sbin/pc-sysinstall/examples/README
index cc269a2..1e8d32d 100644
--- a/usr.sbin/pc-sysinstall/examples/README
+++ b/usr.sbin/pc-sysinstall/examples/README
@@ -243,11 +243,16 @@ Set installMedium= to the source type we will be using for this install.
Available Types:
dvd - Search for and mount the DVD which contains the install archive
+local - Pull files directly from a local directory
usb - Search for and mount the USB drive which contains the install archive
ftp - The install archive will be fetched from a FTP / HTTP server before install
rsync - Pull the system data from a ssh + rsync server, specified with variables below
image - Install system from an image
+# localPath=/usr/freebsd-dist
+
+Location of the directory we will be pulling installation files from
+
# installType=(PCBSD, FreeBSD)
Set the type of system we are installing, PCBSD or FreeBSD
@@ -256,10 +261,14 @@ Set the type of system we are installing, PCBSD or FreeBSD
The installer archive, if not using the defaults specified in conf/pc-sysinstall.conf
-# packageType=(tar, uzip, split)
+# packageType=(tar, uzip, split, dist)
The archive type we are extracting from when using dvd, usb or ftp
+# distFiles=base src kernel
+
+List of dist files to install when packageType=dist
+
# ftpPath=ftp://ftp.pcbsd.org/pub/8.0/netinstall
Location of the installer archive when using a installMedium=ftp
diff --git a/usr.sbin/pkg/Makefile b/usr.sbin/pkg/Makefile
index c2ca0a3..0e1c2d8 100644
--- a/usr.sbin/pkg/Makefile
+++ b/usr.sbin/pkg/Makefile
@@ -1,10 +1,10 @@
# $FreeBSD$
PROG= pkg
-SRCS= pkg.c dns_utils.c
+SRCS= pkg.c dns_utils.c config.c
NO_MAN= yes
-DPADD= ${LIBARCHIVE} ${LIBELF} ${LIBFETCH}
-LDADD= -larchive -lelf -lfetch
+DPADD= ${LIBARCHIVE} ${LIBELF} ${LIBFETCH} ${LIBBSDYML} ${LIBSUBF}
+LDADD= -larchive -lelf -lfetch -lbsdyml -lsbuf
.include <bsd.prog.mk>
diff --git a/usr.sbin/pkg/config.c b/usr.sbin/pkg/config.c
new file mode 100644
index 0000000..5924d57
--- /dev/null
+++ b/usr.sbin/pkg/config.c
@@ -0,0 +1,428 @@
+/*-
+ * Copyright (c) 2013 Baptiste Daroussin <bapt@FreeBSD.org>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include <sys/param.h>
+#include <sys/sbuf.h>
+#include <sys/elf_common.h>
+#include <sys/endian.h>
+
+#include <bsdyml.h>
+#include <ctype.h>
+#include <err.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <gelf.h>
+#include <inttypes.h>
+#include <paths.h>
+#include <stdbool.h>
+#include <string.h>
+#include <unistd.h>
+
+#include "elf_tables.h"
+#include "config.h"
+
+#define roundup2(x, y) (((x)+((y)-1))&(~((y)-1))) /* if y is powers of two */
+
+struct config_entry {
+ uint8_t type;
+ const char *key;
+ const char *val;
+ char *value;
+ bool envset;
+};
+
+static struct config_entry c[] = {
+ [PACKAGESITE] = {
+ PKG_CONFIG_STRING,
+ "PACKAGESITE",
+ "http://pkg.FreeBSD.org/${ABI}/latest",
+ NULL,
+ false,
+ },
+ [ABI] = {
+ PKG_CONFIG_STRING,
+ "ABI",
+ NULL,
+ NULL,
+ false,
+ },
+ [MIRROR_TYPE] = {
+ PKG_CONFIG_STRING,
+ "MIRROR_TYPE",
+ "SRV",
+ NULL,
+ false,
+ },
+ [ASSUME_ALWAYS_YES] = {
+ PKG_CONFIG_BOOL,
+ "ASSUME_ALWAYS_YES",
+ "NO",
+ NULL,
+ false,
+ }
+};
+
+static const char *
+elf_corres_to_string(struct _elf_corres *m, int e)
+{
+ int i;
+
+ for (i = 0; m[i].string != NULL; i++)
+ if (m[i].elf_nb == e)
+ return (m[i].string);
+
+ return ("unknown");
+}
+
+static int
+pkg_get_myabi(char *dest, size_t sz)
+{
+ Elf *elf;
+ Elf_Data *data;
+ Elf_Note note;
+ Elf_Scn *scn;
+ char *src, *osname;
+ const char *abi;
+ GElf_Ehdr elfhdr;
+ GElf_Shdr shdr;
+ int fd, i, ret;
+ uint32_t version;
+
+ version = 0;
+ ret = -1;
+ scn = NULL;
+ abi = NULL;
+
+ if (elf_version(EV_CURRENT) == EV_NONE) {
+ warnx("ELF library initialization failed: %s",
+ elf_errmsg(-1));
+ return (-1);
+ }
+
+ if ((fd = open(_PATH_BSHELL, O_RDONLY)) < 0) {
+ warn("open()");
+ return (-1);
+ }
+
+ if ((elf = elf_begin(fd, ELF_C_READ, NULL)) == NULL) {
+ ret = -1;
+ warnx("elf_begin() failed: %s.", elf_errmsg(-1));
+ goto cleanup;
+ }
+
+ if (gelf_getehdr(elf, &elfhdr) == NULL) {
+ ret = -1;
+ warn("getehdr() failed: %s.", elf_errmsg(-1));
+ goto cleanup;
+ }
+ while ((scn = elf_nextscn(elf, scn)) != NULL) {
+ if (gelf_getshdr(scn, &shdr) != &shdr) {
+ ret = -1;
+ warn("getshdr() failed: %s.", elf_errmsg(-1));
+ goto cleanup;
+ }
+
+ if (shdr.sh_type == SHT_NOTE)
+ break;
+ }
+
+ if (scn == NULL) {
+ ret = -1;
+ warn("failed to get the note section");
+ goto cleanup;
+ }
+
+ data = elf_getdata(scn, NULL);
+ src = data->d_buf;
+ for (;;) {
+ memcpy(&note, src, sizeof(Elf_Note));
+ src += sizeof(Elf_Note);
+ if (note.n_type == NT_VERSION)
+ break;
+ src += note.n_namesz + note.n_descsz;
+ }
+ osname = src;
+ src += roundup2(note.n_namesz, 4);
+ if (elfhdr.e_ident[EI_DATA] == ELFDATA2MSB)
+ version = be32dec(src);
+ else
+ version = le32dec(src);
+
+ for (i = 0; osname[i] != '\0'; i++)
+ osname[i] = (char)tolower(osname[i]);
+
+ snprintf(dest, sz, "%s:%d:%s:%s",
+ osname, version / 100000,
+ elf_corres_to_string(mach_corres, (int)elfhdr.e_machine),
+ elf_corres_to_string(wordsize_corres,
+ (int)elfhdr.e_ident[EI_CLASS]));
+
+ ret = 0;
+
+ switch (elfhdr.e_machine) {
+ case EM_ARM:
+ snprintf(dest + strlen(dest), sz - strlen(dest),
+ ":%s:%s:%s", elf_corres_to_string(endian_corres,
+ (int)elfhdr.e_ident[EI_DATA]),
+ (elfhdr.e_flags & EF_ARM_NEW_ABI) > 0 ?
+ "eabi" : "oabi",
+ (elfhdr.e_flags & EF_ARM_VFP_FLOAT) > 0 ?
+ "softfp" : "vfp");
+ break;
+ case EM_MIPS:
+ /*
+ * this is taken from binutils sources:
+ * include/elf/mips.h
+ * mapping is figured out from binutils:
+ * gas/config/tc-mips.c
+ */
+ switch (elfhdr.e_flags & EF_MIPS_ABI) {
+ case E_MIPS_ABI_O32:
+ abi = "o32";
+ break;
+ case E_MIPS_ABI_N32:
+ abi = "n32";
+ break;
+ default:
+ if (elfhdr.e_ident[EI_DATA] ==
+ ELFCLASS32)
+ abi = "o32";
+ else if (elfhdr.e_ident[EI_DATA] ==
+ ELFCLASS64)
+ abi = "n64";
+ break;
+ }
+ snprintf(dest + strlen(dest), sz - strlen(dest),
+ ":%s:%s", elf_corres_to_string(endian_corres,
+ (int)elfhdr.e_ident[EI_DATA]), abi);
+ break;
+ }
+
+cleanup:
+ if (elf != NULL)
+ elf_end(elf);
+
+ close(fd);
+ return (ret);
+}
+
+static void
+subst_packagesite(const char *abi)
+{
+ struct sbuf *newval;
+ const char *variable_string;
+ const char *oldval;
+
+ if (c[PACKAGESITE].value != NULL)
+ oldval = c[PACKAGESITE].value;
+ else
+ oldval = c[PACKAGESITE].val;
+
+ if ((variable_string = strstr(oldval, "${ABI}")) == NULL)
+ return;
+
+ newval = sbuf_new_auto();
+ sbuf_bcat(newval, oldval, variable_string - oldval);
+ sbuf_cat(newval, abi);
+ sbuf_cat(newval, variable_string + strlen("${ABI}"));
+ sbuf_finish(newval);
+
+ free(c[PACKAGESITE].value);
+ c[PACKAGESITE].value = strdup(sbuf_data(newval));
+}
+
+static void
+config_parse(yaml_document_t *doc, yaml_node_t *node)
+{
+ yaml_node_pair_t *pair;
+ yaml_node_t *key, *val;
+ struct sbuf *buf = sbuf_new_auto();
+ int i;
+ size_t j;
+
+ pair = node->data.mapping.pairs.start;
+
+ while (pair < node->data.mapping.pairs.top) {
+ key = yaml_document_get_node(doc, pair->key);
+ val = yaml_document_get_node(doc, pair->value);
+
+ /*
+ * ignoring silently empty keys can be empty lines
+ * or user mistakes
+ */
+ if (key->data.scalar.length <= 0) {
+ ++pair;
+ continue;
+ }
+
+ /*
+ * silently skip on purpose to allow user to leave
+ * empty lines without complaining
+ */
+ if (val->type == YAML_NO_NODE ||
+ (val->type == YAML_SCALAR_NODE &&
+ val->data.scalar.length <= 0)) {
+ ++pair;
+ continue;
+ }
+
+ sbuf_clear(buf);
+ for (j = 0; j < strlen(key->data.scalar.value); ++j)
+ sbuf_putc(buf, toupper(key->data.scalar.value[j]));
+
+ sbuf_finish(buf);
+ for (i = 0; i < CONFIG_SIZE; i++) {
+ if (strcmp(sbuf_data(buf), c[i].key) == 0)
+ break;
+ }
+
+ if (i == CONFIG_SIZE) {
+ ++pair;
+ continue;
+ }
+
+ /* env has priority over config file */
+ if (c[i].envset) {
+ ++pair;
+ continue;
+ }
+
+ c[i].value = strdup(val->data.scalar.value);
+ ++pair;
+ }
+
+ sbuf_delete(buf);
+}
+
+int
+config_init(void)
+{
+ FILE *fp;
+ yaml_parser_t parser;
+ yaml_document_t doc;
+ yaml_node_t *node;
+ const char *val;
+ int i;
+ const char *localbase;
+ char confpath[MAXPATHLEN];
+ char abi[BUFSIZ];
+
+ for (i = 0; i < CONFIG_SIZE; i++) {
+ val = getenv(c[i].key);
+ if (val != NULL) {
+ c[i].val = val;
+ c[i].envset = true;
+ }
+ }
+
+ localbase = getenv("LOCALBASE") ? getenv("LOCALBASE") : _LOCALBASE;
+ snprintf(confpath, sizeof(confpath), "%s/etc/pkg.conf", localbase);
+
+ if ((fp = fopen(confpath, "r")) == NULL) {
+ if (errno != ENOENT)
+ err(EXIT_FAILURE, "Unable to open configuration file %s", confpath);
+ /* no configuration present */
+ goto finalize;
+ }
+
+ yaml_parser_initialize(&parser);
+ yaml_parser_set_input_file(&parser, fp);
+ yaml_parser_load(&parser, &doc);
+
+ node = yaml_document_get_root_node(&doc);
+
+ if (node != NULL) {
+ if (node->type != YAML_MAPPING_NODE)
+ warnx("Invalid configuration format, ignoring the configuration file");
+ else
+ config_parse(&doc, node);
+ } else {
+ warnx("Invalid configuration format, ignoring the configuration file");
+ }
+
+ yaml_document_delete(&doc);
+ yaml_parser_delete(&parser);
+
+finalize:
+ if (c[ABI].val == NULL && c[ABI].value == NULL) {
+ if (pkg_get_myabi(abi, BUFSIZ) != 0)
+ errx(EXIT_FAILURE, "Failed to determine the system ABI");
+ c[ABI].val = abi;
+ }
+
+ subst_packagesite(c[ABI].value != NULL ? c[ABI].value : c[ABI].val);
+
+ return (0);
+}
+
+int
+config_string(pkg_config_key k, const char **val)
+{
+ if (c[k].type != PKG_CONFIG_STRING)
+ return (-1);
+
+ if (c[k].value != NULL)
+ *val = c[k].value;
+ else
+ *val = c[k].val;
+
+ return (0);
+}
+
+int
+config_bool(pkg_config_key k, bool *val)
+{
+ const char *value;
+
+ if (c[k].type != PKG_CONFIG_BOOL)
+ return (-1);
+
+ *val = false;
+
+ if (c[k].value != NULL)
+ value = c[k].value;
+ else
+ value = c[k].val;
+
+ if (strcasecmp(value, "true") == 0 ||
+ strcasecmp(value, "yes") == 0 ||
+ strcasecmp(value, "on") == 0 ||
+ *value == '1')
+ *val = true;
+
+ return (0);
+}
+
+void
+config_finish(void) {
+ int i;
+
+ for (i = 0; i < CONFIG_SIZE; i++)
+ free(c[i].value);
+}
diff --git a/sys/fs/hpfs/hpfs_ioctl.h b/usr.sbin/pkg/config.h
index 7f60729..e592f6d 100644
--- a/sys/fs/hpfs/hpfs_ioctl.h
+++ b/usr.sbin/pkg/config.h
@@ -1,5 +1,5 @@
/*-
- * Copyright (c) 1998, 1999 Semen Ustimenko (semenu@FreeBSD.org)
+ * Copyright (c) 2013 Baptiste Daroussin <bapt@FreeBSD.org>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -10,7 +10,7 @@
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
- *
+ *
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
@@ -26,18 +26,27 @@
* $FreeBSD$
*/
-#ifndef _HPFS_IOCTL_H_
-#define _HPFS_IOCTL_H_
-#include <sys/ioccom.h>
+#ifndef _PKG_CONFIG_H
+#define _PKG_CONFIG_H
+
+#define _LOCALBASE "/usr/local"
+
+typedef enum {
+ PACKAGESITE = 0,
+ ABI,
+ MIRROR_TYPE,
+ ASSUME_ALWAYS_YES,
+ CONFIG_SIZE
+} pkg_config_key;
-struct hpfs_rdea {
- u_long ea_no;
- u_long ea_sz;
- void * ea_data;
-};
+typedef enum {
+ PKG_CONFIG_STRING=0,
+ PKG_CONFIG_BOOL,
+} pkg_config_t;
-#define HPFSIOCGEANUM _IOR('H', 0, u_long) /* Get EA number */
-#define HPFSIOCGEASZ _IOWR('H', 1, u_long) /* Get EA size */
-#define HPFSIOCRDEA _IOWR('H', 2, struct hpfs_rdea) /* Read EA */
+int config_init(void);
+void config_finish(void);
+int config_string(pkg_config_key, const char **);
+int config_bool(pkg_config_key, bool *);
#endif
diff --git a/usr.sbin/pkg/pkg.c b/usr.sbin/pkg/pkg.c
index 32591f3..ccb1b91 100644
--- a/usr.sbin/pkg/pkg.c
+++ b/usr.sbin/pkg/pkg.c
@@ -1,5 +1,5 @@
/*-
- * Copyright (c) 2012 Baptiste Daroussin <bapt@FreeBSD.org>
+ * Copyright (c) 2012-2013 Baptiste Daroussin <bapt@FreeBSD.org>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -28,175 +28,23 @@
__FBSDID("$FreeBSD$");
#include <sys/param.h>
-#include <sys/elf_common.h>
-#include <sys/endian.h>
#include <sys/wait.h>
#include <archive.h>
#include <archive_entry.h>
-#include <ctype.h>
#include <err.h>
#include <errno.h>
-#include <fcntl.h>
#include <fetch.h>
-#include <gelf.h>
#include <paths.h>
+#include <stdbool.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <time.h>
#include <unistd.h>
-#include "elf_tables.h"
#include "dns_utils.h"
-
-#define _LOCALBASE "/usr/local"
-#define _PKGS_URL "http://pkg.FreeBSD.org"
-
-static const char *
-elf_corres_to_string(struct _elf_corres *m, int e)
-{
- int i;
-
- for (i = 0; m[i].string != NULL; i++)
- if (m[i].elf_nb == e)
- return (m[i].string);
-
- return ("unknown");
-}
-
-static int
-pkg_get_myabi(char *dest, size_t sz)
-{
- Elf *elf;
- Elf_Data *data;
- Elf_Note note;
- Elf_Scn *scn;
- char *src, *osname;
- const char *abi;
- GElf_Ehdr elfhdr;
- GElf_Shdr shdr;
- int fd, i, ret;
- uint32_t version;
-
- version = 0;
- ret = -1;
- scn = NULL;
- abi = NULL;
-
- if (elf_version(EV_CURRENT) == EV_NONE) {
- warnx("ELF library initialization failed: %s",
- elf_errmsg(-1));
- return (-1);
- }
-
- if ((fd = open("/bin/sh", O_RDONLY)) < 0) {
- warn("open()");
- return (-1);
- }
-
- if ((elf = elf_begin(fd, ELF_C_READ, NULL)) == NULL) {
- ret = -1;
- warnx("elf_begin() failed: %s.", elf_errmsg(-1));
- goto cleanup;
- }
-
- if (gelf_getehdr(elf, &elfhdr) == NULL) {
- ret = -1;
- warn("getehdr() failed: %s.", elf_errmsg(-1));
- goto cleanup;
- }
-
- while ((scn = elf_nextscn(elf, scn)) != NULL) {
- if (gelf_getshdr(scn, &shdr) != &shdr) {
- ret = -1;
- warn("getshdr() failed: %s.", elf_errmsg(-1));
- goto cleanup;
- }
-
- if (shdr.sh_type == SHT_NOTE)
- break;
- }
-
- if (scn == NULL) {
- ret = -1;
- warn("failed to get the note section");
- goto cleanup;
- }
-
- data = elf_getdata(scn, NULL);
- src = data->d_buf;
- for (;;) {
- memcpy(&note, src, sizeof(Elf_Note));
- src += sizeof(Elf_Note);
- if (note.n_type == NT_VERSION)
- break;
- src += note.n_namesz + note.n_descsz;
- }
- osname = src;
- src += note.n_namesz;
- if (elfhdr.e_ident[EI_DATA] == ELFDATA2MSB)
- version = be32dec(src);
- else
- version = le32dec(src);
-
- for (i = 0; osname[i] != '\0'; i++)
- osname[i] = (char)tolower(osname[i]);
-
- snprintf(dest, sz, "%s:%d:%s:%s",
- osname, version / 100000,
- elf_corres_to_string(mach_corres, (int)elfhdr.e_machine),
- elf_corres_to_string(wordsize_corres,
- (int)elfhdr.e_ident[EI_CLASS]));
-
- ret = 0;
-
- switch (elfhdr.e_machine) {
- case EM_ARM:
- snprintf(dest + strlen(dest), sz - strlen(dest),
- ":%s:%s:%s", elf_corres_to_string(endian_corres,
- (int)elfhdr.e_ident[EI_DATA]),
- (elfhdr.e_flags & EF_ARM_NEW_ABI) > 0 ?
- "eabi" : "oabi",
- (elfhdr.e_flags & EF_ARM_VFP_FLOAT) > 0 ?
- "softfp" : "vfp");
- break;
- case EM_MIPS:
- /*
- * this is taken from binutils sources:
- * include/elf/mips.h
- * mapping is figured out from binutils:
- * gas/config/tc-mips.c
- */
- switch (elfhdr.e_flags & EF_MIPS_ABI) {
- case E_MIPS_ABI_O32:
- abi = "o32";
- break;
- case E_MIPS_ABI_N32:
- abi = "n32";
- break;
- default:
- if (elfhdr.e_ident[EI_DATA] ==
- ELFCLASS32)
- abi = "o32";
- else if (elfhdr.e_ident[EI_DATA] ==
- ELFCLASS64)
- abi = "n64";
- break;
- }
- snprintf(dest + strlen(dest), sz - strlen(dest),
- ":%s:%s", elf_corres_to_string(endian_corres,
- (int)elfhdr.e_ident[EI_DATA]), abi);
- break;
- }
-
-cleanup:
- if (elf != NULL)
- elf_end(elf);
-
- close(fd);
- return (ret);
-}
+#include "config.h"
static int
extract_pkg_static(int fd, char *p, int sz)
@@ -291,8 +139,8 @@ bootstrap_pkg(void)
char zone[MAXHOSTNAMELEN + 13];
char url[MAXPATHLEN];
char conf[MAXPATHLEN];
- char abi[BUFSIZ];
char tmppkg[MAXPATHLEN];
+ const char *packagesite, *mirror_type;
char buf[10240];
char pkgstatic[MAXPATHLEN];
int fd, retry, ret, max_retry;
@@ -311,17 +159,15 @@ bootstrap_pkg(void)
printf("Bootstrapping pkg please wait\n");
- if (pkg_get_myabi(abi, MAXPATHLEN) != 0) {
- warnx("failed to determine the system ABI");
+ if (config_string(PACKAGESITE, &packagesite) != 0) {
+ warnx("No PACKAGESITE defined");
return (-1);
}
-
- if (getenv("PACKAGESITE") != NULL)
- snprintf(url, MAXPATHLEN, "%s/Latest/pkg.txz", getenv("PACKAGESITE"));
- else
- snprintf(url, MAXPATHLEN, "%s/%s/latest/Latest/pkg.txz",
- getenv("PACKAGEROOT") ? getenv("PACKAGEROOT") : _PKGS_URL,
- getenv("ABI") ? getenv("ABI") : abi);
+ if (config_string(MIRROR_TYPE, &mirror_type) != 0) {
+ warnx("No MIRROR_TYPE defined");
+ return (-1);
+ }
+ snprintf(url, MAXPATHLEN, "%s/latest/Latest/pkg.txz", packagesite);
snprintf(tmppkg, MAXPATHLEN, "%s/pkg.txz.XXXXXX",
getenv("TMPDIR") ? getenv("TMPDIR") : _PATH_TMP);
@@ -336,10 +182,10 @@ bootstrap_pkg(void)
u = fetchParseURL(url);
while (remote == NULL) {
if (retry == max_retry) {
- if (strcmp(u->scheme, "file") != 0) {
+ if (strcmp(u->scheme, "file") != 0 &&
+ strcasecmp(mirror_type, "srv") == 0) {
snprintf(zone, sizeof(zone),
"_%s._tcp.%s", u->scheme, u->host);
- printf("%s\n", zone);
mirrors = dns_getsrvinfo(zone);
current = mirrors;
}
@@ -449,6 +295,7 @@ int
main(__unused int argc, char *argv[])
{
char pkgpath[MAXPATHLEN];
+ bool yes = false;
snprintf(pkgpath, MAXPATHLEN, "%s/sbin/pkg",
getenv("LOCALBASE") ? getenv("LOCALBASE") : _LOCALBASE);
@@ -467,7 +314,9 @@ main(__unused int argc, char *argv[])
* not tty. Check the environment to see if user has answer
* tucked in there already.
*/
- if (getenv("ASSUME_ALWAYS_YES") == NULL) {
+ config_init();
+ config_bool(ASSUME_ALWAYS_YES, &yes);
+ if (!yes) {
printf("%s", confirmation_message);
if (!isatty(fileno(stdin)))
exit(EXIT_FAILURE);
@@ -477,6 +326,7 @@ main(__unused int argc, char *argv[])
}
if (bootstrap_pkg() != 0)
exit(EXIT_FAILURE);
+ config_finish();
}
execv(pkgpath, argv);
diff --git a/usr.sbin/rtadvd/rtadvd.c b/usr.sbin/rtadvd/rtadvd.c
index 4d2a527..880b283 100644
--- a/usr.sbin/rtadvd/rtadvd.c
+++ b/usr.sbin/rtadvd/rtadvd.c
@@ -1008,6 +1008,8 @@ set_short_delay(struct ifinfo *ifi)
long delay; /* must not be greater than 1000000 */
struct timeval interval, now, min_delay, tm_tmp, *rest;
+ if (ifi->ifi_ra_timer == NULL)
+ return;
/*
* Compute a random delay. If the computed value
* corresponds to a time later than the time the next
diff --git a/usr.sbin/tzsetup/tzsetup.c b/usr.sbin/tzsetup/tzsetup.c
index 97daa0b..cea8533 100644
--- a/usr.sbin/tzsetup/tzsetup.c
+++ b/usr.sbin/tzsetup/tzsetup.c
@@ -703,8 +703,13 @@ install_zoneinfo_file(const char *zoneinfo_file)
return (DITEM_FAILURE | DITEM_RECREATE);
}
#ifdef VERBOSE
+ snprintf(title, sizeof(title), "Done");
snprintf(prompt, sizeof(prompt),
"Removed %s", path_localtime);
+ if (usedialog)
+ dialog_msgbox(title, prompt, 8, 72, 1);
+ else
+ fprintf(stderr, "%s\n", prompt);
#endif
return (DITEM_LEAVE_MENU);
}
OpenPOWER on IntegriCloud