git: 171b75b0efd0 - stable/13 - msdosfs: add msdosfs_integrity_error()
- Go to: [ bottom of page ] [ top of archives ] [ this month ]
Date: Sat, 15 Jan 2022 00:51:44 UTC
The branch stable/13 has been updated by kib:
URL: https://cgit.FreeBSD.org/src/commit/?id=171b75b0efd0bb56597acb3c12f57db03fabc660
commit 171b75b0efd0bb56597acb3c12f57db03fabc660
Author: Konstantin Belousov <kib@FreeBSD.org>
AuthorDate: 2021-12-25 21:20:56 +0000
Commit: Konstantin Belousov <kib@FreeBSD.org>
CommitDate: 2022-01-14 18:11:02 +0000
msdosfs: add msdosfs_integrity_error()
(cherry picked from commit b2e4b635844091de0601f5b7157d87115386b2a9)
---
sys/fs/msdosfs/msdosfs_vfsops.c | 58 +++++++++++++++++++++++++++++++++++++++++
sys/fs/msdosfs/msdosfsmount.h | 7 +++++
2 files changed, 65 insertions(+)
diff --git a/sys/fs/msdosfs/msdosfs_vfsops.c b/sys/fs/msdosfs/msdosfs_vfsops.c
index 77942ed88ce4..e09a75a698d7 100644
--- a/sys/fs/msdosfs/msdosfs_vfsops.c
+++ b/sys/fs/msdosfs/msdosfs_vfsops.c
@@ -65,6 +65,7 @@
#include <sys/priv.h>
#include <sys/proc.h>
#include <sys/stat.h>
+#include <sys/taskqueue.h>
#include <sys/vnode.h>
#include <geom/geom.h>
@@ -112,6 +113,7 @@ struct iconv_functions *msdosfs_iconv;
static int update_mp(struct mount *mp, struct thread *td);
static int mountmsdosfs(struct vnode *devvp, struct mount *mp);
+static void msdosfs_remount_ro(void *arg, int pending);
static vfs_fhtovp_t msdosfs_fhtovp;
static vfs_mount_t msdosfs_mount;
static vfs_root_t msdosfs_root;
@@ -337,6 +339,13 @@ msdosfs_mount(struct mount *mp)
mp->mnt_flag &= ~MNT_RDONLY;
MNT_IUNLOCK(mp);
}
+
+ /*
+ * Avoid namei() below. The "from" option is not set.
+ * Update of the devvp is pointless for this case.
+ */
+ if ((pmp->pm_flags & MSDOSFS_ERR_RO) != 0)
+ return (0);
}
/*
* Not an update, or updating the name: look up the name
@@ -471,6 +480,8 @@ mountmsdosfs(struct vnode *devvp, struct mount *mp)
lockinit(&pmp->pm_fatlock, 0, msdosfs_lock_msg, 0, 0);
lockinit(&pmp->pm_checkpath_lock, 0, "msdoscp", 0, 0);
+ TASK_INIT(&pmp->pm_rw2ro_task, 0, msdosfs_remount_ro, pmp);
+
/*
* Initialize ownerships and permissions, since nothing else will
* initialize them iff we are mounting root.
@@ -847,6 +858,53 @@ msdosfs_unmount(struct mount *mp, int mntflags)
return (error);
}
+static void
+msdosfs_remount_ro(void *arg, int pending)
+{
+ struct msdosfsmount *pmp;
+ int error;
+
+ pmp = arg;
+
+ MSDOSFS_LOCK_MP(pmp);
+ if ((pmp->pm_flags & MSDOSFS_ERR_RO) != 0) {
+ while ((pmp->pm_flags & MSDOSFS_ERR_RO) != 0)
+ msleep(&pmp->pm_flags, &pmp->pm_fatlock, PVFS,
+ "msdoserrro", hz);
+ } else if ((pmp->pm_mountp->mnt_flag & MNT_RDONLY) == 0) {
+ pmp->pm_flags |= MSDOSFS_ERR_RO;
+ MSDOSFS_UNLOCK_MP(pmp);
+ printf("%s: remounting read-only due to corruption\n",
+ pmp->pm_mountp->mnt_stat.f_mntfromname);
+ error = vfs_remount_ro(pmp->pm_mountp);
+ if (error != 0)
+ printf("%s: remounting read-only failed: error %d\n",
+ pmp->pm_mountp->mnt_stat.f_mntfromname, error);
+ else
+ printf("remounted %s read-only\n",
+ pmp->pm_mountp->mnt_stat.f_mntfromname);
+ MSDOSFS_LOCK_MP(pmp);
+ pmp->pm_flags &= ~MSDOSFS_ERR_RO;
+ wakeup(&pmp->pm_flags);
+ }
+ MSDOSFS_UNLOCK_MP(pmp);
+
+ vfs_unbusy(pmp->pm_mountp);
+}
+
+void
+msdosfs_integrity_error(struct msdosfsmount *pmp)
+{
+ int error;
+
+ error = vfs_busy(pmp->pm_mountp, MBF_NOWAIT);
+ if (error == 0)
+ taskqueue_enqueue(taskqueue_thread, &pmp->pm_rw2ro_task);
+ else
+ printf("%s: integrity error busying failed, error %d\n",
+ pmp->pm_mountp->mnt_stat.f_mntfromname, error);
+}
+
static int
msdosfs_root(struct mount *mp, int flags, struct vnode **vpp)
{
diff --git a/sys/fs/msdosfs/msdosfsmount.h b/sys/fs/msdosfs/msdosfsmount.h
index 46a02e611cf5..6a0ba896dff5 100644
--- a/sys/fs/msdosfs/msdosfsmount.h
+++ b/sys/fs/msdosfs/msdosfsmount.h
@@ -59,6 +59,7 @@
#ifndef MAKEFS
#include <sys/lock.h>
#include <sys/lockmgr.h>
+#include <sys/_task.h>
#endif
#include <sys/tree.h>
@@ -115,6 +116,7 @@ struct msdosfsmount {
#ifndef MAKEFS
struct lock pm_fatlock; /* lockmgr protecting allocations */
struct lock pm_checkpath_lock; /* protects doscheckpath result */
+ struct task pm_rw2ro_task; /* context for emergency remount ro */
#endif
};
@@ -263,5 +265,10 @@ struct msdosfs_args {
#define MSDOSFSMNT_WAITONFAT 0x40000000 /* mounted synchronous */
#define MSDOSFS_FATMIRROR 0x20000000 /* FAT is mirrored */
#define MSDOSFS_FSIMOD 0x01000000
+#define MSDOSFS_ERR_RO 0x00800000 /* remouning ro due to error */
+
+#ifdef _KERNEL
+void msdosfs_integrity_error(struct msdosfsmount *pmp);
+#endif
#endif /* !_MSDOSFS_MSDOSFSMOUNT_H_ */