Page MenuHomeFreeBSD

D17658.id49478.diff
No OneTemporary

D17658.id49478.diff

Index: sys/fs/nfsclient/nfs_clvnops.c
===================================================================
--- sys/fs/nfsclient/nfs_clvnops.c
+++ sys/fs/nfsclient/nfs_clvnops.c
@@ -147,7 +147,8 @@
/*
* Global vfs data structures for nfs
*/
-struct vop_vector newnfs_vnodeops = {
+
+static struct vop_vector newnfs_vnodeops_nosig = {
.vop_default = &default_vnodeops,
.vop_access = nfs_access,
.vop_advlock = nfs_advlock,
@@ -182,7 +183,19 @@
.vop_set_text = nfs_set_text,
};
-struct vop_vector newnfs_fifoops = {
+static int
+nfs_vnodeops_bypass(struct vop_generic_args *a)
+{
+
+ return (vop_sigdefer(&newnfs_vnodeops_nosig, a));
+}
+
+struct vop_vector newnfs_vnodeops = {
+ .vop_default = &default_vnodeops,
+ .vop_bypass = nfs_vnodeops_bypass,
+};
+
+static struct vop_vector newnfs_fifoops_nosig = {
.vop_default = &fifo_specops,
.vop_access = nfsspec_access,
.vop_close = nfsfifo_close,
@@ -197,6 +210,18 @@
.vop_write = nfsfifo_write,
};
+static int
+nfs_fifoops_bypass(struct vop_generic_args *a)
+{
+
+ return (vop_sigdefer(&newnfs_fifoops_nosig, a));
+}
+
+struct vop_vector newnfs_fifoops = {
+ .vop_default = &default_vnodeops,
+ .vop_bypass = nfs_fifoops_bypass,
+};
+
static int nfs_mknodrpc(struct vnode *dvp, struct vnode **vpp,
struct componentname *cnp, struct vattr *vap);
static int nfs_removerpc(struct vnode *dvp, struct vnode *vp, char *name,
Index: sys/kern/vfs_default.c
===================================================================
--- sys/kern/vfs_default.c
+++ sys/kern/vfs_default.c
@@ -1322,4 +1322,29 @@
return (EOPNOTSUPP);
}
-/* end of vfs default ops */
+static vop_bypass_t *
+bp_by_off(struct vop_vector *vop, struct vop_generic_args *a)
+{
+
+ return (*(vop_bypass_t **)((char *)vop + a->a_desc->vdesc_vop_offset));
+}
+
+int
+vop_sigdefer(struct vop_vector *vop, struct vop_generic_args *a)
+{
+ vop_bypass_t *bp;
+ int prev_stops, rc;
+
+ /*
+ * No bypass supported.
+ */
+ for (; vop != NULL && (bp = bp_by_off(vop, a)) == NULL;
+ vop = vop->vop_default)
+ ;
+ MPASS(bp != NULL);
+
+ prev_stops = sigdeferstop(SIGDEFERSTOP_SILENT);
+ rc = bp(a);
+ sigallowstop(prev_stops);
+ return (rc);
+}
Index: sys/kern/vfs_init.c
===================================================================
--- sys/kern/vfs_init.c
+++ sys/kern/vfs_init.c
@@ -165,6 +165,198 @@
return (vfsp);
}
+static int
+vfs_mount_sigdefer(struct mount *mp)
+{
+ int prev_stops, rc;
+
+ TSRAW(curthread, TS_ENTER, "VFS_MOUNT", mp->mnt_vfc->vfc_name);
+ prev_stops = sigdeferstop(SIGDEFERSTOP_SILENT);
+ rc = (*mp->mnt_vfc->vfc_vfsops_sd->vfs_mount)(mp);
+ sigallowstop(prev_stops);
+ TSRAW(curthread, TS_EXIT, "VFS_MOUNT", mp->mnt_vfc->vfc_name);
+ return (rc);
+}
+
+static int
+vfs_unmount_sigdefer(struct mount *mp, int mntflags)
+{
+ int prev_stops, rc;
+
+ prev_stops = sigdeferstop(SIGDEFERSTOP_SILENT);
+ rc = (*mp->mnt_vfc->vfc_vfsops_sd->vfs_unmount)(mp, mntflags);
+ sigallowstop(prev_stops);
+ return (rc);
+}
+
+static int
+vfs_root_sigdefer(struct mount *mp, int flags, struct vnode **vpp)
+{
+ int prev_stops, rc;
+
+ prev_stops = sigdeferstop(SIGDEFERSTOP_SILENT);
+ rc = (*mp->mnt_vfc->vfc_vfsops_sd->vfs_root)(mp, flags, vpp);
+ sigallowstop(prev_stops);
+ return (rc);
+}
+
+static int
+vfs_quotactl_sigdefer(struct mount *mp, int cmd, uid_t uid, void *arg)
+{
+ int prev_stops, rc;
+
+ prev_stops = sigdeferstop(SIGDEFERSTOP_SILENT);
+ rc = (*mp->mnt_vfc->vfc_vfsops_sd->vfs_quotactl)(mp, cmd, uid, arg);
+ sigallowstop(prev_stops);
+ return (rc);
+}
+
+static int
+vfs_statfs_sigdefer(struct mount *mp, struct statfs *sbp)
+{
+ int prev_stops, rc;
+
+ prev_stops = sigdeferstop(SIGDEFERSTOP_SILENT);
+ rc = (*mp->mnt_vfc->vfc_vfsops_sd->vfs_statfs)(mp, sbp);
+ sigallowstop(prev_stops);
+ return (rc);
+}
+
+static int
+vfs_sync_sigdefer(struct mount *mp, int waitfor)
+{
+ int prev_stops, rc;
+
+ prev_stops = sigdeferstop(SIGDEFERSTOP_SILENT);
+ rc = (*mp->mnt_vfc->vfc_vfsops_sd->vfs_sync)(mp, waitfor);
+ sigallowstop(prev_stops);
+ return (rc);
+}
+
+static int
+vfs_vget_sigdefer(struct mount *mp, ino_t ino, int flags, struct vnode **vpp)
+{
+ int prev_stops, rc;
+
+ prev_stops = sigdeferstop(SIGDEFERSTOP_SILENT);
+ rc = (*mp->mnt_vfc->vfc_vfsops_sd->vfs_vget)(mp, ino, flags, vpp);
+ sigallowstop(prev_stops);
+ return (rc);
+}
+
+static int
+vfs_fhtovp_sigdefer(struct mount *mp, struct fid *fidp, int flags,
+ struct vnode **vpp)
+{
+ int prev_stops, rc;
+
+ prev_stops = sigdeferstop(SIGDEFERSTOP_SILENT);
+ rc = (*mp->mnt_vfc->vfc_vfsops_sd->vfs_fhtovp)(mp, fidp, flags, vpp);
+ sigallowstop(prev_stops);
+ return (rc);
+}
+
+static int
+vfs_checkexp_sigdefer(struct mount *mp, struct sockaddr *nam, int *exflg,
+ struct ucred **credp, int *numsecflavors, int **secflavors)
+{
+ int prev_stops, rc;
+
+ prev_stops = sigdeferstop(SIGDEFERSTOP_SILENT);
+ rc = (*mp->mnt_vfc->vfc_vfsops_sd->vfs_checkexp)(mp, nam, exflg, credp,
+ numsecflavors, secflavors);
+ sigallowstop(prev_stops);
+ return (rc);
+}
+
+static int
+vfs_extattrctl_sigdefer(struct mount *mp, int cmd, struct vnode *filename_vp,
+ int attrnamespace, const char *attrname)
+{
+ int prev_stops, rc;
+
+ prev_stops = sigdeferstop(SIGDEFERSTOP_SILENT);
+ rc = (*mp->mnt_vfc->vfc_vfsops_sd->vfs_extattrctl)(mp, cmd,
+ filename_vp, attrnamespace, attrname);
+ sigallowstop(prev_stops);
+ return (rc);
+}
+
+static int
+vfs_sysctl_sigdefer(struct mount *mp, fsctlop_t op, struct sysctl_req *req)
+{
+ int prev_stops, rc;
+
+ prev_stops = sigdeferstop(SIGDEFERSTOP_SILENT);
+ rc = (*mp->mnt_vfc->vfc_vfsops_sd->vfs_sysctl)(mp, op, req);
+ sigallowstop(prev_stops);
+ return (rc);
+}
+
+static void
+vfs_susp_clean_sigdefer(struct mount *mp)
+{
+ int prev_stops;
+
+ if (*mp->mnt_vfc->vfc_vfsops_sd->vfs_susp_clean == NULL)
+ return;
+ prev_stops = sigdeferstop(SIGDEFERSTOP_SILENT);
+ (*mp->mnt_vfc->vfc_vfsops_sd->vfs_susp_clean)(mp);
+ sigallowstop(prev_stops);
+}
+
+static void
+vfs_reclaim_lowervp_sigdefer(struct mount *mp, struct vnode *vp)
+{
+ int prev_stops;
+
+ if (*mp->mnt_vfc->vfc_vfsops_sd->vfs_reclaim_lowervp == NULL)
+ return;
+ prev_stops = sigdeferstop(SIGDEFERSTOP_SILENT);
+ (*mp->mnt_vfc->vfc_vfsops_sd->vfs_reclaim_lowervp)(mp, vp);
+ sigallowstop(prev_stops);
+}
+
+static void
+vfs_unlink_lowervp_sigdefer(struct mount *mp, struct vnode *vp)
+{
+ int prev_stops;
+
+ if (*mp->mnt_vfc->vfc_vfsops_sd->vfs_unlink_lowervp == NULL)
+ return;
+ prev_stops = sigdeferstop(SIGDEFERSTOP_SILENT);
+ (*(mp)->mnt_vfc->vfc_vfsops_sd->vfs_unlink_lowervp)(mp, vp);
+ sigallowstop(prev_stops);
+}
+
+static void
+vfs_purge_sigdefer(struct mount *mp)
+{
+ int prev_stops;
+
+ prev_stops = sigdeferstop(SIGDEFERSTOP_SILENT);
+ (*mp->mnt_vfc->vfc_vfsops_sd->vfs_purge)(mp);
+ sigallowstop(prev_stops);
+}
+
+static struct vfsops vfsops_sigdefer = {
+ .vfs_mount = vfs_mount_sigdefer,
+ .vfs_unmount = vfs_unmount_sigdefer,
+ .vfs_root = vfs_root_sigdefer,
+ .vfs_quotactl = vfs_quotactl_sigdefer,
+ .vfs_statfs = vfs_statfs_sigdefer,
+ .vfs_sync = vfs_sync_sigdefer,
+ .vfs_vget = vfs_vget_sigdefer,
+ .vfs_fhtovp = vfs_fhtovp_sigdefer,
+ .vfs_checkexp = vfs_checkexp_sigdefer,
+ .vfs_extattrctl = vfs_extattrctl_sigdefer,
+ .vfs_sysctl = vfs_sysctl_sigdefer,
+ .vfs_susp_clean = vfs_susp_clean_sigdefer,
+ .vfs_reclaim_lowervp = vfs_reclaim_lowervp_sigdefer,
+ .vfs_unlink_lowervp = vfs_unlink_lowervp_sigdefer,
+ .vfs_purge = vfs_purge_sigdefer,
+
+};
/* Register a new filesystem type in the global table */
static int
@@ -278,13 +470,21 @@
if (vfsops->vfs_sysctl == NULL)
vfsops->vfs_sysctl = vfs_stdsysctl;
+ if ((vfc->vfc_flags & VFCF_SBDRY) != 0) {
+ vfc->vfc_vfsops_sd = vfc->vfc_vfsops;
+ vfc->vfc_vfsops = &vfsops_sigdefer;
+ }
+
if (vfc->vfc_flags & VFCF_JAIL)
prison_add_vfs(vfc);
/*
* Call init function for this VFS...
*/
- (*(vfc->vfc_vfsops->vfs_init))(vfc);
+ if ((vfc->vfc_flags & VFCF_SBDRY) != 0)
+ vfc->vfc_vfsops_sd->vfs_init(vfc);
+ else
+ vfc->vfc_vfsops->vfs_init(vfc);
vfsconf_unlock();
/*
@@ -329,12 +529,18 @@
vfsconf_unlock();
return (EBUSY);
}
- if (vfc->vfc_vfsops->vfs_uninit != NULL) {
- error = (*vfc->vfc_vfsops->vfs_uninit)(vfsp);
- if (error != 0) {
- vfsconf_unlock();
- return (error);
- }
+ error = 0;
+ if ((vfc->vfc_flags & VFCF_SBDRY) != 0) {
+ if (vfc->vfc_vfsops_sd->vfs_uninit != NULL)
+ error = vfc->vfc_vfsops_sd->vfs_uninit(vfsp);
+ } else {
+ if (vfc->vfc_vfsops->vfs_uninit != NULL) {
+ error = vfc->vfc_vfsops->vfs_uninit(vfsp);
+ }
+ if (error != 0) {
+ vfsconf_unlock();
+ return (error);
+ }
}
TAILQ_REMOVE(&vfsconf, vfsp, vfc_list);
maxtypenum = VFS_GENERIC;
Index: sys/kern/vfs_mount.c
===================================================================
--- sys/kern/vfs_mount.c
+++ sys/kern/vfs_mount.c
@@ -808,7 +808,8 @@
free(fstype, M_TEMP);
if (vfsp == NULL)
return (ENOENT);
- if (vfsp->vfc_vfsops->vfs_cmount == NULL)
+ if (vfsp->vfc_vfsops->vfs_cmount == NULL || ((vfsp->vfc_flags &
+ VFCF_SBDRY) != 0 && (vfsp->vfc_vfsops_sd->vfs_cmount == NULL)))
return (EOPNOTSUPP);
ma = mount_argsu(ma, "fstype", uap->type, MFSNAMELEN);
@@ -817,8 +818,9 @@
ma = mount_argb(ma, !(flags & MNT_NOSUID), "nosuid");
ma = mount_argb(ma, !(flags & MNT_NOEXEC), "noexec");
- error = vfsp->vfc_vfsops->vfs_cmount(ma, uap->data, flags);
- return (error);
+ if ((vfsp->vfc_flags & VFCF_SBDRY) != 0)
+ return (vfsp->vfc_vfsops_sd->vfs_cmount(ma, uap->data, flags));
+ return (vfsp->vfc_vfsops->vfs_cmount(ma, uap->data, flags));
}
/*
Index: sys/sys/mount.h
===================================================================
--- sys/sys/mount.h
+++ sys/sys/mount.h
@@ -513,6 +513,7 @@
u_int vfc_version; /* ABI version number */
char vfc_name[MFSNAMELEN]; /* filesystem type name */
struct vfsops *vfc_vfsops; /* filesystem operations vector */
+ struct vfsops *vfc_vfsops_sd; /* ... signal-deferred */
int vfc_typenum; /* historic filesystem type number */
int vfc_refcount; /* number mounted of this type */
int vfc_flags; /* permanent flags */
@@ -694,139 +695,96 @@
vfs_statfs_t __vfs_statfs;
-#define VFS_PROLOGUE(MP) do { \
- struct mount *mp__; \
- int _prev_stops; \
- \
- mp__ = (MP); \
- _prev_stops = sigdeferstop((mp__ != NULL && \
- (mp__->mnt_vfc->vfc_flags & VFCF_SBDRY) != 0) ? \
- SIGDEFERSTOP_SILENT : SIGDEFERSTOP_NOP);
-
-#define VFS_EPILOGUE(MP) \
- sigallowstop(_prev_stops); \
-} while (0)
-
#define VFS_MOUNT(MP) ({ \
int _rc; \
\
TSRAW(curthread, TS_ENTER, "VFS_MOUNT", (MP)->mnt_vfc->vfc_name);\
- VFS_PROLOGUE(MP); \
_rc = (*(MP)->mnt_op->vfs_mount)(MP); \
- VFS_EPILOGUE(MP); \
TSRAW(curthread, TS_EXIT, "VFS_MOUNT", (MP)->mnt_vfc->vfc_name);\
_rc; })
#define VFS_UNMOUNT(MP, FORCE) ({ \
int _rc; \
\
- VFS_PROLOGUE(MP); \
_rc = (*(MP)->mnt_op->vfs_unmount)(MP, FORCE); \
- VFS_EPILOGUE(MP); \
_rc; })
#define VFS_ROOT(MP, FLAGS, VPP) ({ \
int _rc; \
\
- VFS_PROLOGUE(MP); \
_rc = (*(MP)->mnt_op->vfs_root)(MP, FLAGS, VPP); \
- VFS_EPILOGUE(MP); \
_rc; })
#define VFS_QUOTACTL(MP, C, U, A) ({ \
int _rc; \
\
- VFS_PROLOGUE(MP); \
_rc = (*(MP)->mnt_op->vfs_quotactl)(MP, C, U, A); \
- VFS_EPILOGUE(MP); \
_rc; })
#define VFS_STATFS(MP, SBP) ({ \
int _rc; \
\
- VFS_PROLOGUE(MP); \
_rc = __vfs_statfs((MP), (SBP)); \
- VFS_EPILOGUE(MP); \
_rc; })
#define VFS_SYNC(MP, WAIT) ({ \
int _rc; \
\
- VFS_PROLOGUE(MP); \
_rc = (*(MP)->mnt_op->vfs_sync)(MP, WAIT); \
- VFS_EPILOGUE(MP); \
_rc; })
#define VFS_VGET(MP, INO, FLAGS, VPP) ({ \
int _rc; \
\
- VFS_PROLOGUE(MP); \
_rc = (*(MP)->mnt_op->vfs_vget)(MP, INO, FLAGS, VPP); \
- VFS_EPILOGUE(MP); \
_rc; })
#define VFS_FHTOVP(MP, FIDP, FLAGS, VPP) ({ \
int _rc; \
\
- VFS_PROLOGUE(MP); \
_rc = (*(MP)->mnt_op->vfs_fhtovp)(MP, FIDP, FLAGS, VPP); \
- VFS_EPILOGUE(MP); \
_rc; })
#define VFS_CHECKEXP(MP, NAM, EXFLG, CRED, NUMSEC, SEC) ({ \
int _rc; \
\
- VFS_PROLOGUE(MP); \
_rc = (*(MP)->mnt_op->vfs_checkexp)(MP, NAM, EXFLG, CRED, NUMSEC,\
SEC); \
- VFS_EPILOGUE(MP); \
_rc; })
#define VFS_EXTATTRCTL(MP, C, FN, NS, N) ({ \
int _rc; \
\
- VFS_PROLOGUE(MP); \
_rc = (*(MP)->mnt_op->vfs_extattrctl)(MP, C, FN, NS, N); \
- VFS_EPILOGUE(MP); \
_rc; })
#define VFS_SYSCTL(MP, OP, REQ) ({ \
int _rc; \
\
- VFS_PROLOGUE(MP); \
_rc = (*(MP)->mnt_op->vfs_sysctl)(MP, OP, REQ); \
- VFS_EPILOGUE(MP); \
_rc; })
#define VFS_SUSP_CLEAN(MP) do { \
if (*(MP)->mnt_op->vfs_susp_clean != NULL) { \
- VFS_PROLOGUE(MP); \
(*(MP)->mnt_op->vfs_susp_clean)(MP); \
- VFS_EPILOGUE(MP); \
} \
} while (0)
#define VFS_RECLAIM_LOWERVP(MP, VP) do { \
if (*(MP)->mnt_op->vfs_reclaim_lowervp != NULL) { \
- VFS_PROLOGUE(MP); \
(*(MP)->mnt_op->vfs_reclaim_lowervp)((MP), (VP)); \
- VFS_EPILOGUE(MP); \
} \
} while (0)
#define VFS_UNLINK_LOWERVP(MP, VP) do { \
if (*(MP)->mnt_op->vfs_unlink_lowervp != NULL) { \
- VFS_PROLOGUE(MP); \
(*(MP)->mnt_op->vfs_unlink_lowervp)((MP), (VP)); \
- VFS_EPILOGUE(MP); \
} \
} while (0)
#define VFS_PURGE(MP) do { \
if (*(MP)->mnt_op->vfs_purge != NULL) { \
- VFS_PROLOGUE(MP); \
(*(MP)->mnt_op->vfs_purge)(MP); \
- VFS_EPILOGUE(MP); \
} \
} while (0)
Index: sys/sys/vnode.h
===================================================================
--- sys/sys/vnode.h
+++ sys/sys/vnode.h
@@ -484,6 +484,7 @@
struct vnodeop_desc {
char *vdesc_name; /* a readable name for debugging */
int vdesc_flags; /* VDESC_* flags */
+ int vdesc_vop_offset;
vop_bypass_t *vdesc_call; /* Function to call */
/*
@@ -785,6 +786,7 @@
void vop_setattr_post(void *a, int rc);
void vop_setextattr_post(void *a, int rc);
void vop_symlink_post(void *a, int rc);
+int vop_sigdefer(struct vop_vector *vop, struct vop_generic_args *a);
#ifdef DEBUG_VFS_LOCKS
void vop_strategy_pre(void *a);
Index: sys/tools/vnode_if.awk
===================================================================
--- sys/tools/vnode_if.awk
+++ sys/tools/vnode_if.awk
@@ -181,6 +181,7 @@
"struct vnodeop_desc vop_default_desc = {\n" \
" \"default\",\n" \
" 0,\n" \
+ " 0,\n" \
" (vop_bypass_t *)vop_panic,\n" \
" NULL,\n" \
" VDESC_NO_OFFSET,\n" \
@@ -366,12 +367,10 @@
add_debug_code(name, args[i], "Entry", "\t");
printc("\tKTR_START" ctrstr);
add_pre(name);
- printc("\tVFS_PROLOGUE(a->a_" args[0]"->v_mount);")
printc("\tif (vop->"name" != NULL)")
printc("\t\trc = vop->"name"(a);")
printc("\telse")
printc("\t\trc = vop->vop_bypass(&a->a_gen);")
- printc("\tVFS_EPILOGUE(a->a_" args[0]"->v_mount);")
printc("\tSDT_PROBE3(vfs, vop, " name ", return, a->a_" args[0] ", a, rc);\n");
printc("\tif (rc == 0) {");
for (i = 0; i < numargs; ++i)
@@ -402,6 +401,8 @@
releflags = "0";
printc("\t" releflags vppwillrele ",");
+ # index in struct vop_vector
+ printc("\t__offsetof(struct vop_vector, " name "),");
# function to call
printc("\t(vop_bypass_t *)" uname "_AP,");
# vp offsets

File Metadata

Mime Type
text/plain
Expires
Mon, Oct 28, 4:22 AM (4 h, 54 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
14364966
Default Alt Text
D17658.id49478.diff (15 KB)

Event Timeline