18c2ecf20Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0
28c2ecf20Sopenharmony_ci/*
38c2ecf20Sopenharmony_ci *  linux/fs/super.c
48c2ecf20Sopenharmony_ci *
58c2ecf20Sopenharmony_ci *  Copyright (C) 1991, 1992  Linus Torvalds
68c2ecf20Sopenharmony_ci *
78c2ecf20Sopenharmony_ci *  super.c contains code to handle: - mount structures
88c2ecf20Sopenharmony_ci *                                   - super-block tables
98c2ecf20Sopenharmony_ci *                                   - filesystem drivers list
108c2ecf20Sopenharmony_ci *                                   - mount system call
118c2ecf20Sopenharmony_ci *                                   - umount system call
128c2ecf20Sopenharmony_ci *                                   - ustat system call
138c2ecf20Sopenharmony_ci *
148c2ecf20Sopenharmony_ci * GK 2/5/95  -  Changed to support mounting the root fs via NFS
158c2ecf20Sopenharmony_ci *
168c2ecf20Sopenharmony_ci *  Added kerneld support: Jacques Gelinas and Bjorn Ekwall
178c2ecf20Sopenharmony_ci *  Added change_root: Werner Almesberger & Hans Lermen, Feb '96
188c2ecf20Sopenharmony_ci *  Added options to /proc/mounts:
198c2ecf20Sopenharmony_ci *    Torbjörn Lindh (torbjorn.lindh@gopta.se), April 14, 1996.
208c2ecf20Sopenharmony_ci *  Added devfs support: Richard Gooch <rgooch@atnf.csiro.au>, 13-JAN-1998
218c2ecf20Sopenharmony_ci *  Heavily rewritten for 'one fs - one tree' dcache architecture. AV, Mar 2000
228c2ecf20Sopenharmony_ci */
238c2ecf20Sopenharmony_ci
248c2ecf20Sopenharmony_ci#include <linux/export.h>
258c2ecf20Sopenharmony_ci#include <linux/slab.h>
268c2ecf20Sopenharmony_ci#include <linux/blkdev.h>
278c2ecf20Sopenharmony_ci#include <linux/mount.h>
288c2ecf20Sopenharmony_ci#include <linux/security.h>
298c2ecf20Sopenharmony_ci#include <linux/writeback.h>		/* for the emergency remount stuff */
308c2ecf20Sopenharmony_ci#include <linux/idr.h>
318c2ecf20Sopenharmony_ci#include <linux/mutex.h>
328c2ecf20Sopenharmony_ci#include <linux/backing-dev.h>
338c2ecf20Sopenharmony_ci#include <linux/rculist_bl.h>
348c2ecf20Sopenharmony_ci#include <linux/cleancache.h>
358c2ecf20Sopenharmony_ci#include <linux/fscrypt.h>
368c2ecf20Sopenharmony_ci#include <linux/fsnotify.h>
378c2ecf20Sopenharmony_ci#include <linux/lockdep.h>
388c2ecf20Sopenharmony_ci#include <linux/user_namespace.h>
398c2ecf20Sopenharmony_ci#include <linux/fs_context.h>
408c2ecf20Sopenharmony_ci#include <uapi/linux/mount.h>
418c2ecf20Sopenharmony_ci#include "internal.h"
428c2ecf20Sopenharmony_ci
438c2ecf20Sopenharmony_cistatic int thaw_super_locked(struct super_block *sb);
448c2ecf20Sopenharmony_ci
458c2ecf20Sopenharmony_cistatic LIST_HEAD(super_blocks);
468c2ecf20Sopenharmony_cistatic DEFINE_SPINLOCK(sb_lock);
478c2ecf20Sopenharmony_ci
488c2ecf20Sopenharmony_cistatic char *sb_writers_name[SB_FREEZE_LEVELS] = {
498c2ecf20Sopenharmony_ci	"sb_writers",
508c2ecf20Sopenharmony_ci	"sb_pagefaults",
518c2ecf20Sopenharmony_ci	"sb_internal",
528c2ecf20Sopenharmony_ci};
538c2ecf20Sopenharmony_ci
548c2ecf20Sopenharmony_ci/*
558c2ecf20Sopenharmony_ci * One thing we have to be careful of with a per-sb shrinker is that we don't
568c2ecf20Sopenharmony_ci * drop the last active reference to the superblock from within the shrinker.
578c2ecf20Sopenharmony_ci * If that happens we could trigger unregistering the shrinker from within the
588c2ecf20Sopenharmony_ci * shrinker path and that leads to deadlock on the shrinker_rwsem. Hence we
598c2ecf20Sopenharmony_ci * take a passive reference to the superblock to avoid this from occurring.
608c2ecf20Sopenharmony_ci */
618c2ecf20Sopenharmony_cistatic unsigned long super_cache_scan(struct shrinker *shrink,
628c2ecf20Sopenharmony_ci				      struct shrink_control *sc)
638c2ecf20Sopenharmony_ci{
648c2ecf20Sopenharmony_ci	struct super_block *sb;
658c2ecf20Sopenharmony_ci	long	fs_objects = 0;
668c2ecf20Sopenharmony_ci	long	total_objects;
678c2ecf20Sopenharmony_ci	long	freed = 0;
688c2ecf20Sopenharmony_ci	long	dentries;
698c2ecf20Sopenharmony_ci	long	inodes;
708c2ecf20Sopenharmony_ci
718c2ecf20Sopenharmony_ci	sb = container_of(shrink, struct super_block, s_shrink);
728c2ecf20Sopenharmony_ci
738c2ecf20Sopenharmony_ci	/*
748c2ecf20Sopenharmony_ci	 * Deadlock avoidance.  We may hold various FS locks, and we don't want
758c2ecf20Sopenharmony_ci	 * to recurse into the FS that called us in clear_inode() and friends..
768c2ecf20Sopenharmony_ci	 */
778c2ecf20Sopenharmony_ci	if (!(sc->gfp_mask & __GFP_FS))
788c2ecf20Sopenharmony_ci		return SHRINK_STOP;
798c2ecf20Sopenharmony_ci
808c2ecf20Sopenharmony_ci	if (!trylock_super(sb))
818c2ecf20Sopenharmony_ci		return SHRINK_STOP;
828c2ecf20Sopenharmony_ci
838c2ecf20Sopenharmony_ci	if (sb->s_op->nr_cached_objects)
848c2ecf20Sopenharmony_ci		fs_objects = sb->s_op->nr_cached_objects(sb, sc);
858c2ecf20Sopenharmony_ci
868c2ecf20Sopenharmony_ci	inodes = list_lru_shrink_count(&sb->s_inode_lru, sc);
878c2ecf20Sopenharmony_ci	dentries = list_lru_shrink_count(&sb->s_dentry_lru, sc);
888c2ecf20Sopenharmony_ci	total_objects = dentries + inodes + fs_objects + 1;
898c2ecf20Sopenharmony_ci	if (!total_objects)
908c2ecf20Sopenharmony_ci		total_objects = 1;
918c2ecf20Sopenharmony_ci
928c2ecf20Sopenharmony_ci	/* proportion the scan between the caches */
938c2ecf20Sopenharmony_ci	dentries = mult_frac(sc->nr_to_scan, dentries, total_objects);
948c2ecf20Sopenharmony_ci	inodes = mult_frac(sc->nr_to_scan, inodes, total_objects);
958c2ecf20Sopenharmony_ci	fs_objects = mult_frac(sc->nr_to_scan, fs_objects, total_objects);
968c2ecf20Sopenharmony_ci
978c2ecf20Sopenharmony_ci	/*
988c2ecf20Sopenharmony_ci	 * prune the dcache first as the icache is pinned by it, then
998c2ecf20Sopenharmony_ci	 * prune the icache, followed by the filesystem specific caches
1008c2ecf20Sopenharmony_ci	 *
1018c2ecf20Sopenharmony_ci	 * Ensure that we always scan at least one object - memcg kmem
1028c2ecf20Sopenharmony_ci	 * accounting uses this to fully empty the caches.
1038c2ecf20Sopenharmony_ci	 */
1048c2ecf20Sopenharmony_ci	sc->nr_to_scan = dentries + 1;
1058c2ecf20Sopenharmony_ci	freed = prune_dcache_sb(sb, sc);
1068c2ecf20Sopenharmony_ci	sc->nr_to_scan = inodes + 1;
1078c2ecf20Sopenharmony_ci	freed += prune_icache_sb(sb, sc);
1088c2ecf20Sopenharmony_ci
1098c2ecf20Sopenharmony_ci	if (fs_objects) {
1108c2ecf20Sopenharmony_ci		sc->nr_to_scan = fs_objects + 1;
1118c2ecf20Sopenharmony_ci		freed += sb->s_op->free_cached_objects(sb, sc);
1128c2ecf20Sopenharmony_ci	}
1138c2ecf20Sopenharmony_ci
1148c2ecf20Sopenharmony_ci	up_read(&sb->s_umount);
1158c2ecf20Sopenharmony_ci	return freed;
1168c2ecf20Sopenharmony_ci}
1178c2ecf20Sopenharmony_ci
1188c2ecf20Sopenharmony_cistatic unsigned long super_cache_count(struct shrinker *shrink,
1198c2ecf20Sopenharmony_ci				       struct shrink_control *sc)
1208c2ecf20Sopenharmony_ci{
1218c2ecf20Sopenharmony_ci	struct super_block *sb;
1228c2ecf20Sopenharmony_ci	long	total_objects = 0;
1238c2ecf20Sopenharmony_ci
1248c2ecf20Sopenharmony_ci	sb = container_of(shrink, struct super_block, s_shrink);
1258c2ecf20Sopenharmony_ci
1268c2ecf20Sopenharmony_ci	/*
1278c2ecf20Sopenharmony_ci	 * We don't call trylock_super() here as it is a scalability bottleneck,
1288c2ecf20Sopenharmony_ci	 * so we're exposed to partial setup state. The shrinker rwsem does not
1298c2ecf20Sopenharmony_ci	 * protect filesystem operations backing list_lru_shrink_count() or
1308c2ecf20Sopenharmony_ci	 * s_op->nr_cached_objects(). Counts can change between
1318c2ecf20Sopenharmony_ci	 * super_cache_count and super_cache_scan, so we really don't need locks
1328c2ecf20Sopenharmony_ci	 * here.
1338c2ecf20Sopenharmony_ci	 *
1348c2ecf20Sopenharmony_ci	 * However, if we are currently mounting the superblock, the underlying
1358c2ecf20Sopenharmony_ci	 * filesystem might be in a state of partial construction and hence it
1368c2ecf20Sopenharmony_ci	 * is dangerous to access it.  trylock_super() uses a SB_BORN check to
1378c2ecf20Sopenharmony_ci	 * avoid this situation, so do the same here. The memory barrier is
1388c2ecf20Sopenharmony_ci	 * matched with the one in mount_fs() as we don't hold locks here.
1398c2ecf20Sopenharmony_ci	 */
1408c2ecf20Sopenharmony_ci	if (!(sb->s_flags & SB_BORN))
1418c2ecf20Sopenharmony_ci		return 0;
1428c2ecf20Sopenharmony_ci	smp_rmb();
1438c2ecf20Sopenharmony_ci
1448c2ecf20Sopenharmony_ci	if (sb->s_op && sb->s_op->nr_cached_objects)
1458c2ecf20Sopenharmony_ci		total_objects = sb->s_op->nr_cached_objects(sb, sc);
1468c2ecf20Sopenharmony_ci
1478c2ecf20Sopenharmony_ci	total_objects += list_lru_shrink_count(&sb->s_dentry_lru, sc);
1488c2ecf20Sopenharmony_ci	total_objects += list_lru_shrink_count(&sb->s_inode_lru, sc);
1498c2ecf20Sopenharmony_ci
1508c2ecf20Sopenharmony_ci	if (!total_objects)
1518c2ecf20Sopenharmony_ci		return SHRINK_EMPTY;
1528c2ecf20Sopenharmony_ci
1538c2ecf20Sopenharmony_ci	total_objects = vfs_pressure_ratio(total_objects);
1548c2ecf20Sopenharmony_ci	return total_objects;
1558c2ecf20Sopenharmony_ci}
1568c2ecf20Sopenharmony_ci
1578c2ecf20Sopenharmony_cistatic void destroy_super_work(struct work_struct *work)
1588c2ecf20Sopenharmony_ci{
1598c2ecf20Sopenharmony_ci	struct super_block *s = container_of(work, struct super_block,
1608c2ecf20Sopenharmony_ci							destroy_work);
1618c2ecf20Sopenharmony_ci	int i;
1628c2ecf20Sopenharmony_ci
1638c2ecf20Sopenharmony_ci	for (i = 0; i < SB_FREEZE_LEVELS; i++)
1648c2ecf20Sopenharmony_ci		percpu_free_rwsem(&s->s_writers.rw_sem[i]);
1658c2ecf20Sopenharmony_ci	kfree(s);
1668c2ecf20Sopenharmony_ci}
1678c2ecf20Sopenharmony_ci
1688c2ecf20Sopenharmony_cistatic void destroy_super_rcu(struct rcu_head *head)
1698c2ecf20Sopenharmony_ci{
1708c2ecf20Sopenharmony_ci	struct super_block *s = container_of(head, struct super_block, rcu);
1718c2ecf20Sopenharmony_ci	INIT_WORK(&s->destroy_work, destroy_super_work);
1728c2ecf20Sopenharmony_ci	schedule_work(&s->destroy_work);
1738c2ecf20Sopenharmony_ci}
1748c2ecf20Sopenharmony_ci
1758c2ecf20Sopenharmony_ci/* Free a superblock that has never been seen by anyone */
1768c2ecf20Sopenharmony_cistatic void destroy_unused_super(struct super_block *s)
1778c2ecf20Sopenharmony_ci{
1788c2ecf20Sopenharmony_ci	if (!s)
1798c2ecf20Sopenharmony_ci		return;
1808c2ecf20Sopenharmony_ci	up_write(&s->s_umount);
1818c2ecf20Sopenharmony_ci	list_lru_destroy(&s->s_dentry_lru);
1828c2ecf20Sopenharmony_ci	list_lru_destroy(&s->s_inode_lru);
1838c2ecf20Sopenharmony_ci	security_sb_free(s);
1848c2ecf20Sopenharmony_ci	put_user_ns(s->s_user_ns);
1858c2ecf20Sopenharmony_ci	kfree(s->s_subtype);
1868c2ecf20Sopenharmony_ci	free_prealloced_shrinker(&s->s_shrink);
1878c2ecf20Sopenharmony_ci	/* no delays needed */
1888c2ecf20Sopenharmony_ci	destroy_super_work(&s->destroy_work);
1898c2ecf20Sopenharmony_ci}
1908c2ecf20Sopenharmony_ci
1918c2ecf20Sopenharmony_ci/**
1928c2ecf20Sopenharmony_ci *	alloc_super	-	create new superblock
1938c2ecf20Sopenharmony_ci *	@type:	filesystem type superblock should belong to
1948c2ecf20Sopenharmony_ci *	@flags: the mount flags
1958c2ecf20Sopenharmony_ci *	@user_ns: User namespace for the super_block
1968c2ecf20Sopenharmony_ci *
1978c2ecf20Sopenharmony_ci *	Allocates and initializes a new &struct super_block.  alloc_super()
1988c2ecf20Sopenharmony_ci *	returns a pointer new superblock or %NULL if allocation had failed.
1998c2ecf20Sopenharmony_ci */
2008c2ecf20Sopenharmony_cistatic struct super_block *alloc_super(struct file_system_type *type, int flags,
2018c2ecf20Sopenharmony_ci				       struct user_namespace *user_ns)
2028c2ecf20Sopenharmony_ci{
2038c2ecf20Sopenharmony_ci	struct super_block *s = kzalloc(sizeof(struct super_block),  GFP_USER);
2048c2ecf20Sopenharmony_ci	static const struct super_operations default_op;
2058c2ecf20Sopenharmony_ci	int i;
2068c2ecf20Sopenharmony_ci
2078c2ecf20Sopenharmony_ci	if (!s)
2088c2ecf20Sopenharmony_ci		return NULL;
2098c2ecf20Sopenharmony_ci
2108c2ecf20Sopenharmony_ci	INIT_LIST_HEAD(&s->s_mounts);
2118c2ecf20Sopenharmony_ci	s->s_user_ns = get_user_ns(user_ns);
2128c2ecf20Sopenharmony_ci	init_rwsem(&s->s_umount);
2138c2ecf20Sopenharmony_ci	lockdep_set_class(&s->s_umount, &type->s_umount_key);
2148c2ecf20Sopenharmony_ci	/*
2158c2ecf20Sopenharmony_ci	 * sget() can have s_umount recursion.
2168c2ecf20Sopenharmony_ci	 *
2178c2ecf20Sopenharmony_ci	 * When it cannot find a suitable sb, it allocates a new
2188c2ecf20Sopenharmony_ci	 * one (this one), and tries again to find a suitable old
2198c2ecf20Sopenharmony_ci	 * one.
2208c2ecf20Sopenharmony_ci	 *
2218c2ecf20Sopenharmony_ci	 * In case that succeeds, it will acquire the s_umount
2228c2ecf20Sopenharmony_ci	 * lock of the old one. Since these are clearly distrinct
2238c2ecf20Sopenharmony_ci	 * locks, and this object isn't exposed yet, there's no
2248c2ecf20Sopenharmony_ci	 * risk of deadlocks.
2258c2ecf20Sopenharmony_ci	 *
2268c2ecf20Sopenharmony_ci	 * Annotate this by putting this lock in a different
2278c2ecf20Sopenharmony_ci	 * subclass.
2288c2ecf20Sopenharmony_ci	 */
2298c2ecf20Sopenharmony_ci	down_write_nested(&s->s_umount, SINGLE_DEPTH_NESTING);
2308c2ecf20Sopenharmony_ci
2318c2ecf20Sopenharmony_ci	if (security_sb_alloc(s))
2328c2ecf20Sopenharmony_ci		goto fail;
2338c2ecf20Sopenharmony_ci
2348c2ecf20Sopenharmony_ci	for (i = 0; i < SB_FREEZE_LEVELS; i++) {
2358c2ecf20Sopenharmony_ci		if (__percpu_init_rwsem(&s->s_writers.rw_sem[i],
2368c2ecf20Sopenharmony_ci					sb_writers_name[i],
2378c2ecf20Sopenharmony_ci					&type->s_writers_key[i]))
2388c2ecf20Sopenharmony_ci			goto fail;
2398c2ecf20Sopenharmony_ci	}
2408c2ecf20Sopenharmony_ci	init_waitqueue_head(&s->s_writers.wait_unfrozen);
2418c2ecf20Sopenharmony_ci	s->s_bdi = &noop_backing_dev_info;
2428c2ecf20Sopenharmony_ci	s->s_flags = flags;
2438c2ecf20Sopenharmony_ci	if (s->s_user_ns != &init_user_ns)
2448c2ecf20Sopenharmony_ci		s->s_iflags |= SB_I_NODEV;
2458c2ecf20Sopenharmony_ci	INIT_HLIST_NODE(&s->s_instances);
2468c2ecf20Sopenharmony_ci	INIT_HLIST_BL_HEAD(&s->s_roots);
2478c2ecf20Sopenharmony_ci	mutex_init(&s->s_sync_lock);
2488c2ecf20Sopenharmony_ci	INIT_LIST_HEAD(&s->s_inodes);
2498c2ecf20Sopenharmony_ci	spin_lock_init(&s->s_inode_list_lock);
2508c2ecf20Sopenharmony_ci	INIT_LIST_HEAD(&s->s_inodes_wb);
2518c2ecf20Sopenharmony_ci	spin_lock_init(&s->s_inode_wblist_lock);
2528c2ecf20Sopenharmony_ci
2538c2ecf20Sopenharmony_ci	s->s_count = 1;
2548c2ecf20Sopenharmony_ci	atomic_set(&s->s_active, 1);
2558c2ecf20Sopenharmony_ci	mutex_init(&s->s_vfs_rename_mutex);
2568c2ecf20Sopenharmony_ci	lockdep_set_class(&s->s_vfs_rename_mutex, &type->s_vfs_rename_key);
2578c2ecf20Sopenharmony_ci	init_rwsem(&s->s_dquot.dqio_sem);
2588c2ecf20Sopenharmony_ci	s->s_maxbytes = MAX_NON_LFS;
2598c2ecf20Sopenharmony_ci	s->s_op = &default_op;
2608c2ecf20Sopenharmony_ci	s->s_time_gran = 1000000000;
2618c2ecf20Sopenharmony_ci	s->s_time_min = TIME64_MIN;
2628c2ecf20Sopenharmony_ci	s->s_time_max = TIME64_MAX;
2638c2ecf20Sopenharmony_ci	s->cleancache_poolid = CLEANCACHE_NO_POOL;
2648c2ecf20Sopenharmony_ci
2658c2ecf20Sopenharmony_ci	s->s_shrink.seeks = DEFAULT_SEEKS;
2668c2ecf20Sopenharmony_ci	s->s_shrink.scan_objects = super_cache_scan;
2678c2ecf20Sopenharmony_ci	s->s_shrink.count_objects = super_cache_count;
2688c2ecf20Sopenharmony_ci	s->s_shrink.batch = 1024;
2698c2ecf20Sopenharmony_ci	s->s_shrink.flags = SHRINKER_NUMA_AWARE | SHRINKER_MEMCG_AWARE;
2708c2ecf20Sopenharmony_ci	if (prealloc_shrinker(&s->s_shrink))
2718c2ecf20Sopenharmony_ci		goto fail;
2728c2ecf20Sopenharmony_ci	if (list_lru_init_memcg(&s->s_dentry_lru, &s->s_shrink))
2738c2ecf20Sopenharmony_ci		goto fail;
2748c2ecf20Sopenharmony_ci	if (list_lru_init_memcg(&s->s_inode_lru, &s->s_shrink))
2758c2ecf20Sopenharmony_ci		goto fail;
2768c2ecf20Sopenharmony_ci	return s;
2778c2ecf20Sopenharmony_ci
2788c2ecf20Sopenharmony_cifail:
2798c2ecf20Sopenharmony_ci	destroy_unused_super(s);
2808c2ecf20Sopenharmony_ci	return NULL;
2818c2ecf20Sopenharmony_ci}
2828c2ecf20Sopenharmony_ci
2838c2ecf20Sopenharmony_ci/* Superblock refcounting  */
2848c2ecf20Sopenharmony_ci
2858c2ecf20Sopenharmony_ci/*
2868c2ecf20Sopenharmony_ci * Drop a superblock's refcount.  The caller must hold sb_lock.
2878c2ecf20Sopenharmony_ci */
2888c2ecf20Sopenharmony_cistatic void __put_super(struct super_block *s)
2898c2ecf20Sopenharmony_ci{
2908c2ecf20Sopenharmony_ci	if (!--s->s_count) {
2918c2ecf20Sopenharmony_ci		list_del_init(&s->s_list);
2928c2ecf20Sopenharmony_ci		WARN_ON(s->s_dentry_lru.node);
2938c2ecf20Sopenharmony_ci		WARN_ON(s->s_inode_lru.node);
2948c2ecf20Sopenharmony_ci		WARN_ON(!list_empty(&s->s_mounts));
2958c2ecf20Sopenharmony_ci		security_sb_free(s);
2968c2ecf20Sopenharmony_ci		fscrypt_destroy_keyring(s);
2978c2ecf20Sopenharmony_ci		put_user_ns(s->s_user_ns);
2988c2ecf20Sopenharmony_ci		kfree(s->s_subtype);
2998c2ecf20Sopenharmony_ci		call_rcu(&s->rcu, destroy_super_rcu);
3008c2ecf20Sopenharmony_ci	}
3018c2ecf20Sopenharmony_ci}
3028c2ecf20Sopenharmony_ci
3038c2ecf20Sopenharmony_ci/**
3048c2ecf20Sopenharmony_ci *	put_super	-	drop a temporary reference to superblock
3058c2ecf20Sopenharmony_ci *	@sb: superblock in question
3068c2ecf20Sopenharmony_ci *
3078c2ecf20Sopenharmony_ci *	Drops a temporary reference, frees superblock if there's no
3088c2ecf20Sopenharmony_ci *	references left.
3098c2ecf20Sopenharmony_ci */
3108c2ecf20Sopenharmony_cistatic void put_super(struct super_block *sb)
3118c2ecf20Sopenharmony_ci{
3128c2ecf20Sopenharmony_ci	spin_lock(&sb_lock);
3138c2ecf20Sopenharmony_ci	__put_super(sb);
3148c2ecf20Sopenharmony_ci	spin_unlock(&sb_lock);
3158c2ecf20Sopenharmony_ci}
3168c2ecf20Sopenharmony_ci
3178c2ecf20Sopenharmony_ci
3188c2ecf20Sopenharmony_ci/**
3198c2ecf20Sopenharmony_ci *	deactivate_locked_super	-	drop an active reference to superblock
3208c2ecf20Sopenharmony_ci *	@s: superblock to deactivate
3218c2ecf20Sopenharmony_ci *
3228c2ecf20Sopenharmony_ci *	Drops an active reference to superblock, converting it into a temporary
3238c2ecf20Sopenharmony_ci *	one if there is no other active references left.  In that case we
3248c2ecf20Sopenharmony_ci *	tell fs driver to shut it down and drop the temporary reference we
3258c2ecf20Sopenharmony_ci *	had just acquired.
3268c2ecf20Sopenharmony_ci *
3278c2ecf20Sopenharmony_ci *	Caller holds exclusive lock on superblock; that lock is released.
3288c2ecf20Sopenharmony_ci */
3298c2ecf20Sopenharmony_civoid deactivate_locked_super(struct super_block *s)
3308c2ecf20Sopenharmony_ci{
3318c2ecf20Sopenharmony_ci	struct file_system_type *fs = s->s_type;
3328c2ecf20Sopenharmony_ci	if (atomic_dec_and_test(&s->s_active)) {
3338c2ecf20Sopenharmony_ci		cleancache_invalidate_fs(s);
3348c2ecf20Sopenharmony_ci		unregister_shrinker(&s->s_shrink);
3358c2ecf20Sopenharmony_ci		fs->kill_sb(s);
3368c2ecf20Sopenharmony_ci
3378c2ecf20Sopenharmony_ci		/*
3388c2ecf20Sopenharmony_ci		 * Since list_lru_destroy() may sleep, we cannot call it from
3398c2ecf20Sopenharmony_ci		 * put_super(), where we hold the sb_lock. Therefore we destroy
3408c2ecf20Sopenharmony_ci		 * the lru lists right now.
3418c2ecf20Sopenharmony_ci		 */
3428c2ecf20Sopenharmony_ci		list_lru_destroy(&s->s_dentry_lru);
3438c2ecf20Sopenharmony_ci		list_lru_destroy(&s->s_inode_lru);
3448c2ecf20Sopenharmony_ci
3458c2ecf20Sopenharmony_ci		put_filesystem(fs);
3468c2ecf20Sopenharmony_ci		put_super(s);
3478c2ecf20Sopenharmony_ci	} else {
3488c2ecf20Sopenharmony_ci		up_write(&s->s_umount);
3498c2ecf20Sopenharmony_ci	}
3508c2ecf20Sopenharmony_ci}
3518c2ecf20Sopenharmony_ci
3528c2ecf20Sopenharmony_ciEXPORT_SYMBOL(deactivate_locked_super);
3538c2ecf20Sopenharmony_ci
3548c2ecf20Sopenharmony_ci/**
3558c2ecf20Sopenharmony_ci *	deactivate_super	-	drop an active reference to superblock
3568c2ecf20Sopenharmony_ci *	@s: superblock to deactivate
3578c2ecf20Sopenharmony_ci *
3588c2ecf20Sopenharmony_ci *	Variant of deactivate_locked_super(), except that superblock is *not*
3598c2ecf20Sopenharmony_ci *	locked by caller.  If we are going to drop the final active reference,
3608c2ecf20Sopenharmony_ci *	lock will be acquired prior to that.
3618c2ecf20Sopenharmony_ci */
3628c2ecf20Sopenharmony_civoid deactivate_super(struct super_block *s)
3638c2ecf20Sopenharmony_ci{
3648c2ecf20Sopenharmony_ci	if (!atomic_add_unless(&s->s_active, -1, 1)) {
3658c2ecf20Sopenharmony_ci		down_write(&s->s_umount);
3668c2ecf20Sopenharmony_ci		deactivate_locked_super(s);
3678c2ecf20Sopenharmony_ci	}
3688c2ecf20Sopenharmony_ci}
3698c2ecf20Sopenharmony_ci
3708c2ecf20Sopenharmony_ciEXPORT_SYMBOL(deactivate_super);
3718c2ecf20Sopenharmony_ci
3728c2ecf20Sopenharmony_ci/**
3738c2ecf20Sopenharmony_ci *	grab_super - acquire an active reference
3748c2ecf20Sopenharmony_ci *	@s: reference we are trying to make active
3758c2ecf20Sopenharmony_ci *
3768c2ecf20Sopenharmony_ci *	Tries to acquire an active reference.  grab_super() is used when we
3778c2ecf20Sopenharmony_ci * 	had just found a superblock in super_blocks or fs_type->fs_supers
3788c2ecf20Sopenharmony_ci *	and want to turn it into a full-blown active reference.  grab_super()
3798c2ecf20Sopenharmony_ci *	is called with sb_lock held and drops it.  Returns 1 in case of
3808c2ecf20Sopenharmony_ci *	success, 0 if we had failed (superblock contents was already dead or
3818c2ecf20Sopenharmony_ci *	dying when grab_super() had been called).  Note that this is only
3828c2ecf20Sopenharmony_ci *	called for superblocks not in rundown mode (== ones still on ->fs_supers
3838c2ecf20Sopenharmony_ci *	of their type), so increment of ->s_count is OK here.
3848c2ecf20Sopenharmony_ci */
3858c2ecf20Sopenharmony_cistatic int grab_super(struct super_block *s) __releases(sb_lock)
3868c2ecf20Sopenharmony_ci{
3878c2ecf20Sopenharmony_ci	s->s_count++;
3888c2ecf20Sopenharmony_ci	spin_unlock(&sb_lock);
3898c2ecf20Sopenharmony_ci	down_write(&s->s_umount);
3908c2ecf20Sopenharmony_ci	if ((s->s_flags & SB_BORN) && atomic_inc_not_zero(&s->s_active)) {
3918c2ecf20Sopenharmony_ci		put_super(s);
3928c2ecf20Sopenharmony_ci		return 1;
3938c2ecf20Sopenharmony_ci	}
3948c2ecf20Sopenharmony_ci	up_write(&s->s_umount);
3958c2ecf20Sopenharmony_ci	put_super(s);
3968c2ecf20Sopenharmony_ci	return 0;
3978c2ecf20Sopenharmony_ci}
3988c2ecf20Sopenharmony_ci
3998c2ecf20Sopenharmony_ci/*
4008c2ecf20Sopenharmony_ci *	trylock_super - try to grab ->s_umount shared
4018c2ecf20Sopenharmony_ci *	@sb: reference we are trying to grab
4028c2ecf20Sopenharmony_ci *
4038c2ecf20Sopenharmony_ci *	Try to prevent fs shutdown.  This is used in places where we
4048c2ecf20Sopenharmony_ci *	cannot take an active reference but we need to ensure that the
4058c2ecf20Sopenharmony_ci *	filesystem is not shut down while we are working on it. It returns
4068c2ecf20Sopenharmony_ci *	false if we cannot acquire s_umount or if we lose the race and
4078c2ecf20Sopenharmony_ci *	filesystem already got into shutdown, and returns true with the s_umount
4088c2ecf20Sopenharmony_ci *	lock held in read mode in case of success. On successful return,
4098c2ecf20Sopenharmony_ci *	the caller must drop the s_umount lock when done.
4108c2ecf20Sopenharmony_ci *
4118c2ecf20Sopenharmony_ci *	Note that unlike get_super() et.al. this one does *not* bump ->s_count.
4128c2ecf20Sopenharmony_ci *	The reason why it's safe is that we are OK with doing trylock instead
4138c2ecf20Sopenharmony_ci *	of down_read().  There's a couple of places that are OK with that, but
4148c2ecf20Sopenharmony_ci *	it's very much not a general-purpose interface.
4158c2ecf20Sopenharmony_ci */
4168c2ecf20Sopenharmony_cibool trylock_super(struct super_block *sb)
4178c2ecf20Sopenharmony_ci{
4188c2ecf20Sopenharmony_ci	if (down_read_trylock(&sb->s_umount)) {
4198c2ecf20Sopenharmony_ci		if (!hlist_unhashed(&sb->s_instances) &&
4208c2ecf20Sopenharmony_ci		    sb->s_root && (sb->s_flags & SB_BORN))
4218c2ecf20Sopenharmony_ci			return true;
4228c2ecf20Sopenharmony_ci		up_read(&sb->s_umount);
4238c2ecf20Sopenharmony_ci	}
4248c2ecf20Sopenharmony_ci
4258c2ecf20Sopenharmony_ci	return false;
4268c2ecf20Sopenharmony_ci}
4278c2ecf20Sopenharmony_ci
4288c2ecf20Sopenharmony_ci/**
4298c2ecf20Sopenharmony_ci *	generic_shutdown_super	-	common helper for ->kill_sb()
4308c2ecf20Sopenharmony_ci *	@sb: superblock to kill
4318c2ecf20Sopenharmony_ci *
4328c2ecf20Sopenharmony_ci *	generic_shutdown_super() does all fs-independent work on superblock
4338c2ecf20Sopenharmony_ci *	shutdown.  Typical ->kill_sb() should pick all fs-specific objects
4348c2ecf20Sopenharmony_ci *	that need destruction out of superblock, call generic_shutdown_super()
4358c2ecf20Sopenharmony_ci *	and release aforementioned objects.  Note: dentries and inodes _are_
4368c2ecf20Sopenharmony_ci *	taken care of and do not need specific handling.
4378c2ecf20Sopenharmony_ci *
4388c2ecf20Sopenharmony_ci *	Upon calling this function, the filesystem may no longer alter or
4398c2ecf20Sopenharmony_ci *	rearrange the set of dentries belonging to this super_block, nor may it
4408c2ecf20Sopenharmony_ci *	change the attachments of dentries to inodes.
4418c2ecf20Sopenharmony_ci */
4428c2ecf20Sopenharmony_civoid generic_shutdown_super(struct super_block *sb)
4438c2ecf20Sopenharmony_ci{
4448c2ecf20Sopenharmony_ci	const struct super_operations *sop = sb->s_op;
4458c2ecf20Sopenharmony_ci
4468c2ecf20Sopenharmony_ci	if (sb->s_root) {
4478c2ecf20Sopenharmony_ci		shrink_dcache_for_umount(sb);
4488c2ecf20Sopenharmony_ci		sync_filesystem(sb);
4498c2ecf20Sopenharmony_ci		sb->s_flags &= ~SB_ACTIVE;
4508c2ecf20Sopenharmony_ci
4518c2ecf20Sopenharmony_ci		cgroup_writeback_umount();
4528c2ecf20Sopenharmony_ci
4538c2ecf20Sopenharmony_ci		/* evict all inodes with zero refcount */
4548c2ecf20Sopenharmony_ci		evict_inodes(sb);
4558c2ecf20Sopenharmony_ci		/* only nonzero refcount inodes can have marks */
4568c2ecf20Sopenharmony_ci		fsnotify_sb_delete(sb);
4578c2ecf20Sopenharmony_ci		fscrypt_destroy_keyring(sb);
4588c2ecf20Sopenharmony_ci
4598c2ecf20Sopenharmony_ci		if (sb->s_dio_done_wq) {
4608c2ecf20Sopenharmony_ci			destroy_workqueue(sb->s_dio_done_wq);
4618c2ecf20Sopenharmony_ci			sb->s_dio_done_wq = NULL;
4628c2ecf20Sopenharmony_ci		}
4638c2ecf20Sopenharmony_ci
4648c2ecf20Sopenharmony_ci		if (sop->put_super)
4658c2ecf20Sopenharmony_ci			sop->put_super(sb);
4668c2ecf20Sopenharmony_ci
4678c2ecf20Sopenharmony_ci		if (!list_empty(&sb->s_inodes)) {
4688c2ecf20Sopenharmony_ci			printk("VFS: Busy inodes after unmount of %s. "
4698c2ecf20Sopenharmony_ci			   "Self-destruct in 5 seconds.  Have a nice day...\n",
4708c2ecf20Sopenharmony_ci			   sb->s_id);
4718c2ecf20Sopenharmony_ci		}
4728c2ecf20Sopenharmony_ci	}
4738c2ecf20Sopenharmony_ci	spin_lock(&sb_lock);
4748c2ecf20Sopenharmony_ci	/* should be initialized for __put_super_and_need_restart() */
4758c2ecf20Sopenharmony_ci	hlist_del_init(&sb->s_instances);
4768c2ecf20Sopenharmony_ci	spin_unlock(&sb_lock);
4778c2ecf20Sopenharmony_ci	up_write(&sb->s_umount);
4788c2ecf20Sopenharmony_ci	if (sb->s_bdi != &noop_backing_dev_info) {
4798c2ecf20Sopenharmony_ci		bdi_put(sb->s_bdi);
4808c2ecf20Sopenharmony_ci		sb->s_bdi = &noop_backing_dev_info;
4818c2ecf20Sopenharmony_ci	}
4828c2ecf20Sopenharmony_ci}
4838c2ecf20Sopenharmony_ci
4848c2ecf20Sopenharmony_ciEXPORT_SYMBOL(generic_shutdown_super);
4858c2ecf20Sopenharmony_ci
4868c2ecf20Sopenharmony_cibool mount_capable(struct fs_context *fc)
4878c2ecf20Sopenharmony_ci{
4888c2ecf20Sopenharmony_ci	if (!(fc->fs_type->fs_flags & FS_USERNS_MOUNT))
4898c2ecf20Sopenharmony_ci		return capable(CAP_SYS_ADMIN);
4908c2ecf20Sopenharmony_ci	else
4918c2ecf20Sopenharmony_ci		return ns_capable(fc->user_ns, CAP_SYS_ADMIN);
4928c2ecf20Sopenharmony_ci}
4938c2ecf20Sopenharmony_ci
4948c2ecf20Sopenharmony_ci/**
4958c2ecf20Sopenharmony_ci * sget_fc - Find or create a superblock
4968c2ecf20Sopenharmony_ci * @fc:	Filesystem context.
4978c2ecf20Sopenharmony_ci * @test: Comparison callback
4988c2ecf20Sopenharmony_ci * @set: Setup callback
4998c2ecf20Sopenharmony_ci *
5008c2ecf20Sopenharmony_ci * Find or create a superblock using the parameters stored in the filesystem
5018c2ecf20Sopenharmony_ci * context and the two callback functions.
5028c2ecf20Sopenharmony_ci *
5038c2ecf20Sopenharmony_ci * If an extant superblock is matched, then that will be returned with an
5048c2ecf20Sopenharmony_ci * elevated reference count that the caller must transfer or discard.
5058c2ecf20Sopenharmony_ci *
5068c2ecf20Sopenharmony_ci * If no match is made, a new superblock will be allocated and basic
5078c2ecf20Sopenharmony_ci * initialisation will be performed (s_type, s_fs_info and s_id will be set and
5088c2ecf20Sopenharmony_ci * the set() callback will be invoked), the superblock will be published and it
5098c2ecf20Sopenharmony_ci * will be returned in a partially constructed state with SB_BORN and SB_ACTIVE
5108c2ecf20Sopenharmony_ci * as yet unset.
5118c2ecf20Sopenharmony_ci */
5128c2ecf20Sopenharmony_cistruct super_block *sget_fc(struct fs_context *fc,
5138c2ecf20Sopenharmony_ci			    int (*test)(struct super_block *, struct fs_context *),
5148c2ecf20Sopenharmony_ci			    int (*set)(struct super_block *, struct fs_context *))
5158c2ecf20Sopenharmony_ci{
5168c2ecf20Sopenharmony_ci	struct super_block *s = NULL;
5178c2ecf20Sopenharmony_ci	struct super_block *old;
5188c2ecf20Sopenharmony_ci	struct user_namespace *user_ns = fc->global ? &init_user_ns : fc->user_ns;
5198c2ecf20Sopenharmony_ci	int err;
5208c2ecf20Sopenharmony_ci
5218c2ecf20Sopenharmony_ciretry:
5228c2ecf20Sopenharmony_ci	spin_lock(&sb_lock);
5238c2ecf20Sopenharmony_ci	if (test) {
5248c2ecf20Sopenharmony_ci		hlist_for_each_entry(old, &fc->fs_type->fs_supers, s_instances) {
5258c2ecf20Sopenharmony_ci			if (test(old, fc))
5268c2ecf20Sopenharmony_ci				goto share_extant_sb;
5278c2ecf20Sopenharmony_ci		}
5288c2ecf20Sopenharmony_ci	}
5298c2ecf20Sopenharmony_ci	if (!s) {
5308c2ecf20Sopenharmony_ci		spin_unlock(&sb_lock);
5318c2ecf20Sopenharmony_ci		s = alloc_super(fc->fs_type, fc->sb_flags, user_ns);
5328c2ecf20Sopenharmony_ci		if (!s)
5338c2ecf20Sopenharmony_ci			return ERR_PTR(-ENOMEM);
5348c2ecf20Sopenharmony_ci		goto retry;
5358c2ecf20Sopenharmony_ci	}
5368c2ecf20Sopenharmony_ci
5378c2ecf20Sopenharmony_ci	s->s_fs_info = fc->s_fs_info;
5388c2ecf20Sopenharmony_ci	err = set(s, fc);
5398c2ecf20Sopenharmony_ci	if (err) {
5408c2ecf20Sopenharmony_ci		s->s_fs_info = NULL;
5418c2ecf20Sopenharmony_ci		spin_unlock(&sb_lock);
5428c2ecf20Sopenharmony_ci		destroy_unused_super(s);
5438c2ecf20Sopenharmony_ci		return ERR_PTR(err);
5448c2ecf20Sopenharmony_ci	}
5458c2ecf20Sopenharmony_ci	fc->s_fs_info = NULL;
5468c2ecf20Sopenharmony_ci	s->s_type = fc->fs_type;
5478c2ecf20Sopenharmony_ci	s->s_iflags |= fc->s_iflags;
5488c2ecf20Sopenharmony_ci	strlcpy(s->s_id, s->s_type->name, sizeof(s->s_id));
5498c2ecf20Sopenharmony_ci	list_add_tail(&s->s_list, &super_blocks);
5508c2ecf20Sopenharmony_ci	hlist_add_head(&s->s_instances, &s->s_type->fs_supers);
5518c2ecf20Sopenharmony_ci	spin_unlock(&sb_lock);
5528c2ecf20Sopenharmony_ci	get_filesystem(s->s_type);
5538c2ecf20Sopenharmony_ci	register_shrinker_prepared(&s->s_shrink);
5548c2ecf20Sopenharmony_ci	return s;
5558c2ecf20Sopenharmony_ci
5568c2ecf20Sopenharmony_cishare_extant_sb:
5578c2ecf20Sopenharmony_ci	if (user_ns != old->s_user_ns) {
5588c2ecf20Sopenharmony_ci		spin_unlock(&sb_lock);
5598c2ecf20Sopenharmony_ci		destroy_unused_super(s);
5608c2ecf20Sopenharmony_ci		return ERR_PTR(-EBUSY);
5618c2ecf20Sopenharmony_ci	}
5628c2ecf20Sopenharmony_ci	if (!grab_super(old))
5638c2ecf20Sopenharmony_ci		goto retry;
5648c2ecf20Sopenharmony_ci	destroy_unused_super(s);
5658c2ecf20Sopenharmony_ci	return old;
5668c2ecf20Sopenharmony_ci}
5678c2ecf20Sopenharmony_ciEXPORT_SYMBOL(sget_fc);
5688c2ecf20Sopenharmony_ci
5698c2ecf20Sopenharmony_ci/**
5708c2ecf20Sopenharmony_ci *	sget	-	find or create a superblock
5718c2ecf20Sopenharmony_ci *	@type:	  filesystem type superblock should belong to
5728c2ecf20Sopenharmony_ci *	@test:	  comparison callback
5738c2ecf20Sopenharmony_ci *	@set:	  setup callback
5748c2ecf20Sopenharmony_ci *	@flags:	  mount flags
5758c2ecf20Sopenharmony_ci *	@data:	  argument to each of them
5768c2ecf20Sopenharmony_ci */
5778c2ecf20Sopenharmony_cistruct super_block *sget(struct file_system_type *type,
5788c2ecf20Sopenharmony_ci			int (*test)(struct super_block *,void *),
5798c2ecf20Sopenharmony_ci			int (*set)(struct super_block *,void *),
5808c2ecf20Sopenharmony_ci			int flags,
5818c2ecf20Sopenharmony_ci			void *data)
5828c2ecf20Sopenharmony_ci{
5838c2ecf20Sopenharmony_ci	struct user_namespace *user_ns = current_user_ns();
5848c2ecf20Sopenharmony_ci	struct super_block *s = NULL;
5858c2ecf20Sopenharmony_ci	struct super_block *old;
5868c2ecf20Sopenharmony_ci	int err;
5878c2ecf20Sopenharmony_ci
5888c2ecf20Sopenharmony_ci	/* We don't yet pass the user namespace of the parent
5898c2ecf20Sopenharmony_ci	 * mount through to here so always use &init_user_ns
5908c2ecf20Sopenharmony_ci	 * until that changes.
5918c2ecf20Sopenharmony_ci	 */
5928c2ecf20Sopenharmony_ci	if (flags & SB_SUBMOUNT)
5938c2ecf20Sopenharmony_ci		user_ns = &init_user_ns;
5948c2ecf20Sopenharmony_ci
5958c2ecf20Sopenharmony_ciretry:
5968c2ecf20Sopenharmony_ci	spin_lock(&sb_lock);
5978c2ecf20Sopenharmony_ci	if (test) {
5988c2ecf20Sopenharmony_ci		hlist_for_each_entry(old, &type->fs_supers, s_instances) {
5998c2ecf20Sopenharmony_ci			if (!test(old, data))
6008c2ecf20Sopenharmony_ci				continue;
6018c2ecf20Sopenharmony_ci			if (user_ns != old->s_user_ns) {
6028c2ecf20Sopenharmony_ci				spin_unlock(&sb_lock);
6038c2ecf20Sopenharmony_ci				destroy_unused_super(s);
6048c2ecf20Sopenharmony_ci				return ERR_PTR(-EBUSY);
6058c2ecf20Sopenharmony_ci			}
6068c2ecf20Sopenharmony_ci			if (!grab_super(old))
6078c2ecf20Sopenharmony_ci				goto retry;
6088c2ecf20Sopenharmony_ci			destroy_unused_super(s);
6098c2ecf20Sopenharmony_ci			return old;
6108c2ecf20Sopenharmony_ci		}
6118c2ecf20Sopenharmony_ci	}
6128c2ecf20Sopenharmony_ci	if (!s) {
6138c2ecf20Sopenharmony_ci		spin_unlock(&sb_lock);
6148c2ecf20Sopenharmony_ci		s = alloc_super(type, (flags & ~SB_SUBMOUNT), user_ns);
6158c2ecf20Sopenharmony_ci		if (!s)
6168c2ecf20Sopenharmony_ci			return ERR_PTR(-ENOMEM);
6178c2ecf20Sopenharmony_ci		goto retry;
6188c2ecf20Sopenharmony_ci	}
6198c2ecf20Sopenharmony_ci
6208c2ecf20Sopenharmony_ci	err = set(s, data);
6218c2ecf20Sopenharmony_ci	if (err) {
6228c2ecf20Sopenharmony_ci		spin_unlock(&sb_lock);
6238c2ecf20Sopenharmony_ci		destroy_unused_super(s);
6248c2ecf20Sopenharmony_ci		return ERR_PTR(err);
6258c2ecf20Sopenharmony_ci	}
6268c2ecf20Sopenharmony_ci	s->s_type = type;
6278c2ecf20Sopenharmony_ci	strlcpy(s->s_id, type->name, sizeof(s->s_id));
6288c2ecf20Sopenharmony_ci	list_add_tail(&s->s_list, &super_blocks);
6298c2ecf20Sopenharmony_ci	hlist_add_head(&s->s_instances, &type->fs_supers);
6308c2ecf20Sopenharmony_ci	spin_unlock(&sb_lock);
6318c2ecf20Sopenharmony_ci	get_filesystem(type);
6328c2ecf20Sopenharmony_ci	register_shrinker_prepared(&s->s_shrink);
6338c2ecf20Sopenharmony_ci	return s;
6348c2ecf20Sopenharmony_ci}
6358c2ecf20Sopenharmony_ciEXPORT_SYMBOL(sget);
6368c2ecf20Sopenharmony_ci
6378c2ecf20Sopenharmony_civoid drop_super(struct super_block *sb)
6388c2ecf20Sopenharmony_ci{
6398c2ecf20Sopenharmony_ci	up_read(&sb->s_umount);
6408c2ecf20Sopenharmony_ci	put_super(sb);
6418c2ecf20Sopenharmony_ci}
6428c2ecf20Sopenharmony_ci
6438c2ecf20Sopenharmony_ciEXPORT_SYMBOL(drop_super);
6448c2ecf20Sopenharmony_ci
6458c2ecf20Sopenharmony_civoid drop_super_exclusive(struct super_block *sb)
6468c2ecf20Sopenharmony_ci{
6478c2ecf20Sopenharmony_ci	up_write(&sb->s_umount);
6488c2ecf20Sopenharmony_ci	put_super(sb);
6498c2ecf20Sopenharmony_ci}
6508c2ecf20Sopenharmony_ciEXPORT_SYMBOL(drop_super_exclusive);
6518c2ecf20Sopenharmony_ci
6528c2ecf20Sopenharmony_cistatic void __iterate_supers(void (*f)(struct super_block *))
6538c2ecf20Sopenharmony_ci{
6548c2ecf20Sopenharmony_ci	struct super_block *sb, *p = NULL;
6558c2ecf20Sopenharmony_ci
6568c2ecf20Sopenharmony_ci	spin_lock(&sb_lock);
6578c2ecf20Sopenharmony_ci	list_for_each_entry(sb, &super_blocks, s_list) {
6588c2ecf20Sopenharmony_ci		if (hlist_unhashed(&sb->s_instances))
6598c2ecf20Sopenharmony_ci			continue;
6608c2ecf20Sopenharmony_ci		sb->s_count++;
6618c2ecf20Sopenharmony_ci		spin_unlock(&sb_lock);
6628c2ecf20Sopenharmony_ci
6638c2ecf20Sopenharmony_ci		f(sb);
6648c2ecf20Sopenharmony_ci
6658c2ecf20Sopenharmony_ci		spin_lock(&sb_lock);
6668c2ecf20Sopenharmony_ci		if (p)
6678c2ecf20Sopenharmony_ci			__put_super(p);
6688c2ecf20Sopenharmony_ci		p = sb;
6698c2ecf20Sopenharmony_ci	}
6708c2ecf20Sopenharmony_ci	if (p)
6718c2ecf20Sopenharmony_ci		__put_super(p);
6728c2ecf20Sopenharmony_ci	spin_unlock(&sb_lock);
6738c2ecf20Sopenharmony_ci}
6748c2ecf20Sopenharmony_ci/**
6758c2ecf20Sopenharmony_ci *	iterate_supers - call function for all active superblocks
6768c2ecf20Sopenharmony_ci *	@f: function to call
6778c2ecf20Sopenharmony_ci *	@arg: argument to pass to it
6788c2ecf20Sopenharmony_ci *
6798c2ecf20Sopenharmony_ci *	Scans the superblock list and calls given function, passing it
6808c2ecf20Sopenharmony_ci *	locked superblock and given argument.
6818c2ecf20Sopenharmony_ci */
6828c2ecf20Sopenharmony_civoid iterate_supers(void (*f)(struct super_block *, void *), void *arg)
6838c2ecf20Sopenharmony_ci{
6848c2ecf20Sopenharmony_ci	struct super_block *sb, *p = NULL;
6858c2ecf20Sopenharmony_ci
6868c2ecf20Sopenharmony_ci	spin_lock(&sb_lock);
6878c2ecf20Sopenharmony_ci	list_for_each_entry(sb, &super_blocks, s_list) {
6888c2ecf20Sopenharmony_ci		if (hlist_unhashed(&sb->s_instances))
6898c2ecf20Sopenharmony_ci			continue;
6908c2ecf20Sopenharmony_ci		sb->s_count++;
6918c2ecf20Sopenharmony_ci		spin_unlock(&sb_lock);
6928c2ecf20Sopenharmony_ci
6938c2ecf20Sopenharmony_ci		down_read(&sb->s_umount);
6948c2ecf20Sopenharmony_ci		if (sb->s_root && (sb->s_flags & SB_BORN))
6958c2ecf20Sopenharmony_ci			f(sb, arg);
6968c2ecf20Sopenharmony_ci		up_read(&sb->s_umount);
6978c2ecf20Sopenharmony_ci
6988c2ecf20Sopenharmony_ci		spin_lock(&sb_lock);
6998c2ecf20Sopenharmony_ci		if (p)
7008c2ecf20Sopenharmony_ci			__put_super(p);
7018c2ecf20Sopenharmony_ci		p = sb;
7028c2ecf20Sopenharmony_ci	}
7038c2ecf20Sopenharmony_ci	if (p)
7048c2ecf20Sopenharmony_ci		__put_super(p);
7058c2ecf20Sopenharmony_ci	spin_unlock(&sb_lock);
7068c2ecf20Sopenharmony_ci}
7078c2ecf20Sopenharmony_ci
7088c2ecf20Sopenharmony_ci/**
7098c2ecf20Sopenharmony_ci *	iterate_supers_type - call function for superblocks of given type
7108c2ecf20Sopenharmony_ci *	@type: fs type
7118c2ecf20Sopenharmony_ci *	@f: function to call
7128c2ecf20Sopenharmony_ci *	@arg: argument to pass to it
7138c2ecf20Sopenharmony_ci *
7148c2ecf20Sopenharmony_ci *	Scans the superblock list and calls given function, passing it
7158c2ecf20Sopenharmony_ci *	locked superblock and given argument.
7168c2ecf20Sopenharmony_ci */
7178c2ecf20Sopenharmony_civoid iterate_supers_type(struct file_system_type *type,
7188c2ecf20Sopenharmony_ci	void (*f)(struct super_block *, void *), void *arg)
7198c2ecf20Sopenharmony_ci{
7208c2ecf20Sopenharmony_ci	struct super_block *sb, *p = NULL;
7218c2ecf20Sopenharmony_ci
7228c2ecf20Sopenharmony_ci	spin_lock(&sb_lock);
7238c2ecf20Sopenharmony_ci	hlist_for_each_entry(sb, &type->fs_supers, s_instances) {
7248c2ecf20Sopenharmony_ci		sb->s_count++;
7258c2ecf20Sopenharmony_ci		spin_unlock(&sb_lock);
7268c2ecf20Sopenharmony_ci
7278c2ecf20Sopenharmony_ci		down_read(&sb->s_umount);
7288c2ecf20Sopenharmony_ci		if (sb->s_root && (sb->s_flags & SB_BORN))
7298c2ecf20Sopenharmony_ci			f(sb, arg);
7308c2ecf20Sopenharmony_ci		up_read(&sb->s_umount);
7318c2ecf20Sopenharmony_ci
7328c2ecf20Sopenharmony_ci		spin_lock(&sb_lock);
7338c2ecf20Sopenharmony_ci		if (p)
7348c2ecf20Sopenharmony_ci			__put_super(p);
7358c2ecf20Sopenharmony_ci		p = sb;
7368c2ecf20Sopenharmony_ci	}
7378c2ecf20Sopenharmony_ci	if (p)
7388c2ecf20Sopenharmony_ci		__put_super(p);
7398c2ecf20Sopenharmony_ci	spin_unlock(&sb_lock);
7408c2ecf20Sopenharmony_ci}
7418c2ecf20Sopenharmony_ci
7428c2ecf20Sopenharmony_ciEXPORT_SYMBOL(iterate_supers_type);
7438c2ecf20Sopenharmony_ci
7448c2ecf20Sopenharmony_cistatic struct super_block *__get_super(struct block_device *bdev, bool excl)
7458c2ecf20Sopenharmony_ci{
7468c2ecf20Sopenharmony_ci	struct super_block *sb;
7478c2ecf20Sopenharmony_ci
7488c2ecf20Sopenharmony_ci	if (!bdev)
7498c2ecf20Sopenharmony_ci		return NULL;
7508c2ecf20Sopenharmony_ci
7518c2ecf20Sopenharmony_ci	spin_lock(&sb_lock);
7528c2ecf20Sopenharmony_cirescan:
7538c2ecf20Sopenharmony_ci	list_for_each_entry(sb, &super_blocks, s_list) {
7548c2ecf20Sopenharmony_ci		if (hlist_unhashed(&sb->s_instances))
7558c2ecf20Sopenharmony_ci			continue;
7568c2ecf20Sopenharmony_ci		if (sb->s_bdev == bdev) {
7578c2ecf20Sopenharmony_ci			sb->s_count++;
7588c2ecf20Sopenharmony_ci			spin_unlock(&sb_lock);
7598c2ecf20Sopenharmony_ci			if (!excl)
7608c2ecf20Sopenharmony_ci				down_read(&sb->s_umount);
7618c2ecf20Sopenharmony_ci			else
7628c2ecf20Sopenharmony_ci				down_write(&sb->s_umount);
7638c2ecf20Sopenharmony_ci			/* still alive? */
7648c2ecf20Sopenharmony_ci			if (sb->s_root && (sb->s_flags & SB_BORN))
7658c2ecf20Sopenharmony_ci				return sb;
7668c2ecf20Sopenharmony_ci			if (!excl)
7678c2ecf20Sopenharmony_ci				up_read(&sb->s_umount);
7688c2ecf20Sopenharmony_ci			else
7698c2ecf20Sopenharmony_ci				up_write(&sb->s_umount);
7708c2ecf20Sopenharmony_ci			/* nope, got unmounted */
7718c2ecf20Sopenharmony_ci			spin_lock(&sb_lock);
7728c2ecf20Sopenharmony_ci			__put_super(sb);
7738c2ecf20Sopenharmony_ci			goto rescan;
7748c2ecf20Sopenharmony_ci		}
7758c2ecf20Sopenharmony_ci	}
7768c2ecf20Sopenharmony_ci	spin_unlock(&sb_lock);
7778c2ecf20Sopenharmony_ci	return NULL;
7788c2ecf20Sopenharmony_ci}
7798c2ecf20Sopenharmony_ci
7808c2ecf20Sopenharmony_ci/**
7818c2ecf20Sopenharmony_ci *	get_super - get the superblock of a device
7828c2ecf20Sopenharmony_ci *	@bdev: device to get the superblock for
7838c2ecf20Sopenharmony_ci *
7848c2ecf20Sopenharmony_ci *	Scans the superblock list and finds the superblock of the file system
7858c2ecf20Sopenharmony_ci *	mounted on the device given. %NULL is returned if no match is found.
7868c2ecf20Sopenharmony_ci */
7878c2ecf20Sopenharmony_cistruct super_block *get_super(struct block_device *bdev)
7888c2ecf20Sopenharmony_ci{
7898c2ecf20Sopenharmony_ci	return __get_super(bdev, false);
7908c2ecf20Sopenharmony_ci}
7918c2ecf20Sopenharmony_ciEXPORT_SYMBOL(get_super);
7928c2ecf20Sopenharmony_ci
7938c2ecf20Sopenharmony_cistatic struct super_block *__get_super_thawed(struct block_device *bdev,
7948c2ecf20Sopenharmony_ci					      bool excl)
7958c2ecf20Sopenharmony_ci{
7968c2ecf20Sopenharmony_ci	while (1) {
7978c2ecf20Sopenharmony_ci		struct super_block *s = __get_super(bdev, excl);
7988c2ecf20Sopenharmony_ci		if (!s || s->s_writers.frozen == SB_UNFROZEN)
7998c2ecf20Sopenharmony_ci			return s;
8008c2ecf20Sopenharmony_ci		if (!excl)
8018c2ecf20Sopenharmony_ci			up_read(&s->s_umount);
8028c2ecf20Sopenharmony_ci		else
8038c2ecf20Sopenharmony_ci			up_write(&s->s_umount);
8048c2ecf20Sopenharmony_ci		wait_event(s->s_writers.wait_unfrozen,
8058c2ecf20Sopenharmony_ci			   s->s_writers.frozen == SB_UNFROZEN);
8068c2ecf20Sopenharmony_ci		put_super(s);
8078c2ecf20Sopenharmony_ci	}
8088c2ecf20Sopenharmony_ci}
8098c2ecf20Sopenharmony_ci
8108c2ecf20Sopenharmony_ci/**
8118c2ecf20Sopenharmony_ci *	get_super_thawed - get thawed superblock of a device
8128c2ecf20Sopenharmony_ci *	@bdev: device to get the superblock for
8138c2ecf20Sopenharmony_ci *
8148c2ecf20Sopenharmony_ci *	Scans the superblock list and finds the superblock of the file system
8158c2ecf20Sopenharmony_ci *	mounted on the device. The superblock is returned once it is thawed
8168c2ecf20Sopenharmony_ci *	(or immediately if it was not frozen). %NULL is returned if no match
8178c2ecf20Sopenharmony_ci *	is found.
8188c2ecf20Sopenharmony_ci */
8198c2ecf20Sopenharmony_cistruct super_block *get_super_thawed(struct block_device *bdev)
8208c2ecf20Sopenharmony_ci{
8218c2ecf20Sopenharmony_ci	return __get_super_thawed(bdev, false);
8228c2ecf20Sopenharmony_ci}
8238c2ecf20Sopenharmony_ciEXPORT_SYMBOL(get_super_thawed);
8248c2ecf20Sopenharmony_ci
8258c2ecf20Sopenharmony_ci/**
8268c2ecf20Sopenharmony_ci *	get_super_exclusive_thawed - get thawed superblock of a device
8278c2ecf20Sopenharmony_ci *	@bdev: device to get the superblock for
8288c2ecf20Sopenharmony_ci *
8298c2ecf20Sopenharmony_ci *	Scans the superblock list and finds the superblock of the file system
8308c2ecf20Sopenharmony_ci *	mounted on the device. The superblock is returned once it is thawed
8318c2ecf20Sopenharmony_ci *	(or immediately if it was not frozen) and s_umount semaphore is held
8328c2ecf20Sopenharmony_ci *	in exclusive mode. %NULL is returned if no match is found.
8338c2ecf20Sopenharmony_ci */
8348c2ecf20Sopenharmony_cistruct super_block *get_super_exclusive_thawed(struct block_device *bdev)
8358c2ecf20Sopenharmony_ci{
8368c2ecf20Sopenharmony_ci	return __get_super_thawed(bdev, true);
8378c2ecf20Sopenharmony_ci}
8388c2ecf20Sopenharmony_ciEXPORT_SYMBOL(get_super_exclusive_thawed);
8398c2ecf20Sopenharmony_ci
8408c2ecf20Sopenharmony_ci/**
8418c2ecf20Sopenharmony_ci * get_active_super - get an active reference to the superblock of a device
8428c2ecf20Sopenharmony_ci * @bdev: device to get the superblock for
8438c2ecf20Sopenharmony_ci *
8448c2ecf20Sopenharmony_ci * Scans the superblock list and finds the superblock of the file system
8458c2ecf20Sopenharmony_ci * mounted on the device given.  Returns the superblock with an active
8468c2ecf20Sopenharmony_ci * reference or %NULL if none was found.
8478c2ecf20Sopenharmony_ci */
8488c2ecf20Sopenharmony_cistruct super_block *get_active_super(struct block_device *bdev)
8498c2ecf20Sopenharmony_ci{
8508c2ecf20Sopenharmony_ci	struct super_block *sb;
8518c2ecf20Sopenharmony_ci
8528c2ecf20Sopenharmony_ci	if (!bdev)
8538c2ecf20Sopenharmony_ci		return NULL;
8548c2ecf20Sopenharmony_ci
8558c2ecf20Sopenharmony_cirestart:
8568c2ecf20Sopenharmony_ci	spin_lock(&sb_lock);
8578c2ecf20Sopenharmony_ci	list_for_each_entry(sb, &super_blocks, s_list) {
8588c2ecf20Sopenharmony_ci		if (hlist_unhashed(&sb->s_instances))
8598c2ecf20Sopenharmony_ci			continue;
8608c2ecf20Sopenharmony_ci		if (sb->s_bdev == bdev) {
8618c2ecf20Sopenharmony_ci			if (!grab_super(sb))
8628c2ecf20Sopenharmony_ci				goto restart;
8638c2ecf20Sopenharmony_ci			up_write(&sb->s_umount);
8648c2ecf20Sopenharmony_ci			return sb;
8658c2ecf20Sopenharmony_ci		}
8668c2ecf20Sopenharmony_ci	}
8678c2ecf20Sopenharmony_ci	spin_unlock(&sb_lock);
8688c2ecf20Sopenharmony_ci	return NULL;
8698c2ecf20Sopenharmony_ci}
8708c2ecf20Sopenharmony_ci
8718c2ecf20Sopenharmony_cistruct super_block *user_get_super(dev_t dev)
8728c2ecf20Sopenharmony_ci{
8738c2ecf20Sopenharmony_ci	struct super_block *sb;
8748c2ecf20Sopenharmony_ci
8758c2ecf20Sopenharmony_ci	spin_lock(&sb_lock);
8768c2ecf20Sopenharmony_cirescan:
8778c2ecf20Sopenharmony_ci	list_for_each_entry(sb, &super_blocks, s_list) {
8788c2ecf20Sopenharmony_ci		if (hlist_unhashed(&sb->s_instances))
8798c2ecf20Sopenharmony_ci			continue;
8808c2ecf20Sopenharmony_ci		if (sb->s_dev ==  dev) {
8818c2ecf20Sopenharmony_ci			sb->s_count++;
8828c2ecf20Sopenharmony_ci			spin_unlock(&sb_lock);
8838c2ecf20Sopenharmony_ci			down_read(&sb->s_umount);
8848c2ecf20Sopenharmony_ci			/* still alive? */
8858c2ecf20Sopenharmony_ci			if (sb->s_root && (sb->s_flags & SB_BORN))
8868c2ecf20Sopenharmony_ci				return sb;
8878c2ecf20Sopenharmony_ci			up_read(&sb->s_umount);
8888c2ecf20Sopenharmony_ci			/* nope, got unmounted */
8898c2ecf20Sopenharmony_ci			spin_lock(&sb_lock);
8908c2ecf20Sopenharmony_ci			__put_super(sb);
8918c2ecf20Sopenharmony_ci			goto rescan;
8928c2ecf20Sopenharmony_ci		}
8938c2ecf20Sopenharmony_ci	}
8948c2ecf20Sopenharmony_ci	spin_unlock(&sb_lock);
8958c2ecf20Sopenharmony_ci	return NULL;
8968c2ecf20Sopenharmony_ci}
8978c2ecf20Sopenharmony_ci
8988c2ecf20Sopenharmony_ci/**
8998c2ecf20Sopenharmony_ci * reconfigure_super - asks filesystem to change superblock parameters
9008c2ecf20Sopenharmony_ci * @fc: The superblock and configuration
9018c2ecf20Sopenharmony_ci *
9028c2ecf20Sopenharmony_ci * Alters the configuration parameters of a live superblock.
9038c2ecf20Sopenharmony_ci */
9048c2ecf20Sopenharmony_ciint reconfigure_super(struct fs_context *fc)
9058c2ecf20Sopenharmony_ci{
9068c2ecf20Sopenharmony_ci	struct super_block *sb = fc->root->d_sb;
9078c2ecf20Sopenharmony_ci	int retval;
9088c2ecf20Sopenharmony_ci	bool remount_ro = false;
9098c2ecf20Sopenharmony_ci	bool remount_rw = false;
9108c2ecf20Sopenharmony_ci	bool force = fc->sb_flags & SB_FORCE;
9118c2ecf20Sopenharmony_ci
9128c2ecf20Sopenharmony_ci	if (fc->sb_flags_mask & ~MS_RMT_MASK)
9138c2ecf20Sopenharmony_ci		return -EINVAL;
9148c2ecf20Sopenharmony_ci	if (sb->s_writers.frozen != SB_UNFROZEN)
9158c2ecf20Sopenharmony_ci		return -EBUSY;
9168c2ecf20Sopenharmony_ci
9178c2ecf20Sopenharmony_ci	retval = security_sb_remount(sb, fc->security);
9188c2ecf20Sopenharmony_ci	if (retval)
9198c2ecf20Sopenharmony_ci		return retval;
9208c2ecf20Sopenharmony_ci
9218c2ecf20Sopenharmony_ci	if (fc->sb_flags_mask & SB_RDONLY) {
9228c2ecf20Sopenharmony_ci#ifdef CONFIG_BLOCK
9238c2ecf20Sopenharmony_ci		if (!(fc->sb_flags & SB_RDONLY) && bdev_read_only(sb->s_bdev))
9248c2ecf20Sopenharmony_ci			return -EACCES;
9258c2ecf20Sopenharmony_ci#endif
9268c2ecf20Sopenharmony_ci		remount_rw = !(fc->sb_flags & SB_RDONLY) && sb_rdonly(sb);
9278c2ecf20Sopenharmony_ci		remount_ro = (fc->sb_flags & SB_RDONLY) && !sb_rdonly(sb);
9288c2ecf20Sopenharmony_ci	}
9298c2ecf20Sopenharmony_ci
9308c2ecf20Sopenharmony_ci	if (remount_ro) {
9318c2ecf20Sopenharmony_ci		if (!hlist_empty(&sb->s_pins)) {
9328c2ecf20Sopenharmony_ci			up_write(&sb->s_umount);
9338c2ecf20Sopenharmony_ci			group_pin_kill(&sb->s_pins);
9348c2ecf20Sopenharmony_ci			down_write(&sb->s_umount);
9358c2ecf20Sopenharmony_ci			if (!sb->s_root)
9368c2ecf20Sopenharmony_ci				return 0;
9378c2ecf20Sopenharmony_ci			if (sb->s_writers.frozen != SB_UNFROZEN)
9388c2ecf20Sopenharmony_ci				return -EBUSY;
9398c2ecf20Sopenharmony_ci			remount_ro = !sb_rdonly(sb);
9408c2ecf20Sopenharmony_ci		}
9418c2ecf20Sopenharmony_ci	}
9428c2ecf20Sopenharmony_ci	shrink_dcache_sb(sb);
9438c2ecf20Sopenharmony_ci
9448c2ecf20Sopenharmony_ci	/* If we are reconfiguring to RDONLY and current sb is read/write,
9458c2ecf20Sopenharmony_ci	 * make sure there are no files open for writing.
9468c2ecf20Sopenharmony_ci	 */
9478c2ecf20Sopenharmony_ci	if (remount_ro) {
9488c2ecf20Sopenharmony_ci		if (force) {
9498c2ecf20Sopenharmony_ci			sb->s_readonly_remount = 1;
9508c2ecf20Sopenharmony_ci			smp_wmb();
9518c2ecf20Sopenharmony_ci		} else {
9528c2ecf20Sopenharmony_ci			retval = sb_prepare_remount_readonly(sb);
9538c2ecf20Sopenharmony_ci			if (retval)
9548c2ecf20Sopenharmony_ci				return retval;
9558c2ecf20Sopenharmony_ci		}
9568c2ecf20Sopenharmony_ci	} else if (remount_rw) {
9578c2ecf20Sopenharmony_ci		/*
9588c2ecf20Sopenharmony_ci		 * We set s_readonly_remount here to protect filesystem's
9598c2ecf20Sopenharmony_ci		 * reconfigure code from writes from userspace until
9608c2ecf20Sopenharmony_ci		 * reconfigure finishes.
9618c2ecf20Sopenharmony_ci		 */
9628c2ecf20Sopenharmony_ci		sb->s_readonly_remount = 1;
9638c2ecf20Sopenharmony_ci		smp_wmb();
9648c2ecf20Sopenharmony_ci	}
9658c2ecf20Sopenharmony_ci
9668c2ecf20Sopenharmony_ci	if (fc->ops->reconfigure) {
9678c2ecf20Sopenharmony_ci		retval = fc->ops->reconfigure(fc);
9688c2ecf20Sopenharmony_ci		if (retval) {
9698c2ecf20Sopenharmony_ci			if (!force)
9708c2ecf20Sopenharmony_ci				goto cancel_readonly;
9718c2ecf20Sopenharmony_ci			/* If forced remount, go ahead despite any errors */
9728c2ecf20Sopenharmony_ci			WARN(1, "forced remount of a %s fs returned %i\n",
9738c2ecf20Sopenharmony_ci			     sb->s_type->name, retval);
9748c2ecf20Sopenharmony_ci		}
9758c2ecf20Sopenharmony_ci	}
9768c2ecf20Sopenharmony_ci
9778c2ecf20Sopenharmony_ci	WRITE_ONCE(sb->s_flags, ((sb->s_flags & ~fc->sb_flags_mask) |
9788c2ecf20Sopenharmony_ci				 (fc->sb_flags & fc->sb_flags_mask)));
9798c2ecf20Sopenharmony_ci	/* Needs to be ordered wrt mnt_is_readonly() */
9808c2ecf20Sopenharmony_ci	smp_wmb();
9818c2ecf20Sopenharmony_ci	sb->s_readonly_remount = 0;
9828c2ecf20Sopenharmony_ci
9838c2ecf20Sopenharmony_ci	/*
9848c2ecf20Sopenharmony_ci	 * Some filesystems modify their metadata via some other path than the
9858c2ecf20Sopenharmony_ci	 * bdev buffer cache (eg. use a private mapping, or directories in
9868c2ecf20Sopenharmony_ci	 * pagecache, etc). Also file data modifications go via their own
9878c2ecf20Sopenharmony_ci	 * mappings. So If we try to mount readonly then copy the filesystem
9888c2ecf20Sopenharmony_ci	 * from bdev, we could get stale data, so invalidate it to give a best
9898c2ecf20Sopenharmony_ci	 * effort at coherency.
9908c2ecf20Sopenharmony_ci	 */
9918c2ecf20Sopenharmony_ci	if (remount_ro && sb->s_bdev)
9928c2ecf20Sopenharmony_ci		invalidate_bdev(sb->s_bdev);
9938c2ecf20Sopenharmony_ci	return 0;
9948c2ecf20Sopenharmony_ci
9958c2ecf20Sopenharmony_cicancel_readonly:
9968c2ecf20Sopenharmony_ci	sb->s_readonly_remount = 0;
9978c2ecf20Sopenharmony_ci	return retval;
9988c2ecf20Sopenharmony_ci}
9998c2ecf20Sopenharmony_ci
10008c2ecf20Sopenharmony_cistatic void do_emergency_remount_callback(struct super_block *sb)
10018c2ecf20Sopenharmony_ci{
10028c2ecf20Sopenharmony_ci	down_write(&sb->s_umount);
10038c2ecf20Sopenharmony_ci	if (sb->s_root && sb->s_bdev && (sb->s_flags & SB_BORN) &&
10048c2ecf20Sopenharmony_ci	    !sb_rdonly(sb)) {
10058c2ecf20Sopenharmony_ci		struct fs_context *fc;
10068c2ecf20Sopenharmony_ci
10078c2ecf20Sopenharmony_ci		fc = fs_context_for_reconfigure(sb->s_root,
10088c2ecf20Sopenharmony_ci					SB_RDONLY | SB_FORCE, SB_RDONLY);
10098c2ecf20Sopenharmony_ci		if (!IS_ERR(fc)) {
10108c2ecf20Sopenharmony_ci			if (parse_monolithic_mount_data(fc, NULL) == 0)
10118c2ecf20Sopenharmony_ci				(void)reconfigure_super(fc);
10128c2ecf20Sopenharmony_ci			put_fs_context(fc);
10138c2ecf20Sopenharmony_ci		}
10148c2ecf20Sopenharmony_ci	}
10158c2ecf20Sopenharmony_ci	up_write(&sb->s_umount);
10168c2ecf20Sopenharmony_ci}
10178c2ecf20Sopenharmony_ci
10188c2ecf20Sopenharmony_cistatic void do_emergency_remount(struct work_struct *work)
10198c2ecf20Sopenharmony_ci{
10208c2ecf20Sopenharmony_ci	__iterate_supers(do_emergency_remount_callback);
10218c2ecf20Sopenharmony_ci	kfree(work);
10228c2ecf20Sopenharmony_ci	printk("Emergency Remount complete\n");
10238c2ecf20Sopenharmony_ci}
10248c2ecf20Sopenharmony_ci
10258c2ecf20Sopenharmony_civoid emergency_remount(void)
10268c2ecf20Sopenharmony_ci{
10278c2ecf20Sopenharmony_ci	struct work_struct *work;
10288c2ecf20Sopenharmony_ci
10298c2ecf20Sopenharmony_ci	work = kmalloc(sizeof(*work), GFP_ATOMIC);
10308c2ecf20Sopenharmony_ci	if (work) {
10318c2ecf20Sopenharmony_ci		INIT_WORK(work, do_emergency_remount);
10328c2ecf20Sopenharmony_ci		schedule_work(work);
10338c2ecf20Sopenharmony_ci	}
10348c2ecf20Sopenharmony_ci}
10358c2ecf20Sopenharmony_ci
10368c2ecf20Sopenharmony_cistatic void do_thaw_all_callback(struct super_block *sb)
10378c2ecf20Sopenharmony_ci{
10388c2ecf20Sopenharmony_ci	down_write(&sb->s_umount);
10398c2ecf20Sopenharmony_ci	if (sb->s_root && sb->s_flags & SB_BORN) {
10408c2ecf20Sopenharmony_ci		emergency_thaw_bdev(sb);
10418c2ecf20Sopenharmony_ci		thaw_super_locked(sb);
10428c2ecf20Sopenharmony_ci	} else {
10438c2ecf20Sopenharmony_ci		up_write(&sb->s_umount);
10448c2ecf20Sopenharmony_ci	}
10458c2ecf20Sopenharmony_ci}
10468c2ecf20Sopenharmony_ci
10478c2ecf20Sopenharmony_cistatic void do_thaw_all(struct work_struct *work)
10488c2ecf20Sopenharmony_ci{
10498c2ecf20Sopenharmony_ci	__iterate_supers(do_thaw_all_callback);
10508c2ecf20Sopenharmony_ci	kfree(work);
10518c2ecf20Sopenharmony_ci	printk(KERN_WARNING "Emergency Thaw complete\n");
10528c2ecf20Sopenharmony_ci}
10538c2ecf20Sopenharmony_ci
10548c2ecf20Sopenharmony_ci/**
10558c2ecf20Sopenharmony_ci * emergency_thaw_all -- forcibly thaw every frozen filesystem
10568c2ecf20Sopenharmony_ci *
10578c2ecf20Sopenharmony_ci * Used for emergency unfreeze of all filesystems via SysRq
10588c2ecf20Sopenharmony_ci */
10598c2ecf20Sopenharmony_civoid emergency_thaw_all(void)
10608c2ecf20Sopenharmony_ci{
10618c2ecf20Sopenharmony_ci	struct work_struct *work;
10628c2ecf20Sopenharmony_ci
10638c2ecf20Sopenharmony_ci	work = kmalloc(sizeof(*work), GFP_ATOMIC);
10648c2ecf20Sopenharmony_ci	if (work) {
10658c2ecf20Sopenharmony_ci		INIT_WORK(work, do_thaw_all);
10668c2ecf20Sopenharmony_ci		schedule_work(work);
10678c2ecf20Sopenharmony_ci	}
10688c2ecf20Sopenharmony_ci}
10698c2ecf20Sopenharmony_ci
10708c2ecf20Sopenharmony_cistatic DEFINE_IDA(unnamed_dev_ida);
10718c2ecf20Sopenharmony_ci
10728c2ecf20Sopenharmony_ci/**
10738c2ecf20Sopenharmony_ci * get_anon_bdev - Allocate a block device for filesystems which don't have one.
10748c2ecf20Sopenharmony_ci * @p: Pointer to a dev_t.
10758c2ecf20Sopenharmony_ci *
10768c2ecf20Sopenharmony_ci * Filesystems which don't use real block devices can call this function
10778c2ecf20Sopenharmony_ci * to allocate a virtual block device.
10788c2ecf20Sopenharmony_ci *
10798c2ecf20Sopenharmony_ci * Context: Any context.  Frequently called while holding sb_lock.
10808c2ecf20Sopenharmony_ci * Return: 0 on success, -EMFILE if there are no anonymous bdevs left
10818c2ecf20Sopenharmony_ci * or -ENOMEM if memory allocation failed.
10828c2ecf20Sopenharmony_ci */
10838c2ecf20Sopenharmony_ciint get_anon_bdev(dev_t *p)
10848c2ecf20Sopenharmony_ci{
10858c2ecf20Sopenharmony_ci	int dev;
10868c2ecf20Sopenharmony_ci
10878c2ecf20Sopenharmony_ci	/*
10888c2ecf20Sopenharmony_ci	 * Many userspace utilities consider an FSID of 0 invalid.
10898c2ecf20Sopenharmony_ci	 * Always return at least 1 from get_anon_bdev.
10908c2ecf20Sopenharmony_ci	 */
10918c2ecf20Sopenharmony_ci	dev = ida_alloc_range(&unnamed_dev_ida, 1, (1 << MINORBITS) - 1,
10928c2ecf20Sopenharmony_ci			GFP_ATOMIC);
10938c2ecf20Sopenharmony_ci	if (dev == -ENOSPC)
10948c2ecf20Sopenharmony_ci		dev = -EMFILE;
10958c2ecf20Sopenharmony_ci	if (dev < 0)
10968c2ecf20Sopenharmony_ci		return dev;
10978c2ecf20Sopenharmony_ci
10988c2ecf20Sopenharmony_ci	*p = MKDEV(0, dev);
10998c2ecf20Sopenharmony_ci	return 0;
11008c2ecf20Sopenharmony_ci}
11018c2ecf20Sopenharmony_ciEXPORT_SYMBOL(get_anon_bdev);
11028c2ecf20Sopenharmony_ci
11038c2ecf20Sopenharmony_civoid free_anon_bdev(dev_t dev)
11048c2ecf20Sopenharmony_ci{
11058c2ecf20Sopenharmony_ci	ida_free(&unnamed_dev_ida, MINOR(dev));
11068c2ecf20Sopenharmony_ci}
11078c2ecf20Sopenharmony_ciEXPORT_SYMBOL(free_anon_bdev);
11088c2ecf20Sopenharmony_ci
11098c2ecf20Sopenharmony_ciint set_anon_super(struct super_block *s, void *data)
11108c2ecf20Sopenharmony_ci{
11118c2ecf20Sopenharmony_ci	return get_anon_bdev(&s->s_dev);
11128c2ecf20Sopenharmony_ci}
11138c2ecf20Sopenharmony_ciEXPORT_SYMBOL(set_anon_super);
11148c2ecf20Sopenharmony_ci
11158c2ecf20Sopenharmony_civoid kill_anon_super(struct super_block *sb)
11168c2ecf20Sopenharmony_ci{
11178c2ecf20Sopenharmony_ci	dev_t dev = sb->s_dev;
11188c2ecf20Sopenharmony_ci	generic_shutdown_super(sb);
11198c2ecf20Sopenharmony_ci	free_anon_bdev(dev);
11208c2ecf20Sopenharmony_ci}
11218c2ecf20Sopenharmony_ciEXPORT_SYMBOL(kill_anon_super);
11228c2ecf20Sopenharmony_ci
11238c2ecf20Sopenharmony_civoid kill_litter_super(struct super_block *sb)
11248c2ecf20Sopenharmony_ci{
11258c2ecf20Sopenharmony_ci	if (sb->s_root)
11268c2ecf20Sopenharmony_ci		d_genocide(sb->s_root);
11278c2ecf20Sopenharmony_ci	kill_anon_super(sb);
11288c2ecf20Sopenharmony_ci}
11298c2ecf20Sopenharmony_ciEXPORT_SYMBOL(kill_litter_super);
11308c2ecf20Sopenharmony_ci
11318c2ecf20Sopenharmony_ciint set_anon_super_fc(struct super_block *sb, struct fs_context *fc)
11328c2ecf20Sopenharmony_ci{
11338c2ecf20Sopenharmony_ci	return set_anon_super(sb, NULL);
11348c2ecf20Sopenharmony_ci}
11358c2ecf20Sopenharmony_ciEXPORT_SYMBOL(set_anon_super_fc);
11368c2ecf20Sopenharmony_ci
11378c2ecf20Sopenharmony_cistatic int test_keyed_super(struct super_block *sb, struct fs_context *fc)
11388c2ecf20Sopenharmony_ci{
11398c2ecf20Sopenharmony_ci	return sb->s_fs_info == fc->s_fs_info;
11408c2ecf20Sopenharmony_ci}
11418c2ecf20Sopenharmony_ci
11428c2ecf20Sopenharmony_cistatic int test_single_super(struct super_block *s, struct fs_context *fc)
11438c2ecf20Sopenharmony_ci{
11448c2ecf20Sopenharmony_ci	return 1;
11458c2ecf20Sopenharmony_ci}
11468c2ecf20Sopenharmony_ci
11478c2ecf20Sopenharmony_ci/**
11488c2ecf20Sopenharmony_ci * vfs_get_super - Get a superblock with a search key set in s_fs_info.
11498c2ecf20Sopenharmony_ci * @fc: The filesystem context holding the parameters
11508c2ecf20Sopenharmony_ci * @keying: How to distinguish superblocks
11518c2ecf20Sopenharmony_ci * @fill_super: Helper to initialise a new superblock
11528c2ecf20Sopenharmony_ci *
11538c2ecf20Sopenharmony_ci * Search for a superblock and create a new one if not found.  The search
11548c2ecf20Sopenharmony_ci * criterion is controlled by @keying.  If the search fails, a new superblock
11558c2ecf20Sopenharmony_ci * is created and @fill_super() is called to initialise it.
11568c2ecf20Sopenharmony_ci *
11578c2ecf20Sopenharmony_ci * @keying can take one of a number of values:
11588c2ecf20Sopenharmony_ci *
11598c2ecf20Sopenharmony_ci * (1) vfs_get_single_super - Only one superblock of this type may exist on the
11608c2ecf20Sopenharmony_ci *     system.  This is typically used for special system filesystems.
11618c2ecf20Sopenharmony_ci *
11628c2ecf20Sopenharmony_ci * (2) vfs_get_keyed_super - Multiple superblocks may exist, but they must have
11638c2ecf20Sopenharmony_ci *     distinct keys (where the key is in s_fs_info).  Searching for the same
11648c2ecf20Sopenharmony_ci *     key again will turn up the superblock for that key.
11658c2ecf20Sopenharmony_ci *
11668c2ecf20Sopenharmony_ci * (3) vfs_get_independent_super - Multiple superblocks may exist and are
11678c2ecf20Sopenharmony_ci *     unkeyed.  Each call will get a new superblock.
11688c2ecf20Sopenharmony_ci *
11698c2ecf20Sopenharmony_ci * A permissions check is made by sget_fc() unless we're getting a superblock
11708c2ecf20Sopenharmony_ci * for a kernel-internal mount or a submount.
11718c2ecf20Sopenharmony_ci */
11728c2ecf20Sopenharmony_ciint vfs_get_super(struct fs_context *fc,
11738c2ecf20Sopenharmony_ci		  enum vfs_get_super_keying keying,
11748c2ecf20Sopenharmony_ci		  int (*fill_super)(struct super_block *sb,
11758c2ecf20Sopenharmony_ci				    struct fs_context *fc))
11768c2ecf20Sopenharmony_ci{
11778c2ecf20Sopenharmony_ci	int (*test)(struct super_block *, struct fs_context *);
11788c2ecf20Sopenharmony_ci	struct super_block *sb;
11798c2ecf20Sopenharmony_ci	int err;
11808c2ecf20Sopenharmony_ci
11818c2ecf20Sopenharmony_ci	switch (keying) {
11828c2ecf20Sopenharmony_ci	case vfs_get_single_super:
11838c2ecf20Sopenharmony_ci	case vfs_get_single_reconf_super:
11848c2ecf20Sopenharmony_ci		test = test_single_super;
11858c2ecf20Sopenharmony_ci		break;
11868c2ecf20Sopenharmony_ci	case vfs_get_keyed_super:
11878c2ecf20Sopenharmony_ci		test = test_keyed_super;
11888c2ecf20Sopenharmony_ci		break;
11898c2ecf20Sopenharmony_ci	case vfs_get_independent_super:
11908c2ecf20Sopenharmony_ci		test = NULL;
11918c2ecf20Sopenharmony_ci		break;
11928c2ecf20Sopenharmony_ci	default:
11938c2ecf20Sopenharmony_ci		BUG();
11948c2ecf20Sopenharmony_ci	}
11958c2ecf20Sopenharmony_ci
11968c2ecf20Sopenharmony_ci	sb = sget_fc(fc, test, set_anon_super_fc);
11978c2ecf20Sopenharmony_ci	if (IS_ERR(sb))
11988c2ecf20Sopenharmony_ci		return PTR_ERR(sb);
11998c2ecf20Sopenharmony_ci
12008c2ecf20Sopenharmony_ci	if (!sb->s_root) {
12018c2ecf20Sopenharmony_ci		err = fill_super(sb, fc);
12028c2ecf20Sopenharmony_ci		if (err)
12038c2ecf20Sopenharmony_ci			goto error;
12048c2ecf20Sopenharmony_ci
12058c2ecf20Sopenharmony_ci		sb->s_flags |= SB_ACTIVE;
12068c2ecf20Sopenharmony_ci		fc->root = dget(sb->s_root);
12078c2ecf20Sopenharmony_ci	} else {
12088c2ecf20Sopenharmony_ci		fc->root = dget(sb->s_root);
12098c2ecf20Sopenharmony_ci		if (keying == vfs_get_single_reconf_super) {
12108c2ecf20Sopenharmony_ci			err = reconfigure_super(fc);
12118c2ecf20Sopenharmony_ci			if (err < 0) {
12128c2ecf20Sopenharmony_ci				dput(fc->root);
12138c2ecf20Sopenharmony_ci				fc->root = NULL;
12148c2ecf20Sopenharmony_ci				goto error;
12158c2ecf20Sopenharmony_ci			}
12168c2ecf20Sopenharmony_ci		}
12178c2ecf20Sopenharmony_ci	}
12188c2ecf20Sopenharmony_ci
12198c2ecf20Sopenharmony_ci	return 0;
12208c2ecf20Sopenharmony_ci
12218c2ecf20Sopenharmony_cierror:
12228c2ecf20Sopenharmony_ci	deactivate_locked_super(sb);
12238c2ecf20Sopenharmony_ci	return err;
12248c2ecf20Sopenharmony_ci}
12258c2ecf20Sopenharmony_ciEXPORT_SYMBOL(vfs_get_super);
12268c2ecf20Sopenharmony_ci
12278c2ecf20Sopenharmony_ciint get_tree_nodev(struct fs_context *fc,
12288c2ecf20Sopenharmony_ci		  int (*fill_super)(struct super_block *sb,
12298c2ecf20Sopenharmony_ci				    struct fs_context *fc))
12308c2ecf20Sopenharmony_ci{
12318c2ecf20Sopenharmony_ci	return vfs_get_super(fc, vfs_get_independent_super, fill_super);
12328c2ecf20Sopenharmony_ci}
12338c2ecf20Sopenharmony_ciEXPORT_SYMBOL(get_tree_nodev);
12348c2ecf20Sopenharmony_ci
12358c2ecf20Sopenharmony_ciint get_tree_single(struct fs_context *fc,
12368c2ecf20Sopenharmony_ci		  int (*fill_super)(struct super_block *sb,
12378c2ecf20Sopenharmony_ci				    struct fs_context *fc))
12388c2ecf20Sopenharmony_ci{
12398c2ecf20Sopenharmony_ci	return vfs_get_super(fc, vfs_get_single_super, fill_super);
12408c2ecf20Sopenharmony_ci}
12418c2ecf20Sopenharmony_ciEXPORT_SYMBOL(get_tree_single);
12428c2ecf20Sopenharmony_ci
12438c2ecf20Sopenharmony_ciint get_tree_single_reconf(struct fs_context *fc,
12448c2ecf20Sopenharmony_ci		  int (*fill_super)(struct super_block *sb,
12458c2ecf20Sopenharmony_ci				    struct fs_context *fc))
12468c2ecf20Sopenharmony_ci{
12478c2ecf20Sopenharmony_ci	return vfs_get_super(fc, vfs_get_single_reconf_super, fill_super);
12488c2ecf20Sopenharmony_ci}
12498c2ecf20Sopenharmony_ciEXPORT_SYMBOL(get_tree_single_reconf);
12508c2ecf20Sopenharmony_ci
12518c2ecf20Sopenharmony_ciint get_tree_keyed(struct fs_context *fc,
12528c2ecf20Sopenharmony_ci		  int (*fill_super)(struct super_block *sb,
12538c2ecf20Sopenharmony_ci				    struct fs_context *fc),
12548c2ecf20Sopenharmony_ci		void *key)
12558c2ecf20Sopenharmony_ci{
12568c2ecf20Sopenharmony_ci	fc->s_fs_info = key;
12578c2ecf20Sopenharmony_ci	return vfs_get_super(fc, vfs_get_keyed_super, fill_super);
12588c2ecf20Sopenharmony_ci}
12598c2ecf20Sopenharmony_ciEXPORT_SYMBOL(get_tree_keyed);
12608c2ecf20Sopenharmony_ci
12618c2ecf20Sopenharmony_ci#ifdef CONFIG_BLOCK
12628c2ecf20Sopenharmony_ci
12638c2ecf20Sopenharmony_cistatic int set_bdev_super(struct super_block *s, void *data)
12648c2ecf20Sopenharmony_ci{
12658c2ecf20Sopenharmony_ci	s->s_bdev = data;
12668c2ecf20Sopenharmony_ci	s->s_dev = s->s_bdev->bd_dev;
12678c2ecf20Sopenharmony_ci	s->s_bdi = bdi_get(s->s_bdev->bd_bdi);
12688c2ecf20Sopenharmony_ci
12698c2ecf20Sopenharmony_ci	if (blk_queue_stable_writes(s->s_bdev->bd_disk->queue))
12708c2ecf20Sopenharmony_ci		s->s_iflags |= SB_I_STABLE_WRITES;
12718c2ecf20Sopenharmony_ci	return 0;
12728c2ecf20Sopenharmony_ci}
12738c2ecf20Sopenharmony_ci
12748c2ecf20Sopenharmony_cistatic int set_bdev_super_fc(struct super_block *s, struct fs_context *fc)
12758c2ecf20Sopenharmony_ci{
12768c2ecf20Sopenharmony_ci	return set_bdev_super(s, fc->sget_key);
12778c2ecf20Sopenharmony_ci}
12788c2ecf20Sopenharmony_ci
12798c2ecf20Sopenharmony_cistatic int test_bdev_super_fc(struct super_block *s, struct fs_context *fc)
12808c2ecf20Sopenharmony_ci{
12818c2ecf20Sopenharmony_ci	return s->s_bdev == fc->sget_key;
12828c2ecf20Sopenharmony_ci}
12838c2ecf20Sopenharmony_ci
12848c2ecf20Sopenharmony_ci/**
12858c2ecf20Sopenharmony_ci * get_tree_bdev - Get a superblock based on a single block device
12868c2ecf20Sopenharmony_ci * @fc: The filesystem context holding the parameters
12878c2ecf20Sopenharmony_ci * @fill_super: Helper to initialise a new superblock
12888c2ecf20Sopenharmony_ci */
12898c2ecf20Sopenharmony_ciint get_tree_bdev(struct fs_context *fc,
12908c2ecf20Sopenharmony_ci		int (*fill_super)(struct super_block *,
12918c2ecf20Sopenharmony_ci				  struct fs_context *))
12928c2ecf20Sopenharmony_ci{
12938c2ecf20Sopenharmony_ci	struct block_device *bdev;
12948c2ecf20Sopenharmony_ci	struct super_block *s;
12958c2ecf20Sopenharmony_ci	fmode_t mode = FMODE_READ | FMODE_EXCL;
12968c2ecf20Sopenharmony_ci	int error = 0;
12978c2ecf20Sopenharmony_ci
12988c2ecf20Sopenharmony_ci	if (!(fc->sb_flags & SB_RDONLY))
12998c2ecf20Sopenharmony_ci		mode |= FMODE_WRITE;
13008c2ecf20Sopenharmony_ci
13018c2ecf20Sopenharmony_ci	if (!fc->source)
13028c2ecf20Sopenharmony_ci		return invalf(fc, "No source specified");
13038c2ecf20Sopenharmony_ci
13048c2ecf20Sopenharmony_ci	bdev = blkdev_get_by_path(fc->source, mode, fc->fs_type);
13058c2ecf20Sopenharmony_ci	if (IS_ERR(bdev)) {
13068c2ecf20Sopenharmony_ci		errorf(fc, "%s: Can't open blockdev", fc->source);
13078c2ecf20Sopenharmony_ci		return PTR_ERR(bdev);
13088c2ecf20Sopenharmony_ci	}
13098c2ecf20Sopenharmony_ci
13108c2ecf20Sopenharmony_ci	/* Once the superblock is inserted into the list by sget_fc(), s_umount
13118c2ecf20Sopenharmony_ci	 * will protect the lockfs code from trying to start a snapshot while
13128c2ecf20Sopenharmony_ci	 * we are mounting
13138c2ecf20Sopenharmony_ci	 */
13148c2ecf20Sopenharmony_ci	mutex_lock(&bdev->bd_fsfreeze_mutex);
13158c2ecf20Sopenharmony_ci	if (bdev->bd_fsfreeze_count > 0) {
13168c2ecf20Sopenharmony_ci		mutex_unlock(&bdev->bd_fsfreeze_mutex);
13178c2ecf20Sopenharmony_ci		warnf(fc, "%pg: Can't mount, blockdev is frozen", bdev);
13188c2ecf20Sopenharmony_ci		blkdev_put(bdev, mode);
13198c2ecf20Sopenharmony_ci		return -EBUSY;
13208c2ecf20Sopenharmony_ci	}
13218c2ecf20Sopenharmony_ci
13228c2ecf20Sopenharmony_ci	fc->sb_flags |= SB_NOSEC;
13238c2ecf20Sopenharmony_ci	fc->sget_key = bdev;
13248c2ecf20Sopenharmony_ci	s = sget_fc(fc, test_bdev_super_fc, set_bdev_super_fc);
13258c2ecf20Sopenharmony_ci	mutex_unlock(&bdev->bd_fsfreeze_mutex);
13268c2ecf20Sopenharmony_ci	if (IS_ERR(s)) {
13278c2ecf20Sopenharmony_ci		blkdev_put(bdev, mode);
13288c2ecf20Sopenharmony_ci		return PTR_ERR(s);
13298c2ecf20Sopenharmony_ci	}
13308c2ecf20Sopenharmony_ci
13318c2ecf20Sopenharmony_ci	if (s->s_root) {
13328c2ecf20Sopenharmony_ci		/* Don't summarily change the RO/RW state. */
13338c2ecf20Sopenharmony_ci		if ((fc->sb_flags ^ s->s_flags) & SB_RDONLY) {
13348c2ecf20Sopenharmony_ci			warnf(fc, "%pg: Can't mount, would change RO state", bdev);
13358c2ecf20Sopenharmony_ci			deactivate_locked_super(s);
13368c2ecf20Sopenharmony_ci			blkdev_put(bdev, mode);
13378c2ecf20Sopenharmony_ci			return -EBUSY;
13388c2ecf20Sopenharmony_ci		}
13398c2ecf20Sopenharmony_ci
13408c2ecf20Sopenharmony_ci		/*
13418c2ecf20Sopenharmony_ci		 * s_umount nests inside bd_mutex during
13428c2ecf20Sopenharmony_ci		 * __invalidate_device().  blkdev_put() acquires
13438c2ecf20Sopenharmony_ci		 * bd_mutex and can't be called under s_umount.  Drop
13448c2ecf20Sopenharmony_ci		 * s_umount temporarily.  This is safe as we're
13458c2ecf20Sopenharmony_ci		 * holding an active reference.
13468c2ecf20Sopenharmony_ci		 */
13478c2ecf20Sopenharmony_ci		up_write(&s->s_umount);
13488c2ecf20Sopenharmony_ci		blkdev_put(bdev, mode);
13498c2ecf20Sopenharmony_ci		down_write(&s->s_umount);
13508c2ecf20Sopenharmony_ci	} else {
13518c2ecf20Sopenharmony_ci		s->s_mode = mode;
13528c2ecf20Sopenharmony_ci		snprintf(s->s_id, sizeof(s->s_id), "%pg", bdev);
13538c2ecf20Sopenharmony_ci		sb_set_blocksize(s, block_size(bdev));
13548c2ecf20Sopenharmony_ci		error = fill_super(s, fc);
13558c2ecf20Sopenharmony_ci		if (error) {
13568c2ecf20Sopenharmony_ci			deactivate_locked_super(s);
13578c2ecf20Sopenharmony_ci			return error;
13588c2ecf20Sopenharmony_ci		}
13598c2ecf20Sopenharmony_ci
13608c2ecf20Sopenharmony_ci		s->s_flags |= SB_ACTIVE;
13618c2ecf20Sopenharmony_ci		bdev->bd_super = s;
13628c2ecf20Sopenharmony_ci	}
13638c2ecf20Sopenharmony_ci
13648c2ecf20Sopenharmony_ci	BUG_ON(fc->root);
13658c2ecf20Sopenharmony_ci	fc->root = dget(s->s_root);
13668c2ecf20Sopenharmony_ci	return 0;
13678c2ecf20Sopenharmony_ci}
13688c2ecf20Sopenharmony_ciEXPORT_SYMBOL(get_tree_bdev);
13698c2ecf20Sopenharmony_ci
13708c2ecf20Sopenharmony_cistatic int test_bdev_super(struct super_block *s, void *data)
13718c2ecf20Sopenharmony_ci{
13728c2ecf20Sopenharmony_ci	return (void *)s->s_bdev == data;
13738c2ecf20Sopenharmony_ci}
13748c2ecf20Sopenharmony_ci
13758c2ecf20Sopenharmony_cistruct dentry *mount_bdev(struct file_system_type *fs_type,
13768c2ecf20Sopenharmony_ci	int flags, const char *dev_name, void *data,
13778c2ecf20Sopenharmony_ci	int (*fill_super)(struct super_block *, void *, int))
13788c2ecf20Sopenharmony_ci{
13798c2ecf20Sopenharmony_ci	struct block_device *bdev;
13808c2ecf20Sopenharmony_ci	struct super_block *s;
13818c2ecf20Sopenharmony_ci	fmode_t mode = FMODE_READ | FMODE_EXCL;
13828c2ecf20Sopenharmony_ci	int error = 0;
13838c2ecf20Sopenharmony_ci
13848c2ecf20Sopenharmony_ci	if (!(flags & SB_RDONLY))
13858c2ecf20Sopenharmony_ci		mode |= FMODE_WRITE;
13868c2ecf20Sopenharmony_ci
13878c2ecf20Sopenharmony_ci	bdev = blkdev_get_by_path(dev_name, mode, fs_type);
13888c2ecf20Sopenharmony_ci	if (IS_ERR(bdev))
13898c2ecf20Sopenharmony_ci		return ERR_CAST(bdev);
13908c2ecf20Sopenharmony_ci
13918c2ecf20Sopenharmony_ci	/*
13928c2ecf20Sopenharmony_ci	 * once the super is inserted into the list by sget, s_umount
13938c2ecf20Sopenharmony_ci	 * will protect the lockfs code from trying to start a snapshot
13948c2ecf20Sopenharmony_ci	 * while we are mounting
13958c2ecf20Sopenharmony_ci	 */
13968c2ecf20Sopenharmony_ci	mutex_lock(&bdev->bd_fsfreeze_mutex);
13978c2ecf20Sopenharmony_ci	if (bdev->bd_fsfreeze_count > 0) {
13988c2ecf20Sopenharmony_ci		mutex_unlock(&bdev->bd_fsfreeze_mutex);
13998c2ecf20Sopenharmony_ci		error = -EBUSY;
14008c2ecf20Sopenharmony_ci		goto error_bdev;
14018c2ecf20Sopenharmony_ci	}
14028c2ecf20Sopenharmony_ci	s = sget(fs_type, test_bdev_super, set_bdev_super, flags | SB_NOSEC,
14038c2ecf20Sopenharmony_ci		 bdev);
14048c2ecf20Sopenharmony_ci	mutex_unlock(&bdev->bd_fsfreeze_mutex);
14058c2ecf20Sopenharmony_ci	if (IS_ERR(s))
14068c2ecf20Sopenharmony_ci		goto error_s;
14078c2ecf20Sopenharmony_ci
14088c2ecf20Sopenharmony_ci	if (s->s_root) {
14098c2ecf20Sopenharmony_ci		if ((flags ^ s->s_flags) & SB_RDONLY) {
14108c2ecf20Sopenharmony_ci			deactivate_locked_super(s);
14118c2ecf20Sopenharmony_ci			error = -EBUSY;
14128c2ecf20Sopenharmony_ci			goto error_bdev;
14138c2ecf20Sopenharmony_ci		}
14148c2ecf20Sopenharmony_ci
14158c2ecf20Sopenharmony_ci		/*
14168c2ecf20Sopenharmony_ci		 * s_umount nests inside bd_mutex during
14178c2ecf20Sopenharmony_ci		 * __invalidate_device().  blkdev_put() acquires
14188c2ecf20Sopenharmony_ci		 * bd_mutex and can't be called under s_umount.  Drop
14198c2ecf20Sopenharmony_ci		 * s_umount temporarily.  This is safe as we're
14208c2ecf20Sopenharmony_ci		 * holding an active reference.
14218c2ecf20Sopenharmony_ci		 */
14228c2ecf20Sopenharmony_ci		up_write(&s->s_umount);
14238c2ecf20Sopenharmony_ci		blkdev_put(bdev, mode);
14248c2ecf20Sopenharmony_ci		down_write(&s->s_umount);
14258c2ecf20Sopenharmony_ci	} else {
14268c2ecf20Sopenharmony_ci		s->s_mode = mode;
14278c2ecf20Sopenharmony_ci		snprintf(s->s_id, sizeof(s->s_id), "%pg", bdev);
14288c2ecf20Sopenharmony_ci		sb_set_blocksize(s, block_size(bdev));
14298c2ecf20Sopenharmony_ci		error = fill_super(s, data, flags & SB_SILENT ? 1 : 0);
14308c2ecf20Sopenharmony_ci		if (error) {
14318c2ecf20Sopenharmony_ci			deactivate_locked_super(s);
14328c2ecf20Sopenharmony_ci			goto error;
14338c2ecf20Sopenharmony_ci		}
14348c2ecf20Sopenharmony_ci
14358c2ecf20Sopenharmony_ci		s->s_flags |= SB_ACTIVE;
14368c2ecf20Sopenharmony_ci		bdev->bd_super = s;
14378c2ecf20Sopenharmony_ci	}
14388c2ecf20Sopenharmony_ci
14398c2ecf20Sopenharmony_ci	return dget(s->s_root);
14408c2ecf20Sopenharmony_ci
14418c2ecf20Sopenharmony_cierror_s:
14428c2ecf20Sopenharmony_ci	error = PTR_ERR(s);
14438c2ecf20Sopenharmony_cierror_bdev:
14448c2ecf20Sopenharmony_ci	blkdev_put(bdev, mode);
14458c2ecf20Sopenharmony_cierror:
14468c2ecf20Sopenharmony_ci	return ERR_PTR(error);
14478c2ecf20Sopenharmony_ci}
14488c2ecf20Sopenharmony_ciEXPORT_SYMBOL(mount_bdev);
14498c2ecf20Sopenharmony_ci
14508c2ecf20Sopenharmony_civoid kill_block_super(struct super_block *sb)
14518c2ecf20Sopenharmony_ci{
14528c2ecf20Sopenharmony_ci	struct block_device *bdev = sb->s_bdev;
14538c2ecf20Sopenharmony_ci	fmode_t mode = sb->s_mode;
14548c2ecf20Sopenharmony_ci
14558c2ecf20Sopenharmony_ci	bdev->bd_super = NULL;
14568c2ecf20Sopenharmony_ci	generic_shutdown_super(sb);
14578c2ecf20Sopenharmony_ci	sync_blockdev(bdev);
14588c2ecf20Sopenharmony_ci	WARN_ON_ONCE(!(mode & FMODE_EXCL));
14598c2ecf20Sopenharmony_ci	blkdev_put(bdev, mode | FMODE_EXCL);
14608c2ecf20Sopenharmony_ci}
14618c2ecf20Sopenharmony_ci
14628c2ecf20Sopenharmony_ciEXPORT_SYMBOL(kill_block_super);
14638c2ecf20Sopenharmony_ci#endif
14648c2ecf20Sopenharmony_ci
14658c2ecf20Sopenharmony_cistruct dentry *mount_nodev(struct file_system_type *fs_type,
14668c2ecf20Sopenharmony_ci	int flags, void *data,
14678c2ecf20Sopenharmony_ci	int (*fill_super)(struct super_block *, void *, int))
14688c2ecf20Sopenharmony_ci{
14698c2ecf20Sopenharmony_ci	int error;
14708c2ecf20Sopenharmony_ci	struct super_block *s = sget(fs_type, NULL, set_anon_super, flags, NULL);
14718c2ecf20Sopenharmony_ci
14728c2ecf20Sopenharmony_ci	if (IS_ERR(s))
14738c2ecf20Sopenharmony_ci		return ERR_CAST(s);
14748c2ecf20Sopenharmony_ci
14758c2ecf20Sopenharmony_ci	error = fill_super(s, data, flags & SB_SILENT ? 1 : 0);
14768c2ecf20Sopenharmony_ci	if (error) {
14778c2ecf20Sopenharmony_ci		deactivate_locked_super(s);
14788c2ecf20Sopenharmony_ci		return ERR_PTR(error);
14798c2ecf20Sopenharmony_ci	}
14808c2ecf20Sopenharmony_ci	s->s_flags |= SB_ACTIVE;
14818c2ecf20Sopenharmony_ci	return dget(s->s_root);
14828c2ecf20Sopenharmony_ci}
14838c2ecf20Sopenharmony_ciEXPORT_SYMBOL(mount_nodev);
14848c2ecf20Sopenharmony_ci
14858c2ecf20Sopenharmony_ciint reconfigure_single(struct super_block *s,
14868c2ecf20Sopenharmony_ci		       int flags, void *data)
14878c2ecf20Sopenharmony_ci{
14888c2ecf20Sopenharmony_ci	struct fs_context *fc;
14898c2ecf20Sopenharmony_ci	int ret;
14908c2ecf20Sopenharmony_ci
14918c2ecf20Sopenharmony_ci	/* The caller really need to be passing fc down into mount_single(),
14928c2ecf20Sopenharmony_ci	 * then a chunk of this can be removed.  [Bollocks -- AV]
14938c2ecf20Sopenharmony_ci	 * Better yet, reconfiguration shouldn't happen, but rather the second
14948c2ecf20Sopenharmony_ci	 * mount should be rejected if the parameters are not compatible.
14958c2ecf20Sopenharmony_ci	 */
14968c2ecf20Sopenharmony_ci	fc = fs_context_for_reconfigure(s->s_root, flags, MS_RMT_MASK);
14978c2ecf20Sopenharmony_ci	if (IS_ERR(fc))
14988c2ecf20Sopenharmony_ci		return PTR_ERR(fc);
14998c2ecf20Sopenharmony_ci
15008c2ecf20Sopenharmony_ci	ret = parse_monolithic_mount_data(fc, data);
15018c2ecf20Sopenharmony_ci	if (ret < 0)
15028c2ecf20Sopenharmony_ci		goto out;
15038c2ecf20Sopenharmony_ci
15048c2ecf20Sopenharmony_ci	ret = reconfigure_super(fc);
15058c2ecf20Sopenharmony_ciout:
15068c2ecf20Sopenharmony_ci	put_fs_context(fc);
15078c2ecf20Sopenharmony_ci	return ret;
15088c2ecf20Sopenharmony_ci}
15098c2ecf20Sopenharmony_ci
15108c2ecf20Sopenharmony_cistatic int compare_single(struct super_block *s, void *p)
15118c2ecf20Sopenharmony_ci{
15128c2ecf20Sopenharmony_ci	return 1;
15138c2ecf20Sopenharmony_ci}
15148c2ecf20Sopenharmony_ci
15158c2ecf20Sopenharmony_cistruct dentry *mount_single(struct file_system_type *fs_type,
15168c2ecf20Sopenharmony_ci	int flags, void *data,
15178c2ecf20Sopenharmony_ci	int (*fill_super)(struct super_block *, void *, int))
15188c2ecf20Sopenharmony_ci{
15198c2ecf20Sopenharmony_ci	struct super_block *s;
15208c2ecf20Sopenharmony_ci	int error;
15218c2ecf20Sopenharmony_ci
15228c2ecf20Sopenharmony_ci	s = sget(fs_type, compare_single, set_anon_super, flags, NULL);
15238c2ecf20Sopenharmony_ci	if (IS_ERR(s))
15248c2ecf20Sopenharmony_ci		return ERR_CAST(s);
15258c2ecf20Sopenharmony_ci	if (!s->s_root) {
15268c2ecf20Sopenharmony_ci		error = fill_super(s, data, flags & SB_SILENT ? 1 : 0);
15278c2ecf20Sopenharmony_ci		if (!error)
15288c2ecf20Sopenharmony_ci			s->s_flags |= SB_ACTIVE;
15298c2ecf20Sopenharmony_ci	} else {
15308c2ecf20Sopenharmony_ci		error = reconfigure_single(s, flags, data);
15318c2ecf20Sopenharmony_ci	}
15328c2ecf20Sopenharmony_ci	if (unlikely(error)) {
15338c2ecf20Sopenharmony_ci		deactivate_locked_super(s);
15348c2ecf20Sopenharmony_ci		return ERR_PTR(error);
15358c2ecf20Sopenharmony_ci	}
15368c2ecf20Sopenharmony_ci	return dget(s->s_root);
15378c2ecf20Sopenharmony_ci}
15388c2ecf20Sopenharmony_ciEXPORT_SYMBOL(mount_single);
15398c2ecf20Sopenharmony_ci
15408c2ecf20Sopenharmony_ci/**
15418c2ecf20Sopenharmony_ci * vfs_get_tree - Get the mountable root
15428c2ecf20Sopenharmony_ci * @fc: The superblock configuration context.
15438c2ecf20Sopenharmony_ci *
15448c2ecf20Sopenharmony_ci * The filesystem is invoked to get or create a superblock which can then later
15458c2ecf20Sopenharmony_ci * be used for mounting.  The filesystem places a pointer to the root to be
15468c2ecf20Sopenharmony_ci * used for mounting in @fc->root.
15478c2ecf20Sopenharmony_ci */
15488c2ecf20Sopenharmony_ciint vfs_get_tree(struct fs_context *fc)
15498c2ecf20Sopenharmony_ci{
15508c2ecf20Sopenharmony_ci	struct super_block *sb;
15518c2ecf20Sopenharmony_ci	int error;
15528c2ecf20Sopenharmony_ci
15538c2ecf20Sopenharmony_ci	if (fc->root)
15548c2ecf20Sopenharmony_ci		return -EBUSY;
15558c2ecf20Sopenharmony_ci
15568c2ecf20Sopenharmony_ci	/* Get the mountable root in fc->root, with a ref on the root and a ref
15578c2ecf20Sopenharmony_ci	 * on the superblock.
15588c2ecf20Sopenharmony_ci	 */
15598c2ecf20Sopenharmony_ci	error = fc->ops->get_tree(fc);
15608c2ecf20Sopenharmony_ci	if (error < 0)
15618c2ecf20Sopenharmony_ci		return error;
15628c2ecf20Sopenharmony_ci
15638c2ecf20Sopenharmony_ci	if (!fc->root) {
15648c2ecf20Sopenharmony_ci		pr_err("Filesystem %s get_tree() didn't set fc->root\n",
15658c2ecf20Sopenharmony_ci		       fc->fs_type->name);
15668c2ecf20Sopenharmony_ci		/* We don't know what the locking state of the superblock is -
15678c2ecf20Sopenharmony_ci		 * if there is a superblock.
15688c2ecf20Sopenharmony_ci		 */
15698c2ecf20Sopenharmony_ci		BUG();
15708c2ecf20Sopenharmony_ci	}
15718c2ecf20Sopenharmony_ci
15728c2ecf20Sopenharmony_ci	sb = fc->root->d_sb;
15738c2ecf20Sopenharmony_ci	WARN_ON(!sb->s_bdi);
15748c2ecf20Sopenharmony_ci
15758c2ecf20Sopenharmony_ci	/*
15768c2ecf20Sopenharmony_ci	 * Write barrier is for super_cache_count(). We place it before setting
15778c2ecf20Sopenharmony_ci	 * SB_BORN as the data dependency between the two functions is the
15788c2ecf20Sopenharmony_ci	 * superblock structure contents that we just set up, not the SB_BORN
15798c2ecf20Sopenharmony_ci	 * flag.
15808c2ecf20Sopenharmony_ci	 */
15818c2ecf20Sopenharmony_ci	smp_wmb();
15828c2ecf20Sopenharmony_ci	sb->s_flags |= SB_BORN;
15838c2ecf20Sopenharmony_ci
15848c2ecf20Sopenharmony_ci	error = security_sb_set_mnt_opts(sb, fc->security, 0, NULL);
15858c2ecf20Sopenharmony_ci	if (unlikely(error)) {
15868c2ecf20Sopenharmony_ci		fc_drop_locked(fc);
15878c2ecf20Sopenharmony_ci		return error;
15888c2ecf20Sopenharmony_ci	}
15898c2ecf20Sopenharmony_ci
15908c2ecf20Sopenharmony_ci	/*
15918c2ecf20Sopenharmony_ci	 * filesystems should never set s_maxbytes larger than MAX_LFS_FILESIZE
15928c2ecf20Sopenharmony_ci	 * but s_maxbytes was an unsigned long long for many releases. Throw
15938c2ecf20Sopenharmony_ci	 * this warning for a little while to try and catch filesystems that
15948c2ecf20Sopenharmony_ci	 * violate this rule.
15958c2ecf20Sopenharmony_ci	 */
15968c2ecf20Sopenharmony_ci	WARN((sb->s_maxbytes < 0), "%s set sb->s_maxbytes to "
15978c2ecf20Sopenharmony_ci		"negative value (%lld)\n", fc->fs_type->name, sb->s_maxbytes);
15988c2ecf20Sopenharmony_ci
15998c2ecf20Sopenharmony_ci	return 0;
16008c2ecf20Sopenharmony_ci}
16018c2ecf20Sopenharmony_ciEXPORT_SYMBOL(vfs_get_tree);
16028c2ecf20Sopenharmony_ci
16038c2ecf20Sopenharmony_ci/*
16048c2ecf20Sopenharmony_ci * Setup private BDI for given superblock. It gets automatically cleaned up
16058c2ecf20Sopenharmony_ci * in generic_shutdown_super().
16068c2ecf20Sopenharmony_ci */
16078c2ecf20Sopenharmony_ciint super_setup_bdi_name(struct super_block *sb, char *fmt, ...)
16088c2ecf20Sopenharmony_ci{
16098c2ecf20Sopenharmony_ci	struct backing_dev_info *bdi;
16108c2ecf20Sopenharmony_ci	int err;
16118c2ecf20Sopenharmony_ci	va_list args;
16128c2ecf20Sopenharmony_ci
16138c2ecf20Sopenharmony_ci	bdi = bdi_alloc(NUMA_NO_NODE);
16148c2ecf20Sopenharmony_ci	if (!bdi)
16158c2ecf20Sopenharmony_ci		return -ENOMEM;
16168c2ecf20Sopenharmony_ci
16178c2ecf20Sopenharmony_ci	va_start(args, fmt);
16188c2ecf20Sopenharmony_ci	err = bdi_register_va(bdi, fmt, args);
16198c2ecf20Sopenharmony_ci	va_end(args);
16208c2ecf20Sopenharmony_ci	if (err) {
16218c2ecf20Sopenharmony_ci		bdi_put(bdi);
16228c2ecf20Sopenharmony_ci		return err;
16238c2ecf20Sopenharmony_ci	}
16248c2ecf20Sopenharmony_ci	WARN_ON(sb->s_bdi != &noop_backing_dev_info);
16258c2ecf20Sopenharmony_ci	sb->s_bdi = bdi;
16268c2ecf20Sopenharmony_ci
16278c2ecf20Sopenharmony_ci	return 0;
16288c2ecf20Sopenharmony_ci}
16298c2ecf20Sopenharmony_ciEXPORT_SYMBOL(super_setup_bdi_name);
16308c2ecf20Sopenharmony_ci
16318c2ecf20Sopenharmony_ci/*
16328c2ecf20Sopenharmony_ci * Setup private BDI for given superblock. I gets automatically cleaned up
16338c2ecf20Sopenharmony_ci * in generic_shutdown_super().
16348c2ecf20Sopenharmony_ci */
16358c2ecf20Sopenharmony_ciint super_setup_bdi(struct super_block *sb)
16368c2ecf20Sopenharmony_ci{
16378c2ecf20Sopenharmony_ci	static atomic_long_t bdi_seq = ATOMIC_LONG_INIT(0);
16388c2ecf20Sopenharmony_ci
16398c2ecf20Sopenharmony_ci	return super_setup_bdi_name(sb, "%.28s-%ld", sb->s_type->name,
16408c2ecf20Sopenharmony_ci				    atomic_long_inc_return(&bdi_seq));
16418c2ecf20Sopenharmony_ci}
16428c2ecf20Sopenharmony_ciEXPORT_SYMBOL(super_setup_bdi);
16438c2ecf20Sopenharmony_ci
16448c2ecf20Sopenharmony_ci/**
16458c2ecf20Sopenharmony_ci * sb_wait_write - wait until all writers to given file system finish
16468c2ecf20Sopenharmony_ci * @sb: the super for which we wait
16478c2ecf20Sopenharmony_ci * @level: type of writers we wait for (normal vs page fault)
16488c2ecf20Sopenharmony_ci *
16498c2ecf20Sopenharmony_ci * This function waits until there are no writers of given type to given file
16508c2ecf20Sopenharmony_ci * system.
16518c2ecf20Sopenharmony_ci */
16528c2ecf20Sopenharmony_cistatic void sb_wait_write(struct super_block *sb, int level)
16538c2ecf20Sopenharmony_ci{
16548c2ecf20Sopenharmony_ci	percpu_down_write(sb->s_writers.rw_sem + level-1);
16558c2ecf20Sopenharmony_ci}
16568c2ecf20Sopenharmony_ci
16578c2ecf20Sopenharmony_ci/*
16588c2ecf20Sopenharmony_ci * We are going to return to userspace and forget about these locks, the
16598c2ecf20Sopenharmony_ci * ownership goes to the caller of thaw_super() which does unlock().
16608c2ecf20Sopenharmony_ci */
16618c2ecf20Sopenharmony_cistatic void lockdep_sb_freeze_release(struct super_block *sb)
16628c2ecf20Sopenharmony_ci{
16638c2ecf20Sopenharmony_ci	int level;
16648c2ecf20Sopenharmony_ci
16658c2ecf20Sopenharmony_ci	for (level = SB_FREEZE_LEVELS - 1; level >= 0; level--)
16668c2ecf20Sopenharmony_ci		percpu_rwsem_release(sb->s_writers.rw_sem + level, 0, _THIS_IP_);
16678c2ecf20Sopenharmony_ci}
16688c2ecf20Sopenharmony_ci
16698c2ecf20Sopenharmony_ci/*
16708c2ecf20Sopenharmony_ci * Tell lockdep we are holding these locks before we call ->unfreeze_fs(sb).
16718c2ecf20Sopenharmony_ci */
16728c2ecf20Sopenharmony_cistatic void lockdep_sb_freeze_acquire(struct super_block *sb)
16738c2ecf20Sopenharmony_ci{
16748c2ecf20Sopenharmony_ci	int level;
16758c2ecf20Sopenharmony_ci
16768c2ecf20Sopenharmony_ci	for (level = 0; level < SB_FREEZE_LEVELS; ++level)
16778c2ecf20Sopenharmony_ci		percpu_rwsem_acquire(sb->s_writers.rw_sem + level, 0, _THIS_IP_);
16788c2ecf20Sopenharmony_ci}
16798c2ecf20Sopenharmony_ci
16808c2ecf20Sopenharmony_cistatic void sb_freeze_unlock(struct super_block *sb, int level)
16818c2ecf20Sopenharmony_ci{
16828c2ecf20Sopenharmony_ci	for (level--; level >= 0; level--)
16838c2ecf20Sopenharmony_ci		percpu_up_write(sb->s_writers.rw_sem + level);
16848c2ecf20Sopenharmony_ci}
16858c2ecf20Sopenharmony_ci
16868c2ecf20Sopenharmony_ci/**
16878c2ecf20Sopenharmony_ci * freeze_super - lock the filesystem and force it into a consistent state
16888c2ecf20Sopenharmony_ci * @sb: the super to lock
16898c2ecf20Sopenharmony_ci *
16908c2ecf20Sopenharmony_ci * Syncs the super to make sure the filesystem is consistent and calls the fs's
16918c2ecf20Sopenharmony_ci * freeze_fs.  Subsequent calls to this without first thawing the fs will return
16928c2ecf20Sopenharmony_ci * -EBUSY.
16938c2ecf20Sopenharmony_ci *
16948c2ecf20Sopenharmony_ci * During this function, sb->s_writers.frozen goes through these values:
16958c2ecf20Sopenharmony_ci *
16968c2ecf20Sopenharmony_ci * SB_UNFROZEN: File system is normal, all writes progress as usual.
16978c2ecf20Sopenharmony_ci *
16988c2ecf20Sopenharmony_ci * SB_FREEZE_WRITE: The file system is in the process of being frozen.  New
16998c2ecf20Sopenharmony_ci * writes should be blocked, though page faults are still allowed. We wait for
17008c2ecf20Sopenharmony_ci * all writes to complete and then proceed to the next stage.
17018c2ecf20Sopenharmony_ci *
17028c2ecf20Sopenharmony_ci * SB_FREEZE_PAGEFAULT: Freezing continues. Now also page faults are blocked
17038c2ecf20Sopenharmony_ci * but internal fs threads can still modify the filesystem (although they
17048c2ecf20Sopenharmony_ci * should not dirty new pages or inodes), writeback can run etc. After waiting
17058c2ecf20Sopenharmony_ci * for all running page faults we sync the filesystem which will clean all
17068c2ecf20Sopenharmony_ci * dirty pages and inodes (no new dirty pages or inodes can be created when
17078c2ecf20Sopenharmony_ci * sync is running).
17088c2ecf20Sopenharmony_ci *
17098c2ecf20Sopenharmony_ci * SB_FREEZE_FS: The file system is frozen. Now all internal sources of fs
17108c2ecf20Sopenharmony_ci * modification are blocked (e.g. XFS preallocation truncation on inode
17118c2ecf20Sopenharmony_ci * reclaim). This is usually implemented by blocking new transactions for
17128c2ecf20Sopenharmony_ci * filesystems that have them and need this additional guard. After all
17138c2ecf20Sopenharmony_ci * internal writers are finished we call ->freeze_fs() to finish filesystem
17148c2ecf20Sopenharmony_ci * freezing. Then we transition to SB_FREEZE_COMPLETE state. This state is
17158c2ecf20Sopenharmony_ci * mostly auxiliary for filesystems to verify they do not modify frozen fs.
17168c2ecf20Sopenharmony_ci *
17178c2ecf20Sopenharmony_ci * sb->s_writers.frozen is protected by sb->s_umount.
17188c2ecf20Sopenharmony_ci */
17198c2ecf20Sopenharmony_ciint freeze_super(struct super_block *sb)
17208c2ecf20Sopenharmony_ci{
17218c2ecf20Sopenharmony_ci	int ret;
17228c2ecf20Sopenharmony_ci
17238c2ecf20Sopenharmony_ci	atomic_inc(&sb->s_active);
17248c2ecf20Sopenharmony_ci	down_write(&sb->s_umount);
17258c2ecf20Sopenharmony_ci	if (sb->s_writers.frozen != SB_UNFROZEN) {
17268c2ecf20Sopenharmony_ci		deactivate_locked_super(sb);
17278c2ecf20Sopenharmony_ci		return -EBUSY;
17288c2ecf20Sopenharmony_ci	}
17298c2ecf20Sopenharmony_ci
17308c2ecf20Sopenharmony_ci	if (!(sb->s_flags & SB_BORN)) {
17318c2ecf20Sopenharmony_ci		up_write(&sb->s_umount);
17328c2ecf20Sopenharmony_ci		return 0;	/* sic - it's "nothing to do" */
17338c2ecf20Sopenharmony_ci	}
17348c2ecf20Sopenharmony_ci
17358c2ecf20Sopenharmony_ci	if (sb_rdonly(sb)) {
17368c2ecf20Sopenharmony_ci		/* Nothing to do really... */
17378c2ecf20Sopenharmony_ci		sb->s_writers.frozen = SB_FREEZE_COMPLETE;
17388c2ecf20Sopenharmony_ci		up_write(&sb->s_umount);
17398c2ecf20Sopenharmony_ci		return 0;
17408c2ecf20Sopenharmony_ci	}
17418c2ecf20Sopenharmony_ci
17428c2ecf20Sopenharmony_ci	sb->s_writers.frozen = SB_FREEZE_WRITE;
17438c2ecf20Sopenharmony_ci	/* Release s_umount to preserve sb_start_write -> s_umount ordering */
17448c2ecf20Sopenharmony_ci	up_write(&sb->s_umount);
17458c2ecf20Sopenharmony_ci	sb_wait_write(sb, SB_FREEZE_WRITE);
17468c2ecf20Sopenharmony_ci	down_write(&sb->s_umount);
17478c2ecf20Sopenharmony_ci
17488c2ecf20Sopenharmony_ci	/* Now we go and block page faults... */
17498c2ecf20Sopenharmony_ci	sb->s_writers.frozen = SB_FREEZE_PAGEFAULT;
17508c2ecf20Sopenharmony_ci	sb_wait_write(sb, SB_FREEZE_PAGEFAULT);
17518c2ecf20Sopenharmony_ci
17528c2ecf20Sopenharmony_ci	/* All writers are done so after syncing there won't be dirty data */
17538c2ecf20Sopenharmony_ci	ret = sync_filesystem(sb);
17548c2ecf20Sopenharmony_ci	if (ret) {
17558c2ecf20Sopenharmony_ci		sb->s_writers.frozen = SB_UNFROZEN;
17568c2ecf20Sopenharmony_ci		sb_freeze_unlock(sb, SB_FREEZE_PAGEFAULT);
17578c2ecf20Sopenharmony_ci		wake_up(&sb->s_writers.wait_unfrozen);
17588c2ecf20Sopenharmony_ci		deactivate_locked_super(sb);
17598c2ecf20Sopenharmony_ci		return ret;
17608c2ecf20Sopenharmony_ci	}
17618c2ecf20Sopenharmony_ci
17628c2ecf20Sopenharmony_ci	/* Now wait for internal filesystem counter */
17638c2ecf20Sopenharmony_ci	sb->s_writers.frozen = SB_FREEZE_FS;
17648c2ecf20Sopenharmony_ci	sb_wait_write(sb, SB_FREEZE_FS);
17658c2ecf20Sopenharmony_ci
17668c2ecf20Sopenharmony_ci	if (sb->s_op->freeze_fs) {
17678c2ecf20Sopenharmony_ci		ret = sb->s_op->freeze_fs(sb);
17688c2ecf20Sopenharmony_ci		if (ret) {
17698c2ecf20Sopenharmony_ci			printk(KERN_ERR
17708c2ecf20Sopenharmony_ci				"VFS:Filesystem freeze failed\n");
17718c2ecf20Sopenharmony_ci			sb->s_writers.frozen = SB_UNFROZEN;
17728c2ecf20Sopenharmony_ci			sb_freeze_unlock(sb, SB_FREEZE_FS);
17738c2ecf20Sopenharmony_ci			wake_up(&sb->s_writers.wait_unfrozen);
17748c2ecf20Sopenharmony_ci			deactivate_locked_super(sb);
17758c2ecf20Sopenharmony_ci			return ret;
17768c2ecf20Sopenharmony_ci		}
17778c2ecf20Sopenharmony_ci	}
17788c2ecf20Sopenharmony_ci	/*
17798c2ecf20Sopenharmony_ci	 * For debugging purposes so that fs can warn if it sees write activity
17808c2ecf20Sopenharmony_ci	 * when frozen is set to SB_FREEZE_COMPLETE, and for thaw_super().
17818c2ecf20Sopenharmony_ci	 */
17828c2ecf20Sopenharmony_ci	sb->s_writers.frozen = SB_FREEZE_COMPLETE;
17838c2ecf20Sopenharmony_ci	lockdep_sb_freeze_release(sb);
17848c2ecf20Sopenharmony_ci	up_write(&sb->s_umount);
17858c2ecf20Sopenharmony_ci	return 0;
17868c2ecf20Sopenharmony_ci}
17878c2ecf20Sopenharmony_ciEXPORT_SYMBOL(freeze_super);
17888c2ecf20Sopenharmony_ci
17898c2ecf20Sopenharmony_ci/**
17908c2ecf20Sopenharmony_ci * thaw_super -- unlock filesystem
17918c2ecf20Sopenharmony_ci * @sb: the super to thaw
17928c2ecf20Sopenharmony_ci *
17938c2ecf20Sopenharmony_ci * Unlocks the filesystem and marks it writeable again after freeze_super().
17948c2ecf20Sopenharmony_ci */
17958c2ecf20Sopenharmony_cistatic int thaw_super_locked(struct super_block *sb)
17968c2ecf20Sopenharmony_ci{
17978c2ecf20Sopenharmony_ci	int error;
17988c2ecf20Sopenharmony_ci
17998c2ecf20Sopenharmony_ci	if (sb->s_writers.frozen != SB_FREEZE_COMPLETE) {
18008c2ecf20Sopenharmony_ci		up_write(&sb->s_umount);
18018c2ecf20Sopenharmony_ci		return -EINVAL;
18028c2ecf20Sopenharmony_ci	}
18038c2ecf20Sopenharmony_ci
18048c2ecf20Sopenharmony_ci	if (sb_rdonly(sb)) {
18058c2ecf20Sopenharmony_ci		sb->s_writers.frozen = SB_UNFROZEN;
18068c2ecf20Sopenharmony_ci		goto out;
18078c2ecf20Sopenharmony_ci	}
18088c2ecf20Sopenharmony_ci
18098c2ecf20Sopenharmony_ci	lockdep_sb_freeze_acquire(sb);
18108c2ecf20Sopenharmony_ci
18118c2ecf20Sopenharmony_ci	if (sb->s_op->unfreeze_fs) {
18128c2ecf20Sopenharmony_ci		error = sb->s_op->unfreeze_fs(sb);
18138c2ecf20Sopenharmony_ci		if (error) {
18148c2ecf20Sopenharmony_ci			printk(KERN_ERR
18158c2ecf20Sopenharmony_ci				"VFS:Filesystem thaw failed\n");
18168c2ecf20Sopenharmony_ci			lockdep_sb_freeze_release(sb);
18178c2ecf20Sopenharmony_ci			up_write(&sb->s_umount);
18188c2ecf20Sopenharmony_ci			return error;
18198c2ecf20Sopenharmony_ci		}
18208c2ecf20Sopenharmony_ci	}
18218c2ecf20Sopenharmony_ci
18228c2ecf20Sopenharmony_ci	sb->s_writers.frozen = SB_UNFROZEN;
18238c2ecf20Sopenharmony_ci	sb_freeze_unlock(sb, SB_FREEZE_FS);
18248c2ecf20Sopenharmony_ciout:
18258c2ecf20Sopenharmony_ci	wake_up(&sb->s_writers.wait_unfrozen);
18268c2ecf20Sopenharmony_ci	deactivate_locked_super(sb);
18278c2ecf20Sopenharmony_ci	return 0;
18288c2ecf20Sopenharmony_ci}
18298c2ecf20Sopenharmony_ci
18308c2ecf20Sopenharmony_ciint thaw_super(struct super_block *sb)
18318c2ecf20Sopenharmony_ci{
18328c2ecf20Sopenharmony_ci	down_write(&sb->s_umount);
18338c2ecf20Sopenharmony_ci	return thaw_super_locked(sb);
18348c2ecf20Sopenharmony_ci}
18358c2ecf20Sopenharmony_ciEXPORT_SYMBOL(thaw_super);
1836