Revert previous commit. Locking the snapshot vnode while the file system
is suspended extends the suspension until the vnode gets unlocked by the caller of ffs_snapshot(). Resuming the file system before expunging all snapshots and syncing the snapshot creates races and deadlocks with journaling file systems at least.
This commit is contained in:
parent
821775e983
commit
f7e12f18b3
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: ffs_snapshot.c,v 1.114 2011/04/29 09:45:15 hannken Exp $ */
|
||||
/* $NetBSD: ffs_snapshot.c,v 1.115 2011/05/08 18:37:15 hannken Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright 2000 Marshall Kirk McKusick. All Rights Reserved.
|
||||
|
@ -38,7 +38,7 @@
|
|||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__KERNEL_RCSID(0, "$NetBSD: ffs_snapshot.c,v 1.114 2011/04/29 09:45:15 hannken Exp $");
|
||||
__KERNEL_RCSID(0, "$NetBSD: ffs_snapshot.c,v 1.115 2011/05/08 18:37:15 hannken Exp $");
|
||||
|
||||
#if defined(_KERNEL_OPT)
|
||||
#include "opt_ffs.h"
|
||||
|
@ -177,7 +177,7 @@ ffs_snapshot(struct mount *mp, struct vnode *vp, struct timespec *ctime)
|
|||
return EOPNOTSUPP;
|
||||
}
|
||||
#else /* defined(FFS_NO_SNAPSHOT) */
|
||||
bool suspended = false, snapshot_locked = false;
|
||||
bool suspended = false;
|
||||
int error, redo = 0, snaploc;
|
||||
void *sbbuf = NULL;
|
||||
daddr_t *snaplist = NULL, snaplistsize = 0;
|
||||
|
@ -309,24 +309,6 @@ ffs_snapshot(struct mount *mp, struct vnode *vp, struct timespec *ctime)
|
|||
DIP_ASSIGN(ip, mtime, ts.tv_sec);
|
||||
DIP_ASSIGN(ip, mtimensec, ts.tv_nsec);
|
||||
ip->i_flag |= IN_CHANGE | IN_UPDATE;
|
||||
/*
|
||||
* Lock the snapshot and resume file system.
|
||||
*/
|
||||
mutex_enter(&si->si_snaplock);
|
||||
mutex_enter(&si->si_lock);
|
||||
si->si_owner = curlwp;
|
||||
mutex_exit(&si->si_lock);
|
||||
snapshot_locked = true;
|
||||
KASSERT(suspended);
|
||||
vfs_resume(vp->v_mount);
|
||||
suspended = false;
|
||||
#ifdef DEBUG
|
||||
getmicrotime(&endtime);
|
||||
timersub(&endtime, &starttime, &endtime);
|
||||
printf("%s: suspended %lld.%03d sec, redo %d of %d\n",
|
||||
mp->mnt_stat.f_mntonname, (long long)endtime.tv_sec,
|
||||
endtime.tv_usec / 1000, redo, fs->fs_ncg);
|
||||
#endif
|
||||
/*
|
||||
* Copy allocation information from all snapshots and then
|
||||
* expunge them from our view.
|
||||
|
@ -399,13 +381,17 @@ out:
|
|||
si->si_gen++;
|
||||
mutex_exit(&si->si_lock);
|
||||
|
||||
if (suspended)
|
||||
if (suspended) {
|
||||
VOP_UNLOCK(vp);
|
||||
vfs_resume(vp->v_mount);
|
||||
if (snapshot_locked) {
|
||||
mutex_enter(&si->si_lock);
|
||||
si->si_owner = NULL;
|
||||
mutex_exit(&si->si_lock);
|
||||
mutex_exit(&si->si_snaplock);
|
||||
vn_lock(vp, LK_EXCLUSIVE | LK_RETRY);
|
||||
#ifdef DEBUG
|
||||
getmicrotime(&endtime);
|
||||
timersub(&endtime, &starttime, &endtime);
|
||||
printf("%s: suspended %lld.%03d sec, redo %d of %d\n",
|
||||
mp->mnt_stat.f_mntonname, (long long)endtime.tv_sec,
|
||||
endtime.tv_usec / 1000, redo, fs->fs_ncg);
|
||||
#endif
|
||||
}
|
||||
if (error) {
|
||||
if (!UFS_WAPBL_BEGIN(mp)) {
|
||||
|
|
Loading…
Reference in New Issue