summaryrefslogtreecommitdiffstats
path: root/sys
diff options
context:
space:
mode:
authormjg <mjg@FreeBSD.org>2014-10-19 06:59:33 +0000
committermjg <mjg@FreeBSD.org>2014-10-19 06:59:33 +0000
commit65ead9d18ac88bfe8360cecee582a9d3676f22ad (patch)
tree36b9f8d68635bf0aae8d06720114cd76dfd5f5e8 /sys
parent9343e2e256e94fb2d630483addc13d5162206a2e (diff)
downloadFreeBSD-src-65ead9d18ac88bfe8360cecee582a9d3676f22ad.zip
FreeBSD-src-65ead9d18ac88bfe8360cecee582a9d3676f22ad.tar.gz
Provide vfs suspension support only for filesystems which need it.
Need is expressed by providing vfs_susp_clean function in vfsops. Differential Revision: D952 Reviewed by: kib (previous version) MFC after: 2 weeks
Diffstat (limited to 'sys')
-rw-r--r--sys/fs/tmpfs/tmpfs_vfsops.c9
-rw-r--r--sys/kern/vfs_vnops.c34
-rw-r--r--sys/sys/mount.h9
3 files changed, 45 insertions, 7 deletions
diff --git a/sys/fs/tmpfs/tmpfs_vfsops.c b/sys/fs/tmpfs/tmpfs_vfsops.c
index cb4a32b..f0bb96b 100644
--- a/sys/fs/tmpfs/tmpfs_vfsops.c
+++ b/sys/fs/tmpfs/tmpfs_vfsops.c
@@ -427,6 +427,14 @@ tmpfs_sync(struct mount *mp, int waitfor)
}
/*
+ * A stub created so that vfs does vn_start_write for this filesystem
+ */
+static void
+tmpfs_susp_clean(struct mount *mp)
+{
+}
+
+/*
* tmpfs vfs operations.
*/
@@ -437,5 +445,6 @@ struct vfsops tmpfs_vfsops = {
.vfs_statfs = tmpfs_statfs,
.vfs_fhtovp = tmpfs_fhtovp,
.vfs_sync = tmpfs_sync,
+ .vfs_susp_clean = tmpfs_susp_clean,
};
VFS_SET(tmpfs_vfsops, tmpfs, VFCF_JAIL);
diff --git a/sys/kern/vfs_vnops.c b/sys/kern/vfs_vnops.c
index b86ffa7..7a72137 100644
--- a/sys/kern/vfs_vnops.c
+++ b/sys/kern/vfs_vnops.c
@@ -1572,6 +1572,25 @@ vn_closefile(fp, td)
return (error);
}
+static bool
+vn_suspendable_mp(struct mount *mp)
+{
+
+ return (mp->mnt_op->vfs_susp_clean != NULL);
+}
+
+static bool
+vn_suspendable(struct vnode *vp, struct mount **mpp)
+{
+
+ if (vp != NULL)
+ *mpp = vp->v_mount;
+ if (*mpp == NULL)
+ return (false);
+
+ return (vn_suspendable_mp(*mpp));
+}
+
/*
* Preparing to start a filesystem write operation. If the operation is
* permitted, then we bump the count of operations in progress and
@@ -1621,6 +1640,9 @@ vn_start_write(vp, mpp, flags)
struct mount *mp;
int error;
+ if (!vn_suspendable(vp, mpp))
+ return (0);
+
error = 0;
/*
* If a vnode is provided, get and return the mount point that
@@ -1667,6 +1689,9 @@ vn_start_secondary_write(vp, mpp, flags)
struct mount *mp;
int error;
+ if (!vn_suspendable(vp, mpp))
+ return (0);
+
retry:
if (vp != NULL) {
if ((error = VOP_GETWRITEMOUNT(vp, mpp)) != 0) {
@@ -1724,7 +1749,7 @@ void
vn_finished_write(mp)
struct mount *mp;
{
- if (mp == NULL)
+ if (mp == NULL || !vn_suspendable_mp(mp))
return;
MNT_ILOCK(mp);
MNT_REL(mp);
@@ -1747,7 +1772,7 @@ void
vn_finished_secondary_write(mp)
struct mount *mp;
{
- if (mp == NULL)
+ if (mp == NULL || !vn_suspendable_mp(mp))
return;
MNT_ILOCK(mp);
MNT_REL(mp);
@@ -1770,6 +1795,8 @@ vfs_write_suspend(struct mount *mp, int flags)
{
int error;
+ MPASS(vn_suspendable_mp(mp));
+
MNT_ILOCK(mp);
if (mp->mnt_susp_owner == curthread) {
MNT_IUNLOCK(mp);
@@ -1811,6 +1838,8 @@ void
vfs_write_resume(struct mount *mp, int flags)
{
+ MPASS(vn_suspendable_mp(mp));
+
MNT_ILOCK(mp);
if ((mp->mnt_kern_flag & MNTK_SUSPEND) != 0) {
KASSERT(mp->mnt_susp_owner == curthread, ("mnt_susp_owner"));
@@ -1844,6 +1873,7 @@ vfs_write_suspend_umnt(struct mount *mp)
{
int error;
+ MPASS(vn_suspendable_mp(mp));
KASSERT((curthread->td_pflags & TDP_IGNSUSP) == 0,
("vfs_write_suspend_umnt: recursed"));
diff --git a/sys/sys/mount.h b/sys/sys/mount.h
index d186599..633c6db 100644
--- a/sys/sys/mount.h
+++ b/sys/sys/mount.h
@@ -754,11 +754,10 @@ vfs_statfs_t __vfs_statfs;
_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); \
- } \
+ MPASS(*(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 { \
OpenPOWER on IntegriCloud