summaryrefslogtreecommitdiffstats
path: root/sys/ufs/ffs/ffs_vfsops.c
diff options
context:
space:
mode:
authortrasz <trasz@FreeBSD.org>2012-11-18 18:57:19 +0000
committertrasz <trasz@FreeBSD.org>2012-11-18 18:57:19 +0000
commit5bb0933cf1cda47a3d3a201d7c18c19beee0c55d (patch)
treed9ce909750c485d5716e2dac618c6d48cd337c13 /sys/ufs/ffs/ffs_vfsops.c
parenta508afc736ff706d06e6afa66982d566c84c2813 (diff)
downloadFreeBSD-src-5bb0933cf1cda47a3d3a201d7c18c19beee0c55d.zip
FreeBSD-src-5bb0933cf1cda47a3d3a201d7c18c19beee0c55d.tar.gz
Add UFS writesuspension mechanism, designed to allow userland processes
to modify on-disk metadata for filesystems mounted for write. Reviewed by: kib, mckusick Sponsored by: FreeBSD Foundation
Diffstat (limited to 'sys/ufs/ffs/ffs_vfsops.c')
-rw-r--r--sys/ufs/ffs/ffs_vfsops.c43
1 files changed, 33 insertions, 10 deletions
diff --git a/sys/ufs/ffs/ffs_vfsops.c b/sys/ufs/ffs/ffs_vfsops.c
index cc54ece..0a43d80 100644
--- a/sys/ufs/ffs/ffs_vfsops.c
+++ b/sys/ufs/ffs/ffs_vfsops.c
@@ -49,6 +49,7 @@ __FBSDID("$FreeBSD$");
#include <sys/buf.h>
#include <sys/conf.h>
#include <sys/fcntl.h>
+#include <sys/ioccom.h>
#include <sys/malloc.h>
#include <sys/mutex.h>
@@ -75,7 +76,6 @@ __FBSDID("$FreeBSD$");
static uma_zone_t uma_inode, uma_ufs1, uma_ufs2;
-static int ffs_reload(struct mount *, struct thread *);
static int ffs_mountfs(struct vnode *, struct mount *, struct thread *);
static void ffs_oldfscompat_read(struct fs *, struct ufsmount *,
ufs2_daddr_t);
@@ -333,7 +333,7 @@ ffs_mount(struct mount *mp)
vfs_write_resume(mp);
}
if ((mp->mnt_flag & MNT_RELOAD) &&
- (error = ffs_reload(mp, td)) != 0)
+ (error = ffs_reload(mp, td, 0)) != 0)
return (error);
if (fs->fs_ronly &&
!vfs_flagopt(mp->mnt_optnew, "ro", NULL, 0)) {
@@ -595,8 +595,8 @@ ffs_cmount(struct mntarg *ma, void *data, uint64_t flags)
/*
* Reload all incore data for a filesystem (used after running fsck on
- * the root filesystem and finding things to fix). The filesystem must
- * be mounted read-only.
+ * the root filesystem and finding things to fix). If the 'force' flag
+ * is 0, the filesystem must be mounted read-only.
*
* Things to do to update the mount:
* 1) invalidate all cached meta-data.
@@ -606,8 +606,8 @@ ffs_cmount(struct mntarg *ma, void *data, uint64_t flags)
* 5) invalidate all cached file data.
* 6) re-read inode data for all active vnodes.
*/
-static int
-ffs_reload(struct mount *mp, struct thread *td)
+int
+ffs_reload(struct mount *mp, struct thread *td, int force)
{
struct vnode *vp, *mvp, *devvp;
struct inode *ip;
@@ -619,9 +619,15 @@ ffs_reload(struct mount *mp, struct thread *td)
int i, blks, size, error;
int32_t *lp;
- if ((mp->mnt_flag & MNT_RDONLY) == 0)
- return (EINVAL);
ump = VFSTOUFS(mp);
+
+ MNT_ILOCK(mp);
+ if ((mp->mnt_flag & MNT_RDONLY) == 0 && force == 0) {
+ MNT_IUNLOCK(mp);
+ return (EINVAL);
+ }
+ MNT_IUNLOCK(mp);
+
/*
* Step 1: invalidate all cached meta-data.
*/
@@ -655,8 +661,7 @@ ffs_reload(struct mount *mp, struct thread *td)
newfs->fs_maxcluster = fs->fs_maxcluster;
newfs->fs_contigdirs = fs->fs_contigdirs;
newfs->fs_active = fs->fs_active;
- /* The file system is still read-only. */
- newfs->fs_ronly = 1;
+ newfs->fs_ronly = fs->fs_ronly;
sblockloc = fs->fs_sblockloc;
bcopy(newfs, fs, (u_int)fs->fs_sbsize);
brelse(bp);
@@ -711,6 +716,13 @@ ffs_reload(struct mount *mp, struct thread *td)
loop:
MNT_VNODE_FOREACH_ALL(vp, mp, mvp) {
/*
+ * Skip syncer vnode.
+ */
+ if (vp->v_type == VNON) {
+ VI_UNLOCK(vp);
+ continue;
+ }
+ /*
* Step 4: invalidate all cached file data.
*/
if (vget(vp, LK_EXCLUSIVE | LK_INTERLOCK, td)) {
@@ -1834,6 +1846,7 @@ ffs_init(vfsp)
struct vfsconf *vfsp;
{
+ ffs_susp_initialize();
softdep_initialize();
return (ufs_init(vfsp));
}
@@ -1849,6 +1862,7 @@ ffs_uninit(vfsp)
ret = ufs_uninit(vfsp);
softdep_uninitialize();
+ ffs_susp_uninitialize();
return (ret);
}
@@ -2198,6 +2212,15 @@ ffs_geom_strategy(struct bufobj *bo, struct buf *bp)
g_vfs_strategy(bo, bp);
}
+int
+ffs_own_mount(const struct mount *mp)
+{
+
+ if (mp->mnt_op == &ufs_vfsops)
+ return (1);
+ return (0);
+}
+
#ifdef DDB
static void
OpenPOWER on IntegriCloud