Fixed clean flag handling:

Fixes for bugs not shared with ffs:
- don't mount unclean filesystems rw unless forced to.
- accept EXT2_ERROR_FS (treat it like !EXT2_VALID_FS).  We still don't set
  this or honour the maximal mount count.
- don't attempt to print the name of the mount point when mounting an
  unclean file system, since the name of the previous mount point is
  unknown and the name of the current mount point is still "".

Fixes for bugs shared with ffs until recently:
- don't set the clean flag on unmount of an initially-unclean filesystem
  that was (forcibly) mounted rw.
- set the clean flag on rw -> ro update of a mounted initially-clean
  filesystem.
- fixed some style bugs (mostly long lines).

The fixes are slightly simpler than for ffs, because the relevant on-disk
state is not a simple boolean variable, and the superblock has a core-only
extension.

Obtained from:	parts from ffs_vfsops.c, parts from NetBSD
This commit is contained in:
Bruce Evans 1998-09-26 06:18:59 +00:00
parent 0922cce61c
commit a094db128f
4 changed files with 72 additions and 20 deletions

View file

@ -73,6 +73,7 @@ struct ext2_sb_info {
unsigned int s_fsbtodb; /* shift to get disk block */
char s_rd_only; /* read-only */
char s_dirt; /* fs modified flag */
char s_wasvalid; /* valid at mount time */
char fs_fsmnt[MAXMNTLEN]; /* name mounted on */
};

View file

