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:
parent
e9a9607fbb
commit
083c109df6
@ -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");
|
||||
|
@ -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");
|
||||
|
@ -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;
|
||||
|
@ -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");
|
||||
|
Loading…
Reference in New Issue
Block a user