The generated VCALL always uses the first vp which in the case of /link/

might not be handled by the same FS as the directory (e.g. special device
files)...so it must be special-cased. This bug is seen when doing
"ln /dev/console /dev/foo" or equivilent and first appeared after I fixed
the argument order of VOP_LINK.  YUCK! There really needs to be a way of
specifying what vp to use in the VCALL; doing this could fix the strategy
and bwrite special-cases, too.
This commit is contained in:
David Greenman 1995-07-07 13:41:28 +00:00
parent e9a9607fbb
commit 083c109df6
4 changed files with 127 additions and 9 deletions

View File

@ -32,7 +32,7 @@
# SUCH DAMAGE.
#
# @(#)vnode_if.sh 8.1 (Berkeley) 6/10/93
# $Id$
# $Id: vnode_if.sh,v 1.2 1994/08/02 07:43:34 davidg Exp $
#
# Script to produce VFS front-end sugar.
@ -372,6 +372,27 @@ static inline int VOP_BWRITE(bp)
a.a_bp = bp;
return (VCALL((bp)->b_vp, VOFFSET(vop_bwrite), &a));
}
struct vop_link_args {
struct vnodeop_desc *a_desc;
struct vnode *a_vp;
struct vnode *a_tdvp;
struct componentname *a_cnp;
};
extern struct vnodeop_desc vop_link_desc;
static inline int VOP_LINK(vp, tdvp, cnp)
struct vnode *vp;
struct vnode *tdvp;
struct componentname *cnp;
{
struct vop_link_args a;
a.a_desc = VDESC(vop_link);
a.a_vp = vp;
a.a_tdvp = tdvp;
a.a_cnp = cnp;
return (VCALL(tdvp, VOFFSET(vop_link), &a));
}
END_OF_SPECIAL_CASES
cat << END_OF_SPECIAL_CASES >> $CFILE
@ -403,6 +424,22 @@ struct vnodeop_desc vop_bwrite_desc = {
VDESC_NO_OFFSET,
NULL,
};
int vop_link_vp_offsets[] = {
VOPARG_OFFSETOF(struct vop_link_args,a_vp),
VOPARG_OFFSETOF(struct vop_link_args,a_tdvp),
VDESC_NO_OFFSET
};
struct vnodeop_desc vop_link_desc = {
0,
"vop_link",
VDESC_VP1_WILLRELE,
vop_link_vp_offsets,
VDESC_NO_OFFSET,
VDESC_NO_OFFSET,
VDESC_NO_OFFSET,
VOPARG_OFFSETOF(struct vop_link_args,a_cnp),
NULL,
};
END_OF_SPECIAL_CASES
# Add the vfs_op_descs array to the C file.
@ -412,6 +449,7 @@ $AWK '
printf("\t&vop_default_desc, /* MUST BE FIRST */\n");
printf("\t&vop_strategy_desc, /* XXX: SPECIAL CASE */\n");
printf("\t&vop_bwrite_desc, /* XXX: SPECIAL CASE */\n");
printf("\t&vop_link_desc, /* XXX: SPECIAL CASE */\n");
}
END {
printf("\tNULL\n};\n");

View File

@ -32,7 +32,7 @@
# SUCH DAMAGE.
#
# @(#)vnode_if.sh 8.1 (Berkeley) 6/10/93
# $Id$
# $Id: vnode_if.sh,v 1.2 1994/08/02 07:43:34 davidg Exp $
#
# Script to produce VFS front-end sugar.
@ -372,6 +372,27 @@ static inline int VOP_BWRITE(bp)
a.a_bp = bp;
return (VCALL((bp)->b_vp, VOFFSET(vop_bwrite), &a));
}
struct vop_link_args {
struct vnodeop_desc *a_desc;
struct vnode *a_vp;
struct vnode *a_tdvp;
struct componentname *a_cnp;
};
extern struct vnodeop_desc vop_link_desc;
static inline int VOP_LINK(vp, tdvp, cnp)
struct vnode *vp;
struct vnode *tdvp;
struct componentname *cnp;
{
struct vop_link_args a;
a.a_desc = VDESC(vop_link);
a.a_vp = vp;
a.a_tdvp = tdvp;
a.a_cnp = cnp;
return (VCALL(tdvp, VOFFSET(vop_link), &a));
}
END_OF_SPECIAL_CASES
cat << END_OF_SPECIAL_CASES >> $CFILE
@ -403,6 +424,22 @@ struct vnodeop_desc vop_bwrite_desc = {
VDESC_NO_OFFSET,
NULL,
};
int vop_link_vp_offsets[] = {
VOPARG_OFFSETOF(struct vop_link_args,a_vp),
VOPARG_OFFSETOF(struct vop_link_args,a_tdvp),
VDESC_NO_OFFSET
};
struct vnodeop_desc vop_link_desc = {
0,
"vop_link",
VDESC_VP1_WILLRELE,
vop_link_vp_offsets,
VDESC_NO_OFFSET,
VDESC_NO_OFFSET,
VDESC_NO_OFFSET,
VOPARG_OFFSETOF(struct vop_link_args,a_cnp),
NULL,
};
END_OF_SPECIAL_CASES
# Add the vfs_op_descs array to the C file.
@ -412,6 +449,7 @@ $AWK '
printf("\t&vop_default_desc, /* MUST BE FIRST */\n");
printf("\t&vop_strategy_desc, /* XXX: SPECIAL CASE */\n");
printf("\t&vop_bwrite_desc, /* XXX: SPECIAL CASE */\n");
printf("\t&vop_link_desc, /* XXX: SPECIAL CASE */\n");
}
END {
printf("\tNULL\n};\n");

View File

@ -31,7 +31,7 @@
# SUCH DAMAGE.
#
# @(#)vnode_if.src 8.3 (Berkeley) 2/3/94
# $Id: vnode_if.src,v 1.3 1994/09/28 16:45:12 dfr Exp $
# $Id: vnode_if.src,v 1.4 1995/06/28 07:06:41 davidg Exp $
#
vop_lookup {
IN struct vnode *dvp;
@ -148,11 +148,15 @@ vop_remove {
IN struct componentname *cnp;
};
vop_link {
IN struct vnode *vp;
IN WILLRELE struct vnode *tdvp;
IN struct componentname *cnp;
};
# Gack. The generated VCALL uses the first vp which might
# not be handled by the same FS as the directory (e.g. special
# device files)...so it's special-cased.
#
#vop_link {
# IN struct vnode *vp;
# IN WILLRELE struct vnode *tdvp;
# IN struct componentname *cnp;
#};
vop_rename {
IN WILLRELE struct vnode *fdvp;

View File

@ -32,7 +32,7 @@
# SUCH DAMAGE.
#
# @(#)vnode_if.sh 8.1 (Berkeley) 6/10/93
# $Id$
# $Id: vnode_if.sh,v 1.2 1994/08/02 07:43:34 davidg Exp $
#
# Script to produce VFS front-end sugar.
@ -372,6 +372,27 @@ static inline int VOP_BWRITE(bp)
a.a_bp = bp;
return (VCALL((bp)->b_vp, VOFFSET(vop_bwrite), &a));
}
struct vop_link_args {
struct vnodeop_desc *a_desc;
struct vnode *a_vp;
struct vnode *a_tdvp;
struct componentname *a_cnp;
};
extern struct vnodeop_desc vop_link_desc;
static inline int VOP_LINK(vp, tdvp, cnp)
struct vnode *vp;
struct vnode *tdvp;
struct componentname *cnp;
{
struct vop_link_args a;
a.a_desc = VDESC(vop_link);
a.a_vp = vp;
a.a_tdvp = tdvp;
a.a_cnp = cnp;
return (VCALL(tdvp, VOFFSET(vop_link), &a));
}
END_OF_SPECIAL_CASES
cat << END_OF_SPECIAL_CASES >> $CFILE
@ -403,6 +424,22 @@ struct vnodeop_desc vop_bwrite_desc = {
VDESC_NO_OFFSET,
NULL,
};
int vop_link_vp_offsets[] = {
VOPARG_OFFSETOF(struct vop_link_args,a_vp),
VOPARG_OFFSETOF(struct vop_link_args,a_tdvp),
VDESC_NO_OFFSET
};
struct vnodeop_desc vop_link_desc = {
0,
"vop_link",
VDESC_VP1_WILLRELE,
vop_link_vp_offsets,
VDESC_NO_OFFSET,
VDESC_NO_OFFSET,
VDESC_NO_OFFSET,
VOPARG_OFFSETOF(struct vop_link_args,a_cnp),
NULL,
};
END_OF_SPECIAL_CASES
# Add the vfs_op_descs array to the C file.
@ -412,6 +449,7 @@ $AWK '
printf("\t&vop_default_desc, /* MUST BE FIRST */\n");
printf("\t&vop_strategy_desc, /* XXX: SPECIAL CASE */\n");
printf("\t&vop_bwrite_desc, /* XXX: SPECIAL CASE */\n");
printf("\t&vop_link_desc, /* XXX: SPECIAL CASE */\n");
}
END {
printf("\tNULL\n};\n");