Source-Changes-HG archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
[src/trunk]: src/sys/ufs/lfs Teach lfs to transition ro<->rw.
details: https://anonhg.NetBSD.org/src/rev/8e8f002f3256
branches: trunk
changeset: 1007585:8e8f002f3256
user: riastradh <riastradh%NetBSD.org@localhost>
date: Sun Feb 23 08:39:18 2020 +0000
description:
Teach lfs to transition ro<->rw.
diffstat:
sys/ufs/lfs/lfs_vfsops.c | 143 +++++++++++++++++++++++++---------------------
1 files changed, 79 insertions(+), 64 deletions(-)
diffs (217 lines):
diff -r bbffb298261b -r 8e8f002f3256 sys/ufs/lfs/lfs_vfsops.c
--- a/sys/ufs/lfs/lfs_vfsops.c Sun Feb 23 08:39:09 2020 +0000
+++ b/sys/ufs/lfs/lfs_vfsops.c Sun Feb 23 08:39:18 2020 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: lfs_vfsops.c,v 1.370 2020/02/18 20:23:17 chs Exp $ */
+/* $NetBSD: lfs_vfsops.c,v 1.371 2020/02/23 08:39:18 riastradh Exp $ */
/*-
* Copyright (c) 1999, 2000, 2001, 2002, 2003, 2007, 2007
@@ -61,7 +61,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: lfs_vfsops.c,v 1.370 2020/02/18 20:23:17 chs Exp $");
+__KERNEL_RCSID(0, "$NetBSD: lfs_vfsops.c,v 1.371 2020/02/23 08:39:18 riastradh Exp $");
#if defined(_KERNEL_OPT)
#include "opt_lfs.h"
@@ -120,6 +120,7 @@
static int lfs_gop_write(struct vnode *, struct vm_page **, int, int);
static int lfs_mountfs(struct vnode *, struct mount *, struct lwp *);
+static int lfs_flushfiles(struct mount *, int);
static struct sysctllog *lfs_sysctl_log;
@@ -755,23 +756,18 @@
ump = VFSTOULFS(mp);
fs = ump->um_lfs;
- if (fs->lfs_ronly == 0 && (mp->mnt_flag & MNT_RDONLY)) {
+ if (!fs->lfs_ronly && (mp->mnt_iflag & IMNT_WANTRDONLY)) {
/*
* Changing from read/write to read-only.
- * XXX: shouldn't we sync here? or does vfs do that?
*/
-#ifdef LFS_QUOTA2
- /* XXX: quotas should remain on when readonly */
- if (fs->lfs_use_quota2) {
- error = lfsquota2_umount(mp, 0);
- if (error) {
- return error;
- }
- }
-#endif
- }
-
- if (fs->lfs_ronly && (mp->mnt_iflag & IMNT_WANTRDWR)) {
+ int flags = WRITECLOSE;
+ if (mp->mnt_flag & MNT_FORCE)
+ flags |= FORCECLOSE;
+ error = lfs_flushfiles(mp, flags);
+ if (error)
+ return error;
+ fs->lfs_ronly = 1;
+ } else if (fs->lfs_ronly && (mp->mnt_iflag & IMNT_WANTRDWR)) {
/*
* Changing from read-only to read/write.
* Note in the superblocks that we're writing.
@@ -805,8 +801,9 @@
lfs_writesuper(fs, lfs_sb_getsboff(fs, 1));
}
}
+
if (args->fspec == NULL)
- return EINVAL;
+ return 0;
}
error = set_statvfs_info(path, UIO_USERSPACE, args->fspec,
@@ -1137,6 +1134,7 @@
mp->mnt_stat.f_iosize = lfs_sb_getbsize(fs);
mp->mnt_flag |= MNT_LOCAL;
mp->mnt_fs_bshift = lfs_sb_getbshift(fs);
+ mp->mnt_iflag |= IMNT_CAN_RWTORO;
if (fs->um_maxsymlinklen > 0)
mp->mnt_iflag |= IMNT_DTYPE;
else
@@ -1328,22 +1326,72 @@
int
lfs_unmount(struct mount *mp, int mntflags)
{
+ struct ulfsmount *ump;
+ struct lfs *fs;
+ int error, ronly;
+
+ ump = VFSTOULFS(mp);
+ fs = ump->um_lfs;
+
+ error = lfs_flushfiles(mp, mntflags & MNT_FORCE ? FORCECLOSE : 0);
+ if (error)
+ return error;
+
+ /* Finish with the Ifile, now that we're done with it */
+ vgone(fs->lfs_ivnode);
+
+ ronly = !fs->lfs_ronly;
+ if (fs->lfs_devvp->v_type != VBAD)
+ spec_node_setmountedfs(fs->lfs_devvp, NULL);
+ vn_lock(fs->lfs_devvp, LK_EXCLUSIVE | LK_RETRY);
+ error = VOP_CLOSE(fs->lfs_devvp,
+ ronly ? FREAD : FREAD|FWRITE, NOCRED);
+ vput(fs->lfs_devvp);
+
+ /* Complain about page leakage */
+ if (fs->lfs_pages > 0)
+ printf("lfs_unmount: still claim %d pages (%d in subsystem)\n",
+ fs->lfs_pages, lfs_subsys_pages);
+
+ /* Free per-mount data structures */
+ free(fs->lfs_ino_bitmap, M_SEGMENT);
+ free(fs->lfs_suflags[0], M_SEGMENT);
+ free(fs->lfs_suflags[1], M_SEGMENT);
+ free(fs->lfs_suflags, M_SEGMENT);
+ lfs_free_resblks(fs);
+ cv_destroy(&fs->lfs_sleeperscv);
+ cv_destroy(&fs->lfs_diropscv);
+ cv_destroy(&fs->lfs_stopcv);
+ cv_destroy(&fs->lfs_nextsegsleep);
+
+ rw_destroy(&fs->lfs_fraglock);
+ rw_destroy(&fs->lfs_iflock);
+
+ kmem_free(fs, sizeof(struct lfs));
+ kmem_free(ump, sizeof(*ump));
+
+ mp->mnt_data = NULL;
+ mp->mnt_flag &= ~MNT_LOCAL;
+ return (error);
+}
+
+static int
+lfs_flushfiles(struct mount *mp, int flags)
+{
struct lwp *l = curlwp;
struct ulfsmount *ump;
struct lfs *fs;
- int error, flags, ronly;
- vnode_t *vp;
-
- flags = 0;
- if (mntflags & MNT_FORCE)
- flags |= FORCECLOSE;
+ struct vnode *vp;
+ int error;
ump = VFSTOULFS(mp);
fs = ump->um_lfs;
/* Two checkpoints */
- lfs_segwrite(mp, SEGM_CKP | SEGM_SYNC);
- lfs_segwrite(mp, SEGM_CKP | SEGM_SYNC);
+ if (!fs->lfs_ronly) {
+ lfs_segwrite(mp, SEGM_CKP | SEGM_SYNC);
+ lfs_segwrite(mp, SEGM_CKP | SEGM_SYNC);
+ }
/* wake up the cleaner so it can die */
/* XXX: shouldn't this be *after* the error cases below? */
@@ -1383,51 +1431,18 @@
mutex_exit(vp->v_interlock);
/* Explicitly write the superblock, to update serial and pflags */
- lfs_sb_setpflags(fs, lfs_sb_getpflags(fs) | LFS_PF_CLEAN);
- lfs_writesuper(fs, lfs_sb_getsboff(fs, 0));
- lfs_writesuper(fs, lfs_sb_getsboff(fs, 1));
+ if (!fs->lfs_ronly) {
+ lfs_sb_setpflags(fs, lfs_sb_getpflags(fs) | LFS_PF_CLEAN);
+ lfs_writesuper(fs, lfs_sb_getsboff(fs, 0));
+ lfs_writesuper(fs, lfs_sb_getsboff(fs, 1));
+ }
mutex_enter(&lfs_lock);
while (fs->lfs_iocount)
mtsleep(&fs->lfs_iocount, PRIBIO + 1, "lfs_umount", 0,
&lfs_lock);
mutex_exit(&lfs_lock);
- /* Finish with the Ifile, now that we're done with it */
- vgone(fs->lfs_ivnode);
-
- ronly = !fs->lfs_ronly;
- if (fs->lfs_devvp->v_type != VBAD)
- spec_node_setmountedfs(fs->lfs_devvp, NULL);
- vn_lock(fs->lfs_devvp, LK_EXCLUSIVE | LK_RETRY);
- error = VOP_CLOSE(fs->lfs_devvp,
- ronly ? FREAD : FREAD|FWRITE, NOCRED);
- vput(fs->lfs_devvp);
-
- /* Complain about page leakage */
- if (fs->lfs_pages > 0)
- printf("lfs_unmount: still claim %d pages (%d in subsystem)\n",
- fs->lfs_pages, lfs_subsys_pages);
-
- /* Free per-mount data structures */
- free(fs->lfs_ino_bitmap, M_SEGMENT);
- free(fs->lfs_suflags[0], M_SEGMENT);
- free(fs->lfs_suflags[1], M_SEGMENT);
- free(fs->lfs_suflags, M_SEGMENT);
- lfs_free_resblks(fs);
- cv_destroy(&fs->lfs_sleeperscv);
- cv_destroy(&fs->lfs_diropscv);
- cv_destroy(&fs->lfs_stopcv);
- cv_destroy(&fs->lfs_nextsegsleep);
-
- rw_destroy(&fs->lfs_fraglock);
- rw_destroy(&fs->lfs_iflock);
-
- kmem_free(fs, sizeof(struct lfs));
- kmem_free(ump, sizeof(*ump));
-
- mp->mnt_data = NULL;
- mp->mnt_flag &= ~MNT_LOCAL;
- return (error);
+ return 0;
}
/*
Home |
Main Index |
Thread Index |
Old Index