Skip site navigation (1)Skip section navigation (2)
Date:      Wed, 26 Sep 2018 14:26:30 +0000 (UTC)
From:      Konstantin Belousov <kib@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-11@freebsd.org
Subject:   svn commit: r338943 - in stable/11/sys: kern ufs/ufs
Message-ID:  <201809261426.w8QEQUjT004738@repo.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: kib
Date: Wed Sep 26 14:26:29 2018
New Revision: 338943
URL: https://svnweb.freebsd.org/changeset/base/338943

Log:
  MFC r338798:
  Fix state of dquot-less vnodes after failed quotaoff.

Modified:
  stable/11/sys/kern/vfs_syscalls.c
  stable/11/sys/ufs/ufs/ufs_quota.c
  stable/11/sys/ufs/ufs/ufs_vfsops.c
Directory Properties:
  stable/11/   (props changed)

Modified: stable/11/sys/kern/vfs_syscalls.c
==============================================================================
--- stable/11/sys/kern/vfs_syscalls.c	Wed Sep 26 13:16:55 2018	(r338942)
+++ stable/11/sys/kern/vfs_syscalls.c	Wed Sep 26 14:26:29 2018	(r338943)
@@ -189,7 +189,8 @@ sys_quotactl(struct thread *td, struct quotactl_args *
 	 * Require that Q_QUOTAON handles the vfs_busy() reference on
 	 * its own, always returning with ubusied mount point.
 	 */
-	if ((uap->cmd >> SUBCMDSHIFT) != Q_QUOTAON)
+	if ((uap->cmd >> SUBCMDSHIFT) != Q_QUOTAON &&
+	    (uap->cmd >> SUBCMDSHIFT) != Q_QUOTAOFF)
 		vfs_unbusy(mp);
 	return (error);
 }

Modified: stable/11/sys/ufs/ufs/ufs_quota.c
==============================================================================
--- stable/11/sys/ufs/ufs/ufs_quota.c	Wed Sep 26 13:16:55 2018	(r338942)
+++ stable/11/sys/ufs/ufs/ufs_quota.c	Wed Sep 26 14:26:29 2018	(r338943)
@@ -710,6 +710,34 @@ again:
 	return (error);
 }
 
+static int
+quotaoff_inchange1(struct thread *td, struct mount *mp, int type)
+{
+	int error;
+	bool need_resume;
+
+	/*
+	 * mp is already suspended on unmount.  If not, suspend it, to
+	 * avoid the situation where quotaoff operation eventually
+	 * failing due to SU structures still keeping references on
+	 * dquots, but vnode's references are already clean.  This
+	 * would cause quota accounting leak and asserts otherwise.
+	 * Note that the thread has already called vn_start_write().
+	 */
+	if (mp->mnt_susp_owner == td) {
+		need_resume = false;
+	} else {
+		error = vfs_write_suspend_umnt(mp);
+		if (error != 0)
+			return (error);
+		need_resume = true;
+	}
+	error = quotaoff1(td, mp, type);
+	if (need_resume)
+		vfs_write_resume(mp, VR_START_WRITE);
+	return (error);
+}
+
 /*
  * Turns off quotas, assumes that ump->um_qflags are already checked
  * and QTF_CLOSING is set to indicate operation in progress. Fixes
@@ -719,10 +747,9 @@ int
 quotaoff_inchange(struct thread *td, struct mount *mp, int type)
 {
 	struct ufsmount *ump;
-	int i;
-	int error;
+	int error, i;
 
-	error = quotaoff1(td, mp, type);
+	error = quotaoff_inchange1(td, mp, type);
 
 	ump = VFSTOUFS(mp);
 	UFS_LOCK(ump);

Modified: stable/11/sys/ufs/ufs/ufs_vfsops.c
==============================================================================
--- stable/11/sys/ufs/ufs/ufs_vfsops.c	Wed Sep 26 13:16:55 2018	(r338942)
+++ stable/11/sys/ufs/ufs/ufs_vfsops.c	Wed Sep 26 14:26:29 2018	(r338943)
@@ -92,7 +92,8 @@ ufs_quotactl(mp, cmds, id, arg)
 	void *arg;
 {
 #ifndef QUOTA
-	if ((cmds >> SUBCMDSHIFT) == Q_QUOTAON)
+	if ((cmds >> SUBCMDSHIFT) == Q_QUOTAON ||
+	    (cmds >> SUBCMDSHIFT) == Q_QUOTAOFF)
 		vfs_unbusy(mp);
 
 	return (EOPNOTSUPP);
@@ -115,13 +116,13 @@ ufs_quotactl(mp, cmds, id, arg)
 			break;
 
 		default:
-			if (cmd == Q_QUOTAON)
+			if (cmd == Q_QUOTAON || cmd == Q_QUOTAOFF)
 				vfs_unbusy(mp);
 			return (EINVAL);
 		}
 	}
 	if ((u_int)type >= MAXQUOTAS) {
-		if (cmd == Q_QUOTAON)
+		if (cmd == Q_QUOTAON || cmd == Q_QUOTAOFF)
 			vfs_unbusy(mp);
 		return (EINVAL);
 	}
@@ -132,7 +133,11 @@ ufs_quotactl(mp, cmds, id, arg)
 		break;
 
 	case Q_QUOTAOFF:
+		vfs_ref(mp);
+		vfs_unbusy(mp);
+		vn_start_write(NULL, &mp, V_WAIT | V_MNTREF);
 		error = quotaoff(td, mp, type);
+		vn_finished_write(mp);
 		break;
 
 	case Q_SETQUOTA32:



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201809261426.w8QEQUjT004738>