Extract the code to put a filesystem into the suspended state (at the

unmount time) in the helper vfs_write_suspend_umnt().  Use it instead
of two inline copies in FFS.

Fix the bug in the FFS unmount, when suspension failed, the ufs
extattrs were not reinitialized.

Tested by:	pho
Sponsored by:	The FreeBSD Foundation
MFC after:	2 weeks
This commit is contained in:
Konstantin Belousov 2014-07-14 09:10:00 +00:00
parent 7a41bc2f41
commit 895b3782c6
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=268612
3 changed files with 39 additions and 44 deletions

View file

@ -1829,6 +1829,37 @@ vfs_write_resume(struct mount *mp, int flags)
}
}
/*
* Helper loop around vfs_write_suspend() for filesystem unmount VFS
* methods.
*/
int
vfs_write_suspend_umnt(struct mount *mp)
{
int error;
KASSERT((curthread->td_pflags & TDP_IGNSUSP) == 0,
("vfs_write_suspend_umnt: recursed"));
/* dounmount() already called vn_start_write(). */
for (;;) {
vn_finished_write(mp);
error = vfs_write_suspend(mp, 0);
if (error != 0)
return (error);
MNT_ILOCK(mp);
if ((mp->mnt_kern_flag & MNTK_SUSPENDED) != 0)
break;
MNT_IUNLOCK(mp);
vn_start_write(NULL, &mp, V_WAIT);
}
mp->mnt_kern_flag &= ~(MNTK_SUSPENDED | MNTK_SUSPEND2);
wakeup(&mp->mnt_flag);
MNT_IUNLOCK(mp);
curthread->td_pflags |= TDP_IGNSUSP;
return (0);
}
/*
* Implement kqueues for files by translating it to vnode operation.
*/

View file

@ -721,6 +721,7 @@ int vfs_cache_lookup(struct vop_lookup_args *ap);
void vfs_timestamp(struct timespec *);
void vfs_write_resume(struct mount *mp, int flags);
int vfs_write_suspend(struct mount *mp, int flags);
int vfs_write_suspend_umnt(struct mount *mp);
int vop_stdbmap(struct vop_bmap_args *);
int vop_stdfsync(struct vop_fsync_args *);
int vop_stdgetwritemount(struct vop_getwritemount_args *);

View file

@ -255,31 +255,9 @@ ffs_mount(struct mount *mp)
*/
if ((error = vn_start_write(NULL, &mp, V_WAIT)) != 0)
return (error);
for (;;) {
vn_finished_write(mp);
if ((error = vfs_write_suspend(mp, 0)) != 0)
return (error);
MNT_ILOCK(mp);
if (mp->mnt_kern_flag & MNTK_SUSPENDED) {
/*
* Allow the secondary writes
* to proceed.
*/
mp->mnt_kern_flag &= ~(MNTK_SUSPENDED |
MNTK_SUSPEND2);
wakeup(&mp->mnt_flag);
MNT_IUNLOCK(mp);
/*
* Allow the curthread to
* ignore the suspension to
* synchronize on-disk state.
*/
td->td_pflags |= TDP_IGNSUSP;
break;
}
MNT_IUNLOCK(mp);
vn_start_write(NULL, &mp, V_WAIT);
}
error = vfs_write_suspend_umnt(mp);
if (error != 0)
return (error);
/*
* Check for and optionally get rid of files open
* for writing.
@ -1250,25 +1228,9 @@ ffs_unmount(mp, mntflags)
}
#endif
if (susp) {
/*
* dounmount already called vn_start_write().
*/
for (;;) {
vn_finished_write(mp);
if ((error = vfs_write_suspend(mp, 0)) != 0)
return (error);
MNT_ILOCK(mp);
if (mp->mnt_kern_flag & MNTK_SUSPENDED) {
mp->mnt_kern_flag &= ~(MNTK_SUSPENDED |
MNTK_SUSPEND2);
wakeup(&mp->mnt_flag);
MNT_IUNLOCK(mp);
td->td_pflags |= TDP_IGNSUSP;
break;
}
MNT_IUNLOCK(mp);
vn_start_write(NULL, &mp, V_WAIT);
}
error = vfs_write_suspend_umnt(mp);
if (error != 0)
goto fail1;
}
if (MOUNTEDSOFTDEP(mp))
error = softdep_flushfiles(mp, flags, td);
@ -1331,6 +1293,7 @@ ffs_unmount(mp, mntflags)
fail:
if (susp)
vfs_write_resume(mp, VR_START_WRITE);
fail1:
#ifdef UFS_EXTATTR
if (e_restart) {
ufs_extattr_uepm_init(&ump->um_extattr);