From ad287e3d61bd9ac5dc16f705f511e471510755c4 Mon Sep 17 00:00:00 2001 From: kib Date: Tue, 16 Sep 2008 10:59:35 +0000 Subject: When downgrading the read-write mount to read-only, do_unmount() sets MNT_RDONLY flag before the VFS_MOUNT() is called. In ufs_inactive() and ufs_itimes_locked(), UFS verifies whether the fs is read-only by checking MNT_RDONLY, but this may cause loss of the IN_MODIFIED flag for inode on the fs being remounted rw->ro. Introduce UFS_RDONLY() struct ufsmount' method that reports the value of the fs_ronly. The later is set to 1 only after the remount is finished. Reviewed by: tegge In collaboration with: pho MFC after: 1 month --- sys/ufs/ffs/ffs_extern.h | 2 ++ sys/ufs/ffs/ffs_inode.c | 8 ++++++++ sys/ufs/ffs/ffs_vfsops.c | 1 + sys/ufs/ufs/ufs_inode.c | 5 ++--- sys/ufs/ufs/ufs_vnops.c | 2 +- sys/ufs/ufs/ufsmount.h | 2 ++ 6 files changed, 16 insertions(+), 4 deletions(-) diff --git a/sys/ufs/ffs/ffs_extern.h b/sys/ufs/ffs/ffs_extern.h index 22afbaa..d5dfa12 100644 --- a/sys/ufs/ffs/ffs_extern.h +++ b/sys/ufs/ffs/ffs_extern.h @@ -131,4 +131,6 @@ int softdep_process_worklist(struct mount *, int); int softdep_fsync(struct vnode *); int softdep_waitidle(struct mount *); +int ffs_rdonly(struct inode *); + #endif /* !_UFS_FFS_EXTERN_H */ diff --git a/sys/ufs/ffs/ffs_inode.c b/sys/ufs/ffs/ffs_inode.c index 0a9bc9d..4c58e41 100644 --- a/sys/ufs/ffs/ffs_inode.c +++ b/sys/ufs/ffs/ffs_inode.c @@ -646,3 +646,11 @@ ffs_indirtrunc(ip, lbn, dbn, lastbn, level, countp) *countp = blocksreleased; return (allerror); } + +int +ffs_rdonly(struct inode *ip) +{ + + return (ip->i_ump->um_fs->fs_ronly != 0); +} + diff --git a/sys/ufs/ffs/ffs_vfsops.c b/sys/ufs/ffs/ffs_vfsops.c index 91cd7cf..67d4496 100644 --- a/sys/ufs/ffs/ffs_vfsops.c +++ b/sys/ufs/ffs/ffs_vfsops.c @@ -734,6 +734,7 @@ ffs_mountfs(devvp, mp, td) ump->um_valloc = ffs_valloc; ump->um_vfree = ffs_vfree; ump->um_ifree = ffs_ifree; + ump->um_rdonly = ffs_rdonly; mtx_init(UFS_MTX(ump), "FFS", "FFS Lock", MTX_DEF); bcopy(bp->b_data, ump->um_fs, (u_int)fs->fs_sbsize); if (fs->fs_sbsize < SBLOCKSIZE) diff --git a/sys/ufs/ufs/ufs_inode.c b/sys/ufs/ufs/ufs_inode.c index 57ede1e..17ec28e 100644 --- a/sys/ufs/ufs/ufs_inode.c +++ b/sys/ufs/ufs/ufs_inode.c @@ -90,8 +90,7 @@ ufs_inactive(ap) ufs_gjournal_close(vp); #endif if ((ip->i_effnlink == 0 && DOINGSOFTDEP(vp)) || - (ip->i_nlink <= 0 && - (vp->v_mount->mnt_flag & MNT_RDONLY) == 0)) { + (ip->i_nlink <= 0 && !UFS_RDONLY(ip))) { loop: if (vn_start_secondary_write(vp, &mp, V_NOWAIT) != 0) { /* Cannot delete file while file system is suspended */ @@ -121,7 +120,7 @@ ufs_inactive(ap) } if (ip->i_effnlink == 0 && DOINGSOFTDEP(vp)) softdep_releasefile(ip); - if (ip->i_nlink <= 0 && (vp->v_mount->mnt_flag & MNT_RDONLY) == 0) { + if (ip->i_nlink <= 0 && !UFS_RDONLY(ip)) { #ifdef QUOTA if (!getinoquota(ip)) (void)chkiq(ip, -1, NOCRED, FORCE); diff --git a/sys/ufs/ufs/ufs_vnops.c b/sys/ufs/ufs/ufs_vnops.c index d3a5c70..506ab6a 100644 --- a/sys/ufs/ufs/ufs_vnops.c +++ b/sys/ufs/ufs/ufs_vnops.c @@ -135,7 +135,7 @@ ufs_itimes_locked(struct vnode *vp) ASSERT_VI_LOCKED(vp, __func__); ip = VTOI(vp); - if ((vp->v_mount->mnt_flag & MNT_RDONLY) != 0) + if (UFS_RDONLY(ip)) goto out; if ((ip->i_flag & (IN_ACCESS | IN_CHANGE | IN_UPDATE)) == 0) return; diff --git a/sys/ufs/ufs/ufsmount.h b/sys/ufs/ufs/ufsmount.h index 50a0941..126867b 100644 --- a/sys/ufs/ufs/ufsmount.h +++ b/sys/ufs/ufs/ufsmount.h @@ -93,6 +93,7 @@ struct ufsmount { int (*um_valloc)(struct vnode *, int, struct ucred *, struct vnode **); int (*um_vfree)(struct vnode *, ino_t, int); void (*um_ifree)(struct ufsmount *, struct inode *); + int (*um_rdonly)(struct inode *); }; #define UFS_BALLOC(aa, bb, cc, dd, ee, ff) VFSTOUFS((aa)->v_mount)->um_balloc(aa, bb, cc, dd, ee, ff) @@ -102,6 +103,7 @@ struct ufsmount { #define UFS_VALLOC(aa, bb, cc, dd) VFSTOUFS((aa)->v_mount)->um_valloc(aa, bb, cc, dd) #define UFS_VFREE(aa, bb, cc) VFSTOUFS((aa)->v_mount)->um_vfree(aa, bb, cc) #define UFS_IFREE(aa, bb) ((aa)->um_ifree(aa, bb)) +#define UFS_RDONLY(aa) ((aa)->i_ump->um_rdonly(aa)) #define UFS_LOCK(aa) mtx_lock(&(aa)->um_lock) #define UFS_UNLOCK(aa) mtx_unlock(&(aa)->um_lock) -- cgit v1.1