@ -213,6 +213,11 @@ ext2_mount(mp, path, data, ndp, p)
return (EBUSY);
error = ext2_flushfiles(mp, flags, p);
vfs_unbusy(mp, p);
if (!error && fs->s_wasvalid) {
fs->s_es->s_state |= EXT2_VALID_FS;
ext2_sbupdate(ump, MNT_WAIT);
}
fs->s_rd_only = 1;
}
if (!error && (mp->mnt_flag & MNT_RELOAD))
error = ext2_reload(mp, ndp->ni_cnd.cn_cred, p);
@ -234,12 +239,22 @@ ext2_mount(mp, path, data, ndp, p)
VOP_UNLOCK(devvp, 0, p);
}
fs->s_rd_only = 0;
}
if (fs->s_rd_only == 0) {
/* don't say it's clean */
if ((fs->s_es->s_state & EXT2_VALID_FS) == 0 ||
(fs->s_es->s_state & EXT2_ERROR_FS)) {
if (mp->mnt_flag & MNT_FORCE) {
printf(
"WARNING: %s was not properly dismounted\n",
fs->fs_fsmnt);
} else {
printf(
"WARNING: R/W mount of %s denied. Filesystem is not clean - run fsck\n",
fs->fs_fsmnt);
return (EPERM);
}
}
fs->s_es->s_state &= ~EXT2_VALID_FS;
ext2_sbupdate(ump, MNT_WAIT);
fs->s_rd_only = 0;
}
if (args.fspec == 0) {
/*
@ -629,6 +644,18 @@ ext2_mountfs(devvp, mp, p)
error = EINVAL; /* XXX needs translation */
goto out;
}
if ((es->s_state & EXT2_VALID_FS) == 0 ||
(es->s_state & EXT2_ERROR_FS)) {
if (ronly || (mp->mnt_flag & MNT_FORCE)) {
printf(
"WARNING: Filesystem was not properly dismounted\n");
} else {
printf(
"WARNING: R/W mount denied. Filesystem is not clean - run fsck\n");
error = EPERM;
goto out;
}
}
ump = bsd_malloc(sizeof *ump, M_UFSMNT, M_WAITOK);
bzero((caddr_t)ump, sizeof *ump);
ump->um_malloctype = M_EXT2NODE;
@ -654,13 +681,10 @@ ext2_mountfs(devvp, mp, p)
bp = NULL;
fs = ump->um_e2fs;
fs->s_rd_only = ronly; /* ronly is set according to mnt_flags */
if (!(fs->s_es->s_state & EXT2_VALID_FS)) {
printf("WARNING: %s was not properly dismounted\n",
fs->fs_fsmnt);
}
/* if the fs is not mounted read-only, make sure the super block is
always written back on a sync()
*/
fs->s_wasvalid = fs->s_es->s_state & EXT2_VALID_FS ? 1 : 0;
if (ronly == 0) {
fs->s_dirt = 1; /* mark it modified */
fs->s_es->s_state &= ~EXT2_VALID_FS; /* set fs invalid */
@ -721,8 +745,9 @@ ext2_unmount(mp, mntflags, p)
ump = VFSTOUFS(mp);
fs = ump->um_e2fs;
ronly = fs->s_rd_only;
if (!ronly) {
fs->s_es->s_state |= EXT2_VALID_FS; /* was fs_clean = 1 */
if (ronly == 0) {
if (fs->s_wasvalid)
fs->s_es->s_state |= EXT2_VALID_FS;
ext2_sbupdate(ump, MNT_WAIT);
}

View file

@ -73,6 +73,7 @@ struct ext2_sb_info {
unsigned int s_fsbtodb; /* shift to get disk block */
char s_rd_only; /* read-only */
char s_dirt; /* fs modified flag */
char s_wasvalid; /* valid at mount time */
char fs_fsmnt[MAXMNTLEN]; /* name mounted on */
};

View file

@ -213,6 +213,11 @@ ext2_mount(mp, path, data, ndp, p)
return (EBUSY);
error = ext2_flushfiles(mp, flags, p);
vfs_unbusy(mp, p);
if (!error && fs->s_wasvalid) {
fs->s_es->s_state |= EXT2_VALID_FS;
ext2_sbupdate(ump, MNT_WAIT);
}
fs->s_rd_only = 1;
}
if (!error && (mp->mnt_flag & MNT_RELOAD))
error = ext2_reload(mp, ndp->ni_cnd.cn_cred, p);
@ -234,12 +239,22 @@ ext2_mount(mp, path, data, ndp, p)
VOP_UNLOCK(devvp, 0, p);
}
fs->s_rd_only = 0;
}
if (fs->s_rd_only == 0) {
/* don't say it's clean */
if ((fs->s_es->s_state & EXT2_VALID_FS) == 0 ||
(fs->s_es->s_state & EXT2_ERROR_FS)) {
if (mp->mnt_flag & MNT_FORCE) {
printf(
"WARNING: %s was not properly dismounted\n",
fs->fs_fsmnt);
} else {
printf(
"WARNING: R/W mount of %s denied. Filesystem is not clean - run fsck\n",
fs->fs_fsmnt);
return (EPERM);
}
}
fs->s_es->s_state &= ~EXT2_VALID_FS;
ext2_sbupdate(ump, MNT_WAIT);
fs->s_rd_only = 0;
}
if (args.fspec == 0) {
/*
@ -629,6 +644,18 @@ ext2_mountfs(devvp, mp, p)
error = EINVAL; /* XXX needs translation */
goto out;
}
if ((es->s_state & EXT2_VALID_FS) == 0 ||
(es->s_state & EXT2_ERROR_FS)) {
if (ronly || (mp->mnt_flag & MNT_FORCE)) {
printf(
"WARNING: Filesystem was not properly dismounted\n");
} else {
printf(
"WARNING: R/W mount denied. Filesystem is not clean - run fsck\n");
error = EPERM;
goto out;
}
}
ump = bsd_malloc(sizeof *ump, M_UFSMNT, M_WAITOK);
bzero((caddr_t)ump, sizeof *ump);
ump->um_malloctype = M_EXT2NODE;
@ -654,13 +681,10 @@ ext2_mountfs(devvp, mp, p)
bp = NULL;
fs = ump->um_e2fs;
fs->s_rd_only = ronly; /* ronly is set according to mnt_flags */
if (!(fs->s_es->s_state & EXT2_VALID_FS)) {
printf("WARNING: %s was not properly dismounted\n",
fs->fs_fsmnt);
}
/* if the fs is not mounted read-only, make sure the super block is
always written back on a sync()
*/
fs->s_wasvalid = fs->s_es->s_state & EXT2_VALID_FS ? 1 : 0;
if (ronly == 0) {
fs->s_dirt = 1; /* mark it modified */
fs->s_es->s_state &= ~EXT2_VALID_FS; /* set fs invalid */
@ -721,8 +745,9 @@ ext2_unmount(mp, mntflags, p)
ump = VFSTOUFS(mp);
fs = ump->um_e2fs;
ronly = fs->s_rd_only;
if (!ronly) {
fs->s_es->s_state |= EXT2_VALID_FS; /* was fs_clean = 1 */
if (ronly == 0) {
if (fs->s_wasvalid)
fs->s_es->s_state |= EXT2_VALID_FS;
ext2_sbupdate(ump, MNT_WAIT);
}