linux/fs/ceph/super.c

// SPDX-License-Identifier: GPL-2.0-only

#include <linux/ceph/ceph_debug.h>

#include <linux/backing-dev.h>
#include <linux/ctype.h>
#include <linux/fs.h>
#include <linux/inet.h>
#include <linux/in6.h>
#include <linux/module.h>
#include <linux/mount.h>
#include <linux/fs_context.h>
#include <linux/fs_parser.h>
#include <linux/sched.h>
#include <linux/seq_file.h>
#include <linux/slab.h>
#include <linux/statfs.h>
#include <linux/string.h>

#include "super.h"
#include "mds_client.h"
#include "cache.h"
#include "crypto.h"

#include <linux/ceph/ceph_features.h>
#include <linux/ceph/decode.h>
#include <linux/ceph/mon_client.h>
#include <linux/ceph/auth.h>
#include <linux/ceph/debugfs.h>

#include <uapi/linux/magic.h>

static DEFINE_SPINLOCK(ceph_fsc_lock);
static LIST_HEAD(ceph_fsc_list);

/*
 * Ceph superblock operations
 *
 * Handle the basics of mounting, unmounting.
 */

/*
 * super ops
 */
static void ceph_put_super(struct super_block *s)
{}

static int ceph_statfs(struct dentry *dentry, struct kstatfs *buf)
{}

static int ceph_sync_fs(struct super_block *sb, int wait)
{}

/*
 * mount options
 */
enum {};

enum ceph_recover_session_mode {};

static const struct constant_table ceph_param_recover[] =;

static const struct fs_parameter_spec ceph_mount_parameters[] =;

struct ceph_parse_opts_ctx {};

/*
 * Remove adjacent slashes and then the trailing slash, unless it is
 * the only remaining character.
 *
 * E.g. "//dir1////dir2///" --> "/dir1/dir2", "///" --> "/".
 */
static void canonicalize_path(char *path)
{}

/*
 * Check if the mds namespace in ceph_mount_options matches
 * the passed in namespace string. First time match (when
 * ->mds_namespace is NULL) is treated specially, since
 * ->mds_namespace needs to be initialized by the caller.
 */
static int namespace_equals(struct ceph_mount_options *fsopt,
			    const char *namespace, size_t len)
{}

static int ceph_parse_old_source(const char *dev_name, const char *dev_name_end,
				 struct fs_context *fc)
{}

static int ceph_parse_new_source(const char *dev_name, const char *dev_name_end,
				 struct fs_context *fc)
{}

/*
 * Parse the source parameter for new device format. Distinguish the device
 * spec from the path. Try parsing new device format and fallback to old
 * format if needed.
 *
 * New device syntax will looks like:
 *     <device_spec>=/<path>
 * where
 *     <device_spec> is [email protected]
 *     <path> is optional, but if present must begin with '/'
 * (monitor addresses are passed via mount option)
 *
 * Old device syntax is:
 *     <server_spec>[,<server_spec>...]:[<path>]
 * where
 *     <server_spec> is <ip>[:<port>]
 *     <path> is optional, but if present must begin with '/'
 */
static int ceph_parse_source(struct fs_parameter *param, struct fs_context *fc)
{}

static int ceph_parse_mon_addr(struct fs_parameter *param,
			       struct fs_context *fc)
{}

static int ceph_parse_mount_param(struct fs_context *fc,
				  struct fs_parameter *param)
{}

static void destroy_mount_options(struct ceph_mount_options *args)
{}

static int strcmp_null(const char *s1, const char *s2)
{}

static int compare_mount_options(struct ceph_mount_options *new_fsopt,
				 struct ceph_options *new_opt,
				 struct ceph_fs_client *fsc)
{}

/**
 * ceph_show_options - Show mount options in /proc/mounts
 * @m: seq_file to write to
 * @root: root of that (sub)tree
 */
static int ceph_show_options(struct seq_file *m, struct dentry *root)
{}

/*
 * handle any mon messages the standard library doesn't understand.
 * return error if we don't either.
 */
static int extra_mon_dispatch(struct ceph_client *client, struct ceph_msg *msg)
{}

/*
 * create a new fs client
 *
 * Success or not, this function consumes @fsopt and @opt.
 */
static struct ceph_fs_client *create_fs_client(struct ceph_mount_options *fsopt,
					struct ceph_options *opt)
{}

static void flush_fs_workqueues(struct ceph_fs_client *fsc)
{}

static void destroy_fs_client(struct ceph_fs_client *fsc)
{}

