svn commit: r338943 - in stable/11/sys: kern ufs/ufs
Konstantin Belousov
kib at FreeBSD.org
Wed Sep 26 14:26:31 UTC 2018
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:
More information about the svn-src-all
mailing list