1994-06-08 15:28:29 +04:00
|
|
|
#!/bin/sh -
|
1996-02-29 23:54:58 +03:00
|
|
|
copyright="\
|
1994-06-15 19:49:03 +04:00
|
|
|
/*
|
1998-03-01 05:20:01 +03:00
|
|
|
* Copyright (c) 1992, 1993, 1994, 1995
|
1994-06-15 19:49:03 +04:00
|
|
|
* 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.
|
2003-08-07 20:26:28 +04:00
|
|
|
* 3. Neither the name of the University nor the names of its contributors
|
1994-06-15 19:49:03 +04:00
|
|
|
* may be used to endorse or promote products derived from this software
|
|
|
|
* without specific prior written permission.
|
|
|
|
*
|
1998-09-13 18:44:34 +04:00
|
|
|
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS \`\`AS IS'' AND
|
1994-06-15 19:49:03 +04:00
|
|
|
* 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.
|
|
|
|
*/
|
1996-02-29 23:54:58 +03:00
|
|
|
"
|
Overhaul of the EVFILT_VNODE kevent(2) filter:
- Centralize vnode kevent handling in the VOP_*() wrappers, rather than
forcing each individual file system to deal with it (except VOP_RENAME(),
because VOP_RENAME() is a mess and we currently have 2 different ways
of handling it; at least it's reasonably well-centralized in the "new"
way).
- Add support for NOTE_OPEN, NOTE_CLOSE, NOTE_CLOSE_WRITE, and NOTE_READ,
compatible with the same events in FreeBSD.
- Track which kevent notifications clients are interested in receiving
to avoid doing work for events no one cares about (avoiding, e.g.
taking locks and traversing the klist to send a NOTE_WRITE when
someone is merely watching for a file to be deleted, for example).
In support of the above:
- Add support in vnode_if.sh for specifying PRE- and POST-op handlers,
to be invoked before and after vop_pre() and vop_post(), respectively.
Basic idea from FreeBSD, but implemented differently.
- Add support in vnode_if.sh for specifying CONTEXT fields in the
vop_*_args structures. These context fields are used to convey information
between the file system VOP function and the VOP wrapper, but do not
occupy an argument slot in the VOP_*() call itself. These context fields
are initialized and subsequently interpreted by PRE- and POST-op handlers.
- Version VOP_REMOVE(), uses the a context field for the file system to report
back the resulting link count of the target vnode. Return this in tmpfs,
udf, nfs, chfs, ext2fs, lfs, and ufs.
NetBSD 9.99.92.
2021-10-20 06:08:16 +03:00
|
|
|
SCRIPT_ID='$NetBSD: vnode_if.sh,v 1.72 2021/10/20 03:08:18 thorpej Exp $'
|
1994-06-08 15:28:29 +04:00
|
|
|
|
|
|
|
# Script to produce VFS front-end sugar.
|
|
|
|
#
|
|
|
|
# usage: vnode_if.sh srcfile
|
|
|
|
# (where srcfile is currently /sys/kern/vnode_if.src)
|
|
|
|
#
|
|
|
|
|
|
|
|
if [ $# -ne 1 ] ; then
|
|
|
|
echo 'usage: vnode_if.sh srcfile'
|
|
|
|
exit 1
|
|
|
|
fi
|
|
|
|
|
1996-02-29 23:54:58 +03:00
|
|
|
# Name and revision of the source file.
|
1994-06-15 19:49:03 +04:00
|
|
|
src=$1
|
1996-02-29 23:54:58 +03:00
|
|
|
SRC_ID=`head -1 $src | sed -e 's/.*\$\(.*\)\$.*/\1/'`
|
1994-06-08 15:28:29 +04:00
|
|
|
|
|
|
|
# Names of the created files.
|
1994-06-15 19:49:03 +04:00
|
|
|
out_c=vnode_if.c
|
2008-11-19 17:10:48 +03:00
|
|
|
out_rumpc=../rump/librump/rumpvfs/rumpvnode_if.c
|
1996-02-29 23:54:58 +03:00
|
|
|
out_h=../sys/vnode_if.h
|
2008-11-17 11:46:03 +03:00
|
|
|
out_rumph=../rump/include/rump/rumpvnode_if.h
|
1994-06-15 19:49:03 +04:00
|
|
|
|
2009-09-29 15:51:02 +04:00
|
|
|
# generate VNODE_LOCKDEBUG checks (not fully functional)
|
|
|
|
lockdebug=0
|
|
|
|
|
1994-06-15 19:49:03 +04:00
|
|
|
# Awk program (must support nawk extensions)
|
|
|
|
# Use "awk" at Berkeley, "nawk" or "gawk" elsewhere.
|
|
|
|
awk=${AWK:-awk}
|
|
|
|
|
|
|
|
# Does this awk have a "toupper" function? (i.e. is it GNU awk)
|
|
|
|
isgawk=`$awk 'BEGIN { print toupper("true"); exit; }' 2>/dev/null`
|
|
|
|
|
|
|
|
# If this awk does not define "toupper" then define our own.
|
|
|
|
if [ "$isgawk" = TRUE ] ; then
|
|
|
|
# GNU awk provides it.
|
|
|
|
toupper=
|
|
|
|
else
|
|
|
|
# Provide our own toupper()
|
|
|
|
toupper='
|
|
|
|
function toupper(str) {
|
|
|
|
_toupper_cmd = "echo "str" |tr a-z A-Z"
|
|
|
|
_toupper_cmd | getline _toupper_str;
|
|
|
|
close(_toupper_cmd);
|
|
|
|
return _toupper_str;
|
|
|
|
}'
|
|
|
|
fi
|
1994-06-08 15:28:29 +04:00
|
|
|
|
1994-06-15 19:49:03 +04:00
|
|
|
#
|
|
|
|
# This is the common part of all awk programs that read $src
|
|
|
|
# This parses the input for one function into the arrays:
|
|
|
|
# argdir, argtype, argname, willrele
|
|
|
|
# and calls "doit()" to generate output for the function.
|
|
|
|
#
|
|
|
|
# Input to this parser is pre-processed slightly by sed
|
|
|
|
# so this awk parser doesn't have to work so hard. The
|
|
|
|
# changes done by the sed pre-processing step are:
|
2021-08-12 22:15:15 +03:00
|
|
|
# insert a space between * and pointer name
|
1994-06-15 19:49:03 +04:00
|
|
|
# replace semicolons with spaces
|
|
|
|
#
|
|
|
|
sed_prep='s:\*\([^\*/]\):\* \1:g
|
|
|
|
s/;/ /'
|
|
|
|
awk_parser='
|
|
|
|
# Comment line
|
|
|
|
/^#/ { next; }
|
|
|
|
# First line of description
|
|
|
|
/^vop_/ {
|
2010-04-14 17:58:51 +04:00
|
|
|
name=$1;
|
2014-01-13 16:07:55 +04:00
|
|
|
args_name=$1;
|
1994-06-15 19:49:03 +04:00
|
|
|
argc=0;
|
Overhaul of the EVFILT_VNODE kevent(2) filter:
- Centralize vnode kevent handling in the VOP_*() wrappers, rather than
forcing each individual file system to deal with it (except VOP_RENAME(),
because VOP_RENAME() is a mess and we currently have 2 different ways
of handling it; at least it's reasonably well-centralized in the "new"
way).
- Add support for NOTE_OPEN, NOTE_CLOSE, NOTE_CLOSE_WRITE, and NOTE_READ,
compatible with the same events in FreeBSD.
- Track which kevent notifications clients are interested in receiving
to avoid doing work for events no one cares about (avoiding, e.g.
taking locks and traversing the klist to send a NOTE_WRITE when
someone is merely watching for a file to be deleted, for example).
In support of the above:
- Add support in vnode_if.sh for specifying PRE- and POST-op handlers,
to be invoked before and after vop_pre() and vop_post(), respectively.
Basic idea from FreeBSD, but implemented differently.
- Add support in vnode_if.sh for specifying CONTEXT fields in the
vop_*_args structures. These context fields are used to convey information
between the file system VOP function and the VOP wrapper, but do not
occupy an argument slot in the VOP_*() call itself. These context fields
are initialized and subsequently interpreted by PRE- and POST-op handlers.
- Version VOP_REMOVE(), uses the a context field for the file system to report
back the resulting link count of the target vnode. Return this in tmpfs,
udf, nfs, chfs, ext2fs, lfs, and ufs.
NetBSD 9.99.92.
2021-10-20 06:08:16 +03:00
|
|
|
have_context=0;
|
|
|
|
is_context=0;
|
|
|
|
ncontext=0;
|
2007-07-23 01:26:53 +04:00
|
|
|
willmake=-1;
|
2017-06-04 10:59:17 +03:00
|
|
|
fstrans="";
|
Overhaul of the EVFILT_VNODE kevent(2) filter:
- Centralize vnode kevent handling in the VOP_*() wrappers, rather than
forcing each individual file system to deal with it (except VOP_RENAME(),
because VOP_RENAME() is a mess and we currently have 2 different ways
of handling it; at least it's reasonably well-centralized in the "new"
way).
- Add support for NOTE_OPEN, NOTE_CLOSE, NOTE_CLOSE_WRITE, and NOTE_READ,
compatible with the same events in FreeBSD.
- Track which kevent notifications clients are interested in receiving
to avoid doing work for events no one cares about (avoiding, e.g.
taking locks and traversing the klist to send a NOTE_WRITE when
someone is merely watching for a file to be deleted, for example).
In support of the above:
- Add support in vnode_if.sh for specifying PRE- and POST-op handlers,
to be invoked before and after vop_pre() and vop_post(), respectively.
Basic idea from FreeBSD, but implemented differently.
- Add support in vnode_if.sh for specifying CONTEXT fields in the
vop_*_args structures. These context fields are used to convey information
between the file system VOP function and the VOP wrapper, but do not
occupy an argument slot in the VOP_*() call itself. These context fields
are initialized and subsequently interpreted by PRE- and POST-op handlers.
- Version VOP_REMOVE(), uses the a context field for the file system to report
back the resulting link count of the target vnode. Return this in tmpfs,
udf, nfs, chfs, ext2fs, lfs, and ufs.
NetBSD 9.99.92.
2021-10-20 06:08:16 +03:00
|
|
|
do_pre="";
|
|
|
|
do_post="";
|
1994-06-15 19:49:03 +04:00
|
|
|
next;
|
|
|
|
}
|
|
|
|
# Last line of description
|
|
|
|
/^}/ {
|
|
|
|
doit();
|
|
|
|
next;
|
|
|
|
}
|
|
|
|
# Middle lines of description
|
|
|
|
{
|
2014-01-13 16:07:55 +04:00
|
|
|
if ($1 == "VERSION") {
|
|
|
|
args_name=args_name "_v" $2;
|
|
|
|
next;
|
2017-06-04 10:59:17 +03:00
|
|
|
} else if ($1 ~ "^FSTRANS=") {
|
|
|
|
fstrans = $1;
|
|
|
|
sub("FSTRANS=", "", fstrans);
|
2017-02-22 12:45:51 +03:00
|
|
|
next;
|
Overhaul of the EVFILT_VNODE kevent(2) filter:
- Centralize vnode kevent handling in the VOP_*() wrappers, rather than
forcing each individual file system to deal with it (except VOP_RENAME(),
because VOP_RENAME() is a mess and we currently have 2 different ways
of handling it; at least it's reasonably well-centralized in the "new"
way).
- Add support for NOTE_OPEN, NOTE_CLOSE, NOTE_CLOSE_WRITE, and NOTE_READ,
compatible with the same events in FreeBSD.
- Track which kevent notifications clients are interested in receiving
to avoid doing work for events no one cares about (avoiding, e.g.
taking locks and traversing the klist to send a NOTE_WRITE when
someone is merely watching for a file to be deleted, for example).
In support of the above:
- Add support in vnode_if.sh for specifying PRE- and POST-op handlers,
to be invoked before and after vop_pre() and vop_post(), respectively.
Basic idea from FreeBSD, but implemented differently.
- Add support in vnode_if.sh for specifying CONTEXT fields in the
vop_*_args structures. These context fields are used to convey information
between the file system VOP function and the VOP wrapper, but do not
occupy an argument slot in the VOP_*() call itself. These context fields
are initialized and subsequently interpreted by PRE- and POST-op handlers.
- Version VOP_REMOVE(), uses the a context field for the file system to report
back the resulting link count of the target vnode. Return this in tmpfs,
udf, nfs, chfs, ext2fs, lfs, and ufs.
NetBSD 9.99.92.
2021-10-20 06:08:16 +03:00
|
|
|
} else if ($1 ~ "^PRE=") {
|
|
|
|
do_pre = $1;
|
|
|
|
sub("PRE=", "", do_pre);
|
|
|
|
next;
|
|
|
|
} else if ($1 ~ "^POST=") {
|
|
|
|
do_post = $1;
|
|
|
|
sub("POST=", "", do_post);
|
|
|
|
next;
|
2014-01-13 16:07:55 +04:00
|
|
|
}
|
|
|
|
|
Overhaul of the EVFILT_VNODE kevent(2) filter:
- Centralize vnode kevent handling in the VOP_*() wrappers, rather than
forcing each individual file system to deal with it (except VOP_RENAME(),
because VOP_RENAME() is a mess and we currently have 2 different ways
of handling it; at least it's reasonably well-centralized in the "new"
way).
- Add support for NOTE_OPEN, NOTE_CLOSE, NOTE_CLOSE_WRITE, and NOTE_READ,
compatible with the same events in FreeBSD.
- Track which kevent notifications clients are interested in receiving
to avoid doing work for events no one cares about (avoiding, e.g.
taking locks and traversing the klist to send a NOTE_WRITE when
someone is merely watching for a file to be deleted, for example).
In support of the above:
- Add support in vnode_if.sh for specifying PRE- and POST-op handlers,
to be invoked before and after vop_pre() and vop_post(), respectively.
Basic idea from FreeBSD, but implemented differently.
- Add support in vnode_if.sh for specifying CONTEXT fields in the
vop_*_args structures. These context fields are used to convey information
between the file system VOP function and the VOP wrapper, but do not
occupy an argument slot in the VOP_*() call itself. These context fields
are initialized and subsequently interpreted by PRE- and POST-op handlers.
- Version VOP_REMOVE(), uses the a context field for the file system to report
back the resulting link count of the target vnode. Return this in tmpfs,
udf, nfs, chfs, ext2fs, lfs, and ufs.
NetBSD 9.99.92.
2021-10-20 06:08:16 +03:00
|
|
|
if ($1 == "CONTEXT") {
|
|
|
|
# CONTEXT require PRE and POST handlers.
|
|
|
|
if (do_pre == "" || do_post == "")
|
|
|
|
next;
|
|
|
|
is_context=1;
|
|
|
|
have_context=1;
|
|
|
|
} else {
|
|
|
|
if (have_context) {
|
|
|
|
# CONTEXT members must come at the end of
|
|
|
|
# the args structure, so everything else
|
|
|
|
# is ignored.
|
|
|
|
next;
|
|
|
|
}
|
|
|
|
argdir[argc] = $1;
|
2007-07-23 01:26:53 +04:00
|
|
|
}
|
Overhaul of the EVFILT_VNODE kevent(2) filter:
- Centralize vnode kevent handling in the VOP_*() wrappers, rather than
forcing each individual file system to deal with it (except VOP_RENAME(),
because VOP_RENAME() is a mess and we currently have 2 different ways
of handling it; at least it's reasonably well-centralized in the "new"
way).
- Add support for NOTE_OPEN, NOTE_CLOSE, NOTE_CLOSE_WRITE, and NOTE_READ,
compatible with the same events in FreeBSD.
- Track which kevent notifications clients are interested in receiving
to avoid doing work for events no one cares about (avoiding, e.g.
taking locks and traversing the klist to send a NOTE_WRITE when
someone is merely watching for a file to be deleted, for example).
In support of the above:
- Add support in vnode_if.sh for specifying PRE- and POST-op handlers,
to be invoked before and after vop_pre() and vop_post(), respectively.
Basic idea from FreeBSD, but implemented differently.
- Add support in vnode_if.sh for specifying CONTEXT fields in the
vop_*_args structures. These context fields are used to convey information
between the file system VOP function and the VOP wrapper, but do not
occupy an argument slot in the VOP_*() call itself. These context fields
are initialized and subsequently interpreted by PRE- and POST-op handlers.
- Version VOP_REMOVE(), uses the a context field for the file system to report
back the resulting link count of the target vnode. Return this in tmpfs,
udf, nfs, chfs, ext2fs, lfs, and ufs.
NetBSD 9.99.92.
2021-10-20 06:08:16 +03:00
|
|
|
i=2;
|
|
|
|
|
|
|
|
if (is_context == 0) {
|
|
|
|
if ($2 == "LOCKED=YES") {
|
|
|
|
lockstate[argc] = 1;
|
|
|
|
i++;
|
|
|
|
} else if ($2 == "LOCKED=NO") {
|
|
|
|
lockstate[argc] = 0;
|
|
|
|
i++;
|
|
|
|
} else
|
|
|
|
lockstate[argc] = -1;
|
|
|
|
|
|
|
|
if ($2 == "WILLRELE" ||
|
|
|
|
$3 == "WILLRELE") {
|
|
|
|
willrele[argc] = 1;
|
|
|
|
i++;
|
|
|
|
} else if ($2 == "WILLPUT" ||
|
|
|
|
$3 == "WILLPUT") {
|
|
|
|
willrele[argc] = 3;
|
|
|
|
i++;
|
|
|
|
} else
|
|
|
|
willrele[argc] = 0;
|
|
|
|
|
|
|
|
if ($2 == "WILLMAKE") {
|
|
|
|
willmake=argc;
|
|
|
|
i++;
|
|
|
|
}
|
|
|
|
if (argc == 0 && fstrans == "") {
|
|
|
|
if (lockstate[0] == 1)
|
|
|
|
fstrans = "NO";
|
|
|
|
else
|
|
|
|
fstrans = "YES";
|
|
|
|
}
|
2017-06-04 10:59:17 +03:00
|
|
|
}
|
2007-07-23 01:26:53 +04:00
|
|
|
|
2008-11-17 11:46:03 +03:00
|
|
|
# XXX: replace non-portable types for rump. We should really
|
|
|
|
# nuke the types from the kernel, but that is a battle for
|
|
|
|
# another day.
|
|
|
|
at = $i;
|
2010-04-14 17:58:51 +04:00
|
|
|
if (rump) {
|
2008-11-17 11:46:03 +03:00
|
|
|
if (at == "vm_prot_t")
|
|
|
|
at = "int";
|
|
|
|
if (at == "voff_t")
|
|
|
|
at = "off_t";
|
2010-04-14 17:58:51 +04:00
|
|
|
if (at == "kauth_cred_t")
|
|
|
|
at = "struct kauth_cred *"
|
2013-07-18 01:20:53 +04:00
|
|
|
if (at == "daddr_t")
|
|
|
|
at = "int64_t"
|
2008-11-17 11:46:03 +03:00
|
|
|
}
|
Overhaul of the EVFILT_VNODE kevent(2) filter:
- Centralize vnode kevent handling in the VOP_*() wrappers, rather than
forcing each individual file system to deal with it (except VOP_RENAME(),
because VOP_RENAME() is a mess and we currently have 2 different ways
of handling it; at least it's reasonably well-centralized in the "new"
way).
- Add support for NOTE_OPEN, NOTE_CLOSE, NOTE_CLOSE_WRITE, and NOTE_READ,
compatible with the same events in FreeBSD.
- Track which kevent notifications clients are interested in receiving
to avoid doing work for events no one cares about (avoiding, e.g.
taking locks and traversing the klist to send a NOTE_WRITE when
someone is merely watching for a file to be deleted, for example).
In support of the above:
- Add support in vnode_if.sh for specifying PRE- and POST-op handlers,
to be invoked before and after vop_pre() and vop_post(), respectively.
Basic idea from FreeBSD, but implemented differently.
- Add support in vnode_if.sh for specifying CONTEXT fields in the
vop_*_args structures. These context fields are used to convey information
between the file system VOP function and the VOP wrapper, but do not
occupy an argument slot in the VOP_*() call itself. These context fields
are initialized and subsequently interpreted by PRE- and POST-op handlers.
- Version VOP_REMOVE(), uses the a context field for the file system to report
back the resulting link count of the target vnode. Return this in tmpfs,
udf, nfs, chfs, ext2fs, lfs, and ufs.
NetBSD 9.99.92.
2021-10-20 06:08:16 +03:00
|
|
|
argtype[argc + ncontext] = at;
|
2008-11-17 11:46:03 +03:00
|
|
|
i++;
|
1994-06-15 19:49:03 +04:00
|
|
|
while (i < NF) {
|
Overhaul of the EVFILT_VNODE kevent(2) filter:
- Centralize vnode kevent handling in the VOP_*() wrappers, rather than
forcing each individual file system to deal with it (except VOP_RENAME(),
because VOP_RENAME() is a mess and we currently have 2 different ways
of handling it; at least it's reasonably well-centralized in the "new"
way).
- Add support for NOTE_OPEN, NOTE_CLOSE, NOTE_CLOSE_WRITE, and NOTE_READ,
compatible with the same events in FreeBSD.
- Track which kevent notifications clients are interested in receiving
to avoid doing work for events no one cares about (avoiding, e.g.
taking locks and traversing the klist to send a NOTE_WRITE when
someone is merely watching for a file to be deleted, for example).
In support of the above:
- Add support in vnode_if.sh for specifying PRE- and POST-op handlers,
to be invoked before and after vop_pre() and vop_post(), respectively.
Basic idea from FreeBSD, but implemented differently.
- Add support in vnode_if.sh for specifying CONTEXT fields in the
vop_*_args structures. These context fields are used to convey information
between the file system VOP function and the VOP wrapper, but do not
occupy an argument slot in the VOP_*() call itself. These context fields
are initialized and subsequently interpreted by PRE- and POST-op handlers.
- Version VOP_REMOVE(), uses the a context field for the file system to report
back the resulting link count of the target vnode. Return this in tmpfs,
udf, nfs, chfs, ext2fs, lfs, and ufs.
NetBSD 9.99.92.
2021-10-20 06:08:16 +03:00
|
|
|
argtype[argc + ncontext] = argtype[argc + ncontext]" "$i;
|
1994-06-15 19:49:03 +04:00
|
|
|
i++;
|
|
|
|
}
|
Overhaul of the EVFILT_VNODE kevent(2) filter:
- Centralize vnode kevent handling in the VOP_*() wrappers, rather than
forcing each individual file system to deal with it (except VOP_RENAME(),
because VOP_RENAME() is a mess and we currently have 2 different ways
of handling it; at least it's reasonably well-centralized in the "new"
way).
- Add support for NOTE_OPEN, NOTE_CLOSE, NOTE_CLOSE_WRITE, and NOTE_READ,
compatible with the same events in FreeBSD.
- Track which kevent notifications clients are interested in receiving
to avoid doing work for events no one cares about (avoiding, e.g.
taking locks and traversing the klist to send a NOTE_WRITE when
someone is merely watching for a file to be deleted, for example).
In support of the above:
- Add support in vnode_if.sh for specifying PRE- and POST-op handlers,
to be invoked before and after vop_pre() and vop_post(), respectively.
Basic idea from FreeBSD, but implemented differently.
- Add support in vnode_if.sh for specifying CONTEXT fields in the
vop_*_args structures. These context fields are used to convey information
between the file system VOP function and the VOP wrapper, but do not
occupy an argument slot in the VOP_*() call itself. These context fields
are initialized and subsequently interpreted by PRE- and POST-op handlers.
- Version VOP_REMOVE(), uses the a context field for the file system to report
back the resulting link count of the target vnode. Return this in tmpfs,
udf, nfs, chfs, ext2fs, lfs, and ufs.
NetBSD 9.99.92.
2021-10-20 06:08:16 +03:00
|
|
|
argname[argc + ncontext] = $i;
|
|
|
|
if (is_context)
|
|
|
|
ncontext++;
|
|
|
|
else
|
|
|
|
argc++;
|
1994-06-15 19:49:03 +04:00
|
|
|
next;
|
|
|
|
}
|
|
|
|
'
|
1994-06-08 15:28:29 +04:00
|
|
|
|
1998-01-09 09:40:43 +03:00
|
|
|
# This is put before the copyright on each generated file.
|
1996-02-29 23:54:58 +03:00
|
|
|
warning="\
|
1998-01-09 09:40:43 +03:00
|
|
|
/* @NetBSD@ */
|
|
|
|
|
1994-06-08 15:28:29 +04:00
|
|
|
/*
|
2005-02-27 00:40:45 +03:00
|
|
|
* Warning: DO NOT EDIT! This file is automatically generated!
|
1994-06-15 19:49:03 +04:00
|
|
|
* (Modifications made here may easily be lost!)
|
1994-06-08 15:28:29 +04:00
|
|
|
*
|
1996-02-29 23:54:58 +03:00
|
|
|
* Created from the file:
|
|
|
|
* ${SRC_ID}
|
|
|
|
* by the script:
|
1994-06-15 19:49:03 +04:00
|
|
|
* ${SCRIPT_ID}
|
1994-06-08 15:28:29 +04:00
|
|
|
*/
|
2005-02-27 00:34:55 +03:00
|
|
|
"
|
1994-06-08 15:28:29 +04:00
|
|
|
|
1994-08-25 07:04:28 +04:00
|
|
|
# This is to satisfy McKusick (get rid of evil spaces 8^)
|
|
|
|
anal_retentive='s:\([^/]\*\) :\1:g'
|
1994-06-08 15:28:29 +04:00
|
|
|
|
2008-11-17 11:46:03 +03:00
|
|
|
do_hfile () {
|
1994-06-15 19:49:03 +04:00
|
|
|
#
|
|
|
|
# Redirect stdout to the H file.
|
|
|
|
#
|
2008-11-17 11:46:03 +03:00
|
|
|
echo "$0: Creating $1" 1>&2
|
|
|
|
exec > $1
|
|
|
|
rump=$2
|
1994-06-08 15:28:29 +04:00
|
|
|
|
1994-06-15 19:49:03 +04:00
|
|
|
# Begin stuff
|
2008-11-17 11:46:03 +03:00
|
|
|
if [ -z "${rump}" ]; then
|
|
|
|
SYS='SYS_'
|
|
|
|
else
|
|
|
|
SYS='RUMP_RUMP'
|
|
|
|
fi
|
2005-02-27 01:06:38 +03:00
|
|
|
echo -n "$warning" | sed -e 's/\$//g;s/@/\$/g;s/ $//'
|
1996-02-29 23:54:58 +03:00
|
|
|
echo ""
|
|
|
|
echo -n "$copyright"
|
1997-01-22 09:51:59 +03:00
|
|
|
echo ''
|
2008-11-17 11:46:03 +03:00
|
|
|
echo "#ifndef _${SYS}VNODE_IF_H_"
|
|
|
|
echo "#define _${SYS}VNODE_IF_H_"
|
2009-09-29 15:51:02 +04:00
|
|
|
if [ ${lockdebug} -ne 0 ] ; then
|
|
|
|
echo ''
|
|
|
|
echo '#ifdef _KERNEL_OPT'
|
|
|
|
echo '#include "opt_vnode_lockdebug.h"'
|
|
|
|
echo '#endif /* _KERNEL_OPT */'
|
|
|
|
fi
|
2010-04-14 17:58:51 +04:00
|
|
|
[ -z "${rump}" ] && echo "
|
|
|
|
extern const struct vnodeop_desc ${rump}vop_default_desc;"
|
|
|
|
echo
|
1994-06-15 19:49:03 +04:00
|
|
|
|
|
|
|
# Body stuff
|
|
|
|
# This awk program needs toupper() so define it if necessary.
|
2008-11-17 11:46:03 +03:00
|
|
|
sed -e "$sed_prep" $src | $awk -v rump=${rump} "$toupper"'
|
1994-06-15 19:49:03 +04:00
|
|
|
function doit() {
|
2010-04-14 17:58:51 +04:00
|
|
|
name = rump name
|
1994-06-15 19:49:03 +04:00
|
|
|
# Declare arg struct, descriptor.
|
2010-04-14 17:58:51 +04:00
|
|
|
if (!rump) {
|
|
|
|
printf("\n#define %s_DESCOFFSET %d\n",
|
|
|
|
toupper(name), vop_offset++);
|
2014-01-13 16:07:55 +04:00
|
|
|
printf("struct %s_args {\n", args_name);
|
2010-04-14 17:58:51 +04:00
|
|
|
printf("\tconst struct vnodeop_desc * a_desc;\n");
|
|
|
|
for (i=0; i<argc; i++) {
|
|
|
|
printf("\t%s a_%s;\n", argtype[i], argname[i]);
|
|
|
|
}
|
Overhaul of the EVFILT_VNODE kevent(2) filter:
- Centralize vnode kevent handling in the VOP_*() wrappers, rather than
forcing each individual file system to deal with it (except VOP_RENAME(),
because VOP_RENAME() is a mess and we currently have 2 different ways
of handling it; at least it's reasonably well-centralized in the "new"
way).
- Add support for NOTE_OPEN, NOTE_CLOSE, NOTE_CLOSE_WRITE, and NOTE_READ,
compatible with the same events in FreeBSD.
- Track which kevent notifications clients are interested in receiving
to avoid doing work for events no one cares about (avoiding, e.g.
taking locks and traversing the klist to send a NOTE_WRITE when
someone is merely watching for a file to be deleted, for example).
In support of the above:
- Add support in vnode_if.sh for specifying PRE- and POST-op handlers,
to be invoked before and after vop_pre() and vop_post(), respectively.
Basic idea from FreeBSD, but implemented differently.
- Add support in vnode_if.sh for specifying CONTEXT fields in the
vop_*_args structures. These context fields are used to convey information
between the file system VOP function and the VOP wrapper, but do not
occupy an argument slot in the VOP_*() call itself. These context fields
are initialized and subsequently interpreted by PRE- and POST-op handlers.
- Version VOP_REMOVE(), uses the a context field for the file system to report
back the resulting link count of the target vnode. Return this in tmpfs,
udf, nfs, chfs, ext2fs, lfs, and ufs.
NetBSD 9.99.92.
2021-10-20 06:08:16 +03:00
|
|
|
for (i=0; i<ncontext; i++) {
|
|
|
|
printf("\t%s ctx_%s;\n", argtype[argc+i], \
|
|
|
|
argname[argc+i]);
|
|
|
|
}
|
2010-04-14 17:58:51 +04:00
|
|
|
printf("};\n");
|
|
|
|
printf("extern const struct vnodeop_desc %s_desc;\n", name);
|
1994-06-15 19:49:03 +04:00
|
|
|
}
|
1995-03-10 07:13:52 +03:00
|
|
|
# Prototype it.
|
2000-09-13 19:50:26 +04:00
|
|
|
protoarg = sprintf("int %s(", toupper(name));
|
1995-03-10 07:13:52 +03:00
|
|
|
protolen = length(protoarg);
|
|
|
|
printf("%s", protoarg);
|
|
|
|
for (i=0; i<argc; i++) {
|
|
|
|
protoarg = sprintf("%s", argtype[i]);
|
|
|
|
if (i < (argc-1)) protoarg = (protoarg ", ");
|
|
|
|
arglen = length(protoarg);
|
|
|
|
if ((protolen + arglen) > 77) {
|
|
|
|
protoarg = ("\n " protoarg);
|
|
|
|
arglen += 4;
|
|
|
|
protolen = 0;
|
|
|
|
}
|
|
|
|
printf("%s", protoarg);
|
|
|
|
protolen += arglen;
|
|
|
|
}
|
2005-12-07 03:42:03 +03:00
|
|
|
printf(");\n");
|
1994-06-15 19:49:03 +04:00
|
|
|
}
|
|
|
|
BEGIN {
|
2006-12-01 00:06:29 +03:00
|
|
|
vop_offset = 1; # start at 1, to count the 'default' op
|
|
|
|
|
2010-04-14 17:58:51 +04:00
|
|
|
printf("struct buf;\n");
|
|
|
|
if (rump) {
|
|
|
|
printf("struct flock;\n");
|
|
|
|
printf("struct knote;\n");
|
|
|
|
printf("struct vm_page;\n");
|
2020-05-16 21:31:45 +03:00
|
|
|
printf("struct acl;\n");
|
|
|
|
printf("\n#include <sys/acl.h>\n");
|
2010-04-14 17:58:51 +04:00
|
|
|
}
|
|
|
|
printf("\n#ifndef _KERNEL\n#include <stdbool.h>\n#endif\n");
|
|
|
|
if (rump)
|
|
|
|
printf("\n");
|
2006-12-01 00:06:29 +03:00
|
|
|
}
|
|
|
|
END {
|
2010-04-14 17:58:51 +04:00
|
|
|
if (!rump) {
|
|
|
|
printf("\n#define VNODE_OPS_COUNT\t%d\n", vop_offset);
|
|
|
|
}
|
1994-06-15 19:49:03 +04:00
|
|
|
}
|
1994-08-25 07:04:28 +04:00
|
|
|
'"$awk_parser" | sed -e "$anal_retentive"
|
1994-06-08 15:28:29 +04:00
|
|
|
|
1994-06-15 19:49:03 +04:00
|
|
|
# End stuff
|
1997-01-22 09:51:59 +03:00
|
|
|
echo ''
|
2008-11-17 11:46:03 +03:00
|
|
|
echo "#endif /* !_${SYS}VNODE_IF_H_ */"
|
|
|
|
}
|
|
|
|
do_hfile $out_h ''
|
|
|
|
do_hfile $out_rumph 'rump_'
|
1994-06-08 15:28:29 +04:00
|
|
|
|
2008-11-17 11:46:03 +03:00
|
|
|
do_cfile () {
|
1994-06-15 19:49:03 +04:00
|
|
|
#
|
|
|
|
# Redirect stdout to the C file.
|
|
|
|
#
|
2008-11-17 11:46:03 +03:00
|
|
|
echo "$0: Creating $1" 1>&2
|
|
|
|
exec > $1
|
|
|
|
rump=$2
|
1994-06-08 15:28:29 +04:00
|
|
|
|
1994-06-15 19:49:03 +04:00
|
|
|
# Begin stuff
|
2005-02-27 01:06:38 +03:00
|
|
|
echo -n "$warning" | sed -e 's/\$//g;s/@/\$/g;s/ $//'
|
1996-02-29 23:54:58 +03:00
|
|
|
echo ""
|
|
|
|
echo -n "$copyright"
|
2001-11-12 17:34:24 +03:00
|
|
|
echo "
|
|
|
|
#include <sys/cdefs.h>
|
2009-09-29 15:51:02 +04:00
|
|
|
__KERNEL_RCSID(0, \"\$NetBSD\$\");"
|
|
|
|
|
|
|
|
[ ${lockdebug} -ne 0 ] && echo && echo '#include "opt_vnode_lockdebug.h"'
|
2001-11-12 17:34:24 +03:00
|
|
|
|
2000-09-13 20:09:27 +04:00
|
|
|
echo '
|
1994-06-08 15:28:29 +04:00
|
|
|
#include <sys/param.h>
|
|
|
|
#include <sys/mount.h>
|
2000-09-13 19:50:26 +04:00
|
|
|
#include <sys/buf.h>
|
Overhaul of the EVFILT_VNODE kevent(2) filter:
- Centralize vnode kevent handling in the VOP_*() wrappers, rather than
forcing each individual file system to deal with it (except VOP_RENAME(),
because VOP_RENAME() is a mess and we currently have 2 different ways
of handling it; at least it's reasonably well-centralized in the "new"
way).
- Add support for NOTE_OPEN, NOTE_CLOSE, NOTE_CLOSE_WRITE, and NOTE_READ,
compatible with the same events in FreeBSD.
- Track which kevent notifications clients are interested in receiving
to avoid doing work for events no one cares about (avoiding, e.g.
taking locks and traversing the klist to send a NOTE_WRITE when
someone is merely watching for a file to be deleted, for example).
In support of the above:
- Add support in vnode_if.sh for specifying PRE- and POST-op handlers,
to be invoked before and after vop_pre() and vop_post(), respectively.
Basic idea from FreeBSD, but implemented differently.
- Add support in vnode_if.sh for specifying CONTEXT fields in the
vop_*_args structures. These context fields are used to convey information
between the file system VOP function and the VOP wrapper, but do not
occupy an argument slot in the VOP_*() call itself. These context fields
are initialized and subsequently interpreted by PRE- and POST-op handlers.
- Version VOP_REMOVE(), uses the a context field for the file system to report
back the resulting link count of the target vnode. Return this in tmpfs,
udf, nfs, chfs, ext2fs, lfs, and ufs.
NetBSD 9.99.92.
2021-10-20 06:08:16 +03:00
|
|
|
#include <sys/fcntl.h>
|
1994-06-08 15:28:29 +04:00
|
|
|
#include <sys/vnode.h>
|
2008-11-17 11:46:03 +03:00
|
|
|
#include <sys/lock.h>'
|
2017-02-22 12:45:51 +03:00
|
|
|
[ -z "${rump}" ] && echo '#include <sys/fstrans.h>'
|
2009-10-15 04:29:40 +04:00
|
|
|
[ ! -z "${rump}" ] && echo '#include <rump/rumpvnode_if.h>' \
|
2016-01-27 02:28:06 +03:00
|
|
|
&& echo '#include <rump-sys/kern.h>'
|
1994-06-08 15:28:29 +04:00
|
|
|
|
2010-04-14 17:58:51 +04:00
|
|
|
if [ -z "${rump}" ] ; then
|
|
|
|
echo "
|
2019-10-11 11:04:52 +03:00
|
|
|
enum fst_op { FST_NO, FST_YES, FST_LAZY, FST_TRY };
|
2017-06-04 10:59:17 +03:00
|
|
|
|
|
|
|
static inline int
|
|
|
|
vop_pre(vnode_t *vp, struct mount **mp, bool *mpsafe, enum fst_op op)
|
|
|
|
{
|
|
|
|
int error;
|
|
|
|
|
|
|
|
*mpsafe = (vp->v_vflag & VV_MPSAFE);
|
|
|
|
|
|
|
|
if (!*mpsafe) {
|
|
|
|
KERNEL_LOCK(1, curlwp);
|
|
|
|
}
|
|
|
|
|
2019-10-11 11:04:52 +03:00
|
|
|
if (op == FST_YES || op == FST_LAZY || op == FST_TRY) {
|
2017-06-04 10:59:17 +03:00
|
|
|
for (;;) {
|
|
|
|
*mp = vp->v_mount;
|
|
|
|
if (op == FST_TRY) {
|
2017-06-04 11:03:26 +03:00
|
|
|
error = fstrans_start_nowait(*mp);
|
2017-06-04 10:59:17 +03:00
|
|
|
if (error) {
|
|
|
|
if (!*mpsafe) {
|
|
|
|
KERNEL_UNLOCK_ONE(curlwp);
|
|
|
|
}
|
|
|
|
return error;
|
|
|
|
}
|
2019-10-11 11:04:52 +03:00
|
|
|
} else if (op == FST_LAZY) {
|
|
|
|
fstrans_start_lazy(*mp);
|
2017-06-04 10:59:17 +03:00
|
|
|
} else {
|
2017-06-04 11:03:26 +03:00
|
|
|
fstrans_start(*mp);
|
2017-06-04 10:59:17 +03:00
|
|
|
}
|
|
|
|
if (__predict_true(*mp == vp->v_mount))
|
|
|
|
break;
|
|
|
|
fstrans_done(*mp);
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
*mp = vp->v_mount;
|
|
|
|
}
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
Overhaul of the EVFILT_VNODE kevent(2) filter:
- Centralize vnode kevent handling in the VOP_*() wrappers, rather than
forcing each individual file system to deal with it (except VOP_RENAME(),
because VOP_RENAME() is a mess and we currently have 2 different ways
of handling it; at least it's reasonably well-centralized in the "new"
way).
- Add support for NOTE_OPEN, NOTE_CLOSE, NOTE_CLOSE_WRITE, and NOTE_READ,
compatible with the same events in FreeBSD.
- Track which kevent notifications clients are interested in receiving
to avoid doing work for events no one cares about (avoiding, e.g.
taking locks and traversing the klist to send a NOTE_WRITE when
someone is merely watching for a file to be deleted, for example).
In support of the above:
- Add support in vnode_if.sh for specifying PRE- and POST-op handlers,
to be invoked before and after vop_pre() and vop_post(), respectively.
Basic idea from FreeBSD, but implemented differently.
- Add support in vnode_if.sh for specifying CONTEXT fields in the
vop_*_args structures. These context fields are used to convey information
between the file system VOP function and the VOP wrapper, but do not
occupy an argument slot in the VOP_*() call itself. These context fields
are initialized and subsequently interpreted by PRE- and POST-op handlers.
- Version VOP_REMOVE(), uses the a context field for the file system to report
back the resulting link count of the target vnode. Return this in tmpfs,
udf, nfs, chfs, ext2fs, lfs, and ufs.
NetBSD 9.99.92.
2021-10-20 06:08:16 +03:00
|
|
|
static inline u_quad_t
|
|
|
|
vop_pre_get_size(struct vnode *vp)
|
|
|
|
{
|
|
|
|
mutex_enter(vp->v_interlock);
|
|
|
|
KASSERT(vp->v_size != VSIZENOTSET);
|
|
|
|
u_quad_t rv = (u_quad_t)vp->v_size;
|
|
|
|
mutex_exit(vp->v_interlock);
|
|
|
|
|
|
|
|
return rv;
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* VOP_RMDIR(), VOP_REMOVE(), and VOP_RENAME() need special handling
|
|
|
|
* because they each drop the caller's references on one or more of
|
|
|
|
* their arguments. While there must be an open file descriptor in
|
|
|
|
* associated with a vnode in order for knotes to be attached to it,
|
|
|
|
* that status could change during the course of the operation. So,
|
|
|
|
* for the vnode arguments that are WILLRELE or WILLPUT, we check
|
|
|
|
* pre-op if there are registered knotes, take a hold count if so,
|
|
|
|
* and post-op release the hold after activating any knotes still
|
|
|
|
* associated with the vnode.
|
|
|
|
*/
|
|
|
|
|
|
|
|
#define VOP_POST_KNOTE(thisvp, e, n) \\
|
|
|
|
do { \\
|
|
|
|
if (__predict_true((e) == 0)) { \\
|
|
|
|
/* \\
|
|
|
|
* VN_KNOTE() does the VN_KEVENT_INTEREST() \\
|
|
|
|
* check for us. \\
|
|
|
|
*/ \\
|
|
|
|
VN_KNOTE((thisvp), (n)); \\
|
|
|
|
} \\
|
|
|
|
} while (/*CONSTCOND*/0)
|
|
|
|
|
|
|
|
#define VOP_POST_KNOTE_HELD(thisvp, e, n) \\
|
|
|
|
do { \\
|
|
|
|
/* \\
|
|
|
|
* We don't perform a VN_KEVENT_INTEREST() check here; it \\
|
|
|
|
* was already performed when we did the pre-op work that \\
|
|
|
|
* caused the vnode to be held in the first place. \\
|
|
|
|
*/ \\
|
|
|
|
mutex_enter((thisvp)->v_interlock); \\
|
|
|
|
if (__predict_true((e) == 0)) { \\
|
|
|
|
knote(&(thisvp)->v_klist, (n)); \\
|
|
|
|
} \\
|
|
|
|
holdrelel((thisvp)); \\
|
|
|
|
mutex_exit((thisvp)->v_interlock); \\
|
|
|
|
/* \\
|
|
|
|
* thisvp might be gone now! Don't touch! \\
|
|
|
|
*/ \\
|
|
|
|
} while (/*CONSTCOND*/0)
|
|
|
|
|
|
|
|
#define vop_create_post(ap, e) \\
|
|
|
|
VOP_POST_KNOTE((ap)->a_dvp, (e), NOTE_WRITE)
|
|
|
|
|
|
|
|
#define vop_mknod_post(ap, e) \\
|
|
|
|
VOP_POST_KNOTE((ap)->a_dvp, (e), NOTE_WRITE)
|
|
|
|
|
|
|
|
#define vop_setattr_pre(ap) \\
|
|
|
|
u_quad_t osize = 0; \\
|
|
|
|
long vp_events = \\
|
|
|
|
VN_KEVENT_INTEREST((ap)->a_vp, NOTE_ATTRIB | NOTE_EXTEND) \\
|
|
|
|
? NOTE_ATTRIB : 0; \\
|
|
|
|
bool check_extend = false; \\
|
|
|
|
if (__predict_false(vp_events != 0 && \\
|
|
|
|
(ap)->a_vap->va_size != VNOVALSIZE)) { \\
|
|
|
|
check_extend = true; \\
|
|
|
|
osize = vop_pre_get_size((ap)->a_vp); \\
|
|
|
|
}
|
|
|
|
|
|
|
|
#define vop_setattr_post(ap, e) \\
|
|
|
|
do { \\
|
|
|
|
if (__predict_false(vp_events != 0)) { \\
|
|
|
|
if (__predict_false(check_extend && \\
|
|
|
|
(ap)->a_vap->va_size > osize)) { \\
|
|
|
|
vp_events |= NOTE_EXTEND; \\
|
|
|
|
} \\
|
|
|
|
VOP_POST_KNOTE((ap)->a_vp, (e), vp_events); \\
|
|
|
|
} \\
|
|
|
|
} while (/*CONSTCOND*/0)
|
|
|
|
|
|
|
|
#define vop_setacl_post(ap, e) \\
|
|
|
|
VOP_POST_KNOTE((ap)->a_vp, (e), NOTE_ATTRIB)
|
|
|
|
|
|
|
|
#define vop_link_post(ap, e) \\
|
|
|
|
do { \\
|
|
|
|
VOP_POST_KNOTE((ap)->a_dvp, (e), NOTE_WRITE); \\
|
|
|
|
VOP_POST_KNOTE((ap)->a_vp, (e), NOTE_LINK); \\
|
|
|
|
} while (/*CONSTCOND*/0)
|
|
|
|
|
|
|
|
#define vop_mkdir_post(ap, e) \\
|
|
|
|
VOP_POST_KNOTE((ap)->a_dvp, (e), NOTE_WRITE | NOTE_LINK)
|
|
|
|
|
|
|
|
#define vop_remove_pre_common(ap) \\
|
|
|
|
bool post_event_vp = \\
|
|
|
|
VN_KEVENT_INTEREST((ap)->a_vp, NOTE_DELETE | NOTE_LINK); \\
|
|
|
|
if (__predict_false(post_event_vp)) { \\
|
|
|
|
vhold((ap)->a_vp); \\
|
|
|
|
}
|
|
|
|
|
|
|
|
#define vop_remove_post_common(ap, e, dn, lc) \\
|
|
|
|
do { \\
|
|
|
|
VOP_POST_KNOTE((ap)->a_dvp, (e), (dn)); \\
|
|
|
|
if (__predict_false(post_event_vp)) { \\
|
|
|
|
VOP_POST_KNOTE_HELD((ap)->a_vp, (e), \\
|
|
|
|
(lc) ? NOTE_LINK : NOTE_DELETE); \\
|
|
|
|
} \\
|
|
|
|
} while (/*CONSTCOND*/0)
|
|
|
|
|
|
|
|
/*
|
|
|
|
* One could make the argument that VOP_REMOVE() should send NOTE_LINK
|
|
|
|
* on vp if the resulting link count is not zero, but that's not what
|
|
|
|
* the documentation says.
|
|
|
|
*
|
|
|
|
* We could change this easily by passing ap->ctx_vp_new_nlink to
|
|
|
|
* vop_remove_post_common().
|
|
|
|
*/
|
|
|
|
#define vop_remove_pre(ap) \\
|
|
|
|
vop_remove_pre_common((ap)); \\
|
|
|
|
/* \\
|
|
|
|
* We will assume that the file being removed is deleted unless \\
|
|
|
|
* the file system tells us otherwise by updating vp_new_nlink. \\
|
|
|
|
*/ \\
|
|
|
|
(ap)->ctx_vp_new_nlink = 0;
|
|
|
|
|
|
|
|
#define vop_remove_post(ap, e) \\
|
|
|
|
vop_remove_post_common((ap), (e), NOTE_WRITE, 0)
|
|
|
|
|
|
|
|
#define vop_rmdir_pre(ap) \\
|
|
|
|
vop_remove_pre_common(ap)
|
|
|
|
|
|
|
|
#define vop_rmdir_post(ap, e) \\
|
|
|
|
vop_remove_post_common((ap), (e), NOTE_WRITE | NOTE_LINK, 0)
|
|
|
|
|
|
|
|
#define vop_symlink_post(ap, e) \\
|
|
|
|
VOP_POST_KNOTE((ap)->a_dvp, (e), NOTE_WRITE)
|
|
|
|
|
|
|
|
#define vop_open_post(ap, e) \\
|
|
|
|
VOP_POST_KNOTE((ap)->a_vp, (e), NOTE_OPEN)
|
|
|
|
|
|
|
|
#define vop_close_post(ap, e) \\
|
|
|
|
do { \\
|
|
|
|
extern int (**dead_vnodeop_p)(void *); \\
|
|
|
|
\\
|
|
|
|
/* See the definition of VN_KNOTE() in <sys/vnode.h>. */ \\
|
|
|
|
if (__predict_false(VN_KEVENT_INTEREST((ap)->a_vp, \\
|
|
|
|
NOTE_CLOSE_WRITE | NOTE_CLOSE) && (e) == 0)) { \\
|
|
|
|
struct vnode *thisvp = (ap)->a_vp; \\
|
|
|
|
mutex_enter(thisvp->v_interlock); \\
|
|
|
|
/* \\
|
|
|
|
* Don't send NOTE_CLOSE when closing a vnode that's \\
|
|
|
|
* been reclaimed or otherwise revoked; a NOTE_REVOKE \\
|
|
|
|
* has already been sent, and this close is effectively \\
|
|
|
|
* meaningless from the watcher's perspective. \\
|
|
|
|
*/ \\
|
|
|
|
if (__predict_true(thisvp->v_op != dead_vnodeop_p)) { \\
|
|
|
|
knote(&thisvp->v_klist, \\
|
|
|
|
((ap)->a_fflag & FWRITE) \\
|
|
|
|
? NOTE_CLOSE_WRITE : NOTE_CLOSE); \\
|
|
|
|
} \\
|
|
|
|
mutex_exit(thisvp->v_interlock); \\
|
|
|
|
} \\
|
|
|
|
} while (/*CONSTCOND*/0)
|
|
|
|
|
|
|
|
#define vop_read_post(ap, e) \\
|
|
|
|
VOP_POST_KNOTE((ap)->a_vp, (e), NOTE_READ)
|
|
|
|
|
|
|
|
#define vop_write_pre(ap) \\
|
|
|
|
off_t ooffset = 0, noffset = 0; \\
|
|
|
|
u_quad_t osize = 0; \\
|
|
|
|
long vp_events = \\
|
|
|
|
VN_KEVENT_INTEREST((ap)->a_vp, NOTE_WRITE | NOTE_EXTEND) \\
|
|
|
|
? NOTE_WRITE : 0; \\
|
|
|
|
if (__predict_false(vp_events != 0)) { \\
|
|
|
|
ooffset = (ap)->a_uio->uio_offset; \\
|
|
|
|
osize = vop_pre_get_size((ap)->a_vp); \\
|
|
|
|
}
|
|
|
|
|
|
|
|
#define vop_write_post(ap, e) \\
|
|
|
|
do { \\
|
|
|
|
/* \\
|
|
|
|
* If any data was written, we'll post an event, even if \\
|
|
|
|
* there was an error. \\
|
|
|
|
*/ \\
|
|
|
|
noffset = (ap)->a_uio->uio_offset; \\
|
|
|
|
if (__predict_false(vp_events != 0 && noffset > ooffset)) { \\
|
|
|
|
if (noffset > osize) { \\
|
|
|
|
vp_events |= NOTE_EXTEND; \\
|
|
|
|
} \\
|
|
|
|
VN_KNOTE((ap)->a_vp, vp_events); \\
|
|
|
|
} \\
|
|
|
|
} while (/*CONSTCOND*/0)
|
|
|
|
|
2017-06-04 10:59:17 +03:00
|
|
|
static inline void
|
|
|
|
vop_post(vnode_t *vp, struct mount *mp, bool mpsafe, enum fst_op op)
|
|
|
|
{
|
|
|
|
|
2019-10-11 11:04:52 +03:00
|
|
|
if (op == FST_YES || op == FST_LAZY) {
|
2017-06-04 10:59:17 +03:00
|
|
|
fstrans_done(mp);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!mpsafe) {
|
|
|
|
KERNEL_UNLOCK_ONE(curlwp);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2010-04-14 17:58:51 +04:00
|
|
|
const struct vnodeop_desc vop_default_desc = {"
|
2008-11-17 11:46:03 +03:00
|
|
|
echo ' 0,
|
1994-06-08 15:28:29 +04:00
|
|
|
"default",
|
|
|
|
0,
|
|
|
|
NULL,
|
|
|
|
VDESC_NO_OFFSET,
|
|
|
|
VDESC_NO_OFFSET,
|
|
|
|
VDESC_NO_OFFSET,
|
|
|
|
};
|
1994-06-15 19:49:03 +04:00
|
|
|
'
|
2010-04-14 17:58:51 +04:00
|
|
|
fi
|
1994-06-15 19:49:03 +04:00
|
|
|
|
|
|
|
# Body stuff
|
2009-09-29 15:51:02 +04:00
|
|
|
sed -e "$sed_prep" $src | $awk -v rump=${rump} -v lockdebug=${lockdebug} '
|
1994-06-15 19:49:03 +04:00
|
|
|
function do_offset(typematch) {
|
|
|
|
for (i=0; i<argc; i++) {
|
|
|
|
if (argtype[i] == typematch) {
|
|
|
|
printf("\tVOPARG_OFFSETOF(struct %s_args, a_%s),\n",
|
2014-01-13 16:07:55 +04:00
|
|
|
args_name, argname[i]);
|
1994-06-15 19:49:03 +04:00
|
|
|
return i;
|
1994-06-08 15:28:29 +04:00
|
|
|
};
|
1994-06-15 19:49:03 +04:00
|
|
|
};
|
|
|
|
print "\tVDESC_NO_OFFSET,";
|
|
|
|
return -1;
|
|
|
|
}
|
1994-06-08 15:28:29 +04:00
|
|
|
|
2010-04-14 17:58:51 +04:00
|
|
|
function offsets() {
|
1994-06-15 19:49:03 +04:00
|
|
|
# Define offsets array
|
2010-04-14 17:58:51 +04:00
|
|
|
printf("const int %s_vp_offsets[] = {\n", name);
|
1994-06-15 19:49:03 +04:00
|
|
|
for (i=0; i<argc; i++) {
|
|
|
|
if (argtype[i] == "struct vnode *") {
|
|
|
|
printf ("\tVOPARG_OFFSETOF(struct %s_args,a_%s),\n",
|
2014-01-13 16:07:55 +04:00
|
|
|
args_name, argname[i]);
|
1994-06-15 19:49:03 +04:00
|
|
|
}
|
1994-06-08 15:28:29 +04:00
|
|
|
}
|
1994-06-15 19:49:03 +04:00
|
|
|
print "\tVDESC_NO_OFFSET";
|
|
|
|
print "};";
|
|
|
|
# Define F_desc
|
2001-01-22 12:52:21 +03:00
|
|
|
printf("const struct vnodeop_desc %s_desc = {\n", name);
|
1994-06-15 19:49:03 +04:00
|
|
|
# offset
|
2006-12-01 00:06:29 +03:00
|
|
|
printf ("\t%s_DESCOFFSET,\n", toupper(name));
|
1994-06-15 19:49:03 +04:00
|
|
|
# printable name
|
|
|
|
printf ("\t\"%s\",\n", name);
|
|
|
|
# flags
|
|
|
|
printf("\t0");
|
|
|
|
vpnum = 0;
|
|
|
|
for (i=0; i<argc; i++) {
|
|
|
|
if (willrele[i]) {
|
2017-04-11 17:29:32 +03:00
|
|
|
if (willrele[i] == 3) {
|
1999-07-08 03:32:50 +04:00
|
|
|
word = "PUT";
|
|
|
|
} else {
|
|
|
|
word = "RELE";
|
|
|
|
}
|
2011-04-03 05:19:35 +04:00
|
|
|
printf(" | VDESC_VP%s_WILL%s", vpnum, word);
|
1994-06-15 19:49:03 +04:00
|
|
|
}
|
2017-04-16 20:18:28 +03:00
|
|
|
if (argtype[i] == "struct vnode *")
|
|
|
|
vpnum++;
|
1994-06-08 15:28:29 +04:00
|
|
|
}
|
1994-06-15 19:49:03 +04:00
|
|
|
print ",";
|
|
|
|
# vp offsets
|
|
|
|
printf ("\t%s_vp_offsets,\n", name);
|
|
|
|
# vpp (if any)
|
|
|
|
do_offset("struct vnode **");
|
|
|
|
# cred (if any)
|
2006-05-15 01:15:11 +04:00
|
|
|
do_offset("kauth_cred_t");
|
1994-06-15 19:49:03 +04:00
|
|
|
# componentname
|
|
|
|
do_offset("struct componentname *");
|
2010-04-10 23:41:54 +04:00
|
|
|
printf ("};\n");
|
2010-04-14 17:58:51 +04:00
|
|
|
}
|
2000-09-13 19:50:26 +04:00
|
|
|
|
2010-04-14 17:58:51 +04:00
|
|
|
function bodyrump() {
|
|
|
|
printf("{\n\tint error;\n\n");
|
|
|
|
printf("\trump_schedule();\n");
|
|
|
|
printf("\terror = %s(", toupper(name));
|
2000-09-13 19:50:26 +04:00
|
|
|
for (i=0; i<argc; i++) {
|
2010-04-14 17:58:51 +04:00
|
|
|
printf("%s", argname[i]);
|
|
|
|
if (i < (argc-1)) printf(", ");
|
2000-09-13 19:50:26 +04:00
|
|
|
}
|
2010-04-14 17:58:51 +04:00
|
|
|
printf(");\n");
|
|
|
|
printf("\trump_unschedule();\n\n");
|
|
|
|
printf("\treturn error;\n}\n");
|
|
|
|
}
|
|
|
|
|
|
|
|
function bodynorm() {
|
2014-01-13 16:07:55 +04:00
|
|
|
printf("{\n\tint error;\n\tbool mpsafe;\n\tstruct %s_args a;\n",
|
|
|
|
args_name);
|
2017-06-04 10:59:17 +03:00
|
|
|
printf("\tstruct mount *mp;\n");
|
2009-09-29 15:51:02 +04:00
|
|
|
if (lockdebug) {
|
|
|
|
printf("#ifdef VNODE_LOCKDEBUG\n");
|
|
|
|
for (i=0; i<argc; i++) {
|
|
|
|
if (lockstate[i] != -1)
|
|
|
|
printf("\tint islocked_%s;\n", argname[i]);
|
|
|
|
}
|
|
|
|
printf("#endif\n");
|
2004-09-21 07:10:35 +04:00
|
|
|
}
|
2000-09-13 19:50:26 +04:00
|
|
|
printf("\ta.a_desc = VDESC(%s);\n", name);
|
|
|
|
for (i=0; i<argc; i++) {
|
|
|
|
printf("\ta.a_%s = %s;\n", argname[i], argname[i]);
|
2009-09-29 15:51:02 +04:00
|
|
|
if (lockdebug && lockstate[i] != -1) {
|
2004-09-21 07:10:35 +04:00
|
|
|
printf("#ifdef VNODE_LOCKDEBUG\n");
|
2007-10-11 00:42:20 +04:00
|
|
|
printf("\tislocked_%s = (%s->v_vflag & VV_LOCKSWORK) ? (VOP_ISLOCKED(%s) == LK_EXCLUSIVE) : %d;\n",
|
2004-09-21 07:10:35 +04:00
|
|
|
argname[i], argname[i], argname[i], lockstate[i]);
|
|
|
|
printf("\tif (islocked_%s != %d)\n", argname[i],
|
|
|
|
lockstate[i]);
|
|
|
|
printf("\t\tpanic(\"%s: %s: locked %%d, expected %%d\", islocked_%s, %d);\n", name, argname[i], argname[i], lockstate[i]);
|
|
|
|
printf("#endif\n");
|
|
|
|
}
|
2000-09-13 19:50:26 +04:00
|
|
|
}
|
Overhaul of the EVFILT_VNODE kevent(2) filter:
- Centralize vnode kevent handling in the VOP_*() wrappers, rather than
forcing each individual file system to deal with it (except VOP_RENAME(),
because VOP_RENAME() is a mess and we currently have 2 different ways
of handling it; at least it's reasonably well-centralized in the "new"
way).
- Add support for NOTE_OPEN, NOTE_CLOSE, NOTE_CLOSE_WRITE, and NOTE_READ,
compatible with the same events in FreeBSD.
- Track which kevent notifications clients are interested in receiving
to avoid doing work for events no one cares about (avoiding, e.g.
taking locks and traversing the klist to send a NOTE_WRITE when
someone is merely watching for a file to be deleted, for example).
In support of the above:
- Add support in vnode_if.sh for specifying PRE- and POST-op handlers,
to be invoked before and after vop_pre() and vop_post(), respectively.
Basic idea from FreeBSD, but implemented differently.
- Add support in vnode_if.sh for specifying CONTEXT fields in the
vop_*_args structures. These context fields are used to convey information
between the file system VOP function and the VOP wrapper, but do not
occupy an argument slot in the VOP_*() call itself. These context fields
are initialized and subsequently interpreted by PRE- and POST-op handlers.
- Version VOP_REMOVE(), uses the a context field for the file system to report
back the resulting link count of the target vnode. Return this in tmpfs,
udf, nfs, chfs, ext2fs, lfs, and ufs.
NetBSD 9.99.92.
2021-10-20 06:08:16 +03:00
|
|
|
# This is done before generic vop_pre() because we want
|
|
|
|
# to do any setup before beginning an fstrans.
|
|
|
|
if (do_pre != "")
|
|
|
|
printf("\t%s(&a);\n", do_pre);
|
2017-06-04 10:59:17 +03:00
|
|
|
if (fstrans == "LOCK")
|
|
|
|
printf("\terror = vop_pre(%s, &mp, &mpsafe, %s);\n",
|
2020-02-24 01:14:03 +03:00
|
|
|
argname[0], "(!(flags & (LK_SHARED|LK_EXCLUSIVE)) ? FST_NO : (flags & LK_NOWAIT ? FST_TRY : FST_YES))");
|
2017-06-04 10:59:17 +03:00
|
|
|
else if (fstrans == "UNLOCK")
|
|
|
|
printf("\terror = vop_pre(%s, &mp, &mpsafe, FST_%s);\n",
|
|
|
|
argname[0], "NO");
|
|
|
|
else
|
|
|
|
printf("\terror = vop_pre(%s, &mp, &mpsafe, FST_%s);\n",
|
|
|
|
argname[0], fstrans);
|
|
|
|
printf("\tif (error)\n\t\treturn error;\n");
|
2011-07-11 12:23:00 +04:00
|
|
|
printf("\terror = (VCALL(%s, VOFFSET(%s), &a));\n",
|
|
|
|
argname[0], name);
|
2017-06-04 10:59:17 +03:00
|
|
|
if (fstrans == "LOCK")
|
|
|
|
printf("\tvop_post(%s, mp, mpsafe, %s);\n",
|
2019-12-01 16:56:29 +03:00
|
|
|
argname[0], "(flags & (LK_UPGRADE|LK_DOWNGRADE) ? FST_NO : (error ? FST_YES : FST_NO))");
|
2017-06-04 10:59:17 +03:00
|
|
|
else if (fstrans == "UNLOCK")
|
|
|
|
printf("\tvop_post(%s, mp, mpsafe, FST_%s);\n",
|
|
|
|
argname[0], "YES");
|
|
|
|
else
|
|
|
|
printf("\tvop_post(%s, mp, mpsafe, FST_%s);\n",
|
|
|
|
argname[0], fstrans);
|
Overhaul of the EVFILT_VNODE kevent(2) filter:
- Centralize vnode kevent handling in the VOP_*() wrappers, rather than
forcing each individual file system to deal with it (except VOP_RENAME(),
because VOP_RENAME() is a mess and we currently have 2 different ways
of handling it; at least it's reasonably well-centralized in the "new"
way).
- Add support for NOTE_OPEN, NOTE_CLOSE, NOTE_CLOSE_WRITE, and NOTE_READ,
compatible with the same events in FreeBSD.
- Track which kevent notifications clients are interested in receiving
to avoid doing work for events no one cares about (avoiding, e.g.
taking locks and traversing the klist to send a NOTE_WRITE when
someone is merely watching for a file to be deleted, for example).
In support of the above:
- Add support in vnode_if.sh for specifying PRE- and POST-op handlers,
to be invoked before and after vop_pre() and vop_post(), respectively.
Basic idea from FreeBSD, but implemented differently.
- Add support in vnode_if.sh for specifying CONTEXT fields in the
vop_*_args structures. These context fields are used to convey information
between the file system VOP function and the VOP wrapper, but do not
occupy an argument slot in the VOP_*() call itself. These context fields
are initialized and subsequently interpreted by PRE- and POST-op handlers.
- Version VOP_REMOVE(), uses the a context field for the file system to report
back the resulting link count of the target vnode. Return this in tmpfs,
udf, nfs, chfs, ext2fs, lfs, and ufs.
NetBSD 9.99.92.
2021-10-20 06:08:16 +03:00
|
|
|
# This is done after generic vop_post() in order to minimize
|
|
|
|
# time spent with the KERNEL_LOCK held for file systems that
|
|
|
|
# still require it.
|
|
|
|
if (do_post != "")
|
|
|
|
printf("\t%s(&a, error);\n", do_post);
|
2007-07-23 01:26:53 +04:00
|
|
|
if (willmake != -1) {
|
|
|
|
printf("#ifdef DIAGNOSTIC\n");
|
2007-11-07 00:59:43 +03:00
|
|
|
printf("\tif (error == 0)\n" \
|
2007-07-23 01:26:53 +04:00
|
|
|
"\t\tKASSERT((*%s)->v_size != VSIZENOTSET\n" \
|
|
|
|
"\t\t && (*%s)->v_writesize != VSIZENOTSET);\n",
|
|
|
|
argname[willmake], argname[willmake]);
|
|
|
|
printf("#endif /* DIAGNOSTIC */\n");
|
|
|
|
}
|
2007-11-07 00:59:43 +03:00
|
|
|
printf("\treturn error;\n}\n");
|
2000-09-13 19:50:26 +04:00
|
|
|
}
|
2010-04-14 17:58:51 +04:00
|
|
|
|
|
|
|
function doit() {
|
|
|
|
printf("\n");
|
|
|
|
if (!rump)
|
|
|
|
offsets();
|
|
|
|
|
|
|
|
if (rump)
|
|
|
|
extname = "RUMP_" toupper(name);
|
|
|
|
else
|
|
|
|
extname = toupper(name);
|
|
|
|
|
|
|
|
# Define function.
|
|
|
|
printf("int\n%s(", extname);
|
|
|
|
for (i=0; i<argc; i++) {
|
|
|
|
printf("%s %s", argtype[i], argname[i]);
|
|
|
|
if (i < (argc-1)) printf(",\n ");
|
|
|
|
}
|
|
|
|
printf(")\n");
|
|
|
|
|
|
|
|
if (rump)
|
|
|
|
bodyrump();
|
|
|
|
else
|
|
|
|
bodynorm();
|
|
|
|
}
|
2000-09-13 19:50:26 +04:00
|
|
|
BEGIN {
|
2001-01-22 12:52:21 +03:00
|
|
|
# start from 1 (vop_default is at 0)
|
1994-06-15 19:49:03 +04:00
|
|
|
argc=1;
|
1994-06-08 15:28:29 +04:00
|
|
|
}
|
1994-08-25 07:04:28 +04:00
|
|
|
'"$awk_parser" | sed -e "$anal_retentive"
|
1994-06-08 15:28:29 +04:00
|
|
|
|
1994-06-15 19:49:03 +04:00
|
|
|
# End stuff
|
2010-04-14 17:58:51 +04:00
|
|
|
[ -n "${rump}" ] && return
|
1994-06-08 15:28:29 +04:00
|
|
|
|
1994-06-15 19:49:03 +04:00
|
|
|
# Add the vfs_op_descs array to the C file.
|
|
|
|
# Begin stuff
|
2008-11-17 11:46:03 +03:00
|
|
|
echo "
|
|
|
|
const struct vnodeop_desc * const ${rump}vfs_op_descs[] = {
|
|
|
|
&${rump}vop_default_desc, /* MUST BE FIRST */
|
|
|
|
"
|
1994-06-15 19:49:03 +04:00
|
|
|
|
|
|
|
# Body stuff
|
2008-11-17 11:46:03 +03:00
|
|
|
sed -e "$sed_prep" $src | $awk -v rump=${rump} '
|
1994-06-15 19:49:03 +04:00
|
|
|
function doit() {
|
|
|
|
printf("\t&%s_desc,\n", name);
|
1994-06-08 15:28:29 +04:00
|
|
|
}
|
1994-06-15 19:49:03 +04:00
|
|
|
'"$awk_parser"
|
1994-06-08 15:28:29 +04:00
|
|
|
|
1994-06-15 19:49:03 +04:00
|
|
|
# End stuff
|
|
|
|
echo ' NULL
|
2010-04-14 16:19:50 +04:00
|
|
|
};'
|
2008-11-17 11:46:03 +03:00
|
|
|
}
|
|
|
|
do_cfile $out_c ''
|
|
|
|
do_cfile $out_rumpc 'rump_'
|
1994-06-08 15:28:29 +04:00
|
|
|
|
1994-06-15 19:49:03 +04:00
|
|
|
exit 0
|
1994-06-08 15:28:29 +04:00
|
|
|
|
1994-06-15 19:49:03 +04:00
|
|
|
# Local Variables:
|
|
|
|
# tab-width: 4
|
|
|
|
# End:
|