Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F101282283
D17658.id49478.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
15 KB
Referenced Files
None
Subscribers
None
D17658.id49478.diff
View Options
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
Details
Attached
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)
Attached To
Mode
D17658: Only call sigdeferstop() for NFS.
Attached
Detach File
Event Timeline
Log In to Comment