From de751599f4c60e271c207a6807f31932b35c5e98 Mon Sep 17 00:00:00 2001
From:
Date: Tue, 10 May 2016 01:21:01 +0900
Subject: [PATCH] sys/kern: Don't implement .vfs_sync for nothing

The only reason filesystems without requirement of syncing
(e.g. no backing storage) need to implement .vfs_sync is because
those fs need a sync with return value of 0 on unmount.

If vfs allows sync with return value of EOPNOTSUPP, then those
fs no longer have to implement .vfs_sync with vfs_stdsync() only
to pass dounmount().

 # grep "\.vfs_sync" sys/vfs sys/gnu/vfs -rI | grep vfs_stdsync
 sys/vfs/udf/udf_vfsops.c:       .vfs_sync =             vfs_stdsync,
 sys/vfs/portal/portal_vfsops.c: .vfs_sync =             vfs_stdsync
 sys/vfs/devfs/devfs_vfsops.c:   .vfs_sync       = vfs_stdsync,
 sys/vfs/isofs/cd9660/cd9660_vfsops.c:   .vfs_sync =             vfs_stdsync,
 sys/vfs/tmpfs/tmpfs_vfsops.c:   .vfs_sync =                     vfs_stdsync,
 sys/vfs/dirfs/dirfs_vfsops.c:   .vfs_sync =                     vfs_stdsync,
 sys/vfs/ntfs/ntfs_vfsops.c:     .vfs_sync =             vfs_stdsync,
 sys/vfs/procfs/procfs_vfsops.c: .vfs_sync =             vfs_stdsync
 sys/vfs/hpfs/hpfs_vfsops.c:     .vfs_sync =             vfs_stdsync,
 sys/vfs/nullfs/null_vfsops.c:   .vfs_sync =             vfs_stdsync,

The drawback is when there is a sync (other than vfs_stdnosync)
that returns EOPNOTSUPP for real errors. The existing fs in
DragonFly don't do this (and shouldn't either).
---
 sys/kern/vfs_syscalls.c              | 14 +++++++-------
 sys/vfs/devfs/devfs_vfsops.c         |  1 -
 sys/vfs/dirfs/dirfs_vfsops.c         |  1 -
 sys/vfs/hpfs/hpfs_vfsops.c           |  1 -
 sys/vfs/isofs/cd9660/cd9660_vfsops.c |  1 -
 sys/vfs/ntfs/ntfs_vfsops.c           |  1 -
 sys/vfs/nullfs/null_vfsops.c         |  1 -
 sys/vfs/portal/portal_vfsops.c       |  1 -
 sys/vfs/procfs/procfs_vfsops.c       |  1 -
 sys/vfs/tmpfs/tmpfs_vfsops.c         |  1 -
 sys/vfs/udf/udf_vfsops.c             |  1 -
 11 files changed, 7 insertions(+), 17 deletions(-)

