summaryrefslogtreecommitdiffstats
path: root/sys/ufs
diff options
context:
space:
mode:
authorkib <kib@FreeBSD.org>2014-11-02 13:14:55 +0000
committerkib <kib@FreeBSD.org>2014-11-02 13:14:55 +0000
commita6f1fd882b93baa96fb863692ab328dcc786c4b3 (patch)
tree6c24d0538e5d16a2de3754199936ee9deff045ea /sys/ufs
parentcf11d25e1821ead21e66c6d5ce99d1b3c7c2dedd (diff)
downloadFreeBSD-src-a6f1fd882b93baa96fb863692ab328dcc786c4b3.zip
FreeBSD-src-a6f1fd882b93baa96fb863692ab328dcc786c4b3.tar.gz
When non-forced unmount or remount rw->ro is performed, writes on UFS
are not suspended. In particular, on the SU-enabled vulumes, there is no reason why, between the call to softdep_flushfiles() and softdep_waitidle(), SU work items cannot be queued. Correct the condition to trigger the panic by only checking when forced operation is done. Convert direct panic() call into KASSERT(), there is no invalid on-disk data structures directly involved, so follow the usual debugging vs. non-debugging approach. Reported and tested by: pho Reviewed by: mckusick Sponsored by: The FreeBSD Foundation MFC after: 1 week
Diffstat (limited to 'sys/ufs')
-rw-r--r--sys/ufs/ffs/ffs_softdep.c11
1 files changed, 6 insertions, 5 deletions
diff --git a/sys/ufs/ffs/ffs_softdep.c b/sys/ufs/ffs/ffs_softdep.c
index ecb7ffa..a95e1ca 100644
--- a/sys/ufs/ffs/ffs_softdep.c
+++ b/sys/ufs/ffs/ffs_softdep.c
@@ -735,7 +735,7 @@ static struct malloc_type *memtype[] = {
static void check_clear_deps(struct mount *);
static void softdep_error(char *, int);
static int softdep_process_worklist(struct mount *, int);
-static int softdep_waitidle(struct mount *);
+static int softdep_waitidle(struct mount *, int);
static void drain_output(struct vnode *);
static struct buf *getdirtybuf(struct buf *, struct rwlock *, int);
static void clear_remove(struct mount *);
@@ -1911,7 +1911,7 @@ softdep_flushworklist(oldmnt, countp, td)
}
static int
-softdep_waitidle(struct mount *mp)
+softdep_waitidle(struct mount *mp, int flags __unused)
{
struct ufsmount *ump;
int error;
@@ -1921,8 +1921,9 @@ softdep_waitidle(struct mount *mp)
ACQUIRE_LOCK(ump);
for (i = 0; i < 10 && ump->softdep_deps; i++) {
ump->softdep_req = 1;
- if (ump->softdep_on_worklist)
- panic("softdep_waitidle: work added after flush.");
+ KASSERT((flags & FORCECLOSE) == 0 ||
+ ump->softdep_on_worklist == 0,
+ ("softdep_waitidle: work added after flush"));
msleep(&ump->softdep_deps, LOCK_PTR(ump), PVM, "softdeps", 1);
}
ump->softdep_req = 0;
@@ -1990,7 +1991,7 @@ retry_flush:
error = EBUSY;
}
if (!error)
- error = softdep_waitidle(oldmnt);
+ error = softdep_waitidle(oldmnt, flags);
if (!error) {
if (oldmnt->mnt_kern_flag & MNTK_UNMOUNT) {
retry = 0;
OpenPOWER on IntegriCloud