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:
parent
7a41bc2f41
commit
895b3782c6
@ -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.
|
||||
*/
|
||||
|
@ -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 *);
|
||||
|
@ -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);
|
||||
|
Loading…
x
Reference in New Issue
Block a user