summaryrefslogtreecommitdiffstats
path: root/sys/gnu
diff options
context:
space:
mode:
authorbde <bde@FreeBSD.org>1998-09-26 06:18:59 +0000
committerbde <bde@FreeBSD.org>1998-09-26 06:18:59 +0000
commit4ef2ffab16674dbf497bca0223d17abe1db20209 (patch)
tree27d9995899929320e7030d1f66081a43a93643d7 /sys/gnu
parentd7210d0597b045421ebd7797db3a860f936ce66f (diff)
downloadFreeBSD-src-4ef2ffab16674dbf497bca0223d17abe1db20209.zip
FreeBSD-src-4ef2ffab16674dbf497bca0223d17abe1db20209.tar.gz
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
Diffstat (limited to 'sys/gnu')
-rw-r--r--sys/gnu/ext2fs/ext2_fs_sb.h1
-rw-r--r--sys/gnu/ext2fs/ext2_vfsops.c45
-rw-r--r--sys/gnu/fs/ext2fs/ext2_fs_sb.h1
-rw-r--r--sys/gnu/fs/ext2fs/ext2_vfsops.c45
4 files changed, 72 insertions, 20 deletions
diff --git a/sys/gnu/ext2fs/ext2_fs_sb.h b/sys/gnu/ext2fs/ext2_fs_sb.h
index 07367cf..85f71bf 100644
--- a/sys/gnu/ext2fs/ext2_fs_sb.h
+++ b/sys/gnu/ext2fs/ext2_fs_sb.h
@@ -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 */
};
diff --git a/sys/gnu/ext2fs/ext2_vfsops.c b/sys/gnu/ext2fs/ext2_vfsops.c
index c9b8e4a..0ec6c8b 100644
--- a/sys/gnu/ext2fs/ext2_vfsops.c
+++ b/sys/gnu/ext2fs/ext2_vfsops.c
@@ -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);
}
diff --git a/sys/gnu/fs/ext2fs/ext2_fs_sb.h b/sys/gnu/fs/ext2fs/ext2_fs_sb.h
index 07367cf..85f71bf 100644
--- a/sys/gnu/fs/ext2fs/ext2_fs_sb.h
+++ b/sys/gnu/fs/ext2fs/ext2_fs_sb.h
@@ -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 */
};
diff --git a/sys/gnu/fs/ext2fs/ext2_vfsops.c b/sys/gnu/fs/ext2fs/ext2_vfsops.c
index c9b8e4a..0ec6c8b 100644
--- a/sys/gnu/fs/ext2fs/ext2_vfsops.c
+++ b/sys/gnu/fs/ext2fs/ext2_vfsops.c
@@ -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);
}
OpenPOWER on IntegriCloud