summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJeff Layton <jlayton@kernel.org>2021-10-14 18:10:47 +0300
committerIlya Dryomov <idryomov@gmail.com>2021-11-08 05:29:52 +0300
commit631ed4b082872767412cda8a941af832f227335c (patch)
tree2afeb0c6d1924769a928751ba4c0387c818de63d
parent0e24421ac431e7af62d4acef6c638b85aae51728 (diff)
downloadlinux-631ed4b082872767412cda8a941af832f227335c.tar.xz
ceph: shut down mount on bad mdsmap or fsmap decode
As Greg pointed out, if we get a mangled mdsmap or fsmap, then something has gone very wrong, and we should avoid doing any activity on the filesystem. When this occurs, shut down the mount the same way we would with a forced umount by calling ceph_umount_begin when decoding fails on either map. This causes most operations done against the filesystem to return an error. Any dirty data or caps in the cache will be dropped as well. The effect is not reversible, so the only remedy is to umount. [ idryomov: print fsmap decoding error ] URL: https://tracker.ceph.com/issues/52303 Signed-off-by: Jeff Layton <jlayton@kernel.org> Acked-by: Greg Farnum <gfarnum@redhat.com> Signed-off-by: Ilya Dryomov <idryomov@gmail.com>
-rw-r--r--fs/ceph/mds_client.c6
-rw-r--r--fs/ceph/super.c2
-rw-r--r--fs/ceph/super.h1
3 files changed, 6 insertions, 3 deletions
diff --git a/fs/ceph/mds_client.c b/fs/ceph/mds_client.c
index 522790c64db4..250aad330a10 100644
--- a/fs/ceph/mds_client.c
+++ b/fs/ceph/mds_client.c
@@ -4983,7 +4983,8 @@ void ceph_mdsc_handle_fsmap(struct ceph_mds_client *mdsc, struct ceph_msg *msg)
return;
bad:
- pr_err("error decoding fsmap\n");
+ pr_err("error decoding fsmap %d. Shutting down mount.\n", err);
+ ceph_umount_begin(mdsc->fsc->sb);
err_out:
mutex_lock(&mdsc->mutex);
mdsc->mdsmap_err = err;
@@ -5050,7 +5051,8 @@ void ceph_mdsc_handle_mdsmap(struct ceph_mds_client *mdsc, struct ceph_msg *msg)
bad_unlock:
mutex_unlock(&mdsc->mutex);
bad:
- pr_err("error decoding mdsmap %d\n", err);
+ pr_err("error decoding mdsmap %d. Shutting down mount.\n", err);
+ ceph_umount_begin(mdsc->fsc->sb);
return;
}
diff --git a/fs/ceph/super.c b/fs/ceph/super.c
index 5fe4d9f102e8..f6cbbfcdf66d 100644
--- a/fs/ceph/super.c
+++ b/fs/ceph/super.c
@@ -842,7 +842,7 @@ static void __ceph_umount_begin(struct ceph_fs_client *fsc)
* ceph_umount_begin - initiate forced umount. Tear down the
* mount, skipping steps that may hang while waiting for server(s).
*/
-static void ceph_umount_begin(struct super_block *sb)
+void ceph_umount_begin(struct super_block *sb)
{
struct ceph_fs_client *fsc = ceph_sb_to_client(sb);
diff --git a/fs/ceph/super.h b/fs/ceph/super.h
index 5c911586593d..93d313294ade 100644
--- a/fs/ceph/super.h
+++ b/fs/ceph/super.h
@@ -941,6 +941,7 @@ extern void ceph_put_snapid_map(struct ceph_mds_client* mdsc,
struct ceph_snapid_map *sm);
extern void ceph_trim_snapid_map(struct ceph_mds_client *mdsc);
extern void ceph_cleanup_snapid_map(struct ceph_mds_client *mdsc);
+void ceph_umount_begin(struct super_block *sb);
/*