diff --git a/sys/kern/vfs_syscalls.c b/sys/kern/vfs_syscalls.c
index 387920b..cca1e13 100644
--- a/sys/kern/vfs_syscalls.c
+++ b/sys/kern/vfs_syscalls.c
@@ -774,19 +774,19 @@ dounmount(struct mount *mp, int flags)
 	/*
 	 * So far so good, sync the filesystem once more and
 	 * call the VFS unmount code if the sync succeeds.
-	 *
-	 * A filesystem without explicitly initialzed .vfs_sync
-	 * fails here since vfs_stdnosync() returns EOPNOTSUPP.
-	 * A filesystem needs to implement vfs_stdsync() which
-	 * returns 0 even if there is no backing storage.
 	 */
 	if (error == 0) {
-		if (((mp->mnt_flag & MNT_RDONLY) ||
-		     (error = VFS_SYNC(mp, MNT_WAIT)) == 0) ||
+		if (mp->mnt_flag & MNT_RDONLY) {
+			error = VFS_UNMOUNT(mp, flags);
+		} else {
+			error = VFS_SYNC(mp, MNT_WAIT);
+			if ((error == 0) ||
+			    (error == EOPNOTSUPP) ||  /* No backing storage */
 			    (flags & MNT_FORCE)) {
 				error = VFS_UNMOUNT(mp, flags);
 			}
 		}
+	}
 
 	/*
 	 * If an error occurred we can still recover, restoring the
diff --git a/sys/vfs/devfs/devfs_vfsops.c b/sys/vfs/devfs/devfs_vfsops.c
index 8d9e012..0e26409 100644
--- a/sys/vfs/devfs/devfs_vfsops.c
+++ b/sys/vfs/devfs/devfs_vfsops.c
@@ -270,7 +270,6 @@ static struct vfsops devfs_vfsops = {
 	.vfs_unmount	= devfs_vfs_unmount,
 	.vfs_root 	= devfs_vfs_root,
 	.vfs_statfs	= devfs_vfs_statfs,
-	.vfs_sync 	= vfs_stdsync,
 	.vfs_vget	= devfs_vfs_vget,
 	.vfs_vptofh	= devfs_vfs_vptofh,
 	.vfs_fhtovp	= devfs_vfs_fhtovp,
diff --git a/sys/vfs/dirfs/dirfs_vfsops.c b/sys/vfs/dirfs/dirfs_vfsops.c
index b77737f..ca874d0 100644
--- a/sys/vfs/dirfs/dirfs_vfsops.c
+++ b/sys/vfs/dirfs/dirfs_vfsops.c
@@ -352,7 +352,6 @@ static struct vfsops dirfs_vfsops = {
 	.vfs_statvfs =			dirfs_statvfs,
 	.vfs_fhtovp =			dirfs_fhtovp,
 	.vfs_vptofh =			dirfs_vptofh,
-	.vfs_sync =			vfs_stdsync,
 	.vfs_checkexp =			dirfs_checkexp
 };
 
diff --git a/sys/vfs/hpfs/hpfs_vfsops.c b/sys/vfs/hpfs/hpfs_vfsops.c
index af65891..aa51e6f 100644
--- a/sys/vfs/hpfs/hpfs_vfsops.c
+++ b/sys/vfs/hpfs/hpfs_vfsops.c
@@ -557,7 +557,6 @@ static struct vfsops hpfs_vfsops = {
 	.vfs_unmount =  	hpfs_unmount,
 	.vfs_root =     	hpfs_root,
 	.vfs_statfs =   	hpfs_statfs,
-	.vfs_sync =     	vfs_stdsync,
 	.vfs_vget =     	hpfs_vget,
 	.vfs_fhtovp =   	hpfs_fhtovp,
 	.vfs_checkexp =  	hpfs_checkexp,
diff --git a/sys/vfs/isofs/cd9660/cd9660_vfsops.c b/sys/vfs/isofs/cd9660/cd9660_vfsops.c
index 7b7a8f2..4c738be 100644
--- a/sys/vfs/isofs/cd9660/cd9660_vfsops.c
+++ b/sys/vfs/isofs/cd9660/cd9660_vfsops.c
@@ -86,7 +86,6 @@ static struct vfsops cd9660_vfsops = {
 	.vfs_unmount =		cd9660_unmount,
 	.vfs_root =		cd9660_root,
 	.vfs_statfs =		cd9660_statfs,
-	.vfs_sync =		vfs_stdsync,
 	.vfs_vget =		cd9660_vget,
 	.vfs_fhtovp =		cd9660_fhtovp,
 	.vfs_checkexp =		cd9660_checkexp,
diff --git a/sys/vfs/ntfs/ntfs_vfsops.c b/sys/vfs/ntfs/ntfs_vfsops.c
index 2e37daf..97b845f 100644
--- a/sys/vfs/ntfs/ntfs_vfsops.c
+++ b/sys/vfs/ntfs/ntfs_vfsops.c
@@ -802,7 +802,6 @@ static struct vfsops ntfs_vfsops = {
 	.vfs_root =     	ntfs_root,
 	.vfs_statfs =   	ntfs_statfs,
 	.vfs_statvfs =		ntfs_statvfs,
-	.vfs_sync =      	vfs_stdsync,
 	.vfs_vget =     	ntfs_vget,
 	.vfs_fhtovp =   	ntfs_fhtovp,
 	.vfs_checkexp =   	ntfs_checkexp,
diff --git a/sys/vfs/nullfs/null_vfsops.c b/sys/vfs/nullfs/null_vfsops.c
index 78352c1..00e0ac7 100644
--- a/sys/vfs/nullfs/null_vfsops.c
+++ b/sys/vfs/nullfs/null_vfsops.c
@@ -398,7 +398,6 @@ static struct vfsops null_vfsops = {
 	.vfs_root =     	nullfs_root,
 	.vfs_quotactl =   	nullfs_quotactl,
 	.vfs_statfs =    	nullfs_statfs,
-	.vfs_sync =     	vfs_stdsync,
 	.vfs_extattrctl =  	nullfs_extattrctl,
 	.vfs_fhtovp =		nullfs_fhtovp,
 	.vfs_vptofh =		nullfs_vptofh,
diff --git a/sys/vfs/portal/portal_vfsops.c b/sys/vfs/portal/portal_vfsops.c
index 1712478..73618a9 100644
--- a/sys/vfs/portal/portal_vfsops.c
+++ b/sys/vfs/portal/portal_vfsops.c
@@ -227,7 +227,6 @@ static struct vfsops portal_vfsops = {
 	.vfs_unmount =  	portal_unmount,
 	.vfs_root =     	portal_root,
 	.vfs_statfs =   	portal_statfs,
-	.vfs_sync =     	vfs_stdsync
 };
 
 VFS_SET(portal_vfsops, portal, VFCF_SYNTHETIC);
diff --git a/sys/vfs/procfs/procfs_vfsops.c b/sys/vfs/procfs/procfs_vfsops.c
index 174fb3d..9737a7d 100644
--- a/sys/vfs/procfs/procfs_vfsops.c
+++ b/sys/vfs/procfs/procfs_vfsops.c
@@ -148,7 +148,6 @@ static struct vfsops procfs_vfsops = {
 	.vfs_unmount =    	procfs_unmount,
 	.vfs_root =    		procfs_root,
 	.vfs_statfs =    	procfs_statfs,
-	.vfs_sync =    		vfs_stdsync
 };
 
 VFS_SET(procfs_vfsops, procfs, VFCF_SYNTHETIC);
diff --git a/sys/vfs/tmpfs/tmpfs_vfsops.c b/sys/vfs/tmpfs/tmpfs_vfsops.c
index 80e5a31..d81ebfa 100644
--- a/sys/vfs/tmpfs/tmpfs_vfsops.c
+++ b/sys/vfs/tmpfs/tmpfs_vfsops.c
@@ -593,7 +593,6 @@ static struct vfsops tmpfs_vfsops = {
 	.vfs_statfs =			tmpfs_statfs,
 	.vfs_fhtovp =			tmpfs_fhtovp,
 	.vfs_vptofh =			tmpfs_vptofh, 
-	.vfs_sync =			vfs_stdsync,
 	.vfs_checkexp =			tmpfs_checkexp,
 };
 
diff --git a/sys/vfs/udf/udf_vfsops.c b/sys/vfs/udf/udf_vfsops.c
index f0615a8..e3bc22c 100644
--- a/sys/vfs/udf/udf_vfsops.c
+++ b/sys/vfs/udf/udf_vfsops.c
@@ -116,7 +116,6 @@ static struct vfsops udf_vfsops = {
 	.vfs_unmount =    	udf_unmount,
 	.vfs_root =    		udf_root,
 	.vfs_statfs =    	udf_statfs,
-	.vfs_sync =    		vfs_stdsync,
 	.vfs_vget =    		udf_vget,
 	.vfs_fhtovp =    	udf_fhtovp,
 	.vfs_vptofh =    	udf_vptofh
-- 
2.8.1

