xref: /kernel/linux/linux-6.6/drivers/md/dm.h (revision 62306a36)
162306a36Sopenharmony_ci/*
262306a36Sopenharmony_ci * Internal header file for device mapper
362306a36Sopenharmony_ci *
462306a36Sopenharmony_ci * Copyright (C) 2001, 2002 Sistina Software
562306a36Sopenharmony_ci * Copyright (C) 2004-2006 Red Hat, Inc. All rights reserved.
662306a36Sopenharmony_ci *
762306a36Sopenharmony_ci * This file is released under the LGPL.
862306a36Sopenharmony_ci */
962306a36Sopenharmony_ci
1062306a36Sopenharmony_ci#ifndef DM_INTERNAL_H
1162306a36Sopenharmony_ci#define DM_INTERNAL_H
1262306a36Sopenharmony_ci
1362306a36Sopenharmony_ci#include <linux/fs.h>
1462306a36Sopenharmony_ci#include <linux/device-mapper.h>
1562306a36Sopenharmony_ci#include <linux/list.h>
1662306a36Sopenharmony_ci#include <linux/moduleparam.h>
1762306a36Sopenharmony_ci#include <linux/blkdev.h>
1862306a36Sopenharmony_ci#include <linux/backing-dev.h>
1962306a36Sopenharmony_ci#include <linux/hdreg.h>
2062306a36Sopenharmony_ci#include <linux/completion.h>
2162306a36Sopenharmony_ci#include <linux/kobject.h>
2262306a36Sopenharmony_ci#include <linux/refcount.h>
2362306a36Sopenharmony_ci#include <linux/log2.h>
2462306a36Sopenharmony_ci
2562306a36Sopenharmony_ci#include "dm-stats.h"
2662306a36Sopenharmony_ci
2762306a36Sopenharmony_ci/*
2862306a36Sopenharmony_ci * Suspend feature flags
2962306a36Sopenharmony_ci */
3062306a36Sopenharmony_ci#define DM_SUSPEND_LOCKFS_FLAG		(1 << 0)
3162306a36Sopenharmony_ci#define DM_SUSPEND_NOFLUSH_FLAG		(1 << 1)
3262306a36Sopenharmony_ci
3362306a36Sopenharmony_ci/*
3462306a36Sopenharmony_ci * Status feature flags
3562306a36Sopenharmony_ci */
3662306a36Sopenharmony_ci#define DM_STATUS_NOFLUSH_FLAG		(1 << 0)
3762306a36Sopenharmony_ci
3862306a36Sopenharmony_ci/*
3962306a36Sopenharmony_ci * List of devices that a metadevice uses and should open/close.
4062306a36Sopenharmony_ci */
4162306a36Sopenharmony_cistruct dm_dev_internal {
4262306a36Sopenharmony_ci	struct list_head list;
4362306a36Sopenharmony_ci	refcount_t count;
4462306a36Sopenharmony_ci	struct dm_dev *dm_dev;
4562306a36Sopenharmony_ci};
4662306a36Sopenharmony_ci
4762306a36Sopenharmony_cistruct dm_table;
4862306a36Sopenharmony_cistruct dm_md_mempools;
4962306a36Sopenharmony_cistruct dm_target_io;
5062306a36Sopenharmony_cistruct dm_io;
5162306a36Sopenharmony_ci
5262306a36Sopenharmony_ci/*
5362306a36Sopenharmony_ci *---------------------------------------------------------------
5462306a36Sopenharmony_ci * Internal table functions.
5562306a36Sopenharmony_ci *---------------------------------------------------------------
5662306a36Sopenharmony_ci */
5762306a36Sopenharmony_civoid dm_table_event_callback(struct dm_table *t,
5862306a36Sopenharmony_ci			     void (*fn)(void *), void *context);
5962306a36Sopenharmony_cistruct dm_target *dm_table_find_target(struct dm_table *t, sector_t sector);
6062306a36Sopenharmony_cibool dm_table_has_no_data_devices(struct dm_table *table);
6162306a36Sopenharmony_ciint dm_calculate_queue_limits(struct dm_table *table,
6262306a36Sopenharmony_ci			      struct queue_limits *limits);
6362306a36Sopenharmony_ciint dm_table_set_restrictions(struct dm_table *t, struct request_queue *q,
6462306a36Sopenharmony_ci			      struct queue_limits *limits);
6562306a36Sopenharmony_cistruct list_head *dm_table_get_devices(struct dm_table *t);
6662306a36Sopenharmony_civoid dm_table_presuspend_targets(struct dm_table *t);
6762306a36Sopenharmony_civoid dm_table_presuspend_undo_targets(struct dm_table *t);
6862306a36Sopenharmony_civoid dm_table_postsuspend_targets(struct dm_table *t);
6962306a36Sopenharmony_ciint dm_table_resume_targets(struct dm_table *t);
7062306a36Sopenharmony_cienum dm_queue_mode dm_table_get_type(struct dm_table *t);
7162306a36Sopenharmony_cistruct target_type *dm_table_get_immutable_target_type(struct dm_table *t);
7262306a36Sopenharmony_cistruct dm_target *dm_table_get_immutable_target(struct dm_table *t);
7362306a36Sopenharmony_cistruct dm_target *dm_table_get_wildcard_target(struct dm_table *t);
7462306a36Sopenharmony_cibool dm_table_bio_based(struct dm_table *t);
7562306a36Sopenharmony_cibool dm_table_request_based(struct dm_table *t);
7662306a36Sopenharmony_ci
7762306a36Sopenharmony_civoid dm_lock_md_type(struct mapped_device *md);
7862306a36Sopenharmony_civoid dm_unlock_md_type(struct mapped_device *md);
7962306a36Sopenharmony_civoid dm_set_md_type(struct mapped_device *md, enum dm_queue_mode type);
8062306a36Sopenharmony_cienum dm_queue_mode dm_get_md_type(struct mapped_device *md);
8162306a36Sopenharmony_cistruct target_type *dm_get_immutable_target_type(struct mapped_device *md);
8262306a36Sopenharmony_ci
8362306a36Sopenharmony_ciint dm_setup_md_queue(struct mapped_device *md, struct dm_table *t);
8462306a36Sopenharmony_ci
8562306a36Sopenharmony_ci/*
8662306a36Sopenharmony_ci * To check whether the target type is bio-based or not (request-based).
8762306a36Sopenharmony_ci */
8862306a36Sopenharmony_ci#define dm_target_bio_based(t) ((t)->type->map != NULL)
8962306a36Sopenharmony_ci
9062306a36Sopenharmony_ci/*
9162306a36Sopenharmony_ci * To check whether the target type is request-based or not (bio-based).
9262306a36Sopenharmony_ci */
9362306a36Sopenharmony_ci#define dm_target_request_based(t) ((t)->type->clone_and_map_rq != NULL)
9462306a36Sopenharmony_ci
9562306a36Sopenharmony_ci/*
9662306a36Sopenharmony_ci * To check whether the target type is a hybrid (capable of being
9762306a36Sopenharmony_ci * either request-based or bio-based).
9862306a36Sopenharmony_ci */
9962306a36Sopenharmony_ci#define dm_target_hybrid(t) (dm_target_bio_based(t) && dm_target_request_based(t))
10062306a36Sopenharmony_ci
10162306a36Sopenharmony_ci/*
10262306a36Sopenharmony_ci * Zoned targets related functions.
10362306a36Sopenharmony_ci */
10462306a36Sopenharmony_ciint dm_set_zones_restrictions(struct dm_table *t, struct request_queue *q);
10562306a36Sopenharmony_civoid dm_zone_endio(struct dm_io *io, struct bio *clone);
10662306a36Sopenharmony_ci#ifdef CONFIG_BLK_DEV_ZONED
10762306a36Sopenharmony_civoid dm_cleanup_zoned_dev(struct mapped_device *md);
10862306a36Sopenharmony_ciint dm_blk_report_zones(struct gendisk *disk, sector_t sector,
10962306a36Sopenharmony_ci			unsigned int nr_zones, report_zones_cb cb, void *data);
11062306a36Sopenharmony_cibool dm_is_zone_write(struct mapped_device *md, struct bio *bio);
11162306a36Sopenharmony_ciint dm_zone_map_bio(struct dm_target_io *io);
11262306a36Sopenharmony_ci#else
11362306a36Sopenharmony_cistatic inline void dm_cleanup_zoned_dev(struct mapped_device *md) {}
11462306a36Sopenharmony_ci#define dm_blk_report_zones	NULL
11562306a36Sopenharmony_cistatic inline bool dm_is_zone_write(struct mapped_device *md, struct bio *bio)
11662306a36Sopenharmony_ci{
11762306a36Sopenharmony_ci	return false;
11862306a36Sopenharmony_ci}
11962306a36Sopenharmony_cistatic inline int dm_zone_map_bio(struct dm_target_io *tio)
12062306a36Sopenharmony_ci{
12162306a36Sopenharmony_ci	return DM_MAPIO_KILL;
12262306a36Sopenharmony_ci}
12362306a36Sopenharmony_ci#endif
12462306a36Sopenharmony_ci
12562306a36Sopenharmony_ci/*
12662306a36Sopenharmony_ci *---------------------------------------------------------------
12762306a36Sopenharmony_ci * A registry of target types.
12862306a36Sopenharmony_ci *---------------------------------------------------------------
12962306a36Sopenharmony_ci */
13062306a36Sopenharmony_ciint dm_target_init(void);
13162306a36Sopenharmony_civoid dm_target_exit(void);
13262306a36Sopenharmony_cistruct target_type *dm_get_target_type(const char *name);
13362306a36Sopenharmony_civoid dm_put_target_type(struct target_type *tt);
13462306a36Sopenharmony_ciint dm_target_iterate(void (*iter_func)(struct target_type *tt,
13562306a36Sopenharmony_ci					void *param), void *param);
13662306a36Sopenharmony_ci
13762306a36Sopenharmony_ciint dm_split_args(int *argc, char ***argvp, char *input);
13862306a36Sopenharmony_ci
13962306a36Sopenharmony_ci/*
14062306a36Sopenharmony_ci * Is this mapped_device being deleted?
14162306a36Sopenharmony_ci */
14262306a36Sopenharmony_ciint dm_deleting_md(struct mapped_device *md);
14362306a36Sopenharmony_ci
14462306a36Sopenharmony_ci/*
14562306a36Sopenharmony_ci * Is this mapped_device suspended?
14662306a36Sopenharmony_ci */
14762306a36Sopenharmony_ciint dm_suspended_md(struct mapped_device *md);
14862306a36Sopenharmony_ci
14962306a36Sopenharmony_ci/*
15062306a36Sopenharmony_ci * Internal suspend and resume methods.
15162306a36Sopenharmony_ci */
15262306a36Sopenharmony_ciint dm_suspended_internally_md(struct mapped_device *md);
15362306a36Sopenharmony_civoid dm_internal_suspend_fast(struct mapped_device *md);
15462306a36Sopenharmony_civoid dm_internal_resume_fast(struct mapped_device *md);
15562306a36Sopenharmony_civoid dm_internal_suspend_noflush(struct mapped_device *md);
15662306a36Sopenharmony_civoid dm_internal_resume(struct mapped_device *md);
15762306a36Sopenharmony_ci
15862306a36Sopenharmony_ci/*
15962306a36Sopenharmony_ci * Test if the device is scheduled for deferred remove.
16062306a36Sopenharmony_ci */
16162306a36Sopenharmony_ciint dm_test_deferred_remove_flag(struct mapped_device *md);
16262306a36Sopenharmony_ci
16362306a36Sopenharmony_ci/*
16462306a36Sopenharmony_ci * Try to remove devices marked for deferred removal.
16562306a36Sopenharmony_ci */
16662306a36Sopenharmony_civoid dm_deferred_remove(void);
16762306a36Sopenharmony_ci
16862306a36Sopenharmony_ci/*
16962306a36Sopenharmony_ci * The device-mapper can be driven through one of two interfaces;
17062306a36Sopenharmony_ci * ioctl or filesystem, depending which patch you have applied.
17162306a36Sopenharmony_ci */
17262306a36Sopenharmony_ciint dm_interface_init(void);
17362306a36Sopenharmony_civoid dm_interface_exit(void);
17462306a36Sopenharmony_ci
17562306a36Sopenharmony_ci/*
17662306a36Sopenharmony_ci * sysfs interface
17762306a36Sopenharmony_ci */
17862306a36Sopenharmony_ciint dm_sysfs_init(struct mapped_device *md);
17962306a36Sopenharmony_civoid dm_sysfs_exit(struct mapped_device *md);
18062306a36Sopenharmony_cistruct kobject *dm_kobject(struct mapped_device *md);
18162306a36Sopenharmony_cistruct mapped_device *dm_get_from_kobject(struct kobject *kobj);
18262306a36Sopenharmony_ci
18362306a36Sopenharmony_ci/*
18462306a36Sopenharmony_ci * The kobject helper
18562306a36Sopenharmony_ci */
18662306a36Sopenharmony_civoid dm_kobject_release(struct kobject *kobj);
18762306a36Sopenharmony_ci
18862306a36Sopenharmony_ci/*
18962306a36Sopenharmony_ci * Targets for linear and striped mappings
19062306a36Sopenharmony_ci */
19162306a36Sopenharmony_ciint dm_linear_init(void);
19262306a36Sopenharmony_civoid dm_linear_exit(void);
19362306a36Sopenharmony_ci
19462306a36Sopenharmony_ciint dm_stripe_init(void);
19562306a36Sopenharmony_civoid dm_stripe_exit(void);
19662306a36Sopenharmony_ci
19762306a36Sopenharmony_ci/*
19862306a36Sopenharmony_ci * mapped_device operations
19962306a36Sopenharmony_ci */
20062306a36Sopenharmony_civoid dm_destroy(struct mapped_device *md);
20162306a36Sopenharmony_civoid dm_destroy_immediate(struct mapped_device *md);
20262306a36Sopenharmony_ciint dm_open_count(struct mapped_device *md);
20362306a36Sopenharmony_ciint dm_lock_for_deletion(struct mapped_device *md, bool mark_deferred, bool only_deferred);
20462306a36Sopenharmony_ciint dm_cancel_deferred_remove(struct mapped_device *md);
20562306a36Sopenharmony_ciint dm_request_based(struct mapped_device *md);
20662306a36Sopenharmony_ciint dm_get_table_device(struct mapped_device *md, dev_t dev, blk_mode_t mode,
20762306a36Sopenharmony_ci			struct dm_dev **result);
20862306a36Sopenharmony_civoid dm_put_table_device(struct mapped_device *md, struct dm_dev *d);
20962306a36Sopenharmony_ci
21062306a36Sopenharmony_ciint dm_kobject_uevent(struct mapped_device *md, enum kobject_action action,
21162306a36Sopenharmony_ci		      unsigned int cookie, bool need_resize_uevent);
21262306a36Sopenharmony_ci
21362306a36Sopenharmony_ciint dm_io_init(void);
21462306a36Sopenharmony_civoid dm_io_exit(void);
21562306a36Sopenharmony_ci
21662306a36Sopenharmony_ciint dm_kcopyd_init(void);
21762306a36Sopenharmony_civoid dm_kcopyd_exit(void);
21862306a36Sopenharmony_ci
21962306a36Sopenharmony_ci/*
22062306a36Sopenharmony_ci * Mempool operations
22162306a36Sopenharmony_ci */
22262306a36Sopenharmony_civoid dm_free_md_mempools(struct dm_md_mempools *pools);
22362306a36Sopenharmony_ci
22462306a36Sopenharmony_ci/*
22562306a36Sopenharmony_ci * Various helpers
22662306a36Sopenharmony_ci */
22762306a36Sopenharmony_ciunsigned int dm_get_reserved_bio_based_ios(void);
22862306a36Sopenharmony_ci
22962306a36Sopenharmony_ci#define DM_HASH_LOCKS_MAX 64
23062306a36Sopenharmony_ci
23162306a36Sopenharmony_cistatic inline unsigned int dm_num_hash_locks(void)
23262306a36Sopenharmony_ci{
23362306a36Sopenharmony_ci	unsigned int num_locks = roundup_pow_of_two(num_online_cpus()) << 1;
23462306a36Sopenharmony_ci
23562306a36Sopenharmony_ci	return min_t(unsigned int, num_locks, DM_HASH_LOCKS_MAX);
23662306a36Sopenharmony_ci}
23762306a36Sopenharmony_ci
23862306a36Sopenharmony_ci#define DM_HASH_LOCKS_MULT  4294967291ULL
23962306a36Sopenharmony_ci#define DM_HASH_LOCKS_SHIFT 6
24062306a36Sopenharmony_ci
24162306a36Sopenharmony_cistatic inline unsigned int dm_hash_locks_index(sector_t block,
24262306a36Sopenharmony_ci					       unsigned int num_locks)
24362306a36Sopenharmony_ci{
24462306a36Sopenharmony_ci	sector_t h1 = (block * DM_HASH_LOCKS_MULT) >> DM_HASH_LOCKS_SHIFT;
24562306a36Sopenharmony_ci	sector_t h2 = h1 >> DM_HASH_LOCKS_SHIFT;
24662306a36Sopenharmony_ci
24762306a36Sopenharmony_ci	return (h1 ^ h2) & (num_locks - 1);
24862306a36Sopenharmony_ci}
24962306a36Sopenharmony_ci
25062306a36Sopenharmony_ci#endif
251