diff options
author | kib <kib@FreeBSD.org> | 2008-09-16 10:59:35 +0000 |
---|---|---|
committer | kib <kib@FreeBSD.org> | 2008-09-16 10:59:35 +0000 |
commit | ad287e3d61bd9ac5dc16f705f511e471510755c4 (patch) | |
tree | 0c1aefb887730cb30f6ad3f69a31afea67c3932f /sys/ufs | |
parent | f67f57a431df0cebe903f455fbe18bc08a370359 (diff) | |
download | FreeBSD-src-ad287e3d61bd9ac5dc16f705f511e471510755c4.zip FreeBSD-src-ad287e3d61bd9ac5dc16f705f511e471510755c4.tar.gz |
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
Diffstat (limited to 'sys/ufs')
-rw-r--r-- | sys/ufs/ffs/ffs_extern.h | 2 | ||||
-rw-r--r-- | sys/ufs/ffs/ffs_inode.c | 8 | ||||
-rw-r--r-- | sys/ufs/ffs/ffs_vfsops.c | 1 | ||||
-rw-r--r-- | sys/ufs/ufs/ufs_inode.c | 5 | ||||
-rw-r--r-- | sys/ufs/ufs/ufs_vnops.c | 2 | ||||
-rw-r--r-- | 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) |