/*
 * caches
 */
struct kmem_cache *ceph_inode_cachep;
struct kmem_cache *ceph_cap_cachep;
struct kmem_cache *ceph_cap_snap_cachep;
struct kmem_cache *ceph_cap_flush_cachep;
struct kmem_cache *ceph_dentry_cachep;
struct kmem_cache *ceph_file_cachep;
struct kmem_cache *ceph_dir_file_cachep;
struct kmem_cache *ceph_mds_request_cachep;
mempool_t *ceph_wb_pagevec_pool;

static void ceph_inode_init_once(void *foo)
{}

static int __init init_caches(void)
{}

static void destroy_caches(void)
{}

static void __ceph_umount_begin(struct ceph_fs_client *fsc)
{}

/*
 * ceph_umount_begin - initiate forced umount.  Tear down the
 * mount, skipping steps that may hang while waiting for server(s).
 */
void ceph_umount_begin(struct super_block *sb)
{}

static const struct super_operations ceph_super_ops =;

/*
 * Bootstrap mount by opening the root directory.  Note the mount
 * @started time from caller, and time out if this takes too long.
 */
static struct dentry *open_root_dentry(struct ceph_fs_client *fsc,
				       const char *path,
				       unsigned long started)
{}

#ifdef CONFIG_FS_ENCRYPTION
static int ceph_apply_test_dummy_encryption(struct super_block *sb,
					    struct fs_context *fc,
					    struct ceph_mount_options *fsopt)
{}
#else
static int ceph_apply_test_dummy_encryption(struct super_block *sb,
					    struct fs_context *fc,
					    struct ceph_mount_options *fsopt)
{
	return 0;
}
#endif

/*
 * mount: join the ceph cluster, and open root directory.
 */
static struct dentry *ceph_real_mount(struct ceph_fs_client *fsc,
				      struct fs_context *fc)
{}

static int ceph_set_super(struct super_block *s, struct fs_context *fc)
{}

/*
 * share superblock if same fs AND options
 */
static int ceph_compare_super(struct super_block *sb, struct fs_context *fc)
{}

/*
 * construct our own bdi so we can control readahead, etc.
 */
static atomic_long_t bdi_seq =;

static int ceph_setup_bdi(struct super_block *sb, struct ceph_fs_client *fsc)
{}

static int ceph_get_tree(struct fs_context *fc)
{}

static void ceph_free_fc(struct fs_context *fc)
{}

static int ceph_reconfigure_fc(struct fs_context *fc)
{}

static const struct fs_context_operations ceph_context_ops =;

/*
 * Set up the filesystem mount context.
 */
static int ceph_init_fs_context(struct fs_context *fc)
{}

/*
 * Return true if it successfully increases the blocker counter,
 * or false if the mdsc is in stopping and flushed state.
 */
static bool __inc_stopping_blocker(struct ceph_mds_client *mdsc)
{}

static void __dec_stopping_blocker(struct ceph_mds_client *mdsc)
{}

/* For metadata IO requests */
bool ceph_inc_mds_stopping_blocker(struct ceph_mds_client *mdsc,
				   struct ceph_mds_session *session)
{}

void ceph_dec_mds_stopping_blocker(struct ceph_mds_client *mdsc)
{}

/* For data IO requests */
bool ceph_inc_osd_stopping_blocker(struct ceph_mds_client *mdsc)
{}

void ceph_dec_osd_stopping_blocker(struct ceph_mds_client *mdsc)
{}

static void ceph_kill_sb(struct super_block *s)
{}

static struct file_system_type ceph_fs_type =;
MODULE_ALIAS_FS();

int ceph_force_reconnect(struct super_block *sb)
{}

static int __init init_ceph(void)
{}

static void __exit exit_ceph(void)
{}

static int param_set_metrics(const char *val, const struct kernel_param *kp)
{}

static const struct kernel_param_ops param_ops_metrics =;

bool disable_send_metrics =;
module_param_cb();
MODULE_PARM_DESC();

/* for both v1 and v2 syntax */
static bool mount_support =;
static const struct kernel_param_ops param_ops_mount_syntax =;
module_param_cb();
module_param_cb();

bool enable_unsafe_idmap =;
module_param(enable_unsafe_idmap, bool, 0644);
MODULE_PARM_DESC();

module_init();
module_exit(exit_ceph);

MODULE_AUTHOR();
MODULE_AUTHOR();
MODULE_AUTHOR();
MODULE_DESCRIPTION();
MODULE_LICENSE();