{ "schema": "pre15-gate-v1", "unit": "G09/P15-032", "batch": "B39", "frozen_base": "bd5a09054e5cf89efd4db82aadb051f20b06ebf7", "freebsd_source": { "outer_git_head": "106727738dcfb6c001b46f25363b91cece970085", "identity": "per-contract-file-sha256" }, "timeouts_seconds": { "whole_gate": 120, "command": 10, "compile": 20, "model": 10 }, "syntax_policy": { "vnode": "vnode:/absolute/path", "geom": "geom:/provider-or-device-path", "legacy_geom": "/provider-or-device-path", "ambiguous_regular_path_is_vnode": false, "multidevice": "all sources in one mount must use the same backend kind" }, "typed_errno": { "cycle": "EDEADLK", "unsupported_dependency_graph": "EOPNOTSUPP", "changed_or_short_source": "EIO", "dead_forced_source": "ENXIO" }, "required_events": [ "parse_tagged_source", "namei_lockleaf", "require_vreg", "resolve_vop_getlowvnode", "check_self_identity", "check_namespace_ancestors", "trace_storage_ancestors", "vop_access", "vn_open_vnode_fread", "crhold_mount_cred", "vop_set_text", "register_upper_mount", "snapshot_size", "first_io", "io_complete", "mark_closing", "drain_inflight", "vflush", "unregister_upper_mount", "vop_unset_text", "vn_close", "crfree_mount_cred", "release_last_reference" ], "required_invariants": [ "explicit_backend_tag", "held_vnode_identity", "held_credential", "held_credential_used_for_read", "kernel_space_read_buffer", "source_range_lock", "source_shared_vnode_lock", "write_exclusion", "size_snapshot_and_short_read_error", "self_check_before_io", "namespace_ancestor_check_before_io", "storage_ancestor_check_before_io", "upper_mount_registration", "inflight_drain_before_release", "same_backend_multidevice", "geom_and_vnode_paths_disjoint", "fault_injection_tc179_constructible", "fault_injection_tc184_constructible" ], "lock_edges": [ ["vfs_mount_busy", "erofs_vnode_lock"], ["erofs_vnode_lock", "source_range_lock"], ["source_range_lock", "source_vnode_lock"], ["source_vnode_lock", "source_vop_read"], ["erofs_vm_object_lock", "erofs_vm_object_unlock_before_vop_read"], ["erofs_vm_object_unlock_before_vop_read", "erofs_vnode_lock"], ["geom_topology_lock", "geom_open_close_only"], ["mark_closing", "drain_inflight"], ["drain_inflight", "vflush"], ["vflush", "unregister_upper_mount"], ["unregister_upper_mount", "source_vnode_close"], ["source_vnode_close", "credential_release"], ["credential_release", "last_reference_release"] ], "false_go_controls": [ "explicit_backend_tag", "held_vnode_identity", "held_credential", "held_credential_used_for_read", "kernel_space_read_buffer", "source_range_lock", "source_shared_vnode_lock", "write_exclusion", "size_snapshot_and_short_read_error", "self_check_before_io", "namespace_ancestor_check_before_io", "upper_mount_registration", "inflight_drain_before_release", "same_backend_multidevice", "geom_and_vnode_paths_disjoint", "fault_injection_tc179_constructible", "fault_injection_tc184_constructible" ], "contracts": [ { "root": "freebsd", "path": "sys/kern/vnode_if.src", "sha256": "5de87ff115f543fd89f762c3d356b6799f30757f8a34fd840370ce7fff53b90b", "must_contain": ["%% read\t\tvp\tL L L", "%% getlowvnode vp\t= = =", "%% getpages\tvp\tL L L", "%% set_text\tvp\t= = ="] }, { "root": "freebsd", "path": "sys/kern/vfs_vnops.c", "sha256": "3bc9735e2a190fc55134a803f5fc8cb6f020b0b1ce925261774db32789bd7f08", "must_contain": ["vn_rdwr(enum uio_rw rw", "vn_rangelock_rlock(vp", "vn_lock(vp, lock_flags | LK_RETRY);", "VOP_READ(vp, &auio, ioflg, cred);"] }, { "root": "freebsd", "path": "sys/kern/vfs_default.c", "sha256": "4286a9bf038c32021f5c116d8ab713b09a5cfa43cf52999bcbf2c0018e7aa177", "must_contain": ["vop_stdset_text(struct vop_set_text_args *ap)", "return (ETXTBSY);", "vop_stdunset_text(struct vop_unset_text_args *ap)", "vop_stdadd_writecount_impl", "vop_stdgetlowvnode(struct vop_getlowvnode_args *ap)"] }, { "root": "freebsd", "path": "sys/kern/vfs_mount.c", "sha256": "eecd22aaf63eda940798af02d2d3068a6ed3dc2d90b74a936190a7e56db0a79a", "must_contain": ["vfs_register_upper_from_vp(struct vnode *vp", "ensure that it cannot be unmounted", "KASSERT(ump != mp", "vfs_unregister_upper(struct mount *mp", "registered upper with pending unmount"] }, { "root": "freebsd", "path": "sys/sys/mount.h", "sha256": "2bc2017d63389c39dfee52b3041970450ef1eebaa149c8fe5e84a871c0f0b738", "must_contain": ["struct mount_upper_node", "struct vnode\t*mnt_vnodecovered", "void *\t\tmnt_data"], "must_not_contain": ["struct g_provider", "struct g_consumer"] }, { "root": "freebsd", "path": "sys/vm/vnode_pager.c", "sha256": "6e2bd8a57bb1c027f303db7bf0e2351fa67af5ca53d6b2b826fa1f12f2c5154e", "must_contain": ["vnode_pager_input_old(vm_object_t object", "VM_OBJECT_WUNLOCK(object);", "auio.uio_segflg = UIO_SYSSPACE;", "VOP_READ(vp, &auio, 0, curthread->td_ucred);"] }, { "root": "freebsd", "path": "sys/fs/tarfs/tarfs_vfsops.c", "sha256": "b4c1a5c7f8870c816917706ed0e4dafd790ca5374690833d8daa321aafb696c1", "must_contain": ["vn_open_vnode", "vn_close"] }, { "root": "freebsd", "path": "sys/fs/tarfs/tarfs_io.c", "sha256": "0c255ba14df3ff7dcec346dee99c9ddbee376e3483370bb7257dffe2f529fc6c", "must_contain": ["vn_rangelock_rlock", "VOP_READ"] }, { "root": "freebsd", "path": "sys/fs/deadfs/dead_vnops.c", "sha256": "1d6864e8cc035ad109ac60c3dab67f31b9c3ad70bee9f9e585b6be10a5657b73", "must_contain": ["dead_read", "return (ENXIO);"] }, { "root": "freebsd", "path": "sys/fs/nullfs/null_vnops.c", "sha256": "b10c2138b649343e6c49a9416b6f4f3a0894388059122eefa190430e13695d6c", "must_contain": ["VOP_GETLOWVNODE"] }, { "root": "freebsd", "path": "sys/fs/nullfs/null_vfsops.c", "sha256": "f5f8803458522d9cecb1e024bdd599630dde02bc1e0578445204602b4db633bd", "must_contain": ["vfs_register_upper_from_vp", "VFCF_LOOPBACK"] }, { "root": "freebsd", "path": "sys/fs/unionfs/union_vnops.c", "sha256": "ce9a41531731170a340e39bfe6afd29f4740d8b705abb6a018176c7a1e159aff", "must_contain": ["VOP_GETLOWVNODE"] }, { "root": "freebsd", "path": "sys/fs/unionfs/union_vfsops.c", "sha256": "c181c0134887a0d8697b739dbbf54b7c4299f337bbd4a3e6e1d62a1b6bfb1b51", "must_contain": ["vfs_register_upper_from_vp", "VFCF_LOOPBACK"] }, { "root": "freebsd", "path": "sys/dev/md/md.c", "sha256": "a19d34da3d391747fbe2e8bee9fbb02a361202351a0b8bfbec1abc7b5a3f2d4b", "must_contain": ["struct md_s {", "struct vnode *vnode;", "gp->softc = sc;", "g_new_providerf(gp, \"md%d\"", "VOP_READ(vp, &auio, 0, sc->cred);", "sbuf_printf(sb, \" file %s\", mp->s_vnode.file);"] }, { "root": "freebsd", "path": "sys/geom/geom.h", "sha256": "22feba6781dcc4e0aae0dea75b83dcae16d077be67853331da35d06edffb0f39", "must_contain": ["struct g_geom", "void\t\t\t*softc;"], "must_not_contain": ["struct vnode"] }, { "root": "repo_base", "path": "repo-pre-15/src/internal.h", "sha256": "3fe8d6ca819f0a1c472cc4b173da80027f957b7f7c25e51ef7fd85b60480c98a", "must_contain": ["struct erofs_device_info", "struct g_consumer *cp;"] }, { "root": "repo_base", "path": "repo-pre-15/src/super.c", "sha256": "61f31906bb7d1872c99cd3cf3859a34daf29a02d91a3caa1bfc8187af562a3d2", "must_contain": ["erofs_open_device", "g_vfs_open", "erofs_read_superblock"] }, { "root": "repo_base", "path": "repo-pre-15/src/data.c", "sha256": "a511146d2d1ff56bc88bae6c550cfdc49a8e978c5c2c88d735de92adaaa836b6", "must_contain": ["erofs_bread_device", "bread(dif->devvp"] }, { "root": "repo_base", "path": "repo-pre-15/src/erofs_vnops.c", "sha256": "f28555606ca006d1646a2fee75b98b2f7452d4283c00b087012b8a6c4ef4bf64", "must_contain": ["vnode_pager_local_getpages", "erofs_read_file"] }, { "root": "linux_reference", "path": "src-linux/fileio.c", "sha256": "1f00f6cee0060072e8300a2e4f7ca8cd2dc566f129b99d2ed34288b19210e59c", "must_contain": ["erofs_fileio"] }, { "root": "linux_reference", "path": "src-linux/super.c", "sha256": "8bda458cca758d8aa9c5a5b05361b2131b896f73fd194f6ad9a8e011e3481bf9", "must_contain": ["s_stack_depth"] } ], "blocking_condition": { "id": "FREEBSD-GEOM-VNODE-ANCESTRY-NO-PUBLIC-IDENTITY-EDGE", "classification": "STOP", "summary": "The transitive storage ancestry of a regular source vnode cannot be discovered generically before first I/O.", "counterexample": [ "An accepted regular source vnode is on a filesystem consuming an md(4) GEOM provider.", "The md provider services BIO_READ by VOP_READ on md_s.s_vnode.vnode.", "That vnode identity is private md.c softc state; GEOM exposes only void *softc and dumpconf exposes a pathname.", "VOP_GETLOWVNODE and vfs_register_upper_from_vp cover VFS alias/lower mounts only, not GEOM-to-vnode backing edges.", "A pathname cannot close identity across rename/replace, so it cannot implement the required ancestor identity comparison.", "Following gp->softc by duplicating private md_s is an undocumented class-specific assumption and still does not cover other GEOM or filesystem-private file-backed storage." ] } }