diff options
author | pjd <pjd@FreeBSD.org> | 2006-11-01 09:37:11 +0000 |
---|---|---|
committer | pjd <pjd@FreeBSD.org> | 2006-11-01 09:37:11 +0000 |
commit | d639eb8d4b2f221976b922085bed1cc30ec65500 (patch) | |
tree | 1543594a741730651a648b0550dc5a7905c4cada /sys/geom/journal | |
parent | 2774462fb7a482505fa84fb87e49c5c480127c38 (diff) | |
download | FreeBSD-src-d639eb8d4b2f221976b922085bed1cc30ec65500.zip FreeBSD-src-d639eb8d4b2f221976b922085bed1cc30ec65500.tar.gz |
Update the code to the current sync(2) version:
- Do not modify mnt_flag without mount interlock held.
- Do not touch MNT_ASYNC flag, as this can lead to a race with nmount(2).
Pointed out by: tegge
Reviewed by: tegge
Diffstat (limited to 'sys/geom/journal')
-rw-r--r-- | sys/geom/journal/g_journal.c | 16 |
1 files changed, 12 insertions, 4 deletions
diff --git a/sys/geom/journal/g_journal.c b/sys/geom/journal/g_journal.c index f51f570..3decb74 100644 --- a/sys/geom/journal/g_journal.c +++ b/sys/geom/journal/g_journal.c @@ -2850,7 +2850,7 @@ g_journal_do_switch(struct g_class *classp, struct thread *td) struct mount *mp; struct bintime bt; char *mountpoint; - int asyncflag, error, vfslocked; + int error, vfslocked; DROP_GIANT(); g_topology_lock(); @@ -2911,8 +2911,11 @@ g_journal_do_switch(struct g_class *classp, struct thread *td) mountpoint, error); goto next; } - asyncflag = mp->mnt_flag & MNT_ASYNC; - mp->mnt_flag &= ~MNT_ASYNC; + + MNT_ILOCK(mp); + mp->mnt_noasync++; + mp->mnt_kern_flag &= ~MNTK_ASYNC; + MNT_IUNLOCK(mp); GJ_TIMER_START(1, &bt); vfs_msync(mp, MNT_NOWAIT); @@ -2926,7 +2929,12 @@ g_journal_do_switch(struct g_class *classp, struct thread *td) GJ_DEBUG(0, "Cannot sync file system %s (error=%d).", mountpoint, error); } - mp->mnt_flag |= asyncflag; + + MNT_ILOCK(mp); + mp->mnt_noasync--; + if ((mp->mnt_flag & MNT_ASYNC) != 0 && mp->mnt_noasync == 0) + mp->mnt_kern_flag |= MNTK_ASYNC; + MNT_IUNLOCK(mp); vn_finished_write(mp); |